@swell/cli 2.4.1 → 2.5.0

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,5 +1,5 @@
1
1
  import { Flags } from '@oclif/core';
2
- import { getProjectCommands, } from '../../../lib/apps/index.js';
2
+ import { CUSTOM_FRAMEWORK_SLUG, getManualDevHint, getProjectCommands, } from '../../../lib/apps/index.js';
3
3
  import { default as localConfig } from '../../../lib/config.js';
4
4
  import style from '../../../lib/style.js';
5
5
  import { PushAppCommand } from '../../../push-app-command.js';
@@ -70,6 +70,23 @@ export default class AppFrontendDev extends PushAppCommand {
70
70
  if (!projectType) {
71
71
  return;
72
72
  }
73
+ // Manual mode for unrecognized frameworks
74
+ if (projectType.slug === CUSTOM_FRAMEWORK_SLUG) {
75
+ const hintCommand = getManualDevHint(this.appPath, serverPort);
76
+ const currentStore = localConfig.getDefaultStore();
77
+ const sessionId = localConfig.getSessionId(currentStore);
78
+ this.log(`Detected a frontend project but could not identify the framework.`);
79
+ this.log(`Start your dev server manually on port ${serverPort}:\n`);
80
+ this.log(` cd frontend && ${hintCommand}\n`);
81
+ this.log(`The Swell tunnel is ready and will route traffic once your server is running.\n`);
82
+ this.logAppLocalUrl(currentStore, sessionId);
83
+ if (!isAppDev) {
84
+ this.watchForChanges();
85
+ }
86
+ // Keep the process alive so the tunnel remains open
87
+ await new Promise(() => { });
88
+ return;
89
+ }
73
90
  // Get commands transformed for the detected package manager
74
91
  const { devCommand } = getProjectCommands(this.appPath, projectType);
75
92
  const currentStore = localConfig.getDefaultStore();
@@ -429,7 +429,7 @@ export class CreateAppCommand extends SwellCommand {
429
429
  // Required for yarn workspaces, good practice for all package managers
430
430
  private: true,
431
431
  scripts: {
432
- typecheck: '([ -z "$(find functions -name \'*.ts\' 2>/dev/null | head -1)" ] || tsc --noEmit) && ([ ! -f test/tsconfig.json ] || tsc --noEmit -p test) && ([ ! -f frontend/tsconfig.json ] || tsc --noEmit -p frontend)',
432
+ typecheck: '([ -z "$(find functions -name \'*.ts\' 2>/dev/null | head -1)" ] || tsc --noEmit) && ([ ! -f test/tsconfig.json ] || tsc --build --noEmit test) && ([ ! -f frontend/tsconfig.json ] || tsc --build --noEmit frontend)',
433
433
  },
434
434
  version: config.get('version'),
435
435
  };
@@ -126,6 +126,7 @@ export interface FrontendProjectType {
126
126
  name: string;
127
127
  slug: string;
128
128
  }
129
+ export declare const CUSTOM_FRAMEWORK_SLUG = "custom";
129
130
  export declare const FrontendProjectTypes: FrontendProjectType[];
130
131
  export declare function getFrontendProjectSlugs(withNone?: boolean, withLegacy?: boolean): string[];
131
132
  export declare function getFrontendProjectValidValues(withNone?: boolean, withLegacy?: boolean): string;
@@ -140,6 +141,11 @@ export declare function getProjectCommands(appPath: string, projectType: Fronten
140
141
  buildCommand?: string;
141
142
  devCommand: string;
142
143
  };
144
+ /**
145
+ * Get a suggested dev command for an unrecognized frontend project,
146
+ * translated for the detected package manager.
147
+ */
148
+ export declare function getManualDevHint(appPath: string, port: number): string;
143
149
  export declare function getConfigTypeFromPath(path: string): ConfigType | undefined;
144
150
  export declare function getConfigTypeKeyFromValue(value: string): string | undefined;
145
151
  export declare function filePathExists(filePath: string): boolean;
@@ -114,6 +114,8 @@ export var ConfigInputFields;
114
114
  ConfigInputFields["VALUES"] = "values";
115
115
  ConfigInputFields["VERSION"] = "version";
116
116
  })(ConfigInputFields || (ConfigInputFields = {}));
117
+ // Slug for unrecognized frontend frameworks (manual dev server mode)
118
+ export const CUSTOM_FRAMEWORK_SLUG = 'custom';
117
119
  // Frontend project types - all use direct commands run from frontend/ directory
118
120
  export const FrontendProjectTypes = [
119
121
  {
@@ -198,6 +200,16 @@ export function getFrontendProjectType(appPath) {
198
200
  return detectedType;
199
201
  }
200
202
  }
203
+ // Fallback: if package.json has a dev script, treat as unrecognized framework
204
+ if (pkg.scripts?.dev) {
205
+ return {
206
+ buildCommand: pkg.scripts?.build ? 'npm run build' : '',
207
+ devCommand: '',
208
+ mainPackage: '',
209
+ name: 'Custom',
210
+ slug: CUSTOM_FRAMEWORK_SLUG,
211
+ };
212
+ }
201
213
  }
202
214
  catch {
203
215
  // Ignore JSON parse errors, try next path
@@ -220,6 +232,14 @@ export function getProjectCommands(appPath, projectType) {
220
232
  devCommand: transformCommand(projectType.devCommand, pm),
221
233
  };
222
234
  }
235
+ /**
236
+ * Get a suggested dev command for an unrecognized frontend project,
237
+ * translated for the detected package manager.
238
+ */
239
+ export function getManualDevHint(appPath, port) {
240
+ const pm = detectPackageManager(appPath);
241
+ return transformCommand(`npm run dev -- --port ${port}`, pm);
242
+ }
223
243
  export function getConfigTypeFromPath(path) {
224
244
  for (const type in AllConfigPaths) {
225
245
  if (AllConfigPaths[type] === path) {
@@ -6,7 +6,7 @@ import * as path from 'node:path';
6
6
  import Stream from 'node:stream';
7
7
  import ora from 'ora';
8
8
  import { default as swellConfig } from './lib/app-config.js';
9
- import { ConfigType, getFrontendProjectValidValues, allConfigFilesInDir, appConfigFromFile, filePathExists, filePathExistsAsync, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, getProjectCommands, globAllFilesByPath, hashString, isPathDirectory, } from './lib/apps/index.js';
9
+ import { ConfigType, getFrontendProjectValidValues, allConfigFilesInDir, CUSTOM_FRAMEWORK_SLUG, appConfigFromFile, filePathExists, filePathExistsAsync, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, getProjectCommands, globAllFilesByPath, hashString, isPathDirectory, } from './lib/apps/index.js';
10
10
  import { getGlobIgnorePathsChecker } from './lib/apps/paths.js';
11
11
  import { default as localConfig } from './lib/config.js';
12
12
  import { toAppId } from './lib/create/index.js';
@@ -110,6 +110,14 @@ export class PushAppCommand extends RemoteAppCommand {
110
110
  this.showFrontendMigrationError();
111
111
  return; // unreachable but helps TypeScript narrow the type
112
112
  }
113
+ // Skip automatic build for unrecognized frameworks
114
+ if (projectType.slug === CUSTOM_FRAMEWORK_SLUG) {
115
+ if (projectType.buildCommand) {
116
+ this.log(`Skipping automatic frontend build for unrecognized framework.\n` +
117
+ `Run your build command manually before deploying.\n`);
118
+ }
119
+ return;
120
+ }
113
121
  // Get commands transformed for the detected package manager
114
122
  const { buildCommand } = getProjectCommands(this.appPath, projectType);
115
123
  if (!buildCommand) {
@@ -758,7 +766,9 @@ export class PushAppCommand extends RemoteAppCommand {
758
766
  $environment_id: 'test',
759
767
  frontend: {
760
768
  deployment_hash: deploymentHash,
761
- framework: projectType.slug,
769
+ ...(projectType.slug !== CUSTOM_FRAMEWORK_SLUG && {
770
+ framework: projectType.slug,
771
+ }),
762
772
  service: 'cloudflare',
763
773
  url: deploymentUrl,
764
774
  },
@@ -2937,5 +2937,5 @@
2937
2937
  ]
2938
2938
  }
2939
2939
  },
2940
- "version": "2.4.1"
2940
+ "version": "2.5.0"
2941
2941
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swell/cli",
3
- "version": "2.4.1",
3
+ "version": "2.5.0",
4
4
  "type": "module",
5
5
  "description": "Swell's command line interface/utility",
6
6
  "keywords": [