@uipath/maestro-builder-sdk 6.47.3 → 6.48.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 +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.48.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",
@@ -93,5 +93,5 @@
93
93
  "@types/node": "^22.7.0",
94
94
  "esbuild": "^0.28.1"
95
95
  },
96
- "gitref": "fc36fa72238f803ed2de5a02dc8a42f6c5d3305d"
96
+ "gitref": "b5eb4fa503b9753a5f3aa2c851c3f00befb13bd1"
97
97
  }