@memberjunction/global 6.1.0-edge.1 → 6.1.0-edge.3

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 (75) hide show
  1. package/LICENSE +180 -4
  2. package/README.md +2 -2
  3. package/dist/ClassUtils.d.ts +20 -0
  4. package/dist/ClassUtils.d.ts.map +1 -1
  5. package/dist/ClassUtils.js +68 -0
  6. package/dist/ClassUtils.js.map +1 -1
  7. package/dist/SQLExpressionValidator.d.ts +28 -1
  8. package/dist/SQLExpressionValidator.d.ts.map +1 -1
  9. package/dist/SQLExpressionValidator.js +42 -4
  10. package/dist/SQLExpressionValidator.js.map +1 -1
  11. package/dist/SafeExpressionEvaluator.d.ts +131 -6
  12. package/dist/SafeExpressionEvaluator.d.ts.map +1 -1
  13. package/dist/SafeExpressionEvaluator.js +344 -41
  14. package/dist/SafeExpressionEvaluator.js.map +1 -1
  15. package/dist/TokenEndpointErrors.d.ts +52 -0
  16. package/dist/TokenEndpointErrors.d.ts.map +1 -0
  17. package/dist/TokenEndpointErrors.js +87 -0
  18. package/dist/TokenEndpointErrors.js.map +1 -0
  19. package/dist/__tests__/ClassUtils.IsMemberOverridden.test.d.ts +2 -0
  20. package/dist/__tests__/ClassUtils.IsMemberOverridden.test.d.ts.map +1 -0
  21. package/dist/__tests__/ClassUtils.IsMemberOverridden.test.js +134 -0
  22. package/dist/__tests__/ClassUtils.IsMemberOverridden.test.js.map +1 -0
  23. package/dist/__tests__/DeepDiff.test.d.ts +2 -0
  24. package/dist/__tests__/DeepDiff.test.d.ts.map +1 -0
  25. package/dist/__tests__/DeepDiff.test.js +229 -0
  26. package/dist/__tests__/DeepDiff.test.js.map +1 -0
  27. package/dist/__tests__/IsPlainObject.test.d.ts +2 -0
  28. package/dist/__tests__/IsPlainObject.test.d.ts.map +1 -0
  29. package/dist/__tests__/IsPlainObject.test.js +68 -0
  30. package/dist/__tests__/IsPlainObject.test.js.map +1 -0
  31. package/dist/__tests__/JSONValidator.test.d.ts +2 -0
  32. package/dist/__tests__/JSONValidator.test.d.ts.map +1 -0
  33. package/dist/__tests__/JSONValidator.test.js +221 -0
  34. package/dist/__tests__/JSONValidator.test.js.map +1 -0
  35. package/dist/__tests__/MJGlobal.test.js +8 -6
  36. package/dist/__tests__/MJGlobal.test.js.map +1 -1
  37. package/dist/__tests__/ResourcePatternUtils.test.d.ts +2 -0
  38. package/dist/__tests__/ResourcePatternUtils.test.d.ts.map +1 -0
  39. package/dist/__tests__/ResourcePatternUtils.test.js +50 -0
  40. package/dist/__tests__/ResourcePatternUtils.test.js.map +1 -0
  41. package/dist/__tests__/SQLExpressionValidator.security.test.js +62 -1
  42. package/dist/__tests__/SQLExpressionValidator.security.test.js.map +1 -1
  43. package/dist/__tests__/SafeExpressionEvaluator.security.test.d.ts +2 -0
  44. package/dist/__tests__/SafeExpressionEvaluator.security.test.d.ts.map +1 -0
  45. package/dist/__tests__/SafeExpressionEvaluator.security.test.js +284 -0
  46. package/dist/__tests__/SafeExpressionEvaluator.security.test.js.map +1 -0
  47. package/dist/__tests__/SafeExpressionEvaluator.test.d.ts +2 -0
  48. package/dist/__tests__/SafeExpressionEvaluator.test.d.ts.map +1 -0
  49. package/dist/__tests__/SafeExpressionEvaluator.test.js +355 -0
  50. package/dist/__tests__/SafeExpressionEvaluator.test.js.map +1 -0
  51. package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.d.ts +2 -0
  52. package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.d.ts.map +1 -0
  53. package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.js +62 -0
  54. package/dist/__tests__/SafeExpressionEvaluator.validateSyntax.test.js.map +1 -0
  55. package/dist/__tests__/TokenEndpointErrors.test.d.ts +2 -0
  56. package/dist/__tests__/TokenEndpointErrors.test.d.ts.map +1 -0
  57. package/dist/__tests__/TokenEndpointErrors.test.js +72 -0
  58. package/dist/__tests__/TokenEndpointErrors.test.js.map +1 -0
  59. package/dist/__tests__/util.toEpochMs.test.d.ts +2 -0
  60. package/dist/__tests__/util.toEpochMs.test.d.ts.map +1 -0
  61. package/dist/__tests__/util.toEpochMs.test.js +57 -0
  62. package/dist/__tests__/util.toEpochMs.test.js.map +1 -0
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +2 -0
  66. package/dist/index.js.map +1 -1
  67. package/dist/util/ResourcePatternUtils.d.ts +35 -0
  68. package/dist/util/ResourcePatternUtils.d.ts.map +1 -0
  69. package/dist/util/ResourcePatternUtils.js +56 -0
  70. package/dist/util/ResourcePatternUtils.js.map +1 -0
  71. package/dist/util.d.ts +36 -0
  72. package/dist/util.d.ts.map +1 -1
  73. package/dist/util.js +43 -0
  74. package/dist/util.js.map +1 -1
  75. package/package.json +3 -2
@@ -0,0 +1,355 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { SafeExpressionEvaluator, defaultExpressionEvaluator, } from '../SafeExpressionEvaluator.js';
3
+ /**
4
+ * Functional tests for SafeExpressionEvaluator.
5
+ *
6
+ * These exercise the documented contract: evaluate a boolean expression against a
7
+ * context object, returning an {@link ExpressionEvaluationResult}. Adversarial /
8
+ * sandbox-escape scenarios live in SafeExpressionEvaluator.security.test.ts.
9
+ */
10
+ describe('SafeExpressionEvaluator', () => {
11
+ let evaluator;
12
+ beforeEach(() => {
13
+ evaluator = new SafeExpressionEvaluator();
14
+ });
15
+ // ---------------------------------------------------------------
16
+ // Simple comparisons over context data
17
+ // ---------------------------------------------------------------
18
+ describe('comparison operators', () => {
19
+ it('should evaluate == to true when values match', () => {
20
+ const r = evaluator.evaluate("status == 'active'", { status: 'active' });
21
+ expect(r.success).toBe(true);
22
+ expect(r.value).toBe(true);
23
+ });
24
+ it('should evaluate == to false when values differ', () => {
25
+ const r = evaluator.evaluate("status == 'active'", { status: 'inactive' });
26
+ expect(r.success).toBe(true);
27
+ expect(r.value).toBe(false);
28
+ });
29
+ it('should evaluate strict === correctly', () => {
30
+ expect(evaluator.evaluate('count === 5', { count: 5 }).value).toBe(true);
31
+ expect(evaluator.evaluate('count === 5', { count: 6 }).value).toBe(false);
32
+ });
33
+ it('should evaluate != and !==', () => {
34
+ expect(evaluator.evaluate('count != 5', { count: 6 }).value).toBe(true);
35
+ expect(evaluator.evaluate('count !== 5', { count: 5 }).value).toBe(false);
36
+ });
37
+ it('should evaluate <, >, <=, >=', () => {
38
+ expect(evaluator.evaluate('n < 10', { n: 5 }).value).toBe(true);
39
+ expect(evaluator.evaluate('n > 10', { n: 5 }).value).toBe(false);
40
+ expect(evaluator.evaluate('n <= 5', { n: 5 }).value).toBe(true);
41
+ expect(evaluator.evaluate('n >= 6', { n: 5 }).value).toBe(false);
42
+ });
43
+ });
44
+ // ---------------------------------------------------------------
45
+ // Logical operators
46
+ // ---------------------------------------------------------------
47
+ describe('logical operators', () => {
48
+ it('should evaluate && (AND)', () => {
49
+ const ctx = { a: true, b: false };
50
+ expect(evaluator.evaluate('a && b', ctx).value).toBe(false);
51
+ expect(evaluator.evaluate('a && !b', ctx).value).toBe(true);
52
+ });
53
+ it('should evaluate || (OR)', () => {
54
+ const ctx = { a: false, b: true };
55
+ expect(evaluator.evaluate('a || b', ctx).value).toBe(true);
56
+ expect(evaluator.evaluate('a || false', ctx).value).toBe(false);
57
+ });
58
+ it('should evaluate ! (NOT)', () => {
59
+ expect(evaluator.evaluate('!isActive', { isActive: false }).value).toBe(true);
60
+ expect(evaluator.evaluate('!isActive', { isActive: true }).value).toBe(false);
61
+ });
62
+ it('should combine comparisons with logical operators', () => {
63
+ const ctx = { tier: 'premium', total: 1500 };
64
+ const r = evaluator.evaluate("tier == 'premium' && total > 1000", ctx);
65
+ expect(r.success).toBe(true);
66
+ expect(r.value).toBe(true);
67
+ });
68
+ });
69
+ // ---------------------------------------------------------------
70
+ // Nested property + array access
71
+ // ---------------------------------------------------------------
72
+ describe('property and array access', () => {
73
+ it('should resolve nested dot-notation properties', () => {
74
+ const ctx = {
75
+ payload: { customer: { tier: 'premium' }, order: { total: 1500 } },
76
+ };
77
+ const r = evaluator.evaluate("payload.customer.tier == 'premium' && payload.order.total > 1000", ctx);
78
+ expect(r.success).toBe(true);
79
+ expect(r.value).toBe(true);
80
+ });
81
+ it('should resolve array index access', () => {
82
+ const ctx = { items: [10, 20, 30] };
83
+ expect(evaluator.evaluate('items[0] == 10', ctx).value).toBe(true);
84
+ expect(evaluator.evaluate('items[2] > items[0]', ctx).value).toBe(true);
85
+ });
86
+ });
87
+ // ---------------------------------------------------------------
88
+ // Safe methods
89
+ // ---------------------------------------------------------------
90
+ describe('safe string/array methods', () => {
91
+ it('should support .length', () => {
92
+ expect(evaluator.evaluate('name.length > 3', { name: 'Alice' }).value).toBe(true);
93
+ expect(evaluator.evaluate('name.length > 3', { name: 'Al' }).value).toBe(false);
94
+ });
95
+ it('should support .includes()', () => {
96
+ expect(evaluator.evaluate("tags.includes('urgent')", { tags: ['work', 'urgent'] }).value).toBe(true);
97
+ });
98
+ it('should support .startsWith() and .endsWith()', () => {
99
+ const ctx = { code: 'AB-123' };
100
+ expect(evaluator.evaluate("code.startsWith('AB')", ctx).value).toBe(true);
101
+ expect(evaluator.evaluate("code.endsWith('123')", ctx).value).toBe(true);
102
+ });
103
+ it('should support .toLowerCase() in a comparison', () => {
104
+ const r = evaluator.evaluate("name.toLowerCase() == 'alice'", { name: 'ALICE' });
105
+ expect(r.success).toBe(true);
106
+ expect(r.value).toBe(true);
107
+ });
108
+ });
109
+ // ---------------------------------------------------------------
110
+ // Array higher-order methods
111
+ // ---------------------------------------------------------------
112
+ describe('array higher-order methods', () => {
113
+ it('should support .some()', () => {
114
+ const ctx = { items: [{ price: 50 }, { price: 150 }] };
115
+ const r = evaluator.evaluate('items.some(item => item.price > 100)', ctx);
116
+ expect(r.success).toBe(true);
117
+ expect(r.value).toBe(true);
118
+ });
119
+ it('should support .every()', () => {
120
+ const ctx = { items: [{ price: 50 }, { price: 150 }] };
121
+ expect(evaluator.evaluate('items.every(item => item.price > 0)', ctx).value).toBe(true);
122
+ expect(evaluator.evaluate('items.every(item => item.price > 100)', ctx).value).toBe(false);
123
+ });
124
+ it('should support .filter().length', () => {
125
+ const ctx = {
126
+ items: [{ price: 50 }, { price: 150 }, { price: 200 }],
127
+ };
128
+ const r = evaluator.evaluate('items.filter(item => item.price > 100).length == 2', ctx);
129
+ expect(r.success).toBe(true);
130
+ expect(r.value).toBe(true);
131
+ });
132
+ });
133
+ // ---------------------------------------------------------------
134
+ // typeof
135
+ // ---------------------------------------------------------------
136
+ describe('typeof', () => {
137
+ it('should evaluate typeof checks', () => {
138
+ expect(evaluator.evaluate("typeof name == 'string'", { name: 'x' }).value).toBe(true);
139
+ expect(evaluator.evaluate("typeof count == 'number'", { count: 5 }).value).toBe(true);
140
+ });
141
+ });
142
+ // ---------------------------------------------------------------
143
+ // Edge values: null / undefined / empty
144
+ // ---------------------------------------------------------------
145
+ describe('edge values', () => {
146
+ it('should compare against null', () => {
147
+ expect(evaluator.evaluate('x == null', { x: null }).value).toBe(true);
148
+ expect(evaluator.evaluate('x === null', { x: null }).value).toBe(true);
149
+ });
150
+ it('should treat missing property (undefined) loosely equal to null', () => {
151
+ const ctx = { obj: {} };
152
+ // obj.missing is undefined; undefined == null is true in JS
153
+ expect(evaluator.evaluate('obj.missing == null', ctx).value).toBe(true);
154
+ });
155
+ it('should coerce a truthy non-boolean result via Boolean()', () => {
156
+ // The evaluator wraps the expression in Boolean(...): a bare truthy string yields true
157
+ const r = evaluator.evaluate('name', { name: 'non-empty' });
158
+ expect(r.success).toBe(true);
159
+ expect(r.value).toBe(true);
160
+ });
161
+ it('should coerce an empty-string result to false', () => {
162
+ const r = evaluator.evaluate('name', { name: '' });
163
+ expect(r.success).toBe(true);
164
+ expect(r.value).toBe(false);
165
+ });
166
+ it('should handle an empty context object with a self-contained expression', () => {
167
+ const r = evaluator.evaluate('1 < 2', {});
168
+ expect(r.success).toBe(true);
169
+ expect(r.value).toBe(true);
170
+ });
171
+ });
172
+ // ---------------------------------------------------------------
173
+ // Error paths for malformed / invalid input
174
+ // ---------------------------------------------------------------
175
+ describe('error handling', () => {
176
+ it('should fail on an empty expression', () => {
177
+ const r = evaluator.evaluate('', { a: 1 });
178
+ expect(r.success).toBe(false);
179
+ expect(r.error).toContain('non-empty string');
180
+ });
181
+ it('should evaluate a whitespace-only expression to false (Boolean() of no argument)', () => {
182
+ // A non-empty but whitespace-only string passes validation and compiles to
183
+ // `Boolean( )`, which is Boolean() === false — so it succeeds with value false.
184
+ const r = evaluator.evaluate(' ', { a: 1 });
185
+ expect(r.success).toBe(true);
186
+ expect(r.value).toBe(false);
187
+ });
188
+ it('should fail on unbalanced parentheses', () => {
189
+ const r = evaluator.evaluate('(a > 1', { a: 5 });
190
+ expect(r.success).toBe(false);
191
+ expect(r.error).toContain('Unbalanced parentheses');
192
+ });
193
+ it('should fail on a closing paren before an opening paren', () => {
194
+ const r = evaluator.evaluate('a > 1)', { a: 5 });
195
+ expect(r.success).toBe(false);
196
+ expect(r.error).toContain('Unbalanced parentheses');
197
+ });
198
+ it('should fail on a syntactically malformed expression', () => {
199
+ const r = evaluator.evaluate('a ===', { a: 1 });
200
+ expect(r.success).toBe(false);
201
+ expect(r.error).toBeDefined();
202
+ });
203
+ it('should fail when referencing an unknown identifier not in context', () => {
204
+ const r = evaluator.evaluate('missingVar > 1', { a: 1 });
205
+ expect(r.success).toBe(false);
206
+ expect(r.error).toContain('Expression evaluation failed');
207
+ });
208
+ it('should fail when the expression exceeds the 1000-character limit', () => {
209
+ const long = '1 == 1 && '.repeat(200) + '1 == 1'; // well over 1000 chars
210
+ const r = evaluator.evaluate(long, {});
211
+ expect(r.success).toBe(false);
212
+ expect(r.error).toContain('maximum length');
213
+ });
214
+ it('should fail when a context key is not a valid JS identifier', () => {
215
+ // Context keys become Function parameter names; "my-key" is not a valid identifier.
216
+ const ctx = { 'my-key': 1 };
217
+ const r = evaluator.evaluate('1 == 1', ctx);
218
+ expect(r.success).toBe(false);
219
+ expect(r.error).toBeDefined();
220
+ });
221
+ });
222
+ // ---------------------------------------------------------------
223
+ // Diagnostics
224
+ // ---------------------------------------------------------------
225
+ describe('diagnostics', () => {
226
+ it('should omit diagnostics by default', () => {
227
+ const r = evaluator.evaluate('a == 1', { a: 1 });
228
+ expect(r.diagnostics).toBeUndefined();
229
+ });
230
+ it('should include diagnostics when enabled on success', () => {
231
+ const r = evaluator.evaluate('a == 1', { a: 1 }, true);
232
+ expect(r.diagnostics).toBeDefined();
233
+ expect(r.diagnostics?.expression).toBe('a == 1');
234
+ expect(r.diagnostics?.context).toEqual({ a: 1 });
235
+ expect(typeof r.diagnostics?.evaluationTime).toBe('number');
236
+ });
237
+ it('should include diagnostics when enabled on failure', () => {
238
+ const r = evaluator.evaluate('', { a: 1 }, true);
239
+ expect(r.success).toBe(false);
240
+ expect(r.diagnostics).toBeDefined();
241
+ expect(r.diagnostics?.expression).toBe('');
242
+ });
243
+ });
244
+ // ---------------------------------------------------------------
245
+ // Caching behaviour (observable: repeated evals stay consistent)
246
+ // ---------------------------------------------------------------
247
+ describe('compiled-expression cache', () => {
248
+ it('should return consistent results across repeated evaluations of the same expression', () => {
249
+ const first = evaluator.evaluate('a > 1', { a: 5 });
250
+ const second = evaluator.evaluate('a > 1', { a: 5 });
251
+ expect(first.value).toBe(true);
252
+ expect(second.value).toBe(true);
253
+ });
254
+ it('should honour different context values on a cached expression', () => {
255
+ // Same expression + same context keys -> cache hit, but different values must still be applied
256
+ expect(evaluator.evaluate('a > 1', { a: 5 }).value).toBe(true);
257
+ expect(evaluator.evaluate('a > 1', { a: 0 }).value).toBe(false);
258
+ });
259
+ });
260
+ // ---------------------------------------------------------------
261
+ // evaluateMultiple
262
+ // ---------------------------------------------------------------
263
+ describe('evaluateMultiple', () => {
264
+ it('should evaluate several named expressions against one context', () => {
265
+ const results = evaluator.evaluateMultiple([
266
+ { expression: 'a > 1', name: 'aPositive' },
267
+ { expression: "b == 'x'", name: 'bIsX' },
268
+ ], { a: 5, b: 'x' });
269
+ expect(results.aPositive.value).toBe(true);
270
+ expect(results.bIsX.value).toBe(true);
271
+ });
272
+ it('should key unnamed expressions by index', () => {
273
+ const results = evaluator.evaluateMultiple([{ expression: 'a > 1' }], { a: 5 });
274
+ expect(results.expression_0.value).toBe(true);
275
+ });
276
+ it('should report per-expression failures independently', () => {
277
+ const results = evaluator.evaluateMultiple([
278
+ { expression: 'a > 1', name: 'ok' },
279
+ { expression: 'a ===', name: 'broken' },
280
+ ], { a: 5 });
281
+ expect(results.ok.success).toBe(true);
282
+ expect(results.broken.success).toBe(false);
283
+ });
284
+ });
285
+ // ---------------------------------------------------------------
286
+ // Safe globals — the shapes authored specs write
287
+ // ---------------------------------------------------------------
288
+ describe('safe global calls', () => {
289
+ // `condition-roots.ts` blesses these twelve names at the task-graph door, and
290
+ // `1efc248ac5` shipped that decision precisely because refusing them rejects specs
291
+ // that run correctly. Receiver and method are both fixed identifiers, so nothing
292
+ // here is reachable by string assembly.
293
+ const ctx = { payload: { count: 4, raw: '7', id: 42 }, output: { delta: -3 } };
294
+ it.each([
295
+ ['Math.abs(output.delta) < 5', true],
296
+ ['Math.max(payload.count, 9) === 9', true],
297
+ ['Number(payload.count) > 3', true],
298
+ ['String(payload.id).length > 0', true],
299
+ ['Boolean(payload.count) === true', true],
300
+ ['Array.isArray(output) === false', true],
301
+ ['Object.keys(payload).length > 0', true],
302
+ ["JSON.stringify(payload) !== ''", true],
303
+ ['Date.now() > 0', true],
304
+ ['parseInt(payload.raw) > 0', true],
305
+ ['parseFloat(payload.raw) === 7', true],
306
+ ['isNaN(payload.count) === false', true],
307
+ ['isFinite(payload.count) === true', true],
308
+ ['Number.isInteger(payload.count)', true],
309
+ ])('should evaluate %s', (expression, expected) => {
310
+ const r = evaluator.evaluate(expression, ctx);
311
+ expect(r.error).toBeUndefined();
312
+ expect(r.value).toBe(expected);
313
+ });
314
+ it('should reject a namespace method that is not on the list', () => {
315
+ // Mutators stay out even on an allowed namespace.
316
+ const r = evaluator.evaluate('Object.assign(payload) !== null', ctx);
317
+ expect(r.success).toBe(false);
318
+ expect(r.error).toContain('forbidden construct');
319
+ });
320
+ it('should reject a global that is not on the list', () => {
321
+ expect(evaluator.evaluate('Symbol("x") !== null', {}).success).toBe(false);
322
+ expect(evaluator.evaluate('fetch("/x") !== null', {}).success).toBe(false);
323
+ });
324
+ });
325
+ // ---------------------------------------------------------------
326
+ // Optional chaining
327
+ // ---------------------------------------------------------------
328
+ describe('optional chaining', () => {
329
+ it('should read through a present chain', () => {
330
+ const r = evaluator.evaluate("payload?.customer?.tier == 'premium'", {
331
+ payload: { customer: { tier: 'premium' } },
332
+ });
333
+ expect(r.value).toBe(true);
334
+ });
335
+ it('should short-circuit on an absent link rather than throwing', () => {
336
+ const r = evaluator.evaluate("payload?.customer?.tier == 'premium'", { payload: {} });
337
+ expect(r.success).toBe(true);
338
+ expect(r.value).toBe(false);
339
+ });
340
+ it('should apply the same rules to an optional index and an optional call', () => {
341
+ expect(evaluator.evaluate('items?.[0]?.price > 100', { items: [{ price: 150 }] }).value).toBe(true);
342
+ expect(evaluator.evaluate("name?.toLowerCase() == 'ada'", { name: 'Ada' }).value).toBe(true);
343
+ });
344
+ });
345
+ // ---------------------------------------------------------------
346
+ // Default exported instance
347
+ // ---------------------------------------------------------------
348
+ describe('defaultExpressionEvaluator', () => {
349
+ it('should be a usable SafeExpressionEvaluator instance', () => {
350
+ expect(defaultExpressionEvaluator).toBeInstanceOf(SafeExpressionEvaluator);
351
+ expect(defaultExpressionEvaluator.evaluate('1 == 1', {}).value).toBe(true);
352
+ });
353
+ });
354
+ });
355
+ //# sourceMappingURL=SafeExpressionEvaluator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafeExpressionEvaluator.test.js","sourceRoot":"","sources":["../../src/__tests__/SafeExpressionEvaluator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SafeExpressionEvaluator.validateSyntax.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafeExpressionEvaluator.validateSyntax.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/SafeExpressionEvaluator.validateSyntax.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * `validateSyntax` — checking that an expression *could* run, without running it.
3
+ *
4
+ * The distinction this draws is the whole point. `evaluate` reports two unrelated problems the same
5
+ * way: given an empty context, `payload.x > 1` fails with "payload is not defined" exactly as
6
+ * `payload.x >` fails with "Unexpected token". One is a typo; the other is a perfectly good
7
+ * condition that simply has no data yet. Anything built on `evaluate` to check authoring-time
8
+ * correctness therefore refuses every legitimate reference — which is the bug this method exists to
9
+ * make impossible.
10
+ *
11
+ * So the accept-list below matters more than the refuse-list: each entry is a shape somebody has
12
+ * already written, and over-refusing breaks saving work that runs fine.
13
+ */
14
+ import { describe, it, expect } from 'vitest';
15
+ import { SafeExpressionEvaluator } from '../SafeExpressionEvaluator.js';
16
+ const evaluator = new SafeExpressionEvaluator();
17
+ describe('validateSyntax — parses without evaluating', () => {
18
+ it.each([
19
+ ['payload.x > 1', 'an identifier that will only exist at runtime'],
20
+ ['payload.x.y === \'a\'', 'a chain one property deeper than the envelope'],
21
+ ['payload.title.includes(\'x\')', 'a method call on a value we cannot see yet'],
22
+ ['stepResult.step === \'Success\'', 'the flow dialect'],
23
+ ['unknownVar === 1', 'an identifier in no dialect at all — D2 may yet add it'],
24
+ ['succeeded', 'the shortest legal condition there is'],
25
+ ['output.count > 0 && !failed', 'operators either dialect uses'],
26
+ ])('accepts %s (%s)', (expression) => {
27
+ expect(evaluator.validateSyntax(expression)).toEqual({ Valid: true });
28
+ });
29
+ it.each([
30
+ ['payload.x >', 'a comparison with nothing on the right'],
31
+ ['foo(', 'an unclosed call'],
32
+ ['(payload.x > 1', 'unbalanced parentheses'],
33
+ ['payload.x > 1)', 'a stray closer'],
34
+ ['a ==== b', 'an operator that does not exist'],
35
+ ])('refuses %s (%s)', (expression) => {
36
+ const verdict = evaluator.validateSyntax(expression);
37
+ expect(verdict.Valid).toBe(false);
38
+ expect(verdict.Error).toBeTruthy();
39
+ });
40
+ it('refuses what the runtime would refuse anyway, rather than letting it hold forever', () => {
41
+ // These are policy, not grammar — but the evaluator rejects them at run time, so the edge
42
+ // would hold on every poll for the life of the graph. Better said now.
43
+ expect(evaluator.validateSyntax('a; b').Valid).toBe(false);
44
+ expect(evaluator.validateSyntax('this.x').Valid).toBe(false);
45
+ expect(evaluator.validateSyntax('x.constructor').Valid).toBe(false);
46
+ });
47
+ it('never runs the expression it is checking', () => {
48
+ // The guarantee that makes compile-don't-execute safe. If validation invoked the body, a
49
+ // condition would have side effects at SAVE time — on somebody else's machine.
50
+ let touched = false;
51
+ const globalScope = globalThis;
52
+ globalScope.__mjConditionProbe = () => { touched = true; return true; };
53
+ try {
54
+ evaluator.validateSyntax('__mjConditionProbe()');
55
+ expect(touched).toBe(false);
56
+ }
57
+ finally {
58
+ delete globalScope.__mjConditionProbe;
59
+ }
60
+ });
61
+ });
62
+ //# sourceMappingURL=SafeExpressionEvaluator.validateSyntax.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SafeExpressionEvaluator.validateSyntax.test.js","sourceRoot":"","sources":["../../src/__tests__/SafeExpressionEvaluator.validateSyntax.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,SAAS,GAAG,IAAI,uBAAuB,EAAE,CAAC;AAEhD,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACxD,EAAE,CAAC,IAAI,CAAC;QACJ,CAAC,eAAe,EAAE,+CAA+C,CAAC;QAClE,CAAC,uBAAuB,EAAE,+CAA+C,CAAC;QAC1E,CAAC,+BAA+B,EAAE,4CAA4C,CAAC;QAC/E,CAAC,iCAAiC,EAAE,kBAAkB,CAAC;QACvD,CAAC,kBAAkB,EAAE,wDAAwD,CAAC;QAC9E,CAAC,WAAW,EAAE,uCAAuC,CAAC;QACtD,CAAC,6BAA6B,EAAE,+BAA+B,CAAC;KACnE,CAAC,CAAC,iBAAiB,EAAE,CAAC,UAAU,EAAE,EAAE;QACjC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;QACJ,CAAC,aAAa,EAAE,wCAAwC,CAAC;QACzD,CAAC,MAAM,EAAE,kBAAkB,CAAC;QAC5B,CAAC,gBAAgB,EAAE,wBAAwB,CAAC;QAC5C,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;QACpC,CAAC,UAAU,EAAE,iCAAiC,CAAC;KAClD,CAAC,CAAC,iBAAiB,EAAE,CAAC,UAAU,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;QACzF,0FAA0F;QAC1F,uEAAuE;QACvE,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3D,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAChD,yFAAyF;QACzF,+EAA+E;QAC/E,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,WAAW,GAAG,UAAgD,CAAC;QACrE,WAAW,CAAC,kBAAkB,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC;YACD,SAAS,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC;YACjD,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;gBAAS,CAAC;YACP,OAAO,WAAW,CAAC,kBAAkB,CAAC;QAC1C,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TokenEndpointErrors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenEndpointErrors.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/TokenEndpointErrors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DescribeTokenEndpointFailure } from '../TokenEndpointErrors.js';
3
+ /** Credentials a token endpoint could echo back in an error body. */
4
+ const ACCESS_TOKEN = 'ya29.LIVE-ACCESS-TOKEN';
5
+ const CLIENT_SECRET = 'cs-LIVE-CLIENT-SECRET';
6
+ const REFRESH_TOKEN = 'rt-LIVE-REFRESH-TOKEN';
7
+ describe('DescribeTokenEndpointFailure', () => {
8
+ describe('withholds credentials the body may carry', () => {
9
+ it('withholds a body that is a bare token response', () => {
10
+ // Reached when a caller guards `!response.ok || !parsed.access_token` and the
11
+ // token was nested somewhere the parser did not look — the body IS the token.
12
+ const out = DescribeTokenEndpointFailure(JSON.stringify({ data: { access_token: ACCESS_TOKEN } }));
13
+ expect(out).not.toContain(ACCESS_TOKEN);
14
+ expect(out).toBe(' — response body withheld (may contain credentials)');
15
+ });
16
+ it('withholds an echoed request carrying client_secret', () => {
17
+ // The common real-world case: the endpoint echoes the failing request.
18
+ const out = DescribeTokenEndpointFailure(JSON.stringify({ request: { client_secret: CLIENT_SECRET, refresh_token: REFRESH_TOKEN } }));
19
+ expect(out).not.toContain(CLIENT_SECRET);
20
+ expect(out).not.toContain(REFRESH_TOKEN);
21
+ });
22
+ it('withholds a body that is not JSON at all', () => {
23
+ const out = DescribeTokenEndpointFailure(`<html>error: token=${ACCESS_TOKEN}</html>`);
24
+ expect(out).not.toContain(ACCESS_TOKEN);
25
+ expect(out).toBe(' — response body withheld (may contain credentials)');
26
+ });
27
+ it('withholds a JSON body carrying only non-standard fields', () => {
28
+ const out = DescribeTokenEndpointFailure(JSON.stringify({ detail: ACCESS_TOKEN }));
29
+ expect(out).not.toContain(ACCESS_TOKEN);
30
+ });
31
+ });
32
+ describe('surfaces the RFC 6749 §5.2 fields, which carry no credentials', () => {
33
+ it('returns both error and error_description when present', () => {
34
+ const out = DescribeTokenEndpointFailure(JSON.stringify({ error: 'invalid_client', error_description: 'Client authentication failed' }));
35
+ expect(out).toBe(' — invalid_client: Client authentication failed');
36
+ });
37
+ it('returns error alone when there is no description', () => {
38
+ expect(DescribeTokenEndpointFailure(JSON.stringify({ error: 'invalid_grant' })))
39
+ .toBe(' — invalid_grant');
40
+ });
41
+ it('returns the description alone when there is no code', () => {
42
+ expect(DescribeTokenEndpointFailure(JSON.stringify({ error_description: 'Token expired' })))
43
+ .toBe(' — Token expired');
44
+ });
45
+ it('ignores the rest of the body while surfacing the safe fields', () => {
46
+ const out = DescribeTokenEndpointFailure(JSON.stringify({ error: 'invalid_grant', access_token: ACCESS_TOKEN }));
47
+ expect(out).toBe(' — invalid_grant');
48
+ expect(out).not.toContain(ACCESS_TOKEN);
49
+ });
50
+ });
51
+ describe('is defensive about hostile or absent input', () => {
52
+ it('returns empty string for an absent body', () => {
53
+ expect(DescribeTokenEndpointFailure(undefined)).toBe('');
54
+ expect(DescribeTokenEndpointFailure(null)).toBe('');
55
+ expect(DescribeTokenEndpointFailure('')).toBe('');
56
+ });
57
+ it('caps an over-long description so a hostile endpoint cannot flood the log', () => {
58
+ const out = DescribeTokenEndpointFailure(JSON.stringify({ error_description: 'x'.repeat(5000) }));
59
+ expect(out.length).toBeLessThan(300);
60
+ expect(out.endsWith('…')).toBe(true);
61
+ });
62
+ it('withholds when the JSON body is not an object', () => {
63
+ expect(DescribeTokenEndpointFailure(JSON.stringify(ACCESS_TOKEN))).not.toContain(ACCESS_TOKEN);
64
+ expect(DescribeTokenEndpointFailure('null')).toBe(' — response body withheld (may contain credentials)');
65
+ });
66
+ it('ignores non-string error fields rather than coercing them', () => {
67
+ expect(DescribeTokenEndpointFailure(JSON.stringify({ error: { nested: ACCESS_TOKEN } })))
68
+ .not.toContain(ACCESS_TOKEN);
69
+ });
70
+ });
71
+ });
72
+ //# sourceMappingURL=TokenEndpointErrors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenEndpointErrors.test.js","sourceRoot":"","sources":["../../src/__tests__/TokenEndpointErrors.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=util.toEpochMs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.toEpochMs.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/util.toEpochMs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ToEpochMs } from '../util.js';
3
+ /**
4
+ * `ToEpochMs` is the shared guard behind every framework date comparator, so its contract
5
+ * is pinned directly here rather than only through those call sites.
6
+ *
7
+ * The contract that matters to a comparator: ALWAYS return a finite number. A comparator that
8
+ * can return `NaN` is incoherent — `sort` gets inconsistent orderings from it — which is the
9
+ * subtle half of the bug the old `?? 0` / `|| 0` patterns left open.
10
+ */
11
+ describe('ToEpochMs', () => {
12
+ const ISO = '2026-08-01T00:00:00.000Z';
13
+ const EPOCH = Date.UTC(2026, 7, 1);
14
+ it('returns getTime() for a Date', () => {
15
+ expect(ToEpochMs(new Date(ISO))).toBe(EPOCH);
16
+ });
17
+ it('parses an ISO string — the poisoned-cache shape that used to throw', () => {
18
+ expect(ToEpochMs(ISO)).toBe(EPOCH);
19
+ });
20
+ it('accepts a numeric timestamp', () => {
21
+ expect(ToEpochMs(EPOCH)).toBe(EPOCH);
22
+ });
23
+ it('returns 0 for null and undefined', () => {
24
+ expect(ToEpochMs(null)).toBe(0);
25
+ expect(ToEpochMs(undefined)).toBe(0);
26
+ });
27
+ it('returns 0 for an unparseable string rather than NaN', () => {
28
+ expect(ToEpochMs('not-a-date')).toBe(0);
29
+ });
30
+ it('returns 0 for an Invalid Date rather than NaN', () => {
31
+ // The case `?? 0` could not catch: Invalid Date's getTime() is NaN, and NaN is not
32
+ // nullish, so the old form propagated NaN straight into the comparator.
33
+ expect(ToEpochMs(new Date('garbage'))).toBe(0);
34
+ });
35
+ it('returns 0 for an empty string', () => {
36
+ expect(ToEpochMs('')).toBe(0);
37
+ });
38
+ it('never returns NaN for any of the above', () => {
39
+ const inputs = [
40
+ new Date(ISO), ISO, EPOCH, null, undefined, 'not-a-date', new Date('garbage'), '', 0,
41
+ ];
42
+ for (const input of inputs) {
43
+ expect(Number.isNaN(ToEpochMs(input))).toBe(false);
44
+ }
45
+ });
46
+ it('orders correctly when used as a descending comparator over mixed shapes', () => {
47
+ const rows = [
48
+ { id: 'missing', at: null },
49
+ { id: 'old', at: '2026-08-01T00:00:00.000Z' },
50
+ { id: 'new', at: new Date('2026-08-03T00:00:00.000Z') },
51
+ { id: 'mid', at: Date.UTC(2026, 7, 2) },
52
+ ];
53
+ const sorted = [...rows].sort((a, b) => ToEpochMs(b.at) - ToEpochMs(a.at));
54
+ expect(sorted.map((r) => r.id)).toEqual(['new', 'mid', 'old', 'missing']);
55
+ });
56
+ });
57
+ //# sourceMappingURL=util.toEpochMs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.toEpochMs.test.js","sourceRoot":"","sources":["../../src/__tests__/util.toEpochMs.test.ts"],"names":[],"mappings":"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"}