UNPKG

@sap/adp-common

Version:
363 lines 18.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = require("fs"); const yaml = __importStar(require("js-yaml")); const path_1 = require("path"); const zip_a_folder_1 = require("zip-a-folder"); const findUp = require("find-up"); const messages_1 = require("../i18n/messages"); const EnvironmentUtils_1 = require("./EnvironmentUtils"); const vscode_1 = require("../vscode"); const enums_1 = require("../enums"); const logger_1 = require("../logger"); const EndpointsManager_1 = require("./EndpointsManager"); const adp_tooling_1 = require("@sap-ux/adp-tooling"); const path = require("path"); const DEPLOY_CONFIG = "ui5-deploy.yaml"; class Workspace { static project(projectPath) { try { const configExists = this.checkConfigExists(projectPath); const variant = this.getManifestAppdescrFile(projectPath); if (EnvironmentUtils_1.EnvironmentUtils.isRunningInBAS() && configExists) { return this.getOldConfigBAS(variant, projectPath); } else { return this.getConfig(variant, projectPath); } } catch (e) { throw new Error(messages_1.Messages.ERROR_UNABLE_TO_GET_PROJECT_FILES(e.message)); } } static getProjectRequiresAuthentication(projectData, fdcService) { return __awaiter(this, void 0, void 0, function* () { try { switch (projectData.environment) { case messages_1.Messages.CLOUD_FOUNDRY: { const isLoggedInToDifferentSource = yield fdcService.isLoggedInToDifferentSource(projectData.cfOrganization, projectData.cfSpace, projectData.cfApiUrl); const isLogged = yield fdcService.isLoggedIn(); return !isLogged || isLoggedInToDifferentSource; } case messages_1.Messages.ABAP: { const endpointsService = yield EndpointsManager_1.EndpointsManager.getInstance(); return yield endpointsService.getSystemRequiresAuth(projectData.sourceSystem); } default: throw new Error("Unknown environment"); } } catch (error) { throw new Error(messages_1.Messages.ERROR_UNABLE_TO_GET_IF_PROJECT_REQUIRES_AUTH(error.message)); } }); } static setGeneratorHeaderTitle(opts, path, type) { var _a, _b; try { if (typeof ((_a = opts === null || opts === void 0 ? void 0 : opts.appWizard) === null || _a === void 0 ? void 0 : _a.setHeaderTitle) === "function") { const packageJsonPath = findUp.sync("package.json", { cwd: path }); if (!packageJsonPath) { return; } const { name, version } = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, "utf-8")); if (name && version) { opts.appWizard.setHeaderTitle(type, `${name}@${version}`); } } } catch (error) { (_b = logger_1.Logger === null || logger_1.Logger === void 0 ? void 0 : logger_1.Logger.getLogger) === null || _b === void 0 ? void 0 : _b.error(`Error occured while trying to set Generator header. Error message: ${error.message}`); } } static isDeploymentAllowed(projectPath) { try { const manifest = this.getManifestAppdescrFile(projectPath); return (manifest === null || manifest === void 0 ? void 0 : manifest.layer) === enums_1.ApplicationLayer.CUSTOMER_BASE; } catch (error) { throw new Error(`Cannot get manifest.appdescr_variant for project path: ${projectPath}! Error: ${error.message}`); } } static getManifestAppdescrFile(projectPath) { return this.parseFile(projectPath, "webapp/manifest.appdescr_variant"); } static getAdpConfig(projectPath) { return this.parseFile(projectPath, ".adp/config.json"); } static getUI5Yaml(projectPath) { const ui5yamlPath = (0, path_1.resolve)(projectPath, "ui5.yaml"); const content = (0, fs_1.readFileSync)(ui5yamlPath, "utf-8"); return yaml.load(content); } static writeUI5Yaml(projectPath, data) { const updatedYaml = yaml.dump(data); const ui5yamlPath = (0, path_1.resolve)(projectPath, "ui5.yaml"); (0, fs_1.writeFileSync)(ui5yamlPath, updatedYaml, "utf8"); } static archive(basePath, archive) { return __awaiter(this, void 0, void 0, function* () { try { const folderPath = (0, adp_tooling_1.isTypescriptSupported)(basePath) ? path.join(basePath, "dist") : path.join(basePath, "webapp"); yield (0, zip_a_folder_1.zip)(folderPath, archive); } catch (error) { throw new Error(`Unable to archive project. ${error === null || error === void 0 ? void 0 : error.message}`); } }); } static deleteFile(folder, file) { const filePath = (0, path_1.join)(folder, file); try { if ((0, fs_1.existsSync)(filePath)) { (0, fs_1.unlinkSync)(filePath); } } catch (error) { throw new Error(`Unable to delete file: ${filePath}. ${error === null || error === void 0 ? void 0 : error.message}`); } } static isCloudProject(projectPath) { const parsedManifest = this.getManifestAppdescrFile(projectPath); return parsedManifest.content.some((change) => change.changeType === "appdescr_app_removeAllInboundsExceptOne"); } static hasDeployConfig(projectPath) { return (0, fs_1.existsSync)((0, path_1.join)(projectPath, DEPLOY_CONFIG)); } static getOldConfigBAS(variant, projectPath) { const config = this.getAdpConfig(projectPath); return { path: projectPath, title: projectPath.split("/").pop(), namespace: variant.namespace, name: config.appvariant, layer: variant.layer, environment: config.environment, sourceSystem: config.sourceSystem, applicationIdx: variant.reference, reference: variant.reference, id: variant.id, ui5Version: config.ui5Version, cfApiUrl: config === null || config === void 0 ? void 0 : config.cfApiUrl, cfOrganization: config === null || config === void 0 ? void 0 : config.cfOrganization, cfSpace: config === null || config === void 0 ? void 0 : config.cfSpace }; } static checkUI5YamlExists(projectPath) { if (!(0, fs_1.existsSync)((0, path_1.resolve)(projectPath, "ui5.yaml"))) { throw new Error("Missing ui5.yaml!"); } } static showErrorWithLink(property) { const vscode = vscode_1.ModuleResolver.resolve("vscode"); const documentation = "Documentation"; vscode.window .showErrorMessage(`The ui5.yaml of your adaptation project does not include a ${property} property and will not function properly without it. Please refer to the documentation how to add it.`, documentation) .then((selection) => { if (selection === documentation) { vscode.env.openExternal(vscode.Uri.parse("https://help.sap.com/docs/bas/developing-sap-fiori-app-in-sap-business-application-studio/adaptation-project-for-on-premise-system?locale=en-US#using-project-created-in-vs-code")); } }); } static getConfig(variant, projectPath) { this.checkUI5YamlExists(projectPath); const { server: { customMiddleware } } = this.getUI5Yaml(projectPath); const { fioriPreviewConfig, fioriProxyConfig } = this.getMiddlewaresConfigurations(customMiddleware); const isRunningInBAS = EnvironmentUtils_1.EnvironmentUtils.isRunningInBAS(); const [{ client, destination, url, authenticationType }, { version }] = [fioriPreviewConfig.adp.target, fioriProxyConfig.ui5]; const sourceSystem = isRunningInBAS ? destination : url; return { path: projectPath, title: projectPath.split("/").pop(), namespace: variant.namespace, name: variant.id.startsWith("customer.") ? variant.id.replace(/customer./, "") : variant.id, layer: variant.layer, environment: messages_1.Messages.ABAP, sourceSystem, client, applicationIdx: variant.reference, reference: variant.reference, id: variant.id, ui5Version: version, authenticationType: authenticationType }; } static validatePropertyExists(property, errMsg) { if (!property) { throw Error(errMsg); } } static validateFileExists(filePath, fileName) { if (!(0, fs_1.existsSync)(filePath)) { throw new Error(`Missing "${fileName}" file!`); } } static removeFlpConfig(projectPath) { return __awaiter(this, void 0, void 0, function* () { const i18nFilePath = (0, path_1.join)(projectPath, "webapp", "i18n", "i18n.properties"); this.validateFileExists(i18nFilePath, "i18n.properties"); const manifestAppDescr = Workspace.getManifestAppdescrFile(projectPath); const filteredContent = manifestAppDescr.content.filter((change) => change.changeType !== "appdescr_app_addNewInbound" && change.changeType !== "appdescr_app_removeAllInboundsExceptOne" && change.changeType !== "appdescr_app_changeInbound"); manifestAppDescr.content = filteredContent; const formattedJson = JSON.stringify(manifestAppDescr, null, 2); (0, fs_1.writeFileSync)((0, path_1.join)(projectPath, "webapp", "manifest.appdescr_variant"), formattedJson, "utf-8"); const content = (0, fs_1.readFileSync)(i18nFilePath, "utf-8"); const lines = content.split("\n"); const updatedLines = lines.filter((line) => !line.includes("sap.app.crossNavigation.inbounds")); (0, fs_1.writeFileSync)(i18nFilePath, updatedLines.join("\n"), "utf-8"); }); } static getCloudConfigs(ui5DeployYamlPath) { const ui5DeployYaml = (0, fs_1.readFileSync)(ui5DeployYamlPath, "utf-8"); const content = yaml.load(ui5DeployYaml); this.validatePropertyExists(content.builder, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("builder")); this.validatePropertyExists(content.builder.customTasks, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("customTasks")); const config = content.builder.customTasks.find((customTask) => customTask.name === "deploy-to-abap"); this.validatePropertyExists(config.configuration, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("configuration")); this.validatePropertyExists(config.configuration.target, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("target")); this.validatePropertyExists(config.configuration.app, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("app")); this.validatePropertyExists(config.configuration.app.name, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("name")); this.validatePropertyExists(config.configuration.app.package, messages_1.Messages.ERROR_MISSING_PROPERTY_IN_UI5_DEPLOY("pakage")); return config; } static getDeployTaskApp(projectPath) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const ui5DeployYamlPath = (0, path_1.join)(projectPath, "ui5-deploy.yaml"); if (!(0, fs_1.existsSync)(ui5DeployYamlPath)) { return undefined; } const fileContent = (0, fs_1.readFileSync)(ui5DeployYamlPath, "utf-8"); const content = yaml.load(fileContent); if (!(content === null || content === void 0 ? void 0 : content.builder)) { return undefined; } const customTasks = (_a = content.builder) === null || _a === void 0 ? void 0 : _a.customTasks; if (!customTasks || !customTasks.length) { return undefined; } const deployTask = customTasks.find((customTask) => customTask.name === "deploy-to-abap"); return (_b = deployTask === null || deployTask === void 0 ? void 0 : deployTask.configuration) === null || _b === void 0 ? void 0 : _b.app; }); } static updateYamlProperty(projectPath, propertyPath, newValue) { try { const data = this.getUI5Yaml(projectPath); let current = data; for (let i = 0; i < propertyPath.length - 1; i++) { if (!(propertyPath[i] in current)) { throw new Error(`Property path not found: ${propertyPath.slice(0, i + 1).join(".")}`); } current = current[propertyPath[i]]; } const propertyName = propertyPath[propertyPath.length - 1]; if (!(propertyName in current)) { throw new Error(`Property path not found: ${propertyPath.join(".")}`); } current[propertyName] = newValue; this.writeUI5Yaml(projectPath, data); } catch (e) { const vscode = vscode_1.ModuleResolver.resolve("vscode"); vscode.window.showErrorMessage(`Cannot update ui5.yaml file. ${e.message}`); } } static getMiddlewaresConfigurations(customMiddleware) { const fioriPreviewConfig = this.findMiddleware(customMiddleware, this.isFioriToolsPreview).configuration; const fioriProxyConfig = this.findMiddleware(customMiddleware, this.isFioriToolsProxy).configuration; return { fioriPreviewConfig, fioriProxyConfig }; } static isValidUI5Yaml(projectPath) { const isRunningInBAS = EnvironmentUtils_1.EnvironmentUtils.isRunningInBAS(); if (isRunningInBAS && this.checkConfigExists(projectPath)) { return true; } this.checkUI5YamlExists(projectPath); const { server: { customMiddleware } } = this.getUI5Yaml(projectPath); const { fioriPreviewConfig, fioriProxyConfig } = this.getMiddlewaresConfigurations(customMiddleware); return this.propertiesExist(fioriPreviewConfig, fioriProxyConfig); } static assertProperties(properties, target) { for (const property of properties) { const value = target[property]; if (value === null || value === undefined) { this.showErrorWithLink(property); return false; } } return true; } static findMiddleware(middlewareList, typeGuard) { const middleware = middlewareList.find(typeGuard); if (!middleware) { throw new Error(`Middleware was not found in ui5.yaml configuration.`); } return middleware; } static isFioriToolsPreview(middleware) { return middleware.name === "fiori-tools-preview"; } static isFioriToolsProxy(middleware) { return middleware.name === "fiori-tools-proxy"; } static parseFile(projectPath, filePath) { return JSON.parse((0, fs_1.readFileSync)((0, path_1.resolve)(projectPath, filePath), "utf-8")); } static propertiesExist(fioriPreviewConfig, fioriProxyConfig) { const adpPropertyExists = this.assertProperties(["adp"], fioriPreviewConfig); const targetPropertyExists = this.assertProperties(["target"], fioriPreviewConfig.adp); const ui5PropertyExists = this.assertProperties(["ui5"], fioriProxyConfig); const ui5PropertiesPropertyExist = this.assertProperties(["version", "path", "url"], fioriProxyConfig.ui5); if (!adpPropertyExists || !targetPropertyExists || !ui5PropertyExists || !ui5PropertiesPropertyExist) { return false; } if (EnvironmentUtils_1.EnvironmentUtils.isRunningInBAS()) { return this.assertProperties(["destination"], fioriPreviewConfig.adp.target); } else { return this.assertProperties(["url", "client"], fioriPreviewConfig.adp.target); } } static checkConfigExists(projectPath) { return (0, fs_1.existsSync)((0, path_1.resolve)(projectPath, ".adp", "config.json")); } } exports.default = Workspace; //# sourceMappingURL=Workspace.js.map