@uofx/cli 1.0.2 → 1.1.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 (240) hide show
  1. package/README.md +159 -3
  2. package/THIRD-PARTY-NOTICES.txt +84 -2
  3. package/dist/application/dtos/config/index.js +22 -0
  4. package/dist/application/dtos/config/request/index.js +19 -0
  5. package/dist/application/dtos/config/request/set-config.request.dto.js +3 -0
  6. package/dist/application/dtos/config/response/get-config.response.dto.js +8 -0
  7. package/dist/application/dtos/config/response/index.js +21 -0
  8. package/dist/application/dtos/dev/index.js +24 -0
  9. package/dist/application/dtos/dev/request/generate-component.request.dto.js +3 -0
  10. package/dist/application/dtos/dev/request/index.js +25 -0
  11. package/dist/application/dtos/dev/request/install-template.request.dto.js +3 -0
  12. package/dist/application/dtos/dev/request/new-project.request.dto.js +3 -0
  13. package/dist/application/dtos/dev/request/publish-plugin.request.dto.js +3 -0
  14. package/dist/application/dtos/dev/request/uninstall-template.request.dto.js +3 -0
  15. package/dist/application/dtos/dev/response/generate-component.response.dto.js +3 -0
  16. package/dist/application/dtos/dev/response/index.js +24 -0
  17. package/dist/application/dtos/dev/response/new-project.response.dto.js +3 -0
  18. package/dist/application/dtos/dev/response/publish-plugin.response.dto.js +3 -0
  19. package/dist/application/dtos/dev/response/template-info.response.dto.js +3 -0
  20. package/dist/application/dtos/env/index.js +24 -0
  21. package/dist/application/dtos/{request → env/request}/index.js +1 -3
  22. package/dist/application/dtos/env/request/list-running-instances.request.dto.js +3 -0
  23. package/dist/application/dtos/{response → env/response}/index.js +1 -1
  24. package/dist/application/dtos/env/response/list-running-instances.response.dto.js +3 -0
  25. package/dist/application/dtos/index.js +9 -2
  26. package/dist/application/dtos/logs/index.js +22 -0
  27. package/dist/application/dtos/logs/request/index.js +18 -0
  28. package/dist/application/dtos/logs/response/index.js +18 -0
  29. package/dist/application/index.js +1 -0
  30. package/dist/application/services/env/environment-validator.service.js +120 -0
  31. package/dist/application/services/env/index.js +11 -0
  32. package/dist/application/services/env/instance-cleanup.service.js +79 -0
  33. package/dist/application/services/index.js +21 -0
  34. package/dist/application/use-cases/config/get-all-config.use-case.js +54 -0
  35. package/dist/application/use-cases/config/get-config.use-case.js +7 -17
  36. package/dist/application/use-cases/config/index.js +23 -0
  37. package/dist/application/use-cases/config/set-config.use-case.js +49 -3
  38. package/dist/application/use-cases/dev/generate-component.use-case.js +138 -0
  39. package/dist/application/use-cases/dev/index.js +28 -0
  40. package/dist/application/use-cases/dev/install-template.use-case.js +60 -0
  41. package/dist/application/use-cases/dev/list-templates.use-case.js +45 -0
  42. package/dist/application/use-cases/dev/new-project.use-case.js +130 -0
  43. package/dist/application/use-cases/dev/publish-plugin.use-case.js +243 -0
  44. package/dist/application/use-cases/dev/uninstall-template.use-case.js +50 -0
  45. package/dist/application/use-cases/{instance → env}/delete-instance.use-case.js +2 -2
  46. package/dist/application/use-cases/{credentials → env}/get-credentials.use-case.js +1 -1
  47. package/dist/application/use-cases/{instance → env}/index.js +11 -0
  48. package/dist/application/use-cases/{instance → env}/install-instance.use-case.js +25 -136
  49. package/dist/application/use-cases/env/list-running-instances.use-case.js +47 -0
  50. package/dist/application/use-cases/{setup → env}/setup-environment.use-case.js +35 -4
  51. package/dist/application/use-cases/{instance → env}/start-instance.use-case.js +53 -41
  52. package/dist/application/use-cases/index.js +9 -6
  53. package/dist/application/use-cases/logs/index.js +21 -0
  54. package/dist/cli.js +175 -26
  55. package/dist/constants/defaults.js +8 -1
  56. package/dist/constants/oci-artifacts.js +4 -0
  57. package/dist/constants/paths.js +0 -4
  58. package/dist/constants/timeouts.js +5 -0
  59. package/dist/di/modules/application.module.js +13 -44
  60. package/dist/di/modules/config.module.js +19 -0
  61. package/dist/di/modules/dev.module.js +45 -0
  62. package/dist/di/modules/env.module.js +42 -0
  63. package/dist/di/modules/index.js +30 -0
  64. package/dist/di/modules/infrastructure.module.js +65 -82
  65. package/dist/di/modules/logs.module.js +15 -0
  66. package/dist/di/modules/presentation.module.js +18 -7
  67. package/dist/di/tokens.js +42 -30
  68. package/dist/domain/entities/credentials-resolver.entity.js +4 -1
  69. package/dist/domain/entities/credentials.entity.js +2 -5
  70. package/dist/domain/entities/delete-instance-validation.entity.js +4 -1
  71. package/dist/domain/entities/deployment-parameters.entity.js +11 -8
  72. package/dist/domain/entities/index.js +5 -1
  73. package/dist/domain/entities/instance-list-aggregator.entity.js +2 -2
  74. package/dist/domain/entities/instance-metadata.entity.js +2 -3
  75. package/dist/domain/entities/instance.entity.js +2 -1
  76. package/dist/domain/entities/log-filter.entity.js +6 -6
  77. package/dist/domain/entities/template-info.entity.js +63 -0
  78. package/dist/{infrastructure/utils/error-formatter.util.js → domain/errors/error-utils.js} +1 -1
  79. package/dist/domain/errors/index.js +19 -0
  80. package/dist/domain/index.js +6 -0
  81. package/dist/domain/interfaces/index.js +21 -0
  82. package/dist/domain/ports/dotnet-publisher.port.js +9 -0
  83. package/dist/{infrastructure/http/interfaces/http-client.interface.js → domain/ports/file-system.port.js} +1 -1
  84. package/dist/domain/ports/http-client.port.js +3 -0
  85. package/dist/domain/ports/index.js +10 -0
  86. package/dist/domain/ports/logger.port.js +3 -3
  87. package/dist/domain/ports/progress.port.js +10 -0
  88. package/dist/domain/ports/project-scaffolder.port.js +9 -0
  89. package/dist/domain/ports/schematics-runner.port.js +9 -0
  90. package/dist/domain/ports/template-manager.port.js +9 -0
  91. package/dist/domain/ports/wsl-setup.port.js +3 -0
  92. package/dist/domain/types/index.js +1 -0
  93. package/dist/domain/value-objects/acr-credentials.value-object.js +13 -1
  94. package/dist/domain/value-objects/chart-version.value-object.js +20 -3
  95. package/dist/domain/value-objects/config-log-level.value-object.js +2 -1
  96. package/dist/domain/value-objects/index.js +3 -1
  97. package/dist/domain/value-objects/instance-name.value-object.js +6 -3
  98. package/dist/domain/value-objects/jwt-key.value-object.js +27 -5
  99. package/dist/domain/value-objects/mssql-password.value-object.js +27 -5
  100. package/dist/domain/value-objects/output-path.value-object.js +85 -0
  101. package/dist/domain/value-objects/rsa-key-pair.value-object.js +29 -3
  102. package/dist/index.js +6 -1
  103. package/dist/infrastructure/config/{app-config.service.js → app-config.adapter.js} +29 -17
  104. package/dist/infrastructure/config/{config-validator.js → config-validator.util.js} +1 -1
  105. package/dist/infrastructure/config/index.js +14 -0
  106. package/dist/infrastructure/config/interfaces/index.js +3 -0
  107. package/dist/infrastructure/config/{crypto.service.js → services/crypto.service.js} +4 -1
  108. package/dist/infrastructure/config/services/index.js +9 -0
  109. package/dist/infrastructure/deployment/deployment.adapter.js +5 -5
  110. package/dist/infrastructure/deployment/index.js +9 -0
  111. package/dist/infrastructure/deployment/interfaces/index.js +3 -0
  112. package/dist/infrastructure/deployment/services/acr-credential-manager.service.js +18 -7
  113. package/dist/infrastructure/deployment/services/app-manager.service.js +3 -3
  114. package/dist/infrastructure/deployment/services/base-helm-deployment.service.js +13 -5
  115. package/dist/infrastructure/deployment/services/helm-registry.service.js +10 -3
  116. package/dist/infrastructure/deployment/services/index.js +35 -0
  117. package/dist/infrastructure/deployment/services/infra-manager.service.js +19 -15
  118. package/dist/infrastructure/deployment/services/k8s-job-runner.service.js +24 -6
  119. package/dist/infrastructure/deployment/services/mssql-database-init.service.js +75 -11
  120. package/dist/infrastructure/deployment/services/mssql-helm-deployment.service.js +17 -5
  121. package/dist/infrastructure/deployment/services/mssql-storage.service.js +5 -1
  122. package/dist/infrastructure/deployment/services/mssql-user-manager.service.js +7 -3
  123. package/dist/infrastructure/deployment/services/oci-artifact.service.js +8 -3
  124. package/dist/infrastructure/deployment/services/secret-manager.service.js +14 -5
  125. package/dist/infrastructure/deployment/services/service-manager.service.js +1 -1
  126. package/dist/infrastructure/deployment/services/version-compatibility.service.js +9 -5
  127. package/dist/infrastructure/dotnet/dotnet-publisher.adapter.js +143 -0
  128. package/dist/infrastructure/dotnet/index.js +9 -0
  129. package/dist/infrastructure/environment/index.js +11 -0
  130. package/dist/infrastructure/environment/interfaces/index.js +3 -0
  131. package/dist/infrastructure/{platform-detector.js → environment/platform-detector.util.js} +1 -1
  132. package/dist/infrastructure/environment/services/hardware-info.service.js +8 -8
  133. package/dist/infrastructure/environment/services/index.js +11 -0
  134. package/dist/infrastructure/errors/{error-handler.js → error-handler.adapter.js} +17 -17
  135. package/dist/infrastructure/errors/index.js +5 -21
  136. package/dist/infrastructure/execution/builders/base-command.builder.js +32 -11
  137. package/dist/infrastructure/execution/builders/index.js +26 -0
  138. package/dist/infrastructure/execution/builders/wsl-command.builder.js +39 -1
  139. package/dist/infrastructure/execution/command-builder.util.js +94 -0
  140. package/dist/infrastructure/execution/environments/index.js +23 -0
  141. package/dist/infrastructure/execution/environments/wsl-execution.environment.js +22 -7
  142. package/dist/infrastructure/execution/index.js +1 -2
  143. package/dist/infrastructure/execution/services/command-executor.service.js +389 -0
  144. package/dist/infrastructure/execution/services/index.js +8 -0
  145. package/dist/infrastructure/execution/{script-executor.service.js → services/script-executor.service.js} +12 -15
  146. package/dist/infrastructure/filesystem/filesystem.adapter.js +86 -0
  147. package/dist/infrastructure/filesystem/index.js +23 -0
  148. package/dist/infrastructure/http/{http-client.service.js → http-client.adapter.js} +20 -13
  149. package/dist/infrastructure/http/index.js +1 -1
  150. package/dist/infrastructure/interceptors/decorators/index.js +23 -0
  151. package/dist/infrastructure/interceptors/index.js +2 -2
  152. package/dist/infrastructure/interceptors/interceptor.factory.js +3 -3
  153. package/dist/infrastructure/interceptors/interfaces/index.js +3 -0
  154. package/dist/infrastructure/interceptors/services/index.js +6 -0
  155. package/dist/infrastructure/interceptors/{logging.interceptor.js → services/logging-interceptor.service.js} +4 -4
  156. package/dist/infrastructure/logger/services/file-log-reader.repository.js +1 -1
  157. package/dist/infrastructure/logger/services/file-log-writer.repository.js +1 -1
  158. package/dist/infrastructure/persistence/instance-metadata.adapter.js +2 -1
  159. package/dist/infrastructure/persistence/services/file-system-config.repository.js +10 -4
  160. package/dist/infrastructure/persistence/services/file-system-instance.repository.js +2 -2
  161. package/dist/infrastructure/platforms/index.js +18 -0
  162. package/dist/infrastructure/platforms/windows/index.js +13 -0
  163. package/dist/infrastructure/platforms/windows/interfaces/index.js +3 -0
  164. package/dist/infrastructure/platforms/windows/parsers/index.js +9 -0
  165. package/dist/infrastructure/platforms/windows/services/index.js +33 -0
  166. package/dist/infrastructure/platforms/windows/services/microk8s.service.js +28 -10
  167. package/dist/infrastructure/platforms/windows/services/rootfs-manager.service.js +7 -3
  168. package/dist/infrastructure/platforms/windows/services/windows-features.service.js +22 -8
  169. package/dist/infrastructure/platforms/windows/services/windows-info.service.js +10 -6
  170. package/dist/infrastructure/platforms/windows/services/wsl-config.service.js +15 -6
  171. package/dist/infrastructure/platforms/windows/services/wsl-info.service.js +12 -12
  172. package/dist/infrastructure/platforms/windows/services/wsl-instance-inspection.service.js +3 -3
  173. package/dist/infrastructure/platforms/windows/services/wsl-instance-lifecycle.service.js +76 -22
  174. package/dist/infrastructure/platforms/windows/services/wsl-updater.service.js +20 -15
  175. package/dist/infrastructure/platforms/windows/services/wslconfig-parser.service.js +3 -3
  176. package/dist/infrastructure/platforms/windows/wsl-instance-manager.adapter.js +8 -3
  177. package/dist/infrastructure/platforms/windows/wsl-setup.adapter.js +100 -0
  178. package/dist/infrastructure/schematics/index.js +11 -0
  179. package/dist/infrastructure/schematics/project-scaffolder.adapter.js +314 -0
  180. package/dist/infrastructure/schematics/schematics-runner.adapter.js +175 -0
  181. package/dist/infrastructure/template/index.js +25 -0
  182. package/dist/infrastructure/template/interfaces/index.js +22 -0
  183. package/dist/infrastructure/template/interfaces/template-downloader.interface.js +6 -0
  184. package/dist/infrastructure/template/interfaces/template-registry.interface.js +6 -0
  185. package/dist/infrastructure/template/services/index.js +24 -0
  186. package/dist/infrastructure/template/services/template-downloader.service.js +319 -0
  187. package/dist/infrastructure/template/services/template-registry.service.js +175 -0
  188. package/dist/infrastructure/template/template-manager.adapter.js +196 -0
  189. package/dist/infrastructure/utils/index.js +23 -0
  190. package/dist/infrastructure/utils/input-validator.util.js +7 -6
  191. package/dist/presentation/controllers/base.controller.js +36 -0
  192. package/dist/presentation/controllers/{config.controller.js → config/config.controller.js} +17 -62
  193. package/dist/presentation/controllers/config/index.js +21 -0
  194. package/dist/presentation/controllers/dev/dev.controller.js +202 -0
  195. package/dist/presentation/controllers/dev/index.js +23 -0
  196. package/dist/presentation/controllers/dev/template.controller.js +158 -0
  197. package/dist/presentation/controllers/{credentials.controller.js → env/credentials.controller.js} +8 -14
  198. package/dist/presentation/controllers/env/index.js +23 -0
  199. package/dist/presentation/controllers/{instance.controller.js → env/instance.controller.js} +35 -92
  200. package/dist/presentation/controllers/{setup.controller.js → env/setup.controller.js} +33 -66
  201. package/dist/presentation/controllers/index.js +9 -5
  202. package/dist/presentation/controllers/logs/index.js +21 -0
  203. package/dist/presentation/controllers/{logs.controller.js → logs/logs.controller.js} +8 -14
  204. package/dist/presentation/interfaces/index.js +21 -0
  205. package/dist/presentation/prompts/acr-credentials.prompt.js +37 -9
  206. package/dist/presentation/ui/constants/index.js +23 -0
  207. package/dist/presentation/ui/interaction.service.js +4 -4
  208. package/dist/presentation/ui/interfaces/cli-progress.interface.js +0 -6
  209. package/dist/presentation/ui/interfaces/index.js +6 -0
  210. package/package.json +6 -1
  211. package/dist/application/dtos/request/set-config.request.dto.js +0 -16
  212. package/dist/infrastructure/errors/error-handler.interface.js +0 -3
  213. package/dist/infrastructure/execution/command-builder.js +0 -252
  214. package/dist/infrastructure/execution/command-executor.service.js +0 -230
  215. /package/dist/application/dtos/{request → config/request}/get-config.request.dto.js +0 -0
  216. /package/dist/application/dtos/{request → env/request}/delete-instance.request.dto.js +0 -0
  217. /package/dist/application/dtos/{request → env/request}/get-credentials.request.dto.js +0 -0
  218. /package/dist/application/dtos/{request → env/request}/install-instance.request.dto.js +0 -0
  219. /package/dist/application/dtos/{request → env/request}/list-charts.request.dto.js +0 -0
  220. /package/dist/application/dtos/{request → env/request}/setup-environment.request.dto.js +0 -0
  221. /package/dist/application/dtos/{request → env/request}/start-instance.request.dto.js +0 -0
  222. /package/dist/application/dtos/{request → env/request}/stop-instance.request.dto.js +0 -0
  223. /package/dist/application/dtos/{response → env/response}/credentials.response.dto.js +0 -0
  224. /package/dist/application/dtos/{response → env/response}/delete-instance.response.dto.js +0 -0
  225. /package/dist/application/dtos/{response → env/response}/install-instance.response.dto.js +0 -0
  226. /package/dist/application/dtos/{response → env/response}/instance-list.response.dto.js +0 -0
  227. /package/dist/application/dtos/{response → env/response}/instance-status.response.dto.js +0 -0
  228. /package/dist/application/dtos/{response → env/response}/setup-result.response.dto.js +0 -0
  229. /package/dist/application/dtos/{response → env/response}/start-instance.response.dto.js +0 -0
  230. /package/dist/application/dtos/{response → env/response}/stop-instance.response.dto.js +0 -0
  231. /package/dist/application/dtos/{request → logs/request}/show-logs.request.dto.js +0 -0
  232. /package/dist/application/dtos/{response → logs/response}/show-logs.response.dto.js +0 -0
  233. /package/dist/application/use-cases/{instance → env}/list-charts.use-case.js +0 -0
  234. /package/dist/application/use-cases/{instance → env}/list-instances.use-case.js +0 -0
  235. /package/dist/application/use-cases/{instance → env}/stop-instance.use-case.js +0 -0
  236. /package/dist/{infrastructure → domain}/errors/app-error.js +0 -0
  237. /package/dist/{infrastructure → domain}/errors/exit-codes.js +0 -0
  238. /package/dist/infrastructure/config/{app-config.interface.js → interfaces/app-config.interface.js} +0 -0
  239. /package/dist/{domain → infrastructure/interceptors}/decorators/sensitive.decorator.js +0 -0
  240. /package/dist/infrastructure/interceptors/{interceptor.interface.js → interfaces/interceptor.interface.js} +0 -0
@@ -0,0 +1,389 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.CommandExecutorService = void 0;
19
+ const tsyringe_1 = require("tsyringe");
20
+ const child_process_1 = require("child_process");
21
+ const cross_spawn_1 = __importDefault(require("cross-spawn"));
22
+ const defaults_1 = require("../../../constants/defaults");
23
+ const sensitive_decorator_1 = require("../../interceptors/decorators/sensitive.decorator");
24
+ const errors_1 = require("../../../domain/errors");
25
+ /**
26
+ * 命令執行器服務
27
+ *
28
+ * 使用 Node.js child_process 模組實作 ICommandExecutor 介面,
29
+ * 提供真實的命令執行功能。支援同步和非同步執行、串流輸出、timeout 機制。
30
+ */
31
+ let CommandExecutorService = class CommandExecutorService {
32
+ /**
33
+ * 同步執行命令
34
+ * @param ctx - 執行上下文(命令、安全命令、選項)
35
+ * @param opts - 同步執行選項(顯示輸出、抑制 stderr)
36
+ * @returns 命令執行結果
37
+ */
38
+ execSync(ctx, opts) {
39
+ const { command, options } = ctx;
40
+ const suppressStderr = opts?.suppressStderr ?? false;
41
+ // 處理 shell 選項
42
+ let shell;
43
+ if (options?.shell === true) {
44
+ shell = process.platform === 'win32' ? 'cmd.exe' : '/bin/sh';
45
+ }
46
+ else if (typeof options?.shell === 'string') {
47
+ shell = options.shell;
48
+ }
49
+ const execOptions = {
50
+ // encoding: 'buffer' 会導致 ERR_UNKNOWN_ENCODING,設為 undefined 則會返回 Buffer
51
+ encoding: undefined,
52
+ cwd: options?.cwd,
53
+ env: options?.env,
54
+ timeout: options?.timeout,
55
+ shell,
56
+ maxBuffer: defaults_1.FILE_SIZE.MAX_COMMAND_BUFFER,
57
+ input: options?.input,
58
+ // 總是 pipe stderr 以便正確解碼 UTF-16LE
59
+ stdio: suppressStderr ? ['pipe', 'pipe', 'ignore'] : ['pipe', 'pipe', 'pipe'],
60
+ };
61
+ try {
62
+ const stdoutBuffer = (0, child_process_1.execSync)(command, execOptions);
63
+ const stdout = this.decodeBuffer(stdoutBuffer);
64
+ return {
65
+ stdout,
66
+ stderr: '',
67
+ exitCode: 0,
68
+ };
69
+ }
70
+ catch (error) {
71
+ if (error && typeof error === 'object' && 'status' in error) {
72
+ const execError = error;
73
+ const stdout = this.decodeBuffer(execError.stdout);
74
+ const stderr = this.decodeBuffer(execError.stderr);
75
+ return {
76
+ stdout,
77
+ stderr: stderr,
78
+ exitCode: execError.status ?? 1,
79
+ };
80
+ }
81
+ throw new errors_1.AppError(`Command execution failed: ${String(error)}`, {
82
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
83
+ });
84
+ }
85
+ }
86
+ /**
87
+ * 非同步執行命令
88
+ * @param ctx - 執行上下文(命令、安全命令、選項)
89
+ * @param callbacks - 標準輸出/錯誤回調函式
90
+ * @returns 命令執行結果
91
+ */
92
+ async exec(ctx, callbacks) {
93
+ const { command, options } = ctx;
94
+ const onStdout = callbacks?.onStdout;
95
+ const onStderr = callbacks?.onStderr;
96
+ return new Promise((resolve, reject) => {
97
+ // 預設 shell 為 true 以支援命令字串
98
+ let shell = true;
99
+ if (options?.shell === false) {
100
+ shell = false;
101
+ }
102
+ else if (typeof options?.shell === 'string') {
103
+ shell = options.shell;
104
+ }
105
+ // 如果需要繼承 stdio(用於 WSL 安裝等需要終端訪問的命令)
106
+ if (options?.inheritStdio) {
107
+ const spawnOptions = {
108
+ cwd: options?.cwd,
109
+ env: options?.env,
110
+ shell,
111
+ stdio: 'inherit',
112
+ };
113
+ const childProcess = (0, child_process_1.spawn)(command, [], spawnOptions);
114
+ childProcess.on('close', (code) => {
115
+ resolve({
116
+ stdout: '',
117
+ stderr: '',
118
+ exitCode: code ?? 0,
119
+ });
120
+ });
121
+ childProcess.on('error', (error) => {
122
+ reject(new errors_1.AppError(`Failed to execute command: ${error.message}`, {
123
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
124
+ }));
125
+ });
126
+ return;
127
+ }
128
+ const spawnOptions = {
129
+ cwd: options?.cwd,
130
+ env: options?.env,
131
+ shell,
132
+ encoding: options?.encoding ?? 'utf8',
133
+ };
134
+ const childProcess = (0, child_process_1.spawn)(command, [], spawnOptions);
135
+ if (options?.input && childProcess.stdin) {
136
+ childProcess.stdin.write(options.input);
137
+ childProcess.stdin.end();
138
+ }
139
+ // 累積輸出 Buffer
140
+ const stdoutChunks = [];
141
+ const stderrChunks = [];
142
+ // 監聽標準輸出
143
+ if (childProcess.stdout) {
144
+ childProcess.stdout.on('data', (data) => {
145
+ stdoutChunks.push(data);
146
+ if (onStdout) {
147
+ onStdout(this.decodeBuffer(data));
148
+ }
149
+ });
150
+ }
151
+ // 監聽標準錯誤輸出
152
+ if (childProcess.stderr) {
153
+ childProcess.stderr.on('data', (data) => {
154
+ stderrChunks.push(data);
155
+ if (onStderr) {
156
+ onStderr(this.decodeBuffer(data));
157
+ }
158
+ });
159
+ }
160
+ // 設定 timeout (如果有指定)
161
+ let timeoutId;
162
+ if (options?.timeout) {
163
+ timeoutId = setTimeout(() => {
164
+ childProcess.kill('SIGTERM');
165
+ reject(new errors_1.AppError(`Command timed out after ${options.timeout}ms`, {
166
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
167
+ }));
168
+ }, options.timeout);
169
+ }
170
+ // 監聽進程結束
171
+ childProcess.on('close', (code) => {
172
+ if (timeoutId) {
173
+ clearTimeout(timeoutId);
174
+ }
175
+ const stdoutBuffer = Buffer.concat(stdoutChunks);
176
+ const stderrBuffer = Buffer.concat(stderrChunks);
177
+ resolve({
178
+ stdout: this.decodeBuffer(stdoutBuffer),
179
+ stderr: this.decodeBuffer(stderrBuffer),
180
+ exitCode: code ?? 0,
181
+ });
182
+ });
183
+ childProcess.on('error', (error) => {
184
+ if (timeoutId) {
185
+ clearTimeout(timeoutId);
186
+ }
187
+ reject(new errors_1.AppError(`Failed to execute command: ${error.message}`, {
188
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
189
+ }));
190
+ });
191
+ });
192
+ }
193
+ /**
194
+ * 直接模式執行命令(command + args,無 shell)
195
+ * 使用 cross-spawn 處理跨平台相容性(自動處理 Windows .cmd、正確跳脫引數),
196
+ * 不經由 shell 解析,從根源消除 command injection 攻擊面。
197
+ * @param command - 可執行檔名稱(如 'npx', 'npm')
198
+ * @param args - 參數陣列
199
+ * @param callbacks - 標準輸出/錯誤回調函式
200
+ * @param options - 執行選項(如 cwd, env, timeout, inheritStdio)
201
+ * @returns 解析為命令執行結果的 Promise
202
+ */
203
+ async spawnProcess(command, args, callbacks, options) {
204
+ const onStdout = callbacks?.onStdout;
205
+ const onStderr = callbacks?.onStderr;
206
+ return new Promise((resolve, reject) => {
207
+ // 如果需要繼承 stdio(用於需要終端互動的命令)
208
+ if (options?.inheritStdio) {
209
+ const childProcess = (0, cross_spawn_1.default)(command, args, {
210
+ cwd: options?.cwd,
211
+ env: options?.env,
212
+ stdio: 'inherit',
213
+ });
214
+ childProcess.on('close', (code) => {
215
+ resolve({
216
+ stdout: '',
217
+ stderr: '',
218
+ exitCode: code ?? 0,
219
+ });
220
+ });
221
+ childProcess.on('error', (error) => {
222
+ reject(new errors_1.AppError(`Failed to execute command: ${error.message}`, {
223
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
224
+ }));
225
+ });
226
+ return;
227
+ }
228
+ // 根據是否有 input 決定 stdin 模式
229
+ const hasInput = !!options?.input;
230
+ const childProcess = (0, cross_spawn_1.default)(command, args, {
231
+ cwd: options?.cwd,
232
+ env: options?.env,
233
+ stdio: [hasInput ? 'pipe' : 'inherit', 'pipe', 'pipe'],
234
+ });
235
+ if (hasInput && childProcess.stdin) {
236
+ childProcess.stdin.write(options.input);
237
+ childProcess.stdin.end();
238
+ }
239
+ // 累積輸出 Buffer
240
+ const stdoutChunks = [];
241
+ const stderrChunks = [];
242
+ // 監聽標準輸出
243
+ if (childProcess.stdout) {
244
+ childProcess.stdout.on('data', (data) => {
245
+ stdoutChunks.push(data);
246
+ if (onStdout) {
247
+ onStdout(this.decodeBuffer(data));
248
+ }
249
+ });
250
+ }
251
+ // 監聽標準錯誤輸出
252
+ if (childProcess.stderr) {
253
+ childProcess.stderr.on('data', (data) => {
254
+ stderrChunks.push(data);
255
+ if (onStderr) {
256
+ onStderr(this.decodeBuffer(data));
257
+ }
258
+ });
259
+ }
260
+ // 設定 timeout(如果有指定)
261
+ let timeoutId;
262
+ if (options?.timeout) {
263
+ timeoutId = setTimeout(() => {
264
+ childProcess.kill('SIGTERM');
265
+ reject(new errors_1.AppError(`Command timed out after ${options.timeout}ms`, {
266
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
267
+ }));
268
+ }, options.timeout);
269
+ }
270
+ // 監聽進程結束
271
+ childProcess.on('close', (code) => {
272
+ if (timeoutId) {
273
+ clearTimeout(timeoutId);
274
+ }
275
+ const stdoutBuffer = Buffer.concat(stdoutChunks);
276
+ const stderrBuffer = Buffer.concat(stderrChunks);
277
+ resolve({
278
+ stdout: this.decodeBuffer(stdoutBuffer),
279
+ stderr: this.decodeBuffer(stderrBuffer),
280
+ exitCode: code ?? 0,
281
+ });
282
+ });
283
+ childProcess.on('error', (error) => {
284
+ if (timeoutId) {
285
+ clearTimeout(timeoutId);
286
+ }
287
+ reject(new errors_1.AppError(`Failed to execute command: ${error.message}`, {
288
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
289
+ }));
290
+ });
291
+ });
292
+ }
293
+ /**
294
+ * 直接模式同步執行命令(command + args,無 shell)
295
+ * 使用 cross-spawn 處理跨平台相容性,不經由 shell 解析,
296
+ * 從根源消除 command injection 攻擊面。
297
+ * @param command - 可執行檔名稱(如 'wsl', 'node')
298
+ * @param args - 參數陣列
299
+ * @param opts - 同步執行選項與額外選項
300
+ * @returns 命令執行結果
301
+ */
302
+ spawnProcessSync(command, args, opts) {
303
+ const suppressStderr = opts?.suppressStderr ?? false;
304
+ const options = opts?.options;
305
+ try {
306
+ const result = cross_spawn_1.default.sync(command, args, {
307
+ cwd: options?.cwd,
308
+ env: options?.env,
309
+ timeout: options?.timeout,
310
+ input: options?.input,
311
+ maxBuffer: defaults_1.FILE_SIZE.MAX_COMMAND_BUFFER,
312
+ stdio: suppressStderr ? ['pipe', 'pipe', 'ignore'] : ['pipe', 'pipe', 'pipe'],
313
+ });
314
+ if (result.error) {
315
+ throw new errors_1.AppError(`Failed to execute command: ${result.error.message}`, {
316
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
317
+ });
318
+ }
319
+ const stdout = this.decodeBuffer(result.stdout);
320
+ const stderr = result.stderr ? this.decodeBuffer(result.stderr) : '';
321
+ return {
322
+ stdout,
323
+ stderr,
324
+ exitCode: result.status ?? 1,
325
+ };
326
+ }
327
+ catch (error) {
328
+ if (error instanceof errors_1.AppError) {
329
+ throw error;
330
+ }
331
+ throw new errors_1.AppError(`Command execution failed: ${String(error)}`, {
332
+ exitCode: errors_1.EXIT_CODES.SYSTEM_ERROR,
333
+ });
334
+ }
335
+ }
336
+ /**
337
+ * 解碼 Buffer
338
+ * 嘗試偵測 UTF-16 LE (常見於 Windows/WSL 輸出),否則使用 UTF-8
339
+ */
340
+ decodeBuffer(buffer) {
341
+ if (!buffer)
342
+ return '';
343
+ if (typeof buffer === 'string')
344
+ return buffer;
345
+ if (buffer.length === 0)
346
+ return '';
347
+ // 1. 檢查 UTF-16LE BOM (FF FE)
348
+ if (buffer.length >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
349
+ return buffer.toString('utf16le');
350
+ }
351
+ // 2. 檢查是否為 UTF-16LE (無 BOM)
352
+ // WSL 輸出通常沒有 BOM,但使用 UTF-16LE 編碼
353
+ const sample = buffer.subarray(0, Math.min(buffer.length, 200));
354
+ let nullCount = 0;
355
+ for (let i = 0; i < sample.length; i++) {
356
+ if (sample[i] === 0)
357
+ nullCount++;
358
+ }
359
+ // 如果 null bytes 超過 20%,很可能是 UTF-16LE
360
+ if (nullCount > sample.length * 0.2) {
361
+ return buffer.toString('utf16le');
362
+ }
363
+ // 3. 預設使用 UTF-8
364
+ return buffer.toString('utf8');
365
+ }
366
+ };
367
+ exports.CommandExecutorService = CommandExecutorService;
368
+ __decorate([
369
+ __param(0, (0, sensitive_decorator_1.Sensitive)()),
370
+ __metadata("design:type", Function),
371
+ __metadata("design:paramtypes", [Object, Object]),
372
+ __metadata("design:returntype", Object)
373
+ ], CommandExecutorService.prototype, "execSync", null);
374
+ __decorate([
375
+ __param(0, (0, sensitive_decorator_1.Sensitive)()),
376
+ __metadata("design:type", Function),
377
+ __metadata("design:paramtypes", [Object, Object]),
378
+ __metadata("design:returntype", Promise)
379
+ ], CommandExecutorService.prototype, "exec", null);
380
+ __decorate([
381
+ __param(2, (0, sensitive_decorator_1.Sensitive)()),
382
+ __metadata("design:type", Function),
383
+ __metadata("design:paramtypes", [String, Array, Object]),
384
+ __metadata("design:returntype", Object)
385
+ ], CommandExecutorService.prototype, "spawnProcessSync", null);
386
+ exports.CommandExecutorService = CommandExecutorService = __decorate([
387
+ (0, tsyringe_1.injectable)()
388
+ ], CommandExecutorService);
389
+ //# sourceMappingURL=command-executor.service.js.map
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScriptExecutorService = exports.CommandExecutorService = void 0;
4
+ var command_executor_service_1 = require("./command-executor.service");
5
+ Object.defineProperty(exports, "CommandExecutorService", { enumerable: true, get: function () { return command_executor_service_1.CommandExecutorService; } });
6
+ var script_executor_service_1 = require("./script-executor.service");
7
+ Object.defineProperty(exports, "ScriptExecutorService", { enumerable: true, get: function () { return script_executor_service_1.ScriptExecutorService; } });
8
+ //# sourceMappingURL=index.js.map
@@ -14,18 +14,17 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ScriptExecutorService = void 0;
16
16
  const tsyringe_1 = require("tsyringe");
17
- const tokens_1 = require("../../di/tokens");
18
- const sensitive_decorator_1 = require("../../domain/decorators/sensitive.decorator");
19
- const input_validator_util_1 = require("../utils/input-validator.util");
20
- const errors_1 = require("../errors");
21
- const index_1 = require("../../constants/index");
17
+ const tokens_1 = require("../../../di/tokens");
18
+ const sensitive_decorator_1 = require("../../interceptors/decorators/sensitive.decorator");
19
+ const input_validator_util_1 = require("../../utils/input-validator.util");
20
+ const errors_1 = require("../../../domain/errors");
21
+ const index_1 = require("../../../constants/index");
22
22
  /**
23
23
  * ScriptExecutor 類別負責在 WSL 實例中執行 bash 腳本
24
24
  */
25
25
  let ScriptExecutorService = class ScriptExecutorService {
26
- constructor(envFactory, commandExecutor, logger, ociArtifact) {
26
+ constructor(envFactory, logger, ociArtifact) {
27
27
  this.envFactory = envFactory;
28
- this.commandExecutor = commandExecutor;
29
28
  this.logger = logger;
30
29
  this.ociArtifact = ociArtifact;
31
30
  }
@@ -54,11 +53,10 @@ let ScriptExecutorService = class ScriptExecutorService {
54
53
  .arg('--')
55
54
  .arg('bash')
56
55
  .arg(scriptPath);
57
- // 取得建構好的命令,加上 timeout 選項執行
58
- const command = builder.buildActual();
56
+ // 透過 withOptions 設定 timeout,使用 builder 的 exec() 執行
59
57
  let scriptOutput = '';
60
58
  try {
61
- const result = await this.commandExecutor.exec(command, (stdout) => {
59
+ const result = await builder.withOptions({ timeout }).exec((stdout) => {
62
60
  scriptOutput += stdout;
63
61
  if (showDetail) {
64
62
  // 詳細模式:記錄所有輸出到 debug log
@@ -80,7 +78,7 @@ let ScriptExecutorService = class ScriptExecutorService {
80
78
  // 記錄 stderr 到 error log
81
79
  this.logger.error(new Error(`Script stderr: ${stderr}`));
82
80
  }
83
- }, { timeout, shell: true }, builder.buildSafe());
81
+ });
84
82
  return { exitCode: result.exitCode, output: scriptOutput };
85
83
  }
86
84
  catch (error) {
@@ -163,9 +161,8 @@ __decorate([
163
161
  exports.ScriptExecutorService = ScriptExecutorService = __decorate([
164
162
  (0, tsyringe_1.injectable)(),
165
163
  __param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.Internal.IExecutionEnvironmentFactory)),
166
- __param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.Internal.ICommandExecutor)),
167
- __param(2, (0, tsyringe_1.inject)(tokens_1.TOKENS.ILoggerPort)),
168
- __param(3, (0, tsyringe_1.inject)(tokens_1.TOKENS.Internal.IOciArtifactService)),
169
- __metadata("design:paramtypes", [Object, Object, Object, Object])
164
+ __param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.ILoggerPort)),
165
+ __param(2, (0, tsyringe_1.inject)(tokens_1.TOKENS.Internal.IOciArtifactService)),
166
+ __metadata("design:paramtypes", [Object, Object, Object])
170
167
  ], ScriptExecutorService);
171
168
  //# sourceMappingURL=script-executor.service.js.map
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ 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;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.FileSystemAdapter = void 0;
43
+ const tsyringe_1 = require("tsyringe");
44
+ const fs = __importStar(require("fs"));
45
+ /**
46
+ * 檔案系統 Adapter
47
+ *
48
+ * 實作 IFileSystemPort,封裝 Node.js fs 模組操作
49
+ */
50
+ let FileSystemAdapter = class FileSystemAdapter {
51
+ /**
52
+ * 檢查檔案或目錄是否存在
53
+ * @param filePath - 檔案或目錄路徑
54
+ * @returns 是否存在
55
+ */
56
+ async exists(filePath) {
57
+ return fs.existsSync(filePath);
58
+ }
59
+ /**
60
+ * 複製檔案
61
+ * @param src - 來源檔案路徑
62
+ * @param dest - 目標檔案路徑
63
+ */
64
+ async copyFile(src, dest) {
65
+ fs.copyFileSync(src, dest);
66
+ }
67
+ /**
68
+ * 確保目錄存在(若不存在則遞迴建立)
69
+ * @param dirPath - 目錄路徑
70
+ */
71
+ async ensureDir(dirPath) {
72
+ fs.mkdirSync(dirPath, { recursive: true });
73
+ }
74
+ /**
75
+ * 遞迴刪除目錄
76
+ * @param dirPath - 目錄路徑
77
+ */
78
+ async removeDir(dirPath) {
79
+ fs.rmSync(dirPath, { recursive: true, force: true });
80
+ }
81
+ };
82
+ exports.FileSystemAdapter = FileSystemAdapter;
83
+ exports.FileSystemAdapter = FileSystemAdapter = __decorate([
84
+ (0, tsyringe_1.injectable)()
85
+ ], FileSystemAdapter);
86
+ //# sourceMappingURL=filesystem.adapter.js.map
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ /**
18
+ * 檔案系統模組
19
+ *
20
+ * 匯出檔案系統 Adapter,實作 Domain 層的 IFileSystemPort
21
+ */
22
+ __exportStar(require("./filesystem.adapter"), exports);
23
+ //# sourceMappingURL=index.js.map
@@ -39,16 +39,17 @@ var __importStar = (this && this.__importStar) || (function () {
39
39
  };
40
40
  })();
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.HttpClientService = void 0;
42
+ exports.HttpClientAdapter = void 0;
43
43
  const tsyringe_1 = require("tsyringe");
44
44
  const axios_1 = __importStar(require("axios"));
45
45
  const fs = __importStar(require("fs"));
46
46
  const path = __importStar(require("path"));
47
47
  const timeouts_1 = require("../../constants/timeouts");
48
+ const errors_1 = require("../../domain/errors");
48
49
  /**
49
50
  * HTTP 客戶端服務
50
51
  *
51
- * 使用 Axios 函式庫實作 IHttpClient 介面,提供真實的 HTTP 請求功能。
52
+ * 使用 Axios 函式庫實作 IHttpClientPort 介面,提供真實的 HTTP 請求功能。
52
53
  * 支援檔案下載、文字內容抓取,以及進度追蹤。
53
54
  *
54
55
  * @example
@@ -61,7 +62,7 @@ const timeouts_1 = require("../../constants/timeouts");
61
62
  * );
62
63
  * ```
63
64
  */
64
- let HttpClientService = class HttpClientService {
65
+ let HttpClientAdapter = class HttpClientAdapter {
65
66
  /**
66
67
  * 下載檔案到指定路徑
67
68
  *
@@ -106,9 +107,11 @@ let HttpClientService = class HttpClientService {
106
107
  }
107
108
  // 包裝錯誤訊息
108
109
  if (error instanceof axios_1.AxiosError) {
109
- throw new Error(`Failed to download file from ${url}: ${error.message} (status: ${error.response?.status ?? 'unknown'})`);
110
+ throw new errors_1.AppError(`Failed to download file from ${url}: ${error.message} (status: ${error.response?.status ?? 'unknown'})`, { exitCode: errors_1.EXIT_CODES.NETWORK_ERROR });
110
111
  }
111
- throw new Error(`Failed to download file from ${url}: ${String(error)}`);
112
+ throw new errors_1.AppError(`Failed to download file from ${url}: ${String(error)}`, {
113
+ exitCode: errors_1.EXIT_CODES.NETWORK_ERROR,
114
+ });
112
115
  }
113
116
  }
114
117
  /**
@@ -130,9 +133,11 @@ let HttpClientService = class HttpClientService {
130
133
  catch (error) {
131
134
  // 包裝錯誤訊息
132
135
  if (error instanceof axios_1.AxiosError) {
133
- throw new Error(`Failed to fetch text from ${url}: ${error.message} (status: ${error.response?.status ?? 'unknown'})`);
136
+ throw new errors_1.AppError(`Failed to fetch text from ${url}: ${error.message} (status: ${error.response?.status ?? 'unknown'})`, { exitCode: errors_1.EXIT_CODES.NETWORK_ERROR });
134
137
  }
135
- throw new Error(`Failed to fetch text from ${url}: ${String(error)}`);
138
+ throw new errors_1.AppError(`Failed to fetch text from ${url}: ${String(error)}`, {
139
+ exitCode: errors_1.EXIT_CODES.NETWORK_ERROR,
140
+ });
136
141
  }
137
142
  }
138
143
  /**
@@ -148,9 +153,11 @@ let HttpClientService = class HttpClientService {
148
153
  }
149
154
  catch (error) {
150
155
  if (error instanceof axios_1.AxiosError) {
151
- throw new Error(`Failed to get JSON from ${url}: ${error.message} (status: ${error.response?.status ?? 'unknown'})`);
156
+ throw new errors_1.AppError(`Failed to get JSON from ${url}: ${error.message} (status: ${error.response?.status ?? 'unknown'})`, { exitCode: errors_1.EXIT_CODES.NETWORK_ERROR });
152
157
  }
153
- throw new Error(`Failed to get JSON from ${url}: ${String(error)}`);
158
+ throw new errors_1.AppError(`Failed to get JSON from ${url}: ${String(error)}`, {
159
+ exitCode: errors_1.EXIT_CODES.NETWORK_ERROR,
160
+ });
154
161
  }
155
162
  }
156
163
  /**
@@ -169,8 +176,8 @@ let HttpClientService = class HttpClientService {
169
176
  }
170
177
  }
171
178
  };
172
- exports.HttpClientService = HttpClientService;
173
- exports.HttpClientService = HttpClientService = __decorate([
179
+ exports.HttpClientAdapter = HttpClientAdapter;
180
+ exports.HttpClientAdapter = HttpClientAdapter = __decorate([
174
181
  (0, tsyringe_1.injectable)()
175
- ], HttpClientService);
176
- //# sourceMappingURL=http-client.service.js.map
182
+ ], HttpClientAdapter);
183
+ //# sourceMappingURL=http-client.adapter.js.map
@@ -14,5 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./http-client.service"), exports);
17
+ __exportStar(require("./http-client.adapter"), exports);
18
18
  //# sourceMappingURL=index.js.map