@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.
@@ -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;
@@ -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 revision = this.getSourceMember(metadataKey);
146
- if (!revision) {
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(revision)) {
150
- quietLogger(`Syncing ${metadataKey} revision from ${revision.lastRetrievedFromServer ?? 'null'} to ${revision.RevisionCounter}`);
151
- this.setMemberRevision(metadataKey, {
152
- ...revision,
153
- lastRetrievedFromServer: revision.RevisionCounter,
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);
@@ -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 {};
@@ -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",
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.1.10",
53
+ "@salesforce/core": "^9.3.6",
54
54
  "@salesforce/kit": "^4.0.0",
55
- "@salesforce/source-deploy-retrieve": "^13.3.1",
55
+ "@salesforce/source-deploy-retrieve": "^13.4.6",
56
56
  "@salesforce/ts-types": "^3.2.0",
57
- "fast-xml-parser": "^5.5.7",
57
+ "fast-xml-parser": "^5.11.2",
58
58
  "graceful-fs": "^4.2.11",
59
- "isomorphic-git": "^1.34.2",
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.25.11",
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",