Skip to content

Commit 83ce8bc

Browse files
committed
fix: resolve decomposed Permission Set parents by suffix
1 parent 6c0fb5c commit 83ce8bc

3 files changed

Lines changed: 30 additions & 4 deletions

File tree

src/resolve/adapters/baseSourceAdapter.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,12 @@ export abstract class BaseSourceAdapter implements SourceAdapter {
110110
const typeDirName = basename(this.type.inFolder ? dirname(parentPath) : parentPath);
111111
const nameMatchesParent = basename(parentPath) === metaXml.fullName;
112112
const inTypeDir = typeDirName === this.type.directoryName;
113-
// if the parent folder name matches the fullName OR parent folder name is
114-
// metadata type's directory name, it's a root metadata xml.
115-
isRootMetadataXml = nameMatchesParent || inTypeDir;
113+
const rootSuffixes = [this.type.suffix, this.type.legacySuffix].filter(Boolean);
114+
const suffixMatchesRoot = rootSuffixes.includes(metaXml.suffix);
115+
// Decomposed children can share the parent fullName (for example,
116+
// MyPermissionSet.applicationVisibility-meta.xml). The suffix must
117+
// identify the parent before the directory name can confirm it.
118+
isRootMetadataXml = suffixMatchesRoot && (nameMatchesParent || inTypeDir);
116119
} else {
117120
isRootMetadataXml = true;
118121
}

src/resolve/adapters/mixedContentSourceAdapter.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import { dirname, basename, sep, join } from 'node:path';
1717
import { Messages } from '@salesforce/core/messages';
1818
import { SfError } from '@salesforce/core/sfError';
19-
import { baseName } from '../../utils/path';
19+
import { baseName, parseMetadataXml } from '../../utils/path';
2020
import { SourcePath } from '../../common/types';
2121
import { SourceComponent } from '../sourceComponent';
2222
import { BaseSourceAdapter } from './baseSourceAdapter';
@@ -55,6 +55,19 @@ export class MixedContentSourceAdapter extends BaseSourceAdapter {
5555
protected getRootMetadataXmlPath(trigger: SourcePath): SourcePath | undefined {
5656
if (this.ownFolder) {
5757
const componentRoot = this.trimPathToContent(trigger);
58+
59+
const rootSuffixes = [this.type.suffix, this.type.legacySuffix].filter(
60+
(suffix): suffix is string => typeof suffix === 'string'
61+
);
62+
const rootFile = this.tree.readDirectory(componentRoot).find((entry) => {
63+
const metadata = parseMetadataXml(join(componentRoot, entry));
64+
return metadata?.suffix !== undefined && rootSuffixes.includes(metadata.suffix);
65+
});
66+
67+
if (rootFile) {
68+
return join(componentRoot, rootFile);
69+
}
70+
5871
return this.tree.find('metadataXml', basename(componentRoot), componentRoot);
5972
}
6073
return this.findMetadataFromContent(trigger);

test/resolve/metadataResolver.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ describe('MetadataResolver', () => {
183183
expect(components2[0].type.name).to.equal('PermissionSet');
184184
});
185185

186+
it('Should resolve the Beta2 Permission Set parent when resolving its directory', () => {
187+
const resolver = new MetadataResolver(regAccPermissionSet, SOURCE_FORMAT_PS.tree);
188+
const permissionSetDirectory = join('main', 'default', 'permissionsets', 'myPS');
189+
const components = resolver.getComponentsFromPath(permissionSetDirectory);
190+
191+
expect(components).to.have.lengthOf(1);
192+
expect(components[0].type.name).to.equal('PermissionSet');
193+
expect(components[0].xml).to.equal(join(permissionSetDirectory, 'myPS.permissionset-meta.xml'));
194+
});
195+
186196
it('Should determine type for metadata file with known suffix and strictDirectoryName', () => {
187197
// CustomSite is an example. The conditions are:
188198
// 1. Type has "strictDirectoryName": true

0 commit comments

Comments
 (0)