@ranger1/dx 0.1.96 → 0.1.97

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.
@@ -6,13 +6,8 @@ import { execManager } from '../../exec.js'
6
6
  import { showHelp, showCommandHelp } from '../help.js'
7
7
 
8
8
  export function handleHelp(cli, args = []) {
9
- void cli
10
- if (args[0]) showCommandHelp(args[0])
11
- else showHelp()
12
- }
13
-
14
- export function handleDev(cli, args = []) {
15
- return cli.reportDevCommandRemoved(args)
9
+ if (args[0]) showCommandHelp(args[0], cli)
10
+ else showHelp(cli)
16
11
  }
17
12
 
18
13
  export async function handleBuild(cli, args) {
@@ -24,12 +19,6 @@ export async function handleBuild(cli, args) {
24
19
 
25
20
  const buildConfig = cli.commands.build[target]
26
21
  if (!buildConfig) {
27
- // 兼容用户误输入或快捷命令,把 "all./scripts/dx" 这类粘连错误拆分
28
- const fixed = String(target).split(/\s|\t|\r|\n|\u00A0|\.|\//)[0]
29
- if (fixed && cli.commands.build[fixed]) {
30
- logger.warn(`自动修正构建目标: ${target} -> ${fixed}`)
31
- return await handleBuild(cli, [fixed])
32
- }
33
22
  logger.error(`未找到构建目标: ${target}`)
34
23
  process.exitCode = 1
35
24
  return
@@ -40,14 +29,12 @@ export async function handleBuild(cli, args) {
40
29
  // 处理嵌套配置
41
30
  let config = buildConfig
42
31
  if (typeof config === 'object' && !config.command) {
43
- const supportsCurrentEnv = Boolean(
44
- config[envKey] || (envKey === 'staging' && config.prod),
45
- )
32
+ const supportsCurrentEnv = Boolean(config[envKey])
46
33
  if (explicitEnv && !supportsCurrentEnv) {
47
34
  const envFlag = cli.getEnvironmentFlagExample(envKey) || `--${envKey}`
48
35
  logger.error(`构建目标 ${target} 不支持 ${envFlag} 环境`)
49
36
  logger.info('显式传入环境标志时,必须是该 target 实际支持的环境。')
50
- const available = ['dev', 'staging', 'prod', 'test', 'e2e']
37
+ const available = ['development', 'staging', 'production', 'test', 'e2e']
51
38
  .filter(key => key in config)
52
39
  .map(key => cli.getEnvironmentFlagExample(key) || `--${key}`)
53
40
  if (available.length > 0) {
@@ -61,10 +48,15 @@ export async function handleBuild(cli, args) {
61
48
  return
62
49
  }
63
50
 
64
- // 如果是嵌套配置,尝试获取环境特定的配置(兼容 dev/prod 与 development/production 命名)
51
+ // 严格按显式环境选择配置,不做环境回退
65
52
  if (config[envKey]) config = config[envKey]
66
- else if (envKey === 'staging' && config.prod) config = config.prod
67
- else config = config.dev || config
53
+ else config = null
54
+ }
55
+
56
+ if (!config) {
57
+ logger.error(`构建目标 ${target} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
58
+ process.exitCode = 1
59
+ return
68
60
  }
69
61
 
70
62
  if (config.concurrent) {
@@ -22,7 +22,7 @@ export async function handleDatabase(cli, args) {
22
22
  const envKey = cli.normalizeEnvKey(environment)
23
23
 
24
24
  // 创建迁移只允许在开发环境进行,避免 AI/用户在非开发环境误执行
25
- if (action === 'migrate' && envKey && envKey !== 'dev') {
25
+ if (action === 'migrate' && envKey && envKey !== 'development') {
26
26
  const envFlag = cli.getEnvironmentFlagExample(envKey) || `--${envKey}`
27
27
  logger.error('dx db migrate 仅允许在 --dev 环境下创建迁移')
28
28
  logger.info('请使用 `dx db migrate --dev --name <migration-name>` 创建新迁移。')
@@ -49,10 +49,15 @@ export async function handleDatabase(cli, args) {
49
49
  // 处理嵌套配置
50
50
  let config = dbConfig
51
51
  if (typeof config === 'object' && !config.command) {
52
- // 如果是嵌套配置,尝试获取环境特定的配置(兼容 dev/prod 与 development/production 命名)
52
+ // 严格按显式环境选择配置,不做环境回退
53
53
  if (config[envKey]) config = config[envKey]
54
- else if (envKey === 'staging' && config.prod) config = config.prod
55
- else config = config.dev || config
54
+ else config = null
55
+ }
56
+
57
+ if (!config) {
58
+ logger.error(`数据库操作 ${action} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
59
+ process.exitCode = 1
60
+ return
56
61
  }
57
62
 
58
63
  // 危险操作确认
@@ -71,7 +76,7 @@ export async function handleDatabase(cli, args) {
71
76
 
72
77
  // 支持为 migrate 传入迁移名:--name/-n
73
78
  let command = config.command
74
- if (action === 'migrate' && envKey === 'dev') {
79
+ if (action === 'migrate' && envKey === 'development') {
75
80
  const allArgs = cli.args
76
81
  let migrationName = null
77
82
  // 优先解析显式标志 --name/-n
@@ -123,24 +128,14 @@ export async function handleDatabase(cli, args) {
123
128
  .join('')
124
129
  }
125
130
 
126
- if (action === 'reset' && envKey !== 'prod') {
131
+ if (action === 'reset' && envKey !== 'production') {
127
132
  extraEnv.PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION = 'yes'
128
133
  logger.info('非生产环境重置数据库,已自动确认危险操作: PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION=yes')
129
134
  }
130
135
 
131
- const execFlags = { ...cli.flags }
132
- ;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
133
- key => delete execFlags[key],
134
- )
135
- if (envKey === 'prod') execFlags.prod = true
136
- else if (envKey === 'dev') execFlags.dev = true
137
- else if (envKey === 'test') execFlags.test = true
138
- else if (envKey === 'e2e') execFlags.e2e = true
139
- else if (envKey === 'staging') execFlags.staging = true
140
-
141
136
  await cli.executeCommand(
142
137
  { ...config, command, env: { ...(config.env || {}), ...extraEnv } },
143
- execFlags,
138
+ cli.createExecutionFlags(environment),
144
139
  )
145
140
  }
146
141
 
@@ -177,7 +172,7 @@ export async function handleDatabaseScript(cli, scriptName, envKey, dbConfig) {
177
172
  return
178
173
  }
179
174
 
180
- const environment = envKey === 'dev' ? 'development' : envKey === 'prod' ? 'production' : envKey
175
+ const environment = envKey
181
176
  logger.step(`执行数据库脚本: ${cleanScriptName} (${environment})`)
182
177
  logger.info(`脚本路径: ${scriptPath}`)
183
178
 
@@ -185,12 +180,17 @@ export async function handleDatabaseScript(cli, scriptName, envKey, dbConfig) {
185
180
  let config = dbConfig
186
181
  if (typeof config === 'object' && !config.command) {
187
182
  if (config[envKey]) config = config[envKey]
188
- else if (envKey === 'staging' && config.prod) config = config.prod
189
- else config = config.dev || config
183
+ else config = null
184
+ }
185
+
186
+ if (!config) {
187
+ logger.error(`数据库脚本 ${scriptName} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
188
+ process.exitCode = 1
189
+ return
190
190
  }
191
191
 
192
192
  // 危险操作确认
193
- if (config.dangerous && envKey === 'prod') {
193
+ if (config.dangerous && envKey === 'production') {
194
194
  const confirmed = await confirmManager.confirmDatabaseOperation(
195
195
  `script: ${cleanScriptName}`,
196
196
  envManager.getEnvironmentDescription(environment),
@@ -224,18 +224,8 @@ export async function handleDatabaseScript(cli, scriptName, envKey, dbConfig) {
224
224
  const extraEnv = { NX_CACHE: 'false' }
225
225
  logger.info('为数据库脚本禁用 Nx 缓存: NX_CACHE=false')
226
226
 
227
- const execFlags = { ...cli.flags }
228
- ;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
229
- key => delete execFlags[key],
230
- )
231
- if (envKey === 'prod') execFlags.prod = true
232
- else if (envKey === 'dev') execFlags.dev = true
233
- else if (envKey === 'test') execFlags.test = true
234
- else if (envKey === 'e2e') execFlags.e2e = true
235
- else if (envKey === 'staging') execFlags.staging = true
236
-
237
227
  await cli.executeCommand(
238
228
  { ...config, command, env: { ...(config.env || {}), ...extraEnv } },
239
- execFlags,
229
+ cli.createExecutionFlags(environment),
240
230
  )
241
231
  }
@@ -25,8 +25,13 @@ export async function handleExport(cli, args) {
25
25
  let config = exportConfig
26
26
  if (typeof config === 'object' && !config.command) {
27
27
  if (config[envKey]) config = config[envKey]
28
- else if (envKey === 'staging' && config.prod) config = config.prod
29
- else config = config.dev || config
28
+ else config = null
29
+ }
30
+
31
+ if (!config) {
32
+ logger.error(`导出目标 ${target} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置`)
33
+ process.exitCode = 1
34
+ return
30
35
  }
31
36
 
32
37
  logger.step(`导出 ${target} (${environment})`)
@@ -1,24 +1,11 @@
1
1
  import { logger } from '../../logger.js'
2
2
 
3
3
  export async function handleStart(cli, args) {
4
- const service = args[0] || 'dev'
4
+ const service = args[0] || 'development'
5
5
 
6
6
  const environment = cli.determineEnvironment()
7
7
  const envKey = cli.normalizeEnvKey(environment)
8
-
9
- let rawConfig = cli.commands.start[service]
10
- let configNamespace = 'start'
11
-
12
- if (!rawConfig && cli.commands.dev?.[service]) {
13
- if (envKey !== 'dev') {
14
- logger.error(`目标 ${service} 仅支持开发环境启动,请使用 --dev 或省略环境标志。`)
15
- process.exitCode = 1
16
- return
17
- }
18
- rawConfig = cli.commands.dev[service]
19
- configNamespace = 'dev'
20
- logger.info(`检测到 legacy "dev" 配置,已自动回退至 ${service} 开发脚本。`)
21
- }
8
+ const rawConfig = cli.commands.start[service]
22
9
 
23
10
  if (!rawConfig) {
24
11
  logger.error(`未找到启动配置: ${service}`)
@@ -27,13 +14,17 @@ export async function handleStart(cli, args) {
27
14
  }
28
15
 
29
16
  let startConfig = rawConfig
30
- if (configNamespace === 'start' && rawConfig && typeof rawConfig === 'object') {
31
- if (rawConfig[envKey]) startConfig = rawConfig[envKey]
32
- else if (envKey === 'staging' && rawConfig?.prod) startConfig = rawConfig.prod
17
+ const isRunnableConfig =
18
+ rawConfig &&
19
+ typeof rawConfig === 'object' &&
20
+ (rawConfig.command || rawConfig.internal || rawConfig.concurrent || rawConfig.sequential)
21
+
22
+ if (!isRunnableConfig && rawConfig && typeof rawConfig === 'object') {
23
+ startConfig = rawConfig[envKey] || null
33
24
  }
34
25
 
35
26
  if (!startConfig) {
36
- logger.error(`启动目标 ${service} 未提供 ${environment} 环境配置。`)
27
+ logger.error(`启动目标 ${service} 未提供 ${cli.getEnvironmentFlagExample(envKey) || envKey} 环境配置。`)
37
28
  process.exitCode = 1
38
29
  return
39
30
  }
@@ -41,7 +32,7 @@ export async function handleStart(cli, args) {
41
32
  logger.step(`启动 ${service} 服务 (${environment})`)
42
33
 
43
34
  if (startConfig.concurrent && Array.isArray(startConfig.commands)) {
44
- await cli.handleConcurrentCommands(startConfig.commands, configNamespace, envKey)
35
+ await cli.handleConcurrentCommands(startConfig.commands, 'start', envKey)
45
36
  return
46
37
  }
47
38
 
@@ -52,26 +43,16 @@ export async function handleStart(cli, args) {
52
43
 
53
44
  const ports = cli.collectStartPorts(service, startConfig, envKey)
54
45
 
55
- if (envKey === 'dev' && ports.length > 0) {
46
+ if (envKey === 'development' && ports.length > 0) {
56
47
  logger.info(`开发环境自动清理端口: ${ports.join(', ')}`)
57
48
  }
58
49
 
59
50
  const configToExecute = {
60
51
  ...startConfig,
61
52
  ...(ports.length > 0 ? { ports } : {}),
62
- ...(envKey === 'dev' ? { forcePortCleanup: true } : {}),
53
+ ...(envKey === 'development' ? { forcePortCleanup: true } : {}),
63
54
  }
64
55
 
65
56
  // 为执行阶段构造环境标志,确保 dotenv 选择正确层
66
- const execFlags = { ...cli.flags }
67
- ;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
68
- key => delete execFlags[key]
69
- )
70
- if (envKey === 'prod') execFlags.prod = true
71
- else if (envKey === 'dev') execFlags.dev = true
72
- else if (envKey === 'test') execFlags.test = true
73
- else if (envKey === 'e2e') execFlags.e2e = true
74
- else if (envKey === 'staging') execFlags.staging = true
75
-
76
- await cli.executeCommand(configToExecute, execFlags)
57
+ await cli.executeCommand(configToExecute, cli.createExecutionFlags(environment))
77
58
  }
@@ -64,8 +64,6 @@ export async function handleWorktree(cli, args) {
64
64
  break
65
65
 
66
66
  case 'del':
67
- case 'delete':
68
- case 'rm':
69
67
  // 互斥校验:--all 不能与 issue 编号同时使用
70
68
  // args[0] 是 action,args[1] 开始才是 issue 编号
71
69
  if (cli.flags.all && args.length > 1) {
@@ -131,12 +129,10 @@ export async function handleWorktree(cli, args) {
131
129
  break
132
130
 
133
131
  case 'list':
134
- case 'ls':
135
132
  await worktreeManager.list()
136
133
  break
137
134
 
138
135
  case 'clean':
139
- case 'prune':
140
136
  await worktreeManager.clean()
141
137
  break
142
138
 
package/lib/cli/dx-cli.js CHANGED
@@ -13,10 +13,10 @@ import {
13
13
  import { FLAG_DEFINITIONS, parseFlags } from './flags.js'
14
14
  import { getCleanArgs, getCleanArgsWithConsumedValues } from './args.js'
15
15
  import { showHelp, showCommandHelp } from './help.js'
16
+ import { buildStrictHelpValidationContext, validateHelpConfig } from './help-schema.js'
16
17
  import { getPackageVersion } from '../version.js'
17
18
  import {
18
19
  handleHelp,
19
- handleDev,
20
20
  handleBuild,
21
21
  handleTest,
22
22
  handleLint,
@@ -51,7 +51,6 @@ class DxCli {
51
51
  this.envCache = null
52
52
  this.commandHandlers = {
53
53
  help: args => handleHelp(this, args),
54
- dev: args => handleDev(this, args),
55
54
  start: args => handleStart(this, args),
56
55
  build: args => handleBuild(this, args),
57
56
  test: args => handleTest(this, args),
@@ -70,6 +69,7 @@ class DxCli {
70
69
  }
71
70
 
72
71
  this.flagDefinitions = FLAG_DEFINITIONS
72
+ this.validateLoadedHelpConfig()
73
73
  }
74
74
 
75
75
  // 加载命令配置
@@ -84,6 +84,10 @@ class DxCli {
84
84
  }
85
85
  }
86
86
 
87
+ validateLoadedHelpConfig() {
88
+ validateHelpConfig(this.commands, buildStrictHelpValidationContext(this))
89
+ }
90
+
87
91
  // 检测并安装依赖
88
92
  async ensureDependencies() {
89
93
  const nodeModulesPath = join(process.cwd(), 'node_modules')
@@ -172,22 +176,9 @@ class DxCli {
172
176
  throw new Error('未找到 db.generate 命令配置,请检查 dx/config/commands.json')
173
177
  }
174
178
 
175
- const envKey = this.normalizeEnvKey(environment)
176
- const execFlags = { ...this.flags }
177
- ;['dev', 'development', 'prod', 'production', 'test', 'e2e', 'staging', 'stage'].forEach(
178
- key => {
179
- delete execFlags[key]
180
- },
181
- )
182
- if (envKey === 'prod') execFlags.prod = true
183
- else if (envKey === 'dev') execFlags.dev = true
184
- else if (envKey === 'test') execFlags.test = true
185
- else if (envKey === 'e2e') execFlags.e2e = true
186
- else if (envKey === 'staging') execFlags.staging = true
187
-
188
179
  await execManager.executeCommand(generateConfig.command, {
189
180
  app: generateConfig.app || 'backend',
190
- flags: execFlags,
181
+ flags: this.createExecutionFlags(environment),
191
182
  // Prisma generate 不应卡在环境变量校验上
192
183
  skipEnvValidation: true,
193
184
  })
@@ -286,9 +277,9 @@ class DxCli {
286
277
  // 显示帮助
287
278
  if (this.flags.help || !this.command) {
288
279
  if (this.flags.help && this.command && this.command !== 'help') {
289
- showCommandHelp(this.command)
280
+ showCommandHelp(this.command, this)
290
281
  } else {
291
- showHelp()
282
+ showHelp(this)
292
283
  }
293
284
  return
294
285
  }
@@ -298,7 +289,7 @@ class DxCli {
298
289
  // Fail fast for unknown commands before dependency/env startup checks.
299
290
  if (this.command && !this.commandHandlers[this.command]) {
300
291
  logger.error(`未知命令: ${this.command}`)
301
- showHelp()
292
+ showHelp(this)
302
293
  process.exit(1)
303
294
  }
304
295
 
@@ -346,7 +337,7 @@ class DxCli {
346
337
  const [, ...subArgs] = cleanArgs
347
338
 
348
339
  if (!command) {
349
- showHelp()
340
+ showHelp(this)
350
341
  return
351
342
  }
352
343
 
@@ -504,14 +495,14 @@ class DxCli {
504
495
  case 'worktree': {
505
496
  if (positionalArgs.length === 0) return
506
497
  const action = positionalArgs[0]
507
- if (['del', 'delete', 'rm'].includes(action)) {
498
+ if (action === 'del') {
508
499
  return
509
500
  }
510
- if (['make'].includes(action)) {
501
+ if (action === 'make') {
511
502
  ensureMax(3)
512
503
  break
513
504
  }
514
- if (['list', 'ls', 'clean', 'prune'].includes(action)) {
505
+ if (action === 'list' || action === 'clean') {
515
506
  ensureMax(1)
516
507
  break
517
508
  }
@@ -550,11 +541,8 @@ class DxCli {
550
541
  const value = String(token).toLowerCase()
551
542
  return (
552
543
  value === 'dev' ||
553
- value === 'development' ||
554
544
  value === 'prod' ||
555
- value === 'production' ||
556
545
  value === 'staging' ||
557
- value === 'stage' ||
558
546
  value === 'test' ||
559
547
  value === 'e2e'
560
548
  )
@@ -570,18 +558,19 @@ class DxCli {
570
558
  if (suggestion) {
571
559
  logger.info(`建议命令: ${suggestion}`)
572
560
  } else if (normalizedFlag) {
573
- logger.info(`示例: ${this.invocation} ${command} ... ${normalizedFlag}`)
561
+ logger.info(`示例: ${this.invocation} ${command} ... ${normalizedFlag}`)
574
562
  }
575
563
  logger.info('未显式指定环境时将默认使用 --dev。')
576
564
  process.exit(1)
577
565
  }
578
566
 
579
567
  getEnvironmentFlagExample(token) {
580
- const key = this.normalizeEnvKey(token)
581
- switch (key) {
568
+ switch (String(token || '').toLowerCase()) {
582
569
  case 'dev':
570
+ case 'development':
583
571
  return '--dev'
584
572
  case 'prod':
573
+ case 'production':
585
574
  return '--prod'
586
575
  case 'staging':
587
576
  return '--staging'
@@ -634,13 +623,13 @@ class DxCli {
634
623
  }
635
624
 
636
625
  validateStartPositionals(positionalArgs) {
637
- const service = positionalArgs[0] || 'dev'
626
+ const service = positionalArgs[0] || 'development'
638
627
  const environment = this.determineEnvironment()
639
628
  const envKey = this.normalizeEnvKey(environment)
640
629
 
641
- if (service === 'dev' && envKey !== 'dev') {
630
+ if (service === 'development' && envKey !== 'development') {
642
631
  logger.error('dx start 在未指定服务时仅允许使用开发环境')
643
- logger.info(`示例: ${this.invocation} start all --dev`)
632
+ logger.info(`示例: ${this.invocation} start --dev`)
644
633
  logger.info(`示例: ${this.invocation} start backend --prod`)
645
634
  process.exit(1)
646
635
  }
@@ -649,7 +638,7 @@ class DxCli {
649
638
  if (!startConfig) return
650
639
 
651
640
  // 对 start 下的单层 command 配置,默认视为开发态目标,仅允许 --dev。
652
- if (startConfig.command && envKey !== 'dev') {
641
+ if (startConfig.command && envKey !== 'development') {
653
642
  logger.error(`启动目标 ${service} 仅支持开发环境`)
654
643
  logger.info(`示例: ${this.invocation} start ${service} --dev`)
655
644
  process.exit(1)
@@ -669,13 +658,13 @@ class DxCli {
669
658
  const buildConfig = this.commands?.build?.[target]
670
659
  if (!buildConfig || buildConfig.command) return
671
660
 
672
- const supportsCurrentEnv = Boolean(buildConfig[envKey] || (envKey === 'staging' && buildConfig.prod))
661
+ const supportsCurrentEnv = Boolean(buildConfig[envKey])
673
662
  if (supportsCurrentEnv) return
674
663
 
675
664
  const envFlag = this.getEnvironmentFlagExample(envKey) || `--${envKey}`
676
665
  logger.error(`构建目标 ${target} 不支持 ${envFlag} 环境`)
677
666
  logger.info('显式传入环境标志时,必须是该 target 实际支持的环境。')
678
- const available = ['dev', 'staging', 'prod', 'test', 'e2e']
667
+ const available = ['development', 'staging', 'production', 'test', 'e2e']
679
668
  .filter(key => key in buildConfig)
680
669
  .map(key => this.getEnvironmentFlagExample(key) || `--${key}`)
681
670
  if (available.length > 0) {
@@ -688,19 +677,6 @@ class DxCli {
688
677
  process.exit(1)
689
678
  }
690
679
 
691
- reportDevCommandRemoved(args) {
692
- const target = args?.[0]
693
- logger.error('`dx dev` 命令已移除,统一使用 `dx start`。')
694
- if (target) {
695
- logger.info(`请执行: ${this.invocation} start ${target} --dev`)
696
- } else {
697
- logger.info(`示例: ${this.invocation} start backend --dev`)
698
- logger.info(` ${this.invocation} start front --dev`)
699
- logger.info(` ${this.invocation} start admin --dev`)
700
- }
701
- process.exit(1)
702
- }
703
-
704
680
  reportExtraPositionals(command, extras) {
705
681
  const list = extras.join(', ')
706
682
  if (command === '全局') {
@@ -772,7 +748,7 @@ class DxCli {
772
748
  continue
773
749
  }
774
750
  commands.push({
775
- command: this.applySdkOfflineFlag(config.command),
751
+ command: config.command,
776
752
  options: {
777
753
  app: config.app,
778
754
  ports: config.ports,
@@ -820,22 +796,11 @@ class DxCli {
820
796
  if (environment && config) {
821
797
  const envKey = this.normalizeEnvKey(environment)
822
798
  if (config[envKey]) config = config[envKey]
823
- else if (envKey === 'staging' && config.prod) config = config.prod
824
799
  }
825
800
 
826
801
  return config
827
802
  }
828
803
 
829
- // SDK 构建命令当前不再暴露 --online/--offline 模式,保留该方法仅为兼容旧调用
830
- applySdkModeFlags(command) {
831
- return command
832
- }
833
-
834
- // 向后兼容的别名
835
- applySdkOfflineFlag(command) {
836
- return command
837
- }
838
-
839
804
  collectStartPorts(service, startConfig, envKey) {
840
805
  const portSet = new Set()
841
806
 
@@ -845,15 +810,6 @@ class DxCli {
845
810
  })
846
811
  }
847
812
 
848
- if (envKey === 'dev') {
849
- const legacyConfig = this.commands.dev?.[service]
850
- if (legacyConfig && Array.isArray(legacyConfig.ports)) {
851
- legacyConfig.ports.forEach(port => {
852
- this.addPortToSet(portSet, port)
853
- })
854
- }
855
- }
856
-
857
813
  return Array.from(portSet)
858
814
  }
859
815
 
@@ -936,28 +892,6 @@ class DxCli {
936
892
  }
937
893
 
938
894
  const rawCommand = String(config.command).trim()
939
- // backward compat: old commands.json referenced scripts/lib/*.js in the project
940
- if (rawCommand.startsWith('node scripts/lib/sdk-build.js')) {
941
- const argsText = rawCommand.replace(/^node\s+scripts\/lib\/sdk-build\.js\s*/g, '')
942
- const args = argsText ? argsText.split(/\s+/).filter(Boolean) : []
943
- await withTempEnv(async () => {
944
- const { runSdkBuild } = await import('../sdk-build.js')
945
- await runSdkBuild(args)
946
- })
947
- return
948
- }
949
-
950
- if (rawCommand.startsWith('node scripts/lib/backend-package.js')) {
951
- const argsText = rawCommand.replace(/^node\s+scripts\/lib\/backend-package\.js\s*/g, '')
952
- const args = argsText ? argsText.split(/\s+/).filter(Boolean) : []
953
- await withTempEnv(async () => {
954
- const { runBackendPackage } = await import('../backend-package.js')
955
- await runBackendPackage(args)
956
- })
957
- return
958
- }
959
-
960
- const command = this.applySdkOfflineFlag(rawCommand)
961
895
 
962
896
  const options = {
963
897
  app: config.app,
@@ -969,7 +903,7 @@ class DxCli {
969
903
  forcePortCleanup: Boolean(config.forcePortCleanup),
970
904
  }
971
905
 
972
- await execManager.executeCommand(command, options)
906
+ await execManager.executeCommand(rawCommand, options)
973
907
  }
974
908
 
975
909
  // 确定环境
@@ -977,17 +911,14 @@ class DxCli {
977
911
  return envManager.detectEnvironment(this.flags)
978
912
  }
979
913
 
980
- // 规范化环境键到命令配置使用的命名(dev/prod/test/e2e)
914
+ // 规范化环境键到命令配置使用的命名(development/staging/production/test/e2e)
981
915
  normalizeEnvKey(env) {
982
916
  switch (String(env || '').toLowerCase()) {
983
917
  case 'development':
984
- case 'dev':
985
- return 'dev'
918
+ return 'development'
986
919
  case 'production':
987
- case 'prod':
988
- return 'prod'
920
+ return 'production'
989
921
  case 'staging':
990
- case 'stage':
991
922
  return 'staging'
992
923
  case 'test':
993
924
  return 'test'
@@ -998,6 +929,23 @@ class DxCli {
998
929
  }
999
930
  }
1000
931
 
932
+ createExecutionFlags(environment) {
933
+ const envKey = this.normalizeEnvKey(environment)
934
+ const execFlags = { ...this.flags }
935
+
936
+ ;['dev', 'prod', 'staging', 'test', 'e2e'].forEach(key => {
937
+ delete execFlags[key]
938
+ })
939
+
940
+ if (envKey === 'production') execFlags.prod = true
941
+ else if (envKey === 'development') execFlags.dev = true
942
+ else if (envKey === 'test') execFlags.test = true
943
+ else if (envKey === 'e2e') execFlags.e2e = true
944
+ else if (envKey === 'staging') execFlags.staging = true
945
+
946
+ return execFlags
947
+ }
948
+
1001
949
  }
1002
950
 
1003
951
  export { DxCli }
package/lib/cli/flags.js CHANGED
@@ -1,11 +1,8 @@
1
1
  export const FLAG_DEFINITIONS = {
2
2
  _global: [
3
3
  { flag: '--dev' },
4
- { flag: '--development' },
5
4
  { flag: '--prod' },
6
- { flag: '--production' },
7
5
  { flag: '--staging' },
8
- { flag: '--stage' },
9
6
  { flag: '--test' },
10
7
  { flag: '--e2e' },
11
8
  { flag: '--no-env-check' },
@@ -59,15 +56,12 @@ export function parseFlags(args = []) {
59
56
  if (!flag.startsWith('-')) continue
60
57
  switch (flag) {
61
58
  case '--dev':
62
- case '--development':
63
59
  flags.dev = true
64
60
  break
65
61
  case '--prod':
66
- case '--production':
67
62
  flags.prod = true
68
63
  break
69
64
  case '--staging':
70
- case '--stage':
71
65
  flags.staging = true
72
66
  break
73
67
  case '--test':