@salesforce/core 8.11.3 → 8.12.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.
- package/lib/config/configFile.js +6 -2
- package/lib/crypto/keyChain.js +4 -0
- package/lib/global.d.ts +4 -0
- package/lib/global.js +6 -0
- package/lib/logger/logger.js +2 -2
- package/lib/messages.js +1 -1
- package/lib/org/scratchOrgSettingsGenerator.js +7 -3
- package/lib/stateAggregator/accessors/aliasAccessor.d.ts +0 -1
- package/lib/stateAggregator/accessors/aliasAccessor.js +16 -36
- package/lib/status/myDomainResolver.d.ts +1 -0
- package/lib/status/myDomainResolver.js +6 -0
- package/lib/util/fileLocking.js +3 -4
- package/lib/util/lockRetryOptions.d.ts +2 -0
- package/lib/util/lockRetryOptions.js +5 -0
- package/lib/util/time.d.ts +1 -0
- package/lib/util/time.js +2 -2
- package/package.json +2 -2
package/lib/config/configFile.js
CHANGED
|
@@ -247,7 +247,7 @@ class ConfigFile extends configStore_1.BaseConfigStore {
|
|
|
247
247
|
const lockResponse = await (0, fileLocking_1.lockInit)(this.getPath());
|
|
248
248
|
// lock the file. Returns an unlock function to call when done.
|
|
249
249
|
try {
|
|
250
|
-
const fileTimestamp =
|
|
250
|
+
const fileTimestamp = await getNsTimeStamp(this.getPath());
|
|
251
251
|
const fileContents = (0, kit_1.parseJsonMap)(await fs.promises.readFile(this.getPath(), 'utf8'), this.getPath());
|
|
252
252
|
this.logAndMergeContents(fileTimestamp, fileContents);
|
|
253
253
|
}
|
|
@@ -268,7 +268,7 @@ class ConfigFile extends configStore_1.BaseConfigStore {
|
|
|
268
268
|
const lockResponse = (0, fileLocking_1.lockInitSync)(this.getPath());
|
|
269
269
|
try {
|
|
270
270
|
// get the file modstamp. Do this after the lock acquisition in case the file is being written to.
|
|
271
|
-
const fileTimestamp =
|
|
271
|
+
const fileTimestamp = getNsTimeStampSync(this.getPath());
|
|
272
272
|
const fileContents = (0, kit_1.parseJsonMap)(fs.readFileSync(this.getPath(), 'utf8'), this.getPath());
|
|
273
273
|
this.logAndMergeContents(fileTimestamp, fileContents);
|
|
274
274
|
}
|
|
@@ -394,4 +394,8 @@ class ConfigFile extends configStore_1.BaseConfigStore {
|
|
|
394
394
|
}
|
|
395
395
|
}
|
|
396
396
|
exports.ConfigFile = ConfigFile;
|
|
397
|
+
const getNsTimeStamp = async (filePath) => getNsTimeStampFromStatus(await fs.promises.stat(filePath, { bigint: true }));
|
|
398
|
+
const getNsTimeStampSync = (filePath) => getNsTimeStampFromStatus(fs.statSync(filePath, { bigint: true }));
|
|
399
|
+
/** in browser environment, memfs is missing the bigInt ns timestamp, so we generate it from the ms */
|
|
400
|
+
const getNsTimeStampFromStatus = (stats) => stats.mtimeNs ?? BigInt(stats.mtimeMs) * BigInt(1_000_000);
|
|
397
401
|
//# sourceMappingURL=configFile.js.map
|
package/lib/crypto/keyChain.js
CHANGED
|
@@ -58,6 +58,10 @@ const retrieveKeychain = async (platform) => {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
+
else if (platform === 'browser') {
|
|
62
|
+
logger.debug(`platform: ${platform}. Using generic keychain.`);
|
|
63
|
+
return keyChainImpl_1.keyChainImpl.generic_unix;
|
|
64
|
+
}
|
|
61
65
|
else {
|
|
62
66
|
throw messages.createError('unsupportedOperatingSystemError', [platform]);
|
|
63
67
|
}
|
package/lib/global.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export declare class Global {
|
|
|
32
32
|
* The preferred global folder in which state is stored.
|
|
33
33
|
*/
|
|
34
34
|
static readonly STATE_FOLDER = ".sfdx";
|
|
35
|
+
/**
|
|
36
|
+
* Whether the code is running in a web browser.
|
|
37
|
+
*/
|
|
38
|
+
static get isWeb(): boolean;
|
|
35
39
|
/**
|
|
36
40
|
* The full system path to the global sfdx state folder.
|
|
37
41
|
*
|
package/lib/global.js
CHANGED
|
@@ -70,6 +70,12 @@ class Global {
|
|
|
70
70
|
* The preferred global folder in which state is stored.
|
|
71
71
|
*/
|
|
72
72
|
static STATE_FOLDER = Global.SFDX_STATE_FOLDER;
|
|
73
|
+
/**
|
|
74
|
+
* Whether the code is running in a web browser.
|
|
75
|
+
*/
|
|
76
|
+
static get isWeb() {
|
|
77
|
+
return 'window' in globalThis;
|
|
78
|
+
}
|
|
73
79
|
/**
|
|
74
80
|
* The full system path to the global sfdx state folder.
|
|
75
81
|
*
|
package/lib/logger/logger.js
CHANGED
|
@@ -233,7 +233,7 @@ class Logger {
|
|
|
233
233
|
* Gets the name of this logger.
|
|
234
234
|
*/
|
|
235
235
|
getName() {
|
|
236
|
-
return this.pinoLogger.bindings().name ?? '';
|
|
236
|
+
return (this.pinoLogger?.bindings ? this.pinoLogger.bindings().name : '') ?? '';
|
|
237
237
|
}
|
|
238
238
|
/**
|
|
239
239
|
* Gets the current level of this logger.
|
|
@@ -409,7 +409,7 @@ const getWriteStream = (level = 'warn') => {
|
|
|
409
409
|
// write to a rotating file
|
|
410
410
|
target: 'pino/file',
|
|
411
411
|
options: {
|
|
412
|
-
destination: path.join(global_1.Global.SF_DIR, `sf-${rotator.get(logRotationPeriod) ?? rotator.get('1d')}.log`),
|
|
412
|
+
destination: path.join(global_1.Global.SF_DIR, `sf-${(0, ts_types_1.ensureString)(rotator.get(logRotationPeriod)) ?? rotator.get('1d')}.log`),
|
|
413
413
|
mkdir: true,
|
|
414
414
|
level,
|
|
415
415
|
},
|
package/lib/messages.js
CHANGED
|
@@ -538,7 +538,7 @@ class Messages {
|
|
|
538
538
|
tokenCur += tokenCount;
|
|
539
539
|
return util.format(msgStr, ...relevantTokens);
|
|
540
540
|
}
|
|
541
|
-
else {
|
|
541
|
+
else if (tokens.length > 0) {
|
|
542
542
|
const logger = logger_1.Logger.childFromRoot('core:messages');
|
|
543
543
|
logger.warn(`Unable to render tokens in message. Ensure a specifier (e.g. %s) exists in the message:\n${msgStr}`);
|
|
544
544
|
}
|
|
@@ -41,6 +41,7 @@ const zipWriter_1 = require("../util/zipWriter");
|
|
|
41
41
|
const directoryWriter_1 = require("../util/directoryWriter");
|
|
42
42
|
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
43
43
|
const messages_1 = require("../messages");
|
|
44
|
+
const configAggregator_1 = require("../config/configAggregator");
|
|
44
45
|
;
|
|
45
46
|
var RequestStatus;
|
|
46
47
|
(function (RequestStatus) {
|
|
@@ -233,9 +234,12 @@ class SettingsGenerator {
|
|
|
233
234
|
const connection = scratchOrg.getConnection();
|
|
234
235
|
logger.debug(`deploying to apiVersion: ${apiVersion}`);
|
|
235
236
|
connection.setApiVersion(apiVersion);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
// Get org-metadata-rest-deploy from config aggregator
|
|
238
|
+
const restDeploy = (await configAggregator_1.ConfigAggregator.create()).getPropertyValue('org-metadata-rest-deploy');
|
|
239
|
+
logger.debug(`Deploying settings to scratch org using ${restDeploy ? 'REST' : 'SOAP'} API`);
|
|
240
|
+
const { id } = await connection.deploy(this.writer.buffer, { rest: restDeploy });
|
|
241
|
+
logger.debug(`Settings deploy id: ${id}`);
|
|
242
|
+
let result = await connection.metadata.checkDeployStatus(id, undefined, restDeploy);
|
|
239
243
|
const pollingOptions = {
|
|
240
244
|
async poll() {
|
|
241
245
|
try {
|
|
@@ -10,11 +10,10 @@ exports.getFileLocation = exports.AliasAccessor = exports.FILENAME = exports.DEF
|
|
|
10
10
|
const node_path_1 = require("node:path");
|
|
11
11
|
const node_os_1 = require("node:os");
|
|
12
12
|
const promises_1 = require("node:fs/promises");
|
|
13
|
-
const proper_lockfile_1 = require("proper-lockfile");
|
|
14
13
|
const kit_1 = require("@salesforce/kit");
|
|
15
14
|
const global_1 = require("../../global");
|
|
16
15
|
const sfError_1 = require("../../sfError");
|
|
17
|
-
const
|
|
16
|
+
const fileLocking_1 = require("../../util/fileLocking");
|
|
18
17
|
exports.DEFAULT_GROUP = 'orgs';
|
|
19
18
|
exports.FILENAME = 'alias.json';
|
|
20
19
|
class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
@@ -94,18 +93,20 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
94
93
|
*/
|
|
95
94
|
async setAndSave(alias, entity) {
|
|
96
95
|
// get a very fresh copy to merge with to avoid conflicts, then lock
|
|
97
|
-
await this.
|
|
96
|
+
const lockResponse = await (0, fileLocking_1.lockInit)(this.fileLocation);
|
|
97
|
+
await this.readFileToAliasStore();
|
|
98
98
|
this.aliasStore.set(alias, getNameOf(entity));
|
|
99
|
-
return this.
|
|
99
|
+
return lockResponse.writeAndUnlock(aliasStoreToRawFileContents(this.aliasStore));
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
102
|
* Unset the given alias(es). Writes to the file
|
|
103
103
|
*
|
|
104
104
|
*/
|
|
105
105
|
async unsetAndSave(alias) {
|
|
106
|
-
await this.
|
|
106
|
+
const lockResponse = await (0, fileLocking_1.lockInit)(this.fileLocation);
|
|
107
|
+
await this.readFileToAliasStore();
|
|
107
108
|
this.aliasStore.delete(alias);
|
|
108
|
-
return this.
|
|
109
|
+
return lockResponse.writeAndUnlock(aliasStoreToRawFileContents(this.aliasStore));
|
|
109
110
|
}
|
|
110
111
|
/**
|
|
111
112
|
* Unset all the aliases for the given array of entity.
|
|
@@ -113,11 +114,12 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
113
114
|
* @param entity the aliasable entity for which you want to unset all aliases
|
|
114
115
|
*/
|
|
115
116
|
async unsetValuesAndSave(aliasees) {
|
|
116
|
-
await this.
|
|
117
|
+
const lockResponse = await (0, fileLocking_1.lockInit)(this.fileLocation);
|
|
118
|
+
await this.readFileToAliasStore();
|
|
117
119
|
(0, kit_1.ensureArray)(aliasees)
|
|
118
120
|
.flatMap((a) => this.getAll(a))
|
|
119
121
|
.map((a) => this.aliasStore.delete(a));
|
|
120
|
-
return this.
|
|
122
|
+
return lockResponse.writeAndUnlock(aliasStoreToRawFileContents(this.aliasStore));
|
|
121
123
|
}
|
|
122
124
|
/**
|
|
123
125
|
* Returns true if the provided alias exists
|
|
@@ -135,29 +137,19 @@ class AliasAccessor extends kit_1.AsyncOptionalCreatable {
|
|
|
135
137
|
* go to the fileSystem and read the file, storing a copy in the class's store
|
|
136
138
|
* if the file doesn't exist, create it empty
|
|
137
139
|
*/
|
|
138
|
-
async readFileToAliasStore(
|
|
139
|
-
if (useLock) {
|
|
140
|
-
await (0, proper_lockfile_1.lock)(this.fileLocation, lockRetryOptions_1.lockRetryOptions);
|
|
141
|
-
}
|
|
140
|
+
async readFileToAliasStore() {
|
|
142
141
|
try {
|
|
143
142
|
this.aliasStore = fileContentsRawToAliasStore(await (0, promises_1.readFile)(this.fileLocation, 'utf-8'));
|
|
144
143
|
}
|
|
145
144
|
catch (e) {
|
|
146
145
|
if (e instanceof Error && 'code' in e && typeof e.code === 'string' && ['ENOENT', 'ENOTDIR'].includes(e.code)) {
|
|
147
|
-
this.aliasStore = new Map();
|
|
148
146
|
await (0, promises_1.mkdir)((0, node_path_1.dirname)(this.fileLocation), { recursive: true });
|
|
149
|
-
|
|
150
|
-
return;
|
|
147
|
+
this.aliasStore = new Map();
|
|
148
|
+
return (0, promises_1.writeFile)(this.fileLocation, aliasStoreToRawFileContents(this.aliasStore));
|
|
151
149
|
}
|
|
152
|
-
if (useLock)
|
|
153
|
-
return unlockIfLocked(this.fileLocation);
|
|
154
150
|
throw e;
|
|
155
151
|
}
|
|
156
152
|
}
|
|
157
|
-
async saveAliasStoreToFile() {
|
|
158
|
-
await (0, promises_1.writeFile)(this.fileLocation, aliasStoreToRawFileContents(this.aliasStore));
|
|
159
|
-
return unlockIfLocked(this.fileLocation);
|
|
160
|
-
}
|
|
161
153
|
}
|
|
162
154
|
exports.AliasAccessor = AliasAccessor;
|
|
163
155
|
/**
|
|
@@ -166,11 +158,11 @@ exports.AliasAccessor = AliasAccessor;
|
|
|
166
158
|
const getNameOf = (entity) => {
|
|
167
159
|
if (typeof entity === 'string')
|
|
168
160
|
return entity;
|
|
169
|
-
const
|
|
170
|
-
if (!
|
|
161
|
+
const { username } = entity;
|
|
162
|
+
if (!username) {
|
|
171
163
|
throw new sfError_1.SfError(`Invalid aliasee, it must contain a user or username property: ${JSON.stringify(entity)}`);
|
|
172
164
|
}
|
|
173
|
-
return
|
|
165
|
+
return username;
|
|
174
166
|
};
|
|
175
167
|
const fileContentsRawToAliasStore = (contents) => {
|
|
176
168
|
const fileContents = JSON.parse(contents);
|
|
@@ -181,16 +173,4 @@ const aliasStoreToRawFileContents = (aliasStore) => JSON.stringify({ [exports.DE
|
|
|
181
173
|
// exported for testSetup mocking
|
|
182
174
|
const getFileLocation = () => (0, node_path_1.join)((0, node_os_1.homedir)(), global_1.Global.SFDX_STATE_FOLDER, exports.FILENAME);
|
|
183
175
|
exports.getFileLocation = getFileLocation;
|
|
184
|
-
const unlockIfLocked = async (fileLocation) => {
|
|
185
|
-
try {
|
|
186
|
-
await (0, proper_lockfile_1.unlock)(fileLocation);
|
|
187
|
-
}
|
|
188
|
-
catch (e) {
|
|
189
|
-
// ignore the error. If it wasn't locked, that's what we wanted
|
|
190
|
-
if (errorIsNotAcquired(e))
|
|
191
|
-
return;
|
|
192
|
-
throw e;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
const errorIsNotAcquired = (e) => e instanceof Error && 'code' in e && e.code === 'ENOTACQUIRED';
|
|
196
176
|
//# sourceMappingURL=aliasAccessor.js.map
|
|
@@ -38,6 +38,7 @@ export declare class MyDomainResolver extends AsyncOptionalCreatable<MyDomainRes
|
|
|
38
38
|
* executing the dns loookup.
|
|
39
39
|
*/
|
|
40
40
|
resolve(): Promise<string>;
|
|
41
|
+
/** @deprecated there is nothing using this in forcedotcom, salesforcecli, or public github search */
|
|
41
42
|
getCnames(): Promise<string[]>;
|
|
42
43
|
/**
|
|
43
44
|
* Used to initialize asynchronous components.
|
|
@@ -14,6 +14,7 @@ const ts_types_1 = require("@salesforce/ts-types");
|
|
|
14
14
|
const kit_1 = require("@salesforce/kit");
|
|
15
15
|
const logger_1 = require("../logger/logger");
|
|
16
16
|
const sfdcUrl_1 = require("../util/sfdcUrl");
|
|
17
|
+
const global_1 = require("../global");
|
|
17
18
|
const pollingClient_1 = require("./pollingClient");
|
|
18
19
|
// Timeout for DNS lookup polling defaults to 3 seconds and should always be at least 3 seconds
|
|
19
20
|
const DNS_TIMEOUT = Math.max(3, new kit_1.Env().getNumber('SFDX_DNS_TIMEOUT', 3));
|
|
@@ -69,6 +70,10 @@ class MyDomainResolver extends kit_1.AsyncOptionalCreatable {
|
|
|
69
70
|
this.logger.debug('SF_DISABLE_DNS_CHECK set to true. Skipping DNS check...');
|
|
70
71
|
return this.options.url.host;
|
|
71
72
|
}
|
|
73
|
+
if (global_1.Global.isWeb) {
|
|
74
|
+
this.logger.debug('Web browser detected. Skipping DNS check...');
|
|
75
|
+
return this.options.url.host;
|
|
76
|
+
}
|
|
72
77
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
73
78
|
const self = this;
|
|
74
79
|
const pollingOptions = {
|
|
@@ -106,6 +111,7 @@ class MyDomainResolver extends kit_1.AsyncOptionalCreatable {
|
|
|
106
111
|
const client = await pollingClient_1.PollingClient.create(pollingOptions);
|
|
107
112
|
return (0, ts_types_1.ensureString)(await client.subscribe());
|
|
108
113
|
}
|
|
114
|
+
/** @deprecated there is nothing using this in forcedotcom, salesforcecli, or public github search */
|
|
109
115
|
async getCnames() {
|
|
110
116
|
try {
|
|
111
117
|
await this.resolve();
|
package/lib/util/fileLocking.js
CHANGED
|
@@ -55,11 +55,10 @@ const lockInit = async (filePath) => {
|
|
|
55
55
|
catch (err) {
|
|
56
56
|
throw sfError_1.SfError.wrap(err);
|
|
57
57
|
}
|
|
58
|
-
const unlock = await (0, proper_lockfile_1.lock)(filePath, { ...lockRetryOptions_1.lockRetryOptions, realpath: false });
|
|
58
|
+
const unlock = await (0, proper_lockfile_1.lock)(filePath, { ...lockRetryOptions_1.lockRetryOptions, realpath: false, fs });
|
|
59
59
|
return {
|
|
60
60
|
writeAndUnlock: async (data) => {
|
|
61
|
-
|
|
62
|
-
logger.debug(`Writing to file: ${filePath}`);
|
|
61
|
+
(await logger_1.Logger.child('fileLocking.writeAndUnlock')).debug(`Writing to file: ${filePath}`);
|
|
63
62
|
try {
|
|
64
63
|
await fs.promises.writeFile(filePath, data);
|
|
65
64
|
}
|
|
@@ -83,7 +82,7 @@ const lockInitSync = (filePath) => {
|
|
|
83
82
|
catch (err) {
|
|
84
83
|
throw sfError_1.SfError.wrap(err);
|
|
85
84
|
}
|
|
86
|
-
const unlock = (0, proper_lockfile_1.lockSync)(filePath, { ...lockRetryOptions_1.lockOptions, realpath: false });
|
|
85
|
+
const unlock = (0, proper_lockfile_1.lockSync)(filePath, { ...lockRetryOptions_1.lockOptions, realpath: false, fs });
|
|
87
86
|
return {
|
|
88
87
|
writeAndUnlock: (data) => {
|
|
89
88
|
const logger = logger_1.Logger.childFromRoot('fileLocking.writeAndUnlock');
|
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
* Licensed under the BSD 3-Clause license.
|
|
6
6
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
7
|
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
8
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
12
|
exports.lockRetryOptions = exports.lockOptions = void 0;
|
|
10
13
|
// docs: https://github.com/moxystudio/node-proper-lockfile
|
|
14
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
15
|
exports.lockOptions = { stale: 10_000 };
|
|
12
16
|
exports.lockRetryOptions = {
|
|
13
17
|
...exports.lockOptions,
|
|
14
18
|
retries: { retries: 10, maxTimeout: 1000, factor: 2 },
|
|
19
|
+
fs: node_fs_1.default, // lockfile supports injectable fs, which is needed for browser use
|
|
15
20
|
};
|
|
16
21
|
//# sourceMappingURL=lockRetryOptions.js.map
|
package/lib/util/time.d.ts
CHANGED
package/lib/util/time.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.nowBigInt = void 0;
|
|
|
7
7
|
* Licensed under the BSD 3-Clause license.
|
|
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
|
-
|
|
11
|
-
const nowBigInt = () => BigInt((
|
|
10
|
+
/** using globalThis.performance instead importing from node:perf_hooks so it works in browser */
|
|
11
|
+
const nowBigInt = () => BigInt((globalThis.performance.now() + globalThis.performance.timeOrigin) * 1_000_000);
|
|
12
12
|
exports.nowBigInt = nowBigInt;
|
|
13
13
|
//# sourceMappingURL=time.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/core",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.12.0",
|
|
4
4
|
"description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@salesforce/ts-sinon": "^1.4.30",
|
|
78
78
|
"@types/benchmark": "^2.1.5",
|
|
79
79
|
"@types/fast-levenshtein": "^0.0.4",
|
|
80
|
-
"@types/jsonwebtoken": "9.0.
|
|
80
|
+
"@types/jsonwebtoken": "9.0.9",
|
|
81
81
|
"@types/proper-lockfile": "^4.1.4",
|
|
82
82
|
"@types/semver": "^7.5.8",
|
|
83
83
|
"benchmark": "^2.1.4",
|