@cloudhal/core-contracts 0.3.4 → 0.3.5
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/package.json +1 -1
- package/schemas/.bundled/analytics-beacon.schema.json +0 -132
- package/schemas/.bundled/analytics-event.schema.json +0 -411
- package/schemas/.bundled/asset.schema.json +0 -519
- package/schemas/.bundled/automation.schema.json +0 -334
- package/schemas/.bundled/comment-submission.schema.json +0 -172
- package/schemas/.bundled/comment.schema.json +0 -425
- package/schemas/.bundled/content-entry.schema.json +0 -514
- package/schemas/.bundled/glossary.schema.json +0 -139
- package/schemas/.bundled/menu.schema.json +0 -371
- package/schemas/.bundled/page.schema.json +0 -738
- package/schemas/.bundled/project.schema.json +0 -97
- package/schemas/.bundled/redirect.schema.json +0 -152
- package/schemas/.bundled/release.schema.json +0 -639
- package/schemas/.bundled/schedule-run.schema.json +0 -310
- package/schemas/.bundled/section.schema.json +0 -434
- package/schemas/.bundled/site.schema.json +0 -1050
- package/schemas/.bundled/skill-manifest.schema.json +0 -51
- package/schemas/.bundled/snapshot.schema.json +0 -192
- package/schemas/.bundled/taxonomy.schema.json +0 -200
- package/schemas/.bundled/term.schema.json +0 -315
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://cloudhal.dev/schemas/v1/asset.schema.json",
|
|
4
|
-
"title": "Asset",
|
|
5
|
-
"description": "A media file of a site (image, video, audio, document, data) as a graph node: its bytes are identified by SHA-256 and stored once per site in the blob store under a content-addressed key, or kept elsewhere (`storage.kind: external`, e.g. a Zenodo or Hugging Face file). Pages, entries and terms refer to it by id (`ImageRef.assetId`, markdown `asset:<id>`). Snapshotted like every node, so a deleted asset's bytes stay while any snapshot references it (RFC-0004).",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"required": [
|
|
9
|
-
"schemaVersion",
|
|
10
|
-
"id",
|
|
11
|
-
"siteId",
|
|
12
|
-
"kind",
|
|
13
|
-
"mediaType",
|
|
14
|
-
"bytes",
|
|
15
|
-
"sha256",
|
|
16
|
-
"slug",
|
|
17
|
-
"storage",
|
|
18
|
-
"status",
|
|
19
|
-
"uploadedBy",
|
|
20
|
-
"source",
|
|
21
|
-
"rev",
|
|
22
|
-
"createdAt",
|
|
23
|
-
"updatedAt"
|
|
24
|
-
],
|
|
25
|
-
"properties": {
|
|
26
|
-
"schemaVersion": {
|
|
27
|
-
"$ref": "#/$defs/SchemaVersion"
|
|
28
|
-
},
|
|
29
|
-
"id": {
|
|
30
|
-
"$ref": "#/$defs/Id"
|
|
31
|
-
},
|
|
32
|
-
"siteId": {
|
|
33
|
-
"$ref": "#/$defs/Id"
|
|
34
|
-
},
|
|
35
|
-
"kind": {
|
|
36
|
-
"type": "string",
|
|
37
|
-
"description": "What the file is, derived from the sniffed media type (never chosen by the client). `other` is allowed for external storage only.",
|
|
38
|
-
"enum": [
|
|
39
|
-
"image",
|
|
40
|
-
"video",
|
|
41
|
-
"audio",
|
|
42
|
-
"document",
|
|
43
|
-
"data",
|
|
44
|
-
"other"
|
|
45
|
-
]
|
|
46
|
-
},
|
|
47
|
-
"mediaType": {
|
|
48
|
-
"type": "string",
|
|
49
|
-
"description": "MIME type of the stored bytes as sniffed by the server (RFC 6838, lower case, no parameters), e.g. image/webp, text/csv. Served as Content-Type.",
|
|
50
|
-
"pattern": "^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$",
|
|
51
|
-
"maxLength": 255
|
|
52
|
-
},
|
|
53
|
-
"bytes": {
|
|
54
|
-
"type": "integer",
|
|
55
|
-
"description": "Size of the stored bytes. For external files: the size the source reports or the uploader declares.",
|
|
56
|
-
"minimum": 0
|
|
57
|
-
},
|
|
58
|
-
"sha256": {
|
|
59
|
-
"$ref": "#/$defs/Sha256",
|
|
60
|
-
"description": "SHA-256 of the stored bytes (lower-case hex): the blob key, the public URL prefix, the ETag and the checksum shown with downloads. Unique per site. For external files see `storage.checksum`."
|
|
61
|
-
},
|
|
62
|
-
"originalSha256": {
|
|
63
|
-
"$ref": "#/$defs/Sha256",
|
|
64
|
-
"description": "SHA-256 of the bytes as uploaded, present only when the server changed them (image metadata stripping)."
|
|
65
|
-
},
|
|
66
|
-
"slug": {
|
|
67
|
-
"$ref": "#/$defs/Slug",
|
|
68
|
-
"description": "File name in the public URL, without extension: /media/<sha256[0..16]>/<slug>.<ext>. May change; the old URL then answers 301 to the new one."
|
|
69
|
-
},
|
|
70
|
-
"storage": {
|
|
71
|
-
"$ref": "#/$defs/AssetStorage"
|
|
72
|
-
},
|
|
73
|
-
"image": {
|
|
74
|
-
"$ref": "#/$defs/AssetImage"
|
|
75
|
-
},
|
|
76
|
-
"title": {
|
|
77
|
-
"type": "object",
|
|
78
|
-
"description": "Display title per locale (download lists, library search).",
|
|
79
|
-
"propertyNames": {
|
|
80
|
-
"$ref": "#/$defs/Locale"
|
|
81
|
-
},
|
|
82
|
-
"minProperties": 1,
|
|
83
|
-
"additionalProperties": {
|
|
84
|
-
"type": "string",
|
|
85
|
-
"minLength": 1,
|
|
86
|
-
"maxLength": 300
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
"alt": {
|
|
90
|
-
"type": "object",
|
|
91
|
-
"description": "Alternative text per locale. An `ImageRef.alt` that is not empty overrides it for one use.",
|
|
92
|
-
"propertyNames": {
|
|
93
|
-
"$ref": "#/$defs/Locale"
|
|
94
|
-
},
|
|
95
|
-
"minProperties": 1,
|
|
96
|
-
"additionalProperties": {
|
|
97
|
-
"type": "string",
|
|
98
|
-
"minLength": 1,
|
|
99
|
-
"maxLength": 500
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
"decorative": {
|
|
103
|
-
"type": "boolean",
|
|
104
|
-
"description": "The image carries no information and renders with alt=\"\". Absent means false; the store never writes false."
|
|
105
|
-
},
|
|
106
|
-
"caption": {
|
|
107
|
-
"type": "object",
|
|
108
|
-
"description": "Caption per locale (plain text), the default for figures that show this asset.",
|
|
109
|
-
"propertyNames": {
|
|
110
|
-
"$ref": "#/$defs/Locale"
|
|
111
|
-
},
|
|
112
|
-
"minProperties": 1,
|
|
113
|
-
"additionalProperties": {
|
|
114
|
-
"type": "string",
|
|
115
|
-
"minLength": 1,
|
|
116
|
-
"maxLength": 1000
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
"credit": {
|
|
120
|
-
"type": "string",
|
|
121
|
-
"description": "Who made it, as shown next to it (e.g. 'Photo: Ayşe Yılmaz').",
|
|
122
|
-
"minLength": 1,
|
|
123
|
-
"maxLength": 300
|
|
124
|
-
},
|
|
125
|
-
"license": {
|
|
126
|
-
"$ref": "#/$defs/AssetLicense"
|
|
127
|
-
},
|
|
128
|
-
"status": {
|
|
129
|
-
"type": "string",
|
|
130
|
-
"description": "active: listed and pickable. retired: hidden from the library and pickers and cannot be newly referenced; existing references keep rendering.",
|
|
131
|
-
"enum": [
|
|
132
|
-
"active",
|
|
133
|
-
"retired"
|
|
134
|
-
]
|
|
135
|
-
},
|
|
136
|
-
"uploadedBy": {
|
|
137
|
-
"$ref": "#/$defs/Actor"
|
|
138
|
-
},
|
|
139
|
-
"source": {
|
|
140
|
-
"$ref": "#/$defs/AssetSource"
|
|
141
|
-
},
|
|
142
|
-
"rev": {
|
|
143
|
-
"$ref": "#/$defs/Revision"
|
|
144
|
-
},
|
|
145
|
-
"createdAt": {
|
|
146
|
-
"$ref": "#/$defs/Timestamp"
|
|
147
|
-
},
|
|
148
|
-
"updatedAt": {
|
|
149
|
-
"$ref": "#/$defs/Timestamp"
|
|
150
|
-
},
|
|
151
|
-
"metadata": {
|
|
152
|
-
"$ref": "#/$defs/Metadata"
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
"$defs": {
|
|
156
|
-
"Actor": {
|
|
157
|
-
"type": "object",
|
|
158
|
-
"additionalProperties": false,
|
|
159
|
-
"required": [
|
|
160
|
-
"kind",
|
|
161
|
-
"id"
|
|
162
|
-
],
|
|
163
|
-
"properties": {
|
|
164
|
-
"kind": {
|
|
165
|
-
"$ref": "#/$defs/ActorKind"
|
|
166
|
-
},
|
|
167
|
-
"id": {
|
|
168
|
-
"$ref": "#/$defs/Id"
|
|
169
|
-
},
|
|
170
|
-
"name": {
|
|
171
|
-
"type": "string",
|
|
172
|
-
"maxLength": 200
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
"ActorKind": {
|
|
177
|
-
"type": "string",
|
|
178
|
-
"description": "Who performed an action. Humans and agents share one actor model so the policy engine treats them uniformly.",
|
|
179
|
-
"enum": [
|
|
180
|
-
"human",
|
|
181
|
-
"agent",
|
|
182
|
-
"system"
|
|
183
|
-
]
|
|
184
|
-
},
|
|
185
|
-
"AssetImage": {
|
|
186
|
-
"type": "object",
|
|
187
|
-
"description": "Intrinsic size and placeholders of an image. Present for every image stored as a blob.",
|
|
188
|
-
"additionalProperties": false,
|
|
189
|
-
"required": [
|
|
190
|
-
"width",
|
|
191
|
-
"height"
|
|
192
|
-
],
|
|
193
|
-
"properties": {
|
|
194
|
-
"width": {
|
|
195
|
-
"type": "integer",
|
|
196
|
-
"minimum": 1,
|
|
197
|
-
"maximum": 100000
|
|
198
|
-
},
|
|
199
|
-
"height": {
|
|
200
|
-
"type": "integer",
|
|
201
|
-
"minimum": 1,
|
|
202
|
-
"maximum": 100000
|
|
203
|
-
},
|
|
204
|
-
"animated": {
|
|
205
|
-
"type": "boolean",
|
|
206
|
-
"description": "Animated GIF or WebP: never resized or re-encoded. Absent means false; the store never writes false."
|
|
207
|
-
},
|
|
208
|
-
"blurhash": {
|
|
209
|
-
"type": "string",
|
|
210
|
-
"description": "BlurHash of the image for themes that decode it client-side.",
|
|
211
|
-
"pattern": "^[0-9A-Za-z#$%*+,.:;=?@^_{|}~\\[\\]-]{6,100}$"
|
|
212
|
-
},
|
|
213
|
-
"lqip": {
|
|
214
|
-
"type": "string",
|
|
215
|
-
"description": "Low-quality placeholder: a raster data: URL of at most about 3 KB, shown while the image loads.",
|
|
216
|
-
"pattern": "^data:image/(?:webp|png|jpeg);base64,[A-Za-z0-9+/]+={0,2}$",
|
|
217
|
-
"maxLength": 4096
|
|
218
|
-
},
|
|
219
|
-
"color": {
|
|
220
|
-
"type": "string",
|
|
221
|
-
"description": "RFC-0028: the image's dominant colour, lower-case #rrggbb. Painted under the placeholder and in color-fill bars.",
|
|
222
|
-
"pattern": "^#[0-9a-f]{6}$"
|
|
223
|
-
},
|
|
224
|
-
"alpha": {
|
|
225
|
-
"type": "boolean",
|
|
226
|
-
"enum": [
|
|
227
|
-
true
|
|
228
|
-
],
|
|
229
|
-
"description": "RFC-0028: the image may have transparent pixels (read from its header at ingest). Absent means opaque; transparent images never show the LQIP."
|
|
230
|
-
},
|
|
231
|
-
"focal": {
|
|
232
|
-
"type": "object",
|
|
233
|
-
"description": "RFC-0028: where the subject is, from the top-left corner as fractions of the width and height. Cover crops keep it in view.",
|
|
234
|
-
"additionalProperties": false,
|
|
235
|
-
"required": [
|
|
236
|
-
"x",
|
|
237
|
-
"y"
|
|
238
|
-
],
|
|
239
|
-
"properties": {
|
|
240
|
-
"x": {
|
|
241
|
-
"type": "number",
|
|
242
|
-
"minimum": 0,
|
|
243
|
-
"maximum": 1
|
|
244
|
-
},
|
|
245
|
-
"y": {
|
|
246
|
-
"type": "number",
|
|
247
|
-
"minimum": 0,
|
|
248
|
-
"maximum": 1
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
},
|
|
254
|
-
"AssetLicense": {
|
|
255
|
-
"description": "Terms the asset may be reused under: an SPDX license expression or a license URL.",
|
|
256
|
-
"oneOf": [
|
|
257
|
-
{
|
|
258
|
-
"type": "object",
|
|
259
|
-
"title": "SpdxLicense",
|
|
260
|
-
"additionalProperties": false,
|
|
261
|
-
"required": [
|
|
262
|
-
"kind",
|
|
263
|
-
"id"
|
|
264
|
-
],
|
|
265
|
-
"properties": {
|
|
266
|
-
"kind": {
|
|
267
|
-
"type": "string",
|
|
268
|
-
"enum": [
|
|
269
|
-
"spdx"
|
|
270
|
-
]
|
|
271
|
-
},
|
|
272
|
-
"id": {
|
|
273
|
-
"type": "string",
|
|
274
|
-
"description": "SPDX license identifier or simple expression, e.g. CC-BY-4.0, CC0-1.0, MIT OR Apache-2.0, LicenseRef-AllRightsReserved.",
|
|
275
|
-
"pattern": "^[A-Za-z0-9][A-Za-z0-9.+-]*(?: (?:AND|OR|WITH) [A-Za-z0-9][A-Za-z0-9.+-]*)*$",
|
|
276
|
-
"maxLength": 200
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
"type": "object",
|
|
282
|
-
"title": "UrlLicense",
|
|
283
|
-
"additionalProperties": false,
|
|
284
|
-
"required": [
|
|
285
|
-
"kind",
|
|
286
|
-
"url"
|
|
287
|
-
],
|
|
288
|
-
"properties": {
|
|
289
|
-
"kind": {
|
|
290
|
-
"type": "string",
|
|
291
|
-
"enum": [
|
|
292
|
-
"url"
|
|
293
|
-
]
|
|
294
|
-
},
|
|
295
|
-
"url": {
|
|
296
|
-
"$ref": "#/$defs/HttpsUrl"
|
|
297
|
-
},
|
|
298
|
-
"name": {
|
|
299
|
-
"type": "string",
|
|
300
|
-
"minLength": 1,
|
|
301
|
-
"maxLength": 200
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
]
|
|
306
|
-
},
|
|
307
|
-
"AssetSource": {
|
|
308
|
-
"description": "How the asset came in. Immutable after create.",
|
|
309
|
-
"oneOf": [
|
|
310
|
-
{
|
|
311
|
-
"type": "object",
|
|
312
|
-
"title": "UploadSource",
|
|
313
|
-
"description": "Bytes uploaded by a person (REST) or an agent (MCP upload_asset).",
|
|
314
|
-
"additionalProperties": false,
|
|
315
|
-
"required": [
|
|
316
|
-
"kind"
|
|
317
|
-
],
|
|
318
|
-
"properties": {
|
|
319
|
-
"kind": {
|
|
320
|
-
"type": "string",
|
|
321
|
-
"enum": [
|
|
322
|
-
"upload"
|
|
323
|
-
]
|
|
324
|
-
},
|
|
325
|
-
"filename": {
|
|
326
|
-
"type": "string",
|
|
327
|
-
"description": "Original file name as sent (never used as a storage key or served).",
|
|
328
|
-
"pattern": "^[^/\\\\\\u0000-\\u001f\\u007f]+$",
|
|
329
|
-
"minLength": 1,
|
|
330
|
-
"maxLength": 255
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
"type": "object",
|
|
336
|
-
"title": "FetchSource",
|
|
337
|
-
"description": "Bytes the server fetched from an https URL (MCP fetch_asset_url, Studio 'From URL') under the SSRF rules.",
|
|
338
|
-
"additionalProperties": false,
|
|
339
|
-
"required": [
|
|
340
|
-
"kind",
|
|
341
|
-
"url",
|
|
342
|
-
"fetchedAt"
|
|
343
|
-
],
|
|
344
|
-
"properties": {
|
|
345
|
-
"kind": {
|
|
346
|
-
"type": "string",
|
|
347
|
-
"enum": [
|
|
348
|
-
"fetch"
|
|
349
|
-
]
|
|
350
|
-
},
|
|
351
|
-
"url": {
|
|
352
|
-
"$ref": "#/$defs/HttpsUrl"
|
|
353
|
-
},
|
|
354
|
-
"fetchedAt": {
|
|
355
|
-
"$ref": "#/$defs/Timestamp"
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
"type": "object",
|
|
361
|
-
"title": "ImportSource",
|
|
362
|
-
"description": "Created by a migration or importer (e.g. `cloudhal media import-urls` from an ImageRef.src).",
|
|
363
|
-
"additionalProperties": false,
|
|
364
|
-
"required": [
|
|
365
|
-
"kind",
|
|
366
|
-
"from"
|
|
367
|
-
],
|
|
368
|
-
"properties": {
|
|
369
|
-
"kind": {
|
|
370
|
-
"type": "string",
|
|
371
|
-
"enum": [
|
|
372
|
-
"import"
|
|
373
|
-
]
|
|
374
|
-
},
|
|
375
|
-
"from": {
|
|
376
|
-
"type": "string",
|
|
377
|
-
"description": "The reference it was imported from: a URL or a site path.",
|
|
378
|
-
"minLength": 1,
|
|
379
|
-
"maxLength": 2048
|
|
380
|
-
},
|
|
381
|
-
"importer": {
|
|
382
|
-
"$ref": "#/$defs/Slug"
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
},
|
|
386
|
-
{
|
|
387
|
-
"type": "object",
|
|
388
|
-
"title": "LinkSource",
|
|
389
|
-
"description": "An external file registered by URL without copying its bytes (storage.kind external).",
|
|
390
|
-
"additionalProperties": false,
|
|
391
|
-
"required": [
|
|
392
|
-
"kind"
|
|
393
|
-
],
|
|
394
|
-
"properties": {
|
|
395
|
-
"kind": {
|
|
396
|
-
"type": "string",
|
|
397
|
-
"enum": [
|
|
398
|
-
"link"
|
|
399
|
-
]
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
]
|
|
404
|
-
},
|
|
405
|
-
"AssetStorage": {
|
|
406
|
-
"description": "Where the bytes live. `blob`: in this deployment's blob store (R2 or the filesystem) under the content-addressed key media/<siteId>/<sha256>, derived and never stored, so the node is portable between backends. `external`: elsewhere, linked rather than hosted (large research files on Zenodo or Hugging Face).",
|
|
407
|
-
"oneOf": [
|
|
408
|
-
{
|
|
409
|
-
"type": "object",
|
|
410
|
-
"title": "BlobStorage",
|
|
411
|
-
"additionalProperties": false,
|
|
412
|
-
"required": [
|
|
413
|
-
"kind"
|
|
414
|
-
],
|
|
415
|
-
"properties": {
|
|
416
|
-
"kind": {
|
|
417
|
-
"type": "string",
|
|
418
|
-
"enum": [
|
|
419
|
-
"blob"
|
|
420
|
-
]
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
},
|
|
424
|
-
{
|
|
425
|
-
"type": "object",
|
|
426
|
-
"title": "ExternalStorage",
|
|
427
|
-
"additionalProperties": false,
|
|
428
|
-
"required": [
|
|
429
|
-
"kind",
|
|
430
|
-
"url",
|
|
431
|
-
"checksum"
|
|
432
|
-
],
|
|
433
|
-
"properties": {
|
|
434
|
-
"kind": {
|
|
435
|
-
"type": "string",
|
|
436
|
-
"enum": [
|
|
437
|
-
"external"
|
|
438
|
-
]
|
|
439
|
-
},
|
|
440
|
-
"url": {
|
|
441
|
-
"$ref": "#/$defs/HttpsUrl",
|
|
442
|
-
"description": "Direct download URL of the file."
|
|
443
|
-
},
|
|
444
|
-
"landingPage": {
|
|
445
|
-
"$ref": "#/$defs/HttpsUrl",
|
|
446
|
-
"description": "Human page of the record the file belongs to (e.g. a Zenodo record or a Hugging Face dataset)."
|
|
447
|
-
},
|
|
448
|
-
"checksum": {
|
|
449
|
-
"type": "string",
|
|
450
|
-
"description": "How `sha256` was obtained. computed: the server or `cloudhal media verify` streamed the URL and hashed it. declared: given by the person who linked it, not verified (shown as such).",
|
|
451
|
-
"enum": [
|
|
452
|
-
"computed",
|
|
453
|
-
"declared"
|
|
454
|
-
]
|
|
455
|
-
},
|
|
456
|
-
"verifiedAt": {
|
|
457
|
-
"$ref": "#/$defs/Timestamp",
|
|
458
|
-
"description": "When the URL last produced bytes with this SHA-256 (checksum `computed`)."
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
]
|
|
463
|
-
},
|
|
464
|
-
"HttpsUrl": {
|
|
465
|
-
"type": "string",
|
|
466
|
-
"description": "Absolute https URL without credentials, whitespace or backslashes.",
|
|
467
|
-
"pattern": "^https://[^\\s\\\\/?#@]+(?:[/?#][^\\s\\\\]*)?$",
|
|
468
|
-
"maxLength": 2048
|
|
469
|
-
},
|
|
470
|
-
"Id": {
|
|
471
|
-
"type": "string",
|
|
472
|
-
"description": "Prefixed, URL-safe identifier, e.g. site_01HZX8K3Q9. The prefix names the entity kind; agents and the MCP server pass these as opaque handles.",
|
|
473
|
-
"pattern": "^[a-z]+_[A-Za-z0-9]{6,32}$",
|
|
474
|
-
"minLength": 8,
|
|
475
|
-
"maxLength": 48
|
|
476
|
-
},
|
|
477
|
-
"Locale": {
|
|
478
|
-
"type": "string",
|
|
479
|
-
"description": "BCP 47 language tag, e.g. en, tr, en-US.",
|
|
480
|
-
"pattern": "^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
|
|
481
|
-
},
|
|
482
|
-
"Metadata": {
|
|
483
|
-
"type": "object",
|
|
484
|
-
"description": "Free-form string-to-string map for extensions. Keys should be namespaced (e.g. cloudhal.source).",
|
|
485
|
-
"additionalProperties": {
|
|
486
|
-
"type": "string"
|
|
487
|
-
}
|
|
488
|
-
},
|
|
489
|
-
"Revision": {
|
|
490
|
-
"type": "integer",
|
|
491
|
-
"description": "Monotonic per-node revision used for optimistic locking (compare-and-swap on write).",
|
|
492
|
-
"minimum": 0
|
|
493
|
-
},
|
|
494
|
-
"SchemaVersion": {
|
|
495
|
-
"type": "integer",
|
|
496
|
-
"description": "Version of this contract. Readers reject unknown versions; migrations move documents forward one version at a time.",
|
|
497
|
-
"enum": [
|
|
498
|
-
1
|
|
499
|
-
]
|
|
500
|
-
},
|
|
501
|
-
"Sha256": {
|
|
502
|
-
"type": "string",
|
|
503
|
-
"description": "Lower-case hex SHA-256 digest.",
|
|
504
|
-
"pattern": "^[0-9a-f]{64}$"
|
|
505
|
-
},
|
|
506
|
-
"Slug": {
|
|
507
|
-
"type": "string",
|
|
508
|
-
"description": "Lower-case URL segment.",
|
|
509
|
-
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
|
|
510
|
-
"minLength": 1,
|
|
511
|
-
"maxLength": 128
|
|
512
|
-
},
|
|
513
|
-
"Timestamp": {
|
|
514
|
-
"type": "string",
|
|
515
|
-
"description": "RFC 3339 / ISO 8601 instant in UTC.",
|
|
516
|
-
"format": "date-time"
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|