@vue-macros/volar
Version:
Volar plugin for Vue Macros.
59 lines (57 loc) • 3.31 kB
JavaScript
import path from "node:path";
import process from "node:process";
import { resolveOptions } from "@vue-macros/config";
import { replace, replaceAll } from "ts-macro";
//#region src/common.ts
const REGEX_DEFINE_COMPONENT = /(?<=(?:__VLS_|\(await import\(\S+\)\)\.)defineComponent\(\{\n)/g;
function addProps(codes, decl, version) {
const codeString = codes.toString();
if (!decl.length) return;
replace(codes, /(?<=type __VLS_PublicProps = )/, `{\n${decl.join(",\n")}\n} & `);
if (!codeString.includes(version >= 3.5 ? "__typeProps: " : "props: ,{} as __VLS_TypePropsToOption")) {
replaceAll(codes, REGEX_DEFINE_COMPONENT, version >= 3.5 ? "__typeProps: {} as __VLS_PublicProps,\n" : "props: {} as __VLS_TypePropsToOption<__VLS_PublicProps>,\n");
if (version < 3.5 && !codeString.includes("type __VLS_NonUndefinedable")) codes.push(`type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;\n`, `type __VLS_TypePropsToOption<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>> } : { type: import('vue').PropType<T[K]>, required: true } };\n`);
}
return true;
}
function addEmits(codes, decl, version) {
const codeString = codes.toString();
if (!decl.length) return;
const index = codes.findIndex((code) => code.toString().startsWith("type __VLS_Emit = "));
const result = decl.join(",\n");
const modelIndex = codes.findIndex((code) => code.toString().includes("type __VLS_ModelEmit = "));
if (modelIndex !== -1) codes.splice(modelIndex + 1, 0, ` ${result} , `);
if (index === -1) {
const propsIndex = codes.findIndex((code) => code.toString().includes("type __VLS_PublicProps = "));
codes.splice(propsIndex, 0, ...version < 3.5 ? [`const __VLS_emit = (await import('vue')).defineEmits<{\n${result}\n}>();\n`, `type __VLS_Emit = typeof __VLS_emit;;\n`] : [`type __VLS_Emit = {\n${result}\n};\n`]);
} else if (modelIndex === -1) codes.splice(index + 2, 0, ` & {\n${result}}\n`);
if (version >= 3.5) {
if (!codeString.includes("__typeEmits: {} as ")) replaceAll(codes, REGEX_DEFINE_COMPONENT, "__typeEmits: {} as __VLS_Emit,\n");
} else if (!codeString.includes("{} as __VLS_NormalizeEmits<typeof __VLS")) replaceAll(codes, REGEX_DEFINE_COMPONENT, "emits: {} as __VLS_NormalizeEmits<__VLS_Emit>,\n");
return true;
}
function addCode(codes, ...args) {
const index = codes.findIndex((code) => code.includes("__VLS_setup = (async () => {"));
codes.splice(index === -1 ? codes.length : index + 1, 0, ...args);
}
const resolvedOptions = /* @__PURE__ */ new Map();
function getVolarOptions(context, key) {
const configPath = context.compilerOptions.configFilePath;
const root = typeof configPath === "string" ? path.dirname(configPath) : process.cwd();
let resolved;
if (!resolvedOptions.has(root)) {
resolved = resolveOptions.sync(context.vueCompilerOptions.vueMacros, root);
resolvedOptions.set(root, resolved);
}
return (resolved || resolvedOptions.get(root))[key];
}
function patchSFC(block, offset) {
if (block) {
block.loc.start.column -= offset;
block.loc.start.offset -= offset;
block.loc.end.offset -= offset;
if (block.loc.end.line === block.loc.start.line) block.loc.end.column -= offset;
}
}
//#endregion
export { REGEX_DEFINE_COMPONENT, addCode, addEmits, addProps, getVolarOptions, patchSFC };