@salesforce/core 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +93 -44
  3. package/lib/config/authInfoConfig.d.ts +19 -0
  4. package/lib/config/authInfoConfig.js +35 -0
  5. package/lib/config/config.d.ts +87 -22
  6. package/lib/config/config.js +117 -65
  7. package/lib/config/configAggregator.d.ts +41 -35
  8. package/lib/config/configAggregator.js +102 -73
  9. package/lib/config/configFile.d.ts +2 -2
  10. package/lib/config/configFile.js +38 -29
  11. package/lib/config/configStore.d.ts +9 -9
  12. package/lib/config/configStore.js +17 -15
  13. package/lib/config/envVars.d.ts +15 -9
  14. package/lib/config/envVars.js +71 -47
  15. package/lib/config/orgUsersConfig.js +2 -0
  16. package/lib/config/sandboxOrgConfig.js +2 -0
  17. package/lib/config/sandboxProcessCache.d.ts +16 -0
  18. package/lib/config/sandboxProcessCache.js +38 -0
  19. package/lib/config/tokensConfig.d.ts +10 -0
  20. package/lib/config/tokensConfig.js +29 -0
  21. package/lib/config/ttlConfig.d.ts +34 -0
  22. package/lib/config/ttlConfig.js +50 -0
  23. package/lib/crypto/crypto.js +15 -22
  24. package/lib/crypto/keyChain.js +2 -3
  25. package/lib/crypto/keyChainImpl.d.ts +5 -3
  26. package/lib/crypto/keyChainImpl.js +58 -61
  27. package/lib/crypto/secureBuffer.d.ts +1 -1
  28. package/lib/deviceOauthService.d.ts +3 -3
  29. package/lib/deviceOauthService.js +27 -25
  30. package/lib/exported.d.ts +15 -12
  31. package/lib/exported.js +28 -16
  32. package/lib/global.d.ts +11 -3
  33. package/lib/global.js +39 -12
  34. package/lib/lifecycleEvents.d.ts +1 -1
  35. package/lib/lifecycleEvents.js +3 -0
  36. package/lib/logger.d.ts +19 -9
  37. package/lib/logger.js +112 -86
  38. package/lib/messages.d.ts +53 -36
  39. package/lib/messages.js +81 -91
  40. package/lib/org/authInfo.d.ts +56 -20
  41. package/lib/org/authInfo.js +232 -131
  42. package/lib/org/authRemover.d.ts +8 -7
  43. package/lib/org/authRemover.js +32 -28
  44. package/lib/org/connection.d.ts +13 -37
  45. package/lib/org/connection.js +78 -124
  46. package/lib/org/index.js +5 -1
  47. package/lib/org/org.d.ts +151 -48
  48. package/lib/org/org.js +468 -225
  49. package/lib/org/orgConfigProperties.d.ts +64 -3
  50. package/lib/org/orgConfigProperties.js +96 -4
  51. package/lib/org/permissionSetAssignment.js +4 -13
  52. package/lib/org/scratchOrgCache.d.ts +20 -0
  53. package/lib/org/scratchOrgCache.js +33 -0
  54. package/lib/org/scratchOrgCreate.d.ts +28 -17
  55. package/lib/org/scratchOrgCreate.js +125 -53
  56. package/lib/org/scratchOrgErrorCodes.d.ts +9 -3
  57. package/lib/org/scratchOrgErrorCodes.js +34 -17
  58. package/lib/org/scratchOrgFeatureDeprecation.js +1 -6
  59. package/lib/org/scratchOrgInfoApi.d.ts +21 -47
  60. package/lib/org/scratchOrgInfoApi.js +129 -63
  61. package/lib/org/scratchOrgInfoGenerator.d.ts +6 -5
  62. package/lib/org/scratchOrgInfoGenerator.js +76 -62
  63. package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -0
  64. package/lib/org/scratchOrgLifecycleEvents.js +41 -0
  65. package/lib/org/scratchOrgSettingsGenerator.d.ts +44 -21
  66. package/lib/org/scratchOrgSettingsGenerator.js +165 -98
  67. package/lib/org/scratchOrgTypes.d.ts +43 -0
  68. package/lib/org/scratchOrgTypes.js +9 -0
  69. package/lib/org/user.d.ts +1 -1
  70. package/lib/org/user.js +25 -34
  71. package/lib/schema/printer.d.ts +6 -0
  72. package/lib/schema/printer.js +34 -31
  73. package/lib/schema/validator.d.ts +12 -10
  74. package/lib/schema/validator.js +56 -76
  75. package/lib/{sfdxError.d.ts → sfError.d.ts} +12 -20
  76. package/lib/{sfdxError.js → sfError.js} +40 -30
  77. package/lib/{sfdxProject.d.ts → sfProject.d.ts} +75 -35
  78. package/lib/sfProject.js +651 -0
  79. package/lib/stateAggregator/accessors/aliasAccessor.d.ts +129 -0
  80. package/lib/stateAggregator/accessors/aliasAccessor.js +263 -0
  81. package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -0
  82. package/lib/stateAggregator/accessors/orgAccessor.js +240 -0
  83. package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -0
  84. package/lib/stateAggregator/accessors/sandboxAccessor.js +28 -0
  85. package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -0
  86. package/lib/stateAggregator/accessors/tokenAccessor.js +80 -0
  87. package/lib/stateAggregator/index.d.ts +4 -0
  88. package/lib/stateAggregator/index.js +27 -0
  89. package/lib/stateAggregator/stateAggregator.d.ts +25 -0
  90. package/lib/stateAggregator/stateAggregator.js +46 -0
  91. package/lib/status/myDomainResolver.d.ts +1 -1
  92. package/lib/status/myDomainResolver.js +4 -4
  93. package/lib/status/pollingClient.js +4 -4
  94. package/lib/status/streamingClient.d.ts +2 -2
  95. package/lib/status/streamingClient.js +58 -63
  96. package/lib/status/types.d.ts +2 -2
  97. package/lib/testSetup.d.ts +204 -75
  98. package/lib/testSetup.js +468 -164
  99. package/lib/util/cache.d.ts +2 -2
  100. package/lib/util/cache.js +6 -6
  101. package/lib/util/checkLightningDomain.js +3 -4
  102. package/lib/util/directoryWriter.d.ts +12 -0
  103. package/lib/util/directoryWriter.js +54 -0
  104. package/lib/util/getJwtAudienceUrl.js +1 -1
  105. package/lib/util/internal.d.ts +28 -2
  106. package/lib/util/internal.js +65 -8
  107. package/lib/util/jsonXmlTools.js +2 -4
  108. package/lib/util/mapKeys.d.ts +9 -9
  109. package/lib/util/mapKeys.js +13 -9
  110. package/lib/util/sfdc.d.ts +51 -51
  111. package/lib/util/sfdc.js +74 -79
  112. package/lib/util/sfdcUrl.d.ts +5 -19
  113. package/lib/util/sfdcUrl.js +40 -49
  114. package/lib/util/structuredWriter.d.ts +9 -0
  115. package/lib/util/structuredWriter.js +3 -0
  116. package/lib/util/zipWriter.d.ts +8 -6
  117. package/lib/util/zipWriter.js +13 -13
  118. package/lib/webOAuthServer.d.ts +20 -6
  119. package/lib/webOAuthServer.js +102 -56
  120. package/messageTransformer/messageTransformer.ts +93 -0
  121. package/messages/auth.md +9 -1
  122. package/messages/config.md +42 -6
  123. package/messages/connection.md +8 -0
  124. package/messages/core.md +10 -0
  125. package/messages/envVars.md +37 -3
  126. package/messages/org.md +21 -1
  127. package/messages/scratchOrgCreate.md +2 -6
  128. package/messages/scratchOrgErrorCodes.md +17 -1
  129. package/messages/scratchOrgInfoApi.md +9 -0
  130. package/messages/scratchOrgInfoGenerator.md +9 -1
  131. package/package.json +123 -46
  132. package/CHANGELOG.md +0 -1244
  133. package/lib/config/keychainConfig.d.ts +0 -19
  134. package/lib/config/keychainConfig.js +0 -43
  135. package/lib/globalInfo/accessors/aliasAccessor.d.ts +0 -83
  136. package/lib/globalInfo/accessors/aliasAccessor.js +0 -130
  137. package/lib/globalInfo/accessors/orgAccessor.d.ts +0 -13
  138. package/lib/globalInfo/accessors/orgAccessor.js +0 -45
  139. package/lib/globalInfo/accessors/tokenAccessor.d.ts +0 -13
  140. package/lib/globalInfo/accessors/tokenAccessor.js +0 -35
  141. package/lib/globalInfo/globalInfoConfig.d.ts +0 -36
  142. package/lib/globalInfo/globalInfoConfig.js +0 -105
  143. package/lib/globalInfo/index.d.ts +0 -6
  144. package/lib/globalInfo/index.js +0 -29
  145. package/lib/globalInfo/sfdxDataHandler.d.ts +0 -43
  146. package/lib/globalInfo/sfdxDataHandler.js +0 -217
  147. package/lib/globalInfo/types.d.ts +0 -39
  148. package/lib/globalInfo/types.js +0 -10
  149. package/lib/sfdxProject.js +0 -557
  150. package/lib/util/fs.d.ts +0 -201
  151. package/lib/util/fs.js +0 -378
package/lib/testSetup.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrow = exports.unexpectedResult = exports.testSetup = exports.restoreContext = exports.stubContext = exports.instantiateContext = void 0;
3
+ exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrowSync = exports.shouldThrow = exports.unexpectedResult = exports.restoreContext = exports.stubContext = exports.instantiateContext = exports.uniqid = exports.TestContext = void 0;
4
4
  /*
5
5
  * Copyright (c) 2020, salesforce.com, inc.
6
6
  * All rights reserved.
@@ -8,11 +8,16 @@ exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMo
8
8
  * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
9
9
  */
10
10
  /* eslint-disable @typescript-eslint/ban-ts-comment */
11
+ /* eslint-disable class-methods-use-this */
12
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
13
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
14
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
15
+ const fs = require("node:fs");
11
16
  const crypto_1 = require("crypto");
12
17
  const events_1 = require("events");
13
18
  const os_1 = require("os");
14
19
  const path_1 = require("path");
15
- const kit_1 = require("@salesforce/kit");
20
+ const util = require("util");
16
21
  const ts_sinon_1 = require("@salesforce/ts-sinon");
17
22
  const ts_types_1 = require("@salesforce/ts-types");
18
23
  const configAggregator_1 = require("./config/configAggregator");
@@ -21,14 +26,302 @@ const connection_1 = require("./org/connection");
21
26
  const crypto_2 = require("./crypto/crypto");
22
27
  const logger_1 = require("./logger");
23
28
  const messages_1 = require("./messages");
24
- const sfdxError_1 = require("./sfdxError");
25
- const sfdxProject_1 = require("./sfdxProject");
29
+ const sfError_1 = require("./sfError");
30
+ const sfProject_1 = require("./sfProject");
31
+ const aliasAccessorEntireFile = require("./stateAggregator/accessors/aliasAccessor");
26
32
  const streamingClient_1 = require("./status/streamingClient");
27
- const globalInfo_1 = require("./globalInfo");
33
+ const stateAggregator_1 = require("./stateAggregator");
34
+ const org_1 = require("./org");
35
+ const sandboxAccessor_1 = require("./stateAggregator/accessors/sandboxAccessor");
28
36
  const global_1 = require("./global");
29
- const uniqid = () => {
30
- return (0, crypto_1.randomBytes)(16).toString('hex');
31
- };
37
+ /**
38
+ * Instantiate a @salesforce/core test context.
39
+ */
40
+ class TestContext {
41
+ constructor(options = {}) {
42
+ /**
43
+ * id A unique id for the test run.
44
+ */
45
+ this.id = uniqid();
46
+ /**
47
+ * An object used in tests that interact with config files.
48
+ */
49
+ this.configStubs = {};
50
+ /**
51
+ * A record of stubs created during instantiation.
52
+ */
53
+ this.stubs = {};
54
+ const opts = { setup: true, ...options };
55
+ const sinon = this.requireSinon(opts.sinon);
56
+ // Create a global sinon sandbox and a test logger instance for use within tests.
57
+ this.SANDBOX = opts.sandbox ?? sinon.createSandbox();
58
+ this.SANDBOXES = {
59
+ DEFAULT: this.SANDBOX,
60
+ CONFIG: sinon.createSandbox(),
61
+ PROJECT: sinon.createSandbox(),
62
+ CRYPTO: sinon.createSandbox(),
63
+ CONNECTION: sinon.createSandbox(),
64
+ FS: sinon.createSandbox(),
65
+ ORGS: sinon.createSandbox(),
66
+ };
67
+ this.TEST_LOGGER = new logger_1.Logger({ name: 'SFDX_Core_Test_Logger' }).useMemoryLogging();
68
+ if (opts.setup) {
69
+ this.setup();
70
+ }
71
+ }
72
+ /**
73
+ * Generate unique string.
74
+ */
75
+ uniqid() {
76
+ return uniqid();
77
+ }
78
+ /**
79
+ * A function used when resolving the local path. Calls localPathResolverSync by default.
80
+ *
81
+ * @param uid Unique id.
82
+ */
83
+ async localPathRetriever(uid) {
84
+ return Promise.resolve(getTestLocalPath(uid));
85
+ }
86
+ /**
87
+ * A function used when resolving the local path.
88
+ *
89
+ * @param uid Unique id.
90
+ */
91
+ localPathRetrieverSync(uid) {
92
+ return getTestLocalPath(uid);
93
+ }
94
+ /**
95
+ * A function used when resolving the global path. Calls globalPathResolverSync by default.
96
+ *
97
+ * @param uid Unique id.
98
+ */
99
+ async globalPathRetriever(uid) {
100
+ return Promise.resolve(getTestGlobalPath(uid));
101
+ }
102
+ /**
103
+ * A function used when resolving the global path.
104
+ *
105
+ * @param uid Unique id.
106
+ */
107
+ globalPathRetrieverSync(uid) {
108
+ return getTestGlobalPath(uid);
109
+ }
110
+ /**
111
+ * A function used for resolving paths. Calls localPathRetriever and globalPathRetriever.
112
+ *
113
+ * @param isGlobal `true` if the config is global.
114
+ * @param uid user id.
115
+ */
116
+ async rootPathRetriever(isGlobal, uid) {
117
+ return retrieveRootPath(isGlobal, uid);
118
+ }
119
+ /**
120
+ * A function used for resolving paths. Calls localPathRetrieverSync and globalPathRetrieverSync.
121
+ *
122
+ * @param isGlobal `true` if the config is global.
123
+ * @param uid user id.
124
+ */
125
+ rootPathRetrieverSync(isGlobal, uid) {
126
+ return retrieveRootPathSync(isGlobal, uid);
127
+ }
128
+ /**
129
+ * Used to mock http request to Salesforce.
130
+ *
131
+ * @param request An HttpRequest.
132
+ * @param options Additional options.
133
+ *
134
+ * **See** {@link Connection.request}
135
+ */
136
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
137
+ async fakeConnectionRequest(request, options) {
138
+ return defaultFakeConnectionRequest();
139
+ }
140
+ /**
141
+ * Gets a config stub contents by name.
142
+ *
143
+ * @param name The name of the config.
144
+ * @param group If the config supports groups.
145
+ */
146
+ getConfigStubContents(name, group) {
147
+ const stub = this.configStubs[name];
148
+ if (stub?.contents) {
149
+ if (group && stub.contents[group]) {
150
+ return (0, ts_types_1.ensureJsonMap)(stub.contents[group]);
151
+ }
152
+ else {
153
+ return stub.contents;
154
+ }
155
+ }
156
+ return {};
157
+ }
158
+ /**
159
+ * Sets a config stub contents by name
160
+ *
161
+ * @param name The name of the config stub.
162
+ * @param value The actual stub contents. The Mock data.
163
+ */
164
+ setConfigStubContents(name, value) {
165
+ if ((0, ts_types_1.ensureString)(name) && (0, ts_types_1.isJsonMap)(value)) {
166
+ this.configStubs[name] = value;
167
+ }
168
+ }
169
+ /**
170
+ * Set stubs for working in the context of a SfProject
171
+ */
172
+ inProject(inProject = true) {
173
+ this.SANDBOXES.PROJECT.restore();
174
+ if (inProject) {
175
+ this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPath').callsFake(() => this.localPathRetriever(this.id));
176
+ this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPathSync').callsFake(() => this.localPathRetrieverSync(this.id));
177
+ }
178
+ else {
179
+ this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPath').rejects(new sfError_1.SfError('', 'InvalidProjectWorkspaceError'));
180
+ this.SANDBOXES.PROJECT.stub(sfProject_1.SfProject, 'resolveProjectPathSync').throws(new sfError_1.SfError('', 'InvalidProjectWorkspaceError'));
181
+ }
182
+ }
183
+ /**
184
+ * Stub salesforce org authorizations.
185
+ */
186
+ async stubAuths(...orgs) {
187
+ const entries = await Promise.all(orgs.map(async (org) => [org.username, await org.getConfig()]));
188
+ const orgMap = new Map(entries);
189
+ (0, ts_sinon_1.stubMethod)(this.SANDBOX, stateAggregator_1.OrgAccessor.prototype, 'getAllFiles').resolves([...orgMap.keys()].map((o) => `${o}.json`));
190
+ (0, ts_sinon_1.stubMethod)(this.SANDBOX, stateAggregator_1.OrgAccessor.prototype, 'hasFile').callsFake((username) => orgMap.has(username));
191
+ const retrieveContents = async function () {
192
+ const username = (0, path_1.basename)(this.path.replace('.json', ''));
193
+ return Promise.resolve(orgMap.get(username) ?? {});
194
+ };
195
+ this.configStubs.AuthInfoConfig = { retrieveContents };
196
+ }
197
+ /**
198
+ * Stub salesforce user authorizations.
199
+ *
200
+ * @param users The users to stub.
201
+ * The key is the username of the admin user and it must be included in the users array in order to obtain the orgId key for the remaining users.
202
+ * The admin user is excluded from the users array.
203
+ *
204
+ */
205
+ stubUsers(users) {
206
+ const mockUsers = Object.values(users).flatMap((orgUsers) => orgUsers.map((user) => {
207
+ const userInfo = user.getMockUserInfo();
208
+ return {
209
+ alias: userInfo.Alias ?? '',
210
+ email: userInfo.Email ?? '',
211
+ emailEncodingKey: userInfo.EmailEncodingKey ?? '',
212
+ id: userInfo.Id ?? '',
213
+ languageLocaleKey: userInfo.LanguageLocaleKey ?? '',
214
+ lastName: userInfo.LastName ?? '',
215
+ localeSidKey: userInfo.LocaleSidKey ?? '',
216
+ profileId: userInfo.ProfileId ?? '',
217
+ timeZoneSidKey: userInfo.TimeZoneSidKey ?? '',
218
+ username: userInfo.Username ?? '',
219
+ };
220
+ }));
221
+ const userOrgsMap = new Map(Object.entries(users).map(([adminUsername, orgs]) => {
222
+ const adminOrg = orgs.find((org) => org.username === adminUsername);
223
+ return adminOrg
224
+ ? [adminOrg.orgId, { usernames: orgs.filter((org) => org.username !== adminUsername) }]
225
+ : [undefined, undefined];
226
+ }));
227
+ (0, ts_sinon_1.stubMethod)(this.SANDBOX, org_1.User.prototype, 'retrieve').callsFake((username) => Promise.resolve(mockUsers.find((org) => org.username === username)));
228
+ const retrieveContents = async function () {
229
+ const orgId = (0, path_1.basename)(this.path.replace('.json', ''));
230
+ return Promise.resolve(userOrgsMap.get(orgId) ?? {});
231
+ };
232
+ this.configStubs.OrgUsersConfig = { retrieveContents };
233
+ }
234
+ /**
235
+ * Stub salesforce sandbox authorizations.
236
+ */
237
+ async stubSandboxes(...sandboxes) {
238
+ const entries = (await Promise.all(sandboxes.map(async (sandbox) => [sandbox.username, await sandbox.getConfig()])));
239
+ const sandboxMap = new Map(entries);
240
+ (0, ts_sinon_1.stubMethod)(this.SANDBOX, sandboxAccessor_1.SandboxAccessor.prototype, 'getAllFiles').resolves([...sandboxMap.keys()].map((o) => `${o}.sandbox.json`));
241
+ const retrieveContents = async function () {
242
+ const username = (0, path_1.basename)(this.path.replace('.sandbox.json', ''));
243
+ return Promise.resolve(sandboxMap.get(username) ?? {});
244
+ };
245
+ this.configStubs.SandboxOrgConfig = { retrieveContents };
246
+ }
247
+ /**
248
+ * Stub the aliases in the global aliases config file.
249
+ */
250
+ stubAliases(aliases, group = aliasAccessorEntireFile.DEFAULT_GROUP) {
251
+ // we don't really "stub" these since they don't use configFile.
252
+ // write the fileContents to location
253
+ fs.mkdirSync((0, path_1.dirname)(getAliasFileLocation()), { recursive: true });
254
+ fs.writeFileSync(getAliasFileLocation(), JSON.stringify({ [group]: aliases }));
255
+ }
256
+ /**
257
+ * Stub contents in the config file.
258
+ */
259
+ async stubConfig(config) {
260
+ this.configStubs.Config = { contents: config };
261
+ // configAggregator may have already loaded an instance. We're not sure why this happens.
262
+ // This seems to solve the problem by forcing a load of the new stubbed config.
263
+ await configAggregator_1.ConfigAggregator.create();
264
+ }
265
+ /**
266
+ * Stub the tokens in the global token config file.
267
+ */
268
+ stubTokens(tokens) {
269
+ this.configStubs.TokensConfig = { contents: tokens };
270
+ }
271
+ restore() {
272
+ (0, exports.restoreContext)(this);
273
+ }
274
+ init() {
275
+ this.stubs = (0, exports.stubContext)(this);
276
+ }
277
+ /**
278
+ * Add beforeEach and afterEach hooks to init the stubs and restore them.
279
+ * This is called automatically when the class is instantiated unless the setup option is set to false.
280
+ */
281
+ setup() {
282
+ beforeEach(() => {
283
+ this.init();
284
+ });
285
+ afterEach(() => {
286
+ this.restore();
287
+ });
288
+ }
289
+ requireSinon(sinon) {
290
+ if (sinon)
291
+ return sinon;
292
+ try {
293
+ sinon = require('sinon');
294
+ }
295
+ catch (e) {
296
+ throw new Error('The package sinon was not found. Add it to your package.json and pass it in to new TestContext({sinon})');
297
+ }
298
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
299
+ return sinon;
300
+ }
301
+ }
302
+ exports.TestContext = TestContext;
303
+ /**
304
+ * A function to generate a unique id and return it in the context of a template, if supplied.
305
+ *
306
+ * A template is a string that can contain `${%s}` to be replaced with a unique id.
307
+ * If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
308
+ *
309
+ * @param options an object with the following properties:
310
+ * - template: a template string.
311
+ * - length: the length of the unique id as presented in hexadecimal.
312
+ */
313
+ function uniqid(options) {
314
+ const uniqueString = (0, crypto_1.randomBytes)(Math.ceil((options?.length ?? 32) / 2.0))
315
+ .toString('hex')
316
+ .slice(0, options?.length ?? 32);
317
+ if (!options?.template) {
318
+ return uniqueString;
319
+ }
320
+ return options.template.includes('%s')
321
+ ? util.format(options.template, uniqueString)
322
+ : `${options.template}${uniqueString}`;
323
+ }
324
+ exports.uniqid = uniqid;
32
325
  function getTestLocalPath(uid) {
33
326
  return (0, path_1.join)((0, os_1.tmpdir)(), uid, 'sfdx_core', 'local');
34
327
  }
@@ -57,86 +350,16 @@ function defaultFakeConnectionRequest() {
57
350
  * const $$ = instantiateContext();
58
351
  *
59
352
  * beforeEach(() => {
60
- * stubContext($$);
353
+ * $$.init()
61
354
  * });
62
355
  *
63
356
  * afterEach(() => {
64
- * restoreContext($$);
357
+ * $$.restore();
65
358
  * });
66
359
  * ```
67
360
  * @param sinon
68
361
  */
69
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
70
- const instantiateContext = (sinon) => {
71
- if (!sinon) {
72
- try {
73
- sinon = require('sinon');
74
- }
75
- catch (e) {
76
- throw new Error('The package sinon was not found. Add it to your package.json and pass it in to testSetup(sinon.sandbox)');
77
- }
78
- }
79
- // Import all the messages files in the sfdx-core messages dir.
80
- // Messages.importMessagesDirectory(pathJoin(__dirname, '..', '..'));
81
- messages_1.Messages.importMessagesDirectory((0, path_1.join)(__dirname));
82
- // Create a global sinon sandbox and a test logger instance for use within tests.
83
- const defaultSandbox = sinon.createSandbox();
84
- const testContext = {
85
- SANDBOX: defaultSandbox,
86
- SANDBOXES: {
87
- DEFAULT: defaultSandbox,
88
- CONFIG: sinon.createSandbox(),
89
- PROJECT: sinon.createSandbox(),
90
- CRYPTO: sinon.createSandbox(),
91
- CONNECTION: sinon.createSandbox(),
92
- FS: sinon.createSandbox(),
93
- },
94
- TEST_LOGGER: new logger_1.Logger({
95
- name: 'SFDX_Core_Test_Logger',
96
- }).useMemoryLogging(),
97
- id: uniqid(),
98
- uniqid,
99
- configStubs: {},
100
- // eslint-disable-next-line @typescript-eslint/require-await
101
- localPathRetriever: async (uid) => getTestLocalPath(uid),
102
- localPathRetrieverSync: getTestLocalPath,
103
- // eslint-disable-next-line @typescript-eslint/require-await
104
- globalPathRetriever: async (uid) => getTestGlobalPath(uid),
105
- globalPathRetrieverSync: getTestGlobalPath,
106
- rootPathRetriever: retrieveRootPath,
107
- rootPathRetrieverSync: retrieveRootPathSync,
108
- fakeConnectionRequest: defaultFakeConnectionRequest,
109
- getConfigStubContents(name, group) {
110
- const stub = this.configStubs[name];
111
- if (stub && stub.contents) {
112
- if (group && stub.contents[group]) {
113
- return (0, ts_types_1.ensureJsonMap)(stub.contents[group]);
114
- }
115
- else {
116
- return stub.contents;
117
- }
118
- }
119
- return {};
120
- },
121
- setConfigStubContents(name, value) {
122
- if ((0, ts_types_1.ensureString)(name) && (0, ts_types_1.isJsonMap)(value)) {
123
- this.configStubs[name] = value;
124
- }
125
- },
126
- inProject(inProject = true) {
127
- testContext.SANDBOXES.PROJECT.restore();
128
- if (inProject) {
129
- testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPath').callsFake(() => testContext.localPathRetriever(testContext.id));
130
- testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPathSync').callsFake(() => testContext.localPathRetrieverSync(testContext.id));
131
- }
132
- else {
133
- testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPath').rejects(new sfdxError_1.SfdxError('', 'InvalidProjectWorkspaceError'));
134
- testContext.SANDBOXES.PROJECT.stub(sfdxProject_1.SfdxProject, 'resolveProjectPathSync').throws(new sfdxError_1.SfdxError('', 'InvalidProjectWorkspaceError'));
135
- }
136
- },
137
- };
138
- return testContext;
139
- };
362
+ const instantiateContext = (sinon) => new TestContext({ sinon, setup: false });
140
363
  exports.instantiateContext = instantiateContext;
141
364
  /**
142
365
  * Stub a @salesforce/core test context. This will mock out logging to a file, config file reading and writing,
@@ -153,11 +376,11 @@ exports.instantiateContext = instantiateContext;
153
376
  * const $$ = instantiateContext();
154
377
  *
155
378
  * beforeEach(() => {
156
- * stubContext($$);
379
+ * $$.init()
157
380
  * });
158
381
  *
159
382
  * afterEach(() => {
160
- * restoreContext($$);
383
+ * $$.restore();
161
384
  * });
162
385
  * ```
163
386
  * @param testContext
@@ -165,34 +388,33 @@ exports.instantiateContext = instantiateContext;
165
388
  const stubContext = (testContext) => {
166
389
  // Turn off the interoperability feature so that we don't have to mock
167
390
  // the old .sfdx config files
168
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
169
- // @ts-ignore
170
391
  global_1.Global.SFDX_INTEROPERABILITY = false;
392
+ const stubs = {};
171
393
  // Most core files create a child logger so stub this to return our test logger.
172
- (0, ts_sinon_1.stubMethod)(testContext.SANDBOX, logger_1.Logger, 'child').returns(Promise.resolve(testContext.TEST_LOGGER));
394
+ (0, ts_sinon_1.stubMethod)(testContext.SANDBOX, logger_1.Logger, 'child').resolves(testContext.TEST_LOGGER);
173
395
  (0, ts_sinon_1.stubMethod)(testContext.SANDBOX, logger_1.Logger, 'childFromRoot').returns(testContext.TEST_LOGGER);
174
396
  testContext.inProject(true);
175
397
  testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile, 'resolveRootFolder').callsFake((isGlobal) => testContext.rootPathRetriever(isGlobal, testContext.id));
176
398
  testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile, 'resolveRootFolderSync').callsFake((isGlobal) => testContext.rootPathRetrieverSync(isGlobal, testContext.id));
177
- (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.PROJECT, sfdxProject_1.SfdxProjectJson.prototype, 'doesPackageExist').callsFake(() => true);
399
+ (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.PROJECT, sfProject_1.SfProjectJson.prototype, 'doesPackageExist').callsFake(() => true);
178
400
  const initStubForRead = (configFile) => {
179
- const stub = testContext.configStubs[configFile.constructor.name] || {};
401
+ const stub = testContext.configStubs[configFile.constructor.name] ?? {};
180
402
  // init calls read calls getPath which sets the path on the config file the first time.
181
403
  // Since read is now stubbed, make sure to call getPath to initialize it.
182
404
  configFile.getPath();
183
- // @ts-ignore set this to true to avoid an infinite loop in tests when reading config files.
405
+ // @ts-expect-error: set this to true to avoid an infinite loop in tests when reading config files.
184
406
  configFile.hasRead = true;
185
407
  return stub;
186
408
  };
187
409
  const readSync = function (newContents) {
188
410
  const stub = initStubForRead(this);
189
- this.setContentsFromObject(newContents || stub.contents || {});
411
+ this.setContentsFromObject(newContents ?? stub.contents ?? {});
190
412
  return this.getContents();
191
413
  };
192
414
  const read = async function () {
193
415
  const stub = initStubForRead(this);
194
416
  if (stub.readFn) {
195
- return await stub.readFn.call(this);
417
+ return stub.readFn.call(this);
196
418
  }
197
419
  if (stub.retrieveContents) {
198
420
  return readSync.call(this, await stub.retrieveContents.call(this));
@@ -202,9 +424,9 @@ const stubContext = (testContext) => {
202
424
  }
203
425
  };
204
426
  // Mock out all config file IO for all tests. They can restore individually if they need original functionality.
205
- // @ts-ignore
206
- testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'readSync').callsFake(readSync);
207
- testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'read').callsFake(read);
427
+ stubs.configRead = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'read').callsFake(read);
428
+ // @ts-expect-error: muting exact type match for stub readSync
429
+ stubs.configReadSync = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'readSync').callsFake(readSync);
208
430
  const writeSync = function (newContents) {
209
431
  if (!testContext.configStubs[this.constructor.name]) {
210
432
  testContext.configStubs[this.constructor.name] = {};
@@ -212,7 +434,7 @@ const stubContext = (testContext) => {
212
434
  const stub = testContext.configStubs[this.constructor.name];
213
435
  if (!stub)
214
436
  return;
215
- this.setContents(newContents || this.getContents());
437
+ this.setContents(newContents ?? this.getContents());
216
438
  stub.contents = this.toObject();
217
439
  };
218
440
  const write = async function (newContents) {
@@ -223,7 +445,7 @@ const stubContext = (testContext) => {
223
445
  if (!stub)
224
446
  return;
225
447
  if (stub.writeFn) {
226
- return await stub.writeFn.call(this, newContents);
448
+ return stub.writeFn.call(this, newContents);
227
449
  }
228
450
  if (stub.updateContents) {
229
451
  writeSync.call(this, await stub.updateContents.call(this));
@@ -232,8 +454,8 @@ const stubContext = (testContext) => {
232
454
  writeSync.call(this);
233
455
  }
234
456
  };
235
- (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'writeSync').callsFake(writeSync);
236
- (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'write').callsFake(write);
457
+ stubs.configWriteSync = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'writeSync').callsFake(writeSync);
458
+ stubs.configWrite = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'write').callsFake(write);
237
459
  (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CRYPTO, crypto_2.Crypto.prototype, 'getKeyChain').callsFake(() => Promise.resolve({
238
460
  setPassword: () => Promise.resolve(),
239
461
  getPassword: (data, cb) => cb(undefined, '12345678901234567890123456789012'),
@@ -245,10 +467,28 @@ const stubContext = (testContext) => {
245
467
  }
246
468
  return testContext.fakeConnectionRequest.call(this, request, options);
247
469
  });
470
+ (0, ts_sinon_1.stubMethod)(testContext.SANDBOX, aliasAccessorEntireFile, 'getFileLocation').returns(getAliasFileLocation());
471
+ stubs.configExists = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.ORGS, stateAggregator_1.OrgAccessor.prototype, 'exists').callsFake(async function (username) {
472
+ // @ts-expect-error because private member
473
+ if ([...this.contents.keys()].includes(username))
474
+ return Promise.resolve(true);
475
+ else
476
+ return Promise.resolve(false);
477
+ });
478
+ stubs.configRemove = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.ORGS, stateAggregator_1.OrgAccessor.prototype, 'remove').callsFake(async function (username) {
479
+ // @ts-expect-error because private member
480
+ if ([...this.contents.keys()].includes(username))
481
+ return Promise.resolve(true);
482
+ else
483
+ return Promise.resolve(false);
484
+ });
248
485
  // Always start with the default and tests beforeEach or it methods can override it.
249
486
  testContext.fakeConnectionRequest = defaultFakeConnectionRequest;
487
+ testContext.stubs = stubs;
488
+ return stubs;
250
489
  };
251
490
  exports.stubContext = stubContext;
491
+ const getAliasFileLocation = () => (0, path_1.join)((0, os_1.tmpdir)(), global_1.Global.SFDX_STATE_FOLDER, aliasAccessorEntireFile.FILENAME);
252
492
  /**
253
493
  * Restore a @salesforce/core test context. This is automatically stubbed in the global beforeEach created by
254
494
  * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
@@ -259,78 +499,41 @@ exports.stubContext = stubContext;
259
499
  * const $$ = instantiateContext();
260
500
  *
261
501
  * beforeEach(() => {
262
- * stubContext($$);
502
+ * $$.init()
263
503
  * });
264
504
  *
265
505
  * afterEach(() => {
266
- * restoreContext($$);
506
+ * $$.restore();
267
507
  * });
268
508
  * ```
269
509
  * @param testContext
270
510
  */
271
511
  const restoreContext = (testContext) => {
512
+ // Restore the default value for this setting on restore.
513
+ global_1.Global.SFDX_INTEROPERABILITY = true;
272
514
  testContext.SANDBOX.restore();
515
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
273
516
  Object.values(testContext.SANDBOXES).forEach((theSandbox) => theSandbox.restore());
274
517
  testContext.configStubs = {};
275
- // Give each test run a clean GlobalInstance
276
- globalInfo_1.GlobalInfo.clearInstance();
518
+ // Give each test run a clean StateAggregator
519
+ stateAggregator_1.StateAggregator.clearInstance();
520
+ // Allow each test to have their own config aggregator
521
+ // @ts-ignore clear for testing.
522
+ delete configAggregator_1.ConfigAggregator.instance;
277
523
  };
278
524
  exports.restoreContext = restoreContext;
279
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
280
- const _testSetup = (sinon) => {
281
- const testContext = (0, exports.instantiateContext)(sinon);
282
- beforeEach(() => {
283
- // Allow each test to have their own config aggregator
284
- // @ts-ignore clear for testing.
285
- delete configAggregator_1.ConfigAggregator.instance;
286
- (0, exports.stubContext)(testContext);
287
- });
288
- afterEach(() => {
289
- (0, exports.restoreContext)(testContext);
290
- });
291
- return testContext;
292
- };
293
- /**
294
- * Use to mock out different pieces of sfdx-core to make testing easier. This will mock out
295
- * logging to a file, config file reading and writing, local and global path resolution, and
296
- * *http request using connection (soon)*.
297
- *
298
- * **Note:** The testSetup should be outside of the describe. If you need to stub per test, use
299
- * `instantiateContext`, `stubContext`, and `restoreContext`.
300
- * ```
301
- * // In a mocha tests
302
- * import testSetup from '@salesforce/core/lib/testSetup';
303
- *
304
- * const $$ = testSetup();
305
- *
306
- * describe(() => {
307
- * it('test', () => {
308
- * // Stub out your own method
309
- * $$.SANDBOX.stub(MyClass.prototype, 'myMethod').returnsFake(() => {});
310
- *
311
- * // Set the contents that is used when aliases are read. Same for all config files.
312
- * $$.configStubs.Aliases = { contents: { 'myTestAlias': 'user@company.com' } };
313
- *
314
- * // Will use the contents set above.
315
- * const username = Aliases.fetch('myTestAlias');
316
- * expect(username).to.equal('user@company.com');
317
- * });
318
- * });
319
- * ```
320
- */
321
- exports.testSetup = (0, kit_1.once)(_testSetup);
322
525
  /**
323
526
  * A pre-canned error for try/catch testing.
324
527
  *
325
528
  * **See** {@link shouldThrow}
326
529
  */
327
- exports.unexpectedResult = new sfdxError_1.SfdxError('This code was expected to fail', 'UnexpectedResult');
530
+ exports.unexpectedResult = new sfError_1.SfError('This code was expected to fail', 'UnexpectedResult');
328
531
  /**
329
532
  * Use for this testing pattern:
330
533
  * ```
331
534
  * try {
332
535
  * await call()
333
- * assert.fail('this should never happen');
536
+ * assert.fail("this should never happen");
334
537
  * } catch (e) {
335
538
  * ...
336
539
  * }
@@ -346,11 +549,47 @@ exports.unexpectedResult = new sfdxError_1.SfdxError('This code was expected to
346
549
  *
347
550
  * @param f The async function that is expected to throw.
348
551
  */
349
- async function shouldThrow(f) {
552
+ async function shouldThrow(f, message) {
350
553
  await f;
351
- throw exports.unexpectedResult;
554
+ if (message) {
555
+ throw new sfError_1.SfError(message, 'UnexpectedResult');
556
+ }
557
+ else {
558
+ throw exports.unexpectedResult;
559
+ }
352
560
  }
353
561
  exports.shouldThrow = shouldThrow;
562
+ /**
563
+ * Use for this testing pattern:
564
+ * ```
565
+ * try {
566
+ * call()
567
+ * assert.fail("this should never happen");
568
+ * } catch (e) {
569
+ * ...
570
+ * }
571
+ *
572
+ * Just do this
573
+ *
574
+ * try {
575
+ * shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
576
+ * } catch(e) {
577
+ * ...
578
+ * }
579
+ * ```
580
+ *
581
+ * @param f The function that is expected to throw.
582
+ */
583
+ function shouldThrowSync(f, message) {
584
+ f();
585
+ if (message) {
586
+ throw new sfError_1.SfError(message, 'UnexpectedResult');
587
+ }
588
+ else {
589
+ throw exports.unexpectedResult;
590
+ }
591
+ }
592
+ exports.shouldThrowSync = shouldThrowSync;
354
593
  /**
355
594
  * A helper to determine if a subscription will use callback or errorback.
356
595
  * Enable errback to simulate a subscription failure.
@@ -472,33 +711,49 @@ class StreamingMockCometClient extends streamingClient_1.CometClient {
472
711
  }
473
712
  exports.StreamingMockCometClient = StreamingMockCometClient;
474
713
  /**
475
- * Mock class for OrgData.
714
+ * Mock class for Salesforce Orgs.
715
+ *
716
+ * @example
717
+ * ```
718
+ * const testOrg = new MockTestOrgData();
719
+ * await $$.stubAuths(testOrg)
720
+ * ```
476
721
  */
477
722
  class MockTestOrgData {
478
723
  constructor(id = uniqid(), options) {
479
724
  this.testId = id;
480
725
  this.userId = `user_id_${this.testId}`;
481
726
  this.orgId = `${this.testId}`;
482
- this.username = (options === null || options === void 0 ? void 0 : options.username) || `admin_${this.testId}@gb.org`;
483
- this.loginUrl = `http://login.${this.testId}.salesforce.com`;
484
- this.instanceUrl = `http://instance.${this.testId}.salesforce.com`;
727
+ this.username = options?.username ?? `admin_${this.testId}@gb.org`;
728
+ this.loginUrl = `https://login.${this.testId}.salesforce.com`;
729
+ this.instanceUrl = `https://instance.${this.testId}.salesforce.com`;
485
730
  this.clientId = `${this.testId}/client_id`;
486
731
  this.clientSecret = `${this.testId}/client_secret`;
487
732
  this.authcode = `${this.testId}/authcode`;
488
733
  this.accessToken = `${this.testId}/accessToken`;
489
734
  this.refreshToken = `${this.testId}/refreshToken`;
490
- this.redirectUri = `http://${this.testId}/localhost:1717/OauthRedirect`;
735
+ this.redirectUri = 'http://localhost:1717/OauthRedirect';
491
736
  }
737
+ /**
738
+ * Add devhub username to properties.
739
+ */
492
740
  createDevHubUsername(username) {
493
741
  this.devHubUsername = username;
494
742
  }
743
+ /**
744
+ * Mark this org as a devhub.
745
+ */
495
746
  makeDevHub() {
496
- (0, kit_1.set)(this, 'isDevHub', true);
747
+ this.isDevHub = true;
497
748
  }
749
+ /**
750
+ * Returns a MockTestOrgData that represents a user created in the org.
751
+ */
498
752
  createUser(user) {
499
753
  const userMock = new MockTestOrgData();
500
754
  userMock.username = user;
501
- userMock.alias = this.alias;
755
+ userMock.aliases = this.aliases;
756
+ userMock.configs = this.configs;
502
757
  userMock.devHubUsername = this.devHubUsername;
503
758
  userMock.orgId = this.orgId;
504
759
  userMock.loginUrl = this.loginUrl;
@@ -506,14 +761,23 @@ class MockTestOrgData {
506
761
  userMock.clientId = this.clientId;
507
762
  userMock.clientSecret = this.clientSecret;
508
763
  userMock.redirectUri = this.redirectUri;
764
+ userMock.isDevHub = this.isDevHub;
765
+ userMock.isScratchOrg = this.isScratchOrg;
766
+ userMock.isExpired = this.isExpired;
767
+ userMock.password = this.password;
768
+ userMock.accessToken = this.accessToken;
509
769
  return userMock;
510
770
  }
771
+ /**
772
+ * Return mock user information based on this org.
773
+ */
511
774
  getMockUserInfo() {
512
775
  return {
513
776
  Id: this.userId,
514
777
  Username: this.username,
515
778
  LastName: `user_lastname_${this.testId}`,
516
- Alias: this.alias || 'user_alias_blah',
779
+ Alias: this.aliases ? this.aliases[0] : 'user_alias_blah',
780
+ Configs: this.configs,
517
781
  TimeZoneSidKey: `user_timezonesidkey_${this.testId}`,
518
782
  LocaleSidKey: `user_localesidkey_${this.testId}`,
519
783
  EmailEncodingKey: `user_emailencodingkey_${this.testId}`,
@@ -522,17 +786,20 @@ class MockTestOrgData {
522
786
  Email: `user_email@${this.testId}.com`,
523
787
  };
524
788
  }
789
+ /**
790
+ * Return the auth config file contents.
791
+ */
525
792
  async getConfig() {
526
793
  const crypto = await crypto_2.Crypto.create();
527
794
  const config = {};
528
795
  config.orgId = this.orgId;
796
+ config.clientId = this.clientId;
529
797
  const accessToken = crypto.encrypt(this.accessToken);
530
798
  if (accessToken) {
531
799
  config.accessToken = accessToken;
532
800
  }
533
- const refreshToken = crypto.encrypt(this.refreshToken);
534
- if (refreshToken) {
535
- config.refreshToken = refreshToken;
801
+ if (this.refreshToken) {
802
+ config.refreshToken = crypto.encrypt(this.refreshToken);
536
803
  }
537
804
  config.instanceUrl = this.instanceUrl;
538
805
  config.loginUrl = this.loginUrl;
@@ -540,16 +807,53 @@ class MockTestOrgData {
540
807
  config.createdOrgInstance = 'CS1';
541
808
  config.created = '1519163543003';
542
809
  config.userId = this.userId;
543
- // config.devHubUsername = 'tn@su-blitz.org';
810
+ config.tracksSource = this.tracksSource;
544
811
  if (this.devHubUsername) {
545
812
  config.devHubUsername = this.devHubUsername;
546
813
  }
547
- const isDevHub = (0, ts_types_1.getBoolean)(this, 'isDevHub');
548
- if (isDevHub) {
549
- config.isDevHub = isDevHub;
814
+ config.isDevHub = this.isDevHub;
815
+ if (this.password) {
816
+ config.password = crypto.encrypt(this.password);
550
817
  }
551
818
  return config;
552
819
  }
820
+ /**
821
+ * Return the Connection for the org.
822
+ */
823
+ async getConnection() {
824
+ return (await org_1.Org.create({ aliasOrUsername: this.username })).getConnection();
825
+ }
553
826
  }
554
827
  exports.MockTestOrgData = MockTestOrgData;
828
+ /**
829
+ * Mock class for Salesforce Sandboxes.
830
+ *
831
+ * @example
832
+ * ```
833
+ * const testOrg = new MockTestSandboxData();
834
+ * await $$.stubSandboxes(testOrg)
835
+ * ```
836
+ */
837
+ class MockTestSandboxData {
838
+ constructor(id = uniqid(), options) {
839
+ this.id = id;
840
+ this.sandboxOrgId = id;
841
+ this.prodOrgUsername = options?.prodOrgUsername ?? `admin_${id}@gb.org`;
842
+ this.sandboxName = options?.name ?? `sandbox_${id}`;
843
+ this.username = options?.username ?? `${this.prodOrgUsername}.sandbox`;
844
+ }
845
+ /**
846
+ * Return the auth config file contents.
847
+ */
848
+ // eslint-disable-next-line @typescript-eslint/require-await
849
+ async getConfig() {
850
+ return {
851
+ sandboxOrgId: this.sandboxOrgId,
852
+ prodOrgUsername: this.prodOrgUsername,
853
+ sandboxName: this.sandboxName,
854
+ sandboxUsername: this.username,
855
+ };
856
+ }
857
+ }
858
+ exports.MockTestSandboxData = MockTestSandboxData;
555
859
  //# sourceMappingURL=testSetup.js.map