@o3r/core
Version:
Core of the Otter Framework
174 lines • 9.54 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ngGeneratePage = void 0;
const path = require("node:path");
const core_1 = require("@angular-devkit/core");
const schematics_1 = require("@angular-devkit/schematics");
const schematics_2 = require("@o3r/schematics");
const ts = require("typescript");
const configuration_1 = require("../rule-factories/component/configuration");
const fixture_1 = require("../rule-factories/component/fixture");
const localization_1 = require("../rule-factories/component/localization");
const theming_1 = require("../rule-factories/component/theming");
/**
* Add a Page to an Otter project
* @param options
*/
function ngGeneratePageFn(options) {
const isApplication = (tree) => {
const workspaceProject = options.projectName ? (0, schematics_2.getWorkspaceConfig)(tree)?.projects[options.projectName] : undefined;
if (!workspaceProject) {
throw new schematics_2.O3rCliError('Cannot create a page on library');
}
return tree;
};
const pageName = core_1.strings.classify(options.name);
/**
* Generates page files.
* @param tree File tree
* @param context Context of the rule
*/
const generateFiles = (tree, context) => {
const workspaceProject = options.projectName ? (0, schematics_2.getWorkspaceConfig)(tree)?.projects[options.projectName] : undefined;
if (!workspaceProject) {
context.logger.warn('No application detected in this project, the page cannot be generated');
return schematics_1.noop;
}
const destination = (0, schematics_2.getDestinationPath)('@o3r/core:page', options.path, tree, options.projectName);
const pagePath = path.posix.join(destination, core_1.strings.dasherize(options.scope), core_1.strings.dasherize(options.name));
const dasherizedPageName = core_1.strings.dasherize(options.name);
const projectName = options.projectName;
const componentPath = path.posix.join(pagePath, `${dasherizedPageName}.component.ts`);
const ngSpecPath = path.posix.join(pagePath, `${dasherizedPageName}.component.spec.ts`);
const o3rSpecPath = path.posix.join(pagePath, `${dasherizedPageName}.spec.ts`);
const ngStylePath = path.posix.join(pagePath, `${dasherizedPageName}.component.scss`);
const o3rStylePath = path.posix.join(pagePath, `${dasherizedPageName}.style.scss`);
const ngTemplatePath = path.posix.join(pagePath, `${dasherizedPageName}.component.html`);
const o3rTemplatePath = path.posix.join(pagePath, `${dasherizedPageName}.template.html`);
const moduleFileName = `${dasherizedPageName}.module.ts`;
const moduleFilePath = path.posix.join(pagePath, moduleFileName);
const rules = [];
if (!options.standalone) {
rules.push((0, schematics_1.externalSchematic)('@schematics/angular', 'module', {
project: projectName,
path: pagePath,
flat: true,
name: pageName,
typeSeparator: '.'
}), () => {
const sourceFileContent = tree.readText(moduleFilePath);
const sourceFile = ts.createSourceFile(moduleFilePath, sourceFileContent, ts.ScriptTarget.ES2015, true);
const recorder = tree.beginUpdate(moduleFilePath);
const { moduleIndex } = (0, schematics_2.getModuleIndex)(sourceFile, sourceFileContent);
(0, schematics_2.addImportToModuleFile)('RouterModule', '@angular/router', sourceFile, sourceFileContent, context, recorder, moduleFilePath, moduleIndex, `.forChild([{path: '', component: ${core_1.strings.classify(pageName)}Component}])`, true);
tree.commitUpdate(recorder);
return tree;
});
}
rules.push((0, schematics_1.externalSchematic)('@schematics/angular', 'component', {
project: projectName,
selector: `${options.prefix || 'o3r'}-${dasherizedPageName}`,
path: pagePath,
name: pageName,
inlineStyle: false,
inlineTemplate: false,
viewEncapsulation: 'None',
changeDetection: 'OnPush',
style: 'scss',
type: 'component',
skipSelector: false,
standalone: options.standalone,
...(options.standalone
? {
skipImport: true
}
: {
module: `${dasherizedPageName}.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 style file with this pattern: component-name.component.scss
(0, schematics_1.chain)([
(0, schematics_1.move)(ngStylePath, o3rStylePath),
(t) => {
t.overwrite(componentPath, t.readText(componentPath).replace(path.basename(ngStylePath), path.basename(o3rStylePath)));
return t;
}
]),
// 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: 'Page'
}), (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./templates'), [
(0, schematics_1.template)({
...core_1.strings,
...options,
pageName
}),
(0, schematics_1.renameTemplateFiles)(),
(0, schematics_1.move)(pagePath)
]), schematics_1.MergeStrategy.Overwrite), (0, configuration_1.getAddConfigurationRules)(componentPath, options), (0, theming_1.getAddThemingRules)(o3rStylePath, options), (0, localization_1.getAddLocalizationRules)(componentPath, options), (0, fixture_1.getAddFixtureRules)(componentPath, {
skipLinter: options.skipLinter,
useComponentFixtures: options.usePageFixtures
}, true));
return (0, schematics_1.chain)(rules);
};
/**
* Updates App Routing Module to add the new page route.
* @param tree File tree
* @param context Context of the rule
*/
const updateAppRoutingModule = (tree, context) => {
const indexFilePath = path.posix.join(core_1.strings.dasherize(options.scope), core_1.strings.dasherize(options.name), 'index');
const route = {
path: core_1.strings.dasherize(options.name),
import: `./${indexFilePath.replace(/[/\\]/g, '/')}`,
module: `${pageName}${options.standalone ? 'Component' : 'Module'}`
};
if (options.appRoutingModulePath) {
return (0, schematics_2.insertRoute)(tree, context, options.appRoutingModulePath, route, options.standalone);
}
const appModuleFilePath = (0, schematics_2.getAppModuleFilePath)(tree, context, options.projectName);
if (appModuleFilePath) {
const text = tree.readText(appModuleFilePath);
const match = text.match(/(provideRouter|RouterModule\.forRoot)\((\s*)?(?<routeVarName>[^\s),]*)/);
const routeVariableName = match?.groups?.routeVarName;
if (routeVariableName) {
const sourceFile = ts.createSourceFile(appModuleFilePath, text, ts.ScriptTarget.ES2015, true);
const importStatement = sourceFile.statements.find((statement) => ts.isImportDeclaration(statement)
&& !!statement?.moduleSpecifier
&& ts.isStringLiteral(statement.moduleSpecifier)
&& !!statement.importClause?.namedBindings
&& ts.isNamedImports(statement.importClause.namedBindings)
&& statement.importClause.namedBindings.elements.some((element) => element.name.escapedText.toString() === routeVariableName));
const importRouteVariablePath = importStatement?.moduleSpecifier?.text;
// If importRouteVariablePath is undefined it is because the variable is defined in this file
const appRoutingModulePath = importRouteVariablePath ? path.join(path.dirname(appModuleFilePath), `${importRouteVariablePath}.ts`) : appModuleFilePath;
return (0, schematics_2.insertRoute)(tree, context, appRoutingModulePath, route, options.standalone);
}
}
throw new schematics_2.O3rCliError('No routes definition found. Please use the option `appRoutingModulePath` to specify the path of the routes definition.');
};
return (0, schematics_1.chain)([
isApplication,
generateFiles,
updateAppRoutingModule,
options.skipLinter ? (0, schematics_1.noop)() : (0, schematics_2.applyEsLintFix)()
]);
}
/**
* Add a Page to an Otter project
* @param options
*/
exports.ngGeneratePage = (0, schematics_2.createOtterSchematic)(ngGeneratePageFn);
//# sourceMappingURL=index.js.map