@sap-ux/project-input-validator 0.1.2 → 0.2.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.
package/README.md CHANGED
@@ -17,4 +17,4 @@ Pnpm
17
17
  `pnpm add @sap-ux/project-input-validator`
18
18
 
19
19
  ## Usage
20
- See example usage in [test folder](./test/validators.test.ts).
20
+ See example usage in [test folder](./test).
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Validator Fiori app name is compatbiel with Fiori project requirements.
2
+ * Validator Fiori app name is compatble with Fiori project requirements.
3
3
  *
4
4
  * @param name Fiori app name
5
5
  * @param prefix Prefix required by backend system
@@ -13,13 +13,6 @@ export declare function validateAppName(name: string, prefix?: string): boolean
13
13
  * @returns true or error message
14
14
  */
15
15
  export declare function validateAppDescription(description: string): boolean | string;
16
- /**
17
- * Client number is either empty or 3 digit string.
18
- *
19
- * @param client ABAP system client number
20
- * @returns true or error message
21
- */
22
- export declare function validateClient(client: string): boolean | string;
23
16
  /**
24
17
  * Transport request number is not required for local package.
25
18
  *
@@ -35,11 +28,4 @@ export declare function validateTransportRequestNumber(transportRequest: string,
35
28
  * @returns true or error message
36
29
  */
37
30
  export declare function validatePackage(input: string): boolean | string;
38
- /**
39
- * Validate url input is valid url format.
40
- *
41
- * @param input Backend ABAP system url
42
- * @returns true or error message
43
- */
44
- export declare function validateUrl(input: string): boolean | string;
45
31
  //# sourceMappingURL=validators.d.ts.map
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateUrl = exports.validatePackage = exports.validateTransportRequestNumber = exports.validateClient = exports.validateAppDescription = exports.validateAppName = void 0;
4
- const i18n_1 = require("./i18n");
3
+ exports.validatePackage = exports.validateTransportRequestNumber = exports.validateAppDescription = exports.validateAppName = void 0;
4
+ const i18n_1 = require("../i18n");
5
5
  const os_1 = require("os");
6
6
  /**
7
- * Validator Fiori app name is compatbiel with Fiori project requirements.
7
+ * Validator Fiori app name is compatble with Fiori project requirements.
8
8
  *
9
9
  * @param name Fiori app name
10
10
  * @param prefix Prefix required by backend system
@@ -14,20 +14,20 @@ function validateAppName(name, prefix) {
14
14
  const errorMessages = [];
15
15
  const length = name ? name.trim().length : 0;
16
16
  if (!length) {
17
- return (0, i18n_1.t)('AbapAppNameRequired');
17
+ return (0, i18n_1.t)('deploy.abapAppNameRequired');
18
18
  }
19
19
  if (name.split('/').length > 3) {
20
- errorMessages.push((0, i18n_1.t)('AbapInvalidNamespace'));
20
+ errorMessages.push((0, i18n_1.t)('deploy.abapInvalidNamespace'));
21
21
  }
22
22
  else if (/^\/.*\/\w*$/g.test(name)) {
23
23
  const splitNames = name.split('/');
24
24
  let accumulatedMsg = '';
25
25
  if (splitNames[1].length > 10) {
26
- const errMsg = (0, i18n_1.t)('AbapInvalidNamespaceLength', { length: splitNames[1].length });
26
+ const errMsg = (0, i18n_1.t)('deploy.abapInvalidNamespaceLength', { length: splitNames[1].length });
27
27
  accumulatedMsg += `${errMsg}, `;
28
28
  }
29
29
  if (splitNames[2].length > 15) {
30
- const errMsg = (0, i18n_1.t)('AbapInvalidAppNameLength', { length: splitNames[2].length });
30
+ const errMsg = (0, i18n_1.t)('deploy.abapInvalidAppNameLength', { length: splitNames[2].length });
31
31
  accumulatedMsg += `${errMsg}, `;
32
32
  }
33
33
  if (accumulatedMsg) {
@@ -36,13 +36,13 @@ function validateAppName(name, prefix) {
36
36
  }
37
37
  }
38
38
  else if (length > 15) {
39
- errorMessages.push((0, i18n_1.t)('AbapInvalidAppNameLength', { length }));
39
+ errorMessages.push((0, i18n_1.t)('deploy.abapInvalidAppNameLength', { length }));
40
40
  }
41
41
  if (prefix && !name.toUpperCase().startsWith(prefix.toUpperCase())) {
42
- errorMessages.push((0, i18n_1.t)('AbapInvalidAppName', { prefix }));
42
+ errorMessages.push((0, i18n_1.t)('deploy.abapInvalidAppName', { prefix }));
43
43
  }
44
44
  if (!/^[A-Za-z0-9_/]*$/.test(name)) {
45
- errorMessages.push((0, i18n_1.t)('CharactersForbiddenInAppName'));
45
+ errorMessages.push((0, i18n_1.t)('deploy.charactersForbiddenInAppName'));
46
46
  }
47
47
  return processErrorMessages(errorMessages);
48
48
  }
@@ -61,7 +61,8 @@ function processErrorMessages(errorMessages) {
61
61
  return errorMessages[0];
62
62
  }
63
63
  else {
64
- return `${(0, i18n_1.t)('InvalidAppNameMultipleReason')}${os_1.EOL}${errorMessages.join(os_1.EOL)}${os_1.EOL}`;
64
+ const indentErrorMessageRows = errorMessages.map((errorMessage) => `${' '.repeat(8)}${errorMessage}`).join(os_1.EOL);
65
+ return `${(0, i18n_1.t)('deploy.invalidAppNameMultipleReason')}${os_1.EOL}${indentErrorMessageRows}${os_1.EOL}`;
65
66
  }
66
67
  }
67
68
  /**
@@ -72,30 +73,13 @@ function processErrorMessages(errorMessages) {
72
73
  */
73
74
  function validateAppDescription(description) {
74
75
  if (description.length > 60) {
75
- return (0, i18n_1.t)('AbapAppDescLength');
76
+ return (0, i18n_1.t)('deploy.abapAppDescLength');
76
77
  }
77
78
  else {
78
79
  return true;
79
80
  }
80
81
  }
81
82
  exports.validateAppDescription = validateAppDescription;
82
- /**
83
- * Client number is either empty or 3 digit string.
84
- *
85
- * @param client ABAP system client number
86
- * @returns true or error message
87
- */
88
- function validateClient(client) {
89
- const formattedInput = (client === null || client === void 0 ? void 0 : client.trim()) || '';
90
- const isValid = formattedInput === '' || /^\d{3}$/.test(formattedInput);
91
- if (isValid) {
92
- return true;
93
- }
94
- else {
95
- return (0, i18n_1.t)('InvalidClient', { client });
96
- }
97
- }
98
- exports.validateClient = validateClient;
99
83
  /**
100
84
  * Transport request number is not required for local package.
101
85
  *
@@ -106,7 +90,7 @@ exports.validateClient = validateClient;
106
90
  function validateTransportRequestNumber(transportRequest, packageName) {
107
91
  const regex = /^[$LlTt]/;
108
92
  if (!regex.test(packageName) && !(transportRequest === null || transportRequest === void 0 ? void 0 : transportRequest.trim())) {
109
- return (0, i18n_1.t)('AbapTransportNumRequired');
93
+ return (0, i18n_1.t)('deploy.abapTransportNumRequired');
110
94
  }
111
95
  else {
112
96
  return true;
@@ -121,27 +105,11 @@ exports.validateTransportRequestNumber = validateTransportRequestNumber;
121
105
  */
122
106
  function validatePackage(input) {
123
107
  if (!(input === null || input === void 0 ? void 0 : input.trim())) {
124
- return (0, i18n_1.t)('AbapPackageWarn');
108
+ return (0, i18n_1.t)('deploy.abapPackageWarn');
125
109
  }
126
110
  else {
127
111
  return true;
128
112
  }
129
113
  }
130
114
  exports.validatePackage = validatePackage;
131
- /**
132
- * Validate url input is valid url format.
133
- *
134
- * @param input Backend ABAP system url
135
- * @returns true or error message
136
- */
137
- function validateUrl(input) {
138
- try {
139
- const url = new URL(input);
140
- return !!url.protocol && !!url.host;
141
- }
142
- catch (_a) {
143
- return (0, i18n_1.t)('InvalidUrl', { input });
144
- }
145
- }
146
- exports.validateUrl = validateUrl;
147
115
  //# sourceMappingURL=validators.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * SAP client number is either empty or 3 digit string.
3
+ *
4
+ * @param client ABAP system client number
5
+ * @returns true or error message
6
+ */
7
+ export declare function validateClient(client: string): boolean | string;
8
+ /**
9
+ * Validate url input is valid url format.
10
+ *
11
+ * @param input Backend ABAP system url
12
+ * @returns true or error message
13
+ */
14
+ export declare function validateUrl(input: string): boolean | string;
15
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateUrl = exports.validateClient = void 0;
4
+ const i18n_1 = require("../i18n");
5
+ /**
6
+ * SAP client number is either empty or 3 digit string.
7
+ *
8
+ * @param client ABAP system client number
9
+ * @returns true or error message
10
+ */
11
+ function validateClient(client) {
12
+ const formattedInput = (client === null || client === void 0 ? void 0 : client.trim()) || '';
13
+ const isValid = formattedInput === '' || /^\d{3}$/.test(formattedInput);
14
+ if (isValid) {
15
+ return true;
16
+ }
17
+ else {
18
+ return (0, i18n_1.t)('general.invalidClient', { client });
19
+ }
20
+ }
21
+ exports.validateClient = validateClient;
22
+ /**
23
+ * Validate url input is valid url format.
24
+ *
25
+ * @param input Backend ABAP system url
26
+ * @returns true or error message
27
+ */
28
+ function validateUrl(input) {
29
+ try {
30
+ const url = new URL(input);
31
+ return !!url.protocol && !!url.host;
32
+ }
33
+ catch (_a) {
34
+ return (0, i18n_1.t)('general.invalidUrl', { input });
35
+ }
36
+ }
37
+ exports.validateUrl = validateUrl;
38
+ //# sourceMappingURL=validators.js.map
package/dist/i18n.d.ts CHANGED
@@ -5,7 +5,7 @@ export declare const PROJECT_INPUT_VALIDATOR_NS = "project-input-validator";
5
5
  */
6
6
  export declare function initI18n(): Promise<void>;
7
7
  /**
8
- * Helper function facading the call to i18next.
8
+ * Helper function facading the call to i18next. Unless a namespace option is provided the local namespace will be used.
9
9
  *
10
10
  * @param key i18n key
11
11
  * @param options additional options
package/dist/i18n.js CHANGED
@@ -14,7 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.t = exports.initI18n = exports.PROJECT_INPUT_VALIDATOR_NS = void 0;
16
16
  const i18next_1 = __importDefault(require("i18next"));
17
- const common_i18n_json_1 = __importDefault(require("./translations/common.i18n.json"));
17
+ const project_input_validator_i18n_json_1 = __importDefault(require("./translations/project-input-validator.i18n.json"));
18
18
  exports.PROJECT_INPUT_VALIDATOR_NS = 'project-input-validator';
19
19
  /**
20
20
  * Initialize i18next with the translations for this module.
@@ -24,7 +24,7 @@ function initI18n() {
24
24
  yield i18next_1.default.init({
25
25
  resources: {
26
26
  en: {
27
- [exports.PROJECT_INPUT_VALIDATOR_NS]: common_i18n_json_1.default
27
+ [exports.PROJECT_INPUT_VALIDATOR_NS]: project_input_validator_i18n_json_1.default
28
28
  }
29
29
  },
30
30
  lng: 'en',
@@ -36,17 +36,20 @@ function initI18n() {
36
36
  }
37
37
  exports.initI18n = initI18n;
38
38
  /**
39
- * Helper function facading the call to i18next.
39
+ * Helper function facading the call to i18next. Unless a namespace option is provided the local namespace will be used.
40
40
  *
41
41
  * @param key i18n key
42
42
  * @param options additional options
43
43
  * @returns {string} localized string stored for the given key
44
44
  */
45
45
  function t(key, options) {
46
+ if (!(options === null || options === void 0 ? void 0 : options.ns)) {
47
+ options = Object.assign(options !== null && options !== void 0 ? options : {}, { ns: exports.PROJECT_INPUT_VALIDATOR_NS });
48
+ }
46
49
  return i18next_1.default.t(key, options);
47
50
  }
48
51
  exports.t = t;
49
52
  initI18n().catch(() => {
50
- // Ignore any errors since the write will still work
53
+ // needed by lint
51
54
  });
52
55
  //# sourceMappingURL=i18n.js.map
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export * from './validators';
1
+ export * from './deploy/validators';
2
+ export * from './ui5/validators';
3
+ export * from './general/validators';
2
4
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -14,5 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./validators"), exports);
17
+ __exportStar(require("./deploy/validators"), exports);
18
+ __exportStar(require("./ui5/validators"), exports);
19
+ __exportStar(require("./general/validators"), exports);
18
20
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,49 @@
1
+ {
2
+ "deploy": {
3
+ "abapAppDescLength": "Deployment Description should not exceed 60 characters",
4
+ "abapTransportNumRequired": "Provide a transport request for your application",
5
+ "abapPackageWarn": "Provide a package",
6
+ "abapAppNameRequired": "Application name required",
7
+ "abapInvalidNamespace": "Namespace invalid as there are too many forward slashes",
8
+ "abapInvalidNamespaceLength": "Namespace limited to 10 characters, entered {{length}}",
9
+ "abapInvalidAppNameLength": "Application name limited to 15 characters, entered {{length}}",
10
+ "abapInvalidAppName": "Application name needs to be prefixed with [{{prefix}}]",
11
+ "charactersForbiddenInAppName": "Only alphanumeric, underscore and slash characters are allowed",
12
+ "invalidAppNameMultipleReason": "Application name is invalid for multiple reasons:"
13
+ },
14
+ "ui5": {
15
+ "namespaceMustStartWithLetter": "The namespace must start with a letter",
16
+ "namespaceEndInPeriod": "The namespace cannot end with a period",
17
+ "namespaceCannotBeSap": "The namespace cannot be {{str}}",
18
+ "namespaceStartsWithNew": "The namespace cannot start with {{str}}",
19
+ "namespaceNumberAfterPeriod": "A number cannot follow a period in the namespace",
20
+ "lowerAlphaNumericOnly": "Please use lowercase alpha numeric characters only",
21
+ "lowerAlphaNumericDotsOnly": "Please use lowercase alpha numeric characters and dots only for the namespace.",
22
+ "namespaceSpecialCharacter": "The namespace can only contain letters, digits, dots, and underscores",
23
+ "moduleNameMustStartWithLetter": "The module name must start with a letter",
24
+ "nameCombinedTooLong": "The combined length of the namespace and module name must not exceed {{length}} characters",
25
+ "folderDoesNotExist": "Folder does not exist. Please enter the root folder for your project",
26
+ "folderDoesNotHaveCorrectPermissions": "Selected folder does not have required permissions. Please ensure you have permission to write to the selected folder and try again.",
27
+ "enterProjectFolder": "Please enter a project folder",
28
+ "nameNull": "Module name cannot be null",
29
+ "nameUndefined": "Module name cannot be undefined",
30
+ "nameNotString": "Module name must be a string",
31
+ "nameLengthZero": "Module name's length must be greater than zero",
32
+ "nameStartsWithPeriod": "Module name cannot start with a period",
33
+ "nameStartsWithUnderscore": "Module name cannot start with an underscore",
34
+ "nameStartsOrEndsWithSpace": "Module name cannot contain leading or trailing spaces",
35
+ "nameBlocklisted": "{{modName}} is a blocklisted module name",
36
+ "nameIsCoreModule": "{{modName}} is a core module name",
37
+ "nameTooLong": "Module name cannot contain more than {{length}} characters",
38
+ "nameTooShort": "Module name must be at least {{length}} characters",
39
+ "inputValueContainsCapital": "{{promptName}} cannot contain capital letters",
40
+ "nameContainsSpecialCharacters": "Module name cannot contain special characters (\"~'!()*)",
41
+ "nameNotUrlFriendly": "Module name can only contain URL-friendly characters",
42
+ "invalidModuleName": "Invalid module name",
43
+ "moduleAlreadyExists": "The folder: {{folderName}} already exists at the specified path"
44
+ },
45
+ "general": {
46
+ "invalidUrl": "Invalid URL: [{{-input}}]",
47
+ "invalidClient": "[{{client}}] is invalid. Enter blank or a value between 000-999"
48
+ }
49
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Validator: UI5 namespace.
3
+ *
4
+ * @param namespace - namepsace to validate
5
+ * @param moduleName - module name
6
+ * @param allowUnderscore - is underscore characters allowed
7
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
8
+ */
9
+ export declare function validateNamespace(namespace: string, moduleName?: string, allowUnderscore?: boolean): boolean | string;
10
+ /**
11
+ * Validator: UI5 library module name.
12
+ *
13
+ * @param libName - library module name
14
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
15
+ */
16
+ export declare function validateLibModuleName(libName: string): boolean | string;
17
+ /**
18
+ * Validator: UI5 project directory can be used to create a UI5 application.
19
+ *
20
+ * @param targetFolder - the directory path not including the application folder (UI5 application name)
21
+ * @param projectName - the UI5 application directory name
22
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation function
23
+ */
24
+ export declare function validateProjectFolder(targetFolder: string, projectName: string): boolean | string;
25
+ /**
26
+ * Validator: UI5 package json module name validator. Validates a module name accoding to npm package rules and some additional UI5 specific rules.
27
+ *
28
+ * @param moduleName - module name to validate
29
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
30
+ */
31
+ export declare function validateModuleName(moduleName: string): boolean | string;
32
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1,182 @@
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.validateModuleName = exports.validateProjectFolder = exports.validateLibModuleName = exports.validateNamespace = void 0;
7
+ const path_1 = require("path");
8
+ const i18n_1 = require("../i18n");
9
+ const fs_1 = require("fs");
10
+ const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name"));
11
+ /**
12
+ * Validator: UI5 application namespace.
13
+ *
14
+ * @param namespace - namespace
15
+ * @param moduleName - module name
16
+ * @param allowUnderscore - should allow underscores in namespace
17
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
18
+ */
19
+ function validateNamespacePattern(namespace, moduleName = '', allowUnderscore = true) {
20
+ // Since namespace is concatenated with name to write the app id to the yamls we must comply with the yaml specVersion validation
21
+ // https://sap.github.io/ui5-tooling/stable/pages/Configuration/#name
22
+ if (!/^[a-zA-Z]/.test(namespace)) {
23
+ return (0, i18n_1.t)('ui5.namespaceMustStartWithLetter');
24
+ }
25
+ if (namespace.endsWith('.')) {
26
+ return (0, i18n_1.t)('ui5.namespaceEndInPeriod');
27
+ }
28
+ if (namespace.toUpperCase() === 'SAP') {
29
+ return (0, i18n_1.t)('ui5.namespaceCannotBeSap', { str: namespace });
30
+ }
31
+ if (namespace.toLowerCase().startsWith('new')) {
32
+ return (0, i18n_1.t)('ui5.namespaceStartsWithNew', { str: namespace.substring(0, 3) });
33
+ }
34
+ if (/\.\d/.test(namespace)) {
35
+ return (0, i18n_1.t)('ui5.namespaceNumberAfterPeriod');
36
+ }
37
+ if (allowUnderscore && !/^[\w.]+$/.test(namespace)) {
38
+ return (0, i18n_1.t)('ui5.namespaceSpecialCharacter');
39
+ }
40
+ else if (!allowUnderscore && !/^[a-z0-9.]*$/g.test(namespace)) {
41
+ return (0, i18n_1.t)('ui5.lowerAlphaNumericDotsOnly');
42
+ }
43
+ if ((moduleName + namespace).length > 70) {
44
+ return (0, i18n_1.t)('ui5.nameCombinedTooLong', { length: 70 });
45
+ }
46
+ if (namespace.toLowerCase() !== namespace) {
47
+ return (0, i18n_1.t)('ui5.inputValueContainsCapital', { promptName: 'Namespace' });
48
+ }
49
+ return true;
50
+ }
51
+ /**
52
+ * Validator: UI5 namespace.
53
+ *
54
+ * @param namespace - namepsace to validate
55
+ * @param moduleName - module name
56
+ * @param allowUnderscore - is underscore characters allowed
57
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
58
+ */
59
+ function validateNamespace(namespace, moduleName, allowUnderscore = true) {
60
+ if (!namespace) {
61
+ return false;
62
+ }
63
+ return validateNamespacePattern(namespace, moduleName, allowUnderscore);
64
+ }
65
+ exports.validateNamespace = validateNamespace;
66
+ /**
67
+ * Validator: UI5 library module name.
68
+ *
69
+ * @param libName - library module name
70
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
71
+ */
72
+ function validateLibModuleName(libName) {
73
+ const isValid = validateModuleName(libName);
74
+ if (typeof isValid === 'string') {
75
+ return isValid;
76
+ }
77
+ if (!/^[a-z0-9]*$/g.test(libName)) {
78
+ return (0, i18n_1.t)('ui5.lowerAlphaNumericOnly');
79
+ }
80
+ return true;
81
+ }
82
+ exports.validateLibModuleName = validateLibModuleName;
83
+ /**
84
+ * Validator: UI5 project directory can be used to create a UI5 application.
85
+ *
86
+ * @param targetFolder - the directory path not including the application folder (UI5 application name)
87
+ * @param projectName - the UI5 application directory name
88
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation function
89
+ */
90
+ function validateProjectFolder(targetFolder, projectName) {
91
+ if (!folderExists(targetFolder)) {
92
+ return (0, i18n_1.t)('ui5.folderDoesNotExist');
93
+ }
94
+ if (!folderWritePermExists(targetFolder)) {
95
+ return (0, i18n_1.t)('ui5.folderDoesNotHaveCorrectPermissions');
96
+ }
97
+ if (targetFolder && targetFolder.length > 0 && !folderExists((0, path_1.join)(targetFolder, projectName))) {
98
+ return true;
99
+ }
100
+ else if (targetFolder && targetFolder.length > 0 && folderExists((0, path_1.join)(targetFolder, projectName))) {
101
+ return (0, i18n_1.t)('ui5.moduleAlreadyExists', { folderName: projectName });
102
+ }
103
+ else {
104
+ return (0, i18n_1.t)('ui5.enterProjectFolder');
105
+ }
106
+ }
107
+ exports.validateProjectFolder = validateProjectFolder;
108
+ /**
109
+ * Validator: UI5 package json module name validator. Validates a module name accoding to npm package rules and some additional UI5 specific rules.
110
+ *
111
+ * @param moduleName - module name to validate
112
+ * @returns true if valid, otherwise an error message string for use in Inquirer validation functions
113
+ */
114
+ function validateModuleName(moduleName) {
115
+ var _a, _b;
116
+ if (/^[^a-zA-Z]/.test(moduleName)) {
117
+ return (0, i18n_1.t)('ui5.moduleNameMustStartWithLetter');
118
+ }
119
+ if ((moduleName === null || moduleName === void 0 ? void 0 : moduleName.length) > 70) {
120
+ return (0, i18n_1.t)('ui5.nameTooLong', { length: 70 });
121
+ }
122
+ if ((moduleName === null || moduleName === void 0 ? void 0 : moduleName.length) < 3) {
123
+ return (0, i18n_1.t)('ui5.nameTooShort', { length: 3 });
124
+ }
125
+ // convert the validation strings from `validateNpmPackageName` to required texts
126
+ const messageMap = {
127
+ 'name cannot be null': (0, i18n_1.t)('ui5.nameNull'),
128
+ 'name cannot be undefined': (0, i18n_1.t)('ui5.nameUndefined'),
129
+ 'name must be a string': (0, i18n_1.t)('ui5.nameNotString'),
130
+ 'name length must be greater than zero': (0, i18n_1.t)('ui5.nameLengthZero'),
131
+ 'name cannot start with a period': (0, i18n_1.t)('ui5.nameStartsWithPeriod'),
132
+ 'name cannot start with an underscore': (0, i18n_1.t)('ui5.nameStartsWithUnderscore'),
133
+ 'name cannot contain leading or trailing spaces': (0, i18n_1.t)('ui5.nameStartsOrEndsWithSpace'),
134
+ [moduleName + ' is a blocklisted name']: (0, i18n_1.t)('ui5.nameBlocklisted', { moduleName }),
135
+ [moduleName + ' is a core module name']: (0, i18n_1.t)('ui5.nameIsCoreModule', { moduleName }),
136
+ 'name can no longer contain more than 214 characters': (0, i18n_1.t)('ui5.nameTooLong', { length: 214 }),
137
+ 'name can no longer contain capital letters': (0, i18n_1.t)('ui5.INPUT_VALUE_CONTAINS_CAPITAL', {
138
+ promptName: 'Module'
139
+ }),
140
+ 'name can no longer contain special characters ("~\'!()*")': (0, i18n_1.t)('ui5.NAME_CONTAINS_SPECIAL_CHARACTERS'),
141
+ 'name can only contain URL-friendly characters': (0, i18n_1.t)('ui5.NAME_NOT_URL_FRIENDLY')
142
+ };
143
+ const valid = (0, validate_npm_package_name_1.default)(moduleName);
144
+ if (valid.validForNewPackages && valid.validForOldPackages) {
145
+ return true;
146
+ }
147
+ return [...((_a = valid.errors) !== null && _a !== void 0 ? _a : []), ...((_b = valid.warnings) !== null && _b !== void 0 ? _b : [])]
148
+ .filter((msg) => !!msg)
149
+ .map((msg) => { var _a; return (_a = messageMap[msg]) !== null && _a !== void 0 ? _a : (0, i18n_1.t)('ui5.invalidModuleName'); })
150
+ .join(', ');
151
+ }
152
+ exports.validateModuleName = validateModuleName;
153
+ /**
154
+ * Test for existence of specified directory path.
155
+ *
156
+ * @param dirPath - directory path
157
+ * @returns true if the directory exists, false if not or validation error message
158
+ */
159
+ function folderExists(dirPath) {
160
+ if (dirPath && typeof dirPath !== 'string') {
161
+ return (0, i18n_1.t)('ERROR_NAME_NOT_STRING');
162
+ }
163
+ return (0, fs_1.existsSync)(dirPath) && (0, fs_1.lstatSync)(dirPath).isDirectory();
164
+ }
165
+ /**
166
+ * Test for directory write permissions.
167
+ *
168
+ * @param dirPath - path to the directory to test
169
+ * @returns true, if write is allowed
170
+ */
171
+ function folderWritePermExists(dirPath) {
172
+ let folderPerm = true;
173
+ const isWin = process.platform === 'win32';
174
+ try {
175
+ (0, fs_1.accessSync)(isWin ? path_1.posix.basename(dirPath) : dirPath, fs_1.constants.W_OK);
176
+ }
177
+ catch (err) {
178
+ folderPerm = false;
179
+ }
180
+ return folderPerm;
181
+ }
182
+ //# sourceMappingURL=validators.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap-ux/project-input-validator",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "Library to validate Fiori project input formats",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,9 +14,14 @@
14
14
  "private": false,
15
15
  "main": "dist/index.js",
16
16
  "dependencies": {
17
- "i18next": "20.6.1"
17
+ "i18next": "20.6.1",
18
+ "validate-npm-package-name": "5.0.0"
19
+ },
20
+ "devDependencies": {
21
+ "@types/validate-npm-package-name": "4.0.1",
22
+ "@types/i18next": "13.0.0",
23
+ "jest-extended": "3.2.4"
18
24
  },
19
- "devDependencies": {},
20
25
  "files": [
21
26
  "dist",
22
27
  "LICENSE",
@@ -25,7 +30,7 @@
25
30
  ],
26
31
  "engines": {
27
32
  "pnpm": ">=6.26.1 < 7.0.0 || >=7.1.0",
28
- "node": ">= 14.16.0 < 15.0.0 || >=16.1.0 < 17.0.0 || >=18.0.0 < 19.0.0"
33
+ "node": ">=18.x"
29
34
  },
30
35
  "scripts": {
31
36
  "build": "tsc --build",
@@ -1,14 +0,0 @@
1
- {
2
- "AbapAppDescLength": "Deployment Description should not exceed 60 characters",
3
- "InvalidClient": "[{{client}}] is invalid. Enter blank or a value between 000-999",
4
- "AbapTransportNumRequired": "Provide a transport request for your application",
5
- "AbapPackageWarn": "Provide a package",
6
- "InvalidUrl": "Invalid URL: [{{input}}]",
7
- "AbapAppNameRequired": "Application name required",
8
- "AbapInvalidNamespace": "Namespace invalid as there are too many forward slashes",
9
- "AbapInvalidNamespaceLength": "Namespace limited to 10 characters, entered {{length}}",
10
- "AbapInvalidAppNameLength": "Application name limited to 15 characters, entered {{length}}",
11
- "AbapInvalidAppName": "Application name needs to be prefixed with [{{prefix}}]",
12
- "CharactersForbiddenInAppName": "Only alphanumeric, underscore and slash characters are allowed",
13
- "InvalidAppNameMultipleReason": "Application name is invalid for multiple reasons:"
14
- }