@uipath/maestro-builder-sdk 6.18.5 → 6.18.7
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/check-cli.js +9 -5
- package/dist/case/check.d.ts +5 -3
- package/dist/case/check.js +17 -4
- package/dist/case/cli-library.d.ts +6 -3
- package/dist/case/cli-library.js +10 -5
- package/dist/case/compile-cli.js +3 -3
- package/dist/case/serialize.js +41 -27
- package/dist/case/subscription.d.ts +9 -2
- package/dist/case/subscription.js +15 -2
- package/dist/cli/commands/case.js +2 -0
- package/dist/core/binding-messages.d.ts +21 -0
- package/dist/core/binding-messages.js +33 -0
- package/dist/core/connector-checks.js +4 -11
- package/dist/serialize.js +4 -10
- package/package.json +2 -2
package/dist/case/check-cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* check-cli — fast static validation of <Name>.case.ts (no output file).
|
|
4
4
|
*
|
|
5
5
|
* Usage: node --experimental-strip-types check-cli.js <case.ts | BaseName> \
|
|
6
|
-
* [--library <library-json dir>] [--connectors-local <overlay dir>]
|
|
6
|
+
* [--library <library-json dir>] [--connectors-local <overlay dir>] [--bindings <bindings.json>]
|
|
7
7
|
* Exits 0 when clean (warnings allowed), 1 on any error.
|
|
8
8
|
*
|
|
9
9
|
* The library is opened exactly as `compile-cli` opens it (`openCliLibrary`), so
|
|
@@ -14,11 +14,13 @@ import { resolveCaseFile, loadBuiltCase } from './load.js';
|
|
|
14
14
|
import { check } from './check.js';
|
|
15
15
|
import { caseCheckOpts } from './cli-library.js';
|
|
16
16
|
import { openCliLibrary } from '../core/cli-library.js';
|
|
17
|
-
import {
|
|
17
|
+
import { Bindings } from '../core/bindings.js';
|
|
18
|
+
import { defaultBindingsFile } from '../workdir.js';
|
|
19
|
+
import { flagValue, runWhenInvokedDirectly } from '../cli-run.js';
|
|
18
20
|
import { ensureTypeScriptRuntime } from '../node-runtime.js';
|
|
19
21
|
/** Flags that take a value: their argument is never the source positional. */
|
|
20
|
-
const VALUE_FLAGS = new Set(['--library', '--connectors-local']);
|
|
21
|
-
const USAGE = 'usage: check <case.ts | BaseName> [--library <dir>] [--connectors-local <dir>]';
|
|
22
|
+
const VALUE_FLAGS = new Set(['--library', '--connectors-local', '--bindings']);
|
|
23
|
+
const USAGE = 'usage: check <case.ts | BaseName> [--library <dir>] [--connectors-local <dir>] [--bindings <file>]';
|
|
22
24
|
export async function run(argv) {
|
|
23
25
|
if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
|
|
24
26
|
console.error(USAGE);
|
|
@@ -32,7 +34,9 @@ export async function run(argv) {
|
|
|
32
34
|
const file = resolveCaseFile(input);
|
|
33
35
|
ensureTypeScriptRuntime();
|
|
34
36
|
const built = await loadBuiltCase(file);
|
|
35
|
-
|
|
37
|
+
// bindings.json as `case compile` reads it, for the binding-label rules (#1034).
|
|
38
|
+
const bindings = new Bindings(flagValue(argv, '--bindings') ?? defaultBindingsFile());
|
|
39
|
+
const diags = check(built, caseCheckOpts(openCliLibrary(argv), bindings));
|
|
36
40
|
reportDiagnostics(diags);
|
|
37
41
|
for (const d of diags)
|
|
38
42
|
console.error(` ${d.level === 'error' ? '✗' : '⚠'} [${d.code}] ${d.message}`);
|
package/dist/case/check.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { BuiltCase } from './case-sdk.js';
|
|
11
11
|
import { type ConnectorCheckOpts } from '../core/connector-checks.js';
|
|
12
12
|
import type { EventSubscription } from '../core/actions.js';
|
|
13
|
+
import { type EventCheckOpts } from '../core/event-checks.js';
|
|
13
14
|
export interface Diagnostic {
|
|
14
15
|
level: 'error' | 'warning';
|
|
15
16
|
code: string;
|
|
@@ -25,13 +26,14 @@ export interface Diagnostic {
|
|
|
25
26
|
* `compile` actually makes. Case `serialize` resolves the connector operation and
|
|
26
27
|
* the event, and validates a connector task's inputs and resolves its lookups
|
|
27
28
|
* through the shared `buildConnectorInputs` (`connectorInputs`, `lookups`,
|
|
28
|
-
* `resolutions`)
|
|
29
|
-
*
|
|
29
|
+
* `resolutions`), and refuses a connection/folder label bindings.json cannot
|
|
30
|
+
* turn into a resource key (`bindings`, `bindingLabelRefusal`), and refuses an
|
|
31
|
+
* event on an unverified BYOA connection (`eventFacts`, `byoa`).
|
|
30
32
|
*
|
|
31
33
|
* Every hook fails open: without a library, `check` stays a pure function of the
|
|
32
34
|
* built model.
|
|
33
35
|
*/
|
|
34
|
-
export type CaseCheckOpts = Pick<ConnectorCheckOpts, 'connectorResolveError' | 'connectorInputs' | 'lookups' | 'resolutions' | 'schemaReadiness'> & {
|
|
36
|
+
export type CaseCheckOpts = Pick<ConnectorCheckOpts, 'connectorResolveError' | 'connectorInputs' | 'lookups' | 'resolutions' | 'schemaReadiness' | 'bindings'> & Pick<EventCheckOpts, 'eventFacts' | 'byoa'> & {
|
|
35
37
|
/**
|
|
36
38
|
* What Case `compile` would refuse an event subscription with, or `undefined`
|
|
37
39
|
* when it resolves: `EVENT_UNKNOWN` (the event is not in the library, or
|
package/dist/case/check.js
CHANGED
|
@@ -2,7 +2,7 @@ import { types } from '../core/expr.js';
|
|
|
2
2
|
import { authoredCaseVersion, CASE_FORMAT_PROFILE, CASE_SCHEMA_VERSIONS } from './format-profile.js';
|
|
3
3
|
import { schemaVersionRefusal } from '../schema-version.js';
|
|
4
4
|
import { caseJsonPreservation, caseJsonPreservationErrors } from './preserve.js';
|
|
5
|
-
import { EQUALS_EXPR_DIALECT, checkConnectorContract, checkConnectorLookups, checkConnectorSchema, } from '../core/connector-checks.js';
|
|
5
|
+
import { EQUALS_EXPR_DIALECT, checkBindingLabels, checkConnectorContract, checkConnectorLookups, checkConnectorSchema, } from '../core/connector-checks.js';
|
|
6
6
|
import { checkEventResolution } from '../core/event-checks.js';
|
|
7
7
|
import { EXTERNAL_TASK_DESCRIPTOR_CONTRACT } from './external.js';
|
|
8
8
|
const TYPE_NAMES = new Set(Object.values(types));
|
|
@@ -114,6 +114,11 @@ export function check(built, opts = {}) {
|
|
|
114
114
|
message: `Stage "${stage.label}" selectNextStage.objectName must name a Data Fabric entity.`,
|
|
115
115
|
where: stage.label,
|
|
116
116
|
});
|
|
117
|
+
// Its connector's labels resolve through the same `bindingRef` as a
|
|
118
|
+
// connector task's, so they get the same binding-label rules.
|
|
119
|
+
const connector = exit.selectNextStage.connector;
|
|
120
|
+
if (connector)
|
|
121
|
+
checkBindingLabels('select-next-stage connector', connector, opts, (code, message) => diags.push({ level: 'error', code, message, where: stage.label }), { key: connector.connectorKey });
|
|
117
122
|
}
|
|
118
123
|
for (const lane of stage.lanes)
|
|
119
124
|
for (const t of lane) {
|
|
@@ -293,9 +298,17 @@ function checkLibraryConnectors(built, opts, diags) {
|
|
|
293
298
|
const refused = opts.subscriptionError?.(kind, sub);
|
|
294
299
|
if (refused !== undefined)
|
|
295
300
|
diags.push({ level: 'error', code: refused.code, message: `${where}: ${refused.message}`, where: at });
|
|
296
|
-
|
|
297
|
-
// shared event rules
|
|
298
|
-
|
|
301
|
+
checkBindingLabels(where, sub, opts, (code, message) => diags.push({ level: 'error', code, message, where: at }), { key: sub.connector, action: sub.event });
|
|
302
|
+
// From the shared event rules, the two Case compile enforces: a `where` lookup
|
|
303
|
+
// nobody recorded (LOOKUP_UNRESOLVED, a warning) and an unverified BYOA
|
|
304
|
+
// connection (EVENT_BYOA_UNVERIFIED). Only their hooks are passed, so nothing
|
|
305
|
+
// else in them fires.
|
|
306
|
+
checkEventResolution(sub, where, kind, {
|
|
307
|
+
resolutions: opts.resolutions ?? {},
|
|
308
|
+
...(opts.eventFacts ? { eventFacts: opts.eventFacts } : {}),
|
|
309
|
+
...(opts.byoa ? { byoa: opts.byoa } : {}),
|
|
310
|
+
...(opts.bindings ? { bindings: opts.bindings } : {}),
|
|
311
|
+
}, (code, message) => diags.push({ level: 'error', code, message, where: at }), (code, message) => diags.push({ level: 'warning', code, message, where: at }));
|
|
299
312
|
};
|
|
300
313
|
const rules = (conditions, where) => {
|
|
301
314
|
for (const c of conditions)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Library } from '../core/library.js';
|
|
2
|
+
import type { BindingsView } from '../core/binding-messages.js';
|
|
2
3
|
import type { CaseCheckOpts } from './check.js';
|
|
3
4
|
/**
|
|
4
5
|
* Case's check options from a library the CLI already opened, or `{}` without one.
|
|
@@ -7,10 +8,12 @@ import type { CaseCheckOpts } from './check.js';
|
|
|
7
8
|
* the operation and event resolution (the event through `resolveCaseSubscription`,
|
|
8
9
|
* compile's own call), a connector task's field contract and lookups (the
|
|
9
10
|
* `=`-expression validator Case compile runs), and the schema-readiness warnings.
|
|
10
|
-
*
|
|
11
|
-
* `serialize`
|
|
11
|
+
* With `bindings`, the binding-label rules (BINDING_SELF_NAME, BINDING_UNDECLARED),
|
|
12
|
+
* which Case `serialize` enforces through the same `bindingLabelRefusal`, and the
|
|
13
|
+
* BYOA facts and ledger, for the refusal `resolveCaseSubscription` makes.
|
|
12
14
|
*
|
|
13
15
|
* @param library - The library `openCliLibrary` returned, or `undefined`.
|
|
16
|
+
* @param bindings - The project's bindings.json, as compile reads it.
|
|
14
17
|
* @returns The options for Case `check`.
|
|
15
18
|
*/
|
|
16
|
-
export declare function caseCheckOpts(library: Library | undefined): CaseCheckOpts;
|
|
19
|
+
export declare function caseCheckOpts(library: Library | undefined, bindings?: BindingsView): CaseCheckOpts;
|
package/dist/case/cli-library.js
CHANGED
|
@@ -17,21 +17,26 @@ import { EVENT_GENERIC_NO_OBJECT, GenericEventNoObjectError, resolveCaseSubscrip
|
|
|
17
17
|
* the operation and event resolution (the event through `resolveCaseSubscription`,
|
|
18
18
|
* compile's own call), a connector task's field contract and lookups (the
|
|
19
19
|
* `=`-expression validator Case compile runs), and the schema-readiness warnings.
|
|
20
|
-
*
|
|
21
|
-
* `serialize`
|
|
20
|
+
* With `bindings`, the binding-label rules (BINDING_SELF_NAME, BINDING_UNDECLARED),
|
|
21
|
+
* which Case `serialize` enforces through the same `bindingLabelRefusal`, and the
|
|
22
|
+
* BYOA facts and ledger, for the refusal `resolveCaseSubscription` makes.
|
|
22
23
|
*
|
|
23
24
|
* @param library - The library `openCliLibrary` returned, or `undefined`.
|
|
25
|
+
* @param bindings - The project's bindings.json, as compile reads it.
|
|
24
26
|
* @returns The options for Case `check`.
|
|
25
27
|
*/
|
|
26
|
-
export function caseCheckOpts(library) {
|
|
28
|
+
export function caseCheckOpts(library, bindings) {
|
|
27
29
|
if (!library)
|
|
28
|
-
return {};
|
|
29
|
-
const shared = connectorCheckOpts(library);
|
|
30
|
+
return bindings ? { bindings } : {};
|
|
31
|
+
const shared = connectorCheckOpts(library, bindings);
|
|
30
32
|
return {
|
|
33
|
+
...(bindings ? { bindings } : {}),
|
|
31
34
|
connectorResolveError: shared.connectorResolveError,
|
|
32
35
|
connectorInputs: shared.connectorInputs,
|
|
33
36
|
lookups: shared.lookups,
|
|
34
37
|
resolutions: shared.resolutions,
|
|
38
|
+
eventFacts: shared.eventFacts,
|
|
39
|
+
byoa: shared.byoa,
|
|
35
40
|
schemaReadiness: shared.schemaReadiness,
|
|
36
41
|
externalDescriptorError: (kind, d) => {
|
|
37
42
|
let rc;
|
package/dist/case/compile-cli.js
CHANGED
|
@@ -49,7 +49,9 @@ export async function run(argv) {
|
|
|
49
49
|
// which is what the three copies of these lines used to each decide for itself.
|
|
50
50
|
// Opened BEFORE the check pass, which reads the same library (#1014).
|
|
51
51
|
const library = openCliLibrary(argv);
|
|
52
|
-
const
|
|
52
|
+
const bindFile = flagValue(argv, '--bindings') ?? defaultBindingsFile();
|
|
53
|
+
const bindings = new Bindings(bindFile);
|
|
54
|
+
const diags = check(built, caseCheckOpts(library, bindings));
|
|
53
55
|
for (const d of diags)
|
|
54
56
|
console.error(` ${d.level === 'error' ? '✗' : '⚠'} [${d.code}] ${d.message}`);
|
|
55
57
|
// Reported before serialize, so every exit path carries what stderr printed.
|
|
@@ -59,8 +61,6 @@ export async function run(argv) {
|
|
|
59
61
|
console.error(`compile: ${errors.length} error(s); not emitting.`);
|
|
60
62
|
return 1;
|
|
61
63
|
}
|
|
62
|
-
const bindFile = flagValue(argv, '--bindings') ?? defaultBindingsFile();
|
|
63
|
-
const bindings = new Bindings(bindFile);
|
|
64
64
|
let caseplan;
|
|
65
65
|
try {
|
|
66
66
|
caseplan = serialize(built, { library, bindings });
|
package/dist/case/serialize.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { IdGen } from './ids.js';
|
|
12
12
|
import { buildConnectorInputs, nestConnectorBody, transportHttpMethod } from '../core/connector-inputs.js';
|
|
13
13
|
import { EQUALS_EXPR_DIALECT } from '../core/connector-checks.js';
|
|
14
|
+
import { bindingLabelRefusal } from '../core/binding-messages.js';
|
|
14
15
|
import { resolveEventWhere } from '../core/lookups.js';
|
|
15
16
|
import { resolveCaseSubscription } from './subscription.js';
|
|
16
17
|
import { externalDescriptorRefusal } from './external.js';
|
|
@@ -177,12 +178,13 @@ export function serialize(built, opts = {}) {
|
|
|
177
178
|
const context = [];
|
|
178
179
|
if (connector) {
|
|
179
180
|
context.push(io('connectorKey', 'string', { value: connector.connectorKey }));
|
|
180
|
-
const
|
|
181
|
+
const site = { where: 'select-next-stage connector', target: { key: connector.connectorKey } };
|
|
182
|
+
const connection = bindingRef(resolver, connector.connection, 'Connection', 'ConnectionId', `${connector.connectorKey} connection`, { ...site, attribute: 'connection' });
|
|
181
183
|
if (connection) {
|
|
182
184
|
context.push(io('connection', 'string', { value: `=bindings.${connection.id}` }));
|
|
183
185
|
context.push(io('resourceKey', 'string', { value: connection.resourceKey }));
|
|
184
186
|
}
|
|
185
|
-
const folder = bindingRef(resolver, connector.folder, 'Connection', 'folderKey', 'FolderKey');
|
|
187
|
+
const folder = bindingRef(resolver, connector.folder, 'Connection', 'folderKey', 'FolderKey', { ...site, attribute: 'folder' });
|
|
186
188
|
if (folder)
|
|
187
189
|
context.push(io('folderKey', 'string', { value: `=bindings.${folder.id}` }));
|
|
188
190
|
}
|
|
@@ -697,7 +699,7 @@ function emitTriggers(triggers, ids, resolver) {
|
|
|
697
699
|
// placeholder. A subscription resolves through the same library/binding
|
|
698
700
|
// machinery as connector tasks and wait-for-connector bags.
|
|
699
701
|
const bag = t.eventSubscription
|
|
700
|
-
? resolvedSubscriptionBag('trigger', t.eventSubscription, resolver, triggerId)
|
|
702
|
+
? resolvedSubscriptionBag('trigger', t.eventSubscription, resolver, triggerId, `Event trigger "${label}"`)
|
|
701
703
|
: { serviceType: CASE_FORMAT_PROFILE.eventServiceType };
|
|
702
704
|
if (t.eventOutputs?.length) {
|
|
703
705
|
const outputs = t.eventOutputs.map((o) => {
|
|
@@ -836,10 +838,10 @@ function taskData(task, resolver, taskId, stageId, ids) {
|
|
|
836
838
|
return data;
|
|
837
839
|
}
|
|
838
840
|
case 'connector':
|
|
839
|
-
return connectorTaskData(task.connector, resolver, taskId);
|
|
841
|
+
return connectorTaskData(task.connector, resolver, taskId, `Connector task "${task.name}"`);
|
|
840
842
|
case 'external-agent':
|
|
841
843
|
case 'external-workflow':
|
|
842
|
-
return externalTaskData(task.kind, task.external, resolver);
|
|
844
|
+
return externalTaskData(task.kind, task.external, resolver, `${task.kind === 'external-agent' ? 'External Agent' : 'External Workflow'} task "${task.name}"`);
|
|
843
845
|
case 'wait-for-timer': {
|
|
844
846
|
if (task.timer?.duration)
|
|
845
847
|
return { timerType: 'timeDuration', timeDuration: task.timer.duration };
|
|
@@ -852,7 +854,7 @@ function taskData(task, resolver, taskId, stageId, ids) {
|
|
|
852
854
|
case 'wait-for-connector':
|
|
853
855
|
// Floor placeholder (no connector named) = `serviceType` only; naming the
|
|
854
856
|
// connector/operation emits the `context` subscription.
|
|
855
|
-
return waitConnectorBag(task.waitConnector, { alwaysContext: false }, resolver, `${stageId}-${taskId}`);
|
|
857
|
+
return waitConnectorBag(task.waitConnector, { alwaysContext: false }, resolver, `${stageId}-${taskId}`, `Wait-for-connector task "${task.name}"`);
|
|
856
858
|
}
|
|
857
859
|
}
|
|
858
860
|
/**
|
|
@@ -863,9 +865,9 @@ function taskData(task, resolver, taskId, stageId, ids) {
|
|
|
863
865
|
* and empty `inputs`/`outputs`/`bindings`. A *rule* always carries the context —
|
|
864
866
|
* `validate` rejects a bare `uipath` ("connector activity missing").
|
|
865
867
|
*/
|
|
866
|
-
function waitConnectorBag(spec, opts, resolver, elementId) {
|
|
868
|
+
function waitConnectorBag(spec, opts, resolver, elementId, where) {
|
|
867
869
|
if (isResolvedSubscription(spec))
|
|
868
|
-
return resolvedSubscriptionBag('event', spec, resolver, elementId);
|
|
870
|
+
return resolvedSubscriptionBag('event', spec, resolver, elementId, where);
|
|
869
871
|
const bag = { serviceType: CASE_FORMAT_PROFILE.waitConnectorServiceType };
|
|
870
872
|
const named = spec?.connectorKey !== undefined || spec?.operation !== undefined;
|
|
871
873
|
if (opts.alwaysContext || named) {
|
|
@@ -884,19 +886,20 @@ function isResolvedSubscription(spec) {
|
|
|
884
886
|
}
|
|
885
887
|
/** Resolve a Case event/wait subscription into the designer/runtime bag pinned
|
|
886
888
|
* by the archived v1 artifacts. Placeholder bags never enter this path. */
|
|
887
|
-
function resolvedSubscriptionBag(kind, spec, resolver, elementId) {
|
|
889
|
+
function resolvedSubscriptionBag(kind, spec, resolver, elementId, where) {
|
|
888
890
|
if (!resolver.library)
|
|
889
891
|
throw new Error(`${kind === 'trigger' ? 'event trigger' : 'wait-for-connector'} needs the connector library — `
|
|
890
892
|
+ `pass { library } to serialize or use uip maestro case compile --library.`);
|
|
891
|
-
const rc = resolveCaseSubscription(resolver.library, kind, spec);
|
|
893
|
+
const rc = resolveCaseSubscription(resolver.library, kind, spec, { where, bindings: resolver.bindings });
|
|
892
894
|
const op = rc.entry.operation ?? {};
|
|
893
895
|
const context = [io('connectorKey', 'string', { value: rc.connectorKey })];
|
|
894
|
-
const
|
|
896
|
+
const target = { key: spec.connector, action: spec.event };
|
|
897
|
+
const connection = bindingRef(resolver, spec.connection, 'Connection', 'ConnectionId', `${rc.connectorKey} connection`, { attribute: 'connection', where, target });
|
|
895
898
|
if (connection) {
|
|
896
899
|
context.push(io('connection', 'string', { value: `=bindings.${connection.id}` }));
|
|
897
900
|
context.push(io('resourceKey', 'string', { value: connection.resourceKey }));
|
|
898
901
|
}
|
|
899
|
-
const folder = bindingRef(resolver, spec.folder, 'Connection', 'folderKey', 'FolderKey');
|
|
902
|
+
const folder = bindingRef(resolver, spec.folder, 'Connection', 'folderKey', 'FolderKey', { attribute: 'folder', where, target });
|
|
900
903
|
if (folder)
|
|
901
904
|
context.push(io('folderKey', 'string', { value: `=bindings.${folder.id}` }));
|
|
902
905
|
context.push(io('method', 'string', {}), io('path', 'string', {}), io('objectName', 'string', { value: op.objectName ?? spec.event }), io('operation', 'string', { value: op.eventOperation ?? spec.event }), io('metadata', 'json', { body: subscriptionMetadata(rc, op, spec.filters ?? [], elementId) }));
|
|
@@ -1077,7 +1080,7 @@ function emitTaskOutput(o, elementId, ids, seed, resolver) {
|
|
|
1077
1080
|
* the op's output schema. Connection/folder resolve through `bindings` and are
|
|
1078
1081
|
* referenced as `=bindings.<id>`, with the binding entry collected at case root.
|
|
1079
1082
|
*/
|
|
1080
|
-
function connectorTaskData(spec, resolver, elementId) {
|
|
1083
|
+
function connectorTaskData(spec, resolver, elementId, where) {
|
|
1081
1084
|
if (!resolver.library)
|
|
1082
1085
|
throw new Error(`connector task needs the connector library — pass { library } to serialize or use uip maestro case compile --library.`);
|
|
1083
1086
|
const rc = resolver.library.resolve(spec.key, spec.action, spec.version, spec.object);
|
|
@@ -1086,12 +1089,13 @@ function connectorTaskData(spec, resolver, elementId) {
|
|
|
1086
1089
|
io('connectorKey', 'string', { value: rc.connectorKey }),
|
|
1087
1090
|
];
|
|
1088
1091
|
// connection + folder → root bindings, referenced by id.
|
|
1089
|
-
const
|
|
1092
|
+
const target = { key: spec.key, action: spec.action };
|
|
1093
|
+
const connRef = bindingRef(resolver, spec.connection, 'Connection', 'ConnectionId', `${rc.connectorKey} connection`, { attribute: 'connection', where, target });
|
|
1090
1094
|
if (connRef) {
|
|
1091
1095
|
context.push(io('connection', 'string', { value: `=bindings.${connRef.id}` }));
|
|
1092
1096
|
context.push(io('resourceKey', 'string', { value: connRef.resourceKey }));
|
|
1093
1097
|
}
|
|
1094
|
-
const folderRef = bindingRef(resolver, spec.folder, 'Connection', 'folderKey', 'FolderKey');
|
|
1098
|
+
const folderRef = bindingRef(resolver, spec.folder, 'Connection', 'folderKey', 'FolderKey', { attribute: 'folder', where, target });
|
|
1095
1099
|
if (folderRef)
|
|
1096
1100
|
context.push(io('folderKey', 'string', { value: `=bindings.${folderRef.id}` }));
|
|
1097
1101
|
context.push(io('objectName', 'string', { value: op.objectName ?? spec.action }), io('method', 'string', { value: transportHttpMethod(rc.httpMethod) }), io('path', 'string', { value: rc.endpoint }), io('metadata', 'json', { body: connectorMetadata(rc, op) }));
|
|
@@ -1128,7 +1132,7 @@ function connectorTaskData(spec, resolver, elementId) {
|
|
|
1128
1132
|
const outputs = connectorOutputs(rc, elementId, resolver);
|
|
1129
1133
|
return { serviceType: CASE_FORMAT_PROFILE.connectorActivityServiceType, context, inputs, outputs, bindings: [] };
|
|
1130
1134
|
}
|
|
1131
|
-
function externalTaskData(kind, spec, resolver) {
|
|
1135
|
+
function externalTaskData(kind, spec, resolver, where) {
|
|
1132
1136
|
if (!resolver.library)
|
|
1133
1137
|
throw new Error(`${kind} task needs the connector library — pass { library } to serialize or use uip maestro case compile --library.`);
|
|
1134
1138
|
const rc = resolver.library.resolve(spec.connector.key, spec.connector.action, spec.connector.version, spec.connector.object);
|
|
@@ -1137,8 +1141,9 @@ function externalTaskData(kind, spec, resolver) {
|
|
|
1137
1141
|
throw new Error(refused);
|
|
1138
1142
|
if (spec.mode !== 'sync' && spec.mode !== 'async')
|
|
1139
1143
|
throw new Error(`${kind} task mode must be "sync" or "async".`);
|
|
1140
|
-
const
|
|
1141
|
-
const
|
|
1144
|
+
const target = { key: spec.connector.key, action: spec.connector.action };
|
|
1145
|
+
const connection = bindingRef(resolver, spec.connector.connection, 'Connection', 'ConnectionId', `${rc.connectorKey} connection`, { attribute: 'connection', where, target });
|
|
1146
|
+
const folder = bindingRef(resolver, spec.connector.folder, 'Connection', 'folderKey', 'FolderKey', { attribute: 'folder', where, target });
|
|
1142
1147
|
if (!connection || !folder)
|
|
1143
1148
|
throw new Error(`${kind} task requires non-empty connection and folder binding names.`);
|
|
1144
1149
|
const serviceType = kind === 'external-agent'
|
|
@@ -1199,9 +1204,17 @@ function ioSlot(name, bodyObj, elementId) {
|
|
|
1199
1204
|
}
|
|
1200
1205
|
/** Resolve a symbolic connection/folder to a root binding entry (collected once),
|
|
1201
1206
|
* returning its id + resourceKey for the `=bindings.<id>` reference. */
|
|
1202
|
-
function bindingRef(resolver, name, resource, propertyAttribute, displayName) {
|
|
1207
|
+
function bindingRef(resolver, name, resource, propertyAttribute, displayName, site) {
|
|
1203
1208
|
if (!name)
|
|
1204
1209
|
return undefined;
|
|
1210
|
+
// A label compile cannot turn into a resource key: one bindings.json answers
|
|
1211
|
+
// with the label itself, or a populated one does not declare it. Falling back
|
|
1212
|
+
// to the label emitted it as the binding's resourceKey, and the run faulted
|
|
1213
|
+
// with "'Connection' has an invalid GUID value" (#1034). Same refusal, same
|
|
1214
|
+
// text, as Flow compile and every family's check (`bindingLabelRefusal`).
|
|
1215
|
+
const refused = bindingLabelRefusal(resolver.bindings, name, site.attribute, site.where, site.target);
|
|
1216
|
+
if (refused)
|
|
1217
|
+
throw refused;
|
|
1205
1218
|
const entry = resolver.bindings?.entry(name);
|
|
1206
1219
|
const id = entry?.id ?? name;
|
|
1207
1220
|
const resourceKey = entry?.resourceKey ?? entry?.default ?? name;
|
|
@@ -1324,10 +1337,11 @@ function toCamel(s) {
|
|
|
1324
1337
|
return s.replace(/_([a-z0-9])/gi, (_m, c) => String(c).toUpperCase());
|
|
1325
1338
|
}
|
|
1326
1339
|
// ─── Conditions & rules ───────────────────────────────────────────────────────
|
|
1327
|
-
|
|
1328
|
-
|
|
1340
|
+
/** `site` names the condition as Case `check` does (`stage "S" entry`), for refusals. */
|
|
1341
|
+
function emitRules(rules, seed, ownerId, ids, resolver, site) {
|
|
1342
|
+
return rules.map((group, gi) => group.map((r, ri) => emitRule(r, `${seed}:${gi}:${ri}`, ownerId, ids, resolver, site)));
|
|
1329
1343
|
}
|
|
1330
|
-
function emitRule(r, seed, ownerId, ids, resolver) {
|
|
1344
|
+
function emitRule(r, seed, ownerId, ids, resolver, site) {
|
|
1331
1345
|
const ruleId = ids.ruleId(seed);
|
|
1332
1346
|
const out = { rule: r.rule, id: ruleId };
|
|
1333
1347
|
if (r.rule === 'selected-stage-completed' || r.rule === 'selected-stage-exited') {
|
|
@@ -1347,7 +1361,7 @@ function emitRule(r, seed, ownerId, ids, resolver) {
|
|
|
1347
1361
|
}
|
|
1348
1362
|
if (r.rule === 'wait-for-connector') {
|
|
1349
1363
|
// A rule always carries the subscription under `uipath` (placeholder-safe).
|
|
1350
|
-
out[CASE_FORMAT_PROFILE.waitConnectorRuleBagField] = waitConnectorBag(r.connector, { alwaysContext: true }, resolver, `${ownerId}-${ruleId}`);
|
|
1364
|
+
out[CASE_FORMAT_PROFILE.waitConnectorRuleBagField] = waitConnectorBag(r.connector, { alwaysContext: true }, resolver, `${ownerId}-${ruleId}`, `wait-for-connector rule in ${site}`);
|
|
1351
1365
|
}
|
|
1352
1366
|
if (r.rule === 'sla-status-change') {
|
|
1353
1367
|
// Resolve the SLA (and, for at-risk, the escalation) by displayName → the
|
|
@@ -1371,7 +1385,7 @@ function emitEntry(c, seed, ownerId, label, ids, resolver) {
|
|
|
1371
1385
|
const out = {
|
|
1372
1386
|
id: ids.conditionId(seed),
|
|
1373
1387
|
displayName: resolver.conditionName(c.displayName, `${label} entry`),
|
|
1374
|
-
rules: emitRules(c.rules, seed, ownerId, ids, resolver),
|
|
1388
|
+
rules: emitRules(c.rules, seed, ownerId, ids, resolver, `stage "${label}" entry`),
|
|
1375
1389
|
};
|
|
1376
1390
|
if (c.isInterrupting !== undefined)
|
|
1377
1391
|
out.isInterrupting = c.isInterrupting;
|
|
@@ -1381,7 +1395,7 @@ function emitExit(c, seed, ownerId, label, ids, resolver) {
|
|
|
1381
1395
|
const out = {
|
|
1382
1396
|
id: ids.conditionId(seed),
|
|
1383
1397
|
displayName: resolver.conditionName(c.displayName, `${label} ${c.marksStageComplete ? 'complete' : 'exit'}`),
|
|
1384
|
-
rules: emitRules(c.rules, seed, ownerId, ids, resolver),
|
|
1398
|
+
rules: emitRules(c.rules, seed, ownerId, ids, resolver, `stage "${label}" exit`),
|
|
1385
1399
|
};
|
|
1386
1400
|
if (c.marksStageComplete !== undefined)
|
|
1387
1401
|
out.marksStageComplete = c.marksStageComplete;
|
|
@@ -1399,7 +1413,7 @@ function emitTaskEntry(c, seed, ownerId, label, ids, resolver) {
|
|
|
1399
1413
|
return {
|
|
1400
1414
|
id: ids.conditionId(seed),
|
|
1401
1415
|
displayName: resolver.conditionName(c.displayName, `${label} entry`),
|
|
1402
|
-
rules: emitRules(c.rules, seed, ownerId, ids, resolver),
|
|
1416
|
+
rules: emitRules(c.rules, seed, ownerId, ids, resolver, `task "${label}" entry`),
|
|
1403
1417
|
};
|
|
1404
1418
|
}
|
|
1405
1419
|
function emitCaseExit(c, i, ids, resolver) {
|
|
@@ -1407,7 +1421,7 @@ function emitCaseExit(c, i, ids, resolver) {
|
|
|
1407
1421
|
const out = {
|
|
1408
1422
|
id: ids.conditionId(seed),
|
|
1409
1423
|
displayName: resolver.conditionName(c.displayName, 'Case complete'),
|
|
1410
|
-
rules: emitRules(c.rules, seed, 'root', ids, resolver),
|
|
1424
|
+
rules: emitRules(c.rules, seed, 'root', ids, resolver, 'case exit'),
|
|
1411
1425
|
};
|
|
1412
1426
|
if (c.marksCaseComplete !== undefined)
|
|
1413
1427
|
out.marksCaseComplete = c.marksCaseComplete;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import type { EventSubscription } from '../core/actions.js';
|
|
12
12
|
import type { Library, ResolvedConnector } from '../core/library.js';
|
|
13
|
+
import type { BindingsView } from '../core/binding-messages.js';
|
|
13
14
|
/** Check's code for {@link GenericEventNoObjectError}; Flow and BPMN `check` use the same one. */
|
|
14
15
|
export declare const EVENT_GENERIC_NO_OBJECT = "EVENT_GENERIC_NO_OBJECT";
|
|
15
16
|
/** A GENERIC event subscription that names no object. */
|
|
@@ -24,7 +25,13 @@ export declare class GenericEventNoObjectError extends Error {
|
|
|
24
25
|
* @param library - The connector library.
|
|
25
26
|
* @param kind - `trigger` for an event trigger, `event` for a wait-for-connector task or rule.
|
|
26
27
|
* @param sub - The authored subscription.
|
|
28
|
+
* @param byoa - Where the subscription is and the bindings, to refuse an
|
|
29
|
+
* unverified BYOA connection; compile passes it, `check` does not (it reports
|
|
30
|
+
* that rule from the shared event rules).
|
|
27
31
|
* @returns The resolved event.
|
|
28
|
-
* @throws What `resolveEvent` throws,
|
|
32
|
+
* @throws What `resolveEvent` throws, {@link GenericEventNoObjectError}, or a `ByoaRefusal`.
|
|
29
33
|
*/
|
|
30
|
-
export declare function resolveCaseSubscription(library: Library, kind: 'trigger' | 'event', sub: EventSubscription
|
|
34
|
+
export declare function resolveCaseSubscription(library: Library, kind: 'trigger' | 'event', sub: EventSubscription, byoa?: {
|
|
35
|
+
where: string;
|
|
36
|
+
bindings?: BindingsView;
|
|
37
|
+
}): ResolvedConnector;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { genericEventObjectRefusal } from '../core/event-checks.js';
|
|
2
|
+
import { ByoaRefusal, byoaUnverified } from '../core/byoa.js';
|
|
2
3
|
/** Check's code for {@link GenericEventNoObjectError}; Flow and BPMN `check` use the same one. */
|
|
3
4
|
export const EVENT_GENERIC_NO_OBJECT = 'EVENT_GENERIC_NO_OBJECT';
|
|
4
5
|
/** A GENERIC event subscription that names no object. */
|
|
@@ -17,13 +18,25 @@ function caseObjectOption(object) {
|
|
|
17
18
|
* @param library - The connector library.
|
|
18
19
|
* @param kind - `trigger` for an event trigger, `event` for a wait-for-connector task or rule.
|
|
19
20
|
* @param sub - The authored subscription.
|
|
21
|
+
* @param byoa - Where the subscription is and the bindings, to refuse an
|
|
22
|
+
* unverified BYOA connection; compile passes it, `check` does not (it reports
|
|
23
|
+
* that rule from the shared event rules).
|
|
20
24
|
* @returns The resolved event.
|
|
21
|
-
* @throws What `resolveEvent` throws,
|
|
25
|
+
* @throws What `resolveEvent` throws, {@link GenericEventNoObjectError}, or a `ByoaRefusal`.
|
|
22
26
|
*/
|
|
23
|
-
export function resolveCaseSubscription(library, kind, sub) {
|
|
27
|
+
export function resolveCaseSubscription(library, kind, sub, byoa) {
|
|
24
28
|
const rc = library.resolveEvent(kind, sub.connector, sub.event, sub.version, sub.object);
|
|
25
29
|
const noObject = genericEventObjectRefusal(rc, sub, caseObjectOption);
|
|
26
30
|
if (noObject)
|
|
27
31
|
throw new GenericEventNoObjectError(noObject);
|
|
32
|
+
// A BYOA-only event on a connection `prepare` never checked deploys and never
|
|
33
|
+
// fires (#848). Flow's `refuseUnverifiedByoa` rule and text (`byoaUnverified`);
|
|
34
|
+
// Case `check` reports it from the shared event rules (`eventFacts` / `byoa`).
|
|
35
|
+
if (byoa && typeof library.eventFacts === 'function') {
|
|
36
|
+
const object = typeof sub.object === 'string' && sub.object !== '' ? sub.object : undefined;
|
|
37
|
+
const message = byoaUnverified(byoa.where, { connector: sub.connector, event: sub.event, ...(object ? { object } : {}), connection: sub.connection }, library.eventFacts(sub.connector, sub.event, object), library.byoaVerifications, byoa.bindings);
|
|
38
|
+
if (message)
|
|
39
|
+
throw new ByoaRefusal(message);
|
|
40
|
+
}
|
|
28
41
|
return rc;
|
|
29
42
|
}
|
|
@@ -26,6 +26,7 @@ export function registerCaseCommands(program) {
|
|
|
26
26
|
// check-cli sees argv.
|
|
27
27
|
.option('--library <dir>', 'connector library directory')
|
|
28
28
|
.option('--connectors-local <dir>', 'connection-resolved connector overlay')
|
|
29
|
+
.option('--bindings <file>', 'bindings.json, for the connection/folder label rules')
|
|
29
30
|
.addOption(retiredCompiledOption())
|
|
30
31
|
.action(async (input, options) => {
|
|
31
32
|
let mode;
|
|
@@ -43,6 +44,7 @@ export function registerCaseCommands(program) {
|
|
|
43
44
|
const argv = [input];
|
|
44
45
|
addValue(argv, '--library', options.library);
|
|
45
46
|
addValue(argv, '--connectors-local', options.connectorsLocal);
|
|
47
|
+
addValue(argv, '--bindings', options.bindings);
|
|
46
48
|
await invoke('case check', () => loadTool(import.meta.url, '../../case/check-cli.js'), argv);
|
|
47
49
|
});
|
|
48
50
|
family.command('decompile')
|
|
@@ -43,6 +43,27 @@ export declare function bindingSelfNameMessage(where: string, name: string, attr
|
|
|
43
43
|
* with nothing real to bind is meant to take.
|
|
44
44
|
*/
|
|
45
45
|
export declare function undeclaredBinding(bindings: BindingsView | undefined, name: string): string[] | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* The refusal for one connection/folder label `compile` cannot turn into a
|
|
48
|
+
* resource key, or `undefined` when the label is acceptable.
|
|
49
|
+
*
|
|
50
|
+
* - `BINDING_SELF_NAME`: bindings.json declares the label and answers with the
|
|
51
|
+
* label itself.
|
|
52
|
+
* - `BINDING_UNDECLARED`: a POPULATED bindings.json does not declare it, and it
|
|
53
|
+
* is not a GUID ({@link undeclaredBinding}).
|
|
54
|
+
*
|
|
55
|
+
* Silent without a bindings.json, or with an empty one: offline authoring. One
|
|
56
|
+
* function for every family's `serialize` (which throws the result) and the
|
|
57
|
+
* shared `check` rule (which reports it), so all print the same sentence.
|
|
58
|
+
*
|
|
59
|
+
* @param bindings - The project's bindings.json, if any.
|
|
60
|
+
* @param name - The authored label.
|
|
61
|
+
* @param attribute - Which half of the pair it is.
|
|
62
|
+
* @param where - The site, prefixed to the message.
|
|
63
|
+
* @param target - The connector and operation, for the `prepare` remedy.
|
|
64
|
+
* @returns The refusal, or `undefined`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function bindingLabelRefusal(bindings: BindingsView | undefined, name: string, attribute: 'connection' | 'folder', where: string, target?: PrepareTarget): BindingRefusal | undefined;
|
|
46
67
|
/**
|
|
47
68
|
* The connector and operation a label belongs to, when the call site knows them:
|
|
48
69
|
* a connector step's `key` + `action`, an event's `connector` + `event`. With it
|
|
@@ -58,6 +58,39 @@ export function undeclaredBinding(bindings, name) {
|
|
|
58
58
|
return undefined;
|
|
59
59
|
return declared;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* The refusal for one connection/folder label `compile` cannot turn into a
|
|
63
|
+
* resource key, or `undefined` when the label is acceptable.
|
|
64
|
+
*
|
|
65
|
+
* - `BINDING_SELF_NAME`: bindings.json declares the label and answers with the
|
|
66
|
+
* label itself.
|
|
67
|
+
* - `BINDING_UNDECLARED`: a POPULATED bindings.json does not declare it, and it
|
|
68
|
+
* is not a GUID ({@link undeclaredBinding}).
|
|
69
|
+
*
|
|
70
|
+
* Silent without a bindings.json, or with an empty one: offline authoring. One
|
|
71
|
+
* function for every family's `serialize` (which throws the result) and the
|
|
72
|
+
* shared `check` rule (which reports it), so all print the same sentence.
|
|
73
|
+
*
|
|
74
|
+
* @param bindings - The project's bindings.json, if any.
|
|
75
|
+
* @param name - The authored label.
|
|
76
|
+
* @param attribute - Which half of the pair it is.
|
|
77
|
+
* @param where - The site, prefixed to the message.
|
|
78
|
+
* @param target - The connector and operation, for the `prepare` remedy.
|
|
79
|
+
* @returns The refusal, or `undefined`.
|
|
80
|
+
*/
|
|
81
|
+
export function bindingLabelRefusal(bindings, name, attribute, where, target) {
|
|
82
|
+
if (!bindings)
|
|
83
|
+
return undefined;
|
|
84
|
+
const resolved = bindings.resolve(name);
|
|
85
|
+
if (resolved === name)
|
|
86
|
+
return new BindingRefusal('BINDING_SELF_NAME', bindingSelfNameMessage(where, name, attribute, target));
|
|
87
|
+
if (resolved === undefined) {
|
|
88
|
+
const declared = undeclaredBinding(bindings, name);
|
|
89
|
+
if (declared)
|
|
90
|
+
return new BindingRefusal('BINDING_UNDECLARED', bindingUndeclaredMessage(where, name, attribute, declared, target));
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
61
94
|
function prepareFor(target) {
|
|
62
95
|
return prepareCommand(target?.key ?? '<connector-key>', target?.action ?? '<action>');
|
|
63
96
|
}
|
|
@@ -26,7 +26,7 @@ import { isLookupToken, resolvedValue, } from './lookups.js';
|
|
|
26
26
|
import { Expr } from './expr.js';
|
|
27
27
|
import { extractRefs } from './expr-check.js';
|
|
28
28
|
import { prepareCommand, resolveFlagArg } from './cli-spelling.js';
|
|
29
|
-
import {
|
|
29
|
+
import { bindingLabelRefusal, bindingMissingMessage, connectionConnectorConflictMessage, missingBindingLabels, } from './binding-messages.js';
|
|
30
30
|
/**
|
|
31
31
|
* Flow: an input is an {@link Expr} object. A non-literal one is runtime; a
|
|
32
32
|
* literal one (`lit(…)`) carries the constant it was built from.
|
|
@@ -370,16 +370,9 @@ use) {
|
|
|
370
370
|
const name = labels[attribute];
|
|
371
371
|
if (typeof name !== 'string')
|
|
372
372
|
continue;
|
|
373
|
-
const
|
|
374
|
-
if (
|
|
375
|
-
report(
|
|
376
|
-
}
|
|
377
|
-
else if (resolved === undefined) {
|
|
378
|
-
const declared = undeclaredBinding(bindings, name);
|
|
379
|
-
if (declared) {
|
|
380
|
-
report('BINDING_UNDECLARED', bindingUndeclaredMessage(where, name, attribute, declared, target));
|
|
381
|
-
}
|
|
382
|
-
}
|
|
373
|
+
const refused = bindingLabelRefusal(bindings, name, attribute, where, target);
|
|
374
|
+
if (refused)
|
|
375
|
+
report(refused.code, refused.message);
|
|
383
376
|
}
|
|
384
377
|
}
|
|
385
378
|
/**
|
package/dist/serialize.js
CHANGED
|
@@ -18,7 +18,7 @@ import { planContributionBindings } from './core/contribution-bindings.js';
|
|
|
18
18
|
import { definitionHasErrorPort, errorPortRefusal } from './core/error-port.js';
|
|
19
19
|
import { isAnswerField } from './core/hitl-answers.js';
|
|
20
20
|
import { connectionConnectors } from './bindings-v2.js';
|
|
21
|
-
import { BindingRefusal, GUID_RE,
|
|
21
|
+
import { BindingRefusal, GUID_RE, bindingLabelRefusal, bindingMissingMessage, missingBindingLabels } from './core/binding-messages.js';
|
|
22
22
|
import { ByoaRefusal, byoaUnverified } from './core/byoa.js';
|
|
23
23
|
import { genericEventObjectRefusal } from './core/event-checks.js';
|
|
24
24
|
import { OUTCOME_HANDLE_NODE_TYPES, assertHitlExitInvariant, hitlExitModel, hitlExitViolation, outcomeSlug } from './core/hitl-routing.js';
|
|
@@ -3886,16 +3886,10 @@ function requireBindingPair(where, labels, target) {
|
|
|
3886
3886
|
function resolveBinding(opts, name, attribute, where, target) {
|
|
3887
3887
|
if (name === undefined)
|
|
3888
3888
|
return undefined;
|
|
3889
|
+
const refused = bindingLabelRefusal(opts.bindings, name, attribute, where, target);
|
|
3890
|
+
if (refused)
|
|
3891
|
+
throw refused;
|
|
3889
3892
|
const resolved = opts.bindings?.resolve(name);
|
|
3890
|
-
if (resolved === name) {
|
|
3891
|
-
throw new BindingRefusal('BINDING_SELF_NAME', bindingSelfNameMessage(where, name, attribute, target));
|
|
3892
|
-
}
|
|
3893
|
-
if (resolved === undefined) {
|
|
3894
|
-
const declared = undeclaredBinding(opts.bindings, name);
|
|
3895
|
-
if (declared) {
|
|
3896
|
-
throw new BindingRefusal('BINDING_UNDECLARED', bindingUndeclaredMessage(where, name, attribute, declared, target));
|
|
3897
|
-
}
|
|
3898
|
-
}
|
|
3899
3893
|
const value = resolved ?? name;
|
|
3900
3894
|
const reason = connectionStubReason(value);
|
|
3901
3895
|
if (reason !== undefined && opts.warn) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/maestro-builder-sdk",
|
|
3
|
-
"version": "6.18.
|
|
3
|
+
"version": "6.18.7",
|
|
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": "7dffe3f9de6568ee2673c38faa5046eb7c86eb54"
|
|
96
96
|
}
|