@ranger1/dx 0.1.75 → 0.1.77

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.
@@ -136,6 +136,46 @@ install_pnpm() {
136
136
  fi
137
137
  }
138
138
 
139
+ persist_user_local_bin_path() {
140
+ local line='export PATH="$HOME/.local/bin:$PATH"'
141
+ local rc
142
+ for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do
143
+ if [[ -f "$rc" ]]; then
144
+ if ! grep -F "$line" "$rc" >/dev/null 2>&1; then
145
+ printf '\n%s\n' "$line" >>"$rc"
146
+ fi
147
+ fi
148
+ done
149
+ }
150
+
151
+ expose_dx_globally() {
152
+ local source_dx="$1"
153
+ local target_dir target_path
154
+
155
+ if [[ ! -x "$source_dx" ]]; then
156
+ echo "dx 源可执行文件不存在:$source_dx" >&2
157
+ return 1
158
+ fi
159
+
160
+ target_dir=""
161
+ if [[ -w "/usr/local/bin" ]]; then
162
+ target_dir="/usr/local/bin"
163
+ elif [[ -w "/opt/homebrew/bin" ]]; then
164
+ target_dir="/opt/homebrew/bin"
165
+ else
166
+ target_dir="$HOME/.local/bin"
167
+ mkdir -p "$target_dir"
168
+ if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
169
+ export PATH="$HOME/.local/bin:$PATH"
170
+ fi
171
+ persist_user_local_bin_path
172
+ fi
173
+
174
+ target_path="$target_dir/dx"
175
+ ln -sf "$source_dx" "$target_path"
176
+ command -v dx >/dev/null 2>&1
177
+ }
178
+
139
179
  ensure_agent_browser() {
140
180
  # 优先使用用户态 pnpm,减少全局权限问题。
141
181
  if command -v pnpm >/dev/null 2>&1; then
@@ -423,7 +463,7 @@ check_codex_config() {
423
463
  }
424
464
 
425
465
  force_dx() {
426
- local pnpm_bin dx_cmd
466
+ local pnpm_bin dx_installed dx_cmd
427
467
  if ! install_pnpm; then
428
468
  DX_FORCE_OK=0
429
469
  DX_FORCE_MSG="pnpm 不可用,无法执行 dx 强制初始化"
@@ -432,21 +472,34 @@ force_dx() {
432
472
 
433
473
  if pnpm add -g @ranger1/dx@latest >/dev/null 2>&1; then
434
474
  pnpm_bin="$(pnpm bin -g 2>/dev/null || true)"
435
- dx_cmd=""
475
+ dx_installed=""
436
476
  if [[ -n "$pnpm_bin" && -x "$pnpm_bin/dx" ]]; then
437
- dx_cmd="$pnpm_bin/dx"
477
+ dx_installed="$pnpm_bin/dx"
438
478
  elif command -v dx >/dev/null 2>&1; then
439
- dx_cmd="$(command -v dx)"
479
+ dx_installed="$(command -v dx)"
480
+ fi
481
+
482
+ if [[ -z "$dx_installed" ]]; then
483
+ DX_FORCE_OK=0
484
+ DX_FORCE_MSG="dx 安装后未找到可执行文件(pnpm bin: ${pnpm_bin:-N/A})"
485
+ return 1
486
+ fi
487
+
488
+ if ! expose_dx_globally "$dx_installed"; then
489
+ DX_FORCE_OK=0
490
+ DX_FORCE_MSG="dx 已安装但未能暴露为全局命令(pnpm bin: ${pnpm_bin:-N/A})"
491
+ return 1
440
492
  fi
441
493
 
442
- if [[ -n "$dx_cmd" ]] && "$dx_cmd" initial >/dev/null 2>&1; then
494
+ dx_cmd="$(command -v dx || true)"
495
+ if [[ -n "$dx_cmd" ]] && dx initial >/dev/null 2>&1; then
443
496
  DX_FORCE_OK=1
444
- DX_FORCE_MSG="已执行 pnpm add -g @ranger1/dx@latest && ${dx_cmd} initial"
497
+ DX_FORCE_MSG="已安装并暴露全局 dx(${dx_cmd}),并执行 dx initial"
445
498
  return 0
446
499
  fi
447
500
 
448
501
  DX_FORCE_OK=0
449
- DX_FORCE_MSG="dx 已安装但无法调用(请检查 PATH,pnpm bin: ${pnpm_bin:-N/A})"
502
+ DX_FORCE_MSG="dx 已暴露为全局命令但 dx initial 执行失败(dx: ${dx_cmd:-N/A})"
450
503
  return 1
451
504
  fi
452
505
 
@@ -8,6 +8,7 @@ export function mergeLayeredDeployEnv(layeredEnv, manager, runtimeEnv = process.
8
8
  'VERCEL_ORG_ID',
9
9
  'VERCEL_PROJECT_ID_FRONT',
10
10
  'VERCEL_PROJECT_ID_ADMIN',
11
+ 'VERCEL_PROJECT_ID_MERCHANT',
11
12
  'VERCEL_PROJECT_ID_TELEGRAM_BOT',
12
13
  ])
13
14
 
@@ -57,7 +58,7 @@ export function parseTelegramWebhookFlags(argv = []) {
57
58
  export async function handleDeploy(cli, args) {
58
59
  const target = args[0]
59
60
  if (!target) {
60
- logger.error('请指定部署目标: front, admin, all')
61
+ logger.error('请指定部署目标: front, admin, merchant, telegram-bot, all')
61
62
  logger.info(`用法: ${cli.invocation} deploy <target> [环境标志]`)
62
63
  logger.info(`示例: ${cli.invocation} deploy front --staging`)
63
64
  process.exitCode = 1
package/lib/cli/help.js CHANGED
@@ -21,7 +21,7 @@ export function showHelp() {
21
21
  ' 环境标志: --dev, --staging, --prod, --test, --e2e(未指定时默认 --dev)',
22
22
  '',
23
23
  ' deploy <target> [环境标志] 部署前端到 Vercel',
24
- ' target: front, admin, telegram-bot, all',
24
+ ' target: front, admin, merchant, telegram-bot, all',
25
25
  ' 环境标志: --dev, --staging, --prod(默认 --staging)',
26
26
  '',
27
27
  ' install 安装依赖(使用 frozen-lockfile 确保版本一致)',
@@ -188,7 +188,7 @@ script 子命令:
188
188
  dx deploy <target> [环境标志] [选项]
189
189
 
190
190
  参数说明:
191
- target: front, admin, telegram-bot, all
191
+ target: front, admin, merchant, telegram-bot, all
192
192
  环境标志: --dev、--staging、--prod(默认 --staging)
193
193
 
194
194
  Telegram Webhook(仅 target=telegram-bot 生效):
@@ -200,11 +200,12 @@ script 子命令:
200
200
  常见示例:
201
201
  dx deploy front --staging # 部署用户前端(staging)
202
202
  dx deploy admin --prod # 部署管理后台(生产)
203
+ dx deploy merchant --staging # 部署商家前端(staging)
203
204
  dx deploy telegram-bot --staging # 部署 Telegram Bot + 自动配置 Webhook
204
205
  dx deploy telegram-bot --staging --webhook-path /webhook # 使用短路径(rewrite 到 /api/webhook)
205
206
  dx deploy telegram-bot --prod --webhook-dry-run # 仅打印,不实际调用 Telegram
206
207
  dx deploy telegram-bot --dev --no-strict-webhook # 开发环境显式降级为仅告警
207
- dx deploy all --staging # 串行部署 front + admin
208
+ dx deploy all --staging # 串行部署 front + admin + merchant
208
209
  `)
209
210
  return
210
211
 
@@ -5,7 +5,7 @@ import { envManager } from './env.js'
5
5
  import { logger } from './logger.js'
6
6
 
7
7
  const ALLOWED_ENVIRONMENTS = ['development', 'staging', 'production']
8
- const VALID_TARGETS = ['front', 'admin', 'telegram-bot']
8
+ const VALID_TARGETS = ['front', 'admin', 'merchant', 'telegram-bot']
9
9
 
10
10
  const TARGET_CONFIGS = {
11
11
  front: {
@@ -22,6 +22,13 @@ const TARGET_CONFIGS = {
22
22
  deployMode: 'prebuilt',
23
23
  prebuiltCwd: '.'
24
24
  },
25
+ merchant: {
26
+ configFile: 'vercel.merchant.json',
27
+ projectIdEnvVar: 'VERCEL_PROJECT_ID_MERCHANT',
28
+ deployCwd: '.',
29
+ deployMode: 'prebuilt',
30
+ prebuiltCwd: '.'
31
+ },
25
32
  'telegram-bot': {
26
33
  configFile: 'vercel.telegram-bot.json',
27
34
  projectIdEnvVar: 'VERCEL_PROJECT_ID_TELEGRAM_BOT',
@@ -229,31 +236,10 @@ export async function deployPrebuiltWithFallback(options) {
229
236
  baseArgs,
230
237
  env,
231
238
  cwd,
232
- run = runVercel,
233
- cleanupArchiveParts = () => {
234
- try {
235
- execSync('rm -f .vercel/source.tgz.part*', { stdio: 'ignore', cwd: cwd || process.cwd() })
236
- } catch {
237
- // ignore
238
- }
239
- },
240
- onMissingFiles = () => {
241
- logger.warn('检测到 missing_files,自动使用 --archive=tgz 重试一次')
242
- }
239
+ run = runVercel
243
240
  } = options || {}
244
-
245
- try {
246
- const result = await run(baseArgs, { env, cwd })
247
- return { usedArchive: false, result }
248
- } catch (e) {
249
- if (!isMissingFilesError(e)) throw e
250
- onMissingFiles(e)
251
- cleanupArchiveParts()
252
- const archiveArgs = baseArgs.slice()
253
- archiveArgs.splice(2, 0, '--archive=tgz')
254
- const result = await run(archiveArgs, { env, cwd })
255
- return { usedArchive: true, result }
256
- }
241
+ const result = await run(baseArgs, { env, cwd })
242
+ return { usedArchive: false, result }
257
243
  }
258
244
 
259
245
  export async function deployToVercel(target, options = {}) {
@@ -274,14 +260,14 @@ export async function deployToVercel(target, options = {}) {
274
260
  }
275
261
 
276
262
  const normalizedTarget = String(target || '').toLowerCase()
277
- const targets = normalizedTarget === 'all' ? ['front', 'admin'] : [normalizedTarget]
263
+ const targets = normalizedTarget === 'all' ? ['front', 'admin', 'merchant'] : [normalizedTarget]
278
264
  const projectRoot = process.cwd()
279
265
 
280
266
  // 校验目标有效性
281
267
  for (const t of targets) {
282
268
  if (!VALID_TARGETS.includes(t)) {
283
269
  logger.error(`不支持的部署目标: ${t}`)
284
- logger.info('可用目标: front, admin, telegram-bot, all')
270
+ logger.info('可用目标: front, admin, merchant, telegram-bot, all')
285
271
  process.exitCode = 1
286
272
  return
287
273
  }
@@ -306,6 +292,7 @@ export async function deployToVercel(target, options = {}) {
306
292
  logger.info(' VERCEL_ORG_ID=team_xxx')
307
293
  logger.info(' VERCEL_PROJECT_ID_FRONT=prj_xxx')
308
294
  logger.info(' VERCEL_PROJECT_ID_ADMIN=prj_xxx')
295
+ logger.info(' VERCEL_PROJECT_ID_MERCHANT=prj_xxx')
309
296
  logger.info(' VERCEL_PROJECT_ID_TELEGRAM_BOT=prj_xxx')
310
297
  logger.info('')
311
298
  logger.info('获取方式:')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ranger1/dx",
3
- "version": "0.1.75",
3
+ "version": "0.1.77",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {