@salesforce/plugin-api 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -61
- 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 +44 -0
- package/messages/rest.md +4 -14
- package/messages/shared.md +7 -0
- package/npm-shrinkwrap.json +3 -2
- package/oclif.manifest.json +102 -2
- 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,13 +59,68 @@ 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
|
|
|
65
|
+
## `sf api request graphql`
|
|
66
|
+
|
|
67
|
+
Execute GraphQL statements
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
USAGE
|
|
71
|
+
$ sf api request graphql -o <value> --body file [--json] [--flags-dir <value>] [--api-version <value>] [-S Example:
|
|
72
|
+
report.xlsx | -i]
|
|
73
|
+
|
|
74
|
+
FLAGS
|
|
75
|
+
-S, --stream-to-file=Example: report.xlsx Stream responses to a file.
|
|
76
|
+
-i, --include Include the HTTP response status and headers in the output.
|
|
77
|
+
-o, --target-org=<value> (required) Username or alias of the target org. Not required if the
|
|
78
|
+
`target-org` configuration variable is already set.
|
|
79
|
+
--api-version=<value> Override the api version used for api requests made by this command
|
|
80
|
+
--body=file (required) File or content with GraphQL statement. Specify "-" to read from
|
|
81
|
+
standard input.
|
|
82
|
+
|
|
83
|
+
GLOBAL FLAGS
|
|
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)
|
|
92
|
+
|
|
93
|
+
EXAMPLES
|
|
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
|
+
mutation AccountExample{
|
|
98
|
+
uiapi {
|
|
99
|
+
AccountCreate(input: {
|
|
100
|
+
Account: {
|
|
101
|
+
Name: "Trailblazer Express"
|
|
102
|
+
}
|
|
103
|
+
}) {
|
|
104
|
+
Record {
|
|
105
|
+
Id
|
|
106
|
+
Name {
|
|
107
|
+
value
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
$ sf api request graphql --body example.txt
|
|
114
|
+
will create a new account returning specified fields (Id, Name)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
_See code: [src/commands/api/request/graphql.ts](https://github.com/salesforcecli/plugin-api/blob/1.2.1/src/commands/api/request/graphql.ts)_
|
|
118
|
+
|
|
112
119
|
## `sf api request rest ENDPOINT`
|
|
113
120
|
|
|
114
121
|
Make an authenticated HTTP request to Salesforce REST API and print the response.
|
|
115
122
|
|
|
116
|
-
|
|
123
|
+
```
|
|
117
124
|
USAGE
|
|
118
125
|
$ sf api request rest ENDPOINT -o <value> [--flags-dir <value>] [--api-version <value>] [-i | -S Example:
|
|
119
126
|
report.xlsx] [-X GET|POST|PUT|PATCH|HEAD|DELETE|OPTIONS|TRACE] [-H key:value...] [--body file]
|
|
@@ -146,20 +153,19 @@ EXAMPLES
|
|
|
146
153
|
- POST to create an Account object
|
|
147
154
|
sf api request rest 'sobjects/account' --body "{\"Name\" : \"Account from REST API\",\"ShippingCity\" : \"Boise\"}" --method POST
|
|
148
155
|
- or with a file 'info.json' containing
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
156
|
+
{
|
|
157
|
+
"Name": "Demo",
|
|
158
|
+
"ShippingCity": "Boise"
|
|
159
|
+
}
|
|
160
|
+
$ sf api request rest 'sobjects/account' --body info.json --method POST
|
|
161
|
+
- Update object
|
|
162
|
+
sf api request rest 'sobjects/account/<Account ID>' --body "{\"BillingCity\": \"San Francisco\"}" --method PATCH
|
|
163
|
+
```
|
|
155
164
|
|
|
156
|
-
|
|
165
|
+
_See code: [src/commands/api/request/rest.ts](https://github.com/salesforcecli/plugin-api/blob/1.2.1/src/commands/api/request/rest.ts)_
|
|
157
166
|
|
|
158
|
-
|
|
159
|
-
sf api request rest 'sobjects/account/<Account ID>' --body "{\"BillingCity\": \"San Francisco\"}" --method PATCH
|
|
167
|
+
<!-- commandsstop -->
|
|
160
168
|
|
|
161
169
|
```
|
|
162
170
|
|
|
163
|
-
_See code: [src/commands/api/request/rest.ts](https://github.com/salesforcecli/plugin-api/blob/0.1.0/src/commands/api/request/rest.ts)_
|
|
164
|
-
<!-- commandsstop -->
|
|
165
171
|
```
|
|
@@ -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":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE3G,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;AAEzE,MAAM,OAAO,IAAK,SAAQ,SAAe;IAChC,MAAM,CAAU,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,CAAU,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;IAC9B,MAAM,CAAU,KAAK,GAAG;QAC7B,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE;QACjC,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;QACpC,OAAO,EAAE,WAAW;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAU;YACvF,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;YACpD,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,KAAK;SACf,CAAC,EAAE;QACJ,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YACnB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;YACpD,SAAS,EAAE,WAAW;YACtB,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;SACf,CAAC;QACF,gBAAgB,EAAE,gBAAgB;QAClC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YACjB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAClD,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,MAAM;SAClB,CAAC;KACH,CAAC;IAEK,MAAM,CAAC,IAAI,GAAG;QACnB,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;YACpB,WAAW,EAAE,yBAAyB;YACtC,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/C,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE7D,wCAAwC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAChG,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,GAAG,GAAG,CAAC,QAAQ,CAAS,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,mBAC9C,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,qBAAqB,EAAE,CAC5D,IAAI,QAAQ,EAAE,CACf,CAAC;QAEF,MAAM,IAAI,GACR,KAAK,CAAC,MAAM,KAAK,KAAK;YACpB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,sDAAsD;gBACxD,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;oBACjD,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;oBACrD,CAAC,CAAC,iDAAiD;wBACjD,KAAK,CAAC,IAAI,CAAC;QAEjB,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QAExB,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,EAAE;YAClC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE;gBACP,GAAG,iBAAiB;gBACpB,aAAa,EAAE,UAAU;gBACvB,0EAA0E;gBAC1E,iEAAiE;gBACjE,GAAG,CAAC,aAAa,EAAE,CAAC,oBAAoB,EAAE,CAAC,WAC7C,EAAE;gBACF,GAAG,OAAO;aACX;YACD,IAAI;YACJ,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;SACtB,CAAC;QAEF,MAAM,mBAAmB,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9F,CAAC"}
|
|
@@ -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,44 @@
|
|
|
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
|
+
mutation AccountExample{
|
|
18
|
+
uiapi {
|
|
19
|
+
AccountCreate(input: {
|
|
20
|
+
Account: {
|
|
21
|
+
Name: "Trailblazer Express"
|
|
22
|
+
}
|
|
23
|
+
}) {
|
|
24
|
+
Record {
|
|
25
|
+
Id
|
|
26
|
+
Name {
|
|
27
|
+
value
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
<%= config.bin %> <%= command.id %> --body example.txt
|
|
35
|
+
|
|
36
|
+
will create a new account returning specified fields (Id, Name)
|
|
37
|
+
|
|
38
|
+
# flags.header.summary
|
|
39
|
+
|
|
40
|
+
HTTP header in "key:value" format.
|
|
41
|
+
|
|
42
|
+
# flags.body.summary
|
|
43
|
+
|
|
44
|
+
File or content with GraphQL statement. Specify "-" to read from standard input.
|
package/messages/rest.md
CHANGED
|
@@ -22,12 +22,10 @@ Make an authenticated HTTP request to Salesforce REST API and print the response
|
|
|
22
22
|
|
|
23
23
|
- or with a file 'info.json' containing
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
```
|
|
25
|
+
{
|
|
26
|
+
"Name": "Demo",
|
|
27
|
+
"ShippingCity": "Boise"
|
|
28
|
+
}
|
|
31
29
|
|
|
32
30
|
<%= config.bin %> <%= command.id %> 'sobjects/account' --body info.json --method POST
|
|
33
31
|
|
|
@@ -35,10 +33,6 @@ Make an authenticated HTTP request to Salesforce REST API and print the response
|
|
|
35
33
|
|
|
36
34
|
<%= config.bin %> <%= command.id %> 'sobjects/account/<Account ID>' --body "{\"BillingCity\": \"San Francisco\"}" --method PATCH
|
|
37
35
|
|
|
38
|
-
# flags.include.summary
|
|
39
|
-
|
|
40
|
-
Include the HTTP response status and headers in the output.
|
|
41
|
-
|
|
42
36
|
# flags.method.summary
|
|
43
37
|
|
|
44
38
|
HTTP method for the request.
|
|
@@ -47,10 +41,6 @@ HTTP method for the request.
|
|
|
47
41
|
|
|
48
42
|
HTTP header in "key:value" format.
|
|
49
43
|
|
|
50
|
-
# flags.stream-to-file.summary
|
|
51
|
-
|
|
52
|
-
Stream responses to a file.
|
|
53
|
-
|
|
54
44
|
# flags.body.summary
|
|
55
45
|
|
|
56
46
|
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.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@salesforce/plugin-api",
|
|
9
|
-
"version": "1.1
|
|
9
|
+
"version": "1.2.1",
|
|
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 mutation 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<%= 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": {
|
|
@@ -10,7 +110,7 @@
|
|
|
10
110
|
}
|
|
11
111
|
},
|
|
12
112
|
"examples": [
|
|
13
|
-
"- List information about limits in the org with alias \"my-org\":\n\n <%= config.bin %> <%= command.id %> 'limits' --target-org my-org\n\n- List all endpoints\n\n <%= config.bin %> <%= command.id %> '/'\n\n- Get the response in XML format by specifying the \"Accept\" HTTP header:\n\n <%= config.bin %> <%= command.id %> 'limits' --target-org my-org --header 'Accept: application/xml'\n\n- POST to create an Account object\n\n <%= config.bin %> <%= command.id %> 'sobjects/account' --body \"{\\\"Name\\\" : \\\"Account from REST API\\\",\\\"ShippingCity\\\" : \\\"Boise\\\"}\" --method POST\n\n- or with a file 'info.json' containing\n\n
|
|
113
|
+
"- List information about limits in the org with alias \"my-org\":\n\n <%= config.bin %> <%= command.id %> 'limits' --target-org my-org\n\n- List all endpoints\n\n <%= config.bin %> <%= command.id %> '/'\n\n- Get the response in XML format by specifying the \"Accept\" HTTP header:\n\n <%= config.bin %> <%= command.id %> 'limits' --target-org my-org --header 'Accept: application/xml'\n\n- POST to create an Account object\n\n <%= config.bin %> <%= command.id %> 'sobjects/account' --body \"{\\\"Name\\\" : \\\"Account from REST API\\\",\\\"ShippingCity\\\" : \\\"Boise\\\"}\" --method POST\n\n- or with a file 'info.json' containing\n\n {\n \"Name\": \"Demo\",\n \"ShippingCity\": \"Boise\"\n }\n\n<%= config.bin %> <%= command.id %> 'sobjects/account' --body info.json --method POST\n\n- Update object\n\n <%= config.bin %> <%= command.id %> 'sobjects/account/<Account ID>' --body \"{\\\"BillingCity\\\": \\\"San Francisco\\\"}\" --method PATCH"
|
|
14
114
|
],
|
|
15
115
|
"flags": {
|
|
16
116
|
"flags-dir": {
|
|
@@ -126,5 +226,5 @@
|
|
|
126
226
|
]
|
|
127
227
|
}
|
|
128
228
|
},
|
|
129
|
-
"version": "1.1
|
|
229
|
+
"version": "1.2.1"
|
|
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.1
|
|
4
|
+
"version": "1.2.1",
|
|
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.1.
|
|
205
|
-
"signatureUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.1.
|
|
205
|
+
"publicKeyUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.2.1.crt",
|
|
206
|
+
"signatureUrl": "https://developer.salesforce.com/media/salesforce-cli/security/@salesforce/plugin-api/1.2.1.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"}
|