Skip to content
This repository has been archived by the owner on Feb 11, 2025. It is now read-only.

Commit

Permalink
feat(core): add chain usage & tests
Browse files Browse the repository at this point in the history
  • Loading branch information
arctome committed Sep 24, 2021
1 parent 92dc00b commit 4d6ec88
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 25 deletions.
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ yarn add koaw-js
You can add offical plugins, here are some example,

```bash
yarn add koaw-plugin-markdown
yarn add koaw-plugin-markdown # Not developed Yet!
```

## Usage
Expand Down Expand Up @@ -52,18 +52,21 @@ import Koaw, { KoawRouter, cors } from "koaw-js";
addEventListener("fetch", (event) => {
const app = new Koaw(event);
const router = new KoawRouter();
app.use(cors(true));
// KoawRouter's handlers
router.get("/example", (ctx) => {
ctx.res.body = "hello example";
ctx.res.status = 200;
ctx.end();
});
// Actually inject middlewares in `Koaw` core
app.use(cors(true));
app.use(router.route());

event.respondWith(app.run());
});
```

## API Reference
> `Koaw` core and `KoawRouter` all support chain usage.
## API Reference

Expand Down Expand Up @@ -149,3 +152,15 @@ event.respondWith(app.run());
### cors

The function `cors` is just so simple, you can pass only `true`, and all CORS configuration will work as default. If you want additional config, you can refer [cors in express.js](https://www.npmjs.com/package/cors)

## Q & A

### Q: Why not continuous maintain `@arctome/worker-scaffold` ?

A: The reason is very simple. `WorkerScaffold` is based on `Response` type detection, every step you need construct a new `Response`, which needs a lot of code. Also, construct a `Response` is not an easy way for a Router package, plenty of detection, plenty of clone and re-construction, made the code of core very difficult to maintain. Therefore, I create this package to replace the "old way".

> Another reason is that I want to extract the plugins not indispensable. That will allow more plugins developed by community.
### Q: Performance ?

A: Not test for now. Will be added soon.
2 changes: 1 addition & 1 deletion lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ declare class Koaw {
run(): Promise<Response>;
}
export default Koaw;
export { KoawRouter, cors as KoawCORS };
export { KoawRouter, cors };
19 changes: 13 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,15 @@ class KoawRouter {
method,
handler: () => { },
});
return this;
}
verb(method, path, handler) {
this.stack.push({
path,
handler,
method,
});
return this;
}
compose(routes, path, ctx) {
let needReRoute = "";
Expand Down Expand Up @@ -745,7 +747,8 @@ class Koaw {
throw new TypeError("`Koaw` context has been modified and cannot make it a response");
if (!ctx.finished) {
ctx.finished = true;
ctx.res.body = ctx.res && ctx.res.body || "Resource Not Found by `koaw`";
ctx.res.body =
(ctx.res && ctx.res.body) || "Resource Not Found by `koaw`";
ctx.res.status = 404;
}
const resp = {
Expand All @@ -762,7 +765,7 @@ class Koaw {
}
const respInit = {
status: resp.status || 404,
headers: resp.headers
headers: resp.headers,
};
return new Response(resp.body, respInit);
}
Expand All @@ -774,7 +777,12 @@ class Koaw {
}
selfReturn(ctx, handler) {
return __awaiter(this, void 0, void 0, function* () {
yield handler(ctx);
try {
yield handler(ctx);
}
catch (e) {
throw e;
}
return ctx;
});
}
Expand All @@ -799,18 +807,17 @@ class Koaw {
return this.contextToResponse(this.ctx);
}
catch (e) {
if (e instanceof Error)
throw e;
this.ctx.res.body =
"Server Crashed, please try later or contact the admin of the website!";
if (this.options.debug && e instanceof Error) {
this.ctx.res.body = e.message;
}
this.ctx.res.status = 500;
this.ctx.end();
return this.contextToResponse(this.ctx);
}
});
}
}

export { cors as KoawCORS, KoawRouter, Koaw as default };
export { KoawRouter, cors, Koaw as default };
20 changes: 10 additions & 10 deletions lib/plugins/koaw-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ declare class KoawRouter {
stack: Array<KoawRoute>;
rewrite: Array<string>;
constructor();
get(path: string, handler: Function): void;
post(path: string, handler: Function): void;
delete(path: string, handler: Function): void;
put(path: string, handler: Function): void;
patch(path: string, handler: Function): void;
connect(path: string, handler: Function): void;
trace(path: string, handler: Function): void;
options(path: string, handler: Function): void;
all(path: string, handler: Function): void;
rewriteTo(origin: string, to: string, method?: string): void;
get(path: string, handler: Function): this;
post(path: string, handler: Function): this;
delete(path: string, handler: Function): this;
put(path: string, handler: Function): this;
patch(path: string, handler: Function): this;
connect(path: string, handler: Function): this;
trace(path: string, handler: Function): this;
options(path: string, handler: Function): this;
all(path: string, handler: Function): this;
rewriteTo(origin: string, to: string, method?: string): this;
private verb;
private compose;
route(): Function;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koaw-js",
"version": "0.0.1",
"version": "0.0.0",
"description": "Cloudflare Worker version of Koa web application framework, customized, well documented.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
12 changes: 8 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ class Koaw {
ctx: ApplicationContext,
handler: Function
): Promise<ApplicationContext> {
await handler(ctx);
try {
await handler(ctx);
} catch (e) {
throw e;
}
return ctx;
}

Expand All @@ -87,18 +91,18 @@ class Koaw {
}

return this.contextToResponse(this.ctx);
} catch (e: unknown) {
if (e instanceof Error) throw e;
} catch (e) {
this.ctx.res.body =
"Server Crashed, please try later or contact the admin of the website!";
if (this.options.debug && e instanceof Error) {
this.ctx.res.body = e.message;
}
this.ctx.res.status = 500;
this.ctx.end();
return this.contextToResponse(this.ctx);
}
}
}

export default Koaw;
export { KoawRouter, cors as KoawCORS };
export { KoawRouter, cors };
2 changes: 2 additions & 0 deletions src/plugins/koaw-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class KoawRouter {
method,
handler: () => {},
});
return this;
}
// Handler of single method
private verb(method: string, path: string, handler: Function) {
Expand All @@ -69,6 +70,7 @@ class KoawRouter {
handler,
method,
});
return this;
}

private compose(
Expand Down
28 changes: 28 additions & 0 deletions test/base.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,32 @@ describe("Testing Koaw's Basic Features ", () => {
const res = await mf.dispatchFetch("http://localhost:8787/favicon.ico");
expect(res.status).toBe(404);
});
test("correctly catch errors in middleware", async () => {
const mf = new Miniflare({
script: testSuite(`
app.use(ctx => {
throw new Error("crash")
})
`),
});
const res = await mf.dispatchFetch("http://localhost:8787/favicon.ico");
expect(res.status).toBe(500);
});
test("`Koaw` supports chain usage", async () => {
const mf = new Miniflare({
script: testSuite(`
app.use(ctx => {
ctx.res.body = 'first'
}).use(ctx => {
ctx.res.body = 'second'
ctx.end();
}).use(ctx => {
ctx.res.body = 'third'
})
`),
});
const res = await mf.dispatchFetch("http://localhost:8787/hello");
let body = await res.text();
expect(body).toBe("second");
});
});
18 changes: 18 additions & 0 deletions test/plugins/router.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,22 @@ describe("Testing Koaw's Router Features ", () => {
let body = await res.text();
expect(body).toBe("not-sync");
});
test("`KoawRouter` works in chain usage", async () => {
const mf = new Miniflare({
script: testSuite(
`
const router = new KoawRouter();
router.rewriteTo('/base/sync', '/base/not-sync').get('/base/not-sync', (ctx, match) => {
ctx.res.body = 'not-sync'
ctx.end();
})
app.use(router.route())
`,
true
),
});
const res = await mf.dispatchFetch("http://localhost:8787/base/sync");
let body = await res.text();
expect(body).toBe("not-sync");
});
});

0 comments on commit 4d6ec88

Please sign in to comment.