@uipath/maestro-builder-sdk 6.47.3 → 6.49.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,11 +1,13 @@
1
1
  /**
2
2
  * The document family's authoring types — Document Classify
3
- * (`uipath.document.classify`) and Dynamic Extract
4
- * (`uipath.ixp.extract-document-builder`) — and their kinds' entries in
3
+ * (`uipath.document.classify`), Dynamic Extract
4
+ * (`uipath.ixp.extract-document-builder`) and an IxP project's extractor
5
+ * (`uipath.ixp.<slug>.<versionId>-<folderKey>`) — and their kinds' entries in
5
6
  * `FlowActionSpecs`. Moved from core/actions.ts in Phase 4 of
6
7
  * docs/NODE_TYPE_ARCHITECTURE_DESIGN.md.
7
8
  */
8
9
  import type { Expr } from '../../../core/expr.js';
10
+ /** What `documentClassify()` takes: the document, and how to split and classify it. */
9
11
  export interface DocumentClassifyInputs {
10
12
  /** The document to classify — a file reference (`input('file')`, `out('fetch', 'fileRef')`, …). */
11
13
  fileRef: string | Expr;
@@ -16,6 +18,7 @@ export interface DocumentClassifyInputs {
16
18
  /** Model configuration overrides; omit for the platform defaults (gemini_2_5_flash). */
17
19
  modelConfig?: Record<string, unknown>;
18
20
  }
21
+ /** What `dynamicExtract()` takes: the document and the fields to extract from it. */
19
22
  export interface DynamicExtractInputs {
20
23
  /** The document to extract from — a file reference. */
21
24
  fileRef: string | Expr;
@@ -51,6 +54,99 @@ export interface DynamicExtractInputs {
51
54
  /** Model configuration overrides; omit for the platform defaults. */
52
55
  modelConfig?: Record<string, unknown>;
53
56
  }
57
+ /**
58
+ * Split an extractor's node type into the two GUIDs its tail packs.
59
+ *
60
+ * `uipath.ixp.<projectSlug>.<projectVersionId>-<folderKey>` — the version id is
61
+ * the `ixpDeployment` binding's `resourceKey` and the node's `model.id`; the
62
+ * folder key is `inputs.folderKey`. Returns `undefined` for a tail that is not
63
+ * exactly two uuids joined by `-`, which is how the two older spellings (a
64
+ * sanitized folder path, and the literal string `undefined`) are refused rather
65
+ * than mis-split.
66
+ *
67
+ * @internal Public for compatibility; not an authoring factory.
68
+ */
69
+ export declare function parseIxpProjectType(nodeType: string): {
70
+ slug: string;
71
+ versionId: string;
72
+ folderKey: string;
73
+ } | undefined;
74
+ /** What `ixpExtract()` takes: the IxP project's extractor, its identity on the tenant, and the document. */
75
+ export interface IxpExtractInputs {
76
+ /**
77
+ * The extractor's node type, verbatim from
78
+ * `uip maestro flow registry search -f "type:startsWith=uipath.ixp"` — e.g.
79
+ * `'uipath.ixp.invoiceixp-cef0d447-ixp.ff973488-5d89-8035-86ac-f980b4be6deb-c4359cde-55f0-4f0e-9322-c6cdce74ab4c'`.
80
+ *
81
+ * **Run `uip maestro flow registry pull --force` first.** `registry search`
82
+ * and `registry get` answer from a local cache (`~/.uipath/nodes/`), so
83
+ * without a pull you are reading whenever you last synced.
84
+ *
85
+ * Two GUIDs are packed in that tail — the project **version** id and the
86
+ * **folder** key — and both are read back out of it here, which is why
87
+ * nothing else has to be passed twice.
88
+ */
89
+ project: string;
90
+ /**
91
+ * The project's own name, as the tenant spells it — the slug, e.g.
92
+ * `'idp-benchmark---invoices-c735405a-ixp'`. It is
93
+ * `inputDefaults.modelName` in `registry get`, and the node carries it as
94
+ * both `modelName` and `projectName` (one value, two fields — the designer
95
+ * shows it in two disabled boxes).
96
+ *
97
+ * It cannot be recovered from {@link IxpExtractInputs.project}: the node type's slug is
98
+ * lower-cased and de-punctuated (`---` collapses to `-`), which does not
99
+ * invert.
100
+ */
101
+ modelName: string;
102
+ /**
103
+ * The deployment's display name, e.g. `'InvoiceIXP'` —
104
+ * `inputDefaults.model.modelDisplayName`. It becomes the node's
105
+ * `model.modelDisplayName` and the `ixpDeployment` binding's `name`.
106
+ */
107
+ name: string;
108
+ /**
109
+ * The folder the project is published in, e.g. `'Shared'` or
110
+ * `'Shared/uipath-maestro-flow/BillingDispute'` —
111
+ * `inputDefaults.folderName`. It becomes the binding's `folderPath` default
112
+ * and the definition's own `description`.
113
+ */
114
+ folderName: string;
115
+ /**
116
+ * The document to extract from — a whole **Flow Attachment** object, the same
117
+ * shape and the same two ways of referencing it as
118
+ * {@link SummarizeInputs.attachment}:
119
+ *
120
+ * ```ts
121
+ * flow('InvoiceIntake')
122
+ * .input({ invoiceFile: types.file })
123
+ * .step('extract', ixpExtract({ …, fileRef: out('start', 'invoiceFile') }))
124
+ * ```
125
+ *
126
+ * It is the node's only authored input, and the definition marks it
127
+ * `required` (with `modelName` and `folderKey`, which this factory fills in).
128
+ */
129
+ fileRef: Expr;
130
+ /** Pages to process, e.g. `'1-5'`. Empty (the default) means the whole document. */
131
+ pageRange?: string;
132
+ /** Pin a published version tag. Empty (the default) means the latest. */
133
+ versionTag?: string;
134
+ /**
135
+ * The folder's key CHAIN, when the project lives in a nested folder —
136
+ * `inputDefaults.model.folderPath`, a dot-joined path of ancestor folder keys
137
+ * (`<root>.<parent>.<folder>`). Defaults to the folder key alone, which is
138
+ * what the platform writes for a project published straight into `Shared`.
139
+ */
140
+ folderPath?: string;
141
+ /**
142
+ * A free-text note on the node. Off by default, deliberately: the definition
143
+ * does not declare it (so setting it draws a "sets an input its type does not
144
+ * declare" warning unless the emitted definition is widened in the same
145
+ * write, which this does), and it is empty in 114 of the 117 deployed nodes
146
+ * that carry it at all.
147
+ */
148
+ description?: string;
149
+ }
54
150
  declare module '../../../core/actions.js' {
55
151
  interface FlowActionSpecs {
56
152
  /** The spec {@link documentClassify} builds. */
@@ -61,5 +157,9 @@ declare module '../../../core/actions.js' {
61
157
  dynamicExtract: {
62
158
  inputs: DynamicExtractInputs;
63
159
  };
160
+ /** The spec {@link ixpExtract} builds. */
161
+ ixpExtract: {
162
+ inputs: IxpExtractInputs;
163
+ };
64
164
  }
65
165
  }
@@ -1 +1,39 @@
1
- export {};
1
+ // ─── Document extraction (uipath.ixp.*) ──────────────────────────────────────
2
+ //
3
+ // The platform's *Extract* node (that is its `display.canvasLabel`): it hands a
4
+ // document to a published IxP — Intelligent eXtraction Platform — project and
5
+ // reads the trained model's fields back. Every extractor on a tenant is its own
6
+ // node type, `uipath.ixp.<projectSlug>.<projectVersionId>-<folderKey>`, so the
7
+ // four identity fields below come from the tenant and are named exactly as the
8
+ // node names them.
9
+ //
10
+ // The type is RESOLVED, never constructed: three different spellings of that
11
+ // tail exist in the deployed corpus (the sanitized folder path, the literal
12
+ // string `undefined`, and today's version-id + folder-key pair), so copy the
13
+ // one `registry search` prints.
14
+ /**
15
+ * Split an extractor's node type into the two GUIDs its tail packs.
16
+ *
17
+ * `uipath.ixp.<projectSlug>.<projectVersionId>-<folderKey>` — the version id is
18
+ * the `ixpDeployment` binding's `resourceKey` and the node's `model.id`; the
19
+ * folder key is `inputs.folderKey`. Returns `undefined` for a tail that is not
20
+ * exactly two uuids joined by `-`, which is how the two older spellings (a
21
+ * sanitized folder path, and the literal string `undefined`) are refused rather
22
+ * than mis-split.
23
+ *
24
+ * @internal Public for compatibility; not an authoring factory.
25
+ */
26
+ export function parseIxpProjectType(nodeType) {
27
+ const rest = nodeType.startsWith('uipath.ixp.') ? nodeType.slice('uipath.ixp.'.length) : undefined;
28
+ if (!rest)
29
+ return undefined;
30
+ const dot = rest.lastIndexOf('.');
31
+ if (dot <= 0)
32
+ return undefined;
33
+ const slug = rest.slice(0, dot);
34
+ const tail = rest.slice(dot + 1);
35
+ const m = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i.exec(tail);
36
+ if (!m)
37
+ return undefined;
38
+ return { slug, versionId: m[1], folderKey: m[2] };
39
+ }
@@ -104,8 +104,8 @@ export declare function serializeWithSidecars(built: BuiltFlow, opts?: Serialize
104
104
  /**
105
105
  * The node type a typed action compiles to, when that type's definition is
106
106
  * bundled in `core-definitions.json`. `undefined` for a family whose definition
107
- * is built per tenant or per call (connector, ixpExtract) and for a spec this
108
- * SDK does not lower by kind.
107
+ * is built per tenant or per call (connector) and for a spec this SDK does not
108
+ * lower by kind.
109
109
  *
110
110
  * A registered kind (flow-node-registry.ts) is not listed: its type is the
111
111
  * registry's.
@@ -114,25 +114,6 @@ export declare function bundledActionNodeType(spec: {
114
114
  kind?: string;
115
115
  inputs?: any;
116
116
  } | undefined): string | undefined;
117
- /**
118
- * The definition serialize synthesizes for a kind that has no bundled one and
119
- * is not on the node-type registry: an `ixpExtract` step. Its node type carries
120
- * a tenant's key, so the SDK builds the definition per call, transcribed from
121
- * what `registry get` returns. `undefined` for every other kind (a bundled
122
- * family, a connector, a container, a registered kind — the published process
123
- * resources and the agent build theirs in nodes/process/flow/).
124
- *
125
- * The emit path builds its definition here, and `check` asks this same
126
- * definition whether the node has an error port (#1040), so the two cannot
127
- * disagree.
128
- *
129
- * Throws what the family's builder throws for an unusable spec (an
130
- * `ixpExtract` project that is not a node type).
131
- */
132
- export declare function perCallDefinition(spec: {
133
- kind?: string;
134
- inputs?: any;
135
- } | undefined): any | undefined;
136
117
  /**
137
118
  * The bundled definition of `nodeType` that `makeNode` resolves: the author's
138
119
  * exact `{ version }` when given, otherwise the pinned default (the first
package/dist/serialize.js CHANGED
@@ -6,10 +6,9 @@
6
6
  * resolved from the connector library (entry + v1def sidecar), matching what
7
7
  * the platform emits, so the result passes `uip maestro flow validate`.
8
8
  */
9
- import ixpDefinition from './core/ixp-definition.json' with { type: 'json' };
10
9
  import { BUNDLED_DEFINITIONS, bundledVersions } from './flow-definitions.js';
11
10
  import { LOOP_DEFAULT_VERSION, bodyUsesBreak, loopDeclaredInputs, loopHasInnerHandles, loopVersion, loopVersionRefusal } from './loop-version.js';
12
- import { Expr, toExpr, SCHEDULE_PRESETS, parseIxpProjectType, flatNameSegmentsOf, parallelFork } from './flow-sdk.js';
11
+ import { Expr, toExpr, SCHEDULE_PRESETS, flatNameSegmentsOf, parallelFork } from './flow-sdk.js';
13
12
  import { FlowAction, FlowTrigger } from './core/node-classes.js';
14
13
  import { connectorRawNodeRefusal } from './core/connector-raw-node.js';
15
14
  import { rawNodeInputProblem, registeredRawType } from './raw-node-advice.js';
@@ -120,176 +119,6 @@ const SUBFLOW_OUTPUT = {
120
119
  var: 'output',
121
120
  };
122
121
  /** The inline (autonomous) agent's node type — fixed, not per-instance. */
123
- /**
124
- * The parts every `uipath.ixp.*` definition shares, bundled verbatim from
125
- * `uip maestro flow registry get` (2026-07-31, after `registry pull --force`).
126
- *
127
- * Unlike rpa's and api-workflow's, an extractor's definition is MOSTLY generic:
128
- * three projects' definitions (`invoiceixp`, `idp-benchmark---invoices`,
129
- * `invoices-billing`) are byte-identical in `category`, `tags`, `sortOrder`,
130
- * `version`, `supportsErrorHandling`, `handleConfiguration`, `form`, `debug`,
131
- * `inputDefinition` and the 18.7 KB `outputDefinition` — and differ in exactly
132
- * five per-project places (`nodeType`, `description`, `display.label`,
133
- * `model.bindings`, `inputDefaults`), all of which `ixpExtractDef` builds from
134
- * the author's call. So the family costs one bundled template, not 13.
135
- *
136
- * **The one thing to know before re-recording it:** `registry get` answers from
137
- * a LOCAL CACHE (`~/.uipath/nodes/index.json`). Without
138
- * `uip maestro flow registry pull --force` first you get whenever you last
139
- * synced — which is how a stale copy of this file would claim `required:
140
- * ["fileRef"]` (the pre-pull answer) instead of the three the platform's
141
- * `ixp-node` validator actually enforces.
142
- */
143
- const IXP_DEF = ixpDefinition;
144
- /**
145
- * Build the definition for one published IxP project.
146
- *
147
- * The per-project half is derived, not asked for twice: the node type's tail
148
- * packs the project VERSION id (the binding's `resourceKey`, and the model
149
- * blob's `id`) and the FOLDER key, so the author passes the type once and those
150
- * two come out of it.
151
- *
152
- * `inputDefaults` matters more here than in the other per-instance families,
153
- * because the platform's own instance IS its defaults: measured on today's 1.0
154
- * nightly artifact, `node.inputs` equals `inputDefaults` verbatim with exactly
155
- * two edits — `fileRef` authored, and `model.modelName` forced non-empty (the
156
- * registry returns `null` for published/OOB deployments, and both `flow
157
- * validate` and Studio Web's property panel refuse that). So the emitter writes
158
- * the defaults and the node reads them back, rather than the two drifting.
159
- */
160
- function ixpExtractDef(spec) {
161
- const parts = parseIxpProjectType(spec.project);
162
- if (!parts) {
163
- throw new Error(`ixpExtract: "${spec.project}" is not a resolvable extractor node type. It must be `
164
- + `uipath.ixp.<slug>.<projectVersionId>-<folderKey> — copy it from `
165
- + `\`uip maestro flow registry pull --force && uip maestro flow registry search -f "type:startsWith=uipath.ixp"\`.`);
166
- }
167
- const { versionId, folderKey } = parts;
168
- const model = {
169
- id: versionId,
170
- // Authoring rule #1 in v1's own IxP reference: non-empty or the `ixp-node`
171
- // validator fails the flow and the designer's panel crashes destructuring it.
172
- modelName: spec.modelName,
173
- modelDisplayName: spec.name,
174
- folderKey,
175
- folderName: spec.folderName,
176
- // The folder's ancestor-key chain for a nested folder; the folder key alone
177
- // for one published straight into a root folder, which is what the platform
178
- // writes there.
179
- folderPath: spec.folderPath ?? folderKey,
180
- description: '',
181
- };
182
- return {
183
- nodeType: spec.project,
184
- version: IXP_DEF.version,
185
- category: IXP_DEF.category,
186
- tags: jsonClone(IXP_DEF.tags),
187
- // The platform's own definition describes an extractor by its FOLDER, and
188
- // the designer prints exactly this in the node's subtitle.
189
- description: `(${spec.folderName})`,
190
- sortOrder: IXP_DEF.sortOrder,
191
- supportsErrorHandling: IXP_DEF.supportsErrorHandling,
192
- display: {
193
- canvasLabel: IXP_DEF.canvasLabel,
194
- label: spec.name,
195
- description: `(${spec.folderName})`,
196
- icon: IXP_DEF.icon,
197
- },
198
- handleConfiguration: jsonClone(IXP_DEF.handleConfiguration),
199
- model: {
200
- ...jsonClone(IXP_DEF.model),
201
- bindings: {
202
- ...jsonClone(IXP_DEF.bindingsFrame),
203
- resourceKey: versionId,
204
- name: spec.name,
205
- values: [
206
- { name: 'name', propertyAttribute: 'name', default: spec.name },
207
- { name: 'folderPath', propertyAttribute: 'folderPath', default: spec.folderName },
208
- ],
209
- },
210
- },
211
- form: jsonClone(IXP_DEF.form),
212
- // A `description` the author asked for is DECLARED in the same write. The
213
- // registry's own copy carries `description` in `inputDefaults` and not in
214
- // `inputDefinition.properties` — lesson 42's gap, live on this family — so
215
- // emitting the input without this would flag our own output as setting an
216
- // undeclared input, which
217
- // is what v1's deployed artifacts do (measured: 1 warning on today's green
218
- // nightly file). The default is to emit no `description` at all, which is
219
- // why this is conditional and the definition otherwise stays byte-identical
220
- // to the platform's.
221
- inputDefinition: spec.description === undefined
222
- ? jsonClone(IXP_DEF.inputDefinition)
223
- : {
224
- ...jsonClone(IXP_DEF.inputDefinition),
225
- properties: { ...jsonClone(IXP_DEF.inputDefinition.properties), description: { type: 'string' } },
226
- },
227
- inputDefaults: {
228
- model,
229
- modelName: spec.modelName,
230
- ...(spec.description === undefined ? {} : { description: spec.description }),
231
- // `modelName` and `projectName` are ONE value in two fields: all three
232
- // measured definitions agree, and the designer shows it in two disabled
233
- // boxes (the IXP-model and Folder rows of the `ixp-model` form section).
234
- projectName: spec.modelName,
235
- versionTag: spec.versionTag ?? '',
236
- folderKey,
237
- folderName: spec.folderName,
238
- fileRef: '',
239
- pageRange: '',
240
- },
241
- outputDefinition: jsonClone(IXP_DEF.outputDefinition),
242
- debug: jsonClone(IXP_DEF.debug),
243
- };
244
- }
245
- /**
246
- * The `ixpDeployment` binding pair for one IxP project — the THIRD resource kind
247
- * this SDK emits, after `process` and `queue`.
248
- *
249
- * Same shape and same one-pair-per-resource rule as
250
- * {@link processResourceBindings}: keyed by `resource + resourceKey +
251
- * propertyAttribute`, so two steps extracting with the same project share one
252
- * pair rather than shadowing each other. `resourceKey` is the project VERSION
253
- * id, which is what the definition's `model.bindings.resourceKey` names.
254
- *
255
- * Measured on 48 of the 151 deployed IxP artifacts (and 3 of today's 4 green
256
- * ones): exactly these two entries, `name` defaulting to the deployment's
257
- * display name and `folderPath` to its folder — note `folderPath` here holds the
258
- * folder NAME, not the key chain that `inputs.model.folderPath` carries.
259
- */
260
- function ixpDeploymentBindings(spec, existing) {
261
- const found = (attr) => [...existing.values()].find((b) => b.resource === 'ixpDeployment' && b.resourceKey === spec.versionId && b.propertyAttribute === attr)?.id;
262
- const already = { name: found('name'), folderPath: found('folderPath') };
263
- if (already.name && already.folderPath) {
264
- return { ids: { name: already.name, folderPath: already.folderPath }, entries: [] };
265
- }
266
- const slug = spec.name.replace(/[^A-Za-z0-9]/g, '') || 'Ixp';
267
- let base = `b${slug.charAt(0).toUpperCase()}${slug.slice(1)}`;
268
- for (let n = 2; existing.has(`${base}Name`) || existing.has(`${base}FolderPath`); n++) {
269
- base = `b${slug.charAt(0).toUpperCase()}${slug.slice(1)}${n}`;
270
- }
271
- const ids = { name: `${base}Name`, folderPath: `${base}FolderPath` };
272
- return { ids, entries: [
273
- {
274
- id: ids.name,
275
- name: 'name',
276
- type: 'string',
277
- resource: 'ixpDeployment',
278
- resourceKey: spec.versionId,
279
- default: spec.name,
280
- propertyAttribute: 'name',
281
- },
282
- {
283
- id: ids.folderPath,
284
- name: 'folderPath',
285
- type: 'string',
286
- resource: 'ixpDeployment',
287
- resourceKey: spec.versionId,
288
- default: spec.folderName,
289
- propertyAttribute: 'folderPath',
290
- },
291
- ] };
292
- }
293
122
  /**
294
123
  * Declare a LIST operation's output as the ARRAY it is, when the ledger has
295
124
  * MEASURED that it is one ([#203](https://github.com/UiPath/flow-builder-sdk/issues/203)).
@@ -843,8 +672,8 @@ function describeDeclared(bindings) {
843
672
  /**
844
673
  * The node type a typed action compiles to, when that type's definition is
845
674
  * bundled in `core-definitions.json`. `undefined` for a family whose definition
846
- * is built per tenant or per call (connector, ixpExtract) and for a spec this
847
- * SDK does not lower by kind.
675
+ * is built per tenant or per call (connector) and for a spec this SDK does not
676
+ * lower by kind.
848
677
  *
849
678
  * A registered kind (flow-node-registry.ts) is not listed: its type is the
850
679
  * registry's.
@@ -855,28 +684,6 @@ export function bundledActionNodeType(spec) {
855
684
  default: return undefined;
856
685
  }
857
686
  }
858
- /**
859
- * The definition serialize synthesizes for a kind that has no bundled one and
860
- * is not on the node-type registry: an `ixpExtract` step. Its node type carries
861
- * a tenant's key, so the SDK builds the definition per call, transcribed from
862
- * what `registry get` returns. `undefined` for every other kind (a bundled
863
- * family, a connector, a container, a registered kind — the published process
864
- * resources and the agent build theirs in nodes/process/flow/).
865
- *
866
- * The emit path builds its definition here, and `check` asks this same
867
- * definition whether the node has an error port (#1040), so the two cannot
868
- * disagree.
869
- *
870
- * Throws what the family's builder throws for an unusable spec (an
871
- * `ixpExtract` project that is not a node type).
872
- */
873
- export function perCallDefinition(spec) {
874
- const s = spec?.inputs ?? {};
875
- switch (spec?.kind) {
876
- case 'ixpExtract': return ixpExtractDef(s);
877
- default: return undefined;
878
- }
879
- }
880
687
  /**
881
688
  * The bundled definition of `nodeType` that `makeNode` resolves: the author's
882
689
  * exact `{ version }` when given, otherwise the pinned default (the first
@@ -2421,11 +2228,6 @@ export function serialize(built, opts = {}) {
2421
2228
  function successPort(type) {
2422
2229
  if (type === NODE_TYPE.loop)
2423
2230
  return 'success';
2424
- // Every extractor's definition declares `success` (+ `error`, gated on
2425
- // `errorHandlingEnabled`) on the right — so the forward edge is `success`,
2426
- // as it is in all 151 deployed IxP instances.
2427
- if (type.startsWith('uipath.ixp.'))
2428
- return 'success';
2429
2231
  // connectors, the trigger, the merge join and the mock placeholder all expose
2430
2232
  // their forward edge on `output` (merge's definition declares exactly one
2431
2233
  // source handle, `output`; so does `core.logic.mock`, and all 74 archived
@@ -2623,9 +2425,10 @@ export function serialize(built, opts = {}) {
2623
2425
  // input (`*_NO_KEY`), and serialize alone emits what it always did.
2624
2426
  const prefix = entry.type.typeNamePrefix;
2625
2427
  const nodeType = prefix !== undefined ? def?.nodeType : impl.typeName;
2626
- if (prefix !== undefined && (typeof nodeType !== 'string' || !nodeType.startsWith(prefix))) {
2428
+ if (prefix !== undefined && (typeof nodeType !== 'string' || !nodeType.startsWith(prefix)
2429
+ || entry.type.typeNameMatches?.(nodeType) === false)) {
2627
2430
  throw new Error(`internal SDK error: ${where}: node type ${impl.typeName}@${version} supplied a definition for `
2628
- + `${JSON.stringify(nodeType)}, which is not a name under "${prefix}".`);
2431
+ + `${JSON.stringify(nodeType)}, which is not a name it owns under "${prefix}".`);
2629
2432
  }
2630
2433
  if (impl.definition === 'per-tenant') {
2631
2434
  // At a version the flow carries, the carried definition answers: the
@@ -2821,51 +2624,6 @@ export function serialize(built, opts = {}) {
2821
2624
  addEdge(scope, t, id);
2822
2625
  return [{ node: id, port: successPort(rc.nodeType) }];
2823
2626
  }
2824
- if (spec.kind === 'ixpExtract') {
2825
- const s = spec.inputs;
2826
- const def = perCallDefinition(spec); // ixpExtractDef: throws on an unparseable project
2827
- const { versionId } = parseIxpProjectType(s.project); // ixpExtractDef threw if it could not parse
2828
- // The bindings first: two steps on the same project share ONE pair, and
2829
- // the definition's `model.bindings.resourceKey` names the key they hang off.
2830
- const { entries } = ixpDeploymentBindings({ name: s.name, folderName: s.folderName, versionId }, resourceBindings);
2831
- for (const b of entries)
2832
- resourceBindings.set(b.id, b);
2833
- const id = stepUid(scope, step.name);
2834
- const node = makeNode(def.nodeType, id, step.name, { parentId, requestedVersion: step.options?.version, def });
2835
- // No node-level `model` — v1's authoring reference makes this rule #15 for
2836
- // this family ("Studio Web–authored .flow files never carry one"), and 151
2837
- // of 151 deployed instances agree. Same reason the rpa/pattern families
2838
- // delete theirs.
2839
- delete node.model;
2840
- // The instance IS the definition's defaults, with the file the author
2841
- // named. Every field the designer writes, in the platform's own order.
2842
- node.inputs = {
2843
- ...jsonClone(def.inputDefaults),
2844
- fileRef: renderValue(s.fileRef, scope.rename),
2845
- ...(s.pageRange === undefined ? {} : { pageRange: s.pageRange }),
2846
- };
2847
- // The instance's `outputs` is a FIXED four-field pair, not a copy of the
2848
- // definition's `outputDefinition` — which `makeNode` writes for every other
2849
- // family and which here would drag the 18.7 KB extraction schema onto the
2850
- // node. v1's authoring reference is explicit ("copying outputDefinition
2851
- // verbatim also validates, but drags in a schema blob the runtime does not
2852
- // need"), and today's green nightly artifact carries exactly this. Both
2853
- // halves are REQUIRED: `flow validate`'s `ixp-node` validator fails a node
2854
- // missing either one.
2855
- node.outputs = {
2856
- output: { name: 'output', type: 'object', source: '=this', var: 'output' },
2857
- error: {
2858
- type: 'object',
2859
- description: 'Error information if the node fails',
2860
- source: '=Error',
2861
- var: 'error',
2862
- },
2863
- };
2864
- scope.nodes.push(node);
2865
- for (const t of tails)
2866
- addEdge(scope, t, id);
2867
- return [{ node: id, port: successPort(def.nodeType) }];
2868
- }
2869
2627
  if (spec.kind === 'waitEvent') {
2870
2628
  if (!opts.library)
2871
2629
  throw new Error(`waitForEvent "${step.name}" needs a library (pass --library / set $FLOW_SDK_LIBRARY_JSON).`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.47.3",
3
+ "version": "6.49.0",
4
4
  "description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.uipath.com/maestro",
@@ -84,7 +84,6 @@
84
84
  "check:definitions": "node scripts/sync-core-definitions.mjs --check"
85
85
  },
86
86
  "dependencies": {
87
- "bpmn-auto-layout": "^1.3.0",
88
87
  "bpmn-moddle": "^9.0.4",
89
88
  "commander": "^14.0.0",
90
89
  "typescript": "^5.9.3"
@@ -93,5 +92,5 @@
93
92
  "@types/node": "^22.7.0",
94
93
  "esbuild": "^0.28.1"
95
94
  },
96
- "gitref": "fc36fa72238f803ed2de5a02dc8a42f6c5d3305d"
95
+ "gitref": "26a34eb76b8f2b38beabdbcf74ef965d2b24a8c4"
97
96
  }
@@ -1,2 +0,0 @@
1
- import { type CliExitCode } from '../cli-run.js';
2
- export declare function run(argv: string[]): Promise<CliExitCode>;
@@ -1,38 +0,0 @@
1
- /**
2
- * tidy-cli — lay out a semantic-only `.bpmn` (add the `bpmndi` diagram).
3
- *
4
- * Usage:
5
- * node --experimental-strip-types tidy-cli.js <file.bpmn> [-o out.bpmn]
6
- *
7
- * The SDK's serializer emits semantic-only BPMN (no diagram) because validation
8
- * is layout-independent. This step runs `bpmn-auto-layout` to synthesize a full
9
- * `bpmndi:BPMNDiagram` — a `BPMNShape` per node and a `BPMNEdge` per flow — so
10
- * the file imports into a visual canvas. The `uipath:*` extension payloads are
11
- * preserved. Overwrites the input unless `-o` is given.
12
- */
13
- import { resolve } from 'node:path';
14
- import { reportResult } from '../cli-result.js';
15
- import { readFileSync, writeFileSync } from 'node:fs';
16
- import { layoutProcess } from 'bpmn-auto-layout';
17
- import { finalizeBpmnXml } from './serialize.js';
18
- import { flagValue, runWhenInvokedDirectly } from '../cli-run.js';
19
- export async function run(argv) {
20
- if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
21
- console.error('usage: tidy <file.bpmn> [-o out.bpmn]');
22
- return 2;
23
- }
24
- const flags = new Set(['-o']);
25
- const input = argv.find((a, i) => !flags.has(a) && !flags.has(argv[i - 1]));
26
- if (!input) {
27
- console.error('tidy: missing <file.bpmn>');
28
- return 2;
29
- }
30
- const laidOut = finalizeBpmnXml(await layoutProcess(readFileSync(input, 'utf8')));
31
- const out = flagValue(argv, '-o') ?? input;
32
- writeFileSync(out, laidOut.endsWith('\n') ? laidOut : laidOut + '\n');
33
- const shapes = (laidOut.match(/BPMNShape/g) ?? []).length;
34
- console.log(`tidy: laid out ${out} (${shapes} shape(s))`);
35
- reportResult({ path: resolve(out), shapes });
36
- return 0;
37
- }
38
- runWhenInvokedDirectly(import.meta.url, 'tidy', run);