@swell/cli 2.3.0 → 2.3.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.
@@ -83,7 +83,7 @@ export default class AppFrontendDev extends PushAppCommand {
83
83
  }
84
84
  // 3. READY DETECTION: Detect server ready, show our message
85
85
  if (!serverReadyDetected &&
86
- (/✓ ready in \d+/.test(string) || /✓ starting/.test(string))) {
86
+ (/✓ ready in \d+/i.test(string) || /✓ starting/i.test(string))) {
87
87
  serverReadyDetected = true;
88
88
  this.log(`Started ${projectType.name} dev server on port ${serverPort}.\n`);
89
89
  const sessionId = localConfig.getSessionId(currentStore);
@@ -168,7 +168,7 @@ behavior by using the --no-git-tag option.`;
168
168
  spinner,
169
169
  });
170
170
  if (!versionResponse || !versionResponse.version) {
171
- spinner.fail('Something went wrong.');
171
+ throw new Error('Something went wrong. Server could not create version.');
172
172
  }
173
173
  // update the local app config file since remote was successful
174
174
  this.swellConfig.set('version', nextVersion);
package/dist/lib/proxy.js CHANGED
@@ -1,8 +1,62 @@
1
+ import { bin, install, Tunnel } from 'cloudflared';
1
2
  import localtunnel from 'localtunnel';
2
3
  import ngrok from 'ngrok';
4
+ import * as fs from 'node:fs';
5
+ import ora from 'ora';
3
6
  import { LOCAL_PROXY_PROVIDER } from './constants.js';
7
+ let activeTunnel = null;
8
+ let cleanupRegistered = false;
9
+ async function startCloudflaredTunnel(port) {
10
+ // Stop existing tunnel if called again
11
+ if (activeTunnel) {
12
+ activeTunnel.stop();
13
+ activeTunnel = null;
14
+ }
15
+ // Ensure cloudflared binary is installed
16
+ if (!fs.existsSync(bin)) {
17
+ const spinner = ora('Installing cloudflared tunnel (first time only)...').start();
18
+ await install(bin);
19
+ spinner.stop();
20
+ }
21
+ // Use Tunnel.quick() for quick tunnels without a Cloudflare account
22
+ const tunnel = Tunnel.quick(`http://localhost:${port}`);
23
+ activeTunnel = tunnel;
24
+ // Wait for the URL to be available
25
+ const url = await new Promise((resolve, reject) => {
26
+ const timeout = setTimeout(() => {
27
+ tunnel.stop();
28
+ activeTunnel = null;
29
+ reject(new Error('Timeout waiting for cloudflared tunnel URL. Check if cloudflared can connect to Cloudflare.'));
30
+ }, 60000);
31
+ tunnel.on('url', (tunnelUrl) => {
32
+ clearTimeout(timeout);
33
+ resolve(tunnelUrl);
34
+ });
35
+ tunnel.on('error', (error) => {
36
+ clearTimeout(timeout);
37
+ activeTunnel = null;
38
+ reject(error);
39
+ });
40
+ });
41
+ // Register cleanup handlers only once, referencing activeTunnel for current tunnel
42
+ if (!cleanupRegistered) {
43
+ cleanupRegistered = true;
44
+ process.on('exit', () => activeTunnel?.stop());
45
+ process.on('SIGINT', () => {
46
+ activeTunnel?.stop();
47
+ // eslint-disable-next-line no-process-exit
48
+ process.exit();
49
+ });
50
+ process.on('SIGTERM', () => {
51
+ activeTunnel?.stop();
52
+ // eslint-disable-next-line no-process-exit
53
+ process.exit();
54
+ });
55
+ }
56
+ return url;
57
+ }
4
58
  export async function getProxyUrl(port) {
5
- const provider = LOCAL_PROXY_PROVIDER || 'localtunnel';
59
+ const provider = LOCAL_PROXY_PROVIDER || 'cloudflared';
6
60
  try {
7
61
  switch (provider) {
8
62
  case 'local': {
@@ -14,16 +68,19 @@ export async function getProxyUrl(port) {
14
68
  region: 'us', // TODO: make it configurable
15
69
  });
16
70
  }
17
- // eslint-disable-next-line unicorn/no-useless-switch-case
18
- case 'localtunnel':
19
- default: {
71
+ case 'localtunnel': {
20
72
  const tunnel = await localtunnel({ port });
21
73
  return tunnel.url;
22
74
  }
75
+ // eslint-disable-next-line unicorn/no-useless-switch-case
76
+ case 'cloudflared':
77
+ default: {
78
+ return await startCloudflaredTunnel(port);
79
+ }
23
80
  }
24
81
  }
25
82
  catch (error) {
26
- console.log(error);
83
+ console.error(error);
27
84
  throw new Error(`Unable to start tunnel on port ${port} (${provider}): ${error.message}`);
28
85
  }
29
86
  }
@@ -2875,5 +2875,5 @@
2875
2875
  ]
2876
2876
  }
2877
2877
  },
2878
- "version": "2.3.0"
2878
+ "version": "2.3.1"
2879
2879
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [
@@ -37,6 +37,7 @@
37
37
  "ajv-formats": "3.0.1",
38
38
  "blake3-wasm": "2.1.5",
39
39
  "chalk": "5.3.0",
40
+ "cloudflared": "0.7.1",
40
41
  "conf": "11.0.2",
41
42
  "configstore": "6.0.0",
42
43
  "esbuild": "0.19.5",