@hyperscale0/udl 1.0.0-alpha.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/AUTHORS +8 -0
- package/CHANGELOG.md +36 -0
- package/LICENSE +661 -0
- package/LICENSING.md +51 -0
- package/README.md +163 -0
- package/SECURITY.md +42 -0
- package/TRADEMARKS.md +35 -0
- package/conformance/README.md +79 -0
- package/conformance/invalid/blank-title.expected.json +10 -0
- package/conformance/invalid/blank-title.udl +50 -0
- package/conformance/invalid/depth-budget.expected.json +10 -0
- package/conformance/invalid/depth-budget.udl +49 -0
- package/conformance/invalid/format-version.expected.json +10 -0
- package/conformance/invalid/format-version.udl +50 -0
- package/conformance/invalid/invalid-utf8.expected.json +10 -0
- package/conformance/invalid/invalid-utf8.udl +1 -0
- package/conformance/invalid/malformed-json.expected.json +10 -0
- package/conformance/invalid/malformed-json.udl +1 -0
- package/conformance/invalid/missing-create-verb.expected.json +10 -0
- package/conformance/invalid/missing-create-verb.udl +45 -0
- package/conformance/invalid/not-an-object.expected.json +10 -0
- package/conformance/invalid/not-an-object.udl +1 -0
- package/conformance/invalid/noun-id-not-snake-case.expected.json +10 -0
- package/conformance/invalid/noun-id-not-snake-case.udl +50 -0
- package/conformance/invalid/unknown-key.expected.json +10 -0
- package/conformance/invalid/unknown-key.udl +51 -0
- package/conformance/invalid/unreachable-state.expected.json +10 -0
- package/conformance/invalid/unreachable-state.udl +51 -0
- package/conformance/invalid/verb-without-transition.expected.json +10 -0
- package/conformance/invalid/verb-without-transition.udl +55 -0
- package/conformance/valid/cards.expected.json +5 -0
- package/conformance/valid/cards.udl +1092 -0
- package/conformance/valid/commerce-escrow.expected.json +5 -0
- package/conformance/valid/commerce-escrow.udl +1011 -0
- package/conformance/valid/hand-edited.expected.json +5 -0
- package/conformance/valid/hand-edited.udl +1 -0
- package/conformance/valid/insured-car-marketplace.expected.json +5 -0
- package/conformance/valid/insured-car-marketplace.udl +831 -0
- package/conformance/valid/insured-travel.expected.json +5 -0
- package/conformance/valid/insured-travel.udl +2621 -0
- package/conformance/valid/minimal.expected.json +5 -0
- package/conformance/valid/minimal.udl +50 -0
- package/conformance/valid/protection.expected.json +5 -0
- package/conformance/valid/protection.udl +1136 -0
- package/dist/canonical.d.ts +2 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +35 -0
- package/dist/canonical.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +138 -0
- package/dist/cli.js.map +1 -0
- package/dist/duration.d.ts +3 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/duration.js +23 -0
- package/dist/duration.js.map +1 -0
- package/dist/evolution.d.ts +63 -0
- package/dist/evolution.d.ts.map +1 -0
- package/dist/evolution.js +345 -0
- package/dist/evolution.js.map +1 -0
- package/dist/finance.d.ts +53 -0
- package/dist/finance.d.ts.map +1 -0
- package/dist/finance.js +511 -0
- package/dist/finance.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/limits.d.ts +33 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +33 -0
- package/dist/limits.js.map +1 -0
- package/dist/parser.d.ts +4 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +54 -0
- package/dist/parser.js.map +1 -0
- package/dist/schema.d.ts +757 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +281 -0
- package/dist/schema.js.map +1 -0
- package/dist/validation.d.ts +64 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +1323 -0
- package/dist/validation.js.map +1 -0
- package/package.json +84 -0
- package/spec/README.md +137 -0
- package/spec/udl.schema.json +1019 -0
- package/src/canonical.ts +41 -0
- package/src/cli.ts +148 -0
- package/src/duration.ts +26 -0
- package/src/evolution.ts +587 -0
- package/src/finance.ts +775 -0
- package/src/index.ts +59 -0
- package/src/limits.ts +32 -0
- package/src/parser.ts +61 -0
- package/src/schema.ts +339 -0
- package/src/validation.ts +2053 -0
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nouns": [
|
|
3
|
+
{
|
|
4
|
+
"description": "A listing starts as a private draft, becomes buyable when published, stays unavailable while funded escrow reserves it, and ends sold, withdrawn, or expired without ever moving money itself.",
|
|
5
|
+
"fields": {
|
|
6
|
+
"askingPrice": {
|
|
7
|
+
"description": "Positive minor-unit integer amount serialized as a string (at most 18 digits)",
|
|
8
|
+
"pattern": "^[1-9][0-9]{0,17}$",
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"currency": {
|
|
12
|
+
"description": "ISO 4217 currency code",
|
|
13
|
+
"maxLength": 3,
|
|
14
|
+
"minLength": 3,
|
|
15
|
+
"pattern": "^[A-Z]{3}$",
|
|
16
|
+
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
"description": {
|
|
19
|
+
"maxLength": 2000,
|
|
20
|
+
"minLength": 1,
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"escrowOrderId": {
|
|
24
|
+
"description": "Escrow order whose held funds reserve this listing",
|
|
25
|
+
"pattern": "^eord_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
26
|
+
"type": "string"
|
|
27
|
+
},
|
|
28
|
+
"expiresAt": {
|
|
29
|
+
"format": "hyperscale-date-time",
|
|
30
|
+
"type": "string"
|
|
31
|
+
},
|
|
32
|
+
"headline": {
|
|
33
|
+
"maxLength": 120,
|
|
34
|
+
"minLength": 1,
|
|
35
|
+
"type": "string"
|
|
36
|
+
},
|
|
37
|
+
"imageUrl": {
|
|
38
|
+
"format": "hyperscale-uri",
|
|
39
|
+
"maxLength": 2000,
|
|
40
|
+
"type": "string"
|
|
41
|
+
},
|
|
42
|
+
"sellerAccountId": {
|
|
43
|
+
"description": "Hyperscale account ID",
|
|
44
|
+
"pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
45
|
+
"type": "string",
|
|
46
|
+
"x-hyperscale-reference-filter": {
|
|
47
|
+
"column": "role",
|
|
48
|
+
"values": [
|
|
49
|
+
"customer_balance"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"id": "listing",
|
|
55
|
+
"idPrefix": "lst",
|
|
56
|
+
"lifecycle": {
|
|
57
|
+
"initial": "draft",
|
|
58
|
+
"states": [
|
|
59
|
+
"draft",
|
|
60
|
+
"active",
|
|
61
|
+
"reserved",
|
|
62
|
+
"sold",
|
|
63
|
+
"withdrawn"
|
|
64
|
+
],
|
|
65
|
+
"transitions": {
|
|
66
|
+
"expire": {
|
|
67
|
+
"from": [
|
|
68
|
+
"active"
|
|
69
|
+
],
|
|
70
|
+
"to": "withdrawn"
|
|
71
|
+
},
|
|
72
|
+
"publish": {
|
|
73
|
+
"from": [
|
|
74
|
+
"draft"
|
|
75
|
+
],
|
|
76
|
+
"to": "active"
|
|
77
|
+
},
|
|
78
|
+
"reopen": {
|
|
79
|
+
"from": [
|
|
80
|
+
"reserved"
|
|
81
|
+
],
|
|
82
|
+
"to": "active"
|
|
83
|
+
},
|
|
84
|
+
"reserve": {
|
|
85
|
+
"from": [
|
|
86
|
+
"active"
|
|
87
|
+
],
|
|
88
|
+
"to": "reserved"
|
|
89
|
+
},
|
|
90
|
+
"sell": {
|
|
91
|
+
"from": [
|
|
92
|
+
"reserved"
|
|
93
|
+
],
|
|
94
|
+
"to": "sold"
|
|
95
|
+
},
|
|
96
|
+
"withdraw": {
|
|
97
|
+
"from": [
|
|
98
|
+
"draft",
|
|
99
|
+
"active"
|
|
100
|
+
],
|
|
101
|
+
"to": "withdrawn"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"parties": {
|
|
106
|
+
"subjectHolder": "sellerAccountId"
|
|
107
|
+
},
|
|
108
|
+
"required": [
|
|
109
|
+
"sellerAccountId",
|
|
110
|
+
"headline",
|
|
111
|
+
"askingPrice",
|
|
112
|
+
"currency"
|
|
113
|
+
],
|
|
114
|
+
"subject": {
|
|
115
|
+
"kinds": [
|
|
116
|
+
"vehicle",
|
|
117
|
+
"merchandise"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"summary": "Subject-backed offer published by a seller.",
|
|
121
|
+
"title": "Listing",
|
|
122
|
+
"update": {
|
|
123
|
+
"fields": [
|
|
124
|
+
"headline",
|
|
125
|
+
"description",
|
|
126
|
+
"askingPrice",
|
|
127
|
+
"imageUrl",
|
|
128
|
+
"escrowOrderId",
|
|
129
|
+
"expiresAt"
|
|
130
|
+
],
|
|
131
|
+
"states": [
|
|
132
|
+
"draft",
|
|
133
|
+
"active"
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"verbs": {
|
|
137
|
+
"create": {
|
|
138
|
+
"description": "Creates a private offer against one subject. Publishing is a separate, explicit decision.",
|
|
139
|
+
"examples": [
|
|
140
|
+
{
|
|
141
|
+
"input": {
|
|
142
|
+
"askingPrice": "240000",
|
|
143
|
+
"currency": "SAR",
|
|
144
|
+
"description": "Single owner, full service history, sold under escrow protection.",
|
|
145
|
+
"expiresAt": "2026-08-31T21:00:00.000Z",
|
|
146
|
+
"headline": "2021 Toyota Land Cruiser GXR",
|
|
147
|
+
"imageUrl": "https://cdn.sandbox.example/listings/landcruiser-2021.jpg",
|
|
148
|
+
"sellerAccountId": "acct_sandbox_seller0001",
|
|
149
|
+
"subject": "sbj_sandbox_landcruiser1"
|
|
150
|
+
},
|
|
151
|
+
"name": "draft_vehicle_offer"
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"moves": [],
|
|
155
|
+
"steps": [],
|
|
156
|
+
"summary": "Draft a listing"
|
|
157
|
+
},
|
|
158
|
+
"expire": {
|
|
159
|
+
"description": "Withdraws an active offer at its declared expiry under the machine principal.",
|
|
160
|
+
"due": {
|
|
161
|
+
"field": "expiresAt"
|
|
162
|
+
},
|
|
163
|
+
"moves": [],
|
|
164
|
+
"steps": [],
|
|
165
|
+
"summary": "Expire a listing"
|
|
166
|
+
},
|
|
167
|
+
"publish": {
|
|
168
|
+
"description": "Makes the draft visible and buyable.",
|
|
169
|
+
"moves": [],
|
|
170
|
+
"steps": [],
|
|
171
|
+
"summary": "Publish a listing"
|
|
172
|
+
},
|
|
173
|
+
"reopen": {
|
|
174
|
+
"description": "Returns the offer to the market after escrow closes without releasing money to the seller.",
|
|
175
|
+
"moves": [],
|
|
176
|
+
"requiresRefs": [
|
|
177
|
+
{
|
|
178
|
+
"field": "escrowOrderId",
|
|
179
|
+
"match": {
|
|
180
|
+
"nounInstanceId": "fields.listingId"
|
|
181
|
+
},
|
|
182
|
+
"statuses": [
|
|
183
|
+
"refunded",
|
|
184
|
+
"penalty_collected",
|
|
185
|
+
"canceled",
|
|
186
|
+
"expired"
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
"steps": [],
|
|
191
|
+
"summary": "Reopen a listing"
|
|
192
|
+
},
|
|
193
|
+
"reserve": {
|
|
194
|
+
"description": "Takes the offer off the market only while its referenced escrow order holds the buyer's funds for this exact listing at its exact economics.",
|
|
195
|
+
"moves": [],
|
|
196
|
+
"requiresRefs": [
|
|
197
|
+
{
|
|
198
|
+
"field": "escrowOrderId",
|
|
199
|
+
"match": {
|
|
200
|
+
"fields.askingPrice": "fields.amount",
|
|
201
|
+
"fields.currency": "fields.currency",
|
|
202
|
+
"fields.sellerAccountId": "fields.sellerAccountId",
|
|
203
|
+
"nounInstanceId": "fields.listingId"
|
|
204
|
+
},
|
|
205
|
+
"statuses": [
|
|
206
|
+
"funded"
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
"steps": [],
|
|
211
|
+
"summary": "Reserve a listing"
|
|
212
|
+
},
|
|
213
|
+
"sell": {
|
|
214
|
+
"description": "Marks the subject sold only after the escrow opened against this exact listing has released the full asking price to this seller.",
|
|
215
|
+
"eventName": "listing.sold",
|
|
216
|
+
"moves": [],
|
|
217
|
+
"requiresRefs": [
|
|
218
|
+
{
|
|
219
|
+
"field": "escrowOrderId",
|
|
220
|
+
"match": {
|
|
221
|
+
"fields.askingPrice": "fields.amount",
|
|
222
|
+
"fields.currency": "fields.currency",
|
|
223
|
+
"fields.sellerAccountId": "fields.sellerAccountId",
|
|
224
|
+
"nounInstanceId": "fields.listingId"
|
|
225
|
+
},
|
|
226
|
+
"statuses": [
|
|
227
|
+
"released"
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"steps": [],
|
|
232
|
+
"summary": "Sell a listing"
|
|
233
|
+
},
|
|
234
|
+
"withdraw": {
|
|
235
|
+
"description": "Closes a draft or active offer before any escrow reservation exists.",
|
|
236
|
+
"eventName": "listing.withdrawn",
|
|
237
|
+
"moves": [],
|
|
238
|
+
"steps": [],
|
|
239
|
+
"summary": "Withdraw a listing"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"description": "An order records the buyer and seller agreement for one listing. Confirmation requires the listing to remain active and its escrow to hold the purchase money; fulfillment requires that escrow to release, while cancellation is allowed only before funding or after escrow safely retreats.",
|
|
245
|
+
"fields": {
|
|
246
|
+
"amount": {
|
|
247
|
+
"description": "Positive minor-unit integer amount serialized as a string (at most 18 digits)",
|
|
248
|
+
"pattern": "^[1-9][0-9]{0,17}$",
|
|
249
|
+
"type": "string"
|
|
250
|
+
},
|
|
251
|
+
"buyerAccountId": {
|
|
252
|
+
"description": "Hyperscale account ID",
|
|
253
|
+
"pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
254
|
+
"type": "string",
|
|
255
|
+
"x-hyperscale-reference-filter": {
|
|
256
|
+
"column": "role",
|
|
257
|
+
"values": [
|
|
258
|
+
"customer_balance"
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
"confirmBy": {
|
|
263
|
+
"format": "hyperscale-date-time",
|
|
264
|
+
"type": "string"
|
|
265
|
+
},
|
|
266
|
+
"currency": {
|
|
267
|
+
"description": "ISO 4217 currency code",
|
|
268
|
+
"maxLength": 3,
|
|
269
|
+
"minLength": 3,
|
|
270
|
+
"pattern": "^[A-Z]{3}$",
|
|
271
|
+
"type": "string"
|
|
272
|
+
},
|
|
273
|
+
"escrowOrderId": {
|
|
274
|
+
"description": "Escrow order holding this order's purchase money",
|
|
275
|
+
"pattern": "^eord_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
276
|
+
"type": "string"
|
|
277
|
+
},
|
|
278
|
+
"listingId": {
|
|
279
|
+
"description": "Listing whose subject the buyer agreed to purchase",
|
|
280
|
+
"pattern": "^lst_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
281
|
+
"type": "string"
|
|
282
|
+
},
|
|
283
|
+
"memo": {
|
|
284
|
+
"maxLength": 180,
|
|
285
|
+
"minLength": 1,
|
|
286
|
+
"type": "string"
|
|
287
|
+
},
|
|
288
|
+
"sellerAccountId": {
|
|
289
|
+
"description": "Hyperscale account ID",
|
|
290
|
+
"pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
291
|
+
"type": "string",
|
|
292
|
+
"x-hyperscale-reference-filter": {
|
|
293
|
+
"column": "role",
|
|
294
|
+
"values": [
|
|
295
|
+
"customer_balance"
|
|
296
|
+
]
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"id": "order",
|
|
301
|
+
"idPrefix": "ord",
|
|
302
|
+
"lifecycle": {
|
|
303
|
+
"initial": "created",
|
|
304
|
+
"states": [
|
|
305
|
+
"created",
|
|
306
|
+
"confirmed",
|
|
307
|
+
"fulfilled",
|
|
308
|
+
"canceled",
|
|
309
|
+
"expired"
|
|
310
|
+
],
|
|
311
|
+
"transitions": {
|
|
312
|
+
"cancel": {
|
|
313
|
+
"from": [
|
|
314
|
+
"created",
|
|
315
|
+
"confirmed"
|
|
316
|
+
],
|
|
317
|
+
"to": "canceled"
|
|
318
|
+
},
|
|
319
|
+
"confirm": {
|
|
320
|
+
"from": [
|
|
321
|
+
"created"
|
|
322
|
+
],
|
|
323
|
+
"to": "confirmed"
|
|
324
|
+
},
|
|
325
|
+
"expire": {
|
|
326
|
+
"from": [
|
|
327
|
+
"created"
|
|
328
|
+
],
|
|
329
|
+
"to": "expired"
|
|
330
|
+
},
|
|
331
|
+
"fulfill": {
|
|
332
|
+
"from": [
|
|
333
|
+
"confirmed"
|
|
334
|
+
],
|
|
335
|
+
"to": "fulfilled"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
"parties": {
|
|
340
|
+
"beneficiary": "sellerAccountId",
|
|
341
|
+
"payer": "buyerAccountId"
|
|
342
|
+
},
|
|
343
|
+
"required": [
|
|
344
|
+
"buyerAccountId",
|
|
345
|
+
"sellerAccountId",
|
|
346
|
+
"listingId",
|
|
347
|
+
"escrowOrderId",
|
|
348
|
+
"amount",
|
|
349
|
+
"currency"
|
|
350
|
+
],
|
|
351
|
+
"subject": {
|
|
352
|
+
"kinds": [
|
|
353
|
+
"vehicle",
|
|
354
|
+
"merchandise"
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
"summary": "Agreement to buy one listed subject at an accepted amount.",
|
|
358
|
+
"title": "Order",
|
|
359
|
+
"update": {
|
|
360
|
+
"fields": [
|
|
361
|
+
"confirmBy",
|
|
362
|
+
"memo"
|
|
363
|
+
],
|
|
364
|
+
"states": [
|
|
365
|
+
"created"
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
"verbs": {
|
|
369
|
+
"cancel": {
|
|
370
|
+
"description": "Closes the agreement only while escrow is still empty or after every held unit has safely returned to the buyer.",
|
|
371
|
+
"moves": [],
|
|
372
|
+
"requiresRefs": [
|
|
373
|
+
{
|
|
374
|
+
"field": "escrowOrderId",
|
|
375
|
+
"statuses": [
|
|
376
|
+
"created",
|
|
377
|
+
"refunded",
|
|
378
|
+
"penalty_collected",
|
|
379
|
+
"canceled",
|
|
380
|
+
"expired"
|
|
381
|
+
]
|
|
382
|
+
}
|
|
383
|
+
],
|
|
384
|
+
"steps": [],
|
|
385
|
+
"summary": "Cancel an order"
|
|
386
|
+
},
|
|
387
|
+
"confirm": {
|
|
388
|
+
"description": "Makes the agreement final only while the listing is active at the agreed price and escrow holds the full purchase amount for that same listing.",
|
|
389
|
+
"moves": [],
|
|
390
|
+
"requiresRefs": [
|
|
391
|
+
{
|
|
392
|
+
"field": "listingId",
|
|
393
|
+
"match": {
|
|
394
|
+
"fields.amount": "fields.askingPrice",
|
|
395
|
+
"fields.currency": "fields.currency",
|
|
396
|
+
"fields.sellerAccountId": "fields.sellerAccountId"
|
|
397
|
+
},
|
|
398
|
+
"statuses": [
|
|
399
|
+
"active"
|
|
400
|
+
]
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"field": "escrowOrderId",
|
|
404
|
+
"match": {
|
|
405
|
+
"fields.amount": "fields.amount",
|
|
406
|
+
"fields.buyerAccountId": "fields.buyerAccountId",
|
|
407
|
+
"fields.currency": "fields.currency",
|
|
408
|
+
"fields.listingId": "fields.listingId",
|
|
409
|
+
"fields.sellerAccountId": "fields.sellerAccountId"
|
|
410
|
+
},
|
|
411
|
+
"statuses": [
|
|
412
|
+
"funded"
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
],
|
|
416
|
+
"steps": [],
|
|
417
|
+
"summary": "Confirm an order"
|
|
418
|
+
},
|
|
419
|
+
"create": {
|
|
420
|
+
"description": "Records the proposed buyer and seller agreement against one listing and one escrow order. The escrow must still hold or await the money, must protect the same listing, and supplies the parties and the amount. No money moves.",
|
|
421
|
+
"examples": [
|
|
422
|
+
{
|
|
423
|
+
"input": {
|
|
424
|
+
"confirmBy": "2026-08-01T20:00:00.000Z",
|
|
425
|
+
"escrowOrderId": "eord_sandbox_buyerorder01",
|
|
426
|
+
"listingId": "lst_sandbox_landcruiser1",
|
|
427
|
+
"memo": "Purchase subject to funded escrow.",
|
|
428
|
+
"subject": "sbj_sandbox_landcruiser1"
|
|
429
|
+
},
|
|
430
|
+
"name": "create_vehicle_purchase_order"
|
|
431
|
+
}
|
|
432
|
+
],
|
|
433
|
+
"moves": [],
|
|
434
|
+
"requiresRefs": [
|
|
435
|
+
{
|
|
436
|
+
"bind": {
|
|
437
|
+
"amount": "fields.amount",
|
|
438
|
+
"buyerAccountId": "fields.buyerAccountId",
|
|
439
|
+
"currency": "fields.currency",
|
|
440
|
+
"sellerAccountId": "fields.sellerAccountId"
|
|
441
|
+
},
|
|
442
|
+
"field": "escrowOrderId",
|
|
443
|
+
"match": {
|
|
444
|
+
"fields.listingId": "fields.listingId"
|
|
445
|
+
},
|
|
446
|
+
"statuses": [
|
|
447
|
+
"created",
|
|
448
|
+
"funded"
|
|
449
|
+
]
|
|
450
|
+
}
|
|
451
|
+
],
|
|
452
|
+
"steps": [],
|
|
453
|
+
"summary": "Create an order"
|
|
454
|
+
},
|
|
455
|
+
"expire": {
|
|
456
|
+
"description": "Closes an unconfirmed agreement at its declared deadline under the machine principal.",
|
|
457
|
+
"due": {
|
|
458
|
+
"field": "confirmBy"
|
|
459
|
+
},
|
|
460
|
+
"moves": [],
|
|
461
|
+
"steps": [],
|
|
462
|
+
"summary": "Expire an order"
|
|
463
|
+
},
|
|
464
|
+
"fulfill": {
|
|
465
|
+
"description": "Closes the agreement after escrow has released the full purchase amount to the seller.",
|
|
466
|
+
"eventName": "order.fulfilled",
|
|
467
|
+
"moves": [],
|
|
468
|
+
"requiresRefs": [
|
|
469
|
+
{
|
|
470
|
+
"field": "escrowOrderId",
|
|
471
|
+
"statuses": [
|
|
472
|
+
"released"
|
|
473
|
+
]
|
|
474
|
+
}
|
|
475
|
+
],
|
|
476
|
+
"steps": [],
|
|
477
|
+
"summary": "Fulfill an order"
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
"description": "An escrow order holds the full purchase amount and releases it to the seller exactly once. Before release, a dispute freezes the full balance until work resumes or a quoted refund is confirmed.",
|
|
483
|
+
"fields": {
|
|
484
|
+
"amount": {
|
|
485
|
+
"description": "Positive minor-unit integer amount serialized as a string (at most 18 digits)",
|
|
486
|
+
"pattern": "^[1-9][0-9]{0,17}$",
|
|
487
|
+
"type": "string"
|
|
488
|
+
},
|
|
489
|
+
"buyerAccountId": {
|
|
490
|
+
"description": "Hyperscale account ID",
|
|
491
|
+
"pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
492
|
+
"type": "string",
|
|
493
|
+
"x-hyperscale-reference-filter": {
|
|
494
|
+
"column": "role",
|
|
495
|
+
"values": [
|
|
496
|
+
"customer_balance"
|
|
497
|
+
]
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
"currency": {
|
|
501
|
+
"description": "ISO 4217 currency code",
|
|
502
|
+
"maxLength": 3,
|
|
503
|
+
"minLength": 3,
|
|
504
|
+
"pattern": "^[A-Z]{3}$",
|
|
505
|
+
"type": "string"
|
|
506
|
+
},
|
|
507
|
+
"fundBy": {
|
|
508
|
+
"format": "hyperscale-date-time",
|
|
509
|
+
"type": "string"
|
|
510
|
+
},
|
|
511
|
+
"listingId": {
|
|
512
|
+
"description": "Listing whose subject and availability this escrow protects",
|
|
513
|
+
"pattern": "^lst_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
514
|
+
"type": "string"
|
|
515
|
+
},
|
|
516
|
+
"memo": {
|
|
517
|
+
"maxLength": 180,
|
|
518
|
+
"minLength": 1,
|
|
519
|
+
"type": "string"
|
|
520
|
+
},
|
|
521
|
+
"sellerAccountId": {
|
|
522
|
+
"description": "Hyperscale account ID",
|
|
523
|
+
"pattern": "^acct_(sandbox|live)_[a-z0-9]{8,64}$",
|
|
524
|
+
"type": "string",
|
|
525
|
+
"x-hyperscale-reference-filter": {
|
|
526
|
+
"column": "role",
|
|
527
|
+
"values": [
|
|
528
|
+
"customer_balance"
|
|
529
|
+
]
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
"id": "escrow_order",
|
|
534
|
+
"idPrefix": "eord",
|
|
535
|
+
"lifecycle": {
|
|
536
|
+
"initial": "created",
|
|
537
|
+
"states": [
|
|
538
|
+
"created",
|
|
539
|
+
"funded",
|
|
540
|
+
"disputed",
|
|
541
|
+
"refund_quoted",
|
|
542
|
+
"released",
|
|
543
|
+
"refunded",
|
|
544
|
+
"penalty_collected",
|
|
545
|
+
"canceled",
|
|
546
|
+
"expired"
|
|
547
|
+
],
|
|
548
|
+
"transitions": {
|
|
549
|
+
"cancel": {
|
|
550
|
+
"from": [
|
|
551
|
+
"created"
|
|
552
|
+
],
|
|
553
|
+
"to": "canceled"
|
|
554
|
+
},
|
|
555
|
+
"collect_penalty": {
|
|
556
|
+
"from": [
|
|
557
|
+
"refunded"
|
|
558
|
+
],
|
|
559
|
+
"to": "penalty_collected"
|
|
560
|
+
},
|
|
561
|
+
"dispute": {
|
|
562
|
+
"from": [
|
|
563
|
+
"funded"
|
|
564
|
+
],
|
|
565
|
+
"to": "disputed"
|
|
566
|
+
},
|
|
567
|
+
"expire": {
|
|
568
|
+
"from": [
|
|
569
|
+
"created"
|
|
570
|
+
],
|
|
571
|
+
"to": "expired"
|
|
572
|
+
},
|
|
573
|
+
"fund": {
|
|
574
|
+
"from": [
|
|
575
|
+
"created"
|
|
576
|
+
],
|
|
577
|
+
"to": "funded"
|
|
578
|
+
},
|
|
579
|
+
"quote": {
|
|
580
|
+
"from": [
|
|
581
|
+
"disputed"
|
|
582
|
+
],
|
|
583
|
+
"to": "refund_quoted"
|
|
584
|
+
},
|
|
585
|
+
"refund": {
|
|
586
|
+
"from": [
|
|
587
|
+
"refund_quoted"
|
|
588
|
+
],
|
|
589
|
+
"to": "refunded"
|
|
590
|
+
},
|
|
591
|
+
"release": {
|
|
592
|
+
"from": [
|
|
593
|
+
"funded"
|
|
594
|
+
],
|
|
595
|
+
"to": "released"
|
|
596
|
+
},
|
|
597
|
+
"resume": {
|
|
598
|
+
"from": [
|
|
599
|
+
"disputed"
|
|
600
|
+
],
|
|
601
|
+
"to": "funded"
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
"parties": {
|
|
606
|
+
"beneficiary": "sellerAccountId",
|
|
607
|
+
"payer": "buyerAccountId"
|
|
608
|
+
},
|
|
609
|
+
"required": [
|
|
610
|
+
"buyerAccountId",
|
|
611
|
+
"sellerAccountId",
|
|
612
|
+
"listingId",
|
|
613
|
+
"amount",
|
|
614
|
+
"currency"
|
|
615
|
+
],
|
|
616
|
+
"subject": {
|
|
617
|
+
"kinds": [
|
|
618
|
+
"vehicle",
|
|
619
|
+
"merchandise"
|
|
620
|
+
]
|
|
621
|
+
},
|
|
622
|
+
"summary": "Purchase money held between buyer and seller.",
|
|
623
|
+
"title": "Escrow order",
|
|
624
|
+
"unwind": {
|
|
625
|
+
"confirm": "refund",
|
|
626
|
+
"penalty": [
|
|
627
|
+
{
|
|
628
|
+
"bps": 0
|
|
629
|
+
}
|
|
630
|
+
],
|
|
631
|
+
"quote": "quote",
|
|
632
|
+
"refundDestinationField": "buyerAccountId",
|
|
633
|
+
"refundableField": "amount"
|
|
634
|
+
},
|
|
635
|
+
"update": {
|
|
636
|
+
"fields": [
|
|
637
|
+
"fundBy",
|
|
638
|
+
"memo"
|
|
639
|
+
],
|
|
640
|
+
"states": [
|
|
641
|
+
"created"
|
|
642
|
+
]
|
|
643
|
+
},
|
|
644
|
+
"verbs": {
|
|
645
|
+
"cancel": {
|
|
646
|
+
"description": "Closes an unfunded escrow. Because no money moved, no unwind quote is required.",
|
|
647
|
+
"moves": [],
|
|
648
|
+
"requiresDrainedAccount": {
|
|
649
|
+
"path": "refs.escrowAccountId"
|
|
650
|
+
},
|
|
651
|
+
"steps": [],
|
|
652
|
+
"summary": "Cancel an escrow order"
|
|
653
|
+
},
|
|
654
|
+
"collect_penalty": {
|
|
655
|
+
"description": "Pays the computed retained penalty to the seller after a penalized refund. Invoke only when refund returns a positive refs.unwindPenalty.",
|
|
656
|
+
"eventName": "escrow_order.penalty_collected",
|
|
657
|
+
"moves": [
|
|
658
|
+
{
|
|
659
|
+
"bind": {
|
|
660
|
+
"amount": {
|
|
661
|
+
"from": "instance",
|
|
662
|
+
"path": "refs.unwindPenalty"
|
|
663
|
+
},
|
|
664
|
+
"currency": {
|
|
665
|
+
"from": "instance",
|
|
666
|
+
"path": "fields.currency"
|
|
667
|
+
},
|
|
668
|
+
"destinationAccountId": {
|
|
669
|
+
"from": "instance",
|
|
670
|
+
"path": "fields.sellerAccountId"
|
|
671
|
+
},
|
|
672
|
+
"sourceAccountId": {
|
|
673
|
+
"from": "instance",
|
|
674
|
+
"path": "refs.escrowAccountId"
|
|
675
|
+
},
|
|
676
|
+
"workspaceId": {
|
|
677
|
+
"from": "instance",
|
|
678
|
+
"path": "workspaceId"
|
|
679
|
+
}
|
|
680
|
+
},
|
|
681
|
+
"capture": {
|
|
682
|
+
"penaltyTransferId": "transferId"
|
|
683
|
+
},
|
|
684
|
+
"key": "transfer",
|
|
685
|
+
"operation": "internal_transfer.create"
|
|
686
|
+
}
|
|
687
|
+
],
|
|
688
|
+
"steps": [],
|
|
689
|
+
"summary": "Collect an escrow refund penalty"
|
|
690
|
+
},
|
|
691
|
+
"create": {
|
|
692
|
+
"description": "Opens escrow against an active listing and provisions its dedicated product escrow account. The amount, currency, and seller are derived from the locked listing -- never caller-supplied -- so escrow economics are the listing's by construction.",
|
|
693
|
+
"examples": [
|
|
694
|
+
{
|
|
695
|
+
"input": {
|
|
696
|
+
"buyerAccountId": "acct_sandbox_buyer000001",
|
|
697
|
+
"fundBy": "2026-08-01T21:00:00.000Z",
|
|
698
|
+
"listingId": "lst_sandbox_landcruiser1",
|
|
699
|
+
"memo": "Release after the vehicle is handed over.",
|
|
700
|
+
"subject": "sbj_sandbox_landcruiser1"
|
|
701
|
+
},
|
|
702
|
+
"name": "open_vehicle_escrow"
|
|
703
|
+
}
|
|
704
|
+
],
|
|
705
|
+
"moves": [],
|
|
706
|
+
"requiresRefs": [
|
|
707
|
+
{
|
|
708
|
+
"bind": {
|
|
709
|
+
"amount": "fields.askingPrice",
|
|
710
|
+
"currency": "fields.currency",
|
|
711
|
+
"sellerAccountId": "fields.sellerAccountId"
|
|
712
|
+
},
|
|
713
|
+
"field": "listingId",
|
|
714
|
+
"statuses": [
|
|
715
|
+
"active"
|
|
716
|
+
]
|
|
717
|
+
}
|
|
718
|
+
],
|
|
719
|
+
"steps": [
|
|
720
|
+
{
|
|
721
|
+
"bind": {
|
|
722
|
+
"currency": {
|
|
723
|
+
"from": "instance",
|
|
724
|
+
"path": "fields.currency"
|
|
725
|
+
},
|
|
726
|
+
"owner.id": {
|
|
727
|
+
"from": "instance",
|
|
728
|
+
"path": "workspaceId"
|
|
729
|
+
},
|
|
730
|
+
"owner.type": {
|
|
731
|
+
"from": "const",
|
|
732
|
+
"value": "workspace"
|
|
733
|
+
},
|
|
734
|
+
"role": {
|
|
735
|
+
"from": "const",
|
|
736
|
+
"value": "workspace_escrow"
|
|
737
|
+
},
|
|
738
|
+
"workspaceId": {
|
|
739
|
+
"from": "instance",
|
|
740
|
+
"path": "workspaceId"
|
|
741
|
+
}
|
|
742
|
+
},
|
|
743
|
+
"capture": {
|
|
744
|
+
"escrowAccountId": "accountId"
|
|
745
|
+
},
|
|
746
|
+
"operation": "account.escrow.provision"
|
|
747
|
+
}
|
|
748
|
+
],
|
|
749
|
+
"summary": "Create an escrow order"
|
|
750
|
+
},
|
|
751
|
+
"dispute": {
|
|
752
|
+
"description": "Freezes the fully funded escrow before either milestone releases, preserving the entire balance while the parties decide what happens next.",
|
|
753
|
+
"moves": [],
|
|
754
|
+
"steps": [],
|
|
755
|
+
"summary": "Dispute an escrow order"
|
|
756
|
+
},
|
|
757
|
+
"expire": {
|
|
758
|
+
"description": "Closes an unfunded escrow at its funding deadline under the machine principal.",
|
|
759
|
+
"due": {
|
|
760
|
+
"field": "fundBy"
|
|
761
|
+
},
|
|
762
|
+
"moves": [],
|
|
763
|
+
"requiresDrainedAccount": {
|
|
764
|
+
"path": "refs.escrowAccountId"
|
|
765
|
+
},
|
|
766
|
+
"steps": [],
|
|
767
|
+
"summary": "Expire an escrow order"
|
|
768
|
+
},
|
|
769
|
+
"fund": {
|
|
770
|
+
"description": "Moves the full purchase amount from the buyer account into the dedicated escrow account while the listing remains active.",
|
|
771
|
+
"moves": [
|
|
772
|
+
{
|
|
773
|
+
"bind": {
|
|
774
|
+
"amount": {
|
|
775
|
+
"from": "instance",
|
|
776
|
+
"path": "fields.amount"
|
|
777
|
+
},
|
|
778
|
+
"currency": {
|
|
779
|
+
"from": "instance",
|
|
780
|
+
"path": "fields.currency"
|
|
781
|
+
},
|
|
782
|
+
"destinationAccountId": {
|
|
783
|
+
"from": "instance",
|
|
784
|
+
"path": "refs.escrowAccountId"
|
|
785
|
+
},
|
|
786
|
+
"sourceAccountId": {
|
|
787
|
+
"from": "instance",
|
|
788
|
+
"path": "fields.buyerAccountId"
|
|
789
|
+
},
|
|
790
|
+
"workspaceId": {
|
|
791
|
+
"from": "instance",
|
|
792
|
+
"path": "workspaceId"
|
|
793
|
+
}
|
|
794
|
+
},
|
|
795
|
+
"capture": {
|
|
796
|
+
"fundTransferId": "transferId"
|
|
797
|
+
},
|
|
798
|
+
"key": "transfer",
|
|
799
|
+
"operation": "internal_transfer.create"
|
|
800
|
+
}
|
|
801
|
+
],
|
|
802
|
+
"requiresRefs": [
|
|
803
|
+
{
|
|
804
|
+
"field": "listingId",
|
|
805
|
+
"statuses": [
|
|
806
|
+
"active"
|
|
807
|
+
]
|
|
808
|
+
}
|
|
809
|
+
],
|
|
810
|
+
"steps": [],
|
|
811
|
+
"summary": "Fund an escrow order"
|
|
812
|
+
},
|
|
813
|
+
"quote": {
|
|
814
|
+
"description": "Calculates the full buyer refund while disputed and parks the escrow for explicit confirmation. No money moves at quote time.",
|
|
815
|
+
"moves": [],
|
|
816
|
+
"steps": [],
|
|
817
|
+
"summary": "Quote an escrow refund"
|
|
818
|
+
},
|
|
819
|
+
"refund": {
|
|
820
|
+
"description": "Confirms the quoted retreat and returns the full held amount from escrow to the buyer.",
|
|
821
|
+
"moves": [
|
|
822
|
+
{
|
|
823
|
+
"bind": {
|
|
824
|
+
"amount": {
|
|
825
|
+
"from": "instance",
|
|
826
|
+
"path": "refs.unwindRefund"
|
|
827
|
+
},
|
|
828
|
+
"currency": {
|
|
829
|
+
"from": "instance",
|
|
830
|
+
"path": "fields.currency"
|
|
831
|
+
},
|
|
832
|
+
"destinationAccountId": {
|
|
833
|
+
"from": "instance",
|
|
834
|
+
"path": "fields.buyerAccountId"
|
|
835
|
+
},
|
|
836
|
+
"sourceAccountId": {
|
|
837
|
+
"from": "instance",
|
|
838
|
+
"path": "refs.escrowAccountId"
|
|
839
|
+
},
|
|
840
|
+
"workspaceId": {
|
|
841
|
+
"from": "instance",
|
|
842
|
+
"path": "workspaceId"
|
|
843
|
+
}
|
|
844
|
+
},
|
|
845
|
+
"capture": {
|
|
846
|
+
"refundTransferId": "transferId"
|
|
847
|
+
},
|
|
848
|
+
"key": "transfer",
|
|
849
|
+
"operation": "internal_transfer.create"
|
|
850
|
+
}
|
|
851
|
+
],
|
|
852
|
+
"steps": [],
|
|
853
|
+
"summary": "Refund an escrow order"
|
|
854
|
+
},
|
|
855
|
+
"release": {
|
|
856
|
+
"description": "Pays the seller the full escrow amount once and closes escrow with no balance remaining. Only the escrow that reserved the listing can release: the listing must name this escrow back.",
|
|
857
|
+
"earnable": true,
|
|
858
|
+
"moves": [
|
|
859
|
+
{
|
|
860
|
+
"bind": {
|
|
861
|
+
"amount": {
|
|
862
|
+
"from": "instance",
|
|
863
|
+
"path": "fields.amount"
|
|
864
|
+
},
|
|
865
|
+
"currency": {
|
|
866
|
+
"from": "instance",
|
|
867
|
+
"path": "fields.currency"
|
|
868
|
+
},
|
|
869
|
+
"destinationAccountId": {
|
|
870
|
+
"from": "instance",
|
|
871
|
+
"path": "fields.sellerAccountId"
|
|
872
|
+
},
|
|
873
|
+
"sourceAccountId": {
|
|
874
|
+
"from": "instance",
|
|
875
|
+
"path": "refs.escrowAccountId"
|
|
876
|
+
},
|
|
877
|
+
"workspaceId": {
|
|
878
|
+
"from": "instance",
|
|
879
|
+
"path": "workspaceId"
|
|
880
|
+
}
|
|
881
|
+
},
|
|
882
|
+
"capture": {
|
|
883
|
+
"releaseTransferId": "transferId"
|
|
884
|
+
},
|
|
885
|
+
"key": "transfer",
|
|
886
|
+
"operation": "internal_transfer.create"
|
|
887
|
+
}
|
|
888
|
+
],
|
|
889
|
+
"requiresRefs": [
|
|
890
|
+
{
|
|
891
|
+
"field": "listingId",
|
|
892
|
+
"match": {
|
|
893
|
+
"nounInstanceId": "fields.escrowOrderId"
|
|
894
|
+
},
|
|
895
|
+
"statuses": [
|
|
896
|
+
"reserved"
|
|
897
|
+
]
|
|
898
|
+
}
|
|
899
|
+
],
|
|
900
|
+
"steps": [],
|
|
901
|
+
"summary": "Release an escrow order"
|
|
902
|
+
},
|
|
903
|
+
"resume": {
|
|
904
|
+
"description": "Ends the dispute hold without moving money and returns the fully funded escrow to its first milestone.",
|
|
905
|
+
"moves": [],
|
|
906
|
+
"steps": [],
|
|
907
|
+
"summary": "Resume an escrow order"
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
],
|
|
912
|
+
"product": "commerce_escrow",
|
|
913
|
+
"subjects": [
|
|
914
|
+
{
|
|
915
|
+
"declaredValue": "required",
|
|
916
|
+
"kind": "vehicle",
|
|
917
|
+
"schema": {
|
|
918
|
+
"additionalProperties": false,
|
|
919
|
+
"properties": {
|
|
920
|
+
"make": {
|
|
921
|
+
"maxLength": 60,
|
|
922
|
+
"minLength": 1,
|
|
923
|
+
"type": "string"
|
|
924
|
+
},
|
|
925
|
+
"mileageKm": {
|
|
926
|
+
"maximum": 9007199254740991,
|
|
927
|
+
"minimum": 0,
|
|
928
|
+
"type": "integer"
|
|
929
|
+
},
|
|
930
|
+
"model": {
|
|
931
|
+
"maxLength": 60,
|
|
932
|
+
"minLength": 1,
|
|
933
|
+
"type": "string"
|
|
934
|
+
},
|
|
935
|
+
"vin": {
|
|
936
|
+
"maxLength": 17,
|
|
937
|
+
"minLength": 11,
|
|
938
|
+
"type": "string"
|
|
939
|
+
},
|
|
940
|
+
"year": {
|
|
941
|
+
"pattern": "^\\d{4}$",
|
|
942
|
+
"type": "string"
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
"required": [
|
|
946
|
+
"vin",
|
|
947
|
+
"make",
|
|
948
|
+
"model",
|
|
949
|
+
"year",
|
|
950
|
+
"mileageKm"
|
|
951
|
+
],
|
|
952
|
+
"type": "object"
|
|
953
|
+
},
|
|
954
|
+
"title": "Vehicle",
|
|
955
|
+
"version": 1
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"declaredValue": "required",
|
|
959
|
+
"kind": "merchandise",
|
|
960
|
+
"schema": {
|
|
961
|
+
"additionalProperties": false,
|
|
962
|
+
"properties": {
|
|
963
|
+
"brand": {
|
|
964
|
+
"maxLength": 60,
|
|
965
|
+
"minLength": 1,
|
|
966
|
+
"type": "string"
|
|
967
|
+
},
|
|
968
|
+
"category": {
|
|
969
|
+
"maxLength": 60,
|
|
970
|
+
"minLength": 1,
|
|
971
|
+
"type": "string"
|
|
972
|
+
},
|
|
973
|
+
"condition": {
|
|
974
|
+
"enum": [
|
|
975
|
+
"new",
|
|
976
|
+
"excellent",
|
|
977
|
+
"good",
|
|
978
|
+
"fair",
|
|
979
|
+
"poor"
|
|
980
|
+
],
|
|
981
|
+
"type": "string"
|
|
982
|
+
},
|
|
983
|
+
"model": {
|
|
984
|
+
"maxLength": 60,
|
|
985
|
+
"minLength": 1,
|
|
986
|
+
"type": "string"
|
|
987
|
+
},
|
|
988
|
+
"serialNumber": {
|
|
989
|
+
"maxLength": 80,
|
|
990
|
+
"minLength": 1,
|
|
991
|
+
"type": "string"
|
|
992
|
+
},
|
|
993
|
+
"yearOfManufacture": {
|
|
994
|
+
"pattern": "^\\d{4}$",
|
|
995
|
+
"type": "string"
|
|
996
|
+
}
|
|
997
|
+
},
|
|
998
|
+
"required": [
|
|
999
|
+
"category",
|
|
1000
|
+
"condition"
|
|
1001
|
+
],
|
|
1002
|
+
"type": "object"
|
|
1003
|
+
},
|
|
1004
|
+
"title": "Merchandise",
|
|
1005
|
+
"version": 1
|
|
1006
|
+
}
|
|
1007
|
+
],
|
|
1008
|
+
"title": "Commerce and escrow",
|
|
1009
|
+
"udl": 1,
|
|
1010
|
+
"version": 1
|
|
1011
|
+
}
|