@uipath/flow-tool 1.0.4 → 1.195.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/README.md +15 -18
- package/dist/init.d.ts +6 -0
- package/dist/init.js +88528 -0
- package/dist/packager-tool.js +58792 -18266
- package/dist/services/connector-binding-validator.d.ts +95 -0
- package/dist/services/connector-node-types.d.ts +27 -0
- package/dist/services/flow-init-service.d.ts +41 -0
- package/dist/services/flow-validate-service.d.ts +100 -7
- package/dist/services/node-service.d.ts +108 -0
- package/dist/services/node-validators/activity-type-id-validator.d.ts +14 -0
- package/dist/services/node-validators/expression-prefix-validator.d.ts +3 -2
- package/dist/services/node-validators/index.d.ts +2 -0
- package/dist/services/node-validators/ixp-node-validator.d.ts +2 -0
- package/dist/services/node-validators/model-source-validator.d.ts +5 -3
- package/dist/services/packaging-utils.d.ts +111 -0
- package/dist/tool.js +241251 -124205
- package/dist/utils/error-edge-handling.d.ts +11 -0
- package/dist/utils/flow-io.d.ts +11 -0
- package/dist/validation.js +30064 -15352
- package/package.json +35 -60
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connector-binding shape validator (MST-9810, upstream UiPath/cli#2027).
|
|
3
|
+
*
|
|
4
|
+
* `uip maestro flow validate` historically only checked that `node.type`
|
|
5
|
+
* existed in the definitions[] list. A flow whose nodes are generic Managed
|
|
6
|
+
* HTTP placeholders (`core.action.http.v2`) labelled like connector activities
|
|
7
|
+
* — e.g. `name: "Send Slack Message"`, `display.label: "Create Jira Issue"` —
|
|
8
|
+
* with no `inputs.detail` binding therefore passed validation cleanly, then
|
|
9
|
+
* 404'd at runtime against the unconfigured HTTP endpoint.
|
|
10
|
+
*
|
|
11
|
+
* This module looks at every Managed-HTTP node, derives whether the label is
|
|
12
|
+
* "connector-shaped" (mentions a connector keyword from the cached IS catalog
|
|
13
|
+
* or a static fallback list), and verifies that the node carries either a
|
|
14
|
+
* connector-mode or manual-mode binding. Misses surface as a `warning` by
|
|
15
|
+
* default and as `error` under `--strict-bindings`.
|
|
16
|
+
*
|
|
17
|
+
* Catalog lookup is best-effort: when the registry cache is missing
|
|
18
|
+
* (offline / first-run), a small static keyword list keeps the check active
|
|
19
|
+
* for the most common connectors (Slack, Gmail, Jira, Salesforce, …) rather
|
|
20
|
+
* than going silent — these are the same connectors most likely to be
|
|
21
|
+
* referenced by hallucinating agents.
|
|
22
|
+
*/
|
|
23
|
+
import type { ValidationIssue } from "./node-validators/types.js";
|
|
24
|
+
/** Generic Managed HTTP node type — the type that historically slipped through. */
|
|
25
|
+
export declare const MANAGED_HTTP_NODE_TYPE = "core.action.http.v2";
|
|
26
|
+
/**
|
|
27
|
+
* Structural shape of a flow node the binding validator needs. Kept loose so
|
|
28
|
+
* `ParsedWorkflow` nodes satisfy it without a cast — fields beyond this set
|
|
29
|
+
* are ignored.
|
|
30
|
+
*/
|
|
31
|
+
export interface ConnectorBindingNode {
|
|
32
|
+
id: string;
|
|
33
|
+
type: string;
|
|
34
|
+
name?: unknown;
|
|
35
|
+
display?: {
|
|
36
|
+
label?: unknown;
|
|
37
|
+
} & Record<string, unknown>;
|
|
38
|
+
inputs?: Record<string, unknown>;
|
|
39
|
+
}
|
|
40
|
+
/** Structural shape of the workflow envelope the validator walks. */
|
|
41
|
+
export interface ConnectorBindingWorkflow {
|
|
42
|
+
nodes: ConnectorBindingNode[];
|
|
43
|
+
subflows?: Record<string, {
|
|
44
|
+
nodes?: ConnectorBindingNode[];
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
export interface ConnectorBindingValidationOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Promote each emitted issue from `warning` to `error`. Wired to the
|
|
50
|
+
* `--strict-bindings` CLI flag. Useful for CI gates that want a
|
|
51
|
+
* mislabeled HTTP node to fail the build rather than passively warn.
|
|
52
|
+
*/
|
|
53
|
+
strict?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Test-time injection. When provided, this overrides whatever
|
|
56
|
+
* `loadRegistry()` would return. Lets specs assert behavior against a
|
|
57
|
+
* known catalog without touching the user's real cache.
|
|
58
|
+
*/
|
|
59
|
+
catalogOverride?: ConnectorCatalog;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Compact view of the IS catalog the validator actually needs — connector
|
|
63
|
+
* keywords (`key`, `name`) and a flat list of activity display tokens.
|
|
64
|
+
* Built once per `validateFile` from the cached `MaestroRegistry`.
|
|
65
|
+
*/
|
|
66
|
+
export interface ConnectorCatalog {
|
|
67
|
+
/**
|
|
68
|
+
* Connector keyword tokens (e.g. "slack" derived from `uipath-uipath-slack`
|
|
69
|
+
* → strip "uipath-" prefix → split by "-"). Lower-cased.
|
|
70
|
+
*/
|
|
71
|
+
keywords: Set<string>;
|
|
72
|
+
/**
|
|
73
|
+
* Activity displayName token bags — each entry is the set of lowercase
|
|
74
|
+
* tokens from one activity's displayName. A label whose tokens match
|
|
75
|
+
* any entry (subset or superset) is considered connector-shaped.
|
|
76
|
+
*/
|
|
77
|
+
activityTokenBags: Array<{
|
|
78
|
+
connectorKey: string;
|
|
79
|
+
connectorName: string;
|
|
80
|
+
tokens: Set<string>;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build a `ConnectorCatalog` from the cached registry. Returns a catalog with
|
|
85
|
+
* empty `activityTokenBags` (but populated with static keywords) when no
|
|
86
|
+
* cache exists — so the check still fires for offline users.
|
|
87
|
+
*/
|
|
88
|
+
export declare function loadConnectorCatalog(): Promise<ConnectorCatalog>;
|
|
89
|
+
/**
|
|
90
|
+
* Walk every node in the flow + every subflow and emit one issue per
|
|
91
|
+
* unbound, connector-shaped Managed HTTP node. Scope mirrors
|
|
92
|
+
* `validateResourceBindings` so the new check stays consistent with the
|
|
93
|
+
* §A4 binding-integrity pass already in `FlowValidateService`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function validateConnectorBindings(workflow: ConnectorBindingWorkflow, catalog: ConnectorCatalog, options?: Pick<ConnectorBindingValidationOptions, "strict">): ValidationIssue[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-type predicates for Integration Service connector nodes in a Flow.
|
|
3
|
+
*
|
|
4
|
+
* Centralized so every consumer — the configure/routing logic in
|
|
5
|
+
* `connector-service.ts` and the flow validators in `node-validators/` —
|
|
6
|
+
* classifies connector nodes the same way. Triggers and wait-for-event nodes
|
|
7
|
+
* share the same detail shape and event-driven semantics; classifying them
|
|
8
|
+
* differently across validators produced inconsistent verdicts for equivalent
|
|
9
|
+
* nodes.
|
|
10
|
+
*/
|
|
11
|
+
/** Start-trigger nodes (`uipath.connector.trigger.*`). */
|
|
12
|
+
export declare function isConnectorTriggerType(nodeType: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Mid-flow wait-for-event nodes (`uipath.connector.event.*`,
|
|
15
|
+
* Intsvc.WaitForEvent / bpmn:ReceiveTask). They share the start-trigger config
|
|
16
|
+
* shape (connectionId/folderKey/eventMode/...) but flip
|
|
17
|
+
* instanceParameters.activityType to "CuratedWaitFor" — Studio Web applies the
|
|
18
|
+
* same translation when persisting these nodes.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isConnectorWaitForEventType(nodeType: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Event-driven connector nodes — start triggers and mid-flow wait-for-event
|
|
23
|
+
* nodes. Both carry eventMode/eventType/eventParameters and leave
|
|
24
|
+
* httpMethod/path null (the shape Studio Web emits), so the activity-only HTTP
|
|
25
|
+
* method/endpoint and `=js:` expression-prefix rules must not fire on them.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isEventDrivenConnectorType(nodeType: string): boolean;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface FlowInitOptions {
|
|
2
|
+
/** Initialize even if the target directory exists and is not empty. */
|
|
3
|
+
force?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Base dir the bare project `name` resolves against. Defaults to `process.cwd()`;
|
|
6
|
+
* lets library callers set a root without mutating the global cwd.
|
|
7
|
+
*/
|
|
8
|
+
cwd?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Inlined mirror of solution-sdk's `ProjectSolutionRegistration`, kept local so the
|
|
12
|
+
* published `init.d.ts` stays free of the private SDK type. Structurally assignable
|
|
13
|
+
* from the real type.
|
|
14
|
+
*/
|
|
15
|
+
export interface FlowProjectRegistration {
|
|
16
|
+
Status: string;
|
|
17
|
+
Message?: string;
|
|
18
|
+
Instructions?: string;
|
|
19
|
+
Solution?: string;
|
|
20
|
+
Project?: string;
|
|
21
|
+
ProjectId?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FlowInitResult {
|
|
24
|
+
projectName: string;
|
|
25
|
+
/** Absolute path to the created project directory. */
|
|
26
|
+
projectDir: string;
|
|
27
|
+
/** Absolute path to the written `<name>.flow`. */
|
|
28
|
+
flowFile: string;
|
|
29
|
+
/**
|
|
30
|
+
* Parent-solution registration result. Always defined (MST-10004): when no
|
|
31
|
+
* parent `.uipx` is found, its Status is "NotInSolution" rather than the
|
|
32
|
+
* field being absent, so callers can always read the outcome.
|
|
33
|
+
*/
|
|
34
|
+
registration: FlowProjectRegistration;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Programmatic core of `uip maestro flow init`: scaffolds `project.uiproj` + `<name>.flow`
|
|
38
|
+
* and registers the project into a parent `.uipx` solution when present. Throws on failure;
|
|
39
|
+
* does not touch `OutputFormatter`/`processContext` (the command wraps it for output + exit).
|
|
40
|
+
*/
|
|
41
|
+
export declare function flowInitAsync(name: string, options?: FlowInitOptions): Promise<FlowInitResult>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NodeManifest } from "@uipath/flow-core";
|
|
2
|
+
import { type ConnectorCatalog } from "./connector-binding-validator.js";
|
|
2
3
|
import { type FlowNodeValidator, type ValidationIssue } from "./node-validators/index.js";
|
|
3
4
|
import type { WorkflowGovernanceEnforcements, WorkflowValidationRule } from "./node-validators/workflow-rule-types.js";
|
|
4
5
|
interface FlowValidateResult {
|
|
@@ -15,7 +16,7 @@ type ManifestForCurrentValidation = Pick<NodeManifest, "nodeType" | "version" |
|
|
|
15
16
|
*/
|
|
16
17
|
export interface FlowValidateOptions {
|
|
17
18
|
/**
|
|
18
|
-
* Extra workflow-scoped rules appended after `
|
|
19
|
+
* Extra workflow-scoped rules appended after `cliRules` and
|
|
19
20
|
* `conditionExpressionRule`. Authored against the structural shape
|
|
20
21
|
* of `@uipath/flow-schema`'s `ValidationRule` — either directly or
|
|
21
22
|
* via the locally-declared `WorkflowValidationRule` which avoids
|
|
@@ -51,6 +52,18 @@ export interface FlowValidateOptions {
|
|
|
51
52
|
* enables current-manifest validation.
|
|
52
53
|
*/
|
|
53
54
|
currentManifests?: ManifestForCurrentValidation[];
|
|
55
|
+
/**
|
|
56
|
+
* Promote connector-binding shape warnings (MST-9810) to errors. By
|
|
57
|
+
* default, an unbound Managed HTTP node carrying a connector-shaped label
|
|
58
|
+
* emits a warning so existing flows keep validating green; CI gates
|
|
59
|
+
* opt in via `--strict-bindings` to fail the build instead.
|
|
60
|
+
*/
|
|
61
|
+
strictBindings?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Test/host override for the connector catalog used by the binding-shape
|
|
64
|
+
* validator. Supplying this skips the `loadRegistry()` cache lookup.
|
|
65
|
+
*/
|
|
66
|
+
connectorCatalog?: ConnectorCatalog;
|
|
54
67
|
}
|
|
55
68
|
export declare class FlowValidateService {
|
|
56
69
|
private readonly fs;
|
|
@@ -60,7 +73,10 @@ export declare class FlowValidateService {
|
|
|
60
73
|
private readonly availableModelNames?;
|
|
61
74
|
private readonly validateCurrentManifests;
|
|
62
75
|
private readonly currentManifestOverrides?;
|
|
76
|
+
private readonly strictBindings;
|
|
77
|
+
private readonly connectorCatalogOverride?;
|
|
63
78
|
private currentManifestCache?;
|
|
79
|
+
private connectorCatalogCache?;
|
|
64
80
|
constructor(options?: FlowValidateOptions);
|
|
65
81
|
execute(flowFilePath: string): Promise<number>;
|
|
66
82
|
private loadCurrentManifestMap;
|
|
@@ -73,12 +89,12 @@ export declare class FlowValidateService {
|
|
|
73
89
|
* settings) from the agent's `messages` array so that schema
|
|
74
90
|
* validation sees them.
|
|
75
91
|
*
|
|
76
|
-
* The UUID
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* `
|
|
81
|
-
*
|
|
92
|
+
* The UUID must be at `inputs.source` (canonical post-flow-core-0.2.50).
|
|
93
|
+
* The autonomous-agent manifest's `model.source: true` declaration is the
|
|
94
|
+
* trigger that this node requires a source UUID; the per-instance write
|
|
95
|
+
* location moved from `model.source` to `inputs.source` in flow-core
|
|
96
|
+
* 0.2.50, and `model-source-validator.ts` now rejects flows that still
|
|
97
|
+
* carry the legacy `model.source` UUID. MST-9263.
|
|
82
98
|
*
|
|
83
99
|
* Returns a map of `nodeId → AgentHydrationDiagnosis` so callers can
|
|
84
100
|
* decorate downstream `REQUIRED_FIELD` validator errors with a
|
|
@@ -100,6 +116,83 @@ export declare class FlowValidateService {
|
|
|
100
116
|
private validateUniqueIds;
|
|
101
117
|
/** Uniqueness check for `variables.globals` IDs; called once per scope (root + each subflow). */
|
|
102
118
|
private validateGlobalVariableUniqueness;
|
|
119
|
+
/**
|
|
120
|
+
* Resource-node bindings integrity (residual roadmap §A4, [MST-9712]).
|
|
121
|
+
*
|
|
122
|
+
* Every process-typed node (RPA workflow, agent, API workflow, agent-tool
|
|
123
|
+
* process — see PROCESS_NODE_PREFIXES) referenced anywhere in the flow
|
|
124
|
+
* — top-level `nodes[]` AND every subflow's `nodes[]` — must have a
|
|
125
|
+
* corresponding `workflow.bindings` entry whose `resourceKey` covers the
|
|
126
|
+
* node's needs. Without it, the workflow passes `flow validate` today but
|
|
127
|
+
* fails opaquely at runtime as "Failure in the Orchestrator Job".
|
|
128
|
+
*
|
|
129
|
+
* Uses `collectNodeBindingResourceKeys` from `node-service.ts` (the same
|
|
130
|
+
* helper `ensureProcessBindings` uses on the write path) to compute each
|
|
131
|
+
* process node's needed resource keys, then checks each against the
|
|
132
|
+
* declared `bindings[].resourceKey` set.
|
|
133
|
+
*/
|
|
134
|
+
private validateResourceBindings;
|
|
135
|
+
/**
|
|
136
|
+
* Cross-node connection ID reuse (residual roadmap §A6, [MST-9714]).
|
|
137
|
+
*
|
|
138
|
+
* Two distinct nodes referencing the same `inputs.detail.connectionResourceId`
|
|
139
|
+
* share runtime connection state. Often that's a bug (a node was duplicated
|
|
140
|
+
* without re-pointing the connection); sometimes it's intentional (two
|
|
141
|
+
* connectors on the same SaaS account, sharing rate-limit headroom).
|
|
142
|
+
*
|
|
143
|
+
* Severity: `warning` — legitimate sharing exists, so don't block validate.
|
|
144
|
+
* Users can investigate or ignore as appropriate.
|
|
145
|
+
*
|
|
146
|
+
* Scope: top-level `workflow.nodes` + every `workflow.subflows[].nodes`
|
|
147
|
+
* (matches A4's iteration shape for consistency).
|
|
148
|
+
*/
|
|
149
|
+
private validateConnectionIdReuse;
|
|
150
|
+
/**
|
|
151
|
+
* Connector-binding shape check (MST-9810, upstream UiPath/cli#2027).
|
|
152
|
+
*
|
|
153
|
+
* Lazy-loads the IS connector catalog (cached registry from
|
|
154
|
+
* `~/.uipath/maestro/registry.json`, falling back to a static keyword
|
|
155
|
+
* list when no cache exists) and delegates to
|
|
156
|
+
* `validateConnectorBindings`. Promotes warnings to errors when
|
|
157
|
+
* constructed with `strictBindings: true` (wired to `--strict-bindings`).
|
|
158
|
+
*
|
|
159
|
+
* Catalog loading is best-effort and never throws: when the cache is
|
|
160
|
+
* missing or unreadable, the validator still runs against the static
|
|
161
|
+
* fallback keyword list. That keeps the check active for offline users
|
|
162
|
+
* who would otherwise be the most likely to hit this bug, while
|
|
163
|
+
* letting tests inject deterministic catalogs via
|
|
164
|
+
* `FlowValidateOptions.connectorCatalog`.
|
|
165
|
+
*/
|
|
166
|
+
private validateConnectorBindingShapes;
|
|
167
|
+
private loadConnectorCatalogCached;
|
|
168
|
+
/**
|
|
169
|
+
* Project↔solution registration + canonical-path layout (residual roadmap
|
|
170
|
+
* §A3, [MST-9711]). Walks up from the .flow's parent looking for a
|
|
171
|
+
* `.uipx` solution file. When one is found, asserts both:
|
|
172
|
+
*
|
|
173
|
+
* (a) the .flow's project directory is registered in the solution's
|
|
174
|
+
* projects[] list (matched by ProjectRelativePath's directory name),
|
|
175
|
+
* and
|
|
176
|
+
* (b) the canonical layout: <solution>/<projectName>/<projectName>.flow
|
|
177
|
+
* — i.e. the .flow file basename equals its parent directory name.
|
|
178
|
+
*
|
|
179
|
+
* Standalone authoring (no .uipx in any parent) is allowed — the rule
|
|
180
|
+
* stays silent in that case so single-flow workflows aren't penalised.
|
|
181
|
+
*
|
|
182
|
+
* Severity: warning. Both issues are recoverable (`uip solution project add`
|
|
183
|
+
* fixes registration; renaming the file or directory fixes the layout).
|
|
184
|
+
*/
|
|
185
|
+
private validateSolutionRegistrationAndLayout;
|
|
186
|
+
/**
|
|
187
|
+
* Best-effort path canonicalization for the registration-comparison
|
|
188
|
+
* call site. Returns `fs.realpath(p)` when the call succeeds, and
|
|
189
|
+
* the original `p` when it fails (e.g., the path doesn't exist).
|
|
190
|
+
* Falling back to the literal path is deliberate: a missing path is
|
|
191
|
+
* exactly the failure mode that the surrounding validator already
|
|
192
|
+
* surfaces via other issues, and canonicalization is an optimization
|
|
193
|
+
* for symlink/case-folding correctness, not a precondition.
|
|
194
|
+
*/
|
|
195
|
+
private canonicalizePath;
|
|
103
196
|
/**
|
|
104
197
|
* Catch stale embedded OOTB definitions. Studio Web renders against the
|
|
105
198
|
* current node manifest, while .flow files carry a serialized copy of the
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { NodeInstance, Workflow } from "@uipath/flow-core";
|
|
2
|
+
import { type ConnectorInfo } from "@uipath/maestro-sdk";
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when a node type is genuinely absent from the SDK bundle and the
|
|
5
|
+
* tenant manifest — i.e. a typo or a removed node.
|
|
6
|
+
*/
|
|
7
|
+
export declare class NodeTypeNotFoundError extends Error {
|
|
8
|
+
readonly code = "NodeTypeNotFound";
|
|
9
|
+
readonly instructions: string;
|
|
10
|
+
constructor(message: string, instructions: string);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Thrown when a node type IS in the SDK bundle (so it exists as a feature on
|
|
14
|
+
* the platform) but is missing from the loaded tenant manifest — almost always
|
|
15
|
+
* a feature-flag / entitlement gate.
|
|
16
|
+
*/
|
|
17
|
+
export declare class NodeTypeNotEnabledError extends Error {
|
|
18
|
+
readonly code = "NodeTypeNotEnabled";
|
|
19
|
+
readonly instructions: string;
|
|
20
|
+
constructor(message: string, instructions: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Thrown when adding a node whose manifest declares `model.source: true`
|
|
24
|
+
* (inline agents, agent-tool resources) without supplying the per-instance
|
|
25
|
+
* source UUID. The CLI can't fabricate this value — it must match the
|
|
26
|
+
* ProjectId of the colocated `<projectId>/agent.json` produced by
|
|
27
|
+
* `uip agent init --inline-in-flow`. Without it the resulting node has
|
|
28
|
+
* neither `inputs.source` nor `model.source`, which `model-source-validator`
|
|
29
|
+
* later rejects (MST-9265).
|
|
30
|
+
*/
|
|
31
|
+
export declare class SourceRequiredError extends Error {
|
|
32
|
+
readonly code = "SourceRequired";
|
|
33
|
+
readonly instructions: string;
|
|
34
|
+
constructor(message: string, instructions: string);
|
|
35
|
+
}
|
|
36
|
+
export interface NodeSummary {
|
|
37
|
+
id: string;
|
|
38
|
+
type: string;
|
|
39
|
+
label: string;
|
|
40
|
+
position: {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface ListNodesResult {
|
|
46
|
+
nodes: NodeSummary[];
|
|
47
|
+
count: number;
|
|
48
|
+
}
|
|
49
|
+
export declare const listNodesInFlow: (filePath: string) => Promise<ListNodesResult>;
|
|
50
|
+
export interface AddNodeOptions {
|
|
51
|
+
position?: {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
};
|
|
55
|
+
label?: string;
|
|
56
|
+
inputs?: Record<string, unknown>;
|
|
57
|
+
source?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface AddNodeResult {
|
|
60
|
+
node: NodeInstance;
|
|
61
|
+
definitionAdded: boolean;
|
|
62
|
+
bindingsCreated: number;
|
|
63
|
+
variableCount: number;
|
|
64
|
+
connectorInfo?: ConnectorInfo;
|
|
65
|
+
}
|
|
66
|
+
export interface DeleteNodeResult {
|
|
67
|
+
deletedNode: NodeSummary;
|
|
68
|
+
edgesRemoved: number;
|
|
69
|
+
bindingsRemoved: number;
|
|
70
|
+
definitionsRemoved: number;
|
|
71
|
+
variablesRemoved: number;
|
|
72
|
+
variableUpdatesRemoved: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Node type prefixes that use process-style bindings (GUID as resourceKey).
|
|
76
|
+
* Covers RPA workflows, agent process tools, and agent nodes.
|
|
77
|
+
*/
|
|
78
|
+
export declare const PROCESS_NODE_PREFIXES: string[];
|
|
79
|
+
export declare function isProcessNode(manifest: {
|
|
80
|
+
nodeType: string;
|
|
81
|
+
}): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Safety net: ensure every process/agent node in the workflow has corresponding
|
|
84
|
+
* entries in the workflow `bindings` array and that `<bindings.*>` placeholders
|
|
85
|
+
* in node model.context are resolved to `=bindings.<id>` references.
|
|
86
|
+
*
|
|
87
|
+
* This handles flows authored outside the CLI (e.g. direct file edits or
|
|
88
|
+
* skill-generated files) where `addNodeToFlow` was never called, so the
|
|
89
|
+
* binding creation / resolution step was skipped.
|
|
90
|
+
*
|
|
91
|
+
* Mutates the workflow in place. Safe to call multiple times — already-resolved
|
|
92
|
+
* nodes are skipped.
|
|
93
|
+
*/
|
|
94
|
+
export declare function ensureProcessBindings(workflow: Workflow): number;
|
|
95
|
+
/**
|
|
96
|
+
* Collect all binding resourceKeys associated with a node.
|
|
97
|
+
* Handles three binding ownership patterns:
|
|
98
|
+
* 1. Process nodes — resourceKey from the definition's model.bindings.resourceKey,
|
|
99
|
+
* falling back to the process GUID extracted from the node type
|
|
100
|
+
* 2. Connector nodes — resourceKey is the connectionId stored in inputs.detail
|
|
101
|
+
* 3. Input refs — "=bindings.<id>" patterns resolved to resourceKeys
|
|
102
|
+
*/
|
|
103
|
+
export declare function collectNodeBindingResourceKeys(node: NodeInstance, bindings: Array<{
|
|
104
|
+
id: string;
|
|
105
|
+
resourceKey: string;
|
|
106
|
+
}>, definitions?: Array<Record<string, unknown>>): Set<string>;
|
|
107
|
+
export declare const addNodeToFlow: (filePath: string, nodeType: string, options?: AddNodeOptions) => Promise<AddNodeResult>;
|
|
108
|
+
export declare const deleteNodeFromFlow: (filePath: string, nodeId: string) => Promise<DeleteNodeResult>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { FlowNodeValidator } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Flags a configured Integration Service node that is missing
|
|
4
|
+
* `inputs.detail.uiPathActivityTypeId`. Without it, Studio Web crashes on
|
|
5
|
+
* canvas open — the property-panel renderer dereferences this field to
|
|
6
|
+
* resolve the activity configuration UI. The BPMN runtime tolerates the
|
|
7
|
+
* missing value (headless `flow debug` and deployed runs still complete),
|
|
8
|
+
* so the failure only surfaces when an operator opens the flow.
|
|
9
|
+
*
|
|
10
|
+
* Scope: `core.action.http.v2` and all `uipath.connector.<name>` nodes
|
|
11
|
+
* (activities, `*.trigger.*`, and `*.event.*` wait-for-event nodes).
|
|
12
|
+
* Severity: error.
|
|
13
|
+
*/
|
|
14
|
+
export declare const activityTypeIdValidator: FlowNodeValidator;
|
|
@@ -24,8 +24,9 @@ import type { FlowNodeValidator } from "./types.js";
|
|
|
24
24
|
* `=js:` so the agent gets an actionable error before `flow debug`.
|
|
25
25
|
*
|
|
26
26
|
* Scope:
|
|
27
|
-
* - Connector activity nodes (`uipath.connector.*`, excluding triggers
|
|
28
|
-
* missing-prefix scan against
|
|
27
|
+
* - Connector activity nodes (`uipath.connector.*`, excluding triggers and
|
|
28
|
+
* wait-for-event nodes) — missing-prefix scan against
|
|
29
|
+
* `inputs.detail.{body,query,path}Parameters`.
|
|
29
30
|
* - Managed HTTP nodes (`core.action.http.v2`) — same scan.
|
|
30
31
|
* - Custom HTTP nodes (`core.action.http`) — same scan.
|
|
31
32
|
* - Script nodes (`core.action.script`) — `inputs.source` literal-vs-
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { FlowNodeValidator } from "./types.js";
|
|
2
|
+
export { activityTypeIdValidator } from "./activity-type-id-validator.js";
|
|
2
3
|
export { connectorNodeValidator } from "./connector-validator.js";
|
|
3
4
|
export { expressionPrefixValidator } from "./expression-prefix-validator.js";
|
|
5
|
+
export { ixpNodeValidator } from "./ixp-node-validator.js";
|
|
4
6
|
export { modelSourceValidator } from "./model-source-validator.js";
|
|
5
7
|
export type { FlowNodeValidator, FlowValidatorContext, FlowValidatorNode, ValidationIssue, ValidationIssueSeverity, } from "./types.js";
|
|
6
8
|
/**
|
|
@@ -4,9 +4,11 @@ import type { FlowNodeValidator } from "./types.js";
|
|
|
4
4
|
* `model: { source: true, ... }` at the top level.
|
|
5
5
|
*
|
|
6
6
|
* flow-core 0.2.50 moved the per-instance source UUID from `node.model.source`
|
|
7
|
-
* to `node.inputs.source`.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* to `node.inputs.source`. The legacy `node.model.source` location is now
|
|
8
|
+
* deprecated: any node instance carrying a UUID there is reported as invalid
|
|
9
|
+
* so callers migrate it to `inputs.source`. The manifest-level declaration
|
|
10
|
+
* `definitions[].model.source: true` is still the trigger for this rule —
|
|
11
|
+
* only the persisted location on the node instance has moved.
|
|
10
12
|
*
|
|
11
13
|
* Scope:
|
|
12
14
|
* - Any node whose plugin manifest declares `model.source === true`.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { IFileSystem } from "@uipath/filesystem";
|
|
2
|
+
import { type EntryPoint, type PackagingBinding, type PackagingNode, type PackagingNodeManifest, type PackagingWorkflowVariables } from "@uipath/flow-schema";
|
|
3
|
+
interface FlowFileNode {
|
|
4
|
+
id: string;
|
|
5
|
+
type: string;
|
|
6
|
+
typeVersion?: string;
|
|
7
|
+
display?: Record<string, unknown>;
|
|
8
|
+
inputs?: Record<string, unknown>;
|
|
9
|
+
outputs?: Record<string, unknown>;
|
|
10
|
+
model?: Record<string, unknown>;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the inline-agent's projectId UUID from a flow node.
|
|
15
|
+
*
|
|
16
|
+
* Reads `inputs.source` (canonical, post-flow-core 0.2.50) and falls
|
|
17
|
+
* back through `model.source` plus the legacy `agentProjectId` aliases
|
|
18
|
+
* that flow-workbench's `extractInlineAgents` also walks. The
|
|
19
|
+
* `model.source` fallback exists so packaging tolerates already-deployed
|
|
20
|
+
* `.flow` files that still carry the legacy shape —
|
|
21
|
+
* `model-source-validator.ts` now flags `model.source` UUIDs as an
|
|
22
|
+
* invalid-flow error, so a deprecated flow is caught at validate time
|
|
23
|
+
* before reaching the packager in any normal workflow.
|
|
24
|
+
*
|
|
25
|
+
* Note: `packager/packager-tool-flow/src/flow-tool.ts` keeps an inline
|
|
26
|
+
* copy of this rule (`readSource` in `generateFlowPackagingArtifacts`).
|
|
27
|
+
* `flow-tool` already imports `@uipath/packager-tool-flow`, so the
|
|
28
|
+
* reverse import would create a cycle. If the priority list ever
|
|
29
|
+
* changes, update both copies — or lift the helper into
|
|
30
|
+
* `@uipath/flow-schema` (currently an external dep) and delete both.
|
|
31
|
+
*/
|
|
32
|
+
export declare function readInlineAgentSource(node: {
|
|
33
|
+
inputs?: Record<string, unknown>;
|
|
34
|
+
model?: Record<string, unknown>;
|
|
35
|
+
}): string | undefined;
|
|
36
|
+
/** Returns true when the node's type is a known inline-agent node type. */
|
|
37
|
+
export declare function isInlineAgentNodeType(type: string | undefined): boolean;
|
|
38
|
+
/** Returns true when the node's type is the conversational agent type. */
|
|
39
|
+
export declare function isConversationalAgentNodeType(type: string | undefined): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Convert file-format nodes (flat `inputs`/`display`/`outputs`) to the
|
|
42
|
+
* `PackagingNode` shape expected by flow-schema packaging helpers — also
|
|
43
|
+
* flat: `display`, `inputs`, `outputs`, and `model` sit at the top of the
|
|
44
|
+
* node, matching `inputsMatchBinding` and `getConnectionMetadata` in
|
|
45
|
+
* `getBindingResources`. We default `typeVersion` here for legacy file-format
|
|
46
|
+
* nodes that omit it; `toPackagingNodes` from flow-schema is an identity cast
|
|
47
|
+
* and does NOT remap fields, so we do that here.
|
|
48
|
+
*/
|
|
49
|
+
export declare function fileNodesToPackagingNodes(nodes: FlowFileNode[]): PackagingNode[];
|
|
50
|
+
/** Packaged inline agent with entry point and file metadata. */
|
|
51
|
+
export interface InlineAgentPackage {
|
|
52
|
+
/** The agent's projectId UUID (directory name). */
|
|
53
|
+
source: string;
|
|
54
|
+
/** Entry point for entry-points.json. */
|
|
55
|
+
entryPoint: EntryPoint;
|
|
56
|
+
/** The raw agent.json content (for .agent-builder/agent.json). */
|
|
57
|
+
agentJson: Record<string, unknown>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Scan workflow nodes for inline agents, read their agent.json,
|
|
61
|
+
* and build entry points + metadata for packaging.
|
|
62
|
+
*
|
|
63
|
+
* The source UUID is read via {@link readInlineAgentSource}, which
|
|
64
|
+
* accepts the canonical `inputs.source` location and tolerates legacy
|
|
65
|
+
* `model.source` UUIDs on already-packaged flows. New flows must use
|
|
66
|
+
* `inputs.source` — `model-source-validator.ts` rejects `model.source`
|
|
67
|
+
* UUIDs at validate time.
|
|
68
|
+
*/
|
|
69
|
+
export declare function packageInlineAgents(fs: IFileSystem, projectDir: string, nodes: Array<{
|
|
70
|
+
type: string;
|
|
71
|
+
inputs?: Record<string, unknown>;
|
|
72
|
+
model?: Record<string, unknown>;
|
|
73
|
+
}>): Promise<InlineAgentPackage[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Build inline-agent descriptors for a debug session's FpsProperties
|
|
76
|
+
* injection. Mirrors flow-workbench's `extractInlineAgents` shape:
|
|
77
|
+
* one entry per agent node with a resolvable source UUID.
|
|
78
|
+
*
|
|
79
|
+
* The runtime resolves each entry by `executorInfo.projectId`, so this
|
|
80
|
+
* walks every agent node — even the ones whose `agent.json` may not be
|
|
81
|
+
* on disk yet — and returns the descriptor list.
|
|
82
|
+
*
|
|
83
|
+
* `entryPointPath` is `<projectId>/agent.json` (no `content/` prefix —
|
|
84
|
+
* runtime resolves against the deployed package root).
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildInlineAgentDescriptors(nodes: Array<{
|
|
87
|
+
type: string;
|
|
88
|
+
display?: Record<string, unknown>;
|
|
89
|
+
inputs?: Record<string, unknown>;
|
|
90
|
+
model?: Record<string, unknown>;
|
|
91
|
+
}>): Array<{
|
|
92
|
+
name: string;
|
|
93
|
+
agentProjectId: string;
|
|
94
|
+
isConversational: boolean;
|
|
95
|
+
entryPointPath: string;
|
|
96
|
+
}>;
|
|
97
|
+
/**
|
|
98
|
+
* Write all packaging artifacts (operate.json, entry-points.json, bindings_v2.json,
|
|
99
|
+
* package-descriptor.json) into a directory using @uipath/flow-schema.
|
|
100
|
+
*
|
|
101
|
+
* Returns the computed entry points so callers can derive PIMS entry point paths
|
|
102
|
+
* without calling getEntryPoints again.
|
|
103
|
+
*/
|
|
104
|
+
export declare function writePackagingArtifacts(fs: IFileSystem, projectDir: string, projectId: string, packagingNodes: PackagingNode[], bindings: PackagingBinding[], variables: PackagingWorkflowVariables, bpmnFileName: string, startEventId: string, flowFileName?: string, definitions?: PackagingNodeManifest[]): Promise<EntryPoint[]>;
|
|
105
|
+
/**
|
|
106
|
+
* Re-read a .flow file and regenerate bindings_v2.json in the same project directory.
|
|
107
|
+
* Called after `node add` (process nodes), `node delete`, and `node configure` to
|
|
108
|
+
* keep bindings in sync with the .flow file.
|
|
109
|
+
*/
|
|
110
|
+
export declare function regenerateBindingsFile(fs: IFileSystem, flowFilePath: string): Promise<void>;
|
|
111
|
+
export {};
|