@swell/cli 2.0.1-alpha.9 → 2.0.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/dist/app-command.d.ts +1 -1
- package/dist/app-command.js +9 -9
- package/dist/commands/app/dev.d.ts +16 -0
- package/dist/commands/app/dev.js +28 -0
- package/dist/commands/app/frontend/deploy.d.ts +15 -0
- package/dist/commands/app/frontend/deploy.js +41 -0
- package/dist/commands/app/frontend/dev.d.ts +19 -0
- package/dist/commands/app/frontend/dev.js +108 -0
- package/dist/commands/app/info.js +14 -9
- package/dist/commands/app/init.d.ts +12 -0
- package/dist/commands/app/init.js +34 -0
- package/dist/commands/app/install.d.ts +4 -4
- package/dist/commands/app/install.js +36 -42
- package/dist/commands/app/pull.d.ts +15 -0
- package/dist/commands/app/pull.js +50 -0
- package/dist/commands/app/push.d.ts +11 -14
- package/dist/commands/app/push.js +64 -138
- package/dist/commands/app/release.d.ts +13 -0
- package/dist/commands/app/release.js +148 -0
- package/dist/commands/app/version.d.ts +5 -4
- package/dist/commands/app/version.js +63 -42
- package/dist/commands/app/watch.d.ts +2 -4
- package/dist/commands/app/watch.js +3 -83
- package/dist/commands/create/app.d.ts +35 -11
- package/dist/commands/create/app.js +143 -137
- package/dist/commands/create/content.d.ts +2 -2
- package/dist/commands/create/content.js +10 -10
- package/dist/commands/create/frontend.d.ts +12 -0
- package/dist/commands/create/frontend.js +38 -0
- package/dist/commands/create/function.d.ts +3 -3
- package/dist/commands/create/function.js +22 -22
- package/dist/commands/create/model.d.ts +2 -2
- package/dist/commands/create/model.js +11 -11
- package/dist/commands/create/notification.d.ts +4 -4
- package/dist/commands/create/notification.js +38 -40
- package/dist/commands/env.d.ts +12 -0
- package/dist/commands/env.js +31 -0
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.js +18 -24
- package/dist/commands/logs.js +0 -1
- package/dist/commands/theme/dev.d.ts +21 -0
- package/dist/commands/theme/dev.js +164 -0
- package/dist/commands/theme/init.d.ts +9 -0
- package/dist/commands/theme/init.js +15 -0
- package/dist/commands/theme/pull.d.ts +20 -0
- package/dist/commands/theme/pull.js +65 -0
- package/dist/commands/theme/push.d.ts +19 -0
- package/dist/commands/theme/push.js +89 -0
- package/dist/create-app-command.d.ts +20 -0
- package/dist/create-app-command.js +253 -0
- package/dist/create-collection-command.d.ts +9 -9
- package/dist/create-collection-command.js +23 -23
- package/dist/{create-command.d.ts → create-config-command.d.ts} +1 -1
- package/dist/{create-command.js → create-config-command.js} +7 -7
- package/dist/env/local.d.ts +8 -0
- package/dist/env/local.js +7 -0
- package/dist/env/production.d.ts +8 -0
- package/dist/env/production.js +7 -0
- package/dist/env/review.d.ts +8 -0
- package/dist/env/review.js +7 -0
- package/dist/env/staging.d.ts +8 -0
- package/dist/env/staging.js +7 -0
- package/dist/lib/api.d.ts +4 -2
- package/dist/lib/api.js +50 -21
- package/dist/lib/app-config.d.ts +13 -5
- package/dist/lib/app-config.js +62 -24
- package/dist/lib/apps/app-config.d.ts +17 -3
- package/dist/lib/apps/app-config.js +194 -66
- package/dist/lib/apps/index.d.ts +93 -12
- package/dist/lib/apps/index.js +155 -50
- package/dist/lib/apps/paths.d.ts +14 -7
- package/dist/lib/apps/paths.js +73 -28
- package/dist/lib/bundle.js +15 -3
- package/dist/lib/config.d.ts +9 -2
- package/dist/lib/config.js +49 -1
- package/dist/lib/constants.d.ts +5 -0
- package/dist/lib/constants.js +24 -6
- package/dist/lib/create/content.d.ts +2 -2
- 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 +11 -7
- package/dist/lib/create/model.d.ts +2 -2
- package/dist/lib/create/notification.d.ts +2 -2
- package/dist/lib/info.js +2 -2
- package/dist/lib/logs/index.js +1 -1
- package/dist/lib/sessions.js +2 -2
- package/dist/lib/stores.d.ts +9 -4
- package/dist/lib/stores.js +13 -8
- package/dist/lib/style.d.ts +2 -0
- package/dist/lib/style.js +2 -0
- package/dist/lib/swell-function-wrapper.d.ts +40 -1
- package/dist/lib/swell-function-wrapper.js +107 -22
- package/dist/push-app-command.d.ts +73 -0
- package/dist/push-app-command.js +743 -0
- package/dist/remote-app-command.d.ts +37 -11
- package/dist/remote-app-command.js +432 -169
- package/oclif.manifest.json +872 -123
- package/package.json +14 -1
- package/dist/commands/app/_pull.d.ts +0 -8
- package/dist/commands/app/_pull.js +0 -45
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CreateConfigCommand } from './create-config-command.js';
|
|
2
2
|
/**
|
|
3
3
|
* A base class for Swell CLI Create [content|models] command input.
|
|
4
4
|
*
|
|
5
|
-
* This class extends the `
|
|
5
|
+
* This class extends the `CreateConfigCommand` class and adds:
|
|
6
6
|
*
|
|
7
7
|
* - promptCollection: Get collection name and description
|
|
8
8
|
*/
|
|
9
|
-
export declare abstract class CreateCollectionCommand extends
|
|
10
|
-
static baseFlags: {
|
|
11
|
-
'app-path': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
-
};
|
|
9
|
+
export declare abstract class CreateCollectionCommand extends CreateConfigCommand {
|
|
13
10
|
static args: {
|
|
14
11
|
collection: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
15
12
|
};
|
|
13
|
+
static baseFlags: {
|
|
14
|
+
'app-path': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
15
|
+
};
|
|
16
16
|
static flags: {
|
|
17
|
-
label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
18
17
|
description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
18
|
+
label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
19
19
|
overwrite: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
20
20
|
};
|
|
21
21
|
promptCollection(): Promise<{
|
|
22
|
-
label: string;
|
|
23
|
-
description: string;
|
|
24
22
|
collection: string;
|
|
23
|
+
description: string;
|
|
24
|
+
label: string;
|
|
25
25
|
}>;
|
|
26
26
|
}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { input, select
|
|
1
|
+
import { Separator, input, select } from '@inquirer/prompts';
|
|
2
2
|
import { Args, Flags } from '@oclif/core';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { CreateConfigCommand } from './create-config-command.js';
|
|
4
|
+
import { toCollectionLabel, toCollectionName } from './lib/create/index.js';
|
|
5
5
|
/**
|
|
6
6
|
* A base class for Swell CLI Create [content|models] command input.
|
|
7
7
|
*
|
|
8
|
-
* This class extends the `
|
|
8
|
+
* This class extends the `CreateConfigCommand` class and adds:
|
|
9
9
|
*
|
|
10
10
|
* - promptCollection: Get collection name and description
|
|
11
11
|
*/
|
|
12
|
-
export class CreateCollectionCommand extends
|
|
12
|
+
export class CreateCollectionCommand extends CreateConfigCommand {
|
|
13
13
|
// base flags for all AppCommands
|
|
14
|
-
// needs to be in a ES2021 format: https://github.com/oclif/oclif/issues/1100
|
|
15
|
-
static baseFlags = {
|
|
16
|
-
'app-path': Flags.string({
|
|
17
|
-
description: 'path to the app directory',
|
|
18
|
-
}),
|
|
19
|
-
};
|
|
20
14
|
static args = {
|
|
21
15
|
collection: Args.string({
|
|
22
16
|
default: '',
|
|
23
17
|
description: 'collection to create or apply to, i.e. products',
|
|
24
18
|
}),
|
|
25
19
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
description: 'the collection label',
|
|
20
|
+
// needs to be in a ES2021 format: https://github.com/oclif/oclif/issues/1100
|
|
21
|
+
static baseFlags = {
|
|
22
|
+
'app-path': Flags.string({
|
|
23
|
+
description: 'path to your app directory',
|
|
31
24
|
}),
|
|
25
|
+
};
|
|
26
|
+
static flags = {
|
|
32
27
|
description: Flags.string({
|
|
33
28
|
char: 'd',
|
|
34
29
|
default: '',
|
|
35
30
|
description: 'the collection description',
|
|
36
31
|
}),
|
|
32
|
+
label: Flags.string({
|
|
33
|
+
char: 'l',
|
|
34
|
+
default: '',
|
|
35
|
+
description: 'the collection label',
|
|
36
|
+
}),
|
|
37
37
|
overwrite: Flags.boolean({
|
|
38
38
|
char: 'o',
|
|
39
39
|
default: false,
|
|
@@ -42,14 +42,13 @@ export class CreateCollectionCommand extends CreateCommand {
|
|
|
42
42
|
};
|
|
43
43
|
async promptCollection() {
|
|
44
44
|
const { args, flags } = await this.parse(CreateCollectionCommand);
|
|
45
|
-
let {
|
|
45
|
+
let { description, label } = flags;
|
|
46
46
|
let { collection } = args;
|
|
47
47
|
let isStandardCollection = false;
|
|
48
48
|
let collectionInput = collection;
|
|
49
49
|
if (!collection) {
|
|
50
50
|
const collections = await this.getCollectionOptions();
|
|
51
51
|
collectionInput = await select({
|
|
52
|
-
message: 'Where will content be stored?',
|
|
53
52
|
choices: [
|
|
54
53
|
{ name: 'Create a new collection', value: '' },
|
|
55
54
|
new Separator(),
|
|
@@ -58,6 +57,7 @@ export class CreateCollectionCommand extends CreateCommand {
|
|
|
58
57
|
value: collectionName,
|
|
59
58
|
})),
|
|
60
59
|
],
|
|
60
|
+
message: 'Where will content be stored?',
|
|
61
61
|
pageSize: 25,
|
|
62
62
|
});
|
|
63
63
|
if (collectionInput) {
|
|
@@ -65,8 +65,8 @@ export class CreateCollectionCommand extends CreateCommand {
|
|
|
65
65
|
}
|
|
66
66
|
else {
|
|
67
67
|
collectionInput = await input({
|
|
68
|
-
message: 'Collection name',
|
|
69
68
|
default: 'special-things',
|
|
69
|
+
message: 'Collection name',
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
// we replace unwanted characters with underscores to make things easier
|
|
@@ -75,23 +75,23 @@ export class CreateCollectionCommand extends CreateCommand {
|
|
|
75
75
|
}
|
|
76
76
|
if (!label && !isStandardCollection) {
|
|
77
77
|
label = await input({
|
|
78
|
-
message: 'Collection label',
|
|
79
78
|
default: toCollectionLabel(collection),
|
|
79
|
+
message: 'Collection label',
|
|
80
80
|
});
|
|
81
81
|
label = toCollectionLabel(label);
|
|
82
82
|
}
|
|
83
83
|
description =
|
|
84
84
|
description ||
|
|
85
85
|
(await input({
|
|
86
|
+
default: 'Special things for special people',
|
|
86
87
|
message: isStandardCollection
|
|
87
88
|
? `Describe the purpose of fields being added to ${collection}`
|
|
88
89
|
: 'Describe what this collection is for',
|
|
89
|
-
default: 'Special things for special people',
|
|
90
90
|
}));
|
|
91
91
|
return {
|
|
92
|
-
label,
|
|
93
|
-
description,
|
|
94
92
|
collection,
|
|
93
|
+
description,
|
|
94
|
+
label,
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -9,7 +9,7 @@ import { CreateFileParams } from './lib/create/index.js';
|
|
|
9
9
|
* - createType: Type of Config to generate file path
|
|
10
10
|
* - createFile: File creation, including general prompts
|
|
11
11
|
*/
|
|
12
|
-
export declare abstract class
|
|
12
|
+
export declare abstract class CreateConfigCommand extends AppCommand {
|
|
13
13
|
protected createType: '' | ConfigType;
|
|
14
14
|
protected createFile({ extension, fileBody, fileName }: CreateFileParams, overwrite: boolean, shouldConfirm?: boolean): Promise<boolean | undefined>;
|
|
15
15
|
protected getCollectionOptions(): Promise<any>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { confirm } from '@inquirer/prompts';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { AppCommand } from './app-command.js';
|
|
4
|
-
import { ConfigPaths,
|
|
4
|
+
import { ConfigPaths, filePathExists, writeFile, writeJsonFile, } from './lib/apps/index.js';
|
|
5
5
|
/**
|
|
6
6
|
* A base class for Swell CLI Create commands for file and input handling.
|
|
7
7
|
*
|
|
@@ -10,7 +10,7 @@ import { ConfigPaths, fileExists, writeFile, writeJsonFile, } from './lib/apps/i
|
|
|
10
10
|
* - createType: Type of Config to generate file path
|
|
11
11
|
* - createFile: File creation, including general prompts
|
|
12
12
|
*/
|
|
13
|
-
export class
|
|
13
|
+
export class CreateConfigCommand extends AppCommand {
|
|
14
14
|
createType = '';
|
|
15
15
|
async createFile({ extension = 'json', fileBody, fileName }, overwrite, shouldConfirm = true) {
|
|
16
16
|
const isJson = extension === 'json';
|
|
@@ -18,7 +18,7 @@ export class CreateCommand extends AppCommand {
|
|
|
18
18
|
if (shouldConfirm) {
|
|
19
19
|
this.log(`\nCreating app ${this.createType} in ${filePath}`);
|
|
20
20
|
this.log(`\n${isJson ? JSON.stringify(fileBody, null, 4) : fileBody}\n`);
|
|
21
|
-
if (
|
|
21
|
+
if (filePathExists(filePath) && !overwrite) {
|
|
22
22
|
const continueWrite = await confirm({
|
|
23
23
|
message: `This will overwrite an existing ${this.createType} file. Ok to continue?`,
|
|
24
24
|
});
|
|
@@ -44,14 +44,14 @@ export class CreateCommand extends AppCommand {
|
|
|
44
44
|
async getCollectionOptions() {
|
|
45
45
|
const models = await this.api.post({ adminPath: `/data/$get/:models` }, {
|
|
46
46
|
body: {
|
|
47
|
-
limit: 1000,
|
|
48
|
-
client_id: null,
|
|
49
|
-
app_id: null,
|
|
50
47
|
abstract: { $ne: true },
|
|
48
|
+
app_id: null,
|
|
49
|
+
client_id: null,
|
|
51
50
|
deprecated: { $ne: true },
|
|
51
|
+
fields: 'name, namespace',
|
|
52
|
+
limit: 1000,
|
|
52
53
|
name: { $nin: ['events', 'notifications', 'settings'] },
|
|
53
54
|
sort: 'namespace asc, name asc',
|
|
54
|
-
fields: 'name, namespace',
|
|
55
55
|
},
|
|
56
56
|
});
|
|
57
57
|
return (models?.results?.map((model) => model.namespace ? `${model.namespace}/${model.name}` : model.name) || []);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
API_BASE_URL: 'https://localapi.schema.io:4443',
|
|
3
|
+
ADMIN_API_BASE_URL: 'http://${STORE_ID}.swell.test:4001/admin/api',
|
|
4
|
+
LOGIN_HOST: 'http://${STORE_ID}.swell.test:3000',
|
|
5
|
+
APP_PAGES_HOST: 'http://${STORE_ID}--${APP_ID}--${ENV}.swell.test:4001',
|
|
6
|
+
STOREFRONT_FRONTEND_HOST: 'http://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.test:4001',
|
|
7
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
API_BASE_URL: 'https://api.swell.store',
|
|
3
|
+
ADMIN_API_BASE_URL: 'https://${STORE_ID}.swell.store/admin/api',
|
|
4
|
+
LOGIN_HOST: 'https://${STORE_ID}.swell.store',
|
|
5
|
+
APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.swell.store',
|
|
6
|
+
STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.store',
|
|
7
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
API_BASE_URL: 'https://${REVIEW_DOMAIN}.rav2.swell.store',
|
|
3
|
+
ADMIN_API_BASE_URL: 'https://${STORE_ID}.${REVIEW_DOMAIN}.rav2.swell.store/admin/api',
|
|
4
|
+
LOGIN_HOST: 'https://${REVIEW_DOMAIN}.rav2.swell.store',
|
|
5
|
+
APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.${REVIEW_DOMAIN}.rav2.swell.store',
|
|
6
|
+
STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.${REVIEW_DOMAIN}.rav2.swell.store',
|
|
7
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
API_BASE_URL: 'https://staging.swell.store',
|
|
3
|
+
ADMIN_API_BASE_URL: 'https://${STORE_ID}.staging.swell.store/admin/api',
|
|
4
|
+
LOGIN_HOST: 'https://staging.swell.store',
|
|
5
|
+
APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.staging.swell.store',
|
|
6
|
+
STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.staging.swell.store',
|
|
7
|
+
};
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export default class Api {
|
|
2
|
+
private envId;
|
|
2
3
|
private secretKey;
|
|
3
4
|
private storeId;
|
|
4
|
-
private envId;
|
|
5
5
|
constructor(storeId?: string, envId?: string, secretKey?: string);
|
|
6
|
-
setStoreEnv(storeId: string, envId?: string): void;
|
|
7
6
|
api(pathOpts: Api.Paths, options: Api.RequestOptions): Promise<any>;
|
|
8
7
|
delete(pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<any>;
|
|
9
8
|
get(pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<any>;
|
|
10
9
|
isAdmin(): boolean;
|
|
11
10
|
post(pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<any>;
|
|
12
11
|
put(pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<any>;
|
|
12
|
+
setStoreEnv(storeId: string, envId?: string): void;
|
|
13
|
+
truncatePath(path: string | undefined): string | undefined;
|
|
14
|
+
waitForAsyncResponse(response: any, pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<any>;
|
|
13
15
|
}
|
package/dist/lib/api.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fetch from 'node-fetch';
|
|
2
|
+
import { stringify } from 'qs';
|
|
2
3
|
import config from './config.js';
|
|
3
|
-
import {
|
|
4
|
+
import { API_BASE_URL, getAdminApiBaseUrl } from './constants.js';
|
|
4
5
|
const defaultHeaders = (opts) => ({
|
|
5
6
|
'Content-Type': 'application/json',
|
|
6
7
|
...opts,
|
|
@@ -23,18 +24,14 @@ const authenticatedHeaders = (storeId, opts = {}) => {
|
|
|
23
24
|
return defaultHeaders(moreOpts);
|
|
24
25
|
};
|
|
25
26
|
export default class Api {
|
|
27
|
+
envId;
|
|
26
28
|
secretKey;
|
|
27
29
|
storeId;
|
|
28
|
-
envId;
|
|
29
30
|
constructor(storeId, envId, secretKey) {
|
|
30
31
|
this.storeId = storeId;
|
|
31
32
|
this.envId = envId;
|
|
32
33
|
this.secretKey = secretKey;
|
|
33
34
|
}
|
|
34
|
-
setStoreEnv(storeId, envId) {
|
|
35
|
-
this.storeId = storeId;
|
|
36
|
-
this.envId = envId;
|
|
37
|
-
}
|
|
38
35
|
async api(pathOpts, options) {
|
|
39
36
|
const storeId = this.storeId || config.getDefaultStore();
|
|
40
37
|
let path;
|
|
@@ -51,38 +48,38 @@ export default class Api {
|
|
|
51
48
|
},
|
|
52
49
|
};
|
|
53
50
|
path = this.isAdmin()
|
|
54
|
-
? `${getAdminApiBaseUrl(storeId)}/${pathOpts.adminPath}`
|
|
55
|
-
: `${API_BASE_URL}/${pathOpts.backendPath}`;
|
|
51
|
+
? `${getAdminApiBaseUrl(storeId)}/${this.truncatePath(pathOpts.adminPath)}`
|
|
52
|
+
: `${API_BASE_URL}/${this.truncatePath(pathOpts.backendPath)}`;
|
|
56
53
|
if (options.query) {
|
|
57
|
-
|
|
58
|
-
path += `?${query.toString()}`;
|
|
54
|
+
path += `?${stringify(options.query)}`;
|
|
59
55
|
}
|
|
60
56
|
path = path
|
|
61
|
-
// eslint-disable-next-line no-template-curly-in-string
|
|
62
57
|
.replace('${STORE_ID}', storeId) // replace store id in template string
|
|
63
58
|
.replaceAll(/([^:]\/)\/+/g, '$1'); // remove duplicate slashes
|
|
64
59
|
if (!path)
|
|
65
60
|
throw new Error('Operation not supported.');
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
if (!
|
|
61
|
+
const res = await fetch(path, fetchOptions);
|
|
62
|
+
const resData = await res.text();
|
|
63
|
+
if (!res.ok) {
|
|
69
64
|
// Try to parse error message
|
|
70
65
|
let errorJson;
|
|
71
66
|
try {
|
|
72
|
-
errorJson = JSON.parse(
|
|
67
|
+
errorJson = JSON.parse(resData);
|
|
73
68
|
}
|
|
74
69
|
catch {
|
|
75
70
|
// ignore
|
|
76
71
|
}
|
|
77
|
-
|
|
72
|
+
const error = new Error(errorJson?.error?.message || errorJson?.error || resData);
|
|
73
|
+
error.status = res.status;
|
|
74
|
+
throw error;
|
|
78
75
|
}
|
|
79
76
|
try {
|
|
80
|
-
return JSON.parse(
|
|
77
|
+
return JSON.parse(resData);
|
|
81
78
|
}
|
|
82
79
|
catch (error) {
|
|
83
80
|
// respData could be "{}" (length: >=2) but it shouldn't be "{", " " (whitespace - length: 1) or
|
|
84
81
|
// "" (empty response - length: 0) while logging the error.
|
|
85
|
-
if (
|
|
82
|
+
if (resData.length >= 2)
|
|
86
83
|
console.log(error);
|
|
87
84
|
return null;
|
|
88
85
|
}
|
|
@@ -91,10 +88,11 @@ export default class Api {
|
|
|
91
88
|
// ensure post body is stringified
|
|
92
89
|
if (options.body)
|
|
93
90
|
options.body = JSON.stringify(options.body);
|
|
94
|
-
|
|
91
|
+
const response = await this.api(pathOpts, {
|
|
95
92
|
method: 'DELETE',
|
|
96
93
|
...options,
|
|
97
94
|
});
|
|
95
|
+
return this.waitForAsyncResponse(response, pathOpts, options);
|
|
98
96
|
}
|
|
99
97
|
async get(pathOpts, options = {}) {
|
|
100
98
|
return this.api(pathOpts, {
|
|
@@ -109,18 +107,49 @@ export default class Api {
|
|
|
109
107
|
// ensure post body is stringified
|
|
110
108
|
if (options.body)
|
|
111
109
|
options.body = JSON.stringify(options.body);
|
|
112
|
-
|
|
110
|
+
const response = await this.api(pathOpts, {
|
|
113
111
|
method: 'POST',
|
|
114
112
|
...options,
|
|
115
113
|
});
|
|
114
|
+
return this.waitForAsyncResponse(response, pathOpts, options);
|
|
116
115
|
}
|
|
117
116
|
async put(pathOpts, options = {}) {
|
|
118
117
|
// ensure post body is stringified
|
|
119
118
|
if (options.body)
|
|
120
119
|
options.body = JSON.stringify(options.body);
|
|
121
|
-
|
|
120
|
+
const response = await this.api(pathOpts, {
|
|
122
121
|
method: 'PUT',
|
|
123
122
|
...options,
|
|
124
123
|
});
|
|
124
|
+
return this.waitForAsyncResponse(response, pathOpts, options);
|
|
125
|
+
}
|
|
126
|
+
setStoreEnv(storeId, envId) {
|
|
127
|
+
this.storeId = storeId;
|
|
128
|
+
this.envId = envId;
|
|
129
|
+
}
|
|
130
|
+
truncatePath(path) {
|
|
131
|
+
return path?.startsWith('/') ? path.slice(1) : path;
|
|
132
|
+
}
|
|
133
|
+
async waitForAsyncResponse(response, pathOpts, options = {}) {
|
|
134
|
+
const { onAsyncGetPath, spinner } = options;
|
|
135
|
+
if (!response?.async_progressing || !onAsyncGetPath) {
|
|
136
|
+
return response;
|
|
137
|
+
}
|
|
138
|
+
/* eslint-disable-next-line no-promise-executor-return */
|
|
139
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
140
|
+
const asyncResponse = await this.api(onAsyncGetPath(response), {
|
|
141
|
+
method: 'GET',
|
|
142
|
+
onAsyncGetPath,
|
|
143
|
+
});
|
|
144
|
+
if (asyncResponse?.async_error) {
|
|
145
|
+
throw new Error(asyncResponse.async_error);
|
|
146
|
+
}
|
|
147
|
+
if (!asyncResponse?.async_progressing && spinner) {
|
|
148
|
+
spinner.suffixText = '';
|
|
149
|
+
}
|
|
150
|
+
else if (asyncResponse?.async_progress > 0 && spinner) {
|
|
151
|
+
spinner.suffixText = `${asyncResponse.async_progress}%`;
|
|
152
|
+
}
|
|
153
|
+
return this.waitForAsyncResponse(asyncResponse, pathOpts, options);
|
|
125
154
|
}
|
|
126
155
|
}
|
package/dist/lib/app-config.d.ts
CHANGED
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
import { App } from './apps';
|
|
2
2
|
/**
|
|
3
|
-
* Checks if the
|
|
3
|
+
* Checks if the swell config file exists at the given path, default to cwd.
|
|
4
4
|
*
|
|
5
5
|
* @param configFilePath - the path to the app config file
|
|
6
6
|
* @returns boolean
|
|
7
7
|
* @throws Error
|
|
8
8
|
*/
|
|
9
|
-
declare function
|
|
9
|
+
declare function swellConfigFileExists(configFilePath?: string): boolean;
|
|
10
10
|
declare function writeRcFile(path: string, data: any): Promise<void>;
|
|
11
11
|
declare function readRcFile(path: string): App;
|
|
12
12
|
/**
|
|
13
13
|
* Returns a new configuration instance in the current working directory or
|
|
14
14
|
* a parent directory.
|
|
15
15
|
*
|
|
16
|
-
* @param
|
|
16
|
+
* @param configDir - the path to the app config directory. If not provided,
|
|
17
17
|
* the config file will be searched for in the current working directory or
|
|
18
18
|
* a parent directory.
|
|
19
19
|
*
|
|
20
20
|
* @returns Conf
|
|
21
21
|
*/
|
|
22
|
-
declare function config(
|
|
22
|
+
declare function config(configDir?: string): LocalApp;
|
|
23
23
|
/**
|
|
24
24
|
* Returns a new configuration instance in the current working directory only.
|
|
25
25
|
*
|
|
26
|
+
* @param path Path of the current working directory
|
|
26
27
|
* @returns Conf
|
|
27
28
|
*/
|
|
28
29
|
declare function newConfig(path?: string): any;
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Returns a new configuration instance at the specified path.
|
|
32
|
+
*
|
|
33
|
+
* @param appPath Path of the current working directory
|
|
34
|
+
* @returns Conf
|
|
35
|
+
*/
|
|
36
|
+
declare function newConfigAtPath(appPath?: string): any;
|
|
37
|
+
export { config as default, newConfig, newConfigAtPath, readRcFile, swellConfigFileExists, writeRcFile, };
|
package/dist/lib/app-config.js
CHANGED
|
@@ -5,12 +5,16 @@ import Conf from 'conf';
|
|
|
5
5
|
import * as fs from 'node:fs';
|
|
6
6
|
import * as path from 'node:path';
|
|
7
7
|
const schema = {
|
|
8
|
+
compatibilities: { type: 'object' },
|
|
9
|
+
description: { type: 'string' },
|
|
8
10
|
id: { type: 'string' },
|
|
9
|
-
|
|
11
|
+
integrations: { type: 'array' },
|
|
10
12
|
name: { type: 'string' },
|
|
11
|
-
description: { type: 'string' },
|
|
12
|
-
type: { type: 'string' },
|
|
13
13
|
permissions: { type: 'array' },
|
|
14
|
+
storefront: { type: 'object' },
|
|
15
|
+
theme: { type: 'object' },
|
|
16
|
+
type: { type: 'string' },
|
|
17
|
+
version: { type: 'string' },
|
|
14
18
|
};
|
|
15
19
|
const APP_FILE_NAME = 'swell';
|
|
16
20
|
const APP_FILE_EXT = 'json';
|
|
@@ -21,23 +25,23 @@ const APP_FILE_EXT = 'json';
|
|
|
21
25
|
* @param dir - the directory to use for the config file path
|
|
22
26
|
* @returns string
|
|
23
27
|
*/
|
|
24
|
-
function
|
|
28
|
+
function swellConfigFile(dir = '') {
|
|
25
29
|
if (!dir) {
|
|
26
30
|
dir = process.cwd();
|
|
27
31
|
}
|
|
28
32
|
return path.join(dir, [APP_FILE_NAME, '.', APP_FILE_EXT].join(''));
|
|
29
33
|
}
|
|
30
34
|
/**
|
|
31
|
-
* Checks if the
|
|
35
|
+
* Checks if the swell config file exists at the given path, default to cwd.
|
|
32
36
|
*
|
|
33
37
|
* @param configFilePath - the path to the app config file
|
|
34
38
|
* @returns boolean
|
|
35
39
|
* @throws Error
|
|
36
40
|
*/
|
|
37
|
-
function
|
|
41
|
+
function swellConfigFileExists(configFilePath = '') {
|
|
38
42
|
// if the config file path is not provided, try to find it as the default
|
|
39
43
|
if (!configFilePath) {
|
|
40
|
-
configFilePath =
|
|
44
|
+
configFilePath = swellConfigFile();
|
|
41
45
|
}
|
|
42
46
|
try {
|
|
43
47
|
// eslint-disable-next-line no-bitwise
|
|
@@ -59,9 +63,9 @@ function appConfigFileExists(configFilePath = '') {
|
|
|
59
63
|
* @returns string
|
|
60
64
|
* @throws Error
|
|
61
65
|
*/
|
|
62
|
-
function
|
|
63
|
-
const configFilePath =
|
|
64
|
-
if (
|
|
66
|
+
function swellConfigFilePath(dir = '') {
|
|
67
|
+
const configFilePath = swellConfigFile(dir);
|
|
68
|
+
if (swellConfigFileExists(configFilePath)) {
|
|
65
69
|
return configFilePath;
|
|
66
70
|
}
|
|
67
71
|
// if the file doesn't exist, try to find it in the parent directory
|
|
@@ -69,10 +73,10 @@ function appConfigFilePath(dir = '') {
|
|
|
69
73
|
if (dir && dir === path.parse(dir).root) {
|
|
70
74
|
return '';
|
|
71
75
|
}
|
|
72
|
-
return
|
|
76
|
+
return swellConfigFilePath(path.resolve(dir, '..'));
|
|
73
77
|
}
|
|
74
78
|
async function writeRcFile(path, data) {
|
|
75
|
-
let dataToWrite = '';
|
|
79
|
+
let dataToWrite = '# This file is automatically generated by the Swell CLI\n';
|
|
76
80
|
for (const [key, value] of Object.entries(data)) {
|
|
77
81
|
dataToWrite += `${key}=${value}\n`;
|
|
78
82
|
}
|
|
@@ -83,9 +87,15 @@ function readRcFile(path) {
|
|
|
83
87
|
const dataFromFile = fs.readFileSync(path, 'utf8');
|
|
84
88
|
const lines = dataFromFile.split('\n');
|
|
85
89
|
for (const line of lines) {
|
|
86
|
-
const
|
|
87
|
-
if (
|
|
88
|
-
|
|
90
|
+
const cleanLine = line.trim();
|
|
91
|
+
if (cleanLine.startsWith('#')) {
|
|
92
|
+
// Ignore comments
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const [key, value] = cleanLine.trim().split('=');
|
|
96
|
+
const cleanValue = value && value.trim();
|
|
97
|
+
if (key && cleanValue) {
|
|
98
|
+
data[key] = cleanValue;
|
|
89
99
|
}
|
|
90
100
|
}
|
|
91
101
|
return data;
|
|
@@ -94,19 +104,26 @@ function readRcFile(path) {
|
|
|
94
104
|
* Returns a new configuration instance in the current working directory or
|
|
95
105
|
* a parent directory.
|
|
96
106
|
*
|
|
97
|
-
* @param
|
|
107
|
+
* @param configDir - the path to the app config directory. If not provided,
|
|
98
108
|
* the config file will be searched for in the current working directory or
|
|
99
109
|
* a parent directory.
|
|
100
110
|
*
|
|
101
111
|
* @returns Conf
|
|
102
112
|
*/
|
|
103
|
-
function config(
|
|
104
|
-
const dirPath =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
function config(configDir = '') {
|
|
114
|
+
const dirPath = configDir || path.dirname(swellConfigFilePath());
|
|
115
|
+
let config;
|
|
116
|
+
try {
|
|
117
|
+
config = new Conf({
|
|
118
|
+
clearInvalidConfig: true,
|
|
119
|
+
configName: APP_FILE_NAME,
|
|
120
|
+
cwd: dirPath,
|
|
121
|
+
schema,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
throw new Error(`Error parsing swell.json: ${error.toString()}`);
|
|
126
|
+
}
|
|
110
127
|
// for convenience, we add custom properties to the Conf object
|
|
111
128
|
// we prefix them with "sw" to avoid conflicts with Conf's properties
|
|
112
129
|
config.swDirPath = dirPath;
|
|
@@ -115,13 +132,34 @@ function config(configDirPath = '') {
|
|
|
115
132
|
/**
|
|
116
133
|
* Returns a new configuration instance in the current working directory only.
|
|
117
134
|
*
|
|
135
|
+
* @param path Path of the current working directory
|
|
118
136
|
* @returns Conf
|
|
119
137
|
*/
|
|
120
138
|
function newConfig(path) {
|
|
121
139
|
return new Conf({
|
|
140
|
+
clearInvalidConfig: true,
|
|
122
141
|
configName: APP_FILE_NAME,
|
|
123
142
|
cwd: `${process.cwd()}${path ? `/${path}` : ''}`,
|
|
124
143
|
schema,
|
|
144
|
+
serialize,
|
|
125
145
|
});
|
|
126
146
|
}
|
|
127
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Returns a new configuration instance at the specified path.
|
|
149
|
+
*
|
|
150
|
+
* @param appPath Path of the current working directory
|
|
151
|
+
* @returns Conf
|
|
152
|
+
*/
|
|
153
|
+
function newConfigAtPath(appPath) {
|
|
154
|
+
const dirPath = appPath || path.dirname(swellConfigFilePath());
|
|
155
|
+
return new Conf({
|
|
156
|
+
configName: APP_FILE_NAME,
|
|
157
|
+
cwd: dirPath,
|
|
158
|
+
schema,
|
|
159
|
+
serialize,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function serialize(value) {
|
|
163
|
+
return JSON.stringify(value, null, 2);
|
|
164
|
+
}
|
|
165
|
+
export { config as default, newConfig, newConfigAtPath, readRcFile, swellConfigFileExists, writeRcFile, };
|