import { DIRECTIVE_IMPORT_PREFIX, DISABLE_COMMENT, getNameFromFilePath, getTransformedPath, isExclude, matchGlobs, normalizeComponentInfo, notNullish, parseId, pascalCase, resolveAlias, shouldTransform, slash, stringifyComponentImport, throttle, toArray } from "./utils-DuLwPrUJ.js";
import { existsSync } from "node:fs";
import process from "node:process";
import chokidar from "chokidar";
import { createUnplugin } from "unplugin";
import { createFilter } from "unplugin-utils";
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
import Debug from "debug";
import { mkdir, readFile, writeFile } from "node:fs/promises";
import { getPackageInfoSync, importModule, isPackageExists } from "local-pkg";
import { globSync } from "tinyglobby";
import MagicString from "magic-string";

//#region src/core/type-imports/index.ts
const TypeImportPresets = [{
	from: "vue-router",
	names: ["RouterView", "RouterLink"]
}, {
	from: "vue-starport",
	names: ["Starport", "StarportCarrier"]
}];

//#endregion
//#region src/core/type-imports/detect.ts
function detectTypeImports() {
	return TypeImportPresets.map((i) => isPackageExists(i.from) ? i : void 0).filter(notNullish);
}
function resolveTypeImports(imports) {
	return imports.flatMap((i) => i.names.map((n) => ({
		from: i.from,
		name: n,
		as: n
	})));
}

//#endregion
//#region src/core/declaration.ts
const multilineCommentsRE = /\/\*.*?\*\//gs;
const singlelineCommentsRE = /\/\/.*$/gm;
function extractImports(code) {
	return Object.fromEntries(Array.from(code.matchAll(/['"]?([^\s'"]+)['"]?\s*:\s*(.+?)[,;\r\n]/g)).map((i) => [i[1], i[2]]));
}
function parseDeclaration(code) {
	var _exec, _exec2;
	if (!code) return;
	code = code.replace(multilineCommentsRE, "").replace(singlelineCommentsRE, "");
	const imports = {
		component: {},
		directive: {}
	};
	const componentDeclaration = (_exec = /export\s+interface\s+GlobalComponents\s*\{.*?\}/s.exec(code)) === null || _exec === void 0 ? void 0 : _exec[0];
	if (componentDeclaration) imports.component = extractImports(componentDeclaration);
	const directiveDeclaration = (_exec2 = /export\s+interface\s+GlobalDirectives\s*\{.*?\}/s.exec(code)) === null || _exec2 === void 0 ? void 0 : _exec2[0];
	if (directiveDeclaration) imports.directive = extractImports(directiveDeclaration);
	return imports;
}
function addComponentPrefix(component, prefix) {
	if (!component.as || !prefix) return component;
	return {
		...component,
		as: `${prefix}${component.as}`
	};
}
/**
* Converts `ComponentInfo` to an array
*
* `[name, "typeof import(path)[importName]"]`
*/
function stringifyComponentInfo(filepath, { from: path, as: name, name: importName }, importPathTransform) {
	if (!name) return void 0;
	path = getTransformedPath(path, importPathTransform);
	const related = isAbsolute(path) ? `./${relative(dirname(filepath), path)}` : path;
	const entry = `typeof import('${slash(related)}')['${importName || "default"}']`;
	return [name, entry];
}
/**
* Converts array of `ComponentInfo` to an import map
*
* `{ name: "typeof import(path)[importName]", ... }`
*/
function stringifyComponentsInfo(filepath, components, importPathTransform) {
	return Object.fromEntries(components.map((info) => stringifyComponentInfo(filepath, info, importPathTransform)).filter(notNullish));
}
function getDeclarationImports(ctx, filepath) {
	const prefixComponentNameMap = Object.values(ctx.componentNameMap).map((info) => addComponentPrefix(info, ctx.options.prefix));
	const component = stringifyComponentsInfo(filepath, [
		...Object.values(ctx.componentCustomMap),
		...prefixComponentNameMap,
		...resolveTypeImports(ctx.options.types)
	], ctx.options.importPathTransform);
	const directive = stringifyComponentsInfo(filepath, Object.values(ctx.directiveCustomMap), ctx.options.importPathTransform);
	if (Object.keys(component).length + Object.keys(directive).length === 0) return;
	return {
		component,
		directive
	};
}
function stringifyDeclarationImports(imports) {
	return Object.entries(imports).sort(([a], [b]) => a.localeCompare(b)).map(([name, v]) => {
		if (!/^\w+$/.test(name)) name = `'${name}'`;
		return `${name}: ${v}`;
	});
}
function getDeclaration(ctx, filepath, originalImports) {
	const imports = getDeclarationImports(ctx, filepath);
	if (!imports) return;
	const declarations = {
		component: stringifyDeclarationImports({
			...originalImports === null || originalImports === void 0 ? void 0 : originalImports.component,
			...imports.component
		}),
		directive: stringifyDeclarationImports({
			...originalImports === null || originalImports === void 0 ? void 0 : originalImports.directive,
			...imports.directive
		})
	};
	let code = `/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}

/* prettier-ignore */
declare module 'vue' {`;
	if (Object.keys(declarations.component).length > 0) code += `
  export interface GlobalComponents {
    ${declarations.component.join("\n    ")}
  }`;
	if (Object.keys(declarations.directive).length > 0) code += `
  export interface GlobalDirectives {
    ${declarations.directive.join("\n    ")}
  }`;
	code += "\n}\n";
	return code;
}
async function writeFile$1(filePath, content) {
	await mkdir(dirname(filePath), { recursive: true });
	return await writeFile(filePath, content, "utf-8");
}
async function writeDeclaration(ctx, filepath, removeUnused = false) {
	const originalContent = existsSync(filepath) ? await readFile(filepath, "utf-8") : "";
	const originalImports = removeUnused ? void 0 : parseDeclaration(originalContent);
	const code = getDeclaration(ctx, filepath, originalImports);
	if (!code) return;
	if (code !== originalContent) await writeFile$1(filepath, code);
}
async function writeComponentsJson(ctx, _removeUnused = false) {
	if (!ctx.dumpComponentsInfoPath) return;
	const components = [...Object.entries({
		...ctx.componentNameMap,
		...ctx.componentCustomMap
	}).map(([_, { name, as, from }]) => ({
		name: name || "default",
		as,
		from
	})), ...resolveTypeImports(ctx.options.types)];
	await writeFile$1(ctx.dumpComponentsInfoPath, JSON.stringify(components, null, 2));
}

//#endregion
//#region src/core/fs/glob.ts
const debug$4 = Debug("unplugin-vue-components:glob");
function searchComponents(ctx) {
	var _ctx$options$resolver;
	debug$4(`started with: [${ctx.options.globs.join(", ")}]`);
	const root = ctx.root;
	const files = globSync(ctx.options.globs, {
		ignore: ctx.options.globsExclude,
		onlyFiles: true,
		cwd: root,
		absolute: true,
		expandDirectories: false
	});
	if (!files.length && !((_ctx$options$resolver = ctx.options.resolvers) === null || _ctx$options$resolver === void 0 ? void 0 : _ctx$options$resolver.length)) console.warn("[unplugin-vue-components] no components found");
	debug$4(`${files.length} components found.`);
	ctx.addComponents(files);
}

//#endregion
//#region src/core/options.ts
const defaultOptions = {
	dirs: "src/components",
	extensions: "vue",
	deep: true,
	dts: isPackageExists("typescript"),
	directoryAsNamespace: false,
	collapseSamePrefixes: false,
	globalNamespaces: [],
	transformerUserResolveFunctions: true,
	resolvers: [],
	importPathTransform: (v) => v,
	allowOverrides: false,
	sourcemap: true,
	dumpComponentsInfo: false,
	prefix: ""
};
function normalizeResolvers(resolvers) {
	return toArray(resolvers).flat().map((r) => typeof r === "function" ? {
		resolve: r,
		type: "component"
	} : r);
}
function resolveGlobsExclude(root, glob) {
	const excludeReg = /^!/;
	return slash(`${excludeReg.test(glob) ? "!" : ""}${resolve(root, glob.replace(excludeReg, ""))}`);
}
function resolveOptions(options, root) {
	const resolved = Object.assign({}, defaultOptions, options);
	resolved.resolvers = normalizeResolvers(resolved.resolvers);
	resolved.extensions = toArray(resolved.extensions);
	if (resolved.globs) {
		resolved.globs = toArray(resolved.globs).map((glob) => resolveGlobsExclude(root, glob));
		resolved.resolvedDirs = [];
	} else {
		const extsGlob = resolved.extensions.length === 1 ? resolved.extensions : `{${resolved.extensions.join(",")}}`;
		resolved.dirs = toArray(resolved.dirs);
		const globs = resolved.dirs.map((i) => resolveGlobsExclude(root, i));
		resolved.resolvedDirs = globs.filter((i) => !i.startsWith("!"));
		resolved.globs = globs.map((i) => {
			let prefix = "";
			if (i.startsWith("!")) {
				prefix = "!";
				i = i.slice(1);
			}
			return resolved.deep ? prefix + slash(join(i, `**/*.${extsGlob}`)) : prefix + slash(join(i, `*.${extsGlob}`));
		});
		if (!resolved.extensions.length) throw new Error("[unplugin-vue-components] `extensions` option is required to search for components");
	}
	resolved.globsExclude = toArray(resolved.globsExclude || []).map((i) => resolveGlobsExclude(root, i));
	resolved.globs = resolved.globs.filter((i) => {
		if (!i.startsWith("!")) return true;
		resolved.globsExclude.push(i.slice(1));
		return false;
	});
	resolved.dts = !resolved.dts ? false : resolve(root, typeof resolved.dts === "string" ? resolved.dts : "components.d.ts");
	if (!resolved.types && resolved.dts) resolved.types = detectTypeImports();
	resolved.types = resolved.types || [];
	resolved.root = root;
	resolved.version = resolved.version ?? getVueVersion(root);
	if (resolved.version < 2 || resolved.version >= 4) throw new Error(`[unplugin-vue-components] unsupported version: ${resolved.version}`);
	resolved.transformer = options.transformer || `vue${Math.trunc(resolved.version)}`;
	resolved.directives = typeof options.directives === "boolean" ? options.directives : !resolved.resolvers.some((i) => i.type === "directive") ? false : resolved.version >= 3;
	return resolved;
}
function getVueVersion(root) {
	var _getPackageInfoSync;
	const raw = ((_getPackageInfoSync = getPackageInfoSync("vue", { paths: [join(root, "/")] })) === null || _getPackageInfoSync === void 0 ? void 0 : _getPackageInfoSync.version) || "3";
	const version = +raw.split(".").slice(0, 2).join(".");
	if (version === 2.7) return 2.7;
	else if (version < 2.7) return 2;
	return 3;
}

//#endregion
//#region src/core/transforms/component.ts
const debug$3 = Debug("unplugin-vue-components:transform:component");
function resolveVue2$1(code, s) {
	const results = [];
	for (const match of code.matchAll(/\b(_c|h)\(\s*['"](.+?)["']([,)])/g)) {
		const [full, renderFunctionName, matchedName, append] = match;
		if (match.index != null && matchedName && !matchedName.startsWith("_")) {
			const start = match.index;
			const end = start + full.length;
			results.push({
				rawName: matchedName,
				replace: (resolved) => s.overwrite(start, end, `${renderFunctionName}(${resolved}${append}`)
			});
		}
	}
	return results;
}
function resolveVue3$1(code, s, transformerUserResolveFunctions) {
	const results = [];
	/**
	* when using some plugin like plugin-vue-jsx, resolveComponent will be imported as resolveComponent1 to avoid duplicate import
	*/
	for (const match of code.matchAll(/_?resolveComponent\d*\("(.+?)"\)/g)) {
		if (!transformerUserResolveFunctions && !match[0].startsWith("_")) continue;
		const matchedName = match[1];
		if (match.index != null && matchedName && !matchedName.startsWith("_")) {
			const start = match.index;
			const end = start + match[0].length;
			results.push({
				rawName: matchedName,
				replace: (resolved) => s.overwrite(start, end, resolved)
			});
		}
	}
	return results;
}
async function transformComponent(code, transformer$1, s, ctx, sfcPath) {
	let no = 0;
	const results = transformer$1 === "vue2" ? resolveVue2$1(code, s) : resolveVue3$1(code, s, ctx.options.transformerUserResolveFunctions);
	for (const { rawName, replace } of results) {
		debug$3(`| ${rawName}`);
		const name = pascalCase(rawName);
		ctx.updateUsageMap(sfcPath, [name]);
		const component = await ctx.findComponent(name, "component", [sfcPath]);
		if (component) {
			const varName = `__unplugin_components_${no}`;
			s.prepend(`${stringifyComponentImport({
				...component,
				as: varName
			}, ctx)};\n`);
			no += 1;
			replace(varName);
		}
	}
	debug$3(`^ (${no})`);
}

//#endregion
//#region src/core/transforms/directive/vue2.ts
/**
* Get Vue 2 render function position
*/
function getRenderFnStart(program) {
	var _ref;
	const renderFn = program.body.find((node) => node.type === "VariableDeclaration" && node.declarations[0].id.type === "Identifier" && ["render", "_sfc_render"].includes(node.declarations[0].id.name));
	const start = renderFn === null || renderFn === void 0 || (_ref = renderFn.declarations[0].init) === null || _ref === void 0 || (_ref = _ref.body) === null || _ref === void 0 ? void 0 : _ref.start;
	if (start === null || start === void 0) throw new Error("[unplugin-vue-components:directive] Cannot find render function position.");
	return start + 1;
}
async function resolveVue2(code, s) {
	if (!isPackageExists("@babel/parser")) throw new Error("[unplugin-vue-components:directive] To use Vue 2 directive you will need to install Babel first: \"npm install -D @babel/parser\"");
	const { parse: parse$1 } = await importModule("@babel/parser");
	const { program } = parse$1(code, { sourceType: "module" });
	const nodes = [];
	const { walk } = await import("./src-a29vieKX.js");
	walk(program, { enter(node) {
		if (node.type === "CallExpression") nodes.push(node);
	} });
	if (nodes.length === 0) return [];
	let _renderStart;
	const getRenderStart = () => {
		if (_renderStart !== void 0) return _renderStart;
		return _renderStart = getRenderFnStart(program);
	};
	const results = [];
	for (const node of nodes) {
		var _args$, _args$1$properties$fi;
		const { callee, arguments: args } = node;
		if (callee.type !== "Identifier" || callee.name !== "_c" || ((_args$ = args[1]) === null || _args$ === void 0 ? void 0 : _args$.type) !== "ObjectExpression") continue;
		const directives = (_args$1$properties$fi = args[1].properties.find((property) => property.type === "ObjectProperty" && property.key.type === "Identifier" && property.key.name === "directives")) === null || _args$1$properties$fi === void 0 ? void 0 : _args$1$properties$fi.value;
		if (!directives || directives.type !== "ArrayExpression") continue;
		for (const directive of directives.elements) {
			var _directive$properties;
			if ((directive === null || directive === void 0 ? void 0 : directive.type) !== "ObjectExpression") continue;
			const nameNode = (_directive$properties = directive.properties.find((p) => p.type === "ObjectProperty" && p.key.type === "Identifier" && p.key.name === "name")) === null || _directive$properties === void 0 ? void 0 : _directive$properties.value;
			if ((nameNode === null || nameNode === void 0 ? void 0 : nameNode.type) !== "StringLiteral") continue;
			const name = nameNode.value;
			if (!name || name.startsWith("_")) continue;
			results.push({
				rawName: name,
				replace: (resolved) => {
					s.prependLeft(getRenderStart(), `\nthis.$options.directives["${name}"] = ${resolved};`);
				}
			});
		}
	}
	return results;
}

//#endregion
//#region src/core/transforms/directive/vue3.ts
function resolveVue3(code, s, transformerUserResolveFunctions) {
	const results = [];
	for (const match of code.matchAll(/_?resolveDirective\("(.+?)"\)/g)) {
		const matchedName = match[1];
		if (!transformerUserResolveFunctions && !match[0].startsWith("_")) continue;
		if (match.index != null && matchedName && !matchedName.startsWith("_")) {
			const start = match.index;
			const end = start + match[0].length;
			results.push({
				rawName: matchedName,
				replace: (resolved) => s.overwrite(start, end, resolved)
			});
		}
	}
	return results;
}

//#endregion
//#region src/core/transforms/directive/index.ts
const debug$2 = Debug("unplugin-vue-components:transform:directive");
async function transformDirective(code, transformer$1, s, ctx, sfcPath) {
	let no = 0;
	const results = await (transformer$1 === "vue2" ? resolveVue2(code, s) : resolveVue3(code, s));
	for (const { rawName, replace } of results) {
		debug$2(`| ${rawName}`);
		const name = `${DIRECTIVE_IMPORT_PREFIX}${pascalCase(rawName)}`;
		ctx.updateUsageMap(sfcPath, [name]);
		const directive = await ctx.findComponent(name, "directive", [sfcPath]);
		if (!directive) continue;
		const varName = `__unplugin_directives_${no}`;
		s.prepend(`${stringifyComponentImport({
			...directive,
			as: varName
		}, ctx)};\n`);
		no += 1;
		replace(varName);
	}
	debug$2(`^ (${no})`);
}

//#endregion
//#region src/core/transformer.ts
const debug$1 = Debug("unplugin-vue-components:transformer");
function transformer(ctx, transformer$1) {
	return async (code, id, path) => {
		ctx.searchGlob();
		const sfcPath = ctx.normalizePath(path);
		debug$1(sfcPath);
		const s = new MagicString(code);
		await transformComponent(code, transformer$1, s, ctx, sfcPath);
		if (ctx.options.directives) await transformDirective(code, transformer$1, s, ctx, sfcPath);
		s.prepend(DISABLE_COMMENT);
		const result = { code: s.toString() };
		if (ctx.sourcemap) result.map = s.generateMap({
			source: id,
			includeContent: true,
			hires: "boundary"
		});
		return result;
	};
}

//#endregion
//#region src/core/context.ts
const debug = {
	components: Debug("unplugin-vue-components:context:components"),
	search: Debug("unplugin-vue-components:context:search"),
	hmr: Debug("unplugin-vue-components:context:hmr"),
	declaration: Debug("unplugin-vue-components:declaration"),
	env: Debug("unplugin-vue-components:env")
};
var Context = class {
	options;
	transformer = void 0;
	_componentPaths = new Set();
	_componentNameMap = {};
	_componentUsageMap = {};
	_componentCustomMap = {};
	_directiveCustomMap = {};
	_server;
	root = process.cwd();
	sourcemap = true;
	alias = {};
	dumpComponentsInfoPath;
	constructor(rawOptions) {
		this.rawOptions = rawOptions;
		this.options = resolveOptions(rawOptions, this.root);
		this.sourcemap = rawOptions.sourcemap ?? true;
		this.generateDeclaration = throttle(500, this._generateDeclaration.bind(this), { noLeading: false });
		if (this.options.dumpComponentsInfo) {
			const dumpComponentsInfo = this.options.dumpComponentsInfo === true ? "./.components-info.json" : this.options.dumpComponentsInfo ?? false;
			this.dumpComponentsInfoPath = dumpComponentsInfo;
			this.generateComponentsJson = throttle(500, this._generateComponentsJson.bind(this), { noLeading: false });
		}
		this.setTransformer(this.options.transformer);
	}
	setRoot(root) {
		if (this.root === root) return;
		debug.env("root", root);
		this.root = root;
		this.options = resolveOptions(this.rawOptions, this.root);
	}
	setTransformer(name) {
		debug.env("transformer", name);
		this.transformer = transformer(this, name || "vue3");
	}
	transform(code, id) {
		const { path, query } = parseId(id);
		return this.transformer(code, id, path, query);
	}
	setupViteServer(server) {
		if (this._server === server) return;
		this._server = server;
		this.setupWatcher(server.watcher);
	}
	setupWatcher(watcher) {
		const { globs } = this.options;
		watcher.on("unlink", (path) => {
			if (!matchGlobs(path, globs)) return;
			path = slash(path);
			this.removeComponents(path);
			this.onUpdate(path);
		});
		watcher.on("add", (path) => {
			if (!matchGlobs(path, globs)) return;
			path = slash(path);
			this.addComponents(path);
			this.onUpdate(path);
		});
	}
	/**
	* start watcher for webpack
	*/
	setupWatcherWebpack(watcher, emitUpdate) {
		const { globs } = this.options;
		watcher.on("unlink", (path) => {
			if (!matchGlobs(path, globs)) return;
			path = slash(path);
			this.removeComponents(path);
			emitUpdate(path, "unlink");
		});
		watcher.on("add", (path) => {
			if (!matchGlobs(path, globs)) return;
			path = slash(path);
			this.addComponents(path);
			emitUpdate(path, "add");
		});
	}
	/**
	* Record the usage of components
	* @param path
	* @param paths paths of used components
	*/
	updateUsageMap(path, paths) {
		if (!this._componentUsageMap[path]) this._componentUsageMap[path] = new Set();
		paths.forEach((p) => {
			this._componentUsageMap[path].add(p);
		});
	}
	addComponents(paths) {
		debug.components("add", paths);
		const size = this._componentPaths.size;
		toArray(paths).forEach((p) => this._componentPaths.add(p));
		if (this._componentPaths.size !== size) {
			this.updateComponentNameMap();
			return true;
		}
		return false;
	}
	addCustomComponents(info) {
		if (info.as) this._componentCustomMap[info.as] = info;
	}
	addCustomDirectives(info) {
		if (info.as) this._directiveCustomMap[info.as] = info;
	}
	removeComponents(paths) {
		debug.components("remove", paths);
		const size = this._componentPaths.size;
		toArray(paths).forEach((p) => this._componentPaths.delete(p));
		if (this._componentPaths.size !== size) {
			this.updateComponentNameMap();
			return true;
		}
		return false;
	}
	onUpdate(path) {
		this.generateDeclaration();
		this.generateComponentsJson();
		if (!this._server) return;
		const payload = {
			type: "update",
			updates: []
		};
		const timestamp = +new Date();
		const name = pascalCase(getNameFromFilePath(path, this.options));
		Object.entries(this._componentUsageMap).forEach(([key, values]) => {
			if (values.has(name)) {
				const r = `/${slash(relative(this.root, key))}`;
				payload.updates.push({
					acceptedPath: r,
					path: r,
					timestamp,
					type: "js-update"
				});
			}
		});
		if (payload.updates.length) this._server.ws.send(payload);
	}
	updateComponentNameMap() {
		this._componentNameMap = {};
		Array.from(this._componentPaths).forEach((path) => {
			const name = pascalCase(getNameFromFilePath(path, this.options));
			if (isExclude(name, this.options.excludeNames)) {
				debug.components("exclude", name);
				return;
			}
			if (this._componentNameMap[name] && !this.options.allowOverrides) {
				console.warn(`[unplugin-vue-components] component "${name}"(${path}) has naming conflicts with other components, ignored.`);
				return;
			}
			this._componentNameMap[name] = {
				as: name,
				from: path
			};
		});
	}
	async findComponent(name, type, excludePaths = []) {
		let info = this._componentNameMap[name];
		if (info && !excludePaths.includes(info.from) && !excludePaths.includes(info.from.slice(1))) return info;
		for (const resolver of this.options.resolvers) {
			if (resolver.type !== type) continue;
			const result = await resolver.resolve(type === "directive" ? name.slice(DIRECTIVE_IMPORT_PREFIX.length) : name);
			if (!result) continue;
			if (typeof result === "string") info = {
				as: name,
				from: result
			};
			else info = {
				as: name,
				...normalizeComponentInfo(result)
			};
			if (type === "component") this.addCustomComponents(info);
			else if (type === "directive") this.addCustomDirectives(info);
			return info;
		}
		return void 0;
	}
	normalizePath(path) {
		var _this$viteConfig, _this$viteConfig2;
		return resolveAlias(path, ((_this$viteConfig = this.viteConfig) === null || _this$viteConfig === void 0 || (_this$viteConfig = _this$viteConfig.resolve) === null || _this$viteConfig === void 0 ? void 0 : _this$viteConfig.alias) || ((_this$viteConfig2 = this.viteConfig) === null || _this$viteConfig2 === void 0 ? void 0 : _this$viteConfig2.alias) || []);
	}
	relative(path) {
		if (path.startsWith("/") && !path.startsWith(this.root)) return slash(path.slice(1));
		return slash(relative(this.root, path));
	}
	_searched = false;
	/**
	* This search for components in with the given options.
	* Will be called multiple times to ensure file loaded,
	* should normally run only once.
	*/
	searchGlob() {
		if (this._searched) return;
		searchComponents(this);
		debug.search(this._componentNameMap);
		this._searched = true;
	}
	_generateDeclaration(removeUnused = !this._server) {
		if (!this.options.dts) return;
		debug.declaration("generating dts");
		return writeDeclaration(this, this.options.dts, removeUnused);
	}
	generateDeclaration(removeUnused = !this._server) {
		this._generateDeclaration(removeUnused);
	}
	_generateComponentsJson(removeUnused = !this._server) {
		if (!Object.keys(this._componentNameMap).length) return;
		debug.components("generating components-info");
		return writeComponentsJson(this, removeUnused);
	}
	generateComponentsJson(removeUnused = !this._server) {
		this._generateComponentsJson(removeUnused);
	}
	get componentNameMap() {
		return this._componentNameMap;
	}
	get componentCustomMap() {
		return this._componentCustomMap;
	}
	get directiveCustomMap() {
		return this._directiveCustomMap;
	}
};

//#endregion
//#region src/core/unplugin.ts
const PLUGIN_NAME = "unplugin:webpack";
var unplugin_default = createUnplugin((options = {}) => {
	const filter = createFilter(options.include || [
		/\.vue$/,
		/\.vue\?vue/,
		/\.vue\.[tj]sx?\?vue/,
		/\.vue\?v=/
	], options.exclude || [
		/[\\/]node_modules[\\/]/,
		/[\\/]\.git[\\/]/,
		/[\\/]\.nuxt[\\/]/
	]);
	const ctx = new Context(options);
	const api = {
		async findComponent(name, filename) {
			return await ctx.findComponent(name, "component", filename ? [filename] : []);
		},
		stringifyImport(info) {
			return stringifyComponentImport(info, ctx);
		}
	};
	return {
		name: "unplugin-vue-components",
		enforce: "post",
		api,
		transformInclude(id) {
			return filter(id);
		},
		async transform(code, id) {
			if (!shouldTransform(code)) return null;
			try {
				const result = await ctx.transform(code, id);
				ctx.generateDeclaration();
				ctx.generateComponentsJson();
				return result;
			} catch (e) {
				this.error(e);
			}
		},
		vite: {
			configResolved(config) {
				ctx.setRoot(config.root);
				ctx.sourcemap = true;
				if (config.plugins.find((i) => i.name === "vite-plugin-vue2")) ctx.setTransformer("vue2");
				if (ctx.options.dts) {
					ctx.searchGlob();
					if (!existsSync(ctx.options.dts)) ctx.generateDeclaration();
				}
				if (ctx.options.dumpComponentsInfo && ctx.dumpComponentsInfoPath) {
					if (!existsSync(ctx.dumpComponentsInfoPath)) ctx.generateComponentsJson();
				}
				if (config.build.watch && config.command === "build") ctx.setupWatcher(chokidar.watch(ctx.options.globs));
			},
			configureServer(server) {
				ctx.setupViteServer(server);
			}
		},
		webpack(compiler) {
			let watcher;
			let fileDepQueue = [];
			compiler.hooks.watchRun.tap(PLUGIN_NAME, () => {
				if (!watcher && compiler.watching) {
					watcher = compiler.watching;
					ctx.setupWatcherWebpack(chokidar.watch(ctx.options.globs), (path, type) => {
						fileDepQueue.push({
							path,
							type
						});
						process.nextTick(() => {
							watcher.invalidate();
						});
					});
				}
			});
			compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
				if (fileDepQueue.length) {
					fileDepQueue.forEach(({ path, type }) => {
						if (type === "unlink") compilation.fileDependencies.delete(path);
						else compilation.fileDependencies.add(path);
					});
					fileDepQueue = [];
				}
			});
		}
	};
});

//#endregion
export { unplugin_default };