import { IntrospectionFileSchemaObject } from '@allianz/taly-core/schemas';
import { BuilderContext, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
import { LogEntry } from '@angular-devkit/core/src/logger';
import fs from 'fs';
import { basename, join, relative } from 'path';
import { scan } from 'rxjs/operators';
import util from 'util';
import { collectBuildingBlockFolders } from '../../shared/metadata-utils/collect-building-block-folders';
import { runIntrospectionOnFiles } from './run-introspection';
import { IntrospectionExecutorSchema } from './schema';
const writeFile = util.promisify(fs.writeFile);
/**
* Write our introspection, include a hash over the given content & a date.
*/
async function writeIntrospection(outputFile: string, content: IntrospectionFileSchemaObject[]) {
const introspectionData = [...content];
await writeFile(outputFile, JSON.stringify(introspectionData, null, 2));
}
interface Options {
project: string;
outputFile: string;
}
async function run(
options: IntrospectionExecutorSchema,
context: BuilderContext
): Promise<{ success: boolean }> {
const logger = context.logger.createChild('Introspection Builder');
const logCompleted$ = logger
.pipe(
scan((hasError: boolean, logEntry: LogEntry) => {
return hasError || logEntry.level === 'error';
}, false)
)
.toPromise();
logger.info(`Running Introspection Executor on '${options.project}'`);
// TODO: infer project path from executor context
const projectPath = join(context.workspaceRoot, options.project);
// TODO: use sane default for outputFile
const outputFile = join(context.workspaceRoot, options.outputFile);
const collection = await collectBuildingBlockFolders(projectPath);
const buildingBlockComponents = collection.result.map((folderName) => {
return join(folderName, `/${basename(folderName)}.component.ts`);
});
const introspectionFn = runIntrospectionOnFiles(context, logger);
const results: IntrospectionFileSchemaObject[] = introspectionFn(
projectPath,
buildingBlockComponents
);
await writeIntrospection(outputFile, results);
logger.complete();
return logCompleted$
.then((hasError) => {
if (!hasError) {
context.logger.info(
`Success ✓\nIntrospection written to '${relative(context.workspaceRoot, outputFile)}'`
);
} else {
context.logger.error(
'The executor failed to create a proper Introspection file due to the above error(s).'
);
}
return { success: !hasError };
})
.catch((error) => {
context.logger.error(error.message);
return { success: false };
});
}
export default createBuilder<JsonObject & Options>(run);