@hyperscale0/udl 1.0.251 → 1.0.258
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.
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/money.d.ts +5 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +5 -0
- package/dist/money.js.map +1 -0
- package/dist/object-semantics-schema.d.ts +12 -12
- package/dist/reporting.d.ts +8 -8
- package/dist/reporting.d.ts.map +1 -1
- package/dist/reporting.js +3 -2
- package/dist/reporting.js.map +1 -1
- package/dist/schema.d.ts +12 -12
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2 -1
- package/dist/schema.js.map +1 -1
- package/dist/validation.d.ts +2 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +32 -22
- package/dist/validation.js.map +1 -1
- package/package.json +2 -2
- package/spec/udl.schema.json +301 -300
- package/src/index.ts +2 -0
- package/src/money.ts +5 -0
- package/src/reporting.ts +3 -2
- package/src/schema.ts +2 -1
- package/src/validation.ts +58 -28
package/src/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export * from "./schema.js";
|
|
2
|
+
export { sarCurrency, sarMinorUnitExponent, currencySchema } from "./money.js";
|
|
2
3
|
export { serializeUdl, canonicalDigest } from "./canonical.js";
|
|
3
4
|
export {
|
|
4
5
|
validateUdl,
|
|
5
6
|
RESERVED_OBJECT_NAMES,
|
|
6
7
|
assertValidUdl,
|
|
7
8
|
resolveField,
|
|
9
|
+
sameAccount,
|
|
8
10
|
resolveSubjectRequirement,
|
|
9
11
|
UdlError,
|
|
10
12
|
type UdlValidationResult,
|
package/src/money.ts
ADDED
package/src/reporting.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
import { currencySchema } from "./money.js";
|
|
2
3
|
|
|
3
4
|
const name = z
|
|
4
5
|
.string()
|
|
@@ -12,7 +13,7 @@ const integer = z.number().int().safe();
|
|
|
12
13
|
export const reportTypeSchema = z.discriminatedUnion("kind", [
|
|
13
14
|
z.strictObject({
|
|
14
15
|
kind: z.literal("money"),
|
|
15
|
-
currency:
|
|
16
|
+
currency: currencySchema,
|
|
16
17
|
}),
|
|
17
18
|
z.strictObject({ kind: z.enum(["text", "integer", "boolean", "date"]) }),
|
|
18
19
|
]);
|
|
@@ -94,7 +95,7 @@ export const reportDefinitionSchema = z.strictObject({
|
|
|
94
95
|
scope: z.strictObject({
|
|
95
96
|
kind: z.enum(["product", "company"]),
|
|
96
97
|
classification: z.enum(["internal", "personal", "restricted"]),
|
|
97
|
-
currency:
|
|
98
|
+
currency: currencySchema,
|
|
98
99
|
}),
|
|
99
100
|
datasets: z
|
|
100
101
|
.array(
|
package/src/schema.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
import { currencySchema } from "./money.js";
|
|
2
3
|
import { reportDefinitionSchema } from "./reporting.js";
|
|
3
4
|
import { writeJson } from "./json.js";
|
|
4
5
|
|
|
@@ -553,7 +554,7 @@ export const udlDocumentSchema = z.strictObject({
|
|
|
553
554
|
version: integer.positive(),
|
|
554
555
|
product: name,
|
|
555
556
|
title: text,
|
|
556
|
-
currency:
|
|
557
|
+
currency: currencySchema,
|
|
557
558
|
parties: z.record(name, udlPartySchema),
|
|
558
559
|
objects: z.array(udlObjectKindSchema).max(256),
|
|
559
560
|
instruments: z.array(udlInstrumentSchema).max(256),
|
package/src/validation.ts
CHANGED
|
@@ -234,6 +234,47 @@ export function resolveField(
|
|
|
234
234
|
return resolvePath(document, instrument, path, input, new Map(), action);
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
/** The account identity used by the distinct-account transfer rule. */
|
|
238
|
+
export function sameAccount(
|
|
239
|
+
document: UdlDocument,
|
|
240
|
+
instrument: UdlInstrument,
|
|
241
|
+
fromPath: string,
|
|
242
|
+
toPath: string,
|
|
243
|
+
input: readonly UdlField[] = [],
|
|
244
|
+
action?: UdlAction,
|
|
245
|
+
): boolean {
|
|
246
|
+
const from = resolveField(document, instrument, fromPath, input, action);
|
|
247
|
+
const to = resolveField(document, instrument, toPath, input, action);
|
|
248
|
+
const accountOwner = (
|
|
249
|
+
field: Extract<UdlField, { type: "account" }>,
|
|
250
|
+
path: string,
|
|
251
|
+
): string => {
|
|
252
|
+
if (typeof field.owner === "string") return `party:${field.owner}`;
|
|
253
|
+
const binding = field.owner.adapter;
|
|
254
|
+
const provider =
|
|
255
|
+
path === `self.${field.name}`
|
|
256
|
+
? Object.values(instrument.actions)
|
|
257
|
+
.flatMap((action) => action.subject?.adapters ?? [])
|
|
258
|
+
.find((entry) => entry.binding === binding && entry.snapshot)
|
|
259
|
+
?.snapshot?.provider
|
|
260
|
+
: undefined;
|
|
261
|
+
return provider ? `provider:${provider}` : `binding:${binding}`;
|
|
262
|
+
};
|
|
263
|
+
return (
|
|
264
|
+
fromPath === toPath ||
|
|
265
|
+
!!(
|
|
266
|
+
from?.type === "account" &&
|
|
267
|
+
to?.type === "account" &&
|
|
268
|
+
(from.owner !== "self" ||
|
|
269
|
+
(fromPath === `self.${from.name}` && toPath === `self.${to.name}`)) &&
|
|
270
|
+
accountOwner(from, fromPath) === accountOwner(to, toPath) &&
|
|
271
|
+
from.book === to.book &&
|
|
272
|
+
(from.key ?? (from.owner === "self" ? from.name : "balance")) ===
|
|
273
|
+
(to.key ?? (to.owner === "self" ? to.name : "balance"))
|
|
274
|
+
)
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
237
278
|
/** A subject expression names a requirement; objectField names its stored metadata. */
|
|
238
279
|
export function resolveSubjectRequirement(
|
|
239
280
|
instrument: UdlInstrument,
|
|
@@ -1101,7 +1142,13 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
1101
1142
|
dependencies.set(
|
|
1102
1143
|
c.target,
|
|
1103
1144
|
operands.flatMap((v) =>
|
|
1104
|
-
"field" in v &&
|
|
1145
|
+
"field" in v &&
|
|
1146
|
+
v.field.startsWith("self.") &&
|
|
1147
|
+
!(
|
|
1148
|
+
act &&
|
|
1149
|
+
v.field === `self.${c.target}` &&
|
|
1150
|
+
!inst.calculate.some((node) => node.target === c.target)
|
|
1151
|
+
)
|
|
1105
1152
|
? [v.field.slice(5)]
|
|
1106
1153
|
: [],
|
|
1107
1154
|
),
|
|
@@ -1526,33 +1573,16 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
1526
1573
|
from.book !== to.book
|
|
1527
1574
|
)
|
|
1528
1575
|
add(where, "moves cannot cross account books", "UDL4001");
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
.find(
|
|
1540
|
-
(entry) => entry.binding === binding && entry.snapshot,
|
|
1541
|
-
)?.snapshot?.provider
|
|
1542
|
-
: undefined;
|
|
1543
|
-
return provider ? `provider:${provider}` : `binding:${binding}`;
|
|
1544
|
-
};
|
|
1545
|
-
const sameBoundAccount =
|
|
1546
|
-
from?.type === "account" &&
|
|
1547
|
-
to?.type === "account" &&
|
|
1548
|
-
(from.owner !== "self" ||
|
|
1549
|
-
(move.from === `self.${from.name}` &&
|
|
1550
|
-
move.to === `self.${to.name}`)) &&
|
|
1551
|
-
accountOwner(from, move.from) === accountOwner(to, move.to) &&
|
|
1552
|
-
from.book === to.book &&
|
|
1553
|
-
(from.key ?? (from.owner === "self" ? from.name : "balance")) ===
|
|
1554
|
-
(to.key ?? (to.owner === "self" ? to.name : "balance"));
|
|
1555
|
-
if (move.from === move.to || sameBoundAccount)
|
|
1576
|
+
if (
|
|
1577
|
+
sameAccount(
|
|
1578
|
+
document,
|
|
1579
|
+
inst,
|
|
1580
|
+
move.from,
|
|
1581
|
+
move.to,
|
|
1582
|
+
action.input,
|
|
1583
|
+
action,
|
|
1584
|
+
)
|
|
1585
|
+
)
|
|
1556
1586
|
add(where, "a transfer needs distinct accounts", "UDL4001");
|
|
1557
1587
|
} else expect(move.transfer, "text", where, action.input, action);
|
|
1558
1588
|
}
|