@suitegeezus/suitecloud-cli 3.1.4

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.
Files changed (157) hide show
  1. package/CONTRIBUTING.md +7 -0
  2. package/DELTA.md +235 -0
  3. package/README.md +107 -0
  4. package/docs/Command.md +299 -0
  5. package/messages.json +317 -0
  6. package/package.json +51 -0
  7. package/postinstall.js +8 -0
  8. package/resources/FUTC-LICENSE.txt +115 -0
  9. package/src/ApplicationConstants.js +87 -0
  10. package/src/CLI.js +202 -0
  11. package/src/CLIException.js +21 -0
  12. package/src/ExecutionEnvironmentContext.js +39 -0
  13. package/src/SdkExecutionContext.js +90 -0
  14. package/src/SdkExecutor.js +160 -0
  15. package/src/commands/Command.js +158 -0
  16. package/src/commands/account/manageauth/ManageAccountAction.js +126 -0
  17. package/src/commands/account/manageauth/ManageAccountCommand.js +20 -0
  18. package/src/commands/account/manageauth/ManageAccountInputHandler.js +215 -0
  19. package/src/commands/account/manageauth/ManageAccountOutputHandler.js +30 -0
  20. package/src/commands/account/setup/SetupAction.js +39 -0
  21. package/src/commands/account/setup/SetupCommand.js +21 -0
  22. package/src/commands/account/setup/SetupInputHandler.js +169 -0
  23. package/src/commands/account/setup/SetupOutputHandler.js +65 -0
  24. package/src/commands/account/setupci/AccountSetupCiAction.js +58 -0
  25. package/src/commands/account/setupci/AccountSetupCiCommand.js +20 -0
  26. package/src/commands/account/setupci/AccountSetupCiConstants.js +21 -0
  27. package/src/commands/account/setupci/AccountSetupCiOutputHandler.js +40 -0
  28. package/src/commands/account/setupci/AccountSetupCiValidation.js +100 -0
  29. package/src/commands/base/BaseAction.js +37 -0
  30. package/src/commands/base/BaseInputHandler.js +24 -0
  31. package/src/commands/base/BaseOutputHandler.js +30 -0
  32. package/src/commands/custom/hello/Action.js +58 -0
  33. package/src/commands/custom/hello/Command.js +20 -0
  34. package/src/commands/custom/hello/Handler.js +26 -0
  35. package/src/commands/custom/hello/README.md +78 -0
  36. package/src/commands/custom/hook/Action.js +28 -0
  37. package/src/commands/custom/hook/Command.js +22 -0
  38. package/src/commands/custom/hook/InputHandler.js +8 -0
  39. package/src/commands/custom/hook/OutputHandler.js +8 -0
  40. package/src/commands/custom/hook/README.md +32 -0
  41. package/src/commands/file/create/CreateFileAction.js +89 -0
  42. package/src/commands/file/create/CreateFileCommand.js +20 -0
  43. package/src/commands/file/create/CreateFileInputHandler.js +175 -0
  44. package/src/commands/file/create/CreateFileOutputHandler.js +22 -0
  45. package/src/commands/file/import/ImportFilesAction.js +112 -0
  46. package/src/commands/file/import/ImportFilesCommand.js +22 -0
  47. package/src/commands/file/import/ImportFilesInputHandler.js +130 -0
  48. package/src/commands/file/import/ImportFilesOutputHandler.js +53 -0
  49. package/src/commands/file/list/ListFilesAction.js +55 -0
  50. package/src/commands/file/list/ListFilesCommand.js +20 -0
  51. package/src/commands/file/list/ListFilesInputHandler.js +55 -0
  52. package/src/commands/file/list/ListFilesOutputHandler.js +24 -0
  53. package/src/commands/file/upload/UploadFilesAction.js +67 -0
  54. package/src/commands/file/upload/UploadFilesCommand.js +20 -0
  55. package/src/commands/file/upload/UploadFilesInputHandler.js +125 -0
  56. package/src/commands/file/upload/UploadFilesOutputHandler.js +49 -0
  57. package/src/commands/object/create/CreateObjectAction.js +33 -0
  58. package/src/commands/object/create/CreateObjectCommand.js +19 -0
  59. package/src/commands/object/create/CreateObjectInputHandler.js +82 -0
  60. package/src/commands/object/import/ImportObjectsAction.js +225 -0
  61. package/src/commands/object/import/ImportObjectsCommand.js +20 -0
  62. package/src/commands/object/import/ImportObjectsInputHandler.js +310 -0
  63. package/src/commands/object/import/ImportObjectsOutputHandler.js +114 -0
  64. package/src/commands/object/list/ListObjectsAction.js +62 -0
  65. package/src/commands/object/list/ListObjectsCommand.js +20 -0
  66. package/src/commands/object/list/ListObjectsInputHandler.js +148 -0
  67. package/src/commands/object/list/ListObjectsOutputHandler.js +29 -0
  68. package/src/commands/object/update/UpdateAction.js +138 -0
  69. package/src/commands/object/update/UpdateCommand.js +20 -0
  70. package/src/commands/object/update/UpdateInputHandler.js +170 -0
  71. package/src/commands/object/update/UpdateOutputHandler.js +61 -0
  72. package/src/commands/project/adddependencies/AddDependenciesAction.js +55 -0
  73. package/src/commands/project/adddependencies/AddDependenciesCommand.js +19 -0
  74. package/src/commands/project/adddependencies/AddDependenciesOutputHandler.js +114 -0
  75. package/src/commands/project/create/CreateProjectAction.js +370 -0
  76. package/src/commands/project/create/CreateProjectCommand.js +20 -0
  77. package/src/commands/project/create/CreateProjectInputHandler.js +169 -0
  78. package/src/commands/project/create/CreateProjectOutputHandler.js +36 -0
  79. package/src/commands/project/deploy/DeployAction.js +161 -0
  80. package/src/commands/project/deploy/DeployCommand.js +20 -0
  81. package/src/commands/project/deploy/DeployInputHandler.js +100 -0
  82. package/src/commands/project/deploy/DeployOutputHandler.js +49 -0
  83. package/src/commands/project/package/PackageAction.js +59 -0
  84. package/src/commands/project/package/PackageCommand.js +18 -0
  85. package/src/commands/project/package/PackageOutputHandler.js +18 -0
  86. package/src/commands/project/validate/ValidateAction.js +106 -0
  87. package/src/commands/project/validate/ValidateCommand.js +20 -0
  88. package/src/commands/project/validate/ValidateInputHandler.js +92 -0
  89. package/src/commands/project/validate/ValidateOutputHandler.js +74 -0
  90. package/src/core/CommandActionExecutor.js +347 -0
  91. package/src/core/CommandAuthentication.js +13 -0
  92. package/src/core/CommandOptionsValidator.js +42 -0
  93. package/src/core/CommandRegistrationService.js +130 -0
  94. package/src/core/CommandsMetadataService.js +104 -0
  95. package/src/core/extensibility/CLIConfigurationService.js +192 -0
  96. package/src/core/extensibility/CommandUserExtension.js +64 -0
  97. package/src/core/sdksetup/SdkDownloadService.js +109 -0
  98. package/src/core/sdksetup/SdkLicense.js +39 -0
  99. package/src/core/sdksetup/SdkProperties.js +51 -0
  100. package/src/loggers/ConsoleLogger.js +32 -0
  101. package/src/loggers/LoggerFontFormatter.mjs +17 -0
  102. package/src/loggers/LoggerOsConstants.js +12 -0
  103. package/src/loggers/NodeConsoleLogger.js +47 -0
  104. package/src/metadata/CommandGenerators.json +92 -0
  105. package/src/metadata/NodeCommandsMetadata.json +139 -0
  106. package/src/metadata/ObjectTypesMetadata.js +615 -0
  107. package/src/metadata/SdkCommandsMetadata.json +846 -0
  108. package/src/metadata/SdkCommandsMetadataPatch.json +130 -0
  109. package/src/metadata/SuiteScriptModulesMetadata.js +152 -0
  110. package/src/metadata/SuiteScriptTypesMetadata.js +64 -0
  111. package/src/services/AccountFileCabinetService.js +86 -0
  112. package/src/services/EnvironmentInformationService.js +31 -0
  113. package/src/services/ExecutionContextService.js +108 -0
  114. package/src/services/FileCabinetService.js +65 -0
  115. package/src/services/FileSystemService.js +245 -0
  116. package/src/services/NodeTranslationService.js +22 -0
  117. package/src/services/NpmInstallRunner.js +33 -0
  118. package/src/services/ProjectInfoService.js +209 -0
  119. package/src/services/SuiteCloudAuthProxyService.js +469 -0
  120. package/src/services/TranslationKeys.js +506 -0
  121. package/src/services/TranslationService.js +30 -0
  122. package/src/services/actionresult/ActionResult.js +129 -0
  123. package/src/services/actionresult/AuthenticateActionResult.js +85 -0
  124. package/src/services/actionresult/CreateProjectActionResult.js +100 -0
  125. package/src/services/actionresult/DeployActionResult.js +69 -0
  126. package/src/services/actionresult/HelloActionResult.js +13 -0
  127. package/src/services/actionresult/ManageAccountActionResult.js +70 -0
  128. package/src/services/settings/CLISettings.js +46 -0
  129. package/src/services/settings/CLISettingsService.js +132 -0
  130. package/src/suitecloud.js +33 -0
  131. package/src/templates/TemplateKeys.js +25 -0
  132. package/src/templates/objects/commerceextension.xml +9 -0
  133. package/src/templates/projectconfigs/default_gitignore.template +47 -0
  134. package/src/templates/projectconfigs/sdf.config.js +4 -0
  135. package/src/templates/projectconfigs/suitecloud.config.js +4 -0
  136. package/src/templates/scripts/blankscript.js +3 -0
  137. package/src/templates/unittest/jest.config.js.template +7 -0
  138. package/src/templates/unittest/jsconfig.json.template +5 -0
  139. package/src/templates/unittest/package.json.template +12 -0
  140. package/src/templates/unittest/sample-test.js.template +37 -0
  141. package/src/templates/unittest/suitecloud.config.js.template +15 -0
  142. package/src/ui/CliSpinner.js +34 -0
  143. package/src/utils/AccountCredentialsFormatter.js +62 -0
  144. package/src/utils/AccountSpecificValuesUtils.js +55 -0
  145. package/src/utils/ActionResultUtils.js +47 -0
  146. package/src/utils/ApplyInstallationPreferencesUtils.js +41 -0
  147. package/src/utils/AuthenticationUtils.js +262 -0
  148. package/src/utils/CommandUtils.js +50 -0
  149. package/src/utils/CryptoUtils.js +41 -0
  150. package/src/utils/ExceptionUtils.js +33 -0
  151. package/src/utils/FileUtils.js +43 -0
  152. package/src/utils/SdkOperationResult.js +68 -0
  153. package/src/utils/SdkOperationResultUtils.js +20 -0
  154. package/src/utils/ValidationErrorsFormatter.js +23 -0
  155. package/src/utils/http/HttpConstants.js +39 -0
  156. package/src/utils/http/ProxyAgent.js +110 -0
  157. package/src/validation/InteractiveAnswersValidator.js +205 -0
@@ -0,0 +1,43 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+
7
+ const fs = require('fs');
8
+ const UTF8 = 'utf8';
9
+
10
+ class FileUtils {
11
+ create(fileName, object) {
12
+ const content = JSON.stringify(object, null,'\t');
13
+
14
+ fs.writeFileSync(fileName, content, UTF8, function (error) {
15
+ if (error) {
16
+ // Using hardcoded message to avoid circular dependency as NodeTranslationService imports FileUtils
17
+ // TODO restore: throw NodeTranslationService.getMessage(ERRORS.WRITING_FILE, fileName, JSON.stringify(error));
18
+ // when NodeTranslationService is refactored to use node require to retrieve messages.json file
19
+ throw `There was a problem while creating the file ${fileName}.\n Error: ${error}`
20
+ }
21
+ });
22
+ }
23
+
24
+ readAsJson(filePath) {
25
+ const content = fs.readFileSync(filePath, UTF8);
26
+ return JSON.parse(content);
27
+ }
28
+
29
+ readAsString(fileName) {
30
+ return fs.readFileSync(fileName, UTF8);
31
+ }
32
+
33
+ exists(fileName) {
34
+ return fs.existsSync(fileName);
35
+ }
36
+
37
+ createDirectory(dirPath) {
38
+ fs.mkdirSync(dirPath, { recursive: true })
39
+ }
40
+
41
+ }
42
+
43
+ module.exports = new FileUtils();
@@ -0,0 +1,68 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+ const assert = require('assert');
7
+
8
+ /*
9
+ // Sample SdkOperation results
10
+ const SdkOperationResultSuccess =
11
+ {
12
+ status: 'SUCCESS',
13
+ data: { needsReauthorization: true },
14
+ errorMessages: []
15
+ }
16
+ // data: could be of any shape/type of object
17
+
18
+ const SdkOperationResultError =
19
+ {
20
+ status: 'ERROR',
21
+ errorCode: 'SAS0001',
22
+ errorMessages: [
23
+ 'The authentication process has been interrupted.\r\n' +
24
+ 'The request was canceled.'
25
+ ]
26
+ }
27
+ */
28
+ const STATUS = {
29
+ SUCCESS: 'SUCCESS',
30
+ ERROR: 'ERROR',
31
+ }
32
+ module.exports = class SdkOperationResult {
33
+ status;
34
+ data;
35
+ resultMessage;
36
+ errorCode;
37
+ errorMessages;
38
+
39
+ constructor(rawOpertionResult) {
40
+ assert(rawOpertionResult)
41
+ assert(rawOpertionResult.status, 'status is required when creating an SdkOperationResult object.')
42
+ // Note: not checking existence of rawOpertionResult.data when status === SUCCESS as refrehAuthorization command returns successfully without data
43
+ if (rawOpertionResult.status === STATUS.ERROR) {
44
+ assert(rawOpertionResult.errorMessages, 'errorMessages is required when SdkOperationResult is an error.');
45
+ assert(Array.isArray(rawOpertionResult.errorMessages), 'errorMessages property must be an array');
46
+ }
47
+ this.status = rawOpertionResult.status;
48
+ this.data = rawOpertionResult.data;
49
+ this.resultMessage = rawOpertionResult.resultMessage;
50
+ this.errorCode = rawOpertionResult.errorCode;
51
+ this.errorMessages = rawOpertionResult.errorMessages;
52
+ }
53
+
54
+ isSuccess() {
55
+ return this.status === STATUS.SUCCESS
56
+ }
57
+
58
+ get errorMessages() {
59
+ if (this.status === STATUS.SUCCESS) {
60
+ throw 'Accessing errorMessages on a successful SdkOperationResult'
61
+ }
62
+ this.errorMessages;
63
+ }
64
+
65
+ get resultMessage() {
66
+ return this.resultMessage ? this.resultMessage : '';
67
+ }
68
+ }
@@ -0,0 +1,20 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+
7
+ module.exports = {
8
+ // TODO: we could be always wrapping OperationResults whenever we run sdkCommand using the sdkExecutor with the SdkOperationResult.js class
9
+ // and then use SdkOperationResult.isSuccess() method instead of (operationResult.status === SdkOperationResultUtils.STATUS.SUCCESS)
10
+ // Also the SdkOperationResult.js class allows to type using jsdocs the return type of any sdkCommand, as done in AuthenticationUtils.refreshAuthorization
11
+ STATUS: {
12
+ SUCCESS: 'SUCCESS',
13
+ ERROR: 'ERROR',
14
+ },
15
+
16
+ getResultMessage: (operationResult) => {
17
+ const { resultMessage } = operationResult;
18
+ return resultMessage ? resultMessage : '';
19
+ },
20
+ };
@@ -0,0 +1,23 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+
7
+ const NodeTranslationService = require('../services/NodeTranslationService');
8
+ const TRANSLATION_KEYS = require('../services/TranslationKeys');
9
+ const { lineBreak } = require('../loggers/LoggerOsConstants');
10
+ const assert = require('assert');
11
+
12
+ class ValidationErrorsFormatter {
13
+ formatErrors(validationErrors) {
14
+ assert(validationErrors);
15
+ assert(Array.isArray(validationErrors));
16
+
17
+ const errorMessageHeader = NodeTranslationService.getMessage(TRANSLATION_KEYS.COMMAND_OPTIONS.VALIDATION_ERRORS);
18
+ const validationErrorsString = validationErrors.join(lineBreak);
19
+ return `${errorMessageHeader}${lineBreak}${validationErrorsString}`;
20
+ }
21
+ }
22
+
23
+ module.exports = new ValidationErrorsFormatter();
@@ -0,0 +1,39 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+
7
+ const ENCODING = {
8
+ BINARY: 'binary'
9
+ }
10
+
11
+ const EVENT = {
12
+ CLOSE: 'close',
13
+ CONNECT: 'connect',
14
+ DATA: 'data',
15
+ END: 'end',
16
+ ERROR: 'error',
17
+ TIMEOUT: 'timeout',
18
+ };
19
+
20
+ const HEADER = {
21
+ CONTENT_TYPE: 'content-type'
22
+ }
23
+
24
+ const PROTOCOL = {
25
+ HTTP: 'http:',
26
+ HTTPS: 'https:',
27
+ };
28
+
29
+ const METHOD = {
30
+ CONNECT: 'CONNECT',
31
+ };
32
+
33
+ module.exports = {
34
+ ENCODING,
35
+ EVENT,
36
+ HEADER,
37
+ PROTOCOL,
38
+ METHOD
39
+ }
@@ -0,0 +1,110 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+
7
+ const http = require('http');
8
+ const { URL } = require('url');
9
+ const tls = require('tls');
10
+ const net = require('net');
11
+ const { PROTOCOL, EVENT, METHOD } = require('./HttpConstants');
12
+
13
+ class ProxyAgent {
14
+ constructor(proxyString, agentOptions) {
15
+ this.proxyString = proxyString;
16
+ this.agentOptions = agentOptions;
17
+ this.initProxyURL();
18
+ }
19
+
20
+ initProxyURL() {
21
+ try {
22
+ const proxy = new URL(this.proxyString);
23
+ proxy.host = proxy.hostname || proxy.host;
24
+ proxy.port = +proxy.port || (proxy.protocol.toLowerCase() === PROTOCOL.HTTPS ? 443 : 80);
25
+ this.proxyURL = proxy;
26
+ } catch (err) {
27
+ throw new ProxyAgentError(`${err.input} ${ERROR_MESSAGES.BAD_PROXY}`);
28
+ }
29
+ }
30
+
31
+ addRequest(req, options) {
32
+ req.shouldKeepAlive = false;
33
+
34
+ this.createConnection(options)
35
+ .then((socket) => {
36
+ req.onSocket(socket);
37
+ })
38
+ .catch((err) => {
39
+ req.emit(EVENT.ERROR, err);
40
+ });
41
+ }
42
+
43
+ createConnection(options) {
44
+ return new Promise((resolve, reject) => {
45
+ const useSSL = options.protocol ? options.protocol.toLowerCase() === PROTOCOL.HTTPS : false;
46
+ if (useSSL && this.agentOptions.tunnel === true) {
47
+ if (options.port === 80) options.port = 443;
48
+ // CONNECT Method
49
+ const req = http.request({
50
+ host: this.proxyURL.hostname,
51
+ port: this.proxyURL.port,
52
+ auth: this.proxyURL.auth,
53
+ method: METHOD.CONNECT,
54
+ path: (options.hostname || options.host) + ':' + options.port,
55
+ headers: {
56
+ host: options.host,
57
+ },
58
+ timeout: this.agentOptions.timeout,
59
+ });
60
+
61
+ req.once(EVENT.CONNECT, (res, socket, head) => {
62
+ const tunnel = tls.connect({
63
+ socket: socket,
64
+ host: options.hostname || options.host,
65
+ port: +options.port,
66
+ servername: options.servername || options.host,
67
+ });
68
+ resolve(tunnel);
69
+ });
70
+
71
+ req.once(EVENT.TIMEOUT, () => {
72
+ req.destroy();
73
+ reject(new ProxyAgentError(ERROR_MESSAGES.CONNECT_TIMEOUT));
74
+ });
75
+
76
+ req.once(EVENT.ERROR, (err) => {
77
+ reject(err);
78
+ });
79
+
80
+ req.once(EVENT.CLOSE, () => {
81
+ reject(new ProxyAgentError(ERROR_MESSAGES.SERVER_CLOSE_EVENT));
82
+ });
83
+
84
+ req.end();
85
+ } else {
86
+ const socket = net.connect({
87
+ host: this.proxyURL.host,
88
+ port: this.proxyURL.port === '' ? 80 : +this.proxyURL.port,
89
+ auth: this.proxyURL.auth,
90
+ });
91
+ resolve(socket);
92
+ }
93
+ });
94
+ }
95
+ }
96
+
97
+ class ProxyAgentError extends Error {
98
+ constructor(message) {
99
+ super(message);
100
+ this.name = 'ProxyAgentError';
101
+ }
102
+ }
103
+
104
+ const ERROR_MESSAGES = {
105
+ CONNECT_TIMEOUT: 'CONNECT request timeout.',
106
+ SERVER_CLOSE_EVENT: 'Tunnel failed. Socket closed prematurely.',
107
+ BAD_PROXY: 'is not a valid value for proxy.'
108
+ }
109
+
110
+ module.exports = ProxyAgent;
@@ -0,0 +1,205 @@
1
+ /*
2
+ ** Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
3
+ ** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
4
+ */
5
+ 'use strict';
6
+
7
+ const path = require('path');
8
+ const ApplicationConstants = require('../ApplicationConstants');
9
+ const FileSystemService = require('../services/FileSystemService');
10
+ const NodeTranslationService = require('../services/NodeTranslationService');
11
+
12
+ const VALIDATION_RESULT_FAILURE = (validationError) => ({
13
+ result: false,
14
+ validationMessage: validationError,
15
+ });
16
+ const VALIDATION_RESULT_SUCCESS = { result: true };
17
+
18
+ const { ANSWERS_VALIDATION_MESSAGES, COMMAND_OPTIONS } = require('../services/TranslationKeys');
19
+
20
+ const ALPHANUMERIC_LOWERCASE_REGEX = '[a-z0-9]+';
21
+ const ALPHANUMERIC_LOWERCASE_WHOLE_REGEX = `^${ALPHANUMERIC_LOWERCASE_REGEX}$`;
22
+ const ALPHANUMERIC_HYPHEN_UNDERSCORE = /^[a-zA-Z0-9-_]+$/;
23
+ const ALPHANUMERIC_HYPHEN_UNDERSCORE_EXTENDED = /^[a-zA-Z0-9-_ ]+([.]*[a-zA-Z0-9-_ ]+)*$/;
24
+ const SCRIPT_ID_REGEX = /^[a-z0-9_]+$/;
25
+ const STRING_WITH_SPACES_REGEX = /\s/;
26
+ const XML_FORBIDDEN_CHARACTERS_REGEX = /[<>&'"]/;
27
+ const FILENAME_FORBIDDEN_CHARACTERS_REGEX = /[\\/:*?"<>|]/;
28
+ const DOT_AT_THE_END_OF_A_STRING_REGEX = /^.*\.$/;
29
+ const PROJECT_VERSION_FORMAT_REGEX = '^\\d+(\\.\\d+){2}$';
30
+ const SUITEAPP_ID_FORMAT_REGEX = '^' + ALPHANUMERIC_LOWERCASE_REGEX + '(\\.' + ALPHANUMERIC_LOWERCASE_REGEX + '){2}$';
31
+ const SUITEAPP_PUBLISHER_ID_FORMAT_REGEX = '^' + ALPHANUMERIC_LOWERCASE_REGEX + '\\.' + ALPHANUMERIC_LOWERCASE_REGEX + '$';
32
+
33
+ const FILE_EXTENSION_JS = '.js';
34
+
35
+ module.exports = {
36
+ showValidationResults(value, ...funcs) {
37
+ for (const func of funcs) {
38
+ const validationOutput = func(value);
39
+ if (!validationOutput.result) {
40
+ return validationOutput.validationMessage;
41
+ }
42
+ }
43
+ return true;
44
+ },
45
+
46
+ validateFieldIsNotEmpty(fieldValue) {
47
+ return fieldValue !== ''
48
+ ? VALIDATION_RESULT_SUCCESS
49
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.EMPTY_FIELD));
50
+ },
51
+
52
+ validateAlphanumericHyphenUnderscoreExtended(fieldValue) {
53
+ return ALPHANUMERIC_HYPHEN_UNDERSCORE_EXTENDED.test(fieldValue)
54
+ ? VALIDATION_RESULT_SUCCESS
55
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.ALPHANUMERIC_HYPHEN_UNDERSCORE_EXTENDED));
56
+ },
57
+
58
+ validateFieldHasNoSpaces(fieldValue) {
59
+ return !STRING_WITH_SPACES_REGEX.test(fieldValue)
60
+ ? VALIDATION_RESULT_SUCCESS
61
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FIELD_HAS_SPACES));
62
+ },
63
+
64
+ validateFieldIsLowerCase(fieldOptionId, fieldValue) {
65
+ return fieldValue.match(ALPHANUMERIC_LOWERCASE_WHOLE_REGEX)
66
+ ? VALIDATION_RESULT_SUCCESS
67
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FIELD_NOT_LOWER_CASE, fieldOptionId));
68
+ },
69
+
70
+ validatePublisherId(fieldValue) {
71
+ return fieldValue.match(SUITEAPP_PUBLISHER_ID_FORMAT_REGEX)
72
+ ? VALIDATION_RESULT_SUCCESS
73
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.PUBLISHER_ID_FORMAT));
74
+ },
75
+
76
+ validateProjectVersion(fieldValue) {
77
+ return fieldValue.match(PROJECT_VERSION_FORMAT_REGEX)
78
+ ? VALIDATION_RESULT_SUCCESS
79
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.PROJECT_VERSION_FORMAT));
80
+ },
81
+
82
+ validateArrayIsNotEmpty(array) {
83
+ return array.length > 0
84
+ ? VALIDATION_RESULT_SUCCESS
85
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.CHOOSE_OPTION));
86
+ },
87
+
88
+ validateSuiteApp(fieldValue) {
89
+ let notEmpty =
90
+ fieldValue !== ''
91
+ ? VALIDATION_RESULT_SUCCESS
92
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.EMPTY_FIELD));
93
+
94
+ if (notEmpty.result !== true) {
95
+ return notEmpty;
96
+ } else if (!fieldValue.match(SUITEAPP_ID_FORMAT_REGEX)) {
97
+ return VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.APP_ID_FORMAT));
98
+ }
99
+ return VALIDATION_RESULT_SUCCESS;
100
+ },
101
+
102
+ validateScriptId(fieldValue) {
103
+ let notEmpty =
104
+ fieldValue !== ''
105
+ ? VALIDATION_RESULT_SUCCESS
106
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.EMPTY_FIELD));
107
+
108
+ if (notEmpty.result !== true) {
109
+ return notEmpty;
110
+ } else if (!fieldValue.match(SCRIPT_ID_REGEX)) {
111
+ return VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.SCRIPT_ID_FORMAT));
112
+ }
113
+ return VALIDATION_RESULT_SUCCESS;
114
+ },
115
+
116
+ validateXMLCharacters(fieldValue) {
117
+ return !XML_FORBIDDEN_CHARACTERS_REGEX.test(fieldValue)
118
+ ? VALIDATION_RESULT_SUCCESS
119
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FIELD_HAS_XML_FORBIDDEN_CHARACTERS));
120
+ },
121
+
122
+ validateNotUndefined(value, optionName) {
123
+ return value !== undefined
124
+ ? VALIDATION_RESULT_SUCCESS
125
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(COMMAND_OPTIONS.IS_MANDATORY, optionName));
126
+ },
127
+
128
+ validateProjectType(value) {
129
+ return [ApplicationConstants.PROJECT_SUITEAPP, ApplicationConstants.PROJECT_ACP].includes(value)
130
+ ? VALIDATION_RESULT_SUCCESS
131
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.WRONG_PROJECT_TYPE));
132
+ },
133
+
134
+ validateSameAuthID(newAuthID, authID) {
135
+ return authID != newAuthID
136
+ ? VALIDATION_RESULT_SUCCESS
137
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.CURRENT_AUTHID, newAuthID));
138
+ },
139
+
140
+ validateAuthIDNotInList(newAuthID, authIDsList) {
141
+ return !authIDsList.includes(newAuthID)
142
+ ? VALIDATION_RESULT_SUCCESS
143
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.AUTH_ID_ALREADY_USED));
144
+ },
145
+
146
+ validateAlphanumericHyphenUnderscore(fieldValue) {
147
+ return ALPHANUMERIC_HYPHEN_UNDERSCORE.test(fieldValue)
148
+ ? VALIDATION_RESULT_SUCCESS
149
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.ALPHANUMERIC_HYPHEN_UNDERSCORE));
150
+ },
151
+
152
+ validateMaximumLength(fieldValue, maxLength = 40) {
153
+ return fieldValue.length <= maxLength
154
+ ? VALIDATION_RESULT_SUCCESS
155
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.MAX_LENGTH, maxLength));
156
+ },
157
+
158
+ validateNonProductionDomain(fieldValue) {
159
+ return !fieldValue.match(ApplicationConstants.DOMAIN.PRODUCTION.PRODUCTION_DOMAIN_REGEX) ||
160
+ fieldValue.match(ApplicationConstants.DOMAIN.NON_PRODUCTION.F_DOMAIN_REGEX) ||
161
+ fieldValue.match(ApplicationConstants.DOMAIN.NON_PRODUCTION.SNAP_DOMAIN_REGEX)
162
+ ? VALIDATION_RESULT_SUCCESS
163
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.PRODUCTION_DOMAIN));
164
+ },
165
+
166
+ validateNonProductionAccountSpecificDomain(fieldValue) {
167
+ return !fieldValue.match(ApplicationConstants.DOMAIN.PRODUCTION.PRODUCTION_ACCOUNT_SPECIFIC_DOMAIN_REGEX) ||
168
+ fieldValue.match(ApplicationConstants.DOMAIN.NON_PRODUCTION.F_ACCOUNT_SPECIFIC_DOMAIN_REGEX) ||
169
+ fieldValue.match(ApplicationConstants.DOMAIN.NON_PRODUCTION.SNAP_ACCOUNT_SPECIFIC_DOMAIN_REGEX)
170
+ ? VALIDATION_RESULT_SUCCESS
171
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.PRODUCTION_DOMAIN));
172
+ },
173
+
174
+ validateSuiteScriptFileDoesNotExist(parentFolderPath, filename) {
175
+ const filenameParts = path.parse(filename);
176
+ const filenameExtension = filenameParts.ext;
177
+ let filenameWithExtension = filename;
178
+ if (!filenameExtension) {
179
+ filenameWithExtension = filenameWithExtension + FILE_EXTENSION_JS;
180
+ }
181
+
182
+ const fileSystemService = new FileSystemService();
183
+ return !fileSystemService.fileExists(path.join(parentFolderPath, filenameWithExtension))
184
+ ? VALIDATION_RESULT_SUCCESS
185
+ : VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FILE_ALREADY_EXISTS));
186
+ },
187
+
188
+ validateFolderDoesNotExist(path) {
189
+ const fileSystemService = new FileSystemService();
190
+
191
+ return !fileSystemService.folderExists(path)
192
+ ? VALIDATION_RESULT_SUCCESS
193
+ : NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FOLDER_ALREADY_EXISTS, path);
194
+ },
195
+
196
+ validateFileName(filename) {
197
+ if (FILENAME_FORBIDDEN_CHARACTERS_REGEX.test(filename)) {
198
+ return VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FILENAME_CONTAINS_FORBIDDEN_CHARACTERS));
199
+ }
200
+
201
+ return DOT_AT_THE_END_OF_A_STRING_REGEX.test(filename)
202
+ ? VALIDATION_RESULT_FAILURE(NodeTranslationService.getMessage(ANSWERS_VALIDATION_MESSAGES.FILENAME_ENDS_WITH_PERIOD))
203
+ : VALIDATION_RESULT_SUCCESS;
204
+ },
205
+ };