@contrail/cli 3.0.6 → 3.1.1

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/README.md CHANGED
@@ -17,7 +17,7 @@ $ npm install -g @contrail/cli
17
17
  $ contrail COMMAND
18
18
  running command...
19
19
  $ contrail (--version)
20
- @contrail/cli/3.0.6 darwin-x64 node-v20.19.1
20
+ @contrail/cli/3.1.1 darwin-arm64 node-v20.18.0
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -34,6 +34,8 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
34
34
  <!-- commands -->
35
35
  * [`contrail app create`](#contrail-app-create)
36
36
  * [`contrail app delete`](#contrail-app-delete)
37
+ * [`contrail app extension deploy`](#contrail-app-extension-deploy)
38
+ * [`contrail app extension deployment list`](#contrail-app-extension-deployment-list)
37
39
  * [`contrail app getApiKey`](#contrail-app-getapikey)
38
40
  * [`contrail app init`](#contrail-app-init)
39
41
  * [`contrail app install`](#contrail-app-install)
@@ -59,15 +61,6 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
59
61
  * [`contrail load custom-entity DATAFILE CONFIGFILE`](#contrail-load-custom-entity-datafile-configfile)
60
62
  * [`contrail load line-sheet DATAFILE CONFIGFILE`](#contrail-load-line-sheet-datafile-configfile)
61
63
  * [`contrail load upload-and-load INCOMINGFILE CONFIGFILENAME`](#contrail-load-upload-and-load-incomingfile-configfilename)
62
- * [`contrail plugins`](#contrail-plugins)
63
- * [`contrail plugins:install PLUGIN...`](#contrail-pluginsinstall-plugin)
64
- * [`contrail plugins:inspect PLUGIN...`](#contrail-pluginsinspect-plugin)
65
- * [`contrail plugins:install PLUGIN...`](#contrail-pluginsinstall-plugin-1)
66
- * [`contrail plugins:link PLUGIN`](#contrail-pluginslink-plugin)
67
- * [`contrail plugins:uninstall PLUGIN...`](#contrail-pluginsuninstall-plugin)
68
- * [`contrail plugins:uninstall PLUGIN...`](#contrail-pluginsuninstall-plugin-1)
69
- * [`contrail plugins:uninstall PLUGIN...`](#contrail-pluginsuninstall-plugin-2)
70
- * [`contrail plugins update`](#contrail-plugins-update)
71
64
  * [`contrail projects export PROJECTNAME`](#contrail-projects-export-projectname)
72
65
  * [`contrail projects list`](#contrail-projects-list)
73
66
  * [`contrail projects load TEMPLATEFILELOCATION`](#contrail-projects-load-templatefilelocation)
@@ -108,7 +101,7 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
108
101
 
109
102
  ## `contrail app create`
110
103
 
111
- Create an app from a template
104
+ Create a new app. The current organization will be set as the owner of the app
112
105
 
113
106
  ```
114
107
  USAGE
@@ -121,7 +114,7 @@ FLAGS
121
114
  <options: error|warn|info|debug>
122
115
 
123
116
  DESCRIPTION
124
- Create an app from a template
117
+ Create a new app. The current organization will be set as the owner of the app
125
118
 
126
119
  EXAMPLES
127
120
  $ contrail app create
@@ -148,9 +141,54 @@ EXAMPLES
148
141
  $ contrail app delete
149
142
  ```
150
143
 
144
+ ## `contrail app extension deploy`
145
+
146
+ Deploy an extension from the extensions directory to a VibeIQ managed URL.
147
+
148
+ ```
149
+ USAGE
150
+ $ contrail app extension deploy -i <value> [-l error|warn|info|debug] [-e true|false]
151
+
152
+ FLAGS
153
+ -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
154
+ <options: true|false>
155
+ -i, --identifier=<value> (required) The extension identifier to deploy. The identifier of the extension is the
156
+ "identifier" property in the extension defined in the app.yml
157
+ -l, --logLevel=<option> The Log Level
158
+ <options: error|warn|info|debug>
159
+
160
+ DESCRIPTION
161
+ Deploy an extension from the extensions directory to a VibeIQ managed URL.
162
+
163
+ EXAMPLES
164
+ $ contrail extension deploy --identifier <extensionIdentifier>
165
+ ```
166
+
167
+ ## `contrail app extension deployment list`
168
+
169
+ List extension deployments
170
+
171
+ ```
172
+ USAGE
173
+ $ contrail app extension deployment list [-l error|warn|info|debug] [-e true|false] [-a]
174
+
175
+ FLAGS
176
+ -a, --all List all extension deployments. By default, only the latest 20 are shown
177
+ -e, --alwaysConfirmEnv=<option> [default: true] The Environment variables
178
+ <options: true|false>
179
+ -l, --logLevel=<option> The Log Level
180
+ <options: error|warn|info|debug>
181
+
182
+ DESCRIPTION
183
+ List extension deployments
184
+
185
+ EXAMPLES
186
+ $ contrail extension deployment list
187
+ ```
188
+
151
189
  ## `contrail app getApiKey`
152
190
 
153
- Get an api key for an app
191
+ Get an api key for an installed app
154
192
 
155
193
  ```
156
194
  USAGE
@@ -164,7 +202,7 @@ FLAGS
164
202
  <options: error|warn|info|debug>
165
203
 
166
204
  DESCRIPTION
167
- Get an api key for an app
205
+ Get an api key for an installed app
168
206
 
169
207
  EXAMPLES
170
208
  $ contrail app getApiKey
@@ -193,7 +231,7 @@ EXAMPLES
193
231
 
194
232
  ## `contrail app install`
195
233
 
196
- Install an app from the marketplace
234
+ Install an app from the marketplace to a specific organization
197
235
 
198
236
  ```
199
237
  USAGE
@@ -208,7 +246,7 @@ FLAGS
208
246
  -w, --installWorkflowTemplates "Install the app's accompanying workflows"
209
247
 
210
248
  DESCRIPTION
211
- Install an app from the marketplace
249
+ Install an app from the marketplace to a specific organization
212
250
 
213
251
  EXAMPLES
214
252
  $ contrail app install --appIdentifier @VibeIQ/Flex-PLM-Connector
@@ -216,7 +254,7 @@ EXAMPLES
216
254
 
217
255
  ## `contrail app publish`
218
256
 
219
- Publish the app
257
+ Publish the app to the marketplace. This visibility of your app depends on the app.yml configuration ("visibility" property)
220
258
 
221
259
  ```
222
260
  USAGE
@@ -233,7 +271,8 @@ FLAGS
233
271
  -v, --verbose Debug the app deployment step and do not remove the intermediate build artifacts.
234
272
 
235
273
  DESCRIPTION
236
- Publish the app
274
+ Publish the app to the marketplace. This visibility of your app depends on the app.yml configuration ("visibility"
275
+ property)
237
276
 
238
277
  EXAMPLES
239
278
  $ contrail app publish
@@ -241,7 +280,7 @@ EXAMPLES
241
280
 
242
281
  ## `contrail app uninstall`
243
282
 
244
- Uninstall an app that is currently installed
283
+ Uninstall an app that is currently installed in a specific organization
245
284
 
246
285
  ```
247
286
  USAGE
@@ -256,7 +295,7 @@ FLAGS
256
295
  <options: error|warn|info|debug>
257
296
 
258
297
  DESCRIPTION
259
- Uninstall an app that is currently installed
298
+ Uninstall an app that is currently installed in a specific organization
260
299
 
261
300
  EXAMPLES
262
301
  $ contrail app uninstall --name @vibeiq/flexplm-connector
@@ -264,7 +303,7 @@ EXAMPLES
264
303
 
265
304
  ## `contrail app upgrade`
266
305
 
267
- Upgrade an installed app
306
+ Upgrade an installed app in a specific organization
268
307
 
269
308
  ```
270
309
  USAGE
@@ -279,7 +318,7 @@ FLAGS
279
318
  <options: error|warn|info|debug>
280
319
 
281
320
  DESCRIPTION
282
- Upgrade an installed app
321
+ Upgrade an installed app in a specific organization
283
322
 
284
323
  EXAMPLES
285
324
  $ contrail app upgrade --appIdentifier @VibeIQ/Flex-PLM-Connector --latest
@@ -401,7 +440,7 @@ EXAMPLES
401
440
 
402
441
  ## `contrail config describe [NAME]`
403
442
 
404
- Describe a configuration file
443
+ Display the contents of a configuration file
405
444
 
406
445
  ```
407
446
  USAGE
@@ -417,7 +456,7 @@ FLAGS
417
456
  <options: error|warn|info|debug>
418
457
 
419
458
  DESCRIPTION
420
- Describe a configuration file
459
+ Display the contents of a configuration file
421
460
 
422
461
  EXAMPLES
423
462
  $ contrail config describe demo-org
@@ -737,249 +776,6 @@ EXAMPLES
737
776
  $ contrail load-processor upload-and-load <File Path> <Config Path>
738
777
  ```
739
778
 
740
- ## `contrail plugins`
741
-
742
- List installed plugins.
743
-
744
- ```
745
- USAGE
746
- $ contrail plugins [--core]
747
-
748
- FLAGS
749
- --core Show core plugins.
750
-
751
- DESCRIPTION
752
- List installed plugins.
753
-
754
- EXAMPLES
755
- $ contrail plugins
756
- ```
757
-
758
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/index.ts)_
759
-
760
- ## `contrail plugins:install PLUGIN...`
761
-
762
- Installs a plugin into the CLI.
763
-
764
- ```
765
- USAGE
766
- $ contrail plugins:install PLUGIN...
767
-
768
- ARGUMENTS
769
- PLUGIN Plugin to install.
770
-
771
- FLAGS
772
- -f, --force Run yarn install with force flag.
773
- -h, --help Show CLI help.
774
- -v, --verbose
775
-
776
- DESCRIPTION
777
- Installs a plugin into the CLI.
778
- Can be installed from npm or a git url.
779
-
780
- Installation of a user-installed plugin will override a core plugin.
781
-
782
- e.g. If you have a core plugin that has a 'hello' command, installing a user-installed plugin with a 'hello' command
783
- will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in
784
- the CLI without the need to patch and update the whole CLI.
785
-
786
-
787
- ALIASES
788
- $ contrail plugins add
789
-
790
- EXAMPLES
791
- $ contrail plugins:install myplugin
792
-
793
- $ contrail plugins:install https://github.com/someuser/someplugin
794
-
795
- $ contrail plugins:install someuser/someplugin
796
- ```
797
-
798
- ## `contrail plugins:inspect PLUGIN...`
799
-
800
- Displays installation properties of a plugin.
801
-
802
- ```
803
- USAGE
804
- $ contrail plugins:inspect PLUGIN...
805
-
806
- ARGUMENTS
807
- PLUGIN [default: .] Plugin to inspect.
808
-
809
- FLAGS
810
- -h, --help Show CLI help.
811
- -v, --verbose
812
-
813
- GLOBAL FLAGS
814
- --json Format output as json.
815
-
816
- DESCRIPTION
817
- Displays installation properties of a plugin.
818
-
819
- EXAMPLES
820
- $ contrail plugins:inspect myplugin
821
- ```
822
-
823
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/inspect.ts)_
824
-
825
- ## `contrail plugins:install PLUGIN...`
826
-
827
- Installs a plugin into the CLI.
828
-
829
- ```
830
- USAGE
831
- $ contrail plugins:install PLUGIN...
832
-
833
- ARGUMENTS
834
- PLUGIN Plugin to install.
835
-
836
- FLAGS
837
- -f, --force Run yarn install with force flag.
838
- -h, --help Show CLI help.
839
- -v, --verbose
840
-
841
- DESCRIPTION
842
- Installs a plugin into the CLI.
843
- Can be installed from npm or a git url.
844
-
845
- Installation of a user-installed plugin will override a core plugin.
846
-
847
- e.g. If you have a core plugin that has a 'hello' command, installing a user-installed plugin with a 'hello' command
848
- will override the core plugin implementation. This is useful if a user needs to update core plugin functionality in
849
- the CLI without the need to patch and update the whole CLI.
850
-
851
-
852
- ALIASES
853
- $ contrail plugins add
854
-
855
- EXAMPLES
856
- $ contrail plugins:install myplugin
857
-
858
- $ contrail plugins:install https://github.com/someuser/someplugin
859
-
860
- $ contrail plugins:install someuser/someplugin
861
- ```
862
-
863
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/install.ts)_
864
-
865
- ## `contrail plugins:link PLUGIN`
866
-
867
- Links a plugin into the CLI for development.
868
-
869
- ```
870
- USAGE
871
- $ contrail plugins:link PLUGIN
872
-
873
- ARGUMENTS
874
- PATH [default: .] path to plugin
875
-
876
- FLAGS
877
- -h, --help Show CLI help.
878
- -v, --verbose
879
-
880
- DESCRIPTION
881
- Links a plugin into the CLI for development.
882
- Installation of a linked plugin will override a user-installed or core plugin.
883
-
884
- e.g. If you have a user-installed or core plugin that has a 'hello' command, installing a linked plugin with a 'hello'
885
- command will override the user-installed or core plugin implementation. This is useful for development work.
886
-
887
-
888
- EXAMPLES
889
- $ contrail plugins:link myplugin
890
- ```
891
-
892
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/link.ts)_
893
-
894
- ## `contrail plugins:uninstall PLUGIN...`
895
-
896
- Removes a plugin from the CLI.
897
-
898
- ```
899
- USAGE
900
- $ contrail plugins:uninstall PLUGIN...
901
-
902
- ARGUMENTS
903
- PLUGIN plugin to uninstall
904
-
905
- FLAGS
906
- -h, --help Show CLI help.
907
- -v, --verbose
908
-
909
- DESCRIPTION
910
- Removes a plugin from the CLI.
911
-
912
- ALIASES
913
- $ contrail plugins unlink
914
- $ contrail plugins remove
915
- ```
916
-
917
- ## `contrail plugins:uninstall PLUGIN...`
918
-
919
- Removes a plugin from the CLI.
920
-
921
- ```
922
- USAGE
923
- $ contrail plugins:uninstall PLUGIN...
924
-
925
- ARGUMENTS
926
- PLUGIN plugin to uninstall
927
-
928
- FLAGS
929
- -h, --help Show CLI help.
930
- -v, --verbose
931
-
932
- DESCRIPTION
933
- Removes a plugin from the CLI.
934
-
935
- ALIASES
936
- $ contrail plugins unlink
937
- $ contrail plugins remove
938
- ```
939
-
940
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/uninstall.ts)_
941
-
942
- ## `contrail plugins:uninstall PLUGIN...`
943
-
944
- Removes a plugin from the CLI.
945
-
946
- ```
947
- USAGE
948
- $ contrail plugins:uninstall PLUGIN...
949
-
950
- ARGUMENTS
951
- PLUGIN plugin to uninstall
952
-
953
- FLAGS
954
- -h, --help Show CLI help.
955
- -v, --verbose
956
-
957
- DESCRIPTION
958
- Removes a plugin from the CLI.
959
-
960
- ALIASES
961
- $ contrail plugins unlink
962
- $ contrail plugins remove
963
- ```
964
-
965
- ## `contrail plugins update`
966
-
967
- Update installed plugins.
968
-
969
- ```
970
- USAGE
971
- $ contrail plugins update [-h] [-v]
972
-
973
- FLAGS
974
- -h, --help Show CLI help.
975
- -v, --verbose
976
-
977
- DESCRIPTION
978
- Update installed plugins.
979
- ```
980
-
981
- _See code: [@oclif/plugin-plugins](https://github.com/oclif/plugin-plugins/blob/v2.3.2/src/commands/plugins/update.ts)_
982
-
983
779
  ## `contrail projects export PROJECTNAME`
984
780
 
985
781
  Export a project.
@@ -0,0 +1,2 @@
1
+ import { AppExtensionDeployment } from '../interfaces';
2
+ export declare function getAppExtensionDeployment(deploymentId: string): Promise<AppExtensionDeployment>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAppExtensionDeployment = void 0;
4
+ const sdk_1 = require("@contrail/sdk");
5
+ async function getAppExtensionDeployment(deploymentId) {
6
+ return await new sdk_1.Entities().get({
7
+ entityName: 'app-extension-deployment',
8
+ id: deploymentId,
9
+ });
10
+ }
11
+ exports.getAppExtensionDeployment = getAppExtensionDeployment;
@@ -0,0 +1,2 @@
1
+ import { AppExtensionPackage } from '../interfaces';
2
+ export declare function getAppExtensionPackage(packageId: string): Promise<AppExtensionPackage>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAppExtensionPackage = void 0;
4
+ const sdk_1 = require("@contrail/sdk");
5
+ async function getAppExtensionPackage(packageId) {
6
+ return await new sdk_1.Entities().get({
7
+ entityName: 'app-extension-package',
8
+ id: packageId,
9
+ });
10
+ }
11
+ exports.getAppExtensionPackage = getAppExtensionPackage;
@@ -10,7 +10,7 @@ const logger_1 = tslib_1.__importDefault(require("../../logger"));
10
10
  const app_deployer_1 = require("../../helpers/app/app-deployer");
11
11
  const load_app_config_1 = require("../../helpers/app/load-app-config");
12
12
  class CreateApp extends basecommand_1.BaseCommand {
13
- static description = 'Create an app from a template';
13
+ static description = 'Create a new app. The current organization will be set as the owner of the app';
14
14
  static examples = [
15
15
  `$ contrail app create
16
16
  `,
@@ -0,0 +1,17 @@
1
+ import { BaseCommand } from '../../../basecommand';
2
+ export default class DeployExtension extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ identifier: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ private pollUntilPackageIsReady;
12
+ private pollUntilDeploymentIsReady;
13
+ private getAppDeclaration;
14
+ private getExistingApp;
15
+ private validateExtensionDeclaration;
16
+ private getExtensionDirectory;
17
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
+ const fs = tslib_1.__importStar(require("fs"));
7
+ const path = tslib_1.__importStar(require("path"));
8
+ const app_extension_deployments_1 = require("../../../api/app-extension-deployments");
9
+ const app_extension_packages_1 = require("../../../api/app-extension-packages");
10
+ const apps_1 = require("../../../api/apps");
11
+ const login_1 = require("../../../auth/login");
12
+ const basecommand_1 = require("../../../basecommand");
13
+ const extension_package_1 = require("../../../helpers/app/extension-package");
14
+ const load_app_config_1 = require("../../../helpers/app/load-app-config");
15
+ const interfaces_1 = require("../../../interfaces");
16
+ const logger_1 = tslib_1.__importDefault(require("../../../logger"));
17
+ class DeployExtension extends basecommand_1.BaseCommand {
18
+ static description = 'Deploy an extension from the extensions directory to a VibeIQ managed URL.';
19
+ static examples = [`$ contrail extension deploy --identifier <extensionIdentifier>`];
20
+ static flags = {
21
+ ...basecommand_1.BaseCommand.baseFlags,
22
+ identifier: core_1.Flags.string({
23
+ char: 'i',
24
+ description: 'The extension identifier to deploy. The identifier of the extension is the "identifier" property in the extension defined in the app.yml',
25
+ required: true,
26
+ }),
27
+ };
28
+ async run() {
29
+ await (0, login_1.authUser)();
30
+ try {
31
+ const extensionIdentifier = this.flags.identifier;
32
+ // 1. Validate manifest and extension existence
33
+ const appDeclaration = this.getAppDeclaration();
34
+ const app = await this.getExistingApp(appDeclaration);
35
+ await this.validateExtensionDeclaration(appDeclaration, extensionIdentifier);
36
+ const extensionDir = this.getExtensionDirectory(extensionIdentifier);
37
+ // 2. Package and upload extension
38
+ const createdPackage = await (0, extension_package_1.createExtensionPackage)(app.id, extensionDir);
39
+ // 3. Poll until package is ready (timeout after 1 minute)
40
+ const readyPackage = await this.pollUntilPackageIsReady(createdPackage);
41
+ logger_1.default.info("Extension package is ready...Checking for extension deployment");
42
+ logger_1.default.debug(JSON.stringify(readyPackage, null, 2));
43
+ const deployment = await this.pollUntilDeploymentIsReady(readyPackage.deploymentId);
44
+ logger_1.default.info(`${chalk_1.default.green.bold('SUCCESS')} Extension package is ready.`);
45
+ logger_1.default.info(`${chalk_1.default.green.bold('SUCCESS')} Please note that it may take a few minutes for the extension to be available if it is the first time you are deploying it.`);
46
+ logger_1.default.info(`${chalk_1.default.green.bold('SUCCESS')} Extension deployment URL: ${deployment.cloudFrontUrl}/packages/${readyPackage.id}/index.html`);
47
+ }
48
+ catch (error) {
49
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Extension Deployment Failed. ${error}`);
50
+ }
51
+ }
52
+ async pollUntilPackageIsReady(createdPackage) {
53
+ let currentPackage = createdPackage;
54
+ const startTime = Date.now();
55
+ const timeoutMs = 120000; // 2 minutes
56
+ while (currentPackage.status !== interfaces_1.AppExtensionPackageStatus.READY) {
57
+ if (Date.now() - startTime > timeoutMs) {
58
+ throw new Error('Timed out waiting for package to be ready');
59
+ }
60
+ await new Promise((resolve) => setTimeout(resolve, 2000));
61
+ currentPackage = await (0, app_extension_packages_1.getAppExtensionPackage)(currentPackage.id);
62
+ logger_1.default.info(`Package status: ${currentPackage.status}`);
63
+ if (currentPackage.status === interfaces_1.AppExtensionPackageStatus.FAILED) {
64
+ throw new Error('Package failed to build');
65
+ }
66
+ }
67
+ return currentPackage;
68
+ }
69
+ async pollUntilDeploymentIsReady(deploymentId) {
70
+ let currentDeployment = await (0, app_extension_deployments_1.getAppExtensionDeployment)(deploymentId);
71
+ const startTime = Date.now();
72
+ const timeoutMs = 60000; // 1 minute
73
+ while (currentDeployment.status !== interfaces_1.AppExtensionDeploymentStatus.DEPLOYED) {
74
+ if (Date.now() - startTime > timeoutMs) {
75
+ throw new Error('Timed out waiting for deployment to be ready');
76
+ }
77
+ await new Promise((resolve) => setTimeout(resolve, 2000));
78
+ currentDeployment = await (0, app_extension_deployments_1.getAppExtensionDeployment)(currentDeployment.id);
79
+ logger_1.default.info(`Deployment status: ${currentDeployment.status}`);
80
+ if (currentDeployment.status === interfaces_1.AppExtensionDeploymentStatus.FAILED) {
81
+ throw new Error('Deployment failed');
82
+ }
83
+ }
84
+ return currentDeployment;
85
+ }
86
+ getAppDeclaration() {
87
+ return (0, load_app_config_1.loadAppConfig)();
88
+ }
89
+ async getExistingApp(appDeclaration) {
90
+ const apps = await (0, apps_1.getAvailableApps)();
91
+ const foundApp = apps.find((app) => app.identifier === appDeclaration.appIdentifier);
92
+ if (!foundApp) {
93
+ throw new Error(`App ${appDeclaration.appIdentifier} not found. Extensions can only be deployed for existing apps.`);
94
+ }
95
+ return foundApp;
96
+ }
97
+ async validateExtensionDeclaration(appDeclaration, extensionIdentifier) {
98
+ const extensions = appDeclaration.extensions;
99
+ if (!Array.isArray(extensions) || extensions.length === 0) {
100
+ throw new Error('No extensions defined in app.yml.');
101
+ }
102
+ const extensionDecl = extensions.find((ext) => ext.identifier === extensionIdentifier);
103
+ if (!extensionDecl) {
104
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Extension '${extensionIdentifier}' not found in app.yml.`);
105
+ return null;
106
+ }
107
+ return extensionDecl;
108
+ }
109
+ getExtensionDirectory(extensionIdentifier) {
110
+ const extensionDir = path.resolve(process.cwd(), 'extensions', extensionIdentifier);
111
+ if (!fs.existsSync(extensionDir)) {
112
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Extension directory '${extensionDir}' does not exist.`);
113
+ return null;
114
+ }
115
+ return extensionDir;
116
+ }
117
+ }
118
+ exports.default = DeployExtension;
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../../../basecommand';
2
+ import { AppExtensionPackage } from '../../../../interfaces';
3
+ export default class ListExtensionDeployments extends BaseCommand {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
9
+ logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ getLatest20ExtensionPackages(appId: string): Promise<AppExtensionPackage[]>;
13
+ getAllExtensionPackages(appId: string): Promise<AppExtensionPackage[]>;
14
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const sdk_1 = require("@contrail/sdk");
5
+ const core_1 = require("@oclif/core");
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const login_1 = require("../../../../auth/login");
8
+ const basecommand_1 = require("../../../../basecommand");
9
+ const extension_package_1 = require("../../../../helpers/app/extension-package");
10
+ const load_app_config_1 = require("../../../../helpers/app/load-app-config");
11
+ const logger_1 = tslib_1.__importDefault(require("../../../../logger"));
12
+ const lodash_1 = require("lodash");
13
+ class ListExtensionDeployments extends basecommand_1.BaseCommand {
14
+ static description = 'List extension deployments';
15
+ static examples = [`$ contrail extension deployment list`];
16
+ static flags = {
17
+ ...basecommand_1.BaseCommand.baseFlags,
18
+ all: core_1.Flags.boolean({
19
+ char: 'a',
20
+ description: 'List all extension deployments. By default, only the latest 20 are shown',
21
+ required: false,
22
+ default: false,
23
+ }),
24
+ };
25
+ async run() {
26
+ await (0, login_1.authUser)();
27
+ logger_1.default.info(`%s Listing extension deployments`, chalk_1.default.blue.bold('START'));
28
+ const appDeclaration = (0, load_app_config_1.loadAppConfig)();
29
+ const app = await (0, extension_package_1.getExistingApp)(appDeclaration);
30
+ const packages = this.flags.all
31
+ ? await this.getAllExtensionPackages(app.id)
32
+ : await this.getLatest20ExtensionPackages(app.id);
33
+ logger_1.default.debug('packages:', packages);
34
+ const deploymentIds = Array.from(new Set(packages.map((p) => p.deploymentId))).filter((id) => !!id);
35
+ logger_1.default.debug('deploymentIds:', deploymentIds);
36
+ const deployments = await Promise.all(deploymentIds.map((id) => new sdk_1.Entities().get({ entityName: 'app-extension-deployment', id })));
37
+ const deploymentsById = (0, lodash_1.keyBy)(deployments, 'id');
38
+ const uniqueDeploymentUrls = new Set(deployments.map((d) => d.cloudFrontUrl).filter((url) => !!url));
39
+ if (uniqueDeploymentUrls.size > 1) {
40
+ logger_1.default.info(`${chalk_1.default.red.yellow('WARNING')} Multiple extension deployment URLS found for app ${appDeclaration.appIdentifier}`);
41
+ return;
42
+ }
43
+ else if (uniqueDeploymentUrls.size === 0) {
44
+ logger_1.default.info(`${chalk_1.default.red.yellow('WARNING')} No extension deployment URL found for app ${appDeclaration.appIdentifier}`);
45
+ return;
46
+ }
47
+ const tableData = packages.map((extensionPackage) => ({
48
+ 'Created At': extensionPackage.createdOn,
49
+ 'Package ID': extensionPackage.id,
50
+ Status: deploymentsById[extensionPackage.deploymentId]?.status || '-',
51
+ URL: deploymentsById[extensionPackage.deploymentId]
52
+ ? `${deploymentsById[extensionPackage.deploymentId]?.cloudFrontUrl}/packages/${extensionPackage.id}/index.html`
53
+ : '-',
54
+ }));
55
+ console.table(tableData);
56
+ }
57
+ async getLatest20ExtensionPackages(appId) {
58
+ return await new sdk_1.Entities().get({
59
+ entityName: 'app-extension-package',
60
+ criteria: { appId },
61
+ order: [{ orderField: 'createdOn', order: sdk_1.SortOrderOptions.DESC }],
62
+ take: 20,
63
+ });
64
+ }
65
+ async getAllExtensionPackages(appId) {
66
+ const packages = [];
67
+ let nextPageKey = null;
68
+ do {
69
+ const response = await new sdk_1.Entities().get({
70
+ entityName: 'app-extension-package',
71
+ criteria: { appId },
72
+ order: [{ orderField: 'createdOn', order: sdk_1.SortOrderOptions.DESC }],
73
+ nextPageKey,
74
+ apiVersion: sdk_1.API_VERSION.V2,
75
+ });
76
+ packages.push(...response.results);
77
+ nextPageKey = response.nextPageKey;
78
+ } while (nextPageKey);
79
+ return packages;
80
+ }
81
+ }
82
+ exports.default = ListExtensionDeployments;
@@ -8,7 +8,7 @@ const login_1 = require("../../auth/login");
8
8
  const basecommand_1 = require("../../basecommand");
9
9
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
10
10
  class GetAPIKeyApp extends basecommand_1.BaseCommand {
11
- static description = 'Get an api key for an app';
11
+ static description = 'Get an api key for an installed app';
12
12
  static examples = [
13
13
  `$ contrail app getApiKey
14
14
  `,
@@ -12,7 +12,7 @@ const basecommand_1 = require("../../basecommand");
12
12
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
13
13
  const common_1 = require("../../common");
14
14
  class InstallApp extends basecommand_1.BaseCommand {
15
- static description = 'Install an app from the marketplace';
15
+ static description = 'Install an app from the marketplace to a specific organization';
16
16
  static examples = [
17
17
  `$ contrail app install --appIdentifier @VibeIQ/Flex-PLM-Connector
18
18
  `,
@@ -11,7 +11,7 @@ const upgrade_1 = require("./upgrade");
11
11
  const basecommand_1 = require("../../basecommand");
12
12
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
13
13
  class PublishApp extends basecommand_1.BaseCommand {
14
- static description = 'Publish the app';
14
+ static description = 'Publish the app to the marketplace. This visibility of your app depends on the app.yml configuration ("visibility" property)';
15
15
  static examples = [
16
16
  `$ contrail app publish
17
17
  `,
@@ -10,7 +10,7 @@ const apps_1 = require("../../api/apps");
10
10
  const basecommand_1 = require("../../basecommand");
11
11
  const common_1 = require("../../common");
12
12
  class UninstallApp extends basecommand_1.BaseCommand {
13
- static description = 'Uninstall an app that is currently installed';
13
+ static description = 'Uninstall an app that is currently installed in a specific organization';
14
14
  static examples = [
15
15
  `$ contrail app uninstall --name @vibeiq/flexplm-connector
16
16
  `,
@@ -12,7 +12,7 @@ const basecommand_1 = require("../../basecommand");
12
12
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
13
13
  const common_1 = require("../../common");
14
14
  class UpgradeApp extends basecommand_1.BaseCommand {
15
- static description = 'Upgrade an installed app';
15
+ static description = 'Upgrade an installed app in a specific organization';
16
16
  static examples = [
17
17
  `$ contrail app upgrade --appIdentifier @VibeIQ/Flex-PLM-Connector --latest
18
18
  `,
@@ -7,7 +7,7 @@ const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
7
7
  const core_1 = require("@oclif/core");
8
8
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
9
9
  class DescribeConfig extends basecommand_1.BaseCommand {
10
- static description = 'Describe a configuration file';
10
+ static description = 'Display the contents of a configuration file';
11
11
  skipConfirmEnv = true;
12
12
  static examples = ['$ contrail config describe demo-org'];
13
13
  static args = {
@@ -0,0 +1,5 @@
1
+ import { App } from '@contrail/entity-types';
2
+ import { AppDeclaration, AppExtensionPackage } from '../../interfaces';
3
+ export declare function createExtensionPackage(appId: string, extensionDir: string): Promise<any>;
4
+ export declare function getExistingApp(appDeclaration: AppDeclaration): Promise<App>;
5
+ export declare function getExtensionPackage(packageId: string): Promise<AppExtensionPackage>;
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getExtensionPackage = exports.getExistingApp = exports.createExtensionPackage = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const sdk_1 = require("@contrail/sdk");
6
+ const axios_1 = tslib_1.__importDefault(require("axios"));
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
+ const path_1 = tslib_1.__importDefault(require("path"));
10
+ const zip_a_folder_1 = require("zip-a-folder");
11
+ const apps_1 = require("../../api/apps");
12
+ const logger_1 = tslib_1.__importDefault(require("../../logger"));
13
+ function createTmpDir(extensionDir) {
14
+ const tmpDir = path_1.default.join(extensionDir, 'tmp');
15
+ fs_1.default.mkdirSync(tmpDir, { recursive: true });
16
+ return tmpDir;
17
+ }
18
+ function cleanAndPrepareTmpDir(extensionDir, tmpDir) {
19
+ try {
20
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
21
+ fs_1.default.mkdirSync(tmpDir, { recursive: true });
22
+ fs_1.default.cpSync(path_1.default.join(extensionDir, 'package.json'), path_1.default.join(tmpDir, 'package.json'));
23
+ if (fs_1.default.existsSync(path_1.default.join(extensionDir, 'package-lock.json'))) {
24
+ fs_1.default.cpSync(path_1.default.join(extensionDir, 'package-lock.json'), path_1.default.join(tmpDir, 'package-lock.json'));
25
+ }
26
+ }
27
+ catch (e) {
28
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Failed during tmp dir preparation: ${e}`);
29
+ throw e;
30
+ }
31
+ }
32
+ function cleanUp(tmpDir) {
33
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
34
+ }
35
+ function installDependencies(tmpDir) {
36
+ try {
37
+ logger_1.default.info('Installing production dependencies started...');
38
+ const child_process = require('child_process');
39
+ child_process.execSync('npm install --omit=dev --prefix ./', {
40
+ cwd: tmpDir,
41
+ stdio: 'inherit',
42
+ });
43
+ logger_1.default.info('Installing production dependencies done.');
44
+ }
45
+ catch (e) {
46
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Failed during dependency install: ${e}`);
47
+ throw e;
48
+ }
49
+ }
50
+ function buildExtension(packageId, extensionDir, tmpDir) {
51
+ try {
52
+ logger_1.default.info('Building package...');
53
+ const child_process = require('child_process');
54
+ console.log('Building package... in ', tmpDir);
55
+ child_process.execSync(`npx ng build --output-path ${tmpDir}/dist --deploy-url /packages/${packageId}/`, {
56
+ cwd: extensionDir,
57
+ stdio: 'inherit',
58
+ });
59
+ logger_1.default.info('Building package done.');
60
+ }
61
+ catch (e) {
62
+ logger_1.default.error(`${chalk_1.default.red.bold('EXTENSION')} Failed to build package.`);
63
+ const stdOut = e.stdout?.toString() || '';
64
+ const stdErr = e.stderr?.toString() || '';
65
+ logger_1.default.error('Build Error(stdout):', stdOut);
66
+ logger_1.default.error('Build Error(stderr):', stdErr);
67
+ throw e;
68
+ }
69
+ }
70
+ function copyAssets(extensionDir, tmpDir) {
71
+ try {
72
+ logger_1.default.info('Copying Assets...');
73
+ const child_process = require('child_process');
74
+ child_process.execSync(`npx copyfiles assets/**/* ${tmpDir}/dist/`, {
75
+ cwd: extensionDir,
76
+ stdio: 'inherit',
77
+ });
78
+ logger_1.default.info('Copying Assets done.');
79
+ }
80
+ catch (e) {
81
+ logger_1.default.info('No assets to copy or failed to copy assets.');
82
+ }
83
+ }
84
+ async function zipDist(tmpDir) {
85
+ const tmpDistPath = path_1.default.join(tmpDir, 'dist');
86
+ const tmpZipPath = path_1.default.join(tmpDir, 'dist.zip');
87
+ try {
88
+ if (fs_1.default.existsSync(tmpZipPath)) {
89
+ fs_1.default.rmSync(tmpZipPath);
90
+ }
91
+ await (0, zip_a_folder_1.zip)(tmpDistPath, tmpZipPath);
92
+ logger_1.default.info(`${chalk_1.default.blue.bold('EXTENSION')} Zipped extension package at ${tmpZipPath}`);
93
+ }
94
+ catch (err) {
95
+ logger_1.default.error(`${chalk_1.default.red.bold('EXTENSION')} Failed to zip extension package: ${err}`);
96
+ throw err;
97
+ }
98
+ }
99
+ async function uploadExtensionPackage(appExtensionPackage, tmpDir) {
100
+ const tmpZipPath = path_1.default.join(tmpDir, 'dist.zip');
101
+ const readStream = fs_1.default.readFileSync(tmpZipPath);
102
+ const postBody = Buffer.from(readStream);
103
+ console.log('extension package ', JSON.stringify(appExtensionPackage, null, 2));
104
+ await axios_1.default.request({
105
+ method: 'PUT',
106
+ url: appExtensionPackage.uploadURL,
107
+ data: postBody,
108
+ headers: {
109
+ 'content-type': '',
110
+ },
111
+ });
112
+ logger_1.default.debug(`${chalk_1.default.green.bold('EXTENSION')} Uploaded extension package to ${appExtensionPackage.uploadURL}`);
113
+ logger_1.default.info(`${chalk_1.default.green.bold('EXTENSION')} Extension package uploaded. ID: ${appExtensionPackage.id}`);
114
+ return appExtensionPackage;
115
+ }
116
+ async function createExtensionPackage(appId, extensionDir) {
117
+ const tmpDir = createTmpDir(extensionDir);
118
+ logger_1.default.info(`%s Creating extension package at ${tmpDir}`, chalk_1.default.blue.bold('START'));
119
+ cleanAndPrepareTmpDir(extensionDir, tmpDir);
120
+ installDependenciesInExtensionDirectory(extensionDir);
121
+ installDependenciesInTmpDir(tmpDir);
122
+ const appExtensionPackage = await new sdk_1.Entities().create({
123
+ entityName: 'app-extension-package',
124
+ object: { appId },
125
+ });
126
+ buildExtension(appExtensionPackage.id, extensionDir, tmpDir);
127
+ copyAssets(extensionDir, tmpDir);
128
+ await zipDist(tmpDir);
129
+ await uploadExtensionPackage(appExtensionPackage, tmpDir);
130
+ logger_1.default.info(`${chalk_1.default.green.bold('COMPLETE')} Extension packaged and uploaded.`);
131
+ cleanUp(tmpDir);
132
+ return appExtensionPackage;
133
+ }
134
+ exports.createExtensionPackage = createExtensionPackage;
135
+ function installDependenciesInExtensionDirectory(extensionDir) {
136
+ try {
137
+ logger_1.default.info('Installing development dependencies in extension directory started...');
138
+ const child_process = require('child_process');
139
+ child_process.execSync('npm install --prefix ./', {
140
+ cwd: extensionDir,
141
+ stdio: 'inherit',
142
+ });
143
+ logger_1.default.info('Installing development dependencies in extension directory done.');
144
+ }
145
+ catch (e) {
146
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Failed during dependency install: ${e}`);
147
+ throw e;
148
+ }
149
+ }
150
+ function installDependenciesInTmpDir(tmpDir) {
151
+ try {
152
+ logger_1.default.info('Installing production dependencies in tmp dir started...');
153
+ const child_process = require('child_process');
154
+ child_process.execSync('npm install --omit=dev --prefix ./', {
155
+ cwd: tmpDir,
156
+ stdio: 'inherit',
157
+ });
158
+ logger_1.default.info('Installing production dependencies in tmp dir done.');
159
+ }
160
+ catch (e) {
161
+ logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Failed during dependency install: ${e}`);
162
+ throw e;
163
+ }
164
+ }
165
+ async function getExistingApp(appDeclaration) {
166
+ const apps = await (0, apps_1.getAvailableApps)();
167
+ const foundApp = apps.find((app) => app.identifier === appDeclaration.appIdentifier);
168
+ if (!foundApp) {
169
+ throw new Error(`App ${appDeclaration.appIdentifier} not found. Extensions deployments can only be deployed for existing apps.`);
170
+ }
171
+ return foundApp;
172
+ }
173
+ exports.getExistingApp = getExistingApp;
174
+ async function getExtensionPackage(packageId) {
175
+ return await new sdk_1.Entities().get({
176
+ entityName: 'app-extension-package',
177
+ criteria: { id: packageId },
178
+ });
179
+ }
180
+ exports.getExtensionPackage = getExtensionPackage;
@@ -402,3 +402,48 @@ export interface CronDeclaration {
402
402
  name: string;
403
403
  cron: string;
404
404
  }
405
+ export declare enum AppExtensionDeploymentStatus {
406
+ PENDING = "PENDING",
407
+ PROCESSING = "PROCESSING",
408
+ FAILED = "FAILED",
409
+ DEPLOYED = "DEPLOYED"
410
+ }
411
+ export declare enum AppExtensionPackageStatus {
412
+ PENDING = "PENDING",
413
+ PROCESSING = "PROCESSING",
414
+ FAILED = "FAILED",
415
+ READY = "READY"
416
+ }
417
+ export interface AppExtensionPackage {
418
+ id: string;
419
+ createdOn?: Date;
420
+ updatedOn?: Date;
421
+ createdById?: string;
422
+ updatedById?: string;
423
+ createdBy?: any;
424
+ updatedBy?: any;
425
+ orgId?: string;
426
+ name: string;
427
+ appId?: string;
428
+ app?: App;
429
+ deploymentId?: string;
430
+ deployment?: AppExtensionDeployment;
431
+ status: AppExtensionPackageStatus;
432
+ uploadURL?: string;
433
+ }
434
+ export interface AppExtensionDeployment {
435
+ id: string;
436
+ createdOn?: Date;
437
+ updatedOn?: Date;
438
+ createdById?: string;
439
+ updatedById?: string;
440
+ createdBy?: any;
441
+ updatedBy?: any;
442
+ orgId?: string;
443
+ appId?: string;
444
+ app?: App;
445
+ name: string;
446
+ cloudFrontUrl?: string;
447
+ distributionId?: string;
448
+ status: AppExtensionDeploymentStatus;
449
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AssortmentConfigurationRelationships = exports.AssortmentConfigurationSlim = exports.FolderSlim = exports.ProjectConfigurationTemplate = exports.ProjectConfiguration = exports.Folder = exports.AssortmentConfiguration = exports.AssortmentType = exports.CommonConfiguration = exports.TriggerKeyDefinition = exports.ConfigProperty = exports.AppApiKey = exports.AppVersion = exports.AppRuntime = exports.AppVersionStatus = exports.AppOrgStatus = exports.AppAccessPermission = exports.AppAccessGrantScope = void 0;
3
+ exports.AppExtensionPackageStatus = exports.AppExtensionDeploymentStatus = exports.AssortmentConfigurationRelationships = exports.AssortmentConfigurationSlim = exports.FolderSlim = exports.ProjectConfigurationTemplate = exports.ProjectConfiguration = exports.Folder = exports.AssortmentConfiguration = exports.AssortmentType = exports.CommonConfiguration = exports.TriggerKeyDefinition = exports.ConfigProperty = exports.AppApiKey = exports.AppVersion = exports.AppRuntime = exports.AppVersionStatus = exports.AppOrgStatus = exports.AppAccessPermission = exports.AppAccessGrantScope = void 0;
4
4
  var AppAccessGrantScope;
5
5
  (function (AppAccessGrantScope) {
6
6
  AppAccessGrantScope["install"] = "INSTALL";
@@ -154,3 +154,17 @@ class AssortmentConfigurationRelationships {
154
154
  assortmentAtts;
155
155
  }
156
156
  exports.AssortmentConfigurationRelationships = AssortmentConfigurationRelationships;
157
+ var AppExtensionDeploymentStatus;
158
+ (function (AppExtensionDeploymentStatus) {
159
+ AppExtensionDeploymentStatus["PENDING"] = "PENDING";
160
+ AppExtensionDeploymentStatus["PROCESSING"] = "PROCESSING";
161
+ AppExtensionDeploymentStatus["FAILED"] = "FAILED";
162
+ AppExtensionDeploymentStatus["DEPLOYED"] = "DEPLOYED";
163
+ })(AppExtensionDeploymentStatus = exports.AppExtensionDeploymentStatus || (exports.AppExtensionDeploymentStatus = {}));
164
+ var AppExtensionPackageStatus;
165
+ (function (AppExtensionPackageStatus) {
166
+ AppExtensionPackageStatus["PENDING"] = "PENDING";
167
+ AppExtensionPackageStatus["PROCESSING"] = "PROCESSING";
168
+ AppExtensionPackageStatus["FAILED"] = "FAILED";
169
+ AppExtensionPackageStatus["READY"] = "READY";
170
+ })(AppExtensionPackageStatus = exports.AppExtensionPackageStatus || (exports.AppExtensionPackageStatus = {}));
@@ -1,9 +1,9 @@
1
1
  {
2
- "version": "3.0.6",
2
+ "version": "3.1.1",
3
3
  "commands": {
4
4
  "app:create": {
5
5
  "id": "app:create",
6
- "description": "Create an app from a template",
6
+ "description": "Create a new app. The current organization will be set as the owner of the app",
7
7
  "strict": true,
8
8
  "pluginName": "@contrail/cli",
9
9
  "pluginAlias": "@contrail/cli",
@@ -87,7 +87,7 @@
87
87
  },
88
88
  "app:getApiKey": {
89
89
  "id": "app:getApiKey",
90
- "description": "Get an api key for an app",
90
+ "description": "Get an api key for an installed app",
91
91
  "strict": true,
92
92
  "pluginName": "@contrail/cli",
93
93
  "pluginAlias": "@contrail/cli",
@@ -179,7 +179,7 @@
179
179
  },
180
180
  "app:install": {
181
181
  "id": "app:install",
182
- "description": "Install an app from the marketplace",
182
+ "description": "Install an app from the marketplace to a specific organization",
183
183
  "strict": true,
184
184
  "pluginName": "@contrail/cli",
185
185
  "pluginAlias": "@contrail/cli",
@@ -237,7 +237,7 @@
237
237
  },
238
238
  "app:publish": {
239
239
  "id": "app:publish",
240
- "description": "Publish the app",
240
+ "description": "Publish the app to the marketplace. This visibility of your app depends on the app.yml configuration (\"visibility\" property)",
241
241
  "strict": true,
242
242
  "pluginName": "@contrail/cli",
243
243
  "pluginAlias": "@contrail/cli",
@@ -303,7 +303,7 @@
303
303
  },
304
304
  "app:uninstall": {
305
305
  "id": "app:uninstall",
306
- "description": "Uninstall an app that is currently installed",
306
+ "description": "Uninstall an app that is currently installed in a specific organization",
307
307
  "strict": true,
308
308
  "pluginName": "@contrail/cli",
309
309
  "pluginAlias": "@contrail/cli",
@@ -353,7 +353,7 @@
353
353
  },
354
354
  "app:upgrade": {
355
355
  "id": "app:upgrade",
356
- "description": "Upgrade an installed app",
356
+ "description": "Upgrade an installed app in a specific organization",
357
357
  "strict": true,
358
358
  "pluginName": "@contrail/cli",
359
359
  "pluginAlias": "@contrail/cli",
@@ -460,7 +460,7 @@
460
460
  },
461
461
  "config:describe": {
462
462
  "id": "config:describe",
463
- "description": "Describe a configuration file",
463
+ "description": "Display the contents of a configuration file",
464
464
  "strict": true,
465
465
  "pluginName": "@contrail/cli",
466
466
  "pluginAlias": "@contrail/cli",
@@ -3010,6 +3010,56 @@
3010
3010
  }
3011
3011
  }
3012
3012
  },
3013
+ "app:extension:deploy": {
3014
+ "id": "app:extension:deploy",
3015
+ "description": "Deploy an extension from the extensions directory to a VibeIQ managed URL.",
3016
+ "strict": true,
3017
+ "pluginName": "@contrail/cli",
3018
+ "pluginAlias": "@contrail/cli",
3019
+ "pluginType": "core",
3020
+ "aliases": [],
3021
+ "examples": [
3022
+ "$ contrail extension deploy --identifier <extensionIdentifier>"
3023
+ ],
3024
+ "flags": {
3025
+ "logLevel": {
3026
+ "name": "logLevel",
3027
+ "type": "option",
3028
+ "char": "l",
3029
+ "description": "The Log Level",
3030
+ "required": false,
3031
+ "multiple": false,
3032
+ "options": [
3033
+ "error",
3034
+ "warn",
3035
+ "info",
3036
+ "debug"
3037
+ ]
3038
+ },
3039
+ "alwaysConfirmEnv": {
3040
+ "name": "alwaysConfirmEnv",
3041
+ "type": "option",
3042
+ "char": "e",
3043
+ "description": "The Environment variables",
3044
+ "required": false,
3045
+ "multiple": false,
3046
+ "options": [
3047
+ "true",
3048
+ "false"
3049
+ ],
3050
+ "default": "true"
3051
+ },
3052
+ "identifier": {
3053
+ "name": "identifier",
3054
+ "type": "option",
3055
+ "char": "i",
3056
+ "description": "The extension identifier to deploy. The identifier of the extension is the \"identifier\" property in the extension defined in the app.yml",
3057
+ "required": true,
3058
+ "multiple": false
3059
+ }
3060
+ },
3061
+ "args": {}
3062
+ },
3013
3063
  "app:version:major": {
3014
3064
  "id": "app:version:major",
3015
3065
  "description": "Upgrade the Major app version",
@@ -3135,6 +3185,56 @@
3135
3185
  }
3136
3186
  },
3137
3187
  "args": {}
3188
+ },
3189
+ "app:extension:deployment:list": {
3190
+ "id": "app:extension:deployment:list",
3191
+ "description": "List extension deployments",
3192
+ "strict": true,
3193
+ "pluginName": "@contrail/cli",
3194
+ "pluginAlias": "@contrail/cli",
3195
+ "pluginType": "core",
3196
+ "aliases": [],
3197
+ "examples": [
3198
+ "$ contrail extension deployment list"
3199
+ ],
3200
+ "flags": {
3201
+ "logLevel": {
3202
+ "name": "logLevel",
3203
+ "type": "option",
3204
+ "char": "l",
3205
+ "description": "The Log Level",
3206
+ "required": false,
3207
+ "multiple": false,
3208
+ "options": [
3209
+ "error",
3210
+ "warn",
3211
+ "info",
3212
+ "debug"
3213
+ ]
3214
+ },
3215
+ "alwaysConfirmEnv": {
3216
+ "name": "alwaysConfirmEnv",
3217
+ "type": "option",
3218
+ "char": "e",
3219
+ "description": "The Environment variables",
3220
+ "required": false,
3221
+ "multiple": false,
3222
+ "options": [
3223
+ "true",
3224
+ "false"
3225
+ ],
3226
+ "default": "true"
3227
+ },
3228
+ "all": {
3229
+ "name": "all",
3230
+ "type": "boolean",
3231
+ "char": "a",
3232
+ "description": "List all extension deployments. By default, only the latest 20 are shown",
3233
+ "required": false,
3234
+ "allowNo": false
3235
+ }
3236
+ },
3237
+ "args": {}
3138
3238
  }
3139
3239
  }
3140
3240
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/cli",
3
- "version": "3.0.6",
3
+ "version": "3.1.1",
4
4
  "description": "VibeIQ's Contrail Platform CLI.",
5
5
  "bin": {
6
6
  "contrail-cli": "./bin/run",
@@ -26,11 +26,10 @@
26
26
  "@contrail/org-config-migration": "^1.1.4",
27
27
  "@contrail/sdk": "^1.4.6",
28
28
  "@contrail/types": "^3.0.48",
29
- "@contrail/util": "^1.0.41",
29
+ "@contrail/util": "^1.1.10",
30
30
  "@oclif/core": "^2",
31
31
  "@oclif/plugin-autocomplete": "^2.1.4",
32
32
  "@oclif/plugin-help": "^5",
33
- "@oclif/plugin-plugins": "^2.3.2",
34
33
  "@typescript-eslint/eslint-plugin": "^5.54.1",
35
34
  "amazon-cognito-identity-js": "^5.2.3",
36
35
  "arg": "^4.0.1",
@@ -78,22 +77,18 @@
78
77
  "commands": "./dist/commands",
79
78
  "plugins": [
80
79
  "@oclif/plugin-help",
81
- "@oclif/plugin-plugins",
82
80
  "@oclif/plugin-autocomplete"
83
81
  ],
84
82
  "topicSeparator": " ",
85
83
  "topics": {
86
84
  "app": {
87
- "description": "Create, deploy, and manage apps"
88
- },
89
- "colors": {
90
- "description": "Load and delete colors"
85
+ "description": "Create, deploy, and manage apps and extensions"
91
86
  },
92
87
  "config": {
93
88
  "description": "Manage the configuration of contrail cli"
94
89
  },
95
- "loader-process": {
96
- "description": "Loader Commands"
90
+ "load": {
91
+ "description": "Load data to VibeIQ from local CSV files"
97
92
  },
98
93
  "types": {
99
94
  "description": "Export, manage, and import types"
@@ -101,6 +96,12 @@
101
96
  "users": {
102
97
  "description": "Export and import users"
103
98
  },
99
+ "groups": {
100
+ "description": "Export and import user groups"
101
+ },
102
+ "webhooks": {
103
+ "description": "Manage VibeIQ webhooks"
104
+ },
104
105
  "workflow-template-definitions": {
105
106
  "description": "Manage workflow template definitions"
106
107
  },