@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.
- package/README.md +159 -3
- package/THIRD-PARTY-NOTICES.txt +84 -2
- package/dist/application/dtos/config/index.js +22 -0
- package/dist/application/dtos/config/request/index.js +19 -0
- package/dist/application/dtos/config/request/set-config.request.dto.js +3 -0
- package/dist/application/dtos/config/response/get-config.response.dto.js +8 -0
- package/dist/application/dtos/config/response/index.js +21 -0
- package/dist/application/dtos/dev/index.js +24 -0
- package/dist/application/dtos/dev/request/generate-component.request.dto.js +3 -0
- package/dist/application/dtos/dev/request/index.js +25 -0
- package/dist/application/dtos/dev/request/install-template.request.dto.js +3 -0
- package/dist/application/dtos/dev/request/new-project.request.dto.js +3 -0
- package/dist/application/dtos/dev/request/publish-plugin.request.dto.js +3 -0
- package/dist/application/dtos/dev/request/uninstall-template.request.dto.js +3 -0
- package/dist/application/dtos/dev/response/generate-component.response.dto.js +3 -0
- package/dist/application/dtos/dev/response/index.js +24 -0
- package/dist/application/dtos/dev/response/new-project.response.dto.js +3 -0
- package/dist/application/dtos/dev/response/publish-plugin.response.dto.js +3 -0
- package/dist/application/dtos/dev/response/template-info.response.dto.js +3 -0
- package/dist/application/dtos/env/index.js +24 -0
- package/dist/application/dtos/{request → env/request}/index.js +1 -3
- package/dist/application/dtos/env/request/list-running-instances.request.dto.js +3 -0
- package/dist/application/dtos/{response → env/response}/index.js +1 -1
- package/dist/application/dtos/env/response/list-running-instances.response.dto.js +3 -0
- package/dist/application/dtos/index.js +9 -2
- package/dist/application/dtos/logs/index.js +22 -0
- package/dist/application/dtos/logs/request/index.js +18 -0
- package/dist/application/dtos/logs/response/index.js +18 -0
- package/dist/application/index.js +1 -0
- package/dist/application/services/env/environment-validator.service.js +120 -0
- package/dist/application/services/env/index.js +11 -0
- package/dist/application/services/env/instance-cleanup.service.js +79 -0
- package/dist/application/services/index.js +21 -0
- package/dist/application/use-cases/config/get-all-config.use-case.js +54 -0
- package/dist/application/use-cases/config/get-config.use-case.js +7 -17
- package/dist/application/use-cases/config/index.js +23 -0
- package/dist/application/use-cases/config/set-config.use-case.js +49 -3
- package/dist/application/use-cases/dev/generate-component.use-case.js +138 -0
- package/dist/application/use-cases/dev/index.js +28 -0
- package/dist/application/use-cases/dev/install-template.use-case.js +60 -0
- package/dist/application/use-cases/dev/list-templates.use-case.js +45 -0
- package/dist/application/use-cases/dev/new-project.use-case.js +130 -0
- package/dist/application/use-cases/dev/publish-plugin.use-case.js +243 -0
- package/dist/application/use-cases/dev/uninstall-template.use-case.js +50 -0
- package/dist/application/use-cases/{instance → env}/delete-instance.use-case.js +2 -2
- package/dist/application/use-cases/{credentials → env}/get-credentials.use-case.js +1 -1
- package/dist/application/use-cases/{instance → env}/index.js +11 -0
- package/dist/application/use-cases/{instance → env}/install-instance.use-case.js +25 -136
- package/dist/application/use-cases/env/list-running-instances.use-case.js +47 -0
- package/dist/application/use-cases/{setup → env}/setup-environment.use-case.js +35 -4
- package/dist/application/use-cases/{instance → env}/start-instance.use-case.js +53 -41
- package/dist/application/use-cases/index.js +9 -6
- package/dist/application/use-cases/logs/index.js +21 -0
- package/dist/cli.js +175 -26
- package/dist/constants/defaults.js +8 -1
- package/dist/constants/oci-artifacts.js +4 -0
- package/dist/constants/paths.js +0 -4
- package/dist/constants/timeouts.js +5 -0
- package/dist/di/modules/application.module.js +13 -44
- package/dist/di/modules/config.module.js +19 -0
- package/dist/di/modules/dev.module.js +45 -0
- package/dist/di/modules/env.module.js +42 -0
- package/dist/di/modules/index.js +30 -0
- package/dist/di/modules/infrastructure.module.js +65 -82
- package/dist/di/modules/logs.module.js +15 -0
- package/dist/di/modules/presentation.module.js +18 -7
- package/dist/di/tokens.js +42 -30
- package/dist/domain/entities/credentials-resolver.entity.js +4 -1
- package/dist/domain/entities/credentials.entity.js +2 -5
- package/dist/domain/entities/delete-instance-validation.entity.js +4 -1
- package/dist/domain/entities/deployment-parameters.entity.js +11 -8
- package/dist/domain/entities/index.js +5 -1
- package/dist/domain/entities/instance-list-aggregator.entity.js +2 -2
- package/dist/domain/entities/instance-metadata.entity.js +2 -3
- package/dist/domain/entities/instance.entity.js +2 -1
- package/dist/domain/entities/log-filter.entity.js +6 -6
- package/dist/domain/entities/template-info.entity.js +63 -0
- package/dist/{infrastructure/utils/error-formatter.util.js → domain/errors/error-utils.js} +1 -1
- package/dist/domain/errors/index.js +19 -0
- package/dist/domain/index.js +6 -0
- package/dist/domain/interfaces/index.js +21 -0
- package/dist/domain/ports/dotnet-publisher.port.js +9 -0
- package/dist/{infrastructure/http/interfaces/http-client.interface.js → domain/ports/file-system.port.js} +1 -1
- package/dist/domain/ports/http-client.port.js +3 -0
- package/dist/domain/ports/index.js +10 -0
- package/dist/domain/ports/logger.port.js +3 -3
- package/dist/domain/ports/progress.port.js +10 -0
- package/dist/domain/ports/project-scaffolder.port.js +9 -0
- package/dist/domain/ports/schematics-runner.port.js +9 -0
- package/dist/domain/ports/template-manager.port.js +9 -0
- package/dist/domain/ports/wsl-setup.port.js +3 -0
- package/dist/domain/types/index.js +1 -0
- package/dist/domain/value-objects/acr-credentials.value-object.js +13 -1
- package/dist/domain/value-objects/chart-version.value-object.js +20 -3
- package/dist/domain/value-objects/config-log-level.value-object.js +2 -1
- package/dist/domain/value-objects/index.js +3 -1
- package/dist/domain/value-objects/instance-name.value-object.js +6 -3
- package/dist/domain/value-objects/jwt-key.value-object.js +27 -5
- package/dist/domain/value-objects/mssql-password.value-object.js +27 -5
- package/dist/domain/value-objects/output-path.value-object.js +85 -0
- package/dist/domain/value-objects/rsa-key-pair.value-object.js +29 -3
- package/dist/index.js +6 -1
- package/dist/infrastructure/config/{app-config.service.js → app-config.adapter.js} +29 -17
- package/dist/infrastructure/config/{config-validator.js → config-validator.util.js} +1 -1
- package/dist/infrastructure/config/index.js +14 -0
- package/dist/infrastructure/config/interfaces/index.js +3 -0
- package/dist/infrastructure/config/{crypto.service.js → services/crypto.service.js} +4 -1
- package/dist/infrastructure/config/services/index.js +9 -0
- package/dist/infrastructure/deployment/deployment.adapter.js +5 -5
- package/dist/infrastructure/deployment/index.js +9 -0
- package/dist/infrastructure/deployment/interfaces/index.js +3 -0
- package/dist/infrastructure/deployment/services/acr-credential-manager.service.js +18 -7
- package/dist/infrastructure/deployment/services/app-manager.service.js +3 -3
- package/dist/infrastructure/deployment/services/base-helm-deployment.service.js +13 -5
- package/dist/infrastructure/deployment/services/helm-registry.service.js +10 -3
- package/dist/infrastructure/deployment/services/index.js +35 -0
- package/dist/infrastructure/deployment/services/infra-manager.service.js +19 -15
- package/dist/infrastructure/deployment/services/k8s-job-runner.service.js +24 -6
- package/dist/infrastructure/deployment/services/mssql-database-init.service.js +75 -11
- package/dist/infrastructure/deployment/services/mssql-helm-deployment.service.js +17 -5
- package/dist/infrastructure/deployment/services/mssql-storage.service.js +5 -1
- package/dist/infrastructure/deployment/services/mssql-user-manager.service.js +7 -3
- package/dist/infrastructure/deployment/services/oci-artifact.service.js +8 -3
- package/dist/infrastructure/deployment/services/secret-manager.service.js +14 -5
- package/dist/infrastructure/deployment/services/service-manager.service.js +1 -1
- package/dist/infrastructure/deployment/services/version-compatibility.service.js +9 -5
- package/dist/infrastructure/dotnet/dotnet-publisher.adapter.js +143 -0
- package/dist/infrastructure/dotnet/index.js +9 -0
- package/dist/infrastructure/environment/index.js +11 -0
- package/dist/infrastructure/environment/interfaces/index.js +3 -0
- package/dist/infrastructure/{platform-detector.js → environment/platform-detector.util.js} +1 -1
- package/dist/infrastructure/environment/services/hardware-info.service.js +8 -8
- package/dist/infrastructure/environment/services/index.js +11 -0
- package/dist/infrastructure/errors/{error-handler.js → error-handler.adapter.js} +17 -17
- package/dist/infrastructure/errors/index.js +5 -21
- package/dist/infrastructure/execution/builders/base-command.builder.js +32 -11
- package/dist/infrastructure/execution/builders/index.js +26 -0
- package/dist/infrastructure/execution/builders/wsl-command.builder.js +39 -1
- package/dist/infrastructure/execution/command-builder.util.js +94 -0
- package/dist/infrastructure/execution/environments/index.js +23 -0
- package/dist/infrastructure/execution/environments/wsl-execution.environment.js +22 -7
- package/dist/infrastructure/execution/index.js +1 -2
- package/dist/infrastructure/execution/services/command-executor.service.js +389 -0
- package/dist/infrastructure/execution/services/index.js +8 -0
- package/dist/infrastructure/execution/{script-executor.service.js → services/script-executor.service.js} +12 -15
- package/dist/infrastructure/filesystem/filesystem.adapter.js +86 -0
- package/dist/infrastructure/filesystem/index.js +23 -0
- package/dist/infrastructure/http/{http-client.service.js → http-client.adapter.js} +20 -13
- package/dist/infrastructure/http/index.js +1 -1
- package/dist/infrastructure/interceptors/decorators/index.js +23 -0
- package/dist/infrastructure/interceptors/index.js +2 -2
- package/dist/infrastructure/interceptors/interceptor.factory.js +3 -3
- package/dist/infrastructure/interceptors/interfaces/index.js +3 -0
- package/dist/infrastructure/interceptors/services/index.js +6 -0
- package/dist/infrastructure/interceptors/{logging.interceptor.js → services/logging-interceptor.service.js} +4 -4
- package/dist/infrastructure/logger/services/file-log-reader.repository.js +1 -1
- package/dist/infrastructure/logger/services/file-log-writer.repository.js +1 -1
- package/dist/infrastructure/persistence/instance-metadata.adapter.js +2 -1
- package/dist/infrastructure/persistence/services/file-system-config.repository.js +10 -4
- package/dist/infrastructure/persistence/services/file-system-instance.repository.js +2 -2
- package/dist/infrastructure/platforms/index.js +18 -0
- package/dist/infrastructure/platforms/windows/index.js +13 -0
- package/dist/infrastructure/platforms/windows/interfaces/index.js +3 -0
- package/dist/infrastructure/platforms/windows/parsers/index.js +9 -0
- package/dist/infrastructure/platforms/windows/services/index.js +33 -0
- package/dist/infrastructure/platforms/windows/services/microk8s.service.js +28 -10
- package/dist/infrastructure/platforms/windows/services/rootfs-manager.service.js +7 -3
- package/dist/infrastructure/platforms/windows/services/windows-features.service.js +22 -8
- package/dist/infrastructure/platforms/windows/services/windows-info.service.js +10 -6
- package/dist/infrastructure/platforms/windows/services/wsl-config.service.js +15 -6
- package/dist/infrastructure/platforms/windows/services/wsl-info.service.js +12 -12
- package/dist/infrastructure/platforms/windows/services/wsl-instance-inspection.service.js +3 -3
- package/dist/infrastructure/platforms/windows/services/wsl-instance-lifecycle.service.js +76 -22
- package/dist/infrastructure/platforms/windows/services/wsl-updater.service.js +20 -15
- package/dist/infrastructure/platforms/windows/services/wslconfig-parser.service.js +3 -3
- package/dist/infrastructure/platforms/windows/wsl-instance-manager.adapter.js +8 -3
- package/dist/infrastructure/platforms/windows/wsl-setup.adapter.js +100 -0
- package/dist/infrastructure/schematics/index.js +11 -0
- package/dist/infrastructure/schematics/project-scaffolder.adapter.js +314 -0
- package/dist/infrastructure/schematics/schematics-runner.adapter.js +175 -0
- package/dist/infrastructure/template/index.js +25 -0
- package/dist/infrastructure/template/interfaces/index.js +22 -0
- package/dist/infrastructure/template/interfaces/template-downloader.interface.js +6 -0
- package/dist/infrastructure/template/interfaces/template-registry.interface.js +6 -0
- package/dist/infrastructure/template/services/index.js +24 -0
- package/dist/infrastructure/template/services/template-downloader.service.js +319 -0
- package/dist/infrastructure/template/services/template-registry.service.js +175 -0
- package/dist/infrastructure/template/template-manager.adapter.js +196 -0
- package/dist/infrastructure/utils/index.js +23 -0
- package/dist/infrastructure/utils/input-validator.util.js +7 -6
- package/dist/presentation/controllers/base.controller.js +36 -0
- package/dist/presentation/controllers/{config.controller.js → config/config.controller.js} +17 -62
- package/dist/presentation/controllers/config/index.js +21 -0
- package/dist/presentation/controllers/dev/dev.controller.js +202 -0
- package/dist/presentation/controllers/dev/index.js +23 -0
- package/dist/presentation/controllers/dev/template.controller.js +158 -0
- package/dist/presentation/controllers/{credentials.controller.js → env/credentials.controller.js} +8 -14
- package/dist/presentation/controllers/env/index.js +23 -0
- package/dist/presentation/controllers/{instance.controller.js → env/instance.controller.js} +35 -92
- package/dist/presentation/controllers/{setup.controller.js → env/setup.controller.js} +33 -66
- package/dist/presentation/controllers/index.js +9 -5
- package/dist/presentation/controllers/logs/index.js +21 -0
- package/dist/presentation/controllers/{logs.controller.js → logs/logs.controller.js} +8 -14
- package/dist/presentation/interfaces/index.js +21 -0
- package/dist/presentation/prompts/acr-credentials.prompt.js +37 -9
- package/dist/presentation/ui/constants/index.js +23 -0
- package/dist/presentation/ui/interaction.service.js +4 -4
- package/dist/presentation/ui/interfaces/cli-progress.interface.js +0 -6
- package/dist/presentation/ui/interfaces/index.js +6 -0
- package/package.json +6 -1
- package/dist/application/dtos/request/set-config.request.dto.js +0 -16
- package/dist/infrastructure/errors/error-handler.interface.js +0 -3
- package/dist/infrastructure/execution/command-builder.js +0 -252
- package/dist/infrastructure/execution/command-executor.service.js +0 -230
- /package/dist/application/dtos/{request → config/request}/get-config.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/delete-instance.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/get-credentials.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/install-instance.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/list-charts.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/setup-environment.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/start-instance.request.dto.js +0 -0
- /package/dist/application/dtos/{request → env/request}/stop-instance.request.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/credentials.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/delete-instance.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/install-instance.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/instance-list.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/instance-status.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/setup-result.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/start-instance.response.dto.js +0 -0
- /package/dist/application/dtos/{response → env/response}/stop-instance.response.dto.js +0 -0
- /package/dist/application/dtos/{request → logs/request}/show-logs.request.dto.js +0 -0
- /package/dist/application/dtos/{response → logs/response}/show-logs.response.dto.js +0 -0
- /package/dist/application/use-cases/{instance → env}/list-charts.use-case.js +0 -0
- /package/dist/application/use-cases/{instance → env}/list-instances.use-case.js +0 -0
- /package/dist/application/use-cases/{instance → env}/stop-instance.use-case.js +0 -0
- /package/dist/{infrastructure → domain}/errors/app-error.js +0 -0
- /package/dist/{infrastructure → domain}/errors/exit-codes.js +0 -0
- /package/dist/infrastructure/config/{app-config.interface.js → interfaces/app-config.interface.js} +0 -0
- /package/dist/{domain → infrastructure/interceptors}/decorators/sensitive.decorator.js +0 -0
- /package/dist/infrastructure/interceptors/{interceptor.interface.js → interfaces/interceptor.interface.js} +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
__exportStar(require("./show-logs.response.dto"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -22,4 +22,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
22
22
|
__exportStar(require("./use-cases"), exports);
|
|
23
23
|
__exportStar(require("./dtos"), exports);
|
|
24
24
|
__exportStar(require("./interfaces"), exports);
|
|
25
|
+
__exportStar(require("./services"), exports);
|
|
25
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,120 @@
|
|
|
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.EnvironmentValidator = void 0;
|
|
16
|
+
const tsyringe_1 = require("tsyringe");
|
|
17
|
+
const errors_1 = require("../../../domain/errors");
|
|
18
|
+
const runtime_environment_port_1 = require("../../../domain/ports/runtime-environment.port");
|
|
19
|
+
const tokens_1 = require("../../../di/tokens");
|
|
20
|
+
/**
|
|
21
|
+
* 環境驗證服務
|
|
22
|
+
*
|
|
23
|
+
* 負責安裝前的環境檢查,包含:
|
|
24
|
+
* - WSL 安裝狀態驗證
|
|
25
|
+
* - 記憶體可用性檢查
|
|
26
|
+
* - 運行中實例檢查
|
|
27
|
+
*/
|
|
28
|
+
let EnvironmentValidator = class EnvironmentValidator {
|
|
29
|
+
constructor(instanceManager, runtimeEnvironment, userInteraction) {
|
|
30
|
+
this.instanceManager = instanceManager;
|
|
31
|
+
this.runtimeEnvironment = runtimeEnvironment;
|
|
32
|
+
this.userInteraction = userInteraction;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 檢查 WSL 是否已安裝
|
|
36
|
+
* @param output - 輸出介面
|
|
37
|
+
* @throws AppError 若 WSL 未安裝
|
|
38
|
+
*/
|
|
39
|
+
async checkWslInstalled(output) {
|
|
40
|
+
output?.section('[1/14] Checking WSL installation').flush();
|
|
41
|
+
output?.item('arrow', 'Verifying runtime environment...').flush();
|
|
42
|
+
const runtimeInfo = await this.runtimeEnvironment.getRuntimeInfo();
|
|
43
|
+
if (!runtimeInfo.isInstalled) {
|
|
44
|
+
throw new errors_1.AppError(`${runtimeInfo.type} is not installed on this system`, {
|
|
45
|
+
exitCode: errors_1.EXIT_CODES.ENVIRONMENT_ERROR,
|
|
46
|
+
solution: 'Please install WSL first. Run: uofx env setup',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
output?.success(`${runtimeInfo.type} is installed (${runtimeInfo.version})`).flush();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 檢查記憶體可用性
|
|
53
|
+
* 綜合考量系統剩餘記憶體、WSL 限制、WSL 目前使用量
|
|
54
|
+
* @param output - 輸出介面
|
|
55
|
+
* @throws AppError 若記憶體不足且使用者取消
|
|
56
|
+
*/
|
|
57
|
+
async checkMemoryAvailability(output) {
|
|
58
|
+
output?.section('[2/14] Checking remaining memory').flush();
|
|
59
|
+
const memoryInfo = await this.runtimeEnvironment.getMemoryAvailability();
|
|
60
|
+
// 顯示詳細資訊
|
|
61
|
+
for (const detail of memoryInfo.details) {
|
|
62
|
+
const suffix = detail.suffix ? ` (${detail.suffix})` : '';
|
|
63
|
+
output?.item('bullet', `${detail.label}: ${detail.valueGB.toFixed(2)} GB${suffix}`).flush();
|
|
64
|
+
}
|
|
65
|
+
if (memoryInfo.availableGB < runtime_environment_port_1.UOFX_REQUIRED_MEMORY_GB) {
|
|
66
|
+
output?.newline().flush();
|
|
67
|
+
output?.warning(`Available memory (${memoryInfo.availableGB.toFixed(2)} GB) is below recommended ${runtime_environment_port_1.UOFX_REQUIRED_MEMORY_GB} GB`).flush();
|
|
68
|
+
output?.info('Insufficient memory may cause:').flush();
|
|
69
|
+
output?.item('bullet', 'Kubernetes pods failing to start').flush();
|
|
70
|
+
output?.item('bullet', 'Services becoming unresponsive or crashing').flush();
|
|
71
|
+
output?.newline().flush();
|
|
72
|
+
const shouldContinue = await this.userInteraction.confirm('Do you want to continue installation anyway?', false);
|
|
73
|
+
if (!shouldContinue) {
|
|
74
|
+
throw new errors_1.AppError('Installation cancelled due to insufficient memory', {
|
|
75
|
+
exitCode: errors_1.EXIT_CODES.BUSINESS_ERROR,
|
|
76
|
+
solution: 'Close other applications or increase memory available for the runtime environment'
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
output?.success('Memory check passed').flush();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* 確保沒有其他實例正在運行
|
|
86
|
+
* 安裝新實例前必須停止所有現有實例
|
|
87
|
+
* @param output - 輸出介面
|
|
88
|
+
* @throws AppError 若有運行中的實例
|
|
89
|
+
*/
|
|
90
|
+
async ensureNoRunningInstances(output) {
|
|
91
|
+
output?.section('[4/14] Checking for running instances').flush();
|
|
92
|
+
output?.item('arrow', 'Scanning running instances...').flush();
|
|
93
|
+
const runningInstances = await this.instanceManager.listRunningInstances();
|
|
94
|
+
if (runningInstances.length > 0) {
|
|
95
|
+
// 將全名轉換為顯示名稱(移除 uofx- 前綴)
|
|
96
|
+
const displayNames = runningInstances.map(name => name.replace('uofx-', ''));
|
|
97
|
+
const instanceList = displayNames
|
|
98
|
+
.map(name => ` - ${name}`)
|
|
99
|
+
.join('\n');
|
|
100
|
+
const stopCommand = displayNames.length === 1
|
|
101
|
+
? `uofx env stop --name ${displayNames[0]}`
|
|
102
|
+
: 'uofx env stop --name <instance-name>';
|
|
103
|
+
throw new errors_1.AppError(`Cannot install: ${runningInstances.length} instance(s) currently running:\n${instanceList}`, {
|
|
104
|
+
exitCode: errors_1.EXIT_CODES.BUSINESS_ERROR,
|
|
105
|
+
solution: `Stop all running instances before installing a new one.\nRun: ${stopCommand}`,
|
|
106
|
+
context: { runningInstances }
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
output?.success('No running instances detected').flush();
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
exports.EnvironmentValidator = EnvironmentValidator;
|
|
113
|
+
exports.EnvironmentValidator = EnvironmentValidator = __decorate([
|
|
114
|
+
(0, tsyringe_1.injectable)(),
|
|
115
|
+
__param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.IInstanceManagerPort)),
|
|
116
|
+
__param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.IRuntimeEnvironmentPort)),
|
|
117
|
+
__param(2, (0, tsyringe_1.inject)(tokens_1.TOKENS.IUserInteractionPort)),
|
|
118
|
+
__metadata("design:paramtypes", [Object, Object, Object])
|
|
119
|
+
], EnvironmentValidator);
|
|
120
|
+
//# sourceMappingURL=environment-validator.service.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InstanceCleanupService = exports.EnvironmentValidator = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Application Services - Env 模組匯出
|
|
6
|
+
*/
|
|
7
|
+
var environment_validator_service_1 = require("./environment-validator.service");
|
|
8
|
+
Object.defineProperty(exports, "EnvironmentValidator", { enumerable: true, get: function () { return environment_validator_service_1.EnvironmentValidator; } });
|
|
9
|
+
var instance_cleanup_service_1 = require("./instance-cleanup.service");
|
|
10
|
+
Object.defineProperty(exports, "InstanceCleanupService", { enumerable: true, get: function () { return instance_cleanup_service_1.InstanceCleanupService; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
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.InstanceCleanupService = void 0;
|
|
16
|
+
const tsyringe_1 = require("tsyringe");
|
|
17
|
+
const errors_1 = require("../../../domain/errors");
|
|
18
|
+
const tokens_1 = require("../../../di/tokens");
|
|
19
|
+
/**
|
|
20
|
+
* 實例清理服務
|
|
21
|
+
*
|
|
22
|
+
* 負責安裝失敗時的清理工作,包含:
|
|
23
|
+
* - 停止運行中的實例
|
|
24
|
+
* - 刪除不完整的實例
|
|
25
|
+
* - 刪除對應的 metadata
|
|
26
|
+
*/
|
|
27
|
+
let InstanceCleanupService = class InstanceCleanupService {
|
|
28
|
+
constructor(instanceManager, instanceStorage) {
|
|
29
|
+
this.instanceManager = instanceManager;
|
|
30
|
+
this.instanceStorage = instanceStorage;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 清理失敗的安裝
|
|
34
|
+
* 用於安裝中斷時的清理
|
|
35
|
+
* @param instanceName - 實例名稱
|
|
36
|
+
* @param output - 輸出介面
|
|
37
|
+
*/
|
|
38
|
+
async cleanupFailedInstallation(instanceName, output) {
|
|
39
|
+
output?.item('arrow', `Removing incomplete instance: ${instanceName.toString()}`).flush();
|
|
40
|
+
try {
|
|
41
|
+
// 嘗試停止實體(如果正在運行)
|
|
42
|
+
const status = await this.instanceManager.getStatus(instanceName);
|
|
43
|
+
if (status.isRunning) {
|
|
44
|
+
output?.indent().item('arrow', 'Stopping instance...').outdent().flush();
|
|
45
|
+
await this.instanceManager.stop(instanceName, true);
|
|
46
|
+
output?.indent().success('Instance stopped').outdent().flush();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
output?.indent().warning(`Failed to stop instance: ${(0, errors_1.formatErrorMessage)(error)}`).outdent().flush();
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
// 刪除實體
|
|
54
|
+
output?.indent().item('arrow', 'Deleting instance...').outdent().flush();
|
|
55
|
+
await this.instanceManager.delete(instanceName);
|
|
56
|
+
output?.indent().success('Instance deleted').outdent().flush();
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
output?.indent().warning(`Failed to delete instance: ${(0, errors_1.formatErrorMessage)(error)}`).outdent().flush();
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
// 刪除 metadata
|
|
63
|
+
output?.indent().item('arrow', 'Deleting metadata...').outdent().flush();
|
|
64
|
+
await this.instanceStorage.deleteInstance(instanceName);
|
|
65
|
+
output?.indent().success('Metadata deleted').outdent().flush();
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
output?.indent().warning(`Failed to delete metadata: ${(0, errors_1.formatErrorMessage)(error)}`).outdent().flush();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.InstanceCleanupService = InstanceCleanupService;
|
|
73
|
+
exports.InstanceCleanupService = InstanceCleanupService = __decorate([
|
|
74
|
+
(0, tsyringe_1.injectable)(),
|
|
75
|
+
__param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.IInstanceManagerPort)),
|
|
76
|
+
__param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.IInstanceStoragePort)),
|
|
77
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
78
|
+
], InstanceCleanupService);
|
|
79
|
+
//# sourceMappingURL=instance-cleanup.service.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
* Application Services 匯出
|
|
19
|
+
*/
|
|
20
|
+
__exportStar(require("./env"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
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.GetAllConfigUseCase = void 0;
|
|
16
|
+
const tsyringe_1 = require("tsyringe");
|
|
17
|
+
const tokens_1 = require("../../../di/tokens");
|
|
18
|
+
/**
|
|
19
|
+
* 取得所有配置 Use Case
|
|
20
|
+
*
|
|
21
|
+
* 使用 IAppConfigPort 讀取合併後的完整配置
|
|
22
|
+
* (default.json + ~/.uofx/config.json)
|
|
23
|
+
*/
|
|
24
|
+
let GetAllConfigUseCase = class GetAllConfigUseCase {
|
|
25
|
+
constructor(appConfigPort) {
|
|
26
|
+
this.appConfigPort = appConfigPort;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 取得所有配置
|
|
30
|
+
* @returns 完整配置資料
|
|
31
|
+
*/
|
|
32
|
+
async execute() {
|
|
33
|
+
// 取得合併後的完整配置
|
|
34
|
+
const config = this.appConfigPort.getConfig();
|
|
35
|
+
// 取得 ACR credentials
|
|
36
|
+
const acrCreds = this.appConfigPort.getAcrCredentials();
|
|
37
|
+
return {
|
|
38
|
+
logLevel: config.logLevel,
|
|
39
|
+
defaultAcrCredentials: acrCreds
|
|
40
|
+
? {
|
|
41
|
+
name: acrCreds.name,
|
|
42
|
+
account: acrCreds.account,
|
|
43
|
+
}
|
|
44
|
+
: null,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.GetAllConfigUseCase = GetAllConfigUseCase;
|
|
49
|
+
exports.GetAllConfigUseCase = GetAllConfigUseCase = __decorate([
|
|
50
|
+
(0, tsyringe_1.injectable)(),
|
|
51
|
+
__param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.IAppConfigPort)),
|
|
52
|
+
__metadata("design:paramtypes", [Object])
|
|
53
|
+
], GetAllConfigUseCase);
|
|
54
|
+
//# sourceMappingURL=get-all-config.use-case.js.map
|
|
@@ -16,15 +16,20 @@ exports.GetConfigUseCase = void 0;
|
|
|
16
16
|
const tsyringe_1 = require("tsyringe");
|
|
17
17
|
const tokens_1 = require("../../../di/tokens");
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* 取得單一配置 Use Case
|
|
20
20
|
*
|
|
21
21
|
* 使用 IAppConfigPort 讀取合併後的配置
|
|
22
|
-
*
|
|
22
|
+
* 支援 dot notation 查詢(如 'acr.name')
|
|
23
23
|
*/
|
|
24
24
|
let GetConfigUseCase = class GetConfigUseCase {
|
|
25
25
|
constructor(appConfigPort) {
|
|
26
26
|
this.appConfigPort = appConfigPort;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* 取得指定 key 的配置值
|
|
30
|
+
* @param request - 包含要查詢的 key
|
|
31
|
+
* @returns 配置值,找不到時返回 null
|
|
32
|
+
*/
|
|
28
33
|
async execute(request) {
|
|
29
34
|
const { key } = request;
|
|
30
35
|
const config = this.appConfigPort.getConfig();
|
|
@@ -41,21 +46,6 @@ let GetConfigUseCase = class GetConfigUseCase {
|
|
|
41
46
|
}
|
|
42
47
|
return value;
|
|
43
48
|
}
|
|
44
|
-
async getAll() {
|
|
45
|
-
// 取得合併後的完整配置
|
|
46
|
-
const config = this.appConfigPort.getConfig();
|
|
47
|
-
// 取得 ACR credentials
|
|
48
|
-
const acrCreds = this.appConfigPort.getAcrCredentials();
|
|
49
|
-
return {
|
|
50
|
-
logLevel: config.logLevel,
|
|
51
|
-
defaultAcrCredentials: acrCreds
|
|
52
|
-
? {
|
|
53
|
-
name: acrCreds.name,
|
|
54
|
-
account: acrCreds.account,
|
|
55
|
-
}
|
|
56
|
-
: null,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
49
|
};
|
|
60
50
|
exports.GetConfigUseCase = GetConfigUseCase;
|
|
61
51
|
exports.GetConfigUseCase = GetConfigUseCase = __decorate([
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Config 指令群組 Use Cases
|
|
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("./get-config.use-case"), exports);
|
|
21
|
+
__exportStar(require("./get-all-config.use-case"), exports);
|
|
22
|
+
__exportStar(require("./set-config.use-case"), exports);
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -15,23 +15,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.SetConfigUseCase = void 0;
|
|
16
16
|
const tsyringe_1 = require("tsyringe");
|
|
17
17
|
const tokens_1 = require("../../../di/tokens");
|
|
18
|
+
const errors_1 = require("../../../domain/errors");
|
|
18
19
|
const acr_credentials_value_object_1 = require("../../../domain/value-objects/acr-credentials.value-object");
|
|
19
20
|
const config_log_level_value_object_1 = require("../../../domain/value-objects/config-log-level.value-object");
|
|
20
21
|
/**
|
|
21
22
|
* 設定配置 Use Case
|
|
22
23
|
*
|
|
23
24
|
* 使用 IUserSettingsPort 寫入使用者配置到 ~/.uofx/config.json
|
|
25
|
+
* 包含輸入驗證邏輯(logLevel 有效性、ACR 憑證完整性、無變更檢查)
|
|
24
26
|
*/
|
|
25
27
|
let SetConfigUseCase = class SetConfigUseCase {
|
|
26
28
|
constructor(userSettings) {
|
|
27
29
|
this.userSettings = userSettings;
|
|
28
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* 執行設定配置
|
|
33
|
+
* @param request - 設定請求
|
|
34
|
+
* @throws AppError 當驗證失敗時
|
|
35
|
+
*/
|
|
29
36
|
async execute(request) {
|
|
37
|
+
// 驗證是否有任何配置變更
|
|
38
|
+
this.validateHasChanges(request);
|
|
39
|
+
// 驗證 ACR credentials 完整性
|
|
40
|
+
this.validateAcrCredentials(request);
|
|
30
41
|
// 處理 logLevel
|
|
31
42
|
if (request.logLevel !== undefined) {
|
|
32
|
-
|
|
33
|
-
const logLevel = config_log_level_value_object_1.ConfigLogLevelValue.create(request.logLevel);
|
|
34
|
-
await this.userSettings.setLogLevel(logLevel.toConfigType());
|
|
43
|
+
this.setLogLevel(request.logLevel);
|
|
35
44
|
}
|
|
36
45
|
// 處理 ACR credentials
|
|
37
46
|
if (request.acrName && request.acrAccount && request.acrPassword) {
|
|
@@ -39,6 +48,43 @@ let SetConfigUseCase = class SetConfigUseCase {
|
|
|
39
48
|
await this.userSettings.saveAcrCredentials(credentials);
|
|
40
49
|
}
|
|
41
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* 驗證是否有任何配置變更
|
|
53
|
+
*/
|
|
54
|
+
validateHasChanges(request) {
|
|
55
|
+
const hasLogLevel = request.logLevel !== undefined;
|
|
56
|
+
const hasAcr = !!(request.acrName || request.acrAccount || request.acrPassword);
|
|
57
|
+
if (!hasLogLevel && !hasAcr) {
|
|
58
|
+
throw new errors_1.AppError('No configuration changes specified', {
|
|
59
|
+
exitCode: errors_1.EXIT_CODES.VALIDATION_ERROR,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 驗證 ACR 憑證完整性(三個欄位必須同時提供)
|
|
65
|
+
*/
|
|
66
|
+
validateAcrCredentials(request) {
|
|
67
|
+
const hasAny = !!(request.acrName || request.acrAccount || request.acrPassword);
|
|
68
|
+
const hasAll = !!(request.acrName && request.acrAccount && request.acrPassword);
|
|
69
|
+
if (hasAny && !hasAll) {
|
|
70
|
+
throw new errors_1.AppError('ACR credentials require all three: --acr.name, --acr.account, --acr.password', { exitCode: errors_1.EXIT_CODES.VALIDATION_ERROR });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 驗證並設定 logLevel
|
|
75
|
+
*/
|
|
76
|
+
setLogLevel(level) {
|
|
77
|
+
try {
|
|
78
|
+
const logLevel = config_log_level_value_object_1.ConfigLogLevelValue.create(level);
|
|
79
|
+
this.userSettings.setLogLevel(logLevel.toConfigType());
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
throw new errors_1.AppError(`Invalid log level: "${level}". Valid values: ${config_log_level_value_object_1.ConfigLogLevelValue.VALID_LEVELS.join(', ')}`, {
|
|
83
|
+
exitCode: errors_1.EXIT_CODES.VALIDATION_ERROR,
|
|
84
|
+
cause: error instanceof Error ? error : undefined,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
42
88
|
};
|
|
43
89
|
exports.SetConfigUseCase = SetConfigUseCase;
|
|
44
90
|
exports.SetConfigUseCase = SetConfigUseCase = __decorate([
|
|
@@ -0,0 +1,138 @@
|
|
|
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.GenerateComponentUseCase = void 0;
|
|
16
|
+
/**
|
|
17
|
+
* Generate Component Use Case
|
|
18
|
+
*
|
|
19
|
+
* 透過 @uofx/plugin-schematics 產生 Plugin 元件
|
|
20
|
+
*/
|
|
21
|
+
const tsyringe_1 = require("tsyringe");
|
|
22
|
+
const tokens_1 = require("../../../di/tokens");
|
|
23
|
+
const errors_1 = require("../../../domain/errors");
|
|
24
|
+
/** 支援的 schematic 類型 */
|
|
25
|
+
const SUPPORTED_TYPES = [
|
|
26
|
+
'field',
|
|
27
|
+
'mobile-field',
|
|
28
|
+
'admin-panel',
|
|
29
|
+
'user-panel',
|
|
30
|
+
'mobile-panel',
|
|
31
|
+
'admin-page',
|
|
32
|
+
'user-page',
|
|
33
|
+
'mobile-page',
|
|
34
|
+
];
|
|
35
|
+
/** 支援 --code 選項的類型清單 */
|
|
36
|
+
const TYPES_SUPPORTING_CODE = [
|
|
37
|
+
'field',
|
|
38
|
+
'mobile-field',
|
|
39
|
+
'admin-panel',
|
|
40
|
+
'user-panel',
|
|
41
|
+
'mobile-panel',
|
|
42
|
+
];
|
|
43
|
+
/** 各 page 類型支援的 layout 清單 */
|
|
44
|
+
const VALID_PAGE_LAYOUTS = {
|
|
45
|
+
'admin-page': ['basic', 'container', 'sider', 'tab'],
|
|
46
|
+
'user-page': ['basic', 'full', 'tab'],
|
|
47
|
+
'mobile-page': ['basic', 'tab'],
|
|
48
|
+
};
|
|
49
|
+
let GenerateComponentUseCase = class GenerateComponentUseCase {
|
|
50
|
+
constructor(schematicsRunner, logger) {
|
|
51
|
+
this.schematicsRunner = schematicsRunner;
|
|
52
|
+
this.logger = logger;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 執行元件產生流程
|
|
56
|
+
* @param request - 元件產生請求參數
|
|
57
|
+
* @param output - 輸出端口,用於回報進度
|
|
58
|
+
* @returns 元件產生結果
|
|
59
|
+
*/
|
|
60
|
+
async execute(request, output) {
|
|
61
|
+
this.logger.debug('Generating component...', { request });
|
|
62
|
+
// 驗證類型
|
|
63
|
+
if (!SUPPORTED_TYPES.includes(request.type)) {
|
|
64
|
+
const msg = `Unsupported component type: "${request.type}". Supported types: ${SUPPORTED_TYPES.join(', ')}`;
|
|
65
|
+
output?.error(msg).flush();
|
|
66
|
+
return { success: false, message: msg };
|
|
67
|
+
}
|
|
68
|
+
// 驗證 layout(pageType)合法性
|
|
69
|
+
if (request.pageType) {
|
|
70
|
+
const validLayouts = VALID_PAGE_LAYOUTS[request.type];
|
|
71
|
+
if (!validLayouts) {
|
|
72
|
+
throw new errors_1.AppError(`Component type "${request.type}" does not support --layout option`, { exitCode: errors_1.EXIT_CODES.VALIDATION_ERROR });
|
|
73
|
+
}
|
|
74
|
+
if (!validLayouts.includes(request.pageType)) {
|
|
75
|
+
throw new errors_1.AppError(`Invalid layout "${request.pageType}" for type "${request.type}". Valid layouts: ${validLayouts.join(', ')}`, { exitCode: errors_1.EXIT_CODES.VALIDATION_ERROR });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 使用當前目錄作為 ClientApp 路徑
|
|
79
|
+
const clientAppPath = process.cwd();
|
|
80
|
+
// 組裝額外參數
|
|
81
|
+
const extraArgs = {};
|
|
82
|
+
// --code 僅 field/mobile-field/panel 類型支援,page 類型靜默忽略
|
|
83
|
+
if (request.code && TYPES_SUPPORTING_CODE.includes(request.type)) {
|
|
84
|
+
extraArgs['code'] = request.code;
|
|
85
|
+
}
|
|
86
|
+
// --group 僅 field 類型支援,其他類型靜默忽略
|
|
87
|
+
if (request.group && request.type === 'field') {
|
|
88
|
+
extraArgs['group'] = request.group;
|
|
89
|
+
}
|
|
90
|
+
if (request.displayName) {
|
|
91
|
+
extraArgs['display-name'] = request.displayName;
|
|
92
|
+
}
|
|
93
|
+
if (request.pageType) {
|
|
94
|
+
extraArgs['type'] = request.pageType;
|
|
95
|
+
}
|
|
96
|
+
if (request.funcId) {
|
|
97
|
+
extraArgs['func-id'] = request.funcId;
|
|
98
|
+
}
|
|
99
|
+
// Field 專屬選項:僅在 type === 'field' 時傳遞
|
|
100
|
+
if (request.type === 'field') {
|
|
101
|
+
if (request.design === false)
|
|
102
|
+
extraArgs['design'] = false;
|
|
103
|
+
if (request.print === false)
|
|
104
|
+
extraArgs['print'] = false;
|
|
105
|
+
if (request.view === false)
|
|
106
|
+
extraArgs['view'] = false;
|
|
107
|
+
}
|
|
108
|
+
// 執行 schematics
|
|
109
|
+
output
|
|
110
|
+
?.section(`Generating ${request.type}: ${request.name}`)
|
|
111
|
+
.flush();
|
|
112
|
+
if (request.dryRun) {
|
|
113
|
+
output?.info('Running in dry-run mode (no files will be written)').flush();
|
|
114
|
+
}
|
|
115
|
+
const result = await this.schematicsRunner.run({
|
|
116
|
+
projectPath: clientAppPath,
|
|
117
|
+
schematicName: request.type,
|
|
118
|
+
componentName: request.name,
|
|
119
|
+
extraArgs,
|
|
120
|
+
dryRun: request.dryRun || false,
|
|
121
|
+
}, output);
|
|
122
|
+
if (result.success && !request.dryRun) {
|
|
123
|
+
output?.newline().success('Component generated successfully!').flush();
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
success: result.success,
|
|
127
|
+
message: result.message,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
exports.GenerateComponentUseCase = GenerateComponentUseCase;
|
|
132
|
+
exports.GenerateComponentUseCase = GenerateComponentUseCase = __decorate([
|
|
133
|
+
(0, tsyringe_1.injectable)(),
|
|
134
|
+
__param(0, (0, tsyringe_1.inject)(tokens_1.TOKENS.ISchematicsRunnerPort)),
|
|
135
|
+
__param(1, (0, tsyringe_1.inject)(tokens_1.TOKENS.ILoggerPort)),
|
|
136
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
137
|
+
], GenerateComponentUseCase);
|
|
138
|
+
//# sourceMappingURL=generate-component.use-case.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
* Dev Use Cases
|
|
19
|
+
*
|
|
20
|
+
* 開發工具相關的 Use Cases
|
|
21
|
+
*/
|
|
22
|
+
__exportStar(require("./install-template.use-case"), exports);
|
|
23
|
+
__exportStar(require("./list-templates.use-case"), exports);
|
|
24
|
+
__exportStar(require("./uninstall-template.use-case"), exports);
|
|
25
|
+
__exportStar(require("./new-project.use-case"), exports);
|
|
26
|
+
__exportStar(require("./generate-component.use-case"), exports);
|
|
27
|
+
__exportStar(require("./publish-plugin.use-case"), exports);
|
|
28
|
+
//# sourceMappingURL=index.js.map
|