@uipath/maestro-builder-sdk 6.20.6 → 6.21.1
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/api-index.md +72 -72
- package/dist/api-members.md +143 -143
- package/dist/check.js +36 -186
- package/dist/core/actions.d.ts +0 -126
- package/dist/core/actions.js +0 -48
- package/dist/core/edit-distance.d.ts +8 -0
- package/dist/core/edit-distance.js +26 -0
- package/dist/core/nodes/node-type.d.ts +17 -2
- package/dist/core/typed-raw-node.js +0 -2
- package/dist/decompile.js +0 -31
- package/dist/flow-node-registry.js +2 -1
- package/dist/flow-node-type.d.ts +6 -0
- package/dist/flow-sdk.d.ts +6 -7
- package/dist/flow-sdk.js +16 -23
- package/dist/nodes/queue/flow/check.d.ts +35 -0
- package/dist/nodes/queue/flow/check.js +126 -0
- package/dist/nodes/queue/flow/factories.d.ts +49 -0
- package/dist/nodes/queue/flow/factories.js +50 -0
- package/dist/nodes/queue/flow/family.d.ts +3 -0
- package/dist/nodes/queue/flow/family.js +8 -0
- package/dist/nodes/queue/flow/index.d.ts +3 -0
- package/dist/nodes/queue/flow/index.js +3 -0
- package/dist/nodes/queue/flow/node-type.d.ts +8 -0
- package/dist/nodes/queue/flow/node-type.js +265 -0
- package/dist/nodes/queue/flow/spec.d.ts +92 -0
- package/dist/nodes/queue/flow/spec.js +1 -0
- package/dist/serialize.d.ts +7 -0
- package/dist/serialize.js +15 -162
- package/package.json +2 -2
- /package/dist/{core/queue-record.d.ts → nodes/queue/flow/record.d.ts} +0 -0
- /package/dist/{core/queue-record.js → nodes/queue/flow/record.js} +0 -0
|
@@ -12,8 +12,9 @@ import { dataFabricFlowFamily } from './nodes/data-fabric/flow/family.js';
|
|
|
12
12
|
import { delayFlowFamily } from './nodes/delay/flow/family.js';
|
|
13
13
|
import { documentFlowFamily } from './nodes/document/flow/family.js';
|
|
14
14
|
import { mockFlowFamily } from './nodes/mock/flow/family.js';
|
|
15
|
+
import { queueFlowFamily } from './nodes/queue/flow/family.js';
|
|
15
16
|
import { scriptFlowFamily } from './nodes/script/flow/family.js';
|
|
16
17
|
import { transformFlowFamily } from './nodes/transform/flow/family.js';
|
|
17
18
|
/** The families, in no significant order. Adding one is the whole of registering it. */
|
|
18
|
-
export const FLOW_NODE_FAMILIES = [dataFabricFlowFamily, delayFlowFamily, documentFlowFamily, mockFlowFamily, scriptFlowFamily, transformFlowFamily];
|
|
19
|
+
export const FLOW_NODE_FAMILIES = [dataFabricFlowFamily, delayFlowFamily, documentFlowFamily, mockFlowFamily, queueFlowFamily, scriptFlowFamily, transformFlowFamily];
|
|
19
20
|
export const FLOW_NODE_TYPES = new NodeTypeRegistry('flow', FLOW_NODE_FAMILIES, { hasBundledDefinition });
|
package/dist/flow-node-type.d.ts
CHANGED
|
@@ -75,6 +75,12 @@ export interface FlowSerializeContext {
|
|
|
75
75
|
} & Readonly<Record<string, unknown>>): void;
|
|
76
76
|
/** The bundled definition `<typeName>@<version>`, or undefined when the SDK does not ship it. */
|
|
77
77
|
definition(typeName: string, version: string): unknown;
|
|
78
|
+
/**
|
|
79
|
+
* The flow's bindings so far, by id — read-only. For a type that SHARES a
|
|
80
|
+
* binding with earlier steps on the same resource (a queue's name + folder
|
|
81
|
+
* pair) or must pick an id that is not taken; add entries through `bind`.
|
|
82
|
+
*/
|
|
83
|
+
readonly bindings: ReadonlyMap<string, Readonly<Record<string, unknown>>>;
|
|
78
84
|
}
|
|
79
85
|
/** What `deserialize` may ask of the decompiler, for one serialized node. */
|
|
80
86
|
export interface FlowDeserializeContext {
|
package/dist/flow-sdk.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export * from './nodes/data-fabric/flow/index.js';
|
|
|
22
22
|
export * from './nodes/delay/flow/index.js';
|
|
23
23
|
export * from './nodes/document/flow/index.js';
|
|
24
24
|
export * from './nodes/mock/flow/index.js';
|
|
25
|
+
export * from './nodes/queue/flow/index.js';
|
|
25
26
|
export * from './nodes/script/flow/index.js';
|
|
26
27
|
export * from './nodes/transform/flow/index.js';
|
|
27
28
|
export { resolveFlowRefs, resolveRefPath, hasFileRefs } from './ref-resolve.js';
|
|
@@ -863,13 +864,11 @@ declare class StepList {
|
|
|
863
864
|
* your handler), and it refuses at build time on a step whose node type has no
|
|
864
865
|
* error port.
|
|
865
866
|
*
|
|
866
|
-
* **A `.loop()` container takes one too.**
|
|
867
|
-
*
|
|
868
|
-
* carries the body's message in `detail` and the
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
* NOT — it declares an error variable and no error handle — so that one is
|
|
872
|
-
* refused by name, and its failures belong to the body step that can fail.
|
|
867
|
+
* **A `.loop()` or `.doWhile()` container takes one too.** Both definitions
|
|
868
|
+
* set `supportsErrorHandling: true`, and a body step's failure routes to the
|
|
869
|
+
* container: its envelope carries the body's message in `detail` and the
|
|
870
|
+
* failing body step's canvas label in `element`, and the instance completes rather than
|
|
871
|
+
* faulting.
|
|
873
872
|
*
|
|
874
873
|
* **A plain `http()` step is the trap worth knowing**: a 404 there is a
|
|
875
874
|
* SUCCESS with `statusCode: 404`, so the handler never runs — use
|
package/dist/flow-sdk.js
CHANGED
|
@@ -26,6 +26,7 @@ export * from './nodes/data-fabric/flow/index.js';
|
|
|
26
26
|
export * from './nodes/delay/flow/index.js';
|
|
27
27
|
export * from './nodes/document/flow/index.js';
|
|
28
28
|
export * from './nodes/mock/flow/index.js';
|
|
29
|
+
export * from './nodes/queue/flow/index.js';
|
|
29
30
|
export * from './nodes/script/flow/index.js';
|
|
30
31
|
export * from './nodes/transform/flow/index.js';
|
|
31
32
|
// `$ref`-split ingestion (design §5): decompile resolves local-file refs into
|
|
@@ -422,13 +423,11 @@ class StepList {
|
|
|
422
423
|
* your handler), and it refuses at build time on a step whose node type has no
|
|
423
424
|
* error port.
|
|
424
425
|
*
|
|
425
|
-
* **A `.loop()` container takes one too.**
|
|
426
|
-
*
|
|
427
|
-
* carries the body's message in `detail` and the
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
* NOT — it declares an error variable and no error handle — so that one is
|
|
431
|
-
* refused by name, and its failures belong to the body step that can fail.
|
|
426
|
+
* **A `.loop()` or `.doWhile()` container takes one too.** Both definitions
|
|
427
|
+
* set `supportsErrorHandling: true`, and a body step's failure routes to the
|
|
428
|
+
* container: its envelope carries the body's message in `detail` and the
|
|
429
|
+
* failing body step's canvas label in `element`, and the instance completes rather than
|
|
430
|
+
* faulting.
|
|
432
431
|
*
|
|
433
432
|
* **A plain `http()` step is the trap worth knowing**: a 404 there is a
|
|
434
433
|
* SUCCESS with `statusCode: 404`, so the handler never runs — use
|
|
@@ -468,25 +467,19 @@ class StepList {
|
|
|
468
467
|
i--;
|
|
469
468
|
}
|
|
470
469
|
const source = this.steps[i];
|
|
471
|
-
// A `.loop()`
|
|
472
|
-
//
|
|
473
|
-
//
|
|
474
|
-
//
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
// and no error HANDLE, so an edge would leave a handle the node does not
|
|
480
|
-
// have — the same shape as the agent `memory` handle that fails validate.
|
|
481
|
-
const containerPort = port === 'error' && source?.kind === 'loop';
|
|
470
|
+
// A container (`.loop()` or `.doWhile()`) is a legal source for the error
|
|
471
|
+
// port. Both definitions set `supportsErrorHandling: true`, and the platform
|
|
472
|
+
// routes it: a body step throwing inside a measured run left the instance
|
|
473
|
+
// Completed with the container's envelope published — `detail` the body's
|
|
474
|
+
// own message, `element` the canvas label of the body step that failed. `check` and
|
|
475
|
+
// `serialize` confirm the port against the bundled definition at the
|
|
476
|
+
// version the container emits (#1010).
|
|
477
|
+
const containerPort = port === 'error' && (source?.kind === 'loop' || source?.kind === 'doWhile');
|
|
482
478
|
if (!source || (source.kind !== 'action' && !containerPort)) {
|
|
483
479
|
throw new TypeError(`${called} leaves a port of the step BEFORE it, and ${source ? `the previous step is a ${source.kind}` : 'there is no previous step'}. `
|
|
484
480
|
+ `Write .step('fetch', http({…}))${called}`
|
|
485
|
-
+ (
|
|
486
|
-
|
|
487
|
-
+ 'would leave a handle the node does not have. Handle the failure inside the body instead.'
|
|
488
|
-
: ' — a branch, parallel, terminate or return has no port to leave from; a .loop() has one only for '
|
|
489
|
-
+ "'error'."));
|
|
481
|
+
+ ' — a branch, parallel, terminate or return has no port to leave from; a .loop() or .doWhile() has one '
|
|
482
|
+
+ "only for 'error'.");
|
|
490
483
|
}
|
|
491
484
|
const taken = attached.some((s) => (s.kind === 'stepToList' || s.kind === 'stepToRef') && s.port === port);
|
|
492
485
|
if (taken) {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Queue family's rules and their catalog. Moved from check.ts in Phase 4 of
|
|
3
|
+
* docs/NODE_TYPE_ARCHITECTURE_DESIGN.md; codes and messages are unchanged.
|
|
4
|
+
*/
|
|
5
|
+
import type { DiagnosticCatalog } from '../../../core/nodes/family.js';
|
|
6
|
+
import type { FlowCheckContext } from '../../../flow-node-type.js';
|
|
7
|
+
import type { QueueItemInputs } from './spec.js';
|
|
8
|
+
/** Every code the family reports, with the severity it reports it at. */
|
|
9
|
+
export declare const QUEUE_DIAGNOSTICS: DiagnosticCatalog;
|
|
10
|
+
/**
|
|
11
|
+
* Check a `queueItem(...)` call.
|
|
12
|
+
*
|
|
13
|
+
* WHAT THESE RULES CAN AND CANNOT SEE. Whether the queue exists, whether anything
|
|
14
|
+
* drains it, and what a consumer writes into a processed item's result all live on
|
|
15
|
+
* the tenant. So these cover the mistakes decidable from the call — plus the one
|
|
16
|
+
* mistake the PLATFORM decides and rejects at run time, which is worth catching
|
|
17
|
+
* here because its error arrives from Orchestrator as an HTTP 400 three layers
|
|
18
|
+
* away:
|
|
19
|
+
*
|
|
20
|
+
* - a missing/blank `queue`, `folderPath` or `key`. Without the first two
|
|
21
|
+
* nothing can resolve the node's `resourceBindings.name`, and without `key`
|
|
22
|
+
* nothing joins the node to its bindings — both read as engine errors rather
|
|
23
|
+
* than authoring ones.
|
|
24
|
+
* - a `key` that is not a GUID. The commonest form is passing the queue's NAME
|
|
25
|
+
* where its Orchestrator key belongs.
|
|
26
|
+
* - a NESTED `item`. Orchestrator answers "Property values must be simple (like
|
|
27
|
+
* numbers or text) and not complex or composite data types (like objects or
|
|
28
|
+
* arrays)" — a run-time 400 for something visible in the source.
|
|
29
|
+
* - a `priority` outside the three the node type offers. The platform normalizes
|
|
30
|
+
* an unknown one silently, so it is a wrong RESULT, not an error.
|
|
31
|
+
* - `returns` on a step that does not wait (there is nothing per-tenant to
|
|
32
|
+
* declare), and a `wait: true` step whose result nothing can read.
|
|
33
|
+
* - a non-ISO `dueDate` / `deferDate`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkQueueItem(inputs: QueueItemInputs | undefined, ctx: FlowCheckContext): void;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { commentText } from '../../../core/comment-text.js';
|
|
2
|
+
import { nearestName } from '../../../core/edit-distance.js';
|
|
3
|
+
import { Expr } from '../../../core/expr.js';
|
|
4
|
+
import { GUID_RE } from '../../../core/binding-messages.js';
|
|
5
|
+
/** Every code the family reports, with the severity it reports it at. */
|
|
6
|
+
export const QUEUE_DIAGNOSTICS = {
|
|
7
|
+
QUEUE_NO_NAME: { severity: 'error', summary: 'no queue name' },
|
|
8
|
+
QUEUE_NO_FOLDER: { severity: 'error', summary: 'no folderPath' },
|
|
9
|
+
QUEUE_NO_KEY: { severity: 'error', summary: 'no queue key' },
|
|
10
|
+
QUEUE_KEY_NOT_GUID: { severity: 'error', summary: 'the key is not an Orchestrator GUID' },
|
|
11
|
+
QUEUE_NO_ITEM: { severity: 'warning', summary: 'the item carries no data' },
|
|
12
|
+
QUEUE_ITEM_NOT_OBJECT: { severity: 'error', summary: 'the item is not an object' },
|
|
13
|
+
QUEUE_ITEM_FIELD_NOT_PRIMITIVE: { severity: 'error', summary: 'an item field is not a primitive' },
|
|
14
|
+
QUEUE_BAD_PRIORITY: { severity: 'error', summary: 'a priority the node type does not offer' },
|
|
15
|
+
QUEUE_BAD_DATE: { severity: 'error', summary: 'a date Orchestrator cannot read' },
|
|
16
|
+
QUEUE_RETURNS_WITHOUT_WAIT: { severity: 'warning', summary: 'returns without wait: true' },
|
|
17
|
+
QUEUE_READ_NOT_OUTPUT: { severity: 'error', summary: 'a read outside the step\'s output' },
|
|
18
|
+
QUEUE_READ_WITHOUT_RETURNS: { severity: 'error', summary: 'a field read off a wait result with no returns' },
|
|
19
|
+
QUEUE_READ_UNKNOWN_FIELD: { severity: 'error', summary: 'a read of a field the step does not publish' },
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Check a `queueItem(...)` call.
|
|
23
|
+
*
|
|
24
|
+
* WHAT THESE RULES CAN AND CANNOT SEE. Whether the queue exists, whether anything
|
|
25
|
+
* drains it, and what a consumer writes into a processed item's result all live on
|
|
26
|
+
* the tenant. So these cover the mistakes decidable from the call — plus the one
|
|
27
|
+
* mistake the PLATFORM decides and rejects at run time, which is worth catching
|
|
28
|
+
* here because its error arrives from Orchestrator as an HTTP 400 three layers
|
|
29
|
+
* away:
|
|
30
|
+
*
|
|
31
|
+
* - a missing/blank `queue`, `folderPath` or `key`. Without the first two
|
|
32
|
+
* nothing can resolve the node's `resourceBindings.name`, and without `key`
|
|
33
|
+
* nothing joins the node to its bindings — both read as engine errors rather
|
|
34
|
+
* than authoring ones.
|
|
35
|
+
* - a `key` that is not a GUID. The commonest form is passing the queue's NAME
|
|
36
|
+
* where its Orchestrator key belongs.
|
|
37
|
+
* - a NESTED `item`. Orchestrator answers "Property values must be simple (like
|
|
38
|
+
* numbers or text) and not complex or composite data types (like objects or
|
|
39
|
+
* arrays)" — a run-time 400 for something visible in the source.
|
|
40
|
+
* - a `priority` outside the three the node type offers. The platform normalizes
|
|
41
|
+
* an unknown one silently, so it is a wrong RESULT, not an error.
|
|
42
|
+
* - `returns` on a step that does not wait (there is nothing per-tenant to
|
|
43
|
+
* declare), and a `wait: true` step whose result nothing can read.
|
|
44
|
+
* - a non-ISO `dueDate` / `deferDate`.
|
|
45
|
+
*/
|
|
46
|
+
export function checkQueueItem(inputs, ctx) {
|
|
47
|
+
const step = ctx.step;
|
|
48
|
+
// Severity is the catalog's (QUEUE_DIAGNOSTICS): `at` and `warn` name the intent.
|
|
49
|
+
const at = (code, message, suggestion) => ctx.report(code, message, suggestion);
|
|
50
|
+
const warn = at;
|
|
51
|
+
const blank = (v) => v === undefined || v === null || (typeof v === 'string' && v.trim() === '');
|
|
52
|
+
if (blank(inputs?.queue)) {
|
|
53
|
+
at('QUEUE_NO_NAME', `Queue step "${step}" has no \`queue\`. That is the queue's name in Orchestrator, and the `
|
|
54
|
+
+ `runtime resolves the queue by name + folder — without it the run fails before dispatch.`, `queue: 'SupplierInvoices'`);
|
|
55
|
+
}
|
|
56
|
+
if (blank(inputs?.folderPath)) {
|
|
57
|
+
at('QUEUE_NO_FOLDER', `Queue step "${step}" has no \`folderPath\`. Queues are folder-scoped, and the runtime `
|
|
58
|
+
+ `resolves this one by name + folder.`, `folderPath: 'Shared'`);
|
|
59
|
+
}
|
|
60
|
+
if (blank(inputs?.key)) {
|
|
61
|
+
at('QUEUE_NO_KEY', `Queue step "${step}" has no \`key\`. That is the queue's own Orchestrator key, and it is `
|
|
62
|
+
+ `what joins this node to the flow's queue bindings — without it nothing says which `
|
|
63
|
+
+ `bindings belong to the node, so it cannot be dispatched. Find it with `
|
|
64
|
+
+ `\`uip or queues list --all-folders\`.`, `key: 'fa1a7328-cd17-4525-b5ab-29d86e399312'`);
|
|
65
|
+
}
|
|
66
|
+
else if (!GUID_RE.test(String(inputs.key).trim())) {
|
|
67
|
+
at('QUEUE_KEY_NOT_GUID', `Queue step "${step}"'s \`key\` is ${JSON.stringify(inputs.key)}, which is not an `
|
|
68
|
+
+ `Orchestrator key. \`key\` is the GUID the tenant gives the queue; the queue's NAME goes `
|
|
69
|
+
+ `in \`queue\` and its folder in \`folderPath\`.`, `key: '<guid>', queue: ${JSON.stringify(inputs.key)}`);
|
|
70
|
+
}
|
|
71
|
+
// The item's data must be FLAT. This is the platform's rule, not ours, and it is
|
|
72
|
+
// enforced at the far end: a nested value earns an HTTP 400 from Orchestrator
|
|
73
|
+
// mid-run, which is a long way from the line that caused it.
|
|
74
|
+
const item = inputs?.item;
|
|
75
|
+
if (item === undefined || item === null) {
|
|
76
|
+
warn('QUEUE_NO_ITEM', `Queue step "${step}" has no \`item\`, so it enqueues an item with no data. That is legal `
|
|
77
|
+
+ `— a bare item with a reference is a real pattern — but if the work needs a payload, this `
|
|
78
|
+
+ `is where it goes.`, `item: { InvoiceId: input('invoiceRef') }`);
|
|
79
|
+
}
|
|
80
|
+
else if (typeof item !== 'object' || Array.isArray(item)) {
|
|
81
|
+
at('QUEUE_ITEM_NOT_OBJECT', `Queue step "${step}"'s \`item\` is ${Array.isArray(item) ? 'an array' : typeof item}. It `
|
|
82
|
+
+ `must be an object of field names to primitive values — that object becomes the queue `
|
|
83
|
+
+ `item's \`SpecificContent\`.`, `item: { InvoiceId: 'INV-1', Amount: 120 }`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
for (const [k, v] of Object.entries(item)) {
|
|
87
|
+
// An Expr is a reference the runtime resolves — its VALUE may be anything,
|
|
88
|
+
// and nothing local can know, so it is not flagged here.
|
|
89
|
+
if (v instanceof Expr)
|
|
90
|
+
continue;
|
|
91
|
+
if (v !== null && typeof v === 'object') {
|
|
92
|
+
at('QUEUE_ITEM_FIELD_NOT_PRIMITIVE', `Queue step "${step}"'s \`item.${k}\` is ${Array.isArray(v) ? 'an array' : 'an object'}. `
|
|
93
|
+
+ `Orchestrator rejects a queue item whose property values are not simple: `
|
|
94
|
+
+ `"Property values must be simple (like numbers or text) and not complex or composite `
|
|
95
|
+
+ `data types (like objects or arrays)". Flatten it, or JSON-encode it into one string `
|
|
96
|
+
+ `field.`, `item: { ${k}: JSON.stringify(...) } // or ${commentText(k)}Id, ${commentText(k)}Name, …`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (inputs?.priority !== undefined && !QUEUE_PRIORITIES.includes(String(inputs.priority))) {
|
|
101
|
+
at('QUEUE_BAD_PRIORITY', `Queue step "${step}"'s \`priority\` is ${JSON.stringify(inputs.priority)}. The node type `
|
|
102
|
+
+ `offers exactly ${QUEUE_PRIORITIES.map((p) => `"${p}"`).join(', ')} — anything else is `
|
|
103
|
+
+ `normalized silently by the platform, so the item is enqueued at the wrong priority `
|
|
104
|
+
+ `rather than rejected.`, `priority: '${nearestName(String(inputs.priority), QUEUE_PRIORITIES) ?? 'Normal'}'`);
|
|
105
|
+
}
|
|
106
|
+
for (const field of ['deferDate', 'dueDate']) {
|
|
107
|
+
const v = inputs?.[field];
|
|
108
|
+
if (typeof v === 'string' && v.trim() !== '' && Number.isNaN(Date.parse(v))) {
|
|
109
|
+
at('QUEUE_BAD_DATE', `Queue step "${step}"'s \`${field}\` is ${JSON.stringify(v)}, which is not a date `
|
|
110
|
+
+ `Orchestrator can read. It takes ISO-8601 — a full timestamp with a zone.`, `${field}: '2026-08-05T17:00:00Z'`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// `returns` describes what a CONSUMER produced, which only exists if the step
|
|
114
|
+
// waited for one. On a fire-and-forget enqueue it is a misunderstanding worth
|
|
115
|
+
// naming: the output is the queue item's own record, and the serializer already
|
|
116
|
+
// declares its fields.
|
|
117
|
+
if (!inputs?.wait && inputs?.returns && Object.keys(inputs.returns).length) {
|
|
118
|
+
warn('QUEUE_RETURNS_WITHOUT_WAIT', `Queue step "${step}" declares \`returns\` but does not \`wait\`, so nothing produces those `
|
|
119
|
+
+ `fields: a fire-and-forget enqueue publishes the queue ITEM's own Orchestrator record `
|
|
120
|
+
+ `(\`Key\`, \`Status\`, \`Reference\`, \`SpecificContent\`, …), whose fields are already `
|
|
121
|
+
+ `declared for you. \`returns\` describes what a CONSUMER wrote into a processed item's `
|
|
122
|
+
+ `result, which needs \`wait: true\`.`, `wait: true`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** The three priorities `core.action.queue.create[-and-wait]`'s form offers. */
|
|
126
|
+
const QUEUE_PRIORITIES = ['Low', 'Normal', 'High'];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** The Queue family's factory. Moved from core/actions.ts in Phase 4 of docs/NODE_TYPE_ARCHITECTURE_DESIGN.md. */
|
|
2
|
+
import { type ActionSpec } from '../../../core/actions.js';
|
|
3
|
+
import type { QueueItemInputs } from './spec.js';
|
|
4
|
+
/**
|
|
5
|
+
* Declare an Orchestrator QUEUE ITEM step.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* A queue is Orchestrator's work list: something puts items on it, and an
|
|
9
|
+
* automation bound to the queue takes them off one at a time. This step is the
|
|
10
|
+
* putting-on half.
|
|
11
|
+
*
|
|
12
|
+
* `queue` + `folderPath` are what the runtime resolves the queue by, and `key` is
|
|
13
|
+
* the queue's own Orchestrator key: it joins this node to the flow's queue
|
|
14
|
+
* bindings, which the serializer emits and points the node at. All three, for the
|
|
15
|
+
* same reason `rpaWorkflow` takes three — the key is the AUTHORING identity, the
|
|
16
|
+
* two bindings are the RUNTIME one.
|
|
17
|
+
*
|
|
18
|
+
* `item` is the work item's data. It becomes the item's `SpecificContent`, and it
|
|
19
|
+
* must be FLAT: Orchestrator rejects a nested object or array outright.
|
|
20
|
+
*
|
|
21
|
+
* **`wait`** picks between the family's two node types, which are one construct
|
|
22
|
+
* with two data paths. Default `false` enqueues and moves on, publishing the queue
|
|
23
|
+
* item's own Orchestrator record — read a field with `out('<step>', 'Key')`, and
|
|
24
|
+
* nothing extra has to be declared because that record's shape is the same for
|
|
25
|
+
* every queue. `wait: true` PARKS the flow until the item has been processed and
|
|
26
|
+
* publishes the consumer's result instead, which is per-automation — so a read of
|
|
27
|
+
* it needs `returns`, exactly as an rpa process's output does.
|
|
28
|
+
*
|
|
29
|
+
* What no rung can tell you: whether anything actually drains this queue. A
|
|
30
|
+
* `wait: true` step on a queue with no consumer waits until it times out.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* **Enqueue a work item and read its Orchestrator key**
|
|
34
|
+
* ```ts
|
|
35
|
+
* .step('enqueue', queueItem({
|
|
36
|
+
* queue: 'SupplierInvoices',
|
|
37
|
+
* folderPath: 'Shared',
|
|
38
|
+
* key: 'fa1a7328-cd17-4525-b5ab-29d86e399312',
|
|
39
|
+
* item: { InvoiceId: input('invoiceRef'), Amount: input('amount') },
|
|
40
|
+
* reference: 'INV-2031',
|
|
41
|
+
* }))
|
|
42
|
+
* .return({ itemKey: out('enqueue', 'Key') })
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @param inputs - The `queue` and `folderPath`, the `item` to add, and whether
|
|
46
|
+
* to `wait` for it to be processed.
|
|
47
|
+
* @returns An action spec to pass to `.step(name, …)`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function queueItem(inputs: QueueItemInputs): ActionSpec;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** The Queue family's factory. Moved from core/actions.ts in Phase 4 of docs/NODE_TYPE_ARCHITECTURE_DESIGN.md. */
|
|
2
|
+
import { builtinActionSpec } from '../../../core/actions.js';
|
|
3
|
+
/**
|
|
4
|
+
* Declare an Orchestrator QUEUE ITEM step.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* A queue is Orchestrator's work list: something puts items on it, and an
|
|
8
|
+
* automation bound to the queue takes them off one at a time. This step is the
|
|
9
|
+
* putting-on half.
|
|
10
|
+
*
|
|
11
|
+
* `queue` + `folderPath` are what the runtime resolves the queue by, and `key` is
|
|
12
|
+
* the queue's own Orchestrator key: it joins this node to the flow's queue
|
|
13
|
+
* bindings, which the serializer emits and points the node at. All three, for the
|
|
14
|
+
* same reason `rpaWorkflow` takes three — the key is the AUTHORING identity, the
|
|
15
|
+
* two bindings are the RUNTIME one.
|
|
16
|
+
*
|
|
17
|
+
* `item` is the work item's data. It becomes the item's `SpecificContent`, and it
|
|
18
|
+
* must be FLAT: Orchestrator rejects a nested object or array outright.
|
|
19
|
+
*
|
|
20
|
+
* **`wait`** picks between the family's two node types, which are one construct
|
|
21
|
+
* with two data paths. Default `false` enqueues and moves on, publishing the queue
|
|
22
|
+
* item's own Orchestrator record — read a field with `out('<step>', 'Key')`, and
|
|
23
|
+
* nothing extra has to be declared because that record's shape is the same for
|
|
24
|
+
* every queue. `wait: true` PARKS the flow until the item has been processed and
|
|
25
|
+
* publishes the consumer's result instead, which is per-automation — so a read of
|
|
26
|
+
* it needs `returns`, exactly as an rpa process's output does.
|
|
27
|
+
*
|
|
28
|
+
* What no rung can tell you: whether anything actually drains this queue. A
|
|
29
|
+
* `wait: true` step on a queue with no consumer waits until it times out.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* **Enqueue a work item and read its Orchestrator key**
|
|
33
|
+
* ```ts
|
|
34
|
+
* .step('enqueue', queueItem({
|
|
35
|
+
* queue: 'SupplierInvoices',
|
|
36
|
+
* folderPath: 'Shared',
|
|
37
|
+
* key: 'fa1a7328-cd17-4525-b5ab-29d86e399312',
|
|
38
|
+
* item: { InvoiceId: input('invoiceRef'), Amount: input('amount') },
|
|
39
|
+
* reference: 'INV-2031',
|
|
40
|
+
* }))
|
|
41
|
+
* .return({ itemKey: out('enqueue', 'Key') })
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @param inputs - The `queue` and `folderPath`, the `item` to add, and whether
|
|
45
|
+
* to `wait` for it to be processed.
|
|
46
|
+
* @returns An action spec to pass to `.step(name, …)`.
|
|
47
|
+
*/
|
|
48
|
+
export function queueItem(inputs) {
|
|
49
|
+
return builtinActionSpec({ kind: 'queueItem', inputs });
|
|
50
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FlowVersionedNodeType } from '../../../flow-node-type.js';
|
|
2
|
+
import type { QueueItemInputs } from './spec.js';
|
|
3
|
+
/** The spec both queue node types read. */
|
|
4
|
+
export type QueueItemSpec = {
|
|
5
|
+
kind: 'queueItem';
|
|
6
|
+
inputs: QueueItemInputs;
|
|
7
|
+
};
|
|
8
|
+
export declare const queueNodeTypes: FlowVersionedNodeType<QueueItemSpec>[];
|