pacc 8.11.6 → 9.1.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/README.md CHANGED
@@ -546,6 +546,7 @@ Retrive attribute values from an object.
546
546
 
547
547
  * `object` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** attribute value source
548
548
  * `definitions` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 
549
+ * `filter` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** 
549
550
 
550
551
  Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** values
551
552
 
@@ -565,12 +566,12 @@ Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/G
565
566
 
566
567
  ## tokens
567
568
 
568
- Split property path into tokens
569
+ Split expression path into tokens.
569
570
 
570
571
  ### Parameters
571
572
 
572
573
  * `string` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
573
- * `options` (optional, default `{}`)
574
+ * `context` (optional, default `{}`)
574
575
 
575
576
  ## setAttribute
576
577
 
@@ -582,7 +583,7 @@ The name may be a property path like 'a.b.c'.
582
583
  * `object` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 
583
584
  * `expression` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
584
585
  * `value` **any** 
585
- * `definition` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** type def
586
+ * `definition` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** type def
586
587
 
587
588
  ## getAttribute
588
589
 
@@ -593,7 +594,7 @@ The name may be a property path like 'a.b.c' or a\[2]
593
594
 
594
595
  * `object` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 
595
596
  * `expression` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
596
- * `definition`  
597
+ * `definition` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** 
597
598
 
598
599
  Returns **any** value associated with the given property name
599
600
 
@@ -654,8 +655,8 @@ Type: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Globa
654
655
  * `str` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
655
656
  * `precedence` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?** (optional, default `0`)
656
657
  * `type` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** 
657
- * `led` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** (optional, default `()=>{}`)
658
- * `nud` (optional, default `()=>{}`)
658
+ * `led` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** (optional, default `(parser,node)=>node`)
659
+ * `nud` (optional, default `parser=>this`)
659
660
 
660
661
  Returns **[Token](#token)** 
661
662
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pacc",
3
- "version": "8.11.6",
3
+ "version": "9.1.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -17,6 +17,7 @@
17
17
  "keywords": [
18
18
  "attributes",
19
19
  "filtering",
20
+ "pratt",
20
21
  "property path",
21
22
  "xpath"
22
23
  ],
package/src/ast.mjs CHANGED
@@ -4,39 +4,8 @@
4
4
  */
5
5
 
6
6
  export function pathEval(node, current, context) {
7
- let collection = false;
8
- let first = true;
9
7
  for (const item of node.path) {
10
- switch (typeof item) {
11
- case "string":
12
- case "number":
13
- switch (typeof current) {
14
- case "undefined":
15
- current = context.getGlobal(item);
16
- break;
17
- default:
18
- if (collection) {
19
- current = current.map(x => x[item]);
20
- } else {
21
- current =
22
- current instanceof Map ? current.get(item) : current[item];
23
-
24
- if (first && current === undefined) {
25
- current = context.getGlobal(item);
26
- }
27
- }
28
- }
29
- break;
30
- case "object":
31
- if (typeof current.values === "function") {
32
- current = current.values();
33
- }
34
-
35
- current = current.filter(c => item.eval(item, c, context));
36
- collection = true;
37
- }
38
-
39
- first = false;
8
+ current = item.eval(item, current, context);
40
9
  }
41
10
 
42
11
  return current;
@@ -46,9 +15,60 @@ export function functionEval(node, current, context) {
46
15
  const args = node.args.map(a =>
47
16
  typeof a === "object" ? a.eval(a, current, context) : a
48
17
  );
49
- return context.getGlobal(node.path[0])(...args);
18
+ return context.valueFor(node.name)(...args);
19
+ }
20
+
21
+ export function keyedAccessOrGlobalEval(node, current, context) {
22
+ return keyedAccessEval(node, current, context) ?? context.valueFor(node.key);
23
+ }
24
+
25
+ export function keyedAccessEval(node, current, context) {
26
+ if (current === undefined) {
27
+ return undefined;
28
+ }
29
+ if (current instanceof Map) {
30
+ return current.get(node.key);
31
+ }
32
+ if (current instanceof Set) {
33
+ return current.has(node.key) ? node.key : undefined;
34
+ }
35
+ if (current instanceof Iterator) {
36
+ return current.map(item => item[node.key]);
37
+ }
38
+
39
+ switch (typeof current[node.key]) {
40
+ case "function": {
41
+ const value = current[node.key]();
42
+
43
+ if (typeof value[Symbol.iterator] === "function") {
44
+ return [...value];
45
+ //return value[Symbol.iterator]();
46
+ }
47
+ return value;
48
+ }
49
+ case "undefined":
50
+ return context.valueFor(node.key, current);
51
+ }
52
+
53
+ return current[node.key];
54
+ }
55
+
56
+ export function filterEval(node, current, context) {
57
+ if (typeof current.values === "function") {
58
+ current = current.values();
59
+ }
60
+
61
+ return current.filter(item => node.filter.eval(node.filter, item, context));
62
+ }
63
+
64
+ export function nullFilterEval(node, current, context) {
65
+ if (typeof current.values === "function") {
66
+ current = current.values();
67
+ }
68
+
69
+ return current;
50
70
  }
51
71
 
52
- export const ASTTrue = {
53
- eval: () => true
72
+ export const ASTNullFilter = {
73
+ eval: nullFilterEval
54
74
  };
package/src/expand.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { parse } from "./expression.mjs";
1
+ import { parse } from "./parser.mjs";
2
2
 
3
3
  const maxNestingLevel = 8;
4
4
 
package/src/module.mjs CHANGED
@@ -7,7 +7,7 @@ export * from "./filter.mjs";
7
7
  export * from "./multiple.mjs";
8
8
  export * from "./common-attributes.mjs";
9
9
  export * from "./properties.mjs";
10
- export * from "./expression.mjs";
10
+ export * from "./parser.mjs";
11
11
  export * from "./expand.mjs";
12
12
  export * from "./environment.mjs";
13
13
  export {
package/src/multiple.mjs CHANGED
@@ -15,21 +15,17 @@ export function setAttributes(object, source, definitions, cb) {
15
15
  let value = getAttribute(source, name);
16
16
 
17
17
  if (value === undefined) {
18
- if (def.default === undefined) {
18
+ if (
19
+ def.default === undefined ||
20
+ getAttribute(object, name) !== undefined
21
+ ) {
19
22
  continue;
20
- } else {
21
- if (getAttribute(object, name, def) !== undefined) {
22
- continue;
23
- }
24
- value = def.default;
25
23
  }
24
+ value = def.default;
26
25
  }
27
26
 
28
- if (def.set) {
29
- def.set.call(object, value, def);
30
- } else {
31
- setAttribute(object, name, value, def);
32
- }
27
+ setAttribute(object, name, value, def);
28
+
33
29
  if (cb) {
34
30
  cb(def, name, value);
35
31
  }
@@ -40,12 +36,13 @@ export function setAttributes(object, source, definitions, cb) {
40
36
  * Retrive attribute values from an object.
41
37
  * @param {Object} object attribute value source
42
38
  * @param {Object} definitions
39
+ * @param {Function} [filter]
43
40
  * @return {Object} values
44
41
  */
45
- export function getAttributes(object, definitions) {
42
+ export function getAttributes(object, definitions, filter) {
46
43
  const result = {};
47
44
 
48
- for (const [path, def] of attributeIterator(definitions)) {
45
+ for (const [path, def] of attributeIterator(definitions, filter)) {
49
46
  const name = path.join(".");
50
47
 
51
48
  const value = getAttribute(object, name, def);
@@ -1,10 +1,8 @@
1
1
  import { tokens, EOF } from "./tokens.mjs";
2
2
 
3
3
  export function parseOnly(input, context = {}) {
4
- context.getGlobal ||= a => globals[a];
5
-
6
4
  input = tokens(input, context);
7
-
5
+
8
6
  let node, token, value;
9
7
 
10
8
  function advance() {
@@ -42,7 +40,7 @@ export function parseOnly(input, context = {}) {
42
40
  expression(precedence) {
43
41
  const last = token;
44
42
  advance();
45
- node = last.nud ? last.nud(parser) : last;
43
+ node = last.nud(parser);
46
44
 
47
45
  while (token.precedence > precedence) {
48
46
  const last = token;
@@ -63,35 +61,3 @@ export function parse(input, context) {
63
61
  const result = parseOnly(input, context);
64
62
  return result.eval ? result.eval(result, context.root, context) : result;
65
63
  }
66
-
67
- export const globals = {
68
- in: (a, b) => {
69
- if (b?.[Symbol.iterator]) {
70
- for (const x of b) {
71
- if (x === a) {
72
- return true;
73
- }
74
- }
75
- }
76
- return false;
77
- },
78
- ceil: Math.ceil,
79
- floor: Math.floor,
80
- abs: Math.abs,
81
- min: Math.min,
82
- max: Math.max,
83
- encodeURI: encodeURI,
84
- decodeURI: decodeURI,
85
- encodeURIComponent: encodeURIComponent,
86
- decodeURIComponent: decodeURIComponent,
87
- trim: a => a.trim(),
88
- uppercase: a => a.toUpperCase(),
89
- lowercase: a => a.toLowerCase(),
90
- substring: (s, a, b) => s.substring(a, b),
91
- length: s => s.length,
92
- join: (separator, ...args) =>
93
- args
94
- .map(item => (item instanceof Iterator ? Array.from(item) : item))
95
- .flat()
96
- .join(separator)
97
- };
@@ -19,8 +19,9 @@ import {
19
19
  NUMBER,
20
20
  BOOLEAN
21
21
  } from "./tokens.mjs";
22
- import { parseOnly } from "./expression.mjs";
22
+ import { parseOnly, parse } from "./parser.mjs";
23
23
  import { toInternal } from "./attributes.mjs";
24
+ import { keyedAccessOrGlobalEval, keyedAccessEval, pathEval } from "./ast.mjs";
24
25
 
25
26
  /**
26
27
  * Set object attribute.
@@ -28,31 +29,43 @@ import { toInternal } from "./attributes.mjs";
28
29
  * @param {Object} object
29
30
  * @param {string} expression
30
31
  * @param {any} value
31
- * @param {Object} definition type def
32
+ * @param {Object} [definition] type def
32
33
  */
33
34
  export function setAttribute(object, expression, value, definition) {
34
- const { path } = parseOnly(expression);
35
+ if(definition?.set) {
36
+ definition.set.call(object, value, definition);
37
+ return;
38
+ }
35
39
 
36
- let anchor, anchorKey;
40
+ const context = {};
41
+ const ast = parseOnly(expression, context);
37
42
 
38
- for (const key of path) {
39
- if (anchor) {
40
- anchor[anchorKey] = object = typeof key === "string" ? {} : [];
41
- anchor = undefined;
42
- }
43
+ let parent, parentItem;
43
44
 
44
- const next = object[key];
45
+ switch (ast.eval) {
46
+ case keyedAccessEval:
47
+ case keyedAccessOrGlobalEval:
48
+ object[ast.key] = toInternal(value, definition);
49
+ break;
45
50
 
46
- if (next === undefined || typeof next !== "object") {
47
- anchor = object;
48
- anchorKey = key;
49
- } else {
50
- object = next;
51
- }
52
- }
51
+ case pathEval:
52
+ for (const item of ast.path) {
53
+ if (typeof object !== "object") {
54
+ object = typeof item.key === "number" ? [] : {};
55
+ parent[parentItem.key] = object;
56
+ }
57
+
58
+ parent = object;
59
+ parentItem = item;
60
+
61
+ object = item.eval(item, object, context);
62
+ }
53
63
 
54
- if (anchor) {
55
- anchor[anchorKey] = toInternal(value, definition);
64
+ parent[parentItem.key] = toInternal(value, definition);
65
+ break;
66
+
67
+ default:
68
+ console.log("UKNOWN AST",ast);
56
69
  }
57
70
  }
58
71
 
@@ -61,34 +74,11 @@ export function setAttribute(object, expression, value, definition) {
61
74
  * The name may be a property path like 'a.b.c' or a[2]
62
75
  * @param {Object} object
63
76
  * @param {string} expression
77
+ * @param {Object} [definition]
64
78
  * @returns {any} value associated with the given property name
65
79
  */
66
80
  export function getAttribute(object, expression, definition) {
67
- const { path } = parseOnly(expression);
68
-
69
- for (const key of path) {
70
- if (object !== undefined) {
71
- switch (typeof object[key]) {
72
- case "function":
73
- object = object[key]();
74
- if (typeof object[Symbol.iterator] === "function") {
75
- object = [...object];
76
- }
77
- break;
78
- default:
79
- object = object[key];
80
- break;
81
- case "undefined":
82
- return undefined;
83
- }
84
- }
85
- }
86
-
87
- if (object === undefined && definition) {
88
- object = definition.default;
89
- }
90
-
91
- return object;
81
+ return parse(expression, { root: object }) ?? definition?.default;
92
82
  }
93
83
 
94
84
  /**
package/src/tokens.mjs CHANGED
@@ -1,4 +1,11 @@
1
- import { pathEval, ASTTrue, functionEval } from "./ast.mjs";
1
+ import {
2
+ pathEval,
3
+ ASTNullFilter,
4
+ keyedAccessEval,
5
+ keyedAccessOrGlobalEval,
6
+ filterEval,
7
+ functionEval
8
+ } from "./ast.mjs";
2
9
 
3
10
  /**
4
11
  * Token lookup
@@ -22,8 +29,8 @@ function createToken(
22
29
  str,
23
30
  precedence = 0,
24
31
  type,
25
- led = () => {},
26
- nud = () => {}
32
+ led = (parser, node) => node,
33
+ nud = parser => this
27
34
  ) {
28
35
  const token = { str, precedence, type };
29
36
 
@@ -146,18 +153,16 @@ export /** @type {Token} */ const LESS_EQUAL = createBinopToken(
146
153
  );
147
154
  export /** @type {Token} */ const OPEN_ROUND = createToken(
148
155
  "(",
149
- 40,
156
+ 100,
150
157
  "prefix",
151
- (parser, left) => {
158
+ (parser, left) => {
152
159
  const args = parser.expression(0);
153
160
  parser.expect(CLOSE_ROUND);
154
-
155
- // TODO why is there a right side ?
156
- const node = left.right || left;
157
- node.eval = functionEval;
158
- node.args = Array.isArray(args) ? args : [args];
159
-
160
- return left;
161
+ return {
162
+ eval: functionEval,
163
+ name: left.key,
164
+ args: Array.isArray(args) ? args : [args]
165
+ };
161
166
  },
162
167
  parser => {
163
168
  const result = parser.expression(0);
@@ -167,38 +172,40 @@ export /** @type {Token} */ const OPEN_ROUND = createToken(
167
172
  );
168
173
 
169
174
  export /** @type {Token} */ const CLOSE_ROUND = createToken(")", 0);
175
+
176
+ function createFilter(parser) {
177
+ if (parser.token === CLOSE_BRACKET) {
178
+ parser.advance();
179
+ return ASTNullFilter;
180
+ }
181
+
182
+ const filter = parser.expression(0);
183
+ parser.expect(CLOSE_BRACKET);
184
+
185
+ switch (typeof filter) {
186
+ case "string":
187
+ case "number":
188
+ return { eval: keyedAccessEval, key: filter };
189
+ default:
190
+ return { eval: filterEval, filter };
191
+ }
192
+ }
193
+
170
194
  export /** @type {Token} */ const OPEN_BRACKET = createToken(
171
195
  "[",
172
- 10,
196
+ 80,
173
197
  "prefix",
174
198
  (parser, left) => {
175
- if (parser.token === CLOSE_BRACKET) {
176
- parser.advance();
177
- left.path.push(ASTTrue);
178
- } else {
179
- const predicate = parser.expression(0);
180
- parser.expect(CLOSE_BRACKET);
181
- left.path.push(predicate);
182
- }
183
- return left;
184
- },
185
- parser => {
186
- if (parser.token === CLOSE_BRACKET) {
187
- parser.advance();
188
- return ASTTrue;
189
- }
199
+ const node = createFilter(parser);
190
200
 
191
- const node = parser.expression(0);
192
- parser.expect(CLOSE_BRACKET);
193
-
194
- switch (typeof node) {
195
- case "string":
196
- case "number":
197
- return { eval: pathEval, path: [node] };
201
+ if (left.key) {
202
+ return { eval: pathEval, path: [left, node] };
198
203
  }
199
204
 
200
- return node;
201
- }
205
+ left.path.push(node);
206
+ return left;
207
+ },
208
+ parser => createFilter(parser)
202
209
  );
203
210
 
204
211
  export /** @type {Token} */ const CLOSE_BRACKET = createToken("]", 0);
@@ -207,19 +214,27 @@ export /** @type {Token} */ const CLOSE_CURLY = createToken("}");
207
214
  export /** @type {Token} */ const QUESTION = createToken("?", 20, "infix");
208
215
  export /** @type {Token} */ const COLON = createToken(":", undefined, "infix");
209
216
  export /** @type {Token} */ const SEMICOLON = createToken(";");
210
- export /** @type {Token} */ const COMMA = createToken(",",20,"infix",(left,right)=>Array.isArray(left) ? [...left,right] : [left,right]);
217
+ export /** @type {Token} */ const COMMA = createToken(
218
+ ",",
219
+ 20,
220
+ "infix",
221
+ (left, right) => (Array.isArray(left) ? [...left, right] : [left, right])
222
+ );
211
223
 
212
224
  export /** @type {Token} */ const DOT = createToken(
213
225
  ".",
214
226
  80,
215
227
  "infix",
216
228
  (left, right) => {
229
+ if (right.eval === keyedAccessOrGlobalEval) {
230
+ right.eval = keyedAccessEval;
231
+ }
217
232
  if (left.path) {
218
- right.path.unshift(...left.path);
219
- } else {
220
- right.path.unshift(left);
233
+ left.path.push(right);
234
+ return left;
221
235
  }
222
- return right;
236
+
237
+ return { eval: pathEval, path: [left, right] };
223
238
  }
224
239
  );
225
240
  export /** @type {Token} */ const AMPERSAND = createToken("&");
@@ -242,7 +257,7 @@ export /** @type {Token} */ const IDENTIFIER = createToken(
242
257
  undefined,
243
258
  undefined,
244
259
  parser => {
245
- return { eval: pathEval, path: [parser.value] };
260
+ return { eval: keyedAccessOrGlobalEval, key: parser.value };
246
261
  }
247
262
  );
248
263
 
@@ -279,11 +294,6 @@ export /** @type {Token} */ const EOF = createToken(
279
294
  }
280
295
  );
281
296
 
282
- export const keywords = {
283
- true: [BOOLEAN, true],
284
- false: [BOOLEAN, false]
285
- };
286
-
287
297
  const esc = {
288
298
  b: "\b",
289
299
  f: "\f",
@@ -293,20 +303,65 @@ const esc = {
293
303
  v: "\v"
294
304
  };
295
305
 
306
+ export const keywords = {
307
+ true: [BOOLEAN, true],
308
+ false: [BOOLEAN, false]
309
+ };
310
+
311
+ export const globals = {
312
+ in: (a, b) => {
313
+ if (b?.[Symbol.iterator]) {
314
+ for (const x of b) {
315
+ if (x === a) {
316
+ return true;
317
+ }
318
+ }
319
+ }
320
+ return false;
321
+ },
322
+ ceil: Math.ceil,
323
+ floor: Math.floor,
324
+ abs: Math.abs,
325
+ min: Math.min,
326
+ max: Math.max,
327
+ encodeURI: encodeURI,
328
+ decodeURI: decodeURI,
329
+ encodeURIComponent: encodeURIComponent,
330
+ decodeURIComponent: decodeURIComponent,
331
+ trim: a => a.trim(),
332
+ uppercase: a => a.toUpperCase(),
333
+ lowercase: a => a.toLowerCase(),
334
+ substring: (s, a, b) => s.substring(a, b),
335
+ length: s => s.length,
336
+ join: (separator, ...args) =>
337
+ args
338
+ .map(item => (item instanceof Iterator ? Array.from(item) : item))
339
+ .flat()
340
+ .join(separator),
341
+ sort: data => {
342
+ return data.sort();
343
+ },
344
+ truncate: (data, length) => {
345
+ data.length = length;
346
+ return data;
347
+ }
348
+ };
349
+
296
350
  /**
297
- * Split property path into tokens
351
+ * Split expression path into tokens.
298
352
  * @generator
299
353
  * @param {string} string
300
354
  * @yields {Token}
301
355
  */
302
- export function* tokens(string, options = {}) {
303
- options.keywords ||= keywords;
304
- options.parseFloat ||= parseFloat;
356
+ export function* tokens(string, context = {}) {
357
+ context.keywords ||= keywords;
358
+ context.parseFloat ||= parseFloat;
359
+ context.valueFor ||= (name, at) => globals[name];
305
360
 
306
361
  let state, value, hex, quote;
307
362
 
308
363
  const keywordOrIdentifier = () =>
309
- options.keywords[value] || [IDENTIFIER, value];
364
+ context.keywords[value] || [IDENTIFIER, value];
310
365
  const startString = c => {
311
366
  value = "";
312
367
  state = "string";
@@ -343,7 +398,7 @@ export function* tokens(string, options = {}) {
343
398
  case " ":
344
399
  switch (state) {
345
400
  case "number":
346
- yield [NUMBER, options.parseFloat(value)];
401
+ yield [NUMBER, context.parseFloat(value)];
347
402
  state = undefined;
348
403
  case undefined:
349
404
  break;
@@ -372,7 +427,7 @@ export function* tokens(string, options = {}) {
372
427
  case "'":
373
428
  switch (state) {
374
429
  case "number":
375
- yield [NUMBER, options.parseFloat(value)];
430
+ yield [NUMBER, context.parseFloat(value)];
376
431
  case undefined:
377
432
  startString(c);
378
433
  break;
@@ -400,7 +455,7 @@ export function* tokens(string, options = {}) {
400
455
  case "|":
401
456
  switch (state) {
402
457
  case "number":
403
- yield [NUMBER, options.parseFloat(value)];
458
+ yield [NUMBER, context.parseFloat(value)];
404
459
  case undefined:
405
460
  state = c;
406
461
  break;
@@ -431,7 +486,7 @@ export function* tokens(string, options = {}) {
431
486
  case "=":
432
487
  switch (state) {
433
488
  case "number":
434
- yield [NUMBER, options.parseFloat(value)];
489
+ yield [NUMBER, context.parseFloat(value)];
435
490
  case undefined:
436
491
  state = c;
437
492
  break;
@@ -472,7 +527,7 @@ export function* tokens(string, options = {}) {
472
527
  case "}":
473
528
  switch (state) {
474
529
  case "number":
475
- yield [NUMBER, options.parseFloat(value)];
530
+ yield [NUMBER, context.parseFloat(value)];
476
531
  case undefined:
477
532
  state = c;
478
533
  break;
@@ -523,7 +578,7 @@ export function* tokens(string, options = {}) {
523
578
  default:
524
579
  switch (state) {
525
580
  case "number":
526
- yield [NUMBER, options.parseFloat(value)];
581
+ yield [NUMBER, context.parseFloat(value)];
527
582
  case undefined:
528
583
  state = "identifier";
529
584
  value = c;
@@ -546,7 +601,7 @@ export function* tokens(string, options = {}) {
546
601
  case "string":
547
602
  throw new Error("unterminated string", { cause: string });
548
603
  case "number":
549
- yield [NUMBER, options.parseFloat(value)];
604
+ yield [NUMBER, context.parseFloat(value)];
550
605
  break;
551
606
  case "identifier":
552
607
  yield keywordOrIdentifier();
package/types/ast.d.mts CHANGED
@@ -4,8 +4,12 @@
4
4
  */
5
5
  export function pathEval(node: any, current: any, context: any): any;
6
6
  export function functionEval(node: any, current: any, context: any): any;
7
- export namespace ASTTrue {
8
- function eval(): boolean;
7
+ export function keyedAccessOrGlobalEval(node: any, current: any, context: any): any;
8
+ export function keyedAccessEval(node: any, current: any, context: any): any;
9
+ export function filterEval(node: any, current: any, context: any): any;
10
+ export function nullFilterEval(node: any, current: any, context: any): any;
11
+ export namespace ASTNullFilter {
12
+ export { nullFilterEval as eval };
9
13
  }
10
14
  export type AST = {
11
15
  eval?: Function;
@@ -7,7 +7,7 @@ export * from "./filter.mjs";
7
7
  export * from "./multiple.mjs";
8
8
  export * from "./common-attributes.mjs";
9
9
  export * from "./properties.mjs";
10
- export * from "./expression.mjs";
10
+ export * from "./parser.mjs";
11
11
  export * from "./expand.mjs";
12
12
  export * from "./environment.mjs";
13
13
  export { setAttribute, getAttribute, getAttributeAndOperator } from "./settergetter.mjs";
@@ -10,9 +10,10 @@ export function setAttributes(object: any, source: any, definitions: any, cb: Fu
10
10
  * Retrive attribute values from an object.
11
11
  * @param {Object} object attribute value source
12
12
  * @param {Object} definitions
13
+ * @param {Function} [filter]
13
14
  * @return {Object} values
14
15
  */
15
- export function getAttributes(object: any, definitions: any): any;
16
+ export function getAttributes(object: any, definitions: any, filter?: Function): any;
16
17
  /**
17
18
  * Retrive attribute values from an object.
18
19
  * @param {Object} object attribute value source
@@ -0,0 +1,2 @@
1
+ export function parseOnly(input: any, context?: {}): any;
2
+ export function parse(input: any, context: any): any;
@@ -4,17 +4,18 @@
4
4
  * @param {Object} object
5
5
  * @param {string} expression
6
6
  * @param {any} value
7
- * @param {Object} definition type def
7
+ * @param {Object} [definition] type def
8
8
  */
9
- export function setAttribute(object: any, expression: string, value: any, definition: any): void;
9
+ export function setAttribute(object: any, expression: string, value: any, definition?: any): void;
10
10
  /**
11
11
  * Deliver attribute value.
12
12
  * The name may be a property path like 'a.b.c' or a[2]
13
13
  * @param {Object} object
14
14
  * @param {string} expression
15
+ * @param {Object} [definition]
15
16
  * @returns {any} value associated with the given property name
16
17
  */
17
- export function getAttribute(object: any, expression: string, definition: any): any;
18
+ export function getAttribute(object: any, expression: string, definition?: any): any;
18
19
  /**
19
20
  * Deliver attribute value and operator.
20
21
  * The name may be a property path like 'a.b.c <='.
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Split property path into tokens
2
+ * Split expression path into tokens.
3
3
  * @generator
4
4
  * @param {string} string
5
5
  * @yields {Token}
6
6
  */
7
- export function tokens(string: string, options?: {}): Generator<any, void, unknown>;
7
+ export function tokens(string: string, context?: {}): Generator<any, void, unknown>;
8
8
  export namespace PLUS {
9
9
  let str: string;
10
10
  }
@@ -46,6 +46,27 @@ export namespace keywords {
46
46
  let _false: (boolean | Token)[];
47
47
  export { _false as false };
48
48
  }
49
+ export namespace globals {
50
+ export function _in(a: any, b: any): boolean;
51
+ export { _in as in };
52
+ export let ceil: (x: number) => number;
53
+ export let floor: (x: number) => number;
54
+ export let abs: (x: number) => number;
55
+ export let min: (...values: number[]) => number;
56
+ export let max: (...values: number[]) => number;
57
+ export let encodeURI: typeof globalThis.encodeURI;
58
+ export let decodeURI: typeof globalThis.decodeURI;
59
+ export let encodeURIComponent: typeof globalThis.encodeURIComponent;
60
+ export let decodeURIComponent: typeof globalThis.decodeURIComponent;
61
+ export function trim(a: any): any;
62
+ export function uppercase(a: any): any;
63
+ export function lowercase(a: any): any;
64
+ export function substring(s: any, a: any, b: any): any;
65
+ export function length(s: any): any;
66
+ export function join(separator: any, ...args: any[]): string;
67
+ export function sort(data: any): any;
68
+ export function truncate(data: any, length: any): any;
69
+ }
49
70
  export type Token = {
50
71
  str: string;
51
72
  };
@@ -1,21 +0,0 @@
1
- export function parseOnly(input: any, context?: {}): any;
2
- export function parse(input: any, context: any): any;
3
- export namespace globals {
4
- export function _in(a: any, b: any): boolean;
5
- export { _in as in };
6
- export let ceil: (x: number) => number;
7
- export let floor: (x: number) => number;
8
- export let abs: (x: number) => number;
9
- export let min: (...values: number[]) => number;
10
- export let max: (...values: number[]) => number;
11
- export let encodeURI: typeof globalThis.encodeURI;
12
- export let decodeURI: typeof globalThis.decodeURI;
13
- export let encodeURIComponent: typeof globalThis.encodeURIComponent;
14
- export let decodeURIComponent: typeof globalThis.decodeURIComponent;
15
- export function trim(a: any): any;
16
- export function uppercase(a: any): any;
17
- export function lowercase(a: any): any;
18
- export function substring(s: any, a: any, b: any): any;
19
- export function length(s: any): any;
20
- export function join(separator: any, ...args: any[]): string;
21
- }