@sap-ux/project-input-validator 0.7.2 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasContentDuplication = hasContentDuplication;
4
- exports.hasCustomerPrefix = hasCustomerPrefix;
5
- exports.isDataSourceURI = isDataSourceURI;
6
- exports.validateProjectName = validateProjectName;
7
- exports.validateProjectNameExternal = validateProjectNameExternal;
8
- exports.validateProjectNameInternal = validateProjectNameInternal;
9
- exports.validateDuplicateProjectName = validateDuplicateProjectName;
10
- exports.validateNamespaceAdp = validateNamespaceAdp;
11
- exports.validateAch = validateAch;
12
- const node_path_1 = require("node:path");
13
- const node_fs_1 = require("node:fs");
14
- const i18n_1 = require("../i18n");
15
- const validators_1 = require("../general/validators");
1
+ import { join } from 'node:path';
2
+ import { existsSync } from 'node:fs';
3
+ import { t } from '../i18n.js';
4
+ import { validateEmptyString } from '../general/validators.js';
16
5
  /**
17
6
  * Validates a value for duplication in existing change files.
18
7
  *
@@ -21,7 +10,7 @@ const validators_1 = require("../general/validators");
21
10
  * @param changeFiles The list of existing change files to check against.
22
11
  * @returns {boolean} Returns true if a content duplication is found and false if there is no content duplication.
23
12
  */
24
- function hasContentDuplication(value, propertyName, changeFiles) {
13
+ export function hasContentDuplication(value, propertyName, changeFiles) {
25
14
  return changeFiles.some(({ content }) => {
26
15
  const contentProperty = content[propertyName];
27
16
  return contentProperty && Object.keys(contentProperty).includes(value);
@@ -33,7 +22,7 @@ function hasContentDuplication(value, propertyName, changeFiles) {
33
22
  * @param value The value to validate.
34
23
  * @returns {boolean} True if the value starts with 'customer.' and false if it does not.
35
24
  */
36
- function hasCustomerPrefix(value) {
25
+ export function hasCustomerPrefix(value) {
37
26
  return value.toLowerCase().startsWith('customer.');
38
27
  }
39
28
  /**
@@ -42,7 +31,7 @@ function hasCustomerPrefix(value) {
42
31
  * @param uri The URI to validate.
43
32
  * @returns {boolean} True if the URI is valid, false if it is not.
44
33
  */
45
- function isDataSourceURI(uri) {
34
+ export function isDataSourceURI(uri) {
46
35
  return /^(?!.*\/\/)\/([^\s]*)\/$/.test(uri);
47
36
  }
48
37
  /**
@@ -54,13 +43,13 @@ function isDataSourceURI(uri) {
54
43
  * @param {boolean} isCfEnv - Whether the project is in a CF environment.
55
44
  * @returns {string | boolean} If value is valid returns true otherwise error message.
56
45
  */
57
- function validateProjectName(value, destinationPath, isCustomerBase, isCfEnv) {
58
- const validationResult = (0, validators_1.validateEmptyString)(value);
46
+ export function validateProjectName(value, destinationPath, isCustomerBase, isCfEnv) {
47
+ const validationResult = validateEmptyString(value);
59
48
  if (typeof validationResult === 'string') {
60
49
  return validationResult;
61
50
  }
62
51
  if (/[A-Z]/.test(value)) {
63
- return (0, i18n_1.t)('adp.projectNameUppercaseError');
52
+ return t('adp.projectNameUppercaseError');
64
53
  }
65
54
  const nameResult = isCustomerBase ? validateProjectNameExternal(value) : validateProjectNameInternal(value);
66
55
  if (typeof nameResult === 'string') {
@@ -77,12 +66,12 @@ function validateProjectName(value, destinationPath, isCustomerBase, isCfEnv) {
77
66
  * @param {string} value - The project name.
78
67
  * @returns {string | boolean} If value is valid returns true otherwise error message.
79
68
  */
80
- function validateProjectNameExternal(value) {
69
+ export function validateProjectNameExternal(value) {
81
70
  if (value.length > 61 || value.toLocaleLowerCase().endsWith('component')) {
82
- return (0, i18n_1.t)('adp.projectNameLengthErrorExt');
71
+ return t('adp.projectNameLengthErrorExt');
83
72
  }
84
73
  if (!/^[a-z][a-z0-9]*(\.[a-z][a-z0-9]*)*$/.test(value)) {
85
- return (0, i18n_1.t)('adp.projectNameValidationErrorExt');
74
+ return t('adp.projectNameValidationErrorExt');
86
75
  }
87
76
  return true;
88
77
  }
@@ -92,14 +81,14 @@ function validateProjectNameExternal(value) {
92
81
  * @param {string} value - The project name.
93
82
  * @returns {string | boolean} If value is valid returns true otherwise error message.
94
83
  */
95
- function validateProjectNameInternal(value) {
84
+ export function validateProjectNameInternal(value) {
96
85
  if (value.toLowerCase().startsWith('customer') ||
97
86
  value.length > 61 ||
98
87
  value.toLocaleLowerCase().endsWith('component')) {
99
- return (0, i18n_1.t)('adp.projectNameLengthErrorInt');
88
+ return t('adp.projectNameLengthErrorInt');
100
89
  }
101
90
  if (!/^[a-z]+[a-z0-9]*(\.[a-z]+[a-z0-9]*)+$/i.test(value)) {
102
- return (0, i18n_1.t)('adp.projectNameValidationErrorInt');
91
+ return t('adp.projectNameValidationErrorInt');
103
92
  }
104
93
  return true;
105
94
  }
@@ -110,9 +99,9 @@ function validateProjectNameInternal(value) {
110
99
  * @param {string} destinationPath - The project directory.
111
100
  * @returns {string | boolean} If project with same name already exists return error message otherwise true.
112
101
  */
113
- function validateDuplicateProjectName(value, destinationPath) {
114
- if ((0, node_fs_1.existsSync)((0, node_path_1.join)(destinationPath, value))) {
115
- return (0, i18n_1.t)('adp.duplicatedProjectName');
102
+ export function validateDuplicateProjectName(value, destinationPath) {
103
+ if (existsSync(join(destinationPath, value))) {
104
+ return t('adp.duplicatedProjectName');
116
105
  }
117
106
  return true;
118
107
  }
@@ -124,27 +113,27 @@ function validateDuplicateProjectName(value, destinationPath) {
124
113
  * @param {boolean} isCustomerBase - Whether the layer is customer base.
125
114
  * @returns {string | boolean} If project namespace is valid returns true otherwise error message.
126
115
  */
127
- function validateNamespaceAdp(namespace, projectName, isCustomerBase) {
128
- const validationResult = (0, validators_1.validateEmptyString)(namespace);
116
+ export function validateNamespaceAdp(namespace, projectName, isCustomerBase) {
117
+ const validationResult = validateEmptyString(namespace);
129
118
  if (typeof validationResult === 'string') {
130
119
  return validationResult;
131
120
  }
132
121
  if (!isCustomerBase) {
133
122
  if (namespace !== projectName) {
134
- return (0, i18n_1.t)('adp.differentNamespaceThanProjectName');
123
+ return t('adp.differentNamespaceThanProjectName');
135
124
  }
136
125
  }
137
126
  else if (namespace.toLowerCase().startsWith('customer.') !== true) {
138
- return (0, i18n_1.t)('adp.namespaceSameAsProjectNameError');
127
+ return t('adp.namespaceSameAsProjectNameError');
139
128
  }
140
129
  else {
141
130
  namespace = namespace.slice('customer.'.length, namespace.length);
142
131
  }
143
132
  if (namespace.length > 61 || namespace.toLowerCase().endsWith('component') === true) {
144
- return (0, i18n_1.t)('adp.namespaceLengthError');
133
+ return t('adp.namespaceLengthError');
145
134
  }
146
135
  else if (namespace !== '' && /^[a-z]+((\.)?[a-z0-9])*$/.test(namespace) === false) {
147
- return (0, i18n_1.t)('adp.namespaceValidationError');
136
+ return t('adp.namespaceValidationError');
148
137
  }
149
138
  return true;
150
139
  }
@@ -155,14 +144,14 @@ function validateNamespaceAdp(namespace, projectName, isCustomerBase) {
155
144
  * @param {boolean} isCustomerBase - Whether the layer is customer base.
156
145
  * @returns {string | boolean} If application ACH is valid returns true otherwise error message.
157
146
  */
158
- function validateAch(value, isCustomerBase) {
159
- const validationResult = (0, validators_1.validateEmptyString)(value);
147
+ export function validateAch(value, isCustomerBase) {
148
+ const validationResult = validateEmptyString(value);
160
149
  if (typeof validationResult === 'string') {
161
150
  return validationResult;
162
151
  }
163
152
  const isValid = /^([A-Z0-9]{2,3})(-[A-Z0-9]{1,6})*$/.exec(value.toUpperCase());
164
153
  if (!isCustomerBase && !isValid) {
165
- return (0, i18n_1.t)('adp.achMandatoryError');
154
+ return t('adp.achMandatoryError');
166
155
  }
167
156
  return true;
168
157
  }
@@ -1,11 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateAppName = validateAppName;
4
- exports.validateAppDescription = validateAppDescription;
5
- exports.validateTransportRequestNumber = validateTransportRequestNumber;
6
- exports.validatePackage = validatePackage;
7
- const i18n_1 = require("../i18n");
8
- const node_os_1 = require("node:os");
1
+ import { t } from '../i18n.js';
2
+ import { EOL } from 'node:os';
9
3
  /**
10
4
  * Validator Fiori app name is compatble with Fiori project requirements.
11
5
  *
@@ -13,24 +7,24 @@ const node_os_1 = require("node:os");
13
7
  * @param prefix Prefix required by backend system
14
8
  * @returns True or error message
15
9
  */
16
- function validateAppName(name, prefix) {
10
+ export function validateAppName(name, prefix) {
17
11
  const errorMessages = [];
18
12
  const length = name ? name.trim().length : 0;
19
13
  if (!length) {
20
- return (0, i18n_1.t)('deploy.abapAppNameRequired');
14
+ return t('deploy.abapAppNameRequired');
21
15
  }
22
16
  if (name.split('/').length > 3) {
23
- errorMessages.push((0, i18n_1.t)('deploy.abapInvalidNamespace'));
17
+ errorMessages.push(t('deploy.abapInvalidNamespace'));
24
18
  }
25
19
  else if (/^\/.*\/\w*$/g.test(name)) {
26
20
  const splitNames = name.split('/');
27
21
  let accumulatedMsg = '';
28
22
  if (splitNames[1].length > 10) {
29
- const errMsg = (0, i18n_1.t)('deploy.abapInvalidNamespaceLength', { length: splitNames[1].length });
23
+ const errMsg = t('deploy.abapInvalidNamespaceLength', { length: splitNames[1].length });
30
24
  accumulatedMsg += `${errMsg}, `;
31
25
  }
32
26
  if (splitNames[2].length > 15) {
33
- const errMsg = (0, i18n_1.t)('deploy.abapInvalidAppNameLength', { length: splitNames[2].length });
27
+ const errMsg = t('deploy.abapInvalidAppNameLength', { length: splitNames[2].length });
34
28
  accumulatedMsg += `${errMsg}, `;
35
29
  }
36
30
  if (accumulatedMsg) {
@@ -39,13 +33,13 @@ function validateAppName(name, prefix) {
39
33
  }
40
34
  }
41
35
  else if (length > 15) {
42
- errorMessages.push((0, i18n_1.t)('deploy.abapInvalidAppNameLength', { length }));
36
+ errorMessages.push(t('deploy.abapInvalidAppNameLength', { length }));
43
37
  }
44
38
  if (prefix && !name.toUpperCase().startsWith(prefix.toUpperCase())) {
45
- errorMessages.push((0, i18n_1.t)('deploy.abapInvalidAppName', { prefix }));
39
+ errorMessages.push(t('deploy.abapInvalidAppName', { prefix }));
46
40
  }
47
41
  if (!/^[A-Za-z0-9_/]*$/.test(name)) {
48
- errorMessages.push((0, i18n_1.t)('deploy.charactersForbiddenInAppName'));
42
+ errorMessages.push(t('deploy.charactersForbiddenInAppName'));
49
43
  }
50
44
  return processErrorMessages(errorMessages);
51
45
  }
@@ -63,8 +57,8 @@ function processErrorMessages(errorMessages) {
63
57
  return errorMessages[0];
64
58
  }
65
59
  else {
66
- const indentErrorMessageRows = errorMessages.map((errorMessage) => `${' '.repeat(8)}${errorMessage}`).join(node_os_1.EOL);
67
- return `${(0, i18n_1.t)('deploy.invalidAppNameMultipleReason')}${node_os_1.EOL}${indentErrorMessageRows}${node_os_1.EOL}`;
60
+ const indentErrorMessageRows = errorMessages.map((errorMessage) => `${' '.repeat(8)}${errorMessage}`).join(EOL);
61
+ return `${t('deploy.invalidAppNameMultipleReason')}${EOL}${indentErrorMessageRows}${EOL}`;
68
62
  }
69
63
  }
70
64
  /**
@@ -73,9 +67,9 @@ function processErrorMessages(errorMessages) {
73
67
  * @param description Fiori app description
74
68
  * @returns true or error message
75
69
  */
76
- function validateAppDescription(description) {
70
+ export function validateAppDescription(description) {
77
71
  if (description.length > 60) {
78
- return (0, i18n_1.t)('deploy.abapAppDescLength');
72
+ return t('deploy.abapAppDescLength');
79
73
  }
80
74
  else {
81
75
  return true;
@@ -88,10 +82,10 @@ function validateAppDescription(description) {
88
82
  * @param packageName Package name
89
83
  * @returns true or error message
90
84
  */
91
- function validateTransportRequestNumber(transportRequest, packageName) {
85
+ export function validateTransportRequestNumber(transportRequest, packageName) {
92
86
  const regex = /^[$LlTt]/;
93
87
  if (!regex.test(packageName) && !transportRequest?.trim()) {
94
- return (0, i18n_1.t)('deploy.abapTransportNumRequired');
88
+ return t('deploy.abapTransportNumRequired');
95
89
  }
96
90
  else {
97
91
  return true;
@@ -103,9 +97,9 @@ function validateTransportRequestNumber(transportRequest, packageName) {
103
97
  * @param input Package name
104
98
  * @returns true or error message
105
99
  */
106
- function validatePackage(input) {
100
+ export function validatePackage(input) {
107
101
  if (!input?.trim()) {
108
- return (0, i18n_1.t)('deploy.abapPackageWarn');
102
+ return t('deploy.abapPackageWarn');
109
103
  }
110
104
  else {
111
105
  return true;
@@ -1,4 +1,4 @@
1
- import type { AllowedCharacters } from '../general/validators';
1
+ import type { AllowedCharacters } from '../general/validators.js';
2
2
  /**
3
3
  * Validates that text input does not have zero length and optionally is less than the specified maximum length.
4
4
  * Returns an end user message if validation fails.
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateText = validateText;
4
- const i18n_1 = require("../i18n");
5
- const validators_1 = require("../general/validators");
1
+ import { t } from '../i18n.js';
2
+ import { validateAllowedCharacters, validateMaxLength } from '../general/validators.js';
6
3
  /**
7
4
  * Validates that text input does not have zero length and optionally is less than the specified maximum length.
8
5
  * Returns an end user message if validation fails.
@@ -13,20 +10,20 @@ const validators_1 = require("../general/validators");
13
10
  * @param allowedCharacters optional, define a list of special characters that should be allowed in the input field
14
11
  * @returns true, if all validation checks pass or a message explaining the validation failure
15
12
  */
16
- function validateText(input, isCLI, maxLength = 0, allowedCharacters) {
13
+ export function validateText(input, isCLI, maxLength = 0, allowedCharacters) {
17
14
  const trimmedInput = input ? input.trim() : '';
18
15
  const length = trimmedInput.length;
19
16
  if (!length) {
20
17
  if (isCLI) {
21
- return (0, i18n_1.t)('general.inputCannotBeEmpty');
18
+ return t('general.inputCannotBeEmpty');
22
19
  }
23
20
  return false;
24
21
  }
25
- const maxLengthValidation = (0, validators_1.validateMaxLength)(input, maxLength);
22
+ const maxLengthValidation = validateMaxLength(input, maxLength);
26
23
  if (typeof maxLengthValidation === 'string') {
27
24
  return maxLengthValidation;
28
25
  }
29
- const allowedCharsValidation = (0, validators_1.validateAllowedCharacters)(input, allowedCharacters);
26
+ const allowedCharsValidation = validateAllowedCharacters(input, allowedCharacters);
30
27
  if (typeof allowedCharsValidation === 'string') {
31
28
  return allowedCharsValidation;
32
29
  }
@@ -1,27 +1,23 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateFioriAppProjectFolder = validateFioriAppProjectFolder;
4
- exports.validateFioriAppTargetFolder = validateFioriAppTargetFolder;
5
- const project_access_1 = require("@sap-ux/project-access");
6
- const node_path_1 = require("node:path");
7
- const i18n_1 = require("../i18n");
8
- const validators_1 = require("../ui5/validators");
9
- const validators_2 = require("./validators");
1
+ import { findCapProjectRoot, findRootsForPath, getCapProjectType } from '@sap-ux/project-access';
2
+ import { join } from 'node:path';
3
+ import { t } from '../i18n.js';
4
+ import { validateProjectFolder } from '../ui5/validators.js';
5
+ import { validateWindowsPathLength } from './validators.js';
10
6
  /**
11
7
  * Returns true if the specified target path does not contain an SAP Fiori project.
12
8
  *
13
9
  * @param targetDir the target directory path.
14
10
  * @returns true, if not Fiori Project, or string message indicating that the path contains an SAP Fiori project.
15
11
  */
16
- async function validateFioriAppProjectFolder(targetDir) {
12
+ export async function validateFioriAppProjectFolder(targetDir) {
17
13
  // Check if the target directory contains a CAP project
18
- if (!!(await (0, project_access_1.findCapProjectRoot)(targetDir, false)) || !!(await (0, project_access_1.getCapProjectType)(targetDir))) {
19
- return (0, i18n_1.t)('ui5.folderContainsCapApp');
14
+ if (!!(await findCapProjectRoot(targetDir, false)) || !!(await getCapProjectType(targetDir))) {
15
+ return t('ui5.folderContainsCapApp');
20
16
  }
21
17
  // Check if the target directory contains an SAP Fiori project
22
- const appRoot = await (0, project_access_1.findRootsForPath)(targetDir);
18
+ const appRoot = await findRootsForPath(targetDir);
23
19
  if (appRoot) {
24
- return (0, i18n_1.t)('ui5.folderContainsFioriApp', { path: appRoot.appRoot });
20
+ return t('ui5.folderContainsFioriApp', { path: appRoot.appRoot });
25
21
  }
26
22
  else {
27
23
  return true;
@@ -51,19 +47,19 @@ async function validateFioriAppProjectFolder(targetDir) {
51
47
  * @param validateFioriAppFolder - If true, validates the target path as an SAP Fiori App project folder.
52
48
  * @returns A boolean value `true` if all validations pass; otherwise, an error message.
53
49
  */
54
- async function validateFioriAppTargetFolder(targetPath, appName, validateFioriAppFolder) {
50
+ export async function validateFioriAppTargetFolder(targetPath, appName, validateFioriAppFolder) {
55
51
  if (validateFioriAppFolder === true) {
56
52
  const isFioriValid = await validateFioriAppProjectFolder(targetPath);
57
53
  if (isFioriValid !== true) {
58
54
  return isFioriValid;
59
55
  }
60
56
  }
61
- const isProjectValid = (0, validators_1.validateProjectFolder)(targetPath, appName);
57
+ const isProjectValid = validateProjectFolder(targetPath, appName);
62
58
  if (isProjectValid !== true) {
63
59
  return isProjectValid;
64
60
  }
65
61
  // Windows path length validation
66
- const winPathResult = (0, validators_2.validateWindowsPathLength)((0, node_path_1.join)(targetPath, appName), (0, i18n_1.t)(`general.windowsFolderPathTooLong`));
62
+ const winPathResult = validateWindowsPathLength(join(targetPath, appName), t(`general.windowsFolderPathTooLong`));
67
63
  if (winPathResult !== true) {
68
64
  return winPathResult;
69
65
  }
@@ -1,29 +1,18 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateClient = validateClient;
4
- exports.validateUrl = validateUrl;
5
- exports.validateEmptyString = validateEmptyString;
6
- exports.validateEmptySpaces = validateEmptySpaces;
7
- exports.validateMaxLength = validateMaxLength;
8
- exports.validateAllowedCharacters = validateAllowedCharacters;
9
- exports.validateJSON = validateJSON;
10
- exports.validateSpecialChars = validateSpecialChars;
11
- exports.validateWindowsPathLength = validateWindowsPathLength;
12
- const i18n_1 = require("../i18n");
1
+ import { t } from '../i18n.js';
13
2
  /**
14
3
  * SAP client number is either empty or 3 digit string.
15
4
  *
16
5
  * @param client ABAP system client number
17
6
  * @returns true or error message
18
7
  */
19
- function validateClient(client) {
8
+ export function validateClient(client) {
20
9
  const formattedInput = client?.trim() || '';
21
10
  const isValid = formattedInput === '' || /^\d{3}$/.test(formattedInput);
22
11
  if (isValid) {
23
12
  return true;
24
13
  }
25
14
  else {
26
- return (0, i18n_1.t)('general.invalidClient', { client });
15
+ return t('general.invalidClient', { client });
27
16
  }
28
17
  }
29
18
  /**
@@ -32,13 +21,13 @@ function validateClient(client) {
32
21
  * @param input Backend ABAP system url
33
22
  * @returns true or error message
34
23
  */
35
- function validateUrl(input) {
24
+ export function validateUrl(input) {
36
25
  try {
37
26
  const url = new URL(input);
38
27
  return !!url.protocol && !!url.host;
39
28
  }
40
29
  catch {
41
- return (0, i18n_1.t)('general.invalidUrl', { input });
30
+ return t('general.invalidUrl', { input });
42
31
  }
43
32
  }
44
33
  /**
@@ -47,12 +36,12 @@ function validateUrl(input) {
47
36
  * @param input input string to be validated
48
37
  * @returns true or error message
49
38
  */
50
- function validateEmptyString(input) {
39
+ export function validateEmptyString(input) {
51
40
  const formattedInput = input?.trim() || '';
52
41
  if (formattedInput.trim().length > 0) {
53
42
  return true;
54
43
  }
55
- return (0, i18n_1.t)('general.inputCannotBeEmpty');
44
+ return t('general.inputCannotBeEmpty');
56
45
  }
57
46
  /**
58
47
  * Validate input does not contain any whitespace characters.
@@ -60,9 +49,9 @@ function validateEmptyString(input) {
60
49
  * @param value The string to check for whitespace characters.
61
50
  * @returns true or error message
62
51
  */
63
- function validateEmptySpaces(value) {
52
+ export function validateEmptySpaces(value) {
64
53
  if (/\s/.test(value)) {
65
- return (0, i18n_1.t)('general.inputCannotHaveSpaces');
54
+ return t('general.inputCannotHaveSpaces');
66
55
  }
67
56
  return true;
68
57
  }
@@ -73,9 +62,9 @@ function validateEmptySpaces(value) {
73
62
  * @param {number} [maxLength] - The maximum allowed length of the string. If 0 or not provided, no length validation is performed.
74
63
  * @returns {boolean | string} Returns `true` if the validation passes, or an error message string if it fails.
75
64
  */
76
- function validateMaxLength(value, maxLength = 0) {
65
+ export function validateMaxLength(value, maxLength = 0) {
77
66
  if (maxLength > 0 && value.length > maxLength) {
78
- return (0, i18n_1.t)('general.maxLength', { maxLength });
67
+ return t('general.maxLength', { maxLength });
79
68
  }
80
69
  return true;
81
70
  }
@@ -86,13 +75,13 @@ function validateMaxLength(value, maxLength = 0) {
86
75
  * @param {string[]} allowedCharacters - An array of allowed special characters.
87
76
  * @returns {boolean | string} Returns `true` if validation passes, or an error message string if validation fails.
88
77
  */
89
- function validateAllowedCharacters(value, allowedCharacters) {
78
+ export function validateAllowedCharacters(value, allowedCharacters) {
90
79
  // Asterisks is supported for the semantic object and action field but not the inbound title
91
80
  if (allowedCharacters && allowedCharacters.length > 0) {
92
81
  const escapedChars = allowedCharacters.map((char) => `\\${char}`).join('');
93
82
  const regex = new RegExp(`^[a-zA-Z0-9${escapedChars}]+$`);
94
83
  if (!regex.test(value)) {
95
- return (0, i18n_1.t)('general.supportedFormats', {
84
+ return t('general.supportedFormats', {
96
85
  allowedCharacters: allowedCharacters.join('')
97
86
  });
98
87
  }
@@ -105,13 +94,13 @@ function validateAllowedCharacters(value, allowedCharacters) {
105
94
  * @param value The string to test.
106
95
  * @returns true or error message
107
96
  */
108
- function validateJSON(value) {
97
+ export function validateJSON(value) {
109
98
  try {
110
99
  JSON.parse(`{${value}}`);
111
100
  return true;
112
101
  }
113
102
  catch {
114
- return (0, i18n_1.t)('general.invalidJSON');
103
+ return t('general.invalidJSON');
115
104
  }
116
105
  }
117
106
  /**
@@ -121,12 +110,12 @@ function validateJSON(value) {
121
110
  * @param regexp The regex expression for allowed special characters.
122
111
  * @returns {boolean} True if validation passes, or an error message if validation fails.
123
112
  */
124
- function validateSpecialChars(value, regexp = '^[a-zA-Z0-9_$.\\-]+$') {
113
+ export function validateSpecialChars(value, regexp = '^[a-zA-Z0-9_$.\\-]+$') {
125
114
  const regex = new RegExp(regexp, 'g');
126
115
  if (regex.test(value)) {
127
116
  return true;
128
117
  }
129
- return (0, i18n_1.t)('general.invalidValueForSpecialChars');
118
+ return t('general.invalidValueForSpecialChars');
130
119
  }
131
120
  /**
132
121
  * Checks if the combined Windows path length exceeds the default limit (256 characters).
@@ -135,7 +124,7 @@ function validateSpecialChars(value, regexp = '^[a-zA-Z0-9_$.\\-]+$') {
135
124
  * @param errorMessage The error message to be returned if the path is too long. Use `{length}` as a placeholder for the actual length.
136
125
  * @returns true if valid, or the error message if too long
137
126
  */
138
- function validateWindowsPathLength(basePath, errorMessage) {
127
+ export function validateWindowsPathLength(basePath, errorMessage) {
139
128
  if (process.platform === 'win32') {
140
129
  const combinedLength = `${basePath}`.length;
141
130
  if (combinedLength >= 256) {
package/dist/i18n.js CHANGED
@@ -1,28 +1,19 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.i18n = exports.PROJECT_INPUT_VALIDATOR_NS = void 0;
7
- exports.addi18nResourceBundle = addi18nResourceBundle;
8
- exports.initI18nProjectValidators = initI18nProjectValidators;
9
- exports.t = t;
10
- const i18next_1 = __importDefault(require("i18next"));
11
- const project_input_validator_i18n_json_1 = __importDefault(require("./translations/project-input-validator.i18n.json"));
12
- exports.PROJECT_INPUT_VALIDATOR_NS = 'project-input-validator';
13
- exports.i18n = i18next_1.default.createInstance();
1
+ import i18next from 'i18next';
2
+ import translations from './translations/project-input-validator.i18n.json' with { type: 'json' };
3
+ export const PROJECT_INPUT_VALIDATOR_NS = 'project-input-validator';
4
+ export const i18n = i18next.createInstance();
14
5
  /**
15
6
  * Adds the `project-input-validator` resource bundle to i18next.
16
7
  * May be required to load i18n translations after initialising in the consumer module.
17
8
  */
18
- function addi18nResourceBundle() {
19
- exports.i18n.addResourceBundle('en', exports.PROJECT_INPUT_VALIDATOR_NS, project_input_validator_i18n_json_1.default);
9
+ export function addi18nResourceBundle() {
10
+ i18n.addResourceBundle('en', PROJECT_INPUT_VALIDATOR_NS, translations);
20
11
  }
21
12
  /**
22
13
  * Initialize i18next with the translations for this module.
23
14
  */
24
- async function initI18nProjectValidators() {
25
- await exports.i18n.init({
15
+ export async function initI18nProjectValidators() {
16
+ await i18n.init({
26
17
  lng: 'en',
27
18
  fallbackLng: 'en',
28
19
  showSupportNotice: false
@@ -36,11 +27,11 @@ async function initI18nProjectValidators() {
36
27
  * @param options additional options
37
28
  * @returns {string} localized string stored for the given key
38
29
  */
39
- function t(key, options) {
30
+ export function t(key, options) {
40
31
  if (!options?.ns) {
41
- options = Object.assign(options ?? {}, { ns: exports.PROJECT_INPUT_VALIDATOR_NS });
32
+ options = Object.assign(options ?? {}, { ns: PROJECT_INPUT_VALIDATOR_NS });
42
33
  }
43
- return exports.i18n.t(key, options);
34
+ return i18n.t(key, options);
44
35
  }
45
36
  initI18nProjectValidators().catch(() => {
46
37
  // needed by lint
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export * from './deploy/validators';
2
- export * from './ui5/validators';
3
- export * from './general/project-path-validators';
4
- export * from './general/validators';
5
- export * from './adp/validators';
6
- export * from './flp/validators';
7
- export { addi18nResourceBundle } from './i18n';
1
+ export * from './deploy/validators.js';
2
+ export * from './ui5/validators.js';
3
+ export * from './general/project-path-validators.js';
4
+ export * from './general/validators.js';
5
+ export * from './adp/validators.js';
6
+ export * from './flp/validators.js';
7
+ export { addi18nResourceBundle, initI18nProjectValidators } from './i18n.js';
8
8
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,26 +1,8 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.addi18nResourceBundle = void 0;
18
- __exportStar(require("./deploy/validators"), exports);
19
- __exportStar(require("./ui5/validators"), exports);
20
- __exportStar(require("./general/project-path-validators"), exports);
21
- __exportStar(require("./general/validators"), exports);
22
- __exportStar(require("./adp/validators"), exports);
23
- __exportStar(require("./flp/validators"), exports);
24
- var i18n_1 = require("./i18n");
25
- Object.defineProperty(exports, "addi18nResourceBundle", { enumerable: true, get: function () { return i18n_1.addi18nResourceBundle; } });
1
+ export * from './deploy/validators.js';
2
+ export * from './ui5/validators.js';
3
+ export * from './general/project-path-validators.js';
4
+ export * from './general/validators.js';
5
+ export * from './adp/validators.js';
6
+ export * from './flp/validators.js';
7
+ export { addi18nResourceBundle, initI18nProjectValidators } from './i18n.js';
26
8
  //# sourceMappingURL=index.js.map
@@ -1,16 +1,7 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.validateNamespace = validateNamespace;
7
- exports.validateLibModuleName = validateLibModuleName;
8
- exports.validateProjectFolder = validateProjectFolder;
9
- exports.validateModuleName = validateModuleName;
10
- const node_path_1 = require("node:path");
11
- const i18n_1 = require("../i18n");
12
- const node_fs_1 = require("node:fs");
13
- const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name"));
1
+ import { join, posix } from 'node:path';
2
+ import { t } from '../i18n.js';
3
+ import { existsSync, lstatSync, accessSync, constants } from 'node:fs';
4
+ import validateNpmPackageName from 'validate-npm-package-name';
14
5
  /**
15
6
  * Validator: UI5 application namespace.
16
7
  *
@@ -23,31 +14,31 @@ function validateNamespacePattern(namespace, moduleName = '', allowUnderscore =
23
14
  // Since namespace is concatenated with name to write the app id to the yamls we must comply with the yaml specVersion validation
24
15
  // https://sap.github.io/ui5-tooling/stable/pages/Configuration/#name
25
16
  if (!/^[a-zA-Z]/.test(namespace)) {
26
- return (0, i18n_1.t)('ui5.namespaceMustStartWithLetter');
17
+ return t('ui5.namespaceMustStartWithLetter');
27
18
  }
28
19
  if (namespace.endsWith('.')) {
29
- return (0, i18n_1.t)('ui5.namespaceEndInPeriod');
20
+ return t('ui5.namespaceEndInPeriod');
30
21
  }
31
22
  if (namespace.toUpperCase() === 'SAP') {
32
- return (0, i18n_1.t)('ui5.namespaceCannotBeSap', { str: namespace });
23
+ return t('ui5.namespaceCannotBeSap', { str: namespace });
33
24
  }
34
25
  if (namespace.toLowerCase().startsWith('new')) {
35
- return (0, i18n_1.t)('ui5.namespaceStartsWithNew', { str: namespace.substring(0, 3) });
26
+ return t('ui5.namespaceStartsWithNew', { str: namespace.substring(0, 3) });
36
27
  }
37
28
  if (/\.\d/.test(namespace)) {
38
- return (0, i18n_1.t)('ui5.namespaceNumberAfterPeriod');
29
+ return t('ui5.namespaceNumberAfterPeriod');
39
30
  }
40
31
  if (allowUnderscore && !/^[\w.]+$/.test(namespace)) {
41
- return (0, i18n_1.t)('ui5.namespaceSpecialCharacter');
32
+ return t('ui5.namespaceSpecialCharacter');
42
33
  }
43
34
  else if (!allowUnderscore && !/^[a-z0-9.]*$/g.test(namespace)) {
44
- return (0, i18n_1.t)('ui5.lowerAlphaNumericDotsOnly');
35
+ return t('ui5.lowerAlphaNumericDotsOnly');
45
36
  }
46
37
  if ((moduleName + namespace).length > 70) {
47
- return (0, i18n_1.t)('ui5.nameCombinedTooLong', { length: 70 });
38
+ return t('ui5.nameCombinedTooLong', { length: 70 });
48
39
  }
49
40
  if (namespace.toLowerCase() !== namespace) {
50
- return (0, i18n_1.t)('ui5.inputValueContainsCapital', { promptName: 'Namespace' });
41
+ return t('ui5.inputValueContainsCapital', { promptName: 'Namespace' });
51
42
  }
52
43
  return true;
53
44
  }
@@ -59,7 +50,7 @@ function validateNamespacePattern(namespace, moduleName = '', allowUnderscore =
59
50
  * @param allowUnderscore - is underscore characters allowed
60
51
  * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
61
52
  */
62
- function validateNamespace(namespace, moduleName, allowUnderscore = true) {
53
+ export function validateNamespace(namespace, moduleName, allowUnderscore = true) {
63
54
  if (!namespace) {
64
55
  return false;
65
56
  }
@@ -71,13 +62,13 @@ function validateNamespace(namespace, moduleName, allowUnderscore = true) {
71
62
  * @param libName - library module name
72
63
  * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
73
64
  */
74
- function validateLibModuleName(libName) {
65
+ export function validateLibModuleName(libName) {
75
66
  const isValid = validateModuleName(libName);
76
67
  if (typeof isValid === 'string') {
77
68
  return isValid;
78
69
  }
79
70
  if (!/^[a-z0-9]*$/g.test(libName)) {
80
- return (0, i18n_1.t)('ui5.lowerAlphaNumericOnly');
71
+ return t('ui5.lowerAlphaNumericOnly');
81
72
  }
82
73
  return true;
83
74
  }
@@ -88,21 +79,21 @@ function validateLibModuleName(libName) {
88
79
  * @param projectName - the UI5 application directory name
89
80
  * @returns true if valid, otherwise an error message string for use in Inquirer validation function
90
81
  */
91
- function validateProjectFolder(targetFolder, projectName) {
82
+ export function validateProjectFolder(targetFolder, projectName) {
92
83
  if (!folderExists(targetFolder)) {
93
- return (0, i18n_1.t)('ui5.folderDoesNotExist');
84
+ return t('ui5.folderDoesNotExist');
94
85
  }
95
86
  if (!folderWritePermExists(targetFolder)) {
96
- return (0, i18n_1.t)('ui5.folderDoesNotHaveCorrectPermissions');
87
+ return t('ui5.folderDoesNotHaveCorrectPermissions');
97
88
  }
98
- if (targetFolder && targetFolder.length > 0 && !folderExists((0, node_path_1.join)(targetFolder, projectName))) {
89
+ if (targetFolder && targetFolder.length > 0 && !folderExists(join(targetFolder, projectName))) {
99
90
  return true;
100
91
  }
101
- else if (targetFolder && targetFolder.length > 0 && folderExists((0, node_path_1.join)(targetFolder, projectName))) {
102
- return (0, i18n_1.t)('ui5.moduleAlreadyExists', { folderName: projectName });
92
+ else if (targetFolder && targetFolder.length > 0 && folderExists(join(targetFolder, projectName))) {
93
+ return t('ui5.moduleAlreadyExists', { folderName: projectName });
103
94
  }
104
95
  else {
105
- return (0, i18n_1.t)('ui5.enterProjectFolder');
96
+ return t('ui5.enterProjectFolder');
106
97
  }
107
98
  }
108
99
  /**
@@ -111,41 +102,41 @@ function validateProjectFolder(targetFolder, projectName) {
111
102
  * @param moduleName - module name to validate
112
103
  * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
113
104
  */
114
- function validateModuleName(moduleName) {
105
+ export function validateModuleName(moduleName) {
115
106
  if (/^[^a-zA-Z]/.test(moduleName)) {
116
- return (0, i18n_1.t)('ui5.moduleNameMustStartWithLetter');
107
+ return t('ui5.moduleNameMustStartWithLetter');
117
108
  }
118
109
  if (moduleName?.length > 70) {
119
- return (0, i18n_1.t)('ui5.nameTooLong', { length: 70 });
110
+ return t('ui5.nameTooLong', { length: 70 });
120
111
  }
121
112
  if (moduleName?.length < 3) {
122
- return (0, i18n_1.t)('ui5.nameTooShort', { length: 3 });
113
+ return t('ui5.nameTooShort', { length: 3 });
123
114
  }
124
115
  // convert the validation strings from `validateNpmPackageName` to required texts
125
116
  const messageMap = {
126
- 'name cannot be null': (0, i18n_1.t)('ui5.nameNull'),
127
- 'name cannot be undefined': (0, i18n_1.t)('ui5.nameUndefined'),
128
- 'name must be a string': (0, i18n_1.t)('ui5.nameNotString'),
129
- 'name length must be greater than zero': (0, i18n_1.t)('ui5.nameLengthZero'),
130
- 'name cannot start with a period': (0, i18n_1.t)('ui5.nameStartsWithPeriod'),
131
- 'name cannot start with an underscore': (0, i18n_1.t)('ui5.nameStartsWithUnderscore'),
132
- 'name cannot contain leading or trailing spaces': (0, i18n_1.t)('ui5.nameStartsOrEndsWithSpace'),
133
- [moduleName + ' is a blocklisted name']: (0, i18n_1.t)('ui5.nameBlocklisted', { moduleName }),
134
- [moduleName + ' is a core module name']: (0, i18n_1.t)('ui5.nameIsCoreModule', { moduleName }),
135
- 'name can no longer contain more than 214 characters': (0, i18n_1.t)('ui5.nameTooLong', { length: 214 }),
136
- 'name can no longer contain capital letters': (0, i18n_1.t)('ui5.inputValueContainsCapital', {
117
+ 'name cannot be null': t('ui5.nameNull'),
118
+ 'name cannot be undefined': t('ui5.nameUndefined'),
119
+ 'name must be a string': t('ui5.nameNotString'),
120
+ 'name length must be greater than zero': t('ui5.nameLengthZero'),
121
+ 'name cannot start with a period': t('ui5.nameStartsWithPeriod'),
122
+ 'name cannot start with an underscore': t('ui5.nameStartsWithUnderscore'),
123
+ 'name cannot contain leading or trailing spaces': t('ui5.nameStartsOrEndsWithSpace'),
124
+ [moduleName + ' is a blocklisted name']: t('ui5.nameBlocklisted', { moduleName }),
125
+ [moduleName + ' is a core module name']: t('ui5.nameIsCoreModule', { moduleName }),
126
+ 'name can no longer contain more than 214 characters': t('ui5.nameTooLong', { length: 214 }),
127
+ 'name can no longer contain capital letters': t('ui5.inputValueContainsCapital', {
137
128
  promptName: 'Module'
138
129
  }),
139
- 'name can no longer contain special characters ("~\'!()*")': (0, i18n_1.t)('ui5.nameContainsSpecialCharacters'),
140
- 'name can only contain URL-friendly characters': (0, i18n_1.t)('ui5.nameNotUrlFriendly')
130
+ 'name can no longer contain special characters ("~\'!()*")': t('ui5.nameContainsSpecialCharacters'),
131
+ 'name can only contain URL-friendly characters': t('ui5.nameNotUrlFriendly')
141
132
  };
142
- const valid = (0, validate_npm_package_name_1.default)(moduleName);
133
+ const valid = validateNpmPackageName(moduleName);
143
134
  if (valid.validForNewPackages && valid.validForOldPackages) {
144
135
  return true;
145
136
  }
146
137
  return [...(valid.errors ?? []), ...(valid.warnings ?? [])]
147
138
  .filter((msg) => !!msg)
148
- .map((msg) => messageMap[msg] ?? (0, i18n_1.t)('ui5.invalidModuleName'))
139
+ .map((msg) => messageMap[msg] ?? t('ui5.invalidModuleName'))
149
140
  .join(', ');
150
141
  }
151
142
  /**
@@ -156,9 +147,9 @@ function validateModuleName(moduleName) {
156
147
  */
157
148
  function folderExists(dirPath) {
158
149
  if (dirPath && typeof dirPath !== 'string') {
159
- return (0, i18n_1.t)('ERROR_NAME_NOT_STRING');
150
+ return t('ERROR_NAME_NOT_STRING');
160
151
  }
161
- return (0, node_fs_1.existsSync)(dirPath) && (0, node_fs_1.lstatSync)(dirPath).isDirectory();
152
+ return existsSync(dirPath) && lstatSync(dirPath).isDirectory();
162
153
  }
163
154
  /**
164
155
  * Test for directory write permissions.
@@ -170,7 +161,7 @@ function folderWritePermExists(dirPath) {
170
161
  let folderPerm = true;
171
162
  const isWin = process.platform === 'win32';
172
163
  try {
173
- (0, node_fs_1.accessSync)(isWin ? node_path_1.posix.basename(dirPath) : dirPath, node_fs_1.constants.W_OK);
164
+ accessSync(isWin ? posix.basename(dirPath) : dirPath, constants.W_OK);
174
165
  }
175
166
  catch (err) {
176
167
  folderPerm = false;
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@sap-ux/project-input-validator",
3
- "version": "0.7.2",
3
+ "version": "1.0.1",
4
4
  "description": "Library to validate Fiori project input formats",
5
+ "type": "module",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -16,9 +17,10 @@
16
17
  "dependencies": {
17
18
  "i18next": "25.10.10",
18
19
  "validate-npm-package-name": "7.0.2",
19
- "@sap-ux/project-access": "1.38.1"
20
+ "@sap-ux/project-access": "2.0.1"
20
21
  },
21
22
  "devDependencies": {
23
+ "@jest/globals": "30.3.0",
22
24
  "@types/validate-npm-package-name": "4.0.2",
23
25
  "jest-extended": "7.0.0"
24
26
  },
@@ -38,8 +40,8 @@
38
40
  "format": "prettier --write '**/*.{js,json,ts,yaml,yml}' --ignore-path ../../.prettierignore",
39
41
  "lint": "eslint",
40
42
  "lint:fix": "eslint --fix",
41
- "test": "jest --ci --forceExit --detectOpenHandles --colors",
42
- "test-u": "jest --ci --forceExit --detectOpenHandles --colors -u",
43
+ "test": "cross-env NODE_OPTIONS='--experimental-vm-modules' jest --ci --forceExit --detectOpenHandles --colors",
44
+ "test-u": "cross-env NODE_OPTIONS='--experimental-vm-modules' jest --ci --forceExit --detectOpenHandles --colors -u",
43
45
  "link": "pnpm link --global",
44
46
  "unlink": "pnpm unlink --global"
45
47
  }