@uipath/maestro-builder-sdk 6.18.9 → 6.19.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.
Files changed (111) hide show
  1. package/dist/api-index.md +185 -184
  2. package/dist/api-members.md +504 -473
  3. package/dist/bpmn/uipath-moddle.v1.json +5 -0
  4. package/dist/case/decompile-cli.js +2 -8
  5. package/dist/check.js +177 -650
  6. package/dist/core/actions.d.ts +119 -760
  7. package/dist/core/actions.js +0 -306
  8. package/dist/core/error-port.d.ts +6 -0
  9. package/dist/core/error-port.js +9 -0
  10. package/dist/core/node-classes.d.ts +4 -63
  11. package/dist/core/node-classes.js +0 -112
  12. package/dist/core/nodes/family.d.ts +36 -0
  13. package/dist/core/nodes/family.js +1 -0
  14. package/dist/core/nodes/node-type.d.ts +136 -0
  15. package/dist/core/nodes/node-type.js +1 -0
  16. package/dist/core/nodes/registry.d.ts +57 -0
  17. package/dist/core/nodes/registry.js +122 -0
  18. package/dist/core/nodes/versioned.d.ts +50 -0
  19. package/dist/core/nodes/versioned.js +46 -0
  20. package/dist/core/typed-raw-node.d.ts +13 -62
  21. package/dist/core/typed-raw-node.js +40 -154
  22. package/dist/decompile-cli.js +2 -9
  23. package/dist/decompile.js +92 -271
  24. package/dist/flow-definitions.d.ts +10 -0
  25. package/dist/flow-definitions.js +35 -0
  26. package/dist/flow-node-registry.d.ts +13 -0
  27. package/dist/flow-node-registry.js +19 -0
  28. package/dist/flow-node-type.d.ts +192 -0
  29. package/dist/flow-node-type.js +1 -0
  30. package/dist/flow-sdk.d.ts +7 -0
  31. package/dist/flow-sdk.js +8 -0
  32. package/dist/nodes/data-fabric/flow/check.d.ts +13 -0
  33. package/dist/nodes/data-fabric/flow/check.js +164 -0
  34. package/dist/nodes/data-fabric/flow/factories.d.ts +113 -0
  35. package/dist/nodes/data-fabric/flow/factories.js +134 -0
  36. package/dist/nodes/data-fabric/flow/family.d.ts +7 -0
  37. package/dist/nodes/data-fabric/flow/family.js +9 -0
  38. package/dist/nodes/data-fabric/flow/index.d.ts +8 -0
  39. package/dist/nodes/data-fabric/flow/index.js +8 -0
  40. package/dist/nodes/data-fabric/flow/raw.d.ts +32 -0
  41. package/dist/nodes/data-fabric/flow/raw.js +100 -0
  42. package/dist/nodes/data-fabric/flow/shared.d.ts +77 -0
  43. package/dist/nodes/data-fabric/flow/shared.js +174 -0
  44. package/dist/nodes/data-fabric/flow/spec.d.ts +238 -0
  45. package/dist/nodes/data-fabric/flow/spec.js +1 -0
  46. package/dist/nodes/data-fabric/flow/verbs.d.ts +29 -0
  47. package/dist/nodes/data-fabric/flow/verbs.js +239 -0
  48. package/dist/nodes/delay/flow/check.d.ts +16 -0
  49. package/dist/nodes/delay/flow/check.js +86 -0
  50. package/dist/nodes/delay/flow/factories.d.ts +28 -0
  51. package/dist/nodes/delay/flow/factories.js +38 -0
  52. package/dist/nodes/delay/flow/family.d.ts +3 -0
  53. package/dist/nodes/delay/flow/family.js +8 -0
  54. package/dist/nodes/delay/flow/index.d.ts +3 -0
  55. package/dist/nodes/delay/flow/index.js +3 -0
  56. package/dist/nodes/delay/flow/node-type.d.ts +13 -0
  57. package/dist/nodes/delay/flow/node-type.js +71 -0
  58. package/dist/nodes/delay/flow/spec.d.ts +43 -0
  59. package/dist/nodes/delay/flow/spec.js +16 -0
  60. package/dist/nodes/document/flow/factories.d.ts +27 -0
  61. package/dist/nodes/document/flow/factories.js +30 -0
  62. package/dist/nodes/document/flow/family.d.ts +3 -0
  63. package/dist/nodes/document/flow/family.js +7 -0
  64. package/dist/nodes/document/flow/index.d.ts +3 -0
  65. package/dist/nodes/document/flow/index.js +3 -0
  66. package/dist/nodes/document/flow/node-type.d.ts +14 -0
  67. package/dist/nodes/document/flow/node-type.js +150 -0
  68. package/dist/nodes/document/flow/spec.d.ts +65 -0
  69. package/dist/nodes/document/flow/spec.js +1 -0
  70. package/dist/nodes/mock/flow/factories.d.ts +51 -0
  71. package/dist/nodes/mock/flow/factories.js +47 -0
  72. package/dist/nodes/mock/flow/family.d.ts +3 -0
  73. package/dist/nodes/mock/flow/family.js +7 -0
  74. package/dist/nodes/mock/flow/index.d.ts +2 -0
  75. package/dist/nodes/mock/flow/index.js +2 -0
  76. package/dist/nodes/mock/flow/node-type.d.ts +11 -0
  77. package/dist/nodes/mock/flow/node-type.js +51 -0
  78. package/dist/nodes/script/flow/check.d.ts +19 -0
  79. package/dist/nodes/script/flow/check.js +49 -0
  80. package/dist/nodes/script/flow/factories.d.ts +14 -0
  81. package/dist/nodes/script/flow/factories.js +15 -0
  82. package/dist/nodes/script/flow/family.d.ts +3 -0
  83. package/dist/nodes/script/flow/family.js +8 -0
  84. package/dist/nodes/script/flow/index.d.ts +3 -0
  85. package/dist/nodes/script/flow/index.js +3 -0
  86. package/dist/nodes/script/flow/node-type.d.ts +7 -0
  87. package/dist/nodes/script/flow/node-type.js +125 -0
  88. package/dist/nodes/script/flow/spec.d.ts +52 -0
  89. package/dist/nodes/script/flow/spec.js +1 -0
  90. package/dist/nodes/transform/flow/check.d.ts +6 -0
  91. package/dist/nodes/transform/flow/check.js +229 -0
  92. package/dist/nodes/transform/flow/factories.d.ts +52 -0
  93. package/dist/nodes/transform/flow/factories.js +53 -0
  94. package/dist/nodes/transform/flow/family.d.ts +3 -0
  95. package/dist/nodes/transform/flow/family.js +8 -0
  96. package/dist/nodes/transform/flow/index.d.ts +3 -0
  97. package/dist/nodes/transform/flow/index.js +3 -0
  98. package/dist/nodes/transform/flow/node-type.d.ts +7 -0
  99. package/dist/nodes/transform/flow/node-type.js +244 -0
  100. package/dist/nodes/transform/flow/spec.d.ts +116 -0
  101. package/dist/nodes/transform/flow/spec.js +10 -0
  102. package/dist/raw-node-advice.d.ts +16 -0
  103. package/dist/raw-node-advice.js +36 -0
  104. package/dist/raw-node.d.ts +71 -0
  105. package/dist/raw-node.js +116 -0
  106. package/dist/registry/uip/launch.d.ts +11 -1
  107. package/dist/registry/uip/launch.js +50 -43
  108. package/dist/registry/uip/pipeline-front-door.d.ts +2 -0
  109. package/dist/registry/uip/pipeline-front-door.js +88 -0
  110. package/dist/serialize.js +138 -492
  111. package/package.json +2 -2
@@ -1,15 +1,5 @@
1
1
  import { splitConnectorNodeType, isTriggerDescriptor, } from './connectors.js';
2
2
  import { FlowAction, FlowTrigger } from './node-classes.js';
3
- /**
4
- * The operation `type` each variant node must carry — one of, and only.
5
- *
6
- * @internal Serializer plumbing; an author states the variant, not the mapping.
7
- */
8
- export const VARIANT_OPERATION = {
9
- map: 'map',
10
- filter: 'filter',
11
- 'group-by': 'groupBy',
12
- };
13
3
  // ─── Document extraction (uipath.ixp.*) ──────────────────────────────────────
14
4
  //
15
5
  // The platform's *Extract* node (that is its `display.canvasLabel`): it hands a
@@ -49,18 +39,6 @@ export function parseIxpProjectType(nodeType) {
49
39
  return undefined;
50
40
  return { slug, versionId: m[1], folderKey: m[2] };
51
41
  }
52
- // ─── Delay (core.logic.delay) ────────────────────────────────────────────────
53
- /**
54
- * The twelve durations the designer's dropdown offers. Purely an ENCODING
55
- * detail: a duration in this list ships as `timerPreset: '<duration>'` and any
56
- * other ships as `timerPreset: 'custom'` + `timerValue: '<duration>'`. Both
57
- * deploy and both wait the same length of time — the author never picks.
58
- * `core-definitions.test.ts` pins this list against the definition's own form.
59
- */
60
- export const DELAY_PRESETS = [
61
- 'PT5S', 'PT15S', 'PT30S', 'PT1M', 'PT5M', 'PT15M', 'PT30M',
62
- 'PT1H', 'PT6H', 'PT12H', 'P1D', 'P1W',
63
- ];
64
42
  // ── Built-in spec adapters ──────────────────────────────────────────────────
65
43
  // Every factory result IS a FlowAction/FlowTrigger instance (design §4.4 pass
66
44
  // 1), so `instanceof` can tell an SDK-owned construct from a raw literal. The
@@ -125,64 +103,6 @@ export function http(inputs) {
125
103
  }
126
104
  return builtinActionSpec({ kind: 'http', inputs });
127
105
  }
128
- /**
129
- * Declare an inline script action.
130
- *
131
- * @param inputs - The JavaScript body (`code`, which must `return`) and what it
132
- * returns (`returns`).
133
- * @returns An action spec to pass to `.step(name, …)`.
134
- */
135
- export function script(inputs) {
136
- return builtinActionSpec({ kind: 'script', inputs });
137
- }
138
- /**
139
- * Declare a Transform action — a chain of declarative operations over a
140
- * collection. Read the result downstream with `out('<step>')`.
141
- *
142
- * @remarks
143
- * For a node that does ONE thing, name the variant — the emitted `.flow` then
144
- * carries `core.action.transform.filter` and reads as `Filter` in the designer
145
- * instead of a generic `Transform`:
146
- *
147
- * ```ts
148
- * .step('bigOrders', transform({
149
- * variant: 'filter',
150
- * collection: v('orders'),
151
- * operations: [
152
- * { type: 'filter', filters: [{ field: 'amount', condition: 'greater_equal', value: 100 }] },
153
- * ],
154
- * }))
155
- * ```
156
- *
157
- * @example
158
- * **Filter a collection, then reshape what survives**
159
- * ```ts
160
- * .var('catalog', types.array, [
161
- * { title: 'Deep Learning', author: 'Goodfellow', difficulty: 9, pages: 800 },
162
- * { title: 'Information Theory', author: 'MacKay', difficulty: 7, pages: 540 },
163
- * ])
164
- * .step('curate', transform({
165
- * collection: v('catalog'),
166
- * operations: [
167
- * { type: 'filter', operation: 'and', filters: [
168
- * { field: 'difficulty', condition: 'greater_than', value: 5 },
169
- * { field: 'pages', condition: 'less_than', value: 600 },
170
- * ] },
171
- * { type: 'map', keepOriginalFields: false, mappings: [
172
- * { field: 'title', transformation: 'uppercase' },
173
- * { field: 'author' },
174
- * ] },
175
- * ],
176
- * }))
177
- * ```
178
- *
179
- * @param inputs - The `collection` to transform and the chain of `operations` to
180
- * run over it.
181
- * @returns An action spec to pass to `.step(name, …)`.
182
- */
183
- export function transform(inputs) {
184
- return builtinActionSpec({ kind: 'transform', inputs });
185
- }
186
106
  /**
187
107
  * Declare a human task — a step that pauses for a person to read some values,
188
108
  * fill others in, and press one of the outcome buttons.
@@ -374,81 +294,6 @@ export function batchTransform(inputs) {
374
294
  export function ixpExtract(inputs) {
375
295
  return builtinActionSpec({ kind: 'ixpExtract', inputs });
376
296
  }
377
- /**
378
- * Declare a delay — a step that pauses the flow for a fixed length of time and
379
- * then carries on.
380
- *
381
- * @remarks
382
- * A delay produces nothing: there is no `out('settle')` to read. It is a wait,
383
- * not a value.
384
- *
385
- * The node itself splits that one duration across two fields (`timerPreset`
386
- * holds it directly, or the literal `"custom"` with the real value in
387
- * `timerValue`); the serializer picks the encoding, so you state the wait once.
388
- *
389
- * @example
390
- * **Wait thirty seconds before carrying on**
391
- * ```ts
392
- * .step('settle', delay({ duration: 'PT30S' }))
393
- * ```
394
- *
395
- * @param inputs - How long to wait (`duration`), as an ISO-8601 duration.
396
- * @returns An action spec to pass to `.step(name, …)`.
397
- */
398
- export function delay(inputs) {
399
- // Key presence, not value shape: `{ duration: undefined }` picks the
400
- // duration arm and flows to check()'s DELAY_NO_DURATION diagnostic — the
401
- // factory only rejects picking BOTH arms or NEITHER.
402
- const hasDuration = 'duration' in inputs;
403
- const hasUntil = 'until' in inputs;
404
- if (hasDuration === hasUntil) {
405
- throw new Error("delay() takes exactly ONE of { duration } (an ISO-8601 duration, e.g. 'PT15M') or "
406
- + "{ until } (an ISO-8601 date-time, e.g. '2026-09-01T09:00:00Z').");
407
- }
408
- return builtinActionSpec({ kind: 'delay', inputs });
409
- }
410
- /**
411
- * Declare a PLACEHOLDER step — "a real node goes here later".
412
- *
413
- * @remarks
414
- * A mock takes **no inputs and publishes nothing**. It is a marker on the canvas
415
- * that keeps the graph wired and the flow deployable while one step is still
416
- * missing — not a stub that returns test data. `out('extractInvoice')` is
417
- * refused at compile time (`MOCK_HAS_NO_OUTPUT`) because it would read `null` at
418
- * run time, always.
419
- *
420
- * Say what belongs there in the step's own name and in the label the canvas
421
- * shows; the corpus's placeholders read like
422
- * `"Extract Invoice Fields (mock — IxP model not yet published)"`.
423
- *
424
- * ### Why there are no arguments (convention #191 — the family contract)
425
- *
426
- * The platform's `core.logic.mock@1.0.0` declares **no `inputDefinition`** and one
427
- * output whose `source` is the literal `"null"`. Measured over the 4,033 distinct
428
- * archived `.flow` artifacts: **74 mock instances in 62 flows, and 0 carrying a
429
- * fixture anywhere in the node** — 71 of them with `inputs: {}` or no `inputs`
430
- * key. The 3 exceptions carry free-text `placeholder` / `_placeholder` keys the
431
- * definition never declares, invented by agents on runs that scored 0.9 and 0.4.
432
- *
433
- * **This is NOT a local runner's `kind: 'mock'` test construct**, which returns a
434
- * baked fixture. They are different things that share
435
- * a name, and a `mock({ fixture })` surface would emit a node whose local
436
- * behaviour and deployed behaviour disagree silently — see
437
- * [#125](https://github.com/UiPath/flow-builder-sdk/issues/125). Nothing this SDK
438
- * emits opens that channel: an SDK-authored mock publishes `null` locally,
439
- * exactly as the platform does.
440
- *
441
- * @example
442
- * **Hold a step's place until the real node exists**
443
- * ```ts
444
- * .step('extractInvoice', mock()) // ← swap for the IxP node once the project exists
445
- * ```
446
- *
447
- * @returns An action spec to pass to `.step(name, …)`.
448
- */
449
- export function mock() {
450
- return builtinActionSpec({ kind: 'mock' });
451
- }
452
297
  /**
453
298
  * Invoke a deployed RPA (robotic process automation) workflow — a classic
454
299
  * UI-automation process, published to Orchestrator, run by a robot.
@@ -866,157 +711,6 @@ export function agent(inputs) {
866
711
  export function inlineAgent(inputs) {
867
712
  return builtinActionSpec({ kind: 'inlineAgent', inputs });
868
713
  }
869
- /**
870
- * Classify a document into a document type (`uipath.document.classify`). The
871
- * result publishes `ClassificationResult` — an array of typed classifications
872
- * with page ranges and confidences.
873
- *
874
- * @param inputs - The file reference and optional page range / split / model settings.
875
- * @returns An action spec to pass to `.step(name, …)`.
876
- */
877
- export function documentClassify(inputs) {
878
- return builtinActionSpec({ kind: 'documentClassify', inputs });
879
- }
880
- /**
881
- * Extract fields from a document with an INLINE schema — Dynamic Extract
882
- * (`uipath.ixp.extract-document-builder`), the newer of the two extraction
883
- * shapes. No deployed IXP project is referenced: the extraction schema rides
884
- * the node. The result publishes `ExtractionResult` (and `Taxonomy`).
885
- *
886
- * @param inputs - The file reference, the inline extraction schema, and
887
- * optional page range / model settings.
888
- * @returns An action spec to pass to `.step(name, …)`.
889
- */
890
- export function dynamicExtract(inputs) {
891
- return builtinActionSpec({ kind: 'dynamicExtract', inputs });
892
- }
893
- /**
894
- * Query entity records from Data Fabric (`core.datafabric.read`). The result
895
- * publishes to the step's `output`; downstream references re-fetch fresh data
896
- * at activation time (the engine re-runs the query rather than caching).
897
- *
898
- * @remarks
899
- * This node is **read-one AND query-many**, on its 1.4 definition: `resultMode:
900
- * 'multiple'` publishes the matching records under `output.results`, and the
901
- * platform renames the node "Query entity records" to say so. The SDK still
902
- * pins 1.0 — read-one — as the no-`{ version }` default, so passing
903
- * `resultMode` is what selects 1.4; see {@link DataFabricReadInputs.resultMode}.
904
- *
905
- * The native family covers all four CRUD verbs: this one,
906
- * {@link dataFabricCreate}, {@link dataFabricUpdate} and
907
- * {@link dataFabricDelete}. What it does NOT cover is get-by-id, a query row
908
- * limit, file record fields, and entity events — those are operations on the
909
- * SAME product reached through its Integration Service connector,
910
- * `uipath-uipath-dataservice` (the tenant displays it as **UiPath Data
911
- * Fabric**). So a flow that needs one of those still straddles two surfaces,
912
- * and the connector remains the one surface that covers everything:
913
- *
914
- * ```ts
915
- * .step('byId', connector('uipath-uipath-dataservice', 'get-entity-record-by-id',
916
- * { entityName: 'Contracts', recordId: input('id') }, { connection: 'df' }))
917
- * ```
918
- *
919
- * Get-by-id matters for long text. This node is a query even when it reads one
920
- * record by an `Id` filter, and a Data Service query returns a PREVIEW of a
921
- * long-text (`MULTILINE_MAX`) field: the first 10,000 characters plus
922
- * `...[Truncated]`, with no flag in the output. A 15,551-character value comes
923
- * back as 10,014 characters. When a field may exceed 10,000 characters, read
924
- * it with `get-entity-record-by-id`, which returns the whole value
925
- * (flow-builder-sdk#954).
926
- *
927
- * A connector operation's body fields come from the entity, so the library
928
- * cannot carry them: run `uip maestro registry prepare uipath-uipath-dataservice
929
- * get-entity-record-by-id -f entityName=<Entity>` first.
930
- * The routing table is in the `data-fabric.md` reference and the parent-field
931
- * loop in `connector-params.md` — cited by name rather than linked, because this
932
- * comment renders both into the flat corpus, where those files sit alongside
933
- * it, and onto the site, where each symbol is its own page and a relative
934
- * `./data-fabric` resolves to nothing.
935
- *
936
- * @param inputs - The entity, optional filter rows, result mode, and folder scope.
937
- * @returns An action spec to pass to `.step(name, …)`.
938
- */
939
- export function dataFabricRead(inputs) {
940
- return builtinActionSpec({ kind: 'dataFabricRead', inputs });
941
- }
942
- /**
943
- * Create an entity record in Data Fabric (`core.datafabric.create`). The new
944
- * record publishes to the step's `output`, so a following
945
- * {@link dataFabricUpdate} or {@link dataFabricDelete} can read its id.
946
- *
947
- * @remarks
948
- * `values` must name at least one column — the node's schema rejects an empty
949
- * field list rather than inserting a blank row, and `check` says so before the
950
- * platform does. Field names are the ENTITY's, so copy them from the scenario
951
- * or the tenant; nothing offline can tell a real column from a typo.
952
- *
953
- * The published `output` is the record as a query returns it, so a long-text
954
- * (`MULTILINE_MAX`) field longer than 10,000 characters comes back cut, with
955
- * `...[Truncated]` appended, even though the whole value was stored. Use the
956
- * value you passed in, or re-read the record with the connector's
957
- * `get-entity-record-by-id`, when the whole text is needed (flow-builder-sdk#954).
958
- *
959
- * See {@link dataFabricRead} for what the native family still does not cover
960
- * and which connector operation covers it.
961
- *
962
- * @param inputs - The entity, the columns the record starts with, and folder scope.
963
- * @returns An action spec to pass to `.step(name, …)`.
964
- */
965
- export function dataFabricCreate(inputs) {
966
- return builtinActionSpec({ kind: 'dataFabricCreate', inputs });
967
- }
968
- /**
969
- * Update an entity record in Data Fabric (`core.datafabric.update`). Target the
970
- * record by id or through an earlier {@link dataFabricRead} step; downstream
971
- * reads of this step observe the record AFTER the write.
972
- *
973
- * @remarks
974
- * `set` must write at least one column: an empty `set` is a no-op the platform
975
- * reports as success, so `check` rejects it.
976
- *
977
- * See {@link dataFabricRead} for what the native family still does not cover
978
- * and which connector operation covers it.
979
- *
980
- * @param inputs - The entity, the record selector, and the columns to write.
981
- * @returns An action spec to pass to `.step(name, …)`.
982
- */
983
- export function dataFabricUpdate(inputs) {
984
- assertOneRecordRef(inputs.record, 'dataFabricUpdate');
985
- return builtinActionSpec({ kind: 'dataFabricUpdate', inputs });
986
- }
987
- /**
988
- * Delete an entity record from Data Fabric (`core.datafabric.delete`). Target
989
- * the record by id or through an earlier {@link dataFabricRead} step, exactly
990
- * as {@link dataFabricUpdate} does.
991
- *
992
- * @remarks
993
- * A delete **publishes nothing** — its definition declares no output — so
994
- * `$vars.<step>.output` is undefined at run time and `check` rejects a read of
995
- * it. Take what you need off the read step that found the record, before the
996
- * delete.
997
- *
998
- * See {@link dataFabricRead} for what the native family still does not cover
999
- * and which connector operation covers it.
1000
- *
1001
- * @param inputs - The entity, the record selector, and folder scope.
1002
- * @returns An action spec to pass to `.step(name, …)`.
1003
- */
1004
- export function dataFabricDelete(inputs) {
1005
- assertOneRecordRef(inputs.record, 'dataFabricDelete');
1006
- return builtinActionSpec({ kind: 'dataFabricDelete', inputs });
1007
- }
1008
- /**
1009
- * `record` names exactly ONE of `{ byId }` / `{ fromRead }`. Both forms are
1010
- * optional properties on the same object type, so TypeScript alone cannot
1011
- * refuse `{}` — and an empty selector compiles into a write with no target.
1012
- */
1013
- function assertOneRecordRef(record, factory) {
1014
- const byId = record?.byId !== undefined;
1015
- const fromRead = typeof record?.fromRead === 'string';
1016
- if (byId === fromRead) {
1017
- throw new Error(`${factory}() targets exactly ONE of record: { byId } or record: { fromRead: '<step>' }.`);
1018
- }
1019
- }
1020
714
  /**
1021
715
  * Declare an Orchestrator QUEUE ITEM step.
1022
716
  *
@@ -25,3 +25,9 @@ export declare function definitionHasErrorPort(def: any): boolean;
25
25
  export declare function errorPortRefusal(stepName: string, def: any, o?: {
26
26
  bundled?: boolean;
27
27
  }): string;
28
+ /**
29
+ * The ONERROR_NO_ERROR_PORT sentence for a registered node type whose definition is
30
+ * built per tenant and which declares no error port (`errorPort: false`), so there
31
+ * is no definition to name. Shared with serialize, which throws it for the same node.
32
+ */
33
+ export declare function declaredErrorPortRefusal(stepName: string, typeName: string, version: string): string;
@@ -34,3 +34,12 @@ export function errorPortRefusal(stepName, def, o = {}) {
34
34
  + `handle the node does not have. Handle the failure downstream instead`
35
35
  + (o.bundled ? '.' : `, or pass the definition exactly as \`uip maestro flow registry get\` returns it.`);
36
36
  }
37
+ /**
38
+ * The ONERROR_NO_ERROR_PORT sentence for a registered node type whose definition is
39
+ * built per tenant and which declares no error port (`errorPort: false`), so there
40
+ * is no definition to name. Shared with serialize, which throws it for the same node.
41
+ */
42
+ export function declaredErrorPortRefusal(stepName, typeName, version) {
43
+ return `Step "${stepName}" is a ${typeName}@${version} node, which has no error port, so the edge would leave a `
44
+ + 'handle the node does not have. Handle the failure downstream instead.';
45
+ }
@@ -19,6 +19,10 @@
19
19
  *
20
20
  * Parity reference: `docs/FLOW_PARITY.md`.
21
21
  */
22
+ /**
23
+ * A diagnostic a node contributes during `check` — surfaced alongside the
24
+ * built-in rules with the same severities.
25
+ */
22
26
  export interface ContributionDiagnostic {
23
27
  /** Stable machine-readable code, SCREAMING_SNAKE by convention. */
24
28
  code: string;
@@ -177,66 +181,3 @@ export declare abstract class FlowResource extends FlowNode<never> {
177
181
  /** Always `'resource'` for an attached node. */
178
182
  get role(): 'resource';
179
183
  }
180
- /**
181
- * Place a node this SDK has no factory for, carrying its definition verbatim
182
- * (`uipath.exotic.thing@2.1` and the manifest the platform served for it).
183
- *
184
- * @remarks
185
- * This is the escape hatch the coverage plan requires: an unknown registry
186
- * definition is expressible without bypassing serializer invariants. The
187
- * serializer still owns the node's id, label, `typeVersion` and edge wiring; you
188
- * supply which definition and which inputs, exactly as a hand-written
189
- * {@link FlowAction} subclass would.
190
- *
191
- * It is also what `decompile` emits for a node type it cannot name, so a
192
- * round trip preserves the node's TYPE and VERSION instead of degrading it to a
193
- * placeholder:
194
- *
195
- * ```ts
196
- * .step('exotic', rawNode({
197
- * nodeType: 'uipath.exotic.thing',
198
- * version: '2.1',
199
- * manifest: exoticManifest, // exactly what `registry get` returned
200
- * inputs: { where: input('scope') },
201
- * }))
202
- * ```
203
- *
204
- * `manifest` must be a real definition — an exact copy of what the registry or
205
- * Workbench serves for that `nodeType@version`. It is not permission to invent
206
- * one: the platform resolves the node against its own catalog at run time, so a
207
- * hand-written manifest validates locally and fails on the tenant.
208
- *
209
- * Prefer a typed factory when one exists — it carries the family's checks, its
210
- * defaults, and its output contract, none of which a raw node can know.
211
- *
212
- * **Never for a connector.** A `uipath.connector.*` node type is refused by
213
- * `check` and `compile`: a raw node carries the author's inputs verbatim, so the
214
- * emitted node has no `inputs.detail` and no connection binding — `validate`
215
- * only warns ("Connector is not configured") and the run can never reach
216
- * Integration Service. Use {@link connector}, and `registry prepare` when
217
- * compile reports an input the static library does not carry; use
218
- * {@link onEvent} for a connector event trigger.
219
- *
220
- * **Prefer the typed factory** for a node type that has one: `check` warns
221
- * (`RAW_NODE_TYPED_FAMILY`), because `validate` cannot see an input the
222
- * registry definition does not declare. For a `core.datafabric.*` type, a key
223
- * the product never reads (an invented `_sortOptions` in place of `_sort`) is
224
- * an error at a version the SDK bundles (`RAW_NODE_UNKNOWN_INPUT`); the
225
- * canvas's snapshots, such as the `_entityFields` a related-path filter
226
- * needs, stay legal.
227
- *
228
- * @param spec - The definition to compile against, plus the node's inputs.
229
- * @returns A node to pass to `.step(...)`.
230
- */
231
- export declare function rawNode(spec: {
232
- /** The definition's `nodeType`, verbatim. */
233
- nodeType: string;
234
- /** The exact definition version; also becomes the node's `typeVersion`. */
235
- version: string;
236
- /** The complete node manifest, exactly as the platform serves it. */
237
- manifest: unknown;
238
- /** The node's `inputs`. `Expr` values render through the usual pipeline. */
239
- inputs?: Record<string, unknown>;
240
- /** Overrides for the node's `outputs`; rarely needed. */
241
- outputs?: Record<string, unknown>;
242
- }): FlowAction;
@@ -19,12 +19,6 @@
19
19
  *
20
20
  * Parity reference: `docs/FLOW_PARITY.md`.
21
21
  */
22
- /**
23
- * A diagnostic a node contributes during `check` — surfaced alongside the
24
- * built-in rules with the same severities.
25
- */
26
- import { connectorRawNodeRefusal } from './connector-raw-node.js';
27
- import { typedFamilyRawNodeWarning, dataFabricUnknownInputs } from './typed-raw-node.js';
28
22
  /**
29
23
  * The abstract root of every definition-backed node the builder can place.
30
24
  *
@@ -74,109 +68,3 @@ export class FlowResource extends FlowNode {
74
68
  return 'resource';
75
69
  }
76
70
  }
77
- /**
78
- * Place a node this SDK has no factory for, carrying its definition verbatim
79
- * (`uipath.exotic.thing@2.1` and the manifest the platform served for it).
80
- *
81
- * @remarks
82
- * This is the escape hatch the coverage plan requires: an unknown registry
83
- * definition is expressible without bypassing serializer invariants. The
84
- * serializer still owns the node's id, label, `typeVersion` and edge wiring; you
85
- * supply which definition and which inputs, exactly as a hand-written
86
- * {@link FlowAction} subclass would.
87
- *
88
- * It is also what `decompile` emits for a node type it cannot name, so a
89
- * round trip preserves the node's TYPE and VERSION instead of degrading it to a
90
- * placeholder:
91
- *
92
- * ```ts
93
- * .step('exotic', rawNode({
94
- * nodeType: 'uipath.exotic.thing',
95
- * version: '2.1',
96
- * manifest: exoticManifest, // exactly what `registry get` returned
97
- * inputs: { where: input('scope') },
98
- * }))
99
- * ```
100
- *
101
- * `manifest` must be a real definition — an exact copy of what the registry or
102
- * Workbench serves for that `nodeType@version`. It is not permission to invent
103
- * one: the platform resolves the node against its own catalog at run time, so a
104
- * hand-written manifest validates locally and fails on the tenant.
105
- *
106
- * Prefer a typed factory when one exists — it carries the family's checks, its
107
- * defaults, and its output contract, none of which a raw node can know.
108
- *
109
- * **Never for a connector.** A `uipath.connector.*` node type is refused by
110
- * `check` and `compile`: a raw node carries the author's inputs verbatim, so the
111
- * emitted node has no `inputs.detail` and no connection binding — `validate`
112
- * only warns ("Connector is not configured") and the run can never reach
113
- * Integration Service. Use {@link connector}, and `registry prepare` when
114
- * compile reports an input the static library does not carry; use
115
- * {@link onEvent} for a connector event trigger.
116
- *
117
- * **Prefer the typed factory** for a node type that has one: `check` warns
118
- * (`RAW_NODE_TYPED_FAMILY`), because `validate` cannot see an input the
119
- * registry definition does not declare. For a `core.datafabric.*` type, a key
120
- * the product never reads (an invented `_sortOptions` in place of `_sort`) is
121
- * an error at a version the SDK bundles (`RAW_NODE_UNKNOWN_INPUT`); the
122
- * canvas's snapshots, such as the `_entityFields` a related-path filter
123
- * needs, stay legal.
124
- *
125
- * @param spec - The definition to compile against, plus the node's inputs.
126
- * @returns A node to pass to `.step(...)`.
127
- */
128
- export function rawNode(spec) {
129
- return new RawNode(spec);
130
- }
131
- /** The {@link rawNode} implementation — a snapshot-backed contribution. */
132
- class RawNode extends FlowAction {
133
- spec;
134
- constructor(spec) {
135
- super();
136
- this.spec = spec;
137
- }
138
- /**
139
- * `check` surfaces the connector refusal as an error, a typed family as a
140
- * warning, and a Data Fabric key the product never reads as an error at a
141
- * bundled version (a warning at any other); `compile` throws the errors
142
- * (see {@link contribute}).
143
- */
144
- diagnostics() {
145
- const refusal = connectorRawNodeRefusal(this.spec.nodeType);
146
- if (refusal)
147
- return [{ code: 'RAW_NODE_CONNECTOR', severity: 'error', message: refusal }];
148
- const out = [];
149
- const unknown = dataFabricUnknownInputs(this.spec.nodeType, this.spec.version, this.spec.inputs);
150
- if (unknown)
151
- out.push({ code: 'RAW_NODE_UNKNOWN_INPUT', ...unknown });
152
- const typed = typedFamilyRawNodeWarning(this.spec.nodeType);
153
- if (typed)
154
- out.push({ code: 'RAW_NODE_TYPED_FAMILY', severity: 'warning', message: typed });
155
- return out;
156
- }
157
- contribute(context) {
158
- // compile does not run diagnostics(); refuse here too so the escape hatch
159
- // cannot emit an unconfigured connector node. (A Data Fabric key the
160
- // product never reads is refused by the serializer, for every contribution.)
161
- const refusal = connectorRawNodeRefusal(this.spec.nodeType);
162
- if (refusal)
163
- throw new Error(refusal);
164
- const version = context.requestedVersion ?? this.spec.version;
165
- if (context.requestedVersion !== undefined && context.requestedVersion !== this.spec.version) {
166
- // Versions are exact everywhere in this SDK: a contributor may not
167
- // substitute its own for an explicit request (design §2.6).
168
- throw new Error(`rawNode("${this.spec.nodeType}") carries version ${this.spec.version}, but the step requests `
169
- + `${context.requestedVersion}. Pass the manifest for the requested version, or drop { version }.`);
170
- }
171
- return {
172
- definition: {
173
- source: 'snapshot',
174
- nodeType: this.spec.nodeType,
175
- version,
176
- manifest: this.spec.manifest,
177
- },
178
- ...(this.spec.inputs !== undefined ? { inputs: this.spec.inputs } : {}),
179
- ...(this.spec.outputs !== undefined ? { outputs: this.spec.outputs } : {}),
180
- };
181
- }
182
- }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Node families — node types grouped under one owner (design §3, §4.4).
3
+ *
4
+ * A family is organizational: one directory, one CODEOWNERS line, one README for
5
+ * the developers who work on it, and one catalog of the diagnostic codes its types
6
+ * emit. Its only behaviour is `check`, for rules that need every placement of the
7
+ * family at once (a Data Fabric update whose `fromRead` names no read step). A
8
+ * family object is per artifact, like its node types: Flow's Data Fabric family and
9
+ * BPMN's are two families that may share a directory and nothing else.
10
+ */
11
+ import type { ArtifactContexts } from './node-type.js';
12
+ import type { AnyNodeType } from './versioned.js';
13
+ /** Every code a family may emit, with its severity and a one-line summary. */
14
+ export type DiagnosticCatalog = Readonly<Record<string, {
15
+ readonly severity: 'error' | 'warning';
16
+ readonly summary: string;
17
+ }>>;
18
+ /** One placed node of a family, as the family-level check sees it. */
19
+ export interface Placement<Spec = unknown> {
20
+ /** The step name the author gave the node. */
21
+ readonly step: string;
22
+ /** The registered kind. */
23
+ readonly kind: string;
24
+ readonly spec: Spec;
25
+ /** The version the node will be emitted at. */
26
+ readonly version: string;
27
+ }
28
+ export interface NodeFamily<Ctx extends ArtifactContexts> {
29
+ /** Stable id, e.g. `'data-fabric'`. Unique within the artifact's registry. */
30
+ readonly id: string;
31
+ readonly title: string;
32
+ readonly types: readonly AnyNodeType<Ctx>[];
33
+ readonly diagnostics: DiagnosticCatalog;
34
+ /** Rules over every placement of this family's types, after the per-node checks. */
35
+ check?(placements: readonly Placement[], ctx: Ctx['familyCheck']): void;
36
+ }
@@ -0,0 +1 @@
1
+ export {};