@salesforce/core 3.30.14 → 3.31.7
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/LICENSE.txt +11 -11
- package/README.md +222 -227
- package/lib/config/aliasesConfig.d.ts +12 -12
- package/lib/config/aliasesConfig.js +27 -27
- package/lib/config/authInfoConfig.d.ts +19 -19
- package/lib/config/authInfoConfig.js +34 -34
- package/lib/config/config.d.ts +311 -311
- package/lib/config/config.js +574 -574
- package/lib/config/configAggregator.d.ts +232 -232
- package/lib/config/configAggregator.js +379 -379
- package/lib/config/configFile.d.ts +199 -199
- package/lib/config/configFile.js +340 -340
- package/lib/config/configGroup.d.ts +141 -141
- package/lib/config/configGroup.js +224 -224
- package/lib/config/configStore.d.ts +241 -241
- package/lib/config/configStore.js +352 -352
- package/lib/config/envVars.d.ts +101 -101
- package/lib/config/envVars.js +456 -456
- package/lib/config/orgUsersConfig.d.ts +31 -31
- package/lib/config/orgUsersConfig.js +41 -41
- package/lib/config/sandboxOrgConfig.d.ts +37 -37
- package/lib/config/sandboxOrgConfig.js +50 -50
- package/lib/config/sandboxProcessCache.d.ts +16 -16
- package/lib/config/sandboxProcessCache.js +37 -37
- package/lib/config/tokensConfig.d.ts +10 -10
- package/lib/config/tokensConfig.js +28 -28
- package/lib/config/ttlConfig.d.ts +34 -34
- package/lib/config/ttlConfig.js +54 -54
- package/lib/crypto/crypto.d.ts +54 -54
- package/lib/crypto/crypto.js +220 -220
- package/lib/crypto/keyChain.d.ts +8 -8
- package/lib/crypto/keyChain.js +61 -61
- package/lib/crypto/keyChainImpl.d.ts +116 -116
- package/lib/crypto/keyChainImpl.js +486 -486
- package/lib/crypto/secureBuffer.d.ts +46 -46
- package/lib/crypto/secureBuffer.js +82 -82
- package/lib/deviceOauthService.d.ts +71 -71
- package/lib/deviceOauthService.js +191 -191
- package/lib/exported.d.ts +38 -38
- package/lib/exported.js +118 -118
- package/lib/global.d.ts +70 -70
- package/lib/global.js +109 -109
- package/lib/lifecycleEvents.d.ts +93 -93
- package/lib/lifecycleEvents.js +188 -188
- package/lib/logger.d.ts +381 -381
- package/lib/logger.js +734 -734
- package/lib/messages.d.ts +291 -291
- package/lib/messages.js +543 -543
- package/lib/org/authInfo.d.ts +344 -344
- package/lib/org/authInfo.js +892 -892
- package/lib/org/authRemover.d.ts +88 -88
- package/lib/org/authRemover.js +182 -182
- package/lib/org/connection.d.ts +197 -197
- package/lib/org/connection.js +395 -395
- package/lib/org/index.d.ts +6 -6
- package/lib/org/index.js +28 -28
- package/lib/org/org.d.ts +558 -558
- package/lib/org/org.js +1267 -1267
- package/lib/org/orgConfigProperties.d.ts +69 -69
- package/lib/org/orgConfigProperties.js +136 -136
- package/lib/org/permissionSetAssignment.d.ts +35 -35
- package/lib/org/permissionSetAssignment.js +125 -125
- package/lib/org/scratchOrgCache.d.ts +20 -20
- package/lib/org/scratchOrgCache.js +32 -32
- package/lib/org/scratchOrgCreate.d.ts +54 -54
- package/lib/org/scratchOrgCreate.js +216 -216
- package/lib/org/scratchOrgErrorCodes.d.ts +10 -10
- package/lib/org/scratchOrgErrorCodes.js +88 -88
- package/lib/org/scratchOrgFeatureDeprecation.d.ts +26 -26
- package/lib/org/scratchOrgFeatureDeprecation.js +109 -109
- package/lib/org/scratchOrgInfoApi.d.ts +68 -68
- package/lib/org/scratchOrgInfoApi.js +413 -413
- package/lib/org/scratchOrgInfoGenerator.d.ts +64 -64
- package/lib/org/scratchOrgInfoGenerator.js +241 -241
- package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -10
- package/lib/org/scratchOrgLifecycleEvents.js +40 -40
- package/lib/org/scratchOrgSettingsGenerator.d.ts +78 -78
- package/lib/org/scratchOrgSettingsGenerator.js +276 -276
- package/lib/org/scratchOrgTypes.d.ts +43 -43
- package/lib/org/scratchOrgTypes.js +8 -8
- package/lib/org/user.d.ts +187 -187
- package/lib/org/user.js +448 -448
- package/lib/schema/printer.d.ts +79 -79
- package/lib/schema/printer.js +260 -260
- package/lib/schema/validator.d.ts +70 -70
- package/lib/schema/validator.js +169 -169
- package/lib/sfError.d.ts +73 -73
- package/lib/sfError.js +136 -136
- package/lib/sfProject.d.ts +357 -357
- package/lib/sfProject.js +671 -671
- package/lib/stateAggregator/accessors/aliasAccessor.d.ts +98 -98
- package/lib/stateAggregator/accessors/aliasAccessor.js +145 -145
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -101
- package/lib/stateAggregator/accessors/orgAccessor.js +240 -240
- package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -8
- package/lib/stateAggregator/accessors/sandboxAccessor.js +27 -27
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -63
- package/lib/stateAggregator/accessors/tokenAccessor.js +79 -79
- package/lib/stateAggregator/index.d.ts +4 -4
- package/lib/stateAggregator/index.js +26 -26
- package/lib/stateAggregator/stateAggregator.d.ts +25 -25
- package/lib/stateAggregator/stateAggregator.js +45 -45
- package/lib/status/myDomainResolver.d.ts +66 -66
- package/lib/status/myDomainResolver.js +124 -124
- package/lib/status/pollingClient.d.ts +85 -85
- package/lib/status/pollingClient.js +115 -115
- package/lib/status/streamingClient.d.ts +244 -244
- package/lib/status/streamingClient.js +436 -436
- package/lib/status/types.d.ts +89 -89
- package/lib/status/types.js +17 -17
- package/lib/testSetup.d.ts +553 -530
- package/lib/testSetup.js +871 -727
- package/lib/util/cache.d.ts +11 -11
- package/lib/util/cache.js +69 -69
- package/lib/util/checkLightningDomain.d.ts +1 -1
- package/lib/util/checkLightningDomain.js +28 -28
- package/lib/util/directoryWriter.d.ts +12 -12
- package/lib/util/directoryWriter.js +53 -53
- package/lib/util/getJwtAudienceUrl.d.ts +4 -4
- package/lib/util/getJwtAudienceUrl.js +18 -18
- package/lib/util/internal.d.ts +58 -58
- package/lib/util/internal.js +118 -118
- package/lib/util/jsonXmlTools.d.ts +14 -14
- package/lib/util/jsonXmlTools.js +38 -38
- package/lib/util/mapKeys.d.ts +14 -14
- package/lib/util/mapKeys.js +51 -51
- package/lib/util/sfdc.d.ts +52 -52
- package/lib/util/sfdc.js +85 -85
- package/lib/util/sfdcUrl.d.ts +72 -72
- package/lib/util/sfdcUrl.js +215 -215
- package/lib/util/structuredWriter.d.ts +9 -9
- package/lib/util/structuredWriter.js +2 -2
- package/lib/util/zipWriter.d.ts +16 -16
- package/lib/util/zipWriter.js +67 -67
- package/lib/webOAuthServer.d.ts +156 -156
- package/lib/webOAuthServer.js +388 -388
- package/messages/auth.md +37 -37
- package/messages/config.md +156 -156
- package/messages/connection.md +30 -30
- package/messages/core.json +20 -20
- package/messages/core.md +67 -67
- package/messages/encryption.md +85 -85
- package/messages/envVars.md +303 -303
- package/messages/org.md +63 -63
- package/messages/permissionSetAssignment.md +31 -31
- package/messages/scratchOrgCreate.md +23 -23
- package/messages/scratchOrgErrorCodes.md +115 -115
- package/messages/scratchOrgFeatureDeprecation.md +11 -11
- package/messages/scratchOrgInfoApi.md +15 -15
- package/messages/scratchOrgInfoGenerator.md +23 -23
- package/messages/streaming.md +23 -23
- package/messages/user.md +35 -35
- package/package.json +97 -97
|
@@ -1,353 +1,353 @@
|
|
|
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.BaseConfigStore = void 0;
|
|
10
|
-
const kit_1 = require("@salesforce/kit");
|
|
11
|
-
const ts_types_1 = require("@salesforce/ts-types");
|
|
12
|
-
const ts_types_2 = require("@salesforce/ts-types");
|
|
13
|
-
const crypto_1 = require("../crypto/crypto");
|
|
14
|
-
const sfError_1 = require("../sfError");
|
|
15
|
-
/**
|
|
16
|
-
* An abstract class that implements all the config management functions but
|
|
17
|
-
* none of the storage functions.
|
|
18
|
-
*
|
|
19
|
-
* **Note:** To see the interface, look in typescripts autocomplete help or the npm package's ConfigStore.d.ts file.
|
|
20
|
-
*/
|
|
21
|
-
class BaseConfigStore extends kit_1.AsyncOptionalCreatable {
|
|
22
|
-
/**
|
|
23
|
-
* Constructor.
|
|
24
|
-
*
|
|
25
|
-
* @param options The options for the class instance.
|
|
26
|
-
* @ignore
|
|
27
|
-
*/
|
|
28
|
-
constructor(options) {
|
|
29
|
-
super(options);
|
|
30
|
-
this.statics = this.constructor;
|
|
31
|
-
this.options = options ?? {};
|
|
32
|
-
this.setContents(this.initialContents());
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Returns an array of {@link ConfigEntry} for each element in the config.
|
|
36
|
-
*/
|
|
37
|
-
entries() {
|
|
38
|
-
return (0, ts_types_2.definiteEntriesOf)(this.contents);
|
|
39
|
-
}
|
|
40
|
-
get(key, decrypt = false) {
|
|
41
|
-
const k = key;
|
|
42
|
-
let value = this.getMethod(this.contents, k);
|
|
43
|
-
if (this.hasEncryption() && decrypt) {
|
|
44
|
-
if ((0, ts_types_2.isJsonMap)(value)) {
|
|
45
|
-
value = this.recursiveDecrypt((0, kit_1.cloneJson)(value), k);
|
|
46
|
-
}
|
|
47
|
-
else if (this.isCryptoKey(k)) {
|
|
48
|
-
value = this.decrypt(value);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return value;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Returns the list of keys that contain a value.
|
|
55
|
-
*
|
|
56
|
-
* @param value The value to filter keys on.
|
|
57
|
-
*/
|
|
58
|
-
getKeysByValue(value) {
|
|
59
|
-
const matchedEntries = this.entries().filter((entry) => entry[1] === value);
|
|
60
|
-
// Only return the keys
|
|
61
|
-
return matchedEntries.map((entry) => entry[0]);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Returns a boolean asserting whether a value has been associated to the key in the config object or not.
|
|
65
|
-
*
|
|
66
|
-
* @param key The key. Supports query key like `a.b[0]`.
|
|
67
|
-
*/
|
|
68
|
-
has(key) {
|
|
69
|
-
return !!this.getMethod(this.contents, key);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Returns an array that contains the keys for each element in the config object.
|
|
73
|
-
*/
|
|
74
|
-
keys() {
|
|
75
|
-
return Object.keys(this.contents);
|
|
76
|
-
}
|
|
77
|
-
set(key, value) {
|
|
78
|
-
if (this.hasEncryption()) {
|
|
79
|
-
if ((0, ts_types_2.isJsonMap)(value)) {
|
|
80
|
-
value = this.recursiveEncrypt(value, key);
|
|
81
|
-
}
|
|
82
|
-
else if (this.isCryptoKey(key)) {
|
|
83
|
-
value = this.encrypt(value);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
this.setMethod(this.contents, key, value);
|
|
87
|
-
}
|
|
88
|
-
update(key, value) {
|
|
89
|
-
const existingValue = this.get(key, true);
|
|
90
|
-
if ((0, ts_types_1.isPlainObject)(existingValue) && (0, ts_types_1.isPlainObject)(value)) {
|
|
91
|
-
value = Object.assign({}, existingValue, value);
|
|
92
|
-
}
|
|
93
|
-
this.set(key, value);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Returns `true` if an element in the config object existed and has been removed, or `false` if the element does not
|
|
97
|
-
* exist. {@link BaseConfigStore.has} will return false afterwards.
|
|
98
|
-
*
|
|
99
|
-
* @param key The key. Supports query key like `a.b[0]`.
|
|
100
|
-
*/
|
|
101
|
-
unset(key) {
|
|
102
|
-
if (this.has(key)) {
|
|
103
|
-
if (this.contents[key]) {
|
|
104
|
-
delete this.contents[key];
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
// It is a query key, so just set it to undefined
|
|
108
|
-
this.setMethod(this.contents, key, undefined);
|
|
109
|
-
}
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Returns `true` if all elements in the config object existed and have been removed, or `false` if all the elements
|
|
116
|
-
* do not exist (some may have been removed). {@link BaseConfigStore.has(key)} will return false afterwards.
|
|
117
|
-
*
|
|
118
|
-
* @param keys The keys. Supports query keys like `a.b[0]`.
|
|
119
|
-
*/
|
|
120
|
-
unsetAll(keys) {
|
|
121
|
-
return keys.reduce((val, key) => val && this.unset(key), true);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Removes all key/value pairs from the config object.
|
|
125
|
-
*/
|
|
126
|
-
clear() {
|
|
127
|
-
this.contents = {};
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Returns an array that contains the values for each element in the config object.
|
|
131
|
-
*/
|
|
132
|
-
values() {
|
|
133
|
-
return (0, ts_types_2.definiteValuesOf)(this.contents);
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Returns the entire config contents.
|
|
137
|
-
*
|
|
138
|
-
* *NOTE:* Data will still be encrypted unless decrypt is passed in. A clone of
|
|
139
|
-
* the data will be returned to prevent storing un-encrypted data in memory and
|
|
140
|
-
* potentially saving to the file system.
|
|
141
|
-
*
|
|
142
|
-
* @param decrypt: decrypt all data in the config. A clone of the data will be returned.
|
|
143
|
-
*
|
|
144
|
-
*/
|
|
145
|
-
getContents(decrypt = false) {
|
|
146
|
-
if (!this.contents) {
|
|
147
|
-
this.setContents();
|
|
148
|
-
}
|
|
149
|
-
if (this.hasEncryption() && decrypt) {
|
|
150
|
-
return this.recursiveDecrypt((0, kit_1.cloneJson)(this.contents));
|
|
151
|
-
}
|
|
152
|
-
return this.contents;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Sets the entire config contents.
|
|
156
|
-
*
|
|
157
|
-
* @param contents The contents.
|
|
158
|
-
*/
|
|
159
|
-
setContents(contents = {}) {
|
|
160
|
-
if (this.hasEncryption()) {
|
|
161
|
-
contents = this.recursiveEncrypt(contents);
|
|
162
|
-
}
|
|
163
|
-
this.contents = contents;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Invokes `actionFn` once for each key-value pair present in the config object.
|
|
167
|
-
*
|
|
168
|
-
* @param {function} actionFn The function `(key: string, value: ConfigValue) => void` to be called for each element.
|
|
169
|
-
*/
|
|
170
|
-
forEach(actionFn) {
|
|
171
|
-
const entries = this.entries();
|
|
172
|
-
for (const entry of entries) {
|
|
173
|
-
actionFn(entry[0], entry[1]);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Asynchronously invokes `actionFn` once for each key-value pair present in the config object.
|
|
178
|
-
*
|
|
179
|
-
* @param {function} actionFn The function `(key: string, value: ConfigValue) => Promise<void>` to be called for
|
|
180
|
-
* each element.
|
|
181
|
-
* @returns {Promise<void>}
|
|
182
|
-
*/
|
|
183
|
-
async awaitEach(actionFn) {
|
|
184
|
-
const entries = this.entries();
|
|
185
|
-
for (const entry of entries) {
|
|
186
|
-
// prevent ConfigFile collision bug
|
|
187
|
-
// eslint-disable-next-line no-await-in-loop
|
|
188
|
-
await actionFn(entry[0], entry[1]);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Convert the config object to a JSON object. Returns the config contents.
|
|
193
|
-
* Same as calling {@link ConfigStore.getContents}
|
|
194
|
-
*/
|
|
195
|
-
toObject() {
|
|
196
|
-
return this.contents;
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Convert an object to a {@link ConfigContents} and set it as the config contents.
|
|
200
|
-
*
|
|
201
|
-
* @param obj The object.
|
|
202
|
-
*/
|
|
203
|
-
setContentsFromObject(obj) {
|
|
204
|
-
this.contents = (this.hasEncryption() ? this.recursiveEncrypt(obj) : {});
|
|
205
|
-
Object.entries(obj).forEach(([key, value]) => {
|
|
206
|
-
this.setMethod(this.contents, key, value);
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
getEncryptedKeys() {
|
|
210
|
-
return [...(this.options?.encryptedKeys ?? []), ...(this.statics?.encryptedKeys || [])];
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* This config file has encrypted keys and it should attempt to encrypt them.
|
|
214
|
-
*
|
|
215
|
-
* @returns Has encrypted keys
|
|
216
|
-
*/
|
|
217
|
-
hasEncryption() {
|
|
218
|
-
return this.getEncryptedKeys().length > 0;
|
|
219
|
-
}
|
|
220
|
-
// Allows extended classes the ability to override the set method. i.e. maybe they want
|
|
221
|
-
// nested object set from kit.
|
|
222
|
-
// eslint-disable-next-line class-methods-use-this
|
|
223
|
-
setMethod(contents, key, value) {
|
|
224
|
-
(0, kit_1.set)(contents, key, value);
|
|
225
|
-
}
|
|
226
|
-
// Allows extended classes the ability to override the get method. i.e. maybe they want
|
|
227
|
-
// nested object get from ts-types.
|
|
228
|
-
// NOTE: Key must stay string to be reliably overwritten.
|
|
229
|
-
// eslint-disable-next-line class-methods-use-this
|
|
230
|
-
getMethod(contents, key) {
|
|
231
|
-
return (0, ts_types_2.get)(contents, key);
|
|
232
|
-
}
|
|
233
|
-
// eslint-disable-next-line class-methods-use-this
|
|
234
|
-
initialContents() {
|
|
235
|
-
return {};
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Used to initialize asynchronous components.
|
|
239
|
-
*/
|
|
240
|
-
async init() {
|
|
241
|
-
if (this.hasEncryption()) {
|
|
242
|
-
await this.initCrypto();
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Initialize the crypto dependency.
|
|
247
|
-
*/
|
|
248
|
-
async initCrypto() {
|
|
249
|
-
if (!this.crypto) {
|
|
250
|
-
this.crypto = await crypto_1.Crypto.create();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Closes the crypto dependency. Crypto should be close after it's used and no longer needed.
|
|
255
|
-
*/
|
|
256
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
257
|
-
async clearCrypto() {
|
|
258
|
-
if (this.crypto) {
|
|
259
|
-
this.crypto.close();
|
|
260
|
-
delete this.crypto;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Should the given key be encrypted on set methods and decrypted on get methods.
|
|
265
|
-
*
|
|
266
|
-
* @param key The key. Supports query key like `a.b[0]`.
|
|
267
|
-
* @returns Should encrypt/decrypt
|
|
268
|
-
*/
|
|
269
|
-
isCryptoKey(key) {
|
|
270
|
-
function resolveProperty() {
|
|
271
|
-
// Handle query keys
|
|
272
|
-
const dotAccessor = /\.([a-zA-Z0-9@._-]+)$/;
|
|
273
|
-
const singleQuoteAccessor = /\['([a-zA-Z0-9@._-]+)'\]$/;
|
|
274
|
-
const doubleQuoteAccessor = /\["([a-zA-Z0-9@._-]+)"\]$/;
|
|
275
|
-
const matcher = dotAccessor.exec(key) ?? singleQuoteAccessor.exec(key) ?? doubleQuoteAccessor.exec(key);
|
|
276
|
-
return matcher ? matcher[1] : key;
|
|
277
|
-
}
|
|
278
|
-
// Any keys named the following should be encrypted/decrypted
|
|
279
|
-
return (this.statics.encryptedKeys || []).find((keyOrExp) => {
|
|
280
|
-
const property = resolveProperty();
|
|
281
|
-
if (keyOrExp instanceof RegExp) {
|
|
282
|
-
return keyOrExp.test(property);
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
return keyOrExp === property;
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
encrypt(value) {
|
|
290
|
-
if (!value)
|
|
291
|
-
return;
|
|
292
|
-
if (!this.crypto)
|
|
293
|
-
throw new sfError_1.SfError('crypto is not initialized', 'CryptoNotInitializedError');
|
|
294
|
-
if (!(0, ts_types_2.isString)(value))
|
|
295
|
-
throw new sfError_1.SfError(`can only encrypt strings but found: ${typeof value} : ${value.toString()}`, 'InvalidCryptoValueError');
|
|
296
|
-
return this.crypto.isEncrypted(value) ? value : this.crypto.encrypt(value);
|
|
297
|
-
}
|
|
298
|
-
decrypt(value) {
|
|
299
|
-
if (!value)
|
|
300
|
-
return;
|
|
301
|
-
if (!this.crypto)
|
|
302
|
-
throw new sfError_1.SfError('crypto is not initialized', 'CryptoNotInitializedError');
|
|
303
|
-
if (!(0, ts_types_2.isString)(value))
|
|
304
|
-
throw new sfError_1.SfError(`can only encrypt strings but found: ${typeof value} : ${value.toString()}`, 'InvalidCryptoValueError');
|
|
305
|
-
return this.crypto.isEncrypted(value) ? this.crypto.decrypt(value) : value;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Encrypt all values in a nested JsonMap.
|
|
309
|
-
*
|
|
310
|
-
* @param keyPaths: The complete path of the (nested) data
|
|
311
|
-
* @param data: The current (nested) data being worked on.
|
|
312
|
-
*/
|
|
313
|
-
recursiveEncrypt(data, parentKey) {
|
|
314
|
-
for (const key of Object.keys(data)) {
|
|
315
|
-
this.recursiveCrypto(this.encrypt.bind(this), [...(parentKey ? [parentKey] : []), key], data);
|
|
316
|
-
}
|
|
317
|
-
return data;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Decrypt all values in a nested JsonMap.
|
|
321
|
-
*
|
|
322
|
-
* @param keyPaths: The complete path of the (nested) data
|
|
323
|
-
* @param data: The current (nested) data being worked on.
|
|
324
|
-
*/
|
|
325
|
-
recursiveDecrypt(data, parentKey) {
|
|
326
|
-
for (const key of Object.keys(data)) {
|
|
327
|
-
this.recursiveCrypto(this.decrypt.bind(this), [...(parentKey ? [parentKey] : []), key], data);
|
|
328
|
-
}
|
|
329
|
-
return data;
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Encrypt/Decrypt all values in a nested JsonMap.
|
|
333
|
-
*
|
|
334
|
-
* @param keyPaths: The complete path of the (nested) data
|
|
335
|
-
* @param data: The current (nested) data being worked on.
|
|
336
|
-
*/
|
|
337
|
-
recursiveCrypto(method, keyPaths, data) {
|
|
338
|
-
const key = keyPaths.pop();
|
|
339
|
-
const value = data[key];
|
|
340
|
-
if ((0, ts_types_2.isJsonMap)(value)) {
|
|
341
|
-
for (const newKey of Object.keys(value)) {
|
|
342
|
-
this.recursiveCrypto(method, [...keyPaths, key, newKey], value);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
else if (this.isCryptoKey(key)) {
|
|
346
|
-
data[key] = method(value);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
exports.BaseConfigStore = BaseConfigStore;
|
|
351
|
-
// If encryptedKeys is an array of RegExps, they should not contain the /g (global) or /y (sticky) flags to avoid stateful issues.
|
|
352
|
-
BaseConfigStore.encryptedKeys = [];
|
|
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.BaseConfigStore = void 0;
|
|
10
|
+
const kit_1 = require("@salesforce/kit");
|
|
11
|
+
const ts_types_1 = require("@salesforce/ts-types");
|
|
12
|
+
const ts_types_2 = require("@salesforce/ts-types");
|
|
13
|
+
const crypto_1 = require("../crypto/crypto");
|
|
14
|
+
const sfError_1 = require("../sfError");
|
|
15
|
+
/**
|
|
16
|
+
* An abstract class that implements all the config management functions but
|
|
17
|
+
* none of the storage functions.
|
|
18
|
+
*
|
|
19
|
+
* **Note:** To see the interface, look in typescripts autocomplete help or the npm package's ConfigStore.d.ts file.
|
|
20
|
+
*/
|
|
21
|
+
class BaseConfigStore extends kit_1.AsyncOptionalCreatable {
|
|
22
|
+
/**
|
|
23
|
+
* Constructor.
|
|
24
|
+
*
|
|
25
|
+
* @param options The options for the class instance.
|
|
26
|
+
* @ignore
|
|
27
|
+
*/
|
|
28
|
+
constructor(options) {
|
|
29
|
+
super(options);
|
|
30
|
+
this.statics = this.constructor;
|
|
31
|
+
this.options = options ?? {};
|
|
32
|
+
this.setContents(this.initialContents());
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns an array of {@link ConfigEntry} for each element in the config.
|
|
36
|
+
*/
|
|
37
|
+
entries() {
|
|
38
|
+
return (0, ts_types_2.definiteEntriesOf)(this.contents);
|
|
39
|
+
}
|
|
40
|
+
get(key, decrypt = false) {
|
|
41
|
+
const k = key;
|
|
42
|
+
let value = this.getMethod(this.contents, k);
|
|
43
|
+
if (this.hasEncryption() && decrypt) {
|
|
44
|
+
if ((0, ts_types_2.isJsonMap)(value)) {
|
|
45
|
+
value = this.recursiveDecrypt((0, kit_1.cloneJson)(value), k);
|
|
46
|
+
}
|
|
47
|
+
else if (this.isCryptoKey(k)) {
|
|
48
|
+
value = this.decrypt(value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the list of keys that contain a value.
|
|
55
|
+
*
|
|
56
|
+
* @param value The value to filter keys on.
|
|
57
|
+
*/
|
|
58
|
+
getKeysByValue(value) {
|
|
59
|
+
const matchedEntries = this.entries().filter((entry) => entry[1] === value);
|
|
60
|
+
// Only return the keys
|
|
61
|
+
return matchedEntries.map((entry) => entry[0]);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns a boolean asserting whether a value has been associated to the key in the config object or not.
|
|
65
|
+
*
|
|
66
|
+
* @param key The key. Supports query key like `a.b[0]`.
|
|
67
|
+
*/
|
|
68
|
+
has(key) {
|
|
69
|
+
return !!this.getMethod(this.contents, key);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns an array that contains the keys for each element in the config object.
|
|
73
|
+
*/
|
|
74
|
+
keys() {
|
|
75
|
+
return Object.keys(this.contents);
|
|
76
|
+
}
|
|
77
|
+
set(key, value) {
|
|
78
|
+
if (this.hasEncryption()) {
|
|
79
|
+
if ((0, ts_types_2.isJsonMap)(value)) {
|
|
80
|
+
value = this.recursiveEncrypt(value, key);
|
|
81
|
+
}
|
|
82
|
+
else if (this.isCryptoKey(key)) {
|
|
83
|
+
value = this.encrypt(value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this.setMethod(this.contents, key, value);
|
|
87
|
+
}
|
|
88
|
+
update(key, value) {
|
|
89
|
+
const existingValue = this.get(key, true);
|
|
90
|
+
if ((0, ts_types_1.isPlainObject)(existingValue) && (0, ts_types_1.isPlainObject)(value)) {
|
|
91
|
+
value = Object.assign({}, existingValue, value);
|
|
92
|
+
}
|
|
93
|
+
this.set(key, value);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns `true` if an element in the config object existed and has been removed, or `false` if the element does not
|
|
97
|
+
* exist. {@link BaseConfigStore.has} will return false afterwards.
|
|
98
|
+
*
|
|
99
|
+
* @param key The key. Supports query key like `a.b[0]`.
|
|
100
|
+
*/
|
|
101
|
+
unset(key) {
|
|
102
|
+
if (this.has(key)) {
|
|
103
|
+
if (this.contents[key]) {
|
|
104
|
+
delete this.contents[key];
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// It is a query key, so just set it to undefined
|
|
108
|
+
this.setMethod(this.contents, key, undefined);
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Returns `true` if all elements in the config object existed and have been removed, or `false` if all the elements
|
|
116
|
+
* do not exist (some may have been removed). {@link BaseConfigStore.has(key)} will return false afterwards.
|
|
117
|
+
*
|
|
118
|
+
* @param keys The keys. Supports query keys like `a.b[0]`.
|
|
119
|
+
*/
|
|
120
|
+
unsetAll(keys) {
|
|
121
|
+
return keys.reduce((val, key) => val && this.unset(key), true);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Removes all key/value pairs from the config object.
|
|
125
|
+
*/
|
|
126
|
+
clear() {
|
|
127
|
+
this.contents = {};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns an array that contains the values for each element in the config object.
|
|
131
|
+
*/
|
|
132
|
+
values() {
|
|
133
|
+
return (0, ts_types_2.definiteValuesOf)(this.contents);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns the entire config contents.
|
|
137
|
+
*
|
|
138
|
+
* *NOTE:* Data will still be encrypted unless decrypt is passed in. A clone of
|
|
139
|
+
* the data will be returned to prevent storing un-encrypted data in memory and
|
|
140
|
+
* potentially saving to the file system.
|
|
141
|
+
*
|
|
142
|
+
* @param decrypt: decrypt all data in the config. A clone of the data will be returned.
|
|
143
|
+
*
|
|
144
|
+
*/
|
|
145
|
+
getContents(decrypt = false) {
|
|
146
|
+
if (!this.contents) {
|
|
147
|
+
this.setContents();
|
|
148
|
+
}
|
|
149
|
+
if (this.hasEncryption() && decrypt) {
|
|
150
|
+
return this.recursiveDecrypt((0, kit_1.cloneJson)(this.contents));
|
|
151
|
+
}
|
|
152
|
+
return this.contents;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Sets the entire config contents.
|
|
156
|
+
*
|
|
157
|
+
* @param contents The contents.
|
|
158
|
+
*/
|
|
159
|
+
setContents(contents = {}) {
|
|
160
|
+
if (this.hasEncryption()) {
|
|
161
|
+
contents = this.recursiveEncrypt(contents);
|
|
162
|
+
}
|
|
163
|
+
this.contents = contents;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Invokes `actionFn` once for each key-value pair present in the config object.
|
|
167
|
+
*
|
|
168
|
+
* @param {function} actionFn The function `(key: string, value: ConfigValue) => void` to be called for each element.
|
|
169
|
+
*/
|
|
170
|
+
forEach(actionFn) {
|
|
171
|
+
const entries = this.entries();
|
|
172
|
+
for (const entry of entries) {
|
|
173
|
+
actionFn(entry[0], entry[1]);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Asynchronously invokes `actionFn` once for each key-value pair present in the config object.
|
|
178
|
+
*
|
|
179
|
+
* @param {function} actionFn The function `(key: string, value: ConfigValue) => Promise<void>` to be called for
|
|
180
|
+
* each element.
|
|
181
|
+
* @returns {Promise<void>}
|
|
182
|
+
*/
|
|
183
|
+
async awaitEach(actionFn) {
|
|
184
|
+
const entries = this.entries();
|
|
185
|
+
for (const entry of entries) {
|
|
186
|
+
// prevent ConfigFile collision bug
|
|
187
|
+
// eslint-disable-next-line no-await-in-loop
|
|
188
|
+
await actionFn(entry[0], entry[1]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Convert the config object to a JSON object. Returns the config contents.
|
|
193
|
+
* Same as calling {@link ConfigStore.getContents}
|
|
194
|
+
*/
|
|
195
|
+
toObject() {
|
|
196
|
+
return this.contents;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Convert an object to a {@link ConfigContents} and set it as the config contents.
|
|
200
|
+
*
|
|
201
|
+
* @param obj The object.
|
|
202
|
+
*/
|
|
203
|
+
setContentsFromObject(obj) {
|
|
204
|
+
this.contents = (this.hasEncryption() ? this.recursiveEncrypt(obj) : {});
|
|
205
|
+
Object.entries(obj).forEach(([key, value]) => {
|
|
206
|
+
this.setMethod(this.contents, key, value);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
getEncryptedKeys() {
|
|
210
|
+
return [...(this.options?.encryptedKeys ?? []), ...(this.statics?.encryptedKeys || [])];
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* This config file has encrypted keys and it should attempt to encrypt them.
|
|
214
|
+
*
|
|
215
|
+
* @returns Has encrypted keys
|
|
216
|
+
*/
|
|
217
|
+
hasEncryption() {
|
|
218
|
+
return this.getEncryptedKeys().length > 0;
|
|
219
|
+
}
|
|
220
|
+
// Allows extended classes the ability to override the set method. i.e. maybe they want
|
|
221
|
+
// nested object set from kit.
|
|
222
|
+
// eslint-disable-next-line class-methods-use-this
|
|
223
|
+
setMethod(contents, key, value) {
|
|
224
|
+
(0, kit_1.set)(contents, key, value);
|
|
225
|
+
}
|
|
226
|
+
// Allows extended classes the ability to override the get method. i.e. maybe they want
|
|
227
|
+
// nested object get from ts-types.
|
|
228
|
+
// NOTE: Key must stay string to be reliably overwritten.
|
|
229
|
+
// eslint-disable-next-line class-methods-use-this
|
|
230
|
+
getMethod(contents, key) {
|
|
231
|
+
return (0, ts_types_2.get)(contents, key);
|
|
232
|
+
}
|
|
233
|
+
// eslint-disable-next-line class-methods-use-this
|
|
234
|
+
initialContents() {
|
|
235
|
+
return {};
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Used to initialize asynchronous components.
|
|
239
|
+
*/
|
|
240
|
+
async init() {
|
|
241
|
+
if (this.hasEncryption()) {
|
|
242
|
+
await this.initCrypto();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Initialize the crypto dependency.
|
|
247
|
+
*/
|
|
248
|
+
async initCrypto() {
|
|
249
|
+
if (!this.crypto) {
|
|
250
|
+
this.crypto = await crypto_1.Crypto.create();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Closes the crypto dependency. Crypto should be close after it's used and no longer needed.
|
|
255
|
+
*/
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
257
|
+
async clearCrypto() {
|
|
258
|
+
if (this.crypto) {
|
|
259
|
+
this.crypto.close();
|
|
260
|
+
delete this.crypto;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Should the given key be encrypted on set methods and decrypted on get methods.
|
|
265
|
+
*
|
|
266
|
+
* @param key The key. Supports query key like `a.b[0]`.
|
|
267
|
+
* @returns Should encrypt/decrypt
|
|
268
|
+
*/
|
|
269
|
+
isCryptoKey(key) {
|
|
270
|
+
function resolveProperty() {
|
|
271
|
+
// Handle query keys
|
|
272
|
+
const dotAccessor = /\.([a-zA-Z0-9@._-]+)$/;
|
|
273
|
+
const singleQuoteAccessor = /\['([a-zA-Z0-9@._-]+)'\]$/;
|
|
274
|
+
const doubleQuoteAccessor = /\["([a-zA-Z0-9@._-]+)"\]$/;
|
|
275
|
+
const matcher = dotAccessor.exec(key) ?? singleQuoteAccessor.exec(key) ?? doubleQuoteAccessor.exec(key);
|
|
276
|
+
return matcher ? matcher[1] : key;
|
|
277
|
+
}
|
|
278
|
+
// Any keys named the following should be encrypted/decrypted
|
|
279
|
+
return (this.statics.encryptedKeys || []).find((keyOrExp) => {
|
|
280
|
+
const property = resolveProperty();
|
|
281
|
+
if (keyOrExp instanceof RegExp) {
|
|
282
|
+
return keyOrExp.test(property);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
return keyOrExp === property;
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
encrypt(value) {
|
|
290
|
+
if (!value)
|
|
291
|
+
return;
|
|
292
|
+
if (!this.crypto)
|
|
293
|
+
throw new sfError_1.SfError('crypto is not initialized', 'CryptoNotInitializedError');
|
|
294
|
+
if (!(0, ts_types_2.isString)(value))
|
|
295
|
+
throw new sfError_1.SfError(`can only encrypt strings but found: ${typeof value} : ${value.toString()}`, 'InvalidCryptoValueError');
|
|
296
|
+
return this.crypto.isEncrypted(value) ? value : this.crypto.encrypt(value);
|
|
297
|
+
}
|
|
298
|
+
decrypt(value) {
|
|
299
|
+
if (!value)
|
|
300
|
+
return;
|
|
301
|
+
if (!this.crypto)
|
|
302
|
+
throw new sfError_1.SfError('crypto is not initialized', 'CryptoNotInitializedError');
|
|
303
|
+
if (!(0, ts_types_2.isString)(value))
|
|
304
|
+
throw new sfError_1.SfError(`can only encrypt strings but found: ${typeof value} : ${value.toString()}`, 'InvalidCryptoValueError');
|
|
305
|
+
return this.crypto.isEncrypted(value) ? this.crypto.decrypt(value) : value;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Encrypt all values in a nested JsonMap.
|
|
309
|
+
*
|
|
310
|
+
* @param keyPaths: The complete path of the (nested) data
|
|
311
|
+
* @param data: The current (nested) data being worked on.
|
|
312
|
+
*/
|
|
313
|
+
recursiveEncrypt(data, parentKey) {
|
|
314
|
+
for (const key of Object.keys(data)) {
|
|
315
|
+
this.recursiveCrypto(this.encrypt.bind(this), [...(parentKey ? [parentKey] : []), key], data);
|
|
316
|
+
}
|
|
317
|
+
return data;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Decrypt all values in a nested JsonMap.
|
|
321
|
+
*
|
|
322
|
+
* @param keyPaths: The complete path of the (nested) data
|
|
323
|
+
* @param data: The current (nested) data being worked on.
|
|
324
|
+
*/
|
|
325
|
+
recursiveDecrypt(data, parentKey) {
|
|
326
|
+
for (const key of Object.keys(data)) {
|
|
327
|
+
this.recursiveCrypto(this.decrypt.bind(this), [...(parentKey ? [parentKey] : []), key], data);
|
|
328
|
+
}
|
|
329
|
+
return data;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Encrypt/Decrypt all values in a nested JsonMap.
|
|
333
|
+
*
|
|
334
|
+
* @param keyPaths: The complete path of the (nested) data
|
|
335
|
+
* @param data: The current (nested) data being worked on.
|
|
336
|
+
*/
|
|
337
|
+
recursiveCrypto(method, keyPaths, data) {
|
|
338
|
+
const key = keyPaths.pop();
|
|
339
|
+
const value = data[key];
|
|
340
|
+
if ((0, ts_types_2.isJsonMap)(value)) {
|
|
341
|
+
for (const newKey of Object.keys(value)) {
|
|
342
|
+
this.recursiveCrypto(method, [...keyPaths, key, newKey], value);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else if (this.isCryptoKey(key)) {
|
|
346
|
+
data[key] = method(value);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
exports.BaseConfigStore = BaseConfigStore;
|
|
351
|
+
// If encryptedKeys is an array of RegExps, they should not contain the /g (global) or /y (sticky) flags to avoid stateful issues.
|
|
352
|
+
BaseConfigStore.encryptedKeys = [];
|
|
353
353
|
//# sourceMappingURL=configStore.js.map
|