From 4383192a425f3abd476cfed2614be7ecf96b21a5 Mon Sep 17 00:00:00 2001 From: andresceballosm Date: Tue, 30 Jul 2024 15:34:23 -0500 Subject: [PATCH 1/6] Added JSONPath syntactic validation --- packages/taco/package.json | 2 + packages/taco/src/conditions/base/json-api.ts | 29 +++++++--- .../test/conditions/base/json-api.test.ts | 56 +++++++++++++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 packages/taco/test/conditions/base/json-api.test.ts diff --git a/packages/taco/package.json b/packages/taco/package.json index fcf61b296..ff213a018 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -43,11 +43,13 @@ "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "*", + "jsonpath": "^1.1.1", "semver": "^7.5.2", "zod": "*" }, "devDependencies": { "@nucypher/test-utils": "workspace:*", + "@types/jsonpath": "^0.2.4", "@types/semver": "^7.5.6" }, "engines": { diff --git a/packages/taco/src/conditions/base/json-api.ts b/packages/taco/src/conditions/base/json-api.ts index 0a55b20b8..f8835913e 100644 --- a/packages/taco/src/conditions/base/json-api.ts +++ b/packages/taco/src/conditions/base/json-api.ts @@ -1,18 +1,31 @@ -import { z } from 'zod'; +import { parse } from "jsonpath"; +import { z } from "zod"; -import { Condition } from '../condition'; -import { - OmitConditionType, - returnValueTestSchema, -} from '../shared'; +import { Condition } from "../condition"; +import { OmitConditionType, returnValueTestSchema } from "../shared"; -export const JsonApiConditionType = 'json-api'; +export const JsonApiConditionType = "json-api"; + +const validateJSONPath = (jsonPath: string): boolean => { + try { + parse(jsonPath); + return true; + } catch (error) { + return false; + } +}; + +export const jsonPathSchema = z + .string() + .refine((val) => validateJSONPath(val), { + message: "Invalid JSONPath expression", + }); export const JsonApiConditionSchema = z.object({ conditionType: z.literal(JsonApiConditionType).default(JsonApiConditionType), endpoint: z.string().url(), parameters: z.record(z.string(), z.unknown()).optional(), - query: z.string().optional(), + query: jsonPathSchema.optional(), returnValueTest: returnValueTestSchema, // Update to allow multiple return values after expanding supported methods }); diff --git a/packages/taco/test/conditions/base/json-api.test.ts b/packages/taco/test/conditions/base/json-api.test.ts new file mode 100644 index 000000000..94b07af81 --- /dev/null +++ b/packages/taco/test/conditions/base/json-api.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from 'vitest'; + +import { jsonPathSchema } from '../../../src/conditions/base/json-api'; + +describe('JSONPath Validation', () => { + it('Invalid JSONPath: Incomplete filter expression', () => { + const invalidPath = '$.store.book[?(@.price < ]'; + const result = jsonPathSchema.safeParse(invalidPath); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.error.errors[0].message).toBe( + 'Invalid JSONPath expression', + ); + } + }); + + it('Invalid JSONPath: Incorrect use of brackets', () => { + const invalidPath = '$[store][book]'; + const result = jsonPathSchema.safeParse(invalidPath); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.error.errors[0].message).toBe( + 'Invalid JSONPath expression', + ); + } + }); + + it('Invalid JSONPath: Unclosed wildcard asterisk', () => { + const invalidPath = '$.store.book[*'; + const result = jsonPathSchema.safeParse(invalidPath); + expect(result.success).toBe(false); + if (!result.success) { + expect(result.error.errors[0].message).toBe( + 'Invalid JSONPath expression', + ); + } + }); + + it('Valid JSONPath expression', () => { + const validPath = '$.store.book[?(@.price < 10)]'; + const result = jsonPathSchema.safeParse(validPath); + expect(result.success).toBe(true); + }); + + it('Valid JSONPath with correct quotes', () => { + const validPath = "$.store['book[?(@.price < ]']"; + const result = jsonPathSchema.safeParse(validPath); + expect(result.success).toBe(true); + }); + + it('Valid JSONPath with correct wildcard', () => { + const validPath = '$.store.book[*]'; + const result = jsonPathSchema.safeParse(validPath); + expect(result.success).toBe(true); + }); +}); From abb82b7b588ad010459fde567b4e2719008ebcfd Mon Sep 17 00:00:00 2001 From: andresceballosm Date: Wed, 31 Jul 2024 10:07:44 -0500 Subject: [PATCH 2/6] Updated pnpm-lock.yamls and fix linter errors --- packages/taco/src/conditions/base/json-api.ts | 12 ++++++------ .../taco/test/conditions/base/json.test.ts | 19 +++++++++++-------- .../test/conditions/condition-expr.test.ts | 11 +++++++---- packages/taco/test/test-utils.ts | 9 +++------ pnpm-lock.yaml | 11 +++++++++++ 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/packages/taco/src/conditions/base/json-api.ts b/packages/taco/src/conditions/base/json-api.ts index f8835913e..7e96cd648 100644 --- a/packages/taco/src/conditions/base/json-api.ts +++ b/packages/taco/src/conditions/base/json-api.ts @@ -1,10 +1,10 @@ -import { parse } from "jsonpath"; -import { z } from "zod"; +import { parse } from 'jsonpath'; +import { z } from 'zod'; -import { Condition } from "../condition"; -import { OmitConditionType, returnValueTestSchema } from "../shared"; +import { Condition } from '../condition'; +import { OmitConditionType, returnValueTestSchema } from '../shared'; -export const JsonApiConditionType = "json-api"; +export const JsonApiConditionType = 'json-api'; const validateJSONPath = (jsonPath: string): boolean => { try { @@ -18,7 +18,7 @@ const validateJSONPath = (jsonPath: string): boolean => { export const jsonPathSchema = z .string() .refine((val) => validateJSONPath(val), { - message: "Invalid JSONPath expression", + message: 'Invalid JSONPath expression', }); export const JsonApiConditionSchema = z.object({ diff --git a/packages/taco/test/conditions/base/json.test.ts b/packages/taco/test/conditions/base/json.test.ts index 9c26a7f7a..0166485a2 100644 --- a/packages/taco/test/conditions/base/json.test.ts +++ b/packages/taco/test/conditions/base/json.test.ts @@ -25,7 +25,10 @@ describe('JsonApiCondition', () => { endpoint: 'not-a-url', }; - const result = JsonApiCondition.validate(JsonApiConditionSchema, badJsonApiObj); + const result = JsonApiCondition.validate( + JsonApiConditionSchema, + badJsonApiObj, + ); expect(result.error).toBeDefined(); expect(result.data).toBeUndefined(); @@ -35,26 +38,26 @@ describe('JsonApiCondition', () => { }, }); }); - + describe('parameters', () => { it('accepts conditions without query path', () => { - const { query, ...noQueryObj} = testJsonApiConditionObj; + const { query, ...noQueryObj } = testJsonApiConditionObj; const result = JsonApiCondition.validate( JsonApiConditionSchema, - noQueryObj + noQueryObj, ); - + expect(result.error).toBeUndefined(); expect(result.data).toEqual(noQueryObj); }); it('accepts conditions without parameters', () => { - const { query, ...noParamsObj} = testJsonApiConditionObj; + const { query, ...noParamsObj } = testJsonApiConditionObj; const result = JsonApiCondition.validate( JsonApiConditionSchema, - noParamsObj + noParamsObj, ); - + expect(result.error).toBeUndefined(); expect(result.data).toEqual(noParamsObj); }); diff --git a/packages/taco/test/conditions/condition-expr.test.ts b/packages/taco/test/conditions/condition-expr.test.ts index 4defa46cf..66bf48299 100644 --- a/packages/taco/test/conditions/condition-expr.test.ts +++ b/packages/taco/test/conditions/condition-expr.test.ts @@ -406,17 +406,20 @@ describe('condition set', () => { it('json api condition serialization', () => { const conditionExpr = new ConditionExpression(jsonApiCondition); - + const conditionExprJson = conditionExpr.toJson(); expect(conditionExprJson).toBeDefined(); expect(conditionExprJson).toContain('endpoint'); - expect(conditionExprJson).toContain('https://_this_would_totally_fail.com'); + expect(conditionExprJson).toContain( + 'https://_this_would_totally_fail.com', + ); expect(conditionExprJson).toContain('parameters'); expect(conditionExprJson).toContain('query'); expect(conditionExprJson).toContain('$.ethereum.usd'); expect(conditionExprJson).toContain('returnValueTest'); - - const conditionExprFromJson = ConditionExpression.fromJSON(conditionExprJson); + + const conditionExprFromJson = + ConditionExpression.fromJSON(conditionExprJson); expect(conditionExprFromJson).toBeDefined(); expect(conditionExprFromJson.condition).toBeInstanceOf(JsonApiCondition); }); diff --git a/packages/taco/test/test-utils.ts b/packages/taco/test/test-utils.ts index 78db4f911..b82eb570a 100644 --- a/packages/taco/test/test-utils.ts +++ b/packages/taco/test/test-utils.ts @@ -39,10 +39,7 @@ import { ContractConditionType, FunctionAbiProps, } from '../src/conditions/base/contract'; -import { - JsonApiConditionProps, - JsonApiConditionType -} from '../src/conditions/base/json-api'; +import { JsonApiConditionType } from '../src/conditions/base/json-api'; import { RpcConditionProps, RpcConditionType, @@ -230,8 +227,8 @@ export const testJsonApiConditionObj = { conditionType: JsonApiConditionType, endpoint: 'https://_this_would_totally_fail.com', parameters: { - 'ids': 'ethereum', - 'vs_currencies': 'usd', + ids: 'ethereum', + vs_currencies: 'usd', }, query: '$.ethereum.usd', returnValueTest: testReturnValueTest, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4937ad55b..9b8887eca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -552,6 +552,9 @@ importers: ethers: specifier: '*' version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + jsonpath: + specifier: ^1.1.1 + version: 1.1.1 semver: specifier: ^7.5.2 version: 7.6.2 @@ -562,6 +565,9 @@ importers: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils + '@types/jsonpath': + specifier: ^0.2.4 + version: 0.2.4 '@types/semver': specifier: ^7.5.6 version: 7.5.8 @@ -2615,6 +2621,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/jsonpath@0.2.4': + resolution: {integrity: sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==} + '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} @@ -11547,6 +11556,8 @@ snapshots: '@types/json5@0.0.29': {} + '@types/jsonpath@0.2.4': {} + '@types/keyv@3.1.4': dependencies: '@types/node': 20.14.2 From f161bc2c38a93f573839e032ccb1b2766e70e918 Mon Sep 17 00:00:00 2001 From: andresceballosm Date: Wed, 31 Jul 2024 14:33:57 -0500 Subject: [PATCH 3/6] Removed jsonpath library --- packages/taco/package.json | 2 - packages/taco/src/conditions/base/json-api.ts | 69 ++++++++++++++++--- pnpm-lock.yaml | 11 --- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index ff213a018..fcf61b296 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -43,13 +43,11 @@ "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", "ethers": "*", - "jsonpath": "^1.1.1", "semver": "^7.5.2", "zod": "*" }, "devDependencies": { "@nucypher/test-utils": "workspace:*", - "@types/jsonpath": "^0.2.4", "@types/semver": "^7.5.6" }, "engines": { diff --git a/packages/taco/src/conditions/base/json-api.ts b/packages/taco/src/conditions/base/json-api.ts index 7e96cd648..01ac73e77 100644 --- a/packages/taco/src/conditions/base/json-api.ts +++ b/packages/taco/src/conditions/base/json-api.ts @@ -1,4 +1,3 @@ -import { parse } from 'jsonpath'; import { z } from 'zod'; import { Condition } from '../condition'; @@ -6,14 +5,68 @@ import { OmitConditionType, returnValueTestSchema } from '../shared'; export const JsonApiConditionType = 'json-api'; -const validateJSONPath = (jsonPath: string): boolean => { - try { - parse(jsonPath); - return true; - } catch (error) { - return false; +function tokenize(expression: string): string[] { + const regex = + /(\$|@|\.\.|\.|[[\]]|\?|\(|\)|==|!=|<=|>=|<|>|&&|\|\||[a-zA-Z_][\w]*|\d+|'[^']*')/g; + return expression.match(regex) || []; +} + +function validateJSONPath(expression: string): boolean { + const tokens = tokenize(expression); + + let depth = 0; + let inBracket = false; + let inFilter = false; + let lastTokenWasCloseBracket = false; + + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + + if (token === '$' && i !== 0) return false; // $ only at the beginning + if (token === '@' && !inFilter) return false; // @ only in filters + + if (token === '[') { + if (lastTokenWasCloseBracket) return false; // Don't allow [...][] + depth++; + inBracket = true; + lastTokenWasCloseBracket = false; + } else if (token === ']') { + if (depth === 0) return false; + depth--; + inBracket = false; + lastTokenWasCloseBracket = true; + } else { + lastTokenWasCloseBracket = false; + } + + if (token === '?') { + if (!inBracket) return false; + inFilter = true; + } else if (token === '(') { + if (!inFilter) return false; + } else if (token === ')') { + if (!inFilter) return false; + inFilter = false; + } + + // Check for valid operators in filters + if ( + inFilter && + ['==', '!=', '<', '<=', '>', '>=', '&&', '||'].includes(token) + ) { + if (i === 0 || i === tokens.length - 1) return false; + } + + // Check that there are no two consecutive dots outside brackets + if (token === '.' && i > 0 && tokens[i - 1] === '.' && !inBracket) + return false; } -}; + + if (depth !== 0) return false; // Unclosed brackets + if (inFilter) return false; // Unclosed filter + + return true; +} export const jsonPathSchema = z .string() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b8887eca..4937ad55b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -552,9 +552,6 @@ importers: ethers: specifier: '*' version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - jsonpath: - specifier: ^1.1.1 - version: 1.1.1 semver: specifier: ^7.5.2 version: 7.6.2 @@ -565,9 +562,6 @@ importers: '@nucypher/test-utils': specifier: workspace:* version: link:../test-utils - '@types/jsonpath': - specifier: ^0.2.4 - version: 0.2.4 '@types/semver': specifier: ^7.5.6 version: 7.5.8 @@ -2621,9 +2615,6 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/jsonpath@0.2.4': - resolution: {integrity: sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==} - '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} @@ -11556,8 +11547,6 @@ snapshots: '@types/json5@0.0.29': {} - '@types/jsonpath@0.2.4': {} - '@types/keyv@3.1.4': dependencies: '@types/node': 20.14.2 From c56d7bdbcedee6038c7baeb3855923e7cfa31bbe Mon Sep 17 00:00:00 2001 From: andresceballosm Date: Thu, 1 Aug 2024 10:47:16 -0500 Subject: [PATCH 4/6] Added Library @astronautlabs/jsonpath --- packages/taco/package.json | 1 + packages/taco/src/conditions/base/json-api.ts | 69 +++---------------- pnpm-lock.yaml | 40 +++++------ 3 files changed, 29 insertions(+), 81 deletions(-) diff --git a/packages/taco/package.json b/packages/taco/package.json index fcf61b296..0b3f0f8ac 100644 --- a/packages/taco/package.json +++ b/packages/taco/package.json @@ -39,6 +39,7 @@ "typedoc": "typedoc" }, "dependencies": { + "@astronautlabs/jsonpath": "^1.1.2", "@nucypher/nucypher-core": "*", "@nucypher/shared": "workspace:*", "@nucypher/taco-auth": "workspace:*", diff --git a/packages/taco/src/conditions/base/json-api.ts b/packages/taco/src/conditions/base/json-api.ts index 01ac73e77..22032cb34 100644 --- a/packages/taco/src/conditions/base/json-api.ts +++ b/packages/taco/src/conditions/base/json-api.ts @@ -1,3 +1,4 @@ +import { JSONPath } from '@astronautlabs/jsonpath'; import { z } from 'zod'; import { Condition } from '../condition'; @@ -5,68 +6,14 @@ import { OmitConditionType, returnValueTestSchema } from '../shared'; export const JsonApiConditionType = 'json-api'; -function tokenize(expression: string): string[] { - const regex = - /(\$|@|\.\.|\.|[[\]]|\?|\(|\)|==|!=|<=|>=|<|>|&&|\|\||[a-zA-Z_][\w]*|\d+|'[^']*')/g; - return expression.match(regex) || []; -} - -function validateJSONPath(expression: string): boolean { - const tokens = tokenize(expression); - - let depth = 0; - let inBracket = false; - let inFilter = false; - let lastTokenWasCloseBracket = false; - - for (let i = 0; i < tokens.length; i++) { - const token = tokens[i]; - - if (token === '$' && i !== 0) return false; // $ only at the beginning - if (token === '@' && !inFilter) return false; // @ only in filters - - if (token === '[') { - if (lastTokenWasCloseBracket) return false; // Don't allow [...][] - depth++; - inBracket = true; - lastTokenWasCloseBracket = false; - } else if (token === ']') { - if (depth === 0) return false; - depth--; - inBracket = false; - lastTokenWasCloseBracket = true; - } else { - lastTokenWasCloseBracket = false; - } - - if (token === '?') { - if (!inBracket) return false; - inFilter = true; - } else if (token === '(') { - if (!inFilter) return false; - } else if (token === ')') { - if (!inFilter) return false; - inFilter = false; - } - - // Check for valid operators in filters - if ( - inFilter && - ['==', '!=', '<', '<=', '>', '>=', '&&', '||'].includes(token) - ) { - if (i === 0 || i === tokens.length - 1) return false; - } - - // Check that there are no two consecutive dots outside brackets - if (token === '.' && i > 0 && tokens[i - 1] === '.' && !inBracket) - return false; +const validateJSONPath = (jsonPath: string): boolean => { + try { + JSONPath.parse(jsonPath); + return true; + } catch (error) { + return false; } - - if (depth !== 0) return false; // Unclosed brackets - if (inFilter) return false; // Unclosed filter - - return true; -} +}; export const jsonPathSchema = z .string() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4937ad55b..91308e3fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -540,6 +540,9 @@ importers: packages/taco: dependencies: + '@astronautlabs/jsonpath': + specifier: ^1.1.2 + version: 1.1.2 '@nucypher/nucypher-core': specifier: ^0.14.5 version: 0.14.5 @@ -634,6 +637,9 @@ packages: resolution: {integrity: sha512-NqJDx39sHN0o7BpxpQzishoZjGBzvXqSVxO+bRm6OPP/Oe+Kb51R5x8dWvW9i3amO3QNdocg/p4jFRCwzqy2Gg==} engines: {node: '>=11.0.0'} + '@astronautlabs/jsonpath@1.1.2': + resolution: {integrity: sha512-FqL/muoreH7iltYC1EB5Tvox5E8NSOOPGkgns4G+qxRKl6k5dxEVljUjB5NcKESzkqwnUqWjSZkL61XGYOuV+A==} + '@babel/code-frame@7.24.6': resolution: {integrity: sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==} engines: {node: '>=6.9.0'} @@ -9044,6 +9050,10 @@ snapshots: transitivePeerDependencies: - debug + '@astronautlabs/jsonpath@1.1.2': + dependencies: + static-eval: 2.0.2 + '@babel/code-frame@7.24.6': dependencies: '@babel/highlight': 7.24.6 @@ -13986,8 +13996,8 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.4.5) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0))(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.56.0) eslint-plugin-react: 7.34.1(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.56.0) @@ -14058,13 +14068,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0))(eslint@8.56.0): dependencies: debug: 4.3.5 enhanced-resolve: 5.17.1 eslint: 8.56.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0))(eslint@8.56.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -14096,24 +14106,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0))(eslint@8.56.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.4.5) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.56.0) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.5) - eslint: 8.56.0 - eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0))(eslint@8.56.0) transitivePeerDependencies: - supports-color @@ -14195,7 +14195,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.56.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -14205,7 +14205,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.56.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -14216,7 +14216,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 6.21.0(eslint@8.56.0)(typescript@5.4.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack From e42e69eb4f89987f03a943e4667df915510330a7 Mon Sep 17 00:00:00 2001 From: andresceballosm Date: Thu, 1 Aug 2024 14:31:32 -0500 Subject: [PATCH 5/6] Updated unit test --- .../taco/test/conditions/base/json-api.test.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/packages/taco/test/conditions/base/json-api.test.ts b/packages/taco/test/conditions/base/json-api.test.ts index 94b07af81..d71d1ee3f 100644 --- a/packages/taco/test/conditions/base/json-api.test.ts +++ b/packages/taco/test/conditions/base/json-api.test.ts @@ -7,33 +7,18 @@ describe('JSONPath Validation', () => { const invalidPath = '$.store.book[?(@.price < ]'; const result = jsonPathSchema.safeParse(invalidPath); expect(result.success).toBe(false); - if (!result.success) { - expect(result.error.errors[0].message).toBe( - 'Invalid JSONPath expression', - ); - } }); it('Invalid JSONPath: Incorrect use of brackets', () => { const invalidPath = '$[store][book]'; const result = jsonPathSchema.safeParse(invalidPath); expect(result.success).toBe(false); - if (!result.success) { - expect(result.error.errors[0].message).toBe( - 'Invalid JSONPath expression', - ); - } }); it('Invalid JSONPath: Unclosed wildcard asterisk', () => { const invalidPath = '$.store.book[*'; const result = jsonPathSchema.safeParse(invalidPath); expect(result.success).toBe(false); - if (!result.success) { - expect(result.error.errors[0].message).toBe( - 'Invalid JSONPath expression', - ); - } }); it('Valid JSONPath expression', () => { From e2d162e23ab6ccdd90d1077c2ff6f59dcda795b6 Mon Sep 17 00:00:00 2001 From: andresceballosm Date: Thu, 1 Aug 2024 14:53:41 -0500 Subject: [PATCH 6/6] Update in unit tests --- packages/taco/test/conditions/base/json-api.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/taco/test/conditions/base/json-api.test.ts b/packages/taco/test/conditions/base/json-api.test.ts index d71d1ee3f..09c622e6e 100644 --- a/packages/taco/test/conditions/base/json-api.test.ts +++ b/packages/taco/test/conditions/base/json-api.test.ts @@ -7,18 +7,21 @@ describe('JSONPath Validation', () => { const invalidPath = '$.store.book[?(@.price < ]'; const result = jsonPathSchema.safeParse(invalidPath); expect(result.success).toBe(false); + expect(result.error!.errors[0].message).toBe('Invalid JSONPath expression'); }); it('Invalid JSONPath: Incorrect use of brackets', () => { const invalidPath = '$[store][book]'; const result = jsonPathSchema.safeParse(invalidPath); expect(result.success).toBe(false); + expect(result.error!.errors[0].message).toBe('Invalid JSONPath expression'); }); it('Invalid JSONPath: Unclosed wildcard asterisk', () => { const invalidPath = '$.store.book[*'; const result = jsonPathSchema.safeParse(invalidPath); expect(result.success).toBe(false); + expect(result.error!.errors[0].message).toBe('Invalid JSONPath expression'); }); it('Valid JSONPath expression', () => {