@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/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
There were a lot of places where projectFolder means a relative location to the suitecloud.config.js file
|
|
2
|
+
Many have been removed.
|
|
3
|
+
There is now a concept of executionPath, projectFolder and projectPath and . see the [DELTA](./DELTA.md) glossary.
|
|
4
|
+
|
|
5
|
+
There are still many places in the command generator codes (i.e. [commands](./src/commands)) where `projectFolder` is being used, but it really means projectPath so to the generator invocation passes in projectPath
|
|
6
|
+
|
|
7
|
+
There are environment variables being used and created adhoc. They won't persist so if you are calling any sub-processes be sure to appropriately set `process.env` from the parent.
|
package/DELTA.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Differences between this and @oracle/suitecloud-cli
|
|
2
|
+
|
|
3
|
+
- binary name is `sdf` (not `suitecloud`)
|
|
4
|
+
- package name is `@suitegeezus/suitecloud-cli`
|
|
5
|
+
- `package.json#configFile` can be used to set expected names of config files to hunt for
|
|
6
|
+
- environment variables for AUTHID, PROJECTFOLDER, PROJECTPATH
|
|
7
|
+
- `authid` option available on many commands
|
|
8
|
+
- `project` option available on many commands (to find resource files)
|
|
9
|
+
- `config` option available on many command (to be exact about config file to use)
|
|
10
|
+
- `customflag` option available on any command
|
|
11
|
+
- `customoptions` option available on any command
|
|
12
|
+
- `debug` option available on any command including in interactive
|
|
13
|
+
|
|
14
|
+
<p align="left"><a href="#"><img width="250" src="resources/Netsuite-logo-ocean-150-bg.png"></a></p>
|
|
15
|
+
|
|
16
|
+
- It can coexist with the regular version. You can install both at the same time. But why.
|
|
17
|
+
- They will share account credentials and the underlying SDK. They will reference the same `~/.suitecloud-sdk` resource folder.
|
|
18
|
+
- Example, They can use different config files and not conflict with each other within the same project.
|
|
19
|
+
- By default, this uses `sdf.config.js`.
|
|
20
|
+
- This can be changed in the package json file in the installed directory. `package.json#configFile` setting. The reason this default is different is because older versions of suitecloud do not support "discovery" for a configuration file and thus
|
|
21
|
+
- In this version you can also specify a `config` argument on the command line where you can point to a specific file (which can have any name).
|
|
22
|
+
If you need to change the name or want to use the legacy `suitecloud.config.js` file then consider creating a `sdf.config.js` file that requires that config you already have. Or if you must then you can go to the global package.json and modify this line:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"configFile": "sdf.config"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Prerequisites
|
|
31
|
+
|
|
32
|
+
The following software is required to work with SuiteCloud CLI for Node.js:
|
|
33
|
+
|
|
34
|
+
- Node.js version 22 LTS
|
|
35
|
+
- Oracle JDK version 17 or 21
|
|
36
|
+
|
|
37
|
+
Read the full list of prerequisites in [SuiteCloud CLI for Node.js Installation Prerequisites](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1558708810.html).
|
|
38
|
+
|
|
39
|
+
## Supported Versions
|
|
40
|
+
|
|
41
|
+
To ensure that you get the latest features and bug fixes, you should use the latest version of the SuiteCloud CLI for Node.js available in NPM.
|
|
42
|
+
|
|
43
|
+
The following table shows the CLI versions currently available in NPM.
|
|
44
|
+
|
|
45
|
+
| CLI Versions Available in NPM | Available Since | Compatible NetSuite Version |
|
|
46
|
+
|:-----------------------------:|:---------------:|:---------------------------:|
|
|
47
|
+
| 3.0.X | 2025.1 | 2024.2 and 2025.1 |
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
> 📝 Note that the reason you have to download a file is because of how the source project is structured. i.e. it's not my fault!!!
|
|
52
|
+
|
|
53
|
+
Since CLI for Node.js is a development tool, use a global instance to install it by:
|
|
54
|
+
|
|
55
|
+
1. running the following command:
|
|
56
|
+
|
|
57
|
+
```shell
|
|
58
|
+
cd ~/Downloads
|
|
59
|
+
npm install -g --acceptSuiteCloudSDKLicense @suitegeezus/suitecloud-cli
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You will now have this available from within any directory by running `sdf`.
|
|
63
|
+
|
|
64
|
+
you can verify the installation with this command:
|
|
65
|
+
|
|
66
|
+
```shell
|
|
67
|
+
sdf -h
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
This version CLI for Node.js uses the following syntax (`sdf` not `suitecloud`)
|
|
73
|
+
|
|
74
|
+
```shell
|
|
75
|
+
sdf <command> <option> <argument>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Example: Importing several files
|
|
79
|
+
|
|
80
|
+
Note: this example does not require a config file
|
|
81
|
+
|
|
82
|
+
```shell
|
|
83
|
+
sdf file:import --excludeproperties --authid MY-SANDBOX --project src --paths "/SuiteScripts/myFolder/myFile.js" "/SuiteScripts/myFolder/myFile2.js"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Glossary
|
|
87
|
+
|
|
88
|
+
| Term | Definition |
|
|
89
|
+
|----------------------|-----------------------------------------------------------------------------------------------------------------|
|
|
90
|
+
| Authentication ID | The alias for a authentication configuration to connect to the account |
|
|
91
|
+
| authId | the current value used for the Authentication Id. Command parameter for this might be different for any command |
|
|
92
|
+
| defaultAuthId | the default value for the authId |
|
|
93
|
+
| executionPath | The location where suitecloud was launched. In this version it is not necessarily same as `config` location |
|
|
94
|
+
| projectFolder | The relative path from the execution path |
|
|
95
|
+
| defaultProjectFolder | The default value for projectFolder provided in `config` files |
|
|
96
|
+
| projectPath | the fully resolved form of executionPath + projectFolder |
|
|
97
|
+
|
|
98
|
+
### Commands
|
|
99
|
+
|
|
100
|
+
| Command | Description |
|
|
101
|
+
|----------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
102
|
+
| [`account:manageauth`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157304934116.html) | Manages authentication IDs for all your projects. |
|
|
103
|
+
| [`account:setup`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_89132630266.html) | Sets up an account to use with SuiteCloud SDK and configures the default auth ID for the SuiteCloud project. It requires browser-based login to NetSuite. |
|
|
104
|
+
| [`account:setup:ci`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_81134826821.html) | Sets up an account to use with SuiteCloud SDK and configures the default auth ID for the SuiteCloud project. It does not require browser-based login to NetSuite. This command is helpful for automated environments such as CI. |
|
|
105
|
+
| `custom:hello` | A sanity command to check configuration. You can use hooks but you should leave it ias it is. |
|
|
106
|
+
| `custom:pass` | A passthrough command that does nothing. You can build hooks for it |
|
|
107
|
+
| `custom:job` | Run pre-configured commands such as running admindocs queries. This also supports hooks |
|
|
108
|
+
| `custom:config` | Show location and contents of config file |
|
|
109
|
+
| [`file:create`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_162810635242.html) | Creates SuiteScript files in the selected folder using the correct template with SuiteScript modules injected. |
|
|
110
|
+
| [`file:import`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156041963273.html) | Imports files from an account to your account customization project. |
|
|
111
|
+
| [`file:list`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156042966488.html) | Lists the files in the File Cabinet of your account. |
|
|
112
|
+
| [`file:upload`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_159066070687.html) | Uploads files from your project to an account. |
|
|
113
|
+
| [`object:import`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156042181820.html) | Imports SDF custom objects from an account to your SuiteCloud project. |
|
|
114
|
+
| [`object:list`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156043303237.html) | Lists the SDF custom objects deployed in an account. |
|
|
115
|
+
| [`object:update`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156050566547.html) | Overwrites the SDF custom objects in the project with their matching objects imported from the account. In the case of custom records, custom instances can be included. |
|
|
116
|
+
| [`project:adddependencies`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_155981452469.html) | Adds missing dependencies to the manifest file. |
|
|
117
|
+
| [`project:create`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156041348327.html) | Creates a SuiteCloud project, either a SuiteApp or an account customization project (ACP). |
|
|
118
|
+
| [`project:deploy`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156044636320.html) | Deploys the folder containing the project. |
|
|
119
|
+
| [`project:package`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_159550971388.html) | Generates a ZIP file from your project, respecting the structure specified in the deploy.xml file. |
|
|
120
|
+
| [`project:validate`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156049843194.html) | Validates the folder containing the SuiteCloud project. |
|
|
121
|
+
|
|
122
|
+
To check the help for a specific command, run the following command:
|
|
123
|
+
|
|
124
|
+
```shell
|
|
125
|
+
sdf {command} -h
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Read the detailed documentation for all the commands in [SuiteCloud CLI for Node.js Reference](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_155931263126.html).
|
|
129
|
+
|
|
130
|
+
#### About Custom Command Configuration: Authorization, Project-Folder and custom command hooks
|
|
131
|
+
|
|
132
|
+
Custom Configuration is provided via `sdf.config.js`. The `project:create` action will result in a `sdf.config.js` file.
|
|
133
|
+
This file can be changed at any time.
|
|
134
|
+
Previously, suitecloud required you to run in the same directory as the config file.
|
|
135
|
+
Now, when you run `sdf` executable it will "walk-up" the directory tree until it finds a `sdf.config.js` file. Specifically, it wil stop walking when it finds:
|
|
136
|
+
|
|
137
|
+
1. `sdf.config.js` or `sdf.config.json` file.
|
|
138
|
+
2. the project root (i.e. `package.json` file).
|
|
139
|
+
3. fallback to sub-folder containing any discovered `FileCabinet`, `Objects` or `AccountConfiguration` directory.
|
|
140
|
+
|
|
141
|
+
The location of the discovered `sdf.config` file is considered the project root.
|
|
142
|
+
|
|
143
|
+
Running this command will show you the discovered root and the contents of the sdf config file:
|
|
144
|
+
|
|
145
|
+
```shell
|
|
146
|
+
# TODO
|
|
147
|
+
sdf custom:config --show
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Project Folder & Project Root
|
|
151
|
+
|
|
152
|
+
The projectFolder is not the location of the `sdf.config.js`. It can be anywhere on your file system, but typically it is the same directory or a subDirectory of the project. It can be overridden in some commands using the `--project` flag
|
|
153
|
+
|
|
154
|
+
If the config (or command line override) specifies a value for `defaultProjectFolder` then that value is appended to the project root to determine the `projectFolder`. That location is expected to contain things such as:
|
|
155
|
+
|
|
156
|
+
- manifest.xml
|
|
157
|
+
- deploy.xml
|
|
158
|
+
- FileCabinet directory
|
|
159
|
+
- Objects directory
|
|
160
|
+
- AccountConfiguration directory
|
|
161
|
+
|
|
162
|
+
many `sdf` commands can run without any config file. You may need to provide additional command line flags in lieu.
|
|
163
|
+
|
|
164
|
+
There are some commands where a `manifest.xml` file or `deploy.xml` file is required in the discovered root, but the file isn't actually
|
|
165
|
+
use. In this case you could use the hook to detect this and create a dummy file and then remove it onCompleted.
|
|
166
|
+
TODO: use `--forceManifest` which will create a temporary `manifest.xml` file and then remove it when done.
|
|
167
|
+
|
|
168
|
+
Ranked from top priority to bottom priority
|
|
169
|
+
|
|
170
|
+
1. ~~value of `project` being returned by the `beforeExecuting` command hook via options. i.e. `options.arguments.project`.~~
|
|
171
|
+
- this property is available in the method but changes to this specific property by the method will be ignored.
|
|
172
|
+
2. value of `projectFolder` property specified on the command's specific authId (if it has one)
|
|
173
|
+
3. value of `project` argument on the command line
|
|
174
|
+
4. value of `SUITECLOUD_PROJECT_FOLDER` environment variable
|
|
175
|
+
5. value of `defaultProjectFolder` in any project.json file (backwards compatibility)
|
|
176
|
+
6. value of `defaultProjectFolder` property at the top level of any discovered `sdf.config.js` file (backwards compatibility)
|
|
177
|
+
7. implied as the "Discovered" location
|
|
178
|
+
|
|
179
|
+
#### Authorization & Authenticated ID
|
|
180
|
+
|
|
181
|
+
Authorization is defined in advance as "authentication ID"s. You can have many of these available to you, but when you run a command you must designate one of them to use.
|
|
182
|
+
|
|
183
|
+
A command that requires authenticating supports the `authid` flag. This was always the case, but was suppressed in the command line interpreter and instead read from the `<projectFolder>/project.json` file. (This was previous a required file).
|
|
184
|
+
|
|
185
|
+
Further, authorization was provided ONLY via the local `project.json` file. This file is now optional, but support exists for backward compatibility. Setting authorization this way is deprecated and easily overridden.
|
|
186
|
+
|
|
187
|
+
Previously, when you wanted to run a command with a different authorization ID you would need to modify the `project.json` file manually or with a separate command. Then you would run the command that you want.
|
|
188
|
+
Now, you can provide the authorization ID adhoc in several different ways. This multi-faceted configuration can be confusing, but there is a priority sequence for determining which authorization ID to use:
|
|
189
|
+
|
|
190
|
+
Ranked from top priority to bottom priority
|
|
191
|
+
|
|
192
|
+
1. value of `authid` being returned by the `beforeExecuting` command hook via options. i.e. `options.arguments.authid`.
|
|
193
|
+
2. value of `authId` property specified on the command's specific authId (if it has one)
|
|
194
|
+
3. value of `authid` argument on the command line
|
|
195
|
+
4. value of `SUITECLOUD_AUTHID` environment variable
|
|
196
|
+
5. value of `defaultAuthId` in the project.json file (backwards compatibility)
|
|
197
|
+
6. value of `defaultAuthId` property at the top level of any discovered `sdf.config.js` file
|
|
198
|
+
|
|
199
|
+
Note: the `authid` command option is never required as you can continue to provide it as a base-level configuration. However, it is highly recommended.
|
|
200
|
+
|
|
201
|
+
## Getting Started
|
|
202
|
+
|
|
203
|
+
🎞 To see how to install and set up CLI for Node.js, watch the following video:
|
|
204
|
+
|
|
205
|
+
<a href="https://videohub.oracle.com/media/Setting+Up+CLI+for+Nodej.s/0_091fc2ca"><img src="resources/video_setting_up_nodejs_cli.png" alt="Setting up CLI for Node.js video" width="400"></a>
|
|
206
|
+
|
|
207
|
+
Create a new project in an empty folder by running the following command:
|
|
208
|
+
|
|
209
|
+
```shell
|
|
210
|
+
sdf project:create -i
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
After you create a project, configure a NetSuite account, by running the following command within the project folder:
|
|
214
|
+
|
|
215
|
+
```shell
|
|
216
|
+
sdf account:setup
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Release Notes & Documentation
|
|
220
|
+
|
|
221
|
+
To read the 2025.1 NetSuite's release notes and documentation, check the following sections of NetSuite's Help Center:
|
|
222
|
+
|
|
223
|
+
- Read the release notes for NetSuite 2025.1 in [SuiteCloud SDK Release Notes](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1558730192.html).
|
|
224
|
+
- Read the latest updates under SuiteCloud SDK in the [Help Center Weekly Updates](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_3798389663.html).
|
|
225
|
+
- Read the CLI for Node.js documentation in [SuiteCloud CLI for Node.js Guide](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_1558708800.html).
|
|
226
|
+
|
|
227
|
+
## Contributing
|
|
228
|
+
|
|
229
|
+
SuiteCloud CLI for Node.js is an open source project. Pull Requests are currently not being accepted. See [Contributing](/CONTRIBUTING.md) for details.
|
|
230
|
+
|
|
231
|
+
## [License](/LICENSE.txt)
|
|
232
|
+
|
|
233
|
+
Copyright (c) 2022, 2023, 2024, 2025 Oracle and/or its affiliates The Universal Permissive License (UPL), Version 1.0.
|
|
234
|
+
|
|
235
|
+
By installing SuiteCloud CLI for Node.js, you are accepting the installation of the SuiteCloud SDK dependency under the [Oracle Free Use Terms and Conditions](https://www.oracle.com/downloads/licenses/oracle-free-license.html) license.
|
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<p align="left"><a href="#"><img width="250" src="resources/Netsuite-logo-ocean-150-bg.png"></a></p>
|
|
2
|
+
|
|
3
|
+
# SuiteCloud CLI for Node.js
|
|
4
|
+
<p>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@oracle/suitecloud-cli">
|
|
6
|
+
<img src="https://img.shields.io/npm/dm/@oracle/suitecloud-cli.svg" alt="npm-cli"/>
|
|
7
|
+
<img src="https://img.shields.io/npm/v/@oracle/suitecloud-cli.svg" alt="npm-cli"/>
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
SuiteCloud Command Line Interface (CLI) for Node.js is a SuiteCloud SDK tool to manage SuiteCloud project components and validate and deploy projects to your account.\
|
|
12
|
+
CLI for Node.js is an interactive tool that guides you through all the steps of the communication between your local project and your account.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
The following software is required to work with SuiteCloud CLI for Node.js:
|
|
16
|
+
- Node.js version 22 LTS
|
|
17
|
+
- Oracle JDK version 17 or 21
|
|
18
|
+
|
|
19
|
+
Read the full list of prerequisites in [SuiteCloud CLI for Node.js Installation Prerequisites](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1558708810.html).
|
|
20
|
+
|
|
21
|
+
## Supported Versions
|
|
22
|
+
To ensure that you get the latest features and bug fixes, you should use the latest version of the SuiteCloud CLI for Node.js available in NPM.
|
|
23
|
+
|
|
24
|
+
The following table shows the CLI versions currently available in NPM.
|
|
25
|
+
|
|
26
|
+
| CLI Versions Available in NPM |
|
|
27
|
+
|:-----------------------------:|
|
|
28
|
+
| 3.1.2 |
|
|
29
|
+
| 3.1.1 |
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
Since CLI for Node.js is a development tool, use a global instance to install it by running the following command:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
npm install -g @oracle/suitecloud-cli
|
|
37
|
+
```
|
|
38
|
+
When installing SuiteCloud CLI for Node.js via script, for instance in a CI environment, you can skip showing the license presented during the normal installation process by adding the --acceptSuiteCloudSDKLicense flag to the install script as shown below. Note that by adding the mentioned flag to the script, you confirm that you have read and accepted the Oracle Free Use Terms and Conditions license. See the [License](#license) section for details.
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
npm install -g --acceptSuiteCloudSDKLicense @oracle/suitecloud-cli
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
CLI for Node.js is available from within any directory by running `suitecloud`.
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
CLI for Node.js uses the following syntax:
|
|
49
|
+
```
|
|
50
|
+
suitecloud <command> <option> <argument>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Commands
|
|
54
|
+
| Command | Description |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
|[`account:manageauth`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157304934116.html)|Manages authentication IDs for all your projects.|
|
|
57
|
+
|[`account:setup`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_89132630266.html)|Sets up an account to use with SuiteCloud SDK and configures the default auth ID for the SuiteCloud project. It requires browser-based login to NetSuite.|
|
|
58
|
+
|[`account:setup:ci`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/article_81134826821.html)|Sets up an account to use with SuiteCloud SDK and configures the default auth ID for the SuiteCloud project. It also allows you to select an existing auth ID for the SuiteCloud project. This command does not require browser-based login to NetSuite and is helpful for automated environments such as CI.|
|
|
59
|
+
|[`file:create`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_162810635242.html)|Creates SuiteScript files in the selected folder using the correct template with SuiteScript modules injected.|
|
|
60
|
+
|[`file:import`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156041963273.html)|Imports files from an account to your account customization project.|
|
|
61
|
+
|[`file:list`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156042966488.html)|Lists the files in the File Cabinet of your account.|
|
|
62
|
+
|[`file:upload`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_159066070687.html)|Uploads files from your project to an account.|
|
|
63
|
+
|[`object:import`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156042181820.html)|Imports SDF custom objects from an account to your SuiteCloud project.|
|
|
64
|
+
|[`object:list`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156043303237.html)|Lists the SDF custom objects deployed in an account.|
|
|
65
|
+
|[`object:update`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156050566547.html)|Overwrites the SDF custom objects in the project with their matching objects imported from the account. In the case of custom records, custom instances can be included.|
|
|
66
|
+
|[`project:adddependencies`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_155981452469.html)| Adds missing dependencies to the manifest file.|
|
|
67
|
+
|[`project:create`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156041348327.html)|Creates a SuiteCloud project, either a SuiteApp or an account customization project (ACP).|
|
|
68
|
+
|[`project:deploy`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156044636320.html)|Deploys the folder containing the project.|
|
|
69
|
+
|[`project:package`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_159550971388.html)|Generates a ZIP file from your project, respecting the structure specified in the deploy.xml file.|
|
|
70
|
+
|[`project:validate`](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_156049843194.html)|Validates the folder containing the SuiteCloud project.|
|
|
71
|
+
|
|
72
|
+
To check the help for a specific command, run the following command:
|
|
73
|
+
```
|
|
74
|
+
suitecloud {command} -h
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Read the detailed documentation for all the commands in [SuiteCloud CLI for Node.js Reference](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_155931263126.html).
|
|
78
|
+
|
|
79
|
+
## Getting Started
|
|
80
|
+
🎞 To see how to install and set up CLI for Node.js, watch the following video:
|
|
81
|
+
|
|
82
|
+
<a href="https://videohub.oracle.com/media/Setting+Up+CLI+for+Nodej.s/0_091fc2ca"><img src="resources/video_setting_up_nodejs_cli.png" alt="Setting up CLI for Node.js video" width="400"></a>
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
Create a new project in an empty folder by running the following command:
|
|
86
|
+
```
|
|
87
|
+
suitecloud project:create -i
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
After you create a project, configure a NetSuite account, by running the following command within the project folder:
|
|
91
|
+
```
|
|
92
|
+
suitecloud account:setup
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Release Notes & Documentation
|
|
96
|
+
To read the 2025.2 NetSuite's release notes and documentation, check the following sections of NetSuite's Help Center:
|
|
97
|
+
- Read the release notes for NetSuite 2025.2 in [SuiteCloud SDK Release Notes](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1558730192.html).
|
|
98
|
+
- Read the latest updates under SuiteCloud SDK in the [Help Center Weekly Updates](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_3798389663.html).
|
|
99
|
+
- Read the CLI for Node.js documentation in [SuiteCloud CLI for Node.js Guide](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_1558708800.html).
|
|
100
|
+
|
|
101
|
+
## Contributing
|
|
102
|
+
SuiteCloud CLI for Node.js is an open source project. Pull Requests are currently not being accepted. See [Contributing](/CONTRIBUTING.md) for details.
|
|
103
|
+
|
|
104
|
+
## [License](/LICENSE.txt)
|
|
105
|
+
Copyright (c) 2019, 2023 Oracle and/or its affiliates The Universal Permissive License (UPL), Version 1.0.
|
|
106
|
+
|
|
107
|
+
By installing SuiteCloud CLI for Node.js, you are accepting the installation of the SuiteCloud SDK dependency under the [Oracle Free Use Terms and Conditions](https://www.oracle.com/downloads/licenses/oracle-free-license.html) license.
|
package/docs/Command.md
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Command.js Architecture
|
|
2
|
+
|
|
3
|
+
This document explains how the `Command.js` module works in the SuiteCloud Node CLI.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `Command` class (`src/commands/Command.js`) implements a **command pattern** with a **builder pattern** for constructing CLI commands. It orchestrates the execution of commands by coordinating three components:
|
|
8
|
+
|
|
9
|
+
1. **Action** - Executes the core business logic
|
|
10
|
+
2. **InputHandler** - Gathers and processes input parameters
|
|
11
|
+
3. **OutputHandler** - Formats and displays results
|
|
12
|
+
|
|
13
|
+
## Class Structure
|
|
14
|
+
|
|
15
|
+
### Command Class
|
|
16
|
+
|
|
17
|
+
The main `Command` class accepts four constructor arguments:
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
constructor(options, action, inputHandler, outputHandler)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
#### Required Options
|
|
24
|
+
|
|
25
|
+
| Option | Type | Description |
|
|
26
|
+
|--------|------|-------------|
|
|
27
|
+
| `commandMetadata` | Object | Metadata about the command including name and options |
|
|
28
|
+
| `projectFolder` | String | Path to the project folder |
|
|
29
|
+
| `log` | Object | Logger instance for output |
|
|
30
|
+
| `interactiveSupport` | String | Interactive mode setting (NEVER, ALWAYS, DEFAULT) |
|
|
31
|
+
| `runInInteractiveMode` | Boolean | Whether to run in interactive mode |
|
|
32
|
+
|
|
33
|
+
#### Optional Options
|
|
34
|
+
|
|
35
|
+
| Option | Type | Description |
|
|
36
|
+
|--------|------|-------------|
|
|
37
|
+
| `executionPath` | String | Path where command is executed |
|
|
38
|
+
| `sdkPath` | String | Path to the SDK |
|
|
39
|
+
| `executionEnvironmentContext` | Object | Environment context for execution |
|
|
40
|
+
|
|
41
|
+
## Interactive Modes
|
|
42
|
+
|
|
43
|
+
The command supports three interactive modes:
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
const INTERACTIVE_MODE = {
|
|
47
|
+
NEVER: 'NEVER', // Never prompt for input
|
|
48
|
+
ALWAYS: 'ALWAYS', // Always prompt for input
|
|
49
|
+
DEFAULT: 'DEFAULT', // Use runInInteractiveMode setting
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Execution Flow
|
|
54
|
+
|
|
55
|
+
The `run(inputParams)` method executes commands in this order:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
59
|
+
│ run(inputParams) │
|
|
60
|
+
└─────────────────────────────────────────────────────────────┘
|
|
61
|
+
│
|
|
62
|
+
▼
|
|
63
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
64
|
+
│ 1. INPUT HANDLING │
|
|
65
|
+
│ - If interactive mode enabled: │
|
|
66
|
+
│ inputHandler.getParameters(inputParams) → execParams │
|
|
67
|
+
│ - Otherwise: use inputParams directly │
|
|
68
|
+
└─────────────────────────────────────────────────────────────┘
|
|
69
|
+
│
|
|
70
|
+
▼
|
|
71
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
72
|
+
│ 2. PRE-EXECUTE │
|
|
73
|
+
│ action.preExecute(execParams) → preExec │
|
|
74
|
+
│ (Transform/validate params before execution) │
|
|
75
|
+
└─────────────────────────────────────────────────────────────┘
|
|
76
|
+
│
|
|
77
|
+
▼
|
|
78
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
79
|
+
│ 3. VALIDATION │
|
|
80
|
+
│ _validateActionParameters(preExec) │
|
|
81
|
+
│ (Checks mandatory options are present) │
|
|
82
|
+
└─────────────────────────────────────────────────────────────┘
|
|
83
|
+
│
|
|
84
|
+
▼
|
|
85
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
86
|
+
│ 4. EXECUTE │
|
|
87
|
+
│ action.execute(preExec) → exec │
|
|
88
|
+
│ (Core business logic) │
|
|
89
|
+
└─────────────────────────────────────────────────────────────┘
|
|
90
|
+
│
|
|
91
|
+
▼
|
|
92
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
93
|
+
│ 5. POST-EXECUTE │
|
|
94
|
+
│ action.postExecute(exec) → actionResult │
|
|
95
|
+
│ (Process/transform execution results) │
|
|
96
|
+
└─────────────────────────────────────────────────────────────┘
|
|
97
|
+
│
|
|
98
|
+
▼
|
|
99
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
100
|
+
│ 6. OUTPUT HANDLING │
|
|
101
|
+
│ - If success: outputHandler.parse(actionResult) │
|
|
102
|
+
│ - If error: outputHandler.parseError(actionResult) │
|
|
103
|
+
└─────────────────────────────────────────────────────────────┘
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Builder Pattern
|
|
107
|
+
|
|
108
|
+
Commands are created using the `CommandBuilder` class accessed via `Command.Builder`:
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
const command = Command.Builder
|
|
112
|
+
.withOptions(options)
|
|
113
|
+
.withAction(MyAction)
|
|
114
|
+
.withInput(MyInputHandler)
|
|
115
|
+
.withOutput(MyOutputHandler)
|
|
116
|
+
.build();
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Builder Methods
|
|
120
|
+
|
|
121
|
+
| Method | Description |
|
|
122
|
+
|--------|-------------|
|
|
123
|
+
| `withOptions(options)` | Set command options |
|
|
124
|
+
| `withAction(action)` | Set the action class |
|
|
125
|
+
| `withInput(input)` | Set the input handler class |
|
|
126
|
+
| `withOutput(output)` | Set the output handler class |
|
|
127
|
+
| `neverInteractive()` | Disable interactive mode |
|
|
128
|
+
| `alwaysInteractive()` | Force interactive mode |
|
|
129
|
+
| `build()` | Create the Command instance |
|
|
130
|
+
|
|
131
|
+
## Base Classes
|
|
132
|
+
|
|
133
|
+
### BaseAction (`src/commands/base/BaseAction.js`)
|
|
134
|
+
|
|
135
|
+
Abstract base class for command actions.
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
class BaseAction {
|
|
139
|
+
constructor(options) // Initialize with options
|
|
140
|
+
async preExecute(params) // Transform params before execution (default: passthrough)
|
|
141
|
+
async execute(params) // Core logic (must be overridden)
|
|
142
|
+
async postExecute(result) // Process results after execution (default: passthrough)
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The `BaseAction` also initializes an `SdkExecutor` for executing SDK operations.
|
|
147
|
+
|
|
148
|
+
### BaseInputHandler (`src/commands/base/BaseInputHandler.js`)
|
|
149
|
+
|
|
150
|
+
Abstract base class for input handling.
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
class BaseInputHandler {
|
|
154
|
+
constructor(options) // Initialize with options
|
|
155
|
+
async getParameters(params) // Gather/transform input params (default: passthrough)
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### BaseOutputHandler (`src/commands/base/BaseOutputHandler.js`)
|
|
160
|
+
|
|
161
|
+
Abstract base class for output formatting.
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
class BaseOutputHandler {
|
|
165
|
+
constructor(options) // Initialize with options
|
|
166
|
+
parse(actionResult) // Format success output (default: passthrough)
|
|
167
|
+
parseError(actionResult) // Format error output (logs error messages)
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## ActionResult
|
|
172
|
+
|
|
173
|
+
All commands must return an `ActionResult` object from `services/actionresult/ActionResult.js`.
|
|
174
|
+
|
|
175
|
+
### Creating Success Results
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
const { ActionResult } = require('../../services/actionresult/ActionResult');
|
|
179
|
+
|
|
180
|
+
return ActionResult.Builder
|
|
181
|
+
.withData({ /* result data */ })
|
|
182
|
+
.withResultMessage('Operation completed successfully')
|
|
183
|
+
.build();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Creating Error Results
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
return ActionResult.Builder
|
|
190
|
+
.withErrors(['Error message 1', 'Error message 2'])
|
|
191
|
+
.build();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Example: Creating a New Command
|
|
195
|
+
|
|
196
|
+
### 1. Create the Action
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
// src/commands/example/ExampleAction.js
|
|
200
|
+
const BaseAction = require('../base/BaseAction');
|
|
201
|
+
const { ActionResult } = require('../../services/actionresult/ActionResult');
|
|
202
|
+
|
|
203
|
+
module.exports = class ExampleAction extends BaseAction {
|
|
204
|
+
async preExecute(params) {
|
|
205
|
+
// Optional: transform params before execution
|
|
206
|
+
return { ...params, timestamp: Date.now() };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async execute(params) {
|
|
210
|
+
// Core business logic
|
|
211
|
+
try {
|
|
212
|
+
const result = await this._sdkExecutor.execute(/* ... */);
|
|
213
|
+
return ActionResult.Builder.withData(result).build();
|
|
214
|
+
} catch (error) {
|
|
215
|
+
return ActionResult.Builder.withErrors([error.message]).build();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async postExecute(actionResult) {
|
|
220
|
+
// Optional: post-process results
|
|
221
|
+
return actionResult;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 2. Create the Input Handler
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// src/commands/example/ExampleInputHandler.js
|
|
230
|
+
const BaseInputHandler = require('../base/BaseInputHandler');
|
|
231
|
+
|
|
232
|
+
module.exports = class ExampleInputHandler extends BaseInputHandler {
|
|
233
|
+
async getParameters(params) {
|
|
234
|
+
// Prompt for missing parameters in interactive mode
|
|
235
|
+
if (!params.name) {
|
|
236
|
+
params.name = await this._promptForName();
|
|
237
|
+
}
|
|
238
|
+
return params;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 3. Create the Output Handler
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
// src/commands/example/ExampleOutputHandler.js
|
|
247
|
+
const BaseOutputHandler = require('../base/BaseOutputHandler');
|
|
248
|
+
|
|
249
|
+
module.exports = class ExampleOutputHandler extends BaseOutputHandler {
|
|
250
|
+
parse(actionResult) {
|
|
251
|
+
this._log.info(`Success: ${actionResult.resultMessage}`);
|
|
252
|
+
return actionResult;
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 4. Create the Command Factory
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
// src/commands/example/ExampleCommand.js
|
|
261
|
+
const Command = require('../Command');
|
|
262
|
+
const ExampleAction = require('./ExampleAction');
|
|
263
|
+
const ExampleInputHandler = require('./ExampleInputHandler');
|
|
264
|
+
const ExampleOutputHandler = require('./ExampleOutputHandler');
|
|
265
|
+
|
|
266
|
+
module.exports = {
|
|
267
|
+
create(options) {
|
|
268
|
+
return Command.Builder
|
|
269
|
+
.withOptions(options)
|
|
270
|
+
.withAction(ExampleAction)
|
|
271
|
+
.withInput(ExampleInputHandler)
|
|
272
|
+
.withOutput(ExampleOutputHandler)
|
|
273
|
+
.build();
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Validation
|
|
279
|
+
|
|
280
|
+
The `CommandOptionsValidator` (`src/core/CommandOptionsValidator.js`) validates that all mandatory options are present before command execution. Validation errors are thrown using `throwValidationException` from `utils/ExceptionUtils.js`.
|
|
281
|
+
|
|
282
|
+
Validation occurs after `preExecute` but before `execute`, allowing `preExecute` to set default values or derive parameters before validation.
|
|
283
|
+
|
|
284
|
+
## File Structure
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
src/commands/
|
|
288
|
+
├── Command.js # Main Command class with Builder
|
|
289
|
+
├── base/
|
|
290
|
+
│ ├── BaseAction.js # Abstract action base class
|
|
291
|
+
│ ├── BaseInputHandler.js # Abstract input handler base class
|
|
292
|
+
│ └── BaseOutputHandler.js # Abstract output handler base class
|
|
293
|
+
└── <command-group>/
|
|
294
|
+
└── <command-name>/
|
|
295
|
+
├── <Command>Action.js
|
|
296
|
+
├── <Command>Command.js
|
|
297
|
+
├── <Command>InputHandler.js
|
|
298
|
+
└── <Command>OutputHandler.js
|
|
299
|
+
```
|