@swell/cli 2.0.1-alpha.12 → 2.0.1-alpha.16
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/dist/commands/app/install.d.ts +5 -2
- package/dist/commands/app/install.js +41 -38
- package/dist/commands/app/push.d.ts +3 -3
- package/dist/commands/app/push.js +46 -49
- package/dist/commands/app/version.js +3 -3
- package/dist/commands/create/app.d.ts +8 -8
- package/dist/commands/create/app.js +74 -71
- package/dist/commands/create/content.d.ts +2 -2
- package/dist/commands/create/content.js +10 -10
- package/dist/commands/create/function.d.ts +1 -1
- package/dist/commands/create/function.js +20 -20
- package/dist/commands/create/model.d.ts +2 -2
- package/dist/commands/create/model.js +11 -11
- package/dist/commands/create/notification.d.ts +2 -2
- package/dist/commands/create/notification.js +36 -38
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.js +8 -7
- package/dist/commands/logs.js +2 -0
- package/dist/create-collection-command.d.ts +6 -6
- package/dist/create-collection-command.js +19 -19
- package/dist/create-command.js +6 -4
- package/dist/lib/api.d.ts +3 -2
- package/dist/lib/api.js +11 -8
- package/dist/lib/app-config.d.ts +1 -0
- package/dist/lib/app-config.js +5 -3
- package/dist/lib/apps/index.d.ts +1 -1
- package/dist/lib/apps/index.js +1 -1
- package/dist/lib/apps/paths.d.ts +1 -1
- package/dist/lib/apps/paths.js +1 -1
- package/dist/lib/bundle.js +15 -3
- package/dist/lib/constants.js +2 -3
- package/dist/lib/create/content.d.ts +1 -1
- package/dist/lib/create/content.js +1 -1
- package/dist/lib/create/function.d.ts +2 -2
- package/dist/lib/create/function.js +2 -2
- package/dist/lib/create/index.d.ts +1 -1
- package/dist/lib/create/index.js +6 -6
- package/dist/lib/create/model.d.ts +2 -2
- package/dist/lib/create/notification.d.ts +2 -2
- package/dist/lib/logs/index.js +1 -1
- package/dist/lib/sessions.js +2 -2
- package/dist/lib/stores.d.ts +4 -1
- package/dist/lib/stores.js +6 -3
- package/dist/lib/swell-function-wrapper.d.ts +40 -1
- package/dist/lib/swell-function-wrapper.js +107 -22
- package/dist/remote-app-command.d.ts +2 -2
- package/dist/remote-app-command.js +18 -18
- package/oclif.manifest.json +60 -57
- package/package.json +2 -1
|
@@ -7,11 +7,14 @@ export default class AppInstall extends RemoteAppCommand {
|
|
|
7
7
|
store: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
8
|
version: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
9
|
};
|
|
10
|
+
static orientation: {
|
|
11
|
+
env: string;
|
|
12
|
+
};
|
|
10
13
|
static summary: string;
|
|
11
14
|
run(): Promise<void>;
|
|
15
|
+
private confirmRemoveDevelopmentApp;
|
|
16
|
+
private getInstalledApp;
|
|
12
17
|
private installApp;
|
|
13
18
|
private installConfirmationMessage;
|
|
14
19
|
private updateApp;
|
|
15
|
-
private getInstalledApp;
|
|
16
|
-
private confirmRemoveDevelopmentApp;
|
|
17
20
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { confirm } from '@inquirer/prompts';
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
|
-
import * as semver from 'semver';
|
|
4
3
|
import ora from 'ora';
|
|
4
|
+
import * as semver from 'semver';
|
|
5
5
|
import config from '../../lib/config.js';
|
|
6
|
+
import { selectEnvironmentId, selectLoggedInStoreId, } from '../../lib/stores.js';
|
|
6
7
|
import style from '../../lib/style.js';
|
|
7
|
-
import { selectLoggedInStoreId, selectEnvironmentId, } from '../../lib/stores.js';
|
|
8
8
|
import { RemoteAppCommand } from '../../remote-app-command.js';
|
|
9
9
|
export default class AppInstall extends RemoteAppCommand {
|
|
10
10
|
static description = `Without a version specified, install the latest version of the app.
|
|
@@ -35,6 +35,9 @@ Without a store specified, install the app in the Live environment of the curren
|
|
|
35
35
|
},
|
|
36
36
|
}),
|
|
37
37
|
};
|
|
38
|
+
static orientation = {
|
|
39
|
+
env: 'test',
|
|
40
|
+
};
|
|
38
41
|
static summary = 'Install an existing app in another store environment.';
|
|
39
42
|
async run() {
|
|
40
43
|
const { flags } = await this.parse(AppInstall);
|
|
@@ -91,7 +94,7 @@ Without a store specified, install the app in the Live environment of the curren
|
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
else {
|
|
94
|
-
extraMessage = ` ${style.appConfigValue(this.app.name)} v${versionToInstall} on ${style.storeId(storeToInstall)} [${envToInstall
|
|
97
|
+
extraMessage = ` ${style.appConfigValue(this.app.name)} v${versionToInstall} on ${style.storeId(storeToInstall)} [${envToInstall || 'live'}]`;
|
|
95
98
|
}
|
|
96
99
|
const shouldContinue = existingVersion ||
|
|
97
100
|
(await this.confirmRemoveDevelopmentApp(storeToInstall));
|
|
@@ -103,11 +106,11 @@ Without a store specified, install the app in the Live environment of the curren
|
|
|
103
106
|
let request;
|
|
104
107
|
if (existingInstalledApp?.id) {
|
|
105
108
|
spinner.start(`Updating${extraMessage}...`);
|
|
106
|
-
request = async () => this.updateApp(versionToInstall
|
|
109
|
+
request = async () => this.updateApp(versionToInstall);
|
|
107
110
|
}
|
|
108
111
|
else {
|
|
109
112
|
spinner.start(`Installing${extraMessage}...`);
|
|
110
|
-
request = async () => this.installApp(versionToInstall
|
|
113
|
+
request = async () => this.installApp(versionToInstall);
|
|
111
114
|
}
|
|
112
115
|
const response = await this.handleRequestErrors(request, () => spinner.fail('Something went wrong.'));
|
|
113
116
|
if (response?.errors) {
|
|
@@ -115,44 +118,15 @@ Without a store specified, install the app in the Live environment of the curren
|
|
|
115
118
|
}
|
|
116
119
|
spinner.succeed(`Install complete. Manage app settings in your dashboard at ${style.link(this.dashboardUrl({ flags: { env: envToInstall } }, storeToInstall))}.`);
|
|
117
120
|
}
|
|
118
|
-
async installApp(version, env) {
|
|
119
|
-
return this.api.post({ adminPath: `/client/apps` },
|
|
120
|
-
// eslint-disable-next-line camelcase
|
|
121
|
-
{ body: { app_id: this.app.id, version } });
|
|
122
|
-
}
|
|
123
|
-
installConfirmationMessage(storeToInstall, envToInstall, versionToInstall, existingVersion) {
|
|
124
|
-
const message = [];
|
|
125
|
-
if (existingVersion && semver.gt(versionToInstall, existingVersion)) {
|
|
126
|
-
message.push('Updating');
|
|
127
|
-
}
|
|
128
|
-
else if (existingVersion &&
|
|
129
|
-
semver.lt(versionToInstall, existingVersion)) {
|
|
130
|
-
message.push('Rolling back');
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
message.push('Install');
|
|
134
|
-
}
|
|
135
|
-
let versionToShow = versionToInstall;
|
|
136
|
-
versionToShow += versionToInstall === this.app.version ? ' (latest)' : '';
|
|
137
|
-
message.push(style.appConfigValue(this.app.name), `v${versionToShow}`, `on ${style.storeId(storeToInstall)} [${envToInstall ? envToInstall : 'live'}]?`);
|
|
138
|
-
return message.join(' ');
|
|
139
|
-
}
|
|
140
|
-
async updateApp(version, env) {
|
|
141
|
-
await this.api.put({ adminPath: `/client/apps/${this.app.id}` }, { body: { version } });
|
|
142
|
-
}
|
|
143
|
-
async getInstalledApp() {
|
|
144
|
-
// check if app is already installed on store
|
|
145
|
-
return await this.api.get({ adminPath: `/client/apps/${this.app.id}` }, {});
|
|
146
|
-
}
|
|
147
121
|
async confirmRemoveDevelopmentApp(storeToInstall) {
|
|
148
122
|
const existingSourcedApps = await this.api.get({ adminPath: `/client/apps` }, {
|
|
123
|
+
// eslint-disable-next-line camelcase
|
|
149
124
|
query: { source_id: this.app.id },
|
|
150
125
|
});
|
|
151
126
|
if (existingSourcedApps.results[0]?.id) {
|
|
152
|
-
console.log(existingSourcedApps.results[0]);
|
|
153
127
|
const continueInstall = await confirm({
|
|
154
|
-
message: `${style.storeId(storeToInstall)} has a development version of ${style.appConfigValue(this.app.name)}. Do you want to replace it with an installed instance?`,
|
|
155
128
|
default: false,
|
|
129
|
+
message: `${style.storeId(storeToInstall)} has a development version of ${style.appConfigValue(this.app.name)}. Do you want to replace it with an installed instance?`,
|
|
156
130
|
});
|
|
157
131
|
if (!continueInstall) {
|
|
158
132
|
return false;
|
|
@@ -168,12 +142,41 @@ Without a store specified, install the app in the Live environment of the curren
|
|
|
168
142
|
});
|
|
169
143
|
spinner.succeed('Development app removed.');
|
|
170
144
|
}
|
|
171
|
-
catch (
|
|
145
|
+
catch (error) {
|
|
172
146
|
spinner.fail(`Error removing development app from ${style.storeId(storeToInstall)}.`);
|
|
173
|
-
this.logError(
|
|
147
|
+
this.logError(error.message);
|
|
174
148
|
return false;
|
|
175
149
|
}
|
|
176
150
|
}
|
|
177
151
|
return true;
|
|
178
152
|
}
|
|
153
|
+
async getInstalledApp() {
|
|
154
|
+
// check if app is already installed on store
|
|
155
|
+
return this.api.get({ adminPath: `/client/apps/${this.app.id}` }, {});
|
|
156
|
+
}
|
|
157
|
+
async installApp(version) {
|
|
158
|
+
return this.api.post({ adminPath: `/client/apps` },
|
|
159
|
+
// eslint-disable-next-line camelcase
|
|
160
|
+
{ body: { app_id: this.app.id, version } });
|
|
161
|
+
}
|
|
162
|
+
installConfirmationMessage(storeToInstall, envToInstall, versionToInstall, existingVersion) {
|
|
163
|
+
const message = [];
|
|
164
|
+
if (existingVersion && semver.gt(versionToInstall, existingVersion)) {
|
|
165
|
+
message.push('Updating');
|
|
166
|
+
}
|
|
167
|
+
else if (existingVersion &&
|
|
168
|
+
semver.lt(versionToInstall, existingVersion)) {
|
|
169
|
+
message.push('Rolling back');
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
message.push('Install');
|
|
173
|
+
}
|
|
174
|
+
let versionToShow = versionToInstall;
|
|
175
|
+
versionToShow += versionToInstall === this.app.version ? ' (latest)' : '';
|
|
176
|
+
message.push(style.appConfigValue(this.app.name), `v${versionToShow}`, `on ${style.storeId(storeToInstall)} [${envToInstall || 'live'}]?`);
|
|
177
|
+
return message.join(' ');
|
|
178
|
+
}
|
|
179
|
+
async updateApp(version) {
|
|
180
|
+
await this.api.put({ adminPath: `/client/apps/${this.app.id}` }, { body: { version } });
|
|
181
|
+
}
|
|
179
182
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { RemoteAppCommand } from '../../remote-app-command.js';
|
|
2
2
|
export default class AppPush extends RemoteAppCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
3
|
static args: {
|
|
6
4
|
file: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>;
|
|
7
5
|
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
9
|
file: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
10
10
|
};
|
|
@@ -13,8 +13,8 @@ export default class AppPush extends RemoteAppCommand {
|
|
|
13
13
|
};
|
|
14
14
|
static summary: string;
|
|
15
15
|
run(): Promise<void>;
|
|
16
|
+
private confirmRemoveInstalledApp;
|
|
16
17
|
private logDashboardUrl;
|
|
17
18
|
private pushConfigPath;
|
|
18
19
|
private pushFile;
|
|
19
|
-
private confirmRemoveInstalledApp;
|
|
20
20
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { confirm } from '@inquirer/prompts';
|
|
2
|
-
import {
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import ora from 'ora';
|
|
5
5
|
import { appConfigFileExists } from '../../lib/app-config.js';
|
|
6
6
|
import { ConfigPaths, allConfigFilesPathsByType, appConfigFromFile, getConfigTypeFromPath, getConfigTypeKeyFromValue, } from '../../lib/apps/index.js';
|
|
7
|
+
import { default as swellConfig } from '../../lib/config.js';
|
|
7
8
|
import style from '../../lib/style.js';
|
|
8
9
|
import { RemoteAppCommand } from '../../remote-app-command.js';
|
|
9
|
-
import { default as swellConfig } from '../../lib/config.js';
|
|
10
10
|
export default class AppPush extends RemoteAppCommand {
|
|
11
|
+
static args = {
|
|
12
|
+
file: Args.string({
|
|
13
|
+
char: 'f',
|
|
14
|
+
description: 'relative path to a configuration file or directory to push',
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
11
17
|
static description = `Push all app configurations, a specific file, or a specific configuration
|
|
12
18
|
type to an app in your store's test environment. If the app does not exist yet,
|
|
13
19
|
it will be created and its global ID saved to a .swellrc file.
|
|
@@ -26,12 +32,6 @@ ${Object.values(ConfigPaths)
|
|
|
26
32
|
'swell app push -f content',
|
|
27
33
|
'swell app push -f models/products.json',
|
|
28
34
|
];
|
|
29
|
-
static args = {
|
|
30
|
-
file: Args.string({
|
|
31
|
-
char: 'f',
|
|
32
|
-
description: 'relative path to a configuration file or directory to push',
|
|
33
|
-
}),
|
|
34
|
-
};
|
|
35
35
|
// Deprecating the flags in favor of args
|
|
36
36
|
static flags = {
|
|
37
37
|
file: Flags.string({
|
|
@@ -50,10 +50,9 @@ ${Object.values(ConfigPaths)
|
|
|
50
50
|
const file = fileArg || fileFlag;
|
|
51
51
|
const currentStore = swellConfig.getDefaultStore();
|
|
52
52
|
this.api.setStoreEnv(currentStore, 'test');
|
|
53
|
-
this.app = await this.getAppWithConfig('').catch((
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
});
|
|
53
|
+
this.app = await this.getAppWithConfig('').catch((_error) =>
|
|
54
|
+
// Ignore so we can continue to create it
|
|
55
|
+
({}));
|
|
57
56
|
const confirmExistingApp = await this.confirmRemoveInstalledApp(currentStore);
|
|
58
57
|
if (confirmExistingApp === false) {
|
|
59
58
|
return;
|
|
@@ -63,10 +62,8 @@ ${Object.values(ConfigPaths)
|
|
|
63
62
|
if (!confirmExistingApp?.id) {
|
|
64
63
|
const otherAppName = this.app.name || this.appConfig.get('name');
|
|
65
64
|
const confirmPushNew = await confirm({
|
|
66
|
-
message: `${style.appConfigValue(otherAppName)} has a dev version in another ${this.app.client_id
|
|
67
|
-
? `store ${style.dim(`(${this.app.client_id})`)}`
|
|
68
|
-
: 'environment'}. Do you want to create a new development instance in ${style.storeId(currentStore)}?`,
|
|
69
65
|
default: false,
|
|
66
|
+
message: `${style.appConfigValue(otherAppName)} has a dev version in another environment. Do you want to create a new development instance in ${style.storeId(currentStore)}?`,
|
|
70
67
|
});
|
|
71
68
|
if (!confirmPushNew) {
|
|
72
69
|
return;
|
|
@@ -104,37 +101,6 @@ ${Object.values(ConfigPaths)
|
|
|
104
101
|
this.log(`Pushed ${installed.length} ${installed.length === 1 ? 'configuration' : 'configurations'}${removed.length > 0 ? ` (removed ${removed.length}).` : '.'}`);
|
|
105
102
|
this.logDashboardUrl(flags, currentStore);
|
|
106
103
|
}
|
|
107
|
-
logDashboardUrl(flags, storeId) {
|
|
108
|
-
this.log(`View the ${style.appConfigValue(this.app.name)} app in your dashboard at ${style.link(this.dashboardUrl(flags, storeId))}.`);
|
|
109
|
-
}
|
|
110
|
-
async pushConfigPath(path) {
|
|
111
|
-
const configType = getConfigTypeFromPath(path);
|
|
112
|
-
const configTypeKey = getConfigTypeKeyFromValue(configType);
|
|
113
|
-
if (!configTypeKey) {
|
|
114
|
-
this.error(`Invalid config path: ${path}`);
|
|
115
|
-
}
|
|
116
|
-
let pushedFiles = 0;
|
|
117
|
-
for (const { configFile } of allConfigFilesPathsByType(this.appPath, configTypeKey)) {
|
|
118
|
-
const appConfig = appConfigFromFile(configFile, configType);
|
|
119
|
-
// eslint-disable-next-line no-await-in-loop
|
|
120
|
-
await this.pushConfigFile(appConfig);
|
|
121
|
-
pushedFiles += 1;
|
|
122
|
-
}
|
|
123
|
-
if (pushedFiles === 0) {
|
|
124
|
-
this.log(`No valid files to push found for ${style.path(path)}.`);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
this.log(`Pushed ${style.path(path)} to ${style.appConfigValue(this.app.name)}.`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async pushFile(file) {
|
|
131
|
-
const configType = getConfigTypeFromPath(path.basename(path.dirname(file)));
|
|
132
|
-
if (!configType) {
|
|
133
|
-
this.error(`File ${file} is not a valid file to push.`);
|
|
134
|
-
}
|
|
135
|
-
const appConfig = appConfigFromFile(file, configType);
|
|
136
|
-
await this.pushConfigFile(appConfig);
|
|
137
|
-
}
|
|
138
104
|
async confirmRemoveInstalledApp(currentStore) {
|
|
139
105
|
if (!this.app.private_id) {
|
|
140
106
|
return true;
|
|
@@ -144,8 +110,8 @@ ${Object.values(ConfigPaths)
|
|
|
144
110
|
}, { query: { versioned: true } });
|
|
145
111
|
if (existingInstalledApp) {
|
|
146
112
|
const continuePush = await confirm({
|
|
147
|
-
message: `${style.storeId(currentStore)} has an installed version of ${style.appConfigValue(this.app.name)} v${existingInstalledApp.version}. Do you want to replace it with a development instance?`,
|
|
148
113
|
default: false,
|
|
114
|
+
message: `${style.storeId(currentStore)} has an installed version of ${style.appConfigValue(this.app.name)} v${existingInstalledApp.version}. Do you want to replace it with a development instance?`,
|
|
149
115
|
});
|
|
150
116
|
if (!continuePush) {
|
|
151
117
|
return false;
|
|
@@ -162,12 +128,43 @@ ${Object.values(ConfigPaths)
|
|
|
162
128
|
spinner.succeed('Installed app removed.');
|
|
163
129
|
this.log();
|
|
164
130
|
}
|
|
165
|
-
catch (
|
|
131
|
+
catch (error) {
|
|
166
132
|
spinner.fail(`Error removing installed app from ${style.storeId(currentStore)}.`);
|
|
167
|
-
this.logError(
|
|
133
|
+
this.logError(error.message);
|
|
168
134
|
return false;
|
|
169
135
|
}
|
|
170
136
|
}
|
|
171
137
|
return existingInstalledApp;
|
|
172
138
|
}
|
|
139
|
+
logDashboardUrl(flags, storeId) {
|
|
140
|
+
this.log(`View the ${style.appConfigValue(this.app.name)} app in your dashboard at ${style.link(this.dashboardUrl(flags, storeId))}.`);
|
|
141
|
+
}
|
|
142
|
+
async pushConfigPath(path) {
|
|
143
|
+
const configType = getConfigTypeFromPath(path);
|
|
144
|
+
const configTypeKey = getConfigTypeKeyFromValue(configType);
|
|
145
|
+
if (!configTypeKey) {
|
|
146
|
+
this.error(`Invalid config path: ${path}`);
|
|
147
|
+
}
|
|
148
|
+
let pushedFiles = 0;
|
|
149
|
+
for (const { configFile } of allConfigFilesPathsByType(this.appPath, configTypeKey)) {
|
|
150
|
+
const appConfig = appConfigFromFile(configFile, configType);
|
|
151
|
+
// eslint-disable-next-line no-await-in-loop
|
|
152
|
+
await this.pushConfigFile(appConfig);
|
|
153
|
+
pushedFiles += 1;
|
|
154
|
+
}
|
|
155
|
+
if (pushedFiles === 0) {
|
|
156
|
+
this.log(`No valid files to push found for ${style.path(path)}.`);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
this.log(`Pushed ${style.path(path)} to ${style.appConfigValue(this.app.name)}.`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async pushFile(file) {
|
|
163
|
+
const configType = getConfigTypeFromPath(path.basename(path.dirname(file)));
|
|
164
|
+
if (!configType) {
|
|
165
|
+
this.error(`File ${file} is not a valid file to push.`);
|
|
166
|
+
}
|
|
167
|
+
const appConfig = appConfigFromFile(file, configType);
|
|
168
|
+
await this.pushConfigFile(appConfig);
|
|
169
|
+
}
|
|
173
170
|
}
|
|
@@ -2,8 +2,8 @@ import { confirm, input } from '@inquirer/prompts';
|
|
|
2
2
|
import git from '@npmcli/git';
|
|
3
3
|
import { Args, Flags } from '@oclif/core';
|
|
4
4
|
import { CLIError } from '@oclif/errors';
|
|
5
|
-
import * as semver from 'semver';
|
|
6
5
|
import ora from 'ora';
|
|
6
|
+
import * as semver from 'semver';
|
|
7
7
|
import style from '../../lib/style.js';
|
|
8
8
|
import { RemoteAppCommand } from '../../remote-app-command.js';
|
|
9
9
|
const RELEASE_TYPES = [
|
|
@@ -105,8 +105,8 @@ behavior by using the --git-tag=false option.`;
|
|
|
105
105
|
if (gitTag)
|
|
106
106
|
await this.gitTag(nextVersion);
|
|
107
107
|
}
|
|
108
|
-
catch (
|
|
109
|
-
spinner.fail(
|
|
108
|
+
catch (error) {
|
|
109
|
+
spinner.fail(error.message);
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
spinner.succeed(`${style.appConfigValue(this.app.name)} version ${nextVersion} created.`);
|
|
@@ -3,19 +3,19 @@ export default class CreateApp extends SwellCommand {
|
|
|
3
3
|
static args: {
|
|
4
4
|
id: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
|
-
static flags: {
|
|
7
|
-
pkg: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
-
yes: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
9
|
-
};
|
|
10
6
|
static description: string;
|
|
11
7
|
static examples: {
|
|
12
8
|
command: string;
|
|
13
9
|
description: string;
|
|
14
10
|
}[];
|
|
11
|
+
static flags: {
|
|
12
|
+
pkg: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
|
+
yes: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
14
|
+
};
|
|
15
15
|
run(): Promise<void>;
|
|
16
|
-
private tryPackageSetup;
|
|
17
|
-
private setupPackage;
|
|
18
|
-
private findPackageManager;
|
|
19
|
-
private doesPackageManagerExist;
|
|
20
16
|
private createAppConfigFolders;
|
|
17
|
+
private doesPackageManagerExist;
|
|
18
|
+
private findPackageManager;
|
|
19
|
+
private setupPackage;
|
|
20
|
+
private tryPackageSetup;
|
|
21
21
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { exec } from 'child_process';
|
|
3
|
-
import { promisify } from 'util';
|
|
4
1
|
import { confirm, input, select } from '@inquirer/prompts';
|
|
5
2
|
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { exec } from 'node:child_process';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
6
|
import ora from 'ora';
|
|
7
7
|
import { appConfigFileExists, newConfig } from '../../lib/app-config.js';
|
|
8
|
+
import { getAllConfigPaths, writeJsonFile } from '../../lib/apps/index.js';
|
|
9
|
+
import { toAppId, toAppName } from '../../lib/create/index.js';
|
|
8
10
|
import style from '../../lib/style.js';
|
|
9
11
|
import { SwellCommand } from '../../swell-command.js';
|
|
10
|
-
import { toAppName, toAppId } from '../../lib/create/index.js';
|
|
11
|
-
import { getAllConfigPaths, writeJsonFile } from '../../lib/apps/index.js';
|
|
12
12
|
const execAsync = promisify(exec);
|
|
13
13
|
export default class CreateApp extends SwellCommand {
|
|
14
14
|
static args = {
|
|
@@ -17,18 +17,6 @@ export default class CreateApp extends SwellCommand {
|
|
|
17
17
|
description: `id of the app to create`,
|
|
18
18
|
}),
|
|
19
19
|
};
|
|
20
|
-
static flags = {
|
|
21
|
-
pkg: Flags.string({
|
|
22
|
-
char: 'p',
|
|
23
|
-
default: 'npm',
|
|
24
|
-
description: `use npm or yarn to install default dependencies, or none to disable`,
|
|
25
|
-
options: ['npm', 'yarn', 'none'],
|
|
26
|
-
}),
|
|
27
|
-
yes: Flags.boolean({
|
|
28
|
-
char: 'y',
|
|
29
|
-
description: `accept all default values`,
|
|
30
|
-
}),
|
|
31
|
-
};
|
|
32
20
|
static description = 'Initialize an app with config file and folder structure.';
|
|
33
21
|
static examples = [
|
|
34
22
|
{
|
|
@@ -48,6 +36,18 @@ export default class CreateApp extends SwellCommand {
|
|
|
48
36
|
description: 'Create app without installing TypeScript bindings, etc.',
|
|
49
37
|
},
|
|
50
38
|
];
|
|
39
|
+
static flags = {
|
|
40
|
+
pkg: Flags.string({
|
|
41
|
+
char: 'p',
|
|
42
|
+
default: 'npm',
|
|
43
|
+
description: `use npm or yarn to install default dependencies, or none to disable`,
|
|
44
|
+
options: ['npm', 'yarn', 'none'],
|
|
45
|
+
}),
|
|
46
|
+
yes: Flags.boolean({
|
|
47
|
+
char: 'y',
|
|
48
|
+
description: `accept all default values`,
|
|
49
|
+
}),
|
|
50
|
+
};
|
|
51
51
|
async run() {
|
|
52
52
|
const { args, flags } = await this.parse(CreateApp);
|
|
53
53
|
const { id } = args;
|
|
@@ -56,15 +56,15 @@ export default class CreateApp extends SwellCommand {
|
|
|
56
56
|
const name = confirmYes
|
|
57
57
|
? toAppName(id)
|
|
58
58
|
: await input({
|
|
59
|
-
message: 'App name',
|
|
60
59
|
default: id ? toAppName(id) : '',
|
|
60
|
+
message: 'App name',
|
|
61
61
|
validate: (answer) => answer.length > 2,
|
|
62
62
|
});
|
|
63
63
|
let appId = toAppId(id || '');
|
|
64
64
|
if (!appId) {
|
|
65
65
|
appId = await input({
|
|
66
|
-
message: 'App ID',
|
|
67
66
|
default: toAppId(name),
|
|
67
|
+
message: 'App ID',
|
|
68
68
|
validate: (answer) => answer.length > 2,
|
|
69
69
|
});
|
|
70
70
|
appId = toAppId(appId);
|
|
@@ -73,26 +73,27 @@ export default class CreateApp extends SwellCommand {
|
|
|
73
73
|
const description = confirmYes
|
|
74
74
|
? ''
|
|
75
75
|
: await input({
|
|
76
|
-
message: 'Describe what the app does',
|
|
77
76
|
default: 'Something special',
|
|
77
|
+
message: 'Describe what the app does',
|
|
78
78
|
});
|
|
79
79
|
const type = confirmYes
|
|
80
80
|
? 'admin'
|
|
81
81
|
: await select({
|
|
82
|
-
message: 'What is the primary purpose of the app?',
|
|
83
82
|
choices: [
|
|
84
83
|
{ name: 'Admin', value: 'admin' },
|
|
85
84
|
{ name: 'Integration', value: 'integration' },
|
|
86
85
|
{ name: 'Storefront', value: 'storefront' },
|
|
87
86
|
],
|
|
87
|
+
message: 'What is the primary purpose of the app?',
|
|
88
88
|
});
|
|
89
89
|
const appConfigJson = {
|
|
90
|
+
description,
|
|
90
91
|
id: appId,
|
|
91
|
-
|
|
92
|
+
integrations: [],
|
|
92
93
|
name,
|
|
93
|
-
description,
|
|
94
|
-
type,
|
|
95
94
|
permissions: [],
|
|
95
|
+
type,
|
|
96
|
+
version: '1.0.0',
|
|
96
97
|
};
|
|
97
98
|
const config = newConfig(appId);
|
|
98
99
|
if (!confirmYes && appConfigFileExists(config.path)) {
|
|
@@ -127,34 +128,67 @@ export default class CreateApp extends SwellCommand {
|
|
|
127
128
|
this.log(`Run ${style.command('swell app push')} to push configurations to your test store.`);
|
|
128
129
|
this.log(`Run ${style.command('swell app install')} to install the app in another store or environment.`);
|
|
129
130
|
}
|
|
130
|
-
async
|
|
131
|
+
async createAppConfigFolders(config) {
|
|
132
|
+
for (const type of getAllConfigPaths()) {
|
|
133
|
+
// Create a config folder
|
|
134
|
+
// eslint-disable-next-line no-await-in-loop
|
|
135
|
+
await execAsync(`mkdir -p ${type}`, {
|
|
136
|
+
cwd: path.dirname(config.path),
|
|
137
|
+
});
|
|
138
|
+
// Create gitkeep file
|
|
139
|
+
// eslint-disable-next-line no-await-in-loop
|
|
140
|
+
await execAsync(`touch ${path.join(type, '.gitkeep')}`, {
|
|
141
|
+
cwd: path.dirname(config.path),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async doesPackageManagerExist(packageManager) {
|
|
131
146
|
try {
|
|
132
|
-
await
|
|
147
|
+
await execAsync(`${packageManager} --version`);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
this.debug(`Could not find ${packageManager} on your system. Please install ${packageManager} and try again.`);
|
|
152
|
+
return false;
|
|
133
153
|
}
|
|
134
|
-
|
|
135
|
-
|
|
154
|
+
}
|
|
155
|
+
async findPackageManager(pkg = '') {
|
|
156
|
+
const packageManager = pkg;
|
|
157
|
+
// Determine if system has yarn or npm install
|
|
158
|
+
if (packageManager) {
|
|
159
|
+
if (await this.doesPackageManagerExist(packageManager)) {
|
|
160
|
+
return packageManager;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
if (await this.doesPackageManagerExist('npm')) {
|
|
165
|
+
return 'npm';
|
|
166
|
+
}
|
|
167
|
+
if (await this.doesPackageManagerExist('yarn')) {
|
|
168
|
+
return 'yarn';
|
|
169
|
+
}
|
|
136
170
|
}
|
|
137
171
|
}
|
|
138
172
|
async setupPackage(name, config, pkg) {
|
|
139
173
|
const execAsync = promisify(exec);
|
|
140
174
|
const packageJson = {
|
|
141
|
-
name,
|
|
142
|
-
version: config.get('version'),
|
|
143
175
|
description: config.get('description'),
|
|
144
|
-
scripts: {},
|
|
145
176
|
devDependencies: {
|
|
146
177
|
'@swell/app-types': '^1.0.5',
|
|
147
178
|
},
|
|
179
|
+
name,
|
|
180
|
+
scripts: {},
|
|
181
|
+
version: config.get('version'),
|
|
148
182
|
};
|
|
149
183
|
const tsConfig = {
|
|
150
184
|
compilerOptions: {
|
|
151
|
-
target: 'esnext',
|
|
152
|
-
module: 'esnext',
|
|
153
185
|
lib: ['esnext', 'webworker'],
|
|
186
|
+
module: 'esnext',
|
|
187
|
+
target: 'esnext',
|
|
154
188
|
types: ['@swell/app-types'],
|
|
155
189
|
},
|
|
156
|
-
include: ['**/*.ts'],
|
|
157
190
|
exclude: ['node_modules'],
|
|
191
|
+
include: ['**/*.ts'],
|
|
158
192
|
};
|
|
159
193
|
await writeJsonFile(path.join(path.dirname(config.path), 'package.json'), packageJson);
|
|
160
194
|
await writeJsonFile(path.join(path.dirname(config.path), 'tsconfig.json'), tsConfig);
|
|
@@ -164,47 +198,16 @@ export default class CreateApp extends SwellCommand {
|
|
|
164
198
|
cwd: path.dirname(config.path),
|
|
165
199
|
});
|
|
166
200
|
}
|
|
167
|
-
catch (
|
|
168
|
-
this.error(
|
|
201
|
+
catch (error) {
|
|
202
|
+
this.error(error.message);
|
|
169
203
|
}
|
|
170
204
|
}
|
|
171
|
-
async
|
|
172
|
-
let packageManager = pkg ? pkg : '';
|
|
173
|
-
// Determine if system has yarn or npm install
|
|
174
|
-
if (packageManager) {
|
|
175
|
-
if (await this.doesPackageManagerExist(packageManager)) {
|
|
176
|
-
return packageManager;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
if (await this.doesPackageManagerExist('npm')) {
|
|
181
|
-
return 'npm';
|
|
182
|
-
}
|
|
183
|
-
else if (await this.doesPackageManagerExist('yarn')) {
|
|
184
|
-
return 'yarn';
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async doesPackageManagerExist(packageManager) {
|
|
205
|
+
async tryPackageSetup(name, config, pkg) {
|
|
189
206
|
try {
|
|
190
|
-
await
|
|
191
|
-
return true;
|
|
192
|
-
}
|
|
193
|
-
catch (err) {
|
|
194
|
-
this.debug(`Could not find ${packageManager} on your system. Please install ${packageManager} and try again.`);
|
|
195
|
-
return false;
|
|
207
|
+
await this.setupPackage(name, config, pkg);
|
|
196
208
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
for (const type of getAllConfigPaths()) {
|
|
200
|
-
// Create a config folder
|
|
201
|
-
await execAsync(`mkdir -p ${type}`, {
|
|
202
|
-
cwd: path.dirname(config.path),
|
|
203
|
-
});
|
|
204
|
-
// Create gitkeep file
|
|
205
|
-
await execAsync(`touch ${path.join(type, '.gitkeep')}`, {
|
|
206
|
-
cwd: path.dirname(config.path),
|
|
207
|
-
});
|
|
209
|
+
catch (error) {
|
|
210
|
+
this.log(`There was an error setting up the package manager: ${error.message}`);
|
|
208
211
|
}
|
|
209
212
|
}
|
|
210
213
|
}
|
|
@@ -7,11 +7,11 @@ export default class CreateContent extends CreateCollectionCommand {
|
|
|
7
7
|
description: string;
|
|
8
8
|
}[];
|
|
9
9
|
static flags: {
|
|
10
|
-
label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
10
|
description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
11
|
fields: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
|
-
|
|
12
|
+
label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
14
13
|
overwrite: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
14
|
+
views: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
15
15
|
};
|
|
16
16
|
static summary: string;
|
|
17
17
|
createType: ConfigType;
|