|
|
|
@@ -1,4 +1,4 @@
|
|
|
|
|
import { existsSync, readFileSync } from "node:fs";
|
|
|
|
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
|
|
|
import { dirname, join, normalize, resolve } from "node:path";
|
|
|
|
|
import ts from "typescript";
|
|
|
|
|
import {
|
|
|
|
@@ -51,6 +51,39 @@ function resolveImportedWrn(source: string, filePath: string, appRoot: string):
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function workspacePackagePaths(appRoot: string): Record<string, string[]> {
|
|
|
|
|
let current = resolve(appRoot);
|
|
|
|
|
while (true) {
|
|
|
|
|
const manifestPath = join(current, "package.json");
|
|
|
|
|
if (existsSync(manifestPath)) {
|
|
|
|
|
try {
|
|
|
|
|
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
|
|
|
if (Array.isArray(manifest.workspaces) && existsSync(join(current, "packages"))) {
|
|
|
|
|
const paths: Record<string, string[]> = {};
|
|
|
|
|
for (const entry of readdirSync(join(current, "packages"), { withFileTypes: true })) {
|
|
|
|
|
if (!entry.isDirectory()) continue;
|
|
|
|
|
const packageRoot = join(current, "packages", entry.name);
|
|
|
|
|
const packageManifestPath = join(packageRoot, "package.json");
|
|
|
|
|
if (!existsSync(packageManifestPath)) continue;
|
|
|
|
|
const packageManifest = JSON.parse(readFileSync(packageManifestPath, "utf8"));
|
|
|
|
|
if (typeof packageManifest.name !== "string") continue;
|
|
|
|
|
const main =
|
|
|
|
|
typeof packageManifest.main === "string" ? packageManifest.main : "src/index.ts";
|
|
|
|
|
paths[packageManifest.name] = [join(packageRoot, main)];
|
|
|
|
|
paths[`${packageManifest.name}/*`] = [join(packageRoot, "src", "*.ts")];
|
|
|
|
|
}
|
|
|
|
|
return paths;
|
|
|
|
|
}
|
|
|
|
|
} catch {
|
|
|
|
|
/* continue toward a parent workspace */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const parent = dirname(current);
|
|
|
|
|
if (parent === current) return {};
|
|
|
|
|
current = parent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function importedWrnDeclarations(ast: PageAst, filePath: string, appRoot: string): string {
|
|
|
|
|
const declarations: string[] = [];
|
|
|
|
|
for (const entry of ast.structuredImports) {
|
|
|
|
@@ -106,7 +139,7 @@ function functionDeclaration(fn: RuntimeFunctionDecl): string {
|
|
|
|
|
const params = fn.parameters
|
|
|
|
|
.map(
|
|
|
|
|
(param) =>
|
|
|
|
|
`${param.name}${param.optional ? "?" : ""}${param.valueType ? `: ${param.valueType}` : ": unknown"}${param.default ? ` = ${param.default}` : ""}`,
|
|
|
|
|
`${param.name}${param.optional ? "?" : ""}${param.valueType ? `: ${param.valueType}` : param.name === "event" ? ": CustomEvent<any> & { target: HTMLElement }" : ": unknown"}${param.default ? ` = ${param.default}` : ""}`,
|
|
|
|
|
)
|
|
|
|
|
.join(", ");
|
|
|
|
|
return `export ${fn.async ? "async " : ""}function ${fn.name}(${params})${fn.returnType ? `: ${fn.returnType}` : ""} {${fn.body}}`;
|
|
|
|
@@ -186,6 +219,12 @@ export function virtualTypeScriptModule(
|
|
|
|
|
)
|
|
|
|
|
.join("; ");
|
|
|
|
|
append(`declare const output: { ${outputType} };`);
|
|
|
|
|
for (const output of ast.outputs)
|
|
|
|
|
append(
|
|
|
|
|
`declare const ${output.name}: (${output.payload ? `${output.payload.name}${output.payload.optional ? "?" : ""}: ${output.payload.valueType}` : ""}) => void;`,
|
|
|
|
|
);
|
|
|
|
|
for (const match of source.matchAll(/@event\s+([A-Za-z_$][\w$]*)\s*=\s*function/g))
|
|
|
|
|
append(`declare const ${match[1]}: ((...args: unknown[]) => void) | undefined;`);
|
|
|
|
|
append(`declare const server: { ${serverType} };`);
|
|
|
|
|
append(`declare const props: Readonly<${ast.name}Props>;`);
|
|
|
|
|
append("declare const refs: Record<string, Element | null>;");
|
|
|
|
@@ -601,8 +640,8 @@ export function checkWrnSource(
|
|
|
|
|
allowArbitraryExtensions: true,
|
|
|
|
|
noEmit: true,
|
|
|
|
|
baseUrl: appRoot,
|
|
|
|
|
paths: { "@/*": ["app/*"] },
|
|
|
|
|
lib: ["lib.esnext.d.ts", "lib.dom.d.ts"],
|
|
|
|
|
paths: { "@/*": ["app/*"], ...workspacePackagePaths(appRoot) },
|
|
|
|
|
lib: ["lib.esnext.d.ts", "lib.dom.d.ts", "lib.dom.iterable.d.ts"],
|
|
|
|
|
};
|
|
|
|
|
const rootNames = [virtual.fileName, ...appTypes.files.keys()];
|
|
|
|
|
const program = ts.createProgram(
|
|
|
|
|