|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
import { SourceMap } from 'magic-string';
|
|
|
|
|
import { SourceMapConsumer, SourceMapGenerator } from 'source-map';
|
|
|
|
|
import getCodeFrame from '../utils/getCodeFrame.js';
|
|
|
|
|
|
|
|
|
|
export interface PreprocessOptions {
|
|
|
|
|
markup?: (options: {
|
|
|
|
@ -62,45 +63,48 @@ async function replaceTagContents(
|
|
|
|
|
if (match) {
|
|
|
|
|
const attributes: Record<string, string | boolean> = parseAttributes(match[1]);
|
|
|
|
|
const content: string = match[2];
|
|
|
|
|
const processed: { code: string, map?: SourceMap | string } = await preprocessor({
|
|
|
|
|
|
|
|
|
|
// Line number of the match
|
|
|
|
|
let line = 0;
|
|
|
|
|
for (let i = 0; i <= match.index; i = source.indexOf('\n', i + 1)) {
|
|
|
|
|
line++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
line--;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const processed: {
|
|
|
|
|
code: string;
|
|
|
|
|
map?: SourceMap | string;
|
|
|
|
|
} = await preprocessor({
|
|
|
|
|
content,
|
|
|
|
|
attributes,
|
|
|
|
|
filename : options.filename
|
|
|
|
|
filename: options.filename,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (processed && processed.code) {
|
|
|
|
|
const code = (
|
|
|
|
|
const code =
|
|
|
|
|
source.slice(0, match.index) +
|
|
|
|
|
`<${type}>${processed.code}</${type}>` +
|
|
|
|
|
source.slice(match.index + match[0].length)
|
|
|
|
|
);
|
|
|
|
|
source.slice(match.index + match[0].length);
|
|
|
|
|
|
|
|
|
|
// Shift sourcemap to the appropriate line
|
|
|
|
|
if (processed.map) {
|
|
|
|
|
const consumer = new SourceMapConsumer(processed.map);
|
|
|
|
|
|
|
|
|
|
// Line number of the match
|
|
|
|
|
let line = 0;
|
|
|
|
|
for(let i = 0; i <= match.index; i = source.indexOf('\n', i + 1)) {
|
|
|
|
|
line++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Skip the <tag ...>
|
|
|
|
|
line++;
|
|
|
|
|
|
|
|
|
|
const generator = new SourceMapGenerator({ file: options.filename })
|
|
|
|
|
const generator = new SourceMapGenerator({ file: options.filename });
|
|
|
|
|
consumer.eachMapping(mapping => {
|
|
|
|
|
generator.addMapping({
|
|
|
|
|
source: mapping.source,
|
|
|
|
|
name: mapping.name,
|
|
|
|
|
original: {
|
|
|
|
|
line: mapping.originalLine + line,
|
|
|
|
|
column: mapping.originalColumn
|
|
|
|
|
column: mapping.originalColumn,
|
|
|
|
|
},
|
|
|
|
|
generated: {
|
|
|
|
|
line: mapping.generatedLine + line,
|
|
|
|
|
column: mapping.generatedColumn
|
|
|
|
|
}
|
|
|
|
|
column: mapping.generatedColumn,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -109,6 +113,18 @@ async function replaceTagContents(
|
|
|
|
|
|
|
|
|
|
return { code };
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
if (err.line && err.column) {
|
|
|
|
|
err.frame = getCodeFrame(source, line + err.line - 1, err.column);
|
|
|
|
|
} else if (err.start && err.start.line && err.start.column) {
|
|
|
|
|
err.frame = getCodeFrame(source, line + err.start.line - 1, err.column);
|
|
|
|
|
} else if (typeof err.start === 'number') {
|
|
|
|
|
const start = locate(contents, err.start, { offsetLine: 1 });
|
|
|
|
|
err.frame = getCodeFrame(source, line + start.line - 1, start.column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { code: source };
|
|
|
|
@ -124,17 +140,32 @@ export default async function preprocess(
|
|
|
|
|
let markupMap: SourceMapGenerator;
|
|
|
|
|
|
|
|
|
|
if (!!markup) {
|
|
|
|
|
try {
|
|
|
|
|
const processed: {
|
|
|
|
|
code: string,
|
|
|
|
|
map?: SourceMap | string
|
|
|
|
|
code: string;
|
|
|
|
|
map?: SourceMap | string;
|
|
|
|
|
} = await markup({
|
|
|
|
|
content: source,
|
|
|
|
|
filename: options.filename
|
|
|
|
|
filename: options.filename,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
source = processed.code;
|
|
|
|
|
if (processed.map) {
|
|
|
|
|
markupMap = SourceMapGenerator.fromSourceMap(new SourceMapConsumer(processed.map));
|
|
|
|
|
markupMap = SourceMapGenerator.fromSourceMap(
|
|
|
|
|
new SourceMapConsumer(processed.map)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
if (err.line && err.column) {
|
|
|
|
|
err.frame = getCodeFrame(source, err.line - 1, err.column);
|
|
|
|
|
} else if (err.start && err.start.line && err.start.column) {
|
|
|
|
|
err.frame = getCodeFrame(source, err.start.line - 1, err.column);
|
|
|
|
|
} else if (typeof err.start === 'number') {
|
|
|
|
|
const start = locate(source, err.start, { offsetLine: 1 });
|
|
|
|
|
err.frame = getCodeFrame(source, start.line - 1, start.column);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|