Skip to content

Commit

Permalink
BREAKING: move a bunch of types into server/ (#263)
Browse files Browse the repository at this point in the history
Moved some server only types like `RouteConfig` into server/. They were
previously in runtime/.
  • Loading branch information
lucacasonato committed Jun 21, 2022
1 parent 3458e35 commit da340da
Show file tree
Hide file tree
Showing 22 changed files with 230 additions and 216 deletions.
5 changes: 2 additions & 3 deletions docs/concepts/routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Now, let's render some HTML using the route component. Another example:

/** @jsx h */
import { h } from "preact";
import { PageProps } from "$fresh/runtime.ts";
import { PageProps } from "$fresh/server.ts";

export default function Page(props: PageProps) {
return <div>You are on the page '{props.url.href}'.</div>;
Expand All @@ -65,8 +65,7 @@ response after rendering the page component.

/** @jsx h */
import { h } from "preact";
import { PageProps } from "$fresh/runtime.ts";
import { HandlerContext, Handlers } from "$fresh/server.ts";
import { HandlerContext, Handlers, PageProps } from "$fresh/server.ts";

export const handler: Handlers = {
async GET(ctx: HandlerContext) {
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/dynamic-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ as arguments in it's `props` object though.

/** @jsx h */
import { h } from "preact";
import { PageProps } from "$fresh/runtime.ts";
import { PageProps } from "$fresh/server.ts";

export default function GreetPage(props: PageProps) {
const { name } = props.params;
Expand Down
3 changes: 1 addition & 2 deletions docs/getting-started/fetching-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ renders it in a page component.

/** @jsx h */
import { h } from "preact";
import { PageProps } from "$fresh/runtime.ts";
import { Handlers } from "$fresh/server.ts";
import { Handlers, PageProps } from "$fresh/server.ts";

interface User {
login: string;
Expand Down
3 changes: 1 addition & 2 deletions docs/getting-started/form-submissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ server side:

/** @jsx h */
import { h } from "preact";
import { PageProps } from "$fresh/runtime.ts";
import { Handlers } from "$fresh/server.ts";
import { Handlers, PageProps } from "$fresh/server.ts";

const NAMES = ["Alice", "Bob", "Charlie", "Dave", "Eve", "Frank"];

Expand Down
2 changes: 1 addition & 1 deletion init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ await Deno.writeTextFile(

const ROUTES_GREET_TSX = `/** @jsx h */
import { h } from "preact";
import { PageProps } from "$fresh/runtime.ts";
import { PageProps } from "$fresh/server.ts";
export default function Greet(props: PageProps) {
return <div>Hello {props.params.name}</div>;
Expand Down
1 change: 0 additions & 1 deletion runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from "./src/runtime/types.ts";
export * from "./src/runtime/utils.ts";
export * from "./src/runtime/head.ts";
export * from "./src/runtime/csp.ts";
70 changes: 0 additions & 70 deletions src/runtime/types.ts

This file was deleted.

85 changes: 44 additions & 41 deletions src/server/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ import {
Middleware,
MiddlewareModule,
MiddlewareRoute,
Page,
PageModule,
RenderFunction,
RouterState,
Route,
RouteModule,
UnknownPage,
UnknownPageModule,
} from "./types.ts";
import { render as internalRender } from "./render.tsx";
import { ContentSecurityPolicyDirectives, SELF } from "../runtime/csp.ts";
import { ASSET_CACHE_BUST_KEY, INTERNAL_PREFIX } from "../runtime/utils.ts";

interface RouterState {
state: Record<string, unknown>;
}

interface StaticFile {
/** The URL to the static file on disk. */
localUrl: URL;
Expand All @@ -49,7 +52,7 @@ interface StaticFile {

export class ServerContext {
#dev: boolean;
#pages: Page[];
#routes: Route[];
#islands: Island[];
#staticFiles: StaticFile[];
#bundler: Bundler;
Expand All @@ -60,7 +63,7 @@ export class ServerContext {
#error: ErrorPage;

constructor(
pages: Page[],
routes: Route[],
islands: Island[],
staticFiles: StaticFile[],
renderfn: RenderFunction,
Expand All @@ -70,7 +73,7 @@ export class ServerContext {
error: ErrorPage,
importMapURL: URL,
) {
this.#pages = pages;
this.#routes = routes;
this.#islands = islands;
this.#staticFiles = staticFiles;
this.#renderFn = renderfn;
Expand All @@ -94,7 +97,7 @@ export class ServerContext {
const importMapURL = new URL("./import_map.json", manifest.baseUrl);

// Extract all routes, and prepare them into the `Page` structure.
const pages: Page[] = [];
const routes: Route[] = [];
const islands: Island[] = [];
const middlewares: MiddlewareRoute[] = [];
let app: AppModule = DEFAULT_APP;
Expand All @@ -112,28 +115,28 @@ export class ServerContext {
path.endsWith("/_middleware.ts") || path.endsWith("/_middleware.jsx") ||
path.endsWith("/_middleware.js");
if (!path.startsWith("/_") && !isMiddleware) {
const { default: component, config } = (module as PageModule);
let route = pathToRoute(baseRoute);
const { default: component, config } = (module as RouteModule);
let pattern = pathToPattern(baseRoute);
if (config?.routeOverride) {
route = String(config.routeOverride);
pattern = String(config.routeOverride);
}
let { handler } = (module as PageModule);
let { handler } = (module as RouteModule);
handler ??= {};
if (
component &&
typeof handler === "object" && handler.GET === undefined
) {
handler.GET = (_req, { render }) => render();
}
const page: Page = {
route,
const route: Route = {
pattern,
url,
name,
component,
handler,
csp: Boolean(config?.csp ?? false),
};
pages.push(page);
routes.push(route);
} else if (isMiddleware) {
middlewares.push({
...middlewarePathToPattern(baseRoute),
Expand All @@ -155,7 +158,7 @@ export class ServerContext {
}

notFound = {
route: pathToRoute(baseRoute),
pattern: pathToPattern(baseRoute),
url,
name,
component,
Expand All @@ -173,7 +176,7 @@ export class ServerContext {
}

error = {
route: pathToRoute(baseRoute),
pattern: pathToPattern(baseRoute),
url,
name,
component,
Expand All @@ -183,7 +186,7 @@ export class ServerContext {
};
}
}
sortRoutes(pages);
sortRoutes(routes);
sortRoutes(middlewares);

for (const [self, module] of Object.entries(manifest.islands)) {
Expand Down Expand Up @@ -249,7 +252,7 @@ export class ServerContext {
}

return new ServerContext(
pages,
routes,
islands,
staticFiles,
opts.render ?? DEFAULT_RENDER_FN,
Expand All @@ -266,7 +269,7 @@ export class ServerContext {
* by fresh, including static files.
*/
handler(): RequestHandler {
const inner = router.router<RouterState>(...this.#routes());
const inner = router.router<RouterState>(...this.#handlers());
const withMiddlewares = this.#composeMiddlewares(this.#middlewares);
return function handler(req: Request, connInfo: ConnInfo) {
// Redirect requests that end with a trailing slash
Expand Down Expand Up @@ -321,7 +324,7 @@ export class ServerContext {
* This function returns all routes required by fresh as an extended
* path-to-regex, to handler mapping.
*/
#routes(): [
#handlers(): [
router.Routes<RouterState>,
router.Handler<RouterState>,
router.ErrorHandler<RouterState>,
Expand Down Expand Up @@ -381,7 +384,7 @@ export class ServerContext {
}

const genRender = <Data = undefined>(
page: Page<Data> | UnknownPage | ErrorPage,
route: Route<Data> | UnknownPage | ErrorPage,
status: number,
) => {
const imports: string[] = [];
Expand All @@ -394,12 +397,12 @@ export class ServerContext {
error?: unknown,
) => {
return async (data?: Data) => {
if (page.component === undefined) {
if (route.component === undefined) {
throw new Error("This page does not have a component to render.");
}
const preloads: string[] = [];
const resp = await internalRender({
page,
route,
islands: this.#islands,
app: this.#app,
imports,
Expand Down Expand Up @@ -435,18 +438,18 @@ export class ServerContext {
};
};

for (const page of this.#pages) {
const createRender = genRender(page, 200);
if (typeof page.handler === "function") {
routes[page.route] = (req, ctx, params) =>
(page.handler as Handler)(req, {
for (const route of this.#routes) {
const createRender = genRender(route, 200);
if (typeof route.handler === "function") {
routes[route.pattern] = (req, ctx, params) =>
(route.handler as Handler)(req, {
...ctx,
params,
render: createRender(req, params),
});
} else {
for (const [method, handler] of Object.entries(page.handler)) {
routes[`${method}@${page.route}`] = (req, ctx, params) =>
for (const [method, handler] of Object.entries(route.handler)) {
routes[`${method}@${route.pattern}`] = (req, ctx, params) =>
handler(req, {
...ctx,
params,
Expand Down Expand Up @@ -573,15 +576,15 @@ const DEFAULT_APP: AppModule = {
};

const DEFAULT_NOT_FOUND: UnknownPage = {
route: "",
pattern: "",
url: "",
name: "_404",
handler: (req) => router.defaultOtherHandler(req),
csp: false,
};

const DEFAULT_ERROR: ErrorPage = {
route: "",
pattern: "",
url: "",
name: "_500",
component: DefaultErrorHandler,
Expand All @@ -598,8 +601,8 @@ export function selectMiddlewares(url: string, middlewares: MiddlewareRoute[]) {
const selectedMws: Middleware[] = [];
const reqURL = new URL(url);

for (const { pattern, handler } of middlewares) {
const res = pattern.exec(reqURL);
for (const { compiledPattern, handler } of middlewares) {
const res = compiledPattern.exec(reqURL);
if (res) {
selectedMws.push({ handler });
}
Expand All @@ -612,10 +615,10 @@ export function selectMiddlewares(url: string, middlewares: MiddlewareRoute[]) {
* Sort pages by their relative routing priority, based on the parts in the
* route matcher
*/
function sortRoutes<T extends { route: string }>(routes: T[]) {
function sortRoutes<T extends { pattern: string }>(routes: T[]) {
routes.sort((a, b) => {
const partsA = a.route.split("/");
const partsB = b.route.split("/");
const partsA = a.pattern.split("/");
const partsB = b.pattern.split("/");
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
const partA = partsA[i];
const partB = partsB[i];
Expand All @@ -631,7 +634,7 @@ function sortRoutes<T extends { route: string }>(routes: T[]) {
}

/** Transform a filesystem URL path to a `path-to-regex` style matcher. */
function pathToRoute(path: string): string {
function pathToPattern(path: string): string {
const parts = path.split("/");
if (parts[parts.length - 1] === "index") {
parts.pop();
Expand Down Expand Up @@ -687,7 +690,7 @@ function serializeCSPDirectives(csp: ContentSecurityPolicyDirectives): string {

export function middlewarePathToPattern(baseRoute: string) {
baseRoute = baseRoute.slice(0, -"_middleware".length);
const regRoute = pathToRoute(baseRoute);
const pattern = new URLPattern({ pathname: `${regRoute}*` });
return { route: regRoute, pattern };
const pattern = pathToPattern(baseRoute);
const compiledPattern = new URLPattern({ pathname: `${pattern}*` });
return { pattern, compiledPattern };
}

0 comments on commit da340da

Please sign in to comment.