feat: add missing primops
This commit is contained in:
8
nix-js/runtime-ts/build.mjs
Normal file
8
nix-js/runtime-ts/build.mjs
Normal file
@@ -0,0 +1,8 @@
|
||||
import * as esbuild from "esbuild";
|
||||
|
||||
await esbuild.build({
|
||||
entryPoints: ["src/index.ts"],
|
||||
outfile: "dist/runtime.js",
|
||||
bundle: true,
|
||||
minify: true,
|
||||
});
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit",
|
||||
"build": "esbuild src/index.ts --bundle --target=es2020 --format=iife --outfile=dist/runtime.js",
|
||||
"build": "node build.mjs",
|
||||
"dev": "npm run typecheck && npm run build"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { NixValue, NixAttrs, NixList } from "../types";
|
||||
import { force_attrs, force_string, force_function, force_list } from "../type-assert";
|
||||
|
||||
export const attrNames = (set: NixValue): string[] => Object.keys(force_attrs(set));
|
||||
export const attrNames = (set: NixValue): string[] => Object.keys(force_attrs(set)).sort();
|
||||
|
||||
export const attrValues = (set: NixValue): NixValue[] => Object.values(force_attrs(set));
|
||||
|
||||
@@ -31,6 +31,21 @@ export const mapAttrs =
|
||||
return new_attrs;
|
||||
};
|
||||
|
||||
export const removeAttrs =
|
||||
(attrs: NixValue) =>
|
||||
(list: NixValue): NixAttrs => {
|
||||
const new_attrs: NixAttrs = {};
|
||||
const forced_attrs = force_attrs(attrs);
|
||||
const forced_list = force_list(list);
|
||||
|
||||
for (const key in forced_attrs) {
|
||||
if (!(key in forced_list)) {
|
||||
new_attrs[key] = forced_attrs[key];
|
||||
}
|
||||
}
|
||||
return new_attrs;
|
||||
};
|
||||
|
||||
export const listToAttrs = (e: NixValue): NixAttrs => {
|
||||
const attrs: NixAttrs = {};
|
||||
const forced_e = [...force_list(e)].reverse();
|
||||
|
||||
9
nix-js/runtime-ts/src/builtins/derivation.ts
Normal file
9
nix-js/runtime-ts/src/builtins/derivation.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { NixValue } from "../types";
|
||||
|
||||
export const derivation = (args: NixValue) => {
|
||||
throw "Not implemented: derivation";
|
||||
};
|
||||
|
||||
export const derivationStrict = (args: NixValue) => {
|
||||
throw "Not implemented: derivationStrict";
|
||||
};
|
||||
@@ -33,7 +33,7 @@ export interface PrimopMetadata {
|
||||
* @param applied - Number of arguments already applied (default: 0)
|
||||
* @returns The marked function
|
||||
*/
|
||||
export const markPrimop = <T extends Function>(
|
||||
export const mkPrimop = <T extends Function>(
|
||||
func: T,
|
||||
name: string,
|
||||
arity: number,
|
||||
@@ -53,7 +53,7 @@ export const markPrimop = <T extends Function>(
|
||||
const result = func(...args);
|
||||
// If result is a function, mark it as the next layer
|
||||
if (typeof result === "function") {
|
||||
return markPrimop(result, name, arity, applied + args.length);
|
||||
return mkPrimop(result, name, arity, applied + args.length);
|
||||
}
|
||||
return result;
|
||||
}) as any;
|
||||
@@ -108,6 +108,7 @@ import * as functional from "./functional";
|
||||
import * as io from "./io";
|
||||
import * as conversion from "./conversion";
|
||||
import * as misc from "./misc";
|
||||
import * as derivation from "./derivation";
|
||||
|
||||
/**
|
||||
* The global builtins object
|
||||
@@ -120,122 +121,131 @@ import * as misc from "./misc";
|
||||
* All primop functions are marked with PRIMOP_METADATA symbol for runtime introspection
|
||||
*/
|
||||
export const builtins: any = {
|
||||
add: markPrimop(arithmetic.add, "add", 2),
|
||||
sub: markPrimop(arithmetic.sub, "sub", 2),
|
||||
mul: markPrimop(arithmetic.mul, "mul", 2),
|
||||
div: markPrimop(arithmetic.div, "div", 2),
|
||||
bitAnd: markPrimop(arithmetic.bitAnd, "bitAnd", 2),
|
||||
bitOr: markPrimop(arithmetic.bitOr, "bitOr", 2),
|
||||
bitXor: markPrimop(arithmetic.bitXor, "bitXor", 2),
|
||||
lessThan: markPrimop(arithmetic.lessThan, "lessThan", 2),
|
||||
add: mkPrimop(arithmetic.add, "add", 2),
|
||||
sub: mkPrimop(arithmetic.sub, "sub", 2),
|
||||
mul: mkPrimop(arithmetic.mul, "mul", 2),
|
||||
div: mkPrimop(arithmetic.div, "div", 2),
|
||||
bitAnd: mkPrimop(arithmetic.bitAnd, "bitAnd", 2),
|
||||
bitOr: mkPrimop(arithmetic.bitOr, "bitOr", 2),
|
||||
bitXor: mkPrimop(arithmetic.bitXor, "bitXor", 2),
|
||||
lessThan: mkPrimop(arithmetic.lessThan, "lessThan", 2),
|
||||
|
||||
ceil: markPrimop(math.ceil, "ceil", 1),
|
||||
floor: markPrimop(math.floor, "floor", 1),
|
||||
ceil: mkPrimop(math.ceil, "ceil", 1),
|
||||
floor: mkPrimop(math.floor, "floor", 1),
|
||||
|
||||
isAttrs: markPrimop(typeCheck.isAttrs, "isAttrs", 1),
|
||||
isBool: markPrimop(typeCheck.isBool, "isBool", 1),
|
||||
isFloat: markPrimop(typeCheck.isFloat, "isFloat", 1),
|
||||
isFunction: markPrimop(typeCheck.isFunction, "isFunction", 1),
|
||||
isInt: markPrimop(typeCheck.isInt, "isInt", 1),
|
||||
isList: markPrimop(typeCheck.isList, "isList", 1),
|
||||
isNull: markPrimop(typeCheck.isNull, "isNull", 1),
|
||||
isPath: markPrimop(typeCheck.isPath, "isPath", 1),
|
||||
isString: markPrimop(typeCheck.isString, "isString", 1),
|
||||
typeOf: markPrimop(typeCheck.typeOf, "typeOf", 1),
|
||||
isAttrs: mkPrimop(typeCheck.isAttrs, "isAttrs", 1),
|
||||
isBool: mkPrimop(typeCheck.isBool, "isBool", 1),
|
||||
isFloat: mkPrimop(typeCheck.isFloat, "isFloat", 1),
|
||||
isFunction: mkPrimop(typeCheck.isFunction, "isFunction", 1),
|
||||
isInt: mkPrimop(typeCheck.isInt, "isInt", 1),
|
||||
isList: mkPrimop(typeCheck.isList, "isList", 1),
|
||||
isNull: mkPrimop(typeCheck.isNull, "isNull", 1),
|
||||
isPath: mkPrimop(typeCheck.isPath, "isPath", 1),
|
||||
isString: mkPrimop(typeCheck.isString, "isString", 1),
|
||||
typeOf: mkPrimop(typeCheck.typeOf, "typeOf", 1),
|
||||
|
||||
map: markPrimop(list.map, "map", 2),
|
||||
filter: markPrimop(list.filter, "filter", 2),
|
||||
length: markPrimop(list.length, "length", 1),
|
||||
head: markPrimop(list.head, "head", 1),
|
||||
tail: markPrimop(list.tail, "tail", 1),
|
||||
elem: markPrimop(list.elem, "elem", 2),
|
||||
elemAt: markPrimop(list.elemAt, "elemAt", 2),
|
||||
concatLists: markPrimop(list.concatLists, "concatLists", 1),
|
||||
concatMap: markPrimop(list.concatMap, "concatMap", 2),
|
||||
"foldl'": markPrimop(list.foldlPrime, "foldl'", 3),
|
||||
sort: markPrimop(list.sort, "sort", 2),
|
||||
partition: markPrimop(list.partition, "partition", 2),
|
||||
genList: markPrimop(list.genList, "genList", 2),
|
||||
all: markPrimop(list.all, "all", 2),
|
||||
any: markPrimop(list.any, "any", 2),
|
||||
map: mkPrimop(list.map, "map", 2),
|
||||
filter: mkPrimop(list.filter, "filter", 2),
|
||||
length: mkPrimop(list.length, "length", 1),
|
||||
head: mkPrimop(list.head, "head", 1),
|
||||
tail: mkPrimop(list.tail, "tail", 1),
|
||||
elem: mkPrimop(list.elem, "elem", 2),
|
||||
elemAt: mkPrimop(list.elemAt, "elemAt", 2),
|
||||
concatLists: mkPrimop(list.concatLists, "concatLists", 1),
|
||||
concatMap: mkPrimop(list.concatMap, "concatMap", 2),
|
||||
"foldl'": mkPrimop(list.foldlPrime, "foldl'", 3),
|
||||
sort: mkPrimop(list.sort, "sort", 2),
|
||||
partition: mkPrimop(list.partition, "partition", 2),
|
||||
genList: mkPrimop(list.genList, "genList", 2),
|
||||
all: mkPrimop(list.all, "all", 2),
|
||||
any: mkPrimop(list.any, "any", 2),
|
||||
|
||||
attrNames: markPrimop(attrs.attrNames, "attrNames", 1),
|
||||
attrValues: markPrimop(attrs.attrValues, "attrValues", 1),
|
||||
getAttr: markPrimop(attrs.getAttr, "getAttr", 2),
|
||||
hasAttr: markPrimop(attrs.hasAttr, "hasAttr", 2),
|
||||
mapAttrs: markPrimop(attrs.mapAttrs, "mapAttrs", 2),
|
||||
listToAttrs: markPrimop(attrs.listToAttrs, "listToAttrs", 1),
|
||||
intersectAttrs: markPrimop(attrs.intersectAttrs, "intersectAttrs", 2),
|
||||
catAttrs: markPrimop(attrs.catAttrs, "catAttrs", 2),
|
||||
groupBy: markPrimop(attrs.groupBy, "groupBy", 2),
|
||||
attrNames: mkPrimop(attrs.attrNames, "attrNames", 1),
|
||||
attrValues: mkPrimop(attrs.attrValues, "attrValues", 1),
|
||||
getAttr: mkPrimop(attrs.getAttr, "getAttr", 2),
|
||||
hasAttr: mkPrimop(attrs.hasAttr, "hasAttr", 2),
|
||||
mapAttrs: mkPrimop(attrs.mapAttrs, "mapAttrs", 2),
|
||||
removeAttrs: mkPrimop(attrs.removeAttrs, "removeAttrs", 2),
|
||||
listToAttrs: mkPrimop(attrs.listToAttrs, "listToAttrs", 1),
|
||||
intersectAttrs: mkPrimop(attrs.intersectAttrs, "intersectAttrs", 2),
|
||||
catAttrs: mkPrimop(attrs.catAttrs, "catAttrs", 2),
|
||||
groupBy: mkPrimop(attrs.groupBy, "groupBy", 2),
|
||||
|
||||
stringLength: markPrimop(string.stringLength, "stringLength", 1),
|
||||
substring: markPrimop(string.substring, "substring", 3),
|
||||
concatStringsSep: markPrimop(string.concatStringsSep, "concatStringsSep", 2),
|
||||
baseNameOf: markPrimop(string.baseNameOf, "baseNameOf", 1),
|
||||
stringLength: mkPrimop(string.stringLength, "stringLength", 1),
|
||||
substring: mkPrimop(string.substring, "substring", 3),
|
||||
concatStringsSep: mkPrimop(string.concatStringsSep, "concatStringsSep", 2),
|
||||
baseNameOf: mkPrimop(string.baseNameOf, "baseNameOf", 1),
|
||||
|
||||
seq: markPrimop(functional.seq, "seq", 2),
|
||||
deepSeq: markPrimop(functional.deepSeq, "deepSeq", 2),
|
||||
abort: markPrimop(functional.abort, "abort", 1),
|
||||
throw: markPrimop(functional.throwFunc, "throw", 1),
|
||||
trace: markPrimop(functional.trace, "trace", 2),
|
||||
warn: markPrimop(functional.warn, "warn", 2),
|
||||
break: markPrimop(functional.breakFunc, "break", 1),
|
||||
seq: mkPrimop(functional.seq, "seq", 2),
|
||||
deepSeq: mkPrimop(functional.deepSeq, "deepSeq", 2),
|
||||
abort: mkPrimop(functional.abort, "abort", 1),
|
||||
throw: mkPrimop(functional.throwFunc, "throw", 1),
|
||||
trace: mkPrimop(functional.trace, "trace", 2),
|
||||
warn: mkPrimop(functional.warn, "warn", 2),
|
||||
break: mkPrimop(functional.breakFunc, "break", 1),
|
||||
|
||||
import: markPrimop(io.importFunc, "import", 1),
|
||||
scopedImport: markPrimop(io.scopedImport, "scopedImport", 2),
|
||||
fetchClosure: markPrimop(io.fetchClosure, "fetchClosure", 1),
|
||||
fetchGit: markPrimop(io.fetchGit, "fetchGit", 1),
|
||||
fetchTarball: markPrimop(io.fetchTarball, "fetchTarball", 1),
|
||||
fetchTree: markPrimop(io.fetchTree, "fetchTree", 1),
|
||||
fetchurl: markPrimop(io.fetchurl, "fetchurl", 1),
|
||||
readDir: markPrimop(io.readDir, "readDir", 1),
|
||||
readFile: markPrimop(io.readFile, "readFile", 1),
|
||||
readFileType: markPrimop(io.readFileType, "readFileType", 1),
|
||||
pathExists: markPrimop(io.pathExists, "pathExists", 1),
|
||||
path: markPrimop(io.path, "path", 1),
|
||||
toFile: markPrimop(io.toFile, "toFile", 2),
|
||||
toPath: markPrimop(io.toPath, "toPath", 1),
|
||||
filterSource: markPrimop(io.filterSource, "filterSource", 2),
|
||||
findFile: markPrimop(io.findFile, "findFile", 2),
|
||||
getEnv: markPrimop(io.getEnv, "getEnv", 1),
|
||||
derivation: mkPrimop(derivation.derivation, "derivation", 1),
|
||||
derivationStrict: mkPrimop(derivation.derivationStrict, "derivationStrict", 1),
|
||||
|
||||
fromJSON: markPrimop(conversion.fromJSON, "fromJSON", 1),
|
||||
fromTOML: markPrimop(conversion.fromTOML, "fromTOML", 1),
|
||||
toJSON: markPrimop(conversion.toJSON, "toJSON", 1),
|
||||
toXML: markPrimop(conversion.toXML, "toXML", 1),
|
||||
toString: markPrimop(conversion.toString, "toString", 1),
|
||||
import: mkPrimop(io.importFunc, "import", 1),
|
||||
scopedImport: mkPrimop(io.scopedImport, "scopedImport", 2),
|
||||
storePath: mkPrimop(io.storePath, "storePath", 1),
|
||||
fetchClosure: mkPrimop(io.fetchClosure, "fetchClosure", 1),
|
||||
fetchMercurial: mkPrimop(io.fetchMercurial, "fetchMercurial", 1),
|
||||
fetchGit: mkPrimop(io.fetchGit, "fetchGit", 1),
|
||||
fetchTarball: mkPrimop(io.fetchTarball, "fetchTarball", 1),
|
||||
fetchTree: mkPrimop(io.fetchTree, "fetchTree", 1),
|
||||
fetchurl: mkPrimop(io.fetchurl, "fetchurl", 1),
|
||||
readDir: mkPrimop(io.readDir, "readDir", 1),
|
||||
readFile: mkPrimop(io.readFile, "readFile", 1),
|
||||
readFileType: mkPrimop(io.readFileType, "readFileType", 1),
|
||||
pathExists: mkPrimop(io.pathExists, "pathExists", 1),
|
||||
path: mkPrimop(io.path, "path", 1),
|
||||
toFile: mkPrimop(io.toFile, "toFile", 2),
|
||||
toPath: mkPrimop(io.toPath, "toPath", 1),
|
||||
filterSource: mkPrimop(io.filterSource, "filterSource", 2),
|
||||
findFile: mkPrimop(io.findFile, "findFile", 2),
|
||||
getEnv: mkPrimop(io.getEnv, "getEnv", 1),
|
||||
|
||||
getContext: markPrimop(misc.getContext, "getContext", 1),
|
||||
hasContext: markPrimop(misc.hasContext, "hasContext", 1),
|
||||
hashFile: markPrimop(misc.hashFile, "hashFile", 2),
|
||||
hashString: markPrimop(misc.hashString, "hashString", 2),
|
||||
convertHash: markPrimop(misc.convertHash, "convertHash", 2),
|
||||
unsafeDiscardOutputDependency: markPrimop(
|
||||
fromJSON: mkPrimop(conversion.fromJSON, "fromJSON", 1),
|
||||
fromTOML: mkPrimop(conversion.fromTOML, "fromTOML", 1),
|
||||
toJSON: mkPrimop(conversion.toJSON, "toJSON", 1),
|
||||
toXML: mkPrimop(conversion.toXML, "toXML", 1),
|
||||
toString: mkPrimop(conversion.toString, "toString", 1),
|
||||
|
||||
addErrorContext: mkPrimop(misc.addErrorContext, "addErrorContext", 1),
|
||||
appendContext: mkPrimop(misc.appendContext, "appendContext", 1),
|
||||
getContext: mkPrimop(misc.getContext, "getContext", 1),
|
||||
hasContext: mkPrimop(misc.hasContext, "hasContext", 1),
|
||||
hashFile: mkPrimop(misc.hashFile, "hashFile", 2),
|
||||
hashString: mkPrimop(misc.hashString, "hashString", 2),
|
||||
convertHash: mkPrimop(misc.convertHash, "convertHash", 2),
|
||||
unsafeDiscardOutputDependency: mkPrimop(
|
||||
misc.unsafeDiscardOutputDependency,
|
||||
"unsafeDiscardOutputDependency",
|
||||
1,
|
||||
),
|
||||
unsafeDiscardStringContext: markPrimop(misc.unsafeDiscardStringContext, "unsafeDiscardStringContext", 1),
|
||||
unsafeGetAttrPos: markPrimop(misc.unsafeGetAttrPos, "unsafeGetAttrPos", 2),
|
||||
addDrvOutputDependencies: markPrimop(misc.addDrvOutputDependencies, "addDrvOutputDependencies", 2),
|
||||
compareVersions: markPrimop(misc.compareVersions, "compareVersions", 2),
|
||||
dirOf: markPrimop(misc.dirOf, "dirOf", 1),
|
||||
flakeRefToString: markPrimop(misc.flakeRefToString, "flakeRefToString", 1),
|
||||
functionArgs: markPrimop(misc.functionArgs, "functionArgs", 1),
|
||||
genericClosure: markPrimop(misc.genericClosure, "genericClosure", 1),
|
||||
getFlake: markPrimop(misc.getFlake, "getFlake", 1),
|
||||
match: markPrimop(misc.match, "match", 2),
|
||||
outputOf: markPrimop(misc.outputOf, "outputOf", 2),
|
||||
parseDrvName: markPrimop(misc.parseDrvName, "parseDrvName", 1),
|
||||
parseFlakeName: markPrimop(misc.parseFlakeName, "parseFlakeName", 1),
|
||||
placeholder: markPrimop(misc.placeholder, "placeholder", 1),
|
||||
replaceStrings: markPrimop(misc.replaceStrings, "replaceStrings", 3),
|
||||
split: markPrimop(misc.split, "split", 2),
|
||||
splitVersion: markPrimop(misc.splitVersion, "splitVersion", 1),
|
||||
traceVerbose: markPrimop(misc.traceVerbose, "traceVerbose", 2),
|
||||
tryEval: markPrimop(misc.tryEval, "tryEval", 1),
|
||||
zipAttrsWith: markPrimop(misc.zipAttrsWith, "zipAttrsWith", 2),
|
||||
unsafeDiscardStringContext: mkPrimop(misc.unsafeDiscardStringContext, "unsafeDiscardStringContext", 1),
|
||||
unsafeGetAttrPos: mkPrimop(misc.unsafeGetAttrPos, "unsafeGetAttrPos", 2),
|
||||
addDrvOutputDependencies: mkPrimop(misc.addDrvOutputDependencies, "addDrvOutputDependencies", 2),
|
||||
compareVersions: mkPrimop(misc.compareVersions, "compareVersions", 2),
|
||||
dirOf: mkPrimop(misc.dirOf, "dirOf", 1),
|
||||
flakeRefToString: mkPrimop(misc.flakeRefToString, "flakeRefToString", 1),
|
||||
functionArgs: mkPrimop(misc.functionArgs, "functionArgs", 1),
|
||||
genericClosure: mkPrimop(misc.genericClosure, "genericClosure", 1),
|
||||
getFlake: mkPrimop(misc.getFlake, "getFlake", 1),
|
||||
match: mkPrimop(misc.match, "match", 2),
|
||||
outputOf: mkPrimop(misc.outputOf, "outputOf", 2),
|
||||
parseDrvName: mkPrimop(misc.parseDrvName, "parseDrvName", 1),
|
||||
parseFlakeName: mkPrimop(misc.parseFlakeName, "parseFlakeName", 1),
|
||||
parseFlakeRef: mkPrimop(misc.parseFlakeRef, "parseFlakeRef", 1),
|
||||
placeholder: mkPrimop(misc.placeholder, "placeholder", 1),
|
||||
replaceStrings: mkPrimop(misc.replaceStrings, "replaceStrings", 3),
|
||||
split: mkPrimop(misc.split, "split", 2),
|
||||
splitVersion: mkPrimop(misc.splitVersion, "splitVersion", 1),
|
||||
traceVerbose: mkPrimop(misc.traceVerbose, "traceVerbose", 2),
|
||||
tryEval: mkPrimop(misc.tryEval, "tryEval", 1),
|
||||
zipAttrsWith: mkPrimop(misc.zipAttrsWith, "zipAttrsWith", 2),
|
||||
|
||||
builtins: create_thunk(() => builtins),
|
||||
currentSystem: create_thunk(() => {
|
||||
|
||||
@@ -28,10 +28,18 @@ export const scopedImport =
|
||||
throw "Not implemented: scopedImport";
|
||||
};
|
||||
|
||||
export const storePath = (args: NixValue): never => {
|
||||
throw "Not implemented: storePath";
|
||||
};
|
||||
|
||||
export const fetchClosure = (args: NixValue): never => {
|
||||
throw "Not implemented: fetchClosure";
|
||||
};
|
||||
|
||||
export const fetchMercurial = (args: NixValue): never => {
|
||||
throw "Not implemented: fetchMercurial";
|
||||
};
|
||||
|
||||
export const fetchGit = (args: NixValue): never => {
|
||||
throw "Not implemented: fetchGit";
|
||||
};
|
||||
|
||||
@@ -4,6 +4,18 @@
|
||||
|
||||
import type { NixValue } from "../types";
|
||||
|
||||
export const addErrorContext =
|
||||
(e1: NixValue) =>
|
||||
(e2: NixValue): never => {
|
||||
throw "Not implemented: addErrorContext";
|
||||
};
|
||||
|
||||
export const appendContext =
|
||||
(e1: NixValue) =>
|
||||
(e2: NixValue): never => {
|
||||
throw "Not implemented: appendContext";
|
||||
};
|
||||
|
||||
export const getContext = (s: NixValue): never => {
|
||||
throw "Not implemented: getContext";
|
||||
};
|
||||
@@ -90,6 +102,10 @@ export const parseFlakeName = (s: NixValue): never => {
|
||||
throw "Not implemented: parseFlakeName";
|
||||
};
|
||||
|
||||
export const parseFlakeRef = (s: NixValue): never => {
|
||||
throw "Not implemented: parseFlakeRef";
|
||||
};
|
||||
|
||||
export const placeholder = (output: NixValue): never => {
|
||||
throw "Not implemented: placeholder";
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/**
|
||||
* Helper functions for nix-js runtime
|
||||
* Implements attribute selection, parameter validation, and lazy sets
|
||||
*/
|
||||
|
||||
import type { NixValue, NixAttrs } from "./types";
|
||||
|
||||
@@ -5,6 +5,22 @@
|
||||
|
||||
import type { NixValue, NixList, NixAttrs, NixFunction, NixInt, NixFloat, NixNumber } from "./types";
|
||||
import { force } from "./thunk";
|
||||
import { isAttrs } from "./builtins/type-check";
|
||||
|
||||
const typeName = (value: NixValue): string => {
|
||||
const val = force(value);
|
||||
|
||||
if (typeof val === "bigint") return "int";
|
||||
if (typeof val === "number") return "float";
|
||||
if (typeof val === "boolean") return "boolean";
|
||||
if (typeof val === "string") return "string";
|
||||
if (val === null) return "null";
|
||||
if (Array.isArray(val)) return "list";
|
||||
if (typeof val === "function") return "lambda";
|
||||
if (typeof val === "object") return "attribute set";
|
||||
|
||||
throw new TypeError(`Unknown Nix type: ${typeof val}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a value and assert it's a list
|
||||
@@ -13,7 +29,7 @@ import { force } from "./thunk";
|
||||
export const force_list = (value: NixValue): NixList => {
|
||||
const forced = force(value);
|
||||
if (!Array.isArray(forced)) {
|
||||
throw new TypeError(`Expected list, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected list, got ${typeName(forced)}`);
|
||||
}
|
||||
return forced;
|
||||
};
|
||||
@@ -25,7 +41,7 @@ export const force_list = (value: NixValue): NixList => {
|
||||
export const force_function = (value: NixValue): NixFunction => {
|
||||
const forced = force(value);
|
||||
if (typeof forced !== "function") {
|
||||
throw new TypeError(`Expected function, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected function, got ${typeName(forced)}`);
|
||||
}
|
||||
return forced;
|
||||
};
|
||||
@@ -36,10 +52,10 @@ export const force_function = (value: NixValue): NixFunction => {
|
||||
*/
|
||||
export const force_attrs = (value: NixValue): NixAttrs => {
|
||||
const forced = force(value);
|
||||
if (typeof forced !== "object" || forced === null || Array.isArray(forced)) {
|
||||
throw new TypeError(`Expected attribute set, got ${typeof forced}`);
|
||||
if (!isAttrs(forced)) {
|
||||
throw new TypeError(`Expected attribute set, got ${typeName(forced)}`);
|
||||
}
|
||||
return forced as NixAttrs;
|
||||
return forced;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -49,7 +65,7 @@ export const force_attrs = (value: NixValue): NixAttrs => {
|
||||
export const force_string = (value: NixValue): string => {
|
||||
const forced = force(value);
|
||||
if (typeof forced !== "string") {
|
||||
throw new TypeError(`Expected string, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected string, got ${typeName(forced)}`);
|
||||
}
|
||||
return forced;
|
||||
};
|
||||
@@ -61,7 +77,7 @@ export const force_string = (value: NixValue): string => {
|
||||
export const force_bool = (value: NixValue): boolean => {
|
||||
const forced = force(value);
|
||||
if (typeof forced !== "boolean") {
|
||||
throw new TypeError(`Expected boolean, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected boolean, got ${typeName(forced)}`);
|
||||
}
|
||||
return forced;
|
||||
};
|
||||
@@ -75,7 +91,7 @@ export const force_int = (value: NixValue): NixInt => {
|
||||
if (typeof forced === "bigint") {
|
||||
return forced;
|
||||
}
|
||||
throw new TypeError(`Expected int, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected int, got ${typeName(forced)}`);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -87,7 +103,7 @@ export const force_float = (value: NixValue): NixFloat => {
|
||||
if (typeof forced === "number") {
|
||||
return forced;
|
||||
}
|
||||
throw new TypeError(`Expected float, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected float, got ${typeName(forced)}`);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,7 +115,7 @@ export const force_numeric = (value: NixValue): NixNumber => {
|
||||
if (typeof forced === "bigint" || typeof forced === "number") {
|
||||
return forced;
|
||||
}
|
||||
throw new TypeError(`Expected numeric type, got ${typeof forced}`);
|
||||
throw new TypeError(`Expected numeric type, got ${typeName(forced)}`);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
2
nix-js/runtime-ts/src/types/global.d.ts
vendored
2
nix-js/runtime-ts/src/types/global.d.ts
vendored
@@ -1,3 +1,5 @@
|
||||
import type { NixRuntime } from "..";
|
||||
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
|
||||
Reference in New Issue
Block a user