@eggjs/core 6.0.0-beta.1 → 6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eggjs/core",
3
- "version": "6.0.0-beta.1",
3
+ "version": "6.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -13,8 +13,10 @@
13
13
  "description": "A core plugin framework based on @eggjs/koa",
14
14
  "scripts": {
15
15
  "lint": "eslint src test --ext ts",
16
+ "pretest": "npm run prepublishOnly",
16
17
  "test": "npm run lint -- --fix && npm run test-local",
17
18
  "test-local": "egg-bin test",
19
+ "preci": "npm run prepublishOnly",
18
20
  "ci": "npm run lint && egg-bin cov && npm run prepublishOnly",
19
21
  "contributor": "git-contributor",
20
22
  "prepublishOnly": "tshy && tshy-after"
@@ -36,6 +38,7 @@
36
38
  "dependencies": {
37
39
  "@eggjs/koa": "^2.18.2",
38
40
  "@eggjs/router": "^3.0.5",
41
+ "@eggjs/utils": "^4.0.2",
39
42
  "egg-logger": "^3.5.0",
40
43
  "egg-path-matching": "^2.0.0",
41
44
  "extend2": "^4.0.0",
@@ -45,7 +48,7 @@
45
48
  "node-homedir": "^2.0.0",
46
49
  "performance-ms": "^1.1.0",
47
50
  "ready-callback": "^4.0.0",
48
- "tsconfig-paths": "^4.1.1",
51
+ "tsconfig-paths": "^4.2.0",
49
52
  "utility": "^2.1.0"
50
53
  },
51
54
  "devDependencies": {
@@ -57,14 +60,12 @@
57
60
  "await-event": "2",
58
61
  "coffee": "5",
59
62
  "egg-bin": "6",
60
- "egg-utils": "2",
61
63
  "eslint": "8",
62
64
  "eslint-config-egg": "13",
63
65
  "gals": "1",
64
66
  "git-contributor": "2",
65
67
  "js-yaml": "3",
66
68
  "mm": "3",
67
- "spy": "1",
68
69
  "supertest": "7",
69
70
  "ts-node": "10",
70
71
  "tshy": "1",
@@ -42,7 +42,7 @@ export interface ContextLoaderOptions extends Omit<FileLoaderOptions, 'target'>
42
42
  /** required inject */
43
43
  inject: Record<string, any>;
44
44
  /** property name defined to target */
45
- property: string;
45
+ property: string | symbol;
46
46
  /** determine the field name of inject object. */
47
47
  fieldClass?: string;
48
48
  }
@@ -86,7 +86,7 @@ export class ContextLoader extends FileLoader {
86
86
  if (!ctx[CLASS_LOADER]) {
87
87
  ctx[CLASS_LOADER] = new Map();
88
88
  }
89
- const classLoader: Map<string, ClassLoader> = ctx[CLASS_LOADER];
89
+ const classLoader: Map<string | symbol, ClassLoader> = ctx[CLASS_LOADER];
90
90
  let instance = classLoader.get(property);
91
91
  if (!instance) {
92
92
  instance = getInstance(target, ctx);
@@ -148,16 +148,12 @@ export class EggLoader {
148
148
  * loader will find all directories from the prototype of Application,
149
149
  * you should define `Symbol.for('egg#eggPath')` property.
150
150
  *
151
- * ```
152
- * // lib/example.js
153
- * const egg = require('egg');
154
- * class ExampleApplication extends egg.Application {
155
- * constructor(options) {
156
- * super(options);
157
- * }
158
- *
151
+ * ```ts
152
+ * // src/example.ts
153
+ * import { Application } from 'egg';
154
+ * class ExampleApplication extends Application {
159
155
  * get [Symbol.for('egg#eggPath')]() {
160
- * return path.join(__dirname, '..');
156
+ * return baseDir;
161
157
  * }
162
158
  * }
163
159
  * ```
@@ -370,17 +366,20 @@ export class EggLoader {
370
366
  if (proto === Object.prototype || proto === EggCore?.prototype) {
371
367
  break;
372
368
  }
373
-
374
- assert(proto.hasOwnProperty(Symbol.for('egg#eggPath')), 'Symbol.for(\'egg#eggPath\') is required on Application');
375
369
  const eggPath = Reflect.get(proto, Symbol.for('egg#eggPath'));
376
- assert(eggPath && typeof eggPath === 'string', 'Symbol.for(\'egg#eggPath\') should be string');
370
+ if (!eggPath) {
371
+ // if (EggCore) {
372
+ // throw new TypeError('Symbol.for(\'egg#eggPath\') is required on Application');
373
+ // }
374
+ continue;
375
+ }
376
+ assert(typeof eggPath === 'string', 'Symbol.for(\'egg#eggPath\') should be string');
377
377
  assert(fs.existsSync(eggPath), `${eggPath} not exists`);
378
378
  const realpath = fs.realpathSync(eggPath);
379
379
  if (!eggPaths.includes(realpath)) {
380
380
  eggPaths.unshift(realpath);
381
381
  }
382
382
  }
383
-
384
383
  return eggPaths;
385
384
  }
386
385
 
@@ -1269,6 +1268,11 @@ export class EggLoader {
1269
1268
 
1270
1269
  this.options.logger.info('[@eggjs/core:egg_loader] Loaded middleware from %j', middlewarePaths);
1271
1270
  this.timing.end('Load Middleware');
1271
+
1272
+ // add router middleware, make sure router is the last middleware
1273
+ const mw = this.app.router.middleware();
1274
+ Reflect.set(mw, '_name', 'routerMiddleware');
1275
+ this.app.use(mw);
1272
1276
  }
1273
1277
  /** end Middleware loader */
1274
1278
 
@@ -1334,10 +1338,6 @@ export class EggLoader {
1334
1338
  async loadRouter() {
1335
1339
  this.timing.start('Load Router');
1336
1340
  await this.loadFile(path.join(this.options.baseDir, 'app/router'));
1337
- // add router middleware
1338
- const mw = this.app.router.middleware();
1339
- Reflect.set(mw, '_name', 'routerMiddleware');
1340
- this.app.use(mw);
1341
1341
  this.timing.end('Load Router');
1342
1342
  }
1343
1343
  /** end Router loader */
@@ -1493,12 +1493,12 @@ export class EggLoader {
1493
1493
  * @param {Object} options - see {@link FileLoader}
1494
1494
  * @since 1.0.0
1495
1495
  */
1496
- async loadToApp(directory: string | string[], property: string, options: FileLoaderOptions) {
1496
+ async loadToApp(directory: string | string[], property: string | symbol, options?: FileLoaderOptions) {
1497
1497
  const target = {};
1498
1498
  Reflect.set(this.app, property, target);
1499
1499
  options = {
1500
1500
  ...options,
1501
- directory: options.directory ?? directory,
1501
+ directory: options?.directory ?? directory,
1502
1502
  target,
1503
1503
  inject: this.app,
1504
1504
  };
@@ -1516,7 +1516,7 @@ export class EggLoader {
1516
1516
  * @param {Object} options - see {@link ContextLoader}
1517
1517
  * @since 1.0.0
1518
1518
  */
1519
- async loadToContext(directory: string | string[], property: string, options?: ContextLoaderOptions) {
1519
+ async loadToContext(directory: string | string[], property: string | symbol, options?: ContextLoaderOptions) {
1520
1520
  options = {
1521
1521
  ...options,
1522
1522
  directory: options?.directory || directory,
@@ -1,9 +1,8 @@
1
1
  import { debuglog } from 'node:util';
2
2
  import path from 'node:path';
3
3
  import fs from 'node:fs';
4
- import { pathToFileURL } from 'node:url';
5
4
  import BuiltinModule from 'node:module';
6
- import { createRequire } from 'node:module';
5
+ import { importResolve, importModule } from '@eggjs/utils';
7
6
 
8
7
  const debug = debuglog('@eggjs/core:utils');
9
8
 
@@ -19,15 +18,6 @@ const extensions = (Module as any)._extensions;
19
18
  const extensionNames = Object.keys(extensions).concat([ '.cjs', '.mjs' ]);
20
19
  debug('Module extensions: %j', extensionNames);
21
20
 
22
- let _customRequire: NodeRequire;
23
- function getCustomRequire() {
24
- if (!_customRequire && typeof require === 'undefined') {
25
- _customRequire = createRequire(process.cwd());
26
- // _customRequire = createRequire(import.meta.url);
27
- }
28
- return _customRequire;
29
- }
30
-
31
21
  export default {
32
22
  deprecated(message: string) {
33
23
  console.warn('[@eggjs/core:deprecated] %s', message);
@@ -35,19 +25,6 @@ export default {
35
25
 
36
26
  extensions,
37
27
 
38
- // async _importOrRequire(filepath: string) {
39
- // // try import first
40
- // let obj: any;
41
- // try {
42
- // obj = await import(filepath);
43
- // } catch (err: any) {
44
- // debug('await import error, use require instead, %s', err);
45
- // // use custom require
46
- // obj = getCustomRequire()(filepath);
47
- // }
48
- // return obj;
49
- // },
50
-
51
28
  async loadFile(filepath: string) {
52
29
  try {
53
30
  // if not js module, just return content buffer
@@ -55,33 +32,7 @@ export default {
55
32
  if (extname && !extensionNames.includes(extname)) {
56
33
  return fs.readFileSync(filepath);
57
34
  }
58
- let obj: any;
59
- let isESM = false;
60
- if (typeof require === 'function') {
61
- // commonjs
62
- obj = require(filepath);
63
- debug('[loadFile] require %s => %o', filepath, obj);
64
- if (obj && obj.__esModule) {
65
- isESM = true;
66
- }
67
- } else {
68
- // esm
69
- debug('[loadFile] await import start: %s', filepath);
70
- const fileUrl = pathToFileURL(filepath).toString();
71
- obj = await import(fileUrl);
72
- debug('[loadFile] await import end: %s => %o', filepath, obj);
73
- isESM = true;
74
- if (obj && typeof obj === 'object' && 'default' in obj) {
75
- // default: { default: [Function (anonymous)] }
76
- obj = obj.default;
77
- }
78
- }
79
- if (!obj) return obj;
80
- // it's es module, use default export
81
- if (isESM && typeof obj === 'object') {
82
- obj = 'default' in obj ? obj.default : obj;
83
- }
84
- debug('[loadFile] return %s => %o', filepath, obj);
35
+ const obj = await importModule(filepath, { importDefaultOnly: true });
85
36
  return obj;
86
37
  } catch (e: any) {
87
38
  const err = new Error(`[@eggjs/core] load file: ${filepath}, error: ${e.message}`);
@@ -92,10 +43,7 @@ export default {
92
43
  },
93
44
 
94
45
  resolvePath(filepath: string, options?: { paths?: string[] }) {
95
- if (typeof require !== 'undefined') {
96
- return require.resolve(filepath, options);
97
- }
98
- return getCustomRequire().resolve(filepath, options);
46
+ return importResolve(filepath, options);
99
47
  },
100
48
 
101
49
  methods: [ 'head', 'options', 'get', 'put', 'patch', 'post', 'delete' ],