docusaurus-plugin-generate-schema-docs 1.8.3 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/__tests__/__fixtures__/validateSchemas/main-schema-with-not-allof.json +11 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-anyof-multi.json +12 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-anyof.json +30 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-edge-cases.json +24 -0
- package/__tests__/__fixtures__/validateSchemas/schema-with-not-non-object.json +15 -0
- package/__tests__/__snapshots__/generateEventDocs.anchor.test.js.snap +6 -0
- package/__tests__/__snapshots__/generateEventDocs.nested.test.js.snap +6 -0
- package/__tests__/__snapshots__/generateEventDocs.test.js.snap +15 -0
- package/__tests__/__snapshots__/generateEventDocs.versioned.test.js.snap +6 -0
- package/__tests__/components/PropertiesTable.test.js +66 -0
- package/__tests__/components/PropertyRow.test.js +85 -4
- package/__tests__/components/SchemaJsonViewer.test.js +118 -0
- package/__tests__/generateEventDocs.anchor.test.js +1 -1
- package/__tests__/generateEventDocs.nested.test.js +1 -1
- package/__tests__/generateEventDocs.partials.test.js +1 -1
- package/__tests__/generateEventDocs.test.js +506 -1
- package/__tests__/generateEventDocs.versioned.test.js +1 -1
- package/__tests__/helpers/buildExampleFromSchema.test.js +240 -0
- package/__tests__/helpers/constraintSchemaPaths.test.js +208 -0
- package/__tests__/helpers/continuingLinesStyle.test.js +492 -0
- package/__tests__/helpers/example-helper.test.js +12 -0
- package/__tests__/helpers/exampleModel.test.js +209 -0
- package/__tests__/helpers/file-system.test.js +73 -1
- package/__tests__/helpers/getConstraints.test.js +43 -0
- package/__tests__/helpers/mergeSchema.test.js +94 -0
- package/__tests__/helpers/processSchema.test.js +309 -1
- package/__tests__/helpers/schema-doc-template.test.js +54 -0
- package/__tests__/helpers/schema-processing.test.js +122 -2
- package/__tests__/helpers/schemaToExamples.test.js +1007 -0
- package/__tests__/helpers/schemaToTableData.mutations.test.js +970 -0
- package/__tests__/helpers/schemaToTableData.test.js +157 -0
- package/__tests__/helpers/schemaTraversal.test.js +110 -0
- package/__tests__/helpers/snippetTargets.test.js +432 -0
- package/__tests__/helpers/trackingTargets.test.js +319 -0
- package/__tests__/helpers/validator.test.js +385 -1
- package/__tests__/index.test.js +436 -0
- package/__tests__/syncGtm.test.js +366 -6
- package/__tests__/update-schema-ids.test.js +70 -1
- package/__tests__/validateSchemas-integration.test.js +2 -2
- package/__tests__/validateSchemas.test.js +192 -1
- package/components/PropertiesTable.js +32 -2
- package/components/PropertyRow.js +29 -2
- package/components/SchemaJsonViewer.js +234 -131
- package/components/SchemaRows.css +40 -0
- package/components/SchemaViewer.js +11 -2
- package/generateEventDocs.js +21 -1
- package/helpers/constraintSchemaPaths.js +10 -14
- package/helpers/example-helper.js +2 -2
- package/helpers/getConstraints.js +20 -0
- package/helpers/processSchema.js +32 -1
- package/helpers/schema-doc-template.js +4 -0
- package/helpers/schemaToExamples.js +29 -35
- package/helpers/schemaToTableData.js +538 -492
- package/helpers/schemaTraversal.cjs +148 -0
- package/helpers/trackingTargets.js +26 -3
- package/helpers/validator.js +18 -4
- package/index.js +1 -2
- package/package.json +1 -1
- package/scripts/sync-gtm.js +65 -34
- package/test-data/payloadContracts.js +35 -0
- package/validateSchemas.js +1 -1
|
@@ -628,4 +628,161 @@ describe('schemaToTableData', () => {
|
|
|
628
628
|
expect(countryProp.isLastInGroup).toBe(false);
|
|
629
629
|
});
|
|
630
630
|
});
|
|
631
|
+
|
|
632
|
+
it('returns empty array for schema with no properties, no type, no choices', () => {
|
|
633
|
+
expect(schemaToTableData({})).toEqual([]);
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it('handles root-level oneOf with primitive options (no path, uses option title as name)', () => {
|
|
637
|
+
const schema = {
|
|
638
|
+
oneOf: [
|
|
639
|
+
{ title: 'String Option', type: 'string', description: 'A string.' },
|
|
640
|
+
{ type: 'integer', description: 'An integer.' },
|
|
641
|
+
],
|
|
642
|
+
};
|
|
643
|
+
const tableData = schemaToTableData(schema);
|
|
644
|
+
const choiceRow = tableData.find((r) => r.type === 'choice');
|
|
645
|
+
expect(choiceRow).toBeDefined();
|
|
646
|
+
expect(choiceRow.options).toHaveLength(2);
|
|
647
|
+
|
|
648
|
+
// First option has a title, primitive type renders as property row
|
|
649
|
+
const opt1Rows = choiceRow.options[0].rows;
|
|
650
|
+
expect(opt1Rows).toHaveLength(1);
|
|
651
|
+
expect(opt1Rows[0].name).toBe('String Option');
|
|
652
|
+
|
|
653
|
+
// Second option has no title, falls back to 'Option'
|
|
654
|
+
const opt2Rows = choiceRow.options[1].rows;
|
|
655
|
+
expect(opt2Rows).toHaveLength(1);
|
|
656
|
+
expect(opt2Rows[0].name).toBe('Option');
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
it('handles conditional with only else (no then branch)', () => {
|
|
660
|
+
const schema = {
|
|
661
|
+
type: 'object',
|
|
662
|
+
properties: { status: { type: 'string' } },
|
|
663
|
+
if: { properties: { status: { const: 'inactive' } } },
|
|
664
|
+
else: {
|
|
665
|
+
properties: { reason: { type: 'string' } },
|
|
666
|
+
},
|
|
667
|
+
};
|
|
668
|
+
const tableData = schemaToTableData(schema);
|
|
669
|
+
const conditionalRow = tableData.find((r) => r.type === 'conditional');
|
|
670
|
+
expect(conditionalRow).toBeDefined();
|
|
671
|
+
expect(conditionalRow.branches).toHaveLength(1);
|
|
672
|
+
expect(conditionalRow.branches[0].title).toBe('Else');
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
it('handles array items with if/else but no then', () => {
|
|
676
|
+
const schema = {
|
|
677
|
+
type: 'object',
|
|
678
|
+
properties: {
|
|
679
|
+
items: {
|
|
680
|
+
type: 'array',
|
|
681
|
+
items: {
|
|
682
|
+
type: 'object',
|
|
683
|
+
if: { properties: { kind: { const: 'physical' } } },
|
|
684
|
+
else: {
|
|
685
|
+
properties: { download_url: { type: 'string' } },
|
|
686
|
+
},
|
|
687
|
+
},
|
|
688
|
+
},
|
|
689
|
+
},
|
|
690
|
+
};
|
|
691
|
+
const tableData = schemaToTableData(schema);
|
|
692
|
+
const conditionalRow = tableData.find((r) => r.type === 'conditional');
|
|
693
|
+
expect(conditionalRow).toBeDefined();
|
|
694
|
+
expect(conditionalRow.branches).toHaveLength(1);
|
|
695
|
+
expect(conditionalRow.branches[0].title).toBe('Else');
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
it('handles property with simple anyOf (scalar options)', () => {
|
|
699
|
+
const schema = {
|
|
700
|
+
properties: {
|
|
701
|
+
value: {
|
|
702
|
+
description: 'A flexible value.',
|
|
703
|
+
anyOf: [
|
|
704
|
+
{ title: 'As String', type: 'string' },
|
|
705
|
+
{ title: 'As Number', type: 'number' },
|
|
706
|
+
],
|
|
707
|
+
},
|
|
708
|
+
},
|
|
709
|
+
};
|
|
710
|
+
const tableData = schemaToTableData(schema);
|
|
711
|
+
const choiceRow = tableData.find(
|
|
712
|
+
(r) => r.type === 'choice' && r.name === 'value',
|
|
713
|
+
);
|
|
714
|
+
expect(choiceRow).toBeDefined();
|
|
715
|
+
expect(choiceRow.choiceType).toBe('anyOf');
|
|
716
|
+
expect(choiceRow.options).toHaveLength(2);
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
it('marks choice as not last when sibling conditional follows', () => {
|
|
720
|
+
const schema = {
|
|
721
|
+
type: 'object',
|
|
722
|
+
properties: {
|
|
723
|
+
event: { type: 'string' },
|
|
724
|
+
},
|
|
725
|
+
oneOf: [
|
|
726
|
+
{
|
|
727
|
+
title: 'Option A',
|
|
728
|
+
properties: { a: { type: 'string' } },
|
|
729
|
+
},
|
|
730
|
+
],
|
|
731
|
+
if: { properties: { event: { const: 'special' } } },
|
|
732
|
+
then: {
|
|
733
|
+
properties: { extra: { type: 'string' } },
|
|
734
|
+
},
|
|
735
|
+
};
|
|
736
|
+
const tableData = schemaToTableData(schema);
|
|
737
|
+
const choiceRow = tableData.find((r) => r.type === 'choice');
|
|
738
|
+
const conditionalRow = tableData.find((r) => r.type === 'conditional');
|
|
739
|
+
expect(choiceRow).toBeDefined();
|
|
740
|
+
expect(conditionalRow).toBeDefined();
|
|
741
|
+
// Choice is NOT last because conditional follows
|
|
742
|
+
expect(choiceRow.isLastInGroup).toBe(false);
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
it('marks choice as not last when if/else (no then) conditional follows', () => {
|
|
746
|
+
const schema = {
|
|
747
|
+
type: 'object',
|
|
748
|
+
properties: {
|
|
749
|
+
event: { type: 'string' },
|
|
750
|
+
},
|
|
751
|
+
anyOf: [
|
|
752
|
+
{
|
|
753
|
+
title: 'Option X',
|
|
754
|
+
properties: { x: { type: 'string' } },
|
|
755
|
+
},
|
|
756
|
+
],
|
|
757
|
+
if: { properties: { event: { const: 'special' } } },
|
|
758
|
+
else: {
|
|
759
|
+
properties: { fallback: { type: 'string' } },
|
|
760
|
+
},
|
|
761
|
+
};
|
|
762
|
+
const tableData = schemaToTableData(schema);
|
|
763
|
+
const choiceRow = tableData.find((r) => r.type === 'choice');
|
|
764
|
+
const conditionalRow = tableData.find((r) => r.type === 'conditional');
|
|
765
|
+
expect(choiceRow).toBeDefined();
|
|
766
|
+
expect(conditionalRow).toBeDefined();
|
|
767
|
+
expect(choiceRow.isLastInGroup).toBe(false);
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
it('marks choice as last when no sibling conditional follows', () => {
|
|
771
|
+
const schema = {
|
|
772
|
+
type: 'object',
|
|
773
|
+
properties: {
|
|
774
|
+
event: { type: 'string' },
|
|
775
|
+
},
|
|
776
|
+
oneOf: [
|
|
777
|
+
{
|
|
778
|
+
title: 'Option A',
|
|
779
|
+
properties: { a: { type: 'string' } },
|
|
780
|
+
},
|
|
781
|
+
],
|
|
782
|
+
};
|
|
783
|
+
const tableData = schemaToTableData(schema);
|
|
784
|
+
const choiceRow = tableData.find((r) => r.type === 'choice');
|
|
785
|
+
expect(choiceRow).toBeDefined();
|
|
786
|
+
expect(choiceRow.isLastInGroup).toBe(true);
|
|
787
|
+
});
|
|
631
788
|
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const {
|
|
2
|
+
visitSchemaNodes,
|
|
3
|
+
visitSchemaPropertyEntries,
|
|
4
|
+
} = require('../../helpers/schemaTraversal.cjs');
|
|
5
|
+
|
|
6
|
+
describe('schemaTraversal', () => {
|
|
7
|
+
it('visits nested choice and conditional schema nodes', () => {
|
|
8
|
+
const schema = {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
payment_method: {
|
|
12
|
+
oneOf: [
|
|
13
|
+
{
|
|
14
|
+
properties: {
|
|
15
|
+
card_number: { type: 'string' },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
if: {
|
|
22
|
+
properties: {
|
|
23
|
+
platform: { const: 'ios' },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
then: {
|
|
27
|
+
properties: {
|
|
28
|
+
att_status: { type: 'string' },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const visitedPaths = [];
|
|
34
|
+
visitSchemaNodes(schema, (_node, context) => {
|
|
35
|
+
visitedPaths.push(context.path.join('.'));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
expect(visitedPaths).toEqual(
|
|
39
|
+
expect.arrayContaining([
|
|
40
|
+
'',
|
|
41
|
+
'properties.payment_method',
|
|
42
|
+
'properties.payment_method.oneOf.0',
|
|
43
|
+
'properties.payment_method.oneOf.0.properties.card_number',
|
|
44
|
+
'if',
|
|
45
|
+
'then',
|
|
46
|
+
'then.properties.att_status',
|
|
47
|
+
]),
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('collects property entries through object, array, choice, and conditional branches', () => {
|
|
52
|
+
const schema = {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
event: { type: 'string' },
|
|
56
|
+
items: {
|
|
57
|
+
type: 'array',
|
|
58
|
+
items: {
|
|
59
|
+
properties: {
|
|
60
|
+
sku: { type: 'string' },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
contact_method: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
oneOf: [
|
|
67
|
+
{
|
|
68
|
+
properties: {
|
|
69
|
+
email: { type: 'string' },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
properties: {
|
|
74
|
+
phone_number: { type: 'string' },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
then: {
|
|
81
|
+
properties: {
|
|
82
|
+
att_status: { type: 'string' },
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
else: {
|
|
86
|
+
properties: {
|
|
87
|
+
ad_personalization_enabled: { type: 'boolean' },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const variableNames = [];
|
|
93
|
+
visitSchemaPropertyEntries(schema, (_property, context) => {
|
|
94
|
+
variableNames.push(context.name);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(variableNames).toEqual(
|
|
98
|
+
expect.arrayContaining([
|
|
99
|
+
'event',
|
|
100
|
+
'items',
|
|
101
|
+
'items.0.sku',
|
|
102
|
+
'contact_method',
|
|
103
|
+
'contact_method.email',
|
|
104
|
+
'contact_method.phone_number',
|
|
105
|
+
'att_status',
|
|
106
|
+
'ad_personalization_enabled',
|
|
107
|
+
]),
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
});
|