express-generator-typescript 2.0.0 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/lib/express-generator-typescript.js +19 -24
- package/lib/project-files/.eslintrc.json +1 -0
- package/lib/project-files/spec/support/login-agent.ts +6 -8
- package/lib/project-files/spec/tests/users.spec.ts +1 -1
- package/lib/project-files/spec/types/supertest/index.d.ts +2 -2
- package/lib/project-files/src/repos/mock-orm.ts +2 -2
- package/lib/project-files/src/repos/user-repo.ts +6 -6
- package/lib/project-files/src/routes/auth-router.ts +5 -4
- package/lib/project-files/src/routes/middleware.ts +2 -2
- package/lib/project-files/src/routes/user-router.ts +1 -1
- package/lib/project-files/src/services/auth-service.ts +1 -1
- package/lib/project-files/src/shared/types.ts +14 -0
- package/lib/project-files/src/types/express/index.d.ts +0 -14
- package/lib/project-files/src/util/jwt-util.ts +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,6 @@ Creates a new express application similar to the _express-generator_ module. Exc
|
|
|
13
13
|
application is configured to use TypeScript instead of plain JavaScript.
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
## Why express-generator-typescript?
|
|
18
17
|
|
|
19
18
|
NodeJS is great for the rapid development of web-projects, but is often neglected because of the lack of
|
|
@@ -97,7 +96,7 @@ In previous version of __express-generator-typescript__ you could disregard auth
|
|
|
97
96
|
command line options. But maintaining two separate project folders which contained and didn't contain
|
|
98
97
|
authentication started to get messy.
|
|
99
98
|
|
|
100
|
-
- Remove following modules from `package.json`:
|
|
99
|
+
- Remove the following modules from `package.json`:
|
|
101
100
|
- `jsonwebtoken`
|
|
102
101
|
- `@types/jsonwebtoken`
|
|
103
102
|
- `bcrypt`
|
|
@@ -157,7 +156,6 @@ To be able to debug in VSCODE on windows I also had to install the `node-gyp` mo
|
|
|
157
156
|
Happy web deving :)
|
|
158
157
|
|
|
159
158
|
|
|
160
|
-
|
|
161
159
|
## License
|
|
162
160
|
|
|
163
161
|
[MIT](LICENSE)
|
|
@@ -13,14 +13,27 @@ const fs = require('fs');
|
|
|
13
13
|
|
|
14
14
|
// **** Variables **** //
|
|
15
15
|
|
|
16
|
+
// Misc
|
|
16
17
|
const prjFolder = './project-files';
|
|
17
18
|
|
|
19
|
+
// ncp options
|
|
18
20
|
const ncpOpts = {
|
|
19
21
|
filter: (fileName) => {
|
|
20
22
|
return !(fileName === 'package-lock.json' || fileName === 'node_modules');
|
|
21
23
|
},
|
|
22
24
|
};
|
|
23
25
|
|
|
26
|
+
// Project-folder dependencies
|
|
27
|
+
const dependencies = 'express dotenv http-status-codes morgan cookie-parser jet-logger ' +
|
|
28
|
+
'module-alias command-line-args express-async-errors helmet jsonfile bcrypt jsonwebtoken';
|
|
29
|
+
|
|
30
|
+
// Project-folder development dependencies
|
|
31
|
+
const devDependencies = 'ts-node typescript nodemon find jasmine supertest ' +
|
|
32
|
+
'@types/node @types/express @types/jasmine @types/find @types/morgan @types/cookie-parser ' +
|
|
33
|
+
'@types/supertest fs-extra tsconfig-paths @types/jsonfile @types/command-line-args ' +
|
|
34
|
+
'@typescript-eslint/eslint-plugin @typescript-eslint/parser eslint @types/fs-extra ' +
|
|
35
|
+
'@types/bcrypt @types/jsonwebtoken eslint-plugin-node';
|
|
36
|
+
|
|
24
37
|
|
|
25
38
|
// **** Functions **** //
|
|
26
39
|
|
|
@@ -32,8 +45,7 @@ async function expressGenTs(destination, useYarn) {
|
|
|
32
45
|
await copyProjectFiles(destination);
|
|
33
46
|
updatePackageJson(destination);
|
|
34
47
|
await renameGitigoreFile(destination);
|
|
35
|
-
|
|
36
|
-
downloadNodeModules(destination, depStrings, useYarn);
|
|
48
|
+
downloadNodeModules(destination, useYarn);
|
|
37
49
|
} catch (err) {
|
|
38
50
|
console.error(err);
|
|
39
51
|
}
|
|
@@ -75,36 +87,19 @@ function renameGitigoreFile(destination) {
|
|
|
75
87
|
});
|
|
76
88
|
}
|
|
77
89
|
|
|
78
|
-
/**
|
|
79
|
-
* Setup dependency strings. This way gets you the latest version of everything.
|
|
80
|
-
*/
|
|
81
|
-
function getDepStrings() {
|
|
82
|
-
let dependencies = 'express dotenv http-status-codes morgan cookie-parser jet-logger ' +
|
|
83
|
-
'module-alias command-line-args express-async-errors helmet jsonfile bcrypt ' +
|
|
84
|
-
'jsonwebtoken';
|
|
85
|
-
let devDependencies = 'ts-node typescript nodemon find jasmine supertest ' +
|
|
86
|
-
'@types/node @types/express @types/jasmine @types/find @types/morgan ' +
|
|
87
|
-
'@types/cookie-parser @types/supertest fs-extra tsconfig-paths @types/jsonfile ' +
|
|
88
|
-
'@types/command-line-args @typescript-eslint/eslint-plugin @typescript-eslint/parser ' +
|
|
89
|
-
'eslint @types/fs-extra @types/bcrypt @types/jsonwebtoken ' +
|
|
90
|
-
'eslint-plugin-node';
|
|
91
|
-
// Return
|
|
92
|
-
return { dependencies, devDependencies };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
90
|
/**
|
|
96
91
|
* Download the dependencies.
|
|
97
92
|
*/
|
|
98
|
-
function downloadNodeModules(destination,
|
|
93
|
+
function downloadNodeModules(destination, useYarn) {
|
|
99
94
|
const options = {cwd: destination};
|
|
100
95
|
let downloadLibCmd;
|
|
101
96
|
let downloadDepCmd;
|
|
102
97
|
if (useYarn) {
|
|
103
|
-
downloadLibCmd = 'yarn add ' +
|
|
104
|
-
downloadDepCmd = 'yarn add ' +
|
|
98
|
+
downloadLibCmd = 'yarn add ' + dependencies;
|
|
99
|
+
downloadDepCmd = 'yarn add ' + devDependencies + ' -D';
|
|
105
100
|
} else {
|
|
106
|
-
downloadLibCmd = 'npm i -s ' +
|
|
107
|
-
downloadDepCmd = 'npm i -D ' +
|
|
101
|
+
downloadLibCmd = 'npm i -s ' + dependencies;
|
|
102
|
+
downloadDepCmd = 'npm i -D ' + devDependencies;
|
|
108
103
|
}
|
|
109
104
|
childProcess.execSync(downloadLibCmd, options);
|
|
110
105
|
childProcess.execSync(downloadDepCmd, options);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import bcrypt from 'bcrypt';
|
|
2
|
-
import { SuperTest, Test } from 'supertest';
|
|
2
|
+
import { SuperTest, Test, Response } from 'supertest';
|
|
3
3
|
|
|
4
4
|
import User, { UserRoles } from '@models/user-model';
|
|
5
5
|
import userRepo from '@repos/user-repo';
|
|
@@ -19,9 +19,6 @@ const creds = {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Login a user.
|
|
22
|
-
*
|
|
23
|
-
* @param beforeAgent
|
|
24
|
-
* @param done
|
|
25
22
|
*/
|
|
26
23
|
function login(beforeAgent: SuperTest<Test>, done: (arg: string) => void) {
|
|
27
24
|
// Setup dummy data
|
|
@@ -34,17 +31,18 @@ function login(beforeAgent: SuperTest<Test>, done: (arg: string) => void) {
|
|
|
34
31
|
.post('/api/auth/login')
|
|
35
32
|
.type('form')
|
|
36
33
|
.send(creds)
|
|
37
|
-
.end((err: Error, res:
|
|
34
|
+
.end((err: Error, res: Response) => {
|
|
38
35
|
if (err) {
|
|
39
36
|
throw err;
|
|
40
37
|
}
|
|
41
|
-
|
|
38
|
+
const cookie = res.headers['set-cookie'][0];
|
|
39
|
+
return done(cookie);
|
|
42
40
|
});
|
|
43
|
-
}
|
|
41
|
+
}
|
|
44
42
|
|
|
45
43
|
|
|
46
44
|
// **** Export default **** //
|
|
47
45
|
|
|
48
46
|
export default {
|
|
49
|
-
|
|
47
|
+
login,
|
|
50
48
|
} as const;
|
|
@@ -79,10 +79,10 @@ async function _delete(id: number): Promise<void> {
|
|
|
79
79
|
// **** Export default **** //
|
|
80
80
|
|
|
81
81
|
export default {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
getOne,
|
|
83
|
+
persists,
|
|
84
|
+
getAll,
|
|
85
|
+
add,
|
|
86
|
+
update,
|
|
87
|
+
delete: _delete,
|
|
88
88
|
} as const;
|
|
@@ -4,7 +4,7 @@ import StatusCodes from 'http-status-codes';
|
|
|
4
4
|
import authService from '@services/auth-service';
|
|
5
5
|
import { ParamMissingError } from '@shared/errors';
|
|
6
6
|
import envVars from 'src/shared/env-vars';
|
|
7
|
-
import { IReq } from '
|
|
7
|
+
import { IReq } from '@shared/types';
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
// **** Types **** //
|
|
@@ -17,9 +17,10 @@ interface ILoginReq {
|
|
|
17
17
|
|
|
18
18
|
// **** Variables **** //
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
const router = Router();
|
|
21
|
+
|
|
22
|
+
// Status codes
|
|
23
|
+
const { OK } = StatusCodes;
|
|
23
24
|
|
|
24
25
|
// Paths
|
|
25
26
|
export const p = {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import StatusCodes from 'http-status-codes';
|
|
2
2
|
import { Request, Response, NextFunction } from 'express';
|
|
3
|
+
import { JwtPayload } from 'jsonwebtoken';
|
|
3
4
|
|
|
4
5
|
import { IUser, UserRoles } from '@models/user-model';
|
|
5
6
|
import envVars from 'src/shared/env-vars';
|
|
6
7
|
import jwtUtil from '@util/jwt-util';
|
|
7
|
-
import { JwtPayload } from 'jsonwebtoken';
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
// **** Variables **** //
|
|
@@ -38,7 +38,7 @@ export async function adminMw(req: Request, res: Response, next: NextFunction) {
|
|
|
38
38
|
}
|
|
39
39
|
// Make sure user role is an admin
|
|
40
40
|
const clientData = await jwtUtil.decode<ISessionUser>(jwt);
|
|
41
|
-
if (clientData.role === UserRoles.Admin) {
|
|
41
|
+
if (typeof clientData === 'object' && clientData.role === UserRoles.Admin) {
|
|
42
42
|
res.locals.sessionUser = clientData;
|
|
43
43
|
next();
|
|
44
44
|
} else {
|
|
@@ -4,7 +4,7 @@ import { Request, Response, Router } from 'express';
|
|
|
4
4
|
import userService from '@services/user-service';
|
|
5
5
|
import { ParamMissingError } from '@shared/errors';
|
|
6
6
|
import { IUser } from '@models/user-model';
|
|
7
|
-
import { IReq } from '
|
|
7
|
+
import { IReq } from '@shared/types';
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
// **** Variables **** //
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as e from 'express';
|
|
2
|
+
import { Query } from 'express-serve-static-core';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// **** Generics for Request Object **** //
|
|
6
|
+
|
|
7
|
+
export interface IReq<T> extends e.Request {
|
|
8
|
+
body: T;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IReqQuery<T extends Query, U = void> extends e.Request {
|
|
12
|
+
query: T;
|
|
13
|
+
body: U;
|
|
14
|
+
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import 'express';
|
|
2
|
-
import * as e from 'express';
|
|
3
|
-
import { Query } from 'express-serve-static-core';
|
|
4
2
|
|
|
5
3
|
import { ISessionUser } from '@routes/middleware';
|
|
6
4
|
|
|
@@ -20,15 +18,3 @@ declare module 'express' {
|
|
|
20
18
|
};
|
|
21
19
|
}
|
|
22
20
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// **** Generics for Request Object **** //
|
|
26
|
-
|
|
27
|
-
export interface IReq<T> extends e.Request {
|
|
28
|
-
body: T;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface IReqQuery<T extends Query, U = void> extends e.Request {
|
|
32
|
-
query: T;
|
|
33
|
-
body?: U;
|
|
34
|
-
}
|
|
@@ -6,7 +6,7 @@ import envVars from '../shared/env-vars';
|
|
|
6
6
|
|
|
7
7
|
// Errors
|
|
8
8
|
const errors = {
|
|
9
|
-
|
|
9
|
+
validation: 'JSON-web-token validation failed.',
|
|
10
10
|
} as const;
|
|
11
11
|
|
|
12
12
|
// Options
|
|
@@ -20,10 +20,10 @@ const options = {
|
|
|
20
20
|
/**
|
|
21
21
|
* Encrypt data and return jwt.
|
|
22
22
|
*/
|
|
23
|
-
function sign(data:
|
|
24
|
-
return new Promise((
|
|
23
|
+
function sign(data: string | object | Buffer): Promise<string> {
|
|
24
|
+
return new Promise((res, rej) => {
|
|
25
25
|
jsonwebtoken.sign(data, envVars.jwt.secret, options, (err, token) => {
|
|
26
|
-
return err ?
|
|
26
|
+
return err ? rej(err) : res(token || '');
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
29
|
}
|
|
@@ -31,7 +31,7 @@ function sign(data: JwtPayload): Promise<string> {
|
|
|
31
31
|
/**
|
|
32
32
|
* Decrypt JWT and extract client data.
|
|
33
33
|
*/
|
|
34
|
-
function decode<T>(jwt: string): Promise<T> {
|
|
34
|
+
async function decode<T extends JwtPayload>(jwt: string): Promise<string | undefined | T> {
|
|
35
35
|
return new Promise((res, rej) => {
|
|
36
36
|
jsonwebtoken.verify(jwt, envVars.jwt.secret, (err, decoded) => {
|
|
37
37
|
return err ? rej(errors.validation) : res(decoded as T);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-generator-typescript",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Generate new Express applications similar to express-generate which but sets it up to use TypeScript instead",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"express-generator-typescript": "node bin/cli.js",
|