@salesforce/source-tracking 8.1.4 → 8.1.6
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/shared/functions.d.ts +1 -0
- package/lib/shared/functions.js +2 -1
- package/lib/shared/remote/remoteSourceTrackingService.d.ts +6 -0
- package/lib/shared/remote/remoteSourceTrackingService.js +34 -7
- package/lib/sourceTracking.d.ts +3 -1
- package/lib/sourceTracking.js +30 -3
- package/package.json +6 -6
|
@@ -41,6 +41,7 @@ export declare const getAllFiles: (sc: SourceComponent) => string[];
|
|
|
41
41
|
export declare const remoteChangeToMetadataMember: (cr: ChangeResult) => MetadataMember;
|
|
42
42
|
export declare const FileResponseSuccessToRemoteSyncInput: (fr: FileResponseSuccess) => RemoteSyncInput;
|
|
43
43
|
export declare const changeResultToMetadataComponent: (registry: RegistryAccess) => (cr: ChangeResultWithNameAndType) => MetadataComponent;
|
|
44
|
+
export declare const TYPES_WITH_SOURCEMEMBER_NAME_MISMATCH: Set<string>;
|
|
44
45
|
export declare const uniqueArrayConcat: <T>(arr1: T[] | Set<T>, arr2: T[] | Set<T>) => T[];
|
|
45
46
|
/** for web, where cwd does not existconstruct a TreeContainer with the projectPath to keep SDR MetadataResolver from trying to use cwd */
|
|
46
47
|
export declare const maybeGetTreeContainer: (projectPath: string) => TreeContainer | undefined;
|
package/lib/shared/functions.js
CHANGED
|
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.maybeGetTreeContainer = exports.uniqueArrayConcat = exports.changeResultToMetadataComponent = exports.FileResponseSuccessToRemoteSyncInput = exports.remoteChangeToMetadataMember = exports.getAllFiles = exports.sourceComponentHasFullNameAndType = exports.sourceComponentIsCustomLabel = exports.forceIgnoreDenies = exports.deleteCustomLabels = exports.ensureRelative = exports.chunkArray = exports.folderContainsPath = exports.pathIsInFolder = exports.excludeLwcLocalOnlyTest = exports.supportsPartialDelete = exports.getKeyFromObject = exports.getMetadataNameFromLegacyKey = exports.getMetadataTypeFromLegacyKey = exports.getMetadataNameFromKey = exports.getMetadataTypeFromKey = exports.getLegacyMetadataKey = exports.getMetadataKey = void 0;
|
|
21
|
+
exports.maybeGetTreeContainer = exports.uniqueArrayConcat = exports.TYPES_WITH_SOURCEMEMBER_NAME_MISMATCH = exports.changeResultToMetadataComponent = exports.FileResponseSuccessToRemoteSyncInput = exports.remoteChangeToMetadataMember = exports.getAllFiles = exports.sourceComponentHasFullNameAndType = exports.sourceComponentIsCustomLabel = exports.forceIgnoreDenies = exports.deleteCustomLabels = exports.ensureRelative = exports.chunkArray = exports.folderContainsPath = exports.pathIsInFolder = exports.excludeLwcLocalOnlyTest = exports.supportsPartialDelete = exports.getKeyFromObject = exports.getMetadataNameFromLegacyKey = exports.getMetadataTypeFromLegacyKey = exports.getMetadataNameFromKey = exports.getMetadataTypeFromKey = exports.getLegacyMetadataKey = exports.getMetadataKey = void 0;
|
|
22
22
|
const node_path_1 = require("node:path");
|
|
23
23
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
24
24
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
@@ -159,6 +159,7 @@ const changeResultToMetadataComponent = (registry) => (cr) => ({
|
|
|
159
159
|
type: registry.getTypeByName(cr.type),
|
|
160
160
|
});
|
|
161
161
|
exports.changeResultToMetadataComponent = changeResultToMetadataComponent;
|
|
162
|
+
exports.TYPES_WITH_SOURCEMEMBER_NAME_MISMATCH = new Set(['NavigationMenu', 'Audience']);
|
|
162
163
|
// TODO: use set.union when node 22 is everywhere
|
|
163
164
|
const uniqueArrayConcat = (arr1, arr2) => Array.from(new Set([...arr1, ...arr2]));
|
|
164
165
|
exports.uniqueArrayConcat = uniqueArrayConcat;
|
|
@@ -80,6 +80,12 @@ export declare class RemoteSourceTrackingService {
|
|
|
80
80
|
/** Return a tracked element as MemberRevision data.*/
|
|
81
81
|
private getSourceMember;
|
|
82
82
|
private setMemberRevision;
|
|
83
|
+
/**
|
|
84
|
+
* SourceMember can use a different name than Metadata API for some types
|
|
85
|
+
* (e.g. NavigationMenu, Audience). When the MDAPI fullName doesn't match
|
|
86
|
+
* any tracked SourceMember, search for a pending member of the same type.
|
|
87
|
+
*/
|
|
88
|
+
private findSourceMemberFallback;
|
|
83
89
|
/** O(1) decoded-key lookup via lazily-built reverse index */
|
|
84
90
|
private resolveDecodedKey;
|
|
85
91
|
}
|
|
@@ -142,15 +142,17 @@ class RemoteSourceTrackingService {
|
|
|
142
142
|
// any item in an aura/LWC bundle needs to represent the top (bundle) level and the file itself
|
|
143
143
|
// so we de-dupe via a set
|
|
144
144
|
Array.from(new Set(elements.flatMap((element) => (0, metadataKeys_1.getMetadataKeyFromFileResponse)(registry)(element)))).map((metadataKey) => {
|
|
145
|
-
const
|
|
146
|
-
|
|
145
|
+
const match = this.getSourceMember(metadataKey)
|
|
146
|
+
? { key: metadataKey, member: this.getSourceMember(metadataKey) }
|
|
147
|
+
: this.findSourceMemberFallback(metadataKey);
|
|
148
|
+
if (!match) {
|
|
147
149
|
this.logger.warn(`found no matching revision for ${metadataKey}`);
|
|
148
150
|
}
|
|
149
|
-
else if (doesNotMatchServer(
|
|
150
|
-
quietLogger(`Syncing ${
|
|
151
|
-
this.setMemberRevision(
|
|
152
|
-
...
|
|
153
|
-
lastRetrievedFromServer:
|
|
151
|
+
else if (doesNotMatchServer(match.member)) {
|
|
152
|
+
quietLogger(`Syncing ${match.key} revision from ${match.member.lastRetrievedFromServer ?? 'null'} to ${match.member.RevisionCounter}`);
|
|
153
|
+
this.setMemberRevision(match.key, {
|
|
154
|
+
...match.member,
|
|
155
|
+
lastRetrievedFromServer: match.member.RevisionCounter,
|
|
154
156
|
});
|
|
155
157
|
}
|
|
156
158
|
});
|
|
@@ -416,6 +418,31 @@ ${formatSourceMemberWarnings(outstandingSourceMembers)}`),
|
|
|
416
418
|
this.decodedKeyIndex.set(decodeURIComponent(matchingKey), matchingKey);
|
|
417
419
|
}
|
|
418
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* SourceMember can use a different name than Metadata API for some types
|
|
423
|
+
* (e.g. NavigationMenu, Audience). When the MDAPI fullName doesn't match
|
|
424
|
+
* any tracked SourceMember, search for a pending member of the same type.
|
|
425
|
+
*/
|
|
426
|
+
findSourceMemberFallback(metadataKey) {
|
|
427
|
+
const metadataType = (0, functions_1.getMetadataTypeFromKey)(metadataKey);
|
|
428
|
+
if (!functions_1.TYPES_WITH_SOURCEMEMBER_NAME_MISMATCH.has(metadataType))
|
|
429
|
+
return undefined;
|
|
430
|
+
const mdApiName = (0, functions_1.getMetadataNameFromKey)(metadataKey);
|
|
431
|
+
const matches = [];
|
|
432
|
+
for (const [key, member] of this.sourceMembers) {
|
|
433
|
+
if (member.MemberType === metadataType &&
|
|
434
|
+
doesNotMatchServer(member) &&
|
|
435
|
+
member.MemberName &&
|
|
436
|
+
mdApiName.includes(member.MemberName)) {
|
|
437
|
+
matches.push({ key, member });
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (matches.length === 1) {
|
|
441
|
+
this.logger.debug(`SourceMember name fallback: matched ${metadataKey} to ${matches[0].key}`);
|
|
442
|
+
return matches[0];
|
|
443
|
+
}
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
419
446
|
/** O(1) decoded-key lookup via lazily-built reverse index */
|
|
420
447
|
resolveDecodedKey(key) {
|
|
421
448
|
this.decodedKeyIndex ??= buildDecodedKeyIndex(this.sourceMembers);
|
package/lib/sourceTracking.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Org, SfProject } from '@salesforce/core';
|
|
2
2
|
import { AsyncCreatable } from '@salesforce/kit';
|
|
3
3
|
import { ComponentSet, SourceComponent, FileResponse, DeployResult, RetrieveResult, RegistryAccess } from '@salesforce/source-deploy-retrieve';
|
|
4
|
-
import { RemoteSyncInput, StatusOutputRow, ChangeOptions, ChangeResult, LocalUpdateOptions } from './shared/types';
|
|
4
|
+
import { RemoteSyncInput, StatusOutputRow, ChangeOptions, ChangeResult, LocalUpdateOptions, RemoteChangeElement } from './shared/types';
|
|
5
5
|
export type SourceTrackingOptions = {
|
|
6
6
|
org: Org;
|
|
7
7
|
project: SfProject;
|
|
@@ -195,4 +195,6 @@ export declare class SourceTracking extends AsyncCreatable {
|
|
|
195
195
|
private getLocalStatusRows;
|
|
196
196
|
private remoteChangesToOutputRows;
|
|
197
197
|
}
|
|
198
|
+
/** Correct SourceMember names that don't match the Metadata API fullName by matching against local files. */
|
|
199
|
+
export declare const correctSourceMemberNames: (changes: RemoteChangeElement[], packageDirPaths: string[], registry: RegistryAccess) => RemoteChangeElement[];
|
|
198
200
|
export {};
|
package/lib/sourceTracking.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SourceTracking = void 0;
|
|
36
|
+
exports.correctSourceMemberNames = exports.SourceTracking = void 0;
|
|
37
37
|
/*
|
|
38
38
|
* Copyright 2026, Salesforce, Inc.
|
|
39
39
|
*
|
|
@@ -229,10 +229,10 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
229
229
|
await this.ensureRemoteTracking();
|
|
230
230
|
const remoteChanges = await this.remoteSourceTrackingService.retrieveUpdates();
|
|
231
231
|
this.logger.debug('remoteChanges', remoteChanges);
|
|
232
|
-
const filteredChanges = remoteChanges
|
|
232
|
+
const filteredChanges = (0, exports.correctSourceMemberNames)(remoteChanges
|
|
233
233
|
.filter(remoteFilterByState[options.state])
|
|
234
234
|
// skip any remote types not in the registry. Will emit warnings
|
|
235
|
-
.filter((rce) => (0, metadataKeys_1.registrySupportsType)(this.registry)(rce.type));
|
|
235
|
+
.filter((rce) => (0, metadataKeys_1.registrySupportsType)(this.registry)(rce.type)), this.project.getPackageDirectories().map((pkgDir) => pkgDir.fullPath), this.registry);
|
|
236
236
|
if (options.format === 'ChangeResult') {
|
|
237
237
|
return filteredChanges.map((0, remoteSourceTrackingService_1.remoteChangeElementToChangeResult)(this.registry));
|
|
238
238
|
}
|
|
@@ -660,4 +660,31 @@ const localChangesToOutputRow = (logger) => (forceIgnore) => (localType) => (inp
|
|
|
660
660
|
}
|
|
661
661
|
throw new Error('no filenames found for local ChangeResult');
|
|
662
662
|
};
|
|
663
|
+
/** Correct SourceMember names that don't match the Metadata API fullName by matching against local files. */
|
|
664
|
+
const correctSourceMemberNames = (changes, packageDirPaths, registry) => {
|
|
665
|
+
const localNamesByType = new Map();
|
|
666
|
+
for (const component of source_deploy_retrieve_1.ComponentSet.fromSource({ fsPaths: packageDirPaths, registry }).getSourceComponents()) {
|
|
667
|
+
const typeName = component.type.name;
|
|
668
|
+
const existing = localNamesByType.get(typeName);
|
|
669
|
+
if (existing) {
|
|
670
|
+
existing.push(component.fullName);
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
localNamesByType.set(typeName, [component.fullName]);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return changes.map((change) => {
|
|
677
|
+
if (!functions_3.TYPES_WITH_SOURCEMEMBER_NAME_MISMATCH.has(change.type))
|
|
678
|
+
return change;
|
|
679
|
+
const localNames = localNamesByType.get(change.type);
|
|
680
|
+
if (!localNames || localNames.includes(change.name))
|
|
681
|
+
return change;
|
|
682
|
+
const matches = localNames.filter((localName) => localName.includes(change.name));
|
|
683
|
+
if (matches.length === 1) {
|
|
684
|
+
return { ...change, name: matches[0] };
|
|
685
|
+
}
|
|
686
|
+
return change;
|
|
687
|
+
});
|
|
688
|
+
};
|
|
689
|
+
exports.correctSourceMemberNames = correctSourceMemberNames;
|
|
663
690
|
//# sourceMappingURL=sourceTracking.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/source-tracking",
|
|
3
3
|
"description": "API for tracking local and remote Salesforce metadata changes",
|
|
4
|
-
"version": "8.1.
|
|
4
|
+
"version": "8.1.6",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"node": ">=22.0.0"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@salesforce/core": "^9.
|
|
53
|
+
"@salesforce/core": "^9.3.6",
|
|
54
54
|
"@salesforce/kit": "^4.0.0",
|
|
55
|
-
"@salesforce/source-deploy-retrieve": "^13.
|
|
55
|
+
"@salesforce/source-deploy-retrieve": "^13.4.6",
|
|
56
56
|
"@salesforce/ts-types": "^3.2.0",
|
|
57
|
-
"fast-xml-parser": "^5.
|
|
57
|
+
"fast-xml-parser": "^5.11.2",
|
|
58
58
|
"graceful-fs": "^4.2.11",
|
|
59
|
-
"isomorphic-git": "^1.
|
|
59
|
+
"isomorphic-git": "^1.44.2",
|
|
60
60
|
"ts-retry-promise": "^0.8.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@types/mocha": "^10.0.10",
|
|
69
69
|
"@types/node": "^18",
|
|
70
70
|
"@types/sinon": "^10.0.20",
|
|
71
|
-
"esbuild": "^0.
|
|
71
|
+
"esbuild": "^0.28.2",
|
|
72
72
|
"eslint": "^10.4.0",
|
|
73
73
|
"eslint-config-salesforce-typescript": "^7.0.0",
|
|
74
74
|
"eslint-plugin-sf-plugin": "^3.0.0",
|