@swell/cli 2.9.25 → 2.9.26

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.
@@ -14,6 +14,8 @@ import { analyzeFunctionSource, hasKindDiagnostic, } from '../../lib/function-so
14
14
  import { detectPackageManager, getExecSpawnArgs, } from '../../lib/package-manager.js';
15
15
  import style from '../../lib/style.js';
16
16
  import { PushAppCommand } from '../../push-app-command.js';
17
+ // How long shutdown waits for the tunnel address to be cleared on the platform
18
+ const UNREGISTER_TIMEOUT_MS = 5000;
17
19
  /**
18
20
  * Headers that show the frontend dev server the public host and scheme, as
19
21
  * managed hosting does. The tunnel replaces both with its own, so without them
@@ -118,7 +120,8 @@ export default class AppDev extends PushAppCommand {
118
120
  // Register cleanup handlers to clear local proxy on exit
119
121
  process.on('SIGINT', this.cleanupOnExit.bind(this));
120
122
  process.on('SIGTERM', this.cleanupOnExit.bind(this));
121
- const serverPort = await this.startProxyServer(port);
123
+ // The handlers above must finish unregistering before the process exits.
124
+ const serverPort = await this.startProxyServer(port, false);
122
125
  await this.startAppFunctionServer(spinner, serverPort);
123
126
  this.emitLifecycleEvent('preview:proxy-ready', {
124
127
  proxyPort: serverPort,
@@ -135,7 +138,14 @@ export default class AppDev extends PushAppCommand {
135
138
  proc.kill();
136
139
  }
137
140
  try {
138
- await this.updateLocalProxy(null, this.storefront?.id);
141
+ // The address can't be cleared while the admin API is unreachable, so
142
+ // don't hold the exit on the request; the platform falls back on its own.
143
+ await Promise.race([
144
+ this.updateLocalProxy(null, this.storefront?.id),
145
+ new Promise((resolve) => {
146
+ setTimeout(resolve, UNREGISTER_TIMEOUT_MS);
147
+ }),
148
+ ]);
139
149
  }
140
150
  catch {
141
151
  // Ignore errors during cleanup
@@ -2,6 +2,7 @@ export interface ProxyContext {
2
2
  appId?: string;
3
3
  storeId?: string;
4
4
  storefrontId?: string;
5
+ handleSignals?: boolean;
5
6
  }
6
7
  /**
7
8
  * Stop the active tunnel (if any) so the process can exit on its own.
package/dist/lib/proxy.js CHANGED
@@ -19,7 +19,7 @@ export function stopProxy() {
19
19
  activeLocaltunnel?.close();
20
20
  activeLocaltunnel = null;
21
21
  }
22
- async function startCloudflaredTunnel(port) {
22
+ async function startCloudflaredTunnel(port, handleSignals = true) {
23
23
  // Stop existing tunnel if called again
24
24
  if (activeTunnel) {
25
25
  activeTunnel.stop();
@@ -56,16 +56,18 @@ async function startCloudflaredTunnel(port) {
56
56
  if (!cleanupRegistered) {
57
57
  cleanupRegistered = true;
58
58
  process.on('exit', () => activeTunnel?.stop());
59
- process.on('SIGINT', () => {
60
- activeTunnel?.stop();
61
- // eslint-disable-next-line no-process-exit
62
- process.exit();
63
- });
64
- process.on('SIGTERM', () => {
65
- activeTunnel?.stop();
66
- // eslint-disable-next-line no-process-exit
67
- process.exit();
68
- });
59
+ if (handleSignals) {
60
+ process.on('SIGINT', () => {
61
+ activeTunnel?.stop();
62
+ // eslint-disable-next-line no-process-exit
63
+ process.exit();
64
+ });
65
+ process.on('SIGTERM', () => {
66
+ activeTunnel?.stop();
67
+ // eslint-disable-next-line no-process-exit
68
+ process.exit();
69
+ });
70
+ }
69
71
  }
70
72
  return url;
71
73
  }
@@ -92,7 +94,7 @@ export async function getProxyUrl(port, context) {
92
94
  // eslint-disable-next-line unicorn/no-useless-switch-case
93
95
  case 'cloudflared':
94
96
  default: {
95
- return await startCloudflaredTunnel(port);
97
+ return await startCloudflaredTunnel(port, context?.handleSignals);
96
98
  }
97
99
  }
98
100
  }
@@ -94,7 +94,7 @@ export declare abstract class PushAppCommand extends RemoteAppCommand {
94
94
  logLocalPreviewUrl(): void;
95
95
  setStoreUser(storeUser: boolean): void;
96
96
  setWatchingFiles(): Promise<void>;
97
- startProxyServer(port?: number): Promise<number>;
97
+ startProxyServer(port?: number, handleSignals?: boolean): Promise<number>;
98
98
  updateFrontendDeployment(currentStore: string, projectType: FrontendProjectType, deploymentUrl: string, deploymentHash: string): Promise<void>;
99
99
  updateLocalProxy(proxyUrl: string | null, storefrontId?: string): Promise<void>;
100
100
  watchForChanges({ logChanges, onChange, syncAll, }?: {
@@ -903,7 +903,7 @@ export class PushAppCommand extends RemoteAppCommand {
903
903
  async setWatchingFiles() {
904
904
  this.watchingFiles = new Set(await globAllFilesByPath(this.appPath));
905
905
  }
906
- async startProxyServer(port) {
906
+ async startProxyServer(port, handleSignals = true) {
907
907
  // Find an open port starting at 3000
908
908
  const freePort = port ||
909
909
  (await getPort({ port: portNumbers(3000, 3100) })) ||
@@ -913,6 +913,7 @@ export class PushAppCommand extends RemoteAppCommand {
913
913
  appId: this.app.id,
914
914
  storeId: localConfig.getDefaultStore(),
915
915
  storefrontId: this.storefront?.id,
916
+ handleSignals,
916
917
  });
917
918
  await this.updateLocalProxy(proxyUrl, this.storefront?.id);
918
919
  return freePort;
@@ -3606,5 +3606,5 @@
3606
3606
  ]
3607
3607
  }
3608
3608
  },
3609
- "version": "2.9.25"
3609
+ "version": "2.9.26"
3610
3610
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.9.25",
3
+ "version": "2.9.26",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [