@salesforce/plugin-api 1.2.2 → 1.3.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/README.md +53 -11
- package/lib/commands/api/request/rest.d.ts +41 -2
- package/lib/commands/api/request/rest.js +95 -20
- package/lib/commands/api/request/rest.js.map +1 -1
- package/lib/shared/shared.d.ts +0 -2
- package/lib/shared/shared.js +0 -14
- package/lib/shared/shared.js.map +1 -1
- package/messages/rest.md +38 -1
- package/oclif.manifest.json +18 -7
- package/package.json +4 -5
- package/npm-shrinkwrap.json +0 -13362
- package/oclif.lock +0 -7529
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ sf plugins
|
|
|
60
60
|
<!-- commands -->
|
|
61
61
|
|
|
62
62
|
- [`sf api request graphql`](#sf-api-request-graphql)
|
|
63
|
-
- [`sf api request rest
|
|
63
|
+
- [`sf api request rest [URL]`](#sf-api-request-rest-url)
|
|
64
64
|
|
|
65
65
|
## `sf api request graphql`
|
|
66
66
|
|
|
@@ -113,31 +113,33 @@ EXAMPLES
|
|
|
113
113
|
$ sf api request graphql --body example.txt --stream-to-file output.txt --include
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
_See code: [src/commands/api/request/graphql.ts](https://github.com/salesforcecli/plugin-api/blob/1.
|
|
116
|
+
_See code: [src/commands/api/request/graphql.ts](https://github.com/salesforcecli/plugin-api/blob/1.3.0/src/commands/api/request/graphql.ts)_
|
|
117
117
|
|
|
118
|
-
## `sf api request rest
|
|
118
|
+
## `sf api request rest [URL]`
|
|
119
119
|
|
|
120
120
|
Make an authenticated HTTP request using the Salesforce REST API.
|
|
121
121
|
|
|
122
122
|
```
|
|
123
123
|
USAGE
|
|
124
|
-
$ sf api request rest
|
|
125
|
-
|
|
124
|
+
$ sf api request rest [URL] -o <value> [--flags-dir <value>] [--api-version <value>] [-i | -S Example: report.xlsx]
|
|
125
|
+
[-X GET|POST|PUT|PATCH|HEAD|DELETE|OPTIONS|TRACE] [-H key:value...] [-f file] [-b file]
|
|
126
126
|
|
|
127
127
|
ARGUMENTS
|
|
128
|
-
|
|
128
|
+
URL Salesforce API endpoint
|
|
129
129
|
|
|
130
130
|
FLAGS
|
|
131
131
|
-H, --header=key:value... HTTP header in "key:value" format.
|
|
132
132
|
-S, --stream-to-file=Example: report.xlsx Stream responses to a file.
|
|
133
|
-
-X, --method=<option>
|
|
133
|
+
-X, --method=<option> HTTP method for the request.
|
|
134
134
|
<options: GET|POST|PUT|PATCH|HEAD|DELETE|OPTIONS|TRACE>
|
|
135
|
+
-b, --body=file File or content for the body of the HTTP request. Specify "-" to read from
|
|
136
|
+
standard input or "" for an empty body.
|
|
137
|
+
-f, --file=file JSON file that contains values for the request header, body, method, and
|
|
138
|
+
URL.
|
|
135
139
|
-i, --include Include the HTTP response status and headers in the output.
|
|
136
140
|
-o, --target-org=<value> (required) Username or alias of the target org. Not required if the
|
|
137
141
|
`target-org` configuration variable is already set.
|
|
138
142
|
--api-version=<value> Override the api version used for api requests made by this command
|
|
139
|
-
--body=file File or content for the body of the HTTP request. Specify "-" to read from
|
|
140
|
-
standard input or "" for an empty body.
|
|
141
143
|
|
|
142
144
|
GLOBAL FLAGS
|
|
143
145
|
--flags-dir=<value> Import flag values from a directory.
|
|
@@ -167,7 +169,7 @@ EXAMPLES
|
|
|
167
169
|
|
|
168
170
|
Create an account record using the POST method; specify the request details directly in the "--body" flag:
|
|
169
171
|
|
|
170
|
-
$ sf api request rest
|
|
172
|
+
$ sf api request rest sobjects/account --body "{\"Name\" : \"Account from REST API\",\"ShippingCity\" : \
|
|
171
173
|
\"Boise\"}" --method POST
|
|
172
174
|
|
|
173
175
|
Create an account record using the information in a file called "info.json":
|
|
@@ -178,9 +180,49 @@ EXAMPLES
|
|
|
178
180
|
|
|
179
181
|
$ sf api request rest 'sobjects/account/<Account ID>' --body "{\"BillingCity\": \"San Francisco\"}" --method \
|
|
180
182
|
PATCH
|
|
183
|
+
|
|
184
|
+
Store the values for the request header, body, and so on, in a file, which you then specify with the --file flag;
|
|
185
|
+
see the description of --file for more information:
|
|
186
|
+
|
|
187
|
+
$ sf api request rest --file myFile.json
|
|
188
|
+
|
|
189
|
+
FLAG DESCRIPTIONS
|
|
190
|
+
-f, --file=file JSON file that contains values for the request header, body, method, and URL.
|
|
191
|
+
|
|
192
|
+
Use this flag instead of specifying the request details with individual flags, such as --body or --method. This
|
|
193
|
+
schema defines how to create the JSON file:
|
|
194
|
+
|
|
195
|
+
{
|
|
196
|
+
url: { raw: string } | string;
|
|
197
|
+
method: 'GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE';
|
|
198
|
+
description?: string;
|
|
199
|
+
header: string | Array<Record<string, string>>;
|
|
200
|
+
body: { mode: 'raw' | 'formdata'; raw: string; formdata: FormData };
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
Salesforce CLI defined this schema to be mimic Postman schemas; both share similar properties. The CLI's schema also
|
|
204
|
+
supports Postman Collections to reuse and share requests. As a result, you can build an API call using Postman,
|
|
205
|
+
export and save it to a file, and then use the file as a value to this flag. For information about Postman, see
|
|
206
|
+
https://learning.postman.com/.
|
|
207
|
+
|
|
208
|
+
Here's a simple example of a JSON file that contains values for the request URL, method, and body:
|
|
209
|
+
|
|
210
|
+
{
|
|
211
|
+
"url": "sobjects/Account/<Account ID>",
|
|
212
|
+
"method": "PATCH",
|
|
213
|
+
"body" : {
|
|
214
|
+
"mode": "raw",
|
|
215
|
+
"raw": {
|
|
216
|
+
"BillingCity": "Boise"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
See more examples in the plugin-api test directory, including JSON files that use "formdata" to define collections:
|
|
222
|
+
https://github.com/salesforcecli/plugin-api/tree/main/test/test-files/data-project.
|
|
181
223
|
```
|
|
182
224
|
|
|
183
|
-
_See code: [src/commands/api/request/rest.ts](https://github.com/salesforcecli/plugin-api/blob/1.
|
|
225
|
+
_See code: [src/commands/api/request/rest.ts](https://github.com/salesforcecli/plugin-api/blob/1.3.0/src/commands/api/request/rest.ts)_
|
|
184
226
|
|
|
185
227
|
<!-- commandsstop -->
|
|
186
228
|
|
|
@@ -1,5 +1,40 @@
|
|
|
1
|
+
import type { Headers } from 'got';
|
|
1
2
|
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
3
|
import { Org } from '@salesforce/core';
|
|
4
|
+
import FormData from 'form-data';
|
|
5
|
+
declare const methodOptions: readonly ["GET", "POST", "PUT", "PATCH", "HEAD", "DELETE", "OPTIONS", "TRACE"];
|
|
6
|
+
type FileFormData = {
|
|
7
|
+
type: 'file';
|
|
8
|
+
src: string | string[];
|
|
9
|
+
key: string;
|
|
10
|
+
};
|
|
11
|
+
type StringFormData = {
|
|
12
|
+
type: 'text';
|
|
13
|
+
value: string;
|
|
14
|
+
key: string;
|
|
15
|
+
};
|
|
16
|
+
type FormDataPostmanSchema = {
|
|
17
|
+
mode: 'formdata';
|
|
18
|
+
formdata: Array<FileFormData | StringFormData>;
|
|
19
|
+
};
|
|
20
|
+
type RawPostmanSchema = {
|
|
21
|
+
mode: 'raw';
|
|
22
|
+
raw: string | Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
export type PostmanSchema = {
|
|
25
|
+
url: {
|
|
26
|
+
raw: string;
|
|
27
|
+
} | string;
|
|
28
|
+
method: typeof methodOptions;
|
|
29
|
+
description?: string;
|
|
30
|
+
header: string | Array<{
|
|
31
|
+
key: string;
|
|
32
|
+
value: string;
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
description?: string;
|
|
35
|
+
}>;
|
|
36
|
+
body: RawPostmanSchema | FormDataPostmanSchema;
|
|
37
|
+
};
|
|
3
38
|
export declare class Rest extends SfCommand<void> {
|
|
4
39
|
static readonly summary: string;
|
|
5
40
|
static readonly description: string;
|
|
@@ -10,13 +45,17 @@ export declare class Rest extends SfCommand<void> {
|
|
|
10
45
|
'target-org': import("@oclif/core/interfaces").OptionFlag<Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
46
|
'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
47
|
include: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
method: import("@oclif/core/interfaces").OptionFlag<"GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "TRACE" | "PATCH", import("@oclif/core/interfaces").CustomOptions>;
|
|
48
|
+
method: import("@oclif/core/interfaces").OptionFlag<"GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "TRACE" | "PATCH" | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
49
|
header: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
50
|
+
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
51
|
'stream-to-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
52
|
body: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
53
|
};
|
|
18
54
|
static args: {
|
|
19
|
-
|
|
55
|
+
url: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
20
56
|
};
|
|
21
57
|
run(): Promise<void>;
|
|
22
58
|
}
|
|
59
|
+
export declare const getBodyContents: (body?: PostmanSchema["body"]) => string | FormData;
|
|
60
|
+
export declare function getHeaders(keyValPair: string[] | PostmanSchema['header'] | undefined): Headers;
|
|
61
|
+
export {};
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
* Licensed under the BSD 3-Clause license.
|
|
5
5
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
6
|
*/
|
|
7
|
-
import { readFileSync,
|
|
8
|
-
import { join } from 'node:path';
|
|
7
|
+
import { readFileSync, createReadStream } from 'node:fs';
|
|
9
8
|
import { ProxyAgent } from 'proxy-agent';
|
|
10
9
|
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
|
|
11
|
-
import { Messages, Org, SFDX_HTTP_HEADERS } from '@salesforce/core';
|
|
10
|
+
import { Messages, Org, SFDX_HTTP_HEADERS, SfError } from '@salesforce/core';
|
|
12
11
|
import { Args } from '@oclif/core';
|
|
13
|
-
import
|
|
12
|
+
import FormData from 'form-data';
|
|
13
|
+
import { includeFlag, sendAndPrintRequest, streamToFileFlag } from '../../../shared/shared.js';
|
|
14
14
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
15
15
|
const messages = Messages.loadMessages('@salesforce/plugin-api', 'rest');
|
|
16
|
+
const methodOptions = ['GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'];
|
|
16
17
|
export class Rest extends SfCommand {
|
|
17
18
|
static summary = messages.getMessage('summary');
|
|
18
19
|
static description = messages.getMessage('description');
|
|
@@ -24,10 +25,9 @@ export class Rest extends SfCommand {
|
|
|
24
25
|
'api-version': Flags.orgApiVersion(),
|
|
25
26
|
include: includeFlag,
|
|
26
27
|
method: Flags.option({
|
|
27
|
-
options:
|
|
28
|
+
options: methodOptions,
|
|
28
29
|
summary: messages.getMessage('flags.method.summary'),
|
|
29
30
|
char: 'X',
|
|
30
|
-
default: 'GET',
|
|
31
31
|
})(),
|
|
32
32
|
header: Flags.string({
|
|
33
33
|
summary: messages.getMessage('flags.header.summary'),
|
|
@@ -35,38 +35,58 @@ export class Rest extends SfCommand {
|
|
|
35
35
|
char: 'H',
|
|
36
36
|
multiple: true,
|
|
37
37
|
}),
|
|
38
|
+
file: Flags.file({
|
|
39
|
+
summary: messages.getMessage('flags.file.summary'),
|
|
40
|
+
description: messages.getMessage('flags.file.description'),
|
|
41
|
+
helpValue: 'file',
|
|
42
|
+
char: 'f',
|
|
43
|
+
}),
|
|
38
44
|
'stream-to-file': streamToFileFlag,
|
|
39
45
|
body: Flags.string({
|
|
40
46
|
summary: messages.getMessage('flags.body.summary'),
|
|
41
47
|
allowStdin: true,
|
|
42
48
|
helpValue: 'file',
|
|
49
|
+
char: 'b',
|
|
43
50
|
}),
|
|
44
51
|
};
|
|
45
52
|
static args = {
|
|
46
|
-
|
|
53
|
+
url: Args.string({
|
|
47
54
|
description: 'Salesforce API endpoint',
|
|
48
|
-
required:
|
|
55
|
+
required: false,
|
|
49
56
|
}),
|
|
50
57
|
};
|
|
51
58
|
async run() {
|
|
52
59
|
const { flags, args } = await this.parse(Rest);
|
|
53
60
|
const org = flags['target-org'];
|
|
54
61
|
const streamFile = flags['stream-to-file'];
|
|
55
|
-
const
|
|
62
|
+
const fileOptions = flags.file
|
|
63
|
+
? JSON.parse(readFileSync(flags.file, 'utf8'))
|
|
64
|
+
: undefined;
|
|
65
|
+
// validate that we have a URL to hit
|
|
66
|
+
if (!args.url && !fileOptions?.url) {
|
|
67
|
+
throw new SfError("The url is required either in --file file's content or as an argument");
|
|
68
|
+
}
|
|
69
|
+
// the conditional above ensures we either have an arg or it's in the file - now we just have to find where the URL value is
|
|
70
|
+
const specified = args.url ?? (fileOptions?.url).raw ?? fileOptions?.url;
|
|
71
|
+
const url = new URL(`${org.getField(Org.Fields.INSTANCE_URL)}/services/data/v${flags['api-version'] ?? (await org.retrieveMaxApiVersion())
|
|
56
72
|
// replace first '/' to create valid URL
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
}/${specified.replace(/\//y, '')}`);
|
|
74
|
+
// default the method to GET here to allow flags to override, but not hinder reading from files, rather than setting the default in the flag definition
|
|
75
|
+
const method = flags.method ?? fileOptions?.method ?? 'GET';
|
|
76
|
+
// @ts-expect-error users _could_ put one of these in their file without knowing it's wrong - TS is smarter than users here :)
|
|
77
|
+
if (!methodOptions.includes(method)) {
|
|
78
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
79
|
+
throw new SfError(`"${method}" must be one of ${methodOptions.join(', ')}`);
|
|
80
|
+
}
|
|
81
|
+
const body = method !== 'GET' ? flags.body ?? getBodyContents(fileOptions?.body) : undefined;
|
|
82
|
+
let headers = getHeaders(flags.header ?? fileOptions?.header);
|
|
83
|
+
if (body instanceof FormData) {
|
|
84
|
+
// if it's a multi-part formdata request, those have extra headers
|
|
85
|
+
headers = { ...headers, ...body.getHeaders() };
|
|
86
|
+
}
|
|
67
87
|
const options = {
|
|
68
88
|
agent: { https: new ProxyAgent() },
|
|
69
|
-
method
|
|
89
|
+
method,
|
|
70
90
|
headers: {
|
|
71
91
|
...SFDX_HTTP_HEADERS,
|
|
72
92
|
Authorization: `Bearer ${
|
|
@@ -79,7 +99,62 @@ export class Rest extends SfCommand {
|
|
|
79
99
|
throwHttpErrors: false,
|
|
80
100
|
followRedirect: false,
|
|
81
101
|
};
|
|
102
|
+
await org.refreshAuth();
|
|
82
103
|
await sendAndPrintRequest({ streamFile, url, options, include: flags.include, this: this });
|
|
83
104
|
}
|
|
84
105
|
}
|
|
106
|
+
export const getBodyContents = (body) => {
|
|
107
|
+
if (!body?.mode) {
|
|
108
|
+
throw new SfError("No 'mode' found in 'body' entry", undefined, ['add "mode":"raw" | "formdata" to your body']);
|
|
109
|
+
}
|
|
110
|
+
if (body?.mode === 'raw') {
|
|
111
|
+
return JSON.stringify(body.raw);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// parse formdata
|
|
115
|
+
const form = new FormData();
|
|
116
|
+
body?.formdata.map((data) => {
|
|
117
|
+
if (data.type === 'text') {
|
|
118
|
+
form.append(data.key, data.value);
|
|
119
|
+
}
|
|
120
|
+
else if (data.type === 'file' && typeof data.src === 'string') {
|
|
121
|
+
form.append(data.key, createReadStream(data.src));
|
|
122
|
+
}
|
|
123
|
+
else if (Array.isArray(data.src)) {
|
|
124
|
+
form.append(data.key, data.src);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
return form;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
export function getHeaders(keyValPair) {
|
|
131
|
+
if (!keyValPair)
|
|
132
|
+
return {};
|
|
133
|
+
const headers = {};
|
|
134
|
+
if (typeof keyValPair === 'string') {
|
|
135
|
+
const [key, ...rest] = keyValPair.split(':');
|
|
136
|
+
headers[key.toLowerCase()] = rest.join(':').trim();
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
keyValPair.map((header) => {
|
|
140
|
+
if (typeof header === 'string') {
|
|
141
|
+
const [key, ...rest] = header.split(':');
|
|
142
|
+
const value = rest.join(':').trim();
|
|
143
|
+
if (!key || !value) {
|
|
144
|
+
throw new SfError(`Failed to parse HTTP header: "${header}".`, 'Failed To Parse HTTP Header', [
|
|
145
|
+
'Make sure the header is in a "key:value" format, e.g. "Accept: application/json"',
|
|
146
|
+
]);
|
|
147
|
+
}
|
|
148
|
+
headers[key.toLowerCase()] = value;
|
|
149
|
+
}
|
|
150
|
+
else if (!header.disabled) {
|
|
151
|
+
if (!header.key || !header.value) {
|
|
152
|
+
throw new SfError(`Failed to validate header: missing key: ${header.key} or value: ${header.value}`);
|
|
153
|
+
}
|
|
154
|
+
headers[header.key.toLowerCase()] = header.value;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return headers;
|
|
159
|
+
}
|
|
85
160
|
//# sourceMappingURL=rest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/commands/api/request/rest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/commands/api/request/rest.ts"],"names":[],"mappings":"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"}
|
package/lib/shared/shared.d.ts
CHANGED
package/lib/shared/shared.js
CHANGED
|
@@ -11,20 +11,6 @@ import ansis from 'ansis';
|
|
|
11
11
|
import got from 'got';
|
|
12
12
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
13
13
|
const messages = Messages.loadMessages('@salesforce/plugin-api', 'shared');
|
|
14
|
-
export function getHeaders(keyValPair) {
|
|
15
|
-
const headers = {};
|
|
16
|
-
for (const header of keyValPair) {
|
|
17
|
-
const [key, ...rest] = header.split(':');
|
|
18
|
-
const value = rest.join(':').trim();
|
|
19
|
-
if (!key || !value) {
|
|
20
|
-
throw new SfError(`Failed to parse HTTP header: "${header}".`, 'Failed To Parse HTTP Header', [
|
|
21
|
-
'Make sure the header is in a "key:value" format, e.g. "Accept: application/json"',
|
|
22
|
-
]);
|
|
23
|
-
}
|
|
24
|
-
headers[key] = value;
|
|
25
|
-
}
|
|
26
|
-
return headers;
|
|
27
|
-
}
|
|
28
14
|
export async function sendAndPrintRequest(options) {
|
|
29
15
|
if (options.streamFile) {
|
|
30
16
|
const responseStream = options.options.method
|
package/lib/shared/shared.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/shared/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/shared/shared.ts"],"names":[],"mappings":"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"}
|
package/messages/rest.md
CHANGED
|
@@ -24,7 +24,7 @@ For a full list of supported REST endpoints and resources, see https://developer
|
|
|
24
24
|
|
|
25
25
|
- Create an account record using the POST method; specify the request details directly in the "--body" flag:
|
|
26
26
|
|
|
27
|
-
<%= config.bin %> <%= command.id %>
|
|
27
|
+
<%= config.bin %> <%= command.id %> sobjects/account --body "{\"Name\" : \"Account from REST API\",\"ShippingCity\" : \"Boise\"}" --method POST
|
|
28
28
|
|
|
29
29
|
- Create an account record using the information in a file called "info.json":
|
|
30
30
|
|
|
@@ -34,10 +34,47 @@ For a full list of supported REST endpoints and resources, see https://developer
|
|
|
34
34
|
|
|
35
35
|
<%= config.bin %> <%= command.id %> 'sobjects/account/<Account ID>' --body "{\"BillingCity\": \"San Francisco\"}" --method PATCH
|
|
36
36
|
|
|
37
|
+
- Store the values for the request header, body, and so on, in a file, which you then specify with the --file flag; see the description of --file for more information:
|
|
38
|
+
|
|
39
|
+
<%= config.bin %> <%= command.id %> --file myFile.json
|
|
40
|
+
|
|
37
41
|
# flags.method.summary
|
|
38
42
|
|
|
39
43
|
HTTP method for the request.
|
|
40
44
|
|
|
45
|
+
# flags.file.summary
|
|
46
|
+
|
|
47
|
+
JSON file that contains values for the request header, body, method, and URL.
|
|
48
|
+
|
|
49
|
+
# flags.file.description
|
|
50
|
+
|
|
51
|
+
Use this flag instead of specifying the request details with individual flags, such as --body or --method. This schema defines how to create the JSON file:
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
url: { raw: string } | string;
|
|
55
|
+
method: 'GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE';
|
|
56
|
+
description?: string;
|
|
57
|
+
header: string | Array<Record<string, string>>;
|
|
58
|
+
body: { mode: 'raw' | 'formdata'; raw: string; formdata: FormData };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
Salesforce CLI defined this schema to be mimic Postman schemas; both share similar properties. The CLI's schema also supports Postman Collections to reuse and share requests. As a result, you can build an API call using Postman, export and save it to a file, and then use the file as a value to this flag. For information about Postman, see https://learning.postman.com/.
|
|
62
|
+
|
|
63
|
+
Here's a simple example of a JSON file that contains values for the request URL, method, and body:
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
"url": "sobjects/Account/<Account ID>",
|
|
67
|
+
"method": "PATCH",
|
|
68
|
+
"body" : {
|
|
69
|
+
"mode": "raw",
|
|
70
|
+
"raw": {
|
|
71
|
+
"BillingCity": "Boise"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
See more examples in the plugin-api test directory, including JSON files that use "formdata" to define collections: https://github.com/salesforcecli/plugin-api/tree/main/test/test-files/data-project.
|
|
77
|
+
|
|
41
78
|
# flags.header.summary
|
|
42
79
|
|
|
43
80
|
HTTP header in "key:value" format.
|
package/oclif.manifest.json
CHANGED
|
@@ -106,10 +106,10 @@
|
|
|
106
106
|
"api:request:rest": {
|
|
107
107
|
"aliases": [],
|
|
108
108
|
"args": {
|
|
109
|
-
"
|
|
109
|
+
"url": {
|
|
110
110
|
"description": "Salesforce API endpoint",
|
|
111
|
-
"name": "
|
|
112
|
-
"required":
|
|
111
|
+
"name": "url",
|
|
112
|
+
"required": false
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
115
|
"description": "When sending the HTTP request with the \"--body\" flag, you can specify the request directly at the command line or with a file that contains the request.\n\nFor a full list of supported REST endpoints and resources, see https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_list.htm.",
|
|
@@ -117,9 +117,10 @@
|
|
|
117
117
|
"List information about limits in the org with alias \"my-org\":\n<%= config.bin %> <%= command.id %> 'limits' --target-org my-org",
|
|
118
118
|
"List all endpoints in your default org; write the output to a file called \"output.txt\" and include the HTTP response status and headers:\n<%= config.bin %> <%= command.id %> '/' --stream-to-file output.txt --include",
|
|
119
119
|
"Get the response in XML format by specifying the \"Accept\" HTTP header:\n<%= config.bin %> <%= command.id %> 'limits' --header 'Accept: application/xml'",
|
|
120
|
-
"Create an account record using the POST method; specify the request details directly in the \"--body\" flag:\n<%= config.bin %> <%= command.id %>
|
|
120
|
+
"Create an account record using the POST method; specify the request details directly in the \"--body\" flag:\n<%= config.bin %> <%= command.id %> sobjects/account --body \"{\\\"Name\\\" : \\\"Account from REST API\\\",\\\"ShippingCity\\\" : \\\"Boise\\\"}\" --method POST",
|
|
121
121
|
"Create an account record using the information in a file called \"info.json\":\n<%= config.bin %> <%= command.id %> 'sobjects/account' --body info.json --method POST",
|
|
122
|
-
"Update an account record using the PATCH method:\n<%= config.bin %> <%= command.id %> 'sobjects/account/<Account ID>' --body \"{\\\"BillingCity\\\": \\\"San Francisco\\\"}\" --method PATCH"
|
|
122
|
+
"Update an account record using the PATCH method:\n<%= config.bin %> <%= command.id %> 'sobjects/account/<Account ID>' --body \"{\\\"BillingCity\\\": \\\"San Francisco\\\"}\" --method PATCH",
|
|
123
|
+
"Store the values for the request header, body, and so on, in a file, which you then specify with the --file flag; see the description of --file for more information:\n<%= config.bin %> <%= command.id %> --file myFile.json"
|
|
123
124
|
],
|
|
124
125
|
"flags": {
|
|
125
126
|
"flags-dir": {
|
|
@@ -161,7 +162,6 @@
|
|
|
161
162
|
"char": "X",
|
|
162
163
|
"name": "method",
|
|
163
164
|
"summary": "HTTP method for the request.",
|
|
164
|
-
"default": "GET",
|
|
165
165
|
"hasDynamicHelp": false,
|
|
166
166
|
"multiple": false,
|
|
167
167
|
"options": [
|
|
@@ -185,6 +185,16 @@
|
|
|
185
185
|
"multiple": true,
|
|
186
186
|
"type": "option"
|
|
187
187
|
},
|
|
188
|
+
"file": {
|
|
189
|
+
"char": "f",
|
|
190
|
+
"description": "Use this flag instead of specifying the request details with individual flags, such as --body or --method. This schema defines how to create the JSON file:\n\n{\nurl: { raw: string } | string;\nmethod: 'GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE';\ndescription?: string;\nheader: string | Array<Record<string, string>>;\nbody: { mode: 'raw' | 'formdata'; raw: string; formdata: FormData };\n}\n\nSalesforce CLI defined this schema to be mimic Postman schemas; both share similar properties. The CLI's schema also supports Postman Collections to reuse and share requests. As a result, you can build an API call using Postman, export and save it to a file, and then use the file as a value to this flag. For information about Postman, see https://learning.postman.com/.\n\nHere's a simple example of a JSON file that contains values for the request URL, method, and body:\n\n{\n\"url\": \"sobjects/Account/<Account ID>\",\n\"method\": \"PATCH\",\n\"body\" : {\n\"mode\": \"raw\",\n\"raw\": {\n\"BillingCity\": \"Boise\"\n}\n}\n}\n\nSee more examples in the plugin-api test directory, including JSON files that use \"formdata\" to define collections: https://github.com/salesforcecli/plugin-api/tree/main/test/test-files/data-project.",
|
|
191
|
+
"name": "file",
|
|
192
|
+
"summary": "JSON file that contains values for the request header, body, method, and URL.",
|
|
193
|
+
"hasDynamicHelp": false,
|
|
194
|
+
"helpValue": "file",
|
|
195
|
+
"multiple": false,
|
|
196
|
+
"type": "option"
|
|
197
|
+
},
|
|
188
198
|
"stream-to-file": {
|
|
189
199
|
"char": "S",
|
|
190
200
|
"exclusive": [
|
|
@@ -198,6 +208,7 @@
|
|
|
198
208
|
"type": "option"
|
|
199
209
|
},
|
|
200
210
|
"body": {
|
|
211
|
+
"char": "b",
|
|
201
212
|
"name": "body",
|
|
202
213
|
"summary": "File or content for the body of the HTTP request. Specify \"-\" to read from standard input or \"\" for an empty body.",
|
|
203
214
|
"hasDynamicHelp": false,
|
|
@@ -235,5 +246,5 @@
|
|
|
235
246
|
]
|
|
236
247
|
}
|
|
237
248
|
},
|
|
238
|
-
"version": "1.
|
|
249
|
+
"version": "1.3.0"
|
|
239
250
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/plugin-api",
|
|
3
3
|
"description": "A plugin to call API endpoints via CLI commands",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/forcedotcom/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"@salesforce/sf-plugins-core": "^11.3.2",
|
|
12
12
|
"@salesforce/ts-types": "^2.0.12",
|
|
13
13
|
"ansis": "^3.3.2",
|
|
14
|
+
"form-data": "^4.0.0",
|
|
14
15
|
"got": "^13.0.0",
|
|
15
16
|
"proxy-agent": "^6.4.0"
|
|
16
17
|
},
|
|
@@ -31,8 +32,6 @@
|
|
|
31
32
|
"files": [
|
|
32
33
|
"/lib",
|
|
33
34
|
"/messages",
|
|
34
|
-
"/npm-shrinkwrap.json",
|
|
35
|
-
"/oclif.lock",
|
|
36
35
|
"/oclif.manifest.json",
|
|
37
36
|
"/schemas"
|
|
38
37
|
],
|
|
@@ -207,7 +206,7 @@
|
|
|
207
206
|
"exports": "./lib/index.js",
|
|
208
207
|
"type": "module",
|
|
209
208
|
"sfdx": {
|
|
210
|
-
"publicKeyUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.
|
|
211
|
-
"signatureUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.
|
|
209
|
+
"publicKeyUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.3.0.crt",
|
|
210
|
+
"signatureUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.3.0.sig"
|
|
212
211
|
}
|
|
213
212
|
}
|