Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sh/exclude custom field translations #444

Merged
merged 4 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/collections/componentSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,17 @@ export class ComponentSet extends LazyCollection<MetadataComponent> {
if (type.folderContentType) {
type = this.registry.getTypeByName(type.folderContentType);
}
addToTypeMap(type.name, fullName);
if (type.isAddressable !== false) {
addToTypeMap(type.name, fullName);
}

// Add children
const componentMap = components.get(key);
for (const comp of componentMap.values()) {
for (const child of comp.getChildren()) {
addToTypeMap(child.type.name, child.fullName);
if (child.isAddressable) {
addToTypeMap(child.type.name, child.fullName);
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/registry/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,8 @@
"id": "customfieldtranslation",
"name": "CustomFieldTranslation",
"directoryName": "fields",
"suffix": "fieldTranslation"
"suffix": "fieldTranslation",
"isAddressable": false
}
},
"suffixes": {
Expand Down
4 changes: 4 additions & 0 deletions src/registry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ export interface MetadataType {
* The xml attribute used as the unique identifier when parsing the xml
*/
uniqueIdElement?: string;
/**
* Whether the component is supported by the Metadata API and therefore should be included within a manifest.
*/
isAddressable?: boolean;
/**
* Type definitions for child types, if the type has any.
*
Expand Down
17 changes: 17 additions & 0 deletions src/resolve/sourceComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,21 @@ export class SourceComponent implements MetadataComponent {
get tree(): TreeContainer {
return this._tree;
}

/**
* Returns whether this component type is supported by the Metadata API
* and therefore should have an entry added to the manifest.
*
* This is defined on the type in the registry. The type is required to
* be in the registry for proper classification and for possible use in
* decomposition/recomposition.
*
* Default value is true, so the only way to return false is to explicitly
* set it in the registry as false.
*
* E.g., CustomFieldTranslation.
*/
get isAddressable(): boolean {
return this.type.isAddressable !== false;
}
}
59 changes: 59 additions & 0 deletions test/collections/componentSet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
MetadataApiRetrieve,
MetadataComponent,
MetadataResolver,
MetadataType,
RegistryAccess,
} from '../../src';
import { ComponentSetError } from '../../src/errors';
Expand Down Expand Up @@ -418,6 +419,64 @@ describe('ComponentSet', () => {
]);
});

it('should exclude components that are not addressable as defined in the registry', () => {
const type: MetadataType = {
id: 'customfieldtranslation',
name: 'CustomFieldTranslation',
directoryName: 'fields',
suffix: 'fieldTranslation',
isAddressable: false,
};
const set = new ComponentSet();
set.add(new SourceComponent({ name: type.name, type }));
expect(set.getObject().Package.types).to.deep.equal([]);
});

it('should exclude child components that are not addressable as defined in the registry', () => {
const childType: MetadataType = {
id: 'customfieldtranslation',
name: 'CustomFieldTranslation',
directoryName: 'fields',
suffix: 'fieldTranslation',
isAddressable: false,
};
const type: MetadataType = {
id: 'customobjecttranslation',
name: 'CustomObjectTranslation',
suffix: 'objectTranslation',
directoryName: 'objectTranslations',
inFolder: false,
strictDirectoryName: true,
children: {
types: {
customfieldtranslation: childType,
},
suffixes: {
fieldTranslation: 'customfieldtranslation',
},
directories: {
fields: 'customfieldtranslation',
},
},
strategies: {
adapter: 'decomposed',
transformer: 'decomposed',
decomposition: 'topLevel',
},
};
const set = new ComponentSet();
const testComp = new SourceComponent({ name: type.name, type });
const childComp = new SourceComponent({ name: childType.name, type: childType });
$$.SANDBOX.stub(testComp, 'getChildren').returns([childComp]);
set.add(testComp);
expect(set.getObject().Package.types).to.deep.equal([
{
name: 'CustomObjectTranslation',
members: ['CustomObjectTranslation'],
},
]);
});

/**
* If component set keys are incorrectly handled, child component names may not be returned properly.
*/
Expand Down
17 changes: 17 additions & 0 deletions test/resolve/sourceComponent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
MATCHING_RULES_COMPONENT,
} from '../mock/registry/type-constants/nonDecomposedConstants';
import { createSandbox } from 'sinon';
import { MetadataType } from '../../src';
import { join } from 'path';
import { DecomposedSourceAdapter } from '../../src/resolve/adapters';
import { TypeInferenceError } from '../../src/errors';
Expand All @@ -38,6 +39,22 @@ describe('SourceComponent', () => {
expect(DECOMPOSED_COMPONENT.fullName).to.equal(DECOMPOSED_COMPONENT.name);
});

it('should return whether the type is addressable', () => {
const type: MetadataType = {
id: 'customfieldtranslation',
name: 'CustomFieldTranslation',
directoryName: 'fields',
suffix: 'fieldTranslation',
};
expect(new SourceComponent({ name: type.name, type }).isAddressable).to.equal(true);
type.isAddressable = false;
expect(new SourceComponent({ name: type.name, type }).isAddressable).to.equal(false);
type.isAddressable = true;
expect(new SourceComponent({ name: type.name, type }).isAddressable).to.equal(true);
type.isAddressable = undefined;
expect(new SourceComponent({ name: type.name, type }).isAddressable).to.equal(true);
});

it('should return correct markedForDelete status', () => {
expect(COMPONENT.isMarkedForDelete()).to.be.false;
try {
Expand Down