evaengine 0.11.2 → 1.0.0

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 (105) 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/index.js +57 -0
  11. package/bin/engine-babel +0 -38
  12. package/lib/commands/index.js +0 -25
  13. package/lib/commands/index.js.map +0 -1
  14. package/lib/commands/interface.js +0 -51
  15. package/lib/commands/interface.js.map +0 -1
  16. package/lib/commands/make_entity.js +0 -549
  17. package/lib/commands/make_entity.js.map +0 -1
  18. package/lib/commands/tramp.js +0 -53
  19. package/lib/commands/tramp.js.map +0 -1
  20. package/lib/config/index.js +0 -98
  21. package/lib/config/index.js.map +0 -1
  22. package/lib/di.js +0 -99
  23. package/lib/di.js.map +0 -1
  24. package/lib/engine.js +0 -558
  25. package/lib/engine.js.map +0 -1
  26. package/lib/entities/index.js +0 -283
  27. package/lib/entities/index.js.map +0 -1
  28. package/lib/exceptions/index.js +0 -522
  29. package/lib/exceptions/index.js.map +0 -1
  30. package/lib/index.js +0 -105
  31. package/lib/index.js.map +0 -1
  32. package/lib/middlewares/auth.js +0 -97
  33. package/lib/middlewares/auth.js.map +0 -1
  34. package/lib/middlewares/auth_kong.js +0 -48
  35. package/lib/middlewares/auth_kong.js.map +0 -1
  36. package/lib/middlewares/debug.js +0 -68
  37. package/lib/middlewares/debug.js.map +0 -1
  38. package/lib/middlewares/index.js +0 -45
  39. package/lib/middlewares/index.js.map +0 -1
  40. package/lib/middlewares/providers.js +0 -102
  41. package/lib/middlewares/providers.js.map +0 -1
  42. package/lib/middlewares/session.js +0 -76
  43. package/lib/middlewares/session.js.map +0 -1
  44. package/lib/middlewares/trace.js +0 -241
  45. package/lib/middlewares/trace.js.map +0 -1
  46. package/lib/middlewares/validator.js +0 -71
  47. package/lib/middlewares/validator.js.map +0 -1
  48. package/lib/middlewares/view_cache.js +0 -160
  49. package/lib/middlewares/view_cache.js.map +0 -1
  50. package/lib/services/cache.js +0 -234
  51. package/lib/services/cache.js.map +0 -1
  52. package/lib/services/config.js +0 -140
  53. package/lib/services/config.js.map +0 -1
  54. package/lib/services/env.js +0 -40
  55. package/lib/services/env.js.map +0 -1
  56. package/lib/services/event_manager.js +0 -110
  57. package/lib/services/event_manager.js.map +0 -1
  58. package/lib/services/http_client.js +0 -178
  59. package/lib/services/http_client.js.map +0 -1
  60. package/lib/services/index.js +0 -70
  61. package/lib/services/index.js.map +0 -1
  62. package/lib/services/interface.js +0 -12
  63. package/lib/services/interface.js.map +0 -1
  64. package/lib/services/joi.js +0 -28
  65. package/lib/services/joi.js.map +0 -1
  66. package/lib/services/jwt_token.js +0 -120
  67. package/lib/services/jwt_token.js.map +0 -1
  68. package/lib/services/jwt_token_kong.js +0 -111
  69. package/lib/services/jwt_token_kong.js.map +0 -1
  70. package/lib/services/logger.js +0 -172
  71. package/lib/services/logger.js.map +0 -1
  72. package/lib/services/namespace.js +0 -188
  73. package/lib/services/namespace.js.map +0 -1
  74. package/lib/services/now.js +0 -69
  75. package/lib/services/now.js.map +0 -1
  76. package/lib/services/providers.js +0 -195
  77. package/lib/services/providers.js.map +0 -1
  78. package/lib/services/redis.js +0 -77
  79. package/lib/services/redis.js.map +0 -1
  80. package/lib/services/rest_client.js +0 -136
  81. package/lib/services/rest_client.js.map +0 -1
  82. package/lib/swagger/index.js +0 -684
  83. package/lib/swagger/index.js.map +0 -1
  84. package/lib/utils/api_scaffold.js +0 -253
  85. package/lib/utils/api_scaffold.js.map +0 -1
  86. package/lib/utils/case_converter.js +0 -48
  87. package/lib/utils/case_converter.js.map +0 -1
  88. package/lib/utils/crc32.js +0 -22
  89. package/lib/utils/crc32.js.map +0 -1
  90. package/lib/utils/datetime.js +0 -21
  91. package/lib/utils/datetime.js.map +0 -1
  92. package/lib/utils/host.js +0 -48
  93. package/lib/utils/host.js.map +0 -1
  94. package/lib/utils/index.js +0 -61
  95. package/lib/utils/index.js.map +0 -1
  96. package/lib/utils/pagination.js +0 -269
  97. package/lib/utils/pagination.js.map +0 -1
  98. package/lib/utils/random.js +0 -33
  99. package/lib/utils/random.js.map +0 -1
  100. package/lib/utils/smart_query.js +0 -342
  101. package/lib/utils/smart_query.js.map +0 -1
  102. package/lib/utils/test.js +0 -62
  103. package/lib/utils/test.js.map +0 -1
  104. package/lib/utils/wrapper.js +0 -9
  105. package/lib/utils/wrapper.js.map +0 -1
@@ -1,241 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.tracerToZipkins = undefined;
7
-
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 => {
37
- if (!tracer) {
38
- return false;
39
- }
40
- const {
41
- url,
42
- method,
43
- serviceName,
44
- spanId: id,
45
- traceId,
46
- parentId,
47
- timestamp,
48
- duration,
49
- statusCode,
50
- port,
51
- queries
52
- } = tracer;
53
-
54
- const name = `${statusCode} ${method} ${url}`;
55
- const endpoint = {
56
- serviceName,
57
- ipv4: hostIp,
58
- port
59
- };
60
- const zipkin = {
61
- id,
62
- traceId,
63
- name,
64
- timestamp,
65
- 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
- }]
94
- };
95
-
96
- if (parentId) {
97
- zipkin.parentId = parentId;
98
- }
99
-
100
- const zipkins = [zipkin];
101
- if (queries && queries.length > 0) {
102
- queries.forEach(element => {
103
- const { query, cost, finishedAt } = element;
104
- zipkins.push({
105
- id: (0, _utils.randomString)(),
106
- parentId: id,
107
- traceId,
108
- name: 'sequelize',
109
- timestamp: finishedAt - cost,
110
- duration: cost,
111
- annotations: [{
112
- endpoint,
113
- timestamp: finishedAt - cost,
114
- value: 'cs'
115
- }, {
116
- endpoint,
117
- timestamp: finishedAt,
118
- value: 'cr'
119
- }],
120
- binaryAnnotations: [{
121
- key: 'query',
122
- value: query
123
- }]
124
- });
125
- });
126
- }
127
- return zipkins;
128
- };
129
-
130
- function TraceMiddleware(ns, config, logger, client) {
131
- const enabled = config.get('trace.enable');
132
- return name => (req, res, next) => {
133
- const spanId = (0, _utils.randomString)();
134
- const traceId = req.get('X-B3-TraceId') || spanId;
135
- const parentId = req.get('X-B3-SpanId') || '';
136
- const startedAt = process.hrtime();
137
- const timestamp = (0, _utils.getMicroTimestamp)();
138
- const serviceName = name || config.get('app.name');
139
- //目前默认全部采样
140
- let sampled = enabled ? 1 : 0;
141
- //只有service为第二级, 且通过参数关闭时才禁止采样
142
- if (sampled && parseInt(req.get('X-B3-Sampled'), 10) < 1 && parentId > 0) {
143
- sampled = 0;
144
- }
145
- const tracer = {
146
- serviceName,
147
- method: req.method,
148
- url: (0, _utils.getHostFullUrl)(req),
149
- port: (0, _utils.getHostPort)(req),
150
- spanId,
151
- traceId,
152
- parentId,
153
- sampled,
154
- timestamp,
155
- duration: null,
156
- statusCode: null,
157
- queries: [],
158
- debug: {}
159
- };
160
-
161
- res.set({
162
- 'X-Service-Name': serviceName,
163
- 'X-Requested-At': timestamp,
164
- 'X-B3-SpanId': spanId,
165
- 'X-B3-TraceId': traceId,
166
- 'X-B3-ParentSpanId': parentId,
167
- 'X-B3-Sampled': enabled ? 1 : 0
168
- });
169
-
170
- if (sampled < 1) {
171
- (0, _onHeaders2.default)(res, () => {
172
- const [seconds, nanoseconds] = process.hrtime(startedAt);
173
- const duration = seconds * 1e3 + nanoseconds * 1e-6;
174
- res.set('X-Response-Milliseconds', parseInt(duration, 10));
175
- });
176
- next();
177
- return;
178
- }
179
-
180
- (0, _onHeaders2.default)(res, () => {
181
- const [seconds, nanoseconds] = process.hrtime(startedAt);
182
- const duration = (seconds * 1e3 + nanoseconds * 1e-6) * 1000;
183
- tracer.duration = parseInt(duration, 10);
184
- tracer.statusCode = res.statusCode;
185
- res.set('X-Response-Milliseconds', tracer.duration / 1000);
186
-
187
- const useHeader = config.get('trace.header');
188
- if (!useHeader) {
189
- return;
190
- }
191
- const zipkins = tracerToZipkins(tracer);
192
- if (!zipkins) {
193
- logger.warn('Tracer not send by no data for request %s', spanId);
194
- } else {
195
- res.set(`X-Debug-${spanId}`, JSON.stringify(zipkins));
196
- }
197
-
198
- if (Object.keys(tracer.debug).length > 0) {
199
- Object.entries(tracer.debug).forEach(([key, value]) => {
200
- res.set(key.replace('x-debug', 'X-Debug'), value);
201
- });
202
- }
203
- });
204
-
205
- const recordZipkin = () => {
206
- const api = config.get('trace.api');
207
- if (!api) {
208
- return;
209
- }
210
- logger.debug('Tracer prepare to send for request %s', spanId);
211
- const zipkins = tracerToZipkins(ns.get('tracer'));
212
- if (!zipkins) {
213
- logger.warn('Tracer not send by no data for request %s', spanId);
214
- return;
215
- }
216
- client.request({
217
- url: api,
218
- method: 'POST',
219
- json: zipkins
220
- }).catch(e => {
221
- logger.error('Error happened on sending tracing data', e);
222
- });
223
- };
224
-
225
- res.on('finish', recordZipkin);
226
- res.on('error', recordZipkin);
227
-
228
- ns.bindEmitter(req);
229
- ns.bindEmitter(res);
230
- ns.run(() => {
231
- // logger.debug('Tracer settled for request %s, tracer: %j', spanId, tracer);
232
- ns.set('tracer', tracer);
233
- next();
234
- });
235
- };
236
- }
237
-
238
- (0, _constitute.Dependencies)(_namespace2.default, _config2.default, _logger2.default, _http_client2.default)(TraceMiddleware); //eslint-disable-line new-cap
239
-
240
- exports.default = TraceMiddleware;
241
- //# sourceMappingURL=trace.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/middlewares/trace.js"],"names":["hostIp","tracerToZipkins","tracer","url","method","serviceName","spanId","id","traceId","parentId","timestamp","duration","statusCode","port","queries","name","endpoint","ipv4","zipkin","annotations","value","binaryAnnotations","key","toString","zipkins","length","forEach","element","query","cost","finishedAt","push","TraceMiddleware","ns","config","logger","client","enabled","get","req","res","next","startedAt","process","hrtime","sampled","parseInt","debug","set","seconds","nanoseconds","useHeader","warn","JSON","stringify","Object","keys","entries","replace","recordZipkin","api","request","json","catch","e","error","on","bindEmitter","run","Namespace","Config","Logger","HttpClient"],"mappings":"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","file":"trace.js","sourcesContent":["import onHeaders from 'on-headers';\nimport { Dependencies } from 'constitute';\nimport { randomString, getHostFullUrl, getHostPort, getHostIp, getMicroTimestamp } from '../utils';\nimport Namespace from '../services/namespace';\nimport Config from '../services/config';\nimport Logger from '../services/logger';\nimport HttpClient from '../services/http_client';\n\nconst hostIp = getHostIp();\n\nexport const tracerToZipkins = (tracer) => {\n if (!tracer) {\n return false;\n }\n const {\n url,\n method,\n serviceName,\n spanId: id,\n traceId,\n parentId,\n timestamp,\n duration,\n statusCode,\n port,\n queries\n } = tracer;\n\n const name = `${statusCode} ${method} ${url}`;\n const endpoint = {\n serviceName,\n ipv4: hostIp,\n port\n };\n const zipkin = {\n id,\n traceId,\n name,\n timestamp,\n duration,\n annotations: [\n {\n endpoint,\n timestamp,\n value: 'sr'\n },\n {\n endpoint,\n timestamp: timestamp + duration,\n value: 'ss'\n }\n ],\n binaryAnnotations: [\n {\n key: 'traceId',\n value: traceId\n },\n {\n key: 'spanId',\n value: id\n },\n {\n key: 'method',\n value: method\n },\n {\n key: 'url',\n value: url\n },\n {\n key: 'port',\n value: port.toString()\n },\n {\n key: 'statusCode',\n value: statusCode.toString()\n }\n ]\n };\n\n if (parentId) {\n zipkin.parentId = parentId;\n }\n\n const zipkins = [zipkin];\n if (queries && queries.length > 0) {\n queries.forEach((element) => {\n const { query, cost, finishedAt } = element;\n zipkins.push({\n id: randomString(),\n parentId: id,\n traceId,\n name: 'sequelize',\n timestamp: finishedAt - cost,\n duration: cost,\n annotations: [\n {\n endpoint,\n timestamp: finishedAt - cost,\n value: 'cs'\n },\n {\n endpoint,\n timestamp: finishedAt,\n value: 'cr'\n }\n ],\n binaryAnnotations: [{\n key: 'query',\n value: query\n }]\n });\n });\n }\n return zipkins;\n};\n\n\nfunction TraceMiddleware(ns, config, logger, client) {\n const enabled = config.get('trace.enable');\n return name => (req, res, next) => {\n const spanId = randomString();\n const traceId = req.get('X-B3-TraceId') || spanId;\n const parentId = req.get('X-B3-SpanId') || '';\n const startedAt = process.hrtime();\n const timestamp = getMicroTimestamp();\n const serviceName = name || config.get('app.name');\n //目前默认全部采样\n let sampled = enabled ? 1 : 0;\n //只有service为第二级, 且通过参数关闭时才禁止采样\n if (sampled && parseInt(req.get('X-B3-Sampled'), 10) < 1 && parentId > 0) {\n sampled = 0;\n }\n const tracer = {\n serviceName,\n method: req.method,\n url: getHostFullUrl(req),\n port: getHostPort(req),\n spanId,\n traceId,\n parentId,\n sampled,\n timestamp,\n duration: null,\n statusCode: null,\n queries: [],\n debug: {}\n };\n\n res.set({\n 'X-Service-Name': serviceName,\n 'X-Requested-At': timestamp,\n 'X-B3-SpanId': spanId,\n 'X-B3-TraceId': traceId,\n 'X-B3-ParentSpanId': parentId,\n 'X-B3-Sampled': enabled ? 1 : 0\n });\n\n if (sampled < 1) {\n onHeaders(res, () => {\n const [seconds, nanoseconds] = process.hrtime(startedAt);\n const duration = ((seconds * 1e3) + (nanoseconds * 1e-6));\n res.set('X-Response-Milliseconds', parseInt(duration, 10));\n });\n next();\n return;\n }\n\n onHeaders(res, () => {\n const [seconds, nanoseconds] = process.hrtime(startedAt);\n const duration = ((seconds * 1e3) + (nanoseconds * 1e-6)) * 1000;\n tracer.duration = parseInt(duration, 10);\n tracer.statusCode = res.statusCode;\n res.set('X-Response-Milliseconds', tracer.duration / 1000);\n\n const useHeader = config.get('trace.header');\n if (!useHeader) {\n return;\n }\n const zipkins = tracerToZipkins(tracer);\n if (!zipkins) {\n logger.warn('Tracer not send by no data for request %s', spanId);\n } else {\n res.set(`X-Debug-${spanId}`, JSON.stringify(zipkins));\n }\n\n if (Object.keys(tracer.debug).length > 0) {\n Object.entries(tracer.debug).forEach(([key, value]) => {\n res.set(key.replace('x-debug', 'X-Debug'), value);\n });\n }\n });\n\n const recordZipkin = () => {\n const api = config.get('trace.api');\n if (!api) {\n return;\n }\n logger.debug('Tracer prepare to send for request %s', spanId);\n const zipkins = tracerToZipkins(ns.get('tracer'));\n if (!zipkins) {\n logger.warn('Tracer not send by no data for request %s', spanId);\n return;\n }\n client.request({\n url: api,\n method: 'POST',\n json: zipkins\n }).catch((e) => {\n logger.error('Error happened on sending tracing data', e);\n });\n };\n\n res.on('finish', recordZipkin);\n res.on('error', recordZipkin);\n\n ns.bindEmitter(req);\n ns.bindEmitter(res);\n ns.run(() => {\n // logger.debug('Tracer settled for request %s, tracer: %j', spanId, tracer);\n ns.set('tracer', tracer);\n next();\n });\n };\n}\n\nDependencies(Namespace, Config, Logger, HttpClient)(TraceMiddleware); //eslint-disable-line new-cap\n\nexport default TraceMiddleware;\n"]}
@@ -1,71 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
-
7
- var _joi = require('joi');
8
-
9
- var _joi2 = _interopRequireDefault(_joi);
10
-
11
- var _constitute = require('constitute');
12
-
13
- var _wrapper = require('../utils/wrapper');
14
-
15
- var _wrapper2 = _interopRequireDefault(_wrapper);
16
-
17
- var _exceptions = require('../exceptions');
18
-
19
- var _joi3 = require('../services/joi');
20
-
21
- var _joi4 = _interopRequireDefault(_joi3);
22
-
23
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24
-
25
- function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
26
-
27
- const validate = (data, schema, options) => new Promise((resolve, reject) => {
28
- _joi2.default.validate(data, schema, Object.assign({ abortEarly: false, allowUnknown: true }, options), (err, value) => {
29
- if (err) {
30
- reject(err);
31
- } else {
32
- resolve(value);
33
- }
34
- });
35
- });
36
-
37
- /**
38
- * @returns {function()}
39
- * @constructor
40
- */
41
- function ValidatorMiddleware(validatorBase) {
42
- return (getSchema, options, validator) => (0, _wrapper2.default)((() => {
43
- var _ref = _asyncToGenerator(function* (req, res, next) {
44
- //eslint-disable-line no-unused-vars
45
- const { query, body, path } = getSchema(validator || validatorBase.getJoi());
46
- try {
47
- if (query) {
48
- yield validate(req.query, query, options);
49
- }
50
- if (body) {
51
- yield validate(req.body, body, options);
52
- }
53
- if (path) {
54
- yield validate(req.params, path, options);
55
- }
56
- return next();
57
- } catch (e) {
58
- throw new _exceptions.FormInvalidateException(e);
59
- }
60
- });
61
-
62
- return function (_x, _x2, _x3) {
63
- return _ref.apply(this, arguments);
64
- };
65
- })());
66
- }
67
-
68
- (0, _constitute.Dependencies)(_joi4.default)(ValidatorMiddleware); //eslint-disable-line new-cap
69
-
70
- exports.default = ValidatorMiddleware;
71
- //# sourceMappingURL=validator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/middlewares/validator.js"],"names":["validate","data","schema","options","Promise","resolve","reject","Joi","Object","assign","abortEarly","allowUnknown","err","value","ValidatorMiddleware","validatorBase","getSchema","validator","req","res","next","query","body","path","getJoi","params","e","FormInvalidateException","ValidatorBase"],"mappings":";;;;;;AAAA;;;;AACA;;AACA;;;;AACA;;AACA;;;;;;;;AAEA,MAAMA,WAAW,CAACC,IAAD,EAAOC,MAAP,EAAeC,OAAf,KACf,IAAIC,OAAJ,CAAY,CAACC,OAAD,EAAUC,MAAV,KAAqB;AAC/BC,gBAAIP,QAAJ,CAAaC,IAAb,EAAmBC,MAAnB,EAA2BM,OAAOC,MAAP,CACzB,EAAEC,YAAY,KAAd,EAAqBC,cAAc,IAAnC,EADyB,EAEzBR,OAFyB,CAA3B,EAGG,CAACS,GAAD,EAAMC,KAAN,KAAgB;AACjB,QAAID,GAAJ,EAAS;AACPN,aAAOM,GAAP;AACD,KAFD,MAEO;AACLP,cAAQQ,KAAR;AACD;AACF,GATD;AAUD,CAXD,CADF;;AAcA;;;;AAIA,SAASC,mBAAT,CAA6BC,aAA7B,EAA4C;AAC1C,SAAO,CAACC,SAAD,EAAYb,OAAZ,EAAqBc,SAArB,KACL;AAAA,iCAAQ,WAAOC,GAAP,EAAYC,GAAZ,EAAiBC,IAAjB,EAA0B;AAAE;AAClC,YAAM,EAAEC,KAAF,EAASC,IAAT,EAAeC,IAAf,KAAwBP,UAAUC,aAAaF,cAAcS,MAAd,EAAvB,CAA9B;AACA,UAAI;AACF,YAAIH,KAAJ,EAAW;AACT,gBAAMrB,SAASkB,IAAIG,KAAb,EAAoBA,KAApB,EAA2BlB,OAA3B,CAAN;AACD;AACD,YAAImB,IAAJ,EAAU;AACR,gBAAMtB,SAASkB,IAAII,IAAb,EAAmBA,IAAnB,EAAyBnB,OAAzB,CAAN;AACD;AACD,YAAIoB,IAAJ,EAAU;AACR,gBAAMvB,SAASkB,IAAIO,MAAb,EAAqBF,IAArB,EAA2BpB,OAA3B,CAAN;AACD;AACD,eAAOiB,MAAP;AACD,OAXD,CAWE,OAAOM,CAAP,EAAU;AACV,cAAM,IAAIC,mCAAJ,CAA4BD,CAA5B,CAAN;AACD;AACF,KAhBD;;AAAA;AAAA;AAAA;AAAA,OADF;AAkBD;;AAED,8BAAaE,aAAb,EAA4Bd,mBAA5B,E,CAAkD;;kBAEnCA,mB","file":"validator.js","sourcesContent":["import Joi from 'joi';\nimport { Dependencies } from 'constitute';\nimport wrapper from '../utils/wrapper';\nimport { FormInvalidateException } from '../exceptions';\nimport ValidatorBase from '../services/joi';\n\nconst validate = (data, schema, options) =>\n new Promise((resolve, reject) => {\n Joi.validate(data, schema, Object.assign(\n { abortEarly: false, allowUnknown: true },\n options\n ), (err, value) => {\n if (err) {\n reject(err);\n } else {\n resolve(value);\n }\n });\n });\n\n/**\n * @returns {function()}\n * @constructor\n */\nfunction ValidatorMiddleware(validatorBase) {\n return (getSchema, options, validator) =>\n wrapper(async (req, res, next) => { //eslint-disable-line no-unused-vars\n const { query, body, path } = getSchema(validator || validatorBase.getJoi());\n try {\n if (query) {\n await validate(req.query, query, options);\n }\n if (body) {\n await validate(req.body, body, options);\n }\n if (path) {\n await validate(req.params, path, options);\n }\n return next();\n } catch (e) {\n throw new FormInvalidateException(e);\n }\n });\n}\n\nDependencies(ValidatorBase)(ValidatorMiddleware); //eslint-disable-line new-cap\n\nexport default ValidatorMiddleware;\n"]}
@@ -1,160 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.requestToCacheKey = exports.defaultHeadersFilter = exports.defaultHashStrategy = undefined;
7
-
8
- var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
9
-
10
- var _constitute = require('constitute');
11
-
12
- var _crypto = require('crypto');
13
-
14
- var _crypto2 = _interopRequireDefault(_crypto);
15
-
16
- var _util = require('util');
17
-
18
- var _util2 = _interopRequireDefault(_util);
19
-
20
- var _momentTimezone = require('moment-timezone');
21
-
22
- var _momentTimezone2 = _interopRequireDefault(_momentTimezone);
23
-
24
- var _logger = require('../services/logger');
25
-
26
- var _logger2 = _interopRequireDefault(_logger);
27
-
28
- var _cache = require('../services/cache');
29
-
30
- var _cache2 = _interopRequireDefault(_cache);
31
-
32
- var _wrapper = require('../utils/wrapper');
33
-
34
- var _wrapper2 = _interopRequireDefault(_wrapper);
35
-
36
- var _exceptions = require('../exceptions');
37
-
38
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
-
40
- function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
41
-
42
- const defaultHashStrategy = exports.defaultHashStrategy = obj => obj;
43
-
44
- const defaultHeadersFilter = exports.defaultHeadersFilter = res => {
45
- const headers = [];
46
- ['Content-Type'].forEach(key => {
47
- const value = res.get(key);
48
- if (value) {
49
- headers.push([key, value]);
50
- }
51
- });
52
- return headers;
53
- };
54
-
55
- const requestToCacheKey = exports.requestToCacheKey = (req, hashStrategy) => {
56
- const {
57
- method,
58
- originalUrl,
59
- query: originQuery,
60
- route,
61
- uid = null //Custom rule
62
- } = req;
63
- const query = _extends({}, originQuery);
64
- delete query.flush;
65
- if (hashStrategy && !_util2.default.isFunction(hashStrategy)) {
66
- throw new _exceptions.RuntimeException(`View cache hash strategy must be a function for ${originalUrl}`);
67
- }
68
- if (!route) {
69
- throw new _exceptions.RuntimeException(`View cache middleware require route for ${originalUrl}`);
70
- }
71
- if (method.toLowerCase() !== 'get') {
72
- throw new _exceptions.RuntimeException(`View cache middleware only support GET method of http request for ${originalUrl}`);
73
- }
74
- const { host = 'unknown' } = req.headers;
75
- const [urlPath = ''] = originalUrl.split('?');
76
- const key = [method, `/${host}`, urlPath].join('').replace(/:/g, '_').toLowerCase();
77
- const strategy = hashStrategy || defaultHashStrategy;
78
- const hash = _crypto2.default.createHash('md5').update(JSON.stringify(strategy({
79
- method,
80
- urlPath,
81
- query,
82
- uid
83
- }))).digest('hex');
84
- return [key, hash].join(':');
85
- };
86
-
87
- /**
88
- * @param {Cache} cache
89
- * @param {Logger} logger
90
- * @returns {function(*=)}
91
- * @constructor
92
- */
93
- function ViewCacheMiddleware(cache, logger) {
94
- return (options = {}) => {
95
- if (!_util2.default.isObject(options)) {
96
- options = { //eslint-disable-line no-param-reassign
97
- ttl: options
98
- };
99
- }
100
- const {
101
- ttl,
102
- headersFilter,
103
- namespace,
104
- hashStrategy
105
- } = Object.assign({
106
- ttl: 60,
107
- headersFilter: defaultHeadersFilter,
108
- hashStrategy: defaultHashStrategy,
109
- namespace: 'view'
110
- }, options);
111
- return (0, _wrapper2.default)((() => {
112
- var _ref = _asyncToGenerator(function* (req, res, next) {
113
- const cacheKey = requestToCacheKey(req, hashStrategy);
114
- const {
115
- headers: cachedHeaders = [],
116
- body: cachedBody
117
- } = (yield cache.namespace(namespace).get(cacheKey)) || {
118
- headers: [],
119
- body: null
120
- };
121
- if (req.query.flush !== 'true' && cachedBody) {
122
- logger.debug('View cache hit by key %s', cacheKey);
123
- if (cachedHeaders.length > 0) {
124
- cachedHeaders.forEach(function ([key, value]) {
125
- res.setHeader(key, value);
126
- });
127
- }
128
- res.setHeader('X-View-Cache-Hit', cacheKey);
129
- res.send(cachedBody);
130
- return;
131
- }
132
- res.realSend = res.send; //eslint-disable-line no-param-reassign
133
- res.send = function (body) {
134
- //eslint-disable-line no-param-reassign
135
- logger.debug('View cache missed by key %s, creating...', cacheKey);
136
- res.setHeader('X-View-Cache-Miss', cacheKey);
137
- res.setHeader('X-View-Cache-Expire-At', (0, _momentTimezone2.default)().add(ttl, 'minute').format('YYYY-MM-DD HH:mm:ss Z'));
138
- res.setHeader('X-View-Cache-Created-At', (0, _momentTimezone2.default)().format('YYYY-MM-DD HH:mm:ss Z'));
139
- res.realSend(body);
140
- const headers = headersFilter && _util2.default.isFunction(headersFilter) ? headersFilter(res) : defaultHeadersFilter(res);
141
- if (res.statusCode <= 500) {
142
- cache.namespace(namespace).set(cacheKey, { headers, body }, ttl).catch(function (e) {
143
- logger.error('View cache set failed for %s', cacheKey, e);
144
- });
145
- }
146
- };
147
- next();
148
- });
149
-
150
- return function (_x, _x2, _x3) {
151
- return _ref.apply(this, arguments);
152
- };
153
- })());
154
- };
155
- }
156
-
157
- (0, _constitute.Dependencies)(_cache2.default, _logger2.default)(ViewCacheMiddleware); //eslint-disable-line new-cap
158
-
159
- exports.default = ViewCacheMiddleware;
160
- //# sourceMappingURL=view_cache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/middlewares/view_cache.js"],"names":["defaultHashStrategy","obj","defaultHeadersFilter","res","headers","forEach","key","value","get","push","requestToCacheKey","req","hashStrategy","method","originalUrl","query","originQuery","route","uid","flush","util","isFunction","RuntimeException","toLowerCase","host","urlPath","split","join","replace","strategy","hash","crypto","createHash","update","JSON","stringify","digest","ViewCacheMiddleware","cache","logger","options","isObject","ttl","headersFilter","namespace","Object","assign","next","cacheKey","cachedHeaders","body","cachedBody","debug","length","setHeader","send","realSend","add","format","statusCode","set","catch","e","error","Cache","Logger"],"mappings":"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","file":"view_cache.js","sourcesContent":["import { Dependencies } from 'constitute';\nimport crypto from 'crypto';\nimport util from 'util';\nimport moment from 'moment-timezone';\nimport Logger from '../services/logger';\nimport Cache from '../services/cache';\nimport wrapper from '../utils/wrapper';\nimport { RuntimeException } from '../exceptions';\n\nexport const defaultHashStrategy = obj => obj;\n\nexport const defaultHeadersFilter = (res) => {\n const headers = [];\n ['Content-Type'].forEach((key) => {\n const value = res.get(key);\n if (value) {\n headers.push([key, value]);\n }\n });\n return headers;\n};\n\nexport const requestToCacheKey = (req, hashStrategy) => {\n const {\n method,\n originalUrl,\n query: originQuery,\n route,\n uid = null //Custom rule\n } = req;\n const query = { ...originQuery };\n delete query.flush;\n if (hashStrategy && !util.isFunction(hashStrategy)) {\n throw new RuntimeException(`View cache hash strategy must be a function for ${originalUrl}`);\n }\n if (!route) {\n throw new RuntimeException(`View cache middleware require route for ${originalUrl}`);\n }\n if (method.toLowerCase() !== 'get') {\n throw new RuntimeException(`View cache middleware only support GET method of http request for ${originalUrl}`);\n }\n const { host = 'unknown' } = req.headers;\n const [urlPath = ''] = originalUrl.split('?');\n const key = [method, `/${host}`, urlPath].join('').replace(/:/g, '_').toLowerCase();\n const strategy = hashStrategy || defaultHashStrategy;\n const hash = crypto\n .createHash('md5')\n .update(JSON\n .stringify(strategy({\n method,\n urlPath,\n query,\n uid\n })))\n .digest('hex');\n return [key, hash].join(':');\n};\n\n\n/**\n * @param {Cache} cache\n * @param {Logger} logger\n * @returns {function(*=)}\n * @constructor\n */\nfunction ViewCacheMiddleware(cache, logger) {\n return (options = {}) => {\n if (!util.isObject(options)) {\n options = { //eslint-disable-line no-param-reassign\n ttl: options\n };\n }\n const {\n ttl,\n headersFilter,\n namespace,\n hashStrategy\n } = Object.assign({\n ttl: 60,\n headersFilter: defaultHeadersFilter,\n hashStrategy: defaultHashStrategy,\n namespace: 'view'\n }, options);\n return wrapper(async (req, res, next) => {\n const cacheKey = requestToCacheKey(req, hashStrategy);\n const {\n headers: cachedHeaders = [],\n body: cachedBody\n } = await cache.namespace(namespace).get(cacheKey)\n || {\n headers: [],\n body: null\n };\n if (req.query.flush !== 'true' && cachedBody) {\n logger.debug('View cache hit by key %s', cacheKey);\n if (cachedHeaders.length > 0) {\n cachedHeaders.forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n }\n res.setHeader('X-View-Cache-Hit', cacheKey);\n res.send(cachedBody);\n return;\n }\n res.realSend = res.send; //eslint-disable-line no-param-reassign\n res.send = (body) => { //eslint-disable-line no-param-reassign\n logger.debug('View cache missed by key %s, creating...', cacheKey);\n res.setHeader('X-View-Cache-Miss', cacheKey);\n res.setHeader('X-View-Cache-Expire-At', moment().add(ttl, 'minute').format('YYYY-MM-DD HH:mm:ss Z'));\n res.setHeader('X-View-Cache-Created-At', moment().format('YYYY-MM-DD HH:mm:ss Z'));\n res.realSend(body);\n const headers = headersFilter && util.isFunction(headersFilter) ?\n headersFilter(res) : defaultHeadersFilter(res);\n if (res.statusCode <= 500) {\n cache.namespace(namespace).set(cacheKey, { headers, body }, ttl).catch((e) => {\n logger.error('View cache set failed for %s', cacheKey, e);\n });\n }\n };\n next();\n });\n };\n}\n\nDependencies(Cache, Logger)(ViewCacheMiddleware);//eslint-disable-line new-cap\n\nexport default ViewCacheMiddleware;\n"]}