@hyperscale0/udl 2.3.0 → 2.4.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 +26 -0
- package/README.md +5 -1
- package/conformance/invalid/invalid-journeys.expected.json +3 -19
- package/conformance/invalid/invalid-journeys.udl +47 -49
- package/conformance/valid/attested.expected.json +6 -0
- package/conformance/valid/attested.udl +251 -0
- package/conformance/valid/hand-edited.expected.json +1 -1
- package/conformance/valid/hand-edited.udl +1 -1
- package/conformance/valid/minimal.expected.json +1 -1
- package/conformance/valid/minimal.udl +0 -15
- package/conformance/valid/vocabulary.expected.json +6 -0
- package/conformance/valid/vocabulary.udl +1999 -0
- package/dist/allocation.d.ts +60 -0
- package/dist/allocation.d.ts.map +1 -0
- package/dist/allocation.js +177 -0
- package/dist/allocation.js.map +1 -0
- package/dist/diagnostics.d.ts +1 -31
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +0 -30
- package/dist/diagnostics.js.map +1 -1
- package/dist/distribution.d.ts +15 -0
- package/dist/distribution.d.ts.map +1 -0
- package/dist/distribution.js +49 -0
- package/dist/distribution.js.map +1 -0
- package/dist/effects.d.ts.map +1 -1
- package/dist/effects.js +23 -1
- package/dist/effects.js.map +1 -1
- package/dist/evolution.d.ts +12 -0
- package/dist/evolution.d.ts.map +1 -1
- package/dist/evolution.js +42 -1
- package/dist/evolution.js.map +1 -1
- package/dist/finance.d.ts +18 -1
- package/dist/finance.d.ts.map +1 -1
- package/dist/finance.js +158 -27
- package/dist/finance.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/instrument-references.d.ts +5 -0
- package/dist/instrument-references.d.ts.map +1 -0
- package/dist/instrument-references.js +69 -0
- package/dist/instrument-references.js.map +1 -0
- package/dist/limits.d.ts +3 -3
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +3 -7
- package/dist/limits.js.map +1 -1
- package/dist/reference.d.ts +3 -0
- package/dist/reference.d.ts.map +1 -0
- package/dist/reference.js +28 -0
- package/dist/reference.js.map +1 -0
- package/dist/schema.d.ts +1232 -83
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +398 -60
- package/dist/schema.js.map +1 -1
- package/dist/validation.d.ts +14 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +75 -131
- package/dist/validation.js.map +1 -1
- package/dist/vocabulary.d.ts +23 -0
- package/dist/vocabulary.d.ts.map +1 -0
- package/dist/vocabulary.js +965 -0
- package/dist/vocabulary.js.map +1 -0
- package/docs/README.md +2 -1
- package/docs/funding-custody.md +165 -0
- package/docs/guide/09-schedules-and-allocation.md +130 -0
- package/docs/llms-full.txt +620 -101
- package/docs/llms.txt +1 -1
- package/docs/reference/clauses.md +451 -63
- package/docs/reference/cli.md +3 -1
- package/docs/reference/diagnostics.md +33 -38
- package/package.json +5 -6
- package/spec/udl.schema.json +1095 -118
- package/src/allocation.ts +259 -0
- package/src/diagnostics.ts +0 -32
- package/src/distribution.ts +61 -0
- package/src/effects.ts +27 -1
- package/src/evolution.ts +63 -3
- package/src/finance.ts +218 -24
- package/src/index.ts +30 -3
- package/src/instrument-references.ts +98 -0
- package/src/limits.ts +3 -7
- package/src/reference.ts +31 -0
- package/src/schema.ts +417 -66
- package/src/validation.ts +112 -182
- package/src/vocabulary.ts +1508 -0
package/dist/schema.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { referencePatternPrefix } from "./reference.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import { udlCheckEvidenceProfiles } from "./check-profiles.js";
|
|
3
4
|
export const udlEffectKinds = [
|
|
@@ -17,6 +18,9 @@ const eventNamePattern = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/;
|
|
|
17
18
|
const udlSnakeCaseSchema = z
|
|
18
19
|
.string()
|
|
19
20
|
.regex(snakeCasePattern, "must be a snake_case identifier");
|
|
21
|
+
const udlInstrumentIdSchema = udlSnakeCaseSchema.meta({
|
|
22
|
+
"x-udl-reference": "instrument",
|
|
23
|
+
});
|
|
20
24
|
const udlActionNameSchema = z
|
|
21
25
|
.string()
|
|
22
26
|
.regex(snakeCasePattern, "must be a snake_case action identifier");
|
|
@@ -30,10 +34,6 @@ export const udlInstrumentActionIdSchema = z
|
|
|
30
34
|
.string()
|
|
31
35
|
.max(160)
|
|
32
36
|
.regex(/^[a-z][a-z0-9_]*\.[a-z][a-z0-9_]*$/, "must name an instrument action as instrument_id.action_key");
|
|
33
|
-
const udlJourneyOperationNameSchema = z
|
|
34
|
-
.string()
|
|
35
|
-
.max(160)
|
|
36
|
-
.regex(/^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/, "must name a dotted operation");
|
|
37
37
|
const nonEmptyTextSchema = z
|
|
38
38
|
.string()
|
|
39
39
|
.refine((value) => value.trim().length > 0, "must not be blank");
|
|
@@ -85,18 +85,6 @@ const udlExampleSchema = z.strictObject({
|
|
|
85
85
|
name: nonEmptyTextSchema,
|
|
86
86
|
output: z.json().optional(),
|
|
87
87
|
});
|
|
88
|
-
const udlJourneyStepSchema = z.strictObject({
|
|
89
|
-
bind: z.record(fieldPathSchema, udlSnakeCaseSchema),
|
|
90
|
-
example: udlSnakeCaseSchema,
|
|
91
|
-
id: udlSnakeCaseSchema.optional(),
|
|
92
|
-
operation: udlJourneyOperationNameSchema,
|
|
93
|
-
});
|
|
94
|
-
export const udlJourneySchema = z.strictObject({
|
|
95
|
-
id: udlSnakeCaseSchema,
|
|
96
|
-
label: nonEmptyTextSchema,
|
|
97
|
-
steps: z.array(udlJourneyStepSchema).min(1),
|
|
98
|
-
summary: nonEmptyTextSchema,
|
|
99
|
-
});
|
|
100
88
|
const udlLifecycleTransitionSchema = z.strictObject({
|
|
101
89
|
from: z.array(udlSnakeCaseSchema).min(1),
|
|
102
90
|
to: udlSnakeCaseSchema,
|
|
@@ -117,10 +105,26 @@ const udlDateComparisonSchema = z.strictObject({
|
|
|
117
105
|
operator: udlDateComparisonOperatorSchema,
|
|
118
106
|
referencedPath: fieldPathSchema,
|
|
119
107
|
});
|
|
108
|
+
const udlStoredFieldSchema = z.strictObject({ field: udlFieldNameSchema });
|
|
109
|
+
const udlOffsetSchema = z.union([nonEmptyTextSchema, udlStoredFieldSchema]);
|
|
110
|
+
const udlAttestationSchema = z.strictObject({
|
|
111
|
+
forAction: udlActionNameSchema.optional(),
|
|
112
|
+
action: instanceValuePathSchema,
|
|
113
|
+
digest: instanceValuePathSchema,
|
|
114
|
+
role: instanceValuePathSchema,
|
|
115
|
+
expiresAt: instanceValuePathSchema,
|
|
116
|
+
instrument: instanceValuePathSchema,
|
|
117
|
+
party: z.string().regex(/^[a-z][A-Za-z0-9_]*$/),
|
|
118
|
+
consume: udlActionNameSchema,
|
|
119
|
+
});
|
|
120
120
|
const udlGateSchema = z.strictObject({
|
|
121
|
+
attests: udlAttestationSchema.optional(),
|
|
121
122
|
/** Local field key <- referenced instance path; create actions only. */
|
|
122
123
|
bind: z.record(udlFieldNameSchema, fieldPathSchema).optional(),
|
|
123
124
|
dateComparison: udlDateComparisonSchema.optional(),
|
|
125
|
+
dueBefore: z
|
|
126
|
+
.strictObject({ field: udlFieldNameSchema, offset: nonEmptyTextSchema })
|
|
127
|
+
.optional(),
|
|
124
128
|
field: udlFieldNameSchema,
|
|
125
129
|
/** Local instance path === referenced instance path at admission. */
|
|
126
130
|
match: z.record(fieldPathSchema, fieldPathSchema).optional(),
|
|
@@ -128,7 +132,15 @@ const udlGateSchema = z.strictObject({
|
|
|
128
132
|
optional: z.literal(true).optional(),
|
|
129
133
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
130
134
|
/** One dependent ever per referenced instance; create actions only. */
|
|
131
|
-
unique: z
|
|
135
|
+
unique: z
|
|
136
|
+
.union([
|
|
137
|
+
z.literal(true),
|
|
138
|
+
z.strictObject({
|
|
139
|
+
namespace: udlSnakeCaseSchema,
|
|
140
|
+
byFields: z.array(udlFieldNameSchema).min(1).max(8),
|
|
141
|
+
}),
|
|
142
|
+
])
|
|
143
|
+
.optional(),
|
|
132
144
|
});
|
|
133
145
|
const udlBindingSchema = z.discriminatedUnion("from", [
|
|
134
146
|
z.strictObject({ from: z.literal("const"), value: z.string() }),
|
|
@@ -178,19 +190,19 @@ const udlDueRecurrenceSchema = z.strictObject({
|
|
|
178
190
|
untilField: udlFieldNameSchema.optional(),
|
|
179
191
|
});
|
|
180
192
|
const udlDueParentStatusSchema = z.strictObject({
|
|
181
|
-
instrumentId:
|
|
193
|
+
instrumentId: udlInstrumentIdSchema,
|
|
182
194
|
refField: udlFieldNameSchema,
|
|
183
195
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
184
196
|
});
|
|
185
197
|
const udlDueSchema = z.strictObject({
|
|
186
198
|
every: udlDueRecurrenceSchema.optional(),
|
|
187
199
|
field: udlFieldNameSchema,
|
|
188
|
-
offset:
|
|
200
|
+
offset: udlOffsetSchema.optional(),
|
|
189
201
|
whenParentStatus: udlDueParentStatusSchema.optional(),
|
|
190
202
|
});
|
|
191
203
|
const udlDeadlineSchema = z.strictObject({
|
|
192
204
|
field: udlFieldNameSchema,
|
|
193
|
-
offset:
|
|
205
|
+
offset: udlOffsetSchema.optional(),
|
|
194
206
|
});
|
|
195
207
|
const udlSetsAtSchema = z.strictObject({
|
|
196
208
|
field: udlFieldNameSchema,
|
|
@@ -294,6 +306,29 @@ const udlAggregateCheckSchema = z.discriminatedUnion("kind", [
|
|
|
294
306
|
kind: z.literal("count_at_least"),
|
|
295
307
|
targetField: udlFieldNameSchema,
|
|
296
308
|
}),
|
|
309
|
+
z.strictObject({
|
|
310
|
+
kind: z.literal("count_exactly"),
|
|
311
|
+
value: z.number().int().min(0),
|
|
312
|
+
}),
|
|
313
|
+
z.strictObject({
|
|
314
|
+
kind: z.literal("ordered"),
|
|
315
|
+
field: udlFieldNameSchema,
|
|
316
|
+
positionField: udlFieldNameSchema,
|
|
317
|
+
}),
|
|
318
|
+
z.strictObject({
|
|
319
|
+
kind: z.literal("schedule"),
|
|
320
|
+
positionField: udlFieldNameSchema,
|
|
321
|
+
dateField: udlFieldNameSchema,
|
|
322
|
+
datesField: udlFieldNameSchema,
|
|
323
|
+
amounts: z
|
|
324
|
+
.array(z.strictObject({
|
|
325
|
+
amountField: udlFieldNameSchema,
|
|
326
|
+
totalField: udlFieldNameSchema,
|
|
327
|
+
}))
|
|
328
|
+
.min(1)
|
|
329
|
+
.max(8),
|
|
330
|
+
remainder: z.literal("first"),
|
|
331
|
+
}),
|
|
297
332
|
z.strictObject({ kind: z.literal("all_in") }),
|
|
298
333
|
z.strictObject({
|
|
299
334
|
field: udlFieldNameSchema,
|
|
@@ -301,18 +336,28 @@ const udlAggregateCheckSchema = z.discriminatedUnion("kind", [
|
|
|
301
336
|
}),
|
|
302
337
|
]);
|
|
303
338
|
const udlAggregateConditionSchema = z.strictObject({
|
|
339
|
+
anchorField: udlFieldNameSchema.optional(),
|
|
340
|
+
dueBefore: z
|
|
341
|
+
.strictObject({
|
|
342
|
+
field: udlFieldNameSchema,
|
|
343
|
+
offset: udlOffsetSchema.optional(),
|
|
344
|
+
})
|
|
345
|
+
.optional(),
|
|
304
346
|
check: udlAggregateCheckSchema,
|
|
305
|
-
instrumentId:
|
|
347
|
+
instrumentId: udlInstrumentIdSchema.optional(),
|
|
306
348
|
over: z.enum(["children", "siblings"]),
|
|
307
349
|
refField: udlFieldNameSchema,
|
|
308
350
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
309
351
|
});
|
|
310
352
|
const udlExposureRequirementSchema = z.strictObject({
|
|
353
|
+
groupField: udlFieldNameSchema.optional(),
|
|
354
|
+
minimumField: udlFieldNameSchema.optional(),
|
|
355
|
+
measure: z.strictObject({ allocation: udlSnakeCaseSchema }).optional(),
|
|
311
356
|
amountField: udlFieldNameSchema,
|
|
312
357
|
anchorField: udlFieldNameSchema,
|
|
313
358
|
capField: udlFieldNameSchema,
|
|
314
359
|
capOnAnchor: z.literal(true).optional(),
|
|
315
|
-
childInstrumentId:
|
|
360
|
+
childInstrumentId: udlInstrumentIdSchema,
|
|
316
361
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
317
362
|
});
|
|
318
363
|
// The tenant-backend decision port: the action's caller asserts the acting
|
|
@@ -321,6 +366,7 @@ const udlExposureRequirementSchema = z.strictObject({
|
|
|
321
366
|
const udlPartyRoleSchema = z.string().regex(/^[a-z][A-Za-z0-9_]*$/);
|
|
322
367
|
const udlPortSchema = z.strictObject({
|
|
323
368
|
allowedParties: z.array(udlPartyRoleSchema).min(1),
|
|
369
|
+
capture: udlFieldNameSchema.optional(),
|
|
324
370
|
});
|
|
325
371
|
const udlPayoutSchema = z.strictObject({
|
|
326
372
|
amount: instanceValuePathSchema,
|
|
@@ -357,7 +403,7 @@ const udlReconcileSchema = z.strictObject({
|
|
|
357
403
|
*/
|
|
358
404
|
exception: z.strictObject({
|
|
359
405
|
amountField: udlFieldNameSchema,
|
|
360
|
-
childInstrumentId:
|
|
406
|
+
childInstrumentId: udlInstrumentIdSchema,
|
|
361
407
|
maxOpen: z.number().int().min(1).max(1_000),
|
|
362
408
|
reasonField: udlFieldNameSchema,
|
|
363
409
|
refField: udlFieldNameSchema,
|
|
@@ -384,7 +430,7 @@ const udlReconcileSchema = z.strictObject({
|
|
|
384
430
|
});
|
|
385
431
|
const udlSignedSumSourceSchema = z.strictObject({
|
|
386
432
|
amountField: udlFieldNameSchema,
|
|
387
|
-
instrumentId:
|
|
433
|
+
instrumentId: udlInstrumentIdSchema,
|
|
388
434
|
refField: udlFieldNameSchema,
|
|
389
435
|
sign: z.enum(["add", "subtract"]),
|
|
390
436
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
@@ -409,7 +455,7 @@ const udlDistributeSchema = z.strictObject({
|
|
|
409
455
|
});
|
|
410
456
|
const udlRemainderCollectedSchema = z.strictObject({
|
|
411
457
|
amountField: udlFieldNameSchema,
|
|
412
|
-
instrumentId:
|
|
458
|
+
instrumentId: udlInstrumentIdSchema,
|
|
413
459
|
path: z.literal("refs").optional(),
|
|
414
460
|
refField: udlFieldNameSchema,
|
|
415
461
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
@@ -421,6 +467,7 @@ const udlRemainderSchema = z.strictObject({
|
|
|
421
467
|
inputKey: udlFieldNameSchema.optional(),
|
|
422
468
|
onZero: z.enum(["refuse", "skip_steps"]),
|
|
423
469
|
totalPath: instanceValuePathSchema,
|
|
470
|
+
subtractPaths: z.array(instanceValuePathSchema).min(1).max(16).optional(),
|
|
424
471
|
});
|
|
425
472
|
const udlCheckRequirementVariants = udlCheckEvidenceProfiles.map((profile) => z.strictObject({
|
|
426
473
|
checkKind: z.literal(profile.checkKind),
|
|
@@ -486,10 +533,16 @@ const udlPartitionSchema = z.strictObject({
|
|
|
486
533
|
const udlDerivedAmountSchema = z.strictObject({
|
|
487
534
|
field: udlFieldNameSchema,
|
|
488
535
|
rounding: z.literal("floor"),
|
|
489
|
-
rule: z.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
536
|
+
rule: z.discriminatedUnion("kind", [
|
|
537
|
+
z.strictObject({
|
|
538
|
+
bps: z.union([z.number().int().min(1).max(9_999), udlStoredFieldSchema]),
|
|
539
|
+
kind: z.literal("percentage_of"),
|
|
540
|
+
}),
|
|
541
|
+
z.strictObject({
|
|
542
|
+
kind: z.literal("minimum"),
|
|
543
|
+
capField: udlFieldNameSchema,
|
|
544
|
+
}),
|
|
545
|
+
]),
|
|
493
546
|
sourceField: udlFieldNameSchema,
|
|
494
547
|
});
|
|
495
548
|
const udlFeeLeafRuleSchema = z.discriminatedUnion("kind", [
|
|
@@ -620,7 +673,162 @@ export const udlActionLibraryModuleSchema = z.strictObject({
|
|
|
620
673
|
actions: z.record(udlSnakeCaseSchema, udlPrivateActionSchema),
|
|
621
674
|
});
|
|
622
675
|
export const udlActionLibrarySchema = z.record(udlSnakeCaseSchema, udlActionLibraryModuleSchema);
|
|
676
|
+
const templateParametersSchema = z.record(udlFieldNameSchema, z.union([z.string(), z.number().int(), z.boolean()]));
|
|
677
|
+
const udlAllocationBucketSchema = z.strictObject({
|
|
678
|
+
key: z.enum(["principal", "profit", "cost", "fine"]),
|
|
679
|
+
source: z.union([
|
|
680
|
+
z.strictObject({
|
|
681
|
+
from: z.literal("slice"),
|
|
682
|
+
amountField: udlFieldNameSchema,
|
|
683
|
+
destinationField: udlFieldNameSchema,
|
|
684
|
+
}),
|
|
685
|
+
z.strictObject({
|
|
686
|
+
from: z.literal("children"),
|
|
687
|
+
instrumentId: udlInstrumentIdSchema,
|
|
688
|
+
refField: udlFieldNameSchema,
|
|
689
|
+
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
690
|
+
amountField: udlFieldNameSchema,
|
|
691
|
+
destinationField: udlFieldNameSchema,
|
|
692
|
+
}),
|
|
693
|
+
z.strictObject({
|
|
694
|
+
from: z.literal("children"),
|
|
695
|
+
template: udlSnakeCaseSchema,
|
|
696
|
+
parameters: templateParametersSchema,
|
|
697
|
+
refField: udlFieldNameSchema,
|
|
698
|
+
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
699
|
+
amountField: udlFieldNameSchema,
|
|
700
|
+
destinationField: udlFieldNameSchema,
|
|
701
|
+
}),
|
|
702
|
+
]),
|
|
703
|
+
});
|
|
704
|
+
const udlAllocationSchema = z.strictObject({
|
|
705
|
+
sliceInstrumentId: udlInstrumentIdSchema,
|
|
706
|
+
sliceRefField: udlFieldNameSchema,
|
|
707
|
+
sliceStatuses: z.array(udlSnakeCaseSchema).min(1),
|
|
708
|
+
dueField: udlFieldNameSchema,
|
|
709
|
+
positionField: udlFieldNameSchema,
|
|
710
|
+
earningRuleField: udlFieldNameSchema,
|
|
711
|
+
buckets: z.array(udlAllocationBucketSchema).min(2).max(4),
|
|
712
|
+
});
|
|
713
|
+
const udlAllocateSchema = z.union([
|
|
714
|
+
z.strictObject({
|
|
715
|
+
refField: udlFieldNameSchema.optional(),
|
|
716
|
+
mode: z.literal("refund"),
|
|
717
|
+
action: udlActionNameSchema.optional(),
|
|
718
|
+
assessmentField: udlFieldNameSchema.optional(),
|
|
719
|
+
capture: udlFieldNameSchema,
|
|
720
|
+
}),
|
|
721
|
+
z.strictObject({
|
|
722
|
+
refField: udlFieldNameSchema,
|
|
723
|
+
mode: z.literal("payment"),
|
|
724
|
+
assessment: z.literal("self").optional(),
|
|
725
|
+
amountField: udlFieldNameSchema.optional(),
|
|
726
|
+
sourceAccountField: udlFieldNameSchema,
|
|
727
|
+
paymentIdentityField: udlFieldNameSchema,
|
|
728
|
+
capture: udlFieldNameSchema,
|
|
729
|
+
}),
|
|
730
|
+
z.strictObject({
|
|
731
|
+
refField: udlFieldNameSchema.optional(),
|
|
732
|
+
mode: z.literal("payoff"),
|
|
733
|
+
amountField: udlFieldNameSchema.optional(),
|
|
734
|
+
sourceAccountField: udlFieldNameSchema,
|
|
735
|
+
paymentIdentityField: udlFieldNameSchema,
|
|
736
|
+
capture: udlFieldNameSchema,
|
|
737
|
+
}),
|
|
738
|
+
z.strictObject({
|
|
739
|
+
refField: udlFieldNameSchema.optional(),
|
|
740
|
+
mode: z.literal("write_off"),
|
|
741
|
+
capture: udlFieldNameSchema,
|
|
742
|
+
}),
|
|
743
|
+
]);
|
|
744
|
+
const udlContributionsSchema = z.strictObject({
|
|
745
|
+
field: udlFieldNameSchema,
|
|
746
|
+
amountKey: udlFieldNameSchema,
|
|
747
|
+
accountKey: udlFieldNameSchema,
|
|
748
|
+
totalField: udlFieldNameSchema,
|
|
749
|
+
});
|
|
750
|
+
// These clauses are opt-in. Absent clauses never add defaults to older documents.
|
|
751
|
+
const udlFundingSchema = z.strictObject({
|
|
752
|
+
obligationField: udlFieldNameSchema,
|
|
753
|
+
ticketInstrumentId: udlInstrumentIdSchema,
|
|
754
|
+
ticketRefField: udlFieldNameSchema,
|
|
755
|
+
ticketAmountField: udlFieldNameSchema,
|
|
756
|
+
ticketInvestorField: udlFieldNameSchema,
|
|
757
|
+
ticketAccountField: udlFieldNameSchema,
|
|
758
|
+
ticketStatus: udlSnakeCaseSchema,
|
|
759
|
+
collectAction: udlActionNameSchema,
|
|
760
|
+
principalField: udlFieldNameSchema,
|
|
761
|
+
sourceAccountPath: instanceValuePathSchema,
|
|
762
|
+
destinationAccountField: udlFieldNameSchema,
|
|
763
|
+
terms: z.record(udlFieldNameSchema, udlFieldNameSchema),
|
|
764
|
+
capture: udlFieldNameSchema,
|
|
765
|
+
});
|
|
766
|
+
const udlReceiptDistributionSchema = z.strictObject({
|
|
767
|
+
roundField: udlFieldNameSchema,
|
|
768
|
+
snapshotRef: udlFieldNameSchema,
|
|
769
|
+
receiptField: udlFieldNameSchema,
|
|
770
|
+
receiptPath: instanceValuePathSchema,
|
|
771
|
+
mode: z.enum(["cash", "loss"]),
|
|
772
|
+
feeBps: z.number().int().min(0).max(10000),
|
|
773
|
+
vatBps: z.number().int().min(0).max(10000),
|
|
774
|
+
feeAccountField: udlFieldNameSchema,
|
|
775
|
+
taxAccountField: udlFieldNameSchema,
|
|
776
|
+
residualAccountField: udlFieldNameSchema,
|
|
777
|
+
capture: udlFieldNameSchema,
|
|
778
|
+
});
|
|
779
|
+
const udlRequestAuthoritySchema = z.strictObject({
|
|
780
|
+
instrumentField: udlFieldNameSchema,
|
|
781
|
+
instanceField: udlFieldNameSchema,
|
|
782
|
+
actionField: udlFieldNameSchema,
|
|
783
|
+
inputField: udlFieldNameSchema,
|
|
784
|
+
digestField: udlFieldNameSchema,
|
|
785
|
+
roleField: udlFieldNameSchema,
|
|
786
|
+
party: udlPartyRoleSchema,
|
|
787
|
+
expiresField: udlFieldNameSchema,
|
|
788
|
+
});
|
|
623
789
|
const udlActionShape = {
|
|
790
|
+
requestAuthority: udlRequestAuthoritySchema.optional(),
|
|
791
|
+
funding: udlFundingSchema.optional(),
|
|
792
|
+
receiptDistribution: udlReceiptDistributionSchema.optional(),
|
|
793
|
+
requiresAllocation: z
|
|
794
|
+
.strictObject({
|
|
795
|
+
refField: udlFieldNameSchema.optional(),
|
|
796
|
+
slice: z.union([z.literal("self"), udlStoredFieldSchema]),
|
|
797
|
+
buckets: z
|
|
798
|
+
.array(z.enum(["principal", "profit", "cost", "fine"]))
|
|
799
|
+
.min(1)
|
|
800
|
+
.max(4),
|
|
801
|
+
check: z.enum(["settled", "outstanding"]),
|
|
802
|
+
})
|
|
803
|
+
.optional(),
|
|
804
|
+
unique: z
|
|
805
|
+
.strictObject({
|
|
806
|
+
namespace: udlSnakeCaseSchema,
|
|
807
|
+
byFields: z.array(udlFieldNameSchema).min(1).max(8),
|
|
808
|
+
})
|
|
809
|
+
.optional(),
|
|
810
|
+
requiresInput: z
|
|
811
|
+
.record(udlFieldNameSchema, instanceValuePathSchema)
|
|
812
|
+
.optional(),
|
|
813
|
+
engineOwned: z.literal(true).optional(),
|
|
814
|
+
captureEngine: z
|
|
815
|
+
.record(udlFieldNameSchema, z.enum(["operationId"]))
|
|
816
|
+
.optional(),
|
|
817
|
+
allocate: udlAllocateSchema.optional(),
|
|
818
|
+
contributionStage: z
|
|
819
|
+
.strictObject({
|
|
820
|
+
stage: z.enum(["fund", "refund"]),
|
|
821
|
+
accountPath: instanceValuePathSchema,
|
|
822
|
+
})
|
|
823
|
+
.optional(),
|
|
824
|
+
transitionsRefs: z
|
|
825
|
+
.array(z.strictObject({
|
|
826
|
+
field: udlFieldNameSchema,
|
|
827
|
+
action: udlActionNameSchema,
|
|
828
|
+
}))
|
|
829
|
+
.min(1)
|
|
830
|
+
.max(16)
|
|
831
|
+
.optional(),
|
|
624
832
|
agentDescription: udlAgentDescriptionSchema.optional(),
|
|
625
833
|
calls: z.array(udlCallSchema).min(1).optional(),
|
|
626
834
|
captureInput: z.record(udlFieldNameSchema, udlFieldNameSchema).optional(),
|
|
@@ -634,7 +842,11 @@ const udlActionShape = {
|
|
|
634
842
|
due: udlDueSchema.optional(),
|
|
635
843
|
earnable: z.boolean().optional(),
|
|
636
844
|
effects: udlEffectsSchema.optional(),
|
|
637
|
-
eventName: z
|
|
845
|
+
eventName: z
|
|
846
|
+
.string()
|
|
847
|
+
.regex(eventNamePattern)
|
|
848
|
+
.meta({ "x-udl-reference": "instrument_event" })
|
|
849
|
+
.optional(),
|
|
638
850
|
examples: z.array(udlExampleSchema).min(1).optional(),
|
|
639
851
|
input: jsonObjectSchema.optional(),
|
|
640
852
|
moves: z.array(udlMoveSchema).default([]),
|
|
@@ -662,7 +874,7 @@ const udlActionShape = {
|
|
|
662
874
|
};
|
|
663
875
|
const udlActionSchema = z.strictObject(udlActionShape);
|
|
664
876
|
const udlAggregateBaseShape = {
|
|
665
|
-
childInstrumentId:
|
|
877
|
+
childInstrumentId: udlInstrumentIdSchema,
|
|
666
878
|
childRefField: udlFieldNameSchema,
|
|
667
879
|
childStatuses: z.array(udlSnakeCaseSchema).min(1),
|
|
668
880
|
parentField: udlFieldNameSchema,
|
|
@@ -687,6 +899,23 @@ const udlAggregateSchema = z.union([
|
|
|
687
899
|
}),
|
|
688
900
|
]);
|
|
689
901
|
const udlInstrumentShape = {
|
|
902
|
+
templateBinding: z
|
|
903
|
+
.strictObject({
|
|
904
|
+
id: udlSnakeCaseSchema,
|
|
905
|
+
parameters: templateParametersSchema,
|
|
906
|
+
})
|
|
907
|
+
.optional(),
|
|
908
|
+
allocation: udlAllocationSchema.optional(),
|
|
909
|
+
contributions: udlContributionsSchema.optional(),
|
|
910
|
+
dateOrder: z
|
|
911
|
+
.array(z.strictObject({
|
|
912
|
+
beforeField: udlFieldNameSchema,
|
|
913
|
+
afterField: udlFieldNameSchema,
|
|
914
|
+
operator: z.enum(["<", "<="]),
|
|
915
|
+
}))
|
|
916
|
+
.min(1)
|
|
917
|
+
.max(16)
|
|
918
|
+
.optional(),
|
|
690
919
|
actionLibrary: udlActionLibrarySchema.optional(),
|
|
691
920
|
actionOrder: z.array(udlActionNameSchema).min(1),
|
|
692
921
|
agentDescription: udlAgentDescriptionSchema.optional(),
|
|
@@ -697,15 +926,14 @@ const udlInstrumentShape = {
|
|
|
697
926
|
description: nonEmptyTextSchema.optional(),
|
|
698
927
|
dials: z.array(udlDialSchema).optional(),
|
|
699
928
|
distinctParties: z.literal(true).optional(),
|
|
700
|
-
derivedAmounts: z.array(udlDerivedAmountSchema).min(1).max(
|
|
929
|
+
derivedAmounts: z.array(udlDerivedAmountSchema).min(1).max(64).optional(),
|
|
701
930
|
feeRules: z.array(udlFeeRuleSchema).min(1).max(4).optional(),
|
|
702
931
|
fields: z.record(udlFieldNameSchema, jsonObjectSchema),
|
|
703
|
-
id:
|
|
932
|
+
id: udlInstrumentIdSchema,
|
|
704
933
|
idPrefix: z
|
|
705
934
|
.string()
|
|
706
935
|
.regex(idPrefixPattern, "must contain 2 to 8 lowercase letters"),
|
|
707
936
|
lifecycle: udlLifecycleSchema,
|
|
708
|
-
journeys: z.array(udlJourneySchema).min(1).optional(),
|
|
709
937
|
nav: z.array(nonEmptyTextSchema).min(1).optional(),
|
|
710
938
|
parties: z.record(udlPartyRoleSchema, udlFieldNameSchema).optional(),
|
|
711
939
|
partitions: z.array(udlPartitionSchema).min(1).optional(),
|
|
@@ -721,6 +949,105 @@ const udlInstrumentShape = {
|
|
|
721
949
|
};
|
|
722
950
|
const udlInstrumentSchema = z.strictObject(udlInstrumentShape);
|
|
723
951
|
export const udlClauseVocabulary = [
|
|
952
|
+
{
|
|
953
|
+
scope: "action",
|
|
954
|
+
spelling: "funding",
|
|
955
|
+
target: "funding",
|
|
956
|
+
cardinality: "one",
|
|
957
|
+
effects: [
|
|
958
|
+
{
|
|
959
|
+
kind: "moves",
|
|
960
|
+
per: "clause",
|
|
961
|
+
signature: { fixed: "transfer.internal" },
|
|
962
|
+
},
|
|
963
|
+
],
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
scope: "action",
|
|
967
|
+
spelling: "receipt distribution",
|
|
968
|
+
target: "receiptDistribution",
|
|
969
|
+
cardinality: "one",
|
|
970
|
+
effects: [
|
|
971
|
+
{ kind: "decides", per: "clause", signature: { fixed: "allocation" } },
|
|
972
|
+
{ kind: "moves", per: "clause", signature: { fixed: "allocation" } },
|
|
973
|
+
],
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
cardinality: "one",
|
|
977
|
+
scope: "action",
|
|
978
|
+
spelling: "requires allocation",
|
|
979
|
+
target: "requiresAllocation",
|
|
980
|
+
effects: [
|
|
981
|
+
{ kind: "decides", per: "clause", signature: { fixed: "allocation" } },
|
|
982
|
+
],
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
cardinality: "one",
|
|
986
|
+
scope: "instrument",
|
|
987
|
+
spelling: "allocation",
|
|
988
|
+
target: "allocation",
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
cardinality: "one",
|
|
992
|
+
scope: "instrument",
|
|
993
|
+
spelling: "contributions",
|
|
994
|
+
target: "contributions",
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
cardinality: "one",
|
|
998
|
+
scope: "action",
|
|
999
|
+
spelling: "allocate",
|
|
1000
|
+
target: "allocate",
|
|
1001
|
+
effects: [
|
|
1002
|
+
{ kind: "decides", per: "clause", signature: { fixed: "allocation" } },
|
|
1003
|
+
{ kind: "moves", per: "clause", signature: { fixed: "allocation" } },
|
|
1004
|
+
],
|
|
1005
|
+
},
|
|
1006
|
+
{
|
|
1007
|
+
cardinality: "one",
|
|
1008
|
+
scope: "action",
|
|
1009
|
+
spelling: "contribution stage",
|
|
1010
|
+
target: "contributionStage",
|
|
1011
|
+
effects: [
|
|
1012
|
+
{
|
|
1013
|
+
kind: "moves",
|
|
1014
|
+
per: "clause",
|
|
1015
|
+
signature: { fixed: "transfer.internal" },
|
|
1016
|
+
},
|
|
1017
|
+
],
|
|
1018
|
+
},
|
|
1019
|
+
{
|
|
1020
|
+
cardinality: "many",
|
|
1021
|
+
scope: "instrument",
|
|
1022
|
+
spelling: "date order",
|
|
1023
|
+
target: "dateOrder",
|
|
1024
|
+
},
|
|
1025
|
+
{
|
|
1026
|
+
cardinality: "one",
|
|
1027
|
+
scope: "action",
|
|
1028
|
+
spelling: "unique",
|
|
1029
|
+
target: "unique",
|
|
1030
|
+
effects: [
|
|
1031
|
+
{
|
|
1032
|
+
kind: "decides",
|
|
1033
|
+
per: "clause",
|
|
1034
|
+
signature: { fixed: "subject_unique" },
|
|
1035
|
+
},
|
|
1036
|
+
],
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
cardinality: "many",
|
|
1040
|
+
scope: "action",
|
|
1041
|
+
spelling: "transitions refs",
|
|
1042
|
+
target: "transitionsRefs",
|
|
1043
|
+
effects: [
|
|
1044
|
+
{
|
|
1045
|
+
kind: "decides",
|
|
1046
|
+
per: "element",
|
|
1047
|
+
signature: { fixed: "referenced_transition" },
|
|
1048
|
+
},
|
|
1049
|
+
],
|
|
1050
|
+
},
|
|
724
1051
|
{
|
|
725
1052
|
cardinality: "one",
|
|
726
1053
|
literalKeys: true,
|
|
@@ -741,6 +1068,26 @@ export const udlClauseVocabulary = [
|
|
|
741
1068
|
spelling: "calls",
|
|
742
1069
|
target: "calls",
|
|
743
1070
|
},
|
|
1071
|
+
{
|
|
1072
|
+
cardinality: "one",
|
|
1073
|
+
scope: "action",
|
|
1074
|
+
spelling: "requires input",
|
|
1075
|
+
target: "requiresInput",
|
|
1076
|
+
literalKeys: true,
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
cardinality: "one",
|
|
1080
|
+
scope: "action",
|
|
1081
|
+
spelling: "engine owned",
|
|
1082
|
+
target: "engineOwned",
|
|
1083
|
+
},
|
|
1084
|
+
{
|
|
1085
|
+
cardinality: "one",
|
|
1086
|
+
scope: "action",
|
|
1087
|
+
spelling: "capture engine",
|
|
1088
|
+
target: "captureEngine",
|
|
1089
|
+
literalKeys: true,
|
|
1090
|
+
},
|
|
744
1091
|
{
|
|
745
1092
|
cardinality: "one",
|
|
746
1093
|
scope: "action",
|
|
@@ -1106,12 +1453,6 @@ export const udlClauseVocabulary = [
|
|
|
1106
1453
|
spelling: "id prefix",
|
|
1107
1454
|
target: "idPrefix",
|
|
1108
1455
|
},
|
|
1109
|
-
{
|
|
1110
|
-
cardinality: "many",
|
|
1111
|
-
scope: "instrument",
|
|
1112
|
-
spelling: "journeys",
|
|
1113
|
-
target: "journeys",
|
|
1114
|
-
},
|
|
1115
1456
|
{
|
|
1116
1457
|
cardinality: "many",
|
|
1117
1458
|
scope: "instrument",
|
|
@@ -1142,6 +1483,12 @@ export const udlClauseVocabulary = [
|
|
|
1142
1483
|
spelling: "surface visibility",
|
|
1143
1484
|
target: "surfaceVisibility",
|
|
1144
1485
|
},
|
|
1486
|
+
{
|
|
1487
|
+
cardinality: "one",
|
|
1488
|
+
scope: "instrument",
|
|
1489
|
+
spelling: "template binding",
|
|
1490
|
+
target: "templateBinding",
|
|
1491
|
+
},
|
|
1145
1492
|
{
|
|
1146
1493
|
cardinality: "one",
|
|
1147
1494
|
scope: "instrument",
|
|
@@ -1160,6 +1507,13 @@ export const udlClauseVocabulary = [
|
|
|
1160
1507
|
spelling: "update",
|
|
1161
1508
|
target: "update",
|
|
1162
1509
|
},
|
|
1510
|
+
{
|
|
1511
|
+
cardinality: "one",
|
|
1512
|
+
effects: [],
|
|
1513
|
+
scope: "action",
|
|
1514
|
+
spelling: "request authority",
|
|
1515
|
+
target: "requestAuthority",
|
|
1516
|
+
},
|
|
1163
1517
|
];
|
|
1164
1518
|
const udlDocumentShapeSchema = z.strictObject({
|
|
1165
1519
|
dials: z.array(udlCompositionDialSchema).min(1).optional(),
|
|
@@ -1175,26 +1529,10 @@ function isMoneyField(schema) {
|
|
|
1175
1529
|
return (typeof schema?.pattern === "string" && moneyPatterns.has(schema.pattern));
|
|
1176
1530
|
}
|
|
1177
1531
|
function referenceTargets(schema, instruments) {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
const match = /^\^([a-z]{2,8})_\(sandbox\|live\)_\[a-z0-9\]\{8,64\}\$$/.exec(schema.pattern);
|
|
1183
|
-
if (!match)
|
|
1184
|
-
return [];
|
|
1185
|
-
const prefix = match[1];
|
|
1186
|
-
const probe = `${prefix}_sandbox_0123456789abcdef`;
|
|
1187
|
-
if (typeof schema.const === "string" && schema.const !== probe)
|
|
1188
|
-
return [];
|
|
1189
|
-
if (Array.isArray(schema.enum) && !schema.enum.includes(probe))
|
|
1190
|
-
return [];
|
|
1191
|
-
if (typeof schema.minLength === "number" && probe.length < schema.minLength) {
|
|
1192
|
-
return [];
|
|
1193
|
-
}
|
|
1194
|
-
if (typeof schema.maxLength === "number" && probe.length > schema.maxLength) {
|
|
1195
|
-
return [];
|
|
1196
|
-
}
|
|
1197
|
-
return instruments.filter((instrument) => instrument.idPrefix === prefix);
|
|
1532
|
+
const prefix = referencePatternPrefix(schema);
|
|
1533
|
+
return prefix
|
|
1534
|
+
? instruments.filter((instrument) => instrument.idPrefix === prefix)
|
|
1535
|
+
: [];
|
|
1198
1536
|
}
|
|
1199
1537
|
function declaredMoneyRefKeys(instrument) {
|
|
1200
1538
|
return new Set([
|