feat: runtime error
This commit is contained in:
@@ -5,21 +5,21 @@
|
|||||||
import type { NixValue } from "../types";
|
import type { NixValue } from "../types";
|
||||||
|
|
||||||
export const fromJSON = (e: NixValue): never => {
|
export const fromJSON = (e: NixValue): never => {
|
||||||
throw "Not implemented: fromJSON";
|
throw new Error("Not implemented: fromJSON");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fromTOML = (e: NixValue): never => {
|
export const fromTOML = (e: NixValue): never => {
|
||||||
throw "Not implemented: fromTOML";
|
throw new Error("Not implemented: fromTOML");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toJSON = (e: NixValue): never => {
|
export const toJSON = (e: NixValue): never => {
|
||||||
throw "Not implemented: toJSON";
|
throw new Error("Not implemented: toJSON");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toXML = (e: NixValue): never => {
|
export const toXML = (e: NixValue): never => {
|
||||||
throw "Not implemented: toXML";
|
throw new Error("Not implemented: toXML");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toString = (name: NixValue, s: NixValue): never => {
|
export const toString = (name: NixValue, s: NixValue): never => {
|
||||||
throw "Not implemented: toString";
|
throw new Error("Not implemented: toString");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { NixValue } from "../types";
|
import type { NixValue } from "../types";
|
||||||
|
|
||||||
export const derivation = (args: NixValue) => {
|
export const derivation = (args: NixValue) => {
|
||||||
throw "Not implemented: derivation";
|
throw new Error("Not implemented: derivation");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const derivationStrict = (args: NixValue) => {
|
export const derivationStrict = (args: NixValue) => {
|
||||||
throw "Not implemented: derivationStrict";
|
throw new Error("Not implemented: derivationStrict");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
* Functional programming builtin functions
|
* Functional programming builtin functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NixValue } from "../types";
|
import { CatchableError, type NixValue } from "../types";
|
||||||
import { force } from "../thunk";
|
import { force } from "../thunk";
|
||||||
|
import { force_string } from "../type-assert";
|
||||||
|
|
||||||
export const seq =
|
export const seq =
|
||||||
(e1: NixValue) =>
|
(e1: NixValue) =>
|
||||||
@@ -15,15 +16,15 @@ export const seq =
|
|||||||
export const deepSeq =
|
export const deepSeq =
|
||||||
(e1: NixValue) =>
|
(e1: NixValue) =>
|
||||||
(e2: NixValue): never => {
|
(e2: NixValue): never => {
|
||||||
throw "Not implemented: deepSeq";
|
throw new Error("Not implemented: deepSeq");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const abort = (s: NixValue): never => {
|
export const abort = (s: NixValue): never => {
|
||||||
throw `evaluation aborted with the following error message: '${force(s)}'`;
|
throw new Error(`evaluation aborted with the following error message: '${force(s)}'`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const throwFunc = (s: NixValue): never => {
|
export const throwFunc = (s: NixValue): never => {
|
||||||
throw force(s);
|
throw new CatchableError(force_string(s));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const trace = (e1: NixValue, e2: NixValue): NixValue => {
|
export const trace = (e1: NixValue, e2: NixValue): NixValue => {
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ export const builtins: any = {
|
|||||||
|
|
||||||
builtins: create_thunk(() => builtins),
|
builtins: create_thunk(() => builtins),
|
||||||
currentSystem: create_thunk(() => {
|
currentSystem: create_thunk(() => {
|
||||||
throw "Not implemented: currentSystem";
|
throw new Error("Not implemented: currentSystem");
|
||||||
}),
|
}),
|
||||||
currentTime: create_thunk(() => Date.now()),
|
currentTime: create_thunk(() => Date.now()),
|
||||||
|
|
||||||
|
|||||||
@@ -25,39 +25,39 @@ export const importFunc = (path: NixValue): NixValue => {
|
|||||||
export const scopedImport =
|
export const scopedImport =
|
||||||
(scope: NixValue) =>
|
(scope: NixValue) =>
|
||||||
(path: NixValue): never => {
|
(path: NixValue): never => {
|
||||||
throw "Not implemented: scopedImport";
|
throw new Error("Not implemented: scopedImport");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const storePath = (args: NixValue): never => {
|
export const storePath = (args: NixValue): never => {
|
||||||
throw "Not implemented: storePath";
|
throw new Error("Not implemented: storePath");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchClosure = (args: NixValue): never => {
|
export const fetchClosure = (args: NixValue): never => {
|
||||||
throw "Not implemented: fetchClosure";
|
throw new Error("Not implemented: fetchClosure");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchMercurial = (args: NixValue): never => {
|
export const fetchMercurial = (args: NixValue): never => {
|
||||||
throw "Not implemented: fetchMercurial";
|
throw new Error("Not implemented: fetchMercurial");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchGit = (args: NixValue): never => {
|
export const fetchGit = (args: NixValue): never => {
|
||||||
throw "Not implemented: fetchGit";
|
throw new Error("Not implemented: fetchGit");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchTarball = (args: NixValue): never => {
|
export const fetchTarball = (args: NixValue): never => {
|
||||||
throw "Not implemented: fetchTarball";
|
throw new Error("Not implemented: fetchTarball");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchTree = (args: NixValue): never => {
|
export const fetchTree = (args: NixValue): never => {
|
||||||
throw "Not implemented: fetchTree";
|
throw new Error("Not implemented: fetchTree");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchurl = (args: NixValue): never => {
|
export const fetchurl = (args: NixValue): never => {
|
||||||
throw "Not implemented: fetchurl";
|
throw new Error("Not implemented: fetchurl");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const readDir = (path: NixValue): never => {
|
export const readDir = (path: NixValue): never => {
|
||||||
throw "Not implemented: readDir";
|
throw new Error("Not implemented: readDir");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const readFile = (path: NixValue): string => {
|
export const readFile = (path: NixValue): string => {
|
||||||
@@ -66,7 +66,7 @@ export const readFile = (path: NixValue): string => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const readFileType = (path: NixValue): never => {
|
export const readFileType = (path: NixValue): never => {
|
||||||
throw "Not implemented: readFileType";
|
throw new Error("Not implemented: readFileType");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pathExists = (path: NixValue): boolean => {
|
export const pathExists = (path: NixValue): boolean => {
|
||||||
@@ -75,27 +75,27 @@ export const pathExists = (path: NixValue): boolean => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const path = (args: NixValue): never => {
|
export const path = (args: NixValue): never => {
|
||||||
throw "Not implemented: path";
|
throw new Error("Not implemented: path");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toFile = (name: NixValue, s: NixValue): never => {
|
export const toFile = (name: NixValue, s: NixValue): never => {
|
||||||
throw "Not implemented: toFile";
|
throw new Error("Not implemented: toFile");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toPath = (name: NixValue, s: NixValue): never => {
|
export const toPath = (name: NixValue, s: NixValue): never => {
|
||||||
throw "Not implemented: toPath";
|
throw new Error("Not implemented: toPath");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const filterSource = (args: NixValue): never => {
|
export const filterSource = (args: NixValue): never => {
|
||||||
throw "Not implemented: filterSource";
|
throw new Error("Not implemented: filterSource");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findFile =
|
export const findFile =
|
||||||
(search: NixValue) =>
|
(search: NixValue) =>
|
||||||
(lookup: NixValue): never => {
|
(lookup: NixValue): never => {
|
||||||
throw "Not implemented: findFile";
|
throw new Error("Not implemented: findFile");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getEnv = (s: NixValue): never => {
|
export const getEnv = (s: NixValue): never => {
|
||||||
throw "Not implemented: getEnv";
|
throw new Error("Not implemented: getEnv");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,141 +2,155 @@
|
|||||||
* Miscellaneous unimplemented builtin functions
|
* Miscellaneous unimplemented builtin functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NixValue } from "../types";
|
import { force } from "../thunk";
|
||||||
|
import { CatchableError } from "../types";
|
||||||
|
import type { NixBool, NixStrictValue, NixValue } from "../types";
|
||||||
|
|
||||||
export const addErrorContext =
|
export const addErrorContext =
|
||||||
(e1: NixValue) =>
|
(e1: NixValue) =>
|
||||||
(e2: NixValue): never => {
|
(e2: NixValue): never => {
|
||||||
throw "Not implemented: addErrorContext";
|
throw new Error("Not implemented: addErrorContext");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const appendContext =
|
export const appendContext =
|
||||||
(e1: NixValue) =>
|
(e1: NixValue) =>
|
||||||
(e2: NixValue): never => {
|
(e2: NixValue): never => {
|
||||||
throw "Not implemented: appendContext";
|
throw new Error("Not implemented: appendContext");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getContext = (s: NixValue): never => {
|
export const getContext = (s: NixValue): never => {
|
||||||
throw "Not implemented: getContext";
|
throw new Error("Not implemented: getContext");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hasContext = (s: NixValue): never => {
|
export const hasContext = (s: NixValue): never => {
|
||||||
throw "Not implemented: hasContext";
|
throw new Error("Not implemented: hasContext");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hashFile =
|
export const hashFile =
|
||||||
(type: NixValue) =>
|
(type: NixValue) =>
|
||||||
(p: NixValue): never => {
|
(p: NixValue): never => {
|
||||||
throw "Not implemented: hashFile";
|
throw new Error("Not implemented: hashFile");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hashString =
|
export const hashString =
|
||||||
(type: NixValue) =>
|
(type: NixValue) =>
|
||||||
(p: NixValue): never => {
|
(p: NixValue): never => {
|
||||||
throw "Not implemented: hashString";
|
throw new Error("Not implemented: hashString");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const convertHash = (args: NixValue): never => {
|
export const convertHash = (args: NixValue): never => {
|
||||||
throw "Not implemented: convertHash";
|
throw new Error("Not implemented: convertHash");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const unsafeDiscardOutputDependency = (s: NixValue): never => {
|
export const unsafeDiscardOutputDependency = (s: NixValue): never => {
|
||||||
throw "Not implemented: unsafeDiscardOutputDependency";
|
throw new Error("Not implemented: unsafeDiscardOutputDependency");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const unsafeDiscardStringContext = (s: NixValue): never => {
|
export const unsafeDiscardStringContext = (s: NixValue): never => {
|
||||||
throw "Not implemented: unsafeDiscardStringContext";
|
throw new Error("Not implemented: unsafeDiscardStringContext");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const unsafeGetAttrPos = (s: NixValue): never => {
|
export const unsafeGetAttrPos = (s: NixValue): never => {
|
||||||
throw "Not implemented: unsafeGetAttrPos";
|
throw new Error("Not implemented: unsafeGetAttrPos");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addDrvOutputDependencies = (s: NixValue): never => {
|
export const addDrvOutputDependencies = (s: NixValue): never => {
|
||||||
throw "Not implemented: addDrvOutputDependencies";
|
throw new Error("Not implemented: addDrvOutputDependencies");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const compareVersions =
|
export const compareVersions =
|
||||||
(s1: NixValue) =>
|
(s1: NixValue) =>
|
||||||
(s2: NixValue): never => {
|
(s2: NixValue): never => {
|
||||||
throw "Not implemented: compareVersions";
|
throw new Error("Not implemented: compareVersions");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dirOf = (s: NixValue): never => {
|
export const dirOf = (s: NixValue): never => {
|
||||||
throw "Not implemented: dirOf";
|
throw new Error("Not implemented: dirOf");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const flakeRefToString = (attrs: NixValue): never => {
|
export const flakeRefToString = (attrs: NixValue): never => {
|
||||||
throw "Not implemented: flakeRefToString";
|
throw new Error("Not implemented: flakeRefToString");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const functionArgs = (f: NixValue): never => {
|
export const functionArgs = (f: NixValue): never => {
|
||||||
throw "Not implemented: functionArgs";
|
throw new Error("Not implemented: functionArgs");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const genericClosure = (args: NixValue): never => {
|
export const genericClosure = (args: NixValue): never => {
|
||||||
throw "Not implemented: genericClosure";
|
throw new Error("Not implemented: genericClosure");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getFlake = (attrs: NixValue): never => {
|
export const getFlake = (attrs: NixValue): never => {
|
||||||
throw "Not implemented: getFlake";
|
throw new Error("Not implemented: getFlake");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const match =
|
export const match =
|
||||||
(regex: NixValue) =>
|
(regex: NixValue) =>
|
||||||
(str: NixValue): never => {
|
(str: NixValue): never => {
|
||||||
throw "Not implemented: match";
|
throw new Error("Not implemented: match");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const outputOf =
|
export const outputOf =
|
||||||
(drv: NixValue) =>
|
(drv: NixValue) =>
|
||||||
(out: NixValue): never => {
|
(out: NixValue): never => {
|
||||||
throw "Not implemented: outputOf";
|
throw new Error("Not implemented: outputOf");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseDrvName = (s: NixValue): never => {
|
export const parseDrvName = (s: NixValue): never => {
|
||||||
throw "Not implemented: parseDrvName";
|
throw new Error("Not implemented: parseDrvName");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseFlakeName = (s: NixValue): never => {
|
export const parseFlakeName = (s: NixValue): never => {
|
||||||
throw "Not implemented: parseFlakeName";
|
throw new Error("Not implemented: parseFlakeName");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseFlakeRef = (s: NixValue): never => {
|
export const parseFlakeRef = (s: NixValue): never => {
|
||||||
throw "Not implemented: parseFlakeRef";
|
throw new Error("Not implemented: parseFlakeRef");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const placeholder = (output: NixValue): never => {
|
export const placeholder = (output: NixValue): never => {
|
||||||
throw "Not implemented: placeholder";
|
throw new Error("Not implemented: placeholder");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const replaceStrings =
|
export const replaceStrings =
|
||||||
(from: NixValue) =>
|
(from: NixValue) =>
|
||||||
(to: NixValue) =>
|
(to: NixValue) =>
|
||||||
(s: NixValue): never => {
|
(s: NixValue): never => {
|
||||||
throw "Not implemented: replaceStrings";
|
throw new Error("Not implemented: replaceStrings");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const split = (regex: NixValue, str: NixValue): never => {
|
export const split = (regex: NixValue, str: NixValue): never => {
|
||||||
throw "Not implemented: split";
|
throw new Error("Not implemented: split");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const splitVersion = (s: NixValue): never => {
|
export const splitVersion = (s: NixValue): never => {
|
||||||
throw "Not implemented: splitVersion";
|
throw new Error("Not implemented: splitVersion");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const traceVerbose = (e1: NixValue, e2: NixValue): never => {
|
export const traceVerbose = (e1: NixValue, e2: NixValue): never => {
|
||||||
throw "Not implemented: traceVerbose";
|
throw new Error("Not implemented: traceVerbose");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const tryEval =
|
export const tryEval = (e: NixValue): { success: NixBool; value: NixStrictValue } => {
|
||||||
(e1: NixValue) =>
|
try {
|
||||||
(e2: NixValue): never => {
|
return {
|
||||||
throw "Not implemented: tryEval";
|
success: true,
|
||||||
|
value: force(e),
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof CatchableError) {
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
value: false,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const zipAttrsWith =
|
export const zipAttrsWith =
|
||||||
(f: NixValue) =>
|
(f: NixValue) =>
|
||||||
(list: NixValue): never => {
|
(list: NixValue): never => {
|
||||||
throw "Not implemented: zipAttrsWith";
|
throw new Error("Not implemented: zipAttrsWith");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type {
|
|||||||
NixInt,
|
NixInt,
|
||||||
NixList,
|
NixList,
|
||||||
NixNull,
|
NixNull,
|
||||||
|
NixStrictValue,
|
||||||
NixString,
|
NixString,
|
||||||
NixValue,
|
NixValue,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
@@ -39,7 +40,7 @@ export const isList = (e: NixValue): e is NixList => Array.isArray(force(e));
|
|||||||
export const isNull = (e: NixValue): e is NixNull => force(e) === null;
|
export const isNull = (e: NixValue): e is NixNull => force(e) === null;
|
||||||
|
|
||||||
export const isPath = (e: NixValue): never => {
|
export const isPath = (e: NixValue): never => {
|
||||||
throw "Not implemented: isPath";
|
throw new Error("Not implemented: isPath");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isString = (e: NixValue): e is NixString => typeof force(e) === "string";
|
export const isString = (e: NixValue): e is NixString => typeof force(e) === "string";
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export const select_with_default = (obj: NixValue, key: NixValue, default_val: N
|
|||||||
|
|
||||||
export const has_attr = (obj: NixValue, attrpath: NixValue[]): NixBool => {
|
export const has_attr = (obj: NixValue, attrpath: NixValue[]): NixBool => {
|
||||||
if (!isAttrs(obj)) {
|
if (!isAttrs(obj)) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
let attrs = obj;
|
let attrs = obj;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Implements thunks for lazy evaluation of Nix expressions
|
* Implements thunks for lazy evaluation of Nix expressions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { NixValue, NixThunkInterface } from "./types";
|
import type { NixValue, NixThunkInterface, NixStrictValue } from "./types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Symbol used to mark objects as thunks
|
* Symbol used to mark objects as thunks
|
||||||
@@ -20,12 +20,12 @@ export const IS_THUNK = Symbol("is_thunk");
|
|||||||
export class NixThunk implements NixThunkInterface {
|
export class NixThunk implements NixThunkInterface {
|
||||||
[key: symbol]: any;
|
[key: symbol]: any;
|
||||||
readonly [IS_THUNK] = true as const;
|
readonly [IS_THUNK] = true as const;
|
||||||
func: (() => NixValue) | null;
|
func: (() => NixValue) | undefined;
|
||||||
result: Exclude<NixValue, NixThunkInterface> | null;
|
result: NixStrictValue | undefined;
|
||||||
|
|
||||||
constructor(func: () => NixValue) {
|
constructor(func: () => NixValue) {
|
||||||
this.func = func;
|
this.func = func;
|
||||||
this.result = null;
|
this.result = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,20 +46,20 @@ export const is_thunk = (value: unknown): value is NixThunkInterface => {
|
|||||||
* @param value - Value to force (may be a thunk)
|
* @param value - Value to force (may be a thunk)
|
||||||
* @returns The forced/evaluated value
|
* @returns The forced/evaluated value
|
||||||
*/
|
*/
|
||||||
export const force = (value: NixValue): Exclude<NixValue, NixThunkInterface> => {
|
export const force = (value: NixValue): NixStrictValue => {
|
||||||
if (!is_thunk(value)) {
|
if (!is_thunk(value)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Already evaluated - return cached result
|
// Already evaluated - return cached result
|
||||||
if (value.func === null) {
|
if (value.func === undefined) {
|
||||||
return value.result!;
|
return value.result!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate and cache
|
// Evaluate and cache
|
||||||
const result = force(value.func());
|
const result = force(value.func());
|
||||||
value.result = result;
|
value.result = result;
|
||||||
value.func = null;
|
value.func = undefined;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
* Core TypeScript type definitions for nix-js runtime
|
* Core TypeScript type definitions for nix-js runtime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { IS_THUNK } from "./thunk";
|
||||||
|
|
||||||
// Nix primitive types
|
// Nix primitive types
|
||||||
export type NixInt = bigint;
|
export type NixInt = bigint;
|
||||||
export type NixFloat = number;
|
export type NixFloat = number;
|
||||||
@@ -20,9 +22,9 @@ export type NixFunction = (...args: any[]) => any;
|
|||||||
* Thunks delay evaluation until forced
|
* Thunks delay evaluation until forced
|
||||||
*/
|
*/
|
||||||
export interface NixThunkInterface {
|
export interface NixThunkInterface {
|
||||||
readonly [key: symbol]: true; // IS_THUNK marker
|
readonly [IS_THUNK]: true;
|
||||||
func: (() => NixValue) | null;
|
func: (() => NixValue) | undefined;
|
||||||
result: Exclude<NixValue, NixThunkInterface> | null;
|
result: NixStrictValue | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Union of all Nix primitive types
|
// Union of all Nix primitive types
|
||||||
@@ -34,6 +36,18 @@ export type NixPrimitive = NixNull | NixBool | NixInt | NixFloat | NixString;
|
|||||||
*/
|
*/
|
||||||
export type NixValue = NixPrimitive | NixList | NixAttrs | NixFunction | NixThunkInterface;
|
export type NixValue = NixPrimitive | NixList | NixAttrs | NixFunction | NixThunkInterface;
|
||||||
|
|
||||||
|
export type NixStrictValue = Exclude<NixValue, NixThunkInterface>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CatchableError: Error type thrown by `builtins.throw`
|
||||||
|
* This can be caught by `builtins.tryEval`
|
||||||
|
*/
|
||||||
|
export class CatchableError extends Error {
|
||||||
|
constructor(msg: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Operator function signatures
|
// Operator function signatures
|
||||||
export type BinaryOp<T = NixValue, U = NixValue, R = NixValue> = (a: T, b: U) => R;
|
export type BinaryOp<T = NixValue, U = NixValue, R = NixValue> = (a: T, b: U) => R;
|
||||||
export type UnaryOp<T = NixValue, R = NixValue> = (a: T) => R;
|
export type UnaryOp<T = NixValue, R = NixValue> = (a: T) => R;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::pin::Pin;
|
|||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
use deno_core::{Extension, ExtensionFileSource, JsRuntime, OpDecl, OpState, RuntimeOptions, v8};
|
use deno_core::{Extension, ExtensionFileSource, JsRuntime, OpDecl, OpState, RuntimeOptions, v8};
|
||||||
|
use deno_error::JsErrorClass;
|
||||||
|
|
||||||
use crate::codegen::{CodegenContext, Compile};
|
use crate::codegen::{CodegenContext, Compile};
|
||||||
use crate::context::{CtxPtr, PathDropGuard};
|
use crate::context::{CtxPtr, PathDropGuard};
|
||||||
@@ -44,12 +45,12 @@ mod private {
|
|||||||
pub struct SimpleErrorWrapper(pub(crate) String);
|
pub struct SimpleErrorWrapper(pub(crate) String);
|
||||||
impl std::fmt::Display for SimpleErrorWrapper {
|
impl std::fmt::Display for SimpleErrorWrapper {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
std::fmt::Debug::fmt(self, f)
|
std::fmt::Display::fmt(&self.0, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::error::Error for SimpleErrorWrapper {}
|
impl std::error::Error for SimpleErrorWrapper {}
|
||||||
|
|
||||||
js_error_wrapper!(SimpleErrorWrapper, NixError, "EvalError");
|
js_error_wrapper!(SimpleErrorWrapper, NixError, "Error");
|
||||||
|
|
||||||
impl From<String> for NixError {
|
impl From<String> for NixError {
|
||||||
fn from(value: String) -> Self {
|
fn from(value: String) -> Self {
|
||||||
@@ -71,10 +72,13 @@ fn op_import(state: &mut OpState, #[string] path: String) -> std::result::Result
|
|||||||
let ctx = unsafe { ptr.as_mut() };
|
let ctx = unsafe { ptr.as_mut() };
|
||||||
|
|
||||||
let current_dir = ctx.get_current_dir();
|
let current_dir = ctx.get_current_dir();
|
||||||
let absolute_path = current_dir
|
let mut absolute_path = current_dir
|
||||||
.join(&path)
|
.join(&path)
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.map_err(|e| format!("Failed to resolve path {}: {}", path, e))?;
|
.map_err(|e| format!("Failed to resolve path {}: {}", path, e))?;
|
||||||
|
if absolute_path.is_dir() {
|
||||||
|
absolute_path.push("default.nix")
|
||||||
|
}
|
||||||
|
|
||||||
let mut guard = PathDropGuard::new(absolute_path.clone(), ctx);
|
let mut guard = PathDropGuard::new(absolute_path.clone(), ctx);
|
||||||
let ctx = guard.as_ctx();
|
let ctx = guard.as_ctx();
|
||||||
@@ -175,7 +179,7 @@ impl Runtime {
|
|||||||
let global_value = self
|
let global_value = self
|
||||||
.js_runtime
|
.js_runtime
|
||||||
.execute_script("<eval>", script)
|
.execute_script("<eval>", script)
|
||||||
.map_err(|e| Error::eval_error(format!("Execution error: {:?}", e)))?;
|
.map_err(|e| Error::eval_error(format!("{}", e.get_message())))?;
|
||||||
|
|
||||||
// Retrieve scope from JsRuntime
|
// Retrieve scope from JsRuntime
|
||||||
deno_core::scope!(scope, self.js_runtime);
|
deno_core::scope!(scope, self.js_runtime);
|
||||||
|
|||||||
Reference in New Issue
Block a user