Skip to content

Commit 7b9a464

Browse files
fix: can retrive COFT with COT automatically (#517)
* fix: can retrive COFT with COT automatically * refactor: requiresParents -> unadressableWithoutParent Co-authored-by: Shane McLaughlin <[email protected]>
1 parent 2e30a2e commit 7b9a464

File tree

4 files changed

+93
-1
lines changed

4 files changed

+93
-1
lines changed

src/convert/transformers/decomposedMetadataTransformer.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { META_XML_SUFFIX, SourcePath, XML_NS_KEY, XML_NS_URL } from '../../commo
1313
import { ComponentSet } from '../../collections';
1414
import { DecompositionState } from '../convertContext';
1515
import { DecompositionStrategy } from '../../registry';
16+
import { normalizeToArray } from '../../utils';
1617
import { BaseMetadataTransformer } from './baseMetadataTransformer';
1718

1819
export class DecomposedMetadataTransformer extends BaseMetadataTransformer {
@@ -61,7 +62,7 @@ export class DecomposedMetadataTransformer extends BaseMetadataTransformer {
6162
const childTypeId = type.children?.directories[tagKey];
6263
if (childTypeId) {
6364
const childType = type.children.types[childTypeId];
64-
const tagValues = Array.isArray(tagValue) ? tagValue : [tagValue];
65+
const tagValues = normalizeToArray(tagValue);
6566
for (const value of tagValues as [{ fullName: string; name: string }]) {
6667
const entryName = value.fullName || value.name;
6768
const childComponent: MetadataComponent = {
@@ -74,6 +75,30 @@ export class DecomposedMetadataTransformer extends BaseMetadataTransformer {
7475
const source = new JsToXml({
7576
[childType.name]: Object.assign({ [XML_NS_KEY]: XML_NS_URL }, value),
7677
});
78+
79+
/*
80+
composedMetadata is a representation of the parent's xml
81+
if there is no CustomObjectTranslation in the org, the composedMetadata will be 2 entries
82+
the xml declaration, and a fields attribute, which points to the child CustomObjectFieldTranslation
83+
because CustomObjectFieldTranslation is the only metadata type with 'requiresParent' = true we can
84+
calculate if a CustomObjectTranslation was retrieved from the org (composedMetadata.length > 2), or,
85+
if we'll have to write an empty CustomObjectTranslation file (composedMetadata.length <=2).
86+
CustomObjectFieldTranslations are only addressable through their parent, and require a
87+
CustomObjectTranslation file to be present
88+
*/
89+
if (childType.unaddressableWithoutParent && composedMetadata.length <= 2) {
90+
parentXmlObject = {
91+
[component.type.name]: '',
92+
};
93+
this.setDecomposedState(childComponent, {
94+
foundMerge: false,
95+
writeInfo: {
96+
source: new JsToXml(parentXmlObject),
97+
output: this.getDefaultOutput(component),
98+
},
99+
});
100+
}
101+
77102
// if there's nothing to merge with, push write operation now to default location
78103
if (!mergeWith) {
79104
writeInfos.push({

src/registry/metadataRegistry.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@
850850
"directoryName": "fields",
851851
"suffix": "fieldTranslation",
852852
"isAddressable": false,
853+
"unaddressableWithoutParent": true,
853854
"uniqueIdElement": "name"
854855
}
855856
},

src/registry/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ export interface MetadataType {
9191
* Whether the component is supported by the Metadata API and therefore should be included within a manifest.
9292
*/
9393
isAddressable?: boolean;
94+
/**
95+
* Whether the component requires the parent to be present when deploying/retrieving
96+
*/
97+
unaddressableWithoutParent?: boolean;
9498

9599
/**
96100
* Whether or not components of the same type can be can be specified with the wildcard character, and by name in a manifest

test/convert/transformers/decomposedMetadataTransformer.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,68 @@ describe('DecomposedMetadataTransformer', () => {
336336
},
337337
]);
338338
});
339+
it('should create a parent xml when requiresParent = true on the child type', async () => {
340+
component.type.children.types.y.unaddressableWithoutParent = true;
341+
component.type.children.types.x.unaddressableWithoutParent = true;
342+
const { type, fullName } = component;
343+
const transformer = new DecomposedMetadataTransformer(mockRegistry);
344+
const root = join('main', 'default', type.directoryName, fullName);
345+
env.stub(component, 'parseXml').resolves({
346+
Decomposed: {
347+
ys: { fullName: 'child', test: 'testVal' },
348+
xs: [
349+
{ fullName: 'child2', test: 'testVal2' },
350+
{ fullName: 'child3', test: 'testVal3' },
351+
],
352+
},
353+
});
354+
355+
const result = await transformer.toSourceFormat(component);
356+
357+
expect(result).to.deep.equal([
358+
{
359+
source: new JsToXml({
360+
Y: {
361+
[XML_NS_KEY]: XML_NS_URL,
362+
fullName: 'child',
363+
test: 'testVal',
364+
},
365+
}),
366+
output: join(root, type.children.types.y.directoryName, 'child.y-meta.xml'),
367+
},
368+
{
369+
source: new JsToXml({
370+
X: {
371+
[XML_NS_KEY]: XML_NS_URL,
372+
fullName: 'child2',
373+
test: 'testVal2',
374+
},
375+
}),
376+
output: join(root, type.children.types.x.directoryName, 'child2.x-meta.xml'),
377+
},
378+
{
379+
source: new JsToXml({
380+
X: {
381+
[XML_NS_KEY]: XML_NS_URL,
382+
fullName: 'child3',
383+
test: 'testVal3',
384+
},
385+
}),
386+
output: join(root, type.children.types.x.directoryName, 'child3.x-meta.xml'),
387+
},
388+
// the new parent was written
389+
{
390+
source: new JsToXml({
391+
[type.name]: '',
392+
}),
393+
output: join(root, 'a.decomposed-meta.xml'),
394+
},
395+
]);
396+
397+
// reset to avoid interfering with other tests
398+
component.type.children.types.y.unaddressableWithoutParent = false;
399+
component.type.children.types.x.unaddressableWithoutParent = false;
400+
});
339401

340402
it('should handle decomposed parents with no files', async () => {
341403
const transformer = new DecomposedMetadataTransformer(mockRegistry);

0 commit comments

Comments
 (0)