@kimesh/auto-import 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,961 @@
1
+ import { t as OxcExportScanner } from "./oxc-scanner-DrjjlY9k.mjs";
2
+ import { a as piniaPreset, c as vuePreset, d as collectExistingDirectories, i as normalizePreset, l as vueRouterPreset, n as builtinPresets, o as resolvePresets, r as kimeshPreset, s as tanstackQueryPreset, t as RegistryBuilder, u as ConflictResolver } from "./builder-c6-47OHx.mjs";
3
+ import { parseSync } from "oxc-parser";
4
+ import { parse } from "@vue/compiler-sfc";
5
+ import * as fs from "node:fs";
6
+ import * as path from "pathe";
7
+ import { consola } from "consola";
8
+ import MagicString from "magic-string";
9
+ import Components from "unplugin-vue-components/vite";
10
+
11
+ //#region src/scanner/reference-detector.ts
12
+ /**
13
+ * @kimesh/auto-import - Unresolved Reference Detector
14
+ *
15
+ * Detects unresolved identifiers in source code using OXC AST analysis.
16
+ * These are the identifiers that need auto-importing.
17
+ */
18
+ /**
19
+ * Global identifiers that should not be auto-imported
20
+ */
21
+ const GLOBALS = new Set([
22
+ "undefined",
23
+ "null",
24
+ "true",
25
+ "false",
26
+ "NaN",
27
+ "Infinity",
28
+ "Object",
29
+ "Array",
30
+ "String",
31
+ "Number",
32
+ "Boolean",
33
+ "Symbol",
34
+ "BigInt",
35
+ "Function",
36
+ "Date",
37
+ "RegExp",
38
+ "Error",
39
+ "TypeError",
40
+ "SyntaxError",
41
+ "RangeError",
42
+ "ReferenceError",
43
+ "EvalError",
44
+ "URIError",
45
+ "Map",
46
+ "Set",
47
+ "WeakMap",
48
+ "WeakSet",
49
+ "Promise",
50
+ "Proxy",
51
+ "Reflect",
52
+ "JSON",
53
+ "Math",
54
+ "console",
55
+ "window",
56
+ "document",
57
+ "globalThis",
58
+ "setTimeout",
59
+ "setInterval",
60
+ "clearTimeout",
61
+ "clearInterval",
62
+ "fetch",
63
+ "Request",
64
+ "Response",
65
+ "Headers",
66
+ "URL",
67
+ "URLSearchParams",
68
+ "FormData",
69
+ "Blob",
70
+ "File",
71
+ "FileReader",
72
+ "ArrayBuffer",
73
+ "DataView",
74
+ "Int8Array",
75
+ "Uint8Array",
76
+ "Uint8ClampedArray",
77
+ "Int16Array",
78
+ "Uint16Array",
79
+ "Int32Array",
80
+ "Uint32Array",
81
+ "Float32Array",
82
+ "Float64Array",
83
+ "BigInt64Array",
84
+ "BigUint64Array",
85
+ "TextEncoder",
86
+ "TextDecoder",
87
+ "alert",
88
+ "confirm",
89
+ "prompt",
90
+ "open",
91
+ "close",
92
+ "print",
93
+ "localStorage",
94
+ "sessionStorage",
95
+ "navigator",
96
+ "location",
97
+ "history",
98
+ "performance",
99
+ "crypto",
100
+ "indexedDB",
101
+ "caches",
102
+ "requestAnimationFrame",
103
+ "cancelAnimationFrame",
104
+ "MutationObserver",
105
+ "ResizeObserver",
106
+ "IntersectionObserver",
107
+ "CustomEvent",
108
+ "Event",
109
+ "EventTarget",
110
+ "AbortController",
111
+ "AbortSignal",
112
+ "structuredClone",
113
+ "atob",
114
+ "btoa",
115
+ "encodeURI",
116
+ "decodeURI",
117
+ "encodeURIComponent",
118
+ "decodeURIComponent",
119
+ "escape",
120
+ "unescape",
121
+ "isFinite",
122
+ "isNaN",
123
+ "parseFloat",
124
+ "parseInt",
125
+ "eval",
126
+ "process",
127
+ "Buffer",
128
+ "global",
129
+ "__dirname",
130
+ "__filename",
131
+ "require",
132
+ "module",
133
+ "exports",
134
+ "Partial",
135
+ "Required",
136
+ "Readonly",
137
+ "Record",
138
+ "Pick",
139
+ "Omit",
140
+ "Exclude",
141
+ "Extract",
142
+ "NonNullable",
143
+ "Parameters",
144
+ "ReturnType",
145
+ "InstanceType",
146
+ "ThisType",
147
+ "Awaited",
148
+ "Uppercase",
149
+ "Lowercase",
150
+ "Capitalize",
151
+ "Uncapitalize",
152
+ "defineProps",
153
+ "defineEmits",
154
+ "defineExpose",
155
+ "defineOptions",
156
+ "defineSlots",
157
+ "defineModel",
158
+ "withDefaults"
159
+ ]);
160
+ /**
161
+ * Reference detector using scope analysis
162
+ */
163
+ var ReferenceDetector = class {
164
+ /**
165
+ * Detect unresolved references in TypeScript/JavaScript code
166
+ */
167
+ detectInScript(code, filePath) {
168
+ try {
169
+ const result = parseSync(filePath, code, { sourceType: "module" });
170
+ if (result.errors.length > 0) return [];
171
+ return this.detectInAST(result.program);
172
+ } catch {
173
+ return [];
174
+ }
175
+ }
176
+ /**
177
+ * Detect unresolved references in Vue SFC
178
+ */
179
+ detectInVue(code, filePath) {
180
+ try {
181
+ const { descriptor, errors } = parse(code, { filename: filePath });
182
+ if (errors.length > 0) return [];
183
+ const refs = [];
184
+ if (descriptor.scriptSetup) {
185
+ const scriptRefs = this.detectInScript(descriptor.scriptSetup.content, filePath + ".setup.ts");
186
+ refs.push(...scriptRefs);
187
+ }
188
+ if (descriptor.script) {
189
+ const scriptRefs = this.detectInScript(descriptor.script.content, filePath + ".ts");
190
+ refs.push(...scriptRefs);
191
+ }
192
+ return refs;
193
+ } catch {
194
+ return [];
195
+ }
196
+ }
197
+ /**
198
+ * Detect unresolved references in parsed AST
199
+ */
200
+ detectInAST(program) {
201
+ const declarations = /* @__PURE__ */ new Set();
202
+ const references = [];
203
+ this.collectDeclarations(program, declarations);
204
+ this.findUnresolvedReferences(program, declarations, references);
205
+ return references;
206
+ }
207
+ /**
208
+ * Collect all declared identifiers in the scope
209
+ */
210
+ collectDeclarations(node, declarations) {
211
+ if (!node || typeof node !== "object") return;
212
+ switch (node.type) {
213
+ case "VariableDeclaration":
214
+ for (const decl of node.declarations || []) this.collectPatternNames(decl.id, declarations);
215
+ break;
216
+ case "FunctionDeclaration":
217
+ if (node.id?.name) declarations.add(node.id.name);
218
+ for (const param of node.params || []) this.collectPatternNames(param, declarations);
219
+ break;
220
+ case "VariableDeclarator":
221
+ this.collectPatternNames(node.id, declarations);
222
+ break;
223
+ case "ClassDeclaration":
224
+ if (node.id?.name) declarations.add(node.id.name);
225
+ break;
226
+ case "ImportDeclaration":
227
+ for (const spec of node.specifiers || []) if (spec.local?.name) declarations.add(spec.local.name);
228
+ break;
229
+ case "TSInterfaceDeclaration":
230
+ case "TSTypeAliasDeclaration":
231
+ case "TSEnumDeclaration":
232
+ if (node.id?.name) declarations.add(node.id.name);
233
+ break;
234
+ case "CatchClause":
235
+ if (node.param) this.collectPatternNames(node.param, declarations);
236
+ break;
237
+ case "ForInStatement":
238
+ case "ForOfStatement":
239
+ if (node.left?.type === "VariableDeclaration") this.collectDeclarations(node.left, declarations);
240
+ break;
241
+ }
242
+ for (const key of Object.keys(node)) {
243
+ if (key === "type" || key === "start" || key === "end") continue;
244
+ const child = node[key];
245
+ if (Array.isArray(child)) for (const item of child) this.collectDeclarations(item, declarations);
246
+ else if (child && typeof child === "object") this.collectDeclarations(child, declarations);
247
+ }
248
+ }
249
+ /**
250
+ * Collect names from binding patterns
251
+ */
252
+ collectPatternNames(pattern, names) {
253
+ if (!pattern) return;
254
+ switch (pattern.type) {
255
+ case "Identifier":
256
+ names.add(pattern.name);
257
+ break;
258
+ case "ObjectPattern":
259
+ for (const prop of pattern.properties || []) if (prop.type === "RestElement") this.collectPatternNames(prop.argument, names);
260
+ else this.collectPatternNames(prop.value || prop.key, names);
261
+ break;
262
+ case "ArrayPattern":
263
+ for (const element of pattern.elements || []) if (element) this.collectPatternNames(element, names);
264
+ break;
265
+ case "RestElement":
266
+ this.collectPatternNames(pattern.argument, names);
267
+ break;
268
+ case "AssignmentPattern":
269
+ this.collectPatternNames(pattern.left, names);
270
+ break;
271
+ }
272
+ }
273
+ /**
274
+ * Find references to undeclared identifiers
275
+ */
276
+ findUnresolvedReferences(node, declarations, references) {
277
+ if (!node || typeof node !== "object") return;
278
+ if (node.type === "Identifier" && node.name) {
279
+ const name = node.name;
280
+ if (!declarations.has(name) && !GLOBALS.has(name) && !this.isPropertyAccess(node) && !this.isPropertyKey(node) && !this.isLabelReference(node)) {
281
+ const isType = this.isTypeContext(node);
282
+ if (!references.find((r) => r.name === name && r.start === node.start)) references.push({
283
+ name,
284
+ start: node.start,
285
+ end: node.end,
286
+ isType
287
+ });
288
+ }
289
+ }
290
+ for (const key of Object.keys(node)) {
291
+ if (this.shouldSkipProperty(key)) continue;
292
+ const child = node[key];
293
+ if (Array.isArray(child)) for (const item of child) this.findUnresolvedReferences(item, declarations, references);
294
+ else if (child && typeof child === "object") this.findUnresolvedReferences(child, declarations, references);
295
+ }
296
+ }
297
+ /**
298
+ * Check if identifier is a property access (obj.prop)
299
+ */
300
+ isPropertyAccess(node) {
301
+ const parent = node._parent;
302
+ return parent?.type === "MemberExpression" && parent.property === node && !parent.computed;
303
+ }
304
+ /**
305
+ * Check if identifier is a property key ({ key: value })
306
+ */
307
+ isPropertyKey(node) {
308
+ const parent = node._parent;
309
+ return parent?.type === "Property" && parent.key === node && !parent.computed;
310
+ }
311
+ /**
312
+ * Check if identifier is a label reference
313
+ */
314
+ isLabelReference(node) {
315
+ const parent = node._parent;
316
+ return parent?.type === "LabeledStatement" || parent?.type === "BreakStatement" || parent?.type === "ContinueStatement";
317
+ }
318
+ /**
319
+ * Check if identifier is in type context
320
+ */
321
+ isTypeContext(node) {
322
+ const parent = node._parent;
323
+ return parent?.type === "TSTypeReference" || parent?.type === "TSQualifiedName" || parent?.type === "TSTypeQuery" || parent?.type === "TSImportType";
324
+ }
325
+ /**
326
+ * Properties to skip when recursing
327
+ */
328
+ shouldSkipProperty(key) {
329
+ return key === "type" || key === "start" || key === "end" || key === "_parent" || key === "loc" || key === "range";
330
+ }
331
+ };
332
+
333
+ //#endregion
334
+ //#region src/script/injector.ts
335
+ /**
336
+ * @kimesh/auto-import - Script Import Injector
337
+ *
338
+ * Handles injecting import statements into script code.
339
+ */
340
+ var ImportInjector = class {
341
+ inject(code, imports, isVue) {
342
+ if (imports.length === 0) return null;
343
+ const s = new MagicString(code);
344
+ const importStatements = this.generateImportStatements(imports);
345
+ const insertPoint = this.findImportInsertionPoint(code, isVue);
346
+ s.appendLeft(insertPoint, "\n" + importStatements + "\n");
347
+ return {
348
+ code: s.toString(),
349
+ map: s.generateMap({ hires: true }),
350
+ count: imports.length
351
+ };
352
+ }
353
+ generateImportStatements(imports) {
354
+ const groups = this.groupImportsBySource(imports);
355
+ const statements = [];
356
+ for (const [source, entries] of groups) {
357
+ const { defaultImports, namedImports, typeImports } = this.categorizeImports(entries);
358
+ const parts = [];
359
+ if (defaultImports.length > 0) parts.push(defaultImports[0]);
360
+ if (namedImports.length > 0) parts.push(`{ ${namedImports.join(", ")} }`);
361
+ if (parts.length > 0) statements.push(`import ${parts.join(", ")} from '${source}';`);
362
+ if (typeImports.length > 0) statements.push(`import type { ${typeImports.join(", ")} } from '${source}';`);
363
+ }
364
+ return statements.join("\n");
365
+ }
366
+ groupImportsBySource(imports) {
367
+ const groups = /* @__PURE__ */ new Map();
368
+ for (const entry of imports) {
369
+ const existing = groups.get(entry.from) ?? [];
370
+ existing.push(entry);
371
+ groups.set(entry.from, existing);
372
+ }
373
+ return groups;
374
+ }
375
+ categorizeImports(entries) {
376
+ const defaultImports = [];
377
+ const namedImports = [];
378
+ const typeImports = [];
379
+ for (const entry of entries) {
380
+ const importName = entry.as ? `${entry.name} as ${entry.as}` : entry.name;
381
+ if (entry.isDefault) defaultImports.push(entry.as ?? entry.name);
382
+ else if (entry.isType) typeImports.push(importName);
383
+ else namedImports.push(importName);
384
+ }
385
+ return {
386
+ defaultImports,
387
+ namedImports,
388
+ typeImports
389
+ };
390
+ }
391
+ findImportInsertionPoint(code, isVue) {
392
+ if (isVue) return this.findVueScriptInsertionPoint(code);
393
+ return this.findJsInsertionPoint(code);
394
+ }
395
+ findVueScriptInsertionPoint(code) {
396
+ const scriptMatch = code.match(/<script(\s+[^>]*)?>|<script\s+setup[^>]*>/i);
397
+ if (!scriptMatch || scriptMatch.index === void 0) return 0;
398
+ const insertPoint = scriptMatch.index + scriptMatch[0].length;
399
+ const importMatch = code.slice(insertPoint).match(/^(\s*\n?\s*import\s+.*?['"].*?['"];?\s*)+/);
400
+ return importMatch ? insertPoint + importMatch[0].length : insertPoint;
401
+ }
402
+ findJsInsertionPoint(code) {
403
+ const importRegex = /^import\s+.*?['"].*?['"];?\s*$/gm;
404
+ let lastImportEnd = 0;
405
+ let match;
406
+ while ((match = importRegex.exec(code)) !== null) lastImportEnd = match.index + match[0].length;
407
+ if (lastImportEnd > 0) return lastImportEnd;
408
+ const useStrictMatch = code.match(/^(['"]use strict['"];?\s*)/);
409
+ if (useStrictMatch) return useStrictMatch[0].length;
410
+ const shebangMatch = code.match(/^#!.*\n/);
411
+ if (shebangMatch) return shebangMatch[0].length;
412
+ return 0;
413
+ }
414
+ extractExistingImports(code, isVue) {
415
+ const imported = /* @__PURE__ */ new Set();
416
+ const scriptContent = isVue ? this.extractVueScriptContent(code) : code;
417
+ if (!scriptContent) return imported;
418
+ const importRegex = /import\s+(?:type\s+)?(?:(\w+)\s*,?\s*)?(?:\{([^}]*)\})?\s*from\s*['"][^'"]+['"]/g;
419
+ let match;
420
+ while ((match = importRegex.exec(scriptContent)) !== null) {
421
+ if (match[1]) imported.add(match[1]);
422
+ if (match[2]) for (const name of match[2].split(",")) {
423
+ const trimmed = name.trim();
424
+ if (!trimmed) continue;
425
+ const asMatch = trimmed.match(/(\w+)\s+as\s+(\w+)/);
426
+ imported.add(asMatch ? asMatch[2] : trimmed);
427
+ }
428
+ }
429
+ return imported;
430
+ }
431
+ extractVueScriptContent(code) {
432
+ const scriptMatch = code.match(/<script[^>]*>([\s\S]*?)<\/script>/gi);
433
+ if (!scriptMatch) return null;
434
+ return scriptMatch.map((m) => {
435
+ const content = m.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
436
+ return content ? content[1] : "";
437
+ }).join("\n");
438
+ }
439
+ };
440
+
441
+ //#endregion
442
+ //#region src/types/generator.ts
443
+ /**
444
+ * @kimesh/auto-import - Type Declaration Generator
445
+ *
446
+ * Generates .d.ts files for auto-imported modules.
447
+ */
448
+ const logger$2 = consola.withTag("kimesh:auto-import:types");
449
+ async function generateDtsFiles(registry, outputDir) {
450
+ fs.mkdirSync(outputDir, { recursive: true });
451
+ writeFile(outputDir, "auto-imports.d.ts", generateAutoImportsDts(registry));
452
+ const presetComponents = generatePresetComponentsDts(registry);
453
+ if (presetComponents) writeFile(outputDir, "kimesh-components.d.ts", presetComponents);
454
+ writeFile(outputDir, ".eslintrc-auto-import.json", generateEslintGlobals(registry));
455
+ }
456
+ function writeFile(outputDir, filename, content) {
457
+ const filePath = path.join(outputDir, filename);
458
+ fs.writeFileSync(filePath, content, "utf-8");
459
+ logger$2.debug(`Generated: ${filePath}`);
460
+ }
461
+ function generateAutoImportsDts(registry) {
462
+ const header = [
463
+ "/* eslint-disable */",
464
+ "/* prettier-ignore */",
465
+ "// @ts-nocheck",
466
+ "// noinspection JSUnusedGlobalSymbols",
467
+ "",
468
+ "// Auto-generated by @kimesh/auto-import",
469
+ "// DO NOT EDIT - changes will be overwritten",
470
+ "",
471
+ "export {}",
472
+ "",
473
+ "declare global {"
474
+ ];
475
+ const groups = groupImportsBySource(registry.imports, [
476
+ "composable",
477
+ "utility",
478
+ "preset",
479
+ "store"
480
+ ]);
481
+ const body = [];
482
+ for (const [source, entries] of groups) {
483
+ body.push(` // ${source}`);
484
+ for (const entry of entries) body.push(formatGlobalDeclaration(entry));
485
+ body.push("");
486
+ }
487
+ return [
488
+ ...header,
489
+ ...body,
490
+ "}"
491
+ ].join("\n");
492
+ }
493
+ function formatGlobalDeclaration(entry) {
494
+ const comment = entry.layer !== "app" ? ` // from ${entry.layer}` : "";
495
+ if (entry.isType) return ` type ${entry.name} = import('${entry.from}').${entry.name}${comment}`;
496
+ if (entry.isDefault) return ` const ${entry.name}: typeof import('${entry.from}').default${comment}`;
497
+ return ` const ${entry.name}: typeof import('${entry.from}').${entry.name}${comment}`;
498
+ }
499
+ function generateEslintGlobals(registry) {
500
+ const globals = {};
501
+ for (const [name, entry] of registry.imports) if (!entry.isType) globals[name] = "readonly";
502
+ return JSON.stringify({ globals }, null, 2);
503
+ }
504
+ const EXCLUDED_TYPE_NAMES = new Set([
505
+ "Ref",
506
+ "ComputedRef",
507
+ "UnwrapRef",
508
+ "ShallowRef",
509
+ "WritableComputedRef",
510
+ "ToRefs",
511
+ "PropType",
512
+ "Component",
513
+ "ComponentPublicInstance",
514
+ "VNode",
515
+ "RouteLocationNormalized",
516
+ "RouteLocationNormalizedLoaded",
517
+ "RouteRecordRaw",
518
+ "NavigationGuard",
519
+ "NavigationFailure",
520
+ "Router",
521
+ "RouteLocation",
522
+ "LocationQuery",
523
+ "RouteParams"
524
+ ]);
525
+ function generatePresetComponentsDts(registry) {
526
+ const presetComponents = [...registry.components.entries()].filter(([name, entry]) => entry.type === "preset" && /^[A-Z][a-zA-Z0-9]*$/.test(name) && !entry.isType && !EXCLUDED_TYPE_NAMES.has(name)).sort((a, b) => a[0].localeCompare(b[0]));
527
+ if (presetComponents.length === 0) return null;
528
+ const header = [
529
+ "/* eslint-disable */",
530
+ "// @ts-nocheck",
531
+ "// Generated by @kimesh/auto-import",
532
+ "// Preset components for Vue templates",
533
+ "// biome-ignore lint: disable",
534
+ "export {}",
535
+ "",
536
+ "/* prettier-ignore */",
537
+ "declare module 'vue' {",
538
+ " export interface GlobalComponents {"
539
+ ];
540
+ const componentDeclarations = presetComponents.map(([name, entry]) => {
541
+ return ` ${name}: ${entry.isDefault ? `typeof import('${entry.from}').default` : `typeof import('${entry.from}')['${entry.name}']`}`;
542
+ });
543
+ return [
544
+ ...header,
545
+ ...componentDeclarations,
546
+ " }",
547
+ "}"
548
+ ].join("\n");
549
+ }
550
+ function groupImportsBySource(imports, types) {
551
+ const groups = /* @__PURE__ */ new Map();
552
+ for (const [, entry] of imports) {
553
+ if (!types.includes(entry.type)) continue;
554
+ const existing = groups.get(entry.from) ?? [];
555
+ existing.push(entry);
556
+ groups.set(entry.from, existing);
557
+ }
558
+ for (const entries of groups.values()) entries.sort((a, b) => {
559
+ if (a.isType !== b.isType) return a.isType ? 1 : -1;
560
+ return a.name.localeCompare(b.name);
561
+ });
562
+ return groups;
563
+ }
564
+ function generateSourceDts(source, entries) {
565
+ const lines = [
566
+ "// Auto-generated by @kimesh/auto-import",
567
+ "",
568
+ `// Exports from: ${source}`,
569
+ ""
570
+ ];
571
+ const defaultExports = entries.filter((e) => e.isDefault);
572
+ const namedExports = entries.filter((e) => !e.isDefault && !e.isType);
573
+ const typeExports = entries.filter((e) => e.isType);
574
+ if (defaultExports.length > 0) lines.push(`export { default as ${defaultExports[0].name} } from '${source}'`);
575
+ if (namedExports.length > 0) {
576
+ const names = namedExports.map((e) => e.as ? `${e.name} as ${e.as}` : e.name);
577
+ lines.push(`export { ${names.join(", ")} } from '${source}'`);
578
+ }
579
+ if (typeExports.length > 0) {
580
+ const names = typeExports.map((e) => e.as ? `${e.name} as ${e.as}` : e.name);
581
+ lines.push(`export type { ${names.join(", ")} } from '${source}'`);
582
+ }
583
+ return lines.join("\n");
584
+ }
585
+
586
+ //#endregion
587
+ //#region src/script/plugin.ts
588
+ const logger$1 = consola.withTag("kimesh:auto-import:script");
589
+ const DEFAULT_INCLUDE = [
590
+ /\.[jt]sx?$/,
591
+ /\.vue$/,
592
+ /\.vue\?vue/
593
+ ];
594
+ const DEFAULT_EXCLUDE = [/node_modules/, /\.d\.ts$/];
595
+ function debounce(fn, ms) {
596
+ let timeoutId = null;
597
+ return ((...args) => {
598
+ if (timeoutId) clearTimeout(timeoutId);
599
+ timeoutId = setTimeout(() => fn(...args), ms);
600
+ });
601
+ }
602
+ function createScriptPlugin(options) {
603
+ const { sources: staticSources, getSources, layers: staticLayers = [], getLayers, include = DEFAULT_INCLUDE, exclude = DEFAULT_EXCLUDE, dts = ".kimesh", debug = false, onRegistryUpdate } = options;
604
+ const builder = new RegistryBuilder();
605
+ const detector = new ReferenceDetector();
606
+ const injector = new ImportInjector();
607
+ let registry = null;
608
+ let config;
609
+ let isBuilding = false;
610
+ let resolvedSources = void 0;
611
+ function resolveSources() {
612
+ if (resolvedSources !== void 0) return resolvedSources;
613
+ resolvedSources = getSources ? getSources() : staticSources ?? [];
614
+ return resolvedSources;
615
+ }
616
+ function resolveLayers() {
617
+ return getLayers ? getLayers() : staticLayers;
618
+ }
619
+ function getRegistry() {
620
+ return registry;
621
+ }
622
+ function resolveDtsDir() {
623
+ return path.isAbsolute(dts) ? dts : path.join(config.root, dts);
624
+ }
625
+ async function generateDtsForLayers(reg) {
626
+ if (dts === false) return;
627
+ const hostDtsDir = resolveDtsDir();
628
+ await generateDtsFiles(reg, hostDtsDir);
629
+ logger$1.debug(`Generated type declarations in ${hostDtsDir}`);
630
+ const resolvedLayerList = resolveLayers();
631
+ for (const layer of resolvedLayerList) {
632
+ if (layer.isApp) continue;
633
+ let layerRoot = layer.path;
634
+ try {
635
+ layerRoot = fs.realpathSync(layer.path);
636
+ } catch {}
637
+ const layerKimeshDir = path.join(layerRoot, ".kimesh");
638
+ try {
639
+ fs.mkdirSync(layerKimeshDir, { recursive: true });
640
+ await generateDtsFiles(reg, layerKimeshDir);
641
+ logger$1.debug(`Generated type declarations for layer: ${layer.name} at ${layerKimeshDir}`);
642
+ } catch (err) {
643
+ logger$1.warn(`Failed to generate .d.ts for layer ${layer.name}: ${err}`);
644
+ }
645
+ }
646
+ }
647
+ async function buildAndLogRegistry() {
648
+ const startTime = performance.now();
649
+ const sources = resolveSources();
650
+ registry = await builder.build(sources);
651
+ const elapsed = performance.now() - startTime;
652
+ logger$1.info(`Script auto-import registry built in ${elapsed.toFixed(1)}ms`);
653
+ logger$1.info(` ${registry.stats.composablesCount} composables, ${registry.stats.utilitiesCount} utilities, ${registry.stats.presetsCount} preset imports`);
654
+ if (registry.conflicts.length > 0) logger$1.warn(` ${registry.conflicts.length} conflicts detected`);
655
+ await generateDtsForLayers(registry);
656
+ onRegistryUpdate?.(registry);
657
+ }
658
+ return {
659
+ name: "kimesh:auto-import:script",
660
+ enforce: "pre",
661
+ getRegistry,
662
+ configResolved(resolvedConfig) {
663
+ config = resolvedConfig;
664
+ isBuilding = config.command === "build";
665
+ },
666
+ async buildStart() {
667
+ await buildAndLogRegistry();
668
+ },
669
+ configureServer(server) {
670
+ if (isBuilding) return;
671
+ const watchDirs = getWatchDirs(resolveSources());
672
+ if (watchDirs.length === 0) {
673
+ logger$1.debug("No directories to watch for auto-import");
674
+ return;
675
+ }
676
+ logger$1.debug(`Watching ${watchDirs.length} directories for auto-import changes`);
677
+ const rebuildRegistry = async () => {
678
+ const startTime = performance.now();
679
+ builder.clearCache();
680
+ const sources = resolveSources();
681
+ registry = await builder.build(sources);
682
+ const elapsed = performance.now() - startTime;
683
+ logger$1.info(`Auto-import registry rebuilt in ${elapsed.toFixed(1)}ms`);
684
+ logger$1.info(` ${registry.stats.componentsCount} components, ${registry.stats.composablesCount} composables, ${registry.stats.utilitiesCount} utilities`);
685
+ await generateDtsForLayers(registry);
686
+ onRegistryUpdate?.(registry);
687
+ };
688
+ const debouncedRebuild = debounce(rebuildRegistry, 300);
689
+ const isWatchedFile = (file) => {
690
+ const ext = path.extname(file);
691
+ if (![
692
+ ".ts",
693
+ ".js",
694
+ ".tsx",
695
+ ".jsx",
696
+ ".mts",
697
+ ".mjs",
698
+ ".vue"
699
+ ].includes(ext)) return false;
700
+ return watchDirs.some((dir) => file.startsWith(dir));
701
+ };
702
+ server.watcher.on("add", (file) => {
703
+ if (!isWatchedFile(file)) return;
704
+ logger$1.debug(`New file detected: ${path.relative(config.root, file)}`);
705
+ debouncedRebuild();
706
+ });
707
+ server.watcher.on("unlink", (file) => {
708
+ if (!isWatchedFile(file)) return;
709
+ logger$1.debug(`File deleted: ${path.relative(config.root, file)}`);
710
+ debouncedRebuild();
711
+ });
712
+ server.watcher.on("change", (file) => {
713
+ if (!isWatchedFile(file)) return;
714
+ logger$1.debug(`File changed: ${path.relative(config.root, file)}`);
715
+ builder.invalidate(file);
716
+ debouncedRebuild();
717
+ });
718
+ },
719
+ transform(code, id) {
720
+ if (!registry) return null;
721
+ if (!shouldTransform(id, include, exclude)) return null;
722
+ const startTime = performance.now();
723
+ const isVue = id.endsWith(".vue") || id.includes(".vue?");
724
+ const refs = isVue ? detector.detectInVue(code, id) : detector.detectInScript(code, id);
725
+ if (refs.length === 0) return null;
726
+ const existingImports = injector.extractExistingImports(code, isVue);
727
+ const imports = [];
728
+ const matched = /* @__PURE__ */ new Set();
729
+ for (const ref of refs) {
730
+ if (matched.has(ref.name)) continue;
731
+ if (existingImports.has(ref.name)) continue;
732
+ const entry = registry.imports.get(ref.name);
733
+ if (!entry) continue;
734
+ if (ref.isType && !entry.isType) continue;
735
+ if (registry.components.has(ref.name)) {
736
+ if (debug) logger$1.debug(`Skipping component ${ref.name} for template plugin`);
737
+ continue;
738
+ }
739
+ imports.push(entry);
740
+ matched.add(ref.name);
741
+ }
742
+ if (imports.length === 0) return null;
743
+ const result = injector.inject(code, imports, isVue);
744
+ if (!result) return null;
745
+ const elapsed = performance.now() - startTime;
746
+ if (debug) logger$1.debug(`[${elapsed.toFixed(1)}ms] ${id}: injected ${imports.length} imports`);
747
+ return {
748
+ code: result.code,
749
+ map: result.map
750
+ };
751
+ },
752
+ handleHotUpdate({ file }) {
753
+ const relativePath = path.relative(config.root, file);
754
+ const sources = resolveSources();
755
+ for (const source of sources) if (file.startsWith(source.layerPath)) {
756
+ logger$1.debug(`HMR update: ${relativePath}`);
757
+ break;
758
+ }
759
+ }
760
+ };
761
+ }
762
+ function getWatchDirs(sources) {
763
+ const dirs = [];
764
+ for (const source of sources) {
765
+ const { layerPath, config: sourceConfig } = source;
766
+ const dirConfigs = [
767
+ sourceConfig.components?.dirs ?? ["components"],
768
+ sourceConfig.composables?.dirs ?? ["composables"],
769
+ sourceConfig.utils?.dirs ?? ["utils"],
770
+ sourceConfig.stores?.dirs ?? ["stores"]
771
+ ];
772
+ for (const configDirs of dirConfigs) dirs.push(...collectExistingDirectories(layerPath, configDirs));
773
+ }
774
+ return [...new Set(dirs)];
775
+ }
776
+ function matchesPattern(id, pattern) {
777
+ if (typeof pattern === "string") return id.includes(pattern);
778
+ return pattern.test(id);
779
+ }
780
+ function shouldTransform(id, include, exclude) {
781
+ if (exclude.some((pattern) => matchesPattern(id, pattern))) return false;
782
+ return include.some((pattern) => matchesPattern(id, pattern));
783
+ }
784
+
785
+ //#endregion
786
+ //#region src/template/resolver.ts
787
+ const logger = consola.withTag("kimesh:auto-import:template:resolver");
788
+ function looksLikeComponent(name) {
789
+ return /^[A-Z][a-zA-Z0-9]*$/.test(name);
790
+ }
791
+ function createResolvedComponent(entry, name) {
792
+ return {
793
+ name: entry.isDefault ? "default" : entry.name,
794
+ from: entry.from,
795
+ as: name
796
+ };
797
+ }
798
+ function createKimeshResolver(options) {
799
+ const { getRegistry, debug = false } = options;
800
+ return {
801
+ type: "component",
802
+ resolve: (name) => {
803
+ const registry = getRegistry();
804
+ if (!registry) {
805
+ if (debug) logger.debug(`Registry not ready, skipping ${name}`);
806
+ return;
807
+ }
808
+ if (debug) {
809
+ logger.debug(`Resolving component: ${name}`);
810
+ logger.debug(` Components map size: ${registry.components.size}`);
811
+ logger.debug(` Imports map size: ${registry.imports.size}`);
812
+ }
813
+ const componentEntry = registry.components.get(name);
814
+ if (componentEntry) {
815
+ if (debug) logger.debug(`Resolved component ${name} from ${componentEntry.from} (layer: ${componentEntry.layer})`);
816
+ return createResolvedComponent(componentEntry, name);
817
+ }
818
+ const importEntry = registry.imports.get(name);
819
+ if (!importEntry) {
820
+ if (debug) logger.debug(`${name} not found in imports map`);
821
+ return;
822
+ }
823
+ if (debug) logger.debug(`Found ${name} in imports, type: ${importEntry.type}`);
824
+ if (importEntry.type === "component" || importEntry.type === "preset" && looksLikeComponent(name)) {
825
+ if (debug) logger.debug(`Resolved component ${name} from ${importEntry.from} (layer: ${importEntry.layer})`);
826
+ return {
827
+ name: importEntry.isDefault ? "default" : name,
828
+ from: importEntry.from,
829
+ as: name
830
+ };
831
+ }
832
+ }
833
+ };
834
+ }
835
+
836
+ //#endregion
837
+ //#region src/template/plugin.ts
838
+ function resolveDtsPath(dts) {
839
+ if (dts === false) return false;
840
+ if (typeof dts === "string") return path.join(dts, "components.d.ts");
841
+ return true;
842
+ }
843
+ function createTemplatePlugin(options) {
844
+ const { getRegistry, dts, debug = false } = options;
845
+ const basePlugin = Components({
846
+ resolvers: [createKimeshResolver({
847
+ getRegistry,
848
+ debug
849
+ })],
850
+ dirs: [],
851
+ dts: resolveDtsPath(dts),
852
+ include: [/\.vue$/, /\.vue\?vue/],
853
+ exclude: [/[\\/]node_modules[\\/]/],
854
+ deep: true,
855
+ directoryAsNamespace: false,
856
+ collapseSamePrefixes: true,
857
+ version: 3
858
+ });
859
+ const plugin = basePlugin;
860
+ plugin.name = "kimesh:auto-import:template";
861
+ const api = basePlugin.api;
862
+ const originalTransform = plugin.transform;
863
+ if (originalTransform) plugin.transform = async function(code, id, transformOptions) {
864
+ if (!code.includes("/* unplugin-vue-components disabled */")) return originalTransform.call(this, code, id, transformOptions);
865
+ const registry = getRegistry();
866
+ if (!registry) return null;
867
+ const unresolvedMatches = [...code.matchAll(/_?resolveComponent\d*\("(.+?)"\)/g)];
868
+ if (unresolvedMatches.length === 0) return null;
869
+ const existingVars = [...code.matchAll(/__unplugin_components_(\d+)/g)];
870
+ let nextVarIndex = existingVars.length > 0 ? Math.max(...existingVars.map((m) => parseInt(m[1], 10))) + 1 : 0;
871
+ const s = new MagicString(code);
872
+ const imports = [];
873
+ const resolved = /* @__PURE__ */ new Set();
874
+ for (const match of unresolvedMatches) {
875
+ const fullMatch = match[0];
876
+ const componentName = match[1];
877
+ if (resolved.has(componentName)) continue;
878
+ if (componentName.startsWith("_")) continue;
879
+ const entry = resolveComponentEntry(registry, componentName);
880
+ if (!entry) continue;
881
+ const varName = `__unplugin_components_${nextVarIndex++}`;
882
+ const importName = entry.isDefault ? "default" : entry.name;
883
+ imports.push(`import { ${importName} as ${varName} } from "${entry.from}";`);
884
+ replaceAllOccurrences(s, code, fullMatch, varName);
885
+ resolved.add(componentName);
886
+ if (api && typeof api.findComponent === "function") try {
887
+ await api.findComponent(componentName, id);
888
+ } catch {}
889
+ }
890
+ if (imports.length === 0) return null;
891
+ s.prepend(imports.join("\n") + "\n");
892
+ return {
893
+ code: s.toString(),
894
+ map: s.generateMap({
895
+ source: id,
896
+ includeContent: true
897
+ })
898
+ };
899
+ };
900
+ return plugin;
901
+ }
902
+ function resolveComponentEntry(registry, componentName) {
903
+ const entry = registry.components.get(componentName);
904
+ if (entry) return entry;
905
+ const importEntry = registry.imports.get(componentName);
906
+ if (importEntry && importEntry.type === "preset" && /^[A-Z][a-zA-Z0-9]*$/.test(componentName)) return importEntry;
907
+ }
908
+ function replaceAllOccurrences(s, code, search, replacement) {
909
+ let searchIndex = 0;
910
+ while (true) {
911
+ const idx = code.indexOf(search, searchIndex);
912
+ if (idx === -1) break;
913
+ s.overwrite(idx, idx + search.length, replacement);
914
+ searchIndex = idx + search.length;
915
+ }
916
+ }
917
+
918
+ //#endregion
919
+ //#region src/vite/plugin.ts
920
+ function resolveDtsDirectory(dts) {
921
+ if (dts === false) return false;
922
+ if (typeof dts === "string") return dts;
923
+ return ".kimesh";
924
+ }
925
+ function autoImportPlugin(options) {
926
+ const { dts = ".kimesh", debug = false } = options;
927
+ let sharedRegistry = null;
928
+ return [createScriptPlugin({
929
+ ...options,
930
+ onRegistryUpdate: (registry) => {
931
+ sharedRegistry = registry;
932
+ }
933
+ }), createTemplatePlugin({
934
+ getRegistry: () => sharedRegistry,
935
+ dts: resolveDtsDirectory(dts),
936
+ debug
937
+ })];
938
+ }
939
+ const kimeshAutoImport = autoImportPlugin;
940
+ var plugin_default = autoImportPlugin;
941
+
942
+ //#endregion
943
+ //#region src/index.ts
944
+ /**
945
+ * Build import registry from sources (convenience function)
946
+ */
947
+ async function buildImportRegistry(sources) {
948
+ const { RegistryBuilder: RegistryBuilder$1 } = await import("./builder-CnceYcPH.mjs");
949
+ return new RegistryBuilder$1().build(sources);
950
+ }
951
+ /**
952
+ * Scan exports from a file (convenience function)
953
+ */
954
+ async function scanExports(filePath) {
955
+ const { OxcExportScanner: OxcExportScanner$1 } = await import("./oxc-scanner-g5pD6w1O.mjs");
956
+ return new OxcExportScanner$1().scanFile(filePath);
957
+ }
958
+
959
+ //#endregion
960
+ export { ConflictResolver, ImportInjector, OxcExportScanner, ReferenceDetector, RegistryBuilder, autoImportPlugin, buildImportRegistry, builtinPresets, createTemplatePlugin as createComponentsPlugin, createTemplatePlugin, createKimeshResolver, createScriptPlugin, plugin_default as default, generateDtsFiles as generateDts, generateDtsFiles, generateSourceDts, kimeshAutoImport, kimeshPreset, normalizePreset, piniaPreset, resolvePresets, scanExports, tanstackQueryPreset, vuePreset, vueRouterPreset };
961
+ //# sourceMappingURL=index.mjs.map