docusaurus-plugin-generate-schema-docs 1.8.4 → 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 +10 -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__/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/exampleModel.test.js +209 -0
- package/__tests__/helpers/file-system.test.js +73 -1
- package/__tests__/helpers/getConstraints.test.js +27 -0
- package/__tests__/helpers/mergeSchema.test.js +94 -0
- package/__tests__/helpers/processSchema.test.js +291 -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/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 +139 -3
- package/__tests__/update-schema-ids.test.js +70 -1
- package/__tests__/validateSchemas-integration.test.js +2 -2
- package/__tests__/validateSchemas.test.js +142 -1
- package/generateEventDocs.js +21 -1
- package/helpers/constraintSchemaPaths.js +10 -14
- package/helpers/schemaToTableData.js +538 -492
- 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 +25 -7
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @jest-environment node
|
|
2
|
+
* @jest-environment @stryker-mutator/jest-runner/jest-env/node
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import fs from 'fs';
|
|
@@ -21,6 +21,75 @@ describe('updateSchemaIds', () => {
|
|
|
21
21
|
fs.rmSync(tempSiteDir, { recursive: true });
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
it('skips versions whose schema directory does not exist (L33)', () => {
|
|
25
|
+
// Add a version that has no corresponding directory
|
|
26
|
+
const versionsPath = path.join(tempSiteDir, 'versions.json');
|
|
27
|
+
fs.writeFileSync(versionsPath, JSON.stringify(['1.1.1', '9.9.9']));
|
|
28
|
+
|
|
29
|
+
// Should not throw; 9.9.9 directory doesn't exist and is skipped
|
|
30
|
+
expect(() => updateSchemaIds(tempSiteDir, url)).not.toThrow();
|
|
31
|
+
|
|
32
|
+
// The existing 1.1.1 schemas should still be updated
|
|
33
|
+
const schemaPath = path.join(
|
|
34
|
+
tempSiteDir,
|
|
35
|
+
'static/schemas',
|
|
36
|
+
'1.1.1',
|
|
37
|
+
'add-to-cart-event.json',
|
|
38
|
+
);
|
|
39
|
+
const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8'));
|
|
40
|
+
expect(schema.$id).toBe(
|
|
41
|
+
'https://tracking-docs-demo.buchert.digital/schemas/1.1.1/add-to-cart-event.json',
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('skips non-.json files in schema directories (L19)', () => {
|
|
46
|
+
// Create a non-json file in the schema directory
|
|
47
|
+
const nonJsonPath = path.join(
|
|
48
|
+
tempSiteDir,
|
|
49
|
+
'static/schemas',
|
|
50
|
+
'1.1.1',
|
|
51
|
+
'readme.txt',
|
|
52
|
+
);
|
|
53
|
+
fs.writeFileSync(nonJsonPath, 'This is not a JSON file');
|
|
54
|
+
|
|
55
|
+
expect(() => updateSchemaIds(tempSiteDir, url)).not.toThrow();
|
|
56
|
+
|
|
57
|
+
// The non-json file should remain unchanged
|
|
58
|
+
const content = fs.readFileSync(nonJsonPath, 'utf8');
|
|
59
|
+
expect(content).toBe('This is not a JSON file');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('accepts a specific version parameter (L27-28)', () => {
|
|
63
|
+
updateSchemaIds(tempSiteDir, url, '1.1.1');
|
|
64
|
+
|
|
65
|
+
const schemaPath = path.join(
|
|
66
|
+
tempSiteDir,
|
|
67
|
+
'static/schemas',
|
|
68
|
+
'1.1.1',
|
|
69
|
+
'add-to-cart-event.json',
|
|
70
|
+
);
|
|
71
|
+
const schema = JSON.parse(fs.readFileSync(schemaPath, 'utf8'));
|
|
72
|
+
expect(schema.$id).toBe(
|
|
73
|
+
'https://tracking-docs-demo.buchert.digital/schemas/1.1.1/add-to-cart-event.json',
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('returns early when versions.json does not exist (L6-8)', () => {
|
|
78
|
+
const noVersionsDir = path.resolve(__dirname, '__temp_no_versions__');
|
|
79
|
+
fs.mkdirSync(noVersionsDir, { recursive: true });
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
83
|
+
updateSchemaIds(noVersionsDir, url);
|
|
84
|
+
expect(consoleSpy).toHaveBeenCalledWith(
|
|
85
|
+
'No versions.json file found, skipping schema ID update.',
|
|
86
|
+
);
|
|
87
|
+
consoleSpy.mockRestore();
|
|
88
|
+
} finally {
|
|
89
|
+
fs.rmSync(noVersionsDir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
24
93
|
it('should update the $id of the schemas in the versioned directories', () => {
|
|
25
94
|
updateSchemaIds(tempSiteDir, url);
|
|
26
95
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @jest-environment node
|
|
2
|
+
* @jest-environment @stryker-mutator/jest-runner/jest-env/node
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import path from 'path';
|
|
@@ -25,5 +25,5 @@ describe('validateSchemas - Integration', () => {
|
|
|
25
25
|
const { schemaDir } = getPathsForVersion('next', siteDir);
|
|
26
26
|
const result = await validateSchemas(schemaDir);
|
|
27
27
|
expect(result).toBe(true);
|
|
28
|
-
});
|
|
28
|
+
}, 60000);
|
|
29
29
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @jest-environment node
|
|
2
|
+
* @jest-environment @stryker-mutator/jest-runner/jest-env/node
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import path from 'path';
|
|
@@ -152,4 +152,145 @@ describe('validateSchemas', () => {
|
|
|
152
152
|
const result = await validateSchemas(schemaDir);
|
|
153
153
|
expect(result).toBe(true);
|
|
154
154
|
});
|
|
155
|
+
|
|
156
|
+
it('should return false and log errors when a schema produces no examples', async () => {
|
|
157
|
+
const fixturePath = path.resolve(
|
|
158
|
+
__dirname,
|
|
159
|
+
'__fixtures__',
|
|
160
|
+
'validateSchemas',
|
|
161
|
+
'no-example-schema.json',
|
|
162
|
+
);
|
|
163
|
+
const schemaDir = path.join(tmpDir, 'schemas');
|
|
164
|
+
fs.mkdirSync(schemaDir, { recursive: true });
|
|
165
|
+
fs.copyFileSync(
|
|
166
|
+
fixturePath,
|
|
167
|
+
path.join(schemaDir, 'no-example-schema.json'),
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const result = await validateSchemas(schemaDir);
|
|
171
|
+
expect(result).toBe(false);
|
|
172
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
173
|
+
const errorMessages = consoleErrorSpy.mock.calls
|
|
174
|
+
.map((c) => c[0])
|
|
175
|
+
.join('\n');
|
|
176
|
+
expect(errorMessages).toContain('does not produce any examples');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should return false and log error when processing a schema throws', async () => {
|
|
180
|
+
const fixturePath = path.resolve(
|
|
181
|
+
__dirname,
|
|
182
|
+
'__fixtures__',
|
|
183
|
+
'validateSchemas',
|
|
184
|
+
'main-schema-with-missing-ref.json',
|
|
185
|
+
);
|
|
186
|
+
const schemaDir = path.join(tmpDir, 'schemas');
|
|
187
|
+
fs.mkdirSync(schemaDir, { recursive: true });
|
|
188
|
+
fs.copyFileSync(
|
|
189
|
+
fixturePath,
|
|
190
|
+
path.join(schemaDir, 'main-schema-with-missing-ref.json'),
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const result = await validateSchemas(schemaDir);
|
|
194
|
+
expect(result).toBe(false);
|
|
195
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
196
|
+
const errorMessages = consoleErrorSpy.mock.calls
|
|
197
|
+
.map((c) => c[0])
|
|
198
|
+
.join('\n');
|
|
199
|
+
expect(errorMessages).toContain('Error processing');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should report errors for all failing schemas when multiple schemas exist', async () => {
|
|
203
|
+
const schemaDir = path.join(tmpDir, 'schemas');
|
|
204
|
+
fs.mkdirSync(schemaDir, { recursive: true });
|
|
205
|
+
|
|
206
|
+
// First schema: valid
|
|
207
|
+
fs.writeFileSync(
|
|
208
|
+
path.join(schemaDir, 'valid.json'),
|
|
209
|
+
JSON.stringify({
|
|
210
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
211
|
+
type: 'object',
|
|
212
|
+
properties: { event: { type: 'string', const: 'ok' } },
|
|
213
|
+
required: ['event'],
|
|
214
|
+
}),
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Second schema: no examples produced
|
|
218
|
+
fs.writeFileSync(
|
|
219
|
+
path.join(schemaDir, 'no-examples.json'),
|
|
220
|
+
JSON.stringify({
|
|
221
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
222
|
+
type: 'object',
|
|
223
|
+
properties: { untyped: { description: 'no type or example' } },
|
|
224
|
+
required: ['untyped'],
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const result = await validateSchemas(schemaDir);
|
|
229
|
+
expect(result).toBe(false);
|
|
230
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('should return false when a oneOf option produces an undefined example', async () => {
|
|
234
|
+
const schemaDir = path.join(tmpDir, 'schemas');
|
|
235
|
+
fs.mkdirSync(schemaDir, { recursive: true });
|
|
236
|
+
|
|
237
|
+
// Schema with a oneOf where one option has no resolvable example
|
|
238
|
+
fs.writeFileSync(
|
|
239
|
+
path.join(schemaDir, 'undef-option.json'),
|
|
240
|
+
JSON.stringify({
|
|
241
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
242
|
+
type: 'object',
|
|
243
|
+
oneOf: [
|
|
244
|
+
{
|
|
245
|
+
title: 'ValidOption',
|
|
246
|
+
properties: { event: { type: 'string', const: 'test' } },
|
|
247
|
+
required: ['event'],
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
title: 'UndefinedOption',
|
|
251
|
+
properties: { mystery: { description: 'no type, no example' } },
|
|
252
|
+
required: ['mystery'],
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
}),
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
const result = await validateSchemas(schemaDir);
|
|
259
|
+
expect(result).toBe(false);
|
|
260
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
261
|
+
const errorMessages = consoleErrorSpy.mock.calls
|
|
262
|
+
.map((c) => c[0])
|
|
263
|
+
.join('\n');
|
|
264
|
+
expect(errorMessages).toContain('does not produce a valid example');
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
it('should report all examples invalid when every example fails validation', async () => {
|
|
268
|
+
const schemaDir = path.join(tmpDir, 'schemas');
|
|
269
|
+
fs.mkdirSync(schemaDir, { recursive: true });
|
|
270
|
+
|
|
271
|
+
// Schema where every oneOf option produces an example that fails schema validation
|
|
272
|
+
fs.writeFileSync(
|
|
273
|
+
path.join(schemaDir, 'all-invalid.json'),
|
|
274
|
+
JSON.stringify({
|
|
275
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
276
|
+
type: 'object',
|
|
277
|
+
properties: {
|
|
278
|
+
count: {
|
|
279
|
+
type: 'integer',
|
|
280
|
+
minimum: 100,
|
|
281
|
+
example: 1,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
required: ['count'],
|
|
285
|
+
}),
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
const result = await validateSchemas(schemaDir);
|
|
289
|
+
expect(result).toBe(false);
|
|
290
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
291
|
+
const errorMessages = consoleErrorSpy.mock.calls
|
|
292
|
+
.map((c) => c[0])
|
|
293
|
+
.join('\n');
|
|
294
|
+
expect(errorMessages).toContain('example data failed validation');
|
|
295
|
+
});
|
|
155
296
|
});
|
package/generateEventDocs.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
writeDoc,
|
|
8
8
|
createDir,
|
|
9
9
|
} from './helpers/file-system.js';
|
|
10
|
-
import { processOneOfSchema
|
|
10
|
+
import { processOneOfSchema } from './helpers/schema-processing.js';
|
|
11
11
|
import SchemaDocTemplate from './helpers/schema-doc-template.js';
|
|
12
12
|
import ChoiceIndexTemplate from './helpers/choice-index-template.js';
|
|
13
13
|
import processSchema from './helpers/processSchema.js';
|
|
@@ -233,6 +233,26 @@ async function generateOneOfDocs(
|
|
|
233
233
|
|
|
234
234
|
const processed = await processOneOfSchema(schema, filePath);
|
|
235
235
|
|
|
236
|
+
// Remove stale files/dirs from previous runs that are no longer in the schema
|
|
237
|
+
const expectedNames = new Set(['index.mdx']);
|
|
238
|
+
for (const [
|
|
239
|
+
index,
|
|
240
|
+
{ slug, schema: processedSchema },
|
|
241
|
+
] of processed.entries()) {
|
|
242
|
+
const prefixedSlug = `${(index + 1).toString().padStart(2, '0')}-${slug}`;
|
|
243
|
+
expectedNames.add(
|
|
244
|
+
processedSchema.oneOf ? prefixedSlug : `${prefixedSlug}.mdx`,
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
for (const entry of fs.readdirSync(eventOutputDir, { withFileTypes: true })) {
|
|
248
|
+
if (!expectedNames.has(entry.name)) {
|
|
249
|
+
const fullPath = path.join(eventOutputDir, entry.name);
|
|
250
|
+
entry.isDirectory()
|
|
251
|
+
? fs.rmSync(fullPath, { recursive: true })
|
|
252
|
+
: fs.unlinkSync(fullPath);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
236
256
|
const indexPageContent = ChoiceIndexTemplate({
|
|
237
257
|
schema,
|
|
238
258
|
processedOptions: processed,
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
|
|
4
|
+
function buildCandidatePaths(baseSegments, packageName) {
|
|
5
|
+
return [
|
|
6
|
+
path.resolve(process.cwd(), ...baseSegments, packageName),
|
|
7
|
+
path.resolve(process.cwd(), '..', ...baseSegments, packageName),
|
|
8
|
+
path.resolve(process.cwd(), '..', '..', ...baseSegments, packageName),
|
|
9
|
+
];
|
|
10
|
+
}
|
|
11
|
+
|
|
4
12
|
function getConstraintsPackageRoot() {
|
|
5
13
|
const candidates = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
process.cwd(),
|
|
9
|
-
'..',
|
|
10
|
-
'packages',
|
|
11
|
-
'tracking-target-constraints',
|
|
12
|
-
),
|
|
13
|
-
path.resolve(
|
|
14
|
-
process.cwd(),
|
|
15
|
-
'..',
|
|
16
|
-
'..',
|
|
17
|
-
'packages',
|
|
18
|
-
'tracking-target-constraints',
|
|
19
|
-
),
|
|
14
|
+
...buildCandidatePaths(['packages'], 'tracking-target-constraints'),
|
|
15
|
+
...buildCandidatePaths(['node_modules'], 'tracking-target-constraints'),
|
|
20
16
|
];
|
|
21
17
|
|
|
22
18
|
return candidates.find((candidate) => fs.existsSync(candidate));
|