@eggjs/core 6.2.11 → 6.2.13
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/dist/commonjs/egg.d.ts +3 -2
- package/dist/commonjs/egg.js +1 -1
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/loader/egg_loader.d.ts +4 -40
- package/dist/commonjs/loader/egg_loader.js +36 -24
- package/dist/commonjs/loader/file_loader.d.ts +5 -1
- package/dist/commonjs/loader/file_loader.js +10 -4
- package/dist/commonjs/types.d.ts +53 -0
- package/dist/commonjs/types.js +3 -0
- package/dist/esm/egg.d.ts +3 -2
- package/dist/esm/egg.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/loader/egg_loader.d.ts +4 -40
- package/dist/esm/loader/egg_loader.js +38 -26
- package/dist/esm/loader/file_loader.d.ts +5 -1
- package/dist/esm/loader/file_loader.js +9 -3
- package/dist/esm/types.d.ts +53 -0
- package/dist/esm/types.js +2 -0
- package/dist/package.json +1 -1
- package/package.json +2 -2
- package/src/egg.ts +3 -2
- package/src/index.ts +1 -0
- package/src/loader/egg_loader.ts +49 -69
- package/src/loader/file_loader.ts +8 -3
- package/src/types.ts +56 -0
package/src/loader/egg_loader.ts
CHANGED
|
@@ -5,12 +5,16 @@ import { debuglog, inspect } from 'node:util';
|
|
|
5
5
|
import { homedir } from 'node-homedir';
|
|
6
6
|
import { isAsyncFunction, isClass, isGeneratorFunction, isObject, isPromise } from 'is-type-of';
|
|
7
7
|
import type { Logger } from 'egg-logger';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getParamNames, readJSONSync, readJSON, exists,
|
|
10
|
+
} from 'utility';
|
|
9
11
|
import { extend } from 'extend2';
|
|
10
12
|
import { Request, Response, Application, Context as KoaContext } from '@eggjs/koa';
|
|
13
|
+
import { register as tsconfigPathsRegister } from 'tsconfig-paths';
|
|
14
|
+
import { isESM, isSupportTypeScript } from '@eggjs/utils';
|
|
11
15
|
import { pathMatching, type PathMatchingOptions } from 'egg-path-matching';
|
|
12
16
|
import { now, diff } from 'performance-ms';
|
|
13
|
-
import { FULLPATH, FileLoader, FileLoaderOptions } from './file_loader.js';
|
|
17
|
+
import { CaseStyle, FULLPATH, FileLoader, FileLoaderOptions } from './file_loader.js';
|
|
14
18
|
import { ContextLoader, ContextLoaderOptions } from './context_loader.js';
|
|
15
19
|
import utils, { Fun } from '../utils/index.js';
|
|
16
20
|
import sequencify from '../utils/sequencify.js';
|
|
@@ -19,6 +23,7 @@ import type {
|
|
|
19
23
|
Context, EggCore, MiddlewareFunc,
|
|
20
24
|
} from '../egg.js';
|
|
21
25
|
import type { BaseContextClass } from '../base_context_class.js';
|
|
26
|
+
import type { EggAppConfig, EggAppInfo, EggPluginInfo } from '../types.js';
|
|
22
27
|
|
|
23
28
|
const debug = debuglog('@eggjs/core/loader/egg_loader');
|
|
24
29
|
|
|
@@ -29,44 +34,6 @@ const originalPrototypes: Record<string, any> = {
|
|
|
29
34
|
application: Application.prototype,
|
|
30
35
|
};
|
|
31
36
|
|
|
32
|
-
export interface EggAppInfo {
|
|
33
|
-
/** package.json */
|
|
34
|
-
pkg: Record<string, any>;
|
|
35
|
-
/** the application name from package.json */
|
|
36
|
-
name: string;
|
|
37
|
-
/** current directory of application */
|
|
38
|
-
baseDir: string;
|
|
39
|
-
/** equals to serverEnv */
|
|
40
|
-
env: string;
|
|
41
|
-
/** equals to serverScope */
|
|
42
|
-
scope: string;
|
|
43
|
-
/** home directory of the OS */
|
|
44
|
-
HOME: string;
|
|
45
|
-
/** baseDir when local and unittest, HOME when other environment */
|
|
46
|
-
root: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface EggPluginInfo {
|
|
50
|
-
/** the plugin name, it can be used in `dep` */
|
|
51
|
-
name: string;
|
|
52
|
-
/** the package name of plugin */
|
|
53
|
-
package?: string;
|
|
54
|
-
version?: string;
|
|
55
|
-
/** whether enabled */
|
|
56
|
-
enable: boolean;
|
|
57
|
-
implicitEnable?: boolean;
|
|
58
|
-
/** the directory of the plugin package */
|
|
59
|
-
path?: string;
|
|
60
|
-
/** the dependent plugins, you can use the plugin name */
|
|
61
|
-
dependencies: string[];
|
|
62
|
-
/** the optional dependent plugins. */
|
|
63
|
-
optionalDependencies: string[];
|
|
64
|
-
dependents?: string[];
|
|
65
|
-
/** specify the serverEnv that only enable the plugin in it */
|
|
66
|
-
env: string[];
|
|
67
|
-
/** the file plugin config in. */
|
|
68
|
-
from: string;
|
|
69
|
-
}
|
|
70
37
|
|
|
71
38
|
export interface EggLoaderOptions {
|
|
72
39
|
/** server env */
|
|
@@ -102,7 +69,6 @@ export class EggLoader {
|
|
|
102
69
|
readonly appInfo: EggAppInfo;
|
|
103
70
|
dirs?: EggDirInfo[];
|
|
104
71
|
|
|
105
|
-
|
|
106
72
|
/**
|
|
107
73
|
* @class
|
|
108
74
|
* @param {Object} options - options
|
|
@@ -132,12 +98,11 @@ export class EggLoader {
|
|
|
132
98
|
if (process.env.EGG_TYPESCRIPT === 'true' || (this.pkg.egg && this.pkg.egg.typescript)) {
|
|
133
99
|
// skip require tsconfig-paths if tsconfig.json not exists
|
|
134
100
|
const tsConfigFile = path.join(this.options.baseDir, 'tsconfig.json');
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
138
|
-
require('tsconfig-paths').register({ cwd: this.options.baseDir });
|
|
101
|
+
if (fs.existsSync(tsConfigFile)) {
|
|
102
|
+
tsconfigPathsRegister({ cwd: this.options.baseDir } as any);
|
|
139
103
|
} else {
|
|
140
|
-
this.logger.info(
|
|
104
|
+
this.logger.info(
|
|
105
|
+
'[@eggjs/core/egg_loader] skip register "tsconfig-paths" because tsconfig.json not exists at %s',
|
|
141
106
|
tsConfigFile);
|
|
142
107
|
}
|
|
143
108
|
}
|
|
@@ -636,7 +601,7 @@ export class EggLoader {
|
|
|
636
601
|
plugin.version = pkg.version;
|
|
637
602
|
}
|
|
638
603
|
// support commonjs and esm dist files
|
|
639
|
-
plugin.path = this.#formatPluginPathFromPackageJSON(plugin.path!, pkg);
|
|
604
|
+
plugin.path = await this.#formatPluginPathFromPackageJSON(plugin.path!, pkg);
|
|
640
605
|
}
|
|
641
606
|
|
|
642
607
|
const logger = this.options.logger;
|
|
@@ -790,26 +755,36 @@ export class EggLoader {
|
|
|
790
755
|
}
|
|
791
756
|
}
|
|
792
757
|
|
|
793
|
-
#formatPluginPathFromPackageJSON(pluginPath: string, pluginPkg: {
|
|
758
|
+
async #formatPluginPathFromPackageJSON(pluginPath: string, pluginPkg: {
|
|
794
759
|
eggPlugin?: {
|
|
795
760
|
exports?: {
|
|
796
761
|
import?: string;
|
|
797
762
|
require?: string;
|
|
763
|
+
typescript?: string;
|
|
798
764
|
};
|
|
799
765
|
};
|
|
800
|
-
}) {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
766
|
+
}): Promise<string> {
|
|
767
|
+
let realPluginPath = pluginPath;
|
|
768
|
+
const exports = pluginPkg.eggPlugin?.exports;
|
|
769
|
+
if (exports) {
|
|
770
|
+
if (isESM) {
|
|
771
|
+
if (exports.import) {
|
|
772
|
+
realPluginPath = path.join(pluginPath, exports.import);
|
|
805
773
|
}
|
|
806
774
|
} else {
|
|
807
|
-
if (
|
|
808
|
-
|
|
775
|
+
if (exports.require) {
|
|
776
|
+
realPluginPath = path.join(pluginPath, exports.require);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
if (exports.typescript && isSupportTypeScript()) {
|
|
780
|
+
if (!(await exists(realPluginPath))) {
|
|
781
|
+
// if require/import path not exists, use typescript path for development stage
|
|
782
|
+
realPluginPath = path.join(pluginPath, exports.typescript);
|
|
783
|
+
debug('[formatPluginPathFromPackageJSON] use typescript path %o', realPluginPath);
|
|
809
784
|
}
|
|
810
785
|
}
|
|
811
786
|
}
|
|
812
|
-
return
|
|
787
|
+
return realPluginPath;
|
|
813
788
|
}
|
|
814
789
|
|
|
815
790
|
#extendPlugins(targets: Record<string, EggPluginInfo>, plugins: Record<string, EggPluginInfo>) {
|
|
@@ -845,7 +820,7 @@ export class EggLoader {
|
|
|
845
820
|
|
|
846
821
|
/** start Config loader */
|
|
847
822
|
configMeta: Record<string, any>;
|
|
848
|
-
config:
|
|
823
|
+
config: EggAppConfig;
|
|
849
824
|
|
|
850
825
|
/**
|
|
851
826
|
* Load config/config.js
|
|
@@ -859,7 +834,10 @@ export class EggLoader {
|
|
|
859
834
|
this.timing.start('Load Config');
|
|
860
835
|
this.configMeta = {};
|
|
861
836
|
|
|
862
|
-
const target:
|
|
837
|
+
const target: EggAppConfig = {
|
|
838
|
+
middleware: [],
|
|
839
|
+
coreMiddleware: [],
|
|
840
|
+
};
|
|
863
841
|
|
|
864
842
|
// Load Application config first
|
|
865
843
|
const appConfig = await this.#preloadAppConfig();
|
|
@@ -1208,7 +1186,7 @@ export class EggLoader {
|
|
|
1208
1186
|
const servicePaths = this.getLoadUnits().map(unit => path.join(unit.path, 'app/service'));
|
|
1209
1187
|
options = {
|
|
1210
1188
|
call: true,
|
|
1211
|
-
caseStyle:
|
|
1189
|
+
caseStyle: CaseStyle.lower,
|
|
1212
1190
|
fieldClass: 'serviceClasses',
|
|
1213
1191
|
directory: servicePaths,
|
|
1214
1192
|
...options,
|
|
@@ -1248,7 +1226,7 @@ export class EggLoader {
|
|
|
1248
1226
|
opt = {
|
|
1249
1227
|
call: false,
|
|
1250
1228
|
override: true,
|
|
1251
|
-
caseStyle:
|
|
1229
|
+
caseStyle: CaseStyle.lower,
|
|
1252
1230
|
directory: middlewarePaths,
|
|
1253
1231
|
...opt,
|
|
1254
1232
|
};
|
|
@@ -1323,7 +1301,7 @@ export class EggLoader {
|
|
|
1323
1301
|
this.timing.start('Load Controller');
|
|
1324
1302
|
const controllerBase = path.join(this.options.baseDir, 'app/controller');
|
|
1325
1303
|
opt = {
|
|
1326
|
-
caseStyle:
|
|
1304
|
+
caseStyle: CaseStyle.lower,
|
|
1327
1305
|
directory: controllerBase,
|
|
1328
1306
|
initializer: (obj, opt) => {
|
|
1329
1307
|
// return class if it exports a function
|
|
@@ -1403,7 +1381,7 @@ export class EggLoader {
|
|
|
1403
1381
|
case 'ctx': {
|
|
1404
1382
|
assert(!(property in this.app.context), `customLoader should not override ctx.${property}`);
|
|
1405
1383
|
const options = {
|
|
1406
|
-
caseStyle:
|
|
1384
|
+
caseStyle: CaseStyle.lower,
|
|
1407
1385
|
fieldClass: `${property}Classes`,
|
|
1408
1386
|
...loaderConfig,
|
|
1409
1387
|
directory,
|
|
@@ -1414,7 +1392,7 @@ export class EggLoader {
|
|
|
1414
1392
|
case 'app': {
|
|
1415
1393
|
assert(!(property in this.app), `customLoader should not override app.${property}`);
|
|
1416
1394
|
const options = {
|
|
1417
|
-
caseStyle:
|
|
1395
|
+
caseStyle: CaseStyle.lower,
|
|
1418
1396
|
initializer: (Clazz: unknown) => {
|
|
1419
1397
|
return isClass(Clazz) ? new Clazz(this.app) : Clazz;
|
|
1420
1398
|
},
|
|
@@ -1533,10 +1511,11 @@ export class EggLoader {
|
|
|
1533
1511
|
* @param {Object} options - see {@link FileLoader}
|
|
1534
1512
|
* @since 1.0.0
|
|
1535
1513
|
*/
|
|
1536
|
-
async loadToApp(directory: string | string[], property: string | symbol,
|
|
1514
|
+
async loadToApp(directory: string | string[], property: string | symbol,
|
|
1515
|
+
options?: Omit<FileLoaderOptions, 'inject' | 'target'>) {
|
|
1537
1516
|
const target = {};
|
|
1538
1517
|
Reflect.set(this.app, property, target);
|
|
1539
|
-
|
|
1518
|
+
const loadOptions: FileLoaderOptions = {
|
|
1540
1519
|
...options,
|
|
1541
1520
|
directory: options?.directory ?? directory,
|
|
1542
1521
|
target,
|
|
@@ -1545,7 +1524,7 @@ export class EggLoader {
|
|
|
1545
1524
|
|
|
1546
1525
|
const timingKey = `Load "${String(property)}" to Application`;
|
|
1547
1526
|
this.timing.start(timingKey);
|
|
1548
|
-
await new FileLoader(
|
|
1527
|
+
await new FileLoader(loadOptions).load();
|
|
1549
1528
|
this.timing.end(timingKey);
|
|
1550
1529
|
}
|
|
1551
1530
|
|
|
@@ -1556,8 +1535,9 @@ export class EggLoader {
|
|
|
1556
1535
|
* @param {Object} options - see {@link ContextLoader}
|
|
1557
1536
|
* @since 1.0.0
|
|
1558
1537
|
*/
|
|
1559
|
-
async loadToContext(directory: string | string[], property: string | symbol,
|
|
1560
|
-
options
|
|
1538
|
+
async loadToContext(directory: string | string[], property: string | symbol,
|
|
1539
|
+
options?: Omit<ContextLoaderOptions, 'inject' | 'property'>) {
|
|
1540
|
+
const loadOptions: ContextLoaderOptions = {
|
|
1561
1541
|
...options,
|
|
1562
1542
|
directory: options?.directory || directory,
|
|
1563
1543
|
property,
|
|
@@ -1566,7 +1546,7 @@ export class EggLoader {
|
|
|
1566
1546
|
|
|
1567
1547
|
const timingKey = `Load "${String(property)}" to Context`;
|
|
1568
1548
|
this.timing.start(timingKey);
|
|
1569
|
-
await new ContextLoader(
|
|
1549
|
+
await new ContextLoader(loadOptions).load();
|
|
1570
1550
|
this.timing.end(timingKey);
|
|
1571
1551
|
}
|
|
1572
1552
|
|
|
@@ -11,7 +11,12 @@ const debug = debuglog('@eggjs/core/file_loader');
|
|
|
11
11
|
export const FULLPATH = Symbol('EGG_LOADER_ITEM_FULLPATH');
|
|
12
12
|
export const EXPORTS = Symbol('EGG_LOADER_ITEM_EXPORTS');
|
|
13
13
|
|
|
14
|
-
export
|
|
14
|
+
export enum CaseStyle {
|
|
15
|
+
camel = 'camel',
|
|
16
|
+
lower = 'lower',
|
|
17
|
+
upper = 'upper',
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
export type CaseStyleFunction = (filepath: string) => string[];
|
|
16
21
|
export type FileLoaderInitializer = (exports: unknown, options: { path: string; pathName: string }) => unknown;
|
|
17
22
|
export type FileLoaderFilter = (exports: unknown) => boolean;
|
|
@@ -79,7 +84,7 @@ export class FileLoader {
|
|
|
79
84
|
assert(options.directory, 'options.directory is required');
|
|
80
85
|
assert(options.target, 'options.target is required');
|
|
81
86
|
this.options = {
|
|
82
|
-
caseStyle:
|
|
87
|
+
caseStyle: CaseStyle.camel,
|
|
83
88
|
call: true,
|
|
84
89
|
override: false,
|
|
85
90
|
...options,
|
|
@@ -88,7 +93,7 @@ export class FileLoader {
|
|
|
88
93
|
// compatible old options _lowercaseFirst_
|
|
89
94
|
if (this.options.lowercaseFirst === true) {
|
|
90
95
|
utils.deprecated('lowercaseFirst is deprecated, use caseStyle instead');
|
|
91
|
-
this.options.caseStyle =
|
|
96
|
+
this.options.caseStyle = CaseStyle.lower;
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
99
|
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export interface EggAppInfo {
|
|
2
|
+
/** package.json */
|
|
3
|
+
pkg: Record<string, any>;
|
|
4
|
+
/** the application name from package.json */
|
|
5
|
+
name: string;
|
|
6
|
+
/** current directory of application */
|
|
7
|
+
baseDir: string;
|
|
8
|
+
/** equals to serverEnv */
|
|
9
|
+
env: string;
|
|
10
|
+
/** equals to serverScope */
|
|
11
|
+
scope: string;
|
|
12
|
+
/** home directory of the OS */
|
|
13
|
+
HOME: string;
|
|
14
|
+
/** baseDir when local and unittest, HOME when other environment */
|
|
15
|
+
root: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface EggPluginInfo {
|
|
19
|
+
/** the plugin name, it can be used in `dep` */
|
|
20
|
+
name: string;
|
|
21
|
+
/** the package name of plugin */
|
|
22
|
+
package?: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
/** whether enabled */
|
|
25
|
+
enable: boolean;
|
|
26
|
+
implicitEnable?: boolean;
|
|
27
|
+
/** the directory of the plugin package */
|
|
28
|
+
path?: string;
|
|
29
|
+
/** the dependent plugins, you can use the plugin name */
|
|
30
|
+
dependencies: string[];
|
|
31
|
+
/** the optional dependent plugins. */
|
|
32
|
+
optionalDependencies: string[];
|
|
33
|
+
dependents?: string[];
|
|
34
|
+
/** specify the serverEnv that only enable the plugin in it */
|
|
35
|
+
env: string[];
|
|
36
|
+
/** the file plugin config in. */
|
|
37
|
+
from: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CustomLoaderConfigItem {
|
|
41
|
+
/** the directory of the custom loader */
|
|
42
|
+
directory: string;
|
|
43
|
+
/** the inject object, it can be app or ctx */
|
|
44
|
+
inject: string;
|
|
45
|
+
/** whether load unit files */
|
|
46
|
+
loadunit?: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface EggAppConfig extends Record<string, any> {
|
|
50
|
+
coreMiddleware: string[];
|
|
51
|
+
middleware: string[];
|
|
52
|
+
customLoader?: Record<string, CustomLoaderConfigItem>;
|
|
53
|
+
controller?: {
|
|
54
|
+
supportParams?: boolean;
|
|
55
|
+
};
|
|
56
|
+
}
|