@cullet/erp-core 1.2.0 → 1.4.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 (218) hide show
  1. package/KIT_CONTEXT.md +5 -3
  2. package/README.md +160 -0
  3. package/dist/abac/index.cjs +7 -0
  4. package/dist/abac/index.d.cts +2 -0
  5. package/dist/abac/index.d.ts +2 -0
  6. package/dist/abac/index.js +2 -0
  7. package/dist/app-error.cjs +193 -0
  8. package/dist/app-error.cjs.map +1 -0
  9. package/dist/app-error.d.cts +108 -0
  10. package/dist/app-error.js +170 -0
  11. package/dist/app-error.js.map +1 -0
  12. package/dist/application/index.cjs +27 -0
  13. package/dist/application/index.d.cts +3 -0
  14. package/dist/application/index.d.ts +2 -1
  15. package/dist/application/index.js +2 -1
  16. package/dist/authorization-error.cjs +157 -0
  17. package/dist/authorization-error.cjs.map +1 -0
  18. package/dist/authorization-error.d.cts +113 -0
  19. package/dist/authorization-error.d.ts +113 -0
  20. package/dist/authorization-error.js +152 -0
  21. package/dist/authorization-error.js.map +1 -0
  22. package/dist/authorizer.port.d.cts +130 -0
  23. package/dist/authorizer.port.d.ts +130 -0
  24. package/dist/composite-authorizer.d.cts +216 -0
  25. package/dist/composite-authorizer.d.ts +216 -0
  26. package/dist/condition-evaluator.cjs +565 -0
  27. package/dist/condition-evaluator.cjs.map +1 -0
  28. package/dist/condition-evaluator.js +536 -0
  29. package/dist/condition-evaluator.js.map +1 -0
  30. package/dist/core-config.d.cts +172 -0
  31. package/dist/{gate-types.d.ts → core-config.d.ts} +78 -77
  32. package/dist/domain/index.cjs +17 -0
  33. package/dist/domain/index.d.cts +4 -0
  34. package/dist/domain/index.d.ts +2 -1
  35. package/dist/domain/index.js +2 -1
  36. package/dist/domain-event-contracts.cjs +34 -0
  37. package/dist/domain-event-contracts.cjs.map +1 -0
  38. package/dist/domain-event-contracts.d.cts +27 -0
  39. package/dist/domain-event-contracts.js +2 -1
  40. package/dist/domain-event-contracts.js.map +1 -1
  41. package/dist/domain-exception.cjs +17 -0
  42. package/dist/domain-exception.cjs.map +1 -0
  43. package/dist/domain-exception.d.cts +7 -0
  44. package/dist/entity.cjs +126 -0
  45. package/dist/entity.cjs.map +1 -0
  46. package/dist/entity.js +115 -0
  47. package/dist/entity.js.map +1 -0
  48. package/dist/errors/index.cjs +43 -0
  49. package/dist/errors/index.d.cts +4 -0
  50. package/dist/errors/index.d.ts +2 -1
  51. package/dist/errors/index.js +4 -2
  52. package/dist/exceptions/index.cjs +17 -0
  53. package/dist/exceptions/index.d.cts +5 -0
  54. package/dist/exceptions/validation-field.cjs +3 -0
  55. package/dist/exceptions/validation-field.d.cts +2 -0
  56. package/dist/gate-engine-registry.cjs +309 -0
  57. package/dist/gate-engine-registry.cjs.map +1 -0
  58. package/dist/gate-engine-registry.d.cts +82 -0
  59. package/dist/gate-engine-registry.d.ts +3 -2
  60. package/dist/gate-engine-registry.js +2 -1
  61. package/dist/gate-engine-registry.js.map +1 -1
  62. package/dist/gate-v1-payload.schema.cjs +76 -0
  63. package/dist/gate-v1-payload.schema.cjs.map +1 -0
  64. package/dist/gate-v1-payload.schema.js +1 -533
  65. package/dist/gate-v1-payload.schema.js.map +1 -1
  66. package/dist/hashing.cjs +66 -0
  67. package/dist/hashing.cjs.map +1 -0
  68. package/dist/immutable.cjs +77 -0
  69. package/dist/immutable.cjs.map +1 -0
  70. package/dist/immutable.d.cts +6 -0
  71. package/dist/index.cjs +181 -0
  72. package/dist/index.cjs.map +1 -0
  73. package/dist/index.d.cts +37 -0
  74. package/dist/index.d.ts +19 -12
  75. package/dist/index.js +15 -9
  76. package/dist/index.js.map +1 -1
  77. package/dist/invalid-state-transition-exception.cjs +47 -0
  78. package/dist/invalid-state-transition-exception.cjs.map +1 -0
  79. package/dist/invariant-violation-exception.cjs +16 -0
  80. package/dist/invariant-violation-exception.cjs.map +1 -0
  81. package/dist/not-found-error.cjs +65 -0
  82. package/dist/not-found-error.cjs.map +1 -0
  83. package/dist/not-found-error.js +1 -1
  84. package/dist/outcome.cjs +97 -0
  85. package/dist/outcome.cjs.map +1 -0
  86. package/dist/outcome.d.cts +58 -0
  87. package/dist/outcome.d.ts +1 -83
  88. package/dist/parse-gate-payload.d.cts +62 -0
  89. package/dist/parse-gate-payload.d.ts +2 -2
  90. package/dist/path.d.cts +90 -0
  91. package/dist/path.d.ts +2 -2
  92. package/dist/plugin.cjs +79 -0
  93. package/dist/plugin.cjs.map +1 -0
  94. package/dist/plugin.d.cts +85 -0
  95. package/dist/plugins/index.cjs +3 -0
  96. package/dist/plugins/index.d.cts +2 -0
  97. package/dist/policies/engines/index.cjs +10 -0
  98. package/dist/policies/engines/index.d.cts +4 -0
  99. package/dist/policies/engines/index.d.ts +1 -1
  100. package/dist/policies/engines/v1/gate/index.cjs +92 -0
  101. package/dist/policies/engines/v1/gate/index.cjs.map +1 -0
  102. package/dist/policies/engines/v1/gate/index.d.cts +121 -0
  103. package/dist/policies/engines/v1/gate/index.d.ts +2 -2
  104. package/dist/policies/engines/v1/gate/index.js +2 -1
  105. package/dist/policies/engines/v1/gate/index.js.map +1 -1
  106. package/dist/policies/index.cjs +41 -0
  107. package/dist/policies/index.d.cts +8 -0
  108. package/dist/policies/index.d.ts +3 -2
  109. package/dist/policies/index.js +2 -2
  110. package/dist/policy-bridge.cjs +437 -0
  111. package/dist/policy-bridge.cjs.map +1 -0
  112. package/dist/policy-bridge.d.cts +185 -0
  113. package/dist/policy-bridge.d.ts +185 -0
  114. package/dist/policy-bridge.js +396 -0
  115. package/dist/policy-bridge.js.map +1 -0
  116. package/dist/policy-service.cjs +1190 -0
  117. package/dist/policy-service.cjs.map +1 -0
  118. package/dist/policy-service.d.cts +559 -0
  119. package/dist/policy-service.d.ts +2 -2
  120. package/dist/policy-service.js +239 -239
  121. package/dist/policy-service.js.map +1 -1
  122. package/dist/rbac/index.cjs +9 -0
  123. package/dist/rbac/index.d.cts +3 -0
  124. package/dist/rbac/index.d.ts +3 -0
  125. package/dist/rbac/index.js +2 -0
  126. package/dist/requested-by.cjs +54 -0
  127. package/dist/requested-by.cjs.map +1 -0
  128. package/dist/requested-by.d.cts +25 -0
  129. package/dist/requested-by.d.ts +25 -0
  130. package/dist/requested-by.js +49 -0
  131. package/dist/requested-by.js.map +1 -0
  132. package/dist/result/index.cjs +7 -0
  133. package/dist/result/index.d.cts +3 -0
  134. package/dist/result/index.d.ts +2 -1
  135. package/dist/result.cjs +135 -0
  136. package/dist/result.cjs.map +1 -0
  137. package/dist/result.d.cts +84 -0
  138. package/dist/result.d.ts +84 -0
  139. package/dist/rule.cjs +327 -0
  140. package/dist/rule.cjs.map +1 -0
  141. package/dist/rule.js +298 -0
  142. package/dist/rule.js.map +1 -0
  143. package/dist/ruleset-registry.cjs +47 -0
  144. package/dist/ruleset-registry.cjs.map +1 -0
  145. package/dist/rulesets/index.cjs +3 -0
  146. package/dist/rulesets/index.d.cts +2 -0
  147. package/dist/temporal-guards.cjs +32 -0
  148. package/dist/temporal-guards.cjs.map +1 -0
  149. package/dist/temporal-use-case.cjs +139 -0
  150. package/dist/temporal-use-case.cjs.map +1 -0
  151. package/dist/temporal-use-case.d.cts +282 -0
  152. package/dist/temporal-use-case.d.ts +5 -27
  153. package/dist/temporal-use-case.js +2 -48
  154. package/dist/temporal-use-case.js.map +1 -1
  155. package/dist/unexpected-error.cjs +19 -0
  156. package/dist/unexpected-error.cjs.map +1 -0
  157. package/dist/unexpected-error.js +2 -167
  158. package/dist/unexpected-error.js.map +1 -1
  159. package/dist/use-case.cjs +96 -0
  160. package/dist/use-case.cjs.map +1 -0
  161. package/dist/uuid-identifier.cjs +65 -0
  162. package/dist/uuid-identifier.cjs.map +1 -0
  163. package/dist/uuid-identifier.d.cts +147 -0
  164. package/dist/uuid-identifier.d.ts +2 -85
  165. package/dist/validation-code.cjs +60 -0
  166. package/dist/validation-code.cjs.map +1 -0
  167. package/dist/validation-code.d.cts +23 -0
  168. package/dist/validation-error.cjs +887 -0
  169. package/dist/validation-error.cjs.map +1 -0
  170. package/dist/validation-error.d.cts +681 -0
  171. package/dist/validation-error.d.ts +2 -98
  172. package/dist/validation-error.js +7 -134
  173. package/dist/validation-error.js.map +1 -1
  174. package/dist/validation-exception.cjs +41 -0
  175. package/dist/validation-exception.cjs.map +1 -0
  176. package/dist/validation-exception.d.cts +50 -0
  177. package/dist/validation-field.cjs +28 -0
  178. package/dist/validation-field.cjs.map +1 -0
  179. package/dist/validation-field.d.cts +12 -0
  180. package/dist/value-object-ruleset.contracts.d.cts +36 -0
  181. package/dist/value-object.cjs +85 -0
  182. package/dist/value-object.cjs.map +1 -0
  183. package/dist/value-object.d.cts +89 -0
  184. package/dist/value-object.d.ts +89 -0
  185. package/dist/value-object.js +1 -112
  186. package/dist/value-object.js.map +1 -1
  187. package/dist/version.d.cts +10 -0
  188. package/dist/versioning/index.cjs +7 -0
  189. package/dist/versioning/index.d.cts +3 -0
  190. package/meta.json +19 -4
  191. package/package.json +173 -28
  192. package/src/abac/index.ts +1 -0
  193. package/src/core/abac/abac-request.ts +29 -0
  194. package/src/core/abac/attributes.ts +39 -0
  195. package/src/core/abac/authorizer.ts +108 -0
  196. package/src/core/abac/combining.ts +63 -0
  197. package/src/core/abac/composite-authorizer.ts +45 -0
  198. package/src/core/abac/domain/policy-set.ts +52 -0
  199. package/src/core/abac/domain/rule.ts +197 -0
  200. package/src/core/abac/index.ts +21 -0
  201. package/src/core/application/ports/abac-authorizer.port.ts +20 -0
  202. package/src/core/application/ports/authorizer.port.ts +22 -0
  203. package/src/core/errors/authorization-error.ts +26 -0
  204. package/src/core/errors/error-codes.ts +1 -0
  205. package/src/core/index.ts +7 -0
  206. package/src/core/rbac/access-request.ts +32 -0
  207. package/src/core/rbac/authorizer.ts +91 -0
  208. package/src/core/rbac/domain/grant.ts +96 -0
  209. package/src/core/rbac/domain/permission-set.ts +67 -0
  210. package/src/core/rbac/domain/permission.ts +119 -0
  211. package/src/core/rbac/domain/role.ts +101 -0
  212. package/src/core/rbac/domain/scope.ts +84 -0
  213. package/src/core/rbac/index.ts +15 -0
  214. package/src/core/rbac/policy-bridge.ts +44 -0
  215. package/src/examples/application/authorize-cancel-order-abac.example.ts +107 -0
  216. package/src/examples/application/authorize-cancel-order.example.ts +101 -0
  217. package/src/rbac/index.ts +1 -0
  218. package/src/version.ts +1 -1
@@ -1,165 +1,5 @@
1
- import { r as isValidDate } from "./temporal-guards.js";
2
1
  import { r as Result } from "./result.js";
3
2
  import { z } from "zod";
4
- //#region src/core/config/silent-policy-reporter.ts
5
- var SilentPolicyReporter = class {
6
- report(_event) {}
7
- };
8
- //#endregion
9
- //#region src/core/config/core-config.ts
10
- function reportSafely(policyReporter, event) {
11
- try {
12
- policyReporter.report(event);
13
- } catch {}
14
- }
15
- /**
16
- * Centraliza a configuracao pura do core sem depender de implementacoes
17
- * concretas de logging, tracing ou report.
18
- */
19
- var CoreConfig = class {
20
- #initialReporter;
21
- #currentReporter;
22
- constructor(options = {}) {
23
- const reporter = options.observability?.reporter ?? new SilentPolicyReporter();
24
- this.#initialReporter = reporter;
25
- this.#currentReporter = reporter;
26
- }
27
- configure(options) {
28
- const reporter = options.observability?.reporter;
29
- if (reporter) this.#currentReporter = reporter;
30
- return this;
31
- }
32
- reset() {
33
- this.#currentReporter = this.#initialReporter;
34
- return this;
35
- }
36
- getPolicyReporter() {
37
- return this.#currentReporter;
38
- }
39
- getConditionEvaluationOptions(engineVersion) {
40
- return {
41
- reporter: this.#bridgeToConditionReporter(this.#currentReporter),
42
- engineVersion
43
- };
44
- }
45
- #bridgeToConditionReporter(policyReporter) {
46
- return {
47
- warn(report) {
48
- reportSafely(policyReporter, {
49
- kind: "condition-eval",
50
- ...report
51
- });
52
- },
53
- error(report) {
54
- reportSafely(policyReporter, {
55
- kind: "condition-eval",
56
- ...report
57
- });
58
- }
59
- };
60
- }
61
- };
62
- //#endregion
63
- //#region src/core/config/core-config.instance.ts
64
- /**
65
- * Shared instance for the application composition root.
66
- * Use `new CoreConfig()` for isolated runtimes, tests, or multi-tenant hosts.
67
- *
68
- * The default reporter is silent so the core has no runtime logging dependency.
69
- * Hosts can swap in their own `PolicyReporter` via
70
- * `coreConfig.configure({ observability: { reporter } })`.
71
- */
72
- const coreConfig = new CoreConfig({ observability: { reporter: new SilentPolicyReporter() } });
73
- //#endregion
74
- //#region src/core/policies/utils/date.ts
75
- var PolicyDateUtils = class {
76
- static isValid(value) {
77
- return isValidDate(value);
78
- }
79
- };
80
- //#endregion
81
- //#region src/core/policies/context/path.ts
82
- /**
83
- * Utilities for reading/writing values at dot-separated paths
84
- * in plain objects, e.g. "installment.dueDate".
85
- */
86
- var PolicyContextPath = class PolicyContextPath {
87
- static {
88
- this.FORBIDDEN_SEGMENTS = new Set([
89
- "__proto__",
90
- "prototype",
91
- "constructor"
92
- ]);
93
- }
94
- static resolve(obj, path) {
95
- const segmentsResult = PolicyContextPath.parseSegments(path);
96
- if (segmentsResult.isErr()) return Result.err(segmentsResult.errorOrNull());
97
- const segments = segmentsResult.getOrNull();
98
- let current = obj;
99
- for (const segment of segments) {
100
- if (current === null || current === void 0 || typeof current !== "object") return Result.ok({
101
- found: false,
102
- value: void 0
103
- });
104
- const record = current;
105
- if (!Object.prototype.hasOwnProperty.call(record, segment)) return Result.ok({
106
- found: false,
107
- value: void 0
108
- });
109
- current = record[segment];
110
- }
111
- return Result.ok({
112
- found: true,
113
- value: current
114
- });
115
- }
116
- static parseSegments(path) {
117
- if (path.trim().length === 0) return Result.err("Path cannot be empty");
118
- const segments = path.split(".");
119
- if (segments.some((segment) => segment.length === 0)) return Result.err(`Path "${path}" contains an empty segment`);
120
- const forbiddenSegment = segments.find((segment) => PolicyContextPath.FORBIDDEN_SEGMENTS.has(segment));
121
- if (forbiddenSegment !== void 0) return Result.err(`Path "${path}" contains forbidden segment "${forbiddenSegment}"`);
122
- return Result.ok(segments);
123
- }
124
- static isPlainRecord(value) {
125
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
126
- const prototype = Object.getPrototypeOf(value);
127
- return prototype === Object.prototype || prototype === null;
128
- }
129
- static getOrAbsent(obj, path) {
130
- const resolvedPath = PolicyContextPath.resolve(obj, path);
131
- if (resolvedPath.isErr()) return Result.err("absent");
132
- const { found, value } = resolvedPath.getOrNull();
133
- if (!found) return Result.err("absent");
134
- return Result.ok(value);
135
- }
136
- static has(obj, path) {
137
- const resolvedPath = PolicyContextPath.resolve(obj, path);
138
- if (resolvedPath.isErr()) return false;
139
- return resolvedPath.getOrNull().found;
140
- }
141
- static set(obj, path, value) {
142
- const segmentsResult = PolicyContextPath.parseSegments(path);
143
- if (segmentsResult.isErr()) return Result.err(segmentsResult.errorOrNull());
144
- const segments = segmentsResult.getOrNull();
145
- let current = obj;
146
- for (let i = 0; i < segments.length - 1; i++) {
147
- const seg = segments[i];
148
- const next = current[seg];
149
- if (next === void 0) {
150
- const container = Object.create(null);
151
- current[seg] = container;
152
- current = container;
153
- continue;
154
- }
155
- if (!PolicyContextPath.isPlainRecord(next)) return Result.err(`Cannot create nested path "${path}" because "${segments.slice(0, i + 1).join(".")}" already contains a non-plain object`);
156
- current = next;
157
- }
158
- current[segments[segments.length - 1]] = value;
159
- return Result.ok(void 0);
160
- }
161
- };
162
- //#endregion
163
3
  //#region src/core/policies/engines/v1/condition-schema.ts
164
4
  const conditionOpSchema = z.enum([
165
5
  "eq",
@@ -186,378 +26,6 @@ const conditionNodeSchema = z.lazy(() => z.union([
186
26
  z.object({ not: conditionNodeSchema }).strict()
187
27
  ]));
188
28
  //#endregion
189
- //#region src/core/policies/engines/v1/condition-evaluator.ts
190
- const CONDITION_EVAL_THROWN_TAG = "CONDITION_EVAL_THREW";
191
- const NULLISH_NUMERIC_OPERAND_NOT_ALLOWED_TAG = "NULLISH_NUMERIC_OPERAND_NOT_ALLOWED";
192
- const NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG = "NULLISH_DATE_OPERAND_NOT_ALLOWED";
193
- const INVALID_DATE_OPERAND_TAG = "INVALID_DATE_OPERAND";
194
- const INVALID_NUMERIC_OPERAND_TAG = "INVALID_NUMERIC_OPERAND";
195
- const INVALID_SET_OPERAND_TAG = "INVALID_SET_OPERAND";
196
- const EMPTY_OR_CONDITION_TAG = "EMPTY_OR_CONDITION";
197
- const EMPTY_AND_CONDITION_TAG = "EMPTY_AND_CONDITION";
198
- const ISO_8601_UTC_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
199
- var ConditionEvaluatorV1 = class ConditionEvaluatorV1 {
200
- constructor(context, options) {
201
- this.context = context;
202
- this.options = options;
203
- }
204
- static isLeafNode(node) {
205
- return "field" in node && "op" in node;
206
- }
207
- static isAndNode(node) {
208
- return "and" in node;
209
- }
210
- static isOrNode(node) {
211
- return "or" in node;
212
- }
213
- static isNotNode(node) {
214
- return "not" in node;
215
- }
216
- static isRelationalOperator(op) {
217
- return op === "gt" || op === "gte" || op === "lt" || op === "lte";
218
- }
219
- static describeError(error) {
220
- if (error instanceof Error) return {
221
- name: error.name,
222
- message: error.message
223
- };
224
- return {
225
- name: "NonErrorThrown",
226
- message: String(error)
227
- };
228
- }
229
- static buildNullishNumericOperandMessage(node, actual) {
230
- const resolvedValue = actual === null ? "null" : "undefined";
231
- return `${NULLISH_NUMERIC_OPERAND_NOT_ALLOWED_TAG}: "${node.field}" resolved to ${resolvedValue} for numeric operator "${node.op}"`;
232
- }
233
- static buildNullishDateOperandMessage(node, actual) {
234
- const resolvedValue = actual === null ? "null" : "undefined";
235
- return `${NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG}: "${node.field}" resolved to ${resolvedValue} for date comparison operator "${node.op}"`;
236
- }
237
- static buildInvalidDateOperandMessage(node) {
238
- return `${INVALID_DATE_OPERAND_TAG}: "${node.field}" with operator "${node.op}" requires Date or ISO 8601 UTC string operands`;
239
- }
240
- static buildInvalidNumericOperandMessage(node) {
241
- return `${INVALID_NUMERIC_OPERAND_TAG}: "${node.field}" with operator "${node.op}" requires numeric operands`;
242
- }
243
- static buildInvalidSetOperandMessage(node) {
244
- return `${INVALID_SET_OPERAND_TAG}: "${node.field}" with operator "${node.op}" requires an array operand`;
245
- }
246
- static buildEmptyOrConditionMessage() {
247
- return `${EMPTY_OR_CONDITION_TAG}: OR nodes must contain at least one child condition`;
248
- }
249
- static buildEmptyAndConditionMessage() {
250
- return `${EMPTY_AND_CONDITION_TAG}: AND nodes must contain at least one child condition`;
251
- }
252
- static parseComparableDate(value) {
253
- if (value instanceof Date) {
254
- if (!PolicyDateUtils.isValid(value)) return Result.err("Invalid Date instance");
255
- return Result.ok(value);
256
- }
257
- if (typeof value !== "string" || !ISO_8601_UTC_DATE_PATTERN.test(value)) return null;
258
- const parsed = new Date(value);
259
- if (!PolicyDateUtils.isValid(parsed) || parsed.toISOString() !== value) return Result.err("Invalid ISO 8601 UTC date string");
260
- return Result.ok(parsed);
261
- }
262
- static evaluateRelationalNumbers(actual, op, expected) {
263
- switch (op) {
264
- case "gt": return actual > expected;
265
- case "gte": return actual >= expected;
266
- case "lt": return actual < expected;
267
- case "lte": return actual <= expected;
268
- }
269
- }
270
- buildReport(params) {
271
- return {
272
- occurredAt: /* @__PURE__ */ new Date(),
273
- level: params.level,
274
- tag: params.tag,
275
- message: params.message,
276
- engineVersion: this.options.engineVersion,
277
- details: params.details
278
- };
279
- }
280
- conditionEvalErr(node, error) {
281
- const cause = ConditionEvaluatorV1.describeError(error);
282
- const message = `${CONDITION_EVAL_THROWN_TAG}: ${cause.name}: ${cause.message}`;
283
- this.options.reporter.error(this.buildReport({
284
- level: "error",
285
- tag: CONDITION_EVAL_THROWN_TAG,
286
- message,
287
- details: {
288
- node,
289
- cause
290
- }
291
- }));
292
- return Result.err(message);
293
- }
294
- reportDateOperandError(node, actual) {
295
- const message = ConditionEvaluatorV1.buildInvalidDateOperandMessage(node);
296
- this.options.reporter.error(this.buildReport({
297
- level: "error",
298
- tag: INVALID_DATE_OPERAND_TAG,
299
- message,
300
- details: {
301
- field: node.field,
302
- op: node.op,
303
- actual,
304
- expected: node.value,
305
- node
306
- }
307
- }));
308
- return Result.err(message);
309
- }
310
- reportInvalidNumericOperand(node, actual) {
311
- const message = ConditionEvaluatorV1.buildInvalidNumericOperandMessage(node);
312
- this.options.reporter.error(this.buildReport({
313
- level: "error",
314
- tag: INVALID_NUMERIC_OPERAND_TAG,
315
- message,
316
- details: {
317
- field: node.field,
318
- op: node.op,
319
- actual,
320
- expected: node.value,
321
- node
322
- }
323
- }));
324
- return Result.err(message);
325
- }
326
- reportInvalidSetOperand(node, actual) {
327
- const message = ConditionEvaluatorV1.buildInvalidSetOperandMessage(node);
328
- this.options.reporter.error(this.buildReport({
329
- level: "error",
330
- tag: INVALID_SET_OPERAND_TAG,
331
- message,
332
- details: {
333
- field: node.field,
334
- op: node.op,
335
- actual,
336
- expected: node.value,
337
- node
338
- }
339
- }));
340
- return Result.err(message);
341
- }
342
- evaluateDateRelationalNode(node, actual) {
343
- if (!ConditionEvaluatorV1.isRelationalOperator(node.op)) return null;
344
- const actualDateResult = ConditionEvaluatorV1.parseComparableDate(actual);
345
- const expectedDateResult = ConditionEvaluatorV1.parseComparableDate(node.value);
346
- if (actualDateResult === null && expectedDateResult === null) return null;
347
- const allowsNull = node.allowNull === true;
348
- if (actual === null) {
349
- if (allowsNull) return Result.ok(false);
350
- const message = ConditionEvaluatorV1.buildNullishDateOperandMessage(node, actual);
351
- this.options.reporter.error(this.buildReport({
352
- level: "error",
353
- tag: NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG,
354
- message,
355
- details: {
356
- field: node.field,
357
- op: node.op,
358
- actual,
359
- expected: node.value,
360
- allowNull: allowsNull,
361
- node
362
- }
363
- }));
364
- return Result.err(message);
365
- }
366
- if (actual === void 0) {
367
- const message = ConditionEvaluatorV1.buildNullishDateOperandMessage(node, actual);
368
- this.options.reporter.error(this.buildReport({
369
- level: "error",
370
- tag: NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG,
371
- message,
372
- details: {
373
- field: node.field,
374
- op: node.op,
375
- actual,
376
- expected: node.value,
377
- allowNull: allowsNull,
378
- node
379
- }
380
- }));
381
- return Result.err(message);
382
- }
383
- if (actualDateResult === null || actualDateResult.isErr() || expectedDateResult === null || expectedDateResult.isErr()) return this.reportDateOperandError(node, actual);
384
- return Result.ok(ConditionEvaluatorV1.evaluateRelationalNumbers(actualDateResult.getOrNull().getTime(), node.op, expectedDateResult.getOrNull().getTime()));
385
- }
386
- evaluateOperator(actual, op, expected) {
387
- switch (op) {
388
- case "eq": return actual === expected;
389
- case "neq": return actual !== expected;
390
- case "gt": return typeof actual === "number" && typeof expected === "number" && ConditionEvaluatorV1.evaluateRelationalNumbers(actual, op, expected);
391
- case "gte": return typeof actual === "number" && typeof expected === "number" && ConditionEvaluatorV1.evaluateRelationalNumbers(actual, op, expected);
392
- case "lt": return typeof actual === "number" && typeof expected === "number" && ConditionEvaluatorV1.evaluateRelationalNumbers(actual, op, expected);
393
- case "lte": return typeof actual === "number" && typeof expected === "number" && ConditionEvaluatorV1.evaluateRelationalNumbers(actual, op, expected);
394
- case "in": return Array.isArray(expected) && expected.includes(actual);
395
- case "notIn": return Array.isArray(expected) && !expected.includes(actual);
396
- case "isNull": return actual === null;
397
- case "isNotNull": return actual !== null && actual !== void 0;
398
- }
399
- }
400
- evaluateNumericRelationalNode(node, actual) {
401
- const allowsNull = node.allowNull === true;
402
- if (actual === void 0 || actual === null && !allowsNull) {
403
- const message = ConditionEvaluatorV1.buildNullishNumericOperandMessage(node, actual);
404
- this.options.reporter.error(this.buildReport({
405
- level: "error",
406
- tag: NULLISH_NUMERIC_OPERAND_NOT_ALLOWED_TAG,
407
- message,
408
- details: {
409
- field: node.field,
410
- op: node.op,
411
- actual,
412
- expected: node.value,
413
- allowNull: allowsNull,
414
- node
415
- }
416
- }));
417
- return Result.err(message);
418
- }
419
- if (actual === null) return Result.ok(false);
420
- if (typeof actual !== "number" || typeof node.value !== "number") return this.reportInvalidNumericOperand(node, actual);
421
- return Result.ok(this.evaluateOperator(actual, node.op, node.value));
422
- }
423
- evaluateLeafNode(node) {
424
- const actualResult = PolicyContextPath.getOrAbsent(this.context, node.field);
425
- if (actualResult.isErr()) {
426
- this.options.reporter.warn(this.buildReport({
427
- level: "warn",
428
- tag: "MISSING_CONTEXT_FIELD",
429
- message: `MISSING_CONTEXT_FIELD: "${node.field}" not found in context`,
430
- details: {
431
- field: node.field,
432
- node
433
- }
434
- }));
435
- return Result.err(`MISSING_CONTEXT_FIELD: "${node.field}" not found in context`);
436
- }
437
- try {
438
- const actual = actualResult.getOrThrow();
439
- if (ConditionEvaluatorV1.isRelationalOperator(node.op)) {
440
- const dateResult = this.evaluateDateRelationalNode(node, actual);
441
- if (dateResult !== null) return dateResult;
442
- return this.evaluateNumericRelationalNode(node, actual);
443
- }
444
- if ((node.op === "in" || node.op === "notIn") && !Array.isArray(node.value)) return this.reportInvalidSetOperand(node, actual);
445
- return Result.ok(this.evaluateOperator(actual, node.op, node.value));
446
- } catch (error) {
447
- return this.conditionEvalErr(node, error);
448
- }
449
- }
450
- buildTrace(params) {
451
- return {
452
- conditionPath: params.conditionPath,
453
- decisiveNode: params.decisiveNode,
454
- lastEvaluatedLeaf: params.lastEvaluatedLeaf,
455
- lastEvaluatedLeafPath: params.lastEvaluatedLeafPath,
456
- lastEvaluatedLeafResult: params.lastEvaluatedLeafResult
457
- };
458
- }
459
- evaluateWithTraceInternal(node, path) {
460
- if (ConditionEvaluatorV1.isLeafNode(node)) {
461
- const leafResult = this.evaluateLeafNode(node);
462
- if (leafResult.isErr()) return Result.err(leafResult.errorOrNull());
463
- const matched = leafResult.getOrNull();
464
- return Result.ok({
465
- matched,
466
- trace: this.buildTrace({
467
- conditionPath: path,
468
- decisiveNode: node,
469
- lastEvaluatedLeaf: node,
470
- lastEvaluatedLeafPath: path,
471
- lastEvaluatedLeafResult: matched
472
- })
473
- });
474
- }
475
- if (ConditionEvaluatorV1.isAndNode(node)) {
476
- if (node.and.length === 0) return Result.err(ConditionEvaluatorV1.buildEmptyAndConditionMessage());
477
- let lastTracedChild = null;
478
- for (const [index, child] of node.and.entries()) {
479
- const childPath = `${path}.and[${index}]`;
480
- const childResult = this.evaluateWithTraceInternal(child, childPath);
481
- if (childResult.isErr()) return Result.err(childResult.errorOrNull());
482
- const tracedChild = childResult.getOrNull();
483
- lastTracedChild = tracedChild;
484
- if (!tracedChild.matched) return Result.ok({
485
- matched: false,
486
- trace: this.buildTrace({
487
- conditionPath: childPath,
488
- decisiveNode: child,
489
- lastEvaluatedLeaf: tracedChild.trace.lastEvaluatedLeaf,
490
- lastEvaluatedLeafPath: tracedChild.trace.lastEvaluatedLeafPath,
491
- lastEvaluatedLeafResult: tracedChild.trace.lastEvaluatedLeafResult
492
- })
493
- });
494
- }
495
- return Result.ok({
496
- matched: true,
497
- trace: lastTracedChild.trace
498
- });
499
- }
500
- if (ConditionEvaluatorV1.isOrNode(node)) {
501
- let lastTrace = null;
502
- for (const [index, child] of node.or.entries()) {
503
- const childResult = this.evaluateWithTraceInternal(child, `${path}.or[${index}]`);
504
- if (childResult.isErr()) return Result.err(childResult.errorOrNull());
505
- const tracedChild = childResult.getOrNull();
506
- lastTrace = tracedChild.trace;
507
- if (tracedChild.matched) return Result.ok({
508
- matched: true,
509
- trace: tracedChild.trace
510
- });
511
- }
512
- if (lastTrace === null) return Result.err(ConditionEvaluatorV1.buildEmptyOrConditionMessage());
513
- return Result.ok({
514
- matched: false,
515
- trace: lastTrace
516
- });
517
- }
518
- if (ConditionEvaluatorV1.isNotNode(node)) {
519
- const childPath = `${path}.not`;
520
- const childResult = this.evaluateWithTraceInternal(node.not, childPath);
521
- if (childResult.isErr()) return Result.err(childResult.errorOrNull());
522
- const tracedChild = childResult.getOrNull();
523
- return Result.ok({
524
- matched: !tracedChild.matched,
525
- trace: this.buildTrace({
526
- conditionPath: path,
527
- decisiveNode: node,
528
- lastEvaluatedLeaf: tracedChild.trace.lastEvaluatedLeaf,
529
- lastEvaluatedLeafPath: tracedChild.trace.lastEvaluatedLeafPath,
530
- lastEvaluatedLeafResult: tracedChild.trace.lastEvaluatedLeafResult
531
- })
532
- });
533
- }
534
- return this.conditionEvalErr(node, /* @__PURE__ */ new TypeError("Invalid condition node shape"));
535
- }
536
- evaluate(node) {
537
- try {
538
- const result = this.evaluateWithTraceInternal(node, "$");
539
- if (result.isErr()) return Result.err(result.errorOrNull());
540
- return Result.ok(result.getOrNull().matched);
541
- } catch (error) {
542
- return this.conditionEvalErr(node, error);
543
- }
544
- }
545
- evaluateWithTrace(node) {
546
- try {
547
- return this.evaluateWithTraceInternal(node, "$");
548
- } catch (error) {
549
- return this.conditionEvalErr(node, error);
550
- }
551
- }
552
- static extractFields(node) {
553
- if (ConditionEvaluatorV1.isLeafNode(node)) return [node.field];
554
- if (ConditionEvaluatorV1.isAndNode(node)) return node.and.flatMap((child) => ConditionEvaluatorV1.extractFields(child));
555
- if (ConditionEvaluatorV1.isOrNode(node)) return node.or.flatMap((child) => ConditionEvaluatorV1.extractFields(child));
556
- if (ConditionEvaluatorV1.isNotNode(node)) return ConditionEvaluatorV1.extractFields(node.not);
557
- return [];
558
- }
559
- };
560
- //#endregion
561
29
  //#region src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts
562
30
  var GatePayloadSchemaV1 = class GatePayloadSchemaV1 {
563
31
  static {
@@ -580,6 +48,6 @@ var GatePayloadSchemaV1 = class GatePayloadSchemaV1 {
580
48
  };
581
49
  const gatePayloadSchema = GatePayloadSchemaV1.schema;
582
50
  //#endregion
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 };
51
+ export { conditionNodeSchema as i, gatePayloadSchema as n, conditionLeafNodeSchema as r, GatePayloadSchemaV1 as t };
584
52
 
585
53
  //# sourceMappingURL=gate-v1-payload.schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gate-v1-payload.schema.js","names":["#initialReporter","#currentReporter","#bridgeToConditionReporter"],"sources":["../src/core/config/silent-policy-reporter.ts","../src/core/config/core-config.ts","../src/core/config/core-config.instance.ts","../src/core/policies/utils/date.ts","../src/core/policies/context/path.ts","../src/core/policies/engines/v1/condition-schema.ts","../src/core/policies/engines/v1/condition-evaluator.ts","../src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts"],"sourcesContent":["import type { PolicyReporter } from \"./policy-reporter.js\";\n\nexport class SilentPolicyReporter implements PolicyReporter {\n report(_event: Parameters<PolicyReporter[\"report\"]>[0]): void {}\n}\n","import type {\n ConditionEvaluationOptions,\n ConditionEvaluatorReporter,\n} from \"../policies/engines/condition-evaluator-reporter.js\";\nimport type { PolicyEvent, PolicyReporter } from \"./policy-reporter.js\";\nimport { SilentPolicyReporter } from \"./silent-policy-reporter.js\";\n\nexport interface CoreObservabilityConfig {\n readonly reporter?: PolicyReporter;\n}\n\nexport interface CoreConfigOptions {\n readonly observability?: CoreObservabilityConfig;\n}\n\nfunction reportSafely(\n policyReporter: PolicyReporter,\n event: PolicyEvent,\n): void {\n try {\n policyReporter.report(event);\n } catch {\n // Falhas de telemetria nao podem interromper o fluxo de dominio.\n }\n}\n\n/**\n * Centraliza a configuracao pura do core sem depender de implementacoes\n * concretas de logging, tracing ou report.\n */\nexport class CoreConfig {\n readonly #initialReporter: PolicyReporter;\n #currentReporter: PolicyReporter;\n\n constructor(options: CoreConfigOptions = {}) {\n const reporter =\n options.observability?.reporter ?? new SilentPolicyReporter();\n this.#initialReporter = reporter;\n this.#currentReporter = reporter;\n }\n\n configure(options: CoreConfigOptions): this {\n const reporter = options.observability?.reporter;\n if (reporter) {\n this.#currentReporter = reporter;\n }\n return this;\n }\n\n // Restores the reporter captured at construction time.\n reset(): this {\n this.#currentReporter = this.#initialReporter;\n return this;\n }\n\n getPolicyReporter(): PolicyReporter {\n return this.#currentReporter;\n }\n\n getConditionEvaluationOptions(\n engineVersion: number,\n ): ConditionEvaluationOptions {\n return {\n reporter: this.#bridgeToConditionReporter(this.#currentReporter),\n engineVersion,\n };\n }\n\n #bridgeToConditionReporter(\n policyReporter: PolicyReporter,\n ): ConditionEvaluatorReporter {\n return {\n warn(report) {\n reportSafely(policyReporter, {\n kind: \"condition-eval\",\n ...report,\n } satisfies PolicyEvent);\n },\n error(report) {\n reportSafely(policyReporter, {\n kind: \"condition-eval\",\n ...report,\n } satisfies PolicyEvent);\n },\n };\n }\n}\n","import { CoreConfig } from \"./core-config.js\";\nimport { SilentPolicyReporter } from \"./silent-policy-reporter.js\";\n\n/**\n * Shared instance for the application composition root.\n * Use `new CoreConfig()` for isolated runtimes, tests, or multi-tenant hosts.\n *\n * The default reporter is silent so the core has no runtime logging dependency.\n * Hosts can swap in their own `PolicyReporter` via\n * `coreConfig.configure({ observability: { reporter } })`.\n */\nexport const coreConfig = new CoreConfig({\n observability: { reporter: new SilentPolicyReporter() },\n});\n","import { isValidDate } from \"../../shared/temporal-guards.js\";\n\nexport class PolicyDateUtils {\n static isValid(value: Date): boolean {\n return isValidDate(value);\n }\n}\n","/**\n * Utilities for reading/writing values at dot-separated paths\n * in plain objects, e.g. \"installment.dueDate\".\n */\n\nimport { Result } from \"../../result/result.js\";\n\nexport class PolicyContextPath {\n private static readonly FORBIDDEN_SEGMENTS = new Set([\n \"__proto__\",\n \"prototype\",\n \"constructor\",\n ]);\n\n private static resolve(\n obj: Record<string, unknown>,\n path: string,\n ): Result<\n {\n readonly found: boolean;\n readonly value: unknown;\n },\n string\n > {\n const segmentsResult = PolicyContextPath.parseSegments(path);\n if (segmentsResult.isErr()) {\n return Result.err(segmentsResult.errorOrNull()!);\n }\n\n const segments = segmentsResult.getOrNull()!;\n let current: unknown = obj;\n\n for (const segment of segments) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== \"object\"\n ) {\n return Result.ok({ found: false, value: undefined });\n }\n\n const record = current as Record<string, unknown>;\n if (!Object.prototype.hasOwnProperty.call(record, segment)) {\n return Result.ok({ found: false, value: undefined });\n }\n\n current = record[segment];\n }\n\n return Result.ok({ found: true, value: current });\n }\n\n private static parseSegments(\n path: string,\n ): Result<readonly string[], string> {\n if (path.trim().length === 0) {\n return Result.err(\"Path cannot be empty\");\n }\n\n const segments = path.split(\".\");\n if (segments.some((segment) => segment.length === 0)) {\n return Result.err(`Path \"${path}\" contains an empty segment`);\n }\n\n const forbiddenSegment = segments.find((segment) =>\n PolicyContextPath.FORBIDDEN_SEGMENTS.has(segment),\n );\n if (forbiddenSegment !== undefined) {\n return Result.err(\n `Path \"${path}\" contains forbidden segment \"${forbiddenSegment}\"`,\n );\n }\n\n return Result.ok(segments);\n }\n\n private static isPlainRecord(\n value: unknown,\n ): value is Record<string, unknown> {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value)\n ) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n }\n\n static getOrAbsent(\n obj: Record<string, unknown>,\n path: string,\n ): Result<unknown, \"absent\"> {\n const resolvedPath = PolicyContextPath.resolve(obj, path);\n if (resolvedPath.isErr()) {\n return Result.err(\"absent\");\n }\n\n const { found, value } = resolvedPath.getOrNull()!;\n if (!found) {\n return Result.err(\"absent\");\n }\n\n return Result.ok(value);\n }\n\n static has(obj: Record<string, unknown>, path: string): boolean {\n const resolvedPath = PolicyContextPath.resolve(obj, path);\n if (resolvedPath.isErr()) {\n return false;\n }\n\n return resolvedPath.getOrNull()!.found;\n }\n\n static set(\n obj: Record<string, unknown>,\n path: string,\n value: unknown,\n ): Result<void, string> {\n const segmentsResult = PolicyContextPath.parseSegments(path);\n if (segmentsResult.isErr()) {\n return Result.err(segmentsResult.errorOrNull()!);\n }\n\n const segments = segmentsResult.getOrNull()!;\n let current: Record<string, unknown> = obj;\n\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n const next = current[seg];\n\n if (next === undefined) {\n const container = Object.create(null) as Record<\n string,\n unknown\n >;\n current[seg] = container;\n current = container;\n continue;\n }\n\n if (!PolicyContextPath.isPlainRecord(next)) {\n return Result.err(\n `Cannot create nested path \"${path}\" because \"${segments\n .slice(0, i + 1)\n .join(\".\")}\" already contains a non-plain object`,\n );\n }\n\n current = next;\n }\n\n current[segments[segments.length - 1]] = value;\n return Result.ok(undefined);\n }\n}\n","import { z } from \"zod\";\n\nimport type { ConditionLeafNode, ConditionNode } from \"./condition-types.js\";\n\n// ─── Shared v1 condition Zod schemas ─────────────────────────────────────────\n// Extracted from gate/v1 so both gate/v1 and compute/v1 can validate\n// condition nodes without either engine depending on the other.\n\nconst conditionOpSchema = z.enum([\n \"eq\",\n \"neq\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"in\",\n \"notIn\",\n \"isNull\",\n \"isNotNull\",\n]);\n\nexport const conditionLeafNodeSchema: z.ZodType<ConditionLeafNode> = z\n .object({\n field: z.string().min(1),\n op: conditionOpSchema,\n value: z.unknown(),\n allowNull: z.literal(true).optional(),\n })\n .strict() as z.ZodType<ConditionLeafNode>;\n\nexport const conditionNodeSchema: z.ZodType<ConditionNode> = z.lazy(() =>\n z.union([\n conditionLeafNodeSchema,\n z\n .object({\n and: z.array(conditionNodeSchema).min(1),\n })\n .strict(),\n z\n .object({\n or: z.array(conditionNodeSchema).min(1),\n })\n .strict(),\n z\n .object({\n not: conditionNodeSchema,\n })\n .strict(),\n ]),\n);\n","import { PolicyContextPath } from \"../../context/index.js\";\nimport { PolicyDateUtils } from \"../../utils/index.js\";\nimport { Result } from \"../../../result/result.js\";\n\nimport type {\n ConditionAndNode,\n ConditionLeafNode,\n ConditionNode,\n ConditionNotNode,\n ConditionOp,\n ConditionOrNode,\n} from \"./condition-types.js\";\nimport type {\n ConditionEvaluationOptions,\n ConditionEvaluationReport,\n} from \"../condition-evaluator-reporter.js\";\nimport type { PolicyContext } from \"../gate-types.js\";\n\nconst CONDITION_EVAL_THROWN_TAG = \"CONDITION_EVAL_THREW\";\nconst NULLISH_NUMERIC_OPERAND_NOT_ALLOWED_TAG =\n \"NULLISH_NUMERIC_OPERAND_NOT_ALLOWED\";\nconst NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG = \"NULLISH_DATE_OPERAND_NOT_ALLOWED\";\nconst INVALID_DATE_OPERAND_TAG = \"INVALID_DATE_OPERAND\";\nconst INVALID_NUMERIC_OPERAND_TAG = \"INVALID_NUMERIC_OPERAND\";\nconst INVALID_SET_OPERAND_TAG = \"INVALID_SET_OPERAND\";\nconst EMPTY_OR_CONDITION_TAG = \"EMPTY_OR_CONDITION\";\nconst EMPTY_AND_CONDITION_TAG = \"EMPTY_AND_CONDITION\";\nconst ISO_8601_UTC_DATE_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\nexport interface ConditionEvaluationTrace {\n readonly conditionPath: string;\n readonly decisiveNode: ConditionNode;\n readonly lastEvaluatedLeaf: ConditionLeafNode;\n readonly lastEvaluatedLeafPath: string;\n readonly lastEvaluatedLeafResult: boolean;\n}\n\nexport interface TracedConditionEvaluation {\n readonly matched: boolean;\n readonly trace: ConditionEvaluationTrace;\n}\n\ntype RelationalOperator = Extract<ConditionOp, \"gt\" | \"gte\" | \"lt\" | \"lte\">;\n\nexport class ConditionEvaluatorV1 {\n constructor(\n private readonly context: PolicyContext,\n private readonly options: ConditionEvaluationOptions,\n ) {}\n\n private static isLeafNode(node: ConditionNode): node is ConditionLeafNode {\n return \"field\" in node && \"op\" in node;\n }\n\n private static isAndNode(node: ConditionNode): node is ConditionAndNode {\n return \"and\" in node;\n }\n\n private static isOrNode(node: ConditionNode): node is ConditionOrNode {\n return \"or\" in node;\n }\n\n private static isNotNode(node: ConditionNode): node is ConditionNotNode {\n return \"not\" in node;\n }\n\n private static isRelationalOperator(\n op: ConditionOp,\n ): op is RelationalOperator {\n return op === \"gt\" || op === \"gte\" || op === \"lt\" || op === \"lte\";\n }\n\n private static describeError(error: unknown): {\n name: string;\n message: string;\n } {\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n };\n }\n\n return {\n name: \"NonErrorThrown\",\n message: String(error),\n };\n }\n\n private static buildNullishNumericOperandMessage(\n node: ConditionLeafNode,\n actual: null | undefined,\n ): string {\n const resolvedValue = actual === null ? \"null\" : \"undefined\";\n\n return `${NULLISH_NUMERIC_OPERAND_NOT_ALLOWED_TAG}: \"${node.field}\" resolved to ${resolvedValue} for numeric operator \"${node.op}\"`;\n }\n\n private static buildNullishDateOperandMessage(\n node: ConditionLeafNode,\n actual: null | undefined,\n ): string {\n const resolvedValue = actual === null ? \"null\" : \"undefined\";\n\n return `${NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG}: \"${node.field}\" resolved to ${resolvedValue} for date comparison operator \"${node.op}\"`;\n }\n\n private static buildInvalidDateOperandMessage(\n node: ConditionLeafNode,\n ): string {\n return `${INVALID_DATE_OPERAND_TAG}: \"${node.field}\" with operator \"${node.op}\" requires Date or ISO 8601 UTC string operands`;\n }\n\n private static buildInvalidNumericOperandMessage(\n node: ConditionLeafNode,\n ): string {\n return `${INVALID_NUMERIC_OPERAND_TAG}: \"${node.field}\" with operator \"${node.op}\" requires numeric operands`;\n }\n\n private static buildInvalidSetOperandMessage(\n node: ConditionLeafNode,\n ): string {\n return `${INVALID_SET_OPERAND_TAG}: \"${node.field}\" with operator \"${node.op}\" requires an array operand`;\n }\n\n private static buildEmptyOrConditionMessage(): string {\n return `${EMPTY_OR_CONDITION_TAG}: OR nodes must contain at least one child condition`;\n }\n\n private static buildEmptyAndConditionMessage(): string {\n return `${EMPTY_AND_CONDITION_TAG}: AND nodes must contain at least one child condition`;\n }\n\n private static parseComparableDate(\n value: unknown,\n ): Result<Date, string> | null {\n if (value instanceof Date) {\n if (!PolicyDateUtils.isValid(value)) {\n return Result.err(\"Invalid Date instance\");\n }\n\n return Result.ok(value);\n }\n\n if (\n typeof value !== \"string\" ||\n !ISO_8601_UTC_DATE_PATTERN.test(value)\n ) {\n return null;\n }\n\n const parsed = new Date(value);\n if (\n !PolicyDateUtils.isValid(parsed) ||\n parsed.toISOString() !== value\n ) {\n return Result.err(\"Invalid ISO 8601 UTC date string\");\n }\n\n return Result.ok(parsed);\n }\n\n private static evaluateRelationalNumbers(\n actual: number,\n op: RelationalOperator,\n expected: number,\n ): boolean {\n switch (op) {\n case \"gt\":\n return actual > expected;\n case \"gte\":\n return actual >= expected;\n case \"lt\":\n return actual < expected;\n case \"lte\":\n return actual <= expected;\n }\n }\n\n private buildReport(params: {\n readonly level: ConditionEvaluationReport[\"level\"];\n readonly tag: ConditionEvaluationReport[\"tag\"];\n readonly message: string;\n readonly details: Readonly<Record<string, unknown>>;\n }): ConditionEvaluationReport {\n return {\n occurredAt: new Date(),\n level: params.level,\n tag: params.tag,\n message: params.message,\n engineVersion: this.options.engineVersion,\n details: params.details,\n };\n }\n\n private conditionEvalErr<TValue>(\n node: ConditionNode,\n error: unknown,\n ): Result<TValue, string> {\n const cause = ConditionEvaluatorV1.describeError(error);\n const message = `${CONDITION_EVAL_THROWN_TAG}: ${cause.name}: ${cause.message}`;\n\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: CONDITION_EVAL_THROWN_TAG,\n message,\n details: { node, cause },\n }),\n );\n\n return Result.err(message);\n }\n\n private reportDateOperandError(\n node: ConditionLeafNode,\n actual: unknown,\n ): Result<boolean, string> {\n const message =\n ConditionEvaluatorV1.buildInvalidDateOperandMessage(node);\n\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: INVALID_DATE_OPERAND_TAG,\n message,\n details: {\n field: node.field,\n op: node.op,\n actual,\n expected: node.value,\n node,\n },\n }),\n );\n\n return Result.err(message);\n }\n\n private reportInvalidNumericOperand(\n node: ConditionLeafNode,\n actual: unknown,\n ): Result<boolean, string> {\n const message =\n ConditionEvaluatorV1.buildInvalidNumericOperandMessage(node);\n\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: INVALID_NUMERIC_OPERAND_TAG,\n message,\n details: {\n field: node.field,\n op: node.op,\n actual,\n expected: node.value,\n node,\n },\n }),\n );\n\n return Result.err(message);\n }\n\n private reportInvalidSetOperand(\n node: ConditionLeafNode,\n actual: unknown,\n ): Result<boolean, string> {\n const message =\n ConditionEvaluatorV1.buildInvalidSetOperandMessage(node);\n\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: INVALID_SET_OPERAND_TAG,\n message,\n details: {\n field: node.field,\n op: node.op,\n actual,\n expected: node.value,\n node,\n },\n }),\n );\n\n return Result.err(message);\n }\n\n private evaluateDateRelationalNode(\n node: ConditionLeafNode,\n actual: unknown,\n ): Result<boolean, string> | null {\n if (!ConditionEvaluatorV1.isRelationalOperator(node.op)) {\n return null;\n }\n\n const actualDateResult =\n ConditionEvaluatorV1.parseComparableDate(actual);\n const expectedDateResult = ConditionEvaluatorV1.parseComparableDate(\n node.value,\n );\n\n if (actualDateResult === null && expectedDateResult === null) {\n return null;\n }\n\n const allowsNull = node.allowNull === true;\n\n if (actual === null) {\n if (allowsNull) {\n return Result.ok(false);\n }\n\n const message = ConditionEvaluatorV1.buildNullishDateOperandMessage(\n node,\n actual,\n );\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG,\n message,\n details: {\n field: node.field,\n op: node.op,\n actual,\n expected: node.value,\n allowNull: allowsNull,\n node,\n },\n }),\n );\n\n return Result.err(message);\n }\n\n if (actual === undefined) {\n const message = ConditionEvaluatorV1.buildNullishDateOperandMessage(\n node,\n actual,\n );\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: NULLISH_DATE_OPERAND_NOT_ALLOWED_TAG,\n message,\n details: {\n field: node.field,\n op: node.op,\n actual,\n expected: node.value,\n allowNull: allowsNull,\n node,\n },\n }),\n );\n\n return Result.err(message);\n }\n\n if (\n actualDateResult === null ||\n actualDateResult.isErr() ||\n expectedDateResult === null ||\n expectedDateResult.isErr()\n ) {\n return this.reportDateOperandError(node, actual);\n }\n\n return Result.ok(\n ConditionEvaluatorV1.evaluateRelationalNumbers(\n actualDateResult.getOrNull()!.getTime(),\n node.op,\n expectedDateResult.getOrNull()!.getTime(),\n ),\n );\n }\n\n private evaluateOperator(\n actual: unknown,\n op: ConditionOp,\n expected: unknown,\n ): boolean {\n switch (op) {\n case \"eq\":\n return actual === expected;\n case \"neq\":\n return actual !== expected;\n case \"gt\":\n return (\n typeof actual === \"number\" &&\n typeof expected === \"number\" &&\n ConditionEvaluatorV1.evaluateRelationalNumbers(\n actual,\n op,\n expected,\n )\n );\n case \"gte\":\n return (\n typeof actual === \"number\" &&\n typeof expected === \"number\" &&\n ConditionEvaluatorV1.evaluateRelationalNumbers(\n actual,\n op,\n expected,\n )\n );\n case \"lt\":\n return (\n typeof actual === \"number\" &&\n typeof expected === \"number\" &&\n ConditionEvaluatorV1.evaluateRelationalNumbers(\n actual,\n op,\n expected,\n )\n );\n case \"lte\":\n return (\n typeof actual === \"number\" &&\n typeof expected === \"number\" &&\n ConditionEvaluatorV1.evaluateRelationalNumbers(\n actual,\n op,\n expected,\n )\n );\n case \"in\":\n return Array.isArray(expected) && expected.includes(actual);\n case \"notIn\":\n return Array.isArray(expected) && !expected.includes(actual);\n case \"isNull\":\n return actual === null;\n case \"isNotNull\":\n return actual !== null && actual !== undefined;\n }\n }\n\n private evaluateNumericRelationalNode(\n node: ConditionLeafNode,\n actual: unknown,\n ): Result<boolean, string> {\n const allowsNull = node.allowNull === true;\n if (actual === undefined || (actual === null && !allowsNull)) {\n const message =\n ConditionEvaluatorV1.buildNullishNumericOperandMessage(\n node,\n actual as null | undefined,\n );\n\n this.options.reporter.error(\n this.buildReport({\n level: \"error\",\n tag: NULLISH_NUMERIC_OPERAND_NOT_ALLOWED_TAG,\n message,\n details: {\n field: node.field,\n op: node.op,\n actual,\n expected: node.value,\n allowNull: allowsNull,\n node,\n },\n }),\n );\n\n return Result.err(message);\n }\n\n // null + allowNull: a relational comparison against a missing value\n // never matches.\n if (actual === null) {\n return Result.ok(false);\n }\n\n // Both operands must be numbers. A present but wrong-typed operand is a\n // context/configuration error, surfaced like the date path instead of\n // silently collapsing to \"no match\".\n if (typeof actual !== \"number\" || typeof node.value !== \"number\") {\n return this.reportInvalidNumericOperand(node, actual);\n }\n\n return Result.ok(this.evaluateOperator(actual, node.op, node.value));\n }\n\n private evaluateLeafNode(node: ConditionLeafNode): Result<boolean, string> {\n const actualResult = PolicyContextPath.getOrAbsent(\n this.context,\n node.field,\n );\n if (actualResult.isErr()) {\n this.options.reporter.warn(\n this.buildReport({\n level: \"warn\",\n tag: \"MISSING_CONTEXT_FIELD\",\n message: `MISSING_CONTEXT_FIELD: \"${node.field}\" not found in context`,\n details: { field: node.field, node },\n }),\n );\n\n return Result.err(\n `MISSING_CONTEXT_FIELD: \"${node.field}\" not found in context`,\n );\n }\n\n try {\n const actual = actualResult.getOrThrow();\n if (ConditionEvaluatorV1.isRelationalOperator(node.op)) {\n const dateResult = this.evaluateDateRelationalNode(\n node,\n actual,\n );\n if (dateResult !== null) {\n return dateResult;\n }\n\n return this.evaluateNumericRelationalNode(node, actual);\n }\n\n if (\n (node.op === \"in\" || node.op === \"notIn\") &&\n !Array.isArray(node.value)\n ) {\n return this.reportInvalidSetOperand(node, actual);\n }\n\n return Result.ok(\n this.evaluateOperator(actual, node.op, node.value),\n );\n } catch (error) {\n return this.conditionEvalErr(node, error);\n }\n }\n\n private buildTrace(params: {\n readonly conditionPath: string;\n readonly decisiveNode: ConditionNode;\n readonly lastEvaluatedLeaf: ConditionLeafNode;\n readonly lastEvaluatedLeafPath: string;\n readonly lastEvaluatedLeafResult: boolean;\n }): ConditionEvaluationTrace {\n return {\n conditionPath: params.conditionPath,\n decisiveNode: params.decisiveNode,\n lastEvaluatedLeaf: params.lastEvaluatedLeaf,\n lastEvaluatedLeafPath: params.lastEvaluatedLeafPath,\n lastEvaluatedLeafResult: params.lastEvaluatedLeafResult,\n };\n }\n\n private evaluateWithTraceInternal(\n node: ConditionNode,\n path: string,\n ): Result<TracedConditionEvaluation, string> {\n if (ConditionEvaluatorV1.isLeafNode(node)) {\n const leafResult = this.evaluateLeafNode(node);\n if (leafResult.isErr()) {\n return Result.err(leafResult.errorOrNull()!);\n }\n\n const matched = leafResult.getOrNull()!;\n return Result.ok({\n matched,\n trace: this.buildTrace({\n conditionPath: path,\n decisiveNode: node,\n lastEvaluatedLeaf: node,\n lastEvaluatedLeafPath: path,\n lastEvaluatedLeafResult: matched,\n }),\n });\n }\n\n if (ConditionEvaluatorV1.isAndNode(node)) {\n if (node.and.length === 0) {\n return Result.err(\n ConditionEvaluatorV1.buildEmptyAndConditionMessage(),\n );\n }\n\n let lastTracedChild: TracedConditionEvaluation | null = null;\n\n for (const [index, child] of node.and.entries()) {\n const childPath = `${path}.and[${index}]`;\n const childResult = this.evaluateWithTraceInternal(\n child,\n childPath,\n );\n if (childResult.isErr()) {\n return Result.err(childResult.errorOrNull()!);\n }\n\n const tracedChild = childResult.getOrNull()!;\n lastTracedChild = tracedChild;\n if (!tracedChild.matched) {\n return Result.ok({\n matched: false,\n trace: this.buildTrace({\n conditionPath: childPath,\n decisiveNode: child,\n lastEvaluatedLeaf:\n tracedChild.trace.lastEvaluatedLeaf,\n lastEvaluatedLeafPath:\n tracedChild.trace.lastEvaluatedLeafPath,\n lastEvaluatedLeafResult:\n tracedChild.trace.lastEvaluatedLeafResult,\n }),\n });\n }\n }\n\n return Result.ok({\n matched: true,\n trace: lastTracedChild!.trace,\n });\n }\n\n if (ConditionEvaluatorV1.isOrNode(node)) {\n let lastTrace: ConditionEvaluationTrace | null = null;\n\n for (const [index, child] of node.or.entries()) {\n const childResult = this.evaluateWithTraceInternal(\n child,\n `${path}.or[${index}]`,\n );\n if (childResult.isErr()) {\n return Result.err(childResult.errorOrNull()!);\n }\n\n const tracedChild = childResult.getOrNull()!;\n lastTrace = tracedChild.trace;\n if (tracedChild.matched) {\n return Result.ok({\n matched: true,\n trace: tracedChild.trace,\n });\n }\n }\n\n if (lastTrace === null) {\n return Result.err(\n ConditionEvaluatorV1.buildEmptyOrConditionMessage(),\n );\n }\n\n return Result.ok({ matched: false, trace: lastTrace! });\n }\n\n if (ConditionEvaluatorV1.isNotNode(node)) {\n const childPath = `${path}.not`;\n const childResult = this.evaluateWithTraceInternal(\n node.not,\n childPath,\n );\n if (childResult.isErr()) {\n return Result.err(childResult.errorOrNull()!);\n }\n\n const tracedChild = childResult.getOrNull()!;\n return Result.ok({\n matched: !tracedChild.matched,\n trace: this.buildTrace({\n conditionPath: path,\n decisiveNode: node,\n lastEvaluatedLeaf: tracedChild.trace.lastEvaluatedLeaf,\n lastEvaluatedLeafPath:\n tracedChild.trace.lastEvaluatedLeafPath,\n lastEvaluatedLeafResult:\n tracedChild.trace.lastEvaluatedLeafResult,\n }),\n });\n }\n\n return this.conditionEvalErr(\n node,\n new TypeError(\"Invalid condition node shape\"),\n );\n }\n\n evaluate(node: ConditionNode): Result<boolean, string> {\n try {\n const result = this.evaluateWithTraceInternal(node, \"$\");\n if (result.isErr()) {\n return Result.err(result.errorOrNull()!);\n }\n\n return Result.ok(result.getOrNull()!.matched);\n } catch (error) {\n return this.conditionEvalErr(node, error);\n }\n }\n\n evaluateWithTrace(\n node: ConditionNode,\n ): Result<TracedConditionEvaluation, string> {\n try {\n return this.evaluateWithTraceInternal(node, \"$\");\n } catch (error) {\n return this.conditionEvalErr(node, error);\n }\n }\n\n static extractFields(node: ConditionNode): string[] {\n if (ConditionEvaluatorV1.isLeafNode(node)) {\n return [node.field];\n }\n\n if (ConditionEvaluatorV1.isAndNode(node)) {\n return node.and.flatMap((child) =>\n ConditionEvaluatorV1.extractFields(child),\n );\n }\n\n if (ConditionEvaluatorV1.isOrNode(node)) {\n return node.or.flatMap((child) =>\n ConditionEvaluatorV1.extractFields(child),\n );\n }\n\n if (ConditionEvaluatorV1.isNotNode(node)) {\n return ConditionEvaluatorV1.extractFields(node.not);\n }\n\n return [];\n }\n}\n","import { z } from \"zod\";\n\nimport { Result } from \"../../../../result/result.js\";\n\nimport type { GatePayloadV1 } from \"./gate-types-v1.js\";\nimport {\n conditionLeafNodeSchema,\n conditionNodeSchema,\n} from \"../condition-schema.js\";\n\n// Re-export so gate/v1 public API remains unchanged.\nexport { conditionLeafNodeSchema, conditionNodeSchema };\n\nexport class GatePayloadSchemaV1 {\n static readonly schema = z.union([\n z\n .object({\n condition: conditionNodeSchema,\n })\n .strict(),\n z\n .object({\n allowIf: conditionNodeSchema,\n defaultOutcome: z.enum([\"ALLOW\", \"DENY\"]),\n })\n .strict(),\n ]);\n\n static parse(payload: unknown): Result<GatePayloadV1, string> {\n const parsed = GatePayloadSchemaV1.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 gate payload: ${details}`);\n }\n\n return Result.ok(parsed.data as GatePayloadV1);\n }\n}\n\nexport const gatePayloadSchema = GatePayloadSchemaV1.schema;\n"],"mappings":";;;;AAEA,IAAa,uBAAb,MAA4D;CACxD,OAAO,QAAuD,CAAC;AACnE;;;ACWA,SAAS,aACL,gBACA,OACI;CACJ,IAAI;EACA,eAAe,OAAO,KAAK;CAC/B,QAAQ,CAER;AACJ;;;;;AAMA,IAAa,aAAb,MAAwB;CACpB;CACA;CAEA,YAAY,UAA6B,CAAC,GAAG;EACzC,MAAM,WACF,QAAQ,eAAe,YAAY,IAAI,qBAAqB;EAChE,KAAKA,mBAAmB;EACxB,KAAKC,mBAAmB;CAC5B;CAEA,UAAU,SAAkC;EACxC,MAAM,WAAW,QAAQ,eAAe;EACxC,IAAI,UACA,KAAKA,mBAAmB;EAE5B,OAAO;CACX;CAGA,QAAc;EACV,KAAKA,mBAAmB,KAAKD;EAC7B,OAAO;CACX;CAEA,oBAAoC;EAChC,OAAO,KAAKC;CAChB;CAEA,8BACI,eAC0B;EAC1B,OAAO;GACH,UAAU,KAAKC,2BAA2B,KAAKD,gBAAgB;GAC/D;EACJ;CACJ;CAEA,2BACI,gBAC0B;EAC1B,OAAO;GACH,KAAK,QAAQ;IACT,aAAa,gBAAgB;KACzB,MAAM;KACN,GAAG;IACP,CAAuB;GAC3B;GACA,MAAM,QAAQ;IACV,aAAa,gBAAgB;KACzB,MAAM;KACN,GAAG;IACP,CAAuB;GAC3B;EACJ;CACJ;AACJ;;;;;;;;;;;AC3EA,MAAa,aAAa,IAAI,WAAW,EACrC,eAAe,EAAE,UAAU,IAAI,qBAAqB,EAAE,EAC1D,CAAC;;;ACXD,IAAa,kBAAb,MAA6B;CACzB,OAAO,QAAQ,OAAsB;EACjC,OAAO,YAAY,KAAK;CAC5B;AACJ;;;;;;;ACCA,IAAa,oBAAb,MAAa,kBAAkB;;4BACkB,IAAI,IAAI;GACjD;GACA;GACA;EACJ,CAAC;;CAED,OAAe,QACX,KACA,MAOF;EACE,MAAM,iBAAiB,kBAAkB,cAAc,IAAI;EAC3D,IAAI,eAAe,MAAM,GACrB,OAAO,OAAO,IAAI,eAAe,YAAY,CAAE;EAGnD,MAAM,WAAW,eAAe,UAAU;EAC1C,IAAI,UAAmB;EAEvB,KAAK,MAAM,WAAW,UAAU;GAC5B,IACI,YAAY,QACZ,YAAY,KAAA,KACZ,OAAO,YAAY,UAEnB,OAAO,OAAO,GAAG;IAAE,OAAO;IAAO,OAAO,KAAA;GAAU,CAAC;GAGvD,MAAM,SAAS;GACf,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,OAAO,GACrD,OAAO,OAAO,GAAG;IAAE,OAAO;IAAO,OAAO,KAAA;GAAU,CAAC;GAGvD,UAAU,OAAO;EACrB;EAEA,OAAO,OAAO,GAAG;GAAE,OAAO;GAAM,OAAO;EAAQ,CAAC;CACpD;CAEA,OAAe,cACX,MACiC;EACjC,IAAI,KAAK,KAAK,EAAE,WAAW,GACvB,OAAO,OAAO,IAAI,sBAAsB;EAG5C,MAAM,WAAW,KAAK,MAAM,GAAG;EAC/B,IAAI,SAAS,MAAM,YAAY,QAAQ,WAAW,CAAC,GAC/C,OAAO,OAAO,IAAI,SAAS,KAAK,4BAA4B;EAGhE,MAAM,mBAAmB,SAAS,MAAM,YACpC,kBAAkB,mBAAmB,IAAI,OAAO,CACpD;EACA,IAAI,qBAAqB,KAAA,GACrB,OAAO,OAAO,IACV,SAAS,KAAK,gCAAgC,iBAAiB,EACnE;EAGJ,OAAO,OAAO,GAAG,QAAQ;CAC7B;CAEA,OAAe,cACX,OACgC;EAChC,IACI,OAAO,UAAU,YACjB,UAAU,QACV,MAAM,QAAQ,KAAK,GAEnB,OAAO;EAGX,MAAM,YAAY,OAAO,eAAe,KAAK;EAC7C,OAAO,cAAc,OAAO,aAAa,cAAc;CAC3D;CAEA,OAAO,YACH,KACA,MACyB;EACzB,MAAM,eAAe,kBAAkB,QAAQ,KAAK,IAAI;EACxD,IAAI,aAAa,MAAM,GACnB,OAAO,OAAO,IAAI,QAAQ;EAG9B,MAAM,EAAE,OAAO,UAAU,aAAa,UAAU;EAChD,IAAI,CAAC,OACD,OAAO,OAAO,IAAI,QAAQ;EAG9B,OAAO,OAAO,GAAG,KAAK;CAC1B;CAEA,OAAO,IAAI,KAA8B,MAAuB;EAC5D,MAAM,eAAe,kBAAkB,QAAQ,KAAK,IAAI;EACxD,IAAI,aAAa,MAAM,GACnB,OAAO;EAGX,OAAO,aAAa,UAAU,EAAG;CACrC;CAEA,OAAO,IACH,KACA,MACA,OACoB;EACpB,MAAM,iBAAiB,kBAAkB,cAAc,IAAI;EAC3D,IAAI,eAAe,MAAM,GACrB,OAAO,OAAO,IAAI,eAAe,YAAY,CAAE;EAGnD,MAAM,WAAW,eAAe,UAAU;EAC1C,IAAI,UAAmC;EAEvC,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,SAAS,GAAG,KAAK;GAC1C,MAAM,MAAM,SAAS;GACrB,MAAM,OAAO,QAAQ;GAErB,IAAI,SAAS,KAAA,GAAW;IACpB,MAAM,YAAY,OAAO,OAAO,IAAI;IAIpC,QAAQ,OAAO;IACf,UAAU;IACV;GACJ;GAEA,IAAI,CAAC,kBAAkB,cAAc,IAAI,GACrC,OAAO,OAAO,IACV,8BAA8B,KAAK,aAAa,SAC3C,MAAM,GAAG,IAAI,CAAC,EACd,KAAK,GAAG,EAAE,sCACnB;GAGJ,UAAU;EACd;EAEA,QAAQ,SAAS,SAAS,SAAS,MAAM;EACzC,OAAO,OAAO,GAAG,KAAA,CAAS;CAC9B;AACJ;;;ACtJA,MAAM,oBAAoB,EAAE,KAAK;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ,CAAC;AAED,MAAa,0BAAwD,EAChE,OAAO;CACJ,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;CACvB,IAAI;CACJ,OAAO,EAAE,QAAQ;CACjB,WAAW,EAAE,QAAQ,IAAI,EAAE,SAAS;AACxC,CAAC,EACA,OAAO;AAEZ,MAAa,sBAAgD,EAAE,WAC3D,EAAE,MAAM;CACJ;CACA,EACK,OAAO,EACJ,KAAK,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC,EAC3C,CAAC,EACA,OAAO;CACZ,EACK,OAAO,EACJ,IAAI,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC,EAC1C,CAAC,EACA,OAAO;CACZ,EACK,OAAO,EACJ,KAAK,oBACT,CAAC,EACA,OAAO;AAChB,CAAC,CACL;;;AC/BA,MAAM,4BAA4B;AAClC,MAAM,0CACF;AACJ,MAAM,uCAAuC;AAC7C,MAAM,2BAA2B;AACjC,MAAM,8BAA8B;AACpC,MAAM,0BAA0B;AAChC,MAAM,yBAAyB;AAC/B,MAAM,0BAA0B;AAChC,MAAM,4BACF;AAiBJ,IAAa,uBAAb,MAAa,qBAAqB;CAC9B,YACI,SACA,SACF;EAFmB,KAAA,UAAA;EACA,KAAA,UAAA;CAClB;CAEH,OAAe,WAAW,MAAgD;EACtE,OAAO,WAAW,QAAQ,QAAQ;CACtC;CAEA,OAAe,UAAU,MAA+C;EACpE,OAAO,SAAS;CACpB;CAEA,OAAe,SAAS,MAA8C;EAClE,OAAO,QAAQ;CACnB;CAEA,OAAe,UAAU,MAA+C;EACpE,OAAO,SAAS;CACpB;CAEA,OAAe,qBACX,IACwB;EACxB,OAAO,OAAO,QAAQ,OAAO,SAAS,OAAO,QAAQ,OAAO;CAChE;CAEA,OAAe,cAAc,OAG3B;EACE,IAAI,iBAAiB,OACjB,OAAO;GACH,MAAM,MAAM;GACZ,SAAS,MAAM;EACnB;EAGJ,OAAO;GACH,MAAM;GACN,SAAS,OAAO,KAAK;EACzB;CACJ;CAEA,OAAe,kCACX,MACA,QACM;EACN,MAAM,gBAAgB,WAAW,OAAO,SAAS;EAEjD,OAAO,GAAG,wCAAwC,KAAK,KAAK,MAAM,gBAAgB,cAAc,yBAAyB,KAAK,GAAG;CACrI;CAEA,OAAe,+BACX,MACA,QACM;EACN,MAAM,gBAAgB,WAAW,OAAO,SAAS;EAEjD,OAAO,GAAG,qCAAqC,KAAK,KAAK,MAAM,gBAAgB,cAAc,iCAAiC,KAAK,GAAG;CAC1I;CAEA,OAAe,+BACX,MACM;EACN,OAAO,GAAG,yBAAyB,KAAK,KAAK,MAAM,mBAAmB,KAAK,GAAG;CAClF;CAEA,OAAe,kCACX,MACM;EACN,OAAO,GAAG,4BAA4B,KAAK,KAAK,MAAM,mBAAmB,KAAK,GAAG;CACrF;CAEA,OAAe,8BACX,MACM;EACN,OAAO,GAAG,wBAAwB,KAAK,KAAK,MAAM,mBAAmB,KAAK,GAAG;CACjF;CAEA,OAAe,+BAAuC;EAClD,OAAO,GAAG,uBAAuB;CACrC;CAEA,OAAe,gCAAwC;EACnD,OAAO,GAAG,wBAAwB;CACtC;CAEA,OAAe,oBACX,OAC2B;EAC3B,IAAI,iBAAiB,MAAM;GACvB,IAAI,CAAC,gBAAgB,QAAQ,KAAK,GAC9B,OAAO,OAAO,IAAI,uBAAuB;GAG7C,OAAO,OAAO,GAAG,KAAK;EAC1B;EAEA,IACI,OAAO,UAAU,YACjB,CAAC,0BAA0B,KAAK,KAAK,GAErC,OAAO;EAGX,MAAM,SAAS,IAAI,KAAK,KAAK;EAC7B,IACI,CAAC,gBAAgB,QAAQ,MAAM,KAC/B,OAAO,YAAY,MAAM,OAEzB,OAAO,OAAO,IAAI,kCAAkC;EAGxD,OAAO,OAAO,GAAG,MAAM;CAC3B;CAEA,OAAe,0BACX,QACA,IACA,UACO;EACP,QAAQ,IAAR;GACI,KAAK,MACD,OAAO,SAAS;GACpB,KAAK,OACD,OAAO,UAAU;GACrB,KAAK,MACD,OAAO,SAAS;GACpB,KAAK,OACD,OAAO,UAAU;EACzB;CACJ;CAEA,YAAoB,QAKU;EAC1B,OAAO;GACH,4BAAY,IAAI,KAAK;GACrB,OAAO,OAAO;GACd,KAAK,OAAO;GACZ,SAAS,OAAO;GAChB,eAAe,KAAK,QAAQ;GAC5B,SAAS,OAAO;EACpB;CACJ;CAEA,iBACI,MACA,OACsB;EACtB,MAAM,QAAQ,qBAAqB,cAAc,KAAK;EACtD,MAAM,UAAU,GAAG,0BAA0B,IAAI,MAAM,KAAK,IAAI,MAAM;EAEtE,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;GACb,OAAO;GACP,KAAK;GACL;GACA,SAAS;IAAE;IAAM;GAAM;EAC3B,CAAC,CACL;EAEA,OAAO,OAAO,IAAI,OAAO;CAC7B;CAEA,uBACI,MACA,QACuB;EACvB,MAAM,UACF,qBAAqB,+BAA+B,IAAI;EAE5D,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;GACb,OAAO;GACP,KAAK;GACL;GACA,SAAS;IACL,OAAO,KAAK;IACZ,IAAI,KAAK;IACT;IACA,UAAU,KAAK;IACf;GACJ;EACJ,CAAC,CACL;EAEA,OAAO,OAAO,IAAI,OAAO;CAC7B;CAEA,4BACI,MACA,QACuB;EACvB,MAAM,UACF,qBAAqB,kCAAkC,IAAI;EAE/D,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;GACb,OAAO;GACP,KAAK;GACL;GACA,SAAS;IACL,OAAO,KAAK;IACZ,IAAI,KAAK;IACT;IACA,UAAU,KAAK;IACf;GACJ;EACJ,CAAC,CACL;EAEA,OAAO,OAAO,IAAI,OAAO;CAC7B;CAEA,wBACI,MACA,QACuB;EACvB,MAAM,UACF,qBAAqB,8BAA8B,IAAI;EAE3D,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;GACb,OAAO;GACP,KAAK;GACL;GACA,SAAS;IACL,OAAO,KAAK;IACZ,IAAI,KAAK;IACT;IACA,UAAU,KAAK;IACf;GACJ;EACJ,CAAC,CACL;EAEA,OAAO,OAAO,IAAI,OAAO;CAC7B;CAEA,2BACI,MACA,QAC8B;EAC9B,IAAI,CAAC,qBAAqB,qBAAqB,KAAK,EAAE,GAClD,OAAO;EAGX,MAAM,mBACF,qBAAqB,oBAAoB,MAAM;EACnD,MAAM,qBAAqB,qBAAqB,oBAC5C,KAAK,KACT;EAEA,IAAI,qBAAqB,QAAQ,uBAAuB,MACpD,OAAO;EAGX,MAAM,aAAa,KAAK,cAAc;EAEtC,IAAI,WAAW,MAAM;GACjB,IAAI,YACA,OAAO,OAAO,GAAG,KAAK;GAG1B,MAAM,UAAU,qBAAqB,+BACjC,MACA,MACJ;GACA,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;IACb,OAAO;IACP,KAAK;IACL;IACA,SAAS;KACL,OAAO,KAAK;KACZ,IAAI,KAAK;KACT;KACA,UAAU,KAAK;KACf,WAAW;KACX;IACJ;GACJ,CAAC,CACL;GAEA,OAAO,OAAO,IAAI,OAAO;EAC7B;EAEA,IAAI,WAAW,KAAA,GAAW;GACtB,MAAM,UAAU,qBAAqB,+BACjC,MACA,MACJ;GACA,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;IACb,OAAO;IACP,KAAK;IACL;IACA,SAAS;KACL,OAAO,KAAK;KACZ,IAAI,KAAK;KACT;KACA,UAAU,KAAK;KACf,WAAW;KACX;IACJ;GACJ,CAAC,CACL;GAEA,OAAO,OAAO,IAAI,OAAO;EAC7B;EAEA,IACI,qBAAqB,QACrB,iBAAiB,MAAM,KACvB,uBAAuB,QACvB,mBAAmB,MAAM,GAEzB,OAAO,KAAK,uBAAuB,MAAM,MAAM;EAGnD,OAAO,OAAO,GACV,qBAAqB,0BACjB,iBAAiB,UAAU,EAAG,QAAQ,GACtC,KAAK,IACL,mBAAmB,UAAU,EAAG,QAAQ,CAC5C,CACJ;CACJ;CAEA,iBACI,QACA,IACA,UACO;EACP,QAAQ,IAAR;GACI,KAAK,MACD,OAAO,WAAW;GACtB,KAAK,OACD,OAAO,WAAW;GACtB,KAAK,MACD,OACI,OAAO,WAAW,YAClB,OAAO,aAAa,YACpB,qBAAqB,0BACjB,QACA,IACA,QACJ;GAER,KAAK,OACD,OACI,OAAO,WAAW,YAClB,OAAO,aAAa,YACpB,qBAAqB,0BACjB,QACA,IACA,QACJ;GAER,KAAK,MACD,OACI,OAAO,WAAW,YAClB,OAAO,aAAa,YACpB,qBAAqB,0BACjB,QACA,IACA,QACJ;GAER,KAAK,OACD,OACI,OAAO,WAAW,YAClB,OAAO,aAAa,YACpB,qBAAqB,0BACjB,QACA,IACA,QACJ;GAER,KAAK,MACD,OAAO,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,MAAM;GAC9D,KAAK,SACD,OAAO,MAAM,QAAQ,QAAQ,KAAK,CAAC,SAAS,SAAS,MAAM;GAC/D,KAAK,UACD,OAAO,WAAW;GACtB,KAAK,aACD,OAAO,WAAW,QAAQ,WAAW,KAAA;EAC7C;CACJ;CAEA,8BACI,MACA,QACuB;EACvB,MAAM,aAAa,KAAK,cAAc;EACtC,IAAI,WAAW,KAAA,KAAc,WAAW,QAAQ,CAAC,YAAa;GAC1D,MAAM,UACF,qBAAqB,kCACjB,MACA,MACJ;GAEJ,KAAK,QAAQ,SAAS,MAClB,KAAK,YAAY;IACb,OAAO;IACP,KAAK;IACL;IACA,SAAS;KACL,OAAO,KAAK;KACZ,IAAI,KAAK;KACT;KACA,UAAU,KAAK;KACf,WAAW;KACX;IACJ;GACJ,CAAC,CACL;GAEA,OAAO,OAAO,IAAI,OAAO;EAC7B;EAIA,IAAI,WAAW,MACX,OAAO,OAAO,GAAG,KAAK;EAM1B,IAAI,OAAO,WAAW,YAAY,OAAO,KAAK,UAAU,UACpD,OAAO,KAAK,4BAA4B,MAAM,MAAM;EAGxD,OAAO,OAAO,GAAG,KAAK,iBAAiB,QAAQ,KAAK,IAAI,KAAK,KAAK,CAAC;CACvE;CAEA,iBAAyB,MAAkD;EACvE,MAAM,eAAe,kBAAkB,YACnC,KAAK,SACL,KAAK,KACT;EACA,IAAI,aAAa,MAAM,GAAG;GACtB,KAAK,QAAQ,SAAS,KAClB,KAAK,YAAY;IACb,OAAO;IACP,KAAK;IACL,SAAS,2BAA2B,KAAK,MAAM;IAC/C,SAAS;KAAE,OAAO,KAAK;KAAO;IAAK;GACvC,CAAC,CACL;GAEA,OAAO,OAAO,IACV,2BAA2B,KAAK,MAAM,uBAC1C;EACJ;EAEA,IAAI;GACA,MAAM,SAAS,aAAa,WAAW;GACvC,IAAI,qBAAqB,qBAAqB,KAAK,EAAE,GAAG;IACpD,MAAM,aAAa,KAAK,2BACpB,MACA,MACJ;IACA,IAAI,eAAe,MACf,OAAO;IAGX,OAAO,KAAK,8BAA8B,MAAM,MAAM;GAC1D;GAEA,KACK,KAAK,OAAO,QAAQ,KAAK,OAAO,YACjC,CAAC,MAAM,QAAQ,KAAK,KAAK,GAEzB,OAAO,KAAK,wBAAwB,MAAM,MAAM;GAGpD,OAAO,OAAO,GACV,KAAK,iBAAiB,QAAQ,KAAK,IAAI,KAAK,KAAK,CACrD;EACJ,SAAS,OAAO;GACZ,OAAO,KAAK,iBAAiB,MAAM,KAAK;EAC5C;CACJ;CAEA,WAAmB,QAMU;EACzB,OAAO;GACH,eAAe,OAAO;GACtB,cAAc,OAAO;GACrB,mBAAmB,OAAO;GAC1B,uBAAuB,OAAO;GAC9B,yBAAyB,OAAO;EACpC;CACJ;CAEA,0BACI,MACA,MACyC;EACzC,IAAI,qBAAqB,WAAW,IAAI,GAAG;GACvC,MAAM,aAAa,KAAK,iBAAiB,IAAI;GAC7C,IAAI,WAAW,MAAM,GACjB,OAAO,OAAO,IAAI,WAAW,YAAY,CAAE;GAG/C,MAAM,UAAU,WAAW,UAAU;GACrC,OAAO,OAAO,GAAG;IACb;IACA,OAAO,KAAK,WAAW;KACnB,eAAe;KACf,cAAc;KACd,mBAAmB;KACnB,uBAAuB;KACvB,yBAAyB;IAC7B,CAAC;GACL,CAAC;EACL;EAEA,IAAI,qBAAqB,UAAU,IAAI,GAAG;GACtC,IAAI,KAAK,IAAI,WAAW,GACpB,OAAO,OAAO,IACV,qBAAqB,8BAA8B,CACvD;GAGJ,IAAI,kBAAoD;GAExD,KAAK,MAAM,CAAC,OAAO,UAAU,KAAK,IAAI,QAAQ,GAAG;IAC7C,MAAM,YAAY,GAAG,KAAK,OAAO,MAAM;IACvC,MAAM,cAAc,KAAK,0BACrB,OACA,SACJ;IACA,IAAI,YAAY,MAAM,GAClB,OAAO,OAAO,IAAI,YAAY,YAAY,CAAE;IAGhD,MAAM,cAAc,YAAY,UAAU;IAC1C,kBAAkB;IAClB,IAAI,CAAC,YAAY,SACb,OAAO,OAAO,GAAG;KACb,SAAS;KACT,OAAO,KAAK,WAAW;MACnB,eAAe;MACf,cAAc;MACd,mBACI,YAAY,MAAM;MACtB,uBACI,YAAY,MAAM;MACtB,yBACI,YAAY,MAAM;KAC1B,CAAC;IACL,CAAC;GAET;GAEA,OAAO,OAAO,GAAG;IACb,SAAS;IACT,OAAO,gBAAiB;GAC5B,CAAC;EACL;EAEA,IAAI,qBAAqB,SAAS,IAAI,GAAG;GACrC,IAAI,YAA6C;GAEjD,KAAK,MAAM,CAAC,OAAO,UAAU,KAAK,GAAG,QAAQ,GAAG;IAC5C,MAAM,cAAc,KAAK,0BACrB,OACA,GAAG,KAAK,MAAM,MAAM,EACxB;IACA,IAAI,YAAY,MAAM,GAClB,OAAO,OAAO,IAAI,YAAY,YAAY,CAAE;IAGhD,MAAM,cAAc,YAAY,UAAU;IAC1C,YAAY,YAAY;IACxB,IAAI,YAAY,SACZ,OAAO,OAAO,GAAG;KACb,SAAS;KACT,OAAO,YAAY;IACvB,CAAC;GAET;GAEA,IAAI,cAAc,MACd,OAAO,OAAO,IACV,qBAAqB,6BAA6B,CACtD;GAGJ,OAAO,OAAO,GAAG;IAAE,SAAS;IAAO,OAAO;GAAW,CAAC;EAC1D;EAEA,IAAI,qBAAqB,UAAU,IAAI,GAAG;GACtC,MAAM,YAAY,GAAG,KAAK;GAC1B,MAAM,cAAc,KAAK,0BACrB,KAAK,KACL,SACJ;GACA,IAAI,YAAY,MAAM,GAClB,OAAO,OAAO,IAAI,YAAY,YAAY,CAAE;GAGhD,MAAM,cAAc,YAAY,UAAU;GAC1C,OAAO,OAAO,GAAG;IACb,SAAS,CAAC,YAAY;IACtB,OAAO,KAAK,WAAW;KACnB,eAAe;KACf,cAAc;KACd,mBAAmB,YAAY,MAAM;KACrC,uBACI,YAAY,MAAM;KACtB,yBACI,YAAY,MAAM;IAC1B,CAAC;GACL,CAAC;EACL;EAEA,OAAO,KAAK,iBACR,sBACA,IAAI,UAAU,8BAA8B,CAChD;CACJ;CAEA,SAAS,MAA8C;EACnD,IAAI;GACA,MAAM,SAAS,KAAK,0BAA0B,MAAM,GAAG;GACvD,IAAI,OAAO,MAAM,GACb,OAAO,OAAO,IAAI,OAAO,YAAY,CAAE;GAG3C,OAAO,OAAO,GAAG,OAAO,UAAU,EAAG,OAAO;EAChD,SAAS,OAAO;GACZ,OAAO,KAAK,iBAAiB,MAAM,KAAK;EAC5C;CACJ;CAEA,kBACI,MACyC;EACzC,IAAI;GACA,OAAO,KAAK,0BAA0B,MAAM,GAAG;EACnD,SAAS,OAAO;GACZ,OAAO,KAAK,iBAAiB,MAAM,KAAK;EAC5C;CACJ;CAEA,OAAO,cAAc,MAA+B;EAChD,IAAI,qBAAqB,WAAW,IAAI,GACpC,OAAO,CAAC,KAAK,KAAK;EAGtB,IAAI,qBAAqB,UAAU,IAAI,GACnC,OAAO,KAAK,IAAI,SAAS,UACrB,qBAAqB,cAAc,KAAK,CAC5C;EAGJ,IAAI,qBAAqB,SAAS,IAAI,GAClC,OAAO,KAAK,GAAG,SAAS,UACpB,qBAAqB,cAAc,KAAK,CAC5C;EAGJ,IAAI,qBAAqB,UAAU,IAAI,GACnC,OAAO,qBAAqB,cAAc,KAAK,GAAG;EAGtD,OAAO,CAAC;CACZ;AACJ;;;AC3sBA,IAAa,sBAAb,MAAa,oBAAoB;;gBACJ,EAAE,MAAM,CAC7B,EACK,OAAO,EACJ,WAAW,oBACf,CAAC,EACA,OAAO,GACZ,EACK,OAAO;GACJ,SAAS;GACT,gBAAgB,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC;EAC5C,CAAC,EACA,OAAO,CAChB,CAAC;;CAED,OAAO,MAAM,SAAiD;EAC1D,MAAM,SAAS,oBAAoB,OAAO,UAAU,OAAO;EAC3D,IAAI,CAAC,OAAO,SAAS;GACjB,MAAM,UAAU,OAAO,MAAM,OACxB,KAAK,UAAU;IACZ,MAAM,OAAO,MAAM,KAAK,KAAK,GAAG;IAChC,OAAO,KAAK,SAAS,IACf,GAAG,KAAK,IAAI,MAAM,YAClB,MAAM;GAChB,CAAC,EACA,KAAK,IAAI;GAEd,OAAO,OAAO,IAAI,yBAAyB,SAAS;EACxD;EAEA,OAAO,OAAO,GAAG,OAAO,IAAqB;CACjD;AACJ;AAEA,MAAa,oBAAoB,oBAAoB"}
1
+ {"version":3,"file":"gate-v1-payload.schema.js","names":[],"sources":["../src/core/policies/engines/v1/condition-schema.ts","../src/core/policies/engines/v1/gate/gate-v1-payload.schema.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport type { ConditionLeafNode, ConditionNode } from \"./condition-types.js\";\n\n// ─── Shared v1 condition Zod schemas ─────────────────────────────────────────\n// Extracted from gate/v1 so both gate/v1 and compute/v1 can validate\n// condition nodes without either engine depending on the other.\n\nconst conditionOpSchema = z.enum([\n \"eq\",\n \"neq\",\n \"gt\",\n \"gte\",\n \"lt\",\n \"lte\",\n \"in\",\n \"notIn\",\n \"isNull\",\n \"isNotNull\",\n]);\n\nexport const conditionLeafNodeSchema: z.ZodType<ConditionLeafNode> = z\n .object({\n field: z.string().min(1),\n op: conditionOpSchema,\n value: z.unknown(),\n allowNull: z.literal(true).optional(),\n })\n .strict() as z.ZodType<ConditionLeafNode>;\n\nexport const conditionNodeSchema: z.ZodType<ConditionNode> = z.lazy(() =>\n z.union([\n conditionLeafNodeSchema,\n z\n .object({\n and: z.array(conditionNodeSchema).min(1),\n })\n .strict(),\n z\n .object({\n or: z.array(conditionNodeSchema).min(1),\n })\n .strict(),\n z\n .object({\n not: conditionNodeSchema,\n })\n .strict(),\n ]),\n);\n","import { z } from \"zod\";\n\nimport { Result } from \"../../../../result/result.js\";\n\nimport type { GatePayloadV1 } from \"./gate-types-v1.js\";\nimport {\n conditionLeafNodeSchema,\n conditionNodeSchema,\n} from \"../condition-schema.js\";\n\n// Re-export so gate/v1 public API remains unchanged.\nexport { conditionLeafNodeSchema, conditionNodeSchema };\n\nexport class GatePayloadSchemaV1 {\n static readonly schema = z.union([\n z\n .object({\n condition: conditionNodeSchema,\n })\n .strict(),\n z\n .object({\n allowIf: conditionNodeSchema,\n defaultOutcome: z.enum([\"ALLOW\", \"DENY\"]),\n })\n .strict(),\n ]);\n\n static parse(payload: unknown): Result<GatePayloadV1, string> {\n const parsed = GatePayloadSchemaV1.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 gate payload: ${details}`);\n }\n\n return Result.ok(parsed.data as GatePayloadV1);\n }\n}\n\nexport const gatePayloadSchema = GatePayloadSchemaV1.schema;\n"],"mappings":";;;AAQA,MAAM,oBAAoB,EAAE,KAAK;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ,CAAC;AAED,MAAa,0BAAwD,EAChE,OAAO;CACJ,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;CACvB,IAAI;CACJ,OAAO,EAAE,QAAQ;CACjB,WAAW,EAAE,QAAQ,IAAI,EAAE,SAAS;AACxC,CAAC,EACA,OAAO;AAEZ,MAAa,sBAAgD,EAAE,WAC3D,EAAE,MAAM;CACJ;CACA,EACK,OAAO,EACJ,KAAK,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC,EAC3C,CAAC,EACA,OAAO;CACZ,EACK,OAAO,EACJ,IAAI,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC,EAC1C,CAAC,EACA,OAAO;CACZ,EACK,OAAO,EACJ,KAAK,oBACT,CAAC,EACA,OAAO;AAChB,CAAC,CACL;;;ACpCA,IAAa,sBAAb,MAAa,oBAAoB;;gBACJ,EAAE,MAAM,CAC7B,EACK,OAAO,EACJ,WAAW,oBACf,CAAC,EACA,OAAO,GACZ,EACK,OAAO;GACJ,SAAS;GACT,gBAAgB,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC;EAC5C,CAAC,EACA,OAAO,CAChB,CAAC;;CAED,OAAO,MAAM,SAAiD;EAC1D,MAAM,SAAS,oBAAoB,OAAO,UAAU,OAAO;EAC3D,IAAI,CAAC,OAAO,SAAS;GACjB,MAAM,UAAU,OAAO,MAAM,OACxB,KAAK,UAAU;IACZ,MAAM,OAAO,MAAM,KAAK,KAAK,GAAG;IAChC,OAAO,KAAK,SAAS,IACf,GAAG,KAAK,IAAI,MAAM,YAClB,MAAM;GAChB,CAAC,EACA,KAAK,IAAI;GAEd,OAAO,OAAO,IAAI,yBAAyB,SAAS;EACxD;EAEA,OAAO,OAAO,GAAG,OAAO,IAAqB;CACjD;AACJ;AAEA,MAAa,oBAAoB,oBAAoB"}