@o3r/core
Version:
Core of the Otter Framework
161 lines • 8.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateAdditionalModules = updateAdditionalModules;
const path = require("node:path");
const schematics_1 = require("@angular-devkit/schematics");
const schematics_2 = require("@o3r/schematics");
const utility_1 = require("@schematics/angular/utility");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const change_1 = require("@schematics/angular/utility/change");
const ts = require("typescript");
const o3rPackageJsonPath = path.resolve(__dirname, '..', '..', '..', 'package.json');
const ngrxStoreDevtoolsDep = '@ngrx/store-devtools';
/**
* Add additional modules for dev only
* @param options @see RuleFactory.options
* @param options.projectName
* @param options.workingDirectory the directory where to execute the rule factory
* @param dependenciesSetupConfig
*/
function updateAdditionalModules(options, dependenciesSetupConfig) {
/**
* Update package.json to add additional modules dependencies
* @param tree
* @param context
*/
const updatePackageJson = (tree, context) => {
const workspaceConfig = (0, schematics_2.getWorkspaceConfig)(tree);
const workspaceProject = (options.projectName && workspaceConfig?.projects?.[options.projectName]) || undefined;
const projectDirectory = workspaceProject?.root || '.';
const projectPackageJson = tree.readJson(path.posix.join(projectDirectory, 'package.json'));
dependenciesSetupConfig.dependencies = {
...dependenciesSetupConfig.dependencies,
...(0, schematics_2.getExternalDependenciesInfo)({
dependenciesToInstall: [ngrxStoreDevtoolsDep],
devDependenciesToInstall: ['chokidar'],
o3rPackageJsonPath,
projectType: workspaceProject?.projectType,
projectPackageJson
}, context.logger)
};
return tree;
};
/**
* Import additional modules in AppModule
* @param tree
* @param context
*/
const registerModules = (tree, context) => {
const additionalRules = [];
const moduleFilePath = (0, schematics_2.getAppModuleFilePath)(tree, context, options.projectName);
if (!moduleFilePath) {
return tree;
}
const sourceFileContent = tree.readText(moduleFilePath);
const sourceFile = ts.createSourceFile(moduleFilePath, sourceFileContent, ts.ScriptTarget.ES2015, true);
// if the app already uses store dev tools do nothing; if additionalModules is already imported do nothing to avoid the double imports
if ((0, ast_utils_1.isImported)(sourceFile, 'StoreDevtoolsModule', ngrxStoreDevtoolsDep) || (0, ast_utils_1.isImported)(sourceFile, 'additionalModules', '../environments/environment')) {
return tree;
}
const addImportToModuleFile = (name, file, moduleFunction) => additionalRules.push((0, utility_1.addRootImport)(options.projectName, ({ code, external }) => code `\n${external(name, file)}${moduleFunction}`));
addImportToModuleFile('additionalModules', '../environments/environment');
return (0, schematics_1.chain)(additionalRules)(tree, context);
};
/**
* Register additional modules for development
* @param tree
* @param context
*/
const registerDevAdditionalModules = (tree, context) => {
const moduleFilePath = (0, schematics_2.getAppModuleFilePath)(tree, context, options.projectName);
if (!moduleFilePath) {
return tree;
}
const sourceFile = ts.createSourceFile(moduleFilePath, tree.read(moduleFilePath).toString(), ts.ScriptTarget.ES2015, true);
// if we already have the StoreDevtoolsModule in app module file, do nothing to avoid overriding the already existing config
if ((0, ast_utils_1.isImported)(sourceFile, 'StoreDevtoolsModule', ngrxStoreDevtoolsDep)) {
return tree;
}
const workspaceProject = options.projectName ? (0, schematics_2.getWorkspaceConfig)(tree)?.projects[options.projectName] : undefined;
if (!workspaceProject) {
context.logger.warn('No application detected in the project, the development modules will not be added.');
return tree;
}
const mainFilePath = workspaceProject.architect.build.options.main ?? workspaceProject.architect.build.options.browser;
// supposing we are in ng 15, the env dev file name is environment.development.ts
let envDevFilePath = path.join(path.dirname(mainFilePath), 'environments', 'environment.development.ts');
if (!tree.exists(envDevFilePath)) {
// we are in ng 14, environment dev file name is: environment.ts
envDevFilePath = path.join(path.dirname(mainFilePath), 'environments', 'environment.ts');
}
if (!tree.exists(envDevFilePath)) { // if we don't use the env setup, we skip the step
context.logger.warn(` Cannot find environment in ${envDevFilePath}`);
return tree;
}
const sourceFileEnvDev = ts.createSourceFile(envDevFilePath, tree.read(envDevFilePath).toString(), ts.ScriptTarget.ES2015, true);
// if we already have the StoreDevtoolsModule in environment dev file, do nothing to avoid overriding the already existing config
if ((0, ast_utils_1.isImported)(sourceFileEnvDev, 'StoreDevtoolsModule', ngrxStoreDevtoolsDep)) {
return tree;
}
const recorder = tree.beginUpdate(envDevFilePath);
const importChange = (0, ast_utils_1.insertImport)(sourceFileEnvDev, envDevFilePath, 'StoreDevtoolsModule', ngrxStoreDevtoolsDep);
if (importChange instanceof change_1.InsertChange) {
recorder.insertLeft(importChange.pos, `${importChange.toAdd}\n`);
}
recorder.insertRight(sourceFileEnvDev.getEnd(), `\nexport const additionalModules = [
StoreDevtoolsModule.instrument()
];\n`);
tree.commitUpdate(recorder);
return tree;
};
/**
* Register additional modules for production
* @param tree
* @param context
*/
const registerProdAdditionalModules = (tree, context) => {
const moduleFilePath = (0, schematics_2.getAppModuleFilePath)(tree, context, options.projectName);
if (!moduleFilePath) {
return tree;
}
const sourceFile = ts.createSourceFile(moduleFilePath, tree.read(moduleFilePath).toString(), ts.ScriptTarget.ES2015, true);
// if we already have the StoreDevtoolsModule in app module file, do nothing to avoid overriding the already existing config
if ((0, ast_utils_1.isImported)(sourceFile, 'StoreDevtoolsModule', ngrxStoreDevtoolsDep)) {
return tree;
}
const workspaceProject = options.projectName ? (0, schematics_2.getWorkspaceConfig)(tree)?.projects[options.projectName] : undefined;
if (!workspaceProject) {
context.logger.warn('No application detected in the project, the development modules will not be added.');
return tree;
}
const mainFilePath = workspaceProject.architect.build.options.main ?? workspaceProject.architect.build.options.browser;
// supposing we are in ng 14, environment prod file name is: environment.prod.ts
let envProdFilePath = path.join(path.dirname(mainFilePath), 'environments', 'environment.prod.ts');
if (!tree.exists(envProdFilePath)) {
// we are in ng 15, environment prod file name is: environment.ts
envProdFilePath = path.join(path.dirname(mainFilePath), 'environments', 'environment.ts');
}
if (!tree.exists(envProdFilePath)) { // if we don't use the env setup, we skip the step
context.logger.warn(` Cannot find environment in ${envProdFilePath}`);
return tree;
}
const sourceFileEnvProd = ts.createSourceFile(envProdFilePath, tree.read(envProdFilePath).toString(), ts.ScriptTarget.ES2015, true);
const envContent = tree.readText(envProdFilePath);
const adModulesRegex = new RegExp(/export\s*const\s*additionalModules/, 'g');
// if we already have the declaration of additional modules constant in environment file, do nothing to avoid duplication
if (adModulesRegex.test(envContent)) {
return tree;
}
const recorder = tree.beginUpdate(envProdFilePath);
recorder.insertRight(sourceFileEnvProd.getEnd(), '\nexport const additionalModules = [];\n');
tree.commitUpdate(recorder);
return tree;
};
return (0, schematics_1.chain)([
updatePackageJson,
registerModules,
registerDevAdditionalModules,
registerProdAdditionalModules
]);
}
//# sourceMappingURL=index.js.map