@sap/adp-common
Version:
common logic for all yeoman generators
363 lines • 18.4 kB
JavaScript
;
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