From 654e8c78bdd29fe992fbf74711a400b2b9ec3103 Mon Sep 17 00:00:00 2001 From: ilikejames Date: Tue, 8 Jan 2019 18:12:48 +0000 Subject: [PATCH 01/14] Add typescript definition files --- .github/workflows/ci.yml | 11 +++- index.d.ts | 138 +++++++++++++++++++++++++++++++++++++++ package.json | 7 +- test/type-check.ts | 61 +++++++++++++++++ tsconfig.json | 22 +++++++ 5 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 index.d.ts create mode 100644 test/type-check.ts create mode 100644 tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b52cfc9..5062ae8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,27 +34,32 @@ jobs: - name: Node.js 0.8 node-version: "0.8" npm-i: mocha@2.5.3 supertest@1.1.0 - npm-rm: nyc + npm-rm: nyc typescript @types/node - name: Node.js 0.10 node-version: "0.10" npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-rm: typescript @types/node - name: Node.js 0.12 node-version: "0.12" npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-rm: typescript @types/node - name: io.js 1.x node-version: "1.8" npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-rm: typescript @types/node - name: io.js 2.x node-version: "2.5" npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-rm: typescript @types/node - name: io.js 3.x node-version: "3.3" npm-i: mocha@3.5.3 nyc@10.3.2 supertest@2.0.0 + npm-rm: typescript @types/node - name: Node.js 4.x node-version: "4.9" @@ -161,6 +166,10 @@ jobs: if: steps.list_env.outputs.eslint != '' run: npm run lint + - name: Test types + if: steps.list_env.outputs.typescript != '' + run: npm run test-types + - name: Collect code coverage uses: coverallsapp/github-action@master if: steps.list_env.outputs.nyc != '' diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..858880d --- /dev/null +++ b/index.d.ts @@ -0,0 +1,138 @@ +export = Router; + +declare namespace Router { + + export interface RouterOptions { + strict?: boolean; + caseSensitive?: boolean; + mergeParams?: boolean; + } + + interface IncommingRequest { + url: string, + method: string, + originalUrl?: string, + params?: any; + } + + interface RoutedRequest extends IncommingRequest { + baseUrl: string, + next?: NextFunction, + route?: IRoute + } + + type RequestParamHandler = (req: IncommingRequest, res: any, next: NextFunction, value: any, name: string) => any; + + interface RouteHandler { + // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 + (req: RoutedRequest, res: any, next: NextFunction): any; + } + + interface RequestHandler { + // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 + (req: IncommingRequest, res: any, next: NextFunction): any; + } + + + interface NextFunction { + // tslint:disable-next-line callable-types (In ts2.1 it thinks the type alias has no call signatures) + (err?: any): void; + } + + type ErrorRequestHandler = (err: any, req: IncommingRequest, res: any, next: NextFunction) => any; + + type PathParams = string | RegExp | Array; + + type RequestHandlerParams = RouteHandler | ErrorRequestHandler | Array; + + interface IRouterMatcher { + (path: PathParams, ...handlers: RouteHandler[]): T; + (path: PathParams, ...handlers: RequestHandlerParams[]): T; + } + + interface IRouterHandler { + (...handlers: RouteHandler[]): T; + (...handlers: RequestHandlerParams[]): T; + } + + interface IRouter { + /** + * Map the given param placeholder `name`(s) to the given callback(s). + * + * Parameter mapping is used to provide pre-conditions to routes + * which use normalized placeholders. For example a _:user_id_ parameter + * could automatically load a user's information from the database without + * any additional code, + * + * The callback uses the samesignature as middleware, the only differencing + * being that the value of the placeholder is passed, in this case the _id_ + * of the user. Once the `next()` function is invoked, just like middleware + * it will continue on to execute the route, or subsequent parameter functions. + * + * app.param('user_id', function(req, res, next, id){ + * User.find(id, function(err, user){ + * if (err) { + * next(err); + * } else if (user) { + * req.user = user; + * next(); + * } else { + * next(new Error('failed to load user')); + * } + * }); + * }); + */ + param(name: string, handler: RequestParamHandler): this; + + /** + * Alternatively, you can pass only a callback, in which case you have the opportunity to alter the app.param() + * + * @deprecated since version 4.11 + */ + param(callback: (name: string, matcher: RegExp) => RequestParamHandler): this; + + /** + * Special-cased "all" method, applying the given route `path`, + * middleware, and callback to _every_ HTTP method. + */ + all: IRouterMatcher; + + get: IRouterMatcher; + post: IRouterMatcher; + put: IRouterMatcher; + delete: IRouterMatcher; + patch: IRouterMatcher; + options: IRouterMatcher; + head: IRouterMatcher; + + use: IRouterHandler & IRouterMatcher; + + handle: RequestHandler; + + route(prefix: PathParams): IRoute; + /** + * Stack of configured routes + */ + stack: any[]; + } + + interface IRoute { + path: string; + stack: any; + all: IRouterHandler; + get: IRouterHandler; + post: IRouterHandler; + put: IRouterHandler; + delete: IRouterHandler; + patch: IRouterHandler; + options: IRouterHandler; + head: IRouterHandler; + } + + interface RouterConstructor extends IRouter { + new(options?: RouterOptions): IRouter & RequestHandler; + } + +} + +declare var Router: Router.RouterConstructor; diff --git a/package.json b/package.json index 2495c71..7f294af 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "utils-merge": "1.0.1" }, "devDependencies": { + "@types/node": "^10.0.0", "after": "0.8.2", "eslint": "7.26.0", "eslint-plugin-markdown": "2.1.0", @@ -25,15 +26,18 @@ "mocha": "8.4.0", "nyc": "15.1.0", "safe-buffer": "5.2.1", - "supertest": "6.1.3" + "supertest": "6.1.3", + "typescript": "^2.9.2" }, "files": [ "lib/", "LICENSE", "HISTORY.md", "README.md", + "index.d.ts", "index.js" ], + "types": "index.d.ts", "engines": { "node": ">= 0.8" }, @@ -42,6 +46,7 @@ "test": "mocha --reporter spec --bail --check-leaks test/", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc --reporter=text npm test", + "test-types": "tsc --project tsconfig.json --noEmit", "version": "node scripts/version-history.js && git add HISTORY.md" } } diff --git a/test/type-check.ts b/test/type-check.ts new file mode 100644 index 0000000..9eb874e --- /dev/null +++ b/test/type-check.ts @@ -0,0 +1,61 @@ +import { createServer, IncomingMessage, ServerResponse } from 'http'; +import { + default as Router, + RouterOptions, + IncommingRequest, + RouteHandler, + IRoute, + NextFunction, + RoutedRequest +} from '..'; + + +const options: RouterOptions = { + strict: false, + caseSensitive: false, + mergeParams: false +}; + +const r = new Router(); +const router = new Router(options); +const routerHandler: RouteHandler = (req: IncommingRequest, res: any, next: NextFunction) => {}; + +router.get('/', routerHandler); +router.post('/', routerHandler); +router.delete('/', routerHandler); +router.patch('/', routerHandler); +router.options('/', routerHandler); +router.head('/', routerHandler); + +// param +router.param('user_id', (req, res, next, id) => {}); + +// middleware +router.use((req, res, next) => { + next(); +}); + +const api: IRoute = router.route('/api/'); + +router.route('/') +.all((req: RoutedRequest, res: any, next: NextFunction) => { + next(); +}) +.get((req, res) => { + // do nothing +}); + + +// test router handling + +var server = createServer(function(req: IncomingMessage, res: ServerResponse) { + router(req as IncommingRequest, res, (err: any) => { + // + }) + router.handle(req as Router.IncommingRequest, res, (err: any) => { + // + }) +}) + + + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9e23537 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "esModuleInterop": true, + "noImplicitAny": false, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "types": ["node"], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "include": [ + "test/**/*" + ], + "files": [ + "index.d.ts" + ] +} From ba7e63b05ee6038a74025a0af150c8e3cef63d0d Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 17:56:59 +0300 Subject: [PATCH 02/14] fix: fix the IncommingRequest typo --- index.d.ts | 10 +++++----- package.json | 2 +- test/type-check.ts | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/index.d.ts b/index.d.ts index 858880d..a2add11 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,20 +8,20 @@ declare namespace Router { mergeParams?: boolean; } - interface IncommingRequest { + interface IncomingRequest { url: string, method: string, originalUrl?: string, params?: any; } - interface RoutedRequest extends IncommingRequest { + interface RoutedRequest extends IncomingRequest { baseUrl: string, next?: NextFunction, route?: IRoute } - type RequestParamHandler = (req: IncommingRequest, res: any, next: NextFunction, value: any, name: string) => any; + type RequestParamHandler = (req: IncomingRequest, res: any, next: NextFunction, value: any, name: string) => any; interface RouteHandler { // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 @@ -30,7 +30,7 @@ declare namespace Router { interface RequestHandler { // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: IncommingRequest, res: any, next: NextFunction): any; + (req: IncomingRequest, res: any, next: NextFunction): any; } @@ -39,7 +39,7 @@ declare namespace Router { (err?: any): void; } - type ErrorRequestHandler = (err: any, req: IncommingRequest, res: any, next: NextFunction) => any; + type ErrorRequestHandler = (err: any, req: IncomingRequest, res: any, next: NextFunction) => any; type PathParams = string | RegExp | Array; diff --git a/package.json b/package.json index 7f294af..e023a22 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "nyc": "15.1.0", "safe-buffer": "5.2.1", "supertest": "6.1.3", - "typescript": "^2.9.2" + "typescript": "^4.2.4" }, "files": [ "lib/", diff --git a/test/type-check.ts b/test/type-check.ts index 9eb874e..e1dee14 100644 --- a/test/type-check.ts +++ b/test/type-check.ts @@ -2,7 +2,7 @@ import { createServer, IncomingMessage, ServerResponse } from 'http'; import { default as Router, RouterOptions, - IncommingRequest, + IncomingRequest, RouteHandler, IRoute, NextFunction, @@ -18,7 +18,7 @@ const options: RouterOptions = { const r = new Router(); const router = new Router(options); -const routerHandler: RouteHandler = (req: IncommingRequest, res: any, next: NextFunction) => {}; +const routerHandler: RouteHandler = (req: IncomingRequest, res: any, next: NextFunction) => {}; router.get('/', routerHandler); router.post('/', routerHandler); @@ -49,10 +49,10 @@ router.route('/') // test router handling var server = createServer(function(req: IncomingMessage, res: ServerResponse) { - router(req as IncommingRequest, res, (err: any) => { + router(req as IncomingRequest, res, (err: any) => { // }) - router.handle(req as Router.IncommingRequest, res, (err: any) => { + router.handle(req as Router.IncomingRequest, res, (err: any) => { // }) }) From 0bead501a836cc097342f187849bfa2e4612ecb6 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 18:00:22 +0300 Subject: [PATCH 03/14] fix: type `req` to IncomingMessage and `res` to ServerResponse --- index.d.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/index.d.ts b/index.d.ts index a2add11..31c51dc 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,3 +1,5 @@ +import * as http from 'http'; + export = Router; declare namespace Router { @@ -8,7 +10,7 @@ declare namespace Router { mergeParams?: boolean; } - interface IncomingRequest { + interface IncomingRequest extends http.IncomingMessage { url: string, method: string, originalUrl?: string, @@ -21,16 +23,16 @@ declare namespace Router { route?: IRoute } - type RequestParamHandler = (req: IncomingRequest, res: any, next: NextFunction, value: any, name: string) => any; + type RequestParamHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction, value: any, name: string) => any; interface RouteHandler { // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: RoutedRequest, res: any, next: NextFunction): any; + (req: RoutedRequest, res: http.ServerResponse, next: NextFunction): any; } interface RequestHandler { // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: IncomingRequest, res: any, next: NextFunction): any; + (req: IncomingRequest, res: http.ServerResponse, next: NextFunction): any; } @@ -39,7 +41,7 @@ declare namespace Router { (err?: any): void; } - type ErrorRequestHandler = (err: any, req: IncomingRequest, res: any, next: NextFunction) => any; + type ErrorRequestHandler = (err: any, req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => any; type PathParams = string | RegExp | Array; From 1d5bb740770680e23ae7efd044e5f5c77d621337 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 18:14:40 +0300 Subject: [PATCH 04/14] feat: sort http methods by name --- index.d.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/index.d.ts b/index.d.ts index 31c51dc..b0d16b4 100644 --- a/index.d.ts +++ b/index.d.ts @@ -99,13 +99,14 @@ declare namespace Router { */ all: IRouterMatcher; + /* Common HTTP methods */ + delete: IRouterMatcher; get: IRouterMatcher; + head: IRouterMatcher; + options: IRouterMatcher; + patch: IRouterMatcher; post: IRouterMatcher; put: IRouterMatcher; - delete: IRouterMatcher; - patch: IRouterMatcher; - options: IRouterMatcher; - head: IRouterMatcher; use: IRouterHandler & IRouterMatcher; @@ -121,14 +122,17 @@ declare namespace Router { interface IRoute { path: string; stack: any; + all: IRouterHandler; + + /* Common HTTP methods */ + delete: IRouterHandler; get: IRouterHandler; + head: IRouterHandler; + options: IRouterHandler; + patch: IRouterHandler; post: IRouterHandler; put: IRouterHandler; - delete: IRouterHandler; - patch: IRouterHandler; - options: IRouterHandler; - head: IRouterHandler; } interface RouterConstructor extends IRouter { From 8b503dc33638fbb4935c9bbf8845e1ca43f93a8c Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 18:21:43 +0300 Subject: [PATCH 05/14] feat: add less common HTTP methods --- index.d.ts | 80 +++++++++++++++++++++++++++++++++++++++------- test/type-check.ts | 1 + 2 files changed, 70 insertions(+), 11 deletions(-) diff --git a/index.d.ts b/index.d.ts index b0d16b4..3c235bb 100644 --- a/index.d.ts +++ b/index.d.ts @@ -99,7 +99,15 @@ declare namespace Router { */ all: IRouterMatcher; - /* Common HTTP methods */ + use: IRouterHandler & IRouterMatcher; + + handle: RequestHandler; + + route(prefix: PathParams): IRoute; + // Stack of configured routes + stack: any[]; + + // Common HTTP methods delete: IRouterMatcher; get: IRouterMatcher; head: IRouterMatcher; @@ -108,15 +116,35 @@ declare namespace Router { post: IRouterMatcher; put: IRouterMatcher; - use: IRouterHandler & IRouterMatcher; - - handle: RequestHandler; - - route(prefix: PathParams): IRoute; - /** - * Stack of configured routes - */ - stack: any[]; + // Exotic HTTP methods + acl: IRouterMatcher; + bind: IRouterMatcher; + checkout: IRouterMatcher; + connect: IRouterMatcher; + copy: IRouterMatcher; + link: IRouterMatcher; + lock: IRouterMatcher; + "m-search": IRouterMatcher; + merge: IRouterMatcher; + mkactivity: IRouterMatcher; + mkcalendar: IRouterMatcher; + mkcol: IRouterMatcher; + move: IRouterMatcher; + notify: IRouterMatcher; + pri: IRouterMatcher; + propfind: IRouterMatcher; + proppatch: IRouterMatcher; + purge: IRouterMatcher; + rebind: IRouterMatcher; + report: IRouterMatcher; + search: IRouterMatcher; + source: IRouterMatcher; + subscribe: IRouterMatcher; + trace: IRouterMatcher; + unbind: IRouterMatcher; + unlink: IRouterMatcher; + unlock: IRouterMatcher; + unsubscribe: IRouterMatcher; } interface IRoute { @@ -125,7 +153,7 @@ declare namespace Router { all: IRouterHandler; - /* Common HTTP methods */ + // Common HTTP methods delete: IRouterHandler; get: IRouterHandler; head: IRouterHandler; @@ -133,6 +161,36 @@ declare namespace Router { patch: IRouterHandler; post: IRouterHandler; put: IRouterHandler; + + // Exotic HTTP methods + acl: IRouterHandler; + bind: IRouterHandler; + checkout: IRouterHandler; + connect: IRouterHandler; + copy: IRouterHandler; + link: IRouterHandler; + lock: IRouterHandler; + "m-search": IRouterHandler; + merge: IRouterHandler; + mkactivity: IRouterHandler; + mkcalendar: IRouterHandler; + mkcol: IRouterHandler; + move: IRouterHandler; + notify: IRouterHandler; + pri: IRouterHandler; + propfind: IRouterHandler; + proppatch: IRouterHandler; + purge: IRouterHandler; + rebind: IRouterHandler; + report: IRouterHandler; + search: IRouterHandler; + source: IRouterHandler; + subscribe: IRouterHandler; + trace: IRouterHandler; + unbind: IRouterHandler; + unlink: IRouterHandler; + unlock: IRouterHandler; + unsubscribe: IRouterHandler; } interface RouterConstructor extends IRouter { diff --git a/test/type-check.ts b/test/type-check.ts index e1dee14..c6c61d2 100644 --- a/test/type-check.ts +++ b/test/type-check.ts @@ -26,6 +26,7 @@ router.delete('/', routerHandler); router.patch('/', routerHandler); router.options('/', routerHandler); router.head('/', routerHandler); +router.unsubscribe('/', routerHandler); // param router.param('user_id', (req, res, next, id) => {}); From 4fc5c25228c3ee5f8661d8afc214971e4a01b21c Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 18:41:41 +0300 Subject: [PATCH 06/14] feat: remove usages of any --- index.d.ts | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/index.d.ts b/index.d.ts index 3c235bb..477f0e6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -4,17 +4,27 @@ export = Router; declare namespace Router { - export interface RouterOptions { + interface RouterOptions { strict?: boolean; caseSensitive?: boolean; mergeParams?: boolean; } + interface Layer { + name: string, + handle: RequestHandler | ErrorRequestHandler, + handle_request: RequestHandler, + handle_error: ErrorRequestHandler, + match: (path: string) => boolean, + } + interface IncomingRequest extends http.IncomingMessage { url: string, method: string, originalUrl?: string, - params?: any; + params?: { + [key: string]: any, + }, } interface RoutedRequest extends IncomingRequest { @@ -23,25 +33,24 @@ declare namespace Router { route?: IRoute } - type RequestParamHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction, value: any, name: string) => any; + type RequestParamHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction, value: string, name: string) => void; interface RouteHandler { // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: RoutedRequest, res: http.ServerResponse, next: NextFunction): any; + (req: RoutedRequest, res: http.ServerResponse, next: NextFunction): void; } interface RequestHandler { // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: IncomingRequest, res: http.ServerResponse, next: NextFunction): any; + (req: IncomingRequest, res: http.ServerResponse, next: NextFunction): void; } - interface NextFunction { // tslint:disable-next-line callable-types (In ts2.1 it thinks the type alias has no call signatures) - (err?: any): void; + (err?: Error | "route" | "router"): void; } - type ErrorRequestHandler = (err: any, req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => any; + type ErrorRequestHandler = (err: Error, req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; type PathParams = string | RegExp | Array; @@ -105,7 +114,7 @@ declare namespace Router { route(prefix: PathParams): IRoute; // Stack of configured routes - stack: any[]; + stack: Layer[]; // Common HTTP methods delete: IRouterMatcher; @@ -149,7 +158,7 @@ declare namespace Router { interface IRoute { path: string; - stack: any; + stack: Layer[]; all: IRouterHandler; From 2cc21cd9ee82bf4525fd722167a89dfa11d90a1e Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 19:16:18 +0300 Subject: [PATCH 07/14] fix: fix places that mistakenly reuse handler signatures --- index.d.ts | 12 +++++------- test/type-check.ts | 28 ++++++++++++++++------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/index.d.ts b/index.d.ts index 477f0e6..ebe5e17 100644 --- a/index.d.ts +++ b/index.d.ts @@ -45,10 +45,8 @@ declare namespace Router { (req: IncomingRequest, res: http.ServerResponse, next: NextFunction): void; } - interface NextFunction { - // tslint:disable-next-line callable-types (In ts2.1 it thinks the type alias has no call signatures) - (err?: Error | "route" | "router"): void; - } + type NextFunction = (err?: Error | "route" | "router") => void; + type Callback = (err?: Error) => void; type ErrorRequestHandler = (err: Error, req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; @@ -75,7 +73,7 @@ declare namespace Router { * could automatically load a user's information from the database without * any additional code, * - * The callback uses the samesignature as middleware, the only differencing + * The callback uses the same signature as middleware, the only differencing * being that the value of the placeholder is passed, in this case the _id_ * of the user. Once the `next()` function is invoked, just like middleware * it will continue on to execute the route, or subsequent parameter functions. @@ -110,7 +108,7 @@ declare namespace Router { use: IRouterHandler & IRouterMatcher; - handle: RequestHandler; + handle: (req: http.IncomingMessage, res: http.ServerResponse, cb: Callback) => void; route(prefix: PathParams): IRoute; // Stack of configured routes @@ -203,7 +201,7 @@ declare namespace Router { } interface RouterConstructor extends IRouter { - new(options?: RouterOptions): IRouter & RequestHandler; + new(options?: RouterOptions): IRouter & ((req: http.IncomingMessage, res: http.ServerResponse, cb: Callback) => void); } } diff --git a/test/type-check.ts b/test/type-check.ts index c6c61d2..2a1f620 100644 --- a/test/type-check.ts +++ b/test/type-check.ts @@ -5,11 +5,9 @@ import { IncomingRequest, RouteHandler, IRoute, - NextFunction, RoutedRequest } from '..'; - const options: RouterOptions = { strict: false, caseSensitive: false, @@ -18,7 +16,9 @@ const options: RouterOptions = { const r = new Router(); const router = new Router(options); -const routerHandler: RouteHandler = (req: IncomingRequest, res: any, next: NextFunction) => {}; +const routerHandler: RouteHandler = (req, res) => { + res.end('FIN'); +}; router.get('/', routerHandler); router.post('/', routerHandler); @@ -29,7 +29,10 @@ router.head('/', routerHandler); router.unsubscribe('/', routerHandler); // param -router.param('user_id', (req, res, next, id) => {}); +router.param('user_id', (req, res, next, id) => { + const val: string = id; + next(); +}); // middleware router.use((req, res, next) => { @@ -39,24 +42,25 @@ router.use((req, res, next) => { const api: IRoute = router.route('/api/'); router.route('/') -.all((req: RoutedRequest, res: any, next: NextFunction) => { +.all((req, res, next) => { + const url: string = req.baseUrl; next(); }) .get((req, res) => { - // do nothing + res.setHeader('x-header', 'value'); + res.end('.'); }); // test router handling - var server = createServer(function(req: IncomingMessage, res: ServerResponse) { - router(req as IncomingRequest, res, (err: any) => { + router(req, res, (err) => { + if (err) { + const e: Error = err; + } // }) - router.handle(req as Router.IncomingRequest, res, (err: any) => { + router.handle(req, res, (err) => { // }) }) - - - From e941dc236cd3b9bbcdf514cbd0d2cbffd953f6ac Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Tue, 27 Apr 2021 19:18:21 +0300 Subject: [PATCH 08/14] fix: remove the workaround for callable types --- index.d.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/index.d.ts b/index.d.ts index ebe5e17..65dd965 100644 --- a/index.d.ts +++ b/index.d.ts @@ -35,15 +35,8 @@ declare namespace Router { type RequestParamHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction, value: string, name: string) => void; - interface RouteHandler { - // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: RoutedRequest, res: http.ServerResponse, next: NextFunction): void; - } - - interface RequestHandler { - // tslint:disable-next-line callable-types (This is extended from and can't extend from a type alias in ts<2.2 - (req: IncomingRequest, res: http.ServerResponse, next: NextFunction): void; - } + type RouteHandler = (req: RoutedRequest, res: http.ServerResponse, next: NextFunction) => void; + type RequestHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; type NextFunction = (err?: Error | "route" | "router") => void; type Callback = (err?: Error) => void; From 8b084656f4111cdb49fa9dac267f24220f1d770c Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Thu, 29 Apr 2021 11:29:43 +0300 Subject: [PATCH 09/14] style: avoid using var --- index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index 65dd965..bc41aa1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -199,4 +199,4 @@ declare namespace Router { } -declare var Router: Router.RouterConstructor; +declare const Router: Router.RouterConstructor; From e7d495b0db18480fbf33197de3ee3c62df35b768 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Sun, 16 May 2021 09:13:20 +0300 Subject: [PATCH 10/14] fix: remove url and method since they are present in IncomingMessage --- index.d.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index bc41aa1..336b6ae 100644 --- a/index.d.ts +++ b/index.d.ts @@ -19,8 +19,6 @@ declare namespace Router { } interface IncomingRequest extends http.IncomingMessage { - url: string, - method: string, originalUrl?: string, params?: { [key: string]: any, From f384d5abf909763dc960a87dacba3e6540a71086 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Sun, 16 May 2021 09:19:39 +0300 Subject: [PATCH 11/14] fix: remove invalid(/deprecated) param signature --- index.d.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index 336b6ae..c53527e 100644 --- a/index.d.ts +++ b/index.d.ts @@ -84,13 +84,6 @@ declare namespace Router { */ param(name: string, handler: RequestParamHandler): this; - /** - * Alternatively, you can pass only a callback, in which case you have the opportunity to alter the app.param() - * - * @deprecated since version 4.11 - */ - param(callback: (name: string, matcher: RegExp) => RequestParamHandler): this; - /** * Special-cased "all" method, applying the given route `path`, * middleware, and callback to _every_ HTTP method. From 4aae4964761ffbe294e05b5df9dbafacf500dda3 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Thu, 15 Jul 2021 15:48:16 +0300 Subject: [PATCH 12/14] fix: broaden error type since there are actually no guards in place I'm leaving `any | "route" | "router"` for NextFunctions param to document the special cases, even though the union doesn't actually widen `any` further. --- index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.d.ts b/index.d.ts index c53527e..b8e6cdb 100644 --- a/index.d.ts +++ b/index.d.ts @@ -36,10 +36,10 @@ declare namespace Router { type RouteHandler = (req: RoutedRequest, res: http.ServerResponse, next: NextFunction) => void; type RequestHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; - type NextFunction = (err?: Error | "route" | "router") => void; - type Callback = (err?: Error) => void; + type NextFunction = (err?: any | "route" | "router") => void; + type Callback = (err?: any) => void; - type ErrorRequestHandler = (err: Error, req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; + type ErrorRequestHandler = (err: any, req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; type PathParams = string | RegExp | Array; From 1cbf48b713e321d4f6be51179924596060c6b554 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Thu, 15 Jul 2021 15:58:39 +0300 Subject: [PATCH 13/14] fix: remove private API from the types I'm going to leave Layer type for documentation again and because it might be useful in cases where someone bypasses to the private API(my case). For example when writing OTel instrumentations. --- index.d.ts | 12 ++++++++---- test/type-check.ts | 5 +---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/index.d.ts b/index.d.ts index b8e6cdb..ff24d50 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,6 +10,7 @@ declare namespace Router { mergeParams?: boolean; } + // Private interface Layer { name: string, handle: RequestHandler | ErrorRequestHandler, @@ -92,11 +93,12 @@ declare namespace Router { use: IRouterHandler & IRouterMatcher; - handle: (req: http.IncomingMessage, res: http.ServerResponse, cb: Callback) => void; + // private + // handle: (req: http.IncomingMessage, res: http.ServerResponse, cb: Callback) => void; route(prefix: PathParams): IRoute; - // Stack of configured routes - stack: Layer[]; + // Stack of configured routes. private + // stack: Layer[]; // Common HTTP methods delete: IRouterMatcher; @@ -140,7 +142,9 @@ declare namespace Router { interface IRoute { path: string; - stack: Layer[]; + + // Stack of configured routes. Private. + // stack: Layer[]; all: IRouterHandler; diff --git a/test/type-check.ts b/test/type-check.ts index 2a1f620..2b41787 100644 --- a/test/type-check.ts +++ b/test/type-check.ts @@ -59,8 +59,5 @@ var server = createServer(function(req: IncomingMessage, res: ServerResponse) { const e: Error = err; } // - }) - router.handle(req, res, (err) => { - // - }) + }); }) From 4a034cf9b8b9dee43e78d6437a0abbb3f7512960 Mon Sep 17 00:00:00 2001 From: Rauno Viskus Date: Thu, 15 Jul 2021 16:13:00 +0300 Subject: [PATCH 14/14] fix: use RoutedRequest in RequestParamHandler --- index.d.ts | 2 +- test/type-check.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index ff24d50..fd64cca 100644 --- a/index.d.ts +++ b/index.d.ts @@ -32,7 +32,7 @@ declare namespace Router { route?: IRoute } - type RequestParamHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction, value: string, name: string) => void; + type RequestParamHandler = (req: RoutedRequest, res: http.ServerResponse, next: NextFunction, value: string, name: string) => void; type RouteHandler = (req: RoutedRequest, res: http.ServerResponse, next: NextFunction) => void; type RequestHandler = (req: IncomingRequest, res: http.ServerResponse, next: NextFunction) => void; diff --git a/test/type-check.ts b/test/type-check.ts index 2b41787..3a486bd 100644 --- a/test/type-check.ts +++ b/test/type-check.ts @@ -30,6 +30,9 @@ router.unsubscribe('/', routerHandler); // param router.param('user_id', (req, res, next, id) => { + const baseUrl: string = req.baseUrl; + const route: string = req.route?.path || 'na'; + const param = req.params?.user_id; const val: string = id; next(); });