@syedar/seedar-cli 1.1.2 → 1.2.0-test.11

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.
Files changed (122) hide show
  1. package/README.md +26 -3
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +20 -522
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/doctor.d.ts +2 -0
  6. package/dist/commands/doctor.d.ts.map +1 -0
  7. package/dist/commands/doctor.js +18 -0
  8. package/dist/commands/doctor.js.map +1 -0
  9. package/dist/commands/help.d.ts +2 -0
  10. package/dist/commands/help.d.ts.map +1 -0
  11. package/dist/commands/help.js +17 -0
  12. package/dist/commands/help.js.map +1 -0
  13. package/dist/commands/install.d.ts +3 -0
  14. package/dist/commands/install.d.ts.map +1 -0
  15. package/dist/commands/install.js +35 -0
  16. package/dist/commands/install.js.map +1 -0
  17. package/dist/commands/lifecycle.d.ts +4 -0
  18. package/dist/commands/lifecycle.d.ts.map +1 -0
  19. package/dist/commands/lifecycle.js +63 -0
  20. package/dist/commands/lifecycle.js.map +1 -0
  21. package/dist/commands/logs.d.ts +3 -0
  22. package/dist/commands/logs.d.ts.map +1 -0
  23. package/dist/commands/logs.js +20 -0
  24. package/dist/commands/logs.js.map +1 -0
  25. package/dist/commands/status.d.ts +4 -0
  26. package/dist/commands/status.d.ts.map +1 -0
  27. package/dist/commands/status.js +230 -0
  28. package/dist/commands/status.js.map +1 -0
  29. package/dist/commands/uninstall.d.ts +5 -0
  30. package/dist/commands/uninstall.d.ts.map +1 -0
  31. package/dist/commands/uninstall.js +163 -0
  32. package/dist/commands/uninstall.js.map +1 -0
  33. package/dist/docker/compose.d.ts +6 -0
  34. package/dist/docker/compose.d.ts.map +1 -0
  35. package/dist/docker/compose.js +55 -0
  36. package/dist/docker/compose.js.map +1 -0
  37. package/dist/docker/health.d.ts +3 -0
  38. package/dist/docker/health.d.ts.map +1 -0
  39. package/dist/docker/health.js +38 -0
  40. package/dist/docker/health.js.map +1 -0
  41. package/dist/docker/ports.d.ts +3 -0
  42. package/dist/docker/ports.d.ts.map +1 -0
  43. package/dist/docker/ports.js +27 -0
  44. package/dist/docker/ports.js.map +1 -0
  45. package/dist/docker/prerequisites.d.ts +2 -0
  46. package/dist/docker/prerequisites.d.ts.map +1 -0
  47. package/dist/docker/prerequisites.js +12 -0
  48. package/dist/docker/prerequisites.js.map +1 -0
  49. package/dist/{process.d.ts → docker/process.d.ts} +2 -1
  50. package/dist/docker/process.d.ts.map +1 -0
  51. package/dist/{process.js → docker/process.js} +11 -0
  52. package/dist/docker/process.js.map +1 -0
  53. package/dist/index.js +0 -0
  54. package/dist/install/config.d.ts +7 -0
  55. package/dist/install/config.d.ts.map +1 -0
  56. package/dist/install/config.js +81 -0
  57. package/dist/install/config.js.map +1 -0
  58. package/dist/install/flow.d.ts +9 -0
  59. package/dist/install/flow.d.ts.map +1 -0
  60. package/dist/install/flow.js +103 -0
  61. package/dist/install/flow.js.map +1 -0
  62. package/dist/install/output.d.ts +7 -0
  63. package/dist/install/output.d.ts.map +1 -0
  64. package/dist/install/output.js +22 -0
  65. package/dist/install/output.js.map +1 -0
  66. package/dist/install/ports.d.ts +8 -0
  67. package/dist/install/ports.d.ts.map +1 -0
  68. package/dist/install/ports.js +38 -0
  69. package/dist/install/ports.js.map +1 -0
  70. package/dist/install/prompts.d.ts +4 -0
  71. package/dist/install/prompts.d.ts.map +1 -0
  72. package/dist/install/prompts.js +155 -0
  73. package/dist/install/prompts.js.map +1 -0
  74. package/dist/runtime/guards.d.ts +3 -0
  75. package/dist/runtime/guards.d.ts.map +1 -0
  76. package/dist/runtime/guards.js +7 -0
  77. package/dist/runtime/guards.js.map +1 -0
  78. package/dist/{runtime.d.ts → runtime/index.d.ts} +2 -2
  79. package/dist/runtime/index.d.ts.map +1 -0
  80. package/dist/{runtime.js → runtime/index.js} +2 -2
  81. package/dist/runtime/index.js.map +1 -0
  82. package/dist/shared/args.d.ts +8 -0
  83. package/dist/shared/args.d.ts.map +1 -0
  84. package/dist/shared/args.js +40 -0
  85. package/dist/shared/args.js.map +1 -0
  86. package/dist/shared/constants.d.ts.map +1 -0
  87. package/dist/shared/constants.js.map +1 -0
  88. package/dist/shared/logging.d.ts +3 -0
  89. package/dist/shared/logging.d.ts.map +1 -0
  90. package/dist/shared/logging.js +8 -0
  91. package/dist/shared/logging.js.map +1 -0
  92. package/dist/shared/package.d.ts +2 -0
  93. package/dist/shared/package.d.ts.map +1 -0
  94. package/dist/shared/package.js +2 -0
  95. package/dist/shared/package.js.map +1 -0
  96. package/dist/shared/time.d.ts +2 -0
  97. package/dist/shared/time.d.ts.map +1 -0
  98. package/dist/shared/time.js +4 -0
  99. package/dist/shared/time.js.map +1 -0
  100. package/dist/{types.d.ts → shared/types.d.ts} +6 -0
  101. package/dist/shared/types.d.ts.map +1 -0
  102. package/dist/shared/types.js.map +1 -0
  103. package/dist/shared/ui.d.ts +7 -0
  104. package/dist/shared/ui.d.ts.map +1 -0
  105. package/dist/shared/ui.js +25 -0
  106. package/dist/shared/ui.js.map +1 -0
  107. package/package.json +11 -6
  108. package/dist/constants.d.ts.map +0 -1
  109. package/dist/constants.js.map +0 -1
  110. package/dist/process.d.ts.map +0 -1
  111. package/dist/process.js.map +0 -1
  112. package/dist/prompts.d.ts +0 -4
  113. package/dist/prompts.d.ts.map +0 -1
  114. package/dist/prompts.js +0 -115
  115. package/dist/prompts.js.map +0 -1
  116. package/dist/runtime.d.ts.map +0 -1
  117. package/dist/runtime.js.map +0 -1
  118. package/dist/types.d.ts.map +0 -1
  119. package/dist/types.js.map +0 -1
  120. /package/dist/{constants.d.ts → shared/constants.d.ts} +0 -0
  121. /package/dist/{constants.js → shared/constants.js} +0 -0
  122. /package/dist/{types.js → shared/types.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC5B,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function printHelp(): void;
2
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,IAAI,IAAI,CAehC"}
@@ -0,0 +1,17 @@
1
+ export function printHelp() {
2
+ console.log(`Seedar CLI
3
+
4
+ ??:
5
+ seedar install [version]
6
+ seedar start
7
+ seedar stop
8
+ seedar update [version]
9
+ seedar uninstall [--remove-data] [--all] [--force]
10
+ seedar remove --force
11
+ seedar purge --force
12
+ seedar status
13
+ seedar logs [mysql|server|web|migrate] [--follow]
14
+ seedar doctor
15
+ `);
16
+ }
17
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS;IACvB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;CAab,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CliFlags } from "../shared/types.js";
2
+ export declare function installCommand(versionArg: string | undefined, flags: CliFlags): Promise<void>;
3
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAa,MAAM,oBAAoB,CAAC;AAU9D,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BnG"}
@@ -0,0 +1,35 @@
1
+ import { ensurePrerequisites } from "../docker/prerequisites.js";
2
+ import { prepareInstallConfig } from "../install/config.js";
3
+ import { runInstallFlowWithValidatedConfig } from "../install/flow.js";
4
+ import { printInstallDetail, printInstallStage, printInstallSummary } from "../install/output.js";
5
+ import { collectInstallConfig } from "../install/prompts.js";
6
+ import { writeCliLog } from "../shared/logging.js";
7
+ import { getRuntimeLayout, hasRuntimeConfig, readEnvConfig, readInstallState, writeInstalledVersion, writeInstallState, } from "../runtime/index.js";
8
+ export async function installCommand(versionArg, flags) {
9
+ const layout = getRuntimeLayout();
10
+ await ensurePrerequisites();
11
+ const state = await readInstallState(layout);
12
+ const hasConfig = await hasRuntimeConfig(layout);
13
+ if (state === "installed" && hasConfig) {
14
+ throw new Error(`检测到现有安装目录 ${layout.installRoot}。如需升级请使用 seedar update。`);
15
+ }
16
+ let env;
17
+ if (state === "uninstalled" && hasConfig) {
18
+ printInstallStage("复用已有配置");
19
+ env = await readEnvConfig(layout);
20
+ env.SEEDAR_VERSION = versionArg ?? env.SEEDAR_VERSION;
21
+ printInstallDetail(`已复用配置文件:${layout.envPath}`);
22
+ await writeCliLog(layout, `reuse existing config reinstall target=${env.SEEDAR_VERSION}`);
23
+ }
24
+ else {
25
+ printInstallStage("填写配置");
26
+ env = await collectInstallConfig(layout, versionArg, flags);
27
+ printInstallDetail("配置填写完成");
28
+ }
29
+ env = await prepareInstallConfig(layout, env, flags);
30
+ await runInstallFlowWithValidatedConfig(layout, env);
31
+ await writeInstalledVersion(layout, env.SEEDAR_VERSION);
32
+ await writeInstallState(layout, "installed");
33
+ printInstallSummary(layout, env);
34
+ }
35
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAA8B,EAAE,KAAe;IAClF,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,mBAAmB,EAAE,CAAC;IAE5B,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,KAAK,KAAK,WAAW,IAAI,SAAS,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,aAAa,MAAM,CAAC,WAAW,yBAAyB,CACzD,CAAC;IACJ,CAAC;IAED,IAAI,GAAc,CAAC;IACnB,IAAI,KAAK,KAAK,aAAa,IAAI,SAAS,EAAE,CAAC;QACzC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC5B,GAAG,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,GAAG,CAAC,cAAc,GAAG,UAAU,IAAI,GAAG,CAAC,cAAc,CAAC;QACtD,kBAAkB,CAAC,WAAW,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,MAAM,WAAW,CAAC,MAAM,EAAE,0CAA0C,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC;IAC5F,CAAC;SAAM,CAAC;QACN,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1B,GAAG,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC5D,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACrD,MAAM,iCAAiC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAErD,MAAM,qBAAqB,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,iBAAiB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7C,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function startCommand(): Promise<void>;
2
+ export declare function stopCommand(): Promise<void>;
3
+ export declare function updateCommand(versionArg: string | undefined): Promise<void>;
4
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/commands/lifecycle.ts"],"names":[],"mappings":"AAmBA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAQlD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAMjD;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDjF"}
@@ -0,0 +1,63 @@
1
+ import { DEFAULT_VERSION } from "../shared/constants.js";
2
+ import { waitForServiceHealthy } from "../docker/health.js";
3
+ import { ensurePrerequisites } from "../docker/prerequisites.js";
4
+ import { runDockerComposeOrThrow } from "../docker/process.js";
5
+ import { startRuntimeServices, stopRuntimeServices } from "../install/flow.js";
6
+ import { writeCliLog } from "../shared/logging.js";
7
+ import { backupRuntime, getRuntimeLayout, readEnvConfig, readInstalledVersion, restoreRuntimeFromBackup, writeInstalledVersion, writeInstallState, writeRuntimeFiles, } from "../runtime/index.js";
8
+ import { requireRuntimeConfig } from "../runtime/guards.js";
9
+ export async function startCommand() {
10
+ const layout = getRuntimeLayout();
11
+ await ensurePrerequisites();
12
+ await requireRuntimeConfig(layout);
13
+ const env = await readEnvConfig(layout);
14
+ await writeCliLog(layout, "manual start requested");
15
+ await startRuntimeServices(layout, env);
16
+ }
17
+ export async function stopCommand() {
18
+ const layout = getRuntimeLayout();
19
+ await requireRuntimeConfig(layout);
20
+ await writeCliLog(layout, "manual stop requested");
21
+ await stopRuntimeServices(layout);
22
+ }
23
+ export async function updateCommand(versionArg) {
24
+ const layout = getRuntimeLayout();
25
+ await ensurePrerequisites();
26
+ await requireRuntimeConfig(layout);
27
+ const currentEnv = await readEnvConfig(layout);
28
+ const currentVersion = await readInstalledVersion(layout);
29
+ const nextVersion = versionArg ?? DEFAULT_VERSION;
30
+ const backupDir = await backupRuntime(layout);
31
+ const nextEnv = {
32
+ ...currentEnv,
33
+ SEEDAR_VERSION: nextVersion,
34
+ };
35
+ await writeRuntimeFiles(layout, nextEnv);
36
+ try {
37
+ await writeCliLog(layout, `开始升级,当前版本 ${currentVersion ?? "unknown"} -> ${nextVersion}`);
38
+ await runDockerComposeOrThrow(layout, ["pull", "mysql", "server", "web"], {
39
+ stdio: "inherit",
40
+ });
41
+ await runDockerComposeOrThrow(layout, ["up", "-d", "mysql"], {
42
+ stdio: "inherit",
43
+ });
44
+ await waitForServiceHealthy(layout, "mysql");
45
+ await runDockerComposeOrThrow(layout, ["run", "--rm", "migrate"], {
46
+ stdio: "inherit",
47
+ });
48
+ await runDockerComposeOrThrow(layout, ["up", "-d", "server", "web"], {
49
+ stdio: "inherit",
50
+ });
51
+ await writeInstalledVersion(layout, nextVersion);
52
+ await writeInstallState(layout, "installed");
53
+ await writeCliLog(layout, `升级完成,版本 ${nextVersion}`);
54
+ console.log(`Seedar 已升级到 ${nextVersion}`);
55
+ console.log(`备份目录: ${backupDir}`);
56
+ }
57
+ catch (error) {
58
+ await restoreRuntimeFromBackup(layout, backupDir);
59
+ await writeCliLog(layout, `升级失败,已恢复运行时配置。备份目录 ${backupDir}`);
60
+ throw new Error(`升级失败,已恢复运行时配置。备份目录: ${backupDir}\n${error instanceof Error ? error.message : "未知错误"}`);
61
+ }
62
+ }
63
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/commands/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CliFlags } from "../shared/types.js";
2
+ export declare function logsCommand(serviceArg: string | undefined, flags: CliFlags): Promise<void>;
3
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAInD,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhG"}
@@ -0,0 +1,20 @@
1
+ import { VALID_SERVICES } from "../shared/constants.js";
2
+ import { runDockerComposeOrThrow } from "../docker/process.js";
3
+ import { getRuntimeLayout } from "../runtime/index.js";
4
+ import { requireRuntimeConfig } from "../runtime/guards.js";
5
+ export async function logsCommand(serviceArg, flags) {
6
+ const layout = getRuntimeLayout();
7
+ await requireRuntimeConfig(layout);
8
+ if (serviceArg && !VALID_SERVICES.includes(serviceArg)) {
9
+ throw new Error(`未知服务 ${serviceArg},可选值: ${VALID_SERVICES.join(", ")}`);
10
+ }
11
+ const args = ["logs", "--tail", "200"];
12
+ if (flags.follow) {
13
+ args.push("--follow");
14
+ }
15
+ if (serviceArg) {
16
+ args.push(serviceArg);
17
+ }
18
+ await runDockerComposeOrThrow(layout, args, { stdio: "inherit" });
19
+ }
20
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAA8B,EAAE,KAAe;IAC/E,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAEnC,IAAI,UAAU,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,UAA6C,CAAC,EAAE,CAAC;QAC1F,MAAM,IAAI,KAAK,CAAC,QAAQ,UAAU,SAAS,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DoctorCheck, RuntimeLayout } from "../shared/types.js";
2
+ export declare function collectDoctorChecks(layout: RuntimeLayout): Promise<DoctorCheck[]>;
3
+ export declare function statusCommand(): Promise<void>;
4
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAa,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAwChF,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA4KvF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAiDnD"}
@@ -0,0 +1,230 @@
1
+ import { access } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { DEFAULT_SERVER_IMAGE, DEFAULT_WEB_IMAGE, MIN_NODE_MAJOR, REQUIRED_ENV_KEYS, } from "../shared/constants.js";
4
+ import { getPublishersFromServices, parseComposePsOutput } from "../docker/compose.js";
5
+ import { isPortAvailable } from "../docker/ports.js";
6
+ import { runCommand, runDockerCompose } from "../docker/process.js";
7
+ import { getRuntimeLayout, hasRuntimeConfig, readEnvConfig, readInstalledVersion, readInstallState, } from "../runtime/index.js";
8
+ async function getDiskFreeBytes(targetPath) {
9
+ if (process.platform === "win32") {
10
+ const root = path.parse(path.resolve(targetPath)).root.replace(/\\$/, "");
11
+ const result = await runCommand("powershell", [
12
+ "-NoProfile",
13
+ "-Command",
14
+ `(Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='${root}'").FreeSpace`,
15
+ ], { shell: false });
16
+ const value = Number(result.stdout.trim());
17
+ return Number.isFinite(value) ? value : null;
18
+ }
19
+ const result = await runCommand("df", ["-Pk", targetPath]);
20
+ const lines = result.stdout.trim().split(/\r?\n/);
21
+ if (lines.length < 2) {
22
+ return null;
23
+ }
24
+ const parts = lines[1].trim().split(/\s+/);
25
+ const availableKb = Number(parts[3]);
26
+ if (!Number.isFinite(availableKb)) {
27
+ return null;
28
+ }
29
+ return availableKb * 1024;
30
+ }
31
+ export async function collectDoctorChecks(layout) {
32
+ const checks = [];
33
+ const nodeMajor = Number(process.versions.node.split(".")[0]);
34
+ checks.push({
35
+ code: "D001",
36
+ status: nodeMajor >= MIN_NODE_MAJOR ? "ok" : "fail",
37
+ title: "Node.js 版本",
38
+ detail: nodeMajor >= MIN_NODE_MAJOR
39
+ ? `当前 ${process.version}`
40
+ : `当前 ${process.version},需要 >= ${MIN_NODE_MAJOR}`,
41
+ });
42
+ const dockerVersion = await runCommand("docker", ["--version"]);
43
+ checks.push({
44
+ code: "D002",
45
+ status: dockerVersion.code === 0 ? "ok" : "fail",
46
+ title: "Docker CLI",
47
+ detail: dockerVersion.code === 0
48
+ ? dockerVersion.stdout.trim()
49
+ : dockerVersion.stderr.trim() || "无法执行 docker --version",
50
+ });
51
+ const dockerInfo = await runCommand("docker", ["info"]);
52
+ checks.push({
53
+ code: "D003",
54
+ status: dockerInfo.code === 0 ? "ok" : "fail",
55
+ title: "Docker Daemon",
56
+ detail: dockerInfo.code === 0
57
+ ? "Docker daemon 可用"
58
+ : dockerInfo.stderr.trim() || "无法连接 Docker daemon",
59
+ });
60
+ const composeVersion = await runCommand("docker", ["compose", "version"]);
61
+ checks.push({
62
+ code: "D004",
63
+ status: composeVersion.code === 0 ? "ok" : "fail",
64
+ title: "Docker Compose",
65
+ detail: composeVersion.code === 0
66
+ ? composeVersion.stdout.trim()
67
+ : composeVersion.stderr.trim() || "无法执行 docker compose version",
68
+ });
69
+ const installRootParent = path.dirname(layout.installRoot);
70
+ try {
71
+ await access(installRootParent);
72
+ checks.push({
73
+ code: "D005",
74
+ status: "ok",
75
+ title: "安装目录访问",
76
+ detail: `可访问 ${installRootParent}`,
77
+ });
78
+ }
79
+ catch (error) {
80
+ checks.push({
81
+ code: "D005",
82
+ status: "fail",
83
+ title: "安装目录访问",
84
+ detail: error instanceof Error ? error.message : "无法访问安装目录父级路径",
85
+ });
86
+ }
87
+ const diskFree = await getDiskFreeBytes(layout.installRoot);
88
+ if (diskFree === null) {
89
+ checks.push({
90
+ code: "D006",
91
+ status: "warn",
92
+ title: "磁盘剩余空间",
93
+ detail: "无法识别磁盘剩余空间",
94
+ });
95
+ }
96
+ else {
97
+ const diskFreeGb = (diskFree / 1024 / 1024 / 1024).toFixed(2);
98
+ checks.push({
99
+ code: "D006",
100
+ status: diskFree >= 2 * 1024 * 1024 * 1024 ? "ok" : "warn",
101
+ title: "磁盘剩余空间",
102
+ detail: `${diskFreeGb} GB`,
103
+ });
104
+ }
105
+ const hasConfig = await hasRuntimeConfig(layout);
106
+ if (!hasConfig) {
107
+ const defaultPorts = [
108
+ ["D009", "3306"],
109
+ ["D010", "8090"],
110
+ ["D011", "8080"],
111
+ ];
112
+ for (const [code, port] of defaultPorts) {
113
+ const available = await isPortAvailable(Number(port));
114
+ checks.push({
115
+ code,
116
+ status: available ? "ok" : "warn",
117
+ title: `默认端口 ${port}`,
118
+ detail: available ? "端口当前可用" : "端口已被占用,安装时需要改配",
119
+ });
120
+ }
121
+ return checks;
122
+ }
123
+ let envConfig = null;
124
+ try {
125
+ envConfig = await readEnvConfig(layout);
126
+ checks.push({
127
+ code: "D007",
128
+ status: "ok",
129
+ title: "运行时配置",
130
+ detail: `已检测到 ${REQUIRED_ENV_KEYS.length} 个必填字段`,
131
+ });
132
+ }
133
+ catch (error) {
134
+ checks.push({
135
+ code: "D007",
136
+ status: "fail",
137
+ title: "运行时配置",
138
+ detail: error instanceof Error ? error.message : "运行时配置损坏",
139
+ });
140
+ }
141
+ if (!envConfig) {
142
+ return checks;
143
+ }
144
+ const composeConfig = await runDockerCompose(layout, ["config", "-q"]);
145
+ checks.push({
146
+ code: "D008",
147
+ status: composeConfig.code === 0 ? "ok" : "fail",
148
+ title: "Compose 配置",
149
+ detail: composeConfig.code === 0
150
+ ? "docker compose config 校验通过"
151
+ : composeConfig.stderr.trim() || "docker compose config 校验失败",
152
+ });
153
+ const services = await parseComposePsOutput(layout);
154
+ const publishedPorts = getPublishersFromServices(services);
155
+ const envPorts = [envConfig.MYSQL_PORT, envConfig.SERVER_PORT, envConfig.WEB_PORT];
156
+ for (const [index, port] of envPorts.entries()) {
157
+ const inUseByCurrentProject = publishedPorts.has(port);
158
+ const available = await isPortAvailable(Number(port));
159
+ const status = inUseByCurrentProject || available ? "ok" : "warn";
160
+ checks.push({
161
+ code: `D01${index}`,
162
+ status,
163
+ title: `端口 ${port}`,
164
+ detail: inUseByCurrentProject
165
+ ? "端口已由当前 Seedar 安装占用"
166
+ : available
167
+ ? "端口配置可用"
168
+ : "端口已被其他进程占用",
169
+ });
170
+ }
171
+ const serverImage = `${DEFAULT_SERVER_IMAGE}:${envConfig.SEEDAR_VERSION}`;
172
+ const webImage = `${DEFAULT_WEB_IMAGE}:${envConfig.SEEDAR_VERSION}`;
173
+ for (const [index, image] of [serverImage, webImage].entries()) {
174
+ const manifest = await runCommand("docker", ["manifest", "inspect", image]);
175
+ checks.push({
176
+ code: `D02${index}`,
177
+ status: manifest.code === 0 ? "ok" : "fail",
178
+ title: `镜像可访问性 ${image}`,
179
+ detail: manifest.code === 0
180
+ ? "镜像清单可访问"
181
+ : manifest.stderr.trim() || "无法访问镜像清单,请检查 DockerHub 凭证或镜像发布状态",
182
+ });
183
+ }
184
+ return checks;
185
+ }
186
+ export async function statusCommand() {
187
+ const layout = getRuntimeLayout();
188
+ const hasConfig = await hasRuntimeConfig(layout);
189
+ if (!hasConfig) {
190
+ console.log(`未检测到 Seedar 安装。预期目录: ${layout.installRoot}`);
191
+ return;
192
+ }
193
+ const env = await readEnvConfig(layout);
194
+ const state = await readInstallState(layout);
195
+ const version = await readInstalledVersion(layout);
196
+ const services = await parseComposePsOutput(layout);
197
+ console.log(`安装目录: ${layout.installRoot}`);
198
+ console.log(`状态: ${state}`);
199
+ console.log(`目标版本: ${version ?? env.SEEDAR_VERSION}`);
200
+ console.log(`Web: http://localhost:${env.WEB_PORT}`);
201
+ console.log(`Server: http://localhost:${env.SERVER_PORT}`);
202
+ console.log(`MySQL: localhost:${env.MYSQL_PORT}`);
203
+ if (services.length === 0) {
204
+ console.log("当前没有运行中的容器。");
205
+ return;
206
+ }
207
+ console.log("");
208
+ console.log("容器状态:");
209
+ for (const service of services) {
210
+ const serviceName = String(service.Service ?? service.Name ?? "unknown");
211
+ const status = String(service.State ?? "unknown");
212
+ const health = service.Health ? `, health=${String(service.Health)}` : "";
213
+ const publishers = Array.isArray(service.Publishers)
214
+ ? service.Publishers.map((item) => {
215
+ if (item &&
216
+ typeof item === "object" &&
217
+ "PublishedPort" in item &&
218
+ "TargetPort" in item) {
219
+ return `${String(item.PublishedPort)}->${String(item.TargetPort)}`;
220
+ }
221
+ return null;
222
+ })
223
+ .filter(Boolean)
224
+ .join(", ")
225
+ : "";
226
+ const ports = publishers ? `, ports=${publishers}` : "";
227
+ console.log(`- ${serviceName}: ${status}${health}${ports}`);
228
+ }
229
+ }
230
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { CliFlags } from "../shared/types.js";
2
+ export declare function uninstallCommand(flags: CliFlags): Promise<void>;
3
+ export declare function removeAllCommand(flags: CliFlags): Promise<void>;
4
+ export declare function purgeCommand(flags: CliFlags): Promise<void>;
5
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AA2CnD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCrE;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCrE;AAuBD,wBAAsB,YAAY,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCjE"}
@@ -0,0 +1,163 @@
1
+ import { rm } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { CLI_PACKAGE_NAME } from "../shared/package.js";
5
+ import { runCommand, runDockerCompose, runDockerComposeOrThrow, spawnDetached } from "../docker/process.js";
6
+ import { ensurePrerequisites } from "../docker/prerequisites.js";
7
+ import { printInstallDetail, printInstallStage, printInstallSuccess, printInstallWarn } from "../install/output.js";
8
+ import { writeCliLog } from "../shared/logging.js";
9
+ import { getRuntimeLayout, hasRuntimeConfig, writeInstallState } from "../runtime/index.js";
10
+ import { requireRuntimeConfig } from "../runtime/guards.js";
11
+ async function isGlobalNpmCliInstall() {
12
+ const entryPath = process.argv[1];
13
+ if (!entryPath) {
14
+ return false;
15
+ }
16
+ const npmRootResult = await runCommand("npm", ["root", "-g"]);
17
+ if (npmRootResult.code !== 0) {
18
+ return false;
19
+ }
20
+ const packageRoot = path.resolve(entryPath, "..", "..");
21
+ const expectedRoot = path.resolve(npmRootResult.stdout.trim(), ...CLI_PACKAGE_NAME.split("/"));
22
+ return normalizePathForCompare(packageRoot) === normalizePathForCompare(expectedRoot);
23
+ }
24
+ async function scheduleCliSelfUninstall() {
25
+ if (!(await isGlobalNpmCliInstall())) {
26
+ return false;
27
+ }
28
+ if (process.platform === "win32") {
29
+ spawnDetached("powershell", [
30
+ "-NoProfile",
31
+ "-WindowStyle",
32
+ "Hidden",
33
+ "-Command",
34
+ `Start-Sleep -Seconds 2; npm uninstall -g ${CLI_PACKAGE_NAME}`,
35
+ ]);
36
+ return true;
37
+ }
38
+ spawnDetached("sh", ["-lc", `sleep 2; npm uninstall -g ${CLI_PACKAGE_NAME} >/dev/null 2>&1`]);
39
+ return true;
40
+ }
41
+ export async function uninstallCommand(flags) {
42
+ if (flags.all) {
43
+ await removeAllCommand(flags);
44
+ return;
45
+ }
46
+ const layout = getRuntimeLayout();
47
+ await ensurePrerequisites();
48
+ await requireRuntimeConfig(layout);
49
+ await writeCliLog(layout, "开始卸载");
50
+ await runDockerComposeOrThrow(layout, ["down", "--remove-orphans"], {
51
+ stdio: "inherit",
52
+ });
53
+ if (flags.removeData) {
54
+ if (!flags.force && process.stdin.isTTY) {
55
+ console.log("检测到 --remove-data,将删除本地数据目录。若需跳过确认,请附带 --force。");
56
+ throw new Error("请确认后重新执行: seedar uninstall --remove-data --force");
57
+ }
58
+ const resolvedDataPath = path.resolve(layout.dataDir);
59
+ const installRoot = path.resolve(layout.installRoot);
60
+ if (!resolvedDataPath.startsWith(installRoot)) {
61
+ throw new Error(`拒绝删除 installRoot 之外的路径: ${resolvedDataPath}`);
62
+ }
63
+ await rm(layout.dataDir, { recursive: true, force: true });
64
+ await writeCliLog(layout, `已删除数据目录 ${layout.dataDir}`);
65
+ }
66
+ await writeInstallState(layout, "uninstalled");
67
+ await writeCliLog(layout, "卸载完成");
68
+ console.log("Seedar 已卸载。");
69
+ console.log(`配置保留在: ${layout.runtimeDir}`);
70
+ console.log(`备份保留在: ${layout.backupsDir}`);
71
+ if (!flags.removeData) {
72
+ console.log(`数据保留在: ${layout.dataDir}`);
73
+ }
74
+ }
75
+ export async function removeAllCommand(flags) {
76
+ const layout = getRuntimeLayout();
77
+ const installRoot = path.resolve(layout.installRoot);
78
+ if (!flags.force) {
79
+ if (process.stdin.isTTY) {
80
+ console.log("该操作会删除 Seedar 的容器、配置、数据、日志、备份,并尝试卸载全局 CLI。");
81
+ throw new Error("请确认后重新执行: seedar uninstall --all --force");
82
+ }
83
+ throw new Error("非交互模式下执行 remove all 需要 --force");
84
+ }
85
+ printInstallStage("移除 Seedar");
86
+ if (await hasRuntimeConfig(layout)) {
87
+ printInstallDetail("开始停止并清理容器");
88
+ const downResult = await runDockerCompose(layout, ["down", "--remove-orphans"]);
89
+ const detail = [downResult.stdout.trim(), downResult.stderr.trim()].filter(Boolean).join("\n");
90
+ if (detail) {
91
+ console.log(detail);
92
+ }
93
+ if (downResult.code !== 0) {
94
+ printInstallWarn("停止容器失败,继续删除本地文件");
95
+ }
96
+ }
97
+ else {
98
+ printInstallDetail("未检测到运行时配置,跳过容器清理");
99
+ }
100
+ const dangerReason = getDangerousDeleteReason(installRoot);
101
+ if (dangerReason) {
102
+ throw new Error(`拒绝删除危险路径: ${installRoot}(${dangerReason})`);
103
+ }
104
+ await rm(installRoot, { recursive: true, force: true });
105
+ printInstallSuccess(`已删除安装目录:${installRoot}`);
106
+ const cliUninstallScheduled = await scheduleCliSelfUninstall();
107
+ if (cliUninstallScheduled) {
108
+ printInstallSuccess(`已安排卸载全局 CLI:${CLI_PACKAGE_NAME}`);
109
+ }
110
+ else {
111
+ printInstallWarn("未检测到 npm 全局安装的 CLI,跳过 CLI 自卸载");
112
+ }
113
+ }
114
+ function normalizePathForCompare(targetPath) {
115
+ return path.resolve(targetPath).replace(/[\\/]+$/, "").toLowerCase();
116
+ }
117
+ function getDangerousDeleteReason(targetPath) {
118
+ const resolved = path.resolve(targetPath);
119
+ const parsed = path.parse(resolved);
120
+ const normalizedTarget = normalizePathForCompare(resolved);
121
+ const normalizedRoot = normalizePathForCompare(parsed.root);
122
+ const normalizedHome = normalizePathForCompare(os.homedir());
123
+ if (normalizedTarget === normalizedRoot) {
124
+ return "目标路径是磁盘根目录";
125
+ }
126
+ if (normalizedTarget === normalizedHome) {
127
+ return "目标路径是用户主目录";
128
+ }
129
+ return null;
130
+ }
131
+ export async function purgeCommand(flags) {
132
+ await removeAllCommand(flags);
133
+ return;
134
+ const layout = getRuntimeLayout();
135
+ const installRoot = path.resolve(layout.installRoot);
136
+ if (!flags.force) {
137
+ if (process.stdin.isTTY) {
138
+ console.log("该操作会彻底删除 Seedar 安装目录(含配置、数据、日志与备份)。");
139
+ throw new Error("请确认后重新执行: seedar purge --force");
140
+ }
141
+ throw new Error("非交互模式下执行 purge 需要 --force");
142
+ }
143
+ const dangerReason = getDangerousDeleteReason(installRoot);
144
+ if (dangerReason) {
145
+ throw new Error(`拒绝删除危险路径: ${installRoot}(${dangerReason})`);
146
+ }
147
+ await writeCliLog(layout, "开始彻底删除安装目录");
148
+ if (await hasRuntimeConfig(layout)) {
149
+ const downResult = await runDockerCompose(layout, ["down", "--remove-orphans"]);
150
+ if (downResult.code !== 0) {
151
+ const detail = [downResult.stdout.trim(), downResult.stderr.trim()]
152
+ .filter(Boolean)
153
+ .join("\n");
154
+ console.warn(detail
155
+ ? `停止容器失败,继续删除本地目录:\n${detail}`
156
+ : "停止容器失败,继续删除本地目录。");
157
+ }
158
+ }
159
+ await rm(installRoot, { recursive: true, force: true });
160
+ console.log("Seedar 已彻底删除。");
161
+ console.log(`已删除目录: ${installRoot}`);
162
+ }
163
+ //# sourceMappingURL=uninstall.js.map