@swell/cli 2.4.0 → 2.5.0
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 +1 -0
- package/dist/commands/api/delete.js +8 -1
- package/dist/commands/api/get.d.ts +1 -0
- package/dist/commands/api/get.js +9 -2
- package/dist/commands/api/index.js +4 -2
- package/dist/commands/api/post.d.ts +1 -0
- package/dist/commands/api/post.js +9 -2
- package/dist/commands/api/put.d.ts +1 -0
- package/dist/commands/api/put.js +9 -2
- package/dist/commands/app/frontend/dev.js +18 -1
- package/dist/commands/inspect/models.d.ts +0 -1
- package/dist/commands/inspect/models.js +2 -15
- package/dist/create-app-command.js +1 -1
- 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 +5 -2
- package/dist/lib/api.js +60 -9
- package/dist/lib/apps/index.d.ts +8 -0
- package/dist/lib/apps/index.js +35 -0
- package/dist/lib/constants.d.ts +1 -0
- package/dist/lib/constants.js +5 -0
- package/dist/push-app-command.js +12 -2
- package/dist/swell-api-command.js +8 -2
- package/oclif.manifest.json +64 -11
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@ export default class ApiDelete extends SwellApiCommand {
|
|
|
8
8
|
};
|
|
9
9
|
static flags: {
|
|
10
10
|
live: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
api: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
12
|
};
|
|
12
13
|
static examples: string[];
|
|
13
14
|
get method(): HttpMethod;
|
|
@@ -3,7 +3,8 @@ import { HttpMethod } from '../../lib/api.js';
|
|
|
3
3
|
import { SwellApiCommand } from '../../swell-api-command.js';
|
|
4
4
|
export default class ApiDelete extends SwellApiCommand {
|
|
5
5
|
static summary = 'Send a DELETE request to the Swell API.';
|
|
6
|
-
static description =
|
|
6
|
+
static description = `Remove existing resources from the Swell API.
|
|
7
|
+
Use --api frontend for public key authentication scoped to your app or user.`;
|
|
7
8
|
static args = {
|
|
8
9
|
path: Args.string({
|
|
9
10
|
description: 'API endpoint path (must start with /)',
|
|
@@ -15,10 +16,16 @@ export default class ApiDelete extends SwellApiCommand {
|
|
|
15
16
|
description: 'Use live environment instead of test',
|
|
16
17
|
default: false,
|
|
17
18
|
}),
|
|
19
|
+
api: Flags.string({
|
|
20
|
+
description: 'Use frontend or backend API (frontend uses public key auth).',
|
|
21
|
+
options: ['backend', 'frontend'],
|
|
22
|
+
default: 'backend',
|
|
23
|
+
}),
|
|
18
24
|
};
|
|
19
25
|
static examples = [
|
|
20
26
|
'swell api delete /products/abc123',
|
|
21
27
|
'swell api delete /functions/my-app/clear-cache',
|
|
28
|
+
'swell api delete /products/abc123 --api frontend',
|
|
22
29
|
];
|
|
23
30
|
get method() {
|
|
24
31
|
return HttpMethod.DELETE;
|
|
@@ -8,6 +8,7 @@ export default class ApiGet extends SwellApiCommand {
|
|
|
8
8
|
};
|
|
9
9
|
static flags: {
|
|
10
10
|
live: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
api: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
12
|
};
|
|
12
13
|
static examples: string[];
|
|
13
14
|
get method(): HttpMethod;
|
package/dist/commands/api/get.js
CHANGED
|
@@ -3,8 +3,9 @@ import { HttpMethod } from '../../lib/api.js';
|
|
|
3
3
|
import { SwellApiCommand } from '../../swell-api-command.js';
|
|
4
4
|
export default class ApiGet extends SwellApiCommand {
|
|
5
5
|
static summary = 'Send a GET request to the Swell API.';
|
|
6
|
-
static description = `Retrieve data from the Swell
|
|
7
|
-
|
|
6
|
+
static description = `Retrieve data from the Swell API.
|
|
7
|
+
The command performs a GET request to the specified endpoint path.
|
|
8
|
+
Use --api frontend for public key authentication scoped to your app or user.`;
|
|
8
9
|
static args = {
|
|
9
10
|
path: Args.string({
|
|
10
11
|
description: 'API endpoint path (must start with /)',
|
|
@@ -16,12 +17,18 @@ export default class ApiGet extends SwellApiCommand {
|
|
|
16
17
|
description: 'Use live environment instead of test',
|
|
17
18
|
default: false,
|
|
18
19
|
}),
|
|
20
|
+
api: Flags.string({
|
|
21
|
+
description: 'Use frontend or backend API (frontend uses public key auth).',
|
|
22
|
+
options: ['backend', 'frontend'],
|
|
23
|
+
default: 'backend',
|
|
24
|
+
}),
|
|
19
25
|
};
|
|
20
26
|
static examples = [
|
|
21
27
|
'swell api get /products',
|
|
22
28
|
'swell api get "/products?limit=10&category=shoes"',
|
|
23
29
|
'swell api get /products/abc123',
|
|
24
30
|
'swell api get /functions/my-app/get-inventory',
|
|
31
|
+
'swell api get /products --api frontend',
|
|
25
32
|
];
|
|
26
33
|
get method() {
|
|
27
34
|
return HttpMethod.GET;
|
|
@@ -2,8 +2,9 @@ import { Command } from '@oclif/core';
|
|
|
2
2
|
export default class Api extends Command {
|
|
3
3
|
static summary = 'Send requests directly to the Swell Backend API.';
|
|
4
4
|
static description = `Run Swell API requests directly from the command line.
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Supports GET, POST, PUT, and DELETE methods with optional test/live environments.
|
|
6
|
+
Use --api frontend for public key authentication via the frontend API.
|
|
7
|
+
Call app functions via /functions/<app_id>/<function_name> paths.`;
|
|
7
8
|
static examples = [
|
|
8
9
|
'swell api get /products',
|
|
9
10
|
'swell api post /products --body \'{"name":"New product"}\'',
|
|
@@ -11,6 +12,7 @@ export default class Api extends Command {
|
|
|
11
12
|
'swell api delete /products/abc123',
|
|
12
13
|
'swell api get /functions/my-app/get-inventory',
|
|
13
14
|
'swell api post /functions/my-app/create-order --body \'{"items":["sku-1"]}\'',
|
|
15
|
+
'swell api get /products --api frontend',
|
|
14
16
|
];
|
|
15
17
|
async run() {
|
|
16
18
|
this.log('Use "swell api get|post|put|delete" to interact with the Swell API.');
|
|
@@ -9,6 +9,7 @@ export default class ApiPost extends SwellApiCommand {
|
|
|
9
9
|
static flags: {
|
|
10
10
|
body: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
11
|
live: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
12
|
+
api: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
static examples: string[];
|
|
14
15
|
get method(): HttpMethod;
|
|
@@ -3,8 +3,9 @@ import { HttpMethod } from '../../lib/api.js';
|
|
|
3
3
|
import { SwellApiCommand } from '../../swell-api-command.js';
|
|
4
4
|
export default class ApiPost extends SwellApiCommand {
|
|
5
5
|
static summary = 'Send a POST request to the Swell API.';
|
|
6
|
-
static description = `Create new resources in the Swell
|
|
7
|
-
|
|
6
|
+
static description = `Create new resources in the Swell API.
|
|
7
|
+
You can provide a JSON body directly or specify a file path containing JSON data.
|
|
8
|
+
Use --api frontend for public key authentication scoped to your app or user.`;
|
|
8
9
|
static args = {
|
|
9
10
|
path: Args.string({
|
|
10
11
|
description: 'API endpoint path (must start with /)',
|
|
@@ -19,11 +20,17 @@ export default class ApiPost extends SwellApiCommand {
|
|
|
19
20
|
description: 'Use live environment instead of test',
|
|
20
21
|
default: false,
|
|
21
22
|
}),
|
|
23
|
+
api: Flags.string({
|
|
24
|
+
description: 'Use frontend or backend API (frontend uses public key auth).',
|
|
25
|
+
options: ['backend', 'frontend'],
|
|
26
|
+
default: 'backend',
|
|
27
|
+
}),
|
|
22
28
|
};
|
|
23
29
|
static examples = [
|
|
24
30
|
'swell api post /products --body \'{"name": "Product", "price": 100}\'',
|
|
25
31
|
'swell api post /products --body ./product.json',
|
|
26
32
|
'swell api post /functions/my-app/create-order --body \'{"items":["sku-1"]}\'',
|
|
33
|
+
`swell api post /products --body '{"name": "Product"}' --api frontend`,
|
|
27
34
|
];
|
|
28
35
|
get method() {
|
|
29
36
|
return HttpMethod.POST;
|
|
@@ -9,6 +9,7 @@ export default class ApiPut extends SwellApiCommand {
|
|
|
9
9
|
static flags: {
|
|
10
10
|
body: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
11
11
|
live: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
12
|
+
api: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
static examples: string[];
|
|
14
15
|
get method(): HttpMethod;
|
package/dist/commands/api/put.js
CHANGED
|
@@ -3,8 +3,9 @@ import { HttpMethod } from '../../lib/api.js';
|
|
|
3
3
|
import { SwellApiCommand } from '../../swell-api-command.js';
|
|
4
4
|
export default class ApiPut extends SwellApiCommand {
|
|
5
5
|
static summary = 'Send a PUT request to the Swell API.';
|
|
6
|
-
static description = `Update existing resources in the Swell
|
|
7
|
-
|
|
6
|
+
static description = `Update existing resources in the Swell API.
|
|
7
|
+
You can provide a JSON body directly or specify a file path containing JSON data.
|
|
8
|
+
Use --api frontend for public key authentication scoped to your app or user.`;
|
|
8
9
|
static args = {
|
|
9
10
|
path: Args.string({
|
|
10
11
|
description: 'API endpoint path (must start with /)',
|
|
@@ -19,11 +20,17 @@ export default class ApiPut extends SwellApiCommand {
|
|
|
19
20
|
description: 'Use live environment instead of test',
|
|
20
21
|
default: false,
|
|
21
22
|
}),
|
|
23
|
+
api: Flags.string({
|
|
24
|
+
description: 'Use frontend or backend API (frontend uses public key auth).',
|
|
25
|
+
options: ['backend', 'frontend'],
|
|
26
|
+
default: 'backend',
|
|
27
|
+
}),
|
|
22
28
|
};
|
|
23
29
|
static examples = [
|
|
24
30
|
'swell api put /products/{id} --body \'{"id": "abc123", "name": "Updated"}\'',
|
|
25
31
|
'swell api put /products/abc123 --body ./product.json',
|
|
26
32
|
'swell api put /functions/my-app/update-stock --body \'{"sku":"abc","qty":10}\'',
|
|
33
|
+
`swell api put /products/abc123 --body '{"name": "Updated"}' --api frontend`,
|
|
27
34
|
];
|
|
28
35
|
get method() {
|
|
29
36
|
return HttpMethod.PUT;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
|
-
import { getProjectCommands, } from '../../../lib/apps/index.js';
|
|
2
|
+
import { CUSTOM_FRAMEWORK_SLUG, getManualDevHint, getProjectCommands, } from '../../../lib/apps/index.js';
|
|
3
3
|
import { default as localConfig } from '../../../lib/config.js';
|
|
4
4
|
import style from '../../../lib/style.js';
|
|
5
5
|
import { PushAppCommand } from '../../../push-app-command.js';
|
|
@@ -70,6 +70,23 @@ export default class AppFrontendDev extends PushAppCommand {
|
|
|
70
70
|
if (!projectType) {
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
+
// Manual mode for unrecognized frameworks
|
|
74
|
+
if (projectType.slug === CUSTOM_FRAMEWORK_SLUG) {
|
|
75
|
+
const hintCommand = getManualDevHint(this.appPath, serverPort);
|
|
76
|
+
const currentStore = localConfig.getDefaultStore();
|
|
77
|
+
const sessionId = localConfig.getSessionId(currentStore);
|
|
78
|
+
this.log(`Detected a frontend project but could not identify the framework.`);
|
|
79
|
+
this.log(`Start your dev server manually on port ${serverPort}:\n`);
|
|
80
|
+
this.log(` cd frontend && ${hintCommand}\n`);
|
|
81
|
+
this.log(`The Swell tunnel is ready and will route traffic once your server is running.\n`);
|
|
82
|
+
this.logAppLocalUrl(currentStore, sessionId);
|
|
83
|
+
if (!isAppDev) {
|
|
84
|
+
this.watchForChanges();
|
|
85
|
+
}
|
|
86
|
+
// Keep the process alive so the tunnel remains open
|
|
87
|
+
await new Promise(() => { });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
73
90
|
// Get commands transformed for the detected package manager
|
|
74
91
|
const { devCommand } = getProjectCommands(this.appPath, projectType);
|
|
75
92
|
const currentStore = localConfig.getDefaultStore();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import * as fs from 'node:fs';
|
|
3
2
|
import { FetchError } from 'node-fetch';
|
|
3
|
+
import { getCurrentAppSlugId } from '../../lib/apps/index.js';
|
|
4
4
|
import { default as localConfig } from '../../lib/config.js';
|
|
5
5
|
import { SwellCommand } from '../../swell-command.js';
|
|
6
6
|
export default class Models extends SwellCommand {
|
|
@@ -109,7 +109,7 @@ With a collection path, it retrieves the model for that specific collection in J
|
|
|
109
109
|
this.showModels(models, 'Standard');
|
|
110
110
|
}
|
|
111
111
|
async showAppModels(appsById, modelsByAppId) {
|
|
112
|
-
const currentAppSlugId = await
|
|
112
|
+
const currentAppSlugId = await getCurrentAppSlugId();
|
|
113
113
|
for (const [appId, app] of Object.entries(appsById)) {
|
|
114
114
|
const models = modelsByAppId[appId];
|
|
115
115
|
if (models) {
|
|
@@ -153,19 +153,6 @@ With a collection path, it retrieves the model for that specific collection in J
|
|
|
153
153
|
}
|
|
154
154
|
return `/${model.name}`;
|
|
155
155
|
}
|
|
156
|
-
async getCurrentAppSlugId() {
|
|
157
|
-
const hasAppContext = fs.existsSync('swell.json');
|
|
158
|
-
if (!hasAppContext) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
const appConfig = JSON.parse(await fs.promises.readFile('swell.json', 'utf8'));
|
|
163
|
-
return appConfig.id;
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
// noop
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
156
|
getAppSlugId(app) {
|
|
170
157
|
return app.public_id || app.private_id.replace(/^_/, '');
|
|
171
158
|
}
|
|
@@ -429,7 +429,7 @@ export class CreateAppCommand extends SwellCommand {
|
|
|
429
429
|
// Required for yarn workspaces, good practice for all package managers
|
|
430
430
|
private: true,
|
|
431
431
|
scripts: {
|
|
432
|
-
typecheck: '([ -z "$(find functions -name \'*.ts\' 2>/dev/null | head -1)" ] || tsc --noEmit) && ([ ! -f test/tsconfig.json ] || tsc --noEmit
|
|
432
|
+
typecheck: '([ -z "$(find functions -name \'*.ts\' 2>/dev/null | head -1)" ] || tsc --noEmit) && ([ ! -f test/tsconfig.json ] || tsc --build --noEmit test) && ([ ! -f frontend/tsconfig.json ] || tsc --build --noEmit frontend)',
|
|
433
433
|
},
|
|
434
434
|
version: config.get('version'),
|
|
435
435
|
};
|
package/dist/env/local.d.ts
CHANGED
package/dist/env/local.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
API_BASE_URL: 'https://localapi.schema.io:4443',
|
|
3
3
|
ADMIN_API_BASE_URL: 'http://${STORE_ID}.swell.test:4001/admin/api',
|
|
4
|
+
FRONTEND_API_BASE_URL: 'http://${STORE_ID}.swell.test:4001/api',
|
|
4
5
|
LOGIN_HOST: 'http://${STORE_ID}.swell.test:3000',
|
|
5
6
|
APP_PAGES_HOST: 'http://${STORE_ID}--${APP_ID}--${ENV}.swell.test:4001',
|
|
6
7
|
STOREFRONT_FRONTEND_HOST: 'http://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.test:4001',
|
package/dist/env/production.d.ts
CHANGED
package/dist/env/production.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
API_BASE_URL: 'https://api.swell.store',
|
|
3
3
|
ADMIN_API_BASE_URL: 'https://${STORE_ID}.swell.store/admin/api',
|
|
4
|
+
FRONTEND_API_BASE_URL: 'https://${STORE_ID}.swell.store/api',
|
|
4
5
|
LOGIN_HOST: 'https://${STORE_ID}.swell.store',
|
|
5
6
|
APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.swell.store',
|
|
6
7
|
STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.swell.store',
|
package/dist/env/review.d.ts
CHANGED
package/dist/env/review.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
API_BASE_URL: 'https://${REVIEW_DOMAIN}.rav2.swell.store',
|
|
3
3
|
ADMIN_API_BASE_URL: 'https://${STORE_ID}.${REVIEW_DOMAIN}.rav2.swell.store/admin/api',
|
|
4
|
+
FRONTEND_API_BASE_URL: 'https://${STORE_ID}.${REVIEW_DOMAIN}.rav2.swell.store/api',
|
|
4
5
|
LOGIN_HOST: 'https://${REVIEW_DOMAIN}.rav2.swell.store',
|
|
5
6
|
APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.${REVIEW_DOMAIN}.rav2.swell.store',
|
|
6
7
|
STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.${REVIEW_DOMAIN}.rav2.swell.store',
|
package/dist/env/staging.d.ts
CHANGED
package/dist/env/staging.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
API_BASE_URL: 'https://staging.swell.store',
|
|
3
3
|
ADMIN_API_BASE_URL: 'https://${STORE_ID}.staging.swell.store/admin/api',
|
|
4
|
+
FRONTEND_API_BASE_URL: 'https://${STORE_ID}.staging.swell.store/api',
|
|
4
5
|
LOGIN_HOST: 'https://staging.swell.store',
|
|
5
6
|
APP_PAGES_HOST: 'https://${STORE_ID}--${APP_ID}--${ENV}.staging.swell.store',
|
|
6
7
|
STOREFRONT_FRONTEND_HOST: 'https://${BRANCH_PREFIX}${STOREFRONT_SLUG}.staging.swell.store',
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -5,10 +5,11 @@ export declare enum HttpMethod {
|
|
|
5
5
|
DELETE = "delete"
|
|
6
6
|
}
|
|
7
7
|
export default class Api {
|
|
8
|
+
storeId: string | undefined;
|
|
8
9
|
envId: string | undefined;
|
|
9
10
|
secretKey: string | undefined;
|
|
10
|
-
|
|
11
|
-
constructor(storeId?: string, envId?: string, secretKey?: string);
|
|
11
|
+
publicKey: string | undefined;
|
|
12
|
+
constructor(storeId?: string, envId?: string, publicKey?: string, secretKey?: string);
|
|
12
13
|
api(pathOpts: Api.Paths, options: Api.RequestOptions): Promise<any>;
|
|
13
14
|
get(pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<any>;
|
|
14
15
|
getAll(pathOpts: Api.Paths, options?: Api.RequestOptions): Promise<{
|
|
@@ -21,6 +22,8 @@ export default class Api {
|
|
|
21
22
|
isTestEnvEnabled(): Promise<boolean>;
|
|
22
23
|
setEnv(envId: string): Promise<void>;
|
|
23
24
|
setStoreEnv(storeId: string, envId?: string): Promise<void>;
|
|
25
|
+
setPublicKey(publicKey?: string): Promise<void>;
|
|
26
|
+
private isFrontend;
|
|
24
27
|
private isAdmin;
|
|
25
28
|
private truncatePath;
|
|
26
29
|
private waitForAsyncResponse;
|
package/dist/lib/api.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import fetch from 'node-fetch';
|
|
2
2
|
import { stringify } from 'qs';
|
|
3
|
+
import { getCurrentAppSlugId, hasAppContext } from './apps/index.js';
|
|
3
4
|
import config from './config.js';
|
|
4
|
-
import { API_BASE_URL, getAdminApiBaseUrl } from './constants.js';
|
|
5
|
+
import { API_BASE_URL, getAdminApiBaseUrl, getFrontendApiBaseUrl, } from './constants.js';
|
|
6
|
+
import style from './style.js';
|
|
5
7
|
export var HttpMethod;
|
|
6
8
|
(function (HttpMethod) {
|
|
7
9
|
HttpMethod["GET"] = "get";
|
|
@@ -15,7 +17,7 @@ const defaultHeaders = (opts) => ({
|
|
|
15
17
|
...opts,
|
|
16
18
|
});
|
|
17
19
|
const authenticatedHeaders = (storeId, opts = {}) => {
|
|
18
|
-
let { secretKey, sessionId, ...moreOpts } = opts;
|
|
20
|
+
let { publicKey, secretKey, sessionId, ...moreOpts } = opts;
|
|
19
21
|
sessionId ??= config.getSessionId(storeId);
|
|
20
22
|
if (secretKey) {
|
|
21
23
|
return defaultHeaders({
|
|
@@ -23,6 +25,12 @@ const authenticatedHeaders = (storeId, opts = {}) => {
|
|
|
23
25
|
...moreOpts,
|
|
24
26
|
});
|
|
25
27
|
}
|
|
28
|
+
if (publicKey) {
|
|
29
|
+
return defaultHeaders({
|
|
30
|
+
Authorization: `Basic ${Buffer.from(publicKey).toString('base64')}`,
|
|
31
|
+
...moreOpts,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
26
34
|
if (sessionId) {
|
|
27
35
|
return defaultHeaders({
|
|
28
36
|
'X-Session': sessionId,
|
|
@@ -32,12 +40,14 @@ const authenticatedHeaders = (storeId, opts = {}) => {
|
|
|
32
40
|
return defaultHeaders(moreOpts);
|
|
33
41
|
};
|
|
34
42
|
export default class Api {
|
|
43
|
+
storeId;
|
|
35
44
|
envId;
|
|
36
45
|
secretKey;
|
|
37
|
-
|
|
38
|
-
constructor(storeId, envId, secretKey) {
|
|
46
|
+
publicKey;
|
|
47
|
+
constructor(storeId, envId, publicKey, secretKey) {
|
|
39
48
|
this.storeId = storeId;
|
|
40
49
|
this.envId = envId;
|
|
50
|
+
this.publicKey = publicKey;
|
|
41
51
|
this.secretKey = secretKey;
|
|
42
52
|
}
|
|
43
53
|
async api(pathOpts, options) {
|
|
@@ -50,14 +60,17 @@ export default class Api {
|
|
|
50
60
|
...options?.headers,
|
|
51
61
|
...(this.envId ? { 'Swell-Env': this.envId } : undefined),
|
|
52
62
|
...authenticatedHeaders(storeId, {
|
|
63
|
+
publicKey: this.publicKey,
|
|
53
64
|
secretKey: this.secretKey,
|
|
54
65
|
sessionId: options.sessionId,
|
|
55
66
|
}),
|
|
56
67
|
},
|
|
57
68
|
};
|
|
58
|
-
path = this.
|
|
59
|
-
? `${
|
|
60
|
-
:
|
|
69
|
+
path = this.isFrontend(pathOpts)
|
|
70
|
+
? `${getFrontendApiBaseUrl(storeId)}/${this.truncatePath(pathOpts.frontendPath)}`
|
|
71
|
+
: this.isAdmin(pathOpts)
|
|
72
|
+
? `${getAdminApiBaseUrl(storeId)}/${this.truncatePath(pathOpts.adminPath)}`
|
|
73
|
+
: `${API_BASE_URL}/${this.truncatePath(pathOpts.backendPath)}`;
|
|
61
74
|
if (options.query) {
|
|
62
75
|
path += `?${stringify(options.query)}`;
|
|
63
76
|
}
|
|
@@ -179,8 +192,46 @@ export default class Api {
|
|
|
179
192
|
this.storeId = storeId;
|
|
180
193
|
this.envId = envId;
|
|
181
194
|
}
|
|
182
|
-
|
|
183
|
-
|
|
195
|
+
async setPublicKey(publicKey) {
|
|
196
|
+
if (publicKey) {
|
|
197
|
+
this.publicKey = publicKey;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const appSlugId = await getCurrentAppSlugId();
|
|
201
|
+
const response = await this.post({ adminPath: '/data/:batch' }, {
|
|
202
|
+
query: [
|
|
203
|
+
{
|
|
204
|
+
method: 'get',
|
|
205
|
+
url: '/:clients/:self/keys/:last',
|
|
206
|
+
data: {
|
|
207
|
+
scope: 'user',
|
|
208
|
+
public: { $exists: true },
|
|
209
|
+
revoked: { $ne: true },
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
appSlugId && {
|
|
213
|
+
method: 'get',
|
|
214
|
+
url: '/:clients/:self/apps/:last',
|
|
215
|
+
data: {
|
|
216
|
+
app_private_id: `_${appSlugId}`,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
});
|
|
221
|
+
const [userKey, installedApp] = Object.values(response);
|
|
222
|
+
this.publicKey = installedApp?.public_key || userKey?.public;
|
|
223
|
+
if (!this.publicKey) {
|
|
224
|
+
throw new Error('No API public key available. Run inside a deployed app or create a user-scoped public key.');
|
|
225
|
+
}
|
|
226
|
+
else if (hasAppContext() && !installedApp?.public_key) {
|
|
227
|
+
console.warn(style.funcWarn('⚠ No app context found. Running in user scope.'));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
isFrontend(pathOpts) {
|
|
231
|
+
return Boolean(pathOpts.frontendPath) && Boolean(this.publicKey);
|
|
232
|
+
}
|
|
233
|
+
isAdmin(pathOpts) {
|
|
234
|
+
return Boolean(pathOpts.adminPath) && !this.secretKey;
|
|
184
235
|
}
|
|
185
236
|
truncatePath(path) {
|
|
186
237
|
return path?.startsWith('/') ? path.slice(1) : path;
|
package/dist/lib/apps/index.d.ts
CHANGED
|
@@ -126,6 +126,7 @@ export interface FrontendProjectType {
|
|
|
126
126
|
name: string;
|
|
127
127
|
slug: string;
|
|
128
128
|
}
|
|
129
|
+
export declare const CUSTOM_FRAMEWORK_SLUG = "custom";
|
|
129
130
|
export declare const FrontendProjectTypes: FrontendProjectType[];
|
|
130
131
|
export declare function getFrontendProjectSlugs(withNone?: boolean, withLegacy?: boolean): string[];
|
|
131
132
|
export declare function getFrontendProjectValidValues(withNone?: boolean, withLegacy?: boolean): string;
|
|
@@ -140,6 +141,11 @@ export declare function getProjectCommands(appPath: string, projectType: Fronten
|
|
|
140
141
|
buildCommand?: string;
|
|
141
142
|
devCommand: string;
|
|
142
143
|
};
|
|
144
|
+
/**
|
|
145
|
+
* Get a suggested dev command for an unrecognized frontend project,
|
|
146
|
+
* translated for the detected package manager.
|
|
147
|
+
*/
|
|
148
|
+
export declare function getManualDevHint(appPath: string, port: number): string;
|
|
143
149
|
export declare function getConfigTypeFromPath(path: string): ConfigType | undefined;
|
|
144
150
|
export declare function getConfigTypeKeyFromValue(value: string): string | undefined;
|
|
145
151
|
export declare function filePathExists(filePath: string): boolean;
|
|
@@ -165,3 +171,5 @@ interface BatchAppFiles {
|
|
|
165
171
|
* @returns {BatchAppFiles[]} Batches of files to push
|
|
166
172
|
*/
|
|
167
173
|
export declare function batchAppFilesByType(configs: AppConfig[]): BatchAppFiles[];
|
|
174
|
+
export declare function hasAppContext(): boolean;
|
|
175
|
+
export declare function getCurrentAppSlugId(): Promise<string | undefined>;
|
package/dist/lib/apps/index.js
CHANGED
|
@@ -114,6 +114,8 @@ export var ConfigInputFields;
|
|
|
114
114
|
ConfigInputFields["VALUES"] = "values";
|
|
115
115
|
ConfigInputFields["VERSION"] = "version";
|
|
116
116
|
})(ConfigInputFields || (ConfigInputFields = {}));
|
|
117
|
+
// Slug for unrecognized frontend frameworks (manual dev server mode)
|
|
118
|
+
export const CUSTOM_FRAMEWORK_SLUG = 'custom';
|
|
117
119
|
// Frontend project types - all use direct commands run from frontend/ directory
|
|
118
120
|
export const FrontendProjectTypes = [
|
|
119
121
|
{
|
|
@@ -198,6 +200,16 @@ export function getFrontendProjectType(appPath) {
|
|
|
198
200
|
return detectedType;
|
|
199
201
|
}
|
|
200
202
|
}
|
|
203
|
+
// Fallback: if package.json has a dev script, treat as unrecognized framework
|
|
204
|
+
if (pkg.scripts?.dev) {
|
|
205
|
+
return {
|
|
206
|
+
buildCommand: pkg.scripts?.build ? 'npm run build' : '',
|
|
207
|
+
devCommand: '',
|
|
208
|
+
mainPackage: '',
|
|
209
|
+
name: 'Custom',
|
|
210
|
+
slug: CUSTOM_FRAMEWORK_SLUG,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
201
213
|
}
|
|
202
214
|
catch {
|
|
203
215
|
// Ignore JSON parse errors, try next path
|
|
@@ -220,6 +232,14 @@ export function getProjectCommands(appPath, projectType) {
|
|
|
220
232
|
devCommand: transformCommand(projectType.devCommand, pm),
|
|
221
233
|
};
|
|
222
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Get a suggested dev command for an unrecognized frontend project,
|
|
237
|
+
* translated for the detected package manager.
|
|
238
|
+
*/
|
|
239
|
+
export function getManualDevHint(appPath, port) {
|
|
240
|
+
const pm = detectPackageManager(appPath);
|
|
241
|
+
return transformCommand(`npm run dev -- --port ${port}`, pm);
|
|
242
|
+
}
|
|
223
243
|
export function getConfigTypeFromPath(path) {
|
|
224
244
|
for (const type in AllConfigPaths) {
|
|
225
245
|
if (AllConfigPaths[type] === path) {
|
|
@@ -361,3 +381,18 @@ export function batchAppFilesByType(configs) {
|
|
|
361
381
|
// Add base files if config types are not specified
|
|
362
382
|
return batches;
|
|
363
383
|
}
|
|
384
|
+
export function hasAppContext() {
|
|
385
|
+
return fs.existsSync('swell.json');
|
|
386
|
+
}
|
|
387
|
+
export async function getCurrentAppSlugId() {
|
|
388
|
+
if (!hasAppContext()) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
const appConfig = JSON.parse(await fs.promises.readFile('swell.json', 'utf8'));
|
|
393
|
+
return appConfig.id;
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
// noop
|
|
397
|
+
}
|
|
398
|
+
}
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export declare const API_BASE_URL: any;
|
|
|
2
2
|
export declare const LOCAL_PROXY_PROVIDER: any;
|
|
3
3
|
export declare const SCHEMAS_BASE_URL: any;
|
|
4
4
|
export declare function getAdminApiBaseUrl(storeId: string): any;
|
|
5
|
+
export declare function getFrontendApiBaseUrl(storeId: string): any;
|
|
5
6
|
export declare function getLoginHost(storeId?: string): any;
|
|
6
7
|
export declare function getAppFrontendHost(storeId: string, installedAppId: string): any;
|
|
7
8
|
export declare function getStorefrontFrontendHost(storefrontSlug: string, branchId?: string): any;
|
package/dist/lib/constants.js
CHANGED
|
@@ -5,6 +5,8 @@ import { env } from './config.js';
|
|
|
5
5
|
export const API_BASE_URL = env.get('API_BASE_URL') || defaultEnv.API_BASE_URL;
|
|
6
6
|
// url for admin api calls
|
|
7
7
|
const ADMIN_API_BASE_URL = env.get('ADMIN_API_BASE_URL') || defaultEnv.ADMIN_API_BASE_URL;
|
|
8
|
+
// url for store api calls
|
|
9
|
+
const FRONTEND_API_BASE_URL = env.get('FRONTEND_API_BASE_URL') || defaultEnv.FRONTEND_API_BASE_URL;
|
|
8
10
|
// url host for admin login
|
|
9
11
|
const LOGIN_HOST = env.get('LOGIN_HOST') || defaultEnv.LOGIN_HOST;
|
|
10
12
|
// url host for app frontend
|
|
@@ -19,6 +21,9 @@ export const SCHEMAS_BASE_URL = env.get('SCHEMAS_BASE_URL') || defaultEnv.SCHEMA
|
|
|
19
21
|
export function getAdminApiBaseUrl(storeId) {
|
|
20
22
|
return ADMIN_API_BASE_URL.replace('${STORE_ID}', storeId);
|
|
21
23
|
}
|
|
24
|
+
export function getFrontendApiBaseUrl(storeId) {
|
|
25
|
+
return FRONTEND_API_BASE_URL.replace('${STORE_ID}', storeId);
|
|
26
|
+
}
|
|
22
27
|
export function getLoginHost(storeId) {
|
|
23
28
|
return LOGIN_HOST.replace('${STORE_ID}', storeId || 'login');
|
|
24
29
|
}
|
package/dist/push-app-command.js
CHANGED
|
@@ -6,7 +6,7 @@ import * as path from 'node:path';
|
|
|
6
6
|
import Stream from 'node:stream';
|
|
7
7
|
import ora from 'ora';
|
|
8
8
|
import { default as swellConfig } from './lib/app-config.js';
|
|
9
|
-
import { ConfigType, getFrontendProjectValidValues, allConfigFilesInDir, appConfigFromFile, filePathExists, filePathExistsAsync, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, getProjectCommands, globAllFilesByPath, hashString, isPathDirectory, } from './lib/apps/index.js';
|
|
9
|
+
import { ConfigType, getFrontendProjectValidValues, allConfigFilesInDir, CUSTOM_FRAMEWORK_SLUG, appConfigFromFile, filePathExists, filePathExistsAsync, findAppConfig, getAppSlugId, getConfigTypeFromPath, getConfigTypeKeyFromValue, getFrontendProjectType, getProjectCommands, globAllFilesByPath, hashString, isPathDirectory, } from './lib/apps/index.js';
|
|
10
10
|
import { getGlobIgnorePathsChecker } from './lib/apps/paths.js';
|
|
11
11
|
import { default as localConfig } from './lib/config.js';
|
|
12
12
|
import { toAppId } from './lib/create/index.js';
|
|
@@ -110,6 +110,14 @@ export class PushAppCommand extends RemoteAppCommand {
|
|
|
110
110
|
this.showFrontendMigrationError();
|
|
111
111
|
return; // unreachable but helps TypeScript narrow the type
|
|
112
112
|
}
|
|
113
|
+
// Skip automatic build for unrecognized frameworks
|
|
114
|
+
if (projectType.slug === CUSTOM_FRAMEWORK_SLUG) {
|
|
115
|
+
if (projectType.buildCommand) {
|
|
116
|
+
this.log(`Skipping automatic frontend build for unrecognized framework.\n` +
|
|
117
|
+
`Run your build command manually before deploying.\n`);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
113
121
|
// Get commands transformed for the detected package manager
|
|
114
122
|
const { buildCommand } = getProjectCommands(this.appPath, projectType);
|
|
115
123
|
if (!buildCommand) {
|
|
@@ -758,7 +766,9 @@ export class PushAppCommand extends RemoteAppCommand {
|
|
|
758
766
|
$environment_id: 'test',
|
|
759
767
|
frontend: {
|
|
760
768
|
deployment_hash: deploymentHash,
|
|
761
|
-
|
|
769
|
+
...(projectType.slug !== CUSTOM_FRAMEWORK_SLUG && {
|
|
770
|
+
framework: projectType.slug,
|
|
771
|
+
}),
|
|
762
772
|
service: 'cloudflare',
|
|
763
773
|
url: deploymentUrl,
|
|
764
774
|
},
|
|
@@ -29,10 +29,14 @@ export class SwellApiCommand extends SwellCommand {
|
|
|
29
29
|
const parsedInput = await super.parse(options, argv);
|
|
30
30
|
const { args, flags } = parsedInput;
|
|
31
31
|
const { path: requestPath } = args;
|
|
32
|
-
const { live, body } = flags;
|
|
32
|
+
const { live, api, body } = flags;
|
|
33
|
+
const isFrontendAPI = api === 'frontend';
|
|
33
34
|
if (!live) {
|
|
34
35
|
await this.api.setEnv('test');
|
|
35
36
|
}
|
|
37
|
+
if (isFrontendAPI) {
|
|
38
|
+
await this.api.setPublicKey();
|
|
39
|
+
}
|
|
36
40
|
if (!requestPath.startsWith('/')) {
|
|
37
41
|
throw new Error('Path must start with a forward slash (/)');
|
|
38
42
|
}
|
|
@@ -53,7 +57,9 @@ export class SwellApiCommand extends SwellCommand {
|
|
|
53
57
|
const queryParams = this.parseQueryString(queryString);
|
|
54
58
|
return this.buildFunctionCallRequest(parsedInput, functionId, processedBody, queryParams);
|
|
55
59
|
}
|
|
56
|
-
const paths =
|
|
60
|
+
const paths = isFrontendAPI
|
|
61
|
+
? { frontendPath: requestPath }
|
|
62
|
+
: { adminPath: `/data${requestPath}` };
|
|
57
63
|
return {
|
|
58
64
|
...parsedInput,
|
|
59
65
|
paths,
|
package/oclif.manifest.json
CHANGED
|
@@ -381,10 +381,11 @@
|
|
|
381
381
|
"required": true
|
|
382
382
|
}
|
|
383
383
|
},
|
|
384
|
-
"description": "Remove existing resources from the Swell
|
|
384
|
+
"description": "Remove existing resources from the Swell API.\n Use --api frontend for public key authentication scoped to your app or user.",
|
|
385
385
|
"examples": [
|
|
386
386
|
"swell api delete /products/abc123",
|
|
387
|
-
"swell api delete /functions/my-app/clear-cache"
|
|
387
|
+
"swell api delete /functions/my-app/clear-cache",
|
|
388
|
+
"swell api delete /products/abc123 --api frontend"
|
|
388
389
|
],
|
|
389
390
|
"flags": {
|
|
390
391
|
"live": {
|
|
@@ -392,6 +393,18 @@
|
|
|
392
393
|
"name": "live",
|
|
393
394
|
"allowNo": false,
|
|
394
395
|
"type": "boolean"
|
|
396
|
+
},
|
|
397
|
+
"api": {
|
|
398
|
+
"description": "Use frontend or backend API (frontend uses public key auth).",
|
|
399
|
+
"name": "api",
|
|
400
|
+
"default": "backend",
|
|
401
|
+
"hasDynamicHelp": false,
|
|
402
|
+
"multiple": false,
|
|
403
|
+
"options": [
|
|
404
|
+
"backend",
|
|
405
|
+
"frontend"
|
|
406
|
+
],
|
|
407
|
+
"type": "option"
|
|
395
408
|
}
|
|
396
409
|
},
|
|
397
410
|
"hasDynamicHelp": false,
|
|
@@ -419,12 +432,13 @@
|
|
|
419
432
|
"required": true
|
|
420
433
|
}
|
|
421
434
|
},
|
|
422
|
-
"description": "Retrieve data from the Swell
|
|
435
|
+
"description": "Retrieve data from the Swell API.\n The command performs a GET request to the specified endpoint path.\n Use --api frontend for public key authentication scoped to your app or user.",
|
|
423
436
|
"examples": [
|
|
424
437
|
"swell api get /products",
|
|
425
438
|
"swell api get \"/products?limit=10&category=shoes\"",
|
|
426
439
|
"swell api get /products/abc123",
|
|
427
|
-
"swell api get /functions/my-app/get-inventory"
|
|
440
|
+
"swell api get /functions/my-app/get-inventory",
|
|
441
|
+
"swell api get /products --api frontend"
|
|
428
442
|
],
|
|
429
443
|
"flags": {
|
|
430
444
|
"live": {
|
|
@@ -432,6 +446,18 @@
|
|
|
432
446
|
"name": "live",
|
|
433
447
|
"allowNo": false,
|
|
434
448
|
"type": "boolean"
|
|
449
|
+
},
|
|
450
|
+
"api": {
|
|
451
|
+
"description": "Use frontend or backend API (frontend uses public key auth).",
|
|
452
|
+
"name": "api",
|
|
453
|
+
"default": "backend",
|
|
454
|
+
"hasDynamicHelp": false,
|
|
455
|
+
"multiple": false,
|
|
456
|
+
"options": [
|
|
457
|
+
"backend",
|
|
458
|
+
"frontend"
|
|
459
|
+
],
|
|
460
|
+
"type": "option"
|
|
435
461
|
}
|
|
436
462
|
},
|
|
437
463
|
"hasDynamicHelp": false,
|
|
@@ -453,14 +479,15 @@
|
|
|
453
479
|
"api": {
|
|
454
480
|
"aliases": [],
|
|
455
481
|
"args": {},
|
|
456
|
-
"description": "Run Swell API requests directly from the command line.\n
|
|
482
|
+
"description": "Run Swell API requests directly from the command line.\n Supports GET, POST, PUT, and DELETE methods with optional test/live environments.\n Use --api frontend for public key authentication via the frontend API.\n Call app functions via /functions/<app_id>/<function_name> paths.",
|
|
457
483
|
"examples": [
|
|
458
484
|
"swell api get /products",
|
|
459
485
|
"swell api post /products --body '{\"name\":\"New product\"}'",
|
|
460
486
|
"swell api put /products/abc123 --body ./update.json",
|
|
461
487
|
"swell api delete /products/abc123",
|
|
462
488
|
"swell api get /functions/my-app/get-inventory",
|
|
463
|
-
"swell api post /functions/my-app/create-order --body '{\"items\":[\"sku-1\"]}'"
|
|
489
|
+
"swell api post /functions/my-app/create-order --body '{\"items\":[\"sku-1\"]}'",
|
|
490
|
+
"swell api get /products --api frontend"
|
|
464
491
|
],
|
|
465
492
|
"flags": {},
|
|
466
493
|
"hasDynamicHelp": false,
|
|
@@ -489,11 +516,12 @@
|
|
|
489
516
|
"required": true
|
|
490
517
|
}
|
|
491
518
|
},
|
|
492
|
-
"description": "Create new resources in the Swell
|
|
519
|
+
"description": "Create new resources in the Swell API.\n You can provide a JSON body directly or specify a file path containing JSON data.\n Use --api frontend for public key authentication scoped to your app or user.",
|
|
493
520
|
"examples": [
|
|
494
521
|
"swell api post /products --body '{\"name\": \"Product\", \"price\": 100}'",
|
|
495
522
|
"swell api post /products --body ./product.json",
|
|
496
|
-
"swell api post /functions/my-app/create-order --body '{\"items\":[\"sku-1\"]}'"
|
|
523
|
+
"swell api post /functions/my-app/create-order --body '{\"items\":[\"sku-1\"]}'",
|
|
524
|
+
"swell api post /products --body '{\"name\": \"Product\"}' --api frontend"
|
|
497
525
|
],
|
|
498
526
|
"flags": {
|
|
499
527
|
"body": {
|
|
@@ -508,6 +536,18 @@
|
|
|
508
536
|
"name": "live",
|
|
509
537
|
"allowNo": false,
|
|
510
538
|
"type": "boolean"
|
|
539
|
+
},
|
|
540
|
+
"api": {
|
|
541
|
+
"description": "Use frontend or backend API (frontend uses public key auth).",
|
|
542
|
+
"name": "api",
|
|
543
|
+
"default": "backend",
|
|
544
|
+
"hasDynamicHelp": false,
|
|
545
|
+
"multiple": false,
|
|
546
|
+
"options": [
|
|
547
|
+
"backend",
|
|
548
|
+
"frontend"
|
|
549
|
+
],
|
|
550
|
+
"type": "option"
|
|
511
551
|
}
|
|
512
552
|
},
|
|
513
553
|
"hasDynamicHelp": false,
|
|
@@ -535,11 +575,12 @@
|
|
|
535
575
|
"required": true
|
|
536
576
|
}
|
|
537
577
|
},
|
|
538
|
-
"description": "Update existing resources in the Swell
|
|
578
|
+
"description": "Update existing resources in the Swell API.\n You can provide a JSON body directly or specify a file path containing JSON data.\n Use --api frontend for public key authentication scoped to your app or user.",
|
|
539
579
|
"examples": [
|
|
540
580
|
"swell api put /products/{id} --body '{\"id\": \"abc123\", \"name\": \"Updated\"}'",
|
|
541
581
|
"swell api put /products/abc123 --body ./product.json",
|
|
542
|
-
"swell api put /functions/my-app/update-stock --body '{\"sku\":\"abc\",\"qty\":10}'"
|
|
582
|
+
"swell api put /functions/my-app/update-stock --body '{\"sku\":\"abc\",\"qty\":10}'",
|
|
583
|
+
"swell api put /products/abc123 --body '{\"name\": \"Updated\"}' --api frontend"
|
|
543
584
|
],
|
|
544
585
|
"flags": {
|
|
545
586
|
"body": {
|
|
@@ -554,6 +595,18 @@
|
|
|
554
595
|
"name": "live",
|
|
555
596
|
"allowNo": false,
|
|
556
597
|
"type": "boolean"
|
|
598
|
+
},
|
|
599
|
+
"api": {
|
|
600
|
+
"description": "Use frontend or backend API (frontend uses public key auth).",
|
|
601
|
+
"name": "api",
|
|
602
|
+
"default": "backend",
|
|
603
|
+
"hasDynamicHelp": false,
|
|
604
|
+
"multiple": false,
|
|
605
|
+
"options": [
|
|
606
|
+
"backend",
|
|
607
|
+
"frontend"
|
|
608
|
+
],
|
|
609
|
+
"type": "option"
|
|
557
610
|
}
|
|
558
611
|
},
|
|
559
612
|
"hasDynamicHelp": false,
|
|
@@ -2884,5 +2937,5 @@
|
|
|
2884
2937
|
]
|
|
2885
2938
|
}
|
|
2886
2939
|
},
|
|
2887
|
-
"version": "2.
|
|
2940
|
+
"version": "2.5.0"
|
|
2888
2941
|
}
|