├── .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 | 
2 |
3 | 🚧 A lightweight routing solution for Node.js. 🚧 [](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 |
--------------------------------------------------------------------------------