@salesforce/core 3.21.3 → 3.21.6
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 +14 -0
- package/lib/org/authInfo.d.ts +2 -0
- package/lib/org/authInfo.js +15 -14
- package/lib/org/connection.js +1 -1
- package/lib/org/org.js +1 -1
- package/lib/org/permissionSetAssignment.js +2 -1
- package/lib/org/scratchOrgCreate.js +1 -1
- package/lib/org/scratchOrgInfoApi.js +2 -3
- package/lib/org/user.js +9 -9
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +69 -0
- package/lib/stateAggregator/accessors/orgAccessor.js +69 -0
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +41 -0
- package/lib/stateAggregator/accessors/tokenAccessor.js +41 -0
- package/lib/testSetup.d.ts +34 -3
- package/lib/testSetup.js +49 -6
- package/package.json +4 -2
- package/lib/config/keychainConfig.d.ts +0 -19
- package/lib/config/keychainConfig.js +0 -44
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [3.21.6](https://github.com/forcedotcom/sfdx-core/compare/v3.21.5...v3.21.6) (2022-06-23)
|
|
6
|
+
|
|
7
|
+
### [3.21.5](https://github.com/forcedotcom/sfdx-core/compare/v3.21.4...v3.21.5) (2022-06-23)
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- bump jsforce ([b1e8604](https://github.com/forcedotcom/sfdx-core/commit/b1e8604203b09df7b252fd6520fb73405e287aa4))
|
|
12
|
+
|
|
13
|
+
### [3.21.4](https://github.com/forcedotcom/sfdx-core/compare/v3.21.3...v3.21.4) (2022-06-22)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- cause release for jsforce again ([0700356](https://github.com/forcedotcom/sfdx-core/commit/0700356759506fce59b426e84fefbe85ae2f247e))
|
|
18
|
+
|
|
5
19
|
### [3.21.3](https://github.com/forcedotcom/sfdx-core/compare/v3.21.2...v3.21.3) (2022-06-22)
|
|
6
20
|
|
|
7
21
|
### Bug Fixes
|
package/lib/org/authInfo.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare type OAuth2Config = JsforceOAuth2Config & {
|
|
|
8
8
|
authCode?: string;
|
|
9
9
|
refreshToken?: string;
|
|
10
10
|
loginUrl?: string;
|
|
11
|
+
username?: string;
|
|
11
12
|
};
|
|
12
13
|
/**
|
|
13
14
|
* Fields for authorization, org, and local information.
|
|
@@ -289,6 +290,7 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
|
|
|
289
290
|
private loadDecryptedAuthFromConfig;
|
|
290
291
|
private isTokenOptions;
|
|
291
292
|
private refreshFn;
|
|
293
|
+
private readJwtKey;
|
|
292
294
|
private authJwt;
|
|
293
295
|
private tryJwtAuth;
|
|
294
296
|
private buildRefreshTokenConfig;
|
package/lib/org/authInfo.js
CHANGED
|
@@ -522,7 +522,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
522
522
|
async init() {
|
|
523
523
|
this.stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
|
|
524
524
|
const username = this.options.username;
|
|
525
|
-
const authOptions = this.options.oauth2Options || this.options.accessTokenOptions;
|
|
525
|
+
const authOptions = (this.options.oauth2Options || this.options.accessTokenOptions);
|
|
526
526
|
// Must specify either username and/or options
|
|
527
527
|
if (!username && !authOptions) {
|
|
528
528
|
throw messages.createError('authInfoCreationError');
|
|
@@ -534,7 +534,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
534
534
|
throw messages.createError('authInfoOverwriteError');
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
|
-
const oauthUsername = username || (0
|
|
537
|
+
const oauthUsername = username || (authOptions === null || authOptions === void 0 ? void 0 : authOptions.username);
|
|
538
538
|
if (oauthUsername) {
|
|
539
539
|
this.username = oauthUsername;
|
|
540
540
|
await this.stateAggregator.orgs.read(oauthUsername, false, false);
|
|
@@ -562,9 +562,9 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
getInstanceUrl(options, aggregator) {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
return instanceUrl
|
|
565
|
+
var _a;
|
|
566
|
+
const instanceUrl = (_a = options === null || options === void 0 ? void 0 : options.instanceUrl) !== null && _a !== void 0 ? _a : aggregator.getPropertyValue(orgConfigProperties_1.OrgConfigProperties.ORG_INSTANCE_URL);
|
|
567
|
+
return instanceUrl !== null && instanceUrl !== void 0 ? instanceUrl : sfdcUrl_1.SfdcUrl.PRODUCTION;
|
|
568
568
|
}
|
|
569
569
|
/**
|
|
570
570
|
* Initialize this AuthInfo instance with the specified options. If options are not provided, initialize it from cache
|
|
@@ -668,15 +668,19 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
668
668
|
return await callback(error);
|
|
669
669
|
}
|
|
670
670
|
}
|
|
671
|
+
async readJwtKey(keyFile) {
|
|
672
|
+
return fs.promises.readFile(keyFile, 'utf8');
|
|
673
|
+
}
|
|
671
674
|
// Build OAuth config for a JWT auth flow
|
|
672
675
|
async authJwt(options) {
|
|
676
|
+
var _a;
|
|
673
677
|
if (!options.clientId) {
|
|
674
678
|
throw messages.createError('missingClientId');
|
|
675
679
|
}
|
|
676
|
-
const privateKeyContents = await
|
|
680
|
+
const privateKeyContents = await this.readJwtKey((0, ts_types_1.ensureString)(options.privateKey));
|
|
677
681
|
const { loginUrl = sfdcUrl_1.SfdcUrl.PRODUCTION } = options;
|
|
678
682
|
const url = new sfdcUrl_1.SfdcUrl(loginUrl);
|
|
679
|
-
const createdOrgInstance = (
|
|
683
|
+
const createdOrgInstance = ((_a = this.getFields().createdOrgInstance) !== null && _a !== void 0 ? _a : '').trim().toLowerCase();
|
|
680
684
|
const audienceUrl = await url.getJwtAudienceUrl(createdOrgInstance);
|
|
681
685
|
let authFieldsBuilder;
|
|
682
686
|
const authErrors = [];
|
|
@@ -751,7 +755,6 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
751
755
|
const { orgId } = parseIdUrl(authFieldsBuilder.id);
|
|
752
756
|
let username = this.getUsername();
|
|
753
757
|
if (!username) {
|
|
754
|
-
// @ts-ignore
|
|
755
758
|
const userInfo = await this.retrieveUserInfo(authFieldsBuilder.instance_url, authFieldsBuilder.access_token);
|
|
756
759
|
username = (0, ts_types_1.ensureString)(userInfo === null || userInfo === void 0 ? void 0 : userInfo.username);
|
|
757
760
|
}
|
|
@@ -854,18 +857,16 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
854
857
|
* @private
|
|
855
858
|
*/
|
|
856
859
|
throwUserGetException(response) {
|
|
857
|
-
var _a;
|
|
860
|
+
var _a, _b, _c;
|
|
858
861
|
let errorMsg = '';
|
|
859
|
-
const bodyAsString = (
|
|
862
|
+
const bodyAsString = (_a = response.body) !== null && _a !== void 0 ? _a : JSON.stringify({ message: 'UNKNOWN', errorCode: 'UNKNOWN' });
|
|
860
863
|
try {
|
|
861
864
|
const body = (0, kit_1.parseJson)(bodyAsString);
|
|
862
865
|
if ((0, ts_types_1.isArray)(body)) {
|
|
863
|
-
errorMsg = body
|
|
864
|
-
.map((line) => { var _a; return (_a = (0, ts_types_1.getString)(line, 'message')) !== null && _a !== void 0 ? _a : (0, ts_types_1.getString)(line, 'errorCode', 'UNKNOWN'); })
|
|
865
|
-
.join(os.EOL);
|
|
866
|
+
errorMsg = body.map((line) => { var _a, _b; return (_b = (_a = line.message) !== null && _a !== void 0 ? _a : line.errorCode) !== null && _b !== void 0 ? _b : 'UNKNOWN'; }).join(os.EOL);
|
|
866
867
|
}
|
|
867
868
|
else {
|
|
868
|
-
errorMsg = (
|
|
869
|
+
errorMsg = (_c = (_b = body.message) !== null && _b !== void 0 ? _b : body.errorCode) !== null && _c !== void 0 ? _c : 'UNKNOWN';
|
|
869
870
|
}
|
|
870
871
|
}
|
|
871
872
|
catch (err) {
|
package/lib/org/connection.js
CHANGED
|
@@ -380,7 +380,7 @@ class Connection extends jsforce_1.Connection {
|
|
|
380
380
|
async loadInstanceApiVersion() {
|
|
381
381
|
const authFileFields = this.options.authInfo.getFields();
|
|
382
382
|
const lastCheckedDateString = authFileFields.instanceApiVersionLastRetrieved;
|
|
383
|
-
let version =
|
|
383
|
+
let version = authFileFields.instanceApiVersion;
|
|
384
384
|
let lastChecked;
|
|
385
385
|
try {
|
|
386
386
|
if (lastCheckedDateString && (0, ts_types_1.isString)(lastCheckedDateString)) {
|
package/lib/org/org.js
CHANGED
|
@@ -292,7 +292,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
292
292
|
const DEV_HUB_SOQL = `SELECT CreatedDate,Edition,ExpirationDate FROM ActiveScratchOrg WHERE ScratchOrg='${trimmedId}'`;
|
|
293
293
|
try {
|
|
294
294
|
const results = await devHubConnection.query(DEV_HUB_SOQL);
|
|
295
|
-
if (
|
|
295
|
+
if (results.records.length !== 1) {
|
|
296
296
|
throw new sfError_1.SfError('No results', 'NoResultsError');
|
|
297
297
|
}
|
|
298
298
|
}
|
|
@@ -49,6 +49,7 @@ class PermissionSetAssignment {
|
|
|
49
49
|
* @param permSetString An array of permission set names.
|
|
50
50
|
*/
|
|
51
51
|
async create(id, permSetString) {
|
|
52
|
+
var _a;
|
|
52
53
|
if (!id) {
|
|
53
54
|
throw messages.createError('userIdRequired');
|
|
54
55
|
}
|
|
@@ -61,7 +62,7 @@ class PermissionSetAssignment {
|
|
|
61
62
|
query += ` AND NamespacePrefix='${nsPrefix}'`;
|
|
62
63
|
}
|
|
63
64
|
const result = await this.org.getConnection().query(query);
|
|
64
|
-
const permissionSetId = (0
|
|
65
|
+
const permissionSetId = (_a = result === null || result === void 0 ? void 0 : result.records[0]) === null || _a === void 0 ? void 0 : _a.Id;
|
|
65
66
|
if (!permissionSetId) {
|
|
66
67
|
if (nsPrefix) {
|
|
67
68
|
throw messages.createError('assignCommandPermissionSetNotFoundForNSError', [permSetName, nsPrefix]);
|
|
@@ -142,7 +142,7 @@ const scratchOrgCreate = async (options) => {
|
|
|
142
142
|
(0, scratchOrgInfoApi_1.requestScratchOrgCreation)(hubOrg, scratchOrgInfo, settingsGenerator),
|
|
143
143
|
getSignupTargetLoginUrl(),
|
|
144
144
|
]);
|
|
145
|
-
const scratchOrgInfoId = (0, ts_types_1.ensureString)(
|
|
145
|
+
const scratchOrgInfoId = (0, ts_types_1.ensureString)(scratchOrgInfoRequestResult.id);
|
|
146
146
|
const cache = await scratchOrgCache_1.ScratchOrgCache.create();
|
|
147
147
|
cache.set(scratchOrgInfoId, {
|
|
148
148
|
hubUsername: hubOrg.getUsername(),
|
|
@@ -8,16 +8,15 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.updateRevisionCounterToZero = exports.resolveUrl = exports.deploySettings = exports.pollForScratchOrgInfo = exports.requestScratchOrgCreation = exports.authorizeScratchOrg = exports.queryScratchOrgInfo = void 0;
|
|
10
10
|
const kit_1 = require("@salesforce/kit");
|
|
11
|
-
const ts_types_1 = require("@salesforce/ts-types");
|
|
12
11
|
const ts_retry_promise_1 = require("ts-retry-promise");
|
|
13
12
|
const logger_1 = require("../logger");
|
|
14
|
-
const mapKeys_1 = require("../util/mapKeys");
|
|
15
13
|
const messages_1 = require("../messages");
|
|
16
14
|
const sfError_1 = require("../sfError");
|
|
17
15
|
const sfdcUrl_1 = require("../util/sfdcUrl");
|
|
18
16
|
const pollingClient_1 = require("../status/pollingClient");
|
|
19
17
|
const myDomainResolver_1 = require("../status/myDomainResolver");
|
|
20
18
|
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
19
|
+
const mapKeys_1 = require("../util/mapKeys");
|
|
21
20
|
const authInfo_1 = require("./authInfo");
|
|
22
21
|
const org_1 = require("./org");
|
|
23
22
|
const scratchOrgErrorCodes_1 = require("./scratchOrgErrorCodes");
|
|
@@ -195,7 +194,7 @@ const checkOrgDoesntExist = async (scratchOrgInfo) => {
|
|
|
195
194
|
if (!usernameKey) {
|
|
196
195
|
return;
|
|
197
196
|
}
|
|
198
|
-
const username =
|
|
197
|
+
const username = scratchOrgInfo[usernameKey];
|
|
199
198
|
if (username && username.length > 0) {
|
|
200
199
|
try {
|
|
201
200
|
await authInfo_1.AuthInfo.create({ username: username.toLowerCase() });
|
package/lib/org/user.js
CHANGED
|
@@ -86,16 +86,16 @@ async function retrieveUserFields(logger, username) {
|
|
|
86
86
|
if (result.totalSize === 1) {
|
|
87
87
|
const results = (0, kit_1.mapKeys)(result.records[0], (value, key) => (0, kit_1.lowerFirst)(key));
|
|
88
88
|
const fields = {
|
|
89
|
-
id: (0, ts_types_1.
|
|
89
|
+
id: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.id]),
|
|
90
90
|
username,
|
|
91
|
-
alias: (0, ts_types_1.
|
|
92
|
-
email: (0, ts_types_1.
|
|
93
|
-
emailEncodingKey: (0, ts_types_1.
|
|
94
|
-
languageLocaleKey: (0, ts_types_1.
|
|
95
|
-
localeSidKey: (0, ts_types_1.
|
|
96
|
-
profileId: (0, ts_types_1.
|
|
97
|
-
lastName: (0, ts_types_1.
|
|
98
|
-
timeZoneSidKey: (0, ts_types_1.
|
|
91
|
+
alias: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.alias]),
|
|
92
|
+
email: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.email]),
|
|
93
|
+
emailEncodingKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.emailEncodingKey]),
|
|
94
|
+
languageLocaleKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.languageLocaleKey]),
|
|
95
|
+
localeSidKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.localeSidKey]),
|
|
96
|
+
profileId: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.profileId]),
|
|
97
|
+
lastName: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.lastName]),
|
|
98
|
+
timeZoneSidKey: (0, ts_types_1.ensureString)(results[exports.REQUIRED_FIELDS.timeZoneSidKey]),
|
|
99
99
|
};
|
|
100
100
|
return fields;
|
|
101
101
|
}
|
|
@@ -25,18 +25,87 @@ export declare abstract class BaseOrgAccessor<T extends ConfigFile, P extends Co
|
|
|
25
25
|
private configs;
|
|
26
26
|
private contents;
|
|
27
27
|
private logger;
|
|
28
|
+
/**
|
|
29
|
+
* Read the auth file for the given useranme. Once the file has been read, it can be reaccessed with the `get` method.
|
|
30
|
+
*
|
|
31
|
+
* @param username username to read
|
|
32
|
+
* @param decrypt if true, decrypt encrypted values
|
|
33
|
+
* @param throwOnNotFound throw if file is not found for username
|
|
34
|
+
*/
|
|
28
35
|
read(username: string, decrypt?: boolean, throwOnNotFound?: boolean): Promise<Nullable<P>>;
|
|
36
|
+
/**
|
|
37
|
+
* Read all the auth files under the global state directory
|
|
38
|
+
*
|
|
39
|
+
* @param decrypt if true, decrypt encrypted values
|
|
40
|
+
*/
|
|
29
41
|
readAll(decrypt?: boolean): Promise<P[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Return the contents of the username's auth file from cache. The `read` or `readAll` methods must be called first in order to populate the cache.
|
|
44
|
+
*
|
|
45
|
+
* @param username username to get
|
|
46
|
+
* @param decrypt if true, decrypt encrypted values
|
|
47
|
+
*/
|
|
30
48
|
get(username: string, decrypt?: boolean): Nullable<P>;
|
|
49
|
+
/**
|
|
50
|
+
* Return the contents of all the auth files from cache. The `read` or `readAll` methods must be called first in order to populate the cache.
|
|
51
|
+
*
|
|
52
|
+
* @param decrypt if true, decrypt encrypted values
|
|
53
|
+
* @returns
|
|
54
|
+
*/
|
|
31
55
|
getAll(decrypt?: boolean): P[];
|
|
56
|
+
/**
|
|
57
|
+
* Returns true if the username has been cached.
|
|
58
|
+
*
|
|
59
|
+
* @param username
|
|
60
|
+
*/
|
|
32
61
|
has(username: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Returns true if there is an auth file for the given username. The `read` or `readAll` methods must be called first in order to populate the cache.
|
|
64
|
+
*
|
|
65
|
+
* @param username
|
|
66
|
+
*/
|
|
33
67
|
exists(username: string): Promise<boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* Return the file stats for a given userame's auth file.
|
|
70
|
+
*
|
|
71
|
+
* @param username
|
|
72
|
+
*/
|
|
34
73
|
stat(username: string): Promise<Nullable<fs.Stats>>;
|
|
74
|
+
/**
|
|
75
|
+
* Returns true if there is an auth file for the given username
|
|
76
|
+
*
|
|
77
|
+
* @param username
|
|
78
|
+
*/
|
|
35
79
|
hasFile(username: string): Promise<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Return all auth files under the global state directory.
|
|
82
|
+
*/
|
|
36
83
|
list(): Promise<string[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Set the contents for a given username.
|
|
86
|
+
*
|
|
87
|
+
* @param username
|
|
88
|
+
* @param org
|
|
89
|
+
*/
|
|
37
90
|
set(username: string, org: P): void;
|
|
91
|
+
/**
|
|
92
|
+
* Update the contents for a given username.
|
|
93
|
+
*
|
|
94
|
+
* @param username
|
|
95
|
+
* @param org
|
|
96
|
+
*/
|
|
38
97
|
update(username: string, org: Partial<P> & JsonMap): void;
|
|
98
|
+
/**
|
|
99
|
+
* Delete the auth file for a given username.
|
|
100
|
+
*
|
|
101
|
+
* @param username
|
|
102
|
+
*/
|
|
39
103
|
remove(username: string): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Write the contents of the auth file for a given username.
|
|
106
|
+
*
|
|
107
|
+
* @param username
|
|
108
|
+
*/
|
|
40
109
|
write(username: string): Promise<Nullable<P>>;
|
|
41
110
|
protected init(): Promise<void>;
|
|
42
111
|
private getAllFiles;
|
|
@@ -63,6 +63,13 @@ class BaseOrgAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
63
63
|
this.configs = new Map();
|
|
64
64
|
this.contents = new Map();
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Read the auth file for the given useranme. Once the file has been read, it can be reaccessed with the `get` method.
|
|
68
|
+
*
|
|
69
|
+
* @param username username to read
|
|
70
|
+
* @param decrypt if true, decrypt encrypted values
|
|
71
|
+
* @param throwOnNotFound throw if file is not found for username
|
|
72
|
+
*/
|
|
66
73
|
async read(username, decrypt = false, throwOnNotFound = true) {
|
|
67
74
|
try {
|
|
68
75
|
const config = await this.initAuthFile(username, throwOnNotFound);
|
|
@@ -73,6 +80,11 @@ class BaseOrgAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
73
80
|
return null;
|
|
74
81
|
}
|
|
75
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Read all the auth files under the global state directory
|
|
85
|
+
*
|
|
86
|
+
* @param decrypt if true, decrypt encrypted values
|
|
87
|
+
*/
|
|
76
88
|
async readAll(decrypt = false) {
|
|
77
89
|
const fileChunks = chunk(await this.getAllFiles(), 50);
|
|
78
90
|
for (const fileChunk of fileChunks) {
|
|
@@ -85,6 +97,12 @@ class BaseOrgAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
85
97
|
}
|
|
86
98
|
return this.getAll(decrypt);
|
|
87
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Return the contents of the username's auth file from cache. The `read` or `readAll` methods must be called first in order to populate the cache.
|
|
102
|
+
*
|
|
103
|
+
* @param username username to get
|
|
104
|
+
* @param decrypt if true, decrypt encrypted values
|
|
105
|
+
*/
|
|
88
106
|
get(username, decrypt = false) {
|
|
89
107
|
const config = this.configs.get(username);
|
|
90
108
|
if (config) {
|
|
@@ -92,23 +110,49 @@ class BaseOrgAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
92
110
|
}
|
|
93
111
|
return this.contents.get(username);
|
|
94
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Return the contents of all the auth files from cache. The `read` or `readAll` methods must be called first in order to populate the cache.
|
|
115
|
+
*
|
|
116
|
+
* @param decrypt if true, decrypt encrypted values
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
95
119
|
getAll(decrypt = false) {
|
|
96
120
|
return [...this.configs.keys()].reduce((orgs, username) => {
|
|
97
121
|
const org = this.get(username, decrypt);
|
|
98
122
|
return org && !(0, kit_1.isEmpty)(org) ? orgs.concat([org]) : orgs;
|
|
99
123
|
}, []);
|
|
100
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Returns true if the username has been cached.
|
|
127
|
+
*
|
|
128
|
+
* @param username
|
|
129
|
+
*/
|
|
101
130
|
has(username) {
|
|
102
131
|
return this.contents.has(username);
|
|
103
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Returns true if there is an auth file for the given username. The `read` or `readAll` methods must be called first in order to populate the cache.
|
|
135
|
+
*
|
|
136
|
+
* @param username
|
|
137
|
+
*/
|
|
104
138
|
async exists(username) {
|
|
105
139
|
const config = this.configs.get(username);
|
|
106
140
|
return config ? await config.exists() : false;
|
|
107
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Return the file stats for a given userame's auth file.
|
|
144
|
+
*
|
|
145
|
+
* @param username
|
|
146
|
+
*/
|
|
108
147
|
async stat(username) {
|
|
109
148
|
const config = this.configs.get(username);
|
|
110
149
|
return config ? await config.stat() : null;
|
|
111
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Returns true if there is an auth file for the given username
|
|
153
|
+
*
|
|
154
|
+
* @param username
|
|
155
|
+
*/
|
|
112
156
|
async hasFile(username) {
|
|
113
157
|
try {
|
|
114
158
|
await fs.promises.access(this.parseFilename(username));
|
|
@@ -119,9 +163,18 @@ class BaseOrgAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
119
163
|
return false;
|
|
120
164
|
}
|
|
121
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Return all auth files under the global state directory.
|
|
168
|
+
*/
|
|
122
169
|
async list() {
|
|
123
170
|
return this.getAllFiles();
|
|
124
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Set the contents for a given username.
|
|
174
|
+
*
|
|
175
|
+
* @param username
|
|
176
|
+
* @param org
|
|
177
|
+
*/
|
|
125
178
|
set(username, org) {
|
|
126
179
|
var _a, _b;
|
|
127
180
|
const config = this.configs.get(username);
|
|
@@ -137,17 +190,33 @@ class BaseOrgAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
137
190
|
this.contents.set(username, org);
|
|
138
191
|
}
|
|
139
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Update the contents for a given username.
|
|
195
|
+
*
|
|
196
|
+
* @param username
|
|
197
|
+
* @param org
|
|
198
|
+
*/
|
|
140
199
|
update(username, org) {
|
|
141
200
|
const existing = this.get(username) || {};
|
|
142
201
|
const merged = Object.assign({}, existing, org);
|
|
143
202
|
return this.set(username, merged);
|
|
144
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Delete the auth file for a given username.
|
|
206
|
+
*
|
|
207
|
+
* @param username
|
|
208
|
+
*/
|
|
145
209
|
async remove(username) {
|
|
146
210
|
var _a;
|
|
147
211
|
await ((_a = this.configs.get(username)) === null || _a === void 0 ? void 0 : _a.unlink());
|
|
148
212
|
this.configs.delete(username);
|
|
149
213
|
this.contents.delete(username);
|
|
150
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Write the contents of the auth file for a given username.
|
|
217
|
+
*
|
|
218
|
+
* @param username
|
|
219
|
+
*/
|
|
151
220
|
async write(username) {
|
|
152
221
|
const config = this.configs.get(username);
|
|
153
222
|
if (config) {
|
|
@@ -17,12 +17,53 @@ export declare class GlobaInfoTokenAccessor {
|
|
|
17
17
|
}
|
|
18
18
|
export declare class TokenAccessor extends AsyncOptionalCreatable {
|
|
19
19
|
private config;
|
|
20
|
+
/**
|
|
21
|
+
* Return all tokens.
|
|
22
|
+
*
|
|
23
|
+
* @param decrypt
|
|
24
|
+
* @returns {SfTokens}
|
|
25
|
+
*/
|
|
20
26
|
getAll(decrypt?: boolean): SfTokens;
|
|
27
|
+
/**
|
|
28
|
+
* Return a token for the provided name.
|
|
29
|
+
*
|
|
30
|
+
* @param name
|
|
31
|
+
* @param decrypt
|
|
32
|
+
* @returns {Optional<SfToken & Timestamp>}
|
|
33
|
+
*/
|
|
21
34
|
get(name: string, decrypt?: boolean): Optional<SfToken & Timestamp>;
|
|
35
|
+
/**
|
|
36
|
+
* Return true if a given name has a token associated with it.
|
|
37
|
+
*
|
|
38
|
+
* @param name
|
|
39
|
+
* @returns {boolean}
|
|
40
|
+
*/
|
|
22
41
|
has(name: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Set the token for the provided name.
|
|
44
|
+
*
|
|
45
|
+
* @param name
|
|
46
|
+
* @param token
|
|
47
|
+
*/
|
|
23
48
|
set(name: string, token: SfToken): void;
|
|
49
|
+
/**
|
|
50
|
+
* Update the token for the provided name.
|
|
51
|
+
*
|
|
52
|
+
* @param name
|
|
53
|
+
* @param token
|
|
54
|
+
*/
|
|
24
55
|
update(name: string, token: Partial<SfToken>): void;
|
|
56
|
+
/**
|
|
57
|
+
* Unet the token for the provided name.
|
|
58
|
+
*
|
|
59
|
+
* @param name
|
|
60
|
+
*/
|
|
25
61
|
unset(name: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Write the contents to the token file.
|
|
64
|
+
*
|
|
65
|
+
* @returns {Promise<SfTokens>}
|
|
66
|
+
*/
|
|
26
67
|
write(): Promise<SfTokens>;
|
|
27
68
|
protected init(): Promise<void>;
|
|
28
69
|
}
|
|
@@ -38,24 +38,65 @@ class GlobaInfoTokenAccessor {
|
|
|
38
38
|
}
|
|
39
39
|
exports.GlobaInfoTokenAccessor = GlobaInfoTokenAccessor;
|
|
40
40
|
class TokenAccessor extends kit_1.AsyncOptionalCreatable {
|
|
41
|
+
/**
|
|
42
|
+
* Return all tokens.
|
|
43
|
+
*
|
|
44
|
+
* @param decrypt
|
|
45
|
+
* @returns {SfTokens}
|
|
46
|
+
*/
|
|
41
47
|
getAll(decrypt = false) {
|
|
42
48
|
return this.config.getContents(decrypt) || {};
|
|
43
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Return a token for the provided name.
|
|
52
|
+
*
|
|
53
|
+
* @param name
|
|
54
|
+
* @param decrypt
|
|
55
|
+
* @returns {Optional<SfToken & Timestamp>}
|
|
56
|
+
*/
|
|
44
57
|
get(name, decrypt = false) {
|
|
45
58
|
return this.config.get(name, decrypt);
|
|
46
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Return true if a given name has a token associated with it.
|
|
62
|
+
*
|
|
63
|
+
* @param name
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
47
66
|
has(name) {
|
|
48
67
|
return !!this.getAll()[name];
|
|
49
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Set the token for the provided name.
|
|
71
|
+
*
|
|
72
|
+
* @param name
|
|
73
|
+
* @param token
|
|
74
|
+
*/
|
|
50
75
|
set(name, token) {
|
|
51
76
|
this.config.set(name, token);
|
|
52
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Update the token for the provided name.
|
|
80
|
+
*
|
|
81
|
+
* @param name
|
|
82
|
+
* @param token
|
|
83
|
+
*/
|
|
53
84
|
update(name, token) {
|
|
54
85
|
this.config.update(name, token);
|
|
55
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Unet the token for the provided name.
|
|
89
|
+
*
|
|
90
|
+
* @param name
|
|
91
|
+
*/
|
|
56
92
|
unset(name) {
|
|
57
93
|
this.config.unset(name);
|
|
58
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Write the contents to the token file.
|
|
97
|
+
*
|
|
98
|
+
* @returns {Promise<SfTokens>}
|
|
99
|
+
*/
|
|
59
100
|
async write() {
|
|
60
101
|
return this.config.write();
|
|
61
102
|
}
|
package/lib/testSetup.d.ts
CHANGED
|
@@ -88,14 +88,21 @@ export interface TestContext {
|
|
|
88
88
|
[configName: string]: Optional<ConfigStub>;
|
|
89
89
|
AliasesConfig?: ConfigStub;
|
|
90
90
|
AuthInfoConfig?: ConfigStub;
|
|
91
|
-
|
|
91
|
+
Config?: ConfigStub;
|
|
92
92
|
SfProjectJson?: ConfigStub;
|
|
93
93
|
TokensConfig?: ConfigStub;
|
|
94
94
|
};
|
|
95
95
|
/**
|
|
96
96
|
* An record of stubs created during instantaion.
|
|
97
97
|
*/
|
|
98
|
-
stubs
|
|
98
|
+
stubs: {
|
|
99
|
+
configRead?: sinonType.SinonStub;
|
|
100
|
+
configReadSync?: sinonType.SinonStub;
|
|
101
|
+
configWriteSync?: sinonType.SinonStub;
|
|
102
|
+
configWrite?: sinonType.SinonStub;
|
|
103
|
+
configExists?: sinonType.SinonStub;
|
|
104
|
+
configRemove?: sinonType.SinonStub;
|
|
105
|
+
};
|
|
99
106
|
/**
|
|
100
107
|
* A function used when resolving the local path. Calls localPathResolverSync by default.
|
|
101
108
|
*
|
|
@@ -161,6 +168,8 @@ export interface TestContext {
|
|
|
161
168
|
stubAuths(...orgs: MockTestOrgData[]): Promise<void>;
|
|
162
169
|
stubSandboxes(...orgs: MockTestSandboxData[]): Promise<void>;
|
|
163
170
|
stubAliases(aliases: Record<string, string>, group?: AliasGroup): void;
|
|
171
|
+
stubConfig(config: Record<string, string>): void;
|
|
172
|
+
stubTokens(tokens: Record<string, string>): void;
|
|
164
173
|
}
|
|
165
174
|
export declare const uniqid: () => string;
|
|
166
175
|
/**
|
|
@@ -286,7 +295,29 @@ export declare const unexpectedResult: SfError;
|
|
|
286
295
|
*
|
|
287
296
|
* @param f The async function that is expected to throw.
|
|
288
297
|
*/
|
|
289
|
-
export declare function shouldThrow(f: Promise<unknown
|
|
298
|
+
export declare function shouldThrow(f: Promise<unknown>, message?: string): Promise<never>;
|
|
299
|
+
/**
|
|
300
|
+
* Use for this testing pattern:
|
|
301
|
+
* ```
|
|
302
|
+
* try {
|
|
303
|
+
* call()
|
|
304
|
+
* assert.fail('this should never happen');
|
|
305
|
+
* } catch (e) {
|
|
306
|
+
* ...
|
|
307
|
+
* }
|
|
308
|
+
*
|
|
309
|
+
* Just do this
|
|
310
|
+
*
|
|
311
|
+
* try {
|
|
312
|
+
* shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
|
|
313
|
+
* } catch(e) {
|
|
314
|
+
* ...
|
|
315
|
+
* }
|
|
316
|
+
* ```
|
|
317
|
+
*
|
|
318
|
+
* @param f The function that is expected to throw.
|
|
319
|
+
*/
|
|
320
|
+
export declare function shouldThrowSync(f: () => unknown, message?: string): never;
|
|
290
321
|
/**
|
|
291
322
|
* A helper to determine if a subscription will use callback or errorback.
|
|
292
323
|
* Enable errback to simulate a subscription failure.
|
package/lib/testSetup.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrow = exports.unexpectedResult = exports.testSetup = exports.restoreContext = exports.stubContext = exports.instantiateContext = exports.uniqid = void 0;
|
|
3
|
+
exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrowSync = exports.shouldThrow = exports.unexpectedResult = exports.testSetup = exports.restoreContext = exports.stubContext = exports.instantiateContext = exports.uniqid = void 0;
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
6
|
* All rights reserved.
|
|
@@ -102,6 +102,7 @@ const instantiateContext = (sinon) => {
|
|
|
102
102
|
id: (0, exports.uniqid)(),
|
|
103
103
|
uniqid: exports.uniqid,
|
|
104
104
|
configStubs: {},
|
|
105
|
+
stubs: {},
|
|
105
106
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
106
107
|
localPathRetriever: async (uid) => getTestLocalPath(uid),
|
|
107
108
|
localPathRetrieverSync: getTestLocalPath,
|
|
@@ -167,6 +168,12 @@ const instantiateContext = (sinon) => {
|
|
|
167
168
|
stubAliases(aliases, group = aliasesConfig_1.AliasGroup.ORGS) {
|
|
168
169
|
this.configStubs.AliasesConfig = { contents: { [group]: aliases } };
|
|
169
170
|
},
|
|
171
|
+
stubConfig(config) {
|
|
172
|
+
this.configStubs.Config = { contents: config };
|
|
173
|
+
},
|
|
174
|
+
stubTokens(tokens) {
|
|
175
|
+
this.configStubs.TokensConfig = { contents: tokens };
|
|
176
|
+
},
|
|
170
177
|
};
|
|
171
178
|
return testContext;
|
|
172
179
|
};
|
|
@@ -235,8 +242,8 @@ const stubContext = (testContext) => {
|
|
|
235
242
|
};
|
|
236
243
|
// Mock out all config file IO for all tests. They can restore individually if they need original functionality.
|
|
237
244
|
// @ts-ignore
|
|
238
|
-
testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'readSync').callsFake(readSync);
|
|
239
|
-
testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'read').callsFake(read);
|
|
245
|
+
stubs.configRead = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'readSync').callsFake(readSync);
|
|
246
|
+
stubs.configReadSync = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'read').callsFake(read);
|
|
240
247
|
const writeSync = function (newContents) {
|
|
241
248
|
if (!testContext.configStubs[this.constructor.name]) {
|
|
242
249
|
testContext.configStubs[this.constructor.name] = {};
|
|
@@ -395,11 +402,47 @@ exports.unexpectedResult = new sfError_1.SfError('This code was expected to fail
|
|
|
395
402
|
*
|
|
396
403
|
* @param f The async function that is expected to throw.
|
|
397
404
|
*/
|
|
398
|
-
async function shouldThrow(f) {
|
|
405
|
+
async function shouldThrow(f, message) {
|
|
399
406
|
await f;
|
|
400
|
-
|
|
407
|
+
if (message) {
|
|
408
|
+
throw new sfError_1.SfError(message, 'UnexpectedResult');
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
throw exports.unexpectedResult;
|
|
412
|
+
}
|
|
401
413
|
}
|
|
402
414
|
exports.shouldThrow = shouldThrow;
|
|
415
|
+
/**
|
|
416
|
+
* Use for this testing pattern:
|
|
417
|
+
* ```
|
|
418
|
+
* try {
|
|
419
|
+
* call()
|
|
420
|
+
* assert.fail('this should never happen');
|
|
421
|
+
* } catch (e) {
|
|
422
|
+
* ...
|
|
423
|
+
* }
|
|
424
|
+
*
|
|
425
|
+
* Just do this
|
|
426
|
+
*
|
|
427
|
+
* try {
|
|
428
|
+
* shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
|
|
429
|
+
* } catch(e) {
|
|
430
|
+
* ...
|
|
431
|
+
* }
|
|
432
|
+
* ```
|
|
433
|
+
*
|
|
434
|
+
* @param f The function that is expected to throw.
|
|
435
|
+
*/
|
|
436
|
+
function shouldThrowSync(f, message) {
|
|
437
|
+
f();
|
|
438
|
+
if (message) {
|
|
439
|
+
throw new sfError_1.SfError(message, 'UnexpectedResult');
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
throw exports.unexpectedResult;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
exports.shouldThrowSync = shouldThrowSync;
|
|
403
446
|
/**
|
|
404
447
|
* A helper to determine if a subscription will use callback or errorback.
|
|
405
448
|
* Enable errback to simulate a subscription failure.
|
|
@@ -536,7 +579,7 @@ class MockTestOrgData {
|
|
|
536
579
|
this.authcode = `${this.testId}/authcode`;
|
|
537
580
|
this.accessToken = `${this.testId}/accessToken`;
|
|
538
581
|
this.refreshToken = `${this.testId}/refreshToken`;
|
|
539
|
-
this.redirectUri =
|
|
582
|
+
this.redirectUri = 'http://localhost:1717/OauthRedirect';
|
|
540
583
|
}
|
|
541
584
|
createDevHubUsername(username) {
|
|
542
585
|
this.devHubUsername = username;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/core",
|
|
3
|
-
"version": "3.21.
|
|
3
|
+
"version": "3.21.6",
|
|
4
4
|
"description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
|
|
5
5
|
"main": "lib/exported",
|
|
6
6
|
"types": "lib/exported.d.ts",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"form-data": "^4.0.0",
|
|
50
50
|
"graceful-fs": "^4.2.9",
|
|
51
51
|
"js2xmlparser": "^4.0.1",
|
|
52
|
-
"jsforce": "2.0.0-beta.
|
|
52
|
+
"jsforce": "2.0.0-beta.14",
|
|
53
53
|
"jsonwebtoken": "8.5.1",
|
|
54
54
|
"mkdirp": "1.0.4",
|
|
55
55
|
"ts-retry-promise": "^0.6.0"
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"@types/debug": "0.0.31",
|
|
64
64
|
"@types/jsen": "0.0.21",
|
|
65
65
|
"@types/jsonwebtoken": "8.5.7",
|
|
66
|
+
"@types/lodash": "^4.14.182",
|
|
66
67
|
"@types/shelljs": "0.8.11",
|
|
67
68
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
68
69
|
"@typescript-eslint/parser": "4.33.0",
|
|
@@ -78,6 +79,7 @@
|
|
|
78
79
|
"eslint-plugin-jsdoc": "^35.1.2",
|
|
79
80
|
"eslint-plugin-prettier": "^3.1.3",
|
|
80
81
|
"husky": "^7.0.4",
|
|
82
|
+
"lodash": "^4.17.21",
|
|
81
83
|
"mocha": "^9.1.3",
|
|
82
84
|
"nyc": "^15.1.0",
|
|
83
85
|
"prettier": "^2.5.1",
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ConfigFile } from './configFile';
|
|
2
|
-
import { ConfigContents } from './configStore';
|
|
3
|
-
/**
|
|
4
|
-
* Represent a key chain config backed by a json file.
|
|
5
|
-
*/
|
|
6
|
-
export declare class KeychainConfig extends ConfigFile<ConfigFile.Options> {
|
|
7
|
-
static getFileName(): string;
|
|
8
|
-
/**
|
|
9
|
-
* Gets default options for the KeychainConfig
|
|
10
|
-
*/
|
|
11
|
-
static getDefaultOptions(): ConfigFile.Options;
|
|
12
|
-
/**
|
|
13
|
-
* Write the config file with new contents. If no new contents are passed in
|
|
14
|
-
* it will write this.contents that was set from read(). Returns the written contents.
|
|
15
|
-
*
|
|
16
|
-
* @param newContents the new contents of the file
|
|
17
|
-
*/
|
|
18
|
-
write(newContents?: ConfigContents): Promise<ConfigContents>;
|
|
19
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright (c) 2020, 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.KeychainConfig = void 0;
|
|
10
|
-
const path_1 = require("path");
|
|
11
|
-
const fs = require("fs");
|
|
12
|
-
const mkdirp = require("mkdirp");
|
|
13
|
-
const configFile_1 = require("./configFile");
|
|
14
|
-
/**
|
|
15
|
-
* Represent a key chain config backed by a json file.
|
|
16
|
-
*/
|
|
17
|
-
// istanbul ignore next - getPassword/setPassword is always mocked out
|
|
18
|
-
class KeychainConfig extends configFile_1.ConfigFile {
|
|
19
|
-
static getFileName() {
|
|
20
|
-
return 'key.json';
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Gets default options for the KeychainConfig
|
|
24
|
-
*/
|
|
25
|
-
static getDefaultOptions() {
|
|
26
|
-
return configFile_1.ConfigFile.getDefaultOptions(true, KeychainConfig.getFileName());
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Write the config file with new contents. If no new contents are passed in
|
|
30
|
-
* it will write this.contents that was set from read(). Returns the written contents.
|
|
31
|
-
*
|
|
32
|
-
* @param newContents the new contents of the file
|
|
33
|
-
*/
|
|
34
|
-
async write(newContents) {
|
|
35
|
-
if (newContents != null) {
|
|
36
|
-
this.setContents(newContents);
|
|
37
|
-
}
|
|
38
|
-
await mkdirp((0, path_1.dirname)(this.getPath()));
|
|
39
|
-
await fs.promises.writeFile(this.getPath(), JSON.stringify(this.getContents(), null, 4), { mode: '600' });
|
|
40
|
-
return this.getContents();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
exports.KeychainConfig = KeychainConfig;
|
|
44
|
-
//# sourceMappingURL=keychainConfig.js.map
|