@uipath/maestro-builder-sdk 6.11.6 → 6.12.0

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.
@@ -1,4 +1,4 @@
1
- import { type BuiltBpmn } from './bpmn-sdk.js';
1
+ import { type BuiltBpmn, type BpmnNode, type BpmnVarDecl } from './bpmn-sdk.js';
2
2
  import type { Library } from '../core/library.js';
3
3
  import type { Bindings } from '../core/bindings.js';
4
4
  /** Optional wiring for connector service tasks. */
@@ -26,3 +26,67 @@ export declare function serialize(built: BuiltBpmn, opts?: BpmnSerializeOpts): P
26
26
  */
27
27
  export declare function finalizeBpmnXml(xml: string): string;
28
28
  export declare function processId(id: string): string;
29
+ /**
30
+ * The variable declarations a scope's output-bearing nodes imply.
31
+ *
32
+ * A connector's or typed node's output row names a variable the author never declared
33
+ * (`<id>_response`, `<id>_Error`). Studio Web carries a matching variable for every
34
+ * such row, and without it the canvas validator warns `MISSING_ROOT_VARIABLE`; declaring
35
+ * them keeps the artifact indistinguishable from a designed one. A SCRIPT task's
36
+ * `outputs` need it more than that: `uip maestro bpmn validate` does NOT treat a
37
+ * `BPMN.ScriptTask` row's `var` as a declaration — a `vars.<output>` read downstream is
38
+ * `VARIABLE_DOES_NOT_EXIST` on 1.202 and 1.203 alike (measured on a gateway condition
39
+ * reading a script's `confidence`) — so those rows get one too, typed `string` like the
40
+ * row itself. Author-declared names win: an explicit `.var()` for the same name is left
41
+ * exactly as written.
42
+ *
43
+ * Each derived declaration belongs to the node whose row fills it (`elementId`), the
44
+ * way the product declares a node's own outputs. `decompile` recognises exactly this
45
+ * shape (`derivedVariableIds`) and does not echo it, so the two sides stay a round trip.
46
+ */
47
+ export declare function implicitNodeVars(nodes: BpmnNode[], declared: BpmnVarDecl[]): BpmnVarDecl[];
48
+ /**
49
+ * The `resourceKey` each author-declared FOLDER binding should carry: the key of the
50
+ * connection it is the companion of.
51
+ *
52
+ * A `folderKey` binding is not a resource of its own. Every real export writes the
53
+ * pair as `ConnectionId` binding `{resourceKey: <connection>, default: <connection>}`
54
+ * and `folderKey` binding `{resourceKey: <connection>, default: <folder>}` — the folder
55
+ * is where the CONNECTION is resolved, so its resource key is the connection's. A
56
+ * binding declared through `.binding('f', { propertyAttribute: 'folderKey', value })`
57
+ * used to collapse `resourceKey` onto `value`, the folder's own key, and
58
+ * `uip maestro bpmn validate` reported `MISSING_BINDING` for it — on every process the
59
+ * run-6 agents authored against Data Fabric or Test Manager.
60
+ *
61
+ * Pairing comes from the nodes: a node whose context reads `=bindings.<c>` as its
62
+ * `connection` and `=bindings.<f>` as its `folderKey` pairs `f` with `c`. A folder no
63
+ * node pairs falls back to the only `ConnectionId` binding when there is exactly one.
64
+ * An explicit `resourceKey` on the declaration is never overridden.
65
+ */
66
+ export declare function folderCompanionKeys(built: BuiltBpmn, sink: Map<string, Record<string, unknown>>): Map<string, string>;
67
+ /**
68
+ * Where an unscoped PUBLIC declaration belongs at the top level of a process.
69
+ *
70
+ * Every real artifact agrees: across the 97 Studio Web exports and converter outputs
71
+ * measured (`research/bpmn-roundtrip/corpus/`, the run-6 `v1` arm), all 107 public
72
+ * `uipath:input` declarations are scoped to the process's manual START event and all
73
+ * 37 `uipath:output` declarations to the END event whose mapping writes them — none to
74
+ * the process. The engine does not need it (`BpmnDataManager.EvaluateProcessVariables`
75
+ * seeds every declaration into one variables scope by id, and an expression resolves
76
+ * `vars.<id>` there whatever the declaration's `elementId`), but the canvas, the
77
+ * entry-point derivation and the graders that read a process's contract do: a process
78
+ * input is "the start event's input". Until this, the SDK wrote the process id, which
79
+ * validated and ran and was the one placement nothing else on the platform produces —
80
+ * cluster D of docs/BPMN_AUTHORING_ERGONOMICS_DESIGN.md §1b.
81
+ *
82
+ * The rule, mirrored by `bpmn-decompile` so an unscoped declaration round-trips without
83
+ * an explicit `elementId`:
84
+ * - `input` → the one root start event with no event definition and no trigger,
85
+ * when there is exactly one; else the process.
86
+ * - `output` → the one root end event whose payload writes `var="<id>"`; else the one
87
+ * root end event, when there is exactly one; else the process.
88
+ * - `inputOutput` → the process (an internal variable is process-level state; the
89
+ * engine's debug variables report lists exactly those).
90
+ * An explicit `elementId` always wins, and `null` still means "write none".
91
+ */
92
+ export declare function publicDeclarationScope(nodes: BpmnNode[], processId: string): (v: BpmnVarDecl) => string;
@@ -104,13 +104,14 @@ export async function serialize(built, opts = {}) {
104
104
  // effect — then assemble the process extensionElements from the result.
105
105
  const flowElements = buildScope(ctx, built.nodes, built.flows);
106
106
  const processExt = [];
107
- const varsExt = buildVariablesExt(ctx, rootVars);
107
+ const varsExt = buildVariablesExt(ctx, rootVars, built.id, publicDeclarationScope(built.nodes, built.id));
108
108
  if (varsExt)
109
109
  processExt.push(varsExt);
110
110
  // Author-declared bindings first, then the ones connector wiring derived —
111
111
  // one `uipath:bindings` block either way, since the runtime reads one registry.
112
112
  // An author declaration wins on an id collision: it is the more specific intent.
113
113
  const declaredIds = new Set(built.bindings.map((b) => b.id));
114
+ const companionKey = folderCompanionKeys(built, ctx.bindingSink);
114
115
  const bindingRows = [
115
116
  ...built.bindings.map((b) => ({
116
117
  id: b.id,
@@ -118,7 +119,7 @@ export async function serialize(built, opts = {}) {
118
119
  type: 'string',
119
120
  resource: b.resource,
120
121
  resourceSubType: b.resourceSubType,
121
- resourceKey: b.resourceKey,
122
+ resourceKey: b.resourceKey ?? companionKey.get(b.id) ?? b.default,
122
123
  default: b.default,
123
124
  propertyAttribute: b.propertyAttribute,
124
125
  })),
@@ -286,6 +287,11 @@ function createNode(ctx, n) {
286
287
  return el;
287
288
  }
288
289
  const el = m.create(`bpmn:${cap(n.kind)}`, { id: n.id, name: n.name });
290
+ // Only the exception is written: BPMN's default is interrupting, and an
291
+ // `isInterrupting="true"` the author never asked for would change the bytes
292
+ // of every existing process.
293
+ if (n.kind === 'startEvent' && n.interrupting === false)
294
+ el.isInterrupting = false;
289
295
  attachExtensionPayload(ctx, el, n.payload);
290
296
  const def = eventDefinition(ctx, n.event);
291
297
  if (def)
@@ -326,6 +332,8 @@ function createNode(ctx, n) {
326
332
  context: n.context,
327
333
  contextRows: n.contextRows,
328
334
  inputs: n.inputs,
335
+ inputRows: n.inputRows,
336
+ spec: n.spec,
329
337
  typeVersion: n.typeVersion,
330
338
  inputSchema: n.inputSchema,
331
339
  outputVar: n.outputVar,
@@ -463,8 +471,12 @@ function createScriptTask(ctx, n) {
463
471
  // these as a sequence and both orders validate, but matching the product's
464
472
  // means an imported script task round-trips without a reordered diff, which
465
473
  // the brownfield `edit/*` eval tasks grade on.
474
+ //
475
+ // The VALUE is the node's, not a constant: it selects the runtime's result shape
476
+ // (v2+ wraps the return value, v1 spreads it), so stamping every script task `v3`
477
+ // silently changed what an imported v1 task's outputs resolved to.
466
478
  extensionElements: m.create('bpmn:ExtensionElements', {
467
- values: [mapping, m.create('uipath:ScriptVersion', { value: 'v3' })],
479
+ values: [mapping, m.create('uipath:ScriptVersion', { value: n.scriptVersion })],
468
480
  }),
469
481
  script: n.script,
470
482
  });
@@ -489,7 +501,13 @@ function createSubProcess(ctx, n) {
489
501
  if (n.triggeredByEvent)
490
502
  props.triggeredByEvent = true;
491
503
  const values = [];
492
- const varsExt = buildVariablesExt(ctx, [...n.variables, ...implicitNodeVars(n.nodes, n.variables)]);
504
+ // The ENCLOSING scopes' declarations count as taken too. Passing only the
505
+ // sub-process's own meant a script task inside it re-declared an output variable the
506
+ // root already declares — same id, twice in one document, which is the
507
+ // DUPLICATE_DOCUMENT_ID the emitter goes out of its way to avoid everywhere else
508
+ // (the XML parser drops the second element that reuses an id).
509
+ const enclosing = [...n.variables, ...[...ctx.varType.keys()].map((id) => ({ id }))];
510
+ const varsExt = buildVariablesExt(ctx, [...n.variables, ...implicitNodeVars(n.nodes, enclosing)], n.id);
493
511
  if (varsExt)
494
512
  values.push(varsExt);
495
513
  if (values.length)
@@ -594,27 +612,34 @@ function assignmentSource(value) {
594
612
  * The variable declarations a scope's output-bearing nodes imply.
595
613
  *
596
614
  * A connector's or typed node's output row names a variable the author never declared
597
- * (`<id>_response`, `<id>_Error`). The reference to one already RESOLVES without
598
- * this — the platform treats an output's `var` as a declaration — but Studio Web
599
- * also carries a matching root variable, and without it the canvas validator
600
- * warns `MISSING_ROOT_VARIABLE`. Declaring them keeps the artifact
601
- * indistinguishable from a designed one. Author-declared names win: an explicit
602
- * `.var()` for the same name is left exactly as written.
615
+ * (`<id>_response`, `<id>_Error`). Studio Web carries a matching variable for every
616
+ * such row, and without it the canvas validator warns `MISSING_ROOT_VARIABLE`; declaring
617
+ * them keeps the artifact indistinguishable from a designed one. A SCRIPT task's
618
+ * `outputs` need it more than that: `uip maestro bpmn validate` does NOT treat a
619
+ * `BPMN.ScriptTask` row's `var` as a declaration — a `vars.<output>` read downstream is
620
+ * `VARIABLE_DOES_NOT_EXIST` on 1.202 and 1.203 alike (measured on a gateway condition
621
+ * reading a script's `confidence`) — so those rows get one too, typed `string` like the
622
+ * row itself. Author-declared names win: an explicit `.var()` for the same name is left
623
+ * exactly as written.
624
+ *
625
+ * Each derived declaration belongs to the node whose row fills it (`elementId`), the
626
+ * way the product declares a node's own outputs. `decompile` recognises exactly this
627
+ * shape (`derivedVariableIds`) and does not echo it, so the two sides stay a round trip.
603
628
  */
604
- function implicitNodeVars(nodes, declared) {
629
+ export function implicitNodeVars(nodes, declared) {
605
630
  const taken = new Set(declared.map((v) => v.id));
606
631
  const out = [];
607
- const claim = (id) => {
632
+ const claim = (id, ownerId, type = 'object') => {
608
633
  if (!id || taken.has(id))
609
634
  return;
610
635
  taken.add(id);
611
- out.push({ id, name: id, type: 'object', direction: 'inputOutput' });
636
+ out.push({ id, name: id, type, direction: 'inputOutput', elementId: ownerId });
612
637
  };
613
638
  for (const n of nodes) {
614
639
  if (n.kind === 'connector') {
615
640
  const { response, error } = connectorOutputVars(n);
616
- claim(response);
617
- claim(error);
641
+ claim(response, n.id);
642
+ claim(error, n.id);
618
643
  }
619
644
  else if (n.kind === 'typed') {
620
645
  // Shared with the expression checker rather than repeated here. Repeating it is
@@ -623,25 +648,94 @@ function implicitNodeVars(nodes, declared) {
623
648
  // side vanishes from the recompiled process. Measured on a Slack connector —
624
649
  // `send_Error` was declared in the original and absent after the round trip.
625
650
  for (const varId of typedNodeDeclaredVars(n))
626
- claim(varId);
651
+ claim(varId, n.id);
627
652
  }
628
653
  else if (n.kind === 'connectorEvent' || n.kind === 'externalTask') {
629
654
  // Same reason as the typed and connector arms: the node's output rows
630
655
  // reference variables the process must declare, or the canvas validator
631
656
  // reports MISSING_ROOT_VARIABLE.
632
- claim(intsvcOutputVar(n));
657
+ claim(intsvcOutputVar(n), n.id);
633
658
  for (const varId of Object.keys(n.outputs ?? {}))
634
- claim(varId);
659
+ claim(varId, n.id);
635
660
  }
636
661
  else if (n.kind === 'startEvent' && n.trigger) {
637
662
  // A trigger's payload row writes a variable like any typed node's, so it
638
663
  // needs the same implicit declaration — without it the row references a
639
664
  // variable the process never declares (MISSING_ROOT_VARIABLE).
640
- claim(typedNodeOutputVar(n.id, n.trigger.type, n.trigger.outputVar));
665
+ claim(typedNodeOutputVar(n.id, n.trigger.type, n.trigger.outputVar), n.id);
666
+ }
667
+ else if (n.kind === 'scriptTask') {
668
+ // `object` (emitted as `json`), not `string`. Under the v3 contract a script
669
+ // returns `{ response: <whatever it returned> }`, so an output nobody declared
670
+ // holds arbitrary JSON — declaring a number or an object as `string` is the
671
+ // mis-declaration this fallback exists to avoid. An output the AUTHOR declared
672
+ // keeps its own type: `claim` skips an id already taken.
673
+ for (const varId of Object.keys(n.outputs))
674
+ claim(varId, n.id);
641
675
  }
642
676
  }
643
677
  return out;
644
678
  }
679
+ /**
680
+ * The `resourceKey` each author-declared FOLDER binding should carry: the key of the
681
+ * connection it is the companion of.
682
+ *
683
+ * A `folderKey` binding is not a resource of its own. Every real export writes the
684
+ * pair as `ConnectionId` binding `{resourceKey: <connection>, default: <connection>}`
685
+ * and `folderKey` binding `{resourceKey: <connection>, default: <folder>}` — the folder
686
+ * is where the CONNECTION is resolved, so its resource key is the connection's. A
687
+ * binding declared through `.binding('f', { propertyAttribute: 'folderKey', value })`
688
+ * used to collapse `resourceKey` onto `value`, the folder's own key, and
689
+ * `uip maestro bpmn validate` reported `MISSING_BINDING` for it — on every process the
690
+ * run-6 agents authored against Data Fabric or Test Manager.
691
+ *
692
+ * Pairing comes from the nodes: a node whose context reads `=bindings.<c>` as its
693
+ * `connection` and `=bindings.<f>` as its `folderKey` pairs `f` with `c`. A folder no
694
+ * node pairs falls back to the only `ConnectionId` binding when there is exactly one.
695
+ * An explicit `resourceKey` on the declaration is never overridden.
696
+ */
697
+ export function folderCompanionKeys(built, sink) {
698
+ const keyOf = new Map();
699
+ const connectionIds = [];
700
+ const isConnectionId = (attr) => String(attr ?? '').toLowerCase() === 'connectionid';
701
+ for (const b of built.bindings) {
702
+ const key = b.resourceKey ?? b.default;
703
+ if (key !== undefined)
704
+ keyOf.set(b.id, key);
705
+ if (isConnectionId(b.propertyAttribute))
706
+ connectionIds.push(b.id);
707
+ }
708
+ for (const b of sink.values()) {
709
+ const key = b.resourceKey ?? b.default;
710
+ if (key !== undefined && !keyOf.has(b.id))
711
+ keyOf.set(b.id, key);
712
+ if (isConnectionId(b.propertyAttribute) && !connectionIds.includes(b.id))
713
+ connectionIds.push(b.id);
714
+ }
715
+ const bindingId = (value) => typeof value === 'string' && value.startsWith('=bindings.') ? value.slice('=bindings.'.length) : undefined;
716
+ const pairs = new Map();
717
+ for (const n of allNodes(built.nodes)) {
718
+ if (n.kind !== 'typed')
719
+ continue;
720
+ const view = { ...n.context };
721
+ for (const row of n.contextRows ?? [])
722
+ view[row.name] = row.value ?? row.body;
723
+ const connection = bindingId(view.connection ?? view.connectionId);
724
+ const folder = bindingId(view.folderKey);
725
+ if (connection && folder && !pairs.has(folder))
726
+ pairs.set(folder, connection);
727
+ }
728
+ const out = new Map();
729
+ for (const b of built.bindings) {
730
+ if (String(b.propertyAttribute ?? '').toLowerCase() !== 'folderkey' || b.resourceKey !== undefined)
731
+ continue;
732
+ const companion = pairs.get(b.id) ?? (connectionIds.length === 1 ? connectionIds[0] : undefined);
733
+ const key = companion !== undefined ? keyOf.get(companion) : undefined;
734
+ if (key !== undefined)
735
+ out.set(b.id, key);
736
+ }
737
+ return out;
738
+ }
645
739
  /**
646
740
  * `uipath:retry` — a retry policy, as a sibling of the activity's mapping/activity
647
741
  * element rather than inside it, which is why it works on every activity kind.
@@ -700,8 +794,21 @@ function buildLoopCharacteristics(ctx, loop) {
700
794
  function defaultAttr(value, mappedType) {
701
795
  return mappedType === 'json' ? JSON.stringify(value) : String(value);
702
796
  }
703
- /** A `uipath:variables` extension element grouping declarations by direction. */
704
- function buildVariablesExt(ctx, vars) {
797
+ /**
798
+ * A `uipath:variables` extension element grouping declarations by direction.
799
+ *
800
+ * `ownerId` is the scope the block sits in — the process or sub-process id — and is
801
+ * what a declaration with no `elementId` of its own is written as belonging to. The
802
+ * product writes every scope-level variable that way, and `uip maestro bpmn validate`
803
+ * 1.203 refuses one without it (`ROOT_VARIABLE_MISSING_ELEMENT_ID`: "no expression can
804
+ * resolve it"); a declaration inside a sub-process is resolved by both 1.202 and 1.203
805
+ * only when it carries one (measured: `vars.decision` declared in the sub-process block
806
+ * was `VARIABLE_DOES_NOT_EXIST` until `elementId` named the sub-process). `null` means
807
+ * the author — in practice `decompile`, echoing an older export — wants none written.
808
+ */
809
+ function buildVariablesExt(ctx, vars, ownerId,
810
+ /** The default scope of a declaration the author left unscoped; the owner when absent. */
811
+ scopeOf = () => ownerId) {
705
812
  const { m } = ctx;
706
813
  if (!vars.length)
707
814
  return undefined;
@@ -711,7 +818,7 @@ function buildVariablesExt(ctx, vars) {
711
818
  id: v.id,
712
819
  name: v.name,
713
820
  type: mapType(v.type),
714
- elementId: v.elementId,
821
+ elementId: v.elementId === null ? undefined : (v.elementId ?? scopeOf(v)),
715
822
  default: v.default === undefined ? undefined : defaultAttr(v.default, mapType(v.type)),
716
823
  // Carried, never interpreted — a schema field this SDK does not model survives.
717
824
  body: schemaBody(ctx, v.schema),
@@ -728,6 +835,46 @@ function buildVariablesExt(ctx, vars) {
728
835
  props.output = groups.output;
729
836
  return m.create('uipath:Variables', props);
730
837
  }
838
+ /**
839
+ * Where an unscoped PUBLIC declaration belongs at the top level of a process.
840
+ *
841
+ * Every real artifact agrees: across the 97 Studio Web exports and converter outputs
842
+ * measured (`research/bpmn-roundtrip/corpus/`, the run-6 `v1` arm), all 107 public
843
+ * `uipath:input` declarations are scoped to the process's manual START event and all
844
+ * 37 `uipath:output` declarations to the END event whose mapping writes them — none to
845
+ * the process. The engine does not need it (`BpmnDataManager.EvaluateProcessVariables`
846
+ * seeds every declaration into one variables scope by id, and an expression resolves
847
+ * `vars.<id>` there whatever the declaration's `elementId`), but the canvas, the
848
+ * entry-point derivation and the graders that read a process's contract do: a process
849
+ * input is "the start event's input". Until this, the SDK wrote the process id, which
850
+ * validated and ran and was the one placement nothing else on the platform produces —
851
+ * cluster D of docs/BPMN_AUTHORING_ERGONOMICS_DESIGN.md §1b.
852
+ *
853
+ * The rule, mirrored by `bpmn-decompile` so an unscoped declaration round-trips without
854
+ * an explicit `elementId`:
855
+ * - `input` → the one root start event with no event definition and no trigger,
856
+ * when there is exactly one; else the process.
857
+ * - `output` → the one root end event whose payload writes `var="<id>"`; else the one
858
+ * root end event, when there is exactly one; else the process.
859
+ * - `inputOutput` → the process (an internal variable is process-level state; the
860
+ * engine's debug variables report lists exactly those).
861
+ * An explicit `elementId` always wins, and `null` still means "write none".
862
+ */
863
+ export function publicDeclarationScope(nodes, processId) {
864
+ const manualStarts = nodes.filter((n) => n.kind === 'startEvent' && n.event === undefined && n.trigger === undefined);
865
+ const ends = nodes.filter((n) => n.kind === 'endEvent');
866
+ return (v) => {
867
+ if (v.direction === 'input')
868
+ return manualStarts.length === 1 ? manualStarts[0].id : processId;
869
+ if (v.direction === 'output') {
870
+ const writers = ends.filter((e) => (e.payload?.outputRows ?? []).some((r) => r.var === v.id));
871
+ if (writers.length === 1)
872
+ return writers[0].id;
873
+ return ends.length === 1 ? ends[0].id : processId;
874
+ }
875
+ return processId;
876
+ };
877
+ }
731
878
  // ─── Small helpers ────────────────────────────────────────────────────────────
732
879
  function cap(s) {
733
880
  return s.charAt(0).toUpperCase() + s.slice(1);
@@ -108,11 +108,12 @@ export declare function registryTypeNames(): string[];
108
108
  * `FLOW_SDK_BPMN_REGISTRY_FALLBACK=0` to keep resolution snapshot-only.
109
109
  *
110
110
  * @param type - The extension type, e.g. `'Intsvc.UnifiedHttpRequest'`.
111
+ * @param inline - A spec supplied by the author, which is used as is.
111
112
  * @returns Its emission spec.
112
113
  * @throws If the type is in neither the snapshot nor the registry — which means a
113
114
  * typo, or no `uip` to ask.
114
115
  */
115
- export declare function registryType(type: string): RegistryTypeSpec;
116
+ export declare function registryType(type: string, inline?: RegistryTypeSpec): RegistryTypeSpec;
116
117
  /** True when the snapshot itself carries the type — no tenant needed to emit it. */
117
118
  export declare function isSnapshotType(type: string): boolean;
118
119
  /**
@@ -138,6 +139,7 @@ export declare function isSnapshotType(type: string): boolean;
138
139
  export declare const REGISTRY_GAPS: Record<string, {
139
140
  resourceSubType?: string;
140
141
  extraContext?: string[];
142
+ requiredContext?: string[];
141
143
  outputRowsFixed?: boolean;
142
144
  notEnforcedInputs?: string[];
143
145
  }>;
@@ -181,6 +183,29 @@ export interface TypedContextRow {
181
183
  /** The row's `required` attribute — 11 context rows in the corpus carry one. */
182
184
  required?: boolean;
183
185
  }
186
+ /**
187
+ * One `uipath:input` payload row spelled out — the `separateInputs` counterpart of
188
+ * {@link TypedContextRow}.
189
+ *
190
+ * `inputs` is a name→value record, so a row's `type` and `target` are derived: the
191
+ * registry's declaration when the type has one, else `json` for a structured value,
192
+ * `string` for a scalar, and the KEY as the target. A real artifact often carries what
193
+ * that cannot express — a connector's `<uipath:input name="start" type="string"
194
+ * value="0" target="query"/>` has a target that is not its name, and a type the
195
+ * registry does not declare. These rows carry their own.
196
+ */
197
+ export interface TypedInputRow {
198
+ /** Row name — the wire parameter name, e.g. `entityName` or `body`. */
199
+ name: string;
200
+ /** The row's type. Defaults to `string`; `json` rows carry their value in `body`. */
201
+ type?: string;
202
+ /** The `target` attribute — `path`, `query`, `body`, `file`, `bodyField`, … */
203
+ target?: string;
204
+ /** The `value` attribute, for a scalar row. Omitted entirely when absent. */
205
+ value?: string;
206
+ /** The row's CDATA body, for a `json` row — the value itself, or a string when the exact bytes matter. */
207
+ body?: unknown;
208
+ }
184
209
  export interface TypedOutputRow {
185
210
  /** Row name, e.g. `response` or `Error`. */
186
211
  name: string;
@@ -216,6 +241,8 @@ export interface TypedNodeInput {
216
241
  contextRows?: TypedContextRow[];
217
242
  /** The payload, shaped per the type's `inputPattern`. */
218
243
  inputs?: Record<string, unknown>;
244
+ /** Payload rows spelled out, replacing `inputs` — see {@link TypedInputRow}. */
245
+ inputRows?: TypedInputRow[];
219
246
  /** The `uipath:type` `version` attribute — see `ActivityNodeOpts.typeVersion`. */
220
247
  typeVersion?: string;
221
248
  /** The `uipath:inputSchema` body inside `uipath:context` — see `ActivityNodeOpts.inputSchema`. */
@@ -265,9 +292,13 @@ export interface TypedNodeInput {
265
292
  * what it had, breaks a byte-exact round-trip. `bpmn-decompile` sets this.
266
293
  */
267
294
  contextVerbatim?: boolean;
295
+ /** The type's emission spec, supplied inline — see `ActivityNodeOpts.spec`. */
296
+ spec?: RegistryTypeSpec;
268
297
  }
269
298
  /** The variable a typed node's output row writes, or `undefined` when it has none. */
270
- export declare function typedNodeOutputVar(id: string, type: string, outputVar?: string): string | undefined;
299
+ export declare function typedNodeOutputVar(id: string, type: string, outputVar?: string, inline?: RegistryTypeSpec): string | undefined;
300
+ /** `uipath:input` payload rows exactly as the caller spelled them, deriving nothing. */
301
+ export declare function verbatimInputRows(m: BpmnModdle, rows: TypedInputRow[]): El[];
271
302
  /**
272
303
  * Emit a registry-backed typed node.
273
304
  *
@@ -320,7 +351,7 @@ export declare function createExtensionPayload(m: BpmnModdle, type: string, rows
320
351
  * @param type - The extension type.
321
352
  * @returns Its fields that must be bound, with the target each binding needs.
322
353
  */
323
- export declare function bindingRequiredFields(type: string): RegistryContextField[];
354
+ export declare function bindingRequiredFields(type: string, inline?: RegistryTypeSpec): RegistryContextField[];
324
355
  /**
325
356
  * Required context fields the author left unset and the registry cannot default.
326
357
  *
@@ -332,7 +363,7 @@ export declare function bindingRequiredFields(type: string): RegistryContextFiel
332
363
  * @param context - The context values the author supplied.
333
364
  * @returns The names of required fields with no value and no default.
334
365
  */
335
- export declare function missingRequiredContext(type: string, context?: Record<string, unknown>): string[];
366
+ export declare function missingRequiredContext(type: string, context?: Record<string, unknown>, inline?: RegistryTypeSpec): string[];
336
367
  /**
337
368
  * Required PAYLOAD fields the author left unset.
338
369
  *
@@ -357,7 +388,7 @@ export declare function missingRequiredInputs(type: string, inputs?: Record<stri
357
388
  * genuinely does not spell (it writes `connection`). Reading both makes this
358
389
  * agree with the CLI instead of guessing on either side of it.
359
390
  */
360
- context?: Record<string, unknown>): string[];
391
+ context?: Record<string, unknown>, inline?: RegistryTypeSpec): string[];
361
392
  /**
362
393
  * Whether this type's required payload fields are UNSATISFIABLE on the wire.
363
394
  *
@@ -389,5 +420,5 @@ context?: Record<string, unknown>): string[];
389
420
  * @param type - The extension type.
390
421
  * @returns The required payload field names that cannot be expressed, or `[]`.
391
422
  */
392
- export declare function unsatisfiableRequiredInputs(type: string): string[];
423
+ export declare function unsatisfiableRequiredInputs(type: string, inline?: RegistryTypeSpec): string[];
393
424
  export {};