@cap-js/process 0.0.0 → 0.1.1

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 (76) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +635 -0
  3. package/cds-plugin.js +2 -0
  4. package/dist/cds-plugin.js +4 -0
  5. package/dist/cds-plugin.js.map +1 -0
  6. package/dist/lib/api/index.js +23 -0
  7. package/dist/lib/api/index.js.map +1 -0
  8. package/dist/lib/api/local-workflow-store.js +85 -0
  9. package/dist/lib/api/local-workflow-store.js.map +1 -0
  10. package/dist/lib/api/process-api-client.js +103 -0
  11. package/dist/lib/api/process-api-client.js.map +1 -0
  12. package/dist/lib/api/workflow-client.js +174 -0
  13. package/dist/lib/api/workflow-client.js.map +1 -0
  14. package/dist/lib/auth/credentials.js +17 -0
  15. package/dist/lib/auth/credentials.js.map +1 -0
  16. package/dist/lib/auth/index.js +11 -0
  17. package/dist/lib/auth/index.js.map +1 -0
  18. package/dist/lib/auth/token-cache.js +67 -0
  19. package/dist/lib/auth/token-cache.js.map +1 -0
  20. package/dist/lib/auth/token-provider.js +32 -0
  21. package/dist/lib/auth/token-provider.js.map +1 -0
  22. package/dist/lib/build/constants.js +106 -0
  23. package/dist/lib/build/constants.js.map +1 -0
  24. package/dist/lib/build/index.js +22 -0
  25. package/dist/lib/build/index.js.map +1 -0
  26. package/dist/lib/build/plugin.js +126 -0
  27. package/dist/lib/build/plugin.js.map +1 -0
  28. package/dist/lib/build/validation-utils.js +309 -0
  29. package/dist/lib/build/validation-utils.js.map +1 -0
  30. package/dist/lib/build/validations.js +185 -0
  31. package/dist/lib/build/validations.js.map +1 -0
  32. package/dist/lib/constants.js +78 -0
  33. package/dist/lib/constants.js.map +1 -0
  34. package/dist/lib/handlers/annotationCache.js +47 -0
  35. package/dist/lib/handlers/annotationCache.js.map +1 -0
  36. package/dist/lib/handlers/annotationHandlers.js +57 -0
  37. package/dist/lib/handlers/annotationHandlers.js.map +1 -0
  38. package/dist/lib/handlers/index.js +26 -0
  39. package/dist/lib/handlers/index.js.map +1 -0
  40. package/dist/lib/handlers/onDeleteUtils.js +63 -0
  41. package/dist/lib/handlers/onDeleteUtils.js.map +1 -0
  42. package/dist/lib/handlers/processActionHandler.js +55 -0
  43. package/dist/lib/handlers/processActionHandler.js.map +1 -0
  44. package/dist/lib/handlers/processCancel.js +28 -0
  45. package/dist/lib/handlers/processCancel.js.map +1 -0
  46. package/dist/lib/handlers/processResume.js +28 -0
  47. package/dist/lib/handlers/processResume.js.map +1 -0
  48. package/dist/lib/handlers/processService.js +125 -0
  49. package/dist/lib/handlers/processService.js.map +1 -0
  50. package/dist/lib/handlers/processStart.js +156 -0
  51. package/dist/lib/handlers/processStart.js.map +1 -0
  52. package/dist/lib/handlers/processSuspend.js +28 -0
  53. package/dist/lib/handlers/processSuspend.js.map +1 -0
  54. package/dist/lib/handlers/utils.js +124 -0
  55. package/dist/lib/handlers/utils.js.map +1 -0
  56. package/dist/lib/index.js +43 -0
  57. package/dist/lib/index.js.map +1 -0
  58. package/dist/lib/processImport.js +449 -0
  59. package/dist/lib/processImport.js.map +1 -0
  60. package/dist/lib/processImportRegistration.js +27 -0
  61. package/dist/lib/processImportRegistration.js.map +1 -0
  62. package/dist/lib/shared/businessKey-helper.js +27 -0
  63. package/dist/lib/shared/businessKey-helper.js.map +1 -0
  64. package/dist/lib/shared/input-parser.js +650 -0
  65. package/dist/lib/shared/input-parser.js.map +1 -0
  66. package/dist/lib/types/csn-extensions.js +37 -0
  67. package/dist/lib/types/csn-extensions.js.map +1 -0
  68. package/dist/srv/BTPProcessService.js +117 -0
  69. package/dist/srv/BTPProcessService.js.map +1 -0
  70. package/dist/srv/localProcessService.js +152 -0
  71. package/dist/srv/localProcessService.js.map +1 -0
  72. package/package.json +98 -1
  73. package/srv/BTPProcessService.cds +42 -0
  74. package/srv/BTPProcessService.js +2 -0
  75. package/srv/localProcessService.cds +3 -0
  76. package/srv/localProcessService.js +2 -0
@@ -0,0 +1,650 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WILDCARD = void 0;
4
+ exports.isAliasInput = isAliasInput;
5
+ exports.isSimpleInput = isSimpleInput;
6
+ exports.parsePath = parsePath;
7
+ exports.parseInputsArray = parseInputsArray;
8
+ exports.buildInputTree = buildInputTree;
9
+ /**
10
+ * Type guard for alias input entries
11
+ */
12
+ function isAliasInput(entry) {
13
+ return 'path' in entry && 'as' in entry;
14
+ }
15
+ /**
16
+ * Type guard for simple input entries
17
+ */
18
+ function isSimpleInput(entry) {
19
+ return '=' in entry && !('path' in entry);
20
+ }
21
+ /**
22
+ * Special marker for selecting all scalar fields
23
+ */
24
+ exports.WILDCARD = '*';
25
+ /**
26
+ * Parses a path string like "$self.items.title" into ["items", "title"]
27
+ * Strips the "$self." prefix and splits by "."
28
+ *
29
+ * Special case: "$self" alone returns ['*'] to indicate all scalar fields
30
+ */
31
+ function parsePath(pathString) {
32
+ // Handle $self alone - means all scalar fields
33
+ if (pathString === '$self') {
34
+ return [exports.WILDCARD];
35
+ }
36
+ return pathString.replace(/^\$self\./, '').split('.');
37
+ }
38
+ /**
39
+ * Parses the inputs CSN array into parsed entries
40
+ *
41
+ * @param inputsCSN - Array of CSN input entries from the annotation
42
+ * @returns Array of parsed entries with path segments and optional alias
43
+ *
44
+ * @example
45
+ * // Input:
46
+ * [
47
+ * { '=': '$self' }, // Wildcard: all scalar fields
48
+ * { '=': '$self.ID' },
49
+ * { '=': '$self.items.title' },
50
+ * { path: { '=': '$self.price' }, as: 'Amount' }
51
+ * ]
52
+ *
53
+ * Output:
54
+ * [
55
+ * { path: ['*'], alias: undefined }, // Wildcard marker
56
+ * { path: ['ID'], alias: undefined },
57
+ * { path: ['items', 'title'], alias: undefined },
58
+ * { path: ['price'], alias: 'Amount' }
59
+ * ]
60
+ */
61
+ function parseInputsArray(inputsCSN) {
62
+ if (!inputsCSN || inputsCSN.length === 0) {
63
+ return [];
64
+ }
65
+ const parsedEntries = [];
66
+ for (const entry of inputsCSN) {
67
+ if (isAliasInput(entry)) {
68
+ parsedEntries.push({
69
+ path: parsePath(entry.path['=']),
70
+ alias: entry.as,
71
+ });
72
+ }
73
+ else if (isSimpleInput(entry)) {
74
+ parsedEntries.push({
75
+ path: parsePath(entry['=']),
76
+ alias: undefined,
77
+ });
78
+ }
79
+ }
80
+ return parsedEntries;
81
+ }
82
+ /**
83
+ * Classification of how an element group should be processed
84
+ */
85
+ var ElementKind;
86
+ (function (ElementKind) {
87
+ /** Simple scalar field */
88
+ ElementKind["SCALAR"] = "SCALAR";
89
+ /** Association/Composition to expand all fields */
90
+ ElementKind["ASSOC_EXPAND_ALL"] = "ASSOC_EXPAND_ALL";
91
+ /** Association/Composition with specific nested fields */
92
+ ElementKind["ASSOC_WITH_NESTED"] = "ASSOC_WITH_NESTED";
93
+ /** Multiple aliases on same element (no non-aliased entry) */
94
+ ElementKind["MULTI_ALIAS"] = "MULTI_ALIAS";
95
+ })(ElementKind || (ElementKind = {}));
96
+ /**
97
+ * Groups entries by their first path segment.
98
+ *
99
+ * This is the first step in preprocessing - it collects all entries that reference
100
+ * the same root element so they can be analyzed together.
101
+ *
102
+ * @example
103
+ * Input: entries from annotation like:
104
+ * inputs: [$self.ID, $self.title, $self.items, $self.items.quantity]
105
+ * const entries = [
106
+ * { path: ['ID'], alias: undefined },
107
+ * { path: ['title'], alias: undefined },
108
+ * { path: ['items'], alias: undefined },
109
+ * { path: ['items', 'quantity'], alias: undefined }
110
+ * ];
111
+ *
112
+ * Output: Map grouping by first segment
113
+ * Map {
114
+ * 'ID' => [{ path: ['ID'], alias: undefined }],
115
+ * 'title' => [{ path: ['title'], alias: undefined }],
116
+ * 'items' => [
117
+ * { path: ['items'], alias: undefined }, // direct reference
118
+ * { path: ['items', 'quantity'], alias: undefined } // nested reference
119
+ * ]
120
+ * }
121
+ *
122
+ * @example
123
+ * Multiple aliases on same element:
124
+ * inputs: [{ path: $self.ID, as: 'OrderId' }, { path: $self.ID, as: 'RefId' }]
125
+ * const entries = [
126
+ * { path: ['ID'], alias: 'OrderId' },
127
+ * { path: ['ID'], alias: 'RefId' }
128
+ * ];
129
+ *
130
+ * Output:
131
+ * Map {
132
+ * 'ID' => [
133
+ * { path: ['ID'], alias: 'OrderId' },
134
+ * { path: ['ID'], alias: 'RefId' }
135
+ * ]
136
+ * }
137
+ */
138
+ function groupEntriesByFirstSegment(entries) {
139
+ const groups = new Map();
140
+ for (const entry of entries) {
141
+ const firstSegment = entry.path[0];
142
+ if (!groups.has(firstSegment)) {
143
+ groups.set(firstSegment, []);
144
+ }
145
+ groups.get(firstSegment).push(entry);
146
+ }
147
+ return groups;
148
+ }
149
+ /**
150
+ * Analyzes a group of entries for the same element and categorizes them.
151
+ *
152
+ * Separates entries into:
153
+ * - directEntries: References to the element itself (path length = 1)
154
+ * - nonAliasedDirect: The first direct entry without an alias (used as primary)
155
+ * - aliasedDirect: Direct entries with aliases (may create additional nodes)
156
+ * - nestedEntries: References to nested fields (path length > 1), with first segment stripped
157
+ *
158
+ * @example
159
+ * Simple scalar field: [$self.ID]
160
+ * analyzeEntryGroup([{ path: ['ID'], alias: undefined }])
161
+ * Returns:
162
+ * {
163
+ * directEntries: [{ path: ['ID'], alias: undefined }],
164
+ * nonAliasedDirect: { path: ['ID'], alias: undefined },
165
+ * aliasedDirect: [],
166
+ * nestedEntries: []
167
+ * }
168
+ *
169
+ * @example
170
+ * Composition with nested fields: [$self.items, $self.items.quantity, $self.items.price]
171
+ * analyzeEntryGroup([
172
+ * { path: ['items'], alias: undefined },
173
+ * { path: ['items', 'quantity'], alias: undefined },
174
+ * { path: ['items', 'price'], alias: undefined }
175
+ * ])
176
+ * Returns:
177
+ * {
178
+ * directEntries: [{ path: ['items'], alias: undefined }],
179
+ * nonAliasedDirect: { path: ['items'], alias: undefined },
180
+ * aliasedDirect: [],
181
+ * nestedEntries: [
182
+ * { path: ['quantity'], alias: undefined }, // 'items' stripped
183
+ * { path: ['price'], alias: undefined } // 'items' stripped
184
+ * ]
185
+ * }
186
+ *
187
+ * @example
188
+ * Multiple aliases without non-aliased: [{ path: $self.ID, as: 'OrderId' }, { path: $self.ID, as: 'RefId' }]
189
+ * analyzeEntryGroup([
190
+ * { path: ['ID'], alias: 'OrderId' },
191
+ * { path: ['ID'], alias: 'RefId' }
192
+ * ])
193
+ * Returns:
194
+ * {
195
+ * directEntries: [{ path: ['ID'], alias: 'OrderId' }, { path: ['ID'], alias: 'RefId' }],
196
+ * nonAliasedDirect: undefined, // No non-aliased entry!
197
+ * aliasedDirect: [{ path: ['ID'], alias: 'OrderId' }, { path: ['ID'], alias: 'RefId' }],
198
+ * nestedEntries: []
199
+ * }
200
+ *
201
+ * @example
202
+ * Both aliased and non-aliased: [$self.ID, { path: $self.ID, as: 'EntityId' }]
203
+ * analyzeEntryGroup([
204
+ * { path: ['ID'], alias: undefined },
205
+ * { path: ['ID'], alias: 'EntityId' }
206
+ * ])
207
+ * Returns:
208
+ * {
209
+ * directEntries: [{ path: ['ID'], alias: undefined }, { path: ['ID'], alias: 'EntityId' }],
210
+ * nonAliasedDirect: { path: ['ID'], alias: undefined },
211
+ * aliasedDirect: [{ path: ['ID'], alias: 'EntityId' }],
212
+ * nestedEntries: []
213
+ * }
214
+ */
215
+ function analyzeEntryGroup(group) {
216
+ const directEntries = group.filter((e) => e.path.length === 1);
217
+ const nonAliasedDirect = directEntries.find((e) => !e.alias);
218
+ const aliasedDirect = directEntries.filter((e) => e.alias);
219
+ const nestedEntries = group
220
+ .filter((e) => e.path.length > 1)
221
+ .map((e) => ({ path: e.path.slice(1), alias: e.alias }));
222
+ return { directEntries, nonAliasedDirect, aliasedDirect, nestedEntries };
223
+ }
224
+ /**
225
+ * Classifies an element and determines how it should be processed.
226
+ *
227
+ * This determines which state machine handler will process the element:
228
+ * - SCALAR: Simple field → creates one node (+ extra nodes for additional aliases)
229
+ * - ASSOC_EXPAND_ALL: Composition without nested fields → expands all fields
230
+ * - ASSOC_WITH_NESTED: Composition with specific nested fields → recurses
231
+ * - MULTI_ALIAS: Multiple aliases without non-aliased entry → creates node per alias
232
+ *
233
+ * @example
234
+ * Case 1: MULTI_ALIAS - Multiple aliases, no non-aliased entry
235
+ * inputs: [{ path: $self.ID, as: 'OrderId' }, { path: $self.ID, as: 'RefId' }]
236
+ * classifyElement('ID', {
237
+ * nonAliasedDirect: undefined,
238
+ * aliasedDirect: [{ path: ['ID'], alias: 'OrderId' }, { path: ['ID'], alias: 'RefId' }],
239
+ * nestedEntries: []
240
+ * }, false)
241
+ * Returns: { kind: MULTI_ALIAS, primaryAlias: undefined, additionalAliasedNodes: [{ alias: 'OrderId' }, { alias: 'RefId' }] }
242
+ * Result: Two separate nodes, one per alias
243
+ *
244
+ * @example
245
+ * Case 2: SCALAR with additional aliases - Both aliased and non-aliased
246
+ * inputs: [$self.ID, { path: $self.ID, as: 'EntityId' }]
247
+ * classifyElement('ID', {
248
+ * nonAliasedDirect: { path: ['ID'], alias: undefined },
249
+ * aliasedDirect: [{ path: ['ID'], alias: 'EntityId' }],
250
+ * nestedEntries: []
251
+ * }, false)
252
+ * Returns: { kind: SCALAR, primaryAlias: undefined, additionalAliasedNodes: [{ alias: 'EntityId' }] }
253
+ * Result: Primary node 'ID', plus extra node 'EntityId'
254
+ *
255
+ * @example
256
+ * Case 3: ASSOC_WITH_NESTED - Composition with specific nested fields
257
+ * inputs: [$self.items.quantity, $self.items.price]
258
+ * classifyElement('items', {
259
+ * nonAliasedDirect: undefined,
260
+ * aliasedDirect: [],
261
+ * nestedEntries: [{ path: ['quantity'] }, { path: ['price'] }]
262
+ * }, true)
263
+ * Returns: { kind: ASSOC_WITH_NESTED, primaryAlias: undefined, additionalAliasedNodes: [] }
264
+ * Result: items node with nested quantity and price
265
+ *
266
+ * @example
267
+ * Case 4: ASSOC_EXPAND_ALL - Composition without nested fields
268
+ * inputs: [$self.items]
269
+ * classifyElement('items', {
270
+ * nonAliasedDirect: { path: ['items'], alias: undefined },
271
+ * aliasedDirect: [],
272
+ * nestedEntries: []
273
+ * }, true)
274
+ * Returns: { kind: ASSOC_EXPAND_ALL, primaryAlias: undefined, additionalAliasedNodes: [] }
275
+ * Result: items node that expands all fields (associatedInputElements: [])
276
+ *
277
+ * @example
278
+ * Case 5: Simple SCALAR
279
+ * inputs: [$self.title]
280
+ * classifyElement('title', {
281
+ * nonAliasedDirect: { path: ['title'], alias: undefined },
282
+ * aliasedDirect: [],
283
+ * nestedEntries: []
284
+ * }, false)
285
+ * Returns: { kind: SCALAR, primaryAlias: undefined, additionalAliasedNodes: [] }
286
+ * Result: Simple { sourceElement: 'title' } node
287
+ */
288
+ function classifyElement(analysis, isAssocOrComp) {
289
+ const { nonAliasedDirect, aliasedDirect, nestedEntries } = analysis;
290
+ // Case 1: Multiple aliases without non-aliased entry → MULTI_ALIAS
291
+ // e.g., [{ path: $self.ID, as: 'OrderId' }, { path: $self.ID, as: 'RefId' }]
292
+ if (aliasedDirect.length > 1 && !nonAliasedDirect) {
293
+ return {
294
+ kind: ElementKind.MULTI_ALIAS,
295
+ primaryAlias: undefined,
296
+ additionalAliasedNodes: aliasedDirect.map((e) => ({ alias: e.alias })),
297
+ };
298
+ }
299
+ // Case 2: Scalar field with both aliased and non-aliased entries
300
+ // e.g., [$self.ID, { path: $self.ID, as: 'EntityId' }]
301
+ // → primary is non-aliased, aliased become additional nodes
302
+ if (!isAssocOrComp && aliasedDirect.length > 0 && nonAliasedDirect) {
303
+ return {
304
+ kind: ElementKind.SCALAR,
305
+ primaryAlias: undefined,
306
+ additionalAliasedNodes: aliasedDirect.map((e) => ({ alias: e.alias })),
307
+ };
308
+ }
309
+ // Case 3: Association with nested entries → ASSOC_WITH_NESTED
310
+ if (nestedEntries.length > 0) {
311
+ return {
312
+ kind: ElementKind.ASSOC_WITH_NESTED,
313
+ primaryAlias: analysis.directEntries[0]?.alias,
314
+ additionalAliasedNodes: [],
315
+ };
316
+ }
317
+ // Case 4: Association without nested → ASSOC_EXPAND_ALL
318
+ if (isAssocOrComp) {
319
+ return {
320
+ kind: ElementKind.ASSOC_EXPAND_ALL,
321
+ primaryAlias: analysis.directEntries[0]?.alias,
322
+ additionalAliasedNodes: [],
323
+ };
324
+ }
325
+ // Case 5: Simple scalar field → SCALAR
326
+ return {
327
+ kind: ElementKind.SCALAR,
328
+ primaryAlias: analysis.directEntries[0]?.alias,
329
+ additionalAliasedNodes: [],
330
+ };
331
+ }
332
+ /**
333
+ * Preprocesses all entries into enriched element descriptors.
334
+ *
335
+ * This is the main preprocessing function that does all upfront analysis:
336
+ * 1. Groups entries by first segment
337
+ * 2. Resolves element types (scalar vs association/composition)
338
+ * 3. Classifies how each element should be processed
339
+ * 4. Prepares nested entries with wildcard injection if needed
340
+ *
341
+ * The result is a flat list of PreprocessedElement objects that the state machine
342
+ * can process sequentially without any additional lookups or analysis.
343
+ *
344
+ * @example
345
+ * Full preprocessing example:
346
+ * Entity: { ID: scalar, title: scalar, items: Composition of Items }
347
+ * Items: { quantity: Integer, price: Decimal }
348
+ *
349
+ * Annotation inputs: [$self.ID, $self.title, $self.items, $self.items.quantity]
350
+ *
351
+ * preprocessEntries([
352
+ * { path: ['ID'], alias: undefined },
353
+ * { path: ['title'], alias: undefined },
354
+ * { path: ['items'], alias: undefined },
355
+ * { path: ['items', 'quantity'], alias: undefined }
356
+ * ], rootEntity, resolver)
357
+ *
358
+ * Returns:
359
+ * [
360
+ * {
361
+ * name: 'ID',
362
+ * kind: SCALAR,
363
+ * primaryAlias: undefined,
364
+ * nestedEntries: [],
365
+ * additionalAliasedNodes: [],
366
+ * isAssocOrComp: false,
367
+ * element: <ID element>,
368
+ * targetEntity: rootEntity
369
+ * },
370
+ * {
371
+ * name: 'title',
372
+ * kind: SCALAR,
373
+ * primaryAlias: undefined,
374
+ * nestedEntries: [],
375
+ * additionalAliasedNodes: [],
376
+ * isAssocOrComp: false,
377
+ * element: <title element>,
378
+ * targetEntity: rootEntity
379
+ * },
380
+ * {
381
+ * name: 'items',
382
+ * kind: ASSOC_WITH_NESTED,
383
+ * primaryAlias: undefined,
384
+ * nestedEntries: [
385
+ * { path: ['*'], alias: undefined }, // Wildcard injected!
386
+ * { path: ['quantity'], alias: undefined }
387
+ * ],
388
+ * additionalAliasedNodes: [],
389
+ * isAssocOrComp: true,
390
+ * targetEntity: <Items entity context>
391
+ * }
392
+ * ]
393
+ *
394
+ * Note: The wildcard ['*'] was injected because we have both:
395
+ * - $self.items (expand all) AND $self.items.quantity (specific nested)
396
+ * This means "expand all items fields PLUS include quantity explicitly (for aliasing)"
397
+ *
398
+ * @example
399
+ * Multiple aliases preprocessing:
400
+ * inputs: [{ path: $self.ID, as: 'OrderId' }, { path: $self.ID, as: 'RefId' }]
401
+ *
402
+ * preprocessEntries([
403
+ * { path: ['ID'], alias: 'OrderId' },
404
+ * { path: ['ID'], alias: 'RefId' }
405
+ * ], rootEntity)
406
+ *
407
+ * Returns:
408
+ * [
409
+ * {
410
+ * name: 'ID',
411
+ * kind: MULTI_ALIAS,
412
+ * primaryAlias: undefined,
413
+ * nestedEntries: [],
414
+ * additionalAliasedNodes: [{ alias: 'OrderId' }, { alias: 'RefId' }],
415
+ * isAssocOrComp: false,
416
+ * targetEntity: rootEntity
417
+ * }
418
+ * ]
419
+ */
420
+ function preprocessEntries(entries, rootEntity) {
421
+ const groups = groupEntriesByFirstSegment(entries);
422
+ const result = [];
423
+ for (const [elementName, group] of groups) {
424
+ const element = rootEntity.getElement(elementName);
425
+ const isAssocOrComp = element?.isAssocOrComp ?? false;
426
+ const targetEntity = element?.targetEntity ?? rootEntity;
427
+ const analysis = analyzeEntryGroup(group);
428
+ const classification = classifyElement(analysis, isAssocOrComp);
429
+ // Prepare nested entries with wildcard injection for composition expand-all + nested fields
430
+ let nestedEntries = analysis.nestedEntries;
431
+ if (isAssocOrComp &&
432
+ analysis.nonAliasedDirect &&
433
+ nestedEntries.length > 0 &&
434
+ classification.kind !== ElementKind.MULTI_ALIAS) {
435
+ // Inject wildcard to expand all fields plus specific nested fields
436
+ nestedEntries = [{ path: [exports.WILDCARD], alias: undefined }, ...nestedEntries];
437
+ }
438
+ result.push({
439
+ name: elementName,
440
+ kind: classification.kind,
441
+ primaryAlias: classification.primaryAlias,
442
+ nestedEntries,
443
+ additionalAliasedNodes: classification.additionalAliasedNodes,
444
+ isAssocOrComp,
445
+ targetEntity,
446
+ });
447
+ }
448
+ return result;
449
+ }
450
+ // ═══════════════════════════════════════════════════════════════════════════
451
+ // STATE MACHINE
452
+ // ═══════════════════════════════════════════════════════════════════════════
453
+ /**
454
+ * State Machine for building input tree from preprocessed elements
455
+ *
456
+ * Simplified Grammar (after preprocessing):
457
+ * <start> ::= INIT
458
+ * INIT ::= NEXT_ELEMENT
459
+ * NEXT_ELEMENT ::= SELECT_HANDLER | DONE
460
+ * SELECT_HANDLER::= BUILD_SCALAR | BUILD_ASSOC_EXPAND | BUILD_ASSOC_NESTED | BUILD_MULTI_ALIAS
461
+ * BUILD_* ::= ADD_EXTRA_ALIASES
462
+ * ADD_EXTRA ::= NEXT_ELEMENT
463
+ * <end> ::= DONE
464
+ */
465
+ var BuildState;
466
+ (function (BuildState) {
467
+ /** Initialize processing */
468
+ BuildState["INIT"] = "INIT";
469
+ /** Move to next element */
470
+ BuildState["NEXT_ELEMENT"] = "NEXT_ELEMENT";
471
+ /** Select appropriate handler based on element kind */
472
+ BuildState["SELECT_HANDLER"] = "SELECT_HANDLER";
473
+ /** Build a simple scalar field node */
474
+ BuildState["BUILD_SCALAR"] = "BUILD_SCALAR";
475
+ /** Build an association node that expands all fields */
476
+ BuildState["BUILD_ASSOC_EXPAND"] = "BUILD_ASSOC_EXPAND";
477
+ /** Build an association node with specific nested fields */
478
+ BuildState["BUILD_ASSOC_NESTED"] = "BUILD_ASSOC_NESTED";
479
+ /** Build multiple nodes for multi-alias case */
480
+ BuildState["BUILD_MULTI_ALIAS"] = "BUILD_MULTI_ALIAS";
481
+ /** Add any additional aliased nodes */
482
+ BuildState["ADD_EXTRA_ALIASES"] = "ADD_EXTRA_ALIASES";
483
+ /** Processing complete */
484
+ BuildState["DONE"] = "DONE";
485
+ })(BuildState || (BuildState = {}));
486
+ /**
487
+ * Builds a tree structure from parsed input entries
488
+ *
489
+ * @param entries - Parsed input entries from parseInputsArray
490
+ * @param rootEntity - The root entity context to resolve elements from
491
+ *
492
+ * @example
493
+ * Input → Output mappings:
494
+ *
495
+ * 1. Wildcard (all scalar fields):
496
+ * [{ path: ['*'] }] → [{ sourceElement: '*' }]
497
+ *
498
+ * 2. Simple field:
499
+ * [{ path: ['ID'] }] → [{ sourceElement: 'ID' }]
500
+ *
501
+ * 3. Association (expand all) - 'items' is a Composition:
502
+ * [{ path: ['items'] }] → [{ sourceElement: 'items', associatedInputElements: [] }]
503
+ *
504
+ * 4. Nested path:
505
+ * [{ path: ['items', 'title'] }]
506
+ * → [{ sourceElement: 'items', associatedInputElements: [{ sourceElement: 'title' }] }]
507
+ *
508
+ * 5. With alias:
509
+ * [{ path: ['price'], alias: 'Amount' }]
510
+ * → [{ sourceElement: 'price', targetVariable: 'Amount' }]
511
+ *
512
+ * 6. Composition expand-all + nested alias:
513
+ * [{ path: ['items'] }, { path: ['items', 'ID'], alias: 'ItemId' }]
514
+ * → [{ sourceElement: 'items', associatedInputElements: [
515
+ * { sourceElement: '*' },
516
+ * { sourceElement: 'ID', targetVariable: 'ItemId' }
517
+ * ]}]
518
+ *
519
+ * 7. Multiple aliases on scalar (no non-aliased entry):
520
+ * [{ path: ['ID'], alias: 'OrderId' }, { path: ['ID'], alias: 'RefId' }]
521
+ * → [{ sourceElement: 'ID', targetVariable: 'OrderId' },
522
+ * { sourceElement: 'ID', targetVariable: 'RefId' }]
523
+ *
524
+ * 8. Multiple aliases on composition:
525
+ * [{ path: ['items'], alias: 'Order' }, { path: ['items'], alias: 'ItemOrder' }]
526
+ * → [{ sourceElement: 'items', targetVariable: 'Order', associatedInputElements: [] },
527
+ * { sourceElement: 'items', targetVariable: 'ItemOrder', associatedInputElements: [] }]
528
+ *
529
+ * @returns Tree of InputTreeNode representing the input structure
530
+ */
531
+ function buildInputTree(entries, rootEntity) {
532
+ if (entries.length === 0) {
533
+ return [];
534
+ }
535
+ // Preprocess entries to classify and enrich them for easier processing in the state machine
536
+ const preprocessedElements = preprocessEntries(entries, rootEntity);
537
+ const result = [];
538
+ let state = BuildState.INIT;
539
+ let currentIndex = 0;
540
+ let currentElement = null;
541
+ while (state !== BuildState.DONE) {
542
+ switch (state) {
543
+ case BuildState.INIT: {
544
+ currentIndex = 0;
545
+ state = BuildState.NEXT_ELEMENT;
546
+ break;
547
+ }
548
+ case BuildState.NEXT_ELEMENT: {
549
+ if (currentIndex >= preprocessedElements.length) {
550
+ state = BuildState.DONE;
551
+ }
552
+ else {
553
+ currentElement = preprocessedElements[currentIndex];
554
+ state = BuildState.SELECT_HANDLER;
555
+ }
556
+ break;
557
+ }
558
+ case BuildState.SELECT_HANDLER: {
559
+ switch (currentElement.kind) {
560
+ case ElementKind.SCALAR:
561
+ state = BuildState.BUILD_SCALAR;
562
+ break;
563
+ case ElementKind.ASSOC_EXPAND_ALL:
564
+ state = BuildState.BUILD_ASSOC_EXPAND;
565
+ break;
566
+ case ElementKind.ASSOC_WITH_NESTED:
567
+ state = BuildState.BUILD_ASSOC_NESTED;
568
+ break;
569
+ case ElementKind.MULTI_ALIAS:
570
+ state = BuildState.BUILD_MULTI_ALIAS;
571
+ break;
572
+ }
573
+ break;
574
+ }
575
+ case BuildState.BUILD_SCALAR: {
576
+ result.push({
577
+ sourceElement: currentElement.name,
578
+ targetVariable: currentElement.primaryAlias,
579
+ });
580
+ state = BuildState.ADD_EXTRA_ALIASES;
581
+ break;
582
+ }
583
+ case BuildState.BUILD_ASSOC_EXPAND: {
584
+ result.push({
585
+ sourceElement: currentElement.name,
586
+ targetVariable: currentElement.primaryAlias,
587
+ associatedInputElements: [],
588
+ });
589
+ state = BuildState.ADD_EXTRA_ALIASES;
590
+ break;
591
+ }
592
+ case BuildState.BUILD_ASSOC_NESTED: {
593
+ const nestedResults = buildInputTree(currentElement.nestedEntries, currentElement.targetEntity);
594
+ result.push({
595
+ sourceElement: currentElement.name,
596
+ targetVariable: currentElement.primaryAlias,
597
+ associatedInputElements: nestedResults,
598
+ });
599
+ state = BuildState.ADD_EXTRA_ALIASES;
600
+ break;
601
+ }
602
+ case BuildState.BUILD_MULTI_ALIAS: {
603
+ // Build a node for each alias
604
+ for (const { alias } of currentElement.additionalAliasedNodes) {
605
+ if (currentElement.isAssocOrComp) {
606
+ if (currentElement.nestedEntries.length > 0) {
607
+ const nestedResults = buildInputTree(currentElement.nestedEntries, currentElement.targetEntity);
608
+ result.push({
609
+ sourceElement: currentElement.name,
610
+ targetVariable: alias,
611
+ associatedInputElements: nestedResults,
612
+ });
613
+ }
614
+ else {
615
+ result.push({
616
+ sourceElement: currentElement.name,
617
+ targetVariable: alias,
618
+ associatedInputElements: [],
619
+ });
620
+ }
621
+ }
622
+ else {
623
+ result.push({
624
+ sourceElement: currentElement.name,
625
+ targetVariable: alias,
626
+ });
627
+ }
628
+ }
629
+ // Skip ADD_EXTRA_ALIASES since MULTI_ALIAS handles all aliases
630
+ currentIndex++;
631
+ state = BuildState.NEXT_ELEMENT;
632
+ break;
633
+ }
634
+ case BuildState.ADD_EXTRA_ALIASES: {
635
+ // Add any additional aliased nodes (e.g., from [$self.ID, { path: $self.ID, as: 'EntityId' }])
636
+ for (const { alias } of currentElement.additionalAliasedNodes) {
637
+ result.push({
638
+ sourceElement: currentElement.name,
639
+ targetVariable: alias,
640
+ });
641
+ }
642
+ currentIndex++;
643
+ state = BuildState.NEXT_ELEMENT;
644
+ break;
645
+ }
646
+ }
647
+ }
648
+ return result;
649
+ }
650
+ //# sourceMappingURL=input-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-parser.js","sourceRoot":"","sources":["../../../lib/shared/input-parser.ts"],"names":[],"mappings":"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"}