@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.
@@ -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 ?? stableUuid(`entrypoint:${n.id}`),
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);
@@ -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;
@@ -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 ?? stableUuid(`${built.id}/${step.name}`);
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 = stableUuid(`${built.id}/${step.name}/context/${cx.id}`);
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 = stableUuid(`${built.id}/${step.name}/tool/${toolSeed}`);
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 = stableUuid(`${built.id}/${step.name}/escalation/${esc.name}`);
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: stableUuid(`${built.id}/${step.name}/escalation/${esc.name}/channel`),
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 = stableUuid(`${built.id}/${step.name}/escalation/${esc.name}`);
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: stableUuid(`${built.id}/${step.name}/escalation/${esc.name}/channel`),
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: stableUuid(`${built.id}/${step.name}/memory/${m.id}`),
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 ?? stableUuid(`${built.id}/${step.name}`);
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 ?? stableUuid(`${built.id}/${step.name}`);
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.7",
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": "c769835ca295fd52b2f51584b3e21ef9bb226347"
95
+ "gitref": "77b292a40160cde6e025bbeb534397e5e930bae1"
96
96
  }