docusaurus-plugin-generate-schema-docs 1.2.0 → 1.4.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 (89) hide show
  1. package/README.md +70 -6
  2. package/__tests__/ExampleDataLayer.test.js +91 -155
  3. package/__tests__/__fixtures__/static/schemas/add-to-cart-event.json +4 -15
  4. package/__tests__/__fixtures__/static/schemas/anchor/parent-event-anchor.json +29 -0
  5. package/__tests__/__fixtures__/static/schemas/choice-event.json +72 -0
  6. package/__tests__/__fixtures__/static/schemas/components/dataLayer.json +52 -54
  7. package/__tests__/__fixtures__/static/schemas/components/product.json +124 -210
  8. package/__tests__/__fixtures__/static/schemas/nested/child-event.json +10 -0
  9. package/__tests__/__fixtures__/static/schemas/nested/grandchild-a.json +9 -0
  10. package/__tests__/__fixtures__/static/schemas/nested/grandchild-b.json +9 -0
  11. package/__tests__/__fixtures__/static/schemas/nested/parent-event.json +7 -0
  12. package/__tests__/__fixtures__/static/schemas/root-any-of-event.json +34 -0
  13. package/__tests__/__fixtures__/static/schemas/root-choice-event.json +36 -0
  14. package/__tests__/__fixtures__/validateSchemas/circular-schema.json +6 -6
  15. package/__tests__/__fixtures__/validateSchemas/components/referenced.json +9 -7
  16. package/__tests__/__fixtures__/validateSchemas/invalid-example-schema.json +7 -7
  17. package/__tests__/__fixtures__/validateSchemas/main-schema-with-missing-ref.json +7 -7
  18. package/__tests__/__fixtures__/validateSchemas/main-schema-with-ref.json +7 -7
  19. package/__tests__/__fixtures__/validateSchemas/no-example-schema.json +11 -11
  20. package/__tests__/__fixtures__/validateSchemas/schema-A.json +5 -5
  21. package/__tests__/__fixtures__/validateSchemas/schema-B.json +5 -5
  22. package/__tests__/__fixtures__/validateSchemas/valid-schema.json +7 -7
  23. package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/add-to-cart-event.json +44 -0
  24. package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/components/dataLayer.json +56 -0
  25. package/__tests__/__fixtures_versioned__/static/schemas/1.1.1/components/product.json +125 -0
  26. package/__tests__/__fixtures_versioned__/static/schemas/next/add-to-cart-event.json +44 -0
  27. package/__tests__/__fixtures_versioned__/static/schemas/next/components/dataLayer.json +56 -0
  28. package/__tests__/__fixtures_versioned__/static/schemas/next/components/product.json +125 -0
  29. package/__tests__/__fixtures_versioned__/versions.json +1 -0
  30. package/__tests__/__snapshots__/ExampleDataLayer.test.js.snap +117 -0
  31. package/__tests__/__snapshots__/generateEventDocs.anchor.test.js.snap +79 -0
  32. package/__tests__/__snapshots__/generateEventDocs.nested.test.js.snap +98 -0
  33. package/__tests__/__snapshots__/generateEventDocs.test.js.snap +129 -16
  34. package/__tests__/__snapshots__/generateEventDocs.versioned.test.js.snap +59 -0
  35. package/__tests__/components/FoldableRows.test.js +330 -0
  36. package/__tests__/components/PropertiesTable.test.js +67 -17
  37. package/__tests__/components/PropertyRow.test.js +471 -51
  38. package/__tests__/components/SchemaJsonViewer.test.js +23 -19
  39. package/__tests__/components/SchemaRows.test.js +96 -66
  40. package/__tests__/components/SchemaViewer.test.js +34 -17
  41. package/__tests__/components/TableHeader.test.js +12 -12
  42. package/__tests__/generateEventDocs.anchor.test.js +71 -0
  43. package/__tests__/generateEventDocs.nested.test.js +80 -0
  44. package/__tests__/generateEventDocs.test.js +77 -71
  45. package/__tests__/generateEventDocs.versioned.test.js +69 -0
  46. package/__tests__/helpers/buildExampleFromSchema.test.js +160 -160
  47. package/__tests__/helpers/example-helper.test.js +71 -0
  48. package/__tests__/helpers/file-system.test.js +44 -0
  49. package/__tests__/helpers/getConstraints.test.js +93 -48
  50. package/__tests__/helpers/loadSchema.test.js +11 -5
  51. package/__tests__/helpers/path-helpers.test.js +34 -0
  52. package/__tests__/helpers/processSchema.test.js +42 -22
  53. package/__tests__/helpers/schema-processing.test.js +82 -0
  54. package/__tests__/helpers/schemaToExamples.test.js +56 -0
  55. package/__tests__/helpers/schemaToTableData.filtering.test.js +65 -0
  56. package/__tests__/helpers/schemaToTableData.hierarchicalLines.test.js +539 -0
  57. package/__tests__/helpers/schemaToTableData.test.js +217 -0
  58. package/__tests__/helpers/update-schema-ids.test.js +107 -0
  59. package/__tests__/update-schema-ids.test.js +39 -0
  60. package/__tests__/validateSchemas.test.js +125 -88
  61. package/components/ExampleDataLayer.js +68 -28
  62. package/components/FoldableRows.js +164 -0
  63. package/components/PropertiesTable.js +24 -6
  64. package/components/PropertiesTable.module.css +27 -0
  65. package/components/PropertyRow.js +168 -60
  66. package/components/SchemaJsonViewer.js +6 -6
  67. package/components/SchemaRows.css +242 -14
  68. package/components/SchemaRows.js +24 -41
  69. package/components/SchemaViewer.js +20 -14
  70. package/components/TableHeader.js +12 -12
  71. package/components/WordWrapButton.js +31 -0
  72. package/components/wordWrapButton.module.css +8 -0
  73. package/generateEventDocs.js +142 -61
  74. package/helpers/buildExampleFromSchema.js +60 -72
  75. package/helpers/choice-index-template.js +22 -0
  76. package/helpers/example-helper.js +41 -0
  77. package/helpers/file-system.js +32 -0
  78. package/helpers/getConstraints.js +44 -44
  79. package/helpers/loadSchema.js +2 -2
  80. package/helpers/path-helpers.js +22 -0
  81. package/helpers/processSchema.js +19 -19
  82. package/helpers/{mdx-template.js → schema-doc-template.js} +20 -13
  83. package/helpers/schema-processing.js +77 -0
  84. package/helpers/schemaToExamples.js +99 -0
  85. package/helpers/schemaToTableData.js +312 -0
  86. package/helpers/update-schema-ids.js +47 -0
  87. package/index.js +153 -55
  88. package/package.json +1 -1
  89. package/validateSchemas.js +56 -71
@@ -0,0 +1,312 @@
1
+ import { getConstraints } from './getConstraints';
2
+ import { getExamples } from './example-helper';
3
+
4
+ function processOptions(
5
+ choices,
6
+ level,
7
+ path,
8
+ isNestedInProperty,
9
+ requiredArray = [],
10
+ continuingLevels = [],
11
+ ) {
12
+ return choices.map((optionSchema, index) => {
13
+ const optionTitle = optionSchema.title || 'Option';
14
+
15
+ // Determine if this is the last option in the list.
16
+ // If it is NOT the last option, its children must not close the visual tree branch.
17
+ const isLastOption = index === choices.length - 1;
18
+
19
+ let optionRows = [];
20
+
21
+ // This is a primitive type (string, number, etc.) within a choice
22
+ if (optionSchema.type && !optionSchema.properties) {
23
+ const isRequired = requiredArray.includes(path[path.length - 1]);
24
+ const constraints = getConstraints(optionSchema);
25
+ if (isRequired) {
26
+ constraints.unshift('required');
27
+ }
28
+
29
+ optionRows.push({
30
+ type: 'property',
31
+ // The name of the property is the name of the parent property that holds the choice
32
+ name: path.length > 0 ? path[path.length - 1] : optionTitle,
33
+ path: [...path, `(${optionTitle})`],
34
+ // If it's a top-level choice (like user_id), the level is the same as the choice itself.
35
+ // Otherwise, it's nested.
36
+ level: level,
37
+ required: isRequired,
38
+ propertyType: optionSchema.type,
39
+ description: optionSchema.description,
40
+ examples: getExamples(optionSchema),
41
+ constraints: constraints,
42
+ isLastInGroup: isLastOption, // Updated: Uses the calculated flag instead of always true
43
+ hasChildren: false,
44
+ containerType: null,
45
+ continuingLevels: [...continuingLevels],
46
+ });
47
+ } else {
48
+ // This is a complex object within a choice
49
+ optionRows = schemaToTableData(
50
+ optionSchema,
51
+ // If nested in a property (like payment_method), the sub-properties start at the same level as the choice
52
+ // Otherwise, they are one level deeper.
53
+ level,
54
+ isNestedInProperty ? [] : path,
55
+ continuingLevels,
56
+ isLastOption,
57
+ );
58
+ }
59
+
60
+ return {
61
+ title: optionTitle,
62
+ description: optionSchema.description,
63
+ rows: optionRows,
64
+ };
65
+ });
66
+ }
67
+
68
+ export function schemaToTableData(
69
+ schema,
70
+ level = 0,
71
+ path = [],
72
+ parentContinuingLevels = [],
73
+ isLastOption = true,
74
+ ) {
75
+ const flatRows = [];
76
+
77
+ function isEffectivelyEmpty(schemaNode) {
78
+ if (
79
+ schemaNode.type !== 'object' &&
80
+ typeof schemaNode.properties === 'undefined'
81
+ ) {
82
+ return false;
83
+ }
84
+ if (schemaNode.oneOf || schemaNode.anyOf) {
85
+ return false;
86
+ }
87
+ if (
88
+ !schemaNode.properties ||
89
+ Object.keys(schemaNode.properties).length === 0
90
+ ) {
91
+ return true;
92
+ }
93
+ return Object.values(schemaNode.properties).every(isEffectivelyEmpty);
94
+ }
95
+
96
+ function buildRows(
97
+ subSchema,
98
+ currentLevel,
99
+ currentPath,
100
+ requiredFromParent = [],
101
+ continuingLevels = [],
102
+ ) {
103
+ if (!subSchema) return;
104
+
105
+ if (subSchema.properties) {
106
+ const propKeys = Object.keys(subSchema.properties);
107
+ const hasSiblingChoices = !!(subSchema.oneOf || subSchema.anyOf);
108
+
109
+ // Filter out properties that should be skipped to get accurate count
110
+ const visiblePropKeys = propKeys.filter((name) => {
111
+ const propSchema = subSchema.properties[name];
112
+ return !(
113
+ propSchema['x-gtm-clear'] === true && isEffectivelyEmpty(propSchema)
114
+ );
115
+ });
116
+
117
+ visiblePropKeys.forEach((name, index) => {
118
+ const propSchema = subSchema.properties[name];
119
+ const newPath = [...currentPath, name];
120
+
121
+ const isLastProp =
122
+ index === visiblePropKeys.length - 1 && !hasSiblingChoices;
123
+
124
+ // Updated Logic:
125
+ // A property is visually "last" only if it is the last property
126
+ // AND (it is deeper in the hierarchy OR the parent option itself is the last one).
127
+ const isLast = isLastProp && (currentLevel !== level || isLastOption);
128
+
129
+ const isChoiceWrapper = !!(propSchema.oneOf || propSchema.anyOf);
130
+
131
+ // Determine if this property has children and what type
132
+ const hasNestedProperties = !!propSchema.properties;
133
+ const hasArrayItems =
134
+ propSchema.type === 'array' && !!propSchema.items?.properties;
135
+ const hasNestedChoice = isChoiceWrapper;
136
+ const hasChildren =
137
+ hasNestedProperties || hasArrayItems || hasNestedChoice;
138
+
139
+ // Determine container type for the symbol
140
+ let containerType = null;
141
+ if (
142
+ hasNestedProperties ||
143
+ (isChoiceWrapper && propSchema.type === 'object')
144
+ ) {
145
+ containerType = 'object';
146
+ } else if (hasArrayItems) {
147
+ containerType = 'array';
148
+ }
149
+
150
+ // Calculate continuing levels for children
151
+ // If this is not the last item, add current level to continuing levels for children
152
+ // If this IS the last item, remove the immediate parent level (currentLevel - 1) because
153
+ // that line stops at this item and should not continue through its children
154
+ const childContinuingLevels = isLast
155
+ ? continuingLevels.filter((lvl) => lvl !== currentLevel - 1)
156
+ : [...continuingLevels, currentLevel];
157
+
158
+ // This is a "simple" choice property like user_id.
159
+ // It gets unwrapped into a choice row directly.
160
+ if (
161
+ isChoiceWrapper &&
162
+ !propSchema.properties &&
163
+ propSchema.type !== 'object'
164
+ ) {
165
+ const choiceType = propSchema.oneOf ? 'oneOf' : 'anyOf';
166
+ const choices = propSchema[choiceType];
167
+ flatRows.push({
168
+ type: 'choice',
169
+ choiceType,
170
+ path: newPath,
171
+ level: currentLevel,
172
+ title: propSchema.title,
173
+ description: propSchema.description,
174
+ isLastInGroup: isLast,
175
+ hasChildren: false,
176
+ containerType: null,
177
+ continuingLevels: [...continuingLevels],
178
+ options: processOptions(
179
+ choices,
180
+ currentLevel,
181
+ newPath,
182
+ false,
183
+ subSchema.required || requiredFromParent,
184
+ childContinuingLevels,
185
+ ),
186
+ });
187
+ } else {
188
+ // This is a "normal" property or a complex one with a nested choice.
189
+ const isRequired =
190
+ (subSchema.required || requiredFromParent)?.includes(name) || false;
191
+ const constraints = getConstraints(propSchema);
192
+ if (isRequired) {
193
+ constraints.unshift('required');
194
+ }
195
+
196
+ flatRows.push({
197
+ type: 'property',
198
+ name,
199
+ path: newPath,
200
+ level: currentLevel,
201
+ required: isRequired,
202
+ propertyType:
203
+ propSchema.type || (propSchema.enum ? 'enum' : 'object'),
204
+ description: propSchema.description,
205
+ examples: getExamples(propSchema),
206
+ constraints,
207
+ isLastInGroup: isLast,
208
+ hasChildren,
209
+ containerType,
210
+ continuingLevels: [...continuingLevels],
211
+ });
212
+
213
+ if (propSchema.properties) {
214
+ buildRows(
215
+ propSchema,
216
+ currentLevel + 1,
217
+ newPath,
218
+ propSchema.required,
219
+ childContinuingLevels,
220
+ );
221
+ } else if (
222
+ propSchema.type === 'array' &&
223
+ propSchema.items?.properties
224
+ ) {
225
+ buildRows(
226
+ propSchema.items,
227
+ currentLevel + 1,
228
+ [...newPath, '[n]'],
229
+ propSchema.items.required,
230
+ childContinuingLevels,
231
+ );
232
+ } else if (isChoiceWrapper) {
233
+ // This handles the "complex" choice property like payment_method.
234
+ // A property row has already been created above, now we add the choice row.
235
+ const choiceType = propSchema.oneOf ? 'oneOf' : 'anyOf';
236
+ const choices = propSchema[choiceType];
237
+ flatRows.push({
238
+ type: 'choice',
239
+ choiceType,
240
+ path: [...newPath, choiceType], // Make path unique
241
+ level: currentLevel + 1,
242
+ title: propSchema.title,
243
+ description: null,
244
+ isLastInGroup: true,
245
+ hasChildren: false,
246
+ containerType: null,
247
+ continuingLevels: childContinuingLevels,
248
+ options: processOptions(
249
+ choices,
250
+ currentLevel + 1,
251
+ newPath,
252
+ true,
253
+ propSchema.required,
254
+ childContinuingLevels,
255
+ ),
256
+ });
257
+ }
258
+ }
259
+ });
260
+ }
261
+
262
+ // This handles choices at the root of a schema
263
+ const choiceType = subSchema.oneOf
264
+ ? 'oneOf'
265
+ : subSchema.anyOf
266
+ ? 'anyOf'
267
+ : null;
268
+ if (choiceType) {
269
+ const choices = subSchema[choiceType];
270
+ flatRows.push({
271
+ type: 'choice',
272
+ choiceType,
273
+ path: currentPath,
274
+ level: currentLevel,
275
+ title: subSchema.title,
276
+ description: subSchema.description,
277
+ isLastInGroup: true,
278
+ hasChildren: false,
279
+ containerType: null,
280
+ continuingLevels: [...continuingLevels],
281
+ options: processOptions(
282
+ choices,
283
+ currentLevel,
284
+ currentPath,
285
+ false,
286
+ subSchema.required || requiredFromParent,
287
+ continuingLevels,
288
+ ),
289
+ });
290
+ } else if (!subSchema.properties && subSchema.type) {
291
+ // This handles a schema that is just a single primitive type
292
+ flatRows.push({
293
+ type: 'property',
294
+ name: subSchema.title || '<value>',
295
+ path: currentPath,
296
+ level: currentLevel,
297
+ required: false,
298
+ propertyType: subSchema.type,
299
+ description: subSchema.description,
300
+ examples: getExamples(subSchema),
301
+ constraints: getConstraints(subSchema),
302
+ isLastInGroup: true,
303
+ hasChildren: false,
304
+ containerType: null,
305
+ continuingLevels: [...continuingLevels],
306
+ });
307
+ }
308
+ }
309
+
310
+ buildRows(schema, level, path, schema.required, parentContinuingLevels);
311
+ return flatRows;
312
+ }
@@ -0,0 +1,47 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ export default function updateSchemaIds(siteDir, url, version = null) {
5
+ const versionsJsonPath = path.join(siteDir, 'versions.json');
6
+ if (!fs.existsSync(versionsJsonPath)) {
7
+ console.log('No versions.json file found, skipping schema ID update.');
8
+ return;
9
+ }
10
+
11
+ const getAllFiles = (dir, allFiles = []) => {
12
+ const files = fs.readdirSync(dir);
13
+
14
+ files.forEach((file) => {
15
+ const filePath = path.join(dir, file);
16
+ if (fs.statSync(filePath).isDirectory()) {
17
+ getAllFiles(filePath, allFiles);
18
+ } else {
19
+ if (file.endsWith('.json')) {
20
+ allFiles.push(filePath);
21
+ }
22
+ }
23
+ });
24
+ return allFiles;
25
+ };
26
+
27
+ const versions = version
28
+ ? [version]
29
+ : JSON.parse(fs.readFileSync(versionsJsonPath, 'utf8'));
30
+
31
+ for (const version of versions) {
32
+ const schemaDir = path.join(siteDir, 'static/schemas', version);
33
+ if (!fs.existsSync(schemaDir)) {
34
+ continue;
35
+ }
36
+ const files = getAllFiles(schemaDir);
37
+
38
+ for (const file of files) {
39
+ const schema = JSON.parse(fs.readFileSync(file, 'utf8'));
40
+ const baseUrl = url.endsWith('/') ? url.slice(0, -1) : url;
41
+ const relativePath = path.relative(path.join(siteDir, 'static'), file);
42
+ schema.$id = `${baseUrl}/${relativePath.replace(/\\/g, '/')}`;
43
+ fs.writeFileSync(file, JSON.stringify(schema, null, 2));
44
+ console.log(`Updated $id for ${file} in version ${version}`);
45
+ }
46
+ }
47
+ }
package/index.js CHANGED
@@ -1,60 +1,158 @@
1
+ import { getPathsForVersion } from './helpers/path-helpers.js';
2
+ import updateSchemaIds from './helpers/update-schema-ids.js';
3
+ import fs from 'fs';
1
4
  import validateSchemas from './validateSchemas.js';
2
5
  import generateEventDocs from './generateEventDocs.js';
3
6
  import path from 'path';
4
7
 
5
- export default async function (context) {
6
- const { siteDir } = context;
7
- const { organizationName, projectName } = context.siteConfig;
8
- const options = { organizationName, projectName, siteDir };
9
- const schemasPath = path.join(siteDir, 'static/schemas');
10
-
11
- // Generate docs on startup
12
- await generateEventDocs(options);
13
-
14
- return {
15
- name: 'docusaurus-plugin-generate-schema-docs',
16
-
17
- getPathsToWatch() {
18
- // Watch the schemas directory for changes
19
- return [schemasPath];
20
- },
21
-
22
- async loadContent() {
23
- // Generate event documentation when watched files change
24
- await generateEventDocs(options);
25
- },
26
-
27
- getThemePath() {
28
- return './components';
29
- },
30
-
31
- extendCli(cli) {
32
- cli
33
- .command('validate-schemas')
34
- .description('Validate JSON Schemas with the examples inside the schemas')
35
- .action(async () => {
36
- console.log('Validating GTM Schemas...');
37
- // You might get the path from 'options' or assume a default
38
- const schemaPath = options?.path || path.join(context.siteDir, 'static/schemas');
39
-
40
- const success = await validateSchemas(schemaPath);
41
-
42
- if (!success)
43
- {
44
- console.error('Validation failed.');
45
- process.exit(1); // Important for CI to fail!
46
- }
47
- console.log('āœ… All schemas and examples are valid!');
48
- });
49
-
50
- cli
51
- .command('generate schema-docs')
52
- .description('Generate schema documentation from JSON schemas')
53
- .action(async () => {
54
- // You can pass options here if generateEventDocs needs the path too
55
- // e.g., await generateEventDocs(options.path || './static/schemas');
56
- await generateEventDocs();
57
- });
58
- },
59
- };
8
+ export default async function (context, options) {
9
+ const { siteDir } = context;
10
+ const { dataLayerName } = options;
11
+ const { organizationName, projectName, url } = context.siteConfig;
12
+
13
+ const pluginOptions = {
14
+ organizationName,
15
+ projectName,
16
+ siteDir,
17
+ url,
18
+ dataLayerName,
19
+ };
20
+ const versionsJsonPath = path.join(siteDir, 'versions.json');
21
+ const isVersioned = fs.existsSync(versionsJsonPath);
22
+
23
+ const extendCli = (cli) => {
24
+ cli
25
+ .command('validate-schemas [version]')
26
+ .description('Validate JSON Schemas with the examples inside the schemas')
27
+ .action(async (version) => {
28
+ console.log('Validating GTM Schemas...');
29
+ const schemaVersion = version || 'next';
30
+ const { schemaDir } = getPathsForVersion(
31
+ schemaVersion,
32
+ context.siteDir,
33
+ );
34
+ const success = await validateSchemas(schemaDir);
35
+ if (!success) {
36
+ console.error('Validation failed.');
37
+ process.exit(1);
38
+ }
39
+ console.log('āœ… All schemas and examples are valid!');
40
+ });
41
+
42
+ cli
43
+ .command('generate-schema-docs')
44
+ .description('Generate schema documentation from JSON schemas')
45
+ .action(async () => {
46
+ if (isVersioned) {
47
+ const versions = JSON.parse(
48
+ fs.readFileSync(versionsJsonPath, 'utf8'),
49
+ );
50
+ for (const version of versions) {
51
+ // FIX 3: Removed 'newOptions' and used the consolidated pluginOptions
52
+ await generateEventDocs({ ...pluginOptions, version });
53
+ }
54
+ await generateEventDocs({ ...pluginOptions, version: 'current' });
55
+ } else {
56
+ await generateEventDocs(pluginOptions);
57
+ }
58
+ });
59
+
60
+ cli
61
+ .command('update-schema-ids [version]')
62
+ .description('Update the $id of the versioned schemas')
63
+ .action((version) => {
64
+ updateSchemaIds(siteDir, url, version);
65
+ });
66
+
67
+ cli
68
+ .command('version-with-schemas <version>')
69
+ .description(
70
+ 'Create a new docs version and copy schemas from next to versioned folder',
71
+ )
72
+ .action(async (version) => {
73
+ const { execSync } = await import('child_process');
74
+
75
+ console.log(`šŸ“¦ Creating docs version ${version}...`);
76
+ try {
77
+ // Run the standard docusaurus docs:version command
78
+ execSync(`npx docusaurus docs:version ${version}`, {
79
+ cwd: siteDir,
80
+ stdio: 'inherit',
81
+ });
82
+ } catch (error) {
83
+ console.error('āŒ Failed to create docs version');
84
+ process.exit(1);
85
+ }
86
+
87
+ console.log(`šŸ“‚ Copying schemas from next to ${version}...`);
88
+ const nextSchemasDir = path.join(siteDir, 'static/schemas/next');
89
+ const versionedSchemasDir = path.join(
90
+ siteDir,
91
+ 'static/schemas',
92
+ version,
93
+ );
94
+
95
+ if (!fs.existsSync(nextSchemasDir)) {
96
+ console.error(
97
+ `āŒ Source schemas directory not found: ${nextSchemasDir}`,
98
+ );
99
+ process.exit(1);
100
+ }
101
+
102
+ // Copy the schemas
103
+ try {
104
+ fs.cpSync(nextSchemasDir, versionedSchemasDir, { recursive: true });
105
+ console.log(`āœ… Schemas copied to ${versionedSchemasDir}`);
106
+ } catch (error) {
107
+ console.error(`āŒ Failed to copy schemas: ${error.message}`);
108
+ process.exit(1);
109
+ }
110
+
111
+ // Update schema IDs for the new version
112
+ console.log(`šŸ”„ Updating schema $ids for version ${version}...`);
113
+ updateSchemaIds(siteDir, url, version);
114
+
115
+ // Generate documentation for the new version
116
+ console.log(`šŸ“ Generating documentation for version ${version}...`);
117
+ await generateEventDocs({ ...pluginOptions, version });
118
+
119
+ console.log(`\nāœ… Version ${version} created successfully!`);
120
+ console.log(`\nNext steps:`);
121
+ console.log(` 1. Review the changes in static/schemas/${version}/`);
122
+ console.log(
123
+ ` 2. Review the changes in versioned_docs/version-${version}/`,
124
+ );
125
+ console.log(` 3. Commit the changes to version control`);
126
+ });
127
+ };
128
+
129
+ const schemasPath = isVersioned
130
+ ? path.join(siteDir, 'static/schemas/next')
131
+ : path.join(siteDir, 'static/schemas');
132
+
133
+ return {
134
+ name: 'docusaurus-plugin-generate-schema-docs',
135
+
136
+ getPathsToWatch() {
137
+ return [schemasPath];
138
+ },
139
+
140
+ async loadContent() {
141
+ if (isVersioned) {
142
+ const versions = JSON.parse(fs.readFileSync(versionsJsonPath, 'utf8'));
143
+ for (const version of versions) {
144
+ await generateEventDocs({ ...pluginOptions, version });
145
+ }
146
+ await generateEventDocs({ ...pluginOptions, version: 'current' });
147
+ } else {
148
+ await generateEventDocs(pluginOptions);
149
+ }
150
+ },
151
+
152
+ getThemePath() {
153
+ return './components';
154
+ },
155
+
156
+ extendCli,
157
+ };
60
158
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docusaurus-plugin-generate-schema-docs",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Docusaurus plugin to generate documentation from JSON schemas.",
5
5
  "main": "index.js",
6
6
  "license": "MIT",