@swell/cli 2.5.6 → 2.5.8

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.
@@ -1,3 +1,5 @@
1
+ /// <reference types="node" />
2
+ import { ChildProcess } from 'node:child_process';
1
3
  import { PushAppCommand } from '../../push-app-command.js';
2
4
  export default class AppDev extends PushAppCommand {
3
5
  static delayOrientation: boolean;
@@ -16,6 +18,7 @@ export default class AppDev extends PushAppCommand {
16
18
  static summary: string;
17
19
  functionErrors: Map<string, string>;
18
20
  functionPorts: Map<string, number>;
21
+ functionProcesses: Map<string, ChildProcess>;
19
22
  tmpDir: string;
20
23
  frontendPort: number | null;
21
24
  isCleaningUp: boolean;
@@ -50,6 +50,8 @@ export default class AppDev extends PushAppCommand {
50
50
  functionErrors = new Map();
51
51
  // All available functions
52
52
  functionPorts = new Map();
53
+ // Wrangler child processes to kill on cleanup
54
+ functionProcesses = new Map();
53
55
  // Directory for compiled function files and wrangler context
54
56
  tmpDir = '';
55
57
  // Port for frontend dev server (used for routing non-function requests)
@@ -84,6 +86,9 @@ export default class AppDev extends PushAppCommand {
84
86
  if (this.isCleaningUp)
85
87
  return;
86
88
  this.isCleaningUp = true;
89
+ for (const [, proc] of this.functionProcesses) {
90
+ proc.kill();
91
+ }
87
92
  try {
88
93
  await this.updateLocalProxy(null, this.storefront?.id);
89
94
  }
@@ -296,7 +301,9 @@ ENVIRONMENT = "development"
296
301
  // Re-bundle the function
297
302
  const { code } = await bundleFunction(fullPath);
298
303
  // Update the bundled file (wrangler dev will auto-reload)
299
- const bundledPath = path.join(this.tmpDir, `${appConfig.name}.js`);
304
+ const functionDir = path.join(this.tmpDir, `${appConfig.name}`);
305
+ await fs.promises.mkdir(functionDir, { recursive: true });
306
+ const bundledPath = path.join(functionDir, `${appConfig.name}.js`);
300
307
  await fs.promises.writeFile(bundledPath, code);
301
308
  if (this.functionPorts.has(appConfig.name)) {
302
309
  this.log(`\nUpdating function ${appConfig.name}...`);
@@ -355,6 +362,7 @@ ENVIRONMENT = "development"
355
362
  }
356
363
  async startFunctionServers(functions) {
357
364
  const functionStatus = new Map();
365
+ const allocatedFunctionPorts = new Set();
358
366
  const allocatedInspectorPorts = new Set();
359
367
  /* eslint-disable no-await-in-loop */
360
368
  for (const func of functions) {
@@ -363,7 +371,11 @@ ENVIRONMENT = "development"
363
371
  // Function server already running
364
372
  continue;
365
373
  }
366
- const functionPort = await getPort({ port: portNumbers(9000, 9100) });
374
+ const functionPort = await getPort({
375
+ port: portNumbers(9000, 9100),
376
+ exclude: [...allocatedFunctionPorts],
377
+ });
378
+ allocatedFunctionPorts.add(functionPort);
367
379
  const inspectorPort = await getPort({
368
380
  port: portNumbers(9229, 9329),
369
381
  exclude: [...allocatedInspectorPorts],
@@ -373,12 +385,15 @@ ENVIRONMENT = "development"
373
385
  // Bundle the function
374
386
  const fullPath = path.join(this.appPath, func.filePath);
375
387
  const { code } = await bundleFunction(fullPath);
376
- // Write bundled function to tmp directory
377
- const bundledPath = path.join(this.tmpDir, `${functionName}.js`);
388
+ // Each function gets its own directory to avoid wrangler state conflicts
389
+ const functionDir = path.join(this.tmpDir, functionName);
390
+ await fs.promises.mkdir(functionDir, { recursive: true });
391
+ // Write bundled function to its directory
392
+ const bundledPath = path.join(functionDir, `${functionName}.js`);
378
393
  await fs.promises.writeFile(bundledPath, code);
379
394
  // Generate wrangler config
380
395
  const wranglerConfig = this.generateWranglerConfig(functionName, bundledPath);
381
- const configPath = path.join(this.tmpDir, `${functionName}.toml`);
396
+ const configPath = path.join(functionDir, `${functionName}.toml`);
382
397
  await fs.promises.writeFile(configPath, wranglerConfig);
383
398
  functionStatus.set(functionName, 'starting');
384
399
  // Start wrangler process in background using detected package manager
@@ -392,7 +407,7 @@ ENVIRONMENT = "development"
392
407
  `--port=${functionPort}`,
393
408
  `--inspector-port=${inspectorPort}`,
394
409
  ], {
395
- cwd: this.tmpDir,
410
+ cwd: functionDir,
396
411
  // stdio: 'pipe', // Capture output for debugging
397
412
  detached: false,
398
413
  });
@@ -458,7 +473,8 @@ ENVIRONMENT = "development"
458
473
  this.functionErrors.set(functionName, `Process exited with code ${code}`);
459
474
  }
460
475
  });
461
- // Store the port for routing
476
+ // Store the process and port for routing
477
+ this.functionProcesses.set(functionName, wranglerProcess);
462
478
  this.functionPorts.set(functionName, functionPort);
463
479
  }
464
480
  catch (error) {
@@ -503,7 +503,7 @@ export class CreateAppCommand extends SwellCommand {
503
503
  }
504
504
  async addFrontendAllowedHosts(projectType, configPath) {
505
505
  // Configure allowedHosts for frameworks using Vite dev server
506
- // This allows tunneling services (ngrok, localtunnel) to proxy requests to the local dev environment
506
+ // This allows tunneling services (localtunnel) to proxy requests to the local dev environment
507
507
  switch (projectType.slug) {
508
508
  case 'astro': {
509
509
  await this.addAllowedHostsToAstro(configPath);
package/dist/lib/proxy.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { bin, install, Tunnel } from 'cloudflared';
2
2
  import localtunnel from 'localtunnel';
3
- import ngrok from 'ngrok';
4
3
  import * as fs from 'node:fs';
5
4
  import ora from 'ora';
6
5
  import { LOCAL_PROXY_PROVIDER } from './constants.js';
@@ -70,12 +69,6 @@ export async function getProxyUrl(port, context) {
70
69
  case 'local': {
71
70
  return `http://localhost:${port}`;
72
71
  }
73
- case 'ngrok': {
74
- return await ngrok.connect({
75
- addr: port,
76
- region: 'us', // TODO: make it configurable
77
- });
78
- }
79
72
  case 'localtunnel': {
80
73
  const tunnel = await localtunnel({ port });
81
74
  return tunnel.url;
@@ -100,6 +100,7 @@ declare class SwellRequest {
100
100
  getIngestableLogs(response: any): {
101
101
  params: any;
102
102
  } | undefined;
103
+ formatRequestData(): string;
103
104
  ingestLogs(response: any): Promise<void>;
104
105
  /**
105
106
  * Merge values into app data for the current request.
@@ -170,12 +170,22 @@ class SwellRequest {
170
170
  ...this.logParams,
171
171
  message: {
172
172
  ...this.logParams?.message,
173
+ data: this.logParams?.message?.data || this.formatRequestData(),
173
174
  logs: this._logs,
174
175
  status: response.status,
175
176
  },
176
177
  },
177
178
  };
178
179
  }
180
+ formatRequestData() {
181
+ try {
182
+ const stringData = JSON.stringify(this.body ?? null);
183
+ return stringData.substring(0, 1024000);
184
+ }
185
+ catch {
186
+ return '';
187
+ }
188
+ }
179
189
  async ingestLogs(response) {
180
190
  const ingestableLogs = this.getIngestableLogs(response);
181
191
  if (!ingestableLogs) {
@@ -2969,5 +2969,5 @@
2969
2969
  ]
2970
2970
  }
2971
2971
  },
2972
- "version": "2.5.6"
2972
+ "version": "2.5.8"
2973
2973
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.5.6",
3
+ "version": "2.5.8",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [
@@ -51,7 +51,6 @@
51
51
  "localtunnel": "2.0.2",
52
52
  "lodash": "4.17.21",
53
53
  "mime-detect": "1.2.0",
54
- "ngrok": "5.0.0-beta.2",
55
54
  "node-fetch": "3.3.2",
56
55
  "oclif": "4.0.3",
57
56
  "open": "9.1.0",