@meekojs/meeko 0.0.3 → 0.0.4
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 +18 -1
- package/dist/autoimports-ts.d.ts +26 -0
- package/dist/autoimports-ts.js +127 -0
- package/dist/autoimports-ts.js.map +1 -0
- package/dist/autoimports.d.ts +21 -0
- package/dist/autoimports.js +285 -0
- package/dist/autoimports.js.map +1 -0
- package/dist/check.js +35 -23
- package/dist/check.js.map +1 -0
- package/dist/cli.js +33 -4
- package/dist/cli.js.map +1 -0
- package/dist/compiler/import-graph.d.ts +8 -0
- package/dist/compiler/import-graph.js +33 -0
- package/dist/compiler/import-graph.js.map +1 -0
- package/dist/compiler/mapping.js +1 -0
- package/dist/compiler/mapping.js.map +1 -0
- package/dist/compiler/project-root.d.ts +2 -0
- package/dist/compiler/project-root.js +18 -0
- package/dist/compiler/project-root.js.map +1 -0
- package/dist/compiler/sfc.js +1 -0
- package/dist/compiler/sfc.js.map +1 -0
- package/dist/compiler/sourcemap.d.ts +3 -0
- package/dist/compiler/sourcemap.js +75 -0
- package/dist/compiler/sourcemap.js.map +1 -0
- package/dist/compiler/template.js +1 -0
- package/dist/compiler/template.js.map +1 -0
- package/dist/compiler.js +11 -5
- package/dist/compiler.js.map +1 -0
- package/dist/devtools-ui/index.js +1 -0
- package/dist/devtools-ui/index.js.map +1 -0
- package/dist/devtools.js +1 -0
- package/dist/devtools.js.map +1 -0
- package/dist/dom.d.ts +8 -1
- package/dist/dom.js +10 -5
- package/dist/dom.js.map +1 -0
- package/dist/framework/check-app.d.ts +5 -0
- package/dist/framework/check-app.js +59 -0
- package/dist/framework/check-app.js.map +1 -0
- package/dist/framework/client.d.ts +45 -0
- package/dist/framework/client.js +146 -0
- package/dist/framework/client.js.map +1 -0
- package/dist/framework/clients.d.ts +82 -0
- package/dist/framework/clients.js +182 -0
- package/dist/framework/clients.js.map +1 -0
- package/dist/framework/config-type.d.ts +10 -0
- package/dist/framework/config-type.js +4 -0
- package/dist/framework/config-type.js.map +1 -0
- package/dist/framework/config.d.ts +15 -0
- package/dist/framework/config.js +138 -0
- package/dist/framework/config.js.map +1 -0
- package/dist/framework/contracts-generate.d.ts +8 -0
- package/dist/framework/contracts-generate.js +227 -0
- package/dist/framework/contracts-generate.js.map +1 -0
- package/dist/framework/generate.d.ts +7 -0
- package/dist/framework/generate.js +67 -0
- package/dist/framework/generate.js.map +1 -0
- package/dist/framework/init.d.ts +2 -0
- package/dist/framework/init.js +362 -0
- package/dist/framework/init.js.map +1 -0
- package/dist/framework/modules.d.ts +22 -0
- package/dist/framework/modules.js +29 -0
- package/dist/framework/modules.js.map +1 -0
- package/dist/framework/page.d.ts +60 -0
- package/dist/framework/page.js +42 -0
- package/dist/framework/page.js.map +1 -0
- package/dist/framework/prerender.d.ts +14 -0
- package/dist/framework/prerender.js +104 -0
- package/dist/framework/prerender.js.map +1 -0
- package/dist/framework/router.d.ts +39 -0
- package/dist/framework/router.js +173 -0
- package/dist/framework/router.js.map +1 -0
- package/dist/framework/server.d.ts +51 -0
- package/dist/framework/server.js +192 -0
- package/dist/framework/server.js.map +1 -0
- package/dist/framework/socket-contracts-generate.d.ts +5 -0
- package/dist/framework/socket-contracts-generate.js +159 -0
- package/dist/framework/socket-contracts-generate.js.map +1 -0
- package/dist/framework/socket.d.ts +70 -0
- package/dist/framework/socket.js +150 -0
- package/dist/framework/socket.js.map +1 -0
- package/dist/framework/state.d.ts +15 -0
- package/dist/framework/state.js +72 -0
- package/dist/framework/state.js.map +1 -0
- package/dist/framework-server/auto-clients.d.ts +3 -0
- package/dist/framework-server/auto-clients.js +27 -0
- package/dist/framework-server/auto-clients.js.map +1 -0
- package/dist/framework-server/context.d.ts +21 -0
- package/dist/framework-server/context.js +22 -0
- package/dist/framework-server/context.js.map +1 -0
- package/dist/framework-server/contracts.d.ts +64 -0
- package/dist/framework-server/contracts.js +129 -0
- package/dist/framework-server/contracts.js.map +1 -0
- package/dist/framework-server/discovery.d.ts +40 -0
- package/dist/framework-server/discovery.js +252 -0
- package/dist/framework-server/discovery.js.map +1 -0
- package/dist/framework-server/local.d.ts +19 -0
- package/dist/framework-server/local.js +98 -0
- package/dist/framework-server/local.js.map +1 -0
- package/dist/framework-server/node-upgrade.d.ts +23 -0
- package/dist/framework-server/node-upgrade.js +78 -0
- package/dist/framework-server/node-upgrade.js.map +1 -0
- package/dist/framework-server/node-websocket.d.ts +16 -0
- package/dist/framework-server/node-websocket.js +125 -0
- package/dist/framework-server/node-websocket.js.map +1 -0
- package/dist/framework-server/openapi.d.ts +17 -0
- package/dist/framework-server/openapi.js +118 -0
- package/dist/framework-server/openapi.js.map +1 -0
- package/dist/framework-server/session-stores.d.ts +66 -0
- package/dist/framework-server/session-stores.js +96 -0
- package/dist/framework-server/session-stores.js.map +1 -0
- package/dist/framework-server/sessions.d.ts +64 -0
- package/dist/framework-server/sessions.js +136 -0
- package/dist/framework-server/sessions.js.map +1 -0
- package/dist/framework-server/socket.d.ts +83 -0
- package/dist/framework-server/socket.js +161 -0
- package/dist/framework-server/socket.js.map +1 -0
- package/dist/framework-server.d.ts +21 -0
- package/dist/framework-server.js +12 -0
- package/dist/framework-server.js.map +1 -0
- package/dist/framework.d.ts +29 -0
- package/dist/framework.js +13 -0
- package/dist/framework.js.map +1 -0
- package/dist/hmr.js +1 -0
- package/dist/hmr.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -0
- package/dist/init.js +4 -2
- package/dist/init.js.map +1 -0
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -0
- package/dist/node.d.ts +12 -0
- package/dist/node.js +52 -0
- package/dist/node.js.map +1 -0
- package/dist/reactivity.d.ts +12 -0
- package/dist/reactivity.js +40 -3
- package/dist/reactivity.js.map +1 -0
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -0
- package/dist/types.js +23 -8
- package/dist/types.js.map +1 -0
- package/dist/vite.js +91 -6
- package/dist/vite.js.map +1 -0
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ El proyecto está en etapa temprana. Ya funciona el recorrido completo de un con
|
|
|
14
14
|
|
|
15
15
|
- [Arquitectura y contratos](docs/architecture.md)
|
|
16
16
|
- [API y límites de compatibilidad](docs/api.md)
|
|
17
|
+
- [Aplicaciones full-stack con Meeko](docs/framework.md)
|
|
17
18
|
- [Plan de desarrollo y criterios de aceptación](docs/roadmap.md)
|
|
18
19
|
- [Comparativa reproducible con Vue](docs/benchmarks.md)
|
|
19
20
|
- [DevTools para depurar componentes](docs/devtools.md)
|
|
@@ -61,6 +62,22 @@ Abre `http://127.0.0.1:4173`. `npm run check` genera los tipos del componente y
|
|
|
61
62
|
|
|
62
63
|
Desde `0.0.3`, si ya ejecutaste `pnpm add @meekojs/meeko` en una carpeta sin código, puedes inicializarla directamente con `pnpm exec meeko init .`. Se conservan el manifiesto, los lockfiles, el workspace y `node_modules`; la CLI rechaza archivos de aplicación o scripts que entrarían en conflicto. Después ejecuta `pnpm install` y `pnpm run dev`. Para actualizar desde `0.0.2`, usa `pnpm add @meekojs/meeko@0.0.3` antes de `init .`.
|
|
63
64
|
|
|
65
|
+
### Crear una aplicación full-stack
|
|
66
|
+
|
|
67
|
+
Meeko Engine permite usar componentes `.meeko` de forma independiente. Meeko Framework añade rutas por archivos, layouts, SSR, estado por petición, API, RPC, sesiones y WebSocket con el mismo compilador y runtime. **La versión `0.0.4` que incluye este framework está preparada, pero aún no se ha publicado en npm.** Una vez publicada e instalada, crea una aplicación con:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
pnpm exec meeko init-framework my-app
|
|
71
|
+
cd my-app
|
|
72
|
+
npm install
|
|
73
|
+
npm run dev
|
|
74
|
+
npm run check
|
|
75
|
+
npm run build
|
|
76
|
+
npm start
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`check` genera contratos y comprueba tipos; `build` produce cliente, servidor y prerender. `start` sirve SSR de producción con Node 24 y requiere configurar sesiones persistentes. La [guía del framework](docs/framework.md) explica configuración, autoimports, rutas, despliegue y seguridad.
|
|
80
|
+
|
|
64
81
|
## Estructura
|
|
65
82
|
|
|
66
83
|
| Ruta | Responsabilidad |
|
|
@@ -135,7 +152,7 @@ Un archivo tiene `<script lang="ts">`, `<template>` y un `<style>` opcional; `sc
|
|
|
135
152
|
|
|
136
153
|
`if:when="expression"` muestra u oculta un elemento. Una lista usa `each:of="items"`, `each:as="item"` y `each:key="item.id"`; `each:index="position"` permite nombrar el índice, que se llama `index` por defecto. Las claves deben ser cadenas o números finitos y no pueden repetirse. Meeko conserva los nodos de las claves existentes al reordenar la lista. [Regions.meeko](examples/regions/Regions.meeko) muestra condiciones, listas anidadas, eventos y atributos dinámicos.
|
|
137
154
|
|
|
138
|
-
Un componente importado en el script se inserta con `<component is="Child" bind:label="expression"></component>`. Las props se comprueban con TypeScript y cada hijo se hidrata dentro de un rango de comentarios, sin un elemento envolvente. El cierre explícito es obligatorio; la sintaxis autocerrada de HTML no se admite para `<component>`. [Parent.meeko](examples/nested/Parent.meeko) muestra hijos y nietos dentro de condiciones y listas.
|
|
155
|
+
Un componente importado en el script se inserta con `<component is="Child" bind:label="expression"></component>`. Las props se comprueban con TypeScript y cada hijo se hidrata dentro de un rango de comentarios, sin un elemento envolvente. `is` también acepta un componente recibido como prop tipada `Component<Props>`; así se puede insertar contenido reutilizable y cambiarlo reactivamente. La comunicación hacia el padre usa callbacks tipados en las props, y `createContext<T>()` permite compartir valores con descendientes. El cierre explícito es obligatorio; la sintaxis autocerrada de HTML no se admite para `<component>`. [Parent.meeko](examples/nested/Parent.meeko) muestra hijos y nietos dentro de condiciones y listas.
|
|
139
156
|
|
|
140
157
|
Los errores de sintaxis de script, plantilla y CSS, así como los errores de tipos en declaraciones y expresiones, tienen ubicación en `.meeko`. Los errores atribuibles sólo al código auxiliar generado se identifican explícitamente.
|
|
141
158
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AutoImport, ImportScope } from "./autoimports.js";
|
|
2
|
+
export type TypeScriptScope = ImportScope;
|
|
3
|
+
/** Selects the application scope of a source file without executing it. */
|
|
4
|
+
export declare function typeScriptScope(root: string, filename: string): TypeScriptScope | undefined;
|
|
5
|
+
/** Produces global editor declarations for isolated app, server and shared TS projects. */
|
|
6
|
+
export declare function generateAutoImportTypes(projectRoot: string): Promise<{
|
|
7
|
+
client: string;
|
|
8
|
+
server: string;
|
|
9
|
+
shared: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Vite can call this for app/shared/server TypeScript before its normal TS transform. */
|
|
12
|
+
export declare function transformTypeScriptAutoImports(source: string, filename: string, root: string, registry: readonly AutoImport[]): string | undefined;
|
|
13
|
+
/** Maps the unchanged source body after imports inserted at the start of a TS module. */
|
|
14
|
+
export declare function typeScriptAutoImportMap(source: string, transformed: string, filename: string): {
|
|
15
|
+
version: 3;
|
|
16
|
+
sources: string[];
|
|
17
|
+
sourcesContent: string[];
|
|
18
|
+
names: string[];
|
|
19
|
+
mappings: string;
|
|
20
|
+
};
|
|
21
|
+
/** Convenience entrypoint for CLI generators. */
|
|
22
|
+
export declare function generateTypeScriptAutoImports(projectRoot: string): Promise<{
|
|
23
|
+
client: string;
|
|
24
|
+
server: string;
|
|
25
|
+
shared: string;
|
|
26
|
+
}>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
3
|
+
import ts from "@typescript/typescript6";
|
|
4
|
+
import { applyAutoImports, discoverAutoImports } from "./autoimports.js";
|
|
5
|
+
function within(root, filename) {
|
|
6
|
+
const path = relative(resolve(root), resolve(filename));
|
|
7
|
+
return path === ".." || path.startsWith(`..${sep}`) || path.startsWith("/") ? undefined : path.replaceAll("\\", "/");
|
|
8
|
+
}
|
|
9
|
+
/** Selects the application scope of a source file without executing it. */
|
|
10
|
+
export function typeScriptScope(root, filename) {
|
|
11
|
+
const path = within(root, filename);
|
|
12
|
+
if (!path || !/\.[cm]?tsx?$/.test(path) || /\.(?:test|spec|d)\.[cm]?tsx?$/.test(path))
|
|
13
|
+
return undefined;
|
|
14
|
+
if (/\.shared\.[cm]?tsx?$/.test(path))
|
|
15
|
+
return "shared";
|
|
16
|
+
if (/\.server\.[cm]?tsx?$/.test(path))
|
|
17
|
+
return "server";
|
|
18
|
+
if (/\.route\.[cm]?tsx?$/.test(path) && /(?:^|\/)app\/pages\//.test(path))
|
|
19
|
+
return "server";
|
|
20
|
+
if (/\.client\.[cm]?tsx?$/.test(path))
|
|
21
|
+
return "client";
|
|
22
|
+
if (path.startsWith("server/"))
|
|
23
|
+
return "server";
|
|
24
|
+
if (path.startsWith("app/"))
|
|
25
|
+
return "client";
|
|
26
|
+
if (path.startsWith("shared/"))
|
|
27
|
+
return "shared";
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
function publicSpecifier(outputDirectory, entry) {
|
|
31
|
+
if (entry.specifier)
|
|
32
|
+
return entry.specifier;
|
|
33
|
+
const path = relative(outputDirectory, entry.file).replaceAll("\\", "/");
|
|
34
|
+
const prefixed = path.startsWith(".") ? path : `./${path}`;
|
|
35
|
+
return entry.component ? prefixed : prefixed.replace(/\.[cm]?ts$/, (extension) => extension === ".mts" ? ".mjs" : extension === ".cts" ? ".cjs" : ".js");
|
|
36
|
+
}
|
|
37
|
+
function scopeEntries(registry, scope) {
|
|
38
|
+
return registry.filter((entry) => entry.scope === "shared" || (scope !== "shared" && entry.scope === scope));
|
|
39
|
+
}
|
|
40
|
+
function assertNoCollisions(entries, scope) {
|
|
41
|
+
const symbols = new Map();
|
|
42
|
+
for (const entry of entries) {
|
|
43
|
+
const previous = symbols.get(entry.name);
|
|
44
|
+
if (previous)
|
|
45
|
+
throw new Error(`Ambiguous autoimport ${entry.name} in ${scope} scope: ${previous.file}, ${entry.file}`);
|
|
46
|
+
symbols.set(entry.name, entry);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function typeDeclaration(entry, specifier) {
|
|
50
|
+
if (entry.specifier)
|
|
51
|
+
return ` type ${entry.name} = import(${specifier}).${entry.imported};`;
|
|
52
|
+
const source = await readFile(entry.file, "utf8");
|
|
53
|
+
const file = ts.createSourceFile(entry.file, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
54
|
+
const declaration = file.statements.find((statement) => (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement)) && statement.name.text === entry.imported);
|
|
55
|
+
if (!declaration || (!ts.isTypeAliasDeclaration(declaration) && !ts.isInterfaceDeclaration(declaration)) || !declaration.typeParameters?.length) {
|
|
56
|
+
return ` type ${entry.name} = import(${specifier}).${entry.imported};`;
|
|
57
|
+
}
|
|
58
|
+
const parameters = `<${declaration.typeParameters.map((parameter) => parameter.getText(file)).join(", ")}>`;
|
|
59
|
+
const arguments_ = `<${declaration.typeParameters.map((parameter) => parameter.name.text).join(", ")}>`;
|
|
60
|
+
return ` type ${entry.name}${parameters} = import(${specifier}).${entry.imported}${arguments_};`;
|
|
61
|
+
}
|
|
62
|
+
/** Produces global editor declarations for isolated app, server and shared TS projects. */
|
|
63
|
+
export async function generateAutoImportTypes(projectRoot) {
|
|
64
|
+
const root = resolve(projectRoot);
|
|
65
|
+
const outputDirectory = join(root, ".meeko", "types", "autoimports");
|
|
66
|
+
const registry = await discoverAutoImports(root);
|
|
67
|
+
await mkdir(outputDirectory, { recursive: true });
|
|
68
|
+
const outputs = {};
|
|
69
|
+
for (const scope of ["client", "server", "shared"]) {
|
|
70
|
+
const entries = scopeEntries(registry, scope);
|
|
71
|
+
assertNoCollisions(entries, scope);
|
|
72
|
+
const declarations = await Promise.all(entries.sort((a, b) => a.name.localeCompare(b.name)).map(async (entry) => {
|
|
73
|
+
const specifier = JSON.stringify(publicSpecifier(outputDirectory, entry));
|
|
74
|
+
if (entry.typeOnly)
|
|
75
|
+
return typeDeclaration(entry, specifier);
|
|
76
|
+
const value = entry.component ? `typeof import(${specifier})` : `typeof import(${specifier})[${JSON.stringify(entry.imported)}]`;
|
|
77
|
+
return ` const ${entry.name}: ${value};`;
|
|
78
|
+
}));
|
|
79
|
+
const path = join(outputDirectory, `${scope}.d.ts`);
|
|
80
|
+
const source = ["// Generated by Meeko. Scope-specific editor declarations.", "export {};", "declare global {", ...declarations, "}", ""].join("\n");
|
|
81
|
+
let previous;
|
|
82
|
+
try {
|
|
83
|
+
previous = await readFile(path, "utf8");
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
if (error.code !== "ENOENT")
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
if (previous !== source)
|
|
90
|
+
await writeFile(path, source, "utf8");
|
|
91
|
+
outputs[scope] = path;
|
|
92
|
+
}
|
|
93
|
+
return outputs;
|
|
94
|
+
}
|
|
95
|
+
/** Vite can call this for app/shared/server TypeScript before its normal TS transform. */
|
|
96
|
+
export function transformTypeScriptAutoImports(source, filename, root, registry) {
|
|
97
|
+
const scope = typeScriptScope(root, filename);
|
|
98
|
+
if (!scope)
|
|
99
|
+
return undefined;
|
|
100
|
+
if (scope === "shared") {
|
|
101
|
+
// A shared module must resolve identically from both client and server views.
|
|
102
|
+
const client = applyAutoImports(source, filename, registry, "client");
|
|
103
|
+
const server = applyAutoImports(source, filename, registry, "server");
|
|
104
|
+
if (client !== server)
|
|
105
|
+
throw new Error(`Shared module ${filename} references an app or server autoimport`);
|
|
106
|
+
return client === source ? undefined : client;
|
|
107
|
+
}
|
|
108
|
+
const transformed = applyAutoImports(source, filename, registry, scope);
|
|
109
|
+
return transformed === source ? undefined : transformed;
|
|
110
|
+
}
|
|
111
|
+
/** Maps the unchanged source body after imports inserted at the start of a TS module. */
|
|
112
|
+
export function typeScriptAutoImportMap(source, transformed, filename) {
|
|
113
|
+
if (!transformed.endsWith(source))
|
|
114
|
+
throw new TypeError("Autoimport transform must preserve the original TypeScript body");
|
|
115
|
+
const prefix = transformed.slice(0, -source.length);
|
|
116
|
+
const insertedLines = (prefix.match(/\n/g) ?? []).length;
|
|
117
|
+
const sourceLines = source.split(/\r\n|\r|\n/).length;
|
|
118
|
+
return {
|
|
119
|
+
version: 3, sources: [filename], sourcesContent: [source], names: [],
|
|
120
|
+
mappings: `${";".repeat(insertedLines)}AAAA${";AACA".repeat(Math.max(0, sourceLines - 1))}`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/** Convenience entrypoint for CLI generators. */
|
|
124
|
+
export async function generateTypeScriptAutoImports(projectRoot) {
|
|
125
|
+
return generateAutoImportTypes(projectRoot);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=autoimports-ts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoimports-ts.js","sourceRoot":"","sources":["../src/autoimports-ts.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join, relative, resolve, sep } from \"node:path\";\nimport ts from \"@typescript/typescript6\";\nimport { applyAutoImports, discoverAutoImports } from \"./autoimports.js\";\nimport type { AutoImport, ImportScope } from \"./autoimports.js\";\n\nexport type TypeScriptScope = ImportScope;\n\nfunction within(root: string, filename: string): string | undefined {\n const path = relative(resolve(root), resolve(filename));\n return path === \"..\" || path.startsWith(`..${sep}`) || path.startsWith(\"/\") ? undefined : path.replaceAll(\"\\\\\", \"/\");\n}\n\n/** Selects the application scope of a source file without executing it. */\nexport function typeScriptScope(root: string, filename: string): TypeScriptScope | undefined {\n const path = within(root, filename);\n if (!path || !/\\.[cm]?tsx?$/.test(path) || /\\.(?:test|spec|d)\\.[cm]?tsx?$/.test(path)) return undefined;\n if (/\\.shared\\.[cm]?tsx?$/.test(path)) return \"shared\";\n if (/\\.server\\.[cm]?tsx?$/.test(path)) return \"server\";\n if (/\\.route\\.[cm]?tsx?$/.test(path) && /(?:^|\\/)app\\/pages\\//.test(path)) return \"server\";\n if (/\\.client\\.[cm]?tsx?$/.test(path)) return \"client\";\n if (path.startsWith(\"server/\")) return \"server\";\n if (path.startsWith(\"app/\")) return \"client\";\n if (path.startsWith(\"shared/\")) return \"shared\";\n return undefined;\n}\n\nfunction publicSpecifier(outputDirectory: string, entry: AutoImport): string {\n if (entry.specifier) return entry.specifier;\n const path = relative(outputDirectory, entry.file).replaceAll(\"\\\\\", \"/\");\n const prefixed = path.startsWith(\".\") ? path : `./${path}`;\n return entry.component ? prefixed : prefixed.replace(/\\.[cm]?ts$/, (extension) => extension === \".mts\" ? \".mjs\" : extension === \".cts\" ? \".cjs\" : \".js\");\n}\n\nfunction scopeEntries(registry: readonly AutoImport[], scope: TypeScriptScope): AutoImport[] {\n return registry.filter((entry) => entry.scope === \"shared\" || (scope !== \"shared\" && entry.scope === scope));\n}\n\nfunction assertNoCollisions(entries: readonly AutoImport[], scope: TypeScriptScope): void {\n const symbols = new Map<string, AutoImport>();\n for (const entry of entries) {\n const previous = symbols.get(entry.name);\n if (previous) throw new Error(`Ambiguous autoimport ${entry.name} in ${scope} scope: ${previous.file}, ${entry.file}`);\n symbols.set(entry.name, entry);\n }\n}\n\nasync function typeDeclaration(entry: AutoImport, specifier: string): Promise<string> {\n if (entry.specifier) return ` type ${entry.name} = import(${specifier}).${entry.imported};`;\n const source = await readFile(entry.file, \"utf8\");\n const file = ts.createSourceFile(entry.file, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const declaration = file.statements.find((statement) =>\n (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement)) && statement.name.text === entry.imported);\n if (!declaration || (!ts.isTypeAliasDeclaration(declaration) && !ts.isInterfaceDeclaration(declaration)) || !declaration.typeParameters?.length) {\n return ` type ${entry.name} = import(${specifier}).${entry.imported};`;\n }\n const parameters = `<${declaration.typeParameters.map((parameter) => parameter.getText(file)).join(\", \")}>`;\n const arguments_ = `<${declaration.typeParameters.map((parameter) => parameter.name.text).join(\", \")}>`;\n return ` type ${entry.name}${parameters} = import(${specifier}).${entry.imported}${arguments_};`;\n}\n\n/** Produces global editor declarations for isolated app, server and shared TS projects. */\nexport async function generateAutoImportTypes(projectRoot: string): Promise<{ client: string; server: string; shared: string }> {\n const root = resolve(projectRoot);\n const outputDirectory = join(root, \".meeko\", \"types\", \"autoimports\");\n const registry = await discoverAutoImports(root);\n await mkdir(outputDirectory, { recursive: true });\n const outputs = {} as { client: string; server: string; shared: string };\n for (const scope of [\"client\", \"server\", \"shared\"] as const) {\n const entries = scopeEntries(registry, scope);\n assertNoCollisions(entries, scope);\n const declarations = await Promise.all(entries.sort((a, b) => a.name.localeCompare(b.name)).map(async (entry) => {\n const specifier = JSON.stringify(publicSpecifier(outputDirectory, entry));\n if (entry.typeOnly) return typeDeclaration(entry, specifier);\n const value = entry.component ? `typeof import(${specifier})` : `typeof import(${specifier})[${JSON.stringify(entry.imported)}]`;\n return ` const ${entry.name}: ${value};`;\n }));\n const path = join(outputDirectory, `${scope}.d.ts`);\n const source = [\"// Generated by Meeko. Scope-specific editor declarations.\", \"export {};\", \"declare global {\", ...declarations, \"}\", \"\"].join(\"\\n\");\n let previous: string | undefined;\n try { previous = await readFile(path, \"utf8\"); }\n catch (error) { if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error; }\n if (previous !== source) await writeFile(path, source, \"utf8\");\n outputs[scope] = path;\n }\n return outputs;\n}\n\n/** Vite can call this for app/shared/server TypeScript before its normal TS transform. */\nexport function transformTypeScriptAutoImports(source: string, filename: string, root: string, registry: readonly AutoImport[]): string | undefined {\n const scope = typeScriptScope(root, filename);\n if (!scope) return undefined;\n if (scope === \"shared\") {\n // A shared module must resolve identically from both client and server views.\n const client = applyAutoImports(source, filename, registry, \"client\");\n const server = applyAutoImports(source, filename, registry, \"server\");\n if (client !== server) throw new Error(`Shared module ${filename} references an app or server autoimport`);\n return client === source ? undefined : client;\n }\n const transformed = applyAutoImports(source, filename, registry, scope);\n return transformed === source ? undefined : transformed;\n}\n\n/** Maps the unchanged source body after imports inserted at the start of a TS module. */\nexport function typeScriptAutoImportMap(source: string, transformed: string, filename: string): {\n version: 3; sources: string[]; sourcesContent: string[]; names: string[]; mappings: string;\n} {\n if (!transformed.endsWith(source)) throw new TypeError(\"Autoimport transform must preserve the original TypeScript body\");\n const prefix = transformed.slice(0, -source.length);\n const insertedLines = (prefix.match(/\\n/g) ?? []).length;\n const sourceLines = source.split(/\\r\\n|\\r|\\n/).length;\n return {\n version: 3, sources: [filename], sourcesContent: [source], names: [],\n mappings: `${\";\".repeat(insertedLines)}AAAA${\";AACA\".repeat(Math.max(0, sourceLines - 1))}`,\n };\n}\n\n/** Convenience entrypoint for CLI generators. */\nexport async function generateTypeScriptAutoImports(projectRoot: string): Promise<{ client: string; server: string; shared: string }> {\n return generateAutoImportTypes(projectRoot);\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CompileOptions, CompileResult } from "./compiler.js";
|
|
2
|
+
export type ImportScope = "client" | "server" | "shared";
|
|
3
|
+
export interface AutoImport {
|
|
4
|
+
name: string;
|
|
5
|
+
imported: string;
|
|
6
|
+
file: string;
|
|
7
|
+
scope: ImportScope;
|
|
8
|
+
typeOnly: boolean;
|
|
9
|
+
component: boolean;
|
|
10
|
+
specifier?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Construye el registro a partir de exports sintácticos, sin ejecutar módulos de la aplicación. */
|
|
13
|
+
export declare function discoverAutoImports(root: string): Promise<AutoImport[]>;
|
|
14
|
+
/** Same static registry used by the synchronous VS Code Language Service. */
|
|
15
|
+
export declare function discoverAutoImportsSync(root: string): AutoImport[];
|
|
16
|
+
/** Añade imports ESM para referencias libres del módulo generado. */
|
|
17
|
+
export declare function applyAutoImports(code: string, filename: string, registry: readonly AutoImport[], target: "client" | "server"): string;
|
|
18
|
+
/** Transforma un SFC usando exactamente el mismo compilador que el plugin Vite. */
|
|
19
|
+
export declare function transformAutoImports(source: string, filename: string, code: string, registry: readonly AutoImport[], target: "client" | "server"): string;
|
|
20
|
+
/** Compile result shared by Vite, CLI checks and declaration generation. */
|
|
21
|
+
export declare function compileWithAutoImports(source: string, filename: string, options?: CompileOptions, target?: "client" | "server"): Promise<CompileResult>;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
3
|
+
import { extname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import ts from "@typescript/typescript6";
|
|
5
|
+
import { compile } from "./compiler.js";
|
|
6
|
+
import { projectRoot } from "./compiler/project-root.js";
|
|
7
|
+
import { parseSfc } from "./compiler/sfc.js";
|
|
8
|
+
import { loadMeekoConfig, readMeekoConfigSync, resolveConfigSources } from "./framework/config.js";
|
|
9
|
+
const directories = [
|
|
10
|
+
"app/components", "app/composables", "app/utils", "app/stores",
|
|
11
|
+
"shared/types", "shared/schemas", "shared/utils", "shared/constants", "shared/enums",
|
|
12
|
+
"server/utils",
|
|
13
|
+
];
|
|
14
|
+
function scopeOf(file) {
|
|
15
|
+
if (/\.shared\.[cm]?tsx?$/.test(file))
|
|
16
|
+
return "shared";
|
|
17
|
+
if (/\.server\.[cm]?tsx?$/.test(file))
|
|
18
|
+
return "server";
|
|
19
|
+
if (/\.client\.[cm]?tsx?$/.test(file))
|
|
20
|
+
return "client";
|
|
21
|
+
if (file.includes(`${sep}server${sep}`))
|
|
22
|
+
return "server";
|
|
23
|
+
if (file.includes(`${sep}app${sep}`))
|
|
24
|
+
return "client";
|
|
25
|
+
return "shared";
|
|
26
|
+
}
|
|
27
|
+
async function filesIn(path) {
|
|
28
|
+
const entries = await readdir(path, { withFileTypes: true }).catch(() => []);
|
|
29
|
+
const files = [];
|
|
30
|
+
for (const entry of entries) {
|
|
31
|
+
const filename = join(path, entry.name);
|
|
32
|
+
if (entry.isDirectory())
|
|
33
|
+
files.push(...await filesIn(filename));
|
|
34
|
+
else if (/\.(?:meeko|[cm]?ts)$/.test(entry.name) && !/\.(?:test|spec|d)\.[cm]?ts$/.test(entry.name))
|
|
35
|
+
files.push(filename);
|
|
36
|
+
}
|
|
37
|
+
return files;
|
|
38
|
+
}
|
|
39
|
+
function filesInSync(path) {
|
|
40
|
+
let entries;
|
|
41
|
+
try {
|
|
42
|
+
entries = readdirSync(path, { withFileTypes: true });
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error.code === "ENOENT")
|
|
46
|
+
return [];
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
const files = [];
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
const filename = join(path, entry.name);
|
|
52
|
+
if (entry.isDirectory())
|
|
53
|
+
files.push(...filesInSync(filename));
|
|
54
|
+
else if (/\.(?:meeko|[cm]?ts)$/.test(entry.name) && !/\.(?:test|spec|d)\.[cm]?ts$/.test(entry.name))
|
|
55
|
+
files.push(filename);
|
|
56
|
+
}
|
|
57
|
+
return files;
|
|
58
|
+
}
|
|
59
|
+
function builtins(root) {
|
|
60
|
+
const entries = [
|
|
61
|
+
...["signal", "computed", "effect", "batch", "onCleanup", "provide", "inject", "createContext"].map((name) => ({ name, imported: name, file: "@meekojs/meeko", specifier: "@meekojs/meeko", scope: "shared", typeOnly: false, component: false })),
|
|
62
|
+
...["useState", "href"].map((name) => ({ name, imported: name, file: "@meekojs/meeko/framework", specifier: "@meekojs/meeko/framework", scope: "shared", typeOnly: false, component: false })),
|
|
63
|
+
];
|
|
64
|
+
for (const scope of ["client", "server"]) {
|
|
65
|
+
const file = join(root, ".meeko", "generated", `clients.${scope}.ts`);
|
|
66
|
+
if (!existsSync(file))
|
|
67
|
+
continue;
|
|
68
|
+
for (const name of ["api", "rpc", "socket", "useSocket"])
|
|
69
|
+
entries.push({ name, imported: name, file, scope, typeOnly: false, component: false });
|
|
70
|
+
}
|
|
71
|
+
if (!entries.some((entry) => entry.name === "useSocket")) {
|
|
72
|
+
entries.push({ name: "useSocket", imported: "useSocket", file: "@meekojs/meeko/framework", specifier: "@meekojs/meeko/framework", scope: "shared", typeOnly: false, component: false });
|
|
73
|
+
}
|
|
74
|
+
return entries;
|
|
75
|
+
}
|
|
76
|
+
function addFileImports(result, root, directory, file, source) {
|
|
77
|
+
const scope = scopeOf(file);
|
|
78
|
+
if (extname(file) === ".meeko") {
|
|
79
|
+
if (directory !== "app/components")
|
|
80
|
+
return;
|
|
81
|
+
const path = relative(join(root, directory), file).replace(/\.meeko$/, "");
|
|
82
|
+
const name = path.split(/[\\/]/).map((part) => part.replace(/(^|[-_])(\w)/g, (_, _dash, letter) => letter.toUpperCase())).join("");
|
|
83
|
+
result.push({ name, imported: "*", file, scope, typeOnly: false, component: true });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const ast = ts.createSourceFile(file, source ?? "", ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
87
|
+
for (const statement of ast.statements) {
|
|
88
|
+
const exported = ts.canHaveModifiers(statement) && ts.getModifiers(statement)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);
|
|
89
|
+
if (exported && (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) {
|
|
90
|
+
result.push({ name: statement.name.text, imported: statement.name.text, file, scope, typeOnly: ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement), component: false });
|
|
91
|
+
}
|
|
92
|
+
if (exported && ts.isVariableStatement(statement)) {
|
|
93
|
+
for (const declaration of statement.declarationList.declarations)
|
|
94
|
+
if (ts.isIdentifier(declaration.name)) {
|
|
95
|
+
result.push({ name: declaration.name.text, imported: declaration.name.text, file, scope, typeOnly: false, component: false });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
|
|
99
|
+
for (const element of statement.exportClause.elements)
|
|
100
|
+
result.push({ name: element.name.text, imported: element.name.text, file, scope, typeOnly: statement.isTypeOnly || element.isTypeOnly, component: false });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Construye el registro a partir de exports sintácticos, sin ejecutar módulos de la aplicación. */
|
|
105
|
+
export async function discoverAutoImports(root) {
|
|
106
|
+
const result = builtins(root);
|
|
107
|
+
const config = await loadMeekoConfig(root);
|
|
108
|
+
const sources = await resolveConfigSources(root, config);
|
|
109
|
+
for (const source of sources) {
|
|
110
|
+
for (const directory of configuredDirectories(config.imports?.serverDirs)) {
|
|
111
|
+
for (const file of await filesIn(join(source.root, directory))) {
|
|
112
|
+
addFileImports(result, source.root, directory, file, extname(file) === ".meeko" ? undefined : await readFile(file, "utf8"));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
/** Same static registry used by the synchronous VS Code Language Service. */
|
|
119
|
+
export function discoverAutoImportsSync(root) {
|
|
120
|
+
const result = builtins(root);
|
|
121
|
+
const config = readMeekoConfigSync(root);
|
|
122
|
+
const sourceRoots = [resolve(root)];
|
|
123
|
+
for (const entry of [...(config.extends ?? []), ...(config.modules ?? [])]) {
|
|
124
|
+
const sourceRoot = resolve(root, entry);
|
|
125
|
+
const path = relative(root, sourceRoot);
|
|
126
|
+
if (path === ".." || path.startsWith(`..${sep}`) || isAbsolute(path))
|
|
127
|
+
throw new Error(`Configured autoimport source escapes project root: ${entry}`);
|
|
128
|
+
sourceRoots.push(sourceRoot);
|
|
129
|
+
}
|
|
130
|
+
for (const sourceRoot of sourceRoots) {
|
|
131
|
+
for (const directory of configuredDirectories(config.imports?.serverDirs)) {
|
|
132
|
+
for (const file of filesInSync(join(sourceRoot, directory))) {
|
|
133
|
+
addFileImports(result, sourceRoot, directory, file, extname(file) === ".meeko" ? undefined : readFileSync(file, "utf8"));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
function configuredDirectories(serverDirs) {
|
|
140
|
+
const result = new Set(directories);
|
|
141
|
+
for (const raw of serverDirs ?? []) {
|
|
142
|
+
const directory = raw.replaceAll("\\", "/").replace(/\/$/, "");
|
|
143
|
+
const parts = directory.split("/");
|
|
144
|
+
if (parts[0] !== "server" || parts.length < 2 || parts.some((part) => !part || part === "." || part === "..")) {
|
|
145
|
+
throw new Error(`Autoimport serverDir must be a relative path under server/: ${raw}`);
|
|
146
|
+
}
|
|
147
|
+
result.add(directory);
|
|
148
|
+
}
|
|
149
|
+
return [...result];
|
|
150
|
+
}
|
|
151
|
+
function bindingNames(name, names) {
|
|
152
|
+
if (ts.isIdentifier(name))
|
|
153
|
+
names.add(name.text);
|
|
154
|
+
else
|
|
155
|
+
for (const element of name.elements)
|
|
156
|
+
if (ts.isBindingElement(element))
|
|
157
|
+
bindingNames(element.name, names);
|
|
158
|
+
}
|
|
159
|
+
function scopeNames(node) {
|
|
160
|
+
const names = new Set();
|
|
161
|
+
if (ts.isFunctionLike(node)) {
|
|
162
|
+
for (const parameter of node.parameters)
|
|
163
|
+
bindingNames(parameter.name, names);
|
|
164
|
+
for (const parameter of node.typeParameters ?? [])
|
|
165
|
+
names.add(parameter.name.text);
|
|
166
|
+
}
|
|
167
|
+
if (ts.isCatchClause(node) && node.variableDeclaration)
|
|
168
|
+
bindingNames(node.variableDeclaration.name, names);
|
|
169
|
+
if (ts.isForStatement(node) && node.initializer && ts.isVariableDeclarationList(node.initializer)) {
|
|
170
|
+
for (const declaration of node.initializer.declarations)
|
|
171
|
+
bindingNames(declaration.name, names);
|
|
172
|
+
}
|
|
173
|
+
if ((ts.isForOfStatement(node) || ts.isForInStatement(node)) && ts.isVariableDeclarationList(node.initializer)) {
|
|
174
|
+
for (const declaration of node.initializer.declarations)
|
|
175
|
+
bindingNames(declaration.name, names);
|
|
176
|
+
}
|
|
177
|
+
if (ts.isSourceFile(node) || ts.isBlock(node)) {
|
|
178
|
+
for (const statement of node.statements) {
|
|
179
|
+
if (ts.isVariableStatement(statement))
|
|
180
|
+
for (const declaration of statement.declarationList.declarations)
|
|
181
|
+
bindingNames(declaration.name, names);
|
|
182
|
+
if ((ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name)
|
|
183
|
+
names.add(statement.name.text);
|
|
184
|
+
if (ts.isImportDeclaration(statement)) {
|
|
185
|
+
const clause = statement.importClause;
|
|
186
|
+
if (clause?.name)
|
|
187
|
+
names.add(clause.name.text);
|
|
188
|
+
if (clause?.namedBindings) {
|
|
189
|
+
if (ts.isNamespaceImport(clause.namedBindings))
|
|
190
|
+
names.add(clause.namedBindings.name.text);
|
|
191
|
+
else
|
|
192
|
+
for (const element of clause.namedBindings.elements)
|
|
193
|
+
names.add(element.name.text);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return names;
|
|
199
|
+
}
|
|
200
|
+
function introducesScope(node) {
|
|
201
|
+
return ts.isSourceFile(node) || ts.isBlock(node) || ts.isFunctionLike(node) || ts.isCatchClause(node)
|
|
202
|
+
|| ts.isForStatement(node) || ts.isForOfStatement(node) || ts.isForInStatement(node);
|
|
203
|
+
}
|
|
204
|
+
function isReference(node) {
|
|
205
|
+
const parent = node.parent;
|
|
206
|
+
if (!parent)
|
|
207
|
+
return false;
|
|
208
|
+
if (ts.isPropertyAccessExpression(parent) && parent.name === node)
|
|
209
|
+
return false;
|
|
210
|
+
if (ts.isQualifiedName(parent) && parent.right === node)
|
|
211
|
+
return false;
|
|
212
|
+
if (ts.isPropertyAssignment(parent) && parent.name === node)
|
|
213
|
+
return false;
|
|
214
|
+
if (ts.isPropertyDeclaration(parent) && parent.name === node)
|
|
215
|
+
return false;
|
|
216
|
+
if (ts.isMethodDeclaration(parent) && parent.name === node)
|
|
217
|
+
return false;
|
|
218
|
+
if (ts.isImportSpecifier(parent) || ts.isExportSpecifier(parent) || ts.isImportClause(parent) || ts.isNamespaceImport(parent))
|
|
219
|
+
return false;
|
|
220
|
+
if (ts.isTypeReferenceNode(parent) && parent.typeName === node)
|
|
221
|
+
return true;
|
|
222
|
+
if (ts.isParameter(parent) && parent.name === node)
|
|
223
|
+
return false;
|
|
224
|
+
if (ts.isTypeParameterDeclaration(parent) && parent.name === node)
|
|
225
|
+
return false;
|
|
226
|
+
if (ts.isVariableDeclaration(parent) && parent.name === node)
|
|
227
|
+
return false;
|
|
228
|
+
if ((ts.isFunctionDeclaration(parent) || ts.isClassDeclaration(parent) || ts.isInterfaceDeclaration(parent) || ts.isTypeAliasDeclaration(parent)) && parent.name === node)
|
|
229
|
+
return false;
|
|
230
|
+
if (ts.isPropertySignature(parent) && parent.name === node)
|
|
231
|
+
return false;
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
/** Añade imports ESM para referencias libres del módulo generado. */
|
|
235
|
+
export function applyAutoImports(code, filename, registry, target) {
|
|
236
|
+
const ast = ts.createSourceFile(filename, code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
237
|
+
const referenced = new Set();
|
|
238
|
+
const visit = (node, scopes) => {
|
|
239
|
+
const active = introducesScope(node) ? [...scopes, scopeNames(node)] : scopes;
|
|
240
|
+
if (ts.isIdentifier(node) && isReference(node) && !active.some((scope) => scope.has(node.text)))
|
|
241
|
+
referenced.add(node.text);
|
|
242
|
+
ts.forEachChild(node, (child) => visit(child, active));
|
|
243
|
+
};
|
|
244
|
+
visit(ast, []);
|
|
245
|
+
const imports = [];
|
|
246
|
+
for (const name of [...referenced].sort()) {
|
|
247
|
+
const candidates = registry.filter((entry) => entry.name === name);
|
|
248
|
+
if (candidates.length === 0)
|
|
249
|
+
continue;
|
|
250
|
+
const allowed = candidates.filter((entry) => entry.scope === "shared" || entry.scope === target);
|
|
251
|
+
if (allowed.length === 0)
|
|
252
|
+
throw new Error(`Autoimport ${name} is unavailable in ${target} scope`);
|
|
253
|
+
if (allowed.length > 1)
|
|
254
|
+
throw new Error(`Ambiguous autoimport ${name}: ${allowed.map((entry) => entry.file).join(", ")}`);
|
|
255
|
+
const entry = allowed[0];
|
|
256
|
+
let specifier = entry.specifier ?? relative(resolve(filename, ".."), entry.file).replaceAll("\\", "/");
|
|
257
|
+
if (!entry.specifier && !specifier.startsWith("."))
|
|
258
|
+
specifier = `./${specifier}`;
|
|
259
|
+
if (!entry.component && !entry.specifier)
|
|
260
|
+
specifier = specifier.replace(/\.[cm]?ts$/, ".js");
|
|
261
|
+
if (entry.component)
|
|
262
|
+
imports.push(`import * as ${name} from ${JSON.stringify(specifier)};`);
|
|
263
|
+
else
|
|
264
|
+
imports.push(`import ${entry.typeOnly ? "type " : ""}{ ${entry.imported} as ${name} } from ${JSON.stringify(specifier)};`);
|
|
265
|
+
}
|
|
266
|
+
return imports.length ? `${imports.join("\n")}\n${code}` : code;
|
|
267
|
+
}
|
|
268
|
+
/** Transforma un SFC usando exactamente el mismo compilador que el plugin Vite. */
|
|
269
|
+
export function transformAutoImports(source, filename, code, registry, target) {
|
|
270
|
+
parseSfc(source, filename);
|
|
271
|
+
return applyAutoImports(code, filename, registry, target);
|
|
272
|
+
}
|
|
273
|
+
/** Compile result shared by Vite, CLI checks and declaration generation. */
|
|
274
|
+
export async function compileWithAutoImports(source, filename, options = {}, target = "client") {
|
|
275
|
+
const compiled = compile(source, filename, options);
|
|
276
|
+
const registry = await discoverAutoImports(projectRoot(filename));
|
|
277
|
+
const code = transformAutoImports(source, filename, compiled.code, registry, target);
|
|
278
|
+
const offset = code.length - compiled.code.length;
|
|
279
|
+
return {
|
|
280
|
+
...compiled,
|
|
281
|
+
code,
|
|
282
|
+
mappings: offset ? compiled.mappings.map((mapping) => ({ ...mapping, generatedStart: mapping.generatedStart + offset, generatedEnd: mapping.generatedEnd + offset })) : compiled.mappings,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=autoimports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoimports.js","sourceRoot":"","sources":["../src/autoimports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAC9E,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAanG,MAAM,WAAW,GAAG;IAClB,gBAAgB,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY;IAC9D,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,EAAE,cAAc;IACpF,cAAc;CACN,CAAC;AAEX,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvD,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvD,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,SAAS,GAAG,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAC;IACzD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC;QAAE,OAAO,QAAQ,CAAC;IACtD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAY;IACjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;aAC3D,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QAAC,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAAC,CAAC;IAC7D,OAAO,KAAK,EAAE,CAAC;QAAC,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IACjG,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;aACzD,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,OAAO,GAAiB;QAC5B,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAc,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9P,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAc,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;KAC3M,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAU,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,KAAK,KAAK,CAAC,CAAC;QACtE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACnJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1L,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,cAAc,CAAC,MAAoB,EAAE,IAAY,EAAE,SAAiB,EAAE,IAAY,EAAE,MAAe;IAC1G,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,SAAS,KAAK,gBAAgB;YAAE,OAAO;QAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,KAAa,EAAE,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnJ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,OAAO;IACT,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACpG,KAAK,MAAM,SAAS,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QACjJ,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YAC/N,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACnM,CAAC;QACD,IAAI,QAAQ,IAAI,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,KAAK,MAAM,WAAW,IAAI,SAAS,CAAC,eAAe,CAAC,YAAY;gBAAE,IAAI,EAAE,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxG,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;gBAChI,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,YAAY,IAAI,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7G,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,YAAY,CAAC,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACpN,CAAC;IACH,CAAC;AACH,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAY;IACpD,MAAM,MAAM,GAAiB,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,SAAS,IAAI,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;YAC1E,KAAK,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;gBAC/D,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAC9H,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACxC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,KAAK,EAAE,CAAC,CAAC;QACrJ,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IACD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,KAAK,MAAM,SAAS,IAAI,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC;YAC1E,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;gBAC5D,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAC3H,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAyC;IACtE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAS,WAAW,CAAC,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC9G,MAAM,IAAI,KAAK,CAAC,+DAA+D,GAAG,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,YAAY,CAAC,IAAoB,EAAE,KAAkB;IAC5D,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;QAC3C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC;gBAAE,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAChH,CAAC;AAED,SAAS,UAAU,CAAC,IAAa;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU;YAAE,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7E,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,cAAc,IAAI,EAAE;YAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,mBAAmB;QAAE,YAAY,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3G,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAClG,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY;YAAE,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/G,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY;YAAE,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,IAAI,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;gBAAE,KAAK,MAAM,WAAW,IAAI,SAAS,CAAC,eAAe,CAAC,YAAY;oBAAE,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC/I,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI;gBAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnP,IAAI,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC;gBACtC,IAAI,MAAM,EAAE,IAAI;oBAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,MAAM,EAAE,aAAa,EAAE,CAAC;oBAC1B,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,aAAa,CAAC;wBAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;wBACrF,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ;4BAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzF,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,IAAa;IACpC,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;WAChG,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;AACzF,CAAC;AAED,SAAS,WAAW,CAAC,IAAmB;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChF,IAAI,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC1E,IAAI,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3E,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5I,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5E,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChF,IAAI,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3E,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACxL,IAAI,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACzE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,QAAgB,EAAE,QAA+B,EAAE,MAA2B;IAC3H,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAChG,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,KAAK,GAAG,CAAC,IAAa,EAAE,MAA8B,EAAQ,EAAE;QACpE,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9E,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3H,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC;IACF,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACf,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACnE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACtC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QACjG,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,sBAAsB,MAAM,QAAQ,CAAC,CAAC;QAClG,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1H,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QAC1B,IAAI,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACvG,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS,GAAG,KAAK,SAAS,EAAE,CAAC;QACjF,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,SAAS;YAAE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAC7F,IAAI,KAAK,CAAC,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,eAAe,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;;YACvF,OAAO,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,QAAQ,OAAO,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClI,CAAC;IACD,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,QAAgB,EAAE,IAAY,EAAE,QAA+B,EAAE,MAA2B;IAC/I,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3B,OAAO,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,MAAc,EAAE,QAAgB,EAAE,OAAO,GAAmB,EAAE,EAAE,MAAM,GAAwB,QAAQ;IACjJ,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClE,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;IAClD,OAAO;QACL,GAAG,QAAQ;QACX,IAAI;QACJ,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,GAAG,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ;KAC1L,CAAC;AACJ,CAAC","sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { extname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport ts from \"@typescript/typescript6\";\nimport { compile } from \"./compiler.js\";\nimport type { CompileOptions, CompileResult } from \"./compiler.js\";\nimport { projectRoot } from \"./compiler/project-root.js\";\nimport { parseSfc } from \"./compiler/sfc.js\";\nimport { loadMeekoConfig, readMeekoConfigSync, resolveConfigSources } from \"./framework/config.js\";\n\nexport type ImportScope = \"client\" | \"server\" | \"shared\";\nexport interface AutoImport {\n name: string;\n imported: string;\n file: string;\n scope: ImportScope;\n typeOnly: boolean;\n component: boolean;\n specifier?: string;\n}\n\nconst directories = [\n \"app/components\", \"app/composables\", \"app/utils\", \"app/stores\",\n \"shared/types\", \"shared/schemas\", \"shared/utils\", \"shared/constants\", \"shared/enums\",\n \"server/utils\",\n] as const;\n\nfunction scopeOf(file: string): ImportScope {\n if (/\\.shared\\.[cm]?tsx?$/.test(file)) return \"shared\";\n if (/\\.server\\.[cm]?tsx?$/.test(file)) return \"server\";\n if (/\\.client\\.[cm]?tsx?$/.test(file)) return \"client\";\n if (file.includes(`${sep}server${sep}`)) return \"server\";\n if (file.includes(`${sep}app${sep}`)) return \"client\";\n return \"shared\";\n}\n\nasync function filesIn(path: string): Promise<string[]> {\n const entries = await readdir(path, { withFileTypes: true }).catch(() => []);\n const files: string[] = [];\n for (const entry of entries) {\n const filename = join(path, entry.name);\n if (entry.isDirectory()) files.push(...await filesIn(filename));\n else if (/\\.(?:meeko|[cm]?ts)$/.test(entry.name) && !/\\.(?:test|spec|d)\\.[cm]?ts$/.test(entry.name)) files.push(filename);\n }\n return files;\n}\n\nfunction filesInSync(path: string): string[] {\n let entries;\n try { entries = readdirSync(path, { withFileTypes: true }); }\n catch (error) { if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return []; throw error; }\n const files: string[] = [];\n for (const entry of entries) {\n const filename = join(path, entry.name);\n if (entry.isDirectory()) files.push(...filesInSync(filename));\n else if (/\\.(?:meeko|[cm]?ts)$/.test(entry.name) && !/\\.(?:test|spec|d)\\.[cm]?ts$/.test(entry.name)) files.push(filename);\n }\n return files;\n}\n\nfunction builtins(root: string): AutoImport[] {\n const entries: AutoImport[] = [\n ...[\"signal\", \"computed\", \"effect\", \"batch\", \"onCleanup\", \"provide\", \"inject\", \"createContext\"].map((name): AutoImport => ({ name, imported: name, file: \"@meekojs/meeko\", specifier: \"@meekojs/meeko\", scope: \"shared\", typeOnly: false, component: false })),\n ...[\"useState\", \"href\"].map((name): AutoImport => ({ name, imported: name, file: \"@meekojs/meeko/framework\", specifier: \"@meekojs/meeko/framework\", scope: \"shared\", typeOnly: false, component: false })),\n ];\n for (const scope of [\"client\", \"server\"] as const) {\n const file = join(root, \".meeko\", \"generated\", `clients.${scope}.ts`);\n if (!existsSync(file)) continue;\n for (const name of [\"api\", \"rpc\", \"socket\", \"useSocket\"]) entries.push({ name, imported: name, file, scope, typeOnly: false, component: false });\n }\n if (!entries.some((entry) => entry.name === \"useSocket\")) {\n entries.push({ name: \"useSocket\", imported: \"useSocket\", file: \"@meekojs/meeko/framework\", specifier: \"@meekojs/meeko/framework\", scope: \"shared\", typeOnly: false, component: false });\n }\n return entries;\n}\n\nfunction addFileImports(result: AutoImport[], root: string, directory: string, file: string, source?: string): void {\n const scope = scopeOf(file);\n if (extname(file) === \".meeko\") {\n if (directory !== \"app/components\") return;\n const path = relative(join(root, directory), file).replace(/\\.meeko$/, \"\");\n const name = path.split(/[\\\\/]/).map((part) => part.replace(/(^|[-_])(\\w)/g, (_, _dash: string, letter: string) => letter.toUpperCase())).join(\"\");\n result.push({ name, imported: \"*\", file, scope, typeOnly: false, component: true });\n return;\n }\n const ast = ts.createSourceFile(file, source ?? \"\", ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n for (const statement of ast.statements) {\n const exported = ts.canHaveModifiers(statement) && ts.getModifiers(statement)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);\n if (exported && (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) {\n result.push({ name: statement.name.text, imported: statement.name.text, file, scope, typeOnly: ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement), component: false });\n }\n if (exported && ts.isVariableStatement(statement)) {\n for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name)) {\n result.push({ name: declaration.name.text, imported: declaration.name.text, file, scope, typeOnly: false, component: false });\n }\n }\n if (ts.isExportDeclaration(statement) && statement.exportClause && ts.isNamedExports(statement.exportClause)) {\n for (const element of statement.exportClause.elements) result.push({ name: element.name.text, imported: element.name.text, file, scope, typeOnly: statement.isTypeOnly || element.isTypeOnly, component: false });\n }\n }\n}\n\n/** Construye el registro a partir de exports sintácticos, sin ejecutar módulos de la aplicación. */\nexport async function discoverAutoImports(root: string): Promise<AutoImport[]> {\n const result: AutoImport[] = builtins(root);\n const config = await loadMeekoConfig(root);\n const sources = await resolveConfigSources(root, config);\n for (const source of sources) {\n for (const directory of configuredDirectories(config.imports?.serverDirs)) {\n for (const file of await filesIn(join(source.root, directory))) {\n addFileImports(result, source.root, directory, file, extname(file) === \".meeko\" ? undefined : await readFile(file, \"utf8\"));\n }\n }\n }\n return result;\n}\n\n/** Same static registry used by the synchronous VS Code Language Service. */\nexport function discoverAutoImportsSync(root: string): AutoImport[] {\n const result = builtins(root);\n const config = readMeekoConfigSync(root);\n const sourceRoots = [resolve(root)];\n for (const entry of [...(config.extends ?? []), ...(config.modules ?? [])]) {\n const sourceRoot = resolve(root, entry);\n const path = relative(root, sourceRoot);\n if (path === \"..\" || path.startsWith(`..${sep}`) || isAbsolute(path)) throw new Error(`Configured autoimport source escapes project root: ${entry}`);\n sourceRoots.push(sourceRoot);\n }\n for (const sourceRoot of sourceRoots) {\n for (const directory of configuredDirectories(config.imports?.serverDirs)) {\n for (const file of filesInSync(join(sourceRoot, directory))) {\n addFileImports(result, sourceRoot, directory, file, extname(file) === \".meeko\" ? undefined : readFileSync(file, \"utf8\"));\n }\n }\n }\n return result;\n}\n\nfunction configuredDirectories(serverDirs: readonly string[] | undefined): readonly string[] {\n const result = new Set<string>(directories);\n for (const raw of serverDirs ?? []) {\n const directory = raw.replaceAll(\"\\\\\", \"/\").replace(/\\/$/, \"\");\n const parts = directory.split(\"/\");\n if (parts[0] !== \"server\" || parts.length < 2 || parts.some((part) => !part || part === \".\" || part === \"..\")) {\n throw new Error(`Autoimport serverDir must be a relative path under server/: ${raw}`);\n }\n result.add(directory);\n }\n return [...result];\n}\n\nfunction bindingNames(name: ts.BindingName, names: Set<string>): void {\n if (ts.isIdentifier(name)) names.add(name.text);\n else for (const element of name.elements) if (ts.isBindingElement(element)) bindingNames(element.name, names);\n}\n\nfunction scopeNames(node: ts.Node): Set<string> {\n const names = new Set<string>();\n if (ts.isFunctionLike(node)) {\n for (const parameter of node.parameters) bindingNames(parameter.name, names);\n for (const parameter of node.typeParameters ?? []) names.add(parameter.name.text);\n }\n if (ts.isCatchClause(node) && node.variableDeclaration) bindingNames(node.variableDeclaration.name, names);\n if (ts.isForStatement(node) && node.initializer && ts.isVariableDeclarationList(node.initializer)) {\n for (const declaration of node.initializer.declarations) bindingNames(declaration.name, names);\n }\n if ((ts.isForOfStatement(node) || ts.isForInStatement(node)) && ts.isVariableDeclarationList(node.initializer)) {\n for (const declaration of node.initializer.declarations) bindingNames(declaration.name, names);\n }\n if (ts.isSourceFile(node) || ts.isBlock(node)) {\n for (const statement of node.statements) {\n if (ts.isVariableStatement(statement)) for (const declaration of statement.declarationList.declarations) bindingNames(declaration.name, names);\n if ((ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement) || ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);\n if (ts.isImportDeclaration(statement)) {\n const clause = statement.importClause;\n if (clause?.name) names.add(clause.name.text);\n if (clause?.namedBindings) {\n if (ts.isNamespaceImport(clause.namedBindings)) names.add(clause.namedBindings.name.text);\n else for (const element of clause.namedBindings.elements) names.add(element.name.text);\n }\n }\n }\n }\n return names;\n}\n\nfunction introducesScope(node: ts.Node): boolean {\n return ts.isSourceFile(node) || ts.isBlock(node) || ts.isFunctionLike(node) || ts.isCatchClause(node)\n || ts.isForStatement(node) || ts.isForOfStatement(node) || ts.isForInStatement(node);\n}\n\nfunction isReference(node: ts.Identifier): boolean {\n const parent = node.parent;\n if (!parent) return false;\n if (ts.isPropertyAccessExpression(parent) && parent.name === node) return false;\n if (ts.isQualifiedName(parent) && parent.right === node) return false;\n if (ts.isPropertyAssignment(parent) && parent.name === node) return false;\n if (ts.isPropertyDeclaration(parent) && parent.name === node) return false;\n if (ts.isMethodDeclaration(parent) && parent.name === node) return false;\n if (ts.isImportSpecifier(parent) || ts.isExportSpecifier(parent) || ts.isImportClause(parent) || ts.isNamespaceImport(parent)) return false;\n if (ts.isTypeReferenceNode(parent) && parent.typeName === node) return true;\n if (ts.isParameter(parent) && parent.name === node) return false;\n if (ts.isTypeParameterDeclaration(parent) && parent.name === node) return false;\n if (ts.isVariableDeclaration(parent) && parent.name === node) return false;\n if ((ts.isFunctionDeclaration(parent) || ts.isClassDeclaration(parent) || ts.isInterfaceDeclaration(parent) || ts.isTypeAliasDeclaration(parent)) && parent.name === node) return false;\n if (ts.isPropertySignature(parent) && parent.name === node) return false;\n return true;\n}\n\n/** Añade imports ESM para referencias libres del módulo generado. */\nexport function applyAutoImports(code: string, filename: string, registry: readonly AutoImport[], target: \"client\" | \"server\"): string {\n const ast = ts.createSourceFile(filename, code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const referenced = new Set<string>();\n const visit = (node: ts.Node, scopes: readonly Set<string>[]): void => {\n const active = introducesScope(node) ? [...scopes, scopeNames(node)] : scopes;\n if (ts.isIdentifier(node) && isReference(node) && !active.some((scope) => scope.has(node.text))) referenced.add(node.text);\n ts.forEachChild(node, (child) => visit(child, active));\n };\n visit(ast, []);\n const imports: string[] = [];\n for (const name of [...referenced].sort()) {\n const candidates = registry.filter((entry) => entry.name === name);\n if (candidates.length === 0) continue;\n const allowed = candidates.filter((entry) => entry.scope === \"shared\" || entry.scope === target);\n if (allowed.length === 0) throw new Error(`Autoimport ${name} is unavailable in ${target} scope`);\n if (allowed.length > 1) throw new Error(`Ambiguous autoimport ${name}: ${allowed.map((entry) => entry.file).join(\", \")}`);\n const entry = allowed[0]!;\n let specifier = entry.specifier ?? relative(resolve(filename, \"..\"), entry.file).replaceAll(\"\\\\\", \"/\");\n if (!entry.specifier && !specifier.startsWith(\".\")) specifier = `./${specifier}`;\n if (!entry.component && !entry.specifier) specifier = specifier.replace(/\\.[cm]?ts$/, \".js\");\n if (entry.component) imports.push(`import * as ${name} from ${JSON.stringify(specifier)};`);\n else imports.push(`import ${entry.typeOnly ? \"type \" : \"\"}{ ${entry.imported} as ${name} } from ${JSON.stringify(specifier)};`);\n }\n return imports.length ? `${imports.join(\"\\n\")}\\n${code}` : code;\n}\n\n/** Transforma un SFC usando exactamente el mismo compilador que el plugin Vite. */\nexport function transformAutoImports(source: string, filename: string, code: string, registry: readonly AutoImport[], target: \"client\" | \"server\"): string {\n parseSfc(source, filename);\n return applyAutoImports(code, filename, registry, target);\n}\n\n/** Compile result shared by Vite, CLI checks and declaration generation. */\nexport async function compileWithAutoImports(source: string, filename: string, options: CompileOptions = {}, target: \"client\" | \"server\" = \"client\"): Promise<CompileResult> {\n const compiled = compile(source, filename, options);\n const registry = await discoverAutoImports(projectRoot(filename));\n const code = transformAutoImports(source, filename, compiled.code, registry, target);\n const offset = code.length - compiled.code.length;\n return {\n ...compiled,\n code,\n mappings: offset ? compiled.mappings.map((mapping) => ({ ...mapping, generatedStart: mapping.generatedStart + offset, generatedEnd: mapping.generatedEnd + offset })) : compiled.mappings,\n };\n}\n"]}
|