@cullet/erp-core 1.0.2 → 1.0.4

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 (146) hide show
  1. package/README.md +24 -24
  2. package/dist/gate-engine-registry.js.map +1 -1
  3. package/dist/gate-v1-payload.schema.js +5 -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 +1 -1
  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 +1 -0
  10. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  11. package/dist/policy-service.js.map +1 -1
  12. package/dist/validation-code.js.map +1 -1
  13. package/dist/validation-error.js.map +1 -1
  14. package/dist/validation-field.js.map +1 -1
  15. package/meta.json +67 -67
  16. package/package.json +56 -56
  17. package/src/core/application/commands/command.ts +3 -3
  18. package/src/core/application/commands/requested-by.ts +60 -60
  19. package/src/core/application/index.ts +21 -21
  20. package/src/core/application/policy-error-mapper.ts +54 -54
  21. package/src/core/application/ports/index.ts +6 -6
  22. package/src/core/application/ports/logger.port.ts +4 -4
  23. package/src/core/application/ports/metrics.port.ts +3 -3
  24. package/src/core/application/ports/policy-port.ts +7 -7
  25. package/src/core/application/ports/repository.port.ts +3 -3
  26. package/src/core/application/ports/temporal-repository.port.ts +4 -4
  27. package/src/core/application/ports/tracer.port.ts +7 -7
  28. package/src/core/application/queries/query.ts +13 -13
  29. package/src/core/application/temporal/index.ts +7 -7
  30. package/src/core/application/temporal/temporal-context.ts +20 -20
  31. package/src/core/application/temporal/temporal-use-case.ts +22 -22
  32. package/src/core/application/use-case.ts +10 -10
  33. package/src/core/config/core-config.instance.ts +1 -1
  34. package/src/core/config/core-config.ts +59 -59
  35. package/src/core/config/index.ts +6 -6
  36. package/src/core/config/policy-reporter.ts +31 -31
  37. package/src/core/config/silent-policy-reporter.ts +1 -1
  38. package/src/core/domain/entity.ts +44 -44
  39. package/src/core/domain/rulesets/entity-ruleset.contracts.ts +6 -6
  40. package/src/core/domain/rulesets/ruleset-registry.ts +49 -49
  41. package/src/core/domain/rulesets/ruleset.contracts.ts +6 -6
  42. package/src/core/domain/rulesets/value-object-ruleset.contracts.ts +5 -5
  43. package/src/core/domain/temporal/index.ts +11 -11
  44. package/src/core/domain/temporal/temporal-range.ts +16 -16
  45. package/src/core/domain/temporal/temporal-snapshot.ts +24 -24
  46. package/src/core/domain/temporal/transaction-time.ts +30 -30
  47. package/src/core/domain/temporal/valid-time.ts +29 -29
  48. package/src/core/domain/value-object.ts +16 -16
  49. package/src/core/errors/app-error.ts +64 -64
  50. package/src/core/errors/authentication-error.ts +134 -134
  51. package/src/core/errors/authorization-error.ts +154 -154
  52. package/src/core/errors/business-rule-violation-error.ts +15 -15
  53. package/src/core/errors/conflict-error.ts +202 -201
  54. package/src/core/errors/error-codes.ts +48 -48
  55. package/src/core/errors/idempotency-error.ts +324 -320
  56. package/src/core/errors/index.ts +50 -50
  57. package/src/core/errors/integration-error.ts +120 -120
  58. package/src/core/errors/legacy-incompatible-error.ts +13 -13
  59. package/src/core/errors/not-found-error.ts +14 -14
  60. package/src/core/errors/serialization-error.ts +167 -167
  61. package/src/core/errors/temporal-error.ts +109 -107
  62. package/src/core/errors/types.ts +35 -35
  63. package/src/core/errors/unexpected-error.ts +10 -10
  64. package/src/core/errors/utils/index.ts +2 -2
  65. package/src/core/errors/utils/json-safe.ts +53 -53
  66. package/src/core/errors/validation-error.ts +18 -18
  67. package/src/core/exceptions/business-rule-violation-exception.ts +6 -6
  68. package/src/core/exceptions/domain-exception.ts +5 -5
  69. package/src/core/exceptions/entity-not-found-exception.ts +6 -6
  70. package/src/core/exceptions/invalid-state-transition-exception.ts +8 -8
  71. package/src/core/exceptions/invariant-violation-exception.ts +3 -3
  72. package/src/core/exceptions/validation-code.ts +35 -29
  73. package/src/core/exceptions/validation-exception.ts +19 -19
  74. package/src/core/exceptions/validation-field.ts +20 -19
  75. package/src/core/index.ts +7 -7
  76. package/src/core/policies/asof/asof.ts +47 -47
  77. package/src/core/policies/catalog/catalog.instance.ts +8 -6
  78. package/src/core/policies/catalog/index.ts +4 -4
  79. package/src/core/policies/catalog/policy-catalog-entry.ts +199 -197
  80. package/src/core/policies/catalog/policy-catalog.ts +101 -101
  81. package/src/core/policies/catalog/policy-key.ts +51 -51
  82. package/src/core/policies/context/context-builder.ts +335 -313
  83. package/src/core/policies/context/context-registry.instance.ts +9 -9
  84. package/src/core/policies/context/context-registry.ts +61 -61
  85. package/src/core/policies/context/context-resolver.ts +12 -12
  86. package/src/core/policies/context/context-seed.ts +19 -15
  87. package/src/core/policies/context/index.ts +9 -9
  88. package/src/core/policies/context/path.ts +135 -128
  89. package/src/core/policies/defs/in-memory-policy-definition-repo.ts +56 -55
  90. package/src/core/policies/defs/index.ts +10 -10
  91. package/src/core/policies/defs/policy-definition-repository.ts +3 -3
  92. package/src/core/policies/defs/policy-definition.ts +143 -142
  93. package/src/core/policies/defs/policy-scope.ts +21 -19
  94. package/src/core/policies/defs/policy-semver.ts +51 -51
  95. package/src/core/policies/engines/compute-engine-registry.ts +43 -43
  96. package/src/core/policies/engines/compute-evaluator-registry.ts +20 -20
  97. package/src/core/policies/engines/compute-registry.ts +45 -45
  98. package/src/core/policies/engines/compute-types.ts +15 -15
  99. package/src/core/policies/engines/condition-evaluator-reporter.ts +17 -17
  100. package/src/core/policies/engines/gate-engine-registry.ts +27 -25
  101. package/src/core/policies/engines/gate-types.ts +28 -28
  102. package/src/core/policies/engines/index.ts +28 -28
  103. package/src/core/policies/engines/parse-compute-payload.ts +51 -45
  104. package/src/core/policies/engines/parse-gate-payload.ts +42 -42
  105. package/src/core/policies/engines/v1/compute/compute-engine-v1.ts +39 -37
  106. package/src/core/policies/engines/v1/compute/compute-payload.schema.ts +43 -41
  107. package/src/core/policies/engines/v1/compute/index.ts +6 -6
  108. package/src/core/policies/engines/v1/compute/resolve-decision-table-v1.ts +41 -39
  109. package/src/core/policies/engines/v1/condition-evaluator.ts +557 -504
  110. package/src/core/policies/engines/v1/condition-schema.ts +35 -35
  111. package/src/core/policies/engines/v1/condition-types.ts +21 -21
  112. package/src/core/policies/engines/v1/gate/gate-engine-v1.ts +134 -130
  113. package/src/core/policies/engines/v1/gate/gate-types-v1.ts +5 -5
  114. package/src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts +32 -30
  115. package/src/core/policies/engines/v1/gate/index.ts +4 -4
  116. package/src/core/policies/engines/v1/index.ts +8 -8
  117. package/src/core/policies/index.ts +72 -72
  118. package/src/core/policies/package/policy-package.ts +3 -3
  119. package/src/core/policies/policy-ids.ts +25 -25
  120. package/src/core/policies/resolver/policy-resolver.ts +34 -34
  121. package/src/core/policies/service/index.ts +6 -6
  122. package/src/core/policies/service/policy-evaluation-error.ts +141 -133
  123. package/src/core/policies/service/policy-service.ts +432 -419
  124. package/src/core/policies/utils/date.ts +3 -3
  125. package/src/core/policies/utils/hash.ts +61 -61
  126. package/src/core/result/outcome.ts +131 -126
  127. package/src/core/result/result.ts +130 -127
  128. package/src/core/shared/aggregate-version.ts +5 -5
  129. package/src/core/shared/hashing.ts +18 -18
  130. package/src/core/shared/immutable.ts +29 -29
  131. package/src/core/shared/temporal-guards.ts +9 -9
  132. package/src/core/versioning/domain-event-contracts.ts +40 -40
  133. package/src/core/versioning/version.ts +19 -19
  134. package/src/examples/rulesets/entity/order-creation-rules-v1.ts +18 -18
  135. package/src/examples/rulesets/entity/order-invariants-v1.ts +31 -29
  136. package/src/examples/rulesets/entity/order-invariants-v2.ts +12 -12
  137. package/src/examples/rulesets/entity/order.ts +127 -127
  138. package/src/examples/rulesets/value-object/cpf-rules-v1.ts +41 -39
  139. package/src/examples/rulesets/value-object/cpf-rules-v2.ts +14 -12
  140. package/src/examples/rulesets/value-object/cpf.ts +24 -24
  141. package/src/examples/rulesets/value-object/customer.ts +42 -39
  142. package/src/examples/rulesets/value-object/person-name-rules-v1.ts +27 -27
  143. package/src/examples/rulesets/value-object/person-name-rules-v2.ts +13 -13
  144. package/src/examples/rulesets/value-object/person-name.ts +29 -26
  145. package/src/index.ts +2 -2
  146. package/src/version.ts +1 -1
@@ -7,44 +7,44 @@ import type { ConditionLeafNode, ConditionNode } from "./condition-types";
7
7
  // condition nodes without either engine depending on the other.
8
8
 
9
9
  const conditionOpSchema = z.enum([
10
- "eq",
11
- "neq",
12
- "gt",
13
- "gte",
14
- "lt",
15
- "lte",
16
- "in",
17
- "notIn",
18
- "isNull",
19
- "isNotNull",
10
+ "eq",
11
+ "neq",
12
+ "gt",
13
+ "gte",
14
+ "lt",
15
+ "lte",
16
+ "in",
17
+ "notIn",
18
+ "isNull",
19
+ "isNotNull",
20
20
  ]);
21
21
 
22
22
  export const conditionLeafNodeSchema: z.ZodType<ConditionLeafNode> = z
23
- .object({
24
- field: z.string().min(1),
25
- op: conditionOpSchema,
26
- value: z.unknown(),
27
- allowNull: z.literal(true).optional(),
28
- })
29
- .strict() as z.ZodType<ConditionLeafNode>;
23
+ .object({
24
+ field: z.string().min(1),
25
+ op: conditionOpSchema,
26
+ value: z.unknown(),
27
+ allowNull: z.literal(true).optional(),
28
+ })
29
+ .strict() as z.ZodType<ConditionLeafNode>;
30
30
 
31
31
  export const conditionNodeSchema: z.ZodType<ConditionNode> = z.lazy(() =>
32
- z.union([
33
- conditionLeafNodeSchema,
34
- z
35
- .object({
36
- and: z.array(conditionNodeSchema).min(1),
37
- })
38
- .strict(),
39
- z
40
- .object({
41
- or: z.array(conditionNodeSchema).min(1),
42
- })
43
- .strict(),
44
- z
45
- .object({
46
- not: conditionNodeSchema,
47
- })
48
- .strict(),
49
- ]),
32
+ z.union([
33
+ conditionLeafNodeSchema,
34
+ z
35
+ .object({
36
+ and: z.array(conditionNodeSchema).min(1),
37
+ })
38
+ .strict(),
39
+ z
40
+ .object({
41
+ or: z.array(conditionNodeSchema).min(1),
42
+ })
43
+ .strict(),
44
+ z
45
+ .object({
46
+ not: conditionNodeSchema,
47
+ })
48
+ .strict(),
49
+ ]),
50
50
  );
@@ -4,38 +4,38 @@
4
4
  // structurally dependent on gate/v1.
5
5
 
6
6
  export type ConditionOp =
7
- | "eq"
8
- | "neq"
9
- | "gt"
10
- | "gte"
11
- | "lt"
12
- | "lte"
13
- | "in"
14
- | "notIn"
15
- | "isNull"
16
- | "isNotNull";
7
+ | "eq"
8
+ | "neq"
9
+ | "gt"
10
+ | "gte"
11
+ | "lt"
12
+ | "lte"
13
+ | "in"
14
+ | "notIn"
15
+ | "isNull"
16
+ | "isNotNull";
17
17
 
18
18
  export interface ConditionLeafNode {
19
- readonly field: string;
20
- readonly op: ConditionOp;
21
- readonly value: unknown;
22
- readonly allowNull?: true;
19
+ readonly field: string;
20
+ readonly op: ConditionOp;
21
+ readonly value: unknown;
22
+ readonly allowNull?: true;
23
23
  }
24
24
 
25
25
  export interface ConditionAndNode {
26
- readonly and: readonly ConditionNode[];
26
+ readonly and: readonly ConditionNode[];
27
27
  }
28
28
 
29
29
  export interface ConditionOrNode {
30
- readonly or: readonly ConditionNode[];
30
+ readonly or: readonly ConditionNode[];
31
31
  }
32
32
 
33
33
  export interface ConditionNotNode {
34
- readonly not: ConditionNode;
34
+ readonly not: ConditionNode;
35
35
  }
36
36
 
37
37
  export type ConditionNode =
38
- | ConditionLeafNode
39
- | ConditionAndNode
40
- | ConditionOrNode
41
- | ConditionNotNode;
38
+ | ConditionLeafNode
39
+ | ConditionAndNode
40
+ | ConditionOrNode
41
+ | ConditionNotNode;
@@ -3,155 +3,159 @@ import { Outcome } from "../../../../result/outcome";
3
3
  import { Result } from "../../../../result/result";
4
4
 
5
5
  import {
6
- ConditionEvaluatorV1,
7
- type TracedConditionEvaluation,
6
+ ConditionEvaluatorV1,
7
+ type TracedConditionEvaluation,
8
8
  } from "../condition-evaluator";
9
9
  import type { ConditionLeafNode, ConditionNode } from "../condition-types";
10
10
  import type { GatePayload } from "../../gate-payload";
11
11
  import type {
12
- GateOutcome,
13
- GateStatus,
14
- GateTraceLeafSnapshot,
15
- GateTraceNodeSnapshot,
16
- PolicyContext,
17
- PolicyViolation,
18
- VersionedGateEngine,
12
+ GateOutcome,
13
+ GateStatus,
14
+ GateTraceLeafSnapshot,
15
+ GateTraceNodeSnapshot,
16
+ PolicyContext,
17
+ PolicyViolation,
18
+ VersionedGateEngine,
19
19
  } from "../../gate-types";
20
20
 
21
21
  // ─── Gate engine v1 ─────────────────────────────────────────────────────────
22
22
 
23
23
  export class GateEngineV1 implements VersionedGateEngine {
24
- public readonly version = 1;
25
- private readonly coreConfig: CoreConfig;
26
-
27
- constructor(params: { readonly coreConfig?: CoreConfig } = {}) {
28
- this.coreConfig = params.coreConfig ?? coreConfig;
29
- }
30
-
31
- private allow(): Result<GateOutcome, string> {
32
- return Result.ok(Outcome.of("ALLOW", { violations: [] }));
33
- }
34
-
35
- private deny(violation: PolicyViolation): Result<GateOutcome, string> {
36
- return Result.ok(
37
- Outcome.of("DENY", {
38
- violations: [violation],
39
- }),
40
- );
41
- }
42
-
43
- private outcomeFromStatus(
44
- status: GateStatus,
45
- violation: PolicyViolation,
46
- ): Result<GateOutcome, string> {
47
- return status === "ALLOW" ? this.allow() : this.deny(violation);
48
- }
49
-
50
- private isLeafNode(node: ConditionNode): node is ConditionLeafNode {
51
- return "field" in node && "op" in node;
52
- }
53
-
54
- private toLeafSnapshot(node: ConditionLeafNode): GateTraceLeafSnapshot {
55
- return {
56
- kind: "LEAF",
57
- field: node.field,
58
- op: node.op,
59
- ...(node.allowNull === true ? { allowNull: true } : {}),
60
- };
61
- }
62
-
63
- private toNodeSnapshot(node: ConditionNode): GateTraceNodeSnapshot {
64
- if (this.isLeafNode(node)) {
65
- return this.toLeafSnapshot(node);
24
+ public readonly version = 1;
25
+ private readonly coreConfig: CoreConfig;
26
+
27
+ constructor(params: { readonly coreConfig?: CoreConfig } = {}) {
28
+ this.coreConfig = params.coreConfig ?? coreConfig;
29
+ }
30
+
31
+ private allow(): Result<GateOutcome, string> {
32
+ return Result.ok(Outcome.of("ALLOW", { violations: [] }));
33
+ }
34
+
35
+ private deny(violation: PolicyViolation): Result<GateOutcome, string> {
36
+ return Result.ok(
37
+ Outcome.of("DENY", {
38
+ violations: [violation],
39
+ }),
40
+ );
41
+ }
42
+
43
+ private outcomeFromStatus(
44
+ status: GateStatus,
45
+ violation: PolicyViolation,
46
+ ): Result<GateOutcome, string> {
47
+ return status === "ALLOW" ? this.allow() : this.deny(violation);
66
48
  }
67
49
 
68
- if ("and" in node) {
69
- return {
70
- kind: "AND",
71
- childCount: node.and.length,
72
- };
50
+ private isLeafNode(node: ConditionNode): node is ConditionLeafNode {
51
+ return "field" in node && "op" in node;
73
52
  }
74
53
 
75
- if ("or" in node) {
76
- return {
77
- kind: "OR",
78
- childCount: node.or.length,
79
- };
54
+ private toLeafSnapshot(node: ConditionLeafNode): GateTraceLeafSnapshot {
55
+ return {
56
+ kind: "LEAF",
57
+ field: node.field,
58
+ op: node.op,
59
+ ...(node.allowNull === true ? { allowNull: true } : {}),
60
+ };
80
61
  }
81
62
 
82
- return {
83
- kind: "NOT",
84
- };
85
- }
86
-
87
- private buildDenyViolation(
88
- conditionResult: TracedConditionEvaluation,
89
- ): PolicyViolation {
90
- return {
91
- code: "DENY_CONDITION_MET",
92
- message: `Gate denied at ${conditionResult.trace.conditionPath}`,
93
- trace: {
94
- conditionPath: conditionResult.trace.conditionPath,
95
- decisiveNode: this.toNodeSnapshot(conditionResult.trace.decisiveNode),
96
- lastEvaluatedLeaf: this.toLeafSnapshot(
97
- conditionResult.trace.lastEvaluatedLeaf,
98
- ),
99
- lastEvaluatedLeafPath: conditionResult.trace.lastEvaluatedLeafPath,
100
- lastEvaluatedLeafResult: conditionResult.trace.lastEvaluatedLeafResult,
101
- field: conditionResult.trace.lastEvaluatedLeaf.field,
102
- op: conditionResult.trace.lastEvaluatedLeaf.op,
103
- },
104
- };
105
- }
106
-
107
- private normalizePayload(payload: GatePayload): {
108
- readonly allowIf: ConditionNode;
109
- readonly defaultOutcome: "ALLOW" | "DENY";
110
- } {
111
- if ("condition" in payload) {
112
- return {
113
- allowIf: payload.condition,
114
- defaultOutcome: "DENY",
115
- };
63
+ private toNodeSnapshot(node: ConditionNode): GateTraceNodeSnapshot {
64
+ if (this.isLeafNode(node)) {
65
+ return this.toLeafSnapshot(node);
66
+ }
67
+
68
+ if ("and" in node) {
69
+ return {
70
+ kind: "AND",
71
+ childCount: node.and.length,
72
+ };
73
+ }
74
+
75
+ if ("or" in node) {
76
+ return {
77
+ kind: "OR",
78
+ childCount: node.or.length,
79
+ };
80
+ }
81
+
82
+ return {
83
+ kind: "NOT",
84
+ };
116
85
  }
117
86
 
118
- return payload;
119
- }
120
-
121
- /**
122
- * Evaluates a GATE payload against a context object.
123
- * Pure function no side effects.
124
- *
125
- * Receives an already-parsed `GatePayload`; the registry is responsible
126
- * for parsing from raw `unknown` before calling this method.
127
- * Returns Result for technical failures (condition evaluation errors).
128
- * The Outcome inside carries the business decision (ALLOW/DENY).
129
- */
130
- evaluate(
131
- payload: GatePayload,
132
- context: PolicyContext,
133
- ): Result<GateOutcome, string> {
134
- const gatePayload = this.normalizePayload(payload);
135
- const conditionEvaluator = new ConditionEvaluatorV1(
136
- context,
137
- this.coreConfig.getConditionEvaluationOptions(this.version),
138
- );
139
-
140
- const isAllowedResult = conditionEvaluator.evaluateWithTrace(
141
- gatePayload.allowIf,
142
- );
143
- if (isAllowedResult.isErr()) {
144
- return Result.err(isAllowedResult.errorOrNull()!);
87
+ private buildDenyViolation(
88
+ conditionResult: TracedConditionEvaluation,
89
+ ): PolicyViolation {
90
+ return {
91
+ code: "DENY_CONDITION_MET",
92
+ message: `Gate denied at ${conditionResult.trace.conditionPath}`,
93
+ trace: {
94
+ conditionPath: conditionResult.trace.conditionPath,
95
+ decisiveNode: this.toNodeSnapshot(
96
+ conditionResult.trace.decisiveNode,
97
+ ),
98
+ lastEvaluatedLeaf: this.toLeafSnapshot(
99
+ conditionResult.trace.lastEvaluatedLeaf,
100
+ ),
101
+ lastEvaluatedLeafPath:
102
+ conditionResult.trace.lastEvaluatedLeafPath,
103
+ lastEvaluatedLeafResult:
104
+ conditionResult.trace.lastEvaluatedLeafResult,
105
+ field: conditionResult.trace.lastEvaluatedLeaf.field,
106
+ op: conditionResult.trace.lastEvaluatedLeaf.op,
107
+ },
108
+ };
145
109
  }
146
110
 
147
- const isAllowed = isAllowedResult.getOrNull()!;
148
- if (isAllowed.matched) {
149
- return this.allow();
111
+ private normalizePayload(payload: GatePayload): {
112
+ readonly allowIf: ConditionNode;
113
+ readonly defaultOutcome: "ALLOW" | "DENY";
114
+ } {
115
+ if ("condition" in payload) {
116
+ return {
117
+ allowIf: payload.condition,
118
+ defaultOutcome: "DENY",
119
+ };
120
+ }
121
+
122
+ return payload;
150
123
  }
151
124
 
152
- return this.outcomeFromStatus(
153
- gatePayload.defaultOutcome,
154
- this.buildDenyViolation(isAllowed),
155
- );
156
- }
125
+ /**
126
+ * Evaluates a GATE payload against a context object.
127
+ * Pure function — no side effects.
128
+ *
129
+ * Receives an already-parsed `GatePayload`; the registry is responsible
130
+ * for parsing from raw `unknown` before calling this method.
131
+ * Returns Result for technical failures (condition evaluation errors).
132
+ * The Outcome inside carries the business decision (ALLOW/DENY).
133
+ */
134
+ evaluate(
135
+ payload: GatePayload,
136
+ context: PolicyContext,
137
+ ): Result<GateOutcome, string> {
138
+ const gatePayload = this.normalizePayload(payload);
139
+ const conditionEvaluator = new ConditionEvaluatorV1(
140
+ context,
141
+ this.coreConfig.getConditionEvaluationOptions(this.version),
142
+ );
143
+
144
+ const isAllowedResult = conditionEvaluator.evaluateWithTrace(
145
+ gatePayload.allowIf,
146
+ );
147
+ if (isAllowedResult.isErr()) {
148
+ return Result.err(isAllowedResult.errorOrNull()!);
149
+ }
150
+
151
+ const isAllowed = isAllowedResult.getOrNull()!;
152
+ if (isAllowed.matched) {
153
+ return this.allow();
154
+ }
155
+
156
+ return this.outcomeFromStatus(
157
+ gatePayload.defaultOutcome,
158
+ this.buildDenyViolation(isAllowed),
159
+ );
160
+ }
157
161
  }
@@ -5,8 +5,8 @@
5
5
  import type { ConditionNode } from "../condition-types";
6
6
 
7
7
  export type GatePayloadV1 =
8
- | { readonly condition: ConditionNode }
9
- | {
10
- readonly allowIf: ConditionNode;
11
- readonly defaultOutcome: "ALLOW" | "DENY";
12
- };
8
+ | { readonly condition: ConditionNode }
9
+ | {
10
+ readonly allowIf: ConditionNode;
11
+ readonly defaultOutcome: "ALLOW" | "DENY";
12
+ };
@@ -4,43 +4,45 @@ import { Result } from "../../../../result/result";
4
4
 
5
5
  import type { GatePayloadV1 } from "./gate-types-v1";
6
6
  import {
7
- conditionLeafNodeSchema,
8
- conditionNodeSchema,
7
+ conditionLeafNodeSchema,
8
+ conditionNodeSchema,
9
9
  } from "../condition-schema";
10
10
 
11
11
  // Re-export so gate/v1 public API remains unchanged.
12
12
  export { conditionLeafNodeSchema, conditionNodeSchema };
13
13
 
14
14
  export class GatePayloadSchemaV1 {
15
- static readonly schema = z.union([
16
- z
17
- .object({
18
- condition: conditionNodeSchema,
19
- })
20
- .strict(),
21
- z
22
- .object({
23
- allowIf: conditionNodeSchema,
24
- defaultOutcome: z.enum(["ALLOW", "DENY"]),
25
- })
26
- .strict(),
27
- ]);
28
-
29
- static parse(payload: unknown): Result<GatePayloadV1, string> {
30
- const parsed = GatePayloadSchemaV1.schema.safeParse(payload);
31
- if (!parsed.success) {
32
- const details = parsed.error.issues
33
- .map((issue) => {
34
- const path = issue.path.join(".");
35
- return path.length > 0 ? `${path}: ${issue.message}` : issue.message;
36
- })
37
- .join("; ");
38
-
39
- return Result.err(`Invalid gate payload: ${details}`);
15
+ static readonly schema = z.union([
16
+ z
17
+ .object({
18
+ condition: conditionNodeSchema,
19
+ })
20
+ .strict(),
21
+ z
22
+ .object({
23
+ allowIf: conditionNodeSchema,
24
+ defaultOutcome: z.enum(["ALLOW", "DENY"]),
25
+ })
26
+ .strict(),
27
+ ]);
28
+
29
+ static parse(payload: unknown): Result<GatePayloadV1, string> {
30
+ const parsed = GatePayloadSchemaV1.schema.safeParse(payload);
31
+ if (!parsed.success) {
32
+ const details = parsed.error.issues
33
+ .map((issue) => {
34
+ const path = issue.path.join(".");
35
+ return path.length > 0
36
+ ? `${path}: ${issue.message}`
37
+ : issue.message;
38
+ })
39
+ .join("; ");
40
+
41
+ return Result.err(`Invalid gate payload: ${details}`);
42
+ }
43
+
44
+ return Result.ok(parsed.data as GatePayloadV1);
40
45
  }
41
-
42
- return Result.ok(parsed.data as GatePayloadV1);
43
- }
44
46
  }
45
47
 
46
48
  export const gatePayloadSchema = GatePayloadSchemaV1.schema;
@@ -2,8 +2,8 @@ export { ConditionEvaluatorV1 } from "../condition-evaluator";
2
2
  export { GateEngineV1 } from "./gate-engine-v1";
3
3
  export type { GatePayloadV1 } from "./gate-types-v1";
4
4
  export {
5
- conditionLeafNodeSchema,
6
- conditionNodeSchema,
7
- gatePayloadSchema,
8
- GatePayloadSchemaV1,
5
+ conditionLeafNodeSchema,
6
+ conditionNodeSchema,
7
+ gatePayloadSchema,
8
+ GatePayloadSchemaV1,
9
9
  } from "./gate-v1-payload.schema";
@@ -1,13 +1,13 @@
1
1
  export { ConditionEvaluatorV1 } from "./condition-evaluator";
2
2
  export {
3
- conditionLeafNodeSchema,
4
- conditionNodeSchema,
3
+ conditionLeafNodeSchema,
4
+ conditionNodeSchema,
5
5
  } from "./condition-schema";
6
6
  export type {
7
- ConditionAndNode,
8
- ConditionLeafNode,
9
- ConditionNode,
10
- ConditionNotNode,
11
- ConditionOp,
12
- ConditionOrNode,
7
+ ConditionAndNode,
8
+ ConditionLeafNode,
9
+ ConditionNode,
10
+ ConditionNotNode,
11
+ ConditionOp,
12
+ ConditionOrNode,
13
13
  } from "./condition-types";