hierarchical-approval 0.2.1 → 0.3.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.
- package/CHANGELOG.md +67 -0
- package/README.md +103 -0
- package/dist/{ApprovalEngine-DICBgdIp.d.ts → ApprovalEngine-Bmg1bbrd.d.cts} +9 -190
- package/dist/{ApprovalEngine-CSxLWZ5h.d.cts → ApprovalEngine-DLyhejR-.d.ts} +9 -190
- package/dist/Clock-3FnOczFJ.d.cts +6 -0
- package/dist/Clock-3FnOczFJ.d.ts +6 -0
- package/dist/IAuditAdapter-B3vvU09m.d.ts +12 -0
- package/dist/IAuditAdapter-B_DhuPsU.d.cts +12 -0
- package/dist/IMetricsAdapter-D9PUz4tM.d.cts +9 -0
- package/dist/IMetricsAdapter-D9PUz4tM.d.ts +9 -0
- package/dist/INotificationAdapter-BdfVjYa8.d.ts +102 -0
- package/dist/INotificationAdapter-DVVmXU6a.d.cts +102 -0
- package/dist/IOperationMiddleware-CkRh93Wf.d.cts +62 -0
- package/dist/IOperationMiddleware-Dk_xOKxR.d.ts +62 -0
- package/dist/IStorageAdapter-DbeWhtCG.d.cts +47 -0
- package/dist/IStorageAdapter-EdwtErKD.d.ts +47 -0
- package/dist/Logger-CIzvalFc.d.cts +9 -0
- package/dist/Logger-CIzvalFc.d.ts +9 -0
- package/dist/adapters/MemoryAdapter.d.cts +2 -1
- package/dist/adapters/MemoryAdapter.d.ts +2 -1
- package/dist/adapters/PostgresAdapter.d.cts +2 -1
- package/dist/adapters/PostgresAdapter.d.ts +2 -1
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/{IStorageAdapter-B2xGuaKi.d.cts → instance-D8D7b07N.d.cts} +1 -45
- package/dist/{IStorageAdapter-B2xGuaKi.d.ts → instance-D8D7b07N.d.ts} +1 -45
- package/dist/plugins/audit.cjs +370 -0
- package/dist/plugins/audit.cjs.map +1 -0
- package/dist/plugins/audit.d.cts +292 -0
- package/dist/plugins/audit.d.ts +292 -0
- package/dist/plugins/audit.js +362 -0
- package/dist/plugins/audit.js.map +1 -0
- package/dist/plugins/metrics.cjs +406 -0
- package/dist/plugins/metrics.cjs.map +1 -0
- package/dist/plugins/metrics.d.cts +282 -0
- package/dist/plugins/metrics.d.ts +282 -0
- package/dist/plugins/metrics.js +399 -0
- package/dist/plugins/metrics.js.map +1 -0
- package/dist/plugins/notify.cjs +373 -0
- package/dist/plugins/notify.cjs.map +1 -0
- package/dist/plugins/notify.d.cts +349 -0
- package/dist/plugins/notify.d.ts +349 -0
- package/dist/plugins/notify.js +368 -0
- package/dist/plugins/notify.js.map +1 -0
- package/dist/plugins/resilience.cjs +328 -0
- package/dist/plugins/resilience.cjs.map +1 -0
- package/dist/plugins/resilience.d.cts +310 -0
- package/dist/plugins/resilience.d.ts +310 -0
- package/dist/plugins/resilience.js +321 -0
- package/dist/plugins/resilience.js.map +1 -0
- package/dist/testing.d.cts +9 -2
- package/dist/testing.d.ts +9 -2
- package/package.json +22 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { b as AuditEntry, a as ApprovalInstance } from './instance-D8D7b07N.cjs';
|
|
2
|
+
|
|
3
|
+
interface IAuditAdapter {
|
|
4
|
+
/**
|
|
5
|
+
* Called after every state-mutating operation, in addition to the primary storage adapter.
|
|
6
|
+
* Intended for write-once sinks: Kafka, S3, CloudTrail, WORM stores.
|
|
7
|
+
* Must not throw — errors are logged and swallowed.
|
|
8
|
+
*/
|
|
9
|
+
append(tenantId: string, instanceId: string, entry: AuditEntry, instance: Readonly<ApprovalInstance>): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type { IAuditAdapter as I };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type MetricName = 'approval.submitted' | 'approval.approved' | 'approval.rejected' | 'approval.cancelled' | 'approval.expired' | 'approval.sla_breached' | 'approval.escalated' | 'approval.reassigned' | 'approval.overridden' | 'approval.conflict_retry' | 'approval.operation_duration_ms';
|
|
2
|
+
interface IMetricsAdapter {
|
|
3
|
+
/** Increment a counter. Synchronous — never awaited. */
|
|
4
|
+
increment(metric: MetricName, labels?: Record<string, string>): void;
|
|
5
|
+
/** Record a timing measurement in milliseconds. Synchronous — never awaited. */
|
|
6
|
+
timing(metric: MetricName, durationMs: number, labels?: Record<string, string>): void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type { IMetricsAdapter as I, MetricName as M };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type MetricName = 'approval.submitted' | 'approval.approved' | 'approval.rejected' | 'approval.cancelled' | 'approval.expired' | 'approval.sla_breached' | 'approval.escalated' | 'approval.reassigned' | 'approval.overridden' | 'approval.conflict_retry' | 'approval.operation_duration_ms';
|
|
2
|
+
interface IMetricsAdapter {
|
|
3
|
+
/** Increment a counter. Synchronous — never awaited. */
|
|
4
|
+
increment(metric: MetricName, labels?: Record<string, string>): void;
|
|
5
|
+
/** Record a timing measurement in milliseconds. Synchronous — never awaited. */
|
|
6
|
+
timing(metric: MetricName, durationMs: number, labels?: Record<string, string>): void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type { IMetricsAdapter as I, MetricName as M };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { a as ApprovalInstance, b as AuditEntry } from './instance-D8D7b07N.js';
|
|
2
|
+
|
|
3
|
+
interface ApprovalEvent {
|
|
4
|
+
instanceId: string;
|
|
5
|
+
documentId: string;
|
|
6
|
+
documentType: string;
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
}
|
|
9
|
+
interface SubmittedEvent extends ApprovalEvent {
|
|
10
|
+
submittedBy: string;
|
|
11
|
+
currentApprovers: string[];
|
|
12
|
+
}
|
|
13
|
+
interface ApprovedEvent extends ApprovalEvent {
|
|
14
|
+
approverId: string;
|
|
15
|
+
level: number;
|
|
16
|
+
comment?: string;
|
|
17
|
+
isFinal: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface RejectedEvent extends ApprovalEvent {
|
|
20
|
+
approverId: string;
|
|
21
|
+
level: number;
|
|
22
|
+
reason: string;
|
|
23
|
+
returnTo: 'originator' | 'previous' | null;
|
|
24
|
+
}
|
|
25
|
+
interface DelegatedEvent extends ApprovalEvent {
|
|
26
|
+
fromApprover: string;
|
|
27
|
+
toApprover: string;
|
|
28
|
+
level: number;
|
|
29
|
+
reason: string;
|
|
30
|
+
}
|
|
31
|
+
interface ReassignedEvent extends ApprovalEvent {
|
|
32
|
+
reassignedBy: string;
|
|
33
|
+
fromApprover: string;
|
|
34
|
+
toApprover: string;
|
|
35
|
+
level: number;
|
|
36
|
+
reason: string;
|
|
37
|
+
}
|
|
38
|
+
interface EscalatedEvent extends ApprovalEvent {
|
|
39
|
+
level: number;
|
|
40
|
+
escalatedTo: string;
|
|
41
|
+
}
|
|
42
|
+
interface CancelledEvent extends ApprovalEvent {
|
|
43
|
+
cancelledBy: string;
|
|
44
|
+
reason: string;
|
|
45
|
+
}
|
|
46
|
+
interface LevelAdvancedEvent extends ApprovalEvent {
|
|
47
|
+
fromLevel: number;
|
|
48
|
+
toLevel: number;
|
|
49
|
+
newApprovers: string[];
|
|
50
|
+
}
|
|
51
|
+
interface ResubmittedEvent extends ApprovalEvent {
|
|
52
|
+
resubmittedBy: string;
|
|
53
|
+
originalInstanceId: string;
|
|
54
|
+
}
|
|
55
|
+
interface OverriddenEvent extends ApprovalEvent {
|
|
56
|
+
overriddenBy: string;
|
|
57
|
+
justification: string;
|
|
58
|
+
}
|
|
59
|
+
interface ExpiredEvent extends ApprovalEvent {
|
|
60
|
+
deadlineAction: 'cancel' | 'reject';
|
|
61
|
+
}
|
|
62
|
+
interface SlaBreachedEvent extends ApprovalEvent {
|
|
63
|
+
slaDeadlineAt: Date;
|
|
64
|
+
}
|
|
65
|
+
interface ApprovalEventMap {
|
|
66
|
+
'approval:submitted': SubmittedEvent;
|
|
67
|
+
'approval:approved': ApprovedEvent;
|
|
68
|
+
'approval:rejected': RejectedEvent;
|
|
69
|
+
'approval:delegated': DelegatedEvent;
|
|
70
|
+
'approval:reassigned': ReassignedEvent;
|
|
71
|
+
'approval:escalated': EscalatedEvent;
|
|
72
|
+
'approval:cancelled': CancelledEvent;
|
|
73
|
+
'approval:completed': ApprovalInstance;
|
|
74
|
+
'approval:level_advanced': LevelAdvancedEvent;
|
|
75
|
+
'approval:resubmitted': ResubmittedEvent;
|
|
76
|
+
'approval:overridden': OverriddenEvent;
|
|
77
|
+
'approval:expired': ExpiredEvent;
|
|
78
|
+
'approval:sla_breached': SlaBreachedEvent;
|
|
79
|
+
}
|
|
80
|
+
type ApprovalEventName = keyof ApprovalEventMap;
|
|
81
|
+
interface HistoryEntry extends AuditEntry {
|
|
82
|
+
instanceId: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface NotificationEvent {
|
|
86
|
+
type: ApprovalEventName;
|
|
87
|
+
instanceId: string;
|
|
88
|
+
documentId: string;
|
|
89
|
+
documentType: string;
|
|
90
|
+
timestamp: Date;
|
|
91
|
+
/** Current-level approver IDs; empty for non-level events (cancelled, expired, etc.). */
|
|
92
|
+
recipients: string[];
|
|
93
|
+
templateName: string;
|
|
94
|
+
tenantId: string;
|
|
95
|
+
payload: ApprovalEventMap[ApprovalEventName];
|
|
96
|
+
}
|
|
97
|
+
interface INotificationAdapter {
|
|
98
|
+
/** Called after every emitted approval event. Must not throw — errors are logged and swallowed. */
|
|
99
|
+
notify(event: NotificationEvent): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type { ApprovalEvent as A, CancelledEvent as C, DelegatedEvent 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, ExpiredEvent as d, RejectedEvent as e, ResubmittedEvent as f, SubmittedEvent as g };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { a as ApprovalInstance, b as AuditEntry } from './instance-D8D7b07N.cjs';
|
|
2
|
+
|
|
3
|
+
interface ApprovalEvent {
|
|
4
|
+
instanceId: string;
|
|
5
|
+
documentId: string;
|
|
6
|
+
documentType: string;
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
}
|
|
9
|
+
interface SubmittedEvent extends ApprovalEvent {
|
|
10
|
+
submittedBy: string;
|
|
11
|
+
currentApprovers: string[];
|
|
12
|
+
}
|
|
13
|
+
interface ApprovedEvent extends ApprovalEvent {
|
|
14
|
+
approverId: string;
|
|
15
|
+
level: number;
|
|
16
|
+
comment?: string;
|
|
17
|
+
isFinal: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface RejectedEvent extends ApprovalEvent {
|
|
20
|
+
approverId: string;
|
|
21
|
+
level: number;
|
|
22
|
+
reason: string;
|
|
23
|
+
returnTo: 'originator' | 'previous' | null;
|
|
24
|
+
}
|
|
25
|
+
interface DelegatedEvent extends ApprovalEvent {
|
|
26
|
+
fromApprover: string;
|
|
27
|
+
toApprover: string;
|
|
28
|
+
level: number;
|
|
29
|
+
reason: string;
|
|
30
|
+
}
|
|
31
|
+
interface ReassignedEvent extends ApprovalEvent {
|
|
32
|
+
reassignedBy: string;
|
|
33
|
+
fromApprover: string;
|
|
34
|
+
toApprover: string;
|
|
35
|
+
level: number;
|
|
36
|
+
reason: string;
|
|
37
|
+
}
|
|
38
|
+
interface EscalatedEvent extends ApprovalEvent {
|
|
39
|
+
level: number;
|
|
40
|
+
escalatedTo: string;
|
|
41
|
+
}
|
|
42
|
+
interface CancelledEvent extends ApprovalEvent {
|
|
43
|
+
cancelledBy: string;
|
|
44
|
+
reason: string;
|
|
45
|
+
}
|
|
46
|
+
interface LevelAdvancedEvent extends ApprovalEvent {
|
|
47
|
+
fromLevel: number;
|
|
48
|
+
toLevel: number;
|
|
49
|
+
newApprovers: string[];
|
|
50
|
+
}
|
|
51
|
+
interface ResubmittedEvent extends ApprovalEvent {
|
|
52
|
+
resubmittedBy: string;
|
|
53
|
+
originalInstanceId: string;
|
|
54
|
+
}
|
|
55
|
+
interface OverriddenEvent extends ApprovalEvent {
|
|
56
|
+
overriddenBy: string;
|
|
57
|
+
justification: string;
|
|
58
|
+
}
|
|
59
|
+
interface ExpiredEvent extends ApprovalEvent {
|
|
60
|
+
deadlineAction: 'cancel' | 'reject';
|
|
61
|
+
}
|
|
62
|
+
interface SlaBreachedEvent extends ApprovalEvent {
|
|
63
|
+
slaDeadlineAt: Date;
|
|
64
|
+
}
|
|
65
|
+
interface ApprovalEventMap {
|
|
66
|
+
'approval:submitted': SubmittedEvent;
|
|
67
|
+
'approval:approved': ApprovedEvent;
|
|
68
|
+
'approval:rejected': RejectedEvent;
|
|
69
|
+
'approval:delegated': DelegatedEvent;
|
|
70
|
+
'approval:reassigned': ReassignedEvent;
|
|
71
|
+
'approval:escalated': EscalatedEvent;
|
|
72
|
+
'approval:cancelled': CancelledEvent;
|
|
73
|
+
'approval:completed': ApprovalInstance;
|
|
74
|
+
'approval:level_advanced': LevelAdvancedEvent;
|
|
75
|
+
'approval:resubmitted': ResubmittedEvent;
|
|
76
|
+
'approval:overridden': OverriddenEvent;
|
|
77
|
+
'approval:expired': ExpiredEvent;
|
|
78
|
+
'approval:sla_breached': SlaBreachedEvent;
|
|
79
|
+
}
|
|
80
|
+
type ApprovalEventName = keyof ApprovalEventMap;
|
|
81
|
+
interface HistoryEntry extends AuditEntry {
|
|
82
|
+
instanceId: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface NotificationEvent {
|
|
86
|
+
type: ApprovalEventName;
|
|
87
|
+
instanceId: string;
|
|
88
|
+
documentId: string;
|
|
89
|
+
documentType: string;
|
|
90
|
+
timestamp: Date;
|
|
91
|
+
/** Current-level approver IDs; empty for non-level events (cancelled, expired, etc.). */
|
|
92
|
+
recipients: string[];
|
|
93
|
+
templateName: string;
|
|
94
|
+
tenantId: string;
|
|
95
|
+
payload: ApprovalEventMap[ApprovalEventName];
|
|
96
|
+
}
|
|
97
|
+
interface INotificationAdapter {
|
|
98
|
+
/** Called after every emitted approval event. Must not throw — errors are logged and swallowed. */
|
|
99
|
+
notify(event: NotificationEvent): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type { ApprovalEvent as A, CancelledEvent as C, DelegatedEvent 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, ExpiredEvent as d, RejectedEvent as e, ResubmittedEvent as f, SubmittedEvent as g };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-D8D7b07N.cjs';
|
|
2
|
+
|
|
3
|
+
declare class ApprovalError extends Error {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
constructor(message: string, code: string);
|
|
6
|
+
toJSON(): {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
toHttpStatus(): number;
|
|
12
|
+
}
|
|
13
|
+
declare class ApprovalNotFoundError extends ApprovalError {
|
|
14
|
+
constructor(resource: string, id: string);
|
|
15
|
+
}
|
|
16
|
+
declare class ApprovalConflictError extends ApprovalError {
|
|
17
|
+
constructor(instanceId: string);
|
|
18
|
+
}
|
|
19
|
+
declare class ApprovalForbiddenError extends ApprovalError {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
declare class ApprovalValidationError extends ApprovalError {
|
|
23
|
+
readonly cause?: unknown | undefined;
|
|
24
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
25
|
+
}
|
|
26
|
+
declare class ApprovalTemplateNotFoundError extends ApprovalError {
|
|
27
|
+
constructor(name: string);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface AuthorizationContext {
|
|
31
|
+
operation: 'submit' | 'approve' | 'reject' | 'delegate' | 'reassign' | 'cancel' | 'escalate' | 'override' | 'resubmit' | 'addComment';
|
|
32
|
+
actorId: string;
|
|
33
|
+
instance: Readonly<ApprovalInstance>;
|
|
34
|
+
level?: Readonly<ApprovalLevelInstance>;
|
|
35
|
+
opts: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
interface IAuthorizationPolicy {
|
|
38
|
+
/**
|
|
39
|
+
* Return undefined to allow the operation.
|
|
40
|
+
* Return a non-empty string to deny — the engine throws ApprovalForbiddenError(message).
|
|
41
|
+
* Throwing ApprovalForbiddenError directly is also permitted.
|
|
42
|
+
*/
|
|
43
|
+
authorize(ctx: AuthorizationContext): Promise<string | undefined> | string | undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface OperationContext<T = unknown> {
|
|
47
|
+
operation: string;
|
|
48
|
+
instanceId?: string;
|
|
49
|
+
actorId?: string;
|
|
50
|
+
tenantId: string;
|
|
51
|
+
input: T;
|
|
52
|
+
}
|
|
53
|
+
interface IOperationMiddleware {
|
|
54
|
+
/** Runs after authorization and input validation, before state mutations. */
|
|
55
|
+
before?(ctx: OperationContext): Promise<void> | void;
|
|
56
|
+
/** Runs after successful completion of the operation. */
|
|
57
|
+
after?(ctx: OperationContext, result: ApprovalInstance | void): Promise<void> | void;
|
|
58
|
+
/** Runs when an ApprovalError is thrown. Does not suppress the error. */
|
|
59
|
+
onError?(ctx: OperationContext, error: ApprovalError): Promise<void> | void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { ApprovalConflictError as A, type IAuthorizationPolicy as I, type OperationContext as O, ApprovalError as a, ApprovalForbiddenError as b, ApprovalNotFoundError as c, ApprovalTemplateNotFoundError as d, ApprovalValidationError as e, type AuthorizationContext as f, type IOperationMiddleware as g };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { a as ApprovalInstance, d as ApprovalLevelInstance } from './instance-D8D7b07N.js';
|
|
2
|
+
|
|
3
|
+
declare class ApprovalError extends Error {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
constructor(message: string, code: string);
|
|
6
|
+
toJSON(): {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
toHttpStatus(): number;
|
|
12
|
+
}
|
|
13
|
+
declare class ApprovalNotFoundError extends ApprovalError {
|
|
14
|
+
constructor(resource: string, id: string);
|
|
15
|
+
}
|
|
16
|
+
declare class ApprovalConflictError extends ApprovalError {
|
|
17
|
+
constructor(instanceId: string);
|
|
18
|
+
}
|
|
19
|
+
declare class ApprovalForbiddenError extends ApprovalError {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
declare class ApprovalValidationError extends ApprovalError {
|
|
23
|
+
readonly cause?: unknown | undefined;
|
|
24
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
25
|
+
}
|
|
26
|
+
declare class ApprovalTemplateNotFoundError extends ApprovalError {
|
|
27
|
+
constructor(name: string);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface AuthorizationContext {
|
|
31
|
+
operation: 'submit' | 'approve' | 'reject' | 'delegate' | 'reassign' | 'cancel' | 'escalate' | 'override' | 'resubmit' | 'addComment';
|
|
32
|
+
actorId: string;
|
|
33
|
+
instance: Readonly<ApprovalInstance>;
|
|
34
|
+
level?: Readonly<ApprovalLevelInstance>;
|
|
35
|
+
opts: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
interface IAuthorizationPolicy {
|
|
38
|
+
/**
|
|
39
|
+
* Return undefined to allow the operation.
|
|
40
|
+
* Return a non-empty string to deny — the engine throws ApprovalForbiddenError(message).
|
|
41
|
+
* Throwing ApprovalForbiddenError directly is also permitted.
|
|
42
|
+
*/
|
|
43
|
+
authorize(ctx: AuthorizationContext): Promise<string | undefined> | string | undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface OperationContext<T = unknown> {
|
|
47
|
+
operation: string;
|
|
48
|
+
instanceId?: string;
|
|
49
|
+
actorId?: string;
|
|
50
|
+
tenantId: string;
|
|
51
|
+
input: T;
|
|
52
|
+
}
|
|
53
|
+
interface IOperationMiddleware {
|
|
54
|
+
/** Runs after authorization and input validation, before state mutations. */
|
|
55
|
+
before?(ctx: OperationContext): Promise<void> | void;
|
|
56
|
+
/** Runs after successful completion of the operation. */
|
|
57
|
+
after?(ctx: OperationContext, result: ApprovalInstance | void): Promise<void> | void;
|
|
58
|
+
/** Runs when an ApprovalError is thrown. Does not suppress the error. */
|
|
59
|
+
onError?(ctx: OperationContext, error: ApprovalError): Promise<void> | void;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { ApprovalConflictError as A, type IAuthorizationPolicy as I, type OperationContext as O, ApprovalError as a, ApprovalForbiddenError as b, ApprovalNotFoundError as c, ApprovalTemplateNotFoundError as d, ApprovalValidationError as e, type AuthorizationContext as f, type IOperationMiddleware as g };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-D8D7b07N.cjs';
|
|
2
|
+
|
|
3
|
+
interface PaginationOpts {
|
|
4
|
+
limit: number;
|
|
5
|
+
offset: number;
|
|
6
|
+
}
|
|
7
|
+
interface PaginatedResult<T> {
|
|
8
|
+
items: T[];
|
|
9
|
+
total: number;
|
|
10
|
+
}
|
|
11
|
+
/** Opaque cursor: base64(updatedAt_iso:id). Use the value from nextCursor/prevCursor. */
|
|
12
|
+
interface CursorPaginationOpts {
|
|
13
|
+
cursor?: string;
|
|
14
|
+
limit: number;
|
|
15
|
+
direction?: 'forward' | 'backward';
|
|
16
|
+
}
|
|
17
|
+
interface CursorPaginatedResult<T> {
|
|
18
|
+
items: T[];
|
|
19
|
+
nextCursor?: string;
|
|
20
|
+
prevCursor?: string;
|
|
21
|
+
hasMore: boolean;
|
|
22
|
+
}
|
|
23
|
+
interface InstanceFilter {
|
|
24
|
+
status?: ApprovalStatus;
|
|
25
|
+
documentType?: string;
|
|
26
|
+
submittedBy?: string;
|
|
27
|
+
fromDate?: Date;
|
|
28
|
+
toDate?: Date;
|
|
29
|
+
}
|
|
30
|
+
interface IStorageAdapter {
|
|
31
|
+
saveTemplate(template: ApprovalTemplate): Promise<void>;
|
|
32
|
+
getTemplate(tenantId: string, name: string): Promise<ApprovalTemplate | null>;
|
|
33
|
+
listTemplates(tenantId: string): Promise<ApprovalTemplate[]>;
|
|
34
|
+
saveInstance(instance: ApprovalInstance): Promise<void>;
|
|
35
|
+
/** Conditional update — throws ApprovalConflictError if stored version !== expectedVersion. */
|
|
36
|
+
updateInstance(instance: ApprovalInstance, expectedVersion: number): Promise<void>;
|
|
37
|
+
getInstance(tenantId: string, id: string): Promise<ApprovalInstance | null>;
|
|
38
|
+
getInstancesByApprover(tenantId: string, approverId: string, opts?: PaginationOpts): Promise<PaginatedResult<ApprovalInstance>>;
|
|
39
|
+
getInstancesByFilter(tenantId: string, filter: InstanceFilter, opts?: PaginationOpts): Promise<PaginatedResult<ApprovalInstance>>;
|
|
40
|
+
/** Optional cursor-based pagination — more efficient than offset at scale. */
|
|
41
|
+
getInstancesByCursor?(tenantId: string, filter: InstanceFilter, opts: CursorPaginationOpts): Promise<CursorPaginatedResult<ApprovalInstance>>;
|
|
42
|
+
getOverdueInstances(tenantId: string, asOf: Date): Promise<ApprovalInstance[]>;
|
|
43
|
+
getIdempotentInstance(tenantId: string, idempotencyKey: string): Promise<ApprovalInstance | null>;
|
|
44
|
+
appendAuditEntry(tenantId: string, instanceId: string, entry: AuditEntry): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type { CursorPaginationOpts as C, IStorageAdapter as I, PaginationOpts as P, PaginatedResult as a, InstanceFilter as b, CursorPaginatedResult as c };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { A as ApprovalTemplate, a as ApprovalInstance, f as ApprovalStatus, b as AuditEntry } from './instance-D8D7b07N.js';
|
|
2
|
+
|
|
3
|
+
interface PaginationOpts {
|
|
4
|
+
limit: number;
|
|
5
|
+
offset: number;
|
|
6
|
+
}
|
|
7
|
+
interface PaginatedResult<T> {
|
|
8
|
+
items: T[];
|
|
9
|
+
total: number;
|
|
10
|
+
}
|
|
11
|
+
/** Opaque cursor: base64(updatedAt_iso:id). Use the value from nextCursor/prevCursor. */
|
|
12
|
+
interface CursorPaginationOpts {
|
|
13
|
+
cursor?: string;
|
|
14
|
+
limit: number;
|
|
15
|
+
direction?: 'forward' | 'backward';
|
|
16
|
+
}
|
|
17
|
+
interface CursorPaginatedResult<T> {
|
|
18
|
+
items: T[];
|
|
19
|
+
nextCursor?: string;
|
|
20
|
+
prevCursor?: string;
|
|
21
|
+
hasMore: boolean;
|
|
22
|
+
}
|
|
23
|
+
interface InstanceFilter {
|
|
24
|
+
status?: ApprovalStatus;
|
|
25
|
+
documentType?: string;
|
|
26
|
+
submittedBy?: string;
|
|
27
|
+
fromDate?: Date;
|
|
28
|
+
toDate?: Date;
|
|
29
|
+
}
|
|
30
|
+
interface IStorageAdapter {
|
|
31
|
+
saveTemplate(template: ApprovalTemplate): Promise<void>;
|
|
32
|
+
getTemplate(tenantId: string, name: string): Promise<ApprovalTemplate | null>;
|
|
33
|
+
listTemplates(tenantId: string): Promise<ApprovalTemplate[]>;
|
|
34
|
+
saveInstance(instance: ApprovalInstance): Promise<void>;
|
|
35
|
+
/** Conditional update — throws ApprovalConflictError if stored version !== expectedVersion. */
|
|
36
|
+
updateInstance(instance: ApprovalInstance, expectedVersion: number): Promise<void>;
|
|
37
|
+
getInstance(tenantId: string, id: string): Promise<ApprovalInstance | null>;
|
|
38
|
+
getInstancesByApprover(tenantId: string, approverId: string, opts?: PaginationOpts): Promise<PaginatedResult<ApprovalInstance>>;
|
|
39
|
+
getInstancesByFilter(tenantId: string, filter: InstanceFilter, opts?: PaginationOpts): Promise<PaginatedResult<ApprovalInstance>>;
|
|
40
|
+
/** Optional cursor-based pagination — more efficient than offset at scale. */
|
|
41
|
+
getInstancesByCursor?(tenantId: string, filter: InstanceFilter, opts: CursorPaginationOpts): Promise<CursorPaginatedResult<ApprovalInstance>>;
|
|
42
|
+
getOverdueInstances(tenantId: string, asOf: Date): Promise<ApprovalInstance[]>;
|
|
43
|
+
getIdempotentInstance(tenantId: string, idempotencyKey: string): Promise<ApprovalInstance | null>;
|
|
44
|
+
appendAuditEntry(tenantId: string, instanceId: string, entry: AuditEntry): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type { CursorPaginationOpts as C, IStorageAdapter as I, PaginationOpts as P, PaginatedResult as a, InstanceFilter as b, CursorPaginatedResult as c };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface Logger {
|
|
2
|
+
info(msg: string, context?: Record<string, unknown>): void;
|
|
3
|
+
warn(msg: string, context?: Record<string, unknown>): void;
|
|
4
|
+
error(msg: string, err?: unknown, context?: Record<string, unknown>): void;
|
|
5
|
+
debug(msg: string, context?: Record<string, unknown>): void;
|
|
6
|
+
}
|
|
7
|
+
declare const noopLogger: Logger;
|
|
8
|
+
|
|
9
|
+
export { type Logger as L, noopLogger as n };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface Logger {
|
|
2
|
+
info(msg: string, context?: Record<string, unknown>): void;
|
|
3
|
+
warn(msg: string, context?: Record<string, unknown>): void;
|
|
4
|
+
error(msg: string, err?: unknown, context?: Record<string, unknown>): void;
|
|
5
|
+
debug(msg: string, context?: Record<string, unknown>): void;
|
|
6
|
+
}
|
|
7
|
+
declare const noopLogger: Logger;
|
|
8
|
+
|
|
9
|
+
export { type Logger as L, noopLogger as n };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { I as IStorageAdapter,
|
|
1
|
+
import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-DbeWhtCG.cjs';
|
|
2
|
+
import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-D8D7b07N.cjs';
|
|
2
3
|
|
|
3
4
|
declare class MemoryAdapter implements IStorageAdapter {
|
|
4
5
|
private templates;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { I as IStorageAdapter,
|
|
1
|
+
import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-EdwtErKD.js';
|
|
2
|
+
import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-D8D7b07N.js';
|
|
2
3
|
|
|
3
4
|
declare class MemoryAdapter implements IStorageAdapter {
|
|
4
5
|
private templates;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as tls from 'tls';
|
|
2
2
|
import * as pg from 'pg';
|
|
3
|
-
import { I as IStorageAdapter,
|
|
3
|
+
import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-DbeWhtCG.cjs';
|
|
4
|
+
import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-D8D7b07N.cjs';
|
|
4
5
|
|
|
5
6
|
interface PostgresAdapterOptions {
|
|
6
7
|
connectionString?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as tls from 'tls';
|
|
2
2
|
import * as pg from 'pg';
|
|
3
|
-
import { I as IStorageAdapter,
|
|
3
|
+
import { I as IStorageAdapter, P as PaginationOpts, a as PaginatedResult, b as InstanceFilter, C as CursorPaginationOpts, c as CursorPaginatedResult } from '../IStorageAdapter-EdwtErKD.js';
|
|
4
|
+
import { A as ApprovalTemplate, a as ApprovalInstance, b as AuditEntry } from '../instance-D8D7b07N.js';
|
|
4
5
|
|
|
5
6
|
interface PostgresAdapterOptions {
|
|
6
7
|
connectionString?: string;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export { A as AddCommentOptions, a as ApprovalEngine, b as ApprovalEngineOptions, c as ApprovalStatistics, d as ApproveOptions, e as ApproverResolverFn, B as BulkResult, f as BusinessCalendar, C as CanApproveResult, g as CancelOptions, h as ConditionOperatorFn, D as DelegateOptions, E as EscalateOptions, H as HealthResult, I as ISchedulerAdapter, i as IdGeneratorFn, j as IdempotencyKeyFn, O as OrgProvider, k as OverrideOptions, P as PreviewChainLevel, l as PreviewResult, R as ReassignOptions, m as RejectOptions, n as ResubmitOptions, o as RetryPolicy, S as SubmitOptions, V as ValidationResult, W as WeekendCalendarOptions, p as defaultIdGenerator, w as weekendCalendar } from './ApprovalEngine-Bmg1bbrd.cjs';
|
|
2
|
+
import { I as IStorageAdapter } from './IStorageAdapter-DbeWhtCG.cjs';
|
|
3
|
+
export { c as CursorPaginatedResult, C as CursorPaginationOpts, b as InstanceFilter, a as PaginatedResult, P as PaginationOpts } from './IStorageAdapter-DbeWhtCG.cjs';
|
|
4
|
+
import { L as Logger } from './Logger-CIzvalFc.cjs';
|
|
5
|
+
export { n as noopLogger } from './Logger-CIzvalFc.cjs';
|
|
6
|
+
import { C as Clock } from './Clock-3FnOczFJ.cjs';
|
|
7
|
+
export { s as systemClock } from './Clock-3FnOczFJ.cjs';
|
|
8
|
+
export { A as ApprovalConflictError, a as ApprovalError, b as ApprovalForbiddenError, c as ApprovalNotFoundError, d as ApprovalTemplateNotFoundError, e as ApprovalValidationError, f as AuthorizationContext, I as IAuthorizationPolicy, g as IOperationMiddleware, O as OperationContext } from './IOperationMiddleware-CkRh93Wf.cjs';
|
|
5
9
|
export { MemoryAdapter } from './adapters/MemoryAdapter.cjs';
|
|
10
|
+
export { A as ApprovalEvent, a as ApprovalEventMap, b as ApprovalEventName, c as ApprovedEvent, C as CancelledEvent, D as DelegatedEvent, E as EscalatedEvent, d as ExpiredEvent, H as HistoryEntry, I as INotificationAdapter, L as LevelAdvancedEvent, N as NotificationEvent, O as OverriddenEvent, R as ReassignedEvent, e as RejectedEvent, f as ResubmittedEvent, S as SlaBreachedEvent, g as SubmittedEvent } from './INotificationAdapter-DVVmXU6a.cjs';
|
|
11
|
+
export { I as IAuditAdapter } from './IAuditAdapter-B_DhuPsU.cjs';
|
|
12
|
+
export { I as IMetricsAdapter, M as MetricName } from './IMetricsAdapter-D9PUz4tM.cjs';
|
|
13
|
+
export { a as ApprovalInstance, c as ApprovalLevelConfig, d as ApprovalLevelInstance, e as ApprovalMode, f as ApprovalStatus, A as ApprovalTemplate, g as ApprovalTemplateConfig, h as ApproverConfig, i as AuditAction, j as AuditContext, b as AuditEntry, C as Condition, k as ConditionOperator, l as ConditionRule, E as EscalationConfig, L as LevelStatus, R as ResolvedApprover, m as ResolverFn, T as TemplateSnapshot } from './instance-D8D7b07N.cjs';
|
|
6
14
|
import 'zod';
|
|
7
15
|
|
|
8
16
|
interface EscalationSchedulerOpts {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export { A as AddCommentOptions, a as ApprovalEngine, b as ApprovalEngineOptions, c as ApprovalStatistics, d as ApproveOptions, e as ApproverResolverFn, B as BulkResult, f as BusinessCalendar, C as CanApproveResult, g as CancelOptions, h as ConditionOperatorFn, D as DelegateOptions, E as EscalateOptions, H as HealthResult, I as ISchedulerAdapter, i as IdGeneratorFn, j as IdempotencyKeyFn, O as OrgProvider, k as OverrideOptions, P as PreviewChainLevel, l as PreviewResult, R as ReassignOptions, m as RejectOptions, n as ResubmitOptions, o as RetryPolicy, S as SubmitOptions, V as ValidationResult, W as WeekendCalendarOptions, p as defaultIdGenerator, w as weekendCalendar } from './ApprovalEngine-DLyhejR-.js';
|
|
2
|
+
import { I as IStorageAdapter } from './IStorageAdapter-EdwtErKD.js';
|
|
3
|
+
export { c as CursorPaginatedResult, C as CursorPaginationOpts, b as InstanceFilter, a as PaginatedResult, P as PaginationOpts } from './IStorageAdapter-EdwtErKD.js';
|
|
4
|
+
import { L as Logger } from './Logger-CIzvalFc.js';
|
|
5
|
+
export { n as noopLogger } from './Logger-CIzvalFc.js';
|
|
6
|
+
import { C as Clock } from './Clock-3FnOczFJ.js';
|
|
7
|
+
export { s as systemClock } from './Clock-3FnOczFJ.js';
|
|
8
|
+
export { A as ApprovalConflictError, a as ApprovalError, b as ApprovalForbiddenError, c as ApprovalNotFoundError, d as ApprovalTemplateNotFoundError, e as ApprovalValidationError, f as AuthorizationContext, I as IAuthorizationPolicy, g as IOperationMiddleware, O as OperationContext } from './IOperationMiddleware-Dk_xOKxR.js';
|
|
5
9
|
export { MemoryAdapter } from './adapters/MemoryAdapter.js';
|
|
10
|
+
export { A as ApprovalEvent, a as ApprovalEventMap, b as ApprovalEventName, c as ApprovedEvent, C as CancelledEvent, D as DelegatedEvent, E as EscalatedEvent, d as ExpiredEvent, H as HistoryEntry, I as INotificationAdapter, L as LevelAdvancedEvent, N as NotificationEvent, O as OverriddenEvent, R as ReassignedEvent, e as RejectedEvent, f as ResubmittedEvent, S as SlaBreachedEvent, g as SubmittedEvent } from './INotificationAdapter-BdfVjYa8.js';
|
|
11
|
+
export { I as IAuditAdapter } from './IAuditAdapter-B3vvU09m.js';
|
|
12
|
+
export { I as IMetricsAdapter, M as MetricName } from './IMetricsAdapter-D9PUz4tM.js';
|
|
13
|
+
export { a as ApprovalInstance, c as ApprovalLevelConfig, d as ApprovalLevelInstance, e as ApprovalMode, f as ApprovalStatus, A as ApprovalTemplate, g as ApprovalTemplateConfig, h as ApproverConfig, i as AuditAction, j as AuditContext, b as AuditEntry, C as Condition, k as ConditionOperator, l as ConditionRule, E as EscalationConfig, L as LevelStatus, R as ResolvedApprover, m as ResolverFn, T as TemplateSnapshot } from './instance-D8D7b07N.js';
|
|
6
14
|
import 'zod';
|
|
7
15
|
|
|
8
16
|
interface EscalationSchedulerOpts {
|
|
@@ -168,48 +168,4 @@ interface ApprovalInstance {
|
|
|
168
168
|
slaBreachedAt?: Date;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
limit: number;
|
|
173
|
-
offset: number;
|
|
174
|
-
}
|
|
175
|
-
interface PaginatedResult<T> {
|
|
176
|
-
items: T[];
|
|
177
|
-
total: number;
|
|
178
|
-
}
|
|
179
|
-
/** Opaque cursor: base64(updatedAt_iso:id). Use the value from nextCursor/prevCursor. */
|
|
180
|
-
interface CursorPaginationOpts {
|
|
181
|
-
cursor?: string;
|
|
182
|
-
limit: number;
|
|
183
|
-
direction?: 'forward' | 'backward';
|
|
184
|
-
}
|
|
185
|
-
interface CursorPaginatedResult<T> {
|
|
186
|
-
items: T[];
|
|
187
|
-
nextCursor?: string;
|
|
188
|
-
prevCursor?: string;
|
|
189
|
-
hasMore: boolean;
|
|
190
|
-
}
|
|
191
|
-
interface InstanceFilter {
|
|
192
|
-
status?: ApprovalStatus;
|
|
193
|
-
documentType?: string;
|
|
194
|
-
submittedBy?: string;
|
|
195
|
-
fromDate?: Date;
|
|
196
|
-
toDate?: Date;
|
|
197
|
-
}
|
|
198
|
-
interface IStorageAdapter {
|
|
199
|
-
saveTemplate(template: ApprovalTemplate): Promise<void>;
|
|
200
|
-
getTemplate(tenantId: string, name: string): Promise<ApprovalTemplate | null>;
|
|
201
|
-
listTemplates(tenantId: string): Promise<ApprovalTemplate[]>;
|
|
202
|
-
saveInstance(instance: ApprovalInstance): Promise<void>;
|
|
203
|
-
/** Conditional update — throws ApprovalConflictError if stored version !== expectedVersion. */
|
|
204
|
-
updateInstance(instance: ApprovalInstance, expectedVersion: number): Promise<void>;
|
|
205
|
-
getInstance(tenantId: string, id: string): Promise<ApprovalInstance | null>;
|
|
206
|
-
getInstancesByApprover(tenantId: string, approverId: string, opts?: PaginationOpts): Promise<PaginatedResult<ApprovalInstance>>;
|
|
207
|
-
getInstancesByFilter(tenantId: string, filter: InstanceFilter, opts?: PaginationOpts): Promise<PaginatedResult<ApprovalInstance>>;
|
|
208
|
-
/** Optional cursor-based pagination — more efficient than offset at scale. */
|
|
209
|
-
getInstancesByCursor?(tenantId: string, filter: InstanceFilter, opts: CursorPaginationOpts): Promise<CursorPaginatedResult<ApprovalInstance>>;
|
|
210
|
-
getOverdueInstances(tenantId: string, asOf: Date): Promise<ApprovalInstance[]>;
|
|
211
|
-
getIdempotentInstance(tenantId: string, idempotencyKey: string): Promise<ApprovalInstance | null>;
|
|
212
|
-
appendAuditEntry(tenantId: string, instanceId: string, entry: AuditEntry): Promise<void>;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export type { ApprovalTemplate as A, CursorPaginationOpts as C, EscalationConfig as E, IStorageAdapter as I, LevelStatus as L, PaginationOpts as P, ResolvedApprover as R, TemplateSnapshot as T, ApprovalInstance as a, PaginatedResult as b, InstanceFilter as c, AuditEntry as d, CursorPaginatedResult as e, ApprovalLevelConfig as f, ApprovalLevelInstance as g, ApprovalMode as h, ApprovalStatus as i, ApprovalTemplateConfig as j, ApproverConfig as k, AuditAction as l, AuditContext as m, Condition as n, ConditionOperator as o, ConditionRule as p, ResolverFn as q };
|
|
171
|
+
export type { ApprovalTemplate as A, Condition as C, EscalationConfig as E, LevelStatus as L, ResolvedApprover as R, TemplateSnapshot as T, ApprovalInstance as a, AuditEntry as b, ApprovalLevelConfig as c, ApprovalLevelInstance as d, ApprovalMode as e, ApprovalStatus as f, ApprovalTemplateConfig as g, ApproverConfig as h, AuditAction as i, AuditContext as j, ConditionOperator as k, ConditionRule as l, ResolverFn as m };
|