@ranger1/dx 0.1.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.
- package/LICENSE +21 -0
- package/README.md +103 -0
- package/bin/dx-with-version-env.js +8 -0
- package/bin/dx.js +86 -0
- package/lib/backend-package.js +664 -0
- package/lib/cli/args.js +19 -0
- package/lib/cli/commands/core.js +233 -0
- package/lib/cli/commands/db.js +239 -0
- package/lib/cli/commands/deploy.js +76 -0
- package/lib/cli/commands/export.js +34 -0
- package/lib/cli/commands/package.js +22 -0
- package/lib/cli/commands/stack.js +451 -0
- package/lib/cli/commands/start.js +83 -0
- package/lib/cli/commands/worktree.js +149 -0
- package/lib/cli/dx-cli.js +864 -0
- package/lib/cli/flags.js +96 -0
- package/lib/cli/help.js +209 -0
- package/lib/cli/index.js +4 -0
- package/lib/confirm.js +213 -0
- package/lib/env.js +296 -0
- package/lib/exec.js +643 -0
- package/lib/logger.js +188 -0
- package/lib/run-with-version-env.js +173 -0
- package/lib/sdk-build.js +424 -0
- package/lib/start-dev.js +401 -0
- package/lib/telegram-webhook.js +134 -0
- package/lib/validate-env.js +284 -0
- package/lib/vercel-deploy.js +237 -0
- package/lib/worktree.js +1032 -0
- package/package.json +34 -0
package/lib/cli/flags.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export const FLAG_DEFINITIONS = {
|
|
2
|
+
_global: [
|
|
3
|
+
{ flag: '--dev' },
|
|
4
|
+
{ flag: '--development' },
|
|
5
|
+
{ flag: '--prod' },
|
|
6
|
+
{ flag: '--production' },
|
|
7
|
+
{ flag: '--staging' },
|
|
8
|
+
{ flag: '--stage' },
|
|
9
|
+
{ flag: '--test' },
|
|
10
|
+
{ flag: '--e2e' },
|
|
11
|
+
{ flag: '--no-env-check' },
|
|
12
|
+
{ flag: '-Y' },
|
|
13
|
+
{ flag: '--yes' },
|
|
14
|
+
{ flag: '-v' },
|
|
15
|
+
{ flag: '--verbose' },
|
|
16
|
+
{ flag: '-h' },
|
|
17
|
+
{ flag: '--help' },
|
|
18
|
+
{ flag: '--parallel' },
|
|
19
|
+
{ flag: '-P' },
|
|
20
|
+
],
|
|
21
|
+
db: [
|
|
22
|
+
{ flag: '--name', expectsValue: true },
|
|
23
|
+
{ flag: '-n', expectsValue: true },
|
|
24
|
+
],
|
|
25
|
+
test: [{ flag: '-t', expectsValue: true }],
|
|
26
|
+
package: [
|
|
27
|
+
{ flag: '--skip-build' },
|
|
28
|
+
{ flag: '--keep-workdir' },
|
|
29
|
+
],
|
|
30
|
+
worktree: [
|
|
31
|
+
{ flag: '--base', expectsValue: true },
|
|
32
|
+
{ flag: '-b', expectsValue: true },
|
|
33
|
+
{ flag: '--all' },
|
|
34
|
+
],
|
|
35
|
+
lint: [
|
|
36
|
+
{ flag: '--fix' },
|
|
37
|
+
],
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function parseFlags(args = []) {
|
|
41
|
+
const flags = {}
|
|
42
|
+
|
|
43
|
+
for (const flag of args) {
|
|
44
|
+
if (flag === '--') break
|
|
45
|
+
if (!flag.startsWith('-')) continue
|
|
46
|
+
switch (flag) {
|
|
47
|
+
case '--dev':
|
|
48
|
+
case '--development':
|
|
49
|
+
flags.dev = true
|
|
50
|
+
break
|
|
51
|
+
case '--prod':
|
|
52
|
+
case '--production':
|
|
53
|
+
flags.prod = true
|
|
54
|
+
break
|
|
55
|
+
case '--staging':
|
|
56
|
+
case '--stage':
|
|
57
|
+
flags.staging = true
|
|
58
|
+
break
|
|
59
|
+
case '--test':
|
|
60
|
+
flags.test = true
|
|
61
|
+
break
|
|
62
|
+
case '--e2e':
|
|
63
|
+
flags.e2e = true
|
|
64
|
+
break
|
|
65
|
+
case '-Y':
|
|
66
|
+
case '--yes':
|
|
67
|
+
flags.Y = true
|
|
68
|
+
break
|
|
69
|
+
case '-v':
|
|
70
|
+
case '--verbose':
|
|
71
|
+
flags.verbose = true
|
|
72
|
+
break
|
|
73
|
+
case '-h':
|
|
74
|
+
case '--help':
|
|
75
|
+
flags.help = true
|
|
76
|
+
break
|
|
77
|
+
case '--no-env-check':
|
|
78
|
+
flags.noEnvCheck = true
|
|
79
|
+
break
|
|
80
|
+
case '--fix':
|
|
81
|
+
flags.fix = true
|
|
82
|
+
break
|
|
83
|
+
case '--parallel':
|
|
84
|
+
case '-P':
|
|
85
|
+
flags.parallel = true
|
|
86
|
+
break
|
|
87
|
+
case '--all':
|
|
88
|
+
flags.all = true
|
|
89
|
+
break
|
|
90
|
+
default:
|
|
91
|
+
break
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return flags
|
|
96
|
+
}
|
package/lib/cli/help.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
export function showHelp() {
|
|
2
|
+
console.log(`
|
|
3
|
+
DX CLI - 统一开发环境管理工具
|
|
4
|
+
|
|
5
|
+
用法:
|
|
6
|
+
dx <命令> [选项] [参数...]
|
|
7
|
+
|
|
8
|
+
命令:
|
|
9
|
+
start [service] [环境标志] 启动/桥接服务
|
|
10
|
+
service: backend, front, admin, all, dev, stack, stagewise-front, stagewise-admin (默认: dev)
|
|
11
|
+
stack: PM2 交互式服务栈管理(推荐)- 同时启动三个服务并提供交互式命令
|
|
12
|
+
环境标志: --dev, --staging, --prod, --test, --e2e(支持别名 --development、--production 等)
|
|
13
|
+
说明: 传入 --staging 时会加载 '.env.staging(.local)' 层,同时复用生产构建/启动流程
|
|
14
|
+
|
|
15
|
+
build [target] [环境标志] 构建应用
|
|
16
|
+
target: backend, shared, front, admin, mobile, all, sdk, affected (默认: all)
|
|
17
|
+
环境标志: --dev, --staging, --prod, --test, --e2e(未指定时默认 --dev)
|
|
18
|
+
|
|
19
|
+
deploy <target> [环境标志] 部署前端到 Vercel
|
|
20
|
+
target: front, admin, telegram-bot, all
|
|
21
|
+
环境标志: --dev, --staging, --prod(默认 --staging)
|
|
22
|
+
|
|
23
|
+
install 安装依赖(使用 frozen-lockfile 确保版本一致)
|
|
24
|
+
|
|
25
|
+
package backend [环境标志] 构建后端部署包(生成 backend-<version>-<sha>.tar.gz)
|
|
26
|
+
环境标志: --dev, --staging, --prod, --test, --e2e(默认 --dev)
|
|
27
|
+
产物位置: dist/backend/backend-*.tar.gz
|
|
28
|
+
内含: dist/、node_modules(生产依赖)、prisma/、config/.env.runtime、bin/start.sh
|
|
29
|
+
|
|
30
|
+
db [action] [环境标志] 数据库操作
|
|
31
|
+
action: generate, migrate, deploy, reset, seed, format, script
|
|
32
|
+
用法示例:
|
|
33
|
+
dx db migrate --dev --name add_user_table # 创建新的迁移(开发环境需指定名称)
|
|
34
|
+
dx db deploy --dev # 应用开发环境已有迁移
|
|
35
|
+
dx db deploy --prod # 生产环境迁移(复用 deploy 流程,需确认)
|
|
36
|
+
dx db script fix-email-verified-status --dev # 运行数据库脚本(开发环境)
|
|
37
|
+
dx db script fix-pending-transfer-status --prod # 运行数据库脚本(生产环境,需确认)
|
|
38
|
+
dx db script my-script --dev -- --arg1 --arg2 # 向脚本传递额外参数(-- 后面的部分)
|
|
39
|
+
|
|
40
|
+
test [type] [target] [path] [-t pattern] 运行测试
|
|
41
|
+
type: e2e, unit (默认: e2e)
|
|
42
|
+
target: backend, all (默认: all)
|
|
43
|
+
path: 测试文件路径 (可选,仅支持e2e backend)
|
|
44
|
+
-t pattern: 指定测试用例名称模式 (可选,需要和path一起使用)
|
|
45
|
+
|
|
46
|
+
worktree [action] [num...] Git Worktree管理
|
|
47
|
+
action: make, del, list, clean
|
|
48
|
+
num: issue编号 (make时需要1个,del时支持多个)
|
|
49
|
+
支持批量删除: dx worktree del 123 456 789
|
|
50
|
+
支持非交互式: dx worktree del 123 -Y
|
|
51
|
+
注意:该封装与原生 git worktree 行为不同,勿混用
|
|
52
|
+
|
|
53
|
+
lint 运行代码检查
|
|
54
|
+
|
|
55
|
+
clean [target] 清理操作
|
|
56
|
+
target: all, deps (默认: all)
|
|
57
|
+
|
|
58
|
+
cache [action] 缓存清理
|
|
59
|
+
action: clear (默认: clear)
|
|
60
|
+
|
|
61
|
+
status 查看系统状态
|
|
62
|
+
|
|
63
|
+
选项:
|
|
64
|
+
--dev, --development 使用开发环境
|
|
65
|
+
--prod, --production 使用生产环境
|
|
66
|
+
--staging, --stage 使用预发环境(加载 .env.staging*.,复用生产流程)
|
|
67
|
+
--test 使用测试环境
|
|
68
|
+
--e2e 使用E2E测试环境
|
|
69
|
+
-Y, --yes 跳过所有确认提示
|
|
70
|
+
-v, --verbose 详细输出
|
|
71
|
+
-h, --help 显示此帮助信息
|
|
72
|
+
|
|
73
|
+
示例:
|
|
74
|
+
dx start stack # PM2 交互式服务栈(推荐)- 同时管理三个服务
|
|
75
|
+
dx start backend --dev # 启动后端开发服务
|
|
76
|
+
dx start front --dev # 启动用户前端开发服务
|
|
77
|
+
dx start admin --dev # 启动管理后台开发服务
|
|
78
|
+
dx start all # 同时启动所有开发服务(默认 --dev)
|
|
79
|
+
dx build all --prod # 构建所有应用(生产环境)
|
|
80
|
+
dx db deploy --dev # 应用开发环境数据库迁移
|
|
81
|
+
dx db reset --prod -Y # 重置生产数据库(跳过确认)
|
|
82
|
+
dx test e2e backend # 运行后端E2E测试
|
|
83
|
+
dx test e2e backend e2e/activity/activity.admin.e2e-spec.ts # 运行单个E2E测试文件
|
|
84
|
+
dx test e2e backend e2e/activity/activity.admin.e2e-spec.ts -t "should list all activity definitions" # 运行特定测试用例
|
|
85
|
+
dx deploy front --staging # 部署前端到 Vercel(staging)
|
|
86
|
+
dx worktree make 88 # 为issue #88创建worktree
|
|
87
|
+
dx worktree del 88 # 删除issue #88的worktree
|
|
88
|
+
dx worktree del 88 89 90 -Y # 批量删除多个worktree(非交互式)
|
|
89
|
+
dx worktree list # 列出所有worktree
|
|
90
|
+
dx clean deps # 清理并重新安装依赖
|
|
91
|
+
dx cache clear # 清除 Nx 与依赖缓存
|
|
92
|
+
|
|
93
|
+
# Stagewise 桥接(固定端口,自动清理占用)
|
|
94
|
+
dx start stagewise-front # 桥接 front: 3001 -> 3002(工作目录 apps/front)
|
|
95
|
+
dx start stagewise-admin # 桥接 admin-front: 3500 -> 3501(工作目录 apps/admin-front)
|
|
96
|
+
|
|
97
|
+
# Start 用法示例
|
|
98
|
+
dx start backend --prod # 以生产环境变量启动后端
|
|
99
|
+
dx start backend --dev # 以开发环境变量启动后端
|
|
100
|
+
dx start backend --e2e # 以 E2E 环境变量启动后端
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
`)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function showCommandHelp(command) {
|
|
107
|
+
const name = String(command || '').toLowerCase()
|
|
108
|
+
|
|
109
|
+
switch (name) {
|
|
110
|
+
case 'build':
|
|
111
|
+
console.log(`
|
|
112
|
+
build 命令用法:
|
|
113
|
+
dx build <target> [环境标志]
|
|
114
|
+
|
|
115
|
+
参数说明:
|
|
116
|
+
target: backend, front, admin, shared, mobile, sdk, all, affected
|
|
117
|
+
环境标志: --dev、--staging、--prod、--test、--e2e(默认 --dev)
|
|
118
|
+
|
|
119
|
+
常见示例:
|
|
120
|
+
dx build backend --staging # 使用 staging 环境变量构建后端 (prod 流程)
|
|
121
|
+
dx build front --prod # 强制以生产配置构建前端
|
|
122
|
+
dx build mobile --staging # 构建移动端 APK (staging 环境)
|
|
123
|
+
dx build mobile --prod # 构建移动端 APK (生产环境)
|
|
124
|
+
dx build affected --dev # 针对受影响项目执行开发态构建
|
|
125
|
+
|
|
126
|
+
提示: 可通过 dx build <target> 分别构建受影响应用。
|
|
127
|
+
`)
|
|
128
|
+
return
|
|
129
|
+
|
|
130
|
+
case 'db':
|
|
131
|
+
console.log(`
|
|
132
|
+
db 命令用法:
|
|
133
|
+
dx db <action> [options]
|
|
134
|
+
|
|
135
|
+
可选 action:
|
|
136
|
+
generate | migrate | deploy | reset | seed | format | script
|
|
137
|
+
|
|
138
|
+
环境说明:
|
|
139
|
+
通过 --dev、--staging、--prod、--test、--e2e 指定 APP_ENV(默认 --dev)
|
|
140
|
+
--staging 会加载 .env.staging*. 文件,并复用 prod 的 Prisma / Nx 流程
|
|
141
|
+
|
|
142
|
+
附加参数:
|
|
143
|
+
--name/-n <migration-name> # 开发环境执行 migrate 必填,禁止通过位置参数传递
|
|
144
|
+
|
|
145
|
+
帮助提示:
|
|
146
|
+
- 未提供迁移名称时命令会直接报错退出,避免 Prisma 进入交互式输入
|
|
147
|
+
- 使用模式示例: dx db migrate --dev --name init-user-table
|
|
148
|
+
- 如需仅执行已有迁移(本地/CI/生产),请使用 dx db deploy(无需 --name)
|
|
149
|
+
|
|
150
|
+
script 子命令:
|
|
151
|
+
dx db script <script-name> [环境标志] [-- <脚本参数>...]
|
|
152
|
+
运行位于 apps/backend/prisma/scripts/ 目录下的数据库脚本
|
|
153
|
+
|
|
154
|
+
脚本参数说明:
|
|
155
|
+
使用 -- 分隔符后可传递任意参数给目标脚本
|
|
156
|
+
例如: dx db script my-script --dev -- --skip-cleanup --note="test"
|
|
157
|
+
|
|
158
|
+
示例:
|
|
159
|
+
dx db migrate --dev --name init-user-table # 创建新迁移(开发环境)
|
|
160
|
+
dx db deploy --dev # 应用开发环境已有迁移
|
|
161
|
+
dx db deploy --staging # 复用生产命令,加载 staging 环境变量
|
|
162
|
+
dx db reset --prod -Y # 生产环境重置 (需确认)
|
|
163
|
+
dx db script fix-email-verified-status --dev # 运行数据库脚本(开发环境)
|
|
164
|
+
dx db script fix-pending-transfer-status --prod -Y # 运行数据库脚本(生产环境,跳过确认)
|
|
165
|
+
dx db script guest-cleanup-verification --dev -- --help # 查看脚本帮助
|
|
166
|
+
dx db script guest-cleanup-verification --dev -- --skip-cleanup --note="dry run" # 传递脚本参数
|
|
167
|
+
`)
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
case 'deploy':
|
|
171
|
+
console.log(`
|
|
172
|
+
deploy 命令用法:
|
|
173
|
+
dx deploy <target> [环境标志]
|
|
174
|
+
|
|
175
|
+
参数说明:
|
|
176
|
+
target: front, admin, telegram-bot, all
|
|
177
|
+
环境标志: --dev、--staging、--prod(默认 --staging)
|
|
178
|
+
|
|
179
|
+
常见示例:
|
|
180
|
+
dx deploy front --staging # 部署用户前端(staging)
|
|
181
|
+
dx deploy admin --prod # 部署管理后台(生产)
|
|
182
|
+
dx deploy telegram-bot --staging # 部署 Telegram Bot + 自动配置 Webhook
|
|
183
|
+
dx deploy all --staging # 串行部署 front + admin
|
|
184
|
+
`)
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
case 'start':
|
|
188
|
+
console.log(`
|
|
189
|
+
start 命令用法:
|
|
190
|
+
dx start <service> [环境标志]
|
|
191
|
+
|
|
192
|
+
服务说明:
|
|
193
|
+
service: backend, dev, stagewise-front, stagewise-admin
|
|
194
|
+
|
|
195
|
+
环境说明:
|
|
196
|
+
支持 --dev、--staging、--prod、--test、--e2e。--staging 会注入 .env.staging*. 层并复用 prod 启动流程
|
|
197
|
+
|
|
198
|
+
常见示例:
|
|
199
|
+
dx start backend --staging # 使用 staging 配置启动后端 (生产模式流程)
|
|
200
|
+
dx start stagewise-front # Stagewise 桥接用户前端,端口 3001 -> 3002
|
|
201
|
+
|
|
202
|
+
提示: service 省略时默认启动 dev 套件,可结合 --dev/--staging/--prod 标志使用。
|
|
203
|
+
`)
|
|
204
|
+
return
|
|
205
|
+
|
|
206
|
+
default:
|
|
207
|
+
showHelp()
|
|
208
|
+
}
|
|
209
|
+
}
|
package/lib/cli/index.js
ADDED
package/lib/confirm.js
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline'
|
|
2
|
+
import { logger } from './logger.js'
|
|
3
|
+
|
|
4
|
+
export class ConfirmManager {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.rl = null
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// 判断是否启用自动确认(CI 或显式环境变量)
|
|
10
|
+
isAutoYes(skipFlag = false) {
|
|
11
|
+
if (skipFlag) return true
|
|
12
|
+
const ci = String(process.env.CI || '').toLowerCase()
|
|
13
|
+
const autoYes = String(process.env.AI_CLI_YES || process.env.YES || '').toLowerCase()
|
|
14
|
+
// 常见 CI 环境会设置 CI=true;也支持自定义 AI_CLI_YES/YES 变量
|
|
15
|
+
return ci === 'true' || ci === '1' || autoYes === 'true' || autoYes === '1'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 基础确认
|
|
19
|
+
async confirm(message, defaultValue = false, skipFlag = false) {
|
|
20
|
+
if (this.isAutoYes(skipFlag)) {
|
|
21
|
+
logger.info(`跳过确认: ${message}`)
|
|
22
|
+
return true
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const prompt = defaultValue ? `${message} [Y/n]: ` : `${message} [y/N]: `
|
|
26
|
+
|
|
27
|
+
return new Promise(resolve => {
|
|
28
|
+
this.rl = createInterface({
|
|
29
|
+
input: process.stdin,
|
|
30
|
+
output: process.stdout,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
this.rl.question(prompt, answer => {
|
|
34
|
+
this.rl.close()
|
|
35
|
+
|
|
36
|
+
const normalized = answer.toLowerCase().trim()
|
|
37
|
+
if (normalized === '') {
|
|
38
|
+
resolve(defaultValue)
|
|
39
|
+
} else {
|
|
40
|
+
resolve(['y', 'yes', '是', 'true', '1'].includes(normalized))
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 危险操作确认
|
|
47
|
+
async confirmDangerous(operation, environment = 'unknown', skipFlag = false) {
|
|
48
|
+
if (this.isAutoYes(skipFlag)) {
|
|
49
|
+
logger.warn(`跳过危险操作确认: ${operation}`)
|
|
50
|
+
return true
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
logger.separator()
|
|
54
|
+
logger.warn('警告: 即将执行危险操作')
|
|
55
|
+
console.log(`操作: ${operation}`)
|
|
56
|
+
console.log(`环境: ${environment}`)
|
|
57
|
+
|
|
58
|
+
if (environment === 'production' || environment === '生产环境') {
|
|
59
|
+
console.log(`🔥 此操作将在生产环境执行,可能导致数据丢失或服务中断`)
|
|
60
|
+
console.log(`🔥 请确保您已经:`)
|
|
61
|
+
console.log(` 1. 备份了重要数据`)
|
|
62
|
+
console.log(` 2. 通知了相关团队成员`)
|
|
63
|
+
console.log(` 3. 确认了操作的必要性`)
|
|
64
|
+
} else {
|
|
65
|
+
console.log(`此操作可能导致数据丢失,请谨慎操作`)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
logger.separator()
|
|
69
|
+
|
|
70
|
+
// 对于生产环境,需要两次确认
|
|
71
|
+
if (environment === 'production' || environment === '生产环境') {
|
|
72
|
+
const firstConfirm = await this.confirm('您确定要在生产环境执行此危险操作吗?', false, false)
|
|
73
|
+
if (!firstConfirm) {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`\n请再次确认,输入操作名称以继续: ${operation}`)
|
|
78
|
+
return new Promise(resolve => {
|
|
79
|
+
this.rl = createInterface({
|
|
80
|
+
input: process.stdin,
|
|
81
|
+
output: process.stdout,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
this.rl.question('请输入操作名称: ', answer => {
|
|
85
|
+
this.rl.close()
|
|
86
|
+
resolve(answer.trim() === operation)
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
} else {
|
|
90
|
+
return this.confirm('确定要继续吗?', false, false)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 批量操作确认
|
|
95
|
+
async confirmBatch(operations, skipFlag = false) {
|
|
96
|
+
if (this.isAutoYes(skipFlag)) {
|
|
97
|
+
logger.info('跳过批量操作确认')
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
logger.separator()
|
|
102
|
+
console.log('即将执行以下操作:')
|
|
103
|
+
operations.forEach((op, index) => {
|
|
104
|
+
console.log(`${index + 1}. ${op}`)
|
|
105
|
+
})
|
|
106
|
+
logger.separator()
|
|
107
|
+
|
|
108
|
+
return this.confirm('确认执行所有操作?', false, false)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 端口冲突确认
|
|
112
|
+
async confirmPortCleanup(port, processes, skipFlag = false) {
|
|
113
|
+
if (this.isAutoYes(skipFlag)) {
|
|
114
|
+
logger.info(`跳过端口清理确认: 端口 ${port}`)
|
|
115
|
+
return true
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
logger.warn(`端口 ${port} 被以下进程占用:`)
|
|
119
|
+
processes.forEach(pid => {
|
|
120
|
+
console.log(` 进程 ID: ${pid}`)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
return this.confirm(`是否杀死这些进程以释放端口 ${port}?`, true, false)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 环境切换确认
|
|
127
|
+
async confirmEnvironmentSwitch(from, to, skipFlag = false) {
|
|
128
|
+
if (this.isAutoYes(skipFlag)) {
|
|
129
|
+
logger.info(`跳过环境切换确认: ${from} -> ${to}`)
|
|
130
|
+
return true
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (to === 'production' || to === '生产环境') {
|
|
134
|
+
logger.warn(`即将从 ${from} 切换到 ${to}`)
|
|
135
|
+
logger.warn('生产环境操作需要额外谨慎')
|
|
136
|
+
return this.confirm('确定要切换到生产环境吗?', false, false)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return this.confirm(`确定要从 ${from} 切换到 ${to} 吗?`, true, false)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// 文件覆盖确认
|
|
143
|
+
async confirmOverwrite(filePath, skipFlag = false) {
|
|
144
|
+
if (this.isAutoYes(skipFlag)) {
|
|
145
|
+
logger.info(`跳过文件覆盖确认: ${filePath}`)
|
|
146
|
+
return true
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
logger.warn(`文件已存在: ${filePath}`)
|
|
150
|
+
return this.confirm('是否覆盖现有文件?', false, false)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 清理操作确认
|
|
154
|
+
async confirmCleanup(targets, skipFlag = false) {
|
|
155
|
+
if (this.isAutoYes(skipFlag)) {
|
|
156
|
+
logger.info('跳过清理操作确认')
|
|
157
|
+
return true
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
logger.warn('即将清理以下内容:')
|
|
161
|
+
targets.forEach(target => {
|
|
162
|
+
console.log(` - ${target}`)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
return this.confirm('确定要执行清理操作吗?', false, false)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 服务启动确认(用于可能有端口冲突的情况)
|
|
169
|
+
async confirmServiceStart(service, port, skipFlag = false) {
|
|
170
|
+
if (this.isAutoYes(skipFlag)) {
|
|
171
|
+
return true
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return this.confirm(`确定要启动 ${service} 服务 (端口 ${port}) 吗?`, true, false)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// 版本发布确认
|
|
178
|
+
async confirmRelease(version, isProduction = false, skipFlag = false) {
|
|
179
|
+
if (this.isAutoYes(skipFlag)) {
|
|
180
|
+
logger.info(`跳过版本发布确认: ${version}`)
|
|
181
|
+
return true
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (isProduction) {
|
|
185
|
+
logger.warn(`即将发布生产版本: ${version}`)
|
|
186
|
+
logger.warn('此操作将创建正式发布标签')
|
|
187
|
+
return this.confirmDangerous(`发布版本 ${version}`, '生产环境', false)
|
|
188
|
+
} else {
|
|
189
|
+
return this.confirm(`确定要发布开发版本 ${version} 吗?`, true, false)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// 数据库操作确认
|
|
194
|
+
async confirmDatabaseOperation(operation, environment, skipFlag = false) {
|
|
195
|
+
const dangerousOps = ['reset', 'drop', 'migrate:reset', 'db:reset']
|
|
196
|
+
const isDangerous = dangerousOps.some(op => operation.includes(op))
|
|
197
|
+
|
|
198
|
+
if (isDangerous) {
|
|
199
|
+
return this.confirmDangerous(
|
|
200
|
+
`数据库操作: ${operation}`,
|
|
201
|
+
environment,
|
|
202
|
+
this.isAutoYes(skipFlag),
|
|
203
|
+
)
|
|
204
|
+
} else {
|
|
205
|
+
if (this.isAutoYes(skipFlag)) {
|
|
206
|
+
return true
|
|
207
|
+
}
|
|
208
|
+
return this.confirm(`确定要执行数据库操作: ${operation} (${environment}) 吗?`, true, false)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export const confirmManager = new ConfirmManager()
|