@salesforce/core 3.7.4 → 4.0.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/CHANGELOG.md +215 -0
- package/lib/config/configStore.js +2 -1
- package/lib/config/envVars.d.ts +20 -5
- package/lib/config/envVars.js +70 -5
- package/lib/crypto/keyChainImpl.js +0 -1
- package/lib/exported.d.ts +4 -2
- package/lib/exported.js +5 -1
- package/lib/lifecycleEvents.js +1 -1
- package/lib/logger.js +0 -1
- package/lib/org/authInfo.js +2 -3
- package/lib/org/connection.d.ts +6 -1
- package/lib/org/connection.js +13 -0
- package/lib/org/org.d.ts +12 -2
- package/lib/org/org.js +39 -36
- package/lib/org/scratchOrgCreate.d.ts +43 -0
- package/lib/org/scratchOrgCreate.js +142 -0
- package/lib/org/scratchOrgErrorCodes.d.ts +4 -0
- package/lib/org/scratchOrgErrorCodes.js +62 -0
- package/lib/org/scratchOrgFeatureDeprecation.d.ts +26 -0
- package/lib/org/scratchOrgFeatureDeprecation.js +110 -0
- package/lib/org/scratchOrgInfoApi.d.ts +94 -0
- package/lib/org/scratchOrgInfoApi.js +350 -0
- package/lib/org/scratchOrgInfoGenerator.d.ts +63 -0
- package/lib/org/scratchOrgInfoGenerator.js +223 -0
- package/lib/org/scratchOrgSettingsGenerator.d.ts +56 -0
- package/lib/org/scratchOrgSettingsGenerator.js +210 -0
- package/lib/org/user.js +4 -3
- package/lib/status/pollingClient.d.ts +2 -2
- package/lib/status/pollingClient.js +8 -2
- package/lib/status/streamingClient.d.ts +1 -1
- package/lib/util/jsonXmlTools.d.ts +14 -0
- package/lib/util/jsonXmlTools.js +41 -0
- package/lib/util/mapKeys.d.ts +14 -0
- package/lib/util/mapKeys.js +48 -0
- package/lib/util/zipWriter.d.ts +14 -0
- package/lib/util/zipWriter.js +68 -0
- package/lib/webOAuthServer.js +1 -1
- package/messages/envVars.md +53 -13
- package/messages/org.md +4 -0
- package/messages/scratchOrgCreate.md +27 -0
- package/messages/scratchOrgErrorCodes.md +99 -0
- package/messages/scratchOrgFeatureDeprecation.md +11 -0
- package/messages/scratchOrgInfoApi.md +11 -0
- package/messages/scratchOrgInfoGenerator.md +19 -0
- package/messages/user.md +4 -0
- package/package.json +5 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { JsonMap } from '@salesforce/ts-types';
|
|
2
|
+
import { ScratchOrgInfo } from './scratchOrgInfoApi';
|
|
3
|
+
import { Org } from './org';
|
|
4
|
+
export declare enum RequestStatus {
|
|
5
|
+
Pending = "Pending",
|
|
6
|
+
InProgress = "InProgress",
|
|
7
|
+
Succeeded = "Succeeded",
|
|
8
|
+
SucceededPartial = "SucceededPartial",
|
|
9
|
+
Failed = "Failed",
|
|
10
|
+
Canceling = "Canceling",
|
|
11
|
+
Canceled = "Canceled"
|
|
12
|
+
}
|
|
13
|
+
export interface ObjectSetting extends JsonMap {
|
|
14
|
+
sharingModel?: string;
|
|
15
|
+
defaultRecordType?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface BusinessProcessFileContent extends JsonMap {
|
|
18
|
+
fullName: string;
|
|
19
|
+
isActive: boolean;
|
|
20
|
+
values: [
|
|
21
|
+
{
|
|
22
|
+
fullName: string;
|
|
23
|
+
default?: boolean;
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
|
|
29
|
+
* settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
|
|
30
|
+
*/
|
|
31
|
+
export default class SettingsGenerator {
|
|
32
|
+
private settingData?;
|
|
33
|
+
private objectSettingsData?;
|
|
34
|
+
private logger;
|
|
35
|
+
private writer;
|
|
36
|
+
private shapeDirName;
|
|
37
|
+
constructor();
|
|
38
|
+
/** extract the settings from the scratch def file, if they are present. */
|
|
39
|
+
extract(scratchDef: ScratchOrgInfo): Promise<void>;
|
|
40
|
+
/** True if we are currently tracking setting or object setting data. */
|
|
41
|
+
hasSettings(): boolean;
|
|
42
|
+
/** Create temporary deploy directory used to upload the scratch org shape.
|
|
43
|
+
* This will create the dir, all of the .setting files and minimal object files needed for objectSettings
|
|
44
|
+
*/
|
|
45
|
+
createDeploy(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Deploys the settings to the org.
|
|
48
|
+
*/
|
|
49
|
+
deploySettingsViaFolder(scratchOrg: Org, apiVersion: string): Promise<void>;
|
|
50
|
+
private writeObjectSettingsIfNeeded;
|
|
51
|
+
private writeSettingsIfNeeded;
|
|
52
|
+
private createPackageXml;
|
|
53
|
+
private createObjectFileContent;
|
|
54
|
+
private createRecordTypeFileContent;
|
|
55
|
+
private createBusinessProcessFileContent;
|
|
56
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
* Licensed under the BSD 3-Clause license.
|
|
6
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RequestStatus = void 0;
|
|
10
|
+
const path = require("path");
|
|
11
|
+
const kit_1 = require("@salesforce/kit");
|
|
12
|
+
const ts_types_1 = require("@salesforce/ts-types");
|
|
13
|
+
const js2xmlparser = require("js2xmlparser");
|
|
14
|
+
const logger_1 = require("../logger");
|
|
15
|
+
const sfdxError_1 = require("../sfdxError");
|
|
16
|
+
const jsonXmlTools_1 = require("../util/jsonXmlTools");
|
|
17
|
+
const zipWriter_1 = require("../util/zipWriter");
|
|
18
|
+
const pollingClient_1 = require("../status/pollingClient");
|
|
19
|
+
var RequestStatus;
|
|
20
|
+
(function (RequestStatus) {
|
|
21
|
+
RequestStatus["Pending"] = "Pending";
|
|
22
|
+
RequestStatus["InProgress"] = "InProgress";
|
|
23
|
+
RequestStatus["Succeeded"] = "Succeeded";
|
|
24
|
+
RequestStatus["SucceededPartial"] = "SucceededPartial";
|
|
25
|
+
RequestStatus["Failed"] = "Failed";
|
|
26
|
+
RequestStatus["Canceling"] = "Canceling";
|
|
27
|
+
RequestStatus["Canceled"] = "Canceled";
|
|
28
|
+
})(RequestStatus = exports.RequestStatus || (exports.RequestStatus = {}));
|
|
29
|
+
const breakPolling = ['Succeeded', 'SucceededPartial', 'Failed', 'Canceled'];
|
|
30
|
+
/**
|
|
31
|
+
* Helper class for dealing with the settings that are defined in a scratch definition file. This class knows how to extract the
|
|
32
|
+
* settings from the definition, how to expand them into a MD directory and how to generate a package.xml.
|
|
33
|
+
*/
|
|
34
|
+
class SettingsGenerator {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.shapeDirName = `shape_${Date.now()}`;
|
|
37
|
+
this.logger = logger_1.Logger.childFromRoot('SettingsGenerator');
|
|
38
|
+
// If SFDX_MDAPI_TEMP_DIR is set, copy settings to that dir for people to inspect.
|
|
39
|
+
const mdapiTmpDir = kit_1.env.getString('SFDX_MDAPI_TEMP_DIR');
|
|
40
|
+
this.writer = new zipWriter_1.ZipWriter(mdapiTmpDir);
|
|
41
|
+
}
|
|
42
|
+
/** extract the settings from the scratch def file, if they are present. */
|
|
43
|
+
async extract(scratchDef) {
|
|
44
|
+
this.logger.debug('extracting settings from scratch definition file');
|
|
45
|
+
this.settingData = scratchDef.settings;
|
|
46
|
+
this.objectSettingsData = scratchDef.objectSettings;
|
|
47
|
+
this.logger.debug('settings are', this.settingData);
|
|
48
|
+
}
|
|
49
|
+
/** True if we are currently tracking setting or object setting data. */
|
|
50
|
+
hasSettings() {
|
|
51
|
+
return !(0, kit_1.isEmpty)(this.settingData) || !(0, kit_1.isEmpty)(this.objectSettingsData);
|
|
52
|
+
}
|
|
53
|
+
/** Create temporary deploy directory used to upload the scratch org shape.
|
|
54
|
+
* This will create the dir, all of the .setting files and minimal object files needed for objectSettings
|
|
55
|
+
*/
|
|
56
|
+
async createDeploy() {
|
|
57
|
+
const settingsDir = path.join(this.shapeDirName, 'settings');
|
|
58
|
+
const objectsDir = path.join(this.shapeDirName, 'objects');
|
|
59
|
+
await Promise.all([this.writeSettingsIfNeeded(settingsDir), this.writeObjectSettingsIfNeeded(objectsDir)]);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Deploys the settings to the org.
|
|
63
|
+
*/
|
|
64
|
+
async deploySettingsViaFolder(scratchOrg, apiVersion) {
|
|
65
|
+
const username = scratchOrg.getUsername();
|
|
66
|
+
const logger = await logger_1.Logger.child('deploySettingsViaFolder');
|
|
67
|
+
this.createPackageXml(apiVersion);
|
|
68
|
+
await this.writer.finalize();
|
|
69
|
+
const connection = scratchOrg.getConnection();
|
|
70
|
+
logger.debug(`deploying to apiVersion: ${apiVersion}`);
|
|
71
|
+
connection.setApiVersion(apiVersion);
|
|
72
|
+
const { id } = await connection.deploy(this.writer.buffer, {});
|
|
73
|
+
logger.debug(`deploying settings id ${id}`);
|
|
74
|
+
let result = await connection.metadata.checkDeployStatus(id);
|
|
75
|
+
const pollingOptions = {
|
|
76
|
+
async poll() {
|
|
77
|
+
try {
|
|
78
|
+
result = await connection.metadata.checkDeployStatus(id, true);
|
|
79
|
+
logger.debug(`Deploy id: ${id} status: ${result.status}`);
|
|
80
|
+
if (breakPolling.includes(result.status)) {
|
|
81
|
+
return {
|
|
82
|
+
completed: true,
|
|
83
|
+
payload: result.status,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
completed: false,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger.debug(`An error occurred trying to check deploy id: ${id}`);
|
|
92
|
+
logger.debug(`Error: ${error.message}`);
|
|
93
|
+
logger.debug('Re-trying deploy check again....');
|
|
94
|
+
return {
|
|
95
|
+
completed: false,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
timeout: kit_1.Duration.minutes(10),
|
|
100
|
+
frequency: kit_1.Duration.seconds(1),
|
|
101
|
+
timeoutErrorName: 'DeployingSettingsTimeoutError',
|
|
102
|
+
};
|
|
103
|
+
const client = await pollingClient_1.PollingClient.create(pollingOptions);
|
|
104
|
+
const status = await client.subscribe();
|
|
105
|
+
if (status !== RequestStatus.Succeeded) {
|
|
106
|
+
const componentFailures = (0, ts_types_1.ensureObject)(result.details).componentFailures;
|
|
107
|
+
const failures = (Array.isArray(componentFailures) ? componentFailures : [componentFailures])
|
|
108
|
+
.map((failure) => failure.problem)
|
|
109
|
+
.join('\n');
|
|
110
|
+
const error = new sfdxError_1.SfdxError(`A scratch org was created with username ${username}, but the settings failed to deploy due to: \n${failures}`, 'ProblemDeployingSettings');
|
|
111
|
+
error.setData(result);
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async writeObjectSettingsIfNeeded(objectsDir) {
|
|
116
|
+
if (!this.objectSettingsData || !Object.keys(this.objectSettingsData).length) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
for (const objectName of Object.keys(this.objectSettingsData)) {
|
|
120
|
+
const value = this.objectSettingsData[objectName];
|
|
121
|
+
// writes the object file in source format
|
|
122
|
+
const objectDir = path.join(objectsDir, (0, kit_1.upperFirst)(objectName));
|
|
123
|
+
const customObjectDir = path.join(objectDir, `${(0, kit_1.upperFirst)(objectName)}.object`);
|
|
124
|
+
const customObjectXml = (0, jsonXmlTools_1.JsonAsXml)({
|
|
125
|
+
json: this.createObjectFileContent(value),
|
|
126
|
+
type: 'RecordType',
|
|
127
|
+
});
|
|
128
|
+
this.writer.addToZip(customObjectXml, customObjectDir);
|
|
129
|
+
if (value.defaultRecordType) {
|
|
130
|
+
const recordTypesDir = path.join(objectDir, 'recordTypes', `${(0, kit_1.upperFirst)(value.defaultRecordType)}.recordType`);
|
|
131
|
+
const recordTypesFileContent = this.createRecordTypeFileContent(objectName, value);
|
|
132
|
+
const recordTypesXml = (0, jsonXmlTools_1.JsonAsXml)({
|
|
133
|
+
json: recordTypesFileContent,
|
|
134
|
+
type: 'RecordType',
|
|
135
|
+
});
|
|
136
|
+
this.writer.addToZip(recordTypesXml, recordTypesDir);
|
|
137
|
+
// for things that required a businessProcess
|
|
138
|
+
if (recordTypesFileContent.businessProcess) {
|
|
139
|
+
const businessProcessesDir = path.join(objectDir, 'businessProcesses', `${recordTypesFileContent.businessProcess}.businessProcess`);
|
|
140
|
+
const businessProcessesXml = (0, jsonXmlTools_1.JsonAsXml)({
|
|
141
|
+
json: this.createBusinessProcessFileContent(objectName, recordTypesFileContent.businessProcess),
|
|
142
|
+
type: 'BusinessProcess',
|
|
143
|
+
});
|
|
144
|
+
this.writer.addToZip(businessProcessesXml, businessProcessesDir);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async writeSettingsIfNeeded(settingsDir) {
|
|
150
|
+
if (this.settingData) {
|
|
151
|
+
for (const item of Object.keys(this.settingData)) {
|
|
152
|
+
const value = (0, ts_types_1.getObject)(this.settingData, item);
|
|
153
|
+
const typeName = (0, kit_1.upperFirst)(item);
|
|
154
|
+
const fname = typeName.replace('Settings', '');
|
|
155
|
+
const fileContent = js2xmlparser.parse(typeName, value);
|
|
156
|
+
this.writer.addToZip(fileContent, path.join(settingsDir, fname + '.settings'));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
createPackageXml(apiVersion) {
|
|
161
|
+
const pkg = `<?xml version="1.0" encoding="UTF-8"?>
|
|
162
|
+
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
163
|
+
<types>
|
|
164
|
+
<members>*</members>
|
|
165
|
+
<name>Settings</name>
|
|
166
|
+
</types>
|
|
167
|
+
<types>
|
|
168
|
+
<members>*</members>
|
|
169
|
+
<name>CustomObject</name>
|
|
170
|
+
</types>
|
|
171
|
+
<version>${apiVersion}</version>
|
|
172
|
+
</Package>`;
|
|
173
|
+
this.writer.addToZip(pkg, path.join(this.shapeDirName, 'package.xml'));
|
|
174
|
+
}
|
|
175
|
+
createObjectFileContent(json) {
|
|
176
|
+
const output = {};
|
|
177
|
+
if (json.sharingModel) {
|
|
178
|
+
output.sharingModel = (0, kit_1.upperFirst)(json.sharingModel);
|
|
179
|
+
}
|
|
180
|
+
return output;
|
|
181
|
+
}
|
|
182
|
+
createRecordTypeFileContent(objectName, setting) {
|
|
183
|
+
const defaultRecordType = (0, kit_1.upperFirst)(setting.defaultRecordType);
|
|
184
|
+
const output = {
|
|
185
|
+
fullName: defaultRecordType,
|
|
186
|
+
label: defaultRecordType,
|
|
187
|
+
active: true,
|
|
188
|
+
};
|
|
189
|
+
// all the edge cases
|
|
190
|
+
if (['Case', 'Lead', 'Opportunity', 'Solution'].includes((0, kit_1.upperFirst)(objectName))) {
|
|
191
|
+
return { ...output, businessProcess: `${defaultRecordType}Process` };
|
|
192
|
+
}
|
|
193
|
+
return output;
|
|
194
|
+
}
|
|
195
|
+
createBusinessProcessFileContent(objectName, businessProcessName) {
|
|
196
|
+
const objectToBusinessProcessPicklist = {
|
|
197
|
+
Opportunity: { fullName: 'Prospecting' },
|
|
198
|
+
Case: { fullName: 'New', default: true },
|
|
199
|
+
Lead: { fullName: 'New - Not Contacted', default: true },
|
|
200
|
+
Solution: { fullName: 'Draft', default: true },
|
|
201
|
+
};
|
|
202
|
+
return {
|
|
203
|
+
fullName: businessProcessName,
|
|
204
|
+
isActive: true,
|
|
205
|
+
values: [objectToBusinessProcessPicklist[(0, kit_1.upperFirst)(objectName)]],
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.default = SettingsGenerator;
|
|
210
|
+
//# sourceMappingURL=scratchOrgSettingsGenerator.js.map
|
package/lib/org/user.js
CHANGED
|
@@ -11,12 +11,12 @@ const os_1 = require("os");
|
|
|
11
11
|
const kit_1 = require("@salesforce/kit");
|
|
12
12
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
13
13
|
const http_api_1 = require("jsforce/lib/http-api");
|
|
14
|
-
const connection_1 = require("../org/connection");
|
|
15
14
|
const logger_1 = require("../logger");
|
|
16
15
|
const messages_1 = require("../messages");
|
|
17
16
|
const secureBuffer_1 = require("../crypto/secureBuffer");
|
|
18
17
|
const sfdxError_1 = require("../sfdxError");
|
|
19
18
|
const sfdc_1 = require("../util/sfdc");
|
|
19
|
+
const connection_1 = require("./connection");
|
|
20
20
|
const permissionSetAssignment_1 = require("./permissionSetAssignment");
|
|
21
21
|
const authInfo_1 = require("./authInfo");
|
|
22
22
|
const rand = (len) => Math.floor(Math.random() * len.length);
|
|
@@ -228,7 +228,6 @@ class User extends kit_1.AsyncCreatable {
|
|
|
228
228
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
229
229
|
password.value(async (buffer) => {
|
|
230
230
|
try {
|
|
231
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
232
231
|
// @ts-ignore TODO: expose `soap` on Connection however appropriate
|
|
233
232
|
const soap = userConnection.soap;
|
|
234
233
|
await soap.setPassword((0, ts_types_1.ensureString)(info.getFields().userId), buffer.toString('utf8'));
|
|
@@ -294,6 +293,7 @@ class User extends kit_1.AsyncCreatable {
|
|
|
294
293
|
* ```
|
|
295
294
|
*/
|
|
296
295
|
async createUser(fields) {
|
|
296
|
+
var _a;
|
|
297
297
|
// Create a user and get a refresh token
|
|
298
298
|
const refreshTokenSecret = await this.createUserInternal(fields);
|
|
299
299
|
// Create the initial auth info
|
|
@@ -301,7 +301,8 @@ class User extends kit_1.AsyncCreatable {
|
|
|
301
301
|
const adminUserAuthFields = authInfo.getFields(true);
|
|
302
302
|
// Setup oauth options for the new user
|
|
303
303
|
const oauthOptions = {
|
|
304
|
-
|
|
304
|
+
// Communities users require the instance for auth
|
|
305
|
+
loginUrl: (_a = adminUserAuthFields.instanceUrl) !== null && _a !== void 0 ? _a : adminUserAuthFields.loginUrl,
|
|
305
306
|
refreshToken: refreshTokenSecret.buffer.value((buffer) => buffer.toString('utf8')),
|
|
306
307
|
clientId: adminUserAuthFields.clientId,
|
|
307
308
|
clientSecret: adminUserAuthFields.clientSecret,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncOptionalCreatable, Duration } from '@salesforce/kit';
|
|
2
2
|
import { AnyJson } from '@salesforce/ts-types';
|
|
3
3
|
import { Logger } from '../logger';
|
|
4
|
-
import { StatusResult } from './
|
|
4
|
+
import { StatusResult } from './types';
|
|
5
5
|
/**
|
|
6
6
|
* This is a polling client that can be used to poll the status of long running tasks. It can be used as a replacement
|
|
7
7
|
* for Streaming when streaming topics are not available or when streaming handshakes are failing. Why wouldn't you
|
|
@@ -38,7 +38,7 @@ export declare class PollingClient extends AsyncOptionalCreatable<PollingClient.
|
|
|
38
38
|
* Returns a promise to call the specified polling function using the interval and timeout specified
|
|
39
39
|
* in the polling options.
|
|
40
40
|
*/
|
|
41
|
-
subscribe(): Promise<
|
|
41
|
+
subscribe<T = AnyJson>(): Promise<T>;
|
|
42
42
|
}
|
|
43
43
|
export declare namespace PollingClient {
|
|
44
44
|
/**
|
|
@@ -12,6 +12,7 @@ const ts_types_1 = require("@salesforce/ts-types");
|
|
|
12
12
|
const ts_retry_promise_1 = require("ts-retry-promise");
|
|
13
13
|
const logger_1 = require("../logger");
|
|
14
14
|
const sfdxError_1 = require("../sfdxError");
|
|
15
|
+
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
15
16
|
/**
|
|
16
17
|
* This is a polling client that can be used to poll the status of long running tasks. It can be used as a replacement
|
|
17
18
|
* for Streaming when streaming topics are not available or when streaming handshakes are failing. Why wouldn't you
|
|
@@ -60,9 +61,14 @@ class PollingClient extends kit_1.AsyncOptionalCreatable {
|
|
|
60
61
|
result = await this.options.poll();
|
|
61
62
|
}
|
|
62
63
|
catch (error) {
|
|
63
|
-
errorInPollingFunction = error;
|
|
64
|
+
const err = (errorInPollingFunction = error);
|
|
65
|
+
if (['ETIMEDOUT', 'ENOTFOUND', 'ECONNRESET', 'socket hang up'].some((retryableNetworkError) => err.message.includes(retryableNetworkError))) {
|
|
66
|
+
this.logger.debug('Network error on the request', err);
|
|
67
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emitWarning('Network error occurred. Continuing to poll.');
|
|
68
|
+
throw sfdxError_1.SfdxError.wrap(err);
|
|
69
|
+
}
|
|
64
70
|
// there was an actual error thrown, so we don't want to keep retrying
|
|
65
|
-
throw new ts_retry_promise_1.NotRetryableError(
|
|
71
|
+
throw new ts_retry_promise_1.NotRetryableError(err.name);
|
|
66
72
|
}
|
|
67
73
|
if (result.completed) {
|
|
68
74
|
return result.payload;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncOptionalCreatable, Duration, Env } from '@salesforce/kit/lib';
|
|
2
2
|
import { AnyJson } from '@salesforce/ts-types/lib';
|
|
3
|
-
import { Org } from '../org
|
|
3
|
+
import { Org } from '../org';
|
|
4
4
|
import { CometClient, CometSubscription, Message, StatusResult, StreamingExtension, StreamProcessor } from './types';
|
|
5
5
|
export { CometClient, CometSubscription, Message, StatusResult, StreamingExtension, StreamProcessor };
|
|
6
6
|
/**
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { JsonMap } from '@salesforce/ts-types';
|
|
2
|
+
import { IOptions } from 'js2xmlparser/lib/options';
|
|
3
|
+
export interface JSONasXML {
|
|
4
|
+
json: JsonMap;
|
|
5
|
+
type: string;
|
|
6
|
+
options?: IOptions;
|
|
7
|
+
}
|
|
8
|
+
export interface WriteJSONasXMLInputs extends JSONasXML {
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const standardOptions: IOptions;
|
|
12
|
+
export declare const writeJSONasXML: ({ path, json, type, options, }: WriteJSONasXMLInputs) => Promise<void>;
|
|
13
|
+
export declare const JsonAsXml: ({ json, type, options }: JSONasXML) => string;
|
|
14
|
+
export declare const fixExistingDollarSign: (existing: WriteJSONasXMLInputs['json']) => Record<string, unknown>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
* Licensed under the BSD 3-Clause license.
|
|
6
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.fixExistingDollarSign = exports.JsonAsXml = exports.writeJSONasXML = exports.standardOptions = void 0;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const jsToXml = require("js2xmlparser");
|
|
12
|
+
exports.standardOptions = {
|
|
13
|
+
declaration: {
|
|
14
|
+
include: true,
|
|
15
|
+
encoding: 'UTF-8',
|
|
16
|
+
version: '1.0',
|
|
17
|
+
},
|
|
18
|
+
format: {
|
|
19
|
+
doubleQuotes: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const writeJSONasXML = async ({ path, json, type, options = exports.standardOptions, }) => {
|
|
23
|
+
const xml = jsToXml.parse(type, (0, exports.fixExistingDollarSign)(json), options);
|
|
24
|
+
return await fs_1.promises.writeFile(path, xml);
|
|
25
|
+
};
|
|
26
|
+
exports.writeJSONasXML = writeJSONasXML;
|
|
27
|
+
const JsonAsXml = ({ json, type, options = exports.standardOptions }) => {
|
|
28
|
+
return jsToXml.parse(type, (0, exports.fixExistingDollarSign)(json), options);
|
|
29
|
+
};
|
|
30
|
+
exports.JsonAsXml = JsonAsXml;
|
|
31
|
+
const fixExistingDollarSign = (existing) => {
|
|
32
|
+
const existingCopy = { ...existing };
|
|
33
|
+
if (existingCopy.$) {
|
|
34
|
+
const temp = existingCopy.$;
|
|
35
|
+
delete existingCopy.$;
|
|
36
|
+
existingCopy['@'] = temp;
|
|
37
|
+
}
|
|
38
|
+
return existingCopy;
|
|
39
|
+
};
|
|
40
|
+
exports.fixExistingDollarSign = fixExistingDollarSign;
|
|
41
|
+
//# sourceMappingURL=jsonXmlTools.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Use mapKeys to convert object keys to another format using the specified conversion function.
|
|
3
|
+
*
|
|
4
|
+
* E.g., to deep convert all object keys to camelCase: mapKeys(myObj, _.camelCase, true)
|
|
5
|
+
* to shallow convert object keys to lower case: mapKeys(myObj, _.toLower)
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This mutates the object passed in for conversion.
|
|
8
|
+
*
|
|
9
|
+
* @param target - {Object} The object to convert the keys
|
|
10
|
+
* @param converter - {Function} The function that converts the object key
|
|
11
|
+
* @param deep - {boolean} Whether to do a deep object key conversion
|
|
12
|
+
* @return {Object} - the object with the converted keys
|
|
13
|
+
*/
|
|
14
|
+
export default function mapKeys(obj: any, converter: (key: string) => string, deep?: boolean): Record<string, unknown>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
* Licensed under the BSD 3-Clause license.
|
|
6
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const ts_types_1 = require("@salesforce/ts-types");
|
|
10
|
+
/**
|
|
11
|
+
* Use mapKeys to convert object keys to another format using the specified conversion function.
|
|
12
|
+
*
|
|
13
|
+
* E.g., to deep convert all object keys to camelCase: mapKeys(myObj, _.camelCase, true)
|
|
14
|
+
* to shallow convert object keys to lower case: mapKeys(myObj, _.toLower)
|
|
15
|
+
*
|
|
16
|
+
* NOTE: This mutates the object passed in for conversion.
|
|
17
|
+
*
|
|
18
|
+
* @param target - {Object} The object to convert the keys
|
|
19
|
+
* @param converter - {Function} The function that converts the object key
|
|
20
|
+
* @param deep - {boolean} Whether to do a deep object key conversion
|
|
21
|
+
* @return {Object} - the object with the converted keys
|
|
22
|
+
*/
|
|
23
|
+
function mapKeys(
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
25
|
+
obj, converter, deep) {
|
|
26
|
+
const target = Object.assign({}, obj);
|
|
27
|
+
return Object.fromEntries(Object.entries(target).map(([key, value]) => {
|
|
28
|
+
const k = converter.call(null, key);
|
|
29
|
+
if (deep) {
|
|
30
|
+
let v = value;
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
v = value.map((v1) => {
|
|
33
|
+
if ((0, ts_types_1.isPlainObject)(v1)) {
|
|
34
|
+
return mapKeys(v1, converter, deep);
|
|
35
|
+
}
|
|
36
|
+
return v1;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else if ((0, ts_types_1.isPlainObject)(value)) {
|
|
40
|
+
v = mapKeys(value, converter, deep);
|
|
41
|
+
}
|
|
42
|
+
return [k, v];
|
|
43
|
+
}
|
|
44
|
+
return [k, value];
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
exports.default = mapKeys;
|
|
48
|
+
//# sourceMappingURL=mapKeys.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { pipeline as cbPipeline, Readable, Writable } from 'stream';
|
|
3
|
+
export declare const pipeline: typeof cbPipeline.__promisify__;
|
|
4
|
+
export declare class ZipWriter extends Writable {
|
|
5
|
+
private rootDestination?;
|
|
6
|
+
private zip;
|
|
7
|
+
private buffers;
|
|
8
|
+
constructor(rootDestination?: string | undefined);
|
|
9
|
+
addToZip(contents: string | Readable | Buffer, path: string): void;
|
|
10
|
+
finalize(): Promise<void>;
|
|
11
|
+
private getOutputStream;
|
|
12
|
+
private getInputBuffer;
|
|
13
|
+
get buffer(): Buffer;
|
|
14
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
4
|
+
* All rights reserved.
|
|
5
|
+
* Licensed under the BSD 3-Clause license.
|
|
6
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ZipWriter = exports.pipeline = void 0;
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
|
+
const stream_1 = require("stream");
|
|
12
|
+
const util_1 = require("util");
|
|
13
|
+
const archiver_1 = require("archiver");
|
|
14
|
+
exports.pipeline = (0, util_1.promisify)(stream_1.pipeline);
|
|
15
|
+
class ZipWriter extends stream_1.Writable {
|
|
16
|
+
constructor(rootDestination) {
|
|
17
|
+
super({ objectMode: true });
|
|
18
|
+
this.rootDestination = rootDestination;
|
|
19
|
+
// compression-/speed+ (0)<---(3)---------->(9) compression+/speed-
|
|
20
|
+
// 3 appears to be a decent balance of compression and speed. It felt like
|
|
21
|
+
// higher values = diminishing returns on compression and made conversion slower
|
|
22
|
+
this.zip = (0, archiver_1.create)('zip', { zlib: { level: 3 } });
|
|
23
|
+
this.buffers = [];
|
|
24
|
+
void (0, exports.pipeline)(this.zip, this.getOutputStream());
|
|
25
|
+
}
|
|
26
|
+
addToZip(contents, path) {
|
|
27
|
+
this.zip.append(contents, { name: path });
|
|
28
|
+
}
|
|
29
|
+
async finalize() {
|
|
30
|
+
await this.zip.finalize();
|
|
31
|
+
await this.getInputBuffer();
|
|
32
|
+
}
|
|
33
|
+
getOutputStream() {
|
|
34
|
+
if (this.rootDestination) {
|
|
35
|
+
return (0, fs_1.createWriteStream)(this.rootDestination);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const bufferWritable = new stream_1.Writable();
|
|
39
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
40
|
+
bufferWritable._write = (chunk, encoding, cb) => {
|
|
41
|
+
this.buffers.push(chunk);
|
|
42
|
+
cb();
|
|
43
|
+
};
|
|
44
|
+
return bufferWritable;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async getInputBuffer() {
|
|
48
|
+
if (this.rootDestination) {
|
|
49
|
+
const inputStream = (0, fs_1.createReadStream)(this.rootDestination);
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
inputStream.on('data', (chunk) => {
|
|
52
|
+
this.buffers.push(chunk);
|
|
53
|
+
});
|
|
54
|
+
inputStream.once('end', () => {
|
|
55
|
+
return resolve();
|
|
56
|
+
});
|
|
57
|
+
inputStream.once('error', (error) => {
|
|
58
|
+
return reject(error);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
get buffer() {
|
|
64
|
+
return Buffer.concat(this.buffers);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.ZipWriter = ZipWriter;
|
|
68
|
+
//# sourceMappingURL=zipWriter.js.map
|
package/lib/webOAuthServer.js
CHANGED
|
@@ -144,7 +144,7 @@ class WebOAuthServer extends kit_1.AsyncCreatable {
|
|
|
144
144
|
async executeOauthRequest() {
|
|
145
145
|
return new Promise((resolve, reject) => {
|
|
146
146
|
this.logger.debug('Starting web auth flow');
|
|
147
|
-
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
147
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises, @typescript-eslint/no-explicit-any
|
|
148
148
|
this.webServer.server.on('request', async (request, response) => {
|
|
149
149
|
const url = (0, url_1.parse)(request.url);
|
|
150
150
|
this.logger.debug(`processing request for uri: ${url.pathname}`);
|