@solidxai/core 0.1.10-beta.24 → 0.1.10-beta.26
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/dist/controllers/action-metadata.controller.d.ts +1 -20
- package/dist/controllers/action-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/agent-event.controller.d.ts +1 -20
- package/dist/controllers/agent-event.controller.d.ts.map +1 -1
- package/dist/controllers/agent-session.controller.d.ts +1 -20
- package/dist/controllers/agent-session.controller.d.ts.map +1 -1
- package/dist/controllers/ai-interaction.controller.d.ts +1 -20
- package/dist/controllers/ai-interaction.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message-details.controller.d.ts +1 -20
- package/dist/controllers/chatter-message-details.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.d.ts +1 -20
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -20
- package/dist/controllers/dashboard-user-layout.controller.d.ts.map +1 -1
- package/dist/controllers/email-template.controller.d.ts +1 -20
- package/dist/controllers/email-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-template.controller.d.ts +1 -20
- package/dist/controllers/export-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-transaction.controller.d.ts +1 -20
- package/dist/controllers/export-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -20
- package/dist/controllers/import-transaction-error-log.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction.controller.d.ts +1 -20
- package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/list-of-values.controller.d.ts +1 -20
- package/dist/controllers/list-of-values.controller.d.ts.map +1 -1
- package/dist/controllers/locale.controller.d.ts +1 -20
- package/dist/controllers/locale.controller.d.ts.map +1 -1
- package/dist/controllers/mcp-audit-log.controller.d.ts +1 -20
- package/dist/controllers/mcp-audit-log.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.d.ts +1 -20
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.d.ts +1 -20
- package/dist/controllers/menu-item-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/model-metadata.controller.d.ts +10 -30
- package/dist/controllers/model-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/model-metadata.controller.js +2 -2
- package/dist/controllers/model-sequence.controller.d.ts +1 -20
- package/dist/controllers/model-sequence.controller.d.ts.map +1 -1
- package/dist/controllers/module-metadata-explorer.controller.d.ts +171 -0
- package/dist/controllers/module-metadata-explorer.controller.d.ts.map +1 -0
- package/dist/controllers/module-metadata-explorer.controller.js +143 -0
- package/dist/controllers/module-metadata-explorer.controller.js.map +1 -0
- package/dist/controllers/module-metadata.controller.d.ts +5 -0
- package/dist/controllers/module-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/module-metadata.controller.js +12 -0
- package/dist/controllers/module-metadata.controller.js.map +1 -1
- package/dist/controllers/module-package.controller.d.ts +622 -0
- package/dist/controllers/module-package.controller.d.ts.map +1 -0
- package/dist/controllers/module-package.controller.js +150 -0
- package/dist/controllers/module-package.controller.js.map +1 -0
- package/dist/controllers/mq-message-queue.controller.d.ts +1 -20
- package/dist/controllers/mq-message-queue.controller.d.ts.map +1 -1
- package/dist/controllers/mq-message.controller.d.ts +1 -20
- package/dist/controllers/mq-message.controller.d.ts.map +1 -1
- package/dist/controllers/permission-metadata.controller.d.ts +1 -20
- package/dist/controllers/permission-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/role-metadata.controller.d.ts +1 -20
- package/dist/controllers/role-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/saved-filters.controller.d.ts +1 -20
- package/dist/controllers/saved-filters.controller.d.ts.map +1 -1
- package/dist/controllers/scheduled-job.controller.d.ts +1 -20
- package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
- package/dist/controllers/security-rule.controller.d.ts +1 -20
- package/dist/controllers/security-rule.controller.d.ts.map +1 -1
- package/dist/controllers/sms-template.controller.d.ts +1 -20
- package/dist/controllers/sms-template.controller.d.ts.map +1 -1
- package/dist/controllers/user-activity-history.controller.d.ts +1 -20
- package/dist/controllers/user-activity-history.controller.d.ts.map +1 -1
- package/dist/controllers/user-view-metadata.controller.d.ts +1 -20
- package/dist/controllers/user-view-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/user.controller.d.ts +1 -20
- package/dist/controllers/user.controller.d.ts.map +1 -1
- package/dist/controllers/view-metadata.controller.d.ts +1 -20
- package/dist/controllers/view-metadata.controller.d.ts.map +1 -1
- package/dist/dtos/confirm-module-package-import.dto.d.ts +4 -0
- package/dist/dtos/confirm-module-package-import.dto.d.ts.map +1 -0
- package/dist/dtos/confirm-module-package-import.dto.js +34 -0
- package/dist/dtos/confirm-module-package-import.dto.js.map +1 -0
- package/dist/dtos/metadata-explorer-references-query.dto.d.ts +10 -0
- package/dist/dtos/metadata-explorer-references-query.dto.d.ts.map +1 -0
- package/dist/dtos/metadata-explorer-references-query.dto.js +69 -0
- package/dist/dtos/metadata-explorer-references-query.dto.js.map +1 -0
- package/dist/dtos/metadata-explorer-search-query.dto.d.ts +8 -0
- package/dist/dtos/metadata-explorer-search-query.dto.d.ts.map +1 -0
- package/dist/dtos/metadata-explorer-search-query.dto.js +55 -0
- package/dist/dtos/metadata-explorer-search-query.dto.js.map +1 -0
- package/dist/dtos/metadata-explorer-write.dto.d.ts +4 -0
- package/dist/dtos/metadata-explorer-write.dto.d.ts.map +1 -0
- package/dist/dtos/metadata-explorer-write.dto.js +30 -0
- package/dist/dtos/metadata-explorer-write.dto.js.map +1 -0
- package/dist/dtos/run-module-package-build.dto.d.ts +5 -0
- package/dist/dtos/run-module-package-build.dto.d.ts.map +1 -0
- package/dist/dtos/run-module-package-build.dto.js +38 -0
- package/dist/dtos/run-module-package-build.dto.js.map +1 -0
- package/dist/dtos/run-module-package-seed.dto.d.ts +4 -0
- package/dist/dtos/run-module-package-seed.dto.d.ts.map +1 -0
- package/dist/dtos/run-module-package-seed.dto.js +34 -0
- package/dist/dtos/run-module-package-seed.dto.js.map +1 -0
- package/dist/helpers/command.service.js +1 -1
- package/dist/helpers/command.service.js.map +1 -1
- package/dist/helpers/module-metadata-helper.service.d.ts +2 -0
- package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/module-metadata-helper.service.js +14 -12
- package/dist/helpers/module-metadata-helper.service.js.map +1 -1
- package/dist/helpers/module.helper.d.ts.map +1 -1
- package/dist/helpers/module.helper.js +11 -6
- package/dist/helpers/module.helper.js.map +1 -1
- package/dist/helpers/typeorm-migration-helpers.d.ts +12 -0
- package/dist/helpers/typeorm-migration-helpers.d.ts.map +1 -0
- package/dist/helpers/typeorm-migration-helpers.js +119 -0
- package/dist/helpers/typeorm-migration-helpers.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +57 -38
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/module-test-data.service.js +1 -1
- package/dist/seeders/module-test-data.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +2364 -1106
- package/dist/services/crud-helper.service.d.ts +18 -0
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +67 -1
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +1 -21
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +23 -87
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/genai/ingest-metadata.service.js +2 -2
- package/dist/services/genai/ingest-metadata.service.js.map +1 -1
- package/dist/services/media.service.d.ts +1 -20
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +31 -2
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js +5 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +15 -30
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +249 -29
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata-explorer.service.d.ts +161 -0
- package/dist/services/module-metadata-explorer.service.d.ts.map +1 -0
- package/dist/services/module-metadata-explorer.service.js +485 -0
- package/dist/services/module-metadata-explorer.service.js.map +1 -0
- package/dist/services/module-metadata.service.d.ts +7 -0
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +121 -2
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/module-package.service.d.ts +266 -0
- package/dist/services/module-package.service.d.ts.map +1 -0
- package/dist/services/module-package.service.js +980 -0
- package/dist/services/module-package.service.js.map +1 -0
- package/dist/services/settings/default-settings-provider.service.d.ts +18 -0
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +10 -0
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +10 -2
- package/dist/solid-core.module.js.map +1 -1
- package/dist-tests/api/authenticate.spec.js +119 -0
- package/dist-tests/api/authenticate.spec.js.map +1 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
- package/dist-tests/api/ping.spec.js +21 -0
- package/dist-tests/api/ping.spec.js.map +1 -0
- package/dist-tests/helpers/auth.js +41 -0
- package/dist-tests/helpers/auth.js.map +1 -0
- package/dist-tests/helpers/env.js +11 -0
- package/dist-tests/helpers/env.js.map +1 -0
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +438 -0
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +146 -0
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +172 -0
- package/docs/grouping-enhancements.md +89 -0
- package/docs/java-spring/README.md +3 -0
- package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
- package/docs/module-package-import-handoff.md +691 -0
- package/docs/seed-changes.md +65 -0
- package/docs/test-data-workflow.md +200 -0
- package/docs/type-declaration-import-issue.md +24 -0
- package/package.json +2 -1
- package/src/controllers/module-metadata-explorer.controller.ts +83 -0
- package/src/controllers/module-metadata.controller.ts +6 -0
- package/src/controllers/module-package.controller.ts +102 -0
- package/src/dtos/confirm-module-package-import.dto.ts +12 -0
- package/src/dtos/metadata-explorer-references-query.dto.ts +39 -0
- package/src/dtos/metadata-explorer-search-query.dto.ts +28 -0
- package/src/dtos/metadata-explorer-write.dto.ts +11 -0
- package/src/dtos/run-module-package-build.dto.ts +14 -0
- package/src/dtos/run-module-package-seed.dto.ts +12 -0
- package/src/helpers/command.service.ts +1 -1
- package/src/helpers/module-metadata-helper.service.ts +19 -21
- package/src/helpers/module.helper.ts +12 -9
- package/src/helpers/typeorm-migration-helpers.ts +163 -0
- package/src/index.ts +8 -0
- package/src/seeders/module-metadata-seeder.service.ts +63 -38
- package/src/seeders/module-test-data.service.ts +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +2365 -1107
- package/src/services/crud-helper.service.ts +79 -1
- package/src/services/crud.service.ts +26 -119
- package/src/services/dashboard-providers/README.md +1 -1
- package/src/services/genai/ingest-metadata.service.ts +3 -3
- package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +37 -2
- package/src/services/mediaStorageProviders/file-storage-provider.ts +5 -1
- package/src/services/model-metadata.service.ts +302 -98
- package/src/services/module-metadata-explorer.service.ts +670 -0
- package/src/services/module-metadata.service.ts +136 -10
- package/src/services/module-package.service.ts +1171 -0
- package/src/services/settings/default-settings-provider.service.ts +10 -0
- package/src/solid-core.module.ts +10 -2
- package/.claude/settings.local.json +0 -15
- package/CLAUDE.md +0 -26
- package/dist/services/database/database-bootstrap.service.d.ts +0 -12
- package/dist/services/database/database-bootstrap.service.d.ts.map +0 -1
- package/dist/services/database/database-bootstrap.service.js +0 -115
- package/dist/services/database/database-bootstrap.service.js.map +0 -1
- package/sql/default/mariadb/proc_CleanupModelMetadata.sql +0 -153
- package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +0 -56
- package/sql/default/mssql/proc_CleanupModuleMetadata.sql +0 -78
- package/sql/default/mysql/proc_CleanupModelMetadata.sql +0 -153
- package/sql/default/mysql/proc_CleanupModuleMetadata.sql +0 -56
- package/sql/default/postgres/proc_CleanupModelMetadata.sql +0 -148
- package/sql/default/postgres/proc_CleanupModuleMetadata.sql +0 -50
- package/sql/default/postgres/scratchpad.sql.txt +0 -12
- package/src/services/1.js +0 -6
- package/src/services/database/database-bootstrap.service.ts +0 -91
|
@@ -0,0 +1,980 @@
|
|
|
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
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
var ModulePackageService_1;
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.ModulePackageService = void 0;
|
|
50
|
+
const common_1 = require("@nestjs/common");
|
|
51
|
+
const crypto_1 = require("crypto");
|
|
52
|
+
const archiver_1 = __importDefault(require("archiver"));
|
|
53
|
+
const fs_1 = require("fs");
|
|
54
|
+
const disallow_in_production_decorator_1 = require("../decorators/disallow-in-production.decorator");
|
|
55
|
+
const confirm_module_package_import_dto_1 = require("../dtos/confirm-module-package-import.dto");
|
|
56
|
+
const run_module_package_build_dto_1 = require("../dtos/run-module-package-build.dto");
|
|
57
|
+
const run_module_package_seed_dto_1 = require("../dtos/run-module-package-seed.dto");
|
|
58
|
+
const command_service_1 = require("../helpers/command.service");
|
|
59
|
+
const module_metadata_helper_service_1 = require("../helpers/module-metadata-helper.service");
|
|
60
|
+
const fs = __importStar(require("fs/promises"));
|
|
61
|
+
const path = __importStar(require("path"));
|
|
62
|
+
const uuid_1 = require("uuid");
|
|
63
|
+
var ModulePackageStatus;
|
|
64
|
+
(function (ModulePackageStatus) {
|
|
65
|
+
ModulePackageStatus["uploaded"] = "uploaded";
|
|
66
|
+
ModulePackageStatus["validated"] = "validated";
|
|
67
|
+
ModulePackageStatus["awaiting_confirmation"] = "awaiting_confirmation";
|
|
68
|
+
ModulePackageStatus["import_running"] = "import_running";
|
|
69
|
+
ModulePackageStatus["awaiting_restart"] = "awaiting_restart";
|
|
70
|
+
ModulePackageStatus["build_running"] = "build_running";
|
|
71
|
+
ModulePackageStatus["build_failed"] = "build_failed";
|
|
72
|
+
ModulePackageStatus["build_succeeded"] = "build_succeeded";
|
|
73
|
+
ModulePackageStatus["seed_running"] = "seed_running";
|
|
74
|
+
ModulePackageStatus["seed_failed"] = "seed_failed";
|
|
75
|
+
ModulePackageStatus["completed"] = "completed";
|
|
76
|
+
ModulePackageStatus["failed"] = "failed";
|
|
77
|
+
})(ModulePackageStatus || (ModulePackageStatus = {}));
|
|
78
|
+
let ModulePackageService = ModulePackageService_1 = class ModulePackageService {
|
|
79
|
+
constructor(commandService, moduleMetadataHelperService) {
|
|
80
|
+
this.commandService = commandService;
|
|
81
|
+
this.moduleMetadataHelperService = moduleMetadataHelperService;
|
|
82
|
+
this.logger = new common_1.Logger(ModulePackageService_1.name);
|
|
83
|
+
}
|
|
84
|
+
async validateUpload(file) {
|
|
85
|
+
if (!file) {
|
|
86
|
+
throw new common_1.BadRequestException('A .sldx archive file is required.');
|
|
87
|
+
}
|
|
88
|
+
await this.cleanupModulePackageTransactions();
|
|
89
|
+
const transactionKey = (0, uuid_1.v4)();
|
|
90
|
+
const workingDir = await this.createWorkingDir(transactionKey);
|
|
91
|
+
const archiveFileName = file.originalname || path.basename(file.path);
|
|
92
|
+
const archiveFilePath = path.join(workingDir, archiveFileName);
|
|
93
|
+
const extractDirPath = path.join(workingDir, 'extract');
|
|
94
|
+
await fs.mkdir(extractDirPath, { recursive: true });
|
|
95
|
+
await fs.rename(file.path, archiveFilePath);
|
|
96
|
+
const parsed = await this.parseArchive(archiveFilePath);
|
|
97
|
+
await this.extractArchive(archiveFilePath, extractDirPath);
|
|
98
|
+
const transaction = {
|
|
99
|
+
transactionKey,
|
|
100
|
+
status: parsed.validation.valid ? ModulePackageStatus.awaiting_confirmation : ModulePackageStatus.failed,
|
|
101
|
+
currentStep: 'preview',
|
|
102
|
+
moduleName: parsed.manifest.module.name,
|
|
103
|
+
moduleDisplayName: parsed.manifest.module.displayName ?? null,
|
|
104
|
+
archiveFileName,
|
|
105
|
+
archiveFilePath,
|
|
106
|
+
extractDirPath,
|
|
107
|
+
archiveRootPrefix: parsed.archiveRootPrefix,
|
|
108
|
+
manifest: parsed.manifest,
|
|
109
|
+
metadataDocument: parsed.metadataDocument,
|
|
110
|
+
preview: parsed.preview,
|
|
111
|
+
validation: parsed.validation,
|
|
112
|
+
conflicts: parsed.preview.conflicts,
|
|
113
|
+
outputs: {
|
|
114
|
+
import: null,
|
|
115
|
+
build: null,
|
|
116
|
+
seed: null,
|
|
117
|
+
},
|
|
118
|
+
errorMessage: parsed.validation.valid ? null : parsed.validation.errors.join('\n'),
|
|
119
|
+
createdAt: new Date().toISOString(),
|
|
120
|
+
updatedAt: new Date().toISOString(),
|
|
121
|
+
};
|
|
122
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
123
|
+
return this.toStatusResponse(transaction);
|
|
124
|
+
}
|
|
125
|
+
async getStatus(transactionKey) {
|
|
126
|
+
const transaction = await this.loadTransaction(transactionKey);
|
|
127
|
+
return this.toStatusResponse(transaction);
|
|
128
|
+
}
|
|
129
|
+
async getLatestResumableImport() {
|
|
130
|
+
await this.cleanupModulePackageTransactions();
|
|
131
|
+
const transaction = await this.resolveLatestResumableTransaction();
|
|
132
|
+
return transaction ? this.toStatusResponse(transaction) : null;
|
|
133
|
+
}
|
|
134
|
+
async dismissImport(transactionKey) {
|
|
135
|
+
const transaction = await this.loadTransaction(transactionKey);
|
|
136
|
+
await this.clearActiveTransactionIfMatches(transaction.transactionKey);
|
|
137
|
+
return this.toStatusResponse(transaction);
|
|
138
|
+
}
|
|
139
|
+
async clearPackageRuntime() {
|
|
140
|
+
const runtimeRoot = this.getModulePackageRuntimeRoot();
|
|
141
|
+
const importsRoot = this.getModulePackageImportsRoot();
|
|
142
|
+
const exportsRoot = this.getModulePackageExportsRoot();
|
|
143
|
+
const snapshot = await this.collectRuntimeCleanupSnapshot();
|
|
144
|
+
await fs.rm(runtimeRoot, { recursive: true, force: true });
|
|
145
|
+
await fs.mkdir(importsRoot, { recursive: true });
|
|
146
|
+
await fs.mkdir(exportsRoot, { recursive: true });
|
|
147
|
+
return {
|
|
148
|
+
runtimeRoot,
|
|
149
|
+
...snapshot,
|
|
150
|
+
clearedAt: new Date().toISOString(),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async exportModulePackage(moduleNameInput) {
|
|
154
|
+
const moduleName = (moduleNameInput ?? '').trim();
|
|
155
|
+
if (!moduleName) {
|
|
156
|
+
throw new common_1.BadRequestException('A module name is required to export a module package.');
|
|
157
|
+
}
|
|
158
|
+
const solidApiModulePath = this.getSolidApiModuleTargetPath(moduleName);
|
|
159
|
+
const solidUiModulePath = this.getSolidUiModuleTargetPath(moduleName);
|
|
160
|
+
const metadataFilePath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(moduleName);
|
|
161
|
+
await this.assertPathExists(solidApiModulePath, 'solid-api module path');
|
|
162
|
+
await this.assertPathExists(solidUiModulePath, 'solid-ui module path');
|
|
163
|
+
await this.assertPathExists(metadataFilePath, 'module metadata file');
|
|
164
|
+
const metadataDocument = this.parseMetadataDocument(await fs.readFile(metadataFilePath, 'utf-8'), []);
|
|
165
|
+
const transactionKey = (0, uuid_1.v4)();
|
|
166
|
+
const exportRoot = path.join(this.getModulePackageExportsRoot(), transactionKey);
|
|
167
|
+
const stagingDir = path.join(exportRoot, 'staging');
|
|
168
|
+
const archiveFileName = `${moduleName}.sldx`;
|
|
169
|
+
const archiveFilePath = path.join(exportRoot, archiveFileName);
|
|
170
|
+
await fs.mkdir(path.join(stagingDir, 'solid-api', 'src'), { recursive: true });
|
|
171
|
+
await fs.mkdir(path.join(stagingDir, 'solid-ui', 'src'), { recursive: true });
|
|
172
|
+
await fs.cp(solidApiModulePath, path.join(stagingDir, 'solid-api', 'src', moduleName), { recursive: true });
|
|
173
|
+
await fs.cp(solidUiModulePath, path.join(stagingDir, 'solid-ui', 'src', moduleName), { recursive: true });
|
|
174
|
+
const manifest = await this.buildExportManifest(moduleName, metadataDocument, stagingDir);
|
|
175
|
+
await fs.writeFile(path.join(stagingDir, 'manifest.json'), JSON.stringify(manifest, null, 2), 'utf-8');
|
|
176
|
+
await this.createArchiveFromDirectory(stagingDir, archiveFilePath);
|
|
177
|
+
return {
|
|
178
|
+
fileName: archiveFileName,
|
|
179
|
+
filePath: archiveFilePath,
|
|
180
|
+
mimeType: 'application/zip',
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
async confirmImport(transactionKey, dto = {}) {
|
|
184
|
+
const transaction = await this.loadTransaction(transactionKey);
|
|
185
|
+
const preview = transaction.preview;
|
|
186
|
+
const validation = transaction.validation;
|
|
187
|
+
if (!preview || !validation) {
|
|
188
|
+
throw new common_1.BadRequestException('The module package transaction is missing preview or validation data.');
|
|
189
|
+
}
|
|
190
|
+
if (!validation.valid) {
|
|
191
|
+
throw new common_1.BadRequestException({
|
|
192
|
+
message: 'The uploaded module package is invalid and cannot be imported.',
|
|
193
|
+
validation,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const overwriteExisting = dto.overwriteExisting ?? false;
|
|
197
|
+
if (preview.conflicts.length > 0 && !overwriteExisting) {
|
|
198
|
+
throw new common_1.BadRequestException({
|
|
199
|
+
message: 'Conflicts were detected. Re-submit with overwriteExisting=true to continue.',
|
|
200
|
+
conflicts: preview.conflicts,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
transaction.status = ModulePackageStatus.import_running;
|
|
204
|
+
transaction.currentStep = 'import';
|
|
205
|
+
transaction.errorMessage = null;
|
|
206
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
207
|
+
try {
|
|
208
|
+
const moduleName = preview.module.name;
|
|
209
|
+
const solidApiTarget = this.getSolidApiModuleTargetPath(moduleName);
|
|
210
|
+
const solidUiTarget = this.getSolidUiModuleTargetPath(moduleName);
|
|
211
|
+
const extractRoot = transaction.archiveRootPrefix
|
|
212
|
+
? path.join(transaction.extractDirPath, transaction.archiveRootPrefix.replace(/\/$/, ''))
|
|
213
|
+
: transaction.extractDirPath;
|
|
214
|
+
const solidApiSource = path.join(extractRoot, 'solid-api', 'src', moduleName);
|
|
215
|
+
const solidUiSource = path.join(extractRoot, 'solid-ui', 'src', moduleName);
|
|
216
|
+
await this.assertPathExists(solidApiSource, 'solid-api module source');
|
|
217
|
+
await this.assertPathExists(solidUiSource, 'solid-ui module source');
|
|
218
|
+
if (overwriteExisting) {
|
|
219
|
+
await fs.rm(solidApiTarget, { recursive: true, force: true });
|
|
220
|
+
await fs.rm(solidUiTarget, { recursive: true, force: true });
|
|
221
|
+
}
|
|
222
|
+
await fs.mkdir(path.dirname(solidApiTarget), { recursive: true });
|
|
223
|
+
await fs.mkdir(path.dirname(solidUiTarget), { recursive: true });
|
|
224
|
+
await fs.cp(solidApiSource, solidApiTarget, { recursive: true, force: overwriteExisting });
|
|
225
|
+
await fs.cp(solidUiSource, solidUiTarget, { recursive: true, force: overwriteExisting });
|
|
226
|
+
if (transaction.extractDirPath) {
|
|
227
|
+
await fs.rm(transaction.extractDirPath, { recursive: true, force: true });
|
|
228
|
+
transaction.extractDirPath = null;
|
|
229
|
+
}
|
|
230
|
+
transaction.status = ModulePackageStatus.awaiting_restart;
|
|
231
|
+
transaction.currentStep = 'restart';
|
|
232
|
+
transaction.outputs.import = [
|
|
233
|
+
`Placed solid-api module at ${solidApiTarget}`,
|
|
234
|
+
`Placed solid-ui module at ${solidUiTarget}`,
|
|
235
|
+
`Metadata file placed at ${preview.requiredPaths.metadataPath}`,
|
|
236
|
+
].join('\n');
|
|
237
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
238
|
+
await this.syncActiveTransactionPointer(transaction);
|
|
239
|
+
return this.toStatusResponse(transaction);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
transaction.status = ModulePackageStatus.failed;
|
|
243
|
+
transaction.currentStep = 'import';
|
|
244
|
+
transaction.errorMessage = error.message ?? 'Failed to import the module package.';
|
|
245
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
246
|
+
await this.syncActiveTransactionPointer(transaction);
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async runBuild(transactionKey, dto = {}) {
|
|
251
|
+
const transaction = await this.loadTransaction(transactionKey);
|
|
252
|
+
transaction.status = ModulePackageStatus.build_running;
|
|
253
|
+
transaction.currentStep = 'build';
|
|
254
|
+
transaction.errorMessage = null;
|
|
255
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
256
|
+
try {
|
|
257
|
+
const buildSolidApi = dto.buildSolidApi ?? true;
|
|
258
|
+
const buildSolidUi = dto.buildSolidUi ?? true;
|
|
259
|
+
const outputs = [];
|
|
260
|
+
const failedTargets = [];
|
|
261
|
+
const projectRoot = this.getProjectRoot();
|
|
262
|
+
if (buildSolidApi) {
|
|
263
|
+
try {
|
|
264
|
+
const output = await this.commandService.executeCommandWithArgs({
|
|
265
|
+
command: 'npx',
|
|
266
|
+
args: ['-y', '@solidxai/solidctl@latest', 'build'],
|
|
267
|
+
cwd: projectRoot,
|
|
268
|
+
});
|
|
269
|
+
outputs.push(`solidctl build [success]\n${output}`.trim());
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
failedTargets.push('solidctl build');
|
|
273
|
+
outputs.push(`solidctl build [failed]\n${error?.message ?? 'Build failed.'}`.trim());
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (buildSolidUi) {
|
|
277
|
+
try {
|
|
278
|
+
const output = await this.commandService.executeCommandWithArgs({
|
|
279
|
+
command: 'npx',
|
|
280
|
+
args: ['-y', '@solidxai/solidctl@latest', 'build', '--ui-only'],
|
|
281
|
+
cwd: projectRoot,
|
|
282
|
+
});
|
|
283
|
+
outputs.push(`solidctl build --ui-only [success]\n${output}`.trim());
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
failedTargets.push('solidctl build --ui-only');
|
|
287
|
+
outputs.push(`solidctl build --ui-only [failed]\n${error?.message ?? 'Build failed.'}`.trim());
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
transaction.status = failedTargets.length > 0
|
|
291
|
+
? ModulePackageStatus.build_failed
|
|
292
|
+
: ModulePackageStatus.build_succeeded;
|
|
293
|
+
transaction.currentStep = 'build';
|
|
294
|
+
transaction.outputs.build = outputs.join('\n\n');
|
|
295
|
+
transaction.errorMessage = failedTargets.length > 0
|
|
296
|
+
? `Build completed with errors in: ${failedTargets.join(', ')}`
|
|
297
|
+
: null;
|
|
298
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
299
|
+
await this.syncActiveTransactionPointer(transaction);
|
|
300
|
+
return this.toStatusResponse(transaction);
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
transaction.status = ModulePackageStatus.build_failed;
|
|
304
|
+
transaction.currentStep = 'build';
|
|
305
|
+
transaction.errorMessage = error.message ?? 'Build failed.';
|
|
306
|
+
transaction.outputs.build = error.message ?? '';
|
|
307
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
308
|
+
await this.syncActiveTransactionPointer(transaction);
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async runSeed(transactionKey, dto = {}) {
|
|
313
|
+
const transaction = await this.loadTransaction(transactionKey);
|
|
314
|
+
const moduleName = transaction.moduleName;
|
|
315
|
+
if (!moduleName) {
|
|
316
|
+
throw new common_1.BadRequestException('Unable to seed because the transaction is missing moduleName.');
|
|
317
|
+
}
|
|
318
|
+
transaction.status = ModulePackageStatus.seed_running;
|
|
319
|
+
transaction.currentStep = 'seed';
|
|
320
|
+
transaction.errorMessage = null;
|
|
321
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
322
|
+
try {
|
|
323
|
+
const output = await this.commandService.executeCommandWithArgs({
|
|
324
|
+
command: 'npx',
|
|
325
|
+
args: ['-y', '@solidxai/solidctl@latest', 'seed', '--modules-to-seed', moduleName],
|
|
326
|
+
cwd: this.getProjectRoot(),
|
|
327
|
+
});
|
|
328
|
+
transaction.status = ModulePackageStatus.completed;
|
|
329
|
+
transaction.currentStep = 'done';
|
|
330
|
+
transaction.outputs.seed = [
|
|
331
|
+
`solidctl seed --modules-to-seed ${moduleName} [success]`,
|
|
332
|
+
output,
|
|
333
|
+
].filter(Boolean).join('\n');
|
|
334
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
335
|
+
await this.syncActiveTransactionPointer(transaction);
|
|
336
|
+
return this.toStatusResponse(transaction);
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
transaction.status = ModulePackageStatus.seed_failed;
|
|
340
|
+
transaction.currentStep = 'seed';
|
|
341
|
+
transaction.errorMessage = error.message ?? 'Seed failed.';
|
|
342
|
+
transaction.outputs.seed = error.message ?? '';
|
|
343
|
+
await this.writeStatusFile(transactionKey, transaction);
|
|
344
|
+
await this.syncActiveTransactionPointer(transaction);
|
|
345
|
+
return this.toStatusResponse(transaction);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
async parseArchive(archiveFilePath) {
|
|
349
|
+
const entries = await this.listArchiveEntries(archiveFilePath);
|
|
350
|
+
const archiveRootPrefix = this.detectArchiveRootPrefix(entries);
|
|
351
|
+
const normalizedEntries = this.normalizeArchiveEntries(entries, archiveRootPrefix);
|
|
352
|
+
const validationErrors = [];
|
|
353
|
+
const validationWarnings = [];
|
|
354
|
+
if (path.extname(archiveFilePath).toLowerCase() !== '.sldx') {
|
|
355
|
+
validationErrors.push('Only .sldx archives are supported.');
|
|
356
|
+
}
|
|
357
|
+
const unsafeEntries = normalizedEntries.filter((entry) => this.isUnsafeArchivePath(entry));
|
|
358
|
+
if (unsafeEntries.length > 0) {
|
|
359
|
+
validationErrors.push(`Archive contains unsafe paths: ${unsafeEntries.join(', ')}`);
|
|
360
|
+
}
|
|
361
|
+
if (!normalizedEntries.includes('manifest.json')) {
|
|
362
|
+
validationErrors.push('Archive is missing manifest.json at the root.');
|
|
363
|
+
}
|
|
364
|
+
const manifestArchivePath = this.toArchiveEntryPath(archiveRootPrefix, 'manifest.json');
|
|
365
|
+
const manifestText = normalizedEntries.includes('manifest.json')
|
|
366
|
+
? await this.readArchiveEntry(archiveFilePath, manifestArchivePath)
|
|
367
|
+
: '';
|
|
368
|
+
const manifest = this.parseManifest(manifestText, validationErrors);
|
|
369
|
+
if (!manifest) {
|
|
370
|
+
return {
|
|
371
|
+
entries: normalizedEntries,
|
|
372
|
+
archiveRootPrefix,
|
|
373
|
+
manifest: this.getFallbackManifest(),
|
|
374
|
+
metadataDocument: null,
|
|
375
|
+
validation: {
|
|
376
|
+
valid: false,
|
|
377
|
+
errors: validationErrors,
|
|
378
|
+
warnings: validationWarnings,
|
|
379
|
+
},
|
|
380
|
+
preview: {
|
|
381
|
+
module: { name: '', displayName: '' },
|
|
382
|
+
manifest: this.getFallbackManifest(),
|
|
383
|
+
contentsSummary: {
|
|
384
|
+
totalEntries: normalizedEntries.length,
|
|
385
|
+
solidApiEntries: normalizedEntries.filter((entry) => entry.startsWith('solid-api/')).length,
|
|
386
|
+
solidUiEntries: normalizedEntries.filter((entry) => entry.startsWith('solid-ui/')).length,
|
|
387
|
+
},
|
|
388
|
+
requiredPaths: {
|
|
389
|
+
metadataPath: '',
|
|
390
|
+
apiModulePath: '',
|
|
391
|
+
uiModulePath: '',
|
|
392
|
+
},
|
|
393
|
+
conflicts: [],
|
|
394
|
+
fileTree: normalizedEntries,
|
|
395
|
+
nextActions: ['Fix archive structure and upload again.'],
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
if (manifest.packageType !== ModulePackageService_1.SUPPORTED_PACKAGE_TYPE) {
|
|
400
|
+
validationErrors.push(`manifest.json packageType must be "${ModulePackageService_1.SUPPORTED_PACKAGE_TYPE}".`);
|
|
401
|
+
}
|
|
402
|
+
if (manifest.schemaVersion !== ModulePackageService_1.SUPPORTED_SCHEMA_VERSION) {
|
|
403
|
+
validationErrors.push(`manifest.json schemaVersion must be "${ModulePackageService_1.SUPPORTED_SCHEMA_VERSION}".`);
|
|
404
|
+
}
|
|
405
|
+
if (!manifest.module?.name) {
|
|
406
|
+
validationErrors.push('manifest.json module.name is required.');
|
|
407
|
+
}
|
|
408
|
+
const moduleName = manifest.module?.name ?? '';
|
|
409
|
+
const expectedPaths = this.buildExpectedPaths(moduleName);
|
|
410
|
+
if (manifest.contents?.metadataPath !== expectedPaths.metadataPath) {
|
|
411
|
+
validationErrors.push(`manifest.json contents.metadataPath must be "${expectedPaths.metadataPath}".`);
|
|
412
|
+
}
|
|
413
|
+
if (manifest.contents?.apiModulePath !== expectedPaths.apiModulePath) {
|
|
414
|
+
validationErrors.push(`manifest.json contents.apiModulePath must be "${expectedPaths.apiModulePath}".`);
|
|
415
|
+
}
|
|
416
|
+
if (manifest.contents?.uiModulePath !== expectedPaths.uiModulePath) {
|
|
417
|
+
validationErrors.push(`manifest.json contents.uiModulePath must be "${expectedPaths.uiModulePath}".`);
|
|
418
|
+
}
|
|
419
|
+
if (!normalizedEntries.includes(expectedPaths.metadataPath)) {
|
|
420
|
+
validationErrors.push(`Archive is missing ${expectedPaths.metadataPath}.`);
|
|
421
|
+
}
|
|
422
|
+
if (!normalizedEntries.includes(expectedPaths.apiModulePath)) {
|
|
423
|
+
validationErrors.push(`Archive is missing ${expectedPaths.apiModulePath}.`);
|
|
424
|
+
}
|
|
425
|
+
if (!normalizedEntries.includes(expectedPaths.uiModulePath)) {
|
|
426
|
+
validationErrors.push(`Archive is missing ${expectedPaths.uiModulePath}.`);
|
|
427
|
+
}
|
|
428
|
+
const metadataDocument = normalizedEntries.includes(expectedPaths.metadataPath)
|
|
429
|
+
? this.parseMetadataDocument(await this.readArchiveEntry(archiveFilePath, this.toArchiveEntryPath(archiveRootPrefix, expectedPaths.metadataPath)), validationErrors)
|
|
430
|
+
: null;
|
|
431
|
+
const metadataModuleName = metadataDocument?.moduleMetadata?.name;
|
|
432
|
+
if (metadataModuleName && metadataModuleName !== moduleName) {
|
|
433
|
+
validationErrors.push(`Metadata module name "${metadataModuleName}" does not match manifest module name "${moduleName}".`);
|
|
434
|
+
}
|
|
435
|
+
if (!manifest.checksums || Object.keys(manifest.checksums).length === 0) {
|
|
436
|
+
validationWarnings.push('manifest.json does not include checksums. Checksums are recommended.');
|
|
437
|
+
}
|
|
438
|
+
const conflicts = await this.detectConflicts(moduleName);
|
|
439
|
+
if (conflicts.length > 0) {
|
|
440
|
+
validationWarnings.push('The target module already exists locally and will require overwrite confirmation.');
|
|
441
|
+
}
|
|
442
|
+
const validation = {
|
|
443
|
+
valid: validationErrors.length === 0,
|
|
444
|
+
errors: validationErrors,
|
|
445
|
+
warnings: validationWarnings,
|
|
446
|
+
};
|
|
447
|
+
const preview = {
|
|
448
|
+
module: manifest.module,
|
|
449
|
+
manifest,
|
|
450
|
+
contentsSummary: {
|
|
451
|
+
totalEntries: normalizedEntries.length,
|
|
452
|
+
solidApiEntries: normalizedEntries.filter((entry) => entry.startsWith('solid-api/')).length,
|
|
453
|
+
solidUiEntries: normalizedEntries.filter((entry) => entry.startsWith('solid-ui/')).length,
|
|
454
|
+
},
|
|
455
|
+
requiredPaths: expectedPaths,
|
|
456
|
+
conflicts,
|
|
457
|
+
fileTree: normalizedEntries,
|
|
458
|
+
nextActions: [
|
|
459
|
+
'Review archive preview.',
|
|
460
|
+
'Confirm import to place files locally.',
|
|
461
|
+
'Wait for service restart, then run build and seed.',
|
|
462
|
+
],
|
|
463
|
+
};
|
|
464
|
+
return {
|
|
465
|
+
entries: normalizedEntries,
|
|
466
|
+
archiveRootPrefix,
|
|
467
|
+
manifest,
|
|
468
|
+
metadataDocument,
|
|
469
|
+
validation,
|
|
470
|
+
preview,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
parseManifest(manifestText, validationErrors) {
|
|
474
|
+
if (!manifestText) {
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
return JSON.parse(manifestText);
|
|
479
|
+
}
|
|
480
|
+
catch (error) {
|
|
481
|
+
validationErrors.push('manifest.json is not valid JSON.');
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
parseMetadataDocument(documentText, validationErrors) {
|
|
486
|
+
try {
|
|
487
|
+
return JSON.parse(documentText);
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
validationErrors.push('Module metadata JSON is not valid JSON.');
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
async listArchiveEntries(archiveFilePath) {
|
|
495
|
+
const output = await this.commandService.executeCommandWithArgs({
|
|
496
|
+
command: 'unzip',
|
|
497
|
+
args: ['-Z1', archiveFilePath],
|
|
498
|
+
});
|
|
499
|
+
return output
|
|
500
|
+
.split(/\r?\n/)
|
|
501
|
+
.map((entry) => entry.trim())
|
|
502
|
+
.filter(Boolean);
|
|
503
|
+
}
|
|
504
|
+
async readArchiveEntry(archiveFilePath, entryPath) {
|
|
505
|
+
return this.commandService.executeCommandWithArgs({
|
|
506
|
+
command: 'unzip',
|
|
507
|
+
args: ['-p', archiveFilePath, entryPath],
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
async extractArchive(archiveFilePath, extractDirPath) {
|
|
511
|
+
await this.commandService.executeCommandWithArgs({
|
|
512
|
+
command: 'unzip',
|
|
513
|
+
args: ['-o', archiveFilePath, '-d', extractDirPath],
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
async detectConflicts(moduleName) {
|
|
517
|
+
const conflicts = [];
|
|
518
|
+
const solidApiTarget = this.getSolidApiModuleTargetPath(moduleName);
|
|
519
|
+
const solidUiTarget = this.getSolidUiModuleTargetPath(moduleName);
|
|
520
|
+
const metadataFilePath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(moduleName);
|
|
521
|
+
if (await this.pathExists(solidApiTarget)) {
|
|
522
|
+
conflicts.push(`solid-api module already exists at ${solidApiTarget}`);
|
|
523
|
+
}
|
|
524
|
+
if (await this.pathExists(solidUiTarget)) {
|
|
525
|
+
conflicts.push(`solid-ui module already exists at ${solidUiTarget}`);
|
|
526
|
+
}
|
|
527
|
+
if (await this.pathExists(metadataFilePath)) {
|
|
528
|
+
conflicts.push(`module metadata already exists at ${metadataFilePath}`);
|
|
529
|
+
}
|
|
530
|
+
return conflicts;
|
|
531
|
+
}
|
|
532
|
+
buildExpectedPaths(moduleName) {
|
|
533
|
+
return {
|
|
534
|
+
metadataPath: `solid-api/src/${moduleName}/metadata/${moduleName}-metadata.json`,
|
|
535
|
+
apiModulePath: `solid-api/src/${moduleName}/${moduleName}.module.ts`,
|
|
536
|
+
uiModulePath: `solid-ui/src/${moduleName}/${moduleName}.ui-module.ts`,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
detectArchiveRootPrefix(entries) {
|
|
540
|
+
const normalized = entries
|
|
541
|
+
.map((entry) => entry.trim())
|
|
542
|
+
.filter(Boolean)
|
|
543
|
+
.filter((entry) => !this.isMacOsMetadataEntry(entry));
|
|
544
|
+
if (normalized.length === 0) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
const topLevelSegments = normalized
|
|
548
|
+
.map((entry) => entry.split('/')[0])
|
|
549
|
+
.filter(Boolean);
|
|
550
|
+
const uniqueTopLevelSegments = Array.from(new Set(topLevelSegments));
|
|
551
|
+
if (uniqueTopLevelSegments.length !== 1) {
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
const onlySegment = uniqueTopLevelSegments[0];
|
|
555
|
+
const hasNestedEntries = normalized.some((entry) => entry.startsWith(`${onlySegment}/`));
|
|
556
|
+
return hasNestedEntries ? `${onlySegment}/` : null;
|
|
557
|
+
}
|
|
558
|
+
normalizeArchiveEntries(entries, archiveRootPrefix) {
|
|
559
|
+
const filteredEntries = entries.filter((entry) => !this.isMacOsMetadataEntry(entry));
|
|
560
|
+
if (!archiveRootPrefix) {
|
|
561
|
+
return filteredEntries;
|
|
562
|
+
}
|
|
563
|
+
return filteredEntries
|
|
564
|
+
.map((entry) => entry.startsWith(archiveRootPrefix) ? entry.slice(archiveRootPrefix.length) : entry)
|
|
565
|
+
.filter(Boolean);
|
|
566
|
+
}
|
|
567
|
+
toArchiveEntryPath(archiveRootPrefix, normalizedEntryPath) {
|
|
568
|
+
return archiveRootPrefix ? `${archiveRootPrefix}${normalizedEntryPath}` : normalizedEntryPath;
|
|
569
|
+
}
|
|
570
|
+
isUnsafeArchivePath(entry) {
|
|
571
|
+
return entry.startsWith('/') || entry.includes('..') || /^[A-Za-z]:/.test(entry);
|
|
572
|
+
}
|
|
573
|
+
isMacOsMetadataEntry(entry) {
|
|
574
|
+
const normalizedEntry = entry.trim();
|
|
575
|
+
if (!normalizedEntry) {
|
|
576
|
+
return false;
|
|
577
|
+
}
|
|
578
|
+
const segments = normalizedEntry.split('/').filter(Boolean);
|
|
579
|
+
return segments.some((segment) => segment === '__MACOSX' || segment.startsWith('._'));
|
|
580
|
+
}
|
|
581
|
+
getFallbackManifest() {
|
|
582
|
+
return {
|
|
583
|
+
schemaVersion: ModulePackageService_1.SUPPORTED_SCHEMA_VERSION,
|
|
584
|
+
packageType: ModulePackageService_1.SUPPORTED_PACKAGE_TYPE,
|
|
585
|
+
module: { name: '', displayName: '' },
|
|
586
|
+
contents: {
|
|
587
|
+
metadataPath: '',
|
|
588
|
+
apiModulePath: '',
|
|
589
|
+
uiModulePath: '',
|
|
590
|
+
},
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
async loadTransaction(transactionKey) {
|
|
594
|
+
this.assertSafeTransactionKey(transactionKey);
|
|
595
|
+
const statusFilePath = this.getStatusFilePath(transactionKey);
|
|
596
|
+
if (!(await this.pathExists(statusFilePath))) {
|
|
597
|
+
throw new common_1.NotFoundException(`Module package transaction ${transactionKey} was not found.`);
|
|
598
|
+
}
|
|
599
|
+
return JSON.parse(await fs.readFile(statusFilePath, 'utf-8'));
|
|
600
|
+
}
|
|
601
|
+
isResumableStatus(status) {
|
|
602
|
+
return [
|
|
603
|
+
ModulePackageStatus.import_running,
|
|
604
|
+
ModulePackageStatus.awaiting_restart,
|
|
605
|
+
ModulePackageStatus.build_running,
|
|
606
|
+
ModulePackageStatus.build_failed,
|
|
607
|
+
ModulePackageStatus.build_succeeded,
|
|
608
|
+
ModulePackageStatus.seed_running,
|
|
609
|
+
ModulePackageStatus.seed_failed,
|
|
610
|
+
].includes(status);
|
|
611
|
+
}
|
|
612
|
+
async createWorkingDir(transactionKey) {
|
|
613
|
+
const baseDir = path.join(this.getModulePackageImportsRoot(), transactionKey);
|
|
614
|
+
await fs.mkdir(baseDir, { recursive: true });
|
|
615
|
+
return baseDir;
|
|
616
|
+
}
|
|
617
|
+
getSolidApiRoot() {
|
|
618
|
+
return process.cwd();
|
|
619
|
+
}
|
|
620
|
+
getProjectRoot() {
|
|
621
|
+
return path.resolve(this.getSolidApiRoot(), '..');
|
|
622
|
+
}
|
|
623
|
+
getSolidUiRoot() {
|
|
624
|
+
return path.join(this.getProjectRoot(), 'solid-ui');
|
|
625
|
+
}
|
|
626
|
+
getModulePackageImportsRoot() {
|
|
627
|
+
return path.join(this.getModulePackageRuntimeRoot(), 'module-package-imports');
|
|
628
|
+
}
|
|
629
|
+
getModulePackageExportsRoot() {
|
|
630
|
+
return path.join(this.getModulePackageRuntimeRoot(), 'module-package-exports');
|
|
631
|
+
}
|
|
632
|
+
getModulePackageRuntimeRoot() {
|
|
633
|
+
const configuredRuntimeRoot = process.env.SOLIDX_MODULE_PACKAGE_RUNTIME_DIR?.trim();
|
|
634
|
+
if (configuredRuntimeRoot) {
|
|
635
|
+
return path.resolve(configuredRuntimeRoot);
|
|
636
|
+
}
|
|
637
|
+
return path.join(this.getProjectRoot(), '.solidx-runtime');
|
|
638
|
+
}
|
|
639
|
+
getSolidApiModuleTargetPath(moduleName) {
|
|
640
|
+
return path.join(this.getSolidApiRoot(), 'src', moduleName);
|
|
641
|
+
}
|
|
642
|
+
getSolidUiModuleTargetPath(moduleName) {
|
|
643
|
+
return path.join(this.getSolidUiRoot(), 'src', moduleName);
|
|
644
|
+
}
|
|
645
|
+
async pathExists(targetPath) {
|
|
646
|
+
try {
|
|
647
|
+
await fs.access(targetPath);
|
|
648
|
+
return true;
|
|
649
|
+
}
|
|
650
|
+
catch (error) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
async assertPathExists(targetPath, label) {
|
|
655
|
+
if (!(await this.pathExists(targetPath))) {
|
|
656
|
+
throw new common_1.BadRequestException(`Expected ${label} at ${targetPath}, but it was not found in the extracted archive.`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
async readDirSafe(targetPath) {
|
|
660
|
+
try {
|
|
661
|
+
return await fs.readdir(targetPath, { withFileTypes: true });
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
return [];
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
assertSafeTransactionKey(transactionKey) {
|
|
668
|
+
if (!/^[a-zA-Z0-9-]+$/.test(transactionKey)) {
|
|
669
|
+
throw new common_1.BadRequestException('Invalid module package transaction key.');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
getStatusFilePath(transactionKey) {
|
|
673
|
+
this.assertSafeTransactionKey(transactionKey);
|
|
674
|
+
return path.join(this.getModulePackageImportsRoot(), transactionKey, 'status.json');
|
|
675
|
+
}
|
|
676
|
+
getActiveTransactionFilePath() {
|
|
677
|
+
return path.join(this.getModulePackageImportsRoot(), 'active-transaction.json');
|
|
678
|
+
}
|
|
679
|
+
async writeStatusFile(transactionKey, payload) {
|
|
680
|
+
payload.updatedAt = new Date().toISOString();
|
|
681
|
+
const statusFilePath = this.getStatusFilePath(transactionKey);
|
|
682
|
+
await fs.mkdir(path.dirname(statusFilePath), { recursive: true });
|
|
683
|
+
await fs.writeFile(statusFilePath, JSON.stringify(payload, null, 2));
|
|
684
|
+
}
|
|
685
|
+
async markActiveTransaction(transactionKey) {
|
|
686
|
+
const activeTransactionFilePath = this.getActiveTransactionFilePath();
|
|
687
|
+
await fs.mkdir(path.dirname(activeTransactionFilePath), { recursive: true });
|
|
688
|
+
const payload = {
|
|
689
|
+
transactionKey,
|
|
690
|
+
updatedAt: new Date().toISOString(),
|
|
691
|
+
};
|
|
692
|
+
await fs.writeFile(activeTransactionFilePath, JSON.stringify(payload, null, 2));
|
|
693
|
+
}
|
|
694
|
+
async clearActiveTransactionIfMatches(transactionKey) {
|
|
695
|
+
const activeTransaction = await this.loadActiveTransactionPointer();
|
|
696
|
+
if (!activeTransaction || activeTransaction.transactionKey !== transactionKey) {
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
await fs.rm(this.getActiveTransactionFilePath(), { force: true });
|
|
700
|
+
}
|
|
701
|
+
async loadActiveTransactionPointer() {
|
|
702
|
+
try {
|
|
703
|
+
return JSON.parse(await fs.readFile(this.getActiveTransactionFilePath(), 'utf-8'));
|
|
704
|
+
}
|
|
705
|
+
catch (error) {
|
|
706
|
+
return null;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
async syncActiveTransactionPointer(transaction) {
|
|
710
|
+
if (this.isResumableStatus(transaction.status)) {
|
|
711
|
+
await this.markActiveTransaction(transaction.transactionKey);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
await this.clearActiveTransactionIfMatches(transaction.transactionKey);
|
|
715
|
+
}
|
|
716
|
+
async collectRuntimeCleanupSnapshot() {
|
|
717
|
+
const importEntries = await this.readDirSafe(this.getModulePackageImportsRoot());
|
|
718
|
+
const exportEntries = await this.readDirSafe(this.getModulePackageExportsRoot());
|
|
719
|
+
const importTransactionEntries = importEntries.filter((entry) => entry.isDirectory() && /^[a-zA-Z0-9-]+$/.test(entry.name));
|
|
720
|
+
const exportTransactionEntries = exportEntries.filter((entry) => entry.isDirectory() && /^[a-zA-Z0-9-]+$/.test(entry.name));
|
|
721
|
+
const importLooseEntries = importEntries.filter((entry) => !(entry.isDirectory() && /^[a-zA-Z0-9-]+$/.test(entry.name)));
|
|
722
|
+
const exportLooseEntries = exportEntries.filter((entry) => !(entry.isDirectory() && /^[a-zA-Z0-9-]+$/.test(entry.name)));
|
|
723
|
+
return {
|
|
724
|
+
removedImportTransactions: importTransactionEntries.length,
|
|
725
|
+
removedExportTransactions: exportTransactionEntries.length,
|
|
726
|
+
removedImportLooseEntries: importLooseEntries.length,
|
|
727
|
+
removedExportLooseEntries: exportLooseEntries.length,
|
|
728
|
+
clearedActiveTransactionPointer: importEntries.some((entry) => entry.name === 'active-transaction.json'),
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
getCompletedTransactionRetentionMs() {
|
|
732
|
+
const retentionDays = Number(process.env.SOLIDX_MODULE_PACKAGE_RETENTION_DAYS ?? 7);
|
|
733
|
+
const safeDays = Number.isFinite(retentionDays) && retentionDays > 0 ? retentionDays : 7;
|
|
734
|
+
return safeDays * 24 * 60 * 60 * 1000;
|
|
735
|
+
}
|
|
736
|
+
getPendingTransactionRetentionMs() {
|
|
737
|
+
const retentionHours = Number(process.env.SOLIDX_MODULE_PACKAGE_PENDING_RETENTION_HOURS ?? 24);
|
|
738
|
+
const safeHours = Number.isFinite(retentionHours) && retentionHours > 0 ? retentionHours : 24;
|
|
739
|
+
return safeHours * 60 * 60 * 1000;
|
|
740
|
+
}
|
|
741
|
+
async cleanupModulePackageTransactions() {
|
|
742
|
+
const importsRoot = this.getModulePackageImportsRoot();
|
|
743
|
+
const activePointer = await this.loadActiveTransactionPointer();
|
|
744
|
+
const now = Date.now();
|
|
745
|
+
try {
|
|
746
|
+
await fs.mkdir(importsRoot, { recursive: true });
|
|
747
|
+
const entries = await fs.readdir(importsRoot, { withFileTypes: true });
|
|
748
|
+
for (const entry of entries) {
|
|
749
|
+
if (!entry.isDirectory()) {
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
const transactionKey = entry.name;
|
|
753
|
+
if (!/^[a-zA-Z0-9-]+$/.test(transactionKey)) {
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
const statusFilePath = this.getStatusFilePath(transactionKey);
|
|
757
|
+
let transaction = null;
|
|
758
|
+
try {
|
|
759
|
+
transaction = JSON.parse(await fs.readFile(statusFilePath, 'utf-8'));
|
|
760
|
+
}
|
|
761
|
+
catch (error) {
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
const updatedAtMs = transaction.updatedAt ? new Date(transaction.updatedAt).getTime() : 0;
|
|
765
|
+
const ageMs = updatedAtMs > 0 ? now - updatedAtMs : Number.MAX_SAFE_INTEGER;
|
|
766
|
+
const isResumable = this.isResumableStatus(transaction.status);
|
|
767
|
+
const maxAgeMs = isResumable
|
|
768
|
+
? this.getPendingTransactionRetentionMs()
|
|
769
|
+
: this.getCompletedTransactionRetentionMs();
|
|
770
|
+
const shouldDelete = ageMs > maxAgeMs;
|
|
771
|
+
if (!shouldDelete) {
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
await fs.rm(path.join(importsRoot, transactionKey), { recursive: true, force: true });
|
|
775
|
+
if (activePointer?.transactionKey === transactionKey) {
|
|
776
|
+
await fs.rm(this.getActiveTransactionFilePath(), { force: true });
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
catch (error) {
|
|
781
|
+
this.logger.warn(`Failed to clean up module package transactions: ${String(error)}`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
async resolveLatestResumableTransaction() {
|
|
785
|
+
const activePointer = await this.loadActiveTransactionPointer();
|
|
786
|
+
if (activePointer?.transactionKey) {
|
|
787
|
+
try {
|
|
788
|
+
const activeTransaction = await this.loadTransaction(activePointer.transactionKey);
|
|
789
|
+
if (this.isResumableStatus(activeTransaction.status)) {
|
|
790
|
+
return activeTransaction;
|
|
791
|
+
}
|
|
792
|
+
await this.clearActiveTransactionIfMatches(activePointer.transactionKey);
|
|
793
|
+
}
|
|
794
|
+
catch (error) {
|
|
795
|
+
await this.clearActiveTransactionIfMatches(activePointer.transactionKey);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
const importsRoot = this.getModulePackageImportsRoot();
|
|
799
|
+
const candidates = [];
|
|
800
|
+
try {
|
|
801
|
+
const entries = await fs.readdir(importsRoot, { withFileTypes: true });
|
|
802
|
+
for (const entry of entries) {
|
|
803
|
+
if (!entry.isDirectory()) {
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
const transactionKey = entry.name;
|
|
807
|
+
if (!/^[a-zA-Z0-9-]+$/.test(transactionKey)) {
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
const transaction = await this.loadTransaction(transactionKey);
|
|
812
|
+
if (this.isResumableStatus(transaction.status)) {
|
|
813
|
+
candidates.push(transaction);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
catch (error) {
|
|
817
|
+
continue;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
catch (error) {
|
|
822
|
+
return null;
|
|
823
|
+
}
|
|
824
|
+
candidates.sort((left, right) => {
|
|
825
|
+
const leftUpdatedAt = new Date(left.updatedAt ?? left.createdAt ?? 0).getTime();
|
|
826
|
+
const rightUpdatedAt = new Date(right.updatedAt ?? right.createdAt ?? 0).getTime();
|
|
827
|
+
return rightUpdatedAt - leftUpdatedAt;
|
|
828
|
+
});
|
|
829
|
+
const latest = candidates[0] ?? null;
|
|
830
|
+
if (latest) {
|
|
831
|
+
await this.markActiveTransaction(latest.transactionKey);
|
|
832
|
+
}
|
|
833
|
+
return latest;
|
|
834
|
+
}
|
|
835
|
+
toStatusResponse(transaction) {
|
|
836
|
+
return {
|
|
837
|
+
transactionKey: transaction.transactionKey,
|
|
838
|
+
status: transaction.status,
|
|
839
|
+
currentStep: transaction.currentStep,
|
|
840
|
+
moduleName: transaction.moduleName,
|
|
841
|
+
moduleDisplayName: transaction.moduleDisplayName,
|
|
842
|
+
archiveFileName: transaction.archiveFileName,
|
|
843
|
+
manifest: transaction.manifest,
|
|
844
|
+
preview: transaction.preview,
|
|
845
|
+
validation: transaction.validation,
|
|
846
|
+
conflicts: transaction.conflicts,
|
|
847
|
+
outputs: transaction.outputs,
|
|
848
|
+
errorMessage: transaction.errorMessage,
|
|
849
|
+
createdAt: transaction.createdAt,
|
|
850
|
+
updatedAt: transaction.updatedAt,
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
async buildExportManifest(moduleName, metadataDocument, stagingDir) {
|
|
854
|
+
const expectedPaths = this.buildExpectedPaths(moduleName);
|
|
855
|
+
const checksums = await this.computeDirectoryChecksums(stagingDir, ['manifest.json']);
|
|
856
|
+
return {
|
|
857
|
+
schemaVersion: ModulePackageService_1.SUPPORTED_SCHEMA_VERSION,
|
|
858
|
+
packageType: ModulePackageService_1.SUPPORTED_PACKAGE_TYPE,
|
|
859
|
+
exportedAt: new Date().toISOString(),
|
|
860
|
+
generatedBy: {
|
|
861
|
+
name: '@solidxai/core',
|
|
862
|
+
},
|
|
863
|
+
module: {
|
|
864
|
+
name: moduleName,
|
|
865
|
+
displayName: metadataDocument?.moduleMetadata?.displayName,
|
|
866
|
+
description: metadataDocument?.moduleMetadata?.description,
|
|
867
|
+
},
|
|
868
|
+
contents: expectedPaths,
|
|
869
|
+
postImport: {
|
|
870
|
+
recommendedSteps: ['restart', 'build', 'seed'],
|
|
871
|
+
},
|
|
872
|
+
checksums,
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
async computeDirectoryChecksums(rootDir, excludedRelativePaths = []) {
|
|
876
|
+
const excludedPaths = new Set(excludedRelativePaths.map((entry) => entry.replace(/\\/g, '/')));
|
|
877
|
+
const filePaths = await this.collectFilePathsRecursively(rootDir);
|
|
878
|
+
const checksums = {};
|
|
879
|
+
for (const filePath of filePaths) {
|
|
880
|
+
const relativePath = path.relative(rootDir, filePath).replace(/\\/g, '/');
|
|
881
|
+
if (excludedPaths.has(relativePath)) {
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
checksums[relativePath] = await this.computeSha256(filePath);
|
|
885
|
+
}
|
|
886
|
+
return checksums;
|
|
887
|
+
}
|
|
888
|
+
async collectFilePathsRecursively(rootDir) {
|
|
889
|
+
const entries = await fs.readdir(rootDir, { withFileTypes: true });
|
|
890
|
+
const nestedPaths = await Promise.all(entries.map(async (entry) => {
|
|
891
|
+
const entryPath = path.join(rootDir, entry.name);
|
|
892
|
+
if (entry.isDirectory()) {
|
|
893
|
+
return this.collectFilePathsRecursively(entryPath);
|
|
894
|
+
}
|
|
895
|
+
return [entryPath];
|
|
896
|
+
}));
|
|
897
|
+
return nestedPaths.flat();
|
|
898
|
+
}
|
|
899
|
+
async createArchiveFromDirectory(sourceDir, archiveFilePath) {
|
|
900
|
+
await fs.mkdir(path.dirname(archiveFilePath), { recursive: true });
|
|
901
|
+
await new Promise((resolve, reject) => {
|
|
902
|
+
const output = (0, fs_1.createWriteStream)(archiveFilePath);
|
|
903
|
+
const archive = (0, archiver_1.default)('zip', {
|
|
904
|
+
zlib: { level: 9 },
|
|
905
|
+
});
|
|
906
|
+
const rejectOnce = (error) => {
|
|
907
|
+
output.destroy();
|
|
908
|
+
reject(error);
|
|
909
|
+
};
|
|
910
|
+
output.on('close', () => resolve());
|
|
911
|
+
output.on('error', rejectOnce);
|
|
912
|
+
archive.on('warning', rejectOnce);
|
|
913
|
+
archive.on('error', rejectOnce);
|
|
914
|
+
archive.pipe(output);
|
|
915
|
+
archive.directory(sourceDir, false);
|
|
916
|
+
void archive.finalize();
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
async computeSha256(filePath) {
|
|
920
|
+
const fileBuffer = await fs.readFile(filePath);
|
|
921
|
+
return (0, crypto_1.createHash)('sha256').update(fileBuffer).digest('hex');
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
exports.ModulePackageService = ModulePackageService;
|
|
925
|
+
ModulePackageService.SUPPORTED_SCHEMA_VERSION = '1.0';
|
|
926
|
+
ModulePackageService.SUPPORTED_PACKAGE_TYPE = 'solidx-module';
|
|
927
|
+
__decorate([
|
|
928
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
929
|
+
__metadata("design:type", Function),
|
|
930
|
+
__metadata("design:paramtypes", [Object]),
|
|
931
|
+
__metadata("design:returntype", Promise)
|
|
932
|
+
], ModulePackageService.prototype, "validateUpload", null);
|
|
933
|
+
__decorate([
|
|
934
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
935
|
+
__metadata("design:type", Function),
|
|
936
|
+
__metadata("design:paramtypes", []),
|
|
937
|
+
__metadata("design:returntype", Promise)
|
|
938
|
+
], ModulePackageService.prototype, "getLatestResumableImport", null);
|
|
939
|
+
__decorate([
|
|
940
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
941
|
+
__metadata("design:type", Function),
|
|
942
|
+
__metadata("design:paramtypes", [String]),
|
|
943
|
+
__metadata("design:returntype", Promise)
|
|
944
|
+
], ModulePackageService.prototype, "dismissImport", null);
|
|
945
|
+
__decorate([
|
|
946
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
947
|
+
__metadata("design:type", Function),
|
|
948
|
+
__metadata("design:paramtypes", []),
|
|
949
|
+
__metadata("design:returntype", Promise)
|
|
950
|
+
], ModulePackageService.prototype, "clearPackageRuntime", null);
|
|
951
|
+
__decorate([
|
|
952
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
953
|
+
__metadata("design:type", Function),
|
|
954
|
+
__metadata("design:paramtypes", [String]),
|
|
955
|
+
__metadata("design:returntype", Promise)
|
|
956
|
+
], ModulePackageService.prototype, "exportModulePackage", null);
|
|
957
|
+
__decorate([
|
|
958
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
959
|
+
__metadata("design:type", Function),
|
|
960
|
+
__metadata("design:paramtypes", [String, confirm_module_package_import_dto_1.ConfirmModulePackageImportDto]),
|
|
961
|
+
__metadata("design:returntype", Promise)
|
|
962
|
+
], ModulePackageService.prototype, "confirmImport", null);
|
|
963
|
+
__decorate([
|
|
964
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
965
|
+
__metadata("design:type", Function),
|
|
966
|
+
__metadata("design:paramtypes", [String, run_module_package_build_dto_1.RunModulePackageBuildDto]),
|
|
967
|
+
__metadata("design:returntype", Promise)
|
|
968
|
+
], ModulePackageService.prototype, "runBuild", null);
|
|
969
|
+
__decorate([
|
|
970
|
+
(0, disallow_in_production_decorator_1.DisallowInProduction)(),
|
|
971
|
+
__metadata("design:type", Function),
|
|
972
|
+
__metadata("design:paramtypes", [String, run_module_package_seed_dto_1.RunModulePackageSeedDto]),
|
|
973
|
+
__metadata("design:returntype", Promise)
|
|
974
|
+
], ModulePackageService.prototype, "runSeed", null);
|
|
975
|
+
exports.ModulePackageService = ModulePackageService = ModulePackageService_1 = __decorate([
|
|
976
|
+
(0, common_1.Injectable)(),
|
|
977
|
+
__metadata("design:paramtypes", [command_service_1.CommandService,
|
|
978
|
+
module_metadata_helper_service_1.ModuleMetadataHelperService])
|
|
979
|
+
], ModulePackageService);
|
|
980
|
+
//# sourceMappingURL=module-package.service.js.map
|