@fibery/expression-utils 1.1.7 → 1.1.9

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.
@@ -6,7 +6,6 @@ var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
6
6
 
7
7
  const getEntityQueryVariables = schema => {
8
8
  const grouped = ___default["default"].groupBy(schema.typeObjects.filter(x => x.isDomain), typeObject => typeObject.pluralTitle);
9
-
10
9
  return ___default["default"].flatten(Object.values(grouped).map(group => {
11
10
  return group.map(typeObject => ({
12
11
  typeObject,
@@ -10,11 +10,9 @@ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
10
10
  const serializeDate = momentDate => {
11
11
  return momentDate.format("YYYY-MM-DD");
12
12
  };
13
-
14
13
  const serializeDateTime = momentDate => {
15
14
  return momentDate.toISOString();
16
15
  };
17
-
18
16
  const formulaTodayDateParamPlaceholder = "$formula-today-date-placeholder";
19
17
  const formulaNowDateTimeParamPlaceholder = "$formula-now-date-time-placeholder";
20
18
  const todayDateParamPlaceholder = "$today-date";
@@ -77,11 +75,9 @@ const paramsPlaceholdersLookup = {
77
75
  };
78
76
  const replacePlaceholdersInParams = params => params && ___default["default"].mapValues(params, (value, key) => {
79
77
  const replaceFn = paramsPlaceholdersLookup[key];
80
-
81
78
  if (replaceFn) {
82
79
  return replaceFn();
83
80
  }
84
-
85
81
  return value;
86
82
  });
87
83
  const dateToDateTimeIntervalLookup = {
@@ -160,20 +156,17 @@ var paramsPlaceholders = {
160
156
  };
161
157
 
162
158
  function _extends() {
163
- _extends = Object.assign || function (target) {
159
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
164
160
  for (var i = 1; i < arguments.length; i++) {
165
161
  var source = arguments[i];
166
-
167
162
  for (var key in source) {
168
163
  if (Object.prototype.hasOwnProperty.call(source, key)) {
169
164
  target[key] = source[key];
170
165
  }
171
166
  }
172
167
  }
173
-
174
168
  return target;
175
169
  };
176
-
177
170
  return _extends.apply(this, arguments);
178
171
  }
179
172
 
@@ -181,15 +174,12 @@ const stringify = x => {
181
174
  if (x === undefined) {
182
175
  return "undefined";
183
176
  }
184
-
185
177
  return JSON.stringify(x);
186
178
  };
187
-
188
179
  class NotImplementedError extends Error {
189
180
  constructor(value, itemType = undefined) {
190
181
  super([`"${stringify(value)}"`, itemType, "is not implemented"].filter(x => x !== undefined).join(" "));
191
182
  }
192
-
193
183
  }
194
184
 
195
185
  const assertIsValidExpression = expression => {
@@ -200,55 +190,56 @@ const assertIsValidExpression = expression => {
200
190
  };
201
191
  const dateRangeFunctions = new Set(["q/start", "q/end"]);
202
192
  const firstLastFunctions = new Set(["q/first", "q/last"]);
203
- const collectionOps = new Set(["q/count", "q/count-distinct", "q/sum", "q/min", "q/max", "q/avg", "q/join", "q/first", "q/last"]); // [op, left, right]
193
+ const collectionOps = new Set(["q/count", "q/count-distinct", "q/sum", "q/min", "q/max", "q/avg", "q/join", "q/first", "q/last"]);
194
+ // [op, left, right]
204
195
  // [=, $true, $false]
205
196
  // [=, $my-id, ["fibery/id"]]
197
+ const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in",
198
+ //asc: obsolete,use q/in
199
+ "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or",
200
+ //asc: obsolete. use q/and, q/or
201
+ "q/and", "q/or", "q/in", "q/not-in"]);
206
202
 
207
- const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in", //asc: obsolete,use q/in
208
- "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or", //asc: obsolete. use q/and, q/or
209
- "q/and", "q/or", "q/in", "q/not-in"]); // TODO: get rid of this. Use visitors everywhere
210
-
203
+ // TODO: get rid of this. Use visitors everywhere
211
204
  const naryOperations = new Set(["and", "or", "q/and", "q/or"]);
212
205
  const logicalOperators = new Set(["and", "or", "q/and", "q/or"]);
213
206
  const relationalOperators = new Set(["=", "!=", "<", ">", "<=", ">="]);
214
207
  const mathOperators = new Set(["+", "-", "*", "/", "q/+", "q/-", "q/concat"]);
215
208
  const isFunctionCallExpression = expression => expression.length > 1 && ___default["default"].isString(expression[0]) && (expression[0].startsWith("q/") || ["=", "!=", "<", ">", "<=", ">=", "+", "-", "*", "/", "in", "and", "or", "not-in"].includes(expression[0]));
209
+ const fromRootKeyword = "q/from-root";
210
+ const isFromRootFieldExpression = expression => ___default["default"].isArray(expression) && expression[0] === fromRootKeyword;
216
211
  const isDateRangeFunctionExpression = expression => (expression.length === 2 || expression.length === 3) && dateRangeFunctions.has(expression[0]) && isFieldExpression(expression[1]);
217
- const isCollectionFunctionExpression = expression => //expression has length 3 in case of q/join
218
- (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]) && isFieldExpression(expression[1]);
212
+ const isCollectionFunctionExpression = expression =>
213
+ //expression has length 3 in case of q/join
214
+ (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]);
219
215
  const isAccessFunctionExpression = expresion => expresion.length === 2 && expresion[0] === "q/access?" && isFieldExpression(expresion[1]);
220
216
  const isBinaryExpression = expression => expression.length === 3 && binaryOperations.has(expression[0]);
221
217
  const isNaryExpression = expression => expression.length > 1 && naryOperations.has(expression[0]);
222
218
  const isVariableExpression = expression => ___default["default"].isString(expression) && expression.startsWith("$");
223
219
  const isFieldExpression = expression => Array.isArray(expression) && expression.every(x => !isVariableExpression(x) && !binaryOperations.has(x) && ___default["default"].isString(x));
224
- const isAxisFieldExpression = expression => isFieldExpression(expression) && expression.length === 1;
225
220
  const isQueryExpression = expression => {
226
221
  if (___default["default"].isObject(expression) && "q/from" in expression) {
227
- const fromExpression = expression["q/from"]; //asc: fromExpression === null for denormalizeSelect for reference collection case
228
-
222
+ const fromExpression = expression["q/from"];
223
+ //asc: fromExpression === null for denormalizeSelect for reference collection case
229
224
  return fromExpression === null || isFieldExpression(fromExpression);
230
225
  }
231
-
232
226
  return false;
233
- }; // [q/count, [..., collection]]
227
+ };
228
+ // [q/count, [..., collection]]
234
229
  // [q/start, [..., range]]
235
230
  // [q/end, [..., range]]
236
231
  // [q/access?, [..., field-expr]]
237
-
238
232
  const isFunctionExpression = expression => {
239
233
  if (!Array.isArray(expression)) {
240
234
  return false;
241
235
  }
242
-
243
236
  if (isFieldExpression(expression)) {
244
237
  return false;
245
238
  } else if (isDateRangeFunctionExpression(expression) || isCollectionFunctionExpression(expression) || isAccessFunctionExpression(expression)) {
246
239
  return true;
247
240
  }
248
-
249
241
  throw new Error("invalid expression:" + JSON.stringify(expression));
250
242
  };
251
-
252
243
  const collectFieldExpressions = (memo, expression) => {
253
244
  if (isVariableExpression(expression)) ; else if (isFunctionCallExpression(expression)) {
254
245
  for (const part of expression.slice(1)) {
@@ -267,7 +258,6 @@ const collectFieldExpressions = (memo, expression) => {
267
258
  const innerMemo = [];
268
259
  expression["q/select"] && collectFieldExpressions(innerMemo, expression["q/select"]);
269
260
  expression["q/where"] && collectFieldExpressions(innerMemo, expression["q/where"]);
270
-
271
261
  for (const fieldExpression of innerMemo) {
272
262
  memo.push([...expression["q/from"], ...fieldExpression]);
273
263
  }
@@ -275,7 +265,6 @@ const collectFieldExpressions = (memo, expression) => {
275
265
  throw new NotImplementedError(expression, "expression");
276
266
  }
277
267
  };
278
-
279
268
  const extractFieldExpressions = expression => {
280
269
  const memo = [];
281
270
  collectFieldExpressions(memo, expression);
@@ -286,6 +275,7 @@ const createExpressionVisitor = visitor => {
286
275
  const visitorDefault = {
287
276
  visitVariableExpression: expression => expression,
288
277
  visitFunctionCallExpression: ([fnName, ...args]) => [fnName, ...args.map(x => visitorWithDefault.visitExpression(x))],
278
+ visitFromRootFieldExpression: ([fromRootKeyword, ...rest]) => [fromRootKeyword, ...rest.map(x => visitorWithDefault.visitExpression(x))],
289
279
  visitFieldExpression: expression => expression,
290
280
  visitOrderByExpression: orderByExpression => orderByExpression.map(x => {
291
281
  const [fieldExpression, orderDir] = x;
@@ -314,6 +304,8 @@ const createExpressionVisitor = visitor => {
314
304
  throw new NotImplementedError(expression, "expression");
315
305
  } else if (isVariableExpression(expression)) {
316
306
  return visitorWithDefault.visitVariableExpression(expression, visitorDefault);
307
+ } else if (isFromRootFieldExpression(expression)) {
308
+ return visitorWithDefault.visitFromRootFieldExpression(expression, visitorDefault);
317
309
  } else if (isFunctionCallExpression(expression)) {
318
310
  return visitorWithDefault.visitFunctionCallExpression(expression, visitorDefault);
319
311
  } else if (isFieldExpression(expression)) {
@@ -338,6 +330,8 @@ var utils = {
338
330
  relationalOperators: relationalOperators,
339
331
  mathOperators: mathOperators,
340
332
  isFunctionCallExpression: isFunctionCallExpression,
333
+ fromRootKeyword: fromRootKeyword,
334
+ isFromRootFieldExpression: isFromRootFieldExpression,
341
335
  isDateRangeFunctionExpression: isDateRangeFunctionExpression,
342
336
  isCollectionFunctionExpression: isCollectionFunctionExpression,
343
337
  isAccessFunctionExpression: isAccessFunctionExpression,
@@ -345,7 +339,6 @@ var utils = {
345
339
  isNaryExpression: isNaryExpression,
346
340
  isVariableExpression: isVariableExpression,
347
341
  isFieldExpression: isFieldExpression,
348
- isAxisFieldExpression: isAxisFieldExpression,
349
342
  isQueryExpression: isQueryExpression,
350
343
  isFunctionExpression: isFunctionExpression,
351
344
  extractFieldExpressions: extractFieldExpressions,
@@ -361,7 +354,6 @@ const defaultIdsWithNamesOnFieldNotFound = ({
361
354
  fieldExpressionInNamesTerms: [...fieldExpressionInNamesTerms, fieldId]
362
355
  };
363
356
  };
364
-
365
357
  const visitFieldExpressionForReplaceIdsWithNamesVisitor = ({
366
358
  expression,
367
359
  typeObject,
@@ -388,7 +380,6 @@ const visitFieldExpressionForReplaceIdsWithNamesVisitor = ({
388
380
  currentTypeObject: typeObject,
389
381
  fieldExpressionInNamesTerms: []
390
382
  });
391
-
392
383
  const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWithNamesOnFieldNotFound) => {
393
384
  const visitor = createExpressionVisitor({
394
385
  visitFieldExpression: expression => visitFieldExpressionForReplaceIdsWithNamesVisitor({
@@ -408,7 +399,6 @@ const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWith
408
399
  onFieldNotFound,
409
400
  typeObject
410
401
  }).currentTypeObject;
411
-
412
402
  if (subQueryTypeObject) {
413
403
  const subQueryVisitor = replaceIdsWithNamesVisitor(subQueryTypeObject, onFieldNotFound);
414
404
  return _extends({}, subQueryExpression, {
@@ -420,13 +410,11 @@ const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWith
420
410
  "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
421
411
  } : null);
422
412
  }
423
-
424
413
  return subQueryExpression;
425
414
  }
426
415
  });
427
416
  return visitor;
428
417
  };
429
-
430
418
  const defaultNamesWithIdsOnFieldNotFound = ({
431
419
  fieldExpressionInIdsTerms,
432
420
  field
@@ -436,7 +424,6 @@ const defaultNamesWithIdsOnFieldNotFound = ({
436
424
  fieldExpressionInIdsTerms: [...fieldExpressionInIdsTerms, field]
437
425
  };
438
426
  };
439
-
440
427
  const visitFieldExpressionForReplaceNamesWithIdsVisitor = ({
441
428
  expression,
442
429
  onFieldNotFound,
@@ -463,7 +450,6 @@ const visitFieldExpressionForReplaceNamesWithIdsVisitor = ({
463
450
  currentTypeObject: typeObject,
464
451
  fieldExpressionInIdsTerms: []
465
452
  });
466
-
467
453
  const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWithIdsOnFieldNotFound) => {
468
454
  const visitor = createExpressionVisitor({
469
455
  visitFieldExpression: expression => visitFieldExpressionForReplaceNamesWithIdsVisitor({
@@ -483,7 +469,6 @@ const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWi
483
469
  onFieldNotFound,
484
470
  typeObject
485
471
  }).currentTypeObject;
486
-
487
472
  if (subQueryTypeObject) {
488
473
  const subQueryVisitor = replaceNamesWithIdsVisitor(subQueryTypeObject, onFieldNotFound);
489
474
  return _extends({}, subQueryExpression, {
@@ -495,7 +480,6 @@ const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWi
495
480
  "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
496
481
  } : null);
497
482
  }
498
-
499
483
  return subQueryExpression;
500
484
  }
501
485
  });
@@ -505,12 +489,10 @@ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
505
489
  const visitor = createExpressionVisitor({
506
490
  visitFunctionCallExpression: ([fnName, ...args]) => {
507
491
  const argsNew = args.map(x => visitor.visitExpression(x)).filter(Boolean);
508
-
509
492
  if (logicalOperators.has(fnName)) {
510
493
  if (argsNew.length > 0) {
511
494
  return argsNew.length === 1 ? argsNew[0] : [fnName, ...argsNew];
512
495
  }
513
-
514
496
  return null;
515
497
  } else {
516
498
  return argsNew.length === args.length ? [fnName, ...argsNew] : null;
@@ -536,10 +518,8 @@ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
536
518
  "q/order-by": orderByExpression
537
519
  } = subQueryExpression;
538
520
  const subQueryTypeObject = fromExpression.reduce((typeObject, field) => typeObject && typeObject.fieldObjectsByName.hasOwnProperty(field) ? typeObject.fieldObjectsByName[field].typeObject : null, typeObject);
539
-
540
521
  if (subQueryTypeObject) {
541
522
  const subQueryVisitor = deleteExpressionsWithNotFoundFieldsVisitor(subQueryTypeObject);
542
-
543
523
  const subQueryExpressionNew = ___default["default"].pickBy(_extends({}, subQueryExpression, {
544
524
  "q/from": visitor.visitFieldExpression(fromExpression),
545
525
  "q/select": subQueryVisitor.visitExpression(selectExpression)
@@ -548,7 +528,6 @@ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
548
528
  } : null, orderByExpression ? {
549
529
  "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
550
530
  } : null));
551
-
552
531
  const {
553
532
  "q/select": selectExpressionNew
554
533
  } = subQueryExpressionNew;
@@ -567,22 +546,26 @@ const expressionContainsAggregation = expression => {
567
546
  const {
568
547
  "q/select": selectExpression
569
548
  } = queryExpression;
570
-
571
549
  if (isCollectionFunctionExpression(selectExpression)) {
572
550
  result = true;
573
551
  }
552
+ },
553
+ visitFunctionCallExpression: (expression, visitorDefault) => {
554
+ if (firstLastFunctions.has(expression[0])) {
555
+ result = true;
556
+ } else {
557
+ visitorDefault.visitFunctionCallExpression(expression);
558
+ }
574
559
  }
575
560
  });
576
561
  visitor.visitExpression(expression);
577
562
  return result;
578
563
  };
579
-
580
564
  const defaultGetExpressionTypeOnFieldNotFound = () => {
581
565
  return {
582
566
  currentTypeObject: null
583
567
  };
584
568
  };
585
-
586
569
  const getFieldAccessExpressionTypeObject = ({
587
570
  expression,
588
571
  typeObject,
@@ -593,14 +576,12 @@ const getFieldAccessExpressionTypeObject = ({
593
576
  currentTypeObject
594
577
  }, fieldId, index) => {
595
578
  const fieldObject = currentTypeObject && currentTypeObject.fieldObjects.find(f => f.id === fieldId);
596
-
597
579
  if (fieldObject) {
598
580
  if (returnRefTypeInsteadOfId && index === expression.length - 1 && fieldObject.isId) {
599
581
  return {
600
582
  currentTypeObject
601
583
  };
602
584
  }
603
-
604
585
  return {
605
586
  currentTypeObject: fieldObject.typeObject
606
587
  };
@@ -615,9 +596,7 @@ const getFieldAccessExpressionTypeObject = ({
615
596
  });
616
597
  return reduced.currentTypeObject;
617
598
  };
618
-
619
599
  const UNKNOWN_EXPRESSION_TYPE = "unknown";
620
-
621
600
  const getExpressionTypeInternal = ({
622
601
  expression,
623
602
  typeObject,
@@ -632,11 +611,9 @@ const getExpressionTypeInternal = ({
632
611
  },
633
612
  visitFunctionCallExpression: function ([fnName, ...args]) {
634
613
  const fnMeta = functionsMeta[fnName];
635
-
636
614
  if (!fnMeta) {
637
615
  throw new Error(`Function meta for "${fnName}" was not provided`);
638
616
  }
639
-
640
617
  const argTypes = args.map(arg => getExpressionTypeInternal({
641
618
  expression: arg,
642
619
  typeObject,
@@ -645,11 +622,9 @@ const getExpressionTypeInternal = ({
645
622
  returnRefTypeInsteadOfId: false
646
623
  }));
647
624
  const overload = fnMeta.overloads.find(o => o["arg-types"].every((argType, index) => argTypes[index] === UNKNOWN_EXPRESSION_TYPE || argTypes[index] === argType));
648
-
649
625
  if (!overload) {
650
626
  throw new Error(`No overload with args ${argTypes.join(",")} found for "${fnName}" in meta`);
651
627
  }
652
-
653
628
  result = overload["result-type"];
654
629
  },
655
630
  visitQueryExpression: expression => {
@@ -663,16 +638,13 @@ const getExpressionTypeInternal = ({
663
638
  onFieldNotFound,
664
639
  returnRefTypeInsteadOfId
665
640
  });
666
-
667
641
  if (!fromTypeObject) {
668
642
  result = null;
669
643
  }
670
-
671
644
  if (___default["default"].isPlainObject(selectExpression)) {
672
645
  if (Object.values(selectExpression).length !== 1) {
673
646
  throw new Error(`Cannot determine type of query expression ${JSON.stringify(expression)}`);
674
647
  }
675
-
676
648
  result = getExpressionTypeInternal({
677
649
  expression: Object.values(selectExpression)[0],
678
650
  typeObject: fromTypeObject,
@@ -690,7 +662,6 @@ const getExpressionTypeInternal = ({
690
662
  });
691
663
  }
692
664
  },
693
-
694
665
  visitFieldExpression(expression) {
695
666
  const fieldAccessExpressionTypeObject = getFieldAccessExpressionTypeObject({
696
667
  expression,
@@ -700,12 +671,10 @@ const getExpressionTypeInternal = ({
700
671
  });
701
672
  result = fieldAccessExpressionTypeObject && fieldAccessExpressionTypeObject.name;
702
673
  }
703
-
704
674
  });
705
675
  visitor.visitExpression(expression);
706
676
  return result;
707
677
  };
708
-
709
678
  const getExpressionType = ({
710
679
  expression,
711
680
  typeObject,
@@ -734,7 +703,6 @@ var visitors = {
734
703
 
735
704
  const getEntityQueryVariables = schema => {
736
705
  const grouped = ___default["default"].groupBy(schema.typeObjects.filter(x => x.isDomain), typeObject => typeObject.pluralTitle);
737
-
738
706
  return ___default["default"].flatten(Object.values(grouped).map(group => {
739
707
  return group.map(typeObject => ({
740
708
  typeObject,
@@ -9,11 +9,9 @@ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
9
9
  const serializeDate = momentDate => {
10
10
  return momentDate.format("YYYY-MM-DD");
11
11
  };
12
-
13
12
  const serializeDateTime = momentDate => {
14
13
  return momentDate.toISOString();
15
14
  };
16
-
17
15
  const formulaTodayDateParamPlaceholder = "$formula-today-date-placeholder";
18
16
  const formulaNowDateTimeParamPlaceholder = "$formula-now-date-time-placeholder";
19
17
  const todayDateParamPlaceholder = "$today-date";
@@ -76,11 +74,9 @@ const paramsPlaceholdersLookup = {
76
74
  };
77
75
  const replacePlaceholdersInParams = params => params && ___default["default"].mapValues(params, (value, key) => {
78
76
  const replaceFn = paramsPlaceholdersLookup[key];
79
-
80
77
  if (replaceFn) {
81
78
  return replaceFn();
82
79
  }
83
-
84
80
  return value;
85
81
  });
86
82
  const dateToDateTimeIntervalLookup = {
package/lib/utils.js CHANGED
@@ -6,20 +6,17 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
6
6
  var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
7
7
 
8
8
  function _extends() {
9
- _extends = Object.assign || function (target) {
9
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
10
10
  for (var i = 1; i < arguments.length; i++) {
11
11
  var source = arguments[i];
12
-
13
12
  for (var key in source) {
14
13
  if (Object.prototype.hasOwnProperty.call(source, key)) {
15
14
  target[key] = source[key];
16
15
  }
17
16
  }
18
17
  }
19
-
20
18
  return target;
21
19
  };
22
-
23
20
  return _extends.apply(this, arguments);
24
21
  }
25
22
 
@@ -27,15 +24,12 @@ const stringify = x => {
27
24
  if (x === undefined) {
28
25
  return "undefined";
29
26
  }
30
-
31
27
  return JSON.stringify(x);
32
28
  };
33
-
34
29
  class NotImplementedError extends Error {
35
30
  constructor(value, itemType = undefined) {
36
31
  super([`"${stringify(value)}"`, itemType, "is not implemented"].filter(x => x !== undefined).join(" "));
37
32
  }
38
-
39
33
  }
40
34
 
41
35
  const assertIsValidExpression = expression => {
@@ -46,55 +40,56 @@ const assertIsValidExpression = expression => {
46
40
  };
47
41
  const dateRangeFunctions = new Set(["q/start", "q/end"]);
48
42
  const firstLastFunctions = new Set(["q/first", "q/last"]);
49
- const collectionOps = new Set(["q/count", "q/count-distinct", "q/sum", "q/min", "q/max", "q/avg", "q/join", "q/first", "q/last"]); // [op, left, right]
43
+ const collectionOps = new Set(["q/count", "q/count-distinct", "q/sum", "q/min", "q/max", "q/avg", "q/join", "q/first", "q/last"]);
44
+ // [op, left, right]
50
45
  // [=, $true, $false]
51
46
  // [=, $my-id, ["fibery/id"]]
47
+ const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in",
48
+ //asc: obsolete,use q/in
49
+ "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or",
50
+ //asc: obsolete. use q/and, q/or
51
+ "q/and", "q/or", "q/in", "q/not-in"]);
52
52
 
53
- const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in", //asc: obsolete,use q/in
54
- "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or", //asc: obsolete. use q/and, q/or
55
- "q/and", "q/or", "q/in", "q/not-in"]); // TODO: get rid of this. Use visitors everywhere
56
-
53
+ // TODO: get rid of this. Use visitors everywhere
57
54
  const naryOperations = new Set(["and", "or", "q/and", "q/or"]);
58
55
  const logicalOperators = new Set(["and", "or", "q/and", "q/or"]);
59
56
  const relationalOperators = new Set(["=", "!=", "<", ">", "<=", ">="]);
60
57
  const mathOperators = new Set(["+", "-", "*", "/", "q/+", "q/-", "q/concat"]);
61
58
  const isFunctionCallExpression = expression => expression.length > 1 && ___default["default"].isString(expression[0]) && (expression[0].startsWith("q/") || ["=", "!=", "<", ">", "<=", ">=", "+", "-", "*", "/", "in", "and", "or", "not-in"].includes(expression[0]));
59
+ const fromRootKeyword = "q/from-root";
60
+ const isFromRootFieldExpression = expression => ___default["default"].isArray(expression) && expression[0] === fromRootKeyword;
62
61
  const isDateRangeFunctionExpression = expression => (expression.length === 2 || expression.length === 3) && dateRangeFunctions.has(expression[0]) && isFieldExpression(expression[1]);
63
- const isCollectionFunctionExpression = expression => //expression has length 3 in case of q/join
64
- (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]) && isFieldExpression(expression[1]);
62
+ const isCollectionFunctionExpression = expression =>
63
+ //expression has length 3 in case of q/join
64
+ (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]);
65
65
  const isAccessFunctionExpression = expresion => expresion.length === 2 && expresion[0] === "q/access?" && isFieldExpression(expresion[1]);
66
66
  const isBinaryExpression = expression => expression.length === 3 && binaryOperations.has(expression[0]);
67
67
  const isNaryExpression = expression => expression.length > 1 && naryOperations.has(expression[0]);
68
68
  const isVariableExpression = expression => ___default["default"].isString(expression) && expression.startsWith("$");
69
69
  const isFieldExpression = expression => Array.isArray(expression) && expression.every(x => !isVariableExpression(x) && !binaryOperations.has(x) && ___default["default"].isString(x));
70
- const isAxisFieldExpression = expression => isFieldExpression(expression) && expression.length === 1;
71
70
  const isQueryExpression = expression => {
72
71
  if (___default["default"].isObject(expression) && "q/from" in expression) {
73
- const fromExpression = expression["q/from"]; //asc: fromExpression === null for denormalizeSelect for reference collection case
74
-
72
+ const fromExpression = expression["q/from"];
73
+ //asc: fromExpression === null for denormalizeSelect for reference collection case
75
74
  return fromExpression === null || isFieldExpression(fromExpression);
76
75
  }
77
-
78
76
  return false;
79
- }; // [q/count, [..., collection]]
77
+ };
78
+ // [q/count, [..., collection]]
80
79
  // [q/start, [..., range]]
81
80
  // [q/end, [..., range]]
82
81
  // [q/access?, [..., field-expr]]
83
-
84
82
  const isFunctionExpression = expression => {
85
83
  if (!Array.isArray(expression)) {
86
84
  return false;
87
85
  }
88
-
89
86
  if (isFieldExpression(expression)) {
90
87
  return false;
91
88
  } else if (isDateRangeFunctionExpression(expression) || isCollectionFunctionExpression(expression) || isAccessFunctionExpression(expression)) {
92
89
  return true;
93
90
  }
94
-
95
91
  throw new Error("invalid expression:" + JSON.stringify(expression));
96
92
  };
97
-
98
93
  const collectFieldExpressions = (memo, expression) => {
99
94
  if (isVariableExpression(expression)) ; else if (isFunctionCallExpression(expression)) {
100
95
  for (const part of expression.slice(1)) {
@@ -113,7 +108,6 @@ const collectFieldExpressions = (memo, expression) => {
113
108
  const innerMemo = [];
114
109
  expression["q/select"] && collectFieldExpressions(innerMemo, expression["q/select"]);
115
110
  expression["q/where"] && collectFieldExpressions(innerMemo, expression["q/where"]);
116
-
117
111
  for (const fieldExpression of innerMemo) {
118
112
  memo.push([...expression["q/from"], ...fieldExpression]);
119
113
  }
@@ -121,7 +115,6 @@ const collectFieldExpressions = (memo, expression) => {
121
115
  throw new NotImplementedError(expression, "expression");
122
116
  }
123
117
  };
124
-
125
118
  const extractFieldExpressions = expression => {
126
119
  const memo = [];
127
120
  collectFieldExpressions(memo, expression);
@@ -132,6 +125,7 @@ const createExpressionVisitor = visitor => {
132
125
  const visitorDefault = {
133
126
  visitVariableExpression: expression => expression,
134
127
  visitFunctionCallExpression: ([fnName, ...args]) => [fnName, ...args.map(x => visitorWithDefault.visitExpression(x))],
128
+ visitFromRootFieldExpression: ([fromRootKeyword, ...rest]) => [fromRootKeyword, ...rest.map(x => visitorWithDefault.visitExpression(x))],
135
129
  visitFieldExpression: expression => expression,
136
130
  visitOrderByExpression: orderByExpression => orderByExpression.map(x => {
137
131
  const [fieldExpression, orderDir] = x;
@@ -160,6 +154,8 @@ const createExpressionVisitor = visitor => {
160
154
  throw new NotImplementedError(expression, "expression");
161
155
  } else if (isVariableExpression(expression)) {
162
156
  return visitorWithDefault.visitVariableExpression(expression, visitorDefault);
157
+ } else if (isFromRootFieldExpression(expression)) {
158
+ return visitorWithDefault.visitFromRootFieldExpression(expression, visitorDefault);
163
159
  } else if (isFunctionCallExpression(expression)) {
164
160
  return visitorWithDefault.visitFunctionCallExpression(expression, visitorDefault);
165
161
  } else if (isFieldExpression(expression)) {
@@ -180,12 +176,13 @@ exports.createExpressionVisitor = createExpressionVisitor;
180
176
  exports.dateRangeFunctions = dateRangeFunctions;
181
177
  exports.extractFieldExpressions = extractFieldExpressions;
182
178
  exports.firstLastFunctions = firstLastFunctions;
179
+ exports.fromRootKeyword = fromRootKeyword;
183
180
  exports.isAccessFunctionExpression = isAccessFunctionExpression;
184
- exports.isAxisFieldExpression = isAxisFieldExpression;
185
181
  exports.isBinaryExpression = isBinaryExpression;
186
182
  exports.isCollectionFunctionExpression = isCollectionFunctionExpression;
187
183
  exports.isDateRangeFunctionExpression = isDateRangeFunctionExpression;
188
184
  exports.isFieldExpression = isFieldExpression;
185
+ exports.isFromRootFieldExpression = isFromRootFieldExpression;
189
186
  exports.isFunctionCallExpression = isFunctionCallExpression;
190
187
  exports.isFunctionExpression = isFunctionExpression;
191
188
  exports.isNaryExpression = isNaryExpression;
package/lib/visitors.js CHANGED
@@ -6,20 +6,17 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
6
6
  var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
7
7
 
8
8
  function _extends() {
9
- _extends = Object.assign || function (target) {
9
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
10
10
  for (var i = 1; i < arguments.length; i++) {
11
11
  var source = arguments[i];
12
-
13
12
  for (var key in source) {
14
13
  if (Object.prototype.hasOwnProperty.call(source, key)) {
15
14
  target[key] = source[key];
16
15
  }
17
16
  }
18
17
  }
19
-
20
18
  return target;
21
19
  };
22
-
23
20
  return _extends.apply(this, arguments);
24
21
  }
25
22
 
@@ -27,44 +24,47 @@ const stringify = x => {
27
24
  if (x === undefined) {
28
25
  return "undefined";
29
26
  }
30
-
31
27
  return JSON.stringify(x);
32
28
  };
33
-
34
29
  class NotImplementedError extends Error {
35
30
  constructor(value, itemType = undefined) {
36
31
  super([`"${stringify(value)}"`, itemType, "is not implemented"].filter(x => x !== undefined).join(" "));
37
32
  }
38
-
39
33
  }
40
34
 
41
- const collectionOps = new Set(["q/count", "q/count-distinct", "q/sum", "q/min", "q/max", "q/avg", "q/join", "q/first", "q/last"]); // [op, left, right]
35
+ const firstLastFunctions = new Set(["q/first", "q/last"]);
36
+ const collectionOps = new Set(["q/count", "q/count-distinct", "q/sum", "q/min", "q/max", "q/avg", "q/join", "q/first", "q/last"]);
37
+ // [op, left, right]
42
38
  // [=, $true, $false]
43
39
  // [=, $my-id, ["fibery/id"]]
44
-
45
- const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in", //asc: obsolete,use q/in
46
- "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or", //asc: obsolete. use q/and, q/or
47
- "q/and", "q/or", "q/in", "q/not-in"]); // TODO: get rid of this. Use visitors everywhere
40
+ const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in",
41
+ //asc: obsolete,use q/in
42
+ "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or",
43
+ //asc: obsolete. use q/and, q/or
44
+ "q/and", "q/or", "q/in", "q/not-in"]);
48
45
  const logicalOperators = new Set(["and", "or", "q/and", "q/or"]);
49
46
  const isFunctionCallExpression = expression => expression.length > 1 && ___default["default"].isString(expression[0]) && (expression[0].startsWith("q/") || ["=", "!=", "<", ">", "<=", ">=", "+", "-", "*", "/", "in", "and", "or", "not-in"].includes(expression[0]));
50
- const isCollectionFunctionExpression = expression => //expression has length 3 in case of q/join
51
- (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]) && isFieldExpression(expression[1]);
47
+ const fromRootKeyword = "q/from-root";
48
+ const isFromRootFieldExpression = expression => ___default["default"].isArray(expression) && expression[0] === fromRootKeyword;
49
+ const isCollectionFunctionExpression = expression =>
50
+ //expression has length 3 in case of q/join
51
+ (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]);
52
52
  const isVariableExpression = expression => ___default["default"].isString(expression) && expression.startsWith("$");
53
53
  const isFieldExpression = expression => Array.isArray(expression) && expression.every(x => !isVariableExpression(x) && !binaryOperations.has(x) && ___default["default"].isString(x));
54
54
  const isQueryExpression = expression => {
55
55
  if (___default["default"].isObject(expression) && "q/from" in expression) {
56
- const fromExpression = expression["q/from"]; //asc: fromExpression === null for denormalizeSelect for reference collection case
57
-
56
+ const fromExpression = expression["q/from"];
57
+ //asc: fromExpression === null for denormalizeSelect for reference collection case
58
58
  return fromExpression === null || isFieldExpression(fromExpression);
59
59
  }
60
-
61
60
  return false;
62
- }; // [q/count, [..., collection]]
61
+ };
63
62
  const createExpressionVisitor = visitor => {
64
63
  let visitorWithDefault = null;
65
64
  const visitorDefault = {
66
65
  visitVariableExpression: expression => expression,
67
66
  visitFunctionCallExpression: ([fnName, ...args]) => [fnName, ...args.map(x => visitorWithDefault.visitExpression(x))],
67
+ visitFromRootFieldExpression: ([fromRootKeyword, ...rest]) => [fromRootKeyword, ...rest.map(x => visitorWithDefault.visitExpression(x))],
68
68
  visitFieldExpression: expression => expression,
69
69
  visitOrderByExpression: orderByExpression => orderByExpression.map(x => {
70
70
  const [fieldExpression, orderDir] = x;
@@ -93,6 +93,8 @@ const createExpressionVisitor = visitor => {
93
93
  throw new NotImplementedError(expression, "expression");
94
94
  } else if (isVariableExpression(expression)) {
95
95
  return visitorWithDefault.visitVariableExpression(expression, visitorDefault);
96
+ } else if (isFromRootFieldExpression(expression)) {
97
+ return visitorWithDefault.visitFromRootFieldExpression(expression, visitorDefault);
96
98
  } else if (isFunctionCallExpression(expression)) {
97
99
  return visitorWithDefault.visitFunctionCallExpression(expression, visitorDefault);
98
100
  } else if (isFieldExpression(expression)) {
@@ -117,7 +119,6 @@ const defaultIdsWithNamesOnFieldNotFound = ({
117
119
  fieldExpressionInNamesTerms: [...fieldExpressionInNamesTerms, fieldId]
118
120
  };
119
121
  };
120
-
121
122
  const visitFieldExpressionForReplaceIdsWithNamesVisitor = ({
122
123
  expression,
123
124
  typeObject,
@@ -144,7 +145,6 @@ const visitFieldExpressionForReplaceIdsWithNamesVisitor = ({
144
145
  currentTypeObject: typeObject,
145
146
  fieldExpressionInNamesTerms: []
146
147
  });
147
-
148
148
  const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWithNamesOnFieldNotFound) => {
149
149
  const visitor = createExpressionVisitor({
150
150
  visitFieldExpression: expression => visitFieldExpressionForReplaceIdsWithNamesVisitor({
@@ -164,7 +164,6 @@ const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWith
164
164
  onFieldNotFound,
165
165
  typeObject
166
166
  }).currentTypeObject;
167
-
168
167
  if (subQueryTypeObject) {
169
168
  const subQueryVisitor = replaceIdsWithNamesVisitor(subQueryTypeObject, onFieldNotFound);
170
169
  return _extends({}, subQueryExpression, {
@@ -176,13 +175,11 @@ const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWith
176
175
  "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
177
176
  } : null);
178
177
  }
179
-
180
178
  return subQueryExpression;
181
179
  }
182
180
  });
183
181
  return visitor;
184
182
  };
185
-
186
183
  const defaultNamesWithIdsOnFieldNotFound = ({
187
184
  fieldExpressionInIdsTerms,
188
185
  field
@@ -192,7 +189,6 @@ const defaultNamesWithIdsOnFieldNotFound = ({
192
189
  fieldExpressionInIdsTerms: [...fieldExpressionInIdsTerms, field]
193
190
  };
194
191
  };
195
-
196
192
  const visitFieldExpressionForReplaceNamesWithIdsVisitor = ({
197
193
  expression,
198
194
  onFieldNotFound,
@@ -219,7 +215,6 @@ const visitFieldExpressionForReplaceNamesWithIdsVisitor = ({
219
215
  currentTypeObject: typeObject,
220
216
  fieldExpressionInIdsTerms: []
221
217
  });
222
-
223
218
  const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWithIdsOnFieldNotFound) => {
224
219
  const visitor = createExpressionVisitor({
225
220
  visitFieldExpression: expression => visitFieldExpressionForReplaceNamesWithIdsVisitor({
@@ -239,7 +234,6 @@ const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWi
239
234
  onFieldNotFound,
240
235
  typeObject
241
236
  }).currentTypeObject;
242
-
243
237
  if (subQueryTypeObject) {
244
238
  const subQueryVisitor = replaceNamesWithIdsVisitor(subQueryTypeObject, onFieldNotFound);
245
239
  return _extends({}, subQueryExpression, {
@@ -251,7 +245,6 @@ const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWi
251
245
  "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
252
246
  } : null);
253
247
  }
254
-
255
248
  return subQueryExpression;
256
249
  }
257
250
  });
@@ -261,12 +254,10 @@ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
261
254
  const visitor = createExpressionVisitor({
262
255
  visitFunctionCallExpression: ([fnName, ...args]) => {
263
256
  const argsNew = args.map(x => visitor.visitExpression(x)).filter(Boolean);
264
-
265
257
  if (logicalOperators.has(fnName)) {
266
258
  if (argsNew.length > 0) {
267
259
  return argsNew.length === 1 ? argsNew[0] : [fnName, ...argsNew];
268
260
  }
269
-
270
261
  return null;
271
262
  } else {
272
263
  return argsNew.length === args.length ? [fnName, ...argsNew] : null;
@@ -292,10 +283,8 @@ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
292
283
  "q/order-by": orderByExpression
293
284
  } = subQueryExpression;
294
285
  const subQueryTypeObject = fromExpression.reduce((typeObject, field) => typeObject && typeObject.fieldObjectsByName.hasOwnProperty(field) ? typeObject.fieldObjectsByName[field].typeObject : null, typeObject);
295
-
296
286
  if (subQueryTypeObject) {
297
287
  const subQueryVisitor = deleteExpressionsWithNotFoundFieldsVisitor(subQueryTypeObject);
298
-
299
288
  const subQueryExpressionNew = ___default["default"].pickBy(_extends({}, subQueryExpression, {
300
289
  "q/from": visitor.visitFieldExpression(fromExpression),
301
290
  "q/select": subQueryVisitor.visitExpression(selectExpression)
@@ -304,7 +293,6 @@ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
304
293
  } : null, orderByExpression ? {
305
294
  "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
306
295
  } : null));
307
-
308
296
  const {
309
297
  "q/select": selectExpressionNew
310
298
  } = subQueryExpressionNew;
@@ -323,22 +311,26 @@ const expressionContainsAggregation = expression => {
323
311
  const {
324
312
  "q/select": selectExpression
325
313
  } = queryExpression;
326
-
327
314
  if (isCollectionFunctionExpression(selectExpression)) {
328
315
  result = true;
329
316
  }
317
+ },
318
+ visitFunctionCallExpression: (expression, visitorDefault) => {
319
+ if (firstLastFunctions.has(expression[0])) {
320
+ result = true;
321
+ } else {
322
+ visitorDefault.visitFunctionCallExpression(expression);
323
+ }
330
324
  }
331
325
  });
332
326
  visitor.visitExpression(expression);
333
327
  return result;
334
328
  };
335
-
336
329
  const defaultGetExpressionTypeOnFieldNotFound = () => {
337
330
  return {
338
331
  currentTypeObject: null
339
332
  };
340
333
  };
341
-
342
334
  const getFieldAccessExpressionTypeObject = ({
343
335
  expression,
344
336
  typeObject,
@@ -349,14 +341,12 @@ const getFieldAccessExpressionTypeObject = ({
349
341
  currentTypeObject
350
342
  }, fieldId, index) => {
351
343
  const fieldObject = currentTypeObject && currentTypeObject.fieldObjects.find(f => f.id === fieldId);
352
-
353
344
  if (fieldObject) {
354
345
  if (returnRefTypeInsteadOfId && index === expression.length - 1 && fieldObject.isId) {
355
346
  return {
356
347
  currentTypeObject
357
348
  };
358
349
  }
359
-
360
350
  return {
361
351
  currentTypeObject: fieldObject.typeObject
362
352
  };
@@ -371,9 +361,7 @@ const getFieldAccessExpressionTypeObject = ({
371
361
  });
372
362
  return reduced.currentTypeObject;
373
363
  };
374
-
375
364
  const UNKNOWN_EXPRESSION_TYPE = "unknown";
376
-
377
365
  const getExpressionTypeInternal = ({
378
366
  expression,
379
367
  typeObject,
@@ -388,11 +376,9 @@ const getExpressionTypeInternal = ({
388
376
  },
389
377
  visitFunctionCallExpression: function ([fnName, ...args]) {
390
378
  const fnMeta = functionsMeta[fnName];
391
-
392
379
  if (!fnMeta) {
393
380
  throw new Error(`Function meta for "${fnName}" was not provided`);
394
381
  }
395
-
396
382
  const argTypes = args.map(arg => getExpressionTypeInternal({
397
383
  expression: arg,
398
384
  typeObject,
@@ -401,11 +387,9 @@ const getExpressionTypeInternal = ({
401
387
  returnRefTypeInsteadOfId: false
402
388
  }));
403
389
  const overload = fnMeta.overloads.find(o => o["arg-types"].every((argType, index) => argTypes[index] === UNKNOWN_EXPRESSION_TYPE || argTypes[index] === argType));
404
-
405
390
  if (!overload) {
406
391
  throw new Error(`No overload with args ${argTypes.join(",")} found for "${fnName}" in meta`);
407
392
  }
408
-
409
393
  result = overload["result-type"];
410
394
  },
411
395
  visitQueryExpression: expression => {
@@ -419,16 +403,13 @@ const getExpressionTypeInternal = ({
419
403
  onFieldNotFound,
420
404
  returnRefTypeInsteadOfId
421
405
  });
422
-
423
406
  if (!fromTypeObject) {
424
407
  result = null;
425
408
  }
426
-
427
409
  if (___default["default"].isPlainObject(selectExpression)) {
428
410
  if (Object.values(selectExpression).length !== 1) {
429
411
  throw new Error(`Cannot determine type of query expression ${JSON.stringify(expression)}`);
430
412
  }
431
-
432
413
  result = getExpressionTypeInternal({
433
414
  expression: Object.values(selectExpression)[0],
434
415
  typeObject: fromTypeObject,
@@ -446,7 +427,6 @@ const getExpressionTypeInternal = ({
446
427
  });
447
428
  }
448
429
  },
449
-
450
430
  visitFieldExpression(expression) {
451
431
  const fieldAccessExpressionTypeObject = getFieldAccessExpressionTypeObject({
452
432
  expression,
@@ -456,12 +436,10 @@ const getExpressionTypeInternal = ({
456
436
  });
457
437
  result = fieldAccessExpressionTypeObject && fieldAccessExpressionTypeObject.name;
458
438
  }
459
-
460
439
  });
461
440
  visitor.visitExpression(expression);
462
441
  return result;
463
442
  };
464
-
465
443
  const getExpressionType = ({
466
444
  expression,
467
445
  typeObject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fibery/expression-utils",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "utils for working with fibery api expressions",
5
5
  "exports": {
6
6
  ".": "./lib/expression-utils.js",
@@ -22,27 +22,26 @@
22
22
  ],
23
23
  "private": false,
24
24
  "dependencies": {
25
+ "@fibery/helpers": "1.0.2",
25
26
  "lodash": "4.17.21",
26
- "moment": "2.20.1",
27
- "@fibery/helpers": "1.0.2"
27
+ "moment": "2.20.1"
28
28
  },
29
29
  "devDependencies": {
30
- "@babel/core": "7.15.0",
31
- "babel-jest": "27.5.1",
32
- "babel-loader": "8.2.5",
30
+ "@babel/core": "7.20.5",
33
31
  "@fibery/babel-preset": "7.2.0",
34
- "@fibery/eslint-config": "8.1.0",
32
+ "@fibery/eslint-config": "8.2.0",
35
33
  "jest": "27.5.1",
36
34
  "jest-junit": "13.0.0",
37
35
  "microbundle": "0.15.0"
38
36
  },
39
37
  "peerDependencies": {
40
- "@fibery/schema": "^8.0.6"
38
+ "@fibery/schema": "^8.1.0"
41
39
  },
42
40
  "scripts": {
43
41
  "build": "rm -rf lib && microbundle paramsPlaceholders.js utils.js visitors.js contextVariables.js index.js -o lib -f cjs --no-compress --target node --sourcemap false",
44
42
  "test": "node scripts/test.js",
45
- "test:ci": "yarn test --coverage --reporters=default --reporters=jest-junit",
43
+ "test:ci": "yarn test --reporters=default --reporters=jest-junit",
44
+ "test:coverage": "yarn test --coverage --coverageDirectory=${JEST_COVERAGE_RESULT_DIR:-$(pwd)}/coverage/expression-utils --reporters=default --reporters=jest-junit",
46
45
  "lint": "eslint ."
47
46
  },
48
47
  "jest": {