@zwave-js/config 15.15.3 → 15.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/JsonTemplate.js +2 -2
- package/build/cjs/JsonTemplate.js.map +2 -2
- package/build/cjs/Logic.d.ts +1 -1
- package/build/cjs/Logic.js +6 -7
- package/build/cjs/Logic.js.map +2 -2
- package/build/cjs/LogicParser.d.ts +66 -84
- package/build/cjs/LogicParser.js +410 -1337
- package/build/cjs/LogicParser.js.map +3 -3
- package/build/cjs/Manufacturers.js +1 -1
- package/build/cjs/Manufacturers.js.map +2 -2
- package/build/cjs/_version.d.ts +1 -1
- package/build/cjs/_version.js +1 -1
- package/build/cjs/_version.js.map +1 -1
- package/build/cjs/devices/DeviceConfig.d.ts +3 -3
- package/build/cjs/devices/DeviceConfig.js +3 -3
- package/build/cjs/devices/DeviceConfig.js.map +2 -2
- package/build/cjs/devices/DeviceConfig.unit._test.js.map +1 -1
- package/build/cjs/devices/ParamInformation.d.ts +2 -0
- package/build/cjs/devices/ParamInformation.js +16 -2
- package/build/cjs/devices/ParamInformation.js.map +2 -2
- package/build/cjs/index.js.map +2 -2
- package/build/esm/JsonTemplate.js +2 -2
- package/build/esm/JsonTemplate.js.map +1 -1
- package/build/esm/Logic.d.ts +1 -1
- package/build/esm/Logic.d.ts.map +1 -1
- package/build/esm/Logic.js +6 -8
- package/build/esm/Logic.js.map +1 -1
- package/build/esm/LogicParser.d.ts +66 -84
- package/build/esm/LogicParser.d.ts.map +1 -1
- package/build/esm/LogicParser.js +432 -2335
- package/build/esm/LogicParser.js.map +1 -1
- package/build/esm/Manufacturers.js +1 -1
- package/build/esm/Manufacturers.js.map +1 -1
- package/build/esm/_version.d.ts +1 -1
- package/build/esm/_version.js +1 -1
- package/build/esm/devices/DeviceConfig.d.ts +3 -3
- package/build/esm/devices/DeviceConfig.d.ts.map +1 -1
- package/build/esm/devices/DeviceConfig.js +4 -3
- package/build/esm/devices/DeviceConfig.js.map +1 -1
- package/build/esm/devices/DeviceConfig.unit._test.js +1 -0
- package/build/esm/devices/DeviceConfig.unit._test.js.map +1 -1
- package/build/esm/devices/ParamInformation.d.ts +2 -0
- package/build/esm/devices/ParamInformation.d.ts.map +1 -1
- package/build/esm/devices/ParamInformation.js +17 -2
- package/build/esm/devices/ParamInformation.js.map +1 -1
- package/build/esm/index.d.ts.map +1 -1
- package/build/esm/index.js +0 -1
- package/build/esm/index.js.map +1 -1
- package/config/devices/0x003b/be468zp.json +1 -1
- package/config/devices/0x003b/be469.json +2 -3
- package/config/devices/0x003b/be469zp.json +2 -3
- package/config/devices/0x0063/55258_zw4002.json +34 -1
- package/config/devices/0x0090/918.json +101 -0
- package/config/devices/0x0090/hc620.json +4 -0
- package/config/devices/0x0148/cometz_700.json +1 -1
- package/config/devices/0x021d/{ddl240x.json → ddl240x_15hzw.json} +1 -2
- package/config/devices/0x021d/ddl240x_1hzw.json +115 -0
- package/config/devices/0x027a/zse11.json +134 -0
- package/config/devices/0x0460/qlsh-001P10.json +119 -0
- package/config/devices/0x0460/qnpl-0A112.json +4 -0
- package/config/devices/0x0460/qnsw-001P16.json +15 -0
- package/config/devices/0x0460/qnsw-001X16.json +10 -0
- package/config/devices/0x0460/templates/wave_template.json +70 -0
- package/config/devices/0x0460/{qnsw-002P16.json → wave_2pm.json} +22 -1
- package/config/devices/templates/master_template.json +1 -1
- package/config/eslint.config.mjs +24 -19
- package/package.json +10 -12
|
@@ -39,7 +39,7 @@ var import_typeguards = require("alcalzone-shared/typeguards");
|
|
|
39
39
|
var import_json5 = __toESM(require("json5"), 1);
|
|
40
40
|
var import_pathe = __toESM(require("pathe"), 1);
|
|
41
41
|
const IMPORT_KEY = "$import";
|
|
42
|
-
const importSpecifierRegex = /^(?<filename>(?:~\/)?[\w\d
|
|
42
|
+
const importSpecifierRegex = /^(?<filename>(?:~\/)?[\w\d/\\._-]+\.json)?(?:#(?<selector>[\w\d/._-]+(?:\[0x[0-9a-fA-F]+\])?))?$/i;
|
|
43
43
|
const templateCache = /* @__PURE__ */ new Map();
|
|
44
44
|
function clearTemplateCache() {
|
|
45
45
|
templateCache.clear();
|
|
@@ -98,7 +98,7 @@ function select(obj, selector) {
|
|
|
98
98
|
}
|
|
99
99
|
__name(select, "select");
|
|
100
100
|
function getImportStack(visited, selector) {
|
|
101
|
-
const source = [...visited, selector ? `#${selector}` : void 0].
|
|
101
|
+
const source = [...visited, selector ? `#${selector}` : void 0].toReversed().filter((s) => !!s);
|
|
102
102
|
if (source.length > 0) {
|
|
103
103
|
return `
|
|
104
104
|
Import stack: ${source.map((s) => `
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/JsonTemplate.ts"],
|
|
4
|
-
"sourcesContent": ["import { ZWaveError, ZWaveErrorCodes } from \"@zwave-js/core\";\nimport { getErrorMessage, pathExists, readTextFile } from \"@zwave-js/shared\";\nimport type { ReadFile, ReadFileSystemInfo } from \"@zwave-js/shared/bindings\";\nimport { isArray, isObject } from \"alcalzone-shared/typeguards\";\nimport JSON5 from \"json5\";\nimport path from \"pathe\";\n\nconst IMPORT_KEY = \"$import\";\nconst importSpecifierRegex =\n\t/^(?<filename>(?:~\\/)?[\\w\\d\\/\\\\\\._-]+\\.json)?(?:#(?<selector>[\\w\\d\\/\\._-]+(?:\\[0x[0-9a-fA-F]+\\])?))?$/i;\n\ntype FileCache = Map<string, Record<string, unknown>>;\n\n// The template cache is used to speed up cases where the same files get parsed multiple times,\n// e.g. during config file linting. It should be cleared whenever the files need to be loaded fresh\n// from disk, like when creating an index\nconst templateCache: FileCache = new Map();\nexport function clearTemplateCache(): void {\n\ttemplateCache.clear();\n}\n\n/** Parses a JSON file with $import keys and replaces them with the selected objects */\nexport async function readJsonWithTemplate(\n\tfs: ReadFileSystemInfo & ReadFile,\n\tfilename: string,\n\trootDirs?: string | string[],\n): Promise<Record<string, unknown>> {\n\tif (!(await pathExists(fs, filename))) {\n\t\tthrow new ZWaveError(\n\t\t\t`Could not open config file ${filename}: not found!`,\n\t\t\tZWaveErrorCodes.Config_NotFound,\n\t\t);\n\t}\n\n\tif (typeof rootDirs === \"string\") rootDirs = [rootDirs];\n\n\t// Try to use the cached versions of the template files to speed up the loading\n\tconst fileCache = new Map(templateCache);\n\tconst ret = await readJsonWithTemplateInternal(\n\t\tfs,\n\t\tfilename,\n\t\tundefined,\n\t\t[],\n\t\tfileCache,\n\t\trootDirs,\n\t);\n\n\t// Only remember the cached templates, not the individual files to save RAM\n\tfor (const [filename, cached] of fileCache) {\n\t\tif (/[\\\\/]templates[\\\\/]/.test(filename)) {\n\t\t\ttemplateCache.set(filename, cached);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nfunction assertImportSpecifier(\n\tval: unknown,\n\tsource?: string,\n): asserts val is string {\n\tif (typeof val !== \"string\") {\n\t\tthrow new ZWaveError(\n\t\t\t`Invalid import specifier ${String(val)}!${\n\t\t\t\tsource != undefined ? ` Source: ${source}` : \"\"\n\t\t\t}`,\n\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t);\n\t}\n\tif (!importSpecifierRegex.test(val)) {\n\t\tthrow new ZWaveError(\n\t\t\t`Import specifier \"${val}\" is invalid!${\n\t\t\t\tsource != undefined ? ` Source: ${source}` : \"\"\n\t\t\t}`,\n\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t);\n\t}\n}\n\nfunction getImportSpecifier(filename: string, selector?: string): string {\n\tlet ret = filename;\n\tif (selector) ret += `#${selector}`;\n\treturn ret;\n}\n\nfunction select(\n\tobj: Record<string, unknown>,\n\tselector: string,\n): Record<string, unknown> {\n\tlet ret: Record<string, unknown> = obj;\n\tconst selectorParts = selector.split(\"/\").filter((s) => !!s);\n\tfor (const part of selectorParts) {\n\t\t// Special case for paramInformation selectors to select params by #\n\t\tif (isArray(ret)) {\n\t\t\tconst item = (ret as any).find(\n\t\t\t\t(r: any) => isObject(r) && \"#\" in r && r[\"#\"] === part,\n\t\t\t);\n\t\t\tif (item != undefined) {\n\t\t\t\t// Don't copy the param number\n\t\t\t\tconst { [\"#\"]: _, ...rest } = item;\n\t\t\t\tret = rest;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\t// By default select the object property\n\t\tret = (ret as any)[part];\n\t}\n\tif (!isObject(ret)) {\n\t\tthrow new ZWaveError(\n\t\t\t`The import target \"${selector}\" is not an object!`,\n\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t);\n\t}\n\treturn ret;\n}\n\nfunction getImportStack(\n\tvisited: string[],\n\tselector: string | undefined,\n): string {\n\tconst source = [...visited, selector ? `#${selector}` : undefined]\n\t\t.reverse()\n\t\t.filter((s) => !!s) as string[];\n\tif (source.length > 0) {\n\t\treturn `\\nImport stack: ${source.map((s) => `\\n in ${s}`).join(\"\")}`;\n\t}\n\treturn \"\";\n}\n\nasync function readJsonWithTemplateInternal(\n\tfs: ReadFileSystemInfo & ReadFile,\n\tfilename: string,\n\tselector: string | undefined,\n\tvisited: string[],\n\tfileCache: FileCache,\n\trootDirs?: string[],\n): Promise<Record<string, unknown>> {\n\tfilename = path.normalize(filename);\n\n\t// If we're limited by one or more root directories, make sure the file is inside one of those\n\tif (rootDirs) {\n\t\tconst outsideAllRootDirs = rootDirs.every((rootDir) => {\n\t\t\tconst relativeToRoot = path.relative(rootDir, filename);\n\t\t\treturn relativeToRoot.startsWith(\"..\");\n\t\t});\n\n\t\tif (outsideAllRootDirs) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Tried to import config file \"${filename}\" from outside all root directories: ${\n\t\t\t\t\trootDirs\n\t\t\t\t\t\t.map((d) => `\\n\u00B7 ${d}`)\n\t\t\t\t\t\t.join(\"\")\n\t\t\t\t}\n${getImportStack(visited, selector)}`,\n\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst specifier = getImportSpecifier(filename, selector);\n\tif (visited.includes(specifier)) {\n\t\tconst msg = `Circular $import in config files: ${\n\t\t\t[\n\t\t\t\t...visited,\n\t\t\t\tspecifier,\n\t\t\t].join(\" -> \")\n\t\t}\\n`;\n\t\t// process.stderr.write(msg + \"\\n\");\n\t\tthrow new ZWaveError(msg, ZWaveErrorCodes.Config_CircularImport);\n\t}\n\n\tlet json: Record<string, unknown>;\n\tif (fileCache.has(filename)) {\n\t\tjson = fileCache.get(filename)!;\n\t} else {\n\t\ttry {\n\t\t\tconst fileContent = await readTextFile(fs, filename, \"utf8\");\n\t\t\tjson = JSON5.parse(fileContent);\n\t\t\tfileCache.set(filename, json);\n\t\t} catch (e) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Could not parse config file ${filename}: ${\n\t\t\t\t\tgetErrorMessage(\n\t\t\t\t\t\te,\n\t\t\t\t\t)\n\t\t\t\t}${getImportStack(visited, selector)}`,\n\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t);\n\t\t}\n\t}\n\t// Resolve the JSON imports for (a subset) of the file and return the compound file\n\treturn resolveJsonImports(\n\t\tfs,\n\t\tselector ? select(json, selector) : json,\n\t\tfilename,\n\t\t[...visited, specifier],\n\t\tfileCache,\n\t\trootDirs,\n\t);\n}\n\n/** Replaces all `$import` properties in a JSON object with object spreads of the referenced file/property */\nasync function resolveJsonImports(\n\tfs: ReadFileSystemInfo & ReadFile,\n\tjson: Record<string, unknown>,\n\tfilename: string,\n\tvisited: string[],\n\tfileCache: FileCache,\n\trootDirs?: string[],\n): Promise<Record<string, unknown>> {\n\tconst ret: Record<string, unknown> = {};\n\t// Loop through all properties and copy them to the resulting object\n\tfor (const [prop, val] of Object.entries(json)) {\n\t\tif (prop === IMPORT_KEY) {\n\t\t\t// This is an import statement. Make sure we're working with a string\n\t\t\tassertImportSpecifier(val, visited.join(\" -> \"));\n\t\t\tconst { filename: importFilename, selector } = importSpecifierRegex\n\t\t\t\t.exec(val)!.groups!;\n\n\t\t\t// Resolve the correct import path\n\t\t\tlet newFilename: string | undefined;\n\t\t\tif (importFilename) {\n\t\t\t\tif (importFilename.startsWith(\"~/\")) {\n\t\t\t\t\t// This is a special import specifier that is relative to the root directory\n\t\t\t\t\t// Try to find at least one root directory that contains the referenced file\n\t\t\t\t\tif (rootDirs) {\n\t\t\t\t\t\tfor (const rootDir of rootDirs) {\n\t\t\t\t\t\t\tnewFilename = path.join(\n\t\t\t\t\t\t\t\trootDir,\n\t\t\t\t\t\t\t\timportFilename.slice(2),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (await pathExists(fs, newFilename)) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Try the next\n\t\t\t\t\t\t\t\tnewFilename = undefined!;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!newFilename) {\n\t\t\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t\t\t`Could not find the referenced file ${\n\t\t\t\t\t\t\t\t\timportFilename.slice(\n\t\t\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t} in any of the root directories: ${\n\t\t\t\t\t\t\t\t\trootDirs\n\t\t\t\t\t\t\t\t\t\t.map((d) => `\\n\u00B7 ${d}`)\n\t\t\t\t\t\t\t\t\t\t.join(\"\")\n\t\t\t\t\t\t\t\t}\\n${\n\t\t\t\t\t\t\t\t\tgetImportStack(\n\t\t\t\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t\t`An $import specifier cannot start with ~/ when no root directory is defined!${\n\t\t\t\t\t\t\t\tgetImportStack(\n\t\t\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnewFilename = path.join(\n\t\t\t\t\t\tpath.dirname(filename),\n\t\t\t\t\t\timportFilename,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewFilename = filename;\n\t\t\t}\n\n\t\t\t// const importFilename = path.join(path.dirname(filename), val);\n\t\t\tconst imported = await readJsonWithTemplateInternal(\n\t\t\t\tfs,\n\t\t\t\tnewFilename,\n\t\t\t\tselector,\n\t\t\t\tvisited,\n\t\t\t\tfileCache,\n\t\t\t\trootDirs,\n\t\t\t);\n\t\t\tObject.assign(ret, imported);\n\t\t} else if (isObject(val)) {\n\t\t\t// We're looking at an object, recurse into it\n\t\t\tret[prop] = await resolveJsonImports(\n\t\t\t\tfs,\n\t\t\t\tval,\n\t\t\t\tfilename,\n\t\t\t\tvisited,\n\t\t\t\tfileCache,\n\t\t\t\trootDirs,\n\t\t\t);\n\t\t} else if (isArray(val)) {\n\t\t\t// We're looking at an array, check if there are objects we need to recurse into\n\t\t\tconst vals: unknown[] = [];\n\t\t\tfor (const v of val) {\n\t\t\t\tif (isObject(v)) {\n\t\t\t\t\tvals.push(\n\t\t\t\t\t\tawait resolveJsonImports(\n\t\t\t\t\t\t\tfs,\n\t\t\t\t\t\t\tv,\n\t\t\t\t\t\t\tfilename,\n\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\tfileCache,\n\t\t\t\t\t\t\trootDirs,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tvals.push(v);\n\t\t\t\t}\n\t\t\t}\n\t\t\tret[prop] = vals;\n\t\t} else {\n\t\t\tret[prop] = val;\n\t\t}\n\t}\n\treturn ret;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;AAAA,kBAA4C;AAC5C,oBAA0D;AAE1D,wBAAkC;AAClC,mBAAkB;AAClB,mBAAiB;AAEjB,MAAM,aAAa;AACnB,MAAM,uBACL;AAOD,MAAM,gBAA2B,oBAAI,IAAG;AAClC,SAAU,qBAAkB;AACjC,gBAAc,MAAK;AACpB;AAFgB;AAKhB,eAAsB,qBACrB,IACA,UACA,UAA4B;AAE5B,MAAI,CAAE,UAAM,0BAAW,IAAI,QAAQ,GAAI;AACtC,UAAM,IAAI,uBACT,8BAA8B,QAAQ,gBACtC,4BAAgB,eAAe;EAEjC;AAEA,MAAI,OAAO,aAAa;AAAU,eAAW,CAAC,QAAQ;AAGtD,QAAM,YAAY,IAAI,IAAI,aAAa;AACvC,QAAM,MAAM,MAAM,6BACjB,IACA,UACA,QACA,CAAA,GACA,WACA,QAAQ;AAIT,aAAW,CAACA,WAAU,MAAM,KAAK,WAAW;AAC3C,QAAI,sBAAsB,KAAKA,SAAQ,GAAG;AACzC,oBAAc,IAAIA,WAAU,MAAM;IACnC;EACD;AAEA,SAAO;AACR;AAjCsB;AAmCtB,SAAS,sBACR,KACA,QAAe;AAEf,MAAI,OAAO,QAAQ,UAAU;AAC5B,UAAM,IAAI,uBACT,4BAA4B,OAAO,GAAG,CAAC,IACtC,UAAU,SAAY,YAAY,MAAM,KAAK,EAC9C,IACA,4BAAgB,cAAc;EAEhC;AACA,MAAI,CAAC,qBAAqB,KAAK,GAAG,GAAG;AACpC,UAAM,IAAI,uBACT,qBAAqB,GAAG,gBACvB,UAAU,SAAY,YAAY,MAAM,KAAK,EAC9C,IACA,4BAAgB,cAAc;EAEhC;AACD;AApBS;AAsBT,SAAS,mBAAmB,UAAkB,UAAiB;AAC9D,MAAI,MAAM;AACV,MAAI;AAAU,WAAO,IAAI,QAAQ;AACjC,SAAO;AACR;AAJS;AAMT,SAAS,OACR,KACA,UAAgB;AAEhB,MAAI,MAA+B;AACnC,QAAM,gBAAgB,SAAS,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,aAAW,QAAQ,eAAe;AAEjC,YAAI,2BAAQ,GAAG,GAAG;AACjB,YAAM,OAAQ,IAAY,KACzB,CAAC,UAAW,4BAAS,CAAC,KAAK,OAAO,KAAK,EAAE,GAAG,MAAM,IAAI;AAEvD,UAAI,QAAQ,QAAW;AAEtB,cAAM,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG,KAAI,IAAK;AAC9B,cAAM;AACN;MACD;IACD;AAEA,UAAO,IAAY,IAAI;EACxB;AACA,MAAI,KAAC,4BAAS,GAAG,GAAG;AACnB,UAAM,IAAI,uBACT,sBAAsB,QAAQ,uBAC9B,4BAAgB,cAAc;EAEhC;AACA,SAAO;AACR;AA7BS;AA+BT,SAAS,eACR,SACA,UAA4B;AAE5B,QAAM,SAAS,CAAC,GAAG,SAAS,WAAW,IAAI,QAAQ,KAAK,MAAS,EAC/D,
|
|
4
|
+
"sourcesContent": ["import { ZWaveError, ZWaveErrorCodes } from \"@zwave-js/core\";\nimport { getErrorMessage, pathExists, readTextFile } from \"@zwave-js/shared\";\nimport type { ReadFile, ReadFileSystemInfo } from \"@zwave-js/shared/bindings\";\nimport { isArray, isObject } from \"alcalzone-shared/typeguards\";\nimport JSON5 from \"json5\";\nimport path from \"pathe\";\n\nconst IMPORT_KEY = \"$import\";\nconst importSpecifierRegex =\n\t/^(?<filename>(?:~\\/)?[\\w\\d/\\\\._-]+\\.json)?(?:#(?<selector>[\\w\\d/._-]+(?:\\[0x[0-9a-fA-F]+\\])?))?$/i;\n\ntype FileCache = Map<string, Record<string, unknown>>;\n\n// The template cache is used to speed up cases where the same files get parsed multiple times,\n// e.g. during config file linting. It should be cleared whenever the files need to be loaded fresh\n// from disk, like when creating an index\nconst templateCache: FileCache = new Map();\nexport function clearTemplateCache(): void {\n\ttemplateCache.clear();\n}\n\n/** Parses a JSON file with $import keys and replaces them with the selected objects */\nexport async function readJsonWithTemplate(\n\tfs: ReadFileSystemInfo & ReadFile,\n\tfilename: string,\n\trootDirs?: string | string[],\n): Promise<Record<string, unknown>> {\n\tif (!(await pathExists(fs, filename))) {\n\t\tthrow new ZWaveError(\n\t\t\t`Could not open config file ${filename}: not found!`,\n\t\t\tZWaveErrorCodes.Config_NotFound,\n\t\t);\n\t}\n\n\tif (typeof rootDirs === \"string\") rootDirs = [rootDirs];\n\n\t// Try to use the cached versions of the template files to speed up the loading\n\tconst fileCache = new Map(templateCache);\n\tconst ret = await readJsonWithTemplateInternal(\n\t\tfs,\n\t\tfilename,\n\t\tundefined,\n\t\t[],\n\t\tfileCache,\n\t\trootDirs,\n\t);\n\n\t// Only remember the cached templates, not the individual files to save RAM\n\tfor (const [filename, cached] of fileCache) {\n\t\tif (/[\\\\/]templates[\\\\/]/.test(filename)) {\n\t\t\ttemplateCache.set(filename, cached);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nfunction assertImportSpecifier(\n\tval: unknown,\n\tsource?: string,\n): asserts val is string {\n\tif (typeof val !== \"string\") {\n\t\tthrow new ZWaveError(\n\t\t\t`Invalid import specifier ${String(val)}!${\n\t\t\t\tsource != undefined ? ` Source: ${source}` : \"\"\n\t\t\t}`,\n\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t);\n\t}\n\tif (!importSpecifierRegex.test(val)) {\n\t\tthrow new ZWaveError(\n\t\t\t`Import specifier \"${val}\" is invalid!${\n\t\t\t\tsource != undefined ? ` Source: ${source}` : \"\"\n\t\t\t}`,\n\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t);\n\t}\n}\n\nfunction getImportSpecifier(filename: string, selector?: string): string {\n\tlet ret = filename;\n\tif (selector) ret += `#${selector}`;\n\treturn ret;\n}\n\nfunction select(\n\tobj: Record<string, unknown>,\n\tselector: string,\n): Record<string, unknown> {\n\tlet ret: Record<string, unknown> = obj;\n\tconst selectorParts = selector.split(\"/\").filter((s) => !!s);\n\tfor (const part of selectorParts) {\n\t\t// Special case for paramInformation selectors to select params by #\n\t\tif (isArray(ret)) {\n\t\t\tconst item = (ret as any).find(\n\t\t\t\t(r: any) => isObject(r) && \"#\" in r && r[\"#\"] === part,\n\t\t\t);\n\t\t\tif (item != undefined) {\n\t\t\t\t// Don't copy the param number\n\t\t\t\tconst { [\"#\"]: _, ...rest } = item;\n\t\t\t\tret = rest;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\t// By default select the object property\n\t\tret = (ret as any)[part];\n\t}\n\tif (!isObject(ret)) {\n\t\tthrow new ZWaveError(\n\t\t\t`The import target \"${selector}\" is not an object!`,\n\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t);\n\t}\n\treturn ret;\n}\n\nfunction getImportStack(\n\tvisited: string[],\n\tselector: string | undefined,\n): string {\n\tconst source = [...visited, selector ? `#${selector}` : undefined]\n\t\t.toReversed()\n\t\t.filter((s) => !!s) as string[];\n\tif (source.length > 0) {\n\t\treturn `\\nImport stack: ${source.map((s) => `\\n in ${s}`).join(\"\")}`;\n\t}\n\treturn \"\";\n}\n\nasync function readJsonWithTemplateInternal(\n\tfs: ReadFileSystemInfo & ReadFile,\n\tfilename: string,\n\tselector: string | undefined,\n\tvisited: string[],\n\tfileCache: FileCache,\n\trootDirs?: string[],\n): Promise<Record<string, unknown>> {\n\tfilename = path.normalize(filename);\n\n\t// If we're limited by one or more root directories, make sure the file is inside one of those\n\tif (rootDirs) {\n\t\tconst outsideAllRootDirs = rootDirs.every((rootDir) => {\n\t\t\tconst relativeToRoot = path.relative(rootDir, filename);\n\t\t\treturn relativeToRoot.startsWith(\"..\");\n\t\t});\n\n\t\tif (outsideAllRootDirs) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Tried to import config file \"${filename}\" from outside all root directories: ${\n\t\t\t\t\trootDirs\n\t\t\t\t\t\t.map((d) => `\\n\u00B7 ${d}`)\n\t\t\t\t\t\t.join(\"\")\n\t\t\t\t}\n${getImportStack(visited, selector)}`,\n\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst specifier = getImportSpecifier(filename, selector);\n\tif (visited.includes(specifier)) {\n\t\tconst msg = `Circular $import in config files: ${\n\t\t\t[\n\t\t\t\t...visited,\n\t\t\t\tspecifier,\n\t\t\t].join(\" -> \")\n\t\t}\\n`;\n\t\t// process.stderr.write(msg + \"\\n\");\n\t\tthrow new ZWaveError(msg, ZWaveErrorCodes.Config_CircularImport);\n\t}\n\n\tlet json: Record<string, unknown>;\n\tif (fileCache.has(filename)) {\n\t\tjson = fileCache.get(filename)!;\n\t} else {\n\t\ttry {\n\t\t\tconst fileContent = await readTextFile(fs, filename, \"utf8\");\n\t\t\tjson = JSON5.parse(fileContent);\n\t\t\tfileCache.set(filename, json);\n\t\t} catch (e) {\n\t\t\tthrow new ZWaveError(\n\t\t\t\t`Could not parse config file ${filename}: ${\n\t\t\t\t\tgetErrorMessage(\n\t\t\t\t\t\te,\n\t\t\t\t\t)\n\t\t\t\t}${getImportStack(visited, selector)}`,\n\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t);\n\t\t}\n\t}\n\t// Resolve the JSON imports for (a subset) of the file and return the compound file\n\treturn resolveJsonImports(\n\t\tfs,\n\t\tselector ? select(json, selector) : json,\n\t\tfilename,\n\t\t[...visited, specifier],\n\t\tfileCache,\n\t\trootDirs,\n\t);\n}\n\n/** Replaces all `$import` properties in a JSON object with object spreads of the referenced file/property */\nasync function resolveJsonImports(\n\tfs: ReadFileSystemInfo & ReadFile,\n\tjson: Record<string, unknown>,\n\tfilename: string,\n\tvisited: string[],\n\tfileCache: FileCache,\n\trootDirs?: string[],\n): Promise<Record<string, unknown>> {\n\tconst ret: Record<string, unknown> = {};\n\t// Loop through all properties and copy them to the resulting object\n\tfor (const [prop, val] of Object.entries(json)) {\n\t\tif (prop === IMPORT_KEY) {\n\t\t\t// This is an import statement. Make sure we're working with a string\n\t\t\tassertImportSpecifier(val, visited.join(\" -> \"));\n\t\t\tconst { filename: importFilename, selector } = importSpecifierRegex\n\t\t\t\t.exec(val)!.groups!;\n\n\t\t\t// Resolve the correct import path\n\t\t\tlet newFilename: string | undefined;\n\t\t\tif (importFilename) {\n\t\t\t\tif (importFilename.startsWith(\"~/\")) {\n\t\t\t\t\t// This is a special import specifier that is relative to the root directory\n\t\t\t\t\t// Try to find at least one root directory that contains the referenced file\n\t\t\t\t\tif (rootDirs) {\n\t\t\t\t\t\tfor (const rootDir of rootDirs) {\n\t\t\t\t\t\t\tnewFilename = path.join(\n\t\t\t\t\t\t\t\trootDir,\n\t\t\t\t\t\t\t\timportFilename.slice(2),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (await pathExists(fs, newFilename)) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Try the next\n\t\t\t\t\t\t\t\tnewFilename = undefined!;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!newFilename) {\n\t\t\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t\t\t`Could not find the referenced file ${\n\t\t\t\t\t\t\t\t\timportFilename.slice(\n\t\t\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t} in any of the root directories: ${\n\t\t\t\t\t\t\t\t\trootDirs\n\t\t\t\t\t\t\t\t\t\t.map((d) => `\\n\u00B7 ${d}`)\n\t\t\t\t\t\t\t\t\t\t.join(\"\")\n\t\t\t\t\t\t\t\t}\\n${\n\t\t\t\t\t\t\t\t\tgetImportStack(\n\t\t\t\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new ZWaveError(\n\t\t\t\t\t\t\t`An $import specifier cannot start with ~/ when no root directory is defined!${\n\t\t\t\t\t\t\t\tgetImportStack(\n\t\t\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\t\t\tselector,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\tZWaveErrorCodes.Config_Invalid,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnewFilename = path.join(\n\t\t\t\t\t\tpath.dirname(filename),\n\t\t\t\t\t\timportFilename,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewFilename = filename;\n\t\t\t}\n\n\t\t\t// const importFilename = path.join(path.dirname(filename), val);\n\t\t\tconst imported = await readJsonWithTemplateInternal(\n\t\t\t\tfs,\n\t\t\t\tnewFilename,\n\t\t\t\tselector,\n\t\t\t\tvisited,\n\t\t\t\tfileCache,\n\t\t\t\trootDirs,\n\t\t\t);\n\t\t\tObject.assign(ret, imported);\n\t\t} else if (isObject(val)) {\n\t\t\t// We're looking at an object, recurse into it\n\t\t\tret[prop] = await resolveJsonImports(\n\t\t\t\tfs,\n\t\t\t\tval,\n\t\t\t\tfilename,\n\t\t\t\tvisited,\n\t\t\t\tfileCache,\n\t\t\t\trootDirs,\n\t\t\t);\n\t\t} else if (isArray(val)) {\n\t\t\t// We're looking at an array, check if there are objects we need to recurse into\n\t\t\tconst vals: unknown[] = [];\n\t\t\tfor (const v of val) {\n\t\t\t\tif (isObject(v)) {\n\t\t\t\t\tvals.push(\n\t\t\t\t\t\tawait resolveJsonImports(\n\t\t\t\t\t\t\tfs,\n\t\t\t\t\t\t\tv,\n\t\t\t\t\t\t\tfilename,\n\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\tfileCache,\n\t\t\t\t\t\t\trootDirs,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tvals.push(v);\n\t\t\t\t}\n\t\t\t}\n\t\t\tret[prop] = vals;\n\t\t} else {\n\t\t\tret[prop] = val;\n\t\t}\n\t}\n\treturn ret;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;AAAA,kBAA4C;AAC5C,oBAA0D;AAE1D,wBAAkC;AAClC,mBAAkB;AAClB,mBAAiB;AAEjB,MAAM,aAAa;AACnB,MAAM,uBACL;AAOD,MAAM,gBAA2B,oBAAI,IAAG;AAClC,SAAU,qBAAkB;AACjC,gBAAc,MAAK;AACpB;AAFgB;AAKhB,eAAsB,qBACrB,IACA,UACA,UAA4B;AAE5B,MAAI,CAAE,UAAM,0BAAW,IAAI,QAAQ,GAAI;AACtC,UAAM,IAAI,uBACT,8BAA8B,QAAQ,gBACtC,4BAAgB,eAAe;EAEjC;AAEA,MAAI,OAAO,aAAa;AAAU,eAAW,CAAC,QAAQ;AAGtD,QAAM,YAAY,IAAI,IAAI,aAAa;AACvC,QAAM,MAAM,MAAM,6BACjB,IACA,UACA,QACA,CAAA,GACA,WACA,QAAQ;AAIT,aAAW,CAACA,WAAU,MAAM,KAAK,WAAW;AAC3C,QAAI,sBAAsB,KAAKA,SAAQ,GAAG;AACzC,oBAAc,IAAIA,WAAU,MAAM;IACnC;EACD;AAEA,SAAO;AACR;AAjCsB;AAmCtB,SAAS,sBACR,KACA,QAAe;AAEf,MAAI,OAAO,QAAQ,UAAU;AAC5B,UAAM,IAAI,uBACT,4BAA4B,OAAO,GAAG,CAAC,IACtC,UAAU,SAAY,YAAY,MAAM,KAAK,EAC9C,IACA,4BAAgB,cAAc;EAEhC;AACA,MAAI,CAAC,qBAAqB,KAAK,GAAG,GAAG;AACpC,UAAM,IAAI,uBACT,qBAAqB,GAAG,gBACvB,UAAU,SAAY,YAAY,MAAM,KAAK,EAC9C,IACA,4BAAgB,cAAc;EAEhC;AACD;AApBS;AAsBT,SAAS,mBAAmB,UAAkB,UAAiB;AAC9D,MAAI,MAAM;AACV,MAAI;AAAU,WAAO,IAAI,QAAQ;AACjC,SAAO;AACR;AAJS;AAMT,SAAS,OACR,KACA,UAAgB;AAEhB,MAAI,MAA+B;AACnC,QAAM,gBAAgB,SAAS,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3D,aAAW,QAAQ,eAAe;AAEjC,YAAI,2BAAQ,GAAG,GAAG;AACjB,YAAM,OAAQ,IAAY,KACzB,CAAC,UAAW,4BAAS,CAAC,KAAK,OAAO,KAAK,EAAE,GAAG,MAAM,IAAI;AAEvD,UAAI,QAAQ,QAAW;AAEtB,cAAM,EAAE,CAAC,GAAG,GAAG,GAAG,GAAG,KAAI,IAAK;AAC9B,cAAM;AACN;MACD;IACD;AAEA,UAAO,IAAY,IAAI;EACxB;AACA,MAAI,KAAC,4BAAS,GAAG,GAAG;AACnB,UAAM,IAAI,uBACT,sBAAsB,QAAQ,uBAC9B,4BAAgB,cAAc;EAEhC;AACA,SAAO;AACR;AA7BS;AA+BT,SAAS,eACR,SACA,UAA4B;AAE5B,QAAM,SAAS,CAAC,GAAG,SAAS,WAAW,IAAI,QAAQ,KAAK,MAAS,EAC/D,WAAU,EACV,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACnB,MAAI,OAAO,SAAS,GAAG;AACtB,WAAO;gBAAmB,OAAO,IAAI,CAAC,MAAM;OAAU,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;EACpE;AACA,SAAO;AACR;AAXS;AAaT,eAAe,6BACd,IACA,UACA,UACA,SACA,WACA,UAAmB;AAEnB,aAAW,aAAAC,QAAK,UAAU,QAAQ;AAGlC,MAAI,UAAU;AACb,UAAM,qBAAqB,SAAS,MAAM,CAAC,YAAW;AACrD,YAAM,iBAAiB,aAAAA,QAAK,SAAS,SAAS,QAAQ;AACtD,aAAO,eAAe,WAAW,IAAI;IACtC,CAAC;AAED,QAAI,oBAAoB;AACvB,YAAM,IAAI,uBACT,gCAAgC,QAAQ,wCACvC,SACE,IAAI,CAAC,MAAM;OAAO,CAAC,EAAE,EACrB,KAAK,EAAE,CACV;EACF,eAAe,SAAS,QAAQ,CAAC,IAC/B,4BAAgB,cAAc;IAEhC;EACD;AAEA,QAAM,YAAY,mBAAmB,UAAU,QAAQ;AACvD,MAAI,QAAQ,SAAS,SAAS,GAAG;AAChC,UAAM,MAAM,qCACX;MACC,GAAG;MACH;MACC,KAAK,MAAM,CACd;;AAEA,UAAM,IAAI,uBAAW,KAAK,4BAAgB,qBAAqB;EAChE;AAEA,MAAI;AACJ,MAAI,UAAU,IAAI,QAAQ,GAAG;AAC5B,WAAO,UAAU,IAAI,QAAQ;EAC9B,OAAO;AACN,QAAI;AACH,YAAM,cAAc,UAAM,4BAAa,IAAI,UAAU,MAAM;AAC3D,aAAO,aAAAC,QAAM,MAAM,WAAW;AAC9B,gBAAU,IAAI,UAAU,IAAI;IAC7B,SAAS,GAAG;AACX,YAAM,IAAI,uBACT,+BAA+B,QAAQ,SACtC,+BACC,CAAC,CAEH,GAAG,eAAe,SAAS,QAAQ,CAAC,IACpC,4BAAgB,cAAc;IAEhC;EACD;AAEA,SAAO,mBACN,IACA,WAAW,OAAO,MAAM,QAAQ,IAAI,MACpC,UACA,CAAC,GAAG,SAAS,SAAS,GACtB,WACA,QAAQ;AAEV;AAtEe;AAyEf,eAAe,mBACd,IACA,MACA,UACA,SACA,WACA,UAAmB;AAEnB,QAAM,MAA+B,CAAA;AAErC,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,SAAS,YAAY;AAExB,4BAAsB,KAAK,QAAQ,KAAK,MAAM,CAAC;AAC/C,YAAM,EAAE,UAAU,gBAAgB,SAAQ,IAAK,qBAC7C,KAAK,GAAG,EAAG;AAGb,UAAI;AACJ,UAAI,gBAAgB;AACnB,YAAI,eAAe,WAAW,IAAI,GAAG;AAGpC,cAAI,UAAU;AACb,uBAAW,WAAW,UAAU;AAC/B,4BAAc,aAAAD,QAAK,KAClB,SACA,eAAe,MAAM,CAAC,CAAC;AAExB,kBAAI,UAAM,0BAAW,IAAI,WAAW,GAAG;AACtC;cACD,OAAO;AAEN,8BAAc;cACf;YACD;AAEA,gBAAI,CAAC,aAAa;AACjB,oBAAM,IAAI,uBACT,sCACC,eAAe,MACd,CAAC,CAEH,oCACC,SACE,IAAI,CAAC,MAAM;OAAO,CAAC,EAAE,EACrB,KAAK,EAAE,CACV;EACC,eACC,SACA,QAAQ,CAEV,IACA,4BAAgB,cAAc;YAEhC;UACD,OAAO;AACN,kBAAM,IAAI,uBACT,+EACC,eACC,SACA,QAAQ,CAEV,IACA,4BAAgB,cAAc;UAEhC;QACD,OAAO;AACN,wBAAc,aAAAA,QAAK,KAClB,aAAAA,QAAK,QAAQ,QAAQ,GACrB,cAAc;QAEhB;MACD,OAAO;AACN,sBAAc;MACf;AAGA,YAAM,WAAW,MAAM,6BACtB,IACA,aACA,UACA,SACA,WACA,QAAQ;AAET,aAAO,OAAO,KAAK,QAAQ;IAC5B,eAAW,4BAAS,GAAG,GAAG;AAEzB,UAAI,IAAI,IAAI,MAAM,mBACjB,IACA,KACA,UACA,SACA,WACA,QAAQ;IAEV,eAAW,2BAAQ,GAAG,GAAG;AAExB,YAAM,OAAkB,CAAA;AACxB,iBAAW,KAAK,KAAK;AACpB,gBAAI,4BAAS,CAAC,GAAG;AAChB,eAAK,KACJ,MAAM,mBACL,IACA,GACA,UACA,SACA,WACA,QAAQ,CACR;QAEH,OAAO;AACN,eAAK,KAAK,CAAC;QACZ;MACD;AACA,UAAI,IAAI,IAAI;IACb,OAAO;AACN,UAAI,IAAI,IAAI;IACb;EACD;AACA,SAAO;AACR;AA1He;",
|
|
6
6
|
"names": ["filename", "path", "JSON5"]
|
|
7
7
|
}
|
package/build/cjs/Logic.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type RulesLogic } from "json-logic-js";
|
|
2
|
-
export declare function parseLogic(
|
|
2
|
+
export declare function parseLogic(input: string): RulesLogic;
|
|
3
3
|
export declare function evaluate(logic: string, context: unknown): string | number | boolean;
|
|
4
4
|
//# sourceMappingURL=Logic.d.ts.map
|
package/build/cjs/Logic.js
CHANGED
|
@@ -39,8 +39,8 @@ var import_gt = __toESM(require("semver/functions/gt.js"), 1);
|
|
|
39
39
|
var import_gte = __toESM(require("semver/functions/gte.js"), 1);
|
|
40
40
|
var import_lt = __toESM(require("semver/functions/lt.js"), 1);
|
|
41
41
|
var import_lte = __toESM(require("semver/functions/lte.js"), 1);
|
|
42
|
-
var import_LogicParser = require("./LogicParser.js");
|
|
43
42
|
var import_json_logic_js = __toESM(require("json-logic-js"), 1);
|
|
43
|
+
var import_LogicParser = require("./LogicParser.js");
|
|
44
44
|
const { add_operation, apply } = import_json_logic_js.default;
|
|
45
45
|
function tryOr(operation, onError) {
|
|
46
46
|
return ((...args) => {
|
|
@@ -57,13 +57,12 @@ add_operation("ver >", tryOr((a, b) => (0, import_gt.default)((0, import_shared.
|
|
|
57
57
|
add_operation("ver <=", tryOr((a, b) => (0, import_lte.default)((0, import_shared.padVersion)(a), (0, import_shared.padVersion)(b)), false));
|
|
58
58
|
add_operation("ver <", tryOr((a, b) => (0, import_lt.default)((0, import_shared.padVersion)(a), (0, import_shared.padVersion)(b)), false));
|
|
59
59
|
add_operation("ver ===", tryOr((a, b) => (0, import_eq.default)((0, import_shared.padVersion)(a), (0, import_shared.padVersion)(b)), false));
|
|
60
|
-
function parseLogic(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
throw new Error(`Invalid logic: ${logic}
|
|
65
|
-
${e.message}`);
|
|
60
|
+
function parseLogic(input) {
|
|
61
|
+
const expr = (0, import_LogicParser.parse)(input);
|
|
62
|
+
if (!expr) {
|
|
63
|
+
throw new Error(`Failed to parse expression: ${input}`);
|
|
66
64
|
}
|
|
65
|
+
return (0, import_LogicParser.toRulesLogic)(expr);
|
|
67
66
|
}
|
|
68
67
|
__name(parseLogic, "parseLogic");
|
|
69
68
|
function evaluate(logic, context) {
|
package/build/cjs/Logic.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/Logic.ts"],
|
|
4
|
-
"sourcesContent": ["import { padVersion } from \"@zwave-js/shared\";\nimport semverEq from \"semver/functions/eq.js\";\nimport semverGt from \"semver/functions/gt.js\";\nimport semverGte from \"semver/functions/gte.js\";\nimport semverLt from \"semver/functions/lt.js\";\nimport semverLte from \"semver/functions/lte.js\";\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;AAAA,oBAA2B;AAC3B,gBAAqB;AACrB,gBAAqB;AACrB,iBAAsB;AACtB,gBAAqB;AACrB,iBAAsB;
|
|
4
|
+
"sourcesContent": ["import { padVersion } from \"@zwave-js/shared\";\nimport semverEq from \"semver/functions/eq.js\";\nimport semverGt from \"semver/functions/gt.js\";\nimport semverGte from \"semver/functions/gte.js\";\nimport semverLt from \"semver/functions/lt.js\";\nimport semverLte from \"semver/functions/lte.js\";\n\n// The types are not correct:\nimport { type RulesLogic, default as JsonLogic } from \"json-logic-js\";\nimport { parse, toRulesLogic } from \"./LogicParser.js\";\nconst { add_operation, apply } = JsonLogic;\n\nfunction tryOr<T extends (...args: any[]) => any>(\n\toperation: T,\n\tonError: ReturnType<T>,\n): T {\n\treturn ((...args: any[]) => {\n\t\ttry {\n\t\t\treturn operation(...args);\n\t\t} catch {\n\t\t\treturn onError;\n\t\t}\n\t}) as any as T;\n}\n\nadd_operation(\n\t\"ver >=\",\n\ttryOr((a, b) => semverGte(padVersion(a), padVersion(b)), false),\n);\nadd_operation(\n\t\"ver >\",\n\ttryOr((a, b) => semverGt(padVersion(a), padVersion(b)), false),\n);\nadd_operation(\n\t\"ver <=\",\n\ttryOr((a, b) => semverLte(padVersion(a), padVersion(b)), false),\n);\nadd_operation(\n\t\"ver <\",\n\ttryOr((a, b) => semverLt(padVersion(a), padVersion(b)), false),\n);\nadd_operation(\n\t\"ver ===\",\n\ttryOr((a, b) => semverEq(padVersion(a), padVersion(b)), false),\n);\n\nexport function parseLogic(input: string): RulesLogic {\n\tconst expr = parse(input);\n\tif (!expr) {\n\t\tthrow new Error(`Failed to parse expression: ${input}`);\n\t}\n\treturn toRulesLogic(expr);\n}\n\nexport function evaluate(\n\tlogic: string,\n\tcontext: unknown,\n): string | number | boolean {\n\tconst rules = parseLogic(logic);\n\treturn apply(rules, context);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;AAAA,oBAA2B;AAC3B,gBAAqB;AACrB,gBAAqB;AACrB,iBAAsB;AACtB,gBAAqB;AACrB,iBAAsB;AAGtB,2BAAsD;AACtD,yBAAoC;AACpC,MAAM,EAAE,eAAe,MAAK,IAAK,qBAAAA;AAEjC,SAAS,MACR,WACA,SAAsB;AAEtB,UAAQ,IAAI,SAAe;AAC1B,QAAI;AACH,aAAO,UAAU,GAAG,IAAI;IACzB,QAAQ;AACP,aAAO;IACR;EACD;AACD;AAXS;AAaT,cACC,UACA,MAAM,CAAC,GAAG,UAAM,WAAAC,aAAU,0BAAW,CAAC,OAAG,0BAAW,CAAC,CAAC,GAAG,KAAK,CAAC;AAEhE,cACC,SACA,MAAM,CAAC,GAAG,UAAM,UAAAC,aAAS,0BAAW,CAAC,OAAG,0BAAW,CAAC,CAAC,GAAG,KAAK,CAAC;AAE/D,cACC,UACA,MAAM,CAAC,GAAG,UAAM,WAAAC,aAAU,0BAAW,CAAC,OAAG,0BAAW,CAAC,CAAC,GAAG,KAAK,CAAC;AAEhE,cACC,SACA,MAAM,CAAC,GAAG,UAAM,UAAAC,aAAS,0BAAW,CAAC,OAAG,0BAAW,CAAC,CAAC,GAAG,KAAK,CAAC;AAE/D,cACC,WACA,MAAM,CAAC,GAAG,UAAM,UAAAC,aAAS,0BAAW,CAAC,OAAG,0BAAW,CAAC,CAAC,GAAG,KAAK,CAAC;AAGzD,SAAU,WAAW,OAAa;AACvC,QAAM,WAAO,0BAAM,KAAK;AACxB,MAAI,CAAC,MAAM;AACV,UAAM,IAAI,MAAM,+BAA+B,KAAK,EAAE;EACvD;AACA,aAAO,iCAAa,IAAI;AACzB;AANgB;AAQV,SAAU,SACf,OACA,SAAgB;AAEhB,QAAM,QAAQ,WAAW,KAAK;AAC9B,SAAO,MAAM,OAAO,OAAO;AAC5B;AANgB;",
|
|
6
6
|
"names": ["JsonLogic", "semverGte", "semverGt", "semverLte", "semverLt", "semverEq"]
|
|
7
7
|
}
|
|
@@ -1,93 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { RulesLogic } from "json-logic-js";
|
|
2
|
+
export declare enum SyntaxKind {
|
|
3
|
+
Group = 0,
|
|
4
|
+
Or = 1,
|
|
5
|
+
And = 2,
|
|
6
|
+
Comparison = 3,
|
|
7
|
+
Identifier = 4,
|
|
8
|
+
NumberLiteral = 5,
|
|
9
|
+
Version = 6
|
|
5
10
|
}
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
export declare enum Operator {
|
|
12
|
+
Equal = 0,
|
|
13
|
+
NotEqual = 1,
|
|
14
|
+
LessThan = 2,
|
|
15
|
+
LessThanOrEqual = 3,
|
|
16
|
+
GreaterThan = 4,
|
|
17
|
+
GreaterThanOrEqual = 5
|
|
10
18
|
}
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
export interface ClassParts extends Array<string | ClassParts> {
|
|
17
|
-
}
|
|
18
|
-
export interface ClassExpectation {
|
|
19
|
-
type: "class";
|
|
20
|
-
parts: ClassParts;
|
|
21
|
-
inverted: boolean;
|
|
22
|
-
ignoreCase: boolean;
|
|
23
|
-
}
|
|
24
|
-
export interface AnyExpectation {
|
|
25
|
-
type: "any";
|
|
26
|
-
}
|
|
27
|
-
export interface EndExpectation {
|
|
28
|
-
type: "end";
|
|
29
|
-
}
|
|
30
|
-
export interface OtherExpectation {
|
|
31
|
-
type: "other";
|
|
32
|
-
description: string;
|
|
33
|
-
}
|
|
34
|
-
export type Expectation = LiteralExpectation | ClassExpectation | AnyExpectation | EndExpectation | OtherExpectation;
|
|
35
|
-
declare class _PeggySyntaxError extends Error {
|
|
36
|
-
static buildMessage(expected: Expectation[], found: string | null): string;
|
|
37
|
-
message: string;
|
|
38
|
-
expected: Expectation[];
|
|
39
|
-
found: string | null;
|
|
40
|
-
location: FileRange;
|
|
41
|
-
name: string;
|
|
42
|
-
constructor(message: string, expected: Expectation[], found: string | null, location: FileRange);
|
|
43
|
-
format(sources: {
|
|
44
|
-
source?: any;
|
|
45
|
-
text: string;
|
|
46
|
-
}[]): string;
|
|
47
|
-
}
|
|
48
|
-
export interface TraceEvent {
|
|
49
|
-
type: string;
|
|
50
|
-
rule: string;
|
|
51
|
-
result?: any;
|
|
52
|
-
location: FileRange;
|
|
53
|
-
}
|
|
54
|
-
export interface ParseOptions {
|
|
55
|
-
filename?: string;
|
|
56
|
-
startRule?: "start";
|
|
57
|
-
tracer?: any;
|
|
58
|
-
[key: string]: any;
|
|
59
|
-
}
|
|
60
|
-
export type ParseFunction = <Options extends ParseOptions>(input: string, options?: Options) => Options extends {
|
|
61
|
-
startRule: infer StartRule;
|
|
62
|
-
} ? StartRule extends "start" ? Start : Start : Start;
|
|
63
|
-
export declare const parse: ParseFunction;
|
|
64
|
-
export declare const PeggySyntaxError: typeof _PeggySyntaxError;
|
|
65
|
-
export type PeggySyntaxError = _PeggySyntaxError;
|
|
66
|
-
export type Start = Group | Or | And | Comparison;
|
|
67
|
-
export type Group = Or;
|
|
68
|
-
export type Or = {
|
|
69
|
-
or: [And | Comparison, ...OrTails[]];
|
|
19
|
+
export type Expression = Or | And | Comparison;
|
|
20
|
+
type Or = {
|
|
21
|
+
kind: SyntaxKind.Or;
|
|
22
|
+
operands: Expression[];
|
|
70
23
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
24
|
+
type And = {
|
|
25
|
+
kind: SyntaxKind.And;
|
|
26
|
+
operands: Expression[];
|
|
74
27
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
28
|
+
type Comparison = {
|
|
29
|
+
kind: SyntaxKind.Comparison;
|
|
30
|
+
left: Identifier;
|
|
31
|
+
operator: Operator;
|
|
32
|
+
right: NumberLiteral | Version;
|
|
79
33
|
};
|
|
80
|
-
|
|
81
|
-
|
|
34
|
+
type Identifier = {
|
|
35
|
+
kind: SyntaxKind.Identifier;
|
|
36
|
+
name: string;
|
|
82
37
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
38
|
+
type NumberLiteral = {
|
|
39
|
+
kind: SyntaxKind.NumberLiteral;
|
|
40
|
+
value: number;
|
|
41
|
+
};
|
|
42
|
+
type Version = {
|
|
43
|
+
kind: SyntaxKind.Version;
|
|
44
|
+
value: string;
|
|
45
|
+
};
|
|
46
|
+
export declare enum TokenKind {
|
|
47
|
+
Identifier = 0,
|
|
48
|
+
NumberLiteral = 1,
|
|
49
|
+
Dot = 2,// "."
|
|
50
|
+
LeftParen = 3,// "("
|
|
51
|
+
RightParen = 4,// ")"
|
|
52
|
+
BarBar = 5,// "||"
|
|
53
|
+
AmpAmp = 6,// "&&"
|
|
54
|
+
EqualsEquals = 7,// "=="
|
|
55
|
+
EqualsEqualsEquals = 8,// "==="
|
|
56
|
+
ExclamationEquals = 9,// "!="
|
|
57
|
+
ExclamationEqualsEquals = 10,// "!=="
|
|
58
|
+
LessThan = 11,// "<"
|
|
59
|
+
LessThanEquals = 12,// "<="
|
|
60
|
+
GreaterThan = 13,// ">"
|
|
61
|
+
GreaterThanEquals = 14
|
|
62
|
+
}
|
|
63
|
+
export type Token = {
|
|
64
|
+
start: number;
|
|
65
|
+
kind: TokenKind;
|
|
66
|
+
value?: string;
|
|
86
67
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
export
|
|
91
|
-
export
|
|
68
|
+
/**
|
|
69
|
+
* Splits a string into tokens to be consumed by the Parser.
|
|
70
|
+
*/
|
|
71
|
+
export declare function tokenize(input: string): Generator<Token>;
|
|
72
|
+
export declare function parse(input: string): Expression | undefined;
|
|
73
|
+
export declare function toRulesLogic(expr: Expression): RulesLogic;
|
|
92
74
|
export {};
|
|
93
75
|
//# sourceMappingURL=LogicParser.d.ts.map
|