@swell/cli 2.3.1 → 2.3.2

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.
@@ -16,7 +16,10 @@ export default class AppDev extends PushAppCommand {
16
16
  functionErrors: Map<string, string>;
17
17
  functionPorts: Map<string, number>;
18
18
  tmpDir: string;
19
+ frontendPort: number | null;
20
+ isCleaningUp: boolean;
19
21
  run(): Promise<void>;
22
+ private cleanupOnExit;
20
23
  runAppFrontendDevIfApplicable(frontendPort?: number): Promise<number | void>;
21
24
  private createFunctionRouter;
22
25
  private createTmpDirectory;
@@ -46,6 +46,10 @@ export default class AppDev extends PushAppCommand {
46
46
  functionPorts = new Map();
47
47
  // Directory for compiled function files and wrangler context
48
48
  tmpDir = '';
49
+ // Port for frontend dev server (used for routing non-function requests)
50
+ frontendPort = null;
51
+ // Guard against multiple cleanup calls
52
+ isCleaningUp = false;
49
53
  async run() {
50
54
  const { flags } = await this.parse(AppDev);
51
55
  const { port, 'frontend-port': frontendPort } = flags;
@@ -62,6 +66,21 @@ export default class AppDev extends PushAppCommand {
62
66
  const serverPort = await this.startProxyServer(port);
63
67
  await this.startAppFunctionServer(spinner, serverPort);
64
68
  await this.runAppFrontendDevIfApplicable(frontendPort);
69
+ // Register cleanup handlers to clear local proxy on exit
70
+ process.on('SIGINT', this.cleanupOnExit.bind(this));
71
+ process.on('SIGTERM', this.cleanupOnExit.bind(this));
72
+ }
73
+ async cleanupOnExit() {
74
+ if (this.isCleaningUp)
75
+ return;
76
+ this.isCleaningUp = true;
77
+ try {
78
+ await this.updateLocalProxy(null, this.storefront?.id);
79
+ }
80
+ catch {
81
+ // Ignore errors during cleanup
82
+ }
83
+ // Note: proxy.ts signal handlers will call process.exit()
65
84
  }
66
85
  async runAppFrontendDevIfApplicable(frontendPort) {
67
86
  const projectType = this.getFrontendProjectType(false);
@@ -70,6 +89,8 @@ export default class AppDev extends PushAppCommand {
70
89
  this.argv.push('--app-dev');
71
90
  // add proxy-port flag (use provided port or auto-detect)
72
91
  const proxyPort = frontendPort || (await getPort({ port: portNumbers(4000, 4100) }));
92
+ // Store frontend port for function router to use for fallback routing
93
+ this.frontendPort = proxyPort;
73
94
  this.argv.push('--proxy-port', String(proxyPort));
74
95
  this.config.runCommand('app:frontend:dev', this.argv);
75
96
  return proxyPort;
@@ -111,6 +132,24 @@ export default class AppDev extends PushAppCommand {
111
132
  });
112
133
  req.pipe(proxyReq);
113
134
  }
135
+ else if (this.frontendPort) {
136
+ // Proxy non-function requests to frontend dev server
137
+ const proxyReq = http.request({
138
+ hostname: 'localhost',
139
+ port: this.frontendPort,
140
+ path: req.url,
141
+ method: req.method,
142
+ headers: req.headers,
143
+ }, (proxyRes) => {
144
+ res.writeHead(proxyRes.statusCode, proxyRes.headers);
145
+ proxyRes.pipe(res);
146
+ });
147
+ proxyReq.on('error', (error) => {
148
+ res.writeHead(502);
149
+ res.end(`Frontend dev server error: ${error.message}`);
150
+ });
151
+ req.pipe(proxyReq);
152
+ }
114
153
  else {
115
154
  res.writeHead(404);
116
155
  const functionError = this.functionErrors.get(functionName);
@@ -26,7 +26,7 @@ export default class AppFrontendDev extends PushAppCommand {
26
26
  }),
27
27
  'app-dev': Flags.boolean({
28
28
  description: 'indicates frontend app is running in app dev mode',
29
- default: true,
29
+ default: false,
30
30
  }),
31
31
  };
32
32
  static orientation = {
@@ -57,7 +57,11 @@ export default class AppFrontendDev extends PushAppCommand {
57
57
  if (!isAppDev) {
58
58
  this.log(`Starting app dev server...\n`);
59
59
  }
60
- const serverPort = await this.startProxyServer(proxyPort || port);
60
+ // When running as child of `swell app dev`, don't create a new tunnel.
61
+ // The parent command already created the tunnel and handles routing.
62
+ const serverPort = isAppDev && proxyPort
63
+ ? proxyPort
64
+ : await this.startProxyServer(proxyPort || port);
61
65
  await this.execFrontendProject(serverPort, isAppDev);
62
66
  }
63
67
  async execFrontendProject(serverPort, isAppDev) {
@@ -80,7 +80,7 @@ export declare abstract class PushAppCommand extends RemoteAppCommand {
80
80
  setWatchingFiles(): Promise<void>;
81
81
  startProxyServer(port?: number): Promise<number>;
82
82
  updateFrontendDeployment(currentStore: string, projectType: FrontendProjectType, deploymentUrl: string, deploymentHash: string): Promise<void>;
83
- updateLocalProxy(proxyUrl: string, storefrontId?: string): Promise<void>;
83
+ updateLocalProxy(proxyUrl: string | null, storefrontId?: string): Promise<void>;
84
84
  watchForChanges({ logChanges, onChange, syncAll, }?: {
85
85
  logChanges?: boolean;
86
86
  onChange?: (appConfig?: AppConfig, result?: any) => void;
@@ -2875,5 +2875,5 @@
2875
2875
  ]
2876
2876
  }
2877
2877
  },
2878
- "version": "2.3.1"
2878
+ "version": "2.3.2"
2879
2879
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.3.1",
3
+ "version": "2.3.2",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [