@pagefront/lint-commerce 0.1.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.
Files changed (101) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +118 -0
  3. package/dist/catalogue.d.ts +9 -0
  4. package/dist/catalogue.js +43 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +144 -0
  7. package/dist/index.d.ts +22 -0
  8. package/dist/index.js +18 -0
  9. package/dist/lint-sheet.d.ts +13 -0
  10. package/dist/lint-sheet.js +25 -0
  11. package/dist/organization-catalogue.d.ts +11 -0
  12. package/dist/organization-catalogue.js +21 -0
  13. package/dist/organization-schema.d.ts +9 -0
  14. package/dist/organization-schema.js +441 -0
  15. package/dist/product-schema.d.ts +9 -0
  16. package/dist/product-schema.js +1853 -0
  17. package/dist/rules/org-shared.d.ts +21 -0
  18. package/dist/rules/org-shared.js +44 -0
  19. package/dist/rules/org-w-001.d.ts +12 -0
  20. package/dist/rules/org-w-001.js +31 -0
  21. package/dist/rules/org-w-002.d.ts +12 -0
  22. package/dist/rules/org-w-002.js +32 -0
  23. package/dist/rules/org-w-003.d.ts +11 -0
  24. package/dist/rules/org-w-003.js +30 -0
  25. package/dist/rules/org-w-004.d.ts +12 -0
  26. package/dist/rules/org-w-004.js +32 -0
  27. package/dist/rules/org-w-005.d.ts +2 -0
  28. package/dist/rules/org-w-005.js +54 -0
  29. package/dist/rules/org-w-006.d.ts +13 -0
  30. package/dist/rules/org-w-006.js +32 -0
  31. package/dist/rules/pdp-e-001.d.ts +2 -0
  32. package/dist/rules/pdp-e-001.js +42 -0
  33. package/dist/rules/pdp-e-002.d.ts +13 -0
  34. package/dist/rules/pdp-e-002.js +33 -0
  35. package/dist/rules/pdp-i-001.d.ts +2 -0
  36. package/dist/rules/pdp-i-001.js +28 -0
  37. package/dist/rules/pdp-w-001.d.ts +12 -0
  38. package/dist/rules/pdp-w-001.js +22 -0
  39. package/dist/rules/pdp-w-002.d.ts +13 -0
  40. package/dist/rules/pdp-w-002.js +23 -0
  41. package/dist/rules/pdp-w-003.d.ts +12 -0
  42. package/dist/rules/pdp-w-003.js +22 -0
  43. package/dist/rules/pdp-w-004.d.ts +11 -0
  44. package/dist/rules/pdp-w-004.js +30 -0
  45. package/dist/rules/pdp-w-005.d.ts +18 -0
  46. package/dist/rules/pdp-w-005.js +44 -0
  47. package/dist/rules/pdp-w-006.d.ts +10 -0
  48. package/dist/rules/pdp-w-006.js +31 -0
  49. package/dist/rules/pdp-w-007.d.ts +9 -0
  50. package/dist/rules/pdp-w-007.js +29 -0
  51. package/dist/rules/pdp-w-008.d.ts +19 -0
  52. package/dist/rules/pdp-w-008.js +43 -0
  53. package/dist/rules/pdp-w-009.d.ts +9 -0
  54. package/dist/rules/pdp-w-009.js +29 -0
  55. package/dist/rules/pdp-w-010.d.ts +24 -0
  56. package/dist/rules/pdp-w-010.js +85 -0
  57. package/dist/rules/pdp-w-011.d.ts +2 -0
  58. package/dist/rules/pdp-w-011.js +44 -0
  59. package/dist/rules/pdp-w-012.d.ts +18 -0
  60. package/dist/rules/pdp-w-012.js +51 -0
  61. package/dist/rules/pdp-w-013.d.ts +13 -0
  62. package/dist/rules/pdp-w-013.js +25 -0
  63. package/dist/rules/pdp-w-014.d.ts +26 -0
  64. package/dist/rules/pdp-w-014.js +69 -0
  65. package/dist/rules/pdp-w-015.d.ts +10 -0
  66. package/dist/rules/pdp-w-015.js +33 -0
  67. package/dist/rules/pdp-w-016.d.ts +9 -0
  68. package/dist/rules/pdp-w-016.js +30 -0
  69. package/dist/rules/pdp-w-017.d.ts +2 -0
  70. package/dist/rules/pdp-w-017.js +55 -0
  71. package/dist/rules/pdp-w-018.d.ts +2 -0
  72. package/dist/rules/pdp-w-018.js +32 -0
  73. package/dist/rules/pdp-w-019.d.ts +14 -0
  74. package/dist/rules/pdp-w-019.js +49 -0
  75. package/dist/rules/pdp-w-020.d.ts +2 -0
  76. package/dist/rules/pdp-w-020.js +64 -0
  77. package/dist/rules/pdp-w-021.d.ts +2 -0
  78. package/dist/rules/pdp-w-021.js +53 -0
  79. package/dist/rules/pdp-w-022.d.ts +11 -0
  80. package/dist/rules/pdp-w-022.js +25 -0
  81. package/dist/rules/pdp-w-023.d.ts +2 -0
  82. package/dist/rules/pdp-w-023.js +39 -0
  83. package/dist/rules/pdp-w-024.d.ts +24 -0
  84. package/dist/rules/pdp-w-024.js +58 -0
  85. package/dist/rules/pdp-w-025.d.ts +2 -0
  86. package/dist/rules/pdp-w-025.js +35 -0
  87. package/dist/rules/pdp-w-026.d.ts +10 -0
  88. package/dist/rules/pdp-w-026.js +31 -0
  89. package/dist/rules/pdp-w-027.d.ts +14 -0
  90. package/dist/rules/pdp-w-027.js +47 -0
  91. package/dist/schema-properties.d.ts +10 -0
  92. package/dist/schema-properties.js +67 -0
  93. package/dist/sheet-type.d.ts +16 -0
  94. package/dist/sheet-type.js +20 -0
  95. package/dist/validate-and-lint.d.ts +47 -0
  96. package/dist/validate-and-lint.js +53 -0
  97. package/dist/validate-organization.d.ts +27 -0
  98. package/dist/validate-organization.js +30 -0
  99. package/dist/version.d.ts +8 -0
  100. package/dist/version.js +8 -0
  101. package/package.json +50 -0
@@ -0,0 +1,1853 @@
1
+ /**
2
+ * The Pagefront product JSON Schema (commerce/spec/product.json,
3
+ * format 0.9), bundled verbatim so the published package can run
4
+ * Layer 1 validation without the monorepo checkout. Generated from
5
+ * the spec file; the schema drift test (test/schema.test.mjs) fails
6
+ * when the two diverge. Regenerate on any schema change, in the same
7
+ * change that motivates it.
8
+ */
9
+ export const PRODUCT_SCHEMA = {
10
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
11
+ "$id": "https://themachineweb.org/pagefront/commerce/schemas/product/v0.9.json",
12
+ "title": "Pagefront Product Sheet v0.9",
13
+ "description": "Formal schema for the Pagefront product sheet. v0.9 is an additive release on top of v0.8: the legalEntity entry's organization now also validates in reference-stub form (@type + @id, no name) so entries can reference a Commerce Organization Sheet; the inline form and all other constraints are unchanged, and v0.8 sheets remain valid once their format_version is updated. v0.8 is an additive release on top of v0.7: it adds a pagefront:featureGroup[] array for grouped, ordered technical specifications (groups of Schema.org PropertyValue entries, with an optional pagefront:presentationValue display variant per entry), a pagefront:productHighlights[] array of ordered publisher-authored selling-point strings, and a pagefront:legalEntity[] array for role-typed legal entities behind a product (closed role enum: brand_owner, licensee, authorized_representative, importer, manufacturer — EU GPSR responsible persons and similar). gtin and gtin13 now accept a string or an array of strings (regional packaging, re-releases); category now accepts the display string, a Schema.org CategoryCode object, or a mixed array of both. The pagefront:Document role enum gains repairability_index, recall_notice, and declaration_of_conformity; the pagefront:RelatedProduct relationship enum gains service. v0.8 also adds two GPSR-driven safety fields: a pagefront:safetyWarning[] array for typed, language-scoped safety warnings (text required; optional pictogram URL and open-vocabulary hazardCategory) and a pagefront:safetyNotice[] array for structured recall/safety notices (closed noticeType enum: recall, warning; closed remedy enum: repair, replacement, refund). v0.7 sheets remain valid under v0.8 once their format_version is updated. Validates the envelope and pagefront-namespaced extensions strictly; Schema.org-typed blocks permit additional unspecified properties.",
14
+ "type": "object",
15
+ "required": [
16
+ "format_version",
17
+ "schema_org_version",
18
+ "canonical_url",
19
+ "sheet_url",
20
+ "generated_at",
21
+ "data"
22
+ ],
23
+ "properties": {
24
+ "$schema": {
25
+ "type": "string",
26
+ "format": "uri"
27
+ },
28
+ "format_version": {
29
+ "const": "0.9"
30
+ },
31
+ "schema_org_version": {
32
+ "type": "string",
33
+ "pattern": "^\\d+(\\.\\d+)?$"
34
+ },
35
+ "canonical_url": {
36
+ "type": "string",
37
+ "format": "uri"
38
+ },
39
+ "sheet_url": {
40
+ "type": "string",
41
+ "format": "uri"
42
+ },
43
+ "generated_at": {
44
+ "type": "string",
45
+ "format": "date-time"
46
+ },
47
+ "expires_at": {
48
+ "type": "string",
49
+ "format": "date-time"
50
+ },
51
+ "data": {
52
+ "$ref": "#/$defs/dataBlock"
53
+ }
54
+ },
55
+ "additionalProperties": false,
56
+ "$defs": {
57
+ "dataBlock": {
58
+ "type": "object",
59
+ "required": [
60
+ "@context",
61
+ "@type",
62
+ "@id",
63
+ "name",
64
+ "inLanguage"
65
+ ],
66
+ "properties": {
67
+ "@context": {
68
+ "oneOf": [
69
+ {
70
+ "const": "https://schema.org"
71
+ },
72
+ {
73
+ "type": "array",
74
+ "items": {
75
+ "oneOf": [
76
+ {
77
+ "type": "string",
78
+ "format": "uri"
79
+ },
80
+ {
81
+ "type": "object"
82
+ }
83
+ ]
84
+ },
85
+ "minItems": 1
86
+ }
87
+ ]
88
+ },
89
+ "@type": {
90
+ "type": "string"
91
+ },
92
+ "@id": {
93
+ "type": "string",
94
+ "format": "uri"
95
+ },
96
+ "url": {
97
+ "type": "string",
98
+ "format": "uri"
99
+ },
100
+ "name": {
101
+ "type": "string",
102
+ "minLength": 1
103
+ },
104
+ "inLanguage": {
105
+ "type": "string"
106
+ },
107
+ "sku": {
108
+ "type": "string"
109
+ },
110
+ "gtin13": {
111
+ "$ref": "#/$defs/gtin13Value"
112
+ },
113
+ "gtin": {
114
+ "$ref": "#/$defs/gtinValue"
115
+ },
116
+ "mpn": {
117
+ "type": "string"
118
+ },
119
+ "productID": {
120
+ "type": "string"
121
+ },
122
+ "productGroupID": {
123
+ "type": "string"
124
+ },
125
+ "variesBy": {
126
+ "type": "array",
127
+ "items": {
128
+ "type": "string"
129
+ }
130
+ },
131
+ "hasVariant": {
132
+ "type": "array",
133
+ "items": {
134
+ "$ref": "#/$defs/variantEntry"
135
+ }
136
+ },
137
+ "brand": {
138
+ "type": "object"
139
+ },
140
+ "description": {
141
+ "type": "string"
142
+ },
143
+ "category": {
144
+ "oneOf": [
145
+ {
146
+ "type": "string"
147
+ },
148
+ {
149
+ "$ref": "#/$defs/categoryCode"
150
+ },
151
+ {
152
+ "type": "array",
153
+ "items": {
154
+ "oneOf": [
155
+ {
156
+ "type": "string"
157
+ },
158
+ {
159
+ "$ref": "#/$defs/categoryCode"
160
+ }
161
+ ]
162
+ },
163
+ "minItems": 1
164
+ }
165
+ ]
166
+ },
167
+ "color": {
168
+ "type": "string"
169
+ },
170
+ "material": {
171
+ "type": "string"
172
+ },
173
+ "weight": {
174
+ "type": "object"
175
+ },
176
+ "height": {
177
+ "type": "object"
178
+ },
179
+ "width": {
180
+ "type": "object"
181
+ },
182
+ "depth": {
183
+ "type": "object"
184
+ },
185
+ "countryOfOrigin": {
186
+ "type": "string",
187
+ "pattern": "^[A-Z]{2}$"
188
+ },
189
+ "image": {
190
+ "type": "array",
191
+ "items": {
192
+ "$ref": "#/$defs/imageObject"
193
+ }
194
+ },
195
+ "video": {
196
+ "type": "array",
197
+ "items": {
198
+ "$ref": "#/$defs/videoObject"
199
+ }
200
+ },
201
+ "additionalProperty": {
202
+ "type": "array"
203
+ },
204
+ "hasCertification": {
205
+ "type": "array",
206
+ "items": {
207
+ "$ref": "#/$defs/certification"
208
+ }
209
+ },
210
+ "manufacturer": {
211
+ "type": "object"
212
+ },
213
+ "offers": {
214
+ "type": "array",
215
+ "items": {
216
+ "oneOf": [
217
+ {
218
+ "$ref": "#/$defs/offer"
219
+ },
220
+ {
221
+ "$ref": "#/$defs/aggregateOffer"
222
+ }
223
+ ]
224
+ },
225
+ "minItems": 1
226
+ },
227
+ "aggregateRating": {
228
+ "type": "object"
229
+ },
230
+ "review": {
231
+ "type": "array"
232
+ },
233
+ "isVariantOf": {
234
+ "type": "object"
235
+ },
236
+ "isRelatedTo": {
237
+ "type": "array"
238
+ },
239
+ "isSimilarTo": {
240
+ "type": "array"
241
+ },
242
+ "isPartOf": {
243
+ "oneOf": [
244
+ {
245
+ "type": "object"
246
+ },
247
+ {
248
+ "type": "array"
249
+ }
250
+ ]
251
+ },
252
+ "hasPart": {
253
+ "oneOf": [
254
+ {
255
+ "type": "object"
256
+ },
257
+ {
258
+ "type": "array"
259
+ }
260
+ ]
261
+ },
262
+ "question": {
263
+ "type": "array",
264
+ "items": {
265
+ "$ref": "#/$defs/questionObject"
266
+ }
267
+ },
268
+ "pagefront:document": {
269
+ "type": "array",
270
+ "items": {
271
+ "$ref": "#/$defs/documentObject"
272
+ }
273
+ },
274
+ "pagefront:relatedProduct": {
275
+ "type": "array",
276
+ "items": {
277
+ "$ref": "#/$defs/relatedProductObject"
278
+ }
279
+ },
280
+ "pagefront:featureGroup": {
281
+ "type": "array",
282
+ "items": {
283
+ "$ref": "#/$defs/featureGroup"
284
+ },
285
+ "minItems": 1
286
+ },
287
+ "pagefront:productHighlights": {
288
+ "type": "array",
289
+ "items": {
290
+ "type": "string"
291
+ },
292
+ "minItems": 1
293
+ },
294
+ "pagefront:legalEntity": {
295
+ "type": "array",
296
+ "items": {
297
+ "$ref": "#/$defs/legalEntity"
298
+ },
299
+ "minItems": 1
300
+ },
301
+ "pagefront:safetyWarning": {
302
+ "type": "array",
303
+ "items": {
304
+ "$ref": "#/$defs/safetyWarning"
305
+ },
306
+ "minItems": 1
307
+ },
308
+ "pagefront:safetyNotice": {
309
+ "type": "array",
310
+ "items": {
311
+ "$ref": "#/$defs/safetyNotice"
312
+ },
313
+ "minItems": 1
314
+ },
315
+ "pagefront:sizeChart": {
316
+ "$ref": "#/$defs/sizeChart"
317
+ },
318
+ "pagefront:sizeRecommendation": {
319
+ "$ref": "#/$defs/sizeRecommendation"
320
+ },
321
+ "pagefront:materialComposition": {
322
+ "type": "array",
323
+ "items": {
324
+ "$ref": "#/$defs/material"
325
+ }
326
+ },
327
+ "pagefront:fabricComposition": {
328
+ "type": "array",
329
+ "items": {
330
+ "$ref": "#/$defs/material"
331
+ }
332
+ },
333
+ "pagefront:construction": {
334
+ "$ref": "#/$defs/construction"
335
+ },
336
+ "pagefront:manufacturingChain": {
337
+ "type": "array",
338
+ "items": {
339
+ "$ref": "#/$defs/manufacturingStage"
340
+ }
341
+ },
342
+ "pagefront:gemstone": {
343
+ "$ref": "#/$defs/gemstone"
344
+ },
345
+ "pagefront:configurator": {
346
+ "$ref": "#/$defs/configurator"
347
+ },
348
+ "pagefront:madeToOrderTerms": {
349
+ "$ref": "#/$defs/madeToOrderTerms"
350
+ },
351
+ "pagefront:careInstructions": {
352
+ "type": "array",
353
+ "items": {
354
+ "type": "string"
355
+ }
356
+ },
357
+ "pagefront:availableLanguages": {
358
+ "type": "array",
359
+ "items": {
360
+ "type": "object",
361
+ "required": [
362
+ "lang",
363
+ "url"
364
+ ],
365
+ "properties": {
366
+ "lang": {
367
+ "type": "string"
368
+ },
369
+ "url": {
370
+ "type": "string",
371
+ "format": "uri"
372
+ }
373
+ },
374
+ "additionalProperties": false
375
+ }
376
+ }
377
+ },
378
+ "if": {
379
+ "properties": {
380
+ "@type": {
381
+ "const": "ProductGroup"
382
+ }
383
+ },
384
+ "required": [
385
+ "@type"
386
+ ]
387
+ },
388
+ "then": {
389
+ "required": [
390
+ "productGroupID"
391
+ ]
392
+ },
393
+ "else": {
394
+ "required": [
395
+ "url"
396
+ ],
397
+ "anyOf": [
398
+ {
399
+ "required": [
400
+ "sku"
401
+ ]
402
+ },
403
+ {
404
+ "required": [
405
+ "gtin13"
406
+ ]
407
+ },
408
+ {
409
+ "required": [
410
+ "gtin"
411
+ ]
412
+ },
413
+ {
414
+ "required": [
415
+ "mpn"
416
+ ]
417
+ },
418
+ {
419
+ "required": [
420
+ "productID"
421
+ ]
422
+ }
423
+ ]
424
+ },
425
+ "additionalProperties": true
426
+ },
427
+ "variantEntry": {
428
+ "type": "object",
429
+ "required": [
430
+ "@type"
431
+ ],
432
+ "properties": {
433
+ "@type": {
434
+ "type": "string"
435
+ },
436
+ "@id": {
437
+ "type": "string",
438
+ "format": "uri"
439
+ },
440
+ "url": {
441
+ "type": "string",
442
+ "format": "uri"
443
+ },
444
+ "sheet_url": {
445
+ "type": "string",
446
+ "format": "uri"
447
+ },
448
+ "name": {
449
+ "type": "string"
450
+ },
451
+ "sku": {
452
+ "type": "string"
453
+ },
454
+ "gtin13": {
455
+ "$ref": "#/$defs/gtin13Value"
456
+ },
457
+ "gtin": {
458
+ "$ref": "#/$defs/gtinValue"
459
+ },
460
+ "mpn": {
461
+ "type": "string"
462
+ },
463
+ "productID": {
464
+ "type": "string"
465
+ },
466
+ "color": {
467
+ "type": "string"
468
+ },
469
+ "size": {
470
+ "type": "string"
471
+ },
472
+ "material": {
473
+ "type": "string"
474
+ },
475
+ "price": {
476
+ "type": [
477
+ "string",
478
+ "number"
479
+ ]
480
+ },
481
+ "image": {
482
+ "type": "string",
483
+ "format": "uri"
484
+ },
485
+ "additionalProperty": {
486
+ "type": "array"
487
+ }
488
+ },
489
+ "additionalProperties": true
490
+ },
491
+ "imageObject": {
492
+ "type": "object",
493
+ "required": [
494
+ "@type",
495
+ "url"
496
+ ],
497
+ "properties": {
498
+ "@type": {
499
+ "const": "ImageObject"
500
+ },
501
+ "url": {
502
+ "type": "string",
503
+ "format": "uri"
504
+ },
505
+ "caption": {
506
+ "type": "string"
507
+ },
508
+ "additionalProperty": {
509
+ "type": "array",
510
+ "items": {
511
+ "type": "object",
512
+ "properties": {
513
+ "@type": {
514
+ "const": "PropertyValue"
515
+ },
516
+ "name": {
517
+ "type": "string"
518
+ },
519
+ "value": {
520
+ "type": "string"
521
+ }
522
+ },
523
+ "allOf": [
524
+ {
525
+ "if": {
526
+ "properties": {
527
+ "name": {
528
+ "const": "role"
529
+ }
530
+ },
531
+ "required": [
532
+ "name"
533
+ ]
534
+ },
535
+ "then": {
536
+ "properties": {
537
+ "value": {
538
+ "enum": [
539
+ "hero",
540
+ "packshot",
541
+ "lifestyle",
542
+ "detail",
543
+ "flatlay",
544
+ "swatch",
545
+ "size_chart",
546
+ "context"
547
+ ]
548
+ }
549
+ }
550
+ }
551
+ }
552
+ ]
553
+ }
554
+ }
555
+ },
556
+ "additionalProperties": true
557
+ },
558
+ "videoObject": {
559
+ "type": "object",
560
+ "required": [
561
+ "@type"
562
+ ],
563
+ "properties": {
564
+ "@type": {
565
+ "const": "VideoObject"
566
+ },
567
+ "url": {
568
+ "type": "string",
569
+ "format": "uri"
570
+ },
571
+ "contentUrl": {
572
+ "type": "string",
573
+ "format": "uri"
574
+ },
575
+ "embedUrl": {
576
+ "type": "string",
577
+ "format": "uri"
578
+ },
579
+ "thumbnailUrl": {
580
+ "type": "string",
581
+ "format": "uri"
582
+ },
583
+ "duration": {
584
+ "type": "string",
585
+ "pattern": "^P(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?:\\d+H)?(?:\\d+M)?(?:\\d+(?:\\.\\d+)?S)?)?$"
586
+ },
587
+ "uploadDate": {
588
+ "type": "string"
589
+ },
590
+ "caption": {
591
+ "type": "string"
592
+ },
593
+ "transcript": {
594
+ "type": "string"
595
+ },
596
+ "description": {
597
+ "type": "string"
598
+ },
599
+ "name": {
600
+ "type": "string"
601
+ },
602
+ "additionalProperty": {
603
+ "type": "array",
604
+ "items": {
605
+ "type": "object",
606
+ "properties": {
607
+ "@type": {
608
+ "const": "PropertyValue"
609
+ },
610
+ "name": {
611
+ "type": "string"
612
+ },
613
+ "value": {
614
+ "type": "string"
615
+ }
616
+ },
617
+ "allOf": [
618
+ {
619
+ "if": {
620
+ "properties": {
621
+ "name": {
622
+ "const": "role"
623
+ }
624
+ },
625
+ "required": [
626
+ "name"
627
+ ]
628
+ },
629
+ "then": {
630
+ "properties": {
631
+ "value": {
632
+ "enum": [
633
+ "overview",
634
+ "tutorial",
635
+ "lifestyle",
636
+ "construction",
637
+ "demonstration",
638
+ "comparison",
639
+ "unboxing",
640
+ "spin"
641
+ ]
642
+ }
643
+ }
644
+ }
645
+ }
646
+ ]
647
+ }
648
+ }
649
+ },
650
+ "anyOf": [
651
+ {
652
+ "required": [
653
+ "url"
654
+ ]
655
+ },
656
+ {
657
+ "required": [
658
+ "contentUrl"
659
+ ]
660
+ },
661
+ {
662
+ "required": [
663
+ "embedUrl"
664
+ ]
665
+ }
666
+ ],
667
+ "additionalProperties": true
668
+ },
669
+ "questionObject": {
670
+ "type": "object",
671
+ "required": [
672
+ "@type",
673
+ "name",
674
+ "acceptedAnswer"
675
+ ],
676
+ "properties": {
677
+ "@type": {
678
+ "const": "Question"
679
+ },
680
+ "name": {
681
+ "type": "string",
682
+ "minLength": 1
683
+ },
684
+ "acceptedAnswer": {
685
+ "type": "object",
686
+ "required": [
687
+ "@type",
688
+ "text"
689
+ ],
690
+ "properties": {
691
+ "@type": {
692
+ "const": "Answer"
693
+ },
694
+ "text": {
695
+ "type": "string",
696
+ "minLength": 1
697
+ }
698
+ },
699
+ "additionalProperties": true
700
+ },
701
+ "suggestedAnswer": {
702
+ "type": "array",
703
+ "items": {
704
+ "type": "object",
705
+ "required": [
706
+ "@type",
707
+ "text"
708
+ ],
709
+ "properties": {
710
+ "@type": {
711
+ "const": "Answer"
712
+ },
713
+ "text": {
714
+ "type": "string",
715
+ "minLength": 1
716
+ }
717
+ },
718
+ "additionalProperties": true
719
+ }
720
+ }
721
+ },
722
+ "additionalProperties": true
723
+ },
724
+ "documentObject": {
725
+ "type": "object",
726
+ "required": [
727
+ "@type",
728
+ "url",
729
+ "role"
730
+ ],
731
+ "properties": {
732
+ "@type": {
733
+ "const": "pagefront:Document"
734
+ },
735
+ "url": {
736
+ "type": "string",
737
+ "format": "uri"
738
+ },
739
+ "role": {
740
+ "type": "string",
741
+ "enum": [
742
+ "manual",
743
+ "assembly",
744
+ "care_guide",
745
+ "spec_sheet",
746
+ "compatibility",
747
+ "warranty",
748
+ "certificate",
749
+ "environmental_declaration",
750
+ "audit_report",
751
+ "lab_test",
752
+ "safety_data_sheet",
753
+ "installation_guide",
754
+ "user_guide",
755
+ "quick_start",
756
+ "brochure",
757
+ "repairability_index",
758
+ "recall_notice",
759
+ "declaration_of_conformity"
760
+ ]
761
+ },
762
+ "name": {
763
+ "type": "string"
764
+ },
765
+ "inLanguage": {
766
+ "type": "string"
767
+ },
768
+ "description": {
769
+ "type": "string"
770
+ },
771
+ "encodingFormat": {
772
+ "type": "string"
773
+ }
774
+ },
775
+ "additionalProperties": false
776
+ },
777
+ "relatedProductObject": {
778
+ "type": "object",
779
+ "required": [
780
+ "@type",
781
+ "relationship"
782
+ ],
783
+ "properties": {
784
+ "@type": {
785
+ "const": "pagefront:RelatedProduct"
786
+ },
787
+ "relationship": {
788
+ "type": "string",
789
+ "enum": [
790
+ "accessory",
791
+ "consumable",
792
+ "required_part",
793
+ "spare_part",
794
+ "often_bought_with",
795
+ "recommended_with",
796
+ "replaces",
797
+ "replaced_by",
798
+ "bundle_component",
799
+ "compatible_with",
800
+ "service"
801
+ ]
802
+ },
803
+ "@id": {
804
+ "type": "string",
805
+ "format": "uri"
806
+ },
807
+ "sku": {
808
+ "type": "string"
809
+ },
810
+ "gtin": {
811
+ "type": "string"
812
+ },
813
+ "gtin13": {
814
+ "type": "string",
815
+ "pattern": "^[0-9]{13}$"
816
+ },
817
+ "mpn": {
818
+ "type": "string"
819
+ },
820
+ "name": {
821
+ "type": "string"
822
+ },
823
+ "url": {
824
+ "type": "string",
825
+ "format": "uri"
826
+ },
827
+ "image": {
828
+ "type": "string",
829
+ "format": "uri"
830
+ }
831
+ },
832
+ "anyOf": [
833
+ {
834
+ "required": [
835
+ "@id"
836
+ ]
837
+ },
838
+ {
839
+ "required": [
840
+ "sku"
841
+ ]
842
+ },
843
+ {
844
+ "required": [
845
+ "gtin"
846
+ ]
847
+ },
848
+ {
849
+ "required": [
850
+ "gtin13"
851
+ ]
852
+ },
853
+ {
854
+ "required": [
855
+ "mpn"
856
+ ]
857
+ }
858
+ ],
859
+ "additionalProperties": false
860
+ },
861
+ "gtinValue": {
862
+ "oneOf": [
863
+ {
864
+ "type": "string"
865
+ },
866
+ {
867
+ "type": "array",
868
+ "items": {
869
+ "type": "string"
870
+ },
871
+ "minItems": 1
872
+ }
873
+ ]
874
+ },
875
+ "gtin13Value": {
876
+ "oneOf": [
877
+ {
878
+ "type": "string",
879
+ "pattern": "^[0-9]{13}$"
880
+ },
881
+ {
882
+ "type": "array",
883
+ "items": {
884
+ "type": "string",
885
+ "pattern": "^[0-9]{13}$"
886
+ },
887
+ "minItems": 1
888
+ }
889
+ ]
890
+ },
891
+ "categoryCode": {
892
+ "type": "object",
893
+ "required": [
894
+ "@type",
895
+ "codeValue"
896
+ ],
897
+ "properties": {
898
+ "@type": {
899
+ "const": "CategoryCode"
900
+ },
901
+ "codeValue": {
902
+ "type": "string",
903
+ "minLength": 1
904
+ },
905
+ "inCodeSet": {
906
+ "oneOf": [
907
+ {
908
+ "type": "string",
909
+ "format": "uri"
910
+ },
911
+ {
912
+ "type": "object"
913
+ }
914
+ ]
915
+ },
916
+ "name": {
917
+ "type": "string"
918
+ }
919
+ },
920
+ "additionalProperties": true
921
+ },
922
+ "featureGroup": {
923
+ "type": "object",
924
+ "required": [
925
+ "@type",
926
+ "name",
927
+ "feature"
928
+ ],
929
+ "properties": {
930
+ "@type": {
931
+ "const": "pagefront:FeatureGroup"
932
+ },
933
+ "name": {
934
+ "type": "string",
935
+ "minLength": 1
936
+ },
937
+ "sortOrder": {
938
+ "type": "integer"
939
+ },
940
+ "feature": {
941
+ "type": "array",
942
+ "items": {
943
+ "$ref": "#/$defs/featureEntry"
944
+ },
945
+ "minItems": 1
946
+ }
947
+ },
948
+ "additionalProperties": false
949
+ },
950
+ "featureEntry": {
951
+ "type": "object",
952
+ "required": [
953
+ "@type",
954
+ "name",
955
+ "value"
956
+ ],
957
+ "properties": {
958
+ "@type": {
959
+ "const": "PropertyValue"
960
+ },
961
+ "propertyID": {
962
+ "type": "string"
963
+ },
964
+ "name": {
965
+ "type": "string",
966
+ "minLength": 1
967
+ },
968
+ "value": {
969
+ "anyOf": [
970
+ {
971
+ "type": "string"
972
+ },
973
+ {
974
+ "type": "number"
975
+ },
976
+ {
977
+ "type": "boolean"
978
+ }
979
+ ]
980
+ },
981
+ "unitCode": {
982
+ "type": "string"
983
+ },
984
+ "description": {
985
+ "type": "string"
986
+ },
987
+ "pagefront:presentationValue": {
988
+ "type": "string"
989
+ }
990
+ },
991
+ "additionalProperties": true
992
+ },
993
+ "legalEntity": {
994
+ "type": "object",
995
+ "required": [
996
+ "@type",
997
+ "role",
998
+ "organization"
999
+ ],
1000
+ "properties": {
1001
+ "@type": {
1002
+ "const": "pagefront:LegalEntity"
1003
+ },
1004
+ "role": {
1005
+ "type": "string",
1006
+ "enum": [
1007
+ "brand_owner",
1008
+ "licensee",
1009
+ "authorized_representative",
1010
+ "importer",
1011
+ "manufacturer"
1012
+ ]
1013
+ },
1014
+ "organization": {
1015
+ "type": "object",
1016
+ "required": [
1017
+ "@type"
1018
+ ],
1019
+ "anyOf": [
1020
+ {
1021
+ "required": [
1022
+ "name"
1023
+ ]
1024
+ },
1025
+ {
1026
+ "required": [
1027
+ "@id"
1028
+ ]
1029
+ }
1030
+ ],
1031
+ "properties": {
1032
+ "@type": {
1033
+ "const": "Organization"
1034
+ },
1035
+ "@id": {
1036
+ "type": "string",
1037
+ "format": "uri"
1038
+ },
1039
+ "name": {
1040
+ "type": "string",
1041
+ "minLength": 1
1042
+ },
1043
+ "address": {
1044
+ "type": "object"
1045
+ },
1046
+ "url": {
1047
+ "type": "string",
1048
+ "format": "uri"
1049
+ },
1050
+ "email": {
1051
+ "type": "string",
1052
+ "format": "email"
1053
+ }
1054
+ },
1055
+ "additionalProperties": true
1056
+ }
1057
+ },
1058
+ "additionalProperties": false
1059
+ },
1060
+ "safetyWarning": {
1061
+ "type": "object",
1062
+ "required": [
1063
+ "@type",
1064
+ "text"
1065
+ ],
1066
+ "properties": {
1067
+ "@type": {
1068
+ "const": "pagefront:SafetyWarning"
1069
+ },
1070
+ "text": {
1071
+ "type": "string",
1072
+ "minLength": 1
1073
+ },
1074
+ "pictogram": {
1075
+ "type": "string",
1076
+ "format": "uri"
1077
+ },
1078
+ "hazardCategory": {
1079
+ "type": "string"
1080
+ }
1081
+ },
1082
+ "additionalProperties": false
1083
+ },
1084
+ "safetyNotice": {
1085
+ "type": "object",
1086
+ "required": [
1087
+ "@type",
1088
+ "noticeType"
1089
+ ],
1090
+ "properties": {
1091
+ "@type": {
1092
+ "const": "pagefront:SafetyNotice"
1093
+ },
1094
+ "noticeType": {
1095
+ "type": "string",
1096
+ "enum": [
1097
+ "recall",
1098
+ "warning"
1099
+ ]
1100
+ },
1101
+ "hazard": {
1102
+ "type": "string"
1103
+ },
1104
+ "remedy": {
1105
+ "type": "string",
1106
+ "enum": [
1107
+ "repair",
1108
+ "replacement",
1109
+ "refund"
1110
+ ]
1111
+ },
1112
+ "description": {
1113
+ "type": "string"
1114
+ },
1115
+ "reference": {
1116
+ "type": "string",
1117
+ "format": "uri"
1118
+ },
1119
+ "datePublished": {
1120
+ "type": "string",
1121
+ "format": "date"
1122
+ },
1123
+ "url": {
1124
+ "type": "string",
1125
+ "format": "uri"
1126
+ }
1127
+ },
1128
+ "additionalProperties": false
1129
+ },
1130
+ "certification": {
1131
+ "type": "object",
1132
+ "required": [
1133
+ "@type",
1134
+ "name"
1135
+ ],
1136
+ "properties": {
1137
+ "@type": {
1138
+ "const": "Certification"
1139
+ },
1140
+ "name": {
1141
+ "type": "string"
1142
+ },
1143
+ "issuedBy": {
1144
+ "type": "object"
1145
+ },
1146
+ "about": {
1147
+ "type": "string"
1148
+ },
1149
+ "additionalProperty": {
1150
+ "type": "array"
1151
+ }
1152
+ },
1153
+ "additionalProperties": true
1154
+ },
1155
+ "offer": {
1156
+ "type": "object",
1157
+ "required": [
1158
+ "@type"
1159
+ ],
1160
+ "properties": {
1161
+ "@type": {
1162
+ "const": "Offer"
1163
+ },
1164
+ "@id": {
1165
+ "type": "string"
1166
+ },
1167
+ "itemOffered": {
1168
+ "type": "object"
1169
+ },
1170
+ "price": {
1171
+ "type": "string"
1172
+ },
1173
+ "priceCurrency": {
1174
+ "type": "string",
1175
+ "pattern": "^[A-Z]{3}$"
1176
+ },
1177
+ "priceSpecification": {
1178
+ "oneOf": [
1179
+ {
1180
+ "type": "object"
1181
+ },
1182
+ {
1183
+ "type": "array",
1184
+ "items": {
1185
+ "type": "object"
1186
+ }
1187
+ }
1188
+ ]
1189
+ },
1190
+ "availability": {
1191
+ "type": "string",
1192
+ "pattern": "^https?://schema\\.org/(InStock|OutOfStock|PreOrder|BackOrder|InStoreOnly|LimitedAvailability|MadeToOrder|OnlineOnly|SoldOut|Discontinued|Reserved)$"
1193
+ },
1194
+ "itemCondition": {
1195
+ "type": "string",
1196
+ "pattern": "^https?://schema\\.org/(NewCondition|UsedCondition|RefurbishedCondition|DamagedCondition)$"
1197
+ },
1198
+ "seller": {
1199
+ "type": "object"
1200
+ },
1201
+ "shippingDetails": {
1202
+ "oneOf": [
1203
+ {
1204
+ "type": "object"
1205
+ },
1206
+ {
1207
+ "type": "array",
1208
+ "items": {
1209
+ "type": "object"
1210
+ }
1211
+ }
1212
+ ]
1213
+ },
1214
+ "hasMerchantReturnPolicy": {
1215
+ "type": "object"
1216
+ },
1217
+ "areaServed": {},
1218
+ "eligibleRegion": {
1219
+ "type": "array"
1220
+ },
1221
+ "acceptedPaymentMethod": {
1222
+ "type": "array"
1223
+ },
1224
+ "pagefront:estimatedDelivery": {
1225
+ "$ref": "#/$defs/deliveryEstimate"
1226
+ },
1227
+ "pagefront:promotions": {
1228
+ "type": "array",
1229
+ "items": {
1230
+ "$ref": "#/$defs/promotion"
1231
+ }
1232
+ },
1233
+ "pagefront:priceOnRequest": {
1234
+ "$ref": "#/$defs/priceOnRequest"
1235
+ }
1236
+ },
1237
+ "anyOf": [
1238
+ {
1239
+ "required": [
1240
+ "price",
1241
+ "priceCurrency"
1242
+ ]
1243
+ },
1244
+ {
1245
+ "required": [
1246
+ "priceSpecification"
1247
+ ]
1248
+ },
1249
+ {
1250
+ "required": [
1251
+ "pagefront:priceOnRequest"
1252
+ ]
1253
+ }
1254
+ ],
1255
+ "additionalProperties": true
1256
+ },
1257
+ "aggregateOffer": {
1258
+ "type": "object",
1259
+ "required": [
1260
+ "@type",
1261
+ "lowPrice",
1262
+ "highPrice",
1263
+ "priceCurrency"
1264
+ ],
1265
+ "properties": {
1266
+ "@type": {
1267
+ "const": "AggregateOffer"
1268
+ },
1269
+ "@id": {
1270
+ "type": "string"
1271
+ },
1272
+ "lowPrice": {
1273
+ "type": "number"
1274
+ },
1275
+ "highPrice": {
1276
+ "type": "number"
1277
+ },
1278
+ "priceCurrency": {
1279
+ "type": "string",
1280
+ "pattern": "^[A-Z]{3}$"
1281
+ },
1282
+ "offerCount": {
1283
+ "type": "integer"
1284
+ },
1285
+ "availability": {
1286
+ "type": "string",
1287
+ "pattern": "^https?://schema\\.org/(InStock|OutOfStock|PreOrder|BackOrder|InStoreOnly|LimitedAvailability|MadeToOrder|OnlineOnly|SoldOut|Discontinued|Reserved)$"
1288
+ },
1289
+ "itemCondition": {
1290
+ "type": "string",
1291
+ "pattern": "^https?://schema\\.org/(NewCondition|UsedCondition|RefurbishedCondition|DamagedCondition)$"
1292
+ },
1293
+ "eligibleRegion": {
1294
+ "type": "array"
1295
+ },
1296
+ "areaServed": {},
1297
+ "validFrom": {
1298
+ "type": "string"
1299
+ },
1300
+ "validThrough": {
1301
+ "type": "string"
1302
+ },
1303
+ "seller": {
1304
+ "type": "object"
1305
+ }
1306
+ },
1307
+ "additionalProperties": true
1308
+ },
1309
+ "priceOnRequest": {
1310
+ "type": "object",
1311
+ "required": [
1312
+ "@type",
1313
+ "method"
1314
+ ],
1315
+ "properties": {
1316
+ "@type": {
1317
+ "const": "pagefront:PriceOnRequest"
1318
+ },
1319
+ "method": {
1320
+ "type": "string",
1321
+ "enum": [
1322
+ "authorized_retailer",
1323
+ "dealer_network",
1324
+ "quote_form",
1325
+ "email",
1326
+ "phone",
1327
+ "unspecified"
1328
+ ]
1329
+ },
1330
+ "contactUrl": {
1331
+ "type": "string",
1332
+ "format": "uri"
1333
+ },
1334
+ "contactEmail": {
1335
+ "type": "string",
1336
+ "format": "email"
1337
+ },
1338
+ "contactPhone": {
1339
+ "type": "string"
1340
+ },
1341
+ "note": {
1342
+ "type": "string"
1343
+ }
1344
+ },
1345
+ "additionalProperties": false
1346
+ },
1347
+ "sizeChart": {
1348
+ "type": "object",
1349
+ "required": [
1350
+ "@type",
1351
+ "unitCode",
1352
+ "sizes",
1353
+ "measurements"
1354
+ ],
1355
+ "properties": {
1356
+ "@type": {
1357
+ "const": "pagefront:SizeChart"
1358
+ },
1359
+ "unitCode": {
1360
+ "type": "string"
1361
+ },
1362
+ "sizes": {
1363
+ "type": "array",
1364
+ "items": {
1365
+ "type": "string"
1366
+ },
1367
+ "minItems": 1
1368
+ },
1369
+ "measurements": {
1370
+ "type": "array",
1371
+ "items": {
1372
+ "$ref": "#/$defs/measurement"
1373
+ },
1374
+ "minItems": 1
1375
+ },
1376
+ "modelReferences": {
1377
+ "type": "array",
1378
+ "items": {
1379
+ "$ref": "#/$defs/modelReference"
1380
+ }
1381
+ }
1382
+ },
1383
+ "additionalProperties": false
1384
+ },
1385
+ "measurement": {
1386
+ "type": "object",
1387
+ "required": [
1388
+ "@type",
1389
+ "name",
1390
+ "values"
1391
+ ],
1392
+ "properties": {
1393
+ "@type": {
1394
+ "const": "pagefront:Measurement"
1395
+ },
1396
+ "name": {
1397
+ "type": "string"
1398
+ },
1399
+ "values": {
1400
+ "type": "object",
1401
+ "additionalProperties": {
1402
+ "type": "number"
1403
+ }
1404
+ }
1405
+ },
1406
+ "additionalProperties": false
1407
+ },
1408
+ "modelReference": {
1409
+ "type": "object",
1410
+ "required": [
1411
+ "@type",
1412
+ "name"
1413
+ ],
1414
+ "properties": {
1415
+ "@type": {
1416
+ "const": "pagefront:ModelReference"
1417
+ },
1418
+ "name": {
1419
+ "type": "string"
1420
+ },
1421
+ "heightCm": {
1422
+ "type": "number",
1423
+ "minimum": 0
1424
+ },
1425
+ "wearsSize": {
1426
+ "type": "string"
1427
+ }
1428
+ },
1429
+ "additionalProperties": false
1430
+ },
1431
+ "sizeRecommendation": {
1432
+ "type": "object",
1433
+ "required": [
1434
+ "@type"
1435
+ ],
1436
+ "properties": {
1437
+ "@type": {
1438
+ "const": "pagefront:SizeRecommendation"
1439
+ },
1440
+ "fitProfile": {
1441
+ "type": "string",
1442
+ "enum": [
1443
+ "runs_small",
1444
+ "true_to_size",
1445
+ "runs_large"
1446
+ ]
1447
+ },
1448
+ "sizeAdjustment": {
1449
+ "$ref": "#/$defs/sizeAdjustment"
1450
+ },
1451
+ "description": {
1452
+ "type": "string"
1453
+ },
1454
+ "appliesTo": {
1455
+ "type": "string"
1456
+ }
1457
+ },
1458
+ "additionalProperties": false
1459
+ },
1460
+ "sizeAdjustment": {
1461
+ "type": "object",
1462
+ "required": [
1463
+ "@type",
1464
+ "direction",
1465
+ "magnitude"
1466
+ ],
1467
+ "properties": {
1468
+ "@type": {
1469
+ "const": "pagefront:SizeAdjustment"
1470
+ },
1471
+ "direction": {
1472
+ "type": "string",
1473
+ "enum": [
1474
+ "up",
1475
+ "down"
1476
+ ]
1477
+ },
1478
+ "magnitude": {
1479
+ "type": "number",
1480
+ "minimum": 0
1481
+ },
1482
+ "sizeSystem": {
1483
+ "type": "string"
1484
+ }
1485
+ },
1486
+ "additionalProperties": false
1487
+ },
1488
+ "material": {
1489
+ "type": "object",
1490
+ "required": [
1491
+ "@type",
1492
+ "material"
1493
+ ],
1494
+ "properties": {
1495
+ "@type": {
1496
+ "const": "pagefront:Material"
1497
+ },
1498
+ "material": {
1499
+ "type": "string"
1500
+ },
1501
+ "percentage": {
1502
+ "type": "number",
1503
+ "minimum": 0,
1504
+ "maximum": 100
1505
+ },
1506
+ "purity": {
1507
+ "type": "string"
1508
+ },
1509
+ "purityPercentage": {
1510
+ "type": "number",
1511
+ "minimum": 0,
1512
+ "maximum": 100
1513
+ },
1514
+ "provenance": {
1515
+ "type": "string",
1516
+ "enum": [
1517
+ "virgin",
1518
+ "recycled",
1519
+ "fair_mined",
1520
+ "lab_grown",
1521
+ "reclaimed",
1522
+ "deadstock"
1523
+ ]
1524
+ },
1525
+ "weightGrams": {
1526
+ "type": "number",
1527
+ "minimum": 0
1528
+ }
1529
+ },
1530
+ "additionalProperties": false
1531
+ },
1532
+ "construction": {
1533
+ "type": "object",
1534
+ "required": [
1535
+ "@type"
1536
+ ],
1537
+ "properties": {
1538
+ "@type": {
1539
+ "const": "pagefront:Construction"
1540
+ },
1541
+ "stitch": {
1542
+ "type": "string"
1543
+ },
1544
+ "gauge": {
1545
+ "type": "number"
1546
+ },
1547
+ "machine": {
1548
+ "type": "string"
1549
+ },
1550
+ "constructionNotes": {
1551
+ "type": "string"
1552
+ }
1553
+ },
1554
+ "additionalProperties": true
1555
+ },
1556
+ "manufacturingStage": {
1557
+ "type": "object",
1558
+ "required": [
1559
+ "@type",
1560
+ "stage",
1561
+ "country"
1562
+ ],
1563
+ "properties": {
1564
+ "@type": {
1565
+ "const": "pagefront:ManufacturingStage"
1566
+ },
1567
+ "stage": {
1568
+ "type": "string"
1569
+ },
1570
+ "country": {
1571
+ "type": "string",
1572
+ "pattern": "^[A-Z]{2}$"
1573
+ },
1574
+ "facility": {
1575
+ "type": "string"
1576
+ },
1577
+ "facilityCountry": {
1578
+ "type": "string",
1579
+ "pattern": "^[A-Z]{2}$"
1580
+ }
1581
+ },
1582
+ "additionalProperties": false
1583
+ },
1584
+ "gemstone": {
1585
+ "type": "object",
1586
+ "required": [
1587
+ "@type",
1588
+ "type"
1589
+ ],
1590
+ "properties": {
1591
+ "@type": {
1592
+ "const": "pagefront:Gemstone"
1593
+ },
1594
+ "type": {
1595
+ "type": "string"
1596
+ },
1597
+ "origin": {
1598
+ "type": "string",
1599
+ "enum": [
1600
+ "natural_mined",
1601
+ "lab_grown",
1602
+ "treated",
1603
+ "synthetic"
1604
+ ]
1605
+ },
1606
+ "shape": {
1607
+ "type": "string"
1608
+ },
1609
+ "caratWeight": {
1610
+ "type": "number",
1611
+ "minimum": 0
1612
+ },
1613
+ "colorGrade": {
1614
+ "type": "string"
1615
+ },
1616
+ "clarityGrade": {
1617
+ "type": "string"
1618
+ },
1619
+ "cutGrade": {
1620
+ "type": "string"
1621
+ },
1622
+ "certifyingBody": {
1623
+ "type": "string"
1624
+ }
1625
+ },
1626
+ "additionalProperties": false
1627
+ },
1628
+ "configurator": {
1629
+ "type": "object",
1630
+ "required": [
1631
+ "@type",
1632
+ "dimensions"
1633
+ ],
1634
+ "properties": {
1635
+ "@type": {
1636
+ "const": "pagefront:Configurator"
1637
+ },
1638
+ "basePrice": {
1639
+ "type": "string"
1640
+ },
1641
+ "basePriceCurrency": {
1642
+ "type": "string",
1643
+ "pattern": "^[A-Z]{3}$"
1644
+ },
1645
+ "priceFormula": {
1646
+ "type": "string"
1647
+ },
1648
+ "dimensions": {
1649
+ "type": "array",
1650
+ "items": {
1651
+ "$ref": "#/$defs/configuratorDimension"
1652
+ },
1653
+ "minItems": 1
1654
+ }
1655
+ },
1656
+ "additionalProperties": false
1657
+ },
1658
+ "configuratorDimension": {
1659
+ "type": "object",
1660
+ "required": [
1661
+ "name"
1662
+ ],
1663
+ "properties": {
1664
+ "name": {
1665
+ "type": "string"
1666
+ },
1667
+ "options": {
1668
+ "type": "array",
1669
+ "items": {
1670
+ "type": "object",
1671
+ "required": [
1672
+ "value"
1673
+ ],
1674
+ "properties": {
1675
+ "value": {
1676
+ "anyOf": [
1677
+ {
1678
+ "type": "string"
1679
+ },
1680
+ {
1681
+ "type": "number"
1682
+ },
1683
+ {
1684
+ "type": "boolean"
1685
+ }
1686
+ ]
1687
+ },
1688
+ "priceModifier": {
1689
+ "type": "string"
1690
+ },
1691
+ "currency": {
1692
+ "type": "string",
1693
+ "pattern": "^[A-Z]{3}$"
1694
+ },
1695
+ "description": {
1696
+ "type": "string"
1697
+ }
1698
+ },
1699
+ "additionalProperties": true
1700
+ }
1701
+ },
1702
+ "system": {
1703
+ "type": "string"
1704
+ },
1705
+ "note": {
1706
+ "type": "string"
1707
+ }
1708
+ },
1709
+ "additionalProperties": false
1710
+ },
1711
+ "madeToOrderTerms": {
1712
+ "type": "object",
1713
+ "required": [
1714
+ "@type"
1715
+ ],
1716
+ "properties": {
1717
+ "@type": {
1718
+ "const": "pagefront:MadeToOrderTerms"
1719
+ },
1720
+ "productionLeadTime": {
1721
+ "$ref": "#/$defs/duration"
1722
+ },
1723
+ "cancellationPolicy": {
1724
+ "type": "string"
1725
+ },
1726
+ "returnsExceptions": {
1727
+ "type": "array",
1728
+ "items": {
1729
+ "type": "string"
1730
+ }
1731
+ },
1732
+ "aftermarketServices": {
1733
+ "type": "array",
1734
+ "items": {
1735
+ "$ref": "#/$defs/aftermarketService"
1736
+ }
1737
+ }
1738
+ },
1739
+ "additionalProperties": false
1740
+ },
1741
+ "duration": {
1742
+ "type": "object",
1743
+ "required": [
1744
+ "@type"
1745
+ ],
1746
+ "properties": {
1747
+ "@type": {
1748
+ "const": "pagefront:Duration"
1749
+ },
1750
+ "minDays": {
1751
+ "type": "integer",
1752
+ "minimum": 0
1753
+ },
1754
+ "maxDays": {
1755
+ "type": "integer",
1756
+ "minimum": 0
1757
+ },
1758
+ "description": {
1759
+ "type": "string"
1760
+ }
1761
+ },
1762
+ "additionalProperties": false
1763
+ },
1764
+ "deliveryEstimate": {
1765
+ "type": "object",
1766
+ "required": [
1767
+ "@type"
1768
+ ],
1769
+ "properties": {
1770
+ "@type": {
1771
+ "const": "pagefront:DeliveryEstimate"
1772
+ },
1773
+ "earliest": {
1774
+ "type": "string",
1775
+ "format": "date"
1776
+ },
1777
+ "latest": {
1778
+ "type": "string",
1779
+ "format": "date"
1780
+ },
1781
+ "description": {
1782
+ "type": "string"
1783
+ }
1784
+ },
1785
+ "additionalProperties": false
1786
+ },
1787
+ "aftermarketService": {
1788
+ "type": "object",
1789
+ "required": [
1790
+ "@type",
1791
+ "service"
1792
+ ],
1793
+ "properties": {
1794
+ "@type": {
1795
+ "const": "pagefront:AftermarketService"
1796
+ },
1797
+ "service": {
1798
+ "type": "string"
1799
+ },
1800
+ "limit": {
1801
+ "type": "string"
1802
+ },
1803
+ "description": {
1804
+ "type": "string"
1805
+ }
1806
+ },
1807
+ "additionalProperties": false
1808
+ },
1809
+ "promotion": {
1810
+ "type": "object",
1811
+ "required": [
1812
+ "@type",
1813
+ "scope"
1814
+ ],
1815
+ "properties": {
1816
+ "@type": {
1817
+ "const": "pagefront:Promotion"
1818
+ },
1819
+ "code": {
1820
+ "type": "string"
1821
+ },
1822
+ "discountPercentage": {
1823
+ "type": "number",
1824
+ "minimum": 0,
1825
+ "maximum": 100
1826
+ },
1827
+ "discountAmount": {
1828
+ "type": "string"
1829
+ },
1830
+ "discountCurrency": {
1831
+ "type": "string",
1832
+ "pattern": "^[A-Z]{3}$"
1833
+ },
1834
+ "scope": {
1835
+ "type": "string",
1836
+ "enum": [
1837
+ "product",
1838
+ "category",
1839
+ "site_wide"
1840
+ ]
1841
+ },
1842
+ "occasion": {
1843
+ "type": "string"
1844
+ },
1845
+ "validUntil": {
1846
+ "type": "string",
1847
+ "format": "date-time"
1848
+ }
1849
+ },
1850
+ "additionalProperties": false
1851
+ }
1852
+ }
1853
+ };