hierarchical-approval 4.0.5 → 4.0.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/{ApprovalEngine-BaJ2PNB7.d.cts → ApprovalEngine-D5ZplHsw.d.cts} +24 -16
  3. package/dist/{ApprovalEngine-CeBKYLz4.d.ts → ApprovalEngine-sUWBHas4.d.ts} +24 -16
  4. package/dist/{IAuditAdapter-ggCTPf02.d.ts → IAuditAdapter-Bg6e0_ME.d.ts} +1 -1
  5. package/dist/{IAuditAdapter-Dqpkg-Tz.d.cts → IAuditAdapter-Bv7jIph1.d.cts} +1 -1
  6. package/dist/{IAuthorizationPolicy-D5mAFBTC.d.cts → IAuthorizationPolicy-D0Phw1c_.d.cts} +1 -1
  7. package/dist/{IAuthorizationPolicy-BUHKvalu.d.ts → IAuthorizationPolicy-abLdaLzR.d.ts} +1 -1
  8. package/dist/{IMetricsAdapter-WROxYSXd.d.cts → IMetricsAdapter-DN9rYsoq.d.cts} +1 -0
  9. package/dist/{IMetricsAdapter-WROxYSXd.d.ts → IMetricsAdapter-DN9rYsoq.d.ts} +1 -0
  10. package/dist/{INotificationAdapter-B_9JFH1i.d.ts → INotificationAdapter-D_b-H3bB.d.ts} +17 -1
  11. package/dist/{INotificationAdapter-D9IOl9G_.d.cts → INotificationAdapter-rBeUKnBa.d.cts} +17 -1
  12. package/dist/{IOperationMiddleware-C-N8MpHV.d.ts → IOperationMiddleware-BuRYpQdL.d.ts} +2 -1
  13. package/dist/{IOperationMiddleware-CsF_xD4b.d.cts → IOperationMiddleware-RGAqQ31Q.d.cts} +2 -1
  14. package/dist/{IStorageAdapter-CrbVtEE-.d.cts → IStorageAdapter-Bje_7c62.d.ts} +16 -1
  15. package/dist/{IStorageAdapter-DDOW9z0L.d.ts → IStorageAdapter-DYFj85oL.d.cts} +16 -1
  16. package/dist/adapters/MemoryAdapter.d.cts +2 -2
  17. package/dist/adapters/MemoryAdapter.d.ts +2 -2
  18. package/dist/adapters/PostgresAdapter.cjs.map +1 -1
  19. package/dist/adapters/PostgresAdapter.d.cts +3 -2
  20. package/dist/adapters/PostgresAdapter.d.ts +3 -2
  21. package/dist/adapters/PostgresAdapter.js.map +1 -1
  22. package/dist/index.cjs +22 -18
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +9 -9
  25. package/dist/index.d.ts +9 -9
  26. package/dist/index.js +22 -18
  27. package/dist/index.js.map +1 -1
  28. package/dist/{instance-Cu6-qPxs.d.cts → instance-Du-TGRH_.d.cts} +26 -5
  29. package/dist/{instance-Cu6-qPxs.d.ts → instance-Du-TGRH_.d.ts} +26 -5
  30. package/dist/nestjs.cjs +22 -18
  31. package/dist/nestjs.cjs.map +1 -1
  32. package/dist/nestjs.d.cts +8 -8
  33. package/dist/nestjs.d.ts +8 -8
  34. package/dist/nestjs.js +22 -18
  35. package/dist/nestjs.js.map +1 -1
  36. package/dist/plugins/audit.d.cts +2 -2
  37. package/dist/plugins/audit.d.ts +2 -2
  38. package/dist/plugins/metrics.d.cts +1 -1
  39. package/dist/plugins/metrics.d.ts +1 -1
  40. package/dist/plugins/notify.d.cts +2 -2
  41. package/dist/plugins/notify.d.ts +2 -2
  42. package/dist/plugins/resilience.cjs +1 -1
  43. package/dist/plugins/resilience.cjs.map +1 -1
  44. package/dist/plugins/resilience.d.cts +3 -3
  45. package/dist/plugins/resilience.d.ts +3 -3
  46. package/dist/plugins/resilience.js +1 -1
  47. package/dist/plugins/resilience.js.map +1 -1
  48. package/dist/plugins/tracing.cjs.map +1 -1
  49. package/dist/plugins/tracing.d.cts +9 -2
  50. package/dist/plugins/tracing.d.ts +9 -2
  51. package/dist/plugins/tracing.js.map +1 -1
  52. package/dist/plugins/webhook.d.cts +2 -2
  53. package/dist/plugins/webhook.d.ts +2 -2
  54. package/dist/testing.cjs +22 -18
  55. package/dist/testing.cjs.map +1 -1
  56. package/dist/testing.d.cts +8 -8
  57. package/dist/testing.d.ts +8 -8
  58. package/dist/testing.js +22 -18
  59. package/dist/testing.js.map +1 -1
  60. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [4.0.7] - 2026-09-28
9
+
10
+ ### Fixed
11
+
12
+ - `RbacAuthorizationPolicy`'s roleProvider-failure denial message now names
13
+ the offending actor id, instead of a message that gave no clue which actor
14
+ triggered the fail-closed denial.
15
+ - `ImportResult` and `PreviewResult`'s array fields are now typed as
16
+ `readonly T[]`, not just `readonly` properties holding a mutable array —
17
+ callers could previously still `push`/`splice` the returned arrays in
18
+ place even though the property itself couldn't be reassigned.
19
+
20
+ ## [4.0.6] - 2026-09-26
21
+
22
+ ### Fixed
23
+
24
+ - `LevelResolver.resolveApprovers`'s empty-result error now names how many
25
+ approver configs were attempted, instead of a message that gave no clue
26
+ whether the level was misconfigured or its role/resolver simply had no
27
+ members.
28
+ - `transferApprovals`'s same-approver guard now names the offending id,
29
+ instead of a message that gave no clue which approver was passed twice.
30
+
8
31
  ## [4.0.5] - 2026-09-25
9
32
 
10
33
  ### Fixed
@@ -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-CrbVtEE-.cjs';
2
- import { m as ConditionExpression, r as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, C as Comment, e as ApprovalMode, f as ApprovalStatus, L as LevelStatus, b as AuditEntry } from './instance-Cu6-qPxs.cjs';
3
- import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-D9IOl9G_.cjs';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from './IStorageAdapter-DYFj85oL.cjs';
2
+ import { m as ConditionExpression, r as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, C as Comment, e as ApprovalMode, f as ApprovalStatus, L as LevelStatus, b as AuditEntry } from './instance-Du-TGRH_.cjs';
3
+ import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-rBeUKnBa.cjs';
4
4
  import { z } from 'zod';
5
5
  import { L as Logger } from './Logger-hqFbBCtB.cjs';
6
6
  import { C as Clock } from './Clock-D8Qp39q_.cjs';
7
- import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-CsF_xD4b.cjs';
8
- import { I as IAuditAdapter } from './IAuditAdapter-Dqpkg-Tz.cjs';
9
- import { I as IMetricsAdapter } from './IMetricsAdapter-WROxYSXd.cjs';
7
+ import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-RGAqQ31Q.cjs';
8
+ import { I as IAuditAdapter } from './IAuditAdapter-Bv7jIph1.cjs';
9
+ import { I as IMetricsAdapter } from './IMetricsAdapter-DN9rYsoq.cjs';
10
10
  import { I as ISchedulerAdapter } from './ISchedulerAdapter-CLMdBA-5.cjs';
11
- import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-D5mAFBTC.cjs';
11
+ import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-D0Phw1c_.cjs';
12
12
 
13
13
  declare const SubmitOptionsSchema: z.ZodObject<{
14
14
  templateName: z.ZodString;
@@ -302,7 +302,7 @@ interface CanApproveResult {
302
302
  eligible: boolean;
303
303
  reason?: 'not_an_approver' | 'already_acted' | 'self_approval' | 'wrong_status' | 'delegated_away';
304
304
  }
305
- /** One entry in a {@link ApprovalEngine.preview} result, resolved against the given data without persisting anything. */
305
+ /** One entry in a {@link ApprovalEngine.previewApprovalChain} result, resolved against the given data without persisting anything. */
306
306
  interface PreviewChainLevel {
307
307
  level: number;
308
308
  name: string;
@@ -310,10 +310,12 @@ interface PreviewChainLevel {
310
310
  resolvedApprovers: string[];
311
311
  mode: ApprovalMode;
312
312
  }
313
+ /** Return value of {@link ApprovalEngine.previewApprovalChain}. */
313
314
  interface PreviewResult {
314
- levels: PreviewChainLevel[];
315
+ /** The resolved chain, in level order. */
316
+ readonly levels: readonly PreviewChainLevel[];
315
317
  /** Indices (0-based) of conditions that fired for this data. */
316
- conditionsApplied: number[];
318
+ readonly conditionsApplied: readonly number[];
317
319
  }
318
320
  /** Where one level in an explained chain came from. */
319
321
  interface ExplainedLevel {
@@ -468,14 +470,14 @@ interface TemplateBundle {
468
470
  }
469
471
  /** Outcome of {@link ApprovalEngine.importTemplates}. */
470
472
  interface ImportResult {
471
- created: string[];
472
- updated: string[];
473
- skipped: string[];
474
- errors: Array<{
473
+ readonly created: readonly string[];
474
+ readonly updated: readonly string[];
475
+ readonly skipped: readonly string[];
476
+ readonly errors: readonly Readonly<{
475
477
  name: string;
476
478
  message: string;
477
- }>;
478
- dryRun: boolean;
479
+ }>[];
480
+ readonly dryRun: boolean;
479
481
  }
480
482
  /** Outcome of a {@link ApprovalEngine.purgeInstances} sweep. */
481
483
  interface PurgeResult {
@@ -577,6 +579,7 @@ interface RetryPolicy {
577
579
  }
578
580
  /** Derives the idempotency key used to dedupe a {@link ApprovalEngine.submit} call from its tenant and document identity. */
579
581
  type IdempotencyKeyFn = (tenantId: string, documentType: string, documentId: string, templateName: string, data: Record<string, unknown>) => string;
582
+ /** Constructor options for {@link ApprovalEngine}. Only `adapter` is required. */
580
583
  interface ApprovalEngineOptions {
581
584
  adapter: IStorageAdapter;
582
585
  tenantId?: string;
@@ -631,6 +634,11 @@ interface ApprovalEngineOptions {
631
634
  /** Middleware chain: before/after/onError hooks for every operation. */
632
635
  middleware?: IOperationMiddleware[];
633
636
  }
637
+ /**
638
+ * Runs multi-level approval workflows against a pluggable {@link IStorageAdapter}:
639
+ * submitting instances against a template, resolving and notifying approvers,
640
+ * recording decisions, and driving escalation, expiry and sub-workflows.
641
+ */
634
642
  declare class ApprovalEngine {
635
643
  private readonly opts;
636
644
  private readonly bus;
@@ -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-DDOW9z0L.js';
2
- import { m as ConditionExpression, r as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, C as Comment, e as ApprovalMode, f as ApprovalStatus, L as LevelStatus, b as AuditEntry } from './instance-Cu6-qPxs.js';
3
- import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-B_9JFH1i.js';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from './IStorageAdapter-Bje_7c62.js';
2
+ import { m as ConditionExpression, r as ResolverFn, g as ApprovalTemplateConfig, A as ApprovalTemplate, k as AuditContext, a as ApprovalInstance, C as Comment, e as ApprovalMode, f as ApprovalStatus, L as LevelStatus, b as AuditEntry } from './instance-Du-TGRH_.js';
3
+ import { I as INotificationAdapter, b as ApprovalEventName, a as ApprovalEventMap } from './INotificationAdapter-D_b-H3bB.js';
4
4
  import { z } from 'zod';
5
5
  import { L as Logger } from './Logger-hqFbBCtB.js';
6
6
  import { C as Clock } from './Clock-D8Qp39q_.js';
7
- import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-C-N8MpHV.js';
8
- import { I as IAuditAdapter } from './IAuditAdapter-ggCTPf02.js';
9
- import { I as IMetricsAdapter } from './IMetricsAdapter-WROxYSXd.js';
7
+ import { I as IOperationMiddleware, a as ApprovalError } from './IOperationMiddleware-BuRYpQdL.js';
8
+ import { I as IAuditAdapter } from './IAuditAdapter-Bg6e0_ME.js';
9
+ import { I as IMetricsAdapter } from './IMetricsAdapter-DN9rYsoq.js';
10
10
  import { I as ISchedulerAdapter } from './ISchedulerAdapter-CLMdBA-5.js';
11
- import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-BUHKvalu.js';
11
+ import { I as IAuthorizationPolicy } from './IAuthorizationPolicy-abLdaLzR.js';
12
12
 
13
13
  declare const SubmitOptionsSchema: z.ZodObject<{
14
14
  templateName: z.ZodString;
@@ -302,7 +302,7 @@ interface CanApproveResult {
302
302
  eligible: boolean;
303
303
  reason?: 'not_an_approver' | 'already_acted' | 'self_approval' | 'wrong_status' | 'delegated_away';
304
304
  }
305
- /** One entry in a {@link ApprovalEngine.preview} result, resolved against the given data without persisting anything. */
305
+ /** One entry in a {@link ApprovalEngine.previewApprovalChain} result, resolved against the given data without persisting anything. */
306
306
  interface PreviewChainLevel {
307
307
  level: number;
308
308
  name: string;
@@ -310,10 +310,12 @@ interface PreviewChainLevel {
310
310
  resolvedApprovers: string[];
311
311
  mode: ApprovalMode;
312
312
  }
313
+ /** Return value of {@link ApprovalEngine.previewApprovalChain}. */
313
314
  interface PreviewResult {
314
- levels: PreviewChainLevel[];
315
+ /** The resolved chain, in level order. */
316
+ readonly levels: readonly PreviewChainLevel[];
315
317
  /** Indices (0-based) of conditions that fired for this data. */
316
- conditionsApplied: number[];
318
+ readonly conditionsApplied: readonly number[];
317
319
  }
318
320
  /** Where one level in an explained chain came from. */
319
321
  interface ExplainedLevel {
@@ -468,14 +470,14 @@ interface TemplateBundle {
468
470
  }
469
471
  /** Outcome of {@link ApprovalEngine.importTemplates}. */
470
472
  interface ImportResult {
471
- created: string[];
472
- updated: string[];
473
- skipped: string[];
474
- errors: Array<{
473
+ readonly created: readonly string[];
474
+ readonly updated: readonly string[];
475
+ readonly skipped: readonly string[];
476
+ readonly errors: readonly Readonly<{
475
477
  name: string;
476
478
  message: string;
477
- }>;
478
- dryRun: boolean;
479
+ }>[];
480
+ readonly dryRun: boolean;
479
481
  }
480
482
  /** Outcome of a {@link ApprovalEngine.purgeInstances} sweep. */
481
483
  interface PurgeResult {
@@ -577,6 +579,7 @@ interface RetryPolicy {
577
579
  }
578
580
  /** Derives the idempotency key used to dedupe a {@link ApprovalEngine.submit} call from its tenant and document identity. */
579
581
  type IdempotencyKeyFn = (tenantId: string, documentType: string, documentId: string, templateName: string, data: Record<string, unknown>) => string;
582
+ /** Constructor options for {@link ApprovalEngine}. Only `adapter` is required. */
580
583
  interface ApprovalEngineOptions {
581
584
  adapter: IStorageAdapter;
582
585
  tenantId?: string;
@@ -631,6 +634,11 @@ interface ApprovalEngineOptions {
631
634
  /** Middleware chain: before/after/onError hooks for every operation. */
632
635
  middleware?: IOperationMiddleware[];
633
636
  }
637
+ /**
638
+ * Runs multi-level approval workflows against a pluggable {@link IStorageAdapter}:
639
+ * submitting instances against a template, resolving and notifying approvers,
640
+ * recording decisions, and driving escalation, expiry and sub-workflows.
641
+ */
634
642
  declare class ApprovalEngine {
635
643
  private readonly opts;
636
644
  private readonly bus;
@@ -1,4 +1,4 @@
1
- import { b as AuditEntry, a as ApprovalInstance } from './instance-Cu6-qPxs.js';
1
+ import { b as AuditEntry, a as ApprovalInstance } from './instance-Du-TGRH_.js';
2
2
 
3
3
  /** Secondary write sink for audit entries, alongside the primary storage adapter. */
4
4
  interface IAuditAdapter {
@@ -1,4 +1,4 @@
1
- import { b as AuditEntry, a as ApprovalInstance } from './instance-Cu6-qPxs.cjs';
1
+ import { b as AuditEntry, a as ApprovalInstance } from './instance-Du-TGRH_.cjs';
2
2
 
3
3
  /** Secondary write sink for audit entries, alongside the primary storage adapter. */
4
4
  interface IAuditAdapter {
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-Cu6-qPxs.cjs';
1
+ import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-Du-TGRH_.cjs';
2
2
 
3
3
  interface AuthorizationContext {
4
4
  /** The engine method the actor is attempting to call. */
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-Cu6-qPxs.js';
1
+ import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-Du-TGRH_.js';
2
2
 
3
3
  interface AuthorizationContext {
4
4
  /** The engine method the actor is attempting to call. */
@@ -1,5 +1,6 @@
1
1
  /** Closed set of metric names an {@link IMetricsAdapter} may be called with, namespaced `approval.<verb>`. */
2
2
  type MetricName = 'approval.submitted' | 'approval.approved' | 'approval.rejected' | 'approval.cancelled' | 'approval.expired' | 'approval.sla_breached' | 'approval.escalated' | 'approval.reassigned' | 'approval.overridden' | 'approval.data_updated' | 'approval.reminded' | 'approval.info_requested' | 'approval.info_provided' | 'approval.attachment_added' | 'approval.attachment_removed' | 'approval.conflict_retry' | 'approval.operation_duration_ms';
3
+ /** Sink for engine metrics. Implementations are called synchronously and must not throw. */
3
4
  interface IMetricsAdapter {
4
5
  /** Increment a counter. Synchronous — never awaited. */
5
6
  increment(metric: MetricName, labels?: Record<string, string>): void;
@@ -1,5 +1,6 @@
1
1
  /** Closed set of metric names an {@link IMetricsAdapter} may be called with, namespaced `approval.<verb>`. */
2
2
  type MetricName = 'approval.submitted' | 'approval.approved' | 'approval.rejected' | 'approval.cancelled' | 'approval.expired' | 'approval.sla_breached' | 'approval.escalated' | 'approval.reassigned' | 'approval.overridden' | 'approval.data_updated' | 'approval.reminded' | 'approval.info_requested' | 'approval.info_provided' | 'approval.attachment_added' | 'approval.attachment_removed' | 'approval.conflict_retry' | 'approval.operation_duration_ms';
3
+ /** Sink for engine metrics. Implementations are called synchronously and must not throw. */
3
4
  interface IMetricsAdapter {
4
5
  /** Increment a counter. Synchronous — never awaited. */
5
6
  increment(metric: MetricName, labels?: Record<string, string>): void;
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, b as AuditEntry } from './instance-Cu6-qPxs.js';
1
+ import { a as ApprovalInstance, b as AuditEntry } from './instance-Du-TGRH_.js';
2
2
 
3
3
  /** Common fields carried by every lifecycle event emitted for an approval instance. */
4
4
  interface ApprovalEvent {
@@ -14,6 +14,7 @@ interface ApprovalEvent {
14
14
  /** Emitted as `approval:submitted` when a new instance is raised. */
15
15
  interface SubmittedEvent extends ApprovalEvent {
16
16
  submittedBy: string;
17
+ /** Deduplicated union of every pending level's approvers in the opening group. */
17
18
  currentApprovers: string[];
18
19
  }
19
20
  /** Emitted as `approval:approved` when an approver accepts a level. */
@@ -21,6 +22,7 @@ interface ApprovedEvent extends ApprovalEvent {
21
22
  approverId: string;
22
23
  level: number;
23
24
  comment?: string;
25
+ /** True only when this was the last open branch — the instance is now fully approved. */
24
26
  isFinal: boolean;
25
27
  }
26
28
  /** Emitted as `approval:rejected` when an approver rejects a level. */
@@ -28,6 +30,11 @@ interface RejectedEvent extends ApprovalEvent {
28
30
  approverId: string;
29
31
  level: number;
30
32
  reason: string;
33
+ /**
34
+ * `'previous'` resets the chain to replay from an earlier level — the instance
35
+ * stays `pending`. `'originator'` and `null` are the same terminal outcome: the
36
+ * instance becomes `rejected`; `null` is just what an unset `returnTo` produces.
37
+ */
31
38
  returnTo: 'originator' | 'previous' | null;
32
39
  }
33
40
  /** Emitted as `approval:delegated` when an approver hands their decision to someone else. */
@@ -86,7 +93,9 @@ interface SlaBreachedEvent extends ApprovalEvent {
86
93
  * did not affect it.
87
94
  */
88
95
  interface DataUpdatedEvent extends ApprovalEvent {
96
+ /** Caller-supplied; not checked against the instance's submitter or approvers. */
89
97
  updatedBy: string;
98
+ /** Caller-supplied explanation for the change, if any. */
90
99
  reason?: string;
91
100
  /** Field paths whose values differ after the update. */
92
101
  changedFields: string[];
@@ -97,6 +106,7 @@ interface DataUpdatedEvent extends ApprovalEvent {
97
106
  }
98
107
  /** Emitted when a pending level's approvers are nudged. */
99
108
  interface ReminderEvent extends ApprovalEvent {
109
+ /** The level number being reminded. */
100
110
  level: number;
101
111
  /** Approvers who still owe a decision on this level. */
102
112
  recipients: string[];
@@ -105,8 +115,10 @@ interface ReminderEvent extends ApprovalEvent {
105
115
  }
106
116
  /** Emitted when an approver asks the submitter for clarification. */
107
117
  interface InfoRequestedEvent extends ApprovalEvent {
118
+ /** Must be an approver on `level` — enforced by requestInfo() before this is recorded. */
108
119
  askedBy: string;
109
120
  question: string;
121
+ /** The level `askedBy` was acting on when they asked. */
110
122
  level: number;
111
123
  /** Who is expected to answer — the submitter. */
112
124
  recipients: string[];
@@ -147,6 +159,7 @@ interface CommentedEvent extends ApprovalEvent {
147
159
  /** Users named in the comment. */
148
160
  recipients: string[];
149
161
  }
162
+ /** Maps each lifecycle event name to its payload type. Keys are what {@link ApprovalEngine.on} accepts; see {@link ApprovalEventName}. */
150
163
  interface ApprovalEventMap {
151
164
  'approval:submitted': SubmittedEvent;
152
165
  'approval:approved': ApprovedEvent;
@@ -172,10 +185,12 @@ interface ApprovalEventMap {
172
185
  'approval:commented': CommentedEvent;
173
186
  }
174
187
  type ApprovalEventName = keyof ApprovalEventMap;
188
+ /** An {@link AuditEntry} tagged with the instance it belongs to, for callers aggregating history across several instances. */
175
189
  interface HistoryEntry extends AuditEntry {
176
190
  instanceId: string;
177
191
  }
178
192
 
193
+ /** Normalized envelope passed to {@link INotificationAdapter.notify} for every approval event. */
179
194
  interface NotificationEvent {
180
195
  /** The event that fired, e.g. `'submitted'`, `'approved'`, `'escalated'`. */
181
196
  type: ApprovalEventName;
@@ -196,6 +211,7 @@ interface NotificationEvent {
196
211
  /** Event-specific detail, shaped by {@link type}. */
197
212
  payload: ApprovalEventMap[ApprovalEventName];
198
213
  }
214
+ /** Sink for approval-event notifications (email, Slack, webhooks, ...). */
199
215
  interface INotificationAdapter {
200
216
  /** Called after every emitted approval event. Must not throw — errors are logged and swallowed. */
201
217
  notify(event: NotificationEvent): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance, b as AuditEntry } from './instance-Cu6-qPxs.cjs';
1
+ import { a as ApprovalInstance, b as AuditEntry } from './instance-Du-TGRH_.cjs';
2
2
 
3
3
  /** Common fields carried by every lifecycle event emitted for an approval instance. */
4
4
  interface ApprovalEvent {
@@ -14,6 +14,7 @@ interface ApprovalEvent {
14
14
  /** Emitted as `approval:submitted` when a new instance is raised. */
15
15
  interface SubmittedEvent extends ApprovalEvent {
16
16
  submittedBy: string;
17
+ /** Deduplicated union of every pending level's approvers in the opening group. */
17
18
  currentApprovers: string[];
18
19
  }
19
20
  /** Emitted as `approval:approved` when an approver accepts a level. */
@@ -21,6 +22,7 @@ interface ApprovedEvent extends ApprovalEvent {
21
22
  approverId: string;
22
23
  level: number;
23
24
  comment?: string;
25
+ /** True only when this was the last open branch — the instance is now fully approved. */
24
26
  isFinal: boolean;
25
27
  }
26
28
  /** Emitted as `approval:rejected` when an approver rejects a level. */
@@ -28,6 +30,11 @@ interface RejectedEvent extends ApprovalEvent {
28
30
  approverId: string;
29
31
  level: number;
30
32
  reason: string;
33
+ /**
34
+ * `'previous'` resets the chain to replay from an earlier level — the instance
35
+ * stays `pending`. `'originator'` and `null` are the same terminal outcome: the
36
+ * instance becomes `rejected`; `null` is just what an unset `returnTo` produces.
37
+ */
31
38
  returnTo: 'originator' | 'previous' | null;
32
39
  }
33
40
  /** Emitted as `approval:delegated` when an approver hands their decision to someone else. */
@@ -86,7 +93,9 @@ interface SlaBreachedEvent extends ApprovalEvent {
86
93
  * did not affect it.
87
94
  */
88
95
  interface DataUpdatedEvent extends ApprovalEvent {
96
+ /** Caller-supplied; not checked against the instance's submitter or approvers. */
89
97
  updatedBy: string;
98
+ /** Caller-supplied explanation for the change, if any. */
90
99
  reason?: string;
91
100
  /** Field paths whose values differ after the update. */
92
101
  changedFields: string[];
@@ -97,6 +106,7 @@ interface DataUpdatedEvent extends ApprovalEvent {
97
106
  }
98
107
  /** Emitted when a pending level's approvers are nudged. */
99
108
  interface ReminderEvent extends ApprovalEvent {
109
+ /** The level number being reminded. */
100
110
  level: number;
101
111
  /** Approvers who still owe a decision on this level. */
102
112
  recipients: string[];
@@ -105,8 +115,10 @@ interface ReminderEvent extends ApprovalEvent {
105
115
  }
106
116
  /** Emitted when an approver asks the submitter for clarification. */
107
117
  interface InfoRequestedEvent extends ApprovalEvent {
118
+ /** Must be an approver on `level` — enforced by requestInfo() before this is recorded. */
108
119
  askedBy: string;
109
120
  question: string;
121
+ /** The level `askedBy` was acting on when they asked. */
110
122
  level: number;
111
123
  /** Who is expected to answer — the submitter. */
112
124
  recipients: string[];
@@ -147,6 +159,7 @@ interface CommentedEvent extends ApprovalEvent {
147
159
  /** Users named in the comment. */
148
160
  recipients: string[];
149
161
  }
162
+ /** Maps each lifecycle event name to its payload type. Keys are what {@link ApprovalEngine.on} accepts; see {@link ApprovalEventName}. */
150
163
  interface ApprovalEventMap {
151
164
  'approval:submitted': SubmittedEvent;
152
165
  'approval:approved': ApprovedEvent;
@@ -172,10 +185,12 @@ interface ApprovalEventMap {
172
185
  'approval:commented': CommentedEvent;
173
186
  }
174
187
  type ApprovalEventName = keyof ApprovalEventMap;
188
+ /** An {@link AuditEntry} tagged with the instance it belongs to, for callers aggregating history across several instances. */
175
189
  interface HistoryEntry extends AuditEntry {
176
190
  instanceId: string;
177
191
  }
178
192
 
193
+ /** Normalized envelope passed to {@link INotificationAdapter.notify} for every approval event. */
179
194
  interface NotificationEvent {
180
195
  /** The event that fired, e.g. `'submitted'`, `'approved'`, `'escalated'`. */
181
196
  type: ApprovalEventName;
@@ -196,6 +211,7 @@ interface NotificationEvent {
196
211
  /** Event-specific detail, shaped by {@link type}. */
197
212
  payload: ApprovalEventMap[ApprovalEventName];
198
213
  }
214
+ /** Sink for approval-event notifications (email, Slack, webhooks, ...). */
199
215
  interface INotificationAdapter {
200
216
  /** Called after every emitted approval event. Must not throw — errors are logged and swallowed. */
201
217
  notify(event: NotificationEvent): Promise<void>;
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance } from './instance-Cu6-qPxs.js';
1
+ import { a as ApprovalInstance } from './instance-Du-TGRH_.js';
2
2
 
3
3
  /** Base class for all errors thrown by this library; carries a stable machine-readable `code`. */
4
4
  declare class ApprovalError extends Error {
@@ -37,6 +37,7 @@ declare class ApprovalTemplateNotFoundError extends ApprovalError {
37
37
  type EngineOperation = 'submit' | 'approve' | 'reject' | 'delegate' | 'reassign' | 'cancel' | 'updateData' | 'requestInfo' | 'provideInfo' | 'addAttachment' | 'removeAttachment' | 'addComment' | 'resubmit' | 'override';
38
38
  /** Context passed to an {@link IOperationMiddleware} hook for one engine call. */
39
39
  interface OperationContext<T = unknown> {
40
+ /** Which engine method is running; see {@link EngineOperation}. */
40
41
  operation: EngineOperation;
41
42
  /** The target instance's id, for operations that act on an existing instance. */
42
43
  instanceId?: string;
@@ -1,4 +1,4 @@
1
- import { a as ApprovalInstance } from './instance-Cu6-qPxs.cjs';
1
+ import { a as ApprovalInstance } from './instance-Du-TGRH_.cjs';
2
2
 
3
3
  /** Base class for all errors thrown by this library; carries a stable machine-readable `code`. */
4
4
  declare class ApprovalError extends Error {
@@ -37,6 +37,7 @@ declare class ApprovalTemplateNotFoundError extends ApprovalError {
37
37
  type EngineOperation = 'submit' | 'approve' | 'reject' | 'delegate' | 'reassign' | 'cancel' | 'updateData' | 'requestInfo' | 'provideInfo' | 'addAttachment' | 'removeAttachment' | 'addComment' | 'resubmit' | 'override';
38
38
  /** Context passed to an {@link IOperationMiddleware} hook for one engine call. */
39
39
  interface OperationContext<T = unknown> {
40
+ /** Which engine method is running; see {@link EngineOperation}. */
40
41
  operation: EngineOperation;
41
42
  /** The target instance's id, for operations that act on an existing instance. */
42
43
  instanceId?: string;
@@ -1,23 +1,31 @@
1
- import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-Cu6-qPxs.cjs';
1
+ import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-Du-TGRH_.js';
2
2
 
3
3
  /** Offset-based pagination request. */
4
4
  interface PaginationOpts {
5
+ /** Maximum number of items to return. */
5
6
  limit: number;
7
+ /** Number of matching items to skip before the page starts. */
6
8
  offset: number;
7
9
  }
8
10
  /** Offset-based pagination response, including the total matching count. */
9
11
  interface PaginatedResult<T> {
12
+ /** The requested page's items. */
10
13
  items: T[];
14
+ /** Total number of items matching the query, across all pages. */
11
15
  total: number;
12
16
  }
13
17
  /** Opaque cursor: base64(updatedAt_iso:id). Use the value from nextCursor/prevCursor. */
14
18
  interface CursorPaginationOpts {
19
+ /** Cursor from a previous page's `nextCursor`/`prevCursor`; omit to start from the first page. */
15
20
  cursor?: string;
21
+ /** Maximum number of items to return. */
16
22
  limit: number;
23
+ /** Which way to page from `cursor`. Defaults to `'forward'`. */
17
24
  direction?: 'forward' | 'backward';
18
25
  }
19
26
  /** Cursor-based pagination response. */
20
27
  interface CursorPaginatedResult<T> {
28
+ /** The requested page's items. */
21
29
  items: T[];
22
30
  /** Pass as `cursor` with `direction: 'forward'` to fetch the next page, if any. */
23
31
  nextCursor?: string;
@@ -26,12 +34,19 @@ interface CursorPaginatedResult<T> {
26
34
  /** Whether another page exists in the requested direction. */
27
35
  hasMore: boolean;
28
36
  }
37
+ /** Query filter for listing/counting instances; every set field narrows the match. */
29
38
  interface InstanceFilter {
39
+ /** Match only instances in this status. */
30
40
  status?: ApprovalStatus;
41
+ /** Match only instances of this document type. */
31
42
  documentType?: string;
43
+ /** Match only instances submitted by this user or system id. */
32
44
  submittedBy?: string;
45
+ /** Match only instances created from this template. */
33
46
  templateName?: string;
47
+ /** Match only instances created on or after this date. */
34
48
  fromDate?: Date;
49
+ /** Match only instances created on or before this date. */
35
50
  toDate?: Date;
36
51
  /**
37
52
  * Match instances whose document `data` contains these field/value pairs —
@@ -1,23 +1,31 @@
1
- import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-Cu6-qPxs.js';
1
+ import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-Du-TGRH_.cjs';
2
2
 
3
3
  /** Offset-based pagination request. */
4
4
  interface PaginationOpts {
5
+ /** Maximum number of items to return. */
5
6
  limit: number;
7
+ /** Number of matching items to skip before the page starts. */
6
8
  offset: number;
7
9
  }
8
10
  /** Offset-based pagination response, including the total matching count. */
9
11
  interface PaginatedResult<T> {
12
+ /** The requested page's items. */
10
13
  items: T[];
14
+ /** Total number of items matching the query, across all pages. */
11
15
  total: number;
12
16
  }
13
17
  /** Opaque cursor: base64(updatedAt_iso:id). Use the value from nextCursor/prevCursor. */
14
18
  interface CursorPaginationOpts {
19
+ /** Cursor from a previous page's `nextCursor`/`prevCursor`; omit to start from the first page. */
15
20
  cursor?: string;
21
+ /** Maximum number of items to return. */
16
22
  limit: number;
23
+ /** Which way to page from `cursor`. Defaults to `'forward'`. */
17
24
  direction?: 'forward' | 'backward';
18
25
  }
19
26
  /** Cursor-based pagination response. */
20
27
  interface CursorPaginatedResult<T> {
28
+ /** The requested page's items. */
21
29
  items: T[];
22
30
  /** Pass as `cursor` with `direction: 'forward'` to fetch the next page, if any. */
23
31
  nextCursor?: string;
@@ -26,12 +34,19 @@ interface CursorPaginatedResult<T> {
26
34
  /** Whether another page exists in the requested direction. */
27
35
  hasMore: boolean;
28
36
  }
37
+ /** Query filter for listing/counting instances; every set field narrows the match. */
29
38
  interface InstanceFilter {
39
+ /** Match only instances in this status. */
30
40
  status?: ApprovalStatus;
41
+ /** Match only instances of this document type. */
31
42
  documentType?: string;
43
+ /** Match only instances submitted by this user or system id. */
32
44
  submittedBy?: string;
45
+ /** Match only instances created from this template. */
33
46
  templateName?: string;
47
+ /** Match only instances created on or after this date. */
34
48
  fromDate?: Date;
49
+ /** Match only instances created on or before this date. */
35
50
  toDate?: Date;
36
51
  /**
37
52
  * Match instances whose document `data` contains these field/value pairs —
@@ -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-CrbVtEE-.cjs';
2
- import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-Cu6-qPxs.cjs';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-DYFj85oL.cjs';
2
+ import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-Du-TGRH_.cjs';
3
3
 
4
4
  /**
5
5
  * In-process {@link IStorageAdapter} backed by two `Map`s, keyed by
@@ -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-DDOW9z0L.js';
2
- import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-Cu6-qPxs.js';
1
+ import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-Bje_7c62.js';
2
+ import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-Du-TGRH_.js';
3
3
 
4
4
  /**
5
5
  * In-process {@link IStorageAdapter} backed by two `Map`s, keyed by