@salesforce/core 3.7.5 → 3.7.8
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 +219 -0
- package/README.md +4 -4
- package/lib/config/config.d.ts +7 -5
- package/lib/config/config.js +14 -9
- package/lib/config/configAggregator.d.ts +2 -2
- package/lib/config/configAggregator.js +2 -2
- package/lib/config/configFile.d.ts +2 -2
- package/lib/config/configFile.js +22 -20
- package/lib/config/configStore.js +7 -6
- package/lib/config/keychainConfig.js +4 -3
- package/lib/crypto/keyChainImpl.js +12 -11
- package/lib/deviceOauthService.js +2 -2
- package/lib/exported.d.ts +6 -5
- package/lib/exported.js +11 -7
- package/lib/global.js +2 -2
- package/lib/globalInfo/accessors/aliasAccessor.js +2 -2
- package/lib/globalInfo/sfdxDataHandler.d.ts +1 -1
- package/lib/globalInfo/sfdxDataHandler.js +5 -4
- package/lib/lifecycleEvents.js +1 -1
- package/lib/logger.d.ts +3 -3
- package/lib/logger.js +20 -19
- package/lib/messages.d.ts +42 -3
- package/lib/messages.js +55 -12
- package/lib/org/authInfo.d.ts +1 -1
- package/lib/org/authInfo.js +8 -9
- package/lib/org/authRemover.d.ts +2 -2
- package/lib/org/authRemover.js +2 -2
- package/lib/org/connection.d.ts +7 -2
- package/lib/org/connection.js +17 -4
- package/lib/org/org.d.ts +16 -6
- package/lib/org/org.js +54 -51
- package/lib/org/permissionSetAssignment.js +2 -2
- 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 +8 -7
- package/lib/schema/printer.js +2 -2
- package/lib/schema/validator.d.ts +4 -4
- package/lib/schema/validator.js +13 -13
- package/lib/{sfdxError.d.ts → sfError.d.ts} +14 -14
- package/lib/{sfdxError.js → sfError.js} +20 -21
- package/lib/{sfdxProject.d.ts → sfProject.d.ts} +37 -27
- package/lib/{sfdxProject.js → sfProject.js} +77 -65
- package/lib/status/pollingClient.d.ts +2 -2
- package/lib/status/pollingClient.js +10 -4
- package/lib/status/streamingClient.d.ts +1 -1
- package/lib/status/streamingClient.js +6 -6
- package/lib/testSetup.d.ts +4 -4
- package/lib/testSetup.js +8 -8
- package/lib/util/internal.d.ts +28 -2
- package/lib/util/internal.js +64 -6
- 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/sfdcUrl.d.ts +2 -2
- package/lib/util/sfdcUrl.js +2 -2
- package/lib/util/zipWriter.d.ts +14 -0
- package/lib/util/zipWriter.js +68 -0
- package/lib/webOAuthServer.js +11 -11
- 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 +4 -1
- package/lib/util/fs.d.ts +0 -201
- package/lib/util/fs.js +0 -378
package/lib/messages.js
CHANGED
|
@@ -13,7 +13,7 @@ const path = require("path");
|
|
|
13
13
|
const util = require("util");
|
|
14
14
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
15
15
|
const kit_1 = require("@salesforce/kit");
|
|
16
|
-
const
|
|
16
|
+
const sfError_1 = require("./sfError");
|
|
17
17
|
class Key {
|
|
18
18
|
constructor(packageName, bundleName) {
|
|
19
19
|
this.packageName = packageName;
|
|
@@ -57,7 +57,7 @@ const markdownLoader = (filePath, fileContents) => {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
60
|
-
// use error instead of
|
|
60
|
+
// use error instead of SfError because messages.js should have no internal dependencies.
|
|
61
61
|
throw new Error(`Invalid markdown message file: ${filePath}\nThe line "# <key>" must be immediately followed by the message on a new line.`);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -217,7 +217,7 @@ class Messages {
|
|
|
217
217
|
if (!fileContents || fileContents.trim().length === 0) {
|
|
218
218
|
// messages.js should have no internal dependencies.
|
|
219
219
|
const error = new Error(`Invalid message file: ${filePath}. No content.`);
|
|
220
|
-
error.name = '
|
|
220
|
+
error.name = 'SfError';
|
|
221
221
|
throw error;
|
|
222
222
|
}
|
|
223
223
|
const map = parser(filePath, fileContents);
|
|
@@ -438,25 +438,68 @@ class Messages {
|
|
|
438
438
|
* @param key The key of the error message.
|
|
439
439
|
* @param tokens The error message tokens.
|
|
440
440
|
* @param actionTokens The action messages tokens.
|
|
441
|
-
* @param exitCodeOrCause The exit code which will be used by SfdxCommand or
|
|
441
|
+
* @param exitCodeOrCause The exit code which will be used by SfdxCommand or the underlying error that caused this error to be raised.
|
|
442
442
|
* @param cause The underlying error that caused this error to be raised.
|
|
443
443
|
*/
|
|
444
444
|
createError(key, tokens = [], actionTokens = [], exitCodeOrCause, cause) {
|
|
445
|
+
const structuredMessage = this.formatMessageContents('error', key, tokens, actionTokens);
|
|
446
|
+
return new sfError_1.SfError(structuredMessage.message, structuredMessage.name, structuredMessage.actions, exitCodeOrCause, cause);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Convenience method to create warning using message labels.
|
|
450
|
+
*
|
|
451
|
+
* `warning.name` will be the upper-cased key, remove prefixed `warning.` and will always end in Warning.
|
|
452
|
+
* `warning.actions` will be loaded using `${key}.actions` if available.
|
|
453
|
+
*
|
|
454
|
+
* @param key The key of the warning message.
|
|
455
|
+
* @param tokens The warning message tokens.
|
|
456
|
+
* @param actionTokens The action messages tokens.
|
|
457
|
+
*/
|
|
458
|
+
createWarning(key, tokens = [], actionTokens = []) {
|
|
459
|
+
return this.formatMessageContents('warning', key, tokens, actionTokens);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Convenience method to create info using message labels.
|
|
463
|
+
*
|
|
464
|
+
* `info.name` will be the upper-cased key, remove prefixed `info.` and will always end in Info.
|
|
465
|
+
* `info.actions` will be loaded using `${key}.actions` if available.
|
|
466
|
+
*
|
|
467
|
+
* @param key The key of the warning message.
|
|
468
|
+
* @param tokens The warning message tokens.
|
|
469
|
+
* @param actionTokens The action messages tokens.
|
|
470
|
+
*/
|
|
471
|
+
createInfo(key, tokens = [], actionTokens = []) {
|
|
472
|
+
return this.formatMessageContents('info', key, tokens, actionTokens);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Formats message contents given a message type, key, tokens and actions tokens
|
|
476
|
+
*
|
|
477
|
+
* `<type>.name` will be the upper-cased key, remove prefixed `<type>.` and will always end in 'Error | Warning | Info.
|
|
478
|
+
* `<type>.actions` will be loaded using `${key}.actions` if available.
|
|
479
|
+
*
|
|
480
|
+
* @param type The type of the message set must 'error' | 'warning' | 'info'.
|
|
481
|
+
* @param key The key of the warning message.
|
|
482
|
+
* @param tokens The warning message tokens.
|
|
483
|
+
* @param actionTokens The action messages tokens.
|
|
484
|
+
*/
|
|
485
|
+
formatMessageContents(type, key, tokens = [], actionTokens = []) {
|
|
486
|
+
const label = (0, kit_1.upperFirst)(type);
|
|
487
|
+
const labelRegExp = new RegExp(`${label}$`);
|
|
488
|
+
const searchValue = type === 'error' ? /^error.*\./ : new RegExp(`^${type}.`);
|
|
445
489
|
// Convert key to name:
|
|
446
|
-
// 'myMessage' -> `
|
|
490
|
+
// 'myMessage' -> `MyMessageWarning`
|
|
447
491
|
// 'myMessageError' -> `MyMessageError`
|
|
448
|
-
// '
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
let errActions;
|
|
492
|
+
// 'warning.myMessage' -> `MyMessageWarning`
|
|
493
|
+
const name = `${(0, kit_1.upperFirst)(key.replace(searchValue, ''))}${labelRegExp.exec(key) ? '' : label}`;
|
|
494
|
+
const message = this.getMessage(key, tokens);
|
|
495
|
+
let actions;
|
|
453
496
|
try {
|
|
454
|
-
|
|
497
|
+
actions = this.getMessageWithMap(`${key}.actions`, actionTokens, this.messages);
|
|
455
498
|
}
|
|
456
499
|
catch (e) {
|
|
457
500
|
/* just ignore if actions aren't found */
|
|
458
501
|
}
|
|
459
|
-
return
|
|
502
|
+
return { message, name, actions };
|
|
460
503
|
}
|
|
461
504
|
getMessageWithMap(key, tokens = [], map) {
|
|
462
505
|
// Allow nested keys for better grouping
|
package/lib/org/authInfo.d.ts
CHANGED
|
@@ -253,7 +253,7 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
|
|
|
253
253
|
*
|
|
254
254
|
* @param options Options to be used for creating an OAuth2 instance.
|
|
255
255
|
*
|
|
256
|
-
* **Throws** *{@link
|
|
256
|
+
* **Throws** *{@link SfError}{ name: 'NamedOrgNotFoundError' }* Org information does not exist.
|
|
257
257
|
* @returns {Promise<AuthInfo>}
|
|
258
258
|
*/
|
|
259
259
|
private initAuthOptions;
|
package/lib/org/authInfo.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthInfo = exports.DEFAULT_CONNECTED_APP_INFO = void 0;
|
|
2
4
|
/*
|
|
3
5
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
4
6
|
* All rights reserved.
|
|
5
7
|
* Licensed under the BSD 3-Clause license.
|
|
6
8
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
9
|
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.AuthInfo = exports.DEFAULT_CONNECTED_APP_INFO = void 0;
|
|
10
|
-
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
11
10
|
const crypto_1 = require("crypto");
|
|
12
11
|
const path_1 = require("path");
|
|
13
12
|
const os = require("os");
|
|
13
|
+
const fs = require("fs");
|
|
14
14
|
const kit_1 = require("@salesforce/kit");
|
|
15
15
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
16
16
|
const jsforce_1 = require("jsforce");
|
|
@@ -19,8 +19,7 @@ const jwt = require("jsonwebtoken");
|
|
|
19
19
|
const config_1 = require("../config/config");
|
|
20
20
|
const configAggregator_1 = require("../config/configAggregator");
|
|
21
21
|
const logger_1 = require("../logger");
|
|
22
|
-
const
|
|
23
|
-
const fs_1 = require("../util/fs");
|
|
22
|
+
const sfError_1 = require("../sfError");
|
|
24
23
|
const sfdc_1 = require("../util/sfdc");
|
|
25
24
|
const globalInfo_1 = require("../globalInfo");
|
|
26
25
|
const messages_1 = require("../messages");
|
|
@@ -237,7 +236,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
237
236
|
static parseSfdxAuthUrl(sfdxAuthUrl) {
|
|
238
237
|
const match = sfdxAuthUrl.match(/^force:\/\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]*):([a-zA-Z0-9._-]+={0,2})@([a-zA-Z0-9._-]+)/);
|
|
239
238
|
if (!match) {
|
|
240
|
-
throw new
|
|
239
|
+
throw new sfError_1.SfError('Invalid SFDX auth URL. Must be in the format "force://<clientId>:<clientSecret>:<refreshToken>@<instanceUrl>". Note that the SFDX auth URL uses the "force" protocol, and not "http" or "https". Also note that the "instanceUrl" inside the SFDX auth URL doesn\'t include the protocol ("https://").', 'INVALID_SFDX_AUTH_URL');
|
|
241
240
|
}
|
|
242
241
|
const [, clientId, clientSecret, refreshToken, loginUrl] = match;
|
|
243
242
|
return {
|
|
@@ -490,7 +489,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
490
489
|
*
|
|
491
490
|
* @param options Options to be used for creating an OAuth2 instance.
|
|
492
491
|
*
|
|
493
|
-
* **Throws** *{@link
|
|
492
|
+
* **Throws** *{@link SfError}{ name: 'NamedOrgNotFoundError' }* Org information does not exist.
|
|
494
493
|
* @returns {Promise<AuthInfo>}
|
|
495
494
|
*/
|
|
496
495
|
async initAuthOptions(options) {
|
|
@@ -585,7 +584,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
585
584
|
}
|
|
586
585
|
// Build OAuth config for a JWT auth flow
|
|
587
586
|
async buildJwtConfig(options) {
|
|
588
|
-
const privateKeyContents = await
|
|
587
|
+
const privateKeyContents = await fs.promises.readFile((0, ts_types_1.ensure)(options.privateKey), 'utf8');
|
|
589
588
|
const { loginUrl = sfdcUrl_1.SfdcUrl.PRODUCTION } = options;
|
|
590
589
|
const url = new sfdcUrl_1.SfdcUrl(loginUrl);
|
|
591
590
|
const createdOrgInstance = (0, ts_types_1.getString)(options, 'createdOrgInstance', '').trim().toLowerCase();
|
|
@@ -769,7 +768,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
769
768
|
catch (err) {
|
|
770
769
|
errorMsg = `${bodyAsString}`;
|
|
771
770
|
}
|
|
772
|
-
throw new
|
|
771
|
+
throw new sfError_1.SfError(errorMsg);
|
|
773
772
|
}
|
|
774
773
|
}
|
|
775
774
|
exports.AuthInfo = AuthInfo;
|
package/lib/org/authRemover.d.ts
CHANGED
|
@@ -39,8 +39,8 @@ export declare class AuthRemover extends AsyncOptionalCreatable {
|
|
|
39
39
|
removeAllAuths(): Promise<void>;
|
|
40
40
|
/**
|
|
41
41
|
* Finds authorization files for username/alias in the global .sfdx folder
|
|
42
|
-
* **Throws** *{@link
|
|
43
|
-
* **Throws** *{@link
|
|
42
|
+
* **Throws** *{@link SfError}{ name: 'TargetOrgNotSetError' }* if no target-org
|
|
43
|
+
* **Throws** *{@link SfError}{ name: 'NamedOrgNotFoundError' }* if specified user is not found
|
|
44
44
|
*
|
|
45
45
|
* @param usernameOrAlias username or alias of the auth you want to find, defaults to the configured target-org
|
|
46
46
|
* @returns {Promise<SfOrg>}
|
package/lib/org/authRemover.js
CHANGED
|
@@ -66,8 +66,8 @@ class AuthRemover extends kit_1.AsyncOptionalCreatable {
|
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Finds authorization files for username/alias in the global .sfdx folder
|
|
69
|
-
* **Throws** *{@link
|
|
70
|
-
* **Throws** *{@link
|
|
69
|
+
* **Throws** *{@link SfError}{ name: 'TargetOrgNotSetError' }* if no target-org
|
|
70
|
+
* **Throws** *{@link SfError}{ name: 'NamedOrgNotFoundError' }* if specified user is not found
|
|
71
71
|
*
|
|
72
72
|
* @param usernameOrAlias username or alias of the auth you want to find, defaults to the configured target-org
|
|
73
73
|
* @returns {Promise<SfOrg>}
|
package/lib/org/connection.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { JsonCollection, JsonMap, Optional } from '@salesforce/ts-types';
|
|
|
4
4
|
import { Connection as JSForceConnection, ConnectionConfig, HttpRequest, QueryOptions, QueryResult, Record, Schema } from 'jsforce';
|
|
5
5
|
import { Tooling as JSForceTooling } from 'jsforce/lib/api/tooling';
|
|
6
6
|
import { StreamPromise } from 'jsforce/lib/util/promise';
|
|
7
|
-
import { AuthFields, AuthInfo } from '../org/authInfo';
|
|
8
7
|
import { ConfigAggregator } from '../config/configAggregator';
|
|
8
|
+
import { AuthFields, AuthInfo } from './authInfo';
|
|
9
9
|
export declare const SFDX_HTTP_HEADERS: {
|
|
10
10
|
'content-type': string;
|
|
11
11
|
'user-agent': string;
|
|
@@ -123,7 +123,7 @@ export declare class Connection<S extends Schema = Schema> extends JSForceConnec
|
|
|
123
123
|
/**
|
|
124
124
|
* Set the API version for all connection requests.
|
|
125
125
|
*
|
|
126
|
-
* **Throws** *{@link
|
|
126
|
+
* **Throws** *{@link SfError}{ name: 'IncorrectAPIVersionError' }* Incorrect API version.
|
|
127
127
|
*
|
|
128
128
|
* @param version The API version.
|
|
129
129
|
*/
|
|
@@ -171,6 +171,11 @@ export declare class Connection<S extends Schema = Schema> extends JSForceConnec
|
|
|
171
171
|
* @param options The query options.
|
|
172
172
|
*/
|
|
173
173
|
singleRecordQuery<T extends Record>(soql: string, options?: SingleRecordQueryOptions): Promise<T>;
|
|
174
|
+
/**
|
|
175
|
+
* Executes a get request on the baseUrl to force an auth refresh
|
|
176
|
+
* Useful for the raw methods (request, requestRaw) that use the accessToken directly and don't handle refreshes
|
|
177
|
+
*/
|
|
178
|
+
refreshAuth(): Promise<void>;
|
|
174
179
|
private loadInstanceApiVersion;
|
|
175
180
|
}
|
|
176
181
|
export declare const SingleRecordQueryErrors: {
|
package/lib/org/connection.js
CHANGED
|
@@ -17,7 +17,7 @@ const tooling_1 = require("jsforce/lib/api/tooling");
|
|
|
17
17
|
const myDomainResolver_1 = require("../status/myDomainResolver");
|
|
18
18
|
const configAggregator_1 = require("../config/configAggregator");
|
|
19
19
|
const logger_1 = require("../logger");
|
|
20
|
-
const
|
|
20
|
+
const sfError_1 = require("../sfError");
|
|
21
21
|
const sfdc_1 = require("../util/sfdc");
|
|
22
22
|
const messages_1 = require("../messages");
|
|
23
23
|
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
@@ -138,6 +138,7 @@ class Connection extends jsforce_1.Connection {
|
|
|
138
138
|
delete options.rest;
|
|
139
139
|
if (rest) {
|
|
140
140
|
this.logger.debug('deploy with REST');
|
|
141
|
+
await this.refreshAuth();
|
|
141
142
|
const headers = {
|
|
142
143
|
Authorization: this && `OAuth ${this.accessToken}`,
|
|
143
144
|
'Sforce-Call-Options': 'client=sfdx-core',
|
|
@@ -273,7 +274,7 @@ class Connection extends jsforce_1.Connection {
|
|
|
273
274
|
/**
|
|
274
275
|
* Set the API version for all connection requests.
|
|
275
276
|
*
|
|
276
|
-
* **Throws** *{@link
|
|
277
|
+
* **Throws** *{@link SfError}{ name: 'IncorrectAPIVersionError' }* Incorrect API version.
|
|
277
278
|
*
|
|
278
279
|
* @param version The API version.
|
|
279
280
|
*/
|
|
@@ -356,15 +357,27 @@ class Connection extends jsforce_1.Connection {
|
|
|
356
357
|
}) {
|
|
357
358
|
const result = options.tooling ? await this.tooling.query(soql) : await this.query(soql);
|
|
358
359
|
if (result.totalSize === 0) {
|
|
359
|
-
throw new
|
|
360
|
+
throw new sfError_1.SfError(`No record found for ${soql}`, exports.SingleRecordQueryErrors.NoRecords);
|
|
360
361
|
}
|
|
361
362
|
if (result.totalSize > 1) {
|
|
362
|
-
throw new
|
|
363
|
+
throw new sfError_1.SfError(options.returnChoicesOnMultiple
|
|
363
364
|
? `Multiple records found. ${result.records.map((item) => item[options.choiceField]).join(',')}`
|
|
364
365
|
: 'The query returned more than 1 record', exports.SingleRecordQueryErrors.MultipleRecords);
|
|
365
366
|
}
|
|
366
367
|
return result.records[0];
|
|
367
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* Executes a get request on the baseUrl to force an auth refresh
|
|
371
|
+
* Useful for the raw methods (request, requestRaw) that use the accessToken directly and don't handle refreshes
|
|
372
|
+
*/
|
|
373
|
+
async refreshAuth() {
|
|
374
|
+
this.logger.debug('Refreshing auth for org.');
|
|
375
|
+
const requestInfo = {
|
|
376
|
+
url: this.baseUrl(),
|
|
377
|
+
method: 'GET',
|
|
378
|
+
};
|
|
379
|
+
await this.request(requestInfo);
|
|
380
|
+
}
|
|
368
381
|
async loadInstanceApiVersion() {
|
|
369
382
|
const authFileFields = this.options.authInfo.getFields();
|
|
370
383
|
const lastCheckedDateString = authFileFields.instanceApiVersionLastRetrieved;
|
package/lib/org/org.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { OrgUsersConfig } from '../config/orgUsersConfig';
|
|
|
5
5
|
import { SandboxOrgConfig } from '../config/sandboxOrgConfig';
|
|
6
6
|
import { Connection } from './connection';
|
|
7
7
|
import { AuthFields, AuthInfo } from './authInfo';
|
|
8
|
+
import { ScratchOrgCreateOptions, ScratchOrgCreateResult } from './scratchOrgCreate';
|
|
8
9
|
export declare type OrganizationInformation = {
|
|
9
10
|
Name: string;
|
|
10
11
|
InstanceName: string;
|
|
@@ -63,6 +64,7 @@ export declare type SandboxRequest = {
|
|
|
63
64
|
SourceId?: string;
|
|
64
65
|
Description?: string;
|
|
65
66
|
};
|
|
67
|
+
export declare type ScratchOrgRequest = Pick<ScratchOrgCreateOptions, 'connectedAppConsumerKey' | 'durationDays' | 'nonamespace' | 'noancestors' | 'wait' | 'retry' | 'apiversion' | 'definitionjson' | 'definitionfile' | 'orgConfig' | 'clientSecret'>;
|
|
66
68
|
/**
|
|
67
69
|
* Provides a way to manage a locally authenticated Org.
|
|
68
70
|
*
|
|
@@ -111,6 +113,14 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
|
|
|
111
113
|
wait?: Duration;
|
|
112
114
|
interval?: Duration;
|
|
113
115
|
}): Promise<SandboxProcessObject>;
|
|
116
|
+
/**
|
|
117
|
+
* Creates a scratchOrg
|
|
118
|
+
* 'this' needs to be a valid dev-hub
|
|
119
|
+
*
|
|
120
|
+
* @param {options} ScratchOrgCreateOptions
|
|
121
|
+
* @returns {ScratchOrgCreateResult}
|
|
122
|
+
*/
|
|
123
|
+
scratchOrgCreate(options: ScratchOrgRequest): Promise<ScratchOrgCreateResult>;
|
|
114
124
|
/**
|
|
115
125
|
* Clean all data files in the org's data path. Usually <workspace>/.sfdx/orgs/<username>.
|
|
116
126
|
*
|
|
@@ -138,9 +148,9 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
|
|
|
138
148
|
/**
|
|
139
149
|
* Check that this org is a scratch org by asking the dev hub if it knows about it.
|
|
140
150
|
*
|
|
141
|
-
* **Throws** *{@link
|
|
151
|
+
* **Throws** *{@link SfError}{ name: 'NotADevHubError' }* Not a Dev Hub.
|
|
142
152
|
*
|
|
143
|
-
* **Throws** *{@link
|
|
153
|
+
* **Throws** *{@link SfError}{ name: 'NoResultsError' }* No results.
|
|
144
154
|
*
|
|
145
155
|
* @param devHubUsernameOrAlias The username or alias of the dev hub org.
|
|
146
156
|
*/
|
|
@@ -243,7 +253,7 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
|
|
|
243
253
|
/**
|
|
244
254
|
* Removes a username from the user config for this object. For convenience `this` object is returned.
|
|
245
255
|
*
|
|
246
|
-
* **Throws** *{@link
|
|
256
|
+
* **Throws** *{@link SfError}{ name: 'MissingAuthInfoError' }* Auth info is missing.
|
|
247
257
|
*
|
|
248
258
|
* @param {AuthInfo | string} auth The AuthInfo containing the username to remove.
|
|
249
259
|
*/
|
|
@@ -295,12 +305,12 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
|
|
|
295
305
|
*/
|
|
296
306
|
protected init(): Promise<void>;
|
|
297
307
|
/**
|
|
298
|
-
* **Throws** *{@link
|
|
308
|
+
* **Throws** *{@link SfError}{ name: 'NotSupportedError' }* Throws an unsupported error.
|
|
299
309
|
*/
|
|
300
310
|
protected getDefaultOptions(): Org.Options;
|
|
301
311
|
private queryProduction;
|
|
302
|
-
private
|
|
303
|
-
private
|
|
312
|
+
private destroySandbox;
|
|
313
|
+
private destroyScratchOrg;
|
|
304
314
|
/**
|
|
305
315
|
* this method will delete the sandbox org from the production org and clean up any local files
|
|
306
316
|
*
|
package/lib/org/org.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.Org = exports.SandboxEvents = exports.OrgTypes = void 0;
|
|
10
10
|
const path_1 = require("path");
|
|
11
|
+
const fs = require("fs");
|
|
11
12
|
const kit_1 = require("@salesforce/kit");
|
|
12
13
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
13
14
|
const config_1 = require("../config/config");
|
|
@@ -15,16 +16,16 @@ const configAggregator_1 = require("../config/configAggregator");
|
|
|
15
16
|
const orgUsersConfig_1 = require("../config/orgUsersConfig");
|
|
16
17
|
const sandboxOrgConfig_1 = require("../config/sandboxOrgConfig");
|
|
17
18
|
const global_1 = require("../global");
|
|
19
|
+
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
18
20
|
const logger_1 = require("../logger");
|
|
19
|
-
const
|
|
20
|
-
const fs_1 = require("../util/fs");
|
|
21
|
+
const sfError_1 = require("../sfError");
|
|
21
22
|
const sfdc_1 = require("../util/sfdc");
|
|
22
|
-
const globalInfo_1 = require("../globalInfo");
|
|
23
|
-
const messages_1 = require("../messages");
|
|
24
|
-
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
25
23
|
const webOAuthServer_1 = require("../webOAuthServer");
|
|
24
|
+
const messages_1 = require("../messages");
|
|
25
|
+
const globalInfo_1 = require("../globalInfo");
|
|
26
26
|
const connection_1 = require("./connection");
|
|
27
27
|
const authInfo_1 = require("./authInfo");
|
|
28
|
+
const scratchOrgCreate_1 = require("./scratchOrgCreate");
|
|
28
29
|
const orgConfigProperties_1 = require("./orgConfigProperties");
|
|
29
30
|
messages_1.Messages.importMessagesDirectory(__dirname);
|
|
30
31
|
const messages = messages_1.Messages.load('@salesforce/core', 'org', [
|
|
@@ -114,6 +115,16 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
114
115
|
pollInterval,
|
|
115
116
|
});
|
|
116
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Creates a scratchOrg
|
|
120
|
+
* 'this' needs to be a valid dev-hub
|
|
121
|
+
*
|
|
122
|
+
* @param {options} ScratchOrgCreateOptions
|
|
123
|
+
* @returns {ScratchOrgCreateResult}
|
|
124
|
+
*/
|
|
125
|
+
async scratchOrgCreate(options) {
|
|
126
|
+
return (0, scratchOrgCreate_1.scratchOrgCreate)({ ...options, hubOrg: this });
|
|
127
|
+
}
|
|
117
128
|
/**
|
|
118
129
|
* Clean all data files in the org's data path. Usually <workspace>/.sfdx/orgs/<username>.
|
|
119
130
|
*
|
|
@@ -136,7 +147,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
136
147
|
}
|
|
137
148
|
throw err;
|
|
138
149
|
}
|
|
139
|
-
return this.manageDelete(async () => await
|
|
150
|
+
return this.manageDelete(async () => await fs.promises.rmdir(dataPath), dataPath, throwWhenRemoveFails);
|
|
140
151
|
}
|
|
141
152
|
/**
|
|
142
153
|
* @ignore
|
|
@@ -176,9 +187,9 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
176
187
|
/**
|
|
177
188
|
* Check that this org is a scratch org by asking the dev hub if it knows about it.
|
|
178
189
|
*
|
|
179
|
-
* **Throws** *{@link
|
|
190
|
+
* **Throws** *{@link SfError}{ name: 'NotADevHubError' }* Not a Dev Hub.
|
|
180
191
|
*
|
|
181
|
-
* **Throws** *{@link
|
|
192
|
+
* **Throws** *{@link SfError}{ name: 'NoResultsError' }* No results.
|
|
182
193
|
*
|
|
183
194
|
* @param devHubUsernameOrAlias The username or alias of the dev hub org.
|
|
184
195
|
*/
|
|
@@ -194,7 +205,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
194
205
|
try {
|
|
195
206
|
const results = await devHubConnection.query(DEV_HUB_SOQL);
|
|
196
207
|
if ((0, ts_types_1.getNumber)(results, 'records.length') !== 1) {
|
|
197
|
-
throw new
|
|
208
|
+
throw new sfError_1.SfError('No results', 'NoResultsError');
|
|
198
209
|
}
|
|
199
210
|
}
|
|
200
211
|
catch (err) {
|
|
@@ -429,7 +440,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
429
440
|
*/
|
|
430
441
|
async addUsername(auth) {
|
|
431
442
|
if (!auth) {
|
|
432
|
-
throw new
|
|
443
|
+
throw new sfError_1.SfError('Missing auth info', 'MissingAuthInfo');
|
|
433
444
|
}
|
|
434
445
|
const authInfo = (0, ts_types_1.isString)(auth) ? await authInfo_1.AuthInfo.create({ username: auth }) : auth;
|
|
435
446
|
this.logger.debug(`adding username ${authInfo.getFields().username}`);
|
|
@@ -439,7 +450,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
439
450
|
// needs config refactoring to improve
|
|
440
451
|
const usernames = contents.usernames || [];
|
|
441
452
|
if (!(0, ts_types_1.isArray)(usernames)) {
|
|
442
|
-
throw new
|
|
453
|
+
throw new sfError_1.SfError('Usernames is not an array', 'UnexpectedDataFormat');
|
|
443
454
|
}
|
|
444
455
|
let shouldUpdate = false;
|
|
445
456
|
const thisUsername = (0, ts_types_1.ensure)(this.getUsername());
|
|
@@ -461,13 +472,13 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
461
472
|
/**
|
|
462
473
|
* Removes a username from the user config for this object. For convenience `this` object is returned.
|
|
463
474
|
*
|
|
464
|
-
* **Throws** *{@link
|
|
475
|
+
* **Throws** *{@link SfError}{ name: 'MissingAuthInfoError' }* Auth info is missing.
|
|
465
476
|
*
|
|
466
477
|
* @param {AuthInfo | string} auth The AuthInfo containing the username to remove.
|
|
467
478
|
*/
|
|
468
479
|
async removeUsername(auth) {
|
|
469
480
|
if (!auth) {
|
|
470
|
-
throw new
|
|
481
|
+
throw new sfError_1.SfError('Missing auth info', 'MissingAuthInfoError');
|
|
471
482
|
}
|
|
472
483
|
const authInfo = (0, ts_types_1.isString)(auth) ? await authInfo_1.AuthInfo.create({ username: auth }) : auth;
|
|
473
484
|
this.logger.debug(`removing username ${authInfo.getFields().username}`);
|
|
@@ -575,7 +586,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
575
586
|
throw messages.createError('noUsernameFound');
|
|
576
587
|
}
|
|
577
588
|
this.connection = await connection_1.Connection.create({
|
|
578
|
-
// If no username is provided or resolvable from an alias, AuthInfo will throw an
|
|
589
|
+
// If no username is provided or resolvable from an alias, AuthInfo will throw an SfError.
|
|
579
590
|
authInfo: await authInfo_1.AuthInfo.create({ username, isDevHub: this.options.isDevHub }),
|
|
580
591
|
});
|
|
581
592
|
}
|
|
@@ -585,18 +596,18 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
585
596
|
this.orgId = this.getField(Org.Fields.ORG_ID);
|
|
586
597
|
}
|
|
587
598
|
/**
|
|
588
|
-
* **Throws** *{@link
|
|
599
|
+
* **Throws** *{@link SfError}{ name: 'NotSupportedError' }* Throws an unsupported error.
|
|
589
600
|
*/
|
|
590
601
|
getDefaultOptions() {
|
|
591
|
-
throw new
|
|
602
|
+
throw new sfError_1.SfError('Not Supported', 'NotSupportedError');
|
|
592
603
|
}
|
|
593
604
|
async queryProduction(org, field, value) {
|
|
594
605
|
return org.connection.singleRecordQuery(`SELECT SandboxInfoId FROM SandboxProcess WHERE ${field} ='${value}' AND Status NOT IN ('D', 'E')`, { tooling: true });
|
|
595
606
|
}
|
|
596
|
-
async
|
|
607
|
+
async destroySandbox(org, id) {
|
|
597
608
|
return org.getConnection().tooling.delete('SandboxInfo', id);
|
|
598
609
|
}
|
|
599
|
-
async
|
|
610
|
+
async destroyScratchOrg(org, id) {
|
|
600
611
|
return org.getConnection().delete('ActiveScratchOrg', id);
|
|
601
612
|
}
|
|
602
613
|
/**
|
|
@@ -641,7 +652,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
641
652
|
}
|
|
642
653
|
}
|
|
643
654
|
// const deleteResult = await prodOrg.connection.tooling.delete('SandboxInfo', result.SandboxInfoId);
|
|
644
|
-
const deleteResult = await this.
|
|
655
|
+
const deleteResult = await this.destroySandbox(prodOrg, result.SandboxInfoId);
|
|
645
656
|
this.logger.debug('Return from calling tooling.delete: %o ', deleteResult);
|
|
646
657
|
await this.remove();
|
|
647
658
|
if (Array.isArray(deleteResult) || !deleteResult.success) {
|
|
@@ -669,7 +680,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
669
680
|
const username = this.getUsername();
|
|
670
681
|
const activeScratchOrgRecordId = (await devHubConn.singleRecordQuery(`SELECT Id FROM ActiveScratchOrg WHERE SignupUsername='${username}'`)).Id;
|
|
671
682
|
this.logger.trace(`found matching ActiveScratchOrg with SignupUsername: ${username}. Deleting...`);
|
|
672
|
-
await this.
|
|
683
|
+
await this.destroyScratchOrg(devHub, activeScratchOrgRecordId);
|
|
673
684
|
await this.remove();
|
|
674
685
|
}
|
|
675
686
|
catch (err) {
|
|
@@ -703,7 +714,6 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
703
714
|
this.logger.debug(`Clearing auth cache for user: ${username}`);
|
|
704
715
|
config.orgs.unset(username);
|
|
705
716
|
}
|
|
706
|
-
await config.write();
|
|
707
717
|
}
|
|
708
718
|
/**
|
|
709
719
|
* Deletes the users config file
|
|
@@ -743,34 +753,27 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
743
753
|
this.logger.debug(`Removing users associate with org: ${this.getOrgId()}`);
|
|
744
754
|
const config = await this.retrieveOrgUsersConfig();
|
|
745
755
|
this.logger.debug(`using path for org users: ${config.getPath()}`);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
};
|
|
768
|
-
await removeConfig(this.configAggregator.getInfo(orgConfigProperties_1.OrgConfigProperties.TARGET_DEV_HUB));
|
|
769
|
-
await removeConfig(this.configAggregator.getInfo(orgConfigProperties_1.OrgConfigProperties.TARGET_ORG));
|
|
770
|
-
await orgForUser.removeAuth();
|
|
771
|
-
}
|
|
772
|
-
await globalInfo.write();
|
|
773
|
-
}
|
|
756
|
+
const authInfos = await this.readUserAuthFiles();
|
|
757
|
+
await Promise.all(authInfos
|
|
758
|
+
.map((auth) => auth.getFields().username)
|
|
759
|
+
.map(async (username) => {
|
|
760
|
+
const aliasKeys = (username && globalInfo.aliases.getAll(username)) || [];
|
|
761
|
+
globalInfo.aliases.unsetAll(username);
|
|
762
|
+
const orgForUser = username === this.getUsername()
|
|
763
|
+
? this
|
|
764
|
+
: await Org.create({
|
|
765
|
+
connection: await connection_1.Connection.create({ authInfo: await authInfo_1.AuthInfo.create({ username }) }),
|
|
766
|
+
});
|
|
767
|
+
const orgType = this.isDevHubOrg() ? orgConfigProperties_1.OrgConfigProperties.TARGET_DEV_HUB : orgConfigProperties_1.OrgConfigProperties.TARGET_ORG;
|
|
768
|
+
const configInfo = orgForUser.configAggregator.getInfo(orgType);
|
|
769
|
+
const needsConfigUpdate = (configInfo.isGlobal() || configInfo.isLocal()) &&
|
|
770
|
+
(configInfo.value === username || aliasKeys.includes(configInfo.value));
|
|
771
|
+
return [
|
|
772
|
+
orgForUser.removeAuth(),
|
|
773
|
+
needsConfigUpdate ? config_1.Config.update(configInfo.isGlobal(), orgType, undefined) : undefined,
|
|
774
|
+
].filter(Boolean);
|
|
775
|
+
}));
|
|
776
|
+
await globalInfo.write();
|
|
774
777
|
}
|
|
775
778
|
/**
|
|
776
779
|
* Remove an associate sandbox config.
|
|
@@ -851,7 +854,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
851
854
|
waitingOnAuth = true;
|
|
852
855
|
}
|
|
853
856
|
else {
|
|
854
|
-
throw
|
|
857
|
+
throw sfError_1.SfError.wrap(error);
|
|
855
858
|
}
|
|
856
859
|
}
|
|
857
860
|
}
|
|
@@ -943,7 +946,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
943
946
|
}
|
|
944
947
|
else {
|
|
945
948
|
// If it fails for any unexpected reason, just pass that through
|
|
946
|
-
throw
|
|
949
|
+
throw sfError_1.SfError.wrap(error);
|
|
947
950
|
}
|
|
948
951
|
}
|
|
949
952
|
}
|
|
@@ -12,7 +12,7 @@ const kit_1 = require("@salesforce/kit");
|
|
|
12
12
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
13
13
|
const logger_1 = require("../logger");
|
|
14
14
|
const messages_1 = require("../messages");
|
|
15
|
-
const
|
|
15
|
+
const sfError_1 = require("../sfError");
|
|
16
16
|
messages_1.Messages.importMessagesDirectory(__dirname);
|
|
17
17
|
const messages = messages_1.Messages.load('@salesforce/core', 'permissionSetAssignment', [
|
|
18
18
|
'errorsEncounteredCreatingAssignment',
|
|
@@ -86,7 +86,7 @@ class PermissionSetAssignment {
|
|
|
86
86
|
errors.forEach((_message) => {
|
|
87
87
|
message = `${message}${_message}${os_1.EOL}`;
|
|
88
88
|
});
|
|
89
|
-
throw new
|
|
89
|
+
throw new sfError_1.SfError(message, 'errorsEncounteredCreatingAssignment');
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
92
92
|
throw messages.createError('notSuccessfulButNoErrorsReported');
|