evaengine 0.11.2 → 1.0.1

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.
Files changed (141) hide show
  1. package/.ai/analysis.md +657 -0
  2. package/.ai/architecture/runtime.md +504 -0
  3. package/.ai/contracts/public-api.md +447 -0
  4. package/.ai/external-project-guide.md +248 -0
  5. package/.ai/vision.md +314 -0
  6. package/README.md +51 -62
  7. package/bin/engine +15 -21
  8. package/index.js +2 -18
  9. package/package.json +60 -64
  10. package/src/commands/index.js +12 -0
  11. package/{lib → src}/commands/interface.js +5 -11
  12. package/src/commands/make_entity.js +490 -0
  13. package/src/commands/tramp.js +34 -0
  14. package/{lib → src}/config/index.js +7 -9
  15. package/{lib → src}/di.js +11 -26
  16. package/src/engine.js +551 -0
  17. package/{lib → src}/entities/index.js +72 -82
  18. package/{lib → src}/exceptions/index.js +71 -92
  19. package/src/index.js +57 -0
  20. package/src/middlewares/auth.js +67 -0
  21. package/src/middlewares/auth_kong.js +28 -0
  22. package/src/middlewares/debug.js +88 -0
  23. package/src/middlewares/index.js +18 -0
  24. package/src/middlewares/providers.js +73 -0
  25. package/src/middlewares/session.js +58 -0
  26. package/{lib → src}/middlewares/trace.js +74 -86
  27. package/src/middlewares/validator.js +50 -0
  28. package/src/middlewares/view_cache.js +127 -0
  29. package/{lib → src}/services/cache.js +45 -56
  30. package/src/services/config.js +111 -0
  31. package/src/services/env.js +28 -0
  32. package/src/services/event_manager.js +84 -0
  33. package/src/services/http_client.js +160 -0
  34. package/src/services/index.js +27 -0
  35. package/src/services/interface.js +5 -0
  36. package/src/services/joi.js +13 -0
  37. package/src/services/jwt_token.js +89 -0
  38. package/src/services/jwt_token_kong.js +75 -0
  39. package/src/services/logger.js +148 -0
  40. package/src/services/namespace.js +176 -0
  41. package/src/services/now.js +49 -0
  42. package/src/services/providers.js +158 -0
  43. package/src/services/redis.js +55 -0
  44. package/src/services/rest_client.js +112 -0
  45. package/src/swagger/index.js +668 -0
  46. package/{lib → src}/utils/api_scaffold.js +26 -39
  47. package/src/utils/case_converter.js +33 -0
  48. package/src/utils/crc32.js +44 -0
  49. package/src/utils/datetime.js +13 -0
  50. package/src/utils/host.js +39 -0
  51. package/src/utils/index.js +35 -0
  52. package/{lib → src}/utils/pagination.js +22 -31
  53. package/src/utils/random.js +23 -0
  54. package/{lib → src}/utils/smart_query.js +27 -27
  55. package/src/utils/test.js +48 -0
  56. package/src/utils/wrapper.js +8 -0
  57. package/bin/engine-babel +0 -38
  58. package/lib/commands/index.js +0 -25
  59. package/lib/commands/index.js.map +0 -1
  60. package/lib/commands/interface.js.map +0 -1
  61. package/lib/commands/make_entity.js +0 -549
  62. package/lib/commands/make_entity.js.map +0 -1
  63. package/lib/commands/tramp.js +0 -53
  64. package/lib/commands/tramp.js.map +0 -1
  65. package/lib/config/index.js.map +0 -1
  66. package/lib/di.js.map +0 -1
  67. package/lib/engine.js +0 -558
  68. package/lib/engine.js.map +0 -1
  69. package/lib/entities/index.js.map +0 -1
  70. package/lib/exceptions/index.js.map +0 -1
  71. package/lib/index.js +0 -105
  72. package/lib/index.js.map +0 -1
  73. package/lib/middlewares/auth.js +0 -97
  74. package/lib/middlewares/auth.js.map +0 -1
  75. package/lib/middlewares/auth_kong.js +0 -48
  76. package/lib/middlewares/auth_kong.js.map +0 -1
  77. package/lib/middlewares/debug.js +0 -68
  78. package/lib/middlewares/debug.js.map +0 -1
  79. package/lib/middlewares/index.js +0 -45
  80. package/lib/middlewares/index.js.map +0 -1
  81. package/lib/middlewares/providers.js +0 -102
  82. package/lib/middlewares/providers.js.map +0 -1
  83. package/lib/middlewares/session.js +0 -76
  84. package/lib/middlewares/session.js.map +0 -1
  85. package/lib/middlewares/trace.js.map +0 -1
  86. package/lib/middlewares/validator.js +0 -71
  87. package/lib/middlewares/validator.js.map +0 -1
  88. package/lib/middlewares/view_cache.js +0 -160
  89. package/lib/middlewares/view_cache.js.map +0 -1
  90. package/lib/services/cache.js.map +0 -1
  91. package/lib/services/config.js +0 -140
  92. package/lib/services/config.js.map +0 -1
  93. package/lib/services/env.js +0 -40
  94. package/lib/services/env.js.map +0 -1
  95. package/lib/services/event_manager.js +0 -110
  96. package/lib/services/event_manager.js.map +0 -1
  97. package/lib/services/http_client.js +0 -178
  98. package/lib/services/http_client.js.map +0 -1
  99. package/lib/services/index.js +0 -70
  100. package/lib/services/index.js.map +0 -1
  101. package/lib/services/interface.js +0 -12
  102. package/lib/services/interface.js.map +0 -1
  103. package/lib/services/joi.js +0 -28
  104. package/lib/services/joi.js.map +0 -1
  105. package/lib/services/jwt_token.js +0 -120
  106. package/lib/services/jwt_token.js.map +0 -1
  107. package/lib/services/jwt_token_kong.js +0 -111
  108. package/lib/services/jwt_token_kong.js.map +0 -1
  109. package/lib/services/logger.js +0 -172
  110. package/lib/services/logger.js.map +0 -1
  111. package/lib/services/namespace.js +0 -188
  112. package/lib/services/namespace.js.map +0 -1
  113. package/lib/services/now.js +0 -69
  114. package/lib/services/now.js.map +0 -1
  115. package/lib/services/providers.js +0 -195
  116. package/lib/services/providers.js.map +0 -1
  117. package/lib/services/redis.js +0 -77
  118. package/lib/services/redis.js.map +0 -1
  119. package/lib/services/rest_client.js +0 -136
  120. package/lib/services/rest_client.js.map +0 -1
  121. package/lib/swagger/index.js +0 -684
  122. package/lib/swagger/index.js.map +0 -1
  123. package/lib/utils/api_scaffold.js.map +0 -1
  124. package/lib/utils/case_converter.js +0 -48
  125. package/lib/utils/case_converter.js.map +0 -1
  126. package/lib/utils/crc32.js +0 -22
  127. package/lib/utils/crc32.js.map +0 -1
  128. package/lib/utils/datetime.js +0 -21
  129. package/lib/utils/datetime.js.map +0 -1
  130. package/lib/utils/host.js +0 -48
  131. package/lib/utils/host.js.map +0 -1
  132. package/lib/utils/index.js +0 -61
  133. package/lib/utils/index.js.map +0 -1
  134. package/lib/utils/pagination.js.map +0 -1
  135. package/lib/utils/random.js +0 -33
  136. package/lib/utils/random.js.map +0 -1
  137. package/lib/utils/smart_query.js.map +0 -1
  138. package/lib/utils/test.js +0 -62
  139. package/lib/utils/test.js.map +0 -1
  140. package/lib/utils/wrapper.js +0 -9
  141. package/lib/utils/wrapper.js.map +0 -1
@@ -0,0 +1,28 @@
1
+ import { UnauthorizedException } from '../exceptions/index.js';
2
+ import wrapper from '../utils/wrapper.js';
3
+
4
+ /**
5
+ * @returns {function()}
6
+ * @constructor
7
+ */
8
+ function AuthKongMiddleware() {
9
+ return () => wrapper(async (req, res, next) => {
10
+ if (req.headers['x-anonymous-consumer'] === 'true') {
11
+ throw new UnauthorizedException('Authentication failed');
12
+ }
13
+ const uid = Number.parseInt(req.headers['x-consumer-custom-id'], 10);
14
+ const mobile = req.headers['x-consumer-custom-username'];
15
+ if (uid > 0) {
16
+ res.set('X-Uid', uid);
17
+ res.set('X-Mobile', mobile);
18
+ req.auth = {
19
+ uid,
20
+ mobile
21
+ };
22
+ return next();
23
+ }
24
+ throw new UnauthorizedException('Authentication failed, invalid UID');
25
+ });
26
+ }
27
+
28
+ export default AuthKongMiddleware;
@@ -0,0 +1,88 @@
1
+ import morgan from 'morgan';
2
+ import os from 'os';
3
+ import constitute from 'constitute';
4
+ import Logger from '../services/logger.js';
5
+
6
+ /**
7
+ Log format:
8
+ NCSA Combined Log Format + extended fields
9
+
10
+ Nginx config as below
11
+
12
+ log_format upstream '$http_x_forwarded_for - $remote_user [$time_local] '
13
+ '"$request" $status $body_bytes_sent '
14
+ '"$http_referer" "$http_user_agent" '
15
+ '"$remote_addr" $host $request_time $upstream_response_time $scheme $server_port '
16
+ '$hostname $upstream_addr $http_x_device_id $sent_http_x_uid $sent_http_x_token '
17
+ '$sent_http_x_service_name $sent_http_x_b3_spanid $sent_http_x_b3_traceid '
18
+ '$sent_http_x_b3_parentspanid $sent_http_x_b3_sampled';
19
+ */
20
+
21
+ morgan.token(
22
+ 'host',
23
+ req =>
24
+ req.headers.host
25
+ );
26
+
27
+ morgan.token(
28
+ 'real-ip',
29
+ req =>
30
+ req.headers['x-real-ip'] ||
31
+ req.headers['x-forwarded-for'] ||
32
+ req.ip ||
33
+ (req.connection && req.connection.remoteAddress)
34
+ );
35
+
36
+ morgan.token(
37
+ 'port',
38
+ req =>
39
+ (req.headers.host && req.headers.host.split(':')[1]) || -1
40
+ );
41
+
42
+ const hostname = os.hostname();
43
+ morgan.token('hostname', () => hostname);
44
+
45
+ morgan.token(
46
+ 'tokens',
47
+ (req, res) =>
48
+ [
49
+ res.getHeader('X-Uid') || '-',
50
+ res.getHeader('X-Token') || '-'
51
+ ].join(' ')
52
+ );
53
+
54
+ morgan.token(
55
+ 'tracer',
56
+ (req, res) =>
57
+ [
58
+ res.getHeader('X-Service-Name') || '-',
59
+ res.getHeader('X-B3-SpanId') || '-',
60
+ res.getHeader('X-B3-TraceId') || '-',
61
+ res.getHeader('X-B3-ParentSpanId') || '-',
62
+ res.getHeader('X-B3-Sampled') || '-'
63
+ ].join(' ')
64
+ );
65
+
66
+
67
+ /**
68
+ * @param logger {Logger}
69
+ * @returns {function()}
70
+ * @constructor
71
+ */
72
+ function DebugMiddleware(logger) {
73
+ return () =>
74
+ morgan(
75
+ ':real-ip - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent" ' +
76
+ '":remote-addr" :host :response-time - :http-version :port :hostname - :tokens :tracer %s',
77
+ {
78
+ stream: {
79
+ write: (message) => {
80
+ logger.info(message);
81
+ }
82
+ }
83
+ }
84
+ );
85
+ }
86
+
87
+ constitute.Dependencies(Logger)(DebugMiddleware);
88
+ export default DebugMiddleware;
@@ -0,0 +1,18 @@
1
+ import AuthMiddleware from './auth.js';
2
+ import AuthKongMiddleware from './auth_kong.js';
3
+ import DebugMiddleware from './debug.js';
4
+ import SessionMiddleware from './session.js';
5
+ import TraceMiddleware from './trace.js';
6
+ import ViewCacheMiddleware from './view_cache.js';
7
+ import ValidatorMiddleware from './validator.js';
8
+
9
+ export {
10
+ AuthMiddleware,
11
+ AuthKongMiddleware,
12
+ DebugMiddleware,
13
+ SessionMiddleware,
14
+ TraceMiddleware,
15
+ ViewCacheMiddleware,
16
+ ValidatorMiddleware
17
+ };
18
+
@@ -0,0 +1,73 @@
1
+ import SessionMiddleware from '../middlewares/session.js';
2
+ import AuthMiddleware from '../middlewares/auth.js';
3
+ import AuthKongMiddleware from '../middlewares/auth_kong.js';
4
+ import DebugMiddleware from '../middlewares/debug.js';
5
+ import TraceMiddleware from '../middlewares/trace.js';
6
+ import ViewCacheMiddleware from '../middlewares/view_cache.js';
7
+ import ValidatorMiddleware from '../middlewares/validator.js';
8
+ import DI from '../di.js';
9
+ import { ServiceProvider } from '../services/providers.js';
10
+
11
+ export class SessionMiddlewareProvider extends ServiceProvider {
12
+ get name() {
13
+ return 'session';
14
+ }
15
+
16
+ register() {
17
+ DI.bindMethod(this.name, SessionMiddleware);
18
+ }
19
+ }
20
+
21
+ export class AuthMiddlewareProvider extends ServiceProvider {
22
+ get name() {
23
+ return 'auth';
24
+ }
25
+
26
+ register() {
27
+ if (DI.get('config').get('token.provider') === 'kong') {
28
+ DI.bindMethod(this.name, AuthKongMiddleware);
29
+ } else {
30
+ DI.bindMethod(this.name, AuthMiddleware);
31
+ }
32
+ }
33
+ }
34
+
35
+ export class DebugMiddlewareProvider extends ServiceProvider {
36
+ get name() {
37
+ return 'debug';
38
+ }
39
+
40
+ register() {
41
+ DI.bindMethod(this.name, DebugMiddleware);
42
+ }
43
+ }
44
+
45
+ export class ViewCacheMiddlewareProvider extends ServiceProvider {
46
+ get name() {
47
+ return 'view_cache';
48
+ }
49
+
50
+ register() {
51
+ DI.bindMethod(this.name, ViewCacheMiddleware);
52
+ }
53
+ }
54
+
55
+ export class TraceMiddlewareProvider extends ServiceProvider {
56
+ get name() {
57
+ return 'trace';
58
+ }
59
+
60
+ register() {
61
+ DI.bindMethod(this.name, TraceMiddleware);
62
+ }
63
+ }
64
+
65
+ export class ValidatorMiddlewareProvider extends ServiceProvider {
66
+ get name() {
67
+ return 'validator';
68
+ }
69
+
70
+ register() {
71
+ DI.bindMethod(this.name, ValidatorMiddleware);
72
+ }
73
+ }
@@ -0,0 +1,58 @@
1
+ import session from 'express-session';
2
+ import { RedisStore } from 'connect-redis';
3
+ import constitute from 'constitute';
4
+ import Config from '../services/config.js';
5
+ import Redis from '../services/redis.js';
6
+ import Namespace from '../services/namespace.js';
7
+
8
+ let middleware = null;
9
+
10
+ //Fix issue https://github.com/othiym23/node-continuation-local-storage/issues/29
11
+ const clsifyMiddleware = (fn, ns) =>
12
+ (req, res, next) =>
13
+ fn.call(this, req, res, ns.bind(next));
14
+
15
+ /**
16
+ * @param _config {Config}
17
+ * @param redis {Redis}
18
+ * @param namespace {Namespace}
19
+ * @returns {function()}
20
+ * @constructor
21
+ */
22
+ function SessionMiddleware(_config, redis, namespace) {
23
+ return () => {
24
+ if (middleware) {
25
+ return middleware;
26
+ }
27
+ const Store = RedisStore;
28
+ let store = null;
29
+ const config = _config.get().session;
30
+
31
+ if (config.store) {
32
+ const RedisClient = new Store(Object.assign({}, config.store, {
33
+ client: config.store.client || redis.getInstance()
34
+ }));
35
+ RedisClient.client.on('error', (err) => {
36
+ throw err;
37
+ });
38
+ store = RedisClient;
39
+ } else {
40
+ store = new Store(Object.assign({}, { client: redis.getInstance() }));
41
+ }
42
+
43
+ middleware = session({
44
+ store,
45
+ cookie: Object.assign({}, _config.get().cookie),
46
+ secret: config.secret,
47
+ resave: config.resave,
48
+ saveUninitialized: config.saveUninitialized
49
+ });
50
+
51
+ return namespace.isEnabled() ?
52
+ clsifyMiddleware(middleware, namespace.use().getContext()) :
53
+ middleware;
54
+ };
55
+ }
56
+ constitute.Dependencies(Config, Redis, Namespace)(SessionMiddleware);
57
+
58
+ export default SessionMiddleware;
@@ -1,39 +1,14 @@
1
- 'use strict';
1
+ import onHeaders from 'on-headers';
2
+ import constitute from 'constitute';
3
+ import { randomString, getHostFullUrl, getHostPort, getHostIp, getMicroTimestamp } from '../utils/index.js';
4
+ import Namespace from '../services/namespace.js';
5
+ import Config from '../services/config.js';
6
+ import Logger from '../services/logger.js';
7
+ import HttpClient from '../services/http_client.js';
2
8
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.tracerToZipkins = undefined;
9
+ const hostIp = getHostIp();
7
10
 
8
- var _onHeaders = require('on-headers');
9
-
10
- var _onHeaders2 = _interopRequireDefault(_onHeaders);
11
-
12
- var _constitute = require('constitute');
13
-
14
- var _utils = require('../utils');
15
-
16
- var _namespace = require('../services/namespace');
17
-
18
- var _namespace2 = _interopRequireDefault(_namespace);
19
-
20
- var _config = require('../services/config');
21
-
22
- var _config2 = _interopRequireDefault(_config);
23
-
24
- var _logger = require('../services/logger');
25
-
26
- var _logger2 = _interopRequireDefault(_logger);
27
-
28
- var _http_client = require('../services/http_client');
29
-
30
- var _http_client2 = _interopRequireDefault(_http_client);
31
-
32
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
-
34
- const hostIp = (0, _utils.getHostIp)();
35
-
36
- const tracerToZipkins = exports.tracerToZipkins = tracer => {
11
+ export const tracerToZipkins = (tracer) => {
37
12
  if (!tracer) {
38
13
  return false;
39
14
  }
@@ -63,34 +38,44 @@ const tracerToZipkins = exports.tracerToZipkins = tracer => {
63
38
  name,
64
39
  timestamp,
65
40
  duration,
66
- annotations: [{
67
- endpoint,
68
- timestamp,
69
- value: 'sr'
70
- }, {
71
- endpoint,
72
- timestamp: timestamp + duration,
73
- value: 'ss'
74
- }],
75
- binaryAnnotations: [{
76
- key: 'traceId',
77
- value: traceId
78
- }, {
79
- key: 'spanId',
80
- value: id
81
- }, {
82
- key: 'method',
83
- value: method
84
- }, {
85
- key: 'url',
86
- value: url
87
- }, {
88
- key: 'port',
89
- value: port.toString()
90
- }, {
91
- key: 'statusCode',
92
- value: statusCode.toString()
93
- }]
41
+ annotations: [
42
+ {
43
+ endpoint,
44
+ timestamp,
45
+ value: 'sr'
46
+ },
47
+ {
48
+ endpoint,
49
+ timestamp: timestamp + duration,
50
+ value: 'ss'
51
+ }
52
+ ],
53
+ binaryAnnotations: [
54
+ {
55
+ key: 'traceId',
56
+ value: traceId
57
+ },
58
+ {
59
+ key: 'spanId',
60
+ value: id
61
+ },
62
+ {
63
+ key: 'method',
64
+ value: method
65
+ },
66
+ {
67
+ key: 'url',
68
+ value: url
69
+ },
70
+ {
71
+ key: 'port',
72
+ value: port.toString()
73
+ },
74
+ {
75
+ key: 'statusCode',
76
+ value: statusCode.toString()
77
+ }
78
+ ]
94
79
  };
95
80
 
96
81
  if (parentId) {
@@ -99,24 +84,27 @@ const tracerToZipkins = exports.tracerToZipkins = tracer => {
99
84
 
100
85
  const zipkins = [zipkin];
101
86
  if (queries && queries.length > 0) {
102
- queries.forEach(element => {
87
+ queries.forEach((element) => {
103
88
  const { query, cost, finishedAt } = element;
104
89
  zipkins.push({
105
- id: (0, _utils.randomString)(),
90
+ id: randomString(),
106
91
  parentId: id,
107
92
  traceId,
108
93
  name: 'sequelize',
109
94
  timestamp: finishedAt - cost,
110
95
  duration: cost,
111
- annotations: [{
112
- endpoint,
113
- timestamp: finishedAt - cost,
114
- value: 'cs'
115
- }, {
116
- endpoint,
117
- timestamp: finishedAt,
118
- value: 'cr'
119
- }],
96
+ annotations: [
97
+ {
98
+ endpoint,
99
+ timestamp: finishedAt - cost,
100
+ value: 'cs'
101
+ },
102
+ {
103
+ endpoint,
104
+ timestamp: finishedAt,
105
+ value: 'cr'
106
+ }
107
+ ],
120
108
  binaryAnnotations: [{
121
109
  key: 'query',
122
110
  value: query
@@ -127,14 +115,15 @@ const tracerToZipkins = exports.tracerToZipkins = tracer => {
127
115
  return zipkins;
128
116
  };
129
117
 
118
+
130
119
  function TraceMiddleware(ns, config, logger, client) {
131
120
  const enabled = config.get('trace.enable');
132
121
  return name => (req, res, next) => {
133
- const spanId = (0, _utils.randomString)();
122
+ const spanId = randomString();
134
123
  const traceId = req.get('X-B3-TraceId') || spanId;
135
124
  const parentId = req.get('X-B3-SpanId') || '';
136
125
  const startedAt = process.hrtime();
137
- const timestamp = (0, _utils.getMicroTimestamp)();
126
+ const timestamp = getMicroTimestamp();
138
127
  const serviceName = name || config.get('app.name');
139
128
  //目前默认全部采样
140
129
  let sampled = enabled ? 1 : 0;
@@ -145,8 +134,8 @@ function TraceMiddleware(ns, config, logger, client) {
145
134
  const tracer = {
146
135
  serviceName,
147
136
  method: req.method,
148
- url: (0, _utils.getHostFullUrl)(req),
149
- port: (0, _utils.getHostPort)(req),
137
+ url: getHostFullUrl(req),
138
+ port: getHostPort(req),
150
139
  spanId,
151
140
  traceId,
152
141
  parentId,
@@ -164,22 +153,22 @@ function TraceMiddleware(ns, config, logger, client) {
164
153
  'X-B3-SpanId': spanId,
165
154
  'X-B3-TraceId': traceId,
166
155
  'X-B3-ParentSpanId': parentId,
167
- 'X-B3-Sampled': enabled ? 1 : 0
156
+ 'X-B3-Sampled': sampled
168
157
  });
169
158
 
170
159
  if (sampled < 1) {
171
- (0, _onHeaders2.default)(res, () => {
160
+ onHeaders(res, () => {
172
161
  const [seconds, nanoseconds] = process.hrtime(startedAt);
173
- const duration = seconds * 1e3 + nanoseconds * 1e-6;
162
+ const duration = ((seconds * 1e3) + (nanoseconds * 1e-6));
174
163
  res.set('X-Response-Milliseconds', parseInt(duration, 10));
175
164
  });
176
165
  next();
177
166
  return;
178
167
  }
179
168
 
180
- (0, _onHeaders2.default)(res, () => {
169
+ onHeaders(res, () => {
181
170
  const [seconds, nanoseconds] = process.hrtime(startedAt);
182
- const duration = (seconds * 1e3 + nanoseconds * 1e-6) * 1000;
171
+ const duration = ((seconds * 1e3) + (nanoseconds * 1e-6)) * 1000;
183
172
  tracer.duration = parseInt(duration, 10);
184
173
  tracer.statusCode = res.statusCode;
185
174
  res.set('X-Response-Milliseconds', tracer.duration / 1000);
@@ -217,7 +206,7 @@ function TraceMiddleware(ns, config, logger, client) {
217
206
  url: api,
218
207
  method: 'POST',
219
208
  json: zipkins
220
- }).catch(e => {
209
+ }).catch((e) => {
221
210
  logger.error('Error happened on sending tracing data', e);
222
211
  });
223
212
  };
@@ -235,7 +224,6 @@ function TraceMiddleware(ns, config, logger, client) {
235
224
  };
236
225
  }
237
226
 
238
- (0, _constitute.Dependencies)(_namespace2.default, _config2.default, _logger2.default, _http_client2.default)(TraceMiddleware); //eslint-disable-line new-cap
227
+ constitute.Dependencies(Namespace, Config, Logger, HttpClient)(TraceMiddleware);
239
228
 
240
- exports.default = TraceMiddleware;
241
- //# sourceMappingURL=trace.js.map
229
+ export default TraceMiddleware;
@@ -0,0 +1,50 @@
1
+ import Joi from 'joi';
2
+ import constitute from 'constitute';
3
+ import wrapper from '../utils/wrapper.js';
4
+ import { FormInvalidateException } from '../exceptions/index.js';
5
+ import ValidatorBase from '../services/joi.js';
6
+
7
+ const validate = (data, schema, options) => {
8
+ const validationOptions = Object.assign(
9
+ { abortEarly: false, allowUnknown: true },
10
+ options
11
+ );
12
+ if (schema && typeof schema.validateAsync === 'function') {
13
+ return schema.validateAsync(data, validationOptions);
14
+ }
15
+ return new Promise((resolve, reject) => {
16
+ Joi.validate(data, schema, validationOptions, (err, value) => {
17
+ if (err) reject(err);
18
+ else resolve(value);
19
+ });
20
+ });
21
+ };
22
+
23
+ /**
24
+ * @returns {function()}
25
+ * @constructor
26
+ */
27
+ function ValidatorMiddleware(validatorBase) {
28
+ return (getSchema, options, validator) =>
29
+ wrapper(async (req, res, next) => {
30
+ const { query, body, path } = getSchema(validator || validatorBase.getJoi());
31
+ try {
32
+ if (query) {
33
+ await validate(req.query, query, options);
34
+ }
35
+ if (body) {
36
+ await validate(req.body, body, options);
37
+ }
38
+ if (path) {
39
+ await validate(req.params, path, options);
40
+ }
41
+ return next();
42
+ } catch (e) {
43
+ throw new FormInvalidateException(e);
44
+ }
45
+ });
46
+ }
47
+
48
+ constitute.Dependencies(ValidatorBase)(ValidatorMiddleware);
49
+
50
+ export default ValidatorMiddleware;
@@ -0,0 +1,127 @@
1
+ import constitute from 'constitute';
2
+ import crypto from 'crypto';
3
+ import util from 'util';
4
+ import moment from 'moment-timezone';
5
+ import Logger from '../services/logger.js';
6
+ import Cache from '../services/cache.js';
7
+ import wrapper from '../utils/wrapper.js';
8
+ import { RuntimeException } from '../exceptions/index.js';
9
+
10
+ export const defaultHashStrategy = obj => obj;
11
+
12
+ export const defaultHeadersFilter = (res) => {
13
+ const headers = [];
14
+ ['Content-Type'].forEach((key) => {
15
+ const value = res.get(key);
16
+ if (value) {
17
+ headers.push([key, value]);
18
+ }
19
+ });
20
+ return headers;
21
+ };
22
+
23
+ export const requestToCacheKey = (req, hashStrategy) => {
24
+ const {
25
+ method,
26
+ originalUrl,
27
+ query: originQuery,
28
+ route,
29
+ uid = null //Custom rule
30
+ } = req;
31
+ const query = { ...originQuery };
32
+ delete query.flush;
33
+ if (hashStrategy && typeof hashStrategy !== 'function') {
34
+ throw new RuntimeException(`View cache hash strategy must be a function for ${originalUrl}`);
35
+ }
36
+ if (!route) {
37
+ throw new RuntimeException(`View cache middleware require route for ${originalUrl}`);
38
+ }
39
+ if (method.toLowerCase() !== 'get') {
40
+ throw new RuntimeException(`View cache middleware only support GET method of http request for ${originalUrl}`);
41
+ }
42
+ const { host = 'unknown' } = req.headers;
43
+ const [urlPath = ''] = originalUrl.split('?');
44
+ const key = [method, `/${host}`, urlPath].join('').replace(/:/g, '_').toLowerCase();
45
+ const strategy = hashStrategy || defaultHashStrategy;
46
+ const hash = crypto
47
+ .createHash('md5')
48
+ .update(JSON
49
+ .stringify(strategy({
50
+ method,
51
+ urlPath,
52
+ query,
53
+ uid
54
+ })))
55
+ .digest('hex');
56
+ return [key, hash].join(':');
57
+ };
58
+
59
+
60
+ /**
61
+ * @param {Cache} cache
62
+ * @param {Logger} logger
63
+ * @returns {function(*=)}
64
+ * @constructor
65
+ */
66
+ function ViewCacheMiddleware(cache, logger) {
67
+ return (options = {}) => {
68
+ if (!util.isObject(options)) {
69
+ options = {
70
+ ttl: options
71
+ };
72
+ }
73
+ const {
74
+ ttl,
75
+ headersFilter,
76
+ namespace,
77
+ hashStrategy
78
+ } = Object.assign({
79
+ ttl: 60,
80
+ headersFilter: defaultHeadersFilter,
81
+ hashStrategy: defaultHashStrategy,
82
+ namespace: 'view'
83
+ }, options);
84
+ return wrapper(async (req, res, next) => {
85
+ const cacheKey = requestToCacheKey(req, hashStrategy);
86
+ const {
87
+ headers: cachedHeaders = [],
88
+ body: cachedBody
89
+ } = await cache.namespace(namespace).get(cacheKey)
90
+ || {
91
+ headers: [],
92
+ body: null
93
+ };
94
+ if (req.query.flush !== 'true' && cachedBody) {
95
+ logger.debug('View cache hit by key %s', cacheKey);
96
+ if (cachedHeaders.length > 0) {
97
+ cachedHeaders.forEach(([key, value]) => {
98
+ res.setHeader(key, value);
99
+ });
100
+ }
101
+ res.setHeader('X-View-Cache-Hit', cacheKey);
102
+ res.send(cachedBody);
103
+ return;
104
+ }
105
+ res.realSend = res.send;
106
+ res.send = (body) => {
107
+ logger.debug('View cache missed by key %s, creating...', cacheKey);
108
+ res.setHeader('X-View-Cache-Miss', cacheKey);
109
+ res.setHeader('X-View-Cache-Expire-At', moment().add(ttl, 'minute').format('YYYY-MM-DD HH:mm:ss Z'));
110
+ res.setHeader('X-View-Cache-Created-At', moment().format('YYYY-MM-DD HH:mm:ss Z'));
111
+ res.realSend(body);
112
+ const headers = headersFilter && typeof headersFilter === 'function' ?
113
+ headersFilter(res) : defaultHeadersFilter(res);
114
+ if (res.statusCode <= 500) {
115
+ cache.namespace(namespace).set(cacheKey, { headers, body }, ttl).catch((e) => {
116
+ logger.error('View cache set failed for %s', cacheKey, e);
117
+ });
118
+ }
119
+ };
120
+ next();
121
+ });
122
+ };
123
+ }
124
+
125
+ constitute.Dependencies(Cache, Logger)(ViewCacheMiddleware);
126
+
127
+ export default ViewCacheMiddleware;