1
+ import type { HardhatPlugin } from "../../types/plugins.js" ;
2
+
1
3
import { HardhatError } from "@nomicfoundation/hardhat-errors" ;
4
+ import { ensureError } from "@nomicfoundation/hardhat-utils/error" ;
2
5
3
- import { HardhatPlugin } from "../../types/plugins .js" ;
6
+ import { validatePluginNpmDependencies } from "./plugin-validation .js" ;
4
7
5
8
/**
6
9
* Resolves the plugin list, returning them in the right order.
7
10
*/
8
- export function resolvePluginList (
11
+ export async function resolvePluginList (
9
12
userConfigPluginList : HardhatPlugin [ ] = [ ] ,
10
- ) : HardhatPlugin [ ] {
11
- return reverseTopologicalSort ( userConfigPluginList ) ;
13
+ basePathForNpmResolution : string ,
14
+ ) : Promise < HardhatPlugin [ ] > {
15
+ return reverseTopologicalSort ( userConfigPluginList , basePathForNpmResolution ) ;
12
16
}
13
17
14
18
/**
@@ -19,13 +23,14 @@ export function resolvePluginList(
19
23
* @param plugins The plugins.
20
24
* @returns The ordered plugins.
21
25
*/
22
- export function reverseTopologicalSort (
26
+ async function reverseTopologicalSort (
23
27
plugins : HardhatPlugin [ ] ,
24
- ) : HardhatPlugin [ ] {
28
+ basePathForNpmResolution : string ,
29
+ ) : Promise < HardhatPlugin [ ] > {
25
30
const visitedPlugins : Map < string , HardhatPlugin > = new Map ( ) ;
26
31
const result : HardhatPlugin [ ] = [ ] ;
27
32
28
- function dfs ( plugin : HardhatPlugin ) {
33
+ async function dfs ( plugin : HardhatPlugin ) {
29
34
const visited = visitedPlugins . get ( plugin . id ) ;
30
35
31
36
if ( visited !== undefined ) {
@@ -42,17 +47,54 @@ export function reverseTopologicalSort(
42
47
visitedPlugins . set ( plugin . id , plugin ) ;
43
48
44
49
if ( plugin . dependencies !== undefined ) {
45
- for ( const dependency of plugin . dependencies ) {
46
- dfs ( dependency ) ;
50
+ for ( const loadFn of plugin . dependencies ) {
51
+ const dependency = await loadDependency (
52
+ plugin ,
53
+ loadFn ,
54
+ basePathForNpmResolution ,
55
+ ) ;
56
+
57
+ await dfs ( dependency ) ;
47
58
}
48
59
}
49
60
50
61
result . push ( plugin ) ;
51
62
}
52
63
53
64
for ( const plugin of plugins ) {
54
- dfs ( plugin ) ;
65
+ await dfs ( plugin ) ;
55
66
}
56
67
57
68
return result ;
58
69
}
70
+
71
+ /**
72
+ * Attempt to load a plugins dependency. If there is an error,
73
+ * first try and validate the npm dependencies of the plugin.
74
+ *
75
+ * @param plugin - the plugin has the dependency
76
+ * @param loadFn - the load function for the dependency
77
+ * @param basePathForNpmResolution - the directory path to use for node module resolution
78
+ * @returns the loaded plugin
79
+ */
80
+ async function loadDependency (
81
+ plugin : HardhatPlugin ,
82
+ loadFn : ( ) => Promise < HardhatPlugin > ,
83
+ basePathForNpmResolution : string ,
84
+ ) : Promise < HardhatPlugin > {
85
+ try {
86
+ return await loadFn ( ) ;
87
+ } catch ( error ) {
88
+ ensureError ( error ) ;
89
+
90
+ await validatePluginNpmDependencies ( plugin , basePathForNpmResolution ) ;
91
+
92
+ throw new HardhatError (
93
+ HardhatError . ERRORS . PLUGINS . PLUGIN_DEPENDENCY_FAILED_LOAD ,
94
+ {
95
+ pluginId : plugin . id ,
96
+ } ,
97
+ error ,
98
+ ) ;
99
+ }
100
+ }
0 commit comments