@uipath/maestro-builder-sdk 6.11.4 → 6.11.5

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.
package/dist/check.js CHANGED
@@ -8,6 +8,7 @@
8
8
  import { Expr, SCHEDULE_PRESETS, DELAY_PRESETS, VARIANT_OPERATION, parseIxpProjectType, flatNameOf, flatNameSegmentsOf, FLAT_SEP } from './flow-sdk.js';
9
9
  import { FlowNode } from './core/node-classes.js';
10
10
  import { isLookupToken, resolvedValue, unresolvedLookupMessage, } from './core/lookups.js';
11
+ import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
11
12
  import { EVENT_FILTER_OPERATORS, readEventFilter, eventFilterProblem } from './event-filters.js';
12
13
  import { extractRefs } from './core/expr-check.js';
13
14
  import { bindingSelfNameMessage, bindingUndeclaredMessage, undeclaredBinding } from './core/binding-messages.js';
@@ -145,20 +146,12 @@ function checkFlow(built, ancestors, opts = {}) {
145
146
  // form's ANSWER fields (plus `Action`), so a read of it is checked against the
146
147
  // form the author wrote rather than waved through (see HITL_READ_* below).
147
148
  const hitlForms = new Map();
148
- const apiWorkflows = new Map();
149
- const publishedFunctions = new Map();
150
- // Agentic-process step name → its call. Same reason as api-workflow's map: the
151
- // step publishes the job's output arguments and the only offline statement of
152
- // what those are is the step's own `returns`.
149
+ // Agentic-process step name → its call, for the form-field rules below. Its
150
+ // output READS go through OUTPUT_READ_RULES like every `returns` family.
153
151
  const agenticProcesses = new Map();
154
- // Published-agent step name → its call. Same reason again: the step publishes the
155
- // agent job's output arguments, and the only offline statement of what those are
156
- // is the step's own `returns`.
157
- const agents = new Map();
158
- // Inline-agent step name → its call. NOT the same reason: an inline agent's
159
- // contract is AUTHORED rather than looked up on a tenant, so a read outside the
160
- // declared `returns` is a mistake the compiler can be certain about.
161
- const inlineAgents = new Map();
152
+ // Step name → the read rule for its output, bound to its inputs. Filled from
153
+ // OUTPUT_READ_RULES for every kind whose inputs take a `returns`.
154
+ const outputReaders = new Map();
162
155
  const connectorSteps = new Map();
163
156
  // Subflow step name → the child flow it runs. A subflow's output is the
164
157
  // OBJECT of the child's declared outputs, so a read of it is checked against
@@ -434,11 +427,9 @@ function checkFlow(built, ancestors, opts = {}) {
434
427
  checkRpaWorkflow(s.name, s.spec.inputs, diags);
435
428
  if (s.spec.kind === 'apiWorkflow') {
436
429
  checkApiWorkflow(s.name, s.spec.inputs, diags);
437
- apiWorkflows.set(s.name, s.spec.inputs);
438
430
  }
439
431
  if (s.spec.kind === 'publishedFunction') {
440
432
  checkPublishedFunction(s.name, s.spec.inputs, diags);
441
- publishedFunctions.set(s.name, s.spec.inputs);
442
433
  }
443
434
  if (s.spec.kind === 'sendMessage' || s.spec.kind === 'waitForMessage'
444
435
  || s.spec.kind === 'conversationContext') {
@@ -456,14 +447,20 @@ function checkFlow(built, ancestors, opts = {}) {
456
447
  }
457
448
  if (s.spec.kind === 'agent') {
458
449
  checkAgent(s.name, s.spec.inputs, diags);
459
- agents.set(s.name, s.spec.inputs);
460
450
  }
461
451
  if (s.spec.kind === 'inlineAgent') {
462
452
  checkInlineAgent(s.name, s.spec.inputs, diags);
463
- inlineAgents.set(s.name, s.spec.inputs);
464
453
  }
465
454
  if (s.spec.kind === 'queueItem')
466
455
  checkQueueItem(s.name, s.spec.inputs, diags);
456
+ {
457
+ const rule = OUTPUT_READ_RULES[s.spec.kind];
458
+ if (typeof rule === 'function') {
459
+ const stepName = s.name;
460
+ const inputs = s.spec.inputs;
461
+ outputReaders.set(stepName, (field, rest, at, d) => rule(stepName, field, rest, inputs, at, d));
462
+ }
463
+ }
467
464
  if (s.spec.kind === 'documentClassify' || s.spec.kind === 'dynamicExtract') {
468
465
  const fr = s.spec.inputs.fileRef;
469
466
  const empty = fr === undefined || fr === null || (typeof fr === 'string' && fr.trim() === '');
@@ -1168,49 +1165,13 @@ function checkFlow(built, ancestors, opts = {}) {
1168
1165
  checkHitlRead(name, field, rest, form, step, diags);
1169
1166
  continue;
1170
1167
  }
1171
- // An API workflow publishes the job's output arguments, and the only offline
1172
- // statement of what those are is the step's own `returns`. A read of anything
1173
- // else is `undefined` on every rung and on the platform — and with no
1174
- // `returns` at all the node declares no output schema, so nothing downstream
1175
- // can tell a real field from a typo.
1176
- const apiwf = apiWorkflows.get(name);
1177
- if (apiwf) {
1178
- checkApiWorkflowRead(name, field, rest, apiwf, step, diags);
1179
- continue;
1180
- }
1181
- // A published function publishes its result the same way, and the same
1182
- // three read mistakes are decidable from the same place — so the reader is
1183
- // shared, with the family named in the codes.
1184
- const fn = publishedFunctions.get(name);
1185
- if (fn) {
1186
- checkPublishedFunctionRead(name, field, rest, fn, step, diags);
1187
- continue;
1188
- }
1189
- // An agentic process publishes its job's output arguments the same way, so
1190
- // the same three read mistakes are decidable from the same place.
1191
- const agentic = agenticProcesses.get(name);
1192
- if (agentic) {
1193
- checkAgenticProcessRead(name, field, rest, agentic, step, diags);
1194
- continue;
1195
- }
1196
- // A published agent publishes its job's output arguments the same way its
1197
- // three siblings do, so the same three read mistakes are decidable — with one
1198
- // extra that only this family has: a read whose CASE differs from the declared
1199
- // field. That used to be a live-only defect (the poll verb PascalCased the
1200
- // answer, flow-builder-sdk #122), so the wrong case was right live and wrong
1201
- // offline for a while. Now it is simply wrong, and worth naming as itself
1202
- // rather than as an unknown field.
1203
- const published = agents.get(name);
1204
- if (published) {
1205
- checkAgentRead(name, field, rest, published, step, diags);
1206
- continue;
1207
- }
1208
- // An inline agent's readable fields are exactly its declared `returns` — the
1209
- // node's `agentOutputVariables`, which is also what the engine's live path
1210
- // coerces the model's completion to. Nothing on a tenant to consult.
1211
- const inline = inlineAgents.get(name);
1212
- if (inline) {
1213
- checkInlineAgentRead(name, field, rest, inline, step, diags);
1168
+ // Every family that declares its output's fields — the author's `returns`, or
1169
+ // a shape the SDK fixes — has its read rule in OUTPUT_READ_RULES, keyed by
1170
+ // kind. A read outside the declared set is undefined on every rung and on
1171
+ // the platform, so it is refused here rather than at `flow debug`.
1172
+ const readOutput = outputReaders.get(name);
1173
+ if (readOutput) {
1174
+ readOutput(field, rest, step, diags);
1214
1175
  continue;
1215
1176
  }
1216
1177
  // A loop step exposes a fixed set of fields, and only those resolve at run
@@ -2815,6 +2776,175 @@ function checkPublishedFunctionRead(name, field, rest, spec, step, diags) {
2815
2776
  suggestion: `returns: { ${wanted}: 'string' }`,
2816
2777
  });
2817
2778
  }
2779
+ /**
2780
+ * The fields every HTTP response carries at the top of `output`, whatever the
2781
+ * API answered. `core.action.http`'s definition declares all three; the author's
2782
+ * `returns` describes what is INSIDE `body`, never beside it.
2783
+ */
2784
+ const HTTP_ENVELOPE_FIELDS = ['body', 'statusCode', 'headers'];
2785
+ /**
2786
+ * A read of an `http()` step's result.
2787
+ *
2788
+ * The response is an envelope — `{ body, statusCode, headers }` — and `returns`
2789
+ * declares the parsed JSON body's top-level fields, so a declared field is read
2790
+ * at `output.body.<field>` (`out('<step>', 'body.<field>')`). That nesting is the
2791
+ * one thing this family does not share with the process families, and it is
2792
+ * exactly where flow-builder-sdk#850's run went wrong: a branch kept reading
2793
+ * `output.currentDayForecast…` (the Azure Maps connector's path) after the step
2794
+ * became an Open-Meteo `http()`, passed `check` and `validate`, and faulted at
2795
+ * `flow debug` as `[400302]`.
2796
+ */
2797
+ function checkHttpRead(name, field, rest, spec, step, diags) {
2798
+ if (field === undefined)
2799
+ return; // `out('fetch')` — the whole response.
2800
+ if (field === 'error')
2801
+ return; // the failure envelope (managed http's error port).
2802
+ if (field !== 'output') {
2803
+ diags.push({
2804
+ level: 'error', code: 'HTTP_READ_NOT_OUTPUT', step,
2805
+ message: `HTTP step "${name}" publishes its response under "output", but "$vars.${name}.${field}" `
2806
+ + `(read in "${step}") asks for "${field}", which is undefined at run time.`,
2807
+ suggestion: `out('${name}', 'body.<field>')`,
2808
+ });
2809
+ return;
2810
+ }
2811
+ const [top, inner] = (rest ?? '').replace(/^\./, '').split('.');
2812
+ if (!top)
2813
+ return; // `$vars.<name>.output` — the whole envelope.
2814
+ const declared = Object.keys(spec?.returns ?? {});
2815
+ if (!HTTP_ENVELOPE_FIELDS.includes(top)) {
2816
+ // The commonest form: a declared body field read one level too high.
2817
+ const hoisted = declared.includes(top) ? top : undefined;
2818
+ const nearest = hoisted ?? nearestName(top, declared);
2819
+ diags.push({
2820
+ level: 'error', code: 'HTTP_READ_UNKNOWN_FIELD', step,
2821
+ message: `"$vars.${name}.output.${top}" (read in "${step}") is not a field of HTTP step "${name}"'s `
2822
+ + `response. An HTTP response publishes ${HTTP_ENVELOPE_FIELDS.map((f) => `"${f}"`).join(', ')}; `
2823
+ + `the fields \`returns\` declares live under "body"`
2824
+ + (hoisted ? `, so "${top}" is read as "$vars.${name}.output.body.${top}".` : '.')
2825
+ + ` A read outside that shape resolves to undefined and faults a gateway at run time.`,
2826
+ ...(nearest !== undefined ? { suggestion: `out('${name}', 'body.${nearest}')` } : {}),
2827
+ });
2828
+ return;
2829
+ }
2830
+ if (top !== 'body' || !inner)
2831
+ return; // `statusCode`, `headers`, or the whole body.
2832
+ if (declared.length === 0) {
2833
+ diags.push({
2834
+ level: 'error', code: 'HTTP_READ_WITHOUT_RETURNS', step,
2835
+ message: `"$vars.${name}.output.body.${inner}" (read in "${step}") reads a field of HTTP step "${name}"'s `
2836
+ + `response body, but the step declares no \`returns\` — so the node carries no body schema and nothing `
2837
+ + `can tell a real field from a typo. Only the API being called knows its body; declare the fields you read.`,
2838
+ suggestion: `returns: { ${inner}: 'string' }`,
2839
+ });
2840
+ return;
2841
+ }
2842
+ if (declared.includes(inner))
2843
+ return;
2844
+ const nearest = nearestName(inner, declared);
2845
+ diags.push({
2846
+ level: 'error', code: 'HTTP_READ_UNKNOWN_FIELD', step,
2847
+ message: `HTTP step "${name}" declares no body field "${inner}" (read as "$vars.${name}.output.body.${inner}" `
2848
+ + `in "${step}"). Its \`returns\` names: ${declared.join(', ')}. A read outside that set resolves to undefined.`,
2849
+ ...(nearest !== undefined ? { suggestion: `out('${name}', 'body.${nearest}')` } : {}),
2850
+ });
2851
+ }
2852
+ /**
2853
+ * The read rule the process-shaped families share: the result is published
2854
+ * under `output`, keyed by a known field list — the author's `returns`, or a
2855
+ * shape the SDK itself fixes. `declared: undefined` means "the author declared
2856
+ * nothing", which is its own mistake (`<PREFIX>_READ_WITHOUT_RETURNS`).
2857
+ */
2858
+ function checkDeclaredOutputRead(o) {
2859
+ const { prefix, what, name, field, rest, step, diags } = o;
2860
+ if (field === undefined || field === 'error')
2861
+ return;
2862
+ if (field !== 'output') {
2863
+ diags.push({
2864
+ level: 'error', code: `${prefix}_READ_NOT_OUTPUT`, step,
2865
+ message: `${what} "${name}" publishes its result under "output", but "$vars.${name}.${field}" `
2866
+ + `(read in "${step}") asks for "${field}", which is undefined at run time.`,
2867
+ suggestion: `out('${name}', '<field>')`,
2868
+ });
2869
+ return;
2870
+ }
2871
+ const wanted = (rest ?? '').replace(/^\./, '').split('.')[0];
2872
+ if (!wanted)
2873
+ return;
2874
+ if (o.declared === undefined) {
2875
+ diags.push({
2876
+ level: 'error', code: `${prefix}_READ_WITHOUT_RETURNS`, step,
2877
+ message: `"$vars.${name}.output.${wanted}" (read in "${step}") reads a field of ${what} "${name}"'s result, `
2878
+ + `but the step declares no \`returns\` — so the node carries no output schema and nothing can tell a `
2879
+ + `real field from a typo. ${o.withoutReturns}`,
2880
+ suggestion: `returns: { ${wanted}: 'string' }`,
2881
+ });
2882
+ return;
2883
+ }
2884
+ if (o.declared.includes(wanted))
2885
+ return;
2886
+ const nearest = nearestName(wanted, o.declared);
2887
+ diags.push({
2888
+ level: 'error', code: `${prefix}_READ_UNKNOWN_FIELD`, step,
2889
+ message: `${what} "${name}" declares no output "${wanted}" (read as "$vars.${name}.output.${wanted}" in `
2890
+ + `"${step}"). It publishes: ${o.declared.join(', ')}. A read outside that set resolves to undefined.`,
2891
+ ...(nearest !== undefined ? { suggestion: `out('${name}', '${nearest}')` } : {}),
2892
+ });
2893
+ }
2894
+ function checkRpaWorkflowRead(name, field, rest, spec, step, diags) {
2895
+ const declared = Object.keys(spec?.returns ?? {});
2896
+ checkDeclaredOutputRead({
2897
+ prefix: 'RPA', what: 'RPA process', name, field, rest, step, diags,
2898
+ declared: declared.length ? declared : undefined,
2899
+ withoutReturns: `The process's output arguments live on the tenant; declare the ones you read. `
2900
+ + `\`uip maestro flow registry get uipath.core.rpa-workflow.${spec?.key}\` shows what the platform `
2901
+ + `synthesizes for it.`,
2902
+ });
2903
+ }
2904
+ /**
2905
+ * A queue step publishes one of two shapes: a plain enqueue publishes the queue
2906
+ * ITEM's Orchestrator record (fixed, declared by the serializer from
2907
+ * `QUEUE_ITEM_RECORD_SCHEMA`), a `wait: true` publishes the processed result,
2908
+ * whose fields only the author's `returns` states.
2909
+ */
2910
+ function checkQueueItemRead(name, field, rest, spec, step, diags) {
2911
+ const waitReturns = Object.keys(spec?.returns ?? {});
2912
+ checkDeclaredOutputRead({
2913
+ prefix: 'QUEUE', what: spec?.wait ? 'Queue wait' : 'Queue item', name, field, rest, step, diags,
2914
+ declared: !spec?.wait
2915
+ ? Object.keys(QUEUE_ITEM_RECORD_SCHEMA.properties)
2916
+ : waitReturns.length ? waitReturns : undefined,
2917
+ withoutReturns: `What the consumer writes into the processed item's result is that automation's business; `
2918
+ + `declare the fields you read.`,
2919
+ });
2920
+ }
2921
+ /**
2922
+ * THE GATE (flow-builder-sdk#850). Each `returns`-bearing kind maps to the rule
2923
+ * that checks a read of its output, or to a stated reason it has none.
2924
+ *
2925
+ * Before this table each family's rule was wired by hand — a map filled in the
2926
+ * walk plus a branch in the `$vars` dispatch — and nothing tied "this family
2927
+ * takes `returns`" to "this family has a read rule". `http`, `rpaWorkflow` and
2928
+ * `queueItem` shipped without one, so a read of an undeclared field passed
2929
+ * `check` and `validate` and only faulted live. The type below is exhaustive
2930
+ * over the derived kinds: give a new family a `returns` and `tsc` refuses to
2931
+ * build until it lands here.
2932
+ */
2933
+ const OUTPUT_READ_RULES = {
2934
+ http: checkHttpRead,
2935
+ rpaWorkflow: checkRpaWorkflowRead,
2936
+ apiWorkflow: checkApiWorkflowRead,
2937
+ publishedFunction: checkPublishedFunctionRead,
2938
+ agenticProcess: checkAgenticProcessRead,
2939
+ agent: checkAgentRead,
2940
+ inlineAgent: checkInlineAgentRead,
2941
+ queueItem: checkQueueItemRead,
2942
+ script: {
2943
+ exempt: 'Not yet: only the field-map form of a script\'s `returns` gives a list to check against (the '
2944
+ + 'type form and the inferred form do not), and script is the most-used step, so its rule lands with '
2945
+ + 'its own false-positive sweep — flow-builder-sdk#855.',
2946
+ },
2947
+ };
2818
2948
  function checkApiWorkflowRead(name, field, rest, spec, step, diags) {
2819
2949
  if (field === undefined)
2820
2950
  return; // `out('call')` — the whole output object.
@@ -82,6 +82,16 @@ interface HttpInputsBase {
82
82
  * fields, and nothing downstream can tell a real field from a typo. Same rule,
83
83
  * and the same word, as
84
84
  * `rpaWorkflow`'s `returns`.
85
+ *
86
+ * **Where a declared field is read:** under `body`, never beside it. The
87
+ * response is an envelope — `{ body, statusCode, headers }` — and these are the
88
+ * body's fields, so `returns: { items: 'array' }` is read as
89
+ * `out('fetch', 'body.items')`, which is `$vars.fetch.output.body.items`.
90
+ * `$vars.fetch.output.items` is undefined at run time.
91
+ *
92
+ * @enforcedBy HTTP_READ_UNKNOWN_FIELD A read must be `output.body.<declared field>`,
93
+ * `output.statusCode` or `output.headers`.
94
+ * @enforcedBy HTTP_READ_WITHOUT_RETURNS Reading a body field requires declaring it here.
85
95
  */
86
96
  returns?: Record<string, ReturnFieldType>;
87
97
  /**
@@ -991,6 +1001,9 @@ export interface RpaWorkflowInputs {
991
1001
  * the fields here is the same thing the platform's own definition does when it
992
1002
  * can reach the process, and it is what lets a misspelled read be caught at
993
1003
  * `uip maestro flow check` instead of at run time.
1004
+ *
1005
+ * @enforcedBy RPA_READ_UNKNOWN_FIELD A read of the output must name a field declared here.
1006
+ * @enforcedBy RPA_READ_WITHOUT_RETURNS Reading a field off the result requires declaring it here.
994
1007
  */
995
1008
  returns?: Record<string, ReturnFieldType>;
996
1009
  }
@@ -2035,6 +2048,11 @@ export interface QueueItemInputs {
2035
2048
  * `wait: false` needs none: what it publishes is the queue ITEM's own
2036
2049
  * Orchestrator record (`Key`, `Status`, `Reference`, `SpecificContent`, …),
2037
2050
  * which is the same for every queue, so the serializer declares it for you.
2051
+ *
2052
+ * @enforcedBy QUEUE_READ_UNKNOWN_FIELD A read must name a field of the record
2053
+ * (`wait: false`) or of this `returns` (`wait: true`).
2054
+ * @enforcedBy QUEUE_READ_WITHOUT_RETURNS Reading a field off a `wait: true` result
2055
+ * requires declaring it here.
2038
2056
  */
2039
2057
  returns?: Record<string, ReturnFieldType>;
2040
2058
  }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The queue item's own Orchestrator record — the fields `core.action.queue.create`
3
+ * publishes, declared so a downstream read is checkable. Shared by the serializer
4
+ * (which declares it on the node) and `check` (which refuses a read outside it).
5
+ *
6
+ * Unlike an rpa process's output arguments, this shape is NOT per-tenant: it is
7
+ * Orchestrator's queue-item record, the same for every queue, so the author has
8
+ * nothing to declare and `returns` is not needed for a fire-and-forget enqueue.
9
+ * The dispatcher returns `env.Data` from `uip or queue-items add` verbatim, and
10
+ * these are the fields a real add answered with (pinned 2026-07-28 against
11
+ * `Shared/SupplierInvoices` on codereval; `gen-tests`' fixture for the node is the
12
+ * same list). Declaring the EVIDENCED fields and no more is PR 10's payload-schema
13
+ * pattern — an invented field would be #73's `firedAt` again.
14
+ */
15
+ export declare const QUEUE_ITEM_RECORD_SCHEMA: {
16
+ readonly type: "object";
17
+ readonly properties: {
18
+ readonly Id: {
19
+ readonly type: "number";
20
+ };
21
+ readonly Key: {
22
+ readonly type: "string";
23
+ };
24
+ readonly UniqueKey: {
25
+ readonly type: "string";
26
+ };
27
+ readonly Reference: {
28
+ readonly type: "string";
29
+ };
30
+ readonly Status: {
31
+ readonly type: "string";
32
+ };
33
+ readonly Priority: {
34
+ readonly type: "string";
35
+ };
36
+ readonly QueueDefinitionName: {
37
+ readonly type: "string";
38
+ };
39
+ readonly QueueDefinitionKey: {
40
+ readonly type: "string";
41
+ };
42
+ readonly CreationTime: {
43
+ readonly type: "string";
44
+ };
45
+ readonly StartProcessing: {
46
+ readonly type: "string";
47
+ };
48
+ readonly EndProcessing: {
49
+ readonly type: "string";
50
+ };
51
+ readonly Progress: {
52
+ readonly type: "string";
53
+ };
54
+ readonly ReviewStatus: {
55
+ readonly type: "string";
56
+ };
57
+ readonly DueDate: {
58
+ readonly type: "string";
59
+ };
60
+ readonly RiskSlaDate: {
61
+ readonly type: "string";
62
+ };
63
+ readonly DeferDate: {
64
+ readonly type: "string";
65
+ };
66
+ readonly Encrypted: {
67
+ readonly type: "boolean";
68
+ };
69
+ readonly SpecificContent: {
70
+ readonly type: "object";
71
+ };
72
+ readonly Output: {
73
+ readonly type: "object";
74
+ };
75
+ readonly OutputData: {
76
+ readonly type: "string";
77
+ };
78
+ readonly Analytics: {
79
+ readonly type: "object";
80
+ };
81
+ readonly AnalyticsData: {
82
+ readonly type: "string";
83
+ };
84
+ readonly ProcessingExceptionType: {
85
+ readonly type: "string";
86
+ };
87
+ readonly ProcessingExceptionReason: {
88
+ readonly type: "string";
89
+ };
90
+ readonly SecondsInPreviousAttempts: {
91
+ readonly type: "number";
92
+ };
93
+ readonly RetryNumber: {
94
+ readonly type: "number";
95
+ };
96
+ readonly CreatorJobKey: {
97
+ readonly type: "string";
98
+ };
99
+ readonly ExecutorJobKey: {
100
+ readonly type: "string";
101
+ };
102
+ readonly RobotKey: {
103
+ readonly type: "string";
104
+ };
105
+ };
106
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The queue item's own Orchestrator record — the fields `core.action.queue.create`
3
+ * publishes, declared so a downstream read is checkable. Shared by the serializer
4
+ * (which declares it on the node) and `check` (which refuses a read outside it).
5
+ *
6
+ * Unlike an rpa process's output arguments, this shape is NOT per-tenant: it is
7
+ * Orchestrator's queue-item record, the same for every queue, so the author has
8
+ * nothing to declare and `returns` is not needed for a fire-and-forget enqueue.
9
+ * The dispatcher returns `env.Data` from `uip or queue-items add` verbatim, and
10
+ * these are the fields a real add answered with (pinned 2026-07-28 against
11
+ * `Shared/SupplierInvoices` on codereval; `gen-tests`' fixture for the node is the
12
+ * same list). Declaring the EVIDENCED fields and no more is PR 10's payload-schema
13
+ * pattern — an invented field would be #73's `firedAt` again.
14
+ */
15
+ export const QUEUE_ITEM_RECORD_SCHEMA = {
16
+ type: 'object',
17
+ properties: {
18
+ Id: { type: 'number' },
19
+ Key: { type: 'string' },
20
+ UniqueKey: { type: 'string' },
21
+ Reference: { type: 'string' },
22
+ Status: { type: 'string' },
23
+ Priority: { type: 'string' },
24
+ QueueDefinitionName: { type: 'string' },
25
+ QueueDefinitionKey: { type: 'string' },
26
+ CreationTime: { type: 'string' },
27
+ StartProcessing: { type: 'string' },
28
+ EndProcessing: { type: 'string' },
29
+ Progress: { type: 'string' },
30
+ ReviewStatus: { type: 'string' },
31
+ DueDate: { type: 'string' },
32
+ RiskSlaDate: { type: 'string' },
33
+ DeferDate: { type: 'string' },
34
+ Encrypted: { type: 'boolean' },
35
+ SpecificContent: { type: 'object' },
36
+ Output: { type: 'object' },
37
+ OutputData: { type: 'string' },
38
+ Analytics: { type: 'object' },
39
+ AnalyticsData: { type: 'string' },
40
+ ProcessingExceptionType: { type: 'string' },
41
+ ProcessingExceptionReason: { type: 'string' },
42
+ SecondsInPreviousAttempts: { type: 'number' },
43
+ RetryNumber: { type: 'number' },
44
+ CreatorJobKey: { type: 'string' },
45
+ ExecutorJobKey: { type: 'string' },
46
+ RobotKey: { type: 'string' },
47
+ },
48
+ };
@@ -974,7 +974,7 @@ declare class StepList {
974
974
  * **Paginate until the API says stop**
975
975
  * ```ts
976
976
  * .var('page', types.number, 1)
977
- * .doWhile('paginate', js`$vars.fetch.output.hasNextPage === true`, (b) => b
977
+ * .doWhile('paginate', js`$vars.fetch.output.body.hasNextPage === true`, (b) => b
978
978
  * .step('fetch', http({ url: tmpl`https://api.example.test/items?page=${v('page')}`, method: 'GET', managed: false, returns: { hasNextPage: 'boolean' } }), {
979
979
  * updates: { page: js`$vars.page + 1` },
980
980
  * }), { limit: 50 })
package/dist/flow-sdk.js CHANGED
@@ -709,7 +709,7 @@ class StepList {
709
709
  * **Paginate until the API says stop**
710
710
  * ```ts
711
711
  * .var('page', types.number, 1)
712
- * .doWhile('paginate', js`$vars.fetch.output.hasNextPage === true`, (b) => b
712
+ * .doWhile('paginate', js`$vars.fetch.output.body.hasNextPage === true`, (b) => b
713
713
  * .step('fetch', http({ url: tmpl`https://api.example.test/items?page=${v('page')}`, method: 'GET', managed: false, returns: { hasNextPage: 'boolean' } }), {
714
714
  * updates: { page: js`$vars.page + 1` },
715
715
  * }), { limit: 50 })
package/dist/serialize.js CHANGED
@@ -27,6 +27,7 @@ import { migrateToSchemaVersion } from './migrate.js';
27
27
  import { FLOW_SCHEMA_VERSIONS } from './format-profile.js';
28
28
  import { resolveSchemaVersion } from './schema-version.js';
29
29
  import { prepareCommand } from './core/cli-spelling.js';
30
+ import { QUEUE_ITEM_RECORD_SCHEMA } from './core/queue-record.js';
30
31
  const HERE = dirname(fileURLToPath(import.meta.url));
31
32
  // core-definitions.json is an object keyed by "<nodeType>@<version>".
32
33
  const DEFS = JSON.parse(readFileSync(join(HERE, 'core-definitions.json'), 'utf8'));
@@ -2329,53 +2330,6 @@ function connectionResourceBindings(spec, existing) {
2329
2330
  });
2330
2331
  return { entries };
2331
2332
  }
2332
- /**
2333
- * The queue item's own Orchestrator record — the fields `core.action.queue.create`
2334
- * publishes, declared so a downstream read is checkable.
2335
- *
2336
- * Unlike an rpa process's output arguments, this shape is NOT per-tenant: it is
2337
- * Orchestrator's queue-item record, the same for every queue, so the author has
2338
- * nothing to declare and `returns` is not needed for a fire-and-forget enqueue.
2339
- * The dispatcher returns `env.Data` from `uip or queue-items add` verbatim, and
2340
- * these are the fields a real add answered with (pinned 2026-07-28 against
2341
- * `Shared/SupplierInvoices` on codereval; `gen-tests`' fixture for the node is the
2342
- * same list). Declaring the EVIDENCED fields and no more is PR 10's payload-schema
2343
- * pattern — an invented field would be #73's `firedAt` again.
2344
- */
2345
- const QUEUE_ITEM_RECORD_SCHEMA = {
2346
- type: 'object',
2347
- properties: {
2348
- Id: { type: 'number' },
2349
- Key: { type: 'string' },
2350
- UniqueKey: { type: 'string' },
2351
- Reference: { type: 'string' },
2352
- Status: { type: 'string' },
2353
- Priority: { type: 'string' },
2354
- QueueDefinitionName: { type: 'string' },
2355
- QueueDefinitionKey: { type: 'string' },
2356
- CreationTime: { type: 'string' },
2357
- StartProcessing: { type: 'string' },
2358
- EndProcessing: { type: 'string' },
2359
- Progress: { type: 'string' },
2360
- ReviewStatus: { type: 'string' },
2361
- DueDate: { type: 'string' },
2362
- RiskSlaDate: { type: 'string' },
2363
- DeferDate: { type: 'string' },
2364
- Encrypted: { type: 'boolean' },
2365
- SpecificContent: { type: 'object' },
2366
- Output: { type: 'object' },
2367
- OutputData: { type: 'string' },
2368
- Analytics: { type: 'object' },
2369
- AnalyticsData: { type: 'string' },
2370
- ProcessingExceptionType: { type: 'string' },
2371
- ProcessingExceptionReason: { type: 'string' },
2372
- SecondsInPreviousAttempts: { type: 'number' },
2373
- RetryNumber: { type: 'number' },
2374
- CreatorJobKey: { type: 'string' },
2375
- ExecutorJobKey: { type: 'string' },
2376
- RobotKey: { type: 'string' },
2377
- },
2378
- };
2379
2333
  /**
2380
2334
  * Build the definition for one queue-item node.
2381
2335
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.11.4",
3
+ "version": "6.11.5",
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",
@@ -92,5 +92,5 @@
92
92
  "@types/node": "^22.7.0",
93
93
  "esbuild": "^0.28.1"
94
94
  },
95
- "gitref": "8c18e5efb6f8dd4b2599f9591cabdff42feaf275"
95
+ "gitref": "db9c4cfda2ffb8c391dc11eb75786eda3c08edcb"
96
96
  }