From 900e1860fb273ba5211fe613b1e3b3194118891d Mon Sep 17 00:00:00 2001 From: Lee Cheneler Date: Tue, 19 Nov 2024 00:05:21 +0000 Subject: [PATCH] fix: restricting settings public properties on classes --- .git-hooks/pre-commit.sh | 8 +++--- README.md | 6 ++--- src/app.ts | 30 +++++++++++------------ src/context.ts | 53 ++++++++++++++++++++++++++-------------- src/router.ts | 10 ++++---- test-utils/server.ts | 20 +++++++++++---- 6 files changed, 75 insertions(+), 52 deletions(-) diff --git a/.git-hooks/pre-commit.sh b/.git-hooks/pre-commit.sh index 2ddc8a6..4f3f93f 100755 --- a/.git-hooks/pre-commit.sh +++ b/.git-hooks/pre-commit.sh @@ -1,7 +1,5 @@ #!/bin/sh -denon task format -denon task lint -denon task check - -git add -u \ No newline at end of file +deno task format --check +deno task lint +deno task check diff --git a/README.md b/README.md index 03dfe7d..a55abc8 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ app.get("/render", async (context) => {

Hello, World!

- + , ); }); @@ -158,7 +158,7 @@ await context.render(

Hello, World!

- + , ); ``` @@ -231,7 +231,7 @@ app.get( }, (context) => { context.text(StatusCode.OK, "Three!"); - } + }, // ... etc ); ``` diff --git a/src/app.ts b/src/app.ts index d0706cd..40b226d 100644 --- a/src/app.ts +++ b/src/app.ts @@ -31,7 +31,7 @@ interface RunOptions { * MageApp is the main class for creating and running Mage applications. */ export class MageApp { - private router = new MageRouter(); + private _router = new MageRouter(); /** * Adds middleware to the application that will be run for every request. @@ -39,7 +39,7 @@ export class MageApp { * @param middleware */ public use(...middleware: MageMiddleware[]): void { - this.router.use(...middleware); + this._router.use(...middleware); } /** @@ -53,7 +53,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.all(routenameOrMiddleware, ...middleware); + this._router.all(routenameOrMiddleware, ...middleware); } /** @@ -67,7 +67,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.get(routenameOrMiddleware, ...middleware); + this._router.get(routenameOrMiddleware, ...middleware); } /** @@ -81,7 +81,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.post(routenameOrMiddleware, ...middleware); + this._router.post(routenameOrMiddleware, ...middleware); } /** @@ -95,7 +95,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.put(routenameOrMiddleware, ...middleware); + this._router.put(routenameOrMiddleware, ...middleware); } /** @@ -109,7 +109,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.delete(routenameOrMiddleware, ...middleware); + this._router.delete(routenameOrMiddleware, ...middleware); } /** @@ -123,7 +123,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.patch(routenameOrMiddleware, ...middleware); + this._router.patch(routenameOrMiddleware, ...middleware); } /** @@ -137,7 +137,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.options(routenameOrMiddleware, ...middleware); + this._router.options(routenameOrMiddleware, ...middleware); } /** @@ -151,7 +151,7 @@ export class MageApp { routenameOrMiddleware: string | MageMiddleware, ...middleware: MageMiddleware[] ): void { - this.router.head(routenameOrMiddleware, ...middleware); + this._router.head(routenameOrMiddleware, ...middleware); } /** @@ -166,14 +166,14 @@ export class MageApp { onListen: options.onListen, }; - return Deno.serve(serveOptions, async (_req) => { - const context: MageContext = new MageContext(_req, this.router); + return Deno.serve(serveOptions, async (req) => { + const context: MageContext = new MageContext(req); - const matchResult = this.router.match(context); + const matchResult = this._router.match(context); const middleware = [ useOptions({ - getAllowedMethods: () => this.router.getAvailableMethods(context), + getAllowedMethods: () => this._router.getAvailableMethods(context), }), ...matchResult.middleware, ]; @@ -185,7 +185,7 @@ export class MageApp { if (!matchResult.matchedMethod) { middleware.push( useMethodNotAllowed({ - getAllowedMethods: () => this.router.getAvailableMethods(context), + getAllowedMethods: () => this._router.getAvailableMethods(context), }), ); } diff --git a/src/context.ts b/src/context.ts index cb4987a..1fafb87 100644 --- a/src/context.ts +++ b/src/context.ts @@ -1,7 +1,6 @@ import type { VNode } from "preact"; import { renderToStringAsync } from "preact-render-to-string"; import { RedirectType, StatusCode, statusTextMap } from "./http.ts"; -import type { MageRouter } from "./router.ts"; /** * Serializable JSON value @@ -18,19 +17,35 @@ type JSON = { [key: string]: JSONValues } | JSONValues[]; * request/response cycle and is used to interact with the request and response. */ export class MageContext { + private _url: URL; + private _response: Response = new Response(); + private _request: Request; + /** * The URL of the request */ - public url: URL; + public get url(): URL { + return this._url; + } /** * The response object that will be sent at the end of the request/response * cycle. */ - public response: Response = new Response(); + public get response(): Response { + return this._response; + } + + /** + * The request object for the current request + */ + public get request(): Request { + return this._request; + } - public constructor(public request: Request, private router: MageRouter) { - this.url = new URL(request.url); + public constructor(request: Request) { + this._url = new URL(request.url); + this._request = request; } /** @@ -39,13 +54,13 @@ export class MageContext { * @param body */ public text(status: StatusCode, body: string) { - this.response = new Response(body, { + this._response = new Response(body, { status: status, statusText: statusTextMap[status], - headers: this.response.headers, + headers: this._response.headers, }); - this.response.headers.set("Content-Type", "text/plain; charset=utf-8"); + this._response.headers.set("Content-Type", "text/plain; charset=utf-8"); } /** @@ -54,13 +69,13 @@ export class MageContext { * @param body */ public json(status: StatusCode, body: JSON) { - this.response = new Response(JSON.stringify(body), { + this._response = new Response(JSON.stringify(body), { status: status, statusText: statusTextMap[status], - headers: this.response.headers, + headers: this._response.headers, }); - this.response.headers.set("Content-Type", "application/json"); + this._response.headers.set("Content-Type", "application/json"); } /** @@ -70,13 +85,13 @@ export class MageContext { */ public async render(status: StatusCode, body: VNode) { const html = await renderToStringAsync(body); - this.response = new Response(`${html}`, { + this._response = new Response(`${html}`, { status: status, statusText: statusTextMap[status], - headers: this.response.headers, + headers: this._response.headers, }); - this.response.headers.set("Content-Type", "text/html; charset=utf-8"); + this._response.headers.set("Content-Type", "text/html; charset=utf-8"); } /** @@ -84,10 +99,10 @@ export class MageContext { * @param status */ public empty(status: StatusCode) { - this.response = new Response(null, { + this._response = new Response(null, { status: status, statusText: statusTextMap[status], - headers: this.response.headers, + headers: this._response.headers, }); } @@ -101,12 +116,12 @@ export class MageContext { ? StatusCode.PermanentRedirect : StatusCode.TemporaryRedirect; - this.response = new Response(null, { + this._response = new Response(null, { status, statusText: statusTextMap[status], - headers: this.response.headers, + headers: this._response.headers, }); - this.response.headers.set("Location", location.toString()); + this._response.headers.set("Location", location.toString()); } } diff --git a/src/router.ts b/src/router.ts index 13dfce4..b3d0799 100644 --- a/src/router.ts +++ b/src/router.ts @@ -47,7 +47,7 @@ interface MatchResult { * application. */ export class MageRouter { - private entries: RouterEntry[] = []; + private _entries: RouterEntry[] = []; /** * Match middleware for a given context. @@ -59,7 +59,7 @@ export class MageRouter { let matchedRoutename = false; let matchedMethod = false; - const middleware = this.entries + const middleware = this._entries .filter((entry) => { if (entry.routename && entry.routename !== context.url.pathname) { return false; @@ -95,7 +95,7 @@ export class MageRouter { * @returns */ public getAvailableMethods(context: MageContext): string[] { - const methods = this.entries + const methods = this._entries .filter((entry) => entry.routename === context.url.pathname) .flatMap((entry) => entry.methods ?? []); @@ -110,7 +110,7 @@ export class MageRouter { * @param middleware */ public use(...middleware: MageMiddleware[]) { - this.entries.push({ + this._entries.push({ middleware, }); } @@ -256,7 +256,7 @@ export class MageRouter { ? additionalMiddleware : [routenameOrMiddleware, ...additionalMiddleware]; - this.entries.push({ + this._entries.push({ routename, middleware, methods, diff --git a/test-utils/server.ts b/test-utils/server.ts index f073490..f89d17b 100644 --- a/test-utils/server.ts +++ b/test-utils/server.ts @@ -2,12 +2,22 @@ import { MageApp } from "../mod.ts"; const TEST_PORT_FLOOR = 60000; +/** + * A test server for running Mage apps in a test environment + */ export class MageTestServer { - public app: MageApp = new MageApp(); - private server: Deno.HttpServer | undefined; + private _app: MageApp = new MageApp(); + private _server: Deno.HttpServer | undefined; + + /** + * The test server's app instance + */ + public get app() { + return this._app; + } start(port?: number) { - this.server = this.app.run({ + this._server = this.app.run({ port: port ?? Math.floor(Math.random() * 1000) + TEST_PORT_FLOOR, }); } @@ -15,11 +25,11 @@ export class MageTestServer { url(path: string) { return new URL( path, - `http://${this.server?.addr.hostname}:${this.server?.addr.port}`, + `http://${this._server?.addr.hostname}:${this._server?.addr.port}`, ); } async stop() { - await this.server?.shutdown(); + await this._server?.shutdown(); } }