File
optionsIntrospectionResult
|
Type
|
OptionsContractType[]
|
import { InjectableMetadata, OptionsContractType, PluginType } from '@allianz/taly-core/schemas';
import { BuilderContext } from '@angular-devkit/architect';
import { strings } from '@angular-devkit/core';
import { Logger } from '@angular-devkit/core/src/logger';
import { basename } from 'path';
import { createIntrospectionContext } from '../../introspection/compat/utils/create-introspection-context';
import { inspectorFactory } from './base/create-inspector';
import { PluginFolderStats } from './utils/collect-plugin-folders';
import { findNgModuleClassFactory } from './utils/find-ng-module-class';
import {
injectableFileInspectionResult,
inspectInjectableClassFactory
} from './utils/inspect-injectable-class';
import { extractMdFileDataFactory } from './utils/markdown/extract-md-file-data';
import { MarkdownAttributes } from './utils/markdown/markdown-validators';
export interface PluginMetadataExtraction {
id: string;
ngModuleClassName: string;
pluginType: PluginType;
optionsIntrospectionResult: OptionsContractType[];
markdownAttributes: MarkdownAttributes;
injectable: InjectableMetadata;
}
export async function runPluginMetadata(
context: BuilderContext,
logger: Logger,
projectPath: string,
{
folderPath: pluginFolder,
moduleFilePath,
injectableFilePath,
markdownFilePath
}: PluginFolderStats
): Promise<PluginMetadataExtraction | undefined> {
let pluginMetadataExtraction: PluginMetadataExtraction = {} as PluginMetadataExtraction;
const basePluginFolder = basename(pluginFolder);
context.logger.info(`└── ${basePluginFolder}`);
const files = [moduleFilePath];
if (injectableFilePath) {
files.push(injectableFilePath);
}
const introspectionContext = createIntrospectionContext({
root: pluginFolder,
files,
context,
logger
});
if (!introspectionContext) {
logger.error(
`Unable to create introspection context for root ${projectPath}. This is most likely not an issue with the TALY Builder but rather an issue with your TypeScript configuration. Please verify that your TypeScript project is set up properly.`
);
return undefined;
}
logger.info(`• Inspecting '${basename(moduleFilePath)}'`);
const ngModuleClassSymbol = findNgModuleClassFactory(introspectionContext)(moduleFilePath);
if (!ngModuleClassSymbol) {
logger.error(
`Unable to find an @NgModule decorated class in "${moduleFilePath}". Please make sure to put your plugin's module definition in that file.`
);
return undefined;
}
const symbolName = ngModuleClassSymbol?.getName();
const inspectorFn = inspectorFactory(introspectionContext);
const optionsIntrospectionResult: OptionsContractType[] = inspectorFn(ngModuleClassSymbol);
pluginMetadataExtraction = {
...pluginMetadataExtraction,
id: getPluginId(symbolName),
ngModuleClassName: symbolName,
optionsIntrospectionResult
};
if (injectableFilePath) {
logger.info(`• Inspecting '${basename(injectableFilePath)}'`);
const injectableIntrospectionResult: injectableFileInspectionResult | undefined =
inspectInjectableClassFactory(introspectionContext, projectPath)(injectableFilePath);
if (!injectableIntrospectionResult) {
logger.error(
`Unable to find an @Injectable decorated class in "${injectableFilePath}". Please make sure to put your plugin's service definition in that file, or remove the file if it is not needed.`
);
return undefined;
}
pluginMetadataExtraction = {
...pluginMetadataExtraction,
pluginType: injectableIntrospectionResult?.pluginType,
injectable: injectableIntrospectionResult?.injectableClassData
};
} else {
pluginMetadataExtraction = { ...pluginMetadataExtraction, pluginType: PluginType.Other };
}
logger.info(`• Inspecting '${basename(markdownFilePath)}'`);
const markdownAttributes = await extractMdFileDataFactory(introspectionContext)(markdownFilePath);
pluginMetadataExtraction = {
...pluginMetadataExtraction,
markdownAttributes
};
return pluginMetadataExtraction;
}
function getPluginId(symbolName = '') {
const pluginId = strings.dasherize(symbolName).replace('-module', '');
return pluginId;
}