@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,37 @@
1
+ import record from 'N/record';
2
+ import Record from 'N/record/instance';
3
+
4
+ jest.mock('N/record');
5
+ jest.mock('N/record/instance');
6
+
7
+ beforeEach(() => {
8
+ jest.clearAllMocks();
9
+ });
10
+
11
+ describe('Basic jest test with simple assert', () => {
12
+ it('should assert strings are equal', () => {
13
+ const a = 'foobar';
14
+ const b = 'foobar';
15
+ expect(a).toMatch(b);
16
+ });
17
+ });
18
+
19
+ describe('Sample test with provided record module stubs', () => {
20
+ it('should update Sales Order memo field', () => {
21
+ // given
22
+ const salesOrderId = 1352;
23
+ record.load.mockReturnValue(Record);
24
+ Record.save.mockReturnValue(salesOrderId);
25
+
26
+ // when
27
+ let salesOrderRecord = record.load({id: salesOrderId});
28
+ salesOrderRecord.setValue({fieldId: 'memo', value: 'foobar'});
29
+ const updatedSalesOrderId = salesOrderRecord.save({enableSourcing: false});
30
+
31
+ // then
32
+ expect(record.load).toHaveBeenCalledWith({id: salesOrderId});
33
+ expect(Record.setValue).toHaveBeenCalledWith({fieldId: 'memo', value: 'foobar'});
34
+ expect(Record.save).toHaveBeenCalledWith({enableSourcing: false});
35
+ expect(salesOrderId).toBe(updatedSalesOrderId);
36
+ });
37
+ });
@@ -0,0 +1,15 @@
1
+ const SuiteCloudJestUnitTestRunner = require('@oracle/suitecloud-unit-testing/services/SuiteCloudJestUnitTestRunner');
2
+
3
+ module.exports = {
4
+ defaultProjectFolder: 'src',
5
+ commands: {
6
+ "project:deploy": {
7
+ beforeExecuting: async args => {
8
+ await SuiteCloudJestUnitTestRunner.run({
9
+ // Jest configuration options.
10
+ });
11
+ return args;
12
+ },
13
+ },
14
+ },
15
+ };
@@ -0,0 +1,34 @@
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 assert = require('assert');
8
+ const Spinner = require('cli-spinner').Spinner;
9
+
10
+ const SPINNER_STRING = '⠋⠙⠹⠸⠼⠴⠦⠧⠏';
11
+
12
+ module.exports = {
13
+ async executeWithSpinner(context) {
14
+ assert(context.action instanceof Promise, 'Promise is expected');
15
+ assert(context.message, 'Message is mandatory when spinner is enabled');
16
+
17
+ const promise = context.action;
18
+ const message = context.message;
19
+
20
+ const spinner = new Spinner(message);
21
+ // TODO: set spinner string conditionally based on the terminal cli is executed in
22
+ // spinner.setSpinnerString(SPINNER_STRING);
23
+
24
+ try {
25
+ spinner.start();
26
+ const result = await promise;
27
+ spinner.stop(true);
28
+ return result;
29
+ } catch (error) {
30
+ spinner.stop(true);
31
+ throw error;
32
+ }
33
+ },
34
+ };
@@ -0,0 +1,62 @@
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 os = require('os');
7
+ const NodeTranslationService = require('../services/NodeTranslationService');
8
+
9
+ const {
10
+ ACCOUNT_CREDENTIALS: { AUTHID, ACCOUNT_INFO, DOMAIN },
11
+ ACCOUNT_TYPE,
12
+ COMMAND_MANAGE_ACCOUNT: { QUESTIONS_CHOICES },
13
+ } = require('../services/TranslationKeys');
14
+ const ApplicationConstants = require('../ApplicationConstants');
15
+
16
+ const SANDBOX_ACCOUNT_ID_REGEX_PATTERN = '.+_SB\\d*$';
17
+ const RELEASE_PREVIEW_ACCOUNT_ID_REGEX_PATTERN = '.+_RP\\d*$';
18
+
19
+ function getInfoString(accountCredentials) {
20
+ const accountInfo = accountCredentials.accountInfo;
21
+ return (
22
+ NodeTranslationService.getMessage(AUTHID, accountCredentials.authId) +
23
+ os.EOL +
24
+ NodeTranslationService.getMessage(ACCOUNT_INFO.ACCOUNT_NAME, accountInfo.companyName) +
25
+ os.EOL +
26
+ NodeTranslationService.getMessage(ACCOUNT_INFO.ACCOUNT_ID, accountInfo.companyId) +
27
+ os.EOL +
28
+ NodeTranslationService.getMessage(ACCOUNT_INFO.ROLE, accountInfo.roleName) +
29
+ os.EOL +
30
+ NodeTranslationService.getMessage(DOMAIN, accountCredentials.domain) +
31
+ os.EOL +
32
+ NodeTranslationService.getMessage(ACCOUNT_INFO.ACCOUNT_TYPE, _getAccountType(accountInfo.companyId))
33
+ );
34
+ }
35
+
36
+ function _getAccountType(accountId) {
37
+ if (accountId.match(SANDBOX_ACCOUNT_ID_REGEX_PATTERN)) {
38
+ return NodeTranslationService.getMessage(ACCOUNT_TYPE.SANDBOX);
39
+ } else if (accountId.match(RELEASE_PREVIEW_ACCOUNT_ID_REGEX_PATTERN)) {
40
+ return NodeTranslationService.getMessage(ACCOUNT_TYPE.RELEASE_PREVIEW);
41
+ }
42
+ return NodeTranslationService.getMessage(ACCOUNT_TYPE.PRODUCTION);
43
+ }
44
+
45
+ function getListItemString(authID, accountCredentials) {
46
+ const isNotProductionUrl =
47
+ accountCredentials.hostInfo.hostName &&
48
+ !accountCredentials.hostInfo.hostName.match(ApplicationConstants.DOMAIN.PRODUCTION.PRODUCTION_DOMAIN_REGEX) &&
49
+ !accountCredentials.hostInfo.hostName.match(ApplicationConstants.DOMAIN.PRODUCTION.PRODUCTION_ACCOUNT_SPECIFIC_DOMAIN_REGEX);
50
+ const notProductionLabel = isNotProductionUrl
51
+ ? NodeTranslationService.getMessage(QUESTIONS_CHOICES.SELECT_AUTHID.EXISTING_AUTH_ID_URL_NOT_PRODUCTION, accountCredentials.hostInfo.hostName)
52
+ : '';
53
+ const accountInfo = `${accountCredentials.accountInfo.roleName} @ ${accountCredentials.accountInfo.companyName}`;
54
+ return NodeTranslationService.getMessage(
55
+ QUESTIONS_CHOICES.SELECT_AUTHID.EXISTING_AUTH_ID,
56
+ authID,
57
+ accountInfo,
58
+ notProductionLabel
59
+ );
60
+ }
61
+
62
+ module.exports = { getInfoString, getListItemString };
@@ -0,0 +1,55 @@
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
+
6
+ 'use strict';
7
+
8
+ const assert = require('assert');
9
+ const NodeTranslationService = require('../services/NodeTranslationService');
10
+ const ProjectInfoService = require('../services/ProjectInfoService');
11
+ const {
12
+ UTILS: {
13
+ ACCOUNT_SPECIFIC_VALUES_ARGUMENT_HANDLER: { ERRORS },
14
+ },
15
+ } = require('../services/TranslationKeys');
16
+ const { PROJECT_SUITEAPP } = require('../ApplicationConstants');
17
+
18
+ const ACCOUNT_SPECIFIC_VALUES = 'accountspecificvalues';
19
+ const ACCOUNT_SPECIFIC_VALUES_OPTIONS = {
20
+ ERROR: 'ERROR',
21
+ WARNING: 'WARNING',
22
+ };
23
+
24
+ function validate(args, projectFolder) {
25
+ const projectInfoService = new ProjectInfoService(projectFolder);
26
+
27
+ if (args.hasOwnProperty(ACCOUNT_SPECIFIC_VALUES)) {
28
+ assert(typeof args[ACCOUNT_SPECIFIC_VALUES] === 'string', NodeTranslationService.getMessage(ERRORS.WRONG_ACCOUNT_SPECIFIC_VALUES_OPTION));
29
+ if (projectInfoService.getProjectType() === PROJECT_SUITEAPP) {
30
+ throw NodeTranslationService.getMessage(ERRORS.APPLY_ACCOUNT_SPECIFIC_VALUES_IN_SUITEAPP);
31
+ }
32
+ }
33
+ }
34
+
35
+ function transformArgument(args) {
36
+ const newArgs = {};
37
+
38
+ if (args.hasOwnProperty(ACCOUNT_SPECIFIC_VALUES)) {
39
+ const upperCaseValue = args[ACCOUNT_SPECIFIC_VALUES].toUpperCase();
40
+ switch (upperCaseValue) {
41
+ case ACCOUNT_SPECIFIC_VALUES_OPTIONS.WARNING:
42
+ newArgs[ACCOUNT_SPECIFIC_VALUES] = ACCOUNT_SPECIFIC_VALUES_OPTIONS.WARNING;
43
+ break;
44
+ case ACCOUNT_SPECIFIC_VALUES_OPTIONS.ERROR:
45
+ newArgs[ACCOUNT_SPECIFIC_VALUES] = ACCOUNT_SPECIFIC_VALUES_OPTIONS.ERROR;
46
+ break;
47
+ default:
48
+ throw NodeTranslationService.getMessage(ERRORS.WRONG_ACCOUNT_SPECIFIC_VALUES_OPTION);
49
+ }
50
+ }
51
+
52
+ return newArgs;
53
+ }
54
+
55
+ module.exports = { validate, transformArgument, ACCOUNT_SPECIFIC_VALUES_OPTIONS, ACCOUNT_SPECIFIC_VALUES };
@@ -0,0 +1,47 @@
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 { lineBreak } = require('../loggers/LoggerOsConstants');
8
+ const disableInIntegrationMode = 'disableInIntegrationMode';
9
+
10
+ module.exports = {
11
+ getErrorMessagesString: actionResult => {
12
+ return actionResult.errorMessages.join(lineBreak);
13
+ },
14
+
15
+ logResultMessage: (actionResult, log) => {
16
+ if (actionResult.resultMessage) {
17
+ log.result(actionResult.resultMessage);
18
+ }
19
+ },
20
+ extractNotInteractiveCommand: (commandName, commandMetadata, actionResult) => {
21
+ const options = _generateOptionsString(commandMetadata, actionResult);
22
+ return `${commandName} ${options}`;
23
+ },
24
+
25
+ };
26
+
27
+ function _generateOptionsString(commandMetadata, actionResult) {
28
+ const flagsReducer = (accumulator, key) => `${accumulator}--${key} `;
29
+ const commandReducer = (accumulator, key) => `${accumulator} --${key} ${actionResult.commandParameters[key]}`;
30
+
31
+ const flags = actionResult.commandFlags && actionResult.commandFlags.length > 0
32
+ ? `${actionResult.commandFlags.filter(key => _hasToBeShown(key, commandMetadata.options)).reduce(flagsReducer, '')}`.trim()
33
+ : ' ';
34
+
35
+ return actionResult.commandParameters
36
+ ? Object.keys(actionResult.commandParameters)
37
+ .filter(key => _hasToBeShown(key, commandMetadata.options))
38
+ .reduce(commandReducer, flags).trim()
39
+ : '';
40
+ }
41
+
42
+ function _hasToBeShown(key, options) {
43
+
44
+ return options.hasOwnProperty(key)
45
+ && options[key].hasOwnProperty(disableInIntegrationMode)
46
+ && options[key][disableInIntegrationMode] === false;
47
+ }
@@ -0,0 +1,41 @@
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
+
6
+ 'use strict';
7
+
8
+ const NodeTranslationService = require('../services/NodeTranslationService');
9
+ const ProjectInfoService = require('../services/ProjectInfoService');
10
+ const { LINKS, PROJECT_ACP } = require('../ApplicationConstants');
11
+
12
+ const APPLY_INSTALLATION_PREFERENCES = 'applyinstallprefs';
13
+
14
+ const {
15
+ COMMAND_DEPLOY: {
16
+ MESSAGES: { NOT_ASKING_INSTALLATION_PREFERENCES_REASON },
17
+ },
18
+ UTILS: {
19
+ APPLY_INSTALLATION_PREFERENCES_ARGUMENT_HANDLER: { INSTALLATION_PREFERENCES_ERRORS },
20
+ ERRORS: { COMMAND },
21
+ },
22
+ } = require('../services/TranslationKeys');
23
+
24
+ function validate(args, projectFolder, commandName) {
25
+ const projectInfoService = new ProjectInfoService(projectFolder);
26
+
27
+ if (args[APPLY_INSTALLATION_PREFERENCES] && projectInfoService.getProjectType() === PROJECT_ACP) {
28
+ throw NodeTranslationService.getMessage(INSTALLATION_PREFERENCES_ERRORS.APPLY_INSTALLATION_PREFERENCES_IN_ACP);
29
+ }
30
+
31
+ if (args[APPLY_INSTALLATION_PREFERENCES] && !projectInfoService.hasLockAndHideFiles()) {
32
+ const errorMessage = NodeTranslationService.getMessage(
33
+ NOT_ASKING_INSTALLATION_PREFERENCES_REASON,
34
+ LINKS.HOW_TO.CREATE_INSTALLATION_PREFERENCES
35
+ );
36
+
37
+ throw NodeTranslationService.getMessage(COMMAND, commandName, errorMessage);
38
+ }
39
+ }
40
+
41
+ module.exports = { validate };
@@ -0,0 +1,262 @@
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 FileUtils = require('./FileUtils');
8
+ const assert = require('assert');
9
+ const NodeTranslationService = require('../services/NodeTranslationService');
10
+ const { ERRORS, UTILS } = require('../services/TranslationKeys');
11
+ const { FILES } = require('../ApplicationConstants');
12
+ const { ActionResult } = require('../services/actionresult/ActionResult');
13
+ const AuthenticateActionResult = require('../services/actionresult/AuthenticateActionResult');
14
+ const { executeWithSpinner } = require('../ui/CliSpinner');
15
+ const path = require('path');
16
+ const SdkExecutionContext = require('../SdkExecutionContext');
17
+ const SdkOperationResultUtils = require('../utils/SdkOperationResultUtils');
18
+ const SdkExecutor = require('../SdkExecutor');
19
+ const { lineBreak } = require('../loggers/LoggerOsConstants')
20
+ const ExecutionEnvironmentContext = require('../ExecutionEnvironmentContext');
21
+ const SdkOperationResult = require('../utils/SdkOperationResult');
22
+ const {ENV_VARS} = require('../ApplicationConstants');
23
+
24
+ const DEFAULT_AUTH_ID_PROPERTY = 'defaultAuthId';
25
+
26
+ const COMMANDS = {
27
+ AUTHENTICATE: {
28
+ SDK_COMMAND: 'authenticate',
29
+ PARAMS: {
30
+ AUTH_ID: 'authid',
31
+ ACCOUNT: 'account',
32
+ TOKEN_ID: 'tokenid',
33
+ TOKEN_SECRET: 'tokensecret',
34
+ URL: 'url',
35
+ },
36
+ MODES: {
37
+ OAUTH: 'OAUTH',
38
+ REUSE: 'REUSE',
39
+ CLIENT_CREDENTIALS: 'CLIENT_CREDENTIALS'
40
+ },
41
+ },
42
+ AUTHENTICATE_CI: {
43
+ SDK_COMMAND: 'authenticateci',
44
+ PARAMS: {
45
+ ACCOUNT: 'account',
46
+ AUTH_ID: 'authid',
47
+ CERTIFICATEID: 'certificateid',
48
+ PRIVATEKEYPATH: 'privatekeypath',
49
+ URL: 'url',
50
+ }
51
+ },
52
+ MANAGEAUTH: {
53
+ SDK_COMMAND: 'manageauth',
54
+ },
55
+ INSPECT_AUTHORIZATION: {
56
+ SDK_COMMAND: 'inspectauthorization',
57
+ PARAMS: {
58
+ AUTH_ID: 'authid',
59
+ }
60
+ },
61
+ REFRESH_AUTHORIZATION: {
62
+ SDK_COMMAND: 'refreshauthorization',
63
+ PARAMS: {
64
+ AUTH_ID: 'authid',
65
+ }
66
+ },
67
+ FORCE_REFRESH_AUTHORIZATION: {
68
+ SDK_COMMAND: 'forcerefreshauthorization',
69
+ PARAMS: {
70
+ AUTH_ID: 'authid',
71
+ }
72
+ },
73
+ };
74
+
75
+ const FLAGS = {
76
+ LIST: 'list'
77
+ };
78
+
79
+ function setDefaultAuthentication(projectFolder, authId) {
80
+ try {
81
+ // nest the values into a DEFAULT_AUTH_ID_PROPERTY property
82
+ const projectConfiguration = {
83
+ [DEFAULT_AUTH_ID_PROPERTY]: authId,
84
+ };
85
+ FileUtils.create(path.join(projectFolder, FILES.PROJECT_JSON), projectConfiguration);
86
+ } catch (error) {
87
+ const errorMessage = error != null && error.message ? NodeTranslationService.getMessage(ERRORS.ADD_ERROR_LINE, error.message) : '';
88
+ throw NodeTranslationService.getMessage(ERRORS.WRITING_PROJECT_JSON, errorMessage);
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @description - Looks at the environment for the value. This should be settled after the command is setup and launched.
94
+ * - only call this internally before the command is generated
95
+ * @deprecated - no new commands should call this directly
96
+ * @returns {string|void}
97
+ */
98
+ function getProjectDefaultAuthId() {
99
+ // look in the environment first
100
+ return process.env[ENV_VARS.SUITECLOUD_AUTHID];
101
+ }
102
+
103
+ async function getAuthIds(sdkPath) {
104
+ const sdkExecutor = new SdkExecutor(sdkPath);
105
+ const getAuthListContext = SdkExecutionContext.Builder.forCommand(COMMANDS.MANAGEAUTH.SDK_COMMAND).integration().addFlag(FLAGS.LIST).build();
106
+
107
+ const operationResult = await executeWithSpinner({
108
+ action: sdkExecutor.execute(getAuthListContext),
109
+ message: NodeTranslationService.getMessage(UTILS.AUTHENTICATION.LOADING_AUTHIDS),
110
+ }).catch((error) => {
111
+ return ActionResult.Builder.withErrors([error]).build();
112
+ });
113
+ return operationResult.status === SdkOperationResultUtils.STATUS.SUCCESS
114
+ ? ActionResult.Builder.withData(operationResult.data).build()
115
+ : ActionResult.Builder.withErrors(operationResult.errorMessages).build();
116
+ }
117
+
118
+ async function authenticateWithOauth(params, sdkPath, projectFolder, cancelToken, executionEnvironmentContext) {
119
+ let authId = params.authid;
120
+ const sdkExecutor = new SdkExecutor(sdkPath, executionEnvironmentContext);
121
+ const contextBuilder = SdkExecutionContext.Builder.forCommand(COMMANDS.AUTHENTICATE.SDK_COMMAND)
122
+ .integration()
123
+ .addParam(COMMANDS.AUTHENTICATE.PARAMS.AUTH_ID, authId);
124
+
125
+ if (params.url) {
126
+ contextBuilder.addParam(COMMANDS.AUTHENTICATE.PARAMS.URL, params.url);
127
+ }
128
+ const oauthContext = contextBuilder.build();
129
+ return executeWithSpinner({
130
+ action: sdkExecutor.execute(oauthContext, cancelToken),
131
+ message: NodeTranslationService.getMessage(UTILS.AUTHENTICATION.STARTING_OAUTH_FLOW),
132
+ })
133
+ .then((operationResult) => {
134
+ if (operationResult.status === SdkOperationResultUtils.STATUS.ERROR) {
135
+ return AuthenticateActionResult.Builder.withErrors(operationResult.errorMessages)
136
+ .withCommandParameters(oauthContext.getParams())
137
+ .build();
138
+ }
139
+ setDefaultAuthentication(projectFolder, authId);
140
+ return AuthenticateActionResult.Builder.success()
141
+ .withMode(COMMANDS.AUTHENTICATE.MODES.OAUTH)
142
+ .withAuthId(authId)
143
+ .withAccountInfo(operationResult.data.accountInfo)
144
+ .withCommandParameters(oauthContext.getParams())
145
+ .build();
146
+ })
147
+ .catch((error) => AuthenticateActionResult.Builder.withErrors([error]).build());
148
+ }
149
+
150
+ async function authenticateCi(params, sdkPath, projectFolder, executionEnvironmentContext) {
151
+ const authId = params.authid;
152
+ const sdkExecutor = new SdkExecutor(sdkPath, executionEnvironmentContext);
153
+ const contextBuilder = SdkExecutionContext.Builder.forCommand(COMMANDS.AUTHENTICATE_CI.SDK_COMMAND)
154
+ .integration()
155
+ .addParam(COMMANDS.AUTHENTICATE_CI.PARAMS.AUTH_ID, authId)
156
+ .addParam(COMMANDS.AUTHENTICATE_CI.PARAMS.ACCOUNT, params.account)
157
+ .addParam(COMMANDS.AUTHENTICATE_CI.PARAMS.CERTIFICATEID, params.certificateid)
158
+ .addParam(COMMANDS.AUTHENTICATE_CI.PARAMS.PRIVATEKEYPATH, params.privatekeypath)
159
+
160
+ if (params.domain) {
161
+ contextBuilder.addParam(COMMANDS.AUTHENTICATE_CI.PARAMS.URL, params.domain);
162
+ }
163
+
164
+ const authenticateCiExecutionContext = contextBuilder.build();
165
+ const operationResult = await executeWithSpinner({
166
+ action: sdkExecutor.execute(authenticateCiExecutionContext),
167
+ message: NodeTranslationService.getMessage(UTILS.AUTHENTICATION.AUTHENTICATING),
168
+ });
169
+ if (operationResult.status === SdkOperationResultUtils.STATUS.ERROR) {
170
+ return AuthenticateActionResult.Builder.withErrors(operationResult.errorMessages).build();
171
+ }
172
+ setDefaultAuthentication(projectFolder, authId);
173
+ return AuthenticateActionResult.Builder.success()
174
+ .withMode(COMMANDS.AUTHENTICATE.MODES.CLIENT_CREDENTIALS)
175
+ .withAuthId(authId)
176
+ .withAccountInfo(operationResult.data.accountInfo)
177
+ .withCommandParameters(authenticateCiExecutionContext.getParams())
178
+ .build();
179
+ }
180
+
181
+ async function selectAuthenticationCI(authId, sdkPath, projectFolder) {
182
+ //Validate authId exists into the CI file
183
+ const authIDActionResult = await getAuthIds(sdkPath);
184
+ if (!authIDActionResult.isSuccess()) {
185
+ throw authIDActionResult.errorMessages;
186
+ }
187
+ const authIDs = Object.keys(authIDActionResult.data);
188
+
189
+ if (authIDs.includes(authId)) {
190
+ setDefaultAuthentication(projectFolder, authId);
191
+ return AuthenticateActionResult.Builder.success()
192
+ .withMode(COMMANDS.AUTHENTICATE.MODES.REUSE)
193
+ .withAuthId(authId)
194
+ .withAccountInfo(authIDActionResult.data[authId].accountInfo)
195
+ .build();
196
+ } else {
197
+ throw NodeTranslationService.getMessage(NOT_EXISTING_AUTH_ID, authId);
198
+ }
199
+ }
200
+
201
+ /**
202
+ *
203
+ * @param {String} authid
204
+ * @param {String} sdkPath
205
+ * @param {ExecutionEnvironmentContext} executionEnvironmentContext
206
+ * @returns {Promise<SdkOperationResult>}
207
+ */
208
+ async function checkIfReauthorizationIsNeeded(authid, sdkPath, executionEnvironmentContext) {
209
+ const sdkExecutor = new SdkExecutor(sdkPath, executionEnvironmentContext);
210
+ const inspectAuthContext = SdkExecutionContext.Builder
211
+ .forCommand(COMMANDS.INSPECT_AUTHORIZATION.SDK_COMMAND)
212
+ .addParam(COMMANDS.INSPECT_AUTHORIZATION.PARAMS.AUTH_ID, authid)
213
+ .integration()
214
+ .build();
215
+ const result = await sdkExecutor.execute(inspectAuthContext);
216
+ return new SdkOperationResult(result);
217
+ }
218
+
219
+ /**
220
+ *
221
+ * @param {String} authid
222
+ * @param {String} sdkPath
223
+ * @param {ExecutionEnvironmentContext} executionEnvironmentContext
224
+ * @returns {Promise<SdkOperationResult>}
225
+ */
226
+ async function refreshAuthorization(authid, sdkPath, executionEnvironmentContext) {
227
+ const sdkExecutor = new SdkExecutor(sdkPath, executionEnvironmentContext);
228
+ const reauthorizeAuthContext = SdkExecutionContext.Builder
229
+ .forCommand(COMMANDS.REFRESH_AUTHORIZATION.SDK_COMMAND)
230
+ .addParam(COMMANDS.REFRESH_AUTHORIZATION.PARAMS.AUTH_ID, authid)
231
+ .integration()
232
+ .build();
233
+ const result = await executeWithSpinner({
234
+ action: sdkExecutor.execute(reauthorizeAuthContext),
235
+ message: NodeTranslationService.getMessage(UTILS.AUTHENTICATION.AUTHORIZING)
236
+ });
237
+ return new SdkOperationResult(result);
238
+ }
239
+
240
+ /**
241
+ *
242
+ * @param {String} authid
243
+ * @param {String} sdkPath
244
+ * @param {ExecutionEnvironmentContext} executionEnvironmentContext
245
+ * @returns {Promise<SdkOperationResult>} with data that contains the refreshed accessToken
246
+ */
247
+ async function forceRefreshAuthorization(authid, sdkPath, executionEnvironmentContext) {
248
+ const sdkExecutor = new SdkExecutor(sdkPath, executionEnvironmentContext);
249
+ const reauthorizeAuthContext = SdkExecutionContext.Builder
250
+ .forCommand(COMMANDS.FORCE_REFRESH_AUTHORIZATION.SDK_COMMAND)
251
+ .addParam(COMMANDS.FORCE_REFRESH_AUTHORIZATION.PARAMS.AUTH_ID, authid)
252
+ .integration()
253
+ .build();
254
+ const result = await executeWithSpinner({
255
+ action: sdkExecutor.execute(reauthorizeAuthContext),
256
+ message: NodeTranslationService.getMessage(UTILS.AUTHENTICATION.AUTHORIZING)
257
+ });
258
+
259
+ return new SdkOperationResult(result);
260
+ }
261
+
262
+ module.exports = { setDefaultAuthentication, getProjectDefaultAuthId, getAuthIds, authenticateWithOauth, authenticateCi, selectAuthenticationCI, checkIfReauthorizationIsNeeded, refreshAuthorization, forceRefreshAuthorization, COMMANDS};
@@ -0,0 +1,50 @@
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 assert = require('assert');
8
+
9
+ class CommandUtils {
10
+ get INQUIRER_TYPES() {
11
+ return {
12
+ CHECKBOX: 'checkbox',
13
+ INPUT: 'input',
14
+ LIST: 'list',
15
+ PASSWORD: 'password',
16
+ PASSWORD_MASK: '*',
17
+ };
18
+ }
19
+
20
+ extractKeysFromObject(object, keys) {
21
+ return keys.reduce((obj, key) => {
22
+ if (object[key]) {
23
+ obj[key] = object[key];
24
+ }
25
+ return obj;
26
+ }, {});
27
+ }
28
+
29
+ extractCommandOptions(answers, commandMetadata) {
30
+ assert(answers);
31
+ assert(commandMetadata);
32
+ assert(commandMetadata.options);
33
+
34
+ const commandOptions = Object.keys(commandMetadata.options);
35
+ return this.extractKeysFromObject(answers, commandOptions);
36
+ }
37
+
38
+ quoteString(string) {
39
+ return `"${string}"`;
40
+ }
41
+
42
+ unquoteString(stringValue) {
43
+ if (stringValue.length > 1 && stringValue.startsWith('"') && stringValue.endsWith('"')) {
44
+ return stringValue.slice(1, -1);
45
+ }
46
+ return stringValue;
47
+ }
48
+ }
49
+
50
+ module.exports = new CommandUtils();
@@ -0,0 +1,41 @@
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 crypto = require('crypto');
8
+ const ALGORITHM = 'aes-256-cbc';
9
+ const ENCRYPTION_KEY_BUFFER_LENGTH = 16;
10
+ const IV_LENGTH = 16;
11
+ const HEX = 'hex';
12
+ const DELIMITER = ':';
13
+
14
+ function encrypt(text, key) {
15
+ const iv = crypto.randomBytes(IV_LENGTH);
16
+ const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(key), iv);
17
+ let encrypted = cipher.update(text);
18
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
19
+
20
+ return iv.toString(HEX) + DELIMITER + encrypted.toString(HEX);
21
+ }
22
+
23
+ function decrypt(text, key) {
24
+ const textParts = text.split(DELIMITER);
25
+ const iv = Buffer.from(textParts.shift(), HEX);
26
+ const encryptedText = Buffer.from(textParts.join(DELIMITER), HEX);
27
+ const decipher = crypto.createDecipheriv(ALGORITHM, Buffer.from(key), iv);
28
+ let decrypted = decipher.update(encryptedText);
29
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
30
+
31
+ return decrypted.toString();
32
+ }
33
+
34
+ function generateRandomKey() {
35
+ return crypto
36
+ .randomBytes(ENCRYPTION_KEY_BUFFER_LENGTH)
37
+ .toString(HEX)
38
+ .substr(0, 32);
39
+ }
40
+
41
+ module.exports = { decrypt, encrypt, generateRandomKey };
@@ -0,0 +1,33 @@
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 CLIException = require('../CLIException');
9
+ const { COMMAND_OPTIONS } = require('../services/TranslationKeys');
10
+ const ValidationErrorsFormatter = require('../utils/ValidationErrorsFormatter');
11
+
12
+ function unwrapExceptionMessage(exception) {
13
+ return exception.getErrorMessage ? exception.getErrorMessage() : exception;
14
+ }
15
+
16
+ function unwrapInformationMessage(exception) {
17
+ return exception.getInfoMessage ? exception.getInfoMessage() : '';
18
+ }
19
+
20
+ function throwValidationException(errorMessages, runInInteractiveMode, commandMetadata) {
21
+ const formattedError = ValidationErrorsFormatter.formatErrors(errorMessages);
22
+ if (!runInInteractiveMode && commandMetadata.supportsInteractiveMode) {
23
+ const suggestedCommandMessage = NodeTranslationService.getMessage(
24
+ COMMAND_OPTIONS.VALIDATION_ERRORS_INTERACTIVE_SUGGESTION,
25
+ commandMetadata.name
26
+ );
27
+ throw new CLIException(formattedError, suggestedCommandMessage);
28
+ }
29
+
30
+ throw new CLIException(formattedError);
31
+ }
32
+
33
+ module.exports = { unwrapExceptionMessage, unwrapInformationMessage, throwValidationException };