Skip to content
Merged
1,460 changes: 373 additions & 1,087 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"dependencies": {
"@salesforce/core": "^8.23.4",
"@salesforce/kit": "^3.2.4",
"@salesforce/source-deploy-retrieve": "^12.26.1",
"@salesforce/source-deploy-retrieve": "^12.29.1",
"@salesforce/ts-types": "^2.0.12",
"fast-xml-parser": "^4.5.3",
"graceful-fs": "^4.2.11",
Expand Down
2 changes: 1 addition & 1 deletion src/shared/conflicts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const findConflictsInComponentSet = (cs: ComponentSet, conflicts: ChangeR
state: 'Conflict',
fullName: cr.name,
type: cr.type,
filePath: resolve(f),
filePath: resolve(...[...(cs.projectDirectory ? [cs.projectDirectory, f] : [f])]),
});
});
});
Expand Down
9 changes: 9 additions & 0 deletions src/shared/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import {
ForceIgnore,
MetadataComponent,
MetadataMember,
NodeFSTreeContainer,
RegistryAccess,
SourceComponent,
TreeContainer,
} from '@salesforce/source-deploy-retrieve';
import { XMLBuilder, XMLParser } from 'fast-xml-parser';
import { ensureArray } from '@salesforce/kit';
Expand Down Expand Up @@ -189,3 +191,10 @@ export const changeResultToMetadataComponent =
// TODO: use set.union when node 22 is everywhere
export const uniqueArrayConcat = <T>(arr1: T[] | Set<T>, arr2: T[] | Set<T>): T[] =>
Array.from(new Set([...arr1, ...arr2]));

/** for web, where cwd does not existconstruct a TreeContainer with the projectPath to keep SDR MetadataResolver from trying to use cwd */
export const maybeGetTreeContainer = (projectPath: string): TreeContainer | undefined =>
// cwd is '/' in extensions unless it's set by some process.
process.env.ESBUILD_PLATFORM === 'web' || process.cwd() !== projectPath
? new NodeFSTreeContainer(projectPath)
: undefined;
13 changes: 5 additions & 8 deletions src/shared/localComponentSetArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ import {
VirtualTreeContainer,
DestructiveChangesType,
RegistryAccess,
NodeFSTreeContainer,
} from '@salesforce/source-deploy-retrieve';
import { isDefined } from './guards';
import { supportsPartialDelete, pathIsInFolder } from './functions';
import { supportsPartialDelete, pathIsInFolder, maybeGetTreeContainer } from './functions';

type GroupedFileInput = {
packageDirs: NamedPackageDir[];
Expand Down Expand Up @@ -102,10 +101,7 @@ export const getComponentSets = ({
const logger = Logger.childFromRoot('localComponentSetArray');

// optimistic resolution...some files may not be possible to resolve
const resolverForNonDeletes = new MetadataResolver(
registry,
process.env.ESBUILD_PLATFORM === 'web' ? new NodeFSTreeContainer(projectPath) : undefined
);
const resolverForNonDeletes = new MetadataResolver(registry, maybeGetTreeContainer(projectPath));

return groupings
.map((grouping) => {
Expand All @@ -132,7 +128,7 @@ export const getComponentSets = ({
// all bundle types have a directory name
try {
resolverForNonDeletes
.getComponentsFromPath(resolve(component.content))
.getComponentsFromPath(resolve(projectPath, component.content))
.filter(isDefined)
.map((nonDeletedComponent) => componentSet.add(nonDeletedComponent));
} catch (e) {
Expand All @@ -148,7 +144,7 @@ export const getComponentSets = ({
grouping.nonDeletes
.flatMap((filename) => {
try {
return resolverForNonDeletes.getComponentsFromPath(resolve(filename));
return resolverForNonDeletes.getComponentsFromPath(resolve(projectPath, filename));
} catch (e) {
logger.warn(`unable to resolve ${filename}`);
return undefined;
Expand All @@ -161,6 +157,7 @@ export const getComponentSets = ({
componentSet.forceIgnoredPaths = new Set(
[...(componentSet.forceIgnoredPaths ?? [])].concat(Array.from(resolverForNonDeletes.forceIgnoredPaths))
);
componentSet.projectDirectory = projectPath;
return componentSet;
})
.filter((componentSet) => componentSet.size > 0 || componentSet.forceIgnoredPaths?.size);
Expand Down
3 changes: 2 additions & 1 deletion src/shared/populateTypesAndNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
excludeLwcLocalOnlyTest,
forceIgnoreDenies,
getAllFiles,
maybeGetTreeContainer,
sourceComponentHasFullNameAndType,
} from './functions';

Expand Down Expand Up @@ -65,7 +66,7 @@ export const populateTypesAndNames =
// component set generated from the filenames on all local changes
const resolver = new MetadataResolver(
registry,
resolveDeleted ? VirtualTreeContainer.fromFilePaths(filenames) : undefined,
resolveDeleted ? VirtualTreeContainer.fromFilePaths(filenames) : maybeGetTreeContainer(projectPath),
!!forceIgnore
);
const sourceComponents = filenames
Expand Down
10 changes: 8 additions & 2 deletions src/sourceTracking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import { removeIgnored } from './shared/remoteChangeIgnoring';
import {
FileResponseSuccessToRemoteSyncInput,
changeResultToMetadataComponent,
maybeGetTreeContainer,
remoteChangeToMetadataMember,
} from './shared/functions';
import {
Expand Down Expand Up @@ -311,7 +312,9 @@ export class SourceTracking extends AsyncCreatable {
if (options.format === 'SourceComponent') {
const resolver = new MetadataResolver(
this.registry,
options.state === 'delete' ? VirtualTreeContainer.fromFilePaths(filenames) : undefined
options.state === 'delete'
? VirtualTreeContainer.fromFilePaths(filenames)
: maybeGetTreeContainer(this.projectPath)
);

return filenames
Expand Down Expand Up @@ -354,7 +357,7 @@ export class SourceTracking extends AsyncCreatable {
this.registry
);
const matchingLocalSourceComponentsSet = ComponentSet.fromSource({
fsPaths: this.packagesDirs.map((dir) => resolve(dir.fullPath)),
fsPaths: this.packagesDirs.map((dir) => resolve(this.projectPath, dir.fullPath)),
include: remoteChangesAsComponentSet,
registry: this.registry,
});
Expand Down Expand Up @@ -466,6 +469,9 @@ export class SourceTracking extends AsyncCreatable {
tree: VirtualTreeContainer.fromFilePaths(relativeOptions.files),
registry: this.registry,
});

deployedFilesAsVirtualComponentSet.projectDirectory = this.projectPath;

// these are top-level bundle paths like lwc/foo
const bundlesWithDeletedFiles = (
await this.getChanges({ origin: 'local', state: 'delete', format: 'SourceComponent' })
Expand Down
32 changes: 32 additions & 0 deletions test/unit/shared/functions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2025, Salesforce, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { expect } from 'chai';
import { ensureRelative } from '../../../src/shared/functions';

describe('ensureRelative', () => {
it('should handle relative paths', () => {
expect(ensureRelative('/foo/bar')('baz')).to.equal('baz');
});

it('should return the relative path', () => {
expect(ensureRelative('/foo/bar')('/foo/bar/baz')).to.equal('baz');
});

it('should handle paths above the project directory', () => {
expect(ensureRelative('/')('/baz')).to.equal('baz');
});
});
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -780,10 +780,10 @@
resolved "https://registry.yarnpkg.com/@salesforce/schemas/-/schemas-1.10.3.tgz#52c867fdd60679cf216110aa49542b7ad391f5d1"
integrity sha512-FKfvtrYTcvTXE9advzS25/DEY9yJhEyLvStm++eQFtnAaX1pe4G3oGHgiQ0q55BM5+0AlCh0+0CVtQv1t4oJRA==

"@salesforce/source-deploy-retrieve@^12.26.1":
version "12.26.1"
resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-12.26.1.tgz#161a37bf7f94273de49fbfb771e7f333937a00b2"
integrity sha512-PQJoURhTBCVM2Q4Sgo6iKZnZfQ1x+fE3r4uUKQ2nzDhPxrICm8OsGRXOS82NVPo8M8jL68sZ6CxPrRYgxZyCfg==
"@salesforce/source-deploy-retrieve@^12.29.1":
version "12.29.1"
resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-12.29.1.tgz#8c195d145952b7fe247a7031affae8ebb7833772"
integrity sha512-5Olq7Wj86+F009i6o+0Dv5bK6f0nn4lj4ohuuNhgllnlQzr50PLXfNZWPbdsBsSn9nFc5F3d45G7x23LE3qETw==
dependencies:
"@salesforce/core" "^8.23.4"
"@salesforce/kit" "^3.2.4"
Expand Down
Loading