ee-core 1.5.0 → 1.5.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 (41) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +2 -2
  3. package/addon/window/index.js +91 -91
  4. package/bin/tools.js +17 -17
  5. package/config/config.default.js +280 -276
  6. package/core/index.js +12 -12
  7. package/core/lib/ee.js +218 -218
  8. package/core/lib/loader/context_loader.js +106 -106
  9. package/core/lib/loader/ee_loader.js +457 -457
  10. package/core/lib/loader/file_loader.js +325 -325
  11. package/core/lib/loader/mixin/addon.js +32 -32
  12. package/core/lib/loader/mixin/config.js +135 -135
  13. package/core/lib/loader/mixin/controller.js +124 -124
  14. package/core/lib/loader/mixin/service.js +28 -28
  15. package/core/lib/utils/base_context_class.js +34 -34
  16. package/core/lib/utils/index.js +127 -127
  17. package/core/lib/utils/sequencify.js +59 -59
  18. package/core/lib/utils/timing.js +77 -77
  19. package/index.js +49 -49
  20. package/lib/appLoader.js +53 -53
  21. package/lib/application.js +84 -84
  22. package/lib/baseApp.js +131 -131
  23. package/lib/constant.js +9 -9
  24. package/lib/eeApp.js +359 -335
  25. package/lib/httpclient.js +136 -136
  26. package/lib/logger.js +46 -46
  27. package/lib/socket/httpServer.js +142 -142
  28. package/lib/socket/io.js +23 -23
  29. package/lib/socket/ipcServer.js +108 -108
  30. package/lib/socket/socketClient.js +50 -50
  31. package/lib/socket/socketServer.js +76 -76
  32. package/lib/socket/start.js +22 -22
  33. package/lib/storage/index.js +33 -33
  34. package/lib/storage/lowdbStorage.js +98 -98
  35. package/lib/storage/sqliteStorage.js +127 -127
  36. package/package.json +45 -45
  37. package/tools/encrypt.js +274 -274
  38. package/tools/replaceDist.js +61 -61
  39. package/utils/common.js +90 -90
  40. package/utils/index.js +246 -246
  41. package/utils/wrap.js +37 -37
@@ -1,457 +1,457 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const assert = require('assert');
6
- const is = require('is-type-of');
7
- const debug = require('debug')('ee-core:EeLoader');
8
- const FileLoader = require('./file_loader');
9
- const ContextLoader = require('./context_loader');
10
- const utility = require('utility');
11
- const utils = require('../utils');
12
- const Timing = require('../utils/timing');
13
-
14
- const REQUIRE_COUNT = Symbol('EeLoader#requireCount');
15
-
16
- class EeLoader {
17
-
18
- /**
19
- * @class
20
- * @param {Object} options - options
21
- * @param {String} options.baseDir - the directory of application
22
- * @param {EeCore} options.app - Application instance
23
- * @param {Logger} options.logger - logger
24
- * @since 1.0.0
25
- */
26
- constructor(options) {
27
- this.options = options;
28
- assert(fs.existsSync(this.options.baseDir), `${this.options.baseDir} not exists`);
29
- assert(this.options.app, 'options.app is required');
30
- assert(this.options.logger, 'options.logger is required');
31
-
32
- this.app = this.options.app;
33
- this.timing = this.app.timing || new Timing();
34
- this[REQUIRE_COUNT] = 0;
35
-
36
- /**
37
- * @member {Object} EeLoader#pkg
38
- * @see {@link AppInfo#pkg}
39
- * @since 1.0.0
40
- */
41
- this.pkg = this.getPkg();
42
-
43
- /**
44
- * Framework directories
45
- *
46
- * @member {Array} EeLoader#EePaths
47
- * @see EeLoader#getEePaths
48
- * @since 1.0.0
49
- */
50
- this.EePaths = this.getEePaths();
51
- debug('Loaded EePaths %j', this.EePaths);
52
-
53
- /**
54
- * @member {String} EeLoader#serverEnv
55
- * @see AppInfo#env
56
- * @since 1.0.0
57
- */
58
- this.serverEnv = this.getServerEnv();
59
- debug('Loaded serverEnv %j', this.serverEnv);
60
-
61
- /**
62
- * @member {AppInfo} EeLoader#appInfo
63
- * @since 1.0.0
64
- */
65
- this.appInfo = this.getAppInfo();
66
-
67
- /**
68
- * @member {String} EeLoader#serverScope
69
- * @see AppInfo#serverScope
70
- */
71
- this.serverScope = options.serverScope !== undefined
72
- ? options.serverScope
73
- : this.getServerScope();
74
- }
75
-
76
- /**
77
- * Get {@link AppInfo#env}
78
- * @return {String} env
79
- * @see AppInfo#env
80
- * @private
81
- * @since 1.0.0
82
- */
83
- getServerEnv() {
84
- let serverEnv = this.options.env;
85
-
86
- const envPath = path.join(this.options.baseDir, 'config/env');
87
- if (!serverEnv && fs.existsSync(envPath)) {
88
- serverEnv = fs.readFileSync(envPath, 'utf8').trim();
89
- }
90
-
91
- if (!serverEnv) {
92
- serverEnv = process.env.EE_SERVER_ENV;
93
- }
94
-
95
- if (!serverEnv) {
96
- if (process.env.NODE_ENV === 'test') {
97
- serverEnv = 'unittest';
98
- } else if (process.env.NODE_ENV === 'production') {
99
- serverEnv = 'prod';
100
- } else {
101
- serverEnv = 'local';
102
- }
103
- } else {
104
- serverEnv = serverEnv.trim();
105
- }
106
-
107
- return serverEnv;
108
- }
109
-
110
- /**
111
- * Get {@link AppInfo#scope}
112
- * @return {String} serverScope
113
- * @private
114
- */
115
- getServerScope() {
116
- return process.env.EE_SERVER_SCOPE || '';
117
- }
118
-
119
- /**
120
- * Get {@link AppInfo#name}
121
- * @return {String} appname
122
- * @private
123
- * @since 1.0.0
124
- */
125
- getAppname() {
126
- if (this.pkg.name) {
127
- debug('Loaded appname(%s) from package.json', this.pkg.name);
128
- return this.pkg.name;
129
- }
130
-
131
- throw new Error(`name is required from ${pkg}`);
132
- }
133
-
134
- /**
135
- * Get home directory
136
- * @return {String} home directory
137
- * @since 3.4.0
138
- */
139
- getHomedir() {
140
- return this.options.homeDir;
141
- }
142
-
143
- /**
144
- * Get app info
145
- * @return {AppInfo} appInfo
146
- * @since 1.0.0
147
- */
148
- getAppInfo() {
149
- const env = this.serverEnv;
150
-
151
- /**
152
- * Meta information of the application
153
- * @class AppInfo
154
- */
155
- return {
156
- /**
157
- * The name of the application, retrieve from the name property in `package.json`.
158
- * @member {String} AppInfo#name
159
- */
160
- name: this.getAppname(),
161
-
162
- /**
163
- * The current directory, where the application code is.
164
- * @member {String} AppInfo#baseDir
165
- */
166
- baseDir: this.options.baseDir,
167
-
168
- /**
169
- * The environment of the application, **it's not NODE_ENV**
170
- *
171
- * 1. from `$baseDir/config/env`
172
- * 2. from EE_SERVER_ENV
173
- * 3. from NODE_ENV
174
- *
175
- * env | description
176
- * --- | ---
177
- * test | system integration testing
178
- * prod | production
179
- * local | local on your own computer
180
- * unittest | unit test
181
- *
182
- * @member {String} AppInfo#env
183
- * @see https://Eejs.org/zh-cn/basics/env.html
184
- */
185
- env: env,
186
-
187
- /**
188
- * @member {String} AppInfo#scope
189
- */
190
- scope: this.serverScope,
191
-
192
- /**
193
- * The use directory, same as `process.env.HOME`
194
- * @member {String} AppInfo#HOME
195
- */
196
- home: this.getHomedir(),
197
-
198
- /**
199
- * The directory whether is homeDir or appUserData depend on env.
200
- * @member {String} AppInfo#root
201
- */
202
- root: env === 'local' || env === 'unittest' ? this.getHomedir() : this.options.appUserData,
203
-
204
- /**
205
- * electron application data dir
206
- * @member {String} AppInfo#appUserDataDir
207
- */
208
- appUserDataDir: this.options.appUserData,
209
-
210
- /**
211
- * system user home dir
212
- * @member {String} AppInfo#userHome
213
- */
214
- userHome: this.options.userHome,
215
-
216
- /**
217
- * application version
218
- * @member {String} AppInfo#appVersion
219
- */
220
- appVersion: this.options.appVersion,
221
-
222
- /**
223
- * application package status
224
- * @member {boolean} AppInfo#isPackaged
225
- */
226
- isPackaged: this.options.isPackaged,
227
-
228
- /**
229
- * application exec file dir
230
- * @member {String} AppInfo#execDir
231
- */
232
- execDir: this.options.execDir
233
- };
234
- }
235
-
236
- /**
237
- * Get {@link EeLoader#EePaths}
238
- * @return {Array} framework directories
239
- * @see {@link EeLoader#EePaths}
240
- * @private
241
- * @since 1.0.0
242
- */
243
- getEePaths() {
244
- // avoid require recursively
245
- const EePaths = [];
246
- EePaths.push(this.app[Symbol.for('ee#eePath')]);
247
-
248
- return EePaths;
249
- }
250
-
251
- // Low Level API
252
-
253
- /**
254
- * Load single file, will invoke when export is function
255
- *
256
- * @param {String} filepath - fullpath
257
- * @param {Array} inject - pass rest arguments into the function when invoke
258
- * @return {Object} exports
259
- * @example
260
- * ```js
261
- * app.loader.loadFile(path.join(app.options.baseDir, 'config/router.js'));
262
- * ```
263
- * @since 1.0.0
264
- */
265
- loadFile(filepath, ...inject) {
266
- filepath = filepath && this.resolveModule(filepath);
267
- if (!filepath) {
268
- return null;
269
- }
270
-
271
- // function(arg1, args, ...) {}
272
- if (inject.length === 0) inject = [ this.app ];
273
-
274
- let ret = this.requireFile(filepath);
275
- if (is.function(ret) && !is.class(ret) && !utils.isBytecodeClass(ret)) {
276
- ret = ret(...inject);
277
- }
278
- return ret;
279
- }
280
-
281
- /**
282
- * @param {String} filepath - fullpath
283
- * @return {Object} exports
284
- * @private
285
- */
286
- requireFile(filepath) {
287
- const timingKey = `Require(${this[REQUIRE_COUNT]++}) ${utils.getResolvedFilename(filepath, this.options.baseDir)}`;
288
- this.timing.start(timingKey);
289
- const ret = utils.loadFile(filepath);
290
- this.timing.end(timingKey);
291
- return ret;
292
- }
293
-
294
- /**
295
- * Get all loadUnit
296
- *
297
- * loadUnit is a directory that can be loaded by EeLoader, it has the same structure.
298
- * loadUnit has a path and a type(app, framework, plugin).
299
- *
300
- * The order of the loadUnits:
301
- *
302
- * 1. plugin
303
- * 2. framework
304
- * 3. app
305
- *
306
- * @return {Array} loadUnits
307
- * @since 1.0.0
308
- */
309
- getLoadUnits() {
310
- if (this.dirs) {
311
- return this.dirs;
312
- }
313
-
314
- const dirs = this.dirs = [];
315
-
316
- if (this.orderPlugins) {
317
- for (const plugin of this.orderPlugins) {
318
- dirs.push({
319
- path: plugin.path,
320
- type: 'plugin',
321
- });
322
- }
323
- }
324
-
325
- // framework or Ee path
326
- for (const EePath of this.EePaths) {
327
- dirs.push({
328
- path: EePath,
329
- type: 'framework',
330
- });
331
- }
332
-
333
- // application
334
- dirs.push({
335
- path: this.options.baseDir,
336
- type: 'app',
337
- });
338
-
339
- debug('Loaded dirs %j', dirs);
340
- return dirs;
341
- }
342
-
343
- /**
344
- * Load files using {@link FileLoader}, inject to {@link Application}
345
- * @param {String|Array} directory - see {@link FileLoader}
346
- * @param {String} property - see {@link FileLoader}
347
- * @param {Object} opt - see {@link FileLoader}
348
- * @since 1.0.0
349
- */
350
- loadToApp(directory, property, opt) {
351
- const target = this.app[property] = {};
352
- opt = Object.assign({}, {
353
- directory,
354
- target,
355
- inject: this.app,
356
- }, opt);
357
-
358
- const timingKey = `Load "${String(property)}" to Application`;
359
- this.timing.start(timingKey);
360
- new FileLoader(opt).load();
361
- this.timing.end(timingKey);
362
- }
363
-
364
- /**
365
- * Load files using {@link ContextLoader}
366
- * @param {String|Array} directory - see {@link ContextLoader}
367
- * @param {String} property - see {@link ContextLoader}
368
- * @param {Object} opt - see {@link ContextLoader}
369
- * @since 1.0.0
370
- */
371
- loadToContext(directory, property, opt) {
372
- opt = Object.assign({}, {
373
- directory,
374
- property,
375
- inject: this.app,
376
- loader: this
377
- }, opt);
378
- const timingKey = `Load "${String(property)}" to Context`;
379
- this.timing.start(timingKey);
380
- if (['addon'].includes(property)) {
381
- new ContextLoader(opt).loadAddons();
382
- } else {
383
- new ContextLoader(opt).load();
384
- }
385
-
386
- this.timing.end(timingKey);
387
- }
388
-
389
- /**
390
- * @member {FileLoader} EeLoader#FileLoader
391
- * @since 1.0.0
392
- */
393
- get FileLoader() {
394
- return FileLoader;
395
- }
396
-
397
- /**
398
- * @member {ContextLoader} EeLoader#ContextLoader
399
- * @since 1.0.0
400
- */
401
- get ContextLoader() {
402
- return ContextLoader;
403
- }
404
-
405
- getTypeFiles(filename) {
406
- const files = [ `${filename}.default` ];
407
- if (this.serverScope) files.push(`${filename}.${this.serverScope}`);
408
- if (this.serverEnv === 'default') return files;
409
-
410
- files.push(`${filename}.${this.serverEnv}`);
411
- if (this.serverScope) files.push(`${filename}.${this.serverScope}_${this.serverEnv}`);
412
- return files;
413
- }
414
-
415
- resolveModule(filepath) {
416
- let fullPath;
417
- try {
418
- fullPath = require.resolve(filepath);
419
- } catch (e) {
420
- let jscFile = filepath + '.jsc';
421
- if (fs.existsSync(jscFile)) {
422
- return jscFile;
423
- }
424
- return undefined;
425
- }
426
-
427
- if (process.env.Ee_TYPESCRIPT !== 'true' && fullPath.endsWith('.ts')) {
428
- return undefined;
429
- }
430
-
431
- return fullPath;
432
- }
433
-
434
- getPkg() {
435
- const filePath = path.join(this.options.homeDir, 'package.json');
436
- const json = utility.readJSONSync(filePath);
437
- return json;
438
- }
439
- }
440
-
441
- /**
442
- * Mixin methods to EeLoader
443
- * // ES6 Multiple Inheritance
444
- * https://medium.com/@leocavalcante/es6-multiple-inheritance-73a3c66d2b6b
445
- */
446
- const loaders = [
447
- require('./mixin/config'),
448
- require('./mixin/service'),
449
- require('./mixin/controller'),
450
- require('./mixin/addon'),
451
- ];
452
-
453
- for (const loader of loaders) {
454
- Object.assign(EeLoader.prototype, loader);
455
- }
456
-
457
- module.exports = EeLoader;
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const assert = require('assert');
6
+ const is = require('is-type-of');
7
+ const debug = require('debug')('ee-core:EeLoader');
8
+ const FileLoader = require('./file_loader');
9
+ const ContextLoader = require('./context_loader');
10
+ const utility = require('utility');
11
+ const utils = require('../utils');
12
+ const Timing = require('../utils/timing');
13
+
14
+ const REQUIRE_COUNT = Symbol('EeLoader#requireCount');
15
+
16
+ class EeLoader {
17
+
18
+ /**
19
+ * @class
20
+ * @param {Object} options - options
21
+ * @param {String} options.baseDir - the directory of application
22
+ * @param {EeCore} options.app - Application instance
23
+ * @param {Logger} options.logger - logger
24
+ * @since 1.0.0
25
+ */
26
+ constructor(options) {
27
+ this.options = options;
28
+ assert(fs.existsSync(this.options.baseDir), `${this.options.baseDir} not exists`);
29
+ assert(this.options.app, 'options.app is required');
30
+ assert(this.options.logger, 'options.logger is required');
31
+
32
+ this.app = this.options.app;
33
+ this.timing = this.app.timing || new Timing();
34
+ this[REQUIRE_COUNT] = 0;
35
+
36
+ /**
37
+ * @member {Object} EeLoader#pkg
38
+ * @see {@link AppInfo#pkg}
39
+ * @since 1.0.0
40
+ */
41
+ this.pkg = this.getPkg();
42
+
43
+ /**
44
+ * Framework directories
45
+ *
46
+ * @member {Array} EeLoader#EePaths
47
+ * @see EeLoader#getEePaths
48
+ * @since 1.0.0
49
+ */
50
+ this.EePaths = this.getEePaths();
51
+ debug('Loaded EePaths %j', this.EePaths);
52
+
53
+ /**
54
+ * @member {String} EeLoader#serverEnv
55
+ * @see AppInfo#env
56
+ * @since 1.0.0
57
+ */
58
+ this.serverEnv = this.getServerEnv();
59
+ debug('Loaded serverEnv %j', this.serverEnv);
60
+
61
+ /**
62
+ * @member {AppInfo} EeLoader#appInfo
63
+ * @since 1.0.0
64
+ */
65
+ this.appInfo = this.getAppInfo();
66
+
67
+ /**
68
+ * @member {String} EeLoader#serverScope
69
+ * @see AppInfo#serverScope
70
+ */
71
+ this.serverScope = options.serverScope !== undefined
72
+ ? options.serverScope
73
+ : this.getServerScope();
74
+ }
75
+
76
+ /**
77
+ * Get {@link AppInfo#env}
78
+ * @return {String} env
79
+ * @see AppInfo#env
80
+ * @private
81
+ * @since 1.0.0
82
+ */
83
+ getServerEnv() {
84
+ let serverEnv = this.options.env;
85
+
86
+ const envPath = path.join(this.options.baseDir, 'config/env');
87
+ if (!serverEnv && fs.existsSync(envPath)) {
88
+ serverEnv = fs.readFileSync(envPath, 'utf8').trim();
89
+ }
90
+
91
+ if (!serverEnv) {
92
+ serverEnv = process.env.EE_SERVER_ENV;
93
+ }
94
+
95
+ if (!serverEnv) {
96
+ if (process.env.NODE_ENV === 'test') {
97
+ serverEnv = 'unittest';
98
+ } else if (process.env.NODE_ENV === 'production') {
99
+ serverEnv = 'prod';
100
+ } else {
101
+ serverEnv = 'local';
102
+ }
103
+ } else {
104
+ serverEnv = serverEnv.trim();
105
+ }
106
+
107
+ return serverEnv;
108
+ }
109
+
110
+ /**
111
+ * Get {@link AppInfo#scope}
112
+ * @return {String} serverScope
113
+ * @private
114
+ */
115
+ getServerScope() {
116
+ return process.env.EE_SERVER_SCOPE || '';
117
+ }
118
+
119
+ /**
120
+ * Get {@link AppInfo#name}
121
+ * @return {String} appname
122
+ * @private
123
+ * @since 1.0.0
124
+ */
125
+ getAppname() {
126
+ if (this.pkg.name) {
127
+ debug('Loaded appname(%s) from package.json', this.pkg.name);
128
+ return this.pkg.name;
129
+ }
130
+
131
+ throw new Error(`name is required from ${pkg}`);
132
+ }
133
+
134
+ /**
135
+ * Get home directory
136
+ * @return {String} home directory
137
+ * @since 3.4.0
138
+ */
139
+ getHomedir() {
140
+ return this.options.homeDir;
141
+ }
142
+
143
+ /**
144
+ * Get app info
145
+ * @return {AppInfo} appInfo
146
+ * @since 1.0.0
147
+ */
148
+ getAppInfo() {
149
+ const env = this.serverEnv;
150
+
151
+ /**
152
+ * Meta information of the application
153
+ * @class AppInfo
154
+ */
155
+ return {
156
+ /**
157
+ * The name of the application, retrieve from the name property in `package.json`.
158
+ * @member {String} AppInfo#name
159
+ */
160
+ name: this.getAppname(),
161
+
162
+ /**
163
+ * The current directory, where the application code is.
164
+ * @member {String} AppInfo#baseDir
165
+ */
166
+ baseDir: this.options.baseDir,
167
+
168
+ /**
169
+ * The environment of the application, **it's not NODE_ENV**
170
+ *
171
+ * 1. from `$baseDir/config/env`
172
+ * 2. from EE_SERVER_ENV
173
+ * 3. from NODE_ENV
174
+ *
175
+ * env | description
176
+ * --- | ---
177
+ * test | system integration testing
178
+ * prod | production
179
+ * local | local on your own computer
180
+ * unittest | unit test
181
+ *
182
+ * @member {String} AppInfo#env
183
+ * @see https://Eejs.org/zh-cn/basics/env.html
184
+ */
185
+ env: env,
186
+
187
+ /**
188
+ * @member {String} AppInfo#scope
189
+ */
190
+ scope: this.serverScope,
191
+
192
+ /**
193
+ * The use directory, same as `process.env.HOME`
194
+ * @member {String} AppInfo#HOME
195
+ */
196
+ home: this.getHomedir(),
197
+
198
+ /**
199
+ * The directory whether is homeDir or appUserData depend on env.
200
+ * @member {String} AppInfo#root
201
+ */
202
+ root: env === 'local' || env === 'unittest' ? this.getHomedir() : this.options.appUserData,
203
+
204
+ /**
205
+ * electron application data dir
206
+ * @member {String} AppInfo#appUserDataDir
207
+ */
208
+ appUserDataDir: this.options.appUserData,
209
+
210
+ /**
211
+ * system user home dir
212
+ * @member {String} AppInfo#userHome
213
+ */
214
+ userHome: this.options.userHome,
215
+
216
+ /**
217
+ * application version
218
+ * @member {String} AppInfo#appVersion
219
+ */
220
+ appVersion: this.options.appVersion,
221
+
222
+ /**
223
+ * application package status
224
+ * @member {boolean} AppInfo#isPackaged
225
+ */
226
+ isPackaged: this.options.isPackaged,
227
+
228
+ /**
229
+ * application exec file dir
230
+ * @member {String} AppInfo#execDir
231
+ */
232
+ execDir: this.options.execDir
233
+ };
234
+ }
235
+
236
+ /**
237
+ * Get {@link EeLoader#EePaths}
238
+ * @return {Array} framework directories
239
+ * @see {@link EeLoader#EePaths}
240
+ * @private
241
+ * @since 1.0.0
242
+ */
243
+ getEePaths() {
244
+ // avoid require recursively
245
+ const EePaths = [];
246
+ EePaths.push(this.app[Symbol.for('ee#eePath')]);
247
+
248
+ return EePaths;
249
+ }
250
+
251
+ // Low Level API
252
+
253
+ /**
254
+ * Load single file, will invoke when export is function
255
+ *
256
+ * @param {String} filepath - fullpath
257
+ * @param {Array} inject - pass rest arguments into the function when invoke
258
+ * @return {Object} exports
259
+ * @example
260
+ * ```js
261
+ * app.loader.loadFile(path.join(app.options.baseDir, 'config/router.js'));
262
+ * ```
263
+ * @since 1.0.0
264
+ */
265
+ loadFile(filepath, ...inject) {
266
+ filepath = filepath && this.resolveModule(filepath);
267
+ if (!filepath) {
268
+ return null;
269
+ }
270
+
271
+ // function(arg1, args, ...) {}
272
+ if (inject.length === 0) inject = [ this.app ];
273
+
274
+ let ret = this.requireFile(filepath);
275
+ if (is.function(ret) && !is.class(ret) && !utils.isBytecodeClass(ret)) {
276
+ ret = ret(...inject);
277
+ }
278
+ return ret;
279
+ }
280
+
281
+ /**
282
+ * @param {String} filepath - fullpath
283
+ * @return {Object} exports
284
+ * @private
285
+ */
286
+ requireFile(filepath) {
287
+ const timingKey = `Require(${this[REQUIRE_COUNT]++}) ${utils.getResolvedFilename(filepath, this.options.baseDir)}`;
288
+ this.timing.start(timingKey);
289
+ const ret = utils.loadFile(filepath);
290
+ this.timing.end(timingKey);
291
+ return ret;
292
+ }
293
+
294
+ /**
295
+ * Get all loadUnit
296
+ *
297
+ * loadUnit is a directory that can be loaded by EeLoader, it has the same structure.
298
+ * loadUnit has a path and a type(app, framework, plugin).
299
+ *
300
+ * The order of the loadUnits:
301
+ *
302
+ * 1. plugin
303
+ * 2. framework
304
+ * 3. app
305
+ *
306
+ * @return {Array} loadUnits
307
+ * @since 1.0.0
308
+ */
309
+ getLoadUnits() {
310
+ if (this.dirs) {
311
+ return this.dirs;
312
+ }
313
+
314
+ const dirs = this.dirs = [];
315
+
316
+ if (this.orderPlugins) {
317
+ for (const plugin of this.orderPlugins) {
318
+ dirs.push({
319
+ path: plugin.path,
320
+ type: 'plugin',
321
+ });
322
+ }
323
+ }
324
+
325
+ // framework or Ee path
326
+ for (const EePath of this.EePaths) {
327
+ dirs.push({
328
+ path: EePath,
329
+ type: 'framework',
330
+ });
331
+ }
332
+
333
+ // application
334
+ dirs.push({
335
+ path: this.options.baseDir,
336
+ type: 'app',
337
+ });
338
+
339
+ debug('Loaded dirs %j', dirs);
340
+ return dirs;
341
+ }
342
+
343
+ /**
344
+ * Load files using {@link FileLoader}, inject to {@link Application}
345
+ * @param {String|Array} directory - see {@link FileLoader}
346
+ * @param {String} property - see {@link FileLoader}
347
+ * @param {Object} opt - see {@link FileLoader}
348
+ * @since 1.0.0
349
+ */
350
+ loadToApp(directory, property, opt) {
351
+ const target = this.app[property] = {};
352
+ opt = Object.assign({}, {
353
+ directory,
354
+ target,
355
+ inject: this.app,
356
+ }, opt);
357
+
358
+ const timingKey = `Load "${String(property)}" to Application`;
359
+ this.timing.start(timingKey);
360
+ new FileLoader(opt).load();
361
+ this.timing.end(timingKey);
362
+ }
363
+
364
+ /**
365
+ * Load files using {@link ContextLoader}
366
+ * @param {String|Array} directory - see {@link ContextLoader}
367
+ * @param {String} property - see {@link ContextLoader}
368
+ * @param {Object} opt - see {@link ContextLoader}
369
+ * @since 1.0.0
370
+ */
371
+ loadToContext(directory, property, opt) {
372
+ opt = Object.assign({}, {
373
+ directory,
374
+ property,
375
+ inject: this.app,
376
+ loader: this
377
+ }, opt);
378
+ const timingKey = `Load "${String(property)}" to Context`;
379
+ this.timing.start(timingKey);
380
+ if (['addon'].includes(property)) {
381
+ new ContextLoader(opt).loadAddons();
382
+ } else {
383
+ new ContextLoader(opt).load();
384
+ }
385
+
386
+ this.timing.end(timingKey);
387
+ }
388
+
389
+ /**
390
+ * @member {FileLoader} EeLoader#FileLoader
391
+ * @since 1.0.0
392
+ */
393
+ get FileLoader() {
394
+ return FileLoader;
395
+ }
396
+
397
+ /**
398
+ * @member {ContextLoader} EeLoader#ContextLoader
399
+ * @since 1.0.0
400
+ */
401
+ get ContextLoader() {
402
+ return ContextLoader;
403
+ }
404
+
405
+ getTypeFiles(filename) {
406
+ const files = [ `${filename}.default` ];
407
+ if (this.serverScope) files.push(`${filename}.${this.serverScope}`);
408
+ if (this.serverEnv === 'default') return files;
409
+
410
+ files.push(`${filename}.${this.serverEnv}`);
411
+ if (this.serverScope) files.push(`${filename}.${this.serverScope}_${this.serverEnv}`);
412
+ return files;
413
+ }
414
+
415
+ resolveModule(filepath) {
416
+ let fullPath;
417
+ try {
418
+ fullPath = require.resolve(filepath);
419
+ } catch (e) {
420
+ let jscFile = filepath + '.jsc';
421
+ if (fs.existsSync(jscFile)) {
422
+ return jscFile;
423
+ }
424
+ return undefined;
425
+ }
426
+
427
+ if (process.env.Ee_TYPESCRIPT !== 'true' && fullPath.endsWith('.ts')) {
428
+ return undefined;
429
+ }
430
+
431
+ return fullPath;
432
+ }
433
+
434
+ getPkg() {
435
+ const filePath = path.join(this.options.homeDir, 'package.json');
436
+ const json = utility.readJSONSync(filePath);
437
+ return json;
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Mixin methods to EeLoader
443
+ * // ES6 Multiple Inheritance
444
+ * https://medium.com/@leocavalcante/es6-multiple-inheritance-73a3c66d2b6b
445
+ */
446
+ const loaders = [
447
+ require('./mixin/config'),
448
+ require('./mixin/service'),
449
+ require('./mixin/controller'),
450
+ require('./mixin/addon'),
451
+ ];
452
+
453
+ for (const loader of loaders) {
454
+ Object.assign(EeLoader.prototype, loader);
455
+ }
456
+
457
+ module.exports = EeLoader;