@cullet/erp-core 1.1.0 → 1.2.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.
Files changed (101) hide show
  1. package/KIT_CONTEXT.md +1 -67
  2. package/dist/application/index.d.ts +1 -1
  3. package/dist/application/index.js +2 -1
  4. package/dist/domain/index.d.ts +3 -0
  5. package/dist/domain/index.js +3 -0
  6. package/dist/domain-event-contracts.d.ts +27 -0
  7. package/dist/domain-event-contracts.js +22 -0
  8. package/dist/domain-event-contracts.js.map +1 -0
  9. package/dist/domain-exception.d.ts +7 -0
  10. package/dist/domain-exception.js +12 -0
  11. package/dist/domain-exception.js.map +1 -0
  12. package/dist/errors/index.js +1 -1
  13. package/dist/exceptions/index.d.ts +5 -0
  14. package/dist/exceptions/index.js +7 -0
  15. package/dist/gate-engine-registry.d.ts +2 -1
  16. package/dist/gate-engine-registry.js +2 -1
  17. package/dist/gate-engine-registry.js.map +1 -1
  18. package/dist/gate-types.d.ts +3 -139
  19. package/dist/gate-v1-payload.schema.js +2 -116
  20. package/dist/gate-v1-payload.schema.js.map +1 -1
  21. package/dist/immutable.d.ts +6 -0
  22. package/dist/immutable.js +54 -0
  23. package/dist/immutable.js.map +1 -0
  24. package/dist/index.d.ts +15 -160
  25. package/dist/index.js +19 -176
  26. package/dist/index.js.map +1 -1
  27. package/dist/invalid-state-transition-exception.js +30 -0
  28. package/dist/invalid-state-transition-exception.js.map +1 -0
  29. package/dist/invariant-violation-exception.js +11 -0
  30. package/dist/invariant-violation-exception.js.map +1 -0
  31. package/dist/not-found-error.js +1 -1
  32. package/dist/outcome.d.ts +140 -0
  33. package/dist/outcome.js +1 -1
  34. package/dist/parse-gate-payload.d.ts +2 -1
  35. package/dist/path.d.ts +2 -1
  36. package/dist/plugin.d.ts +85 -0
  37. package/dist/plugin.js +74 -0
  38. package/dist/plugin.js.map +1 -0
  39. package/dist/plugins/index.d.ts +2 -0
  40. package/dist/plugins/index.js +2 -0
  41. package/dist/policies/engines/index.d.ts +1 -1
  42. package/dist/policies/engines/v1/gate/index.d.ts +2 -1
  43. package/dist/policies/engines/v1/gate/index.js +2 -1
  44. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  45. package/dist/policies/index.d.ts +2 -1
  46. package/dist/policies/index.js +2 -1
  47. package/dist/policy-service.d.ts +2 -1
  48. package/dist/policy-service.js +6 -3
  49. package/dist/policy-service.js.map +1 -1
  50. package/dist/result/index.d.ts +2 -0
  51. package/dist/result/index.js +3 -0
  52. package/dist/result.js +118 -0
  53. package/dist/result.js.map +1 -0
  54. package/dist/ruleset-registry.js +42 -0
  55. package/dist/ruleset-registry.js.map +1 -0
  56. package/dist/rulesets/index.d.ts +2 -0
  57. package/dist/rulesets/index.js +2 -0
  58. package/dist/temporal-guards.js +2 -17
  59. package/dist/temporal-guards.js.map +1 -1
  60. package/dist/temporal-use-case.d.ts +4 -9
  61. package/dist/temporal-use-case.js +6 -140
  62. package/dist/temporal-use-case.js.map +1 -1
  63. package/dist/unexpected-error.js +179 -0
  64. package/dist/unexpected-error.js.map +1 -0
  65. package/dist/use-case.js +91 -0
  66. package/dist/use-case.js.map +1 -0
  67. package/dist/uuid-identifier.d.ts +230 -0
  68. package/dist/uuid-identifier.js +60 -0
  69. package/dist/uuid-identifier.js.map +1 -0
  70. package/dist/validation-code.d.ts +23 -0
  71. package/dist/validation-code.js +1 -177
  72. package/dist/validation-code.js.map +1 -1
  73. package/dist/validation-error.d.ts +1 -21
  74. package/dist/validation-error.js +1 -1
  75. package/dist/validation-exception.d.ts +50 -0
  76. package/dist/validation-exception.js +8 -2
  77. package/dist/validation-exception.js.map +1 -1
  78. package/dist/value-object-ruleset.contracts.d.ts +36 -0
  79. package/dist/value-object.js +191 -0
  80. package/dist/value-object.js.map +1 -0
  81. package/dist/version.d.ts +10 -0
  82. package/dist/versioning/index.d.ts +3 -0
  83. package/dist/versioning/index.js +3 -0
  84. package/meta.json +17 -3
  85. package/package.json +33 -4
  86. package/src/core/domain/rulesets/index.ts +7 -0
  87. package/src/core/domain/uuid-identifier.ts +72 -0
  88. package/src/core/domain/value-object.ts +37 -5
  89. package/src/core/exceptions/index.ts +13 -0
  90. package/src/core/index.ts +14 -2
  91. package/src/core/plugins/index.ts +7 -0
  92. package/src/core/plugins/plugin.ts +99 -0
  93. package/src/core/plugins/types.ts +53 -0
  94. package/src/core/versioning/index.ts +14 -0
  95. package/src/domain/index.ts +7 -0
  96. package/src/exceptions/index.ts +1 -0
  97. package/src/plugins/index.ts +1 -0
  98. package/src/result/index.ts +2 -0
  99. package/src/rulesets/index.ts +1 -0
  100. package/src/version.ts +1 -1
  101. package/src/versioning/index.ts +1 -0
package/KIT_CONTEXT.md CHANGED
@@ -22,73 +22,7 @@ Núcleo arquitetural para sistemas ERP (e domínios transacionais com temporalid
22
22
  - **Policies como dados**, não como if-statements: avaliáveis, compostas, serializáveis.
23
23
  - **Policies permitem disable sem remover código**: `PolicyDefinition` aceita `enabled: false` e o repositório ignora definições desabilitadas.
24
24
  - **Composição isolada é de primeira classe**: use `new CoreConfig()`, `new ContextResolverRegistry()` e `registerNamespacedContextResolversIn(...)` quando precisar evitar singletons compartilhados.
25
-
26
- ## [example] Exemplo end-to-end (Command + Repository + PolicyPort)
27
-
28
- Um `Command` carrega o agregado por um `ResultRepository`, consulta um
29
- `PolicyPort` (gate `ALLOW`/`DENY`) e persiste. Falhas recuperáveis voltam como
30
- `Result.err`, nunca como exceção.
31
-
32
- ```ts
33
- class CancelOrder extends Command<
34
- CancelOrderInput,
35
- Result<Order, CancelOrderError>
36
- > {
37
- constructor(
38
- private readonly orders: ResultRepository<
39
- Order,
40
- string,
41
- CancelOrderError
42
- >,
43
- private readonly policies: PolicyPort,
44
- ) {
45
- super();
46
- }
47
-
48
- protected async execute(input: CancelOrderInput) {
49
- const found = await this.orders.findById(input.orderId);
50
- if (found.isErr()) return found;
51
- const order = found.getOrThrow();
52
- if (!order)
53
- return Result.err(
54
- new NotFoundError("Order", { id: input.orderId }),
55
- );
56
-
57
- const evaluated = await this.policies.evaluate({
58
- decisionId: asPolicyDecisionId(input.orderId),
59
- policyKey: "order.cancel",
60
- scopeChain: [],
61
- contextVersion: 1,
62
- seed: {
63
- tenantId: asTenantId(input.tenantId),
64
- schoolId: asSchoolId(input.schoolId),
65
- fields: { orderStatus: order.status },
66
- },
67
- });
68
- if (evaluated.isErr()) return evaluated;
69
-
70
- const result = evaluated.getOrThrow();
71
- if (result.kind === "GATE" && result.decision.status === "DENY") {
72
- return Result.err(
73
- AuthorizationError.policyDenied({
74
- action: "order.cancel",
75
- policyId: result.ref.definitionId,
76
- policyVersion: Number(result.ref.policyVersion),
77
- evaluatedAtIso: result.evaluatedAt.toISOString(),
78
- }),
79
- );
80
- }
81
-
82
- const saved = await this.orders.save({ ...order, status: "CANCELLED" });
83
- if (saved.isErr()) return saved;
84
- return Result.ok({ ...order, status: "CANCELLED" });
85
- }
86
- }
87
- ```
88
-
89
- - **Imports**: tudo do root `@cullet/erp-core`.
90
- - **`Repository` vs `ResultRepository`**: `Repository` (`save`/`delete` → `Promise<void>`) é o estilo imperativo; `ResultRepository` devolve `Result` para sinalizar not-found / concorrência otimista sem quebrar o fluxo.
91
- - **Referência compilada/testada**: `src/examples/application/cancel-order.example.ts` (+ `.spec.ts`).
25
+ - **`Repository` vs `ResultRepository`**: `Repository` (`save`/`delete` → `Promise<void>`) é o estilo imperativo; `ResultRepository` devolve `Result` para sinalizar not-found / concorrência otimista sem quebrar o fluxo. Exemplo end-to-end (Command + ResultRepository + PolicyPort) compilado e testado em `src/examples/application/cancel-order.example.ts` (+ `.spec.ts`).
92
26
 
93
27
  ## [extension-points] Pontos de extensão
94
28
 
@@ -1,2 +1,2 @@
1
- import { A as TracerPort, C as RequestedBy, D as UseCaseObservability, E as UseCase, M as MetricsPort, N as LogPayload, O as TraceAttributeValue, P as LoggerPort, S as CommandInput, T as MaybePromise, _ as PolicyEvaluationInput, a as TemporalContext, b as PolicyPortError, c as CacheStrategy, d as mapPolicyEvaluationError, f as TemporalHistory, g as ResultRepository, h as Repository, i as CreateTemporalContextInput, j as MetricLabels, k as TraceSpan, l as Page, n as TemporalUseCaseInput, o as assertTemporalContext, p as TemporalRepository, r as TemporalizedContextSeed, s as createTemporalContext, t as TemporalUseCase, u as Query, v as PolicyEvaluationOutput, w as RequestedByKind, x as Command, y as PolicyPort } from "../temporal-use-case.js";
1
+ import { A as MetricLabels, C as RequestedByKind, D as TraceAttributeValue, E as UseCaseObservability, M as LogPayload, N as LoggerPort, O as TraceSpan, S as RequestedBy, T as UseCase, _ as PolicyEvaluationOutput, a as TemporalContext, b as Command, c as CacheStrategy, d as mapPolicyEvaluationError, f as TemporalHistory, g as PolicyEvaluationInput, h as ResultRepository, i as CreateTemporalContextInput, j as MetricsPort, k as TracerPort, l as Page, m as Repository, n as TemporalUseCaseInput, o as assertTemporalContext, p as TemporalRepository, r as TemporalizedContextSeed, s as createTemporalContext, t as TemporalUseCase, u as Query, v as PolicyPort, w as MaybePromise, x as CommandInput, y as PolicyPortError } from "../temporal-use-case.js";
2
2
  export { CacheStrategy, Command, CommandInput, CreateTemporalContextInput, LogPayload, LoggerPort, MaybePromise, MetricLabels, MetricsPort, Page, PolicyEvaluationInput, PolicyEvaluationOutput, PolicyPort, PolicyPortError, Query, Repository, RequestedBy, RequestedByKind, ResultRepository, TemporalContext, TemporalHistory, TemporalRepository, TemporalUseCase, TemporalUseCaseInput, TemporalizedContextSeed, TraceAttributeValue, TraceSpan, TracerPort, UseCase, UseCaseObservability, assertTemporalContext, createTemporalContext, mapPolicyEvaluationError };
@@ -1,2 +1,3 @@
1
- import { a as Query, c as RequestedBy, l as UseCase, n as assertTemporalContext, o as mapPolicyEvaluationError, r as createTemporalContext, s as Command, t as TemporalUseCase } from "../temporal-use-case.js";
1
+ import { t as UseCase } from "../use-case.js";
2
+ import { a as mapPolicyEvaluationError, i as Query, n as assertTemporalContext, o as Command, r as createTemporalContext, s as RequestedBy, t as TemporalUseCase } from "../temporal-use-case.js";
2
3
  export { Command, Query, RequestedBy, TemporalUseCase, UseCase, assertTemporalContext, createTemporalContext, mapPolicyEvaluationError };
@@ -0,0 +1,3 @@
1
+ import { t as DeepReadonly } from "../immutable.js";
2
+ import { a as EntityState, i as Entity, n as ValueObject, r as ValueObjectPluginContract, t as UuidIdentifier } from "../uuid-identifier.js";
3
+ export { type DeepReadonly, Entity, type EntityState, UuidIdentifier, ValueObject, type ValueObjectPluginContract };
@@ -0,0 +1,3 @@
1
+ import { n as Entity, t as ValueObject } from "../value-object.js";
2
+ import { t as UuidIdentifier } from "../uuid-identifier.js";
3
+ export { Entity, UuidIdentifier, ValueObject };
@@ -0,0 +1,27 @@
1
+ import { n as ContractVersion } from "./version.js";
2
+
3
+ //#region src/core/versioning/domain-event-contracts.d.ts
4
+ interface DomainEventContractSelection {
5
+ readonly entity?: boolean;
6
+ readonly valueObject?: boolean;
7
+ readonly useCase?: boolean;
8
+ }
9
+ interface DomainEventContractVersions {
10
+ readonly entity_contract?: ContractVersion;
11
+ readonly value_object_contract?: ContractVersion;
12
+ readonly use_case_contract?: ContractVersion;
13
+ }
14
+ interface CreateDomainEventEnvelopeInput<TPayload> {
15
+ readonly aggregateVersion: number;
16
+ readonly payload: TPayload;
17
+ readonly contracts: DomainEventContractSelection;
18
+ }
19
+ interface DomainEventEnvelope<TPayload> extends DomainEventContractVersions {
20
+ readonly aggregate_version: number;
21
+ readonly payload: TPayload;
22
+ }
23
+ declare function buildDomainEventContractVersions(selection: DomainEventContractSelection): DomainEventContractVersions;
24
+ declare function createDomainEventEnvelope<TPayload>(input: CreateDomainEventEnvelopeInput<TPayload>): DomainEventEnvelope<TPayload>;
25
+ //#endregion
26
+ export { buildDomainEventContractVersions as a, DomainEventEnvelope as i, DomainEventContractSelection as n, createDomainEventEnvelope as o, DomainEventContractVersions as r, CreateDomainEventEnvelopeInput as t };
27
+ //# sourceMappingURL=domain-event-contracts.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { t as UseCase } from "./use-case.js";
2
+ import { n as Entity, r as assertValidAggregateVersion, t as ValueObject } from "./value-object.js";
3
+ //#region src/core/versioning/domain-event-contracts.ts
4
+ function buildDomainEventContractVersions(selection) {
5
+ const contractVersions = {};
6
+ if (selection.entity) contractVersions.entity_contract = Entity.CONTRACT_VERSION;
7
+ if (selection.valueObject) contractVersions.value_object_contract = ValueObject.CONTRACT_VERSION;
8
+ if (selection.useCase) contractVersions.use_case_contract = UseCase.CONTRACT_VERSION;
9
+ return Object.freeze(contractVersions);
10
+ }
11
+ function createDomainEventEnvelope(input) {
12
+ assertValidAggregateVersion(input.aggregateVersion);
13
+ return Object.freeze({
14
+ aggregate_version: input.aggregateVersion,
15
+ payload: input.payload,
16
+ ...buildDomainEventContractVersions(input.contracts)
17
+ });
18
+ }
19
+ //#endregion
20
+ export { createDomainEventEnvelope as n, buildDomainEventContractVersions as t };
21
+
22
+ //# sourceMappingURL=domain-event-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-event-contracts.js","names":[],"sources":["../src/core/versioning/domain-event-contracts.ts"],"sourcesContent":["import { UseCase } from \"../application/use-case.js\";\nimport { Entity } from \"../domain/entity.js\";\nimport { ValueObject } from \"../domain/value-object.js\";\nimport { assertValidAggregateVersion } from \"../shared/aggregate-version.js\";\nimport { type ContractVersion } from \"./version.js\";\n\ninterface DomainEventContractSelection {\n readonly entity?: boolean;\n readonly valueObject?: boolean;\n readonly useCase?: boolean;\n}\n\ninterface DomainEventContractVersions {\n readonly entity_contract?: ContractVersion;\n readonly value_object_contract?: ContractVersion;\n readonly use_case_contract?: ContractVersion;\n}\n\ninterface CreateDomainEventEnvelopeInput<TPayload> {\n readonly aggregateVersion: number;\n readonly payload: TPayload;\n readonly contracts: DomainEventContractSelection;\n}\n\ninterface DomainEventEnvelope<TPayload> extends DomainEventContractVersions {\n readonly aggregate_version: number;\n readonly payload: TPayload;\n}\n\nfunction buildDomainEventContractVersions(\n selection: DomainEventContractSelection,\n): DomainEventContractVersions {\n const contractVersions: {\n entity_contract?: ContractVersion;\n value_object_contract?: ContractVersion;\n use_case_contract?: ContractVersion;\n } = {};\n\n if (selection.entity) {\n contractVersions.entity_contract = Entity.CONTRACT_VERSION;\n }\n\n if (selection.valueObject) {\n contractVersions.value_object_contract = ValueObject.CONTRACT_VERSION;\n }\n\n if (selection.useCase) {\n contractVersions.use_case_contract = UseCase.CONTRACT_VERSION;\n }\n\n return Object.freeze(contractVersions);\n}\n\nfunction createDomainEventEnvelope<TPayload>(\n input: CreateDomainEventEnvelopeInput<TPayload>,\n): DomainEventEnvelope<TPayload> {\n assertValidAggregateVersion(input.aggregateVersion);\n\n return Object.freeze({\n aggregate_version: input.aggregateVersion,\n payload: input.payload,\n ...buildDomainEventContractVersions(input.contracts),\n });\n}\n\nexport {\n buildDomainEventContractVersions,\n createDomainEventEnvelope,\n type CreateDomainEventEnvelopeInput,\n type DomainEventContractSelection,\n type DomainEventContractVersions,\n type DomainEventEnvelope,\n};\n"],"mappings":";;;AA6BA,SAAS,iCACL,WAC2B;CAC3B,MAAM,mBAIF,CAAC;CAEL,IAAI,UAAU,QACV,iBAAiB,kBAAkB,OAAO;CAG9C,IAAI,UAAU,aACV,iBAAiB,wBAAwB,YAAY;CAGzD,IAAI,UAAU,SACV,iBAAiB,oBAAoB,QAAQ;CAGjD,OAAO,OAAO,OAAO,gBAAgB;AACzC;AAEA,SAAS,0BACL,OAC6B;CAC7B,4BAA4B,MAAM,gBAAgB;CAElD,OAAO,OAAO,OAAO;EACjB,mBAAmB,MAAM;EACzB,SAAS,MAAM;EACf,GAAG,iCAAiC,MAAM,SAAS;CACvD,CAAC;AACL"}
@@ -0,0 +1,7 @@
1
+ //#region src/core/exceptions/domain-exception.d.ts
2
+ declare abstract class DomainException extends Error {
3
+ constructor(message: string);
4
+ }
5
+ //#endregion
6
+ export { DomainException as t };
7
+ //# sourceMappingURL=domain-exception.d.ts.map
@@ -0,0 +1,12 @@
1
+ //#region src/core/exceptions/domain-exception.ts
2
+ var DomainException = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ Object.setPrototypeOf(this, new.target.prototype);
6
+ this.name = new.target.name;
7
+ }
8
+ };
9
+ //#endregion
10
+ export { DomainException as t };
11
+
12
+ //# sourceMappingURL=domain-exception.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-exception.js","names":[],"sources":["../src/core/exceptions/domain-exception.ts"],"sourcesContent":["abstract class DomainException extends Error {\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = new.target.name;\n }\n}\n\nexport { DomainException };\n"],"mappings":";AAAA,IAAe,kBAAf,cAAuC,MAAM;CACzC,YAAY,SAAiB;EACzB,MAAM,OAAO;EACb,OAAO,eAAe,MAAM,IAAI,OAAO,SAAS;EAChD,KAAK,OAAO,IAAI,OAAO;CAC3B;AACJ"}
@@ -1,4 +1,4 @@
1
- import { a as ErrorCodes, i as assertJsonSafeMetadata, n as UnexpectedError, o as serializationErrorCode, r as AppError } from "../validation-code.js";
1
+ import { a as serializationErrorCode, i as ErrorCodes, n as AppError, r as assertJsonSafeMetadata, t as UnexpectedError } from "../unexpected-error.js";
2
2
  import { C as translateUniqueViolationToDuplicate, S as UniqueConstraintViolationError, T as AuthenticationError, _ as IdempotencyPayloadMismatchError, a as evaluateTemporalWindow, b as ConflictError, c as SerializationInError, d as safePreview, f as LegacyIncompatibleError, g as IdempotencyKeyMissingError, h as IdempotencyInProgressError, i as TemporalError, l as SerializationMessages, m as IdempotencyError, n as ExpiredError, o as SerializationCodes, p as IntegrationError, r as NotYetValidError, s as SerializationError, t as ValidationError, u as SerializationOutError, v as IdempotencyReplayNotSupportedError, w as AuthorizationError, x as DuplicateError, y as AlreadyExistsError } from "../validation-error.js";
3
3
  import { n as BusinessRuleViolationError, t as NotFoundError } from "../not-found-error.js";
4
4
  import { n as sha256Hex, r as stableStringify, t as payloadHash } from "../hashing.js";
@@ -0,0 +1,5 @@
1
+ import { t as ValidationCode } from "../validation-code.js";
2
+ import { t as ValidationField } from "../validation-field.js";
3
+ import { t as DomainException } from "../domain-exception.js";
4
+ import { a as InvariantViolationException, c as BusinessRuleViolationException, i as ValidationViolation, n as MultipleValidationException, o as InvalidStateTransitionException, r as ValidationException, s as EntityNotFoundException, t as InvalidValueException } from "../validation-exception.js";
5
+ export { BusinessRuleViolationException, DomainException, EntityNotFoundException, InvalidStateTransitionException, InvalidValueException, InvariantViolationException, MultipleValidationException, ValidationCode, ValidationException, ValidationField, ValidationViolation };
@@ -0,0 +1,7 @@
1
+ import { t as ValidationCode } from "../validation-code.js";
2
+ import { t as ValidationField } from "../validation-field.js";
3
+ import { t as DomainException } from "../domain-exception.js";
4
+ import { n as EntityNotFoundException, r as BusinessRuleViolationException, t as InvalidStateTransitionException } from "../invalid-state-transition-exception.js";
5
+ import { t as InvariantViolationException } from "../invariant-violation-exception.js";
6
+ import { n as MultipleValidationException, r as ValidationException, t as InvalidValueException } from "../validation-exception.js";
7
+ export { BusinessRuleViolationException, DomainException, EntityNotFoundException, InvalidStateTransitionException, InvalidValueException, InvariantViolationException, MultipleValidationException, ValidationCode, ValidationException, ValidationField };
@@ -1,4 +1,5 @@
1
- import { I as Result, c as PolicyViolation, g as CoreConfig, h as Outcome, l as VersionedGateEngine, p as ConditionNode, s as PolicyContext, t as GateOutcome } from "./gate-types.js";
1
+ import { a as Result, n as Outcome } from "./outcome.js";
2
+ import { c as PolicyViolation, l as VersionedGateEngine, m as CoreConfig, p as ConditionNode, s as PolicyContext, t as GateOutcome } from "./gate-types.js";
2
3
  import { z } from "zod";
3
4
 
4
5
  //#region src/core/policies/engines/v1/compute/compute-payload.schema.d.ts
@@ -1,4 +1,5 @@
1
- import { a as conditionNodeSchema, l as Result, r as ConditionEvaluatorV1, t as GatePayloadSchemaV1, u as coreConfig } from "./gate-v1-payload.schema.js";
1
+ import { a as conditionNodeSchema, r as ConditionEvaluatorV1, s as coreConfig, t as GatePayloadSchemaV1 } from "./gate-v1-payload.schema.js";
2
+ import { r as Result } from "./result.js";
2
3
  import { z } from "zod";
3
4
  //#region src/core/policies/engines/v1/compute/compute-payload.schema.ts
4
5
  const computeDecisionTableRuleSchema = z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"gate-engine-registry.js","names":[],"sources":["../src/core/policies/engines/v1/compute/compute-payload.schema.ts","../src/core/policies/engines/parse-compute-payload.ts","../src/core/policies/engines/compute-engine-registry.ts","../src/core/policies/engines/compute-evaluator-registry.ts","../src/core/policies/engines/v1/compute/resolve-decision-table-v1.ts","../src/core/policies/engines/v1/compute/compute-engine-v1.ts","../src/core/policies/engines/compute-registry.ts","../src/core/policies/engines/parse-gate-payload.ts","../src/core/policies/engines/gate-engine-registry.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { Result } from \"../../../../result/result.js\";\n\nimport { conditionNodeSchema } from \"../condition-schema.js\";\nimport type { ConditionNode } from \"../condition-types.js\";\n\n// ─── Pattern 1: Params ──────────────────────────────────────────────────────\n\nexport interface ComputeParamsPayload {\n readonly type: \"params\";\n readonly data: Readonly<Record<string, unknown>>;\n}\n\n// ─── Pattern 2: Decision table ──────────────────────────────────────────────\n\nexport interface ComputeDecisionTableRule<R = unknown> {\n readonly conditions: ConditionNode;\n readonly result: R;\n}\n\nexport interface ComputeDecisionTablePayload<R = unknown> {\n readonly type: \"decision-table\";\n readonly rules: readonly ComputeDecisionTableRule<R>[];\n readonly default: R;\n}\n\n// ─── Union ──────────────────────────────────────────────────────────────────\n\nexport type ComputePayloadV1 =\n | ComputeDecisionTablePayload<unknown>\n | ComputeParamsPayload;\n\n// ─── Zod schemas ────────────────────────────────────────────────────────────\n\nconst computeDecisionTableRuleSchema = z.object({\n conditions: conditionNodeSchema,\n result: z.unknown(),\n});\n\nexport class ComputePayloadSchemaV1 {\n static readonly schema = z.union([\n z\n .object({\n type: z.literal(\"decision-table\"),\n rules: z.array(computeDecisionTableRuleSchema).min(1),\n default: z.unknown(),\n })\n .strict(),\n z\n .object({\n type: z.literal(\"params\"),\n data: z.record(z.string(), z.unknown()),\n })\n .strict(),\n ]);\n\n static parse(payload: unknown): Result<ComputePayloadV1, string> {\n const parsed = ComputePayloadSchemaV1.schema.safeParse(payload);\n if (!parsed.success) {\n const details = parsed.error.issues\n .map((issue) => {\n const path = issue.path.join(\".\");\n return path.length > 0\n ? `${path}: ${issue.message}`\n : issue.message;\n })\n .join(\"; \");\n\n return Result.err(`Invalid compute payload: ${details}`);\n }\n\n return Result.ok(parsed.data as ComputePayloadV1);\n }\n}\n\nexport const computePayloadSchema = ComputePayloadSchemaV1.schema;\n","import type { Result as ResultType } from \"../../result/result.js\";\nimport { Result } from \"../../result/result.js\";\n\nimport type { ComputePayload } from \"./compute-payload.js\";\nimport { ComputePayloadSchemaV1 } from \"./v1/compute/compute-payload.schema.js\";\n\nexport type ComputePayloadParser = (\n payload: unknown,\n) => ResultType<ComputePayload, string>;\n\nexport class ComputePayloadParserRegistry {\n private readonly parsers = new Map<number, ComputePayloadParser>();\n\n register(payloadSchemaVersion: number, parser: ComputePayloadParser): void {\n this.parsers.set(payloadSchemaVersion, parser);\n }\n\n get(payloadSchemaVersion: number): ComputePayloadParser | undefined {\n return this.parsers.get(payloadSchemaVersion);\n }\n\n parse(payloadSchemaVersion: number, payload: unknown) {\n const parser = this.parsers.get(payloadSchemaVersion);\n\n if (parser === undefined) {\n return Result.err(\n `No compute payload parser registered for schema version \"${payloadSchemaVersion}\"`,\n );\n }\n\n return parser(payload);\n }\n}\n\nexport class ComputePayloadParsers {\n private static readonly registry = new ComputePayloadParserRegistry();\n private static defaultsRegistered = false;\n\n // Registers the built-in v1 parser lazily, the first time the default\n // dispatcher is touched. Done here — rather than as a top-level module\n // statement — so the package's `\"sideEffects\": false` flag stays honest and\n // a tree-shaking bundler cannot drop the v1 registration and leave the\n // compute engine unable to parse v1 payloads at runtime.\n private static ensureDefaults(): void {\n if (ComputePayloadParsers.defaultsRegistered) {\n return;\n }\n ComputePayloadParsers.defaultsRegistered = true;\n ComputePayloadParsers.registry.register(\n 1,\n ComputePayloadSchemaV1.parse,\n );\n }\n\n static register(\n payloadSchemaVersion: number,\n parser: ComputePayloadParser,\n ): void {\n ComputePayloadParsers.ensureDefaults();\n ComputePayloadParsers.registry.register(payloadSchemaVersion, parser);\n }\n\n static get(payloadSchemaVersion: number): ComputePayloadParser | undefined {\n ComputePayloadParsers.ensureDefaults();\n return ComputePayloadParsers.registry.get(payloadSchemaVersion);\n }\n\n static parse(payloadSchemaVersion: number, payload: unknown) {\n ComputePayloadParsers.ensureDefaults();\n return ComputePayloadParsers.registry.parse(\n payloadSchemaVersion,\n payload,\n );\n }\n}\n\nexport type { ComputePayload };\n","import { Result } from \"../../result/result.js\";\n\nimport type { PolicyContext } from \"./gate-types.js\";\nimport { ComputePayloadParsers } from \"./parse-compute-payload.js\";\nimport type { ComputeEvaluatorRegistry } from \"./compute-evaluator-registry.js\";\nimport type {\n ComputeOutcome,\n VersionedComputeEngine,\n} from \"./compute-types.js\";\n\nexport class ComputeEngineRegistry {\n private readonly engines = new Map<number, VersionedComputeEngine>();\n\n register(engine: VersionedComputeEngine): void {\n this.engines.set(engine.version, engine);\n }\n\n get(version: number): VersionedComputeEngine | undefined {\n return this.engines.get(version);\n }\n\n evaluate(\n version: number,\n params: {\n readonly policyKey: string;\n readonly payloadSchemaVersion: number;\n readonly payload: unknown;\n readonly context: PolicyContext;\n readonly evaluators: ComputeEvaluatorRegistry;\n },\n ): Result<ComputeOutcome, string> {\n const engine = this.get(version);\n if (engine === undefined) {\n return Result.err(\n `No compute engine registered for version \"${version}\"`,\n );\n }\n\n const evaluator = params.evaluators.get(params.policyKey, version);\n if (evaluator === undefined) {\n return Result.err(\n `No compute evaluator registered for policy key \"${params.policyKey}\" and version \"${version}\"`,\n );\n }\n\n const parsedPayloadResult = ComputePayloadParsers.parse(\n params.payloadSchemaVersion,\n params.payload,\n );\n if (parsedPayloadResult.isErr()) {\n return Result.err(parsedPayloadResult.errorOrNull()!);\n }\n\n return engine.evaluate(\n parsedPayloadResult.getOrNull()!,\n params.context,\n evaluator,\n );\n }\n}\n","import type {\n ComputeEvaluator,\n ComputeEvaluatorRegistration,\n} from \"./compute-types.js\";\n\nexport class ComputeEvaluatorRegistry {\n private readonly evaluators = new Map<string, ComputeEvaluator>();\n\n private static toRegistryKey(policyKey: string, version: number): string {\n return `${policyKey}::${version}`;\n }\n\n register(registration: ComputeEvaluatorRegistration): void {\n this.evaluators.set(\n ComputeEvaluatorRegistry.toRegistryKey(\n registration.policyKey,\n registration.version,\n ),\n registration.evaluator,\n );\n }\n\n get(policyKey: string, version: number): ComputeEvaluator | undefined {\n return this.evaluators.get(\n ComputeEvaluatorRegistry.toRegistryKey(policyKey, version),\n );\n }\n}\n","import { Result } from \"../../../../result/result.js\";\n\nimport type { ConditionEvaluationOptions } from \"../../condition-evaluator-reporter.js\";\n\nimport { ConditionEvaluatorV1 } from \"../condition-evaluator.js\";\nimport type { ComputeDecisionTablePayload } from \"./compute-payload.schema.js\";\n\nconst COMPUTE_CONDITION_EVAL_FAILED_TAG = \"COMPUTE_CONDITION_EVAL_FAILED\";\n\nexport class DecisionTableResolverV1 {\n constructor(\n private readonly payload: ComputeDecisionTablePayload,\n private readonly context: Record<string, unknown>,\n private readonly conditionEvaluationOptions: ConditionEvaluationOptions,\n ) {}\n\n private wrapConditionEvaluationError(\n error: string,\n ): Result<unknown, string> {\n return Result.err(`${COMPUTE_CONDITION_EVAL_FAILED_TAG}: ${error}`);\n }\n\n resolve(): Result<unknown, string> {\n const evaluator = new ConditionEvaluatorV1(\n this.context,\n this.conditionEvaluationOptions,\n );\n\n for (const rule of this.payload.rules) {\n const conditionResult = evaluator.evaluate(rule.conditions);\n if (conditionResult.isErr()) {\n return this.wrapConditionEvaluationError(\n conditionResult.errorOrNull()!,\n );\n }\n\n if (conditionResult.getOrNull()) {\n return Result.ok(rule.result);\n }\n }\n\n return Result.ok(this.payload.default);\n }\n\n static resolve(\n payload: ComputeDecisionTablePayload,\n context: Record<string, unknown>,\n conditionEvaluationOptions: ConditionEvaluationOptions,\n ): Result<unknown, string> {\n return new DecisionTableResolverV1(\n payload,\n context,\n conditionEvaluationOptions,\n ).resolve();\n }\n}\n","import { type CoreConfig, coreConfig } from \"../../../../config/index.js\";\nimport { Result } from \"../../../../result/result.js\";\n\nimport type { ComputePayloadV1 as ComputePayload } from \"./compute-payload.schema.js\";\nimport { DecisionTableResolverV1 } from \"./resolve-decision-table-v1.js\";\nimport type {\n ComputeEvaluator,\n ComputeOutcome,\n VersionedComputeEngine,\n} from \"../../compute-types.js\";\nimport type { PolicyContext } from \"../../gate-types.js\";\n\n// ─── Compute engine v1 ───────────────────────────────────────────────────────\n\nconst COMPUTE_ENGINE_VERSION = 1;\n\nexport class ComputeEngineV1 implements VersionedComputeEngine {\n readonly version = COMPUTE_ENGINE_VERSION;\n private readonly coreConfig: CoreConfig;\n\n constructor(params: { readonly coreConfig?: CoreConfig } = {}) {\n this.coreConfig = params.coreConfig ?? coreConfig;\n }\n\n /**\n * Evaluates an already-parsed ComputePayload against a context.\n * Pure function — no side effects.\n *\n * For `params`: forwards `payload.data` directly to the evaluator.\n * For `decision-table`: evaluates the rules in order and passes the `result`\n * of the first one that satisfies its conditions, or `default` if none match.\n *\n * The evaluator is responsible for validating and transforming the final value.\n */\n evaluate(\n payload: ComputePayload,\n context: PolicyContext,\n evaluator: ComputeEvaluator,\n ): Result<ComputeOutcome, string> {\n if (payload.type === \"params\") {\n return evaluator.evaluate(payload.data, context);\n }\n\n const resolvedResult = DecisionTableResolverV1.resolve(\n payload,\n context,\n this.coreConfig.getConditionEvaluationOptions(\n COMPUTE_ENGINE_VERSION,\n ),\n );\n if (resolvedResult.isErr()) {\n return Result.err(resolvedResult.errorOrNull()!);\n }\n\n return evaluator.evaluate(resolvedResult.getOrNull()!, context);\n }\n}\n","import { type CoreConfig, coreConfig } from \"../../config/index.js\";\nimport type { Result } from \"../../result/result.js\";\n\nimport { ComputeEngineRegistry } from \"./compute-engine-registry.js\";\nimport { ComputeEvaluatorRegistry } from \"./compute-evaluator-registry.js\";\nimport type { PolicyContext } from \"./gate-types.js\";\nimport type {\n ComputeEvaluator,\n ComputeEvaluatorRegistration,\n ComputeOutcome,\n VersionedComputeEngine,\n} from \"./compute-types.js\";\nimport { ComputeEngineV1 } from \"./v1/compute/index.js\";\n\nexport interface ComputeRegistryOptions {\n readonly coreConfig?: CoreConfig;\n}\n\nexport class ComputeRegistry {\n private readonly engines = new ComputeEngineRegistry();\n private readonly evaluators = new ComputeEvaluatorRegistry();\n\n constructor(params: ComputeRegistryOptions = {}) {\n const resolvedCoreConfig = params.coreConfig ?? coreConfig;\n\n this.engines.register(\n new ComputeEngineV1({\n coreConfig: resolvedCoreConfig,\n }),\n );\n }\n\n register(registration: ComputeEvaluatorRegistration): void {\n this.evaluators.register(registration);\n }\n\n registerEngine(engine: VersionedComputeEngine): void {\n this.engines.register(engine);\n }\n\n getEngine(version: number): VersionedComputeEngine | undefined {\n return this.engines.get(version);\n }\n\n getEvaluator(\n policyKey: string,\n version: number,\n ): ComputeEvaluator | undefined {\n return this.evaluators.get(policyKey, version);\n }\n\n evaluate(\n policyKey: string,\n computeEngineVersion: number,\n payloadSchemaVersion: number,\n payload: unknown,\n context: PolicyContext,\n ): Result<ComputeOutcome, string> {\n return this.engines.evaluate(computeEngineVersion, {\n policyKey,\n payloadSchemaVersion,\n payload,\n context,\n evaluators: this.evaluators,\n });\n }\n}\n","import type { Result as ResultType } from \"../../result/result.js\";\nimport { Result } from \"../../result/result.js\";\n\nimport type { GatePayload } from \"./gate-payload.js\";\nimport { GatePayloadSchemaV1 } from \"./v1/gate/gate-v1-payload.schema.js\";\n\nexport type GatePayloadParser = (\n payload: unknown,\n) => ResultType<GatePayload, string>;\n\nexport class GatePayloadParserRegistry {\n private readonly parsers = new Map<number, GatePayloadParser>();\n\n register(engineVersion: number, parser: GatePayloadParser): void {\n this.parsers.set(engineVersion, parser);\n }\n\n get(engineVersion: number): GatePayloadParser | undefined {\n return this.parsers.get(engineVersion);\n }\n\n parse(engineVersion: number, payload: unknown) {\n const parser = this.parsers.get(engineVersion);\n\n if (parser === undefined) {\n return Result.err(\n `No gate payload parser registered for engine version \"${engineVersion}\"`,\n );\n }\n\n return parser(payload);\n }\n}\n\nexport class GatePayloadParsers {\n private static readonly registry = new GatePayloadParserRegistry();\n private static defaultsRegistered = false;\n\n // Registers the built-in v1 parser lazily, the first time the default\n // dispatcher is touched. Done here — rather than as a top-level module\n // statement — so the package's `\"sideEffects\": false` flag stays honest and\n // a tree-shaking bundler cannot drop the v1 registration and leave the gate\n // engine unable to parse v1 payloads at runtime.\n private static ensureDefaults(): void {\n if (GatePayloadParsers.defaultsRegistered) {\n return;\n }\n GatePayloadParsers.defaultsRegistered = true;\n GatePayloadParsers.registry.register(1, GatePayloadSchemaV1.parse);\n }\n\n static register(engineVersion: number, parser: GatePayloadParser): void {\n GatePayloadParsers.ensureDefaults();\n GatePayloadParsers.registry.register(engineVersion, parser);\n }\n\n static get(engineVersion: number): GatePayloadParser | undefined {\n GatePayloadParsers.ensureDefaults();\n return GatePayloadParsers.registry.get(engineVersion);\n }\n\n static parse(engineVersion: number, payload: unknown) {\n GatePayloadParsers.ensureDefaults();\n return GatePayloadParsers.registry.parse(engineVersion, payload);\n }\n}\n\nexport type { GatePayload };\n","import { Result } from \"../../result/result.js\";\n\nimport type {\n GateOutcome,\n PolicyContext,\n VersionedGateEngine,\n} from \"./gate-types.js\";\nimport { GatePayloadParsers } from \"./parse-gate-payload.js\";\n\nexport class GateEngineRegistry {\n private readonly engines = new Map<number, VersionedGateEngine>();\n\n register(engine: VersionedGateEngine): void {\n this.engines.set(engine.version, engine);\n }\n\n get(version: number): VersionedGateEngine | undefined {\n return this.engines.get(version);\n }\n\n evaluate(\n version: number,\n payload: unknown,\n context: PolicyContext,\n ): Result<GateOutcome, string> {\n const engine = this.engines.get(version);\n if (!engine) {\n return Result.err(\n `No gate engine registered for version \"${version}\"`,\n );\n }\n\n const parsedPayload = GatePayloadParsers.parse(version, payload);\n if (parsedPayload.isErr()) {\n return Result.err(parsedPayload.errorOrNull()!);\n }\n\n return engine.evaluate(parsedPayload.getOrNull()!, context);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"gate-engine-registry.js","names":[],"sources":["../src/core/policies/engines/v1/compute/compute-payload.schema.ts","../src/core/policies/engines/parse-compute-payload.ts","../src/core/policies/engines/compute-engine-registry.ts","../src/core/policies/engines/compute-evaluator-registry.ts","../src/core/policies/engines/v1/compute/resolve-decision-table-v1.ts","../src/core/policies/engines/v1/compute/compute-engine-v1.ts","../src/core/policies/engines/compute-registry.ts","../src/core/policies/engines/parse-gate-payload.ts","../src/core/policies/engines/gate-engine-registry.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport { Result } from \"../../../../result/result.js\";\n\nimport { conditionNodeSchema } from \"../condition-schema.js\";\nimport type { ConditionNode } from \"../condition-types.js\";\n\n// ─── Pattern 1: Params ──────────────────────────────────────────────────────\n\nexport interface ComputeParamsPayload {\n readonly type: \"params\";\n readonly data: Readonly<Record<string, unknown>>;\n}\n\n// ─── Pattern 2: Decision table ──────────────────────────────────────────────\n\nexport interface ComputeDecisionTableRule<R = unknown> {\n readonly conditions: ConditionNode;\n readonly result: R;\n}\n\nexport interface ComputeDecisionTablePayload<R = unknown> {\n readonly type: \"decision-table\";\n readonly rules: readonly ComputeDecisionTableRule<R>[];\n readonly default: R;\n}\n\n// ─── Union ──────────────────────────────────────────────────────────────────\n\nexport type ComputePayloadV1 =\n | ComputeDecisionTablePayload<unknown>\n | ComputeParamsPayload;\n\n// ─── Zod schemas ────────────────────────────────────────────────────────────\n\nconst computeDecisionTableRuleSchema = z.object({\n conditions: conditionNodeSchema,\n result: z.unknown(),\n});\n\nexport class ComputePayloadSchemaV1 {\n static readonly schema = z.union([\n z\n .object({\n type: z.literal(\"decision-table\"),\n rules: z.array(computeDecisionTableRuleSchema).min(1),\n default: z.unknown(),\n })\n .strict(),\n z\n .object({\n type: z.literal(\"params\"),\n data: z.record(z.string(), z.unknown()),\n })\n .strict(),\n ]);\n\n static parse(payload: unknown): Result<ComputePayloadV1, string> {\n const parsed = ComputePayloadSchemaV1.schema.safeParse(payload);\n if (!parsed.success) {\n const details = parsed.error.issues\n .map((issue) => {\n const path = issue.path.join(\".\");\n return path.length > 0\n ? `${path}: ${issue.message}`\n : issue.message;\n })\n .join(\"; \");\n\n return Result.err(`Invalid compute payload: ${details}`);\n }\n\n return Result.ok(parsed.data as ComputePayloadV1);\n }\n}\n\nexport const computePayloadSchema = ComputePayloadSchemaV1.schema;\n","import type { Result as ResultType } from \"../../result/result.js\";\nimport { Result } from \"../../result/result.js\";\n\nimport type { ComputePayload } from \"./compute-payload.js\";\nimport { ComputePayloadSchemaV1 } from \"./v1/compute/compute-payload.schema.js\";\n\nexport type ComputePayloadParser = (\n payload: unknown,\n) => ResultType<ComputePayload, string>;\n\nexport class ComputePayloadParserRegistry {\n private readonly parsers = new Map<number, ComputePayloadParser>();\n\n register(payloadSchemaVersion: number, parser: ComputePayloadParser): void {\n this.parsers.set(payloadSchemaVersion, parser);\n }\n\n get(payloadSchemaVersion: number): ComputePayloadParser | undefined {\n return this.parsers.get(payloadSchemaVersion);\n }\n\n parse(payloadSchemaVersion: number, payload: unknown) {\n const parser = this.parsers.get(payloadSchemaVersion);\n\n if (parser === undefined) {\n return Result.err(\n `No compute payload parser registered for schema version \"${payloadSchemaVersion}\"`,\n );\n }\n\n return parser(payload);\n }\n}\n\nexport class ComputePayloadParsers {\n private static readonly registry = new ComputePayloadParserRegistry();\n private static defaultsRegistered = false;\n\n // Registers the built-in v1 parser lazily, the first time the default\n // dispatcher is touched. Done here — rather than as a top-level module\n // statement — so the package's `\"sideEffects\": false` flag stays honest and\n // a tree-shaking bundler cannot drop the v1 registration and leave the\n // compute engine unable to parse v1 payloads at runtime.\n private static ensureDefaults(): void {\n if (ComputePayloadParsers.defaultsRegistered) {\n return;\n }\n ComputePayloadParsers.defaultsRegistered = true;\n ComputePayloadParsers.registry.register(\n 1,\n ComputePayloadSchemaV1.parse,\n );\n }\n\n static register(\n payloadSchemaVersion: number,\n parser: ComputePayloadParser,\n ): void {\n ComputePayloadParsers.ensureDefaults();\n ComputePayloadParsers.registry.register(payloadSchemaVersion, parser);\n }\n\n static get(payloadSchemaVersion: number): ComputePayloadParser | undefined {\n ComputePayloadParsers.ensureDefaults();\n return ComputePayloadParsers.registry.get(payloadSchemaVersion);\n }\n\n static parse(payloadSchemaVersion: number, payload: unknown) {\n ComputePayloadParsers.ensureDefaults();\n return ComputePayloadParsers.registry.parse(\n payloadSchemaVersion,\n payload,\n );\n }\n}\n\nexport type { ComputePayload };\n","import { Result } from \"../../result/result.js\";\n\nimport type { PolicyContext } from \"./gate-types.js\";\nimport { ComputePayloadParsers } from \"./parse-compute-payload.js\";\nimport type { ComputeEvaluatorRegistry } from \"./compute-evaluator-registry.js\";\nimport type {\n ComputeOutcome,\n VersionedComputeEngine,\n} from \"./compute-types.js\";\n\nexport class ComputeEngineRegistry {\n private readonly engines = new Map<number, VersionedComputeEngine>();\n\n register(engine: VersionedComputeEngine): void {\n this.engines.set(engine.version, engine);\n }\n\n get(version: number): VersionedComputeEngine | undefined {\n return this.engines.get(version);\n }\n\n evaluate(\n version: number,\n params: {\n readonly policyKey: string;\n readonly payloadSchemaVersion: number;\n readonly payload: unknown;\n readonly context: PolicyContext;\n readonly evaluators: ComputeEvaluatorRegistry;\n },\n ): Result<ComputeOutcome, string> {\n const engine = this.get(version);\n if (engine === undefined) {\n return Result.err(\n `No compute engine registered for version \"${version}\"`,\n );\n }\n\n const evaluator = params.evaluators.get(params.policyKey, version);\n if (evaluator === undefined) {\n return Result.err(\n `No compute evaluator registered for policy key \"${params.policyKey}\" and version \"${version}\"`,\n );\n }\n\n const parsedPayloadResult = ComputePayloadParsers.parse(\n params.payloadSchemaVersion,\n params.payload,\n );\n if (parsedPayloadResult.isErr()) {\n return Result.err(parsedPayloadResult.errorOrNull()!);\n }\n\n return engine.evaluate(\n parsedPayloadResult.getOrNull()!,\n params.context,\n evaluator,\n );\n }\n}\n","import type {\n ComputeEvaluator,\n ComputeEvaluatorRegistration,\n} from \"./compute-types.js\";\n\nexport class ComputeEvaluatorRegistry {\n private readonly evaluators = new Map<string, ComputeEvaluator>();\n\n private static toRegistryKey(policyKey: string, version: number): string {\n return `${policyKey}::${version}`;\n }\n\n register(registration: ComputeEvaluatorRegistration): void {\n this.evaluators.set(\n ComputeEvaluatorRegistry.toRegistryKey(\n registration.policyKey,\n registration.version,\n ),\n registration.evaluator,\n );\n }\n\n get(policyKey: string, version: number): ComputeEvaluator | undefined {\n return this.evaluators.get(\n ComputeEvaluatorRegistry.toRegistryKey(policyKey, version),\n );\n }\n}\n","import { Result } from \"../../../../result/result.js\";\n\nimport type { ConditionEvaluationOptions } from \"../../condition-evaluator-reporter.js\";\n\nimport { ConditionEvaluatorV1 } from \"../condition-evaluator.js\";\nimport type { ComputeDecisionTablePayload } from \"./compute-payload.schema.js\";\n\nconst COMPUTE_CONDITION_EVAL_FAILED_TAG = \"COMPUTE_CONDITION_EVAL_FAILED\";\n\nexport class DecisionTableResolverV1 {\n constructor(\n private readonly payload: ComputeDecisionTablePayload,\n private readonly context: Record<string, unknown>,\n private readonly conditionEvaluationOptions: ConditionEvaluationOptions,\n ) {}\n\n private wrapConditionEvaluationError(\n error: string,\n ): Result<unknown, string> {\n return Result.err(`${COMPUTE_CONDITION_EVAL_FAILED_TAG}: ${error}`);\n }\n\n resolve(): Result<unknown, string> {\n const evaluator = new ConditionEvaluatorV1(\n this.context,\n this.conditionEvaluationOptions,\n );\n\n for (const rule of this.payload.rules) {\n const conditionResult = evaluator.evaluate(rule.conditions);\n if (conditionResult.isErr()) {\n return this.wrapConditionEvaluationError(\n conditionResult.errorOrNull()!,\n );\n }\n\n if (conditionResult.getOrNull()) {\n return Result.ok(rule.result);\n }\n }\n\n return Result.ok(this.payload.default);\n }\n\n static resolve(\n payload: ComputeDecisionTablePayload,\n context: Record<string, unknown>,\n conditionEvaluationOptions: ConditionEvaluationOptions,\n ): Result<unknown, string> {\n return new DecisionTableResolverV1(\n payload,\n context,\n conditionEvaluationOptions,\n ).resolve();\n }\n}\n","import { type CoreConfig, coreConfig } from \"../../../../config/index.js\";\nimport { Result } from \"../../../../result/result.js\";\n\nimport type { ComputePayloadV1 as ComputePayload } from \"./compute-payload.schema.js\";\nimport { DecisionTableResolverV1 } from \"./resolve-decision-table-v1.js\";\nimport type {\n ComputeEvaluator,\n ComputeOutcome,\n VersionedComputeEngine,\n} from \"../../compute-types.js\";\nimport type { PolicyContext } from \"../../gate-types.js\";\n\n// ─── Compute engine v1 ───────────────────────────────────────────────────────\n\nconst COMPUTE_ENGINE_VERSION = 1;\n\nexport class ComputeEngineV1 implements VersionedComputeEngine {\n readonly version = COMPUTE_ENGINE_VERSION;\n private readonly coreConfig: CoreConfig;\n\n constructor(params: { readonly coreConfig?: CoreConfig } = {}) {\n this.coreConfig = params.coreConfig ?? coreConfig;\n }\n\n /**\n * Evaluates an already-parsed ComputePayload against a context.\n * Pure function — no side effects.\n *\n * For `params`: forwards `payload.data` directly to the evaluator.\n * For `decision-table`: evaluates the rules in order and passes the `result`\n * of the first one that satisfies its conditions, or `default` if none match.\n *\n * The evaluator is responsible for validating and transforming the final value.\n */\n evaluate(\n payload: ComputePayload,\n context: PolicyContext,\n evaluator: ComputeEvaluator,\n ): Result<ComputeOutcome, string> {\n if (payload.type === \"params\") {\n return evaluator.evaluate(payload.data, context);\n }\n\n const resolvedResult = DecisionTableResolverV1.resolve(\n payload,\n context,\n this.coreConfig.getConditionEvaluationOptions(\n COMPUTE_ENGINE_VERSION,\n ),\n );\n if (resolvedResult.isErr()) {\n return Result.err(resolvedResult.errorOrNull()!);\n }\n\n return evaluator.evaluate(resolvedResult.getOrNull()!, context);\n }\n}\n","import { type CoreConfig, coreConfig } from \"../../config/index.js\";\nimport type { Result } from \"../../result/result.js\";\n\nimport { ComputeEngineRegistry } from \"./compute-engine-registry.js\";\nimport { ComputeEvaluatorRegistry } from \"./compute-evaluator-registry.js\";\nimport type { PolicyContext } from \"./gate-types.js\";\nimport type {\n ComputeEvaluator,\n ComputeEvaluatorRegistration,\n ComputeOutcome,\n VersionedComputeEngine,\n} from \"./compute-types.js\";\nimport { ComputeEngineV1 } from \"./v1/compute/index.js\";\n\nexport interface ComputeRegistryOptions {\n readonly coreConfig?: CoreConfig;\n}\n\nexport class ComputeRegistry {\n private readonly engines = new ComputeEngineRegistry();\n private readonly evaluators = new ComputeEvaluatorRegistry();\n\n constructor(params: ComputeRegistryOptions = {}) {\n const resolvedCoreConfig = params.coreConfig ?? coreConfig;\n\n this.engines.register(\n new ComputeEngineV1({\n coreConfig: resolvedCoreConfig,\n }),\n );\n }\n\n register(registration: ComputeEvaluatorRegistration): void {\n this.evaluators.register(registration);\n }\n\n registerEngine(engine: VersionedComputeEngine): void {\n this.engines.register(engine);\n }\n\n getEngine(version: number): VersionedComputeEngine | undefined {\n return this.engines.get(version);\n }\n\n getEvaluator(\n policyKey: string,\n version: number,\n ): ComputeEvaluator | undefined {\n return this.evaluators.get(policyKey, version);\n }\n\n evaluate(\n policyKey: string,\n computeEngineVersion: number,\n payloadSchemaVersion: number,\n payload: unknown,\n context: PolicyContext,\n ): Result<ComputeOutcome, string> {\n return this.engines.evaluate(computeEngineVersion, {\n policyKey,\n payloadSchemaVersion,\n payload,\n context,\n evaluators: this.evaluators,\n });\n }\n}\n","import type { Result as ResultType } from \"../../result/result.js\";\nimport { Result } from \"../../result/result.js\";\n\nimport type { GatePayload } from \"./gate-payload.js\";\nimport { GatePayloadSchemaV1 } from \"./v1/gate/gate-v1-payload.schema.js\";\n\nexport type GatePayloadParser = (\n payload: unknown,\n) => ResultType<GatePayload, string>;\n\nexport class GatePayloadParserRegistry {\n private readonly parsers = new Map<number, GatePayloadParser>();\n\n register(engineVersion: number, parser: GatePayloadParser): void {\n this.parsers.set(engineVersion, parser);\n }\n\n get(engineVersion: number): GatePayloadParser | undefined {\n return this.parsers.get(engineVersion);\n }\n\n parse(engineVersion: number, payload: unknown) {\n const parser = this.parsers.get(engineVersion);\n\n if (parser === undefined) {\n return Result.err(\n `No gate payload parser registered for engine version \"${engineVersion}\"`,\n );\n }\n\n return parser(payload);\n }\n}\n\nexport class GatePayloadParsers {\n private static readonly registry = new GatePayloadParserRegistry();\n private static defaultsRegistered = false;\n\n // Registers the built-in v1 parser lazily, the first time the default\n // dispatcher is touched. Done here — rather than as a top-level module\n // statement — so the package's `\"sideEffects\": false` flag stays honest and\n // a tree-shaking bundler cannot drop the v1 registration and leave the gate\n // engine unable to parse v1 payloads at runtime.\n private static ensureDefaults(): void {\n if (GatePayloadParsers.defaultsRegistered) {\n return;\n }\n GatePayloadParsers.defaultsRegistered = true;\n GatePayloadParsers.registry.register(1, GatePayloadSchemaV1.parse);\n }\n\n static register(engineVersion: number, parser: GatePayloadParser): void {\n GatePayloadParsers.ensureDefaults();\n GatePayloadParsers.registry.register(engineVersion, parser);\n }\n\n static get(engineVersion: number): GatePayloadParser | undefined {\n GatePayloadParsers.ensureDefaults();\n return GatePayloadParsers.registry.get(engineVersion);\n }\n\n static parse(engineVersion: number, payload: unknown) {\n GatePayloadParsers.ensureDefaults();\n return GatePayloadParsers.registry.parse(engineVersion, payload);\n }\n}\n\nexport type { GatePayload };\n","import { Result } from \"../../result/result.js\";\n\nimport type {\n GateOutcome,\n PolicyContext,\n VersionedGateEngine,\n} from \"./gate-types.js\";\nimport { GatePayloadParsers } from \"./parse-gate-payload.js\";\n\nexport class GateEngineRegistry {\n private readonly engines = new Map<number, VersionedGateEngine>();\n\n register(engine: VersionedGateEngine): void {\n this.engines.set(engine.version, engine);\n }\n\n get(version: number): VersionedGateEngine | undefined {\n return this.engines.get(version);\n }\n\n evaluate(\n version: number,\n payload: unknown,\n context: PolicyContext,\n ): Result<GateOutcome, string> {\n const engine = this.engines.get(version);\n if (!engine) {\n return Result.err(\n `No gate engine registered for version \"${version}\"`,\n );\n }\n\n const parsedPayload = GatePayloadParsers.parse(version, payload);\n if (parsedPayload.isErr()) {\n return Result.err(parsedPayload.errorOrNull()!);\n }\n\n return engine.evaluate(parsedPayload.getOrNull()!, context);\n }\n}\n"],"mappings":"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"}
@@ -1,85 +1,5 @@
1
- //#region src/core/result/result.d.ts
2
- /**
3
- * Represents the outcome of an operation that may succeed or fail.
4
- * Useful for avoiding excessive exceptions and making error flows explicit.
5
- */
6
- declare abstract class Result<T, E> {
7
- protected constructor();
8
- /**
9
- * Creates a success result containing a value.
10
- */
11
- static ok<T>(value: T): Result<T, never>;
12
- /**
13
- * Creates an error result containing an error object.
14
- */
15
- static err<E>(error: E): Result<never, E>;
16
- /**
17
- * Returns true when this is a success result.
18
- */
19
- abstract isOk(): this is Ok<T>;
20
- /**
21
- * Returns true when this is an error result.
22
- */
23
- abstract isErr(): this is Err<E>;
24
- /**
25
- * Runs a handler based on the result state (similar to pattern matching).
26
- */
27
- abstract match<R>(handlers: {
28
- ok: (value: T) => R;
29
- err: (error: E) => R;
30
- }): R;
31
- /**
32
- * Returns the value when this is success, or null when this is an error.
33
- */
34
- getOrNull(): T | null;
35
- /**
36
- * Returns the error when this is a failure, or null when this is a success.
37
- */
38
- errorOrNull(): E | null;
39
- /**
40
- * Returns the value when this is a success, or throws the error when this is a failure.
41
- */
42
- getOrThrow(): T;
43
- /**
44
- * Transforms the success value using the provided function. Keeps the error when this is a failure.
45
- */
46
- map<R>(transform: (value: T) => R): Result<R, E>;
47
- /**
48
- * Transforms the error using the provided function. Keeps the value when this is a success.
49
- */
50
- mapError<F>(transform: (error: E) => F): Result<T, F>;
51
- /**
52
- * Chains another operation that returns a Result when this result is a success.
53
- */
54
- flatMap<R>(transform: (value: T) => Result<R, E>): Result<R, E>;
55
- }
56
- /**
57
- * Success variant of Result.
58
- */
59
- declare class Ok<T> extends Result<T, never> {
60
- readonly value: T;
61
- constructor(value: T);
62
- isOk(): this is Ok<T>;
63
- isErr(): this is Err<never>;
64
- match<R>(handlers: {
65
- ok: (value: T) => R;
66
- err: (error: never) => R;
67
- }): R;
68
- }
69
- /**
70
- * Error variant of Result.
71
- */
72
- declare class Err<E> extends Result<never, E> {
73
- readonly error: E;
74
- constructor(error: E);
75
- isOk(): this is Ok<never>;
76
- isErr(): this is Err<E>;
77
- match<R>(handlers: {
78
- ok: (value: never) => R;
79
- err: (error: E) => R;
80
- }): R;
81
- }
82
- //#endregion
1
+ import { a as Result, n as Outcome } from "./outcome.js";
2
+
83
3
  //#region src/core/policies/engines/condition-evaluator-reporter.d.ts
84
4
  interface ConditionEvaluationCause {
85
5
  readonly name: string;
@@ -173,62 +93,6 @@ declare class CoreConfig {
173
93
  getConditionEvaluationOptions(engineVersion: number): ConditionEvaluationOptions;
174
94
  }
175
95
  //#endregion
176
- //#region src/core/result/outcome.d.ts
177
- /**
178
- * Outcome — Business decision abstraction.
179
- *
180
- * Represents the semantic result of a domain decision, policy evaluation,
181
- * or business rule. NOT for technical success/failure — use Result for that.
182
- *
183
- * Mental model:
184
- * "What was the business decision?"
185
- * NOT "Did the operation succeed?"
186
- *
187
- * The status axis represents valid business outcomes (APPROVED, REJECTED,
188
- * ALLOW, DENY, NO_OP, etc.), never technical Ok/Err.
189
- *
190
- * @typeParam S - Union of valid status literals for this outcome
191
- * @typeParam D - Shape of the decision data carried by this outcome
192
- */
193
- declare class Outcome<S extends string, D = undefined> {
194
- readonly status: S;
195
- readonly data: D;
196
- readonly reason: string | undefined;
197
- readonly metadata: Readonly<Record<string, unknown>>;
198
- private constructor();
199
- static of<S extends string, D = undefined>(status: S, data: D, reason?: string, metadata?: Record<string, unknown>): Outcome<S, D>;
200
- static approved<D = undefined>(data: D, reason?: string): Outcome<"APPROVED", D>;
201
- static rejected<D = undefined>(data: D, reason: string): Outcome<"REJECTED", D>;
202
- static noOp<D = undefined>(data: D, reason?: string): Outcome<"NO_OP", D>;
203
- static deferred<D = undefined>(data: D, reason: string): Outcome<"DEFERRED", D>;
204
- static requiresReview<D = undefined>(data: D, reason: string): Outcome<"REQUIRES_REVIEW", D>;
205
- /**
206
- * Narrows this Outcome to a specific status.
207
- *
208
- * @example
209
- * if (outcome.is('DENY')) {
210
- * outcome.data.violations // TS knows status is 'DENY'
211
- * }
212
- */
213
- is<T extends S>(status: T): this is Outcome<T, D>;
214
- /**
215
- * Exhaustive pattern match over all possible statuses.
216
- * TypeScript enforces that every status has a handler.
217
- *
218
- * @example
219
- * outcome.match({
220
- * ALLOW: (o) => handleAllow(o.data),
221
- * DENY: (o) => handleDeny(o.data.violations),
222
- * })
223
- */
224
- match<THandlers extends { [K in S]: (outcome: Outcome<K, D>) => unknown }>(handlers: THandlers): ReturnType<THandlers[S]>;
225
- withMetadata(extra: Record<string, unknown>): Outcome<S, D>;
226
- withReason(reason: string): Outcome<S, D>;
227
- toString(): string;
228
- }
229
- /** Common business outcome statuses. Extend per domain as needed. */
230
- type CommonOutcomeStatus = "APPROVED" | "REJECTED" | "NO_OP" | "DEFERRED" | "REQUIRES_REVIEW";
231
- //#endregion
232
96
  //#region src/core/policies/engines/v1/condition-types.d.ts
233
97
  type ConditionOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "isNull" | "isNotNull";
234
98
  interface ConditionLeafNode {
@@ -303,5 +167,5 @@ interface VersionedGateEngine {
303
167
  evaluate(payload: GatePayload, context: PolicyContext): Result<GateOutcome, string>;
304
168
  }
305
169
  //#endregion
306
- export { ConditionEvaluationReport as A, TenantId as C, asTenantId as D, asSchoolId as E, Ok as F, Result as I, ConditionEvaluationReportTag as M, ConditionEvaluatorReporter as N, ConditionEvaluationCause as O, Err as P, SchoolId as S, asPolicyDefinitionId as T, CoreConfigOptions as _, GateTraceNodeSnapshot as a, PolicyDecisionId as b, PolicyViolation as c, GatePayloadV1 as d, ConditionLeafNode as f, CoreConfig as g, Outcome as h, GateTraceLeafSnapshot as i, ConditionEvaluationReportLevel as j, ConditionEvaluationOptions as k, VersionedGateEngine as l, CommonOutcomeStatus as m, GateOutcomeData as n, GateViolationTrace as o, ConditionNode as p, GateStatus as r, PolicyContext as s, GateOutcome as t, GatePayload as u, CoreObservabilityConfig as v, asPolicyDecisionId as w, PolicyDefinitionId as x, PolicyReporter as y };
170
+ export { ConditionEvaluationReportTag as A, asPolicyDefinitionId as C, ConditionEvaluationOptions as D, ConditionEvaluationCause as E, ConditionEvaluationReport as O, asPolicyDecisionId as S, asTenantId as T, PolicyReporter as _, GateTraceNodeSnapshot as a, SchoolId as b, PolicyViolation as c, GatePayloadV1 as d, ConditionLeafNode as f, CoreObservabilityConfig as g, CoreConfigOptions as h, GateTraceLeafSnapshot as i, ConditionEvaluatorReporter as j, ConditionEvaluationReportLevel as k, VersionedGateEngine as l, CoreConfig as m, GateOutcomeData as n, GateViolationTrace as o, ConditionNode as p, GateStatus as r, PolicyContext as s, GateOutcome as t, GatePayload as u, PolicyDecisionId as v, asSchoolId as w, TenantId as x, PolicyDefinitionId as y };
307
171
  //# sourceMappingURL=gate-types.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { r as isValidDate } from "./temporal-guards.js";
2
+ import { r as Result } from "./result.js";
2
3
  import { z } from "zod";
3
4
  //#region src/core/config/silent-policy-reporter.ts
4
5
  var SilentPolicyReporter = class {
@@ -70,121 +71,6 @@ var CoreConfig = class {
70
71
  */
71
72
  const coreConfig = new CoreConfig({ observability: { reporter: new SilentPolicyReporter() } });
72
73
  //#endregion
73
- //#region src/core/result/result.ts
74
- /**
75
- * Represents the outcome of an operation that may succeed or fail.
76
- * Useful for avoiding excessive exceptions and making error flows explicit.
77
- */
78
- var Result = class Result {
79
- constructor() {}
80
- /**
81
- * Creates a success result containing a value.
82
- */
83
- static ok(value) {
84
- return new Ok(value);
85
- }
86
- /**
87
- * Creates an error result containing an error object.
88
- */
89
- static err(error) {
90
- return new Err(error);
91
- }
92
- /**
93
- * Returns the value when this is success, or null when this is an error.
94
- */
95
- getOrNull() {
96
- return this.match({
97
- ok: (value) => value,
98
- err: () => null
99
- });
100
- }
101
- /**
102
- * Returns the error when this is a failure, or null when this is a success.
103
- */
104
- errorOrNull() {
105
- return this.match({
106
- ok: () => null,
107
- err: (error) => error
108
- });
109
- }
110
- /**
111
- * Returns the value when this is a success, or throws the error when this is a failure.
112
- */
113
- getOrThrow() {
114
- return this.match({
115
- ok: (value) => value,
116
- err: (error) => {
117
- throw error instanceof Error ? error : new Error(String(error));
118
- }
119
- });
120
- }
121
- /**
122
- * Transforms the success value using the provided function. Keeps the error when this is a failure.
123
- */
124
- map(transform) {
125
- return this.match({
126
- ok: (value) => Result.ok(transform(value)),
127
- err: (error) => Result.err(error)
128
- });
129
- }
130
- /**
131
- * Transforms the error using the provided function. Keeps the value when this is a success.
132
- */
133
- mapError(transform) {
134
- return this.match({
135
- ok: (value) => Result.ok(value),
136
- err: (error) => Result.err(transform(error))
137
- });
138
- }
139
- /**
140
- * Chains another operation that returns a Result when this result is a success.
141
- */
142
- flatMap(transform) {
143
- return this.match({
144
- ok: (value) => transform(value),
145
- err: (error) => Result.err(error)
146
- });
147
- }
148
- };
149
- /**
150
- * Success variant of Result.
151
- */
152
- var Ok = class extends Result {
153
- constructor(value) {
154
- super();
155
- this.value = value;
156
- Object.freeze(this);
157
- }
158
- isOk() {
159
- return true;
160
- }
161
- isErr() {
162
- return false;
163
- }
164
- match(handlers) {
165
- return handlers.ok(this.value);
166
- }
167
- };
168
- /**
169
- * Error variant of Result.
170
- */
171
- var Err = class extends Result {
172
- constructor(error) {
173
- super();
174
- this.error = error;
175
- Object.freeze(this);
176
- }
177
- isOk() {
178
- return false;
179
- }
180
- isErr() {
181
- return true;
182
- }
183
- match(handlers) {
184
- return handlers.err(this.error);
185
- }
186
- };
187
- //#endregion
188
74
  //#region src/core/policies/utils/date.ts
189
75
  var PolicyDateUtils = class {
190
76
  static isValid(value) {
@@ -694,6 +580,6 @@ var GatePayloadSchemaV1 = class GatePayloadSchemaV1 {
694
580
  };
695
581
  const gatePayloadSchema = GatePayloadSchemaV1.schema;
696
582
  //#endregion
697
- export { conditionNodeSchema as a, Ok as c, CoreConfig as d, SilentPolicyReporter as f, conditionLeafNodeSchema as i, Result as l, gatePayloadSchema as n, PolicyContextPath as o, ConditionEvaluatorV1 as r, Err as s, GatePayloadSchemaV1 as t, coreConfig as u };
583
+ export { conditionNodeSchema as a, CoreConfig as c, conditionLeafNodeSchema as i, SilentPolicyReporter as l, gatePayloadSchema as n, PolicyContextPath as o, ConditionEvaluatorV1 as r, coreConfig as s, GatePayloadSchemaV1 as t };
698
584
 
699
585
  //# sourceMappingURL=gate-v1-payload.schema.js.map