@o3r/core
Version:
Core of the Otter Framework
192 lines • 11.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ngGenerateComponentContainer = exports.CONTAINER_FOLDER = void 0;
const path = require("node:path");
const schematics_1 = require("@angular-devkit/schematics");
const schematics_2 = require("@o3r/schematics");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const change_1 = require("@schematics/angular/utility/change");
const ts = require("typescript");
const configuration_1 = require("../../rule-factories/component/configuration");
const context_1 = require("../../rule-factories/component/context");
const fixture_1 = require("../../rule-factories/component/fixture");
const rules_engine_1 = require("../../rule-factories/component/rules-engine");
const presenter_1 = require("../presenter");
const structures_types_1 = require("../structures.types");
exports.CONTAINER_FOLDER = 'container';
/**
* Generates the template properties
* @param options
* @param componentStructureDef
* @param prefix
*/
const getTemplateProperties = (options, componentStructureDef, prefix) => {
const inputComponentName = (0, schematics_2.getInputComponentName)(options.componentName);
const folderName = (0, schematics_2.getComponentFolderName)(inputComponentName);
const componentSelector = (0, schematics_2.getComponentSelectorWithoutSuffix)(options.componentName, prefix || null);
return {
...options,
componentType: options.componentStructure === 'full' ? 'Block' : 'Component',
presenterModuleName: (0, schematics_2.getComponentModuleName)(inputComponentName, structures_types_1.ComponentStructureDef.Pres),
componentName: (0, schematics_2.getComponentName)(inputComponentName, componentStructureDef).replace(/Component$/, ''),
presenterComponentName: (0, schematics_2.getComponentName)(inputComponentName, structures_types_1.ComponentStructureDef.Pres),
presenterComponentSelector: `${componentSelector}-${structures_types_1.ComponentStructureDef.Pres.toLowerCase()}`,
componentSelector: (0, schematics_2.getComponentSelectorWithoutSuffix)(options.componentName, prefix || null),
folderName,
name: (0, schematics_2.getComponentFileName)(options.componentName, componentStructureDef), // air-offer | air-offer-cont,
suffix: componentStructureDef.toLowerCase(), // cont | ''
description: options.description || ''
};
};
/**
* Add Otter container component to an Angular Project
* @param options
*/
function ngGenerateComponentContainerFn(options) {
const fullStructureRequested = options.componentStructure === 'full';
const generateFiles = (tree, context) => {
const workspaceProject = options.projectName ? (0, schematics_2.getWorkspaceConfig)(tree)?.projects[options.projectName] : undefined;
const properties = getTemplateProperties(options, structures_types_1.ComponentStructureDef.Cont, options.prefix || workspaceProject?.prefix);
const destination = (0, schematics_2.getDestinationPath)('@o3r/core:component', options.path, tree, options.projectName);
const componentDestination = path.posix.join(destination, fullStructureRequested ? path.posix.join(properties.folderName, exports.CONTAINER_FOLDER) : properties.folderName);
const componentPath = path.posix.join(componentDestination, `${properties.name}.component.ts`);
const ngSpecPath = path.posix.join(componentDestination, `${properties.name}.component.spec.ts`);
const o3rSpecPath = path.posix.join(componentDestination, `${properties.name}.spec.ts`);
const ngTemplatePath = path.posix.join(componentDestination, `${properties.name}.component.html`);
const o3rTemplatePath = path.posix.join(componentDestination, `${properties.name}.template.html`);
const rules = [];
if (!options.standalone) {
rules.push((0, schematics_1.externalSchematic)('@schematics/angular', 'module', {
project: properties.projectName,
path: componentDestination,
flat: true,
name: properties.componentName
}));
}
rules.push((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./templates'), [
(0, schematics_1.template)(properties),
(0, schematics_1.renameTemplateFiles)(),
(0, schematics_1.move)(componentDestination)
]), schematics_1.MergeStrategy.Overwrite), (0, schematics_1.externalSchematic)('@schematics/angular', 'component', {
project: properties.projectName,
selector: `${properties.componentSelector}-${properties.suffix}`,
path: componentDestination,
name: properties.componentName,
inlineStyle: false,
inlineTemplate: false,
viewEncapsulation: 'None',
changeDetection: 'OnPush',
style: 'none',
type: 'Component',
skipSelector: false,
skipTests: false,
standalone: options.standalone,
...(options.standalone
? {
skipImport: true
}
: {
module: `${properties.name}.module.ts`,
export: true
}),
flat: true
}),
// Angular schematics generate spec file with this pattern: component-name.component.spec.ts
(0, schematics_1.move)(ngSpecPath, o3rSpecPath),
// Angular schematics generate template file with this pattern: component-name.component.html
(0, schematics_1.chain)([
(0, schematics_1.move)(ngTemplatePath, o3rTemplatePath),
(t) => {
t.overwrite(componentPath, t.readText(componentPath).replace(path.basename(ngTemplatePath), path.basename(o3rTemplatePath)));
return t;
}
]), (0, schematics_1.schematic)('convert-component', {
path: componentPath,
skipLinter: options.skipLinter,
componentType: properties.componentType
}));
if (fullStructureRequested) {
const componentPresenterDestination = path.posix.join('..', presenter_1.PRESENTER_FOLDER, 'index');
const addPresenterComponentOrModuleToImport = options.standalone
? (0, schematics_1.chain)([
(0, schematics_2.addImportsRule)(componentPath, [
{
from: componentPresenterDestination,
importNames: [properties.presenterComponentName]
}
]),
() => {
const componentSourceFile = ts.createSourceFile(componentPath, tree.readText(componentPath), ts.ScriptTarget.ES2020, true);
const result = ts.transform(componentSourceFile, [
(0, schematics_2.addImportsIntoComponentDecoratorTransformerFactory)([properties.presenterComponentName])
]);
const printer = ts.createPrinter({
removeComments: false,
newLine: ts.NewLineKind.LineFeed
});
tree.overwrite(componentPath, printer.printFile(result.transformed[0]));
return tree;
}
])
: () => {
const modulePath = path.posix.join(componentDestination, `${properties.name}.module.ts`);
const moduleSourceFile = ts.createSourceFile(modulePath, tree.readText(modulePath), ts.ScriptTarget.ES2020, true);
const changes = (0, ast_utils_1.addImportToModule)(moduleSourceFile, modulePath, properties.presenterModuleName, componentPresenterDestination);
const recorder = tree.beginUpdate(modulePath);
(0, change_1.applyToUpdateRecorder)(recorder, changes);
tree.commitUpdate(recorder);
return tree;
};
const addMockPresenterComponentInSpecFile = () => {
if (!tree.exists(o3rSpecPath)) {
context.logger.warn(`No update applied on spec file because ${o3rSpecPath} does not exist.`);
return;
}
let specSourceFile = ts.createSourceFile(o3rSpecPath, tree.readText(o3rSpecPath), ts.ScriptTarget.ES2020, true);
const recorder = tree.beginUpdate(o3rSpecPath);
const lastImport = [...specSourceFile.statements].reverse().find((statement) => ts.isImportDeclaration(statement));
const changes = [
(0, ast_utils_1.insertImport)(specSourceFile, o3rSpecPath, 'Component', '@angular/core'),
new change_1.InsertChange(o3rSpecPath, lastImport?.getEnd() || 0, `
@Component({
template: '',
selector: '${properties.presenterComponentSelector}'
})
class Mock${properties.presenterComponentName} {}
`)
];
(0, change_1.applyToUpdateRecorder)(recorder, changes);
tree.commitUpdate(recorder);
specSourceFile = ts.createSourceFile(o3rSpecPath, tree.readText(o3rSpecPath), ts.ScriptTarget.ES2020, true);
const result = ts.transform(specSourceFile, [
(0, schematics_2.addImportsAndCodeBlockStatementAtSpecInitializationTransformerFactory)([
`Mock${properties.presenterComponentName}`
])
]);
const printer = ts.createPrinter({
removeComments: false,
newLine: ts.NewLineKind.LineFeed
});
const newContent = printer.printFile(result.transformed[0]);
tree.overwrite(o3rSpecPath, newContent);
return tree;
};
rules.push((t) => {
t.overwrite(o3rTemplatePath, `<${properties.presenterComponentSelector}></${properties.presenterComponentSelector}>`);
return t;
}, addPresenterComponentOrModuleToImport, addMockPresenterComponentInSpecFile);
}
rules.push((0, configuration_1.getAddConfigurationRules)(componentPath, options), (0, fixture_1.getAddFixtureRules)(componentPath, options), (0, context_1.getAddContextRules)(componentPath, options), (0, rules_engine_1.getAddRulesEngineRules)(path.posix.join(componentDestination, `${properties.name}.component.ts`), options));
return (0, schematics_1.chain)(rules);
};
return (0, schematics_1.chain)([
generateFiles,
fullStructureRequested ? (0, schematics_1.noop)() : (options.skipLinter ? (0, schematics_1.noop)() : (0, schematics_2.applyEsLintFix)())
]);
}
/**
* Add Otter container component to an Angular Project
* @param options
*/
exports.ngGenerateComponentContainer = (0, schematics_2.createOtterSchematic)(ngGenerateComponentContainerFn);
//# sourceMappingURL=index.js.map