@raystack/chronicle 0.1.0-canary.a320792 → 0.1.0-canary.ac60f9f

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 (82) hide show
  1. package/dist/cli/index.js +150 -416
  2. package/package.json +13 -9
  3. package/src/cli/commands/build.ts +30 -48
  4. package/src/cli/commands/dev.ts +24 -13
  5. package/src/cli/commands/init.ts +38 -123
  6. package/src/cli/commands/serve.ts +35 -50
  7. package/src/cli/commands/start.ts +20 -16
  8. package/src/cli/index.ts +14 -14
  9. package/src/cli/utils/config.ts +25 -26
  10. package/src/cli/utils/index.ts +3 -2
  11. package/src/cli/utils/resolve.ts +7 -3
  12. package/src/cli/utils/scaffold.ts +14 -16
  13. package/src/components/mdx/code.tsx +1 -10
  14. package/src/components/mdx/details.module.css +24 -1
  15. package/src/components/mdx/details.tsx +3 -2
  16. package/src/components/mdx/image.tsx +5 -20
  17. package/src/components/mdx/index.tsx +3 -3
  18. package/src/components/mdx/link.tsx +24 -20
  19. package/src/components/ui/footer.tsx +2 -3
  20. package/src/components/ui/search.tsx +116 -71
  21. package/src/lib/config.ts +31 -29
  22. package/src/lib/get-llm-text.ts +10 -0
  23. package/src/lib/head.tsx +26 -22
  24. package/src/lib/openapi.ts +8 -8
  25. package/src/lib/page-context.tsx +76 -57
  26. package/src/lib/source.ts +144 -96
  27. package/src/pages/ApiLayout.tsx +22 -18
  28. package/src/pages/ApiPage.tsx +32 -27
  29. package/src/pages/DocsLayout.tsx +7 -7
  30. package/src/pages/DocsPage.tsx +11 -11
  31. package/src/pages/NotFound.tsx +11 -4
  32. package/src/server/App.tsx +35 -27
  33. package/src/server/api/apis-proxy.ts +69 -0
  34. package/src/server/api/health.ts +5 -0
  35. package/src/server/api/page/[...slug].ts +18 -0
  36. package/src/server/api/search.ts +170 -0
  37. package/src/server/api/specs.ts +9 -0
  38. package/src/server/build-search-index.ts +117 -0
  39. package/src/server/entry-client.tsx +52 -56
  40. package/src/server/entry-server.tsx +95 -35
  41. package/src/server/routes/llms.txt.ts +61 -0
  42. package/src/server/routes/og.tsx +75 -0
  43. package/src/server/routes/robots.txt.ts +11 -0
  44. package/src/server/routes/sitemap.xml.ts +39 -0
  45. package/src/server/utils/safe-path.ts +17 -0
  46. package/src/server/vite-config.ts +50 -49
  47. package/src/themes/default/Layout.tsx +69 -41
  48. package/src/themes/default/Page.module.css +0 -60
  49. package/src/themes/default/Page.tsx +9 -11
  50. package/src/themes/default/Toc.tsx +30 -28
  51. package/src/themes/default/index.ts +7 -9
  52. package/src/themes/paper/ChapterNav.tsx +59 -39
  53. package/src/themes/paper/Layout.module.css +1 -1
  54. package/src/themes/paper/Layout.tsx +24 -12
  55. package/src/themes/paper/Page.module.css +11 -4
  56. package/src/themes/paper/Page.tsx +67 -47
  57. package/src/themes/paper/ReadingProgress.tsx +160 -139
  58. package/src/themes/paper/index.ts +5 -5
  59. package/src/themes/registry.ts +7 -7
  60. package/src/types/globals.d.ts +4 -0
  61. package/src/cli/__tests__/config.test.ts +0 -25
  62. package/src/cli/__tests__/scaffold.test.ts +0 -10
  63. package/src/pages/__tests__/head.test.tsx +0 -57
  64. package/src/server/__tests__/entry-server.test.tsx +0 -35
  65. package/src/server/__tests__/handlers.test.ts +0 -77
  66. package/src/server/__tests__/og.test.ts +0 -23
  67. package/src/server/__tests__/router.test.ts +0 -72
  68. package/src/server/__tests__/vite-config.test.ts +0 -25
  69. package/src/server/dev.ts +0 -156
  70. package/src/server/entry-prod.ts +0 -127
  71. package/src/server/handlers/apis-proxy.ts +0 -52
  72. package/src/server/handlers/health.ts +0 -3
  73. package/src/server/handlers/llms.ts +0 -58
  74. package/src/server/handlers/og.ts +0 -87
  75. package/src/server/handlers/robots.ts +0 -11
  76. package/src/server/handlers/search.ts +0 -140
  77. package/src/server/handlers/sitemap.ts +0 -39
  78. package/src/server/handlers/specs.ts +0 -9
  79. package/src/server/index.html +0 -12
  80. package/src/server/prod.ts +0 -18
  81. package/src/server/router.ts +0 -42
  82. package/src/themes/default/font.ts +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raystack/chronicle",
3
- "version": "0.1.0-canary.a320792",
3
+ "version": "0.1.0-canary.ac60f9f",
4
4
  "description": "Config-driven documentation framework",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -15,7 +15,8 @@
15
15
  "chronicle": "./bin/chronicle.js"
16
16
  },
17
17
  "scripts": {
18
- "build:cli": "bun build-cli.ts"
18
+ "build:cli": "bun build-cli.ts",
19
+ "lint": "biome lint src/"
19
20
  },
20
21
  "devDependencies": {
21
22
  "@biomejs/biome": "^2.3.13",
@@ -35,32 +36,35 @@
35
36
  "@codemirror/theme-one-dark": "^6.1.3",
36
37
  "@codemirror/view": "^6.39.14",
37
38
  "@heroicons/react": "^2.2.0",
38
- "@mdx-js/rollup": "^3.1.1",
39
- "@raystack/apsara": "^0.56.0",
39
+ "@raystack/apsara": "0.55.1",
40
+ "@shikijs/rehype": "^4.0.2",
40
41
  "@vitejs/plugin-react": "^6.0.1",
41
42
  "chalk": "^5.6.2",
42
43
  "class-variance-authority": "^0.7.1",
43
44
  "codemirror": "^6.0.2",
44
45
  "commander": "^14.0.2",
46
+ "fumadocs-core": "16.6.15",
47
+ "fumadocs-mdx": "^14.2.6",
45
48
  "glob": "^11.0.0",
46
49
  "gray-matter": "^4.0.3",
50
+ "h3": "^2.0.1-rc.16",
47
51
  "lodash": "^4.17.23",
48
52
  "mermaid": "^11.13.0",
53
+ "minisearch": "^7.2.0",
54
+ "nitro": "latest",
49
55
  "openapi-types": "^12.1.3",
50
56
  "react": "^19.0.0",
51
57
  "react-dom": "^19.0.0",
52
- "react-router-dom": "^7.13.1",
58
+ "react-router": "^7.13.1",
53
59
  "remark-directive": "^4.0.0",
54
- "remark-gfm": "^4.0.1",
55
- "@shikijs/rehype": "^4.0.2",
60
+ "remark-parse": "^11.0.0",
56
61
  "remark-frontmatter": "^5.0.0",
62
+ "remark-gfm": "^4.0.1",
57
63
  "remark-mdx-frontmatter": "^5.2.0",
58
64
  "satori": "^0.25.0",
59
- "sirv": "^3.0.1",
60
65
  "slugify": "^1.6.6",
61
66
  "unified": "^11.0.5",
62
67
  "unist-util-visit": "^5.1.0",
63
- "minisearch": "^7.2.0",
64
68
  "vite": "^8.0.0",
65
69
  "yaml": "^2.8.2"
66
70
  }
@@ -1,52 +1,34 @@
1
- import { Command } from 'commander'
2
- import path from 'path'
3
- import chalk from 'chalk'
4
- import { resolveContentDir } from '@/cli/utils/config'
5
- import { PACKAGE_ROOT } from '@/cli/utils/resolve'
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ import { resolveContentDir } from '@/cli/utils/config';
4
+ import { PACKAGE_ROOT } from '@/cli/utils/resolve';
5
+ import { linkContent } from '@/cli/utils/scaffold';
6
6
 
7
7
  export const buildCommand = new Command('build')
8
8
  .description('Build for production')
9
9
  .option('-c, --content <path>', 'Content directory')
10
- .option('-o, --outDir <path>', 'Output directory', 'dist')
11
- .action(async (options) => {
12
- const contentDir = resolveContentDir(options.content)
13
- const outDir = path.resolve(options.outDir)
14
-
15
- process.env.CHRONICLE_PROJECT_ROOT = process.cwd()
16
- process.env.CHRONICLE_CONTENT_DIR = contentDir
17
-
18
- console.log(chalk.cyan('Building for production...'))
19
-
20
- const { build } = await import('vite')
21
- const { createViteConfig } = await import('@/server/vite-config')
22
-
23
- const baseConfig = await createViteConfig({ root: PACKAGE_ROOT, contentDir })
24
-
25
- // Build client bundle
26
- console.log(chalk.gray('Building client...'))
27
- await build({
28
- ...baseConfig,
29
- build: {
30
- outDir: path.join(outDir, 'client'),
31
- ssrManifest: true,
32
- rolldownOptions: {
33
- input: path.resolve(PACKAGE_ROOT, 'src/server/index.html'),
34
- },
35
- },
36
- })
37
-
38
- // Build server bundle (noExternal: true to bundle all deps for portability)
39
- console.log(chalk.gray('Building server...'))
40
- await build({
41
- ...baseConfig,
42
- ssr: {
43
- noExternal: true,
44
- },
45
- build: {
46
- outDir: path.join(outDir, 'server'),
47
- ssr: path.resolve(PACKAGE_ROOT, 'src/server/entry-prod.ts'),
48
- },
49
- })
50
-
51
- console.log(chalk.green('Build complete →'), outDir)
52
- })
10
+ .option(
11
+ '--preset <preset>',
12
+ 'Deploy preset (vercel, cloudflare, node-server)'
13
+ )
14
+ .action(async options => {
15
+ const contentDir = resolveContentDir(options.content);
16
+ await linkContent(contentDir);
17
+
18
+ console.log(chalk.cyan('Building for production...'));
19
+
20
+ const { createBuilder } = await import('vite');
21
+ const { createViteConfig } = await import('@/server/vite-config');
22
+
23
+ const config = await createViteConfig({
24
+ packageRoot: PACKAGE_ROOT,
25
+ projectRoot: process.cwd(),
26
+ contentDir,
27
+ preset: options.preset
28
+ });
29
+
30
+ const builder = await createBuilder({ ...config, builder: {} });
31
+ await builder.buildApp();
32
+
33
+ console.log(chalk.green('Build complete'));
34
+ });
@@ -1,21 +1,32 @@
1
- import { Command } from 'commander'
2
- import chalk from 'chalk'
3
- import { resolveContentDir } from '@/cli/utils/config'
4
- import { PACKAGE_ROOT } from '@/cli/utils/resolve'
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import { Command } from 'commander';
5
+ import { resolveContentDir } from '@/cli/utils/config';
6
+ import { PACKAGE_ROOT } from '@/cli/utils/resolve';
7
+ import { linkContent } from '@/cli/utils/scaffold';
5
8
 
6
9
  export const devCommand = new Command('dev')
7
10
  .description('Start development server')
8
11
  .option('-p, --port <port>', 'Port number', '3000')
9
12
  .option('-c, --content <path>', 'Content directory')
10
- .action(async (options) => {
11
- const contentDir = resolveContentDir(options.content)
12
- const port = parseInt(options.port, 10)
13
+ .action(async options => {
14
+ const contentDir = resolveContentDir(options.content);
15
+ const port = parseInt(options.port, 10);
13
16
 
14
- process.env.CHRONICLE_PROJECT_ROOT = process.cwd()
15
- process.env.CHRONICLE_CONTENT_DIR = contentDir
17
+ await linkContent(contentDir);
16
18
 
17
- console.log(chalk.cyan('Starting dev server...'))
19
+ console.log(chalk.cyan('Starting dev server...'));
18
20
 
19
- const { startDevServer } = await import('@/server/dev')
20
- await startDevServer({ port, root: PACKAGE_ROOT, contentDir })
21
- })
21
+ const { createServer } = await import('vite');
22
+ const { createViteConfig } = await import('@/server/vite-config');
23
+
24
+ const config = await createViteConfig({ packageRoot: PACKAGE_ROOT, projectRoot: process.cwd(), contentDir });
25
+ const server = await createServer({
26
+ ...config,
27
+ server: { ...config.server, port }
28
+ });
29
+
30
+ await server.listen();
31
+ server.printUrls();
32
+ });
@@ -1,43 +1,16 @@
1
- import { Command } from 'commander'
2
- import { execSync } from 'child_process'
3
- import fs from 'fs'
4
- import path from 'path'
5
- import chalk from 'chalk'
6
- import { stringify } from 'yaml'
7
- import type { ChronicleConfig } from '@/types'
8
- import { detectPackageManager, getChronicleVersion } from '@/cli/utils/scaffold'
9
-
10
- function createConfig(): ChronicleConfig {
11
- return {
12
- title: 'My Documentation',
13
- description: 'Documentation powered by Chronicle',
14
- theme: { name: 'default' },
15
- search: { enabled: true, placeholder: 'Search documentation...' },
16
- }
17
- }
18
-
19
- function createPackageJson(name: string): Record<string, unknown> {
20
- return {
21
- name,
22
- private: true,
23
- type: 'module',
24
- scripts: {
25
- dev: 'chronicle dev',
26
- build: 'chronicle build',
27
- start: 'chronicle start',
28
- },
29
- dependencies: {
30
- '@raystack/chronicle': `^${getChronicleVersion()}`,
31
- },
32
- devDependencies: {
33
- '@raystack/tools-config': '0.56.0',
34
- 'openapi-types': '^12.1.3',
35
- typescript: '5.9.3',
36
- '@types/react': '^19.2.10',
37
- '@types/node': '^25.1.0',
38
- },
39
- }
40
- }
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import { Command } from 'commander';
5
+ import { stringify } from 'yaml';
6
+ import type { ChronicleConfig } from '@/types';
7
+
8
+ const defaultConfig: ChronicleConfig = {
9
+ title: 'My Documentation',
10
+ description: 'Documentation powered by Chronicle',
11
+ theme: { name: 'default' },
12
+ search: { enabled: true, placeholder: 'Search documentation...' }
13
+ };
41
14
 
42
15
  const sampleMdx = `---
43
16
  title: Welcome
@@ -48,107 +21,49 @@ order: 1
48
21
  # Welcome
49
22
 
50
23
  This is your documentation home page.
51
- `
24
+ `;
52
25
 
53
26
  export const initCommand = new Command('init')
54
27
  .description('Initialize a new Chronicle project')
55
28
  .option('-c, --content <path>', 'Content directory name', 'content')
56
- .action((options) => {
57
- const projectDir = process.cwd()
58
- const dirName = path.basename(projectDir) || 'docs'
59
- const contentDir = path.join(projectDir, options.content)
29
+ .action(options => {
30
+ const projectDir = process.cwd();
31
+ const contentDir = path.join(projectDir, options.content);
60
32
 
61
- // Create content directory
62
33
  if (!fs.existsSync(contentDir)) {
63
- fs.mkdirSync(contentDir, { recursive: true })
64
- console.log(chalk.green('\u2713'), 'Created', contentDir)
65
- }
66
-
67
- // Create or update package.json
68
- const packageJsonPath = path.join(projectDir, 'package.json')
69
- if (!fs.existsSync(packageJsonPath)) {
70
- fs.writeFileSync(packageJsonPath, JSON.stringify(createPackageJson(dirName), null, 2) + '\n')
71
- console.log(chalk.green('\u2713'), 'Created', packageJsonPath)
72
- } else {
73
- const existing = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
74
- const template = createPackageJson(dirName)
75
- let updated = false
76
-
77
- if (existing.type !== 'module') {
78
- existing.type = 'module'
79
- updated = true
80
- }
81
-
82
- if (!existing.scripts) existing.scripts = {}
83
- for (const [key, value] of Object.entries(template.scripts as Record<string, string>)) {
84
- if (!existing.scripts[key]) {
85
- existing.scripts[key] = value
86
- updated = true
87
- }
88
- }
89
-
90
- if (!existing.dependencies) existing.dependencies = {}
91
- for (const [key, value] of Object.entries(template.dependencies as Record<string, string>)) {
92
- if (!existing.dependencies[key]) {
93
- existing.dependencies[key] = value
94
- updated = true
95
- }
96
- }
97
-
98
- if (!existing.devDependencies) existing.devDependencies = {}
99
- for (const [key, value] of Object.entries(template.devDependencies as Record<string, string>)) {
100
- if (!existing.devDependencies[key]) {
101
- existing.devDependencies[key] = value
102
- updated = true
103
- }
104
- }
105
-
106
- if (updated) {
107
- fs.writeFileSync(packageJsonPath, JSON.stringify(existing, null, 2) + '\n')
108
- console.log(chalk.green('\u2713'), 'Updated', packageJsonPath)
109
- } else {
110
- console.log(chalk.yellow('\u26a0'), packageJsonPath, 'already has all required entries')
111
- }
34
+ fs.mkdirSync(contentDir, { recursive: true });
35
+ console.log(chalk.green('\u2713'), 'Created', contentDir);
112
36
  }
113
37
 
114
- // Create chronicle.yaml
115
- const configPath = path.join(projectDir, 'chronicle.yaml')
38
+ const configPath = path.join(projectDir, 'chronicle.yaml');
116
39
  if (!fs.existsSync(configPath)) {
117
- fs.writeFileSync(configPath, stringify(createConfig()))
118
- console.log(chalk.green('\u2713'), 'Created', configPath)
40
+ fs.writeFileSync(configPath, stringify(defaultConfig));
41
+ console.log(chalk.green('\u2713'), 'Created', configPath);
119
42
  } else {
120
- console.log(chalk.yellow('\u26a0'), configPath, 'already exists')
43
+ console.log(chalk.yellow('\u26a0'), configPath, 'already exists');
121
44
  }
122
45
 
123
- // Create sample index.mdx
124
- const contentFiles = fs.readdirSync(contentDir)
46
+ const contentFiles = fs.readdirSync(contentDir);
125
47
  if (contentFiles.length === 0) {
126
- const indexPath = path.join(contentDir, 'index.mdx')
127
- fs.writeFileSync(indexPath, sampleMdx)
128
- console.log(chalk.green('\u2713'), 'Created', indexPath)
48
+ const indexPath = path.join(contentDir, 'index.mdx');
49
+ fs.writeFileSync(indexPath, sampleMdx);
50
+ console.log(chalk.green('\u2713'), 'Created', indexPath);
129
51
  }
130
52
 
131
- // Update .gitignore
132
- const gitignorePath = path.join(projectDir, '.gitignore')
133
- const gitignoreEntries = ['node_modules', 'dist']
53
+ const gitignorePath = path.join(projectDir, '.gitignore');
54
+ const gitignoreEntries = ['node_modules', 'dist', '.output'];
134
55
  if (fs.existsSync(gitignorePath)) {
135
- const existing = fs.readFileSync(gitignorePath, 'utf-8')
136
- const missing = gitignoreEntries.filter(e => !existing.includes(e))
56
+ const existing = fs.readFileSync(gitignorePath, 'utf-8');
57
+ const missing = gitignoreEntries.filter(e => !existing.includes(e));
137
58
  if (missing.length > 0) {
138
- fs.appendFileSync(gitignorePath, `\n${missing.join('\n')}\n`)
139
- console.log(chalk.green('\u2713'), 'Added', missing.join(', '), 'to .gitignore')
59
+ fs.appendFileSync(gitignorePath, `\n${missing.join('\n')}\n`);
60
+ console.log(chalk.green('\u2713'), 'Added', missing.join(', '), 'to .gitignore');
140
61
  }
141
62
  } else {
142
- fs.writeFileSync(gitignorePath, `${gitignoreEntries.join('\n')}\n`)
143
- console.log(chalk.green('\u2713'), 'Created .gitignore')
63
+ fs.writeFileSync(gitignorePath, `${gitignoreEntries.join('\n')}\n`);
64
+ console.log(chalk.green('\u2713'), 'Created .gitignore');
144
65
  }
145
66
 
146
- // Install dependencies
147
- const pm = detectPackageManager()
148
- console.log(chalk.cyan(`\nInstalling dependencies with ${pm}...`))
149
- execSync(`${pm} install`, { cwd: projectDir, stdio: 'inherit' })
150
-
151
- const runCmd = pm === 'npm' ? 'npx' : pm === 'bun' ? 'bunx' : `${pm} dlx`
152
- console.log(chalk.green('\n\u2713 Chronicle initialized!'))
153
- console.log('\nRun', chalk.cyan(`${runCmd} chronicle dev`), 'to start development server')
154
- })
67
+ console.log(chalk.green('\n\u2713 Chronicle initialized!'));
68
+ console.log('\nRun', chalk.cyan('chronicle dev'), 'to start development server');
69
+ });
@@ -1,55 +1,40 @@
1
- import { Command } from 'commander'
2
- import path from 'path'
3
- import chalk from 'chalk'
4
- import { resolveContentDir } from '@/cli/utils/config'
5
- import { PACKAGE_ROOT } from '@/cli/utils/resolve'
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ import { resolveContentDir } from '@/cli/utils/config';
4
+ import { PACKAGE_ROOT } from '@/cli/utils/resolve';
5
+ import { linkContent } from '@/cli/utils/scaffold';
6
6
 
7
7
  export const serveCommand = new Command('serve')
8
8
  .description('Build and start production server')
9
9
  .option('-p, --port <port>', 'Port number', '3000')
10
10
  .option('-c, --content <path>', 'Content directory')
11
- .option('-o, --outDir <path>', 'Output directory', 'dist')
12
- .action(async (options) => {
13
- const contentDir = resolveContentDir(options.content)
14
- const port = parseInt(options.port, 10)
15
- const outDir = path.resolve(options.outDir)
16
-
17
- process.env.CHRONICLE_PROJECT_ROOT = process.cwd()
18
- process.env.CHRONICLE_CONTENT_DIR = contentDir
19
-
20
- // Build
21
- console.log(chalk.cyan('Building for production...'))
22
-
23
- const { build } = await import('vite')
24
- const { createViteConfig } = await import('@/server/vite-config')
25
-
26
- const baseConfig = await createViteConfig({ root: PACKAGE_ROOT, contentDir })
27
-
28
- await build({
29
- ...baseConfig,
30
- build: {
31
- outDir: path.join(outDir, 'client'),
32
- ssrManifest: true,
33
- rolldownOptions: {
34
- input: path.resolve(PACKAGE_ROOT, 'src/server/index.html'),
35
- },
36
- },
37
- })
38
-
39
- await build({
40
- ...baseConfig,
41
- ssr: {
42
- noExternal: true,
43
- },
44
- build: {
45
- outDir: path.join(outDir, 'server'),
46
- ssr: path.resolve(PACKAGE_ROOT, 'src/server/entry-prod.ts'),
47
- },
48
- })
49
-
50
- // Start
51
- console.log(chalk.cyan('Starting production server...'))
52
-
53
- const { startProdServer } = await import('@/server/prod')
54
- await startProdServer({ port, root: PACKAGE_ROOT, distDir: outDir })
55
- })
11
+ .option(
12
+ '--preset <preset>',
13
+ 'Deploy preset (vercel, cloudflare, node-server)'
14
+ )
15
+ .action(async options => {
16
+ const contentDir = resolveContentDir(options.content);
17
+ const port = parseInt(options.port, 10);
18
+ await linkContent(contentDir);
19
+
20
+ const { build, preview } = await import('vite');
21
+ const { createViteConfig } = await import('@/server/vite-config');
22
+
23
+ const config = await createViteConfig({
24
+ packageRoot: PACKAGE_ROOT,
25
+ projectRoot: process.cwd(),
26
+ contentDir,
27
+ preset: options.preset
28
+ });
29
+
30
+ console.log(chalk.cyan('Building for production...'));
31
+ await build(config);
32
+
33
+ console.log(chalk.cyan('Starting production server...'));
34
+ const server = await preview({
35
+ ...config,
36
+ preview: { port }
37
+ });
38
+
39
+ server.printUrls();
40
+ });
@@ -1,24 +1,28 @@
1
- import { Command } from 'commander'
2
- import path from 'path'
3
- import chalk from 'chalk'
4
- import { resolveContentDir } from '@/cli/utils/config'
5
- import { PACKAGE_ROOT } from '@/cli/utils/resolve'
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ import { resolveContentDir } from '@/cli/utils/config';
4
+ import { PACKAGE_ROOT } from '@/cli/utils/resolve';
5
+ import { linkContent } from '@/cli/utils/scaffold';
6
6
 
7
7
  export const startCommand = new Command('start')
8
8
  .description('Start production server')
9
9
  .option('-p, --port <port>', 'Port number', '3000')
10
10
  .option('-c, --content <path>', 'Content directory')
11
- .option('-d, --dist <path>', 'Dist directory', 'dist')
12
- .action(async (options) => {
13
- const contentDir = resolveContentDir(options.content)
14
- const port = parseInt(options.port, 10)
15
- const distDir = path.resolve(options.dist)
11
+ .action(async options => {
12
+ const contentDir = resolveContentDir(options.content);
13
+ const port = parseInt(options.port, 10);
14
+ await linkContent(contentDir);
16
15
 
17
- process.env.CHRONICLE_PROJECT_ROOT = process.cwd()
18
- process.env.CHRONICLE_CONTENT_DIR = contentDir
16
+ console.log(chalk.cyan('Starting production server...'));
19
17
 
20
- console.log(chalk.cyan('Starting production server...'))
18
+ const { preview } = await import('vite');
19
+ const { createViteConfig } = await import('@/server/vite-config');
21
20
 
22
- const { startProdServer } = await import('@/server/prod')
23
- await startProdServer({ port, root: PACKAGE_ROOT, distDir })
24
- })
21
+ const config = await createViteConfig({ packageRoot: PACKAGE_ROOT, projectRoot: process.cwd(), contentDir });
22
+ const server = await preview({
23
+ ...config,
24
+ preview: { port }
25
+ });
26
+
27
+ server.printUrls();
28
+ });
package/src/cli/index.ts CHANGED
@@ -1,21 +1,21 @@
1
- import { Command } from 'commander'
2
- import { initCommand } from './commands/init'
3
- import { devCommand } from './commands/dev'
4
- import { buildCommand } from './commands/build'
5
- import { startCommand } from './commands/start'
6
- import { serveCommand } from './commands/serve'
1
+ import { Command } from 'commander';
2
+ import { buildCommand } from './commands/build';
3
+ import { devCommand } from './commands/dev';
4
+ import { initCommand } from './commands/init';
5
+ import { serveCommand } from './commands/serve';
6
+ import { startCommand } from './commands/start';
7
7
 
8
- const program = new Command()
8
+ const program = new Command();
9
9
 
10
10
  program
11
11
  .name('chronicle')
12
12
  .description('Config-driven documentation framework')
13
- .version('0.1.0')
13
+ .version('0.1.0');
14
14
 
15
- program.addCommand(initCommand)
16
- program.addCommand(devCommand)
17
- program.addCommand(buildCommand)
18
- program.addCommand(startCommand)
19
- program.addCommand(serveCommand)
15
+ program.addCommand(initCommand);
16
+ program.addCommand(devCommand);
17
+ program.addCommand(buildCommand);
18
+ program.addCommand(startCommand);
19
+ program.addCommand(serveCommand);
20
20
 
21
- program.parse()
21
+ program.parse();
@@ -1,43 +1,42 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { parse } from 'yaml'
4
- import chalk from 'chalk'
5
- import type { ChronicleConfig } from '@/types'
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import chalk from 'chalk';
4
+ import { parse } from 'yaml';
5
+ import type { ChronicleConfig } from '@/types';
6
6
 
7
7
  export interface CLIConfig {
8
- config: ChronicleConfig
9
- configPath: string
10
- contentDir: string
8
+ config: ChronicleConfig;
9
+ configPath: string;
10
+ contentDir: string;
11
11
  }
12
12
 
13
13
  export function resolveContentDir(contentFlag?: string): string {
14
- if (contentFlag) return path.resolve(contentFlag)
15
- if (process.env.CHRONICLE_CONTENT_DIR) return path.resolve(process.env.CHRONICLE_CONTENT_DIR)
16
- return path.resolve('content')
14
+ if (contentFlag) return path.resolve(contentFlag);
15
+ return path.resolve('content');
17
16
  }
18
17
 
19
18
  function resolveConfigPath(contentDir: string): string | null {
20
- const cwdPath = path.join(process.cwd(), 'chronicle.yaml')
21
- if (fs.existsSync(cwdPath)) return cwdPath
22
- const contentPath = path.join(contentDir, 'chronicle.yaml')
23
- if (fs.existsSync(contentPath)) return contentPath
24
- return null
19
+ const cwdPath = path.join(process.cwd(), 'chronicle.yaml');
20
+ if (fs.existsSync(cwdPath)) return cwdPath;
21
+ const contentPath = path.join(contentDir, 'chronicle.yaml');
22
+ if (fs.existsSync(contentPath)) return contentPath;
23
+ return null;
25
24
  }
26
25
 
27
26
  export function loadCLIConfig(contentDir: string): CLIConfig {
28
- const configPath = resolveConfigPath(contentDir)
27
+ const configPath = resolveConfigPath(contentDir);
29
28
 
30
29
  if (!configPath) {
31
- console.log(chalk.red(`Error: chronicle.yaml not found in '${process.cwd()}' or '${contentDir}'`))
32
- console.log(chalk.gray(`Run 'chronicle init' to create one`))
33
- process.exit(1)
30
+ console.log(
31
+ chalk.red(
32
+ `Error: chronicle.yaml not found in '${process.cwd()}' or '${contentDir}'`
33
+ )
34
+ );
35
+ console.log(chalk.gray("Run 'chronicle init' to create one"));
36
+ process.exit(1);
34
37
  }
35
38
 
36
- const config = parse(fs.readFileSync(configPath, 'utf-8')) as ChronicleConfig
39
+ const config = parse(fs.readFileSync(configPath, 'utf-8')) as ChronicleConfig;
37
40
 
38
- return {
39
- config,
40
- configPath,
41
- contentDir,
42
- }
41
+ return { config, configPath, contentDir };
43
42
  }
@@ -1,2 +1,3 @@
1
- export * from './config'
2
- export * from './resolve'
1
+ export * from './config';
2
+ export * from './resolve';
3
+ export * from './scaffold';
@@ -1,6 +1,10 @@
1
- import path from 'path'
2
- import { fileURLToPath } from 'url'
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
3
 
4
4
  // After bundling: dist/cli/index.js → ../.. = package root
5
5
  // After install: node_modules/@raystack/chronicle/dist/cli/index.js → ../.. = package root
6
- export const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
6
+ export const PACKAGE_ROOT = path.resolve(
7
+ path.dirname(fileURLToPath(import.meta.url)),
8
+ '..',
9
+ '..'
10
+ );