@hyperscale0/udl 1.0.0 → 2.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 +19 -4
- package/README.md +24 -36
- package/conformance/invalid/invalid-journeys.expected.json +26 -0
- package/conformance/invalid/invalid-journeys.udl +79 -0
- package/conformance/valid/commerce-escrow.expected.json +1 -1
- package/conformance/valid/commerce-escrow.udl +1 -1
- 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 +23 -0
- package/dist/check-profiles.d.ts.map +1 -1
- package/dist/diagnostics.d.ts +31 -1
- package/dist/diagnostics.d.ts.map +1 -1
- package/dist/diagnostics.js +30 -0
- package/dist/diagnostics.js.map +1 -1
- package/dist/effects.d.ts.map +1 -1
- package/dist/evolution.js +30 -9
- package/dist/evolution.js.map +1 -1
- package/dist/finance.d.ts.map +1 -1
- package/dist/finance.js +37 -18
- package/dist/finance.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +1 -1
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +7 -4
- package/dist/limits.js.map +1 -1
- package/dist/schema.d.ts +258 -147
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +33 -10
- package/dist/schema.js.map +1 -1
- package/dist/validation.d.ts +5 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +176 -7
- package/dist/validation.js.map +1 -1
- package/docs/assets/udl.svg +18 -0
- package/docs/guide/03-laws.md +1 -1
- package/docs/guide/08-implementing.md +1 -1
- package/docs/llms-full.txt +62 -29
- package/docs/llms.txt +1 -1
- package/docs/reference/clauses.md +29 -1
- package/docs/reference/cli.md +1 -1
- package/docs/reference/diagnostics.md +32 -27
- package/package.json +6 -5
- package/spec/README.md +8 -16
- package/spec/udl.schema.json +83 -15
- package/src/diagnostics.ts +32 -0
- package/src/evolution.ts +31 -13
- package/src/finance.ts +53 -20
- package/src/index.ts +6 -0
- package/src/limits.ts +7 -4
- package/src/schema.ts +48 -10
- package/src/validation.ts +252 -6
package/src/evolution.ts
CHANGED
|
@@ -157,7 +157,7 @@ export function snapshotUdlInstrument(
|
|
|
157
157
|
fields: Object.fromEntries(
|
|
158
158
|
Object.entries(instrument.fields).map(([field, schema]) => [
|
|
159
159
|
field,
|
|
160
|
-
{ required: required.has(field), schema },
|
|
160
|
+
{ required: required.has(field), schema: withoutProse(schema) },
|
|
161
161
|
]),
|
|
162
162
|
),
|
|
163
163
|
id: instrument.id,
|
|
@@ -575,11 +575,34 @@ function snapshotJsonSchemaFields(
|
|
|
575
575
|
return Object.fromEntries(
|
|
576
576
|
Object.entries(properties).map(([field, fieldSchema]) => [
|
|
577
577
|
field,
|
|
578
|
-
{ required: required.has(field), schema: fieldSchema },
|
|
578
|
+
{ required: required.has(field), schema: withoutProse(fieldSchema) },
|
|
579
579
|
]),
|
|
580
580
|
);
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
+
/**
|
|
584
|
+
* Descriptions are prose for readers, not shape: a wording fix in a std
|
|
585
|
+
* template must land on a live flow as an extension, never as a refusal.
|
|
586
|
+
*/
|
|
587
|
+
function withoutProse(value: unknown, depth = 1): unknown {
|
|
588
|
+
if (depth > UDL_LIMITS.maxDepth) throw nestingExceeded();
|
|
589
|
+
if (Array.isArray(value)) {
|
|
590
|
+
return value.map((item) => withoutProse(item, depth + 1));
|
|
591
|
+
}
|
|
592
|
+
if (value === null || typeof value !== "object") return value;
|
|
593
|
+
return Object.fromEntries(
|
|
594
|
+
Object.entries(value as Record<string, unknown>)
|
|
595
|
+
.filter(([key]) => key !== "description")
|
|
596
|
+
.map(([key, entry]) => [key, withoutProse(entry, depth + 1)]),
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function nestingExceeded(): UdlError {
|
|
601
|
+
return new UdlError([
|
|
602
|
+
issue("UDL1004", "$", `UDL nesting exceeds ${UDL_LIMITS.maxDepth} levels`),
|
|
603
|
+
]);
|
|
604
|
+
}
|
|
605
|
+
|
|
583
606
|
function snapshotJsonSchemaConstraints(
|
|
584
607
|
schema: Readonly<Record<string, unknown>>,
|
|
585
608
|
): Readonly<Record<string, unknown>> {
|
|
@@ -753,9 +776,12 @@ function diffActions(
|
|
|
753
776
|
) {
|
|
754
777
|
violations.push(`action ${action} changed its check prerequisites`);
|
|
755
778
|
}
|
|
779
|
+
// A failure point only adds a sandbox refusal for one documented amount, so
|
|
780
|
+
// declaring one on an action that had none is additive; changing or
|
|
781
|
+
// removing a declared one rewrites what a sandbox integration relies on.
|
|
756
782
|
if (
|
|
757
|
-
|
|
758
|
-
(current.sandboxFailurePoint ?? null)
|
|
783
|
+
descriptor.sandboxFailurePoint &&
|
|
784
|
+
descriptor.sandboxFailurePoint !== (current.sandboxFailurePoint ?? null)
|
|
759
785
|
) {
|
|
760
786
|
violations.push(`action ${action} changed its sandbox failure point`);
|
|
761
787
|
}
|
|
@@ -937,15 +963,7 @@ function recordValue(value: unknown): Readonly<Record<string, unknown>> {
|
|
|
937
963
|
* and lands here rather than exhausting the call stack.
|
|
938
964
|
*/
|
|
939
965
|
function stableStringify(value: unknown, depth = 1): string {
|
|
940
|
-
if (depth > UDL_LIMITS.maxDepth)
|
|
941
|
-
throw new UdlError([
|
|
942
|
-
issue(
|
|
943
|
-
"UDL1004",
|
|
944
|
-
"$",
|
|
945
|
-
`UDL nesting exceeds ${UDL_LIMITS.maxDepth} levels`,
|
|
946
|
-
),
|
|
947
|
-
]);
|
|
948
|
-
}
|
|
966
|
+
if (depth > UDL_LIMITS.maxDepth) throw nestingExceeded();
|
|
949
967
|
if (value === null || typeof value !== "object") {
|
|
950
968
|
return JSON.stringify(value) ?? "null";
|
|
951
969
|
}
|
package/src/finance.ts
CHANGED
|
@@ -207,6 +207,7 @@ export function analyzeInstrumentFinance(
|
|
|
207
207
|
return issues;
|
|
208
208
|
}
|
|
209
209
|
const initial = applyEffects(
|
|
210
|
+
instrument,
|
|
210
211
|
account,
|
|
211
212
|
"create",
|
|
212
213
|
{ balance: EMPTY, holds: {} },
|
|
@@ -243,6 +244,7 @@ export function analyzeInstrumentFinance(
|
|
|
243
244
|
return issues;
|
|
244
245
|
}
|
|
245
246
|
const targetState = applyEffects(
|
|
247
|
+
instrument,
|
|
246
248
|
account,
|
|
247
249
|
action,
|
|
248
250
|
sourceState,
|
|
@@ -274,19 +276,21 @@ export function analyzeInstrumentFinance(
|
|
|
274
276
|
(transition) => transition.from,
|
|
275
277
|
),
|
|
276
278
|
);
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
279
|
+
if (account.startsWith("ref:")) {
|
|
280
|
+
for (const [state, variants] of states) {
|
|
281
|
+
if (nonterminalStates.has(state)) continue;
|
|
282
|
+
for (const variant of variants.values()) {
|
|
283
|
+
if (
|
|
284
|
+
variant.balance.kind === "empty" &&
|
|
285
|
+
Object.keys(variant.holds).length === 0
|
|
286
|
+
) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
add(
|
|
290
|
+
["lifecycle", "states", instrument.lifecycle.states.indexOf(state)],
|
|
291
|
+
`terminal state ${state} can strand value in ${formatAccount(account)}`,
|
|
292
|
+
);
|
|
285
293
|
}
|
|
286
|
-
add(
|
|
287
|
-
["lifecycle", "states", instrument.lifecycle.states.indexOf(state)],
|
|
288
|
-
`terminal state ${state} can strand value in ${formatAccount(account)}`,
|
|
289
|
-
);
|
|
290
294
|
}
|
|
291
295
|
}
|
|
292
296
|
}
|
|
@@ -434,7 +438,7 @@ function effectsByAction(
|
|
|
434
438
|
instrument,
|
|
435
439
|
step.bind.sourceAccountId,
|
|
436
440
|
);
|
|
437
|
-
if (source && accountsMayAlias(source, account)) {
|
|
441
|
+
if (source && accountsMayAlias(instrument, source, account)) {
|
|
438
442
|
const committed = quoteByCommit.get(actionName);
|
|
439
443
|
const amountPath =
|
|
440
444
|
step.bind.amount?.from === "instance"
|
|
@@ -474,7 +478,7 @@ function effectsByAction(
|
|
|
474
478
|
instrument,
|
|
475
479
|
step.bind.sourceAccountId,
|
|
476
480
|
);
|
|
477
|
-
if (source && accountsMayAlias(source, account)) {
|
|
481
|
+
if (source && accountsMayAlias(instrument, source, account)) {
|
|
478
482
|
effects.push({
|
|
479
483
|
amount: amountIdentity(step.bind.amount),
|
|
480
484
|
kind: "outgoing_reserve",
|
|
@@ -504,7 +508,10 @@ function effectsByAction(
|
|
|
504
508
|
const reserved = reservations.get(reservation);
|
|
505
509
|
if (
|
|
506
510
|
!reserved ||
|
|
507
|
-
(!(
|
|
511
|
+
(!(
|
|
512
|
+
reserved.source &&
|
|
513
|
+
accountsMayAlias(instrument, reserved.source, account)
|
|
514
|
+
) &&
|
|
508
515
|
reserved.destination !== account)
|
|
509
516
|
) {
|
|
510
517
|
return [];
|
|
@@ -526,6 +533,7 @@ function effectsByAction(
|
|
|
526
533
|
}
|
|
527
534
|
|
|
528
535
|
function applyEffects(
|
|
536
|
+
instrument: FinancialInstrument,
|
|
529
537
|
account: string,
|
|
530
538
|
action: string,
|
|
531
539
|
input: AccountState,
|
|
@@ -582,7 +590,7 @@ function applyEffects(
|
|
|
582
590
|
const reservation = reservations.get(key);
|
|
583
591
|
if (
|
|
584
592
|
reservation?.source &&
|
|
585
|
-
accountsMayAlias(reservation.source, account)
|
|
593
|
+
accountsMayAlias(instrument, reservation.source, account)
|
|
586
594
|
) {
|
|
587
595
|
const held = holds[key];
|
|
588
596
|
delete holds[key];
|
|
@@ -784,7 +792,7 @@ function validateChargePayout(
|
|
|
784
792
|
source !== undefined &&
|
|
785
793
|
source === refundSource &&
|
|
786
794
|
destination !== undefined &&
|
|
787
|
-
!accountsMayAlias(source, destination);
|
|
795
|
+
!accountsMayAlias(instrument, source, destination);
|
|
788
796
|
if (!valid) {
|
|
789
797
|
add(
|
|
790
798
|
["actions", use.actionName, "moves", use.stepIndex, "bind", use.target],
|
|
@@ -812,9 +820,34 @@ function canonicalAccount(
|
|
|
812
820
|
return undefined;
|
|
813
821
|
}
|
|
814
822
|
|
|
815
|
-
function accountsMayAlias(
|
|
816
|
-
|
|
817
|
-
|
|
823
|
+
function accountsMayAlias(
|
|
824
|
+
instrument: FinancialInstrument,
|
|
825
|
+
left: string,
|
|
826
|
+
right: string,
|
|
827
|
+
): boolean {
|
|
828
|
+
if (left === right) return true;
|
|
829
|
+
if (left.startsWith("field:") && right.startsWith("field:")) {
|
|
830
|
+
const leftField = left.slice("field:".length);
|
|
831
|
+
const rightField = right.slice("field:".length);
|
|
832
|
+
if (leftField === rightField) return true;
|
|
833
|
+
if (instrument.parties) {
|
|
834
|
+
const leftParty = Object.entries(instrument.parties).find(
|
|
835
|
+
([, field]) => field === leftField,
|
|
836
|
+
)?.[0];
|
|
837
|
+
const rightParty = Object.entries(instrument.parties).find(
|
|
838
|
+
([, field]) => field === rightField,
|
|
839
|
+
)?.[0];
|
|
840
|
+
if (
|
|
841
|
+
leftParty !== undefined &&
|
|
842
|
+
rightParty !== undefined &&
|
|
843
|
+
leftParty !== rightParty
|
|
844
|
+
) {
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return true;
|
|
849
|
+
}
|
|
850
|
+
return false;
|
|
818
851
|
}
|
|
819
852
|
|
|
820
853
|
function amountIdentity(binding: UdlBinding | undefined): string {
|
package/src/index.ts
CHANGED
|
@@ -48,6 +48,7 @@ export {
|
|
|
48
48
|
udlClauseVocabulary,
|
|
49
49
|
udlDocumentSchema,
|
|
50
50
|
udlInstrumentActionIdSchema,
|
|
51
|
+
udlJourneySchema,
|
|
51
52
|
udlKernelOperationSchema,
|
|
52
53
|
udlProviderFamilyIdSchema,
|
|
53
54
|
udlPublicActionSchema,
|
|
@@ -64,12 +65,16 @@ export type {
|
|
|
64
65
|
UdlDue,
|
|
65
66
|
UdlEffects,
|
|
66
67
|
UdlExample,
|
|
68
|
+
UdlDateComparison,
|
|
69
|
+
UdlDateComparisonOperator,
|
|
67
70
|
UdlGate,
|
|
68
71
|
UdlKernelOperation,
|
|
69
72
|
UdlLifecycle,
|
|
70
73
|
UdlLifecycleTransition,
|
|
71
74
|
UdlInstrument,
|
|
72
75
|
UdlInstrumentSubject,
|
|
76
|
+
UdlJourney,
|
|
77
|
+
UdlJourneyStep,
|
|
73
78
|
UdlPayout,
|
|
74
79
|
UdlQuote,
|
|
75
80
|
UdlProviderFamilyId,
|
|
@@ -95,5 +100,6 @@ export {
|
|
|
95
100
|
} from "./validation.js";
|
|
96
101
|
export type {
|
|
97
102
|
ReferenceShapeBudget,
|
|
103
|
+
UdlValidationOptions,
|
|
98
104
|
UdlValidationResult,
|
|
99
105
|
} from "./validation.js";
|
package/src/limits.ts
CHANGED
|
@@ -9,7 +9,8 @@ export const UDL_LIMITS = Object.freeze({
|
|
|
9
9
|
financeWork: 4_096,
|
|
10
10
|
maxDepth: 24,
|
|
11
11
|
maxKeyLength: 128,
|
|
12
|
-
|
|
12
|
+
// The 33-instrument catalog includes its executable authored journeys.
|
|
13
|
+
maxNodes: 20_000,
|
|
13
14
|
maxPatternLength: 320,
|
|
14
15
|
/**
|
|
15
16
|
* Upper bound on the match attempts a document-authored `pattern` can force
|
|
@@ -26,8 +27,10 @@ export const UDL_LIMITS = Object.freeze({
|
|
|
26
27
|
* of the instruments x gate-fields product that asks for them.
|
|
27
28
|
*/
|
|
28
29
|
maxSchemaProbes: 2_048,
|
|
29
|
-
// The complete
|
|
30
|
-
|
|
30
|
+
// The complete catalog now carries executable authored journeys beside the
|
|
31
|
+
// instrument mechanics, so its bounded source and string budgets include
|
|
32
|
+
// that contract-owned corpus.
|
|
33
|
+
maxSourceBytes: 1_024 * 1_024,
|
|
31
34
|
maxStringLength: 2_048,
|
|
32
|
-
maxTotalStringLength:
|
|
35
|
+
maxTotalStringLength: 512 * 1_024,
|
|
33
36
|
});
|
package/src/schema.ts
CHANGED
|
@@ -33,6 +33,14 @@ export const udlInstrumentActionIdSchema = z
|
|
|
33
33
|
"must name an instrument action as instrument_id.action_key",
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
+
const udlJourneyOperationNameSchema = z
|
|
37
|
+
.string()
|
|
38
|
+
.max(160)
|
|
39
|
+
.regex(
|
|
40
|
+
/^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/,
|
|
41
|
+
"must name a dotted operation",
|
|
42
|
+
);
|
|
43
|
+
|
|
36
44
|
const nonEmptyTextSchema = z
|
|
37
45
|
.string()
|
|
38
46
|
.refine((value) => value.trim().length > 0, "must not be blank");
|
|
@@ -93,6 +101,20 @@ const udlExampleSchema = z.strictObject({
|
|
|
93
101
|
output: z.json().optional(),
|
|
94
102
|
});
|
|
95
103
|
|
|
104
|
+
const udlJourneyStepSchema = z.strictObject({
|
|
105
|
+
bind: z.record(fieldPathSchema, udlSnakeCaseSchema),
|
|
106
|
+
example: udlSnakeCaseSchema,
|
|
107
|
+
id: udlSnakeCaseSchema.optional(),
|
|
108
|
+
operation: udlJourneyOperationNameSchema,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export const udlJourneySchema = z.strictObject({
|
|
112
|
+
id: udlSnakeCaseSchema,
|
|
113
|
+
label: nonEmptyTextSchema,
|
|
114
|
+
steps: z.array(udlJourneyStepSchema).min(1),
|
|
115
|
+
summary: nonEmptyTextSchema,
|
|
116
|
+
});
|
|
117
|
+
|
|
96
118
|
const udlLifecycleTransitionSchema = z.strictObject({
|
|
97
119
|
from: z.array(udlSnakeCaseSchema).min(1),
|
|
98
120
|
to: udlSnakeCaseSchema,
|
|
@@ -110,9 +132,18 @@ const udlUpdatePolicySchema = z.strictObject({
|
|
|
110
132
|
states: z.array(udlSnakeCaseSchema).min(1),
|
|
111
133
|
});
|
|
112
134
|
|
|
135
|
+
const udlDateComparisonOperatorSchema = z.enum([">=", ">", "<=", "<", "=="]);
|
|
136
|
+
|
|
137
|
+
const udlDateComparisonSchema = z.strictObject({
|
|
138
|
+
localPath: fieldPathSchema,
|
|
139
|
+
operator: udlDateComparisonOperatorSchema,
|
|
140
|
+
referencedPath: fieldPathSchema,
|
|
141
|
+
});
|
|
142
|
+
|
|
113
143
|
const udlGateSchema = z.strictObject({
|
|
114
144
|
/** Local field key <- referenced instance path; create actions only. */
|
|
115
145
|
bind: z.record(udlFieldNameSchema, fieldPathSchema).optional(),
|
|
146
|
+
dateComparison: udlDateComparisonSchema.optional(),
|
|
116
147
|
field: udlFieldNameSchema,
|
|
117
148
|
/** Local instance path === referenced instance path at admission. */
|
|
118
149
|
match: z.record(fieldPathSchema, fieldPathSchema).optional(),
|
|
@@ -329,10 +360,10 @@ const udlExposureRequirementSchema = z.strictObject({
|
|
|
329
360
|
// The tenant-backend decision port: the action's caller asserts the acting
|
|
330
361
|
// party, checked at admission against the instrument's party bindings for the
|
|
331
362
|
// allowed roles.
|
|
363
|
+
const udlPartyRoleSchema = z.string().regex(/^[a-z][A-Za-z0-9_]*$/);
|
|
364
|
+
|
|
332
365
|
const udlPortSchema = z.strictObject({
|
|
333
|
-
allowedParties: z
|
|
334
|
-
.array(z.enum(["payer", "beneficiary", "subjectHolder"]))
|
|
335
|
-
.min(1),
|
|
366
|
+
allowedParties: z.array(udlPartyRoleSchema).min(1),
|
|
336
367
|
});
|
|
337
368
|
|
|
338
369
|
const udlPayoutSchema = z.strictObject({
|
|
@@ -686,14 +717,9 @@ const udlInstrumentShape = {
|
|
|
686
717
|
.string()
|
|
687
718
|
.regex(idPrefixPattern, "must contain 2 to 8 lowercase letters"),
|
|
688
719
|
lifecycle: udlLifecycleSchema,
|
|
720
|
+
journeys: z.array(udlJourneySchema).min(1).optional(),
|
|
689
721
|
nav: z.array(nonEmptyTextSchema).min(1).optional(),
|
|
690
|
-
parties: z
|
|
691
|
-
.strictObject({
|
|
692
|
-
beneficiary: udlFieldNameSchema.optional(),
|
|
693
|
-
payer: udlFieldNameSchema.optional(),
|
|
694
|
-
subjectHolder: udlFieldNameSchema.optional(),
|
|
695
|
-
})
|
|
696
|
-
.optional(),
|
|
722
|
+
parties: z.record(udlPartyRoleSchema, udlFieldNameSchema).optional(),
|
|
697
723
|
partitions: z.array(udlPartitionSchema).min(1).optional(),
|
|
698
724
|
required: z.array(udlFieldNameSchema),
|
|
699
725
|
subject: udlInstrumentSubjectSchema.optional(),
|
|
@@ -1099,6 +1125,12 @@ export const udlClauseVocabulary = [
|
|
|
1099
1125
|
spelling: "id prefix",
|
|
1100
1126
|
target: "idPrefix",
|
|
1101
1127
|
},
|
|
1128
|
+
{
|
|
1129
|
+
cardinality: "many",
|
|
1130
|
+
scope: "instrument",
|
|
1131
|
+
spelling: "journeys",
|
|
1132
|
+
target: "journeys",
|
|
1133
|
+
},
|
|
1102
1134
|
{
|
|
1103
1135
|
cardinality: "many",
|
|
1104
1136
|
scope: "instrument",
|
|
@@ -1330,6 +1362,10 @@ export type UdlDocument = z.infer<typeof udlDocumentSchema>;
|
|
|
1330
1362
|
export type UdlDue = z.infer<typeof udlDueSchema>;
|
|
1331
1363
|
export type UdlEffects = z.infer<typeof udlEffectsSchema>;
|
|
1332
1364
|
export type UdlExample = z.infer<typeof udlExampleSchema>;
|
|
1365
|
+
export type UdlDateComparison = z.infer<typeof udlDateComparisonSchema>;
|
|
1366
|
+
export type UdlDateComparisonOperator = z.infer<
|
|
1367
|
+
typeof udlDateComparisonOperatorSchema
|
|
1368
|
+
>;
|
|
1333
1369
|
export type UdlGate = z.infer<typeof udlGateSchema>;
|
|
1334
1370
|
export type UdlKernelOperation = z.infer<typeof udlKernelOperationSchema>;
|
|
1335
1371
|
export type UdlLifecycle = z.infer<typeof udlLifecycleSchema>;
|
|
@@ -1338,6 +1374,8 @@ export type UdlLifecycleTransition = z.infer<
|
|
|
1338
1374
|
>;
|
|
1339
1375
|
export type UdlInstrument = z.infer<typeof udlInstrumentSchema>;
|
|
1340
1376
|
export type UdlInstrumentSubject = z.infer<typeof udlInstrumentSubjectSchema>;
|
|
1377
|
+
export type UdlJourney = z.infer<typeof udlJourneySchema>;
|
|
1378
|
+
export type UdlJourneyStep = z.infer<typeof udlJourneyStepSchema>;
|
|
1341
1379
|
export type UdlMove = z.infer<typeof udlMoveSchema>;
|
|
1342
1380
|
export type UdlPayout = z.infer<typeof udlPayoutSchema>;
|
|
1343
1381
|
export type UdlQuote = z.infer<typeof udlQuoteSchema>;
|