@player-ui/player 0.8.0--canary.307.9621 → 0.8.0-next.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.
Files changed (214) hide show
  1. package/dist/Player.native.js +11630 -0
  2. package/dist/Player.native.js.map +1 -0
  3. package/dist/cjs/index.cjs +5626 -0
  4. package/dist/cjs/index.cjs.map +1 -0
  5. package/dist/{index.esm.js → index.legacy-esm.js} +2044 -1667
  6. package/dist/{index.cjs.js → index.mjs} +2052 -1761
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +29 -63
  9. package/src/__tests__/data.test.ts +498 -0
  10. package/src/__tests__/flow.test.ts +312 -0
  11. package/src/__tests__/helpers/action-exp.plugin.ts +22 -0
  12. package/src/__tests__/helpers/actions.flow.ts +67 -0
  13. package/src/__tests__/helpers/binding.plugin.ts +125 -0
  14. package/src/__tests__/helpers/expression.plugin.ts +88 -0
  15. package/src/__tests__/helpers/transform-plugin.ts +19 -0
  16. package/src/__tests__/helpers/validation.flow.ts +56 -0
  17. package/src/__tests__/player.test.ts +597 -0
  18. package/src/__tests__/string-resolver.test.ts +186 -0
  19. package/src/__tests__/validation.test.ts +3555 -0
  20. package/src/__tests__/view.test.ts +715 -0
  21. package/src/binding/__tests__/binding.test.ts +113 -0
  22. package/src/binding/__tests__/index.test.ts +208 -0
  23. package/src/binding/__tests__/resolver.test.ts +83 -0
  24. package/src/binding/binding.ts +6 -6
  25. package/src/binding/index.ts +34 -34
  26. package/src/binding/resolver.ts +19 -19
  27. package/src/binding/utils.ts +7 -7
  28. package/src/binding-grammar/__tests__/parser.test.ts +64 -0
  29. package/src/binding-grammar/__tests__/test-utils/ast-cases.ts +198 -0
  30. package/src/binding-grammar/__tests__/test-utils/perf-test.ts +66 -0
  31. package/src/binding-grammar/ast.ts +11 -11
  32. package/src/binding-grammar/custom/index.ts +19 -22
  33. package/src/binding-grammar/ebnf/index.ts +20 -21
  34. package/src/binding-grammar/ebnf/types.ts +13 -13
  35. package/src/binding-grammar/index.ts +4 -4
  36. package/src/binding-grammar/parsimmon/index.ts +14 -14
  37. package/src/controllers/constants/__tests__/index.test.ts +106 -0
  38. package/src/controllers/constants/index.ts +3 -3
  39. package/src/controllers/constants/utils.ts +4 -4
  40. package/src/controllers/data/controller.ts +22 -22
  41. package/src/controllers/data/index.ts +1 -1
  42. package/src/controllers/data/utils.ts +7 -7
  43. package/src/controllers/flow/__tests__/controller.test.ts +195 -0
  44. package/src/controllers/flow/__tests__/flow.test.ts +381 -0
  45. package/src/controllers/flow/controller.ts +13 -13
  46. package/src/controllers/flow/flow.ts +23 -23
  47. package/src/controllers/flow/index.ts +2 -2
  48. package/src/controllers/index.ts +5 -5
  49. package/src/controllers/validation/binding-tracker.ts +71 -59
  50. package/src/controllers/validation/controller.ts +104 -104
  51. package/src/controllers/validation/index.ts +2 -2
  52. package/src/controllers/view/asset-transform.ts +20 -20
  53. package/src/controllers/view/controller.ts +27 -27
  54. package/src/controllers/view/index.ts +4 -4
  55. package/src/controllers/view/store.ts +3 -3
  56. package/src/controllers/view/types.ts +7 -7
  57. package/src/data/__tests__/__snapshots__/dependency-tracker.test.ts.snap +64 -0
  58. package/src/data/__tests__/dependency-tracker.test.ts +146 -0
  59. package/src/data/__tests__/local-model.test.ts +46 -0
  60. package/src/data/__tests__/model.test.ts +78 -0
  61. package/src/data/dependency-tracker.ts +16 -16
  62. package/src/data/index.ts +4 -4
  63. package/src/data/local-model.ts +6 -6
  64. package/src/data/model.ts +17 -17
  65. package/src/data/noop-model.ts +1 -1
  66. package/src/expressions/__tests__/__snapshots__/parser.test.ts.snap +854 -0
  67. package/src/expressions/__tests__/evaluator-functions.test.ts +47 -0
  68. package/src/expressions/__tests__/evaluator.test.ts +410 -0
  69. package/src/expressions/__tests__/parser.test.ts +115 -0
  70. package/src/expressions/__tests__/utils.test.ts +44 -0
  71. package/src/expressions/evaluator-functions.ts +6 -6
  72. package/src/expressions/evaluator.ts +71 -67
  73. package/src/expressions/index.ts +4 -4
  74. package/src/expressions/parser.ts +102 -105
  75. package/src/expressions/types.ts +29 -21
  76. package/src/expressions/utils.ts +32 -21
  77. package/src/index.ts +13 -13
  78. package/src/logger/__tests__/consoleLogger.test.ts +46 -0
  79. package/src/logger/__tests__/noopLogger.test.ts +13 -0
  80. package/src/logger/__tests__/proxyLogger.test.ts +31 -0
  81. package/src/logger/__tests__/tapableLogger.test.ts +41 -0
  82. package/src/logger/consoleLogger.ts +9 -9
  83. package/src/logger/index.ts +5 -5
  84. package/src/logger/noopLogger.ts +1 -1
  85. package/src/logger/proxyLogger.ts +6 -6
  86. package/src/logger/tapableLogger.ts +7 -7
  87. package/src/logger/types.ts +2 -2
  88. package/src/player.ts +60 -58
  89. package/src/plugins/default-exp-plugin.ts +10 -10
  90. package/src/plugins/default-view-plugin.ts +29 -0
  91. package/src/plugins/flow-exp-plugin.ts +6 -6
  92. package/src/schema/__tests__/schema.test.ts +243 -0
  93. package/src/schema/index.ts +2 -2
  94. package/src/schema/schema.ts +24 -24
  95. package/src/schema/types.ts +4 -4
  96. package/src/string-resolver/__tests__/index.test.ts +361 -0
  97. package/src/string-resolver/index.ts +17 -17
  98. package/src/types.ts +17 -17
  99. package/src/utils/__tests__/replaceParams.test.ts +33 -0
  100. package/src/utils/index.ts +1 -1
  101. package/src/utils/replaceParams.ts +1 -1
  102. package/src/validator/__tests__/binding-map-splice.test.ts +53 -0
  103. package/src/validator/__tests__/validation-middleware.test.ts +127 -0
  104. package/src/validator/binding-map-splice.ts +5 -5
  105. package/src/validator/index.ts +4 -4
  106. package/src/validator/registry.ts +1 -1
  107. package/src/validator/types.ts +13 -13
  108. package/src/validator/validation-middleware.ts +15 -15
  109. package/src/view/__tests__/view.immutable.test.ts +269 -0
  110. package/src/view/__tests__/view.test.ts +959 -0
  111. package/src/view/builder/index.test.ts +69 -0
  112. package/src/view/builder/index.ts +3 -3
  113. package/src/view/index.ts +5 -5
  114. package/src/view/parser/__tests__/__snapshots__/parser.test.ts.snap +394 -0
  115. package/src/view/parser/__tests__/parser.test.ts +264 -0
  116. package/src/view/parser/index.ts +43 -33
  117. package/src/view/parser/types.ts +11 -11
  118. package/src/view/parser/utils.ts +5 -5
  119. package/src/view/plugins/__tests__/__snapshots__/template.test.ts.snap +278 -0
  120. package/src/view/plugins/__tests__/applicability.test.ts +265 -0
  121. package/src/view/plugins/__tests__/string.test.ts +122 -0
  122. package/src/view/plugins/__tests__/template.test.ts +724 -0
  123. package/src/view/plugins/applicability.ts +19 -19
  124. package/src/view/plugins/index.ts +4 -5
  125. package/src/view/plugins/options.ts +1 -1
  126. package/src/view/plugins/string-resolver.ts +22 -22
  127. package/src/view/plugins/switch.ts +22 -23
  128. package/src/view/plugins/template-plugin.ts +26 -27
  129. package/src/view/resolver/__tests__/dependencies.test.ts +321 -0
  130. package/src/view/resolver/__tests__/edgecases.test.ts +626 -0
  131. package/src/view/resolver/index.ts +42 -42
  132. package/src/view/resolver/types.ts +21 -20
  133. package/src/view/resolver/utils.ts +9 -9
  134. package/src/view/view.ts +32 -22
  135. package/types/binding/binding.d.ts +50 -0
  136. package/types/binding/index.d.ts +29 -0
  137. package/types/binding/resolver.d.ts +26 -0
  138. package/types/binding/utils.d.ts +12 -0
  139. package/types/binding-grammar/ast.d.ts +67 -0
  140. package/types/binding-grammar/custom/index.d.ts +4 -0
  141. package/types/binding-grammar/ebnf/index.d.ts +4 -0
  142. package/types/binding-grammar/ebnf/types.d.ts +75 -0
  143. package/types/binding-grammar/index.d.ts +5 -0
  144. package/types/binding-grammar/parsimmon/index.d.ts +4 -0
  145. package/types/controllers/constants/index.d.ts +45 -0
  146. package/types/controllers/constants/utils.d.ts +6 -0
  147. package/types/controllers/data/controller.d.ts +45 -0
  148. package/types/controllers/data/index.d.ts +2 -0
  149. package/types/controllers/data/utils.d.ts +14 -0
  150. package/types/controllers/flow/controller.d.ts +25 -0
  151. package/types/controllers/flow/flow.d.ts +50 -0
  152. package/types/controllers/flow/index.d.ts +3 -0
  153. package/types/controllers/index.d.ts +6 -0
  154. package/types/controllers/validation/binding-tracker.d.ts +32 -0
  155. package/types/controllers/validation/controller.d.ts +151 -0
  156. package/types/controllers/validation/index.d.ts +3 -0
  157. package/types/controllers/view/asset-transform.d.ts +19 -0
  158. package/types/controllers/view/controller.d.ts +37 -0
  159. package/types/controllers/view/index.d.ts +5 -0
  160. package/types/controllers/view/store.d.ts +20 -0
  161. package/types/controllers/view/types.d.ts +16 -0
  162. package/types/data/dependency-tracker.d.ts +49 -0
  163. package/types/data/index.d.ts +5 -0
  164. package/types/data/local-model.d.ts +16 -0
  165. package/types/data/model.d.ts +86 -0
  166. package/types/data/noop-model.d.ts +13 -0
  167. package/types/expressions/evaluator-functions.d.ts +15 -0
  168. package/types/expressions/evaluator.d.ts +52 -0
  169. package/types/expressions/index.d.ts +5 -0
  170. package/types/expressions/parser.d.ts +10 -0
  171. package/types/expressions/types.d.ts +144 -0
  172. package/types/expressions/utils.d.ts +12 -0
  173. package/types/index.d.ts +14 -0
  174. package/types/logger/consoleLogger.d.ts +17 -0
  175. package/types/logger/index.d.ts +6 -0
  176. package/types/logger/noopLogger.d.ts +10 -0
  177. package/types/logger/proxyLogger.d.ts +15 -0
  178. package/types/logger/tapableLogger.d.ts +23 -0
  179. package/types/logger/types.d.ts +6 -0
  180. package/types/player.d.ts +101 -0
  181. package/types/plugins/default-exp-plugin.d.ts +9 -0
  182. package/types/plugins/default-view-plugin.d.ts +9 -0
  183. package/types/plugins/flow-exp-plugin.d.ts +11 -0
  184. package/types/schema/index.d.ts +3 -0
  185. package/types/schema/schema.d.ts +36 -0
  186. package/types/schema/types.d.ts +38 -0
  187. package/types/string-resolver/index.d.ts +30 -0
  188. package/types/types.d.ts +73 -0
  189. package/types/utils/index.d.ts +2 -0
  190. package/types/utils/replaceParams.d.ts +9 -0
  191. package/types/validator/binding-map-splice.d.ts +10 -0
  192. package/types/validator/index.d.ts +5 -0
  193. package/types/validator/registry.d.ts +11 -0
  194. package/types/validator/types.d.ts +53 -0
  195. package/types/validator/validation-middleware.d.ts +36 -0
  196. package/types/view/builder/index.d.ts +35 -0
  197. package/types/view/index.d.ts +6 -0
  198. package/types/view/parser/index.d.ts +52 -0
  199. package/types/view/parser/types.d.ts +109 -0
  200. package/types/view/parser/utils.d.ts +6 -0
  201. package/types/view/plugins/applicability.d.ts +10 -0
  202. package/types/view/plugins/index.d.ts +5 -0
  203. package/types/view/plugins/options.d.ts +4 -0
  204. package/types/view/plugins/string-resolver.d.ts +13 -0
  205. package/types/view/plugins/switch.d.ts +14 -0
  206. package/types/view/plugins/template-plugin.d.ts +33 -0
  207. package/types/view/resolver/index.d.ts +73 -0
  208. package/types/view/resolver/types.d.ts +129 -0
  209. package/types/view/resolver/utils.d.ts +11 -0
  210. package/types/view/view.d.ts +37 -0
  211. package/dist/index.d.ts +0 -1814
  212. package/dist/player.dev.js +0 -11472
  213. package/dist/player.prod.js +0 -2
  214. package/src/view/plugins/plugin.ts +0 -21
@@ -2,8 +2,13 @@
2
2
  /**
3
3
  * An expression to AST parser based on JSEP: http://jsep.from.so/
4
4
  */
5
- import type { ExpressionNode, ExpressionNodeType, NodeLocation } from './types';
6
- import { ExpNodeOpaqueIdentifier } from './types';
5
+ import type {
6
+ ErrorWithLocation,
7
+ ExpressionNode,
8
+ ExpressionNodeType,
9
+ NodeLocation,
10
+ } from "./types";
11
+ import { ExpNodeOpaqueIdentifier } from "./types";
7
12
 
8
13
  const PERIOD_CODE = 46; // '.'
9
14
  const COMMA_CODE = 44; // ','
@@ -27,51 +32,43 @@ const t = true;
27
32
 
28
33
  // Use a quickly-accessible map to store all of the unary operators
29
34
  // Values are set to `true` (it really doesn't matter)
30
- const unaryOps = { '-': t, '!': t, '~': t, '+': t };
35
+ const unaryOps = { "-": t, "!": t, "~": t, "+": t };
31
36
 
32
37
  // Also use a map for the binary operations but set their values to their
33
38
  // binary precedence for quick reference:
34
39
  // see [Operator precedence](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)
35
40
  const binaryOps: Record<string, number> = {
36
- '=': 3,
37
- '+=': 3,
38
- '-=': 3,
39
- '&=': 3,
40
- '|=': 3,
41
+ "=": 3,
42
+ "+=": 3,
43
+ "-=": 3,
44
+ "&=": 3,
45
+ "|=": 3,
41
46
  // Conditional: 4,
42
- '||': 5,
43
- '&&': 6,
44
- '|': 7,
45
- '^': 8,
46
- '&': 9,
47
- '==': 10,
48
- '!=': 10,
49
- '===': 10,
50
- '!==': 10,
51
- '<': 11,
52
- '>': 11,
53
- '<=': 11,
54
- '>=': 11,
55
- '<<': 12,
56
- '>>': 12,
57
- '>>>': 12,
58
- '+': 13,
59
- '-': 13,
60
- '*': 14,
61
- '/': 14,
62
- '%': 14,
47
+ "||": 5,
48
+ "&&": 6,
49
+ "|": 7,
50
+ "^": 8,
51
+ "&": 9,
52
+ "==": 10,
53
+ "!=": 10,
54
+ "===": 10,
55
+ "!==": 10,
56
+ "<": 11,
57
+ ">": 11,
58
+ "<=": 11,
59
+ ">=": 11,
60
+ "<<": 12,
61
+ ">>": 12,
62
+ ">>>": 12,
63
+ "+": 13,
64
+ "-": 13,
65
+ "*": 14,
66
+ "/": 14,
67
+ "%": 14,
63
68
  };
64
69
 
65
- interface ErrorWithLocation extends Error {
66
- /** The place in the string where the error occurs */
67
- index: number;
68
-
69
- /** a helpful description */
70
- description: string;
71
- }
72
-
73
70
  /** Wrap the message and index in an error and throw it */
74
- function throwError(message: string, index: number) {
71
+ function throwError(message: string, index: number): ErrorWithLocation {
75
72
  const err = new Error(`${message} at character ${index}`);
76
73
 
77
74
  (err as ErrorWithLocation).index = index;
@@ -119,7 +116,7 @@ const literals = {
119
116
  } as const;
120
117
 
121
118
  // Except for `this`, which is special. This could be changed to something like `'self'` as well
122
- const thisStr = 'this';
119
+ const thisStr = "this";
123
120
 
124
121
  /** Returns the precedence of a binary operator or `0` if it isn't a binary operator */
125
122
  function binaryPrecedence(opVal: string): number {
@@ -134,23 +131,23 @@ function createBinaryExpression(
134
131
  operator: string | boolean,
135
132
  left: string,
136
133
  right: string,
137
- location?: NodeLocation
134
+ location?: NodeLocation,
138
135
  ) {
139
136
  let type: ExpressionNodeType;
140
137
 
141
- if (operator === '||' || operator === '&&') {
142
- type = 'LogicalExpression';
143
- } else if (operator === '=') {
144
- type = 'Assignment';
138
+ if (operator === "||" || operator === "&&") {
139
+ type = "LogicalExpression";
140
+ } else if (operator === "=") {
141
+ type = "Assignment";
145
142
  } else if (
146
- operator === '+=' ||
147
- operator === '-=' ||
148
- operator === '&=' ||
149
- operator === '|='
143
+ operator === "+=" ||
144
+ operator === "-=" ||
145
+ operator === "&=" ||
146
+ operator === "|="
150
147
  ) {
151
- type = 'Modification';
148
+ type = "Modification";
152
149
  } else {
153
- type = 'BinaryExpression';
150
+ type = "BinaryExpression";
154
151
  }
155
152
 
156
153
  return {
@@ -200,7 +197,7 @@ export function parseExpression(
200
197
  options?: {
201
198
  /** If true (the default), will throw on invalid expressions */
202
199
  strict?: boolean;
203
- }
200
+ },
204
201
  ): ExpressionNode {
205
202
  const strictMode = options?.strict ?? true;
206
203
 
@@ -263,7 +260,7 @@ export function parseExpression(
263
260
  if (chCode === CCURL_CODE) {
264
261
  // if we are at the end but a key was defined
265
262
  if (key) {
266
- throwError('A key was defined but a value was not', index);
263
+ throwError("A key was defined but a value was not", index);
267
264
  }
268
265
 
269
266
  index++;
@@ -272,7 +269,7 @@ export function parseExpression(
272
269
  } else if (shouldDefineKey) {
273
270
  // check for key
274
271
  if (chCode !== SQUOTE_CODE && chCode !== DQUOTE_CODE) {
275
- throwError('An object must start wtih a key', index);
272
+ throwError("An object must start wtih a key", index);
276
273
  }
277
274
 
278
275
  // get key
@@ -284,7 +281,7 @@ export function parseExpression(
284
281
  index++;
285
282
  shouldDefineKey = false;
286
283
  } else {
287
- throwError('A colon must follow an object key', index);
284
+ throwError("A colon must follow an object key", index);
288
285
  }
289
286
  } else {
290
287
  value = gobbleExpression();
@@ -295,7 +292,7 @@ export function parseExpression(
295
292
  if (chCode === COMMA_CODE) {
296
293
  index++;
297
294
  } else if (chCode !== CCURL_CODE) {
298
- throwError('Please add a comma to add another key', index);
295
+ throwError("Please add a comma to add another key", index);
299
296
  }
300
297
 
301
298
  shouldDefineKey = true;
@@ -313,7 +310,7 @@ export function parseExpression(
313
310
 
314
311
  return {
315
312
  __id: ExpNodeOpaqueIdentifier,
316
- type: 'Object',
313
+ type: "Object",
317
314
  attributes,
318
315
  location: getLocation(startCharIndex),
319
316
  };
@@ -344,7 +341,7 @@ export function parseExpression(
344
341
  const consequent = gobbleExpression();
345
342
 
346
343
  if (!consequent) {
347
- throwError('Expected expression', index);
344
+ throwError("Expected expression", index);
348
345
  }
349
346
 
350
347
  gobbleSpaces();
@@ -354,12 +351,12 @@ export function parseExpression(
354
351
  const alternate = gobbleExpression();
355
352
 
356
353
  if (!alternate) {
357
- throwError('Expected expression', index);
354
+ throwError("Expected expression", index);
358
355
  }
359
356
 
360
357
  return {
361
358
  __id: ExpNodeOpaqueIdentifier,
362
- type: 'ConditionalExpression',
359
+ type: "ConditionalExpression",
363
360
  test,
364
361
  consequent,
365
362
  alternate,
@@ -367,7 +364,7 @@ export function parseExpression(
367
364
  };
368
365
  }
369
366
 
370
- throwError('Expected :', index);
367
+ throwError("Expected :", index);
371
368
  }
372
369
 
373
370
  return test;
@@ -447,7 +444,7 @@ export function parseExpression(
447
444
  biop,
448
445
  left,
449
446
  right,
450
- createSpanningLocation(left.location, right.location)
447
+ createSpanningLocation(left.location, right.location),
451
448
  );
452
449
  stack.push(node);
453
450
  }
@@ -470,7 +467,7 @@ export function parseExpression(
470
467
  stack[i - 1].value,
471
468
  stack[i - 2],
472
469
  node,
473
- createSpanningLocation(stack[i - 2].location, node.location)
470
+ createSpanningLocation(stack[i - 2].location, node.location),
474
471
  );
475
472
  i -= 2;
476
473
  }
@@ -524,7 +521,7 @@ export function parseExpression(
524
521
  index += tcLen;
525
522
  return {
526
523
  __id: ExpNodeOpaqueIdentifier,
527
- type: 'UnaryExpression',
524
+ type: "UnaryExpression",
528
525
  operator: toCheck,
529
526
  argument: gobbleToken(),
530
527
  prefix: true,
@@ -543,7 +540,7 @@ export function parseExpression(
543
540
  * keep track of everything in the numeric literal and then calling `parseFloat` on that string
544
541
  */
545
542
  function gobbleNumericLiteral() {
546
- let num = '';
543
+ let num = "";
547
544
  const startCharIndex = index;
548
545
 
549
546
  while (isDecimalDigit(exprICode(index))) {
@@ -560,12 +557,12 @@ export function parseExpression(
560
557
  }
561
558
 
562
559
  let ch = exprI(index);
563
- if (ch === 'e' || ch === 'E') {
560
+ if (ch === "e" || ch === "E") {
564
561
  // Exponent marker
565
562
  num += exprI(index++);
566
563
  ch = exprI(index);
567
564
 
568
- if (ch === '+' || ch === '-') {
565
+ if (ch === "+" || ch === "-") {
569
566
  // Exponent sign
570
567
  num += exprI(index++);
571
568
  }
@@ -585,15 +582,15 @@ export function parseExpression(
585
582
  if (isIdentifierStart(chCode)) {
586
583
  throwError(
587
584
  `Variable names cannot start with a number (${num}${exprI(index)})`,
588
- index
585
+ index,
589
586
  );
590
587
  } else if (chCode === PERIOD_CODE) {
591
- throwError('Unexpected period', index);
588
+ throwError("Unexpected period", index);
592
589
  }
593
590
 
594
591
  return {
595
592
  __id: ExpNodeOpaqueIdentifier,
596
- type: 'Literal',
593
+ type: "Literal",
597
594
  value: parseFloat(num),
598
595
  raw: num,
599
596
  location: getLocation(startCharIndex),
@@ -606,7 +603,7 @@ export function parseExpression(
606
603
  */
607
604
  function gobbleStringLiteral() {
608
605
  const quote = exprI(index++);
609
- let str = '';
606
+ let str = "";
610
607
  let closed = false;
611
608
  const startCharIndex = index;
612
609
 
@@ -618,7 +615,7 @@ export function parseExpression(
618
615
  break;
619
616
  }
620
617
 
621
- if (ch !== '\\') {
618
+ if (ch !== "\\") {
622
619
  str += ch;
623
620
  continue;
624
621
  }
@@ -627,23 +624,23 @@ export function parseExpression(
627
624
  ch = exprI(index++);
628
625
 
629
626
  switch (ch) {
630
- case 'n':
631
- str += '\n';
627
+ case "n":
628
+ str += "\n";
632
629
  break;
633
- case 'r':
634
- str += '\r';
630
+ case "r":
631
+ str += "\r";
635
632
  break;
636
- case 't':
637
- str += '\t';
633
+ case "t":
634
+ str += "\t";
638
635
  break;
639
- case 'b':
640
- str += '\b';
636
+ case "b":
637
+ str += "\b";
641
638
  break;
642
- case 'f':
643
- str += '\f';
639
+ case "f":
640
+ str += "\f";
644
641
  break;
645
- case 'v':
646
- str += '\u000B';
642
+ case "v":
643
+ str += "\u000B";
647
644
  break;
648
645
  default:
649
646
  }
@@ -655,7 +652,7 @@ export function parseExpression(
655
652
 
656
653
  return {
657
654
  __id: ExpNodeOpaqueIdentifier,
658
- type: 'Literal',
655
+ type: "Literal",
659
656
  value: str,
660
657
  raw: `${quote}${str}${quote}`,
661
658
  location: getLocation(startCharIndex),
@@ -667,7 +664,7 @@ export function parseExpression(
667
664
  * e.g. {{foo.bar.ref}}
668
665
  */
669
666
  function gobbleModelRef() {
670
- let str = '';
667
+ let str = "";
671
668
  let closed = false;
672
669
  let openBraceCount = 1;
673
670
  const startCharIndex = index;
@@ -676,7 +673,7 @@ export function parseExpression(
676
673
  while (index < length) {
677
674
  const ch = exprI(index++);
678
675
 
679
- if (ch === '}' && exprICode(index) === CCURL_CODE) {
676
+ if (ch === "}" && exprICode(index) === CCURL_CODE) {
680
677
  index++;
681
678
  openBraceCount--;
682
679
 
@@ -685,10 +682,10 @@ export function parseExpression(
685
682
  break;
686
683
  }
687
684
 
688
- str += '}}';
689
- } else if (ch === '{' && exprICode(index) === OCURL_CODE) {
685
+ str += "}}";
686
+ } else if (ch === "{" && exprICode(index) === OCURL_CODE) {
690
687
  openBraceCount++;
691
- str += '{{';
688
+ str += "{{";
692
689
  index++;
693
690
  } else {
694
691
  str += ch;
@@ -701,7 +698,7 @@ export function parseExpression(
701
698
 
702
699
  return {
703
700
  __id: ExpNodeOpaqueIdentifier,
704
- type: 'ModelRef',
701
+ type: "ModelRef",
705
702
  ref: str,
706
703
  location: getLocation(startCharIndex),
707
704
  };
@@ -737,7 +734,7 @@ export function parseExpression(
737
734
  if (Object.prototype.hasOwnProperty.call(literals, identifier)) {
738
735
  return {
739
736
  __id: ExpNodeOpaqueIdentifier,
740
- type: 'Literal',
737
+ type: "Literal",
741
738
  value: (literals as any)[identifier],
742
739
  raw: identifier,
743
740
  location: getLocation(start),
@@ -747,14 +744,14 @@ export function parseExpression(
747
744
  if (identifier === thisStr) {
748
745
  return {
749
746
  __id: ExpNodeOpaqueIdentifier,
750
- type: 'ThisExpression',
747
+ type: "ThisExpression",
751
748
  location: getLocation(start),
752
749
  };
753
750
  }
754
751
 
755
752
  return {
756
753
  __id: ExpNodeOpaqueIdentifier,
757
- type: 'Identifier',
754
+ type: "Identifier",
758
755
  name: identifier,
759
756
  location: getLocation(start),
760
757
  };
@@ -790,14 +787,14 @@ export function parseExpression(
790
787
 
791
788
  node = gobbleExpression();
792
789
 
793
- if (!node || node.type === 'Compound') {
794
- throwError('Expected comma', index);
790
+ if (!node || node.type === "Compound") {
791
+ throwError("Expected comma", index);
795
792
  }
796
793
 
797
794
  args.push(node);
798
795
  }
799
796
 
800
- if (charIndex !== termination) {
797
+ if (strictMode && charIndex !== termination) {
801
798
  throwError(`Expected ${String.fromCharCode(termination)}`, index);
802
799
  }
803
800
 
@@ -830,7 +827,7 @@ export function parseExpression(
830
827
 
831
828
  node = {
832
829
  __id: ExpNodeOpaqueIdentifier,
833
- type: 'MemberExpression',
830
+ type: "MemberExpression",
834
831
  computed: false,
835
832
  object: node,
836
833
  property: gobbleIdentifier(),
@@ -839,7 +836,7 @@ export function parseExpression(
839
836
  } else if (charIndex === OBRACK_CODE) {
840
837
  node = {
841
838
  __id: ExpNodeOpaqueIdentifier,
842
- type: 'MemberExpression',
839
+ type: "MemberExpression",
843
840
  computed: true,
844
841
  object: node,
845
842
  property: gobbleExpression(),
@@ -850,7 +847,7 @@ export function parseExpression(
850
847
  charIndex = exprICode(index);
851
848
 
852
849
  if (charIndex !== CBRACK_CODE) {
853
- throwError('Unclosed [', index);
850
+ throwError("Unclosed [", index);
854
851
  }
855
852
 
856
853
  index++;
@@ -858,7 +855,7 @@ export function parseExpression(
858
855
  // A function call is being made; gobble all the arguments
859
856
  node = {
860
857
  __id: ExpNodeOpaqueIdentifier,
861
- type: 'CallExpression',
858
+ type: "CallExpression",
862
859
  args: gobbleArguments(CPAREN_CODE),
863
860
  callTarget: node,
864
861
  location: getLocation(startCharIndex),
@@ -889,7 +886,7 @@ export function parseExpression(
889
886
  return node;
890
887
  }
891
888
 
892
- throwError('Unclosed (', index);
889
+ throwError("Unclosed (", index);
893
890
  }
894
891
 
895
892
  /**
@@ -903,7 +900,7 @@ export function parseExpression(
903
900
 
904
901
  return {
905
902
  __id: ExpNodeOpaqueIdentifier,
906
- type: 'ArrayExpression',
903
+ type: "ArrayExpression",
907
904
  elements: gobbleArguments(CBRACK_CODE),
908
905
  location: getLocation(startCharIndex),
909
906
  };
@@ -929,7 +926,7 @@ export function parseExpression(
929
926
  nodes.push(node);
930
927
  // If we weren't able to find a binary expression and are out of room, then
931
928
  // the expression passed in probably has too much
932
- } else if (index < length) {
929
+ } else if (strictMode && index < length) {
933
930
  throwError(`Unexpected "${exprI(index)}"`, index);
934
931
  }
935
932
  }
@@ -941,7 +938,7 @@ export function parseExpression(
941
938
 
942
939
  return {
943
940
  __id: ExpNodeOpaqueIdentifier,
944
- type: 'Compound',
941
+ type: "Compound",
945
942
  body: nodes,
946
943
  location: getLocation(0),
947
944
  };
@@ -952,7 +949,7 @@ export function parseExpression(
952
949
 
953
950
  return {
954
951
  __id: ExpNodeOpaqueIdentifier,
955
- type: 'Compound',
952
+ type: "Compound",
956
953
  body: nodes,
957
954
  location: getLocation(0),
958
955
  error: e,
@@ -1,5 +1,5 @@
1
- import type { DataModelWithParser } from '../data';
2
- import type { Logger } from '../logger';
1
+ import type { DataModelWithParser } from "../data";
2
+ import type { Logger } from "../logger";
3
3
 
4
4
  export type ExpressionObjectType = {
5
5
  /** The expression to eval */
@@ -52,16 +52,16 @@ export interface ExpressionContext {
52
52
 
53
53
  export type ExpressionHandler<
54
54
  T extends readonly unknown[] = unknown[],
55
- R = void
55
+ R = void,
56
56
  > = ((context: ExpressionContext, ...args: T) => R) &
57
57
  Partial<OperatorProcessingOptions>;
58
58
 
59
- export const ExpNodeOpaqueIdentifier = Symbol('Expression Node ID');
59
+ export const ExpNodeOpaqueIdentifier = Symbol("Expression Node ID");
60
60
 
61
61
  /** Checks if the input is an already processed Expression node */
62
62
  export function isExpressionNode(x: any): x is ExpressionNode {
63
63
  return (
64
- typeof x === 'object' &&
64
+ typeof x === "object" &&
65
65
  x !== null &&
66
66
  !Array.isArray(x) &&
67
67
  x.__id === ExpNodeOpaqueIdentifier
@@ -110,7 +110,7 @@ export interface DirectionalNode {
110
110
  right: ExpressionNode;
111
111
  }
112
112
 
113
- export interface LiteralNode extends BaseNode<'Literal'> {
113
+ export interface LiteralNode extends BaseNode<"Literal"> {
114
114
  /** A node that holds a literal value */
115
115
  value: string | number;
116
116
 
@@ -119,20 +119,20 @@ export interface LiteralNode extends BaseNode<'Literal'> {
119
119
  }
120
120
 
121
121
  export interface BinaryNode
122
- extends BaseNode<'BinaryExpression'>,
122
+ extends BaseNode<"BinaryExpression">,
123
123
  DirectionalNode {
124
124
  /** The operation to perform on the nodes */
125
125
  operator: string;
126
126
  }
127
127
 
128
128
  export interface LogicalNode
129
- extends BaseNode<'LogicalExpression'>,
129
+ extends BaseNode<"LogicalExpression">,
130
130
  DirectionalNode {
131
131
  /** The logical operation to perform on the nodes */
132
132
  operator: string;
133
133
  }
134
134
 
135
- export interface UnaryNode extends BaseNode<'UnaryExpression'> {
135
+ export interface UnaryNode extends BaseNode<"UnaryExpression"> {
136
136
  /** The operation to perform on the node */
137
137
  operator: string;
138
138
 
@@ -140,14 +140,14 @@ export interface UnaryNode extends BaseNode<'UnaryExpression'> {
140
140
  argument: ExpressionNode;
141
141
  }
142
142
 
143
- export type ThisNode = BaseNode<'ThisExpression'>;
143
+ export type ThisNode = BaseNode<"ThisExpression">;
144
144
 
145
- export interface ModelRefNode extends BaseNode<'ModelRef'> {
145
+ export interface ModelRefNode extends BaseNode<"ModelRef"> {
146
146
  /** The binding that the model reference points to */
147
147
  ref: string;
148
148
  }
149
149
 
150
- export interface ObjectNode extends BaseNode<'Object'> {
150
+ export interface ObjectNode extends BaseNode<"Object"> {
151
151
  /** */
152
152
  attributes: Array<{
153
153
  /** The property name of the object */
@@ -158,7 +158,7 @@ export interface ObjectNode extends BaseNode<'Object'> {
158
158
  }>;
159
159
  }
160
160
 
161
- export interface MemberExpressionNode extends BaseNode<'MemberExpression'> {
161
+ export interface MemberExpressionNode extends BaseNode<"MemberExpression"> {
162
162
  /** The object to be introspected */
163
163
  object: ExpressionNode;
164
164
 
@@ -170,7 +170,7 @@ export interface MemberExpressionNode extends BaseNode<'MemberExpression'> {
170
170
  }
171
171
 
172
172
  export interface ConditionalExpressionNode
173
- extends BaseNode<'ConditionalExpression'> {
173
+ extends BaseNode<"ConditionalExpression"> {
174
174
  /** The test for the ternary */
175
175
  test: ExpressionNode;
176
176
 
@@ -181,12 +181,12 @@ export interface ConditionalExpressionNode
181
181
  alternate: ExpressionNode;
182
182
  }
183
183
 
184
- export interface CompoundNode extends BaseNode<'Compound'> {
184
+ export interface CompoundNode extends BaseNode<"Compound"> {
185
185
  /** The contents of the compound expression */
186
186
  body: ExpressionNode[];
187
187
  }
188
188
 
189
- export interface CallExpressionNode extends BaseNode<'CallExpression'> {
189
+ export interface CallExpressionNode extends BaseNode<"CallExpression"> {
190
190
  /** The arguments to the function */
191
191
  args: ExpressionNode[];
192
192
 
@@ -194,20 +194,20 @@ export interface CallExpressionNode extends BaseNode<'CallExpression'> {
194
194
  callTarget: IdentifierNode;
195
195
  }
196
196
 
197
- export interface ArrayExpressionNode extends BaseNode<'ArrayExpression'> {
197
+ export interface ArrayExpressionNode extends BaseNode<"ArrayExpression"> {
198
198
  /** The items in an array */
199
199
  elements: ExpressionNode[];
200
200
  }
201
201
 
202
- export interface IdentifierNode extends BaseNode<'Identifier'> {
202
+ export interface IdentifierNode extends BaseNode<"Identifier"> {
203
203
  /** The variable name */
204
204
  name: string;
205
205
  }
206
206
 
207
- export type AssignmentNode = BaseNode<'Assignment'> & DirectionalNode;
207
+ export type AssignmentNode = BaseNode<"Assignment"> & DirectionalNode;
208
208
 
209
209
  export interface ModificationNode
210
- extends BaseNode<'Modification'>,
210
+ extends BaseNode<"Modification">,
211
211
  DirectionalNode {
212
212
  /** The operator for the modification */
213
213
  operator: string;
@@ -230,4 +230,12 @@ export type ExpressionNode =
230
230
  | ModificationNode
231
231
  | ObjectNode;
232
232
 
233
- export type ExpressionNodeType = ExpressionNode['type'];
233
+ export type ExpressionNodeType = ExpressionNode["type"];
234
+
235
+ export interface ErrorWithLocation extends Error {
236
+ /** The place in the string where the error occurs */
237
+ index: number;
238
+
239
+ /** a helpful description */
240
+ description: string;
241
+ }