Skip to content

Commit 8ff1e3b

Browse files
authored
Port latest changes from gbx util-expr (#3636)
1 parent d7596bf commit 8ff1e3b

File tree

9 files changed

+104
-7
lines changed

9 files changed

+104
-7
lines changed

.changeset/shy-mails-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@gitbook/expr": patch
3+
---
4+
5+
Add support for every/some array methods

bun.lock

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,12 @@
7070
"acorn-loose": "8.4.0",
7171
"acorn-walk": "^8.3.4",
7272
"assert-never": "^1.2.1",
73-
"eval-estree-expression": "^2.0.3",
73+
"escodegen": "^2.1.0",
74+
"eval-estree-expression": "github:jonschlinkert/eval-estree-expression#9cf28d2",
7475
},
7576
"devDependencies": {
7677
"@babel/types": "^7.26.0",
78+
"@types/escodegen": "^0.0.10",
7779
"@types/estree": "^1.0.6",
7880
"@types/json-schema": "^7.0.15",
7981
"bun-types": "^1.1.20",
@@ -1376,6 +1378,8 @@
13761378

13771379
"@types/diff-match-patch": ["@types/[email protected]", "", {}, "sha512-xFdR6tkm0MWvBfO8xXCSsinYxHcqkQUlcHeSpMC2ukzOb6lwQAfDmW+Qt0AvlGd8HpsS28qKsB+oPeJn9I39jg=="],
13781380

1381+
"@types/escodegen": ["@types/[email protected]", "", {}, "sha512-IVvcNLEFbiL17qiGRGzyfx/u9K6lA5w6wcQSIgv2h4JG3ZAFIY1Be9ITTSPuARIxRpzW54s8OvcF6PdonBbDzg=="],
1382+
13791383
"@types/estree": ["@types/[email protected]", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
13801384

13811385
"@types/har-format": ["@types/[email protected]", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="],
@@ -1852,15 +1856,21 @@
18521856

18531857
"escape-string-regexp": ["[email protected]", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
18541858

1859+
"escodegen": ["[email protected]", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="],
1860+
18551861
"esniff": ["[email protected]", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="],
18561862

18571863
"esprima": ["[email protected]", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
18581864

1865+
"estraverse": ["[email protected]", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
1866+
18591867
"estree-walker": ["[email protected]", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
18601868

1869+
"esutils": ["[email protected]", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
1870+
18611871
"etag": ["[email protected]", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
18621872

1863-
"eval-estree-expression": ["eval-estree-expression@2.1.1", "", {}, "sha512-9kNUU4c+kUs5rKR7V5n81Ebp6fId1v01XSHshPuDIQ8N2VKAAzSzN3o/hfzERdNU6ZGh97LYFT7wWrL0cqhV3A=="],
1873+
"eval-estree-expression": ["eval-estree-expression@github:jonschlinkert/eval-estree-expression#9cf28d2", {}, "jonschlinkert-eval-estree-expression-9cf28d2"],
18641874

18651875
"event-emitter": ["[email protected]", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA=="],
18661876

packages/expr/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,19 @@
1212
},
1313
"sideEffects": false,
1414
"dependencies": {
15-
"eval-estree-expression": "^2.0.3",
15+
"eval-estree-expression": "github:jonschlinkert/eval-estree-expression#9cf28d2",
1616
"acorn": "^8.14.0",
1717
"acorn-loose": "8.4.0",
1818
"acorn-walk": "^8.3.4",
19+
"escodegen": "^2.1.0",
1920
"assert-never": "^1.2.1"
2021
},
2122
"devDependencies": {
2223
"bun-types": "^1.1.20",
2324
"@types/estree": "^1.0.6",
2425
"@babel/types": "^7.26.0",
25-
"@types/json-schema": "^7.0.15"
26+
"@types/json-schema": "^7.0.15",
27+
"@types/escodegen": "^0.0.10"
2628
},
2729
"scripts": {
2830
"build": "tsc --project tsconfig.build.json",

packages/expr/src/__tests__/autocomplete.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ describe('autocomplete', () => {
210210
'visitor.claims.hello.length',
211211
'visitor.claims.hello.at',
212212
'visitor.claims.hello.includes',
213+
'visitor.claims.hello.some',
214+
'visitor.claims.hello.every',
213215
],
214216
},
215217
},
@@ -268,6 +270,8 @@ describe('autocomplete', () => {
268270
'visitor.claims.hello.length',
269271
'visitor.claims.hello.at',
270272
'visitor.claims.hello.includes',
273+
'visitor.claims.hello.some',
274+
'visitor.claims.hello.every',
271275
],
272276
},
273277
},

packages/expr/src/__tests__/runtime.test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,29 @@ describe('ExpressionRuntime', () => {
4242
},
4343
expectedResult: true,
4444
},
45+
{
46+
scenario: 'array method',
47+
condition: 'reviews.every(review => !!review.status)',
48+
inputs: { reviews: [{ status: 'approved' }, { status: 'approved' }] },
49+
expectedResult: true,
50+
},
51+
{
52+
scenario: 'array every',
53+
condition: 'reviews.every(review => review.status === "approved")',
54+
inputs: { reviews: [{ status: 'approved' }, { status: 'approved' }] },
55+
expectedResult: true,
56+
},
57+
{
58+
scenario: 'array map',
59+
condition: '[1, 2, 3].map(n => n * x)',
60+
inputs: { x: 2 },
61+
expectedResult: [2, 4, 6],
62+
},
4563
])(
4664
'should properly evaluate/safeEvaluate a valid conditional expression: $scenario',
4765
({ condition, inputs, expectedResult }) => {
48-
expect(runtime.evaluate(condition, inputs)).toBe(expectedResult);
49-
expect(runtime.safeEvaluate(condition, inputs).value).toBe(expectedResult);
66+
expect(runtime.evaluate(condition, inputs)).toEqual(expectedResult);
67+
expect(runtime.safeEvaluate(condition, inputs).value).toEqual(expectedResult);
5068
}
5169
);
5270

packages/expr/src/runtime.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
tokenizer,
1010
} from 'acorn';
1111
import { parse as parseLoose } from 'acorn-loose';
12+
import escodegen from 'escodegen';
1213
import { evaluate } from 'eval-estree-expression';
1314

1415
import { AutoComplete } from './autocomplete';
@@ -49,6 +50,7 @@ export class ExpressionRuntime {
4950
return evaluate.sync<Expression>(parsed.result, inputs, {
5051
functions: true,
5152
withMembers: true,
53+
generate: escodegen.generate,
5254
});
5355
} catch (error) {
5456
throw error instanceof Error

packages/expr/src/symbols/__tests__/symbols.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ describe('ExpressionRuntime', () => {
338338
'visitor.claims.hello.length',
339339
'visitor.claims.hello.at',
340340
'visitor.claims.hello.includes',
341+
'visitor.claims.hello.some',
342+
'visitor.claims.hello.every',
341343
],
342344
});
343345
});

packages/expr/src/symbols/symbols.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,60 @@ const StandardLibrary: Partial<
259259
'true if the value searchElement is found within the array (or the part of the array indicated by the index fromIndex, if specified).',
260260
}),
261261
}),
262+
SymbolFunction({
263+
name: 'some',
264+
description:
265+
'Tests whether at least one element in the array passes the test implemented by the provided function.',
266+
link: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some',
267+
args: [
268+
SymbolFunction({
269+
name: 'callback',
270+
description: 'A function that tests each element of the array.',
271+
args: [
272+
{
273+
...arraySymbolDef.items,
274+
name: 'element',
275+
description: 'The current element being processed in the array.',
276+
},
277+
],
278+
returns: SymbolBoolean({
279+
description:
280+
'true if the callback function returns a truthy value for at least one element in the array.',
281+
}),
282+
}),
283+
],
284+
returns: SymbolBoolean({
285+
description:
286+
'true if the callback function returns a truthy value for at least one element in the array.',
287+
}),
288+
}),
289+
SymbolFunction({
290+
name: 'every',
291+
description:
292+
'Tests whether all elements in the array pass the test implemented by the provided function.',
293+
link: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every',
294+
args: [
295+
SymbolFunction({
296+
name: 'callback',
297+
description: 'A function that tests each element of the array.',
298+
args: [
299+
{
300+
...arraySymbolDef.items,
301+
name: 'element',
302+
description: 'The current element being processed in the array.',
303+
},
304+
],
305+
returns: SymbolBoolean({
306+
description:
307+
'true if the callback function returns a truthy value for all elements in the array.',
308+
}),
309+
}),
310+
],
311+
returns: SymbolBoolean({
312+
description:
313+
'true if the callback function returns a truthy value for all elements in the array.',
314+
}),
315+
}),
262316
],
263317
}),
264318
};

packages/expr/types/eval-estree-expression.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ declare module 'eval-estree-expression' {
1414
/**
1515
* Enable support for function statements and expressions by enabling the functions option AND by passing the .generate() function from the escodegen library. Default: undefined
1616
*/
17-
generate?: boolean;
17+
generate?: boolean | ((node: any) => string);
1818
/**
1919
* Enable the =~ regex operator to support testing values without using functions (example name =~ /^a.*c$/). Default: true
2020
*/

0 commit comments

Comments
 (0)