hierarchical-approval 2.3.0 → 2.5.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 +74 -0
- package/README.md +27 -0
- package/dist/{ApprovalEngine-Ci9urTDI.d.ts → ApprovalEngine-BHWls8-z.d.ts} +59 -7
- package/dist/{ApprovalEngine-C1dUPnLM.d.cts → ApprovalEngine-CW7Uu1bV.d.cts} +59 -7
- package/dist/{IAuditAdapter-C4OASS6u.d.ts → IAuditAdapter-CMCirvY-.d.ts} +1 -1
- package/dist/{IAuditAdapter-BHVKMMv6.d.cts → IAuditAdapter-Dwx8ZP4J.d.cts} +1 -1
- package/dist/{IAuthorizationPolicy-CtLkwQ8I.d.cts → IAuthorizationPolicy-B3vaV69v.d.cts} +1 -1
- package/dist/{IAuthorizationPolicy-BA_m2Dg9.d.ts → IAuthorizationPolicy-BryQIKko.d.ts} +1 -1
- package/dist/{INotificationAdapter-JJAiMyMd.d.cts → INotificationAdapter-AwbhZEqz.d.cts} +1 -1
- package/dist/{INotificationAdapter-BdgfUrIn.d.ts → INotificationAdapter-BBq2czpO.d.ts} +1 -1
- package/dist/{IOperationMiddleware-D0ksiFM3.d.cts → IOperationMiddleware-3J-_NSGq.d.cts} +1 -1
- package/dist/{IOperationMiddleware-BGYrAqep.d.ts → IOperationMiddleware-CqzFklMn.d.ts} +1 -1
- package/dist/{IStorageAdapter-BU3sau5W.d.ts → IStorageAdapter-Dw2xXP9B.d.ts} +1 -1
- package/dist/{IStorageAdapter-DdHO4Rf1.d.cts → IStorageAdapter-Pq9J60xv.d.cts} +1 -1
- package/dist/adapters/MemoryAdapter.d.cts +2 -2
- package/dist/adapters/MemoryAdapter.d.ts +2 -2
- package/dist/adapters/PostgresAdapter.d.cts +2 -2
- package/dist/adapters/PostgresAdapter.d.ts +2 -2
- package/dist/index.cjs +117 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +117 -7
- package/dist/index.js.map +1 -1
- package/dist/{instance-DUJY_Axf.d.cts → instance-BO-i9-nq.d.cts} +13 -0
- package/dist/{instance-DUJY_Axf.d.ts → instance-BO-i9-nq.d.ts} +13 -0
- package/dist/nestjs.cjs +49 -6
- package/dist/nestjs.cjs.map +1 -1
- package/dist/nestjs.d.cts +7 -7
- package/dist/nestjs.d.ts +7 -7
- package/dist/nestjs.js +49 -6
- package/dist/nestjs.js.map +1 -1
- package/dist/plugins/audit.d.cts +2 -2
- package/dist/plugins/audit.d.ts +2 -2
- package/dist/plugins/notify.cjs +105 -9
- package/dist/plugins/notify.cjs.map +1 -1
- package/dist/plugins/notify.d.cts +91 -3
- package/dist/plugins/notify.d.ts +91 -3
- package/dist/plugins/notify.js +105 -10
- package/dist/plugins/notify.js.map +1 -1
- package/dist/plugins/resilience.d.cts +3 -3
- package/dist/plugins/resilience.d.ts +3 -3
- package/dist/plugins/tracing.d.cts +2 -2
- package/dist/plugins/tracing.d.ts +2 -2
- package/dist/plugins/webhook.d.cts +2 -2
- package/dist/plugins/webhook.d.ts +2 -2
- package/dist/testing.cjs +49 -6
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +7 -7
- package/dist/testing.d.ts +7 -7
- package/dist/testing.js +49 -6
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
export { A as AddCommentOptions, a as ApprovalEngine, b as ApprovalEngineOptions, c as ApprovalStatistics, d as ApproveOptions, e as ApproverResolverFn, f as ApproverWorkload, B as BulkResult, g as BusinessCalendar, C as CanApproveResult,
|
|
2
|
-
import { I as IStorageAdapter } from './IStorageAdapter-
|
|
3
|
-
export { c as CursorPaginatedResult, C as CursorPaginationOpts, b as InstanceFilter, a as PaginatedResult, P as PaginationOpts } from './IStorageAdapter-
|
|
1
|
+
export { A as AddCommentOptions, a as ApprovalEngine, b as ApprovalEngineOptions, c as ApprovalStatistics, d as ApproveOptions, e as ApproverResolverFn, f as ApproverWorkload, B as BulkResult, g as BusinessCalendar, h as BusinessHoursCalendarOptions, C as CanApproveResult, i as CancelOptions, j as ConditionOperatorFn, k as CycleTimeStats, D as DelegateOptions, E as EscalateOptions, H as HealthResult, I as IdGeneratorFn, l as IdempotencyKeyFn, m as ImportResult, O as OrgProvider, n as OutOfOfficeProvider, o as OverrideOptions, P as PreviewChainLevel, p as PreviewResult, q as ProvideInfoOptions, r as PurgeResult, R as ReassignOptions, s as RejectOptions, t as RequestInfoOptions, u as ResubmitOptions, v as RetryPolicy, S as SubmitOptions, T as TEMPLATE_BUNDLE_VERSION, w as TemplateBundle, x as TransferResult, U as UpdateDataOptions, V as ValidationResult, W as WeekendCalendarOptions, y as businessHoursCalendar, z as defaultIdGenerator, F as toComparableNumber, G as validateConditionExpression, J as weekendCalendar } from './ApprovalEngine-CW7Uu1bV.cjs';
|
|
2
|
+
import { I as IStorageAdapter } from './IStorageAdapter-Pq9J60xv.cjs';
|
|
3
|
+
export { c as CursorPaginatedResult, C as CursorPaginationOpts, b as InstanceFilter, a as PaginatedResult, P as PaginationOpts } from './IStorageAdapter-Pq9J60xv.cjs';
|
|
4
4
|
import { L as Logger } from './Logger-BplhlU7l.cjs';
|
|
5
5
|
export { n as noopLogger } from './Logger-BplhlU7l.cjs';
|
|
6
6
|
import { C as Clock } from './Clock-3FnOczFJ.cjs';
|
|
7
7
|
export { s as systemClock } from './Clock-3FnOczFJ.cjs';
|
|
8
|
-
export { A as AuthorizationContext, I as IAuthorizationPolicy } from './IAuthorizationPolicy-
|
|
9
|
-
export { A as ApprovalConflictError, a as ApprovalError, b as ApprovalForbiddenError, c as ApprovalNotFoundError, d as ApprovalTemplateNotFoundError, e as ApprovalValidationError, I as IOperationMiddleware, O as OperationContext } from './IOperationMiddleware-
|
|
8
|
+
export { A as AuthorizationContext, I as IAuthorizationPolicy } from './IAuthorizationPolicy-B3vaV69v.cjs';
|
|
9
|
+
export { A as ApprovalConflictError, a as ApprovalError, b as ApprovalForbiddenError, c as ApprovalNotFoundError, d as ApprovalTemplateNotFoundError, e as ApprovalValidationError, I as IOperationMiddleware, O as OperationContext } from './IOperationMiddleware-3J-_NSGq.cjs';
|
|
10
10
|
export { MemoryAdapter } from './adapters/MemoryAdapter.cjs';
|
|
11
|
-
export { A as ApprovalEvent, a as ApprovalEventMap, b as ApprovalEventName, c as ApprovedEvent, d as AttachmentEvent, C as CancelledEvent, D as DataUpdatedEvent, e as DelegatedEvent, E as EscalatedEvent, f as ExpiredEvent, H as HistoryEntry, I as INotificationAdapter, g as InfoProvidedEvent, h as InfoRequestedEvent, L as LevelAdvancedEvent, N as NotificationEvent, O as OverriddenEvent, R as ReassignedEvent, i as RejectedEvent, j as ReminderEvent, k as ResubmittedEvent, S as SlaBreachedEvent, l as SubWorkflowEvent, m as SubmittedEvent } from './INotificationAdapter-
|
|
12
|
-
export { I as IAuditAdapter } from './IAuditAdapter-
|
|
11
|
+
export { A as ApprovalEvent, a as ApprovalEventMap, b as ApprovalEventName, c as ApprovedEvent, d as AttachmentEvent, C as CancelledEvent, D as DataUpdatedEvent, e as DelegatedEvent, E as EscalatedEvent, f as ExpiredEvent, H as HistoryEntry, I as INotificationAdapter, g as InfoProvidedEvent, h as InfoRequestedEvent, L as LevelAdvancedEvent, N as NotificationEvent, O as OverriddenEvent, R as ReassignedEvent, i as RejectedEvent, j as ReminderEvent, k as ResubmittedEvent, S as SlaBreachedEvent, l as SubWorkflowEvent, m as SubmittedEvent } from './INotificationAdapter-AwbhZEqz.cjs';
|
|
12
|
+
export { I as IAuditAdapter } from './IAuditAdapter-Dwx8ZP4J.cjs';
|
|
13
13
|
export { I as IMetricsAdapter, M as MetricName } from './IMetricsAdapter-DWq8IFaf.cjs';
|
|
14
14
|
export { I as ISchedulerAdapter } from './ISchedulerAdapter-DKv_QjVN.cjs';
|
|
15
|
-
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 Attachment, j as AuditAction, k as AuditContext, b as AuditEntry, C as Condition, l as ConditionExpression, m as ConditionGroup, n as ConditionOperator, o as ConditionRule, E as EscalationConfig, I as InfoRequest, L as LevelStatus, R as ResolvedApprover, p as ResolverFn, S as SubWorkflowConfig, T as TemplateSnapshot } from './instance-
|
|
15
|
+
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 Attachment, j as AuditAction, k as AuditContext, b as AuditEntry, C as Condition, l as ConditionExpression, m as ConditionGroup, n as ConditionOperator, o as ConditionRule, E as EscalationConfig, I as InfoRequest, L as LevelStatus, R as ResolvedApprover, p as ResolverFn, S as SubWorkflowConfig, T as TemplateSnapshot } from './instance-BO-i9-nq.cjs';
|
|
16
16
|
import 'zod';
|
|
17
17
|
|
|
18
18
|
interface EscalationSchedulerOpts {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
export { A as AddCommentOptions, a as ApprovalEngine, b as ApprovalEngineOptions, c as ApprovalStatistics, d as ApproveOptions, e as ApproverResolverFn, f as ApproverWorkload, B as BulkResult, g as BusinessCalendar, C as CanApproveResult,
|
|
2
|
-
import { I as IStorageAdapter } from './IStorageAdapter-
|
|
3
|
-
export { c as CursorPaginatedResult, C as CursorPaginationOpts, b as InstanceFilter, a as PaginatedResult, P as PaginationOpts } from './IStorageAdapter-
|
|
1
|
+
export { A as AddCommentOptions, a as ApprovalEngine, b as ApprovalEngineOptions, c as ApprovalStatistics, d as ApproveOptions, e as ApproverResolverFn, f as ApproverWorkload, B as BulkResult, g as BusinessCalendar, h as BusinessHoursCalendarOptions, C as CanApproveResult, i as CancelOptions, j as ConditionOperatorFn, k as CycleTimeStats, D as DelegateOptions, E as EscalateOptions, H as HealthResult, I as IdGeneratorFn, l as IdempotencyKeyFn, m as ImportResult, O as OrgProvider, n as OutOfOfficeProvider, o as OverrideOptions, P as PreviewChainLevel, p as PreviewResult, q as ProvideInfoOptions, r as PurgeResult, R as ReassignOptions, s as RejectOptions, t as RequestInfoOptions, u as ResubmitOptions, v as RetryPolicy, S as SubmitOptions, T as TEMPLATE_BUNDLE_VERSION, w as TemplateBundle, x as TransferResult, U as UpdateDataOptions, V as ValidationResult, W as WeekendCalendarOptions, y as businessHoursCalendar, z as defaultIdGenerator, F as toComparableNumber, G as validateConditionExpression, J as weekendCalendar } from './ApprovalEngine-BHWls8-z.js';
|
|
2
|
+
import { I as IStorageAdapter } from './IStorageAdapter-Dw2xXP9B.js';
|
|
3
|
+
export { c as CursorPaginatedResult, C as CursorPaginationOpts, b as InstanceFilter, a as PaginatedResult, P as PaginationOpts } from './IStorageAdapter-Dw2xXP9B.js';
|
|
4
4
|
import { L as Logger } from './Logger-BplhlU7l.js';
|
|
5
5
|
export { n as noopLogger } from './Logger-BplhlU7l.js';
|
|
6
6
|
import { C as Clock } from './Clock-3FnOczFJ.js';
|
|
7
7
|
export { s as systemClock } from './Clock-3FnOczFJ.js';
|
|
8
|
-
export { A as AuthorizationContext, I as IAuthorizationPolicy } from './IAuthorizationPolicy-
|
|
9
|
-
export { A as ApprovalConflictError, a as ApprovalError, b as ApprovalForbiddenError, c as ApprovalNotFoundError, d as ApprovalTemplateNotFoundError, e as ApprovalValidationError, I as IOperationMiddleware, O as OperationContext } from './IOperationMiddleware-
|
|
8
|
+
export { A as AuthorizationContext, I as IAuthorizationPolicy } from './IAuthorizationPolicy-BryQIKko.js';
|
|
9
|
+
export { A as ApprovalConflictError, a as ApprovalError, b as ApprovalForbiddenError, c as ApprovalNotFoundError, d as ApprovalTemplateNotFoundError, e as ApprovalValidationError, I as IOperationMiddleware, O as OperationContext } from './IOperationMiddleware-CqzFklMn.js';
|
|
10
10
|
export { MemoryAdapter } from './adapters/MemoryAdapter.js';
|
|
11
|
-
export { A as ApprovalEvent, a as ApprovalEventMap, b as ApprovalEventName, c as ApprovedEvent, d as AttachmentEvent, C as CancelledEvent, D as DataUpdatedEvent, e as DelegatedEvent, E as EscalatedEvent, f as ExpiredEvent, H as HistoryEntry, I as INotificationAdapter, g as InfoProvidedEvent, h as InfoRequestedEvent, L as LevelAdvancedEvent, N as NotificationEvent, O as OverriddenEvent, R as ReassignedEvent, i as RejectedEvent, j as ReminderEvent, k as ResubmittedEvent, S as SlaBreachedEvent, l as SubWorkflowEvent, m as SubmittedEvent } from './INotificationAdapter-
|
|
12
|
-
export { I as IAuditAdapter } from './IAuditAdapter-
|
|
11
|
+
export { A as ApprovalEvent, a as ApprovalEventMap, b as ApprovalEventName, c as ApprovedEvent, d as AttachmentEvent, C as CancelledEvent, D as DataUpdatedEvent, e as DelegatedEvent, E as EscalatedEvent, f as ExpiredEvent, H as HistoryEntry, I as INotificationAdapter, g as InfoProvidedEvent, h as InfoRequestedEvent, L as LevelAdvancedEvent, N as NotificationEvent, O as OverriddenEvent, R as ReassignedEvent, i as RejectedEvent, j as ReminderEvent, k as ResubmittedEvent, S as SlaBreachedEvent, l as SubWorkflowEvent, m as SubmittedEvent } from './INotificationAdapter-BBq2czpO.js';
|
|
12
|
+
export { I as IAuditAdapter } from './IAuditAdapter-CMCirvY-.js';
|
|
13
13
|
export { I as IMetricsAdapter, M as MetricName } from './IMetricsAdapter-DWq8IFaf.js';
|
|
14
14
|
export { I as ISchedulerAdapter } from './ISchedulerAdapter-DKv_QjVN.js';
|
|
15
|
-
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 Attachment, j as AuditAction, k as AuditContext, b as AuditEntry, C as Condition, l as ConditionExpression, m as ConditionGroup, n as ConditionOperator, o as ConditionRule, E as EscalationConfig, I as InfoRequest, L as LevelStatus, R as ResolvedApprover, p as ResolverFn, S as SubWorkflowConfig, T as TemplateSnapshot } from './instance-
|
|
15
|
+
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 Attachment, j as AuditAction, k as AuditContext, b as AuditEntry, C as Condition, l as ConditionExpression, m as ConditionGroup, n as ConditionOperator, o as ConditionRule, E as EscalationConfig, I as InfoRequest, L as LevelStatus, R as ResolvedApprover, p as ResolverFn, S as SubWorkflowConfig, T as TemplateSnapshot } from './instance-BO-i9-nq.js';
|
|
16
16
|
import 'zod';
|
|
17
17
|
|
|
18
18
|
interface EscalationSchedulerOpts {
|
package/dist/index.js
CHANGED
|
@@ -1065,6 +1065,18 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
1065
1065
|
message: `Level ${l.level} sets reminderEveryDays without reminderAfterDays, so no reminder would ever be sent.`
|
|
1066
1066
|
});
|
|
1067
1067
|
}
|
|
1068
|
+
if (l.escalationAfterHours !== void 0 && l.escalationAfterHours <= 0) {
|
|
1069
|
+
errors.push({
|
|
1070
|
+
field: `levels[${i}].escalationAfterHours`,
|
|
1071
|
+
message: `Level ${l.level} escalationAfterHours must be a positive number.`
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
if (l.escalationAfterDays !== void 0 && l.escalationAfterHours !== void 0) {
|
|
1075
|
+
errors.push({
|
|
1076
|
+
field: `levels[${i}].escalationAfterHours`,
|
|
1077
|
+
message: `Level ${l.level} sets both escalationAfterDays and escalationAfterHours; pick one so the deadline is unambiguous.`
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1068
1080
|
if (l.escalationAfterDays !== void 0 && l.escalationAfterDays <= 0) {
|
|
1069
1081
|
errors.push({
|
|
1070
1082
|
field: `levels[${i}].escalationAfterDays`,
|
|
@@ -1129,6 +1141,18 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
1129
1141
|
}
|
|
1130
1142
|
});
|
|
1131
1143
|
}
|
|
1144
|
+
if (config.slaDeadlineDays !== void 0 && config.slaDeadlineHours !== void 0) {
|
|
1145
|
+
errors.push({
|
|
1146
|
+
field: "slaDeadlineHours",
|
|
1147
|
+
message: "Template sets both slaDeadlineDays and slaDeadlineHours; pick one so the SLA is unambiguous."
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
if (config.slaDeadlineHours !== void 0 && config.slaDeadlineHours <= 0) {
|
|
1151
|
+
errors.push({
|
|
1152
|
+
field: "slaDeadlineHours",
|
|
1153
|
+
message: "slaDeadlineHours must be a positive number."
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1132
1156
|
if (config.conditions) {
|
|
1133
1157
|
config.conditions.forEach((rule, ruleIdx) => {
|
|
1134
1158
|
errors.push(...validateConditionExpression(rule.when, `conditions[${ruleIdx}].when`));
|
|
@@ -1242,7 +1266,8 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
1242
1266
|
threshold: cfg.threshold,
|
|
1243
1267
|
weights: cfg.weights,
|
|
1244
1268
|
escalationAfterDays: cfg.escalationAfterDays,
|
|
1245
|
-
|
|
1269
|
+
escalationAfterHours: cfg.escalationAfterHours,
|
|
1270
|
+
escalationDueAt: inFirstGroup ? this.levelEscalationDue(now, cfg) : void 0,
|
|
1246
1271
|
subWorkflowTemplate: cfg.subWorkflow?.templateName,
|
|
1247
1272
|
reminderAfterDays: cfg.reminderAfterDays,
|
|
1248
1273
|
reminderEveryDays: cfg.reminderEveryDays,
|
|
@@ -1272,7 +1297,7 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
1272
1297
|
timestamp: now,
|
|
1273
1298
|
...auditCtx
|
|
1274
1299
|
};
|
|
1275
|
-
const slaDeadlineAt = template.slaDeadlineDays ? this.deadlineFrom(now, template.slaDeadlineDays) : void 0;
|
|
1300
|
+
const slaDeadlineAt = template.slaDeadlineHours ? this.deadlineFromHours(now, template.slaDeadlineHours) : template.slaDeadlineDays ? this.deadlineFrom(now, template.slaDeadlineDays) : void 0;
|
|
1276
1301
|
const instance = {
|
|
1277
1302
|
id: instanceId,
|
|
1278
1303
|
tenantId: this.tenantId,
|
|
@@ -1300,6 +1325,7 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
1300
1325
|
templateSnapshot: {
|
|
1301
1326
|
escalation: template.escalation,
|
|
1302
1327
|
slaDeadlineDays: template.slaDeadlineDays,
|
|
1328
|
+
slaDeadlineHours: template.slaDeadlineHours,
|
|
1303
1329
|
allowOverride: template.allowOverride
|
|
1304
1330
|
}
|
|
1305
1331
|
};
|
|
@@ -2571,7 +2597,7 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
2571
2597
|
reason: opts.reason,
|
|
2572
2598
|
...auditCtx
|
|
2573
2599
|
};
|
|
2574
|
-
const slaDeadlineAt = template.slaDeadlineDays ? this.deadlineFrom(now, template.slaDeadlineDays) : void 0;
|
|
2600
|
+
const slaDeadlineAt = template.slaDeadlineHours ? this.deadlineFromHours(now, template.slaDeadlineHours) : template.slaDeadlineDays ? this.deadlineFrom(now, template.slaDeadlineDays) : void 0;
|
|
2575
2601
|
const newInstance = {
|
|
2576
2602
|
id: newInstanceId,
|
|
2577
2603
|
tenantId: this.tenantId,
|
|
@@ -2594,6 +2620,7 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
2594
2620
|
templateSnapshot: {
|
|
2595
2621
|
escalation: template.escalation,
|
|
2596
2622
|
slaDeadlineDays: template.slaDeadlineDays,
|
|
2623
|
+
slaDeadlineHours: template.slaDeadlineHours,
|
|
2597
2624
|
allowOverride: template.allowOverride
|
|
2598
2625
|
}
|
|
2599
2626
|
};
|
|
@@ -3536,6 +3563,24 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
3536
3563
|
deadlineFrom(from, days) {
|
|
3537
3564
|
return this.calendar ? this.calendar.addBusinessDays(from, days) : new Date(from.getTime() + days * 864e5);
|
|
3538
3565
|
}
|
|
3566
|
+
/**
|
|
3567
|
+
* Resolve an hour-based deadline.
|
|
3568
|
+
*
|
|
3569
|
+
* A calendar that only knows whole days — `weekendCalendar`, say — has no
|
|
3570
|
+
* `addBusinessHours`, and this falls back to elapsed clock time rather than
|
|
3571
|
+
* quietly pretending the calendar was applied. Configure
|
|
3572
|
+
* `businessHoursCalendar` to have hours skip evenings and weekends.
|
|
3573
|
+
*/
|
|
3574
|
+
deadlineFromHours(from, hours) {
|
|
3575
|
+
const addHours = this.calendar?.addBusinessHours?.bind(this.calendar);
|
|
3576
|
+
return addHours ? addHours(from, hours) : new Date(from.getTime() + hours * 36e5);
|
|
3577
|
+
}
|
|
3578
|
+
/** Level deadline from whichever of days/hours the template configured. */
|
|
3579
|
+
levelEscalationDue(from, level) {
|
|
3580
|
+
if (level.escalationAfterHours) return this.deadlineFromHours(from, level.escalationAfterHours);
|
|
3581
|
+
if (level.escalationAfterDays) return this.deadlineFrom(from, level.escalationAfterDays);
|
|
3582
|
+
return void 0;
|
|
3583
|
+
}
|
|
3539
3584
|
async requireInstance(id) {
|
|
3540
3585
|
const instance = await this.opts.adapter.getInstance(this.tenantId, id);
|
|
3541
3586
|
if (!instance) throw new ApprovalNotFoundError("Instance", id);
|
|
@@ -3641,9 +3686,7 @@ var ApprovalEngine = class _ApprovalEngine {
|
|
|
3641
3686
|
now
|
|
3642
3687
|
);
|
|
3643
3688
|
}
|
|
3644
|
-
|
|
3645
|
-
lvl.escalationDueAt = this.deadlineFrom(now, lvl.escalationAfterDays);
|
|
3646
|
-
}
|
|
3689
|
+
lvl.escalationDueAt = this.levelEscalationDue(now, lvl);
|
|
3647
3690
|
this.scheduleReminder(lvl, now);
|
|
3648
3691
|
lvl.status = "pending";
|
|
3649
3692
|
}
|
|
@@ -4284,7 +4327,74 @@ function weekendCalendar(options = {}) {
|
|
|
4284
4327
|
}
|
|
4285
4328
|
};
|
|
4286
4329
|
}
|
|
4330
|
+
var HOUR_MS = 36e5;
|
|
4331
|
+
function businessHoursCalendar(options = {}) {
|
|
4332
|
+
const startHour = options.workdayStartHour ?? 9;
|
|
4333
|
+
const endHour = options.workdayEndHour ?? 17;
|
|
4334
|
+
if (!(endHour > startHour)) {
|
|
4335
|
+
throw new Error(
|
|
4336
|
+
`businessHoursCalendar: workdayEndHour (${endHour}) must be greater than workdayStartHour (${startHour}).`
|
|
4337
|
+
);
|
|
4338
|
+
}
|
|
4339
|
+
const weekend = new Set(options.weekendDays ?? [0, 6]);
|
|
4340
|
+
const holidays = new Set((options.holidays ?? []).map(dayKey));
|
|
4341
|
+
const isBusinessDay = (d) => !weekend.has(d.getDay()) && !holidays.has(dayKey(d));
|
|
4342
|
+
const startOfWorkday = (d) => {
|
|
4343
|
+
const out = new Date(d.getTime());
|
|
4344
|
+
out.setHours(startHour, 0, 0, 0);
|
|
4345
|
+
return out;
|
|
4346
|
+
};
|
|
4347
|
+
const endOfWorkday = (d) => {
|
|
4348
|
+
const out = new Date(d.getTime());
|
|
4349
|
+
out.setHours(endHour, 0, 0, 0);
|
|
4350
|
+
return out;
|
|
4351
|
+
};
|
|
4352
|
+
const toWorkingMoment = (from) => {
|
|
4353
|
+
const cursor = new Date(from.getTime());
|
|
4354
|
+
for (let guard = 0; guard < 3660; guard++) {
|
|
4355
|
+
if (!isBusinessDay(cursor)) {
|
|
4356
|
+
cursor.setDate(cursor.getDate() + 1);
|
|
4357
|
+
cursor.setHours(startHour, 0, 0, 0);
|
|
4358
|
+
continue;
|
|
4359
|
+
}
|
|
4360
|
+
if (cursor.getTime() < startOfWorkday(cursor).getTime()) return startOfWorkday(cursor);
|
|
4361
|
+
if (cursor.getTime() >= endOfWorkday(cursor).getTime()) {
|
|
4362
|
+
cursor.setDate(cursor.getDate() + 1);
|
|
4363
|
+
cursor.setHours(startHour, 0, 0, 0);
|
|
4364
|
+
continue;
|
|
4365
|
+
}
|
|
4366
|
+
return cursor;
|
|
4367
|
+
}
|
|
4368
|
+
throw new Error(
|
|
4369
|
+
"businessHoursCalendar: no working day found within 10 years of the start date."
|
|
4370
|
+
);
|
|
4371
|
+
};
|
|
4372
|
+
const base = weekendCalendar(options);
|
|
4373
|
+
return {
|
|
4374
|
+
addBusinessDays: base.addBusinessDays,
|
|
4375
|
+
addBusinessHours(from, hours) {
|
|
4376
|
+
if (hours <= 0 || Number.isNaN(hours)) return new Date(from.getTime());
|
|
4377
|
+
let cursor = toWorkingMoment(from);
|
|
4378
|
+
let remainingMs = Math.round(hours * HOUR_MS);
|
|
4379
|
+
for (let guard = 0; remainingMs > 0 && guard < 3660; guard++) {
|
|
4380
|
+
const dayEnd = endOfWorkday(cursor);
|
|
4381
|
+
const availableMs = dayEnd.getTime() - cursor.getTime();
|
|
4382
|
+
if (remainingMs <= availableMs) {
|
|
4383
|
+
return new Date(cursor.getTime() + remainingMs);
|
|
4384
|
+
}
|
|
4385
|
+
remainingMs -= availableMs;
|
|
4386
|
+
const next = new Date(cursor.getTime());
|
|
4387
|
+
next.setDate(next.getDate() + 1);
|
|
4388
|
+
next.setHours(startHour, 0, 0, 0);
|
|
4389
|
+
cursor = toWorkingMoment(next);
|
|
4390
|
+
}
|
|
4391
|
+
throw new Error(
|
|
4392
|
+
`businessHoursCalendar: ${hours} working hours could not be scheduled within 10 years \u2014 check weekendDays and holidays.`
|
|
4393
|
+
);
|
|
4394
|
+
}
|
|
4395
|
+
};
|
|
4396
|
+
}
|
|
4287
4397
|
|
|
4288
|
-
export { ApprovalConflictError, ApprovalEngine, ApprovalError, ApprovalForbiddenError, ApprovalNotFoundError, ApprovalTemplateNotFoundError, ApprovalValidationError, EscalationScheduler, MemoryAdapter, TEMPLATE_BUNDLE_VERSION, defaultIdGenerator, noopLogger, systemClock, toComparableNumber, validateConditionExpression, weekendCalendar };
|
|
4398
|
+
export { ApprovalConflictError, ApprovalEngine, ApprovalError, ApprovalForbiddenError, ApprovalNotFoundError, ApprovalTemplateNotFoundError, ApprovalValidationError, EscalationScheduler, MemoryAdapter, TEMPLATE_BUNDLE_VERSION, businessHoursCalendar, defaultIdGenerator, noopLogger, systemClock, toComparableNumber, validateConditionExpression, weekendCalendar };
|
|
4289
4399
|
//# sourceMappingURL=index.js.map
|
|
4290
4400
|
//# sourceMappingURL=index.js.map
|