Skip to content

Commit

Permalink
feat: source to madapi finalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Aug 8, 2024
1 parent 8b80738 commit e8676fb
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/convert/convertContext/convertContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import { RecompositionFinalizer } from './recompositionFinalizer';
import { NonDecompositionFinalizer } from './nonDecompositionFinalizer';
import { DecompositionFinalizer } from './decompositionFinalizer';
import { ConvertTransactionFinalizer } from './transactionFinalizer';

import { DecomposedCustomLabelsFinalizer } from './decomposedCustomLabelFinalizer';
/**
* A state manager over the course of a single metadata conversion call.
*/
export class ConvertContext {
public readonly decomposition = new DecompositionFinalizer();
public readonly recomposition = new RecompositionFinalizer();
public readonly nonDecomposition = new NonDecompositionFinalizer();
public readonly decomposedLabels = new DecomposedCustomLabelsFinalizer();

// eslint-disable-next-line @typescript-eslint/require-await
public async *executeFinalizers(defaultDirectory?: string): AsyncIterable<WriterFormat[]> {
Expand Down
70 changes: 70 additions & 0 deletions src/convert/convertContext/decomposedCustomLabelFinalizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2023, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { join } from 'node:path';
import { ensure, JsonMap } from '@salesforce/ts-types';
import type { CustomLabel } from '@jsforce/jsforce-node/lib/api/metadata';
import { MetadataType } from '../../registry';
import { XML_NS_KEY, XML_NS_URL } from '../../common/constants';
import { JsToXml } from '../streams';
import { WriterFormat } from '../types';
import { ConvertTransactionFinalizer } from './transactionFinalizer';

type CustomLabelState = {
/*
* Incoming child xml (CustomLabel) keyed by label fullname
*/
customLabelByFullName: Map<string, CustomLabel>;
};

/**
* Merges child components that share the same parent in the conversion pipeline
* into a single file.
*
* Inserts unclaimed child components into the parent that belongs to the default package
*/
export class DecomposedCustomLabelsFinalizer extends ConvertTransactionFinalizer<CustomLabelState> {
public transactionState: CustomLabelState = {
customLabelByFullName: new Map(),
};

/** to support custom presets (the only way this code should get hit at all pass in the type from a transformer that has registry access */
public customLabelsType?: MetadataType;

// have to maintain the existing interface
// eslint-disable-next-line @typescript-eslint/require-await, @typescript-eslint/no-unused-vars
public async finalize(defaultDirectory?: string): Promise<WriterFormat[]> {
if (this.transactionState.customLabelByFullName.size === 0) {
return [];
}
return [
{
component: {
type: ensure(this.customLabelsType, 'DecomposedCustomLabelsFinalizer should have set customLabelsType'),
fullName: 'CustomLabels',
},
writeInfos: [
{
output: join(
ensure(this.customLabelsType?.directoryName, 'directoryName missing from customLabels type'),
'CustomLabels.labels'
),
source: new JsToXml(generateXml(this.transactionState.customLabelByFullName)),
},
],
},
];
}
}

/** Return a json object that's built up from the mergeMap children */
const generateXml = (children: Map<string, CustomLabel>): JsonMap => ({
['CustomLabels']: {
[XML_NS_KEY]: XML_NS_URL,
// for CustomLabels, that's `labels`
labels: Array.from(children.values()),
},
});
13 changes: 7 additions & 6 deletions src/convert/transformers/decomposeLabelsTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { DefaultMetadataTransformer } from './defaultMetadataTransformer';

/* Use for the metadata type CustomLabels */
export class LabelsMetadataTransformer extends DefaultMetadataTransformer {
// CustomLabels file => CustomLabel
/** CustomLabels file => Array of CustomLabel WriteInfo (one for each label) */
public async toSourceFormat({ component, mergeSet }: ToSourceFormatInput): Promise<WriteInfo[]> {
const labelType = this.registry.getTypeByName('CustomLabel');
const partiallyAppliedPathCalculator = calculateRelativePath('source')({
Expand All @@ -36,12 +36,13 @@ export class LabelsMetadataTransformer extends DefaultMetadataTransformer {

/* Use for the metadata type CustomLabel */
export class LabelMetadataTransformer extends DefaultMetadataTransformer {
// eslint-disable-next-line @typescript-eslint/require-await, class-methods-use-this, @typescript-eslint/no-unused-vars
public async toMetadataFormat(component: SourceComponent): Promise<WriteInfo[]> {
// TODO:
// read all each label from the recomposition state, regardless of parents
// merge them all to a single CustomLabels file
// write the CustomLabels file
// only need to do this once
this.context.decomposedLabels.customLabelsType ??= this.registry.getTypeByName('CustomLabels');
this.context.decomposedLabels.transactionState.customLabelByFullName.set(
component.fullName,
unwrapAndOmitNS('CustomLabel')(await component.parseXml()) as CustomLabel
);
return [];
}

Expand Down

0 comments on commit e8676fb

Please sign in to comment.