From e969943ea6edcb38cbdca1f27be40d9c95f7794d Mon Sep 17 00:00:00 2001 From: Sebastien Ringrose Date: Thu, 27 Apr 2023 11:30:22 +0100 Subject: [PATCH 1/2] Update README.md --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cd663be6..4f7dbb29 100644 --- a/README.md +++ b/README.md @@ -83,19 +83,22 @@ server.listen(7777, () => console.log("Peko server started - let's go!")); PR to add your project 🙌 -### [iiisun.art](https://iiisun.art) - artistic storefront [source](https://github.com/sebringrose/third-sun/blob/main/server.ts) +### [iiisun.art](https://iiisun.art) - artistic storefront - **Stack:** React, ImageMagick_deno - **Features:** CI resized-image precaching, Gelato & Stripe integrations, Parallax CSS -- **Note:** [lit-html](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html) and [es6-string-css](https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css) VS Code extensions recommended. +- [source](https://github.com/sebringrose/third-sun/blob/main/server.ts) -### [shineponics.org](https://shineponics.org) - smart-farming PaaS [source](https://github.com/shine-systems/shineponics/blob/main/server.ts) +### [shineponics.org](https://shineponics.org) - smart-farming PaaS - **Stack:** React, Google Cloud Platform - **Features:** Google Sheet analytics, GCP email list, Markdown rendering -- **Note:** [lit-html](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html) and [es6-string-css](https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css) VS Code extensions recommended. +- [source](https://github.com/shine-systems/shineponics/blob/main/server.ts) -### [peko-auth.deno.dev](https://peko-auth.deno.dev) - basic authentication demo [source](https://github.com/sebringrose/peko/blob/main/examples/auth/app.ts) +### [peko-auth.deno.dev](https://peko-auth.deno.dev) - basic authentication demo - **Stack:** HTML5 - **Features:** JWT-based auth +- [source](https://github.com/sebringrose/peko/blob/main/examples/auth/app.ts) + +**Note:** [lit-html](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html) and [es6-string-css](https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css) VS Code extensions recommended.

Deployment

From 1fdafe901bd08689f030c18d0d9c8a0a94757a27 Mon Sep 17 00:00:00 2001 From: Sebastien Ringrose Date: Thu, 27 Apr 2023 12:14:57 +0100 Subject: [PATCH 2/2] feat: server http method aliases --- lib/utils/Router.ts | 156 ++++++++++++++++++++++++------------- tests/server_test.ts | 4 +- tests/utils/Router_test.ts | 33 +++++++- 3 files changed, 133 insertions(+), 60 deletions(-) diff --git a/lib/utils/Router.ts b/lib/utils/Router.ts index c874c30d..29a28cfd 100644 --- a/lib/utils/Router.ts +++ b/lib/utils/Router.ts @@ -23,62 +23,108 @@ export class Router { * @param route: Route | Route["path"] * @param arg2?: Partial | Middleware | Middleware[], * @param arg3?: Handler - * @returns number - Router.length + * @returns route: Route - added route object */ - addRoute(route: Route): number - addRoute(route: Route["path"], data: Handler | Partial): number - addRoute(route: Route["path"], middleware: Middleware | Middleware[], handler: Handler): number - addRoute( - arg1: Route | Route["path"], - arg2?: Partial | Middleware | Middleware[], - arg3?: Handler - ): number { - const routeObj: Partial = typeof arg1 !== "string" - ? arg1 - : arguments.length === 2 - ? typeof arg2 === "function" - ? { path: arg1, handler: arg2 as Handler } - : { path: arg1, ...arg2 as Partial } - : { path: arg1, middleware: arg2 as Middleware | Middleware[], handler: arg3 } - - if (this.routes.find(existing => existing.path === routeObj.path)) { - throw new Error(`Route with path ${routeObj.path} already exists!`) - } - - return this.routes.push(Router.applyDefaults(routeObj)) - } - - /** - * Add Routes - * @param routes: Route[] - middleware can be Middlewares or Middleware - * @returns number - routes.length - */ - addRoutes(routes: Route[]): number { - routes.forEach(route => this.addRoute(route)) - return this.routes.length - } - - /** - * Remove Route from Peko server - * @param route: Route["path"] of route to remove - * @returns - */ - removeRoute(route: Route["path"]): number { - const routeToRemove = this.routes.find(r => r.path === route) - if (routeToRemove) { - this.routes.splice(this.routes.indexOf(routeToRemove), 1) - } - - return this.routes.length + addRoute(route: Route): Route + addRoute(route: Route["path"], data: Handler | Partial): Route + addRoute(route: Route["path"], middleware: Middleware | Middleware[], handler: Handler): Route + addRoute( + arg1: Route | Route["path"], + arg2?: Partial | Middleware | Middleware[], + arg3?: Handler + ): Route { + const routeObj: Partial = typeof arg1 !== "string" + ? arg1 + : arguments.length === 2 + ? typeof arg2 === "function" + ? { path: arg1, handler: arg2 as Handler } + : { path: arg1, ...arg2 as Partial } + : { path: arg1, middleware: arg2 as Middleware | Middleware[], handler: arg3 } + + if (this.routes.find(existing => existing.path === routeObj.path)) { + throw new Error(`Route with path ${routeObj.path} already exists!`) } - - /** - * Remove Routes - * @param routes: Route["path"] of routes to remove - * @returns - */ - removeRoutes(routes: Route["path"][]): number { - routes.forEach(route => this.removeRoute(route)) - return this.routes.length + + const fullRoute = Router.applyDefaults(routeObj) + this.routes.push(fullRoute) + + return fullRoute + } + /** + * Add Route with method "GET" (same as default addRoute behaviour) + * @returns route: Route - added route object + */ + get: typeof this.addRoute = function() { + // @ts-ignore supply overload args + const newRoute = this.addRoute(...arguments) + newRoute.method = "GET" + return newRoute + } + + /** + * Add Route with method "POST" + * @returns route: Route - added route object + */ + post: typeof this.addRoute = function() { + // @ts-ignore supply overload args + const newRoute = this.addRoute(...arguments) + newRoute.method = "POST" + return newRoute + } + + /** + * Add Route with method "PUT" + * @returns route: Route - added route object + */ + put: typeof this.addRoute = function() { + // @ts-ignore supply overload args + const newRoute = this.addRoute(...arguments) + newRoute.method = "PUT" + return newRoute + } + + /** + * Add Route with method "DELETE" + * @returns route: Route - added route object + */ + delete: typeof this.addRoute = function() { + // @ts-ignore supply overload args + const newRoute = this.addRoute(...arguments) + newRoute.method = "DELETE" + return newRoute + } + + /** + * Add Routes + * @param routes: Route[] - middleware can be Middlewares or Middleware + * @returns number - routes.length + */ + addRoutes(routes: Route[]): number { + routes.forEach(route => this.addRoute(route)) + return this.routes.length + } + + /** + * Remove Route from Peko server + * @param route: Route["path"] of route to remove + * @returns + */ + removeRoute(route: Route["path"]): number { + const routeToRemove = this.routes.find(r => r.path === route) + if (routeToRemove) { + this.routes.splice(this.routes.indexOf(routeToRemove), 1) } + + return this.routes.length + } + + /** + * Remove Routes + * @param routes: Route["path"] of routes to remove + * @returns + */ + removeRoutes(routes: Route["path"][]): number { + routes.forEach(route => this.removeRoute(route)) + return this.routes.length + } } \ No newline at end of file diff --git a/tests/server_test.ts b/tests/server_test.ts index 82c0f04a..29756d21 100644 --- a/tests/server_test.ts +++ b/tests/server_test.ts @@ -15,9 +15,9 @@ Deno.test("SERVER", async (t) => { server.addRoute({ path: "/route", handler: testHandler }) server.addRoute("/anotherRoute", { handler: testHandler }) server.addRoute("/anotherNotherRoute", testHandler) - const routesLength = server.addRoute("/anotherNotherNotherRoute", testMiddleware2, testHandler) + server.addRoute("/anotherNotherNotherRoute", testMiddleware2, testHandler) - assert(routesLength === 4 && server.routes.length === 4) + assert(server.routes.length === 4) const request = new Request("http://localhost:7777/route") const anotherRequest = new Request("http://localhost:7777/anotherRoute") diff --git a/tests/utils/Router_test.ts b/tests/utils/Router_test.ts index 9be95656..552457b2 100644 --- a/tests/utils/Router_test.ts +++ b/tests/utils/Router_test.ts @@ -6,16 +6,16 @@ import { testHandler, } from "../mocks/middleware.ts" -Deno.test("SERVER", async (t) => { +Deno.test("ROUTER", async (t) => { const router = new Router() await t.step("routes added with full route and string arg options", () => { router.addRoute({ path: "/route", handler: testHandler }) router.addRoute("/anotherRoute", { handler: testHandler }) router.addRoute("/anotherNotherRoute", testHandler) - const routesLength = router.addRoute("/anotherNotherNotherRoute", testMiddleware1, testHandler) + const finalRoute = router.addRoute("/anotherNotherNotherRoute", testMiddleware1, testHandler) - assert(routesLength === 4 && router.routes.length === 4) + assert(finalRoute.path === "/anotherNotherNotherRoute" && router.routes.length === 4) }) await t.step("routes removed", () => { @@ -43,4 +43,31 @@ Deno.test("SERVER", async (t) => { assert(!aRouter.routes.find(route => route.path === "/route")) assert(aRouter.routes.length === 2) }) + + await t.step ("http shorthand methods work correctly", () => { + const router = new Router() + + const getRoute = router.get({ + path: "/get", + handler: () => new Response("GET") + }) + const postRoute = router.post({ + path: "/post", + handler: () => new Response("POST") + }) + const putRoute =router.put({ + path: "/put", + handler: () => new Response("PUT") + }) + const deleteRoute = router.delete({ + path: "/delete", + handler: () => new Response("DELETE") + }) + + assert(router.routes.length === 4) + assert(getRoute.method === "GET") + assert(postRoute.method === "POST") + assert(putRoute.method === "PUT") + assert(deleteRoute.method === "DELETE") + }) })