@taprootio/docs-artifact 1.0.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.
Files changed (36) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +362 -0
  3. package/bin/taproot-docs-conformance.js +20 -0
  4. package/bin/taproot-docs-validate.js +17 -0
  5. package/conformance.d.ts +11 -0
  6. package/fixtures/README.md +24 -0
  7. package/fixtures/conformance.json +1630 -0
  8. package/fixtures/invalid/duplicate-json-key.json +1 -0
  9. package/fixtures/invalid/hash-drift/taproot-docs/fragments/welcome.html +1 -0
  10. package/fixtures/invalid/size-drift/taproot-docs/fragments/welcome.html +1 -0
  11. package/fixtures/invalid/unsafe-markup/taproot-docs/fragments/welcome.html +1 -0
  12. package/fixtures/valid/complete/taproot-docs/assets/pixel.png.base64 +1 -0
  13. package/fixtures/valid/complete/taproot-docs/fragments/button.en-us.html +1 -0
  14. package/fixtures/valid/complete/taproot-docs/fragments/button.fr-fr.html +1 -0
  15. package/fixtures/valid/complete/taproot-docs/fragments/getting-started.en-us.html +3 -0
  16. package/fixtures/valid/complete/taproot-docs/fragments/getting-started.fr-fr.html +3 -0
  17. package/fixtures/valid/complete/taproot-docs-manifest.json +231 -0
  18. package/fixtures/valid/minimal/taproot-docs/fragments/welcome.html +1 -0
  19. package/fixtures/valid/minimal/taproot-docs-manifest.json +80 -0
  20. package/index.d.ts +204 -0
  21. package/node.d.ts +6 -0
  22. package/package.json +54 -0
  23. package/schema/taproot-docs-manifest.schema.json +487 -0
  24. package/src/artifact-validator.js +870 -0
  25. package/src/binary.js +67 -0
  26. package/src/conformance.js +578 -0
  27. package/src/constants.js +104 -0
  28. package/src/errors.js +139 -0
  29. package/src/index.js +18 -0
  30. package/src/json.js +516 -0
  31. package/src/manifest-validator.js +650 -0
  32. package/src/markup.js +578 -0
  33. package/src/node-internal.js +4 -0
  34. package/src/node.js +513 -0
  35. package/src/path.js +103 -0
  36. package/src/text.js +30 -0
@@ -0,0 +1,487 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:taproot:docs:artifact:manifest:v1",
4
+ "title": "Taproot Docs artifact manifest",
5
+ "description": "Portable semantic documentation contract. Cross-reference, path-reservation, capability, file-byte, hash, media, string-control, and markup rules are enforced by @taprootio/docs-artifact in addition to this structural schema.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "schemaVersion",
10
+ "defaultLocale",
11
+ "source",
12
+ "build",
13
+ "capabilities",
14
+ "locales",
15
+ "resources",
16
+ "navigation",
17
+ "redirects",
18
+ "assets"
19
+ ],
20
+ "properties": {
21
+ "schemaVersion": {
22
+ "const": 1
23
+ },
24
+ "defaultLocale": {
25
+ "$ref": "#/$defs/locale"
26
+ },
27
+ "source": {
28
+ "type": "object",
29
+ "additionalProperties": false,
30
+ "required": ["provider", "repositoryId", "repository", "repositoryUrl", "revision", "ref"],
31
+ "properties": {
32
+ "provider": {
33
+ "const": "github"
34
+ },
35
+ "repositoryId": {
36
+ "type": "string",
37
+ "minLength": 1,
38
+ "maxLength": 200,
39
+ "pattern": "^[A-Za-z0-9_.:-]+$"
40
+ },
41
+ "repository": {
42
+ "type": "string",
43
+ "minLength": 3,
44
+ "maxLength": 300,
45
+ "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$"
46
+ },
47
+ "repositoryUrl": {
48
+ "type": "string",
49
+ "format": "uri",
50
+ "maxLength": 2000,
51
+ "pattern": "^https://"
52
+ },
53
+ "revision": {
54
+ "type": "string",
55
+ "pattern": "^(?:[0-9a-f]{40}|[0-9a-f]{64})$"
56
+ },
57
+ "ref": {
58
+ "type": "string",
59
+ "maxLength": 500,
60
+ "pattern": "^refs/(?:heads|tags)/[A-Za-z0-9][A-Za-z0-9._/-]*$"
61
+ }
62
+ }
63
+ },
64
+ "build": {
65
+ "type": "object",
66
+ "additionalProperties": false,
67
+ "required": ["producer", "producerVersion", "configurationSha256", "sourceDateEpoch"],
68
+ "properties": {
69
+ "producer": {
70
+ "type": "string",
71
+ "minLength": 1,
72
+ "maxLength": 200,
73
+ "pattern": "^(?:@[a-z0-9._-]+/)?[a-z0-9._-]+$"
74
+ },
75
+ "producerVersion": {
76
+ "type": "string",
77
+ "maxLength": 100,
78
+ "pattern": "^(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*)(?:-(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$"
79
+ },
80
+ "configurationSha256": {
81
+ "$ref": "#/$defs/hash"
82
+ },
83
+ "sourceDateEpoch": {
84
+ "type": "integer",
85
+ "minimum": 0,
86
+ "maximum": 253402300799
87
+ }
88
+ }
89
+ },
90
+ "capabilities": {
91
+ "type": "object",
92
+ "additionalProperties": false,
93
+ "required": ["required", "optional"],
94
+ "properties": {
95
+ "required": {
96
+ "type": "array",
97
+ "minItems": 1,
98
+ "maxItems": 100,
99
+ "uniqueItems": true,
100
+ "items": {
101
+ "$ref": "#/$defs/resourceKey"
102
+ },
103
+ "contains": {
104
+ "const": "taproot.docs.fragments.html.v1"
105
+ }
106
+ },
107
+ "optional": {
108
+ "type": "array",
109
+ "maxItems": 100,
110
+ "uniqueItems": true,
111
+ "items": {
112
+ "$ref": "#/$defs/resourceKey"
113
+ }
114
+ }
115
+ }
116
+ },
117
+ "locales": {
118
+ "type": "array",
119
+ "minItems": 1,
120
+ "maxItems": 100,
121
+ "items": {
122
+ "type": "object",
123
+ "additionalProperties": false,
124
+ "required": ["tag", "label"],
125
+ "properties": {
126
+ "tag": {
127
+ "$ref": "#/$defs/locale"
128
+ },
129
+ "label": {
130
+ "type": "string",
131
+ "minLength": 1,
132
+ "maxLength": 100
133
+ }
134
+ }
135
+ }
136
+ },
137
+ "resources": {
138
+ "type": "array",
139
+ "minItems": 1,
140
+ "maxItems": 10000,
141
+ "items": {
142
+ "$ref": "#/$defs/resource"
143
+ }
144
+ },
145
+ "navigation": {
146
+ "type": "array",
147
+ "minItems": 1,
148
+ "maxItems": 100,
149
+ "items": {
150
+ "$ref": "#/$defs/navigation"
151
+ }
152
+ },
153
+ "redirects": {
154
+ "type": "array",
155
+ "maxItems": 10000,
156
+ "items": {
157
+ "$ref": "#/$defs/redirect"
158
+ }
159
+ },
160
+ "assets": {
161
+ "type": "array",
162
+ "maxItems": 10000,
163
+ "items": {
164
+ "$ref": "#/$defs/asset"
165
+ }
166
+ }
167
+ },
168
+ "$defs": {
169
+ "resourceKey": {
170
+ "type": "string",
171
+ "minLength": 1,
172
+ "maxLength": 200,
173
+ "pattern": "^[a-z0-9]+(?:[._:/-][a-z0-9]+)*$"
174
+ },
175
+ "token": {
176
+ "type": "string",
177
+ "minLength": 1,
178
+ "maxLength": 100,
179
+ "pattern": "^[a-z0-9]+(?:[._-][a-z0-9]+)*$"
180
+ },
181
+ "locale": {
182
+ "type": "string",
183
+ "$comment": "Docs v1 pins a deterministic BCP 47 subset independent of the host ICU database: a two- or three-letter lowercase language, an optional title-case four-letter Script subtag, and an optional uppercase two-letter or three-digit region subtag.",
184
+ "minLength": 2,
185
+ "maxLength": 12,
186
+ "pattern": "^[a-z]{2,3}(?:-[A-Z][a-z]{3})?(?:-(?:[A-Z]{2}|[0-9]{3}))?$"
187
+ },
188
+ "hash": {
189
+ "type": "string",
190
+ "pattern": "^sha256:[0-9a-f]{64}$"
191
+ },
192
+ "route": {
193
+ "type": "string",
194
+ "$comment": "The runtime validator additionally rejects Windows device-name aliases in every segment, Taproot shell prefixes, and the complete first-segment subtrees rooted at reserved published files such as /index.html/, /robots.txt/, and /sitemap.xml/.",
195
+ "maxLength": 512,
196
+ "pattern": "^(?:/|/(?:[a-z0-9]+(?:[._~-][a-z0-9]+)*/)+)$"
197
+ },
198
+ "sourceLocation": {
199
+ "type": "object",
200
+ "additionalProperties": false,
201
+ "required": ["path", "url"],
202
+ "properties": {
203
+ "path": {
204
+ "type": "string",
205
+ "minLength": 1,
206
+ "maxLength": 1000
207
+ },
208
+ "url": {
209
+ "type": "string",
210
+ "format": "uri",
211
+ "maxLength": 2000,
212
+ "pattern": "^https://"
213
+ },
214
+ "startLine": {
215
+ "type": "integer",
216
+ "minimum": 1,
217
+ "maximum": 10000000
218
+ },
219
+ "endLine": {
220
+ "type": "integer",
221
+ "minimum": 1,
222
+ "maximum": 10000000
223
+ }
224
+ },
225
+ "dependentRequired": {
226
+ "startLine": ["endLine"],
227
+ "endLine": ["startLine"]
228
+ }
229
+ },
230
+ "heading": {
231
+ "type": "object",
232
+ "additionalProperties": false,
233
+ "required": ["id", "text", "level"],
234
+ "properties": {
235
+ "id": {
236
+ "type": "string",
237
+ "maxLength": 200,
238
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
239
+ },
240
+ "text": {
241
+ "type": "string",
242
+ "minLength": 1,
243
+ "maxLength": 300
244
+ },
245
+ "level": {
246
+ "type": "integer",
247
+ "minimum": 2,
248
+ "maximum": 6
249
+ }
250
+ }
251
+ },
252
+ "fragment": {
253
+ "type": "object",
254
+ "additionalProperties": false,
255
+ "required": ["key", "role", "path", "mediaType", "bytes", "sha256"],
256
+ "properties": {
257
+ "key": {
258
+ "$ref": "#/$defs/token"
259
+ },
260
+ "role": {
261
+ "enum": ["aside", "body", "example"]
262
+ },
263
+ "path": {
264
+ "type": "string",
265
+ "maxLength": 512,
266
+ "pattern": "^taproot-docs/fragments/(?!(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\.|/|$))[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/(?!(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\.|/|$))[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
267
+ },
268
+ "mediaType": {
269
+ "const": "text/html; charset=utf-8"
270
+ },
271
+ "bytes": {
272
+ "type": "integer",
273
+ "minimum": 1,
274
+ "maximum": 2097152
275
+ },
276
+ "sha256": {
277
+ "$ref": "#/$defs/hash"
278
+ }
279
+ }
280
+ },
281
+ "variant": {
282
+ "type": "object",
283
+ "additionalProperties": false,
284
+ "required": ["locale", "route", "title", "description", "headings", "source", "fragments"],
285
+ "properties": {
286
+ "locale": {
287
+ "$ref": "#/$defs/locale"
288
+ },
289
+ "route": {
290
+ "$ref": "#/$defs/route"
291
+ },
292
+ "title": {
293
+ "type": "string",
294
+ "minLength": 1,
295
+ "maxLength": 300
296
+ },
297
+ "description": {
298
+ "type": "string",
299
+ "maxLength": 1000
300
+ },
301
+ "headings": {
302
+ "type": "array",
303
+ "maxItems": 500,
304
+ "items": {
305
+ "$ref": "#/$defs/heading"
306
+ }
307
+ },
308
+ "source": {
309
+ "$ref": "#/$defs/sourceLocation"
310
+ },
311
+ "fragments": {
312
+ "type": "array",
313
+ "minItems": 1,
314
+ "maxItems": 20000,
315
+ "items": {
316
+ "$ref": "#/$defs/fragment"
317
+ },
318
+ "contains": {
319
+ "type": "object",
320
+ "properties": {
321
+ "role": {
322
+ "const": "body"
323
+ }
324
+ },
325
+ "required": ["role"]
326
+ },
327
+ "minContains": 1,
328
+ "maxContains": 1
329
+ }
330
+ }
331
+ },
332
+ "semantic": {
333
+ "type": "object",
334
+ "additionalProperties": false,
335
+ "required": ["kind", "audiences", "tags"],
336
+ "properties": {
337
+ "kind": {
338
+ "enum": ["api", "changelog", "concept", "guide", "other", "reference"]
339
+ },
340
+ "audiences": {
341
+ "type": "array",
342
+ "minItems": 1,
343
+ "maxItems": 4,
344
+ "uniqueItems": true,
345
+ "items": {
346
+ "enum": ["administrator", "developer", "operator", "user"]
347
+ }
348
+ },
349
+ "tags": {
350
+ "type": "array",
351
+ "maxItems": 100,
352
+ "uniqueItems": true,
353
+ "items": {
354
+ "$ref": "#/$defs/token"
355
+ }
356
+ }
357
+ }
358
+ },
359
+ "resource": {
360
+ "type": "object",
361
+ "additionalProperties": false,
362
+ "required": ["key", "semantic", "variants"],
363
+ "properties": {
364
+ "key": {
365
+ "$ref": "#/$defs/resourceKey"
366
+ },
367
+ "semantic": {
368
+ "$ref": "#/$defs/semantic"
369
+ },
370
+ "variants": {
371
+ "type": "array",
372
+ "minItems": 1,
373
+ "maxItems": 20000,
374
+ "items": {
375
+ "$ref": "#/$defs/variant"
376
+ }
377
+ }
378
+ }
379
+ },
380
+ "navigationNode": {
381
+ "type": "object",
382
+ "$comment": "The runtime validator counts top-level navigation items as level 1, accepts leaves through level 12, and rejects child nodes at level 13.",
383
+ "additionalProperties": false,
384
+ "required": ["label"],
385
+ "properties": {
386
+ "label": {
387
+ "type": "string",
388
+ "minLength": 1,
389
+ "maxLength": 300
390
+ },
391
+ "resourceKey": {
392
+ "$ref": "#/$defs/resourceKey"
393
+ },
394
+ "children": {
395
+ "type": "array",
396
+ "minItems": 1,
397
+ "maxItems": 20000,
398
+ "items": {
399
+ "$ref": "#/$defs/navigationNode"
400
+ }
401
+ }
402
+ },
403
+ "anyOf": [
404
+ {
405
+ "required": ["resourceKey"]
406
+ },
407
+ {
408
+ "required": ["children"]
409
+ }
410
+ ]
411
+ },
412
+ "navigation": {
413
+ "type": "object",
414
+ "additionalProperties": false,
415
+ "required": ["locale", "items"],
416
+ "properties": {
417
+ "locale": {
418
+ "$ref": "#/$defs/locale"
419
+ },
420
+ "items": {
421
+ "type": "array",
422
+ "minItems": 1,
423
+ "maxItems": 20000,
424
+ "items": {
425
+ "$ref": "#/$defs/navigationNode"
426
+ }
427
+ }
428
+ }
429
+ },
430
+ "redirect": {
431
+ "type": "object",
432
+ "additionalProperties": false,
433
+ "required": ["from", "toResourceKey", "locale", "status"],
434
+ "properties": {
435
+ "from": {
436
+ "$ref": "#/$defs/route"
437
+ },
438
+ "toResourceKey": {
439
+ "$ref": "#/$defs/resourceKey"
440
+ },
441
+ "locale": {
442
+ "$ref": "#/$defs/locale"
443
+ },
444
+ "status": {
445
+ "enum": [301, 308]
446
+ }
447
+ }
448
+ },
449
+ "asset": {
450
+ "type": "object",
451
+ "$comment": "The runtime validator additionally requires width * height <= 67108864 decoded pixels and the sum of animated frame rectangle areas <= 67108864 decoded pixels; JSON Schema cannot express these media-derived products.",
452
+ "additionalProperties": false,
453
+ "required": ["key", "path", "mediaType", "bytes", "sha256", "width", "height"],
454
+ "properties": {
455
+ "key": {
456
+ "$ref": "#/$defs/resourceKey"
457
+ },
458
+ "path": {
459
+ "type": "string",
460
+ "maxLength": 512,
461
+ "pattern": "^taproot-docs/assets/(?!(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\.|/|$))[a-z0-9]+(?:[._-][a-z0-9]+)*(?:/(?!(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\.|/|$))[a-z0-9]+(?:[._-][a-z0-9]+)*)*$"
462
+ },
463
+ "mediaType": {
464
+ "enum": ["image/gif", "image/jpeg", "image/png", "image/webp"]
465
+ },
466
+ "bytes": {
467
+ "type": "integer",
468
+ "minimum": 1,
469
+ "maximum": 26214400
470
+ },
471
+ "sha256": {
472
+ "$ref": "#/$defs/hash"
473
+ },
474
+ "width": {
475
+ "type": "integer",
476
+ "minimum": 1,
477
+ "maximum": 32768
478
+ },
479
+ "height": {
480
+ "type": "integer",
481
+ "minimum": 1,
482
+ "maximum": 32768
483
+ }
484
+ }
485
+ }
486
+ }
487
+ }