@hyperscale0/udl 3.2.0 → 4.1.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 +8 -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 +11 -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 +144 -0
- package/dist/object-contract.d.ts.map +1 -0
- package/dist/object-contract.js +279 -0
- package/dist/object-contract.js.map +1 -0
- package/dist/reporting.d.ts +0 -1
- package/dist/reporting.d.ts.map +1 -1
- package/dist/reporting.js +0 -1
- package/dist/reporting.js.map +1 -1
- package/dist/schema.d.ts +1815 -126
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +100 -33
- 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 +403 -146
- package/dist/validation.js.map +1 -1
- package/docs/README.md +66 -17
- package/package.json +4 -4
- package/spec/README.md +66 -17
- package/spec/{darb.udl.json → cars.udl.json} +7 -7
- package/spec/udl.schema.json +2876 -6516
- package/src/diagnostics.ts +27 -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 +464 -0
- package/src/reporting.ts +0 -1
- package/src/schema.ts +155 -33
- package/src/validation.ts +635 -174
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,14 +124,88 @@ 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,
|
|
155
|
+
]);
|
|
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 }),
|
|
106
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
|
+
});
|
|
107
209
|
|
|
108
210
|
/** Values are constants or resolved typed paths, never executable strings. */
|
|
109
211
|
export const udlValueSchema = z.union([
|
|
@@ -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,
|
|
@@ -225,15 +328,9 @@ export const udlRequirementSchema = z.discriminatedUnion("kind", [
|
|
|
225
328
|
operator: z.enum(["==", "<=", ">=", "<", ">"]),
|
|
226
329
|
value,
|
|
227
330
|
}),
|
|
228
|
-
z.strictObject({
|
|
229
|
-
kind: z.literal("approval"),
|
|
230
|
-
target: path.default("self"),
|
|
231
|
-
party: name,
|
|
232
|
-
action: name.optional(),
|
|
233
|
-
decision: z.enum(["approved", "declined"]),
|
|
234
|
-
}),
|
|
235
331
|
z.strictObject({
|
|
236
332
|
kind: z.literal("evidence"),
|
|
333
|
+
instruction: path.optional(),
|
|
237
334
|
subject: path,
|
|
238
335
|
family: name,
|
|
239
336
|
check: name,
|
|
@@ -260,6 +357,7 @@ export const udlMoveSchema = z.discriminatedUnion("operation", [
|
|
|
260
357
|
z.strictObject({
|
|
261
358
|
key: name,
|
|
262
359
|
operation: z.literal("internal_transfer.reserve"),
|
|
360
|
+
boundary: z.strictObject({ adapter: name }).optional(),
|
|
263
361
|
amount: value,
|
|
264
362
|
from: path,
|
|
265
363
|
to: path,
|
|
@@ -294,7 +392,6 @@ export const udlActionSchema = z.strictObject({
|
|
|
294
392
|
summary: text,
|
|
295
393
|
publicAction: name.optional(),
|
|
296
394
|
expansionLimit: z.literal(8192).optional(),
|
|
297
|
-
humanApproval: z.literal("distinct_member").optional(),
|
|
298
395
|
reminder: z
|
|
299
396
|
.strictObject({
|
|
300
397
|
installment: path,
|
|
@@ -319,6 +416,7 @@ export const udlActionSchema = z.strictObject({
|
|
|
319
416
|
parent: z.union([instrumentId, z.array(instrumentId).min(1).max(16)]),
|
|
320
417
|
}),
|
|
321
418
|
]),
|
|
419
|
+
subject: udlActionSubjectSchema.optional(),
|
|
322
420
|
input: z.array(udlFieldSchema).max(128),
|
|
323
421
|
requires: z.array(udlRequirementSchema).max(128),
|
|
324
422
|
due: clock.optional(),
|
|
@@ -358,16 +456,6 @@ export const udlActionSchema = z.strictObject({
|
|
|
358
456
|
)
|
|
359
457
|
.max(16)
|
|
360
458
|
.optional(),
|
|
361
|
-
approval: z
|
|
362
|
-
.strictObject({
|
|
363
|
-
target: path,
|
|
364
|
-
action: name,
|
|
365
|
-
party: name,
|
|
366
|
-
expires: path,
|
|
367
|
-
input: z.record(name, value),
|
|
368
|
-
decision: z.enum(["approved", "declined"]),
|
|
369
|
-
})
|
|
370
|
-
.optional(),
|
|
371
459
|
});
|
|
372
460
|
export const udlLifecycleSchema = z.strictObject({
|
|
373
461
|
states: z.array(name).min(1).max(64),
|
|
@@ -380,7 +468,9 @@ export const udlLifecycleSchema = z.strictObject({
|
|
|
380
468
|
export const udlInstrumentSchema = z.strictObject({
|
|
381
469
|
reports: z.array(reportDefinitionSchema).max(16).optional(),
|
|
382
470
|
revisioned: z.literal(true).optional(),
|
|
471
|
+
family: udlFamilySchema.optional(),
|
|
383
472
|
id: instrumentId,
|
|
473
|
+
subject: objectKindId.optional(),
|
|
384
474
|
title: text,
|
|
385
475
|
summary: text,
|
|
386
476
|
fields: z.array(udlFieldSchema).max(256),
|
|
@@ -401,9 +491,11 @@ export const udlDocumentSchema = z.strictObject({
|
|
|
401
491
|
title: text,
|
|
402
492
|
currency: z.literal("SAR"),
|
|
403
493
|
parties: z.record(name, udlPartySchema),
|
|
404
|
-
|
|
494
|
+
objects: z.array(udlObjectKindSchema).max(256),
|
|
495
|
+
instruments: z.array(udlInstrumentSchema).max(256),
|
|
405
496
|
});
|
|
406
497
|
|
|
498
|
+
export type UdlFamily = z.infer<typeof udlFamilySchema>;
|
|
407
499
|
export type UdlDocument = z.infer<typeof udlDocumentSchema>;
|
|
408
500
|
export type UdlInstrument = z.infer<typeof udlInstrumentSchema>;
|
|
409
501
|
export type UdlField = z.infer<typeof udlFieldSchema>;
|
|
@@ -417,3 +509,33 @@ export type UdlLifecycle = z.infer<typeof udlLifecycleSchema>;
|
|
|
417
509
|
export type UdlKernelOperation = z.infer<typeof udlKernelOperationSchema>;
|
|
418
510
|
|
|
419
511
|
export type UdlSelection = z.infer<typeof selection>;
|
|
512
|
+
|
|
513
|
+
export type UdlObjectField = z.infer<typeof udlObjectFieldSchema>;
|
|
514
|
+
export type UdlObjectKind = z.infer<typeof udlObjectKindSchema>;
|
|
515
|
+
export type UdlActionSubject = z.infer<typeof udlActionSubjectSchema>;
|
|
516
|
+
export type UdlSubjectRequirement = z.infer<typeof udlSubjectRequirementSchema>;
|
|
517
|
+
export type UdlAdapterSubjectSnapshot = z.infer<
|
|
518
|
+
typeof adapterSubjectSnapshotSchema
|
|
519
|
+
>;
|
|
520
|
+
|
|
521
|
+
/** Names and display text may differ; executable constraints must match. */
|
|
522
|
+
export function sameObjectField(
|
|
523
|
+
left: UdlObjectField,
|
|
524
|
+
right: UdlObjectField,
|
|
525
|
+
): boolean {
|
|
526
|
+
const signature = (field: UdlObjectField) =>
|
|
527
|
+
JSON.stringify(
|
|
528
|
+
Object.fromEntries(
|
|
529
|
+
Object.entries(field)
|
|
530
|
+
.filter(
|
|
531
|
+
([key, value]) =>
|
|
532
|
+
!["name", "description", "optional"].includes(key) &&
|
|
533
|
+
value !== undefined,
|
|
534
|
+
)
|
|
535
|
+
.sort(([left], [right]) =>
|
|
536
|
+
left < right ? -1 : left > right ? 1 : 0,
|
|
537
|
+
),
|
|
538
|
+
),
|
|
539
|
+
);
|
|
540
|
+
return signature(left) === signature(right);
|
|
541
|
+
}
|