@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.
package/lib/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from './sourceTracking';
1
+ export { SourceTracking, SourceTrackingOptions } from './sourceTracking';
2
2
  export { RemoteSyncInput, ChangeOptionType, ChangeOptions, LocalUpdateOptions, ChangeResult, StatusOutputRow, ConflictResponse, SourceConflictError, SourceMemberPollingEvent, } from './shared/types';
3
3
  export { getKeyFromObject, deleteCustomLabels } from './shared/functions';
package/lib/index.js CHANGED
@@ -5,23 +5,10 @@
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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
- if (k2 === undefined) k2 = k;
10
- var desc = Object.getOwnPropertyDescriptor(m, k);
11
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
- desc = { enumerable: true, get: function() { return m[k]; } };
13
- }
14
- Object.defineProperty(o, k2, desc);
15
- }) : (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- o[k2] = m[k];
18
- }));
19
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
- };
22
8
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.deleteCustomLabels = exports.getKeyFromObject = exports.SourceConflictError = void 0;
24
- __exportStar(require("./sourceTracking"), exports);
9
+ exports.deleteCustomLabels = exports.getKeyFromObject = exports.SourceConflictError = exports.SourceTracking = void 0;
10
+ var sourceTracking_1 = require("./sourceTracking");
11
+ Object.defineProperty(exports, "SourceTracking", { enumerable: true, get: function () { return sourceTracking_1.SourceTracking; } });
25
12
  var types_1 = require("./shared/types");
26
13
  Object.defineProperty(exports, "SourceConflictError", { enumerable: true, get: function () { return types_1.SourceConflictError; } });
27
14
  var functions_1 = require("./shared/functions");
@@ -1,4 +1,4 @@
1
- import { ComponentSet, ForceIgnore } from '@salesforce/source-deploy-retrieve';
1
+ import { ComponentSet, ForceIgnore, RegistryAccess } from '@salesforce/source-deploy-retrieve';
2
2
  import { ConflictResponse, ChangeResult } from './types';
3
3
  export declare const throwIfConflicts: (conflicts: ConflictResponse[]) => void;
4
4
  /**
@@ -8,9 +8,10 @@ export declare const throwIfConflicts: (conflicts: ConflictResponse[]) => void;
8
8
  * @returns ConflictResponse[] de-duped and formatted for json or table display
9
9
  */
10
10
  export declare const findConflictsInComponentSet: (cs: ComponentSet, conflicts: ChangeResult[]) => ConflictResponse[];
11
- export declare const getDedupedConflictsFromChanges: ({ localChanges, remoteChanges, projectPath, forceIgnore, }: {
11
+ export declare const getDedupedConflictsFromChanges: ({ localChanges, remoteChanges, projectPath, forceIgnore, registry, }: {
12
12
  localChanges: ChangeResult[];
13
13
  remoteChanges: ChangeResult[];
14
14
  projectPath: string;
15
15
  forceIgnore: ForceIgnore;
16
+ registry: RegistryAccess;
16
17
  }) => ChangeResult[];
@@ -11,6 +11,7 @@ const node_path_1 = require("node:path");
11
11
  const types_1 = require("./types");
12
12
  const functions_1 = require("./functions");
13
13
  const populateTypesAndNames_1 = require("./populateTypesAndNames");
14
+ const guards_1 = require("./guards");
14
15
  const throwIfConflicts = (conflicts) => {
15
16
  if (conflicts.length > 0) {
16
17
  throw new types_1.SourceConflictError(`${conflicts.length} conflicts detected`, conflicts);
@@ -27,13 +28,12 @@ const findConflictsInComponentSet = (cs, conflicts) => {
27
28
  // map do dedupe by name-type-filename
28
29
  const conflictMap = new Map();
29
30
  conflicts
30
- .filter((cr) => cr.name && cr.type && cs.has({ fullName: cr.name, type: cr.type }))
31
+ .filter(guards_1.isChangeResultWithNameAndType)
32
+ .filter((cr) => cs.has({ fullName: cr.name, type: cr.type }))
31
33
  .forEach((cr) => {
32
34
  cr.filenames?.forEach((f) => {
33
35
  conflictMap.set(`${cr.name}#${cr.type}#${f}`, {
34
36
  state: 'Conflict',
35
- // the following 2 type assertions are valid because of previous filter statement
36
- // they can be removed once TS is smarter about filtering
37
37
  fullName: cr.name,
38
38
  type: cr.type,
39
39
  filePath: (0, node_path_1.resolve)(f),
@@ -44,36 +44,23 @@ const findConflictsInComponentSet = (cs, conflicts) => {
44
44
  return reformattedConflicts;
45
45
  };
46
46
  exports.findConflictsInComponentSet = findConflictsInComponentSet;
47
- const getDedupedConflictsFromChanges = ({ localChanges = [], remoteChanges = [], projectPath, forceIgnore, }) => {
48
- // index the remoteChanges by filename
49
- const fileNameIndex = new Map();
50
- const metadataKeyIndex = new Map();
51
- remoteChanges.map((change) => {
52
- if (change.name && change.type) {
53
- metadataKeyIndex.set((0, functions_1.getMetadataKey)(change.name, change.type), change);
54
- }
55
- change.filenames?.map((filename) => {
56
- fileNameIndex.set(filename, change);
57
- });
58
- });
59
- const conflicts = new Set();
60
- (0, populateTypesAndNames_1.populateTypesAndNames)({ elements: localChanges, excludeUnresolvable: true, projectPath, forceIgnore }).map((change) => {
47
+ const getDedupedConflictsFromChanges = ({ localChanges = [], remoteChanges = [], projectPath, forceIgnore, registry, }) => {
48
+ const metadataKeyIndex = new Map(remoteChanges
49
+ .filter(guards_1.isChangeResultWithNameAndType)
50
+ .map((change) => [(0, functions_1.getMetadataKey)(change.name, change.type), change]));
51
+ const fileNameIndex = new Map(remoteChanges.flatMap((change) => (change.filenames ?? []).map((filename) => [filename, change])));
52
+ return (0, populateTypesAndNames_1.populateTypesAndNames)({ excludeUnresolvable: true, projectPath, forceIgnore, registry })(localChanges)
53
+ .filter(guards_1.isChangeResultWithNameAndType)
54
+ .flatMap((change) => {
61
55
  const metadataKey = (0, functions_1.getMetadataKey)(change.name, change.type);
62
- // option 1: name and type match
63
- if (metadataKeyIndex.has(metadataKey)) {
64
- conflicts.add({ ...metadataKeyIndex.get(metadataKey) });
65
- }
66
- else {
67
- // option 2: some of the filenames match
68
- change.filenames?.map((filename) => {
69
- if (fileNameIndex.has(filename)) {
70
- conflicts.add({ ...fileNameIndex.get(filename) });
71
- }
72
- });
73
- }
56
+ return metadataKeyIndex.has(metadataKey)
57
+ ? // option 1: name and type match
58
+ [metadataKeyIndex.get(metadataKey)]
59
+ : // option 2: some of the filenames match
60
+ (change.filenames ?? [])
61
+ .filter((filename) => fileNameIndex.has(filename))
62
+ .map((filename) => fileNameIndex.get(filename));
74
63
  });
75
- // deeply de-dupe
76
- return Array.from(conflicts);
77
64
  };
78
65
  exports.getDedupedConflictsFromChanges = getDedupedConflictsFromChanges;
79
66
  //# sourceMappingURL=conflicts.js.map
@@ -1,16 +1,18 @@
1
- import { SourceComponent } from '@salesforce/source-deploy-retrieve';
2
- import { RemoteChangeElement, ChangeResult } from './types';
1
+ import { FileResponseSuccess, ForceIgnore, MetadataComponent, MetadataMember, RegistryAccess, SourceComponent } from '@salesforce/source-deploy-retrieve';
2
+ import { RemoteChangeElement, ChangeResult, ChangeResultWithNameAndType, RemoteSyncInput } from './types';
3
3
  export declare const getMetadataKey: (metadataType: string, metadataName: string) => string;
4
4
  export declare const getKeyFromObject: (element: RemoteChangeElement | ChangeResult) => string;
5
5
  export declare const supportsPartialDelete: (cmp: SourceComponent) => boolean;
6
- export declare const isLwcLocalOnlyTest: (filePath: string) => boolean;
6
+ export declare const excludeLwcLocalOnlyTest: (filePath: string) => boolean;
7
7
  /**
8
8
  * Verify that a filepath starts exactly with a complete parent path
9
9
  * ex: '/foo/bar-extra/baz'.startsWith('foo/bar') would be true, but this function understands that they are not in the same folder
10
10
  */
11
- export declare const pathIsInFolder: (filePath: string, folder: string) => boolean;
11
+ export declare const pathIsInFolder: (folder: string) => (filePath: string) => boolean;
12
+ /** just like pathIsInFolder but with the parameter order reversed for iterating a single file against an array of folders */
13
+ export declare const folderContainsPath: (filePath: string) => (folder: string) => boolean;
12
14
  export declare const chunkArray: <T>(arr: T[], size: number) => T[][];
13
- export declare const ensureRelative: (filePath: string, projectPath: string) => string;
15
+ export declare const ensureRelative: (projectPath: string) => (filePath: string) => string;
14
16
  export type ParsedCustomLabels = {
15
17
  CustomLabels: {
16
18
  labels: Array<{
@@ -26,3 +28,11 @@ export type ParsedCustomLabels = {
26
28
  * @returns -json equivalent of the custom labels file's contents OR undefined if the file was deleted/not written
27
29
  */
28
30
  export declare const deleteCustomLabels: (filename: string, customLabels: SourceComponent[]) => Promise<ParsedCustomLabels | undefined>;
31
+ /** returns true if forceIgnore denies a path OR if there is no forceIgnore provided */
32
+ export declare const forceIgnoreDenies: (forceIgnore?: ForceIgnore) => (filePath: string) => boolean;
33
+ export declare const sourceComponentIsCustomLabel: (input: SourceComponent) => boolean;
34
+ export declare const sourceComponentHasFullNameAndType: (input: SourceComponent) => boolean;
35
+ export declare const getAllFiles: (sc: SourceComponent) => string[];
36
+ export declare const remoteChangeToMetadataMember: (cr: ChangeResult) => MetadataMember;
37
+ export declare const FileResponseSuccessToRemoteSyncInput: (fr: FileResponseSuccess) => RemoteSyncInput;
38
+ export declare const changeResultToMetadataComponent: (registry?: RegistryAccess) => (cr: ChangeResultWithNameAndType) => MetadataComponent;
@@ -6,12 +6,14 @@
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
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.deleteCustomLabels = exports.ensureRelative = exports.chunkArray = exports.pathIsInFolder = exports.isLwcLocalOnlyTest = exports.supportsPartialDelete = exports.getKeyFromObject = exports.getMetadataKey = void 0;
9
+ 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.getMetadataKey = void 0;
10
10
  const node_path_1 = require("node:path");
11
11
  const fs = require("node:fs");
12
12
  const ts_types_1 = require("@salesforce/ts-types");
13
+ const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
13
14
  const fast_xml_parser_1 = require("fast-xml-parser");
14
15
  const kit_1 = require("@salesforce/kit");
16
+ const remoteChangeIgnoring_1 = require("./remoteChangeIgnoring");
15
17
  const getMetadataKey = (metadataType, metadataName) => `${metadataType}__${metadataName}`;
16
18
  exports.getMetadataKey = getMetadataKey;
17
19
  const getKeyFromObject = (element) => {
@@ -23,13 +25,13 @@ const getKeyFromObject = (element) => {
23
25
  exports.getKeyFromObject = getKeyFromObject;
24
26
  const supportsPartialDelete = (cmp) => !!cmp.type.supportsPartialDelete;
25
27
  exports.supportsPartialDelete = supportsPartialDelete;
26
- const isLwcLocalOnlyTest = (filePath) => filePath.includes('__utam__') || filePath.includes('__tests__');
27
- exports.isLwcLocalOnlyTest = isLwcLocalOnlyTest;
28
+ const excludeLwcLocalOnlyTest = (filePath) => !(filePath.includes('__utam__') || filePath.includes('__tests__'));
29
+ exports.excludeLwcLocalOnlyTest = excludeLwcLocalOnlyTest;
28
30
  /**
29
31
  * Verify that a filepath starts exactly with a complete parent path
30
32
  * ex: '/foo/bar-extra/baz'.startsWith('foo/bar') would be true, but this function understands that they are not in the same folder
31
33
  */
32
- const pathIsInFolder = (filePath, folder) => {
34
+ const pathIsInFolder = (folder) => (filePath) => {
33
35
  const biggerStringParts = (0, node_path_1.normalize)(filePath).split(node_path_1.sep).filter(nonEmptyStringFilter);
34
36
  return (0, node_path_1.normalize)(folder)
35
37
  .split(node_path_1.sep)
@@ -37,11 +39,14 @@ const pathIsInFolder = (filePath, folder) => {
37
39
  .every((part, index) => part === biggerStringParts[index]);
38
40
  };
39
41
  exports.pathIsInFolder = pathIsInFolder;
42
+ /** just like pathIsInFolder but with the parameter order reversed for iterating a single file against an array of folders */
43
+ const folderContainsPath = (filePath) => (folder) => (0, exports.pathIsInFolder)(folder)(filePath);
44
+ exports.folderContainsPath = folderContainsPath;
40
45
  const nonEmptyStringFilter = (value) => (0, ts_types_1.isString)(value) && value.length > 0;
41
46
  // adapted for TS from https://github.com/30-seconds/30-seconds-of-code/blob/master/snippets/chunk.md
42
47
  const chunkArray = (arr, size) => Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(i * size, i * size + size));
43
48
  exports.chunkArray = chunkArray;
44
- const ensureRelative = (filePath, projectPath) => (0, node_path_1.isAbsolute)(filePath) ? (0, node_path_1.relative)(projectPath, filePath) : filePath;
49
+ const ensureRelative = (projectPath) => (filePath) => (0, node_path_1.isAbsolute)(filePath) ? (0, node_path_1.relative)(projectPath, filePath) : filePath;
45
50
  exports.ensureRelative = ensureRelative;
46
51
  /**
47
52
  * A method to help delete custom labels from a file, or the entire file if there are no more labels
@@ -51,11 +56,9 @@ exports.ensureRelative = ensureRelative;
51
56
  * @returns -json equivalent of the custom labels file's contents OR undefined if the file was deleted/not written
52
57
  */
53
58
  const deleteCustomLabels = async (filename, customLabels) => {
54
- const customLabelsToDelete = customLabels
55
- .filter((label) => label.type.id === 'customlabel')
56
- .map((change) => change.fullName);
59
+ const customLabelsToDelete = new Set(customLabels.filter(exports.sourceComponentIsCustomLabel).map((change) => change.fullName));
57
60
  // if we don't have custom labels, we don't need to do anything
58
- if (!customLabelsToDelete.length) {
61
+ if (!customLabelsToDelete.size) {
59
62
  return undefined;
60
63
  }
61
64
  // for custom labels, we need to remove the individual label from the xml file
@@ -67,7 +70,7 @@ const deleteCustomLabels = async (filename, customLabels) => {
67
70
  });
68
71
  const cls = parser.parse(fs.readFileSync(filename, 'utf8'));
69
72
  // delete the labels from the json based on their fullName's
70
- cls.CustomLabels.labels = (0, kit_1.ensureArray)(cls.CustomLabels.labels).filter((label) => !customLabelsToDelete.includes(label.fullName));
73
+ cls.CustomLabels.labels = (0, kit_1.ensureArray)(cls.CustomLabels.labels).filter((label) => !customLabelsToDelete.has(label.fullName));
71
74
  if (cls.CustomLabels.labels.length === 0) {
72
75
  // we've deleted everything, so let's delete the file
73
76
  await fs.promises.unlink(filename);
@@ -88,4 +91,29 @@ const deleteCustomLabels = async (filename, customLabels) => {
88
91
  }
89
92
  };
90
93
  exports.deleteCustomLabels = deleteCustomLabels;
94
+ /** returns true if forceIgnore denies a path OR if there is no forceIgnore provided */
95
+ const forceIgnoreDenies = (forceIgnore) => (filePath) => forceIgnore?.denies(filePath) ?? false;
96
+ exports.forceIgnoreDenies = forceIgnoreDenies;
97
+ const sourceComponentIsCustomLabel = (input) => input.type.name === 'CustomLabel';
98
+ exports.sourceComponentIsCustomLabel = sourceComponentIsCustomLabel;
99
+ const sourceComponentHasFullNameAndType = (input) => typeof input.fullName === 'string' && typeof input.type.name === 'string';
100
+ exports.sourceComponentHasFullNameAndType = sourceComponentHasFullNameAndType;
101
+ const getAllFiles = (sc) => [sc.xml, ...sc.walkContent()].filter(ts_types_1.isString);
102
+ exports.getAllFiles = getAllFiles;
103
+ const remoteChangeToMetadataMember = (cr) => {
104
+ const checked = (0, remoteChangeIgnoring_1.ensureNameAndType)(cr);
105
+ return {
106
+ fullName: checked.name,
107
+ type: checked.type,
108
+ };
109
+ };
110
+ exports.remoteChangeToMetadataMember = remoteChangeToMetadataMember;
111
+ // weird, right? This is for oclif.table which allows types but not interfaces. In this case, they are equivalent
112
+ const FileResponseSuccessToRemoteSyncInput = (fr) => fr;
113
+ exports.FileResponseSuccessToRemoteSyncInput = FileResponseSuccessToRemoteSyncInput;
114
+ const changeResultToMetadataComponent = (registry = new source_deploy_retrieve_1.RegistryAccess()) => (cr) => ({
115
+ fullName: cr.name,
116
+ type: registry.getTypeByName(cr.type),
117
+ });
118
+ exports.changeResultToMetadataComponent = changeResultToMetadataComponent;
91
119
  //# sourceMappingURL=functions.js.map
@@ -1,3 +1,11 @@
1
- import { SourceComponent, MetadataMember } from '@salesforce/source-deploy-retrieve';
1
+ import { SourceComponent, MetadataMember, FileResponse, FileResponseFailure, FileResponseSuccess } from '@salesforce/source-deploy-retrieve';
2
+ import { ChangeResult } from './types';
3
+ import { ChangeResultWithNameAndType } from './types';
2
4
  export declare const sourceComponentGuard: (input: SourceComponent | undefined) => input is SourceComponent;
3
5
  export declare const metadataMemberGuard: (input: MetadataMember | undefined | Partial<MetadataMember>) => input is MetadataMember;
6
+ export declare const isSdrFailure: (fileResponse: FileResponse) => fileResponse is FileResponseFailure;
7
+ export declare const isSdrSuccess: (fileResponse: FileResponse) => fileResponse is FileResponseSuccess;
8
+ export declare const FileResponseIsDeleted: (fileResponse: FileResponse) => boolean;
9
+ export declare const FileResponseIsNotDeleted: (fileResponse: FileResponse) => boolean;
10
+ export declare const FileResponseHasPath: (fileResponse: FileResponseSuccess) => fileResponse is FileResponseSuccess & Required<Pick<FileResponseSuccess, "filePath">>;
11
+ export declare const isChangeResultWithNameAndType: (cr?: ChangeResult) => cr is ChangeResultWithNameAndType;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.metadataMemberGuard = exports.sourceComponentGuard = void 0;
3
+ exports.isChangeResultWithNameAndType = exports.FileResponseHasPath = exports.FileResponseIsNotDeleted = exports.FileResponseIsDeleted = exports.isSdrSuccess = exports.isSdrFailure = exports.metadataMemberGuard = exports.sourceComponentGuard = void 0;
4
4
  /*
5
5
  * Copyright (c) 2020, salesforce.com, inc.
6
6
  * All rights reserved.
@@ -12,4 +12,16 @@ const sourceComponentGuard = (input) => input instanceof source_deploy_retrieve_
12
12
  exports.sourceComponentGuard = sourceComponentGuard;
13
13
  const metadataMemberGuard = (input) => input !== undefined && typeof input.fullName === 'string' && typeof input.type === 'string';
14
14
  exports.metadataMemberGuard = metadataMemberGuard;
15
+ const isSdrFailure = (fileResponse) => fileResponse.state === source_deploy_retrieve_1.ComponentStatus.Failed;
16
+ exports.isSdrFailure = isSdrFailure;
17
+ const isSdrSuccess = (fileResponse) => fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Failed;
18
+ exports.isSdrSuccess = isSdrSuccess;
19
+ const FileResponseIsDeleted = (fileResponse) => fileResponse.state === source_deploy_retrieve_1.ComponentStatus.Deleted;
20
+ exports.FileResponseIsDeleted = FileResponseIsDeleted;
21
+ const FileResponseIsNotDeleted = (fileResponse) => fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Deleted;
22
+ exports.FileResponseIsNotDeleted = FileResponseIsNotDeleted;
23
+ const FileResponseHasPath = (fileResponse) => fileResponse.filePath !== undefined;
24
+ exports.FileResponseHasPath = FileResponseHasPath;
25
+ const isChangeResultWithNameAndType = (cr) => typeof cr === 'object' && typeof cr.name === 'string' && typeof cr.type === 'string';
26
+ exports.isChangeResultWithNameAndType = isChangeResultWithNameAndType;
15
27
  //# sourceMappingURL=guards.js.map
@@ -1,5 +1,5 @@
1
1
  import { NamedPackageDir } from '@salesforce/core';
2
- import { ComponentSet } from '@salesforce/source-deploy-retrieve';
2
+ import { ComponentSet, RegistryAccess } from '@salesforce/source-deploy-retrieve';
3
3
  interface GroupedFileInput {
4
4
  packageDirs: NamedPackageDir[];
5
5
  nonDeletes: string[];
@@ -11,5 +11,9 @@ interface GroupedFile {
11
11
  deletes: string[];
12
12
  }
13
13
  export declare const getGroupedFiles: (input: GroupedFileInput, byPackageDir?: boolean) => GroupedFile[];
14
- export declare const getComponentSets: (groupings: GroupedFile[], sourceApiVersion?: string) => ComponentSet[];
14
+ export declare const getComponentSets: ({ groupings, sourceApiVersion, registry, }: {
15
+ groupings: GroupedFile[];
16
+ sourceApiVersion?: string | undefined;
17
+ registry: RegistryAccess;
18
+ }) => ComponentSet[];
15
19
  export {};
@@ -17,8 +17,8 @@ const getGroupedFiles = (input, byPackageDir = false) => (byPackageDir ? getSequ
17
17
  exports.getGroupedFiles = getGroupedFiles;
18
18
  const getSequential = ({ packageDirs, nonDeletes, deletes }) => packageDirs.map((pkgDir) => ({
19
19
  path: pkgDir.name,
20
- nonDeletes: nonDeletes.filter((f) => (0, functions_1.pathIsInFolder)(f, pkgDir.name)),
21
- deletes: deletes.filter((f) => (0, functions_1.pathIsInFolder)(f, pkgDir.name)),
20
+ nonDeletes: nonDeletes.filter((0, functions_1.pathIsInFolder)(pkgDir.name)),
21
+ deletes: deletes.filter((0, functions_1.pathIsInFolder)(pkgDir.name)),
22
22
  }));
23
23
  const getNonSequential = ({ packageDirs, nonDeletes: nonDeletes, deletes: deletes, }) => [
24
24
  {
@@ -27,20 +27,20 @@ const getNonSequential = ({ packageDirs, nonDeletes: nonDeletes, deletes: delete
27
27
  path: packageDirs.map((dir) => dir.name).join(';'),
28
28
  },
29
29
  ];
30
- const getComponentSets = (groupings, sourceApiVersion) => {
30
+ const getComponentSets = ({ groupings, sourceApiVersion, registry = new source_deploy_retrieve_1.RegistryAccess(), }) => {
31
31
  const logger = core_1.Logger.childFromRoot('localComponentSetArray');
32
32
  // optimistic resolution...some files may not be possible to resolve
33
- const resolverForNonDeletes = new source_deploy_retrieve_1.MetadataResolver();
33
+ const resolverForNonDeletes = new source_deploy_retrieve_1.MetadataResolver(registry);
34
34
  return groupings
35
35
  .map((grouping) => {
36
36
  logger.debug(`building componentSet for ${grouping.path} (deletes: ${grouping.deletes.length} nonDeletes: ${grouping.nonDeletes.length})`);
37
- const componentSet = new source_deploy_retrieve_1.ComponentSet();
37
+ const componentSet = new source_deploy_retrieve_1.ComponentSet(undefined, registry);
38
38
  if (sourceApiVersion) {
39
39
  componentSet.sourceApiVersion = sourceApiVersion;
40
40
  }
41
41
  // we need virtual components for the deletes.
42
42
  // TODO: could we use the same for the non-deletes?
43
- const resolverForDeletes = new source_deploy_retrieve_1.MetadataResolver(undefined, source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(grouping.deletes));
43
+ const resolverForDeletes = new source_deploy_retrieve_1.MetadataResolver(registry, source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(grouping.deletes));
44
44
  grouping.deletes
45
45
  .flatMap((filename) => resolverForDeletes.getComponentsFromPath(filename))
46
46
  .filter(guards_1.sourceComponentGuard)
@@ -38,7 +38,7 @@ class ShadowRepo {
38
38
  this.projectPath = options.projectPath;
39
39
  this.packageDirs = options.packageDirs;
40
40
  this.isWindows = os.type() === 'Windows_NT';
41
- this.maxFileAdd = kit_1.env.getNumber('SF_SOURCE_TRACKING_BATCH_SIZE', kit_1.env.getNumber('SFDX_SOURCE_TRACKING_BATCH_SIZE', this.isWindows ? 8000 : 15000));
41
+ this.maxFileAdd = kit_1.env.getNumber('SF_SOURCE_TRACKING_BATCH_SIZE', kit_1.env.getNumber('SFDX_SOURCE_TRACKING_BATCH_SIZE', this.isWindows ? 8000 : 15_000));
42
42
  }
43
43
  // think of singleton behavior but unique to the projectPath
44
44
  static async getInstance(options) {
@@ -100,26 +100,24 @@ class ShadowRepo {
100
100
  // iso-git uses relative, posix paths
101
101
  // but packageDirs has already resolved / normalized them
102
102
  // so we need to make them project-relative again and convert if windows
103
- const filepaths = this.packageDirs
104
- .map((dir) => path.relative(this.projectPath, dir.fullPath))
105
- .map((p) => (this.isWindows ? p.split(path.sep).join(path.posix.sep) : p));
103
+ const pkgDirs = this.packageDirs.map(packageDirToRelativePosixPath(this.isWindows)(this.projectPath));
106
104
  try {
107
105
  // status hasn't been initialized yet
108
106
  this.status = await git.statusMatrix({
109
107
  fs,
110
108
  dir: this.projectPath,
111
109
  gitdir: this.gitDir,
112
- filepaths,
110
+ filepaths: pkgDirs,
113
111
  ignored: true,
114
112
  filter: (f) =>
115
113
  // no hidden files
116
114
  !f.includes(`${path.sep}.`) &&
117
115
  // no lwc tests
118
- !(0, functions_1.isLwcLocalOnlyTest)(f) &&
116
+ (0, functions_1.excludeLwcLocalOnlyTest)(f) &&
119
117
  // no gitignore files
120
118
  !f.endsWith('.gitignore') &&
121
119
  // isogit uses `startsWith` for filepaths so it's possible to get a false positive
122
- filepaths.some((pkgDir) => (0, functions_1.pathIsInFolder)(f, pkgDir)),
120
+ pkgDirs.some((0, functions_1.folderContainsPath)(f)),
123
121
  });
124
122
  }
125
123
  catch (e) {
@@ -198,10 +196,10 @@ class ShadowRepo {
198
196
  deletedFiles: deletedFiles.length,
199
197
  });
200
198
  // these are stored in posix/style/path format. We have to convert inbound stuff from windows
201
- if (os.type() === 'Windows_NT') {
199
+ if (this.isWindows) {
202
200
  this.logger.trace('start: transforming windows paths to posix');
203
- deployedFiles = deployedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
204
- deletedFiles = deletedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
201
+ deployedFiles = deployedFiles.map(normalize).map(ensurePosix);
202
+ deletedFiles = deletedFiles.map(normalize).map(ensurePosix);
205
203
  this.logger.trace('done: transforming windows paths to posix');
206
204
  }
207
205
  if (deployedFiles.length) {
@@ -266,4 +264,9 @@ class ShadowRepo {
266
264
  }
267
265
  exports.ShadowRepo = ShadowRepo;
268
266
  ShadowRepo.instanceMap = new Map();
267
+ const packageDirToRelativePosixPath = (isWindows) => (projectPath) => (packageDir) => isWindows
268
+ ? ensurePosix(path.relative(projectPath, packageDir.fullPath))
269
+ : path.relative(projectPath, packageDir.fullPath);
270
+ const normalize = (filepath) => path.normalize(filepath);
271
+ const ensurePosix = (filepath) => filepath.split(path.sep).join(path.posix.sep);
269
272
  //# sourceMappingURL=localShadowRepo.js.map
@@ -20,6 +20,7 @@ const registry = new source_deploy_retrieve_1.RegistryAccess();
20
20
  // only compute once
21
21
  const aliasTypes = registry
22
22
  .getAliasTypes()
23
+ // allow assertion because aliasTypes are defined as having that property
23
24
  .map((aliasType) => [aliasType.name, registry.getTypeByName(aliasType.aliasFor).name]);
24
25
  const reverseAliasTypes = new Map(aliasTypes.map(([alias, type]) => [type, alias]));
25
26
  // handle all "weird" type/name translation between SourceMember and SDR FileResponse
@@ -1,3 +1,4 @@
1
+ import { RegistryAccess } from '@salesforce/source-deploy-retrieve';
1
2
  import { ChangeResult } from './types';
2
3
  /**
3
4
  * Will build a component set, crawling your local directory, to get paths for remote changes
@@ -6,4 +7,8 @@ import { ChangeResult } from './types';
6
7
  * @param packageDirPaths Array of paths from PackageDirectories
7
8
  * @returns
8
9
  */
9
- export declare const populateFilePaths: (elements: ChangeResult[], packageDirPaths: string[]) => ChangeResult[];
10
+ export declare const populateFilePaths: ({ elements, packageDirPaths, registry, }: {
11
+ elements: ChangeResult[];
12
+ packageDirPaths: string[];
13
+ registry: RegistryAccess;
14
+ }) => ChangeResult[];
@@ -19,7 +19,7 @@ const functions_1 = require("./functions");
19
19
  * @param packageDirPaths Array of paths from PackageDirectories
20
20
  * @returns
21
21
  */
22
- const populateFilePaths = (elements, packageDirPaths) => {
22
+ const populateFilePaths = ({ elements, packageDirPaths, registry, }) => {
23
23
  if (elements.length === 0) {
24
24
  return [];
25
25
  }
@@ -28,22 +28,17 @@ const populateFilePaths = (elements, packageDirPaths) => {
28
28
  // component set generated from an array of MetadataMember from all the remote changes
29
29
  // but exclude the ones that aren't in the registry
30
30
  const remoteChangesAsMetadataMember = elements
31
- .map((element) => {
32
- if (typeof element.type === 'string' && typeof element.name === 'string') {
33
- return {
34
- type: element.type,
35
- fullName: element.name,
36
- };
37
- }
38
- })
39
- .filter(guards_1.metadataMemberGuard);
40
- const remoteChangesAsComponentSet = new source_deploy_retrieve_1.ComponentSet(remoteChangesAsMetadataMember);
31
+ .filter(guards_1.isChangeResultWithNameAndType)
32
+ .map(functions_1.remoteChangeToMetadataMember);
33
+ const remoteChangesAsComponentSet = new source_deploy_retrieve_1.ComponentSet(remoteChangesAsMetadataMember, registry);
41
34
  logger.debug(` the generated component set has ${remoteChangesAsComponentSet.size.toString()} items`);
42
35
  if (remoteChangesAsComponentSet.size < elements.length) {
43
36
  // there *could* be something missing
44
37
  // some types (ex: LWC) show up as multiple files in the remote changes, but only one in the component set
45
38
  // iterate the elements to see which ones didn't make it into the component set
46
- const missingComponents = elements.filter((element) => !remoteChangesAsComponentSet.has({ type: element?.type, fullName: element?.name }));
39
+ const missingComponents = elements
40
+ .filter(guards_1.isChangeResultWithNameAndType)
41
+ .filter((element) => !remoteChangesAsComponentSet.has({ type: element.type, fullName: element.name }));
47
42
  // Throw if anything was actually missing
48
43
  if (missingComponents.length > 0) {
49
44
  throw new Error(`unable to generate complete component set for ${elements
@@ -54,25 +49,28 @@ const populateFilePaths = (elements, packageDirPaths) => {
54
49
  const matchingLocalSourceComponentsSet = source_deploy_retrieve_1.ComponentSet.fromSource({
55
50
  fsPaths: packageDirPaths,
56
51
  include: remoteChangesAsComponentSet,
52
+ registry,
57
53
  });
58
54
  logger.debug(` local source-backed component set has ${matchingLocalSourceComponentsSet.size.toString()} items from remote`);
59
55
  // make it simpler to find things later
60
56
  const elementMap = new Map(elements.map((e) => [(0, functions_1.getKeyFromObject)(e), e]));
61
57
  // iterates the local components and sets their filenames
62
- for (const matchingComponent of matchingLocalSourceComponentsSet.getSourceComponents().toArray()) {
63
- if (matchingComponent.fullName && matchingComponent.type.name) {
64
- logger.debug(`${matchingComponent.fullName}|${matchingComponent.type.name} matches ${matchingComponent.xml} and maybe ${matchingComponent.walkContent().toString()}`);
65
- // Decode the key since local components can have encoded fullNames, but results from querying
66
- // SourceMembers have fullNames that are not encoded. See: https://github.com/forcedotcom/cli/issues/1683
67
- const key = decodeURIComponent((0, functions_1.getMetadataKey)(matchingComponent.type.name, matchingComponent.fullName));
68
- elementMap.set(key, {
69
- ...elementMap.get(key),
70
- modified: true,
71
- origin: 'remote',
72
- filenames: [matchingComponent.xml, ...matchingComponent.walkContent()].filter((filename) => filename),
73
- });
74
- }
75
- }
58
+ matchingLocalSourceComponentsSet
59
+ .getSourceComponents()
60
+ .toArray()
61
+ .filter(functions_1.sourceComponentHasFullNameAndType)
62
+ .map((matchingComponent) => {
63
+ logger.debug(`${matchingComponent.fullName}|${matchingComponent.type.name} matches ${matchingComponent.xml} and maybe ${matchingComponent.walkContent().toString()}`);
64
+ // Decode the key since local components can have encoded fullNames, but results from querying
65
+ // SourceMembers have fullNames that are not encoded. See: https://github.com/forcedotcom/cli/issues/1683
66
+ const key = decodeURIComponent((0, functions_1.getMetadataKey)(matchingComponent.type.name, matchingComponent.fullName));
67
+ elementMap.set(key, {
68
+ ...elementMap.get(key),
69
+ modified: true,
70
+ origin: 'remote',
71
+ filenames: (0, functions_1.getAllFiles)(matchingComponent),
72
+ });
73
+ });
76
74
  return Array.from(elementMap.values());
77
75
  };
78
76
  exports.populateFilePaths = populateFilePaths;
@@ -1,4 +1,4 @@
1
- import { ForceIgnore } from '@salesforce/source-deploy-retrieve';
1
+ import { ForceIgnore, RegistryAccess } from '@salesforce/source-deploy-retrieve';
2
2
  import { ChangeResult } from './types';
3
3
  /**
4
4
  * uses SDR to translate remote metadata records into local file paths (which only typically have the filename).
@@ -9,10 +9,10 @@ import { ChangeResult } from './types';
9
9
  * @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)
10
10
  * @input resolveDeleted: constructs a virtualTree instead of the actual filesystem--useful when the files no longer exist
11
11
  */
12
- export declare const populateTypesAndNames: ({ elements, projectPath, forceIgnore, excludeUnresolvable, resolveDeleted, }: {
13
- elements: ChangeResult[];
12
+ export declare const populateTypesAndNames: ({ projectPath, forceIgnore, excludeUnresolvable, resolveDeleted, registry, }: {
14
13
  projectPath: string;
15
14
  forceIgnore?: ForceIgnore | undefined;
16
15
  excludeUnresolvable?: boolean | undefined;
17
16
  resolveDeleted?: boolean | undefined;
18
- }) => ChangeResult[];
17
+ registry: RegistryAccess;
18
+ }) => (elements: ChangeResult[]) => ChangeResult[];