@azteam/express 1.2.119 → 1.2.122

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azteam/express",
3
- "version": "1.2.119",
3
+ "version": "1.2.122",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -1,194 +1,178 @@
1
- import { NOT_EXISTS, PERMISSION } from '@azteam/error';
1
+ import { NOT_EXISTS } from '@azteam/error';
2
2
 
3
- import { HTTP_METHOD, paginateMiddleware, REQUEST_TYPE, roleMiddleware, validateMiddleware, rulesID } from './ApiServer';
3
+ import { REQUEST_TYPE, USER_LEVEL } from './constant';
4
+ import { paginateMiddleware, roleMiddleware, validateMiddleware } from './middleware';
5
+ import { rulesID } from './validate';
4
6
  import Controller from './Controller';
5
7
 
6
- import { USER_LEVEL } from './constant';
7
-
8
8
 
9
9
  class AdminController extends Controller {
10
10
  constructor(pathName, repository, options = {}) {
11
- this.options = {
11
+ super(pathName, repository, {
12
12
  roles: {
13
13
  READ: 1,
14
14
  CREATE: 2,
15
15
  UPDATE: 3,
16
16
  DELETE: 4,
17
- RESTORE: 5,
17
+ RESTORE: 5
18
18
  }, // system roles
19
19
 
20
+ paginateOptions: {},
20
21
  rulesCreate: {},
21
22
  rulesModify: {},
22
23
 
23
24
  guardResponse: {},
24
25
  allowResponse: {},
25
26
 
26
- ...options,
27
- }
28
-
29
- super(pathName, repository);
30
- }
31
-
32
-
33
- usePublic(controllers = []){
34
- return super([
35
- getPaginate,
36
- getPaginateTrash,
37
- getOne,
38
- getOneTrash,
39
- postCreate,
40
- putModify,
41
- deleteOne,
42
- postRestore,
43
- ]);
27
+ ...options
28
+ });
44
29
  }
45
30
 
46
-
47
31
  getPaginate() {
48
32
  return {
49
- path: `/${this.pathName}`,
33
+ path: '/public',
50
34
  method: [
51
35
  roleMiddleware([this.options.roles.READ], USER_LEVEL.ADMIN),
52
- paginateMiddleware(paginateOptions),
53
- async function(req, res) {
36
+ paginateMiddleware(this.options.paginateOptions),
37
+ async (req, res) => {
54
38
  const paginateData = await this.repository.find(req.query, req.paginate);
55
39
 
56
40
  return res.success(paginateData, this.options.guardResponse, this.options.allowResponse);
57
- },
58
- ],
59
- }
60
- }
41
+ }
42
+ ]
43
+ };
44
+ };
61
45
 
62
46
  getPaginateTrash() {
63
47
  return {
64
- path: `/trash_${this.pathName}`,
48
+ path: '/trash',
65
49
  method: [
66
50
  roleMiddleware([this.options.roles.READ], USER_LEVEL.ADMIN),
67
- paginateMiddleware(paginateOptions),
68
- async function(req, res) {
51
+ paginateMiddleware(this.options.paginateOptions),
52
+ async (req, res) => {
69
53
  const paginateData = await this.repository.findTrash(req.query, req.paginate);
70
54
 
71
55
  return res.success(paginateData, this.options.guardResponse, this.options.allowResponse);
72
- },
73
- ],
74
- }
75
- }
56
+ }
57
+ ]
58
+ };
59
+ };
76
60
 
77
61
  getOne() {
78
62
  return {
79
- path: `/${this.pathName}/:id`,
63
+ path: '/public/:id',
80
64
  method: [
81
65
  roleMiddleware([this.options.roles.READ], USER_LEVEL.ADMIN),
82
66
  validateMiddleware(REQUEST_TYPE.PARAMS, rulesID),
83
- async function(req, res) {
67
+ async (req, res) => {
84
68
  const item = await this.repository.findOneById(req.params.id);
85
69
  if (!item) return res.error(NOT_EXISTS);
86
70
  return res.success(item, this.options.guardResponse, this.options.allowResponse);
87
- },
88
- ],
89
- }
71
+ }
72
+ ]
73
+ };
90
74
 
91
- }
75
+ };
92
76
 
93
77
  getOneTrash() {
94
78
  return {
95
- path: `/trash_${this.pathName}/:id`,
79
+ path: '/trash/:id',
96
80
  method: [
97
81
  roleMiddleware([this.options.roles.READ], USER_LEVEL.ADMIN),
98
82
  validateMiddleware(REQUEST_TYPE.PARAMS, rulesID),
99
- async function(req, res) {
83
+ async (req, res) => {
100
84
  const item = await this.repository.findOneTrashById(req.params.id);
101
85
  if (!item) return res.error(NOT_EXISTS);
102
86
  return res.success(item, this.options.guardResponse, this.options.allowResponse);
103
- },
104
- ],
105
- }
87
+ }
88
+ ]
89
+ };
106
90
 
107
- }
91
+ };
108
92
 
109
93
 
110
- beforePostCreate(data) {
94
+ async beforeCreate(data, user) {
111
95
  return data;
112
- }
96
+ };
113
97
 
114
98
  postCreate() {
115
99
  return {
116
- path: `/${this.pathName}`,
100
+ path: '/public',
117
101
  method: [
118
102
  roleMiddleware([this.options.roles.CREATE], USER_LEVEL.ADMIN),
119
103
  validateMiddleware(REQUEST_TYPE.BODY, this.options.rulesCreate),
120
- async function(req, res) {
104
+ async (req, res) => {
121
105
 
122
- const data = this.beforePostCreate(req.body);
106
+ const data = await this.beforeCreate(req.body, req.user);
123
107
 
124
108
  const item = await this.repository.createByUser(req.user.id, data);
125
109
 
126
110
  return res.success(item, this.options.guardResponse, this.options.allowResponse);
127
- },
128
- ],
129
- }
130
- }
111
+ }
112
+ ]
113
+ };
114
+ };
131
115
 
132
116
 
133
- beforePutModify(item) {
134
- return item;
135
- }
117
+ async beforeModify(data, user) {
118
+ return data;
119
+ };
136
120
 
137
121
  putModify() {
138
122
  return {
139
- path: `/${this.pathName}/:id`,
123
+ path: '/public/:id',
140
124
  method: [
141
125
  roleMiddleware([this.options.roles.UPDATE], USER_LEVEL.ADMIN),
142
126
  validateMiddleware(REQUEST_TYPE.PARAMS, rulesID),
143
127
  validateMiddleware(REQUEST_TYPE.BODY, this.options.rulesModify),
144
- async function(req, res) {
128
+ async (req, res) => {
145
129
 
146
130
  let item = await this.options.roles.findOneById(req.params.id);
147
131
  if (!item) return res.error(NOT_EXISTS);
148
132
 
149
- item = await this.beforePutModify(item);
133
+ const data = await this.beforeModify(req.body, req.user);
150
134
 
151
- item = await this.options.roles.modifyByUser(req.user.id, item, req.body);
135
+ item = await this.options.roles.modifyByUser(req.user.id, item, rdata);
152
136
 
153
137
  return res.success(item, this.options.guardResponse, this.options.allowResponse);
154
- },
155
- ],
156
- }
157
- }
138
+ }
139
+ ]
140
+ };
141
+ };
158
142
 
159
- deleteOne() {
143
+ delete() {
160
144
  return {
161
- path: `/${this.pathName}/:id`,
145
+ path: '/public/:id',
162
146
  method: [
163
147
  roleMiddleware([this.options.roles.DELETE], USER_LEVEL.ADMIN),
164
148
  validateMiddleware(REQUEST_TYPE.PARAMS, rulesID),
165
- async function(req, res) {
149
+ async (req, res) => {
166
150
  const item = await this.repository.findOneById(req.params.id);
167
151
  if (!item) return res.error(NOT_EXISTS);
168
152
 
169
153
  await this.repository.deleteByUser(req.user.id, item);
170
154
  return res.success(true);
171
- },
172
- ],
173
- }
174
- }
155
+ }
156
+ ]
157
+ };
158
+ };
175
159
 
176
160
  postRestore() {
177
161
  return {
178
- path: `/trash_${this.pathName}/:id`,
162
+ path: '/trash/:id',
179
163
  method: [
180
164
  roleMiddleware([this.options.roles.RESTORE], USER_LEVEL.ADMIN),
181
165
  validateMiddleware(REQUEST_TYPE.PARAMS, rulesID),
182
- async function(req, res) {
166
+ async (req, res) => {
183
167
  const item = await this.repository.findOneTrashById(req.params.id);
184
168
  if (!item) return res.error(NOT_EXISTS);
185
169
 
186
170
  await this.repository.restoreByUser(req.user.id, item);
187
171
  return res.success(true);
188
- },
189
- ],
190
- }
191
- },
172
+ }
173
+ ]
174
+ };
175
+ };
192
176
  }
193
177
 
194
178
  export default AdminController;
package/src/ApiServer.js CHANGED
@@ -9,8 +9,7 @@ import morgan from 'morgan';
9
9
  import cors from 'cors';
10
10
  import _ from 'lodash';
11
11
  import 'express-async-errors';
12
- import { decryptAES, encryptAES } from '@azteam/crypto';
13
- import { errorCatch, ErrorException, NOT_FOUND, UNKNOWN } from '@azteam/error';
12
+ import {errorCatch, ErrorException, NOT_FOUND, UNKNOWN} from '@azteam/error';
14
13
 
15
14
  function omitItem(item, guard) {
16
15
  if (item.toJSON) {
@@ -33,7 +32,7 @@ class ApiServer {
33
32
  httpOnly: true,
34
33
  signed: true,
35
34
  sameSite: 'Lax'
36
- }
35
+ };
37
36
 
38
37
  this.middlewares = [];
39
38
  this.controllers = [];
@@ -114,8 +113,8 @@ class ApiServer {
114
113
  }));
115
114
 
116
115
  app.use(methodOverride());
117
- app.use(bodyParser.urlencoded({ limit: '5mb', extended: true }));
118
- app.use(bodyParser.json({ limit: '5mb' }));
116
+ app.use(bodyParser.urlencoded({limit: '5mb', extended: true}));
117
+ app.use(bodyParser.json({limit: '5mb'}));
119
118
 
120
119
  app.set('trust proxy', 1);
121
120
 
@@ -128,11 +127,11 @@ class ApiServer {
128
127
  if (
129
128
  !origin || !WHITE_LIST.length ||
130
129
  WHITE_LIST.some(re => origin.endsWith(re))) {
131
- callback(null, true)
130
+ callback(null, true);
132
131
  } else {
133
132
  callback(new Error(`${origin} Not allowed by CORS`));
134
133
  }
135
- },
134
+ }
136
135
  }));
137
136
 
138
137
  if (this.debug) {
@@ -150,13 +149,13 @@ class ApiServer {
150
149
  ip: req.ip,
151
150
  device: req.get('X-DEVICE') || req.get('User-Agent'),
152
151
  device_id: req.get('X-DEVICE-ID') || 'web',
153
- os: req.get('X-OS') || 'web',
154
- }
152
+ os: req.get('X-OS') || 'web'
153
+ };
155
154
 
156
155
 
157
156
  res.error = function(code, errors = []) {
158
157
  throw new ErrorException(code, errors);
159
- }
158
+ };
160
159
 
161
160
  res.success = function(data = {}, guard = [], allows = []) {
162
161
  if (data) {
@@ -176,7 +175,7 @@ class ApiServer {
176
175
  'metadata_disable',
177
176
  'metadata_keywords',
178
177
  'metadata_description',
179
- 'metadata_image_url',
178
+ 'metadata_image_url'
180
179
  ];
181
180
  }
182
181
 
@@ -200,7 +199,7 @@ class ApiServer {
200
199
  return res.json({
201
200
  success: true,
202
201
  data,
203
- options: req.resOptions,
202
+ options: req.resOptions
204
203
  });
205
204
  };
206
205
 
@@ -210,7 +209,7 @@ class ApiServer {
210
209
  domain: COOKIE_OPTIONS.domain
211
210
  });
212
211
  });
213
- }
212
+ };
214
213
 
215
214
  res.addCookie = function(data) {
216
215
  _.map(data, (value, key) => {
@@ -221,7 +220,7 @@ class ApiServer {
221
220
  expires: new Date(Date.now() + maxAge)
222
221
  });
223
222
  });
224
- }
223
+ };
225
224
  next();
226
225
  });
227
226
 
@@ -231,19 +230,32 @@ class ApiServer {
231
230
 
232
231
  const msg = [];
233
232
  _.map(this.controllers, (obj) => {
234
- const controller = obj.controller;
235
- _.map(controller, (item, key) => {
236
- item.path = obj.version.startsWith('v') ? `/${obj.version}${item.path}` : item.path;
237
-
238
- msg.push({
239
- controller: obj.name,
240
- version: obj.version,
241
- type: item.type,
242
- method: key,
243
- path: item.path,
244
- });
245
233
 
246
- app[item.type.toLowerCase()](item.path, ...item.method);
234
+ const {name, controller, version} = obj;
235
+
236
+ const listPublicMethod = obj.controller.publicMethod();
237
+
238
+ _.map(listPublicMethod, (methodName) => {
239
+
240
+ const matches = methodName.match(/get|post|put|patch|delete/);
241
+ if (matches) {
242
+ const type = matches[0];
243
+ const item = controller[methodName]();
244
+
245
+ item.path = controller.pathName ? `/${controller.pathName}${item.path}` : item.path;
246
+
247
+ item.path = version.startsWith('v') ? `/${version}${item.path}` : item.path;
248
+
249
+ msg.push({
250
+ controller: name,
251
+ version,
252
+ type,
253
+ method: methodName,
254
+ path: item.path
255
+ });
256
+
257
+ app[type](item.path, ...item.method);
258
+ }
247
259
  });
248
260
  });
249
261
 
@@ -268,7 +280,7 @@ class ApiServer {
268
280
  this.callbackError(error);
269
281
  }
270
282
 
271
- return res.status(error.status).json({ success: false, errors: error.errors });
283
+ return res.status(error.status).json({success: false, errors: error.errors});
272
284
  });
273
285
 
274
286
  const server = http.Server(app);
@@ -324,4 +336,4 @@ class ApiServer {
324
336
  }
325
337
  }
326
338
 
327
- export default ApiServer;
339
+ export default ApiServer;
package/src/Controller.js CHANGED
@@ -1,21 +1,30 @@
1
- import { NOT_EXISTS, PERMISSION } from '@azteam/error';
2
-
3
- import { HTTP_METHOD, paginateMiddleware, REQUEST_TYPE, roleMiddleware, validateMiddleware, rulesID } from './ApiServer';
4
- import { USER_LEVEL } from './constant';
5
-
6
-
7
1
  class Controller {
8
- constructor(pathName, repository) {
2
+ constructor(pathName = '', repository = null, options = {}) {
9
3
  this.pathName = pathName;
10
4
  this.repository = repository;
5
+
6
+ this.options = {
7
+ ...options
8
+ };
11
9
  }
12
10
 
11
+ publicMethod() {
12
+ let child = this;
13
+ let result = [];
14
+
15
+ while (Object.getPrototypeOf(child.__proto__)) {
16
+
17
+ const data = Object.getOwnPropertyNames(Object.getPrototypeOf(child));
18
+
19
+ result = [
20
+ ...result,
21
+ ...data.filter((methodName) => methodName.match(/^get|post|put|patch|delete/))
22
+ ]
13
23
 
14
- usePublic(controllers = []) {
15
- return [
16
- ...controllers
17
- ]
24
+ child = child.__proto__;
25
+ }
26
+ return result;
18
27
  }
19
28
  }
20
29
 
21
- export default Controller;
30
+ export default Controller;
package/src/constant.js CHANGED
@@ -1,11 +1,3 @@
1
- export const HTTP_METHOD = {
2
- HEAD: 'HEAD',
3
- GET: 'GET',
4
- POST: 'POST',
5
- PUT: 'PUT',
6
- DEL: 'DELETE',
7
- };
8
-
9
1
  export const REQUEST_TYPE = {
10
2
  PARAMS: 'params',
11
3
  BODY: 'body',
@@ -1,6 +1,5 @@
1
1
  import etag from 'etag';
2
2
 
3
- import { HTTP_GET } from '../constant';
4
3
 
5
4
 
6
5
  function floorToMinute(time, minutes) {
@@ -11,7 +10,7 @@ function floorToMinute(time, minutes) {
11
10
 
12
11
  export default function(mTimeout = 5) {
13
12
  return async function(req, res, next) {
14
- if (req.method === HTTP_GET) {
13
+ if (req.method === 'GET') {
15
14
  const etag_hash = etag(req.url + floorToMinute(Math.floor(Date.now() / 1000), mTimeout));
16
15
  if (req.headers['if-none-match'] === etag_hash) {
17
16
  return res.status(304).send();