@salesforce/plugin-api 1.1.0 → 1.2.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 +89 -75
- package/lib/commands/api/request/graphql.d.ts +16 -0
- package/lib/commands/api/request/graphql.js +55 -0
- package/lib/commands/api/request/graphql.js.map +1 -0
- package/lib/commands/api/request/rest.js +6 -50
- package/lib/commands/api/request/rest.js.map +1 -1
- package/lib/shared/shared.d.ts +12 -0
- package/lib/shared/shared.js +82 -0
- package/lib/shared/shared.js.map +1 -0
- package/messages/graphql.md +46 -0
- package/messages/rest.md +0 -8
- package/messages/shared.md +7 -0
- package/npm-shrinkwrap.json +3 -2
- package/oclif.manifest.json +101 -1
- package/package.json +4 -3
- package/lib/shared/methods.d.ts +0 -2
- package/lib/shared/methods.js +0 -22
- package/lib/shared/methods.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,55 +1,7 @@
|
|
|
1
|
-
**NOTE: This template for sf plugins is not yet official. Please consult with the Platform CLI team before using this template.**
|
|
2
|
-
|
|
3
|
-
# plugin-template-sf
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@salesforce/plugin-template-sf) [](https://npmjs.org/package/@salesforce/plugin-template-sf) [](https://raw.githubusercontent.com/salesforcecli/plugin-template-sf/main/LICENSE.txt)
|
|
6
|
-
|
|
7
|
-
## Using the template
|
|
8
|
-
|
|
9
|
-
This repository provides a template for creating a plugin for the Salesforce CLI. To convert this template to a working plugin:
|
|
10
|
-
|
|
11
|
-
1. Please get in touch with the Platform CLI team. We want to help you develop your plugin.
|
|
12
|
-
2. Generate your plugin:
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
sf plugins install dev
|
|
16
|
-
sf dev generate plugin
|
|
17
|
-
|
|
18
|
-
git init -b main
|
|
19
|
-
git add . && git commit -m "chore: initial commit"
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
3. Create your plugin's repo in the salesforcecli github org
|
|
23
|
-
4. When you're ready, replace the contents of this README with the information you want.
|
|
24
|
-
|
|
25
|
-
## Learn about `sf` plugins
|
|
26
|
-
|
|
27
|
-
Salesforce CLI plugins are based on the [oclif plugin framework](https://oclif.io/docs/introduction). Read the [plugin developer guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_plugins.meta/sfdx_cli_plugins/cli_plugins_architecture_sf_cli.htm) to learn about Salesforce CLI plugin development.
|
|
28
|
-
|
|
29
|
-
This repository contains a lot of additional scripts and tools to help with general Salesforce node development and enforce coding standards. You should familiarize yourself with some of the [node developer packages](#tooling) used by Salesforce. There is also a default circleci config using the [release management orb](https://github.com/forcedotcom/npm-release-management-orb) standards.
|
|
30
|
-
|
|
31
|
-
Additionally, there are some additional tests that the Salesforce CLI will enforce if this plugin is ever bundled with the CLI. These test are included by default under the `posttest` script and it is required to keep these tests active in your plugin if you plan to have it bundled.
|
|
32
|
-
|
|
33
|
-
### Tooling
|
|
34
|
-
|
|
35
|
-
- [@salesforce/core](https://github.com/forcedotcom/sfdx-core)
|
|
36
|
-
- [@salesforce/kit](https://github.com/forcedotcom/kit)
|
|
37
|
-
- [@salesforce/sf-plugins-core](https://github.com/salesforcecli/sf-plugins-core)
|
|
38
|
-
- [@salesforce/ts-types](https://github.com/forcedotcom/ts-types)
|
|
39
|
-
- [@salesforce/ts-sinon](https://github.com/forcedotcom/ts-sinon)
|
|
40
|
-
- [@salesforce/dev-config](https://github.com/forcedotcom/dev-config)
|
|
41
|
-
- [@salesforce/dev-scripts](https://github.com/forcedotcom/dev-scripts)
|
|
42
|
-
|
|
43
|
-
# Everything past here is only a suggestion as to what should be in your specific plugin's description
|
|
44
|
-
|
|
45
|
-
This plugin is bundled with the [Salesforce CLI](https://developer.salesforce.com/tools/sfdxcli). For more information on the CLI, read the [getting started guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm).
|
|
46
|
-
|
|
47
|
-
We always recommend using the latest version of these commands bundled with the CLI, however, you can install a specific version or tag if needed.
|
|
48
|
-
|
|
49
1
|
## Install
|
|
50
2
|
|
|
51
3
|
```bash
|
|
52
|
-
sf plugins install @salesforce/plugin-
|
|
4
|
+
sf plugins install @salesforce/plugin-api
|
|
53
5
|
```
|
|
54
6
|
|
|
55
7
|
## Issues
|
|
@@ -107,52 +59,114 @@ sf plugins
|
|
|
107
59
|
|
|
108
60
|
<!-- commands -->
|
|
109
61
|
|
|
62
|
+
- [`sf api request graphql`](#sf-api-request-graphql)
|
|
110
63
|
- [`sf api request rest ENDPOINT`](#sf-api-request-rest-endpoint)
|
|
111
64
|
|
|
112
|
-
## `sf api request
|
|
65
|
+
## `sf api request graphql`
|
|
113
66
|
|
|
114
|
-
|
|
67
|
+
Execute GraphQL statements
|
|
115
68
|
|
|
116
69
|
````
|
|
117
70
|
USAGE
|
|
118
|
-
$ sf api request
|
|
119
|
-
report.xlsx
|
|
120
|
-
|
|
121
|
-
ARGUMENTS
|
|
122
|
-
ENDPOINT Salesforce API endpoint
|
|
71
|
+
$ sf api request graphql -o <value> --body file [--json] [--flags-dir <value>] [--api-version <value>] [-S Example:
|
|
72
|
+
report.xlsx | -i]
|
|
123
73
|
|
|
124
74
|
FLAGS
|
|
125
|
-
-H, --header=key:value... HTTP header in "key:value" format.
|
|
126
75
|
-S, --stream-to-file=Example: report.xlsx Stream responses to a file.
|
|
127
|
-
-X, --method=<option> [default: GET] HTTP method for the request.
|
|
128
|
-
<options: GET|POST|PUT|PATCH|HEAD|DELETE|OPTIONS|TRACE>
|
|
129
76
|
-i, --include Include the HTTP response status and headers in the output.
|
|
130
77
|
-o, --target-org=<value> (required) Username or alias of the target org. Not required if the
|
|
131
78
|
`target-org` configuration variable is already set.
|
|
132
79
|
--api-version=<value> Override the api version used for api requests made by this command
|
|
133
|
-
--body=file File
|
|
134
|
-
input
|
|
80
|
+
--body=file (required) File or content with GraphQL statement. Specify "-" to read from
|
|
81
|
+
standard input.
|
|
135
82
|
|
|
136
83
|
GLOBAL FLAGS
|
|
137
84
|
--flags-dir=<value> Import flag values from a directory.
|
|
85
|
+
--json Format output as json.
|
|
86
|
+
|
|
87
|
+
DESCRIPTION
|
|
88
|
+
Execute GraphQL statements
|
|
89
|
+
|
|
90
|
+
Run any valid GraphQL statement via the /graphql
|
|
91
|
+
[API](https://developer.salesforce.com/docs/platform/graphql/guide/graphql-about.html)
|
|
138
92
|
|
|
139
93
|
EXAMPLES
|
|
140
|
-
-
|
|
141
|
-
sf api request
|
|
142
|
-
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
94
|
+
- Runs the graphql query directly via the command line
|
|
95
|
+
sf api request graphql --body "query accounts { uiapi { query { Account { edges { node { Id \n Name { value } } } } } } }"
|
|
96
|
+
- Runs a mutation to create an Account, with an `example.txt` file, containing
|
|
97
|
+
```text
|
|
98
|
+
mutation AccountExample{
|
|
99
|
+
uiapi {
|
|
100
|
+
AccountCreate(input: {
|
|
101
|
+
Account: {
|
|
102
|
+
Name: "Trailblazer Express"
|
|
103
|
+
}
|
|
104
|
+
}) {
|
|
105
|
+
Record {
|
|
106
|
+
Id
|
|
107
|
+
Name {
|
|
108
|
+
value
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
153
113
|
}
|
|
154
114
|
````
|
|
155
115
|
|
|
116
|
+
$ sf api request graphql --body example.txt
|
|
117
|
+
will create a new account returning specified fields (Id, Name)
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
_See code: [src/commands/api/request/graphql.ts](https://github.com/salesforcecli/plugin-api/blob/1.2.0/src/commands/api/request/graphql.ts)_
|
|
122
|
+
|
|
123
|
+
## `sf api request rest ENDPOINT`
|
|
124
|
+
|
|
125
|
+
Make an authenticated HTTP request to Salesforce REST API and print the response.
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
USAGE
|
|
130
|
+
$ sf api request rest ENDPOINT -o <value> [--flags-dir <value>] [--api-version <value>] [-i | -S Example:
|
|
131
|
+
report.xlsx] [-X GET|POST|PUT|PATCH|HEAD|DELETE|OPTIONS|TRACE] [-H key:value...] [--body file]
|
|
132
|
+
|
|
133
|
+
ARGUMENTS
|
|
134
|
+
ENDPOINT Salesforce API endpoint
|
|
135
|
+
|
|
136
|
+
FLAGS
|
|
137
|
+
-H, --header=key:value... HTTP header in "key:value" format.
|
|
138
|
+
-S, --stream-to-file=Example: report.xlsx Stream responses to a file.
|
|
139
|
+
-X, --method=<option> [default: GET] HTTP method for the request.
|
|
140
|
+
<options: GET|POST|PUT|PATCH|HEAD|DELETE|OPTIONS|TRACE>
|
|
141
|
+
-i, --include Include the HTTP response status and headers in the output.
|
|
142
|
+
-o, --target-org=<value> (required) Username or alias of the target org. Not required if the
|
|
143
|
+
`target-org` configuration variable is already set.
|
|
144
|
+
--api-version=<value> Override the api version used for api requests made by this command
|
|
145
|
+
--body=file File to use as the body for the request. Specify "-" to read from standard
|
|
146
|
+
input; specify "" for an empty body.
|
|
147
|
+
|
|
148
|
+
GLOBAL FLAGS
|
|
149
|
+
--flags-dir=<value> Import flag values from a directory.
|
|
150
|
+
|
|
151
|
+
EXAMPLES
|
|
152
|
+
|
|
153
|
+
- List information about limits in the org with alias "my-org":
|
|
154
|
+
sf api request rest 'limits' --target-org my-org
|
|
155
|
+
- List all endpoints
|
|
156
|
+
sf api request rest '/'
|
|
157
|
+
- Get the response in XML format by specifying the "Accept" HTTP header:
|
|
158
|
+
sf api request rest 'limits' --target-org my-org --header 'Accept: application/xml'
|
|
159
|
+
- POST to create an Account object
|
|
160
|
+
sf api request rest 'sobjects/account' --body "{\"Name\" : \"Account from REST API\",\"ShippingCity\" : \"Boise\"}" --method POST
|
|
161
|
+
- or with a file 'info.json' containing
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"Name": "Demo",
|
|
166
|
+
"ShippingCity": "Boise"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
156
170
|
$ sf api request rest 'sobjects/account' --body info.json --method POST
|
|
157
171
|
|
|
158
172
|
- Update object
|
|
@@ -160,6 +174,6 @@ $ sf api request rest 'sobjects/account' --body info.json --method POST
|
|
|
160
174
|
|
|
161
175
|
```
|
|
162
176
|
|
|
163
|
-
_See code: [src/commands/api/request/rest.ts](https://github.com/salesforcecli/plugin-api/blob/
|
|
177
|
+
_See code: [src/commands/api/request/rest.ts](https://github.com/salesforcecli/plugin-api/blob/1.2.0/src/commands/api/request/rest.ts)_
|
|
164
178
|
<!-- commandsstop -->
|
|
165
179
|
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { Org } from '@salesforce/core';
|
|
3
|
+
export default class Graphql extends SfCommand<void> {
|
|
4
|
+
static readonly summary: string;
|
|
5
|
+
static readonly description: string;
|
|
6
|
+
static readonly examples: string[];
|
|
7
|
+
static readonly state = "beta";
|
|
8
|
+
static readonly flags: {
|
|
9
|
+
'target-org': import("@oclif/core/interfaces").OptionFlag<Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'stream-to-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
include: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
body: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
};
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
10
|
+
import { Messages, Org, SFDX_HTTP_HEADERS } from '@salesforce/core';
|
|
11
|
+
import { ProxyAgent } from 'proxy-agent';
|
|
12
|
+
import { includeFlag, sendAndPrintRequest, streamToFileFlag } from '../../../shared/shared.js';
|
|
13
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
14
|
+
const messages = Messages.loadMessages('@salesforce/plugin-api', 'graphql');
|
|
15
|
+
export default class Graphql extends SfCommand {
|
|
16
|
+
static summary = messages.getMessage('summary');
|
|
17
|
+
static description = messages.getMessage('description');
|
|
18
|
+
static examples = messages.getMessages('examples');
|
|
19
|
+
static state = 'beta';
|
|
20
|
+
static flags = {
|
|
21
|
+
'target-org': Flags.requiredOrg(),
|
|
22
|
+
'api-version': Flags.orgApiVersion(),
|
|
23
|
+
'stream-to-file': streamToFileFlag,
|
|
24
|
+
include: includeFlag,
|
|
25
|
+
body: Flags.string({
|
|
26
|
+
summary: messages.getMessage('flags.body.summary'),
|
|
27
|
+
allowStdin: true,
|
|
28
|
+
helpValue: 'file',
|
|
29
|
+
required: true,
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
async run() {
|
|
33
|
+
const { flags } = await this.parse(Graphql);
|
|
34
|
+
const org = flags['target-org'];
|
|
35
|
+
const streamFile = flags['stream-to-file'];
|
|
36
|
+
const apiVersion = flags['api-version'] ?? (await org.retrieveMaxApiVersion());
|
|
37
|
+
const body = `{"query":"${(fs.existsSync(flags.body) ? fs.readFileSync(flags.body, 'utf8') : flags.body)
|
|
38
|
+
.replaceAll(os.EOL, '\\n')
|
|
39
|
+
.replaceAll('"', '\\"')}"}`;
|
|
40
|
+
const url = new URL(`${org.getField(Org.Fields.INSTANCE_URL)}/services/data/v${apiVersion}/graphql`);
|
|
41
|
+
await org.refreshAuth();
|
|
42
|
+
const options = {
|
|
43
|
+
agent: { https: new ProxyAgent() },
|
|
44
|
+
headers: {
|
|
45
|
+
...SFDX_HTTP_HEADERS,
|
|
46
|
+
Authorization: `Bearer ${org.getConnection(apiVersion).getConnectionOptions().accessToken}`,
|
|
47
|
+
},
|
|
48
|
+
body,
|
|
49
|
+
throwHttpErrors: false,
|
|
50
|
+
followRedirect: false,
|
|
51
|
+
};
|
|
52
|
+
await sendAndPrintRequest({ streamFile, url, options, include: flags.include, this: this });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../../src/commands/api/request/graphql.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,15 +4,13 @@
|
|
|
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 {
|
|
7
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
|
-
import got from 'got';
|
|
10
9
|
import { ProxyAgent } from 'proxy-agent';
|
|
11
10
|
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
|
|
12
|
-
import { Messages, Org, SFDX_HTTP_HEADERS
|
|
11
|
+
import { Messages, Org, SFDX_HTTP_HEADERS } from '@salesforce/core';
|
|
13
12
|
import { Args } from '@oclif/core';
|
|
14
|
-
import
|
|
15
|
-
import { getHeaders } from '../../../shared/methods.js';
|
|
13
|
+
import { getHeaders, includeFlag, sendAndPrintRequest, streamToFileFlag } from '../../../shared/shared.js';
|
|
16
14
|
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
17
15
|
const messages = Messages.loadMessages('@salesforce/plugin-api', 'rest');
|
|
18
16
|
export class Rest extends SfCommand {
|
|
@@ -23,12 +21,7 @@ export class Rest extends SfCommand {
|
|
|
23
21
|
static flags = {
|
|
24
22
|
'target-org': Flags.requiredOrg(),
|
|
25
23
|
'api-version': Flags.orgApiVersion(),
|
|
26
|
-
include:
|
|
27
|
-
char: 'i',
|
|
28
|
-
summary: messages.getMessage('flags.include.summary'),
|
|
29
|
-
default: false,
|
|
30
|
-
exclusive: ['stream-to-file'],
|
|
31
|
-
}),
|
|
24
|
+
include: includeFlag,
|
|
32
25
|
method: Flags.option({
|
|
33
26
|
options: ['GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'],
|
|
34
27
|
summary: messages.getMessage('flags.method.summary'),
|
|
@@ -41,12 +34,7 @@ export class Rest extends SfCommand {
|
|
|
41
34
|
char: 'H',
|
|
42
35
|
multiple: true,
|
|
43
36
|
}),
|
|
44
|
-
'stream-to-file':
|
|
45
|
-
summary: messages.getMessage('flags.stream-to-file.summary'),
|
|
46
|
-
helpValue: 'Example: report.xlsx',
|
|
47
|
-
char: 'S',
|
|
48
|
-
exclusive: ['include'],
|
|
49
|
-
}),
|
|
37
|
+
'stream-to-file': streamToFileFlag,
|
|
50
38
|
body: Flags.string({
|
|
51
39
|
summary: messages.getMessage('flags.body.summary'),
|
|
52
40
|
allowStdin: true,
|
|
@@ -90,39 +78,7 @@ export class Rest extends SfCommand {
|
|
|
90
78
|
throwHttpErrors: false,
|
|
91
79
|
followRedirect: false,
|
|
92
80
|
};
|
|
93
|
-
|
|
94
|
-
const responseStream = got.stream(url, options);
|
|
95
|
-
const fileStream = createWriteStream(streamFile);
|
|
96
|
-
responseStream.pipe(fileStream);
|
|
97
|
-
fileStream.on('finish', () => this.log(`File saved to ${streamFile}`));
|
|
98
|
-
fileStream.on('error', (error) => {
|
|
99
|
-
throw SfError.wrap(error);
|
|
100
|
-
});
|
|
101
|
-
responseStream.on('error', (error) => {
|
|
102
|
-
throw SfError.wrap(error);
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
const res = await got(url, options);
|
|
107
|
-
// Print HTTP response status and headers.
|
|
108
|
-
if (flags.include) {
|
|
109
|
-
this.log(`HTTP/${res.httpVersion} ${res.statusCode}`);
|
|
110
|
-
Object.entries(res.headers).map(([header, value]) => {
|
|
111
|
-
this.log(`${ansis.blue.bold(header)}: ${Array.isArray(value) ? value.join(',') : value ?? '<undefined>'}`);
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
try {
|
|
115
|
-
// Try to pretty-print JSON response.
|
|
116
|
-
this.styledJSON(JSON.parse(res.body));
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
// If response body isn't JSON, just print it to stdout.
|
|
120
|
-
this.log(res.body === '' ? `Server responded with an empty body, status code ${res.statusCode}` : res.body);
|
|
121
|
-
}
|
|
122
|
-
if (res.statusCode >= 400) {
|
|
123
|
-
process.exitCode = 1;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
81
|
+
await sendAndPrintRequest({ streamFile, url, options, include: flags.include, this: this });
|
|
126
82
|
}
|
|
127
83
|
}
|
|
128
84
|
//# 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,
|
|
1
|
+
{"version":3,"file":"rest.js","sourceRoot":"","sources":["../../../../src/commands/api/request/rest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Headers } from 'got';
|
|
2
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
3
|
+
export declare function getHeaders(keyValPair: string[]): Headers;
|
|
4
|
+
export declare function sendAndPrintRequest(options: {
|
|
5
|
+
streamFile?: string;
|
|
6
|
+
url: URL;
|
|
7
|
+
options: Record<string, unknown>;
|
|
8
|
+
include: boolean;
|
|
9
|
+
this: SfCommand<unknown>;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export declare const includeFlag: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
export declare const streamToFileFlag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
import { createWriteStream } from 'node:fs';
|
|
8
|
+
import { Messages, SfError } from '@salesforce/core';
|
|
9
|
+
import { Flags } from '@salesforce/sf-plugins-core';
|
|
10
|
+
import ansis from 'ansis';
|
|
11
|
+
import got from 'got';
|
|
12
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
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
|
+
export async function sendAndPrintRequest(options) {
|
|
29
|
+
if (options.streamFile) {
|
|
30
|
+
const responseStream = options.options.method
|
|
31
|
+
? got.stream(options.url, options.options)
|
|
32
|
+
: // default to 'POST' if not specified
|
|
33
|
+
got.stream.post(options.url, options.options);
|
|
34
|
+
const fileStream = createWriteStream(options.streamFile);
|
|
35
|
+
responseStream.pipe(fileStream);
|
|
36
|
+
// we just ensured it existed with the 'if'
|
|
37
|
+
fileStream.on('finish', () => options.this.log(`File saved to ${options.streamFile}`));
|
|
38
|
+
fileStream.on('error', (error) => {
|
|
39
|
+
throw SfError.wrap(error);
|
|
40
|
+
});
|
|
41
|
+
responseStream.on('error', (error) => {
|
|
42
|
+
throw SfError.wrap(error);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const res = options.options.method
|
|
47
|
+
? // default to 'POST' if not specified
|
|
48
|
+
await got(options.url, options.options)
|
|
49
|
+
: await got.post(options.url, options.options);
|
|
50
|
+
// Print HTTP response status and headers.
|
|
51
|
+
if (options.include) {
|
|
52
|
+
options.this.log(`HTTP/${res.httpVersion} ${res.statusCode}`);
|
|
53
|
+
Object.entries(res.headers).map(([header, value]) => {
|
|
54
|
+
options.this.log(`${ansis.blue.bold(header)}: ${Array.isArray(value) ? value.join(',') : value ?? '<undefined>'}`);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
// Try to pretty-print JSON response.
|
|
59
|
+
options.this.styledJSON(JSON.parse(res.body));
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
// If response body isn't JSON, just print it to stdout.
|
|
63
|
+
options.this.log(res.body);
|
|
64
|
+
}
|
|
65
|
+
if (res.statusCode >= 400) {
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export const includeFlag = Flags.boolean({
|
|
71
|
+
char: 'i',
|
|
72
|
+
summary: messages.getMessage('flags.include.summary'),
|
|
73
|
+
default: false,
|
|
74
|
+
exclusive: ['stream-to-file'],
|
|
75
|
+
});
|
|
76
|
+
export const streamToFileFlag = Flags.string({
|
|
77
|
+
summary: messages.getMessage('flags.stream-to-file.summary'),
|
|
78
|
+
helpValue: 'Example: report.xlsx',
|
|
79
|
+
char: 'S',
|
|
80
|
+
exclusive: ['include'],
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/shared/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Execute GraphQL statements
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Run any valid GraphQL statement via the /graphql [API](https://developer.salesforce.com/docs/platform/graphql/guide/graphql-about.html)
|
|
8
|
+
|
|
9
|
+
# examples
|
|
10
|
+
|
|
11
|
+
- Runs the graphql query directly via the command line
|
|
12
|
+
|
|
13
|
+
<%= config.bin %> <%= command.id %> --body "query accounts { uiapi { query { Account { edges { node { Id \n Name { value } } } } } } }"
|
|
14
|
+
|
|
15
|
+
- Runs a mutation to create an Account, with an `example.txt` file, containing
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
mutation AccountExample{
|
|
19
|
+
uiapi {
|
|
20
|
+
AccountCreate(input: {
|
|
21
|
+
Account: {
|
|
22
|
+
Name: "Trailblazer Express"
|
|
23
|
+
}
|
|
24
|
+
}) {
|
|
25
|
+
Record {
|
|
26
|
+
Id
|
|
27
|
+
Name {
|
|
28
|
+
value
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
<%= config.bin %> <%= command.id %> --body example.txt
|
|
37
|
+
|
|
38
|
+
will create a new account returning specified fields (Id, Name)
|
|
39
|
+
|
|
40
|
+
# flags.header.summary
|
|
41
|
+
|
|
42
|
+
HTTP header in "key:value" format.
|
|
43
|
+
|
|
44
|
+
# flags.body.summary
|
|
45
|
+
|
|
46
|
+
File or content with GraphQL statement. Specify "-" to read from standard input.
|
package/messages/rest.md
CHANGED
|
@@ -35,10 +35,6 @@ Make an authenticated HTTP request to Salesforce REST API and print the response
|
|
|
35
35
|
|
|
36
36
|
<%= config.bin %> <%= command.id %> 'sobjects/account/<Account ID>' --body "{\"BillingCity\": \"San Francisco\"}" --method PATCH
|
|
37
37
|
|
|
38
|
-
# flags.include.summary
|
|
39
|
-
|
|
40
|
-
Include the HTTP response status and headers in the output.
|
|
41
|
-
|
|
42
38
|
# flags.method.summary
|
|
43
39
|
|
|
44
40
|
HTTP method for the request.
|
|
@@ -47,10 +43,6 @@ HTTP method for the request.
|
|
|
47
43
|
|
|
48
44
|
HTTP header in "key:value" format.
|
|
49
45
|
|
|
50
|
-
# flags.stream-to-file.summary
|
|
51
|
-
|
|
52
|
-
Stream responses to a file.
|
|
53
|
-
|
|
54
46
|
# flags.body.summary
|
|
55
47
|
|
|
56
48
|
File to use as the body for the request. Specify "-" to read from standard input; specify "" for an empty body.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/plugin-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@salesforce/plugin-api",
|
|
9
|
-
"version": "1.
|
|
9
|
+
"version": "1.2.0",
|
|
10
10
|
"license": "BSD-3-Clause",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@oclif/core": "^4",
|
|
13
13
|
"@salesforce/core": "^8.4.0",
|
|
14
14
|
"@salesforce/kit": "^3.2.1",
|
|
15
15
|
"@salesforce/sf-plugins-core": "^11.3.2",
|
|
16
|
+
"@salesforce/ts-types": "^2.0.12",
|
|
16
17
|
"ansis": "^3.3.2",
|
|
17
18
|
"got": "^13.0.0",
|
|
18
19
|
"proxy-agent": "^6.4.0"
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,105 @@
|
|
|
1
1
|
{
|
|
2
2
|
"commands": {
|
|
3
|
+
"api:request:graphql": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": "Run any valid GraphQL statement via the /graphql [API](https://developer.salesforce.com/docs/platform/graphql/guide/graphql-about.html)",
|
|
7
|
+
"examples": [
|
|
8
|
+
"- Runs the graphql query directly via the command line\n\n <%= config.bin %> <%= command.id %> --body \"query accounts { uiapi { query { Account { edges { node { Id \\n Name { value } } } } } } }\"\n\n- Runs a mutation to create an Account, with an `example.txt` file, containing\n\n```text\nmutation AccountExample{\n uiapi {\n AccountCreate(input: {\n Account: {\n Name: \"Trailblazer Express\"\n }\n }) {\n Record {\n Id\n Name {\n value\n }\n }\n }\n }\n}\n```\n\n<%= config.bin %> <%= command.id %> --body example.txt\n\nwill create a new account returning specified fields (Id, Name)"
|
|
9
|
+
],
|
|
10
|
+
"flags": {
|
|
11
|
+
"json": {
|
|
12
|
+
"description": "Format output as json.",
|
|
13
|
+
"helpGroup": "GLOBAL",
|
|
14
|
+
"name": "json",
|
|
15
|
+
"allowNo": false,
|
|
16
|
+
"type": "boolean"
|
|
17
|
+
},
|
|
18
|
+
"flags-dir": {
|
|
19
|
+
"helpGroup": "GLOBAL",
|
|
20
|
+
"name": "flags-dir",
|
|
21
|
+
"summary": "Import flag values from a directory.",
|
|
22
|
+
"hasDynamicHelp": false,
|
|
23
|
+
"multiple": false,
|
|
24
|
+
"type": "option"
|
|
25
|
+
},
|
|
26
|
+
"target-org": {
|
|
27
|
+
"char": "o",
|
|
28
|
+
"name": "target-org",
|
|
29
|
+
"noCacheDefault": true,
|
|
30
|
+
"required": true,
|
|
31
|
+
"summary": "Username or alias of the target org. Not required if the `target-org` configuration variable is already set.",
|
|
32
|
+
"hasDynamicHelp": true,
|
|
33
|
+
"multiple": false,
|
|
34
|
+
"type": "option"
|
|
35
|
+
},
|
|
36
|
+
"api-version": {
|
|
37
|
+
"description": "Override the api version used for api requests made by this command",
|
|
38
|
+
"name": "api-version",
|
|
39
|
+
"hasDynamicHelp": false,
|
|
40
|
+
"multiple": false,
|
|
41
|
+
"type": "option"
|
|
42
|
+
},
|
|
43
|
+
"stream-to-file": {
|
|
44
|
+
"char": "S",
|
|
45
|
+
"exclusive": [
|
|
46
|
+
"include"
|
|
47
|
+
],
|
|
48
|
+
"name": "stream-to-file",
|
|
49
|
+
"summary": "Stream responses to a file.",
|
|
50
|
+
"hasDynamicHelp": false,
|
|
51
|
+
"helpValue": "Example: report.xlsx",
|
|
52
|
+
"multiple": false,
|
|
53
|
+
"type": "option"
|
|
54
|
+
},
|
|
55
|
+
"include": {
|
|
56
|
+
"char": "i",
|
|
57
|
+
"exclusive": [
|
|
58
|
+
"stream-to-file"
|
|
59
|
+
],
|
|
60
|
+
"name": "include",
|
|
61
|
+
"summary": "Include the HTTP response status and headers in the output.",
|
|
62
|
+
"allowNo": false,
|
|
63
|
+
"type": "boolean"
|
|
64
|
+
},
|
|
65
|
+
"body": {
|
|
66
|
+
"name": "body",
|
|
67
|
+
"required": true,
|
|
68
|
+
"summary": "File or content with GraphQL statement. Specify \"-\" to read from standard input.",
|
|
69
|
+
"hasDynamicHelp": false,
|
|
70
|
+
"helpValue": "file",
|
|
71
|
+
"multiple": false,
|
|
72
|
+
"type": "option"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"hasDynamicHelp": true,
|
|
76
|
+
"hiddenAliases": [],
|
|
77
|
+
"id": "api:request:graphql",
|
|
78
|
+
"pluginAlias": "@salesforce/plugin-api",
|
|
79
|
+
"pluginName": "@salesforce/plugin-api",
|
|
80
|
+
"pluginType": "core",
|
|
81
|
+
"state": "beta",
|
|
82
|
+
"strict": true,
|
|
83
|
+
"summary": "Execute GraphQL statements",
|
|
84
|
+
"enableJsonFlag": true,
|
|
85
|
+
"isESM": true,
|
|
86
|
+
"relativePath": [
|
|
87
|
+
"lib",
|
|
88
|
+
"commands",
|
|
89
|
+
"api",
|
|
90
|
+
"request",
|
|
91
|
+
"graphql.js"
|
|
92
|
+
],
|
|
93
|
+
"aliasPermutations": [],
|
|
94
|
+
"permutations": [
|
|
95
|
+
"api:request:graphql",
|
|
96
|
+
"request:api:graphql",
|
|
97
|
+
"request:graphql:api",
|
|
98
|
+
"api:graphql:request",
|
|
99
|
+
"graphql:api:request",
|
|
100
|
+
"graphql:request:api"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
3
103
|
"api:request:rest": {
|
|
4
104
|
"aliases": [],
|
|
5
105
|
"args": {
|
|
@@ -126,5 +226,5 @@
|
|
|
126
226
|
]
|
|
127
227
|
}
|
|
128
228
|
},
|
|
129
|
-
"version": "1.
|
|
229
|
+
"version": "1.2.0"
|
|
130
230
|
}
|
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.2.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"bugs": "https://github.com/forcedotcom/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"@salesforce/core": "^8.4.0",
|
|
10
10
|
"@salesforce/kit": "^3.2.1",
|
|
11
11
|
"@salesforce/sf-plugins-core": "^11.3.2",
|
|
12
|
+
"@salesforce/ts-types": "^2.0.12",
|
|
12
13
|
"ansis": "^3.3.2",
|
|
13
14
|
"got": "^13.0.0",
|
|
14
15
|
"proxy-agent": "^6.4.0"
|
|
@@ -201,7 +202,7 @@
|
|
|
201
202
|
"exports": "./lib/index.js",
|
|
202
203
|
"type": "module",
|
|
203
204
|
"sfdx": {
|
|
204
|
-
"publicKeyUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.
|
|
205
|
-
"signatureUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.
|
|
205
|
+
"publicKeyUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.2.0.crt",
|
|
206
|
+
"signatureUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.2.0.sig"
|
|
206
207
|
}
|
|
207
208
|
}
|
package/lib/shared/methods.d.ts
DELETED
package/lib/shared/methods.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023, salesforce.com, inc.
|
|
3
|
-
* All rights reserved.
|
|
4
|
-
* Licensed under the BSD 3-Clause license.
|
|
5
|
-
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
-
*/
|
|
7
|
-
import { SfError } from '@salesforce/core';
|
|
8
|
-
export function getHeaders(keyValPair) {
|
|
9
|
-
const headers = {};
|
|
10
|
-
for (const header of keyValPair) {
|
|
11
|
-
const [key, ...rest] = header.split(':');
|
|
12
|
-
const value = rest.join(':').trim();
|
|
13
|
-
if (!key || !value) {
|
|
14
|
-
throw new SfError(`Failed to parse HTTP header: "${header}".`, 'Failed To Parse HTTP Header', [
|
|
15
|
-
'Make sure the header is in a "key:value" format, e.g. "Accept: application/json"',
|
|
16
|
-
]);
|
|
17
|
-
}
|
|
18
|
-
headers[key] = value;
|
|
19
|
-
}
|
|
20
|
-
return headers;
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=methods.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"methods.js","sourceRoot":"","sources":["../../src/shared/methods.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,MAAM,UAAU,UAAU,CAAC,UAAoB;IAC7C,MAAM,OAAO,GAA8B,EAAE,CAAC;IAE9C,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,OAAO,CAAC,iCAAiC,MAAM,IAAI,EAAE,6BAA6B,EAAE;gBAC5F,kFAAkF;aACnF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|