@swell/cli 1.0.2 → 2.0.1-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +2 -140
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +7 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +7 -0
  7. package/dist/app-command.d.ts +22 -0
  8. package/dist/app-command.js +45 -0
  9. package/dist/commands/app/_pull.d.ts +8 -0
  10. package/dist/commands/app/_pull.js +45 -0
  11. package/dist/commands/app/_uninstall.d.ts +12 -0
  12. package/dist/commands/app/_uninstall.js +45 -0
  13. package/dist/commands/app/info.d.ts +15 -0
  14. package/dist/commands/app/info.js +92 -0
  15. package/dist/commands/app/install.d.ts +17 -0
  16. package/dist/commands/app/install.js +179 -0
  17. package/dist/commands/app/push.d.ts +20 -0
  18. package/dist/commands/app/push.js +170 -0
  19. package/dist/commands/app/version.d.ts +18 -0
  20. package/dist/commands/app/version.js +156 -0
  21. package/dist/commands/app/watch.d.ts +15 -0
  22. package/dist/commands/app/watch.js +110 -0
  23. package/dist/commands/create/app.d.ts +21 -0
  24. package/dist/commands/create/app.js +210 -0
  25. package/dist/commands/create/content.d.ts +19 -0
  26. package/dist/commands/create/content.js +87 -0
  27. package/dist/commands/create/function.d.ts +25 -0
  28. package/dist/commands/create/function.js +191 -0
  29. package/dist/commands/create/index.d.ts +6 -0
  30. package/dist/commands/create/index.js +34 -0
  31. package/dist/commands/create/model.d.ts +19 -0
  32. package/dist/commands/create/model.js +87 -0
  33. package/dist/commands/create/notification.d.ts +25 -0
  34. package/dist/commands/create/notification.js +170 -0
  35. package/dist/commands/login.d.ts +22 -0
  36. package/dist/commands/login.js +77 -0
  37. package/dist/commands/logout.d.ts +8 -0
  38. package/dist/commands/logout.js +45 -0
  39. package/dist/commands/logs.d.ts +24 -0
  40. package/dist/commands/logs.js +212 -0
  41. package/dist/commands/switch.d.ts +10 -0
  42. package/dist/commands/switch.js +41 -0
  43. package/dist/commands/whoami.d.ts +7 -0
  44. package/dist/commands/whoami.js +24 -0
  45. package/dist/create-collection-command.d.ts +26 -0
  46. package/dist/create-collection-command.js +97 -0
  47. package/dist/create-command.d.ts +16 -0
  48. package/dist/create-command.js +59 -0
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.js +1 -0
  51. package/dist/lib/api.d.ts +13 -0
  52. package/dist/lib/api.js +126 -0
  53. package/dist/lib/app-config.d.ts +29 -0
  54. package/dist/lib/app-config.js +127 -0
  55. package/dist/lib/apps/app-config.d.ts +42 -0
  56. package/dist/lib/apps/app-config.js +170 -0
  57. package/dist/lib/apps/index.d.ts +67 -0
  58. package/dist/lib/apps/index.js +167 -0
  59. package/dist/lib/apps/paths.d.ts +18 -0
  60. package/dist/lib/apps/paths.js +54 -0
  61. package/dist/lib/bundle.d.ts +1 -0
  62. package/dist/lib/bundle.js +43 -0
  63. package/dist/lib/config.d.ts +37 -0
  64. package/dist/lib/config.js +131 -0
  65. package/dist/lib/constants.d.ts +5 -0
  66. package/dist/lib/constants.js +17 -0
  67. package/dist/lib/create/content.d.ts +23 -0
  68. package/dist/lib/create/content.js +40 -0
  69. package/dist/lib/create/function.d.ts +17 -0
  70. package/dist/lib/create/function.js +36 -0
  71. package/dist/lib/create/index.d.ts +13 -0
  72. package/dist/lib/create/index.js +22 -0
  73. package/dist/lib/create/model.d.ts +22 -0
  74. package/dist/lib/create/model.js +30 -0
  75. package/dist/lib/create/notification.d.ts +25 -0
  76. package/dist/lib/create/notification.js +1 -0
  77. package/dist/lib/info.d.ts +38 -0
  78. package/dist/lib/info.js +91 -0
  79. package/dist/lib/logs/index.d.ts +23 -0
  80. package/dist/lib/logs/index.js +88 -0
  81. package/dist/lib/logs/line-output.d.ts +5 -0
  82. package/dist/lib/logs/line-output.js +13 -0
  83. package/dist/lib/logs/output.d.ts +7 -0
  84. package/dist/lib/logs/output.js +8 -0
  85. package/dist/lib/logs/table-output.d.ts +11 -0
  86. package/dist/lib/logs/table-output.js +128 -0
  87. package/dist/lib/sessions.d.ts +9 -0
  88. package/dist/lib/sessions.js +110 -0
  89. package/dist/lib/stores.d.ts +63 -0
  90. package/dist/lib/stores.js +173 -0
  91. package/dist/lib/style.d.ts +24 -0
  92. package/dist/lib/style.js +29 -0
  93. package/dist/lib/swell-function-wrapper.d.ts +88 -0
  94. package/dist/lib/swell-function-wrapper.js +302 -0
  95. package/dist/remote-app-command.d.ts +36 -0
  96. package/dist/remote-app-command.js +388 -0
  97. package/dist/swell-command.d.ts +21 -0
  98. package/dist/swell-command.js +43 -0
  99. package/oclif.manifest.json +1090 -0
  100. package/package.json +81 -43
  101. package/LICENSE +0 -674
  102. package/dist/bin/multipart-parser-85ef9626.js +0 -456
  103. package/dist/bin/swell-0f71f07d.js +0 -30670
  104. package/dist/bin/swell.js +0 -24
  105. package/dist/man/swell.1 +0 -85
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Swell Commerce Corp.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,141 +1,3 @@
1
- # @swell/cli
1
+ # @swell/cli 2 alpha
2
2
 
3
- #We're in beta: commands and arguments can still change.#
4
-
5
- Install with:
6
-
7
- ```sh
8
- npm install -g @swell/cli
9
- ```
10
-
11
- If you are using tools for version managing like [asdf](https://asdf-vm.com/), make sure you [reshim](https://asdf-vm.com/manage/core.html#reshim) after install:
12
-
13
- ```sh
14
- asdf reshim
15
- ```
16
-
17
- # Commands
18
-
19
- ## General options
20
-
21
- Commands tend to support the following helper options:
22
-
23
- - --quiet (-q): Boolean, quiets the progress indicator and output of intermediary commands
24
- - --verbose (-v): Boolean, outputs all commands
25
- - --dry-run: Boolean, dry runs requests that delete data, but doesn't run them
26
- - --yes (-y): Boolean, answers all confirmation questions with **yes**.
27
-
28
- ## Login
29
-
30
- The `admin login` command authenticates and stores a user's session locally. Saved sessions can/will be used by other commands, unless a secret key is specified.
31
-
32
- ```sh
33
- swell login [--username (-u) String] [--password (-p) String] [--set-default Boolean]
34
- ```
35
-
36
- ### Examples
37
-
38
- ```sh
39
- swell login
40
- swell login --set-default
41
- ```
42
-
43
- ## Storefronts
44
-
45
- List all storefronts associated to logged in user:
46
-
47
- ```sh
48
- swell storefronts list
49
- ```
50
-
51
- Retrieves storefront configuration data from the server and writes it to a file if specified or stdout by default. It requires a type to run. Configuration types allowed are "editor", "menus" and "settings":
52
- ```sh
53
- swell storefronts pull --id String --type (-t) String [--file (-f) String]
54
- ```
55
-
56
- Send storefront configuration data to the server. Configuration types allowed are "editor", "menus" and "settings":
57
- ```sh
58
- swell storefronts push --id String --type (-t) String [--file (-f) String] [--strategy (-i) String]
59
- ```
60
-
61
- ### Examples
62
-
63
- ```sh
64
- swell storefronts pull --id P5OzfzLD -t editor
65
- swell storefronts pull --id P5OzfzLD -t menus -f menus.json
66
- swell storefronts push --id P5OzfzLD -t editor -s set -f ../origin-storefront/config/editor.json
67
- ```
68
-
69
- ### Without logging in
70
-
71
- ```sh
72
- swell storefronts pull --id P5OzfzLD -t editor --store my-test-store --secret-key my-dev-secret-key
73
- swell storefronts pull --id P5OzfzLD -t menus -f menus.json --store my-test-store --secret-key my-dev-secret-key
74
- swell storefronts push --id P5OzfzLD -t editor -s set -f ../origin-storefront/config/editor.json --store my-test-store --secret-key my-dev-secret-key
75
- ```
76
-
77
- ## Model
78
-
79
- Push or pull model definitions, including namespaced models (e.g. content models), abstract content models and content fields.
80
-
81
- ```sh
82
- # pull => retrieves a model from the server and tries to merge and/or write to a specified JSON file or stdout (by default)
83
- # --content flag toggles between base models and abstract content models or content fields
84
- swell model pull -m MODEL_ID [--file (-f) String] [--strategy (-s) String] [--content Boolean]
85
-
86
- # push => send a model definition from a JSON file or stdin to the server
87
- swell model push [--file (-f) String] [--input (-i) stdin] [--content Boolean]
88
- ```
89
-
90
- It is important that the model definition includes some fields depending on the type/source of the model.
91
-
92
- #### Basic model
93
-
94
- ```json
95
- {
96
- "name": "Test", // slug will be assumed from this field
97
- "slug": "test_model", // or you can define one explicitly
98
- "fields": { ... }
99
- }
100
- ```
101
-
102
- #### Namespaced model
103
-
104
- ```json
105
- {
106
- "name": "Page", // slug will be assumed from this field
107
- "namespace": "content",
108
- "fields": { ... }
109
- }
110
- ```
111
-
112
- #### Theme content (abstract) model/fields (use with --content flag)
113
-
114
- ```json
115
- {
116
- "name": "Test", // slug will be assumed from this field
117
- "fields": { ... },
118
- "source_type": "theme",
119
- "source_id": "origin"
120
- }
121
- ```
122
-
123
- ### Examples
124
-
125
- ```sh
126
- swell model pull -m products # pull products model and display in stdout
127
- swell model pull -m theme.origin.page --content -f models/page.json # pull a content model and save it to a file
128
-
129
- swell model push -f models/orders.json
130
- swell model push -c -f models/page.json # push a content model
131
- ```
132
-
133
- ### Without logging in
134
-
135
- ```sh
136
- swell model pull -m products --store my-test-store --secret-key my-dev-secret-key
137
- swell model pull -m theme.origin.page --content -f models/page.json --store my-test-store --secret-key my-dev-secret-key
138
-
139
- swell model push -f models/orders.json --store my-test-store --secret-key my-dev-secret-key
140
- swell model push -c -f models/page.json --store my-test-store --secret-key my-dev-secret-key
141
- ```
3
+ Find the alpha docs at https://www.notion.so/swellcorp/CLI-reference-c3553ebb3de24d94becbedf95a5a25d8?pvs=4
package/bin/dev.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\dev" %*
package/bin/dev.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ // eslint-disable-next-line unicorn/prefer-top-level-await, node/shebang
4
+ (async () => {
5
+ const oclif = await import('@oclif/core');
6
+ await oclif.execute({ type: 'esm', development: true, dir: import.meta.url });
7
+ })();
package/bin/run.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
package/bin/run.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ // eslint-disable-next-line unicorn/prefer-top-level-await, node/shebang
4
+ (async () => {
5
+ const oclif = await import('@oclif/core');
6
+ await oclif.execute({ type: 'esm', dir: import.meta.url });
7
+ })();
@@ -0,0 +1,22 @@
1
+ import { Config } from '@oclif/core';
2
+ import { SwellCommand } from './swell-command.js';
3
+ /**
4
+ * A base class for Swell CLI commands that do not require an app to be saved
5
+ * to the API. If your command requires an app to be saved to the API, extend
6
+ * the `RemoteAppCommand` class instead.
7
+ *
8
+ * This class extends the `SwellCommand` class and adds:
9
+ *
10
+ * - a config instance
11
+ * - a shorthand attribute for the app directory
12
+ */
13
+ export declare abstract class AppCommand extends SwellCommand {
14
+ static baseFlags: {
15
+ 'app-path': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
16
+ };
17
+ appConfig: any;
18
+ appPath: string;
19
+ constructor(argv: string[], config: Config);
20
+ init(): Promise<void>;
21
+ protected initBaseFlags(): Promise<void>;
22
+ }
@@ -0,0 +1,45 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { default as appConfig } from './lib/app-config.js';
3
+ import { SwellCommand } from './swell-command.js';
4
+ /**
5
+ * A base class for Swell CLI commands that do not require an app to be saved
6
+ * to the API. If your command requires an app to be saved to the API, extend
7
+ * the `RemoteAppCommand` class instead.
8
+ *
9
+ * This class extends the `SwellCommand` class and adds:
10
+ *
11
+ * - a config instance
12
+ * - a shorthand attribute for the app directory
13
+ */
14
+ export class AppCommand extends SwellCommand {
15
+ // base flags for all AppCommands
16
+ // needs to be in a ES2021 format: https://github.com/oclif/oclif/issues/1100
17
+ static baseFlags = {
18
+ 'app-path': Flags.string({
19
+ description: 'path to the app directory',
20
+ }),
21
+ };
22
+ // local app configuration, what developers define
23
+ appConfig;
24
+ // the local path to the app directory
25
+ appPath = '';
26
+ constructor(argv, config) {
27
+ super(argv, config);
28
+ this.appConfig = appConfig();
29
+ this.appPath = this.appConfig.swDirPath;
30
+ }
31
+ async init() {
32
+ await super.init();
33
+ await this.initBaseFlags();
34
+ }
35
+ async initBaseFlags() {
36
+ const klass = super.ctor;
37
+ // ensure the base flags are available
38
+ klass.flags = { ...klass.flags, ...AppCommand.baseFlags };
39
+ const { flags } = await this.parse(klass);
40
+ // if the user passed an app path, use it: reload the app config
41
+ this.appConfig = appConfig(flags['app-path']);
42
+ this.appPath = this.appConfig.swDirPath;
43
+ this.debug(`config path loaded: ${this.appConfig.path}`);
44
+ }
45
+ }
@@ -0,0 +1,8 @@
1
+ import { RemoteAppCommand } from '../../remote-app-command.js';
2
+ export default class AppPull extends RemoteAppCommand {
3
+ static args: {
4
+ appId: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static summary: string;
7
+ run(): Promise<void>;
8
+ }
@@ -0,0 +1,45 @@
1
+ import { Args } from '@oclif/core';
2
+ import { dasherize, pluralize, underscore } from 'inflection';
3
+ import * as path from 'node:path';
4
+ import { newConfig } from '../../lib/app-config.js';
5
+ import { ConfigPaths, writeJsonFile, } from '../../lib/apps/index.js';
6
+ import { toAppId } from '../../lib/create/index.js';
7
+ import style from '../../lib/style.js';
8
+ import { RemoteAppCommand } from '../../remote-app-command.js';
9
+ export default class AppPull extends RemoteAppCommand {
10
+ static args = {
11
+ appId: Args.string({ description: 'app id to pull' }),
12
+ };
13
+ static summary = 'Pull app configuration from remote.';
14
+ async run() {
15
+ const { args } = await this.parse(AppPull);
16
+ const { appId } = args;
17
+ this.appPath = process.cwd();
18
+ if (!appId) {
19
+ this.error('You must provide an app id to pull');
20
+ }
21
+ this.log(`Will pull app configuration for ${style.appConfigValue(appId)} in ${this.appPath}`);
22
+ this.app = await this.getApp(appId);
23
+ this.debug('run: app', this.app);
24
+ // save app definition
25
+ const config = newConfig();
26
+ const appConfigJson = {
27
+ description: this.app.description || '',
28
+ id: toAppId(this.app.name),
29
+ name: this.app.name,
30
+ version: this.app.version,
31
+ };
32
+ config.clear();
33
+ config.set(appConfigJson);
34
+ // save app configs
35
+ for (const config of this.app?.configs || []) {
36
+ if (!config)
37
+ continue;
38
+ const configType = config.type;
39
+ const typeDirName = ConfigPaths[configType];
40
+ const fileName = pluralize(dasherize(underscore(config.name)).toLowerCase());
41
+ const filePath = path.join(this.appPath, typeDirName, `${fileName}.json`);
42
+ writeJsonFile(filePath, config.values);
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,12 @@
1
+ import { RemoteAppCommand } from '../../remote-app-command.js';
2
+ export default class AppUninstall extends RemoteAppCommand {
3
+ static description: string;
4
+ static flags: {
5
+ env: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
6
+ store: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ };
8
+ static orientation: {
9
+ env: string;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,45 @@
1
+ import { confirm } from '@inquirer/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import config from '../../lib/config.js';
4
+ import style from '../../lib/style.js';
5
+ import { RemoteAppCommand } from '../../remote-app-command.js';
6
+ export default class AppUninstall extends RemoteAppCommand {
7
+ static description = 'Uninstalls an existing App';
8
+ static flags = {
9
+ env: Flags.string({
10
+ default: 'test',
11
+ description: 'environment to uninstall the app from',
12
+ }),
13
+ store: Flags.string({
14
+ char: 's',
15
+ description: 'store id to uninstall the app from',
16
+ }),
17
+ };
18
+ static orientation = {
19
+ env: 'test',
20
+ };
21
+ async run() {
22
+ const { flags } = await this.parse(AppUninstall);
23
+ const { env, store } = flags;
24
+ this.app = await this.getAppWithConfig();
25
+ const storeToUninstall = store || config.getDefaultStore();
26
+ config.ensureLoggedIn(storeToUninstall);
27
+ const uninstallMsg = `${style.appConfigValue(this.app.name)} from store ${style.storeId(storeToUninstall)} with version ${style.appConfigValue(this.app.version)}`;
28
+ const continueUninstall = await confirm({
29
+ message: `Uninstalling ${uninstallMsg}. Ok to continue?`,
30
+ });
31
+ if (!continueUninstall) {
32
+ this.logError('Uninstall cancelled');
33
+ return;
34
+ }
35
+ const clientApp = await this.api.get({ adminPath: `/client/apps/${this.app.id}` }, { query: { env } });
36
+ if (!clientApp) {
37
+ this.error(`Error uninstalling ${uninstallMsg}: app not installed on store.`);
38
+ }
39
+ if (clientApp.uninstalled) {
40
+ this.error(`Error uninstalling ${uninstallMsg}: app already uninstalled on store.`);
41
+ }
42
+ await this.api.put({ adminPath: `/client/apps/${this.app.id}` }, { body: { env, uninstalled: true } });
43
+ this.log(`${style.appConfigValue(this.app.name)} app uninstalled from store ${style.storeId(storeToUninstall)}.`);
44
+ }
45
+ }
@@ -0,0 +1,15 @@
1
+ import { RemoteAppCommand } from '../../remote-app-command.js';
2
+ export default class AppInfo extends RemoteAppCommand {
3
+ static args: {
4
+ versions: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: {
8
+ command: string;
9
+ description: string;
10
+ }[];
11
+ static summary: string;
12
+ run(): Promise<void>;
13
+ private showAppInfo;
14
+ private showVersions;
15
+ }
@@ -0,0 +1,92 @@
1
+ import { Args } from '@oclif/core';
2
+ import ora from 'ora';
3
+ import { getBorderCharacters, table } from 'table';
4
+ import { FieldDefinitions } from '../../lib/info.js';
5
+ import style from '../../lib/style.js';
6
+ import { RemoteAppCommand } from '../../remote-app-command.js';
7
+ // The app fields will be displayed in the order they are defined here
8
+ const FIELDS_TO_DISPLAY = [
9
+ 'name',
10
+ 'description',
11
+ 'version',
12
+ 'public_id',
13
+ 'published',
14
+ 'date_created',
15
+ 'date_updated',
16
+ 'installed',
17
+ 'client',
18
+ ];
19
+ export default class AppInfo extends RemoteAppCommand {
20
+ static args = {
21
+ versions: Args.string({ description: 'list all app versions' }),
22
+ };
23
+ static description = `The command shows the latest information about your app including the name,
24
+ description, version, public ID, test store, and more. If the ${style.command('versions')} argument is passed,
25
+ it will output all versions of the app instead.`;
26
+ static examples = [
27
+ {
28
+ command: 'swell app info',
29
+ description: 'Show general information about the app.',
30
+ },
31
+ {
32
+ command: 'swell app info versions',
33
+ description: 'Show all established versions of the app.',
34
+ },
35
+ ];
36
+ static summary = 'Show information about your Swell app.';
37
+ async run() {
38
+ const { args } = await this.parse(AppInfo);
39
+ const { versions } = args;
40
+ if (versions) {
41
+ await this.showVersions();
42
+ return;
43
+ }
44
+ await this.showAppInfo();
45
+ }
46
+ async showAppInfo() {
47
+ const spinner = ora();
48
+ spinner.start('Retrieving app info...');
49
+ this.app = await this.getAppWithConfig().catch((error) => {
50
+ spinner.fail(`Error fetching app info:`);
51
+ throw error;
52
+ });
53
+ if (spinner.isSpinning) {
54
+ spinner.stop();
55
+ }
56
+ // we pull versions to make sure that what is displayed is the latest
57
+ const versions = await this.getVersions();
58
+ // Output the app field information, e.g.:
59
+ // Name: My App
60
+ const fieldDefinitions = new FieldDefinitions(this.app, versions);
61
+ for (const field of FIELDS_TO_DISPLAY) {
62
+ const fieldDef = fieldDefinitions.getFieldDefinition(field);
63
+ this.log(style.appConfigName(`${fieldDef.label}:`), fieldDef.value);
64
+ }
65
+ // dashboard url is built, not part of the app object
66
+ // we display it at the end for better readability and simplicity
67
+ this.log(style.appConfigName('Dashboard:'), style.link(this.dashboardUrl({}, this.app.client_id)));
68
+ }
69
+ async showVersions() {
70
+ const spinner = ora();
71
+ spinner.start('Retrieving app versions...');
72
+ this.app = await this.getAppWithConfig().catch((error) => {
73
+ spinner.fail(`Error fetching app info: ${JSON.stringify(this.app)}`);
74
+ throw error;
75
+ });
76
+ const versions = await this.handleRequestErrors(async () => this.getVersions(), () => spinner.fail('Error fetching app versions'));
77
+ if (versions.length === 0) {
78
+ spinner.warn('No versions found');
79
+ return;
80
+ }
81
+ spinner.succeed(`${this.app.name} app versions:\n`);
82
+ const displayData = versions.map((appVersion) => [
83
+ style.appConfigValue(appVersion.version),
84
+ appVersion.notes,
85
+ new Date(appVersion.date_created).toUTCString(),
86
+ ]);
87
+ this.log(table(displayData, {
88
+ border: getBorderCharacters('void'),
89
+ drawHorizontalLine: () => false,
90
+ }));
91
+ }
92
+ }
@@ -0,0 +1,17 @@
1
+ import { RemoteAppCommand } from '../../remote-app-command.js';
2
+ export default class AppInstall extends RemoteAppCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ env: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ store: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ version: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
9
+ };
10
+ static summary: string;
11
+ run(): Promise<void>;
12
+ private installApp;
13
+ private installConfirmationMessage;
14
+ private updateApp;
15
+ private getInstalledApp;
16
+ private confirmRemoveDevelopmentApp;
17
+ }