@salesforce/core 3.31.7 → 3.31.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.
Files changed (153) hide show
  1. package/LICENSE.txt +11 -11
  2. package/README.md +222 -222
  3. package/lib/config/aliasesConfig.d.ts +12 -12
  4. package/lib/config/aliasesConfig.js +27 -27
  5. package/lib/config/authInfoConfig.d.ts +19 -19
  6. package/lib/config/authInfoConfig.js +34 -34
  7. package/lib/config/config.d.ts +311 -311
  8. package/lib/config/config.js +574 -574
  9. package/lib/config/configAggregator.d.ts +232 -232
  10. package/lib/config/configAggregator.js +379 -379
  11. package/lib/config/configFile.d.ts +199 -199
  12. package/lib/config/configFile.js +340 -340
  13. package/lib/config/configGroup.d.ts +141 -141
  14. package/lib/config/configGroup.js +224 -224
  15. package/lib/config/configStore.d.ts +241 -241
  16. package/lib/config/configStore.js +352 -352
  17. package/lib/config/envVars.d.ts +101 -101
  18. package/lib/config/envVars.js +456 -456
  19. package/lib/config/orgUsersConfig.d.ts +31 -31
  20. package/lib/config/orgUsersConfig.js +41 -41
  21. package/lib/config/sandboxOrgConfig.d.ts +37 -37
  22. package/lib/config/sandboxOrgConfig.js +50 -50
  23. package/lib/config/sandboxProcessCache.d.ts +16 -16
  24. package/lib/config/sandboxProcessCache.js +37 -37
  25. package/lib/config/tokensConfig.d.ts +10 -10
  26. package/lib/config/tokensConfig.js +28 -28
  27. package/lib/config/ttlConfig.d.ts +34 -34
  28. package/lib/config/ttlConfig.js +54 -54
  29. package/lib/crypto/crypto.d.ts +54 -54
  30. package/lib/crypto/crypto.js +220 -220
  31. package/lib/crypto/keyChain.d.ts +8 -8
  32. package/lib/crypto/keyChain.js +61 -61
  33. package/lib/crypto/keyChainImpl.d.ts +116 -116
  34. package/lib/crypto/keyChainImpl.js +486 -486
  35. package/lib/crypto/secureBuffer.d.ts +46 -46
  36. package/lib/crypto/secureBuffer.js +82 -82
  37. package/lib/deviceOauthService.d.ts +71 -71
  38. package/lib/deviceOauthService.js +191 -191
  39. package/lib/exported.d.ts +38 -38
  40. package/lib/exported.js +118 -118
  41. package/lib/global.d.ts +70 -70
  42. package/lib/global.js +109 -109
  43. package/lib/lifecycleEvents.d.ts +93 -93
  44. package/lib/lifecycleEvents.js +188 -188
  45. package/lib/logger.d.ts +381 -381
  46. package/lib/logger.js +734 -734
  47. package/lib/messages.d.ts +291 -291
  48. package/lib/messages.js +543 -543
  49. package/lib/org/authInfo.d.ts +344 -344
  50. package/lib/org/authInfo.js +892 -892
  51. package/lib/org/authRemover.d.ts +88 -88
  52. package/lib/org/authRemover.js +182 -182
  53. package/lib/org/connection.d.ts +197 -197
  54. package/lib/org/connection.js +395 -395
  55. package/lib/org/index.d.ts +6 -6
  56. package/lib/org/index.js +28 -28
  57. package/lib/org/org.d.ts +558 -558
  58. package/lib/org/org.js +1267 -1267
  59. package/lib/org/orgConfigProperties.d.ts +69 -69
  60. package/lib/org/orgConfigProperties.js +136 -136
  61. package/lib/org/permissionSetAssignment.d.ts +35 -35
  62. package/lib/org/permissionSetAssignment.js +125 -125
  63. package/lib/org/scratchOrgCache.d.ts +20 -20
  64. package/lib/org/scratchOrgCache.js +32 -32
  65. package/lib/org/scratchOrgCreate.d.ts +54 -54
  66. package/lib/org/scratchOrgCreate.js +216 -216
  67. package/lib/org/scratchOrgErrorCodes.d.ts +10 -10
  68. package/lib/org/scratchOrgErrorCodes.js +88 -88
  69. package/lib/org/scratchOrgFeatureDeprecation.d.ts +26 -26
  70. package/lib/org/scratchOrgFeatureDeprecation.js +109 -109
  71. package/lib/org/scratchOrgInfoApi.d.ts +68 -68
  72. package/lib/org/scratchOrgInfoApi.js +413 -413
  73. package/lib/org/scratchOrgInfoGenerator.d.ts +64 -64
  74. package/lib/org/scratchOrgInfoGenerator.js +241 -241
  75. package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -10
  76. package/lib/org/scratchOrgLifecycleEvents.js +40 -40
  77. package/lib/org/scratchOrgSettingsGenerator.d.ts +78 -78
  78. package/lib/org/scratchOrgSettingsGenerator.js +276 -276
  79. package/lib/org/scratchOrgTypes.d.ts +43 -43
  80. package/lib/org/scratchOrgTypes.js +8 -8
  81. package/lib/org/user.d.ts +187 -187
  82. package/lib/org/user.js +448 -448
  83. package/lib/schema/printer.d.ts +79 -79
  84. package/lib/schema/printer.js +260 -260
  85. package/lib/schema/validator.d.ts +70 -70
  86. package/lib/schema/validator.js +169 -169
  87. package/lib/sfError.d.ts +73 -73
  88. package/lib/sfError.js +136 -136
  89. package/lib/sfProject.d.ts +357 -357
  90. package/lib/sfProject.js +671 -671
  91. package/lib/stateAggregator/accessors/aliasAccessor.d.ts +98 -98
  92. package/lib/stateAggregator/accessors/aliasAccessor.js +145 -145
  93. package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -101
  94. package/lib/stateAggregator/accessors/orgAccessor.js +240 -240
  95. package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -8
  96. package/lib/stateAggregator/accessors/sandboxAccessor.js +27 -27
  97. package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -63
  98. package/lib/stateAggregator/accessors/tokenAccessor.js +79 -79
  99. package/lib/stateAggregator/index.d.ts +4 -4
  100. package/lib/stateAggregator/index.js +26 -26
  101. package/lib/stateAggregator/stateAggregator.d.ts +25 -25
  102. package/lib/stateAggregator/stateAggregator.js +45 -45
  103. package/lib/status/myDomainResolver.d.ts +66 -66
  104. package/lib/status/myDomainResolver.js +124 -124
  105. package/lib/status/pollingClient.d.ts +85 -85
  106. package/lib/status/pollingClient.js +115 -115
  107. package/lib/status/streamingClient.d.ts +244 -244
  108. package/lib/status/streamingClient.js +436 -436
  109. package/lib/status/types.d.ts +89 -89
  110. package/lib/status/types.js +17 -17
  111. package/lib/testSetup.d.ts +553 -553
  112. package/lib/testSetup.js +871 -871
  113. package/lib/util/cache.d.ts +11 -11
  114. package/lib/util/cache.js +69 -69
  115. package/lib/util/checkLightningDomain.d.ts +1 -1
  116. package/lib/util/checkLightningDomain.js +28 -28
  117. package/lib/util/directoryWriter.d.ts +12 -12
  118. package/lib/util/directoryWriter.js +53 -53
  119. package/lib/util/getJwtAudienceUrl.d.ts +4 -4
  120. package/lib/util/getJwtAudienceUrl.js +18 -18
  121. package/lib/util/internal.d.ts +58 -58
  122. package/lib/util/internal.js +118 -118
  123. package/lib/util/jsonXmlTools.d.ts +14 -14
  124. package/lib/util/jsonXmlTools.js +38 -38
  125. package/lib/util/mapKeys.d.ts +14 -14
  126. package/lib/util/mapKeys.js +51 -51
  127. package/lib/util/sfdc.d.ts +52 -52
  128. package/lib/util/sfdc.js +85 -85
  129. package/lib/util/sfdcUrl.d.ts +72 -72
  130. package/lib/util/sfdcUrl.js +215 -215
  131. package/lib/util/structuredWriter.d.ts +9 -9
  132. package/lib/util/structuredWriter.js +2 -2
  133. package/lib/util/zipWriter.d.ts +16 -16
  134. package/lib/util/zipWriter.js +67 -67
  135. package/lib/webOAuthServer.d.ts +156 -156
  136. package/lib/webOAuthServer.js +388 -388
  137. package/messages/auth.md +37 -37
  138. package/messages/config.md +156 -156
  139. package/messages/connection.md +30 -30
  140. package/messages/core.json +20 -20
  141. package/messages/core.md +67 -67
  142. package/messages/encryption.md +85 -85
  143. package/messages/envVars.md +303 -303
  144. package/messages/org.md +63 -63
  145. package/messages/permissionSetAssignment.md +31 -31
  146. package/messages/scratchOrgCreate.md +23 -23
  147. package/messages/scratchOrgErrorCodes.md +115 -115
  148. package/messages/scratchOrgFeatureDeprecation.md +11 -11
  149. package/messages/scratchOrgInfoApi.md +15 -15
  150. package/messages/scratchOrgInfoGenerator.md +23 -23
  151. package/messages/streaming.md +23 -23
  152. package/messages/user.md +35 -35
  153. package/package.json +97 -97
@@ -1,341 +1,341 @@
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.ConfigFile = void 0;
10
- const fs = require("fs");
11
- const fs_1 = require("fs");
12
- const os_1 = require("os");
13
- const path_1 = require("path");
14
- const ts_types_1 = require("@salesforce/ts-types");
15
- const kit_1 = require("@salesforce/kit");
16
- const global_1 = require("../global");
17
- const logger_1 = require("../logger");
18
- const sfError_1 = require("../sfError");
19
- const internal_1 = require("../util/internal");
20
- const configStore_1 = require("./configStore");
21
- /**
22
- * Represents a json config file used to manage settings and state. Global config
23
- * files are stored in the home directory hidden state folder (.sfdx) and local config
24
- * files are stored in the project path, either in the hidden state folder or wherever
25
- * specified.
26
- *
27
- * ```
28
- * class MyConfig extends ConfigFile {
29
- * public static getFileName(): string {
30
- * return 'myConfigFilename.json';
31
- * }
32
- * }
33
- * const myConfig = await MyConfig.create({
34
- * isGlobal: true
35
- * });
36
- * myConfig.set('mykey', 'myvalue');
37
- * await myConfig.write();
38
- * ```
39
- */
40
- class ConfigFile extends configStore_1.BaseConfigStore {
41
- /**
42
- * Create an instance of a config file without reading the file. Call `read` or `readSync`
43
- * after creating the ConfigFile OR instantiate with {@link ConfigFile.create} instead.
44
- *
45
- * @param options The options for the class instance
46
- * @ignore
47
- */
48
- constructor(options) {
49
- super(options);
50
- // whether file contents have been read
51
- this.hasRead = false;
52
- this.logger = logger_1.Logger.childFromRoot(this.constructor.name);
53
- const statics = this.constructor;
54
- let defaultOptions = {};
55
- try {
56
- defaultOptions = statics.getDefaultOptions();
57
- }
58
- catch (e) {
59
- /* Some implementations don't let you call default options */
60
- }
61
- // Merge default and passed in options
62
- this.options = Object.assign(defaultOptions, this.options);
63
- }
64
- /**
65
- * Returns the config's filename.
66
- */
67
- static getFileName() {
68
- // Can not have abstract static methods, so throw a runtime error.
69
- throw new sfError_1.SfError('Unknown filename for config file.');
70
- }
71
- /**
72
- * Returns the default options for the config file.
73
- *
74
- * @param isGlobal If the file should be stored globally or locally.
75
- * @param filename The name of the config file.
76
- */
77
- static getDefaultOptions(isGlobal = false, filename) {
78
- return {
79
- isGlobal,
80
- isState: true,
81
- filename: filename ?? this.getFileName(),
82
- stateFolder: global_1.Global.SFDX_STATE_FOLDER,
83
- };
84
- }
85
- /**
86
- * Helper used to determine what the local and global folder point to. Returns the file path of the root folder.
87
- *
88
- * @param isGlobal True if the config should be global. False for local.
89
- */
90
- static async resolveRootFolder(isGlobal) {
91
- return isGlobal ? (0, os_1.homedir)() : (0, internal_1.resolveProjectPath)();
92
- }
93
- /**
94
- * Helper used to determine what the local and global folder point to. Returns the file path of the root folder.
95
- *
96
- * @param isGlobal True if the config should be global. False for local.
97
- */
98
- static resolveRootFolderSync(isGlobal) {
99
- return isGlobal ? (0, os_1.homedir)() : (0, internal_1.resolveProjectPathSync)();
100
- }
101
- /**
102
- * Determines if the config file is read/write accessible. Returns `true` if the user has capabilities specified
103
- * by perm.
104
- *
105
- * @param {number} perm The permission.
106
- *
107
- * **See** {@link https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_access_path_mode_callback}
108
- */
109
- async access(perm) {
110
- try {
111
- await fs.promises.access(this.getPath(), perm);
112
- return true;
113
- }
114
- catch (err) {
115
- return false;
116
- }
117
- }
118
- /**
119
- * Determines if the config file is read/write accessible. Returns `true` if the user has capabilities specified
120
- * by perm.
121
- *
122
- * @param {number} perm The permission.
123
- *
124
- * **See** {@link https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_access_path_mode_callback}
125
- */
126
- accessSync(perm) {
127
- try {
128
- fs.accessSync(this.getPath(), perm);
129
- return true;
130
- }
131
- catch (err) {
132
- return false;
133
- }
134
- }
135
- /**
136
- * Read the config file and set the config contents. Returns the config contents of the config file. As an
137
- * optimization, files are only read once per process and updated in memory and via `write()`. To force
138
- * a read from the filesystem pass `force=true`.
139
- * **Throws** *{@link SfError}{ name: 'UnexpectedJsonFileFormat' }* There was a problem reading or parsing the file.
140
- *
141
- * @param [throwOnNotFound = false] Optionally indicate if a throw should occur on file read.
142
- * @param [force = false] Optionally force the file to be read from disk even when already read within the process.
143
- */
144
- async read(throwOnNotFound = false, force = false) {
145
- try {
146
- // Only need to read config files once. They are kept up to date
147
- // internally and updated persistently via write().
148
- if (!this.hasRead || force) {
149
- this.logger.info(`Reading config file: ${this.getPath()}`);
150
- const obj = (0, kit_1.parseJsonMap)(await fs.promises.readFile(this.getPath(), 'utf8'));
151
- this.setContentsFromObject(obj);
152
- }
153
- return this.getContents();
154
- }
155
- catch (err) {
156
- if (err.code === 'ENOENT') {
157
- if (!throwOnNotFound) {
158
- this.setContents();
159
- return this.getContents();
160
- }
161
- }
162
- throw err;
163
- }
164
- finally {
165
- // Necessarily set this even when an error happens to avoid infinite re-reading.
166
- // To attempt another read, pass `force=true`.
167
- this.hasRead = true;
168
- }
169
- }
170
- /**
171
- * Read the config file and set the config contents. Returns the config contents of the config file. As an
172
- * optimization, files are only read once per process and updated in memory and via `write()`. To force
173
- * a read from the filesystem pass `force=true`.
174
- * **Throws** *{@link SfError}{ name: 'UnexpectedJsonFileFormat' }* There was a problem reading or parsing the file.
175
- *
176
- * @param [throwOnNotFound = false] Optionally indicate if a throw should occur on file read.
177
- * @param [force = false] Optionally force the file to be read from disk even when already read within the process.
178
- */
179
- readSync(throwOnNotFound = false, force = false) {
180
- try {
181
- // Only need to read config files once. They are kept up to date
182
- // internally and updated persistently via write().
183
- if (!this.hasRead || force) {
184
- this.logger.info(`Reading config file: ${this.getPath()}`);
185
- const obj = (0, kit_1.parseJsonMap)(fs.readFileSync(this.getPath(), 'utf8'));
186
- this.setContentsFromObject(obj);
187
- }
188
- return this.getContents();
189
- }
190
- catch (err) {
191
- if (err.code === 'ENOENT') {
192
- if (!throwOnNotFound) {
193
- this.setContents();
194
- return this.getContents();
195
- }
196
- }
197
- throw err;
198
- }
199
- finally {
200
- // Necessarily set this even when an error happens to avoid infinite re-reading.
201
- // To attempt another read, pass `force=true`.
202
- this.hasRead = true;
203
- }
204
- }
205
- /**
206
- * Write the config file with new contents. If no new contents are provided it will write the existing config
207
- * contents that were set from {@link ConfigFile.read}, or an empty file if {@link ConfigFile.read} was not called.
208
- *
209
- * @param newContents The new contents of the file.
210
- */
211
- async write(newContents) {
212
- if (newContents) {
213
- this.setContents(newContents);
214
- }
215
- try {
216
- await fs.promises.mkdir((0, path_1.dirname)(this.getPath()), { recursive: true });
217
- }
218
- catch (err) {
219
- throw sfError_1.SfError.wrap(err);
220
- }
221
- this.logger.info(`Writing to config file: ${this.getPath()}`);
222
- await fs.promises.writeFile(this.getPath(), JSON.stringify(this.toObject(), null, 2));
223
- return this.getContents();
224
- }
225
- /**
226
- * Write the config file with new contents. If no new contents are provided it will write the existing config
227
- * contents that were set from {@link ConfigFile.read}, or an empty file if {@link ConfigFile.read} was not called.
228
- *
229
- * @param newContents The new contents of the file.
230
- */
231
- writeSync(newContents) {
232
- if ((0, ts_types_1.isPlainObject)(newContents)) {
233
- this.setContents(newContents);
234
- }
235
- try {
236
- fs.mkdirSync((0, path_1.dirname)(this.getPath()), { recursive: true });
237
- }
238
- catch (err) {
239
- throw sfError_1.SfError.wrap(err);
240
- }
241
- this.logger.info(`Writing to config file: ${this.getPath()}`);
242
- fs.writeFileSync(this.getPath(), JSON.stringify(this.toObject(), null, 2));
243
- return this.getContents();
244
- }
245
- /**
246
- * Check to see if the config file exists. Returns `true` if the config file exists and has access, false otherwise.
247
- */
248
- async exists() {
249
- return this.access(fs_1.constants.R_OK);
250
- }
251
- /**
252
- * Check to see if the config file exists. Returns `true` if the config file exists and has access, false otherwise.
253
- */
254
- existsSync() {
255
- return this.accessSync(fs_1.constants.R_OK);
256
- }
257
- /**
258
- * Get the stats of the file. Returns the stats of the file.
259
- *
260
- * {@link fs.stat}
261
- */
262
- async stat() {
263
- return fs.promises.stat(this.getPath());
264
- }
265
- /**
266
- * Get the stats of the file. Returns the stats of the file.
267
- *
268
- * {@link fs.stat}
269
- */
270
- statSync() {
271
- return fs.statSync(this.getPath());
272
- }
273
- /**
274
- * Delete the config file if it exists.
275
- *
276
- * **Throws** *`Error`{ name: 'TargetFileNotFound' }* If the {@link ConfigFile.getFilename} file is not found.
277
- * {@link fs.unlink}
278
- */
279
- async unlink() {
280
- const exists = await this.exists();
281
- if (exists) {
282
- return fs.promises.unlink(this.getPath());
283
- }
284
- throw new sfError_1.SfError(`Target file doesn't exist. path: ${this.getPath()}`, 'TargetFileNotFound');
285
- }
286
- /**
287
- * Delete the config file if it exists.
288
- *
289
- * **Throws** *`Error`{ name: 'TargetFileNotFound' }* If the {@link ConfigFile.getFilename} file is not found.
290
- * {@link fs.unlink}
291
- */
292
- unlinkSync() {
293
- const exists = this.existsSync();
294
- if (exists) {
295
- return fs.unlinkSync(this.getPath());
296
- }
297
- throw new sfError_1.SfError(`Target file doesn't exist. path: ${this.getPath()}`, 'TargetFileNotFound');
298
- }
299
- /**
300
- * Returns the absolute path to the config file.
301
- *
302
- * The first time getPath is called, the path is resolved and becomes immutable. This allows implementers to
303
- * override options properties, like filePath, on the init method for async creation. If that is required for
304
- * creation, the config files can not be synchronously created.
305
- */
306
- getPath() {
307
- if (!this.path) {
308
- if (!this.options.filename) {
309
- throw new sfError_1.SfError('The ConfigOptions filename parameter is invalid.', 'InvalidParameter');
310
- }
311
- // Don't let users store config files in homedir without being in the state folder.
312
- let configRootFolder = this.options.rootFolder
313
- ? this.options.rootFolder
314
- : ConfigFile.resolveRootFolderSync(Boolean(this.options.isGlobal));
315
- if (this.options.isGlobal === true || this.options.isState === true) {
316
- configRootFolder = (0, path_1.join)(configRootFolder, this.options.stateFolder ?? global_1.Global.SFDX_STATE_FOLDER);
317
- }
318
- this.path = (0, path_1.join)(configRootFolder, this.options.filePath ? this.options.filePath : '', this.options.filename);
319
- }
320
- return this.path;
321
- }
322
- /**
323
- * Returns `true` if this config is using the global path, `false` otherwise.
324
- */
325
- isGlobal() {
326
- return !!this.options.isGlobal;
327
- }
328
- /**
329
- * Used to initialize asynchronous components.
330
- *
331
- * **Throws** *`Error`{ code: 'ENOENT' }* If the {@link ConfigFile.getFilename} file is not found when
332
- * options.throwOnNotFound is true.
333
- */
334
- async init() {
335
- await super.init();
336
- // Read the file, which also sets the path and throws any errors around project paths.
337
- await this.read(this.options.throwOnNotFound);
338
- }
339
- }
340
- exports.ConfigFile = ConfigFile;
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.ConfigFile = void 0;
10
+ const fs = require("fs");
11
+ const fs_1 = require("fs");
12
+ const os_1 = require("os");
13
+ const path_1 = require("path");
14
+ const ts_types_1 = require("@salesforce/ts-types");
15
+ const kit_1 = require("@salesforce/kit");
16
+ const global_1 = require("../global");
17
+ const logger_1 = require("../logger");
18
+ const sfError_1 = require("../sfError");
19
+ const internal_1 = require("../util/internal");
20
+ const configStore_1 = require("./configStore");
21
+ /**
22
+ * Represents a json config file used to manage settings and state. Global config
23
+ * files are stored in the home directory hidden state folder (.sfdx) and local config
24
+ * files are stored in the project path, either in the hidden state folder or wherever
25
+ * specified.
26
+ *
27
+ * ```
28
+ * class MyConfig extends ConfigFile {
29
+ * public static getFileName(): string {
30
+ * return 'myConfigFilename.json';
31
+ * }
32
+ * }
33
+ * const myConfig = await MyConfig.create({
34
+ * isGlobal: true
35
+ * });
36
+ * myConfig.set('mykey', 'myvalue');
37
+ * await myConfig.write();
38
+ * ```
39
+ */
40
+ class ConfigFile extends configStore_1.BaseConfigStore {
41
+ /**
42
+ * Create an instance of a config file without reading the file. Call `read` or `readSync`
43
+ * after creating the ConfigFile OR instantiate with {@link ConfigFile.create} instead.
44
+ *
45
+ * @param options The options for the class instance
46
+ * @ignore
47
+ */
48
+ constructor(options) {
49
+ super(options);
50
+ // whether file contents have been read
51
+ this.hasRead = false;
52
+ this.logger = logger_1.Logger.childFromRoot(this.constructor.name);
53
+ const statics = this.constructor;
54
+ let defaultOptions = {};
55
+ try {
56
+ defaultOptions = statics.getDefaultOptions();
57
+ }
58
+ catch (e) {
59
+ /* Some implementations don't let you call default options */
60
+ }
61
+ // Merge default and passed in options
62
+ this.options = Object.assign(defaultOptions, this.options);
63
+ }
64
+ /**
65
+ * Returns the config's filename.
66
+ */
67
+ static getFileName() {
68
+ // Can not have abstract static methods, so throw a runtime error.
69
+ throw new sfError_1.SfError('Unknown filename for config file.');
70
+ }
71
+ /**
72
+ * Returns the default options for the config file.
73
+ *
74
+ * @param isGlobal If the file should be stored globally or locally.
75
+ * @param filename The name of the config file.
76
+ */
77
+ static getDefaultOptions(isGlobal = false, filename) {
78
+ return {
79
+ isGlobal,
80
+ isState: true,
81
+ filename: filename ?? this.getFileName(),
82
+ stateFolder: global_1.Global.SFDX_STATE_FOLDER,
83
+ };
84
+ }
85
+ /**
86
+ * Helper used to determine what the local and global folder point to. Returns the file path of the root folder.
87
+ *
88
+ * @param isGlobal True if the config should be global. False for local.
89
+ */
90
+ static async resolveRootFolder(isGlobal) {
91
+ return isGlobal ? (0, os_1.homedir)() : (0, internal_1.resolveProjectPath)();
92
+ }
93
+ /**
94
+ * Helper used to determine what the local and global folder point to. Returns the file path of the root folder.
95
+ *
96
+ * @param isGlobal True if the config should be global. False for local.
97
+ */
98
+ static resolveRootFolderSync(isGlobal) {
99
+ return isGlobal ? (0, os_1.homedir)() : (0, internal_1.resolveProjectPathSync)();
100
+ }
101
+ /**
102
+ * Determines if the config file is read/write accessible. Returns `true` if the user has capabilities specified
103
+ * by perm.
104
+ *
105
+ * @param {number} perm The permission.
106
+ *
107
+ * **See** {@link https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_access_path_mode_callback}
108
+ */
109
+ async access(perm) {
110
+ try {
111
+ await fs.promises.access(this.getPath(), perm);
112
+ return true;
113
+ }
114
+ catch (err) {
115
+ return false;
116
+ }
117
+ }
118
+ /**
119
+ * Determines if the config file is read/write accessible. Returns `true` if the user has capabilities specified
120
+ * by perm.
121
+ *
122
+ * @param {number} perm The permission.
123
+ *
124
+ * **See** {@link https://nodejs.org/dist/latest/docs/api/fs.html#fs_fs_access_path_mode_callback}
125
+ */
126
+ accessSync(perm) {
127
+ try {
128
+ fs.accessSync(this.getPath(), perm);
129
+ return true;
130
+ }
131
+ catch (err) {
132
+ return false;
133
+ }
134
+ }
135
+ /**
136
+ * Read the config file and set the config contents. Returns the config contents of the config file. As an
137
+ * optimization, files are only read once per process and updated in memory and via `write()`. To force
138
+ * a read from the filesystem pass `force=true`.
139
+ * **Throws** *{@link SfError}{ name: 'UnexpectedJsonFileFormat' }* There was a problem reading or parsing the file.
140
+ *
141
+ * @param [throwOnNotFound = false] Optionally indicate if a throw should occur on file read.
142
+ * @param [force = false] Optionally force the file to be read from disk even when already read within the process.
143
+ */
144
+ async read(throwOnNotFound = false, force = false) {
145
+ try {
146
+ // Only need to read config files once. They are kept up to date
147
+ // internally and updated persistently via write().
148
+ if (!this.hasRead || force) {
149
+ this.logger.info(`Reading config file: ${this.getPath()}`);
150
+ const obj = (0, kit_1.parseJsonMap)(await fs.promises.readFile(this.getPath(), 'utf8'));
151
+ this.setContentsFromObject(obj);
152
+ }
153
+ return this.getContents();
154
+ }
155
+ catch (err) {
156
+ if (err.code === 'ENOENT') {
157
+ if (!throwOnNotFound) {
158
+ this.setContents();
159
+ return this.getContents();
160
+ }
161
+ }
162
+ throw err;
163
+ }
164
+ finally {
165
+ // Necessarily set this even when an error happens to avoid infinite re-reading.
166
+ // To attempt another read, pass `force=true`.
167
+ this.hasRead = true;
168
+ }
169
+ }
170
+ /**
171
+ * Read the config file and set the config contents. Returns the config contents of the config file. As an
172
+ * optimization, files are only read once per process and updated in memory and via `write()`. To force
173
+ * a read from the filesystem pass `force=true`.
174
+ * **Throws** *{@link SfError}{ name: 'UnexpectedJsonFileFormat' }* There was a problem reading or parsing the file.
175
+ *
176
+ * @param [throwOnNotFound = false] Optionally indicate if a throw should occur on file read.
177
+ * @param [force = false] Optionally force the file to be read from disk even when already read within the process.
178
+ */
179
+ readSync(throwOnNotFound = false, force = false) {
180
+ try {
181
+ // Only need to read config files once. They are kept up to date
182
+ // internally and updated persistently via write().
183
+ if (!this.hasRead || force) {
184
+ this.logger.info(`Reading config file: ${this.getPath()}`);
185
+ const obj = (0, kit_1.parseJsonMap)(fs.readFileSync(this.getPath(), 'utf8'));
186
+ this.setContentsFromObject(obj);
187
+ }
188
+ return this.getContents();
189
+ }
190
+ catch (err) {
191
+ if (err.code === 'ENOENT') {
192
+ if (!throwOnNotFound) {
193
+ this.setContents();
194
+ return this.getContents();
195
+ }
196
+ }
197
+ throw err;
198
+ }
199
+ finally {
200
+ // Necessarily set this even when an error happens to avoid infinite re-reading.
201
+ // To attempt another read, pass `force=true`.
202
+ this.hasRead = true;
203
+ }
204
+ }
205
+ /**
206
+ * Write the config file with new contents. If no new contents are provided it will write the existing config
207
+ * contents that were set from {@link ConfigFile.read}, or an empty file if {@link ConfigFile.read} was not called.
208
+ *
209
+ * @param newContents The new contents of the file.
210
+ */
211
+ async write(newContents) {
212
+ if (newContents) {
213
+ this.setContents(newContents);
214
+ }
215
+ try {
216
+ await fs.promises.mkdir((0, path_1.dirname)(this.getPath()), { recursive: true });
217
+ }
218
+ catch (err) {
219
+ throw sfError_1.SfError.wrap(err);
220
+ }
221
+ this.logger.info(`Writing to config file: ${this.getPath()}`);
222
+ await fs.promises.writeFile(this.getPath(), JSON.stringify(this.toObject(), null, 2));
223
+ return this.getContents();
224
+ }
225
+ /**
226
+ * Write the config file with new contents. If no new contents are provided it will write the existing config
227
+ * contents that were set from {@link ConfigFile.read}, or an empty file if {@link ConfigFile.read} was not called.
228
+ *
229
+ * @param newContents The new contents of the file.
230
+ */
231
+ writeSync(newContents) {
232
+ if ((0, ts_types_1.isPlainObject)(newContents)) {
233
+ this.setContents(newContents);
234
+ }
235
+ try {
236
+ fs.mkdirSync((0, path_1.dirname)(this.getPath()), { recursive: true });
237
+ }
238
+ catch (err) {
239
+ throw sfError_1.SfError.wrap(err);
240
+ }
241
+ this.logger.info(`Writing to config file: ${this.getPath()}`);
242
+ fs.writeFileSync(this.getPath(), JSON.stringify(this.toObject(), null, 2));
243
+ return this.getContents();
244
+ }
245
+ /**
246
+ * Check to see if the config file exists. Returns `true` if the config file exists and has access, false otherwise.
247
+ */
248
+ async exists() {
249
+ return this.access(fs_1.constants.R_OK);
250
+ }
251
+ /**
252
+ * Check to see if the config file exists. Returns `true` if the config file exists and has access, false otherwise.
253
+ */
254
+ existsSync() {
255
+ return this.accessSync(fs_1.constants.R_OK);
256
+ }
257
+ /**
258
+ * Get the stats of the file. Returns the stats of the file.
259
+ *
260
+ * {@link fs.stat}
261
+ */
262
+ async stat() {
263
+ return fs.promises.stat(this.getPath());
264
+ }
265
+ /**
266
+ * Get the stats of the file. Returns the stats of the file.
267
+ *
268
+ * {@link fs.stat}
269
+ */
270
+ statSync() {
271
+ return fs.statSync(this.getPath());
272
+ }
273
+ /**
274
+ * Delete the config file if it exists.
275
+ *
276
+ * **Throws** *`Error`{ name: 'TargetFileNotFound' }* If the {@link ConfigFile.getFilename} file is not found.
277
+ * {@link fs.unlink}
278
+ */
279
+ async unlink() {
280
+ const exists = await this.exists();
281
+ if (exists) {
282
+ return fs.promises.unlink(this.getPath());
283
+ }
284
+ throw new sfError_1.SfError(`Target file doesn't exist. path: ${this.getPath()}`, 'TargetFileNotFound');
285
+ }
286
+ /**
287
+ * Delete the config file if it exists.
288
+ *
289
+ * **Throws** *`Error`{ name: 'TargetFileNotFound' }* If the {@link ConfigFile.getFilename} file is not found.
290
+ * {@link fs.unlink}
291
+ */
292
+ unlinkSync() {
293
+ const exists = this.existsSync();
294
+ if (exists) {
295
+ return fs.unlinkSync(this.getPath());
296
+ }
297
+ throw new sfError_1.SfError(`Target file doesn't exist. path: ${this.getPath()}`, 'TargetFileNotFound');
298
+ }
299
+ /**
300
+ * Returns the absolute path to the config file.
301
+ *
302
+ * The first time getPath is called, the path is resolved and becomes immutable. This allows implementers to
303
+ * override options properties, like filePath, on the init method for async creation. If that is required for
304
+ * creation, the config files can not be synchronously created.
305
+ */
306
+ getPath() {
307
+ if (!this.path) {
308
+ if (!this.options.filename) {
309
+ throw new sfError_1.SfError('The ConfigOptions filename parameter is invalid.', 'InvalidParameter');
310
+ }
311
+ // Don't let users store config files in homedir without being in the state folder.
312
+ let configRootFolder = this.options.rootFolder
313
+ ? this.options.rootFolder
314
+ : ConfigFile.resolveRootFolderSync(Boolean(this.options.isGlobal));
315
+ if (this.options.isGlobal === true || this.options.isState === true) {
316
+ configRootFolder = (0, path_1.join)(configRootFolder, this.options.stateFolder ?? global_1.Global.SFDX_STATE_FOLDER);
317
+ }
318
+ this.path = (0, path_1.join)(configRootFolder, this.options.filePath ? this.options.filePath : '', this.options.filename);
319
+ }
320
+ return this.path;
321
+ }
322
+ /**
323
+ * Returns `true` if this config is using the global path, `false` otherwise.
324
+ */
325
+ isGlobal() {
326
+ return !!this.options.isGlobal;
327
+ }
328
+ /**
329
+ * Used to initialize asynchronous components.
330
+ *
331
+ * **Throws** *`Error`{ code: 'ENOENT' }* If the {@link ConfigFile.getFilename} file is not found when
332
+ * options.throwOnNotFound is true.
333
+ */
334
+ async init() {
335
+ await super.init();
336
+ // Read the file, which also sets the path and throws any errors around project paths.
337
+ await this.read(this.options.throwOnNotFound);
338
+ }
339
+ }
340
+ exports.ConfigFile = ConfigFile;
341
341
  //# sourceMappingURL=configFile.js.map