@uofx/cli 1.0.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.
Files changed (238) hide show
  1. package/LICENSE +40 -0
  2. package/README.md +444 -0
  3. package/THIRD-PARTY-NOTICES.txt +894 -0
  4. package/dist/application/dtos/index.js +24 -0
  5. package/dist/application/dtos/request/delete-instance.request.dto.js +3 -0
  6. package/dist/application/dtos/request/get-config.request.dto.js +3 -0
  7. package/dist/application/dtos/request/get-credentials.request.dto.js +3 -0
  8. package/dist/application/dtos/request/index.js +27 -0
  9. package/dist/application/dtos/request/install-instance.request.dto.js +3 -0
  10. package/dist/application/dtos/request/list-charts.request.dto.js +3 -0
  11. package/dist/application/dtos/request/set-config.request.dto.js +16 -0
  12. package/dist/application/dtos/request/setup-environment.request.dto.js +16 -0
  13. package/dist/application/dtos/request/show-logs.request.dto.js +19 -0
  14. package/dist/application/dtos/request/start-instance.request.dto.js +3 -0
  15. package/dist/application/dtos/request/stop-instance.request.dto.js +3 -0
  16. package/dist/application/dtos/response/credentials.response.dto.js +3 -0
  17. package/dist/application/dtos/response/delete-instance.response.dto.js +3 -0
  18. package/dist/application/dtos/response/index.js +26 -0
  19. package/dist/application/dtos/response/install-instance.response.dto.js +3 -0
  20. package/dist/application/dtos/response/instance-list.response.dto.js +3 -0
  21. package/dist/application/dtos/response/instance-status.response.dto.js +3 -0
  22. package/dist/application/dtos/response/setup-result.response.dto.js +3 -0
  23. package/dist/application/dtos/response/show-logs.response.dto.js +3 -0
  24. package/dist/application/dtos/response/start-instance.response.dto.js +3 -0
  25. package/dist/application/dtos/response/stop-instance.response.dto.js +3 -0
  26. package/dist/application/index.js +25 -0
  27. package/dist/application/interfaces/index.js +24 -0
  28. package/dist/application/interfaces/use-case.interface.js +3 -0
  29. package/dist/application/use-cases/config/get-config.use-case.js +66 -0
  30. package/dist/application/use-cases/config/set-config.use-case.js +49 -0
  31. package/dist/application/use-cases/credentials/get-credentials.use-case.js +57 -0
  32. package/dist/application/use-cases/index.js +28 -0
  33. package/dist/application/use-cases/instance/delete-instance.use-case.js +81 -0
  34. package/dist/application/use-cases/instance/index.js +23 -0
  35. package/dist/application/use-cases/instance/install-instance.use-case.js +424 -0
  36. package/dist/application/use-cases/instance/list-charts.use-case.js +43 -0
  37. package/dist/application/use-cases/instance/list-instances.use-case.js +62 -0
  38. package/dist/application/use-cases/instance/start-instance.use-case.js +154 -0
  39. package/dist/application/use-cases/instance/stop-instance.use-case.js +55 -0
  40. package/dist/application/use-cases/logs/show-logs.use-case.js +66 -0
  41. package/dist/application/use-cases/setup/setup-environment.use-case.js +53 -0
  42. package/dist/cli.js +286 -0
  43. package/dist/constants/config-defaults.js +23 -0
  44. package/dist/constants/defaults.js +89 -0
  45. package/dist/constants/deployment.js +39 -0
  46. package/dist/constants/environments.js +93 -0
  47. package/dist/constants/index.js +53 -0
  48. package/dist/constants/oci-artifacts.js +25 -0
  49. package/dist/constants/paths.js +92 -0
  50. package/dist/constants/timeouts.js +60 -0
  51. package/dist/di/container.js +34 -0
  52. package/dist/di/index.js +22 -0
  53. package/dist/di/modules/application.module.js +54 -0
  54. package/dist/di/modules/infrastructure.module.js +206 -0
  55. package/dist/di/modules/interceptor.module.js +68 -0
  56. package/dist/di/modules/presentation.module.js +31 -0
  57. package/dist/di/tokens.js +149 -0
  58. package/dist/domain/decorators/sensitive.decorator.js +39 -0
  59. package/dist/domain/entities/credentials-resolver.entity.js +127 -0
  60. package/dist/domain/entities/credentials.entity.js +65 -0
  61. package/dist/domain/entities/delete-instance-validation.entity.js +100 -0
  62. package/dist/domain/entities/deployment-parameters.entity.js +120 -0
  63. package/dist/domain/entities/environment-validation.entity.js +125 -0
  64. package/dist/domain/entities/index.js +29 -0
  65. package/dist/domain/entities/instance-lifecycle-state.entity.js +100 -0
  66. package/dist/domain/entities/instance-list-aggregator.entity.js +104 -0
  67. package/dist/domain/entities/instance-metadata.entity.js +86 -0
  68. package/dist/domain/entities/instance-status.entity.js +79 -0
  69. package/dist/domain/entities/instance.entity.js +128 -0
  70. package/dist/domain/entities/log-filter.entity.js +141 -0
  71. package/dist/domain/index.js +29 -0
  72. package/dist/domain/interfaces/safe-loggable.interface.js +3 -0
  73. package/dist/domain/ports/app-config.port.js +3 -0
  74. package/dist/domain/ports/base-image.port.js +3 -0
  75. package/dist/domain/ports/chart-version.port.js +3 -0
  76. package/dist/domain/ports/correlation-id.port.js +3 -0
  77. package/dist/domain/ports/credentials.port.js +3 -0
  78. package/dist/domain/ports/deployment.port.js +3 -0
  79. package/dist/domain/ports/error-handler.port.js +3 -0
  80. package/dist/domain/ports/index.js +46 -0
  81. package/dist/domain/ports/instance-manager.port.js +3 -0
  82. package/dist/domain/ports/instance-metadata.port.js +8 -0
  83. package/dist/domain/ports/instance-storage.port.js +3 -0
  84. package/dist/domain/ports/k8s-deployer.port.js +3 -0
  85. package/dist/domain/ports/logger.port.js +14 -0
  86. package/dist/domain/ports/output.port.js +3 -0
  87. package/dist/domain/ports/runtime-environment.port.js +6 -0
  88. package/dist/domain/ports/user-interaction.port.js +9 -0
  89. package/dist/domain/ports/user-settings.port.js +3 -0
  90. package/dist/domain/types/index.js +22 -0
  91. package/dist/domain/types/logger.types.js +29 -0
  92. package/dist/domain/types/validation.types.js +9 -0
  93. package/dist/domain/value-objects/acr-credentials.value-object.js +92 -0
  94. package/dist/domain/value-objects/chart-version.value-object.js +124 -0
  95. package/dist/domain/value-objects/config-log-level.value-object.js +84 -0
  96. package/dist/domain/value-objects/connection-info.value-object.js +65 -0
  97. package/dist/domain/value-objects/index.js +25 -0
  98. package/dist/domain/value-objects/instance-name.value-object.js +91 -0
  99. package/dist/domain/value-objects/jwt-key.value-object.js +97 -0
  100. package/dist/domain/value-objects/mssql-password.value-object.js +140 -0
  101. package/dist/domain/value-objects/rsa-key-pair.value-object.js +181 -0
  102. package/dist/index.js +6 -0
  103. package/dist/infrastructure/config/app-config.interface.js +3 -0
  104. package/dist/infrastructure/config/app-config.service.js +280 -0
  105. package/dist/infrastructure/config/config-validator.js +31 -0
  106. package/dist/infrastructure/config/crypto.service.js +125 -0
  107. package/dist/infrastructure/deployment/deployment.adapter.js +118 -0
  108. package/dist/infrastructure/deployment/interfaces/acr-credential-manager.interface.js +3 -0
  109. package/dist/infrastructure/deployment/interfaces/app-manager.interface.js +3 -0
  110. package/dist/infrastructure/deployment/interfaces/helm-registry.interface.js +3 -0
  111. package/dist/infrastructure/deployment/interfaces/infra-manager.interface.js +3 -0
  112. package/dist/infrastructure/deployment/interfaces/k8s-job-runner.interface.js +3 -0
  113. package/dist/infrastructure/deployment/interfaces/mssql-database-init.interface.js +3 -0
  114. package/dist/infrastructure/deployment/interfaces/mssql-helm-deployment.interface.js +3 -0
  115. package/dist/infrastructure/deployment/interfaces/mssql-storage.interface.js +3 -0
  116. package/dist/infrastructure/deployment/interfaces/mssql-user-manager.interface.js +3 -0
  117. package/dist/infrastructure/deployment/interfaces/oci-artifact.interface.js +3 -0
  118. package/dist/infrastructure/deployment/interfaces/secret-manager.interface.js +3 -0
  119. package/dist/infrastructure/deployment/interfaces/service-manager.interface.js +3 -0
  120. package/dist/infrastructure/deployment/interfaces/version-compatibility.interface.js +3 -0
  121. package/dist/infrastructure/deployment/services/acr-credential-manager.service.js +144 -0
  122. package/dist/infrastructure/deployment/services/app-manager.service.js +193 -0
  123. package/dist/infrastructure/deployment/services/base-helm-deployment.service.js +163 -0
  124. package/dist/infrastructure/deployment/services/helm-registry.service.js +126 -0
  125. package/dist/infrastructure/deployment/services/infra-manager.service.js +130 -0
  126. package/dist/infrastructure/deployment/services/k8s-job-runner.service.js +194 -0
  127. package/dist/infrastructure/deployment/services/mssql-database-init.service.js +139 -0
  128. package/dist/infrastructure/deployment/services/mssql-helm-deployment.service.js +100 -0
  129. package/dist/infrastructure/deployment/services/mssql-storage.service.js +54 -0
  130. package/dist/infrastructure/deployment/services/mssql-user-manager.service.js +66 -0
  131. package/dist/infrastructure/deployment/services/oci-artifact.service.js +289 -0
  132. package/dist/infrastructure/deployment/services/secret-manager.service.js +179 -0
  133. package/dist/infrastructure/deployment/services/service-manager.service.js +82 -0
  134. package/dist/infrastructure/deployment/services/version-compatibility.service.js +291 -0
  135. package/dist/infrastructure/environment/interfaces/hardware-info.interface.js +3 -0
  136. package/dist/infrastructure/environment/interfaces/network-checker.interface.js +3 -0
  137. package/dist/infrastructure/environment/services/hardware-info.service.js +135 -0
  138. package/dist/infrastructure/environment/services/network-checker.service.js +142 -0
  139. package/dist/infrastructure/environment/windows-environment.adapter.js +162 -0
  140. package/dist/infrastructure/errors/app-error.js +73 -0
  141. package/dist/infrastructure/errors/error-handler.interface.js +3 -0
  142. package/dist/infrastructure/errors/error-handler.js +218 -0
  143. package/dist/infrastructure/errors/exit-codes.js +27 -0
  144. package/dist/infrastructure/errors/index.js +25 -0
  145. package/dist/infrastructure/execution/builders/base-command.builder.js +122 -0
  146. package/dist/infrastructure/execution/builders/host-command.builder.js +58 -0
  147. package/dist/infrastructure/execution/builders/windows-host-command.builder.js +50 -0
  148. package/dist/infrastructure/execution/builders/wsl-command.builder.js +29 -0
  149. package/dist/infrastructure/execution/command-builder.js +252 -0
  150. package/dist/infrastructure/execution/command-executor.service.js +230 -0
  151. package/dist/infrastructure/execution/environments/wsl-execution.environment.js +70 -0
  152. package/dist/infrastructure/execution/execution-environment.factory.js +53 -0
  153. package/dist/infrastructure/execution/index.js +25 -0
  154. package/dist/infrastructure/execution/interfaces/command-builder.interface.js +3 -0
  155. package/dist/infrastructure/execution/interfaces/command-executor.interface.js +3 -0
  156. package/dist/infrastructure/execution/interfaces/execution-environment-factory.interface.js +3 -0
  157. package/dist/infrastructure/execution/interfaces/execution-environment.interface.js +7 -0
  158. package/dist/infrastructure/execution/interfaces/host-command-builder.interface.js +3 -0
  159. package/dist/infrastructure/execution/interfaces/index.js +23 -0
  160. package/dist/infrastructure/execution/interfaces/script-executor.interface.js +3 -0
  161. package/dist/infrastructure/execution/script-executor.service.js +171 -0
  162. package/dist/infrastructure/http/http-client.service.js +176 -0
  163. package/dist/infrastructure/http/index.js +18 -0
  164. package/dist/infrastructure/http/interfaces/http-client.interface.js +3 -0
  165. package/dist/infrastructure/interceptors/index.js +8 -0
  166. package/dist/infrastructure/interceptors/interceptor.factory.js +44 -0
  167. package/dist/infrastructure/interceptors/interceptor.interface.js +3 -0
  168. package/dist/infrastructure/interceptors/logging.interceptor.js +171 -0
  169. package/dist/infrastructure/logger/correlation-id.adapter.js +68 -0
  170. package/dist/infrastructure/logger/index.js +23 -0
  171. package/dist/infrastructure/logger/interfaces/index.js +22 -0
  172. package/dist/infrastructure/logger/interfaces/log-reader.repository.interface.js +7 -0
  173. package/dist/infrastructure/logger/interfaces/log-writer.repository.interface.js +7 -0
  174. package/dist/infrastructure/logger/logger.adapter.js +274 -0
  175. package/dist/infrastructure/logger/services/file-log-reader.repository.js +148 -0
  176. package/dist/infrastructure/logger/services/file-log-writer.repository.js +307 -0
  177. package/dist/infrastructure/logger/services/index.js +22 -0
  178. package/dist/infrastructure/persistence/index.js +25 -0
  179. package/dist/infrastructure/persistence/instance-metadata.adapter.js +100 -0
  180. package/dist/infrastructure/persistence/instance-storage.adapter.js +64 -0
  181. package/dist/infrastructure/persistence/interfaces/config.repository.interface.js +3 -0
  182. package/dist/infrastructure/persistence/interfaces/index.js +22 -0
  183. package/dist/infrastructure/persistence/interfaces/instance.repository.interface.js +3 -0
  184. package/dist/infrastructure/persistence/services/file-system-config.repository.js +168 -0
  185. package/dist/infrastructure/persistence/services/file-system-instance.repository.js +170 -0
  186. package/dist/infrastructure/persistence/services/index.js +22 -0
  187. package/dist/infrastructure/persistence/user-settings.adapter.js +55 -0
  188. package/dist/infrastructure/platform-detector.js +71 -0
  189. package/dist/infrastructure/platforms/windows/interfaces/microk8s.interface.js +3 -0
  190. package/dist/infrastructure/platforms/windows/interfaces/rootfs-manager.interface.js +3 -0
  191. package/dist/infrastructure/platforms/windows/interfaces/windows-features.interface.js +3 -0
  192. package/dist/infrastructure/platforms/windows/interfaces/windows-info.interface.js +3 -0
  193. package/dist/infrastructure/platforms/windows/interfaces/wsl-config.interface.js +3 -0
  194. package/dist/infrastructure/platforms/windows/interfaces/wsl-info.interface.js +3 -0
  195. package/dist/infrastructure/platforms/windows/interfaces/wsl-instance-inspection.interface.js +3 -0
  196. package/dist/infrastructure/platforms/windows/interfaces/wsl-instance-lifecycle.interface.js +3 -0
  197. package/dist/infrastructure/platforms/windows/interfaces/wsl-instance-naming.interface.js +3 -0
  198. package/dist/infrastructure/platforms/windows/interfaces/wsl-manager.interface.js +3 -0
  199. package/dist/infrastructure/platforms/windows/interfaces/wsl-resources.interface.js +8 -0
  200. package/dist/infrastructure/platforms/windows/interfaces/wsl-updater.interface.js +3 -0
  201. package/dist/infrastructure/platforms/windows/interfaces/wslconfig-parser.interface.js +3 -0
  202. package/dist/infrastructure/platforms/windows/parsers/wsl-version.parser.js +133 -0
  203. package/dist/infrastructure/platforms/windows/services/microk8s.service.js +168 -0
  204. package/dist/infrastructure/platforms/windows/services/rootfs-manager.service.js +336 -0
  205. package/dist/infrastructure/platforms/windows/services/windows-features.service.js +191 -0
  206. package/dist/infrastructure/platforms/windows/services/windows-info.service.js +138 -0
  207. package/dist/infrastructure/platforms/windows/services/wsl-config.service.js +171 -0
  208. package/dist/infrastructure/platforms/windows/services/wsl-info.service.js +226 -0
  209. package/dist/infrastructure/platforms/windows/services/wsl-instance-inspection.service.js +325 -0
  210. package/dist/infrastructure/platforms/windows/services/wsl-instance-lifecycle.service.js +442 -0
  211. package/dist/infrastructure/platforms/windows/services/wsl-instance-naming.service.js +93 -0
  212. package/dist/infrastructure/platforms/windows/services/wsl-updater.service.js +273 -0
  213. package/dist/infrastructure/platforms/windows/services/wslconfig-parser.service.js +222 -0
  214. package/dist/infrastructure/platforms/windows/wsl-base-image.adapter.js +41 -0
  215. package/dist/infrastructure/platforms/windows/wsl-instance-manager.adapter.js +150 -0
  216. package/dist/infrastructure/utils/error-formatter.util.js +29 -0
  217. package/dist/infrastructure/utils/file-operations.util.js +201 -0
  218. package/dist/infrastructure/utils/input-validator.util.js +152 -0
  219. package/dist/infrastructure/utils/retry.util.js +98 -0
  220. package/dist/presentation/controllers/config.controller.js +146 -0
  221. package/dist/presentation/controllers/credentials.controller.js +105 -0
  222. package/dist/presentation/controllers/index.js +25 -0
  223. package/dist/presentation/controllers/instance.controller.js +363 -0
  224. package/dist/presentation/controllers/logs.controller.js +103 -0
  225. package/dist/presentation/controllers/setup.controller.js +175 -0
  226. package/dist/presentation/interfaces/cli-options.interface.js +8 -0
  227. package/dist/presentation/prompts/acr-credentials.prompt.js +76 -0
  228. package/dist/presentation/prompts/index.js +21 -0
  229. package/dist/presentation/ui/cli-progress.service.js +193 -0
  230. package/dist/presentation/ui/constants/output-symbols.js +42 -0
  231. package/dist/presentation/ui/index.js +27 -0
  232. package/dist/presentation/ui/interaction.service.js +276 -0
  233. package/dist/presentation/ui/interfaces/cli-progress.interface.js +9 -0
  234. package/dist/presentation/ui/interfaces/output-formatter.interface.js +23 -0
  235. package/dist/presentation/ui/log-level.enum.js +66 -0
  236. package/dist/presentation/ui/output-builder.service.js +378 -0
  237. package/dist/presentation/ui/output-formatter.service.js +393 -0
  238. package/package.json +65 -0
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CredentialsController = void 0;
16
+ const tsyringe_1 = require("tsyringe");
17
+ const tokens_1 = require("../../di/tokens");
18
+ const get_credentials_use_case_1 = require("../../application/use-cases/credentials/get-credentials.use-case");
19
+ const error_formatter_util_1 = require("../../infrastructure/utils/error-formatter.util");
20
+ /**
21
+ * Credentials Controller
22
+ *
23
+ * 處理憑證相關的 CLI 命令
24
+ */
25
+ let CredentialsController = class CredentialsController {
26
+ constructor(getCredentialsUseCase, output) {
27
+ this.getCredentialsUseCase = getCredentialsUseCase;
28
+ this.output = output;
29
+ }
30
+ /**
31
+ * 取得實例憑證
32
+ * @param name - 實例名稱
33
+ * @param reveal - 是否顯示完整憑證
34
+ */
35
+ async get(name, reveal = false) {
36
+ try {
37
+ const credentials = await this.getCredentialsUseCase.execute({ name });
38
+ if (!credentials) {
39
+ this.output
40
+ .error(`Credentials not found for instance ${name}`)
41
+ .render();
42
+ return;
43
+ }
44
+ this.output
45
+ .newline()
46
+ .section(`Credentials for instance '${name}'`)
47
+ .divider()
48
+ .newline()
49
+ .section('Database Credentials')
50
+ .item('bullet', `SA Default Password: ${this.maskPassword(credentials.saPassword, reveal)}`)
51
+ .newline()
52
+ .section('UofX Admin Credentials')
53
+ .item('bullet', 'Username: uofxadmin')
54
+ .item('bullet', `Default Password: ${this.maskPassword(credentials.adminPassword, reveal)}`)
55
+ .newline();
56
+ // 顯示安全警告
57
+ if (reveal) {
58
+ this.output
59
+ .warning('Full credentials displayed. Clear your terminal history to avoid exposing secrets.');
60
+ }
61
+ else {
62
+ this.output
63
+ .info('Passwords are masked for security. Use --reveal to show full credentials.');
64
+ }
65
+ this.output
66
+ .newline()
67
+ .section('Important')
68
+ .item('bullet', 'Keep these credentials secure')
69
+ .item('bullet', 'Do not share passwords in plain text')
70
+ .newline()
71
+ .render();
72
+ }
73
+ catch (error) {
74
+ this.output
75
+ .error(`Failed to retrieve credentials: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
76
+ .render();
77
+ throw error;
78
+ }
79
+ }
80
+ /**
81
+ * 遮罩密碼 - 僅顯示後 4 碼
82
+ * @param password - 原始密碼
83
+ * @param reveal - 是否顯示完整密碼
84
+ */
85
+ maskPassword(password, reveal) {
86
+ if (!password) {
87
+ return '';
88
+ }
89
+ if (reveal) {
90
+ return password;
91
+ }
92
+ if (password.length <= 4) {
93
+ return '****';
94
+ }
95
+ return '****' + password.slice(-4);
96
+ }
97
+ };
98
+ exports.CredentialsController = CredentialsController;
99
+ exports.CredentialsController = CredentialsController = __decorate([
100
+ (0, tsyringe_1.injectable)(),
101
+ __param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.GetCredentialsUseCase)),
102
+ __param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.IOutputPort)),
103
+ __metadata("design:paramtypes", [get_credentials_use_case_1.GetCredentialsUseCase, Object])
104
+ ], CredentialsController);
105
+ //# sourceMappingURL=credentials.controller.js.map
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /**
3
+ * Presentation Controllers
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./instance.controller"), exports);
21
+ __exportStar(require("./setup.controller"), exports);
22
+ __exportStar(require("./config.controller"), exports);
23
+ __exportStar(require("./logs.controller"), exports);
24
+ __exportStar(require("./credentials.controller"), exports);
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,363 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.InstanceController = void 0;
16
+ const tsyringe_1 = require("tsyringe");
17
+ const tokens_1 = require("../../di/tokens");
18
+ const install_instance_use_case_1 = require("../../application/use-cases/instance/install-instance.use-case");
19
+ const start_instance_use_case_1 = require("../../application/use-cases/instance/start-instance.use-case");
20
+ const stop_instance_use_case_1 = require("../../application/use-cases/instance/stop-instance.use-case");
21
+ const delete_instance_use_case_1 = require("../../application/use-cases/instance/delete-instance.use-case");
22
+ const list_instances_use_case_1 = require("../../application/use-cases/instance/list-instances.use-case");
23
+ const list_charts_use_case_1 = require("../../application/use-cases/instance/list-charts.use-case");
24
+ const error_formatter_util_1 = require("../../infrastructure/utils/error-formatter.util");
25
+ /**
26
+ * Instance Controller
27
+ *
28
+ * 處理實例相關的 CLI 命令
29
+ */
30
+ let InstanceController = class InstanceController {
31
+ constructor(installUseCase, startUseCase, stopUseCase, deleteUseCase, listUseCase, listChartsUseCase, output, interaction) {
32
+ this.installUseCase = installUseCase;
33
+ this.startUseCase = startUseCase;
34
+ this.stopUseCase = stopUseCase;
35
+ this.deleteUseCase = deleteUseCase;
36
+ this.listUseCase = listUseCase;
37
+ this.listChartsUseCase = listChartsUseCase;
38
+ this.output = output;
39
+ this.interaction = interaction;
40
+ output.resetIndent();
41
+ }
42
+ /**
43
+ * 安裝新實例
44
+ */
45
+ async install(options) {
46
+ try {
47
+ const request = {
48
+ name: options.name,
49
+ chartVersion: options.chartVersion,
50
+ pullSecretPath: options.pullSecret,
51
+ rootfsPath: options.rootfs,
52
+ };
53
+ this.output
54
+ .info(`Installing instance: ${request.name}`)
55
+ .flush();
56
+ const result = await this.installUseCase.execute(request, this.output);
57
+ this.output
58
+ .newline()
59
+ .success(`Instance ${request.name} installed successfully!`);
60
+ // 使用統一格式顯示連線資訊
61
+ this.displayConnectionInfo(result.connectionInfo);
62
+ this.output
63
+ .newline()
64
+ .info('To view credentials, run:')
65
+ .item('bullet', `uofx env list credentials --name ${result.instanceName} --reveal`)
66
+ .render();
67
+ }
68
+ catch (error) {
69
+ this.output
70
+ .error(`Installation failed: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
71
+ .render();
72
+ throw error;
73
+ }
74
+ }
75
+ /**
76
+ * 啟動實例
77
+ */
78
+ async start(name, options) {
79
+ try {
80
+ // 檢查其他運行中的實例
81
+ const otherRunning = await this.startUseCase.listOtherRunningInstances(name);
82
+ if (otherRunning.length > 0) {
83
+ const otherName = otherRunning[0];
84
+ this.output
85
+ .newline()
86
+ .warning(`Another instance is already running: ${otherName}`)
87
+ .flush();
88
+ const shouldStop = await this.interaction.confirm(`Do you want to stop "${otherName}" and start "${name}"?`, false);
89
+ if (!shouldStop) {
90
+ this.output.info('Start cancelled').render();
91
+ return;
92
+ }
93
+ this.output.info(`Stopping ${otherName}...`).flush();
94
+ await this.startUseCase.stopInstance(otherName, this.output);
95
+ this.output.success(`${otherName} stopped`).flush();
96
+ }
97
+ this.output.newline().flush();
98
+ const result = await this.startUseCase.execute({ name, waitForReady: true }, this.output);
99
+ this.output.newline();
100
+ if (result.alreadyRunning) {
101
+ this.output.success(`Instance '${result.instanceName}' is already running`);
102
+ }
103
+ else {
104
+ this.output.success(`Instance '${result.instanceName}' started successfully!`);
105
+ }
106
+ // 顯示連線資訊
107
+ this.displayConnectionInfo(result.connectionInfo);
108
+ if (options?.showCredentials !== false) {
109
+ this.output
110
+ .newline()
111
+ .info('To view credentials, run:')
112
+ .item('bullet', `uofx env list credentials --name ${name} --reveal`);
113
+ }
114
+ this.output.render();
115
+ }
116
+ catch (error) {
117
+ this.output
118
+ .error(`Start failed: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
119
+ .render();
120
+ throw error;
121
+ }
122
+ }
123
+ /**
124
+ * 顯示連線資訊
125
+ */
126
+ displayConnectionInfo(connectionInfo) {
127
+ this.output
128
+ .newline()
129
+ .divider()
130
+ .section('Connection Information')
131
+ .divider();
132
+ if (connectionInfo.adminUrl) {
133
+ this.output
134
+ .newline()
135
+ .section('UofX Services')
136
+ .item('bullet', `Admin Interface: ${connectionInfo.adminUrl}`);
137
+ }
138
+ if (connectionInfo.sqlServer) {
139
+ this.output
140
+ .newline()
141
+ .section('SQL Server')
142
+ .item('bullet', `Server: ${connectionInfo.sqlServer}`)
143
+ .item('bullet', 'User: SA');
144
+ }
145
+ if (!connectionInfo.instanceIp) {
146
+ this.output
147
+ .newline()
148
+ .warning('Could not determine instance IP address');
149
+ }
150
+ this.output.divider();
151
+ }
152
+ /**
153
+ * 停止實例
154
+ */
155
+ async stop(name, options) {
156
+ try {
157
+ const force = options?.force || false;
158
+ this.output
159
+ .info(`Stopping instance: ${name}`)
160
+ .newline()
161
+ .flush();
162
+ const result = await this.stopUseCase.execute({ name, force }, this.output);
163
+ if (result.alreadyStopped) {
164
+ this.output
165
+ .info(`Instance '${result.instanceName}' is already stopped`)
166
+ .newline()
167
+ .info(`To start this instance: uofx env start --name ${name}`)
168
+ .render();
169
+ return;
170
+ }
171
+ this.output
172
+ .success(`Instance ${name} stopped`)
173
+ .render();
174
+ }
175
+ catch (error) {
176
+ this.output
177
+ .error(`Stop failed: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
178
+ .newline()
179
+ .section('Troubleshooting')
180
+ .item('bullet', `Try force stop: uofx env stop --name ${name} --force`)
181
+ .item('bullet', 'Check WSL status: wsl --list --verbose')
182
+ .item('bullet', `Manually terminate: wsl --terminate uofx-${name}`)
183
+ .render();
184
+ throw error;
185
+ }
186
+ }
187
+ /**
188
+ * 刪除實例
189
+ */
190
+ async delete(name, force = false) {
191
+ try {
192
+ // 取得實例詳細資訊
193
+ const details = await this.deleteUseCase.getInstanceDetails(name);
194
+ if (!details) {
195
+ this.output
196
+ .error(`Instance "${name}" not found`)
197
+ .render();
198
+ return;
199
+ }
200
+ // 顯示實例詳細資訊
201
+ const installedDisplay = details.installedAt
202
+ ? new Date(details.installedAt).toLocaleString()
203
+ : 'N/A';
204
+ this.output
205
+ .newline()
206
+ .divider()
207
+ .section('Instance Details')
208
+ .divider()
209
+ .item('bullet', `Name: ${details.name}`)
210
+ .item('bullet', `Status: ${details.isRunning ? 'Running' : 'Stopped'}`)
211
+ .item('bullet', `Chart Version: ${details.chartVersion || 'N/A'}`)
212
+ .item('bullet', `Installed: ${installedDisplay}`)
213
+ .divider()
214
+ .flush();
215
+ if (!force) {
216
+ const confirmed = await this.interaction.confirm(`Are you sure you want to delete instance "${name}"? This action cannot be undone.`, false);
217
+ if (!confirmed) {
218
+ this.output.info('Deletion cancelled').render();
219
+ return;
220
+ }
221
+ }
222
+ this.output
223
+ .newline()
224
+ .info(`Deleting instance: ${name}`)
225
+ .flush();
226
+ const result = await this.deleteUseCase.execute({ name, force }, this.output);
227
+ // 如果停止時有警告,顯示警告
228
+ if (result.stopWarning) {
229
+ this.output
230
+ .warning(result.stopWarning)
231
+ .info('Continuing with deletion...');
232
+ }
233
+ this.output.success(`Instance ${name} deleted`);
234
+ // 顯示剩餘實例數量
235
+ if (result.remainingInstanceCount > 0) {
236
+ this.output
237
+ .newline()
238
+ .info(`Remaining instances: ${result.remainingInstanceCount}`)
239
+ .info('Use "uofx env list" to see all instances.');
240
+ }
241
+ else {
242
+ this.output
243
+ .newline()
244
+ .info('No remaining instances.')
245
+ .info('Use "uofx env install --name <name>" to create a new instance.');
246
+ }
247
+ this.output.render();
248
+ }
249
+ catch (error) {
250
+ this.output
251
+ .error(`Deletion failed: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
252
+ .newline()
253
+ .section('If the instance is corrupted, try manual cleanup')
254
+ .item('bullet', `wsl --unregister uofx-${name}`)
255
+ .item('bullet', 'Delete the instance folder manually')
256
+ .render();
257
+ throw error;
258
+ }
259
+ }
260
+ /**
261
+ * 列出所有實例
262
+ */
263
+ async list() {
264
+ try {
265
+ const result = await this.listUseCase.execute();
266
+ if (result.instances.length === 0) {
267
+ this.output
268
+ .info('No instances found')
269
+ .newline()
270
+ .info('Use the following command to install a new instance:')
271
+ .item('bullet', 'uofx env install --name <name>')
272
+ .render();
273
+ return;
274
+ }
275
+ this.output
276
+ .newline()
277
+ .section('Instances')
278
+ .table(['NAME', 'STATUS', 'VERSION', 'CHART VERSION', 'ADMIN URL', 'SQL SERVER'], result.instances.map(inst => [
279
+ inst.name,
280
+ inst.status,
281
+ inst.wslVersion,
282
+ inst.chartVersion,
283
+ inst.adminUrl ?? '',
284
+ inst.sqlServer ?? '',
285
+ ]))
286
+ .newline()
287
+ .info(`Total: ${result.instances.length} instances`)
288
+ .render();
289
+ }
290
+ catch (error) {
291
+ this.output
292
+ .error(`Failed to list instances: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
293
+ .render();
294
+ throw error;
295
+ }
296
+ }
297
+ /**
298
+ * 列出可用的 Chart 版本
299
+ */
300
+ async listCharts() {
301
+ try {
302
+ const versions = await this.listChartsUseCase.execute({ chartName: 'uofx' });
303
+ if (versions.length === 0) {
304
+ this.output
305
+ .info('No chart versions found')
306
+ .render();
307
+ return;
308
+ }
309
+ this.output
310
+ .newline()
311
+ .section('Available UOFX Chart Versions')
312
+ .table(['VERSION', 'TYPE', 'STATUS'], versions.map((v, i) => [
313
+ v.toString(),
314
+ this.getVersionType(v.toString()),
315
+ i === 0 ? 'Latest' : '',
316
+ ]))
317
+ .newline()
318
+ .info(`Total: ${versions.length} versions available`)
319
+ .newline()
320
+ .info('Use the following command to install a specific version:')
321
+ .item('bullet', 'uofx env install --name <name> --chart-version <version>')
322
+ .render();
323
+ }
324
+ catch (error) {
325
+ this.output
326
+ .error(`Failed to query chart versions: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
327
+ .render();
328
+ throw error;
329
+ }
330
+ }
331
+ /**
332
+ * 判斷版本類型 (Beta/Stable)
333
+ */
334
+ getVersionType(version) {
335
+ const parts = version.split('.');
336
+ if (parts.length >= 3) {
337
+ const patch = parts[2];
338
+ if (patch.startsWith('2')) {
339
+ return 'Beta';
340
+ }
341
+ }
342
+ return 'Stable';
343
+ }
344
+ };
345
+ exports.InstanceController = InstanceController;
346
+ exports.InstanceController = InstanceController = __decorate([
347
+ (0, tsyringe_1.injectable)(),
348
+ __param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.InstallInstanceUseCase)),
349
+ __param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.StartInstanceUseCase)),
350
+ __param(2, (0, tsyringe_1.inject)(tokens_1.TOKENS.StopInstanceUseCase)),
351
+ __param(3, (0, tsyringe_1.inject)(tokens_1.TOKENS.DeleteInstanceUseCase)),
352
+ __param(4, (0, tsyringe_1.inject)(tokens_1.TOKENS.ListInstancesUseCase)),
353
+ __param(5, (0, tsyringe_1.inject)(tokens_1.TOKENS.ListChartsUseCase)),
354
+ __param(6, (0, tsyringe_1.inject)(tokens_1.TOKENS.IOutputPort)),
355
+ __param(7, (0, tsyringe_1.inject)(tokens_1.TOKENS.IUserInteractionPort)),
356
+ __metadata("design:paramtypes", [install_instance_use_case_1.InstallInstanceUseCase,
357
+ start_instance_use_case_1.StartInstanceUseCase,
358
+ stop_instance_use_case_1.StopInstanceUseCase,
359
+ delete_instance_use_case_1.DeleteInstanceUseCase,
360
+ list_instances_use_case_1.ListInstancesUseCase,
361
+ list_charts_use_case_1.ListChartsUseCase, Object, Object])
362
+ ], InstanceController);
363
+ //# sourceMappingURL=instance.controller.js.map
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.LogsController = void 0;
16
+ const tsyringe_1 = require("tsyringe");
17
+ const tokens_1 = require("../../di/tokens");
18
+ const show_logs_use_case_1 = require("../../application/use-cases/logs/show-logs.use-case");
19
+ const error_formatter_util_1 = require("../../infrastructure/utils/error-formatter.util");
20
+ /**
21
+ * Logs Controller
22
+ *
23
+ * 處理日誌相關的 CLI 命令
24
+ */
25
+ let LogsController = class LogsController {
26
+ constructor(showLogsUseCase, output) {
27
+ this.showLogsUseCase = showLogsUseCase;
28
+ this.output = output;
29
+ }
30
+ /**
31
+ * 顯示日志
32
+ */
33
+ async show(options) {
34
+ try {
35
+ const request = {
36
+ lines: options.lines || 50,
37
+ level: options.level,
38
+ since: options.since,
39
+ correlation: options.correlation,
40
+ command: options.command,
41
+ commandGroup: options.commandGroup,
42
+ follow: options.follow || false,
43
+ };
44
+ const result = await this.showLogsUseCase.execute(request);
45
+ this.formatAndDisplayLogs(result);
46
+ }
47
+ catch (error) {
48
+ this.output
49
+ .error(`Failed to show logs: ${(0, error_formatter_util_1.formatErrorMessage)(error)}`)
50
+ .render();
51
+ throw error;
52
+ }
53
+ }
54
+ /**
55
+ * 格式化並顯示日誌
56
+ */
57
+ formatAndDisplayLogs(result) {
58
+ // 檢查是否有日誌
59
+ if (result.entries.length === 0) {
60
+ this.output
61
+ .info('No logs found matching the criteria.')
62
+ .render();
63
+ return;
64
+ }
65
+ // 顯示每個日誌項目
66
+ result.entries.forEach(entry => {
67
+ const level = entry.level.padEnd(5);
68
+ let logLine = `[${entry.timestamp}] ${level} ${entry.message}`;
69
+ // 顯示 correlation ID
70
+ if (entry.correlationId) {
71
+ logLine += ` (correlation: ${entry.correlationId})`;
72
+ }
73
+ // 顯示命令資訊
74
+ if (entry.command) {
75
+ logLine += ` [${entry.command}]`;
76
+ }
77
+ this.output.line(logLine);
78
+ // 顯示錯誤堆疊
79
+ if (entry.errorStack) {
80
+ this.output.indent().item('bullet', `Stack: ${entry.errorStack}`).outdent();
81
+ }
82
+ });
83
+ // 顯示總計
84
+ this.output
85
+ .newline()
86
+ .info(`--- Total: ${result.total} entries ---`);
87
+ // 如果是追蹤模式,顯示提示
88
+ if (result.isFollowing) {
89
+ this.output
90
+ .newline()
91
+ .info('[Following logs... Press Ctrl+C to exit]');
92
+ }
93
+ this.output.render();
94
+ }
95
+ };
96
+ exports.LogsController = LogsController;
97
+ exports.LogsController = LogsController = __decorate([
98
+ (0, tsyringe_1.injectable)(),
99
+ __param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.ShowLogsUseCase)),
100
+ __param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.IOutputPort)),
101
+ __metadata("design:paramtypes", [show_logs_use_case_1.ShowLogsUseCase, Object])
102
+ ], LogsController);
103
+ //# sourceMappingURL=logs.controller.js.map