@yumerijs/loader 3.1.2 → 3.1.3
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/index.d.ts +2 -0
- package/dist/index.js +43 -12
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,8 @@ export declare class PluginLoader {
|
|
|
63
63
|
private isNpxInvocation;
|
|
64
64
|
private detectPackageManager;
|
|
65
65
|
private confirmPluginInstall;
|
|
66
|
+
private isPluginModuleResolvable;
|
|
67
|
+
private installMissingPluginModules;
|
|
66
68
|
private installMissingPlugin;
|
|
67
69
|
private importPluginModule;
|
|
68
70
|
loadModule(pluginName: string): Promise<Plugin>;
|
package/dist/index.js
CHANGED
|
@@ -153,6 +153,8 @@ export class PluginLoader {
|
|
|
153
153
|
this.logger.info('No enabled plugins found in configuration.');
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
|
+
// Resolve and install every configured plugin before any plugin module is loaded.
|
|
157
|
+
await this.installMissingPluginModules(allEntries.filter(entry => entry.enabled));
|
|
156
158
|
// 第一阶段:将 optional 与 depend 一样处理,尽量让可选服务先完成加载并注入。
|
|
157
159
|
while (await this._loadPendingPlugins(true)) {
|
|
158
160
|
// Continue scanning until no plugin can satisfy all required and optional dependencies.
|
|
@@ -414,7 +416,36 @@ export class PluginLoader {
|
|
|
414
416
|
readline.close();
|
|
415
417
|
}
|
|
416
418
|
}
|
|
419
|
+
isPluginModuleResolvable(moduleName) {
|
|
420
|
+
try {
|
|
421
|
+
import.meta.resolve(moduleName);
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
if (this.isMissingModuleError(error, moduleName))
|
|
426
|
+
return false;
|
|
427
|
+
throw error;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
async installMissingPluginModules(entries) {
|
|
431
|
+
const missingModules = [...new Set(entries.map(entry => entry.moduleName))]
|
|
432
|
+
.filter(moduleName => !this.isPluginModuleResolvable(moduleName));
|
|
433
|
+
for (const moduleName of missingModules) {
|
|
434
|
+
const shouldInstall = await this.confirmPluginInstall(moduleName);
|
|
435
|
+
if (!shouldInstall)
|
|
436
|
+
continue;
|
|
437
|
+
try {
|
|
438
|
+
await this.installMissingPlugin(moduleName);
|
|
439
|
+
}
|
|
440
|
+
catch (error) {
|
|
441
|
+
this.logger.error(`Failed to install missing plugin "${moduleName}":`, error);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
417
445
|
async installMissingPlugin(moduleName) {
|
|
446
|
+
if (!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/i.test(moduleName)) {
|
|
447
|
+
throw new Error(`Cannot automatically install invalid package name "${moduleName}".`);
|
|
448
|
+
}
|
|
418
449
|
const packageManager = this.detectPackageManager();
|
|
419
450
|
const global = this.isNpxInvocation();
|
|
420
451
|
const argsByManager = {
|
|
@@ -427,21 +458,21 @@ export class PluginLoader {
|
|
|
427
458
|
const command = process.platform === 'win32' ? `${packageManager}.cmd` : packageManager;
|
|
428
459
|
this.logger.info(`Installing missing plugin "${moduleName}" with ${command} ${args.join(' ')}` +
|
|
429
460
|
(global ? ' (global)' : ''));
|
|
461
|
+
// Windows command shims (for example npm.cmd) require cmd.exe; execFile
|
|
462
|
+
// otherwise fails before the package manager can start with spawn EINVAL.
|
|
463
|
+
if (process.platform === 'win32') {
|
|
464
|
+
await execFileAsync(process.env.ComSpec || 'cmd.exe', [
|
|
465
|
+
'/d',
|
|
466
|
+
'/s',
|
|
467
|
+
'/c',
|
|
468
|
+
`${command} ${args.join(' ')}`,
|
|
469
|
+
], { cwd: process.cwd() });
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
430
472
|
await execFileAsync(command, args, { cwd: process.cwd() });
|
|
431
473
|
}
|
|
432
474
|
async importPluginModule(moduleName) {
|
|
433
|
-
|
|
434
|
-
return await import(moduleName);
|
|
435
|
-
}
|
|
436
|
-
catch (error) {
|
|
437
|
-
if (!this.isMissingModuleError(error, moduleName))
|
|
438
|
-
throw error;
|
|
439
|
-
const shouldInstall = await this.confirmPluginInstall(moduleName);
|
|
440
|
-
if (!shouldInstall)
|
|
441
|
-
throw error;
|
|
442
|
-
await this.installMissingPlugin(moduleName);
|
|
443
|
-
return await import(moduleName);
|
|
444
|
-
}
|
|
475
|
+
return await import(moduleName);
|
|
445
476
|
}
|
|
446
477
|
async loadModule(pluginName) {
|
|
447
478
|
const entry = this.getPluginEntry(pluginName);
|