@hyperscale0/udl 3.2.0 → 4.0.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.
- package/CHANGELOG.md +4 -0
- package/README.md +1 -1
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +13 -1
- package/dist/diagnostics.js.map +1 -1
- package/dist/evolution.d.ts.map +1 -1
- package/dist/evolution.js +5 -0
- package/dist/evolution.js.map +1 -1
- 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/instrument-references.d.ts.map +1 -1
- package/dist/instrument-references.js +21 -1
- package/dist/instrument-references.js.map +1 -1
- package/dist/object-contract.d.ts +157 -0
- package/dist/object-contract.d.ts.map +1 -0
- package/dist/object-contract.js +306 -0
- package/dist/object-contract.js.map +1 -0
- package/dist/schema.d.ts +1835 -27
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +103 -15
- package/dist/schema.js.map +1 -1
- package/dist/validation.d.ts +5 -2
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +427 -133
- package/dist/validation.js.map +1 -1
- package/docs/README.md +61 -9
- package/package.json +4 -4
- package/spec/README.md +61 -9
- package/spec/{darb.udl.json → cars.udl.json} +7 -7
- package/spec/udl.schema.json +2960 -6505
- package/src/diagnostics.ts +33 -1
- package/src/evolution.ts +8 -0
- package/src/index.ts +3 -0
- package/src/instrument-references.ts +25 -1
- package/src/object-contract.ts +498 -0
- package/src/schema.ts +158 -15
- package/src/validation.ts +689 -150
package/src/schema.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { reportDefinitionSchema } from "./reporting.js";
|
|
3
3
|
|
|
4
|
-
export const UDL_FORMAT_VERSION =
|
|
4
|
+
export const UDL_FORMAT_VERSION = 4 as const;
|
|
5
5
|
/** Counts the root and every nested invocation, including selected and ranged children. */
|
|
6
6
|
export const MAX_ACTION_EXPANSION = 4096;
|
|
7
7
|
const name = z
|
|
@@ -17,6 +17,13 @@ const path = z
|
|
|
17
17
|
.regex(/^[a-z][a-zA-Z0-9_]*(?:\.[a-z][a-zA-Z0-9_]*)*$/)
|
|
18
18
|
.max(240);
|
|
19
19
|
const instrumentId = name.meta({ "x-udl-reference": "instrument" });
|
|
20
|
+
const objectKindId = name.meta({ "x-udl-reference": "object" });
|
|
21
|
+
|
|
22
|
+
export const udlPartyNameSchema = name;
|
|
23
|
+
|
|
24
|
+
export const udlObjectIdSchema = z.string().min(1).max(160);
|
|
25
|
+
export const udlExternalIdSchema = z.string().min(1).max(2048);
|
|
26
|
+
export const udlObjectRevisionSchema = integer.positive();
|
|
20
27
|
|
|
21
28
|
/** Currency belongs to the document. Accounts and amounts cannot override it. */
|
|
22
29
|
export const udlPartySchema = z.strictObject({
|
|
@@ -24,11 +31,37 @@ export const udlPartySchema = z.strictObject({
|
|
|
24
31
|
role: name.optional(),
|
|
25
32
|
});
|
|
26
33
|
|
|
34
|
+
export const udlFamilySchema = z.strictObject({
|
|
35
|
+
module: name,
|
|
36
|
+
exportPath: path,
|
|
37
|
+
revision: integer.positive(),
|
|
38
|
+
});
|
|
39
|
+
|
|
27
40
|
const fieldBase = {
|
|
28
41
|
name,
|
|
29
42
|
optional: z.literal(true).optional(),
|
|
30
43
|
description: text.optional(),
|
|
44
|
+
sensitive: z.literal(true).optional(),
|
|
31
45
|
};
|
|
46
|
+
|
|
47
|
+
const referenceField = z.strictObject({
|
|
48
|
+
...fieldBase,
|
|
49
|
+
type: z.literal("ref"),
|
|
50
|
+
targetKind: z.enum(["instrument", "object"]),
|
|
51
|
+
targetFamily: udlFamilySchema.optional(),
|
|
52
|
+
target: z.union([name, z.array(name).min(1).max(16)]),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const listField = z.strictObject({
|
|
56
|
+
...fieldBase,
|
|
57
|
+
type: z.literal("list"),
|
|
58
|
+
item: z.enum(["money", "date", "text", "integer", "ref"]),
|
|
59
|
+
targetKind: z.enum(["instrument", "object"]).optional(),
|
|
60
|
+
targetFamily: udlFamilySchema.optional(),
|
|
61
|
+
target: name.optional(),
|
|
62
|
+
maxItems: integer.min(1).max(366),
|
|
63
|
+
});
|
|
64
|
+
|
|
32
65
|
export const udlFieldSchema = z.discriminatedUnion("type", [
|
|
33
66
|
z.strictObject({
|
|
34
67
|
...fieldBase,
|
|
@@ -44,13 +77,8 @@ export const udlFieldSchema = z.discriminatedUnion("type", [
|
|
|
44
77
|
key: name.optional(),
|
|
45
78
|
book: z.enum(["cash", "claim"]).default("cash"),
|
|
46
79
|
contra: z.literal(true).optional(),
|
|
47
|
-
external: z.literal(true).optional(),
|
|
48
|
-
}),
|
|
49
|
-
z.strictObject({
|
|
50
|
-
...fieldBase,
|
|
51
|
-
type: z.literal("ref"),
|
|
52
|
-
target: z.union([instrumentId, z.array(instrumentId).min(1).max(16)]),
|
|
53
80
|
}),
|
|
81
|
+
referenceField,
|
|
54
82
|
z.strictObject({
|
|
55
83
|
...fieldBase,
|
|
56
84
|
type: z.literal("date"),
|
|
@@ -96,15 +124,89 @@ export const udlFieldSchema = z.discriminatedUnion("type", [
|
|
|
96
124
|
values: z.array(name).min(1).max(64),
|
|
97
125
|
value: name.optional(),
|
|
98
126
|
}),
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
127
|
+
listField,
|
|
128
|
+
]);
|
|
129
|
+
|
|
130
|
+
const [
|
|
131
|
+
moneyField,
|
|
132
|
+
,
|
|
133
|
+
refField,
|
|
134
|
+
dateField,
|
|
135
|
+
durationField,
|
|
136
|
+
textField,
|
|
137
|
+
integerField,
|
|
138
|
+
percentField,
|
|
139
|
+
booleanField,
|
|
140
|
+
enumField,
|
|
141
|
+
boundedListField,
|
|
142
|
+
] = udlFieldSchema.options;
|
|
143
|
+
|
|
144
|
+
export const udlObjectFieldSchema = z.discriminatedUnion("type", [
|
|
145
|
+
moneyField,
|
|
146
|
+
refField,
|
|
147
|
+
dateField,
|
|
148
|
+
durationField,
|
|
149
|
+
textField,
|
|
150
|
+
integerField,
|
|
151
|
+
percentField,
|
|
152
|
+
booleanField,
|
|
153
|
+
enumField,
|
|
154
|
+
boundedListField,
|
|
106
155
|
]);
|
|
107
156
|
|
|
157
|
+
export const udlSubjectRequirementSchema = z.strictObject({
|
|
158
|
+
field: udlObjectFieldSchema,
|
|
159
|
+
// Present only for an authored rename.
|
|
160
|
+
objectField: name.optional(),
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
export const adapterSubjectSnapshotSchema = z.strictObject({
|
|
164
|
+
provider: text,
|
|
165
|
+
capability: text,
|
|
166
|
+
operation: text,
|
|
167
|
+
declarationDigest: z.string().regex(/^[a-f0-9]{64}$/),
|
|
168
|
+
requirements: z.array(udlObjectFieldSchema).max(128),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
export const udlActionSubjectSchema = z.strictObject({
|
|
172
|
+
requirements: z.array(udlSubjectRequirementSchema).max(128),
|
|
173
|
+
adapters: z
|
|
174
|
+
.array(
|
|
175
|
+
z.strictObject({
|
|
176
|
+
binding: name,
|
|
177
|
+
// null means unavailable, never "no requirements".
|
|
178
|
+
snapshot: adapterSubjectSnapshotSchema.nullable(),
|
|
179
|
+
renames: z.record(name, name).optional(),
|
|
180
|
+
}),
|
|
181
|
+
)
|
|
182
|
+
.max(16),
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export const subjectPartyRoles = ["owner", "actor", "operator"] as const;
|
|
186
|
+
export const attachmentPartyBindingSchema = z.union([
|
|
187
|
+
z.strictObject({ role: z.enum(subjectPartyRoles) }),
|
|
188
|
+
z.strictObject({ party: name }),
|
|
189
|
+
]);
|
|
190
|
+
export type AttachmentPartyBinding = z.infer<
|
|
191
|
+
typeof attachmentPartyBindingSchema
|
|
192
|
+
>;
|
|
193
|
+
export const udlObjectAttachmentSchema = z.strictObject({
|
|
194
|
+
name,
|
|
195
|
+
instrument: instrumentId,
|
|
196
|
+
parties: z.record(name, attachmentPartyBindingSchema),
|
|
197
|
+
});
|
|
198
|
+
export type SubjectPartyRole = (typeof subjectPartyRoles)[number];
|
|
199
|
+
export type UdlObjectAttachment = z.infer<typeof udlObjectAttachmentSchema>;
|
|
200
|
+
|
|
201
|
+
export const udlObjectKindSchema = z.strictObject({
|
|
202
|
+
id: objectKindId,
|
|
203
|
+
title: text,
|
|
204
|
+
authoredFields: z.array(name).max(256),
|
|
205
|
+
attachments: z.array(udlObjectAttachmentSchema).max(256),
|
|
206
|
+
fields: z.array(udlObjectFieldSchema).max(256),
|
|
207
|
+
columns: z.array(name).max(8),
|
|
208
|
+
});
|
|
209
|
+
|
|
108
210
|
/** Values are constants or resolved typed paths, never executable strings. */
|
|
109
211
|
export const udlValueSchema = z.union([
|
|
110
212
|
z.strictObject({ literal: scalar }),
|
|
@@ -114,6 +216,7 @@ const value = udlValueSchema;
|
|
|
114
216
|
const values = z.array(value).min(1).max(256);
|
|
115
217
|
|
|
116
218
|
const selection = z.strictObject({
|
|
219
|
+
family: udlFamilySchema.optional(),
|
|
117
220
|
instrument: z.union([instrumentId, z.array(instrumentId).min(1).max(16)]),
|
|
118
221
|
reference: name,
|
|
119
222
|
anchor: path,
|
|
@@ -231,9 +334,12 @@ export const udlRequirementSchema = z.discriminatedUnion("kind", [
|
|
|
231
334
|
party: name,
|
|
232
335
|
action: name.optional(),
|
|
233
336
|
decision: z.enum(["approved", "declined"]),
|
|
337
|
+
differentFromInitiator: z.literal(true).optional(),
|
|
338
|
+
protectedRequest: path.default("self"),
|
|
234
339
|
}),
|
|
235
340
|
z.strictObject({
|
|
236
341
|
kind: z.literal("evidence"),
|
|
342
|
+
instruction: path.optional(),
|
|
237
343
|
subject: path,
|
|
238
344
|
family: name,
|
|
239
345
|
check: name,
|
|
@@ -260,6 +366,7 @@ export const udlMoveSchema = z.discriminatedUnion("operation", [
|
|
|
260
366
|
z.strictObject({
|
|
261
367
|
key: name,
|
|
262
368
|
operation: z.literal("internal_transfer.reserve"),
|
|
369
|
+
boundary: z.strictObject({ adapter: name }).optional(),
|
|
263
370
|
amount: value,
|
|
264
371
|
from: path,
|
|
265
372
|
to: path,
|
|
@@ -319,6 +426,7 @@ export const udlActionSchema = z.strictObject({
|
|
|
319
426
|
parent: z.union([instrumentId, z.array(instrumentId).min(1).max(16)]),
|
|
320
427
|
}),
|
|
321
428
|
]),
|
|
429
|
+
subject: udlActionSubjectSchema.optional(),
|
|
322
430
|
input: z.array(udlFieldSchema).max(128),
|
|
323
431
|
requires: z.array(udlRequirementSchema).max(128),
|
|
324
432
|
due: clock.optional(),
|
|
@@ -360,6 +468,7 @@ export const udlActionSchema = z.strictObject({
|
|
|
360
468
|
.optional(),
|
|
361
469
|
approval: z
|
|
362
470
|
.strictObject({
|
|
471
|
+
protectedRequest: path.default("self"),
|
|
363
472
|
target: path,
|
|
364
473
|
action: name,
|
|
365
474
|
party: name,
|
|
@@ -380,7 +489,9 @@ export const udlLifecycleSchema = z.strictObject({
|
|
|
380
489
|
export const udlInstrumentSchema = z.strictObject({
|
|
381
490
|
reports: z.array(reportDefinitionSchema).max(16).optional(),
|
|
382
491
|
revisioned: z.literal(true).optional(),
|
|
492
|
+
family: udlFamilySchema.optional(),
|
|
383
493
|
id: instrumentId,
|
|
494
|
+
subject: objectKindId.optional(),
|
|
384
495
|
title: text,
|
|
385
496
|
summary: text,
|
|
386
497
|
fields: z.array(udlFieldSchema).max(256),
|
|
@@ -401,9 +512,11 @@ export const udlDocumentSchema = z.strictObject({
|
|
|
401
512
|
title: text,
|
|
402
513
|
currency: z.literal("SAR"),
|
|
403
514
|
parties: z.record(name, udlPartySchema),
|
|
404
|
-
|
|
515
|
+
objects: z.array(udlObjectKindSchema).max(256),
|
|
516
|
+
instruments: z.array(udlInstrumentSchema).max(256),
|
|
405
517
|
});
|
|
406
518
|
|
|
519
|
+
export type UdlFamily = z.infer<typeof udlFamilySchema>;
|
|
407
520
|
export type UdlDocument = z.infer<typeof udlDocumentSchema>;
|
|
408
521
|
export type UdlInstrument = z.infer<typeof udlInstrumentSchema>;
|
|
409
522
|
export type UdlField = z.infer<typeof udlFieldSchema>;
|
|
@@ -417,3 +530,33 @@ export type UdlLifecycle = z.infer<typeof udlLifecycleSchema>;
|
|
|
417
530
|
export type UdlKernelOperation = z.infer<typeof udlKernelOperationSchema>;
|
|
418
531
|
|
|
419
532
|
export type UdlSelection = z.infer<typeof selection>;
|
|
533
|
+
|
|
534
|
+
export type UdlObjectField = z.infer<typeof udlObjectFieldSchema>;
|
|
535
|
+
export type UdlObjectKind = z.infer<typeof udlObjectKindSchema>;
|
|
536
|
+
export type UdlActionSubject = z.infer<typeof udlActionSubjectSchema>;
|
|
537
|
+
export type UdlSubjectRequirement = z.infer<typeof udlSubjectRequirementSchema>;
|
|
538
|
+
export type UdlAdapterSubjectSnapshot = z.infer<
|
|
539
|
+
typeof adapterSubjectSnapshotSchema
|
|
540
|
+
>;
|
|
541
|
+
|
|
542
|
+
/** Names and display text may differ; executable constraints must match. */
|
|
543
|
+
export function sameObjectField(
|
|
544
|
+
left: UdlObjectField,
|
|
545
|
+
right: UdlObjectField,
|
|
546
|
+
): boolean {
|
|
547
|
+
const signature = (field: UdlObjectField) =>
|
|
548
|
+
JSON.stringify(
|
|
549
|
+
Object.fromEntries(
|
|
550
|
+
Object.entries(field)
|
|
551
|
+
.filter(
|
|
552
|
+
([key, value]) =>
|
|
553
|
+
!["name", "description", "optional"].includes(key) &&
|
|
554
|
+
value !== undefined,
|
|
555
|
+
)
|
|
556
|
+
.sort(([left], [right]) =>
|
|
557
|
+
left < right ? -1 : left > right ? 1 : 0,
|
|
558
|
+
),
|
|
559
|
+
),
|
|
560
|
+
);
|
|
561
|
+
return signature(left) === signature(right);
|
|
562
|
+
}
|