diff --git a/.changeset/real-points-chew.md b/.changeset/real-points-chew.md new file mode 100644 index 00000000..0be96644 --- /dev/null +++ b/.changeset/real-points-chew.md @@ -0,0 +1,8 @@ +--- +"@vinxi/plugin-references": patch +"@vinxi/solid-start": patch +"@vinxi/router": patch +"vinxi": patch +--- + +changed `style` to `routes` and removed `compile` nested, flat options API diff --git a/examples/react/rsc/spa/app.config.js b/examples/react/rsc/spa/app.config.js index cc499307..27756195 100644 --- a/examples/react/rsc/spa/app.config.js +++ b/examples/react/rsc/spa/app.config.js @@ -23,25 +23,21 @@ export default createApp({ mode: "handler", base: "/_rsc", handler: "./app/react-server.tsx", - compile: { - target: "server", - plugins: () => [references.serverComponents(), reactRefresh()], - }, + target: "server", + plugins: () => [references.serverComponents(), reactRefresh()], }, { name: "client", mode: "spa", handler: "./index.ts", - compile: { - target: "browser", - plugins: () => [ - references.clientRouterPlugin({ - runtime: "@vinxi/react-server-dom/runtime", - }), - reactRefresh(), - references.clientComponents(), - ], - }, + target: "browser", + plugins: () => [ + references.clientRouterPlugin({ + runtime: "@vinxi/react-server-dom/runtime", + }), + reactRefresh(), + references.clientComponents(), + ], base: "/", }, { @@ -50,16 +46,14 @@ export default createApp({ mode: "handler", base: "/_server", handler: "./app/server-action.tsx", - compile: { - target: "server", - plugins: () => [ - references.serverRouterPlugin({ - resolve: { - conditions: ["react-server"], - }, - }), - ], - }, + target: "server", + plugins: () => [ + references.serverRouterPlugin({ + resolve: { + conditions: ["react-server"], + }, + }), + ], }, ], }); diff --git a/examples/react/spa/mdx/app.config.js b/examples/react/spa/mdx/app.config.js index 101f5c3e..922de816 100644 --- a/examples/react/spa/mdx/app.config.js +++ b/examples/react/spa/mdx/app.config.js @@ -45,7 +45,7 @@ function wouterFileRouter(config) { return (router, app) => new WouterFileSystemRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: config.extensions ?? ["js", "jsx", "ts", "tsx", "mdx"], }, router, @@ -64,18 +64,16 @@ export default createApp({ name: "client", mode: "spa", handler: "./index.html", - style: wouterFileRouter({ dir: "./app/pages" }), - compile: { - target: "browser", - plugins: () => [ - mdx.withImports({ - react: "React", - })({ - providerImportSource: "@mdx-js/react", - }), - reactRefresh({}), - ], - }, + routes: wouterFileRouter({ dir: "./app/pages" }), + target: "browser", + plugins: () => [ + mdx.withImports({ + react: "React", + })({ + providerImportSource: "@mdx-js/react", + }), + reactRefresh({}), + ], }, ], }); diff --git a/examples/react/spa/tanstack-router-app/app.config.js b/examples/react/spa/tanstack-router-app/app.config.js index 17dd1b74..44ae56b0 100644 --- a/examples/react/spa/tanstack-router-app/app.config.js +++ b/examples/react/spa/tanstack-router-app/app.config.js @@ -62,13 +62,13 @@ class TanstackFileSystemRouter extends BaseFileSystemRouter { /** * - * @param {import("vinxi/file-system-router").FileSystemRouterConfig} config + * @param {Partial} config */ function tanstackFileRouter(config) { return (router, app) => new TanstackFileSystemRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: config.extensions ?? ["ts", "tsx", "jsx", "js"], }, router, @@ -87,13 +87,11 @@ export default createApp({ name: "client", mode: "spa", handler: "./index.html", - style: tanstackFileRouter({ + routes: tanstackFileRouter({ dir: "./app/routes", }), - compile: { - target: "browser", - plugins: () => [reactRefresh()], - }, + target: "browser", + plugins: () => [reactRefresh()], }, ], }); diff --git a/examples/react/spa/tanstack-router/app.config.js b/examples/react/spa/tanstack-router/app.config.js index e90b8978..2df9961a 100644 --- a/examples/react/spa/tanstack-router/app.config.js +++ b/examples/react/spa/tanstack-router/app.config.js @@ -23,23 +23,19 @@ export default createApp({ name: "client", mode: "spa", handler: "./index.html", - style: tanstackFileRouter({ + routes: tanstackFileRouter({ dir: "./app/pages", }), - compile: { - target: "browser", - plugins: () => [references.clientRouterPlugin(), reactRefresh()], - }, + target: "browser", + plugins: () => [references.clientRouterPlugin(), reactRefresh()], }, { name: "server", mode: "handler", base: "/_server", handler: "./app/entry-server.tsx", - compile: { - target: "server", - plugins: () => [references.serverRouterPlugin()], - }, + target: "server", + plugins: () => [references.serverRouterPlugin()], }, ], }); diff --git a/examples/react/spa/tanstack-router/lib/file-router.js b/examples/react/spa/tanstack-router/lib/file-router.js index 85b9ff05..1b0119a4 100644 --- a/examples/react/spa/tanstack-router/lib/file-router.js +++ b/examples/react/spa/tanstack-router/lib/file-router.js @@ -58,7 +58,7 @@ export function tanstackFileRouter(config) { return (router, app) => new TanstackFileRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: config.extensions ?? ["js", "jsx", "ts", "tsx"], }, router, diff --git a/examples/react/spa/wouter/app.config.js b/examples/react/spa/wouter/app.config.js index 9e426c55..58add997 100644 --- a/examples/react/spa/wouter/app.config.js +++ b/examples/react/spa/wouter/app.config.js @@ -44,7 +44,7 @@ function wouterFileRouter(config) { return (router, app) => new WouterFileSystemRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: config.extensions ?? ["js", "jsx", "ts", "tsx"], }, router, @@ -63,13 +63,11 @@ export default createApp({ name: "client", mode: "spa", handler: "./index.html", - style: wouterFileRouter({ + routes: wouterFileRouter({ dir: "./app/pages", }), - compile: { - target: "browser", - plugins: () => [reactRefresh()], - }, + target: "browser", + plugins: () => [reactRefresh()], }, ], }); diff --git a/examples/react/ssr/basic/app.config.js b/examples/react/ssr/basic/app.config.js index ae6a7b51..69f66be5 100644 --- a/examples/react/ssr/basic/app.config.js +++ b/examples/react/ssr/basic/app.config.js @@ -13,10 +13,8 @@ export default createApp({ name: "client", mode: "build", handler: "./app/client.tsx", - compile: { - target: "browser", - plugins: () => [reactRefresh()], - }, + target: "browser", + plugins: () => [reactRefresh()], base: "/_build", }, { @@ -24,9 +22,8 @@ export default createApp({ mode: "handler", middleware: "./app/middleware.tsx", handler: "./app/server.tsx", - compile: { - target: "server", - }, + target: "server", + plugins: () => [reactRefresh()], }, ], }); diff --git a/examples/react/ssr/basic/app/server.tsx b/examples/react/ssr/basic/app/server.tsx index 692d6b53..1b06d90e 100644 --- a/examples/react/ssr/basic/app/server.tsx +++ b/examples/react/ssr/basic/app/server.tsx @@ -27,12 +27,6 @@ export default eventHandler(async (event) => { ); }); - // @ts-ignore - stream._read = () => {}; - // @ts-ignore - stream.on = (event, listener) => { - events[event] = listener; - }; event.node.res.setHeader("Content-Type", "text/html"); return stream; }); diff --git a/examples/react/ssr/tanstack-router-app/app.config.js b/examples/react/ssr/tanstack-router-app/app.config.js index a720f30f..d46e54f6 100644 --- a/examples/react/ssr/tanstack-router-app/app.config.js +++ b/examples/react/ssr/tanstack-router-app/app.config.js @@ -64,7 +64,7 @@ function tanstackFileRouter(config) { return (router, app) => new TanstackFileRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: config.extensions ?? ["ts", "tsx", "jsx", "js"], }, router, @@ -91,21 +91,17 @@ export default createApp({ name: "client", mode: "build", handler: "./app/client.tsx", - style: tanstackFileRouter({ dir: "./app/routes" }), - compile: { - target: "browser", - plugins: () => [reactRefresh()], - }, + routes: tanstackFileRouter({ dir: "./app/routes" }), + target: "browser", + plugins: () => [reactRefresh()], }, { name: "ssr", mode: "handler", handler: "./app/server.tsx", - style: tanstackFileRouter({ dir: "./app/routes" }), - compile: { - target: "server", - plugins: () => [reactRefresh()], - }, + routes: tanstackFileRouter({ dir: "./app/routes" }), + target: "server", + plugins: () => [reactRefresh()], }, ], }); diff --git a/examples/solid/ssr/solid-router/app.config.js b/examples/solid/ssr/solid-router/app.config.js index 977e1ea5..0cb05c21 100644 --- a/examples/solid/ssr/solid-router/app.config.js +++ b/examples/solid/ssr/solid-router/app.config.js @@ -52,7 +52,7 @@ function solidStartFileRouter(config) { return (router, app) => new SolidStartFileSystemRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: config.extensions ?? ["js", "jsx", "ts", "tsx"], }, router, @@ -72,30 +72,26 @@ export default createApp({ name: "client", mode: "build", handler: "./app/client.tsx", - style: solidStartFileRouter({ + routes: solidStartFileRouter({ dir: "./app/pages", }), - compile: { - target: "browser", - plugins: () => [ - solid({ - ssr: true, - }), - ], - }, + target: "browser", + plugins: () => [ + solid({ + ssr: true, + }), + ], base: "/_build", }, { name: "ssr", mode: "handler", handler: "./app/server.tsx", - style: solidStartFileRouter({ + routes: solidStartFileRouter({ dir: "./app/pages", }), - compile: { - target: "server", - plugins: () => [solid({ ssr: true })], - }, + target: "server", + plugins: () => [solid({ ssr: true })], }, ], }); diff --git a/frameworks/solid-start/index.js b/frameworks/solid-start/index.js index 85c0bd6b..7498834e 100644 --- a/frameworks/solid-start/index.js +++ b/frameworks/solid-start/index.js @@ -54,7 +54,7 @@ function solidStartFileSystemRouter(config) { return (router, app) => new SolidStartFileSystemRouter( { - dir: resolve.absolute(config.dir, router, app), + dir: resolve.absolute(config.dir, router.root), extensions: ["tsx", "ts", "jsx", "js"], }, router, @@ -75,46 +75,42 @@ export function defineConfig({} = {}) { name: "client", mode: "build", handler: "./src/entry-client.tsx", - style: solidStartFileSystemRouter({ + routes: solidStartFileSystemRouter({ dir: "./src/routes", }), - compile: { - target: "browser", - plugins: () => [ - solid({ - ssr: true, - }), - config("root", { - resolve: { - alias: { - "#start/root": join(process.cwd(), "src", "root.tsx"), - }, + target: "browser", + plugins: () => [ + solid({ + ssr: true, + }), + config("root", { + resolve: { + alias: { + "#start/root": join(process.cwd(), "src", "root.tsx"), }, - }), - ], - }, + }, + }), + ], base: "/_build", }, { name: "ssr", mode: "handler", handler: "./src/entry-server.tsx", - style: solidStartFileSystemRouter({ + routes: solidStartFileSystemRouter({ dir: "./src/routes", }), - compile: { - target: "server", - plugins: () => [ - solid({ ssr: true }), - config("root", { - resolve: { - alias: { - "#start/root": join(process.cwd(), "src", "root.tsx"), - }, + target: "server", + plugins: () => [ + solid({ ssr: true }), + config("root", { + resolve: { + alias: { + "#start/root": join(process.cwd(), "src", "root.tsx"), }, - }), - ], - }, + }, + }), + ], }, ], }); diff --git a/packages/vinxi-references/chunks.js b/packages/vinxi-references/chunks.js index 3565a428..9eff1ca2 100644 --- a/packages/vinxi-references/chunks.js +++ b/packages/vinxi-references/chunks.js @@ -4,10 +4,7 @@ import { join } from "path"; function getChunks(app, routerName, modIndex) { const router = app.getRouter(routerName); const bundlerManifest = JSON.parse( - readFileSync( - join(router.build.outDir, router.base, "manifest.json"), - "utf-8", - ), + readFileSync(join(router.outDir, router.base, "manifest.json"), "utf-8"), ); const chunks = Object.entries(bundlerManifest) @@ -15,7 +12,7 @@ function getChunks(app, routerName, modIndex) { ([name, chunk]) => chunk.file.startsWith("c_") && name !== router.handler, ) .map(([name, chunk], index) => { - const chunkPath = join(router.build.outDir, router.base, chunk.file); + const chunkPath = join(router.outDir, router.base, chunk.file); return ` import * as mod_${index}_${modIndex} from '${chunkPath}'; chunks['${chunk.file}'] = mod_${index}_${modIndex} diff --git a/packages/vinxi-references/client-components.js b/packages/vinxi-references/client-components.js index b6f284cf..5f610748 100644 --- a/packages/vinxi-references/client-components.js +++ b/packages/vinxi-references/client-components.js @@ -5,7 +5,7 @@ import { SERVER_REFERENCES_MANIFEST, hash } from "./constants.js"; /** * - * @returns {import('vinxi').PluginOption} + * @returns {import('vinxi').Plugin} */ export function clientComponents({ server = "rsc", @@ -28,7 +28,7 @@ export function clientComponents({ const serverManifest = JSON.parse( readFileSync( - join(serverRouter.build.outDir, serverRouter.base, manifest), + join(serverRouter.outDir, serverRouter.base, manifest), "utf-8", ), ); diff --git a/packages/vinxi-references/index.js b/packages/vinxi-references/index.js index b768e6e8..0d5553d4 100644 --- a/packages/vinxi-references/index.js +++ b/packages/vinxi-references/index.js @@ -20,11 +20,8 @@ export const references = { mode: "handler", base: "/_server", handler: fileURLToPath(new URL("./server-handler.js", import.meta.url)), + target: "server", ...(overrides ?? {}), - build: { - target: "server", - ...(overrides?.build ?? {}), - plugins: () => [server(), ...(overrides?.build?.plugins?.() ?? [])], - }, + plugins: () => [server(), ...(overrides?.plugins?.() ?? [])], }), }; diff --git a/packages/vinxi-references/server.js b/packages/vinxi-references/server.js index 287c3410..5a2e0f73 100644 --- a/packages/vinxi-references/server.js +++ b/packages/vinxi-references/server.js @@ -31,7 +31,7 @@ export function server({ const reactClientManifest = JSON.parse( readFileSync( - join(rscRouter.build.outDir, rscRouter.base, manifest), + join(rscRouter.outDir, rscRouter.base, manifest), "utf-8", ), ); diff --git a/packages/vinxi-router/spa.js b/packages/vinxi-router/spa.js index ea6af6f9..bad221be 100644 --- a/packages/vinxi-router/spa.js +++ b/packages/vinxi-router/spa.js @@ -3,29 +3,22 @@ import tsconfigPaths from "vite-tsconfig-paths"; /** * - * @param {{ plugins: () => import('vinxi').Plugin[]; dir: string; style: string; }} param0 - * @returns {import('vinxi').RouterSchema} + * @param {{ plugins?: () => import('vinxi').Plugin[]; routes?: import("vinxi").RouterStyleFn; }} param0 + * @returns {import('vinxi').RouterSchemaInput} */ -export function spaRouter({ - plugins = () => [], - dir = undefined, - style = undefined, -} = {}) { +export function spaRouter({ plugins = () => [], routes = undefined } = {}) { return { name: "client", mode: "spa", handler: "./index.html", - dir, - style, - build: { - target: "browser", - plugins: () => [ - ...((plugins?.() ?? []).filter(Boolean) ?? []), - config("env-vars", { - envPrefix: "PUBLIC_", - }), - tsconfigPaths(), - ], - }, + routes, + target: "browser", + plugins: () => [ + ...((plugins?.() ?? []).filter(Boolean) ?? []), + config("env-vars", { + envPrefix: "PUBLIC_", + }), + tsconfigPaths(), + ], }; } diff --git a/packages/vinxi/lib/app.js b/packages/vinxi/lib/app.js index 856b2448..7b6bdfb4 100644 --- a/packages/vinxi/lib/app.js +++ b/packages/vinxi/lib/app.js @@ -6,103 +6,38 @@ import invariant, { InvariantError } from "./invariant.js"; import { resolve } from "./resolve.js"; export { resolve }; -/** - * - * @param {RouterSchema} router - * @param {AppOptions} appConfig - * @returns {RouterSchema} - */ -function resolveConfig(router, appConfig) { - switch (router.mode) { - case "static": - return { - base: "/", - root: appConfig.root, - ...router, - }; - case "build": - return { - base: "/", - root: appConfig.root, - ...router, - handler: resolve.relative(router.handler, router, appConfig), - compiled: router.style ? router.style(router, appConfig) : undefined, - compile: { - ...(router.compile ?? {}), - outDir: router.compile?.outDir - ? join(appConfig.root, router.compile.outDir) - : join(appConfig.root, ".nitro", "build", router.name), - }, - }; - case "handler": - return { - base: "/", - root: appConfig.root, - ...router, - handler: resolve.relative(router.handler, router, appConfig), - middleware: resolve.relative(router.middleware, router, appConfig), - compiled: router.style ? router.style(router, appConfig) : undefined, - compile: { - ...(router.compile ?? {}), - outDir: router.compile?.outDir - ? join(appConfig.root, router.compile.outDir) - : join(appConfig.root, ".nitro", "build", router.name), - }, - }; - case "spa": - return { - base: "/", - root: appConfig.root, - ...router, - handler: resolve.relative(router.handler, router, appConfig), - compiled: router.style ? router.style(router, appConfig) : undefined, - compile: { - ...(router.compile ?? {}), - outDir: router.compile?.outDir - ? join(appConfig.root, router.compile.outDir) - : join(appConfig.root, ".nitro", "build", router.name), - }, - }; - } -} -/** @typedef {"static" | "build" | "spa" | "handler"} RouterModes */ -/** @type {[RouterModes, ...RouterModes[]]} */ -const routerModes = ["static", "build", "spa", "handler"]; +/** + * @typedef {{ routes?: CompiledRouter; devServer?: import('vite').ViteDevServer; appWorker?: import('./app-worker-client.js').AppWorkerClient; }} Internals + * @typedef {{ getRoutes(): Promise; } & EventTarget} CompiledRouter + * @typedef {(router: RouterSchemaInput, app: AppOptions) => CompiledRouter} RouterStyleFn + * */ const staticRouterSchema = v.object({ name: v.string(), - base: v.string().default("/"), + base: v.optional(v.string().default("/")), mode: v.literal("static"), dir: v.string(), root: v.optional(v.string()), }); -/** @typedef {v.infer} StaticRouterSchema */ - const buildRouterSchema = v.object({ name: v.string(), - base: v.string().default("/"), + base: v.optional(v.string().default("/")), root: v.optional(v.string()), mode: v.literal("build"), handler: v.string(), - /** @type {v.ZodType} */ - style: v.custom((value) => value !== null), + /** @type {v.ZodOptionalType>} */ + routes: v.optional(v.custom((value) => value !== null)), extensions: v.array(v.string()).optional(), - compile: v.object({ - outDir: v.string().optional(), - target: v.literal("browser"), - plugins: v.optional(v.custom((value) => typeof value === "function")), - }), + outDir: v.string().optional(), + target: v.literal("browser"), + plugins: v.optional(v.custom((value) => typeof value === "function")), }); -/** @typedef {{ getRoutes(): Promise }} CompiledRouter */ -/** @typedef {(router: RouterSchema, app: AppOptions) => CompiledRouter} RouterStyleFn */ -/** @typedef {v.infer & { compiled?: CompiledRouter }} BuildRouterSchema */ - const handlerRouterSchema = v.object({ name: v.string(), - base: v.string().default("/"), + base: v.optional(v.string().default("/")), root: v.optional(v.string()), mode: v.literal("handler"), @@ -110,34 +45,26 @@ const handlerRouterSchema = v.object({ worker: v.optional(v.boolean()), handler: v.string(), middleware: v.optional(v.string()), - /** @type {v.ZodType} */ - style: v.custom((value) => value !== null), - compile: v.object({ - outDir: v.string().optional(), - target: v.literal("server"), - plugins: v.optional(v.custom((value) => typeof value === "function")), - }), + /** @type {v.ZodOptionalType>} */ + routes: v.optional(v.custom((value) => value !== null)), + outDir: v.string().optional(), + target: v.literal("server"), + plugins: v.optional(v.custom((value) => typeof value === "function")), }); -/** @typedef {v.infer & { compiled?: CompiledRouter }} HandlerRouterSchema */ - const spaRouterSchema = v.object({ name: v.string(), - base: v.string().default("/"), + base: v.optional(v.string().default("/")), root: v.optional(v.string()), mode: v.literal("spa"), - /** @type {v.ZodType} */ - style: v.custom((value) => value !== null), + /** @type {v.ZodOptionalType>} */ + routes: v.optional(v.custom((value) => value !== null)), handler: v.string(), - compile: v.object({ - outDir: v.string().optional(), - target: v.literal("browser"), - plugins: v.optional(v.custom((value) => typeof value === "function")), - }), + outDir: v.string().optional(), + target: v.literal("browser"), + plugins: v.optional(v.custom((value) => typeof value === "function")), }); -/** @typedef {v.infer & { compiled?: CompiledRouter }} SPARouterSchema */ - const routerSchema = { static: staticRouterSchema, build: buildRouterSchema, @@ -145,17 +72,116 @@ const routerSchema = { handler: handlerRouterSchema, }; -/** @typedef {(HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema) & { fileRouter?: any }} RouterSchema */ -/** @typedef {{ routers?: RouterSchema[]; name?: string; server?: import('nitropack').NitroConfig; root?: string }} AppOptions */ -/** @typedef {{ config: { name: string; server: import('nitropack').NitroConfig; routers: RouterSchema[]; root: string; }; getRouter: (name: string) => RouterSchema & { devServer: import('vite').ViteDevServer } }} App */ +/** @typedef {v.infer & { outDir: string; base: string; order: number; root: string; internals: Internals }} BuildRouterSchema */ +/** @typedef {v.infer & { outDir: string; base: string; order: number; internals?: Internals }} StaticRouterSchema */ +/** @typedef {v.infer & { outDir: string; base: string; order: number; root: string; internals: Internals }} HandlerRouterSchema */ +/** @typedef {v.infer & { outDir: string; base: string; order: number; root: string; internals: Internals }} SPARouterSchema */ +/** @typedef {(HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema)} RouterSchema */ +/** @typedef {(v.infer | v.infer | v.infer | v.infer)} RouterSchemaInput */ +/** @typedef {{ routers?: RouterSchemaInput[]; name?: string; server?: import('nitropack').NitroConfig; root?: string }} AppOptions */ +/** @typedef {{ config: { name: string; server: import('nitropack').NitroConfig; routers: RouterSchema[]; root: string; }; getRouter: (name: string) => RouterSchema; dev(): Promise; build(): Promise }} App */ + +/** + * + * @param {RouterSchemaInput} router + * @param {AppOptions} appConfig + * @param {number} order + * @returns {RouterSchema} + */ +function resolveConfig(router, appConfig, order) { + const appRoot = appConfig.root ?? process.cwd(); + const root = router.root ?? appRoot; + switch (router.mode) { + case "static": + return { + ...router, + base: router.base ?? "/", + root, + order, + outDir: join(appRoot, ".nitro", "build", router.name), + }; + case "build": + /** @type {BuildRouterSchema} */ + const buildRouter = { + ...router, + root, + base: router.base ?? "/", + handler: resolve.relative(router.handler, root), + target: router.target ?? "browser", + outDir: router.outDir + ? join(appRoot, router.outDir) + : join(appRoot, ".nitro", "build", router.name), + internals: {}, + order, + }; + + buildRouter.internals = { + routes: router.routes + ? router.routes(buildRouter, appConfig) + : undefined, + devServer: undefined, + }; + + return buildRouter; + case "handler": + /** @type {HandlerRouterSchema} */ + const handlerRouter = { + ...router, + root, + base: router.base ?? "/", + internals: {}, + handler: resolve.relative(router.handler, root), + middleware: resolve.relative(router.middleware, root), + target: router.target ?? "server", + outDir: router.outDir + ? join(appRoot, router.outDir) + : join(appRoot, ".nitro", "build", router.name), + order, + }; + + handlerRouter.internals = { + routes: router.routes + ? router.routes(handlerRouter, appConfig) + : undefined, + devServer: undefined, + }; + return handlerRouter; + case "spa": + /** @type {SPARouterSchema} */ + const spaRouter = { + ...router, + base: router.base ?? "/", + root, + internals: {}, + handler: resolve.relative(router.handler, root), + target: router.target ?? "browser", + outDir: router.outDir + ? join(appRoot, router.outDir) + : join(appRoot, ".nitro", "build", router.name), + order, + }; + + spaRouter.internals = { + routes: router.routes ? router.routes(spaRouter, appConfig) : undefined, + devServer: undefined, + }; + + return spaRouter; + } +} /** * * @param {AppOptions} param0 * @returns {App} */ -export function createApp({ routers = [], name = "app", server = {} }) { - routers = routers.map((router) => { +export function createApp({ + routers = [], + name = "app", + server = {}, + root = process.cwd(), +}) { + const parsedRouters = routers.map((router) => { invariant( router.mode in routerSchema, `Invalid router mode ${router.mode}`, @@ -172,26 +198,40 @@ export function createApp({ routers = [], name = "app", server = {} }) { return result.data; }); + const resolvedRouters = routers.map((router, index) => { + return { + ...resolveConfig( + router, + { + name: name ?? "vinxi", + // @ts-ignore + routers: parsedRouters, + server, + root, + }, + index, + ), + }; + }); + const config = { name: name ?? "vinxi", - routers, + routers: resolvedRouters, server, - root: process.cwd(), + root, }; - config.routers = routers.map((router, index) => { - return { - ...resolveConfig(router, config), - index, - }; - }); - + /** @type {App} */ const app = { config, - getRouter(name) { - return config.routers.find((router) => router.name === name); + getRouter(/** @type {string} */ name) { + const router = config.routers.find((router) => router.name === name); + if (!router) { + throw new InvariantError(`Router ${name} not found`); + } + return router; }, - async serve() { + async dev() { if (isMainThread) { const { createDevServer } = await import("./dev-server.js"); await createDevServer(app, { @@ -202,12 +242,12 @@ export function createApp({ routers = [], name = "app", server = {} }) { }, async build() { const { createBuild } = await import("./build.js"); - await createBuild(app); + await createBuild(app, {}); }, }; if (process.argv.includes("--dev")) { - app.serve(); + app.dev(); } else if (process.argv.includes("--build")) { app.build(); } diff --git a/packages/vinxi/lib/build.js b/packages/vinxi/lib/build.js index ecc9146b..293079d9 100644 --- a/packages/vinxi/lib/build.js +++ b/packages/vinxi/lib/build.js @@ -14,6 +14,7 @@ import { relative } from "pathe"; import { writeFileSync } from "node:fs"; import { createIncomingMessage, createServerResponse } from "./http-stream.js"; +import invariant from "./invariant.js"; import { consola, withLogger } from "./logger.js"; import { createSPAManifest } from "./manifest/spa-manifest.js"; import { config } from "./plugins/config.js"; @@ -22,12 +23,14 @@ import { routes } from "./plugins/routes.js"; import { treeShake } from "./plugins/tree-shake.js"; import { virtual } from "./plugins/virtual.js"; +/** @typedef {{}} BuildConfig */ + const require = createRequire(import.meta.url); /** * * @param {import('./app.js').App} app - * @param {*} buildConfig + * @param {BuildConfig} buildConfig */ export async function createBuild(app, buildConfig) { const { existsSync, promises: fsPromises, readFileSync } = await import("fs"); @@ -35,21 +38,21 @@ export async function createBuild(app, buildConfig) { const { fileURLToPath } = await import("url"); for (const router of app.config.routers) { if ("compile" in router) { - if (existsSync(router.compile.outDir)) { - await fsPromises.rm(router.compile.outDir, { recursive: true }); + if (existsSync(router.outDir)) { + await fsPromises.rm(router.outDir, { recursive: true }); } } } - for (const router of app.config.routers.filter( - (router) => router.mode != "static", - )) { - // if (router.mode in routers) { - await withLogger({ router, requestId: "build" }, async () => { - await createRouterBuild(app, router); + for (const router of app.config.routers) { + if (router.mode !== "static") { + // if (router.mode in routers) { + await withLogger({ router, requestId: "build" }, async () => { + await createRouterBuild(app, router); - // await routers[router.mode].build.apply(this, [router]) - }); + // await routers[router.mode].build.apply(this, [router]) + }); + } // } } @@ -82,7 +85,7 @@ export async function createBuild(app, buildConfig) { // ...app.config.routers // .map((router) => // router.mode === "handler" - // ? router.compile.server?.middleware ?? [] + // ? router.server?.middleware ?? [] // : [], // ) // .flat(), @@ -95,13 +98,13 @@ export async function createBuild(app, buildConfig) { if (router.mode === "handler") { const bundlerManifest = JSON.parse( readFileSync( - join(router.compile.outDir, router.base, "manifest.json"), + join(router.outDir, router.base, "manifest.json"), "utf-8", ), ); const handler = join( - router.compile.outDir, + router.outDir, router.base, bundlerManifest[ "virtual:#vinxi/handler" in bundlerManifest @@ -138,35 +141,28 @@ export async function createBuild(app, buildConfig) { ].filter(Boolean), publicAssets: [ ...app.config.routers - .filter((router) => router.mode === "static") - .map((/** @type {import("./app.js").StaticRouterSchema} */ router) => ({ - dir: router.dir, - baseURL: router.base, - passthrough: true, - })), - ...app.config.routers - .filter((router) => router.mode === "build") - .map((/** @type {import("./app.js").BuildRouterSchema} */ router) => ({ - dir: join(router.compile.outDir, router.base), - baseURL: router.base, - passthrough: true, - })), - ...app.config.routers - .filter((router) => router.mode === "spa") - .map((/** @type {import("./app.js").SPARouterSchema} */ router) => ({ - dir: join(router.compile.outDir, router.base), - baseURL: router.base, - passthrough: true, - })), - ...app.config.routers - .filter((router) => router.mode === "handler") - .map( - (/** @type {import("./app.js").HandlerRouterSchema} */ router) => ({ - dir: join(router.compile.outDir, router.base, "assets"), - baseURL: join(router.base, "assets"), - passthrough: true, - }), - ), + .map((router) => { + if (router.mode === "static") { + return { + dir: router.dir, + baseURL: router.base, + passthrough: true, + }; + } else if (router.mode === "handler") { + return { + dir: join(router.outDir, router.base, "assets"), + baseURL: join(router.base, "assets"), + passthrough: true, + }; + } else if (router.mode === "spa" || router.mode === "build") { + return { + dir: join(router.outDir, router.base), + baseURL: router.base, + passthrough: true, + }; + } + }) + .filter(Boolean), ...(app.config.server.publicAssets ?? []), ], scanDirs: [], @@ -189,34 +185,28 @@ export async function createBuild(app, buildConfig) { }; return ` const appConfig = ${JSON.stringify(config, (k, v) => { - if (k === "compiled") { + if (["routes", "internals", "plugins"].includes(k)) { return undefined; - } else if (k === "compile") { - return { - target: v.target, - outDir: v.outDir, - }; } return v; })} const buildManifest = ${JSON.stringify( Object.fromEntries( + // @ts-ignore app.config.routers - .filter((router) => router.mode !== "static") - .map( - ( - /** @type {Exclude} */ router, - ) => { + .map((router) => { + if (router.mode !== "static") { const bundlerManifest = JSON.parse( readFileSync( - join(router.compile.outDir, router.base, "manifest.json"), + join(router.outDir, router.base, "manifest.json"), "utf-8", ), ); return [router.name, bundlerManifest]; - }, - ), + } + }) + .filter(Boolean), ), )} @@ -240,12 +230,10 @@ export async function createBuild(app, buildConfig) { (router) => router.mode === "spa", ); - if (!("compile" in router)) { - return; - } + invariant(router?.mode === "spa", "No SPA router found"); const indexHtml = readFileSync( - join(router.compile.outDir, router.base, "index.html"), + join(router.outDir, router.base, "index.html"), "utf-8", ); return ` @@ -260,7 +248,7 @@ export async function createBuild(app, buildConfig) { // app.config.routers // .map((router) => // router.mode === "handler" - // ? Object.entries(router.compile.server?.virtual ?? {}).map( + // ? Object.entries(router.server?.virtual ?? {}).map( // ([k, v]) => [k, typeof v === "function" ? () => v(app) : v], // ) // : [], @@ -300,6 +288,11 @@ async function createViteBuild(config) { return await vite.build({ ...config, configFile: false }); } +/** + * + * @param {import("./app.js").App} app + * @param {Exclude} router + */ async function createRouterBuild(app, router) { let buildRouter = router; if (router.mode === "spa" && !router.handler.endsWith(".html")) { @@ -313,13 +306,11 @@ async function createRouterBuild(app, router) { external: ["h3"], }, target: "esnext", - outDir: join(router.compile.outDir + "_entry"), + outDir: join(router.outDir + "_entry"), }, }); - const render = await import( - join(router.compile.outDir + "_entry", "handler.js") - ); + const render = await import(join(router.outDir + "_entry", "handler.js")); const smallApp = createApp(); smallApp.use(render.default); @@ -356,8 +347,8 @@ async function createRouterBuild(app, router) { app, plugins: [ routerModePlugin[buildRouter.mode]?.() ?? [], - buildTargetPlugin[buildRouter.compile.target]?.() ?? [], - ...((await buildRouter.compile.plugins?.()) ?? []), + buildTargetPlugin[buildRouter.target]?.() ?? [], + ...((await buildRouter.plugins?.()) ?? []), ], }); @@ -374,10 +365,13 @@ const buildTargetPlugin = { }; const spaManifest = () => { + /** @type {import('./vite-dev.d.ts').ViteConfig} */ let config; + /** @type {import('./vite-dev.d.ts').ConfigEnv} */ let env; - return { + /** @type {import('./vite-dev.d.ts').Plugin} */ + const plugin = { name: "spa-manifest", enforce: "post", config(c, e) { @@ -408,6 +402,8 @@ const spaManifest = () => { }); }, }; + + return plugin; }; const routerModePlugin = { @@ -416,6 +412,10 @@ const routerModePlugin = { virtual( { "#vinxi/handler": ({ config }) => { + invariant( + config.router.mode === "build", + "#vinxi/handler is only supported in build mode", + ); return `import * as mod from "${join( config.router.root, config.router.handler, @@ -447,6 +447,11 @@ const routerModePlugin = { virtual( { "#vinxi/handler": ({ config }) => { + invariant( + config.router.mode === "handler", + "#vinxi/handler is only supported in handler mode", + ); + if (config.router.middleware) { return ` import middleware from "${join(config.router.root, config.router.middleware)}"; @@ -503,15 +508,25 @@ const routerModePlugin = { ], }; +/** + * + * @param {{ src: string; pick: string[] }} route + * @returns + */ function toRouteId(route) { return `${route.src}?${route.pick.map((p) => `pick=${p}`).join("&")}`; } +/** + * + * @param {Exclude} router + * @returns + */ export async function getEntries(router) { return [ router.handler.endsWith(".html") ? router.handler : "#vinxi/handler", ...( - (await router.compiled?.getRoutes())?.map((r) => + (await router.internals.routes?.getRoutes())?.map((r) => Object.entries(r) .filter(([r, v]) => v && r.startsWith("$") && !r.startsWith("$$")) .map(([, v]) => toRouteId(v)), @@ -528,6 +543,10 @@ function handerBuild() { name: "react-rsc:handler", async config(inlineConfig, env) { if (env.command === "build") { + invariant( + inlineConfig.router && inlineConfig.router.mode !== "static", + "Invalid router", + ); const { builtinModules } = await import("module"); const { join } = await import("path"); const input = await getEntries(inlineConfig.router); @@ -545,10 +564,7 @@ function handerBuild() { manifest: true, target: "node18", ssrEmitAssets: true, - outDir: join( - inlineConfig.router.compile.outDir, - inlineConfig.router.base, - ), + outDir: join(inlineConfig.router.outDir, inlineConfig.router.base), emptyOutDir: false, }, base: inlineConfig.router.base, @@ -567,6 +583,10 @@ function browserBuild() { name: "build:browser", async config(inlineConfig, env) { if (env.command === "build") { + invariant( + inlineConfig.router && inlineConfig.router.mode !== "static", + "Invalid router", + ); const { join } = await import("path"); return { build: { @@ -575,10 +595,7 @@ function browserBuild() { treeshake: true, }, manifest: true, - outDir: join( - inlineConfig.router.compile.outDir, - inlineConfig.router.base, - ), + outDir: join(inlineConfig.router.outDir, inlineConfig.router.base), target: "esnext", emptyOutDir: false, }, diff --git a/packages/vinxi/lib/dev-server.js b/packages/vinxi/lib/dev-server.js index 8babd1ec..c9d97528 100644 --- a/packages/vinxi/lib/dev-server.js +++ b/packages/vinxi/lib/dev-server.js @@ -1,5 +1,11 @@ import getPort from "get-port"; -import { H3Event, createApp, defineEventHandler, fromNodeMiddleware } from "h3"; +import { + H3Event, + createApp, + defineEventHandler, + fromNodeMiddleware, + getRequestURL, +} from "h3"; import { createNitro } from "nitropack"; import { join } from "node:path"; @@ -8,6 +14,7 @@ import { isMainThread } from "node:worker_threads"; import { AppWorkerClient } from "./app-worker-client.js"; import { createServerResponse } from "./http-stream.js"; +import invariant from "./invariant.js"; import { consola } from "./logger.js"; import { createDevServer as createDevNitroServer } from "./nitro-dev.js"; import { config } from "./plugins/config.js"; @@ -17,6 +24,9 @@ import { routes } from "./plugins/routes.js"; import { treeShake } from "./plugins/tree-shake.js"; import { virtual } from "./plugins/virtual.js"; +/** @typedef {{ port?: number; dev?: boolean; ws?: { port?: number } }} ServeConfigInput */ +/** @typedef {{ port: number; dev: boolean; ws: { port: number } }} ServeConfig */ + /** * * @returns {import('./vite-dev.d.ts').Plugin} @@ -38,7 +48,7 @@ function devEntries() { /** * - * @param {import('vite').InlineConfig & { router: any; app: any }} config + * @param {import('vite').InlineConfig & { router: import("./app.js").RouterSchema; app: import("./app.js").App }} config * @returns */ async function createViteServer(config) { @@ -47,46 +57,52 @@ async function createViteServer(config) { } const targetDevPlugin = { - browser: () => [css()], - node: () => [], + browser: (/** @type {import("./app.js").RouterSchema} */ router) => [css()], + server: (/** @type {import("./app.js").RouterSchema} */ router) => [], }; +/** + * + * @param {import('vite').FSWatcher} watcher + * @param {import("./app.js").RouterSchema} router + */ function setupWatcher(watcher, router) { - watcher.on("unlink", async (path) => { - // path = slash(path); - // if (!isTarget(path, this.options)) return; - await router.compiled.removeRoute(path); - }); - watcher.on("add", async (path) => { - // path = slash(path); - // if (!isTarget(path, this.options)) return; - // const page = this.options.dirs.find((i) => - // path.startsWith(slash(resolve(this.root, i.dir))), - // ); - await router.compiled.addRoute(path); - }); + if (router.internals?.routes) { + watcher.on("unlink", async (path) => { + if (router.internals?.routes) { + await router.internals?.routes.removeRoute(path); + } + }); - watcher.on("change", async (path) => { - // path = slash(path); - // if (!isTarget(path, this.options)) return; - // const page = this._pageRouteMap.get(path); - // if (page) await this.options.resolver.hmr?.changed?.(this, path); - await router.compiled.updateRoute(path); - }); + watcher.on("add", async (path) => { + if (router.internals?.routes) { + await router.internals?.routes.addRoute(path); + } + }); + + watcher.on("change", async (path) => { + if (router.internals?.routes) { + await router.internals?.routes.updateRoute(path); + } + }); + } } const fileSystemWatcher = () => { + /** @type {import('./vite-dev.d.ts').ViteConfig} */ let config; - return { + + /** @type {import('./vite-dev.d.ts').Plugin} */ + const plugin = { name: "fs-watcher", apply: "serve", configResolved(resolvedConfig) { config = resolvedConfig; }, configureServer(server) { - if (config.router.fileRouter) { + if (config.router.internals?.routes) { setupWatcher(server.watcher, config.router); - config.router.compiled.update = () => { + config.router.internals.routes.addEventListener("reload", () => { const { moduleGraph } = server; const mods = moduleGraph.getModulesByFile( fileURLToPath(new URL("./routes.js", import.meta.url)), @@ -101,14 +117,15 @@ const fileSystemWatcher = () => { server.ws.send({ type: "full-reload", }); - }; + }); } }, }; + return plugin; }; const routerModeDevPlugin = { - spa: (router) => [ + spa: (/** @type {import("./app.js").SPARouterSchema} */ router) => [ routes(), devEntries(), manifest(), @@ -125,11 +142,15 @@ const routerModeDevPlugin = { }, }), treeShake(), - router.fileRouter ? fileSystemWatcher() : null, + router.internals.routes ? fileSystemWatcher() : null, ], - handler: (router) => [ + handler: (/** @type {import("./app.js").HandlerRouterSchema} */ router) => [ virtual({ "#vinxi/handler": ({ config }) => { + invariant( + config.router.mode === "handler", + "#vinxi/handler is only supported in handler mode", + ); if (config.router.middleware) { return ` import middleware from "${join(config.router.root, config.router.middleware)}"; @@ -159,12 +180,16 @@ const routerModeDevPlugin = { }, }), treeShake(), - router.fileRouter ? fileSystemWatcher() : null, + router.internals.routes ? fileSystemWatcher() : null, ], - build: (router) => [ + build: (/** @type {import("./app.js").BuildRouterSchema} */ router) => [ virtual( { "#vinxi/handler": ({ config }) => { + invariant( + config.router.mode === "build", + "#vinxi/handler is only supported in build mode", + ); return `import * as mod from "${join( config.router.root, config.router.handler, @@ -190,46 +215,61 @@ const routerModeDevPlugin = { }, }), treeShake(), - router.fileRouter ? fileSystemWatcher() : null, + router.internals.routes ? fileSystemWatcher() : null, ], }; +/** + * + * @param {import('./app.js').App} app + * @param {import('./app.js').RouterSchema} router + * @param {ServeConfig} serveConfig + * @returns + */ async function createViteHandler(app, router, serveConfig) { - if (router.worker && isMainThread) { - if (!router.appWorker) { - router.appWorker = new AppWorkerClient( + if (router.mode === "handler" && router.worker && isMainThread) { + if (!router.internals.appWorker) { + router.internals.appWorker = new AppWorkerClient( new URL("./app-worker.js", import.meta.url), ); } return defineEventHandler(async (event) => { - await router.appWorker.init(() => {}); - await router.appWorker.handle(event); + invariant( + router.internals.appWorker, + "Router App Worker not initialized", + ); + await router.internals.appWorker.init(() => {}); + await router.internals.appWorker.handle(event); }); } + invariant( + router.mode !== "static", + "Vite does not need to run for static mode", + ); + const viteDevServer = await createViteServer({ configFile: false, base: router.base, plugins: [ - ...((targetDevPlugin[router.compile.target]?.(router) ?? []).filter( - Boolean, - ) ?? []), - ...((routerModeDevPlugin[router.mode]?.(router) ?? []).filter(Boolean) ?? + ...((targetDevPlugin[router.target]?.(router) ?? []).filter(Boolean) ?? []), - ...(((await router.compile?.plugins?.(router)) ?? []).filter(Boolean) || + // @ts-expect-error + ...((routerModeDevPlugin[router.mode]?.(router) ?? []).filter(Boolean) ?? []), + ...(((await router.plugins?.(router)) ?? []).filter(Boolean) || []), ], router, app, server: { middlewareMode: true, hmr: { - port: await getPort({ port: serveConfig.ws.port + router.index }), + port: await getPort({ port: serveConfig.ws.port + router.order }), }, }, }); - router.devServer = viteDevServer; + router.internals.devServer = viteDevServer; if (router.mode === "handler") { return defineEventHandler(async (event) => { @@ -283,7 +323,7 @@ async function createViteHandler(app, router, serveConfig) { }); const transformedHtml = await viteDevServer.transformIndexHtml( - event.node.req.url, + getRequestURL(event).href, text, ); @@ -295,6 +335,13 @@ async function createViteHandler(app, router, serveConfig) { } } +/** + * + * @param {import('./app.js').App} app + * @param {import('./app.js').RouterSchema} router + * @param {ServeConfig} serveConfig + * @returns + */ async function createDevRouterHandler(app, router, serveConfig) { return { route: router.base, @@ -305,18 +352,18 @@ async function createDevRouterHandler(app, router, serveConfig) { /** * * @param {import('./app.js').App} app - * @param {{ port?: number; dev?: boolean; ws?: { port?: number } }} param1 + * @param {ServeConfigInput} param1 * @returns */ export async function createDevServer( app, - { port = 3000, dev = false, ws: { port: wsPort = null } = {} }, + { port = 3000, dev = false, ws: { port: wsPort = undefined } = {} }, ) { const serveConfig = { port, dev, ws: { - port: wsPort, + port: wsPort ?? 8989, }, }; @@ -328,21 +375,22 @@ export async function createDevServer( preset: "nitro-dev", publicAssets: [ ...app.config.routers - .filter((router) => router.mode === "static") - .map( - (/** @type {import("./app.js").StaticRouterSchema} */ router) => ({ - dir: router.dir, - baseURL: router.base, - passthrough: true, - }), - ), + .map((router) => { + if (router.mode === "static") { + return { + dir: router.dir, + baseURL: router.base, + fallthrough: true, + }; + } + }) + .filter(Boolean), ...(app.config.server.publicAssets ?? []), ], devHandlers: [ ...(await Promise.all( app.config.routers .filter((router) => router.mode != "static") - .sort((a, b) => b.base.length - a.base.length) .map((router) => createDevRouterHandler(app, router, serveConfig)), )), @@ -358,14 +406,15 @@ export async function createDevServer( await devApp.listen(port, {}); for (const router of app.config.routers) { - if ("compiled" in router && router.compiled) { - const routes = await router.compiled.getRoutes(); + if (router.internals && router.internals.routes) { + const routes = await router.internals.routes.getRoutes(); for (const route of routes) { console.log(route.path); } } } + // @ts-ignore globalThis.app = app; const plugins = [ diff --git a/packages/vinxi/lib/file-system-router.js b/packages/vinxi/lib/file-system-router.js index 970b8a2f..4cab9acc 100644 --- a/packages/vinxi/lib/file-system-router.js +++ b/packages/vinxi/lib/file-system-router.js @@ -10,16 +10,33 @@ import { pathToRegexp } from "path-to-regexp"; export { pathToRegexp }; +/** + * + * @param {string} path + * @returns {string[]} + */ export const glob = (path) => fg.sync(path, { absolute: true }); +/** @typedef {{ dir: string; extensions: string[] }} FileSystemRouterConfig */ +/** @typedef {{ path: string } & any} Route */ + +/** + * + * @param {string} src + * @param {FileSystemRouterConfig} config + * @returns + */ export function cleanPath(src, config) { return src .slice(config.dir.length) - .replace(new RegExp(`\.(${config.extensions.join("|")})$`), ""); + .replace(new RegExp(`\.(${(config.extensions ?? []).join("|")})$`), ""); } -/** @typedef {{ dir: string; extensions?: string[] }} FileSystemRouterConfig */ - +/** + * + * @param {string} src + * @returns + */ export function analyzeModule(src) { return parse( esbuild.transformSync(fs.readFileSync(src, "utf-8"), { @@ -31,10 +48,17 @@ export function analyzeModule(src) { ); } -export class BaseFileSystemRouter { +export class BaseFileSystemRouter extends EventTarget { + /** @type {any[]} */ routes; + + /** @type {import("./app").RouterSchema} */ routerConfig; + + /** @type {import("./app").AppOptions} */ appConfig; + + /** @type {FileSystemRouterConfig} */ config; /** @@ -44,6 +68,7 @@ export class BaseFileSystemRouter { * @param {import("./app").AppOptions} app */ constructor(config, router, app) { + super(); this.routes = []; this.config = config; this.routerConfig = router; @@ -78,7 +103,7 @@ export class BaseFileSystemRouter { * @returns {boolean} */ isRoute(src) { - return micromatch(src, this.glob()); + return Boolean(micromatch(src, this.glob())?.length); } /** @@ -93,7 +118,7 @@ export class BaseFileSystemRouter { /** * * @param {*} src - * @returns {object} + * @returns {Route | null} */ toRoute(src) { let path = this.toPath(src); @@ -123,27 +148,51 @@ export class BaseFileSystemRouter { */ update = undefined; + /** + * + * @param {Route} route + */ _addRoute(route) { const existing = this.routes.find((r) => r.path === route.path); if (!existing) this.routes.push(route); } + /** + * + * @param {string} src + */ addRoute(src) { if (this.isRoute(src)) { const route = this.toRoute(src); if (route) { this._addRoute(route); - this.update?.(); + this.dispatchEvent( + new Event("reload", { + // @ts-ignore + detail: { + route, + }, + }), + ); } } } + /** + * + * @param {string} src + */ updateRoute(src) { if (this.isRoute(src)) { // this.update?.(); } } + /** + * + * @param {string} src + * @returns + */ removeRoute(src) { if (this.isRoute(src)) { const path = this.toPath(src); @@ -151,10 +200,11 @@ export class BaseFileSystemRouter { return; } this.routes = this.routes.filter((r) => r.path !== path); - this.update?.(); + this.dispatchEvent(new Event("reload", {})); } } + /** @type {Promise | undefined} */ buildRoutesPromise = undefined; async getRoutes() { diff --git a/packages/vinxi/lib/load-app.js b/packages/vinxi/lib/load-app.js index 8e14bdda..4beed716 100644 --- a/packages/vinxi/lib/load-app.js +++ b/packages/vinxi/lib/load-app.js @@ -53,10 +53,8 @@ export async function loadApp(configFile = undefined) { name: "client", mode: "spa", handler: "./index.html", - build: { - target: "browser", - plugins: () => config.plugins ?? [], - }, + target: "browser", + plugins: () => config.plugins ?? [], }, ], }); diff --git a/packages/vinxi/lib/manifest/dev-server-manifest.js b/packages/vinxi/lib/manifest/dev-server-manifest.js index 5bfeec7e..311aa5e2 100644 --- a/packages/vinxi/lib/manifest/dev-server-manifest.js +++ b/packages/vinxi/lib/manifest/dev-server-manifest.js @@ -19,7 +19,7 @@ export function createDevManifest(app) { invariant(router.mode != "static", "No manifest for static router"); - const viteServer = router.devServer; + const viteServer = router.internals.devServer; return { json() { return {}; @@ -42,7 +42,7 @@ export function createDevManifest(app) { ); let relativePath = relative(app.config.root, chunk); - if (router.compile.target === "browser") { + if (router.target === "browser") { return { output: { path: join(router.base, "@fs", absolutePath), @@ -76,9 +76,11 @@ export function createDevManifest(app) { let isHandler = router.handler === relativePath; async function getVitePluginAssets() { - const plugins = router.devServer.config.plugins.filter( - (plugin) => "transformIndexHtml" in plugin, - ); + const plugins = router.internals?.devServer + ? router.internals.devServer.config.plugins.filter( + (plugin) => "transformIndexHtml" in plugin, + ) + : []; let pluginAssets = []; for (let plugin of plugins) { // @ts-ignore @@ -107,23 +109,27 @@ export function createDevManifest(app) { }); } - if (router.compile.target === "browser") { + if (router.target === "browser") { return { async assets() { return [ - ...Object.entries( - await findStylesInModuleGraph(viteServer, [ - absolutePath, - ]), - ).map(([key, value]) => ({ - tag: "style", - attrs: { - type: "text/css", - key, - "data-vite-dev-id": key, - }, - children: value, - })), + ...(viteServer + ? Object.entries( + await findStylesInModuleGraph( + viteServer, + [absolutePath], + false, + ), + ).map(([key, value]) => ({ + tag: "style", + attrs: { + type: "text/css", + key, + "data-vite-dev-id": key, + }, + children: value, + })) + : []), ...(isHandler ? [ ...(await getVitePluginAssets()), @@ -147,21 +153,23 @@ export function createDevManifest(app) { return { async assets() { return [ - ...Object.entries( - await findStylesInModuleGraph( - viteServer, - [input], - true, - ), - ).map(([key, value]) => ({ - tag: "style", - attrs: { - type: "text/css", - key, - "data-vite-dev-id": key, - }, - children: value, - })), + ...(viteServer + ? Object.entries( + await findStylesInModuleGraph( + viteServer, + [input], + true, + ), + ).map(([key, value]) => ({ + tag: "style", + attrs: { + type: "text/css", + key, + "data-vite-dev-id": key, + }, + children: value, + })) + : []), ]; }, output: { diff --git a/packages/vinxi/lib/manifest/prod-server-manifest.js b/packages/vinxi/lib/manifest/prod-server-manifest.js index a27e9672..89ac367e 100644 --- a/packages/vinxi/lib/manifest/prod-server-manifest.js +++ b/packages/vinxi/lib/manifest/prod-server-manifest.js @@ -3,6 +3,13 @@ import { join, relative } from "pathe"; import invariant from "../invariant.js"; import findAssetsInViteManifest from "./vite-manifest.js"; +/** @typedef {import("../app.js").App & { config: { buildManifest: { [key:string]: any } }}} ProdApp */ + +/** + * + * @param {ProdApp} app + * @returns + */ export function createProdManifest(app) { const manifest = new Proxy( {}, @@ -12,12 +19,18 @@ export function createProdManifest(app) { const router = app.getRouter(routerName); const bundlerManifest = app.config.buildManifest[routerName]; + invariant( + router.mode !== "static", + "manifest not available for static router", + ); return { handler: router.handler, async assets() { + /** @type {{ [key: string]: string[] }} */ let assets = {}; assets[router.handler] = await this.inputs[router.handler].assets(); - for (const route of (await router.compiled?.getRoutes()) ?? []) { + for (const route of (await router.internals.routes?.getRoutes()) ?? + []) { assets[route.filePath] = await this.inputs[ route.filePath ].assets(); @@ -25,6 +38,7 @@ export function createProdManifest(app) { return assets; }, async json() { + /** @type {{ [key: string]: { output: string; assets: string[]} }} */ let json = {}; for (const input of Object.keys(this.inputs)) { json[input] = { @@ -41,11 +55,7 @@ export function createProdManifest(app) { invariant(typeof chunk === "string", "Chunk expected"); return { output: { - path: join( - router.compile.outDir, - router.base, - chunk + ".js", - ), + path: join(router.outDir, router.base, chunk + ".js"), }, }; }, @@ -69,7 +79,7 @@ export function createProdManifest(app) { get(target, input) { invariant(typeof input === "string", "Input expected"); const id = input; - if (router.compile.target === "server") { + if (router.target === "server") { const id = input === router.handler ? "virtual:#vinxi/handler" : input; return { @@ -88,13 +98,13 @@ export function createProdManifest(app) { }, output: { path: join( - router.compile.outDir, + router.outDir, router.base, bundlerManifest[id].file, ), }, }; - } else if (router.compile.target === "browser") { + } else if (router.target === "browser") { const id = input === router.handler && !input.endsWith(".html") ? "virtual:#vinxi/handler" diff --git a/packages/vinxi/lib/manifest/spa-manifest.js b/packages/vinxi/lib/manifest/spa-manifest.js index e50df61e..958a63d4 100644 --- a/packages/vinxi/lib/manifest/spa-manifest.js +++ b/packages/vinxi/lib/manifest/spa-manifest.js @@ -12,7 +12,7 @@ async function getEntries(router) { return [ router.handler, ...( - (await router.compiled?.getRoutes()).map((r) => + (await router.internals.routes?.getRoutes()).map((r) => Object.entries(r) .filter(([r, v]) => v && r.startsWith("$") && !r.startsWith("$$")) .map(([, v]) => toRouteId(v)), diff --git a/packages/vinxi/lib/manifest/vite-manifest.js b/packages/vinxi/lib/manifest/vite-manifest.js index 4c63e300..f163d2df 100644 --- a/packages/vinxi/lib/manifest/vite-manifest.js +++ b/packages/vinxi/lib/manifest/vite-manifest.js @@ -3,33 +3,36 @@ /** * Traverses the module graph and collects assets for a given chunk * - * @param manifest Client manifest - * @param id Chunk id - * @param assetMap Cache of assets + * @param {any} manifest Client manifest + * @param {string} id Chunk id + * @param {Map} assetMap Cache of assets * @returns Array of asset URLs */ const findAssetsInViteManifest = (manifest, id, assetMap = new Map()) => { - function traverse(id) { - const cached = assetMap.get(id); - if (cached) { - return cached; - } - const chunk = manifest[id]; - if (!chunk) { - return []; - } - const assets = [ - ...(chunk.assets || []), - ...(chunk.css || []), - ...(chunk.imports?.flatMap(traverse) || []), - ]; - const imports = chunk.imports?.flatMap(traverse) || []; - const all = [...assets, ...imports].filter(Boolean); - all.push(chunk.file); - assetMap.set(id, all); - return Array.from(new Set(all)); - } - return traverse(id); + /** + * @param {string} id + */ + function traverse(id) { + const cached = assetMap.get(id); + if (cached) { + return cached; + } + const chunk = manifest[id]; + if (!chunk) { + return []; + } + const assets = [ + ...(chunk.assets || []), + ...(chunk.css || []), + ...(chunk.imports?.flatMap(traverse) || []), + ]; + const imports = chunk.imports?.flatMap(traverse) || []; + const all = [...assets, ...imports].filter(Boolean); + all.push(chunk.file); + assetMap.set(id, all); + return Array.from(new Set(all)); + } + return traverse(id); }; export default findAssetsInViteManifest; diff --git a/packages/vinxi/lib/plugins/config.js b/packages/vinxi/lib/plugins/config.js index 5ba2e858..89b7a97a 100644 --- a/packages/vinxi/lib/plugins/config.js +++ b/packages/vinxi/lib/plugins/config.js @@ -1,12 +1,13 @@ /** * * @param {string} tag - * @param {import('vite').InlineConfig} conf + * @param {Omit} conf * @returns {import('../vite-dev.d.ts').Plugin} */ export function config(tag, conf) { return { name: `vinxi:config:${tag}`, + // @ts-ignore config() { return { ...conf }; }, diff --git a/packages/vinxi/lib/plugins/routes.js b/packages/vinxi/lib/plugins/routes.js index b73ee556..77538755 100644 --- a/packages/vinxi/lib/plugins/routes.js +++ b/packages/vinxi/lib/plugins/routes.js @@ -2,18 +2,37 @@ import { relative } from "node:path"; import { fileURLToPath } from "node:url"; export function routes() { + /** + * @type {Exclude} + */ let router; + /** + * @type {string} + */ let root; + /** + * @type {boolean} + */ let isBuild; return { name: "vinxi:routes", + /** + * @param {any} config + * @param {{ command: string; }} command + */ config(config, command) { isBuild = command.command === "build"; }, + /** + * @param {{ root: any; router: any; }} config + */ configResolved(config) { root = config.root; router = config.router; }, + /** + * @param {{ split: (arg0: string) => [any, any]; }} url + */ async load(url) { const [id, query] = url.split("?"); if ( @@ -24,7 +43,7 @@ export function routes() { ) ) { const js = jsCode(); - const routes = await router.compiled?.getRoutes(); + const routes = await router.internals.routes?.getRoutes(); console.log(routes); let routesCode = JSON.stringify(routes ?? [], (k, v) => { @@ -34,9 +53,12 @@ export function routes() { if (k.startsWith("$$")) { const buildId = `${v.src}?${v.pick - .map((p) => `pick=${p}`) + .map((/** @type {any} */ p) => `pick=${p}`) .join("&")}`; + /** + * @type {{ [key: string]: string }} + */ const refs = {}; for (var pick of v.pick) { refs[pick] = js.addNamedImport(pick, buildId); @@ -49,7 +71,7 @@ export function routes() { }; } else if (k.startsWith("$")) { const buildId = `${v.src}?${v.pick - .map((p) => `pick=${p}`) + .map((/** @type {any} */ p) => `pick=${p}`) .join("&")}`; return { src: isBuild ? relative(root, buildId) : buildId, @@ -57,7 +79,7 @@ export function routes() { ? `_$() => import(/* @vite-ignore */ '${buildId}')$_` : undefined, import: - router.compile.target === "server" + router.target === "server" ? `_$() => import(/* @vite-ignore */ '${buildId}')$_` : `_$(() => { const id = '${relative( root, @@ -84,6 +106,9 @@ function jsCode() { let imports = new Map(); let vars = 0; + /** + * @param {any} p + */ function addImport(p) { let id = imports.get(p); if (!id) { @@ -96,6 +121,10 @@ function jsCode() { return d; } + /** + * @param {string | number} name + * @param {any} p + */ function addNamedImport(name, p) { let id = imports.get(p); if (!id) { @@ -108,7 +137,7 @@ function jsCode() { return d; } - const getNamedExport = (p) => { + const getNamedExport = (/** @type {any} */ p) => { let id = imports.get(p); delete id["default"]; diff --git a/packages/vinxi/lib/plugins/virtual.js b/packages/vinxi/lib/plugins/virtual.js index cf1b1455..b71f07bc 100644 --- a/packages/vinxi/lib/plugins/virtual.js +++ b/packages/vinxi/lib/plugins/virtual.js @@ -4,7 +4,7 @@ const PREFIX = "\0virtual:"; /** * - * @param {{ [key: string] : any }} modules + * @param {{ [key: string] : (ctx: { config: import("../vite-dev.d.ts").ViteConfig }) => (string | Promise) }} modules * @param {string} name * @param {any} cache * @returns {import('../vite-dev.d.ts').Plugin} @@ -18,7 +18,9 @@ export function virtual(modules, name = "", cache = {}) { _modules.set(resolve(id), mod); } + /** @type {import('../vite-dev.d.ts').ViteConfig} */ let config; + /** @type {import('vite').ConfigEnv} */ let env; return { diff --git a/packages/vinxi/lib/resolve.js b/packages/vinxi/lib/resolve.js index 74f28b57..057a319e 100644 --- a/packages/vinxi/lib/resolve.js +++ b/packages/vinxi/lib/resolve.js @@ -1,19 +1,25 @@ import { isAbsolute, join, relative } from "pathe"; -function absoluteAppPath(path, router, appConfig) { - return path - ? isAbsolute(path) - ? path - : join(router.root ?? appConfig.root, path) - : undefined; +/** + * @template {string | undefined} T + * @param {T} path + * @param {string} root + * @returns {T} + */ +function absoluteAppPath(path, root) { + //@ts-ignore + return path ? (isAbsolute(path) ? path : join(root, path)) : path; } -export function relativeAppPath(path, router, appConfig) { - return path - ? relative( - router.root ?? appConfig.root, - absoluteAppPath(path, router, appConfig), - ) - : undefined; + +/** + * @template {string | undefined} T + * @param {T} path + * @param {string} root + * @returns {T} + */ +export function relativeAppPath(path, root) { + //@ts-ignore + return path ? relative(root, absoluteAppPath(path, root)) : path; } export const resolve = { diff --git a/packages/vinxi/lib/vite-dev.d.ts b/packages/vinxi/lib/vite-dev.d.ts index ba2c1144..023eb64e 100644 --- a/packages/vinxi/lib/vite-dev.d.ts +++ b/packages/vinxi/lib/vite-dev.d.ts @@ -3,12 +3,27 @@ // // router: any; // // } // } -import { ConfigEnv, UserConfig, Plugin as VitePlugin } from "vite"; - -export interface Plugin extends VitePlugin { - config?: ( - this: void, - config: UserConfig & { router: any }, - env: ConfigEnv, - ) => void | UserConfig | Promise; +import { + ConfigEnv, + UserConfig, + Plugin as VitePlugin, + ResolvedConfig as _ResolvedConfig, +} from "vite"; + +import { RouterSchema } from "./app"; + +declare module "vite" { + interface UserConfig { + router?: RouterSchema; + } + + interface PluginHookUtils { + router: RouterSchema; + } } + +export type ViteConfig = _ResolvedConfig & { router: RouterSchema }; + +export type Plugin = VitePlugin; + +export { ConfigEnv } from "vite"; diff --git a/packages/vinxi/package.json b/packages/vinxi/package.json index 2f3e6a6f..9f538c9d 100644 --- a/packages/vinxi/package.json +++ b/packages/vinxi/package.json @@ -52,6 +52,7 @@ "@babel/core": "^7.22.11", "@babel/plugin-syntax-jsx": "^7.22.5", "@babel/plugin-syntax-typescript": "^7.22.5", + "@types/micromatch": "^4.0.2", "c12": "^1.4.2", "chokidar": "^3.5.3", "consola": "^3.2.3", diff --git a/packages/vinxi/runtime/server.js b/packages/vinxi/runtime/server.js index a84de5df..60588c09 100644 --- a/packages/vinxi/runtime/server.js +++ b/packages/vinxi/runtime/server.js @@ -1,13 +1,31 @@ +import { H3Event } from "h3"; + export * from "h3"; +/** + * + * @param {H3Event} event + * @param {string} key + * @param {any} value + */ export function setContext(event, key, value) { event.context[key] = value; } -export function getContext(event, key, value) { +/** + * + * @param {H3Event} event + * @param {string} key + */ +export function getContext(event, key) { return event.context[key]; } +/** + * + * @param {{ onRequest?: import("h3")._RequestMiddleware | import("h3")._RequestMiddleware[]; onBeforeResponse?: import("h3")._ResponseMiddleware | import("h3")._ResponseMiddleware[] }} options + * @returns + */ export function defineMiddleware(options) { return options; } diff --git a/packages/vinxi/tsconfig.json b/packages/vinxi/tsconfig.json index 44090d00..55fa6155 100644 --- a/packages/vinxi/tsconfig.json +++ b/packages/vinxi/tsconfig.json @@ -6,6 +6,7 @@ "allowSyntheticDefaultImports": true, "esModuleInterop": true, "allowJs": true, + "strict": true, "checkJs": true, "noEmit": true, "isolatedModules": true diff --git a/packages/vinxi/types.sh b/packages/vinxi/types.sh new file mode 100755 index 00000000..2b5a2965 --- /dev/null +++ b/packages/vinxi/types.sh @@ -0,0 +1,4 @@ +npx dts-buddy +sed -i '' '/declare module '\''vinxi\/runtime\/server'\'' {/a\ +export * from "h3" +' types/index.d.ts \ No newline at end of file diff --git a/packages/vinxi/types/index.d.ts b/packages/vinxi/types/index.d.ts index 0340994d..ef4b57b0 100644 --- a/packages/vinxi/types/index.d.ts +++ b/packages/vinxi/types/index.d.ts @@ -1,11 +1,37 @@ declare module 'vinxi' { import * as v from 'zod'; - export function createApp({ routers, name, server }: AppOptions): App; - export type RouterSchema = (HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema) & { - fileRouter?: any; + export function createApp({ routers, name, server, root, }: AppOptions): App; + export type BuildRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; + }; + export type StaticRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + internals?: Internals; + }; + export type HandlerRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; + }; + export type SPARouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; }; + export type RouterSchema = (HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema); + export type RouterSchemaInput = (v.infer | v.infer | v.infer | v.infer); export type AppOptions = { - routers?: RouterSchema[]; + routers?: RouterSchemaInput[]; name?: string; server?: import('nitropack').NitroConfig; root?: string; @@ -17,217 +43,191 @@ declare module 'vinxi' { routers: RouterSchema[]; root: string; }; - getRouter: (name: string) => RouterSchema & { - devServer: import('vite').ViteDevServer; - }; + getRouter: (name: string) => RouterSchema; + dev(): Promise; + build(): Promise; + }; + export type Internals = { + routes?: CompiledRouter; + devServer?: import('vite').ViteDevServer; + appWorker?: AppWorkerClient; }; - export type RouterModes = "static" | "build" | "spa" | "handler"; - export type StaticRouterSchema = v.infer; export type CompiledRouter = { getRoutes(): Promise; - }; - export type RouterStyleFn = (router: RouterSchema, app: AppOptions) => CompiledRouter; - export type BuildRouterSchema = v.infer & { - compiled?: CompiledRouter; - }; - export type HandlerRouterSchema = v.infer & { - compiled?: CompiledRouter; - }; - export type SPARouterSchema = v.infer & { - compiled?: CompiledRouter; - }; - const staticRouterSchema: v.ZodObject<{ - name: v.ZodString; - base: v.ZodDefault; - mode: v.ZodLiteral<"static">; - dir: v.ZodString; - root: v.ZodOptional; - }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - mode?: "static"; - dir?: string; - root?: string; - }, { - name?: string; - base?: string; - mode?: "static"; - dir?: string; - root?: string; - }>; - + } & EventTarget; + export type RouterStyleFn = (router: RouterSchemaInput, app: AppOptions) => CompiledRouter; const buildRouterSchema: v.ZodObject<{ name: v.ZodString; - base: v.ZodDefault; + base: v.ZodOptional>; root: v.ZodOptional; mode: v.ZodLiteral<"build">; handler: v.ZodString; - style: v.ZodType; + routes: v.ZodOptionalType>; extensions: v.ZodOptional>; - compile: v.ZodObject<{ - outDir: v.ZodOptional; - target: v.ZodLiteral<"browser">; - plugins: v.ZodOptional>; - }, "strip", v.ZodTypeAny, { - outDir?: string; - target?: "browser"; - plugins?: any; - }, { - outDir?: string; - target?: "browser"; - plugins?: any; - }>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"browser">; + plugins: v.ZodOptional>; }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - root?: string; - mode?: "build"; - handler?: string; - style?: RouterStyleFn; - extensions?: string[]; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "build"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + extensions?: string[] | undefined; + outDir?: string | undefined; + plugins?: any; }, { - name?: string; - base?: string; - root?: string; - mode?: "build"; - handler?: string; - style?: RouterStyleFn; - extensions?: string[]; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "build"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + extensions?: string[] | undefined; + outDir?: string | undefined; + plugins?: any; }>; - - + const staticRouterSchema: v.ZodObject<{ + name: v.ZodString; + base: v.ZodOptional>; + mode: v.ZodLiteral<"static">; + dir: v.ZodString; + root: v.ZodOptional; + }, "strip", v.ZodTypeAny, { + name: string; + dir: string; + mode: "static"; + base?: string | undefined; + root?: string | undefined; + }, { + name: string; + dir: string; + mode: "static"; + base?: string | undefined; + root?: string | undefined; + }>; const handlerRouterSchema: v.ZodObject<{ name: v.ZodString; - base: v.ZodDefault; + base: v.ZodOptional>; root: v.ZodOptional; mode: v.ZodLiteral<"handler">; worker: v.ZodOptional; handler: v.ZodString; middleware: v.ZodOptional; - style: v.ZodType; - compile: v.ZodObject<{ - outDir: v.ZodOptional; - target: v.ZodLiteral<"server">; - plugins: v.ZodOptional>; - }, "strip", v.ZodTypeAny, { - outDir?: string; - target?: "server"; - plugins?: any; - }, { - outDir?: string; - target?: "server"; - plugins?: any; - }>; + routes: v.ZodOptionalType>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"server">; + plugins: v.ZodOptional>; }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - root?: string; - mode?: "handler"; - worker?: boolean; - handler?: string; - middleware?: string; - style?: RouterStyleFn; - compile?: { - outDir?: string; - target?: "server"; - plugins?: any; - }; + name: string; + target: "server"; + mode: "handler"; + handler: string; + base?: string | undefined; + root?: string | undefined; + worker?: boolean | undefined; + middleware?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }, { - name?: string; - base?: string; - root?: string; - mode?: "handler"; - worker?: boolean; - handler?: string; - middleware?: string; - style?: RouterStyleFn; - compile?: { - outDir?: string; - target?: "server"; - plugins?: any; - }; + name: string; + target: "server"; + mode: "handler"; + handler: string; + base?: string | undefined; + root?: string | undefined; + worker?: boolean | undefined; + middleware?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }>; - const spaRouterSchema: v.ZodObject<{ name: v.ZodString; - base: v.ZodDefault; + base: v.ZodOptional>; root: v.ZodOptional; mode: v.ZodLiteral<"spa">; - style: v.ZodType; + routes: v.ZodOptionalType>; handler: v.ZodString; - compile: v.ZodObject<{ - outDir: v.ZodOptional; - target: v.ZodLiteral<"browser">; - plugins: v.ZodOptional>; - }, "strip", v.ZodTypeAny, { - outDir?: string; - target?: "browser"; - plugins?: any; - }, { - outDir?: string; - target?: "browser"; - plugins?: any; - }>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"browser">; + plugins: v.ZodOptional>; }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - root?: string; - mode?: "spa"; - style?: RouterStyleFn; - handler?: string; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "spa"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }, { - name?: string; - base?: string; - root?: string; - mode?: "spa"; - style?: RouterStyleFn; - handler?: string; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "spa"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }>; - function relativeAppPath(path: any, router: any, appConfig: any): string; + /** + * Create a worker thread that will be used to render RSC chunks. + * @param buildPath Absolute path to the the built RSC bundle. + * @param onReload Called when the worker reloads. + */ + class AppWorkerClient { + constructor(url: any); + + worker: import('node:worker_threads').Worker | null; + + responses: Map void>; + url: any; + /** + * + // * @param {() => void} onReload + */ + init(onReload: any): Promise; + + handle(event: import('h3').H3Event): null; + close(): void; + } + function relativeAppPath(path: T, root: string): T; export namespace resolve { export { relativeAppPath as relative }; export { absoluteAppPath as absolute }; } - function absoluteAppPath(path: any, router: any, appConfig: any): any; + + function absoluteAppPath(path: T, root: string): T; } declare module 'vinxi/file-system-router' { import type { pathToRegexp } from 'path-to-regexp'; import * as v from 'zod'; - export function cleanPath(src: any, config: any): any; + export function cleanPath(src: string, config: FileSystemRouterConfig): string; - export function analyzeModule(src: any): readonly [imports: readonly import("es-module-lexer").ImportSpecifier[], exports: readonly import("es-module-lexer").ExportSpecifier[], facade: boolean]; - export function glob(path: any): string[]; - export class BaseFileSystemRouter { + export function analyzeModule(src: string): readonly [imports: readonly import("es-module-lexer").ImportSpecifier[], exports: readonly import("es-module-lexer").ExportSpecifier[], facade: boolean]; + export function glob(path: string): string[]; + export class BaseFileSystemRouter extends EventTarget { constructor(config: FileSystemRouterConfig, router: RouterSchema, app: AppOptions); + routes: any[]; + routerConfig: RouterSchema; + appConfig: AppOptions; + config: FileSystemRouterConfig; glob(): string; @@ -237,233 +237,247 @@ declare module 'vinxi/file-system-router' { toPath(src: any): string; - toRoute(src: any): object; + toRoute(src: any): Route | null; /** * To be attached by vite plugin to the vite dev server */ - update: any; - _addRoute(route: any): void; - addRoute(src: any): void; - updateRoute(src: any): void; - removeRoute(src: any): void; - buildRoutesPromise: any; + update: undefined; + + _addRoute(route: Route): void; + + addRoute(src: string): void; + + updateRoute(src: string): void; + + removeRoute(src: string): void; + + buildRoutesPromise: Promise | undefined; getRoutes(): Promise; } export type FileSystemRouterConfig = { dir: string; - extensions?: string[]; - }; - type RouterSchema = (HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema) & { - fileRouter?: any; - }; - type AppOptions = { - routers?: RouterSchema[]; - name?: string; - server?: import('nitropack').NitroConfig; - root?: string; - }; - type StaticRouterSchema = v.infer; - type CompiledRouter = { - getRoutes(): Promise; + extensions: string[]; }; - type RouterStyleFn = (router: RouterSchema, app: AppOptions) => CompiledRouter; + export type Route = { + path: string; + } & any; type BuildRouterSchema = v.infer & { - compiled?: CompiledRouter; + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; + }; + type StaticRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + internals?: Internals; }; type HandlerRouterSchema = v.infer & { - compiled?: CompiledRouter; + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; }; type SPARouterSchema = v.infer & { - compiled?: CompiledRouter; + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; }; - const staticRouterSchema: v.ZodObject<{ - name: v.ZodString; - base: v.ZodDefault; - mode: v.ZodLiteral<"static">; - dir: v.ZodString; - root: v.ZodOptional; - }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - mode?: "static"; - dir?: string; - root?: string; - }, { + type RouterSchema = (HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema); + type RouterSchemaInput = (v.infer | v.infer | v.infer | v.infer); + type AppOptions = { + routers?: RouterSchemaInput[]; name?: string; - base?: string; - mode?: "static"; - dir?: string; + server?: import('nitropack').NitroConfig; root?: string; - }>; - + }; + type Internals = { + routes?: CompiledRouter; + devServer?: import('vite').ViteDevServer; + appWorker?: AppWorkerClient; + }; + type CompiledRouter = { + getRoutes(): Promise; + } & EventTarget; + type RouterStyleFn = (router: RouterSchemaInput, app: AppOptions) => CompiledRouter; const buildRouterSchema: v.ZodObject<{ name: v.ZodString; - base: v.ZodDefault; + base: v.ZodOptional>; root: v.ZodOptional; mode: v.ZodLiteral<"build">; handler: v.ZodString; - style: v.ZodType; + routes: v.ZodOptionalType>; extensions: v.ZodOptional>; - compile: v.ZodObject<{ - outDir: v.ZodOptional; - target: v.ZodLiteral<"browser">; - plugins: v.ZodOptional>; - }, "strip", v.ZodTypeAny, { - outDir?: string; - target?: "browser"; - plugins?: any; - }, { - outDir?: string; - target?: "browser"; - plugins?: any; - }>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"browser">; + plugins: v.ZodOptional>; }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - root?: string; - mode?: "build"; - handler?: string; - style?: RouterStyleFn; - extensions?: string[]; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "build"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + extensions?: string[] | undefined; + outDir?: string | undefined; + plugins?: any; }, { - name?: string; - base?: string; - root?: string; - mode?: "build"; - handler?: string; - style?: RouterStyleFn; - extensions?: string[]; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "build"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + extensions?: string[] | undefined; + outDir?: string | undefined; + plugins?: any; }>; - - + const staticRouterSchema: v.ZodObject<{ + name: v.ZodString; + base: v.ZodOptional>; + mode: v.ZodLiteral<"static">; + dir: v.ZodString; + root: v.ZodOptional; + }, "strip", v.ZodTypeAny, { + name: string; + dir: string; + mode: "static"; + base?: string | undefined; + root?: string | undefined; + }, { + name: string; + dir: string; + mode: "static"; + base?: string | undefined; + root?: string | undefined; + }>; const handlerRouterSchema: v.ZodObject<{ name: v.ZodString; - base: v.ZodDefault; + base: v.ZodOptional>; root: v.ZodOptional; mode: v.ZodLiteral<"handler">; worker: v.ZodOptional; handler: v.ZodString; middleware: v.ZodOptional; - style: v.ZodType; - compile: v.ZodObject<{ - outDir: v.ZodOptional; - target: v.ZodLiteral<"server">; - plugins: v.ZodOptional>; - }, "strip", v.ZodTypeAny, { - outDir?: string; - target?: "server"; - plugins?: any; - }, { - outDir?: string; - target?: "server"; - plugins?: any; - }>; + routes: v.ZodOptionalType>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"server">; + plugins: v.ZodOptional>; }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - root?: string; - mode?: "handler"; - worker?: boolean; - handler?: string; - middleware?: string; - style?: RouterStyleFn; - compile?: { - outDir?: string; - target?: "server"; - plugins?: any; - }; + name: string; + target: "server"; + mode: "handler"; + handler: string; + base?: string | undefined; + root?: string | undefined; + worker?: boolean | undefined; + middleware?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }, { - name?: string; - base?: string; - root?: string; - mode?: "handler"; - worker?: boolean; - handler?: string; - middleware?: string; - style?: RouterStyleFn; - compile?: { - outDir?: string; - target?: "server"; - plugins?: any; - }; + name: string; + target: "server"; + mode: "handler"; + handler: string; + base?: string | undefined; + root?: string | undefined; + worker?: boolean | undefined; + middleware?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }>; - const spaRouterSchema: v.ZodObject<{ name: v.ZodString; - base: v.ZodDefault; + base: v.ZodOptional>; root: v.ZodOptional; mode: v.ZodLiteral<"spa">; - style: v.ZodType; + routes: v.ZodOptionalType>; handler: v.ZodString; - compile: v.ZodObject<{ - outDir: v.ZodOptional; - target: v.ZodLiteral<"browser">; - plugins: v.ZodOptional>; - }, "strip", v.ZodTypeAny, { - outDir?: string; - target?: "browser"; - plugins?: any; - }, { - outDir?: string; - target?: "browser"; - plugins?: any; - }>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"browser">; + plugins: v.ZodOptional>; }, "strip", v.ZodTypeAny, { - name?: string; - base?: string; - root?: string; - mode?: "spa"; - style?: RouterStyleFn; - handler?: string; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "spa"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }, { - name?: string; - base?: string; - root?: string; - mode?: "spa"; - style?: RouterStyleFn; - handler?: string; - compile?: { - outDir?: string; - target?: "browser"; - plugins?: any; - }; + name: string; + target: "browser"; + mode: "spa"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; }>; + /** + * Create a worker thread that will be used to render RSC chunks. + * @param buildPath Absolute path to the the built RSC bundle. + * @param onReload Called when the worker reloads. + */ + class AppWorkerClient { + constructor(url: any); + + worker: import('node:worker_threads').Worker | null; + + responses: Map void>; + url: any; + /** + * + // * @param {() => void} onReload + */ + init(onReload: any): Promise; + + handle(event: import('h3').H3Event): null; + close(): void; + } export { pathToRegexp }; } declare module 'vinxi/routes' { - export const routes: { + const _default: { path: string; }[]; + export default _default; } declare module 'vinxi/runtime/client' { } declare module 'vinxi/runtime/server' { - export * from "h3"; - export function setContext(event: any, key: any, value: any): void; - export function getContext(event: any, key: any, value: any): any; - export function defineMiddleware(options: any): any; +export * from "h3" + import type { H3Event } from 'h3'; + export function setContext(event: H3Event, key: string, value: any): void; + + export function getContext(event: H3Event, key: string): any; + + export function defineMiddleware(options: { + onRequest?: import("h3")._RequestMiddleware | import("h3")._RequestMiddleware[]; + onBeforeResponse?: import("h3")._ResponseMiddleware | import("h3")._ResponseMiddleware[]; + }): { + onRequest?: import("h3")._RequestMiddleware | import("h3")._RequestMiddleware[] | undefined; + onBeforeResponse?: import("h3")._ResponseMiddleware | import("h3")._ResponseMiddleware[] | undefined; + }; } declare module 'vinxi/runtime/style' { @@ -473,29 +487,215 @@ declare module 'vinxi/runtime/style' { } declare module 'vinxi/plugins/config' { - import type { ConfigEnv, UserConfig, Plugin as VitePlugin } from 'vite'; - export function config(tag: string, conf: import('vite').InlineConfig): Plugin; - interface Plugin extends VitePlugin { - config?: ( - this: void, - config: UserConfig & { router: any }, - env: ConfigEnv, - ) => void | UserConfig | Promise; - } + import type { Plugin as VitePlugin } from 'vite'; + import * as v from 'zod'; + export { ConfigEnv as } from 'vite'; + export function config(tag: string, conf: Omit): Plugin; + type Plugin = VitePlugin; } declare module 'vinxi/plugins/virtual' { - import type { ConfigEnv, UserConfig, Plugin as VitePlugin } from 'vite'; + import type { Plugin as VitePlugin, ResolvedConfig as _ResolvedConfig } from 'vite'; + import * as v from 'zod'; + export { ConfigEnv as } from 'vite'; export function virtual(modules: { - [key: string]: any; + [key: string]: (ctx: { + config: ViteConfig; + }) => (string | Promise); }, name?: string, cache?: any): Plugin; - interface Plugin extends VitePlugin { - config?: ( - this: void, - config: UserConfig & { router: any }, - env: ConfigEnv, - ) => void | UserConfig | Promise; - } + type ViteConfig = _ResolvedConfig & { router: RouterSchema }; + + type Plugin = VitePlugin; + type BuildRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; + }; + type StaticRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + internals?: Internals; + }; + type HandlerRouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; + }; + type SPARouterSchema = v.infer & { + outDir: string; + base: string; + order: number; + root: string; + internals: Internals; + }; + type RouterSchema = (HandlerRouterSchema | BuildRouterSchema | SPARouterSchema | StaticRouterSchema); + type RouterSchemaInput = (v.infer | v.infer | v.infer | v.infer); + type AppOptions = { + routers?: RouterSchemaInput[]; + name?: string; + server?: import('nitropack').NitroConfig; + root?: string; + }; + type Internals = { + routes?: CompiledRouter; + devServer?: import('vite').ViteDevServer; + appWorker?: AppWorkerClient; + }; + type CompiledRouter = { + getRoutes(): Promise; + } & EventTarget; + type RouterStyleFn = (router: RouterSchemaInput, app: AppOptions) => CompiledRouter; + const buildRouterSchema: v.ZodObject<{ + name: v.ZodString; + base: v.ZodOptional>; + root: v.ZodOptional; + mode: v.ZodLiteral<"build">; + handler: v.ZodString; + + routes: v.ZodOptionalType>; + extensions: v.ZodOptional>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"browser">; + plugins: v.ZodOptional>; + }, "strip", v.ZodTypeAny, { + name: string; + target: "browser"; + mode: "build"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + extensions?: string[] | undefined; + outDir?: string | undefined; + plugins?: any; + }, { + name: string; + target: "browser"; + mode: "build"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + extensions?: string[] | undefined; + outDir?: string | undefined; + plugins?: any; + }>; + + const staticRouterSchema: v.ZodObject<{ + name: v.ZodString; + base: v.ZodOptional>; + mode: v.ZodLiteral<"static">; + dir: v.ZodString; + root: v.ZodOptional; + }, "strip", v.ZodTypeAny, { + name: string; + dir: string; + mode: "static"; + base?: string | undefined; + root?: string | undefined; + }, { + name: string; + dir: string; + mode: "static"; + base?: string | undefined; + root?: string | undefined; + }>; + const handlerRouterSchema: v.ZodObject<{ + name: v.ZodString; + base: v.ZodOptional>; + root: v.ZodOptional; + mode: v.ZodLiteral<"handler">; + worker: v.ZodOptional; + handler: v.ZodString; + middleware: v.ZodOptional; + + routes: v.ZodOptionalType>; + outDir: v.ZodOptional; + target: v.ZodLiteral<"server">; + plugins: v.ZodOptional>; + }, "strip", v.ZodTypeAny, { + name: string; + target: "server"; + mode: "handler"; + handler: string; + base?: string | undefined; + root?: string | undefined; + worker?: boolean | undefined; + middleware?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; + }, { + name: string; + target: "server"; + mode: "handler"; + handler: string; + base?: string | undefined; + root?: string | undefined; + worker?: boolean | undefined; + middleware?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; + }>; + const spaRouterSchema: v.ZodObject<{ + name: v.ZodString; + base: v.ZodOptional>; + root: v.ZodOptional; + mode: v.ZodLiteral<"spa">; + + routes: v.ZodOptionalType>; + handler: v.ZodString; + outDir: v.ZodOptional; + target: v.ZodLiteral<"browser">; + plugins: v.ZodOptional>; + }, "strip", v.ZodTypeAny, { + name: string; + target: "browser"; + mode: "spa"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; + }, { + name: string; + target: "browser"; + mode: "spa"; + handler: string; + base?: string | undefined; + root?: string | undefined; + routes?: RouterStyleFn | undefined; + outDir?: string | undefined; + plugins?: any; + }>; + /** + * Create a worker thread that will be used to render RSC chunks. + * @param buildPath Absolute path to the the built RSC bundle. + * @param onReload Called when the worker reloads. + */ + class AppWorkerClient { + constructor(url: any); + + worker: import('node:worker_threads').Worker | null; + + responses: Map void>; + url: any; + /** + * + // * @param {() => void} onReload + */ + init(onReload: any): Promise; + + handle(event: import('h3').H3Event): null; + close(): void; + } } //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/packages/vinxi/types/index.d.ts.map b/packages/vinxi/types/index.d.ts.map index 09f4afcb..00c02c25 100644 --- a/packages/vinxi/types/index.d.ts.map +++ b/packages/vinxi/types/index.d.ts.map @@ -3,22 +3,24 @@ "file": "index.d.ts", "names": [ "createApp", + "BuildRouterSchema", + "StaticRouterSchema", + "HandlerRouterSchema", + "SPARouterSchema", "RouterSchema", + "RouterSchemaInput", "AppOptions", - "RouterModes", - "StaticRouterSchema", + "Internals", "CompiledRouter", "RouterStyleFn", - "BuildRouterSchema", - "HandlerRouterSchema", - "SPARouterSchema", + "AppWorkerClient", "relativeAppPath", "cleanPath", "analyzeModule", "glob", "BaseFileSystemRouter", "FileSystemRouterConfig", - "routes", + "Route", "setContext", "getContext", "defineMiddleware", @@ -27,13 +29,14 @@ "cleanupStyles", "config", "Plugin", - "virtual" + "virtual", + "ViteConfig" ], "sources": [ "../lib/app.js", + "../lib/app-worker-client.js", "../lib/resolve.js", "../lib/file-system-router.js", - "../lib/routes.js", "../runtime/server.js", "../runtime/style.js", "../lib/plugins/config.js", @@ -51,5 +54,5 @@ null, null ], - "mappings": ";;iBA4JgBA,SAASA;aAT8FC,YAAYA;;;aACfC,UAAUA;;;;;;;;;;;;;;;;;aAhFxEC,WAAWA;aAYfC,kBAAkBA;aAkBrBC,cAAcA;;;aACYC,aAAaA;aACLC,iBAAiBA;;;aAqBfC,mBAAmBA;;;aAiBtBC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UCjI/EC,eAAeA;;;;;;;;;;;iBCKfC,SAASA;;iBAQTC,aAAaA;iBAVhBC,IAAIA;cAqBJC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;aAbqBC,sBAAsBA;;;;MF+H2Cd,YAAYA;;;MACfC,UAAUA;;;;;;MApE5EE,kBAAkBA;MAkBrBC,cAAcA;;;MACYC,aAAaA;MACLC,iBAAiBA;;;MAqBfC,mBAAmBA;;;MAiBtBC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cGrIlFO,MAAMA;;;;;;;;;iBCHHC,UAAUA;iBAIVC,UAAUA;iBAIVC,gBAAgBA;;;;iBCVhBC,YAAYA;iBAeZC,YAAYA;iBAcZC,aAAaA;;;;;iBCvBbC,MAAMA;WCCLC,MAAMA;;;;;;;;;;;iBCIPC,OAAOA;;;WDJND,MAAMA" + "mappings": ";;iBAiLgBA,SAASA;aAvG8GC,iBAAiBA;;;;;;;aAC7BC,kBAAkBA;;;;;;aACJC,mBAAmBA;;;;;;;aACvBC,eAAeA;;;;;;;aACpDC,YAAYA;aACqDC,iBAAiBA;aACzDC,UAAUA;;;;;;;;;;;;;;;;;aAtEgBC,SAASA;;;;;aAC/FC,cAAcA;;;aACEC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QCiC7EC,eAAeA;;;;;;;;;;;;;;;;UC1BZC,eAAeA;;;;;;;;;;;;iBCSfC,SAASA;;iBAWTC,aAAaA;iBAtBhBC,IAAIA;cAiCJC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA/BoBC,sBAAsBA;;;;aACrCC,KAAKA;;;MHsD4FjB,iBAAiBA;;;;;;;MAC7BC,kBAAkBA;;;;;;MACJC,mBAAmBA;;;;;;;MACvBC,eAAeA;;;;;;;MACpDC,YAAYA;MACqDC,iBAAiBA;MACzDC,UAAUA;;;;;;MAtEgBC,SAASA;;;;;MAC/FC,cAAcA;;;MACEC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QCiC7EC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBGnCZQ,UAAUA;;iBASVC,UAAUA;;iBASVC,gBAAgBA;;;;;;;;;;iBC5BhBC,YAAYA;iBAeZC,YAAYA;iBAcZC,aAAaA;;;;;;;iBCvBbC,MAAMA;MCoBVC,MAAMA;;;;;;;iBCfFC,OAAOA;;;;;MDaXC,UAAUA;;MAEVF,MAAMA;MPgDqHzB,iBAAiBA;;;;;;;MAC7BC,kBAAkBA;;;;;;MACJC,mBAAmBA;;;;;;;MACvBC,eAAeA;;;;;;;MACpDC,YAAYA;MACqDC,iBAAiBA;MACzDC,UAAUA;;;;;;MAtEgBC,SAASA;;;;;MAC/FC,cAAcA;;;MACEC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QCiC7EC,eAAeA" } \ No newline at end of file diff --git a/test/templates/react/app.config.js b/test/templates/react/app.config.js index ad41fe41..7391cedb 100644 --- a/test/templates/react/app.config.js +++ b/test/templates/react/app.config.js @@ -54,7 +54,7 @@ export default createApp({ name: "api", mode: "handler", handler: "./app/api.ts", - style: (router, app) => + routes: (router, app) => new APIFileSystemRouter( { dir: resolve.absolute("./app/api", router, app), @@ -63,29 +63,23 @@ export default createApp({ router, app, ), - compile: { - target: "server", - // plugins: () => [reactRefresh()], - }, + target: "server", + // plugins: () => [reactRefresh()], base: "/api", }, { name: "client", mode: "build", handler: "./app/entry-client.tsx", - compile: { - target: "browser", - plugins: () => [reactRefresh()], - }, + target: "browser", + plugins: () => [reactRefresh()], base: "/_build", }, { name: "ssr", mode: "handler", handler: "./app/entry-server.tsx", - compile: { - target: "server", - }, + target: "server", }, ], });