@hyperscale0/udl 4.5.1 → 4.6.1
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 +11 -0
- package/dist/field-value.d.ts +5 -0
- package/dist/field-value.d.ts.map +1 -0
- package/dist/field-value.js +85 -0
- package/dist/field-value.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/object-contract.d.ts +35 -12
- package/dist/object-contract.d.ts.map +1 -1
- package/dist/object-contract.js +33 -91
- package/dist/object-contract.js.map +1 -1
- package/dist/object-semantics-schema.d.ts +5565 -0
- package/dist/object-semantics-schema.d.ts.map +1 -0
- package/dist/object-semantics-schema.js +119 -0
- package/dist/object-semantics-schema.js.map +1 -0
- package/dist/object-semantics.d.ts +6 -0
- package/dist/object-semantics.d.ts.map +1 -0
- package/dist/object-semantics.js +279 -0
- package/dist/object-semantics.js.map +1 -0
- package/dist/object-structures.d.ts +4 -0
- package/dist/object-structures.d.ts.map +1 -0
- package/dist/object-structures.js +134 -0
- package/dist/object-structures.js.map +1 -0
- package/dist/schema.d.ts +205 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +5 -1
- package/dist/schema.js.map +1 -1
- package/dist/validation.js +1 -1
- package/dist/validation.js.map +1 -1
- package/package.json +2 -2
- package/spec/udl.schema.json +296 -245
- package/src/field-value.ts +87 -0
- package/src/index.ts +1 -0
- package/src/object-contract.ts +87 -99
- package/src/object-semantics-schema.ts +148 -0
- package/src/object-semantics.ts +378 -0
- package/src/object-structures.ts +255 -0
- package/src/schema.ts +5 -1
- package/src/validation.ts +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { udlObjectIdSchema, type UdlField } from "./schema.js";
|
|
3
|
+
|
|
4
|
+
const amount = z.string().regex(/^(0|[1-9][0-9]{0,17})$/);
|
|
5
|
+
const text = z.string().min(1).max(2048);
|
|
6
|
+
|
|
7
|
+
/** Values, rather than declarations. The same validator feeds forms and admission. */
|
|
8
|
+
export function udlFieldValueSchema(field: UdlField): z.ZodType {
|
|
9
|
+
let schema: z.ZodType;
|
|
10
|
+
switch (field.type) {
|
|
11
|
+
case "money":
|
|
12
|
+
schema = amount
|
|
13
|
+
.refine(
|
|
14
|
+
(value) =>
|
|
15
|
+
/^(0|[1-9][0-9]{0,17})$/.test(value) &&
|
|
16
|
+
(field.minimum === undefined ||
|
|
17
|
+
BigInt(value) >= BigInt(field.minimum)) &&
|
|
18
|
+
(field.maximum === undefined ||
|
|
19
|
+
BigInt(value) <= BigInt(field.maximum)),
|
|
20
|
+
"Money is outside its declared bounds",
|
|
21
|
+
)
|
|
22
|
+
.meta({
|
|
23
|
+
...(field.minimum !== undefined
|
|
24
|
+
? { "x-udl-minimum": field.minimum }
|
|
25
|
+
: {}),
|
|
26
|
+
...(field.maximum !== undefined
|
|
27
|
+
? { "x-udl-maximum": field.maximum }
|
|
28
|
+
: {}),
|
|
29
|
+
});
|
|
30
|
+
break;
|
|
31
|
+
case "account":
|
|
32
|
+
schema = text;
|
|
33
|
+
break;
|
|
34
|
+
case "ref":
|
|
35
|
+
schema = field.targetKind === "object" ? udlObjectIdSchema : text;
|
|
36
|
+
break;
|
|
37
|
+
case "date":
|
|
38
|
+
schema = z.iso.datetime({ offset: true });
|
|
39
|
+
break;
|
|
40
|
+
case "duration":
|
|
41
|
+
schema = z.number().int().safe().positive();
|
|
42
|
+
break;
|
|
43
|
+
case "text": {
|
|
44
|
+
let value = z
|
|
45
|
+
.string()
|
|
46
|
+
.min(field.minLength ?? 1)
|
|
47
|
+
.max(field.maxLength ?? 2048);
|
|
48
|
+
if (field.pattern) value = value.regex(new RegExp(field.pattern));
|
|
49
|
+
schema = value;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "integer": {
|
|
53
|
+
let value = z.number().int().safe();
|
|
54
|
+
if (field.minimum !== undefined) value = value.min(field.minimum);
|
|
55
|
+
if (field.maximum !== undefined) value = value.max(field.maximum);
|
|
56
|
+
schema = value;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "percent":
|
|
60
|
+
schema = z.number().int().min(0).max(10000);
|
|
61
|
+
break;
|
|
62
|
+
case "boolean":
|
|
63
|
+
schema = z.boolean();
|
|
64
|
+
break;
|
|
65
|
+
case "enum":
|
|
66
|
+
schema = z.enum(field.values);
|
|
67
|
+
break;
|
|
68
|
+
case "list": {
|
|
69
|
+
const item =
|
|
70
|
+
field.item === "money"
|
|
71
|
+
? amount
|
|
72
|
+
: field.item === "date"
|
|
73
|
+
? z.iso.datetime({ offset: true })
|
|
74
|
+
: field.item === "integer"
|
|
75
|
+
? z.number().int().safe()
|
|
76
|
+
: field.item === "ref" && field.targetKind === "object"
|
|
77
|
+
? udlObjectIdSchema
|
|
78
|
+
: text;
|
|
79
|
+
schema = z.array(item).max(field.maxItems);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if ("value" in field && field.value !== undefined)
|
|
84
|
+
schema = z.literal(field.value);
|
|
85
|
+
if (field.description) schema = schema.describe(field.description);
|
|
86
|
+
return schema;
|
|
87
|
+
}
|
package/src/index.ts
CHANGED
package/src/object-contract.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
import { udlFieldValueSchema } from "./field-value.js";
|
|
3
|
+
import {
|
|
4
|
+
projectDocumentSemantics,
|
|
5
|
+
presentationLabel,
|
|
6
|
+
} from "./object-semantics.js";
|
|
7
|
+
import type { DocumentSemantics } from "./object-semantics-schema.js";
|
|
8
|
+
export * from "./object-semantics-schema.js";
|
|
9
|
+
export {
|
|
10
|
+
projectDocumentSemantics,
|
|
11
|
+
presentationLabel,
|
|
12
|
+
} from "./object-semantics.js";
|
|
2
13
|
import {
|
|
3
14
|
udlExternalIdSchema,
|
|
4
|
-
udlObjectIdSchema,
|
|
5
15
|
type UdlDocument,
|
|
6
|
-
type UdlField,
|
|
7
16
|
type UdlObjectField,
|
|
8
17
|
type UdlObjectKind,
|
|
9
18
|
type UdlSubjectRequirement,
|
|
@@ -43,9 +52,30 @@ export interface ObjectKindDiscovery {
|
|
|
43
52
|
fields: readonly UdlObjectField[];
|
|
44
53
|
authoredFields: readonly string[];
|
|
45
54
|
columns: readonly string[];
|
|
55
|
+
filters: readonly {
|
|
56
|
+
field: string;
|
|
57
|
+
type: "text" | "enum" | "date" | "boolean" | "integer";
|
|
58
|
+
}[];
|
|
46
59
|
createSchema: JsonSchemaDocument;
|
|
47
60
|
actions: readonly ObjectActionDiscovery[];
|
|
48
61
|
}
|
|
62
|
+
export function objectKindFilters(
|
|
63
|
+
kind: UdlObjectKind,
|
|
64
|
+
): ObjectKindDiscovery["filters"] {
|
|
65
|
+
return kind.columns.flatMap((column) => {
|
|
66
|
+
const field = kind.fields.find((item) => item.name === column);
|
|
67
|
+
return field &&
|
|
68
|
+
!field.sensitive &&
|
|
69
|
+
["text", "enum", "date", "boolean", "integer"].includes(field.type)
|
|
70
|
+
? [
|
|
71
|
+
{
|
|
72
|
+
field: column,
|
|
73
|
+
type: field.type as ObjectKindDiscovery["filters"][number]["type"],
|
|
74
|
+
},
|
|
75
|
+
]
|
|
76
|
+
: [];
|
|
77
|
+
});
|
|
78
|
+
}
|
|
49
79
|
export type ObjectActionTarget =
|
|
50
80
|
| { kind: "attachment"; attachment: string }
|
|
51
81
|
| { kind: "instance"; attachment: string; instanceId: string };
|
|
@@ -69,10 +99,41 @@ export interface ObjectActionDiscovery extends ObjectActionContext {
|
|
|
69
99
|
creationOnlyNames?: readonly string[];
|
|
70
100
|
inputSchema: JsonSchemaDocument;
|
|
71
101
|
fieldsSchema: JsonSchemaDocument;
|
|
72
|
-
availability:
|
|
73
|
-
| { status: "available" }
|
|
74
|
-
| { status: "unavailable"; code: string; message: string };
|
|
102
|
+
availability: ObjectActionAvailability;
|
|
75
103
|
}
|
|
104
|
+
export type ObjectActionBlockerCode =
|
|
105
|
+
| "permission_required"
|
|
106
|
+
| "state_changed"
|
|
107
|
+
| "not_due"
|
|
108
|
+
| "deadline_passed"
|
|
109
|
+
| "clock_pending"
|
|
110
|
+
| "condition_not_met"
|
|
111
|
+
| "already_used"
|
|
112
|
+
| "evidence_required"
|
|
113
|
+
| "account_unavailable"
|
|
114
|
+
| "insufficient_money"
|
|
115
|
+
| "setup_required"
|
|
116
|
+
| "invalid_input"
|
|
117
|
+
| "operation_pending";
|
|
118
|
+
export type ObjectActionAvailability =
|
|
119
|
+
| { status: "available" }
|
|
120
|
+
| {
|
|
121
|
+
status: "requires_input";
|
|
122
|
+
subjectFields: readonly string[];
|
|
123
|
+
actionInputs: readonly string[];
|
|
124
|
+
parties: readonly string[];
|
|
125
|
+
reason: string;
|
|
126
|
+
}
|
|
127
|
+
| {
|
|
128
|
+
status: "unavailable";
|
|
129
|
+
blockers: readonly {
|
|
130
|
+
code: ObjectActionBlockerCode;
|
|
131
|
+
reason: string;
|
|
132
|
+
recheckAt?: string;
|
|
133
|
+
}[];
|
|
134
|
+
}
|
|
135
|
+
| { status: "unknown"; reason: string };
|
|
136
|
+
|
|
76
137
|
export type EvidenceState =
|
|
77
138
|
| "missing"
|
|
78
139
|
| "pending"
|
|
@@ -100,13 +161,14 @@ export interface ObjectActionState extends ObjectActionDiscovery {
|
|
|
100
161
|
/** GET /v1/products/{productId}/objects. Core supplies the frozen Build identity. */
|
|
101
162
|
export type RetainedObjectKind = Pick<
|
|
102
163
|
ObjectKindDiscovery,
|
|
103
|
-
"kind" | "title" | "fields" | "authoredFields" | "columns"
|
|
164
|
+
"kind" | "title" | "fields" | "authoredFields" | "columns" | "filters"
|
|
104
165
|
> & {
|
|
105
166
|
productBuildId: string;
|
|
106
167
|
digest: string;
|
|
107
168
|
creation: false;
|
|
108
169
|
};
|
|
109
170
|
export interface ObjectDiscovery {
|
|
171
|
+
semantics: DocumentSemantics;
|
|
110
172
|
navigation: readonly { kind: string; title: string; creation: boolean }[];
|
|
111
173
|
retainedKinds: readonly RetainedObjectKind[];
|
|
112
174
|
productBuildId: string;
|
|
@@ -131,6 +193,8 @@ export interface ObjectInstance {
|
|
|
131
193
|
export interface ObjectListResponse {
|
|
132
194
|
items: ObjectInstance[];
|
|
133
195
|
nextCursor?: string;
|
|
196
|
+
total: number;
|
|
197
|
+
facets: Record<string, Record<string, number>>;
|
|
134
198
|
}
|
|
135
199
|
export interface ObjectActionResponse {
|
|
136
200
|
object: ObjectInstance;
|
|
@@ -138,90 +202,6 @@ export interface ObjectActionResponse {
|
|
|
138
202
|
evidence: readonly ObjectEvidenceSummary[];
|
|
139
203
|
}
|
|
140
204
|
|
|
141
|
-
const amount = z.string().regex(/^(0|[1-9][0-9]{0,17})$/);
|
|
142
|
-
const text = z.string().min(1).max(2048);
|
|
143
|
-
|
|
144
|
-
/** Values, rather than declarations. The same validator feeds forms and admission. */
|
|
145
|
-
export function udlFieldValueSchema(field: UdlField): z.ZodType {
|
|
146
|
-
let schema: z.ZodType;
|
|
147
|
-
switch (field.type) {
|
|
148
|
-
case "money":
|
|
149
|
-
schema = amount
|
|
150
|
-
.refine(
|
|
151
|
-
(value) =>
|
|
152
|
-
/^(0|[1-9][0-9]{0,17})$/.test(value) &&
|
|
153
|
-
(field.minimum === undefined ||
|
|
154
|
-
BigInt(value) >= BigInt(field.minimum)) &&
|
|
155
|
-
(field.maximum === undefined ||
|
|
156
|
-
BigInt(value) <= BigInt(field.maximum)),
|
|
157
|
-
"Money is outside its declared bounds",
|
|
158
|
-
)
|
|
159
|
-
.meta({
|
|
160
|
-
...(field.minimum !== undefined
|
|
161
|
-
? { "x-udl-minimum": field.minimum }
|
|
162
|
-
: {}),
|
|
163
|
-
...(field.maximum !== undefined
|
|
164
|
-
? { "x-udl-maximum": field.maximum }
|
|
165
|
-
: {}),
|
|
166
|
-
});
|
|
167
|
-
break;
|
|
168
|
-
case "account":
|
|
169
|
-
schema = text;
|
|
170
|
-
break;
|
|
171
|
-
case "ref":
|
|
172
|
-
schema = field.targetKind === "object" ? udlObjectIdSchema : text;
|
|
173
|
-
break;
|
|
174
|
-
case "date":
|
|
175
|
-
schema = z.iso.datetime({ offset: true });
|
|
176
|
-
break;
|
|
177
|
-
case "duration":
|
|
178
|
-
schema = z.number().int().safe().positive();
|
|
179
|
-
break;
|
|
180
|
-
case "text": {
|
|
181
|
-
let value = z
|
|
182
|
-
.string()
|
|
183
|
-
.min(field.minLength ?? 1)
|
|
184
|
-
.max(field.maxLength ?? 2048);
|
|
185
|
-
if (field.pattern) value = value.regex(new RegExp(field.pattern));
|
|
186
|
-
schema = value;
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
case "integer": {
|
|
190
|
-
let value = z.number().int().safe();
|
|
191
|
-
if (field.minimum !== undefined) value = value.min(field.minimum);
|
|
192
|
-
if (field.maximum !== undefined) value = value.max(field.maximum);
|
|
193
|
-
schema = value;
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
case "percent":
|
|
197
|
-
schema = z.number().int().min(0).max(10000);
|
|
198
|
-
break;
|
|
199
|
-
case "boolean":
|
|
200
|
-
schema = z.boolean();
|
|
201
|
-
break;
|
|
202
|
-
case "enum":
|
|
203
|
-
schema = z.enum(field.values);
|
|
204
|
-
break;
|
|
205
|
-
case "list": {
|
|
206
|
-
const item =
|
|
207
|
-
field.item === "money"
|
|
208
|
-
? amount
|
|
209
|
-
: field.item === "date"
|
|
210
|
-
? z.iso.datetime({ offset: true })
|
|
211
|
-
: field.item === "integer"
|
|
212
|
-
? z.number().int().safe()
|
|
213
|
-
: field.item === "ref" && field.targetKind === "object"
|
|
214
|
-
? udlObjectIdSchema
|
|
215
|
-
: text;
|
|
216
|
-
schema = z.array(item).max(field.maxItems);
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
if ("value" in field && field.value !== undefined)
|
|
221
|
-
schema = z.literal(field.value);
|
|
222
|
-
if (field.description) schema = schema.describe(field.description);
|
|
223
|
-
return schema;
|
|
224
|
-
}
|
|
225
205
|
/** Creation accepts the full metadata union, with every value optional. */
|
|
226
206
|
export function objectCreateSchema(kind: UdlObjectKind): z.ZodObject {
|
|
227
207
|
return z.strictObject({
|
|
@@ -239,20 +219,22 @@ export function objectCreateSchema(kind: UdlObjectKind): z.ZodObject {
|
|
|
239
219
|
});
|
|
240
220
|
}
|
|
241
221
|
|
|
242
|
-
/** Canonical UDL supplies meaning; core adds authority,
|
|
222
|
+
/** Canonical UDL supplies meaning; core adds authority, instance state and readiness. */
|
|
243
223
|
export function projectObjectDiscovery(
|
|
244
224
|
document: UdlDocument,
|
|
245
225
|
build: Pick<ObjectDiscovery, "productBuildId" | "digest">,
|
|
246
226
|
): ObjectDiscovery {
|
|
227
|
+
const semantics = projectDocumentSemantics(document);
|
|
247
228
|
return {
|
|
248
229
|
...build,
|
|
230
|
+
semantics,
|
|
249
231
|
navigation: document.objects.map((kind) => ({
|
|
250
232
|
kind: kind.id,
|
|
251
233
|
title: kind.title,
|
|
252
234
|
creation: true,
|
|
253
235
|
})),
|
|
254
236
|
retainedKinds: [],
|
|
255
|
-
kinds:
|
|
237
|
+
kinds: semantics.objects.map((kind) => ({
|
|
256
238
|
...build,
|
|
257
239
|
creation: true,
|
|
258
240
|
kind: kind.id,
|
|
@@ -260,6 +242,7 @@ export function projectObjectDiscovery(
|
|
|
260
242
|
fields: kind.fields,
|
|
261
243
|
authoredFields: kind.authoredFields,
|
|
262
244
|
columns: kind.columns,
|
|
245
|
+
filters: objectKindFilters(kind),
|
|
263
246
|
createSchema: z.toJSONSchema(objectCreateSchema(kind), { io: "input" }),
|
|
264
247
|
actions: document.instruments
|
|
265
248
|
.filter((instrument) => instrument.subject === kind.id)
|
|
@@ -344,9 +327,7 @@ export function projectObjectDiscovery(
|
|
|
344
327
|
)!.name,
|
|
345
328
|
},
|
|
346
329
|
name: action.publicAction,
|
|
347
|
-
title: action.publicAction
|
|
348
|
-
.replace(/_/g, " ")
|
|
349
|
-
.replace(/^./, (letter) => letter.toUpperCase()),
|
|
330
|
+
title: action.title ?? presentationLabel(action.publicAction),
|
|
350
331
|
summary: action.summary,
|
|
351
332
|
instrument: instrument.id,
|
|
352
333
|
action: name,
|
|
@@ -393,8 +374,13 @@ export function projectObjectDiscovery(
|
|
|
393
374
|
availability: unbound
|
|
394
375
|
? {
|
|
395
376
|
status: "unavailable" as const,
|
|
396
|
-
|
|
397
|
-
|
|
377
|
+
blockers: [
|
|
378
|
+
{
|
|
379
|
+
code: "setup_required" as const,
|
|
380
|
+
reason:
|
|
381
|
+
"A required external check has not been set up.",
|
|
382
|
+
},
|
|
383
|
+
],
|
|
398
384
|
}
|
|
399
385
|
: { status: "available" as const },
|
|
400
386
|
},
|
|
@@ -559,13 +545,15 @@ export function validateObjectActionSubject(
|
|
|
559
545
|
const issues: SubjectRequirementIssue[] = [];
|
|
560
546
|
if (
|
|
561
547
|
action.availability.status === "unavailable" &&
|
|
562
|
-
action.availability.
|
|
548
|
+
action.availability.blockers.some(
|
|
549
|
+
(blocker) => blocker.code === "setup_required",
|
|
550
|
+
)
|
|
563
551
|
) {
|
|
564
552
|
issues.push({
|
|
565
553
|
code: "subject_adapter_unbound",
|
|
566
554
|
action: action.name,
|
|
567
555
|
origin,
|
|
568
|
-
message:
|
|
556
|
+
message: "A required external check has not been set up.",
|
|
569
557
|
});
|
|
570
558
|
}
|
|
571
559
|
const admitted = new Set(action.requirements.map((field) => field.name));
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import {
|
|
3
|
+
udlActionSchema,
|
|
4
|
+
udlCalculationSchema,
|
|
5
|
+
udlFieldSchema,
|
|
6
|
+
udlInstrumentSchema,
|
|
7
|
+
udlObjectKindSchema,
|
|
8
|
+
udlObjectAttachmentSchema,
|
|
9
|
+
udlPartySchema,
|
|
10
|
+
udlRequirementSchema,
|
|
11
|
+
udlValueSchema,
|
|
12
|
+
udlKernelOperationSchema,
|
|
13
|
+
subjectPartyRoles,
|
|
14
|
+
} from "./schema.js";
|
|
15
|
+
|
|
16
|
+
const text = z.string();
|
|
17
|
+
export const cardinalitySchema = z.strictObject({
|
|
18
|
+
min: z.number().int().nonnegative(),
|
|
19
|
+
// null means the declarations supply no upper bound.
|
|
20
|
+
max: z.number().int().nonnegative().nullable(),
|
|
21
|
+
});
|
|
22
|
+
export const semanticOwnerSchema = z.union([
|
|
23
|
+
z.strictObject({ kind: z.literal("instrument"), instrument: text }),
|
|
24
|
+
z.strictObject({ kind: z.literal("role"), role: z.enum(subjectPartyRoles) }),
|
|
25
|
+
z.strictObject({ kind: z.literal("party"), party: text }),
|
|
26
|
+
z.strictObject({ kind: z.literal("adapter"), adapter: text }),
|
|
27
|
+
]);
|
|
28
|
+
export const semanticAccountSchema = z.strictObject({
|
|
29
|
+
path: text,
|
|
30
|
+
scope: text,
|
|
31
|
+
instrument: text,
|
|
32
|
+
field: text,
|
|
33
|
+
owner: semanticOwnerSchema,
|
|
34
|
+
book: z.enum(["cash", "claim"]),
|
|
35
|
+
key: text.optional(),
|
|
36
|
+
contra: z.boolean(),
|
|
37
|
+
});
|
|
38
|
+
export const semanticRoleSchema = z.union([
|
|
39
|
+
semanticOwnerSchema,
|
|
40
|
+
z.strictObject({ kind: z.enum(["caller", "clock"]) }),
|
|
41
|
+
z.strictObject({ kind: z.literal("parent"), instruments: z.array(text) }),
|
|
42
|
+
]);
|
|
43
|
+
export const semanticRelationshipSchema = z.strictObject({
|
|
44
|
+
kind: z.enum(["reference", "child"]),
|
|
45
|
+
via: z.enum(["field", "attachment", "invocation", "parent_actor"]),
|
|
46
|
+
name: text,
|
|
47
|
+
targetKind: z.enum(["instrument", "object"]),
|
|
48
|
+
targets: z.array(text),
|
|
49
|
+
cardinality: cardinalitySchema,
|
|
50
|
+
});
|
|
51
|
+
export const semanticMoneyEffectSchema = z.strictObject({
|
|
52
|
+
key: text,
|
|
53
|
+
operation: udlKernelOperationSchema,
|
|
54
|
+
amount: udlValueSchema.nullable(),
|
|
55
|
+
from: z.array(semanticAccountSchema),
|
|
56
|
+
to: z.array(semanticAccountSchema),
|
|
57
|
+
// Expressions describe declared effects, never a receipt or evaluated quote.
|
|
58
|
+
disposition: z.enum(["held", "paid", "released", "claim", "unresolved"]),
|
|
59
|
+
transfer: text.nullable(),
|
|
60
|
+
reservations: z.array(
|
|
61
|
+
z.strictObject({ instrument: text, action: text, key: text }),
|
|
62
|
+
),
|
|
63
|
+
});
|
|
64
|
+
export const semanticActionSchema = z.strictObject({
|
|
65
|
+
name: text,
|
|
66
|
+
alias: text.nullable(),
|
|
67
|
+
title: text,
|
|
68
|
+
actor: udlActionSchema.shape.actor,
|
|
69
|
+
roles: z.array(semanticRoleSchema),
|
|
70
|
+
from: z.array(text),
|
|
71
|
+
to: text.nullable(),
|
|
72
|
+
references: z.array(udlFieldSchema).optional(),
|
|
73
|
+
invokedBy: z
|
|
74
|
+
.array(
|
|
75
|
+
z.strictObject({
|
|
76
|
+
instrument: text,
|
|
77
|
+
action: text,
|
|
78
|
+
alias: text.nullable(),
|
|
79
|
+
invocation: udlActionSchema.shape.invoke.unwrap().element,
|
|
80
|
+
}),
|
|
81
|
+
)
|
|
82
|
+
.optional(),
|
|
83
|
+
inputs: udlActionSchema.shape.input,
|
|
84
|
+
subject: udlActionSchema.shape.subject,
|
|
85
|
+
prerequisites: udlActionSchema.shape.requires,
|
|
86
|
+
due: udlActionSchema.shape.due.unwrap().nullable(),
|
|
87
|
+
deadline: udlActionSchema.shape.deadline.unwrap().nullable(),
|
|
88
|
+
calculations: z.array(udlCalculationSchema),
|
|
89
|
+
assignments: udlActionSchema.shape.set.unwrap(),
|
|
90
|
+
moves: udlActionSchema.shape.moves,
|
|
91
|
+
moneyEffects: z.array(semanticMoneyEffectSchema),
|
|
92
|
+
invokes: udlActionSchema.shape.invoke.unwrap(),
|
|
93
|
+
});
|
|
94
|
+
export const semanticStructureSchema = z.enum([
|
|
95
|
+
"stage_and_decisions",
|
|
96
|
+
"payment_review",
|
|
97
|
+
"held_funds",
|
|
98
|
+
"reserved_payment",
|
|
99
|
+
"payment_calendar",
|
|
100
|
+
"funding_progress",
|
|
101
|
+
"cancellation_review",
|
|
102
|
+
"external_checks",
|
|
103
|
+
"report_view",
|
|
104
|
+
]);
|
|
105
|
+
export const semanticInstrumentSchema = z.strictObject({
|
|
106
|
+
id: text,
|
|
107
|
+
title: text,
|
|
108
|
+
subject: text.optional(),
|
|
109
|
+
fields: z.array(udlFieldSchema),
|
|
110
|
+
accounts: z.array(semanticAccountSchema),
|
|
111
|
+
relationships: z.array(semanticRelationshipSchema),
|
|
112
|
+
calculations: z.array(udlCalculationSchema),
|
|
113
|
+
invariants: z.array(udlRequirementSchema),
|
|
114
|
+
initialState: text,
|
|
115
|
+
lifecycle: z.strictObject({
|
|
116
|
+
initial: text,
|
|
117
|
+
states: z.array(
|
|
118
|
+
z.strictObject({ name: text, label: text, terminal: z.boolean() }),
|
|
119
|
+
),
|
|
120
|
+
cancellationActions: z.array(text),
|
|
121
|
+
}),
|
|
122
|
+
actions: z.array(semanticActionSchema),
|
|
123
|
+
reports: udlInstrumentSchema.shape.reports.unwrap(),
|
|
124
|
+
structures: z.array(semanticStructureSchema),
|
|
125
|
+
});
|
|
126
|
+
export const documentSemanticsSchema = z.strictObject({
|
|
127
|
+
currency: text,
|
|
128
|
+
parties: z.record(text, udlPartySchema),
|
|
129
|
+
objects: z.array(
|
|
130
|
+
z.strictObject({
|
|
131
|
+
...udlObjectKindSchema.shape,
|
|
132
|
+
attachments: z.array(
|
|
133
|
+
z.strictObject({
|
|
134
|
+
...udlObjectAttachmentSchema.shape,
|
|
135
|
+
cardinality: cardinalitySchema,
|
|
136
|
+
}),
|
|
137
|
+
),
|
|
138
|
+
}),
|
|
139
|
+
),
|
|
140
|
+
instruments: z.array(semanticInstrumentSchema),
|
|
141
|
+
});
|
|
142
|
+
export type DocumentSemantics = z.infer<typeof documentSemanticsSchema>;
|
|
143
|
+
export type SemanticInstrument = z.infer<typeof semanticInstrumentSchema>;
|
|
144
|
+
export type SemanticAction = z.infer<typeof semanticActionSchema>;
|
|
145
|
+
export type SemanticAccount = z.infer<typeof semanticAccountSchema>;
|
|
146
|
+
export type SemanticOwner = z.infer<typeof semanticOwnerSchema>;
|
|
147
|
+
export type SemanticRelationship = z.infer<typeof semanticRelationshipSchema>;
|
|
148
|
+
export type SemanticMoneyEffect = z.infer<typeof semanticMoneyEffectSchema>;
|