UNPKG

@vulcan-sql/extension-store-canner

Version:

Canner persistence store for Vulcan SQL

145 lines 8.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CannerPersistenceStore = void 0; const tslib_1 = require("tslib"); const core_1 = require("@vulcan-sql/core"); const inversify_1 = require("inversify"); const storageService_1 = require("../storageService"); const config_1 = require("../config"); const utils_1 = require("./utils"); /** * Used the string to identify the extension Id not by the enum "ArtifactBuilderProviderType". * Because if we create another enum to extend the 'ArtifactBuilderProviderType', it seems unnecessary to give the new enum only has 'Canner' as its type." * */ let CannerPersistenceStore = class CannerPersistenceStore extends core_1.PersistentStore { constructor(options, config, moduleName) { super(config, moduleName); this.logger = this.getLogger(); this.envConfig = (0, config_1.getEnvConfig)(); this.filePath = options.filePath; } // eslint-disable-next-line @typescript-eslint/no-unused-vars save(data) { return tslib_1.__awaiter(this, void 0, void 0, function* () { throw new Error('The extension not provide the save method, it only use to load the data from the storage'); }); } load() { return tslib_1.__awaiter(this, void 0, void 0, function* () { const storageService = yield (0, storageService_1.createStorageService)(this.envConfig.storage); this.logger.debug('Canner storage service created'); const filesInfo = yield storageService.listObjects({ path: this.filePath, recursive: true, }); // get the indicator files path of each workspaces const files = yield (0, utils_1.getIndicatorFilesOfWorkspaces)(filesInfo); this.logger.debug(`Succeed to get the indicator files of each workspaces: ${JSON.stringify(files)}`); // get the latest artifacts of each workspaces const artifacts = yield this.getLatestArtifactsOfWorkspaces(storageService, files); // merge the artifacts of each workspaces to one artifact const artifact = yield this.mergeArtifactsOfWorkspaces(artifacts); this.logger.debug(`Succeed to merge the artifacts: ${artifact}`); return Buffer.from(JSON.stringify(artifact), 'utf-8'); }); } getLatestArtifactsOfWorkspaces(storageService, indicators) { return tslib_1.__awaiter(this, void 0, void 0, function* () { return yield Promise.all( // download latest artifact buffer content of each workspace by viewing the indicator.json of the each workspace indicators.map(({ workspaceId, name: indicatorPath }) => tslib_1.__awaiter(this, void 0, void 0, function* () { const buffer = yield storageService.downObjectAsBuffer({ name: indicatorPath, }); const indicator = JSON.parse(buffer.toString('utf-8')); const artifact = yield this.getWorkspaceArtifact(storageService, indicatorPath, indicator); this.logger.debug('Succeed to download latest artifacts of workspaces'); return { workspaceSqlName: indicator[workspaceId], artifact, }; }))); }); } getWorkspaceArtifact(storageService, indicatorPath, indicator) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const latestArtifactFolder = indicator[indicator.master]; const vulcanFolderPath = indicatorPath.replace('/indicator.json', ''); const path = `${vulcanFolderPath}/${latestArtifactFolder}/result.json`; this.logger.debug(`Download the artifact from path: ${path}`); // download from artifact path name const buffer = yield storageService.downObjectAsBuffer({ name: path, }); // parse the artifact buffer content to object return JSON.parse(buffer.toString('utf-8')); }); } mergeArtifactsOfWorkspaces(artifacts) { return tslib_1.__awaiter(this, void 0, void 0, function* () { const merged = artifacts.reduce((merged, { workspaceSqlName, artifact }) => { // Template Object.entries(artifact.templates).forEach(([sourceName, value]) => { // add the workspace sql name prefix to original source name const workspaceSourceName = `${workspaceSqlName}/${sourceName}`; merged.templates[workspaceSourceName] = value; }); // API Schemas const profile = `canner-${workspaceSqlName}`; artifact.schemas.forEach((schema) => { var _a; // concat the workspace sql name prefix to urlPath, urlPath has the "/" prefix, so concat directly schema.urlPath = `${workspaceSqlName}${schema.urlPath}`; // concat the workspace sql name prefix to template source, so it could find the "sourceName" in templates schema.templateSource = `${workspaceSqlName}/${schema.templateSource}`; // replace the profile to the canner enterprise integration used profile name, it will match to the profiles from canner profile reader. schema.profiles = [profile]; schema.cache = ((_a = schema.cache) === null || _a === void 0 ? void 0 : _a.map((cacheData) => (Object.assign(Object.assign({}, cacheData), { profile })))) || []; merged.schemas.push(schema); }); // Specs, only support the oas3 specification for canner enterprise integration used if (!artifact.specs['oas3']) throw new Error(`The workspace sql name "${workspaceSqlName}" artifact not use "oas3" specification, canner persistence store only support the "oas3" specification`); if (artifact.specs['oas3']['paths']) Object.entries(artifact.specs['oas3']['paths']).forEach(([apiEndpoint, endpointInfo]) => { // concat the workspace sql name prefix to original api endpoint, the "apiEndpoint" has the "/" prefix, so concat directly const endpoint = `${workspaceSqlName}${apiEndpoint}`; merged.specs['oas3']['paths'][endpoint] = endpointInfo; // Add workspace sql name prefix to original operationId & summary const { summary, operationId } = merged.specs['oas3']['paths'][endpoint]['get']; merged.specs['oas3']['paths'][endpoint]['get'] = Object.assign(Object.assign({}, merged.specs['oas3']['paths'][endpoint]['get']), { // e.g: get/xxx => get/{workspaceSqlName}/xxx operationId: `get/${workspaceSqlName}/${operationId === null || operationId === void 0 ? void 0 : operationId.slice(4)}`, // e.g: /xxx => /{workspaceSqlName}/xxx summary: `/${workspaceSqlName}${summary}` }); }); return merged; }, { templates: {}, schemas: [], specs: { oas3: { paths: {} } }, }); // assign the openapi version and info to the merged artifact merged.specs['oas3'] = Object.assign(Object.assign({}, merged.specs['oas3']), { // Follow the OpenAPI specification version 3.0.3 // see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md openapi: '3.0.3', info: { title: 'Data API', version: 'latest', description: 'Data API for Canner Enterprise', } }); return merged; }); } }; CannerPersistenceStore = tslib_1.__decorate([ (0, core_1.VulcanExtensionId)('Canner'), tslib_1.__param(0, (0, inversify_1.inject)(core_1.TYPES.ArtifactBuilderOptions)), tslib_1.__param(1, (0, inversify_1.inject)(core_1.TYPES.ExtensionConfig)), tslib_1.__param(2, (0, inversify_1.inject)(core_1.TYPES.ExtensionName)), tslib_1.__metadata("design:paramtypes", [core_1.ArtifactBuilderOptions, Object, String]) ], CannerPersistenceStore); exports.CannerPersistenceStore = CannerPersistenceStore; //# sourceMappingURL=persistenceStore.js.map