@taiga-ui/cdk
Version:
Base library for creating Angular components and applications using Taiga UI principles regarding of actual visual appearance
120 lines • 5.54 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrateFilterByInput = migrateFilterByInput;
const ng_morph_1 = require("ng-morph");
const constants_1 = require("../../../constants");
const add_unique_import_1 = require("../../../utils/add-unique-import");
const get_component_templates_1 = require("../../../utils/templates/get-component-templates");
const FILTER_BY_INPUT_PIPE_RE = /\|\s*tuiFilterByInput:\s*(\w+)(\s*\(([^)]*)\))?/g;
const TUI_STRING_MATCHER_GENERIC_RE = /TuiStringMatcher<([^>]+)>/;
function migrateFilterByInput(tree, _options) {
for (const resource of (0, get_component_templates_1.getComponentTemplates)(constants_1.ALL_TS_FILES)) {
migrateResource(resource, tree);
}
}
function migrateResource(resource, tree) {
var _a, _b;
const isExternal = 'templatePath' in resource;
const templateText = isExternal
? ((_b = (_a = tree.read(resource.templatePath)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '')
: resource.template;
if (!templateText) {
return;
}
const matcherUsages = collectMatcherUsages(templateText);
if (matcherUsages.size === 0) {
return;
}
const [sourceFile] = (0, ng_morph_1.getSourceFiles)(resource.componentPath);
if (!sourceFile) {
return;
}
const componentClass = sourceFile
.getClasses()
.find((cls) => cls.getDecorator('Component'));
if (!componentClass) {
return;
}
const propsToAdd = buildFilterProps(matcherUsages, componentClass);
if (propsToAdd.length === 0) {
return;
}
const newTemplateText = replaceMatcherNames(templateText, propsToAdd);
if (isExternal) {
tree.overwrite(resource.templatePath, newTemplateText);
}
else {
updateInlineTemplate(componentClass, newTemplateText);
}
addFilterWrapperProperties(componentClass, propsToAdd);
(0, add_unique_import_1.addUniqueImport)(resource.componentPath, 'TuiFilterByInputOptions', '@taiga-ui/core');
}
function collectMatcherUsages(templateText) {
FILTER_BY_INPUT_PIPE_RE.lastIndex = 0;
const usages = new Map();
let match;
while ((match = FILTER_BY_INPUT_PIPE_RE.exec(templateText)) !== null) {
const name = match[1];
const callSuffix = match[2];
const args = match[3];
let kind = 'reference';
if (callSuffix !== undefined) {
kind = (args === null || args === void 0 ? void 0 : args.trim()) ? 'call-with-args' : 'call-no-args';
}
if (!usages.has(name)) {
usages.set(name, kind);
}
}
return usages;
}
function buildFilterProps(matcherUsages, componentClass) {
var _a, _b;
const result = [];
for (const [matcherName, kind] of matcherUsages) {
const filterWithName = `filterWith${matcherName[0].toUpperCase()}${matcherName.slice(1)}`;
if (componentClass.getProperty(filterWithName)) {
continue;
}
const prop = componentClass.getProperty(matcherName);
const typeText = (_b = (_a = prop === null || prop === void 0 ? void 0 : prop.getTypeNode()) === null || _a === void 0 ? void 0 : _a.getText()) !== null && _b !== void 0 ? _b : '';
const genericMatch = TUI_STRING_MATCHER_GENERIC_RE.exec(typeText);
const generic = genericMatch ? `<${genericMatch[1]}>` : '';
result.push({ filterWithName, matcherName, generic, kind });
}
return result;
}
function replaceMatcherNames(templateText, propsToAdd) {
return propsToAdd.reduce((text, { filterWithName, matcherName }) => text.replaceAll(new RegExp(String.raw `(\|\s*tuiFilterByInput:\s*)${matcherName}\b`, 'g'), `$1${filterWithName}`), templateText);
}
function updateInlineTemplate(componentClass, newTemplateText) {
var _a;
const decorator = componentClass.getDecorator('Component');
const [metadata] = decorator.getArguments();
if (!ng_morph_1.Node.isObjectLiteralExpression(metadata)) {
return;
}
const templateProp = metadata.getProperty('template');
if (ng_morph_1.Node.isPropertyAssignment(templateProp)) {
(_a = templateProp.getInitializer()) === null || _a === void 0 ? void 0 : _a.replaceWithText(newTemplateText);
}
}
function addFilterWrapperProperties(componentClass, propsToAdd) {
const closeBrace = componentClass.getLastToken();
if (!closeBrace) {
return;
}
const indent = ' ';
const propsText = `\n${propsToAdd.map((prop) => buildFilterPropLine(prop, indent)).join('\n')}\n`;
closeBrace.getSourceFile().insertText(closeBrace.getStart(), propsText);
}
function buildFilterPropLine({ filterWithName, matcherName, generic, kind }, indent) {
switch (kind) {
case 'call-no-args':
return `${indent}${filterWithName} = (): TuiFilterByInputOptions${generic}['filter'] => (items, query, stringify) => items.filter((item) => this.${matcherName}()(item, query, stringify));`;
case 'call-with-args':
return `${indent}${filterWithName} = (...args: any[]): TuiFilterByInputOptions${generic}['filter'] => (items, query, stringify) => items.filter((item) => this.${matcherName}(...args)(item, query, stringify));`;
default:
return `${indent}${filterWithName}: TuiFilterByInputOptions${generic}['filter'] = (items, query, stringify) => items.filter((item) => this.${matcherName}(item, query, stringify));`;
}
}
//# sourceMappingURL=migrate-filter-by-input.js.map