@vendure-io/docs-provider 0.9.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.
@@ -1,10 +1,10 @@
1
- # MDX Compilation Testing
1
+ # Documentation Testing
2
2
 
3
- `@vendure-io/docs-provider` includes a testing module that allows you to validate MDX files **before publishing** your documentation package. This catches compilation errors early, reducing the feedback loop between publishing and discovering issues.
3
+ `@vendure-io/docs-provider` includes a comprehensive testing module that validates your documentation **before publishing**. It catches errors early, reducing the feedback loop between publishing and discovering issues.
4
4
 
5
- ## Why Test MDX Files?
5
+ ## Why Test Documentation?
6
6
 
7
- MDX compilation errors only surface when the documentation website attempts to render your pages. Without pre-publish testing, this creates a slow feedback loop:
7
+ Documentation errors only surface when the website attempts to render your pages. Without pre-publish testing, this creates a slow feedback loop:
8
8
 
9
9
  1. Write MDX content
10
10
  2. Publish package to npm
@@ -15,9 +15,18 @@ MDX compilation errors only surface when the documentation website attempts to r
15
15
 
16
16
  The testing module lets you catch errors at step 1, before any publishing occurs.
17
17
 
18
+ ## What Gets Validated?
19
+
20
+ The testing module runs four validators in sequence:
21
+
22
+ 1. **Frontmatter Validation** - Validates frontmatter against the DocPageMeta schema
23
+ 2. **Admonition Validation** - Checks for correct admonition syntax (bracket notation)
24
+ 3. **Code Language Validation** - Ensures code blocks use valid Shiki language identifiers
25
+ 4. **MDX Compilation** - Full AST parsing to catch syntax errors
26
+
18
27
  ## Installation
19
28
 
20
- The testing module is included in `@vendure-io/docs-provider`. No additional installation is required, but ensure you have the package installed:
29
+ The testing module is included in `@vendure-io/docs-provider`. No additional installation is required:
21
30
 
22
31
  ```bash
23
32
  npm install @vendure-io/docs-provider
@@ -27,30 +36,30 @@ bun add @vendure-io/docs-provider
27
36
 
28
37
  ## Quick Start
29
38
 
30
- ### Testing Your Manifest
39
+ ### Using runAllTests (Recommended)
31
40
 
32
- The simplest way to test all MDX files in your documentation package:
41
+ The simplest way to validate all documentation in your package:
33
42
 
34
43
  ```typescript
35
- import { manifest } from './src/manifest'
36
- import { testManifestMdx, formatTestReport } from '@vendure-io/docs-provider/testing'
44
+ // scripts/test-docs.ts
45
+ import { manifest } from '../src/manifest'
46
+ import { runAllTests } from '@vendure-io/docs-provider/testing'
37
47
 
38
- async function main() {
39
- const report = await testManifestMdx(manifest)
48
+ runAllTests(manifest)
49
+ ```
40
50
 
41
- console.log(formatTestReport(report))
42
- process.exit(report.failed > 0 ? 1 : 0)
43
- }
51
+ That's it! This single function call:
44
52
 
45
- main()
46
- ```
53
+ - Runs all 4 validators in sequence
54
+ - Prints a unified report to the console
55
+ - Exits with code 1 if any errors are found
47
56
 
48
- Save this as `scripts/test-mdx.ts` and run it:
57
+ Save this as `scripts/test-docs.ts` and run it:
49
58
 
50
59
  ```bash
51
- npx tsx scripts/test-mdx.ts
60
+ npx tsx scripts/test-docs.ts
52
61
  # or with bun
53
- bun run scripts/test-mdx.ts
62
+ bun run scripts/test-docs.ts
54
63
  ```
55
64
 
56
65
  ### Adding to package.json
@@ -60,25 +69,25 @@ Add a script to your `package.json` for easy execution:
60
69
  ```json
61
70
  {
62
71
  "scripts": {
63
- "test:mdx": "tsx scripts/test-mdx.ts",
64
- "prepublishOnly": "npm run test:mdx"
72
+ "test:docs": "tsx scripts/test-docs.ts",
73
+ "prepublishOnly": "npm run test:docs"
65
74
  }
66
75
  }
67
76
  ```
68
77
 
69
- The `prepublishOnly` script ensures MDX validation runs before every npm publish.
78
+ The `prepublishOnly` script ensures validation runs before every npm publish.
70
79
 
71
- ## API Reference
80
+ ## Unified Test Runner
72
81
 
73
- ### testManifestMdx
82
+ ### runAllTests
74
83
 
75
- Tests all MDX files referenced in a manifest's navigation tree.
84
+ Runs all documentation validators on a manifest.
76
85
 
77
86
  ```typescript
78
- async function testManifestMdx(
87
+ async function runAllTests(
79
88
  manifest: DocsPackageManifest,
80
- options?: TestManifestOptions,
81
- ): Promise<MdxTestReport>
89
+ options?: TestRunnerOptions,
90
+ ): Promise<TestRunnerReport>
82
91
  ```
83
92
 
84
93
  **Parameters:**
@@ -88,6 +97,175 @@ async function testManifestMdx(
88
97
 
89
98
  **Options:**
90
99
 
100
+ | Option | Type | Default | Description |
101
+ | --------------- | ----------------------------------------- | ------- | ---------------------------------------------------- |
102
+ | `verbose` | `boolean` | `false` | Show details for all files, not just failures |
103
+ | `failFast` | `boolean` | `false` | Stop on first error in any validator |
104
+ | `exit` | `boolean` | `true` | Auto-exit process with appropriate code |
105
+ | `silent` | `boolean` | `false` | Suppress all console output |
106
+ | `frontmatter` | `boolean \| ValidateFrontmatterOptions` | `true` | Frontmatter validation options, or `false` to skip |
107
+ | `admonitions` | `boolean \| ValidateAdmonitionsOptions` | `true` | Admonition validation options, or `false` to skip |
108
+ | `codeLanguages` | `boolean \| ValidateCodeLanguagesOptions` | `true` | Code language validation options, or `false` to skip |
109
+ | `mdx` | `boolean \| TestManifestOptions` | `true` | MDX compilation options, or `false` to skip |
110
+
111
+ **Example with options:**
112
+
113
+ ```typescript
114
+ import { manifest } from '../src/manifest'
115
+ import { runAllTests } from '@vendure-io/docs-provider/testing'
116
+
117
+ // Skip frontmatter validation, enable verbose output
118
+ runAllTests(manifest, {
119
+ verbose: true,
120
+ frontmatter: false,
121
+ })
122
+ ```
123
+
124
+ **Example for programmatic use:**
125
+
126
+ ```typescript
127
+ import { manifest } from '../src/manifest'
128
+ import { runAllTests } from '@vendure-io/docs-provider/testing'
129
+
130
+ async function main() {
131
+ const report = await runAllTests(manifest, {
132
+ exit: false, // Don't auto-exit, we want the report
133
+ silent: true, // Suppress default output
134
+ })
135
+
136
+ // Custom handling
137
+ if (!report.success) {
138
+ console.error(`Found ${report.totalErrors} errors`)
139
+ // Do something with report.frontmatter, report.admonitions, etc.
140
+ }
141
+ }
142
+
143
+ main()
144
+ ```
145
+
146
+ **Example output:**
147
+
148
+ ```
149
+ Documentation Test Report: my-plugin
150
+ ============================================================
151
+
152
+ Summary
153
+ ------------------------------------------------------------
154
+ ✓ Frontmatter OK (25 files)
155
+ ✓ Admonitions OK (25 files)
156
+ ✗ Code Languages 2 errors (142 blocks)
157
+ ✓ MDX Compilation 25/25 passed (25 files)
158
+
159
+ Total errors: 2
160
+ Total time: 156.32ms
161
+
162
+ Details
163
+ ------------------------------------------------------------
164
+
165
+ Code Language Validation:
166
+ Language 'env' - Use 'dotenv' instead of 'env'
167
+ - docs/configuration.mdx:15
168
+ - docs/deployment.mdx:42
169
+
170
+ ✗ 2 errors found.
171
+ ```
172
+
173
+ ### TestRunnerReport
174
+
175
+ ```typescript
176
+ interface TestRunnerReport {
177
+ /** Package ID from the manifest */
178
+ packageId: string
179
+ /** Frontmatter validation report (if run) */
180
+ frontmatter?: FrontmatterValidationReport
181
+ /** Admonition validation report (if run) */
182
+ admonitions?: AdmonitionValidationReport
183
+ /** Code language validation report (if run) */
184
+ codeLanguages?: CodeLanguageValidationReport
185
+ /** MDX compilation report (if run) */
186
+ mdx?: MdxTestReport
187
+ /** Total number of errors across all validators */
188
+ totalErrors: number
189
+ /** Total time taken in milliseconds */
190
+ totalTime: number
191
+ /** Whether all validations passed */
192
+ success: boolean
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Individual Validators
199
+
200
+ For fine-grained control, you can run validators individually.
201
+
202
+ ### Frontmatter Validation
203
+
204
+ Validates that all MDX files have valid frontmatter according to the DocPageMeta schema.
205
+
206
+ ```typescript
207
+ import { manifest } from './src/manifest'
208
+ import { validateFrontmatter, formatFrontmatterReport } from '@vendure-io/docs-provider/testing'
209
+
210
+ const report = validateFrontmatter(manifest)
211
+
212
+ if (report.errors.length > 0) {
213
+ console.error(formatFrontmatterReport(report))
214
+ process.exit(1)
215
+ }
216
+ ```
217
+
218
+ **Options:**
219
+
220
+ | Option | Type | Default | Description |
221
+ | ---------- | ---------- | ----------- | ----------------------------- |
222
+ | `failFast` | `boolean` | `false` | Stop on first error |
223
+ | `onError` | `Function` | `undefined` | Callback for each error found |
224
+
225
+ **Example output:**
226
+
227
+ ```
228
+ Frontmatter Validation Report: my-plugin
229
+ ==================================================
230
+
231
+ Files scanned: 25
232
+ Errors found: 2
233
+ Total time: 12.45ms
234
+
235
+ Errors:
236
+ --------------------------------------------------
237
+
238
+ docs/getting-started.mdx
239
+ - title: Page title is required
240
+
241
+ docs/advanced.mdx
242
+ - lastModified: Invalid datetime
243
+
244
+ Frontmatter requirements:
245
+ - title: Required, non-empty string
246
+ - description: Optional string
247
+ - keywords: Optional array of strings
248
+ - sidebarLabel: Optional string
249
+ - hidden: Optional boolean
250
+ - order: Optional integer
251
+ - lastModified: Optional ISO 8601 datetime
252
+ ```
253
+
254
+ ### MDX Compilation Testing
255
+
256
+ #### testManifestMdx
257
+
258
+ Tests all MDX files referenced in a manifest's navigation tree.
259
+
260
+ ```typescript
261
+ async function testManifestMdx(
262
+ manifest: DocsPackageManifest,
263
+ options?: TestManifestOptions,
264
+ ): Promise<MdxTestReport>
265
+ ```
266
+
267
+ **Options:**
268
+
91
269
  | Option | Type | Default | Description |
92
270
  | --------------- | --------------- | --------------- | --------------------- |
93
271
  | `failFast` | `boolean` | `false` | Stop on first failure |
@@ -98,15 +276,19 @@ async function testManifestMdx(
98
276
  **Example with progress reporting:**
99
277
 
100
278
  ```typescript
279
+ import { testManifestMdx, formatTestReport } from '@vendure-io/docs-provider/testing'
280
+
101
281
  const report = await testManifestMdx(manifest, {
102
282
  onProgress: (current, total, result) => {
103
283
  const status = result.success ? '✓' : '✗'
104
284
  console.log(`[${current}/${total}] ${status} ${result.filePath}`)
105
285
  },
106
286
  })
287
+
288
+ console.log(formatTestReport(report))
107
289
  ```
108
290
 
109
- ### compileMdx
291
+ #### compileMdx
110
292
 
111
293
  Compiles a single MDX string and returns the result.
112
294
 
@@ -142,106 +324,136 @@ if (result.success) {
142
324
  }
143
325
  ```
144
326
 
145
- ### formatTestReport
327
+ #### createProgressReporter
146
328
 
147
- Formats a test report for console output.
329
+ Creates a simple progress reporter for console output.
148
330
 
149
331
  ```typescript
150
- function formatTestReport(report: MdxTestReport, verbose?: boolean): string
332
+ import { testManifestMdx, createProgressReporter } from '@vendure-io/docs-provider/testing'
333
+
334
+ const report = await testManifestMdx(manifest, {
335
+ onProgress: createProgressReporter(),
336
+ })
151
337
  ```
152
338
 
153
- **Parameters:**
339
+ #### getDefaultRemarkPlugins / getDefaultRehypePlugins
154
340
 
155
- - `report` - The test report to format
156
- - `verbose` - If `true`, shows all results. If `false`, only shows failures.
341
+ Get the default plugins used for MDX compilation. Useful for extending the plugin list.
157
342
 
158
- **Example output (verbose):**
343
+ ```typescript
344
+ import {
345
+ testManifestMdx,
346
+ getDefaultRemarkPlugins,
347
+ getDefaultRehypePlugins,
348
+ } from '@vendure-io/docs-provider/testing'
349
+ import myCustomPlugin from './my-plugin'
159
350
 
351
+ const report = await testManifestMdx(manifest, {
352
+ remarkPlugins: [...getDefaultRemarkPlugins(), myCustomPlugin],
353
+ rehypePlugins: getDefaultRehypePlugins(),
354
+ })
160
355
  ```
161
- MDX Compilation Report: my-plugin
162
- ==================================================
163
356
 
164
- Total files: 5
165
- Passed: 4 (80.0%)
166
- Failed: 1
167
- Total time: 156.32ms
357
+ ---
168
358
 
169
- Results:
170
- --------------------------------------------------
171
- [PASS] docs/getting-started.mdx (45.21ms)
172
- [PASS] docs/installation.mdx (32.11ms)
173
- [PASS] docs/configuration.mdx (28.54ms)
174
- [PASS] docs/api-reference.mdx (35.67ms)
175
- [FAIL] docs/advanced.mdx (14.79ms)
176
- Error (line 42:15): Unexpected token
359
+ ## Types Reference
177
360
 
178
- 1 file(s) failed to compile.
179
- ```
361
+ ### TestRunnerReport
180
362
 
181
- ### createProgressReporter
363
+ ```typescript
364
+ interface TestRunnerReport {
365
+ packageId: string
366
+ frontmatter?: FrontmatterValidationReport
367
+ admonitions?: AdmonitionValidationReport
368
+ codeLanguages?: CodeLanguageValidationReport
369
+ mdx?: MdxTestReport
370
+ totalErrors: number
371
+ totalTime: number
372
+ success: boolean
373
+ }
374
+ ```
182
375
 
183
- Creates a simple progress reporter for console output.
376
+ ### FrontmatterError
184
377
 
185
378
  ```typescript
186
- function createProgressReporter(): (
187
- current: number,
188
- total: number,
189
- result: MdxCompilationResult,
190
- ) => void
379
+ interface FrontmatterError {
380
+ file: string
381
+ absolutePath: string
382
+ issues: string[] // Zod validation issues
383
+ }
191
384
  ```
192
385
 
193
- **Example:**
386
+ ### FrontmatterValidationReport
194
387
 
195
388
  ```typescript
196
- import { testManifestMdx, createProgressReporter } from '@vendure-io/docs-provider/testing'
197
-
198
- const report = await testManifestMdx(manifest, {
199
- onProgress: createProgressReporter(),
200
- })
389
+ interface FrontmatterValidationReport {
390
+ packageId: string
391
+ filesScanned: number
392
+ errors: FrontmatterError[]
393
+ totalTime: number
394
+ }
201
395
  ```
202
396
 
203
- ### getDefaultRemarkPlugins / getDefaultRehypePlugins
204
-
205
- Get the default plugins used for MDX compilation. Useful for extending the plugin list.
397
+ ### AdmonitionError
206
398
 
207
399
  ```typescript
208
- function getDefaultRemarkPlugins(): PluggableList
209
- function getDefaultRehypePlugins(): PluggableList
400
+ interface AdmonitionError {
401
+ file: string
402
+ absolutePath: string
403
+ line: number
404
+ column: number
405
+ content: string
406
+ admonitionType: string
407
+ label: string
408
+ suggestion: string
409
+ }
210
410
  ```
211
411
 
212
- **Example (extending plugins):**
412
+ ### AdmonitionValidationReport
213
413
 
214
414
  ```typescript
215
- import {
216
- testManifestMdx,
217
- getDefaultRemarkPlugins,
218
- getDefaultRehypePlugins,
219
- } from '@vendure-io/docs-provider/testing'
220
- import myCustomPlugin from './my-plugin'
415
+ interface AdmonitionValidationReport {
416
+ packageId: string
417
+ filesScanned: number
418
+ errors: AdmonitionError[]
419
+ totalTime: number
420
+ }
421
+ ```
221
422
 
222
- const report = await testManifestMdx(manifest, {
223
- remarkPlugins: [...getDefaultRemarkPlugins(), myCustomPlugin],
224
- rehypePlugins: getDefaultRehypePlugins(),
225
- })
423
+ ### CodeLanguageError
424
+
425
+ ```typescript
426
+ interface CodeLanguageError {
427
+ file: string
428
+ absolutePath: string
429
+ line: number
430
+ language: string
431
+ content: string
432
+ suggestion?: string
433
+ }
226
434
  ```
227
435
 
228
- ## Types
436
+ ### CodeLanguageValidationReport
437
+
438
+ ```typescript
439
+ interface CodeLanguageValidationReport {
440
+ packageId: string
441
+ filesScanned: number
442
+ codeBlocksFound: number
443
+ errors: CodeLanguageError[]
444
+ totalTime: number
445
+ }
446
+ ```
229
447
 
230
448
  ### MdxCompilationResult
231
449
 
232
450
  ```typescript
233
451
  interface MdxCompilationResult {
234
- /** Path to the MDX file that was compiled */
235
452
  filePath: string
236
- /** Whether compilation was successful */
237
453
  success: boolean
238
- /** Error message if compilation failed */
239
454
  error?: string
240
- /** Line number where the error occurred */
241
455
  line?: number
242
- /** Column number where the error occurred */
243
456
  column?: number
244
- /** Time taken to compile in milliseconds */
245
457
  compilationTime: number
246
458
  }
247
459
  ```
@@ -250,40 +462,74 @@ interface MdxCompilationResult {
250
462
 
251
463
  ```typescript
252
464
  interface MdxTestReport {
253
- /** Package ID from the manifest */
254
465
  packageId: string
255
- /** Total number of MDX files tested */
256
466
  totalFiles: number
257
- /** Number of files that compiled successfully */
258
467
  passed: number
259
- /** Number of files that failed to compile */
260
468
  failed: number
261
- /** Individual results for each file */
262
469
  results: MdxCompilationResult[]
263
- /** Total time taken in milliseconds */
264
470
  totalTime: number
265
471
  }
266
472
  ```
267
473
 
474
+ ---
475
+
268
476
  ## Integration with Vitest
269
477
 
270
- You can integrate MDX testing into your existing test suite:
478
+ You can integrate documentation testing into your existing test suite:
271
479
 
272
480
  ```typescript
273
- // tests/mdx-compilation.test.ts
481
+ // tests/docs-validation.test.ts
274
482
  import { describe, it, expect } from 'vitest'
275
483
  import { manifest } from '../src/manifest'
276
- import { testManifestMdx } from '@vendure-io/docs-provider/testing'
484
+ import { runAllTests } from '@vendure-io/docs-provider/testing'
277
485
 
278
- describe('MDX Compilation', () => {
279
- it('should compile all MDX files without errors', async () => {
280
- const report = await testManifestMdx(manifest)
486
+ describe('Documentation Validation', () => {
487
+ it('should pass all documentation tests', async () => {
488
+ const report = await runAllTests(manifest, {
489
+ exit: false,
490
+ silent: true,
491
+ })
281
492
 
282
- expect(report.failed).toBe(0)
493
+ expect(report.success).toBe(true)
283
494
  }, 30000) // Increase timeout for large doc sets
284
495
  })
285
496
  ```
286
497
 
498
+ Or test individual validators:
499
+
500
+ ```typescript
501
+ import { describe, it, expect } from 'vitest'
502
+ import { manifest } from '../src/manifest'
503
+ import {
504
+ validateFrontmatter,
505
+ validateAdmonitions,
506
+ validateCodeLanguages,
507
+ testManifestMdx,
508
+ } from '@vendure-io/docs-provider/testing'
509
+
510
+ describe('Documentation Validation', () => {
511
+ it('should have valid frontmatter', () => {
512
+ const report = validateFrontmatter(manifest)
513
+ expect(report.errors).toHaveLength(0)
514
+ })
515
+
516
+ it('should use correct admonition syntax', () => {
517
+ const report = validateAdmonitions(manifest)
518
+ expect(report.errors).toHaveLength(0)
519
+ })
520
+
521
+ it('should use valid code languages', () => {
522
+ const report = validateCodeLanguages(manifest)
523
+ expect(report.errors).toHaveLength(0)
524
+ })
525
+
526
+ it('should compile all MDX files', async () => {
527
+ const report = await testManifestMdx(manifest)
528
+ expect(report.failed).toBe(0)
529
+ }, 30000)
530
+ })
531
+ ```
532
+
287
533
  ## Supported MDX Features
288
534
 
289
535
  The testing module uses the same remark/rehype plugins as the Vendure documentation website:
@@ -295,7 +541,7 @@ The testing module uses the same remark/rehype plugins as the Vendure documentat
295
541
  This is an info callout.
296
542
  :::
297
543
 
298
- :::warning Custom Title
544
+ :::warning[Custom Title]
299
545
  This is a warning with a custom title.
300
546
  :::
301
547
  ```
@@ -329,8 +575,148 @@ export function example() {
329
575
  </Callout>
330
576
  ````
331
577
 
578
+ ### Admonition Validation
579
+
580
+ Validates that admonitions use the correct bracket syntax required by remark-directive v4+.
581
+
582
+ ```typescript
583
+ import { manifest } from './src/manifest'
584
+ import { validateAdmonitions, formatAdmonitionReport } from '@vendure-io/docs-provider/testing'
585
+
586
+ const report = validateAdmonitions(manifest)
587
+
588
+ if (report.errors.length > 0) {
589
+ console.error(formatAdmonitionReport(report))
590
+ process.exit(1)
591
+ }
592
+ ```
593
+
594
+ **Valid syntax:**
595
+
596
+ ```mdx
597
+ :::warning[Deprecated]
598
+ This feature is deprecated.
599
+ :::
600
+ ```
601
+
602
+ **Invalid syntax (caught by validator):**
603
+
604
+ ```mdx
605
+ :::warning Deprecated
606
+ This feature is deprecated.
607
+ :::
608
+ ```
609
+
610
+ ### Code Language Validation
611
+
612
+ Validates that code blocks use supported Shiki language identifiers.
613
+
614
+ ```typescript
615
+ import { manifest } from './src/manifest'
616
+ import { validateCodeLanguages, formatCodeLanguageReport } from '@vendure-io/docs-provider/testing'
617
+
618
+ const report = validateCodeLanguages(manifest)
619
+
620
+ if (report.errors.length > 0) {
621
+ console.error(formatCodeLanguageReport(report))
622
+ process.exit(1)
623
+ }
624
+ ```
625
+
626
+ **Options:**
627
+
628
+ | Option | Type | Default | Description |
629
+ | --------------------- | ------------------------ | ----------- | --------------------------------- |
630
+ | `failFast` | `boolean` | `false` | Stop on first error |
631
+ | `onError` | `Function` | `undefined` | Callback for each error found |
632
+ | `additionalAliases` | `Record<string, string>` | `{}` | Extra aliases to consider valid |
633
+ | `additionalLanguages` | `string[]` | `[]` | Extra languages to consider valid |
634
+
635
+ #### Utility Functions
636
+
637
+ **isValidCodeLanguage** - Check if a language identifier is valid:
638
+
639
+ ```typescript
640
+ import { isValidCodeLanguage } from '@vendure-io/docs-provider/testing'
641
+
642
+ isValidCodeLanguage('typescript') // true
643
+ isValidCodeLanguage('ts') // true (alias)
644
+ isValidCodeLanguage('env') // true (maps to 'dotenv')
645
+ isValidCodeLanguage('foobar') // false
646
+ ```
647
+
648
+ **getCanonicalLanguage** - Get the canonical Shiki language name:
649
+
650
+ ```typescript
651
+ import { getCanonicalLanguage } from '@vendure-io/docs-provider/testing'
652
+
653
+ getCanonicalLanguage('env') // 'dotenv'
654
+ getCanonicalLanguage('text') // 'ini'
655
+ getCanonicalLanguage('terminal') // 'shellscript'
656
+ ```
657
+
658
+ #### Common Language Issues
659
+
660
+ | Invalid | Use Instead | Notes |
661
+ | ----------- | ----------- | ---------------------------- |
662
+ | `env` | `dotenv` | For `.env` files |
663
+ | `text` | (none) | Remove language or use `ini` |
664
+ | `plaintext` | (none) | Remove language or use `ini` |
665
+ | `terminal` | `bash` | Or `shell`, `sh`, `zsh` |
666
+
667
+ #### Supported Languages
668
+
669
+ The validator includes all 328 languages bundled with Shiki v3.22+. Common languages include:
670
+
671
+ - **Web**: `html`, `css`, `javascript`, `typescript`, `jsx`, `tsx`, `json`, `yaml`
672
+ - **Backend**: `python`, `ruby`, `php`, `java`, `go`, `rust`, `csharp`
673
+ - **Shell**: `bash`, `shell`, `sh`, `zsh`, `powershell`
674
+ - **Config**: `ini`, `toml`, `dotenv`, `nginx`, `docker`
675
+ - **Data**: `sql`, `graphql`, `xml`, `csv`
676
+ - **Markup**: `markdown`, `mdx`, `latex`
677
+
678
+ See the full list at [shiki.style/languages](https://shiki.style/languages)
679
+
680
+ ---
681
+
332
682
  ## Common Errors
333
683
 
684
+ ### Missing or Invalid Frontmatter
685
+
686
+ The frontmatter validator catches:
687
+
688
+ - Missing `title` field (required)
689
+ - Invalid `lastModified` format (must be ISO 8601)
690
+ - Wrong types (e.g., `keywords` as string instead of array)
691
+
692
+ ```mdx
693
+ ---
694
+ title: My Page Title
695
+ description: Optional description
696
+ keywords:
697
+ - keyword1
698
+ - keyword2
699
+ ---
700
+
701
+ # Content
702
+ ```
703
+
704
+ ### Invalid Admonition Syntax
705
+
706
+ ```
707
+ :::warning Deprecated
708
+ ```
709
+
710
+ Must use bracket syntax:
711
+
712
+ ```
713
+ :::warning[Deprecated]
714
+ ```
715
+
716
+ ### Unsupported Code Language
717
+
718
+ Using `env` instead of `dotenv`, or `terminal` instead of `bash`.
719
+
334
720
  ### Unclosed JSX Tags
335
721
 
336
722
  ```
@@ -362,56 +748,46 @@ Check for:
362
748
  - Unescaped special characters (`<`, `>`, `{`, `}`)
363
749
  - JavaScript expressions not wrapped in curly braces
364
750
 
365
- ### Missing Frontmatter
366
-
367
- While the MDX compiler doesn't require frontmatter, the docs website does. Ensure all files have at least a `title`:
368
-
369
- ```mdx
370
- ---
371
- title: My Page Title
372
751
  ---
373
752
 
374
- # Content
375
- ```
376
-
377
753
  ## Best Practices
378
754
 
379
- 1. **Run tests before commits**: Add MDX testing to your pre-commit hooks
380
- 2. **Use CI/CD**: Include MDX testing in your continuous integration pipeline
381
- 3. **Test incrementally**: Use `failFast: true` during development for faster feedback
382
- 4. **Verbose output for debugging**: Use `formatTestReport(report, true)` when troubleshooting
755
+ 1. **Use `runAllTests()` as your default** - It runs all validators and handles exit codes automatically
756
+ 2. **Run tests before commits** - Add documentation testing to your pre-commit hooks
757
+ 3. **Use CI/CD** - Include documentation testing in your continuous integration pipeline
758
+ 4. **Test incrementally** - Use `failFast: true` during development for faster feedback
759
+ 5. **Verbose output for debugging** - Use `verbose: true` when troubleshooting
383
760
 
384
- ## Example: Complete Test Script
761
+ ---
385
762
 
386
- Here's a complete test script with all features:
763
+ ## Complete Examples
764
+
765
+ ### Minimal Test Script (Recommended)
387
766
 
388
767
  ```typescript
389
- // scripts/test-mdx.ts
768
+ // scripts/test-docs.ts
390
769
  import { manifest } from '../src/manifest'
391
- import {
392
- testManifestMdx,
393
- formatTestReport,
394
- createProgressReporter,
395
- } from '@vendure-io/docs-provider/testing'
770
+ import { runAllTests } from '@vendure-io/docs-provider/testing'
396
771
 
397
- async function main() {
398
- console.log('Testing MDX files...\n')
772
+ runAllTests(manifest)
773
+ ```
399
774
 
400
- const report = await testManifestMdx(manifest, {
401
- onProgress: createProgressReporter(),
402
- })
775
+ Run with:
403
776
 
404
- console.log('\n')
405
- console.log(formatTestReport(report, process.argv.includes('--verbose')))
777
+ ```bash
778
+ bun run scripts/test-docs.ts
779
+ ```
406
780
 
407
- if (report.failed > 0) {
408
- process.exit(1)
409
- }
410
- }
781
+ ### With Options
411
782
 
412
- main().catch((error) => {
413
- console.error('Test runner error:', error)
414
- process.exit(1)
783
+ ```typescript
784
+ // scripts/test-docs.ts
785
+ import { manifest } from '../src/manifest'
786
+ import { runAllTests } from '@vendure-io/docs-provider/testing'
787
+
788
+ runAllTests(manifest, {
789
+ verbose: process.argv.includes('--verbose'),
790
+ failFast: process.argv.includes('--fail-fast'),
415
791
  })
416
792
  ```
417
793
 
@@ -419,8 +795,45 @@ Run with:
419
795
 
420
796
  ```bash
421
797
  # Standard output
422
- bun run scripts/test-mdx.ts
798
+ bun run scripts/test-docs.ts
423
799
 
424
800
  # Verbose output showing all results
425
- bun run scripts/test-mdx.ts --verbose
801
+ bun run scripts/test-docs.ts --verbose
802
+
803
+ # Stop on first error
804
+ bun run scripts/test-docs.ts --fail-fast
805
+ ```
806
+
807
+ ### Programmatic Usage
808
+
809
+ ```typescript
810
+ // scripts/test-docs.ts
811
+ import { manifest } from '../src/manifest'
812
+ import { runAllTests, formatTestRunnerReport } from '@vendure-io/docs-provider/testing'
813
+
814
+ async function main() {
815
+ const report = await runAllTests(manifest, {
816
+ exit: false,
817
+ silent: true,
818
+ })
819
+
820
+ // Custom output
821
+ console.log(formatTestRunnerReport(report, true))
822
+
823
+ // Custom error handling
824
+ if (!report.success) {
825
+ console.error(`\nFailed with ${report.totalErrors} errors`)
826
+
827
+ if (report.frontmatter?.errors.length) {
828
+ console.error(`- ${report.frontmatter.errors.length} frontmatter errors`)
829
+ }
830
+ if (report.mdx?.failed) {
831
+ console.error(`- ${report.mdx.failed} MDX compilation errors`)
832
+ }
833
+
834
+ process.exit(1)
835
+ }
836
+ }
837
+
838
+ main()
426
839
  ```