@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.
- package/CONTRIBUTING.md +7 -0
- package/DELTA.md +235 -0
- package/README.md +107 -0
- package/docs/Command.md +299 -0
- package/messages.json +317 -0
- package/package.json +51 -0
- package/postinstall.js +8 -0
- package/resources/FUTC-LICENSE.txt +115 -0
- package/src/ApplicationConstants.js +87 -0
- package/src/CLI.js +202 -0
- package/src/CLIException.js +21 -0
- package/src/ExecutionEnvironmentContext.js +39 -0
- package/src/SdkExecutionContext.js +90 -0
- package/src/SdkExecutor.js +160 -0
- package/src/commands/Command.js +158 -0
- package/src/commands/account/manageauth/ManageAccountAction.js +126 -0
- package/src/commands/account/manageauth/ManageAccountCommand.js +20 -0
- package/src/commands/account/manageauth/ManageAccountInputHandler.js +215 -0
- package/src/commands/account/manageauth/ManageAccountOutputHandler.js +30 -0
- package/src/commands/account/setup/SetupAction.js +39 -0
- package/src/commands/account/setup/SetupCommand.js +21 -0
- package/src/commands/account/setup/SetupInputHandler.js +169 -0
- package/src/commands/account/setup/SetupOutputHandler.js +65 -0
- package/src/commands/account/setupci/AccountSetupCiAction.js +58 -0
- package/src/commands/account/setupci/AccountSetupCiCommand.js +20 -0
- package/src/commands/account/setupci/AccountSetupCiConstants.js +21 -0
- package/src/commands/account/setupci/AccountSetupCiOutputHandler.js +40 -0
- package/src/commands/account/setupci/AccountSetupCiValidation.js +100 -0
- package/src/commands/base/BaseAction.js +37 -0
- package/src/commands/base/BaseInputHandler.js +24 -0
- package/src/commands/base/BaseOutputHandler.js +30 -0
- package/src/commands/custom/hello/Action.js +58 -0
- package/src/commands/custom/hello/Command.js +20 -0
- package/src/commands/custom/hello/Handler.js +26 -0
- package/src/commands/custom/hello/README.md +78 -0
- package/src/commands/custom/hook/Action.js +28 -0
- package/src/commands/custom/hook/Command.js +22 -0
- package/src/commands/custom/hook/InputHandler.js +8 -0
- package/src/commands/custom/hook/OutputHandler.js +8 -0
- package/src/commands/custom/hook/README.md +32 -0
- package/src/commands/file/create/CreateFileAction.js +89 -0
- package/src/commands/file/create/CreateFileCommand.js +20 -0
- package/src/commands/file/create/CreateFileInputHandler.js +175 -0
- package/src/commands/file/create/CreateFileOutputHandler.js +22 -0
- package/src/commands/file/import/ImportFilesAction.js +112 -0
- package/src/commands/file/import/ImportFilesCommand.js +22 -0
- package/src/commands/file/import/ImportFilesInputHandler.js +130 -0
- package/src/commands/file/import/ImportFilesOutputHandler.js +53 -0
- package/src/commands/file/list/ListFilesAction.js +55 -0
- package/src/commands/file/list/ListFilesCommand.js +20 -0
- package/src/commands/file/list/ListFilesInputHandler.js +55 -0
- package/src/commands/file/list/ListFilesOutputHandler.js +24 -0
- package/src/commands/file/upload/UploadFilesAction.js +67 -0
- package/src/commands/file/upload/UploadFilesCommand.js +20 -0
- package/src/commands/file/upload/UploadFilesInputHandler.js +125 -0
- package/src/commands/file/upload/UploadFilesOutputHandler.js +49 -0
- package/src/commands/object/create/CreateObjectAction.js +33 -0
- package/src/commands/object/create/CreateObjectCommand.js +19 -0
- package/src/commands/object/create/CreateObjectInputHandler.js +82 -0
- package/src/commands/object/import/ImportObjectsAction.js +225 -0
- package/src/commands/object/import/ImportObjectsCommand.js +20 -0
- package/src/commands/object/import/ImportObjectsInputHandler.js +310 -0
- package/src/commands/object/import/ImportObjectsOutputHandler.js +114 -0
- package/src/commands/object/list/ListObjectsAction.js +62 -0
- package/src/commands/object/list/ListObjectsCommand.js +20 -0
- package/src/commands/object/list/ListObjectsInputHandler.js +148 -0
- package/src/commands/object/list/ListObjectsOutputHandler.js +29 -0
- package/src/commands/object/update/UpdateAction.js +138 -0
- package/src/commands/object/update/UpdateCommand.js +20 -0
- package/src/commands/object/update/UpdateInputHandler.js +170 -0
- package/src/commands/object/update/UpdateOutputHandler.js +61 -0
- package/src/commands/project/adddependencies/AddDependenciesAction.js +55 -0
- package/src/commands/project/adddependencies/AddDependenciesCommand.js +19 -0
- package/src/commands/project/adddependencies/AddDependenciesOutputHandler.js +114 -0
- package/src/commands/project/create/CreateProjectAction.js +370 -0
- package/src/commands/project/create/CreateProjectCommand.js +20 -0
- package/src/commands/project/create/CreateProjectInputHandler.js +169 -0
- package/src/commands/project/create/CreateProjectOutputHandler.js +36 -0
- package/src/commands/project/deploy/DeployAction.js +161 -0
- package/src/commands/project/deploy/DeployCommand.js +20 -0
- package/src/commands/project/deploy/DeployInputHandler.js +100 -0
- package/src/commands/project/deploy/DeployOutputHandler.js +49 -0
- package/src/commands/project/package/PackageAction.js +59 -0
- package/src/commands/project/package/PackageCommand.js +18 -0
- package/src/commands/project/package/PackageOutputHandler.js +18 -0
- package/src/commands/project/validate/ValidateAction.js +106 -0
- package/src/commands/project/validate/ValidateCommand.js +20 -0
- package/src/commands/project/validate/ValidateInputHandler.js +92 -0
- package/src/commands/project/validate/ValidateOutputHandler.js +74 -0
- package/src/core/CommandActionExecutor.js +347 -0
- package/src/core/CommandAuthentication.js +13 -0
- package/src/core/CommandOptionsValidator.js +42 -0
- package/src/core/CommandRegistrationService.js +130 -0
- package/src/core/CommandsMetadataService.js +104 -0
- package/src/core/extensibility/CLIConfigurationService.js +192 -0
- package/src/core/extensibility/CommandUserExtension.js +64 -0
- package/src/core/sdksetup/SdkDownloadService.js +109 -0
- package/src/core/sdksetup/SdkLicense.js +39 -0
- package/src/core/sdksetup/SdkProperties.js +51 -0
- package/src/loggers/ConsoleLogger.js +32 -0
- package/src/loggers/LoggerFontFormatter.mjs +17 -0
- package/src/loggers/LoggerOsConstants.js +12 -0
- package/src/loggers/NodeConsoleLogger.js +47 -0
- package/src/metadata/CommandGenerators.json +92 -0
- package/src/metadata/NodeCommandsMetadata.json +139 -0
- package/src/metadata/ObjectTypesMetadata.js +615 -0
- package/src/metadata/SdkCommandsMetadata.json +846 -0
- package/src/metadata/SdkCommandsMetadataPatch.json +130 -0
- package/src/metadata/SuiteScriptModulesMetadata.js +152 -0
- package/src/metadata/SuiteScriptTypesMetadata.js +64 -0
- package/src/services/AccountFileCabinetService.js +86 -0
- package/src/services/EnvironmentInformationService.js +31 -0
- package/src/services/ExecutionContextService.js +108 -0
- package/src/services/FileCabinetService.js +65 -0
- package/src/services/FileSystemService.js +245 -0
- package/src/services/NodeTranslationService.js +22 -0
- package/src/services/NpmInstallRunner.js +33 -0
- package/src/services/ProjectInfoService.js +209 -0
- package/src/services/SuiteCloudAuthProxyService.js +469 -0
- package/src/services/TranslationKeys.js +506 -0
- package/src/services/TranslationService.js +30 -0
- package/src/services/actionresult/ActionResult.js +129 -0
- package/src/services/actionresult/AuthenticateActionResult.js +85 -0
- package/src/services/actionresult/CreateProjectActionResult.js +100 -0
- package/src/services/actionresult/DeployActionResult.js +69 -0
- package/src/services/actionresult/HelloActionResult.js +13 -0
- package/src/services/actionresult/ManageAccountActionResult.js +70 -0
- package/src/services/settings/CLISettings.js +46 -0
- package/src/services/settings/CLISettingsService.js +132 -0
- package/src/suitecloud.js +33 -0
- package/src/templates/TemplateKeys.js +25 -0
- package/src/templates/objects/commerceextension.xml +9 -0
- package/src/templates/projectconfigs/default_gitignore.template +47 -0
- package/src/templates/projectconfigs/sdf.config.js +4 -0
- package/src/templates/projectconfigs/suitecloud.config.js +4 -0
- package/src/templates/scripts/blankscript.js +3 -0
- package/src/templates/unittest/jest.config.js.template +7 -0
- package/src/templates/unittest/jsconfig.json.template +5 -0
- package/src/templates/unittest/package.json.template +12 -0
- package/src/templates/unittest/sample-test.js.template +37 -0
- package/src/templates/unittest/suitecloud.config.js.template +15 -0
- package/src/ui/CliSpinner.js +34 -0
- package/src/utils/AccountCredentialsFormatter.js +62 -0
- package/src/utils/AccountSpecificValuesUtils.js +55 -0
- package/src/utils/ActionResultUtils.js +47 -0
- package/src/utils/ApplyInstallationPreferencesUtils.js +41 -0
- package/src/utils/AuthenticationUtils.js +262 -0
- package/src/utils/CommandUtils.js +50 -0
- package/src/utils/CryptoUtils.js +41 -0
- package/src/utils/ExceptionUtils.js +33 -0
- package/src/utils/FileUtils.js +43 -0
- package/src/utils/SdkOperationResult.js +68 -0
- package/src/utils/SdkOperationResultUtils.js +20 -0
- package/src/utils/ValidationErrorsFormatter.js +23 -0
- package/src/utils/http/HttpConstants.js +39 -0
- package/src/utils/http/ProxyAgent.js +110 -0
- package/src/validation/InteractiveAnswersValidator.js +205 -0
package/src/CLI.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
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 assert = require('assert');
|
|
9
|
+
const program = require('commander');
|
|
10
|
+
const NodeConsoleLogger = require('./loggers/NodeConsoleLogger');
|
|
11
|
+
const NodeTranslationService = require('./services/NodeTranslationService');
|
|
12
|
+
const {
|
|
13
|
+
CLI: { INTERACTIVE_OPTION_DESCRIPTION, TITLE, USAGE, VERSION_HELP },
|
|
14
|
+
COMMAND_OPTIONS,
|
|
15
|
+
ERRORS,
|
|
16
|
+
} = require('./services/TranslationKeys');
|
|
17
|
+
const unwrapExceptionMessage = require('./utils/ExceptionUtils').unwrapExceptionMessage;
|
|
18
|
+
const INTERACTIVE_ALIAS = '-i';
|
|
19
|
+
const INTERACTIVE_OPTION = '--interactive';
|
|
20
|
+
|
|
21
|
+
// suitecloud executable is in {root}/src/suitecloud.js. package.json file is one level before
|
|
22
|
+
const PACKAGE_FILE = `${path.dirname(require.main.filename)}/../package.json`;
|
|
23
|
+
const configFile = require(PACKAGE_FILE);
|
|
24
|
+
const CLI_VERSION = configFile ? configFile.version : 'unknown';
|
|
25
|
+
const { nsCompatibleVersion } = require(PACKAGE_FILE);
|
|
26
|
+
const COMMAND_ALIAS = '[command]';
|
|
27
|
+
const HELP_COMMAND = 'help';
|
|
28
|
+
const HELP_OPTION = '--help';
|
|
29
|
+
const HELP_ALIAS = '-h';
|
|
30
|
+
const VERSION_OPTION = '--version';
|
|
31
|
+
|
|
32
|
+
module.exports = class CLI {
|
|
33
|
+
constructor(dependencies) {
|
|
34
|
+
assert(dependencies);
|
|
35
|
+
assert(dependencies.commandsMetadataService);
|
|
36
|
+
assert(dependencies.commandActionExecutor);
|
|
37
|
+
assert(dependencies.commandRegistrationService);
|
|
38
|
+
|
|
39
|
+
this._commandsMetadataService = dependencies.commandsMetadataService;
|
|
40
|
+
this._commandActionExecutor = dependencies.commandActionExecutor;
|
|
41
|
+
this._commandRegistrationService = dependencies.commandRegistrationService;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
start(process) {
|
|
45
|
+
try {
|
|
46
|
+
const commandMetadataList = this._commandsMetadataService.getCommandsMetadata();
|
|
47
|
+
|
|
48
|
+
this._addUbiquitousOptions(commandMetadataList, [] );
|
|
49
|
+
const thirdArgument = process.argv[2];
|
|
50
|
+
if (
|
|
51
|
+
thirdArgument &&
|
|
52
|
+
thirdArgument !== HELP_ALIAS &&
|
|
53
|
+
thirdArgument !== HELP_OPTION &&
|
|
54
|
+
thirdArgument !== HELP_COMMAND &&
|
|
55
|
+
thirdArgument !== VERSION_OPTION
|
|
56
|
+
) {
|
|
57
|
+
this._validateCommandExists(commandMetadataList, thirdArgument);
|
|
58
|
+
} else if (thirdArgument == HELP_COMMAND && process.argv[3]) {
|
|
59
|
+
this._validateCommandExists(commandMetadataList, process.argv[3]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (process.argv.length > 3 && (process.argv.includes(HELP_ALIAS) || process.argv.includes(HELP_OPTION))) {
|
|
63
|
+
process.argv = this._leaveOnlyHelpArguments();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const runInInteractiveMode = this._isRunningInInteractiveMode();
|
|
67
|
+
this._initializeCommands(commandMetadataList, runInInteractiveMode);
|
|
68
|
+
|
|
69
|
+
// If there are no arguments, we print SuiteCloud version header
|
|
70
|
+
if (!process.argv || process.argv.length <= 2) {
|
|
71
|
+
NodeConsoleLogger.info(NodeTranslationService.getMessage(TITLE, nsCompatibleVersion));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
program
|
|
75
|
+
.version(CLI_VERSION, VERSION_OPTION, NodeTranslationService.getMessage(VERSION_HELP))
|
|
76
|
+
.option(
|
|
77
|
+
`${INTERACTIVE_ALIAS}, ${INTERACTIVE_OPTION}`,
|
|
78
|
+
NodeTranslationService.getMessage(INTERACTIVE_OPTION_DESCRIPTION),
|
|
79
|
+
this._validateInteractive
|
|
80
|
+
)
|
|
81
|
+
.helpOption(`${HELP_ALIAS}, ${HELP_OPTION}`, NodeTranslationService.getMessage(COMMAND_OPTIONS.HELP))
|
|
82
|
+
.addHelpCommand(`${HELP_COMMAND} ${COMMAND_ALIAS}`, NodeTranslationService.getMessage(COMMAND_OPTIONS.HELP))
|
|
83
|
+
.on('command:*', (args) => {
|
|
84
|
+
NodeConsoleLogger.error(NodeTranslationService.getMessage(ERRORS.COMMAND_DOES_NOT_EXIST, args[0]));
|
|
85
|
+
})
|
|
86
|
+
.usage(NodeTranslationService.getMessage(USAGE))
|
|
87
|
+
.parse(process.argv);
|
|
88
|
+
} catch (exception) {
|
|
89
|
+
NodeConsoleLogger.error(unwrapExceptionMessage(exception));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_validateCommandExists(commandMetadataList, possibleCommand) {
|
|
94
|
+
if (!commandMetadataList.hasOwnProperty(possibleCommand)) {
|
|
95
|
+
throw NodeTranslationService.getMessage(ERRORS.COMMAND_DOES_NOT_EXIST, possibleCommand);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
_leaveOnlyHelpArguments() {
|
|
100
|
+
return process.argv.slice(0, 3).concat(HELP_ALIAS); //We only leave commandName and help argument
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
_isRunningInInteractiveMode() {
|
|
104
|
+
return process.argv.includes(INTERACTIVE_ALIAS) || process.argv.includes(INTERACTIVE_OPTION);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
_validateInteractive() {
|
|
108
|
+
let additionalAllowed = 0;
|
|
109
|
+
process.argv.forEach((arg)=>{
|
|
110
|
+
if( /\b(authid|project|config|debug)\b/.test(arg) ) additionalAllowed += 2;
|
|
111
|
+
});
|
|
112
|
+
if (process.argv.length > (4 + additionalAllowed) ) {
|
|
113
|
+
// There are more options apart from -i or --interactive
|
|
114
|
+
throw NodeTranslationService.getMessage(ERRORS.INTERACTIVE_MODE_MORE_OPTIONS);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
_addUbiquitousOptions(commandMetadataList, exemptions= []) {
|
|
119
|
+
Object.values(commandMetadataList).forEach((commandMetadata) => {
|
|
120
|
+
if(exemptions.includes( commandMetadata.name )) return;
|
|
121
|
+
|
|
122
|
+
Object.assign(
|
|
123
|
+
commandMetadata.options,
|
|
124
|
+
{
|
|
125
|
+
"config": {
|
|
126
|
+
"name": "config",
|
|
127
|
+
"option": "config",
|
|
128
|
+
"description": "Specify a config file to use. Otherwise cli will discover closest config file",
|
|
129
|
+
"mandatory": false,
|
|
130
|
+
"type": "SINGLE",
|
|
131
|
+
"usage": "\"./path/to/sdf.config.alt.js\"",
|
|
132
|
+
"defaultOption": false,
|
|
133
|
+
"disableInIntegrationMode": false,
|
|
134
|
+
"conflicts": ["noconfig"]
|
|
135
|
+
},
|
|
136
|
+
"noconfig": {
|
|
137
|
+
"name": "noconfig",
|
|
138
|
+
"option": "noconfig",
|
|
139
|
+
"description": "Do not use any config file",
|
|
140
|
+
"mandatory": false,
|
|
141
|
+
"type": "FLAG",
|
|
142
|
+
"usage": "",
|
|
143
|
+
"defaultOption": false,
|
|
144
|
+
"disableInIntegrationMode": false,
|
|
145
|
+
"conflicts": ["config"]
|
|
146
|
+
},
|
|
147
|
+
"customflag": {
|
|
148
|
+
"name": "customflag",
|
|
149
|
+
"option": "customflag",
|
|
150
|
+
"description": "A custom boolean that will be passed into the hooks. Has no effect unless you implement the logic in a hook",
|
|
151
|
+
"mandatory": false,
|
|
152
|
+
"type": "FLAG",
|
|
153
|
+
"usage": "",
|
|
154
|
+
"defaultOption": false,
|
|
155
|
+
"disableInIntegrationMode": false
|
|
156
|
+
},
|
|
157
|
+
"customoptions": {
|
|
158
|
+
"name": "customoptions",
|
|
159
|
+
"option": "customoptions",
|
|
160
|
+
"description": "Custom string values that will be passed into the hooks. Has no effect unless you implement the logic in a hook",
|
|
161
|
+
"mandatory": false,
|
|
162
|
+
"type": "MULTIPLE",
|
|
163
|
+
"usage": "\"value1\" \"value2\"",
|
|
164
|
+
"defaultOption": false,
|
|
165
|
+
"disableInIntegrationMode": false
|
|
166
|
+
},
|
|
167
|
+
"debug": {
|
|
168
|
+
"name": "debug",
|
|
169
|
+
"option": "debug",
|
|
170
|
+
"description": "Directory to dump debug data for debugging. Creates a unique {command}.{datetime}.json file per run",
|
|
171
|
+
"mandatory": false,
|
|
172
|
+
"type": "SINGLE",
|
|
173
|
+
"usage": "\"./debug-output\"",
|
|
174
|
+
"defaultOption": false,
|
|
175
|
+
"disableInIntegrationMode": false
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
_initializeCommands(commandMetadataList, runInInteractiveMode) {
|
|
183
|
+
const commandsMetadataArraySortedByCommandName = Object.values(commandMetadataList).sort((command1, command2) =>
|
|
184
|
+
command1.name.localeCompare(command2.name)
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
commandsMetadataArraySortedByCommandName.forEach((commandMetadata) => {
|
|
188
|
+
this._commandRegistrationService.register({
|
|
189
|
+
commandMetadata: commandMetadata,
|
|
190
|
+
program: program,
|
|
191
|
+
runInInteractiveMode: runInInteractiveMode,
|
|
192
|
+
executeCommandFunction: async (options) => {
|
|
193
|
+
return this._commandActionExecutor.executeAction({
|
|
194
|
+
commandName: commandMetadata.name,
|
|
195
|
+
runInInteractiveMode: runInInteractiveMode,
|
|
196
|
+
arguments: options,
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
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 = class CLIException {
|
|
8
|
+
constructor(defaultMessage, infoMessage, translationKey) {
|
|
9
|
+
this._defaultMessage = defaultMessage;
|
|
10
|
+
this._infoMessage = infoMessage;
|
|
11
|
+
this._translationKey = translationKey;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getInfoMessage() {
|
|
15
|
+
return this._infoMessage;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getErrorMessage() {
|
|
19
|
+
return this._defaultMessage;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -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 { SDK_CLIENT_PLATFORM } = require('./ApplicationConstants');
|
|
8
|
+
|
|
9
|
+
module.exports = class ExecutionEnvironmentContext {
|
|
10
|
+
|
|
11
|
+
constructor(params) {
|
|
12
|
+
this._platform = SDK_CLIENT_PLATFORM;
|
|
13
|
+
this._platformVersion = process.version;
|
|
14
|
+
|
|
15
|
+
if (!params) {
|
|
16
|
+
params = {
|
|
17
|
+
platform: SDK_CLIENT_PLATFORM,
|
|
18
|
+
platformVersion: process.version,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (params.platform) {
|
|
23
|
+
this._platform = params.platform;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (params.platformVersion) {
|
|
27
|
+
this._platformVersion = params.platformVersion;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getPlatform() {
|
|
32
|
+
return this._platform;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getPlatformVersion() {
|
|
36
|
+
return this._platformVersion;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
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 SdkExecutionContext {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
assert(options.command, 'Command is mandatory option');
|
|
12
|
+
this._command = options.command;
|
|
13
|
+
this._integrationMode = options.integrationMode;
|
|
14
|
+
this._params = options.params;
|
|
15
|
+
this._flags = options.flags;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getCommand() {
|
|
19
|
+
return this._command;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getParams() {
|
|
23
|
+
return this._params;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getFlags() {
|
|
27
|
+
return this._flags;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
isIntegrationMode() {
|
|
31
|
+
return this._integrationMode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static get Builder() {
|
|
35
|
+
return new SdkExecutionContextBuilder();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class SdkExecutionContextBuilder {
|
|
40
|
+
constructor() {
|
|
41
|
+
this._params = {};
|
|
42
|
+
this._flags = [];
|
|
43
|
+
this._integrationMode = false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
forCommand(command) {
|
|
47
|
+
this._command = command;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
integration() {
|
|
52
|
+
this._integrationMode = true;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
addParams(params) {
|
|
57
|
+
Object.keys(params).forEach((key) => {
|
|
58
|
+
this.addParam(key, params[key]);
|
|
59
|
+
});
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
addParam(param, value) {
|
|
64
|
+
this._params[`-${param}`] = value;
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
addFlags(flags) {
|
|
69
|
+
flags.forEach((flag) => {
|
|
70
|
+
this.addFlag(flag);
|
|
71
|
+
});
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
addFlag(flag) {
|
|
76
|
+
this._flags.push(`-${flag}`);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
build() {
|
|
81
|
+
return new SdkExecutionContext({
|
|
82
|
+
command: this._command,
|
|
83
|
+
params: this._params,
|
|
84
|
+
flags: this._flags,
|
|
85
|
+
integrationMode: this._integrationMode,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = SdkExecutionContext;
|
|
@@ -0,0 +1,160 @@
|
|
|
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 {
|
|
8
|
+
SDK_INTEGRATION_MODE_JVM_OPTION,
|
|
9
|
+
SDK_CLIENT_PLATFORM_JVM_OPTION,
|
|
10
|
+
SDK_CLIENT_PLATFORM_VERSION_JVM_OPTION,
|
|
11
|
+
SDK_COMPATIBLE_JAVA_VERSIONS,
|
|
12
|
+
} = require('./ApplicationConstants');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const FileUtils = require('./utils/FileUtils');
|
|
15
|
+
const spawn = require('child_process').spawn;
|
|
16
|
+
const CLISettingsService = require('./services/settings/CLISettingsService');
|
|
17
|
+
const EnvironmentInformationService = require('./services/EnvironmentInformationService');
|
|
18
|
+
const url = require('url');
|
|
19
|
+
const NodeTranslationService = require('./services/NodeTranslationService');
|
|
20
|
+
const { ERRORS } = require('./services/TranslationKeys');
|
|
21
|
+
const ExecutionEnvironmentContext = require('./ExecutionEnvironmentContext');
|
|
22
|
+
|
|
23
|
+
const DATA_EVENT = 'data';
|
|
24
|
+
const CLOSE_EVENT = 'close';
|
|
25
|
+
const UTF8 = 'utf8';
|
|
26
|
+
|
|
27
|
+
module.exports = class SdkExecutor {
|
|
28
|
+
constructor(sdkPath, executionEnvironmentContext) {
|
|
29
|
+
this._sdkPath = sdkPath;
|
|
30
|
+
|
|
31
|
+
this._CLISettingsService = new CLISettingsService();
|
|
32
|
+
this._environmentInformationService = new EnvironmentInformationService();
|
|
33
|
+
this.childProcess = null;
|
|
34
|
+
|
|
35
|
+
if (!executionEnvironmentContext) {
|
|
36
|
+
this._executionEnvironmentContext = new ExecutionEnvironmentContext();
|
|
37
|
+
} else {
|
|
38
|
+
this._executionEnvironmentContext = executionEnvironmentContext;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
execute(executionContext, token) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
if (token !== undefined && token !== null) {
|
|
45
|
+
token.cancel = (reason) => {
|
|
46
|
+
this.childProcess.kill('SIGKILL');
|
|
47
|
+
reject(reason);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
this.childProcess = this._launchJvmCommand(executionContext);
|
|
52
|
+
this._addChildProcessListeners(executionContext.isIntegrationMode(), resolve, reject);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
reject(e);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
_addChildProcessListeners(isIntegrationMode, resolve, reject) {
|
|
60
|
+
let lastSdkOutput = '';
|
|
61
|
+
let lastSdkError = '';
|
|
62
|
+
|
|
63
|
+
this.childProcess.stderr.on(DATA_EVENT, (data) => {
|
|
64
|
+
lastSdkError += data.toString(UTF8);
|
|
65
|
+
});
|
|
66
|
+
this.childProcess.stdout.on(DATA_EVENT, (data) => {
|
|
67
|
+
lastSdkOutput += data.toString(UTF8);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
this.childProcess.on(CLOSE_EVENT, (code) => {
|
|
71
|
+
if (code === 0) {
|
|
72
|
+
try {
|
|
73
|
+
const output = isIntegrationMode ? JSON.parse(lastSdkOutput) : lastSdkOutput;
|
|
74
|
+
resolve(output);
|
|
75
|
+
} catch (error) {
|
|
76
|
+
reject(NodeTranslationService.getMessage(ERRORS.SDKEXECUTOR.RUNNING_COMMAND, error));
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
const javaVersionError = this._checkIfJavaVersionIssue();
|
|
80
|
+
if (javaVersionError) {
|
|
81
|
+
reject(javaVersionError);
|
|
82
|
+
}
|
|
83
|
+
reject(NodeTranslationService.getMessage(ERRORS.SDKEXECUTOR.SDK_ERROR, code, lastSdkError));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_launchJvmCommand(executionContext) {
|
|
89
|
+
if (!this._CLISettingsService.isJavaVersionValid()) {
|
|
90
|
+
const javaVersionError = this._checkIfJavaVersionIssue();
|
|
91
|
+
if (javaVersionError) {
|
|
92
|
+
throw javaVersionError;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const cliParams = this._convertParamsObjToString(executionContext.getParams(), executionContext.getFlags());
|
|
97
|
+
|
|
98
|
+
const integrationModeOption = executionContext.isIntegrationMode() ? SDK_INTEGRATION_MODE_JVM_OPTION : '';
|
|
99
|
+
|
|
100
|
+
const clientPlatform = `${SDK_CLIENT_PLATFORM_JVM_OPTION}=${this._executionEnvironmentContext.getPlatform()}`;
|
|
101
|
+
const clientPlatformVersionOption = `${SDK_CLIENT_PLATFORM_VERSION_JVM_OPTION}=${this._executionEnvironmentContext.getPlatformVersion()}`;
|
|
102
|
+
const customVmOptions = this._getCustomVmOptionsString();
|
|
103
|
+
|
|
104
|
+
if (!FileUtils.exists(this._sdkPath)) {
|
|
105
|
+
throw NodeTranslationService.getMessage(ERRORS.SDKEXECUTOR.NO_JAR_FILE_FOUND, path.join(__dirname, '..'));
|
|
106
|
+
}
|
|
107
|
+
const quotedSdkJarPath = `"${this._sdkPath}"`;
|
|
108
|
+
|
|
109
|
+
const vmOptions = `${integrationModeOption} ${clientPlatform} ${clientPlatformVersionOption} ${customVmOptions}`;
|
|
110
|
+
const jvmCommand = `java -jar ${vmOptions} ${quotedSdkJarPath} ${executionContext.getCommand()} ${cliParams}`;
|
|
111
|
+
|
|
112
|
+
return spawn(jvmCommand, [], { shell: true });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_convertParamsObjToString(cliParams, flags) {
|
|
116
|
+
let cliParamsAsString = '';
|
|
117
|
+
for (const param in cliParams) {
|
|
118
|
+
if (cliParams.hasOwnProperty(param)) {
|
|
119
|
+
const value = cliParams[param] ? ` ${cliParams[param]} ` : ' ';
|
|
120
|
+
cliParamsAsString += param + value;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (flags && Array.isArray(flags)) {
|
|
125
|
+
flags.forEach((flag) => {
|
|
126
|
+
cliParamsAsString += ` ${flag} `;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return cliParamsAsString;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
_getCustomVmOptionsString() {
|
|
134
|
+
const customVmOptions = this._CLISettingsService.getCustomVmOptions();
|
|
135
|
+
if (!customVmOptions) {
|
|
136
|
+
return '';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const addVmOptionToString = (prevString, vmOptionKey) =>
|
|
140
|
+
(prevString += customVmOptions[vmOptionKey] === '' ? ` ${vmOptionKey}` : ` ${vmOptionKey}="${customVmOptions[vmOptionKey].trim()}"`);
|
|
141
|
+
// customVmOptions are already validated at CLISettingsService, it will be an object at this point
|
|
142
|
+
return Object.keys(customVmOptions).reduce(addVmOptionToString, '').trim();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_checkIfJavaVersionIssue() {
|
|
146
|
+
const javaVersionInstalled = this._environmentInformationService.getInstalledJavaVersionString();
|
|
147
|
+
for (const compatibleJavaVersion of SDK_COMPATIBLE_JAVA_VERSIONS) {
|
|
148
|
+
if (javaVersionInstalled.startsWith(compatibleJavaVersion)) {
|
|
149
|
+
this._CLISettingsService.setJavaVersionValid(true);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
this._CLISettingsService.setJavaVersionValid(false);
|
|
155
|
+
if (javaVersionInstalled === '') {
|
|
156
|
+
return NodeTranslationService.getMessage(ERRORS.CLI_SDK_JAVA_VERSION_NOT_INSTALLED, SDK_COMPATIBLE_JAVA_VERSIONS.join(', '));
|
|
157
|
+
}
|
|
158
|
+
return NodeTranslationService.getMessage(ERRORS.CLI_SDK_JAVA_VERSION_NOT_COMPATIBLE, javaVersionInstalled, SDK_COMPATIBLE_JAVA_VERSIONS.join(', '));
|
|
159
|
+
}
|
|
160
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
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 CommandOptionsValidator = require('../core/CommandOptionsValidator');
|
|
9
|
+
const { throwValidationException } = require('../utils/ExceptionUtils');
|
|
10
|
+
const { ActionResult } = require('../services/actionresult/ActionResult');
|
|
11
|
+
|
|
12
|
+
const BaseAction = require('./base/BaseAction');
|
|
13
|
+
const BaseInputHandler = require('./base/BaseInputHandler');
|
|
14
|
+
const BaseOutputHandler = require('./base/BaseOutputHandler');
|
|
15
|
+
|
|
16
|
+
const INTERACTIVE_MODE = {
|
|
17
|
+
NEVER: 'NEVER',
|
|
18
|
+
ALWAYS: 'ALWAYS',
|
|
19
|
+
DEFAULT: 'DEFAULT',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const NEVER_PARAMS = {
|
|
23
|
+
'CONFIG': 'config',
|
|
24
|
+
'NOCONFIG': 'noconfig',
|
|
25
|
+
'CUSTOMFLAG': 'customflag',
|
|
26
|
+
'CUSTOMOPTIONS': 'customoptions',
|
|
27
|
+
'DEBUG': 'debug'
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** @type {import('./Command')} */
|
|
31
|
+
class Command {
|
|
32
|
+
constructor(options, action, inputHandler, outputHandler) {
|
|
33
|
+
assert(options);
|
|
34
|
+
assert(options.commandMetadata);
|
|
35
|
+
assert(options.projectFolder);
|
|
36
|
+
assert(options.log);
|
|
37
|
+
assert(options.interactiveSupport);
|
|
38
|
+
assert(typeof options.runInInteractiveMode === 'boolean');
|
|
39
|
+
|
|
40
|
+
assert(action, 'Commands must have an action');
|
|
41
|
+
assert(inputHandler, 'Commands must have an input handler');
|
|
42
|
+
assert(outputHandler, 'Commands must have an output handler');
|
|
43
|
+
|
|
44
|
+
this._commandMetadata = options.commandMetadata;
|
|
45
|
+
this._projectFolder = options.projectFolder;
|
|
46
|
+
this.__executionPath = options.executionPath;
|
|
47
|
+
this._runInInteractiveMode = options.runInInteractiveMode;
|
|
48
|
+
this._interactiveSupport = options.interactiveSupport;
|
|
49
|
+
this._log = options.log;
|
|
50
|
+
|
|
51
|
+
this._action = new action(options);
|
|
52
|
+
this._inputHandler = new inputHandler(options);
|
|
53
|
+
this._outputHandler = new outputHandler(options);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get _executionPath(){
|
|
57
|
+
debugger;
|
|
58
|
+
return this.__executionPath;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async run(inputParams) {
|
|
62
|
+
this._cleanNeverParams(inputParams);
|
|
63
|
+
const execParams =
|
|
64
|
+
this._interactiveSupport === INTERACTIVE_MODE.ALWAYS || (this._interactiveSupport !== INTERACTIVE_MODE.NEVER && this._runInInteractiveMode)
|
|
65
|
+
? await this._inputHandler.getParameters(inputParams)
|
|
66
|
+
: inputParams;
|
|
67
|
+
|
|
68
|
+
if( this._interactiveSupport === INTERACTIVE_MODE.ALWAYS || (this._interactiveSupport !== INTERACTIVE_MODE.NEVER && this._runInInteractiveMode)) {
|
|
69
|
+
if( inputParams.authid) execParams.authid = inputParams.authid
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const preExec = await this._action.preExecute(execParams);
|
|
73
|
+
|
|
74
|
+
this._validateActionParameters(preExec);
|
|
75
|
+
|
|
76
|
+
const exec = await this._action.execute(preExec);
|
|
77
|
+
const actionResult = await this._action.postExecute(exec);
|
|
78
|
+
|
|
79
|
+
if (!(actionResult instanceof ActionResult)) {
|
|
80
|
+
throw 'INTERNAL ERROR: Command must return an ActionResult object.';
|
|
81
|
+
} else if (!actionResult.isSuccess()) {
|
|
82
|
+
return this._outputHandler.parseError(actionResult);
|
|
83
|
+
} else {
|
|
84
|
+
return this._outputHandler.parse(actionResult);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_cleanNeverParams(params){
|
|
89
|
+
Object.values(NEVER_PARAMS).forEach((p)=>{
|
|
90
|
+
if( Reflect.has(params,p)) delete params[p];
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_validateActionParameters(params) {
|
|
95
|
+
const commandOptionsValidator = new CommandOptionsValidator();
|
|
96
|
+
const validationErrors = commandOptionsValidator.validate({
|
|
97
|
+
commandOptions: this._commandMetadata.options,
|
|
98
|
+
arguments: params,
|
|
99
|
+
});
|
|
100
|
+
if (validationErrors.length > 0) {
|
|
101
|
+
throwValidationException(validationErrors, this._runInInteractiveMode, this._commandMetadata);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static get Builder() {
|
|
106
|
+
return new CommandBuilder();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
class CommandBuilder {
|
|
111
|
+
constructor() {
|
|
112
|
+
this._options = {
|
|
113
|
+
interactiveSupport: INTERACTIVE_MODE.DEFAULT,
|
|
114
|
+
};
|
|
115
|
+
this._action = BaseAction;
|
|
116
|
+
this._input = BaseInputHandler;
|
|
117
|
+
this._output = BaseOutputHandler;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
withOptions(options) {
|
|
121
|
+
this._options = {
|
|
122
|
+
...this._options,
|
|
123
|
+
...options,
|
|
124
|
+
};
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
neverInteractive() {
|
|
129
|
+
this._options.interactiveSupport = INTERACTIVE_MODE.NEVER;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
alwaysInteractive() {
|
|
134
|
+
this._options.interactiveSupport = INTERACTIVE_MODE.ALWAYS;
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
withAction(action) {
|
|
139
|
+
this._action = action;
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
withInput(input) {
|
|
144
|
+
this._input = input;
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
withOutput(output) {
|
|
149
|
+
this._output = output;
|
|
150
|
+
return this;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
build() {
|
|
154
|
+
return new Command(this._options, this._action, this._input, this._output);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
module.exports = Command;
|