Skip to content

Commit dbbc6b1

Browse files
authored
Merge pull request #102 from Dashron/fix/routerTypes
Fix/router types
2 parents 459994d + 2fce876 commit dbbc6b1

19 files changed

+75
-172
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Roads is a simple web framework. It's similar to Express.js, but has some very i
4242
- [Parsing request bodies](#parsing-request-bodies)
4343
- [Parse Body Context](#parse-body-context)
4444
- [Remove trailing slash](#remove-trailing-slash)
45-
- [Basic router](#basic-router)
45+
- [Router](#router)
4646
- [applyMiddleware(road: *Road*)](#applymiddlewareroad-road)
4747
- [addRoute(method: *string*, path: *string*, fn: *function*)](#addroutemethod-string-path-string-fn-function)
4848
- [addRouteFile(filePath: *string*, prefix?: *string*)](#addroutefilefilepath-string-prefix-string)
@@ -547,8 +547,8 @@ var road = new Road();
547547
road.use(RemoveTrailingSlashMiddleware.middleware);
548548
```
549549
550-
## Basic router
551-
This is a basic router middleware for roads. It allows you to easily attach functionality to HTTP methods and paths.
550+
## Router
551+
This is a Router middleware for roads. It allows you to easily attach functionality to HTTP methods and paths.
552552
553553
Here's how you use it.
554554

example/ts/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
public/*
1+
public/*
2+
types/*

example/ts/src/client.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* This file is an example of using roads router in the client
77
*/
88

9-
import { Road, RoadsPJAX, ParseBodyMiddleware, BasicRouterMiddleware, CookieMiddleware, Request } from 'roads';
9+
import { Road, RoadsPJAX, ParseBodyMiddleware, RouterMiddleware, CookieMiddleware, Request } from 'roads';
1010
import applyPublicRotues from './routes/applyPublicRoutes';
1111
import emptyTo404 from './middleware/emptyTo404';
1212

@@ -25,7 +25,7 @@ road.use(ParseBodyMiddleware.middleware);
2525
road.use(CookieMiddleware.buildClientMiddleware(document));
2626
pjax.register();
2727
pjax.registerAdditionalElement(document.getElementById('home') as HTMLAnchorElement);
28-
const router = new BasicRouterMiddleware.BasicRouter(road);
28+
const router = new RouterMiddleware.Router(road);
2929
applyPublicRotues(router);
3030

3131
const testRequest = new Request(false, 'localhost', 8081);

example/ts/src/routes/applyPrivateRoutes.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import * as fs from 'fs';
1010
import { CookieContext } from 'roads/types/middleware/cookieMiddleware';
1111
import { StoreValsContext } from 'roads/types/middleware/storeVals';
12-
import { BasicRouterMiddleware, Response } from 'roads';
12+
import { RouterMiddleware, Response } from 'roads';
1313
const TITLE_KEY = 'page-title';
1414

1515
/**
@@ -19,8 +19,8 @@ const TITLE_KEY = 'page-title';
1919
*
2020
* @param {SimpleRouter} router - The router that the routes will be added to
2121
*/
22-
export default function applyPrivateRotues(router: BasicRouterMiddleware.BasicRouter): void {
23-
router.addRoute('GET', '/private', async function (this: CookieContext & StoreValsContext) {
22+
export default function applyPrivateRotues(router: RouterMiddleware.Router<StoreValsContext>): void {
23+
router.addRoute<CookieContext>('GET', '/private', async function () {
2424
this.storeVal(TITLE_KEY, 'Private Resource');
2525
this.setCookie('private_cookie', 'foo', {
2626
httpOnly: true
@@ -36,13 +36,13 @@ export default function applyPrivateRotues(router: BasicRouterMiddleware.BasicRo
3636
<a href="/" data-roads="link">home</a>!<br />`);
3737
});
3838

39-
router.addRoute('GET', '/privateJSON', async function (this: StoreValsContext, ) {
39+
router.addRoute('GET', '/privateJSON', async function () {
4040
this.storeVal('ignoreLayout', true);
4141
return new Response(JSON.stringify({'private-success': true}));
4242
});
4343

4444
// eslint-disable-next-line @typescript-eslint/no-unused-vars
45-
router.addRoute('GET', 'client.js', async function (this: StoreValsContext, url, body, headers) {
45+
router.addRoute('GET', 'client.js', async function (url, body, headers) {
4646
this.storeVal('ignoreLayout', true);
4747
// In the real world the body of the response should be created from a template engine.
4848
return new Response(fs.readFileSync(`${__dirname }/../../../public/client.js`).toString('utf-8'), 200, {

example/ts/src/routes/applyPublicRoutes.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* This file is an example of how to assign some public routes to a roads server
77
*/
88

9-
import { Response, BasicRouterMiddleware } from 'roads';
9+
import { Response, RouterMiddleware } from 'roads';
1010
const TITLE_KEY = 'page-title';
1111

1212
import { ParseBodyContext } from 'roads/types/middleware/parseBody';
@@ -24,8 +24,8 @@ interface ExampleRequestBody {
2424
*
2525
* @param {SimpleRouter} router - The router that the routes will be added to
2626
*/
27-
export default function applyPublicRotues(router: BasicRouterMiddleware.BasicRouter): void {
28-
router.addRoute('GET', '/', async function (this: StoreValsContext) {
27+
export default function applyPublicRotues(router: RouterMiddleware.Router<StoreValsContext>): void {
28+
router.addRoute('GET', '/', async function () {
2929
this.storeVal(TITLE_KEY, 'Root Resource');
3030

3131
// In the real world the body of the response should be created from a template engine.
@@ -39,7 +39,7 @@ export default function applyPublicRotues(router: BasicRouterMiddleware.BasicRou
3939
});
4040
});
4141

42-
router.addRoute('GET', '/public', async function (this: StoreValsContext & CookieContext) {
42+
router.addRoute<CookieContext>('GET', '/public', async function () {
4343
this.storeVal(TITLE_KEY, 'Public Resource');
4444
console.log('Here are all cookies accessible to this code: ', this.getCookies());
4545
console.log('Cookies are not set until you access the private route.');
@@ -59,7 +59,7 @@ export default function applyPublicRotues(router: BasicRouterMiddleware.BasicRou
5959
});
6060

6161
// eslint-disable-next-line @typescript-eslint/no-unused-vars
62-
router.addRoute('POST', '/postdata', async function (this: ParseBodyContext<ExampleRequestBody>, url, body, headers) {
62+
router.addRoute<ParseBodyContext<ExampleRequestBody>>('POST', '/postdata', async function (url, body, headers) {
6363
console.log(`You sent the message:${this.body?.message}`);
6464
this.ignore_layout = true;
6565
return new Response('', 302, { location: '/public' });

example/ts/src/server.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { Road, Response, RemoveTrailingSlashMiddleware, CookieMiddleware,
10-
StoreValsMiddleware, ParseBodyMiddleware, BasicRouterMiddleware } from 'roads';
10+
StoreValsMiddleware, ParseBodyMiddleware, RouterMiddleware } from 'roads';
1111

1212
import { Server } from 'roads-server';
1313
import addLayout from './middleware/addLayout';
@@ -28,7 +28,7 @@ road.use(StoreValsMiddleware.middleware);
2828
road.use(addLayout);
2929
road.use(ParseBodyMiddleware.middleware);
3030

31-
const router = new BasicRouterMiddleware.BasicRouter(road);
31+
const router = new RouterMiddleware.Router(road);
3232
applyPublicRotues(router);
3333
applyPrivateRoutes(router);
3434
road.use(emptyTo404);

example/ts/types/build.d.ts

-8
This file was deleted.

example/ts/types/buildClient.d.ts

-9
This file was deleted.

example/ts/types/client.d.ts

-8
This file was deleted.

example/ts/types/middleware/addLayout.d.ts

-22
This file was deleted.

example/ts/types/middleware/emptyTo404.d.ts

-19
This file was deleted.

example/ts/types/routes/applyPrivateRoutes.d.ts

-16
This file was deleted.

example/ts/types/routes/applyPublicRoutes.d.ts

-16
This file was deleted.

example/ts/types/server.d.ts

-8
This file was deleted.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "roads",
3-
"version": "8.0.0-alpha.1",
3+
"version": "8.0.0-alpha.2",
44
"author": {
55
"name": "Aaron Hedges",
66
"email": "[email protected]",

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ export * as ParseBodyMiddleware from './middleware/parseBody';
1111
export * as RerouteMiddleware from './middleware/reroute';
1212
export * as StoreValsMiddleware from './middleware/storeVals';
1313
export * as ModifiedSinceMiddleware from './middleware/modifiedSince';
14-
export * as BasicRouterMiddleware from './middleware/basicRouter';
14+
export * as RouterMiddleware from './middleware/router';

src/middleware/basicRouter.ts src/middleware/router.ts

+22-20
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/**
2-
* basicRouter.ts
2+
* router.ts
33
* Copyright(c) 2021 Aaron Hedges <[email protected]>
44
* MIT Licensed
55
*
6-
* This is a basic router middleware for roads.
6+
* This is a router middleware for roads.
77
* It allows you to easily attach functionality to HTTP methods and paths.
88
*/
99

@@ -15,7 +15,7 @@ import { NextCallback, RequestChain } from '../core/requestChain';
1515

1616

1717
export interface Route<ContextType extends Context> {
18-
(this: ContextType, method: string, path: BasicRouterURL, body: string,
18+
(this: ContextType, method: string, path: RouterURL, body: string,
1919
headers: IncomingHeaders, next: NextCallback): Promise<Response>
2020
}
2121

@@ -25,14 +25,14 @@ interface RouteDetails {
2525
method: string
2626
}
2727

28-
export interface BasicRouterURL extends ReturnType<typeof parse> {
28+
export interface RouterURL extends ReturnType<typeof parse> {
2929
args?: Record<string, string | number>
3030
}
3131
/**
32-
* This is a basic router middleware for roads.
33-
* You can assign functions to url paths, and those paths can have some very basic variable templating
32+
* This is a router middleware for roads.
33+
* You can assign functions to url paths, and those paths can have variable templating
3434
*
35-
* Templating is basic. Each URI is considered to be a series of "path parts" separated by slashes.
35+
* There are only a couple of template options. Each URI is considered to be a series of "path parts" separated by slashes.
3636
* If a path part starts with a #, it is assumed to be a numeric variable. Non-numbers will not match this route
3737
* If a path part starts with a $, it is considered to be an alphanumeric variabe.
3838
* All non-slash values will match this route.
@@ -43,13 +43,13 @@ export interface BasicRouterURL extends ReturnType<typeof parse> {
4343
* /users/#user_id will match /users/12345, not /users/abcde. If a request is made to /users/12345
4444
* the route's requestUrl object will contain { args: {user_id: 12345}} along with all other url object values
4545
*
46-
* @name BasicRouter
46+
* @name Router
4747
*/
48-
export class BasicRouter {
48+
export class Router<RouterContextType extends Context> {
4949
protected _routes: RouteDetails[];
5050

5151
/**
52-
* @param {Road} [road] - The road that will receive the BasicRouter middleware
52+
* @param {Road} [road] - The road that will receive the Router middleware
5353
*/
5454
constructor (road?: Road) {
5555
this._routes = [];
@@ -63,15 +63,15 @@ export class BasicRouter {
6363
* If you don't provide a road to the SimpleRouter constructor, your routes will not be executed.
6464
* If you have reason not to assign the road off the bat, you can assign it later with this function.
6565
*
66-
* @param {Road} road - The road that will receive the BasicRouter middleware
66+
* @param {Road} road - The road that will receive the Router middleware
6767
*/
6868
applyMiddleware (road: Road): void {
6969
// We need to alias because "this" for the middleware function must
70-
// be the this applied by road.use, not the BasicRouter
70+
// be the this applied by road.use, not the Router
7171
// eslint-disable-next-line @typescript-eslint/no-this-alias
7272
const _self = this;
7373

74-
// We do this to ensure we have access to the BasicRouter once we lose this due to road's context
74+
// We do this to ensure we have access to the Router once we lose this due to road's context
7575
road.use((function (request_method, request_url, request_body, request_headers, next) {
7676
return _self._middleware.call(this, _self._routes, request_method, request_url,
7777
request_body, request_headers, next);
@@ -82,7 +82,7 @@ export class BasicRouter {
8282
* This is where you want to write the majority of your webservice. The `fn` parameter should contain
8383
* the actions you want to perform when a certain `path` and HTTP `method` are accessed via the `road` object.
8484
*
85-
* The path supports a very basic templating system. The values inbetween each slash can be interpreted
85+
* The path supports a templating system. The values inbetween each slash can be interpreted
8686
* in one of three ways
8787
* - If a path part starts with a #, it is assumed to be a numeric variable. Non-numbers will not match this route
8888
* - If a path part starts with a $, it is considered to be an alphanumeric variabe. All non-slash values
@@ -99,8 +99,10 @@ export class BasicRouter {
9999
* @param {(string|array)} paths - One or many URL paths that will trigger the provided function
100100
* @param {function} fn - The function containing all of your route logic
101101
*/
102-
addRoute<ContextType extends Context> (
103-
method: string, paths: string | string[], fn: Route<ContextType> | Route<ContextType>[]
102+
addRoute<RouteContextType extends Context> (
103+
method: string,
104+
paths: string | string[],
105+
fn: Route<RouterContextType & RouteContextType> | Route<RouterContextType & RouteContextType>[]
104106
): void {
105107
if (!Array.isArray(paths)) {
106108
paths = [paths];
@@ -201,7 +203,7 @@ export class BasicRouter {
201203
/**
202204
* Checks to see if the route matches the request, and if true assigns any applicable url variables and returns the route
203205
*
204-
* @param {object} route - Route object from this basic router class
206+
* @param {object} route - Route object from this router class
205207
* @param {object} route.method - HTTP method associated with this route
206208
* @param {object} route.path - HTTP path associated with this route
207209
* @param {object} request_url - Parsed HTTP request url
@@ -240,14 +242,14 @@ function compareRouteAndApplyArgs (route: {method: string, path: string}, reques
240242
}
241243

242244
// TODO: get rid of this `as`
243-
applyArg(request_url as BasicRouterURL, template_part.substring(1), Number(actual_part));
245+
applyArg(request_url as RouterURL, template_part.substring(1), Number(actual_part));
244246
continue;
245247
}
246248

247249
if (template_part[0] === '$') {
248250
// $ templates accept any non-slash alphanumeric character
249251
// TODO: get rid of this `as`
250-
applyArg(request_url as BasicRouterURL, template_part.substring(1), String(actual_part));
252+
applyArg(request_url as RouterURL, template_part.substring(1), String(actual_part));
251253
// Continue so that
252254
continue;
253255
}
@@ -270,7 +272,7 @@ function compareRouteAndApplyArgs (route: {method: string, path: string}, reques
270272
* @param {string} template_part - The template variable
271273
* @param {*} actual_part - The url value
272274
*/
273-
function applyArg(request_url: BasicRouterURL, template_part: string, actual_part: string | number): void {
275+
function applyArg(request_url: RouterURL, template_part: string, actual_part: string | number): void {
274276
if (typeof(request_url.args) === 'undefined') {
275277
request_url.args = {};
276278
}

0 commit comments

Comments
 (0)