@pagefront/lint-commerce 0.8.0 → 0.10.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 (55) hide show
  1. package/README.md +64 -6
  2. package/dist/catalogue.js +12 -3
  3. package/dist/index.d.ts +7 -4
  4. package/dist/index.js +6 -3
  5. package/dist/legacy-schemas.d.ts +9 -0
  6. package/dist/legacy-schemas.js +2446 -0
  7. package/dist/organization-catalogue.js +6 -3
  8. package/dist/organization-schema.d.ts +2 -1
  9. package/dist/organization-schema.js +9 -7
  10. package/dist/product-schema.d.ts +2 -2
  11. package/dist/product-schema.js +54 -22
  12. package/dist/releases.d.ts +36 -0
  13. package/dist/releases.js +41 -0
  14. package/dist/rules/configurator-pricing.d.ts +21 -2
  15. package/dist/rules/configurator-pricing.js +41 -5
  16. package/dist/rules/org-e-002.d.ts +7 -0
  17. package/dist/rules/org-e-002.js +13 -0
  18. package/dist/rules/org-e-003.d.ts +7 -0
  19. package/dist/rules/org-e-003.js +13 -0
  20. package/dist/rules/pdp-e-002.d.ts +3 -9
  21. package/dist/rules/pdp-e-002.js +6 -26
  22. package/dist/rules/pdp-e-008.js +1 -1
  23. package/dist/rules/pdp-e-009.d.ts +1 -1
  24. package/dist/rules/pdp-e-009.js +3 -3
  25. package/dist/rules/pdp-e-013.d.ts +9 -0
  26. package/dist/rules/pdp-e-013.js +26 -0
  27. package/dist/rules/pdp-e-014.d.ts +11 -0
  28. package/dist/rules/pdp-e-014.js +34 -0
  29. package/dist/rules/pdp-e-015.d.ts +2 -0
  30. package/dist/rules/pdp-e-015.js +91 -0
  31. package/dist/rules/pdp-e-016.d.ts +7 -0
  32. package/dist/rules/pdp-e-016.js +13 -0
  33. package/dist/rules/pdp-w-032.d.ts +3 -2
  34. package/dist/rules/pdp-w-032.js +20 -12
  35. package/dist/rules/pdp-w-036.d.ts +2 -0
  36. package/dist/rules/pdp-w-036.js +31 -0
  37. package/dist/rules/pdp-w-037.d.ts +2 -0
  38. package/dist/rules/pdp-w-037.js +37 -0
  39. package/dist/rules/pdp-w-038.d.ts +2 -0
  40. package/dist/rules/pdp-w-038.js +30 -0
  41. package/dist/rules/pdp-w-039.d.ts +10 -0
  42. package/dist/rules/pdp-w-039.js +29 -0
  43. package/dist/rules/release-schema.d.ts +16 -0
  44. package/dist/rules/release-schema.js +77 -0
  45. package/dist/schema-validators.d.ts +2 -0
  46. package/dist/schema-validators.js +10 -4
  47. package/dist/sheet-type.d.ts +17 -0
  48. package/dist/sheet-type.js +25 -0
  49. package/dist/validate-and-lint.d.ts +9 -5
  50. package/dist/validate-and-lint.js +17 -9
  51. package/dist/validate-organization.d.ts +4 -4
  52. package/dist/validate-organization.js +8 -5
  53. package/dist/version.d.ts +1 -1
  54. package/dist/version.js +1 -1
  55. package/package.json +2 -2
@@ -0,0 +1,2446 @@
1
+ /**
2
+ * The legacy draft line's JSON Schemas (commerce/spec/legacy/*.v0.9.json),
3
+ * bundled verbatim so sheets carrying `format_version` keep validating
4
+ * against the schemas their `$schema` URLs name. The files are frozen:
5
+ * the schema drift test (test/schema.test.mjs) fails if a bundled copy
6
+ * and its source diverge.
7
+ */
8
+ export const LEGACY_PRODUCT_SCHEMA = {
9
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
10
+ "$id": "https://themachineweb.org/pagefront/spec/commerce/product/v0.9.json",
11
+ "title": "Pagefront Product Sheet v0.9",
12
+ "description": "Formal schema for the Pagefront product sheet. Revision of 2026-10-01 (breaking, within v0.9): configurator pricing moves from pagefront:configurator to the offer. The configurator loses basePrice, basePriceCurrency and priceFormula, its options lose priceModifier and currency, and it gains an optional @id and an exclusions[] array; configurator dimensions gain affectsPrice, inputType (select or text, for free-text dimensions) and maxLength; Offer and AggregateOffer accept pagefront:configuratorPricing, which names the configurator it prices and carries baseConfiguration, basePrice, modifiers, optional adjustments[] and a pricing completeness flag; every amount field (Offer price, AggregateOffer lowPrice and highPrice, variant price hints, promotion discountAmount, and the pricing block's basePrice, modifiers and adjustment amounts) references a shared definition, a JSON number or a plain decimal string: nonNegativeAmount for prices, bounds, base prices, price hints and discount amounts, and the signed amount for modifiers and adjustment amounts. v0.9 sheets that carried prices inside the configurator no longer validate. v0.9 was otherwise 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.",
13
+ "type": "object",
14
+ "required": [
15
+ "format_version",
16
+ "schema_org_version",
17
+ "canonical_url",
18
+ "sheet_url",
19
+ "generated_at",
20
+ "data"
21
+ ],
22
+ "properties": {
23
+ "$schema": {
24
+ "type": "string",
25
+ "format": "uri"
26
+ },
27
+ "format_version": {
28
+ "const": "0.9"
29
+ },
30
+ "schema_org_version": {
31
+ "type": "string",
32
+ "pattern": "^\\d+(\\.\\d+)?$"
33
+ },
34
+ "canonical_url": {
35
+ "type": "string",
36
+ "format": "uri"
37
+ },
38
+ "sheet_url": {
39
+ "type": "string",
40
+ "format": "uri"
41
+ },
42
+ "generated_at": {
43
+ "type": "string",
44
+ "format": "date-time"
45
+ },
46
+ "expires_at": {
47
+ "type": "string",
48
+ "format": "date-time"
49
+ },
50
+ "data": {
51
+ "$ref": "#/$defs/dataBlock"
52
+ }
53
+ },
54
+ "additionalProperties": false,
55
+ "$defs": {
56
+ "dataBlock": {
57
+ "type": "object",
58
+ "required": [
59
+ "@context",
60
+ "@type",
61
+ "@id",
62
+ "name",
63
+ "inLanguage"
64
+ ],
65
+ "properties": {
66
+ "@context": {
67
+ "oneOf": [
68
+ {
69
+ "const": "https://schema.org"
70
+ },
71
+ {
72
+ "type": "array",
73
+ "items": {
74
+ "oneOf": [
75
+ {
76
+ "type": "string",
77
+ "format": "uri"
78
+ },
79
+ {
80
+ "type": "object"
81
+ }
82
+ ]
83
+ },
84
+ "minItems": 1
85
+ }
86
+ ]
87
+ },
88
+ "@type": {
89
+ "type": "string"
90
+ },
91
+ "@id": {
92
+ "type": "string",
93
+ "format": "uri"
94
+ },
95
+ "url": {
96
+ "type": "string",
97
+ "format": "uri"
98
+ },
99
+ "name": {
100
+ "type": "string",
101
+ "minLength": 1
102
+ },
103
+ "inLanguage": {
104
+ "type": "string"
105
+ },
106
+ "sku": {
107
+ "type": "string"
108
+ },
109
+ "gtin13": {
110
+ "$ref": "#/$defs/gtin13Value"
111
+ },
112
+ "gtin": {
113
+ "$ref": "#/$defs/gtinValue"
114
+ },
115
+ "mpn": {
116
+ "type": "string"
117
+ },
118
+ "productID": {
119
+ "type": "string"
120
+ },
121
+ "productGroupID": {
122
+ "type": "string"
123
+ },
124
+ "variesBy": {
125
+ "type": "array",
126
+ "items": {
127
+ "type": "string"
128
+ }
129
+ },
130
+ "hasVariant": {
131
+ "type": "array",
132
+ "items": {
133
+ "$ref": "#/$defs/variantEntry"
134
+ }
135
+ },
136
+ "brand": {
137
+ "type": "object",
138
+ "properties": {
139
+ "pagefront:sheetUrl": {
140
+ "type": "string",
141
+ "format": "uri"
142
+ }
143
+ }
144
+ },
145
+ "description": {
146
+ "type": "string"
147
+ },
148
+ "category": {
149
+ "oneOf": [
150
+ {
151
+ "type": "string"
152
+ },
153
+ {
154
+ "$ref": "#/$defs/categoryCode"
155
+ },
156
+ {
157
+ "type": "array",
158
+ "items": {
159
+ "oneOf": [
160
+ {
161
+ "type": "string"
162
+ },
163
+ {
164
+ "$ref": "#/$defs/categoryCode"
165
+ }
166
+ ]
167
+ },
168
+ "minItems": 1
169
+ }
170
+ ]
171
+ },
172
+ "color": {
173
+ "type": "string"
174
+ },
175
+ "material": {
176
+ "type": "string"
177
+ },
178
+ "weight": {
179
+ "type": "object"
180
+ },
181
+ "height": {
182
+ "type": "object"
183
+ },
184
+ "width": {
185
+ "type": "object"
186
+ },
187
+ "depth": {
188
+ "type": "object"
189
+ },
190
+ "countryOfOrigin": {
191
+ "type": "string",
192
+ "pattern": "^[A-Z]{2}$"
193
+ },
194
+ "image": {
195
+ "type": "array",
196
+ "items": {
197
+ "$ref": "#/$defs/imageObject"
198
+ }
199
+ },
200
+ "video": {
201
+ "type": "array",
202
+ "items": {
203
+ "$ref": "#/$defs/videoObject"
204
+ }
205
+ },
206
+ "additionalProperty": {
207
+ "type": "array"
208
+ },
209
+ "hasCertification": {
210
+ "type": "array",
211
+ "items": {
212
+ "$ref": "#/$defs/certification"
213
+ }
214
+ },
215
+ "manufacturer": {
216
+ "type": "object"
217
+ },
218
+ "offers": {
219
+ "type": "array",
220
+ "items": {
221
+ "oneOf": [
222
+ {
223
+ "$ref": "#/$defs/offer"
224
+ },
225
+ {
226
+ "$ref": "#/$defs/aggregateOffer"
227
+ }
228
+ ]
229
+ },
230
+ "minItems": 1
231
+ },
232
+ "aggregateRating": {
233
+ "type": "object"
234
+ },
235
+ "review": {
236
+ "type": "array"
237
+ },
238
+ "isVariantOf": {
239
+ "type": "object"
240
+ },
241
+ "isRelatedTo": {
242
+ "type": "array"
243
+ },
244
+ "isSimilarTo": {
245
+ "type": "array"
246
+ },
247
+ "isPartOf": {
248
+ "oneOf": [
249
+ {
250
+ "type": "object"
251
+ },
252
+ {
253
+ "type": "array"
254
+ }
255
+ ]
256
+ },
257
+ "hasPart": {
258
+ "oneOf": [
259
+ {
260
+ "type": "object"
261
+ },
262
+ {
263
+ "type": "array"
264
+ }
265
+ ]
266
+ },
267
+ "question": {
268
+ "type": "array",
269
+ "items": {
270
+ "$ref": "#/$defs/questionObject"
271
+ }
272
+ },
273
+ "pagefront:document": {
274
+ "type": "array",
275
+ "items": {
276
+ "$ref": "#/$defs/documentObject"
277
+ }
278
+ },
279
+ "pagefront:relatedProduct": {
280
+ "type": "array",
281
+ "items": {
282
+ "$ref": "#/$defs/relatedProductObject"
283
+ }
284
+ },
285
+ "pagefront:featureGroup": {
286
+ "type": "array",
287
+ "items": {
288
+ "$ref": "#/$defs/featureGroup"
289
+ },
290
+ "minItems": 1
291
+ },
292
+ "pagefront:productHighlights": {
293
+ "type": "array",
294
+ "items": {
295
+ "type": "string"
296
+ },
297
+ "minItems": 1
298
+ },
299
+ "pagefront:legalEntity": {
300
+ "type": "array",
301
+ "items": {
302
+ "$ref": "#/$defs/legalEntity"
303
+ },
304
+ "minItems": 1
305
+ },
306
+ "pagefront:safetyWarning": {
307
+ "type": "array",
308
+ "items": {
309
+ "$ref": "#/$defs/safetyWarning"
310
+ },
311
+ "minItems": 1
312
+ },
313
+ "pagefront:safetyNotice": {
314
+ "type": "array",
315
+ "items": {
316
+ "$ref": "#/$defs/safetyNotice"
317
+ },
318
+ "minItems": 1
319
+ },
320
+ "pagefront:sizeChart": {
321
+ "$ref": "#/$defs/sizeChart"
322
+ },
323
+ "pagefront:sizeRecommendation": {
324
+ "$ref": "#/$defs/sizeRecommendation"
325
+ },
326
+ "pagefront:materialComposition": {
327
+ "type": "array",
328
+ "items": {
329
+ "$ref": "#/$defs/material"
330
+ }
331
+ },
332
+ "pagefront:fabricComposition": {
333
+ "type": "array",
334
+ "items": {
335
+ "$ref": "#/$defs/material"
336
+ }
337
+ },
338
+ "pagefront:construction": {
339
+ "$ref": "#/$defs/construction"
340
+ },
341
+ "pagefront:manufacturingChain": {
342
+ "type": "array",
343
+ "items": {
344
+ "$ref": "#/$defs/manufacturingStage"
345
+ }
346
+ },
347
+ "pagefront:gemstone": {
348
+ "$ref": "#/$defs/gemstone"
349
+ },
350
+ "pagefront:configurator": {
351
+ "$ref": "#/$defs/configurator"
352
+ },
353
+ "pagefront:madeToOrderTerms": {
354
+ "$ref": "#/$defs/madeToOrderTerms"
355
+ },
356
+ "pagefront:manufacturerWarranty": {
357
+ "type": "object"
358
+ },
359
+ "pagefront:careInstructions": {
360
+ "type": "array",
361
+ "items": {
362
+ "type": "string"
363
+ }
364
+ },
365
+ "pagefront:availableLanguages": {
366
+ "type": "array",
367
+ "items": {
368
+ "type": "object",
369
+ "required": [
370
+ "lang",
371
+ "url"
372
+ ],
373
+ "properties": {
374
+ "lang": {
375
+ "type": "string"
376
+ },
377
+ "url": {
378
+ "type": "string",
379
+ "format": "uri"
380
+ }
381
+ },
382
+ "additionalProperties": false
383
+ }
384
+ }
385
+ },
386
+ "if": {
387
+ "properties": {
388
+ "@type": {
389
+ "const": "ProductGroup"
390
+ }
391
+ },
392
+ "required": [
393
+ "@type"
394
+ ]
395
+ },
396
+ "then": {
397
+ "required": [
398
+ "productGroupID"
399
+ ]
400
+ },
401
+ "else": {
402
+ "required": [
403
+ "url"
404
+ ],
405
+ "anyOf": [
406
+ {
407
+ "required": [
408
+ "sku"
409
+ ]
410
+ },
411
+ {
412
+ "required": [
413
+ "gtin13"
414
+ ]
415
+ },
416
+ {
417
+ "required": [
418
+ "gtin"
419
+ ]
420
+ },
421
+ {
422
+ "required": [
423
+ "mpn"
424
+ ]
425
+ },
426
+ {
427
+ "required": [
428
+ "productID"
429
+ ]
430
+ }
431
+ ]
432
+ },
433
+ "additionalProperties": true
434
+ },
435
+ "amount": {
436
+ "description": "A currency amount: a JSON number, or a decimal string with a dot as decimal point, no thousands separators and no currency symbol. A Sheet uses one of the two carriers for all its amounts.",
437
+ "oneOf": [
438
+ {
439
+ "type": "number"
440
+ },
441
+ {
442
+ "type": "string",
443
+ "pattern": "^-?\\d+(\\.\\d+)?$"
444
+ }
445
+ ]
446
+ },
447
+ "nonNegativeAmount": {
448
+ "description": "An amount that is zero or positive: the same two carriers as amount, with no leading minus. Used for prices, price bounds, base prices, price hints and discount amounts; only modifiers and adjustment amounts are signed.",
449
+ "oneOf": [
450
+ {
451
+ "type": "number",
452
+ "minimum": 0
453
+ },
454
+ {
455
+ "type": "string",
456
+ "pattern": "^\\d+(\\.\\d+)?$"
457
+ }
458
+ ]
459
+ },
460
+ "variantEntry": {
461
+ "type": "object",
462
+ "required": [
463
+ "@type"
464
+ ],
465
+ "properties": {
466
+ "@type": {
467
+ "type": "string"
468
+ },
469
+ "@id": {
470
+ "type": "string",
471
+ "format": "uri"
472
+ },
473
+ "url": {
474
+ "type": "string",
475
+ "format": "uri"
476
+ },
477
+ "sheet_url": {
478
+ "type": "string",
479
+ "format": "uri"
480
+ },
481
+ "name": {
482
+ "type": "string"
483
+ },
484
+ "sku": {
485
+ "type": "string"
486
+ },
487
+ "gtin13": {
488
+ "$ref": "#/$defs/gtin13Value"
489
+ },
490
+ "gtin": {
491
+ "$ref": "#/$defs/gtinValue"
492
+ },
493
+ "mpn": {
494
+ "type": "string"
495
+ },
496
+ "productID": {
497
+ "type": "string"
498
+ },
499
+ "color": {
500
+ "type": "string"
501
+ },
502
+ "size": {
503
+ "type": "string"
504
+ },
505
+ "material": {
506
+ "type": "string"
507
+ },
508
+ "price": {
509
+ "$ref": "#/$defs/nonNegativeAmount"
510
+ },
511
+ "image": {
512
+ "type": "string",
513
+ "format": "uri"
514
+ },
515
+ "additionalProperty": {
516
+ "type": "array"
517
+ }
518
+ },
519
+ "additionalProperties": true
520
+ },
521
+ "imageObject": {
522
+ "type": "object",
523
+ "required": [
524
+ "@type",
525
+ "url"
526
+ ],
527
+ "properties": {
528
+ "@type": {
529
+ "const": "ImageObject"
530
+ },
531
+ "url": {
532
+ "type": "string",
533
+ "format": "uri"
534
+ },
535
+ "caption": {
536
+ "type": "string"
537
+ },
538
+ "additionalProperty": {
539
+ "type": "array",
540
+ "items": {
541
+ "type": "object",
542
+ "properties": {
543
+ "@type": {
544
+ "const": "PropertyValue"
545
+ },
546
+ "name": {
547
+ "type": "string"
548
+ },
549
+ "value": {
550
+ "type": "string"
551
+ }
552
+ },
553
+ "allOf": [
554
+ {
555
+ "if": {
556
+ "properties": {
557
+ "name": {
558
+ "const": "role"
559
+ }
560
+ },
561
+ "required": [
562
+ "name"
563
+ ]
564
+ },
565
+ "then": {
566
+ "properties": {
567
+ "value": {
568
+ "enum": [
569
+ "hero",
570
+ "packshot",
571
+ "lifestyle",
572
+ "detail",
573
+ "flatlay",
574
+ "swatch",
575
+ "size_chart",
576
+ "context"
577
+ ]
578
+ }
579
+ }
580
+ }
581
+ }
582
+ ]
583
+ }
584
+ }
585
+ },
586
+ "additionalProperties": true
587
+ },
588
+ "videoObject": {
589
+ "type": "object",
590
+ "required": [
591
+ "@type"
592
+ ],
593
+ "properties": {
594
+ "@type": {
595
+ "const": "VideoObject"
596
+ },
597
+ "url": {
598
+ "type": "string",
599
+ "format": "uri"
600
+ },
601
+ "contentUrl": {
602
+ "type": "string",
603
+ "format": "uri"
604
+ },
605
+ "embedUrl": {
606
+ "type": "string",
607
+ "format": "uri"
608
+ },
609
+ "thumbnailUrl": {
610
+ "type": "string",
611
+ "format": "uri"
612
+ },
613
+ "duration": {
614
+ "type": "string",
615
+ "pattern": "^P(?:\\d+Y)?(?:\\d+M)?(?:\\d+D)?(?:T(?:\\d+H)?(?:\\d+M)?(?:\\d+(?:\\.\\d+)?S)?)?$"
616
+ },
617
+ "uploadDate": {
618
+ "type": "string"
619
+ },
620
+ "caption": {
621
+ "type": "string"
622
+ },
623
+ "transcript": {
624
+ "type": "string"
625
+ },
626
+ "description": {
627
+ "type": "string"
628
+ },
629
+ "name": {
630
+ "type": "string"
631
+ },
632
+ "additionalProperty": {
633
+ "type": "array",
634
+ "items": {
635
+ "type": "object",
636
+ "properties": {
637
+ "@type": {
638
+ "const": "PropertyValue"
639
+ },
640
+ "name": {
641
+ "type": "string"
642
+ },
643
+ "value": {
644
+ "type": "string"
645
+ }
646
+ },
647
+ "allOf": [
648
+ {
649
+ "if": {
650
+ "properties": {
651
+ "name": {
652
+ "const": "role"
653
+ }
654
+ },
655
+ "required": [
656
+ "name"
657
+ ]
658
+ },
659
+ "then": {
660
+ "properties": {
661
+ "value": {
662
+ "enum": [
663
+ "overview",
664
+ "tutorial",
665
+ "lifestyle",
666
+ "construction",
667
+ "demonstration",
668
+ "comparison",
669
+ "unboxing",
670
+ "spin"
671
+ ]
672
+ }
673
+ }
674
+ }
675
+ }
676
+ ]
677
+ }
678
+ }
679
+ },
680
+ "anyOf": [
681
+ {
682
+ "required": [
683
+ "url"
684
+ ]
685
+ },
686
+ {
687
+ "required": [
688
+ "contentUrl"
689
+ ]
690
+ },
691
+ {
692
+ "required": [
693
+ "embedUrl"
694
+ ]
695
+ }
696
+ ],
697
+ "additionalProperties": true
698
+ },
699
+ "questionObject": {
700
+ "type": "object",
701
+ "required": [
702
+ "@type",
703
+ "name",
704
+ "acceptedAnswer"
705
+ ],
706
+ "properties": {
707
+ "@type": {
708
+ "const": "Question"
709
+ },
710
+ "name": {
711
+ "type": "string",
712
+ "minLength": 1
713
+ },
714
+ "acceptedAnswer": {
715
+ "type": "object",
716
+ "required": [
717
+ "@type",
718
+ "text"
719
+ ],
720
+ "properties": {
721
+ "@type": {
722
+ "const": "Answer"
723
+ },
724
+ "text": {
725
+ "type": "string",
726
+ "minLength": 1
727
+ }
728
+ },
729
+ "additionalProperties": true
730
+ },
731
+ "suggestedAnswer": {
732
+ "type": "array",
733
+ "items": {
734
+ "type": "object",
735
+ "required": [
736
+ "@type",
737
+ "text"
738
+ ],
739
+ "properties": {
740
+ "@type": {
741
+ "const": "Answer"
742
+ },
743
+ "text": {
744
+ "type": "string",
745
+ "minLength": 1
746
+ }
747
+ },
748
+ "additionalProperties": true
749
+ }
750
+ }
751
+ },
752
+ "additionalProperties": true
753
+ },
754
+ "documentObject": {
755
+ "type": "object",
756
+ "required": [
757
+ "@type",
758
+ "url",
759
+ "role"
760
+ ],
761
+ "properties": {
762
+ "@type": {
763
+ "const": "pagefront:Document"
764
+ },
765
+ "url": {
766
+ "type": "string",
767
+ "format": "uri"
768
+ },
769
+ "role": {
770
+ "type": "string",
771
+ "enum": [
772
+ "manual",
773
+ "assembly",
774
+ "care_guide",
775
+ "spec_sheet",
776
+ "compatibility",
777
+ "warranty",
778
+ "certificate",
779
+ "environmental_declaration",
780
+ "audit_report",
781
+ "lab_test",
782
+ "safety_data_sheet",
783
+ "installation_guide",
784
+ "user_guide",
785
+ "quick_start",
786
+ "brochure",
787
+ "repairability_index",
788
+ "recall_notice",
789
+ "declaration_of_conformity"
790
+ ]
791
+ },
792
+ "name": {
793
+ "type": "string"
794
+ },
795
+ "inLanguage": {
796
+ "type": "string"
797
+ },
798
+ "description": {
799
+ "type": "string"
800
+ },
801
+ "encodingFormat": {
802
+ "type": "string"
803
+ }
804
+ },
805
+ "additionalProperties": false
806
+ },
807
+ "relatedProductObject": {
808
+ "type": "object",
809
+ "required": [
810
+ "@type",
811
+ "relationship"
812
+ ],
813
+ "properties": {
814
+ "@type": {
815
+ "const": "pagefront:RelatedProduct"
816
+ },
817
+ "relationship": {
818
+ "type": "string",
819
+ "enum": [
820
+ "accessory",
821
+ "consumable",
822
+ "required_part",
823
+ "spare_part",
824
+ "often_bought_with",
825
+ "recommended_with",
826
+ "replaces",
827
+ "replaced_by",
828
+ "bundle_component",
829
+ "compatible_with",
830
+ "service"
831
+ ]
832
+ },
833
+ "@id": {
834
+ "type": "string",
835
+ "format": "uri"
836
+ },
837
+ "sku": {
838
+ "type": "string"
839
+ },
840
+ "gtin": {
841
+ "type": "string"
842
+ },
843
+ "gtin13": {
844
+ "type": "string",
845
+ "pattern": "^[0-9]{13}$"
846
+ },
847
+ "mpn": {
848
+ "type": "string"
849
+ },
850
+ "name": {
851
+ "type": "string"
852
+ },
853
+ "url": {
854
+ "type": "string",
855
+ "format": "uri"
856
+ },
857
+ "image": {
858
+ "type": "string",
859
+ "format": "uri"
860
+ }
861
+ },
862
+ "anyOf": [
863
+ {
864
+ "required": [
865
+ "@id"
866
+ ]
867
+ },
868
+ {
869
+ "required": [
870
+ "sku"
871
+ ]
872
+ },
873
+ {
874
+ "required": [
875
+ "gtin"
876
+ ]
877
+ },
878
+ {
879
+ "required": [
880
+ "gtin13"
881
+ ]
882
+ },
883
+ {
884
+ "required": [
885
+ "mpn"
886
+ ]
887
+ }
888
+ ],
889
+ "additionalProperties": false
890
+ },
891
+ "gtinValue": {
892
+ "oneOf": [
893
+ {
894
+ "type": "string"
895
+ },
896
+ {
897
+ "type": "array",
898
+ "items": {
899
+ "type": "string"
900
+ },
901
+ "minItems": 1
902
+ }
903
+ ]
904
+ },
905
+ "gtin13Value": {
906
+ "oneOf": [
907
+ {
908
+ "type": "string",
909
+ "pattern": "^[0-9]{13}$"
910
+ },
911
+ {
912
+ "type": "array",
913
+ "items": {
914
+ "type": "string",
915
+ "pattern": "^[0-9]{13}$"
916
+ },
917
+ "minItems": 1
918
+ }
919
+ ]
920
+ },
921
+ "categoryCode": {
922
+ "type": "object",
923
+ "required": [
924
+ "@type",
925
+ "codeValue"
926
+ ],
927
+ "properties": {
928
+ "@type": {
929
+ "const": "CategoryCode"
930
+ },
931
+ "codeValue": {
932
+ "type": "string",
933
+ "minLength": 1
934
+ },
935
+ "inCodeSet": {
936
+ "oneOf": [
937
+ {
938
+ "type": "string",
939
+ "format": "uri"
940
+ },
941
+ {
942
+ "type": "object"
943
+ }
944
+ ]
945
+ },
946
+ "name": {
947
+ "type": "string"
948
+ }
949
+ },
950
+ "additionalProperties": true
951
+ },
952
+ "featureGroup": {
953
+ "type": "object",
954
+ "required": [
955
+ "@type",
956
+ "name",
957
+ "feature"
958
+ ],
959
+ "properties": {
960
+ "@type": {
961
+ "const": "pagefront:FeatureGroup"
962
+ },
963
+ "name": {
964
+ "type": "string",
965
+ "minLength": 1
966
+ },
967
+ "sortOrder": {
968
+ "type": "integer"
969
+ },
970
+ "feature": {
971
+ "type": "array",
972
+ "items": {
973
+ "$ref": "#/$defs/featureEntry"
974
+ },
975
+ "minItems": 1
976
+ }
977
+ },
978
+ "additionalProperties": false
979
+ },
980
+ "featureEntry": {
981
+ "type": "object",
982
+ "required": [
983
+ "@type",
984
+ "name",
985
+ "value"
986
+ ],
987
+ "properties": {
988
+ "@type": {
989
+ "const": "PropertyValue"
990
+ },
991
+ "propertyID": {
992
+ "type": "string"
993
+ },
994
+ "name": {
995
+ "type": "string",
996
+ "minLength": 1
997
+ },
998
+ "value": {
999
+ "anyOf": [
1000
+ {
1001
+ "type": "string"
1002
+ },
1003
+ {
1004
+ "type": "number"
1005
+ },
1006
+ {
1007
+ "type": "boolean"
1008
+ }
1009
+ ]
1010
+ },
1011
+ "unitCode": {
1012
+ "type": "string"
1013
+ },
1014
+ "description": {
1015
+ "type": "string"
1016
+ },
1017
+ "pagefront:presentationValue": {
1018
+ "type": "string"
1019
+ }
1020
+ },
1021
+ "additionalProperties": true
1022
+ },
1023
+ "legalEntity": {
1024
+ "type": "object",
1025
+ "required": [
1026
+ "@type",
1027
+ "role",
1028
+ "organization"
1029
+ ],
1030
+ "properties": {
1031
+ "@type": {
1032
+ "const": "pagefront:LegalEntity"
1033
+ },
1034
+ "role": {
1035
+ "type": "string",
1036
+ "enum": [
1037
+ "brand_owner",
1038
+ "licensee",
1039
+ "authorized_representative",
1040
+ "importer",
1041
+ "manufacturer"
1042
+ ]
1043
+ },
1044
+ "organization": {
1045
+ "type": "object",
1046
+ "required": [
1047
+ "@type"
1048
+ ],
1049
+ "anyOf": [
1050
+ {
1051
+ "required": [
1052
+ "name"
1053
+ ]
1054
+ },
1055
+ {
1056
+ "required": [
1057
+ "@id"
1058
+ ]
1059
+ }
1060
+ ],
1061
+ "properties": {
1062
+ "@type": {
1063
+ "const": "Organization"
1064
+ },
1065
+ "@id": {
1066
+ "type": "string",
1067
+ "format": "uri"
1068
+ },
1069
+ "name": {
1070
+ "type": "string",
1071
+ "minLength": 1
1072
+ },
1073
+ "address": {
1074
+ "type": "object"
1075
+ },
1076
+ "url": {
1077
+ "type": "string",
1078
+ "format": "uri"
1079
+ },
1080
+ "email": {
1081
+ "type": "string",
1082
+ "format": "email"
1083
+ },
1084
+ "pagefront:sheetUrl": {
1085
+ "type": "string",
1086
+ "format": "uri"
1087
+ }
1088
+ },
1089
+ "additionalProperties": true
1090
+ }
1091
+ },
1092
+ "additionalProperties": false
1093
+ },
1094
+ "safetyWarning": {
1095
+ "type": "object",
1096
+ "required": [
1097
+ "@type",
1098
+ "text"
1099
+ ],
1100
+ "properties": {
1101
+ "@type": {
1102
+ "const": "pagefront:SafetyWarning"
1103
+ },
1104
+ "text": {
1105
+ "type": "string",
1106
+ "minLength": 1
1107
+ },
1108
+ "pictogram": {
1109
+ "type": "string",
1110
+ "format": "uri"
1111
+ },
1112
+ "hazardCategory": {
1113
+ "type": "string"
1114
+ }
1115
+ },
1116
+ "additionalProperties": false
1117
+ },
1118
+ "safetyNotice": {
1119
+ "type": "object",
1120
+ "required": [
1121
+ "@type",
1122
+ "noticeType"
1123
+ ],
1124
+ "properties": {
1125
+ "@type": {
1126
+ "const": "pagefront:SafetyNotice"
1127
+ },
1128
+ "noticeType": {
1129
+ "type": "string",
1130
+ "enum": [
1131
+ "recall",
1132
+ "warning"
1133
+ ]
1134
+ },
1135
+ "hazard": {
1136
+ "type": "string"
1137
+ },
1138
+ "remedy": {
1139
+ "type": "string",
1140
+ "enum": [
1141
+ "repair",
1142
+ "replacement",
1143
+ "refund"
1144
+ ]
1145
+ },
1146
+ "description": {
1147
+ "type": "string"
1148
+ },
1149
+ "reference": {
1150
+ "type": "string",
1151
+ "format": "uri"
1152
+ },
1153
+ "datePublished": {
1154
+ "type": "string",
1155
+ "format": "date"
1156
+ },
1157
+ "url": {
1158
+ "type": "string",
1159
+ "format": "uri"
1160
+ }
1161
+ },
1162
+ "additionalProperties": false
1163
+ },
1164
+ "certification": {
1165
+ "type": "object",
1166
+ "required": [
1167
+ "@type",
1168
+ "name"
1169
+ ],
1170
+ "properties": {
1171
+ "@type": {
1172
+ "const": "Certification"
1173
+ },
1174
+ "name": {
1175
+ "type": "string"
1176
+ },
1177
+ "issuedBy": {
1178
+ "type": "object"
1179
+ },
1180
+ "about": {
1181
+ "type": "string"
1182
+ },
1183
+ "additionalProperty": {
1184
+ "type": "array"
1185
+ }
1186
+ },
1187
+ "additionalProperties": true
1188
+ },
1189
+ "offer": {
1190
+ "type": "object",
1191
+ "required": [
1192
+ "@type"
1193
+ ],
1194
+ "properties": {
1195
+ "@type": {
1196
+ "const": "Offer"
1197
+ },
1198
+ "@id": {
1199
+ "type": "string"
1200
+ },
1201
+ "itemOffered": {
1202
+ "type": "object"
1203
+ },
1204
+ "price": {
1205
+ "$ref": "#/$defs/nonNegativeAmount"
1206
+ },
1207
+ "priceCurrency": {
1208
+ "type": "string",
1209
+ "pattern": "^[A-Z]{3}$"
1210
+ },
1211
+ "priceSpecification": {
1212
+ "oneOf": [
1213
+ {
1214
+ "type": "object"
1215
+ },
1216
+ {
1217
+ "type": "array",
1218
+ "items": {
1219
+ "type": "object"
1220
+ }
1221
+ }
1222
+ ]
1223
+ },
1224
+ "availability": {
1225
+ "type": "string",
1226
+ "pattern": "^https?://schema\\.org/(InStock|OutOfStock|PreOrder|BackOrder|InStoreOnly|LimitedAvailability|MadeToOrder|OnlineOnly|SoldOut|Discontinued|Reserved)$"
1227
+ },
1228
+ "itemCondition": {
1229
+ "type": "string",
1230
+ "pattern": "^https?://schema\\.org/(NewCondition|UsedCondition|RefurbishedCondition|DamagedCondition)$"
1231
+ },
1232
+ "seller": {
1233
+ "type": "object",
1234
+ "properties": {
1235
+ "pagefront:sheetUrl": {
1236
+ "type": "string",
1237
+ "format": "uri"
1238
+ }
1239
+ }
1240
+ },
1241
+ "shippingDetails": {
1242
+ "oneOf": [
1243
+ {
1244
+ "type": "object"
1245
+ },
1246
+ {
1247
+ "type": "array",
1248
+ "items": {
1249
+ "type": "object"
1250
+ }
1251
+ }
1252
+ ]
1253
+ },
1254
+ "hasMerchantReturnPolicy": {
1255
+ "type": "object"
1256
+ },
1257
+ "warranty": {
1258
+ "type": "object"
1259
+ },
1260
+ "areaServed": {},
1261
+ "eligibleRegion": {
1262
+ "type": "array"
1263
+ },
1264
+ "acceptedPaymentMethod": {
1265
+ "type": "array"
1266
+ },
1267
+ "pagefront:estimatedDelivery": {
1268
+ "$ref": "#/$defs/deliveryEstimate"
1269
+ },
1270
+ "pagefront:promotions": {
1271
+ "type": "array",
1272
+ "items": {
1273
+ "$ref": "#/$defs/promotion"
1274
+ }
1275
+ },
1276
+ "pagefront:priceOnRequest": {
1277
+ "$ref": "#/$defs/priceOnRequest"
1278
+ },
1279
+ "pagefront:configuratorPricing": {
1280
+ "$ref": "#/$defs/configuratorPricing"
1281
+ }
1282
+ },
1283
+ "anyOf": [
1284
+ {
1285
+ "required": [
1286
+ "price",
1287
+ "priceCurrency"
1288
+ ]
1289
+ },
1290
+ {
1291
+ "required": [
1292
+ "priceSpecification"
1293
+ ]
1294
+ },
1295
+ {
1296
+ "required": [
1297
+ "pagefront:priceOnRequest"
1298
+ ]
1299
+ }
1300
+ ],
1301
+ "dependentRequired": {
1302
+ "pagefront:configuratorPricing": [
1303
+ "price",
1304
+ "priceCurrency"
1305
+ ]
1306
+ },
1307
+ "additionalProperties": true
1308
+ },
1309
+ "aggregateOffer": {
1310
+ "type": "object",
1311
+ "required": [
1312
+ "@type",
1313
+ "lowPrice",
1314
+ "highPrice",
1315
+ "priceCurrency"
1316
+ ],
1317
+ "properties": {
1318
+ "@type": {
1319
+ "const": "AggregateOffer"
1320
+ },
1321
+ "@id": {
1322
+ "type": "string"
1323
+ },
1324
+ "lowPrice": {
1325
+ "$ref": "#/$defs/nonNegativeAmount"
1326
+ },
1327
+ "highPrice": {
1328
+ "$ref": "#/$defs/nonNegativeAmount"
1329
+ },
1330
+ "priceCurrency": {
1331
+ "type": "string",
1332
+ "pattern": "^[A-Z]{3}$"
1333
+ },
1334
+ "offerCount": {
1335
+ "type": "integer"
1336
+ },
1337
+ "availability": {
1338
+ "type": "string",
1339
+ "pattern": "^https?://schema\\.org/(InStock|OutOfStock|PreOrder|BackOrder|InStoreOnly|LimitedAvailability|MadeToOrder|OnlineOnly|SoldOut|Discontinued|Reserved)$"
1340
+ },
1341
+ "itemCondition": {
1342
+ "type": "string",
1343
+ "pattern": "^https?://schema\\.org/(NewCondition|UsedCondition|RefurbishedCondition|DamagedCondition)$"
1344
+ },
1345
+ "eligibleRegion": {
1346
+ "type": "array"
1347
+ },
1348
+ "areaServed": {},
1349
+ "validFrom": {
1350
+ "type": "string"
1351
+ },
1352
+ "validThrough": {
1353
+ "type": "string"
1354
+ },
1355
+ "seller": {
1356
+ "type": "object"
1357
+ },
1358
+ "pagefront:configuratorPricing": {
1359
+ "$ref": "#/$defs/configuratorPricing"
1360
+ }
1361
+ },
1362
+ "additionalProperties": true
1363
+ },
1364
+ "priceOnRequest": {
1365
+ "type": "object",
1366
+ "required": [
1367
+ "@type",
1368
+ "method"
1369
+ ],
1370
+ "properties": {
1371
+ "@type": {
1372
+ "const": "pagefront:PriceOnRequest"
1373
+ },
1374
+ "method": {
1375
+ "type": "string",
1376
+ "enum": [
1377
+ "authorized_retailer",
1378
+ "dealer_network",
1379
+ "quote_form",
1380
+ "email",
1381
+ "phone",
1382
+ "unspecified"
1383
+ ]
1384
+ },
1385
+ "contactUrl": {
1386
+ "type": "string",
1387
+ "format": "uri"
1388
+ },
1389
+ "contactEmail": {
1390
+ "type": "string",
1391
+ "format": "email"
1392
+ },
1393
+ "contactPhone": {
1394
+ "type": "string"
1395
+ },
1396
+ "note": {
1397
+ "type": "string"
1398
+ }
1399
+ },
1400
+ "additionalProperties": false
1401
+ },
1402
+ "sizeChart": {
1403
+ "type": "object",
1404
+ "required": [
1405
+ "@type",
1406
+ "unitCode",
1407
+ "sizes",
1408
+ "measurements"
1409
+ ],
1410
+ "properties": {
1411
+ "@type": {
1412
+ "const": "pagefront:SizeChart"
1413
+ },
1414
+ "unitCode": {
1415
+ "type": "string"
1416
+ },
1417
+ "sizes": {
1418
+ "type": "array",
1419
+ "items": {
1420
+ "type": "string"
1421
+ },
1422
+ "minItems": 1
1423
+ },
1424
+ "measurements": {
1425
+ "type": "array",
1426
+ "items": {
1427
+ "$ref": "#/$defs/measurement"
1428
+ },
1429
+ "minItems": 1
1430
+ },
1431
+ "modelReferences": {
1432
+ "type": "array",
1433
+ "items": {
1434
+ "$ref": "#/$defs/modelReference"
1435
+ }
1436
+ }
1437
+ },
1438
+ "additionalProperties": false
1439
+ },
1440
+ "measurement": {
1441
+ "type": "object",
1442
+ "required": [
1443
+ "@type",
1444
+ "name",
1445
+ "values"
1446
+ ],
1447
+ "properties": {
1448
+ "@type": {
1449
+ "const": "pagefront:Measurement"
1450
+ },
1451
+ "name": {
1452
+ "type": "string"
1453
+ },
1454
+ "values": {
1455
+ "type": "object",
1456
+ "additionalProperties": {
1457
+ "type": "number"
1458
+ }
1459
+ }
1460
+ },
1461
+ "additionalProperties": false
1462
+ },
1463
+ "modelReference": {
1464
+ "type": "object",
1465
+ "required": [
1466
+ "@type",
1467
+ "name"
1468
+ ],
1469
+ "properties": {
1470
+ "@type": {
1471
+ "const": "pagefront:ModelReference"
1472
+ },
1473
+ "name": {
1474
+ "type": "string"
1475
+ },
1476
+ "heightCm": {
1477
+ "type": "number",
1478
+ "minimum": 0
1479
+ },
1480
+ "wearsSize": {
1481
+ "type": "string"
1482
+ }
1483
+ },
1484
+ "additionalProperties": false
1485
+ },
1486
+ "sizeRecommendation": {
1487
+ "type": "object",
1488
+ "required": [
1489
+ "@type"
1490
+ ],
1491
+ "properties": {
1492
+ "@type": {
1493
+ "const": "pagefront:SizeRecommendation"
1494
+ },
1495
+ "fitProfile": {
1496
+ "type": "string",
1497
+ "enum": [
1498
+ "runs_small",
1499
+ "true_to_size",
1500
+ "runs_large"
1501
+ ]
1502
+ },
1503
+ "sizeAdjustment": {
1504
+ "$ref": "#/$defs/sizeAdjustment"
1505
+ },
1506
+ "description": {
1507
+ "type": "string"
1508
+ },
1509
+ "appliesTo": {
1510
+ "type": "string"
1511
+ }
1512
+ },
1513
+ "additionalProperties": false
1514
+ },
1515
+ "sizeAdjustment": {
1516
+ "type": "object",
1517
+ "required": [
1518
+ "@type",
1519
+ "direction",
1520
+ "magnitude"
1521
+ ],
1522
+ "properties": {
1523
+ "@type": {
1524
+ "const": "pagefront:SizeAdjustment"
1525
+ },
1526
+ "direction": {
1527
+ "type": "string",
1528
+ "enum": [
1529
+ "up",
1530
+ "down"
1531
+ ]
1532
+ },
1533
+ "magnitude": {
1534
+ "type": "number",
1535
+ "minimum": 0
1536
+ },
1537
+ "sizeSystem": {
1538
+ "type": "string"
1539
+ }
1540
+ },
1541
+ "additionalProperties": false
1542
+ },
1543
+ "material": {
1544
+ "type": "object",
1545
+ "required": [
1546
+ "@type",
1547
+ "material"
1548
+ ],
1549
+ "properties": {
1550
+ "@type": {
1551
+ "const": "pagefront:Material"
1552
+ },
1553
+ "material": {
1554
+ "type": "string"
1555
+ },
1556
+ "percentage": {
1557
+ "type": "number",
1558
+ "minimum": 0,
1559
+ "maximum": 100
1560
+ },
1561
+ "purity": {
1562
+ "type": "string"
1563
+ },
1564
+ "purityPercentage": {
1565
+ "type": "number",
1566
+ "minimum": 0,
1567
+ "maximum": 100
1568
+ },
1569
+ "provenance": {
1570
+ "type": "string",
1571
+ "enum": [
1572
+ "virgin",
1573
+ "recycled",
1574
+ "fair_mined",
1575
+ "lab_grown",
1576
+ "reclaimed",
1577
+ "deadstock"
1578
+ ]
1579
+ },
1580
+ "weightGrams": {
1581
+ "type": "number",
1582
+ "minimum": 0
1583
+ }
1584
+ },
1585
+ "additionalProperties": false
1586
+ },
1587
+ "construction": {
1588
+ "type": "object",
1589
+ "required": [
1590
+ "@type"
1591
+ ],
1592
+ "properties": {
1593
+ "@type": {
1594
+ "const": "pagefront:Construction"
1595
+ },
1596
+ "stitch": {
1597
+ "type": "string"
1598
+ },
1599
+ "gauge": {
1600
+ "type": "number"
1601
+ },
1602
+ "machine": {
1603
+ "type": "string"
1604
+ },
1605
+ "constructionNotes": {
1606
+ "type": "string"
1607
+ }
1608
+ },
1609
+ "additionalProperties": true
1610
+ },
1611
+ "manufacturingStage": {
1612
+ "type": "object",
1613
+ "required": [
1614
+ "@type",
1615
+ "stage",
1616
+ "country"
1617
+ ],
1618
+ "properties": {
1619
+ "@type": {
1620
+ "const": "pagefront:ManufacturingStage"
1621
+ },
1622
+ "stage": {
1623
+ "type": "string"
1624
+ },
1625
+ "country": {
1626
+ "type": "string",
1627
+ "pattern": "^[A-Z]{2}$"
1628
+ },
1629
+ "facility": {
1630
+ "type": "string"
1631
+ },
1632
+ "facilityCountry": {
1633
+ "type": "string",
1634
+ "pattern": "^[A-Z]{2}$"
1635
+ }
1636
+ },
1637
+ "additionalProperties": false
1638
+ },
1639
+ "gemstone": {
1640
+ "type": "object",
1641
+ "required": [
1642
+ "@type",
1643
+ "type"
1644
+ ],
1645
+ "properties": {
1646
+ "@type": {
1647
+ "const": "pagefront:Gemstone"
1648
+ },
1649
+ "type": {
1650
+ "type": "string"
1651
+ },
1652
+ "origin": {
1653
+ "type": "string",
1654
+ "enum": [
1655
+ "natural_mined",
1656
+ "lab_grown",
1657
+ "treated",
1658
+ "synthetic"
1659
+ ]
1660
+ },
1661
+ "shape": {
1662
+ "type": "string"
1663
+ },
1664
+ "caratWeight": {
1665
+ "type": "number",
1666
+ "minimum": 0
1667
+ },
1668
+ "colorGrade": {
1669
+ "type": "string"
1670
+ },
1671
+ "clarityGrade": {
1672
+ "type": "string"
1673
+ },
1674
+ "cutGrade": {
1675
+ "type": "string"
1676
+ },
1677
+ "certifyingBody": {
1678
+ "type": "string"
1679
+ }
1680
+ },
1681
+ "additionalProperties": false
1682
+ },
1683
+ "configurator": {
1684
+ "type": "object",
1685
+ "required": [
1686
+ "@type",
1687
+ "dimensions"
1688
+ ],
1689
+ "properties": {
1690
+ "@type": {
1691
+ "const": "pagefront:Configurator"
1692
+ },
1693
+ "@id": {
1694
+ "type": "string",
1695
+ "minLength": 1
1696
+ },
1697
+ "dimensions": {
1698
+ "type": "array",
1699
+ "items": {
1700
+ "$ref": "#/$defs/configuratorDimension"
1701
+ },
1702
+ "minItems": 1
1703
+ },
1704
+ "exclusions": {
1705
+ "type": "array",
1706
+ "items": {
1707
+ "$ref": "#/$defs/configurationSelection",
1708
+ "type": "object",
1709
+ "minProperties": 1
1710
+ }
1711
+ }
1712
+ },
1713
+ "additionalProperties": false
1714
+ },
1715
+ "configuratorDimension": {
1716
+ "type": "object",
1717
+ "required": [
1718
+ "name"
1719
+ ],
1720
+ "properties": {
1721
+ "name": {
1722
+ "type": "string"
1723
+ },
1724
+ "options": {
1725
+ "type": "array",
1726
+ "items": {
1727
+ "type": "object",
1728
+ "required": [
1729
+ "value"
1730
+ ],
1731
+ "properties": {
1732
+ "value": {
1733
+ "anyOf": [
1734
+ {
1735
+ "type": "string"
1736
+ },
1737
+ {
1738
+ "type": "number"
1739
+ },
1740
+ {
1741
+ "type": "boolean"
1742
+ }
1743
+ ]
1744
+ },
1745
+ "description": {
1746
+ "type": "string"
1747
+ },
1748
+ "priceModifier": false,
1749
+ "currency": false
1750
+ },
1751
+ "additionalProperties": true
1752
+ }
1753
+ },
1754
+ "affectsPrice": {
1755
+ "type": "boolean",
1756
+ "default": true
1757
+ },
1758
+ "inputType": {
1759
+ "type": "string",
1760
+ "enum": [
1761
+ "select",
1762
+ "text"
1763
+ ],
1764
+ "default": "select"
1765
+ },
1766
+ "maxLength": {
1767
+ "type": "integer",
1768
+ "minimum": 1
1769
+ },
1770
+ "system": {
1771
+ "type": "string"
1772
+ },
1773
+ "note": {
1774
+ "type": "string"
1775
+ }
1776
+ },
1777
+ "additionalProperties": false
1778
+ },
1779
+ "configurationSelection": {
1780
+ "type": "object",
1781
+ "additionalProperties": {
1782
+ "anyOf": [
1783
+ {
1784
+ "type": "string"
1785
+ },
1786
+ {
1787
+ "type": "number"
1788
+ },
1789
+ {
1790
+ "type": "boolean"
1791
+ }
1792
+ ]
1793
+ }
1794
+ },
1795
+ "configuratorPricing": {
1796
+ "type": "object",
1797
+ "required": [
1798
+ "@type",
1799
+ "configurator",
1800
+ "baseConfiguration",
1801
+ "basePrice",
1802
+ "modifiers"
1803
+ ],
1804
+ "properties": {
1805
+ "@type": {
1806
+ "const": "pagefront:ConfiguratorPricing"
1807
+ },
1808
+ "configurator": {
1809
+ "type": "object",
1810
+ "required": [
1811
+ "@id"
1812
+ ],
1813
+ "properties": {
1814
+ "@type": {
1815
+ "const": "pagefront:Configurator"
1816
+ },
1817
+ "@id": {
1818
+ "type": "string",
1819
+ "minLength": 1
1820
+ }
1821
+ },
1822
+ "additionalProperties": false
1823
+ },
1824
+ "baseConfiguration": {
1825
+ "$ref": "#/$defs/configurationSelection"
1826
+ },
1827
+ "basePrice": {
1828
+ "$ref": "#/$defs/nonNegativeAmount"
1829
+ },
1830
+ "modifiers": {
1831
+ "type": "object",
1832
+ "additionalProperties": {
1833
+ "type": "object",
1834
+ "additionalProperties": {
1835
+ "$ref": "#/$defs/amount"
1836
+ }
1837
+ }
1838
+ },
1839
+ "adjustments": {
1840
+ "type": "array",
1841
+ "items": {
1842
+ "type": "object",
1843
+ "required": [
1844
+ "when",
1845
+ "priceModifier"
1846
+ ],
1847
+ "properties": {
1848
+ "when": {
1849
+ "$ref": "#/$defs/configurationSelection",
1850
+ "type": "object",
1851
+ "minProperties": 1
1852
+ },
1853
+ "priceModifier": {
1854
+ "$ref": "#/$defs/amount"
1855
+ }
1856
+ },
1857
+ "additionalProperties": false
1858
+ }
1859
+ },
1860
+ "pricing": {
1861
+ "type": "string",
1862
+ "enum": [
1863
+ "complete",
1864
+ "partial"
1865
+ ],
1866
+ "default": "complete"
1867
+ }
1868
+ },
1869
+ "additionalProperties": false
1870
+ },
1871
+ "madeToOrderTerms": {
1872
+ "type": "object",
1873
+ "required": [
1874
+ "@type"
1875
+ ],
1876
+ "properties": {
1877
+ "@type": {
1878
+ "const": "pagefront:MadeToOrderTerms"
1879
+ },
1880
+ "productionLeadTime": {
1881
+ "$ref": "#/$defs/duration"
1882
+ },
1883
+ "cancellationPolicy": {
1884
+ "type": "string"
1885
+ },
1886
+ "returnsExceptions": {
1887
+ "type": "array",
1888
+ "items": {
1889
+ "type": "string"
1890
+ }
1891
+ },
1892
+ "aftermarketServices": {
1893
+ "type": "array",
1894
+ "items": {
1895
+ "$ref": "#/$defs/aftermarketService"
1896
+ }
1897
+ }
1898
+ },
1899
+ "additionalProperties": false
1900
+ },
1901
+ "duration": {
1902
+ "type": "object",
1903
+ "required": [
1904
+ "@type"
1905
+ ],
1906
+ "properties": {
1907
+ "@type": {
1908
+ "const": "pagefront:Duration"
1909
+ },
1910
+ "minDays": {
1911
+ "type": "integer",
1912
+ "minimum": 0
1913
+ },
1914
+ "maxDays": {
1915
+ "type": "integer",
1916
+ "minimum": 0
1917
+ },
1918
+ "description": {
1919
+ "type": "string"
1920
+ }
1921
+ },
1922
+ "additionalProperties": false
1923
+ },
1924
+ "deliveryEstimate": {
1925
+ "type": "object",
1926
+ "required": [
1927
+ "@type"
1928
+ ],
1929
+ "properties": {
1930
+ "@type": {
1931
+ "const": "pagefront:DeliveryEstimate"
1932
+ },
1933
+ "earliest": {
1934
+ "type": "string",
1935
+ "format": "date"
1936
+ },
1937
+ "latest": {
1938
+ "type": "string",
1939
+ "format": "date"
1940
+ },
1941
+ "description": {
1942
+ "type": "string"
1943
+ }
1944
+ },
1945
+ "additionalProperties": false
1946
+ },
1947
+ "aftermarketService": {
1948
+ "type": "object",
1949
+ "required": [
1950
+ "@type",
1951
+ "service"
1952
+ ],
1953
+ "properties": {
1954
+ "@type": {
1955
+ "const": "pagefront:AftermarketService"
1956
+ },
1957
+ "service": {
1958
+ "type": "string"
1959
+ },
1960
+ "limit": {
1961
+ "type": "string"
1962
+ },
1963
+ "description": {
1964
+ "type": "string"
1965
+ }
1966
+ },
1967
+ "additionalProperties": false
1968
+ },
1969
+ "promotion": {
1970
+ "type": "object",
1971
+ "required": [
1972
+ "@type",
1973
+ "scope"
1974
+ ],
1975
+ "properties": {
1976
+ "@type": {
1977
+ "const": "pagefront:Promotion"
1978
+ },
1979
+ "code": {
1980
+ "type": "string"
1981
+ },
1982
+ "discountPercentage": {
1983
+ "type": "number",
1984
+ "minimum": 0,
1985
+ "maximum": 100
1986
+ },
1987
+ "discountAmount": {
1988
+ "$ref": "#/$defs/nonNegativeAmount"
1989
+ },
1990
+ "discountCurrency": {
1991
+ "type": "string",
1992
+ "pattern": "^[A-Z]{3}$"
1993
+ },
1994
+ "scope": {
1995
+ "type": "string",
1996
+ "enum": [
1997
+ "product",
1998
+ "category",
1999
+ "site_wide"
2000
+ ]
2001
+ },
2002
+ "occasion": {
2003
+ "type": "string"
2004
+ },
2005
+ "validUntil": {
2006
+ "type": "string",
2007
+ "format": "date-time"
2008
+ }
2009
+ },
2010
+ "additionalProperties": false
2011
+ }
2012
+ }
2013
+ };
2014
+ export const LEGACY_ORGANIZATION_SCHEMA = {
2015
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
2016
+ "$id": "https://themachineweb.org/pagefront/spec/commerce/organization/v0.9.json",
2017
+ "title": "Pagefront Commerce Organization Sheet v0.9",
2018
+ "description": "Formal schema for the Pagefront Commerce Organization Sheet — the sheet describing the entity behind products (brand owner, manufacturer, seller), introduced with commerce format 0.9 alongside the reference-capable legalEntity and the seller-sheet return/shipping model. The data block roots on Schema.org Organization (recognized subtypes permitted; @type is not constrained to a single value). pagefront:commerceRole is the required role discriminator, an array of one or more values from the closed enum brand_owner / manufacturer / seller. pagefront:fulfillmentTerms carries the store-wide shipping defaults as an array of Schema.org-native OfferShippingDetails objects; only the attachment shell is validated, the payload is Schema.org content. pagefront:socialAccount carries the organization's official social accounts (platform / url / handle; publisher-stated only), distinct from sameAs, which carries identity authority records only. pagefront:authorizedResellers carries the brand's authorization claim over its distribution — a pagefront:AuthorizedResellers object with an optional exhaustive flag and a reseller array whose entries name an Organization either as a reference stub (@id) or inline (name plus url and/or address), with optional Schema.org-native areaServed; valid only where commerceRole includes brand_owner (linter ORG-W-006). There is no GTIN-equivalent identifier requirement: identity is @id + name. Validates the envelope and pagefront-namespaced extensions strictly; Schema.org-typed blocks permit additional unspecified properties.",
2019
+ "type": "object",
2020
+ "required": [
2021
+ "format_version",
2022
+ "schema_org_version",
2023
+ "canonical_url",
2024
+ "sheet_url",
2025
+ "generated_at",
2026
+ "data"
2027
+ ],
2028
+ "properties": {
2029
+ "$schema": {
2030
+ "type": "string",
2031
+ "format": "uri"
2032
+ },
2033
+ "format_version": {
2034
+ "const": "0.9"
2035
+ },
2036
+ "schema_org_version": {
2037
+ "type": "string",
2038
+ "pattern": "^\\d+(\\.\\d+)?$"
2039
+ },
2040
+ "canonical_url": {
2041
+ "type": "string",
2042
+ "format": "uri"
2043
+ },
2044
+ "sheet_url": {
2045
+ "type": "string",
2046
+ "format": "uri"
2047
+ },
2048
+ "generated_at": {
2049
+ "type": "string",
2050
+ "format": "date-time"
2051
+ },
2052
+ "expires_at": {
2053
+ "type": "string",
2054
+ "format": "date-time"
2055
+ },
2056
+ "data": {
2057
+ "$ref": "#/$defs/dataBlock"
2058
+ }
2059
+ },
2060
+ "additionalProperties": false,
2061
+ "$defs": {
2062
+ "dataBlock": {
2063
+ "type": "object",
2064
+ "required": [
2065
+ "@context",
2066
+ "@type",
2067
+ "@id",
2068
+ "name",
2069
+ "inLanguage",
2070
+ "pagefront:commerceRole"
2071
+ ],
2072
+ "properties": {
2073
+ "@context": {
2074
+ "oneOf": [
2075
+ {
2076
+ "const": "https://schema.org"
2077
+ },
2078
+ {
2079
+ "type": "array",
2080
+ "items": {
2081
+ "oneOf": [
2082
+ {
2083
+ "type": "string",
2084
+ "format": "uri"
2085
+ },
2086
+ {
2087
+ "type": "object"
2088
+ }
2089
+ ]
2090
+ },
2091
+ "minItems": 1
2092
+ }
2093
+ ]
2094
+ },
2095
+ "@type": {
2096
+ "type": "string"
2097
+ },
2098
+ "@id": {
2099
+ "type": "string",
2100
+ "format": "uri"
2101
+ },
2102
+ "name": {
2103
+ "type": "string",
2104
+ "minLength": 1
2105
+ },
2106
+ "legalName": {
2107
+ "type": "string"
2108
+ },
2109
+ "inLanguage": {
2110
+ "type": "string"
2111
+ },
2112
+ "url": {
2113
+ "type": "string",
2114
+ "format": "uri"
2115
+ },
2116
+ "description": {
2117
+ "type": "string"
2118
+ },
2119
+ "slogan": {
2120
+ "type": "string"
2121
+ },
2122
+ "logo": {
2123
+ "oneOf": [
2124
+ {
2125
+ "type": "string",
2126
+ "format": "uri"
2127
+ },
2128
+ {
2129
+ "type": "object"
2130
+ }
2131
+ ]
2132
+ },
2133
+ "iso6523Code": {
2134
+ "type": "string"
2135
+ },
2136
+ "identifier": {
2137
+ "oneOf": [
2138
+ {
2139
+ "type": "string"
2140
+ },
2141
+ {
2142
+ "type": "object"
2143
+ },
2144
+ {
2145
+ "type": "array",
2146
+ "items": {
2147
+ "oneOf": [
2148
+ {
2149
+ "type": "string"
2150
+ },
2151
+ {
2152
+ "type": "object"
2153
+ }
2154
+ ]
2155
+ }
2156
+ }
2157
+ ]
2158
+ },
2159
+ "sameAs": {
2160
+ "oneOf": [
2161
+ {
2162
+ "type": "string",
2163
+ "format": "uri"
2164
+ },
2165
+ {
2166
+ "type": "array",
2167
+ "items": {
2168
+ "type": "string",
2169
+ "format": "uri"
2170
+ }
2171
+ }
2172
+ ]
2173
+ },
2174
+ "email": {
2175
+ "type": "string",
2176
+ "format": "email"
2177
+ },
2178
+ "address": {
2179
+ "type": "object"
2180
+ },
2181
+ "contactPoint": {
2182
+ "oneOf": [
2183
+ {
2184
+ "type": "object"
2185
+ },
2186
+ {
2187
+ "type": "array",
2188
+ "items": {
2189
+ "type": "object"
2190
+ }
2191
+ }
2192
+ ]
2193
+ },
2194
+ "foundingDate": {
2195
+ "type": "string"
2196
+ },
2197
+ "numberOfEmployees": {
2198
+ "type": "object"
2199
+ },
2200
+ "parentOrganization": {
2201
+ "type": "object"
2202
+ },
2203
+ "subOrganization": {
2204
+ "oneOf": [
2205
+ {
2206
+ "type": "object"
2207
+ },
2208
+ {
2209
+ "type": "array",
2210
+ "items": {
2211
+ "type": "object"
2212
+ }
2213
+ }
2214
+ ]
2215
+ },
2216
+ "location": {
2217
+ "oneOf": [
2218
+ {
2219
+ "type": "object"
2220
+ },
2221
+ {
2222
+ "type": "array",
2223
+ "items": {
2224
+ "type": "object"
2225
+ }
2226
+ }
2227
+ ]
2228
+ },
2229
+ "brand": {
2230
+ "type": "object"
2231
+ },
2232
+ "aggregateRating": {
2233
+ "type": "object"
2234
+ },
2235
+ "hasCertification": {
2236
+ "type": "array",
2237
+ "items": {
2238
+ "$ref": "#/$defs/certification"
2239
+ }
2240
+ },
2241
+ "hasMerchantReturnPolicy": {
2242
+ "type": "object"
2243
+ },
2244
+ "paymentAccepted": {
2245
+ "oneOf": [
2246
+ {
2247
+ "type": "string"
2248
+ },
2249
+ {
2250
+ "type": "array",
2251
+ "items": {
2252
+ "type": "string"
2253
+ }
2254
+ }
2255
+ ]
2256
+ },
2257
+ "pagefront:commerceRole": {
2258
+ "type": "array",
2259
+ "minItems": 1,
2260
+ "items": {
2261
+ "type": "string",
2262
+ "enum": [
2263
+ "brand_owner",
2264
+ "manufacturer",
2265
+ "seller"
2266
+ ]
2267
+ }
2268
+ },
2269
+ "pagefront:fulfillmentTerms": {
2270
+ "type": "array",
2271
+ "items": {
2272
+ "type": "object",
2273
+ "required": [
2274
+ "@type"
2275
+ ],
2276
+ "properties": {
2277
+ "@type": {
2278
+ "const": "OfferShippingDetails"
2279
+ }
2280
+ },
2281
+ "additionalProperties": true
2282
+ }
2283
+ },
2284
+ "pagefront:socialAccount": {
2285
+ "type": "array",
2286
+ "items": {
2287
+ "type": "object",
2288
+ "required": [
2289
+ "platform",
2290
+ "url"
2291
+ ],
2292
+ "properties": {
2293
+ "@type": {
2294
+ "const": "pagefront:SocialAccount"
2295
+ },
2296
+ "platform": {
2297
+ "type": "string",
2298
+ "minLength": 1
2299
+ },
2300
+ "url": {
2301
+ "type": "string",
2302
+ "format": "uri"
2303
+ },
2304
+ "handle": {
2305
+ "type": "string",
2306
+ "minLength": 1
2307
+ }
2308
+ },
2309
+ "additionalProperties": true
2310
+ }
2311
+ },
2312
+ "pagefront:authorizedResellers": {
2313
+ "type": "object",
2314
+ "required": [
2315
+ "reseller"
2316
+ ],
2317
+ "properties": {
2318
+ "@type": {
2319
+ "const": "pagefront:AuthorizedResellers"
2320
+ },
2321
+ "exhaustive": {
2322
+ "type": "boolean"
2323
+ },
2324
+ "reseller": {
2325
+ "type": "array",
2326
+ "minItems": 1,
2327
+ "items": {
2328
+ "type": "object",
2329
+ "required": [
2330
+ "organization"
2331
+ ],
2332
+ "properties": {
2333
+ "organization": {
2334
+ "type": "object",
2335
+ "properties": {
2336
+ "@type": {
2337
+ "type": "string"
2338
+ },
2339
+ "@id": {
2340
+ "type": "string",
2341
+ "format": "uri"
2342
+ },
2343
+ "name": {
2344
+ "type": "string",
2345
+ "minLength": 1
2346
+ },
2347
+ "url": {
2348
+ "type": "string",
2349
+ "format": "uri"
2350
+ },
2351
+ "address": {
2352
+ "type": "object"
2353
+ }
2354
+ },
2355
+ "anyOf": [
2356
+ {
2357
+ "required": [
2358
+ "@id"
2359
+ ]
2360
+ },
2361
+ {
2362
+ "required": [
2363
+ "name",
2364
+ "url"
2365
+ ]
2366
+ },
2367
+ {
2368
+ "required": [
2369
+ "name",
2370
+ "address"
2371
+ ]
2372
+ }
2373
+ ],
2374
+ "additionalProperties": true
2375
+ },
2376
+ "areaServed": {
2377
+ "oneOf": [
2378
+ {
2379
+ "type": "object"
2380
+ },
2381
+ {
2382
+ "type": "array",
2383
+ "minItems": 1,
2384
+ "items": {
2385
+ "type": "object"
2386
+ }
2387
+ }
2388
+ ]
2389
+ }
2390
+ },
2391
+ "additionalProperties": false
2392
+ }
2393
+ }
2394
+ },
2395
+ "additionalProperties": false
2396
+ },
2397
+ "pagefront:availableLanguages": {
2398
+ "type": "array",
2399
+ "items": {
2400
+ "type": "object",
2401
+ "required": [
2402
+ "lang",
2403
+ "url"
2404
+ ],
2405
+ "properties": {
2406
+ "lang": {
2407
+ "type": "string"
2408
+ },
2409
+ "url": {
2410
+ "type": "string",
2411
+ "format": "uri"
2412
+ }
2413
+ },
2414
+ "additionalProperties": false
2415
+ }
2416
+ }
2417
+ },
2418
+ "additionalProperties": true
2419
+ },
2420
+ "certification": {
2421
+ "type": "object",
2422
+ "required": [
2423
+ "@type",
2424
+ "name"
2425
+ ],
2426
+ "properties": {
2427
+ "@type": {
2428
+ "const": "Certification"
2429
+ },
2430
+ "name": {
2431
+ "type": "string"
2432
+ },
2433
+ "issuedBy": {
2434
+ "type": "object"
2435
+ },
2436
+ "about": {
2437
+ "type": "string"
2438
+ },
2439
+ "additionalProperty": {
2440
+ "type": "array"
2441
+ }
2442
+ },
2443
+ "additionalProperties": true
2444
+ }
2445
+ }
2446
+ };