@uipath/maestro-builder-sdk 6.57.0 → 6.58.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.
- package/dist/case/subscription.d.ts +4 -2
- package/dist/case/subscription.js +5 -2
- package/dist/core/actions.js +2 -2
- package/dist/core/binding-messages.d.ts +2 -1
- package/dist/core/binding-messages.js +3 -4
- package/dist/core/byoa.d.ts +3 -2
- package/dist/core/byoa.js +3 -3
- package/dist/core/carried-definitions.d.ts +0 -18
- package/dist/core/carried-definitions.js +3 -2
- package/dist/core/ceql.d.ts +2 -1
- package/dist/core/ceql.js +3 -2
- package/dist/core/compile-refusal.d.ts +21 -0
- package/dist/core/compile-refusal.js +26 -0
- package/dist/core/connector-inputs.js +2 -1
- package/dist/core/connector-resolve-error.d.ts +2 -1
- package/dist/core/connector-resolve-error.js +3 -4
- package/dist/core/connectors.js +2 -1
- package/dist/core/event-filters.js +2 -1
- package/dist/core/hitl-routing.d.ts +7 -82
- package/dist/core/hitl-routing.js +95 -6
- package/dist/core/library.js +4 -3
- package/dist/core/lookups.js +6 -5
- package/dist/core/nodes/registry.js +3 -2
- package/dist/core/nodes/versioned.js +3 -2
- package/dist/core/process-resource-sort-order.js +1 -1
- package/dist/core/read-text.d.ts +0 -28
- package/dist/core/read-text.js +3 -2
- package/dist/core/refusals.d.ts +465 -0
- package/dist/core/refusals.js +504 -0
- package/dist/core/script-function.js +2 -1
- package/dist/core/typescript-module.js +2 -1
- package/dist/flow-expr-check.d.ts +2 -1
- package/dist/flow-expr-check.js +4 -2
- package/dist/flow-sdk.js +17 -16
- package/dist/flow-step-tree.js +1 -1
- package/dist/flow-variables.js +3 -2
- package/dist/load.js +7 -6
- package/dist/nodes/agent/flow/inline-agent.js +7 -6
- package/dist/nodes/connector/flow/node-type.js +2 -1
- package/dist/nodes/data-fabric/flow/factories.js +2 -1
- package/dist/nodes/data-fabric/flow/verbs.js +2 -1
- package/dist/nodes/delay/flow/factories.js +2 -1
- package/dist/nodes/document/flow/ixp.js +5 -1
- package/dist/nodes/hitl/flow/check.js +4 -2
- package/dist/nodes/hitl/flow/node-type.js +6 -5
- package/dist/nodes/http/flow/factories.js +2 -1
- package/dist/nodes/http/flow/node-type.js +6 -5
- package/dist/nodes/process/flow/factories.js +2 -1
- package/dist/nodes/queue/flow/node-type.js +3 -2
- package/dist/nodes/transform/flow/node-type.js +2 -1
- package/dist/raw-node.js +3 -2
- package/dist/ref-resolve.d.ts +0 -36
- package/dist/ref-resolve.js +9 -8
- package/dist/schema-version.d.ts +0 -38
- package/dist/schema-version.js +3 -2
- package/dist/sdk-resolve.js +2 -1
- package/dist/serialize.d.ts +5 -2
- package/dist/serialize.js +115 -83
- package/package.json +2 -2
package/dist/flow-sdk.js
CHANGED
|
@@ -48,6 +48,7 @@ import { checkFlowExpressions, FlowBuildError } from './flow-expr-check.js';
|
|
|
48
48
|
import { FLOW_SCHEMA_VERSIONS } from './format-profile.js';
|
|
49
49
|
import { schemaVersionRefusal } from './schema-version.js';
|
|
50
50
|
import { indexCarriedDefinitions } from './core/carried-definitions.js';
|
|
51
|
+
import { CompileRefusal } from './core/compile-refusal.js';
|
|
51
52
|
export { FlowBuildError, checkFlowExpressions } from './flow-expr-check.js';
|
|
52
53
|
const TYPE_NAMES = Object.values(types);
|
|
53
54
|
/**
|
|
@@ -69,7 +70,7 @@ const TYPE_NAMES = Object.values(types);
|
|
|
69
70
|
*/
|
|
70
71
|
function assertShape(method, shape) {
|
|
71
72
|
if (typeof shape !== 'object' || shape === null || Array.isArray(shape)) {
|
|
72
|
-
throw new
|
|
73
|
+
throw new CompileRefusal('DECLARATION_SHAPE', `.${method}() takes ONE object mapping names to types — got ${Array.isArray(shape) ? 'an array' : typeof shape}`
|
|
73
74
|
+ `${typeof shape === 'string' ? ` (${JSON.stringify(shape)})` : ''}. `
|
|
74
75
|
+ `Write .${method}({ ${typeof shape === 'string' ? shape : 'name'}: types.string }), not `
|
|
75
76
|
+ `.${method}('name', 'string'): a string would be iterated character by character and `
|
|
@@ -89,12 +90,12 @@ function varDeclOf(method, name, value) {
|
|
|
89
90
|
assertType(method, name, spec.type);
|
|
90
91
|
if (spec.shared !== undefined) {
|
|
91
92
|
if (method !== 'input') {
|
|
92
|
-
throw new
|
|
93
|
+
throw new CompileRefusal('SHARED_INPUT_NOT_INPUT', `.${method}() declared ${JSON.stringify(name)} with { shared }, which only an input takes: it names `
|
|
93
94
|
+ `the flow variable a root's input is copied into. Declare the variable with .var() and feed it from `
|
|
94
95
|
+ `.input({ <name>: { type, shared: ${JSON.stringify(spec.shared)} } }).`);
|
|
95
96
|
}
|
|
96
97
|
if (typeof spec.shared !== 'string' || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(spec.shared)) {
|
|
97
|
-
throw new
|
|
98
|
+
throw new CompileRefusal('SHARED_INPUT_NAME_INVALID', `Input ${JSON.stringify(name)}: { shared } must be a variable name (letters, digits, _), got `
|
|
98
99
|
+ `${JSON.stringify(spec.shared)}.`);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
@@ -114,7 +115,7 @@ function varDeclOf(method, name, value) {
|
|
|
114
115
|
function assertType(method, name, type) {
|
|
115
116
|
if (typeof type === 'string' && TYPE_NAMES.includes(type))
|
|
116
117
|
return;
|
|
117
|
-
throw new
|
|
118
|
+
throw new CompileRefusal('DECLARATION_TYPE_UNKNOWN', `.${method}() declared ${JSON.stringify(name)} with type ${JSON.stringify(type)}, which is not `
|
|
118
119
|
+ `a type. Use one of ${TYPE_NAMES.map((t) => `types.${t}`).join(', ')}.`);
|
|
119
120
|
}
|
|
120
121
|
// ─── Triggers (what starts the flow) ────────────────────────────────────────
|
|
@@ -374,7 +375,7 @@ class StepList {
|
|
|
374
375
|
*/
|
|
375
376
|
err(field) {
|
|
376
377
|
if (!this.errorSource) {
|
|
377
|
-
throw new
|
|
378
|
+
throw new CompileRefusal('ERROR_READ_OUTSIDE_HANDLER', 'err(field) with no step name is only available inside an error handler — the sub-builder '
|
|
378
379
|
+ '.onError((h) => …) / .stepToList(\'error\', (h) => …) passes. Elsewhere, name the step: '
|
|
379
380
|
+ "err('<step>', 'message').");
|
|
380
381
|
}
|
|
@@ -438,7 +439,7 @@ class StepList {
|
|
|
438
439
|
*/
|
|
439
440
|
stepSwitch(name, spec, cases, options) {
|
|
440
441
|
if (!Array.isArray(cases) || cases.length === 0) {
|
|
441
|
-
throw new
|
|
442
|
+
throw new CompileRefusal('STEP_SWITCH_NO_ARMS', `.stepSwitch('${name}'): needs at least one arm. With nothing to route, use .step().`);
|
|
442
443
|
}
|
|
443
444
|
const arms = cases.map((c) => {
|
|
444
445
|
const arm = new ArmBuilder();
|
|
@@ -448,7 +449,7 @@ class StepList {
|
|
|
448
449
|
// is already named by the outcome or branch it leaves. Refusing beats
|
|
449
450
|
// accepting it and dropping it on the floor.
|
|
450
451
|
if (arm.armLabel !== undefined) {
|
|
451
|
-
throw new
|
|
452
|
+
throw new CompileRefusal('STEP_SWITCH_ARM_LABEL', `.stepSwitch('${name}') arm '${c.value}': .label() has nowhere to go — a port edge carries no `
|
|
452
453
|
+ `label, and the exit is named by "${c.value}" already. Use options.label to rename the NODE.`);
|
|
453
454
|
}
|
|
454
455
|
return { value: String(c.value), body: arm.steps };
|
|
@@ -551,14 +552,14 @@ class StepList {
|
|
|
551
552
|
// version the container emits (#1010).
|
|
552
553
|
const containerPort = port === 'error' && (source?.kind === 'loop' || source?.kind === 'doWhile');
|
|
553
554
|
if (!source || (source.kind !== 'action' && !containerPort)) {
|
|
554
|
-
throw new
|
|
555
|
+
throw new CompileRefusal('PORT_NO_SOURCE_STEP', `${called} leaves a port of the step BEFORE it, and ${source ? `the previous step is a ${source.kind}` : 'there is no previous step'}. `
|
|
555
556
|
+ `Write .step('fetch', http({…}))${called}`
|
|
556
557
|
+ ' — a branch, parallel, terminate or return has no port to leave from; a .loop() or .doWhile() has one '
|
|
557
558
|
+ "only for 'error'.");
|
|
558
559
|
}
|
|
559
560
|
const taken = attached.some((s) => (s.kind === 'stepToList' || s.kind === 'stepToRef') && s.port === port);
|
|
560
561
|
if (taken) {
|
|
561
|
-
throw new
|
|
562
|
+
throw new CompileRefusal('PORT_ALREADY_ROUTED', `${called} is already set on step "${source.name}"'s "${port}" port. A port takes exactly ONE outgoing edge `
|
|
562
563
|
+ `(the definition says so: maxConnections: 1), so put everything that path needs in one place.`);
|
|
563
564
|
}
|
|
564
565
|
return source;
|
|
@@ -611,7 +612,7 @@ class StepList {
|
|
|
611
612
|
h.errorSource = prev.name;
|
|
612
613
|
bodyFn?.(h);
|
|
613
614
|
if (h.steps.length === 0) {
|
|
614
|
-
throw new
|
|
615
|
+
throw new CompileRefusal('PORT_EMPTY_PATH', `${called} on step "${prev.name}" has an empty ${noun}. An edge to nothing is worse than none — `
|
|
615
616
|
+ `the path still leaves the main flow. Return a value, terminate the run, or do the compensating work.`);
|
|
616
617
|
}
|
|
617
618
|
this.steps.push({ kind: 'stepToList', port, body: h.steps });
|
|
@@ -637,7 +638,7 @@ class StepList {
|
|
|
637
638
|
*/
|
|
638
639
|
branch(name, cond, thenFn, elseFn, options) {
|
|
639
640
|
if (options?.updates) {
|
|
640
|
-
throw new
|
|
641
|
+
throw new CompileRefusal('UPDATES_NOT_SUPPORTED', '.branch(): { updates } is not supported here — the platform strips variable updates from '
|
|
641
642
|
+ 'decision/switch/merge nodes on save. Attach them to a step before or after instead.');
|
|
642
643
|
}
|
|
643
644
|
const t = new ArmBuilder();
|
|
@@ -707,7 +708,7 @@ class StepList {
|
|
|
707
708
|
*/
|
|
708
709
|
switch(name, on, cases, defaultFn, options) {
|
|
709
710
|
if (options?.updates) {
|
|
710
|
-
throw new
|
|
711
|
+
throw new CompileRefusal('UPDATES_NOT_SUPPORTED', '.switch(): { updates } is not supported here — the platform strips variable updates from '
|
|
711
712
|
+ 'decision/switch/merge nodes on save. Attach them to a step before or after instead.');
|
|
712
713
|
}
|
|
713
714
|
const arms = (cases ?? []).map((c) => {
|
|
@@ -789,7 +790,7 @@ class StepList {
|
|
|
789
790
|
*/
|
|
790
791
|
parallel(name, arms, options) {
|
|
791
792
|
if (options?.updates) {
|
|
792
|
-
throw new
|
|
793
|
+
throw new CompileRefusal('UPDATES_NOT_SUPPORTED', '.parallel(): { updates } is not supported here — the platform strips variable updates from '
|
|
793
794
|
+ 'decision/switch/merge nodes on save. Attach them to a step before or after instead.');
|
|
794
795
|
}
|
|
795
796
|
const built = (arms ?? []).map((armFn) => {
|
|
@@ -924,7 +925,7 @@ class StepList {
|
|
|
924
925
|
const port = maybeTarget === undefined ? 'output' : portOrTarget;
|
|
925
926
|
const target = maybeTarget === undefined ? portOrTarget : maybeTarget;
|
|
926
927
|
if (typeof target !== 'string' || target.length === 0) {
|
|
927
|
-
throw new
|
|
928
|
+
throw new CompileRefusal('REF_TARGET_NOT_NAME', `.stepToRef() takes the NAME of the step to continue at — .stepToRef('priceIt') — and got ${JSON.stringify(target)}. `
|
|
928
929
|
+ `It is the same name you passed to .step() (or a .return() End's \`name\`), so the edge can be wired after the whole flow is built.`);
|
|
929
930
|
}
|
|
930
931
|
// A non-default port leaves the PRECEDING step, so it is guarded the same way
|
|
@@ -1103,7 +1104,7 @@ class FlowBuilder extends StepList {
|
|
|
1103
1104
|
*/
|
|
1104
1105
|
trigger(spec, options) {
|
|
1105
1106
|
if (options?.updates) {
|
|
1106
|
-
throw new
|
|
1107
|
+
throw new CompileRefusal('UPDATES_NOT_SUPPORTED', '.trigger(): { updates } is not supported — a trigger has not run anything to assign from.');
|
|
1107
1108
|
}
|
|
1108
1109
|
this._trigger = spec;
|
|
1109
1110
|
if (options)
|
|
@@ -1263,7 +1264,7 @@ class FlowBuilder extends StepList {
|
|
|
1263
1264
|
schemaVersion(version) {
|
|
1264
1265
|
const refusal = schemaVersionRefusal(FLOW_SCHEMA_VERSIONS, version);
|
|
1265
1266
|
if (refusal)
|
|
1266
|
-
throw new
|
|
1267
|
+
throw new CompileRefusal('SCHEMA_VERSION_UNSUPPORTED', refusal);
|
|
1267
1268
|
this._schemaVersion = version;
|
|
1268
1269
|
return this;
|
|
1269
1270
|
}
|
package/dist/flow-step-tree.js
CHANGED
|
@@ -44,7 +44,7 @@ export function childStepLists(step) {
|
|
|
44
44
|
return [];
|
|
45
45
|
default: {
|
|
46
46
|
const unhandled = step;
|
|
47
|
-
throw new Error(`childStepLists: unhandled step kind ${JSON.stringify(unhandled.kind)}`);
|
|
47
|
+
throw new Error(`internal SDK error: childStepLists: unhandled step kind ${JSON.stringify(unhandled.kind)}`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
}
|
package/dist/flow-variables.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { globalNameCollisionMessage, globalNameCollisions } from './core/global-names.js';
|
|
2
|
+
import { CompileRefusal } from './core/compile-refusal.js';
|
|
2
3
|
/** The keys of `variables` that hold declarations rather than name one (the map spelling). */
|
|
3
4
|
export const CONTAINER_KEYS = new Set(['globals', 'nodes', 'variableUpdates']);
|
|
4
5
|
const DIRECTIONS = new Set(['in', 'out', 'inout']);
|
|
@@ -8,7 +9,7 @@ export function readFlowGlobals(variables, strict = false) {
|
|
|
8
9
|
return [];
|
|
9
10
|
if (typeof variables !== 'object' || Array.isArray(variables)) {
|
|
10
11
|
if (strict)
|
|
11
|
-
throw new
|
|
12
|
+
throw new CompileRefusal('DECOMPILE_VARIABLES_SHAPE', 'decompile: variables must be an object.');
|
|
12
13
|
return [];
|
|
13
14
|
}
|
|
14
15
|
const source = variables;
|
|
@@ -37,7 +38,7 @@ export function readFlowGlobals(variables, strict = false) {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
if (strict && unknown.length > 0) {
|
|
40
|
-
throw new
|
|
41
|
+
throw new CompileRefusal('DECOMPILE_VARIABLES_SHAPE', `decompile: unrecognized variables key${unknown.length === 1 ? '' : 's'}: `
|
|
41
42
|
+ `${unknown.map((key) => JSON.stringify(key)).join(', ')}.`);
|
|
42
43
|
}
|
|
43
44
|
return globals;
|
package/dist/load.js
CHANGED
|
@@ -5,6 +5,7 @@ import { statSync } from 'node:fs';
|
|
|
5
5
|
import { useThisSdkForAuthoredSource } from './sdk-resolve.js';
|
|
6
6
|
import { scriptFunctionLowerings } from './core/script-function.js';
|
|
7
7
|
import { scriptFunctionScopeProblem } from './script-function-scope.js';
|
|
8
|
+
import { CompileRefusal } from './core/compile-refusal.js';
|
|
8
9
|
/** Resolve a user argument (a `.ts` path or a BaseName) to a flow source file. */
|
|
9
10
|
export function resolveFlowFile(arg) {
|
|
10
11
|
const candidates = [arg, `${arg}.flow.ts`, `${arg}.ts`];
|
|
@@ -19,7 +20,7 @@ export function resolveFlowFile(arg) {
|
|
|
19
20
|
}
|
|
20
21
|
return resolvedCandidate;
|
|
21
22
|
}
|
|
22
|
-
throw new
|
|
23
|
+
throw new CompileRefusal('FLOW_SOURCE_NOT_FOUND', `flow source not found: tried ${candidates.join(', ')}`);
|
|
23
24
|
}
|
|
24
25
|
export async function loadBuiltFlow(file) {
|
|
25
26
|
useThisSdkForAuthoredSource();
|
|
@@ -33,10 +34,10 @@ export async function loadBuiltFlow(file) {
|
|
|
33
34
|
}
|
|
34
35
|
const exp = mod.default ?? mod.flow ?? mod.workflow;
|
|
35
36
|
if (!exp)
|
|
36
|
-
throw new
|
|
37
|
+
throw new CompileRefusal('FLOW_NO_DEFAULT_EXPORT', `${file} has no default export. Add: export default flow('id')...build();`);
|
|
37
38
|
const built = typeof exp.build === 'function' ? exp.build() : exp;
|
|
38
39
|
if (!built || !Array.isArray(built.steps))
|
|
39
|
-
throw new
|
|
40
|
+
throw new CompileRefusal('FLOW_EXPORT_NOT_BUILT', `${file} default export is not a built flow. Did you call .build()?`);
|
|
40
41
|
// A `script(fn)` function was lowered from its own text, which cannot show a
|
|
41
42
|
// name it takes from its module; this source can (script-function-scope.ts).
|
|
42
43
|
// Only a flow that lowered one pays for the program this builds.
|
|
@@ -45,7 +46,7 @@ export async function loadBuiltFlow(file) {
|
|
|
45
46
|
if (lowered.length > 0) {
|
|
46
47
|
const problem = scriptFunctionScopeProblem(file, lowered);
|
|
47
48
|
if (problem)
|
|
48
|
-
throw new
|
|
49
|
+
throw new CompileRefusal('SCRIPT_FUNCTION_SCOPE', problem);
|
|
49
50
|
}
|
|
50
51
|
return built;
|
|
51
52
|
}
|
|
@@ -96,7 +97,7 @@ export function connectorImportDiagnostic(error) {
|
|
|
96
97
|
return undefined;
|
|
97
98
|
}
|
|
98
99
|
if (parent === 'connectors') {
|
|
99
|
-
return new
|
|
100
|
+
return new CompileRefusal('CONNECTOR_IMPORT_NOT_A_FILE', `connector import "${unresolved}" does not name a file. The generated ` +
|
|
100
101
|
`descriptors are TypeScript, so the specifier keeps its real extension; ` +
|
|
101
102
|
`import "${moduleFile}"`);
|
|
102
103
|
}
|
|
@@ -104,7 +105,7 @@ export function connectorImportDiagnostic(error) {
|
|
|
104
105
|
if (!statSync(descriptorData, { throwIfNoEntry: false })?.isDirectory()) {
|
|
105
106
|
return undefined;
|
|
106
107
|
}
|
|
107
|
-
return new
|
|
108
|
+
return new CompileRefusal('CONNECTOR_IMPORT_NOT_A_FILE', `connector import "${unresolved}" does not name a file; module candidate ` +
|
|
108
109
|
`"${moduleFile}" and descriptor data "${descriptorData}" are separate; ` +
|
|
109
110
|
`import "${moduleFile}"`);
|
|
110
111
|
}
|
|
@@ -10,6 +10,7 @@ import { processResourceBindings } from '../../../core/process-resource.js';
|
|
|
10
10
|
import { fnv1aX4Uuid, schemaId } from '../../../core/stable-id.js';
|
|
11
11
|
import { synthesizedDefinitionRefusal } from '../../../core/synthesized-definition.js';
|
|
12
12
|
import { BUILTIN_TOOL_DEFS, INLINE_AGENT, PROCESS_TOOL_META, a2aToolDef, builtinToolResourceJson, connectorToolDef, connectorToolDescription, connectorToolDetail, connectorToolResourceJson, contextIndexDef, contextResourceJson, declaresMemoryHandle, escalationAppFolder, escalationDef, escalationResourceJson, fieldSchema, httpRequestToolResourceJson, inlineAgentDef, ixpToolDef, mcpToolDef, memoryResourceDef, processToolDef, renderContextQuery, toolResourceJson, } from './resources.js';
|
|
13
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
13
14
|
/** Every bundled version of the inline agent, oldest first; the newest is the default (#956). */
|
|
14
15
|
export const INLINE_AGENT_VERSIONS = ['1.2', '1.3', '1.4'];
|
|
15
16
|
export const INLINE_AGENT_DEFAULT_VERSION = INLINE_AGENT_VERSIONS[INLINE_AGENT_VERSIONS.length - 1];
|
|
@@ -39,7 +40,7 @@ export function serializeInlineAgent(s, ctx) {
|
|
|
39
40
|
if (!def)
|
|
40
41
|
throw new Error(`internal SDK error: step "${step}": no definition resolves for ${INLINE_AGENT}@${version}.`);
|
|
41
42
|
if (s.memory !== undefined && !declaresMemoryHandle(def)) {
|
|
42
|
-
throw new
|
|
43
|
+
throw new CompileRefusal('AGENT_MEMORY_VERSION_NO_HANDLE', `"${step}" attaches \`memory\`, but ${INLINE_AGENT}@${version} declares no \`memory\` handle. `
|
|
43
44
|
+ (version === INLINE_AGENT_DEFAULT_VERSION
|
|
44
45
|
? `Pin a version that has it with inlineAgent({ ..., version: '<x.y>' }) `
|
|
45
46
|
+ `(bundled with memory: ${INLINE_AGENT_VERSIONS.filter((v) => declaresMemoryHandle(ctx.definition(INLINE_AGENT, v))).join(', ') || 'none'}), or drop \`memory\`.`
|
|
@@ -134,8 +135,8 @@ export function serializeInlineAgent(s, ctx) {
|
|
|
134
135
|
// the type `…context.index.<slug>.`, which no tenant serves, and nothing
|
|
135
136
|
// after this point would say so.
|
|
136
137
|
if (typeof cx?.id !== 'string' || !GUID_RE.test(cx.id)) {
|
|
137
|
-
throw
|
|
138
|
-
+ `got ${JSON.stringify(cx?.id)}. \`uip solution resources list --kind Index --source remote --search "<name>"\` returns it as \`Key\`.`)
|
|
138
|
+
throw new CompileRefusal('AGENT_CONTEXT_NO_ID', `inline agent "${step}": context index "${cx?.name ?? ''}" needs its index id (a GUID) as \`id\`; `
|
|
139
|
+
+ `got ${JSON.stringify(cx?.id)}. \`uip solution resources list --kind Index --source remote --search "<name>"\` returns it as \`Key\`.`);
|
|
139
140
|
}
|
|
140
141
|
const cdef = contextIndexDef({ name: cx.name, id: cx.id });
|
|
141
142
|
// `<step>Context`, deduped for a second index on the same agent, unless the
|
|
@@ -207,7 +208,7 @@ export function serializeInlineAgent(s, ctx) {
|
|
|
207
208
|
const bdef = ownEntry(BUILTIN_TOOL_DEFS, tr.tool);
|
|
208
209
|
tdef = bdef === undefined ? undefined : jsonClone(bdef);
|
|
209
210
|
if (!tdef)
|
|
210
|
-
throw new
|
|
211
|
+
throw new CompileRefusal('INLINE_AGENT_TOOL_UNKNOWN_BUILTIN', `inline agent "${step}": unknown builtin tool "${tr.tool}" (analyzefiles | summarize | batchtransform).`);
|
|
211
212
|
label = tdef.display.label;
|
|
212
213
|
// The designer-placed node carries the def's `inputDefaults` with the
|
|
213
214
|
// author's values over them — the context rule, kept per builtin (each def
|
|
@@ -242,7 +243,7 @@ export function serializeInlineAgent(s, ctx) {
|
|
|
242
243
|
}
|
|
243
244
|
else if (tr.kind === 'connector') {
|
|
244
245
|
if (!ctx.library)
|
|
245
|
-
throw new
|
|
246
|
+
throw new CompileRefusal('LIBRARY_REQUIRED', `inline agent "${step}"'s connector tool needs a library (pass --library / set $FLOW_SDK_LIBRARY_JSON).`);
|
|
246
247
|
const rc = ctx.library.resolve(tr.connector, tr.operation, tr.version, tr.object);
|
|
247
248
|
// An entry `prepare` synthesized from Integration Service compiles in BPMN
|
|
248
249
|
// only — for a tool as for a step: `connectorToolDef` reads the same
|
|
@@ -337,7 +338,7 @@ export function serializeInlineAgent(s, ctx) {
|
|
|
337
338
|
else {
|
|
338
339
|
const meta = ownEntry(PROCESS_TOOL_META, tr.kind);
|
|
339
340
|
if (!meta)
|
|
340
|
-
throw new
|
|
341
|
+
throw new CompileRefusal('INLINE_AGENT_TOOL_UNKNOWN_KIND', `inline agent "${step}": unknown tool kind "${tr.kind}".`);
|
|
341
342
|
tdef = processToolDef(tr.kind, tr);
|
|
342
343
|
label = tr.name;
|
|
343
344
|
// The definition's `model.context` names `<bindings.name>` /
|
|
@@ -9,6 +9,7 @@ import { jsonClone } from '../../../core/json-clone.js';
|
|
|
9
9
|
import { subNodeId } from '../../../core/node-id-placeholder.js';
|
|
10
10
|
import { synthesizedDefinitionRefusal } from '../../../core/synthesized-definition.js';
|
|
11
11
|
import { tsLiteral, tsObject } from '../../../core/ts-literal.js';
|
|
12
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
12
13
|
const CONNECTOR_PREFIX = 'uipath.connector.';
|
|
13
14
|
/** `<key>.<action>` after the prefix, split on the last dot; undefined for an event, a trigger, or a name with no action. */
|
|
14
15
|
function splitOperation(typeName) {
|
|
@@ -65,7 +66,7 @@ function listOutputs(rc, nodeId) {
|
|
|
65
66
|
function serializeConnector(spec, ctx) {
|
|
66
67
|
const step = ctx.step;
|
|
67
68
|
if (!ctx.library)
|
|
68
|
-
throw new
|
|
69
|
+
throw new CompileRefusal('LIBRARY_REQUIRED', `connector "${step}" needs a library (pass --library / set $FLOW_SDK_LIBRARY_JSON).`);
|
|
69
70
|
let rc;
|
|
70
71
|
try {
|
|
71
72
|
rc = ctx.library.resolve(spec.key, spec.action, spec.version, spec.object);
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* them, so authors import them exactly as before.
|
|
6
6
|
*/
|
|
7
7
|
import { builtinActionSpec } from '../../../core/actions.js';
|
|
8
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
8
9
|
/**
|
|
9
10
|
* Query entity records from Data Fabric (`core.datafabric.read`). The result
|
|
10
11
|
* publishes to the step's `output`; downstream references re-fetch fresh data
|
|
@@ -129,6 +130,6 @@ function assertOneRecordRef(record, factory) {
|
|
|
129
130
|
const byId = record?.byId !== undefined;
|
|
130
131
|
const fromRead = typeof record?.fromRead === 'string';
|
|
131
132
|
if (byId === fromRead) {
|
|
132
|
-
throw new
|
|
133
|
+
throw new CompileRefusal('DATAFABRIC_RECORD_REF', `${factory}() targets exactly ONE of record: { byId } or record: { fromRead: '<step>' }.`);
|
|
133
134
|
}
|
|
134
135
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { applyScope, baseConfig, entityConfigOf, fieldRows, filterRows, liftFields, liftRecord, liftScope, liftValue, printFields, printRecord, scopeOptions, targetRecord, } from './shared.js';
|
|
2
2
|
import { checkCreate, checkRead, checkUpdate, checkWrite } from './check.js';
|
|
3
3
|
import { rawNodeAdvice } from './raw.js';
|
|
4
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
4
5
|
/**
|
|
5
6
|
* Every Data Fabric node carries no node-level `model`, whichever path emits it
|
|
6
7
|
* (a verb, or a rawNode of its definition). Studio Web never writes one
|
|
@@ -36,7 +37,7 @@ function readAt(version) {
|
|
|
36
37
|
nodeModel: NODE_MODEL, rawNode: READ_ADVICE,
|
|
37
38
|
serialize: ({ inputs }, ctx) => {
|
|
38
39
|
if (version === '1.0' && inputs.resultMode !== undefined) {
|
|
39
|
-
throw new
|
|
40
|
+
throw new CompileRefusal('DATAFABRIC_RESULT_MODE_VERSION', "dataFabricRead(): { resultMode } needs the node's 1.4 definition, but { version: '1.0' } was "
|
|
40
41
|
+ 'requested. Drop the version, request 1.4, or drop resultMode.');
|
|
41
42
|
}
|
|
42
43
|
const cfg = baseConfig(inputs);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* docs/NODE_TYPE_ARCHITECTURE_DESIGN.md; the package entry re-exports it.
|
|
4
4
|
*/
|
|
5
5
|
import { builtinActionSpec } from '../../../core/actions.js';
|
|
6
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
6
7
|
/**
|
|
7
8
|
* Declare a delay — a step that pauses the flow for a fixed length of time and
|
|
8
9
|
* then carries on.
|
|
@@ -31,7 +32,7 @@ export function delay(inputs) {
|
|
|
31
32
|
const hasDuration = 'duration' in inputs;
|
|
32
33
|
const hasUntil = 'until' in inputs;
|
|
33
34
|
if (hasDuration === hasUntil) {
|
|
34
|
-
throw new
|
|
35
|
+
throw new CompileRefusal('DELAY_DURATION_XOR_UNTIL', "delay() takes exactly ONE of { duration } (an ISO-8601 duration, e.g. 'PT15M') or "
|
|
35
36
|
+ "{ until } (an ISO-8601 date-time, e.g. '2026-09-01T09:00:00Z').");
|
|
36
37
|
}
|
|
37
38
|
return builtinActionSpec({ kind: 'delay', inputs });
|
|
@@ -14,6 +14,7 @@ import { definitionHasErrorPort } from '../../../core/error-port.js';
|
|
|
14
14
|
import { Expr } from '../../../core/expr.js';
|
|
15
15
|
import { jsonClone } from '../../../core/json-clone.js';
|
|
16
16
|
import { parseIxpProjectType } from './spec.js';
|
|
17
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
17
18
|
const IXP_PREFIX = 'uipath.ixp.';
|
|
18
19
|
export const IXP_DIAGNOSTICS = {
|
|
19
20
|
IXP_FORBIDDEN_INPUT: { severity: 'error', summary: 'an IxP step setting an input the current node does not declare' },
|
|
@@ -65,7 +66,10 @@ const IXP_DEF = ixpDefinition;
|
|
|
65
66
|
export function ixpExtractDef(spec) {
|
|
66
67
|
const parts = parseIxpProjectType(spec.project);
|
|
67
68
|
if (!parts) {
|
|
68
|
-
|
|
69
|
+
// The three conditions check tells apart, under check's three codes.
|
|
70
|
+
const code = typeof spec.project !== 'string' || spec.project.trim() === '' ? 'IXP_NO_PROJECT'
|
|
71
|
+
: !spec.project.startsWith('uipath.ixp.') ? 'IXP_PROJECT_NOT_NODE_TYPE' : 'IXP_PROJECT_TAIL_UNPARSEABLE';
|
|
72
|
+
throw new CompileRefusal(code, `ixpExtract: "${spec.project}" is not a resolvable extractor node type. It must be `
|
|
69
73
|
+ `uipath.ixp.<slug>.<projectVersionId>-<folderKey> — copy it from `
|
|
70
74
|
+ `\`uip maestro flow registry pull --force && uip maestro flow registry search -f "type:startsWith=uipath.ixp"\`.`);
|
|
71
75
|
}
|
|
@@ -7,7 +7,8 @@ export const HITL_DIAGNOSTICS = {
|
|
|
7
7
|
HITL_VARIANT_UNKNOWN: { severity: 'error', summary: 'a variant that names no human-task node type' },
|
|
8
8
|
HITL_OUTCOME_PORTS_VARIANT: { severity: 'error', summary: 'exposeError or outcomePorts on a variant that cannot honour it' },
|
|
9
9
|
HITL_LEGACY_COMPLETED: { severity: 'warning', summary: "a task with outcomes that leaves on the legacy 'completed' handle" },
|
|
10
|
-
HITL_LEGACY_COMPLETED_CONFLICT: { severity: 'error', summary: 'legacyCompleted with outcomePorts or exposeError
|
|
10
|
+
HITL_LEGACY_COMPLETED_CONFLICT: { severity: 'error', summary: 'legacyCompleted with outcomePorts or exposeError' },
|
|
11
|
+
HITL_LEGACY_COMPLETED_NO_EFFECT: { severity: 'error', summary: "legacyCompleted where 'completed' is already the only exit" },
|
|
11
12
|
HITL_DOCUMENT_WITHOUT_VARIANT: { severity: 'error', summary: 'a document on a task that is not a validation station' },
|
|
12
13
|
HITL_DOCVAL_WITH_FIELDS: { severity: 'error', summary: 'form fields on a validation station' },
|
|
13
14
|
HITL_DOCVAL_NO_DOCUMENT: { severity: 'error', summary: 'a validation station with no document' },
|
|
@@ -103,7 +104,8 @@ export function checkHitl(inputs, ctx) {
|
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
105
106
|
if (!hitlDerivesOutcomeHandles(variant) || outcomes.length === 0) {
|
|
106
|
-
|
|
107
|
+
// Its own code: this flow compiles, so the code is check's alone.
|
|
108
|
+
at('HITL_LEGACY_COMPLETED_NO_EFFECT', `Human task "${step}" sets legacyCompleted: true, but ${outcomes.length === 0 ? 'it has no outcomes'
|
|
107
109
|
: `its variant is "${variant}", which reads its outcomes from its app`}, so 'completed' is already its only exit.`, 'Drop `legacyCompleted`.');
|
|
108
110
|
return;
|
|
109
111
|
}
|
|
@@ -20,6 +20,7 @@ import { jsonClone } from '../../../core/json-clone.js';
|
|
|
20
20
|
import { schemaId } from '../../../core/stable-id.js';
|
|
21
21
|
import { wireExprBody } from '../../../core/wire-expr.js';
|
|
22
22
|
import { checkHitl, checkHitlRead } from './check.js';
|
|
23
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
23
24
|
const BASE = 'uipath.human-in-the-loop';
|
|
24
25
|
const QUICK_FORM = 'uipath.human-in-the-loop.quick-form';
|
|
25
26
|
const ACTION_APP = 'uipath.human-in-the-loop.coded-action-app';
|
|
@@ -556,23 +557,23 @@ function hitlAt(typeName, version, factory) {
|
|
|
556
557
|
const pinned = ctx.pinnedVersion;
|
|
557
558
|
const exitModel = hitlExitModel(inputs, pinned);
|
|
558
559
|
if (typeName !== BASE && inputs?.exposeError === true) {
|
|
559
|
-
throw new
|
|
560
|
+
throw new CompileRefusal('HITL_OUTCOME_PORTS_VARIANT', `"${ctx.step}": exposeError needs the base human task's 1.2 definition, which adds the `
|
|
560
561
|
+ `error output — the '${inputs?.variant}' variant has no such version. Drop the variant or exposeError.`);
|
|
561
562
|
}
|
|
562
563
|
if (inputs?.outcomePorts === true && !OUTCOME_HANDLE_NODE_TYPES.has(typeName)) {
|
|
563
|
-
throw new
|
|
564
|
+
throw new CompileRefusal('HITL_OUTCOME_PORTS_VARIANT', `"${ctx.step}": outcomePorts: true, but the '${inputs?.variant}' variant reads its outcomes `
|
|
564
565
|
+ `from its app and leaves on its single 'completed' exit. Route on out('${ctx.step}', 'Action') downstream.`);
|
|
565
566
|
}
|
|
566
567
|
if (inputs?.legacyCompleted === true && (inputs?.outcomePorts !== undefined || inputs?.exposeError === true)) {
|
|
567
|
-
throw new
|
|
568
|
+
throw new CompileRefusal('HITL_LEGACY_COMPLETED_CONFLICT', `"${ctx.step}": legacyCompleted: true leaves the task on its single 'completed' handle, so it cannot also `
|
|
568
569
|
+ `${inputs?.exposeError === true ? 'expose the error output (exposeError)' : 'set outcomePorts'}. Drop one.`);
|
|
569
570
|
}
|
|
570
571
|
if (inputs?.legacyCompleted === true && typeName === BASE && (pinned === '1.1' || pinned === '1.2')) {
|
|
571
|
-
throw new
|
|
572
|
+
throw new CompileRefusal('HITL_LEGACY_COMPLETED_VERSION', `"${ctx.step}": legacyCompleted: true, but { version: '${pinned}' } pins the task's per-outcome definition, `
|
|
572
573
|
+ `which has no 'completed' handle (flow validate refuses the edge). Drop the pin or legacyCompleted.`);
|
|
573
574
|
}
|
|
574
575
|
if (inputs?.exposeError === true && pinned !== undefined && pinned !== '1.2') {
|
|
575
|
-
throw new
|
|
576
|
+
throw new CompileRefusal('HITL_EXPOSE_ERROR_VERSION', `"${ctx.step}": exposeError needs the task's 1.2 definition, but { version: '${pinned}' } pins it. `
|
|
576
577
|
+ `Drop the pin or match it.`);
|
|
577
578
|
}
|
|
578
579
|
const { inputs: nodeInputs, outputs } = hitlInputs(inputs, typeName, ctx);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* docs/NODE_TYPE_ARCHITECTURE_DESIGN.md; the package entry re-exports it.
|
|
4
4
|
*/
|
|
5
5
|
import { builtinActionSpec } from '../../../core/actions.js';
|
|
6
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
6
7
|
/**
|
|
7
8
|
* Declare an HTTP request action, explicitly choosing standalone or managed.
|
|
8
9
|
*
|
|
@@ -12,7 +13,7 @@ import { builtinActionSpec } from '../../../core/actions.js';
|
|
|
12
13
|
*/
|
|
13
14
|
export function http(inputs) {
|
|
14
15
|
if (typeof inputs.managed !== 'boolean') {
|
|
15
|
-
throw new
|
|
16
|
+
throw new CompileRefusal('HTTP_MANAGED_REQUIRED', 'http() requires managed: true or managed: false because they emit different platform nodes. '
|
|
16
17
|
+ 'Use true for Managed HTTP Request/core.action.http.v2 or when non-2xx statuses must reach .onError(); '
|
|
17
18
|
+ 'use false for the standalone core.action.http node.');
|
|
18
19
|
}
|
|
@@ -12,6 +12,7 @@ import { MANAGED_HTTP_ACTIVITY_TYPE_ID, MANAGED_HTTP_ESSENTIAL_CONFIGURATION, MA
|
|
|
12
12
|
import { isRecord } from '../../../core/node-envelope.js';
|
|
13
13
|
import { wireExprBody } from '../../../core/wire-expr.js';
|
|
14
14
|
import { checkHttpRead, checkHttpStep, plainHttpOnErrorMessage } from './check.js';
|
|
15
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
15
16
|
const PLAIN = 'core.action.http';
|
|
16
17
|
const MANAGED = 'core.action.http.v2';
|
|
17
18
|
/** The definition's `inputDefaults` at the version being emitted. */
|
|
@@ -67,7 +68,7 @@ function plainHttpInputs(i, ctx) {
|
|
|
67
68
|
if (i.connection !== undefined
|
|
68
69
|
|| i.folder !== undefined
|
|
69
70
|
|| i.targetConnector !== undefined) {
|
|
70
|
-
throw new
|
|
71
|
+
throw new CompileRefusal('HTTP_BINDING_REQUIRES_MANAGED', 'standalone http cannot use Integration Service connection settings; set managed: true');
|
|
71
72
|
}
|
|
72
73
|
return {
|
|
73
74
|
...defaults(ctx, PLAIN),
|
|
@@ -91,7 +92,7 @@ function managedHttpBinding(i, ctx) {
|
|
|
91
92
|
return undefined;
|
|
92
93
|
if (typeof i.connection !== 'string' || i.connection.trim() === ''
|
|
93
94
|
|| typeof i.folder !== 'string' || i.folder.trim() === '') {
|
|
94
|
-
throw new
|
|
95
|
+
throw new CompileRefusal('HTTP_MANAGED_BINDING_INCOMPLETE', 'managed http connection mode requires both a non-empty connection and folder');
|
|
95
96
|
}
|
|
96
97
|
// The same resolution a connector step gets: a self-referential binding is an
|
|
97
98
|
// error, a stub is a warning.
|
|
@@ -121,11 +122,11 @@ function managedHttpBinding(i, ctx) {
|
|
|
121
122
|
*/
|
|
122
123
|
function managedHttpInputs(i, binding, ctx) {
|
|
123
124
|
if (i.targetConnector !== undefined && !binding) {
|
|
124
|
-
throw new
|
|
125
|
+
throw new CompileRefusal('HTTP_TARGET_CONNECTOR_REQUIRES_BINDING', 'managed http targetConnector requires both a non-empty connection and folder');
|
|
125
126
|
}
|
|
126
127
|
if (i.targetConnector !== undefined
|
|
127
128
|
&& (typeof i.targetConnector !== 'string' || i.targetConnector.trim() === '')) {
|
|
128
|
-
throw new
|
|
129
|
+
throw new CompileRefusal('HTTP_TARGET_CONNECTOR_EMPTY', 'managed http targetConnector must be a non-empty connector key');
|
|
129
130
|
}
|
|
130
131
|
const url = ctx.render(i.url);
|
|
131
132
|
const bodyParameters = {
|
|
@@ -270,7 +271,7 @@ function liftHttp(node, ctx, managed) {
|
|
|
270
271
|
const connectionValue = detail.connectionId ?? detail.connectionResourceId ?? req.connection;
|
|
271
272
|
const retry = inputs.retryCount !== undefined && Number(inputs.retryCount) !== 0 ? Number(inputs.retryCount) : undefined;
|
|
272
273
|
if (retry !== undefined && !Number.isFinite(retry)) {
|
|
273
|
-
throw new
|
|
274
|
+
throw new CompileRefusal('DECOMPILE_NOT_A_NUMBER', `decompile: expected a number, got ${JSON.stringify(inputs.retryCount)}.`);
|
|
274
275
|
}
|
|
275
276
|
const branchRows = Array.isArray(inputs.branches) ? inputs.branches : [];
|
|
276
277
|
const returns = liftReturns(node) ?? returnsFromReads(ctx.reads());
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* docs/NODE_TYPE_ARCHITECTURE_DESIGN.md; the package entry re-exports them.
|
|
5
5
|
*/
|
|
6
6
|
import { builtinActionSpec } from '../../../core/actions.js';
|
|
7
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
7
8
|
/**
|
|
8
9
|
* Invoke a deployed RPA (robotic process automation) workflow — a classic
|
|
9
10
|
* UI-automation process, published to Orchestrator, run by a robot.
|
|
@@ -166,7 +167,7 @@ export function agenticProcess(inputs) {
|
|
|
166
167
|
// code — and silently dropping the returns would validate a read that can
|
|
167
168
|
// never be satisfied.
|
|
168
169
|
if (inputs.completion === 'fire-and-forget' && inputs.returns !== undefined) {
|
|
169
|
-
throw new
|
|
170
|
+
throw new CompileRefusal('FIRE_AND_FORGET_RETURNS', "agenticProcess(): completion 'fire-and-forget' publishes no output — remove `returns`, "
|
|
170
171
|
+ "or use completion: 'wait' to read the process result.");
|
|
171
172
|
}
|
|
172
173
|
return builtinActionSpec({ kind: 'agenticProcess', inputs });
|
|
@@ -3,6 +3,7 @@ import { jsonClone } from '../../../core/json-clone.js';
|
|
|
3
3
|
import { isRecord } from '../../../core/node-envelope.js';
|
|
4
4
|
import { checkQueueItem, itemDataIsString, queueItemExprMessage } from './check.js';
|
|
5
5
|
import { QUEUE_ITEM_RECORD_SCHEMA } from './record.js';
|
|
6
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
6
7
|
const CREATE = 'core.action.queue.create';
|
|
7
8
|
const CREATE_AND_WAIT = 'core.action.queue.create-and-wait';
|
|
8
9
|
/**
|
|
@@ -39,7 +40,7 @@ function queueItemDef(spec, nodeType, stepName, ids, base) {
|
|
|
39
40
|
// The template at the version being emitted: the registry resolved it exactly
|
|
40
41
|
// (an unregistered pin is NODE_VERSION_UNREGISTERED before this runs).
|
|
41
42
|
if (!base)
|
|
42
|
-
throw new Error(`no bundled definition for "${nodeType}"`);
|
|
43
|
+
throw new Error(`internal SDK error: no bundled definition for "${nodeType}"`);
|
|
43
44
|
const def = jsonClone(base);
|
|
44
45
|
def.model.bindings.resourceKey = spec.key;
|
|
45
46
|
def.model.context = [
|
|
@@ -172,7 +173,7 @@ function itemDataString(item, step, typeName, version) {
|
|
|
172
173
|
return '';
|
|
173
174
|
for (const [k, v] of rows) {
|
|
174
175
|
if (v instanceof Expr)
|
|
175
|
-
throw new
|
|
176
|
+
throw new CompileRefusal('QUEUE_ITEM_EXPR_UNSUPPORTED', queueItemExprMessage(step, typeName, version, k));
|
|
176
177
|
}
|
|
177
178
|
return JSON.stringify(item);
|
|
178
179
|
}
|
|
@@ -11,6 +11,7 @@ import { wireExprBody } from '../../../core/wire-expr.js';
|
|
|
11
11
|
import { jsonClone } from '../../../core/json-clone.js';
|
|
12
12
|
import { VARIANT_OPERATION } from './spec.js';
|
|
13
13
|
import { checkTransform } from './check.js';
|
|
14
|
+
import { CompileRefusal } from '../../../core/compile-refusal.js';
|
|
14
15
|
/**
|
|
15
16
|
* Emit a transform's `inputs` in the canonical shape the node's runtime reads:
|
|
16
17
|
* `collection` as a BARE variable path (not `=js:`-prefixed — it is a path
|
|
@@ -210,7 +211,7 @@ function transformAt(typeName, variant, version, factory) {
|
|
|
210
211
|
// (TRANSFORM_VARIANT_UNKNOWN). A compile that skipped check refuses here
|
|
211
212
|
// rather than emit the generic node, which would run and be the wrong node.
|
|
212
213
|
if (variant === undefined && inputs?.variant !== undefined && inputs.variant !== null) {
|
|
213
|
-
throw new
|
|
214
|
+
throw new CompileRefusal('TRANSFORM_VARIANT_UNKNOWN', `transform step "${ctx.step}": variant ${JSON.stringify(inputs.variant)} is not a Transform node type `
|
|
214
215
|
+ `(${VARIANTS.join(', ')}), so there is no node to emit. Fix the variant, or omit it for the generic Transform.`);
|
|
215
216
|
}
|
|
216
217
|
const base = ctx.definition(typeName, version)?.outputDefinition;
|
package/dist/raw-node.js
CHANGED
|
@@ -10,6 +10,7 @@ import { connectorRawNodeRefusal } from './core/connector-raw-node.js';
|
|
|
10
10
|
import { rawNodeInputProblem, rawNodeTypedFamilyWarning } from './raw-node-advice.js';
|
|
11
11
|
import { forwardFanOut } from './core/definition-handles.js';
|
|
12
12
|
import { RAW_NODE_EXITS } from './core/raw-node-exits.js';
|
|
13
|
+
import { CompileRefusal } from './core/compile-refusal.js';
|
|
13
14
|
/**
|
|
14
15
|
* Place a node this SDK has no factory for, carrying its definition verbatim
|
|
15
16
|
* (`uipath.exotic.thing@2.1` and the manifest the platform served for it).
|
|
@@ -101,12 +102,12 @@ class RawNode extends FlowAction {
|
|
|
101
102
|
// type never reads is refused by the serializer, for every contribution.)
|
|
102
103
|
const refusal = connectorRawNodeRefusal(this.spec.nodeType);
|
|
103
104
|
if (refusal)
|
|
104
|
-
throw new
|
|
105
|
+
throw new CompileRefusal('RAW_NODE_CONNECTOR', refusal);
|
|
105
106
|
const version = context.requestedVersion ?? this.spec.version;
|
|
106
107
|
if (context.requestedVersion !== undefined && context.requestedVersion !== this.spec.version) {
|
|
107
108
|
// Versions are exact everywhere in this SDK: a contributor may not
|
|
108
109
|
// substitute its own for an explicit request (design §2.6).
|
|
109
|
-
throw new
|
|
110
|
+
throw new CompileRefusal('RAW_NODE_VERSION_MISMATCH', `rawNode("${this.spec.nodeType}") carries version ${this.spec.version}, but the step requests `
|
|
110
111
|
+ `${context.requestedVersion}. Pass the manifest for the requested version, or drop { version }.`);
|
|
111
112
|
}
|
|
112
113
|
return {
|