@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,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Credentials = void 0;
4
+ const instance_name_value_object_1 = require("../value-objects/instance-name.value-object");
5
+ const mssql_password_value_object_1 = require("../value-objects/mssql-password.value-object");
6
+ const rsa_key_pair_value_object_1 = require("../value-objects/rsa-key-pair.value-object");
7
+ const jwt_key_value_object_1 = require("../value-objects/jwt-key.value-object");
8
+ /**
9
+ * 憑證 Entity
10
+ *
11
+ * 儲存實例的各項憑證資訊
12
+ */
13
+ class Credentials {
14
+ constructor(
15
+ /** 實例名稱 */
16
+ instanceName,
17
+ /** SA 密碼 */
18
+ saPassword,
19
+ /** Admin 密碼 */
20
+ adminPassword,
21
+ /** SignIn RSA 金鑰對 */
22
+ signInRsaKeys,
23
+ /** Uofx RSA 金鑰對 */
24
+ uofxRsaKeys,
25
+ /** JWT 簽署金鑰 */
26
+ jwtKey,
27
+ /** UofxDb 連線字串 */
28
+ connectionStringUofxDb,
29
+ /** UofxSearchDb 連線字串 */
30
+ connectionStringUofxSearchDb) {
31
+ this.instanceName = instanceName;
32
+ this.saPassword = saPassword;
33
+ this.adminPassword = adminPassword;
34
+ this.signInRsaKeys = signInRsaKeys;
35
+ this.uofxRsaKeys = uofxRsaKeys;
36
+ this.jwtKey = jwtKey;
37
+ this.connectionStringUofxDb = connectionStringUofxDb;
38
+ this.connectionStringUofxSearchDb = connectionStringUofxSearchDb;
39
+ }
40
+ /**
41
+ * 從原始物件建立 Credentials
42
+ */
43
+ static fromObject(data) {
44
+ return new Credentials(instance_name_value_object_1.InstanceName.create(data.instanceName), mssql_password_value_object_1.MssqlPassword.create(data.saPassword), mssql_password_value_object_1.MssqlPassword.create(data.adminPassword), rsa_key_pair_value_object_1.RsaKeyPair.create(data.signInRsaPrivateKey, data.signInRsaPublicKey), rsa_key_pair_value_object_1.RsaKeyPair.create(data.uofxRsaPrivateKey, data.uofxRsaPublicKey), jwt_key_value_object_1.JwtKey.create(data.jwtSigningKey), data.connectionStringUofxDb, data.connectionStringUofxSearchDb);
45
+ }
46
+ /**
47
+ * 轉換為回應 DTO
48
+ */
49
+ toResponseDto() {
50
+ return {
51
+ instanceName: this.instanceName.toString(),
52
+ saPassword: this.saPassword.toString(),
53
+ adminPassword: this.adminPassword.toString(),
54
+ signInRsaPrivateKey: this.signInRsaKeys.privateKey,
55
+ signInRsaPublicKey: this.signInRsaKeys.publicKey,
56
+ uofxRsaPrivateKey: this.uofxRsaKeys.privateKey,
57
+ uofxRsaPublicKey: this.uofxRsaKeys.publicKey,
58
+ jwtSigningKey: this.jwtKey.toString(),
59
+ connectionStringUofxDb: this.connectionStringUofxDb,
60
+ connectionStringUofxSearchDb: this.connectionStringUofxSearchDb,
61
+ };
62
+ }
63
+ }
64
+ exports.Credentials = Credentials;
65
+ //# sourceMappingURL=credentials.entity.js.map
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeleteInstanceValidation = void 0;
4
+ /**
5
+ * 刪除實例驗證 Entity
6
+ *
7
+ * 封裝刪除實例的驗證邏輯:
8
+ * - 運行中 + 無 force → 不允許刪除
9
+ * - 運行中 + force → 允許刪除,但需先停止
10
+ * - 已停止 → 直接允許刪除
11
+ */
12
+ class DeleteInstanceValidation {
13
+ constructor(instanceName, isRunning, force) {
14
+ this.instanceName = instanceName;
15
+ this.isRunning = isRunning;
16
+ this.force = force;
17
+ }
18
+ /**
19
+ * 從實例狀態建立驗證物件
20
+ * @param status - 實例狀態
21
+ * @param force - 是否強制刪除
22
+ * @returns 驗證物件
23
+ */
24
+ static fromStatus(status, force) {
25
+ return new DeleteInstanceValidation(status.name, status.isRunning, force);
26
+ }
27
+ /**
28
+ * 建立運行中狀態的驗證物件
29
+ * @param instanceName - 實例名稱
30
+ * @param force - 是否強制刪除
31
+ * @returns 驗證物件
32
+ */
33
+ static running(instanceName, force) {
34
+ return new DeleteInstanceValidation(instanceName, true, force);
35
+ }
36
+ /**
37
+ * 建立已停止狀態的驗證物件
38
+ * @param instanceName - 實例名稱
39
+ * @returns 驗證物件
40
+ */
41
+ static stopped(instanceName) {
42
+ return new DeleteInstanceValidation(instanceName, false, false);
43
+ }
44
+ /**
45
+ * 驗證是否可以刪除
46
+ * @returns 驗證結果
47
+ */
48
+ validate() {
49
+ // 已停止:直接允許刪除
50
+ if (!this.isRunning) {
51
+ return {
52
+ canDelete: true,
53
+ needsStop: false,
54
+ };
55
+ }
56
+ // 運行中 + 無 force:不允許刪除
57
+ if (!this.force) {
58
+ return {
59
+ canDelete: false,
60
+ needsStop: false,
61
+ errorMessage: `Instance "${this.instanceName}" is running. Stop it first or use --force flag.`,
62
+ };
63
+ }
64
+ // 運行中 + force:允許刪除,但需先停止
65
+ return {
66
+ canDelete: true,
67
+ needsStop: true,
68
+ };
69
+ }
70
+ /**
71
+ * 是否可以刪除
72
+ */
73
+ get canDelete() {
74
+ return this.validate().canDelete;
75
+ }
76
+ /**
77
+ * 是否需要先停止實例
78
+ */
79
+ get needsStop() {
80
+ return this.validate().needsStop;
81
+ }
82
+ /**
83
+ * 取得錯誤訊息(如果不允許刪除)
84
+ */
85
+ get errorMessage() {
86
+ return this.validate().errorMessage;
87
+ }
88
+ /**
89
+ * 如果不允許刪除則拋出錯誤
90
+ * @throws Error 如果不允許刪除
91
+ */
92
+ assertCanDelete() {
93
+ const result = this.validate();
94
+ if (!result.canDelete) {
95
+ throw new Error(result.errorMessage);
96
+ }
97
+ }
98
+ }
99
+ exports.DeleteInstanceValidation = DeleteInstanceValidation;
100
+ //# sourceMappingURL=delete-instance-validation.entity.js.map
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeploymentParameters = void 0;
4
+ const mssql_password_value_object_1 = require("../value-objects/mssql-password.value-object");
5
+ const jwt_key_value_object_1 = require("../value-objects/jwt-key.value-object");
6
+ const rsa_key_pair_value_object_1 = require("../value-objects/rsa-key-pair.value-object");
7
+ /**
8
+ * 部署參數 Entity
9
+ *
10
+ * 聚合所有部署所需的憑證與參數
11
+ */
12
+ class DeploymentParameters {
13
+ constructor(instanceName, saPassword, adminPassword, signInRsaKeys, uofxRsaKeys, jwtKey, acrCredentials) {
14
+ this.instanceName = instanceName;
15
+ this.saPassword = saPassword;
16
+ this.adminPassword = adminPassword;
17
+ this.signInRsaKeys = signInRsaKeys;
18
+ this.uofxRsaKeys = uofxRsaKeys;
19
+ this.jwtKey = jwtKey;
20
+ this.acrCredentials = acrCredentials;
21
+ }
22
+ /**
23
+ * 建立部署參數
24
+ * @param instanceName - 實例名稱
25
+ * @param saPassword - SA 密碼
26
+ * @param adminPassword - Admin 密碼
27
+ * @param signInRsaKeys - SignIn RSA 金鑰對
28
+ * @param uofxRsaKeys - Uofx RSA 金鑰對
29
+ * @param jwtKey - JWT 金鑰
30
+ * @param acrCredentials - ACR 憑證
31
+ * @returns 部署參數物件
32
+ */
33
+ static create(instanceName, saPassword, adminPassword, signInRsaKeys, uofxRsaKeys, jwtKey, acrCredentials) {
34
+ return new DeploymentParameters(instanceName, saPassword, adminPassword, signInRsaKeys, uofxRsaKeys, jwtKey, acrCredentials);
35
+ }
36
+ /**
37
+ * 使用自動生成的憑證建立部署參數
38
+ * @param instanceName - 實例名稱
39
+ * @param acrCredentials - ACR 憑證
40
+ * @returns 部署參數物件
41
+ */
42
+ static createWithGeneratedCredentials(instanceName, acrCredentials) {
43
+ return new DeploymentParameters(instanceName, mssql_password_value_object_1.MssqlPassword.generate(), mssql_password_value_object_1.MssqlPassword.generate(), rsa_key_pair_value_object_1.RsaKeyPair.generate(), rsa_key_pair_value_object_1.RsaKeyPair.generate(), jwt_key_value_object_1.JwtKey.generate(), acrCredentials);
44
+ }
45
+ /**
46
+ * 取得 MSSQL 連線字串
47
+ * @param database - 資料庫名稱
48
+ * @param user - 使用者名稱
49
+ * @param password - 密碼
50
+ * @returns 連線字串
51
+ */
52
+ getConnectionString(database, user, password) {
53
+ return `Server=uofx-mssql-service;Database=${database};User Id=${user};Password=${password.toString()};TrustServerCertificate=True;`;
54
+ }
55
+ /**
56
+ * 取得 UofxDb 連線字串
57
+ * @returns 連線字串
58
+ */
59
+ get connectionStringUofxDb() {
60
+ return this.getConnectionString('UofxDb', 'admin', this.adminPassword);
61
+ }
62
+ /**
63
+ * 取得 UofxSearchDb 連線字串
64
+ * @returns 連線字串
65
+ */
66
+ get connectionStringUofxSearchDb() {
67
+ return this.getConnectionString('UofxSearchDb', 'admin', this.adminPassword);
68
+ }
69
+ /**
70
+ * 轉換為 Helm 部署格式
71
+ * @returns 包含所有參數的物件(值已編碼)
72
+ */
73
+ toHelmParameters() {
74
+ return {
75
+ saPasswordB64: Buffer.from(this.saPassword.toString()).toString('base64'),
76
+ adminPasswordB64: Buffer.from(this.adminPassword.toString()).toString('base64'),
77
+ rsaSignInPrivateB64: this.signInRsaKeys.toBase64ForSignIn('private'),
78
+ rsaSignInPublicB64: this.signInRsaKeys.toBase64ForSignIn('public'),
79
+ rsaUofxPrivateB64: this.uofxRsaKeys.toBase64ForUofx('private'),
80
+ rsaUofxPublicB64: this.uofxRsaKeys.toBase64ForUofx('public'),
81
+ jwtKeyB64: this.jwtKey.toBase64(),
82
+ connectionStringUofxDb: this.connectionStringUofxDb,
83
+ connectionStringUofxSearchDb: this.connectionStringUofxSearchDb,
84
+ };
85
+ }
86
+ /**
87
+ * 轉換為一般物件(用於日誌或序列化)
88
+ * 注意:敏感資訊已遮罩
89
+ * @returns 包含參數資訊的物件
90
+ */
91
+ toObject() {
92
+ return {
93
+ instanceName: this.instanceName.toString(),
94
+ saPassword: this.saPassword.toMasked(),
95
+ adminPassword: this.adminPassword.toMasked(),
96
+ acrName: this.acrCredentials.name,
97
+ };
98
+ }
99
+ /**
100
+ * 回傳可安全記錄到日志的物件
101
+ * 所有敏感欄位(密碼、金鑰)將被遮罩
102
+ *
103
+ * @returns 遮罩後的物件,可安全寫入日志
104
+ */
105
+ toSafeLog() {
106
+ return {
107
+ instanceName: this.instanceName.toString(),
108
+ saPassword: '***MASKED***',
109
+ adminPassword: '***MASKED***',
110
+ signInRsaKeys: '***MASKED***',
111
+ uofxRsaKeys: '***MASKED***',
112
+ jwtKey: '***MASKED***',
113
+ acrCredentials: this.acrCredentials.toSafeLog(),
114
+ connectionStringUofxDb: '***MASKED***',
115
+ connectionStringUofxSearchDb: '***MASKED***',
116
+ };
117
+ }
118
+ }
119
+ exports.DeploymentParameters = DeploymentParameters;
120
+ //# sourceMappingURL=deployment-parameters.entity.js.map
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnvironmentValidation = void 0;
4
+ /**
5
+ * 環境驗證 Entity
6
+ *
7
+ * 封裝環境驗證的業務邏輯,包括:
8
+ * - 運行環境檢查(WSL 是否已安裝)
9
+ * - 網路連線檢查(是否可連線至 Registry)
10
+ * - 系統資源檢查(記憶體是否足夠)
11
+ */
12
+ class EnvironmentValidation {
13
+ constructor(
14
+ /** 作業系統資訊 */
15
+ osInfo,
16
+ /** 運行環境資訊 */
17
+ runtimeInfo,
18
+ /** 系統資源 */
19
+ systemResources,
20
+ /** 網路狀態 */
21
+ networkStatus) {
22
+ this.osInfo = osInfo;
23
+ this.runtimeInfo = runtimeInfo;
24
+ this.systemResources = systemResources;
25
+ this.networkStatus = networkStatus;
26
+ }
27
+ /**
28
+ * 建立環境驗證實例
29
+ * @param osInfo - 作業系統資訊
30
+ * @param runtimeInfo - 運行環境資訊
31
+ * @param systemResources - 系統資源
32
+ * @param networkStatus - 網路狀態
33
+ * @returns EnvironmentValidation 實例
34
+ */
35
+ static create(osInfo, runtimeInfo, systemResources, networkStatus) {
36
+ return new EnvironmentValidation(osInfo, runtimeInfo, systemResources, networkStatus);
37
+ }
38
+ /**
39
+ * 檢查運行環境是否已安裝
40
+ */
41
+ get isRuntimeInstalled() {
42
+ return this.runtimeInfo.isInstalled;
43
+ }
44
+ /**
45
+ * 檢查網路是否正常(在線且可連線至 Registry)
46
+ */
47
+ get isNetworkHealthy() {
48
+ return this.networkStatus.isOnline && this.networkStatus.canReachRegistry;
49
+ }
50
+ /**
51
+ * 檢查是否有足夠的記憶體
52
+ */
53
+ get hasSufficientMemory() {
54
+ return this.systemResources.freeMemory >= EnvironmentValidation.REQUIRED_FREE_MEMORY;
55
+ }
56
+ /**
57
+ * 檢查所有驗證是否通過
58
+ */
59
+ get allChecksPassed() {
60
+ return this.isRuntimeInstalled && this.isNetworkHealthy;
61
+ }
62
+ /**
63
+ * 取得驗證失敗原因列表
64
+ * @returns 失敗原因陣列(若全部通過則為空陣列)
65
+ */
66
+ getFailureReasons() {
67
+ const failures = [];
68
+ if (!this.isRuntimeInstalled) {
69
+ failures.push({
70
+ type: 'runtime',
71
+ message: `${this.runtimeInfo.type} is not installed`,
72
+ });
73
+ }
74
+ if (!this.networkStatus.isOnline) {
75
+ failures.push({
76
+ type: 'network',
77
+ message: 'Network is offline',
78
+ });
79
+ }
80
+ else if (!this.networkStatus.canReachRegistry) {
81
+ failures.push({
82
+ type: 'network',
83
+ message: 'Cannot reach container registry',
84
+ });
85
+ }
86
+ if (!this.hasSufficientMemory) {
87
+ const requiredGb = EnvironmentValidation.REQUIRED_FREE_MEMORY / (1024 * 1024 * 1024);
88
+ const freeGb = (this.systemResources.freeMemory / (1024 * 1024 * 1024)).toFixed(1);
89
+ failures.push({
90
+ type: 'memory',
91
+ message: `Insufficient memory: ${freeGb}GB available, ${requiredGb}GB required`,
92
+ });
93
+ }
94
+ return failures;
95
+ }
96
+ /**
97
+ * 取得驗證失敗訊息(用於顯示)
98
+ * @returns 失敗訊息字串陣列
99
+ */
100
+ getFailureMessages() {
101
+ return this.getFailureReasons().map(f => f.message);
102
+ }
103
+ /**
104
+ * 取得可用記憶體(GB)
105
+ */
106
+ get freeMemoryGb() {
107
+ return this.systemResources.freeMemory / (1024 * 1024 * 1024);
108
+ }
109
+ /**
110
+ * 取得總記憶體(GB)
111
+ */
112
+ get totalMemoryGb() {
113
+ return this.systemResources.totalMemory / (1024 * 1024 * 1024);
114
+ }
115
+ /**
116
+ * 取得最低記憶體需求(GB)
117
+ */
118
+ static get requiredMemoryGb() {
119
+ return EnvironmentValidation.REQUIRED_FREE_MEMORY / (1024 * 1024 * 1024);
120
+ }
121
+ }
122
+ exports.EnvironmentValidation = EnvironmentValidation;
123
+ /** 最低可用記憶體需求(16GB) */
124
+ EnvironmentValidation.REQUIRED_FREE_MEMORY = 16 * 1024 * 1024 * 1024;
125
+ //# sourceMappingURL=environment-validation.entity.js.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /**
3
+ * Domain Entities
4
+ *
5
+ * 業務核心實體,封裝業務邏輯與狀態
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.CredentialsResolver = exports.DeleteInstanceValidation = exports.InstanceListAggregator = exports.EnvironmentValidation = exports.InstanceLifecycleState = exports.LogFilter = exports.DeploymentParameters = exports.InstanceStatus = exports.InstanceMetadata = exports.Instance = void 0;
9
+ var instance_entity_1 = require("./instance.entity");
10
+ Object.defineProperty(exports, "Instance", { enumerable: true, get: function () { return instance_entity_1.Instance; } });
11
+ var instance_metadata_entity_1 = require("./instance-metadata.entity");
12
+ Object.defineProperty(exports, "InstanceMetadata", { enumerable: true, get: function () { return instance_metadata_entity_1.InstanceMetadata; } });
13
+ var instance_status_entity_1 = require("./instance-status.entity");
14
+ Object.defineProperty(exports, "InstanceStatus", { enumerable: true, get: function () { return instance_status_entity_1.InstanceStatus; } });
15
+ var deployment_parameters_entity_1 = require("./deployment-parameters.entity");
16
+ Object.defineProperty(exports, "DeploymentParameters", { enumerable: true, get: function () { return deployment_parameters_entity_1.DeploymentParameters; } });
17
+ var log_filter_entity_1 = require("./log-filter.entity");
18
+ Object.defineProperty(exports, "LogFilter", { enumerable: true, get: function () { return log_filter_entity_1.LogFilter; } });
19
+ var instance_lifecycle_state_entity_1 = require("./instance-lifecycle-state.entity");
20
+ Object.defineProperty(exports, "InstanceLifecycleState", { enumerable: true, get: function () { return instance_lifecycle_state_entity_1.InstanceLifecycleState; } });
21
+ var environment_validation_entity_1 = require("./environment-validation.entity");
22
+ Object.defineProperty(exports, "EnvironmentValidation", { enumerable: true, get: function () { return environment_validation_entity_1.EnvironmentValidation; } });
23
+ var instance_list_aggregator_entity_1 = require("./instance-list-aggregator.entity");
24
+ Object.defineProperty(exports, "InstanceListAggregator", { enumerable: true, get: function () { return instance_list_aggregator_entity_1.InstanceListAggregator; } });
25
+ var delete_instance_validation_entity_1 = require("./delete-instance-validation.entity");
26
+ Object.defineProperty(exports, "DeleteInstanceValidation", { enumerable: true, get: function () { return delete_instance_validation_entity_1.DeleteInstanceValidation; } });
27
+ var credentials_resolver_entity_1 = require("./credentials-resolver.entity");
28
+ Object.defineProperty(exports, "CredentialsResolver", { enumerable: true, get: function () { return credentials_resolver_entity_1.CredentialsResolver; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InstanceLifecycleState = void 0;
4
+ /**
5
+ * 實例生命週期狀態 Entity
6
+ *
7
+ * 封裝實例的運行狀態判斷邏輯,包括 WSL 和 MicroK8s 的狀態組合
8
+ *
9
+ * 狀態組合:
10
+ * - WSL 停止 + K8s 停止 = 完全停止
11
+ * - WSL 運行 + K8s 停止 = 部分啟動(需要啟動 K8s)
12
+ * - WSL 運行 + K8s 運行 = 完全運行
13
+ */
14
+ class InstanceLifecycleState {
15
+ constructor(
16
+ /** WSL 是否運行中 */
17
+ isWslRunning,
18
+ /** MicroK8s 是否運行中 */
19
+ isMicroK8sRunning) {
20
+ this.isWslRunning = isWslRunning;
21
+ this.isMicroK8sRunning = isMicroK8sRunning;
22
+ }
23
+ /**
24
+ * 從狀態資訊建立生命週期狀態
25
+ * @param wslStatus - WSL 實例狀態
26
+ * @param k8sRunning - MicroK8s 是否運行中
27
+ * @returns InstanceLifecycleState 實例
28
+ */
29
+ static fromStatus(wslStatus, k8sRunning) {
30
+ return new InstanceLifecycleState(wslStatus.isRunning, k8sRunning);
31
+ }
32
+ /**
33
+ * 建立完全停止狀態
34
+ * @returns InstanceLifecycleState 實例
35
+ */
36
+ static stopped() {
37
+ return new InstanceLifecycleState(false, false);
38
+ }
39
+ /**
40
+ * 建立完全運行狀態
41
+ * @returns InstanceLifecycleState 實例
42
+ */
43
+ static fullyRunning() {
44
+ return new InstanceLifecycleState(true, true);
45
+ }
46
+ /**
47
+ * 建立部分啟動狀態(WSL 運行但 K8s 未運行)
48
+ * @returns InstanceLifecycleState 實例
49
+ */
50
+ static partiallyRunning() {
51
+ return new InstanceLifecycleState(true, false);
52
+ }
53
+ /**
54
+ * 檢查是否完全運行(WSL + K8s 都在運行)
55
+ */
56
+ get isFullyRunning() {
57
+ return this.isWslRunning && this.isMicroK8sRunning;
58
+ }
59
+ /**
60
+ * 檢查是否完全停止
61
+ */
62
+ get isStopped() {
63
+ return !this.isWslRunning && !this.isMicroK8sRunning;
64
+ }
65
+ /**
66
+ * 檢查是否可以啟動 K8s(WSL 運行但 K8s 未運行)
67
+ */
68
+ get canStartK8s() {
69
+ return this.isWslRunning && !this.isMicroK8sRunning;
70
+ }
71
+ /**
72
+ * 檢查是否需要啟動(非完全運行狀態)
73
+ */
74
+ get needsStart() {
75
+ return !this.isFullyRunning;
76
+ }
77
+ /**
78
+ * 取得狀態描述
79
+ */
80
+ get description() {
81
+ if (this.isFullyRunning) {
82
+ return 'Fully Running';
83
+ }
84
+ if (this.canStartK8s) {
85
+ return 'WSL Running, K8s Stopped';
86
+ }
87
+ return 'Stopped';
88
+ }
89
+ /**
90
+ * 比較兩個狀態是否相等
91
+ * @param other - 另一個生命週期狀態
92
+ * @returns 若相等則回傳 true
93
+ */
94
+ equals(other) {
95
+ return (this.isWslRunning === other.isWslRunning &&
96
+ this.isMicroK8sRunning === other.isMicroK8sRunning);
97
+ }
98
+ }
99
+ exports.InstanceLifecycleState = InstanceLifecycleState;
100
+ //# sourceMappingURL=instance-lifecycle-state.entity.js.map
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InstanceListAggregator = void 0;
4
+ const connection_info_value_object_1 = require("../value-objects/connection-info.value-object");
5
+ /**
6
+ * 實例列表聚合器 Entity
7
+ *
8
+ * 封裝實例列表的聚合邏輯,包括:
9
+ * - 合併 WSL 實例資訊與 Metadata
10
+ * - 處理缺失的 Metadata 情況
11
+ * - 計算統計資訊
12
+ */
13
+ class InstanceListAggregator {
14
+ /**
15
+ * 聚合實例資訊與 Metadata
16
+ * @param infos - WSL 實例資訊陣列
17
+ * @param metadataList - Metadata 陣列
18
+ * @param ipMap - 實例 IP 對照表 (fullName -> IP)
19
+ * @returns 聚合後的實例列表項目
20
+ */
21
+ static aggregate(infos, metadataList, ipMap) {
22
+ return infos.map(info => this.mergeInstanceInfo(info, metadataList, ipMap));
23
+ }
24
+ /**
25
+ * 合併單一實例資訊與 Metadata
26
+ * @param info - WSL 實例資訊
27
+ * @param metadataList - Metadata 陣列
28
+ * @param ipMap - 實例 IP 對照表
29
+ * @returns 聚合後的實例列表項目
30
+ */
31
+ static mergeInstanceInfo(info, metadataList, ipMap) {
32
+ const metadata = metadataList.find(m => m.name.fullName === info.name);
33
+ const ip = ipMap.get(info.name) ?? null;
34
+ const connectionInfo = connection_info_value_object_1.ConnectionInfo.create(ip);
35
+ const connectionDto = connectionInfo.toDto();
36
+ return {
37
+ name: metadata?.name.toString() || this.extractNameFromFullName(info.name),
38
+ fullName: info.name,
39
+ status: info.state,
40
+ wslVersion: info.version.toString(),
41
+ chartVersion: metadata?.chartVersion?.toString() || 'unknown',
42
+ installedAt: metadata?.createdAt.toISOString() || 'unknown',
43
+ adminUrl: connectionDto.adminUrl,
44
+ sqlServer: connectionDto.sqlServer,
45
+ };
46
+ }
47
+ /**
48
+ * 從完整名稱提取顯示名稱
49
+ * @param fullName - 完整名稱(uofx-xxx)
50
+ * @returns 顯示名稱
51
+ */
52
+ static extractNameFromFullName(fullName) {
53
+ const prefix = 'uofx-';
54
+ if (fullName.startsWith(prefix)) {
55
+ return fullName.substring(prefix.length);
56
+ }
57
+ return fullName;
58
+ }
59
+ /**
60
+ * 計算實例統計資訊
61
+ * @param instances - 實例列表項目陣列
62
+ * @returns 統計資訊
63
+ */
64
+ static calculateStatistics(instances) {
65
+ const total = instances.length;
66
+ const runningCount = instances.filter(i => i.status === 'Running').length;
67
+ const stoppedCount = instances.filter(i => i.status === 'Stopped').length;
68
+ return {
69
+ total,
70
+ runningCount,
71
+ stoppedCount,
72
+ };
73
+ }
74
+ /**
75
+ * 聚合並計算統計資訊(組合方法)
76
+ * @param infos - WSL 實例資訊陣列
77
+ * @param metadataList - Metadata 陣列
78
+ * @param ipMap - 實例 IP 對照表 (fullName -> IP)
79
+ * @returns 包含實例列表和統計資訊的物件
80
+ */
81
+ static aggregateWithStatistics(infos, metadataList, ipMap) {
82
+ const instances = this.aggregate(infos, metadataList, ipMap);
83
+ const statistics = this.calculateStatistics(instances);
84
+ return { instances, statistics };
85
+ }
86
+ /**
87
+ * 過濾運行中的實例
88
+ * @param instances - 實例列表項目陣列
89
+ * @returns 運行中的實例
90
+ */
91
+ static filterRunning(instances) {
92
+ return instances.filter(i => i.status === 'Running');
93
+ }
94
+ /**
95
+ * 過濾停止的實例
96
+ * @param instances - 實例列表項目陣列
97
+ * @returns 停止的實例
98
+ */
99
+ static filterStopped(instances) {
100
+ return instances.filter(i => i.status === 'Stopped');
101
+ }
102
+ }
103
+ exports.InstanceListAggregator = InstanceListAggregator;
104
+ //# sourceMappingURL=instance-list-aggregator.entity.js.map