Skip to content

Commit

Permalink
fix: restricting settings public properties on classes
Browse files Browse the repository at this point in the history
  • Loading branch information
LeeCheneler committed Nov 19, 2024
1 parent 81513fb commit 900e186
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 52 deletions.
8 changes: 3 additions & 5 deletions .git-hooks/pre-commit.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#!/bin/sh

denon task format
denon task lint
denon task check

git add -u
deno task format --check
deno task lint
deno task check
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ app.get("/render", async (context) => {
<body>
<h1>Hello, World!</h1>
</body>
</html>
</html>,
);
});

Expand Down Expand Up @@ -158,7 +158,7 @@ await context.render(
<body>
<h1>Hello, World!</h1>
</body>
</html>
</html>,
);
```

Expand Down Expand Up @@ -231,7 +231,7 @@ app.get(
},
(context) => {
context.text(StatusCode.OK, "Three!");
}
},
// ... etc
);
```
30 changes: 15 additions & 15 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ 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.
*
* @param middleware
*/
public use(...middleware: MageMiddleware[]): void {
this.router.use(...middleware);
this._router.use(...middleware);
}

/**
Expand All @@ -53,7 +53,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.all(routenameOrMiddleware, ...middleware);
this._router.all(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -67,7 +67,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.get(routenameOrMiddleware, ...middleware);
this._router.get(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -81,7 +81,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.post(routenameOrMiddleware, ...middleware);
this._router.post(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -95,7 +95,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.put(routenameOrMiddleware, ...middleware);
this._router.put(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -109,7 +109,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.delete(routenameOrMiddleware, ...middleware);
this._router.delete(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -123,7 +123,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.patch(routenameOrMiddleware, ...middleware);
this._router.patch(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -137,7 +137,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.options(routenameOrMiddleware, ...middleware);
this._router.options(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -151,7 +151,7 @@ export class MageApp {
routenameOrMiddleware: string | MageMiddleware,
...middleware: MageMiddleware[]
): void {
this.router.head(routenameOrMiddleware, ...middleware);
this._router.head(routenameOrMiddleware, ...middleware);
}

/**
Expand All @@ -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,
];
Expand All @@ -185,7 +185,7 @@ export class MageApp {
if (!matchResult.matchedMethod) {
middleware.push(
useMethodNotAllowed({
getAllowedMethods: () => this.router.getAvailableMethods(context),
getAllowedMethods: () => this._router.getAvailableMethods(context),
}),
);
}
Expand Down
53 changes: 34 additions & 19 deletions src/context.ts
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
}

/**
Expand All @@ -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");
}

/**
Expand All @@ -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");
}

/**
Expand All @@ -70,24 +85,24 @@ export class MageContext {
*/
public async render(status: StatusCode, body: VNode) {
const html = await renderToStringAsync(body);
this.response = new Response(`<!DOCTYPE html>${html}`, {
this._response = new Response(`<!DOCTYPE html>${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");
}

/**
* Sends an empty response with the provided status code
* @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,
});
}

Expand All @@ -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());
}
}
10 changes: 5 additions & 5 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ interface MatchResult {
* application.
*/
export class MageRouter {
private entries: RouterEntry[] = [];
private _entries: RouterEntry[] = [];

/**
* Match middleware for a given context.
Expand All @@ -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;
Expand Down Expand Up @@ -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 ?? []);

Expand All @@ -110,7 +110,7 @@ export class MageRouter {
* @param middleware
*/
public use(...middleware: MageMiddleware[]) {
this.entries.push({
this._entries.push({
middleware,
});
}
Expand Down Expand Up @@ -256,7 +256,7 @@ export class MageRouter {
? additionalMiddleware
: [routenameOrMiddleware, ...additionalMiddleware];

this.entries.push({
this._entries.push({
routename,
middleware,
methods,
Expand Down
20 changes: 15 additions & 5 deletions test-utils/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,34 @@ 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<Deno.NetAddr> | undefined;
private _app: MageApp = new MageApp();
private _server: Deno.HttpServer<Deno.NetAddr> | 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,
});
}

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();
}
}

0 comments on commit 900e186

Please sign in to comment.