@uipath/maestro-builder-sdk 6.17.6 → 6.18.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 (67) hide show
  1. package/dist/bindings-v2.js +15 -17
  2. package/dist/bpmn/bpmn-sdk.js +3 -2
  3. package/dist/bpmn/check.js +3 -2
  4. package/dist/bpmn/decompile.js +123 -137
  5. package/dist/bpmn/intsvc.js +7 -2
  6. package/dist/bpmn/serialize.js +1 -1
  7. package/dist/bpmn/typed-node.js +5 -4
  8. package/dist/case/check-cli.js +18 -4
  9. package/dist/case/check.d.ts +26 -1
  10. package/dist/case/check.js +80 -2
  11. package/dist/case/cli-library.d.ts +14 -0
  12. package/dist/case/cli-library.js +31 -0
  13. package/dist/case/compile-cli.js +12 -12
  14. package/dist/case/decompile.js +103 -109
  15. package/dist/case/entry-points.js +2 -1
  16. package/dist/case/merge.js +3 -5
  17. package/dist/case/serialize.js +1 -1
  18. package/dist/check.js +26 -10
  19. package/dist/cli/commands/case.js +10 -1
  20. package/dist/core/ceql.js +5 -2
  21. package/dist/core/connector-inputs.js +4 -4
  22. package/dist/core/event-checks.js +17 -2
  23. package/dist/core/event-filters.d.ts +38 -4
  24. package/dist/core/event-filters.js +63 -7
  25. package/dist/core/expr.d.ts +1 -1
  26. package/dist/core/expr.js +3 -3
  27. package/dist/core/json-file.d.ts +2 -0
  28. package/dist/core/json-file.js +4 -0
  29. package/dist/core/library.js +2 -1
  30. package/dist/core/node-envelope.d.ts +1 -0
  31. package/dist/core/node-envelope.js +1 -1
  32. package/dist/core/own-entry.d.ts +9 -0
  33. package/dist/core/own-entry.js +11 -0
  34. package/dist/core/ts-literal.d.ts +22 -0
  35. package/dist/core/ts-literal.js +37 -0
  36. package/dist/core/typed-raw-node.js +4 -3
  37. package/dist/decompile.js +238 -255
  38. package/dist/merge.js +10 -12
  39. package/dist/registry/compat/pystr.d.ts +2 -0
  40. package/dist/registry/compat/pystr.js +35 -0
  41. package/dist/registry/compat/pyvalue.d.ts +16 -0
  42. package/dist/registry/compat/pyvalue.js +35 -0
  43. package/dist/registry/generators/markdown/pyvalue.d.ts +1 -4
  44. package/dist/registry/generators/markdown/pyvalue.js +2 -30
  45. package/dist/registry/generators/markdown/sections/inputs.js +3 -2
  46. package/dist/registry/generators/type-tree.d.ts +1 -7
  47. package/dist/registry/generators/type-tree.js +5 -22
  48. package/dist/registry/library-build/build.js +6 -6
  49. package/dist/registry/library-build/canonical.js +25 -25
  50. package/dist/registry/library-build/context.js +5 -5
  51. package/dist/registry/library-build/enrich.js +18 -18
  52. package/dist/registry/library-build/events.js +25 -24
  53. package/dist/registry/library-build/generic-expand.js +21 -20
  54. package/dist/registry/library-build/plan.js +8 -8
  55. package/dist/registry/library-build/py.d.ts +3 -10
  56. package/dist/registry/library-build/py.js +9 -52
  57. package/dist/registry/library-build/schema-action.js +6 -6
  58. package/dist/registry/prepare/event.js +2 -2
  59. package/dist/registry/prepare/source-import.js +2 -9
  60. package/dist/registry/prepare/source-labels.js +2 -9
  61. package/dist/registry/prepare/support.d.ts +2 -6
  62. package/dist/registry/prepare/support.js +3 -58
  63. package/dist/registry/pull-cli.js +6 -14
  64. package/dist/registry/search-cli.js +2 -2
  65. package/dist/schema-version.js +0 -1
  66. package/dist/serialize.js +86 -76
  67. package/package.json +2 -2
@@ -1,6 +1,8 @@
1
1
  import { commentText } from '../core/comment-text.js';
2
+ import { tsLiteral, tsNumber } from '../core/ts-literal.js';
2
3
  import { CASE_FORMAT_PROFILE, CASE_SCHEMA_VERSIONS } from './format-profile.js';
3
4
  import { preserveSchemaVersion } from '../schema-version.js';
5
+ import { ownEntry } from '../core/own-entry.js';
4
6
  const TASK_KIND_METHOD = {
5
7
  process: 'process',
6
8
  agent: 'agent',
@@ -9,20 +11,11 @@ const TASK_KIND_METHOD = {
9
11
  'case-management': 'caseManagement',
10
12
  'flow-process': 'flowProcess',
11
13
  };
12
- function str(value) {
13
- return JSON.stringify(value).replace(/[\u2028\u2029]/g, (char) => `\\u${char.charCodeAt(0).toString(16)}`);
14
- }
15
14
  function boolLit(value) {
16
15
  return value ? 'true' : 'false';
17
16
  }
18
17
  function key(value) {
19
- return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value) ? value : str(value);
20
- }
21
- function literal(value) {
22
- const rendered = JSON.stringify(value);
23
- if (rendered === undefined)
24
- throw new Error('cannot decompile a non-JSON value.');
25
- return rendered.replace(/[\u2028\u2029]/g, (char) => `\\u${char.charCodeAt(0).toString(16)}`);
18
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value) ? value : tsLiteral(value);
26
19
  }
27
20
  function opts(entries) {
28
21
  const parts = entries.filter((entry) => entry[1] !== undefined)
@@ -122,8 +115,8 @@ function waitConnectorSpec(bag, owner, refs) {
122
115
  if (connectorKey === 'placeholder' && operation === 'placeholder')
123
116
  return '{}';
124
117
  return opts([
125
- ['connectorKey', str(connectorKey)],
126
- ['operation', str(operation)],
118
+ ['connectorKey', tsLiteral(connectorKey)],
119
+ ['operation', tsLiteral(operation)],
127
120
  ]);
128
121
  }
129
122
  return resolvedSubscriptionSource(bag, owner, 'event', refs);
@@ -195,13 +188,13 @@ function resolvedSubscriptionSource(bag, owner, kind, refs) {
195
188
  const where = subscriptionWhere(bag, owner);
196
189
  const filters = subscriptionFilters(config, owner);
197
190
  return opts([
198
- ['connector', str(identity.key)],
199
- ['event', str(identity.event)],
200
- ['where', where !== undefined ? literal(where) : undefined],
201
- ['filters', filters !== undefined ? literal(filters) : undefined],
202
- ['connection', connection !== undefined ? str(connection) : undefined],
203
- ['folder', folder !== undefined ? str(folder) : undefined],
204
- ['version', identity.version !== '1.0.0' ? str(identity.version) : undefined],
191
+ ['connector', tsLiteral(identity.key)],
192
+ ['event', tsLiteral(identity.event)],
193
+ ['where', where !== undefined ? tsLiteral(where) : undefined],
194
+ ['filters', filters !== undefined ? tsLiteral(filters) : undefined],
195
+ ['connection', connection !== undefined ? tsLiteral(connection) : undefined],
196
+ ['folder', folder !== undefined ? tsLiteral(folder) : undefined],
197
+ ['version', identity.version !== '1.0.0' ? tsLiteral(identity.version) : undefined],
205
198
  ]);
206
199
  }
207
200
  function emitRule(rule, refs) {
@@ -220,20 +213,20 @@ function emitRule(rule, refs) {
220
213
  });
221
214
  label = `__UNRESOLVED_STAGE_ID__:${stageIds[0]}`;
222
215
  }
223
- entries.push(['stage', str(label)]);
216
+ entries.push(['stage', tsLiteral(label)]);
224
217
  }
225
218
  if (rule.selectedTasksIds !== undefined) {
226
219
  const names = rule.selectedTasksIds.map((id) => {
227
220
  const name = refs.taskNameById.get(id);
228
221
  if (name !== undefined)
229
- return str(name);
222
+ return tsLiteral(name);
230
223
  const message = `rule "${rule.rule}" references unknown task id "${id}".`;
231
224
  diagnose(refs, {
232
225
  code: 'UNKNOWN_TASK_REFERENCE',
233
226
  message,
234
227
  location: `rule:${rule.id ?? rule.rule}`,
235
228
  });
236
- return str(`__UNRESOLVED_TASK_ID__:${id}`);
229
+ return tsLiteral(`__UNRESOLVED_TASK_ID__:${id}`);
237
230
  });
238
231
  entries.push(['tasks', `[${names.join(', ')}]`]);
239
232
  }
@@ -246,18 +239,18 @@ function emitRule(rule, refs) {
246
239
  const sla = rule.slaId && refs.slaNameById.get(rule.slaId);
247
240
  if (!sla)
248
241
  throw new Error(`sla-status-change rule references unnamed or unknown SLA id "${rule.slaId ?? ''}".`);
249
- entries.push(['sla', str(sla)]);
242
+ entries.push(['sla', tsLiteral(sla)]);
250
243
  if (rule.escalationId !== undefined) {
251
244
  const escalation = refs.escalationNameById.get(rule.escalationId);
252
245
  if (!escalation)
253
246
  throw new Error(`sla-status-change rule references unnamed or unknown escalation id "${rule.escalationId}".`);
254
- entries.push(['escalation', str(escalation)]);
247
+ entries.push(['escalation', tsLiteral(escalation)]);
255
248
  }
256
249
  }
257
250
  if (rule.conditionExpression !== undefined)
258
- entries.push(['expression', str(rule.conditionExpression)]);
251
+ entries.push(['expression', tsLiteral(rule.conditionExpression)]);
259
252
  const options = opts(entries);
260
- return options ? `rule(${str(rule.rule)}, ${options})` : `rule(${str(rule.rule)})`;
253
+ return options ? `rule(${tsLiteral(rule.rule)}, ${options})` : `rule(${tsLiteral(rule.rule)})`;
261
254
  }
262
255
  function emitRuleArg(condition, refs) {
263
256
  const groups = condition.rules ?? [];
@@ -272,7 +265,7 @@ function emitEntryWhen(out, depth, condition, refs, stage) {
272
265
  // only while that default was a constant: now that an omitted name is DERIVED
273
266
  // from the owner, dropping it would make decompile → compile rename the rule.
274
267
  // Round-trip identity over the existing corpus beats a tidier generated source.
275
- const displayName = condition.displayName ? str(condition.displayName) : undefined;
268
+ const displayName = condition.displayName ? tsLiteral(condition.displayName) : undefined;
276
269
  const options = opts([
277
270
  ['displayName', displayName],
278
271
  ['isInterrupting', stage && condition.isInterrupting !== undefined ? boolLit(condition.isInterrupting) : undefined],
@@ -282,7 +275,7 @@ function emitEntryWhen(out, depth, condition, refs, stage) {
282
275
  }
283
276
  function emitExitWhen(out, depth, condition, refs, selectNextStage) {
284
277
  // See emitEntryWhen: the name is preserved verbatim so the round trip is exact.
285
- const displayName = condition.displayName ? str(condition.displayName) : undefined;
278
+ const displayName = condition.displayName ? tsLiteral(condition.displayName) : undefined;
286
279
  let exitToStage;
287
280
  if (condition.exitToStageId !== undefined) {
288
281
  let label = refs.stageLabelById.get(condition.exitToStageId);
@@ -295,12 +288,12 @@ function emitExitWhen(out, depth, condition, refs, selectNextStage) {
295
288
  });
296
289
  label = `__UNRESOLVED_STAGE_ID__:${condition.exitToStageId}`;
297
290
  }
298
- exitToStage = str(label);
291
+ exitToStage = tsLiteral(label);
299
292
  }
300
293
  const options = opts([
301
294
  ['displayName', displayName],
302
295
  ['marksStageComplete', condition.marksStageComplete !== undefined ? boolLit(condition.marksStageComplete) : undefined],
303
- ['type', condition.type !== undefined ? str(condition.type) : undefined],
296
+ ['type', condition.type !== undefined ? tsLiteral(condition.type) : undefined],
304
297
  ['exitToStage', exitToStage],
305
298
  ['selectNextStage', selectNextStage],
306
299
  ]);
@@ -310,7 +303,7 @@ function emitExitWhen(out, depth, condition, refs, selectNextStage) {
310
303
  function emitCompleteWhen(out, depth, condition, refs) {
311
304
  // See emitEntryWhen: the name is preserved verbatim so the round trip is exact.
312
305
  const displayName = condition.displayName
313
- ? str(condition.displayName)
306
+ ? tsLiteral(condition.displayName)
314
307
  : undefined;
315
308
  const options = opts([
316
309
  ['displayName', displayName],
@@ -323,13 +316,13 @@ function actionFields(rows) {
323
316
  if (!rows?.length)
324
317
  return undefined;
325
318
  return `[${rows.map((row) => opts([
326
- ['name', str(row.name ?? '')],
327
- ['type', row.type && row.type !== 'string' ? str(row.type) : undefined],
328
- ['subType', row.subType !== undefined ? str(row.subType) : undefined],
329
- ['displayName', row.displayName !== undefined ? str(row.displayName) : undefined],
330
- ['value', row.value !== undefined ? literal(row.value) : undefined],
331
- ['required', row.required !== undefined ? literal(row.required) : undefined],
332
- ['options', row.options !== undefined ? literal(row.options) : undefined],
319
+ ['name', tsLiteral(row.name ?? '')],
320
+ ['type', row.type && row.type !== 'string' ? tsLiteral(row.type) : undefined],
321
+ ['subType', row.subType !== undefined ? tsLiteral(row.subType) : undefined],
322
+ ['displayName', row.displayName !== undefined ? tsLiteral(row.displayName) : undefined],
323
+ ['value', row.value !== undefined ? tsLiteral(row.value) : undefined],
324
+ ['required', row.required !== undefined ? tsLiteral(row.required) : undefined],
325
+ ['options', row.options !== undefined ? tsLiteral(row.options) : undefined],
333
326
  ])).join(', ')}]`;
334
327
  }
335
328
  function bindingName(value, refs) {
@@ -400,10 +393,10 @@ function selectNextStageByExit(plan, refs) {
400
393
  if (context.has('folderKey') && folder === undefined)
401
394
  throw new Error('select-next-stage connector folderKey must reference a root binding.');
402
395
  connectorSource = opts([
403
- ['connectorKey', str(connectorKey)],
404
- ['operation', str(operation)],
405
- ['connection', connection !== undefined ? str(connection) : undefined],
406
- ['folder', folder !== undefined ? str(folder) : undefined],
396
+ ['connectorKey', tsLiteral(connectorKey)],
397
+ ['operation', tsLiteral(operation)],
398
+ ['connection', connection !== undefined ? tsLiteral(connection) : undefined],
399
+ ['folder', folder !== undefined ? tsLiteral(folder) : undefined],
407
400
  ]);
408
401
  }
409
402
  const exits = (plan.nodes ?? []).filter(isStage)
@@ -412,7 +405,7 @@ function selectNextStageByExit(plan, refs) {
412
405
  if (exits.length !== 1)
413
406
  throw new Error(`select-next-stage connector requires exactly one wait-for-user exit; found ${exits.length}.`);
414
407
  return new Map([[exits[0], opts([
415
- ['objectName', str(objectName)],
408
+ ['objectName', tsLiteral(objectName)],
416
409
  ['connector', connectorSource],
417
410
  ])]]);
418
411
  }
@@ -476,12 +469,12 @@ function connectorCall(task, refs, library) {
476
469
  const connection = bindingName(context.get('connection')?.value, refs);
477
470
  const folder = bindingName(context.get('folderKey')?.value, refs);
478
471
  const options = opts([
479
- ['connection', connection !== undefined ? str(connection) : undefined],
480
- ['folder', folder !== undefined ? str(folder) : undefined],
481
- ['version', identity.version !== '1.0.0' ? str(identity.version) : undefined],
482
- ['object', identity.object !== undefined ? str(identity.object) : undefined],
472
+ ['connection', connection !== undefined ? tsLiteral(connection) : undefined],
473
+ ['folder', folder !== undefined ? tsLiteral(folder) : undefined],
474
+ ['version', identity.version !== '1.0.0' ? tsLiteral(identity.version) : undefined],
475
+ ['object', identity.object !== undefined ? tsLiteral(identity.object) : undefined],
483
476
  ]);
484
- return `.connector(${str(identity.key)}, ${str(identity.action)}, ${literal(inputs)}${options ? `, ${options}` : ''})`;
477
+ return `.connector(${tsLiteral(identity.key)}, ${tsLiteral(identity.action)}, ${tsLiteral(inputs)}${options ? `, ${options}` : ''})`;
485
478
  }
486
479
  function externalCall(task, refs, library) {
487
480
  const kind = task.type;
@@ -558,12 +551,12 @@ function externalCall(task, refs, library) {
558
551
  if (output.name !== 'response' || output.type !== 'json' || output.source !== '.'
559
552
  || typeof output.var !== 'string' || output.id !== output.var)
560
553
  throw new Error(`${owner} has an unsupported response output.`);
561
- const descriptor = `{ nodeType: ${str(resolved.nodeType)}, version: ${str(resolved.version)} }`;
554
+ const descriptor = `{ nodeType: ${tsLiteral(resolved.nodeType)}, version: ${tsLiteral(resolved.version)} }`;
562
555
  const options = opts([
563
- ['connection', str(binding('connection'))],
564
- ['folder', str(binding('folderKey'))],
565
- ['mode', str(mode)],
566
- ['inputs', literal(inputs)],
556
+ ['connection', tsLiteral(binding('connection'))],
557
+ ['folder', tsLiteral(binding('folderKey'))],
558
+ ['mode', tsLiteral(mode)],
559
+ ['inputs', tsLiteral(inputs)],
567
560
  ]);
568
561
  const method = kind === 'external-agent' ? 'externalAgent' : 'externalWorkflow';
569
562
  return `.${method}(${descriptor}, ${options})`;
@@ -571,16 +564,17 @@ function externalCall(task, refs, library) {
571
564
  function emitTaskKind(task, refs, library) {
572
565
  const kind = task.type;
573
566
  const data = task.data ?? {};
574
- if (TASK_KIND_METHOD[kind]) {
567
+ const method = ownEntry(TASK_KIND_METHOD, kind);
568
+ if (method) {
575
569
  if (kind !== 'flow-process' && data.name === undefined && data.folderPath === undefined) {
576
570
  if ((Array.isArray(data.inputs) && data.inputs.length) || (Array.isArray(data.outputs) && data.outputs.length))
577
571
  throw new Error(`unresolved ${kind} task "${task.displayName ?? task.id ?? '?'}" cannot carry input or output bindings.`);
578
- return `.unresolved(${str(kind)})`;
572
+ return `.unresolved(${tsLiteral(kind)})`;
579
573
  }
580
574
  const name = bindingDefault(data.name, refs);
581
575
  const folderPath = bindingDefault(data.folderPath, refs);
582
- const folder = folderPath ? `, ${opts([['folder', str(folderPath)]])}` : '';
583
- return `.${TASK_KIND_METHOD[kind]}(${str(name ?? '')}${folder})`;
576
+ const folder = folderPath ? `, ${opts([['folder', tsLiteral(folderPath)]])}` : '';
577
+ return `.${method}(${tsLiteral(name ?? '')}${folder})`;
584
578
  }
585
579
  if (kind === 'action') {
586
580
  let recipient;
@@ -589,15 +583,15 @@ function emitTaskKind(task, refs, library) {
589
583
  if (!Number.isFinite(type))
590
584
  throw new Error(`task recipient has a non-numeric type "${data.recipient.Type}".`);
591
585
  recipient = type === 2
592
- ? str(data.recipient.Value)
593
- : opts([['type', String(type)], ['value', str(data.recipient.Value)]]);
586
+ ? tsLiteral(data.recipient.Value)
587
+ : opts([['type', String(type)], ['value', tsLiteral(data.recipient.Value)]]);
594
588
  }
595
589
  const spec = opts([
596
- ['title', data.taskTitle !== undefined ? str(data.taskTitle) : undefined],
597
- ['priority', data.priority && data.priority !== 'Medium' ? str(data.priority) : undefined],
590
+ ['title', data.taskTitle !== undefined ? tsLiteral(data.taskTitle) : undefined],
591
+ ['priority', data.priority && data.priority !== 'Medium' ? tsLiteral(data.priority) : undefined],
598
592
  ['recipient', recipient],
599
- ['labels', data.labels !== undefined ? str(data.labels) : undefined],
600
- ['actionCatalogName', data.actionCatalogName !== undefined ? str(data.actionCatalogName) : undefined],
593
+ ['labels', data.labels !== undefined ? tsLiteral(data.labels) : undefined],
594
+ ['actionCatalogName', data.actionCatalogName !== undefined ? tsLiteral(data.actionCatalogName) : undefined],
601
595
  ['inputs', actionFields(data.inputs)],
602
596
  ['outputs', actionFields(data.outputs)],
603
597
  ]);
@@ -609,9 +603,9 @@ function emitTaskKind(task, refs, library) {
609
603
  return externalCall(task, refs, library);
610
604
  if (kind === 'wait-for-timer') {
611
605
  const spec = opts([
612
- ['duration', data.timeDuration !== undefined ? str(data.timeDuration) : undefined],
613
- ['date', data.timeDate !== undefined ? str(data.timeDate) : undefined],
614
- ['cycle', data.timeCycle !== undefined ? str(data.timeCycle) : undefined],
606
+ ['duration', data.timeDuration !== undefined ? tsLiteral(data.timeDuration) : undefined],
607
+ ['date', data.timeDate !== undefined ? tsLiteral(data.timeDate) : undefined],
608
+ ['cycle', data.timeCycle !== undefined ? tsLiteral(data.timeCycle) : undefined],
615
609
  ]);
616
610
  return `.waitForTimer(${spec})`;
617
611
  }
@@ -625,25 +619,25 @@ function emitTaskKind(task, refs, library) {
625
619
  message,
626
620
  location: `task:${task.id ?? task.displayName ?? '?'}`,
627
621
  });
628
- return `.__UNRESOLVED_TASK_KIND__(${str(kind)}, ${literal(data)})`;
622
+ return `.__UNRESOLVED_TASK_KIND__(${tsLiteral(kind)}, ${tsLiteral(data)})`;
629
623
  }
630
624
  function ioArg(rows, kind) {
631
625
  const valueField = kind === 'inputs' ? 'value' : 'source';
632
626
  const entries = rows.map((row) => {
633
627
  const name = kind === 'inputs' ? row.name : row.var;
634
- const value = str(row[valueField] ?? '');
628
+ const value = tsLiteral(row[valueField] ?? '');
635
629
  const cell = row.type && row.type !== 'string'
636
- ? `{ ${valueField}: ${value}, type: ${str(row.type)} }`
630
+ ? `{ ${valueField}: ${value}, type: ${tsLiteral(row.type)} }`
637
631
  : value;
638
632
  return `${key(String(name ?? ''))}: ${cell}`;
639
633
  });
640
634
  return `{ ${entries.join(', ')} }`;
641
635
  }
642
636
  function emitTask(out, depth, task, lane, refs, library) {
643
- out.line(depth, `.task(${str(task.displayName ?? '')}, t => t`);
637
+ out.line(depth, `.task(${tsLiteral(task.displayName ?? '')}, t => t`);
644
638
  const inner = depth + 1;
645
639
  out.line(inner, emitTaskKind(task, refs, library));
646
- if (TASK_KIND_METHOD[task.type]) {
640
+ if (ownEntry(TASK_KIND_METHOD, task.type)) {
647
641
  const data = task.data ?? {};
648
642
  if (Array.isArray(data.inputs) && data.inputs.length)
649
643
  out.line(inner, `.inputs(${ioArg(data.inputs, 'inputs')})`);
@@ -655,9 +649,9 @@ function emitTask(out, depth, task, lane, refs, library) {
655
649
  if (task.shouldRunOnlyOnce !== undefined)
656
650
  out.line(inner, task.shouldRunOnlyOnce ? '.runOnce()' : '.runOnReEntry()');
657
651
  if (task.description)
658
- out.line(inner, `.description(${str(task.description)})`);
652
+ out.line(inner, `.description(${tsLiteral(task.description)})`);
659
653
  if (task.skipCondition)
660
- out.line(inner, `.skipWhen(${str(task.skipCondition)})`);
654
+ out.line(inner, `.skipWhen(${tsLiteral(task.skipCondition)})`);
661
655
  for (const condition of task.entryConditions ?? [])
662
656
  emitEntryWhen(out, inner, condition, refs, false);
663
657
  out.line(depth, lane > 0 ? `, ${opts([['lane', String(lane)]])})` : ')');
@@ -673,18 +667,18 @@ function escalationSource(escalation, slaName, index) {
673
667
  throw new Error(`SLA escalation "${escalation.displayName ?? escalation.id ?? index}" has unsupported recipient scope "${recipient.scope}".`);
674
668
  const helper = recipient.scope === 'User' ? 'toUser' : 'toGroup';
675
669
  const target = recipient.target ?? '';
676
- const value = recipient.value !== undefined && recipient.value !== target ? `, ${str(recipient.value)}` : '';
677
- return `${helper}(${str(target)}${value})`;
670
+ const value = recipient.value !== undefined && recipient.value !== target ? `, ${tsLiteral(recipient.value)}` : '';
671
+ return `${helper}(${tsLiteral(target)}${value})`;
678
672
  });
679
673
  const generatedName = `Escalation rule ${index + 1} - ${slaName}`;
680
674
  const trigger = escalation.triggerInfo?.type;
681
675
  if (trigger !== 'at-risk' && trigger !== 'sla-breached')
682
676
  throw new Error(`SLA escalation "${escalation.displayName ?? escalation.id ?? index}" has unsupported trigger "${trigger}".`);
683
677
  return `escalation(${opts([
684
- ['displayName', escalation.displayName && escalation.displayName !== generatedName ? str(escalation.displayName) : undefined],
685
- ['trigger', str(trigger)],
678
+ ['displayName', escalation.displayName && escalation.displayName !== generatedName ? tsLiteral(escalation.displayName) : undefined],
679
+ ['trigger', tsLiteral(trigger)],
686
680
  ['atRiskPercentage', trigger === 'at-risk' && escalation.triggerInfo?.atRiskPercentage !== undefined
687
- ? String(escalation.triggerInfo.atRiskPercentage)
681
+ ? tsNumber(escalation.triggerInfo.atRiskPercentage)
688
682
  : undefined],
689
683
  ['notify', `[${notify.join(', ')}]`],
690
684
  ])})`;
@@ -693,20 +687,20 @@ function slaSource(sla, index) {
693
687
  const displayName = sla.displayName ?? `SLA ${index + 1}`;
694
688
  const escalations = (sla.escalationRule ?? []).map((entry, escalationIndex) => escalationSource(entry, displayName, escalationIndex));
695
689
  return opts([
696
- ['displayName', sla.displayName !== undefined ? str(sla.displayName) : undefined],
697
- ['count', sla.count !== undefined ? String(sla.count) : undefined],
698
- ['unit', sla.unit !== undefined ? str(sla.unit) : undefined],
699
- ['when', sla.expression !== undefined && sla.expression !== '=js:true' ? str(sla.expression) : undefined],
690
+ ['displayName', sla.displayName !== undefined ? tsLiteral(sla.displayName) : undefined],
691
+ ['count', sla.count !== undefined ? tsNumber(sla.count) : undefined],
692
+ ['unit', sla.unit !== undefined ? tsLiteral(sla.unit) : undefined],
693
+ ['when', sla.expression !== undefined && sla.expression !== '=js:true' ? tsLiteral(sla.expression) : undefined],
700
694
  ['escalations', escalations.length ? `[${escalations.join(', ')}]` : undefined],
701
695
  ]);
702
696
  }
703
697
  function emitStage(out, depth, stage, refs, library, selectNextStage) {
704
698
  const exception = stage.type.endsWith('ExceptionStage') || stage.stageType === 'secondary' || stage.data?.stageType === 'secondary';
705
699
  const data = stage.data ?? {};
706
- out.line(depth, `.${exception ? 'exceptionStage' : 'stage'}(${str(data.label ?? '')}, s => s`);
700
+ out.line(depth, `.${exception ? 'exceptionStage' : 'stage'}(${tsLiteral(data.label ?? '')}, s => s`);
707
701
  const inner = depth + 1;
708
702
  if (data.description)
709
- out.line(inner, `.description(${str(data.description)})`);
703
+ out.line(inner, `.description(${tsLiteral(data.description)})`);
710
704
  if (data.isRequired !== undefined)
711
705
  out.line(inner, data.isRequired ? '.required()' : '.required(false)');
712
706
  for (const condition of data.entryConditions ?? [])
@@ -721,15 +715,15 @@ function emitStage(out, depth, stage, refs, library, selectNextStage) {
721
715
  function varSpec(entry) {
722
716
  const body = entry.body ?? entry._jsonSchema;
723
717
  if (entry.type === 'jsonSchema' && body !== undefined && entry.default === undefined)
724
- return `jsonSchema(${literal(body)})`;
718
+ return `jsonSchema(${tsLiteral(body)})`;
725
719
  if (entry.default !== undefined || (entry.type === 'jsonSchema' && body !== undefined)) {
726
720
  return opts([
727
- ['type', str(entry.type)],
728
- ['default', entry.default !== undefined ? literal(entry.default) : undefined],
729
- ['body', entry.type === 'jsonSchema' && body !== undefined ? literal(body) : undefined],
721
+ ['type', tsLiteral(entry.type)],
722
+ ['default', entry.default !== undefined ? tsLiteral(entry.default) : undefined],
723
+ ['body', entry.type === 'jsonSchema' && body !== undefined ? tsLiteral(body) : undefined],
730
724
  ]);
731
725
  }
732
- return str(entry.type);
726
+ return tsLiteral(entry.type);
733
727
  }
734
728
  function isResolvedConnectorOutput(row, triggerId, resolved) {
735
729
  if (!resolved || row.elementId !== triggerId)
@@ -753,7 +747,7 @@ function producedVariableNames(plan) {
753
747
  continue;
754
748
  for (const lane of node.data?.tasks ?? [])
755
749
  for (const task of lane)
756
- if (TASK_KIND_METHOD[task.type])
750
+ if (ownEntry(TASK_KIND_METHOD, task.type))
757
751
  for (const row of task.data?.outputs ?? [])
758
752
  if (row.var)
759
753
  produced.add(row.var);
@@ -776,10 +770,10 @@ function emitVariables(out, depth, plan, triggerNameById) {
776
770
  continue;
777
771
  const body = variable.body ?? variable._jsonSchema;
778
772
  const type = variable.type === 'jsonSchema' && body !== undefined
779
- ? `jsonSchema(${literal(body)})`
780
- : str(variable.type);
781
- const defaultValue = variable.default !== undefined ? `, ${literal(variable.default)}` : '';
782
- out.line(depth, `.var(${str(variable.name)}, ${type}${defaultValue})`);
773
+ ? `jsonSchema(${tsLiteral(body)})`
774
+ : tsLiteral(variable.type);
775
+ const defaultValue = variable.default !== undefined ? `, ${tsLiteral(variable.default)}` : '';
776
+ out.line(depth, `.var(${tsLiteral(variable.name)}, ${type}${defaultValue})`);
783
777
  }
784
778
  }
785
779
  function triggerData(node) {
@@ -804,16 +798,16 @@ function bridgeRows(plan, triggerId, bag) {
804
798
  }
805
799
  function triggerSource(node, index, plan, refs) {
806
800
  const { label, description, bag } = triggerData(node);
807
- const name = label !== `Trigger ${index + 1}` ? str(label) : undefined;
801
+ const name = label !== `Trigger ${index + 1}` ? tsLiteral(label) : undefined;
808
802
  if (!bag?.serviceType || bag.serviceType === 'None')
809
- return `manualTrigger(${opts([['name', name], ['description', description ? str(description) : undefined]])})`;
803
+ return `manualTrigger(${opts([['name', name], ['description', description ? tsLiteral(description) : undefined]])})`;
810
804
  if (bag.serviceType === 'Intsvc.TimerTrigger' || bag.serviceType === 'timer') {
811
805
  if (bag.timerType !== undefined && bag.timerType !== 'timeCycle')
812
806
  throw new Error(`timer trigger "${label ?? node.id ?? index}" has unsupported timerType "${bag.timerType}".`);
813
807
  return `timerTrigger(${opts([
814
- ['every', bag.timeCycle !== undefined ? str(bag.timeCycle) : undefined],
808
+ ['every', bag.timeCycle !== undefined ? tsLiteral(bag.timeCycle) : undefined],
815
809
  ['name', name],
816
- ['description', description ? str(description) : undefined],
810
+ ['description', description ? tsLiteral(description) : undefined],
817
811
  ])})`;
818
812
  }
819
813
  if (bag.serviceType === 'Intsvc.EventTrigger') {
@@ -825,16 +819,16 @@ function triggerSource(node, index, plan, refs) {
825
819
  : undefined;
826
820
  const outputShape = outputs.length
827
821
  ? `{ ${outputs.map((row) => {
828
- const source = str(row.source ?? '');
822
+ const source = tsLiteral(row.source ?? '');
829
823
  const cell = row.type && row.type !== 'string'
830
- ? `{ source: ${source}, type: ${str(row.type)} }`
824
+ ? `{ source: ${source}, type: ${tsLiteral(row.type)} }`
831
825
  : source;
832
826
  return `${key(String(row.var ?? row.name ?? ''))}: ${cell}`;
833
827
  }).join(', ')} }`
834
828
  : undefined;
835
829
  return `eventTrigger(${opts([
836
830
  ['name', name],
837
- ['description', description ? str(description) : undefined],
831
+ ['description', description ? tsLiteral(description) : undefined],
838
832
  ['subscription', subscription],
839
833
  ['outputs', outputShape],
840
834
  ])})`;
@@ -866,7 +860,7 @@ function caseAppSource(config) {
866
860
  throw new Error(`caseAppConfig section "${section.title}" detail "${nested[0]}" is not primitive.`);
867
861
  return { id: section.id, title: section.title, details };
868
862
  });
869
- return literal({ summary: config.caseSummary, sections });
863
+ return tsLiteral({ summary: config.caseSummary, sections });
870
864
  }
871
865
  function refuseUnsupportedAuthoring(plan) {
872
866
  if (plan.metadata?.adhocCaseEndData !== undefined)
@@ -1152,7 +1146,7 @@ export function decompileWithDiagnostics(plan, options = {}) {
1152
1146
  });
1153
1147
  if (triggers.length)
1154
1148
  out.line(0, '');
1155
- out.line(0, `${preservation ? 'const caseDefinition =' : 'export default'} casePlan(${str(slugId(plan))})`);
1149
+ out.line(0, `${preservation ? 'const caseDefinition =' : 'export default'} casePlan(${tsLiteral(slugId(plan))})`);
1156
1150
  const depth = 1;
1157
1151
  // The declared grammar version first, mirroring the document's own key order
1158
1152
  // and emitted even when it equals this SDK's write version: preserving means
@@ -1167,14 +1161,14 @@ export function decompileWithDiagnostics(plan, options = {}) {
1167
1161
  if (schema.problem)
1168
1162
  out.line(depth, `// TODO: ${commentText(schema.problem)}`);
1169
1163
  if (plan.name !== undefined)
1170
- out.line(depth, `.name(${str(plan.name)})`);
1164
+ out.line(depth, `.name(${tsLiteral(plan.name)})`);
1171
1165
  if (plan.description !== undefined)
1172
- out.line(depth, `.description(${str(plan.description)})`);
1166
+ out.line(depth, `.description(${tsLiteral(plan.description)})`);
1173
1167
  if (metadata.caseIdentifier !== undefined) {
1174
1168
  const type = metadata.caseIdentifierType && metadata.caseIdentifierType !== 'constant'
1175
- ? `, ${str(metadata.caseIdentifierType)}`
1169
+ ? `, ${tsLiteral(metadata.caseIdentifierType)}`
1176
1170
  : '';
1177
- out.line(depth, `.identifier(${str(metadata.caseIdentifier)}${type})`);
1171
+ out.line(depth, `.identifier(${tsLiteral(metadata.caseIdentifier)}${type})`);
1178
1172
  }
1179
1173
  if (metadata.caseAppConfig !== undefined)
1180
1174
  out.line(depth, `.caseApp(${caseAppSource(metadata.caseAppConfig)})`);
@@ -1198,7 +1192,7 @@ export function decompileWithDiagnostics(plan, options = {}) {
1198
1192
  out.line(depth, '.build();');
1199
1193
  if (preservation) {
1200
1194
  out.line(0, '');
1201
- out.line(0, `export default preserveCaseJson(caseDefinition, ${literal(preservation)});`);
1195
+ out.line(0, `export default preserveCaseJson(caseDefinition, ${tsLiteral(preservation)});`);
1202
1196
  }
1203
1197
  const imports = ['casePlan', 'rule', 'manualTrigger', 'timerTrigger', 'eventTrigger', 'jsonSchema', 'escalation', 'toUser', 'toGroup'];
1204
1198
  if (preservation)
@@ -1210,7 +1204,7 @@ export function decompileWithDiagnostics(plan, options = {}) {
1210
1204
  .replace(/[\r\n]+/g, ' ')),
1211
1205
  ].join('\n')}\n\n`
1212
1206
  : '';
1213
- const source = `import { ${imports.join(', ')} } from ${str(options.importSpecifier ?? './case-sdk.js')};\n\n${diagnosticHeader}${out.toString()}\n`;
1207
+ const source = `import { ${imports.join(', ')} } from ${tsLiteral(options.importSpecifier ?? './case-sdk.js')};\n\n${diagnosticHeader}${out.toString()}\n`;
1214
1208
  return { source, diagnostics };
1215
1209
  }
1216
1210
  export function decompile(plan, options = {}) {
@@ -27,6 +27,7 @@
27
27
  * `elementId`); its `output` projects every Out-arg (default from the Out-arg's
28
28
  * `inputOutputs` companion).
29
29
  */
30
+ import { ownEntry } from '../core/own-entry.js';
30
31
  /** The fixed JobAttachment definition a `file` property `$ref`s into. */
31
32
  export const JOB_ATTACHMENT_DEFINITION = {
32
33
  type: 'object',
@@ -52,7 +53,7 @@ function propertyForVar(v) {
52
53
  }
53
54
  // Build in the platform's key order: type, format, title, default.
54
55
  const out = {};
55
- const tf = TYPE_FORMAT[type];
56
+ const tf = ownEntry(TYPE_FORMAT, type);
56
57
  if (tf) {
57
58
  out.type = tf.type;
58
59
  if (tf.format)
@@ -48,9 +48,7 @@
48
48
  */
49
49
  import { collectPreservation } from './decompile.js';
50
50
  import { applyPreservation } from './serialize.js';
51
- function clone(value) {
52
- return JSON.parse(JSON.stringify(value));
53
- }
51
+ import { jsonClone } from '../core/json-file.js';
54
52
  /** Stage labels in a document, in order. */
55
53
  function stageLabels(document) {
56
54
  return (document.nodes ?? [])
@@ -102,11 +100,11 @@ function warnOrphanedIdentities(preservation, edited, warn) {
102
100
  export function mergeCase(original, edited, options = {}) {
103
101
  const preservation = collectPreservation(original);
104
102
  if (!preservation)
105
- return clone(edited);
103
+ return jsonClone(edited);
106
104
  if (options.warn)
107
105
  warnOrphanedIdentities(preservation, edited, options.warn);
108
106
  // `applyPreservation` is what `compile` runs with the payload a source
109
107
  // carries. Handing it the ORIGINAL's payload and the EDITED graph is the whole
110
108
  // merge: same operation, different provenance.
111
- return applyPreservation(clone(edited), preservation, { overwrite: true });
109
+ return applyPreservation(jsonClone(edited), preservation, { overwrite: true });
112
110
  }
@@ -1414,7 +1414,7 @@ function emitCaseExit(c, i, ids, resolver) {
1414
1414
  }
1415
1415
  /** One `slaRules[]` entry: the deadline + its escalations. `id` (+ `displayName`
1416
1416
  * when named) is preallocated so a `sla-status-change` rule can reference it. */
1417
- function emitSla(sla, index, count, ids, resolver) {
1417
+ function emitSla(sla, index, count, _ids, resolver) {
1418
1418
  const displayName = sla.displayName ?? (index === count - 1 ? 'Default SLA' : `Conditional SLA ${count - index - 1}`);
1419
1419
  const out = {
1420
1420
  id: resolver.slaId.get(sla),