@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/README.md +3 -0
- package/dist/builder-CnceYcPH.mjs +4 -0
- package/dist/builder-c6-47OHx.mjs +614 -0
- package/dist/builder-c6-47OHx.mjs.map +1 -0
- package/dist/index.d.mts +417 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +961 -0
- package/dist/index.mjs.map +1 -0
- package/dist/oxc-scanner-DrjjlY9k.mjs +195 -0
- package/dist/oxc-scanner-DrjjlY9k.mjs.map +1 -0
- package/dist/oxc-scanner-g5pD6w1O.mjs +3 -0
- package/package.json +41 -0
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
|