@salesforce/source-tracking 5.1.18 → 5.2.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.
@@ -21,7 +21,7 @@ const functions_1 = require("./functions");
21
21
  * @input excludeUnresolvable: boolean Filter out components where you can't get the name and type (that is, it's probably not a valid source component)
22
22
  * @input resolveDeleted: constructs a virtualTree instead of the actual filesystem--useful when the files no longer exist
23
23
  */
24
- const populateTypesAndNames = ({ elements, projectPath, forceIgnore, excludeUnresolvable = false, resolveDeleted = false, }) => {
24
+ const populateTypesAndNames = ({ projectPath, forceIgnore, excludeUnresolvable = false, resolveDeleted = false, registry, }) => (elements) => {
25
25
  if (elements.length === 0) {
26
26
  return [];
27
27
  }
@@ -29,7 +29,7 @@ const populateTypesAndNames = ({ elements, projectPath, forceIgnore, excludeUnre
29
29
  logger.debug(`populateTypesAndNames for ${elements.length} change elements`);
30
30
  const filenames = elements.flatMap((element) => element.filenames).filter(ts_types_1.isString);
31
31
  // component set generated from the filenames on all local changes
32
- const resolver = new source_deploy_retrieve_1.MetadataResolver(undefined, resolveDeleted ? source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(filenames) : undefined, !!forceIgnore);
32
+ const resolver = new source_deploy_retrieve_1.MetadataResolver(registry, resolveDeleted ? source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(filenames) : undefined, !!forceIgnore);
33
33
  const sourceComponents = filenames
34
34
  .flatMap((filename) => {
35
35
  try {
@@ -42,37 +42,28 @@ const populateTypesAndNames = ({ elements, projectPath, forceIgnore, excludeUnre
42
42
  })
43
43
  .filter(guards_1.sourceComponentGuard);
44
44
  logger.debug(` matching SourceComponents have ${sourceComponents.length} items from local`);
45
- // make it simpler to find things later
46
- const elementMap = new Map();
47
- elements.map((element) => {
48
- element.filenames?.map((filename) => {
49
- elementMap.set((0, functions_1.ensureRelative)(filename, projectPath), element);
50
- });
51
- });
45
+ const elementMap = new Map(elements.flatMap((e) => (e.filenames ?? []).map((f) => [(0, functions_1.ensureRelative)(projectPath)(f), e])));
52
46
  // iterates the local components and sets their filenames
53
- sourceComponents.map((matchingComponent) => {
54
- if (matchingComponent?.fullName && matchingComponent?.type.name) {
55
- const filenamesFromMatchingComponent = [matchingComponent.xml, ...matchingComponent.walkContent()];
56
- const ignored = filenamesFromMatchingComponent
57
- .filter(ts_types_1.isString)
58
- .filter((f) => !(0, functions_1.isLwcLocalOnlyTest)(f))
59
- .some((f) => forceIgnore?.denies(f));
60
- filenamesFromMatchingComponent.map((filename) => {
61
- if (filename && elementMap.has(filename)) {
62
- // add the type/name from the componentSet onto the element
63
- elementMap.set(filename, {
64
- origin: 'remote',
65
- ...elementMap.get(filename),
66
- type: matchingComponent.type.name,
67
- name: matchingComponent.fullName,
68
- ignored,
69
- });
70
- }
71
- });
72
- }
47
+ sourceComponents.filter(functions_1.sourceComponentHasFullNameAndType).map((matchingComponent) => {
48
+ const filenamesFromMatchingComponent = (0, functions_1.getAllFiles)(matchingComponent);
49
+ const ignored = filenamesFromMatchingComponent
50
+ .filter(functions_1.excludeLwcLocalOnlyTest)
51
+ .some((0, functions_1.forceIgnoreDenies)(forceIgnore));
52
+ filenamesFromMatchingComponent.map((filename) => {
53
+ if (filename && elementMap.has(filename)) {
54
+ // add the type/name from the componentSet onto the element
55
+ elementMap.set(filename, {
56
+ origin: 'remote',
57
+ ...elementMap.get(filename),
58
+ type: matchingComponent.type.name,
59
+ name: matchingComponent.fullName,
60
+ ignored,
61
+ });
62
+ }
63
+ });
73
64
  });
74
65
  return excludeUnresolvable
75
- ? Array.from(new Set(elementMap.values())).filter((changeResult) => changeResult.name && changeResult.type)
66
+ ? Array.from(new Set(elementMap.values())).filter(guards_1.isChangeResultWithNameAndType)
76
67
  : Array.from(new Set(elementMap.values()));
77
68
  };
78
69
  exports.populateTypesAndNames = populateTypesAndNames;
@@ -1,5 +1,5 @@
1
- import { ForceIgnore, MetadataComponent, MetadataMember, RegistryAccess } from '@salesforce/source-deploy-retrieve';
1
+ import { ForceIgnore, MetadataMember } from '@salesforce/source-deploy-retrieve';
2
2
  import { ChangeResult } from './types';
3
- export declare const changeResultToMetadataComponent: (cr: ChangeResult, registry?: RegistryAccess) => MetadataComponent;
3
+ import { ChangeResultWithNameAndType } from './types';
4
4
  export declare const removeIgnored: (changeResults: ChangeResult[], forceIgnore: ForceIgnore, defaultPkgDir: string) => MetadataMember[];
5
- export declare const remoteChangeToMetadataMember: (cr: ChangeResult) => MetadataMember;
5
+ export declare const ensureNameAndType: (cr: ChangeResult) => ChangeResultWithNameAndType;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.remoteChangeToMetadataMember = exports.removeIgnored = exports.changeResultToMetadataComponent = void 0;
3
+ exports.ensureNameAndType = exports.removeIgnored = void 0;
4
4
  /*
5
5
  * Copyright (c) 2023, salesforce.com, inc.
6
6
  * All rights reserved.
@@ -10,32 +10,26 @@ exports.remoteChangeToMetadataMember = exports.removeIgnored = exports.changeRes
10
10
  const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
11
11
  const core_1 = require("@salesforce/core");
12
12
  const filePathGenerator_1 = require("@salesforce/source-deploy-retrieve/lib/src/utils/filePathGenerator");
13
- const changeResultToMetadataComponent = (cr, registry = new source_deploy_retrieve_1.RegistryAccess()) => {
14
- if (!cr.name || !cr.type) {
15
- throw new core_1.SfError(`Change Result is missing name or type: ${JSON.stringify(cr)}`);
16
- }
17
- return {
18
- fullName: cr.name,
19
- type: registry.getTypeByName(cr.type),
20
- };
21
- };
22
- exports.changeResultToMetadataComponent = changeResultToMetadataComponent;
13
+ const guards_1 = require("./guards");
14
+ const functions_1 = require("./functions");
23
15
  const removeIgnored = (changeResults, forceIgnore, defaultPkgDir) => {
24
16
  const registry = new source_deploy_retrieve_1.RegistryAccess();
25
17
  return changeResults
26
- .map((cr) => (0, exports.changeResultToMetadataComponent)(cr, registry))
27
- .filter((mc) => !(0, filePathGenerator_1.filePathsFromMetadataComponent)(mc, defaultPkgDir).some((f) => forceIgnore.denies(f)))
28
- .map((mc) => ({ type: mc.type.name, fullName: mc.fullName }));
18
+ .map(exports.ensureNameAndType)
19
+ .map((0, functions_1.changeResultToMetadataComponent)(registry))
20
+ .filter((mc) => !(0, filePathGenerator_1.filePathsFromMetadataComponent)(mc, defaultPkgDir).some((0, functions_1.forceIgnoreDenies)(forceIgnore)))
21
+ .map(metadataComponentToMetadataMember);
29
22
  };
30
23
  exports.removeIgnored = removeIgnored;
31
- const remoteChangeToMetadataMember = (cr) => {
32
- if (!cr.name || !cr.type) {
33
- throw new core_1.SfError(`Change Result is missing name or type: ${JSON.stringify(cr)}`);
24
+ const metadataComponentToMetadataMember = (mc) => ({
25
+ type: mc.type.name,
26
+ fullName: mc.fullName,
27
+ });
28
+ const ensureNameAndType = (cr) => {
29
+ if ((0, guards_1.isChangeResultWithNameAndType)(cr)) {
30
+ return cr;
34
31
  }
35
- return {
36
- fullName: cr.name,
37
- type: cr.type,
38
- };
32
+ throw new core_1.SfError(`Change Result is missing name or type: ${JSON.stringify(cr)}`);
39
33
  };
40
- exports.remoteChangeToMetadataMember = remoteChangeToMetadataMember;
34
+ exports.ensureNameAndType = ensureNameAndType;
41
35
  //# sourceMappingURL=remoteChangeIgnoring.js.map
@@ -1,4 +1,4 @@
1
- import { Org, Connection } from '@salesforce/core';
1
+ import { Logger, Org, Connection } from '@salesforce/core';
2
2
  import { Duration } from '@salesforce/kit';
3
3
  import { ChangeResult, RemoteChangeElement, MemberRevision, SourceMember, RemoteSyncInput } from './types';
4
4
  /** represents the contents of the config file stored in 'maxRevision.json' */
@@ -128,6 +128,6 @@ export declare class RemoteSourceTrackingService {
128
128
  * Useful for correcing bundle types where the files show change results with types but aren't resolvable
129
129
  */
130
130
  export declare const remoteChangeElementToChangeResult: (rce: RemoteChangeElement) => ChangeResult;
131
- export declare const calculateTimeout: (memberCount: number) => Duration;
131
+ export declare const calculateTimeout: (logger: Logger) => (memberCount: number) => Duration;
132
132
  /** exported only for spy/mock */
133
133
  export declare const querySourceMembersTo: (conn: Connection, toRevision: number) => Promise<SourceMember[]>;
@@ -123,7 +123,7 @@ class RemoteSourceTrackingService {
123
123
  if (!revision) {
124
124
  this.logger.warn(`found no matching revision for ${metadataKey}`);
125
125
  }
126
- else if (revision.lastRetrievedFromServer !== revision.serverRevisionCounter) {
126
+ else if (doesNotMatchServer(revision)) {
127
127
  if (!quiet) {
128
128
  this.logger.debug(`Syncing ${metadataKey} revision from ${revision.lastRetrievedFromServer} to ${revision.serverRevisionCounter}`);
129
129
  }
@@ -171,8 +171,8 @@ class RemoteSourceTrackingService {
171
171
  // Look for any changed that haven't been synced. I.e, the lastRetrievedFromServer
172
172
  // does not match the serverRevisionCounter.
173
173
  const returnElements = Array.from(this.sourceMembers.entries())
174
- .filter(([, member]) => member.serverRevisionCounter !== member.lastRetrievedFromServer)
175
- .map(([key, member]) => convertRevisionToChange(key, member));
174
+ .filter(revisionDoesNotMatch)
175
+ .map(revisionToRemoteChangeElement);
176
176
  this.logger.debug(returnElements.length
177
177
  ? `Found ${returnElements.length} elements not synced with org`
178
178
  : 'Remote source tracking is up to date');
@@ -198,7 +198,7 @@ class RemoteSourceTrackingService {
198
198
  const originalOutstandingSize = outstandingSourceMembers.size;
199
199
  // this will be the absolute timeout from the start of the poll. We can also exit early if it doesn't look like more results are coming in
200
200
  let highestRevisionSoFar = this.serverMaxRevisionCounter;
201
- const pollingTimeout = (0, exports.calculateTimeout)(outstandingSourceMembers.size);
201
+ const pollingTimeout = (0, exports.calculateTimeout)(this.logger)(outstandingSourceMembers.size);
202
202
  let pollAttempts = 0;
203
203
  let consecutiveEmptyResults = 0;
204
204
  let someResultsReturned = false;
@@ -425,7 +425,7 @@ const remoteChangeElementToChangeResult = (rce) => ({
425
425
  origin: 'remote', // we know they're remote
426
426
  });
427
427
  exports.remoteChangeElementToChangeResult = remoteChangeElementToChangeResult;
428
- const convertRevisionToChange = (memberKey, memberRevision) => ({
428
+ const revisionToRemoteChangeElement = ([memberKey, memberRevision]) => ({
429
429
  type: memberRevision.memberType,
430
430
  name: memberKey.replace(`${memberRevision.memberType}__`, ''),
431
431
  deleted: memberRevision.isNameObsolete,
@@ -462,8 +462,7 @@ const readFileContents = async (filePath) => {
462
462
  return {};
463
463
  }
464
464
  };
465
- const calculateTimeout = (memberCount) => {
466
- const logger = core_1.Logger.childFromRoot('remoteSourceTrackingService:calculateTimeout');
465
+ const calculateTimeout = (logger) => (memberCount) => {
467
466
  const overriddenTimeout = kit_1.env.getNumber('SFDX_SOURCE_MEMBER_POLLING_TIMEOUT', 0);
468
467
  if (overriddenTimeout > 0) {
469
468
  logger.debug(`Overriding SourceMember polling timeout to ${overriddenTimeout}`);
@@ -485,10 +484,10 @@ const querySourceMembersTo = async (conn, toRevision) => {
485
484
  exports.querySourceMembersTo = querySourceMembersTo;
486
485
  const queryFn = async (conn, query) => {
487
486
  try {
488
- return (await conn.tooling.query(query, { autoFetch: true, maxFetch: 50000 })).records;
487
+ return (await conn.tooling.query(query, { autoFetch: true, maxFetch: 50_000 })).records;
489
488
  }
490
489
  catch (error) {
491
- throw core_1.SfError.wrap(error);
490
+ throw error instanceof Error ? core_1.SfError.wrap(error) : error;
492
491
  }
493
492
  };
494
493
  /** organize by type and format for warning output */
@@ -502,4 +501,6 @@ const formatSourceMemberWarnings = (outstandingSourceMembers) => {
502
501
  .map(([type, names]) => ` - ${type}: ${names.join(', ')}`)
503
502
  .join(node_os_1.EOL);
504
503
  };
504
+ const revisionDoesNotMatch = ([, member]) => doesNotMatchServer(member);
505
+ const doesNotMatchServer = (member) => member.serverRevisionCounter !== member.lastRetrievedFromServer;
505
506
  //# sourceMappingURL=remoteSourceTrackingService.js.map
@@ -61,3 +61,4 @@ export type SourceMemberPollingEvent = {
61
61
  attempts: number;
62
62
  consecutiveEmptyResults: number;
63
63
  };
64
+ export type ChangeResultWithNameAndType = ChangeResult & Required<Pick<ChangeResult, 'name' | 'type'>>;
@@ -1,6 +1,6 @@
1
1
  import { Org, SfProject } from '@salesforce/core';
2
2
  import { AsyncCreatable } from '@salesforce/kit';
3
- import { ComponentSet, SourceComponent, FileResponse, DeployResult, RetrieveResult } from '@salesforce/source-deploy-retrieve';
3
+ import { ComponentSet, SourceComponent, FileResponse, DeployResult, RetrieveResult, RegistryAccess } from '@salesforce/source-deploy-retrieve';
4
4
  import { RemoteSyncInput, StatusOutputRow, ChangeOptions, ChangeResult, LocalUpdateOptions } from './shared/types';
5
5
  export interface SourceTrackingOptions {
6
6
  org: Org;
@@ -30,9 +30,10 @@ type RemoteChangesResults = {
30
30
  *
31
31
  */
32
32
  export declare class SourceTracking extends AsyncCreatable {
33
+ readonly registry: RegistryAccess;
34
+ readonly projectPath: string;
33
35
  private org;
34
36
  private project;
35
- private projectPath;
36
37
  private packagesDirs;
37
38
  private logger;
38
39
  private localRepo;
@@ -189,8 +190,6 @@ export declare class SourceTracking extends AsyncCreatable {
189
190
  setIgnoreConflicts(value: boolean): void;
190
191
  private maybeSubscribeLifecycleEvents;
191
192
  private getLocalStatusRows;
192
- private getLocalChangesAsFilenames;
193
- private localChangesToOutputRow;
194
193
  private remoteChangesToOutputRows;
195
194
  }
196
195
  export {};
@@ -22,10 +22,12 @@ const conflicts_1 = require("./shared/conflicts");
22
22
  const guards_1 = require("./shared/guards");
23
23
  const remoteChangeIgnoring_1 = require("./shared/remoteChangeIgnoring");
24
24
  const functions_1 = require("./shared/functions");
25
+ const functions_2 = require("./shared/functions");
25
26
  const metadataKeys_1 = require("./shared/metadataKeys");
26
27
  const populateFilePaths_1 = require("./shared/populateFilePaths");
27
28
  const populateTypesAndNames_1 = require("./shared/populateTypesAndNames");
28
29
  const localComponentSetArray_1 = require("./shared/localComponentSetArray");
30
+ const functions_3 = require("./shared/functions");
29
31
  /**
30
32
  * Manages source tracking files (remote and local)
31
33
  *
@@ -44,6 +46,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
44
46
  this.ignoreConflicts = options.ignoreConflicts ?? false;
45
47
  this.ignoreLocalCache = options.ignoreLocalCache ?? false;
46
48
  this.subscribeSDREvents = options.subscribeSDREvents ?? false;
49
+ this.registry = new source_deploy_retrieve_1.RegistryAccess(undefined, this.projectPath);
47
50
  }
48
51
  async init() {
49
52
  await this.maybeSubscribeLifecycleEvents();
@@ -72,7 +75,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
72
75
  deletes,
73
76
  }, byPackageDir ?? Boolean(projectConfig.pushPackageDirectoriesSequentially)); // if the users specified true or false for the param, that overrides the project config
74
77
  this.logger.debug(`will build array of ${groupings.length} componentSet(s)`);
75
- return (0, localComponentSetArray_1.getComponentSets)(groupings, sourceApiVersion);
78
+ return (0, localComponentSetArray_1.getComponentSets)({ groupings, sourceApiVersion, registry: this.registry });
76
79
  }
77
80
  /** reads tracking files for remote changes. It DOES NOT consider the effects of .forceignore unless told to */
78
81
  async remoteNonDeletesAsComponentSet({ applyIgnore = false, } = {}) {
@@ -94,13 +97,11 @@ class SourceTracking extends kit_1.AsyncCreatable {
94
97
  }),
95
98
  this.project.resolveProjectConfig(),
96
99
  ]);
97
- const componentSet = new source_deploy_retrieve_1.ComponentSet(applyIgnore
98
- ? sourceBackedComponents.filter((sc) => ![sc.content, sc.xml].some((f) => f && this.forceIgnore.denies(f)))
99
- : sourceBackedComponents);
100
+ const componentSet = new source_deploy_retrieve_1.ComponentSet(applyIgnore ? sourceBackedComponents.filter(noFileIsIgnored(this.forceIgnore)) : sourceBackedComponents, this.registry);
100
101
  // there may be remote adds not in the SBC. So we add those manually
101
102
  (applyIgnore
102
103
  ? (0, remoteChangeIgnoring_1.removeIgnored)(changeResults, this.forceIgnore, this.project.getDefaultPackage().fullPath)
103
- : changeResults.map(remoteChangeIgnoring_1.remoteChangeToMetadataMember)).forEach((mm) => {
104
+ : changeResults.map(functions_1.remoteChangeToMetadataMember)).map((mm) => {
104
105
  componentSet.add(mm);
105
106
  });
106
107
  if (projectConfig.sourceApiVersion) {
@@ -131,10 +132,10 @@ class SourceTracking extends kit_1.AsyncCreatable {
131
132
  }
132
133
  if (local && remote) {
133
134
  // keys like ApexClass__MyClass.cls
134
- const conflictFiles = (await this.getConflicts()).flatMap((conflict) => conflict.filenames).filter(ts_types_1.isString);
135
+ const conflictFiles = new Set((await this.getConflicts()).flatMap((conflict) => conflict.filenames).filter(ts_types_1.isString));
135
136
  results = results.map((row) => ({
136
137
  ...row,
137
- conflict: !!row.filePath && conflictFiles.includes(row.filePath),
138
+ conflict: !!row.filePath && conflictFiles.has(row.filePath),
138
139
  }));
139
140
  }
140
141
  return results;
@@ -142,7 +143,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
142
143
  async getChanges(options) {
143
144
  if (options?.origin === 'local') {
144
145
  await this.ensureLocalTracking();
145
- const filenames = await this.getLocalChangesAsFilenames(options.state);
146
+ const filenames = await getLocalChangesAsFilenames(this.localRepo)(options.state);
146
147
  if (options.format === 'string') {
147
148
  return filenames;
148
149
  }
@@ -153,9 +154,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
153
154
  }));
154
155
  }
155
156
  if (options.format === 'SourceComponent') {
156
- const resolver = options.state === 'delete'
157
- ? new source_deploy_retrieve_1.MetadataResolver(undefined, source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(filenames))
158
- : new source_deploy_retrieve_1.MetadataResolver();
157
+ const resolver = new source_deploy_retrieve_1.MetadataResolver(this.registry, options.state === 'delete' ? source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(filenames) : undefined);
159
158
  return filenames
160
159
  .flatMap((filename) => {
161
160
  try {
@@ -178,25 +177,27 @@ class SourceTracking extends kit_1.AsyncCreatable {
178
177
  // skip any remote types not in the registry. Will emit warnings
179
178
  .filter((rce) => (0, metadataKeys_1.registrySupportsType)(rce.type));
180
179
  if (options.format === 'ChangeResult') {
181
- return filteredChanges.map((change) => (0, remoteSourceTrackingService_1.remoteChangeElementToChangeResult)(change));
180
+ return filteredChanges.map(remoteSourceTrackingService_1.remoteChangeElementToChangeResult);
182
181
  }
183
182
  if (options.format === 'ChangeResultWithPaths') {
184
- return (0, populateFilePaths_1.populateFilePaths)(filteredChanges.map((change) => (0, remoteSourceTrackingService_1.remoteChangeElementToChangeResult)(change)), this.project.getPackageDirectories().map((pkgDir) => pkgDir.path));
183
+ return (0, populateFilePaths_1.populateFilePaths)({
184
+ elements: filteredChanges.map(remoteSourceTrackingService_1.remoteChangeElementToChangeResult),
185
+ packageDirPaths: this.project.getPackageDirectories().map((pkgDir) => pkgDir.path),
186
+ registry: this.registry,
187
+ });
185
188
  }
186
189
  // turn it into a componentSet to resolve filenames
187
190
  const remoteChangesAsComponentSet = new source_deploy_retrieve_1.ComponentSet(filteredChanges.map((element) => ({
188
191
  type: element?.type,
189
192
  fullName: element?.name,
190
- })));
193
+ })), this.registry);
191
194
  const matchingLocalSourceComponentsSet = source_deploy_retrieve_1.ComponentSet.fromSource({
192
195
  fsPaths: this.packagesDirs.map((dir) => (0, node_path_1.resolve)(dir.fullPath)),
193
196
  include: remoteChangesAsComponentSet,
197
+ registry: this.registry,
194
198
  });
195
199
  if (options.format === 'string') {
196
- return matchingLocalSourceComponentsSet
197
- .getSourceComponents()
198
- .toArray()
199
- .flatMap((component) => [component.xml, ...component.walkContent()].filter((filename) => filename));
200
+ return matchingLocalSourceComponentsSet.getSourceComponents().toArray().flatMap(functions_2.getAllFiles);
200
201
  }
201
202
  else if (options.format === 'SourceComponent') {
202
203
  return matchingLocalSourceComponentsSet.getSourceComponents().toArray();
@@ -224,12 +225,9 @@ class SourceTracking extends kit_1.AsyncCreatable {
224
225
  if (changesToDelete.length === 0) {
225
226
  return [];
226
227
  }
227
- const sourceComponentByFileName = new Map();
228
- changesToDelete.flatMap((component) => [component.xml, ...component.walkContent()]
229
- .filter((filename) => filename)
230
- .map((filename) => sourceComponentByFileName.set(filename, component)));
228
+ const sourceComponentByFileName = new Map(changesToDelete.flatMap((component) => (0, functions_2.getAllFiles)(component).map((filename) => [filename, component])));
231
229
  // calculate what to return before we delete any files and .walkContent is no longer valid
232
- const changedToBeDeleted = changesToDelete.flatMap((component) => [...component.walkContent(), component.xml].map((file) => ({
230
+ const changedToBeDeleted = changesToDelete.flatMap((component) => (0, functions_2.getAllFiles)(component).map((file) => ({
233
231
  state: source_deploy_retrieve_1.ComponentStatus.Deleted,
234
232
  filePath: file,
235
233
  type: component.type.name,
@@ -237,14 +235,9 @@ class SourceTracking extends kit_1.AsyncCreatable {
237
235
  })));
238
236
  const filenames = Array.from(sourceComponentByFileName.keys());
239
237
  // delete the files
240
- await Promise.all(filenames.map(async (filename) => {
241
- if (sourceComponentByFileName.get(filename)?.type.id === 'customlabel') {
242
- await (0, functions_1.deleteCustomLabels)(filename, changesToDelete.filter((c) => c.type.id === 'customlabel'));
243
- }
244
- else {
245
- return fs.promises.unlink(filename);
246
- }
247
- }));
238
+ await Promise.all(filenames.map((filename) => sourceComponentByFileName.get(filename)?.type.id === 'customlabel'
239
+ ? (0, functions_2.deleteCustomLabels)(filename, changesToDelete.filter(functions_3.sourceComponentIsCustomLabel))
240
+ : fs.promises.unlink(filename)));
248
241
  // update the tracking files. We're simulating SDR-style fileResponse
249
242
  await Promise.all([
250
243
  this.updateLocalTracking({ deletedFiles: filenames }),
@@ -267,10 +260,11 @@ class SourceTracking extends kit_1.AsyncCreatable {
267
260
  const marker = core_2.Performance.mark('@salesforce/source-tracking', 'SourceTracking.updateLocalTracking');
268
261
  marker?.addDetails({ nonDeletes: options.files?.length ?? 0, deletes: options.deletedFiles?.length ?? 0 });
269
262
  await this.ensureLocalTracking();
263
+ this.logger.trace('files', options.files);
270
264
  // relative paths make smaller trees AND isogit wants them relative
271
265
  const relativeOptions = {
272
- files: (options.files ?? []).map((file) => (0, functions_1.ensureRelative)(file, this.projectPath)),
273
- deletedFiles: (options.deletedFiles ?? []).map((file) => (0, functions_1.ensureRelative)(file, this.projectPath)),
266
+ files: (options.files ?? []).map((0, functions_2.ensureRelative)(this.projectPath)),
267
+ deletedFiles: (options.deletedFiles ?? []).map((0, functions_2.ensureRelative)(this.projectPath)),
274
268
  };
275
269
  // plot twist: if you delete a member of a bundle (ex: lwc/foo/foo.css) and push, it'll not be in the fileResponses (deployedFiles) or deletedFiles
276
270
  // what got deleted? Any local changes NOT in the fileResponses but part of a successfully deployed bundle
@@ -278,16 +272,17 @@ class SourceTracking extends kit_1.AsyncCreatable {
278
272
  // resolve from highest possible level. TODO: can we use [.]
279
273
  fsPaths: relativeOptions.files.length ? [relativeOptions.files[0].split(node_path_1.sep)[0]] : [],
280
274
  tree: source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(relativeOptions.files),
275
+ registry: this.registry,
281
276
  });
282
277
  // these are top-level bundle paths like lwc/foo
283
278
  const bundlesWithDeletedFiles = (await this.getChanges({ origin: 'local', state: 'delete', format: 'SourceComponent' }))
284
- .filter(functions_1.supportsPartialDelete)
279
+ .filter(functions_2.supportsPartialDelete)
285
280
  .filter((cmp) => deployedFilesAsVirtualComponentSet.has({ type: cmp.type, fullName: cmp.fullName }))
286
281
  .map((cmp) => cmp.content)
287
282
  .filter(ts_types_1.isString);
288
283
  await this.localRepo.commitChanges({
289
284
  deployedFiles: relativeOptions.files,
290
- deletedFiles: relativeOptions.deletedFiles.concat((await this.localRepo.getDeleteFilenames()).filter((deployedFile) => bundlesWithDeletedFiles.some((bundlePath) => (0, functions_1.pathIsInFolder)(deployedFile, bundlePath)) &&
285
+ deletedFiles: relativeOptions.deletedFiles.concat((await this.localRepo.getDeleteFilenames()).filter((deployedFile) => bundlesWithDeletedFiles.some((0, functions_2.folderContainsPath)(deployedFile)) &&
291
286
  !relativeOptions.files.includes(deployedFile))),
292
287
  });
293
288
  marker?.stop();
@@ -421,6 +416,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
421
416
  remoteChanges,
422
417
  projectPath: this.projectPath,
423
418
  forceIgnore: this.forceIgnore,
419
+ registry: this.registry,
424
420
  });
425
421
  marker?.stop();
426
422
  return result;
@@ -431,23 +427,17 @@ class SourceTracking extends kit_1.AsyncCreatable {
431
427
  * @param result FileResponse[]
432
428
  */
433
429
  async updateTrackingFromDeploy(deployResult) {
434
- const successes = deployResult
435
- .getFileResponses()
436
- .filter((fileResponse) => fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Failed && fileResponse.filePath);
430
+ const successes = deployResult.getFileResponses().filter(guards_1.isSdrSuccess).filter(guards_1.FileResponseHasPath);
437
431
  if (!successes.length) {
438
432
  return;
439
433
  }
440
434
  await Promise.all([
441
435
  this.updateLocalTracking({
442
436
  // assertions allowed because filtered above
443
- files: successes
444
- .filter((fileResponse) => fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Deleted)
445
- .map((fileResponse) => fileResponse.filePath),
446
- deletedFiles: successes
447
- .filter((fileResponse) => fileResponse.state === source_deploy_retrieve_1.ComponentStatus.Deleted)
448
- .map((fileResponse) => fileResponse.filePath),
437
+ files: successes.filter(guards_1.FileResponseIsNotDeleted).map(filePathFromFileResponse),
438
+ deletedFiles: successes.filter(guards_1.FileResponseIsDeleted).map(filePathFromFileResponse),
449
439
  }),
450
- this.updateRemoteTracking(successes.map(({ state, fullName, type, filePath }) => ({ state, fullName, type, filePath }))),
440
+ this.updateRemoteTracking(successes.map(functions_1.FileResponseSuccessToRemoteSyncInput)),
451
441
  ]);
452
442
  }
453
443
  /**
@@ -456,25 +446,17 @@ class SourceTracking extends kit_1.AsyncCreatable {
456
446
  * @param result FileResponse[]
457
447
  */
458
448
  async updateTrackingFromRetrieve(retrieveResult) {
459
- const successes = retrieveResult
460
- .getFileResponses()
461
- .filter((fileResponse) => fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Failed);
449
+ const successes = retrieveResult.getFileResponses().filter(guards_1.isSdrSuccess);
462
450
  if (!successes.length) {
463
451
  return;
464
452
  }
465
453
  await Promise.all([
466
454
  this.updateLocalTracking({
467
455
  // assertion allowed because it's filtering out undefined
468
- files: successes
469
- .filter((fileResponse) => fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Deleted)
470
- .map((fileResponse) => fileResponse.filePath)
471
- .filter(Boolean),
472
- deletedFiles: successes
473
- .filter((fileResponse) => fileResponse.state === source_deploy_retrieve_1.ComponentStatus.Deleted)
474
- .map((fileResponse) => fileResponse.filePath)
475
- .filter(Boolean),
456
+ files: successes.filter(guards_1.FileResponseIsNotDeleted).filter(guards_1.FileResponseHasPath).map(filePathFromFileResponse),
457
+ deletedFiles: successes.filter(guards_1.FileResponseIsDeleted).filter(guards_1.FileResponseHasPath).map(filePathFromFileResponse),
476
458
  }),
477
- this.updateRemoteTracking(successes.map(({ state, fullName, type, filePath }) => ({ state, fullName, type, filePath })), true // retrieves don't need to poll for SourceMembers
459
+ this.updateRemoteTracking(successes.map(functions_1.FileResponseSuccessToRemoteSyncInput), true // retrieves don't need to poll for SourceMembers
478
460
  ),
479
461
  ]);
480
462
  }
@@ -526,55 +508,15 @@ class SourceTracking extends kit_1.AsyncCreatable {
526
508
  }
527
509
  async getLocalStatusRows() {
528
510
  await this.ensureLocalTracking();
529
- let results = [];
530
- const localDeletes = (0, populateTypesAndNames_1.populateTypesAndNames)({
531
- elements: await this.getChanges({ origin: 'local', state: 'delete', format: 'ChangeResult' }),
532
- excludeUnresolvable: true,
533
- resolveDeleted: true,
534
- projectPath: this.projectPath,
535
- });
536
- const localAdds = (0, populateTypesAndNames_1.populateTypesAndNames)({
537
- elements: await this.getChanges({ origin: 'local', state: 'add', format: 'ChangeResult' }),
538
- excludeUnresolvable: true,
539
- projectPath: this.projectPath,
540
- });
541
- const localModifies = (0, populateTypesAndNames_1.populateTypesAndNames)({
542
- elements: await this.getChanges({ origin: 'local', state: 'modify', format: 'ChangeResult' }),
543
- excludeUnresolvable: true,
544
- projectPath: this.projectPath,
545
- });
546
- results = results.concat(localAdds.flatMap((item) => this.localChangesToOutputRow(item, 'add')), localModifies.flatMap((item) => this.localChangesToOutputRow(item, 'modify')), localDeletes.flatMap((item) => this.localChangesToOutputRow(item, 'delete')));
547
- return results;
548
- }
549
- async getLocalChangesAsFilenames(state) {
550
- if (state === 'modify') {
551
- return this.localRepo.getModifyFilenames();
552
- }
553
- if (state === 'nondelete') {
554
- return this.localRepo.getNonDeleteFilenames();
555
- }
556
- if (state === 'delete') {
557
- return this.localRepo.getDeleteFilenames();
558
- }
559
- if (state === 'add') {
560
- return this.localRepo.getAddFilenames();
561
- }
562
- throw new Error(`unable to get local changes for state ${state}`);
563
- }
564
- localChangesToOutputRow(input, localType) {
565
- this.logger.debug('converting ChangeResult to a row', input);
566
- this.forceIgnore ??= source_deploy_retrieve_1.ForceIgnore.findAndCreate(this.project.getDefaultPackage().path);
567
- if (input.filenames) {
568
- return input.filenames.map((filename) => ({
569
- type: input.type ?? '',
570
- state: localType,
571
- fullName: input.name ?? '',
572
- filePath: filename,
573
- origin: 'local',
574
- ignored: this.forceIgnore.denies(filename),
575
- }));
576
- }
577
- throw new Error('no filenames found for local ChangeResult');
511
+ this.forceIgnore ??= source_deploy_retrieve_1.ForceIgnore.findAndCreate(this.project.getDefaultPackage().path); // ensure forceignore is initialized
512
+ const [adds, modifies, deletes] = await Promise.all(['add', 'modify', 'delete'].map((state) => this.getChanges({ origin: 'local', state, format: 'ChangeResult' })));
513
+ const base = { projectPath: this.projectPath, registry: this.registry, excludeUnresolvable: true };
514
+ const toOutput = localChangesToOutputRow(this.logger)(this.forceIgnore);
515
+ return [
516
+ ...(0, populateTypesAndNames_1.populateTypesAndNames)(base)(adds).flatMap(toOutput('add')),
517
+ ...(0, populateTypesAndNames_1.populateTypesAndNames)(base)(modifies).flatMap(toOutput('modify')),
518
+ ...(0, populateTypesAndNames_1.populateTypesAndNames)({ ...base, resolveDeleted: true })(deletes).flatMap(toOutput('delete')),
519
+ ];
578
520
  }
579
521
  // reserve the right to do something more sophisticated in the future
580
522
  // via async for figuring out hypothetical filenames (ex: getting default packageDir)
@@ -598,14 +540,12 @@ class SourceTracking extends kit_1.AsyncCreatable {
598
540
  }
599
541
  // when the file doesn't exist locally, there are no filePaths
600
542
  // SDR can generate the hypothetical place it *would* go and check that
601
- if (input.name && input.type) {
543
+ if ((0, guards_1.isChangeResultWithNameAndType)(input)) {
544
+ const ignored = (0, filePathGenerator_1.filePathsFromMetadataComponent)((0, functions_1.changeResultToMetadataComponent)(registry)(input)).some((0, functions_2.forceIgnoreDenies)(this.forceIgnore));
602
545
  return [
603
546
  {
604
547
  ...baseObject,
605
- ignored: (0, filePathGenerator_1.filePathsFromMetadataComponent)({
606
- fullName: input.name,
607
- type: registry.getTypeByName(input.type),
608
- }).some((hypotheticalFilePath) => this.forceIgnore.denies(hypotheticalFilePath)),
548
+ ignored,
609
549
  },
610
550
  ];
611
551
  }
@@ -628,4 +568,32 @@ const stateFromChangeResult = (input) => {
628
568
  }
629
569
  return 'add';
630
570
  };
571
+ const getLocalChangesAsFilenames = (localRepo) => async (state) => {
572
+ switch (state) {
573
+ case 'modify':
574
+ return localRepo.getModifyFilenames();
575
+ case 'nondelete':
576
+ return localRepo.getNonDeleteFilenames();
577
+ case 'delete':
578
+ return localRepo.getDeleteFilenames();
579
+ case 'add':
580
+ return localRepo.getAddFilenames();
581
+ }
582
+ };
583
+ const filePathFromFileResponse = (input) => input.filePath;
584
+ const noFileIsIgnored = (forceIgnore) => (cmp) => !(0, functions_2.getAllFiles)(cmp).some((0, functions_2.forceIgnoreDenies)(forceIgnore));
585
+ const localChangesToOutputRow = (logger) => (forceIgnore) => (localType) => (input) => {
586
+ logger.debug('converting ChangeResult to a row', input);
587
+ if (input.filenames) {
588
+ return input.filenames.map((filename) => ({
589
+ type: input.type ?? '',
590
+ state: localType,
591
+ fullName: input.name ?? '',
592
+ filePath: filename,
593
+ origin: 'local',
594
+ ignored: forceIgnore.denies(filename),
595
+ }));
596
+ }
597
+ throw new Error('no filenames found for local ChangeResult');
598
+ };
631
599
  //# sourceMappingURL=sourceTracking.js.map