@uipath/maestro-builder-sdk 6.48.0 → 6.49.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/README.md +2 -2
- package/dist/api-index.md +43 -43
- package/dist/api-members.md +203 -203
- package/dist/bpmn/bpmn-sdk.d.ts +26 -21
- package/dist/bpmn/bpmn-sdk.js +32 -64
- package/dist/bpmn/check.js +18 -1
- package/dist/bpmn/compile-cli.js +1 -1
- package/dist/bpmn/decompile-cli.js +2 -2
- package/dist/bpmn/decompile.js +3 -3
- package/dist/bpmn/known-methods.d.ts +1 -1
- package/dist/bpmn/known-methods.js +1 -1
- package/dist/bpmn/managed-http.d.ts +56 -0
- package/dist/bpmn/managed-http.js +159 -0
- package/dist/bpmn/merge.js +1 -1
- package/dist/bpmn/serialize.d.ts +1 -2
- package/dist/bpmn/serialize.js +3 -4
- package/dist/cli/commands/bpmn.js +0 -9
- package/dist/core/managed-http.d.ts +43 -0
- package/dist/core/managed-http.js +37 -0
- package/dist/nodes/http/flow/node-type.js +4 -27
- package/package.json +2 -3
- package/dist/bpmn/tidy-cli.d.ts +0 -2
- package/dist/bpmn/tidy-cli.js +0 -38
package/dist/bpmn/bpmn-sdk.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* Diagram interchange (`bpmndi`) is intentionally **not** emitted here: BPMN
|
|
19
19
|
* validation is layout-independent, so the SDK emits semantic-only XML and a
|
|
20
|
-
*
|
|
20
|
+
* `uip maestro bpmn format` lays it out. See serialize.ts.
|
|
21
21
|
*/
|
|
22
22
|
import type { TypeDesc } from '../core/expr.js';
|
|
23
23
|
import { type ConnectorOpts, type EventFilter } from '../core/actions.js';
|
|
@@ -1157,16 +1157,19 @@ export interface DataServiceOpts extends ActivityOpts {
|
|
|
1157
1157
|
export interface HttpOpts extends ActivityOpts {
|
|
1158
1158
|
/** Display name the designer shows on the task. */
|
|
1159
1159
|
name?: string;
|
|
1160
|
-
/**
|
|
1160
|
+
/**
|
|
1161
|
+
* Request URL. Accepts an `=`-expression, including `=bindings.<id>`. In connector mode
|
|
1162
|
+
* (see {@link HttpOpts.connection}) it is the endpoint on the target connector, relative
|
|
1163
|
+
* to the connection's base URL, e.g. `/emoji.list`.
|
|
1164
|
+
*/
|
|
1161
1165
|
url: string;
|
|
1162
1166
|
/** HTTP method. Defaults to `'GET'`, matching the registry's own default. */
|
|
1163
1167
|
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
1164
1168
|
/** Request headers — serialized to the node's json context field. */
|
|
1165
1169
|
headers?: Record<string, unknown>;
|
|
1166
1170
|
/**
|
|
1167
|
-
* Query parameters — serialized to the node's json context field
|
|
1168
|
-
* (see {@link HttpOpts.connection})
|
|
1169
|
-
* a literal there.
|
|
1171
|
+
* Query parameters — serialized to the node's json context field, or to the request's
|
|
1172
|
+
* `query` in connector mode (see {@link HttpOpts.connection}).
|
|
1170
1173
|
*/
|
|
1171
1174
|
parameters?: Record<string, unknown>;
|
|
1172
1175
|
/**
|
|
@@ -1186,16 +1189,15 @@ export interface HttpOpts extends ActivityOpts {
|
|
|
1186
1189
|
* @remarks
|
|
1187
1190
|
* Without it the node is `Intsvc.UnifiedHttpRequest` in `mode="manual"`: the
|
|
1188
1191
|
* process owns the URL, headers and auth, and nothing on the tenant is involved.
|
|
1189
|
-
* With it the node is the
|
|
1190
|
-
* `
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
*
|
|
1192
|
+
* With it the node is the V2 `Intsvc.UnifiedHttpRequest` in connector mode, as
|
|
1193
|
+
* `uip maestro bpmn registry get Intsvc.UnifiedHttpRequest --connection-id` builds it:
|
|
1194
|
+
* context `connectorKey` `uipath-uipath-http`, the connection bound, and a `body` row
|
|
1195
|
+
* carrying the request
|
|
1196
|
+
* (`{"authentication":"connector","method":"GET","targetConnector":…,"connection":…,"path":…,"url":…,"headers":…,"query":…,"body":…}`),
|
|
1197
|
+
* whose auth is the connection's. A value that reads a variable is written `=js:`, as the
|
|
1198
|
+
* CLI writes it (`=vars.x` becomes `=js:vars.x`). That is the shape for "call an endpoint the
|
|
1194
1199
|
* connector catalog has no activity for, through an existing connection" — the
|
|
1195
|
-
* non-catalog HTTP fallback
|
|
1196
|
-
* both fallback cards (non-catalog-http-fallback, slack-http-fallback) authored a
|
|
1197
|
-
* connectionless node because this option did not exist, and the grader found
|
|
1198
|
-
* `connectorKey values seen: []`.
|
|
1200
|
+
* non-catalog HTTP fallback.
|
|
1199
1201
|
*
|
|
1200
1202
|
* Pair it with {@link HttpOpts.folder}; both resolve as `.dataService()`'s do — an
|
|
1201
1203
|
* existing binding by id, else `<id>_connection` / `<id>_folder` declared for you
|
|
@@ -1205,13 +1207,13 @@ export interface HttpOpts extends ActivityOpts {
|
|
|
1205
1207
|
* belongs to one (see {@link HttpOpts.connectorKey}).
|
|
1206
1208
|
*/
|
|
1207
1209
|
connection?: string;
|
|
1208
|
-
/** Symbolic binding name of the connection's folder — connector mode only. */
|
|
1210
|
+
/** Symbolic binding name of the connection's folder — connector mode only, where the CLI requires it. */
|
|
1209
1211
|
folder?: string;
|
|
1210
1212
|
/**
|
|
1211
1213
|
* The connector the connection belongs to, connector mode only. Defaults to
|
|
1212
1214
|
* `uipath-uipath-http`, the generic HTTP connector. Set it when the connection is a
|
|
1213
1215
|
* specific connector's (a Slack connection calling a Slack endpoint the catalog does
|
|
1214
|
-
* not expose); the
|
|
1216
|
+
* not expose); it becomes the request's `targetConnector`.
|
|
1215
1217
|
*/
|
|
1216
1218
|
connectorKey?: string;
|
|
1217
1219
|
/**
|
|
@@ -1226,7 +1228,11 @@ export interface HttpOpts extends ActivityOpts {
|
|
|
1226
1228
|
* stays what the platform expects.
|
|
1227
1229
|
*/
|
|
1228
1230
|
outputs?: Record<string, string>;
|
|
1229
|
-
/**
|
|
1231
|
+
/**
|
|
1232
|
+
* Variable the response lands in. Defaults to `<id>_response`. In connector mode it is
|
|
1233
|
+
* the response body; the status code and headers land in `<id>_code` and `<id>_headers`,
|
|
1234
|
+
* so it cannot be either.
|
|
1235
|
+
*/
|
|
1230
1236
|
outputVar?: string;
|
|
1231
1237
|
/** `=`-expression that skips the request when truthy. */
|
|
1232
1238
|
skipCondition?: string;
|
|
@@ -2439,10 +2445,9 @@ declare abstract class ScopeBuilder {
|
|
|
2439
2445
|
http(id: string, opts: HttpOpts, body?: ActivityBodyFn): this;
|
|
2440
2446
|
/**
|
|
2441
2447
|
* @internal Connector-mode `.http()`: the request through an Integration Service
|
|
2442
|
-
* connection, as `Intsvc.
|
|
2443
|
-
*
|
|
2444
|
-
*
|
|
2445
|
-
* resolve exactly as `.dataService()`'s do.
|
|
2448
|
+
* connection, as the V2 `Intsvc.UnifiedHttpRequest` element `uip maestro bpmn registry
|
|
2449
|
+
* get Intsvc.UnifiedHttpRequest --connection-id` builds (see `managed-http.ts`). The
|
|
2450
|
+
* connection and folder resolve exactly as `.dataService()`'s do.
|
|
2446
2451
|
*/
|
|
2447
2452
|
private connectorHttp;
|
|
2448
2453
|
/**
|
package/dist/bpmn/bpmn-sdk.js
CHANGED
|
@@ -5,6 +5,7 @@ import { schemaVersionRefusal } from '../schema-version.js';
|
|
|
5
5
|
import { bindingRequiredFields, REGISTRY_GAPS, registryType } from './typed-node.js';
|
|
6
6
|
import { resolveResourceKeyPattern } from './resource-key-pattern.js';
|
|
7
7
|
import { DATA_SERVICE_ACTIVITY_TYPE, DATA_SERVICE_CONNECTOR_KEY, dataServiceWire } from './data-service.js';
|
|
8
|
+
import { MANAGED_HTTP_CONNECTION_NAME, MANAGED_HTTP_CONNECTOR_KEY, MANAGED_HTTP_FOLDER_NAME, MANAGED_HTTP_TYPE, managedHttpContext, managedHttpInputs, managedHttpOutputs, } from './managed-http.js';
|
|
8
9
|
import { ownEntry } from '../core/own-entry.js';
|
|
9
10
|
export { BpmnBuildError } from './bpmn-expr-check.js';
|
|
10
11
|
// @internal helpers kept on the published /bpmn subpath; SDK code imports declared-vars.js.
|
|
@@ -1032,79 +1033,46 @@ class ScopeBuilder {
|
|
|
1032
1033
|
}
|
|
1033
1034
|
/**
|
|
1034
1035
|
* @internal Connector-mode `.http()`: the request through an Integration Service
|
|
1035
|
-
* connection, as `Intsvc.
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1038
|
-
* resolve exactly as `.dataService()`'s do.
|
|
1036
|
+
* connection, as the V2 `Intsvc.UnifiedHttpRequest` element `uip maestro bpmn registry
|
|
1037
|
+
* get Intsvc.UnifiedHttpRequest --connection-id` builds (see `managed-http.ts`). The
|
|
1038
|
+
* connection and folder resolve exactly as `.dataService()`'s do.
|
|
1039
1039
|
*/
|
|
1040
1040
|
connectorHttp(id, opts, body) {
|
|
1041
|
-
const
|
|
1042
|
-
const
|
|
1041
|
+
const codeVar = `${id}_code`;
|
|
1042
|
+
const headersVar = `${id}_headers`;
|
|
1043
|
+
if (opts.outputVar === codeVar || opts.outputVar === headersVar) {
|
|
1044
|
+
throw new Error(`http "${id}": outputVar "${opts.outputVar}" is the variable connector mode writes the status code or headers to. ` +
|
|
1045
|
+
`Pick another name, or drop outputVar for the default "${id}_response".`);
|
|
1046
|
+
}
|
|
1047
|
+
const connection = this.dataServiceBinding(id, 'connection', opts.connection, 'ConnectionId', MANAGED_HTTP_CONNECTION_NAME);
|
|
1043
1048
|
const folder = opts.folder !== undefined
|
|
1044
|
-
? this.dataServiceBinding(id, 'folder', opts.folder, 'folderKey',
|
|
1049
|
+
? this.dataServiceBinding(id, 'folder', opts.folder, 'folderKey', MANAGED_HTTP_FOLDER_NAME, connection.key)
|
|
1045
1050
|
: undefined;
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
catch {
|
|
1057
|
-
throw new Error(`http "${id}": connector mode needs an absolute URL (got ${JSON.stringify(url)}).`);
|
|
1058
|
-
}
|
|
1059
|
-
for (const [k, v] of Object.entries(opts.parameters ?? {}))
|
|
1060
|
-
parsed.searchParams.set(k, String(v));
|
|
1061
|
-
url = parsed.toString();
|
|
1062
|
-
path = parsed.pathname;
|
|
1063
|
-
}
|
|
1064
|
-
else if (opts.parameters !== undefined) {
|
|
1065
|
-
throw new Error(`http "${id}": connector mode appends \`parameters\` to the URL, so the URL cannot be an expression when they are given — ` +
|
|
1066
|
-
`write them into the expression instead.`);
|
|
1067
|
-
}
|
|
1068
|
-
const responseVar = opts.outputVar ?? `${id}_response`;
|
|
1051
|
+
const request = {
|
|
1052
|
+
connection,
|
|
1053
|
+
folder,
|
|
1054
|
+
targetConnector: opts.connectorKey ?? MANAGED_HTTP_CONNECTOR_KEY,
|
|
1055
|
+
method: opts.method ?? 'GET',
|
|
1056
|
+
url: opts.url,
|
|
1057
|
+
headers: opts.headers,
|
|
1058
|
+
query: opts.parameters,
|
|
1059
|
+
body: opts.body,
|
|
1060
|
+
};
|
|
1069
1061
|
return this.pushActivity({
|
|
1070
1062
|
kind: 'typed',
|
|
1071
1063
|
id,
|
|
1072
1064
|
name: opts.name,
|
|
1073
|
-
type:
|
|
1074
|
-
context: {
|
|
1075
|
-
|
|
1076
|
-
connectorKey,
|
|
1077
|
-
connection: connection.ref,
|
|
1078
|
-
...(folder ? { folderKey: folder.ref } : {}),
|
|
1079
|
-
operation: 'Create',
|
|
1080
|
-
objectName: 'http-request',
|
|
1081
|
-
method: 'POST',
|
|
1082
|
-
path: '/http-request',
|
|
1083
|
-
activityConfigurationVersion: 'v1',
|
|
1084
|
-
metadata: {},
|
|
1085
|
-
},
|
|
1065
|
+
type: MANAGED_HTTP_TYPE,
|
|
1066
|
+
context: {},
|
|
1067
|
+
contextRows: managedHttpContext(request),
|
|
1086
1068
|
inputs: {},
|
|
1087
|
-
inputRows:
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
targetConnector: connectorKey,
|
|
1095
|
-
connection: connection.ref,
|
|
1096
|
-
method: opts.method ?? 'GET',
|
|
1097
|
-
url,
|
|
1098
|
-
...(path !== undefined ? { path } : {}),
|
|
1099
|
-
headers: opts.headers ?? {},
|
|
1100
|
-
body: opts.body ?? null,
|
|
1101
|
-
},
|
|
1102
|
-
},
|
|
1103
|
-
],
|
|
1104
|
-
outputRows: [
|
|
1105
|
-
{ name: 'response', type: 'jsonSchema', source: '=response', var: responseVar },
|
|
1106
|
-
{ name: 'Error', type: 'jsonSchema', source: '=Error', var: `${id}_Error`, schema: errorSchema },
|
|
1107
|
-
],
|
|
1069
|
+
inputRows: managedHttpInputs(request),
|
|
1070
|
+
outputRows: managedHttpOutputs({
|
|
1071
|
+
code: codeVar,
|
|
1072
|
+
headers: headersVar,
|
|
1073
|
+
body: opts.outputVar ?? `${id}_response`,
|
|
1074
|
+
error: `${id}_Error`,
|
|
1075
|
+
}),
|
|
1108
1076
|
outputs: opts.outputs,
|
|
1109
1077
|
skipCondition: opts.skipCondition,
|
|
1110
1078
|
tags: opts.tags,
|
package/dist/bpmn/check.js
CHANGED
|
@@ -5,6 +5,7 @@ import { EQUALS_EXPR_DIALECT, checkConnectorContract, checkConnectorLookups, che
|
|
|
5
5
|
import { checkEventResolution, checkEventSubscription, eventParamsFor, } from '../core/event-checks.js';
|
|
6
6
|
import { bindingRequiredFields, CASE_RUNTIME_INTERNAL_TYPES, missingRequiredContext, missingRequiredInputs, REGISTRY_GAPS, registryType, } from './typed-node.js';
|
|
7
7
|
import { ownEntry } from '../core/own-entry.js';
|
|
8
|
+
import { isManagedHttpV2, managedHttpAbsoluteUrl, managedHttpMissing } from './managed-http.js';
|
|
8
9
|
/**
|
|
9
10
|
* The job-start family — the types whose engine handler switches addressing on the
|
|
10
11
|
* `uipath:type` version: v2 reads `name`/`folderPath`, v1 reads `releaseKey`/`folderKey`.
|
|
@@ -1391,7 +1392,12 @@ inEventSubProcess = false) {
|
|
|
1391
1392
|
// emits, so whether this fired depended on a detail of the source document that
|
|
1392
1393
|
// has nothing to do with whether the field is set.
|
|
1393
1394
|
const contextNames = contextView;
|
|
1394
|
-
|
|
1395
|
+
const managedHttp = isManagedHttpV2(n.type, contextNames);
|
|
1396
|
+
const httpRequest = n.inputRows?.find((row) => row.name === 'body')?.body ?? n.inputs?.body;
|
|
1397
|
+
const requiredContext = managedHttp
|
|
1398
|
+
? managedHttpMissing(contextNames, httpRequest)
|
|
1399
|
+
: missingRequiredContext(n.type, contextNames, n.spec);
|
|
1400
|
+
for (const field of requiredContext) {
|
|
1395
1401
|
diags.push({
|
|
1396
1402
|
level: 'error',
|
|
1397
1403
|
code: 'EMPTY_REQUIRED_FIELD',
|
|
@@ -1399,6 +1405,17 @@ inEventSubProcess = false) {
|
|
|
1399
1405
|
where: n.id,
|
|
1400
1406
|
});
|
|
1401
1407
|
}
|
|
1408
|
+
const absoluteUrl = managedHttp ? managedHttpAbsoluteUrl(httpRequest) : undefined;
|
|
1409
|
+
if (absoluteUrl !== undefined) {
|
|
1410
|
+
diags.push({
|
|
1411
|
+
level: 'warning',
|
|
1412
|
+
code: 'MANAGED_HTTP_ABSOLUTE_URL',
|
|
1413
|
+
message: `"${n.id}" (${n.type}) sends the absolute URL "${absoluteUrl.url}" through a ${absoluteUrl.targetConnector} connection. ` +
|
|
1414
|
+
`Integration Service refuses any host but that connector's with 400 "Invalid request URL". ` +
|
|
1415
|
+
`Write url relative to the connection's base URL, e.g. "/emoji.list" for Slack's https://slack.com/api/emoji.list.`,
|
|
1416
|
+
where: n.id,
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1402
1419
|
// The same rule over the PAYLOAD fields — the platform's RequiredFieldsRule
|
|
1403
1420
|
// draws on both, so an unset required input is the same EMPTY_REQUIRED_FIELD.
|
|
1404
1421
|
// The payload reaches a node the same two ways — `inputs`, or the verbatim
|
package/dist/bpmn/compile-cli.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* Runs the fast static check first; if it passes, serializes to Maestro `.bpmn`
|
|
15
15
|
* XML (semantic-only — no diagram). The authoritative deploy gate is
|
|
16
|
-
* `uip maestro bpmn validate`;
|
|
16
|
+
* `uip maestro bpmn validate`; `uip maestro bpmn format` lays the diagram out.
|
|
17
17
|
*/
|
|
18
18
|
import { reportDiagnostics, reportResult, thrownDiagnostic } from '../cli-result.js';
|
|
19
19
|
import { writeFileSync } from 'node:fs';
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
* repo-relative for in-tree callers, mirroring the Flow and Case arms.
|
|
23
23
|
*
|
|
24
24
|
* Diagram layout is not read or emitted — the SDK emits semantic-only XML and
|
|
25
|
-
* `
|
|
26
|
-
* needs one.
|
|
25
|
+
* `uip maestro bpmn format` regenerates `bpmndi`. Run it on the recompiled artifact
|
|
26
|
+
* when a canvas needs one.
|
|
27
27
|
*
|
|
28
28
|
* `--style nested` lifts the regions the builder's nesting constructs lower to —
|
|
29
29
|
* see `BpmnDecompileOptions.style`. It is written only after both sources have been
|
package/dist/bpmn/decompile.js
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* What does NOT survive, and why:
|
|
18
18
|
*
|
|
19
|
-
* - **`bpmndi` diagram layout.** The SDK emits none and `
|
|
20
|
-
* there is nothing to preserve. A decompiled file recompiles
|
|
21
|
-
* XML; re-run `
|
|
19
|
+
* - **`bpmndi` diagram layout.** The SDK emits none and `uip maestro bpmn format`
|
|
20
|
+
* regenerates it, so there is nothing to preserve. A decompiled file recompiles
|
|
21
|
+
* to semantic-only XML; re-run `format` for a canvas.
|
|
22
22
|
* - **Comments, method order, and formatting.** Regenerated, not preserved.
|
|
23
23
|
*
|
|
24
24
|
* Everything else round-trips: events and their definitions, all four gateways,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Method names the platform expects to be CALLED, not merely named.
|
|
3
3
|
*
|
|
4
4
|
* Generated — do not edit by hand. Run `node scripts/gen-bpmn-known-methods.mjs`
|
|
5
|
-
* to refresh from the installed `@uipath/maestro-
|
|
5
|
+
* to refresh from the installed `@uipath/maestro-validation`.
|
|
6
6
|
*
|
|
7
7
|
* The canvas validator's `METHOD_MISSING_PARENTHESES` rule reads this list: an
|
|
8
8
|
* expression containing `.<name>` not followed by `(` is an ERROR when `<name>` is
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Method names the platform expects to be CALLED, not merely named.
|
|
3
3
|
*
|
|
4
4
|
* Generated — do not edit by hand. Run `node scripts/gen-bpmn-known-methods.mjs`
|
|
5
|
-
* to refresh from the installed `@uipath/maestro-
|
|
5
|
+
* to refresh from the installed `@uipath/maestro-validation`.
|
|
6
6
|
*
|
|
7
7
|
* The canvas validator's `METHOD_MISSING_PARENTHESES` rule reads this list: an
|
|
8
8
|
* expression containing `.<name>` not followed by `(` is an ERROR when `<name>` is
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bpmn/managed-http — the wire shape behind connector-mode `.http()`: a V2
|
|
3
|
+
* `Intsvc.UnifiedHttpRequest` through an Integration Service connection, as
|
|
4
|
+
* `uip maestro bpmn registry get Intsvc.UnifiedHttpRequest --connection-id <id>` builds it
|
|
5
|
+
* (UiPath/cli `buildManagedHttpSpec` rendered by `renderBpmnV2Element`).
|
|
6
|
+
*/
|
|
7
|
+
import { MANAGED_HTTP_CONNECTOR_KEY } from '../core/managed-http.js';
|
|
8
|
+
import type { TypedContextRow, TypedInputRow, TypedOutputRow } from './typed-node.js';
|
|
9
|
+
export { MANAGED_HTTP_CONNECTOR_KEY };
|
|
10
|
+
export declare const MANAGED_HTTP_TYPE = "Intsvc.UnifiedHttpRequest";
|
|
11
|
+
/** The connection binding's name, after the node's `connectorKey`, as the CLI names it. */
|
|
12
|
+
export declare const MANAGED_HTTP_CONNECTION_NAME = "uipath-uipath-http connection";
|
|
13
|
+
export declare const MANAGED_HTTP_FOLDER_NAME = "FolderKey";
|
|
14
|
+
/**
|
|
15
|
+
* True for a V2 HTTP request. `registry-types.json` holds the V1 manual node, whose
|
|
16
|
+
* required `url` and `mode` a V2 one does not carry.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isManagedHttpV2(type: string, context: Record<string, unknown>): boolean;
|
|
19
|
+
/** The required fields a V2 HTTP request leaves unset, a request field as `body.<key>`; `body` is its request row. */
|
|
20
|
+
export declare function managedHttpMissing(context: Record<string, unknown>, body: unknown): string[];
|
|
21
|
+
/**
|
|
22
|
+
* A connector request's absolute `url`, when the connector it goes through is not the generic
|
|
23
|
+
* HTTP one. Integration Service refuses a host other than the connector's with 400 "Invalid request URL".
|
|
24
|
+
*/
|
|
25
|
+
export declare function managedHttpAbsoluteUrl(body: unknown): {
|
|
26
|
+
url: string;
|
|
27
|
+
targetConnector: string;
|
|
28
|
+
} | undefined;
|
|
29
|
+
export interface ManagedHttpRequest {
|
|
30
|
+
/** `ref` is the `=bindings.<id>` reference; `key` the connection id it resolves to. */
|
|
31
|
+
connection: {
|
|
32
|
+
ref: string;
|
|
33
|
+
key: string;
|
|
34
|
+
};
|
|
35
|
+
folder?: {
|
|
36
|
+
ref: string;
|
|
37
|
+
};
|
|
38
|
+
/** The connector the connection belongs to. */
|
|
39
|
+
targetConnector: string;
|
|
40
|
+
method: string;
|
|
41
|
+
/** The endpoint on the target connector, e.g. `/emoji.list`. */
|
|
42
|
+
url: string;
|
|
43
|
+
headers?: Record<string, unknown>;
|
|
44
|
+
query?: Record<string, unknown>;
|
|
45
|
+
body?: unknown;
|
|
46
|
+
}
|
|
47
|
+
export interface ManagedHttpVars {
|
|
48
|
+
code: string;
|
|
49
|
+
headers: string;
|
|
50
|
+
body: string;
|
|
51
|
+
error: string;
|
|
52
|
+
}
|
|
53
|
+
export declare function managedHttpContext(req: ManagedHttpRequest): TypedContextRow[];
|
|
54
|
+
export declare function managedHttpInputs(req: ManagedHttpRequest): TypedInputRow[];
|
|
55
|
+
/** Studio Web's curated HTTP outputs, then `Error`. */
|
|
56
|
+
export declare function managedHttpOutputs(vars: ManagedHttpVars): TypedOutputRow[];
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bpmn/managed-http — the wire shape behind connector-mode `.http()`: a V2
|
|
3
|
+
* `Intsvc.UnifiedHttpRequest` through an Integration Service connection, as
|
|
4
|
+
* `uip maestro bpmn registry get Intsvc.UnifiedHttpRequest --connection-id <id>` builds it
|
|
5
|
+
* (UiPath/cli `buildManagedHttpSpec` rendered by `renderBpmnV2Element`).
|
|
6
|
+
*/
|
|
7
|
+
import { MANAGED_HTTP_ACTIVITY_TYPE_ID, MANAGED_HTTP_CONNECTOR_KEY, MANAGED_HTTP_ENDPOINT, MANAGED_HTTP_ENDPOINT_METHOD, MANAGED_HTTP_ESSENTIAL_CONFIGURATION, MANAGED_HTTP_INSTANCE_PARAMETERS, MANAGED_HTTP_OBJECT_NAME, MANAGED_HTTP_TELEMETRY, } from '../core/managed-http.js';
|
|
8
|
+
import { isRecord } from '../core/node-envelope.js';
|
|
9
|
+
export { MANAGED_HTTP_CONNECTOR_KEY };
|
|
10
|
+
export const MANAGED_HTTP_TYPE = 'Intsvc.UnifiedHttpRequest';
|
|
11
|
+
/** The connection binding's name, after the node's `connectorKey`, as the CLI names it. */
|
|
12
|
+
export const MANAGED_HTTP_CONNECTION_NAME = `${MANAGED_HTTP_CONNECTOR_KEY} connection`;
|
|
13
|
+
export const MANAGED_HTTP_FOLDER_NAME = 'FolderKey';
|
|
14
|
+
const CONNECTOR_VERSION = '1.4.50';
|
|
15
|
+
const CONFIGURATION_VERSION = 'v2';
|
|
16
|
+
const CONNECTOR_AUTHENTICATION = 'connector';
|
|
17
|
+
/** Studio Web's guard on a JSON string it stores in node metadata. */
|
|
18
|
+
const JSON_STRING_PREFIX = '=jsonString:';
|
|
19
|
+
/** The CLI's `EXPRESSION_SHAPED`: a value Studio Web's V2 component reads as an expression only as `=js:`. */
|
|
20
|
+
const EXPRESSION_SHAPED = /^=(vars|metadata|response|Error)\b/;
|
|
21
|
+
/**
|
|
22
|
+
* The V2 contract's required context (UiPath/cli `manifest/bpmn-spec.json`), and the fields
|
|
23
|
+
* the CLI requires of a connector request (`managedHttpDetailErrors`).
|
|
24
|
+
*/
|
|
25
|
+
const REQUIRED_CONTEXT = ['connectorKey'];
|
|
26
|
+
const CONNECTOR_REQUIRED_CONTEXT = ['folderKey'];
|
|
27
|
+
const CONNECTOR_REQUIRED_BODY = ['targetConnector', 'connection'];
|
|
28
|
+
const ABSOLUTE_URL = /^[a-z][a-z\d+.-]*:\/\//i;
|
|
29
|
+
const ESSENTIAL_CONFIGURATION = {
|
|
30
|
+
essentialConfiguration: {
|
|
31
|
+
connectorVersion: CONNECTOR_VERSION,
|
|
32
|
+
executionType: null,
|
|
33
|
+
customFieldsRequestDetails: null,
|
|
34
|
+
...MANAGED_HTTP_ESSENTIAL_CONFIGURATION,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
/** The tenant-independent fields of Studio's TypeCache entry, which the CLI fetches live. */
|
|
38
|
+
const CATALOG_ENTRY = {
|
|
39
|
+
displayName: 'HTTP Request',
|
|
40
|
+
description: 'Use HTTP requests to interact with APIs via the selected connector and connection configuration.',
|
|
41
|
+
category: '',
|
|
42
|
+
configuration: JSON.stringify({ ...MANAGED_HTTP_INSTANCE_PARAMETERS, supportsStreaming: false, subType: 'method' }),
|
|
43
|
+
uiPathActivityTypeId: MANAGED_HTTP_ACTIVITY_TYPE_ID,
|
|
44
|
+
isEnabled: true,
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* True for a V2 HTTP request. `registry-types.json` holds the V1 manual node, whose
|
|
48
|
+
* required `url` and `mode` a V2 one does not carry.
|
|
49
|
+
*/
|
|
50
|
+
export function isManagedHttpV2(type, context) {
|
|
51
|
+
return type === MANAGED_HTTP_TYPE && context.activityConfigurationVersion === CONFIGURATION_VERSION;
|
|
52
|
+
}
|
|
53
|
+
/** The required fields a V2 HTTP request leaves unset, a request field as `body.<key>`; `body` is its request row. */
|
|
54
|
+
export function managedHttpMissing(context, body) {
|
|
55
|
+
const unset = (v) => v === undefined || v === null || (typeof v === 'string' && v.trim() === '');
|
|
56
|
+
const missingContext = REQUIRED_CONTEXT.filter((name) => unset(context[name]));
|
|
57
|
+
const request = connectorRequest(body);
|
|
58
|
+
if (request === undefined)
|
|
59
|
+
return missingContext;
|
|
60
|
+
return [
|
|
61
|
+
...missingContext,
|
|
62
|
+
...CONNECTOR_REQUIRED_CONTEXT.filter((name) => unset(context[name])),
|
|
63
|
+
...CONNECTOR_REQUIRED_BODY.filter((name) => typeof request[name] !== 'string' || unset(request[name])).map((name) => `body.${name}`),
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A connector request's absolute `url`, when the connector it goes through is not the generic
|
|
68
|
+
* HTTP one. Integration Service refuses a host other than the connector's with 400 "Invalid request URL".
|
|
69
|
+
*/
|
|
70
|
+
export function managedHttpAbsoluteUrl(body) {
|
|
71
|
+
const request = connectorRequest(body);
|
|
72
|
+
if (request === undefined)
|
|
73
|
+
return undefined;
|
|
74
|
+
const { url, targetConnector } = request;
|
|
75
|
+
if (typeof url !== 'string' || typeof targetConnector !== 'string')
|
|
76
|
+
return undefined;
|
|
77
|
+
if (targetConnector === MANAGED_HTTP_CONNECTOR_KEY || !ABSOLUTE_URL.test(url))
|
|
78
|
+
return undefined;
|
|
79
|
+
return { url, targetConnector };
|
|
80
|
+
}
|
|
81
|
+
function connectorRequest(body) {
|
|
82
|
+
const request = typeof body === 'string' ? parseObject(body) : body;
|
|
83
|
+
return isRecord(request) && request.authentication === CONNECTOR_AUTHENTICATION ? request : undefined;
|
|
84
|
+
}
|
|
85
|
+
function parseObject(text) {
|
|
86
|
+
try {
|
|
87
|
+
return JSON.parse(text);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** UiPath/cli `asDesignTimeExpressions`: `=vars.x` → `=js:vars.x`, at any depth; other text stays literal. */
|
|
94
|
+
function designTimeExpressions(value) {
|
|
95
|
+
if (typeof value === 'string')
|
|
96
|
+
return EXPRESSION_SHAPED.test(value) ? `=js:${value.slice(1)}` : value;
|
|
97
|
+
if (Array.isArray(value))
|
|
98
|
+
return value.map(designTimeExpressions);
|
|
99
|
+
if (isRecord(value))
|
|
100
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, designTimeExpressions(v)]));
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
export function managedHttpContext(req) {
|
|
104
|
+
return [
|
|
105
|
+
{ name: 'connectorKey', value: MANAGED_HTTP_CONNECTOR_KEY },
|
|
106
|
+
{ name: 'connection', value: req.connection.ref },
|
|
107
|
+
{ name: 'resourceKey', value: req.connection.key },
|
|
108
|
+
...(req.folder ? [{ name: 'folderKey', value: req.folder.ref }] : []),
|
|
109
|
+
{ name: 'method', value: MANAGED_HTTP_ENDPOINT_METHOD },
|
|
110
|
+
{ name: 'path', value: MANAGED_HTTP_ENDPOINT },
|
|
111
|
+
{ name: 'objectName', value: MANAGED_HTTP_OBJECT_NAME },
|
|
112
|
+
{
|
|
113
|
+
name: 'metadata',
|
|
114
|
+
type: 'json',
|
|
115
|
+
body: {
|
|
116
|
+
activityPropertyConfiguration: {
|
|
117
|
+
configuration: `${JSON_STRING_PREFIX}${JSON.stringify(ESSENTIAL_CONFIGURATION)}`,
|
|
118
|
+
uiPathActivityTypeId: MANAGED_HTTP_ACTIVITY_TYPE_ID,
|
|
119
|
+
errorState: { issues: [] },
|
|
120
|
+
},
|
|
121
|
+
activityMetadata: { activity: CATALOG_ENTRY },
|
|
122
|
+
inputMetadata: {},
|
|
123
|
+
telemetryData: MANAGED_HTTP_TELEMETRY,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{ name: 'activityConfigurationVersion', value: CONFIGURATION_VERSION },
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
export function managedHttpInputs(req) {
|
|
130
|
+
const url = designTimeExpressions(req.url);
|
|
131
|
+
const body = {
|
|
132
|
+
authentication: CONNECTOR_AUTHENTICATION,
|
|
133
|
+
method: req.method,
|
|
134
|
+
targetConnector: req.targetConnector,
|
|
135
|
+
connection: req.connection.key,
|
|
136
|
+
path: url,
|
|
137
|
+
url,
|
|
138
|
+
};
|
|
139
|
+
if (req.headers !== undefined)
|
|
140
|
+
body.headers = designTimeExpressions(req.headers);
|
|
141
|
+
if (req.query !== undefined)
|
|
142
|
+
body.query = designTimeExpressions(req.query);
|
|
143
|
+
if (req.body !== undefined)
|
|
144
|
+
body.body = designTimeExpressions(req.body);
|
|
145
|
+
return [
|
|
146
|
+
{ name: 'pathParameters', type: 'json', target: 'pathParameters', body: {} },
|
|
147
|
+
{ name: 'queryParameters', type: 'json', target: 'queryParameters', body: {} },
|
|
148
|
+
{ name: 'body', type: 'json', target: 'body', body },
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
/** Studio Web's curated HTTP outputs, then `Error`. */
|
|
152
|
+
export function managedHttpOutputs(vars) {
|
|
153
|
+
return [
|
|
154
|
+
{ name: 'code', type: 'number', source: '=response.code', var: vars.code },
|
|
155
|
+
{ name: 'headers', type: 'object', source: '=response.headers', var: vars.headers },
|
|
156
|
+
{ name: 'body', type: 'object', source: '=response.body', var: vars.body },
|
|
157
|
+
{ name: 'Error', type: 'jsonSchema', source: '=Error', var: vars.error },
|
|
158
|
+
];
|
|
159
|
+
}
|
package/dist/bpmn/merge.js
CHANGED
|
@@ -274,7 +274,7 @@ export function mergeBpmn(originalXml, editedXml, options = {}) {
|
|
|
274
274
|
originalXml.slice(originalProcess.innerEnd);
|
|
275
275
|
// The diagram: the original's layout survives, which is strictly better than the
|
|
276
276
|
// re-layout a bare recompile forces. Shapes and edges for deleted elements go with
|
|
277
|
-
// them; anything newly added has no DI yet, which is what `format
|
|
277
|
+
// them; anything newly added has no DI yet, which is what `format` is for.
|
|
278
278
|
if (removed.length > 0) {
|
|
279
279
|
const plane = findByLocal(parseXmlRanges(merged), 'BPMNPlane');
|
|
280
280
|
if (plane) {
|
package/dist/bpmn/serialize.d.ts
CHANGED
|
@@ -12,8 +12,7 @@ export declare function serialize(built: BuiltBpmn, opts?: BpmnSerializeOpts): P
|
|
|
12
12
|
* an attribute whose value equals the BPMN default, but Studio Web (and the
|
|
13
13
|
* canvas graders) expect an interrupting boundary event to carry an explicit
|
|
14
14
|
* `cancelActivity="true"`. Add it wherever a boundary event lacks the attribute
|
|
15
|
-
* (its absence already means interrupting). Idempotent
|
|
16
|
-
* which re-serializes through moddle and drops the attribute again.
|
|
15
|
+
* (its absence already means interrupting). Idempotent.
|
|
17
16
|
*
|
|
18
17
|
* **This one is a KNOWN divergence from what the product writes, kept on purpose.**
|
|
19
18
|
* None of the 71 boundary events across the five real Studio Web exports in
|
package/dist/bpmn/serialize.js
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* descriptor.
|
|
11
11
|
*
|
|
12
12
|
* **Semantic-only, no diagram.** BPMN validation is layout-independent, so no
|
|
13
|
-
* `bpmndi:BPMNDiagram` is emitted here;
|
|
14
|
-
*
|
|
13
|
+
* `bpmndi:BPMNDiagram` is emitted here; `uip maestro bpmn format` adds geometry
|
|
14
|
+
* when a visual diagram is needed.
|
|
15
15
|
*/
|
|
16
16
|
import BpmnModdle from 'bpmn-moddle';
|
|
17
17
|
import { createRequire } from 'node:module';
|
|
@@ -170,8 +170,7 @@ export async function serialize(built, opts = {}) {
|
|
|
170
170
|
* an attribute whose value equals the BPMN default, but Studio Web (and the
|
|
171
171
|
* canvas graders) expect an interrupting boundary event to carry an explicit
|
|
172
172
|
* `cancelActivity="true"`. Add it wherever a boundary event lacks the attribute
|
|
173
|
-
* (its absence already means interrupting). Idempotent
|
|
174
|
-
* which re-serializes through moddle and drops the attribute again.
|
|
173
|
+
* (its absence already means interrupting). Idempotent.
|
|
175
174
|
*
|
|
176
175
|
* **This one is a KNOWN divergence from what the product writes, kept on purpose.**
|
|
177
176
|
* None of the 71 boundary events across the five real Studio Web exports in
|
|
@@ -53,15 +53,6 @@ export function registerBpmnCommands(program) {
|
|
|
53
53
|
addValue(argv, '--bindings', options.bindings);
|
|
54
54
|
await invoke('bpmn check', () => import('../../bpmn/check-cli.js'), argv);
|
|
55
55
|
});
|
|
56
|
-
family.command('tidy')
|
|
57
|
-
.description('Add diagram layout to a compiled .bpmn artifact.')
|
|
58
|
-
.argument('<input>', 'input .bpmn path')
|
|
59
|
-
.option('-o, --output <file>', 'output .bpmn path')
|
|
60
|
-
.action(async (input, options) => {
|
|
61
|
-
const argv = [input];
|
|
62
|
-
addValue(argv, '-o', options.output);
|
|
63
|
-
await invoke('bpmn tidy', () => import('../../bpmn/tidy-cli.js'), argv);
|
|
64
|
-
});
|
|
65
56
|
family
|
|
66
57
|
.command('decompile')
|
|
67
58
|
.description('Convert a .bpmn artifact to authored TypeScript.')
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The managed HTTP request's fixed identity — Integration Service's generic HTTP
|
|
3
|
+
* connector, `POST /http-request` — shared by Flow's `core.action.http.v2` and BPMN's
|
|
4
|
+
* V2 `Intsvc.UnifiedHttpRequest`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MANAGED_HTTP_CONNECTOR_KEY = "uipath-uipath-http";
|
|
7
|
+
export declare const MANAGED_HTTP_OBJECT_NAME = "http-request";
|
|
8
|
+
export declare const MANAGED_HTTP_ENDPOINT = "/http-request";
|
|
9
|
+
export declare const MANAGED_HTTP_ENDPOINT_METHOD = "POST";
|
|
10
|
+
/** Studio's HTTP Request activity type, the same on every tenant. */
|
|
11
|
+
export declare const MANAGED_HTTP_ACTIVITY_TYPE_ID = "5c4cc855-b42a-37e6-b910-de8588998fce";
|
|
12
|
+
export declare const MANAGED_HTTP_INSTANCE_PARAMETERS: {
|
|
13
|
+
connectorKey: string;
|
|
14
|
+
objectName: string;
|
|
15
|
+
httpMethod: string;
|
|
16
|
+
activityType: string;
|
|
17
|
+
version: string;
|
|
18
|
+
};
|
|
19
|
+
/** The `essentialConfiguration` fields both hosts write, in the order they write them. */
|
|
20
|
+
export declare const MANAGED_HTTP_ESSENTIAL_CONFIGURATION: {
|
|
21
|
+
instanceParameters: {
|
|
22
|
+
connectorKey: string;
|
|
23
|
+
objectName: string;
|
|
24
|
+
httpMethod: string;
|
|
25
|
+
activityType: string;
|
|
26
|
+
version: string;
|
|
27
|
+
};
|
|
28
|
+
objectName: string;
|
|
29
|
+
operation: string;
|
|
30
|
+
packageVersion: string;
|
|
31
|
+
httpMethod: string;
|
|
32
|
+
path: string;
|
|
33
|
+
unifiedTypesCompatible: boolean;
|
|
34
|
+
savedJitInputFieldId: string;
|
|
35
|
+
};
|
|
36
|
+
export declare const MANAGED_HTTP_TELEMETRY: {
|
|
37
|
+
connectorKey: string;
|
|
38
|
+
connectorName: string;
|
|
39
|
+
operationType: string;
|
|
40
|
+
objectName: string;
|
|
41
|
+
objectDisplayName: string;
|
|
42
|
+
primaryKeyName: string;
|
|
43
|
+
};
|