@burger-api/cli 0.7.1 → 0.9.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to the Burger API CLI will be documented in this file.
4
4
 
5
+ ## Version 0.9.0 - (March 15, 2026)
6
+
7
+ - ✨ **Create** – New projects get a config file (`burger.config.ts`) from
8
+ your answers; the build uses this config when present.
9
+ - 🔨 **Build** – One build pipeline for both bundle and executable; routes
10
+ are found at build time so production is fast and reliable.
11
+ - 📂 **Defaults** – Executable output: `.build/executable/<project>` (or
12
+ `.exe` on Windows); bundle: `.build/bundle/app.js`.
13
+ - 🧪 **Tests** – New tests for routes, config, and build output; CI catches
14
+ broken builds early.
15
+ - 🐛 **Fixed** – Invalid route combinations are caught at build time.
16
+ - 🐛 **Fixed** – Production build keeps your middleware and options (e.g.
17
+ title, description) instead of dropping them.
18
+ - 📚 **Docs** – README updated with production build steps and test
19
+ commands.
20
+
5
21
  ## Version 0.7.0 - (December 23, 2025)
6
22
 
7
23
  ### Added
@@ -32,7 +48,7 @@ All notable changes to the Burger API CLI will be documented in this file.
32
48
  - `list` command to show available middleware from ecosystem
33
49
  - `add` command to download and install middleware
34
50
  - `build` command to bundle projects to single JS file
35
- - `build:executable` command to compile to standalone executable
51
+ - `build:exec` command to compile to standalone executable
36
52
  - `serve` command for development server with hot reload
37
53
  - Beautiful console output with colors and symbols
38
54
  - Zero external dependencies for file operations (uses Bun's native APIs)
package/README.md CHANGED
@@ -69,9 +69,24 @@ installed!
69
69
  - ✅ Full project structure
70
70
  - ✅ TypeScript configured
71
71
  - ✅ Dependencies installed
72
+ - ✅ `burger.config.ts` generated from your answers
72
73
  - ✅ Example routes
73
74
  - ✅ Ready to run!
74
75
 
76
+ Generated config example:
77
+
78
+ ```ts
79
+ export default {
80
+ apiDir: './src/api',
81
+ pageDir: './src/pages',
82
+ apiPrefix: '/api',
83
+ pagePrefix: '/',
84
+ debug: false,
85
+ };
86
+ ```
87
+
88
+ Edit `burger.config.ts` anytime to change routes, prefixes, or debug mode.
89
+
75
90
  ---
76
91
 
77
92
  ### `burger-api list`
@@ -151,7 +166,8 @@ const app = new Burger({
151
166
 
152
167
  ### `burger-api build <file>`
153
168
 
154
- Bundle your project into a single JavaScript file.
169
+ Bundle your project with build-time (AOT) route discovery.
170
+ The CLI scans routes first, generates a virtual entry file, then runs Bun build.
155
171
 
156
172
  **Example:**
157
173
 
@@ -171,22 +187,29 @@ burger-api build index.ts --sourcemap linked
171
187
 
172
188
  **Options:**
173
189
 
174
- - `--outfile <path>` - Output file path (default: `.build/bundle.js`)
190
+ - `--outfile <path>` - Output file path (default: `.build/bundle/app.js`)
175
191
  - `--minify` - Minify the output for smaller file size
176
192
  - `--sourcemap <type>` - Generate sourcemaps (inline, linked, or none)
177
193
  - `--target <target>` - Target environment (e.g., bun, node)
178
194
 
195
+ Build config is loaded from `burger.config.ts` or `burger.config.js` when
196
+ present. If no config exists, the CLI uses defaults:
197
+ `apiDir=./src/api`, `pageDir=./src/pages`, `apiPrefix=/api`, `pagePrefix=/`.
198
+
179
199
  **Output:**
180
200
 
181
201
  ```
182
202
  ✓ Build completed successfully!
183
- Output: .build/bundle.js
203
+ Output: .build/bundle/app.js
184
204
  Size: 42.5 KB
185
205
  ```
186
206
 
207
+ - API-only apps: `app.js` is usually enough to deploy.
208
+ - Apps with pages/assets: deploy the full `.build/bundle/` directory.
209
+
187
210
  ---
188
211
 
189
- ### `burger-api build:executable <file>`
212
+ ### `burger-api build:exec <file>`
190
213
 
191
214
  Compile your project to a standalone executable that runs without Bun installed!
192
215
 
@@ -194,19 +217,19 @@ Compile your project to a standalone executable that runs without Bun installed!
194
217
 
195
218
  ```bash
196
219
  # Build for current platform
197
- burger-api build:executable index.ts
220
+ burger-api build:exec index.ts
198
221
 
199
222
  # Build for Windows
200
- burger-api build:executable index.ts --target bun-windows-x64
223
+ burger-api build:exec index.ts --target bun-windows-x64
201
224
 
202
225
  # Build for Linux
203
- burger-api build:executable index.ts --target bun-linux-x64
226
+ burger-api build:exec index.ts --target bun-linux-x64
204
227
 
205
228
  # Build for Mac (ARM)
206
- burger-api build:executable index.ts --target bun-darwin-arm64
229
+ burger-api build:exec index.ts --target bun-darwin-arm64
207
230
 
208
231
  # Custom output name
209
- burger-api build:executable index.ts --outfile my-server.exe
232
+ burger-api build:exec index.ts --outfile my-server.exe
210
233
  ```
211
234
 
212
235
  **Options:**
@@ -228,11 +251,11 @@ burger-api build:executable index.ts --outfile my-server.exe
228
251
 
229
252
  ```
230
253
  ✓ Compilation completed successfully!
231
- Executable: .build/my-api.exe
254
+ Executable: .build/executable/<project>.exe
232
255
  Size: 45.2 MB
233
256
 
234
257
  Your standalone executable is ready to run!
235
- Run it: .build/my-api.exe
258
+ Run it: .build/executable/<project>.exe
236
259
  ```
237
260
 
238
261
  **Use case:** Perfect for deploying your API to production servers without
@@ -371,9 +394,13 @@ burger-api serve
371
394
  1. You're in a Burger API project directory
372
395
  2. The entry file exists
373
396
  3. There are no TypeScript errors in your code
397
+ 4. Route folder rules are valid (no mixed dynamic + wildcard siblings)
374
398
 
375
399
  Run `bun run dev` first to see any errors.
376
400
 
401
+ If you use custom folders or prefixes, verify your `burger.config.ts` /
402
+ `burger.config.js` values.
403
+
377
404
  ### Cross-compilation fails from Windows (D:\ drive)
378
405
 
379
406
  **Error:**
@@ -500,17 +527,23 @@ you encounter crashes, rebuild without `--bytecode`. The build scripts use
500
527
 
501
528
  ### Testing
502
529
 
503
- Test commands locally:
530
+ Run tests (from `packages/cli`):
504
531
 
505
532
  ```bash
506
- # Create a test project
507
- bun run src/index.ts create test-app
533
+ # Run all CLI tests
534
+ bun run test
535
+
536
+ # Run build tests only (check production matches dev)
537
+ bun run test:build
538
+
539
+ # Run one test file
540
+ bun test test/build-output.test.ts
541
+ ```
542
+
543
+ From the **repo root**, run all CLI tests with:
508
544
 
509
- # Test other commands
510
- cd test-app
511
- bun run ../src/index.ts list
512
- bun run ../src/index.ts add cors
513
- bun run ../src/index.ts serve
545
+ ```bash
546
+ bun run test:cli
514
547
  ```
515
548
 
516
549
  ### Contributing
@@ -527,6 +560,11 @@ bun run ../src/index.ts serve
527
560
  - Add comments explaining your code
528
561
  - Test all commands before submitting
529
562
  - Update README if adding new features
563
+ - Keep route rules in one place:
564
+ - runtime/shared rules: `packages/burger-api/src/utils/pathConversion.ts`
565
+ - scanner traversal: `packages/cli/src/utils/scanner.ts`
566
+ - Run build tests when changing routing/build (keeps dev and production behavior the same):
567
+ - `bun run test:build`
530
568
 
531
569
  ### Design Principles
532
570
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burger-api/cli",
3
- "version": "0.7.1",
3
+ "version": "0.9.1",
4
4
  "description": "Simple command-line tool for Burger API projects",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
@@ -18,6 +18,8 @@
18
18
  },
19
19
  "scripts": {
20
20
  "dev": "bun run src/index.ts",
21
+ "test": "bun test --timeout 30000 ./test",
22
+ "test:build": "bun test test/scanner.test.ts test/virtual-entry.test.ts test/entry-options.test.ts test/build-preserve-options.test.ts",
21
23
  "build:win": "bun build ./src/index.ts --compile --target bun-windows-x64 --outfile dist/burger-api.exe --minify",
22
24
  "build:linux": "bun build ./src/index.ts --compile --target bun-linux-x64 --outfile dist/burger-api-linux --minify",
23
25
  "build:mac": "bun build ./src/index.ts --compile --target bun-darwin-arm64 --outfile dist/burger-api-mac --minify",
@@ -29,8 +31,7 @@
29
31
  "@clack/prompts": "^0.7.0"
30
32
  },
31
33
  "devDependencies": {
32
- "@types/bun": "latest",
33
- "@types/commander": "^2.12.5"
34
+ "@types/bun": "latest"
34
35
  },
35
36
  "peerDependencies": {
36
37
  "typescript": "^5"
@@ -47,5 +48,8 @@
47
48
  "type": "git",
48
49
  "url": "git+https://github.com/isfhan/burger-api.git",
49
50
  "directory": "packages/cli"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
50
54
  }
51
- }
55
+ }
@@ -2,15 +2,15 @@
2
2
  * Build Commands
3
3
  *
4
4
  * Two commands for packaging your Burger API project:
5
- * 1. `burger-api build <file>` - Bundle to single JS file
6
- * 2. `burger-api build:executable <file>` - Compile to standalone executable
5
+ * 1. `burger-api build <file>` Bundle to .build/bundle/
6
+ * 2. `burger-api build:exec <file>` Compile to .build/executable/
7
7
  *
8
- * These are wrappers around Bun's build commands with sensible defaults.
8
+ * Both use build-time (AOT) route discovery no filesystem scanning at runtime.
9
9
  */
10
10
 
11
11
  import { Command } from 'commander';
12
- import { existsSync, readFileSync } from 'fs';
13
- import { join } from 'path';
12
+ import { existsSync } from 'fs';
13
+ import { dirname, resolve } from 'path';
14
14
  import {
15
15
  spinner,
16
16
  success,
@@ -20,9 +20,11 @@ import {
20
20
  formatSize,
21
21
  dim,
22
22
  } from '../utils/logger';
23
+ import { runVirtualEntryBuild } from '../utils/build/pipeline';
24
+ import { getProjectName } from '../utils/build/project';
23
25
 
24
26
  /**
25
- * Build command options
27
+ * Options for the `build` command.
26
28
  */
27
29
  interface BuildCommandOptions {
28
30
  outfile: string;
@@ -32,7 +34,7 @@ interface BuildCommandOptions {
32
34
  }
33
35
 
34
36
  /**
35
- * Build executable command options
37
+ * Options for the `build:exec` command.
36
38
  */
37
39
  interface BuildExecutableOptions {
38
40
  outfile?: string;
@@ -42,74 +44,81 @@ interface BuildExecutableOptions {
42
44
  }
43
45
 
44
46
  /**
45
- * Create the "build" command
46
- * Bundles your code into a single JavaScript file
47
+ * `burger-api build <file>`
48
+ *
49
+ * Bundles your project into .build/bundle/ using AOT route discovery.
50
+ *
51
+ * Output:
52
+ * .build/bundle/
53
+ * app.js — Bun server (run with: bun .build/bundle/app.js)
54
+ * index.html — HTML pages (flat, one per page route)
55
+ * style-[hash].css — CSS assets (flat)
56
+ * app-[hash].js — JS chunks (flat)
57
+ *
58
+ * API-only projects: app.js is a self-contained single file.
59
+ * Projects with HTML pages: deploy the entire .build/bundle/ directory.
47
60
  */
48
61
  export const buildCommand = new Command('build')
49
- .description('Bundle your project to a single JavaScript file')
50
- .argument('<file>', 'Entry file to build (e.g., index.ts)')
51
- .option('--outfile <path>', 'Output file path', '.build/bundle.js')
62
+ .description('Bundle your project into .build/bundle/')
63
+ .argument(
64
+ '<file>',
65
+ 'Entry file (used for compatibility; config from burger.config.ts or conventions)'
66
+ )
67
+ .option('--outfile <path>', 'Output bundle path', '.build/bundle/app.js')
52
68
  .option('--minify', 'Minify the output')
53
69
  .option(
54
70
  '--sourcemap <type>',
55
71
  'Generate sourcemaps (inline, linked, or none)'
56
72
  )
57
- .option('--target <target>', 'Target environment (e.g., bun, node)')
73
+ .option('--target <env>', 'Target environment (default: bun)')
58
74
  .action(async (file: string, options: BuildCommandOptions) => {
59
- // Check if the input file exists
60
- if (!existsSync(file)) {
61
- logError(`File not found: ${file}`);
75
+ const cwd = process.cwd();
76
+ const entryPath = resolve(cwd, file);
77
+ if (!existsSync(entryPath)) {
78
+ logError(`Entry file not found: ${file}`);
79
+ info('Make sure you are in the project directory.');
62
80
  process.exit(1);
63
81
  }
64
82
 
65
83
  const spin = spinner('Building project...');
66
84
 
67
85
  try {
68
- // Build the command arguments for Bun
69
- const args = ['build', file];
70
-
71
- // Add output file
72
- args.push('--outfile', options.outfile);
73
-
74
- // Add optional flags
75
- if (options.minify) {
76
- args.push('--minify');
77
- }
78
-
79
- if (options.sourcemap) {
80
- args.push('--sourcemap', options.sourcemap);
81
- }
82
-
83
- // Always target bun by default since BurgerAPI uses Bun builtins
84
- args.push('--target', options.target || 'bun');
85
-
86
- // Run the build using Bun.spawn
87
- const proc = Bun.spawn(['bun', ...args], {
88
- stdout: 'pipe',
89
- stderr: 'pipe',
86
+ info('Build-time route discovery enabled.');
87
+
88
+ const { success: ok, hasPages } = await runVirtualEntryBuild({
89
+ cwd,
90
+ entryFile: file,
91
+ outfile: options.outfile,
92
+ target: options.target || 'bun',
93
+ minify: options.minify,
94
+ sourcemap: options.sourcemap,
90
95
  });
91
96
 
92
- // Wait for it to complete
93
- const exitCode = await proc.exited;
94
-
95
- if (exitCode !== 0) {
96
- // Read error output
97
- const errorText = await new Response(proc.stderr).text();
97
+ if (!ok) {
98
98
  spin.stop('Build failed', true);
99
- logError(errorText || 'Build process failed');
99
+ logError(
100
+ 'Bun.build failed. Check that api/page directories and route files are valid.'
101
+ );
100
102
  process.exit(1);
101
103
  }
102
104
 
103
- // Get file size
104
- const outputFile = Bun.file(options.outfile);
105
- const size = outputFile.size;
105
+ const size = Bun.file(options.outfile).size;
106
+ const bundleDir = dirname(options.outfile);
106
107
 
107
108
  spin.stop('Build completed successfully!');
108
109
  newline();
109
- success(`Output: ${options.outfile}`);
110
- info(`Size: ${formatSize(size)}`);
110
+ success(`Bundle: ${options.outfile} (${formatSize(size)})`);
111
111
  newline();
112
- dim('Run your bundle with: bun ' + options.outfile);
112
+ if (hasPages) {
113
+ info(`Pages and assets are in: ${bundleDir}/`);
114
+ dim(
115
+ 'Deploy the entire directory — HTML pages depend on their chunks.'
116
+ );
117
+ dim(`Run: bun ${options.outfile}`);
118
+ } else {
119
+ info('API-only bundle — self-contained single file.');
120
+ dim(`Run anywhere: bun ${options.outfile}`);
121
+ }
113
122
  newline();
114
123
  } catch (err) {
115
124
  spin.stop('Build failed', true);
@@ -119,109 +128,92 @@ export const buildCommand = new Command('build')
119
128
  });
120
129
 
121
130
  /**
122
- * Create the "build:executable" command
123
- * Compiles your code to a standalone executable
131
+ * `burger-api build:exec <file>`
132
+ *
133
+ * Compiles your project into a standalone binary in .build/executable/.
134
+ * The binary is fully self-contained — no Bun installation required on the target.
135
+ * All routes, pages, and assets are embedded inside the binary.
124
136
  */
125
- export const buildExecutableCommand = new Command('build:executable')
126
- .description('Compile your project to a standalone executable')
127
- .argument('<file>', 'Entry file to compile (e.g., index.ts)')
128
- .option('--outfile <path>', 'Output file path')
137
+ export const buildExecutableCommand = new Command('build:exec')
138
+ .description(
139
+ 'Compile your project to a standalone executable in .build/executable/'
140
+ )
141
+ .argument(
142
+ '<file>',
143
+ 'Entry file (used for compatibility; config from burger.config.ts or conventions)'
144
+ )
145
+ .option('--outfile <path>', 'Output executable path')
129
146
  .option(
130
- '--target <target>',
147
+ '--target <platform>',
131
148
  'Target platform (bun-windows-x64, bun-linux-x64, bun-darwin-arm64)'
132
149
  )
133
150
  .option('--minify', 'Minify the output (enabled by default)', true)
134
151
  .option('--no-bytecode', 'Disable bytecode compilation')
135
152
  .action(async (file: string, options: BuildExecutableOptions) => {
136
- // Check if the input file exists
137
- if (!existsSync(file)) {
138
- logError(`File not found: ${file}`);
153
+ const cwd = process.cwd();
154
+ const entryPath = resolve(cwd, file);
155
+ if (!existsSync(entryPath)) {
156
+ logError(`Entry file not found: ${file}`);
157
+ info('Make sure you are in the project directory.');
139
158
  process.exit(1);
140
159
  }
141
160
 
142
- // Determine output filename
143
161
  let outfile = options.outfile;
144
162
  if (!outfile) {
145
- // Get project name from package.json or use basename
146
- const projectName = getProjectName();
147
-
148
- // Add platform-specific extension
149
- // Check if targeting Windows or if we're on Windows without a specific target
163
+ const projectName = getProjectName(cwd);
150
164
  const isWindows =
151
165
  options.target?.includes('windows') ||
152
166
  (!options.target && process.platform === 'win32');
153
-
154
- if (isWindows) {
155
- outfile = `.build/${projectName}.exe`;
156
- } else {
157
- outfile = `.build/${projectName}`;
158
- }
167
+ outfile = isWindows
168
+ ? `.build/executable/${projectName}.exe`
169
+ : `.build/executable/${projectName}`;
159
170
  }
160
171
 
161
172
  const spin = spinner('Compiling to executable...');
162
173
 
163
174
  try {
164
- // Build the command arguments for Bun
165
- const args = ['build', file, '--compile'];
166
-
167
- // Add output file
168
- args.push('--outfile', outfile);
169
-
170
- // Add target platform
171
- if (options.target) {
172
- args.push('--target', options.target);
173
- }
174
-
175
- // Add minify (on by default)
176
- if (options.minify) {
177
- args.push('--minify');
178
- }
179
-
180
- // Add bytecode (on by default, unless --no-bytecode is passed)
181
- if (options.bytecode !== false) {
182
- args.push('--bytecode');
183
- }
184
-
175
+ info('Build-time route discovery enabled.');
185
176
  spin.update('Compiling... (this may take a minute)');
186
177
 
187
- // Run the build using Bun.spawn
188
- const proc = Bun.spawn(['bun', ...args], {
189
- stdout: 'pipe',
190
- stderr: 'pipe',
178
+ const { success: ok, outputs } = await runVirtualEntryBuild({
179
+ cwd,
180
+ entryFile: file,
181
+ outfile,
182
+ target: options.target,
183
+ minify: options.minify,
184
+ bytecode: options.bytecode !== false,
185
+ compile: true,
191
186
  });
192
187
 
193
- // Wait for it to complete
194
- const exitCode = await proc.exited;
195
-
196
- if (exitCode !== 0) {
197
- // Read error output
198
- const errorText = await new Response(proc.stderr).text();
188
+ if (!ok) {
199
189
  spin.stop('Compilation failed', true);
200
- logError(errorText || 'Compilation process failed');
190
+ logError(
191
+ 'Bun.build failed. Check that api/page directories and route files are valid.'
192
+ );
201
193
  process.exit(1);
202
194
  }
203
195
 
204
- // Get file size - check if file exists first
205
- let size = 0;
206
- if (existsSync(outfile)) {
207
- const executableFile = Bun.file(outfile);
208
- size = executableFile.size;
209
- }
196
+ const size = existsSync(outfile)
197
+ ? Bun.file(outfile).size
198
+ : (outputs[0]?.size ?? 0);
210
199
 
211
200
  spin.stop('Compilation completed successfully!');
212
201
  newline();
213
202
  success(`Executable: ${outfile}`);
214
- if (size > 0) {
215
- info(`Size: ${formatSize(size)}`);
216
- }
203
+ if (size > 0) info(`Size: ${formatSize(size)}`);
204
+ newline();
205
+ info(
206
+ 'Standalone binary — copy it anywhere, no Bun required on the target.'
207
+ );
208
+ dim(
209
+ 'All routes, pages, and assets are embedded inside the binary.'
210
+ );
217
211
  newline();
218
- info('Your standalone executable is ready to run!');
219
-
220
212
  if (process.platform !== 'win32') {
221
- dim(`Make it executable: chmod +x ${outfile}`);
222
- dim(`Run it: ./${outfile}`);
213
+ dim(`Make executable: chmod +x ${outfile}`);
214
+ dim(`Run: ./${outfile}`);
223
215
  } else {
224
- dim(`Run it: ${outfile}`);
216
+ dim(`Run: ${outfile}`);
225
217
  }
226
218
  newline();
227
219
  } catch (err) {
@@ -230,21 +222,3 @@ export const buildExecutableCommand = new Command('build:executable')
230
222
  process.exit(1);
231
223
  }
232
224
  });
233
-
234
- /**
235
- * Get the project name from package.json
236
- * Falls back to 'app' if not found
237
- */
238
- function getProjectName(): string {
239
- try {
240
- const packageJsonPath = join(process.cwd(), 'package.json');
241
- if (existsSync(packageJsonPath)) {
242
- const content = readFileSync(packageJsonPath, 'utf-8');
243
- const packageJson = JSON.parse(content);
244
- return packageJson?.name || 'app';
245
- }
246
- } catch (err) {
247
- // Ignore errors
248
- }
249
- return 'app';
250
- }
@@ -82,6 +82,7 @@ export const createCommand = new Command('create')
82
82
  info('Creating project with the following configuration:');
83
83
  newline();
84
84
  console.log(` Name: ${projectName}`);
85
+ console.log(` Config File: burger.config.ts`);
85
86
  if (options.useApi) {
86
87
  console.log(` API Routes: ${options.apiDir || 'api'}`);
87
88
  }
@@ -106,10 +107,13 @@ export const createCommand = new Command('create')
106
107
  console.log(` 2. Start the development server:`);
107
108
  command('bun run dev');
108
109
  newline();
109
- console.log(` 3. Open your browser:`);
110
+ console.log(` 3. Edit config if needed:`);
111
+ command('burger.config.ts');
112
+ newline();
113
+ console.log(` 4. Open your browser:`);
110
114
  console.log(` ${highlight('http://localhost:4000')}`);
111
115
  newline();
112
- console.log(` 4. Add middleware (optional):`);
116
+ console.log(` 5. Add middleware (optional):`);
113
117
  command('burger-api add cors logger');
114
118
  newline();
115
119
  success('Happy coding!');
package/src/index.ts CHANGED
@@ -10,6 +10,8 @@
10
10
  * This makes it easy to add new commands and provide helpful error messages.
11
11
  */
12
12
 
13
+ import { readFileSync } from 'fs';
14
+ import { join } from 'path';
13
15
  import { Command } from 'commander';
14
16
  import { createCommand } from './commands/create';
15
17
  import { addCommand } from './commands/add';
@@ -18,6 +20,22 @@ import { buildCommand, buildExecutableCommand } from './commands/build';
18
20
  import { serveCommand } from './commands/serve';
19
21
  import { showBanner } from './utils/logger';
20
22
 
23
+ /**
24
+ * Read CLI version from package.json (single source of truth for publish).
25
+ * @returns The version of the CLI.
26
+ */
27
+ function getVersion(): string {
28
+ try {
29
+ const pkgPath = join(import.meta.dir, '..', 'package.json');
30
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) as {
31
+ version?: string;
32
+ };
33
+ return pkg.version ?? '0.0.0';
34
+ } catch {
35
+ return '0.0.0';
36
+ }
37
+ }
38
+
21
39
  /**
22
40
  * Create the main CLI program
23
41
  * This is what runs when someone types 'burger-api' in their terminal
@@ -28,7 +46,7 @@ const program = new Command();
28
46
  program
29
47
  .name('burger-api')
30
48
  .description('Simple tool to work with BurgerAPI projects')
31
- .version('0.7.1');
49
+ .version(getVersion());
32
50
 
33
51
  // Add all our commands to the CLI
34
52
  // Each command is defined in its own file for better organization
@@ -41,7 +59,7 @@ program.addCommand(serveCommand); // Run development server
41
59
 
42
60
  // Show banner + help when no command is provided
43
61
  program.action(() => {
44
- showBanner();
62
+ showBanner(getVersion());
45
63
  program.help();
46
64
  });
47
65
 
@@ -51,3 +51,15 @@ export interface GitHubFile {
51
51
  download_url?: string;
52
52
  size: number;
53
53
  }
54
+
55
+ /**
56
+ * Build-time configuration for Burger API (conventions or burger.config.ts).
57
+ * Used by the CLI when generating the virtual entry and scanning routes.
58
+ */
59
+ export interface BuildConfig {
60
+ apiDir: string;
61
+ pageDir: string;
62
+ apiPrefix: string;
63
+ pagePrefix: string;
64
+ debug?: boolean;
65
+ }