@o3r/configuration
Version:
This module contains configuration-related features such as CMS compatibility, Configuration override, store and debugging. It enables your application runtime configuration and comes with an integrated ng builder to help you generate configurations suppo
94 lines (92 loc) • 4.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ngUseConfigSignal = void 0;
const schematics_1 = require("@angular-devkit/schematics");
const schematics_2 = require("@o3r/schematics");
const ts = require("typescript");
const configObserverRegexp = /.*new ConfigurationObserver<(?<configName>\w+)>\(\s*(?<configId>\w+),\s*(?<defaultConfig>\w+)(,\s*\w+)?\s*\);/;
function ngUseConfigSignalFn(options) {
return (0, schematics_1.chain)([
(0, schematics_2.addImportsRule)(options.path, [
{
from: '@angular/core',
importNames: [
'inject',
'input'
]
},
{
from: '@angular/core/rxjs-interop',
importNames: [
'toObservable'
]
},
{
from: '@o3r/configuration',
importNames: [
'configSignal',
'O3rConfig',
'DynamicConfigurableWithSignal'
]
}
]),
(tree) => {
const content = tree.readText(options.path);
// Retrieve all info
const match = content.match(configObserverRegexp);
const { configName, configId, defaultConfig } = match?.groups || {};
if (!configName || !configId || !defaultConfig) {
throw new schematics_2.O3rCliError(`Configuration name, id or default value not found in ${options.path}.\nCannot migrate to signal based configuration.`);
}
const componentSourceFile = ts.createSourceFile(options.path, content, ts.ScriptTarget.ES2020, true);
const result = ts.transform(componentSourceFile, [
(0, schematics_2.addInterfaceToClassTransformerFactory)(`DynamicConfigurableWithSignal<${configName}>`, schematics_2.isO3rClassComponent, new Set(['DynamicConfigurable'])),
(ctx) => (rootNode) => {
const { factory } = ctx;
const visit = (node) => {
if (ts.isClassDeclaration(node) && (0, schematics_2.isO3rClassComponent)(node)) {
const propertiesToAdd = (0, schematics_2.generateClassElementsFromString)(`
public config = input<Partial<${configName}>>();
@O3rConfig()
public readonly configSignal = configSignal(this.config, ${configId}, ${defaultConfig});
public readonly config$ = toObservable(this.configSignal);`);
const newMembers = propertiesToAdd.concat(node.members.filter((member) => !member.name
|| (ts.isIdentifier(member.name)
&& ![
'config$',
'config',
'dynamicConfig$'
].includes(member.name.escapedText.toString()))));
(0, schematics_2.addCommentsOnClassProperties)(newMembers, {
config: 'Input configuration to override the default configuration of the component',
configSignal: 'Configuration signal based on the input and the stored configuration',
config$: '@deprecated use configSignal instead'
});
return factory.updateClassDeclaration(node, ts.getModifiers(node), node.name, node.typeParameters, node.heritageClauses, newMembers);
}
return ts.visitEachChild(node, visit, ctx);
};
return ts.visitNode(rootNode, visit);
}
]);
const printer = ts.createPrinter({
removeComments: false,
newLine: ts.NewLineKind.LineFeed
});
let newContent = printer.printFile(result.transformed[0]);
newContent = newContent
.replace(/this\.dynamicConfig\$\.next\(this.config\);/, '// TODO remove the ngOnChanges if empty')
.replace(configObserverRegexp, '')
.replace(/this\.config\$\s*=\s*this\.dynamicConfig\$\s*\.asObservable\(\);/, '');
tree.overwrite(options.path, newContent);
return tree;
},
options.skipLinter ? (0, schematics_1.noop)() : (0, schematics_2.applyEsLintFix)()
]);
}
/**
* Migrate from configuration observable to signal
* @param options
*/
exports.ngUseConfigSignal = (0, schematics_2.createOtterSchematic)(ngUseConfigSignalFn);
//# sourceMappingURL=index.js.map