@swell/cli 2.1.0 → 2.2.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/dist/commands/api/delete.d.ts +15 -0
- package/dist/commands/api/delete.js +26 -0
- package/dist/commands/api/get.d.ts +15 -0
- package/dist/commands/api/get.js +31 -0
- package/dist/commands/api/index.d.ts +7 -0
- package/dist/commands/api/index.js +16 -0
- package/dist/commands/api/post.d.ts +16 -0
- package/dist/commands/api/post.js +33 -0
- package/dist/commands/api/put.d.ts +16 -0
- package/dist/commands/api/put.js +33 -0
- package/dist/commands/app/dev.d.ts +9 -9
- package/dist/commands/app/dev.js +163 -139
- package/dist/commands/app/frontend/dev.d.ts +1 -1
- package/dist/commands/app/frontend/dev.js +84 -78
- package/dist/commands/app/install.js +3 -3
- package/dist/commands/app/pull.d.ts +1 -1
- package/dist/commands/app/pull.js +6 -6
- package/dist/commands/app/push.d.ts +3 -3
- package/dist/commands/app/push.js +8 -6
- package/dist/commands/app/release.d.ts +1 -1
- package/dist/commands/app/release.js +1 -1
- package/dist/commands/app/version.d.ts +1 -1
- package/dist/commands/app/version.js +5 -3
- package/dist/commands/create/app.d.ts +10 -2
- package/dist/commands/create/app.js +226 -57
- package/dist/commands/create/content.d.ts +4 -0
- package/dist/commands/create/content.js +83 -15
- package/dist/commands/create/function.js +27 -5
- package/dist/commands/create/index.js +5 -1
- package/dist/commands/create/model.d.ts +4 -0
- package/dist/commands/create/model.js +120 -25
- package/dist/commands/create/tests.d.ts +15 -0
- package/dist/commands/create/tests.js +79 -0
- package/dist/commands/inspect/content.d.ts +25 -0
- package/dist/commands/inspect/content.js +159 -0
- package/dist/commands/inspect/index.d.ts +7 -0
- package/dist/commands/inspect/index.js +16 -0
- package/dist/commands/inspect/models.d.ts +27 -0
- package/dist/commands/inspect/models.js +197 -0
- package/dist/commands/schema.d.ts +27 -0
- package/dist/commands/schema.js +231 -0
- package/dist/commands/theme/dev.d.ts +1 -1
- package/dist/commands/theme/dev.js +2 -2
- package/dist/commands/theme/init.d.ts +1 -1
- package/dist/commands/theme/init.js +1 -1
- package/dist/commands/theme/pull.d.ts +2 -2
- package/dist/commands/theme/pull.js +2 -2
- package/dist/commands/theme/push.d.ts +1 -1
- package/dist/commands/theme/push.js +1 -1
- package/dist/create-app-command.d.ts +12 -2
- package/dist/create-app-command.js +103 -80
- package/dist/create-collection-command.js +4 -1
- package/dist/create-config-command.js +4 -0
- package/dist/env/local.d.ts +1 -0
- package/dist/env/local.js +1 -0
- package/dist/env/production.d.ts +1 -0
- package/dist/env/production.js +1 -0
- package/dist/env/review.d.ts +1 -0
- package/dist/env/review.js +1 -0
- package/dist/env/staging.d.ts +1 -0
- package/dist/env/staging.js +1 -0
- package/dist/lib/api.d.ts +16 -5
- package/dist/lib/api.js +67 -25
- package/dist/lib/app-config.js +1 -0
- package/dist/lib/apps/index.d.ts +2 -0
- package/dist/lib/apps/index.js +20 -14
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/constants.d.ts +1 -0
- package/dist/lib/constants.js +1 -0
- package/dist/lib/create/content.d.ts +5 -1
- package/dist/lib/create/content.js +8 -1
- package/dist/lib/create/function.d.ts +2 -1
- package/dist/lib/create/function.js +7 -3
- package/dist/lib/create/model.d.ts +1 -0
- package/dist/lib/create/schemas.d.ts +6 -0
- package/dist/lib/create/schemas.js +6 -0
- package/dist/lib/create/tests/templates/env-dts.d.ts +1 -0
- package/dist/lib/create/tests/templates/env-dts.js +14 -0
- package/dist/lib/create/tests/templates/index.d.ts +8 -0
- package/dist/lib/create/tests/templates/index.js +8 -0
- package/dist/lib/create/tests/templates/integration-test.d.ts +1 -0
- package/dist/lib/create/tests/templates/integration-test.js +19 -0
- package/dist/lib/create/tests/templates/mock-request.d.ts +2 -0
- package/dist/lib/create/tests/templates/mock-request.js +112 -0
- package/dist/lib/create/tests/templates/setup-globals.d.ts +1 -0
- package/dist/lib/create/tests/templates/setup-globals.js +23 -0
- package/dist/lib/create/tests/templates/swell-client.d.ts +1 -0
- package/dist/lib/create/tests/templates/swell-client.js +126 -0
- package/dist/lib/create/tests/templates/tsconfig.d.ts +1 -0
- package/dist/lib/create/tests/templates/tsconfig.js +15 -0
- package/dist/lib/create/tests/templates/unit-test.d.ts +1 -0
- package/dist/lib/create/tests/templates/unit-test.js +42 -0
- package/dist/lib/create/tests/templates/vitest-config.d.ts +2 -0
- package/dist/lib/create/tests/templates/vitest-config.js +121 -0
- package/dist/lib/create/tests/types.d.ts +21 -0
- package/dist/lib/create/tests/types.js +1 -0
- package/dist/lib/create/tests.d.ts +4 -0
- package/dist/lib/create/tests.js +113 -0
- package/dist/lib/sessions.js +4 -3
- package/dist/lib/style.js +0 -1
- package/dist/lib/theme-sync.d.ts +6 -6
- package/dist/lib/theme-sync.js +49 -39
- package/dist/push-app-command.d.ts +7 -7
- package/dist/push-app-command.js +38 -36
- package/dist/remote-app-command.d.ts +1 -1
- package/dist/remote-app-command.js +4 -2
- package/dist/swell-api-command.d.ts +13 -0
- package/dist/swell-api-command.js +75 -0
- package/dist/swell-command.d.ts +1 -1
- package/dist/swell-command.js +9 -9
- package/oclif.manifest.json +639 -46
- package/package.json +8 -1
|
@@ -36,6 +36,12 @@ ${Object.values(ConfigPaths)
|
|
|
36
36
|
env: 'test',
|
|
37
37
|
};
|
|
38
38
|
static summary = 'Pull app files from Swell to your local machine.';
|
|
39
|
+
logPulledChanges(pulled, removed) {
|
|
40
|
+
const typeLabel = this.appType === 'theme' ? 'theme' : 'app';
|
|
41
|
+
const changeCount = pulled.length + removed.length;
|
|
42
|
+
const pluralFiles = changeCount === 1 ? 'file' : 'files';
|
|
43
|
+
this.log(`Pulled ${changeCount} ${pluralFiles} from ${style.appConfigValue(this.app.name)} ${typeLabel} in ${style.path(path.resolve(this.appPath))}.`);
|
|
44
|
+
}
|
|
39
45
|
async run() {
|
|
40
46
|
const { args, flags } = await this.parse(AppPull);
|
|
41
47
|
const { force } = flags;
|
|
@@ -44,10 +50,4 @@ ${Object.values(ConfigPaths)
|
|
|
44
50
|
const { pulled, removed } = await this.pullAppConfigs(force);
|
|
45
51
|
this.logPulledChanges(pulled, removed);
|
|
46
52
|
}
|
|
47
|
-
logPulledChanges(pulled, removed) {
|
|
48
|
-
const typeLabel = this.appType === 'theme' ? 'theme' : 'app';
|
|
49
|
-
const changeCount = pulled.length + removed.length;
|
|
50
|
-
const pluralFiles = changeCount === 1 ? 'file' : 'files';
|
|
51
|
-
this.log(`Pulled ${changeCount} ${pluralFiles} from ${style.appConfigValue(this.app.name)} ${typeLabel} in ${style.path(path.resolve(this.appPath))}.`);
|
|
52
|
-
}
|
|
53
53
|
}
|
|
@@ -3,15 +3,15 @@ export default class AppPush extends PushAppCommand {
|
|
|
3
3
|
static args: {
|
|
4
4
|
file: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
|
+
static delayOrientation: boolean;
|
|
6
7
|
static description: string;
|
|
7
8
|
static examples: string[];
|
|
8
9
|
static flags: any;
|
|
9
|
-
static summary: string;
|
|
10
|
-
static delayOrientation: boolean;
|
|
11
10
|
static orientation: {
|
|
12
11
|
env: string;
|
|
13
12
|
};
|
|
14
|
-
|
|
13
|
+
static summary: string;
|
|
14
|
+
resolvePushPaths(file: string, appPathFlag?: string): {
|
|
15
15
|
filePath: string;
|
|
16
16
|
relativePath: string;
|
|
17
17
|
};
|
|
@@ -10,6 +10,7 @@ export default class AppPush extends PushAppCommand {
|
|
|
10
10
|
description: 'relative path to a configuration file or directory to push',
|
|
11
11
|
}),
|
|
12
12
|
};
|
|
13
|
+
static delayOrientation = true;
|
|
13
14
|
static description = `Push all app files, a specific file, or a specific configuration
|
|
14
15
|
type to an app in your store's test environment.
|
|
15
16
|
|
|
@@ -38,14 +39,15 @@ ${Object.values(ConfigPaths)
|
|
|
38
39
|
description: 'skip deploying app frontend',
|
|
39
40
|
}),
|
|
40
41
|
};
|
|
41
|
-
static summary = 'Push local files to your Swell app.';
|
|
42
|
-
static delayOrientation = true;
|
|
43
42
|
static orientation = {
|
|
44
43
|
env: 'test',
|
|
45
44
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
static summary = 'Push local files to your Swell app.';
|
|
46
|
+
resolvePushPaths(file, appPathFlag) {
|
|
47
|
+
// If --app-path was explicitly provided, resolve FILE relative to appPath
|
|
48
|
+
// Otherwise, resolve relative to cwd for better UX (tab completion)
|
|
49
|
+
const baseDir = appPathFlag ? this.appPath : process.cwd();
|
|
50
|
+
const filePath = path.resolve(baseDir, file);
|
|
49
51
|
// Check if filePath is outside of appPath
|
|
50
52
|
const relativePath = path.relative(this.appPath, filePath);
|
|
51
53
|
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
|
|
@@ -71,7 +73,7 @@ ${Object.values(ConfigPaths)
|
|
|
71
73
|
return;
|
|
72
74
|
}
|
|
73
75
|
if (file) {
|
|
74
|
-
const { filePath, relativePath } = this.resolvePushPaths(file);
|
|
76
|
+
const { filePath, relativePath } = this.resolvePushPaths(file, flags['app-path']);
|
|
75
77
|
// Push individual files if not referring to the whole app path
|
|
76
78
|
if (filePath !== this.appPath) {
|
|
77
79
|
if (!filePathExists(filePath)) {
|
|
@@ -6,10 +6,10 @@ export default class AppRelease extends PushAppCommand {
|
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
8
8
|
static flags: any;
|
|
9
|
-
static summary: string;
|
|
10
9
|
static orientation: {
|
|
11
10
|
env: string;
|
|
12
11
|
};
|
|
12
|
+
static summary: string;
|
|
13
13
|
run(): Promise<void>;
|
|
14
14
|
validateReleaseDetails(): void;
|
|
15
15
|
private validateCreateVersion;
|
|
@@ -56,10 +56,10 @@ The app must be connected to a partner account with access to publish.`;
|
|
|
56
56
|
description: 'skip confirmation prompt',
|
|
57
57
|
}),
|
|
58
58
|
};
|
|
59
|
-
static summary = 'Release a new version of your an app for publishing to the App Store.';
|
|
60
59
|
static orientation = {
|
|
61
60
|
env: 'test',
|
|
62
61
|
};
|
|
62
|
+
static summary = 'Release a new version of your an app for publishing to the App Store.';
|
|
63
63
|
async run() {
|
|
64
64
|
const { args, flags } = await this.parse(AppRelease);
|
|
65
65
|
const { amend, message, 'not-supported': notSupported, 'release-notes': releaseNotesFile, yes, } = flags;
|
|
@@ -11,10 +11,10 @@ export default class AppVersion extends PushAppCommand {
|
|
|
11
11
|
'no-git-tag': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
12
12
|
yes: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
13
13
|
};
|
|
14
|
-
static summary: string;
|
|
15
14
|
static orientation: {
|
|
16
15
|
env: string;
|
|
17
16
|
};
|
|
17
|
+
static summary: string;
|
|
18
18
|
run(): Promise<void>;
|
|
19
19
|
private createRemoteVersion;
|
|
20
20
|
private gitCommit;
|
|
@@ -67,10 +67,10 @@ behavior by using the --no-git-tag option.`;
|
|
|
67
67
|
description: 'skip confirmation prompt',
|
|
68
68
|
}),
|
|
69
69
|
};
|
|
70
|
-
static summary = 'Increment the version of your Swell app.';
|
|
71
70
|
static orientation = {
|
|
72
71
|
env: 'test',
|
|
73
72
|
};
|
|
73
|
+
static summary = 'Increment the version of your Swell app.';
|
|
74
74
|
async run() {
|
|
75
75
|
const { args, flags } = await this.parse(AppVersion);
|
|
76
76
|
const { amend, 'no-git-tag': noGitTag, yes } = flags;
|
|
@@ -96,7 +96,9 @@ behavior by using the --no-git-tag option.`;
|
|
|
96
96
|
const latestVersion = await this.getVersion();
|
|
97
97
|
const remoteVersion = latestVersion?.version;
|
|
98
98
|
// Suggest the next version if not provided
|
|
99
|
-
if (!nextVersion &&
|
|
99
|
+
if (!nextVersion &&
|
|
100
|
+
remoteVersion &&
|
|
101
|
+
semver.gt(localVersion, remoteVersion)) {
|
|
100
102
|
nextVersion = localVersion;
|
|
101
103
|
}
|
|
102
104
|
// If the user didn't specify a version, show the latest one
|
|
@@ -187,7 +189,7 @@ behavior by using the --no-git-tag option.`;
|
|
|
187
189
|
// increment the version
|
|
188
190
|
version = semver.inc(localVersion, version);
|
|
189
191
|
}
|
|
190
|
-
if (semver.
|
|
192
|
+
if (semver.lte(version, localVersion)) {
|
|
191
193
|
this.error(`Version ${version} must be greater than the current version ${localVersion}.`);
|
|
192
194
|
}
|
|
193
195
|
return version;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CreateAppCommand } from '../../create-app-command.js';
|
|
2
2
|
export default class CreateApp extends CreateAppCommand {
|
|
3
|
-
appType: string;
|
|
4
3
|
static args: {
|
|
5
4
|
id: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
6
5
|
};
|
|
@@ -10,11 +9,18 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
10
9
|
description: string;
|
|
11
10
|
}[];
|
|
12
11
|
static flags: any;
|
|
13
|
-
|
|
12
|
+
appType: string;
|
|
13
|
+
createSwellConfig({ allowOverwrite, inputId, inputStorefrontApp, inputType, inputName, inputVersion, inputDescription, inputFrontend, inputIntegrationType, inputIntegrationId, inputYes, nestedPath, }: {
|
|
14
14
|
allowOverwrite?: boolean;
|
|
15
|
+
inputDescription?: string;
|
|
16
|
+
inputFrontend?: string;
|
|
15
17
|
inputId?: string;
|
|
18
|
+
inputIntegrationId?: string;
|
|
19
|
+
inputIntegrationType?: string;
|
|
20
|
+
inputName?: string;
|
|
16
21
|
inputStorefrontApp?: string;
|
|
17
22
|
inputType?: string;
|
|
23
|
+
inputVersion?: string;
|
|
18
24
|
inputYes?: boolean;
|
|
19
25
|
nestedPath?: boolean;
|
|
20
26
|
}): Promise<{
|
|
@@ -22,6 +28,7 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
22
28
|
config: any;
|
|
23
29
|
installedStorefrontApp: any;
|
|
24
30
|
swellConfigJson: {
|
|
31
|
+
extensions?: any[] | undefined;
|
|
25
32
|
theme: {
|
|
26
33
|
storefront: {
|
|
27
34
|
app: string;
|
|
@@ -33,6 +40,7 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
33
40
|
type: string;
|
|
34
41
|
version: string;
|
|
35
42
|
} | {
|
|
43
|
+
extensions?: any[] | undefined;
|
|
36
44
|
permissions: never[];
|
|
37
45
|
description: string;
|
|
38
46
|
id: string;
|
|
@@ -7,30 +7,49 @@ import { newConfig, swellConfigFileExists } from '../../lib/app-config.js';
|
|
|
7
7
|
import { toAppId, toAppName } from '../../lib/create/index.js';
|
|
8
8
|
import style from '../../lib/style.js';
|
|
9
9
|
export default class CreateApp extends CreateAppCommand {
|
|
10
|
-
appType = '';
|
|
11
10
|
static args = {
|
|
12
11
|
id: Args.string({
|
|
13
12
|
default: '',
|
|
14
|
-
description: `id of the app to create`,
|
|
13
|
+
description: `id of the app to create (required in -y)`,
|
|
15
14
|
}),
|
|
16
15
|
};
|
|
17
16
|
static description = 'Create an app.';
|
|
18
17
|
static examples = [
|
|
19
18
|
{
|
|
20
19
|
command: 'swell create app',
|
|
21
|
-
description: '
|
|
20
|
+
description: 'Interactive: follow prompts to create an app.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
command: 'swell create app my_app -t admin -y',
|
|
24
|
+
description: 'Non-interactive: minimal with defaults.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
command: 'swell create app my_app --type admin --name "My App" --version 1.0.1 --description "" -y',
|
|
28
|
+
description: 'Non-interactive: explicit name, version, description.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
command: 'swell create app my_app --type admin --frontend astro -y',
|
|
32
|
+
description: 'Non-interactive: initialize an Astro frontend.',
|
|
22
33
|
},
|
|
23
34
|
{
|
|
24
|
-
command: 'swell create app
|
|
25
|
-
description: '
|
|
35
|
+
command: 'swell create app my_theme --type theme --storefront-app proxima -y',
|
|
36
|
+
description: 'Non-interactive: theme targeting a specific storefront app.',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
command: 'swell create app my_payment --type integration --integration-type payment --integration-id card -y',
|
|
40
|
+
description: 'Non-interactive: payment integration for credit cards.',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
command: 'swell create app my_shipping --type integration --integration-type shipping --integration-id fedex -y',
|
|
44
|
+
description: 'Non-interactive: shipping integration for FedEx.',
|
|
26
45
|
},
|
|
27
46
|
{
|
|
28
47
|
command: 'swell create app -p yarn',
|
|
29
|
-
description: '
|
|
48
|
+
description: 'Package manager: use Yarn instead of npm.',
|
|
30
49
|
},
|
|
31
50
|
{
|
|
32
51
|
command: 'swell create app -p none',
|
|
33
|
-
description: '
|
|
52
|
+
description: 'Package manager: skip installing default dependencies.',
|
|
34
53
|
},
|
|
35
54
|
];
|
|
36
55
|
static flags = {
|
|
@@ -42,34 +61,66 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
42
61
|
}),
|
|
43
62
|
type: Flags.string({
|
|
44
63
|
char: 't',
|
|
45
|
-
description: `create a specific app type`,
|
|
64
|
+
description: `create a specific app type (required in -y)`,
|
|
46
65
|
options: ['admin', 'integration', 'storefront', 'theme'],
|
|
47
66
|
}),
|
|
67
|
+
name: Flags.string({
|
|
68
|
+
char: 'n',
|
|
69
|
+
description: `application name (default: capitalized ID)`,
|
|
70
|
+
}),
|
|
71
|
+
version: Flags.string({
|
|
72
|
+
char: 'v',
|
|
73
|
+
description: `application version (default: 1.0.0)`,
|
|
74
|
+
}),
|
|
75
|
+
description: Flags.string({
|
|
76
|
+
char: 'd',
|
|
77
|
+
description: `application description`,
|
|
78
|
+
}),
|
|
48
79
|
};
|
|
49
|
-
|
|
50
|
-
|
|
80
|
+
appType = '';
|
|
81
|
+
async createSwellConfig({ allowOverwrite = true, inputId = '', inputStorefrontApp, inputType, inputName, inputVersion, inputDescription, inputFrontend, inputIntegrationType, inputIntegrationId, inputYes, nestedPath = true, }) {
|
|
82
|
+
const confirmYes = inputYes;
|
|
83
|
+
let appId = toAppId(inputId || '');
|
|
84
|
+
let storefrontInstalledApps;
|
|
85
|
+
let storefrontAppId;
|
|
86
|
+
let installedStorefrontApp;
|
|
87
|
+
// check missed parameters
|
|
88
|
+
if (confirmYes) {
|
|
89
|
+
if (!appId) {
|
|
90
|
+
this.error('Missing application id for non-interactive mode\n\nYou need to provide an app id value for non-interactive mode\n\nExample: swell create app reviews --type admin -y', {
|
|
91
|
+
exit: 1,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (!inputType) {
|
|
95
|
+
this.error('Missing required flag for non-interactive mode: --type\n\nValid types: admin, integration, storefront, theme\n\nExample: swell create app reviews --type admin -y', {
|
|
96
|
+
exit: 1,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (!inputName) {
|
|
100
|
+
inputName = toAppName(inputId);
|
|
101
|
+
}
|
|
102
|
+
if (!inputVersion) {
|
|
103
|
+
inputVersion = '1.0.0';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
51
106
|
const type = inputType ||
|
|
52
|
-
(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
message: `What is the primary purpose of the app?`,
|
|
62
|
-
}));
|
|
107
|
+
(await select({
|
|
108
|
+
choices: [
|
|
109
|
+
{ name: 'Admin', value: 'admin' },
|
|
110
|
+
{ name: 'Integration', value: 'integration' },
|
|
111
|
+
{ name: 'Storefront', value: 'storefront' },
|
|
112
|
+
{ name: 'Theme', value: 'theme' },
|
|
113
|
+
],
|
|
114
|
+
message: `What is the primary purpose of the app?`,
|
|
115
|
+
}));
|
|
63
116
|
const typeLabel = type === 'theme' ? 'theme' : 'app';
|
|
64
117
|
const typeLabelTitle = type === 'theme' ? 'Theme' : 'App';
|
|
65
|
-
const name =
|
|
66
|
-
|
|
67
|
-
: await input({
|
|
118
|
+
const name = inputName ||
|
|
119
|
+
(await input({
|
|
68
120
|
default: inputId ? toAppName(inputId) : '',
|
|
69
121
|
message: `${typeLabelTitle} name`,
|
|
70
122
|
validate: (answer) => answer.length > 2,
|
|
71
|
-
});
|
|
72
|
-
let appId = toAppId(inputId || '');
|
|
123
|
+
}));
|
|
73
124
|
if (!appId) {
|
|
74
125
|
appId = await input({
|
|
75
126
|
default: toAppId(name),
|
|
@@ -77,39 +128,135 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
77
128
|
validate: (answer) => answer.length > 2,
|
|
78
129
|
});
|
|
79
130
|
appId = toAppId(appId);
|
|
80
|
-
confirmYes = Boolean(inputYes && appId);
|
|
81
131
|
}
|
|
82
|
-
const version =
|
|
83
|
-
|
|
84
|
-
: await input({
|
|
132
|
+
const version = inputVersion ||
|
|
133
|
+
(await input({
|
|
85
134
|
default: '1.0.0',
|
|
86
135
|
message: `${typeLabelTitle} version`,
|
|
87
|
-
});
|
|
88
|
-
const description =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let
|
|
96
|
-
let
|
|
136
|
+
}));
|
|
137
|
+
const description = inputDescription ||
|
|
138
|
+
(confirmYes
|
|
139
|
+
? ''
|
|
140
|
+
: await input({
|
|
141
|
+
default: 'Something special',
|
|
142
|
+
message: `Describe your ${typeLabel}`,
|
|
143
|
+
}));
|
|
144
|
+
let integrationType;
|
|
145
|
+
let extensions;
|
|
146
|
+
if (type === 'integration') {
|
|
147
|
+
if (confirmYes && !inputIntegrationType) {
|
|
148
|
+
this.error('Missing required flag for non-interactive mode for integration app: --integration-type\n\nValid types: generic, payment, shipping, tax\n\nExample: swell create app reviews --type integration --integration-type generic -y', {
|
|
149
|
+
exit: 1,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
integrationType =
|
|
153
|
+
inputIntegrationType ||
|
|
154
|
+
(await select({
|
|
155
|
+
choices: [
|
|
156
|
+
{ name: 'Generic', value: 'generic' },
|
|
157
|
+
{ name: 'Payment gateway', value: 'payment' },
|
|
158
|
+
{ name: 'Shipping service', value: 'shipping' },
|
|
159
|
+
{ name: 'Tax service', value: 'tax' },
|
|
160
|
+
],
|
|
161
|
+
message: `What type of integration?`,
|
|
162
|
+
}));
|
|
163
|
+
// Create extensions array based on integration type
|
|
164
|
+
switch (integrationType) {
|
|
165
|
+
case 'generic': {
|
|
166
|
+
// No extension needed for generic integrations
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case 'payment':
|
|
170
|
+
case 'shipping':
|
|
171
|
+
case 'tax': {
|
|
172
|
+
// Unified validation for all extension-based integrations
|
|
173
|
+
if (confirmYes && !inputIntegrationId) {
|
|
174
|
+
const validValues = integrationType === 'payment'
|
|
175
|
+
? "use 'card' for credit card integration or unique custom ID for other payment integrations"
|
|
176
|
+
: 'unique custom ID';
|
|
177
|
+
this.error(`Missing required flag for non-interactive mode for ${integrationType} integration: --integration-id\n\nValid values: ${validValues}\n\nExample: swell create app my_app --type integration --integration-type ${integrationType} --integration-id ${integrationType === 'payment' ? 'card' : 'myid'} -y`, {
|
|
178
|
+
exit: 1,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// Interactive prompting
|
|
182
|
+
let integrationId = inputIntegrationId;
|
|
183
|
+
if (!integrationId) {
|
|
184
|
+
if (integrationType === 'payment') {
|
|
185
|
+
const methodChoice = await select({
|
|
186
|
+
choices: [
|
|
187
|
+
{ name: 'Credit card', value: 'card' },
|
|
188
|
+
{ name: 'Custom method', value: 'custom' },
|
|
189
|
+
],
|
|
190
|
+
message: `What type of payment method?`,
|
|
191
|
+
});
|
|
192
|
+
integrationId =
|
|
193
|
+
methodChoice === 'custom'
|
|
194
|
+
? await input({
|
|
195
|
+
message: `Enter a unique ID for your payment method`,
|
|
196
|
+
validate: (answer) => answer.length > 2,
|
|
197
|
+
})
|
|
198
|
+
: methodChoice; // 'card'
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Shipping or tax
|
|
202
|
+
const serviceLabel = integrationType === 'shipping'
|
|
203
|
+
? 'shipping service'
|
|
204
|
+
: 'tax service';
|
|
205
|
+
integrationId = await input({
|
|
206
|
+
message: `Enter a unique ID for your ${serviceLabel}`,
|
|
207
|
+
validate: (answer) => answer.length > 2,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Unified validation
|
|
212
|
+
if (integrationId.length < 3) {
|
|
213
|
+
this.error(`--integration-id must contain at least 3 characters\n\nValid value is a custom ID containing at least 3 characters\n\nExample: swell create app my_app --type integration --integration-type ${integrationType} --integration-id ${integrationType === 'payment' ? 'card' : 'myid'} -y`, {
|
|
214
|
+
exit: 1,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// Create extension
|
|
218
|
+
extensions = [
|
|
219
|
+
{
|
|
220
|
+
id: integrationId,
|
|
221
|
+
type: integrationType,
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
default: {
|
|
227
|
+
this.error('Incorrect value for --integration-type\n\nValid types: generic, payment, shipping, tax\n\nExample: swell create app reviews --type integration --integration-type generic -y', {
|
|
228
|
+
exit: 1,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
97
233
|
if (type === 'theme') {
|
|
98
234
|
storefrontInstalledApps = await this.getInstalledStorefrontApps();
|
|
99
235
|
if (storefrontInstalledApps === false) {
|
|
100
|
-
|
|
236
|
+
this.error('There are no installed storefront apps\n\nTo use the theme type, you first need to install the storefront app', {
|
|
237
|
+
exit: 1,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
storefrontAppId = inputStorefrontApp || '';
|
|
241
|
+
if (!storefrontAppId) {
|
|
242
|
+
if (storefrontInstalledApps.length === 1) {
|
|
243
|
+
storefrontAppId = storefrontInstalledApps[0].id;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
if (confirmYes) {
|
|
247
|
+
this.error('There are several installed storefront apps to choose from\n\nYou should select a specific storefront app in the non-interactive mode using --storefront-app appid\n\nExample: swell create app reviews --type theme --storefront-app proxima -y', {
|
|
248
|
+
exit: 1,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
storefrontAppId = await select({
|
|
252
|
+
choices: storefrontInstalledApps.map(({ app, id }) => ({
|
|
253
|
+
name: app.name,
|
|
254
|
+
value: id,
|
|
255
|
+
})),
|
|
256
|
+
message: `Which storefront app is your theme for?`,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
101
259
|
}
|
|
102
|
-
storefrontAppId =
|
|
103
|
-
inputStorefrontApp ||
|
|
104
|
-
(storefrontInstalledApps.length > 1
|
|
105
|
-
? await select({
|
|
106
|
-
choices: storefrontInstalledApps.map(({ app, id }) => ({
|
|
107
|
-
name: app.name,
|
|
108
|
-
value: id,
|
|
109
|
-
})),
|
|
110
|
-
message: `Which storefront app is your theme for?`,
|
|
111
|
-
})
|
|
112
|
-
: storefrontInstalledApps[0].id);
|
|
113
260
|
installedStorefrontApp = storefrontInstalledApps.find((installedApp) => inputStorefrontApp
|
|
114
261
|
? inputStorefrontApp === installedApp.app_private_id ||
|
|
115
262
|
inputStorefrontApp === installedApp.app_public_id ||
|
|
@@ -117,7 +264,20 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
117
264
|
inputStorefrontApp === toAppId(installedApp.app_private_id)
|
|
118
265
|
: installedApp.id === storefrontAppId);
|
|
119
266
|
if (!installedStorefrontApp) {
|
|
120
|
-
this.error(`Could not find an installed storefront app by id: ${storefrontAppId}
|
|
267
|
+
this.error(`Could not find an installed storefront app by id: ${storefrontAppId}\n\nThe selected storefront app is not among the installed storefront apps`, {
|
|
268
|
+
exit: 1,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// check inputFrontend value
|
|
273
|
+
if (!installedStorefrontApp &&
|
|
274
|
+
confirmYes &&
|
|
275
|
+
inputFrontend &&
|
|
276
|
+
inputFrontend !== 'none') {
|
|
277
|
+
const projectType = this.getProjectType(inputFrontend);
|
|
278
|
+
if (!projectType) {
|
|
279
|
+
// error should be thrown from getProjectType
|
|
280
|
+
return;
|
|
121
281
|
}
|
|
122
282
|
}
|
|
123
283
|
const swellConfigJson = {
|
|
@@ -137,6 +297,7 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
137
297
|
: {
|
|
138
298
|
permissions: [],
|
|
139
299
|
}),
|
|
300
|
+
...(extensions && { extensions }),
|
|
140
301
|
};
|
|
141
302
|
const appPath = path.join(process.cwd(), inputId || appId);
|
|
142
303
|
if (swellConfigFileExists(appPath)) {
|
|
@@ -151,7 +312,9 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
151
312
|
}
|
|
152
313
|
}
|
|
153
314
|
else {
|
|
154
|
-
this.error(`An app already exists in the target path ${appPath}
|
|
315
|
+
this.error(`An app already exists in the target path ${appPath}.\n\nCannot overwrite existing app`, {
|
|
316
|
+
exit: 1,
|
|
317
|
+
});
|
|
155
318
|
}
|
|
156
319
|
}
|
|
157
320
|
this.log(`\nCreating ${this.appType === 'theme' ? 'theme' : 'app'} ${style.appConfigValue(name)} in ${appPath}/swell.json`);
|
|
@@ -172,13 +335,19 @@ export default class CreateApp extends CreateAppCommand {
|
|
|
172
335
|
async run() {
|
|
173
336
|
const { args, flags } = await this.parse(CreateApp);
|
|
174
337
|
const { id } = args;
|
|
175
|
-
const { pkg, yes } = flags;
|
|
176
|
-
const confirmYes = Boolean(yes
|
|
338
|
+
const { pkg, yes, name, type, version, description, frontend } = flags;
|
|
339
|
+
const confirmYes = Boolean(yes);
|
|
177
340
|
const createParams = await this.createSwellConfig({
|
|
178
341
|
inputId: id,
|
|
179
342
|
inputStorefrontApp: flags['storefront-app'],
|
|
180
|
-
inputType:
|
|
343
|
+
inputType: type,
|
|
181
344
|
inputYes: confirmYes,
|
|
345
|
+
inputName: name,
|
|
346
|
+
inputVersion: version,
|
|
347
|
+
inputDescription: description,
|
|
348
|
+
inputFrontend: frontend,
|
|
349
|
+
inputIntegrationType: flags['integration-type'],
|
|
350
|
+
inputIntegrationId: flags['integration-id'],
|
|
182
351
|
});
|
|
183
352
|
if (!createParams) {
|
|
184
353
|
return;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { CreateCollectionCommand } from '../../create-collection-command.js';
|
|
2
2
|
import { ConfigType } from '../../lib/apps/index.js';
|
|
3
3
|
export default class CreateContent extends CreateCollectionCommand {
|
|
4
|
+
static args: {
|
|
5
|
+
collection: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
4
7
|
static description: string;
|
|
5
8
|
static examples: {
|
|
6
9
|
command: string;
|
|
@@ -12,6 +15,7 @@ export default class CreateContent extends CreateCollectionCommand {
|
|
|
12
15
|
label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
13
16
|
overwrite: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
14
17
|
views: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
18
|
+
yes: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
15
19
|
};
|
|
16
20
|
static summary: string;
|
|
17
21
|
createType: ConfigType;
|