Skip to content

Commit

Permalink
refactor: milestone, functional album except workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
catalandres committed Dec 24, 2023
1 parent 879e5fe commit db66eb7
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 5 deletions.
41 changes: 37 additions & 4 deletions src/shared/Atlas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import { SfProject, NamedPackageDir } from '@salesforce/core';
import * as ExcelJS from 'exceljs';
import { Spinner } from '@salesforce/sf-plugins-core';
import * as Metadata from './metadata/types/metadata.js';
import { Extended } from './metadata/file/index.js';
import { XmlParser } from './XmlParser.js';

import { Extended, Album, Definition, ALL_DEFINITIONS, getExtension } from './metadata/file/index.js';
// TO DO
// - flexipages / lightning pages
// - flows
// - global value sets
// - lightning components

export class Atlas {
public projectPath: string;

public apexClasses: Array<Extended<Metadata.ApexClass>> = [];
public apexTriggers: Array<Extended<Metadata.ApexTrigger>> = [];
public visualforcePages: Array<Extended<Metadata.ApexPage>> = [];
Expand Down Expand Up @@ -50,12 +47,34 @@ export class Atlas {
public flows: Array<Extended<Metadata.Flow>> = [];
// public globalValueSets: Array<Extended<Metadata.GlobalValueSet>> = [];

public projectPath: string;
public album: Album = {};
private fileDefinitionsByExtension: Map<string, Definition>;
private metadataExtensions: Set<string>;

public constructor(projectPath: string) {
this.projectPath = projectPath;
this.fileDefinitionsByExtension = new Map();
for (const thisFileDefinition of ALL_DEFINITIONS) {
this.album[thisFileDefinition.list] = [];
if (thisFileDefinition.extension) {
this.fileDefinitionsByExtension.set(thisFileDefinition.extension, thisFileDefinition);
}
}
this.metadataExtensions = new Set(this.fileDefinitionsByExtension.keys());
}

public async initialize(spinner: Spinner): Promise<void> {
const allFiles = await getAllProjectFiles(this.projectPath);
const allMetadataFiles = allFiles.filter((theFile) => this.isMetadataFile(theFile));

for (const thisFile of allMetadataFiles) {
spinner.status = thisFile;
const thisDefinition: Definition = this.fileDefinitionsByExtension.get(getExtension(thisFile))!;
const xml = fs.readFileSync(thisFile, 'utf-8');
this.absorb(XmlParser.getMetadata<Extended<typeof thisDefinition.metadataType>>(xml, thisFile, thisDefinition));
}

for (const thisFile of allFiles) {
spinner.status = thisFile;

Expand Down Expand Up @@ -171,6 +190,16 @@ export class Atlas {
}
}

private absorb(album: Album): void {
for (const thisList of Object.keys(album)) {
if (!this.album[thisList]) {
this.album[thisList] = [];
}
this.album[thisList].push(...album[thisList]);
}
}

// eslint-disable-next-line @typescript-eslint/member-ordering
public async writeXlsx(): Promise<string> {
const workbook = new ExcelJS.default.Workbook();

Expand Down Expand Up @@ -834,6 +863,10 @@ export class Atlas {
await workbook.xlsx.writeFile(fileName);
return fileName;
}

private isMetadataFile(thisFile: string): boolean {
return this.metadataExtensions.has(getExtension(thisFile));
}
}

async function getAllProjectFiles(projectPath: string): Promise<string[]> {
Expand Down
47 changes: 46 additions & 1 deletion src/shared/XmlParser.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable @typescript-eslint/member-ordering */
import * as path from 'node:path';
import * as xml2js from 'xml2js';
import * as Metadata from './metadata/types/metadata.js';
import { Extended } from './metadata/file/index.js';
import { array } from './array.js';
import { Extended, ExtendedMetadata, Album, Definition } from './metadata/file/index.js';

const nameRegEx = new RegExp('.+/([^.]*)');
const parserOptions: xml2js.ParserOptions = {
Expand All @@ -17,6 +18,50 @@ const parserOptions: xml2js.ParserOptions = {
};

export class XmlParser {
public static getMetadata<T extends ExtendedMetadata>(xml: string, fileName: string, definition: Definition): Album {
const album: Album = {};
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
xml2js.parseString(xml, parserOptions, (err, result: Record<string, T>) => {
const theRecord = result[definition.name];
if (!definition.container) {
XmlParser.treatRecord(theRecord, definition, fileName);
album[definition.list] = [theRecord];
}
if (definition.children) {
for (const listName of definition.children.keys()) {
const thisDefinition = definition.children.get(listName) as Definition;
album[thisDefinition.list] = [];
const records = array(theRecord[listName]) as Array<Extended<typeof thisDefinition.metadataType>>;
for (const thisRecord of records) {
XmlParser.treatRecord(thisRecord, thisDefinition, fileName);
album[thisDefinition.list].push(thisRecord as T);
}
}
}
});
return album;
}

private static treatRecord<T extends ExtendedMetadata>(
record: Extended<T>,
metadata: Definition,
fileName: string
): void {
record.fileName = fileName;
if (metadata.setName) {
record.name = metadata.setName(fileName);
}
if (metadata.setObjectname) {
record.objectName = metadata.setObjectname(fileName);
}
if (metadata.setFullName) {
record.fullName = metadata.setFullName(fileName);
}
if (metadata.transform) {
metadata.transform(record);
}
}

public static getApexClasses(xml: string, fileName: string): Array<Extended<Metadata.ApexClass>> {
const apexClasses: Array<Extended<Metadata.ApexClass>> = [];
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
Expand Down

0 comments on commit db66eb7

Please sign in to comment.