Skip to content

Commit

Permalink
fix: PluginRoute supports AsyncRoute and AsyncLayout (denoland#2139)
Browse files Browse the repository at this point in the history
  • Loading branch information
deer authored Dec 4, 2023
1 parent 993f102 commit c8844ad
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 16 deletions.
6 changes: 5 additions & 1 deletion src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,11 @@ export interface PluginRoute {
/** A path in the format of a filename path without filetype */
path: string;

component?: ComponentType<PageProps> | ComponentType<AppProps>;
component?:
| ComponentType<PageProps>
| ComponentType<AppProps>
| AsyncRoute
| AsyncLayout;

// deno-lint-ignore no-explicit-any
handler?: Handler<any, any> | Handlers<any, any>;
Expand Down
2 changes: 1 addition & 1 deletion tests/fixture_plugin/fresh.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default {
jsInjectPlugin,
cssInjectPluginAsync,
linkInjectPlugin,
routePlugin({ title: "Title Set From Plugin Config" }),
routePlugin({ title: "Title Set From Plugin Config", async: false }),
secondMiddlewarePlugin(),
],
} as FreshConfig;
3 changes: 3 additions & 0 deletions tests/fixture_plugin/utils/route-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { handler as testMiddleware } from "./sample_routes/_middleware.ts";
import { AppBuilder } from "./sample_routes/AppBuilder.tsx";
import IslandPluginComponent from "./sample_routes/PluginRouteWithIsland.tsx";
import { SimpleRoute } from "./sample_routes/simple-route.tsx";
import AsyncRoute from "./sample_routes/async-route.tsx";
export type { Options };

interface Options {
title: string;
async: boolean;
}
export type PluginMiddlewareState = {
num: number;
Expand Down Expand Up @@ -45,6 +47,7 @@ export default function routePlugin(
path: "lots-of-middleware",
}],
routes: [
{ path: "/async-route", component: AsyncRoute },
{
path: "/_app",
component: AppBuilder(options),
Expand Down
40 changes: 27 additions & 13 deletions tests/fixture_plugin/utils/sample_routes/AppBuilder.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { PageProps } from "$fresh/server.ts";
import { defineApp, PageProps } from "$fresh/server.ts";
import { Head } from "../../../../runtime.ts";
import { Options } from "../route-plugin.ts";

export function AppBuilder(options: Options) {
return ({ Component }: PageProps) => {
return (
<>
<Head>
<title>{options.title}</title>
</Head>
<main class="max-w-screen-md px-4 pt-16 mx-auto">
<Component />
</main>
</>
);
};
return options.async
? defineApp((_req, ctx) => {
return (
<>
<Head>
<title>{options.title}</title>
</Head>
<main class="max-w-screen-md px-4 pt-16 mx-auto">
foo
<ctx.Component />
</main>
</>
);
})
: ({ Component }: PageProps) => {
return (
<>
<Head>
<title>{options.title}</title>
</Head>
<main class="max-w-screen-md px-4 pt-16 mx-auto">
<Component />
</main>
</>
);
};
}
9 changes: 9 additions & 0 deletions tests/fixture_plugin/utils/sample_routes/async-route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineRoute } from "$fresh/src/server/defines.ts";

export default defineRoute((_req, _ctx) => {
return (
<div>
this is an async route!
</div>
);
});
49 changes: 48 additions & 1 deletion tests/plugin_test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ServerContext, STATUS_CODE } from "../server.ts";
import { type FreshConfig, ServerContext, STATUS_CODE } from "../server.ts";
import {
assert,
assertEquals,
Expand All @@ -17,6 +17,8 @@ import {
withFakeServe,
withPageName,
} from "./test_utils.ts";
import routePlugin from "./fixture_plugin/utils/route-plugin.ts";
import secondMiddlewarePlugin from "./fixture_plugin/utils/second-middleware-plugin.ts";

const ctx = await ServerContext.fromManifest(manifest, config);
const handler = ctx.handler();
Expand Down Expand Up @@ -81,6 +83,38 @@ Deno.test("plugin routes and middleware", async () => {
);
});

Deno.test("plugin routes and middleware -- async _app", async () => {
const ctx = await ServerContext.fromManifest(manifest, {
plugins: [
routePlugin({ title: "Title Set From Plugin Config", async: true }),
secondMiddlewarePlugin(),
],
} as FreshConfig);
const handler = ctx.handler();
const router = (req: Request) => {
return handler(req, {
remoteAddr: {
transport: "tcp",
hostname: "127.0.0.1",
port: 80,
},
});
};

const resp = await router(new Request("https://fresh.deno.dev/test"));
assert(resp);
assertEquals(resp.status, STATUS_CODE.OK);
const body = await resp.text();
assertStringIncludes(
body,
`<h1>look, i'm set from a plugin!</h1>`,
);
assertStringIncludes(
body,
`<title>Title Set From Plugin Config</title>`,
);
});

Deno.test("plugin middleware multiple handlers", async () => {
const resp = await router(
new Request("https://fresh.deno.dev/lots-of-middleware"),
Expand All @@ -107,6 +141,19 @@ Deno.test("plugin route no leading slash", async () => {
);
});

Deno.test("plugin async route", async () => {
const resp = await router(
new Request("https://fresh.deno.dev/async-route"),
);
assert(resp);
assertEquals(resp.status, STATUS_CODE.OK);
const body = await resp.text();
assertStringIncludes(
body,
`<div>this is an async route!</div>`,
);
});

Deno.test({
name: "plugin supports islands",
async fn(t) {
Expand Down

0 comments on commit c8844ad

Please sign in to comment.