@uipath/packager-tool-bpmn 1.201.0 → 1.202.0-preview.136
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/bpmn-tool.d.ts +2 -0
- package/dist/index.js +287 -72
- package/package.json +4 -4
- package/src/bpmn-tool.ts +43 -19
package/dist/bpmn-tool.d.ts
CHANGED
|
@@ -6,9 +6,11 @@ import { type IFileSystem, type IToolLogger, ProjectTool, ToolResult } from "@ui
|
|
|
6
6
|
export declare class BpmnTool extends ProjectTool {
|
|
7
7
|
private readonly _temporaryStorage;
|
|
8
8
|
private readonly _validateService;
|
|
9
|
+
private readonly _packValidateService;
|
|
9
10
|
constructor(fileSystem: IFileSystem, logger: IToolLogger);
|
|
10
11
|
restoreAsync(_options: IProjectRestoreOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
11
12
|
validateAsync(options: IProjectValidateOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
13
|
+
private runValidation;
|
|
12
14
|
buildAsync(options: IProjectBuildOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
13
15
|
packAsync(options: IProjectPackOptions, cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
14
16
|
dispose(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -17,19 +17,19 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
17
17
|
// ../../maestro-sdk/dist/bpmn-packaging/index.js
|
|
18
18
|
var exports_bpmn_packaging = {};
|
|
19
19
|
__export(exports_bpmn_packaging, {
|
|
20
|
-
|
|
21
|
-
parseOptionalJson: () => parseOptionalJson,
|
|
22
|
-
parseJson: () => parseJson,
|
|
23
|
-
parseBpmnProcesses: () => parseBpmnProcesses,
|
|
24
|
-
isJsonObject: () => isJsonObject,
|
|
25
|
-
formatBpmnPackageFile: () => formatBpmnPackageFile,
|
|
26
|
-
extensionValues: () => extensionValues,
|
|
27
|
-
entryPointDisplayName: () => entryPointDisplayName,
|
|
28
|
-
deriveBpmnEntryPoints: () => deriveBpmnEntryPoints,
|
|
29
|
-
childNodes: () => childNodes,
|
|
30
|
-
buildConnectionResources: () => buildConnectionResources,
|
|
20
|
+
BPMN_PACKAGE_FILES: () => BPMN_PACKAGE_FILES,
|
|
31
21
|
buildBpmnPackageMetadata: () => buildBpmnPackageMetadata,
|
|
32
|
-
|
|
22
|
+
buildConnectionResources: () => buildConnectionResources,
|
|
23
|
+
childNodes: () => childNodes,
|
|
24
|
+
deriveBpmnEntryPoints: () => deriveBpmnEntryPoints,
|
|
25
|
+
entryPointDisplayName: () => entryPointDisplayName,
|
|
26
|
+
extensionValues: () => extensionValues,
|
|
27
|
+
formatBpmnPackageFile: () => formatBpmnPackageFile,
|
|
28
|
+
isJsonObject: () => isJsonObject,
|
|
29
|
+
parseBpmnProcesses: () => parseBpmnProcesses,
|
|
30
|
+
parseJson: () => parseJson,
|
|
31
|
+
parseOptionalJson: () => parseOptionalJson,
|
|
32
|
+
required: () => required
|
|
33
33
|
});
|
|
34
34
|
function isGuid2(value) {
|
|
35
35
|
return GUID_REGEX2.test(value);
|
|
@@ -57,26 +57,34 @@ function buildConnectionResources(processes, existingResources) {
|
|
|
57
57
|
const connectionBindings = childNodes(extensionValues(process).find((node) => node.$type === "uipath:bindings")).filter((node) => node.$type === "uipath:binding" && node.resource === "Connection" && node.propertyAttribute === "ConnectionId").map(toConnectionBinding);
|
|
58
58
|
const bindingById = new Map(connectionBindings.map((binding) => [binding.id, binding]));
|
|
59
59
|
for (const element of allFlowElements(process)) {
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
60
|
+
const payload = extensionValues(element).find((node) => node.$type === "uipath:activity" || node.$type === "uipath:event");
|
|
61
|
+
const extensionType = childNodes(payload).find((node) => node.$type === "uipath:type")?.value;
|
|
62
|
+
if (extensionType === undefined || !CONNECTION_CONNECTOR_TYPES.has(extensionType)) {
|
|
63
63
|
continue;
|
|
64
64
|
}
|
|
65
|
-
const context = childNodes(
|
|
66
|
-
const values = new Map(childNodes(context).filter((node) => node.$type === "uipath:input" && node.name).map((node) => [
|
|
65
|
+
const context = childNodes(payload).find((node) => node.$type === "uipath:context");
|
|
66
|
+
const values = new Map([...childNodes(context), ...childNodes(payload)].filter((node) => node.$type === "uipath:input" && node.name).map((node) => [
|
|
67
67
|
node.name,
|
|
68
68
|
node.value ?? node.$body
|
|
69
69
|
]));
|
|
70
|
-
if (!isIntsvcActivityExecutionV12(values.get("activityConfigurationVersion"), workflowActivityConfigurationVersion)) {
|
|
70
|
+
if (extensionType === "Intsvc.ActivityExecution" && !isIntsvcActivityExecutionV12(values.get("activityConfigurationVersion"), workflowActivityConfigurationVersion)) {
|
|
71
71
|
continue;
|
|
72
72
|
}
|
|
73
|
-
const
|
|
73
|
+
const connectionRef = [
|
|
74
|
+
values.get("connection"),
|
|
75
|
+
values.get("connectionId")
|
|
76
|
+
].find((value) => value?.trim());
|
|
77
|
+
if (connectionRef === undefined && extensionType !== "Intsvc.ActivityExecution") {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const nodeLabel = extensionType === "Intsvc.EventTrigger" ? "Trigger" : extensionType === "Intsvc.WaitForEvent" ? "Wait" : "Activity";
|
|
81
|
+
const activityId = required(element.id, `Integration Service ${nodeLabel.toLowerCase()} id`);
|
|
74
82
|
const activityDisplayName = element.name?.trim() || activityId;
|
|
75
|
-
const connector = required(values.get("connectorKey"),
|
|
76
|
-
const bindingId = bindingReference(
|
|
83
|
+
const connector = required(values.get("connectorKey"), `${nodeLabel} "${activityDisplayName}" connectorKey`);
|
|
84
|
+
const bindingId = bindingReference(connectionRef, activityDisplayName, nodeLabel);
|
|
77
85
|
const binding = bindingById.get(bindingId);
|
|
78
86
|
if (!binding) {
|
|
79
|
-
throw new Error(
|
|
87
|
+
throw new Error(`${nodeLabel} "${activityDisplayName}" references missing Connection binding "${bindingId}".`);
|
|
80
88
|
}
|
|
81
89
|
const current = connectionResource({
|
|
82
90
|
activityId,
|
|
@@ -87,7 +95,7 @@ function buildConnectionResources(processes, existingResources) {
|
|
|
87
95
|
const prior = generated.get(binding.resourceKey);
|
|
88
96
|
if (prior) {
|
|
89
97
|
if (prior.metadata.Connector !== connector || prior.value.ConnectionId.defaultValue !== binding.connectionId) {
|
|
90
|
-
throw new Error(`Connection resource "${binding.resourceKey}" is used by Integration Service
|
|
98
|
+
throw new Error(`Connection resource "${binding.resourceKey}" is used by Integration Service nodes with different connectors or connections.`);
|
|
91
99
|
}
|
|
92
100
|
continue;
|
|
93
101
|
}
|
|
@@ -146,10 +154,10 @@ function allFlowElements(element) {
|
|
|
146
154
|
}
|
|
147
155
|
return result;
|
|
148
156
|
}
|
|
149
|
-
function bindingReference(value,
|
|
157
|
+
function bindingReference(value, nodeName, nodeLabel) {
|
|
150
158
|
const match = /^=bindings\.([A-Za-z_][\w.-]*)$/.exec(value ?? "");
|
|
151
159
|
if (!match) {
|
|
152
|
-
throw new Error(
|
|
160
|
+
throw new Error(`${nodeLabel} "${nodeName}" connection must reference a root binding as "=bindings.<id>".`);
|
|
153
161
|
}
|
|
154
162
|
return match[1];
|
|
155
163
|
}
|
|
@@ -1451,7 +1459,7 @@ function parseJson(raw, label) {
|
|
|
1451
1459
|
}
|
|
1452
1460
|
return value;
|
|
1453
1461
|
}
|
|
1454
|
-
var GUID_REGEX2, bpmn_spec_default2, BPMN_SPEC2, STATIC_UIPATH_EXTENSION_TAG_NAMES2, SUPPORTED_UIPATH_EXTENSION_TAG_NAMES2, SUPPORTED_UIPATH_EXTENSION_TAGS2, KNOWN_UIPATH_TAGS2, ACTIVITY_CONFIGURATION_V12 = "v1", nativeToString, nativeHasOwnProperty, BUILTINS, TYPE_CONVERTERS, fromCharCode, hasOwnProperty, ENTITY_PATTERN, ENTITY_MAPPING, NON_WHITESPACE_OUTSIDE_ROOT_NODE = "non-whitespace outside of root node", DEFAULT_NS_MAP, SERIALIZE_PROPERTY = "property", XML_PREAMBLE = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1462
|
+
var GUID_REGEX2, bpmn_spec_default2, BPMN_SPEC2, STATIC_UIPATH_EXTENSION_TAG_NAMES2, SUPPORTED_UIPATH_EXTENSION_TAG_NAMES2, SUPPORTED_UIPATH_EXTENSION_TAGS2, KNOWN_UIPATH_TAGS2, CALL_ACTIVITY_TYPES2, CALL_ACTIVITY_PAYLOAD_TAGS2, ACTIVITY_CONFIGURATION_V12 = "v1", FREE_TEXT_ELEMENTS2, CONNECTION_CONNECTOR_TYPES, nativeToString, nativeHasOwnProperty, BUILTINS, TYPE_CONVERTERS, fromCharCode, hasOwnProperty, ENTITY_PATTERN, ENTITY_MAPPING, NON_WHITESPACE_OUTSIDE_ROOT_NODE = "non-whitespace outside of root node", DEFAULT_NS_MAP, SERIALIZE_PROPERTY = "property", XML_PREAMBLE = `<?xml version="1.0" encoding="UTF-8"?>
|
|
1455
1463
|
`, ESCAPE_ATTR_CHARS, ESCAPE_CHARS, ESCAPE_ATTR_MAP, ESCAPE_MAP, name$5 = "BPMN20", uri$5 = "http://www.omg.org/spec/BPMN/20100524/MODEL", prefix$5 = "bpmn", associations$5, types$5, enumerations$3, xml$1, BpmnPackage, name$4 = "BPMNDI", uri$4 = "http://www.omg.org/spec/BPMN/20100524/DI", prefix$4 = "bpmndi", types$4, enumerations$2, associations$4, BpmnDiPackage, name$3 = "DC", uri$3 = "http://www.omg.org/spec/DD/20100524/DC", prefix$3 = "dc", types$3, associations$3, DcPackage, name$2 = "DI", uri$2 = "http://www.omg.org/spec/DD/20100524/DI", prefix$2 = "di", types$2, associations$2, xml, DiPackage, name$1 = "bpmn.io colors for BPMN", uri$1 = "http://bpmn.io/schema/bpmn/biocolor/1.0", prefix$1 = "bioc", types$1, enumerations$1, associations$1, BiocPackage, name = "BPMN in Color", uri = "http://www.omg.org/spec/BPMN/non-normative/color/1.0", prefix = "color", types, enumerations, associations, BpmnInColorPackage, packages, BPMN_PACKAGE_FILES, SCHEMA_ANNOTATIONS;
|
|
1456
1464
|
var init_bpmn_packaging = __esm(() => {
|
|
1457
1465
|
GUID_REGEX2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -2237,6 +2245,15 @@ var init_bpmn_packaging = __esm(() => {
|
|
|
2237
2245
|
<bpmn:extensionElements>
|
|
2238
2246
|
<uipath:event version="v1">
|
|
2239
2247
|
<uipath:type value="Intsvc.WaitForEvent" version="v1" />
|
|
2248
|
+
<uipath:context>
|
|
2249
|
+
<uipath:input name="connectorKey" type="string" value="{connectorKey}" />
|
|
2250
|
+
<uipath:input name="connectionId" type="string" value="=bindings.{connectionBindingId}" />
|
|
2251
|
+
<uipath:input name="folderId" type="string" value="{folderId}" />
|
|
2252
|
+
<uipath:input name="folderPath" type="string" value="{folderPath}" />
|
|
2253
|
+
<uipath:input name="folderKey" type="string" value="{folderKey}" />
|
|
2254
|
+
<uipath:input name="operation" type="string" value="{operation}" />
|
|
2255
|
+
<uipath:input name="objectName" type="string" value="{objectName}" />
|
|
2256
|
+
</uipath:context>
|
|
2240
2257
|
<uipath:output name="result" type="custom" source="." var="{varId}" />
|
|
2241
2258
|
</uipath:event>
|
|
2242
2259
|
</bpmn:extensionElements>
|
|
@@ -2257,7 +2274,12 @@ var init_bpmn_packaging = __esm(() => {
|
|
|
2257
2274
|
isPrimaryKey: false,
|
|
2258
2275
|
binding: true,
|
|
2259
2276
|
defaultValue: null,
|
|
2260
|
-
description: "Connection ID for the IS connector (bindable)"
|
|
2277
|
+
description: "Connection ID for the IS connector (bindable)",
|
|
2278
|
+
bindingInfo: {
|
|
2279
|
+
resource: "Connection",
|
|
2280
|
+
resourceKeyPattern: "${resourceKey}",
|
|
2281
|
+
propertyAttribute: "ConnectionId"
|
|
2282
|
+
}
|
|
2261
2283
|
},
|
|
2262
2284
|
{
|
|
2263
2285
|
name: "connectorKey",
|
|
@@ -2375,6 +2397,15 @@ var init_bpmn_packaging = __esm(() => {
|
|
|
2375
2397
|
<bpmn:extensionElements>
|
|
2376
2398
|
<uipath:event version="v1">
|
|
2377
2399
|
<uipath:type value="Intsvc.EventTrigger" version="v1" />
|
|
2400
|
+
<uipath:context>
|
|
2401
|
+
<uipath:input name="connectorKey" type="string" value="{connectorKey}" />
|
|
2402
|
+
<uipath:input name="connectionId" type="string" value="=bindings.{connectionBindingId}" />
|
|
2403
|
+
<uipath:input name="folderId" type="string" value="{folderId}" />
|
|
2404
|
+
<uipath:input name="folderPath" type="string" value="{folderPath}" />
|
|
2405
|
+
<uipath:input name="folderKey" type="string" value="{folderKey}" />
|
|
2406
|
+
<uipath:input name="operation" type="string" value="{operation}" />
|
|
2407
|
+
<uipath:input name="objectName" type="string" value="{objectName}" />
|
|
2408
|
+
</uipath:context>
|
|
2378
2409
|
<uipath:output name="result" type="custom" source="." var="{varId}" />
|
|
2379
2410
|
</uipath:event>
|
|
2380
2411
|
</bpmn:extensionElements>
|
|
@@ -2396,7 +2427,12 @@ var init_bpmn_packaging = __esm(() => {
|
|
|
2396
2427
|
isPrimaryKey: false,
|
|
2397
2428
|
binding: true,
|
|
2398
2429
|
defaultValue: null,
|
|
2399
|
-
description: "Connection ID for the IS connector (bindable)"
|
|
2430
|
+
description: "Connection ID for the IS connector (bindable)",
|
|
2431
|
+
bindingInfo: {
|
|
2432
|
+
resource: "Connection",
|
|
2433
|
+
resourceKeyPattern: "${resourceKey}",
|
|
2434
|
+
propertyAttribute: "ConnectionId"
|
|
2435
|
+
}
|
|
2400
2436
|
},
|
|
2401
2437
|
{
|
|
2402
2438
|
name: "connectorKey",
|
|
@@ -4455,6 +4491,14 @@ var init_bpmn_packaging = __esm(() => {
|
|
|
4455
4491
|
].sort());
|
|
4456
4492
|
SUPPORTED_UIPATH_EXTENSION_TAGS2 = Object.freeze(SUPPORTED_UIPATH_EXTENSION_TAG_NAMES2.map((tag) => `uipath:${tag}`));
|
|
4457
4493
|
KNOWN_UIPATH_TAGS2 = new Set(SUPPORTED_UIPATH_EXTENSION_TAGS2);
|
|
4494
|
+
CALL_ACTIVITY_TYPES2 = Object.entries(BPMN_SPEC2.extensionTypes).filter(([, contract]) => contract.bpmnElement === "bpmn:CallActivity").map(([type]) => type).sort((a, b) => a.localeCompare(b));
|
|
4495
|
+
CALL_ACTIVITY_PAYLOAD_TAGS2 = new Set(Object.values(BPMN_SPEC2.extensionTypes).filter((contract) => contract.bpmnElement === "bpmn:CallActivity").map((contract) => contract.extensionTag).filter((tag) => typeof tag === "string"));
|
|
4496
|
+
FREE_TEXT_ELEMENTS2 = new Set(["documentation", "text"]);
|
|
4497
|
+
CONNECTION_CONNECTOR_TYPES = new Set([
|
|
4498
|
+
"Intsvc.ActivityExecution",
|
|
4499
|
+
"Intsvc.EventTrigger",
|
|
4500
|
+
"Intsvc.WaitForEvent"
|
|
4501
|
+
]);
|
|
4458
4502
|
nativeToString = Object.prototype.toString;
|
|
4459
4503
|
nativeHasOwnProperty = Object.prototype.hasOwnProperty;
|
|
4460
4504
|
Base.prototype.get = function(name) {
|
|
@@ -9304,6 +9348,14 @@ import {
|
|
|
9304
9348
|
|
|
9305
9349
|
// ../../maestro-sdk/dist/bpmn-validation/project-validator.js
|
|
9306
9350
|
var {createRequire} = (() => ({}));
|
|
9351
|
+
var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
9352
|
+
function isGuid(value) {
|
|
9353
|
+
return GUID_REGEX.test(value);
|
|
9354
|
+
}
|
|
9355
|
+
var GUID_REGEX;
|
|
9356
|
+
var init_guid = __esm2(() => {
|
|
9357
|
+
GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9358
|
+
});
|
|
9307
9359
|
var bpmn_spec_default = {
|
|
9308
9360
|
version: "1.0.0",
|
|
9309
9361
|
source: "PO.Frontend registry generator (2026-04-14) + CLI notes",
|
|
@@ -10086,6 +10138,15 @@ var bpmn_spec_default = {
|
|
|
10086
10138
|
<bpmn:extensionElements>
|
|
10087
10139
|
<uipath:event version="v1">
|
|
10088
10140
|
<uipath:type value="Intsvc.WaitForEvent" version="v1" />
|
|
10141
|
+
<uipath:context>
|
|
10142
|
+
<uipath:input name="connectorKey" type="string" value="{connectorKey}" />
|
|
10143
|
+
<uipath:input name="connectionId" type="string" value="=bindings.{connectionBindingId}" />
|
|
10144
|
+
<uipath:input name="folderId" type="string" value="{folderId}" />
|
|
10145
|
+
<uipath:input name="folderPath" type="string" value="{folderPath}" />
|
|
10146
|
+
<uipath:input name="folderKey" type="string" value="{folderKey}" />
|
|
10147
|
+
<uipath:input name="operation" type="string" value="{operation}" />
|
|
10148
|
+
<uipath:input name="objectName" type="string" value="{objectName}" />
|
|
10149
|
+
</uipath:context>
|
|
10089
10150
|
<uipath:output name="result" type="custom" source="." var="{varId}" />
|
|
10090
10151
|
</uipath:event>
|
|
10091
10152
|
</bpmn:extensionElements>
|
|
@@ -10106,7 +10167,12 @@ var bpmn_spec_default = {
|
|
|
10106
10167
|
isPrimaryKey: false,
|
|
10107
10168
|
binding: true,
|
|
10108
10169
|
defaultValue: null,
|
|
10109
|
-
description: "Connection ID for the IS connector (bindable)"
|
|
10170
|
+
description: "Connection ID for the IS connector (bindable)",
|
|
10171
|
+
bindingInfo: {
|
|
10172
|
+
resource: "Connection",
|
|
10173
|
+
resourceKeyPattern: "${resourceKey}",
|
|
10174
|
+
propertyAttribute: "ConnectionId"
|
|
10175
|
+
}
|
|
10110
10176
|
},
|
|
10111
10177
|
{
|
|
10112
10178
|
name: "connectorKey",
|
|
@@ -10224,6 +10290,15 @@ var bpmn_spec_default = {
|
|
|
10224
10290
|
<bpmn:extensionElements>
|
|
10225
10291
|
<uipath:event version="v1">
|
|
10226
10292
|
<uipath:type value="Intsvc.EventTrigger" version="v1" />
|
|
10293
|
+
<uipath:context>
|
|
10294
|
+
<uipath:input name="connectorKey" type="string" value="{connectorKey}" />
|
|
10295
|
+
<uipath:input name="connectionId" type="string" value="=bindings.{connectionBindingId}" />
|
|
10296
|
+
<uipath:input name="folderId" type="string" value="{folderId}" />
|
|
10297
|
+
<uipath:input name="folderPath" type="string" value="{folderPath}" />
|
|
10298
|
+
<uipath:input name="folderKey" type="string" value="{folderKey}" />
|
|
10299
|
+
<uipath:input name="operation" type="string" value="{operation}" />
|
|
10300
|
+
<uipath:input name="objectName" type="string" value="{objectName}" />
|
|
10301
|
+
</uipath:context>
|
|
10227
10302
|
<uipath:output name="result" type="custom" source="." var="{varId}" />
|
|
10228
10303
|
</uipath:event>
|
|
10229
10304
|
</bpmn:extensionElements>
|
|
@@ -10245,7 +10320,12 @@ var bpmn_spec_default = {
|
|
|
10245
10320
|
isPrimaryKey: false,
|
|
10246
10321
|
binding: true,
|
|
10247
10322
|
defaultValue: null,
|
|
10248
|
-
description: "Connection ID for the IS connector (bindable)"
|
|
10323
|
+
description: "Connection ID for the IS connector (bindable)",
|
|
10324
|
+
bindingInfo: {
|
|
10325
|
+
resource: "Connection",
|
|
10326
|
+
resourceKeyPattern: "${resourceKey}",
|
|
10327
|
+
propertyAttribute: "ConnectionId"
|
|
10328
|
+
}
|
|
10249
10329
|
},
|
|
10250
10330
|
{
|
|
10251
10331
|
name: "connectorKey",
|
|
@@ -12303,11 +12383,10 @@ var SUPPORTED_UIPATH_EXTENSION_TAG_NAMES = Object.freeze([
|
|
|
12303
12383
|
])
|
|
12304
12384
|
].sort());
|
|
12305
12385
|
var SUPPORTED_UIPATH_EXTENSION_TAGS = Object.freeze(SUPPORTED_UIPATH_EXTENSION_TAG_NAMES.map((tag) => `uipath:${tag}`));
|
|
12306
|
-
|
|
12307
|
-
function isGuid(value) {
|
|
12308
|
-
return GUID_REGEX.test(value);
|
|
12309
|
-
}
|
|
12386
|
+
init_guid();
|
|
12310
12387
|
var KNOWN_UIPATH_TAGS = new Set(SUPPORTED_UIPATH_EXTENSION_TAGS);
|
|
12388
|
+
var CALL_ACTIVITY_TYPES = Object.entries(BPMN_SPEC.extensionTypes).filter(([, contract]) => contract.bpmnElement === "bpmn:CallActivity").map(([type]) => type).sort((a, b) => a.localeCompare(b));
|
|
12389
|
+
var CALL_ACTIVITY_PAYLOAD_TAGS = new Set(Object.values(BPMN_SPEC.extensionTypes).filter((contract) => contract.bpmnElement === "bpmn:CallActivity").map((contract) => contract.extensionTag).filter((tag) => typeof tag === "string"));
|
|
12311
12390
|
var SEMANTIC_VALIDATION_ERROR = "BPMN_VALIDATION_ERROR";
|
|
12312
12391
|
var BPMN_MODEL_NAMESPACE = "http://www.omg.org/spec/BPMN/20100524/MODEL";
|
|
12313
12392
|
var ACTIVITY_CONFIGURATION_VERSION = "activityConfigurationVersion";
|
|
@@ -12420,6 +12499,84 @@ class BpmnValidateService {
|
|
|
12420
12499
|
const availableBindings = new Map(bindings);
|
|
12421
12500
|
collectInlineBindings(definitions, availableBindings);
|
|
12422
12501
|
this.validateUiPathTags(file, definitions, availableBindings, diagnostics);
|
|
12502
|
+
this.validateUnassignedVariables(file, definitions, diagnostics);
|
|
12503
|
+
this.validateCallActivityReferences(file, definitions, diagnostics);
|
|
12504
|
+
}
|
|
12505
|
+
validateUnassignedVariables(file, definitions, diagnostics) {
|
|
12506
|
+
for (const process of findChildren(definitions, (node) => hasLocalName(node, "process"))) {
|
|
12507
|
+
this.reportUnassignedVariables(file, process, diagnostics);
|
|
12508
|
+
}
|
|
12509
|
+
}
|
|
12510
|
+
reportUnassignedVariables(file, process, diagnostics) {
|
|
12511
|
+
const startEventIds = new Set(findChildren(process, (node) => hasLocalName(node, "startEvent")).filter(isManualStartEvent).map((node) => node.attributes.id).filter((id) => Boolean(id)));
|
|
12512
|
+
const declaredById = new Map;
|
|
12513
|
+
for (const block of findDescendants(process, (node) => hasLocalName(node, "variables"))) {
|
|
12514
|
+
for (const decl of block.children) {
|
|
12515
|
+
const declKind = getLocalName(decl.name);
|
|
12516
|
+
if (declKind !== "input" && declKind !== "inputoutput" && declKind !== "output") {
|
|
12517
|
+
continue;
|
|
12518
|
+
}
|
|
12519
|
+
const id = decl.attributes.id;
|
|
12520
|
+
if (!id) {
|
|
12521
|
+
continue;
|
|
12522
|
+
}
|
|
12523
|
+
const elementId = decl.attributes.elementId?.trim() ?? "";
|
|
12524
|
+
const callerCanSupply = declKind === "input" && !!decl.attributes.name?.trim() && startEventIds.has(elementId);
|
|
12525
|
+
declaredById.set(id, {
|
|
12526
|
+
hasValueSource: !!decl.attributes.default?.trim() || callerCanSupply,
|
|
12527
|
+
declKind,
|
|
12528
|
+
element: describeElement(decl)
|
|
12529
|
+
});
|
|
12530
|
+
}
|
|
12531
|
+
}
|
|
12532
|
+
if (declaredById.size === 0) {
|
|
12533
|
+
return;
|
|
12534
|
+
}
|
|
12535
|
+
const assigned = new Set;
|
|
12536
|
+
for (const output of findDescendants(process, (node) => hasLocalName(node, "output"))) {
|
|
12537
|
+
const target = output.attributes.var;
|
|
12538
|
+
const isDeclaration = output.parent !== undefined && hasLocalName(output.parent, "variables");
|
|
12539
|
+
if (target && !isDeclaration) {
|
|
12540
|
+
assigned.add(target);
|
|
12541
|
+
}
|
|
12542
|
+
}
|
|
12543
|
+
for (const id of collectVariableReads(process)) {
|
|
12544
|
+
const declared = declaredById.get(id);
|
|
12545
|
+
if (!declared || declared.hasValueSource || assigned.has(id)) {
|
|
12546
|
+
continue;
|
|
12547
|
+
}
|
|
12548
|
+
diagnostics.push({
|
|
12549
|
+
file,
|
|
12550
|
+
element: declared.element,
|
|
12551
|
+
message: `Variable "vars.${id}" is read but never assigned; it will be empty at run time.`,
|
|
12552
|
+
instruction: declared.declKind === "input" ? "Give the variable a default, assign it through a uipath:output mapping, or bind it to an entry-point start event by giving it both a name and an elementId." : "Give the variable a default, or assign it through a uipath:output mapping before it is read.",
|
|
12553
|
+
severity: "warning"
|
|
12554
|
+
});
|
|
12555
|
+
}
|
|
12556
|
+
}
|
|
12557
|
+
validateCallActivityReferences(file, definitions, diagnostics) {
|
|
12558
|
+
for (const callActivity of findDescendants(definitions, (node) => hasLocalName(node, "callActivity"))) {
|
|
12559
|
+
const hasUiPathPayload = findDescendants(callActivity, (node) => CALL_ACTIVITY_PAYLOAD_TAGS.has(node.name)).length > 0;
|
|
12560
|
+
const calledElement = callActivity.attributes.calledElement?.trim() ?? "";
|
|
12561
|
+
if (!hasUiPathPayload) {
|
|
12562
|
+
diagnostics.push({
|
|
12563
|
+
file,
|
|
12564
|
+
element: describeElement(callActivity),
|
|
12565
|
+
message: "Call activity has no uipath:activity payload, so it invokes nothing at run time.",
|
|
12566
|
+
instruction: `Add a payload naming one of the call-activity types (${CALL_ACTIVITY_TYPES.join(", ")}), with a process resource binding.`
|
|
12567
|
+
});
|
|
12568
|
+
continue;
|
|
12569
|
+
}
|
|
12570
|
+
if (calledElement) {
|
|
12571
|
+
diagnostics.push({
|
|
12572
|
+
file,
|
|
12573
|
+
element: describeElement(callActivity),
|
|
12574
|
+
message: `Call activity attribute calledElement="${calledElement}" is ignored; the invoked process comes from the uipath:activity payload and its process binding.`,
|
|
12575
|
+
instruction: "Remove calledElement, or ensure the uipath:activity payload names the process you intend to invoke.",
|
|
12576
|
+
severity: "warning"
|
|
12577
|
+
});
|
|
12578
|
+
}
|
|
12579
|
+
}
|
|
12423
12580
|
}
|
|
12424
12581
|
validateRootEntryPointIds(file, process, diagnostics) {
|
|
12425
12582
|
const rootStartEvents = findChildren(process, (node) => hasLocalName(node, "startEvent"));
|
|
@@ -12522,12 +12679,13 @@ class BpmnValidateService {
|
|
|
12522
12679
|
}
|
|
12523
12680
|
const contract = BPMN_SPEC.extensionTypes[extensionType];
|
|
12524
12681
|
if (!contract) {
|
|
12682
|
+
const severity = this.options.unsupportedExtensionTypeSeverity ?? "warning";
|
|
12525
12683
|
diagnostics.push({
|
|
12526
12684
|
file,
|
|
12527
12685
|
element: describeElement(typeNode ?? payload),
|
|
12528
12686
|
message: `Unsupported UiPath extension type "${extensionType}".`,
|
|
12529
|
-
instruction: "Use an extension type present in the UiPath BPMN contract, or update the contract before packaging this project.",
|
|
12530
|
-
severity
|
|
12687
|
+
instruction: severity === "error" ? `"${extensionType}" is not in this CLI's BPMN contract, so Orchestrator will reject the package at deploy (Error 1654). Use a supported extension type, remove the node, or upgrade the CLI to a version whose contract includes it.` : "Use an extension type present in the UiPath BPMN contract, or update the contract before packaging this project.",
|
|
12688
|
+
severity
|
|
12531
12689
|
});
|
|
12532
12690
|
return;
|
|
12533
12691
|
}
|
|
@@ -12540,6 +12698,9 @@ class BpmnValidateService {
|
|
|
12540
12698
|
if (contract.extensionType === "Orchestrator.StartAgentJob") {
|
|
12541
12699
|
this.validateStartAgentJobBindings(file, payload, owner, bindings, diagnostics);
|
|
12542
12700
|
}
|
|
12701
|
+
if (contract.extensionType === "Intsvc.EventTrigger" || contract.extensionType === "Intsvc.WaitForEvent") {
|
|
12702
|
+
this.validateTriggerConnectionBinding(file, payload, owner, bindings, contract.extensionType === "Intsvc.WaitForEvent" ? "wait" : "trigger", diagnostics);
|
|
12703
|
+
}
|
|
12543
12704
|
this.validateInputs(file, payload, owner, contract, diagnostics);
|
|
12544
12705
|
this.validateOutput(file, payload, owner, contract, diagnostics);
|
|
12545
12706
|
this.validateBindingReferences(file, payload, bindings, diagnostics);
|
|
@@ -12613,23 +12774,44 @@ class BpmnValidateService {
|
|
|
12613
12774
|
}
|
|
12614
12775
|
}
|
|
12615
12776
|
validateActivityExecutionV1Bindings(file, payload, owner, bindings, diagnostics) {
|
|
12616
|
-
const
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12777
|
+
const resourceKeys = this.validateConnectionBindings(file, payload, owner, bindings, diagnostics, "activity", [
|
|
12778
|
+
{
|
|
12779
|
+
contextName: "connection",
|
|
12780
|
+
propertyAttribute: "ConnectionId"
|
|
12781
|
+
},
|
|
12782
|
+
{ contextName: "folderKey", propertyAttribute: "folderKey" }
|
|
12783
|
+
]);
|
|
12784
|
+
const connectionResourceKey = resourceKeys.get("connection");
|
|
12785
|
+
const folderResourceKey = resourceKeys.get("folderKey");
|
|
12786
|
+
if (connectionResourceKey && folderResourceKey && connectionResourceKey !== folderResourceKey) {
|
|
12787
|
+
diagnostics.push({
|
|
12788
|
+
file,
|
|
12789
|
+
element: describeElement(owner),
|
|
12790
|
+
message: "Integration Service activity connection and folder bindings refer to different connection resources.",
|
|
12791
|
+
instruction: "Set the same resourceKey on both root bindings."
|
|
12792
|
+
});
|
|
12793
|
+
}
|
|
12794
|
+
}
|
|
12795
|
+
validateTriggerConnectionBinding(file, payload, owner, bindings, nodeLabel, diagnostics) {
|
|
12796
|
+
this.validateConnectionBindings(file, payload, owner, bindings, diagnostics, nodeLabel, [
|
|
12621
12797
|
{
|
|
12622
12798
|
contextName: "connection",
|
|
12623
12799
|
propertyAttribute: "ConnectionId"
|
|
12624
12800
|
},
|
|
12625
12801
|
{
|
|
12626
|
-
contextName: "
|
|
12627
|
-
propertyAttribute: "
|
|
12802
|
+
contextName: "connectionId",
|
|
12803
|
+
propertyAttribute: "ConnectionId"
|
|
12628
12804
|
}
|
|
12629
|
-
];
|
|
12805
|
+
]);
|
|
12806
|
+
}
|
|
12807
|
+
validateConnectionBindings(file, payload, owner, bindings, diagnostics, nodeLabel, bindingFields) {
|
|
12808
|
+
const inputByName = new Map(getConnectorInputs(payload).map((input) => [
|
|
12809
|
+
input.attributes.name,
|
|
12810
|
+
input
|
|
12811
|
+
]));
|
|
12630
12812
|
const resourceKeys = new Map;
|
|
12631
12813
|
for (const field of bindingFields) {
|
|
12632
|
-
const contextInput =
|
|
12814
|
+
const contextInput = inputByName.get(field.contextName);
|
|
12633
12815
|
if (!contextInput) {
|
|
12634
12816
|
continue;
|
|
12635
12817
|
}
|
|
@@ -12641,7 +12823,7 @@ class BpmnValidateService {
|
|
|
12641
12823
|
diagnostics.push({
|
|
12642
12824
|
file,
|
|
12643
12825
|
element: describeElement(owner),
|
|
12644
|
-
message: `Integration Service
|
|
12826
|
+
message: `Integration Service ${nodeLabel} context input "${field.contextName}" must reference a root binding.`,
|
|
12645
12827
|
instruction: `Set ${field.contextName} to =bindings.<bindingId> and declare that binding with resource="Connection" and propertyAttribute="${field.propertyAttribute}".`
|
|
12646
12828
|
});
|
|
12647
12829
|
continue;
|
|
@@ -12656,7 +12838,7 @@ class BpmnValidateService {
|
|
|
12656
12838
|
diagnostics.push({
|
|
12657
12839
|
file,
|
|
12658
12840
|
element: describeElement(owner),
|
|
12659
|
-
message: `Integration Service
|
|
12841
|
+
message: `Integration Service ${nodeLabel} ${field.contextName} binding "${bindingId}" must use resource="Connection" and propertyAttribute="${field.propertyAttribute}".`,
|
|
12660
12842
|
instruction: `Set resource="Connection" and propertyAttribute="${field.propertyAttribute}" on that binding.`
|
|
12661
12843
|
});
|
|
12662
12844
|
}
|
|
@@ -12665,23 +12847,14 @@ class BpmnValidateService {
|
|
|
12665
12847
|
diagnostics.push({
|
|
12666
12848
|
file,
|
|
12667
12849
|
element: describeElement(owner),
|
|
12668
|
-
message: `Integration Service
|
|
12850
|
+
message: `Integration Service ${nodeLabel} ${field.contextName} binding "${bindingId}" is missing resourceKey.`,
|
|
12669
12851
|
instruction: "Set resourceKey on that root binding."
|
|
12670
12852
|
});
|
|
12671
12853
|
} else if (!hasInvalidBindingShape) {
|
|
12672
12854
|
resourceKeys.set(field.contextName, resourceKey);
|
|
12673
12855
|
}
|
|
12674
12856
|
}
|
|
12675
|
-
|
|
12676
|
-
const folderResourceKey = resourceKeys.get("folderKey");
|
|
12677
|
-
if (connectionResourceKey && folderResourceKey && connectionResourceKey !== folderResourceKey) {
|
|
12678
|
-
diagnostics.push({
|
|
12679
|
-
file,
|
|
12680
|
-
element: describeElement(owner),
|
|
12681
|
-
message: "Integration Service activity connection and folder bindings refer to different connection resources.",
|
|
12682
|
-
instruction: "Set the same resourceKey on both root bindings."
|
|
12683
|
-
});
|
|
12684
|
-
}
|
|
12857
|
+
return resourceKeys;
|
|
12685
12858
|
}
|
|
12686
12859
|
validateInputs(file, payload, owner, contract, diagnostics) {
|
|
12687
12860
|
const directInputs = childElements(payload, "uipath:input");
|
|
@@ -13102,6 +13275,38 @@ function findFirst(node, predicate) {
|
|
|
13102
13275
|
}
|
|
13103
13276
|
return;
|
|
13104
13277
|
}
|
|
13278
|
+
function isManualStartEvent(startEvent) {
|
|
13279
|
+
const hasEventDefinition = startEvent.children.some((child) => getLocalName(child.name).endsWith("eventdefinition"));
|
|
13280
|
+
const hasUiPathEvent = findDescendants(startEvent, (node) => hasLocalName(node, "event")).length > 0;
|
|
13281
|
+
return !hasEventDefinition && !hasUiPathEvent;
|
|
13282
|
+
}
|
|
13283
|
+
var VARIABLE_READ = /vars(?:\.([A-Za-z_$][\w$]*)|\[\s*["']([^"']+)["']\s*\])/g;
|
|
13284
|
+
var FREE_TEXT_ELEMENTS = new Set(["documentation", "text"]);
|
|
13285
|
+
function collectVariableReads(node, into = new Set) {
|
|
13286
|
+
for (const value of Object.values(node.attributes)) {
|
|
13287
|
+
if (!value.trimStart().startsWith("=")) {
|
|
13288
|
+
continue;
|
|
13289
|
+
}
|
|
13290
|
+
for (const match of value.matchAll(VARIABLE_READ)) {
|
|
13291
|
+
const id = match[1] ?? match[2];
|
|
13292
|
+
if (id) {
|
|
13293
|
+
into.add(id);
|
|
13294
|
+
}
|
|
13295
|
+
}
|
|
13296
|
+
}
|
|
13297
|
+
if (node.text && !FREE_TEXT_ELEMENTS.has(getLocalName(node.name))) {
|
|
13298
|
+
for (const match of node.text.matchAll(VARIABLE_READ)) {
|
|
13299
|
+
const id = match[1] ?? match[2];
|
|
13300
|
+
if (id) {
|
|
13301
|
+
into.add(id);
|
|
13302
|
+
}
|
|
13303
|
+
}
|
|
13304
|
+
}
|
|
13305
|
+
for (const child of node.children) {
|
|
13306
|
+
collectVariableReads(child, into);
|
|
13307
|
+
}
|
|
13308
|
+
return into;
|
|
13309
|
+
}
|
|
13105
13310
|
function hasLocalName(node, localName) {
|
|
13106
13311
|
return getLocalName(node.name) === localName.toLowerCase();
|
|
13107
13312
|
}
|
|
@@ -13134,6 +13339,12 @@ function findBpmnOwner(payload) {
|
|
|
13134
13339
|
function getContextInputs(payload) {
|
|
13135
13340
|
return childElements(payload, "uipath:context").flatMap((context) => childElements(context, "uipath:input"));
|
|
13136
13341
|
}
|
|
13342
|
+
function getConnectorInputs(payload) {
|
|
13343
|
+
return [
|
|
13344
|
+
...getContextInputs(payload),
|
|
13345
|
+
...childElements(payload, "uipath:input")
|
|
13346
|
+
];
|
|
13347
|
+
}
|
|
13137
13348
|
function isIntsvcActivityExecutionV1(nodeVersion, workflowVersion) {
|
|
13138
13349
|
const version = nodeVersion ?? workflowVersion;
|
|
13139
13350
|
return version === undefined || version === ACTIVITY_CONFIGURATION_V1;
|
|
@@ -13354,18 +13565,24 @@ function createBpmnValidationFileSystem(fileSystem) {
|
|
|
13354
13565
|
class BpmnTool extends ProjectTool {
|
|
13355
13566
|
_temporaryStorage;
|
|
13356
13567
|
_validateService;
|
|
13568
|
+
_packValidateService;
|
|
13357
13569
|
constructor(fileSystem, logger) {
|
|
13358
13570
|
super(fileSystem, logger);
|
|
13359
13571
|
this._temporaryStorage = new TemporaryStorageService(fileSystem);
|
|
13360
|
-
|
|
13572
|
+
const validationFileSystem = createBpmnValidationFileSystem(fileSystem);
|
|
13573
|
+
this._validateService = new BpmnValidateService(validationFileSystem);
|
|
13574
|
+
this._packValidateService = new BpmnValidateService(validationFileSystem, { unsupportedExtensionTypeSeverity: "error" });
|
|
13361
13575
|
}
|
|
13362
13576
|
async restoreAsync(_options, _cancellationToken) {
|
|
13363
13577
|
this.logger.info("Restore operation is not required for ProcessOrchestration projects");
|
|
13364
13578
|
return ToolResult.success();
|
|
13365
13579
|
}
|
|
13366
13580
|
async validateAsync(options, _cancellationToken) {
|
|
13581
|
+
return this.runValidation(this._validateService, options.projectPath);
|
|
13582
|
+
}
|
|
13583
|
+
async runValidation(service, projectPath) {
|
|
13367
13584
|
this.logger.info("Validating ProcessOrchestration BPMN project...");
|
|
13368
|
-
const result = await
|
|
13585
|
+
const result = await service.validateProject(projectPath);
|
|
13369
13586
|
if (!result.isValid) {
|
|
13370
13587
|
if (result.message) {
|
|
13371
13588
|
this.logger.error(result.message);
|
|
@@ -13384,16 +13601,7 @@ class BpmnTool extends ProjectTool {
|
|
|
13384
13601
|
const contentFolder = Path.join(localBuildFolder, NugetConstants.ContentFolderName);
|
|
13385
13602
|
try {
|
|
13386
13603
|
if (!options.skipValidate) {
|
|
13387
|
-
const validationResult = await this.
|
|
13388
|
-
projectPath: options.projectPath,
|
|
13389
|
-
excludeConfiguredSources: options.excludeConfiguredSources,
|
|
13390
|
-
skipAnalyze: options.skipAnalyze,
|
|
13391
|
-
skipValidate: options.skipValidate,
|
|
13392
|
-
detailedLogPath: options.detailedLogPath,
|
|
13393
|
-
policyFilePath: options.policyFilePath,
|
|
13394
|
-
logLevel: options.logLevel,
|
|
13395
|
-
nuGetSourcesConfigPath: options.nuGetSourcesConfigPath
|
|
13396
|
-
});
|
|
13604
|
+
const validationResult = await this.runValidation(this._packValidateService, options.projectPath);
|
|
13397
13605
|
if (!validationResult.isSuccess) {
|
|
13398
13606
|
return validationResult;
|
|
13399
13607
|
}
|
|
@@ -13515,11 +13723,18 @@ class BpmnTool extends ProjectTool {
|
|
|
13515
13723
|
const existing = await this.readExistingArtifacts(contentFolder, parseOptionalJson2);
|
|
13516
13724
|
const existingBindings = existing["bindings_v2.json"];
|
|
13517
13725
|
const existingResources = Array.isArray(existingBindings?.resources) ? existingBindings.resources.filter(isJsonObject2) : [];
|
|
13726
|
+
let resources;
|
|
13727
|
+
try {
|
|
13728
|
+
resources = buildConnectionResources2(processes, existingResources);
|
|
13729
|
+
} catch (error3) {
|
|
13730
|
+
const message = error3 instanceof Error ? error3.message : String(error3);
|
|
13731
|
+
return `${bpmnFile} has an Integration Service connection binding that cannot be resolved — ${message}`;
|
|
13732
|
+
}
|
|
13518
13733
|
const metadata = buildBpmnPackageMetadata2({
|
|
13519
13734
|
bpmnFile,
|
|
13520
13735
|
entryPoints,
|
|
13521
13736
|
projectId: options.projectStorageId ?? crypto.randomUUID(),
|
|
13522
|
-
resources
|
|
13737
|
+
resources,
|
|
13523
13738
|
existing
|
|
13524
13739
|
});
|
|
13525
13740
|
for (const name2 of [
|
|
@@ -13630,4 +13845,4 @@ export {
|
|
|
13630
13845
|
BpmnToolFactory
|
|
13631
13846
|
};
|
|
13632
13847
|
|
|
13633
|
-
//# debugId=
|
|
13848
|
+
//# debugId=63A8A4C6F0F0836164756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/packager-tool-bpmn",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.202.0-preview.136",
|
|
4
4
|
"description": "UiPath ProcessOrchestration (BPMN) tool implementation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"author": "",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@uipath/solutionpackager-tool-core": "1.
|
|
28
|
+
"@uipath/solutionpackager-tool-core": "1.202.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@uipath/maestro-sdk": "1.
|
|
31
|
+
"@uipath/maestro-sdk": "1.202.0"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "f6270de2c7c04f4c43b2f5187b0c3d3c314c2610"
|
|
34
34
|
}
|
package/src/bpmn-tool.ts
CHANGED
|
@@ -51,13 +51,23 @@ function createBpmnValidationFileSystem(
|
|
|
51
51
|
*/
|
|
52
52
|
export class BpmnTool extends ProjectTool {
|
|
53
53
|
private readonly _temporaryStorage: TemporaryStorageService;
|
|
54
|
+
// Standalone `validate` keeps an extension type absent from the contract a
|
|
55
|
+
// warning, so authoring against a type newer than the CLI's bundled contract
|
|
56
|
+
// is not blocked.
|
|
54
57
|
private readonly _validateService: BpmnValidateService;
|
|
58
|
+
// Packaging must fail fast on such a type rather than ship a package
|
|
59
|
+
// Orchestrator rejects at deploy (Error 1654), so the build path validates
|
|
60
|
+
// with error severity.
|
|
61
|
+
private readonly _packValidateService: BpmnValidateService;
|
|
55
62
|
|
|
56
63
|
constructor(fileSystem: IFileSystem, logger: IToolLogger) {
|
|
57
64
|
super(fileSystem, logger);
|
|
58
65
|
this._temporaryStorage = new TemporaryStorageService(fileSystem);
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
const validationFileSystem = createBpmnValidationFileSystem(fileSystem);
|
|
67
|
+
this._validateService = new BpmnValidateService(validationFileSystem);
|
|
68
|
+
this._packValidateService = new BpmnValidateService(
|
|
69
|
+
validationFileSystem,
|
|
70
|
+
{ unsupportedExtensionTypeSeverity: "error" },
|
|
61
71
|
);
|
|
62
72
|
}
|
|
63
73
|
|
|
@@ -74,11 +84,16 @@ export class BpmnTool extends ProjectTool {
|
|
|
74
84
|
override async validateAsync(
|
|
75
85
|
options: IProjectValidateOptions,
|
|
76
86
|
_cancellationToken?: AbortSignal,
|
|
87
|
+
): Promise<ToolResult> {
|
|
88
|
+
return this.runValidation(this._validateService, options.projectPath);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private async runValidation(
|
|
92
|
+
service: BpmnValidateService,
|
|
93
|
+
projectPath: string,
|
|
77
94
|
): Promise<ToolResult> {
|
|
78
95
|
this.logger.info("Validating ProcessOrchestration BPMN project...");
|
|
79
|
-
const result = await
|
|
80
|
-
options.projectPath,
|
|
81
|
-
);
|
|
96
|
+
const result = await service.validateProject(projectPath);
|
|
82
97
|
if (!result.isValid) {
|
|
83
98
|
if (result.message) {
|
|
84
99
|
this.logger.error(result.message);
|
|
@@ -111,16 +126,13 @@ export class BpmnTool extends ProjectTool {
|
|
|
111
126
|
|
|
112
127
|
try {
|
|
113
128
|
if (!options.skipValidate) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
logLevel: options.logLevel,
|
|
122
|
-
nuGetSourcesConfigPath: options.nuGetSourcesConfigPath,
|
|
123
|
-
});
|
|
129
|
+
// Error severity here: the build/pack path fails fast on an
|
|
130
|
+
// extension type absent from the contract, unlike standalone
|
|
131
|
+
// `validate`.
|
|
132
|
+
const validationResult = await this.runValidation(
|
|
133
|
+
this._packValidateService,
|
|
134
|
+
options.projectPath,
|
|
135
|
+
);
|
|
124
136
|
if (!validationResult.isSuccess) {
|
|
125
137
|
return validationResult;
|
|
126
138
|
}
|
|
@@ -348,9 +360,8 @@ export class BpmnTool extends ProjectTool {
|
|
|
348
360
|
// Deferred, not a top-level import: the derivation carries bpmn-moddle,
|
|
349
361
|
// and a static import lands it in a chunk that `maestro-tool`'s eager
|
|
350
362
|
// startup graph also touches — it is only needed when a BPMN project is
|
|
351
|
-
// actually built.
|
|
352
|
-
//
|
|
353
|
-
// `BpmnRefreshService`.
|
|
363
|
+
// actually built. The BPMN validate service and refresh command defer
|
|
364
|
+
// their own heavy code for the same reason.
|
|
354
365
|
const {
|
|
355
366
|
buildBpmnPackageMetadata,
|
|
356
367
|
buildConnectionResources,
|
|
@@ -381,6 +392,19 @@ export class BpmnTool extends ProjectTool {
|
|
|
381
392
|
? existingBindings.resources.filter(isJsonObject)
|
|
382
393
|
: [];
|
|
383
394
|
|
|
395
|
+
// buildConnectionResources throws when an Integration Service node's
|
|
396
|
+
// connection binding cannot be resolved (missing, literal, or malformed).
|
|
397
|
+
// Turn that into a specific reason here so `uip solution pack` reports
|
|
398
|
+
// the real cause instead of buildAsync's generic InternalError.
|
|
399
|
+
let resources: ReturnType<typeof buildConnectionResources>;
|
|
400
|
+
try {
|
|
401
|
+
resources = buildConnectionResources(processes, existingResources);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
const message =
|
|
404
|
+
error instanceof Error ? error.message : String(error);
|
|
405
|
+
return `${bpmnFile} has an Integration Service connection binding that cannot be resolved — ${message}`;
|
|
406
|
+
}
|
|
407
|
+
|
|
384
408
|
const metadata = buildBpmnPackageMetadata({
|
|
385
409
|
bpmnFile,
|
|
386
410
|
entryPoints,
|
|
@@ -388,7 +412,7 @@ export class BpmnTool extends ProjectTool {
|
|
|
388
412
|
// so this id is inert: operate.json stays owned by
|
|
389
413
|
// `ensureContentOperateFile`, which backfills the stable project id.
|
|
390
414
|
projectId: options.projectStorageId ?? crypto.randomUUID(),
|
|
391
|
-
resources
|
|
415
|
+
resources,
|
|
392
416
|
existing,
|
|
393
417
|
});
|
|
394
418
|
|