ee-core 1.2.8-beta.3 → 1.2.9-bate.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 (42) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +2 -2
  3. package/bin/tools.js +22 -22
  4. package/config/config.default.js +255 -250
  5. package/core/index.js +12 -12
  6. package/core/lib/ee.js +209 -209
  7. package/core/lib/loader/context_loader.js +105 -105
  8. package/core/lib/loader/ee_loader.js +451 -451
  9. package/core/lib/loader/file_loader.js +262 -262
  10. package/core/lib/loader/mixin/config.js +138 -138
  11. package/core/lib/loader/mixin/controller.js +123 -123
  12. package/core/lib/loader/mixin/service.js +29 -29
  13. package/core/lib/utils/base_context_class.js +34 -34
  14. package/core/lib/utils/index.js +100 -100
  15. package/core/lib/utils/sequencify.js +59 -59
  16. package/core/lib/utils/timing.js +77 -77
  17. package/index.js +49 -49
  18. package/lib/appLoader.js +45 -45
  19. package/lib/application.js +80 -80
  20. package/lib/baseApp.js +118 -118
  21. package/lib/constant.js +28 -28
  22. package/lib/eeApp.js +326 -326
  23. package/lib/helper.js +51 -51
  24. package/lib/httpclient.js +136 -136
  25. package/lib/logger.js +46 -46
  26. package/lib/socket/httpServer.js +134 -102
  27. package/lib/socket/io.js +23 -23
  28. package/lib/socket/ipcServer.js +128 -128
  29. package/lib/socket/socketClient.js +50 -50
  30. package/lib/socket/socketServer.js +76 -76
  31. package/lib/socket/start.js +22 -22
  32. package/lib/storage/index.js +33 -33
  33. package/lib/storage/lowdbStorage.js +98 -98
  34. package/lib/storage/sqliteStorage.js +58 -58
  35. package/package.json +45 -45
  36. package/resource/loading.html +21 -21
  37. package/resource/view_example.html +21 -21
  38. package/tools/codeCompress.js +204 -204
  39. package/tools/replaceDist.js +76 -76
  40. package/utils/common.js +90 -90
  41. package/utils/index.js +207 -207
  42. package/utils/wrap.js +37 -37
@@ -1,262 +1,262 @@
1
- 'use strict';
2
-
3
- const assert = require('assert');
4
- const fs = require('fs');
5
- const debug = require('debug')('ee-core:fileLoader');
6
- const path = require('path');
7
- const globby = require('globby');
8
- const is = require('is-type-of');
9
- const deprecate = require('depd')('ee');
10
- const utils = require('../utils');
11
- const FULLPATH = Symbol('EE_LOADER_ITEM_FULLPATH');
12
- const EXPORTS = Symbol('EE_LOADER_ITEM_EXPORTS');
13
-
14
- const defaults = {
15
- directory: null,
16
- target: null,
17
- match: undefined,
18
- ignore: undefined,
19
- lowercaseFirst: false,
20
- caseStyle: 'camel',
21
- initializer: null,
22
- call: true,
23
- override: false,
24
- inject: undefined,
25
- filter: null,
26
- };
27
-
28
- /**
29
- * Load files from directory to target object.
30
- * @since 1.0.0
31
- */
32
- class FileLoader {
33
-
34
- /**
35
- * @class
36
- * @param {Object} options - options
37
- * @param {String|Array} options.directory - directories to be loaded
38
- * @param {Object} options.target - attach the target object from loaded files
39
- * @param {String} options.match - match the files when load, support glob, default to all js files
40
- * @param {String} options.ignore - ignore the files when load, support glob
41
- * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path`
42
- * @param {Boolean} options.call - determine whether invoke when exports is function
43
- * @param {Boolean} options.override - determine whether override the property when get the same name
44
- * @param {Object} options.inject - an object that be the argument when invoke the function
45
- * @param {Function} options.filter - a function that filter the exports which can be loaded
46
- * @param {String|Function} options.caseStyle - set property's case when converting a filepath to property list.
47
- */
48
- constructor(options) {
49
- assert(options.directory, 'options.directory is required');
50
- assert(options.target, 'options.target is required');
51
- this.options = Object.assign({}, defaults, options);
52
-
53
- // compatible old options _lowercaseFirst_
54
- if (this.options.lowercaseFirst === true) {
55
- deprecate('lowercaseFirst is deprecated, use caseStyle instead');
56
- this.options.caseStyle = 'lower';
57
- }
58
- }
59
-
60
- /**
61
- * attach items to target object. Mapping the directory to properties.
62
- * `app/controller/group/repository.js` => `target.group.repository`
63
- * @return {Object} target
64
- * @since 1.0.0
65
- */
66
- load() {
67
- const items = this.parse();
68
- //console.log('FileLoader load items:', items);
69
- const target = this.options.target;
70
- for (const item of items) {
71
- // item { properties: [ 'a', 'b', 'c'], exports }
72
- // => target.a.b.c = exports
73
- item.properties.reduce((target, property, index) => {
74
- let obj;
75
- const properties = item.properties.slice(0, index + 1).join('.');
76
- if (index === item.properties.length - 1) {
77
- if (property in target) {
78
- if (!this.options.override) throw new Error(`can't overwrite property '${properties}' from ${target[property][FULLPATH]} by ${item.fullpath}`);
79
- }
80
- obj = item.exports;
81
- if (obj && !is.primitive(obj)) {
82
- obj[FULLPATH] = item.fullpath;
83
- obj[EXPORTS] = true;
84
- }
85
- } else {
86
- obj = target[property] || {};
87
- }
88
-
89
- target[property] = obj;
90
- debug('loaded %s', properties);
91
- return obj;
92
- }, target);
93
- }
94
-
95
- return target;
96
- }
97
-
98
- /**
99
- * Parse files from given directories, then return an items list, each item contains properties and exports.
100
- *
101
- * For example, parse `app/controller/group/repository.js`
102
- *
103
- * ```
104
- * module.exports = app => {
105
- * return class RepositoryController extends app.Controller {};
106
- * }
107
- * ```
108
- *
109
- * It returns a item
110
- *
111
- * ```
112
- * {
113
- * properties: [ 'group', 'repository' ],
114
- * exports: app => { ... },
115
- * }
116
- * ```
117
- *
118
- * `Properties` is an array that contains the directory of a filepath.
119
- *
120
- * `Exports` depends on type, if exports is a function, it will be called. if initializer is specified, it will be called with exports for customizing.
121
- * @return {Array} items
122
- * @since 1.0.0
123
- */
124
- parse() {
125
- let files = this.options.match;
126
-
127
- if (!files) {
128
- files = (process.env.EE_TYPESCRIPT === 'true' && utils.extensions['.ts'])
129
- ? [ '**/*.(js|ts)', '!**/*.d.ts' ]
130
- : [ '**/*.js' ];
131
- } else {
132
- files = Array.isArray(files) ? files : [ files ];
133
- }
134
-
135
- let ignore = this.options.ignore;
136
- if (ignore) {
137
- ignore = Array.isArray(ignore) ? ignore : [ ignore ];
138
- ignore = ignore.filter(f => !!f).map(f => '!' + f);
139
- files = files.concat(ignore);
140
- }
141
-
142
- let directories = this.options.directory;
143
- if (!Array.isArray(directories)) {
144
- directories = [ directories ];
145
- }
146
-
147
- const filter = is.function(this.options.filter) ? this.options.filter : null;
148
- const items = [];
149
- debug('parsing %j', directories);
150
-
151
- for (const directory of directories) {
152
- const filepaths = globby.sync(files, { cwd: directory });
153
-
154
- for (const filepath of filepaths) {
155
- const fullpath = path.join(directory, filepath);
156
- if (!fs.statSync(fullpath).isFile()) continue;
157
- // get properties
158
- // app/service/foo/bar.js => [ 'foo', 'bar' ]
159
- const properties = getProperties(filepath, this.options);
160
- // app/service/foo/bar.js => service.foo.bar
161
- const pathName = directory.split(/[/\\]/).slice(-1) + '.' + properties.join('.');
162
- // get exports from the file
163
- const exports = getExports(fullpath, this.options, pathName);
164
-
165
- // ignore exports when it's null or false returned by filter function
166
- if (exports == null || (filter && filter(exports) === false)) continue;
167
-
168
- // set properties of class
169
- if (is.class(exports)) {
170
- exports.prototype.pathName = pathName;
171
- exports.prototype.fullPath = fullpath;
172
- }
173
- //console.log('lll---------------pathName:', pathName);
174
- items.push({ fullpath, properties, exports });
175
- debug('parse %s, properties %j, export %O', fullpath, properties, exports);
176
- }
177
- }
178
-
179
- return items;
180
- }
181
-
182
- }
183
-
184
- module.exports = FileLoader;
185
- module.exports.EXPORTS = EXPORTS;
186
- module.exports.FULLPATH = FULLPATH;
187
-
188
- // convert file path to an array of properties
189
- // a/b/c.js => ['a', 'b', 'c']
190
- function getProperties(filepath, { caseStyle }) {
191
- // if caseStyle is function, return the result of function
192
- if (is.function(caseStyle)) {
193
- const result = caseStyle(filepath);
194
- assert(is.array(result), `caseStyle expect an array, but got ${result}`);
195
- return result;
196
- }
197
- // use default camelize
198
- return defaultCamelize(filepath, caseStyle);
199
- }
200
-
201
- // Get exports from filepath
202
- // If exports is null/undefined, it will be ignored
203
- function getExports(fullpath, { initializer, call, inject }, pathName) {
204
- let exports = utils.loadFile(fullpath);
205
- // process exports as you like
206
- if (initializer) {
207
- exports = initializer(exports, { path: fullpath, pathName });
208
- }
209
-
210
- // return exports when it's a class or generator
211
- //
212
- // module.exports = class Service {};
213
- // or
214
- // module.exports = function*() {}
215
- if (is.class(exports) || is.generatorFunction(exports) || is.asyncFunction(exports)) {
216
- return exports;
217
- }
218
-
219
- // return exports after call when it's a function
220
- //
221
- // module.exports = function(app) {
222
- // return {};
223
- // }
224
- if (call && is.function(exports)) {
225
- exports = exports(inject);
226
- if (exports != null) {
227
- return exports;
228
- }
229
- }
230
-
231
- // return exports what is
232
- return exports;
233
- }
234
-
235
- function defaultCamelize(filepath, caseStyle) {
236
- const properties = filepath.substring(0, filepath.lastIndexOf('.')).split('/');
237
- return properties.map(property => {
238
- if (!/^[a-z][a-z0-9_-]*$/i.test(property)) {
239
- throw new Error(`${property} is not match 'a-z0-9_-' in ${filepath}`);
240
- }
241
-
242
- // use default camelize, will capitalize the first letter
243
- // foo_bar.js > FooBar
244
- // fooBar.js > FooBar
245
- // FooBar.js > FooBar
246
- // FooBar.js > FooBar
247
- // FooBar.js > fooBar (if lowercaseFirst is true)
248
- property = property.replace(/[_-][a-z]/ig, s => s.substring(1).toUpperCase());
249
- let first = property[0];
250
- switch (caseStyle) {
251
- case 'lower':
252
- first = first.toLowerCase();
253
- break;
254
- case 'upper':
255
- first = first.toUpperCase();
256
- break;
257
- case 'camel':
258
- default:
259
- }
260
- return first + property.substring(1);
261
- });
262
- }
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const fs = require('fs');
5
+ const debug = require('debug')('ee-core:fileLoader');
6
+ const path = require('path');
7
+ const globby = require('globby');
8
+ const is = require('is-type-of');
9
+ const deprecate = require('depd')('ee');
10
+ const utils = require('../utils');
11
+ const FULLPATH = Symbol('EE_LOADER_ITEM_FULLPATH');
12
+ const EXPORTS = Symbol('EE_LOADER_ITEM_EXPORTS');
13
+
14
+ const defaults = {
15
+ directory: null,
16
+ target: null,
17
+ match: undefined,
18
+ ignore: undefined,
19
+ lowercaseFirst: false,
20
+ caseStyle: 'camel',
21
+ initializer: null,
22
+ call: true,
23
+ override: false,
24
+ inject: undefined,
25
+ filter: null,
26
+ };
27
+
28
+ /**
29
+ * Load files from directory to target object.
30
+ * @since 1.0.0
31
+ */
32
+ class FileLoader {
33
+
34
+ /**
35
+ * @class
36
+ * @param {Object} options - options
37
+ * @param {String|Array} options.directory - directories to be loaded
38
+ * @param {Object} options.target - attach the target object from loaded files
39
+ * @param {String} options.match - match the files when load, support glob, default to all js files
40
+ * @param {String} options.ignore - ignore the files when load, support glob
41
+ * @param {Function} options.initializer - custom file exports, receive two parameters, first is the inject object(if not js file, will be content buffer), second is an `options` object that contain `path`
42
+ * @param {Boolean} options.call - determine whether invoke when exports is function
43
+ * @param {Boolean} options.override - determine whether override the property when get the same name
44
+ * @param {Object} options.inject - an object that be the argument when invoke the function
45
+ * @param {Function} options.filter - a function that filter the exports which can be loaded
46
+ * @param {String|Function} options.caseStyle - set property's case when converting a filepath to property list.
47
+ */
48
+ constructor(options) {
49
+ assert(options.directory, 'options.directory is required');
50
+ assert(options.target, 'options.target is required');
51
+ this.options = Object.assign({}, defaults, options);
52
+
53
+ // compatible old options _lowercaseFirst_
54
+ if (this.options.lowercaseFirst === true) {
55
+ deprecate('lowercaseFirst is deprecated, use caseStyle instead');
56
+ this.options.caseStyle = 'lower';
57
+ }
58
+ }
59
+
60
+ /**
61
+ * attach items to target object. Mapping the directory to properties.
62
+ * `app/controller/group/repository.js` => `target.group.repository`
63
+ * @return {Object} target
64
+ * @since 1.0.0
65
+ */
66
+ load() {
67
+ const items = this.parse();
68
+ //console.log('FileLoader load items:', items);
69
+ const target = this.options.target;
70
+ for (const item of items) {
71
+ // item { properties: [ 'a', 'b', 'c'], exports }
72
+ // => target.a.b.c = exports
73
+ item.properties.reduce((target, property, index) => {
74
+ let obj;
75
+ const properties = item.properties.slice(0, index + 1).join('.');
76
+ if (index === item.properties.length - 1) {
77
+ if (property in target) {
78
+ if (!this.options.override) throw new Error(`can't overwrite property '${properties}' from ${target[property][FULLPATH]} by ${item.fullpath}`);
79
+ }
80
+ obj = item.exports;
81
+ if (obj && !is.primitive(obj)) {
82
+ obj[FULLPATH] = item.fullpath;
83
+ obj[EXPORTS] = true;
84
+ }
85
+ } else {
86
+ obj = target[property] || {};
87
+ }
88
+
89
+ target[property] = obj;
90
+ debug('loaded %s', properties);
91
+ return obj;
92
+ }, target);
93
+ }
94
+
95
+ return target;
96
+ }
97
+
98
+ /**
99
+ * Parse files from given directories, then return an items list, each item contains properties and exports.
100
+ *
101
+ * For example, parse `app/controller/group/repository.js`
102
+ *
103
+ * ```
104
+ * module.exports = app => {
105
+ * return class RepositoryController extends app.Controller {};
106
+ * }
107
+ * ```
108
+ *
109
+ * It returns a item
110
+ *
111
+ * ```
112
+ * {
113
+ * properties: [ 'group', 'repository' ],
114
+ * exports: app => { ... },
115
+ * }
116
+ * ```
117
+ *
118
+ * `Properties` is an array that contains the directory of a filepath.
119
+ *
120
+ * `Exports` depends on type, if exports is a function, it will be called. if initializer is specified, it will be called with exports for customizing.
121
+ * @return {Array} items
122
+ * @since 1.0.0
123
+ */
124
+ parse() {
125
+ let files = this.options.match;
126
+
127
+ if (!files) {
128
+ files = (process.env.EE_TYPESCRIPT === 'true' && utils.extensions['.ts'])
129
+ ? [ '**/*.(js|ts)', '!**/*.d.ts' ]
130
+ : [ '**/*.js' ];
131
+ } else {
132
+ files = Array.isArray(files) ? files : [ files ];
133
+ }
134
+
135
+ let ignore = this.options.ignore;
136
+ if (ignore) {
137
+ ignore = Array.isArray(ignore) ? ignore : [ ignore ];
138
+ ignore = ignore.filter(f => !!f).map(f => '!' + f);
139
+ files = files.concat(ignore);
140
+ }
141
+
142
+ let directories = this.options.directory;
143
+ if (!Array.isArray(directories)) {
144
+ directories = [ directories ];
145
+ }
146
+
147
+ const filter = is.function(this.options.filter) ? this.options.filter : null;
148
+ const items = [];
149
+ debug('parsing %j', directories);
150
+
151
+ for (const directory of directories) {
152
+ const filepaths = globby.sync(files, { cwd: directory });
153
+
154
+ for (const filepath of filepaths) {
155
+ const fullpath = path.join(directory, filepath);
156
+ if (!fs.statSync(fullpath).isFile()) continue;
157
+ // get properties
158
+ // app/service/foo/bar.js => [ 'foo', 'bar' ]
159
+ const properties = getProperties(filepath, this.options);
160
+ // app/service/foo/bar.js => service.foo.bar
161
+ const pathName = directory.split(/[/\\]/).slice(-1) + '.' + properties.join('.');
162
+ // get exports from the file
163
+ const exports = getExports(fullpath, this.options, pathName);
164
+
165
+ // ignore exports when it's null or false returned by filter function
166
+ if (exports == null || (filter && filter(exports) === false)) continue;
167
+
168
+ // set properties of class
169
+ if (is.class(exports)) {
170
+ exports.prototype.pathName = pathName;
171
+ exports.prototype.fullPath = fullpath;
172
+ }
173
+ //console.log('lll---------------pathName:', pathName);
174
+ items.push({ fullpath, properties, exports });
175
+ debug('parse %s, properties %j, export %O', fullpath, properties, exports);
176
+ }
177
+ }
178
+
179
+ return items;
180
+ }
181
+
182
+ }
183
+
184
+ module.exports = FileLoader;
185
+ module.exports.EXPORTS = EXPORTS;
186
+ module.exports.FULLPATH = FULLPATH;
187
+
188
+ // convert file path to an array of properties
189
+ // a/b/c.js => ['a', 'b', 'c']
190
+ function getProperties(filepath, { caseStyle }) {
191
+ // if caseStyle is function, return the result of function
192
+ if (is.function(caseStyle)) {
193
+ const result = caseStyle(filepath);
194
+ assert(is.array(result), `caseStyle expect an array, but got ${result}`);
195
+ return result;
196
+ }
197
+ // use default camelize
198
+ return defaultCamelize(filepath, caseStyle);
199
+ }
200
+
201
+ // Get exports from filepath
202
+ // If exports is null/undefined, it will be ignored
203
+ function getExports(fullpath, { initializer, call, inject }, pathName) {
204
+ let exports = utils.loadFile(fullpath);
205
+ // process exports as you like
206
+ if (initializer) {
207
+ exports = initializer(exports, { path: fullpath, pathName });
208
+ }
209
+
210
+ // return exports when it's a class or generator
211
+ //
212
+ // module.exports = class Service {};
213
+ // or
214
+ // module.exports = function*() {}
215
+ if (is.class(exports) || is.generatorFunction(exports) || is.asyncFunction(exports)) {
216
+ return exports;
217
+ }
218
+
219
+ // return exports after call when it's a function
220
+ //
221
+ // module.exports = function(app) {
222
+ // return {};
223
+ // }
224
+ if (call && is.function(exports)) {
225
+ exports = exports(inject);
226
+ if (exports != null) {
227
+ return exports;
228
+ }
229
+ }
230
+
231
+ // return exports what is
232
+ return exports;
233
+ }
234
+
235
+ function defaultCamelize(filepath, caseStyle) {
236
+ const properties = filepath.substring(0, filepath.lastIndexOf('.')).split('/');
237
+ return properties.map(property => {
238
+ if (!/^[a-z][a-z0-9_-]*$/i.test(property)) {
239
+ throw new Error(`${property} is not match 'a-z0-9_-' in ${filepath}`);
240
+ }
241
+
242
+ // use default camelize, will capitalize the first letter
243
+ // foo_bar.js > FooBar
244
+ // fooBar.js > FooBar
245
+ // FooBar.js > FooBar
246
+ // FooBar.js > FooBar
247
+ // FooBar.js > fooBar (if lowercaseFirst is true)
248
+ property = property.replace(/[_-][a-z]/ig, s => s.substring(1).toUpperCase());
249
+ let first = property[0];
250
+ switch (caseStyle) {
251
+ case 'lower':
252
+ first = first.toLowerCase();
253
+ break;
254
+ case 'upper':
255
+ first = first.toUpperCase();
256
+ break;
257
+ case 'camel':
258
+ default:
259
+ }
260
+ return first + property.substring(1);
261
+ });
262
+ }