@eggjs/utils 4.4.0 → 4.5.0-beta.2
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/README.md +1 -6
- package/dist/_virtual/rolldown_runtime.js +7 -0
- package/dist/{commonjs/deprecated.d.ts → deprecated.d.ts} +4 -1
- package/dist/deprecated.js +41 -0
- package/dist/error/ImportResolveError.d.ts +8 -0
- package/dist/error/ImportResolveError.js +16 -0
- package/dist/{commonjs/framework.d.ts → framework.d.ts} +6 -4
- package/dist/framework.js +60 -0
- package/dist/import.d.ts +14 -0
- package/dist/import.js +231 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +45 -0
- package/dist/plugin.d.ts +51 -0
- package/dist/plugin.js +112 -0
- package/dist/utils.js +12 -0
- package/package.json +26 -57
- package/dist/commonjs/deprecated.js +0 -59
- package/dist/commonjs/error/ImportResolveError.d.ts +0 -5
- package/dist/commonjs/error/ImportResolveError.js +0 -17
- package/dist/commonjs/error/index.d.ts +0 -1
- package/dist/commonjs/error/index.js +0 -18
- package/dist/commonjs/framework.js +0 -84
- package/dist/commonjs/import.d.ts +0 -11
- package/dist/commonjs/import.js +0 -326
- package/dist/commonjs/index.d.ts +0 -26
- package/dist/commonjs/index.js +0 -77
- package/dist/commonjs/package.json +0 -3
- package/dist/commonjs/plugin.d.ts +0 -30
- package/dist/commonjs/plugin.js +0 -125
- package/dist/commonjs/utils.d.ts +0 -2
- package/dist/commonjs/utils.js +0 -25
- package/dist/esm/deprecated.d.ts +0 -10
- package/dist/esm/deprecated.js +0 -53
- package/dist/esm/error/ImportResolveError.d.ts +0 -5
- package/dist/esm/error/ImportResolveError.js +0 -13
- package/dist/esm/error/index.d.ts +0 -1
- package/dist/esm/error/index.js +0 -2
- package/dist/esm/framework.d.ts +0 -16
- package/dist/esm/framework.js +0 -78
- package/dist/esm/import.d.ts +0 -11
- package/dist/esm/import.js +0 -316
- package/dist/esm/index.d.ts +0 -26
- package/dist/esm/index.js +0 -51
- package/dist/esm/package.json +0 -3
- package/dist/esm/plugin.d.ts +0 -30
- package/dist/esm/plugin.js +0 -117
- package/dist/esm/utils.d.ts +0 -2
- package/dist/esm/utils.js +0 -18
- package/dist/package.json +0 -4
- package/src/deprecated.ts +0 -58
- package/src/error/ImportResolveError.ts +0 -13
- package/src/error/index.ts +0 -1
- package/src/framework.ts +0 -92
- package/src/import.ts +0 -344
- package/src/index.ts +0 -58
- package/src/plugin.ts +0 -167
- package/src/utils.ts +0 -19
package/src/import.ts
DELETED
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
import { debuglog } from 'node:util';
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import fs from 'node:fs';
|
|
6
|
-
import { ImportResolveError } from './error/index.js';
|
|
7
|
-
|
|
8
|
-
const debug = debuglog('@eggjs/utils/import');
|
|
9
|
-
|
|
10
|
-
export interface ImportResolveOptions {
|
|
11
|
-
paths?: string[];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface ImportModuleOptions extends ImportResolveOptions {
|
|
15
|
-
// only import export default object
|
|
16
|
-
importDefaultOnly?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const isESM = typeof require === 'undefined';
|
|
20
|
-
const nodeMajorVersion = parseInt(process.versions.node.split('.', 1)[0], 10);
|
|
21
|
-
const supportImportMetaResolve = nodeMajorVersion >= 18;
|
|
22
|
-
|
|
23
|
-
let _customRequire: NodeRequire;
|
|
24
|
-
function getRequire() {
|
|
25
|
-
if (!_customRequire) {
|
|
26
|
-
if (typeof require !== 'undefined') {
|
|
27
|
-
_customRequire = require;
|
|
28
|
-
} else {
|
|
29
|
-
_customRequire = createRequire(process.cwd());
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return _customRequire;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function getExtensions() {
|
|
36
|
-
return getRequire().extensions;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
let _supportTypeScript: boolean | undefined;
|
|
40
|
-
export function isSupportTypeScript() {
|
|
41
|
-
if (_supportTypeScript === undefined) {
|
|
42
|
-
const extensions = getExtensions();
|
|
43
|
-
// enable ts by process.env.EGG_TS_ENABLE or process.env.VITEST
|
|
44
|
-
_supportTypeScript = extensions['.ts'] !== undefined || process.env.VITEST === 'true' || process.env.EGG_TS_ENABLE === 'true';
|
|
45
|
-
debug('[isSupportTypeScript] %o, extensions: %j, process.env.VITEST: %j, process.env.EGG_TS_ENABLE: %j',
|
|
46
|
-
_supportTypeScript, Object.keys(extensions), process.env.VITEST, process.env.EGG_TS_ENABLE);
|
|
47
|
-
}
|
|
48
|
-
return _supportTypeScript;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function tryToResolveFromFile(filepath: string): string | undefined {
|
|
52
|
-
// "type": "module", try index.mjs then index.js
|
|
53
|
-
const type = isESM ? 'module' : 'commonjs';
|
|
54
|
-
let mainIndexFile = '';
|
|
55
|
-
if (type === 'module') {
|
|
56
|
-
mainIndexFile = filepath + '.mjs';
|
|
57
|
-
if (fs.existsSync(mainIndexFile)) {
|
|
58
|
-
debug('[tryToResolveFromFile] %o, use index.mjs, type: %o', mainIndexFile, type);
|
|
59
|
-
return mainIndexFile;
|
|
60
|
-
}
|
|
61
|
-
mainIndexFile = filepath + '.js';
|
|
62
|
-
if (fs.existsSync(mainIndexFile)) {
|
|
63
|
-
debug('[tryToResolveFromFile] %o, use index.js, type: %o', mainIndexFile, type);
|
|
64
|
-
return mainIndexFile;
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
// "type": "commonjs", try index.js then index.cjs
|
|
68
|
-
mainIndexFile = filepath + '.cjs';
|
|
69
|
-
if (fs.existsSync(mainIndexFile)) {
|
|
70
|
-
debug('[tryToResolveFromFile] %o, use index.cjs, type: %o', mainIndexFile, type);
|
|
71
|
-
return mainIndexFile;
|
|
72
|
-
}
|
|
73
|
-
mainIndexFile = filepath + '.js';
|
|
74
|
-
if (fs.existsSync(mainIndexFile)) {
|
|
75
|
-
debug('[tryToResolveFromFile] %o, use index.js, type: %o', mainIndexFile, type);
|
|
76
|
-
return mainIndexFile;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (!isSupportTypeScript()) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// for the module under development
|
|
85
|
-
mainIndexFile = filepath + '.ts';
|
|
86
|
-
if (fs.existsSync(mainIndexFile)) {
|
|
87
|
-
debug('[tryToResolveFromFile] %o, use index.ts, type: %o', mainIndexFile, type);
|
|
88
|
-
return mainIndexFile;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function tryToResolveByDirnameFromPackage(dirname: string, pkg: any): string | undefined {
|
|
93
|
-
// try to read pkg.main or pkg.module first
|
|
94
|
-
// "main": "./dist/commonjs/index.js",
|
|
95
|
-
// "module": "./dist/esm/index.js"
|
|
96
|
-
const defaultMainFile = isESM ? pkg.module ?? pkg.main : pkg.main;
|
|
97
|
-
if (defaultMainFile) {
|
|
98
|
-
const mainIndexFilePath = path.join(dirname, defaultMainFile);
|
|
99
|
-
if (fs.existsSync(mainIndexFilePath)) {
|
|
100
|
-
debug('[tryToResolveByDirnameFromPackage] %o, use pkg.main or pkg.module: %o, isESM: %s',
|
|
101
|
-
mainIndexFilePath, defaultMainFile, isESM);
|
|
102
|
-
return mainIndexFilePath;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// "type": "module", try index.mjs then index.js
|
|
107
|
-
const type = pkg?.type ?? (isESM ? 'module' : 'commonjs');
|
|
108
|
-
if (type === 'module') {
|
|
109
|
-
const mainIndexFilePath = path.join(dirname, 'index.mjs');
|
|
110
|
-
if (fs.existsSync(mainIndexFilePath)) {
|
|
111
|
-
debug('[tryToResolveByDirnameFromPackage] %o, use index.mjs, pkg.type: %o', mainIndexFilePath, type);
|
|
112
|
-
return mainIndexFilePath;
|
|
113
|
-
}
|
|
114
|
-
const mainIndexMjsFilePath = path.join(dirname, 'index.js');
|
|
115
|
-
if (fs.existsSync(mainIndexMjsFilePath)) {
|
|
116
|
-
debug('[tryToResolveByDirnameFromPackage] %o, use index.js, pkg.type: %o', mainIndexMjsFilePath, type);
|
|
117
|
-
return mainIndexMjsFilePath;
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
// "type": "commonjs", try index.cjs then index.js
|
|
121
|
-
const mainIndexFilePath = path.join(dirname, 'index.cjs');
|
|
122
|
-
if (fs.existsSync(mainIndexFilePath)) {
|
|
123
|
-
debug('[tryToResolveByDirnameFromPackage] %o, use index.cjs, pkg.type: %o', mainIndexFilePath, type);
|
|
124
|
-
return mainIndexFilePath;
|
|
125
|
-
}
|
|
126
|
-
const mainIndexCjsFilePath = path.join(dirname, 'index.js');
|
|
127
|
-
if (fs.existsSync(mainIndexCjsFilePath)) {
|
|
128
|
-
debug('[tryToResolveByDirnameFromPackage] %o, use index.js, pkg.type: %o', mainIndexCjsFilePath, type);
|
|
129
|
-
return mainIndexCjsFilePath;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (!isSupportTypeScript()) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// for the module under development
|
|
138
|
-
// "tshy": {
|
|
139
|
-
// "exports": {
|
|
140
|
-
// "./package.json": "./package.json",
|
|
141
|
-
// ".": "./src/index.ts"
|
|
142
|
-
// }
|
|
143
|
-
// }
|
|
144
|
-
const mainIndexFile = pkg.tshy?.exports?.['.'] ?? 'index.ts';
|
|
145
|
-
const mainIndexFilePath = path.join(dirname, mainIndexFile);
|
|
146
|
-
if (fs.existsSync(mainIndexFilePath)) {
|
|
147
|
-
return mainIndexFilePath;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function tryToResolveByDirname(dirname: string): string | undefined {
|
|
152
|
-
let pkg: any = {};
|
|
153
|
-
const pkgFile = path.join(dirname, 'package.json');
|
|
154
|
-
if (fs.existsSync(pkgFile)) {
|
|
155
|
-
pkg = JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
|
|
156
|
-
}
|
|
157
|
-
return tryToResolveByDirnameFromPackage(dirname, pkg);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function isRelativePath(filepath: string): boolean {
|
|
161
|
-
return filepath.startsWith('./')
|
|
162
|
-
|| filepath.startsWith('../')
|
|
163
|
-
|| filepath.startsWith('.\\')
|
|
164
|
-
|| filepath.startsWith('..\\');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function tryToResolveFromAbsoluteFile(filepath: string): string | undefined {
|
|
168
|
-
let moduleFilePath: string | undefined;
|
|
169
|
-
const stat = fs.statSync(filepath, { throwIfNoEntry: false });
|
|
170
|
-
// try to resolve from directory
|
|
171
|
-
if (stat?.isDirectory()) {
|
|
172
|
-
moduleFilePath = tryToResolveByDirname(filepath);
|
|
173
|
-
if (moduleFilePath) {
|
|
174
|
-
return moduleFilePath;
|
|
175
|
-
}
|
|
176
|
-
} else if (stat?.isFile()) {
|
|
177
|
-
return filepath;
|
|
178
|
-
}
|
|
179
|
-
// try to resolve from file
|
|
180
|
-
moduleFilePath = tryToResolveFromFile(filepath);
|
|
181
|
-
if (moduleFilePath) {
|
|
182
|
-
return moduleFilePath;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export function importResolve(filepath: string, options?: ImportResolveOptions) {
|
|
187
|
-
// find *.json or CommonJS module by require.resolve
|
|
188
|
-
// e.g.: importResolve('egg/package.json', { paths })
|
|
189
|
-
const cwd = process.cwd();
|
|
190
|
-
const paths = options?.paths ?? [ cwd ];
|
|
191
|
-
|
|
192
|
-
let moduleFilePath: string | undefined;
|
|
193
|
-
const isAbsolute = path.isAbsolute(filepath);
|
|
194
|
-
if (isAbsolute) {
|
|
195
|
-
moduleFilePath = tryToResolveFromAbsoluteFile(filepath);
|
|
196
|
-
if (moduleFilePath) {
|
|
197
|
-
debug('[importResolve:isAbsolute] %o => %o', filepath, moduleFilePath);
|
|
198
|
-
return moduleFilePath;
|
|
199
|
-
}
|
|
200
|
-
} else if (isRelativePath(filepath)) {
|
|
201
|
-
for (const p of paths) {
|
|
202
|
-
const resolvedPath = path.resolve(p, filepath);
|
|
203
|
-
moduleFilePath = tryToResolveFromAbsoluteFile(resolvedPath);
|
|
204
|
-
if (moduleFilePath) {
|
|
205
|
-
debug('[importResolve:isRelativePath] %o => %o => %o',
|
|
206
|
-
filepath, resolvedPath, moduleFilePath);
|
|
207
|
-
return moduleFilePath;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// find from node_modules
|
|
213
|
-
for (const p of paths) {
|
|
214
|
-
let resolvedPath = path.join(p, 'node_modules', filepath);
|
|
215
|
-
moduleFilePath = tryToResolveFromAbsoluteFile(resolvedPath);
|
|
216
|
-
if (moduleFilePath) {
|
|
217
|
-
debug('[importResolve:node_modules] %o => %o => %o',
|
|
218
|
-
filepath, resolvedPath, moduleFilePath);
|
|
219
|
-
return moduleFilePath;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// find from parent node_modules
|
|
223
|
-
// non-scoped package, e.g: node_modules/egg
|
|
224
|
-
let parentPath = path.dirname(p);
|
|
225
|
-
if (path.basename(parentPath) === 'node_modules') {
|
|
226
|
-
resolvedPath = path.join(parentPath, filepath);
|
|
227
|
-
moduleFilePath = tryToResolveFromAbsoluteFile(resolvedPath);
|
|
228
|
-
if (moduleFilePath) {
|
|
229
|
-
debug('[importResolve:node_modules] %o => %o => %o',
|
|
230
|
-
filepath, resolvedPath, moduleFilePath);
|
|
231
|
-
return moduleFilePath;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// scoped package, e.g: node_modules/@eggjs/tegg
|
|
236
|
-
parentPath = path.dirname(parentPath);
|
|
237
|
-
if (path.basename(parentPath) === 'node_modules') {
|
|
238
|
-
resolvedPath = path.join(parentPath, filepath);
|
|
239
|
-
moduleFilePath = tryToResolveFromAbsoluteFile(resolvedPath);
|
|
240
|
-
if (moduleFilePath) {
|
|
241
|
-
debug('[importResolve:node_modules] %o => %o => %o',
|
|
242
|
-
filepath, resolvedPath, moduleFilePath);
|
|
243
|
-
return moduleFilePath;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const extname = path.extname(filepath);
|
|
249
|
-
if ((!isAbsolute && extname === '.json') || !isESM) {
|
|
250
|
-
moduleFilePath = getRequire().resolve(filepath, {
|
|
251
|
-
paths,
|
|
252
|
-
});
|
|
253
|
-
} else {
|
|
254
|
-
if (supportImportMetaResolve) {
|
|
255
|
-
try {
|
|
256
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
257
|
-
// @ts-ignore
|
|
258
|
-
moduleFilePath = import.meta.resolve(filepath);
|
|
259
|
-
} catch (err) {
|
|
260
|
-
throw new ImportResolveError(filepath, paths, err as Error);
|
|
261
|
-
}
|
|
262
|
-
if (moduleFilePath.startsWith('file://')) {
|
|
263
|
-
// resolve will return file:// URL on Linux and MacOS expect on Windows
|
|
264
|
-
moduleFilePath = fileURLToPath(moduleFilePath);
|
|
265
|
-
}
|
|
266
|
-
debug('[importResolve] import.meta.resolve %o => %o', filepath, moduleFilePath);
|
|
267
|
-
const stat = fs.statSync(moduleFilePath, { throwIfNoEntry: false });
|
|
268
|
-
if (!stat?.isFile()) {
|
|
269
|
-
throw new TypeError(`Cannot find module ${filepath}, because ${moduleFilePath} does not exists`);
|
|
270
|
-
}
|
|
271
|
-
} else {
|
|
272
|
-
moduleFilePath = getRequire().resolve(filepath);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
debug('[importResolve] %o, options: %o => %o, isESM: %s',
|
|
276
|
-
filepath, options, moduleFilePath, isESM);
|
|
277
|
-
return moduleFilePath;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
export async function importModule(filepath: string, options?: ImportModuleOptions) {
|
|
281
|
-
const moduleFilePath = importResolve(filepath, options);
|
|
282
|
-
let obj: any;
|
|
283
|
-
if (isESM) {
|
|
284
|
-
// esm
|
|
285
|
-
const fileUrl = pathToFileURL(moduleFilePath).toString();
|
|
286
|
-
obj = await import(fileUrl);
|
|
287
|
-
debug('[importModule] await import %o', fileUrl);
|
|
288
|
-
// {
|
|
289
|
-
// default: { foo: 'bar', one: 1 },
|
|
290
|
-
// foo: 'bar',
|
|
291
|
-
// one: 1,
|
|
292
|
-
// [Symbol(Symbol.toStringTag)]: 'Module'
|
|
293
|
-
// }
|
|
294
|
-
if (obj?.default?.__esModule === true && 'default' in obj?.default) {
|
|
295
|
-
// 兼容 cjs 模拟 esm 的导出格式
|
|
296
|
-
// {
|
|
297
|
-
// __esModule: true,
|
|
298
|
-
// default: {
|
|
299
|
-
// __esModule: true,
|
|
300
|
-
// default: {
|
|
301
|
-
// fn: [Function: fn] { [length]: 0, [name]: 'fn' },
|
|
302
|
-
// foo: 'bar',
|
|
303
|
-
// one: 1
|
|
304
|
-
// }
|
|
305
|
-
// },
|
|
306
|
-
// [Symbol(Symbol.toStringTag)]: 'Module'
|
|
307
|
-
// }
|
|
308
|
-
// 兼容 ts module
|
|
309
|
-
// {
|
|
310
|
-
// default: {
|
|
311
|
-
// [__esModule]: true,
|
|
312
|
-
// default: <ref *1> [Function: default_1] {
|
|
313
|
-
// [length]: 0,
|
|
314
|
-
// [name]: 'default_1',
|
|
315
|
-
// [prototype]: { [constructor]: [Circular *1] }
|
|
316
|
-
// }
|
|
317
|
-
// },
|
|
318
|
-
// [Symbol(Symbol.toStringTag)]: 'Module'
|
|
319
|
-
// }
|
|
320
|
-
obj = obj.default;
|
|
321
|
-
}
|
|
322
|
-
if (options?.importDefaultOnly) {
|
|
323
|
-
if ('default' in obj) {
|
|
324
|
-
obj = obj.default;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
} else {
|
|
328
|
-
// commonjs
|
|
329
|
-
obj = require(moduleFilePath);
|
|
330
|
-
debug('[importModule] require %o', moduleFilePath);
|
|
331
|
-
if (obj?.__esModule === true && 'default' in obj) {
|
|
332
|
-
// 兼容 cjs 模拟 esm 的导出格式
|
|
333
|
-
// {
|
|
334
|
-
// __esModule: true,
|
|
335
|
-
// default: { fn: [Function: fn], foo: 'bar', one: 1 }
|
|
336
|
-
// }
|
|
337
|
-
obj = obj.default;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
if (debug.enabled) {
|
|
341
|
-
debug('[importModule] return %o => keys: %j', filepath, obj ? Object.keys(obj) : obj);
|
|
342
|
-
}
|
|
343
|
-
return obj;
|
|
344
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import { getFrameworkPath } from './framework.js';
|
|
4
|
-
import { getPlugins, getConfig, getLoadUnits } from './plugin.js';
|
|
5
|
-
import { getFrameworkOrEggPath } from './deprecated.js';
|
|
6
|
-
|
|
7
|
-
// support import { getFrameworkPath } from '@eggjs/utils'
|
|
8
|
-
export { getFrameworkPath } from './framework.js';
|
|
9
|
-
export { getPlugins, getConfig, getLoadUnits } from './plugin.js';
|
|
10
|
-
export { getFrameworkOrEggPath } from './deprecated.js';
|
|
11
|
-
export * from './import.js';
|
|
12
|
-
export * from './error/index.js';
|
|
13
|
-
|
|
14
|
-
// support import utils from '@eggjs/utils'
|
|
15
|
-
export default {
|
|
16
|
-
getFrameworkPath,
|
|
17
|
-
getPlugins, getConfig, getLoadUnits,
|
|
18
|
-
getFrameworkOrEggPath,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export enum EggType {
|
|
22
|
-
framework = 'framework',
|
|
23
|
-
plugin = 'plugin',
|
|
24
|
-
application = 'application',
|
|
25
|
-
unknown = 'unknown',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Detect the type of egg project
|
|
30
|
-
*/
|
|
31
|
-
export async function detectType(baseDir: string): Promise<EggType> {
|
|
32
|
-
const pkgFile = path.join(baseDir, 'package.json');
|
|
33
|
-
let pkg: {
|
|
34
|
-
egg?: {
|
|
35
|
-
framework?: boolean;
|
|
36
|
-
};
|
|
37
|
-
eggPlugin?: {
|
|
38
|
-
name: string;
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
try {
|
|
42
|
-
await fs.access(pkgFile);
|
|
43
|
-
} catch {
|
|
44
|
-
return EggType.unknown;
|
|
45
|
-
}
|
|
46
|
-
try {
|
|
47
|
-
pkg = JSON.parse(await fs.readFile(pkgFile, 'utf-8'));
|
|
48
|
-
} catch {
|
|
49
|
-
return EggType.unknown;
|
|
50
|
-
}
|
|
51
|
-
if (pkg.egg?.framework) {
|
|
52
|
-
return EggType.framework;
|
|
53
|
-
}
|
|
54
|
-
if (pkg.eggPlugin?.name) {
|
|
55
|
-
return EggType.plugin;
|
|
56
|
-
}
|
|
57
|
-
return EggType.application;
|
|
58
|
-
}
|
package/src/plugin.ts
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { debuglog } from 'node:util';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import assert from 'node:assert';
|
|
4
|
-
import os from 'node:os';
|
|
5
|
-
import { stat, mkdir, writeFile, realpath } from 'node:fs/promises';
|
|
6
|
-
import { importModule } from './import.js';
|
|
7
|
-
|
|
8
|
-
const debug = debuglog('@eggjs/utils/plugin');
|
|
9
|
-
|
|
10
|
-
const tmpDir = os.tmpdir();
|
|
11
|
-
|
|
12
|
-
function noop() {}
|
|
13
|
-
|
|
14
|
-
const logger = {
|
|
15
|
-
debug: noop,
|
|
16
|
-
info: noop,
|
|
17
|
-
warn: noop,
|
|
18
|
-
error: noop,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export interface LoaderOptions {
|
|
22
|
-
framework: string;
|
|
23
|
-
baseDir: string;
|
|
24
|
-
env?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface Plugin {
|
|
28
|
-
name: string;
|
|
29
|
-
version?: string;
|
|
30
|
-
enable: boolean;
|
|
31
|
-
implicitEnable: boolean;
|
|
32
|
-
path: string;
|
|
33
|
-
dependencies: string[];
|
|
34
|
-
optionalDependencies: string[];
|
|
35
|
-
env: string[];
|
|
36
|
-
from: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @see https://github.com/eggjs/egg-core/blob/2920f6eade07959d25f5c4f96b154d3fbae877db/lib/loader/mixin/plugin.js#L203
|
|
41
|
-
*/
|
|
42
|
-
export async function getPlugins(options: LoaderOptions) {
|
|
43
|
-
const loader = await getLoader(options);
|
|
44
|
-
await loader.loadPlugin();
|
|
45
|
-
return loader.allPlugins;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
interface Unit {
|
|
49
|
-
type: 'plugin' | 'framework' | 'app';
|
|
50
|
-
path: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @see https://github.com/eggjs/egg-core/blob/2920f6eade07959d25f5c4f96b154d3fbae877db/lib/loader/egg_loader.js#L348
|
|
55
|
-
*/
|
|
56
|
-
export async function getLoadUnits(options: LoaderOptions) {
|
|
57
|
-
const loader = await getLoader(options);
|
|
58
|
-
await loader.loadPlugin();
|
|
59
|
-
return loader.getLoadUnits();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export async function getConfig(options: LoaderOptions) {
|
|
63
|
-
const loader = await getLoader(options);
|
|
64
|
-
await loader.loadPlugin();
|
|
65
|
-
await loader.loadConfig();
|
|
66
|
-
return loader.config;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function exists(filepath: string) {
|
|
70
|
-
try {
|
|
71
|
-
await stat(filepath);
|
|
72
|
-
return true;
|
|
73
|
-
} catch {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
interface IEggLoader {
|
|
79
|
-
loadPlugin(): Promise<void>;
|
|
80
|
-
loadConfig(): Promise<void>;
|
|
81
|
-
config: Record<string, any>;
|
|
82
|
-
getLoadUnits(): Unit[];
|
|
83
|
-
allPlugins: Record<string, Plugin>;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
interface IEggLoaderOptions {
|
|
87
|
-
baseDir: string;
|
|
88
|
-
app: unknown;
|
|
89
|
-
logger: object;
|
|
90
|
-
EggCoreClass?: unknown;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
type EggLoaderImplClass<T = IEggLoader> = new(options: IEggLoaderOptions) => T;
|
|
94
|
-
|
|
95
|
-
async function getLoader(options: LoaderOptions) {
|
|
96
|
-
assert(options.framework, 'framework is required');
|
|
97
|
-
assert(await exists(options.framework), `${options.framework} should exist`);
|
|
98
|
-
if (!(options.baseDir && await exists(options.baseDir))) {
|
|
99
|
-
options.baseDir = path.join(tmpDir, 'egg_utils', `${Date.now()}`, 'tmp_app');
|
|
100
|
-
await mkdir(options.baseDir, { recursive: true });
|
|
101
|
-
await writeFile(path.join(options.baseDir, 'package.json'), JSON.stringify({
|
|
102
|
-
name: 'tmp_app',
|
|
103
|
-
}));
|
|
104
|
-
debug('[getLoader] create baseDir: %o', options.baseDir);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const { EggCore, EggLoader } = await findEggCore(options);
|
|
108
|
-
const mod = await importModule(options.framework);
|
|
109
|
-
const Application = mod.Application ?? mod.default?.Application;
|
|
110
|
-
assert(Application, `Application not export on ${options.framework}`);
|
|
111
|
-
if (options.env) {
|
|
112
|
-
process.env.EGG_SERVER_ENV = options.env;
|
|
113
|
-
}
|
|
114
|
-
return new EggLoader({
|
|
115
|
-
baseDir: options.baseDir,
|
|
116
|
-
logger,
|
|
117
|
-
app: Object.create(Application.prototype),
|
|
118
|
-
EggCoreClass: EggCore,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async function findEggCore(options: LoaderOptions): Promise<{ EggCore?: object; EggLoader: EggLoaderImplClass }> {
|
|
123
|
-
const baseDirRealpath = await realpath(options.baseDir);
|
|
124
|
-
const frameworkRealpath = await realpath(options.framework);
|
|
125
|
-
const paths = [ frameworkRealpath, baseDirRealpath ];
|
|
126
|
-
// custom framework => egg => @eggjs/core
|
|
127
|
-
try {
|
|
128
|
-
const { EggCore, EggLoader } = await importModule('egg', { paths });
|
|
129
|
-
if (EggLoader) {
|
|
130
|
-
return { EggCore, EggLoader };
|
|
131
|
-
}
|
|
132
|
-
} catch (err: any) {
|
|
133
|
-
debug('[findEggCore] import "egg" from paths:%o error: %o', paths, err);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// egg-core 在 6.2.3 版本中更名为 @eggjs/core,为兼容老版本,支持同时查找两个包,优先使用新名字
|
|
137
|
-
const names = [ '@eggjs/core', 'egg-core' ];
|
|
138
|
-
for (const name of names) {
|
|
139
|
-
try {
|
|
140
|
-
const { EggCore, EggLoader } = await importModule(name, { paths });
|
|
141
|
-
if (EggLoader) {
|
|
142
|
-
return { EggCore, EggLoader };
|
|
143
|
-
}
|
|
144
|
-
} catch (err: any) {
|
|
145
|
-
debug('[findEggCore] import "%s" from paths:%o error: %o', name, paths, err);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
const { EggCore, EggLoader } = await importModule(name);
|
|
150
|
-
if (EggLoader) {
|
|
151
|
-
return { EggCore, EggLoader };
|
|
152
|
-
}
|
|
153
|
-
} catch (err: any) {
|
|
154
|
-
debug('[findEggCore] import "%s" error: %o', name, err);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
let eggCorePath = path.join(options.baseDir, `node_modules/${name}`);
|
|
158
|
-
if (!(await exists(eggCorePath))) {
|
|
159
|
-
eggCorePath = path.join(options.framework, `node_modules/${name}`);
|
|
160
|
-
}
|
|
161
|
-
if (await exists(eggCorePath)) {
|
|
162
|
-
return await importModule(eggCorePath);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
assert(false, `Can't find ${names.join(' or ')} from ${options.baseDir} and ${options.framework}`);
|
|
167
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { fileURLToPath } from 'node:url';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
|
|
5
|
-
export function readJSONSync(file: string) {
|
|
6
|
-
if (!existsSync(file)) {
|
|
7
|
-
throw new Error(`${file} is not found`);
|
|
8
|
-
}
|
|
9
|
-
return JSON.parse(readFileSync(file, 'utf-8'));
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function getDirname() {
|
|
13
|
-
if (typeof __dirname !== 'undefined') {
|
|
14
|
-
return __dirname;
|
|
15
|
-
}
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
return path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
-
}
|