diff --git a/package-lock.json b/package-lock.json index b509807..2afaf56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.16.1", "license": "MIT", "dependencies": { - "jsonpath-plus": "^10.3.0" + "jsonata": "^2.1.0" }, "devDependencies": { "@types/jest": "^28.1.3", @@ -48,14 +48,15 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.25.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -256,9 +257,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", - "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -266,9 +267,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", - "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, "license": "MIT", "engines": { @@ -285,121 +286,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.6.tgz", - "integrity": "sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", - "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.8" + "@babel/types": "^7.28.4" }, "bin": { "parser": "bin/babel-parser.js" @@ -571,15 +478,15 @@ } }, "node_modules/@babel/template": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/types": "^7.25.7" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -614,15 +521,14 @@ } }, "node_modules/@babel/types": { - "version": "7.25.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", - "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1295,30 +1201,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jsep-plugin/assignment": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", - "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, - "node_modules/@jsep-plugin/regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", - "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - }, - "peerDependencies": { - "jsep": "^0.4.0||^1.0.0" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1993,10 +1875,11 @@ "dev": true }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4424,15 +4307,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsep": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", - "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", - "license": "MIT", - "engines": { - "node": ">= 10.16.0" - } - }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -4477,22 +4351,13 @@ "json5": "lib/cli.js" } }, - "node_modules/jsonpath-plus": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", - "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", + "node_modules/jsonata": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.1.0.tgz", + "integrity": "sha512-OCzaRMK8HobtX8fp37uIVmL8CY1IGc/a6gLsDqz3quExFR09/U78HUzWYr7T31UEB6+Eu0/8dkVD5fFDOl9a8w==", "license": "MIT", - "dependencies": { - "@jsep-plugin/assignment": "^1.3.0", - "@jsep-plugin/regex": "^1.0.4", - "jsep": "^1.4.0" - }, - "bin": { - "jsonpath": "bin/jsonpath-cli.js", - "jsonpath-plus": "bin/jsonpath-cli.js" - }, "engines": { - "node": ">=18.0.0" + "node": ">= 8" } }, "node_modules/kleur": { @@ -4997,10 +4862,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -5350,9 +5216,9 @@ } }, "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5766,15 +5632,6 @@ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index 3391b14..032344a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "asl-path-validator", - "version": "0.17.0", + "version": "1.0.0", "description": "Validates the path expressions for the Amazon States Language", "main": "./dist/index.js", "scripts": { @@ -50,6 +50,6 @@ "typescript": "^4.7.4" }, "dependencies": { - "jsonpath-plus": "^10.3.0" + "jsonata": "^2.1.0" } } diff --git a/src/__tests__/ajv.test.ts b/src/__tests__/ajv.test.ts index c6d2b96..0d214b4 100644 --- a/src/__tests__/ajv.test.ts +++ b/src/__tests__/ajv.test.ts @@ -5,14 +5,16 @@ import fs from "fs"; import path from "path"; import { registerAll } from "../ajv"; import { must } from "../assertions"; -import { JSONPath } from "jsonpath-plus"; describe("tests for the ajv custom formatters", () => { let ajv: Ajv | null = null; beforeAll(() => { ajv = new Ajv({ - schemas: [example, payloadTemplateSchema], + schemas: [ + { ...example, $async: true }, + { ...payloadTemplateSchema, $async: true }, + ], allowUnionTypes: true, }); registerAll(ajv); @@ -39,17 +41,18 @@ describe("tests for the ajv custom formatters", () => { }, ]; - it.each(valid_inputs)("$label", (inputWithLabel) => { + it.each(valid_inputs)("$label", async (inputWithLabel) => { expect.hasAssertions(); must(ajv); const { label, ...input } = inputWithLabel; - const result = ajv.validate( - "https://asl-path-validator.cloud/example.json#", - input + const validator = ajv.getSchema( + "https://asl-path-validator.cloud/example.json#" ); + must(validator); + const result = await validator(input); expect(label).toBeTruthy(); expect(ajv.errors ?? []).toStrictEqual([]); - expect(result).toBe(true); + expect(result).toBeTruthy(); }); const invalid_shapes: Array<{ @@ -79,7 +82,7 @@ describe("tests for the ajv custom formatters", () => { "dynamic.path1.$": "not a valid path", static2: "ok", }, - label: "field matching path pattern doesn't have a valud path", + label: "field matching path pattern doesn't have a valid path", }, { Parameters: { @@ -105,24 +108,32 @@ describe("tests for the ajv custom formatters", () => { }, ]; - it.each(invalid_shapes)("$label should be rejected", (inputWithLabel) => { - expect.hasAssertions(); - must(ajv); - const { label, ...input } = inputWithLabel; - expect(label).toBeTruthy(); - const inputFields = Object.keys(input); - expect(inputFields).toHaveLength(1); - const result = ajv.validate( - "https://asl-path-validator.cloud/example.json#", - { ...input, Type: "Example" } - ); - expect(result).toBe(false); - const instancePath: string = JSONPath({ - json: ajv, - path: "$.errors.[0].instancePath", - wrap: false, - }); - - expect(instancePath.split("/")[1]).toStrictEqual(inputFields[0]); - }); + it.each(invalid_shapes)( + "$label should be rejected", + async (inputWithLabel) => { + expect.hasAssertions(); + must(ajv); + const { label, ...input } = inputWithLabel; + expect(label).toBeTruthy(); + const inputFields = Object.keys(input); + expect(inputFields).toHaveLength(1); + const validator = ajv.getSchema( + "https://asl-path-validator.cloud/example.json#" + ); + must(validator); + try { + await validator({ ...input, Type: "Example" }); + fail("expected validation to fail"); + } catch (e: unknown) { + expect(e).toBeTruthy(); + } + // const instancePath: string = JSONPath({ + // json: ajv, + // path: "$.errors.[0].instancePath", + // wrap: false, + // }); + // + // expect(instancePath.split("/")[1]).toStrictEqual(inputFields[0]); + } + ); }); diff --git a/src/__tests__/validatePath.test.ts b/src/__tests__/validatePath.test.ts index 7f470d8..d4b855b 100644 --- a/src/__tests__/validatePath.test.ts +++ b/src/__tests__/validatePath.test.ts @@ -248,10 +248,10 @@ describe("unit tests for the parser", () => { describe("valid paths", () => { it.each(toInput())( "$path as $context expected: $expected_outcome", - ({ path, context, expected_outcome }) => { + async ({ path, context, expected_outcome }) => { expect.hasAssertions(); must(context); - const result = validatePath(path, context); + const result = await validatePath(path, context); if (!result.isValid && expected_outcome) { // gets a better error message expect(result.message).toBeFalsy(); diff --git a/src/ajv.ts b/src/ajv.ts index c53de10..4f11952 100644 --- a/src/ajv.ts +++ b/src/ajv.ts @@ -16,8 +16,11 @@ export const registerAll = ( ajv: Ajv, config = AslPathValidatorConfig ): void => { - const validateAdapter = (path: string, pathType: AslPathContext): boolean => { - const result = validatePath(path, pathType); + const validateAdapter = async ( + path: string, + pathType: AslPathContext + ): Promise => { + const result = await validatePath(path, pathType); if (!config.silent && !result.isValid) { ajv.logger.error( `asl_path_validator: code:${result.code}. pathType:${pathType}. input: ${path}` @@ -26,31 +29,31 @@ export const registerAll = ( return result.isValid; }; - ajv.addFormat( - config.format_names[AslPathContext.REFERENCE_PATH], - (path: string): boolean => { + ajv.addFormat(config.format_names[AslPathContext.REFERENCE_PATH], { + async: true, + validate: (path: string): Promise => { return validateAdapter(path, AslPathContext.REFERENCE_PATH); - } - ); + }, + }); - ajv.addFormat( - config.format_names[AslPathContext.PATH], - (path: string): boolean => { + ajv.addFormat(config.format_names[AslPathContext.PATH], { + async: true, + validate: (path: string): Promise => { return validateAdapter(path, AslPathContext.PATH); - } - ); + }, + }); - ajv.addFormat( - config.format_names[AslPathContext.PAYLOAD_TEMPLATE], - (path: string): boolean => { + ajv.addFormat(config.format_names[AslPathContext.PAYLOAD_TEMPLATE], { + async: true, + validate: (path: string): Promise => { return validateAdapter(path, AslPathContext.PAYLOAD_TEMPLATE); - } - ); + }, + }); - ajv.addFormat( - config.format_names[AslPathContext.RESULT_PATH], - (path: string): boolean => { + ajv.addFormat(config.format_names[AslPathContext.RESULT_PATH], { + async: true, + validate: (path: string): Promise => { return validateAdapter(path, AslPathContext.RESULT_PATH); - } - ); + }, + }); }; diff --git a/src/ast.ts b/src/ast.ts index 2769eb3..0c6c2a4 100644 --- a/src/ast.ts +++ b/src/ast.ts @@ -1,24 +1,33 @@ -import { JSONPath } from "jsonpath-plus"; +import jsonata from "jsonata"; -const find = (path: string, ast: unknown): boolean => { - const results: unknown[] = JSONPath({ - path, - json: ast as object, - }); - return results.length > 0; +const find = async (fields: string[], ast: unknown): Promise => { + for (const field of fields) { + const expr = jsonata(`**.${field}`); + const result: unknown = await expr.evaluate(ast); + if (result) { + return true; + } + } + return false; }; -export const referencePathChecks = (ast: unknown): boolean => { - return !find( - "$..[atmark,wildcard,negOffset,slice,recursiveDescent,multipleIndex,filter]", - ast - ); +export const referencePathChecks = async (ast: unknown): Promise => { + const names = [ + "atmark", + "wildcard", + "negOffset", + "slice", + "recursiveDescent", + "multipleIndex", + "filter", + ]; + return !(await find(names, ast)); }; -export const hasFunctions = (ast: unknown): boolean => { - return find("$..[func]", ast); +export const hasFunctions = async (ast: unknown): Promise => { + return find(["func"], ast); }; -export const hasVariable = (ast: unknown): boolean => { - return find("$..[var]", ast); +export const hasVariable = async (ast: unknown): Promise => { + return find(["var"], ast); }; diff --git a/src/index.ts b/src/index.ts index ac1de21..6a95be5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,10 +4,10 @@ import { parse } from "./generated/aslPaths"; import { AslPathContext, ErrorCodes, ValidationResult } from "./types"; import { hasFunctions, hasVariable, referencePathChecks } from "./ast"; -export const validatePath = ( +export const validatePath = async ( path: string, context: AslPathContext -): ValidationResult => { +): Promise => { let ast: unknown | null = null; try { ast = parse(path); @@ -29,7 +29,7 @@ export const validatePath = ( case AslPathContext.PAYLOAD_TEMPLATE: break; case AslPathContext.PATH: - if (hasFunctions(ast)) { + if (await hasFunctions(ast)) { return { isValid: false, code: ErrorCodes.exp_has_functions, @@ -38,20 +38,20 @@ export const validatePath = ( break; case AslPathContext.REFERENCE_PATH: case AslPathContext.RESULT_PATH: - if (hasFunctions(ast)) { + if (await hasFunctions(ast)) { return { isValid: false, code: ErrorCodes.exp_has_functions, }; } - if (!referencePathChecks(ast)) { + if (!(await referencePathChecks(ast))) { return { isValid: false, code: ErrorCodes.exp_has_non_reference_path_ops, }; } if (context === AslPathContext.RESULT_PATH) { - if (hasVariable(ast)) { + if (await hasVariable(ast)) { return { isValid: false, code: ErrorCodes.exp_has_variable,