Skip to content

Commit 59f0d15

Browse files
authored
feat(cli): add start command (#2501)
* feat(cli): add start command * fix: pass port to execa command * chore: add test * refactor: handle error message correctly * fix: add start to program test
1 parent 071b7f5 commit 59f0d15

4 files changed

Lines changed: 75 additions & 1 deletion

File tree

packages/cli/src/commands/start.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Command } from 'commander';
2+
import consola from 'consola';
3+
import { execa } from 'execa';
4+
import { join } from 'node:path';
5+
6+
export const start = new Command('start')
7+
.description('Start your Catalyst storefront in optimized production mode.')
8+
.option('-p, --port <number>', 'Port to run the production server on (default: 3000).', '3000')
9+
.option(
10+
'--root-dir <path>',
11+
'Path to the root directory of your Catalyst project (default: current working directory).',
12+
process.cwd(),
13+
)
14+
.action(async (opts) => {
15+
try {
16+
const nextBin = join(opts.rootDir, 'node_modules', '.bin', 'next');
17+
18+
// @todo conditionally run `next start` or `opennextjs-cloudflare preview` based on the framework type
19+
await execa(nextBin, ['start', '-p', opts.port], {
20+
stdio: 'inherit',
21+
cwd: opts.rootDir,
22+
});
23+
} catch (error) {
24+
consola.error(error instanceof Error ? error.message : error);
25+
process.exit(1);
26+
}
27+
});

packages/cli/src/program.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import PACKAGE_INFO from '../package.json';
77
import { build } from './commands/build';
88
import { deploy } from './commands/deploy';
99
import { dev } from './commands/dev';
10+
import { start } from './commands/start';
1011
import { version } from './commands/version';
1112

1213
export const program = new Command();
@@ -20,4 +21,5 @@ program
2021
.addCommand(build)
2122
.addCommand(deploy)
2223
.addCommand(dev)
23-
.addCommand(version);
24+
.addCommand(version)
25+
.addCommand(start);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Command } from 'commander';
2+
import { execa } from 'execa';
3+
import { expect, test, vi } from 'vitest';
4+
5+
import { start } from '../../src/commands/start';
6+
import { program } from '../../src/program';
7+
8+
vi.mock('execa', () => ({
9+
execa: vi.fn(() => Promise.resolve({})),
10+
__esModule: true,
11+
}));
12+
13+
test('properly configured Command instance', () => {
14+
expect(start).toBeInstanceOf(Command);
15+
expect(start.name()).toBe('start');
16+
expect(start.description()).toBe('Start your Catalyst storefront in optimized production mode.');
17+
expect(start.options).toEqual(
18+
expect.arrayContaining([
19+
expect.objectContaining({ flags: '-p, --port <number>', defaultValue: '3000' }),
20+
expect.objectContaining({ flags: '--root-dir <path>', defaultValue: process.cwd() }),
21+
]),
22+
);
23+
});
24+
25+
test('calls execa with Next.js production optimized server', async () => {
26+
await program.parseAsync([
27+
'node',
28+
'catalyst',
29+
'start',
30+
'-p',
31+
'3001',
32+
'--root-dir',
33+
'/path/to/root',
34+
]);
35+
36+
expect(execa).toHaveBeenCalledWith(
37+
'/path/to/root/node_modules/.bin/next',
38+
['start', '-p', '3001'],
39+
expect.objectContaining({
40+
stdio: 'inherit',
41+
cwd: '/path/to/root',
42+
}),
43+
);
44+
});

packages/cli/tests/index.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ describe('CLI program', () => {
1818
expect(commands).toContain('build');
1919
expect(commands).toContain('deploy');
2020
expect(commands).toContain('dev');
21+
expect(commands).toContain('start');
2122
});
2223
});

0 commit comments

Comments
 (0)