├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── __tests__ ├── compareRoutes.test.js ├── find.test.js ├── routeSplitter.test.js ├── set.test.js └── use.test.js ├── jest.config.js ├── lib └── index.ts ├── package.json ├── practice.js └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | lib/index.js -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | index.ts 2 | node_modules 3 | __tests__ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 10 4 | before_script: 5 | - npm run setup 6 | - npm run build 7 | script: 8 | - npm run test -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Eli Gallipoli, Alex Kang, Izumi Sato, Sara Powers. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![DirextLogo](https://i.ibb.co/3CCS8g5/dirextlogo.png) 2 | 3 | 🚧 A lightweight routing solution for Node.js. 🚧 [![Build Status](https://travis-ci.org/dirext-js/dirext.svg?branch=master)](https://travis-ci.org/dirext-js/dirext) 4 | 5 | ## **Install dirext** 6 | ` npm i dirext-js` 7 | 8 | Initialize a new instance of dirext. 9 | 10 | ```javascript 11 | const Dirext = require('dirext-js'); 12 | const app = new Dirext(); 13 | ``` 14 | 15 | ## Setting routes 16 | 17 | Syntax in `dirext` is similar to Express. 18 | 19 | ### method 20 | Any uppercase valid HTTP method: 21 | * GET 22 | * POST 23 | * PUT 24 | * PATCH 25 | * DELETE 26 | * HEAD 27 | * CONNECT 28 | * OPTIONS 29 | * TRACE 30 | 31 | ### url 32 | Any endpoint. Dirext supports: 33 | * static - `/home` 34 | * parameters - `/home/:user` 35 | * nested parameters - `/home/:user/posts/:id` 36 | * queries - `/home/?user` 37 | * wildcards - `/home/*` 38 | 39 | 40 | #### dirext.set(method, url, [...middleware]) 41 | Initializes a route based on a specific **method**. Returns itself. 42 | 43 | ```javascript 44 | app.set('GET', '/home', middlewareFunction, middlewareFunctionTwo); 45 | app.set('POST', '/home', middlewareFunctionThree, middlewareFunctionFour); 46 | ``` 47 | 48 | #### dirext.use(url, [...middleware]) 49 | 50 | Initializes a route with middleware to execute regardless of the method. If no url is provided, it will be set as global middlware. Returns itself. 51 | 52 | ```javascript 53 | app.use('/', middlewareFunction); 54 | app.use(globalMiddlewareFunction); 55 | ``` 56 | 57 | #### dirext.METHOD(url, [...middleware]) 58 | 59 | Utilizes dirext's own `set` method to set a method-specific route without passing in method as an argument. Returns itself. 60 | 61 | ```javascript 62 | app.get('/home', middlewareFunction); 63 | app.post('/home/:user', userMiddlewareFunction); 64 | app.delete('/home/:user/posts/:id', deletePostMiddleware); 65 | ``` 66 | 67 | #### dirext.find(method, url) 68 | 69 | Finds all stored route-specific and global middleware, parameters, and queries, for a route. Returns an object with **middleware, params, and queries**. 70 | > Middleware will be returned in an array **_in the order it was defined_**. Queries and Params will be returned in objects with key/value pairs. 71 | 72 | ```javascript 73 | app.use(globalMiddleware); 74 | app.use('/home', homeMiddleware); 75 | app.get('/home', getHomeMiddleware); 76 | app.post('/home/:user', postUserMiddleware); 77 | app.delete('/home/?user=user1/posts/:id', deleteMiddleware); 78 | 79 | app.find('GET', '/home'); 80 | // -> { middleware: [globalMiddleware, homeMiddleware, getHomeMiddleware] } 81 | 82 | app.find('POST', '/home/user1'); 83 | // -> { middleware: [globalMiddleware, postUserMiddleware], params: { user: user1 } } 84 | 85 | app.find('DELETE', '/home/posts/2/?user=user1'); 86 | // -> { middleware: [globalMiddleware, deleteMiddleware], params: { id: 2 }, queries: { user: user1 } } 87 | ``` 88 | 89 | ### Creators 90 | 91 | [Sara Powers](https://github.com/sarapowers) 92 | 93 | [Eli Gallipoli](https://github.com/egcg317) 94 | 95 | [Izumi Sato](https://github.com/izumi411) 96 | 97 | [Alex Kang](https://github.com/akang0408) 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /__tests__/compareRoutes.test.js: -------------------------------------------------------------------------------- 1 | const Dirext = require('../lib/index.js'); 2 | 3 | const router = new Dirext(); 4 | 5 | test('input parameters that contain static routes and return { match: true } if they match', () => { 6 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { route: 'jest' }], method: 'GET', middleware: [] }, [{ route: 'testing' }, { route: 'jest' }], 2)).toEqual({ match: true }); 7 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'user1' }, { route: 'posts' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'user1' }, { route: 'posts' }], 3)).toEqual({ match: true }); 8 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'profile' }, { route: 'data' }, { route: 'address' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'profile' }, { route: 'data' }, { route: 'address' }], 4)).toEqual({ match: true }); 9 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }], method: 'GET', middleware: [] }, [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }], 4)).toEqual({ match: true }); 10 | }); 11 | 12 | test('input parameters that contain static routes and return { match: false } if they do not match', () => { 13 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { route: 'jest' }], method: 'GET', middleware: [] }, [{ route: 'testing' }, { route: 'notJest' }], 2)).toEqual({ match: false }); 14 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'user1' }, { route: 'posts' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'notUser1' }, { route: 'posts' }], 3)).toEqual({ match: false }); 15 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'profile' }, { route: 'data' }, { route: 'address' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'profile' }, { route: 'notData' }, { route: 'address' }], 4)).toEqual({ match: false }); 16 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }], method: 'GET', middleware: [] }, [{ route: 'notInterface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }], 4)).toEqual({ match: false }); 17 | }); 18 | 19 | test('input parameters that contain static routes and params and return { match: true, params: { : } } if they match', () => { 20 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { param: 'jest' }], method: 'GET', middleware: [] }, [{ route: 'testing' }, { route: 'jest1' }], 2)).toEqual({ match: true, params: { jest: 'jest1' } }); 21 | expect(router.compareRoutes({ url: [{ route: 'home' }, { param: 'user' }, { param: 'posts' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'user1' }, { route: 'posts1' }], 3)).toEqual({ match: true, params: { user: 'user1', posts: 'posts1' } }); 22 | expect(router.compareRoutes({ url: [{ route: 'home' }, { param: 'profile' }, { param: 'data' }, { route: 'address' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'profile1' }, { route: 'data1' }, { route: 'address' }], 4)).toEqual({ match: true, params: { profile: 'profile1', data: 'data1' } }); 23 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { param: 'pic' }], method: 'GET', middleware: [] }, [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }], 4)).toEqual({ match: true, params: { pic: 'pic1' } }); 24 | }); 25 | 26 | test('input parameters that contain static routes and params and return { match: false } if they do not match', () => { 27 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { param: 'jest' }], method: 'GET', middleware: [] }, [{ route: 'notTesting' }, { route: 'jest1' }], 2)).toEqual({ match: false }); 28 | expect(router.compareRoutes({ url: [{ route: 'home' }, { param: 'user' }, { param: 'posts' }], method: 'GET', middleware: [] }, [{ route: 'notHome' }, { route: 'user1' }, { route: 'posts1' }], 3)).toEqual({ match: false }); 29 | expect(router.compareRoutes({ url: [{ route: 'home' }, { param: 'profile' }, { param: 'data' }, { route: 'address' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'profile1' }, { route: 'data1' }, { route: 'notAddress' }], 4)).toEqual({ match: false, params: { profile: 'profile1', data: 'data1' } }); 30 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { param: 'pic' }], method: 'GET', middleware: [] }, [{ route: 'notInterface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }], 4)).toEqual({ match: false }); 31 | }); 32 | 33 | test('input parameters that contain static routes and wildcards and if the request url matches before the wildcard return { match: true }', () => { 34 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'testing' }, { route: 'jest1' }], 2)).toEqual({ match: true }); 35 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'user' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'user' }, { route: 'jest1' }], 3)).toEqual({ match: true }); 36 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'profile' }, { route: 'data' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'profile' }, { route: 'data' }, { route: 'Address' }], 4)).toEqual({ match: true }); 37 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic' }, { route: 'pic1' }], 5)).toEqual({ match: true }); 38 | }); 39 | 40 | test('input parameters that contain static routes, param routes and wildcards and if the request url matches before the wildcard return { match: true, params: { : } }', () => { 41 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { param: 'jest' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'testing' }, { route: 'jest1' }, { route: 'jest2' }], 3)).toEqual({ match: true, params: { jest: 'jest1' } }); 42 | expect(router.compareRoutes({ url: [{ route: 'home' }, { param: 'user' }, { param: 'posts' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'user1' }, { route: 'post1' }, { route: 'data1' }], 4)).toEqual({ match: true, params: { user: 'user1', posts: 'post1' } }); 43 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { route: 'jest' }, { param: 'posts' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'interface' }, { route: 'jest' }, { route: 'post1' }, { route: 'data1' }], 4)).toEqual({ match: true, params: { posts: 'post1' } }); 44 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'profile' }, { param: 'data' }, { param: 'address' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'profile' }, { route: 'data1' }, { route: 'address1' }, { route: 'image' }], 5)).toEqual({ match: true, params: { data: 'data1', address: 'address1' } }); 45 | }); 46 | 47 | test('input parameters that contain static routes, param routes and wildcards and if the request url does not before the wildcard return { match: false, params: { : } } ', () => { 48 | expect(router.compareRoutes({ url: [{ route: 'testing' }, { param: 'jest' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'notTesting' }, { route: 'jest1' }, { route: 'jest2' }], 3)).toEqual({ match: false }); 49 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'user' }, { param: 'posts' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'notUser' }, { route: 'post1' }, { route: 'data1' }], 4)).toEqual({ match: false }); 50 | expect(router.compareRoutes({ url: [{ route: 'interface' }, { param: 'posts' }, { route: 'jest' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'interface' }, { route: 'post1' }, { route: 'notJest' }, { route: 'data1' }], 4)).toEqual({ match: false, params: { posts: 'post1' } }); 51 | expect(router.compareRoutes({ url: [{ route: 'home' }, { route: 'profile' }, { param: 'data' }, { param: 'address' }, { route: '*' }], method: 'GET', middleware: [] }, [{ route: 'home' }, { route: 'notProfile' }, { route: 'data1' }, { route: 'address1' }, { route: 'image' }], 5)).toEqual({ match: false }); 52 | }); 53 | -------------------------------------------------------------------------------- /__tests__/find.test.js: -------------------------------------------------------------------------------- 1 | const Dirext = require('../lib/index.js'); 2 | 3 | const router = new Dirext(); 4 | 5 | test('if corresponding url and method that is passed into find method exist in router.routes, return { middleware: [ <...middleware funcs>], params: { : } }', () => { 6 | const middleware1 = () => 'testing1'; 7 | const middleware2 = () => 'testing2'; 8 | const middleware3 = () => 'testing3'; 9 | const middleware4 = () => 'testing4'; 10 | 11 | router.set('GET', '/home/user', middleware1); 12 | router.set('POST', '/home/:posts/images', middleware1, middleware2); 13 | router.set('DELETE', '/interface/user/address', middleware1, middleware3); 14 | router.set('PUT', '/interface/:posts/images', middleware2, middleware4); 15 | router.set('PATCH', '/home/users/images', middleware2, middleware3, middleware4); 16 | router.set('HEAD', '/home/users/portfolio/pictures', middleware1, middleware2, middleware4); 17 | router.set('CONNECT', '/home/:users/data', middleware1); 18 | router.set('OPTIONS', '/interface/home/portfolio/pictures', middleware2, middleware4); 19 | router.set('TRACE', '/home/:users/:portfolios/pictures', middleware1, middleware2, middleware3, middleware4); 20 | 21 | expect(router.find('GET', '/home/user')).toEqual({ middleware: [middleware1], params: {} }); 22 | expect(router.find('POST', '/home/post1/images')).toEqual({ middleware: [middleware1, middleware2], params: { posts: 'post1' } }); 23 | expect(router.find('DELETE', '/interface/user/address')).toEqual({ middleware: [middleware1, middleware3], params: {} }); 24 | expect(router.find('PUT', '/interface/post1/images')).toEqual({ middleware: [middleware2, middleware4], params: { posts: 'post1' } }); 25 | expect(router.find('PATCH', '/home/users/images')).toEqual({ middleware: [middleware2, middleware3, middleware4], params: {} }); 26 | expect(router.find('HEAD', '/home/users/portfolio/pictures')).toEqual({ middleware: [middleware1, middleware2, middleware4], params: {} }); 27 | expect(router.find('CONNECT', '/home/user1/data')).toEqual({ middleware: [middleware1], params: { users: 'user1' } }); 28 | expect(router.find('OPTIONS', '/interface/home/portfolio/pictures')).toEqual({ middleware: [middleware2, middleware4], params: {} }); 29 | expect(router.find('TRACE', '/home/user1/portfolio1/pictures')).toEqual({ middleware: [middleware1, middleware2, middleware3, middleware4], params: { users: 'user1', portfolios: 'portfolio1' } }); 30 | }); 31 | 32 | test('if corresponding url and method that is passed into find method does not exist in router.routes, return { middleware: [], params: {} }', () => { 33 | const middleware1 = () => 'testing1'; 34 | const middleware2 = () => 'testing2'; 35 | const middleware3 = () => 'testing3'; 36 | const middleware4 = () => 'testing4'; 37 | 38 | router.set('GET', '/home/user', middleware1); 39 | router.set('POST', '/home/:posts/images', middleware1, middleware2); 40 | router.set('DELETE', '/interface/user/address', middleware1, middleware3); 41 | router.set('PUT', '/interface/:posts/images', middleware2, middleware4); 42 | router.set('PATCH', '/home/users/images', middleware2, middleware3, middleware4); 43 | router.set('HEAD', '/home/users/portfolio/pictures', middleware1, middleware2, middleware4); 44 | router.set('CONNECT', '/home/:users/data', middleware1); 45 | router.set('OPTIONS', '/interface/home/portfolio/pictures', middleware2, middleware4); 46 | router.set('TRACE', '/home/:users/:portfolios/pictures', middleware1, middleware2, middleware3, middleware4); 47 | 48 | expect(router.find('GET', '/home/testing')).toEqual({ middleware: [], params: {} }); 49 | expect(router.find('POST', '/home/testing/testing')).toEqual({ middleware: [], params: {} }); 50 | expect(router.find('DELETE', '/interface/user/testing')).toEqual({ middleware: [], params: {} }); 51 | expect(router.find('PUT', '/interface/testing/testing')).toEqual({ middleware: [], params: {} }); 52 | expect(router.find('PATCH', '/home/testing/images')).toEqual({ middleware: [], params: {} }); 53 | expect(router.find('HEAD', '/home/users/testing/pictures')).toEqual({ middleware: [], params: {} }); 54 | expect(router.find('CONNECT', '/home/testing/testing')).toEqual({ middleware: [], params: {} }); 55 | expect(router.find('OPTIONS', '/interface/testing/portfolio/pictures')).toEqual({ middleware: [], params: {} }); 56 | expect(router.find('TRACE', '/home/user1/testing/testing')).toEqual({ middleware: [], params: {} }); 57 | }); 58 | -------------------------------------------------------------------------------- /__tests__/routeSplitter.test.js: -------------------------------------------------------------------------------- 1 | const Dirext = require('../lib/index.js'); 2 | 3 | const router = new Dirext(); 4 | 5 | test('input string URL with only static routes and return correct array of objects', () => { 6 | expect(router.routeSplitter('/home/user1/posts')).toEqual([{ route: 'home' }, { route: 'user1' }, { route: 'posts' }]); 7 | expect(router.routeSplitter('/home/profile/data/address')).toEqual([{ route: 'home' }, { route: 'profile' }, { route: 'data' }, { route: 'address' }]); 8 | expect(router.routeSplitter('/interface/user1/images/pic1')).toEqual([{ route: 'interface' }, { route: 'user1' }, { route: 'images' }, { route: 'pic1' }]); 9 | expect(router.routeSplitter('/testing/jest/dirext/routes')).toEqual([{ route: 'testing' }, { route: 'jest' }, { route: 'dirext' }, { route: 'routes' }]); 10 | }); 11 | 12 | test('input string URL with static routes and params and return correct array of objects', () => { 13 | expect(router.routeSplitter('/home/:user/posts')).toEqual([{ route: 'home' }, { param: 'user' }, { route: 'posts' }]); 14 | expect(router.routeSplitter('/home/user/posts/:postId')).toEqual([{ route: 'home' }, { route: 'user' }, { route: 'posts' }, { param: 'postId' }]); 15 | expect(router.routeSplitter('/interface/user/images/:imageId')).toEqual([{ route: 'interface' }, { route: 'user' }, { route: 'images' }, { param: 'imageId' }]); 16 | expect(router.routeSplitter('/testing/jest/dirext/:routeId')).toEqual([{ route: 'testing' }, { route: 'jest' }, { route: 'dirext' }, { param: 'routeId' }]); 17 | }); 18 | 19 | test('input string URL with static routes and nested params and return correct array of objects', () => { 20 | expect(router.routeSplitter('/home/:user/posts/:postId')).toEqual([{ route: 'home' }, { param: 'user' }, { route: 'posts' }, { param: 'postId' }]); 21 | expect(router.routeSplitter('/home/:user/images/:imageId')).toEqual([{ route: 'home' }, { param: 'user' }, { route: 'images' }, { param: 'imageId' }]); 22 | expect(router.routeSplitter('/interface/:user/images/:imageId')).toEqual([{ route: 'interface' }, { param: 'user' }, { route: 'images' }, { param: 'imageId' }]); 23 | expect(router.routeSplitter('/testing/:jest/:dirext/route')).toEqual([{ route: 'testing' }, { param: 'jest' }, { param: 'dirext' }, { route: 'route' }]); 24 | }); 25 | 26 | test('input string URL with static routes and queries and return correct array of objects', () => { 27 | expect(router.routeSplitter('/home/posts/?user=user1')).toEqual([{ route: 'home' }, { route: 'posts' }, { query: { user: 'user1' } }]); 28 | expect(router.routeSplitter('/home/user/imageId/?images=image1')).toEqual([{ route: 'home' }, { route: 'user' }, { route: 'imageId' }, { query: { images: 'image1' } }]); 29 | expect(router.routeSplitter('/user/images/imageId/?interface=interface1')).toEqual([{ route: 'user' }, { route: 'images' }, { route: 'imageId' }, { query: { interface: 'interface1' } }]); 30 | expect(router.routeSplitter('/testing/jest/dirext/?route=route1')).toEqual([{ route: 'testing' }, { route: 'jest' }, { route: 'dirext' }, { query: { route: 'route1' } }]); 31 | }); 32 | 33 | test('input string URL with static routes, params, and queries and return correct array of objects', () => { 34 | expect(router.routeSplitter('/home/posts/:postId/?user=user1')).toEqual([{ route: 'home' }, { route: 'posts' }, { param: 'postId' }, { query: { user: 'user1' } }]); 35 | expect(router.routeSplitter('/home/user/:imageId/timeStamp/?images=image1')).toEqual([{ route: 'home' }, { route: 'user' }, { param: 'imageId' }, { route: 'timeStamp' }, { query: { images: 'image1' } }]); 36 | expect(router.routeSplitter('/:user/:userImages/imageId/?interface=interface1')).toEqual([{ param: 'user' }, { param: 'userImages' }, { route: 'imageId' }, { query: { interface: 'interface1' } }]); 37 | expect(router.routeSplitter('/testing/jest/:dirext/?route=route1')).toEqual([{ route: 'testing' }, { route: 'jest' }, { param: 'dirext' }, { query: { route: 'route1' } }]); 38 | }); 39 | 40 | test('input string URL with param routes and queries and return correct array of objects', () => { 41 | expect(router.routeSplitter('/:posts/:timeStamp/?user=user1')).toEqual([{ param: 'posts' }, { param: 'timeStamp' }, { query: { user: 'user1' } }]); 42 | expect(router.routeSplitter('/:user/:imageId/?images=image1')).toEqual([{ param: 'user' }, { param: 'imageId' }, { query: { images: 'image1' } }]); 43 | expect(router.routeSplitter('/:user/:images/?interface=interface1')).toEqual([{ param: 'user' }, { param: 'images' }, { query: { interface: 'interface1' } }]); 44 | expect(router.routeSplitter('/:testing/:jest/:dirext/?route=route1')).toEqual([{ param: 'testing' }, { param: 'jest' }, { param: 'dirext' }, { query: { route: 'route1' } }]); 45 | }); 46 | 47 | test('input string URL with static routes and wildcard', () => { 48 | expect(router.routeSplitter('/home/posts/*')).toEqual([{ route: 'home' }, { route: 'posts' }, { route: '*' }]); 49 | expect(router.routeSplitter('/home/user/userId/*')).toEqual([{ route: 'home' }, { route: 'user' }, { route: 'userId' }, { route: '*' }]); 50 | expect(router.routeSplitter('/interface/users/*')).toEqual([{ route: 'interface' }, { route: 'users' }, { route: '*' }]); 51 | expect(router.routeSplitter('/home/posts/*')).toEqual([{ route: 'home' }, { route: 'posts' }, { route: '*' }]); 52 | }); 53 | 54 | test('input string URL with static routes, params, queries, and wildcard', () => { 55 | expect(router.routeSplitter('/home/:user/posts/*')).toEqual([{ route: 'home' }, { param: 'user' }, { route: 'posts' }, { route: '*' }]); 56 | expect(router.routeSplitter('/posts/:timeStamp/*')).toEqual([{ route: 'posts' }, { param: 'timeStamp' }, { route: '*' }]); 57 | expect(router.routeSplitter('/interface/:users/userInfo/*')).toEqual([{ route: 'interface' }, { param: 'users' }, { route: 'userInfo' }, { route: '*' }]); 58 | expect(router.routeSplitter('/interface/:home/posts/*')).toEqual([{ route: 'interface' }, { param: 'home' }, { route: 'posts' }, { route: '*' }]); 59 | }); 60 | -------------------------------------------------------------------------------- /__tests__/set.test.js: -------------------------------------------------------------------------------- 1 | const Dirext = require('../lib/index.js'); 2 | 3 | const router = new Dirext(); 4 | 5 | test('input method, url, and middlewareFuncs as args and check to see that correct obj has been pushed into this.routes array', () => { 6 | const middleware1 = () => 'testing1'; 7 | const middleware2 = () => 'testing2'; 8 | const middleware3 = () => 'testing3'; 9 | const middleware4 = () => 'testing4'; 10 | 11 | router.set('GET', '/home/user', middleware1); 12 | expect(router.routes[router.routes.length - 1]).toEqual( 13 | { 14 | url: [{ route: 'home' }, { route: 'user' }], 15 | method: 'GET', 16 | middleware: [middleware1], 17 | }, 18 | ); 19 | router.set('POST', '/home/posts/images', middleware1, middleware2); 20 | expect(router.routes[router.routes.length - 1]).toEqual( 21 | { 22 | url: [{ route: 'home' }, { route: 'posts' }, { route: 'images' }], 23 | method: 'POST', 24 | middleware: [middleware1, middleware2], 25 | }, 26 | ); 27 | router.set('DELETE', '/interface/user/address', middleware1, middleware3); 28 | expect(router.routes[router.routes.length - 1]).toEqual( 29 | { 30 | url: [{ route: 'interface' }, { route: 'user' }, { route: 'address' }], 31 | method: 'DELETE', 32 | middleware: [middleware1, middleware3], 33 | }, 34 | ); 35 | router.set('PUT', '/interface/posts/images', middleware2, middleware4); 36 | expect(router.routes[router.routes.length - 1]).toEqual( 37 | { 38 | url: [{ route: 'interface' }, { route: 'posts' }, { route: 'images' }], 39 | method: 'PUT', 40 | middleware: [middleware2, middleware4], 41 | }, 42 | ); 43 | router.set('PATCH', '/home/users/images', middleware2, middleware3, middleware4); 44 | expect(router.routes[router.routes.length - 1]).toEqual( 45 | { 46 | url: [{ route: 'home' }, { route: 'users' }, { route: 'images' }], 47 | method: 'PATCH', 48 | middleware: [middleware2, middleware3, middleware4], 49 | }, 50 | ); 51 | router.set('HEAD', '/home/users/portfolio/pictures', middleware1, middleware2, middleware4); 52 | expect(router.routes[router.routes.length - 1]).toEqual( 53 | { 54 | url: [{ route: 'home' }, { route: 'users' }, { route: 'portfolio' }, { route: 'pictures' }], 55 | method: 'HEAD', 56 | middleware: [middleware1, middleware2, middleware4], 57 | }, 58 | ); 59 | router.set('CONNECT', '/home/users/data', middleware1 ); 60 | expect(router.routes[router.routes.length - 1]).toEqual( 61 | { 62 | url: [{ route: 'home' }, { route: 'users' }, { route: 'data' }], 63 | method: 'CONNECT', 64 | middleware: [middleware1], 65 | }, 66 | ); 67 | router.set('OPTIONS', '/interface/home/portfolio/pictures', middleware2, middleware4); 68 | expect(router.routes[router.routes.length - 1]).toEqual( 69 | { 70 | url: [{ route: 'interface' }, { route: 'home' }, { route: 'portfolio' }, { route: 'pictures' }], 71 | method: 'OPTIONS', 72 | middleware: [middleware2, middleware4], 73 | }, 74 | ); 75 | router.set('TRACE', '/home/users/portfolio/pictures', middleware1, middleware2, middleware3, middleware4); 76 | expect(router.routes[router.routes.length - 1]).toEqual( 77 | { 78 | url: [{ route: 'home' }, { route: 'users' }, { route: 'portfolio' }, { route: 'pictures' }], 79 | method: 'TRACE', 80 | middleware: [middleware1, middleware2, middleware3, middleware4], 81 | }, 82 | ); 83 | }); 84 | -------------------------------------------------------------------------------- /__tests__/use.test.js: -------------------------------------------------------------------------------- 1 | const Dirext = require('../lib/index.js'); 2 | 3 | const router = new Dirext(); 4 | 5 | test('input url and middlewareFuncs as args and check to see that correct obj has been pushed into this.routes array', () => { 6 | const middleware1 = () => 'testing1'; 7 | const middleware2 = () => 'testing2'; 8 | const middleware3 = () => 'testing3'; 9 | const middleware4 = () => 'testing4'; 10 | 11 | router.use('/home', middleware1); 12 | expect(router.routes[router.routes.length - 1]).toEqual( 13 | { 14 | url: [{ route: 'home' }], 15 | method: '', 16 | middleware: [middleware1], 17 | }, 18 | ); 19 | 20 | router.use('/interface', middleware2, middleware3); 21 | expect(router.routes[router.routes.length - 1]).toEqual( 22 | { 23 | url: [{ route: 'interface' }], 24 | method: '', 25 | middleware: [middleware2, middleware3], 26 | }, 27 | ); 28 | 29 | router.use('/home/user/images', middleware1, middleware4); 30 | expect(router.routes[router.routes.length - 1]).toEqual( 31 | { 32 | url: [{ route: 'home' }, { route: 'user' }, { route: 'images' }], 33 | method: '', 34 | middleware: [middleware1, middleware4], 35 | }, 36 | ); 37 | 38 | router.use('/interface/user/images/pic1', middleware2, middleware3, middleware4); 39 | expect(router.routes[router.routes.length - 1]).toEqual( 40 | { 41 | url: [{ route: 'interface' }, { route: 'user' }, { route: 'images' }, { route: 'pic1' }], 42 | method: '', 43 | middleware: [middleware2, middleware3, middleware4], 44 | }, 45 | ); 46 | 47 | router.use(middleware2); 48 | expect(router.routes[router.routes.length - 1]).toEqual( 49 | { 50 | url: [{ route: 'global' }], 51 | method: '', 52 | middleware: [middleware2], 53 | }, 54 | ); 55 | 56 | router.use(middleware2, middleware4); 57 | expect(router.routes[router.routes.length - 1]).toEqual( 58 | { 59 | url: [{ route: 'global' }], 60 | method: '', 61 | middleware: [middleware2, middleware4], 62 | }, 63 | ); 64 | 65 | router.use(middleware1, middleware3, middleware4); 66 | expect(router.routes[router.routes.length - 1]).toEqual( 67 | { 68 | url: [{ route: 'global' }], 69 | method: '', 70 | middleware: [middleware1, middleware3, middleware4], 71 | }, 72 | ); 73 | 74 | router.use(middleware1, middleware2, middleware3, middleware4); 75 | expect(router.routes[router.routes.length - 1]).toEqual( 76 | { 77 | url: [{ route: 'global' }], 78 | method: '', 79 | middleware: [middleware1, middleware2, middleware3, middleware4], 80 | }, 81 | ); 82 | }); 83 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | module.exports = { 4 | // All imported modules in your tests should be mocked automatically 5 | // automock: false, 6 | // Stop running tests after `n` failures 7 | // bail: 0, 8 | // Respect "browser" field in package.json when resolving modules 9 | // browser: false, 10 | // The directory where Jest should store its cached dependency information 11 | // cacheDirectory: "/private/var/folders/mn/rdyx1f3x1_190xq31xbtq6rr0000gp/T/jest_dy", 12 | // Automatically clear mock calls and instances between every test 13 | clearMocks: true, 14 | // Indicates whether the coverage information should be collected while executing the test 15 | // collectCoverage: false, 16 | // An array of glob patterns indicating a set of files for which coverage information should be collected 17 | // collectCoverageFrom: null, 18 | // The directory where Jest should output its coverage files 19 | coverageDirectory: "coverage", 20 | // An array of regexp pattern strings used to skip coverage collection 21 | // coveragePathIgnorePatterns: [ 22 | // "/node_modules/" 23 | // ], 24 | // A list of reporter names that Jest uses when writing coverage reports 25 | // coverageReporters: [ 26 | // "json", 27 | // "text", 28 | // "lcov", 29 | // "clover" 30 | // ], 31 | // An object that configures minimum threshold enforcement for coverage results 32 | // coverageThreshold: null, 33 | // A path to a custom dependency extractor 34 | // dependencyExtractor: null, 35 | // Make calling deprecated APIs throw helpful error messages 36 | // errorOnDeprecated: false, 37 | // Force coverage collection from ignored files using an array of glob patterns 38 | // forceCoverageMatch: [], 39 | // A path to a module which exports an async function that is triggered once before all test suites 40 | // globalSetup: null, 41 | // A path to a module which exports an async function that is triggered once after all test suites 42 | // globalTeardown: null, 43 | // A set of global variables that need to be available in all test environments 44 | // globals: {}, 45 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. 46 | // maxWorkers: "50%", 47 | // An array of directory names to be searched recursively up from the requiring module's location 48 | // moduleDirectories: [ 49 | // "node_modules" 50 | // ], 51 | // An array of file extensions your modules use 52 | moduleFileExtensions: [ 53 | "js", 54 | "json", 55 | "jsx", 56 | "ts", 57 | "tsx", 58 | "node" 59 | ], 60 | // A map from regular expressions to module names that allow to stub out resources with a single module 61 | // moduleNameMapper: {}, 62 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 63 | // modulePathIgnorePatterns: [], 64 | // Activates notifications for test results 65 | // notify: false, 66 | // An enum that specifies notification mode. Requires { notify: true } 67 | // notifyMode: "failure-change", 68 | // A preset that is used as a base for Jest's configuration 69 | // preset: null, 70 | // Run tests from one or more projects 71 | // projects: null, 72 | // Use this configuration option to add custom reporters to Jest 73 | // reporters: undefined, 74 | // Automatically reset mock state between every test 75 | // resetMocks: false, 76 | // Reset the module registry before running each individual test 77 | // resetModules: false, 78 | // A path to a custom resolver 79 | // resolver: null, 80 | // Automatically restore mock state between every test 81 | // restoreMocks: false, 82 | // The root directory that Jest should scan for tests and modules within 83 | // rootDir: null, 84 | // A list of paths to directories that Jest should use to search for files in 85 | // roots: [ 86 | // "" 87 | // ], 88 | // Allows you to use a custom runner instead of Jest's default test runner 89 | // runner: "jest-runner", 90 | // The paths to modules that run some code to configure or set up the testing environment before each test 91 | // setupFiles: [], 92 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 93 | // setupFilesAfterEnv: [], 94 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 95 | // snapshotSerializers: [], 96 | // The test environment that will be used for testing 97 | testEnvironment: "node", 98 | // Options that will be passed to the testEnvironment 99 | // testEnvironmentOptions: {}, 100 | // Adds a location field to test results 101 | // testLocationInResults: false, 102 | // The glob patterns Jest uses to detect test files 103 | // testMatch: [ 104 | // "**/__tests__/**/*.[jt]s?(x)", 105 | // "**/?(*.)+(spec|test).[tj]s?(x)" 106 | // ], 107 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 108 | // testPathIgnorePatterns: [ 109 | // "/node_modules/" 110 | // ], 111 | // The regexp pattern or array of patterns that Jest uses to detect test files 112 | testRegex: ['(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$'], 113 | // This option allows the use of a custom results processor 114 | // testResultsProcessor: null, 115 | // This option allows use of a custom test runner 116 | // testRunner: "jasmine2", 117 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href 118 | // testURL: "http://localhost", 119 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" 120 | // timers: "real", 121 | // A map from regular expressions to paths to transformers 122 | transform: { 123 | '^.+\\.tsx?$': 'ts-jest', 124 | }, 125 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 126 | // transformIgnorePatterns: [ 127 | // "/node_modules/" 128 | // ], 129 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 130 | // unmockedModulePathPatterns: undefined, 131 | // Indicates whether each individual test should be reported during the run 132 | // verbose: null, 133 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 134 | // watchPathIgnorePatterns: [], 135 | // Whether to use watchman for file crawling 136 | // watchman: true, 137 | }; -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | /* eslint-disable class-methods-use-this */ 3 | /* eslint-disable no-continue */ 4 | class Dirext { 5 | constructor() { 6 | // an array of routes 7 | // @ts-ignore 8 | this.routes = []; 9 | 10 | // binding all HTTP req methods as methods on Dirext using bind and our set method 11 | // @ts-ignore 12 | this.get = this.set.bind(null, 'GET'); 13 | // @ts-ignore 14 | this.post = this.set.bind(null, 'POST'); 15 | // @ts-ignore 16 | this.put = this.set.bind(null, 'PUT'); 17 | // @ts-ignore 18 | this.patch = this.set.bind(null, 'PATCH'); 19 | // @ts-ignore 20 | this.delete = this.set.bind(null, 'DELETE'); 21 | // @ts-ignore 22 | this.head = this.set.bind(null, 'HEAD'); 23 | // @ts-ignore 24 | this.connect = this.set.bind(null, 'CONNECT'); 25 | // @ts-ignore 26 | this.options = this.set.bind(null, 'OPTIONS'); 27 | // @ts-ignore 28 | this.trace = this.set.bind(null, 'TRACE'); 29 | 30 | } 31 | 32 | // a helper function that takes each segment of a route and creates an array of key value pairs 33 | // edge case for global middleware 34 | routeSplitter(url: string) { 35 | if (url === '/' || url === '*' || url === 'global') return [{ route: url }]; 36 | // split route on each / then map through elements 37 | const route = url.split('/').splice(1).map((elem) => { 38 | // if element is a param return an object with key param value elem 39 | if (elem[0] === ':') return { param: elem.slice(1) }; 40 | // if element is a query string 41 | if (elem[0] === '?') { 42 | // split on & to seperate multiple queries 43 | const queryArr = elem.slice(1).split('&'); 44 | // reduce query arr to an object holding key query which holds key value pairs of queries 45 | return queryArr.reduce((obj, query) => { 46 | // @ts-ignore 47 | if (!obj.query) obj.query = {}; 48 | const split = query.split('='); 49 | // @ts-ignore 50 | obj.query[split[0]] = split[1]; 51 | return obj; 52 | }, {}); 53 | } 54 | // else return obj with key route and value of elem 55 | return { route: elem }; 56 | }); 57 | // return array of routes 58 | return route; 59 | } 60 | 61 | 62 | compareRoutes(currentRoute: object, splitRoute: object, loopLength: number) { 63 | const response = { 64 | match: true, 65 | }; 66 | for (let j = 0; j < loopLength; j += 1) { 67 | // confirm that all route segment objects hold the same value 68 | // @ts-ignore 69 | if (currentRoute.url[j].route && splitRoute[j].route) { 70 | // @ts-ignore 71 | if (currentRoute.url[j].route === splitRoute[j].route) { 72 | continue; 73 | // @ts-ignore 74 | } else if (currentRoute.url[j].route === '*' && splitRoute[j].route !== undefined) { 75 | return response; 76 | } else { 77 | response.match = false; 78 | return response; 79 | } 80 | // @ts-ignore 81 | } else if (currentRoute.url[j].param && splitRoute[j].route) { 82 | // if there is a param in url route, save variable and value to params obj 83 | // @ts-ignore 84 | const variable = currentRoute.url[j].param; 85 | const value = splitRoute[j].route; 86 | splitRoute[j].params = { [variable]: value }; 87 | // @ts-ignore 88 | if (!response.params) response.params = {}; 89 | // @ts-ignore 90 | response.params[variable] = value; 91 | // delete route obj now that we know it's a param 92 | delete splitRoute[j].route; 93 | // store new param object on response 94 | continue; 95 | // logic for handling wildcard routes 96 | } else { 97 | response.match = false; 98 | return response; 99 | } 100 | } 101 | return response; 102 | } 103 | 104 | // method to add routes for router to recognize 105 | set(method: string, url: string, ...middlewareFuncs: any) { 106 | // array of middleware functions 107 | const middleware = [...middlewareFuncs]; 108 | // push object with url, method, and middlware to routes 109 | // @ts-ignore 110 | this.routes.push({ url: this.routeSplitter(url), method, middleware }); 111 | return this; 112 | } 113 | 114 | // method to add middleware to routes without specific http req method 115 | use(url: string, ...middlewareFuncs: any) { 116 | if (typeof url !== 'string') { 117 | middlewareFuncs = [url, ...middlewareFuncs]; 118 | url = 'global'; 119 | } 120 | // array of middleware funcs 121 | const middleware = [...middlewareFuncs]; 122 | // push obect with url, method, and middleware to routes 123 | // @ts-ignore 124 | this.routes.push({ url: this.routeSplitter(url), method: '', middleware }); 125 | return this; 126 | } 127 | 128 | find(method: string, url: string) { 129 | // parse input route using routeSplitter helper function 130 | const splitRoute = this.routeSplitter(url); 131 | // initialize empty array to push middleware to 132 | const response = { 133 | middleware: [], 134 | params: {}, 135 | }; 136 | 137 | // initialize loopLength variable 138 | let loopLength; 139 | // check if input route contains a query at the end 140 | // @ts-ignore 141 | if (splitRoute[splitRoute.length - 1].query) { 142 | // assign query object to response object 143 | // @ts-ignore 144 | response.query = splitRoute[splitRoute.length - 1].query; 145 | // don't compare last obj in route array 146 | loopLength = splitRoute.length - 1; 147 | } else { 148 | loopLength = splitRoute.length; 149 | } 150 | // @ts-ignore 151 | for (let i = 0; i < this.routes.length; i += 1) { 152 | // @ts-ignore 153 | const currentRoute = this.routes[i]; 154 | // check if the route at i has a url of "global" 155 | if (currentRoute.url[0].route === 'global') { 156 | // if it does, push it to the middleware 157 | response.middleware.push(...currentRoute.middleware); 158 | } 159 | // check if the route at index i has a method 160 | else if (!currentRoute.method) { 161 | // if there is no method, push middleware and break out of the loop 162 | response.middleware.push(...currentRoute.middleware); 163 | break; 164 | } 165 | // otherwise compare the length of the two routes 166 | else if (currentRoute.url.length === loopLength && currentRoute.method === method) { 167 | // if they do match, push middleware to middleware array 168 | const result = this.compareRoutes(currentRoute, splitRoute, loopLength); // set default parameter for loop length? don't use it if it's a wildcard? 169 | if (result.match) { 170 | response.middleware.push(...currentRoute.middleware); 171 | // @ts-ignore 172 | if (result.params) response.params = { ...result.params }; 173 | } 174 | } else if (currentRoute.method === method) { 175 | // loop through currentRoute and compare each index with splitRoute 176 | const result = this.compareRoutes(currentRoute, splitRoute, loopLength); 177 | if (result.match) { 178 | response.middleware.push(...currentRoute.middleware); 179 | // @ts-ignore 180 | if (result.params) response.params = { ...result.params }; 181 | } 182 | } 183 | } 184 | return response; 185 | } 186 | } 187 | 188 | module.exports = Dirext; 189 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dirext-js", 3 | "version": "1.0.5", 4 | "description": "A lightweight routing solution for Node.js", 5 | "main": "lib/index.js", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "setup": "npm install", 9 | "build": "tsc lib/index.ts", 10 | "test": "jest" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/dirext-js/dirext.git" 15 | }, 16 | "author": "Eli Gallipoli, Alex Kang, Izumi Sato, Sara Powers", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/dirext-js/dirext/issues" 20 | }, 21 | "homepage": "https://github.com/dirext-js/dirext#readme", 22 | "keywords": [ 23 | "router", 24 | "routing", 25 | "middleware", 26 | "route" 27 | ], 28 | "dependencies": { 29 | "@types/node": "^13.7.7" 30 | }, 31 | "devDependencies": { 32 | "@types/jest": "^25.1.3", 33 | "jest": "^25.1.0", 34 | "ts-jest": "^25.2.1", 35 | "typescript": "^3.8.2" 36 | }, 37 | "prepublish": "tsc" 38 | } 39 | -------------------------------------------------------------------------------- /practice.js: -------------------------------------------------------------------------------- 1 | const Dirext = require('./index.js'); 2 | const router = new Dirext(); 3 | 4 | router.use(middleware2, middleware4); 5 | console.log(router.routes) 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | // "incremental": true, /* Enable incremental compilation */ 5 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 6 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 7 | // "lib": [], /* Specify library files to be included in the compilation. */ 8 | // "allowJs": true, /* Allow javascript files to be compiled. */ 9 | // "checkJs": true, /* Report errors in .js files. */ 10 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 11 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 12 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 13 | "sourceMap": true, /* Generates corresponding '.map' file. */ 14 | // "outFile": "./", /* Concatenate and emit output to single file. */ 15 | // "outDir": "./", /* Redirect output structure to the directory. */ 16 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 17 | // "composite": true, /* Enable project compilation */ 18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 19 | // "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": true, /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 34 | 35 | /* Additional Checks */ 36 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 40 | 41 | /* Module Resolution Options */ 42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 46 | // "typeRoots": [], /* List of folders to include type definitions from. */ 47 | // "types": [], /* Type declaration files to be included in compilation. */ 48 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 49 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 50 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 51 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 52 | 53 | /* Source Map Options */ 54 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 55 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 56 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 57 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 58 | 59 | /* Experimental Options */ 60 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 61 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 62 | 63 | /* Advanced Options */ 64 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 65 | }, 66 | "include": [ 67 | "./src/**/*.ts" 68 | ] 69 | } 70 | --------------------------------------------------------------------------------