@hyperscale0/udl 1.0.0 → 1.0.123

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 (234) hide show
  1. package/CHANGELOG.md +5 -216
  2. package/LICENSE.md +356 -0
  3. package/NOTICE.md +8 -0
  4. package/README.md +14 -106
  5. package/dist/canonical.d.ts.map +1 -1
  6. package/dist/canonical.js +1 -29
  7. package/dist/canonical.js.map +1 -1
  8. package/dist/diagnostics.d.ts +13 -165
  9. package/dist/diagnostics.d.ts.map +1 -1
  10. package/dist/diagnostics.js +33 -157
  11. package/dist/diagnostics.js.map +1 -1
  12. package/dist/field-value.d.ts +5 -0
  13. package/dist/field-value.d.ts.map +1 -0
  14. package/dist/field-value.js +85 -0
  15. package/dist/field-value.js.map +1 -0
  16. package/dist/finance.d.ts +10 -53
  17. package/dist/finance.d.ts.map +1 -1
  18. package/dist/finance.js +252 -536
  19. package/dist/finance.js.map +1 -1
  20. package/dist/index.d.ts +9 -13
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +9 -9
  23. package/dist/index.js.map +1 -1
  24. package/dist/json.d.ts +2 -0
  25. package/dist/json.d.ts.map +1 -0
  26. package/dist/json.js +30 -0
  27. package/dist/json.js.map +1 -0
  28. package/dist/limits.d.ts +3 -28
  29. package/dist/limits.d.ts.map +1 -1
  30. package/dist/limits.js +5 -31
  31. package/dist/limits.js.map +1 -1
  32. package/dist/object-contract.d.ts +140 -0
  33. package/dist/object-contract.d.ts.map +1 -0
  34. package/dist/object-contract.js +314 -0
  35. package/dist/object-contract.js.map +1 -0
  36. package/dist/object-semantics-schema.d.ts +5710 -0
  37. package/dist/object-semantics-schema.d.ts.map +1 -0
  38. package/dist/object-semantics-schema.js +119 -0
  39. package/dist/object-semantics-schema.js.map +1 -0
  40. package/dist/object-semantics.d.ts +6 -0
  41. package/dist/object-semantics.d.ts.map +1 -0
  42. package/dist/object-semantics.js +279 -0
  43. package/dist/object-semantics.js.map +1 -0
  44. package/dist/object-structures.d.ts +4 -0
  45. package/dist/object-structures.d.ts.map +1 -0
  46. package/dist/object-structures.js +134 -0
  47. package/dist/object-structures.js.map +1 -0
  48. package/dist/reporting-validation.d.ts +8 -0
  49. package/dist/reporting-validation.d.ts.map +1 -0
  50. package/dist/reporting-validation.js +252 -0
  51. package/dist/reporting-validation.js.map +1 -0
  52. package/dist/reporting.d.ts +477 -0
  53. package/dist/reporting.d.ts.map +1 -0
  54. package/dist/reporting.js +169 -0
  55. package/dist/reporting.js.map +1 -0
  56. package/dist/schema.d.ts +5572 -2710
  57. package/dist/schema.d.ts.map +1 -1
  58. package/dist/schema.js +444 -1121
  59. package/dist/schema.js.map +1 -1
  60. package/dist/validation.d.ts +10 -73
  61. package/dist/validation.d.ts.map +1 -1
  62. package/dist/validation.js +1109 -2569
  63. package/dist/validation.js.map +1 -1
  64. package/docs/assets/brand/manifest.json +30 -0
  65. package/docs/assets/brand/udl-horizontal-white.svg +1 -0
  66. package/docs/assets/brand/udl-horizontal.svg +1 -0
  67. package/docs/assets/brand/udl-stacked-white.svg +1 -0
  68. package/docs/assets/brand/udl-stacked.svg +1 -0
  69. package/docs/assets/udl.svg +11 -0
  70. package/package.json +13 -22
  71. package/spec/README.md +300 -172
  72. package/spec/cars.udl.json +249 -0
  73. package/spec/udl.schema.json +3066 -2242
  74. package/src/canonical.ts +1 -35
  75. package/src/diagnostics.ts +76 -209
  76. package/src/field-value.ts +87 -0
  77. package/src/finance.ts +327 -832
  78. package/src/index.ts +18 -95
  79. package/src/json.ts +34 -0
  80. package/src/limits.ts +5 -31
  81. package/src/object-contract.ts +559 -0
  82. package/src/object-semantics-schema.ts +148 -0
  83. package/src/object-semantics.ts +378 -0
  84. package/src/object-structures.ts +255 -0
  85. package/src/reporting-validation.ts +383 -0
  86. package/src/reporting.ts +178 -0
  87. package/src/schema.ts +510 -1277
  88. package/src/validation.ts +1630 -4545
  89. package/LICENSE +0 -661
  90. package/LICENSING.md +0 -51
  91. package/TRADEMARKS.md +0 -35
  92. package/conformance/README.md +0 -82
  93. package/conformance/evolution/action-contract.expected.json +0 -10
  94. package/conformance/evolution/action-contract.live.udl +0 -44
  95. package/conformance/evolution/action-contract.next.udl +0 -45
  96. package/conformance/evolution/product-identity.expected.json +0 -10
  97. package/conformance/evolution/product-identity.live.udl +0 -55
  98. package/conformance/evolution/product-identity.next.udl +0 -55
  99. package/conformance/evolution/version-required.expected.json +0 -10
  100. package/conformance/evolution/version-required.live.udl +0 -55
  101. package/conformance/evolution/version-required.next.udl +0 -58
  102. package/conformance/invalid/action-without-transition.expected.json +0 -10
  103. package/conformance/invalid/action-without-transition.udl +0 -60
  104. package/conformance/invalid/agent-description-too-long.expected.json +0 -10
  105. package/conformance/invalid/agent-description-too-long.udl +0 -57
  106. package/conformance/invalid/blank-title.expected.json +0 -10
  107. package/conformance/invalid/blank-title.udl +0 -54
  108. package/conformance/invalid/composition-dial-duplicate-key.expected.json +0 -10
  109. package/conformance/invalid/composition-dial-duplicate-key.udl +0 -73
  110. package/conformance/invalid/depth-budget.expected.json +0 -10
  111. package/conformance/invalid/depth-budget.udl +0 -49
  112. package/conformance/invalid/duplicate-subject.expected.json +0 -10
  113. package/conformance/invalid/duplicate-subject.udl +0 -230
  114. package/conformance/invalid/forged-effects.expected.json +0 -10
  115. package/conformance/invalid/forged-effects.udl +0 -76
  116. package/conformance/invalid/format-version.expected.json +0 -10
  117. package/conformance/invalid/format-version.udl +0 -54
  118. package/conformance/invalid/instrument-id-not-snake-case.expected.json +0 -10
  119. package/conformance/invalid/instrument-id-not-snake-case.udl +0 -54
  120. package/conformance/invalid/invalid-aggregate-gate-shape.expected.json +0 -10
  121. package/conformance/invalid/invalid-aggregate-gate-shape.udl +0 -1819
  122. package/conformance/invalid/invalid-check-duration.expected.json +0 -10
  123. package/conformance/invalid/invalid-check-duration.udl +0 -219
  124. package/conformance/invalid/invalid-dial-anchor.expected.json +0 -10
  125. package/conformance/invalid/invalid-dial-anchor.udl +0 -219
  126. package/conformance/invalid/invalid-exception-parent-ref.expected.json +0 -10
  127. package/conformance/invalid/invalid-exception-parent-ref.udl +0 -2487
  128. package/conformance/invalid/invalid-exposure-shape.expected.json +0 -10
  129. package/conformance/invalid/invalid-exposure-shape.udl +0 -1819
  130. package/conformance/invalid/invalid-remainder.expected.json +0 -10
  131. package/conformance/invalid/invalid-remainder.udl +0 -220
  132. package/conformance/invalid/invalid-schema-keyword.expected.json +0 -10
  133. package/conformance/invalid/invalid-schema-keyword.udl +0 -220
  134. package/conformance/invalid/invalid-utf8.expected.json +0 -10
  135. package/conformance/invalid/invalid-utf8.udl +0 -1
  136. package/conformance/invalid/malformed-json.expected.json +0 -10
  137. package/conformance/invalid/malformed-json.udl +0 -1
  138. package/conformance/invalid/missing-create-action.expected.json +0 -10
  139. package/conformance/invalid/missing-create-action.udl +0 -48
  140. package/conformance/invalid/missing-exception-amount-field.expected.json +0 -10
  141. package/conformance/invalid/missing-exception-amount-field.udl +0 -2487
  142. package/conformance/invalid/missing-exception-contract.expected.json +0 -14
  143. package/conformance/invalid/missing-exception-contract.udl +0 -2523
  144. package/conformance/invalid/missing-exception-reason-field.expected.json +0 -10
  145. package/conformance/invalid/missing-exception-reason-field.udl +0 -2487
  146. package/conformance/invalid/not-an-object.expected.json +0 -10
  147. package/conformance/invalid/not-an-object.udl +0 -1
  148. package/conformance/invalid/payout-reconcile-not-a-bank-debit.expected.json +0 -10
  149. package/conformance/invalid/payout-reconcile-not-a-bank-debit.udl +0 -259
  150. package/conformance/invalid/quote-freeze-set-incomplete.expected.json +0 -10
  151. package/conformance/invalid/quote-freeze-set-incomplete.udl +0 -261
  152. package/conformance/invalid/quote-named-reference-gate.expected.json +0 -10
  153. package/conformance/invalid/quote-named-reference-gate.udl +0 -50
  154. package/conformance/invalid/reconcile-named-reference-gate.expected.json +0 -10
  155. package/conformance/invalid/reconcile-named-reference-gate.udl +0 -50
  156. package/conformance/invalid/unknown-key.expected.json +0 -10
  157. package/conformance/invalid/unknown-key.udl +0 -55
  158. package/conformance/invalid/unknown-reference-gate-field.expected.json +0 -10
  159. package/conformance/invalid/unknown-reference-gate-field.udl +0 -1819
  160. package/conformance/invalid/unknown-required-field.expected.json +0 -10
  161. package/conformance/invalid/unknown-required-field.udl +0 -220
  162. package/conformance/invalid/unreachable-state.expected.json +0 -10
  163. package/conformance/invalid/unreachable-state.udl +0 -55
  164. package/conformance/invalid/wrong-exception-amount-field.expected.json +0 -10
  165. package/conformance/invalid/wrong-exception-amount-field.udl +0 -2487
  166. package/conformance/invalid/wrong-exception-reason-field.expected.json +0 -10
  167. package/conformance/invalid/wrong-exception-reason-field.udl +0 -2487
  168. package/conformance/valid/agent-description.expected.json +0 -6
  169. package/conformance/valid/agent-description.udl +0 -66
  170. package/conformance/valid/cards.expected.json +0 -6
  171. package/conformance/valid/cards.udl +0 -1579
  172. package/conformance/valid/commerce-escrow.expected.json +0 -6
  173. package/conformance/valid/commerce-escrow.udl +0 -1512
  174. package/conformance/valid/compiled-crowdfunding.expected.json +0 -6
  175. package/conformance/valid/compiled-crowdfunding.udl +0 -1843
  176. package/conformance/valid/compiled-watch-club.expected.json +0 -6
  177. package/conformance/valid/compiled-watch-club.udl +0 -2486
  178. package/conformance/valid/complete-contract.expected.json +0 -6
  179. package/conformance/valid/complete-contract.udl +0 -218
  180. package/conformance/valid/effect-signatures.expected.json +0 -6
  181. package/conformance/valid/effect-signatures.udl +0 -75
  182. package/conformance/valid/hand-edited.expected.json +0 -6
  183. package/conformance/valid/hand-edited.udl +0 -1
  184. package/conformance/valid/insured-car-marketplace.expected.json +0 -6
  185. package/conformance/valid/insured-car-marketplace.udl +0 -1050
  186. package/conformance/valid/insured-travel.expected.json +0 -6
  187. package/conformance/valid/insured-travel.udl +0 -3469
  188. package/conformance/valid/minimal.expected.json +0 -6
  189. package/conformance/valid/minimal.udl +0 -54
  190. package/conformance/valid/protection.expected.json +0 -6
  191. package/conformance/valid/protection.udl +0 -1551
  192. package/conformance/valid/string-escaping.expected.json +0 -6
  193. package/conformance/valid/string-escaping.udl +0 -54
  194. package/dist/check-profiles.d.ts +0 -57
  195. package/dist/check-profiles.d.ts.map +0 -1
  196. package/dist/check-profiles.js +0 -62
  197. package/dist/check-profiles.js.map +0 -1
  198. package/dist/cli.d.ts +0 -3
  199. package/dist/cli.d.ts.map +0 -1
  200. package/dist/cli.js +0 -184
  201. package/dist/cli.js.map +0 -1
  202. package/dist/effects.d.ts +0 -41
  203. package/dist/effects.d.ts.map +0 -1
  204. package/dist/effects.js +0 -110
  205. package/dist/effects.js.map +0 -1
  206. package/dist/evolution.d.ts +0 -120
  207. package/dist/evolution.d.ts.map +0 -1
  208. package/dist/evolution.js +0 -567
  209. package/dist/evolution.js.map +0 -1
  210. package/dist/parser.d.ts +0 -4
  211. package/dist/parser.d.ts.map +0 -1
  212. package/dist/parser.js +0 -44
  213. package/dist/parser.js.map +0 -1
  214. package/docs/README.md +0 -14
  215. package/docs/guide/01-a-document.md +0 -37
  216. package/docs/guide/02-money-steps.md +0 -23
  217. package/docs/guide/03-laws.md +0 -18
  218. package/docs/guide/04-fees-and-remainder.md +0 -15
  219. package/docs/guide/05-checks-updates-dials.md +0 -7
  220. package/docs/guide/06-effects.md +0 -11
  221. package/docs/guide/07-evolution.md +0 -11
  222. package/docs/guide/08-implementing.md +0 -13
  223. package/docs/llms-full.txt +0 -1241
  224. package/docs/llms.txt +0 -14
  225. package/docs/reference/canonical.md +0 -16
  226. package/docs/reference/clauses.md +0 -986
  227. package/docs/reference/cli.md +0 -22
  228. package/docs/reference/diagnostics.md +0 -32
  229. package/skills/udl/SKILL.md +0 -28
  230. package/src/check-profiles.ts +0 -80
  231. package/src/cli.ts +0 -196
  232. package/src/effects.ts +0 -163
  233. package/src/evolution.ts +0 -965
  234. package/src/parser.ts +0 -58
@@ -0,0 +1,252 @@
1
+ const sealedFields = new Map([
2
+ ["id", "text"],
3
+ ["status", "text"],
4
+ ["createdAt", "date"],
5
+ ]);
6
+ const integer = { kind: "integer" };
7
+ const boolean = { kind: "boolean" };
8
+ const date = { kind: "date" };
9
+ const same = (a, b) => a.kind === b.kind &&
10
+ (a.kind !== "money" || (b.kind === "money" && a.currency === b.currency));
11
+ function requireType(types, name) {
12
+ const value = types.get(name);
13
+ if (!value)
14
+ throw new Error(`Unknown reporting field or expression ${name}`);
15
+ return value;
16
+ }
17
+ function requireRule(condition, message) {
18
+ if (!condition)
19
+ throw new Error(message);
20
+ }
21
+ export function reportExpressionTypes(expressions, initial) {
22
+ const types = new Map(initial);
23
+ for (const expression of expressions) {
24
+ requireRule(!types.has(expression.id), `Duplicate expression ${expression.id}`);
25
+ const read = (name) => requireType(types, name);
26
+ let result;
27
+ switch (expression.op) {
28
+ case "field":
29
+ result = read(expression.path);
30
+ break;
31
+ case "parameter":
32
+ result = date;
33
+ break;
34
+ case "literal": {
35
+ result = expression.type;
36
+ const value = expression.value;
37
+ requireRule(result.kind === "money"
38
+ ? typeof value === "string" && /^(0|[1-9][0-9]{0,17})$/.test(value)
39
+ : result.kind === "integer"
40
+ ? typeof value === "number" && Number.isSafeInteger(value)
41
+ : result.kind === "boolean"
42
+ ? typeof value === "boolean"
43
+ : result.kind === "date"
44
+ ? typeof value === "string" &&
45
+ Number.isFinite(Date.parse(value))
46
+ : typeof value === "string", `Invalid literal ${expression.id}`);
47
+ break;
48
+ }
49
+ case "not":
50
+ requireRule(read(expression.value).kind === "boolean", "not requires boolean");
51
+ result = boolean;
52
+ break;
53
+ case "choose": {
54
+ requireRule(read(expression.condition).kind === "boolean", "choose requires boolean");
55
+ result = read(expression.yes);
56
+ requireRule(same(result, read(expression.no)), "choose branches must have matching types and currencies");
57
+ break;
58
+ }
59
+ case "bucket":
60
+ requireRule(read(expression.value).kind === "date", "bucket requires date");
61
+ result = { kind: "text" };
62
+ break;
63
+ case "ratio": {
64
+ const numerator = read(expression.numerator), denominator = read(expression.denominator);
65
+ requireRule(same(numerator, denominator) &&
66
+ ["money", "integer"].includes(numerator.kind), "ratio needs matching numeric measures");
67
+ result = integer;
68
+ break;
69
+ }
70
+ default: {
71
+ const left = read(expression.left), right = read(expression.right);
72
+ requireRule(same(left, right), `Incompatible types or currencies in ${expression.id}`);
73
+ if (["equal", "less", "atMost"].includes(expression.op))
74
+ result = boolean;
75
+ else if (expression.op === "and" || expression.op === "or") {
76
+ requireRule(left.kind === "boolean", "Boolean operation requires booleans");
77
+ result = boolean;
78
+ }
79
+ else if (expression.op === "daysBetween") {
80
+ requireRule(left.kind === "date", "daysBetween requires dates");
81
+ result = integer;
82
+ }
83
+ else {
84
+ requireRule(["money", "integer"].includes(left.kind), "Arithmetic requires numeric measures");
85
+ result = left;
86
+ }
87
+ }
88
+ }
89
+ types.set(expression.id, result);
90
+ }
91
+ return types;
92
+ }
93
+ function aggregateTypes(aggregates, input, target) {
94
+ for (const aggregate of aggregates) {
95
+ requireRule(!target.has(aggregate.name), `Duplicate aggregate ${aggregate.name}`);
96
+ const type = aggregate.op === "count"
97
+ ? integer
98
+ : requireType(input, aggregate.value ?? "");
99
+ requireRule(!["sum", "average"].includes(aggregate.op) ||
100
+ ["money", "integer"].includes(type.kind), "sum requires numeric values");
101
+ requireRule(aggregate.op !== "count" || aggregate.value === undefined, "count has no value field");
102
+ requireRule(aggregate.op === "average"
103
+ ? aggregate.rounding !== undefined
104
+ : aggregate.rounding === undefined, "Only average requires an explicit rounding policy");
105
+ target.set(aggregate.name, type);
106
+ }
107
+ }
108
+ /** Used by compilation and replay, never a report-name dispatch. */
109
+ export function validateReportDefinition(report, document) {
110
+ requireRule(report.scope.currency === document.currency, "Report currency differs from Product currency");
111
+ const datasets = new Map();
112
+ for (const dataset of report.datasets) {
113
+ requireRule(!datasets.has(dataset.id), `Duplicate dataset ${dataset.id}`);
114
+ const fields = new Map();
115
+ for (const column of dataset.columns) {
116
+ requireRule(!fields.has(column.name), `Duplicate column ${column.name}`);
117
+ if (column.type.kind === "money")
118
+ requireRule(column.type.currency === report.scope.currency, "Incompatible dataset currency");
119
+ if (dataset.source === "instrument") {
120
+ requireRule(report.scope.kind === "product", "Company instrument reports require cross-Build bindings");
121
+ requireRule(dataset.instruments.length > 0, "Instrument source requires declared instruments");
122
+ for (const id of dataset.instruments) {
123
+ const instrument = document.instruments.find((entry) => entry.id === id);
124
+ requireRule(instrument, `Unknown report instrument ${id}`);
125
+ const parts = column.field.split(".");
126
+ const field = instrument.fields.find((entry) => entry.name === parts[0]);
127
+ const sealed = sealedFields.get(column.field);
128
+ const actual = parts.length === 2 &&
129
+ parts[1] === "balance" &&
130
+ field?.type === "account"
131
+ ? "money"
132
+ : parts.length === 1
133
+ ? (sealed ??
134
+ (field && ["ref", "account", "enum"].includes(field.type)
135
+ ? "text"
136
+ : field?.type))
137
+ : undefined;
138
+ requireRule(actual === column.type.kind, `Unknown or mistyped report field ${id}.${column.field}`);
139
+ }
140
+ }
141
+ else {
142
+ requireRule(dataset.instruments.length === 0, "Only instrument sources bind instruments");
143
+ const sourceFields = {
144
+ account: {
145
+ id: "text",
146
+ ownerParticipantId: "text",
147
+ currency: "text",
148
+ role: "text",
149
+ status: "text",
150
+ createdAt: "date",
151
+ balance: "money",
152
+ },
153
+ identity: {
154
+ id: "text",
155
+ entityId: "text",
156
+ participantId: "text",
157
+ status: "text",
158
+ createdAt: "date",
159
+ },
160
+ operation: {
161
+ id: "text",
162
+ name: "text",
163
+ status: "text",
164
+ createdAt: "date",
165
+ },
166
+ };
167
+ requireRule(sourceFields[dataset.source]?.[column.field] === column.type.kind, `Unknown or mistyped ${dataset.source} field ${column.field}`);
168
+ }
169
+ fields.set(column.name, column.type);
170
+ }
171
+ requireRule(requireType(fields, dataset.rowKey).kind === "text", "Row key must be text");
172
+ const types = reportExpressionTypes(dataset.expressions, fields);
173
+ if (dataset.selection)
174
+ requireRule(requireType(types, dataset.selection).kind === "boolean", "Selection must be boolean");
175
+ if (dataset.selection)
176
+ validateSourceKey(dataset, dataset.selection);
177
+ datasets.set(dataset.id, types);
178
+ }
179
+ const aggregateNames = [
180
+ ...report.calculation.joins.flatMap((join) => join.aggregates),
181
+ ...report.calculation.aggregates,
182
+ ].map((aggregate) => aggregate.name);
183
+ requireRule(new Set(aggregateNames).size === aggregateNames.length, "Aggregate names must be unique across stages for null accounting");
184
+ const primary = datasets.get(report.selection.dataset);
185
+ requireRule(primary, "Unknown primary dataset");
186
+ let types = new Map(primary);
187
+ const joined = new Set();
188
+ for (const join of report.calculation.joins) {
189
+ requireRule(!joined.has(join.dataset), "Duplicate join requires a distinct dataset alias");
190
+ requireRule(join.dataset !== report.selection.dataset, "Self joins require a distinct dataset alias");
191
+ joined.add(join.dataset);
192
+ const foreign = datasets.get(join.dataset);
193
+ requireRule(foreign, `Unknown joined dataset ${join.dataset}`);
194
+ validateSourceKey(report.datasets.find((dataset) => dataset.id === join.dataset), join.foreign);
195
+ requireRule(same(requireType(types, join.local), requireType(foreign, join.foreign)), "Join keys have incompatible types");
196
+ requireRule(join.aggregates.length > 0, "Joins must declare aggregates; implicit row multiplication is forbidden");
197
+ aggregateTypes(join.aggregates, foreign, types);
198
+ }
199
+ types = reportExpressionTypes(report.calculation.expressions, types);
200
+ if (report.selection.predicate)
201
+ requireRule(requireType(types, report.selection.predicate).kind === "boolean", "Selection must be boolean");
202
+ for (const required of report.validation.required)
203
+ requireType(types, required);
204
+ for (const pair of report.validation.rowReconcile)
205
+ requireRule(same(requireType(types, pair.left), requireType(types, pair.right)), "Row reconciliation requires matching measures");
206
+ if (report.calculation.aggregates.length) {
207
+ const grouped = new Map(report.calculation.groupBy.map((key) => [key, requireType(types, key)]));
208
+ aggregateTypes(report.calculation.aggregates, types, grouped);
209
+ types = grouped;
210
+ }
211
+ else
212
+ requireRule(report.calculation.groupBy.length === 0, "Grouping requires aggregates");
213
+ types = reportExpressionTypes(report.calculation.resultExpressions, types);
214
+ for (const pair of report.validation.reconcile)
215
+ requireRule(same(requireType(types, pair.left), requireType(types, pair.right)), "Reconciliation requires matching measures");
216
+ const outputs = new Set();
217
+ for (const column of report.output.columns) {
218
+ requireRule(!outputs.has(column.name), "Duplicate output column");
219
+ outputs.add(column.name);
220
+ requireRule(same(requireType(types, column.name), column.type), `Output type differs for ${column.name}`);
221
+ }
222
+ for (const sort of report.output.sort)
223
+ requireRule(outputs.has(sort), `Sort key ${sort} must be an output column`);
224
+ }
225
+ function validateSourceKey(dataset, key, seen = new Set()) {
226
+ if (seen.has(key))
227
+ return;
228
+ seen.add(key);
229
+ const column = dataset.columns.find((entry) => entry.name === key);
230
+ if (column) {
231
+ requireRule(column.field !== "balance" && !column.field.endsWith(".balance"), "Source selection and join keys cannot depend on ledger balances");
232
+ return;
233
+ }
234
+ const expression = dataset.expressions.find((entry) => entry.id === key);
235
+ requireRule(expression, `Unknown source key ${key}`);
236
+ requireRule(expression.op !== "ratio", "Ratios belong after source selection");
237
+ const read = (name) => validateSourceKey(dataset, name, seen);
238
+ if (expression.op === "field")
239
+ read(expression.path);
240
+ else if (expression.op === "choose") {
241
+ read(expression.condition);
242
+ read(expression.yes);
243
+ read(expression.no);
244
+ }
245
+ else if (expression.op === "not" || expression.op === "bucket")
246
+ read(expression.value);
247
+ else if ("left" in expression) {
248
+ read(expression.left);
249
+ read(expression.right);
250
+ }
251
+ }
252
+ //# sourceMappingURL=reporting-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporting-validation.js","sourceRoot":"","sources":["../src/reporting-validation.ts"],"names":[],"mappings":"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"}