Skip to content

Commit

Permalink
chore: a lot of changes, writing xml in dirs, now to group by object
Browse files Browse the repository at this point in the history
  • Loading branch information
WillieRuemmele committed Aug 29, 2024
1 parent 8a29f76 commit 4b24bd8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 36 deletions.
52 changes: 33 additions & 19 deletions src/convert/transformers/filePerChildTypeMetadataTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@

import { dirname, join } from 'node:path';
import fs from 'node:fs';
import { AnyJson, JsonMap, ensureString, isJsonMap } from '@salesforce/ts-types';
import { ensureArray } from '@salesforce/kit';
import { AnyJson, JsonMap, ensureString } from '@salesforce/ts-types';
import { Messages } from '@salesforce/core';
import { calculateRelativePath } from '../../utils/path';
import { ForceIgnore } from '../../resolve/forceIgnore';
import { extractUniqueElementValue, objectHasSomeRealValues } from '../../utils/decomposed';
import { objectHasSomeRealValues } from '../../utils/decomposed';
import type { MetadataComponent } from '../../resolve/types';
import { type MetadataType } from '../../registry/types';
import { SourceComponent } from '../../resolve/sourceComponent';
Expand Down Expand Up @@ -59,7 +58,6 @@ export class FilePerChildTypeMetadataTransformer extends BaseMetadataTransformer
// noop since the finalizer will push the writes to the component writer
return [];
}

public async toSourceFormat({ component, mergeWith }: ToSourceFormatInput): Promise<WriteInfo[]> {
const forceIgnore = component.getForceIgnore();

Expand All @@ -77,15 +75,17 @@ export class FilePerChildTypeMetadataTransformer extends BaseMetadataTransformer
const writeInfosForChildren = composedMetadata
.filter(hasChildTypeId)
.map(addChildType)
.flatMap(({ tagValue, childType }) =>
// iterate each array member if it's Object-like (ex: customField of a CustomObject)
ensureArray(tagValue)
.filter(isJsonMap)
.map(toInfoContainer(mergeWith)(component)(childType))
.filter(forceIgnoreAllowsComponent(forceIgnore)) // only process child types that aren't forceignored
.map(handleUnaddressableChildAlone(composedMetadata.length)(parentXmlObject)(stateSetter))
.flatMap(getChildWriteInfos(stateSetter)(childrenOfMergeComponent))
);
.map((c) => {
if (c.childType.directoryName) {
// merge all child types that will end up in the same file
return toInfoContainer(mergeWith)(component)(c.childType)(c.tagValue as JsonMap);
} else {
return toInfoContainer(mergeWith)(component)(c.childType)(c.tagValue as JsonMap);
}
})
.filter(forceIgnoreAllowsComponent(forceIgnore))
.map(handleUnaddressableChildAlone(composedMetadata.length)(parentXmlObject)(stateSetter))
.flatMap(getChildWriteInfos(stateSetter)(childrenOfMergeComponent));

const writeInfoForParent = mergeWith
? getWriteInfosFromMerge(mergeWith)(stateSetter)(parentXmlObject)(component)
Expand Down Expand Up @@ -150,7 +150,9 @@ const getChildWriteInfos =
(stateSetter: StateSetter) =>
(childrenOfMergeComponent: ComponentSet) =>
({ mergeWith, childComponent, value, entryName }: InfoContainer): WriteInfo[] => {
const source = objectToSource(childComponent.type.name)(value);
const source = objectToSource(childComponent.parent!.type.name)(childComponent.type.name)(
value as unknown as JsonMap[]
);
// if there's nothing to merge with, push write operation now to default location
if (!mergeWith) {
return [{ source, output: getDefaultOutput(childComponent) }];
Expand Down Expand Up @@ -265,9 +267,10 @@ const getDefaultOutput = (component: MetadataComponent): SourcePath => {
// there could be a '.' inside the child name (ex: PermissionSet.FieldPermissions.field uses Obj__c.Field__c)
const childName = tail.length ? tail.join('.') : undefined;
const output = join(
parent?.type.strategies?.decomposition === 'folderPerType' ? type.directoryName : '',
parent?.type.strategies?.decomposition === 'filePerType' ? type.directoryName : '',
`${childName ?? baseName}.${ensureString(component.type.suffix)}${META_XML_SUFFIX}`
);
// const output = join(type.directoryName, `${baseName}.${ensureString(component.type.suffix)}${META_XML_SUFFIX}`);
return join(calculateRelativePath('source')({ self: parent?.type ?? type })(fullName)(baseName), output);
};

Expand Down Expand Up @@ -298,13 +301,23 @@ type InfoContainer = {
mergeWith?: SourceComponent;
};

/** returns an data structure with lots of context information in it */
// const toInfoContainer =
// (mergeWith: SourceComponent | undefined) =>
// (parent: SourceComponent) =>
// (c: MetadataType) =>
// (tagValue: JsonMap[]): InfoContainer => {
// const entryName = childType.directoryName
// ? tagValue[childType.uniqueIdElement]?.split('.')?.at(0) ?? parent.name
// : parent.name;
/** returns a data structure with lots of context information in it */
const toInfoContainer =
(mergeWith: SourceComponent | undefined) =>
(parent: SourceComponent) =>
(childType: MetadataType) =>
(tagValue: JsonMap): InfoContainer => {
const entryName = ensureString(extractUniqueElementValue(tagValue, childType.uniqueIdElement));
const entryName = childType.directoryName
? ((tagValue as unknown as JsonMap[]).at(0)?.[childType.uniqueIdElement!] as string).split('.')[0]
: parent.name;
return {
parentComponent: parent,
entryName,
Expand All @@ -325,9 +338,10 @@ const forceIgnoreAllowsComponent =

/** wrap some xml in the Metadata type and add the NS stuff */
const objectToSource =
(parentType: string) =>
(childTypeName: string) =>
(obj: JsonMap): JsToXml =>
new JsToXml({ [childTypeName]: { [XML_NS_KEY]: XML_NS_URL, ...obj } });
(obj: JsonMap[]): JsToXml =>
new JsToXml({ [parentType]: { [childTypeName]: obj } });

/** filter out the children and create the remaining parentXml */
const buildParentXml =
Expand Down
2 changes: 1 addition & 1 deletion src/convert/transformers/metadataTransformerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class MetadataTransformerFactory {
return new StaticResourceMetadataTransformer(this.registry, this.context);
case 'nonDecomposed':
return new NonDecomposedMetadataTransformer(this.registry, this.context);
case 'filePerChild':
case 'filePerType':
return new FilePerChildTypeMetadataTransformer(this.registry, this.context);
case 'decomposedLabels':
return component.type.name === 'CustomLabels'
Expand Down
24 changes: 12 additions & 12 deletions src/registry/presets/decomposePermissionSetBeta2.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,55 +58,55 @@
},
"types": {
"applicationvisibility": {
"directoryName": "applicationVisibilities",
"directoryName": "",
"id": "applicationvisibility",
"isAddressable": false,
"name": "ApplicationVisibility",
"suffix": "applicationVisibility",
"uniqueIdElement": "application"
},
"classaccess": {
"directoryName": "classAccesses",
"directoryName": "",
"id": "classaccess",
"isAddressable": false,
"name": "ClassAccess",
"suffix": "classAccess",
"uniqueIdElement": "apexClass"
},
"custommetadatatypeaccess": {
"directoryName": "customMetadataTypeAccesses",
"directoryName": "",
"id": "custommetadatatypeaccess",
"isAddressable": false,
"name": "CustomMetadataTypeAccess",
"suffix": "customMetadataTypeAccess",
"uniqueIdElement": "name"
},
"custompermissions": {
"directoryName": "customPermissions",
"directoryName": "",
"id": "custompermissions",
"isAddressable": false,
"name": "CustomPermission",
"suffix": "customPermission",
"uniqueIdElement": "name"
},
"customsettingaccess": {
"directoryName": "customSettingAccesses",
"directoryName": "",
"id": "customsettingaccess",
"isAddressable": false,
"name": "CustomSettingAccess",
"suffix": "customSettingAccess",
"uniqueIdElement": "name"
},
"externalcredentialprincipalaccess": {
"directoryName": "externalCredentialPrincipalAccesses",
"directoryName": "",
"id": "externalcredentialprincipalaccess",
"isAddressable": false,
"name": "ExternalCredentialPrincipalAccess",
"suffix": "externalCredentialPrincipalAccess",
"uniqueIdElement": "externalCredentialPrincipal"
},
"externaldatasourceaccess": {
"directoryName": "externalDataSourceAccesses",
"directoryName": "",
"id": "externaldatasourceaccess",
"isAddressable": false,
"name": "ExternalDataSourceAccess",
Expand All @@ -123,7 +123,7 @@
"uniqueIdElement": "field"
},
"flowaccess": {
"directoryName": "flowAccesses",
"directoryName": "",
"id": "flowaccess",
"isAddressable": false,
"name": "FlowAccess",
Expand All @@ -140,7 +140,7 @@
"uniqueIdElement": "object"
},
"pageaccess": {
"directoryName": "pageAccesses",
"directoryName": "",
"id": "pageaccess",
"isAddressable": false,
"name": "PageAccess",
Expand All @@ -166,7 +166,7 @@
"uniqueIdElement": "tab"
},
"userpermission": {
"directoryName": "userPermissions",
"directoryName": "",
"id": "userpermission",
"isAddressable": false,
"name": "UserPermission",
Expand All @@ -180,8 +180,8 @@
"name": "PermissionSet",
"strategies": {
"decomposition": "filePerType",
"adapter": "filePerChild",
"transformer": "filePerChild"
"adapter": "filePerType",
"transformer": "filePerType"
},
"strictDirectoryName": true,
"suffix": "permissionset",
Expand Down
6 changes: 3 additions & 3 deletions src/registry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ export type MetadataType = {
| 'decomposed'
| 'digitalExperience'
| 'bundle'
| 'filePerChild'
| 'filePerType'
| 'default';
transformer?: 'decomposed' | 'staticResource' | 'nonDecomposed' | 'standard' | 'decomposedLabels' | 'filePerChild';
decomposition?: 'topLevel' | 'folderPerType' | 'filePerChild';
transformer?: 'decomposed' | 'staticResource' | 'nonDecomposed' | 'standard' | 'decomposedLabels' | 'filePerType';
decomposition?: 'topLevel' | 'folderPerType' | 'filePerType';
recomposition?: 'startEmpty';
};
};
Expand Down
2 changes: 1 addition & 1 deletion src/resolve/adapters/sourceAdapterFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class SourceAdapterFactory {
return new MixedContentSourceAdapter(type, this.registry, forceIgnore, this.tree);
case 'digitalExperience':
return new DigitalExperienceSourceAdapter(type, this.registry, forceIgnore, this.tree);
case 'filePerChild':
case 'filePerType':
return new FilePerChildTypeSourceAdapter(type, this.registry, forceIgnore, this.tree);
case 'default':
case undefined:
Expand Down

0 comments on commit 4b24bd8

Please sign in to comment.