UNPKG

@sap/generator-adaptation-project

Version:

Adaptation project allows you to create an app variant for an existing SAP Fiori elements-based or SAPUI5 freestyle application, without changing the original application.

465 lines 21.2 kB
"use strict"; 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 }); exports.validateCloudPackage = exports.validatePackageExtended = exports.validateTransportChoiceInput = exports.validatePackageChoiceInput = exports.validateDuplicateName = exports.validateSAPUI5Repository = exports.validatePackage = exports.validatePropertyObject = exports.validateEnvironment = exports.validatePropertyNumber = exports.validatePropertyBoolean = exports.validatePropertyBinding = exports.validateClient = exports.validateForSpecialCharacters = exports.validateURI = exports.validateExistingAnnotationFile = exports.validateFieldForEmptyValueAndUserState = exports.validateAnnotationJSON = exports.validateForEmptyValue = exports.validateEmptySelect = exports.validateBusinessSolutionName = exports.validateEmptyInput = exports.validateProjectPath = exports.validateAch = exports.validateNamespace = exports.validateProjectName = void 0; const fs = require("fs"); const adp_common_1 = require("@sap/adp-common"); const adp_cf_1 = require("@sap/adp-cf"); const path_1 = require("path"); const transport_list_1 = require("../utils/transport-list"); const axios_extension_1 = require("@sap-ux/axios-extension"); function validateProjectName(value, destinationPath, isInternalMode, isCfMode) { return new Promise((resolve) => { if (!value) { resolve(adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(isCfMode ? adp_common_1.Messages.PROJECT_NAME_CF_INTERNAL_PROMPT_LABEL : adp_common_1.Messages.PROJECT_NAME_INTERNAL_PROMPT_LABEL)); } if (/[A-Z]/.test(value)) { resolve(adp_common_1.Messages.PROJECT_NAME_UPPERCASE_LETTERS_ERROR(isCfMode)); } if (isInternalMode) { resolve(validateProjectNameInternal(value, destinationPath, isCfMode)); } else { resolve(validateProjectNameExternal(value, destinationPath, isCfMode)); } }); } exports.validateProjectName = validateProjectName; function validateProjectNameInternal(value, destinationPath, isCfMode) { const sProjectNameInternalPattern = /^([a-z]{1,}[a-z0-9]*((\.){1}[a-z]{1,}[a-z0-9]*){1,})+$/i; if (sProjectNameInternalPattern.test(value)) { if (value.toLowerCase().startsWith("customer") || value.length > 61 || value.toLocaleLowerCase().endsWith("component")) { return adp_common_1.Messages.PROJECT_NAME_INTERNAL_LENGTH_ERROR(isCfMode); } if (isCfMode) { return validateDuplicateProjectName(value, destinationPath); } return true; } else { return adp_common_1.Messages.INTERNAL_PROJECT_NAME_VALIDATION_ERROR(isCfMode); } } function validateProjectNameExternal(value, destinationPath, isCfMode) { const sProjectNameExternalPattern = /^[a-zA-Z]+((\.)?[a-zA-Z0-9])*$/; if (sProjectNameExternalPattern.test(value)) { if (value.length > 61 || value.toLocaleLowerCase().endsWith("component")) { return adp_common_1.Messages.PROJECT_NAME_EXTERNAL_LENGTH_ERROR(isCfMode); } if (isCfMode) { return validateDuplicateProjectName(value, destinationPath); } return true; } else { return adp_common_1.Messages.EXTERNAL_PROJECT_NAME_VALIDATION_ERROR(isCfMode); } } function validateNamespace(namespace, projectName, isInternalMode) { return new Promise((resolve) => { if (namespace.length <= 0) { resolve(adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.NAMESPACE_PROMPT_LABEL)); } if (isInternalMode) { if (namespace !== projectName) { resolve(adp_common_1.Messages.NAMESPACE_SAME_AS_PROJECT_NAME_ERROR); } } else if (namespace.toLowerCase().startsWith("customer.") !== true) { resolve(adp_common_1.Messages.NAMESPACE_SHOULD_START_WITH_CUSTOMER_ERROR); } else { // simulate the behavior of FullStack as the customer prefix is in another input namespace = namespace.slice("customer.".length, namespace.length); } const sNamespacePattern = /^[a-zA-Z]+((\.)?[a-zA-Z0-9])*$/; if (namespace.length > 61 || namespace.toLowerCase().endsWith("component") === true) { resolve(adp_common_1.Messages.NAMESPACE_MAXLENGTH_VALIDATION_ERROR); } else if (namespace !== "" && sNamespacePattern.test(namespace) === false) { resolve(adp_common_1.Messages.NAMESPACE_VALIDATION_ERROR); } resolve(true); }); } exports.validateNamespace = validateNamespace; function validateAch(ach, isInternalMode) { return new Promise((resolve) => { if (!ach) { resolve(adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.ACH_PROMPT_LABEL)); } // eslint-disable-next-line const isValid = ach.toUpperCase().match(/^([A-Z0-9]{2,3})(\-[A-Z0-9]{1,6})*$/); if (isInternalMode && !isValid) { resolve(adp_common_1.Messages.ACH_MANDATORY_ERROR); } resolve(true); }); } exports.validateAch = validateAch; function validateProjectPath(projectPath, fdcService) { return __awaiter(this, void 0, void 0, function* () { // validate input is not empty if (!projectPath) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.PROJECT_PATH); } try { fs.realpathSync(projectPath, "utf-8"); } catch (err) { return adp_common_1.Messages.ERROR_PROJECT_DOES_NOT_EXIST; } // validate if project exist if (!fs.existsSync(projectPath)) { return adp_common_1.Messages.ERROR_PROJECT_DOES_NOT_EXIST; } if (!adp_cf_1.YamlUtils.isMtaProject(projectPath)) { return adp_common_1.Messages.ERROR_INVALID_PROJECT_PATH; } let services; try { services = yield fdcService.getServices(projectPath); } catch (err) { services = []; } if (services.length < 1) { return adp_common_1.Messages.NO_SERVICES_ERROR; } return true; }); } exports.validateProjectPath = validateProjectPath; function validateEmptyInput(input, label) { // validate input is not empty if (!input) { return Promise.resolve(adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(label)); } return Promise.resolve(true); } exports.validateEmptyInput = validateEmptyInput; function validateBusinessSolutionName(input) { const namePattern = /^([a-z]{1,}[a-z0-9]*((\.){1}[a-z]{1,}[a-z0-9]*){1,})+$/i; const isValid = namePattern.test(input); if (!input) { return Promise.resolve(adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.BUSINESS_SOLUTION_NAME)); } if (!isValid) { return Promise.resolve(adp_common_1.Messages.BUSINESS_SOLUTION_NAME_SEGMENTS_ERR); } return Promise.resolve(true); } exports.validateBusinessSolutionName = validateBusinessSolutionName; function validateEmptySelect(select, label) { // validate select is not empty if (!select) { return Promise.resolve(adp_common_1.Messages.SELECT_CANNOT_BE_EMPTY_ERROR(label)); } return Promise.resolve(true); } exports.validateEmptySelect = validateEmptySelect; function validateForEmptyValue(value, inputName) { return value ? true : adp_common_1.Messages.ERROR_INPUT_CANNOT_BE_EMPTY(inputName); } exports.validateForEmptyValue = validateForEmptyValue; function validateAnnotationJSON(value, inputName) { if (value.length === 0) { return true; } if (isValidJSON(value)) { return true; } return adp_common_1.Messages.ERROR_INPUT_INVALID_VALUE(inputName); } exports.validateAnnotationJSON = validateAnnotationJSON; function validateFieldForEmptyValueAndUserState(value, isExternalUsage, input) { const specialCharactersValidation = validateForSpecialCharacters(value, input); if (typeof specialCharactersValidation === "string") { return specialCharactersValidation; } const customerPrefix = "customer."; if (isExternalUsage && (!value.toLocaleLowerCase().startsWith(customerPrefix) || value.length <= customerPrefix.length)) { return adp_common_1.Messages.ERROR_INPUT_INVALID_VALUE_FOR_PREFIX(input, customerPrefix); } return true; } exports.validateFieldForEmptyValueAndUserState = validateFieldForEmptyValueAndUserState; function validateExistingAnnotationFile(value, projectPath) { return __awaiter(this, void 0, void 0, function* () { if (value.length === 0) { return Promise.resolve(adp_common_1.Messages.ERROR_INPUT_CANNOT_BE_EMPTY("Annotation file")); } if (!fs.existsSync(value)) { return Promise.resolve(adp_common_1.Messages.ERROR_FILE_DOES_NOT_EXIST); } const selectedAnnotationFile = value.split(path_1.sep).pop(); const selectedAnnotationFileDirectory = value.replace(selectedAnnotationFile, ""); const projectAnnotationDirectory = `${projectPath}/webapp/changes/annotations/`; if (selectedAnnotationFileDirectory !== projectAnnotationDirectory && fs.existsSync(projectAnnotationDirectory)) { try { const existingAnnotationFiles = yield fs.promises.readdir(projectAnnotationDirectory, { withFileTypes: true }); const duplicateFilesExist = existingAnnotationFiles.some((file) => file.name === selectedAnnotationFile); if (duplicateFilesExist) { return Promise.resolve(adp_common_1.Messages.ERROR_EXISTING_ANNOTATION_FILE); } } catch (error) { throw new Error(adp_common_1.Messages.ERROR_UNABLE_TO_VALIDATE_ANNOTATION_FILE(error.message)); } } return Promise.resolve(true); }); } exports.validateExistingAnnotationFile = validateExistingAnnotationFile; function validateURI(value, input, isMandatory = true) { if (value.length === 0) { return isMandatory ? adp_common_1.Messages.ERROR_INPUT_CANNOT_BE_EMPTY(input) : true; } if (value.indexOf(" ") >= 0) { return adp_common_1.Messages.ERROR_INPUT_CANNOT_HAVE_SPACES(input); } return true; } exports.validateURI = validateURI; function validateForSpecialCharacters(value, input, specialCharactersExpression = "^[a-zA-Z0-9_$.\\-]+$", charactersDisMatchErrorMessage = adp_common_1.Messages.ERROR_INVALID_VALUE_FOR_SPECIAL_CHARACTERS(input)) { if (value.length === 0) { return adp_common_1.Messages.ERROR_INPUT_CANNOT_BE_EMPTY(input); } if (value.indexOf(" ") >= 0) { return adp_common_1.Messages.ERROR_INPUT_CANNOT_HAVE_SPACES(input); } const regex = new RegExp(specialCharactersExpression, "g"); if (!regex.test(value)) { return charactersDisMatchErrorMessage; } return true; } exports.validateForSpecialCharacters = validateForSpecialCharacters; function validateClient(client) { return new Promise((resolve) => { if (!client) { resolve(adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.SYSTEM_CLIENT_PROMPT_LABEL)); } // eslint-disable-next-line const isValid = client.match(/^([0-9])*$/); if (!isValid) { resolve(adp_common_1.Messages.SYSTEM_CLIENT_MANDATORY_ERROR); } resolve(true); }); } exports.validateClient = validateClient; function validatePropertyBinding(value, label) { if (!value) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(label); } const isInCorrectFormat = value.includes("{{") && value.includes("}}") && value.length > 4; if (!isInCorrectFormat) { return adp_common_1.Messages.ERROR_BINDING_IS_IN_INCORRECT_FORMAT; } return true; } exports.validatePropertyBinding = validatePropertyBinding; function validatePropertyBoolean(value, label) { if (!value) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(label); } const isInCorrectFormat = value.includes("false") || value.includes("true"); if (!isInCorrectFormat) { return adp_common_1.Messages.ERROR_BOOLEAN_IS_IN_INCORRECT_FORMAT; } return true; } exports.validatePropertyBoolean = validatePropertyBoolean; function validatePropertyNumber(value, label) { if (!value) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(label); } const parsedNumber = Number(value); if (isNaN(parsedNumber)) { return adp_common_1.Messages.ERROR_NUMBER_IS_IN_INCORRECT_FORMAT; } return true; } exports.validatePropertyNumber = validatePropertyNumber; function validateEnvironment(value, label, fdcService) { return __awaiter(this, void 0, void 0, function* () { if (!value) { return adp_common_1.Messages.SELECT_CANNOT_BE_EMPTY_ERROR(label); } if (value === adp_common_1.Messages.CLOUD_FOUNDRY && !adp_common_1.EnvironmentUtils.isRunningInBAS()) { const isExternalLoginEnabled = yield fdcService.isExternalLoginEnabled(); if (!isExternalLoginEnabled) { return adp_cf_1.Messages.EXTERNAL_LOGIN_DISABLED_MESSAGE; } } return true; }); } exports.validateEnvironment = validateEnvironment; function validatePropertyObject(value, label) { if (!value) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(label); } try { JSON.parse(value); } catch (e) { return adp_common_1.Messages.ERROR_OBJECT_IS_IN_INCORRECT_FORMAT; } return true; } exports.validatePropertyObject = validatePropertyObject; function validatePackage(value, repository) { if (!value) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.DEPLOY_CONFIG_PACKAGE_LABEL); } //Validation for format if (!/^(?:\/\w+\/)?[$]?\w*$/.test(value)) { return adp_common_1.Messages.INVALID_DEPLOYMENT_PACKAGE_MESSAGES.INVALID_FORMAT; } //Validation for repository namespace if (value.startsWith("/")) { const valueParts = value.split("/").filter((el) => el !== ""); const packageNamespace = valueParts[0]; if (!repository.startsWith(`/${packageNamespace}/`)) { return adp_common_1.Messages.INVALID_DEPLOYMENT_PACKAGE_MESSAGES.INVALID_REPOSITORY_NAMESPACE; } return undefined; } //Validation for prefix const startPrefix = value.startsWith("SAP") ? "SAP" : value[0]; const allowedPrefixes = ["$", "Z", "Y", "SAP"]; if (!allowedPrefixes.find((el) => el === startPrefix)) { return adp_common_1.Messages.INVALID_DEPLOYMENT_PACKAGE_MESSAGES.INVALID_STARTING_PREFIX; } //Validation for repository prefix if (repository && !value.startsWith("$") && !repository.startsWith(startPrefix)) { return adp_common_1.Messages.INVALID_DEPLOYMENT_PACKAGE_MESSAGES.INVALID_REPOSITORY_NAMESPACE; } return undefined; } exports.validatePackage = validatePackage; function validateSAPUI5Repository(value) { if (!value) { return adp_common_1.Messages.INPUT_CANNOT_BE_EMPTY_ERROR(adp_common_1.Messages.SAPUI5_ABAP_REPOSITORY_LABEL); } if (!/^(?:[/]\w{1,8}[/])?\w{1,15}$/.test(value)) { return adp_common_1.Messages.INVALID_SAPUI5_ABAP_REPOSITORY_MESSAGE; } return true; } exports.validateSAPUI5Repository = validateSAPUI5Repository; function validateDuplicateName(fieldValue, comparativeValue, field1Name, field2Name) { if (fieldValue === comparativeValue) { return adp_common_1.Messages.DUPLICATE_NAME_VALIDATION_ERROR(field1Name, field2Name); } return true; } exports.validateDuplicateName = validateDuplicateName; function validatePackageChoiceInput(value, abapService) { var _a; return __awaiter(this, void 0, void 0, function* () { try { if (!value) { return adp_common_1.Messages.ERROR_EMPTY_PACKAGE_INPUT_CHOICE; } if (value === adp_common_1.InputChoice.CHOOSE_FROM_EXISTING) { const packages = yield abapService.listPackages(""); if (!packages || (packages && packages.length === 0)) { return adp_common_1.Messages.ERROR_PROMPT_ABAP_PACKAGE_NOT_FOUND; } } return true; } catch (error) { (_a = adp_common_1.Logger === null || adp_common_1.Logger === void 0 ? void 0 : adp_common_1.Logger.getLogger) === null || _a === void 0 ? void 0 : _a.error(`Cannot fetch package list! Error: ${error.message}`); return adp_common_1.Messages.ERROR_PROMPT_ABAP_PACKAGE_NOT_FOUND; } }); } exports.validatePackageChoiceInput = validatePackageChoiceInput; function validateTransportChoiceInput(value, packageName, repository, abapService) { var _a; return __awaiter(this, void 0, void 0, function* () { try { if (!value) { return adp_common_1.Messages.ERROR_EMPTY_TRANSPORT_INPUT_CHOICE; } if (value === adp_common_1.InputChoice.CHOOSE_FROM_EXISTING) { if (!packageName || !repository) { return adp_common_1.Messages.ERROR_TRANSPORT_LIST_MISSING_PRE_REQS; } const transportList = yield abapService.listTransports(packageName, repository); if (!transportList || (transportList && transportList.length === 0)) { return adp_common_1.Messages.ERROR_TRANSPORT_NO_EXISTING_LIST; } } return true; } catch (error) { (_a = adp_common_1.Logger === null || adp_common_1.Logger === void 0 ? void 0 : adp_common_1.Logger.getLogger) === null || _a === void 0 ? void 0 : _a.error(`Cannot fetch transport list! Error: ${error.message}`); return adp_common_1.Messages.ERROR_TRANSPORT_NO_EXISTING_LIST; } }); } exports.validateTransportChoiceInput = validateTransportChoiceInput; function validatePackageExtended(value, abapService, answers) { return __awaiter(this, void 0, void 0, function* () { const errorMessage = validatePackage(value, answers.sapui5ABAPRepository); if (errorMessage) { return errorMessage; } if (value && answers.sapui5ABAPRepository) { yield (0, transport_list_1.fetchTransportList)(abapService, value, answers.sapui5ABAPRepository); } return validateCloudPackage(value, abapService); }); } exports.validatePackageExtended = validatePackageExtended; function validateCloudPackage(packageName, abapService) { return __awaiter(this, void 0, void 0, function* () { try { const systemInfo = yield abapService.getSystemInfo(undefined, packageName); //When passing package to the API for getting system info the response contains the type of the package (cloud or onPremise) //If the package is cloud in adaptationProjectTypes we will have array with only one element 'cloudReady', if it is 'onPremise' the element in the array will be 'onPremise' if (systemInfo.adaptationProjectTypes[0] !== axios_extension_1.AdaptationProjectType.CLOUD_READY) { return adp_common_1.Messages.INVALID_DEPLOYMENT_PACKAGE_MESSAGES.INVALID_CLOUD_PACKAGE; } return true; } catch (error) { //If there is no such package the API will response with 400 or 404 status codes if (error.response && (error.response.status === 400 || error.response.status === 404)) { return adp_common_1.Messages.INVALID_DEPLOYMENT_PACKAGE_MESSAGES.INVALID_CLOUD_PACKAGE; } //In case of different response status code than 400 or 404 we are showing the error message return error.message; } }); } exports.validateCloudPackage = validateCloudPackage; function validateDuplicateProjectName(value, destinationPath) { if (fs.existsSync(destinationPath + "/" + value)) { return adp_common_1.Messages.DUPLICATE_PROJECT_NAME_VALIDATION_ERROR; } return true; } function isValidJSON(value) { try { JSON.parse(`{${value}}`); return true; } catch (e) { return false; } } //# sourceMappingURL=validator.js.map