@hyperscale0/udl 1.0.265 → 1.0.284
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/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/SECURITY.md +15 -14
- package/dist/diagnostics.d.ts +7 -6
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/field-value.d.ts.map +1 -1
- package/dist/field-value.js +5 -6
- package/dist/field-value.js.map +1 -1
- package/dist/finance.d.ts +2 -6
- package/dist/finance.d.ts.map +1 -1
- package/dist/finance.js +20 -14
- package/dist/finance.js.map +1 -1
- package/dist/limits.d.ts +0 -1
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +0 -1
- package/dist/limits.js.map +1 -1
- package/dist/object-contract.d.ts +2 -2
- package/dist/object-contract.d.ts.map +1 -1
- package/dist/object-contract.js +4 -4
- package/dist/object-contract.js.map +1 -1
- package/dist/object-semantics-schema.d.ts +0 -10
- package/dist/object-semantics-schema.d.ts.map +1 -1
- package/dist/object-semantics.d.ts.map +1 -1
- package/dist/object-semantics.js +9 -9
- package/dist/object-semantics.js.map +1 -1
- package/dist/object-structures.d.ts.map +1 -1
- package/dist/object-structures.js +2 -3
- package/dist/object-structures.js.map +1 -1
- package/dist/primitives.d.ts +12 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +21 -0
- package/dist/primitives.js.map +1 -0
- package/dist/reporting-validation.d.ts.map +1 -1
- package/dist/reporting-validation.js +2 -1
- package/dist/reporting-validation.js.map +1 -1
- package/dist/reporting.d.ts +0 -5
- package/dist/reporting.d.ts.map +1 -1
- package/dist/reporting.js +0 -5
- package/dist/reporting.js.map +1 -1
- package/dist/schema.d.ts +1 -11
- 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.map +1 -1
- package/dist/validation.js +20 -43
- package/dist/validation.js.map +1 -1
- package/package.json +2 -2
- package/spec/README.md +24 -23
- package/spec/udl.schema.json +1 -36
- package/src/diagnostics.ts +7 -6
- package/src/field-value.ts +5 -6
- package/src/finance.ts +20 -22
- package/src/limits.ts +0 -1
- package/src/object-contract.ts +4 -10
- package/src/object-semantics.ts +14 -13
- package/src/object-structures.ts +2 -4
- package/src/primitives.ts +29 -0
- package/src/reporting-validation.ts +2 -1
- package/src/reporting.ts +0 -5
- package/src/schema.ts +2 -1
- package/src/validation.ts +22 -65
package/src/validation.ts
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
udlDocumentSchema,
|
|
3
3
|
subjectPartyRoles,
|
|
4
4
|
sameObjectField,
|
|
5
|
-
MAX_ACTION_EXPANSION,
|
|
6
5
|
type UdlDocument,
|
|
6
|
+
type UdlFamily,
|
|
7
7
|
type UdlField,
|
|
8
8
|
type UdlInstrument,
|
|
9
9
|
type UdlValue,
|
|
@@ -20,6 +20,7 @@ import { validateReportDefinition } from "./reporting-validation.js";
|
|
|
20
20
|
import { analyzeInstrumentFinance } from "./finance.js";
|
|
21
21
|
import { UDL_LIMITS } from "./limits.js";
|
|
22
22
|
import { udlFieldValueSchema } from "./field-value.js";
|
|
23
|
+
import { isMinorUnits, own, targetIds } from "./primitives.js";
|
|
23
24
|
|
|
24
25
|
export const RESERVED_OBJECT_NAMES = [
|
|
25
26
|
"objectId",
|
|
@@ -136,17 +137,13 @@ function bounded(value: unknown): boolean {
|
|
|
136
137
|
}
|
|
137
138
|
}
|
|
138
139
|
|
|
139
|
-
function own<T>(
|
|
140
|
-
record: Record<string, T> | undefined,
|
|
141
|
-
key: string,
|
|
142
|
-
): T | undefined {
|
|
143
|
-
return record && Object.hasOwn(record, key) ? record[key] : undefined;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const targetIds = (target: string | string[]): string[] =>
|
|
147
|
-
typeof target === "string" ? [target] : target;
|
|
148
140
|
const overlap = (a: string | string[], b: string | string[]) =>
|
|
149
141
|
targetIds(a).some((id) => targetIds(b).includes(id));
|
|
142
|
+
const sameFamily = (actual: UdlFamily | undefined, expected: UdlFamily) =>
|
|
143
|
+
actual !== undefined &&
|
|
144
|
+
actual.module === expected.module &&
|
|
145
|
+
actual.exportPath === expected.exportPath &&
|
|
146
|
+
actual.revision === expected.revision;
|
|
150
147
|
|
|
151
148
|
/** Union paths retain only fields with compatible types on every member. */
|
|
152
149
|
function commonField(
|
|
@@ -615,10 +612,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
615
612
|
const targetInst = byId.get(id);
|
|
616
613
|
if (
|
|
617
614
|
targetInst &&
|
|
618
|
-
(
|
|
619
|
-
targetInst.family.module !== f.targetFamily.module ||
|
|
620
|
-
targetInst.family.exportPath !== f.targetFamily.exportPath ||
|
|
621
|
-
targetInst.family.revision !== f.targetFamily.revision)
|
|
615
|
+
!sameFamily(targetInst.family, f.targetFamily)
|
|
622
616
|
) {
|
|
623
617
|
add(
|
|
624
618
|
where,
|
|
@@ -659,13 +653,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
659
653
|
);
|
|
660
654
|
} else if (f.target) {
|
|
661
655
|
const targetInst = byId.get(f.target);
|
|
662
|
-
if (
|
|
663
|
-
targetInst &&
|
|
664
|
-
(!targetInst.family ||
|
|
665
|
-
targetInst.family.module !== f.targetFamily.module ||
|
|
666
|
-
targetInst.family.exportPath !== f.targetFamily.exportPath ||
|
|
667
|
-
targetInst.family.revision !== f.targetFamily.revision)
|
|
668
|
-
) {
|
|
656
|
+
if (targetInst && !sameFamily(targetInst.family, f.targetFamily)) {
|
|
669
657
|
add(
|
|
670
658
|
where,
|
|
671
659
|
`targetFamily does not match target instrument ${f.target} family`,
|
|
@@ -775,7 +763,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
775
763
|
}
|
|
776
764
|
}
|
|
777
765
|
|
|
778
|
-
const calls = new Map<string,
|
|
766
|
+
const calls = new Map<string, string[]>();
|
|
779
767
|
for (const [index, inst] of document.instruments.entries()) {
|
|
780
768
|
const base = `$.instruments[${index}]`;
|
|
781
769
|
if (inst.subject && !byObjectId.has(inst.subject))
|
|
@@ -831,8 +819,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
831
819
|
}
|
|
832
820
|
const valid =
|
|
833
821
|
type === "money"
|
|
834
|
-
? typeof v.literal === "string" &&
|
|
835
|
-
/^(0|[1-9][0-9]{0,17})$/.test(v.literal)
|
|
822
|
+
? typeof v.literal === "string" && isMinorUnits(v.literal)
|
|
836
823
|
: type === "integer" || type === "percent" || type === "duration"
|
|
837
824
|
? typeof v.literal === "number" &&
|
|
838
825
|
Number.isSafeInteger(v.literal) &&
|
|
@@ -885,10 +872,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
885
872
|
where: string,
|
|
886
873
|
input: readonly UdlField[] = [],
|
|
887
874
|
) => {
|
|
888
|
-
const ids =
|
|
889
|
-
typeof selection.instrument === "string"
|
|
890
|
-
? [selection.instrument]
|
|
891
|
-
: selection.instrument;
|
|
875
|
+
const ids = targetIds(selection.instrument);
|
|
892
876
|
duplicate(ids, where);
|
|
893
877
|
const targets = ids.flatMap((id) => {
|
|
894
878
|
const target = byId.get(id);
|
|
@@ -905,13 +889,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
905
889
|
overlap(a.target, b.target)));
|
|
906
890
|
const anchor = field(selection.anchor, input);
|
|
907
891
|
for (const target of targets) {
|
|
908
|
-
if (
|
|
909
|
-
selection.family &&
|
|
910
|
-
(!target.family ||
|
|
911
|
-
target.family.module !== selection.family.module ||
|
|
912
|
-
target.family.exportPath !== selection.family.exportPath ||
|
|
913
|
-
target.family.revision !== selection.family.revision)
|
|
914
|
-
)
|
|
892
|
+
if (selection.family && !sameFamily(target.family, selection.family))
|
|
915
893
|
add(
|
|
916
894
|
where,
|
|
917
895
|
`selection family does not match target instrument ${target.id} family`,
|
|
@@ -1077,7 +1055,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
1077
1055
|
"literal" in operand &&
|
|
1078
1056
|
(typeof operand.literal === "number" ||
|
|
1079
1057
|
(typeof operand.literal === "string" &&
|
|
1080
|
-
|
|
1058
|
+
isMinorUnits(operand.literal))) &&
|
|
1081
1059
|
(positive
|
|
1082
1060
|
? BigInt(operand.literal) <= 0n
|
|
1083
1061
|
: BigInt(operand.literal) < 0n)
|
|
@@ -1651,7 +1629,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
1651
1629
|
}
|
|
1652
1630
|
}
|
|
1653
1631
|
};
|
|
1654
|
-
const targets:
|
|
1632
|
+
const targets: string[] = [];
|
|
1655
1633
|
for (const call of action.invoke ?? []) {
|
|
1656
1634
|
if (call.guard)
|
|
1657
1635
|
checkRequirements([call.guard], where, action.input, action);
|
|
@@ -1725,11 +1703,7 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
1725
1703
|
}
|
|
1726
1704
|
}
|
|
1727
1705
|
}
|
|
1728
|
-
targets.push({
|
|
1729
|
-
targets: ids.map((id) => `${id}.${call.action}`),
|
|
1730
|
-
count:
|
|
1731
|
-
"selection" in call ? call.selection.limit : (range?.maximum ?? 1),
|
|
1732
|
-
});
|
|
1706
|
+
targets.push(...ids.map((id) => `${id}.${call.action}`));
|
|
1733
1707
|
}
|
|
1734
1708
|
calls.set(`${inst.id}.${actionName}`, targets);
|
|
1735
1709
|
}
|
|
@@ -1742,34 +1716,17 @@ export function validateUdl(value: unknown): UdlValidationResult {
|
|
|
1742
1716
|
);
|
|
1743
1717
|
}
|
|
1744
1718
|
const active = new Set<string>();
|
|
1745
|
-
const
|
|
1746
|
-
const visit = (key: string):
|
|
1719
|
+
const visited = new Set<string>();
|
|
1720
|
+
const visit = (key: string): void => {
|
|
1747
1721
|
if (active.has(key)) {
|
|
1748
1722
|
add("$.instruments", `invocation cycle at ${key}`, "UDL2010");
|
|
1749
|
-
return
|
|
1723
|
+
return;
|
|
1750
1724
|
}
|
|
1751
|
-
|
|
1752
|
-
if (known !== undefined) return known;
|
|
1725
|
+
if (visited.has(key)) return;
|
|
1753
1726
|
active.add(key);
|
|
1754
|
-
const
|
|
1755
|
-
1 +
|
|
1756
|
-
(calls.get(key) ?? []).reduce(
|
|
1757
|
-
(n, edge) => n + edge.count * Math.max(0, ...edge.targets.map(visit)),
|
|
1758
|
-
0,
|
|
1759
|
-
);
|
|
1727
|
+
for (const target of calls.get(key) ?? []) visit(target);
|
|
1760
1728
|
active.delete(key);
|
|
1761
|
-
|
|
1762
|
-
const [id, action] = key.split(".");
|
|
1763
|
-
const limit =
|
|
1764
|
-
document.instruments.find((item) => item.id === id)?.actions[action!]
|
|
1765
|
-
?.expansionLimit ?? MAX_ACTION_EXPANSION;
|
|
1766
|
-
if (size > limit)
|
|
1767
|
-
add(
|
|
1768
|
-
"$.instruments",
|
|
1769
|
-
`invocation ${key} exceeds ${limit} actions`,
|
|
1770
|
-
"UDL2010",
|
|
1771
|
-
);
|
|
1772
|
-
return size;
|
|
1729
|
+
visited.add(key);
|
|
1773
1730
|
};
|
|
1774
1731
|
for (const key of calls.keys()) visit(key);
|
|
1775
1732
|
return issues.length ? { ok: false, issues } : { ok: true, value: document };
|