hierarchical-approval 4.0.2 → 4.0.3

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 (72) hide show
  1. package/CHANGELOG.md +20 -4
  2. package/dist/{ApprovalEngine-Dqe-rC6K.d.ts → ApprovalEngine-BtgQDr_8.d.ts} +13 -9
  3. package/dist/{ApprovalEngine-XgGBQLC_.d.cts → ApprovalEngine-Djdw-JzA.d.cts} +13 -9
  4. package/dist/Clock-D8Qp39q_.d.cts +8 -0
  5. package/dist/Clock-D8Qp39q_.d.ts +8 -0
  6. package/dist/{IAuditAdapter-DkbyFFjb.d.ts → IAuditAdapter-C-04ar9A.d.ts} +1 -1
  7. package/dist/{IAuditAdapter-Dt8qjkQL.d.cts → IAuditAdapter-TT2Xhtu6.d.cts} +1 -1
  8. package/dist/{IAuthorizationPolicy-eo6glbpE.d.ts → IAuthorizationPolicy-D6tTT3gv.d.cts} +6 -1
  9. package/dist/{IAuthorizationPolicy-YJ_08Mof.d.cts → IAuthorizationPolicy-wIE1mpTy.d.ts} +6 -1
  10. package/dist/{IMetricsAdapter-DWq8IFaf.d.cts → IMetricsAdapter-WROxYSXd.d.cts} +1 -0
  11. package/dist/{IMetricsAdapter-DWq8IFaf.d.ts → IMetricsAdapter-WROxYSXd.d.ts} +1 -0
  12. package/dist/{INotificationAdapter-BTO9FSKy.d.ts → INotificationAdapter-BcUskJ6z.d.ts} +9 -1
  13. package/dist/{INotificationAdapter-XbD69gss.d.cts → INotificationAdapter-CBsJDk-Y.d.cts} +9 -1
  14. package/dist/{IOperationMiddleware-CX7lo4lp.d.ts → IOperationMiddleware-C7ciNnJp.d.ts} +3 -2
  15. package/dist/{IOperationMiddleware-BBLk8MIz.d.cts → IOperationMiddleware-D3Yelw9R.d.cts} +3 -2
  16. package/dist/{IStorageAdapter-CdXMggPK.d.ts → IStorageAdapter-CVvNsnnD.d.ts} +7 -1
  17. package/dist/{IStorageAdapter-Cjw5zDwQ.d.cts → IStorageAdapter-D7cy20uD.d.cts} +7 -1
  18. package/dist/{Logger-BplhlU7l.d.cts → Logger-hqFbBCtB.d.cts} +7 -0
  19. package/dist/{Logger-BplhlU7l.d.ts → Logger-hqFbBCtB.d.ts} +7 -0
  20. package/dist/adapters/MemoryAdapter.d.cts +2 -2
  21. package/dist/adapters/MemoryAdapter.d.ts +2 -2
  22. package/dist/adapters/PostgresAdapter.d.cts +2 -2
  23. package/dist/adapters/PostgresAdapter.d.ts +2 -2
  24. package/dist/index.cjs +32 -3
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +13 -13
  27. package/dist/index.d.ts +13 -13
  28. package/dist/index.js +32 -3
  29. package/dist/index.js.map +1 -1
  30. package/dist/{instance-uUQh5XW3.d.cts → instance-Dd1jQizG.d.cts} +19 -0
  31. package/dist/{instance-uUQh5XW3.d.ts → instance-Dd1jQizG.d.ts} +19 -0
  32. package/dist/nestjs.cjs +31 -2
  33. package/dist/nestjs.cjs.map +1 -1
  34. package/dist/nestjs.d.cts +10 -10
  35. package/dist/nestjs.d.ts +10 -10
  36. package/dist/nestjs.js +31 -2
  37. package/dist/nestjs.js.map +1 -1
  38. package/dist/plugins/audit.cjs.map +1 -1
  39. package/dist/plugins/audit.d.cts +3 -3
  40. package/dist/plugins/audit.d.ts +3 -3
  41. package/dist/plugins/audit.js.map +1 -1
  42. package/dist/plugins/metrics.cjs.map +1 -1
  43. package/dist/plugins/metrics.d.cts +2 -2
  44. package/dist/plugins/metrics.d.ts +2 -2
  45. package/dist/plugins/metrics.js.map +1 -1
  46. package/dist/plugins/notify.cjs.map +1 -1
  47. package/dist/plugins/notify.d.cts +4 -4
  48. package/dist/plugins/notify.d.ts +4 -4
  49. package/dist/plugins/notify.js.map +1 -1
  50. package/dist/plugins/resilience.cjs.map +1 -1
  51. package/dist/plugins/resilience.d.cts +5 -5
  52. package/dist/plugins/resilience.d.ts +5 -5
  53. package/dist/plugins/resilience.js.map +1 -1
  54. package/dist/plugins/scheduler.cjs.map +1 -1
  55. package/dist/plugins/scheduler.d.cts +2 -2
  56. package/dist/plugins/scheduler.d.ts +2 -2
  57. package/dist/plugins/scheduler.js.map +1 -1
  58. package/dist/plugins/tracing.d.cts +2 -2
  59. package/dist/plugins/tracing.d.ts +2 -2
  60. package/dist/plugins/webhook.cjs.map +1 -1
  61. package/dist/plugins/webhook.d.cts +4 -4
  62. package/dist/plugins/webhook.d.ts +4 -4
  63. package/dist/plugins/webhook.js.map +1 -1
  64. package/dist/testing.cjs +31 -2
  65. package/dist/testing.cjs.map +1 -1
  66. package/dist/testing.d.cts +10 -10
  67. package/dist/testing.d.ts +10 -10
  68. package/dist/testing.js +31 -2
  69. package/dist/testing.js.map +1 -1
  70. package/package.json +1 -1
  71. package/dist/Clock-3FnOczFJ.d.cts +0 -6
  72. package/dist/Clock-3FnOczFJ.d.ts +0 -6
package/dist/nestjs.d.cts CHANGED
@@ -1,16 +1,16 @@
1
1
  import { OnModuleDestroy, DynamicModule, ModuleMetadata, InjectionToken, OptionalFactoryDependency, Inject } from '@nestjs/common';
2
- import { a as ApprovalEngine, b as ApprovalEngineOptions } from './ApprovalEngine-XgGBQLC_.cjs';
3
- import './IStorageAdapter-Cjw5zDwQ.cjs';
4
- import './instance-uUQh5XW3.cjs';
5
- import './INotificationAdapter-XbD69gss.cjs';
2
+ import { a as ApprovalEngine, b as ApprovalEngineOptions } from './ApprovalEngine-Djdw-JzA.cjs';
3
+ import './IStorageAdapter-D7cy20uD.cjs';
4
+ import './instance-Dd1jQizG.cjs';
5
+ import './INotificationAdapter-CBsJDk-Y.cjs';
6
6
  import 'zod';
7
- import './Logger-BplhlU7l.cjs';
8
- import './Clock-3FnOczFJ.cjs';
9
- import './IOperationMiddleware-BBLk8MIz.cjs';
10
- import './IAuditAdapter-Dt8qjkQL.cjs';
11
- import './IMetricsAdapter-DWq8IFaf.cjs';
7
+ import './Logger-hqFbBCtB.cjs';
8
+ import './Clock-D8Qp39q_.cjs';
9
+ import './IOperationMiddleware-D3Yelw9R.cjs';
10
+ import './IAuditAdapter-TT2Xhtu6.cjs';
11
+ import './IMetricsAdapter-WROxYSXd.cjs';
12
12
  import './ISchedulerAdapter-DKv_QjVN.cjs';
13
- import './IAuthorizationPolicy-YJ_08Mof.cjs';
13
+ import './IAuthorizationPolicy-D6tTT3gv.cjs';
14
14
 
15
15
  /** Options for {@link HierarchicalApprovalModule.forRoot}. */
16
16
  interface HierarchicalApprovalModuleOptions extends ApprovalEngineOptions {
package/dist/nestjs.d.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  import { OnModuleDestroy, DynamicModule, ModuleMetadata, InjectionToken, OptionalFactoryDependency, Inject } from '@nestjs/common';
2
- import { a as ApprovalEngine, b as ApprovalEngineOptions } from './ApprovalEngine-Dqe-rC6K.js';
3
- import './IStorageAdapter-CdXMggPK.js';
4
- import './instance-uUQh5XW3.js';
5
- import './INotificationAdapter-BTO9FSKy.js';
2
+ import { a as ApprovalEngine, b as ApprovalEngineOptions } from './ApprovalEngine-BtgQDr_8.js';
3
+ import './IStorageAdapter-CVvNsnnD.js';
4
+ import './instance-Dd1jQizG.js';
5
+ import './INotificationAdapter-BcUskJ6z.js';
6
6
  import 'zod';
7
- import './Logger-BplhlU7l.js';
8
- import './Clock-3FnOczFJ.js';
9
- import './IOperationMiddleware-CX7lo4lp.js';
10
- import './IAuditAdapter-DkbyFFjb.js';
11
- import './IMetricsAdapter-DWq8IFaf.js';
7
+ import './Logger-hqFbBCtB.js';
8
+ import './Clock-D8Qp39q_.js';
9
+ import './IOperationMiddleware-C7ciNnJp.js';
10
+ import './IAuditAdapter-C-04ar9A.js';
11
+ import './IMetricsAdapter-WROxYSXd.js';
12
12
  import './ISchedulerAdapter-DKv_QjVN.js';
13
- import './IAuthorizationPolicy-eo6glbpE.js';
13
+ import './IAuthorizationPolicy-wIE1mpTy.js';
14
14
 
15
15
  /** Options for {@link HierarchicalApprovalModule.forRoot}. */
16
16
  interface HierarchicalApprovalModuleOptions extends ApprovalEngineOptions {
package/dist/nestjs.js CHANGED
@@ -551,6 +551,7 @@ var TemplateRegistry = class {
551
551
  delete resolved.removeLevels;
552
552
  return resolved;
553
553
  }
554
+ /** Register a new template. Throws if a template with this name already exists for the tenant. */
554
555
  async define(config) {
555
556
  const existing = await this.adapter.getTemplate(this.tenantId, config.name);
556
557
  if (existing) {
@@ -587,11 +588,13 @@ var TemplateRegistry = class {
587
588
  await this.adapter.saveTemplate(updated);
588
589
  return newId;
589
590
  }
591
+ /** Fetch a template by name. Throws if no template with this name exists for the tenant. */
590
592
  async get(name) {
591
593
  const template = await this.adapter.getTemplate(this.tenantId, name);
592
594
  if (!template) throw new ApprovalTemplateNotFoundError(name);
593
595
  return template;
594
596
  }
597
+ /** List every template registered for the tenant. */
595
598
  async list() {
596
599
  return this.adapter.listTemplates(this.tenantId);
597
600
  }
@@ -631,6 +634,32 @@ var LevelResolver = class {
631
634
  for (const [name, fn] of this.resolvers) target.register(name, fn);
632
635
  for (const [name, fn] of this.approverTypes) target.registerApproverType(name, fn);
633
636
  }
637
+ /**
638
+ * Resolve a level's `approvers` config down to a deduplicated list of user
639
+ * ids, applying out-of-office cover last so a substitute never sees a stale
640
+ * approver id.
641
+ *
642
+ * @param approvers - The level's approver configs (`user`, `role`,
643
+ * `dynamic`, or a custom type registered via {@link registerApproverType}).
644
+ * @param submittedBy - Passed through to `dynamic` resolvers and custom
645
+ * approver-type functions as routing context.
646
+ * @param data - The instance's document data, passed through the same way.
647
+ * @param orgProvider - Required to resolve `role` approvers; omit only when
648
+ * the template uses no `role` approvers.
649
+ * @param outOfOffice - Optional cover lookup, consulted after every other
650
+ * approver type has resolved.
651
+ * @param at - The moment out-of-office cover is resolved for. Defaults to
652
+ * now.
653
+ * @param substitutions - Filled with `original -> stand-in` for each
654
+ * approver replaced by out-of-office cover, so the caller can carry
655
+ * anything keyed by the original id (such as a weighted level's vote
656
+ * weight) across to the substitute.
657
+ * @returns The resolved, deduplicated approver ids (post-substitution).
658
+ * @throws {ApprovalValidationError} If no approvers resolve at all, a
659
+ * `role` approver is configured without an `orgProvider`, a `dynamic`
660
+ * approver names a resolver that was never registered, or a custom
661
+ * approver type was never registered.
662
+ */
634
663
  async resolveApprovers(approvers, submittedBy, data, orgProvider, outOfOffice, at, substitutions) {
635
664
  const resolved = [];
636
665
  for (const approver of approvers) {
@@ -1042,7 +1071,7 @@ function evaluateConditions(conditions, data) {
1042
1071
  function assertStatus(instance, expected) {
1043
1072
  if (instance.status !== expected) {
1044
1073
  throw new ApprovalError(
1045
- `Expected instance status "${expected}" but got "${instance.status}".`,
1074
+ `Instance "${instance.id}": expected status "${expected}" but got "${instance.status}".`,
1046
1075
  "INVALID_STATUS"
1047
1076
  );
1048
1077
  }
@@ -1050,7 +1079,7 @@ function assertStatus(instance, expected) {
1050
1079
  function assertApproverOnLevel(level, approverId) {
1051
1080
  if (!level.approverIds.includes(approverId)) {
1052
1081
  throw new ApprovalForbiddenError(
1053
- `User "${approverId}" is not an approver for level ${level.level}.`
1082
+ `User "${approverId}" is not an approver for level ${level.level} ("${level.name}").`
1054
1083
  );
1055
1084
  }
1056
1085
  }