quarc/cli/processors/inject-processor.ts

95 lines
3.1 KiB
TypeScript

import { BaseProcessor, ProcessorContext, ProcessorResult } from './base-processor';
export class InjectProcessor extends BaseProcessor {
get name(): string {
return 'inject-processor';
}
private findMatchingAngleBracket(source: string, startIndex: number): number {
let depth = 1;
let i = startIndex + 1;
while (i < source.length && depth > 0) {
if (source[i] === '<') depth++;
else if (source[i] === '>') depth--;
i++;
}
return depth === 0 ? i - 1 : -1;
}
async process(context: ProcessorContext): Promise<ProcessorResult> {
if (!context.source.includes('inject')) {
return this.noChange(context.source);
}
let source = context.source;
let modified = false;
const replacements: Array<{ start: number; end: number; replacement: string }> = [];
const injectStartPattern = /inject\s*/g;
let match;
while ((match = injectStartPattern.exec(source)) !== null) {
const injectStart = match.index;
let currentPos = injectStart + match[0].length;
let genericPart = '';
if (source[currentPos] === '<') {
const closingBracket = this.findMatchingAngleBracket(source, currentPos);
if (closingBracket !== -1) {
genericPart = source.substring(currentPos, closingBracket + 1);
currentPos = closingBracket + 1;
}
}
while (currentPos < source.length && /\s/.test(source[currentPos])) {
currentPos++;
}
if (source[currentPos] === '(') {
currentPos++;
while (currentPos < source.length && /\s/.test(source[currentPos])) {
currentPos++;
}
const classNameMatch = source.substring(currentPos).match(/^([A-Z]\w*)/);
if (classNameMatch) {
const className = classNameMatch[1];
currentPos += className.length;
while (currentPos < source.length && /\s/.test(source[currentPos])) {
currentPos++;
}
if (source[currentPos] === ')') {
currentPos++;
const fullMatch = source.substring(injectStart, currentPos);
const replacement = `inject${genericPart}("${className}")`;
replacements.push({
start: injectStart,
end: currentPos,
replacement
});
}
}
}
}
if (replacements.length > 0) {
replacements.sort((a, b) => b.start - a.start);
for (const { start, end, replacement } of replacements) {
source = source.slice(0, start) + replacement + source.slice(end);
}
modified = true;
}
return modified ? this.changed(source) : this.noChange(source);
}
}