@fibery/expression-utils 1.0.21 → 1.1.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.
@@ -0,0 +1,794 @@
1
+ var _ = require('lodash');
2
+ var moment = require('moment');
3
+ var util = require('util');
4
+
5
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
6
+
7
+ var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
8
+ var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
9
+ var util__default = /*#__PURE__*/_interopDefaultLegacy(util);
10
+
11
+ const serializeDate = momentDate => {
12
+ return momentDate.format("YYYY-MM-DD");
13
+ };
14
+
15
+ const serializeDateTime = momentDate => {
16
+ return momentDate.toISOString();
17
+ };
18
+
19
+ const formulaTodayDateParamPlaceholder = "$formula-today-date-placeholder";
20
+ const formulaNowDateTimeParamPlaceholder = "$formula-now-date-time-placeholder";
21
+ const todayDateParamPlaceholder = "$today-date";
22
+ const tomorrowDateParamPlaceholder = "$tomorrow-date";
23
+ const yesterdayDateParamPlaceholder = "$yesterday-date";
24
+ const weekAgoDateParamPlaceholder = "$week-ago-date";
25
+ const weekFromNowDateParamPlaceholder = "$week-from-now-date";
26
+ const monthAgoDateParamPlaceholder = "$month-ago-date";
27
+ const monthFromNowDateParamPlaceholder = "$month-from-now-date";
28
+ const yearAgoDateParamPlaceholder = "$year-ago-date";
29
+ const yearFromNowDateParamPlaceholder = "$year-from-now-date";
30
+ const todayStartDateTimeParamPlaceholder = "$today-date-time-start";
31
+ const todayEndDateTimeParamPlaceholder = "$today-date-time-end";
32
+ const tomorrowStartDateTimeParamPlaceholder = "$tomorrow-date-time-start";
33
+ const tomorrowEndDateTimeParamPlaceholder = "$tomorrow-date-time-end";
34
+ const yesterdayStartDateTimeParamPlaceholder = "$yesterday-date-time-start";
35
+ const yesterdayEndDateTimeParamPlaceholder = "$yesterday-date-time-end";
36
+ const weekAgoStartDateTimeParamPlaceholder = "$week-ago-date-time-start";
37
+ const weekAgoEndDateTimeParamPlaceholder = "$week-ago-date-time-end";
38
+ const weekFromNowStartDateTimeParamPlaceholder = "$week-from-now-date-time-start";
39
+ const weekFromNowEndDateTimeParamPlaceholder = "$week-from-now-date-time-end";
40
+ const monthAgoStartDateTimeParamPlaceholder = "$month-ago-date-time-start";
41
+ const monthAgoEndDateTimeParamPlaceholder = "$month-ago-date-time-end";
42
+ const monthFromNowStartDateTimeParamPlaceholder = "$month-from-now-date-time-start";
43
+ const monthFromNowEndDateTimeParamPlaceholder = "$month-from-now-date-time-end";
44
+ const yearAgoStartDateTimeParamPlaceholder = "$year-ago-date-time-start";
45
+ const yearAgoEndDateTimeParamPlaceholder = "$year-ago-date-time-end";
46
+ const yearFromNowStartDateTimeParamPlaceholder = "$year-from-now-date-time-start";
47
+ const yearFromNowEndDateTimeParamPlaceholder = "$year-from-now-date-time-end";
48
+ const paramsPlaceholdersLookup = {
49
+ [todayDateParamPlaceholder]: () => serializeDate(moment__default["default"]()),
50
+ [formulaTodayDateParamPlaceholder]: () => serializeDate(moment__default["default"]()),
51
+ [formulaNowDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]()),
52
+ [tomorrowDateParamPlaceholder]: () => serializeDate(moment__default["default"]().add(1, "days")),
53
+ [yesterdayDateParamPlaceholder]: () => serializeDate(moment__default["default"]().subtract(1, "days")),
54
+ [weekAgoDateParamPlaceholder]: () => serializeDate(moment__default["default"]().subtract(7, "days")),
55
+ [weekFromNowDateParamPlaceholder]: () => serializeDate(moment__default["default"]().add(7, "days")),
56
+ [monthAgoDateParamPlaceholder]: () => serializeDate(moment__default["default"]().subtract(1, "months")),
57
+ [monthFromNowDateParamPlaceholder]: () => serializeDate(moment__default["default"]().add(1, "months")),
58
+ [yearAgoDateParamPlaceholder]: () => serializeDate(moment__default["default"]().subtract(1, "year")),
59
+ [yearFromNowDateParamPlaceholder]: () => serializeDate(moment__default["default"]().add(1, "year")),
60
+ [todayStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().startOf("day")),
61
+ [todayEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().endOf("day")),
62
+ [tomorrowStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(1, "days").startOf("day")),
63
+ [tomorrowEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(1, "days").endOf("day")),
64
+ [yesterdayStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(1, "days").startOf("day")),
65
+ [yesterdayEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(1, "days").endOf("day")),
66
+ [weekAgoStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(7, "days").startOf("day")),
67
+ [weekAgoEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(7, "days").endOf("day")),
68
+ [weekFromNowStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(7, "days").startOf("day")),
69
+ [weekFromNowEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(7, "days").endOf("day")),
70
+ [monthAgoStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(1, "months").startOf("day")),
71
+ [monthAgoEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(1, "months").endOf("day")),
72
+ [monthFromNowStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(1, "months").startOf("day")),
73
+ [monthFromNowEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(1, "months").endOf("day")),
74
+ [yearAgoStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(1, "year").startOf("day")),
75
+ [yearAgoEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().subtract(1, "year").endOf("day")),
76
+ [yearFromNowStartDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(1, "year").startOf("day")),
77
+ [yearFromNowEndDateTimeParamPlaceholder]: () => serializeDateTime(moment__default["default"]().add(1, "year").endOf("day"))
78
+ };
79
+ const replacePlaceholdersInParams = params => params && ___default["default"].mapValues(params, (value, key) => {
80
+ const replaceFn = paramsPlaceholdersLookup[key];
81
+
82
+ if (replaceFn) {
83
+ return replaceFn();
84
+ }
85
+
86
+ return value;
87
+ });
88
+ const dateToDateTimeIntervalLookup = {
89
+ [todayDateParamPlaceholder]: {
90
+ start: todayStartDateTimeParamPlaceholder,
91
+ end: todayEndDateTimeParamPlaceholder
92
+ },
93
+ [tomorrowDateParamPlaceholder]: {
94
+ start: tomorrowStartDateTimeParamPlaceholder,
95
+ end: tomorrowEndDateTimeParamPlaceholder
96
+ },
97
+ [yesterdayDateParamPlaceholder]: {
98
+ start: yesterdayStartDateTimeParamPlaceholder,
99
+ end: yesterdayEndDateTimeParamPlaceholder
100
+ },
101
+ [weekAgoDateParamPlaceholder]: {
102
+ start: weekAgoStartDateTimeParamPlaceholder,
103
+ end: weekAgoEndDateTimeParamPlaceholder
104
+ },
105
+ [weekFromNowDateParamPlaceholder]: {
106
+ start: weekFromNowStartDateTimeParamPlaceholder,
107
+ end: weekFromNowEndDateTimeParamPlaceholder
108
+ },
109
+ [monthAgoDateParamPlaceholder]: {
110
+ start: monthAgoStartDateTimeParamPlaceholder,
111
+ end: monthAgoEndDateTimeParamPlaceholder
112
+ },
113
+ [monthFromNowDateParamPlaceholder]: {
114
+ start: monthFromNowStartDateTimeParamPlaceholder,
115
+ end: monthFromNowEndDateTimeParamPlaceholder
116
+ },
117
+ [yearAgoDateParamPlaceholder]: {
118
+ start: yearAgoStartDateTimeParamPlaceholder,
119
+ end: yearAgoEndDateTimeParamPlaceholder
120
+ },
121
+ [yearFromNowDateParamPlaceholder]: {
122
+ start: yearFromNowStartDateTimeParamPlaceholder,
123
+ end: yearFromNowEndDateTimeParamPlaceholder
124
+ }
125
+ };
126
+
127
+ var paramsPlaceholders = {
128
+ __proto__: null,
129
+ formulaTodayDateParamPlaceholder: formulaTodayDateParamPlaceholder,
130
+ formulaNowDateTimeParamPlaceholder: formulaNowDateTimeParamPlaceholder,
131
+ todayDateParamPlaceholder: todayDateParamPlaceholder,
132
+ tomorrowDateParamPlaceholder: tomorrowDateParamPlaceholder,
133
+ yesterdayDateParamPlaceholder: yesterdayDateParamPlaceholder,
134
+ weekAgoDateParamPlaceholder: weekAgoDateParamPlaceholder,
135
+ weekFromNowDateParamPlaceholder: weekFromNowDateParamPlaceholder,
136
+ monthAgoDateParamPlaceholder: monthAgoDateParamPlaceholder,
137
+ monthFromNowDateParamPlaceholder: monthFromNowDateParamPlaceholder,
138
+ yearAgoDateParamPlaceholder: yearAgoDateParamPlaceholder,
139
+ yearFromNowDateParamPlaceholder: yearFromNowDateParamPlaceholder,
140
+ todayStartDateTimeParamPlaceholder: todayStartDateTimeParamPlaceholder,
141
+ todayEndDateTimeParamPlaceholder: todayEndDateTimeParamPlaceholder,
142
+ tomorrowStartDateTimeParamPlaceholder: tomorrowStartDateTimeParamPlaceholder,
143
+ tomorrowEndDateTimeParamPlaceholder: tomorrowEndDateTimeParamPlaceholder,
144
+ yesterdayStartDateTimeParamPlaceholder: yesterdayStartDateTimeParamPlaceholder,
145
+ yesterdayEndDateTimeParamPlaceholder: yesterdayEndDateTimeParamPlaceholder,
146
+ weekAgoStartDateTimeParamPlaceholder: weekAgoStartDateTimeParamPlaceholder,
147
+ weekAgoEndDateTimeParamPlaceholder: weekAgoEndDateTimeParamPlaceholder,
148
+ weekFromNowStartDateTimeParamPlaceholder: weekFromNowStartDateTimeParamPlaceholder,
149
+ weekFromNowEndDateTimeParamPlaceholder: weekFromNowEndDateTimeParamPlaceholder,
150
+ monthAgoStartDateTimeParamPlaceholder: monthAgoStartDateTimeParamPlaceholder,
151
+ monthAgoEndDateTimeParamPlaceholder: monthAgoEndDateTimeParamPlaceholder,
152
+ monthFromNowStartDateTimeParamPlaceholder: monthFromNowStartDateTimeParamPlaceholder,
153
+ monthFromNowEndDateTimeParamPlaceholder: monthFromNowEndDateTimeParamPlaceholder,
154
+ yearAgoStartDateTimeParamPlaceholder: yearAgoStartDateTimeParamPlaceholder,
155
+ yearAgoEndDateTimeParamPlaceholder: yearAgoEndDateTimeParamPlaceholder,
156
+ yearFromNowStartDateTimeParamPlaceholder: yearFromNowStartDateTimeParamPlaceholder,
157
+ yearFromNowEndDateTimeParamPlaceholder: yearFromNowEndDateTimeParamPlaceholder,
158
+ paramsPlaceholdersLookup: paramsPlaceholdersLookup,
159
+ replacePlaceholdersInParams: replacePlaceholdersInParams,
160
+ dateToDateTimeIntervalLookup: dateToDateTimeIntervalLookup
161
+ };
162
+
163
+ function _extends() {
164
+ _extends = Object.assign || function (target) {
165
+ for (var i = 1; i < arguments.length; i++) {
166
+ var source = arguments[i];
167
+
168
+ for (var key in source) {
169
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
170
+ target[key] = source[key];
171
+ }
172
+ }
173
+ }
174
+
175
+ return target;
176
+ };
177
+
178
+ return _extends.apply(this, arguments);
179
+ }
180
+
181
+ const formatWithCustomInspectParams = function (args) {
182
+ const transformedArgs = args.map(value => {
183
+ if (typeof value === "object") {
184
+ return {
185
+ [util__default["default"].inspect.custom || "inspect"](recurseTimes, ctx) {
186
+ return util__default["default"].inspect(value, _extends({}, ctx, {
187
+ showHidden: false,
188
+ depth: null,
189
+ maxArrayLength: null
190
+ }));
191
+ }
192
+
193
+ };
194
+ } else if (typeof value === "string") {
195
+ return {
196
+ [util__default["default"].inspect.custom || "inspect"](recurseTimes, ctx) {
197
+ return value;
198
+ }
199
+
200
+ };
201
+ } else {
202
+ return value;
203
+ }
204
+ });
205
+ return util__default["default"].format(...transformedArgs);
206
+ };
207
+ function assert(condition, ...args) {
208
+ if (!condition) {
209
+ const message = args.length > 0 ? formatWithCustomInspectParams(args) : `Assertion failed with no details`;
210
+ throw new Error(message);
211
+ }
212
+ }
213
+
214
+ [console.error.bind(console)];
215
+
216
+ const stringify = x => {
217
+ if (x === undefined) {
218
+ return "undefined";
219
+ }
220
+
221
+ return JSON.stringify(x);
222
+ };
223
+
224
+ class NotImplementedError extends Error {
225
+ constructor(value, itemType = undefined) {
226
+ super([`"${stringify(value)}"`, itemType, "is not implemented"].filter(x => x !== undefined).join(" "));
227
+ }
228
+
229
+ }
230
+
231
+ const assertIsValidExpression = expression => {
232
+ assert(Array.isArray(expression), "expression must be array", {
233
+ expression
234
+ });
235
+ assert(expression.length > 0, "empty expression does not make any sense");
236
+ };
237
+ const dateRangeFunctions = new Set(["q/start", "q/end"]);
238
+ const firstLastFunctions = new Set(["q/first", "q/last"]);
239
+ 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]
240
+ // [=, $true, $false]
241
+ // [=, $my-id, ["fibery/id"]]
242
+
243
+ const binaryOperations = new Set(["=", "!=", "<", ">", "<=", ">=", "in", //asc: obsolete,use q/in
244
+ "q/contains", "q/not-contains", "+", "-", "*", "/", "and", "or", //asc: obsolete. use q/and, q/or
245
+ "q/and", "q/or", "q/in", "q/not-in"]); // TODO: get rid of this. Use visitors everywhere
246
+
247
+ const naryOperations = new Set(["and", "or", "q/and", "q/or"]);
248
+ const logicalOperators = new Set(["and", "or", "q/and", "q/or"]);
249
+ const relationalOperators = new Set(["=", "!=", "<", ">", "<=", ">="]);
250
+ const mathOperators = new Set(["+", "-", "*", "/", "q/+", "q/-", "q/concat"]);
251
+ const isFunctionCallExpression = expression => expression.length > 1 && ___default["default"].isString(expression[0]) && (expression[0].startsWith("q/") || ["=", "!=", "<", ">", "<=", ">=", "+", "-", "*", "/", "in", "and", "or", "not-in"].includes(expression[0]));
252
+ const isDateRangeFunctionExpression = expression => expression.length === 2 && dateRangeFunctions.has(expression[0]) && isFieldExpression(expression[1]);
253
+ const isCollectionFunctionExpression = expression => //expression has length 3 in case of q/join
254
+ (expression.length === 2 || expression.length === 3) && collectionOps.has(expression[0]) && isFieldExpression(expression[1]);
255
+ const isAccessFunctionExpression = expresion => expresion.length === 2 && expresion[0] === "q/access?" && isFieldExpression(expresion[1]);
256
+ const isBinaryExpression = expression => expression.length === 3 && binaryOperations.has(expression[0]);
257
+ const isNaryExpression = expression => expression.length > 1 && naryOperations.has(expression[0]);
258
+ const isVariableExpression = expression => ___default["default"].isString(expression) && expression.startsWith("$");
259
+ const isFieldExpression = expression => Array.isArray(expression) && expression.every(x => !isVariableExpression(x) && !binaryOperations.has(x) && ___default["default"].isString(x));
260
+ const isAxisFieldExpression = expression => isFieldExpression(expression) && expression.length === 1;
261
+ const isQueryExpression = expression => {
262
+ if (___default["default"].isObject(expression) && "q/from" in expression) {
263
+ const fromExpression = expression["q/from"]; //asc: fromExpression === null for denormalizeSelect for reference collection case
264
+
265
+ return fromExpression === null || isFieldExpression(fromExpression);
266
+ }
267
+
268
+ return false;
269
+ }; // [q/count, [..., collection]]
270
+ // [q/start, [..., range]]
271
+ // [q/end, [..., range]]
272
+ // [q/access?, [..., field-expr]]
273
+
274
+ const isFunctionExpression = expression => {
275
+ if (!Array.isArray(expression)) {
276
+ return false;
277
+ }
278
+
279
+ if (isFieldExpression(expression)) {
280
+ return false;
281
+ } else if (isDateRangeFunctionExpression(expression) || isCollectionFunctionExpression(expression) || isAccessFunctionExpression(expression)) {
282
+ return true;
283
+ }
284
+
285
+ throw new Error("invalid expression:" + JSON.stringify(expression));
286
+ };
287
+
288
+ const collectFieldExpressions = (memo, expression) => {
289
+ if (isVariableExpression(expression)) ; else if (isBinaryExpression(expression) || isNaryExpression(expression)) {
290
+ for (const part of expression.slice(1)) {
291
+ if (isVariableExpression(part) || part === null) ; else {
292
+ if (___default["default"].isString(part)) {
293
+ // field path shortcut
294
+ memo.push([part]);
295
+ } else {
296
+ collectFieldExpressions(memo, part);
297
+ }
298
+ }
299
+ }
300
+ } else if (isFieldExpression(expression)) {
301
+ memo.push(expression);
302
+ } else if (isDateRangeFunctionExpression(expression) || isCollectionFunctionExpression(expression)) {
303
+ collectFieldExpressions(memo, expression[1]);
304
+ } else if (expression["q/from"] && isFieldExpression(expression["q/from"])) {
305
+ const innerMemo = [];
306
+ expression["q/select"] && collectFieldExpressions(innerMemo, expression["q/select"]);
307
+ expression["q/where"] && collectFieldExpressions(innerMemo, expression["q/where"]);
308
+
309
+ for (const fieldExpression of innerMemo) {
310
+ memo.push([...expression["q/from"], ...fieldExpression]);
311
+ }
312
+ } else {
313
+ throw new NotImplementedError(expression, "expression");
314
+ }
315
+ };
316
+
317
+ const extractFieldExpressions = expression => {
318
+ const memo = [];
319
+ collectFieldExpressions(memo, expression);
320
+ return ___default["default"].uniqBy(memo, x => x.join(","));
321
+ };
322
+ const createExpressionVisitor = visitor => {
323
+ let visitorWithDefault = null;
324
+ const visitorDefault = {
325
+ visitVariableExpression: expression => expression,
326
+ visitFunctionCallExpression: ([fnName, ...args]) => [fnName, ...args.map(x => visitorWithDefault.visitExpression(x))],
327
+ visitFieldExpression: expression => expression,
328
+ visitOrderByExpression: orderByExpression => orderByExpression.map(x => {
329
+ const [fieldExpression, orderDir] = x;
330
+ const fieldExpressionNew = visitorWithDefault.visitExpression(fieldExpression);
331
+ return [fieldExpressionNew, orderDir];
332
+ }),
333
+ visitQueryExpression: subQueryExpression => {
334
+ const {
335
+ "q/from": fromExpression,
336
+ "q/select": selectExpression,
337
+ "q/where": whereExpression,
338
+ "q/order-by": orderByExpression
339
+ } = subQueryExpression;
340
+ return _extends({}, subQueryExpression, fromExpression ? {
341
+ "q/from": visitorWithDefault.visitFieldExpression(fromExpression)
342
+ } : null, selectExpression ? {
343
+ "q/select": ___default["default"].isPlainObject(selectExpression) ? ___default["default"].mapValues(selectExpression, val => visitorWithDefault.visitExpression(val)) : visitorWithDefault.visitExpression(selectExpression)
344
+ } : null, whereExpression ? {
345
+ "q/where": visitorWithDefault.visitExpression(whereExpression)
346
+ } : null, orderByExpression ? {
347
+ "q/order-by": visitorWithDefault.visitOrderByExpression(orderByExpression)
348
+ } : null);
349
+ },
350
+ visitExpression: expression => {
351
+ if (expression === null) {
352
+ throw new NotImplementedError(expression, "expression");
353
+ } else if (isVariableExpression(expression)) {
354
+ return visitorWithDefault.visitVariableExpression(expression, visitorDefault);
355
+ } else if (isFunctionCallExpression(expression)) {
356
+ return visitorWithDefault.visitFunctionCallExpression(expression, visitorDefault);
357
+ } else if (isFieldExpression(expression)) {
358
+ return visitorWithDefault.visitFieldExpression(expression, visitorDefault);
359
+ } else if (isQueryExpression(expression)) {
360
+ return visitorWithDefault.visitQueryExpression(expression, visitorDefault);
361
+ } else {
362
+ throw new NotImplementedError(expression, "expression");
363
+ }
364
+ }
365
+ };
366
+ visitorWithDefault = _extends({}, visitorDefault, visitor);
367
+ return visitorWithDefault;
368
+ };
369
+
370
+ var utils = {
371
+ __proto__: null,
372
+ assertIsValidExpression: assertIsValidExpression,
373
+ dateRangeFunctions: dateRangeFunctions,
374
+ firstLastFunctions: firstLastFunctions,
375
+ logicalOperators: logicalOperators,
376
+ relationalOperators: relationalOperators,
377
+ mathOperators: mathOperators,
378
+ isFunctionCallExpression: isFunctionCallExpression,
379
+ isDateRangeFunctionExpression: isDateRangeFunctionExpression,
380
+ isCollectionFunctionExpression: isCollectionFunctionExpression,
381
+ isAccessFunctionExpression: isAccessFunctionExpression,
382
+ isBinaryExpression: isBinaryExpression,
383
+ isNaryExpression: isNaryExpression,
384
+ isVariableExpression: isVariableExpression,
385
+ isFieldExpression: isFieldExpression,
386
+ isAxisFieldExpression: isAxisFieldExpression,
387
+ isQueryExpression: isQueryExpression,
388
+ isFunctionExpression: isFunctionExpression,
389
+ extractFieldExpressions: extractFieldExpressions,
390
+ createExpressionVisitor: createExpressionVisitor
391
+ };
392
+
393
+ const defaultIdsWithNamesOnFieldNotFound = ({
394
+ fieldExpressionInNamesTerms,
395
+ fieldId
396
+ }) => {
397
+ return {
398
+ currentTypeObject: null,
399
+ fieldExpressionInNamesTerms: [...fieldExpressionInNamesTerms, fieldId]
400
+ };
401
+ };
402
+
403
+ const visitFieldExpressionForReplaceIdsWithNamesVisitor = ({
404
+ expression,
405
+ typeObject,
406
+ onFieldNotFound
407
+ }) => expression.reduce(({
408
+ currentTypeObject,
409
+ fieldExpressionInNamesTerms
410
+ }, fieldId) => {
411
+ if (currentTypeObject && currentTypeObject.fieldObjectsById.hasOwnProperty(fieldId)) {
412
+ const fieldObject = currentTypeObject.fieldObjectsById[fieldId];
413
+ return {
414
+ currentTypeObject: fieldObject.typeObject,
415
+ fieldExpressionInNamesTerms: [...fieldExpressionInNamesTerms, fieldObject.name]
416
+ };
417
+ } else {
418
+ return onFieldNotFound({
419
+ currentTypeObject,
420
+ fieldExpressionInNamesTerms,
421
+ fieldId,
422
+ expression
423
+ });
424
+ }
425
+ }, {
426
+ currentTypeObject: typeObject,
427
+ fieldExpressionInNamesTerms: []
428
+ });
429
+
430
+ const replaceIdsWithNamesVisitor = (typeObject, onFieldNotFound = defaultIdsWithNamesOnFieldNotFound) => {
431
+ const visitor = createExpressionVisitor({
432
+ visitFieldExpression: expression => visitFieldExpressionForReplaceIdsWithNamesVisitor({
433
+ expression,
434
+ typeObject,
435
+ onFieldNotFound
436
+ }).fieldExpressionInNamesTerms,
437
+ visitQueryExpression: subQueryExpression => {
438
+ const {
439
+ "q/from": fromExpression,
440
+ "q/select": selectExpression,
441
+ "q/where": whereExpression,
442
+ "q/order-by": orderByExpression
443
+ } = subQueryExpression;
444
+ const subQueryTypeObject = visitFieldExpressionForReplaceIdsWithNamesVisitor({
445
+ expression: fromExpression,
446
+ onFieldNotFound,
447
+ typeObject
448
+ }).currentTypeObject;
449
+
450
+ if (subQueryTypeObject) {
451
+ const subQueryVisitor = replaceIdsWithNamesVisitor(subQueryTypeObject, onFieldNotFound);
452
+ return _extends({}, subQueryExpression, {
453
+ "q/from": visitor.visitFieldExpression(fromExpression),
454
+ "q/select": ___default["default"].isPlainObject(selectExpression) ? ___default["default"].mapValues(selectExpression, val => subQueryVisitor.visitExpression(val)) : subQueryVisitor.visitExpression(selectExpression)
455
+ }, whereExpression ? {
456
+ "q/where": subQueryVisitor.visitExpression(whereExpression)
457
+ } : null, orderByExpression ? {
458
+ "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
459
+ } : null);
460
+ }
461
+
462
+ return subQueryExpression;
463
+ }
464
+ });
465
+ return visitor;
466
+ };
467
+
468
+ const defaultNamesWithIdsOnFieldNotFound = ({
469
+ fieldExpressionInIdsTerms,
470
+ field
471
+ }) => {
472
+ return {
473
+ currentTypeObject: null,
474
+ fieldExpressionInIdsTerms: [...fieldExpressionInIdsTerms, field]
475
+ };
476
+ };
477
+
478
+ const visitFieldExpressionForReplaceNamesWithIdsVisitor = ({
479
+ expression,
480
+ onFieldNotFound,
481
+ typeObject
482
+ }) => expression.reduce(({
483
+ currentTypeObject,
484
+ fieldExpressionInIdsTerms
485
+ }, field) => {
486
+ if (currentTypeObject && currentTypeObject.fieldObjectsByName.hasOwnProperty(field)) {
487
+ const fieldObject = currentTypeObject.fieldObjectsByName[field];
488
+ return {
489
+ currentTypeObject: fieldObject.typeObject,
490
+ fieldExpressionInIdsTerms: [...fieldExpressionInIdsTerms, fieldObject.id]
491
+ };
492
+ } else {
493
+ return onFieldNotFound({
494
+ currentTypeObject,
495
+ fieldExpressionInIdsTerms,
496
+ field,
497
+ expression
498
+ });
499
+ }
500
+ }, {
501
+ currentTypeObject: typeObject,
502
+ fieldExpressionInIdsTerms: []
503
+ });
504
+
505
+ const replaceNamesWithIdsVisitor = (typeObject, onFieldNotFound = defaultNamesWithIdsOnFieldNotFound) => {
506
+ const visitor = createExpressionVisitor({
507
+ visitFieldExpression: expression => visitFieldExpressionForReplaceNamesWithIdsVisitor({
508
+ expression,
509
+ onFieldNotFound,
510
+ typeObject
511
+ }).fieldExpressionInIdsTerms,
512
+ visitQueryExpression: subQueryExpression => {
513
+ const {
514
+ "q/from": fromExpression,
515
+ "q/select": selectExpression,
516
+ "q/where": whereExpression,
517
+ "q/order-by": orderByExpression
518
+ } = subQueryExpression;
519
+ const subQueryTypeObject = visitFieldExpressionForReplaceNamesWithIdsVisitor({
520
+ expression: fromExpression,
521
+ onFieldNotFound,
522
+ typeObject
523
+ }).currentTypeObject;
524
+
525
+ if (subQueryTypeObject) {
526
+ const subQueryVisitor = replaceNamesWithIdsVisitor(subQueryTypeObject);
527
+ return _extends({}, subQueryExpression, {
528
+ "q/from": visitor.visitFieldExpression(fromExpression),
529
+ "q/select": ___default["default"].isPlainObject(selectExpression) ? ___default["default"].mapValues(selectExpression, val => subQueryVisitor.visitExpression(val)) : subQueryVisitor.visitExpression(selectExpression)
530
+ }, whereExpression ? {
531
+ "q/where": subQueryVisitor.visitExpression(whereExpression)
532
+ } : null, orderByExpression ? {
533
+ "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
534
+ } : null);
535
+ }
536
+
537
+ return subQueryExpression;
538
+ }
539
+ });
540
+ return visitor;
541
+ };
542
+ const deleteExpressionsWithNotFoundFieldsVisitor = typeObject => {
543
+ const visitor = createExpressionVisitor({
544
+ visitFunctionCallExpression: ([fnName, ...args]) => {
545
+ const argsNew = args.map(x => visitor.visitExpression(x)).filter(Boolean);
546
+
547
+ if (logicalOperators.has(fnName)) {
548
+ if (argsNew.length > 0) {
549
+ return argsNew.length === 1 ? argsNew[0] : [fnName, ...argsNew];
550
+ }
551
+
552
+ return null;
553
+ } else {
554
+ return argsNew.length === args.length ? [fnName, ...argsNew] : null;
555
+ }
556
+ },
557
+ visitFieldExpression: expression => {
558
+ const fieldTypeObject = expression.reduce((holderTypeObject, field) => holderTypeObject && holderTypeObject.fieldObjectsByName.hasOwnProperty(field) ? holderTypeObject.fieldObjectsByName[field].typeObject : null, typeObject);
559
+ return fieldTypeObject && expression;
560
+ },
561
+ visitOrderByExpression: orderByExpression => {
562
+ const orderByExpressionNew = orderByExpression.map(x => {
563
+ const [fieldExpression, orderDir] = x;
564
+ const fieldExpressionNew = visitor.visitExpression(fieldExpression);
565
+ return fieldExpressionNew && [fieldExpressionNew, orderDir];
566
+ }).filter(Boolean);
567
+ return orderByExpressionNew.length > 0 && orderByExpressionNew;
568
+ },
569
+ visitQueryExpression: subQueryExpression => {
570
+ const {
571
+ "q/from": fromExpression,
572
+ "q/select": selectExpression,
573
+ "q/where": whereExpression,
574
+ "q/order-by": orderByExpression
575
+ } = subQueryExpression;
576
+ const subQueryTypeObject = fromExpression.reduce((typeObject, field) => typeObject && typeObject.fieldObjectsByName.hasOwnProperty(field) ? typeObject.fieldObjectsByName[field].typeObject : null, typeObject);
577
+
578
+ if (subQueryTypeObject) {
579
+ const subQueryVisitor = deleteExpressionsWithNotFoundFieldsVisitor(subQueryTypeObject);
580
+
581
+ const subQueryExpressionNew = ___default["default"].pickBy(_extends({}, subQueryExpression, {
582
+ "q/from": visitor.visitFieldExpression(fromExpression),
583
+ "q/select": subQueryVisitor.visitExpression(selectExpression)
584
+ }, whereExpression ? {
585
+ "q/where": subQueryVisitor.visitExpression(whereExpression)
586
+ } : null, orderByExpression ? {
587
+ "q/order-by": subQueryVisitor.visitOrderByExpression(orderByExpression)
588
+ } : null));
589
+
590
+ const {
591
+ "q/select": selectExpressionNew
592
+ } = subQueryExpressionNew;
593
+ return selectExpressionNew ? subQueryExpressionNew : null;
594
+ } else {
595
+ return null;
596
+ }
597
+ }
598
+ });
599
+ return visitor;
600
+ };
601
+ const expressionContainsAggregation = expression => {
602
+ let result = false;
603
+ const visitor = createExpressionVisitor({
604
+ visitQueryExpression: queryExpression => {
605
+ const {
606
+ "q/select": selectExpression
607
+ } = queryExpression;
608
+
609
+ if (isCollectionFunctionExpression(selectExpression)) {
610
+ result = true;
611
+ }
612
+ }
613
+ });
614
+ visitor.visitExpression(expression);
615
+ return result;
616
+ };
617
+
618
+ const defaultGetExpressionTypeOnFieldNotFound = () => {
619
+ return {
620
+ currentTypeObject: null
621
+ };
622
+ };
623
+
624
+ const getFieldAccessExpressionTypeObject = ({
625
+ expression,
626
+ typeObject,
627
+ onFieldNotFound,
628
+ returnRefTypeInsteadOfId
629
+ }) => {
630
+ const reduced = expression.reduce(({
631
+ currentTypeObject
632
+ }, fieldId, index) => {
633
+ const fieldObject = currentTypeObject && currentTypeObject.fieldObjects.find(f => f.id === fieldId);
634
+
635
+ if (fieldObject) {
636
+ if (returnRefTypeInsteadOfId && index === expression.length - 1 && fieldObject.isId) {
637
+ return {
638
+ currentTypeObject
639
+ };
640
+ }
641
+
642
+ return {
643
+ currentTypeObject: fieldObject.typeObject
644
+ };
645
+ } else {
646
+ return onFieldNotFound({
647
+ currentTypeObject,
648
+ fieldId
649
+ });
650
+ }
651
+ }, {
652
+ currentTypeObject: typeObject
653
+ });
654
+ return reduced.currentTypeObject;
655
+ };
656
+
657
+ const UNKNOWN_EXPRESSION_TYPE = "unknown";
658
+
659
+ const getExpressionTypeInternal = ({
660
+ expression,
661
+ typeObject,
662
+ functionsMeta,
663
+ onFieldNotFound,
664
+ returnRefTypeInsteadOfId
665
+ }) => {
666
+ let result = null;
667
+ const visitor = createExpressionVisitor({
668
+ visitVariableExpression: function () {
669
+ result = UNKNOWN_EXPRESSION_TYPE;
670
+ },
671
+ visitFunctionCallExpression: function ([fnName, ...args]) {
672
+ const fnMeta = functionsMeta[fnName];
673
+
674
+ if (!fnMeta) {
675
+ throw new Error(`Function meta for "${fnName}" was not provided`);
676
+ }
677
+
678
+ const argTypes = args.map(arg => getExpressionTypeInternal({
679
+ expression: arg,
680
+ typeObject,
681
+ functionsMeta,
682
+ onFieldNotFound,
683
+ returnRefTypeInsteadOfId: false
684
+ }));
685
+ const overload = fnMeta.overloads.find(o => o["arg-types"].every((argType, index) => argTypes[index] === UNKNOWN_EXPRESSION_TYPE || argTypes[index] === argType));
686
+
687
+ if (!overload) {
688
+ throw new Error(`No overload with args ${argTypes.join(",")} found for "${fnName}" in meta`);
689
+ }
690
+
691
+ result = overload["result-type"];
692
+ },
693
+ visitQueryExpression: expression => {
694
+ const {
695
+ "q/from": fromExpression,
696
+ "q/select": selectExpression
697
+ } = expression;
698
+ const fromTypeObject = getFieldAccessExpressionTypeObject({
699
+ expression: fromExpression,
700
+ typeObject,
701
+ onFieldNotFound,
702
+ returnRefTypeInsteadOfId
703
+ });
704
+
705
+ if (!fromTypeObject) {
706
+ result = null;
707
+ }
708
+
709
+ if (___default["default"].isPlainObject(selectExpression)) {
710
+ if (Object.values(selectExpression).length !== 1) {
711
+ throw new Error(`Cannot determine type of query expression ${JSON.stringify(expression)}`);
712
+ }
713
+
714
+ result = getExpressionTypeInternal({
715
+ expression: Object.values(selectExpression)[0],
716
+ typeObject: fromTypeObject,
717
+ functionsMeta,
718
+ onFieldNotFound,
719
+ returnRefTypeInsteadOfId
720
+ });
721
+ } else {
722
+ result = getExpressionTypeInternal({
723
+ expression: selectExpression,
724
+ typeObject: fromTypeObject,
725
+ functionsMeta,
726
+ onFieldNotFound,
727
+ returnRefTypeInsteadOfId
728
+ });
729
+ }
730
+ },
731
+
732
+ visitFieldExpression(expression) {
733
+ const fieldAccessExpressionTypeObject = getFieldAccessExpressionTypeObject({
734
+ expression,
735
+ typeObject,
736
+ onFieldNotFound,
737
+ returnRefTypeInsteadOfId
738
+ });
739
+ result = fieldAccessExpressionTypeObject && fieldAccessExpressionTypeObject.name;
740
+ }
741
+
742
+ });
743
+ visitor.visitExpression(expression);
744
+ return result;
745
+ };
746
+
747
+ const getExpressionType = ({
748
+ expression,
749
+ typeObject,
750
+ functionsMeta,
751
+ onFieldNotFound = defaultGetExpressionTypeOnFieldNotFound,
752
+ returnRefTypeInsteadOfId = true
753
+ }) => {
754
+ return getExpressionTypeInternal({
755
+ expression,
756
+ typeObject,
757
+ functionsMeta,
758
+ onFieldNotFound,
759
+ returnRefTypeInsteadOfId
760
+ });
761
+ };
762
+
763
+ var visitors = {
764
+ __proto__: null,
765
+ replaceIdsWithNamesVisitor: replaceIdsWithNamesVisitor,
766
+ replaceNamesWithIdsVisitor: replaceNamesWithIdsVisitor,
767
+ deleteExpressionsWithNotFoundFieldsVisitor: deleteExpressionsWithNotFoundFieldsVisitor,
768
+ expressionContainsAggregation: expressionContainsAggregation,
769
+ UNKNOWN_EXPRESSION_TYPE: UNKNOWN_EXPRESSION_TYPE,
770
+ getExpressionType: getExpressionType
771
+ };
772
+
773
+ const getEntityQueryVariables = schema => {
774
+ const grouped = ___default["default"].groupBy(schema.typeObjects.filter(x => x.isDomain), typeObject => typeObject.pluralTitle);
775
+
776
+ return ___default["default"].flatten(Object.values(grouped).map(group => {
777
+ return group.map(typeObject => ({
778
+ typeObject,
779
+ id: `entityQuery_${typeObject.id}`,
780
+ title: group.length > 1 ? `${typeObject.pluralTitle} (${typeObject.nameParts.namespace})` : typeObject.pluralTitle,
781
+ isCollection: true
782
+ }));
783
+ }));
784
+ };
785
+
786
+ var contextVariables = {
787
+ __proto__: null,
788
+ getEntityQueryVariables: getEntityQueryVariables
789
+ };
790
+
791
+ exports.contextVariables = contextVariables;
792
+ exports.paramsPlaceholders = paramsPlaceholders;
793
+ exports.utils = utils;
794
+ exports.visitors = visitors;