hierarchical-approval 2.0.0 → 2.1.0

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +34 -0
  3. package/dist/{ApprovalEngine-B8bPZq01.d.ts → ApprovalEngine-CJwnpnpL.d.ts} +52 -7
  4. package/dist/{ApprovalEngine-C7p9cOA3.d.cts → ApprovalEngine-DqRIadYg.d.cts} +52 -7
  5. package/dist/{IAuditAdapter-UJNdJanq.d.cts → IAuditAdapter-BHVKMMv6.d.cts} +1 -1
  6. package/dist/{IAuditAdapter-DDV4Rf9F.d.ts → IAuditAdapter-C4OASS6u.d.ts} +1 -1
  7. package/dist/{IAuthorizationPolicy-CFJ-gXKl.d.ts → IAuthorizationPolicy-BA_m2Dg9.d.ts} +1 -1
  8. package/dist/{IAuthorizationPolicy-CN6LAaKg.d.cts → IAuthorizationPolicy-CtLkwQ8I.d.cts} +1 -1
  9. package/dist/{INotificationAdapter-Dv_MuYwS.d.ts → INotificationAdapter-BdgfUrIn.d.ts} +12 -2
  10. package/dist/{INotificationAdapter-Dy2d0JKy.d.cts → INotificationAdapter-JJAiMyMd.d.cts} +12 -2
  11. package/dist/{IOperationMiddleware-DWYXVuJD.d.ts → IOperationMiddleware-BGYrAqep.d.ts} +1 -1
  12. package/dist/{IOperationMiddleware-DGG-guxK.d.cts → IOperationMiddleware-D0ksiFM3.d.cts} +1 -1
  13. package/dist/{IStorageAdapter-Bgd6p8XL.d.cts → IStorageAdapter-Bk7ybd3z.d.cts} +1 -1
  14. package/dist/{IStorageAdapter-B8aRYeGI.d.ts → IStorageAdapter-DjRvHUF0.d.ts} +1 -1
  15. package/dist/adapters/MemoryAdapter.d.cts +2 -2
  16. package/dist/adapters/MemoryAdapter.d.ts +2 -2
  17. package/dist/adapters/PostgresAdapter.d.cts +2 -2
  18. package/dist/adapters/PostgresAdapter.d.ts +2 -2
  19. package/dist/index.cjs +271 -13
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +8 -8
  22. package/dist/index.d.ts +8 -8
  23. package/dist/index.js +271 -13
  24. package/dist/index.js.map +1 -1
  25. package/dist/{instance-BE0uJmg3.d.cts → instance-DUJY_Axf.d.cts} +41 -3
  26. package/dist/{instance-BE0uJmg3.d.ts → instance-DUJY_Axf.d.ts} +41 -3
  27. package/dist/nestjs.cjs +271 -13
  28. package/dist/nestjs.cjs.map +1 -1
  29. package/dist/nestjs.d.cts +7 -7
  30. package/dist/nestjs.d.ts +7 -7
  31. package/dist/nestjs.js +271 -13
  32. package/dist/nestjs.js.map +1 -1
  33. package/dist/plugins/audit.d.cts +2 -2
  34. package/dist/plugins/audit.d.ts +2 -2
  35. package/dist/plugins/notify.d.cts +2 -2
  36. package/dist/plugins/notify.d.ts +2 -2
  37. package/dist/plugins/resilience.d.cts +3 -3
  38. package/dist/plugins/resilience.d.ts +3 -3
  39. package/dist/plugins/tracing.d.cts +2 -2
  40. package/dist/plugins/tracing.d.ts +2 -2
  41. package/dist/plugins/webhook.d.cts +2 -2
  42. package/dist/plugins/webhook.d.ts +2 -2
  43. package/dist/testing.cjs +271 -13
  44. package/dist/testing.cjs.map +1 -1
  45. package/dist/testing.d.cts +7 -7
  46. package/dist/testing.d.ts +7 -7
  47. package/dist/testing.js +271 -13
  48. package/dist/testing.js.map +1 -1
  49. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,47 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  _Nothing yet._
9
9
 
10
+ ## [2.1.0] - 2026-09-04
11
+
12
+ ### Added — sub-workflows
13
+
14
+ - **A level can delegate to a whole separate approval.** "A capital request over
15
+ 1M needs its own board approval before this purchase order can proceed" could
16
+ only be modelled by flattening the board's chain into the purchase order's —
17
+ duplicating it in every template that needed it, and losing the board approval
18
+ as a thing with its own identity, audit trail and lifecycle.
19
+
20
+ ```ts
21
+ { level: 2, name: 'Board approval', mode: 'any', approvers: [],
22
+ subWorkflow: { templateName: 'BOARD' } }
23
+ ```
24
+
25
+ When the level opens, a child instance is submitted against the named
26
+ template, carrying the parent's document data so the child's own conditions
27
+ see the same document. The parent level stays open, with no approvers of its
28
+ own, until the child finishes.
29
+
30
+ - **An approved child advances the parent; any other terminal outcome rejects
31
+ it.** Rejected, cancelled and expired all collapse into one rejection
32
+ deliberately: a parent that treated a cancelled child as "carry on" would
33
+ advance past a gate nobody cleared.
34
+
35
+ - **Children are spawned outside the parent's optimistic write.** The child's own
36
+ `submit()` reads and writes; nesting that inside the parent's compare-and-set
37
+ would turn a slow child template into spurious version conflicts on the
38
+ decision the user just made. The same applies in reverse when a child returns
39
+ its outcome.
40
+
41
+ - **Nesting is capped at five levels**, and `validateTemplate()` rejects a
42
+ template that would spawn itself, sets both `approvers` and `subWorkflow`
43
+ (whose approvers would never be asked), or names no child template. A
44
+ sub-workflow level is exempt from the "must have at least one approver" rule,
45
+ since its child decides it.
46
+
47
+ New exports: `SubWorkflowConfig`, `SubWorkflowEvent`. `ApprovalInstance` gains
48
+ `parentLevel` and `subWorkflowDepth`; levels gain `childInstanceId` and
49
+ `subWorkflowTemplate`.
50
+
10
51
  ## [2.0.0] - 2026-09-04
11
52
 
12
53
  ### BREAKING — `IStorageAdapter` requires `countInstances`
package/README.md CHANGED
@@ -468,6 +468,40 @@ The sweep is **not atomic**: it reports per-instance failures rather than rollin
468
468
  back. A partial transfer is the useful outcome — the approvals that can move
469
469
  should move, and the ones that cannot are named so a human can look at them.
470
470
 
471
+ ### Sub-workflows
472
+
473
+ A level can delegate to a whole separate approval instead of to a list of
474
+ approvers — "a capital request over 1M needs its own board approval before this
475
+ purchase order can proceed" — without flattening the board's chain into the
476
+ purchase order's:
477
+
478
+ ```ts
479
+ levels: [
480
+ { level: 1, name: 'Manager', approvers: [{ type: 'user', userId: 'mgr' }], mode: 'any' },
481
+ { level: 2, name: 'Board approval', mode: 'any', approvers: [],
482
+ subWorkflow: { templateName: 'BOARD' } },
483
+ { level: 3, name: 'CEO', approvers: [{ type: 'user', userId: 'ceo' }], mode: 'any' },
484
+ ]
485
+ ```
486
+
487
+ When level 2 opens, a child instance is submitted against `BOARD`, carrying the
488
+ parent's document data so the child's own conditions see the same document. The
489
+ parent level stays open, with no approvers of its own, until the child finishes.
490
+
491
+ | Child outcome | Parent |
492
+ |---|---|
493
+ | `approved` | Level approved; the chain advances |
494
+ | `rejected`, `cancelled`, `expired` | Parent rejected |
495
+
496
+ Collapsing the non-approved outcomes into one rejection is deliberate: a parent
497
+ that treated a cancelled child as "carry on" would advance past a gate nobody
498
+ cleared.
499
+
500
+ Children link back via `parentInstanceId` and `parentLevel`, and the level
501
+ records `childInstanceId`. Nesting is allowed up to five levels deep, and
502
+ `validateTemplate()` rejects a template that would spawn itself. Emits
503
+ `approval:subworkflow_started` / `approval:subworkflow_completed`.
504
+
471
505
  ### Attachments
472
506
 
473
507
  Attach supporting evidence — a quote PDF, a signed contract, a screenshot of a
@@ -1,14 +1,14 @@
1
- import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from './IStorageAdapter-B8aRYeGI.js';
2
- import { l as ConditionExpression, p as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, e as ApprovalMode, b as AuditEntry } from './instance-BE0uJmg3.js';
3
- import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-Dv_MuYwS.js';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from './IStorageAdapter-DjRvHUF0.js';
2
+ import { l as ConditionExpression, p as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, e as ApprovalMode, b as AuditEntry } from './instance-DUJY_Axf.js';
3
+ import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-BdgfUrIn.js';
4
4
  import { z } from 'zod';
5
5
  import { L as Logger } from './Logger-BplhlU7l.js';
6
6
  import { C as Clock } from './Clock-3FnOczFJ.js';
7
- import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-DWYXVuJD.js';
8
- import { I as IAuditAdapter } from './IAuditAdapter-DDV4Rf9F.js';
7
+ import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-BGYrAqep.js';
8
+ import { I as IAuditAdapter } from './IAuditAdapter-C4OASS6u.js';
9
9
  import { I as IMetricsAdapter } from './IMetricsAdapter-DWq8IFaf.js';
10
10
  import { I as ISchedulerAdapter } from './ISchedulerAdapter-DKv_QjVN.js';
11
- import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-CFJ-gXKl.js';
11
+ import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-BA_m2Dg9.js';
12
12
 
13
13
  declare const SubmitOptionsSchema: z.ZodObject<{
14
14
  templateName: z.ZodString;
@@ -470,7 +470,18 @@ declare class ApprovalEngine {
470
470
  updateTemplate(config: ApprovalTemplateConfig): Promise<string>;
471
471
  getTemplate(name: string): Promise<ApprovalTemplate>;
472
472
  listTemplates(): Promise<ApprovalTemplate[]>;
473
- submit(raw: SubmitOptions, auditCtx?: AuditContext): Promise<ApprovalInstance>;
473
+ submit(raw: SubmitOptions, auditCtx?: AuditContext,
474
+ /**
475
+ * @internal Set only when the engine spawns a sub-workflow child. Passed at
476
+ * creation rather than stamped afterwards, because the child spawns its own
477
+ * children before any post-submit update could reach it — which is how a
478
+ * grandchild ended up recorded at depth 1.
479
+ */
480
+ link?: {
481
+ parentInstanceId: string;
482
+ parentLevel: number;
483
+ depth: number;
484
+ }): Promise<ApprovalInstance>;
474
485
  approve(instanceId: string, raw: ApproveOptions, auditCtx?: AuditContext): Promise<ApprovalInstance>;
475
486
  reject(instanceId: string, raw: RejectOptions, auditCtx?: AuditContext): Promise<ApprovalInstance>;
476
487
  delegate(instanceId: string, raw: DelegateOptions, auditCtx?: AuditContext): Promise<void>;
@@ -736,6 +747,40 @@ declare class ApprovalEngine {
736
747
  * half-decided quorum level stops pestering the approvers who did their part.
737
748
  */
738
749
  private sendReminder;
750
+ /**
751
+ * Start child approvals for any open level that delegates to a sub-workflow.
752
+ *
753
+ * Run after the parent has been persisted, never inside the same optimistic
754
+ * write: the child's own `submit()` performs its own reads and writes, and
755
+ * nesting them under the parent's compare-and-set would make a slow child
756
+ * template a source of spurious version conflicts on the parent.
757
+ */
758
+ private startSubWorkflows;
759
+ /**
760
+ * Return a finished child's outcome to the parent level that is waiting on it.
761
+ *
762
+ * An approved child approves its parent level and lets the chain advance; any
763
+ * other terminal outcome — rejected, cancelled, expired — rejects the parent,
764
+ * because the approval the parent was waiting for did not happen. Collapsing
765
+ * those into one rejection is deliberate: a parent that treated a cancelled
766
+ * child as "carry on" would advance past a gate nobody cleared.
767
+ */
768
+ private propagateToParent;
769
+ /** Mark a sub-workflow level approved and advance the parent chain. */
770
+ private completeSubWorkflowLevel;
771
+ /** Reject a parent because the child approval it was waiting on did not succeed. */
772
+ private rejectFromSubWorkflow;
773
+ /**
774
+ * Work that must happen after a decision is durably recorded, not inside it.
775
+ *
776
+ * Both branches touch other instances — a newly opened level may spawn a
777
+ * child approval, and a finished instance may be a child that owes its
778
+ * outcome to a parent. Doing either inside the deciding instance's
779
+ * compare-and-set would nest writes under a version guard that knows nothing
780
+ * about them, so a slow child template would surface as a spurious conflict
781
+ * on the decision the user just made.
782
+ */
783
+ private afterDecision;
739
784
  private findNextLevel;
740
785
  private findPreviousLevel;
741
786
  private guardBulkSize;
@@ -1,14 +1,14 @@
1
- import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from './IStorageAdapter-Bgd6p8XL.cjs';
2
- import { l as ConditionExpression, p as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, e as ApprovalMode, b as AuditEntry } from './instance-BE0uJmg3.cjs';
3
- import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-Dy2d0JKy.cjs';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from './IStorageAdapter-Bk7ybd3z.cjs';
2
+ import { l as ConditionExpression, p as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, e as ApprovalMode, b as AuditEntry } from './instance-DUJY_Axf.cjs';
3
+ import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-JJAiMyMd.cjs';
4
4
  import { z } from 'zod';
5
5
  import { L as Logger } from './Logger-BplhlU7l.cjs';
6
6
  import { C as Clock } from './Clock-3FnOczFJ.cjs';
7
- import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-DGG-guxK.cjs';
8
- import { I as IAuditAdapter } from './IAuditAdapter-UJNdJanq.cjs';
7
+ import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-D0ksiFM3.cjs';
8
+ import { I as IAuditAdapter } from './IAuditAdapter-BHVKMMv6.cjs';
9
9
  import { I as IMetricsAdapter } from './IMetricsAdapter-DWq8IFaf.cjs';
10
10
  import { I as ISchedulerAdapter } from './ISchedulerAdapter-DKv_QjVN.cjs';
11
- import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-CN6LAaKg.cjs';
11
+ import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-CtLkwQ8I.cjs';
12
12
 
13
13
  declare const SubmitOptionsSchema: z.ZodObject<{
14
14
  templateName: z.ZodString;
@@ -470,7 +470,18 @@ declare class ApprovalEngine {
470
470
  updateTemplate(config: ApprovalTemplateConfig): Promise<string>;
471
471
  getTemplate(name: string): Promise<ApprovalTemplate>;
472
472
  listTemplates(): Promise<ApprovalTemplate[]>;
473
- submit(raw: SubmitOptions, auditCtx?: AuditContext): Promise<ApprovalInstance>;
473
+ submit(raw: SubmitOptions, auditCtx?: AuditContext,
474
+ /**
475
+ * @internal Set only when the engine spawns a sub-workflow child. Passed at
476
+ * creation rather than stamped afterwards, because the child spawns its own
477
+ * children before any post-submit update could reach it — which is how a
478
+ * grandchild ended up recorded at depth 1.
479
+ */
480
+ link?: {
481
+ parentInstanceId: string;
482
+ parentLevel: number;
483
+ depth: number;
484
+ }): Promise<ApprovalInstance>;
474
485
  approve(instanceId: string, raw: ApproveOptions, auditCtx?: AuditContext): Promise<ApprovalInstance>;
475
486
  reject(instanceId: string, raw: RejectOptions, auditCtx?: AuditContext): Promise<ApprovalInstance>;
476
487
  delegate(instanceId: string, raw: DelegateOptions, auditCtx?: AuditContext): Promise<void>;
@@ -736,6 +747,40 @@ declare class ApprovalEngine {
736
747
  * half-decided quorum level stops pestering the approvers who did their part.
737
748
  */
738
749
  private sendReminder;
750
+ /**
751
+ * Start child approvals for any open level that delegates to a sub-workflow.
752
+ *
753
+ * Run after the parent has been persisted, never inside the same optimistic
754
+ * write: the child's own `submit()` performs its own reads and writes, and
755
+ * nesting them under the parent's compare-and-set would make a slow child
756
+ * template a source of spurious version conflicts on the parent.
757
+ */
758
+ private startSubWorkflows;
759
+ /**
760
+ * Return a finished child's outcome to the parent level that is waiting on it.
761
+ *
762
+ * An approved child approves its parent level and lets the chain advance; any
763
+ * other terminal outcome — rejected, cancelled, expired — rejects the parent,
764
+ * because the approval the parent was waiting for did not happen. Collapsing
765
+ * those into one rejection is deliberate: a parent that treated a cancelled
766
+ * child as "carry on" would advance past a gate nobody cleared.
767
+ */
768
+ private propagateToParent;
769
+ /** Mark a sub-workflow level approved and advance the parent chain. */
770
+ private completeSubWorkflowLevel;
771
+ /** Reject a parent because the child approval it was waiting on did not succeed. */
772
+ private rejectFromSubWorkflow;
773
+ /**
774
+ * Work that must happen after a decision is durably recorded, not inside it.
775
+ *
776
+ * Both branches touch other instances — a newly opened level may spawn a
777
+ * child approval, and a finished instance may be a child that owes its
778
+ * outcome to a parent. Doing either inside the deciding instance's
779
+ * compare-and-set would nest writes under a version guard that knows nothing
780
+ * about them, so a slow child template would surface as a spurious conflict
781
+ * on the decision the user just made.
782
+ */
783
+ private afterDecision;
739
784
  private findNextLevel;
740
785
  private findPreviousLevel;
741
786
  private guardBulkSize;
@@ -1,4 +1,4 @@
1
- import { b as AuditEntry, a as ApprovalInstance } from './instance-BE0uJmg3.cjs';
1
+ import { b as AuditEntry, a as ApprovalInstance } from './instance-DUJY_Axf.cjs';
2
2
 
3
3
  interface IAuditAdapter {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { b as AuditEntry, a as ApprovalInstance } from './instance-BE0uJmg3.js';
1
+ import { b as AuditEntry, a as ApprovalInstance } from './instance-DUJY_Axf.js';
2
2
 
3
3
  interface IAuditAdapter {
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-BE0uJmg3.js';
1
+ import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-DUJY_Axf.js';
2
2
 
3
3
  interface AuthorizationContext {
4
4
  operation: 'submit' | 'approve' | 'reject' | 'delegate' | 'reassign' | 'cancel' | 'escalate' | 'override' | 'resubmit' | 'addComment' | 'updateData' | 'requestInfo' | 'provideInfo' | 'addAttachment' | 'removeAttachment';
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-BE0uJmg3.cjs';
1
+ import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-DUJY_Axf.cjs';
2
2
 
3
3
  interface AuthorizationContext {
4
4
  operation: 'submit' | 'approve' | 'reject' | 'delegate' | 'reassign' | 'cancel' | 'escalate' | 'override' | 'resubmit' | 'addComment' | 'updateData' | 'requestInfo' | 'provideInfo' | 'addAttachment' | 'removeAttachment';
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, b as AuditEntry } from './instance-BE0uJmg3.js';
1
+ import { a as ApprovalInstance, b as AuditEntry } from './instance-DUJY_Axf.js';
2
2
 
3
3
  interface ApprovalEvent {
4
4
  instanceId: string;
@@ -112,6 +112,14 @@ interface AttachmentEvent extends ApprovalEvent {
112
112
  uri: string;
113
113
  level?: number;
114
114
  }
115
+ /** Emitted when a level hands off to a child approval, and when that child returns. */
116
+ interface SubWorkflowEvent extends ApprovalEvent {
117
+ level: number;
118
+ childInstanceId: string;
119
+ childTemplateName: string;
120
+ /** Set on completion: the outcome the child returned. */
121
+ outcome?: 'approved' | 'rejected' | 'cancelled' | 'expired';
122
+ }
115
123
  interface ApprovalEventMap {
116
124
  'approval:submitted': SubmittedEvent;
117
125
  'approval:approved': ApprovedEvent;
@@ -132,6 +140,8 @@ interface ApprovalEventMap {
132
140
  'approval:info_provided': InfoProvidedEvent;
133
141
  'approval:attachment_added': AttachmentEvent;
134
142
  'approval:attachment_removed': AttachmentEvent;
143
+ 'approval:subworkflow_started': SubWorkflowEvent;
144
+ 'approval:subworkflow_completed': SubWorkflowEvent;
135
145
  }
136
146
  type ApprovalEventName = keyof ApprovalEventMap;
137
147
  interface HistoryEntry extends AuditEntry {
@@ -155,4 +165,4 @@ interface INotificationAdapter {
155
165
  notify(event: NotificationEvent): Promise<void>;
156
166
  }
157
167
 
158
- export type { ApprovalEvent as A, CancelledEvent as C, DataUpdatedEvent as D, EscalatedEvent as E, HistoryEntry as H, INotificationAdapter as I, LevelAdvancedEvent as L, NotificationEvent as N, OverriddenEvent as O, ReassignedEvent as R, SlaBreachedEvent as S, ApprovalEventMap as a, ApprovalEventName as b, ApprovedEvent as c, AttachmentEvent as d, DelegatedEvent as e, ExpiredEvent as f, InfoProvidedEvent as g, InfoRequestedEvent as h, RejectedEvent as i, ReminderEvent as j, ResubmittedEvent as k, SubmittedEvent as l };
168
+ export type { ApprovalEvent as A, CancelledEvent as C, DataUpdatedEvent as D, EscalatedEvent as E, HistoryEntry as H, INotificationAdapter as I, LevelAdvancedEvent as L, NotificationEvent as N, OverriddenEvent as O, ReassignedEvent as R, SlaBreachedEvent as S, ApprovalEventMap as a, ApprovalEventName as b, ApprovedEvent as c, AttachmentEvent as d, DelegatedEvent as e, ExpiredEvent as f, InfoProvidedEvent as g, InfoRequestedEvent as h, RejectedEvent as i, ReminderEvent as j, ResubmittedEvent as k, SubWorkflowEvent as l, SubmittedEvent as m };
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, b as AuditEntry } from './instance-BE0uJmg3.cjs';
1
+ import { a as ApprovalInstance, b as AuditEntry } from './instance-DUJY_Axf.cjs';
2
2
 
3
3
  interface ApprovalEvent {
4
4
  instanceId: string;
@@ -112,6 +112,14 @@ interface AttachmentEvent extends ApprovalEvent {
112
112
  uri: string;
113
113
  level?: number;
114
114
  }
115
+ /** Emitted when a level hands off to a child approval, and when that child returns. */
116
+ interface SubWorkflowEvent extends ApprovalEvent {
117
+ level: number;
118
+ childInstanceId: string;
119
+ childTemplateName: string;
120
+ /** Set on completion: the outcome the child returned. */
121
+ outcome?: 'approved' | 'rejected' | 'cancelled' | 'expired';
122
+ }
115
123
  interface ApprovalEventMap {
116
124
  'approval:submitted': SubmittedEvent;
117
125
  'approval:approved': ApprovedEvent;
@@ -132,6 +140,8 @@ interface ApprovalEventMap {
132
140
  'approval:info_provided': InfoProvidedEvent;
133
141
  'approval:attachment_added': AttachmentEvent;
134
142
  'approval:attachment_removed': AttachmentEvent;
143
+ 'approval:subworkflow_started': SubWorkflowEvent;
144
+ 'approval:subworkflow_completed': SubWorkflowEvent;
135
145
  }
136
146
  type ApprovalEventName = keyof ApprovalEventMap;
137
147
  interface HistoryEntry extends AuditEntry {
@@ -155,4 +165,4 @@ interface INotificationAdapter {
155
165
  notify(event: NotificationEvent): Promise<void>;
156
166
  }
157
167
 
158
- export type { ApprovalEvent as A, CancelledEvent as C, DataUpdatedEvent as D, EscalatedEvent as E, HistoryEntry as H, INotificationAdapter as I, LevelAdvancedEvent as L, NotificationEvent as N, OverriddenEvent as O, ReassignedEvent as R, SlaBreachedEvent as S, ApprovalEventMap as a, ApprovalEventName as b, ApprovedEvent as c, AttachmentEvent as d, DelegatedEvent as e, ExpiredEvent as f, InfoProvidedEvent as g, InfoRequestedEvent as h, RejectedEvent as i, ReminderEvent as j, ResubmittedEvent as k, SubmittedEvent as l };
168
+ export type { ApprovalEvent as A, CancelledEvent as C, DataUpdatedEvent as D, EscalatedEvent as E, HistoryEntry as H, INotificationAdapter as I, LevelAdvancedEvent as L, NotificationEvent as N, OverriddenEvent as O, ReassignedEvent as R, SlaBreachedEvent as S, ApprovalEventMap as a, ApprovalEventName as b, ApprovedEvent as c, AttachmentEvent as d, DelegatedEvent as e, ExpiredEvent as f, InfoProvidedEvent as g, InfoRequestedEvent as h, RejectedEvent as i, ReminderEvent as j, ResubmittedEvent as k, SubWorkflowEvent as l, SubmittedEvent as m };
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance } from './instance-BE0uJmg3.js';
1
+ import { a as ApprovalInstance } from './instance-DUJY_Axf.js';
2
2
 
3
3
  declare class ApprovalError extends Error {
4
4
  readonly code: string;
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance } from './instance-BE0uJmg3.cjs';
1
+ import { a as ApprovalInstance } from './instance-DUJY_Axf.cjs';
2
2
 
3
3
  declare class ApprovalError extends Error {
4
4
  readonly code: string;
@@ -1,4 +1,4 @@
1
- import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-BE0uJmg3.cjs';
1
+ import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-DUJY_Axf.cjs';
2
2
 
3
3
  interface PaginationOpts {
4
4
  limit: number;
@@ -1,4 +1,4 @@
1
- import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-BE0uJmg3.js';
1
+ import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-DUJY_Axf.js';
2
2
 
3
3
  interface PaginationOpts {
4
4
  limit: number;
@@ -1,5 +1,5 @@
1
- import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-Bgd6p8XL.cjs';
2
- import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-BE0uJmg3.cjs';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-Bk7ybd3z.cjs';
2
+ import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-DUJY_Axf.cjs';
3
3
 
4
4
  declare class MemoryAdapter implements IStorageAdapter {
5
5
  private templates;
@@ -1,5 +1,5 @@
1
- import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-B8aRYeGI.js';
2
- import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-BE0uJmg3.js';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-DjRvHUF0.js';
2
+ import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-DUJY_Axf.js';
3
3
 
4
4
  declare class MemoryAdapter implements IStorageAdapter {
5
5
  private templates;
@@ -1,7 +1,7 @@
1
1
  import * as tls from 'tls';
2
2
  import * as pg from 'pg';
3
- import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-Bgd6p8XL.cjs';
4
- import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-BE0uJmg3.cjs';
3
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-Bk7ybd3z.cjs';
4
+ import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-DUJY_Axf.cjs';
5
5
 
6
6
  interface PostgresAdapterOptions {
7
7
  connectionString?: string;
@@ -1,7 +1,7 @@
1
1
  import * as tls from 'tls';
2
2
  import * as pg from 'pg';
3
- import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-B8aRYeGI.js';
4
- import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-BE0uJmg3.js';
3
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-DjRvHUF0.js';
4
+ import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-DUJY_Axf.js';
5
5
 
6
6
  interface PostgresAdapterOptions {
7
7
  connectionString?: string;