@cullet/erp-core 1.0.5 → 1.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 (143) hide show
  1. package/dist/gate-engine-registry.js.map +1 -1
  2. package/dist/gate-types.d.ts +1 -1
  3. package/dist/gate-v1-payload.schema.js +43 -0
  4. package/dist/gate-v1-payload.schema.js.map +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +9 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/outcome.js.map +1 -1
  9. package/dist/policies/engines/v1/gate/index.d.ts +4 -0
  10. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  11. package/dist/policy-service.js +14 -11
  12. package/dist/policy-service.js.map +1 -1
  13. package/dist/validation-code.js +43 -9
  14. package/dist/validation-code.js.map +1 -1
  15. package/dist/validation-error.d.ts +15 -1
  16. package/dist/validation-error.js.map +1 -1
  17. package/meta.json +2 -2
  18. package/package.json +1 -1
  19. package/src/core/application/commands/command.ts +4 -4
  20. package/src/core/application/commands/index.ts +2 -2
  21. package/src/core/application/commands/requested-by.ts +3 -3
  22. package/src/core/application/index.ts +8 -8
  23. package/src/core/application/policy-error-mapper.ts +2 -2
  24. package/src/core/application/ports/index.ts +10 -6
  25. package/src/core/application/ports/policy-port.ts +6 -3
  26. package/src/core/application/ports/temporal-repository.port.ts +2 -2
  27. package/src/core/application/queries/index.ts +2 -2
  28. package/src/core/application/queries/query.ts +4 -4
  29. package/src/core/application/temporal/index.ts +2 -2
  30. package/src/core/application/temporal/temporal-context.ts +2 -2
  31. package/src/core/application/temporal/temporal-use-case.ts +4 -4
  32. package/src/core/application/use-case.ts +3 -3
  33. package/src/core/config/core-config.instance.ts +2 -2
  34. package/src/core/config/core-config.ts +3 -3
  35. package/src/core/config/index.ts +8 -5
  36. package/src/core/config/policy-reporter.ts +3 -3
  37. package/src/core/config/silent-policy-reporter.ts +1 -1
  38. package/src/core/domain/entity.ts +11 -5
  39. package/src/core/domain/rulesets/entity-ruleset.contracts.ts +2 -2
  40. package/src/core/domain/rulesets/ruleset-registry.ts +2 -2
  41. package/src/core/domain/rulesets/value-object-ruleset.contracts.ts +2 -2
  42. package/src/core/domain/temporal/index.ts +4 -4
  43. package/src/core/domain/temporal/temporal-range.ts +2 -2
  44. package/src/core/domain/temporal/temporal-snapshot.ts +3 -3
  45. package/src/core/domain/temporal/transaction-time.ts +3 -3
  46. package/src/core/domain/temporal/valid-time.ts +3 -3
  47. package/src/core/domain/value-object.ts +3 -3
  48. package/src/core/errors/app-error.ts +6 -2
  49. package/src/core/errors/authentication-error.ts +3 -3
  50. package/src/core/errors/authorization-error.ts +3 -3
  51. package/src/core/errors/business-rule-violation-error.ts +3 -3
  52. package/src/core/errors/conflict-error.ts +3 -3
  53. package/src/core/errors/idempotency-error.ts +3 -3
  54. package/src/core/errors/index.ts +23 -23
  55. package/src/core/errors/integration-error.ts +3 -3
  56. package/src/core/errors/legacy-incompatible-error.ts +3 -3
  57. package/src/core/errors/not-found-error.ts +3 -3
  58. package/src/core/errors/serialization-error.ts +3 -3
  59. package/src/core/errors/temporal-error.ts +3 -3
  60. package/src/core/errors/unexpected-error.ts +3 -3
  61. package/src/core/errors/utils/index.ts +2 -1
  62. package/src/core/errors/utils/json-safe.ts +25 -7
  63. package/src/core/errors/validation-error.ts +5 -5
  64. package/src/core/exceptions/business-rule-violation-exception.ts +1 -1
  65. package/src/core/exceptions/entity-not-found-exception.ts +1 -1
  66. package/src/core/exceptions/invalid-state-transition-exception.ts +1 -1
  67. package/src/core/exceptions/invariant-violation-exception.ts +1 -1
  68. package/src/core/exceptions/validation-exception.ts +3 -3
  69. package/src/core/index.ts +7 -7
  70. package/src/core/policies/asof/asof.ts +4 -4
  71. package/src/core/policies/asof/index.ts +2 -2
  72. package/src/core/policies/catalog/catalog.instance.ts +3 -3
  73. package/src/core/policies/catalog/index.ts +6 -6
  74. package/src/core/policies/catalog/policy-catalog-entry.ts +3 -3
  75. package/src/core/policies/catalog/policy-catalog.ts +3 -3
  76. package/src/core/policies/catalog/policy-key.ts +1 -1
  77. package/src/core/policies/context/context-builder.ts +5 -5
  78. package/src/core/policies/context/context-registry.instance.ts +3 -3
  79. package/src/core/policies/context/context-registry.ts +2 -2
  80. package/src/core/policies/context/context-resolver.ts +2 -2
  81. package/src/core/policies/context/context-seed.ts +2 -2
  82. package/src/core/policies/context/index.ts +9 -9
  83. package/src/core/policies/context/path.ts +1 -1
  84. package/src/core/policies/defs/in-memory-policy-definition-repo.ts +3 -3
  85. package/src/core/policies/defs/index.ts +8 -8
  86. package/src/core/policies/defs/policy-definition-repository.ts +1 -1
  87. package/src/core/policies/defs/policy-definition.ts +6 -6
  88. package/src/core/policies/defs/policy-payload.contracts.ts +1 -1
  89. package/src/core/policies/defs/policy-scope.ts +2 -2
  90. package/src/core/policies/defs/policy-semver.ts +12 -5
  91. package/src/core/policies/engines/compute-engine-registry.ts +9 -6
  92. package/src/core/policies/engines/compute-evaluator-registry.ts +1 -1
  93. package/src/core/policies/engines/compute-payload.ts +1 -1
  94. package/src/core/policies/engines/compute-registry.ts +7 -7
  95. package/src/core/policies/engines/compute-types.ts +4 -4
  96. package/src/core/policies/engines/condition-evaluator-reporter.ts +2 -0
  97. package/src/core/policies/engines/gate-engine-registry.ts +3 -3
  98. package/src/core/policies/engines/gate-payload.ts +1 -1
  99. package/src/core/policies/engines/gate-types.ts +3 -3
  100. package/src/core/policies/engines/index.ts +14 -14
  101. package/src/core/policies/engines/parse-compute-payload.ts +4 -4
  102. package/src/core/policies/engines/parse-gate-payload.ts +4 -4
  103. package/src/core/policies/engines/v1/compute/compute-engine-v1.ts +6 -6
  104. package/src/core/policies/engines/v1/compute/compute-payload.schema.ts +3 -3
  105. package/src/core/policies/engines/v1/compute/index.ts +4 -4
  106. package/src/core/policies/engines/v1/compute/resolve-decision-table-v1.ts +4 -4
  107. package/src/core/policies/engines/v1/condition-evaluator.ts +90 -6
  108. package/src/core/policies/engines/v1/condition-schema.ts +1 -1
  109. package/src/core/policies/engines/v1/gate/gate-engine-v1.ts +7 -7
  110. package/src/core/policies/engines/v1/gate/gate-types-v1.ts +1 -1
  111. package/src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts +3 -3
  112. package/src/core/policies/engines/v1/gate/index.ts +4 -4
  113. package/src/core/policies/engines/v1/index.ts +3 -3
  114. package/src/core/policies/index.ts +30 -23
  115. package/src/core/policies/package/policy-package.ts +3 -3
  116. package/src/core/policies/policy-ids.ts +3 -3
  117. package/src/core/policies/resolver/index.ts +1 -1
  118. package/src/core/policies/resolver/policy-resolver.ts +4 -4
  119. package/src/core/policies/service/index.ts +3 -3
  120. package/src/core/policies/service/policy-evaluation-error.ts +1 -1
  121. package/src/core/policies/service/policy-service.ts +21 -14
  122. package/src/core/policies/utils/date.ts +1 -1
  123. package/src/core/policies/utils/hash.ts +23 -11
  124. package/src/core/policies/utils/index.ts +3 -3
  125. package/src/core/policies/utils/result.ts +1 -1
  126. package/src/core/result/outcome.ts +1 -1
  127. package/src/core/shared/aggregate-version.ts +1 -1
  128. package/src/core/shared/hashing.ts +33 -4
  129. package/src/core/shared/immutable.ts +13 -2
  130. package/src/core/shared/temporal-guards.ts +1 -1
  131. package/src/core/versioning/domain-event-contracts.ts +5 -5
  132. package/src/examples/rulesets/entity/order-creation-rules-v1.ts +2 -2
  133. package/src/examples/rulesets/entity/order-invariants-v1.ts +2 -2
  134. package/src/examples/rulesets/entity/order-invariants-v2.ts +3 -3
  135. package/src/examples/rulesets/entity/order.ts +1 -1
  136. package/src/examples/rulesets/value-object/cpf-rules-v1.ts +1 -1
  137. package/src/examples/rulesets/value-object/cpf-rules-v2.ts +2 -2
  138. package/src/examples/rulesets/value-object/cpf.ts +1 -1
  139. package/src/examples/rulesets/value-object/customer.ts +3 -3
  140. package/src/examples/rulesets/value-object/person-name-rules-v1.ts +1 -1
  141. package/src/examples/rulesets/value-object/person-name-rules-v2.ts +2 -2
  142. package/src/examples/rulesets/value-object/person-name.ts +1 -1
  143. package/src/version.ts +1 -1
@@ -1,6 +1,6 @@
1
- import { AppError } from "./app-error";
2
- import { serializationErrorCode } from "./error-codes";
3
- import type { AppErrorOptions } from "./types";
1
+ import { AppError } from "./app-error.js";
2
+ import { serializationErrorCode } from "./error-codes.js";
3
+ import type { AppErrorOptions } from "./types.js";
4
4
 
5
5
  // ─────────────────────────────────────────────────────────────────────────────
6
6
  // Types
@@ -1,6 +1,6 @@
1
- import { AppError } from "./app-error";
2
- import { ErrorCodes } from "./error-codes";
3
- import type { AppErrorOptions } from "./types";
1
+ import { AppError } from "./app-error.js";
2
+ import { ErrorCodes } from "./error-codes.js";
3
+ import type { AppErrorOptions } from "./types.js";
4
4
 
5
5
  type TemporalKind = "expired" | "not_yet_valid";
6
6
 
@@ -1,6 +1,6 @@
1
- import { AppError } from "./app-error";
2
- import { ErrorCodes } from "./error-codes";
3
- import type { AppErrorOptions } from "./types";
1
+ import { AppError } from "./app-error.js";
2
+ import { ErrorCodes } from "./error-codes.js";
3
+ import type { AppErrorOptions } from "./types.js";
4
4
 
5
5
  // ─────────────────────────────────────────────────────────────────────────────
6
6
  // UnexpectedError
@@ -1,4 +1,5 @@
1
1
  export {
2
2
  assertJsonSafeMetadata,
3
+ CIRCULAR_REFERENCE_PLACEHOLDER,
3
4
  NON_SERIALIZABLE_PLACEHOLDER,
4
- } from "./json-safe";
5
+ } from "./json-safe.js";
@@ -1,12 +1,13 @@
1
1
  // Utilities for ensuring metadata is JSON-serializable.
2
2
 
3
- import type { JsonSafeRecord, JsonSafeValue } from "../types";
3
+ import type { JsonSafeRecord, JsonSafeValue } from "../types.js";
4
4
 
5
5
  // ─────────────────────────────────────────────────────────────────────────────
6
6
  // Constants
7
7
  // ─────────────────────────────────────────────────────────────────────────────
8
8
 
9
9
  const NON_SERIALIZABLE_PLACEHOLDER = "[NonSerializable]";
10
+ const CIRCULAR_REFERENCE_PLACEHOLDER = "[Circular]";
10
11
 
11
12
  // ─────────────────────────────────────────────────────────────────────────────
12
13
  // Internal helpers
@@ -18,7 +19,12 @@ function isPlainObject(value: unknown): value is Record<string, unknown> {
18
19
  return proto === Object.prototype || proto === null;
19
20
  }
20
21
 
21
- function sanitizeValue(value: unknown): JsonSafeValue {
22
+ // `seen` tracks the ancestors on the current traversal branch (a DFS path), not
23
+ // every object visited. This collapses true circular references to a placeholder
24
+ // while still serializing the same object referenced more than once across
25
+ // sibling branches (a DAG) — matching `JSON.stringify`, which only rejects
26
+ // cycles, not shared references.
27
+ function sanitizeValue(value: unknown, seen: WeakSet<object>): JsonSafeValue {
22
28
  // Null passthrough
23
29
  if (value === null) return null;
24
30
 
@@ -41,7 +47,11 @@ function sanitizeValue(value: unknown): JsonSafeValue {
41
47
 
42
48
  // Arrays (recursive)
43
49
  if (Array.isArray(value)) {
44
- return value.map(sanitizeValue);
50
+ if (seen.has(value)) return CIRCULAR_REFERENCE_PLACEHOLDER;
51
+ seen.add(value);
52
+ const sanitized = value.map((item) => sanitizeValue(item, seen));
53
+ seen.delete(value);
54
+ return sanitized;
45
55
  }
46
56
 
47
57
  // Date → placeholder (could also use .toISOString() if preferred)
@@ -55,10 +65,13 @@ function sanitizeValue(value: unknown): JsonSafeValue {
55
65
  }
56
66
 
57
67
  // Plain object (recursive)
68
+ if (seen.has(value)) return CIRCULAR_REFERENCE_PLACEHOLDER;
69
+ seen.add(value);
58
70
  const result: Record<string, JsonSafeValue> = {};
59
71
  for (const [key, val] of Object.entries(value)) {
60
- result[key] = sanitizeValue(val);
72
+ result[key] = sanitizeValue(val, seen);
61
73
  }
74
+ seen.delete(value);
62
75
  return result;
63
76
  }
64
77
 
@@ -72,7 +85,8 @@ function sanitizeValue(value: unknown): JsonSafeValue {
72
85
  * **Allowed:** string, number, boolean, null, arrays, and plain objects.
73
86
  *
74
87
  * **Converted to placeholder:** Date, BigInt, class instances, functions,
75
- * symbols, undefined.
88
+ * symbols, undefined, and circular references (which would otherwise make
89
+ * `JSON.stringify` throw).
76
90
  *
77
91
  * @throws {TypeError} If `input` is not a plain object at the root level.
78
92
  */
@@ -87,7 +101,11 @@ function assertJsonSafeMetadata(input: unknown): JsonSafeRecord {
87
101
  );
88
102
  }
89
103
 
90
- return sanitizeValue(input) as JsonSafeRecord;
104
+ return sanitizeValue(input, new WeakSet<object>()) as JsonSafeRecord;
91
105
  }
92
106
 
93
- export { assertJsonSafeMetadata, NON_SERIALIZABLE_PLACEHOLDER };
107
+ export {
108
+ assertJsonSafeMetadata,
109
+ CIRCULAR_REFERENCE_PLACEHOLDER,
110
+ NON_SERIALIZABLE_PLACEHOLDER,
111
+ };
@@ -1,9 +1,9 @@
1
- import { ValidationCode } from "../exceptions/validation-code";
2
- import { ValidationField } from "../exceptions/validation-field";
1
+ import { ValidationCode } from "../exceptions/validation-code.js";
2
+ import { ValidationField } from "../exceptions/validation-field.js";
3
3
 
4
- import { AppError } from "./app-error";
5
- import { ErrorCodes } from "./error-codes";
6
- import type { AppErrorOptions } from "./types";
4
+ import { AppError } from "./app-error.js";
5
+ import { ErrorCodes } from "./error-codes.js";
6
+ import type { AppErrorOptions } from "./types.js";
7
7
 
8
8
  // ─────────────────────────────────────────────────────────────────────────────
9
9
  // ValidationError
@@ -1,4 +1,4 @@
1
- import { DomainException } from "./domain-exception";
1
+ import { DomainException } from "./domain-exception.js";
2
2
 
3
3
  class BusinessRuleViolationException extends DomainException {
4
4
  constructor(
@@ -1,4 +1,4 @@
1
- import { DomainException } from "./domain-exception";
1
+ import { DomainException } from "./domain-exception.js";
2
2
 
3
3
  class EntityNotFoundException extends DomainException {
4
4
  constructor(
@@ -1,4 +1,4 @@
1
- import { DomainException } from "./domain-exception";
1
+ import { DomainException } from "./domain-exception.js";
2
2
 
3
3
  class InvalidStateTransitionException<
4
4
  TState extends string = string,
@@ -1,4 +1,4 @@
1
- import { DomainException } from "./domain-exception";
1
+ import { DomainException } from "./domain-exception.js";
2
2
 
3
3
  class InvariantViolationException extends DomainException {
4
4
  constructor(message: string) {
@@ -1,6 +1,6 @@
1
- import { DomainException } from "./domain-exception";
2
- import { ValidationCode } from "./validation-code";
3
- import { ValidationField } from "./validation-field";
1
+ import { DomainException } from "./domain-exception.js";
2
+ import { ValidationCode } from "./validation-code.js";
3
+ import { ValidationField } from "./validation-field.js";
4
4
 
5
5
  export interface ValidationViolation {
6
6
  readonly field: ValidationField;
package/src/core/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- export * from "./errors";
2
- export * from "./exceptions/validation-field";
1
+ export * from "./errors/index.js";
2
+ export * from "./exceptions/validation-field.js";
3
3
  export type {
4
4
  LogPayload,
5
5
  LoggerPort,
@@ -8,8 +8,8 @@ export type {
8
8
  TraceAttributeValue,
9
9
  TraceSpan,
10
10
  TracerPort,
11
- } from "./application";
12
- export { mapPolicyEvaluationError } from "./application/policy-error-mapper";
13
- export { Entity, type EntityState } from "./domain/entity";
14
- export { ValueObject, type DeepReadonly } from "./domain/value-object";
15
- export * from "./policies";
11
+ } from "./application/index.js";
12
+ export { mapPolicyEvaluationError } from "./application/policy-error-mapper.js";
13
+ export { Entity, type EntityState } from "./domain/entity.js";
14
+ export { ValueObject, type DeepReadonly } from "./domain/value-object.js";
15
+ export * from "./policies/index.js";
@@ -1,7 +1,7 @@
1
- import type { AsOfSource } from "../catalog";
2
- import type { ContextSeed } from "../context";
3
- import { Result } from "../../result/result";
4
- import { isValidDate } from "../../shared/temporal-guards";
1
+ import type { AsOfSource } from "../catalog/index.js";
2
+ import type { ContextSeed } from "../context/index.js";
3
+ import { Result } from "../../result/result.js";
4
+ import { isValidDate } from "../../shared/temporal-guards.js";
5
5
 
6
6
  const DEFAULT_MAX_AS_OF_FUTURE_YEARS = 10;
7
7
 
@@ -1,2 +1,2 @@
1
- export { PolicyAsOfResolver } from "./asof";
2
- export type { DeriveAsOfOptions } from "./asof";
1
+ export { PolicyAsOfResolver } from "./asof.js";
2
+ export type { DeriveAsOfOptions } from "./asof.js";
@@ -1,7 +1,7 @@
1
- import type { PolicyPackage } from "../package/policy-package";
1
+ import type { PolicyPackage } from "../package/policy-package.js";
2
2
 
3
- import { PolicyCatalog } from "./policy-catalog";
4
- import { PolicyCatalogEntry } from "./policy-catalog-entry";
3
+ import { PolicyCatalog } from "./policy-catalog.js";
4
+ import { PolicyCatalogEntry } from "./policy-catalog-entry.js";
5
5
 
6
6
  // ─── Factory ────────────────────────────────────────────────────────────────
7
7
 
@@ -3,9 +3,9 @@ export type {
3
3
  PolicyKind,
4
4
  PolicyOwner,
5
5
  PolicyScopeLevel,
6
- } from "./catalog-types";
7
- export type { PolicyCatalogEntryProps } from "./policy-catalog-entry";
8
- export { PolicyCatalogEntry } from "./policy-catalog-entry";
9
- export { PolicyCatalog } from "./policy-catalog";
10
- export { PolicyCatalogFactory } from "./catalog.instance";
11
- export { PolicyKey } from "./policy-key";
6
+ } from "./catalog-types.js";
7
+ export type { PolicyCatalogEntryProps } from "./policy-catalog-entry.js";
8
+ export { PolicyCatalogEntry } from "./policy-catalog-entry.js";
9
+ export { PolicyCatalog } from "./policy-catalog.js";
10
+ export { PolicyCatalogFactory } from "./catalog.instance.js";
11
+ export { PolicyKey } from "./policy-key.js";
@@ -1,12 +1,12 @@
1
- import { UnexpectedError } from "../../errors";
1
+ import { UnexpectedError } from "../../errors/index.js";
2
2
 
3
3
  import type {
4
4
  AsOfSource,
5
5
  PolicyKind,
6
6
  PolicyOwner,
7
7
  PolicyScopeLevel,
8
- } from "./catalog-types";
9
- import type { PolicyKey } from "./policy-key";
8
+ } from "./catalog-types.js";
9
+ import type { PolicyKey } from "./policy-key.js";
10
10
 
11
11
  /**
12
12
  * Properties for creating a PolicyCatalogEntry.
@@ -1,7 +1,7 @@
1
- import { UnexpectedError } from "../../errors";
2
- import { Result } from "../../result/result";
1
+ import { UnexpectedError } from "../../errors/index.js";
2
+ import { Result } from "../../result/result.js";
3
3
 
4
- import { PolicyCatalogEntry } from "./policy-catalog-entry";
4
+ import { PolicyCatalogEntry } from "./policy-catalog-entry.js";
5
5
 
6
6
  /**
7
7
  * In-code catalog of all known policies.
@@ -1,4 +1,4 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
3
  /**
4
4
  * PolicyKey value object.
@@ -1,13 +1,13 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
- import type { ContextResolverRegistry } from "./context-registry";
3
+ import type { ContextResolverRegistry } from "./context-registry.js";
4
4
  import type {
5
5
  ContextResolverResilienceOptions,
6
6
  ContextResolverRetryOptions,
7
7
  ContextValueResolver,
8
- } from "./context-resolver";
9
- import type { ContextSeed } from "./context-seed";
10
- import { PolicyContextPath } from "./path";
8
+ } from "./context-resolver.js";
9
+ import type { ContextSeed } from "./context-seed.js";
10
+ import { PolicyContextPath } from "./path.js";
11
11
 
12
12
  interface NormalizedContextResolverRetryOptions {
13
13
  readonly maxAttempts: number;
@@ -1,11 +1,11 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
3
  import {
4
4
  ContextResolverRegistry,
5
5
  registerNamespacedContextResolversIn,
6
- } from "./context-registry";
6
+ } from "./context-registry.js";
7
7
 
8
- import type { ContextValueResolver } from "./context-resolver";
8
+ import type { ContextValueResolver } from "./context-resolver.js";
9
9
 
10
10
  /**
11
11
  * Official instance of the ContextResolverRegistry.
@@ -1,6 +1,6 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
- import type { ContextValueResolver } from "./context-resolver";
3
+ import type { ContextValueResolver } from "./context-resolver.js";
4
4
 
5
5
  export interface ContextResolverRegistrationOptions {
6
6
  readonly namespace?: string;
@@ -1,6 +1,6 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
- import type { ContextSeed } from "./context-seed";
3
+ import type { ContextSeed } from "./context-seed.js";
4
4
 
5
5
  export interface ContextResolverRetryOptions {
6
6
  readonly maxAttempts?: number;
@@ -1,6 +1,6 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
- import type { SchoolId, TenantId } from "../policy-ids";
3
+ import type { SchoolId, TenantId } from "../policy-ids.js";
4
4
 
5
5
  /**
6
6
  * Seed data provided by the use case / caller.
@@ -1,21 +1,21 @@
1
- export { PolicyContextBuilder } from "./context-builder";
1
+ export { PolicyContextBuilder } from "./context-builder.js";
2
2
  export {
3
3
  ContextResolverRegistry,
4
4
  DEFAULT_CONTEXT_RESOLVER_NAMESPACE,
5
5
  registerNamespacedContextResolversIn,
6
- } from "./context-registry";
6
+ } from "./context-registry.js";
7
7
  export {
8
8
  contextResolverRegistry,
9
9
  registerNamespacedContextResolvers,
10
- } from "./context-registry.instance";
11
- export type { ContextResolverRegistrationOptions } from "./context-registry";
10
+ } from "./context-registry.instance.js";
11
+ export type { ContextResolverRegistrationOptions } from "./context-registry.js";
12
12
  export type {
13
13
  ContextResolverCircuitBreakerOptions,
14
14
  ContextResolverResilienceOptions,
15
15
  ContextResolverRetryOptions,
16
16
  ContextValueResolver,
17
- } from "./context-resolver";
18
- export type { PolicyContextBuilderOptions } from "./context-builder";
19
- export { ContextSeedValidator } from "./context-seed";
20
- export type { ContextSeed } from "./context-seed";
21
- export { PolicyContextPath } from "./path";
17
+ } from "./context-resolver.js";
18
+ export type { PolicyContextBuilderOptions } from "./context-builder.js";
19
+ export { ContextSeedValidator } from "./context-seed.js";
20
+ export type { ContextSeed } from "./context-seed.js";
21
+ export { PolicyContextPath } from "./path.js";
@@ -3,7 +3,7 @@
3
3
  * in plain objects, e.g. "installment.dueDate".
4
4
  */
5
5
 
6
- import { Result } from "../../result/result";
6
+ import { Result } from "../../result/result.js";
7
7
 
8
8
  export class PolicyContextPath {
9
9
  private static readonly FORBIDDEN_SEGMENTS = new Set([
@@ -1,9 +1,9 @@
1
1
  import type {
2
2
  FindCandidatesParams,
3
3
  PolicyDefinition,
4
- } from "./policy-definition";
5
- import type { PolicyDefinitionRepository } from "./policy-definition-repository";
6
- import { PolicyScopeMatcher } from "./policy-scope";
4
+ } from "./policy-definition.js";
5
+ import type { PolicyDefinitionRepository } from "./policy-definition-repository.js";
6
+ import { PolicyScopeMatcher } from "./policy-scope.js";
7
7
 
8
8
  export class InMemoryPolicyDefinitionRepository implements PolicyDefinitionRepository {
9
9
  private readonly definitions: readonly PolicyDefinition[];
@@ -1,4 +1,4 @@
1
- export { InMemoryPolicyDefinitionRepository } from "./in-memory-policy-definition-repo";
1
+ export { InMemoryPolicyDefinitionRepository } from "./in-memory-policy-definition-repo.js";
2
2
  export type {
3
3
  BasePolicyDefinitionProps,
4
4
  ComputePolicyDefinitionInput,
@@ -8,13 +8,13 @@ export type {
8
8
  GatePolicyDefinitionProps,
9
9
  PolicyDefinitionProps,
10
10
  PolicyDefinitionStatus,
11
- } from "./policy-definition";
12
- export { PolicyDefinition } from "./policy-definition";
13
- export type { PolicyDefinitionRepository } from "./policy-definition-repository";
11
+ } from "./policy-definition.js";
12
+ export { PolicyDefinition } from "./policy-definition.js";
13
+ export type { PolicyDefinitionRepository } from "./policy-definition-repository.js";
14
14
  export type {
15
15
  AnyPolicyPayload,
16
16
  PayloadForKey,
17
- } from "./policy-payload.contracts";
18
- export { comparePolicySemver, POLICY_SEMVER_PATTERN } from "./policy-semver";
19
- export type { PolicyScope, ScopeChain } from "./policy-scope";
20
- export { PolicyScopeMatcher } from "./policy-scope";
17
+ } from "./policy-payload.contracts.js";
18
+ export { comparePolicySemver, POLICY_SEMVER_PATTERN } from "./policy-semver.js";
19
+ export type { PolicyScope, ScopeChain } from "./policy-scope.js";
20
+ export { PolicyScopeMatcher } from "./policy-scope.js";
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  FindCandidatesParams,
3
3
  PolicyDefinition,
4
- } from "./policy-definition";
4
+ } from "./policy-definition.js";
5
5
 
6
6
  export interface PolicyDefinitionRepository {
7
7
  findCandidates(params: FindCandidatesParams): PolicyDefinition[];
@@ -1,10 +1,10 @@
1
- import { InvariantViolationException } from "../../exceptions/invariant-violation-exception";
2
- import type { PolicyKind } from "../catalog";
3
- import type { PolicyDefinitionId } from "../policy-ids";
1
+ import { InvariantViolationException } from "../../exceptions/invariant-violation-exception.js";
2
+ import type { PolicyKind } from "../catalog/index.js";
3
+ import type { PolicyDefinitionId } from "../policy-ids.js";
4
4
 
5
- import type { AnyPolicyPayload } from "./policy-payload.contracts";
6
- import type { PolicyScope } from "./policy-scope";
7
- import { POLICY_SEMVER_PATTERN } from "./policy-semver";
5
+ import type { AnyPolicyPayload } from "./policy-payload.contracts.js";
6
+ import type { PolicyScope } from "./policy-scope.js";
7
+ import { POLICY_SEMVER_PATTERN } from "./policy-semver.js";
8
8
 
9
9
  // ─── Status ────────────────────────────────────────────────────────────────
10
10
 
@@ -1,4 +1,4 @@
1
- import type { ComputePayload, GatePayload } from "../engines";
1
+ import type { ComputePayload, GatePayload } from "../engines/index.js";
2
2
 
3
3
  export type AnyPolicyPayload = GatePayload | ComputePayload;
4
4
 
@@ -1,5 +1,5 @@
1
- import type { PolicyScopeLevel } from "../catalog";
2
- import type { SchoolId, TenantId } from "../policy-ids";
1
+ import type { PolicyScopeLevel } from "../catalog/index.js";
2
+ import type { SchoolId, TenantId } from "../policy-ids.js";
3
3
 
4
4
  /**
5
5
  * Scope attached to a PolicyDefinition — defines where it applies.
@@ -12,16 +12,23 @@ interface ParsedSemver {
12
12
 
13
13
  function parseSemver(version: string): ParsedSemver {
14
14
  const withoutBuild = version.split("+")[0];
15
- const [core, preRelease = null] = withoutBuild.split("-") as [
16
- string,
17
- string | undefined,
18
- ];
15
+
16
+ // Split on the first hyphen only. A pre-release identifier may itself
17
+ // contain hyphens (e.g. "1.0.0-x-1"); `split("-")` would drop everything
18
+ // after the first one and corrupt the comparison.
19
+ const dashIndex = withoutBuild.indexOf("-");
20
+ const core =
21
+ dashIndex === -1 ? withoutBuild : withoutBuild.slice(0, dashIndex);
22
+ const preRelease =
23
+ dashIndex === -1 ? null : withoutBuild.slice(dashIndex + 1);
24
+
19
25
  const [major, minor, patch] = core.split(".").map(Number) as [
20
26
  number,
21
27
  number,
22
28
  number,
23
29
  ];
24
- return { major, minor, patch, preRelease: preRelease ?? null };
30
+
31
+ return { major, minor, patch, preRelease };
25
32
  }
26
33
 
27
34
  function comparePreRelease(a: string, b: string): number {
@@ -1,9 +1,12 @@
1
- import { Result } from "../../result/result";
2
-
3
- import type { PolicyContext } from "./gate-types";
4
- import { ComputePayloadParsers } from "./parse-compute-payload";
5
- import type { ComputeEvaluatorRegistry } from "./compute-evaluator-registry";
6
- import type { ComputeOutcome, VersionedComputeEngine } from "./compute-types";
1
+ import { Result } from "../../result/result.js";
2
+
3
+ import type { PolicyContext } from "./gate-types.js";
4
+ import { ComputePayloadParsers } from "./parse-compute-payload.js";
5
+ import type { ComputeEvaluatorRegistry } from "./compute-evaluator-registry.js";
6
+ import type {
7
+ ComputeOutcome,
8
+ VersionedComputeEngine,
9
+ } from "./compute-types.js";
7
10
 
8
11
  export class ComputeEngineRegistry {
9
12
  private readonly engines = new Map<number, VersionedComputeEngine>();
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  ComputeEvaluator,
3
3
  ComputeEvaluatorRegistration,
4
- } from "./compute-types";
4
+ } from "./compute-types.js";
5
5
 
6
6
  export class ComputeEvaluatorRegistry {
7
7
  private readonly evaluators = new Map<string, ComputeEvaluator>();
@@ -1,4 +1,4 @@
1
- import type { ComputePayloadV1 } from "./v1/compute/compute-payload.schema";
1
+ import type { ComputePayloadV1 } from "./v1/compute/compute-payload.schema.js";
2
2
 
3
3
  export type { ComputePayloadV1 };
4
4
 
@@ -1,16 +1,16 @@
1
- import { type CoreConfig, coreConfig } from "../../config";
2
- import type { Result } from "../../result/result";
1
+ import { type CoreConfig, coreConfig } from "../../config/index.js";
2
+ import type { Result } from "../../result/result.js";
3
3
 
4
- import { ComputeEngineRegistry } from "./compute-engine-registry";
5
- import { ComputeEvaluatorRegistry } from "./compute-evaluator-registry";
6
- import type { PolicyContext } from "./gate-types";
4
+ import { ComputeEngineRegistry } from "./compute-engine-registry.js";
5
+ import { ComputeEvaluatorRegistry } from "./compute-evaluator-registry.js";
6
+ import type { PolicyContext } from "./gate-types.js";
7
7
  import type {
8
8
  ComputeEvaluator,
9
9
  ComputeEvaluatorRegistration,
10
10
  ComputeOutcome,
11
11
  VersionedComputeEngine,
12
- } from "./compute-types";
13
- import { ComputeEngineV1 } from "./v1/compute";
12
+ } from "./compute-types.js";
13
+ import { ComputeEngineV1 } from "./v1/compute/index.js";
14
14
 
15
15
  export interface ComputeRegistryOptions {
16
16
  readonly coreConfig?: CoreConfig;
@@ -1,8 +1,8 @@
1
- import type { Outcome } from "../../result/outcome";
2
- import type { Result } from "../../result/result";
1
+ import type { Outcome } from "../../result/outcome.js";
2
+ import type { Result } from "../../result/result.js";
3
3
 
4
- import type { ComputePayload } from "./compute-payload";
5
- import type { PolicyContext, PolicyViolation } from "./gate-types";
4
+ import type { ComputePayload } from "./compute-payload.js";
5
+ import type { PolicyContext, PolicyViolation } from "./gate-types.js";
6
6
 
7
7
  // ─── Compute outcome (business decision) ────────────────────────────────────
8
8
 
@@ -10,6 +10,8 @@ export type ConditionEvaluationReportTag =
10
10
  | "NULLISH_NUMERIC_OPERAND_NOT_ALLOWED"
11
11
  | "NULLISH_DATE_OPERAND_NOT_ALLOWED"
12
12
  | "INVALID_DATE_OPERAND"
13
+ | "INVALID_NUMERIC_OPERAND"
14
+ | "INVALID_SET_OPERAND"
13
15
  | "CONDITION_EVAL_THREW";
14
16
 
15
17
  export interface ConditionEvaluationReport {
@@ -1,11 +1,11 @@
1
- import { Result } from "../../result/result";
1
+ import { Result } from "../../result/result.js";
2
2
 
3
3
  import type {
4
4
  GateOutcome,
5
5
  PolicyContext,
6
6
  VersionedGateEngine,
7
- } from "./gate-types";
8
- import { GatePayloadParsers } from "./parse-gate-payload";
7
+ } from "./gate-types.js";
8
+ import { GatePayloadParsers } from "./parse-gate-payload.js";
9
9
 
10
10
  export class GateEngineRegistry {
11
11
  private readonly engines = new Map<number, VersionedGateEngine>();
@@ -1,4 +1,4 @@
1
- import type { GatePayloadV1 } from "./v1/gate/gate-types-v1";
1
+ import type { GatePayloadV1 } from "./v1/gate/gate-types-v1.js";
2
2
 
3
3
  export type { GatePayloadV1 };
4
4