@salesforce/core 5.3.8 → 5.4.0-crdt.1
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/lib/config/config.d.ts +4 -4
- package/lib/config/config.js +6 -9
- package/lib/config/configFile.d.ts +4 -3
- package/lib/config/configFile.js +63 -14
- package/lib/config/configStackTypes.d.ts +14 -0
- package/lib/config/configStackTypes.js +3 -0
- package/lib/config/configStore.d.ts +8 -19
- package/lib/config/configStore.js +36 -37
- package/lib/config/lwwMap.d.ts +25 -0
- package/lib/config/lwwMap.js +93 -0
- package/lib/config/lwwRegister.d.ts +19 -0
- package/lib/config/lwwRegister.js +39 -0
- package/lib/config/orgUsersConfig.d.ts +5 -1
- package/lib/config/tokensConfig.d.ts +1 -1
- package/lib/config/ttlConfig.js +4 -1
- package/lib/exported.d.ts +2 -1
- package/lib/org/authInfo.d.ts +3 -1
- package/lib/org/authInfo.js +2 -0
- package/lib/org/org.js +2 -2
- package/lib/org/orgConfigProperties.d.ts +1 -1
- package/lib/org/user.js +1 -2
- package/lib/sfProject.d.ts +3 -3
- package/lib/sfProject.js +5 -19
- package/lib/stateAggregator/accessors/aliasAccessor.d.ts +2 -2
- package/lib/stateAggregator/accessors/aliasAccessor.js +3 -7
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +2 -1
- package/lib/stateAggregator/accessors/orgAccessor.js +1 -0
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +1 -1
- package/lib/stateAggregator/accessors/tokenAccessor.js +1 -1
- package/lib/testSetup.d.ts +3 -20
- package/lib/testSetup.js +24 -58
- package/lib/util/lockRetryOptions.d.ts +11 -0
- package/lib/util/lockRetryOptions.js +16 -0
- package/lib/util/uniqid.d.ts +14 -0
- package/lib/util/uniqid.js +34 -0
- package/package.json +5 -5
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2023, 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.LWWRegister = void 0;
|
|
10
|
+
/** a CRDT implementation. Uses timestamps to resolve conflicts when updating the value (last write wins)
|
|
11
|
+
* mostly based on https://jakelazaroff.com/words/an-interactive-intro-to-crdts/
|
|
12
|
+
*
|
|
13
|
+
* @param T the type of the value stored in the register
|
|
14
|
+
*/
|
|
15
|
+
class LWWRegister {
|
|
16
|
+
constructor(id, state) {
|
|
17
|
+
this.id = id;
|
|
18
|
+
this.state = state;
|
|
19
|
+
}
|
|
20
|
+
get value() {
|
|
21
|
+
return this.state.value;
|
|
22
|
+
}
|
|
23
|
+
set(value) {
|
|
24
|
+
// set the peer ID to the local ID, timestamp it and set the value
|
|
25
|
+
this.state = { peer: this.id, timestamp: process.hrtime.bigint(), value };
|
|
26
|
+
}
|
|
27
|
+
merge(incoming) {
|
|
28
|
+
// only update if the incoming timestamp is greater than the local timestamp
|
|
29
|
+
// console.log(`incoming: ${}`);
|
|
30
|
+
// console.log(`local: ${JSON.stringify(this.state)}`);
|
|
31
|
+
if (incoming.timestamp > this.state.timestamp) {
|
|
32
|
+
this.state = incoming;
|
|
33
|
+
}
|
|
34
|
+
// TODO: if the timestamps match, use the peer ID to break the tie (prefer self?)
|
|
35
|
+
return this.state;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.LWWRegister = LWWRegister;
|
|
39
|
+
//# sourceMappingURL=lwwRegister.js.map
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { ConfigFile } from './configFile';
|
|
2
|
+
type UserConfig = {
|
|
3
|
+
usernames: string[];
|
|
4
|
+
};
|
|
2
5
|
/**
|
|
3
6
|
* A config file that stores usernames for an org.
|
|
4
7
|
*/
|
|
5
|
-
export declare class OrgUsersConfig extends ConfigFile<OrgUsersConfig.Options> {
|
|
8
|
+
export declare class OrgUsersConfig extends ConfigFile<OrgUsersConfig.Options, UserConfig> {
|
|
6
9
|
/**
|
|
7
10
|
* Constructor.
|
|
8
11
|
* **Do not directly construct instances of this class -- use {@link OrgUsersConfig.create} instead.**
|
|
@@ -29,3 +32,4 @@ export declare namespace OrgUsersConfig {
|
|
|
29
32
|
orgId: string;
|
|
30
33
|
}
|
|
31
34
|
}
|
|
35
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Optional } from '@salesforce/ts-types';
|
|
2
2
|
import { SfTokens } from '../stateAggregator';
|
|
3
3
|
import { ConfigFile } from './configFile';
|
|
4
|
-
import { ConfigContents, ConfigValue } from './
|
|
4
|
+
import { ConfigContents, ConfigValue } from './configStackTypes';
|
|
5
5
|
export declare class TokensConfig extends ConfigFile<ConfigFile.Options, SfTokens> {
|
|
6
6
|
protected static encryptedKeys: RegExp[];
|
|
7
7
|
static getDefaultOptions(): ConfigFile.Options;
|
package/lib/config/ttlConfig.js
CHANGED
|
@@ -39,7 +39,10 @@ class TTLConfig extends configFile_1.ConfigFile {
|
|
|
39
39
|
async init() {
|
|
40
40
|
const contents = await this.read(this.options.throwOnNotFound);
|
|
41
41
|
const date = new Date().getTime();
|
|
42
|
-
|
|
42
|
+
// delete all the expired entries
|
|
43
|
+
Object.entries(contents)
|
|
44
|
+
.filter(([, value]) => this.isExpired(date, value))
|
|
45
|
+
.map(([key]) => this.unset(key));
|
|
43
46
|
}
|
|
44
47
|
// eslint-disable-next-line class-methods-use-this
|
|
45
48
|
timestamp(value) {
|
package/lib/exported.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export { OAuth2Config } from 'jsforce';
|
|
|
2
2
|
export { ConfigFile } from './config/configFile';
|
|
3
3
|
export { TTLConfig } from './config/ttlConfig';
|
|
4
4
|
export { envVars, EnvironmentVariable, SUPPORTED_ENV_VARS, EnvVars } from './config/envVars';
|
|
5
|
-
export {
|
|
5
|
+
export { ConfigStore } from './config/configStore';
|
|
6
|
+
export { ConfigEntry, ConfigContents, ConfigValue } from './config/configStackTypes';
|
|
6
7
|
export { SfTokens, StateAggregator } from './stateAggregator';
|
|
7
8
|
export { DeviceOauthService, DeviceCodeResponse, DeviceCodePollingResponse } from './deviceOauthService';
|
|
8
9
|
export { OrgUsersConfig } from './config/orgUsersConfig';
|
package/lib/org/authInfo.d.ts
CHANGED
|
@@ -242,8 +242,10 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
|
|
|
242
242
|
* Get the authorization fields.
|
|
243
243
|
*
|
|
244
244
|
* @param decrypt Decrypt the fields.
|
|
245
|
+
*
|
|
246
|
+
* Returns a ReadOnly object of the fields. If you need to modify the fields, use AuthInfo.update()
|
|
245
247
|
*/
|
|
246
|
-
getFields(decrypt?: boolean): AuthFields
|
|
248
|
+
getFields(decrypt?: boolean): Readonly<AuthFields>;
|
|
247
249
|
/**
|
|
248
250
|
* Get the org front door (used for web based oauth flows)
|
|
249
251
|
*/
|
package/lib/org/authInfo.js
CHANGED
|
@@ -461,6 +461,8 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
461
461
|
* Get the authorization fields.
|
|
462
462
|
*
|
|
463
463
|
* @param decrypt Decrypt the fields.
|
|
464
|
+
*
|
|
465
|
+
* Returns a ReadOnly object of the fields. If you need to modify the fields, use AuthInfo.update()
|
|
464
466
|
*/
|
|
465
467
|
getFields(decrypt) {
|
|
466
468
|
return this.stateAggregator.orgs.get(this.username, decrypt) ?? {};
|
package/lib/org/org.js
CHANGED
|
@@ -631,8 +631,8 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
631
631
|
const orgConfig = await this.retrieveOrgUsersConfig();
|
|
632
632
|
const contents = await orgConfig.read();
|
|
633
633
|
const targetUser = authInfo.getFields().username;
|
|
634
|
-
const usernames = (contents.usernames ?? []);
|
|
635
|
-
|
|
634
|
+
const usernames = (contents.usernames ?? []).filter((username) => username !== targetUser);
|
|
635
|
+
orgConfig.set('usernames', usernames);
|
|
636
636
|
await orgConfig.write();
|
|
637
637
|
return this;
|
|
638
638
|
}
|
package/lib/org/user.js
CHANGED
|
@@ -303,8 +303,7 @@ class User extends kit_1.AsyncCreatable {
|
|
|
303
303
|
oauth2Options: oauthOptions,
|
|
304
304
|
});
|
|
305
305
|
// Update the auth info object with created user id.
|
|
306
|
-
|
|
307
|
-
newUserAuthFields.userId = refreshTokenSecret.userId;
|
|
306
|
+
newUserAuthInfo.update({ userId: refreshTokenSecret.userId });
|
|
308
307
|
// Make sure we can connect and if so save the auth info.
|
|
309
308
|
await this.describeUserAndSave(newUserAuthInfo);
|
|
310
309
|
// Let the org know there is a new user. See $HOME/.sfdx/[orgid].json for the mapping.
|
package/lib/sfProject.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Dictionary, JsonMap, Nullable, Optional } from '@salesforce/ts-types';
|
|
2
2
|
import { ConfigFile } from './config/configFile';
|
|
3
|
-
import { ConfigContents } from './config/
|
|
3
|
+
import { ConfigContents } from './config/configStackTypes';
|
|
4
4
|
export type PackageDirDependency = {
|
|
5
5
|
[k: string]: unknown;
|
|
6
6
|
package: string;
|
|
@@ -70,8 +70,8 @@ export declare class SfProjectJson extends ConfigFile {
|
|
|
70
70
|
static getDefaultOptions(isGlobal?: boolean): ConfigFile.Options;
|
|
71
71
|
read(): Promise<ConfigContents>;
|
|
72
72
|
readSync(): ConfigContents;
|
|
73
|
-
write(
|
|
74
|
-
writeSync(
|
|
73
|
+
write(): Promise<ConfigContents>;
|
|
74
|
+
writeSync(): ConfigContents;
|
|
75
75
|
getContents(): ProjectJson;
|
|
76
76
|
getDefaultOptions(options?: ConfigFile.Options): ConfigFile.Options;
|
|
77
77
|
/**
|
package/lib/sfProject.js
CHANGED
|
@@ -57,17 +57,11 @@ class SfProjectJson extends configFile_1.ConfigFile {
|
|
|
57
57
|
this.validateKeys();
|
|
58
58
|
return contents;
|
|
59
59
|
}
|
|
60
|
-
async write(
|
|
61
|
-
if (newContents) {
|
|
62
|
-
this.setContents(newContents);
|
|
63
|
-
}
|
|
60
|
+
async write() {
|
|
64
61
|
this.validateKeys();
|
|
65
62
|
return super.write();
|
|
66
63
|
}
|
|
67
|
-
writeSync(
|
|
68
|
-
if (newContents) {
|
|
69
|
-
this.setContents(newContents);
|
|
70
|
-
}
|
|
64
|
+
writeSync() {
|
|
71
65
|
this.validateKeys();
|
|
72
66
|
return super.writeSync();
|
|
73
67
|
}
|
|
@@ -76,11 +70,7 @@ class SfProjectJson extends configFile_1.ConfigFile {
|
|
|
76
70
|
}
|
|
77
71
|
// eslint-disable-next-line class-methods-use-this
|
|
78
72
|
getDefaultOptions(options) {
|
|
79
|
-
|
|
80
|
-
isState: false,
|
|
81
|
-
};
|
|
82
|
-
Object.assign(defaultOptions, options ?? {});
|
|
83
|
-
return defaultOptions;
|
|
73
|
+
return { ...{ isState: false }, ...(options ?? {}) };
|
|
84
74
|
}
|
|
85
75
|
/**
|
|
86
76
|
* Validates sfdx-project.json against the schema.
|
|
@@ -259,12 +249,8 @@ class SfProjectJson extends configFile_1.ConfigFile {
|
|
|
259
249
|
if (!/^.{15,18}$/.test(id)) {
|
|
260
250
|
throw messages.createError('invalidId', [id]);
|
|
261
251
|
}
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
contents.packageAliases = {};
|
|
265
|
-
}
|
|
266
|
-
contents.packageAliases[alias] = id;
|
|
267
|
-
this.setContents(contents);
|
|
252
|
+
const newAliases = { ...(this.getContents().packageAliases ?? {}), [alias]: id };
|
|
253
|
+
this.contents.set('packageAliases', newAliases);
|
|
268
254
|
}
|
|
269
255
|
/**
|
|
270
256
|
* Add a package directory to the project.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncOptionalCreatable } from '@salesforce/kit';
|
|
2
2
|
import { Nullable } from '@salesforce/ts-types';
|
|
3
3
|
import { AuthFields } from '../../org/authInfo';
|
|
4
|
-
import { ConfigContents } from '../../config/
|
|
4
|
+
import { ConfigContents } from '../../config/configStackTypes';
|
|
5
5
|
import { SfToken } from './tokenAccessor';
|
|
6
6
|
export type Aliasable = string | (Partial<AuthFields> & Partial<SfToken>);
|
|
7
7
|
export declare const DEFAULT_GROUP = "orgs";
|
|
@@ -103,7 +103,7 @@ export declare class AliasAccessor extends AsyncOptionalCreatable {
|
|
|
103
103
|
/**
|
|
104
104
|
* @deprecated the set/unset methods now write to the file when called. Use (un)setAndSave instead of calling (un)set and then calling write()
|
|
105
105
|
*/
|
|
106
|
-
write(): Promise<ConfigContents
|
|
106
|
+
write(): Promise<ConfigContents<string>>;
|
|
107
107
|
/**
|
|
108
108
|
* Returns true if the provided alias exists
|
|
109
109
|
*
|
|
@@ -15,13 +15,9 @@ const proper_lockfile_1 = require("proper-lockfile");
|
|
|
15
15
|
const kit_1 = require("@salesforce/kit");
|
|
16
16
|
const global_1 = require("../../global");
|
|
17
17
|
const sfError_1 = require("../../sfError");
|
|
18
|
+
const lockRetryOptions_1 = require("../../util/lockRetryOptions");
|
|
18
19
|
exports.DEFAULT_GROUP = 'orgs';
|
|
19
20
|
exports.FILENAME = 'alias.json';
|
|
20
|
-
const lockOptions = { stale: 10000 };
|
|
21
|
-
const lockRetryOptions = {
|
|
22
|
-
...lockOptions,
|
|
23
|
-
retries: { retries: 10, maxTimeout: 1000, factor: 2 },
|
|
24
|
-
};
|
|
25
21
|
class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
26
22
|
getAll(entity) {
|
|
27
23
|
// This will only return aliases under "orgs". This will need to be modified
|
|
@@ -181,7 +177,7 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
181
177
|
*/
|
|
182
178
|
async readFileToAliasStore(useLock = false) {
|
|
183
179
|
if (useLock) {
|
|
184
|
-
await (0, proper_lockfile_1.lock)(this.fileLocation, lockRetryOptions);
|
|
180
|
+
await (0, proper_lockfile_1.lock)(this.fileLocation, lockRetryOptions_1.lockRetryOptions);
|
|
185
181
|
}
|
|
186
182
|
try {
|
|
187
183
|
this.aliasStore = fileContentsRawToAliasStore(await (0, promises_1.readFile)(this.fileLocation, 'utf-8'));
|
|
@@ -208,7 +204,7 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
208
204
|
readFileToAliasStoreSync() {
|
|
209
205
|
// the file is guaranteed to exist because this init method ensures it
|
|
210
206
|
// put a lock in place. This method is only used by legacy set/unset methods.
|
|
211
|
-
(0, proper_lockfile_1.lockSync)(this.fileLocation, lockOptions);
|
|
207
|
+
(0, proper_lockfile_1.lockSync)(this.fileLocation, lockRetryOptions_1.lockOptions);
|
|
212
208
|
this.aliasStore = fileContentsRawToAliasStore((0, node_fs_1.readFileSync)(this.fileLocation, 'utf-8'));
|
|
213
209
|
}
|
|
214
210
|
/**
|
|
@@ -5,9 +5,10 @@ import { AsyncOptionalCreatable } from '@salesforce/kit';
|
|
|
5
5
|
import { AuthInfoConfig } from '../../config/authInfoConfig';
|
|
6
6
|
import { AuthFields } from '../../org';
|
|
7
7
|
import { ConfigFile } from '../../config/configFile';
|
|
8
|
-
import { ConfigContents } from '../../config/
|
|
8
|
+
import { ConfigContents } from '../../config/configStackTypes';
|
|
9
9
|
export declare abstract class BaseOrgAccessor<T extends ConfigFile, P extends ConfigContents> extends AsyncOptionalCreatable {
|
|
10
10
|
private configs;
|
|
11
|
+
/** map of Org files by username */
|
|
11
12
|
private contents;
|
|
12
13
|
private logger;
|
|
13
14
|
/**
|
package/lib/testSetup.d.ts
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import { SinonSandbox, SinonStatic, SinonStub } from 'sinon';
|
|
4
4
|
import { AnyJson, JsonMap, Optional } from '@salesforce/ts-types';
|
|
5
|
-
import { ConfigContents } from './config/
|
|
5
|
+
import { ConfigContents } from './config/configStackTypes';
|
|
6
6
|
import { Connection } from './org/connection';
|
|
7
7
|
import { Logger } from './logger/logger';
|
|
8
8
|
import { SfError } from './sfError';
|
|
9
9
|
import { CometClient, CometSubscription, Message, StreamingExtension } from './status/streamingClient';
|
|
10
10
|
import { AuthFields, SandboxFields } from './org';
|
|
11
|
+
import { uniqid } from './util/uniqid';
|
|
12
|
+
export { uniqid };
|
|
11
13
|
/**
|
|
12
14
|
* Different parts of the system that are mocked out. They can be restored for
|
|
13
15
|
* individual tests. Test's stubs should always go on the DEFAULT which is exposed
|
|
@@ -48,10 +50,6 @@ export interface ConfigStub {
|
|
|
48
50
|
* A function to conditionally read based on the config instance. The `this` value will be the config instance.
|
|
49
51
|
*/
|
|
50
52
|
retrieveContents?: () => Promise<JsonMap>;
|
|
51
|
-
/**
|
|
52
|
-
* A function to conditionally set based on the config instance. The `this` value will be the config instance.
|
|
53
|
-
*/
|
|
54
|
-
updateContents?: () => Promise<JsonMap>;
|
|
55
53
|
}
|
|
56
54
|
/**
|
|
57
55
|
* Instantiate a @salesforce/core test context.
|
|
@@ -203,20 +201,6 @@ export declare class TestContext {
|
|
|
203
201
|
setup(): void;
|
|
204
202
|
private requireSinon;
|
|
205
203
|
}
|
|
206
|
-
/**
|
|
207
|
-
* A function to generate a unique id and return it in the context of a template, if supplied.
|
|
208
|
-
*
|
|
209
|
-
* A template is a string that can contain `${%s}` to be replaced with a unique id.
|
|
210
|
-
* If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
|
|
211
|
-
*
|
|
212
|
-
* @param options an object with the following properties:
|
|
213
|
-
* - template: a template string.
|
|
214
|
-
* - length: the length of the unique id as presented in hexadecimal.
|
|
215
|
-
*/
|
|
216
|
-
export declare function uniqid(options?: {
|
|
217
|
-
template?: string;
|
|
218
|
-
length?: number;
|
|
219
|
-
}): string;
|
|
220
204
|
/**
|
|
221
205
|
* Instantiate a @salesforce/core test context. This is automatically created by `const $$ = testSetup()`
|
|
222
206
|
* but is useful if you don't want to have a global stub of @salesforce/core and you want to isolate it to
|
|
@@ -528,4 +512,3 @@ export declare class MockTestSandboxData {
|
|
|
528
512
|
*/
|
|
529
513
|
getConfig(): Promise<SandboxFields>;
|
|
530
514
|
}
|
|
531
|
-
export {};
|
package/lib/testSetup.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrowSync = exports.shouldThrow = exports.unexpectedResult = exports.restoreContext = exports.stubContext = exports.instantiateContext = exports.
|
|
3
|
+
exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCometClient = exports.StreamingMockCometSubscription = exports.StreamingMockSubscriptionCall = exports.shouldThrowSync = exports.shouldThrow = exports.unexpectedResult = exports.restoreContext = exports.stubContext = exports.instantiateContext = exports.TestContext = exports.uniqid = void 0;
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
6
|
* All rights reserved.
|
|
@@ -13,17 +13,15 @@ exports.MockTestSandboxData = exports.MockTestOrgData = exports.StreamingMockCom
|
|
|
13
13
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
14
14
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
15
15
|
const fs = require("node:fs");
|
|
16
|
-
const crypto_1 = require("crypto");
|
|
17
16
|
const events_1 = require("events");
|
|
18
17
|
const os_1 = require("os");
|
|
19
18
|
const path_1 = require("path");
|
|
20
|
-
const util = require("util");
|
|
21
19
|
const ts_sinon_1 = require("@salesforce/ts-sinon");
|
|
22
20
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
23
21
|
const configAggregator_1 = require("./config/configAggregator");
|
|
24
22
|
const configFile_1 = require("./config/configFile");
|
|
25
23
|
const connection_1 = require("./org/connection");
|
|
26
|
-
const
|
|
24
|
+
const crypto_1 = require("./crypto/crypto");
|
|
27
25
|
const logger_1 = require("./logger/logger");
|
|
28
26
|
const messages_1 = require("./messages");
|
|
29
27
|
const sfError_1 = require("./sfError");
|
|
@@ -34,6 +32,8 @@ const stateAggregator_1 = require("./stateAggregator");
|
|
|
34
32
|
const org_1 = require("./org");
|
|
35
33
|
const sandboxAccessor_1 = require("./stateAggregator/accessors/sandboxAccessor");
|
|
36
34
|
const global_1 = require("./global");
|
|
35
|
+
const uniqid_1 = require("./util/uniqid");
|
|
36
|
+
Object.defineProperty(exports, "uniqid", { enumerable: true, get: function () { return uniqid_1.uniqid; } });
|
|
37
37
|
/**
|
|
38
38
|
* Instantiate a @salesforce/core test context.
|
|
39
39
|
*/
|
|
@@ -42,7 +42,7 @@ class TestContext {
|
|
|
42
42
|
/**
|
|
43
43
|
* id A unique id for the test run.
|
|
44
44
|
*/
|
|
45
|
-
this.id = uniqid();
|
|
45
|
+
this.id = (0, uniqid_1.uniqid)();
|
|
46
46
|
/**
|
|
47
47
|
* An object used in tests that interact with config files.
|
|
48
48
|
*/
|
|
@@ -73,7 +73,7 @@ class TestContext {
|
|
|
73
73
|
* Generate unique string.
|
|
74
74
|
*/
|
|
75
75
|
uniqid() {
|
|
76
|
-
return uniqid();
|
|
76
|
+
return (0, uniqid_1.uniqid)();
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
79
|
* A function used when resolving the local path. Calls localPathResolverSync by default.
|
|
@@ -300,39 +300,17 @@ class TestContext {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
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;
|
|
325
303
|
function getTestLocalPath(uid) {
|
|
326
304
|
return (0, path_1.join)((0, os_1.tmpdir)(), uid, 'sfdx_core', 'local');
|
|
327
305
|
}
|
|
328
306
|
function getTestGlobalPath(uid) {
|
|
329
307
|
return (0, path_1.join)((0, os_1.tmpdir)(), uid, 'sfdx_core', 'global');
|
|
330
308
|
}
|
|
331
|
-
function retrieveRootPathSync(isGlobal, uid = uniqid()) {
|
|
309
|
+
function retrieveRootPathSync(isGlobal, uid = (0, uniqid_1.uniqid)()) {
|
|
332
310
|
return isGlobal ? getTestGlobalPath(uid) : getTestLocalPath(uid);
|
|
333
311
|
}
|
|
334
312
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
335
|
-
async function retrieveRootPath(isGlobal, uid = uniqid()) {
|
|
313
|
+
async function retrieveRootPath(isGlobal, uid = (0, uniqid_1.uniqid)()) {
|
|
336
314
|
return retrieveRootPathSync(isGlobal, uid);
|
|
337
315
|
}
|
|
338
316
|
function defaultFakeConnectionRequest() {
|
|
@@ -398,6 +376,7 @@ const stubContext = (testContext) => {
|
|
|
398
376
|
testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile, 'resolveRootFolderSync').callsFake((isGlobal) => testContext.rootPathRetrieverSync(isGlobal, testContext.id));
|
|
399
377
|
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.PROJECT, sfProject_1.SfProjectJson.prototype, 'doesPackageExist').callsFake(() => true);
|
|
400
378
|
const initStubForRead = (configFile) => {
|
|
379
|
+
testContext.configStubs[configFile.constructor.name] ??= {};
|
|
401
380
|
const stub = testContext.configStubs[configFile.constructor.name] ?? {};
|
|
402
381
|
// init calls read calls getPath which sets the path on the config file the first time.
|
|
403
382
|
// Since read is now stubbed, make sure to call getPath to initialize it.
|
|
@@ -408,7 +387,7 @@ const stubContext = (testContext) => {
|
|
|
408
387
|
};
|
|
409
388
|
const readSync = function (newContents) {
|
|
410
389
|
const stub = initStubForRead(this);
|
|
411
|
-
this.
|
|
390
|
+
this.setContentsFromFileContents(newContents ?? stub.contents ?? {}, BigInt(Date.now()));
|
|
412
391
|
return this.getContents();
|
|
413
392
|
};
|
|
414
393
|
const read = async function () {
|
|
@@ -427,36 +406,22 @@ const stubContext = (testContext) => {
|
|
|
427
406
|
stubs.configRead = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'read').callsFake(read);
|
|
428
407
|
// @ts-expect-error: muting exact type match for stub readSync
|
|
429
408
|
stubs.configReadSync = testContext.SANDBOXES.CONFIG.stub(configFile_1.ConfigFile.prototype, 'readSync').callsFake(readSync);
|
|
430
|
-
const writeSync = function (
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}
|
|
434
|
-
const stub = testContext.configStubs[this.constructor.name];
|
|
435
|
-
if (!stub)
|
|
436
|
-
return;
|
|
437
|
-
this.setContents(newContents ?? this.getContents());
|
|
409
|
+
const writeSync = function () {
|
|
410
|
+
testContext.configStubs[this.constructor.name] ??= {};
|
|
411
|
+
const stub = testContext.configStubs[this.constructor.name] ?? {};
|
|
438
412
|
stub.contents = this.toObject();
|
|
439
413
|
};
|
|
440
|
-
const write = async function (
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
const stub = testContext.configStubs[this.constructor.name];
|
|
445
|
-
if (!stub)
|
|
446
|
-
return;
|
|
414
|
+
const write = async function () {
|
|
415
|
+
testContext.configStubs[this.constructor.name] ??= {};
|
|
416
|
+
const stub = testContext.configStubs[this.constructor.name] ?? {};
|
|
447
417
|
if (stub.writeFn) {
|
|
448
|
-
return stub.writeFn.call(this
|
|
449
|
-
}
|
|
450
|
-
if (stub.updateContents) {
|
|
451
|
-
writeSync.call(this, await stub.updateContents.call(this));
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
writeSync.call(this);
|
|
418
|
+
return stub.writeFn.call(this);
|
|
455
419
|
}
|
|
420
|
+
writeSync.call(this);
|
|
456
421
|
};
|
|
457
422
|
stubs.configWriteSync = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'writeSync').callsFake(writeSync);
|
|
458
423
|
stubs.configWrite = (0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CONFIG, configFile_1.ConfigFile.prototype, 'write').callsFake(write);
|
|
459
|
-
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CRYPTO,
|
|
424
|
+
(0, ts_sinon_1.stubMethod)(testContext.SANDBOXES.CRYPTO, crypto_1.Crypto.prototype, 'getKeyChain').callsFake(() => Promise.resolve({
|
|
460
425
|
setPassword: () => Promise.resolve(),
|
|
461
426
|
getPassword: (data, cb) => cb(undefined, '12345678901234567890123456789012'),
|
|
462
427
|
}));
|
|
@@ -720,7 +685,7 @@ exports.StreamingMockCometClient = StreamingMockCometClient;
|
|
|
720
685
|
* ```
|
|
721
686
|
*/
|
|
722
687
|
class MockTestOrgData {
|
|
723
|
-
constructor(id = uniqid(), options) {
|
|
688
|
+
constructor(id = (0, uniqid_1.uniqid)(), options) {
|
|
724
689
|
this.testId = id;
|
|
725
690
|
this.userId = `user_id_${this.testId}`;
|
|
726
691
|
this.orgId = `${this.testId}`;
|
|
@@ -791,7 +756,7 @@ class MockTestOrgData {
|
|
|
791
756
|
* Return the auth config file contents.
|
|
792
757
|
*/
|
|
793
758
|
async getConfig() {
|
|
794
|
-
const crypto = await
|
|
759
|
+
const crypto = await crypto_1.Crypto.create();
|
|
795
760
|
const config = {};
|
|
796
761
|
config.orgId = this.orgId;
|
|
797
762
|
config.clientId = this.clientId;
|
|
@@ -816,7 +781,8 @@ class MockTestOrgData {
|
|
|
816
781
|
if (this.password) {
|
|
817
782
|
config.password = crypto.encrypt(this.password);
|
|
818
783
|
}
|
|
819
|
-
|
|
784
|
+
// remove "undefined" properties that don't exist in actual files
|
|
785
|
+
return Object.fromEntries(Object.entries(config).filter(([, v]) => v !== undefined));
|
|
820
786
|
}
|
|
821
787
|
/**
|
|
822
788
|
* Return the Connection for the org.
|
|
@@ -836,7 +802,7 @@ exports.MockTestOrgData = MockTestOrgData;
|
|
|
836
802
|
* ```
|
|
837
803
|
*/
|
|
838
804
|
class MockTestSandboxData {
|
|
839
|
-
constructor(id = uniqid(), options) {
|
|
805
|
+
constructor(id = (0, uniqid_1.uniqid)(), options) {
|
|
840
806
|
this.id = id;
|
|
841
807
|
this.sandboxOrgId = id;
|
|
842
808
|
this.prodOrgUsername = options?.prodOrgUsername ?? `admin_${id}@gb.org`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2023, 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.lockRetryOptions = exports.lockOptions = void 0;
|
|
10
|
+
// docs: https://github.com/moxystudio/node-proper-lockfile
|
|
11
|
+
exports.lockOptions = { stale: 10000 };
|
|
12
|
+
exports.lockRetryOptions = {
|
|
13
|
+
...exports.lockOptions,
|
|
14
|
+
retries: { retries: 10, maxTimeout: 1000, factor: 2 },
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=lockRetryOptions.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function to generate a unique id and return it in the context of a template, if supplied.
|
|
3
|
+
*
|
|
4
|
+
* A template is a string that can contain `${%s}` to be replaced with a unique id.
|
|
5
|
+
* If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
|
|
6
|
+
*
|
|
7
|
+
* @param options an object with the following properties:
|
|
8
|
+
* - template: a template string.
|
|
9
|
+
* - length: the length of the unique id as presented in hexadecimal.
|
|
10
|
+
*/
|
|
11
|
+
export declare function uniqid(options?: {
|
|
12
|
+
template?: string;
|
|
13
|
+
length?: number;
|
|
14
|
+
}): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.uniqid = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2023, salesforce.com, inc.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
* Licensed under the BSD 3-Clause license.
|
|
8
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
|
+
*/
|
|
10
|
+
const crypto_1 = require("crypto");
|
|
11
|
+
const util = require("util");
|
|
12
|
+
/**
|
|
13
|
+
* A function to generate a unique id and return it in the context of a template, if supplied.
|
|
14
|
+
*
|
|
15
|
+
* A template is a string that can contain `${%s}` to be replaced with a unique id.
|
|
16
|
+
* If the template contains the "%s" placeholder, it will be replaced with the unique id otherwise the id will be appended to the template.
|
|
17
|
+
*
|
|
18
|
+
* @param options an object with the following properties:
|
|
19
|
+
* - template: a template string.
|
|
20
|
+
* - length: the length of the unique id as presented in hexadecimal.
|
|
21
|
+
*/
|
|
22
|
+
function uniqid(options) {
|
|
23
|
+
const uniqueString = (0, crypto_1.randomBytes)(Math.ceil((options?.length ?? 32) / 2))
|
|
24
|
+
.toString('hex')
|
|
25
|
+
.slice(0, options?.length ?? 32);
|
|
26
|
+
if (!options?.template) {
|
|
27
|
+
return uniqueString;
|
|
28
|
+
}
|
|
29
|
+
return options.template.includes('%s')
|
|
30
|
+
? util.format(options.template, uniqueString)
|
|
31
|
+
: `${options.template}${uniqueString}`;
|
|
32
|
+
}
|
|
33
|
+
exports.uniqid = uniqid;
|
|
34
|
+
//# sourceMappingURL=uniqid.js.map
|