@oxlint/migrate
Version:
Generates a `.oxlintrc.json` from a existing eslint flat config
168 lines (167 loc) • 4.88 kB
JavaScript
function extractLangAttribute(source) {
const langIndex = source.indexOf("lang");
if (langIndex === -1) return void 0;
let cursor = langIndex + 4;
while (cursor < source.length && isWhitespace(source[cursor])) {
cursor++;
}
if (source[cursor] !== "=") return void 0;
cursor++;
while (cursor < source.length && isWhitespace(source[cursor])) {
cursor++;
}
const quote = source[cursor];
if (quote !== '"' && quote !== "'") return void 0;
cursor++;
let value = "";
while (cursor < source.length && source[cursor] !== quote) {
value += source[cursor++];
}
if (value === "js" || value === "jsx" || value === "ts" || value === "tsx") {
return value;
}
return void 0;
}
function extractScriptBlocks(sourceText, offset, maxBlocks, parseLangAttribute) {
const results = [];
while (offset < sourceText.length) {
const idx = sourceText.indexOf("<script", offset);
if (idx === -1) break;
const nextChar = sourceText[idx + 7];
if (nextChar !== " " && nextChar !== ">" && nextChar !== "\n" && nextChar !== " ") {
offset = idx + 7;
continue;
}
let i = idx + 7;
let inQuote = null;
let genericDepth = 0;
let selfClosing = false;
while (i < sourceText.length) {
const c = sourceText[i];
if (inQuote) {
if (c === inQuote) inQuote = null;
} else if (c === '"' || c === "'") {
inQuote = c;
} else if (c === "<") {
genericDepth++;
} else if (c === ">") {
if (genericDepth > 0) {
genericDepth--;
} else {
if (i > idx && sourceText[i - 1] === "/") {
selfClosing = true;
}
i++;
break;
}
}
i++;
}
if (selfClosing) {
offset = i;
continue;
}
if (i >= sourceText.length) break;
let lang = void 0;
if (parseLangAttribute) {
lang = extractLangAttribute(sourceText.slice(idx, i));
}
const contentStart = i;
const closeTag = "<\/script>";
const closeIdx = sourceText.indexOf(closeTag, contentStart);
if (closeIdx === -1) break;
const content = sourceText.slice(contentStart, closeIdx);
results.push({ sourceText: content, offset: contentStart, lang });
if (results.length >= maxBlocks) {
break;
}
offset = closeIdx + closeTag.length;
}
return results;
}
function partialSourceTextLoader(absoluteFilePath, fileContent) {
if (absoluteFilePath.endsWith(".vue")) {
return partialVueSourceTextLoader(fileContent);
} else if (absoluteFilePath.endsWith(".astro")) {
return partialAstroSourceTextLoader(fileContent);
} else if (absoluteFilePath.endsWith(".svelte")) {
return partialSvelteSourceTextLoader(fileContent);
}
return [
{
sourceText: fileContent,
offset: 0
}
];
}
function isWhitespace(char) {
return char === " " || char === " " || char === "\r";
}
function findDelimiter(sourceText, startPos) {
let i = startPos;
while (i < sourceText.length) {
if (i === 0 || sourceText[i - 1] === "\n") {
let j = i;
while (j < sourceText.length && isWhitespace(sourceText[j])) j++;
if (sourceText[j] === "-" && sourceText[j + 1] === "-" && sourceText[j + 2] === "-") {
let k = j + 3;
while (k < sourceText.length && sourceText[k] !== "\n") {
if (!isWhitespace(sourceText[k])) break;
k++;
}
if (k === sourceText.length || sourceText[k] === "\n") {
return j;
}
}
}
i++;
}
return -1;
}
function partialVueSourceTextLoader(sourceText) {
return extractScriptBlocks(sourceText, 0, 2, true);
}
function partialSvelteSourceTextLoader(sourceText) {
return extractScriptBlocks(sourceText, 0, 2, true);
}
function partialAstroSourceTextLoader(sourceText) {
const results = [];
let pos = 0;
const frontmatterStartDelimiter = findDelimiter(sourceText, pos);
if (frontmatterStartDelimiter !== -1) {
const frontmatterContentStart = frontmatterStartDelimiter + 3;
const frontmatterEndDelimiter = findDelimiter(
sourceText,
frontmatterContentStart
);
if (frontmatterEndDelimiter !== -1) {
const content = sourceText.slice(
frontmatterContentStart,
frontmatterEndDelimiter
);
results.push({
sourceText: content,
offset: frontmatterContentStart,
lang: "ts",
sourceType: "module"
});
pos = frontmatterEndDelimiter + 3;
}
}
results.push(
...extractScriptBlocks(sourceText, pos, Number.MAX_SAFE_INTEGER, false).map(
(sourceText2) => ({
...sourceText2,
lang: "ts",
sourceType: "module"
})
)
);
return results;
}
export {
partialSourceTextLoader as default,
partialAstroSourceTextLoader,
partialSvelteSourceTextLoader,
partialVueSourceTextLoader
};