@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
JavaScript
"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