@uipath/maestro-builder-sdk 6.16.7 → 6.16.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/case/compile-cli.js +2 -7
- package/dist/core/stable-id.d.ts +33 -0
- package/dist/core/stable-id.js +56 -0
- package/dist/serialize.js +11 -42
- package/package.json +2 -2
package/dist/case/compile-cli.js
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
import { reportResult } from '../cli-result.js';
|
|
13
13
|
import { writeFileSync, readFileSync, existsSync } from 'node:fs';
|
|
14
14
|
import { join, dirname, basename, resolve } from 'node:path';
|
|
15
|
-
import { createHash } from 'node:crypto';
|
|
16
15
|
import { resolveCaseFile, loadBuiltCase } from './load.js';
|
|
17
16
|
import { serialize } from './serialize.js';
|
|
18
17
|
import { check } from './check.js';
|
|
@@ -23,6 +22,7 @@ import { defaultBindingsFile } from '../workdir.js';
|
|
|
23
22
|
import { flagValue, runWhenInvokedDirectly } from '../cli-run.js';
|
|
24
23
|
import { ensureTypeScriptRuntime } from '../node-runtime.js';
|
|
25
24
|
import { CASE_FORMAT_PROFILE } from './format-profile.js';
|
|
25
|
+
import { sha256Uuid } from '../core/stable-id.js';
|
|
26
26
|
export async function run(argv) {
|
|
27
27
|
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
28
28
|
console.error('usage: compile <case.ts | BaseName> [-o caseplan.json]');
|
|
@@ -128,7 +128,7 @@ function syncEntryPoints(caseplan, outPath) {
|
|
|
128
128
|
const { input, output } = entryPointIO(caseplan.variables, n.id);
|
|
129
129
|
return {
|
|
130
130
|
filePath: `/content/${base}.bpmn#${n.id}`,
|
|
131
|
-
uniqueId: prev?.uniqueId ??
|
|
131
|
+
uniqueId: prev?.uniqueId ?? sha256Uuid(`entrypoint:${n.id}`),
|
|
132
132
|
type: 'CaseManagement',
|
|
133
133
|
input,
|
|
134
134
|
output,
|
|
@@ -279,9 +279,4 @@ function isRecord(value) {
|
|
|
279
279
|
function stringValue(value) {
|
|
280
280
|
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
281
281
|
}
|
|
282
|
-
/** A deterministic UUID-shaped id (not a real v4 — the schema only needs a stable string). */
|
|
283
|
-
function stableUuid(seed) {
|
|
284
|
-
const h = createHash('sha256').update(seed).digest('hex');
|
|
285
|
-
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
|
|
286
|
-
}
|
|
287
282
|
runWhenInvokedDirectly(import.meta.url, 'compile', run);
|
package/dist/core/stable-id.d.ts
CHANGED
|
@@ -24,5 +24,38 @@
|
|
|
24
24
|
* cannot read as a uuid. Coercing to unsigned first is the whole repair; the
|
|
25
25
|
* hash itself is unchanged, so a seed that produced a WELL-FORMED id still
|
|
26
26
|
* produces exactly that id.
|
|
27
|
+
*
|
|
28
|
+
* ## Three seed → uuid algorithms live here, and they are NOT interchangeable
|
|
29
|
+
*
|
|
30
|
+
* `stableId` (connector filter trees, event subscriptions), `fnv1aX4Uuid` (Flow
|
|
31
|
+
* inline-agent resource ids) and `sha256Uuid` (Case entry-point `uniqueId`) each
|
|
32
|
+
* produce ids that are already in shipped artifacts. Replacing one with another
|
|
33
|
+
* renames those resources on the next compile of every existing project. They are
|
|
34
|
+
* owned here so there is one place to look. The golden table in
|
|
35
|
+
* `tests/stable-id.test.ts` pins what each function returns, not which one a call
|
|
36
|
+
* site uses; `tests/cli.test.ts` pins the Case entry point's `uniqueId`. Change one
|
|
37
|
+
* only deliberately, updating that table and any byte-lock fixture it moves.
|
|
27
38
|
*/
|
|
39
|
+
/** A uuid-shaped id derived from `seed`. Every segment is unsigned, including the `>>> 0` fix explained above. */
|
|
28
40
|
export declare function stableId(seed: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* A deterministic v4-shaped uuid from a string.
|
|
43
|
+
*
|
|
44
|
+
* Used for an inline agent's `source` when the author does not pass one. It has to
|
|
45
|
+
* LOOK like a uuid (the platform treats it as an opaque directory name and the
|
|
46
|
+
* designer shows it as a folder) and it has to be STABLE, because a random one would
|
|
47
|
+
* make every recompile a diff of the `.flow` and a rename of a directory. FNV-1a
|
|
48
|
+
* ×4 with the version/variant nibbles pinned — not a cryptographic hash, and it does
|
|
49
|
+
* not need to be: the only requirement is that two different (flow, step) pairs do
|
|
50
|
+
* not collide within one project.
|
|
51
|
+
*
|
|
52
|
+
* Consumer: Flow inline-agent resource ids in `serialize.ts`.
|
|
53
|
+
*/
|
|
54
|
+
export declare function fnv1aX4Uuid(seed: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* A deterministic UUID-shaped id (not a real v4 — the schema only needs a stable string):
|
|
57
|
+
* the first 128 bits of SHA-256(`seed`), no version or variant bits set.
|
|
58
|
+
*
|
|
59
|
+
* Consumer: a Case entry point's `uniqueId` in `entry-points.json` (`case/compile-cli.ts`).
|
|
60
|
+
*/
|
|
61
|
+
export declare function sha256Uuid(seed: string): string;
|
package/dist/core/stable-id.js
CHANGED
|
@@ -24,7 +24,20 @@
|
|
|
24
24
|
* cannot read as a uuid. Coercing to unsigned first is the whole repair; the
|
|
25
25
|
* hash itself is unchanged, so a seed that produced a WELL-FORMED id still
|
|
26
26
|
* produces exactly that id.
|
|
27
|
+
*
|
|
28
|
+
* ## Three seed → uuid algorithms live here, and they are NOT interchangeable
|
|
29
|
+
*
|
|
30
|
+
* `stableId` (connector filter trees, event subscriptions), `fnv1aX4Uuid` (Flow
|
|
31
|
+
* inline-agent resource ids) and `sha256Uuid` (Case entry-point `uniqueId`) each
|
|
32
|
+
* produce ids that are already in shipped artifacts. Replacing one with another
|
|
33
|
+
* renames those resources on the next compile of every existing project. They are
|
|
34
|
+
* owned here so there is one place to look. The golden table in
|
|
35
|
+
* `tests/stable-id.test.ts` pins what each function returns, not which one a call
|
|
36
|
+
* site uses; `tests/cli.test.ts` pins the Case entry point's `uniqueId`. Change one
|
|
37
|
+
* only deliberately, updating that table and any byte-lock fixture it moves.
|
|
27
38
|
*/
|
|
39
|
+
import { createHash } from 'node:crypto';
|
|
40
|
+
/** A uuid-shaped id derived from `seed`. Every segment is unsigned, including the `>>> 0` fix explained above. */
|
|
28
41
|
export function stableId(seed) {
|
|
29
42
|
let h1 = 0x811c9dc5;
|
|
30
43
|
let h2 = 0x01000193;
|
|
@@ -35,3 +48,46 @@ export function stableId(seed) {
|
|
|
35
48
|
const hex = (n, len) => (n >>> 0).toString(16).padStart(8, '0').slice(0, len);
|
|
36
49
|
return `${hex(h1, 8)}-${hex(h2, 4)}-4${hex(h1 >>> 8, 3)}-8${hex(h2 >>> 8, 3)}-${hex(h1 ^ h2, 8)}${hex(h2, 4)}`;
|
|
37
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* A deterministic v4-shaped uuid from a string.
|
|
53
|
+
*
|
|
54
|
+
* Used for an inline agent's `source` when the author does not pass one. It has to
|
|
55
|
+
* LOOK like a uuid (the platform treats it as an opaque directory name and the
|
|
56
|
+
* designer shows it as a folder) and it has to be STABLE, because a random one would
|
|
57
|
+
* make every recompile a diff of the `.flow` and a rename of a directory. FNV-1a
|
|
58
|
+
* ×4 with the version/variant nibbles pinned — not a cryptographic hash, and it does
|
|
59
|
+
* not need to be: the only requirement is that two different (flow, step) pairs do
|
|
60
|
+
* not collide within one project.
|
|
61
|
+
*
|
|
62
|
+
* Consumer: Flow inline-agent resource ids in `serialize.ts`.
|
|
63
|
+
*/
|
|
64
|
+
export function fnv1aX4Uuid(seed) {
|
|
65
|
+
const words = [];
|
|
66
|
+
for (let i = 0; i < 4; i++) {
|
|
67
|
+
let h = 0x811c9dc5 ^ (i * 0x9e3779b9);
|
|
68
|
+
const s = `${seed}#${i}`;
|
|
69
|
+
for (let j = 0; j < s.length; j++) {
|
|
70
|
+
h ^= s.charCodeAt(j);
|
|
71
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
72
|
+
}
|
|
73
|
+
words.push(h >>> 0);
|
|
74
|
+
}
|
|
75
|
+
const hex = words.map((w) => w.toString(16).padStart(8, '0')).join('');
|
|
76
|
+
return [
|
|
77
|
+
hex.slice(0, 8),
|
|
78
|
+
hex.slice(8, 12),
|
|
79
|
+
`4${hex.slice(13, 16)}`,
|
|
80
|
+
`${((parseInt(hex.slice(16, 17), 16) & 0x3) | 0x8).toString(16)}${hex.slice(17, 20)}`,
|
|
81
|
+
hex.slice(20, 32),
|
|
82
|
+
].join('-');
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A deterministic UUID-shaped id (not a real v4 — the schema only needs a stable string):
|
|
86
|
+
* the first 128 bits of SHA-256(`seed`), no version or variant bits set.
|
|
87
|
+
*
|
|
88
|
+
* Consumer: a Case entry point's `uniqueId` in `entry-points.json` (`case/compile-cli.ts`).
|
|
89
|
+
*/
|
|
90
|
+
export function sha256Uuid(seed) {
|
|
91
|
+
const h = createHash('sha256').update(seed).digest('hex');
|
|
92
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
|
|
93
|
+
}
|
package/dist/serialize.js
CHANGED
|
@@ -23,7 +23,7 @@ import { declaredExits, hasExits } from './core/step-ports.js';
|
|
|
23
23
|
import { stopsAtEnd } from './flow-step-tree.js';
|
|
24
24
|
import { assertNodeEnvelope } from './core/node-envelope.js';
|
|
25
25
|
import { buildConfiguration } from './config.js';
|
|
26
|
-
import { stableId } from './core/stable-id.js';
|
|
26
|
+
import { fnv1aX4Uuid, stableId } from './core/stable-id.js';
|
|
27
27
|
import { readEventFilter, eventFilterProblem, eventFilterJmes, eventFilterTreeLeaf } from './core/event-filters.js';
|
|
28
28
|
import { FLOW_EXPR_DIALECT } from './core/connector-checks.js';
|
|
29
29
|
import { buildConnectorInputs, connectorInputErrors as coreConnectorInputErrors, multipartBodyFieldName, transportHttpMethod } from './core/connector-inputs.js';
|
|
@@ -3429,37 +3429,6 @@ export function serializeWithSidecars(built, opts = {}) {
|
|
|
3429
3429
|
const flow = serialize(built, { ...opts, sidecars });
|
|
3430
3430
|
return { flow, sidecars };
|
|
3431
3431
|
}
|
|
3432
|
-
/**
|
|
3433
|
-
* A deterministic v4-shaped uuid from a string.
|
|
3434
|
-
*
|
|
3435
|
-
* Used for an inline agent's `source` when the author does not pass one. It has to
|
|
3436
|
-
* LOOK like a uuid (the platform treats it as an opaque directory name and the
|
|
3437
|
-
* designer shows it as a folder) and it has to be STABLE, because a random one would
|
|
3438
|
-
* make every recompile a diff of the `.flow` and a rename of a directory. FNV-1a
|
|
3439
|
-
* ×4 with the version/variant nibbles pinned — not a cryptographic hash, and it does
|
|
3440
|
-
* not need to be: the only requirement is that two different (flow, step) pairs do
|
|
3441
|
-
* not collide within one project.
|
|
3442
|
-
*/
|
|
3443
|
-
function stableUuid(seed) {
|
|
3444
|
-
const words = [];
|
|
3445
|
-
for (let i = 0; i < 4; i++) {
|
|
3446
|
-
let h = 0x811c9dc5 ^ (i * 0x9e3779b9);
|
|
3447
|
-
const s = `${seed}#${i}`;
|
|
3448
|
-
for (let j = 0; j < s.length; j++) {
|
|
3449
|
-
h ^= s.charCodeAt(j);
|
|
3450
|
-
h = Math.imul(h, 0x01000193) >>> 0;
|
|
3451
|
-
}
|
|
3452
|
-
words.push(h >>> 0);
|
|
3453
|
-
}
|
|
3454
|
-
const hex = words.map((w) => w.toString(16).padStart(8, '0')).join('');
|
|
3455
|
-
return [
|
|
3456
|
-
hex.slice(0, 8),
|
|
3457
|
-
hex.slice(8, 12),
|
|
3458
|
-
`4${hex.slice(13, 16)}`,
|
|
3459
|
-
`${((parseInt(hex.slice(16, 17), 16) & 0x3) | 0x8).toString(16)}${hex.slice(17, 20)}`,
|
|
3460
|
-
hex.slice(20, 32),
|
|
3461
|
-
].join('-');
|
|
3462
|
-
}
|
|
3463
3432
|
/**
|
|
3464
3433
|
* `variables.nodes` — one entry per node OUTPUT, derived from the nodes we just
|
|
3465
3434
|
* emitted.
|
|
@@ -5081,7 +5050,7 @@ export function serialize(built, opts = {}) {
|
|
|
5081
5050
|
// name rather than random so a recompile is byte-identical — a v4-shaped uuid
|
|
5082
5051
|
// over a stable hash, because the platform treats it as an opaque id and the
|
|
5083
5052
|
// designer shows it as a folder.
|
|
5084
|
-
const source = s.source ??
|
|
5053
|
+
const source = s.source ?? fnv1aX4Uuid(`${built.id}/${step.name}`);
|
|
5085
5054
|
const node = makeNode(def.nodeType, id, step.name, { parentId, requestedVersion: step.options?.version, def });
|
|
5086
5055
|
// Unlike the published families the inline agent KEEPS no node-level model:
|
|
5087
5056
|
// 29 of 29 deployed instances carry none (the def's `model.source: true` is
|
|
@@ -5193,7 +5162,7 @@ export function serialize(built, opts = {}) {
|
|
|
5193
5162
|
// resource's `id` are the same uuid, because that is what joins them. The
|
|
5194
5163
|
// platform validator says so in its own refusal text — *"the resource id
|
|
5195
5164
|
// from the parent inline agent's `resources[]`"*.
|
|
5196
|
-
const contextResourceId =
|
|
5165
|
+
const contextResourceId = fnv1aX4Uuid(`${built.id}/${step.name}/context/${cx.id}`);
|
|
5197
5166
|
const contextQuery = renderContextQuery(cx.query, scope.rename);
|
|
5198
5167
|
cnode.inputs = {
|
|
5199
5168
|
// REQUIRED, and the platform's validator is what says so — measured
|
|
@@ -5407,7 +5376,7 @@ export function serialize(built, opts = {}) {
|
|
|
5407
5376
|
: tr.kind === 'clientside' ? `clientside.${tr.name}`
|
|
5408
5377
|
: tr.kind === 'httpRequest' ? `httprequest.${tr.name ?? 'default'}`
|
|
5409
5378
|
: tr.key;
|
|
5410
|
-
const toolResourceId =
|
|
5379
|
+
const toolResourceId = fnv1aX4Uuid(`${built.id}/${step.name}/tool/${toolSeed}`);
|
|
5411
5380
|
tnode.inputs = {
|
|
5412
5381
|
source: toolResourceId,
|
|
5413
5382
|
...extraInputs,
|
|
@@ -5450,7 +5419,7 @@ export function serialize(built, opts = {}) {
|
|
|
5450
5419
|
type: f.type,
|
|
5451
5420
|
direction: f.direction,
|
|
5452
5421
|
}));
|
|
5453
|
-
const qsource =
|
|
5422
|
+
const qsource = fnv1aX4Uuid(`${built.id}/${step.name}/escalation/${esc.name}`);
|
|
5454
5423
|
qnode.inputs = {
|
|
5455
5424
|
source: qsource,
|
|
5456
5425
|
name: esc.name,
|
|
@@ -5486,7 +5455,7 @@ export function serialize(built, opts = {}) {
|
|
|
5486
5455
|
path: `${source}/resources/${qsource}/resource.json`,
|
|
5487
5456
|
json: escalationResourceJson(esc, {
|
|
5488
5457
|
id: qsource,
|
|
5489
|
-
channelId:
|
|
5458
|
+
channelId: fnv1aX4Uuid(`${built.id}/${step.name}/escalation/${esc.name}/channel`),
|
|
5490
5459
|
quickFormSchema: qnode.inputs.schema,
|
|
5491
5460
|
}),
|
|
5492
5461
|
});
|
|
@@ -5498,7 +5467,7 @@ export function serialize(built, opts = {}) {
|
|
|
5498
5467
|
const enode = makeNode(edef.nodeType, eid, esc.name, { parentId, def: edef });
|
|
5499
5468
|
enode.display = { ...enode.display, shape: 'circle' };
|
|
5500
5469
|
delete enode.model;
|
|
5501
|
-
const esource =
|
|
5470
|
+
const esource = fnv1aX4Uuid(`${built.id}/${step.name}/escalation/${esc.name}`);
|
|
5502
5471
|
enode.inputs = {
|
|
5503
5472
|
source: esource,
|
|
5504
5473
|
name: esc.name,
|
|
@@ -5535,7 +5504,7 @@ export function serialize(built, opts = {}) {
|
|
|
5535
5504
|
path: `${source}/resources/${esource}/resource.json`,
|
|
5536
5505
|
json: escalationResourceJson(esc, {
|
|
5537
5506
|
id: esource,
|
|
5538
|
-
channelId:
|
|
5507
|
+
channelId: fnv1aX4Uuid(`${built.id}/${step.name}/escalation/${esc.name}/channel`),
|
|
5539
5508
|
}),
|
|
5540
5509
|
});
|
|
5541
5510
|
}
|
|
@@ -5549,7 +5518,7 @@ export function serialize(built, opts = {}) {
|
|
|
5549
5518
|
mnode.display = { ...mnode.display, shape: 'circle' };
|
|
5550
5519
|
delete mnode.model;
|
|
5551
5520
|
mnode.inputs = {
|
|
5552
|
-
source:
|
|
5521
|
+
source: fnv1aX4Uuid(`${built.id}/${step.name}/memory/${m.id}`),
|
|
5553
5522
|
name: m.name,
|
|
5554
5523
|
description: m.description ?? '',
|
|
5555
5524
|
dynamicFewShotLearning: m.dynamicFewShotLearning ?? true,
|
|
@@ -5665,7 +5634,7 @@ export function serialize(built, opts = {}) {
|
|
|
5665
5634
|
// lets the platform do that translation.
|
|
5666
5635
|
const s = spec.inputs;
|
|
5667
5636
|
const id = stepUid(scope, step.name);
|
|
5668
|
-
const source = s.source ??
|
|
5637
|
+
const source = s.source ?? fnv1aX4Uuid(`${built.id}/${step.name}`);
|
|
5669
5638
|
const node = makeNode(NODE_TYPE.conversationalAgent, id, step.name, { parentId, requestedVersion: step.options?.version });
|
|
5670
5639
|
delete node.model;
|
|
5671
5640
|
const st = s.settings ?? {};
|
|
@@ -5758,7 +5727,7 @@ export function serialize(built, opts = {}) {
|
|
|
5758
5727
|
// definition declares what comes back.
|
|
5759
5728
|
const s = spec.inputs;
|
|
5760
5729
|
const id = stepUid(scope, step.name);
|
|
5761
|
-
const source = s.source ??
|
|
5730
|
+
const source = s.source ?? fnv1aX4Uuid(`${built.id}/${step.name}`);
|
|
5762
5731
|
const node = makeNode(NODE_TYPE.voiceAgent, id, step.name, { parentId, requestedVersion: step.options?.version });
|
|
5763
5732
|
// Same rule as the inline agent's: the resource model lives on the
|
|
5764
5733
|
// definition (its `model.source: true` is what makes `source` an input).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.16.
|
|
3
|
+
"version": "6.16.8",
|
|
4
4
|
"description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://docs.uipath.com/maestro",
|
|
@@ -92,5 +92,5 @@
|
|
|
92
92
|
"@types/node": "^22.7.0",
|
|
93
93
|
"esbuild": "^0.28.1"
|
|
94
94
|
},
|
|
95
|
-
"gitref": "
|
|
95
|
+
"gitref": "77b292a40160cde6e025bbeb534397e5e930bae1"
|
|
96
96
|
}
|