evaengine 0.11.1 → 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.
- package/.ai/analysis.md +657 -0
- package/.ai/architecture/runtime.md +504 -0
- package/.ai/contracts/public-api.md +447 -0
- package/.ai/external-project-guide.md +248 -0
- package/.ai/vision.md +314 -0
- package/README.md +51 -62
- package/bin/engine +15 -21
- package/index.js +2 -18
- package/package.json +60 -64
- package/src/index.js +57 -0
- package/bin/engine-babel +0 -38
- package/lib/commands/index.js +0 -25
- package/lib/commands/index.js.map +0 -1
- package/lib/commands/interface.js +0 -51
- package/lib/commands/interface.js.map +0 -1
- package/lib/commands/make_entity.js +0 -549
- package/lib/commands/make_entity.js.map +0 -1
- package/lib/commands/tramp.js +0 -53
- package/lib/commands/tramp.js.map +0 -1
- package/lib/config/index.js +0 -98
- package/lib/config/index.js.map +0 -1
- package/lib/di.js +0 -99
- package/lib/di.js.map +0 -1
- package/lib/engine.js +0 -558
- package/lib/engine.js.map +0 -1
- package/lib/entities/index.js +0 -283
- package/lib/entities/index.js.map +0 -1
- package/lib/exceptions/index.js +0 -522
- package/lib/exceptions/index.js.map +0 -1
- package/lib/index.js +0 -105
- package/lib/index.js.map +0 -1
- package/lib/middlewares/auth.js +0 -97
- package/lib/middlewares/auth.js.map +0 -1
- package/lib/middlewares/auth_kong.js +0 -48
- package/lib/middlewares/auth_kong.js.map +0 -1
- package/lib/middlewares/debug.js +0 -68
- package/lib/middlewares/debug.js.map +0 -1
- package/lib/middlewares/index.js +0 -45
- package/lib/middlewares/index.js.map +0 -1
- package/lib/middlewares/providers.js +0 -102
- package/lib/middlewares/providers.js.map +0 -1
- package/lib/middlewares/session.js +0 -76
- package/lib/middlewares/session.js.map +0 -1
- package/lib/middlewares/trace.js +0 -241
- package/lib/middlewares/trace.js.map +0 -1
- package/lib/middlewares/validator.js +0 -71
- package/lib/middlewares/validator.js.map +0 -1
- package/lib/middlewares/view_cache.js +0 -160
- package/lib/middlewares/view_cache.js.map +0 -1
- package/lib/services/cache.js +0 -234
- package/lib/services/cache.js.map +0 -1
- package/lib/services/config.js +0 -140
- package/lib/services/config.js.map +0 -1
- package/lib/services/env.js +0 -40
- package/lib/services/env.js.map +0 -1
- package/lib/services/event_manager.js +0 -110
- package/lib/services/event_manager.js.map +0 -1
- package/lib/services/http_client.js +0 -178
- package/lib/services/http_client.js.map +0 -1
- package/lib/services/index.js +0 -70
- package/lib/services/index.js.map +0 -1
- package/lib/services/interface.js +0 -12
- package/lib/services/interface.js.map +0 -1
- package/lib/services/joi.js +0 -28
- package/lib/services/joi.js.map +0 -1
- package/lib/services/jwt_token.js +0 -120
- package/lib/services/jwt_token.js.map +0 -1
- package/lib/services/jwt_token_kong.js +0 -111
- package/lib/services/jwt_token_kong.js.map +0 -1
- package/lib/services/logger.js +0 -172
- package/lib/services/logger.js.map +0 -1
- package/lib/services/namespace.js +0 -188
- package/lib/services/namespace.js.map +0 -1
- package/lib/services/now.js +0 -69
- package/lib/services/now.js.map +0 -1
- package/lib/services/providers.js +0 -195
- package/lib/services/providers.js.map +0 -1
- package/lib/services/redis.js +0 -77
- package/lib/services/redis.js.map +0 -1
- package/lib/services/rest_client.js +0 -136
- package/lib/services/rest_client.js.map +0 -1
- package/lib/swagger/index.js +0 -684
- package/lib/swagger/index.js.map +0 -1
- package/lib/utils/api_scaffold.js +0 -253
- package/lib/utils/api_scaffold.js.map +0 -1
- package/lib/utils/case_converter.js +0 -48
- package/lib/utils/case_converter.js.map +0 -1
- package/lib/utils/crc32.js +0 -22
- package/lib/utils/crc32.js.map +0 -1
- package/lib/utils/datetime.js +0 -21
- package/lib/utils/datetime.js.map +0 -1
- package/lib/utils/host.js +0 -48
- package/lib/utils/host.js.map +0 -1
- package/lib/utils/index.js +0 -61
- package/lib/utils/index.js.map +0 -1
- package/lib/utils/pagination.js +0 -269
- package/lib/utils/pagination.js.map +0 -1
- package/lib/utils/random.js +0 -33
- package/lib/utils/random.js.map +0 -1
- package/lib/utils/smart_query.js +0 -342
- package/lib/utils/smart_query.js.map +0 -1
- package/lib/utils/test.js +0 -62
- package/lib/utils/test.js.map +0 -1
- package/lib/utils/wrapper.js +0 -9
- package/lib/utils/wrapper.js.map +0 -1
package/lib/swagger/index.js
DELETED
|
@@ -1,684 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.ExSwagger = exports.AnnotationsContainer = exports.Annotation = exports.Fragment = exports.MODEL_TO_FRAGMENT_TYPES_MAPPING = exports.YamlParsingException = exports.AcornParsingException = undefined;
|
|
7
|
-
|
|
8
|
-
var _fs = require('fs');
|
|
9
|
-
|
|
10
|
-
var _fs2 = _interopRequireDefault(_fs);
|
|
11
|
-
|
|
12
|
-
var _util = require('util');
|
|
13
|
-
|
|
14
|
-
var _assert = require('assert');
|
|
15
|
-
|
|
16
|
-
var _assert2 = _interopRequireDefault(_assert);
|
|
17
|
-
|
|
18
|
-
var _merge = require('lodash/merge');
|
|
19
|
-
|
|
20
|
-
var _merge2 = _interopRequireDefault(_merge);
|
|
21
|
-
|
|
22
|
-
var _doctrine = require('doctrine');
|
|
23
|
-
|
|
24
|
-
var _doctrine2 = _interopRequireDefault(_doctrine);
|
|
25
|
-
|
|
26
|
-
var _acorn = require('acorn/dist/acorn');
|
|
27
|
-
|
|
28
|
-
var acorn = _interopRequireWildcard(_acorn);
|
|
29
|
-
|
|
30
|
-
var _glob = require('glob');
|
|
31
|
-
|
|
32
|
-
var _glob2 = _interopRequireDefault(_glob);
|
|
33
|
-
|
|
34
|
-
var _jsYaml = require('js-yaml');
|
|
35
|
-
|
|
36
|
-
var _jsYaml2 = _interopRequireDefault(_jsYaml);
|
|
37
|
-
|
|
38
|
-
var _entities = require('../entities');
|
|
39
|
-
|
|
40
|
-
var _entities2 = _interopRequireDefault(_entities);
|
|
41
|
-
|
|
42
|
-
var _exceptions = require('../exceptions');
|
|
43
|
-
|
|
44
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
45
|
-
|
|
46
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
47
|
-
|
|
48
|
-
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"); }); }; } /*eslint new-cap: [1]*/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
let AcornParsingException = exports.AcornParsingException = class AcornParsingException extends _exceptions.StandardException {};
|
|
52
|
-
let YamlParsingException = exports.YamlParsingException = class YamlParsingException extends _exceptions.StandardException {
|
|
53
|
-
/**
|
|
54
|
-
* @param {Annotation} annotation
|
|
55
|
-
* @returns {YamlParsingException}
|
|
56
|
-
*/
|
|
57
|
-
setAnnotation(annotation) {
|
|
58
|
-
this.annotation = annotation || {};
|
|
59
|
-
return this;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @returns {Annotation}
|
|
64
|
-
*/
|
|
65
|
-
getAnnotation() {
|
|
66
|
-
return this.annotation || {};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
toString() {
|
|
70
|
-
const {
|
|
71
|
-
file, start, end, value
|
|
72
|
-
} = this.getAnnotation();
|
|
73
|
-
return (0, _util.format)('Yaml parsing error happened in %s Line[%s - %s]\n Yaml error: %s \nOriginal Yaml Text:', file, start, end, this.getPrevError() ? this.getPrevError().message : '', value ? value.split('\n').map((v, i) => `${(i - 1).toString().padStart(5)} ${v}`) : []);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
constructor(...args) {
|
|
77
|
-
super(...args);
|
|
78
|
-
this.annotation = {};
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
//Mapping sequelize data types to swagger data types
|
|
83
|
-
//Sequelize types: http://docs.sequelizejs.com/en/latest/api/datatypes/
|
|
84
|
-
//Swagger Data Types: http://swagger.io/specification/
|
|
85
|
-
|
|
86
|
-
const MODEL_TO_FRAGMENT_TYPES_MAPPING = exports.MODEL_TO_FRAGMENT_TYPES_MAPPING = {
|
|
87
|
-
BIGINT: 'integer',
|
|
88
|
-
ENUM: 'string',
|
|
89
|
-
INTEGER: 'integer',
|
|
90
|
-
FLOAT: 'number',
|
|
91
|
-
DOUBLE: 'number',
|
|
92
|
-
DECIMAL: 'number',
|
|
93
|
-
BOOLEAN: 'boolean',
|
|
94
|
-
CHAR: 'string',
|
|
95
|
-
STRING: 'string',
|
|
96
|
-
TEXT: 'string',
|
|
97
|
-
REAL: 'string',
|
|
98
|
-
TIME: 'string',
|
|
99
|
-
DATE: 'string',
|
|
100
|
-
DATEONLY: 'string',
|
|
101
|
-
HSTORE: 'string',
|
|
102
|
-
JSON: 'string',
|
|
103
|
-
JSONB: 'string',
|
|
104
|
-
NOW: 'string',
|
|
105
|
-
BLOB: 'string',
|
|
106
|
-
UUID: 'string',
|
|
107
|
-
UUIDV1: 'string',
|
|
108
|
-
UUIDV4: 'string',
|
|
109
|
-
VIRTUAL: 'string'
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const modelDefaultValueHandlers = {
|
|
113
|
-
integer: v => parseInt(v, 10),
|
|
114
|
-
boolean: v => Boolean(parseInt(v, 10)),
|
|
115
|
-
number: v => parseFloat(v),
|
|
116
|
-
default: v => v
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const FRAGMENT_TYPE_PATH = 'path';
|
|
120
|
-
const FRAGMENT_TYPE_DEFINITION = 'definition';
|
|
121
|
-
const FRAGMENT_TYPE_EXCEPTION = 'exception';
|
|
122
|
-
const FRAGMENT_TYPE_UNKNOWN = 'unknown';
|
|
123
|
-
|
|
124
|
-
let Fragment = exports.Fragment = class Fragment {
|
|
125
|
-
/**
|
|
126
|
-
* @returns {[*,*,*,*]}
|
|
127
|
-
*/
|
|
128
|
-
getTypes() {
|
|
129
|
-
return [FRAGMENT_TYPE_PATH, FRAGMENT_TYPE_DEFINITION, FRAGMENT_TYPE_EXCEPTION, FRAGMENT_TYPE_UNKNOWN];
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
isPath() {
|
|
133
|
-
return this.type === FRAGMENT_TYPE_PATH;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
isDefinition() {
|
|
137
|
-
return this.type === FRAGMENT_TYPE_DEFINITION;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
isUnknown() {
|
|
141
|
-
return this.type === FRAGMENT_TYPE_UNKNOWN;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
isException() {
|
|
145
|
-
return this.type === FRAGMENT_TYPE_EXCEPTION;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* @param {Fragment} fragment
|
|
150
|
-
* @returns {Fragment}
|
|
151
|
-
*/
|
|
152
|
-
setParentFragment(fragment) {
|
|
153
|
-
(0, _assert2.default)(fragment && fragment instanceof Fragment, 'Parent fragment must be instance of Fragment');
|
|
154
|
-
this.parent = fragment;
|
|
155
|
-
return this;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* @returns {null|Fragment}
|
|
160
|
-
*/
|
|
161
|
-
getParentFragment() {
|
|
162
|
-
return this.parent;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
correctSwaggerPath(swaggerDoc = {}) {
|
|
166
|
-
return swaggerDoc;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
toSwaggerDoc(exceptions = {}) {
|
|
170
|
-
if (this.isPath()) {
|
|
171
|
-
const path = Object.keys(this.value)[0];
|
|
172
|
-
const method = Object.keys(this.value[path])[0];
|
|
173
|
-
return {
|
|
174
|
-
paths: {
|
|
175
|
-
[path]: {
|
|
176
|
-
[method]: this.correctSwaggerPath(this.value[path][method])
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (this.isDefinition()) {
|
|
183
|
-
const key = Object.keys(this.value)[0];
|
|
184
|
-
return {
|
|
185
|
-
definitions: {
|
|
186
|
-
[key]: this.value[key]
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (!this.isUnknown()) {
|
|
192
|
-
return {};
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
if (this.isException()) {
|
|
196
|
-
if (!this.getParentFragment()) {
|
|
197
|
-
return {};
|
|
198
|
-
}
|
|
199
|
-
const key = this.value;
|
|
200
|
-
const exception = exceptions[key];
|
|
201
|
-
if (!exception) {
|
|
202
|
-
return {};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const path = Object.keys(this.getParentFragment().value)[0];
|
|
206
|
-
const method = Object.keys(this.getParentFragment().value[path])[0];
|
|
207
|
-
return {
|
|
208
|
-
definitions: {
|
|
209
|
-
[key]: Fragment.exceptionMapping(exception)
|
|
210
|
-
},
|
|
211
|
-
paths: {
|
|
212
|
-
[path]: {
|
|
213
|
-
[method]: {
|
|
214
|
-
responses: {
|
|
215
|
-
[exception.getStatusCode()]: {
|
|
216
|
-
description: this.description,
|
|
217
|
-
schema: {
|
|
218
|
-
$ref: `#/definitions/${key}`
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return {};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
static exceptionMapping(exception) {
|
|
232
|
-
return {
|
|
233
|
-
properties: {
|
|
234
|
-
code: {
|
|
235
|
-
type: 'integer',
|
|
236
|
-
format: 'int64'
|
|
237
|
-
},
|
|
238
|
-
message: {
|
|
239
|
-
type: 'string'
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
required: ['code', 'message'],
|
|
243
|
-
example: {
|
|
244
|
-
code: exception.getCode(),
|
|
245
|
-
message: exception.message
|
|
246
|
-
}
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* @param jsdoc
|
|
252
|
-
* @param {Annotation} annotation
|
|
253
|
-
* @returns {Fragment}
|
|
254
|
-
*/
|
|
255
|
-
static factory(jsdoc, annotation) {
|
|
256
|
-
const { title, description, type } = jsdoc;
|
|
257
|
-
if (title === 'throws') {
|
|
258
|
-
return new Fragment({
|
|
259
|
-
type: FRAGMENT_TYPE_EXCEPTION,
|
|
260
|
-
description,
|
|
261
|
-
value: type ? type.name : FRAGMENT_TYPE_UNKNOWN,
|
|
262
|
-
file: annotation.file,
|
|
263
|
-
start: annotation.start,
|
|
264
|
-
end: annotation.end
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
let elementType = FRAGMENT_TYPE_UNKNOWN;
|
|
269
|
-
const value = _jsYaml2.default.load(description);
|
|
270
|
-
const key = Object.keys(value)[0];
|
|
271
|
-
if (title === 'swagger') {
|
|
272
|
-
elementType = key.startsWith('/') ? FRAGMENT_TYPE_PATH : FRAGMENT_TYPE_DEFINITION;
|
|
273
|
-
}
|
|
274
|
-
return new Fragment({
|
|
275
|
-
type: elementType,
|
|
276
|
-
description,
|
|
277
|
-
value,
|
|
278
|
-
file: annotation.file,
|
|
279
|
-
start: annotation.start,
|
|
280
|
-
end: annotation.end
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
constructor({
|
|
285
|
-
type, description, value, file, start, end
|
|
286
|
-
}) {
|
|
287
|
-
(0, _assert2.default)(type && description && value && file && start && end, 'Fragment require type && description && value && file && start && end');
|
|
288
|
-
(0, _assert2.default)(this.getTypes().includes(type), 'Fragment types not match input');
|
|
289
|
-
this.type = type;
|
|
290
|
-
this.description = description;
|
|
291
|
-
this.value = value;
|
|
292
|
-
this.file = file;
|
|
293
|
-
this.start = start;
|
|
294
|
-
this.end = end;
|
|
295
|
-
this.parent = null;
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
let Annotation = exports.Annotation = class Annotation {
|
|
299
|
-
/**
|
|
300
|
-
* @returns {Array<Fragment>}
|
|
301
|
-
*/
|
|
302
|
-
getFragments() {
|
|
303
|
-
if (this.fragments) {
|
|
304
|
-
return this.fragments;
|
|
305
|
-
}
|
|
306
|
-
//支持两种注解:
|
|
307
|
-
//1. 所有行首必定为 space*
|
|
308
|
-
//2. 所有行首必定不为 space*
|
|
309
|
-
const unwrap = this.value.startsWith('*\n *');
|
|
310
|
-
const { tags: jsDocs = [] } = _doctrine2.default.parse(this.value, { unwrap });
|
|
311
|
-
if (jsDocs.length < 1) {
|
|
312
|
-
return [];
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* @type {Array<Fragment>}
|
|
317
|
-
*/
|
|
318
|
-
const fragments = [];
|
|
319
|
-
jsDocs.filter(jsDoc => jsDoc.title && (jsDoc.title === 'swagger' || jsDoc.title === 'throws') && jsDoc.description).forEach(jsDoc => {
|
|
320
|
-
try {
|
|
321
|
-
fragments.push(Fragment.factory(jsDoc, this));
|
|
322
|
-
} catch (e) {
|
|
323
|
-
this.yamlErrors.push(new YamlParsingException(e).setAnnotation(this));
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
fragments.forEach(fragment => {
|
|
328
|
-
if (fragment.isException()) {
|
|
329
|
-
fragment.setParentFragment(fragments.filter(f => f.isPath())[0]);
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
this.fragments = fragments;
|
|
334
|
-
return fragments;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
toString() {
|
|
338
|
-
return (0, _util.format)('Annotation %s [%s - %s]: %s', this.file, this.start, this.end, this.value);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
getYamlErrors() {
|
|
342
|
-
return this.yamlErrors;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
constructor({
|
|
346
|
-
type, //Block
|
|
347
|
-
value, //Long string
|
|
348
|
-
file, //String
|
|
349
|
-
start,
|
|
350
|
-
end
|
|
351
|
-
}) {
|
|
352
|
-
(0, _assert2.default)(type && type === 'Block', 'Annotation type must be Block');
|
|
353
|
-
(0, _assert2.default)(value && typeof value === 'string', 'Annotation value must be Block');
|
|
354
|
-
(0, _assert2.default)(file, 'Annotation must have file');
|
|
355
|
-
this.value = value;
|
|
356
|
-
this.file = file;
|
|
357
|
-
this.start = start;
|
|
358
|
-
this.end = end;
|
|
359
|
-
this.yamlErrors = [];
|
|
360
|
-
this.fragments = null;
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
let AnnotationsContainer = exports.AnnotationsContainer = class AnnotationsContainer {
|
|
364
|
-
/**
|
|
365
|
-
* @returns {string}
|
|
366
|
-
*/
|
|
367
|
-
getFile() {
|
|
368
|
-
return this.file;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* @returns {boolean}
|
|
373
|
-
*/
|
|
374
|
-
hasAnnotations() {
|
|
375
|
-
return this.annotations.length > 0;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* @returns {Array<Annotation>}
|
|
380
|
-
*/
|
|
381
|
-
getAnnotations() {
|
|
382
|
-
return this.annotations;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* @returns {Array.<Fragment>}
|
|
387
|
-
*/
|
|
388
|
-
collectFragments() {
|
|
389
|
-
if (this.fragments.length > 0) {
|
|
390
|
-
return this.fragments;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
for (const annotation of this.getAnnotations()) {
|
|
394
|
-
this.fragments = this.fragments.concat(annotation.getFragments());
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
return this.fragments;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* @returns {Array}
|
|
402
|
-
*/
|
|
403
|
-
collectYamlErrors() {
|
|
404
|
-
let errors = [];
|
|
405
|
-
for (const annotation of this.getAnnotations()) {
|
|
406
|
-
errors = errors.concat(annotation.getYamlErrors());
|
|
407
|
-
}
|
|
408
|
-
return errors;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
constructor(file, acornComments) {
|
|
412
|
-
(0, _assert2.default)(file && typeof file === 'string', 'Annotations require a file input');
|
|
413
|
-
(0, _assert2.default)(acornComments && Array.isArray(acornComments), `Annotations for ${file} require an array of Acorn comments input`);
|
|
414
|
-
this.file = file;
|
|
415
|
-
//Annotations MUST start with double stars
|
|
416
|
-
this.annotations = acornComments.filter(v => v.type === 'Block' && v.value.startsWith('*\n')).map(c => new Annotation(Object.assign(c, { file })));
|
|
417
|
-
this.fragments = [];
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
/**
|
|
422
|
-
* A Swagger Json document generator
|
|
423
|
-
* Generate document from
|
|
424
|
-
* - JS source code annotations (Parser is Doctrine)
|
|
425
|
-
* - ORM entities (Based on Sequelize)
|
|
426
|
-
* - EvaEngine Exceptions
|
|
427
|
-
*/
|
|
428
|
-
|
|
429
|
-
let ExSwagger = exports.ExSwagger = class ExSwagger {
|
|
430
|
-
/**
|
|
431
|
-
* Get file path array by glob
|
|
432
|
-
* @param path
|
|
433
|
-
* @param options
|
|
434
|
-
* @returns {Promise|Array.<string>}
|
|
435
|
-
*/
|
|
436
|
-
static scanFiles(path, options = {}) {
|
|
437
|
-
return _asyncToGenerator(function* () {
|
|
438
|
-
return new Promise(function (resolve, reject) {
|
|
439
|
-
(0, _glob2.default)(path, options, function (err, files) {
|
|
440
|
-
if (err) {
|
|
441
|
-
return reject(err);
|
|
442
|
-
}
|
|
443
|
-
return resolve(files);
|
|
444
|
-
});
|
|
445
|
-
});
|
|
446
|
-
})();
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**
|
|
450
|
-
* Get annotations from comments
|
|
451
|
-
* An annotation MUST start with double stars
|
|
452
|
-
* @param files {Array.<string>}
|
|
453
|
-
* @returns {Array.<AnnotationsContainer>}
|
|
454
|
-
*/
|
|
455
|
-
static filesToAnnotationsContainers(files) {
|
|
456
|
-
return _asyncToGenerator(function* () {
|
|
457
|
-
const results = [];
|
|
458
|
-
for (const file of files) {
|
|
459
|
-
const comments = [];
|
|
460
|
-
const source = yield _fs2.default.readFileSync(file);
|
|
461
|
-
try {
|
|
462
|
-
acorn.parse(source, {
|
|
463
|
-
ecmaVersion: 9,
|
|
464
|
-
allowImportExportEverywhere: true,
|
|
465
|
-
onComment: comments
|
|
466
|
-
});
|
|
467
|
-
} catch (e) {
|
|
468
|
-
throw new AcornParsingException(`Acorn parsing file ${file} failed`).setPrevError(e);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
results.push(new AnnotationsContainer(file, comments));
|
|
472
|
-
}
|
|
473
|
-
return results;
|
|
474
|
-
})();
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
static modelToSwaggerDefinition(model) {
|
|
478
|
-
const definition = {
|
|
479
|
-
type: 'object',
|
|
480
|
-
properties: {}
|
|
481
|
-
};
|
|
482
|
-
const requires = [];
|
|
483
|
-
Object.keys(model).forEach(columnName => {
|
|
484
|
-
const column = model[columnName];
|
|
485
|
-
const swaggerType = MODEL_TO_FRAGMENT_TYPES_MAPPING[column.type.key];
|
|
486
|
-
const property = {
|
|
487
|
-
type: swaggerType,
|
|
488
|
-
description: column.comment
|
|
489
|
-
};
|
|
490
|
-
if (column.defaultValue) {
|
|
491
|
-
const defaultValueHandler = modelDefaultValueHandlers[swaggerType] ? modelDefaultValueHandlers[swaggerType] : modelDefaultValueHandlers.default;
|
|
492
|
-
property.default = defaultValueHandler(column.defaultValue);
|
|
493
|
-
}
|
|
494
|
-
if (column.allowNull === false) {
|
|
495
|
-
requires.push(columnName);
|
|
496
|
-
}
|
|
497
|
-
definition.properties[columnName] = property;
|
|
498
|
-
});
|
|
499
|
-
definition.required = requires;
|
|
500
|
-
return definition;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
static modelsToSwaggerDefinitions(models, blacklist = []) {
|
|
504
|
-
const definitions = new Map();
|
|
505
|
-
Object.keys(models).forEach(modelName => {
|
|
506
|
-
if (blacklist.includes(modelName)) {
|
|
507
|
-
return true;
|
|
508
|
-
}
|
|
509
|
-
const definition = ExSwagger.modelToSwaggerDefinition(models[modelName].attributes);
|
|
510
|
-
definitions.set(modelName, definition);
|
|
511
|
-
return true;
|
|
512
|
-
});
|
|
513
|
-
return definitions;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
static scanExceptions(path, exceptionInterface = Error) {
|
|
517
|
-
return _asyncToGenerator(function* () {
|
|
518
|
-
const exceptions = {};
|
|
519
|
-
const files = yield ExSwagger.scanFiles(path);
|
|
520
|
-
if (files.length < 1) {
|
|
521
|
-
return exceptions;
|
|
522
|
-
}
|
|
523
|
-
for (const file of files) {
|
|
524
|
-
const exceptionsInFile = require(file); //eslint-disable-line
|
|
525
|
-
Object.keys(exceptionsInFile).forEach(function (exceptionName) {
|
|
526
|
-
const exceptionClass = exceptionsInFile[exceptionName];
|
|
527
|
-
const exception = new exceptionClass(exceptionName); //eslint-disable-line new-cap
|
|
528
|
-
if (exception instanceof exceptionInterface) {
|
|
529
|
-
exceptions[exceptionName] = exception;
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
return exceptions;
|
|
534
|
-
})();
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
exportJson(dist = this.swaggerDocsPath) {
|
|
538
|
-
var _this = this;
|
|
539
|
-
|
|
540
|
-
return _asyncToGenerator(function* () {
|
|
541
|
-
_this.logger.debug('Start export swagger docs by meta %j', _this.getStates());
|
|
542
|
-
const fileGroups = yield Promise.all(_this.sourceFilesPath.map(function (path) {
|
|
543
|
-
return ExSwagger.scanFiles(path);
|
|
544
|
-
}));
|
|
545
|
-
let files = [];
|
|
546
|
-
fileGroups.forEach(function (fileGroup) {
|
|
547
|
-
files = files.concat(fileGroup);
|
|
548
|
-
});
|
|
549
|
-
if (!files || files.length < 1) {
|
|
550
|
-
throw new _exceptions.RuntimeException('No swagger source files found');
|
|
551
|
-
}
|
|
552
|
-
_this.logger.debug('Scanner will scan %s files under %j:', files.length, _this.sourceFilesPath);
|
|
553
|
-
|
|
554
|
-
const annotationsContainers = yield ExSwagger.filesToAnnotationsContainers(files);
|
|
555
|
-
let fragments = [];
|
|
556
|
-
annotationsContainers.forEach(function (annotationsContainer) {
|
|
557
|
-
if (!annotationsContainer.hasAnnotations()) {
|
|
558
|
-
return false;
|
|
559
|
-
}
|
|
560
|
-
const annotationFragments = annotationsContainer.collectFragments();
|
|
561
|
-
fragments = fragments.concat(annotationFragments);
|
|
562
|
-
_this.logger.debug('Scanner found %s annotations and collected %s fragments in file %s', annotationsContainer.getAnnotations().length.toString().padStart(3), annotationFragments.length.toString().padStart(3), annotationsContainer.getFile());
|
|
563
|
-
|
|
564
|
-
const yamlErrors = annotationsContainer.collectYamlErrors();
|
|
565
|
-
yamlErrors.forEach(function (yamlError) {
|
|
566
|
-
return _this.logger.error(yamlError);
|
|
567
|
-
});
|
|
568
|
-
return true;
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
_this.logger.debug('Scanner collected %s fragments in total', fragments.length);
|
|
572
|
-
|
|
573
|
-
const template = _this.swaggerDocsTemplate;
|
|
574
|
-
const exceptions = {};
|
|
575
|
-
for (const exceptionPath of _this.exceptionPaths) {
|
|
576
|
-
_this.logger.debug('Search exception in %s', exceptionPath);
|
|
577
|
-
const exceptionsInFile = yield ExSwagger.scanExceptions(exceptionPath, _this.exceptionInterface);
|
|
578
|
-
Object.assign(exceptions, exceptionsInFile);
|
|
579
|
-
_this.logger.debug('Scanner found %s exceptions', Object.keys(exceptions).length, Object.keys(exceptions));
|
|
580
|
-
}
|
|
581
|
-
const modelDefinitions = _this.models ? ExSwagger.modelsToSwaggerDefinitions(_this.models, _this.modelBlacklist) : new Map();
|
|
582
|
-
const swaggerDocs = ExSwagger.mergeAll(template, fragments, exceptions, modelDefinitions);
|
|
583
|
-
_this.logger.debug('Export to', dist);
|
|
584
|
-
yield _fs2.default.writeFileSync(dist, JSON.stringify(swaggerDocs));
|
|
585
|
-
return swaggerDocs;
|
|
586
|
-
})();
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* @param _template
|
|
591
|
-
* @param {Array<Fragment>} fragments
|
|
592
|
-
* @param exceptions
|
|
593
|
-
* @param modelDefinitions
|
|
594
|
-
* @returns {*}
|
|
595
|
-
*/
|
|
596
|
-
static mergeAll(_template, fragments, exceptions, modelDefinitions) {
|
|
597
|
-
const template = _template;
|
|
598
|
-
fragments.forEach(fragment => (0, _merge2.default)(template, fragment.toSwaggerDoc(exceptions)));
|
|
599
|
-
if (modelDefinitions) {
|
|
600
|
-
modelDefinitions.forEach((definition, modelName) => {
|
|
601
|
-
template.definitions[modelName] = definition;
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
return template;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
getStates() {
|
|
608
|
-
return {
|
|
609
|
-
swaggerTemplate: this.swaggerDocsTemplate,
|
|
610
|
-
modelBlacklist: this.modelBlacklist,
|
|
611
|
-
sourceFilesPath: this.sourceFilesPath,
|
|
612
|
-
exceptionPaths: this.exceptionPaths,
|
|
613
|
-
compileDistPath: this.compileDistPath,
|
|
614
|
-
swaggerUIPath: this.swaggerUIPath,
|
|
615
|
-
swaggerDocsPath: this.swaggerDocsPath
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
getSwaggerUIPath() {
|
|
620
|
-
return this.swaggerUIPath;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
getSwaggerIndexHtml() {
|
|
624
|
-
var _this2 = this;
|
|
625
|
-
|
|
626
|
-
return _asyncToGenerator(function* () {
|
|
627
|
-
const uiPath = _this2.getSwaggerUIPath();
|
|
628
|
-
const content = yield _fs2.default.readFileSync(`${uiPath}/index.html`);
|
|
629
|
-
return content.toString().replace('https://petstore.swagger.io/v2/swagger.json', _this2.swaggerDocsPath.replace(_this2.compileDistPath, ''));
|
|
630
|
-
})();
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
getCompileDistPath() {
|
|
634
|
-
return this.compileDistPath;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
constructor({
|
|
638
|
-
sourceRootPath,
|
|
639
|
-
compileDistPath,
|
|
640
|
-
models,
|
|
641
|
-
modelBlacklist = [],
|
|
642
|
-
swaggerDocsTemplate,
|
|
643
|
-
logger,
|
|
644
|
-
swaggerUIPath,
|
|
645
|
-
swaggerDocsPath = `${compileDistPath}/docs.json`,
|
|
646
|
-
sourceFilesPath = `${sourceRootPath}/**/*.js`,
|
|
647
|
-
exceptionInterface = _exceptions.StandardException,
|
|
648
|
-
extraSourcePaths = [`${__dirname}/../utils/**/*.js`],
|
|
649
|
-
exceptionPaths
|
|
650
|
-
}) {
|
|
651
|
-
this.logger = logger || {
|
|
652
|
-
debug: () => {},
|
|
653
|
-
warn: () => {},
|
|
654
|
-
error: () => {}
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
if (!swaggerDocsTemplate) {
|
|
658
|
-
throw new _exceptions.RuntimeException('No swagger docs template input');
|
|
659
|
-
}
|
|
660
|
-
this.swaggerDocsTemplate = swaggerDocsTemplate;
|
|
661
|
-
if (models && !(models instanceof _entities2.default)) {
|
|
662
|
-
throw new _exceptions.RuntimeException('Input models must instance of engine.Entities');
|
|
663
|
-
}
|
|
664
|
-
this.models = models ? models.getAll() : null;
|
|
665
|
-
this.modelBlacklist = modelBlacklist;
|
|
666
|
-
|
|
667
|
-
this.sourceFilesPath = Array.isArray(sourceFilesPath) ? extraSourcePaths.concat(sourceFilesPath) : extraSourcePaths.concat([sourceFilesPath]);
|
|
668
|
-
this.exceptionPaths = exceptionPaths ? [`${__dirname}/../exceptions`].concat(exceptionPaths) : [`${__dirname}/../exceptions`];
|
|
669
|
-
this.exceptionInterface = exceptionInterface;
|
|
670
|
-
this.compileDistPath = compileDistPath;
|
|
671
|
-
if (swaggerUIPath) {
|
|
672
|
-
this.swaggerUIPath = swaggerUIPath;
|
|
673
|
-
} else {
|
|
674
|
-
this.swaggerUIPath = `${__dirname}/../../node_modules/swagger-ui-dist`;
|
|
675
|
-
try {
|
|
676
|
-
_fs2.default.accessSync(this.swaggerUIPath, _fs2.default.F_OK);
|
|
677
|
-
} catch (e) {
|
|
678
|
-
this.swaggerUIPath = `${__dirname}/../../../swagger-ui-dist`; //For NPM v3.x
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
this.swaggerDocsPath = swaggerDocsPath;
|
|
682
|
-
}
|
|
683
|
-
};
|
|
684
|
-
//# sourceMappingURL=index.js.map
|