@lark-people/cli 0.0.4 → 0.0.6

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.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-people/cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "The official CLI for People open platform",
5
5
  "bin": {
6
6
  "people-cli": "scripts/run.js"
@@ -58,6 +58,7 @@ const messages = {
58
58
  step4: "授权",
59
59
  step4NotFound: "未找到 people-cli,跳过授权",
60
60
  step4Confirm: "是否现在执行登录授权,让 CLI 能访问你已授权的 People 数据?",
61
+ step4SkipExisting: "检测到已有用户授权,跳过登录",
61
62
  step4Skip: "跳过授权。后续运行 people-cli auth login 完成授权",
62
63
  step4Done: "授权完成",
63
64
  step4Fail: "授权失败。运行以下命令重试: people-cli auth login",
@@ -91,6 +92,7 @@ const messages = {
91
92
  step4: "Authorization",
92
93
  step4NotFound: "people-cli not found. Skipping authorization",
93
94
  step4Confirm: "Authorize now so People CLI can access your approved People data?",
95
+ step4SkipExisting: "Existing user authorization found. Skipped login",
94
96
  step4Skip: "Skipped. Run people-cli auth login to authorize later",
95
97
  step4Done: "Authorization complete",
96
98
  step4Fail: "Failed to authorize. Run people-cli auth login to retry",
@@ -307,6 +309,29 @@ function sameResolvedPath(a, b) {
307
309
  }
308
310
  }
309
311
 
312
+ function resolveExistingPath(targetPath) {
313
+ if (!targetPath) {
314
+ return null;
315
+ }
316
+ try {
317
+ return fs.realpathSync(targetPath);
318
+ } catch (_) {
319
+ return targetPath;
320
+ }
321
+ }
322
+
323
+ function isNpxCachePath(packageDir) {
324
+ if (!packageDir) {
325
+ return false;
326
+ }
327
+ const normalized = String(packageDir).replace(/\\/g, "/");
328
+ return normalized.includes("/_npx/") && normalized.includes("/node_modules/");
329
+ }
330
+
331
+ function packageInstallTarget(packageName, version) {
332
+ return version ? `${packageName}@${version}` : packageName;
333
+ }
334
+
310
335
  function parseVersion(version) {
311
336
  if (!version) {
312
337
  return null;
@@ -353,10 +378,19 @@ function planGlobalInstall({
353
378
  currentPackageDir = CURRENT_PACKAGE_DIR,
354
379
  globalPackageDir = resolveGlobalPackageDir(currentPackageName),
355
380
  } = {}) {
381
+ const resolvedCurrentPackageDir = resolveExistingPath(currentPackageDir);
382
+ const resolvedGlobalPackageDir = resolveExistingPath(globalPackageDir);
383
+ const currentPackageFromNpxCache = isNpxCachePath(currentPackageDir) || isNpxCachePath(resolvedCurrentPackageDir);
384
+ const globalPackageLinkedToNpxCache = isNpxCachePath(globalPackageDir) || isNpxCachePath(resolvedGlobalPackageDir);
385
+ const missingGlobalInstallFromNpxCache = currentPackageFromNpxCache && !installedVersion;
386
+ const registryInstallVersion = currentVersion || latestVersion || installedVersion || null;
387
+ const registryInstallTarget = packageInstallTarget(currentPackageName, registryInstallVersion);
356
388
  const useCurrentPackage = Boolean(
357
389
  currentPackageDir &&
358
390
  globalPackageDir &&
359
- !sameResolvedPath(currentPackageDir, globalPackageDir),
391
+ !sameResolvedPath(currentPackageDir, globalPackageDir) &&
392
+ !currentPackageFromNpxCache &&
393
+ !globalPackageLinkedToNpxCache,
360
394
  );
361
395
 
362
396
  if (useCurrentPackage) {
@@ -375,11 +409,12 @@ function planGlobalInstall({
375
409
  installVersion &&
376
410
  compareVersions(installedVersion, installVersion) < 0,
377
411
  );
412
+ const needsRepair = Boolean(globalPackageLinkedToNpxCache || missingGlobalInstallFromNpxCache);
378
413
 
379
414
  return {
380
- skip: Boolean(installedVersion && !needsUpgrade),
415
+ skip: Boolean(installedVersion && !needsUpgrade && !needsRepair),
381
416
  needsUpgrade,
382
- installTarget: currentPackageName,
417
+ installTarget: needsRepair ? registryInstallTarget : currentPackageName,
383
418
  installVersion,
384
419
  useCurrentPackage: false,
385
420
  };
@@ -451,6 +486,23 @@ function getExistingAppId(binPath) {
451
486
  }
452
487
  }
453
488
 
489
+ function isAuthenticatedStatus(status) {
490
+ return Boolean(
491
+ status &&
492
+ status.identity === "user" &&
493
+ status.userOpenId &&
494
+ status.tokenStatus !== "expired",
495
+ );
496
+ }
497
+
498
+ function shouldAutoReuseExistingConfig(existing) {
499
+ return Boolean(existing && existing.appId && existing.reusable);
500
+ }
501
+
502
+ function shouldSkipAuthLogin(existing) {
503
+ return Boolean(existing && existing.authenticated);
504
+ }
505
+
454
506
  function inspectExistingAppConfig(binPath, deps = {}) {
455
507
  const runSilentFn = deps.runSilent || runSilent;
456
508
  try {
@@ -458,16 +510,17 @@ function inspectExistingAppConfig(binPath, deps = {}) {
458
510
  const parsed = JSON.parse(out.toString());
459
511
  const appId = parsed.appId || parsed.app_id || null;
460
512
  if (!appId) {
461
- return { appId: null, reusable: false };
513
+ return { appId: null, reusable: false, authenticated: false };
462
514
  }
463
515
  try {
464
- runSilentFn(binPath, ["auth", "status"], { timeout: 10000 });
465
- return { appId, reusable: true };
516
+ const statusOut = runSilentFn(binPath, ["auth", "status"], { timeout: 10000 });
517
+ const status = JSON.parse(statusOut.toString());
518
+ return { appId, reusable: true, authenticated: isAuthenticatedStatus(status) };
466
519
  } catch (_) {
467
- return { appId, reusable: false };
520
+ return { appId, reusable: false, authenticated: false };
468
521
  }
469
522
  } catch (_) {
470
- return { appId: null, reusable: false };
523
+ return { appId: null, reusable: false, authenticated: false };
471
524
  }
472
525
  }
473
526
 
@@ -733,12 +786,16 @@ async function stepConfigInit(msg, lang) {
733
786
  }
734
787
 
735
788
  if (existing.appId && existing.reusable) {
789
+ if (shouldAutoReuseExistingConfig(existing)) {
790
+ p.log.info(msg.step3Skip);
791
+ return existing;
792
+ }
736
793
  const reuse = await p.confirm({
737
794
  message: fmt(msg.step3Found, existing.appId),
738
795
  });
739
796
  if (handleCancel(reuse, msg) && reuse) {
740
797
  p.log.info(msg.step3Skip);
741
- return;
798
+ return existing;
742
799
  }
743
800
  } else if (existing.appId) {
744
801
  p.log.warn(msg.step3Reinit);
@@ -747,19 +804,25 @@ async function stepConfigInit(msg, lang) {
747
804
  try {
748
805
  run(peopleCli, ["config", "init", "--new", "--lang", lang]);
749
806
  p.log.success(msg.step3Done);
807
+ return { appId: null, reusable: false, authenticated: false };
750
808
  } catch (_) {
751
809
  p.log.error(msg.step3Fail);
752
810
  process.exit(1);
753
811
  }
754
812
  }
755
813
 
756
- async function stepAuthLogin(msg) {
814
+ async function stepAuthLogin(msg, existing = null) {
757
815
  const peopleCli = whichPeopleCli();
758
816
  if (!peopleCli) {
759
817
  p.log.warn(msg.step4NotFound);
760
818
  return;
761
819
  }
762
820
 
821
+ if (shouldSkipAuthLogin(existing)) {
822
+ p.log.info(msg.step4SkipExisting);
823
+ return;
824
+ }
825
+
763
826
  const yes = await p.confirm({
764
827
  message: msg.step4Confirm,
765
828
  });
@@ -790,8 +853,8 @@ async function main() {
790
853
  p.intro(msg.setup);
791
854
  await stepInstallGlobally(msg);
792
855
  await stepInstallSkills(msg);
793
- await stepConfigInit(msg, lang);
794
- await stepAuthLogin(msg);
856
+ const existing = await stepConfigInit(msg, lang);
857
+ await stepAuthLogin(msg, existing);
795
858
  p.outro(msg.done);
796
859
  } else {
797
860
  console.log(msg.setup);
@@ -824,6 +887,8 @@ module.exports = {
824
887
  removeConflictingLegacyPackage,
825
888
  resolveGlobalBinOwner,
826
889
  resolveSkillsLauncher,
890
+ shouldAutoReuseExistingConfig,
891
+ shouldSkipAuthLogin,
827
892
  stepInstallSkills,
828
893
  main,
829
894
  runCLI,
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: people-cli
3
3
  version: 1.0.0
4
- description: "当用户需要通过 people-cli/People CLI 处理飞书人事或招聘数据时使用;覆盖 CoreHR 员工、部门组织、待入职、异动、离职、续约/续签、编制/HC,以及 Hire 职位、招需、投递、候选人、面试、评估、人才查询;也适用于 CLI 安装、升级、登录授权、Permission denied 和 scope 权限问题。"
4
+ description: "当用户需要处理飞书人事或飞书招聘数据时使用;覆盖 CoreHR 员工、部门组织、待入职、异动、离职、续约/续签、编制/HC,以及 Hire 职位、招需、投递、候选人、面试、评估、人才查询;也适用于 CLI 安装、升级、登录授权、Permission denied 和 scope 权限问题。"
5
5
  metadata:
6
6
  requires:
7
7
  bins: ["people-cli"]
@@ -49,7 +49,7 @@ npx @lark-people/cli install
49
49
  people-cli update --check
50
50
  ```
51
51
 
52
- 如果提示有新版本,或任意 `people-cli` JSON 输出中包含 `_notice.update` / `_notice.skills`,执行:
52
+ 如果提示有新版本,或后续任意 `people-cli` 输出中提示需要更新 CLI / Skills,执行:
53
53
 
54
54
  ```bash
55
55
  people-cli update
Binary file