@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,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
+ 'use strict';
6
+
7
+ const { ActionResult } = require('../../../services/actionresult/ActionResult');
8
+ const BaseAction = require('../../base/BaseAction');
9
+ const SdkExecutionContext = require('../../../SdkExecutionContext');
10
+ const executeWithSpinner = require('../../../ui/CliSpinner').executeWithSpinner;
11
+ const NodeTranslationService = require('../../../services/NodeTranslationService');
12
+ const CommandUtils = require('../../../utils/CommandUtils');
13
+ const SdkOperationResultUtils = require('../../../utils/SdkOperationResultUtils');
14
+
15
+ const {
16
+ COMMAND_ADDDEPENDENCIES: { MESSAGES },
17
+ } = require('../../../services/TranslationKeys');
18
+
19
+ const COMMAND_OPTIONS = {
20
+ AUTH_ID: 'authid',
21
+ ALL: 'all',
22
+ PROJECT: 'project',
23
+ };
24
+
25
+ module.exports = class AddDependenciesAction extends BaseAction {
26
+ constructor(options) {
27
+ super(options);
28
+ }
29
+
30
+ preExecute(params) {
31
+ params[COMMAND_OPTIONS.PROJECT] = CommandUtils.quoteString(this._projectFolder);
32
+ return params;
33
+ }
34
+
35
+ async execute(params) {
36
+ try {
37
+ const executionContext = SdkExecutionContext.Builder.forCommand(this._commandMetadata.sdkCommand)
38
+ .integration()
39
+ .addParams(params)
40
+ .addFlag(COMMAND_OPTIONS.ALL)
41
+ .build();
42
+
43
+ const operationResult = await executeWithSpinner({
44
+ action: this._sdkExecutor.execute(executionContext),
45
+ message: NodeTranslationService.getMessage(MESSAGES.ADDING_DEPENDENCIES),
46
+ });
47
+
48
+ return operationResult.status === SdkOperationResultUtils.STATUS.SUCCESS
49
+ ? ActionResult.Builder.withData(operationResult.data).withResultMessage(operationResult.resultMessage).build()
50
+ : ActionResult.Builder.withErrors(operationResult.errorMessages).build();
51
+ } catch (error) {
52
+ return ActionResult.Builder.withErrors([error]).build();
53
+ }
54
+ }
55
+ };
@@ -0,0 +1,19 @@
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 Command = require('../../Command');
8
+ const AddDependenciesAction = require('./AddDependenciesAction');
9
+ const AddDependenciesOutputHandler = require('./AddDependenciesOutputHandler');
10
+
11
+ module.exports = {
12
+ create(options) {
13
+ return Command.Builder.withOptions(options)
14
+ .withAction(AddDependenciesAction)
15
+ .withOutput(AddDependenciesOutputHandler)
16
+ .neverInteractive()
17
+ .build();
18
+ }
19
+ };
@@ -0,0 +1,114 @@
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 BaseOutputHandler = require('../../base/BaseOutputHandler');
7
+ const NodeTranslationService = require('../../../services/NodeTranslationService');
8
+
9
+ const {
10
+ COMMAND_ADDDEPENDENCIES: { MESSAGES },
11
+ } = require('../../../services/TranslationKeys');
12
+
13
+ const DEPENDENCY_TYPES = {
14
+ FEATURE: {
15
+ name: 'FEATURE',
16
+ prefix: 'Feature -',
17
+ },
18
+ FILE: {
19
+ name: 'FILE',
20
+ prefix: 'File -',
21
+ },
22
+ FOLDER: {
23
+ name: 'FOLDER',
24
+ prefix: 'Folder -',
25
+ },
26
+ OBJECT: {
27
+ name: 'OBJECT',
28
+ prefix: 'Object -',
29
+ },
30
+ PLATFORMEXTENSION: {
31
+ name: 'PLATFORMEXTENSION',
32
+ prefix: 'Platform Extension -',
33
+ },
34
+ };
35
+
36
+ const FEATURE_REQUIRED = 'required';
37
+ const FEATURE_OPTIONAL = 'optional';
38
+
39
+ const OBJECT_REFERENCE_ATTRIBUTES = {
40
+ APP_ID: 'appId=',
41
+ BUNDLE_ID: 'bundleId=',
42
+ OBJECT_TYPE: 'objectType=',
43
+ SCRIPT_ID: 'scriptId=',
44
+ };
45
+
46
+ const OBJECT_CONTAINER_PREFIX = {
47
+ BUNDLE: 'Bundle',
48
+ SUITEAPP: 'Application',
49
+ };
50
+
51
+ module.exports = class AddDependenciesOutputFormatter extends BaseOutputHandler {
52
+ constructor(options) {
53
+ super(options);
54
+ }
55
+
56
+ parse(actionResult) {
57
+ if (actionResult.data.length === 0) {
58
+ this._log.result(NodeTranslationService.getMessage(MESSAGES.NO_UNRESOLVED_DEPENDENCIES));
59
+ return actionResult;
60
+ }
61
+
62
+ this._log.result(NodeTranslationService.getMessage(MESSAGES.DEPENDENCIES_ADDED_TO_MANIFEST));
63
+
64
+ this._getDependenciesStringsArray(actionResult.data)
65
+ .sort()
66
+ .forEach((output) => this._log.result(output));
67
+ return actionResult;
68
+ }
69
+
70
+ _getDependenciesStringsArray(data) {
71
+ const dependenciesString = [];
72
+ //Features
73
+ const features = data.filter((dependency) => dependency.type === DEPENDENCY_TYPES.FEATURE.name);
74
+ features.forEach((feature) => {
75
+ const requiredOrOptional = feature.required ? FEATURE_REQUIRED : FEATURE_OPTIONAL;
76
+ dependenciesString.push(`${DEPENDENCY_TYPES.FEATURE.prefix} ${feature.value}:${requiredOrOptional}`);
77
+ });
78
+
79
+ //Files
80
+ const files = data.filter((dependency) => dependency.type === DEPENDENCY_TYPES.FILE.name);
81
+ files.forEach((file) => {
82
+ dependenciesString.push(`${DEPENDENCY_TYPES.FILE.prefix} ${file.value}`);
83
+ });
84
+
85
+ //Folders
86
+ const folders = data.filter((dependency) => dependency.type === DEPENDENCY_TYPES.FOLDER.name);
87
+ folders.forEach((folder) => {
88
+ dependenciesString.push(`${DEPENDENCY_TYPES.FOLDER.prefix} ${folder.value}`);
89
+ });
90
+
91
+ //Objects - Regular, SuiteApp, Bundle dependencies
92
+ const objects = data.filter((dependency) => dependency.type === DEPENDENCY_TYPES.OBJECT.name);
93
+ objects.forEach((object) => {
94
+ const appIdDisplay = object.appId
95
+ ? `in [${OBJECT_CONTAINER_PREFIX.SUITEAPP} - ${OBJECT_REFERENCE_ATTRIBUTES.APP_ID}${object.appId}]`
96
+ : '';
97
+ const bundleIdDisplay = object.bundleIds
98
+ ? `in [${OBJECT_CONTAINER_PREFIX.BUNDLE} - ${OBJECT_REFERENCE_ATTRIBUTES.BUNDLE_ID}${object.bundleIds}]`
99
+ : '';
100
+ const scriptIdDisplay = `${OBJECT_REFERENCE_ATTRIBUTES.SCRIPT_ID}${object.scriptId}`;
101
+ dependenciesString.push(`[${DEPENDENCY_TYPES.OBJECT.prefix} ${scriptIdDisplay}] ${appIdDisplay}${bundleIdDisplay}`);
102
+ });
103
+
104
+ //Platform Extensions
105
+ const platformExtensions = data.filter((dependency) => dependency.type === DEPENDENCY_TYPES.PLATFORMEXTENSION.name);
106
+ platformExtensions.forEach((platformExtension) => {
107
+ const appIdDisplay = platformExtension.appId ? `${OBJECT_REFERENCE_ATTRIBUTES.APP_ID}${platformExtension.appId}, ` : '';
108
+ const objectTypeDisplay = `${OBJECT_REFERENCE_ATTRIBUTES.OBJECT_TYPE}${platformExtension.objectType}`;
109
+ dependenciesString.push(`${DEPENDENCY_TYPES.PLATFORMEXTENSION.prefix} ${appIdDisplay}${objectTypeDisplay}`);
110
+ });
111
+
112
+ return dependenciesString;
113
+ }
114
+ };
@@ -0,0 +1,370 @@
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 CreateProjectActionResult = require('../../../services/actionresult/CreateProjectActionResult');
8
+ const BaseAction = require('../../base/BaseAction');
9
+ const TemplateKeys = require('../../../templates/TemplateKeys');
10
+ const CommandUtils = require('../../../utils/CommandUtils');
11
+ const NodeTranslationService = require('../../../services/NodeTranslationService');
12
+ const SdkOperationResultUtils = require('../../../utils/SdkOperationResultUtils');
13
+ const SdkExecutionContext = require('../../../SdkExecutionContext');
14
+ const ApplicationConstants = require('../../../ApplicationConstants');
15
+ const NpmInstallRunner = require('../../../services/NpmInstallRunner');
16
+ const FileSystemService = require('../../../services/FileSystemService');
17
+ const { throwValidationException, unwrapExceptionMessage } = require('../../../utils/ExceptionUtils');
18
+ const {
19
+ COMMAND_CREATEPROJECT: { MESSAGES },
20
+ } = require('../../../services/TranslationKeys');
21
+ const path = require('path');
22
+
23
+ const {
24
+ validateFieldIsNotEmpty,
25
+ showValidationResults,
26
+ validateFieldHasNoSpaces,
27
+ validateFieldIsLowerCase,
28
+ validatePublisherId,
29
+ validateProjectVersion,
30
+ validateXMLCharacters,
31
+ validateNotUndefined,
32
+ validateProjectType,
33
+ } = require('../../../validation/InteractiveAnswersValidator');
34
+
35
+ const JEST_CONFIG_FILENAME = 'jest.config.js';
36
+ const JEST_CONFIG_PROJECT_TYPE_ACP = 'SuiteCloudJestConfiguration.ProjectType.ACP';
37
+ const JEST_CONFIG_PROJECT_TYPE_SUITEAPP = 'SuiteCloudJestConfiguration.ProjectType.SUITEAPP';
38
+ const JEST_CONFIG_REPLACE_STRING_PROJECT_TYPE = '{{projectType}}';
39
+ const PACKAGE_JSON_FILENAME = 'package.json';
40
+ const PACKAGE_JSON_DEFAULT_VERSION = '1.0.0';
41
+ const PACKAGE_JSON_REPLACE_STRING_VERSION = '{{version}}';
42
+
43
+ const SOURCE_FOLDER = 'src';
44
+ const UNIT_TEST_TEST_FOLDER = '__tests__';
45
+
46
+ const CLI_CONFIG_TEMPLATE_KEY = 'cliconfig';
47
+ const GITIGNORE_TEMPLATE_KEY = 'gitignore';
48
+ const CLI_CONFIG_FILENAME = 'suitecloud.config';
49
+ const GITIGNORE_FILENAME = '.gitignore';
50
+ const CLI_CONFIG_EXTENSION = 'js';
51
+ const UNIT_TEST_CLI_CONFIG_TEMPLATE_KEY = 'cliconfig';
52
+ const UNIT_TEST_CLI_CONFIG_FILENAME = 'suitecloud.config';
53
+ const UNIT_TEST_CLI_CONFIG_EXTENSION = 'js';
54
+ const UNIT_TEST_PACKAGE_TEMPLATE_KEY = 'packagejson';
55
+ const UNIT_TEST_PACKAGE_FILENAME = 'package';
56
+ const UNIT_TEST_PACKAGE_EXTENSION = 'json';
57
+ const UNIT_TEST_JEST_CONFIG_TEMPLATE_KEY = 'jestconfig';
58
+ const UNIT_TEST_JEST_CONFIG_FILENAME = 'jest.config';
59
+ const UNIT_TEST_JEST_CONFIG_EXTENSION = 'js';
60
+ const UNIT_TEST_SAMPLE_TEST_KEY = 'sampletest';
61
+ const UNIT_TEST_SAMPLE_TEST_FILENAME = 'sample-test';
62
+ const UNIT_TEST_SAMPLE_TEST_EXTENSION = 'js';
63
+ const UNIT_TEST_JSCONFIG_TEMPLATE_KEY = 'jsconfig';
64
+ const UNIT_TEST_JSCONFIG_FILENAME = 'jsconfig';
65
+ const UNIT_TEST_JSCONFIG_EXTENSION = 'json';
66
+
67
+ const COMMAND_OPTIONS = {
68
+ OVERWRITE: 'overwrite',
69
+ PARENT_DIRECTORY: 'parentdirectory',
70
+ PROJECT_ID: 'projectid',
71
+ PROJECT_NAME: 'projectname',
72
+ PROJECT_VERSION: 'projectversion',
73
+ PUBLISHER_ID: 'publisherid',
74
+ TYPE: 'type',
75
+ INCLUDE_UNIT_TESTING: 'includeunittesting',
76
+ PROJECT_FOLDER_NAME: 'projectfoldername',
77
+ };
78
+
79
+ module.exports = class CreateProjectAction extends BaseAction {
80
+ constructor(options) {
81
+ super(options);
82
+ this._fileSystemService = new FileSystemService();
83
+ }
84
+
85
+ preExecute(params) {
86
+ if (!params[COMMAND_OPTIONS.PROJECT_FOLDER_NAME]) {
87
+ params[COMMAND_OPTIONS.PROJECT_FOLDER_NAME] = this._getProjectFolderName(params);
88
+ }
89
+ if (!params[COMMAND_OPTIONS.PARENT_DIRECTORY]) {
90
+ params[COMMAND_OPTIONS.PARENT_DIRECTORY] = path.join(this._executionPath, params[COMMAND_OPTIONS.PROJECT_FOLDER_NAME]);
91
+ }
92
+ return params;
93
+ }
94
+
95
+ async execute(params) {
96
+ try {
97
+ const projectFolderName = params[COMMAND_OPTIONS.PROJECT_FOLDER_NAME];
98
+ const projectAbsolutePath = params[COMMAND_OPTIONS.PARENT_DIRECTORY];
99
+ const manifestFilePath = path.join(projectAbsolutePath, SOURCE_FOLDER, ApplicationConstants.FILES.MANIFEST_XML);
100
+
101
+ const validationErrors = this._validateParams(params);
102
+
103
+ if (validationErrors.length > 0) {
104
+ throwValidationException(validationErrors, false, this._commandMetadata);
105
+ }
106
+
107
+ if (this._fileSystemService.folderExists(projectAbsolutePath) && !params[COMMAND_OPTIONS.OVERWRITE]) {
108
+ throw NodeTranslationService.getMessage(MESSAGES.OVERWRITE_ERROR, projectAbsolutePath);
109
+ }
110
+
111
+ const projectType = params[COMMAND_OPTIONS.TYPE];
112
+
113
+ const createProjectParams = {
114
+ //Enclose in double quotes to also support project names with spaces
115
+ parentdirectory: CommandUtils.quoteString(projectAbsolutePath),
116
+ type: projectType,
117
+ projectname: SOURCE_FOLDER,
118
+ ...(params[COMMAND_OPTIONS.OVERWRITE] && { overwrite: '' }),
119
+ ...(projectType === ApplicationConstants.PROJECT_SUITEAPP && {
120
+ publisherid: params[COMMAND_OPTIONS.PUBLISHER_ID],
121
+ projectid: params[COMMAND_OPTIONS.PROJECT_ID],
122
+ projectversion: params[COMMAND_OPTIONS.PROJECT_VERSION],
123
+ }),
124
+ };
125
+
126
+ this._fileSystemService.createFolderFromAbsolutePath(projectAbsolutePath);
127
+
128
+ const executionContextCreateProject = SdkExecutionContext.Builder.forCommand(this._commandMetadata.sdkCommand)
129
+ .integration()
130
+ .addParams(createProjectParams)
131
+ .build();
132
+
133
+ const createProjectAction = new Promise(
134
+ this.createProject(executionContextCreateProject, params, projectAbsolutePath, projectFolderName, manifestFilePath)
135
+ );
136
+
137
+ const createProjectActionData = await createProjectAction;
138
+
139
+ const projectName = params[COMMAND_OPTIONS.PROJECT_NAME];
140
+ const includeUnitTesting = this._getIncludeUnitTestingBoolean(params[COMMAND_OPTIONS.INCLUDE_UNIT_TESTING]);
141
+ //fixing project name for not interactive output before building results
142
+ const commandParameters = { ...createProjectParams, [`${COMMAND_OPTIONS.PROJECT_NAME}`]: params[COMMAND_OPTIONS.PROJECT_NAME] };
143
+
144
+ return createProjectActionData.operationResult.status === SdkOperationResultUtils.STATUS.SUCCESS
145
+ ? CreateProjectActionResult.Builder.withData(createProjectActionData.operationResult.data)
146
+ .withResultMessage(createProjectActionData.operationResult.resultMessage)
147
+ .withProjectType(projectType)
148
+ .withProjectName(projectName)
149
+ .withProjectDirectory(createProjectActionData.projectDirectory)
150
+ .withUnitTesting(includeUnitTesting)
151
+ .withNpmPackageInitialized(createProjectActionData.npmInstallSuccess)
152
+ .withCommandParameters(commandParameters)
153
+ .build()
154
+ : CreateProjectActionResult.Builder.withErrors(createProjectActionData.operationResult.errorMessages)
155
+ .withCommandParameters(commandParameters)
156
+ .build();
157
+ } catch (error) {
158
+ return CreateProjectActionResult.Builder.withErrors([unwrapExceptionMessage(error)]).build();
159
+ }
160
+ }
161
+
162
+ createProject(executionContextCreateProject, params, projectAbsolutePath, projectFolderName, manifestFilePath) {
163
+ return async (resolve, reject) => {
164
+ try {
165
+ await this._log.info(NodeTranslationService.getMessage(MESSAGES.CREATING_PROJECT_STRUCTURE));
166
+ if (params[COMMAND_OPTIONS.OVERWRITE]) {
167
+ this._fileSystemService.emptyFolderRecursive(projectAbsolutePath);
168
+ }
169
+
170
+ const operationResult = await this._sdkExecutor.execute(executionContextCreateProject);
171
+
172
+ if (operationResult.status === SdkOperationResultUtils.STATUS.ERROR) {
173
+ resolve({
174
+ operationResult: operationResult,
175
+ projectType: params[COMMAND_OPTIONS.TYPE],
176
+ projectDirectory: projectAbsolutePath,
177
+ });
178
+ return;
179
+ }
180
+ if (params[COMMAND_OPTIONS.TYPE] === ApplicationConstants.PROJECT_SUITEAPP) {
181
+ const oldPath = path.join(projectAbsolutePath, projectFolderName);
182
+ const newPath = path.join(projectAbsolutePath, SOURCE_FOLDER);
183
+ this._fileSystemService.deleteFolderRecursive(newPath);
184
+ this._fileSystemService.renameFolder(oldPath, newPath);
185
+ }
186
+ this._fileSystemService.replaceStringInFile(manifestFilePath, SOURCE_FOLDER, params[COMMAND_OPTIONS.PROJECT_NAME]);
187
+ let npmInstallSuccess;
188
+ let includeUnitTesting = this._getIncludeUnitTestingBoolean(params[COMMAND_OPTIONS.INCLUDE_UNIT_TESTING]);
189
+ if (includeUnitTesting) {
190
+ await this._log.info(NodeTranslationService.getMessage(MESSAGES.SETUP_TEST_ENV));
191
+ await this._createUnitTestFiles(
192
+ params[COMMAND_OPTIONS.TYPE],
193
+ params[COMMAND_OPTIONS.PROJECT_NAME],
194
+ params[COMMAND_OPTIONS.PROJECT_VERSION],
195
+ projectAbsolutePath
196
+ );
197
+
198
+ await this._log.info(NodeTranslationService.getMessage(MESSAGES.INIT_NPM_DEPENDENCIES));
199
+ npmInstallSuccess = await this._runNpmInstall(projectAbsolutePath);
200
+ } else {
201
+ await this._createDefaultSuiteCloudConfigFile(projectAbsolutePath);
202
+ }
203
+
204
+ await this._createGitignoreFile(projectAbsolutePath);
205
+
206
+ return resolve({
207
+ operationResult: operationResult,
208
+ projectDirectory: projectAbsolutePath,
209
+ npmInstallSuccess: npmInstallSuccess,
210
+ });
211
+ } catch (error) {
212
+ this._fileSystemService.deleteFolderRecursive(path.join(projectAbsolutePath, projectFolderName));
213
+ reject(error);
214
+ }
215
+ };
216
+ }
217
+
218
+ _getIncludeUnitTestingBoolean(includeUnitTestingParam) {
219
+ let includeUnitTesting = includeUnitTestingParam;
220
+ if (typeof includeUnitTesting === 'string') {
221
+ includeUnitTesting = includeUnitTesting === 'true';
222
+ }
223
+
224
+ return includeUnitTesting;
225
+ }
226
+
227
+ _getProjectFolderName(params) {
228
+ switch (params[COMMAND_OPTIONS.TYPE]) {
229
+ case ApplicationConstants.PROJECT_SUITEAPP:
230
+ return params[COMMAND_OPTIONS.PUBLISHER_ID] && params[COMMAND_OPTIONS.PROJECT_ID]
231
+ ? params[COMMAND_OPTIONS.PUBLISHER_ID] + '.' + params[COMMAND_OPTIONS.PROJECT_ID]
232
+ : 'not_specified';
233
+ case ApplicationConstants.PROJECT_ACP:
234
+ return params[COMMAND_OPTIONS.PROJECT_NAME] ? params[COMMAND_OPTIONS.PROJECT_NAME] : 'not_specified';
235
+ default:
236
+ // if --type parameter isn't correct, it doesn't matter the project folder name. It will throw a validation error later
237
+ return 'not_specified';
238
+ }
239
+ }
240
+
241
+ async _createUnitTestFiles(type, projectName, projectVersion, projectAbsolutePath) {
242
+ await this._createUnitTestCliConfigFile(projectAbsolutePath);
243
+ await this._createUnitTestPackageJsonFile(type, projectName, projectVersion, projectAbsolutePath);
244
+ await this._createJestConfigFile(type, projectAbsolutePath);
245
+ await this._createSampleUnitTestFile(projectAbsolutePath);
246
+ await this._createJsConfigFile(projectAbsolutePath);
247
+ }
248
+
249
+ async _createGitignoreFile(projectAbsolutePath) {
250
+ await this._fileSystemService.createFileFromTemplate({
251
+ template: TemplateKeys.PROJECTCONFIGS[GITIGNORE_TEMPLATE_KEY],
252
+ destinationFolder: projectAbsolutePath,
253
+ fileName: GITIGNORE_FILENAME,
254
+ });
255
+ }
256
+
257
+ async _createDefaultSuiteCloudConfigFile(projectAbsolutePath) {
258
+ await this._fileSystemService.createFileFromTemplate({
259
+ template: TemplateKeys.PROJECTCONFIGS[CLI_CONFIG_TEMPLATE_KEY],
260
+ destinationFolder: projectAbsolutePath,
261
+ fileName: CLI_CONFIG_FILENAME,
262
+ fileExtension: CLI_CONFIG_EXTENSION,
263
+ });
264
+ }
265
+
266
+ async _createUnitTestCliConfigFile(projectAbsolutePath) {
267
+ await this._fileSystemService.createFileFromTemplate({
268
+ template: TemplateKeys.UNIT_TEST[UNIT_TEST_CLI_CONFIG_TEMPLATE_KEY],
269
+ destinationFolder: projectAbsolutePath,
270
+ fileName: UNIT_TEST_CLI_CONFIG_FILENAME,
271
+ fileExtension: UNIT_TEST_CLI_CONFIG_EXTENSION,
272
+ });
273
+ }
274
+
275
+ async _createUnitTestPackageJsonFile(type, projectName, projectVersion, projectAbsolutePath) {
276
+ await this._fileSystemService.createFileFromTemplate({
277
+ template: TemplateKeys.UNIT_TEST[UNIT_TEST_PACKAGE_TEMPLATE_KEY],
278
+ destinationFolder: projectAbsolutePath,
279
+ fileName: UNIT_TEST_PACKAGE_FILENAME,
280
+ fileExtension: UNIT_TEST_PACKAGE_EXTENSION,
281
+ });
282
+
283
+ let packageJsonAbsolutePath = path.join(projectAbsolutePath, PACKAGE_JSON_FILENAME);
284
+
285
+ let version = PACKAGE_JSON_DEFAULT_VERSION;
286
+ if (type === ApplicationConstants.PROJECT_SUITEAPP) {
287
+ version = projectVersion;
288
+ }
289
+ await this._fileSystemService.replaceStringInFile(packageJsonAbsolutePath, PACKAGE_JSON_REPLACE_STRING_VERSION, version);
290
+ }
291
+
292
+ async _createJestConfigFile(type, projectAbsolutePath) {
293
+ await this._fileSystemService.createFileFromTemplate({
294
+ template: TemplateKeys.UNIT_TEST[UNIT_TEST_JEST_CONFIG_TEMPLATE_KEY],
295
+ destinationFolder: projectAbsolutePath,
296
+ fileName: UNIT_TEST_JEST_CONFIG_FILENAME,
297
+ fileExtension: UNIT_TEST_JEST_CONFIG_EXTENSION,
298
+ });
299
+
300
+ let jestConfigProjectType = JEST_CONFIG_PROJECT_TYPE_ACP;
301
+ if (type === ApplicationConstants.PROJECT_SUITEAPP) {
302
+ jestConfigProjectType = JEST_CONFIG_PROJECT_TYPE_SUITEAPP;
303
+ }
304
+ let jestConfigAbsolutePath = path.join(projectAbsolutePath, JEST_CONFIG_FILENAME);
305
+ await this._fileSystemService.replaceStringInFile(jestConfigAbsolutePath, JEST_CONFIG_REPLACE_STRING_PROJECT_TYPE, jestConfigProjectType);
306
+ }
307
+
308
+ async _createSampleUnitTestFile(projectAbsolutePath) {
309
+ let testsFolderAbsolutePath = this._fileSystemService.createFolder(projectAbsolutePath, UNIT_TEST_TEST_FOLDER);
310
+ await this._fileSystemService.createFileFromTemplate({
311
+ template: TemplateKeys.UNIT_TEST[UNIT_TEST_SAMPLE_TEST_KEY],
312
+ destinationFolder: testsFolderAbsolutePath,
313
+ fileName: UNIT_TEST_SAMPLE_TEST_FILENAME,
314
+ fileExtension: UNIT_TEST_SAMPLE_TEST_EXTENSION,
315
+ });
316
+ }
317
+
318
+ async _createJsConfigFile(projectAbsolutePath) {
319
+ await this._fileSystemService.createFileFromTemplate({
320
+ template: TemplateKeys.UNIT_TEST[UNIT_TEST_JSCONFIG_TEMPLATE_KEY],
321
+ destinationFolder: projectAbsolutePath,
322
+ fileName: UNIT_TEST_JSCONFIG_FILENAME,
323
+ fileExtension: UNIT_TEST_JSCONFIG_EXTENSION,
324
+ });
325
+ }
326
+
327
+ async _runNpmInstall(projectAbsolutePath) {
328
+ try {
329
+ await NpmInstallRunner.run(projectAbsolutePath);
330
+ return true;
331
+ } catch (error) {
332
+ return false;
333
+ }
334
+ }
335
+
336
+ _validateParams(answers) {
337
+ const validationErrors = [];
338
+ validationErrors.push(showValidationResults(answers[COMMAND_OPTIONS.PROJECT_NAME], validateFieldIsNotEmpty, validateXMLCharacters));
339
+ validationErrors.push(showValidationResults(answers[COMMAND_OPTIONS.TYPE], validateProjectType));
340
+ if (answers[COMMAND_OPTIONS.TYPE] === ApplicationConstants.PROJECT_SUITEAPP) {
341
+ validationErrors.push(
342
+ showValidationResults(
343
+ answers[COMMAND_OPTIONS.PUBLISHER_ID],
344
+ (optionValue) => validateNotUndefined(optionValue, COMMAND_OPTIONS.PUBLISHER_ID),
345
+ validatePublisherId
346
+ )
347
+ );
348
+
349
+ validationErrors.push(
350
+ showValidationResults(
351
+ answers[COMMAND_OPTIONS.PROJECT_VERSION],
352
+ (optionValue) => validateNotUndefined(optionValue, COMMAND_OPTIONS.PROJECT_VERSION),
353
+ validateProjectVersion
354
+ )
355
+ );
356
+
357
+ validationErrors.push(
358
+ showValidationResults(
359
+ answers[COMMAND_OPTIONS.PROJECT_ID],
360
+ (optionValue) => validateNotUndefined(optionValue, COMMAND_OPTIONS.PROJECT_ID),
361
+ validateFieldIsNotEmpty,
362
+ validateFieldHasNoSpaces,
363
+ (optionValue) => validateFieldIsLowerCase(COMMAND_OPTIONS.PROJECT_ID, optionValue)
364
+ )
365
+ );
366
+ }
367
+
368
+ return validationErrors.filter((item) => item !== true);
369
+ }
370
+ };
@@ -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
+ const Command = require('../../Command');
8
+ const CreateProjectAction = require('./CreateProjectAction');
9
+ const CreateProjectInputHandler = require('./CreateProjectInputHandler');
10
+ const CreateProjectOutputHandler = require('./CreateProjectOutputHandler');
11
+
12
+ module.exports = {
13
+ create(options) {
14
+ return Command.Builder.withOptions(options)
15
+ .withAction(CreateProjectAction)
16
+ .withInput(CreateProjectInputHandler)
17
+ .withOutput(CreateProjectOutputHandler)
18
+ .build();
19
+ }
20
+ };