@objectstack/plugin-approvals 17.0.0-rc.2 → 17.0.0-rc.4
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/CHANGELOG.md +282 -0
- package/dist/index.d.mts +180 -95
- package/dist/index.d.ts +180 -95
- package/dist/index.js +157 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +155 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -10
package/dist/index.js
CHANGED
|
@@ -1334,13 +1334,15 @@ var init_translations = __esm({
|
|
|
1334
1334
|
// src/index.ts
|
|
1335
1335
|
var index_exports = {};
|
|
1336
1336
|
__export(index_exports, {
|
|
1337
|
+
APPROVAL_REVISE_CORRELATION_PREFIX: () => APPROVAL_REVISE_CORRELATION_PREFIX,
|
|
1337
1338
|
ApprovalService: () => ApprovalService,
|
|
1338
1339
|
ApprovalsServicePlugin: () => ApprovalsServicePlugin,
|
|
1339
1340
|
SysApprovalAction: () => SysApprovalAction,
|
|
1340
1341
|
SysApprovalApprover: () => SysApprovalApprover,
|
|
1341
1342
|
SysApprovalDelegation: () => SysApprovalDelegation,
|
|
1342
1343
|
SysApprovalRequest: () => SysApprovalRequest,
|
|
1343
|
-
registerApprovalNode: () => registerApprovalNode
|
|
1344
|
+
registerApprovalNode: () => registerApprovalNode,
|
|
1345
|
+
registerApprovalReviseNode: () => registerApprovalReviseNode
|
|
1344
1346
|
});
|
|
1345
1347
|
module.exports = __toCommonJS(index_exports);
|
|
1346
1348
|
|
|
@@ -3445,6 +3447,47 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3445
3447
|
);
|
|
3446
3448
|
}
|
|
3447
3449
|
}
|
|
3450
|
+
/**
|
|
3451
|
+
* The run named by a recorded outcome cannot be advanced at all, because no
|
|
3452
|
+
* automation engine in THIS process implements the capability it needs
|
|
3453
|
+
* (#4420). Returns the reason, or `undefined` when the capability is there
|
|
3454
|
+
* and the caller should proceed.
|
|
3455
|
+
*
|
|
3456
|
+
* **Why this is not simply "not our problem".** Approvals is legitimately
|
|
3457
|
+
* usable with no engine attached, and {@link assertRunResumable} deliberately
|
|
3458
|
+
* stays out of the way for that reason. But "no engine is attached" and "no
|
|
3459
|
+
* run is waiting" are different facts, and only the second is benign: a
|
|
3460
|
+
* `flow_run_id` on the row is the request's OWN declaration that a run is
|
|
3461
|
+
* parked on this decision. Deciding it in a process that cannot resume it
|
|
3462
|
+
* reproduces #4420's reported half-state exactly — a durable decision, a
|
|
3463
|
+
* mirrored status field frozen mid-workflow, a flow parked forever — while
|
|
3464
|
+
* the caller is answered HTTP 200. The engine-less composition is the one
|
|
3465
|
+
* path the #4420 fix left silent, because every guard it added hangs off an
|
|
3466
|
+
* engine that is not there.
|
|
3467
|
+
*
|
|
3468
|
+
* **So the outcome stands, but it is never silent.** Rolling the decision
|
|
3469
|
+
* back is not on the table (a human really did decide, and the row is
|
|
3470
|
+
* already durable), and refusing every such call would break the standalone
|
|
3471
|
+
* compositions the pre-flight protects. What is owed is the report: `error`
|
|
3472
|
+
* level per AGENTS.md's durability rule — persisted state and runtime state
|
|
3473
|
+
* disagree and nothing looks broken from the outside — plus a `resumeError`
|
|
3474
|
+
* on the response, so `resumed: false` carries its reason instead of leaving
|
|
3475
|
+
* the caller to guess whether a resume was even attempted.
|
|
3476
|
+
*
|
|
3477
|
+
* Reuses the registered `RESUME_FAILED` code (ADR-0112 ledger) and
|
|
3478
|
+
* {@link serviceResume}'s message shape: the fact being reported — an
|
|
3479
|
+
* outcome recorded whose run did not advance — is the same one, and this
|
|
3480
|
+
* needs no new vocabulary of its own.
|
|
3481
|
+
*/
|
|
3482
|
+
missingRunCapability(runId, requestId, what, capability) {
|
|
3483
|
+
const fn = capability === "resume" ? this.automation?.resume : this.automation?.cancelRun;
|
|
3484
|
+
if (typeof fn === "function") return void 0;
|
|
3485
|
+
this.logger?.error?.(
|
|
3486
|
+
"[approvals] no automation engine to advance the recorded outcome \u2014 the run is stranded",
|
|
3487
|
+
{ request: requestId, run: runId, outcome: what, capability }
|
|
3488
|
+
);
|
|
3489
|
+
return `${capability} of run '${runId}' failed [RESUME_FAILED]: ${what} was recorded on request ${requestId}, but no automation engine in this process can ${capability} its flow run \u2014 the run stays parked and the record's mirrored status will not advance. Compose the automation service in this host, or recall the request to release the record.`;
|
|
3490
|
+
}
|
|
3448
3491
|
/**
|
|
3449
3492
|
* Resume the run behind an outcome that has ALREADY been written down, and
|
|
3450
3493
|
* fail loudly when it cannot be (#4420).
|
|
@@ -3456,12 +3499,17 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3456
3499
|
* everything it catches never reaches a write.
|
|
3457
3500
|
*
|
|
3458
3501
|
* `RESUME_IN_PROGRESS` is the exception — a concurrent resume is already
|
|
3459
|
-
* advancing the run, so the outcome stands and only `resumed` is false.
|
|
3502
|
+
* advancing the run, so the outcome stands and only `resumed` is false. So
|
|
3503
|
+
* is a composition with no engine at all ({@link missingRunCapability}),
|
|
3504
|
+
* which cannot throw without breaking every standalone deployment — it
|
|
3505
|
+
* reports through `resumeError` instead.
|
|
3460
3506
|
*
|
|
3461
3507
|
* @param what - how the recorded outcome reads in the error, e.g.
|
|
3462
3508
|
* `"the approve decision"`.
|
|
3463
3509
|
*/
|
|
3464
3510
|
async resumeRecordedOutcome(runId, requestId, what, signal) {
|
|
3511
|
+
const missing = this.missingRunCapability(runId, requestId, what, "resume");
|
|
3512
|
+
if (missing) return { resumed: false, resumeError: missing };
|
|
3465
3513
|
try {
|
|
3466
3514
|
await this.serviceResume(runId, signal);
|
|
3467
3515
|
return { resumed: true };
|
|
@@ -3504,7 +3552,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3504
3552
|
const result = await this.decideNode(requestId, input, context);
|
|
3505
3553
|
let resumed = false;
|
|
3506
3554
|
let resumeError;
|
|
3507
|
-
if (result.finalized && result.runId
|
|
3555
|
+
if (result.finalized && result.runId) {
|
|
3508
3556
|
const branchLabel = result.decision === "approve" ? import_automation.APPROVAL_BRANCH_LABELS.approve : import_automation.APPROVAL_BRANCH_LABELS.reject;
|
|
3509
3557
|
const outcome = await this.resumeRecordedOutcome(
|
|
3510
3558
|
result.runId,
|
|
@@ -3541,7 +3589,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3541
3589
|
*
|
|
3542
3590
|
* ADR-0044: also valid on the LATEST `returned` request of its run — the
|
|
3543
3591
|
* submitter abandons the revision window instead of resubmitting. The run
|
|
3544
|
-
* is then paused at the revise
|
|
3592
|
+
* is then paused at the revise-window node (no reject edge), so it is
|
|
3545
3593
|
* terminally cancelled via {@link ApprovalResumeSurface.cancelRun} rather
|
|
3546
3594
|
* than resumed.
|
|
3547
3595
|
*/
|
|
@@ -3599,33 +3647,39 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3599
3647
|
let resumed = false;
|
|
3600
3648
|
let resumeError;
|
|
3601
3649
|
if (inReviseWindow) {
|
|
3602
|
-
if (runId
|
|
3650
|
+
if (runId) {
|
|
3651
|
+
resumeError = this.missingRunCapability(runId, requestId, "the recall", "cancelRun");
|
|
3652
|
+
if (!resumeError) {
|
|
3653
|
+
try {
|
|
3654
|
+
await this.automation.cancelRun(runId, `approval request ${requestId} recalled during revision`);
|
|
3655
|
+
} catch (err) {
|
|
3656
|
+
resumeError = err?.message ?? String(err);
|
|
3657
|
+
this.logger?.error?.("[approvals] cancelRun after revise-window recall failed \u2014 the run may be stranded", {
|
|
3658
|
+
request: requestId,
|
|
3659
|
+
run: runId,
|
|
3660
|
+
error: resumeError
|
|
3661
|
+
});
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
} else if (runId) {
|
|
3666
|
+
resumeError = this.missingRunCapability(runId, requestId, "the recall", "resume");
|
|
3667
|
+
if (!resumeError) {
|
|
3603
3668
|
try {
|
|
3604
|
-
await this.
|
|
3669
|
+
await this.serviceResume(runId, {
|
|
3670
|
+
branchLabel: import_automation.APPROVAL_BRANCH_LABELS.reject,
|
|
3671
|
+
output: { decision: "recall", requestId }
|
|
3672
|
+
});
|
|
3673
|
+
resumed = true;
|
|
3605
3674
|
} catch (err) {
|
|
3606
3675
|
resumeError = err?.message ?? String(err);
|
|
3607
|
-
this.logger?.error?.("[approvals]
|
|
3676
|
+
this.logger?.error?.("[approvals] resume after recall failed \u2014 the run may be stranded", {
|
|
3608
3677
|
request: requestId,
|
|
3609
3678
|
run: runId,
|
|
3610
3679
|
error: resumeError
|
|
3611
3680
|
});
|
|
3612
3681
|
}
|
|
3613
3682
|
}
|
|
3614
|
-
} else if (runId && typeof this.automation?.resume === "function") {
|
|
3615
|
-
try {
|
|
3616
|
-
await this.serviceResume(runId, {
|
|
3617
|
-
branchLabel: import_automation.APPROVAL_BRANCH_LABELS.reject,
|
|
3618
|
-
output: { decision: "recall", requestId }
|
|
3619
|
-
});
|
|
3620
|
-
resumed = true;
|
|
3621
|
-
} catch (err) {
|
|
3622
|
-
resumeError = err?.message ?? String(err);
|
|
3623
|
-
this.logger?.error?.("[approvals] resume after recall failed \u2014 the run may be stranded", {
|
|
3624
|
-
request: requestId,
|
|
3625
|
-
run: runId,
|
|
3626
|
-
error: resumeError
|
|
3627
|
-
});
|
|
3628
|
-
}
|
|
3629
3683
|
}
|
|
3630
3684
|
const fresh = await this.readBackRequest(requestId, context);
|
|
3631
3685
|
return { request: fresh, runId, resumed, ...resumeError ? { resumeError } : {} };
|
|
@@ -3635,7 +3689,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3635
3689
|
* ADR-0044 send back for revision. Finalises the pending request as
|
|
3636
3690
|
* `returned` (a third terminal state — approver-initiated rework, distinct
|
|
3637
3691
|
* from submitter-initiated `recalled`) and resumes the owning flow run down
|
|
3638
|
-
* its `revise` edge to
|
|
3692
|
+
* its `revise` edge to the revise window: the record lock (keyed on `pending`)
|
|
3639
3693
|
* releases, the submitter reworks the data, then {@link resubmit}s.
|
|
3640
3694
|
*
|
|
3641
3695
|
* Requires the approval node to declare a `revise` out-edge — validated
|
|
@@ -3710,7 +3764,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3710
3764
|
}
|
|
3711
3765
|
let resumed2 = false;
|
|
3712
3766
|
let resumeError2;
|
|
3713
|
-
if (runId
|
|
3767
|
+
if (runId) {
|
|
3714
3768
|
const outcome = await this.resumeRecordedOutcome(
|
|
3715
3769
|
runId,
|
|
3716
3770
|
requestId,
|
|
@@ -3758,7 +3812,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3758
3812
|
}
|
|
3759
3813
|
let resumed = false;
|
|
3760
3814
|
let resumeError;
|
|
3761
|
-
if (runId
|
|
3815
|
+
if (runId) {
|
|
3762
3816
|
const outcome = await this.resumeRecordedOutcome(
|
|
3763
3817
|
runId,
|
|
3764
3818
|
requestId,
|
|
@@ -3790,7 +3844,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3790
3844
|
/**
|
|
3791
3845
|
* ADR-0044 resubmit after rework. Valid on the LATEST `returned` request of
|
|
3792
3846
|
* its run, submitter-only. Audits `resubmit` on the returned (round-N)
|
|
3793
|
-
* request and resumes the run from the revise
|
|
3847
|
+
* request and resumes the run from the revise-window node; traversal walks
|
|
3794
3848
|
* the declared back-edge into the approval node, whose executor opens the
|
|
3795
3849
|
* round-N+1 request — fresh approver slate, record re-locks.
|
|
3796
3850
|
*/
|
|
@@ -3838,7 +3892,7 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3838
3892
|
}, { context: SYSTEM_CTX2 });
|
|
3839
3893
|
let resumed = false;
|
|
3840
3894
|
let resumeError;
|
|
3841
|
-
if (runId
|
|
3895
|
+
if (runId) {
|
|
3842
3896
|
const outcome = await this.resumeRecordedOutcome(
|
|
3843
3897
|
runId,
|
|
3844
3898
|
requestId,
|
|
@@ -3859,6 +3913,21 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3859
3913
|
* out-edge before send-back is allowed — the engine's branch-label fallback
|
|
3860
3914
|
* (no matching label ⇒ ALL out-edges) must never be reachable from a user
|
|
3861
3915
|
* action.
|
|
3916
|
+
*
|
|
3917
|
+
* Since #3823 it also checks WHAT that edge targets: the revise window must
|
|
3918
|
+
* be an `approval_revise` node, the pause this service owns. ADR-0044 D3
|
|
3919
|
+
* pointed the edge at an ordinary `wait`, which is `resumeAuthority: 'any'`,
|
|
3920
|
+
* so a raw engine resume walked the resubmit back-edge with no submitter
|
|
3921
|
+
* check, no `resubmit` audit row, and — with a pending request colliding on
|
|
3922
|
+
* the record — destroyed the run by consuming the suspension before the
|
|
3923
|
+
* re-entry failed. Refused HERE, before any mutation, for the same reason the
|
|
3924
|
+
* missing-edge check is: a run must never be parked in a revise window that
|
|
3925
|
+
* something other than {@link resubmit} can advance.
|
|
3926
|
+
*
|
|
3927
|
+
* Also refused at authoring time — `flow-approval-revise-target-not-service-owned`
|
|
3928
|
+
* in `@objectstack/lint` gates `os build` / `os validate` / `os lint` and the
|
|
3929
|
+
* runtime metadata publish path — so a flow reaching this check at all is one
|
|
3930
|
+
* published before that gate existed.
|
|
3862
3931
|
*/
|
|
3863
3932
|
async assertReviseEdge(raw, nodeId) {
|
|
3864
3933
|
const processName = String(raw.process_name ?? "");
|
|
@@ -3867,12 +3936,23 @@ var _ApprovalService = class _ApprovalService {
|
|
|
3867
3936
|
throw new Error("VALIDATION_FAILED: send-back requires the owning flow definition (automation engine unavailable)");
|
|
3868
3937
|
}
|
|
3869
3938
|
const flow = await this.automation.getFlow(flowName);
|
|
3870
|
-
const
|
|
3871
|
-
if (
|
|
3939
|
+
const reviseEdges = Array.isArray(flow?.edges) ? flow.edges.filter((e) => e?.source === nodeId && e?.label === import_automation.APPROVAL_BRANCH_LABELS.revise) : [];
|
|
3940
|
+
if (reviseEdges.length === 0) {
|
|
3872
3941
|
throw new Error(
|
|
3873
3942
|
`VALIDATION_FAILED: approval node '${nodeId}' has no '${import_automation.APPROVAL_BRANCH_LABELS.revise}' out-edge \u2014 the flow does not support send-back for revision`
|
|
3874
3943
|
);
|
|
3875
3944
|
}
|
|
3945
|
+
const nodeTypeById = new Map(
|
|
3946
|
+
(Array.isArray(flow?.nodes) ? flow.nodes : []).filter((n) => typeof n?.id === "string").map((n) => [n.id, typeof n.type === "string" ? n.type : ""])
|
|
3947
|
+
);
|
|
3948
|
+
for (const edge of reviseEdges) {
|
|
3949
|
+
const target = typeof edge?.target === "string" ? edge.target : "";
|
|
3950
|
+
const targetType = nodeTypeById.get(target);
|
|
3951
|
+
if (targetType === import_automation.APPROVAL_REVISE_NODE_TYPE) continue;
|
|
3952
|
+
throw new Error(
|
|
3953
|
+
`VALIDATION_FAILED: approval node '${nodeId}' has a '${import_automation.APPROVAL_BRANCH_LABELS.revise}' out-edge into node '${target || "(unknown)"}'` + (targetType === void 0 ? " which the flow does not declare" : ` of type '${targetType || "(untyped)"}'`) + `, but the revise window must be an '${import_automation.APPROVAL_REVISE_NODE_TYPE}' node \u2014 that pause continues only through this service (submitter-only, audited, and refusing a colliding pending request), and any other node type there is resumable by anyone with the run id (amended ADR-0044, #3823). Fix the flow: set node '${target || "<revise target>"}' to type '${import_automation.APPROVAL_REVISE_NODE_TYPE}'.`
|
|
3954
|
+
);
|
|
3955
|
+
}
|
|
3876
3956
|
}
|
|
3877
3957
|
/**
|
|
3878
3958
|
* ADR-0044 guard: a `returned` request is only actionable (resubmit /
|
|
@@ -5604,8 +5684,6 @@ function bindApprovalLockHook(engine, logger) {
|
|
|
5604
5684
|
const changedFields = Object.keys(data).filter((k) => k !== "id" && k !== "updated_at");
|
|
5605
5685
|
if (changedFields.length === 0) return;
|
|
5606
5686
|
if (ctx?.session?.isSystem) return;
|
|
5607
|
-
const roles = ctx?.session?.roles ?? [];
|
|
5608
|
-
if (Array.isArray(roles) && roles.includes("admin")) return;
|
|
5609
5687
|
const gating = await gatingRequests(engine, ctx, object);
|
|
5610
5688
|
if (gating.length === 0) return;
|
|
5611
5689
|
const writerRun = ctx?.provenance?.flowRunId;
|
|
@@ -5627,8 +5705,6 @@ function bindDelegationWriteGuard(engine, logger) {
|
|
|
5627
5705
|
const makeGuard = (isInsert) => async (ctx) => {
|
|
5628
5706
|
const session = ctx?.session ?? {};
|
|
5629
5707
|
if (session.isSystem) return;
|
|
5630
|
-
const roles = session.roles ?? [];
|
|
5631
|
-
if (Array.isArray(roles) && roles.includes("admin")) return;
|
|
5632
5708
|
const userId = session.userId != null ? String(session.userId) : "";
|
|
5633
5709
|
const data = ctx?.input?.data;
|
|
5634
5710
|
const rows = Array.isArray(data) ? data : data && typeof data === "object" ? [data] : [];
|
|
@@ -5661,7 +5737,46 @@ function unbindAllHooks(engine) {
|
|
|
5661
5737
|
}
|
|
5662
5738
|
|
|
5663
5739
|
// src/approval-node.ts
|
|
5740
|
+
var import_automation3 = require("@objectstack/spec/automation");
|
|
5741
|
+
|
|
5742
|
+
// src/approval-revise-node.ts
|
|
5664
5743
|
var import_automation2 = require("@objectstack/spec/automation");
|
|
5744
|
+
var APPROVAL_REVISE_CORRELATION_PREFIX = "approval_revise:";
|
|
5745
|
+
function registerApprovalReviseNode(automation, logger) {
|
|
5746
|
+
automation.registerNodeExecutor({
|
|
5747
|
+
type: import_automation2.APPROVAL_REVISE_NODE_TYPE,
|
|
5748
|
+
descriptor: (0, import_automation2.defineActionDescriptor)({
|
|
5749
|
+
type: import_automation2.APPROVAL_REVISE_NODE_TYPE,
|
|
5750
|
+
version: "1.0.0",
|
|
5751
|
+
name: "Revise Window",
|
|
5752
|
+
description: "Durable pause an approval send-back parks the run on while the submitter reworks the record. Continues only through the approvals service (resubmit), which re-enters the approval node over the declared back-edge.",
|
|
5753
|
+
icon: "pencil",
|
|
5754
|
+
// Waits on a human — the same category as `approval` and `screen`.
|
|
5755
|
+
category: "human",
|
|
5756
|
+
paradigms: ["flow"],
|
|
5757
|
+
source: "plugin",
|
|
5758
|
+
supportsPause: true,
|
|
5759
|
+
isAsync: true,
|
|
5760
|
+
// #3823 / amended ADR-0044: THE point of this node type. The revise
|
|
5761
|
+
// window is a service-owned continuation, so the #3801 gate must refuse
|
|
5762
|
+
// a raw resume of it — which it does for any node type declaring this.
|
|
5763
|
+
resumeAuthority: "service"
|
|
5764
|
+
// No config: the window is pure position in the graph. Left schemaless
|
|
5765
|
+
// (like `wait` / `subflow` / `decision`) rather than declaring an empty
|
|
5766
|
+
// object, so nothing invents an authorable surface that has no reader.
|
|
5767
|
+
}),
|
|
5768
|
+
async execute(node) {
|
|
5769
|
+
return {
|
|
5770
|
+
success: true,
|
|
5771
|
+
suspend: true,
|
|
5772
|
+
correlation: `${APPROVAL_REVISE_CORRELATION_PREFIX}${node.id}`
|
|
5773
|
+
};
|
|
5774
|
+
}
|
|
5775
|
+
});
|
|
5776
|
+
logger?.info?.("[approvals] approval revise-window node executor registered");
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5779
|
+
// src/approval-node.ts
|
|
5665
5780
|
var SYSTEM_CTX4 = { isSystem: true, positions: [], permissions: [] };
|
|
5666
5781
|
function nestVariables(variables) {
|
|
5667
5782
|
const vars = {};
|
|
@@ -5679,10 +5794,11 @@ function nestVariables(variables) {
|
|
|
5679
5794
|
return vars;
|
|
5680
5795
|
}
|
|
5681
5796
|
function registerApprovalNode(automation, service, logger) {
|
|
5797
|
+
registerApprovalReviseNode(automation, logger);
|
|
5682
5798
|
automation.registerNodeExecutor({
|
|
5683
|
-
type:
|
|
5684
|
-
descriptor: (0,
|
|
5685
|
-
type:
|
|
5799
|
+
type: import_automation3.APPROVAL_NODE_TYPE,
|
|
5800
|
+
descriptor: (0, import_automation3.defineActionDescriptor)({
|
|
5801
|
+
type: import_automation3.APPROVAL_NODE_TYPE,
|
|
5686
5802
|
version: "1.0.0",
|
|
5687
5803
|
name: "Approval",
|
|
5688
5804
|
description: "Route a record for human approval; suspends the flow until a decision, then continues down the approve / reject branch.",
|
|
@@ -5705,10 +5821,10 @@ function registerApprovalNode(automation, service, logger) {
|
|
|
5705
5821
|
// Publish the node's config contract (ADR-0018 §configSchema) so the
|
|
5706
5822
|
// Studio flow designer renders the Approval property form from the engine
|
|
5707
5823
|
// rather than a hardcoded client form — the engine owns the shape.
|
|
5708
|
-
configSchema: (0,
|
|
5824
|
+
configSchema: (0, import_automation3.getApprovalNodeConfigJsonSchema)()
|
|
5709
5825
|
}),
|
|
5710
5826
|
async execute(node, variables, context) {
|
|
5711
|
-
const parsed =
|
|
5827
|
+
const parsed = import_automation3.ApprovalNodeConfigSchema.safeParse(node.config ?? {});
|
|
5712
5828
|
if (!parsed.success) {
|
|
5713
5829
|
const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
5714
5830
|
return { success: false, error: `Approval node '${node.id}' has invalid config: ${msg}` };
|
|
@@ -6000,12 +6116,14 @@ var ApprovalsServicePlugin = class {
|
|
|
6000
6116
|
};
|
|
6001
6117
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6002
6118
|
0 && (module.exports = {
|
|
6119
|
+
APPROVAL_REVISE_CORRELATION_PREFIX,
|
|
6003
6120
|
ApprovalService,
|
|
6004
6121
|
ApprovalsServicePlugin,
|
|
6005
6122
|
SysApprovalAction,
|
|
6006
6123
|
SysApprovalApprover,
|
|
6007
6124
|
SysApprovalDelegation,
|
|
6008
6125
|
SysApprovalRequest,
|
|
6009
|
-
registerApprovalNode
|
|
6126
|
+
registerApprovalNode,
|
|
6127
|
+
registerApprovalReviseNode
|
|
6010
6128
|
});
|
|
6011
6129
|
//# sourceMappingURL=index.js.map
|