express-generator-typescript 2.4.6 → 2.4.8
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/lib/express-generator-typescript.js +1 -1
- package/lib/project-files/package.json +4 -3
- package/lib/project-files/spec/support/apiCb.ts +76 -0
- package/lib/project-files/spec/tests/users.spec.ts +102 -127
- package/lib/project-files/spec/types/misc.ts +18 -0
- package/lib/project-files/src/models/User.ts +13 -27
- package/lib/project-files/src/public/scripts/http.js +3 -1
- package/lib/project-files/src/public/scripts/users.js +31 -65
- package/lib/project-files/src/public/stylesheets/users.css +4 -6
- package/lib/project-files/src/repos/UserRepo.ts +6 -1
- package/lib/project-files/src/repos/database.json +22 -1
- package/lib/project-files/src/routes/types/express/misc.ts +1 -5
- package/lib/project-files/src/routes/types/types.ts +0 -8
- package/lib/project-files/src/views/users.html +100 -5
- package/lib/project-files-auth/package.json +4 -3
- package/lib/project-files-auth/spec/support/apiCb.ts +76 -0
- package/lib/project-files-auth/spec/support/login.ts +6 -8
- package/lib/project-files-auth/spec/tests/auth.spec.ts +52 -59
- package/lib/project-files-auth/spec/tests/users.spec.ts +101 -133
- package/lib/project-files-auth/spec/types/misc.ts +18 -0
- package/lib/project-files-auth/src/models/User.ts +17 -12
- package/lib/project-files-auth/src/public/scripts/http.js +3 -1
- package/lib/project-files-auth/src/public/scripts/login.js +1 -3
- package/lib/project-files-auth/src/public/scripts/users.js +31 -63
- package/lib/project-files-auth/src/public/stylesheets/users.css +4 -11
- package/lib/project-files-auth/src/repos/UserRepo.ts +6 -1
- package/lib/project-files-auth/src/repos/database.json +1 -1
- package/lib/project-files-auth/src/services/UserService.ts +2 -8
- package/lib/project-files-auth/src/views/login.html +26 -3
- package/lib/project-files-auth/src/views/users.html +106 -8
- package/package.json +1 -1
- package/lib/project-files/spec/support/types.ts +0 -1
- package/lib/project-files-auth/spec/support/types.ts +0 -1
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
//
|
|
1
|
+
// **** Variables **** //
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const DateFormatter = new Intl.DateTimeFormat('en-US', {
|
|
4
|
+
year: 'numeric',
|
|
5
|
+
month: '2-digit',
|
|
6
|
+
day: '2-digit',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const formatDate = (date) => DateFormatter.format(new Date(date));
|
|
4
10
|
|
|
5
11
|
|
|
6
|
-
//
|
|
12
|
+
// **** Run **** //
|
|
13
|
+
|
|
14
|
+
// Start
|
|
15
|
+
displayUsers();
|
|
7
16
|
|
|
8
17
|
/**
|
|
9
18
|
* Call api
|
|
@@ -12,59 +21,22 @@ function displayUsers() {
|
|
|
12
21
|
Http
|
|
13
22
|
.get('/api/users/all')
|
|
14
23
|
.then(resp => resp.json())
|
|
15
|
-
.then(
|
|
16
|
-
var
|
|
17
|
-
|
|
24
|
+
.then(resp => {
|
|
25
|
+
var allUsersTemplate = document.getElementById('all-users-template'),
|
|
26
|
+
allUsersTemplateHtml = allUsersTemplate.innerHTML,
|
|
27
|
+
template = Handlebars.compile(allUsersTemplateHtml);
|
|
18
28
|
var allUsersAnchor = document.getElementById('all-users-anchor');
|
|
19
|
-
allUsersAnchor.innerHTML =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
allUsersAnchor.innerHTML = template({
|
|
30
|
+
users: resp.users.map(user => ({
|
|
31
|
+
...user,
|
|
32
|
+
createdFormatted: formatDate(user.created),
|
|
33
|
+
})),
|
|
23
34
|
});
|
|
24
35
|
});
|
|
25
36
|
}
|
|
26
37
|
|
|
27
|
-
/**
|
|
28
|
-
* Get user display element
|
|
29
|
-
*/
|
|
30
|
-
function getUserDisplayEle(user) {
|
|
31
|
-
return (
|
|
32
|
-
`<div class="user-display-ele">
|
|
33
|
-
|
|
34
|
-
<div class="normal-view">
|
|
35
|
-
<div>Name: ${user.name}</div>
|
|
36
|
-
<div>Email: ${user.email}</div>
|
|
37
|
-
<button class="edit-user-btn" data-user-id="${user.id}" data-user-role="${user.role}">
|
|
38
|
-
Edit
|
|
39
|
-
</button>
|
|
40
|
-
<button class="delete-user-btn" data-user-id="${user.id}">
|
|
41
|
-
Delete
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<div class="edit-view">
|
|
46
|
-
<div>
|
|
47
|
-
Name: <input class="name-edit-input" value="${user.name}">
|
|
48
|
-
</div>
|
|
49
|
-
<div>
|
|
50
|
-
Email: <input class="email-edit-input" value="${user.email}">
|
|
51
|
-
</div>
|
|
52
|
-
<button class="submit-edit-btn" data-user-id="${user.id}">
|
|
53
|
-
Submit
|
|
54
|
-
</button>
|
|
55
|
-
<button class="cancel-edit-btn" data-user-id="${user.id}">
|
|
56
|
-
Cancel
|
|
57
|
-
</button>
|
|
58
|
-
</div>
|
|
59
|
-
</div>`
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// **** Add, Edit, and Delete Users **** //
|
|
65
|
-
|
|
66
38
|
// Setup event listener for button click
|
|
67
|
-
document.addEventListener('click',
|
|
39
|
+
document.addEventListener('click', event => {
|
|
68
40
|
event.preventDefault();
|
|
69
41
|
var ele = event.target;
|
|
70
42
|
if (ele.matches('#add-user-btn')) {
|
|
@@ -93,13 +65,17 @@ function addUser() {
|
|
|
93
65
|
id: -1,
|
|
94
66
|
name: nameInput.value,
|
|
95
67
|
email: emailInput.value,
|
|
96
|
-
|
|
68
|
+
created: new Date(),
|
|
97
69
|
},
|
|
98
70
|
};
|
|
99
71
|
// Call api
|
|
100
72
|
Http
|
|
101
73
|
.post('/api/users/add', data)
|
|
102
|
-
.then(() =>
|
|
74
|
+
.then(() => {
|
|
75
|
+
nameInput.value = '';
|
|
76
|
+
emailInput.value = '';
|
|
77
|
+
displayUsers();
|
|
78
|
+
});
|
|
103
79
|
}
|
|
104
80
|
|
|
105
81
|
/**
|
|
@@ -130,13 +106,14 @@ function submitEdit(ele) {
|
|
|
130
106
|
var nameInput = userEle.getElementsByClassName('name-edit-input')[0];
|
|
131
107
|
var emailInput = userEle.getElementsByClassName('email-edit-input')[0];
|
|
132
108
|
var id = ele.getAttribute('data-user-id');
|
|
133
|
-
var
|
|
109
|
+
var created = ele.getAttribute('data-user-created');
|
|
110
|
+
console.log(ele, created)
|
|
134
111
|
var data = {
|
|
135
112
|
user: {
|
|
136
113
|
id: Number(id),
|
|
137
114
|
name: nameInput.value,
|
|
138
115
|
email: emailInput.value,
|
|
139
|
-
|
|
116
|
+
created: new Date(created),
|
|
140
117
|
},
|
|
141
118
|
};
|
|
142
119
|
Http
|
|
@@ -153,12 +130,3 @@ function deleteUser(ele) {
|
|
|
153
130
|
.delete('/api/users/delete/' + id)
|
|
154
131
|
.then(() => displayUsers());
|
|
155
132
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// **** Logout **** //
|
|
159
|
-
|
|
160
|
-
function logoutUser() {
|
|
161
|
-
Http
|
|
162
|
-
.get('/api/auth/logout')
|
|
163
|
-
.then(() => window.location.href = '/');
|
|
164
|
-
}
|
|
@@ -22,20 +22,13 @@ body .add-user-col input {
|
|
|
22
22
|
margin-bottom: 10px;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
body .add-user-col #add-user-btn {
|
|
26
|
-
margin-top: 2px;
|
|
27
|
-
margin-bottom: 10px;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
body .add-user-col #logout-btn {
|
|
31
|
-
margin-top: 25px;
|
|
32
|
-
margin-bottom: 10px;
|
|
33
|
-
font-size: 15px;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
|
|
37
26
|
/** Users Display Column **/
|
|
38
27
|
|
|
28
|
+
.email-edit {
|
|
29
|
+
padding-bottom: 8px;
|
|
30
|
+
}
|
|
31
|
+
|
|
39
32
|
body .users-column .user-display-ele {
|
|
40
33
|
padding-bottom: 10px;
|
|
41
34
|
}
|
|
@@ -56,7 +56,12 @@ async function update(user: IUser): Promise<void> {
|
|
|
56
56
|
const db = await orm.openDb();
|
|
57
57
|
for (let i = 0; i < db.users.length; i++) {
|
|
58
58
|
if (db.users[i].id === user.id) {
|
|
59
|
-
db.users[i]
|
|
59
|
+
const dbUser = db.users[i];
|
|
60
|
+
db.users[i] = {
|
|
61
|
+
...dbUser,
|
|
62
|
+
name: user.name,
|
|
63
|
+
email: user.email,
|
|
64
|
+
};
|
|
60
65
|
return orm.saveDb(db);
|
|
61
66
|
}
|
|
62
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"users":[{"name":"Sean Maxwell","email":"sean.maxwell@gmail.com","pwdHash":"$2b$12$1mE2OI9hMS/rgH9Mi0s85OM2V5gzm7aF3gJIWH1y0S1MqVBueyjsy","role":1,"id":159123164363},{"name":"
|
|
1
|
+
{"users":[{"name":"Sean Maxwell","email":"sean.maxwell@gmail.com","pwdHash":"$2b$12$1mE2OI9hMS/rgH9Mi0s85OM2V5gzm7aF3gJIWH1y0S1MqVBueyjsy","role":1,"id":159123164363,"created":"2024-03-22T05:20:55.079Z"},{"name":"John Smith","email":"john.smith@yahoo.com","pwdHash":"$2b$12$1mE2OI9hMS/rgH9Mi0s85OM2V5gzm7aF3gJIWH1y0S1MqVBueyjsy","role":0,"id":357437875835,"created":"2024-03-22T05:20:55.079Z"},{"id":28541714318,"name":"Gordan Freeman","email":"nova@prospect.com","created":"2024-03-23T15:56:42.615Z"}]}
|
|
@@ -31,10 +31,7 @@ function addOne(user: IUser): Promise<void> {
|
|
|
31
31
|
async function updateOne(user: IUser): Promise<void> {
|
|
32
32
|
const persists = await UserRepo.persists(user.id);
|
|
33
33
|
if (!persists) {
|
|
34
|
-
throw new RouteError(
|
|
35
|
-
HttpStatusCodes.NOT_FOUND,
|
|
36
|
-
USER_NOT_FOUND_ERR,
|
|
37
|
-
);
|
|
34
|
+
throw new RouteError(HttpStatusCodes.NOT_FOUND, USER_NOT_FOUND_ERR);
|
|
38
35
|
}
|
|
39
36
|
// Return user
|
|
40
37
|
return UserRepo.update(user);
|
|
@@ -46,10 +43,7 @@ async function updateOne(user: IUser): Promise<void> {
|
|
|
46
43
|
async function _delete(id: number): Promise<void> {
|
|
47
44
|
const persists = await UserRepo.persists(id);
|
|
48
45
|
if (!persists) {
|
|
49
|
-
throw new RouteError(
|
|
50
|
-
HttpStatusCodes.NOT_FOUND,
|
|
51
|
-
USER_NOT_FOUND_ERR,
|
|
52
|
-
);
|
|
46
|
+
throw new RouteError(HttpStatusCodes.NOT_FOUND, USER_NOT_FOUND_ERR);
|
|
53
47
|
}
|
|
54
48
|
// Delete user
|
|
55
49
|
return UserRepo.delete(id);
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<!-- Head -->
|
|
3
5
|
<head>
|
|
4
6
|
<meta charset="UTF-8">
|
|
5
7
|
<title>Login</title>
|
|
6
8
|
<link rel="stylesheet" type="text/css" href="/stylesheets/login.css" />
|
|
9
|
+
|
|
10
|
+
<!-- Handlebars -->
|
|
11
|
+
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>
|
|
12
|
+
|
|
13
|
+
<!-- Bootstrap -->
|
|
14
|
+
<link
|
|
15
|
+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
|
16
|
+
rel="stylesheet"
|
|
17
|
+
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
|
18
|
+
crossorigin="anonymous"
|
|
19
|
+
/>
|
|
20
|
+
<script
|
|
21
|
+
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
|
22
|
+
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
|
23
|
+
crossorigin="anonymous"
|
|
24
|
+
></script>
|
|
7
25
|
</head>
|
|
26
|
+
|
|
27
|
+
<!-- Body -->
|
|
8
28
|
<body>
|
|
9
29
|
|
|
10
30
|
<div class="login-block">
|
|
@@ -12,16 +32,18 @@
|
|
|
12
32
|
|
|
13
33
|
<div class="login-input">
|
|
14
34
|
Username:<br/>
|
|
15
|
-
<input id="email-input" type="text"/>
|
|
35
|
+
<input id="email-input" type="text" class="form-control"/>
|
|
16
36
|
</div>
|
|
17
37
|
|
|
18
38
|
<div class="login-input">
|
|
19
39
|
Password:<br/>
|
|
20
|
-
<input id="pwd-input" type="password"/>
|
|
40
|
+
<input id="pwd-input" type="password" class="form-control"/>
|
|
21
41
|
</div>
|
|
22
42
|
|
|
23
43
|
<div>
|
|
24
|
-
<button id="login-btn">
|
|
44
|
+
<button id="login-btn" class="btn btn-primary">
|
|
45
|
+
Login
|
|
46
|
+
</button>
|
|
25
47
|
</div>
|
|
26
48
|
|
|
27
49
|
<div class="default-login-user">
|
|
@@ -30,6 +52,7 @@
|
|
|
30
52
|
</div>
|
|
31
53
|
|
|
32
54
|
</body>
|
|
55
|
+
|
|
33
56
|
<script src="scripts/http.js"></script>
|
|
34
57
|
<script src="scripts/login.js"></script>
|
|
35
58
|
</html>
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<!-- Head -->
|
|
3
5
|
<head>
|
|
4
6
|
<meta charset="UTF-8">
|
|
5
7
|
<title>Users</title>
|
|
6
8
|
<link rel="stylesheet" type="text/css" href="/stylesheets/users.css" />
|
|
9
|
+
|
|
10
|
+
<!-- Handlebars -->
|
|
11
|
+
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.8/handlebars.min.js"></script>
|
|
12
|
+
|
|
13
|
+
<!-- Bootstrap -->
|
|
14
|
+
<link
|
|
15
|
+
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
|
|
16
|
+
rel="stylesheet"
|
|
17
|
+
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
|
18
|
+
crossorigin="anonymous"
|
|
19
|
+
/>
|
|
20
|
+
<script
|
|
21
|
+
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
|
|
22
|
+
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
|
|
23
|
+
crossorigin="anonymous"
|
|
24
|
+
></script>
|
|
7
25
|
</head>
|
|
26
|
+
|
|
27
|
+
<!-- Body -->
|
|
8
28
|
<body>
|
|
9
29
|
|
|
10
30
|
<!-- Add Users -->
|
|
@@ -13,18 +33,32 @@
|
|
|
13
33
|
Add User:
|
|
14
34
|
</div>
|
|
15
35
|
<div>
|
|
16
|
-
<input
|
|
36
|
+
<input
|
|
37
|
+
id="name-input"
|
|
38
|
+
type="text"
|
|
39
|
+
class="form-control"
|
|
40
|
+
placeholder="Name"
|
|
41
|
+
/>
|
|
17
42
|
</div>
|
|
18
43
|
<div>
|
|
19
|
-
<input
|
|
44
|
+
<input
|
|
45
|
+
id="email-input"
|
|
46
|
+
type="email"
|
|
47
|
+
class="form-control"
|
|
48
|
+
placeholder="Email"
|
|
49
|
+
/>
|
|
20
50
|
</div>
|
|
21
51
|
<div>
|
|
22
|
-
<button
|
|
52
|
+
<button
|
|
53
|
+
id="add-user-btn"
|
|
54
|
+
class="btn btn-success"
|
|
55
|
+
>
|
|
23
56
|
Add
|
|
24
57
|
</button>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
58
|
+
<button
|
|
59
|
+
id="logout-btn"
|
|
60
|
+
class="btn btn-secondary"
|
|
61
|
+
>
|
|
28
62
|
Logout
|
|
29
63
|
</button>
|
|
30
64
|
</div>
|
|
@@ -32,11 +66,75 @@
|
|
|
32
66
|
|
|
33
67
|
<!-- Display Users -->
|
|
34
68
|
<div class="users-column">
|
|
35
|
-
<div class="column-header">
|
|
69
|
+
<div class="column-header">
|
|
70
|
+
Users:
|
|
71
|
+
</div>
|
|
72
|
+
|
|
36
73
|
<div id="all-users-anchor"></div>
|
|
37
|
-
|
|
74
|
+
<script
|
|
75
|
+
id="all-users-template"
|
|
76
|
+
type="text/x-handlebars-template"
|
|
77
|
+
>
|
|
78
|
+
{{#each users}}
|
|
79
|
+
<div class="user-display-ele">
|
|
80
|
+
<div class="normal-view">
|
|
81
|
+
<div class="display-wrapper">
|
|
82
|
+
<div><b>Name:</b> {{name}}</div>
|
|
83
|
+
<div><b>Email:</b> {{email}}</div>
|
|
84
|
+
<div><b>Created:</b> {{createdFormatted}}</div>
|
|
85
|
+
</div>
|
|
86
|
+
<button
|
|
87
|
+
type="button"
|
|
88
|
+
class="btn btn-primary edit-user-btn"
|
|
89
|
+
data-user-id="{{id}}"
|
|
90
|
+
>
|
|
91
|
+
Edit
|
|
92
|
+
</button>
|
|
93
|
+
<button
|
|
94
|
+
class="btn btn-danger delete-user-btn"
|
|
95
|
+
data-user-id="{{id}}"
|
|
96
|
+
>
|
|
97
|
+
Delete
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
38
100
|
|
|
101
|
+
<div class="edit-view">
|
|
102
|
+
<div>
|
|
103
|
+
Name:
|
|
104
|
+
<input
|
|
105
|
+
type="text"
|
|
106
|
+
class="form-control name-edit-input"
|
|
107
|
+
value="{{name}}"
|
|
108
|
+
/>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="email-edit">
|
|
111
|
+
Email:
|
|
112
|
+
<input
|
|
113
|
+
type="email"
|
|
114
|
+
class="form-control email-edit-input"
|
|
115
|
+
value="{{email}}"
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
<button
|
|
119
|
+
class="btn btn-primary submit-edit-btn"
|
|
120
|
+
data-user-id="{{id}}"
|
|
121
|
+
data-user-created="{{created}}"
|
|
122
|
+
>
|
|
123
|
+
Submit
|
|
124
|
+
</button>
|
|
125
|
+
<button
|
|
126
|
+
class="btn btn-secondary cancel-edit-btn"
|
|
127
|
+
data-user-id="{{id}}"
|
|
128
|
+
>
|
|
129
|
+
Cancel
|
|
130
|
+
</button>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
{{/each}}
|
|
134
|
+
</script>
|
|
135
|
+
</div>
|
|
39
136
|
</body>
|
|
137
|
+
|
|
40
138
|
<script src="scripts/http.js"></script>
|
|
41
139
|
<script src="scripts/users.js"></script>
|
|
42
140
|
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-generator-typescript",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.8",
|
|
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",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type TReqBody = string | object | undefined;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type TReqBody = string | object | undefined;
|