@gadmin2n/cli 0.0.188 → 0.0.189

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.
@@ -30,6 +30,7 @@ const types_1 = require("../lib/template-merge/types");
30
30
  const executable_paths_1 = require("../lib/executable-paths");
31
31
  class NewAction extends abstract_action_1.AbstractAction {
32
32
  handle(inputs, options) {
33
+ var _a;
33
34
  return __awaiter(this, void 0, void 0, function* () {
34
35
  const directoryOption = options.find((option) => option.name === 'directory');
35
36
  const dryRunOption = options.find((option) => option.name === 'dry-run');
@@ -77,7 +78,7 @@ class NewAction extends abstract_action_1.AbstractAction {
77
78
  try {
78
79
  (0, executable_paths_1.ensureExecutableBits)(projectAbsDir);
79
80
  }
80
- catch (_a) {
81
+ catch (_b) {
81
82
  // best-effort, never fatal
82
83
  }
83
84
  // npm strips .gitignore when packing, so the template ships it as
@@ -104,8 +105,14 @@ class NewAction extends abstract_action_1.AbstractAction {
104
105
  console.info();
105
106
  }
106
107
  if (!isDryRunEnabled) {
107
- const inputPackageManager = (options.find((option) => option.name === 'package-manager')
108
- .value || 'yarn').toLowerCase();
108
+ // 未显式指定包管理器时(通常是 --skip-install 场景),按模板自带的
109
+ // lock 文件推断,保证打印的指引命令与实际项目一致;兜底 pnpm。
110
+ let pmOption = options.find((option) => option.name === 'package-manager').value;
111
+ if (!pmOption) {
112
+ const detected = (_a = (yield package_managers_1.PackageManagerFactory.findByLockFile((0, path_1.join)(projectAbsDir, 'server')))) !== null && _a !== void 0 ? _a : (yield package_managers_1.PackageManagerFactory.findByLockFile((0, path_1.join)(projectAbsDir, 'web')));
113
+ pmOption = detected ? detected.name.toLowerCase() : 'pnpm';
114
+ }
115
+ const inputPackageManager = pmOption.toLowerCase();
109
116
  // 收集仍未填写、需要在引导中提示用户处理的环境变量
110
117
  const viteAgentId = getOptionByName(options, 'vite-agent-id') || '';
111
118
  const taihuToken = getOptionByName(options, 'taihu-app-token') || '';
@@ -356,7 +363,19 @@ const installPackages = (options, dryRunMode, installDirectory) => __awaiter(voi
356
363
  if (inputPackageManager !== undefined) {
357
364
  try {
358
365
  packageManager = package_managers_1.PackageManagerFactory.create(inputPackageManager);
366
+ // 显式指定的包管理器与模板自带的 lock 文件冲突时:警告,并在安装
367
+ // 成功后删除陈旧 lock,避免项目里多个 lock 并存导致后续
368
+ // update / add 命令按错误的 lock 探测包管理器。
369
+ const staleLocks = findConflictingLockFiles(installDirectory, inputPackageManager);
370
+ if (staleLocks.length > 0) {
371
+ console.info(chalk.yellow(`[WARN] --package-manager ${inputPackageManager} conflicts with ` +
372
+ `${staleLocks.join(', ')} in ${installDirectory}; ` +
373
+ `stale lock file(s) will be removed after install.`));
374
+ }
359
375
  yield packageManager.install(installDirectory, inputPackageManager);
376
+ for (const lock of staleLocks) {
377
+ fs.unlinkSync((0, path_1.join)(installDirectory, lock));
378
+ }
360
379
  }
361
380
  catch (error) {
362
381
  if (error && error.message) {
@@ -365,21 +384,43 @@ const installPackages = (options, dryRunMode, installDirectory) => __awaiter(voi
365
384
  }
366
385
  }
367
386
  else {
368
- packageManager = yield selectPackageManager();
387
+ packageManager = yield selectPackageManager(installDirectory);
369
388
  yield packageManager.install(installDirectory, packageManager.name.toLowerCase());
370
389
  options.find((option) => option.name === 'package-manager').value = packageManager.name.toLowerCase();
371
390
  }
372
391
  });
373
- const selectPackageManager = () => __awaiter(void 0, void 0, void 0, function* () {
392
+ const MANAGER_LOCK_FILES = {
393
+ yarn: 'yarn.lock',
394
+ pnpm: 'pnpm-lock.yaml',
395
+ npm: 'package-lock.json',
396
+ };
397
+ /** 返回 dir 下与指定包管理器不一致的 lock 文件名列表(可能为空)。 */
398
+ const findConflictingLockFiles = (dir, manager) => {
399
+ const normalized = manager.toLowerCase();
400
+ return Object.entries(MANAGER_LOCK_FILES)
401
+ .filter(([m, file]) => m !== normalized && fs.existsSync((0, path_1.join)(dir, file)))
402
+ .map(([, file]) => file);
403
+ };
404
+ const selectPackageManager = (installDirectory) => __awaiter(void 0, void 0, void 0, function* () {
405
+ // 模板自带的 lock 文件即包管理器的权威声明(如 server/yarn.lock),
406
+ // 探测到就直接使用,不再询问;没有 lock 文件时才回退到交互选择。
407
+ if (installDirectory) {
408
+ const detected = yield package_managers_1.PackageManagerFactory.findByLockFile(installDirectory);
409
+ if (detected) {
410
+ console.info(chalk.gray(`Using ${detected.name.toLowerCase()} (detected from lock file).`));
411
+ return detected;
412
+ }
413
+ }
374
414
  const answers = yield askForPackageManager();
375
415
  return package_managers_1.PackageManagerFactory.create(answers['package-manager']);
376
416
  });
377
417
  const askForPackageManager = () => __awaiter(void 0, void 0, void 0, function* () {
418
+ // pnpm 放首位作为默认选项,用户仍可改选 yarn / npm
378
419
  const questions = [
379
420
  (0, questions_1.generateSelect)('package-manager')(ui_1.MESSAGES.PACKAGE_MANAGER_QUESTION)([
421
+ package_managers_1.PackageManager.PNPM,
380
422
  package_managers_1.PackageManager.YARN,
381
423
  package_managers_1.PackageManager.NPM,
382
- package_managers_1.PackageManager.PNPM,
383
424
  ]),
384
425
  ];
385
426
  const prompt = inquirer.createPromptModule();
@@ -3,4 +3,10 @@ import { PackageManager } from './package-manager';
3
3
  export declare class PackageManagerFactory {
4
4
  static create(name: PackageManager | string): AbstractPackageManager;
5
5
  static find(): Promise<AbstractPackageManager>;
6
+ /**
7
+ * Detect the package manager from lock files in `dir`.
8
+ * Returns null when the directory has no lock file (or is unreadable),
9
+ * so callers can distinguish "no signal" from a genuine npm project.
10
+ */
11
+ static findByLockFile(dir: string): Promise<AbstractPackageManager | null>;
6
12
  }
@@ -29,11 +29,22 @@ class PackageManagerFactory {
29
29
  }
30
30
  }
31
31
  static find() {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ const found = yield this.findByLockFile(process.cwd());
34
+ return found !== null && found !== void 0 ? found : this.create(package_manager_1.PackageManager.NPM);
35
+ });
36
+ }
37
+ /**
38
+ * Detect the package manager from lock files in `dir`.
39
+ * Returns null when the directory has no lock file (or is unreadable),
40
+ * so callers can distinguish "no signal" from a genuine npm project.
41
+ */
42
+ static findByLockFile(dir) {
32
43
  return __awaiter(this, void 0, void 0, function* () {
33
44
  return new Promise((resolve) => {
34
- (0, fs_1.readdir)(process.cwd(), (error, files) => {
45
+ (0, fs_1.readdir)(dir, (error, files) => {
35
46
  if (error) {
36
- resolve(this.create(package_manager_1.PackageManager.NPM));
47
+ resolve(null);
37
48
  }
38
49
  else {
39
50
  if (files.findIndex((filename) => filename === 'yarn.lock') > -1) {
@@ -42,9 +53,13 @@ class PackageManagerFactory {
42
53
  else if (files.findIndex((filename) => filename === 'pnpm-lock.yaml') > -1) {
43
54
  resolve(this.create(package_manager_1.PackageManager.PNPM));
44
55
  }
45
- else {
56
+ else if (files.findIndex((filename) => filename === 'package-lock.json') >
57
+ -1) {
46
58
  resolve(this.create(package_manager_1.PackageManager.NPM));
47
59
  }
60
+ else {
61
+ resolve(null);
62
+ }
48
63
  }
49
64
  });
50
65
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gadmin2n/cli",
3
- "version": "0.0.188",
3
+ "version": "0.0.189",
4
4
  "description": "Gadmin - modern, fast, powerful node.js web framework (@cli)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -47,7 +47,7 @@
47
47
  "@angular-devkit/core": "13.3.2",
48
48
  "@angular-devkit/schematics": "13.3.2",
49
49
  "@angular-devkit/schematics-cli": "13.3.2",
50
- "@gadmin2n/schematics": "^0.0.153",
50
+ "@gadmin2n/schematics": "^0.0.154",
51
51
  "abc": "^0.6.1",
52
52
  "chalk": "3.0.0",
53
53
  "chokidar": "3.5.3",