@swell/cli 1.0.2 → 2.0.1-alpha.2
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/LICENSE.md +21 -0
- package/README.md +2 -140
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +7 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +7 -0
- package/dist/app-command.d.ts +22 -0
- package/dist/app-command.js +45 -0
- package/dist/commands/app/_pull.d.ts +8 -0
- package/dist/commands/app/_pull.js +45 -0
- package/dist/commands/app/_uninstall.d.ts +12 -0
- package/dist/commands/app/_uninstall.js +45 -0
- package/dist/commands/app/info.d.ts +15 -0
- package/dist/commands/app/info.js +92 -0
- package/dist/commands/app/install.d.ts +17 -0
- package/dist/commands/app/install.js +177 -0
- package/dist/commands/app/push.d.ts +17 -0
- package/dist/commands/app/push.js +158 -0
- package/dist/commands/app/version.d.ts +18 -0
- package/dist/commands/app/version.js +156 -0
- package/dist/commands/app/watch.d.ts +15 -0
- package/dist/commands/app/watch.js +110 -0
- package/dist/commands/create/app.d.ts +21 -0
- package/dist/commands/create/app.js +210 -0
- package/dist/commands/create/content.d.ts +19 -0
- package/dist/commands/create/content.js +87 -0
- package/dist/commands/create/function.d.ts +25 -0
- package/dist/commands/create/function.js +191 -0
- package/dist/commands/create/index.d.ts +6 -0
- package/dist/commands/create/index.js +34 -0
- package/dist/commands/create/model.d.ts +19 -0
- package/dist/commands/create/model.js +87 -0
- package/dist/commands/create/notification.d.ts +25 -0
- package/dist/commands/create/notification.js +170 -0
- package/dist/commands/login.d.ts +22 -0
- package/dist/commands/login.js +77 -0
- package/dist/commands/logout.d.ts +8 -0
- package/dist/commands/logout.js +45 -0
- package/dist/commands/logs.d.ts +23 -0
- package/dist/commands/logs.js +207 -0
- package/dist/commands/switch.d.ts +10 -0
- package/dist/commands/switch.js +41 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.js +24 -0
- package/dist/create-collection-command.d.ts +26 -0
- package/dist/create-collection-command.js +97 -0
- package/dist/create-command.d.ts +16 -0
- package/dist/create-command.js +59 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/api.d.ts +13 -0
- package/dist/lib/api.js +117 -0
- package/dist/lib/app-config.d.ts +29 -0
- package/dist/lib/app-config.js +127 -0
- package/dist/lib/apps/app-config.d.ts +42 -0
- package/dist/lib/apps/app-config.js +167 -0
- package/dist/lib/apps/index.d.ts +67 -0
- package/dist/lib/apps/index.js +167 -0
- package/dist/lib/apps/paths.d.ts +18 -0
- package/dist/lib/apps/paths.js +54 -0
- package/dist/lib/bundle.d.ts +1 -0
- package/dist/lib/bundle.js +40 -0
- package/dist/lib/config.d.ts +37 -0
- package/dist/lib/config.js +131 -0
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +17 -0
- package/dist/lib/create/content.d.ts +23 -0
- package/dist/lib/create/content.js +40 -0
- package/dist/lib/create/function.d.ts +17 -0
- package/dist/lib/create/function.js +36 -0
- package/dist/lib/create/index.d.ts +13 -0
- package/dist/lib/create/index.js +20 -0
- package/dist/lib/create/model.d.ts +22 -0
- package/dist/lib/create/model.js +30 -0
- package/dist/lib/create/notification.d.ts +25 -0
- package/dist/lib/create/notification.js +1 -0
- package/dist/lib/info.d.ts +38 -0
- package/dist/lib/info.js +91 -0
- package/dist/lib/logs/index.d.ts +23 -0
- package/dist/lib/logs/index.js +88 -0
- package/dist/lib/logs/line-output.d.ts +5 -0
- package/dist/lib/logs/line-output.js +13 -0
- package/dist/lib/logs/output.d.ts +7 -0
- package/dist/lib/logs/output.js +8 -0
- package/dist/lib/logs/table-output.d.ts +11 -0
- package/dist/lib/logs/table-output.js +128 -0
- package/dist/lib/sessions.d.ts +9 -0
- package/dist/lib/sessions.js +110 -0
- package/dist/lib/stores.d.ts +63 -0
- package/dist/lib/stores.js +173 -0
- package/dist/lib/style.d.ts +24 -0
- package/dist/lib/style.js +29 -0
- package/dist/lib/swell-function-wrapper.d.ts +88 -0
- package/dist/lib/swell-function-wrapper.js +302 -0
- package/dist/remote-app-command.d.ts +36 -0
- package/dist/remote-app-command.js +367 -0
- package/dist/swell-command.d.ts +21 -0
- package/dist/swell-command.js +43 -0
- package/oclif.manifest.json +1085 -0
- package/package.json +81 -43
- package/LICENSE +0 -674
- package/dist/bin/multipart-parser-85ef9626.js +0 -456
- package/dist/bin/swell-0f71f07d.js +0 -30670
- package/dist/bin/swell.js +0 -24
- 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
|
-
|
|
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
package/bin/dev.js
ADDED
package/bin/run.cmd
ADDED
package/bin/run.js
ADDED
|
@@ -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 snakeCase from 'lodash/snakeCase.js';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { newConfig } from '../../lib/app-config.js';
|
|
6
|
+
import { ConfigPaths, writeJsonFile, } from '../../lib/apps/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: snakeCase(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: ${JSON.stringify(this.app)}`);
|
|
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
|
+
}
|