@alliance-droid/svelte-docs-system 0.0.1

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 (134) hide show
  1. package/COMPONENTS.md +365 -0
  2. package/COVERAGE_REPORT.md +663 -0
  3. package/README.md +42 -0
  4. package/SEARCH_VERIFICATION.md +229 -0
  5. package/TEST_SUMMARY.md +344 -0
  6. package/bin/init.js +821 -0
  7. package/docs/E2E_TESTS.md +354 -0
  8. package/docs/TESTING.md +754 -0
  9. package/docs/de/index.md +41 -0
  10. package/docs/en/COMPONENTS.md +443 -0
  11. package/docs/en/api/examples.md +100 -0
  12. package/docs/en/api/overview.md +69 -0
  13. package/docs/en/components/index.md +622 -0
  14. package/docs/en/config/navigation.md +505 -0
  15. package/docs/en/config/theme-and-colors.md +395 -0
  16. package/docs/en/getting-started/integration.md +406 -0
  17. package/docs/en/guides/common-setups.md +651 -0
  18. package/docs/en/index.md +243 -0
  19. package/docs/en/markdown.md +102 -0
  20. package/docs/en/routing.md +64 -0
  21. package/docs/en/setup.md +52 -0
  22. package/docs/en/troubleshooting.md +704 -0
  23. package/docs/es/index.md +41 -0
  24. package/docs/fr/index.md +41 -0
  25. package/docs/ja/index.md +41 -0
  26. package/package.json +40 -0
  27. package/pagefind.toml +8 -0
  28. package/postcss.config.js +5 -0
  29. package/src/app.css +119 -0
  30. package/src/app.d.ts +13 -0
  31. package/src/app.html +11 -0
  32. package/src/lib/assets/favicon.svg +1 -0
  33. package/src/lib/components/APITable.svelte +120 -0
  34. package/src/lib/components/APITable.test.ts +153 -0
  35. package/src/lib/components/Breadcrumbs.svelte +85 -0
  36. package/src/lib/components/Breadcrumbs.test.ts +148 -0
  37. package/src/lib/components/Callout.svelte +60 -0
  38. package/src/lib/components/Callout.test.ts +100 -0
  39. package/src/lib/components/CodeBlock.svelte +68 -0
  40. package/src/lib/components/CodeBlock.test.ts +133 -0
  41. package/src/lib/components/DocLayout.svelte +84 -0
  42. package/src/lib/components/Footer.svelte +78 -0
  43. package/src/lib/components/Image.svelte +100 -0
  44. package/src/lib/components/Image.test.ts +163 -0
  45. package/src/lib/components/Navbar.svelte +141 -0
  46. package/src/lib/components/Search.svelte +248 -0
  47. package/src/lib/components/Sidebar.svelte +110 -0
  48. package/src/lib/components/Tabs.svelte +48 -0
  49. package/src/lib/components/Tabs.test.ts +102 -0
  50. package/src/lib/config.test.ts +140 -0
  51. package/src/lib/config.ts +179 -0
  52. package/src/lib/configIntegration.test.ts +272 -0
  53. package/src/lib/configLoader.ts +231 -0
  54. package/src/lib/configParser.test.ts +217 -0
  55. package/src/lib/configParser.ts +234 -0
  56. package/src/lib/index.ts +34 -0
  57. package/src/lib/integration.test.ts +426 -0
  58. package/src/lib/navigationBuilder.test.ts +338 -0
  59. package/src/lib/navigationBuilder.ts +268 -0
  60. package/src/lib/performance.test.ts +369 -0
  61. package/src/lib/routing.test.ts +202 -0
  62. package/src/lib/routing.ts +127 -0
  63. package/src/lib/search-functionality.test.ts +493 -0
  64. package/src/lib/stores/i18n.test.ts +180 -0
  65. package/src/lib/stores/i18n.ts +143 -0
  66. package/src/lib/stores/nav.ts +36 -0
  67. package/src/lib/stores/search.test.ts +140 -0
  68. package/src/lib/stores/search.ts +162 -0
  69. package/src/lib/stores/theme.ts +59 -0
  70. package/src/lib/stores/version.test.ts +139 -0
  71. package/src/lib/stores/version.ts +111 -0
  72. package/src/lib/themeCustomization.test.ts +223 -0
  73. package/src/lib/themeCustomization.ts +212 -0
  74. package/src/lib/utils/highlight.test.ts +136 -0
  75. package/src/lib/utils/highlight.ts +100 -0
  76. package/src/lib/utils/index.ts +7 -0
  77. package/src/lib/utils/markdown.test.ts +357 -0
  78. package/src/lib/utils/markdown.ts +77 -0
  79. package/src/routes/+layout.server.ts +1 -0
  80. package/src/routes/+layout.svelte +28 -0
  81. package/src/routes/+page.svelte +165 -0
  82. package/static/robots.txt +3 -0
  83. package/svelte.config.js +18 -0
  84. package/tailwind.config.ts +55 -0
  85. package/template-starter/.github/workflows/build.yml +40 -0
  86. package/template-starter/.github/workflows/deploy-github-pages.yml +47 -0
  87. package/template-starter/.github/workflows/deploy-netlify.yml +41 -0
  88. package/template-starter/.github/workflows/deploy-vercel.yml +64 -0
  89. package/template-starter/NPM-PACKAGE-SETUP.md +233 -0
  90. package/template-starter/README.md +320 -0
  91. package/template-starter/docs/_config.json +39 -0
  92. package/template-starter/docs/api/components.md +257 -0
  93. package/template-starter/docs/api/overview.md +169 -0
  94. package/template-starter/docs/guides/configuration.md +145 -0
  95. package/template-starter/docs/guides/github-pages-deployment.md +254 -0
  96. package/template-starter/docs/guides/netlify-deployment.md +159 -0
  97. package/template-starter/docs/guides/vercel-deployment.md +131 -0
  98. package/template-starter/docs/index.md +49 -0
  99. package/template-starter/docs/setup.md +149 -0
  100. package/template-starter/package.json +31 -0
  101. package/template-starter/pagefind.toml +3 -0
  102. package/template-starter/postcss.config.js +5 -0
  103. package/template-starter/src/app.css +34 -0
  104. package/template-starter/src/app.d.ts +13 -0
  105. package/template-starter/src/app.html +11 -0
  106. package/template-starter/src/lib/components/APITable.svelte +120 -0
  107. package/template-starter/src/lib/components/APITable.test.ts +19 -0
  108. package/template-starter/src/lib/components/Breadcrumbs.svelte +85 -0
  109. package/template-starter/src/lib/components/Breadcrumbs.test.ts +19 -0
  110. package/template-starter/src/lib/components/Callout.svelte +60 -0
  111. package/template-starter/src/lib/components/Callout.test.ts +16 -0
  112. package/template-starter/src/lib/components/CodeBlock.svelte +68 -0
  113. package/template-starter/src/lib/components/CodeBlock.test.ts +12 -0
  114. package/template-starter/src/lib/components/DocLayout.svelte +84 -0
  115. package/template-starter/src/lib/components/Footer.svelte +78 -0
  116. package/template-starter/src/lib/components/Image.svelte +100 -0
  117. package/template-starter/src/lib/components/Image.test.ts +15 -0
  118. package/template-starter/src/lib/components/Navbar.svelte +141 -0
  119. package/template-starter/src/lib/components/Search.svelte +248 -0
  120. package/template-starter/src/lib/components/Sidebar.svelte +110 -0
  121. package/template-starter/src/lib/components/Tabs.svelte +48 -0
  122. package/template-starter/src/lib/components/Tabs.test.ts +17 -0
  123. package/template-starter/src/lib/index.ts +15 -0
  124. package/template-starter/src/routes/+layout.svelte +28 -0
  125. package/template-starter/src/routes/+page.svelte +92 -0
  126. package/template-starter/svelte.config.js +17 -0
  127. package/template-starter/tailwind.config.ts +17 -0
  128. package/template-starter/tsconfig.json +13 -0
  129. package/template-starter/vite.config.ts +6 -0
  130. package/tests/e2e/example.spec.ts +345 -0
  131. package/tsconfig.json +20 -0
  132. package/vite.config.ts +6 -0
  133. package/vitest.config.ts +34 -0
  134. package/vitest.setup.ts +21 -0
package/bin/init.js ADDED
@@ -0,0 +1,821 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Initialize docs system in an existing SvelteKit project
5
+ *
6
+ * Usage:
7
+ * npx svelte-docs-system init [--route /docs] [--folder ./docs]
8
+ */
9
+
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import { fileURLToPath } from 'url';
13
+ import { dirname } from 'path';
14
+ import readline from 'readline';
15
+
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const projectRoot = process.cwd();
18
+
19
+ // Colors for console output
20
+ const colors = {
21
+ reset: '\x1b[0m',
22
+ bright: '\x1b[1m',
23
+ green: '\x1b[32m',
24
+ yellow: '\x1b[33m',
25
+ blue: '\x1b[34m',
26
+ red: '\x1b[31m'
27
+ };
28
+
29
+ function log(message, color = 'reset') {
30
+ console.log(`${colors[color]}${message}${colors.reset}`);
31
+ }
32
+
33
+ function error(message) {
34
+ console.error(`${colors.red}✘ Error: ${message}${colors.reset}`);
35
+ process.exit(1);
36
+ }
37
+
38
+ function success(message) {
39
+ log(`✓ ${message}`, 'green');
40
+ }
41
+
42
+ function info(message) {
43
+ log(`ℹ ${message}`, 'blue');
44
+ }
45
+
46
+ function warn(message) {
47
+ log(`⚠ ${message}`, 'yellow');
48
+ }
49
+
50
+ // Create readline interface for prompts
51
+ const rl = readline.createInterface({
52
+ input: process.stdin,
53
+ output: process.stdout
54
+ });
55
+
56
+ function prompt(question) {
57
+ return new Promise((resolve) => {
58
+ rl.question(question, (answer) => {
59
+ resolve(answer);
60
+ });
61
+ });
62
+ }
63
+
64
+ // Simple argument parser
65
+ function parseArgs() {
66
+ const args = process.argv.slice(2);
67
+ const result = {
68
+ route: null,
69
+ folder: null
70
+ };
71
+
72
+ for (let i = 0; i < args.length; i++) {
73
+ if (args[i] === '--route' && args[i + 1]) {
74
+ result.route = args[i + 1];
75
+ i++;
76
+ } else if (args[i] === '--folder' && args[i + 1]) {
77
+ result.folder = args[i + 1];
78
+ i++;
79
+ }
80
+ }
81
+
82
+ return result;
83
+ }
84
+
85
+ async function main() {
86
+ try {
87
+ log('\n🚀 Initializing documentation system...', 'bright');
88
+
89
+ // Check if we're in a SvelteKit project
90
+ const svelteConfigPath = path.join(projectRoot, 'svelte.config.js');
91
+ if (!fs.existsSync(svelteConfigPath)) {
92
+ error('svelte.config.js not found. Please run this in a SvelteKit project root.');
93
+ }
94
+
95
+ // Get config options from args or prompts
96
+ const defaultRoute = '/docs';
97
+ const defaultFolder = './docs';
98
+ const args = parseArgs();
99
+
100
+ let finalRoute, finalFolder;
101
+
102
+ if (args.route && args.folder) {
103
+ // Non-interactive mode
104
+ finalRoute = args.route;
105
+ finalFolder = args.folder;
106
+ info(`Using route: ${finalRoute}`);
107
+ info(`Using folder: ${finalFolder}`);
108
+ } else {
109
+ // Interactive mode
110
+ log('\nConfiguration:', 'bright');
111
+ const docsRoute = await prompt(
112
+ `Enter docs route (default: ${defaultRoute}): `
113
+ );
114
+ finalRoute = docsRoute.trim() || defaultRoute;
115
+
116
+ const docsFolder = await prompt(
117
+ `Enter docs folder path (default: ${defaultFolder}): `
118
+ );
119
+ finalFolder = docsFolder.trim() || defaultFolder;
120
+
121
+ info(`Using route: ${finalRoute}`);
122
+ info(`Using folder: ${finalFolder}`);
123
+ }
124
+
125
+ // Create docs folder structure
126
+ log('\nCreating folder structure...', 'bright');
127
+ const docsFolderPath = path.join(projectRoot, finalFolder);
128
+ const apiFolderPath = path.join(docsFolderPath, 'api');
129
+ const guidesFolderPath = path.join(docsFolderPath, 'guides');
130
+
131
+ // Create directories
132
+ [docsFolderPath, apiFolderPath, guidesFolderPath].forEach((dir) => {
133
+ if (!fs.existsSync(dir)) {
134
+ fs.mkdirSync(dir, { recursive: true });
135
+ success(`Created directory: ${path.relative(projectRoot, dir)}`);
136
+ } else {
137
+ warn(`Directory already exists: ${path.relative(projectRoot, dir)}`);
138
+ }
139
+ });
140
+
141
+ // Create example markdown files
142
+ log('\nCreating example documentation...', 'bright');
143
+ createMarkdownFiles(docsFolderPath, finalRoute);
144
+
145
+ // Create route handlers
146
+ log('\nCreating route handlers...', 'bright');
147
+ createRouteHandlers(projectRoot, finalRoute, finalFolder);
148
+
149
+ // Update svelte.config.js
150
+ log('\nUpdating svelte.config.js...', 'bright');
151
+ updateSvelteConfig(svelteConfigPath, finalRoute, finalFolder);
152
+
153
+ // Create navigation config
154
+ log('\nCreating navigation config...', 'bright');
155
+ createNavConfig(docsFolderPath, finalRoute);
156
+
157
+ log('\n✨ Documentation system initialized!', 'green');
158
+ log(`\nNext steps:`, 'bright');
159
+ log(` 1. Start dev server: npm run dev`);
160
+ log(` 2. Visit: http://localhost:5173${finalRoute}`);
161
+ log(` 3. Edit markdown files in ${finalFolder}/ to customize docs`);
162
+ log(` 4. Edit ${finalFolder}/_config.json to customize navigation\n`);
163
+
164
+ rl.close();
165
+ } catch (err) {
166
+ error(err.message);
167
+ }
168
+ }
169
+
170
+ function createMarkdownFiles(docsFolderPath, docsRoute) {
171
+ const files = {
172
+ 'index.md': `---
173
+ title: Documentation Home
174
+ description: Welcome to your documentation
175
+ author: Your Name
176
+ date: ${new Date().toISOString().split('T')[0]}
177
+ ---
178
+
179
+ # Welcome to Your Documentation
180
+
181
+ This is the home page of your documentation site.
182
+
183
+ ## Getting Started
184
+
185
+ - Check out the [Setup Guide](${docsRoute}/setup) to get started
186
+ - Read the [Architecture Guide](${docsRoute}/guides/architecture) for an overview
187
+ - Visit the [API Reference](${docsRoute}/api/overview) for detailed API docs
188
+
189
+ ## Features
190
+
191
+ - **Automatic routing** from markdown files
192
+ - **Nested paths** support (organize docs in folders)
193
+ - **Frontmatter metadata** (title, author, date)
194
+ - **Professional styling** out of the box
195
+ - **Easy to customize** and extend
196
+
197
+ ## Project Structure
198
+
199
+ \`\`\`
200
+ ${path.basename(docsFolderPath)}/
201
+ ├── index.md (This file)
202
+ ├── setup.md (Getting started)
203
+ ├── api/
204
+ │ ├── overview.md (API overview)
205
+ │ └── reference.md (API reference)
206
+ └── guides/
207
+ ├── architecture.md (Architecture guide)
208
+ └── advanced.md (Advanced topics)
209
+ \`\`\`
210
+
211
+ Each markdown file automatically becomes a route. For example:
212
+ - \`${path.basename(docsFolderPath)}/setup.md\` → \`${docsRoute}/setup\`
213
+ - \`${path.basename(docsFolderPath)}/api/overview.md\` → \`${docsRoute}/api/overview\`
214
+ `,
215
+ 'setup.md': `---
216
+ title: Setup Guide
217
+ description: Get started with your documentation
218
+ author: Your Name
219
+ date: ${new Date().toISOString().split('T')[0]}
220
+ ---
221
+
222
+ # Setup Guide
223
+
224
+ This guide will help you get started with your documentation.
225
+
226
+ ## Prerequisites
227
+
228
+ - Node.js 18 or higher
229
+ - npm, pnpm, or yarn
230
+
231
+ ## Installation
232
+
233
+ If you haven't already, install the dependencies:
234
+
235
+ \`\`\`bash
236
+ npm install
237
+ \`\`\`
238
+
239
+ ## Starting Development
240
+
241
+ Start the development server:
242
+
243
+ \`\`\`bash
244
+ npm run dev
245
+ \`\`\`
246
+
247
+ Visit \`http://localhost:5173\` in your browser.
248
+
249
+ ## Creating Documentation
250
+
251
+ 1. Create new markdown files in the \`docs/\` folder
252
+ 2. Use frontmatter for metadata (title, description, author, date)
253
+ 3. Organize files in folders for nested routing
254
+ 4. Markdown files automatically become routes
255
+
256
+ ### Example
257
+
258
+ Create \`docs/guides/my-guide.md\`:
259
+
260
+ \`\`\`markdown
261
+ ---
262
+ title: My Guide
263
+ description: A guide about something
264
+ ---
265
+
266
+ # My Guide
267
+
268
+ Content goes here...
269
+ \`\`\`
270
+
271
+ This creates a route: \`/docs/guides/my-guide\`
272
+
273
+ ## Customization
274
+
275
+ Edit \`docs/_config.json\` to customize the navigation structure. See the comments in that file for options.
276
+
277
+ ## Next Steps
278
+
279
+ - Read the [API Reference](/docs/api/overview)
280
+ - Explore the [Architecture Guide](/docs/guides/architecture)
281
+ `,
282
+ 'api/overview.md': `---
283
+ title: API Overview
284
+ description: API documentation overview
285
+ author: Your Name
286
+ date: ${new Date().toISOString().split('T')[0]}
287
+ ---
288
+
289
+ # API Overview
290
+
291
+ This page provides an overview of your API.
292
+
293
+ ## Base URL
294
+
295
+ \`\`\`
296
+ https://api.example.com/v1
297
+ \`\`\`
298
+
299
+ ## Authentication
300
+
301
+ Include your API key in the request headers:
302
+
303
+ \`\`\`bash
304
+ curl -H "Authorization: Bearer YOUR_API_KEY" https://api.example.com/v1/...
305
+ \`\`\`
306
+
307
+ ## Response Format
308
+
309
+ All responses are JSON:
310
+
311
+ \`\`\`json
312
+ {
313
+ "success": true,
314
+ "data": { /* ... */ }
315
+ }
316
+ \`\`\`
317
+
318
+ ## Endpoints
319
+
320
+ For detailed endpoint documentation, see the [API Reference](/docs/api/reference).
321
+
322
+ ## Rate Limiting
323
+
324
+ API requests are rate limited to 1000 per hour per API key.
325
+ `,
326
+ 'api/reference.md': `---
327
+ title: API Reference
328
+ description: Complete API reference documentation
329
+ author: Your Name
330
+ date: ${new Date().toISOString().split('T')[0]}
331
+ ---
332
+
333
+ # API Reference
334
+
335
+ Complete documentation of all API endpoints.
336
+
337
+ ## GET /users
338
+
339
+ Retrieve a list of users.
340
+
341
+ ### Parameters
342
+
343
+ | Name | Type | Description |
344
+ |------|------|-------------|
345
+ | page | integer | Page number (default: 1) |
346
+ | limit | integer | Results per page (default: 10) |
347
+
348
+ ### Example
349
+
350
+ \`\`\`bash
351
+ curl https://api.example.com/v1/users?page=1&limit=10
352
+ \`\`\`
353
+
354
+ ### Response
355
+
356
+ \`\`\`json
357
+ {
358
+ "success": true,
359
+ "data": [
360
+ {
361
+ "id": "user_123",
362
+ "name": "John Doe",
363
+ "email": "john@example.com"
364
+ }
365
+ ]
366
+ }
367
+ \`\`\`
368
+
369
+ ## POST /users
370
+
371
+ Create a new user.
372
+
373
+ ### Request Body
374
+
375
+ | Field | Type | Required | Description |
376
+ |-------|------|----------|-------------|
377
+ | name | string | Yes | User's full name |
378
+ | email | string | Yes | User's email address |
379
+
380
+ ### Example
381
+
382
+ \`\`\`bash
383
+ curl -X POST https://api.example.com/v1/users \\
384
+ -H "Content-Type: application/json" \\
385
+ -d '{"name":"Jane Doe","email":"jane@example.com"}'
386
+ \`\`\`
387
+
388
+ ### Response
389
+
390
+ \`\`\`json
391
+ {
392
+ "success": true,
393
+ "data": {
394
+ "id": "user_456",
395
+ "name": "Jane Doe",
396
+ "email": "jane@example.com"
397
+ }
398
+ }
399
+ \`\`\`
400
+ `,
401
+ 'guides/architecture.md': `---
402
+ title: Architecture Guide
403
+ description: Overview of the system architecture
404
+ author: Your Name
405
+ date: ${new Date().toISOString().split('T')[0]}
406
+ ---
407
+
408
+ # Architecture Guide
409
+
410
+ This guide explains the high-level architecture of the system.
411
+
412
+ ## Overview
413
+
414
+ The system is built with modern web technologies:
415
+
416
+ - **Frontend:** SvelteKit with Svelte 5
417
+ - **Styling:** Tailwind CSS
418
+ - **Build Tool:** Vite
419
+ - **Documentation:** This markdown-based system
420
+
421
+ ## Components
422
+
423
+ ### Documentation System
424
+
425
+ The documentation system automatically:
426
+
427
+ - Converts markdown files to web pages
428
+ - Generates navigation from folder structure
429
+ - Provides search functionality
430
+ - Handles dark mode and responsive design
431
+
432
+ ### Adding Custom Components
433
+
434
+ You can add custom Svelte components to your markdown files by extending the markdown processor.
435
+
436
+ ## Data Flow
437
+
438
+ \`\`\`
439
+ User navigates to /docs/page
440
+
441
+ SvelteKit router matches route
442
+
443
+ Page loader fetches markdown file
444
+
445
+ Markdown is parsed and converted to HTML
446
+
447
+ Components are rendered with Svelte
448
+
449
+ Page is displayed in browser
450
+ \`\`\`
451
+
452
+ ## Performance
453
+
454
+ - Static file serving for fast load times
455
+ - Optimized image delivery
456
+ - Minimal JavaScript by default
457
+ - Full-text search via Pagefind
458
+
459
+ ## Customization
460
+
461
+ All components can be customized by:
462
+
463
+ 1. Overriding styles via Tailwind CSS
464
+ 2. Creating custom Svelte components
465
+ 3. Modifying the layout templates
466
+
467
+ See the configuration guide for more details.
468
+ `,
469
+ 'guides/advanced.md': `---
470
+ title: Advanced Topics
471
+ description: Advanced usage and customization
472
+ author: Your Name
473
+ date: ${new Date().toISOString().split('T')[0]}
474
+ ---
475
+
476
+ # Advanced Topics
477
+
478
+ This guide covers advanced usage and customization topics.
479
+
480
+ ## Custom Components in Markdown
481
+
482
+ Create reusable components for your documentation:
483
+
484
+ \`\`\`svelte
485
+ <script>
486
+ export let type = 'info';
487
+ </script>
488
+
489
+ <div class="custom-component {type}">
490
+ <slot />
491
+ </div>
492
+ \`\`\`
493
+
494
+ Then use them in markdown:
495
+
496
+ \`\`\`markdown
497
+ <CustomComponent type="warning">
498
+ This is important!
499
+ </CustomComponent>
500
+ \`\`\`
501
+
502
+ ## Extending the Theme
503
+
504
+ Customize the theme by:
505
+
506
+ 1. Modifying Tailwind CSS configuration
507
+ 2. Overriding component styles
508
+ 3. Creating custom layout templates
509
+
510
+ ## SEO Optimization
511
+
512
+ Each markdown file supports frontmatter metadata:
513
+
514
+ - \`title\` - Page title (shown in browser tab)
515
+ - \`description\` - Meta description (shown in search results)
516
+ - \`author\` - Author name
517
+ - \`date\` - Last modified date
518
+
519
+ These are automatically converted to meta tags.
520
+
521
+ ## Version Management
522
+
523
+ You can maintain multiple versions of documentation:
524
+
525
+ \`\`\`
526
+ docs/
527
+ ├── v1/
528
+ │ ├── index.md
529
+ │ └── api/
530
+ ├── v2/
531
+ │ ├── index.md
532
+ │ └── api/
533
+ └── latest -> v2 (symlink or config)
534
+ \`\`\`
535
+
536
+ ## Troubleshooting
537
+
538
+ ### Pages not appearing
539
+
540
+ Make sure markdown files are in the \`docs/\` folder and have \`.md\` extension.
541
+
542
+ ### Styling issues
543
+
544
+ Clear the \`.svelte-kit\` and \`node_modules\` folders and rebuild:
545
+
546
+ \`\`\`bash
547
+ rm -rf .svelte-kit node_modules
548
+ npm install
549
+ npm run build
550
+ \`\`\`
551
+
552
+ ### Search not working
553
+
554
+ Ensure the project is built:
555
+
556
+ \`\`\`bash
557
+ npm run build
558
+ \`\`\`
559
+
560
+ Search only works with built pages.
561
+ `
562
+ };
563
+
564
+ for (const [filename, content] of Object.entries(files)) {
565
+ const filePath = path.join(docsFolderPath, filename);
566
+ const dirPath = path.dirname(filePath);
567
+
568
+ if (!fs.existsSync(dirPath)) {
569
+ fs.mkdirSync(dirPath, { recursive: true });
570
+ }
571
+
572
+ if (!fs.existsSync(filePath)) {
573
+ fs.writeFileSync(filePath, content);
574
+ success(`Created: ${path.relative(projectRoot, filePath)}`);
575
+ } else {
576
+ warn(`File already exists: ${path.relative(projectRoot, filePath)}`);
577
+ }
578
+ }
579
+ }
580
+
581
+ function createRouteHandlers(projectRoot, docsRoute, docsFolder) {
582
+ const routePath = path.join(projectRoot, 'src/routes');
583
+ const docsRouteName = docsRoute.substring(1); // Remove leading /
584
+
585
+ // Create the docs route folder
586
+ const docsRouteFolder = path.join(routePath, docsRouteName);
587
+ if (!fs.existsSync(docsRouteFolder)) {
588
+ fs.mkdirSync(docsRouteFolder, { recursive: true });
589
+ success(`Created directory: src/routes/${docsRouteName}`);
590
+ }
591
+
592
+ // Create the dynamic route folder
593
+ const dynamicFolder = path.join(docsRouteFolder, '[...slug]');
594
+ if (!fs.existsSync(dynamicFolder)) {
595
+ fs.mkdirSync(dynamicFolder, { recursive: true });
596
+ success(`Created directory: src/routes/${docsRouteName}/[...slug]`);
597
+ }
598
+
599
+ // Create layout.svelte
600
+ const layoutContent = `<script lang="ts">
601
+ import { DocLayout } from 'svelte-docs-system';
602
+ import { onMount } from 'svelte';
603
+
604
+ let config = {};
605
+
606
+ onMount(async () => {
607
+ // Load nav config if _config.json exists
608
+ try {
609
+ const response = await fetch('${docsRoute}/_config.json');
610
+ if (response.ok) {
611
+ config = await response.json();
612
+ }
613
+ } catch (e) {
614
+ // Config file not found, use defaults
615
+ }
616
+ });
617
+ </script>
618
+
619
+ <DocLayout {config}>
620
+ <slot />
621
+ </DocLayout>
622
+ `;
623
+
624
+ const layoutPath = path.join(docsRouteFolder, '+layout.svelte');
625
+ if (!fs.existsSync(layoutPath)) {
626
+ fs.writeFileSync(layoutPath, layoutContent);
627
+ success(`Created: src/routes/${docsRouteName}/+layout.svelte`);
628
+ } else {
629
+ warn(`File already exists: src/routes/${docsRouteName}/+layout.svelte`);
630
+ }
631
+
632
+ // Create +page.svelte for dynamic route
633
+ const pageContent = `<script lang="ts" context="module">
634
+ import { dev } from '$app/environment';
635
+
636
+ export async function load({ params }) {
637
+ const slug = params.slug || 'index';
638
+ const docPath = '${docsRoute}/\${slug}.md';
639
+
640
+ try {
641
+ const response = await fetch(docPath);
642
+ if (!response.ok) {
643
+ return {
644
+ status: 404,
645
+ error: new Error('Documentation page not found')
646
+ };
647
+ }
648
+
649
+ const content = await response.text();
650
+ return {
651
+ props: {
652
+ content,
653
+ slug
654
+ }
655
+ };
656
+ } catch (error) {
657
+ return {
658
+ status: 500,
659
+ error: new Error('Failed to load documentation')
660
+ };
661
+ }
662
+ }
663
+ </script>
664
+
665
+ <script>
666
+ import { renderMarkdown } from 'svelte-docs-system';
667
+
668
+ export let data;
669
+
670
+ let { html = '', metadata = {} } = renderMarkdown(data.props?.content || '') || {};
671
+ </script>
672
+
673
+ <svelte:head>
674
+ <title>{metadata.title || 'Documentation'} | Docs</title>
675
+ <meta name="description" content={metadata.description || 'Documentation'} />
676
+ </svelte:head>
677
+
678
+ <article>
679
+ {@html html}
680
+ </article>
681
+
682
+ <style>
683
+ :global(article) {
684
+ max-width: 900px;
685
+ margin: 0 auto;
686
+ padding: 2rem;
687
+ }
688
+
689
+ :global(article h1) {
690
+ font-size: 2.5rem;
691
+ margin-bottom: 1rem;
692
+ }
693
+
694
+ :global(article h2) {
695
+ font-size: 1.875rem;
696
+ margin-top: 2rem;
697
+ margin-bottom: 1rem;
698
+ }
699
+
700
+ :global(article p) {
701
+ line-height: 1.75;
702
+ margin-bottom: 1rem;
703
+ }
704
+
705
+ :global(article code) {
706
+ background-color: #f3f4f6;
707
+ padding: 0.125rem 0.5rem;
708
+ border-radius: 0.25rem;
709
+ font-family: 'Courier New', monospace;
710
+ }
711
+
712
+ :global(article pre) {
713
+ background-color: #1f2937;
714
+ color: #f3f4f6;
715
+ padding: 1rem;
716
+ border-radius: 0.5rem;
717
+ overflow-x: auto;
718
+ margin-bottom: 1rem;
719
+ }
720
+
721
+ :global(article pre code) {
722
+ background-color: transparent;
723
+ padding: 0;
724
+ color: inherit;
725
+ }
726
+ </style>
727
+ `;
728
+
729
+ const pagePath = path.join(dynamicFolder, '+page.svelte');
730
+ if (!fs.existsSync(pagePath)) {
731
+ fs.writeFileSync(pagePath, pageContent);
732
+ success(`Created: src/routes/${docsRouteName}/[...slug]/+page.svelte`);
733
+ } else {
734
+ warn(`File already exists: src/routes/${docsRouteName}/[...slug]/+page.svelte`);
735
+ }
736
+ }
737
+
738
+ function updateSvelteConfig(configPath, docsRoute, docsFolder) {
739
+ let config = fs.readFileSync(configPath, 'utf-8');
740
+
741
+ // Check if docs plugin is already registered
742
+ if (config.includes('docs plugin')) {
743
+ warn('Docs plugin appears to already be configured in svelte.config.js');
744
+ return;
745
+ }
746
+
747
+ // Insert plugin configuration
748
+ const pluginConfig = `\timport { docs } from 'svelte-docs-system';\n\n`;
749
+ const pluginInConfig = `\t\tdocs({
750
+ \t\t\tdocsRoute: '${docsRoute}',
751
+ \t\t\tdocsFolderPath: '${docsFolder}',
752
+ \t\t\tbasePath: '${docsRoute}'
753
+ \t\t}),`;
754
+
755
+ // Add import at the top
756
+ if (!config.includes("from 'svelte-docs-system'")) {
757
+ const firstImportIndex = config.indexOf('import');
758
+ config = config.slice(0, firstImportIndex) + pluginConfig + config.slice(firstImportIndex);
759
+ }
760
+
761
+ // Add to plugins array if exists
762
+ const pluginsIndex = config.indexOf('plugins:');
763
+ if (pluginsIndex !== -1) {
764
+ const arrayStart = config.indexOf('[', pluginsIndex);
765
+ const insertPos = arrayStart + 1;
766
+ config = config.slice(0, insertPos) + '\n' + pluginInConfig + '\n' + config.slice(insertPos);
767
+ } else {
768
+ // Add plugins section
769
+ const kitClosing = config.lastIndexOf('}');
770
+ const plugins = `,\n\t\tplugins: [
771
+ ${pluginInConfig}
772
+ \t\t]`;
773
+ config = config.slice(0, kitClosing) + plugins + config.slice(kitClosing);
774
+ }
775
+
776
+ fs.writeFileSync(configPath, config);
777
+ success('Updated svelte.config.js with docs plugin');
778
+ }
779
+
780
+ function createNavConfig(docsFolderPath, docsRoute) {
781
+ const configPath = path.join(docsFolderPath, '_config.json');
782
+
783
+ if (fs.existsSync(configPath)) {
784
+ warn(`Navigation config already exists: _config.json`);
785
+ return;
786
+ }
787
+
788
+ const navConfig = {
789
+ name: 'Documentation',
790
+ baseUrl: docsRoute,
791
+ sections: [
792
+ {
793
+ title: 'Getting Started',
794
+ pages: [
795
+ { label: 'Home', path: docsRoute },
796
+ { label: 'Setup', path: `${docsRoute}/setup` }
797
+ ]
798
+ },
799
+ {
800
+ title: 'API',
801
+ pages: [
802
+ { label: 'Overview', path: `${docsRoute}/api/overview` },
803
+ { label: 'Reference', path: `${docsRoute}/api/reference` }
804
+ ]
805
+ },
806
+ {
807
+ title: 'Guides',
808
+ pages: [
809
+ { label: 'Architecture', path: `${docsRoute}/guides/architecture` },
810
+ { label: 'Advanced', path: `${docsRoute}/guides/advanced` }
811
+ ]
812
+ }
813
+ ]
814
+ };
815
+
816
+ fs.writeFileSync(configPath, JSON.stringify(navConfig, null, 2));
817
+ success('Created: docs/_config.json');
818
+ }
819
+
820
+ // Run the main function
821
+ main();