Skip to content

Commit eda47ea

Browse files
fix: change map to use name#type for key @W-18476014@ (#1571)
* fix: change map to use name+type for key * chore: create a key type to ensure correct keys are used
1 parent 935645e commit eda47ea

File tree

11 files changed

+115
-23
lines changed

11 files changed

+115
-23
lines changed

src/collections/componentSet.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export type RetrieveSetOptions = Omit<MetadataApiRetrieveOptions, 'components'>;
4848

4949
const KEY_DELIMITER = '#';
5050

51+
export type SimpleKeyString = `${string}#${string}`;
52+
5153
/**
5254
* A collection containing no duplicate metadata members (`fullName` and `type` pairs). `ComponentSets`
5355
* are a convenient way of constructing a unique collection of components to perform operations such as
@@ -750,7 +752,7 @@ const sourceKey = (component: SourceComponent): string => {
750752
return `${type.name}${fullName}${xml ?? ''}${content ?? ''}`;
751753
};
752754

753-
const simpleKey = (component: ComponentLike): string => {
755+
export const simpleKey = (component: ComponentLike): SimpleKeyString => {
754756
const typeName = typeof component.type === 'string' ? component.type.toLowerCase().trim() : component.type.id;
755757
return `${typeName}${KEY_DELIMITER}${component.fullName}`;
756758
};

src/convert/convertContext/recompositionFinalizer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Messages } from '@salesforce/core';
1010
import { extractUniqueElementValue, getXmlElement, unwrapAndOmitNS } from '../../utils/decomposed';
1111
import { MetadataComponent } from '../../resolve/types';
1212
import { XML_NS_KEY, XML_NS_URL } from '../../common/constants';
13-
import { ComponentSet } from '../../collections/componentSet';
13+
import { ComponentSet, SimpleKeyString } from '../../collections/componentSet';
1414
import { SourceComponent } from '../../resolve/sourceComponent';
1515
import { JsToXml } from '../streams';
1616
import { WriterFormat } from '../types';
@@ -41,7 +41,7 @@ type XmlCache = Map<string, JsonMap>;
4141
*
4242
*/
4343
export class RecompositionFinalizer extends ConvertTransactionFinalizer<RecompositionState> {
44-
public transactionState: RecompositionState = new Map<string, RecompositionStateValue>();
44+
public transactionState: RecompositionState = new Map<SimpleKeyString, RecompositionStateValue>();
4545
private xmlCache: XmlCache = new Map();
4646

4747
public async finalize(): Promise<WriterFormat[]> {

src/convert/transformers/decomposedMetadataTransformer.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { JsToXml } from '../streams';
2020
import type { ToSourceFormatInput, WriteInfo, XmlObj } from '../types';
2121
import { META_XML_SUFFIX, XML_NS_KEY, XML_NS_URL } from '../../common/constants';
2222
import type { SourcePath } from '../../common/types';
23-
import { ComponentSet } from '../../collections/componentSet';
23+
import { ComponentSet, simpleKey } from '../../collections/componentSet';
2424
import type { DecompositionState, DecompositionStateValue } from '../convertContext/decompositionFinalizer';
2525
import { BaseMetadataTransformer } from './baseMetadataTransformer';
2626
import type { ComposedMetadata, ComposedMetadataWithChildType, InfoContainer } from './types';
@@ -34,16 +34,16 @@ export class DecomposedMetadataTransformer extends BaseMetadataTransformer {
3434
// eslint-disable-next-line @typescript-eslint/require-await
3535
public async toMetadataFormat(component: SourceComponent): Promise<WriteInfo[]> {
3636
if (component.parent) {
37-
const { fullName: parentName } = component.parent;
38-
const stateForParent = this.context.recomposition.transactionState.get(parentName) ?? {
37+
const key = simpleKey(component.parent);
38+
const stateForParent = this.context.recomposition.transactionState.get(key) ?? {
3939
component: component.parent,
4040
children: new ComponentSet([], this.registry),
4141
};
4242
stateForParent.children?.add(component);
43-
this.context.recomposition.transactionState.set(parentName, stateForParent);
43+
this.context.recomposition.transactionState.set(key, stateForParent);
4444
} else {
45-
const { fullName } = component;
46-
const existing = this.context.recomposition.transactionState.get(fullName) ?? {
45+
const key = simpleKey(component);
46+
const existing = this.context.recomposition.transactionState.get(key) ?? {
4747
component,
4848
children: new ComponentSet([], this.registry),
4949
};
@@ -55,7 +55,7 @@ export class DecomposedMetadataTransformer extends BaseMetadataTransformer {
5555
(component.getChildren() ?? []).map((child) => {
5656
existing.children?.add(child);
5757
});
58-
this.context.recomposition.transactionState.set(fullName, existing);
58+
this.context.recomposition.transactionState.set(key, existing);
5959
}
6060
// noop since the finalizer will push the writes to the component writer
6161
return [];
@@ -237,16 +237,14 @@ export const getWriteInfosWithoutMerge =
237237
export const setDecomposedState =
238238
(state: DecompositionState) =>
239239
(forComponent: MetadataComponent, props: Partial<Omit<DecompositionStateValue, 'origin'>>): void => {
240-
const key = getKey(forComponent);
240+
const key = simpleKey(forComponent);
241241
state.set(key, {
242242
// origin gets set the first time
243243
...(state.get(key) ?? { origin: forComponent.parent ?? forComponent }),
244244
...(props ?? {}),
245245
});
246246
};
247247

248-
const getKey = (component: MetadataComponent): string => `${component.type.name}#${component.fullName}`;
249-
250248
/** for a component, parse the xml and create an json object with contents, child typeId, etc */
251249
const getComposedMetadataEntries = async (component: SourceComponent): Promise<ComposedMetadata[]> =>
252250
// composedMetadata might be undefined if you call toSourceFormat() from a non-source-backed Component

test/convert/transformers/decomposedMetadataTransformer.test.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { DECOMPOSED_TOP_LEVEL_COMPONENT } from '../../mock/type-constants/custom
1717
import { ComponentSet, ForceIgnore, registry, RegistryAccess, SourceComponent } from '../../../src';
1818
import { XML_NS_KEY, XML_NS_URL } from '../../../src/common';
1919
import { ConvertContext } from '../../../src/convert/convertContext/convertContext';
20+
import { simpleKey } from '../../../src/collections/componentSet';
2021

2122
const registryAccess = new RegistryAccess();
2223

@@ -28,15 +29,15 @@ describe('DecomposedMetadataTransformer', () => {
2829
const component = decomposed.DECOMPOSED_COMPONENT;
2930

3031
describe('toMetadataFormat', () => {
31-
it('should defer write operations and set context state when a child components are given', async () => {
32+
it('should defer write operations and set context state when child components are given', async () => {
3233
const [child1, child2] = component.getChildren();
3334
const context = new ConvertContext();
3435
const transformer = new DecomposedMetadataTransformer(registryAccess, context);
3536

3637
expect(await transformer.toMetadataFormat(child1)).to.deep.equal([]);
3738
expect(await transformer.toMetadataFormat(child2)).to.deep.equal([]);
3839
expect(context.recomposition.transactionState.size).to.deep.equal(1);
39-
expect(context.recomposition.transactionState.get(component.fullName)).to.deep.equal({
40+
expect(context.recomposition.transactionState.get(simpleKey(component))).to.deep.equal({
4041
component,
4142
children: new ComponentSet([child1, child2], registryAccess),
4243
});
@@ -49,7 +50,7 @@ describe('DecomposedMetadataTransformer', () => {
4950
expect(await transformer.toMetadataFormat(component)).to.deep.equal([]);
5051
expect(context.recomposition.transactionState.size).to.equal(1);
5152

52-
expect(context.recomposition.transactionState.get(component.fullName)).to.deep.equal({
53+
expect(context.recomposition.transactionState.get(simpleKey(component))).to.deep.equal({
5354
component,
5455
children: new ComponentSet(component.getChildren(), registryAccess),
5556
});
@@ -65,11 +66,11 @@ describe('DecomposedMetadataTransformer', () => {
6566
expect(await transformer.toMetadataFormat(component)).to.deep.equal([]);
6667
expect(context.recomposition.transactionState.size).to.deep.equal(1);
6768

68-
const stateValue = context.recomposition.transactionState.get(component.fullName);
69+
const stateValue = context.recomposition.transactionState.get(simpleKey(component));
6970
assert(stateValue, 'expected stateValue to be defined');
7071
expect(stateValue.component).to.deep.equal(component);
7172
expect(stateValue.children?.size).to.deep.equal(2);
72-
expect(context.recomposition.transactionState.get(component.fullName)).to.deep.equal({
73+
expect(context.recomposition.transactionState.get(simpleKey(component))).to.deep.equal({
7374
component,
7475
children: new ComponentSet([child1, child2], registryAccess),
7576
});
@@ -592,9 +593,7 @@ describe('DecomposedMetadataTransformer', () => {
592593

593594
const result = await transformer.toSourceFormat({ component, mergeWith: componentToMerge });
594595
expect(result).to.be.empty;
595-
expect(
596-
context.decomposition.transactionState.get(`${mergeComponentChild.type.name}#${mergeComponentChild.fullName}`)
597-
).to.deep.equal({
596+
expect(context.decomposition.transactionState.get(simpleKey(mergeComponentChild))).to.deep.equal({
598597
origin: component,
599598
writeInfo: {
600599
source: new JsToXml({
@@ -635,7 +634,7 @@ describe('DecomposedMetadataTransformer', () => {
635634

636635
const result = await transformer.toSourceFormat({ component, mergeWith });
637636
expect(result).to.be.empty;
638-
expect(context.decomposition.transactionState.get(`${type.name}#${fullName}`)).to.deep.equal({
637+
expect(context.decomposition.transactionState.get(simpleKey(component))).to.deep.equal({
639638
origin: component,
640639
writeInfo: {
641640
source: new JsToXml({

test/convert/transformers/nonDecomposedMetadataTransformer.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { nonDecomposed } from '../../mock';
1111
import { NonDecomposedMetadataTransformer } from '../../../src/convert/transformers/nonDecomposedMetadataTransformer';
1212
import { ComponentSet, registry, RegistryAccess, SourceComponent } from '../../../src';
1313
import { ConvertContext } from '../../../src/convert/convertContext/convertContext';
14+
import { simpleKey } from '../../../src/collections/componentSet';
1415

1516
describe('NonDecomposedMetadataTransformer', () => {
1617
const $$ = new TestContext();
@@ -28,7 +29,7 @@ describe('NonDecomposedMetadataTransformer', () => {
2829
expect(await transformer.toMetadataFormat(child2)).to.deep.equal([]);
2930

3031
expect(context.recomposition.transactionState.size).to.equal(1);
31-
expect(context.recomposition.transactionState.get(component.fullName)).to.deep.equal({
32+
expect(context.recomposition.transactionState.get(simpleKey(component))).to.deep.equal({
3233
component,
3334
children: new ComponentSet([child1, child2]),
3435
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<actionOverrides>
4+
<actionName>WebsiteHighlightAction</actionName>
5+
<formFactor>Small</formFactor>
6+
<type>Default</type>
7+
</actionOverrides>
8+
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
9+
<enableFeeds>true</enableFeeds>
10+
<enableHistory>false</enableHistory>
11+
<externalSharingModel>Private</externalSharingModel>
12+
<searchLayouts>
13+
<customTabListAdditionalFields>ACCOUNT.NAME</customTabListAdditionalFields>
14+
<customTabListAdditionalFields>ACCOUNT.ADDRESS1_CITY</customTabListAdditionalFields>
15+
<customTabListAdditionalFields>ACCOUNT.PHONE1</customTabListAdditionalFields>
16+
</searchLayouts>
17+
<sharingModel>ReadWrite</sharingModel>
18+
<fields>
19+
<fullName>AccountNumber</fullName>
20+
<trackFeedHistory>false</trackFeedHistory>
21+
</fields>
22+
<fields>
23+
<fullName>AccountSource</fullName>
24+
<trackFeedHistory>false</trackFeedHistory>
25+
<type>Picklist</type>
26+
</fields>
27+
</CustomObject>

test/snapshot/sampleProjects/preset-workflow/__snapshots__/verify-md-files.expected/package.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<types>
4+
<members>Account.AccountNumber</members>
5+
<members>Account.AccountSource</members>
6+
<name>CustomField</name>
7+
</types>
8+
<types>
9+
<members>Account</members>
10+
<name>CustomObject</name>
11+
</types>
312
<types>
413
<members>emailtest/MarketingProductInquiryResponse</members>
514
<name>EmailTemplate</name>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<actionOverrides>
4+
<actionName>WebsiteHighlightAction</actionName>
5+
<formFactor>Small</formFactor>
6+
<type>Default</type>
7+
</actionOverrides>
8+
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
9+
<enableFeeds>true</enableFeeds>
10+
<enableHistory>false</enableHistory>
11+
<externalSharingModel>Private</externalSharingModel>
12+
<searchLayouts>
13+
<customTabListAdditionalFields>ACCOUNT.NAME</customTabListAdditionalFields>
14+
<customTabListAdditionalFields>ACCOUNT.ADDRESS1_CITY</customTabListAdditionalFields>
15+
<customTabListAdditionalFields>ACCOUNT.PHONE1</customTabListAdditionalFields>
16+
</searchLayouts>
17+
<sharingModel>ReadWrite</sharingModel>
18+
</CustomObject>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<fullName>AccountNumber</fullName>
4+
<trackFeedHistory>false</trackFeedHistory>
5+
</CustomField>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<fullName>AccountSource</fullName>
4+
<trackFeedHistory>false</trackFeedHistory>
5+
<type>Picklist</type>
6+
</CustomField>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
3+
<actionOverrides>
4+
<actionName>WebsiteHighlightAction</actionName>
5+
<formFactor>Small</formFactor>
6+
<type>Default</type>
7+
</actionOverrides>
8+
<compactLayoutAssignment>SYSTEM</compactLayoutAssignment>
9+
<enableFeeds>true</enableFeeds>
10+
<enableHistory>false</enableHistory>
11+
<externalSharingModel>Private</externalSharingModel>
12+
<searchLayouts>
13+
<customTabListAdditionalFields>ACCOUNT.NAME</customTabListAdditionalFields>
14+
<customTabListAdditionalFields>ACCOUNT.ADDRESS1_CITY</customTabListAdditionalFields>
15+
<customTabListAdditionalFields>ACCOUNT.PHONE1</customTabListAdditionalFields>
16+
</searchLayouts>
17+
<sharingModel>ReadWrite</sharingModel>
18+
<fields>
19+
<fullName>AccountNumber</fullName>
20+
<trackFeedHistory>false</trackFeedHistory>
21+
</fields>
22+
<fields>
23+
<fullName>AccountSource</fullName>
24+
<trackFeedHistory>false</trackFeedHistory>
25+
<type>Picklist</type>
26+
</fields>
27+
</CustomObject>

0 commit comments

Comments
 (0)