hardhat 3.0.0-next.2 → 3.0.0-next.20

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.
Files changed (702) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/coverage.sol +38 -0
  3. package/dist/src/hre.d.ts +2 -1
  4. package/dist/src/hre.d.ts.map +1 -1
  5. package/dist/src/hre.js +2 -1
  6. package/dist/src/hre.js.map +1 -1
  7. package/dist/src/index.js +1 -1
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/internal/builtin-global-options.js +2 -2
  10. package/dist/src/internal/builtin-global-options.js.map +1 -1
  11. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts +2 -2
  12. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts.map +1 -1
  13. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.js +7 -4
  14. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.js.map +1 -1
  15. package/dist/src/internal/builtin-plugins/clean/index.d.ts +1 -0
  16. package/dist/src/internal/builtin-plugins/clean/index.d.ts.map +1 -1
  17. package/dist/src/internal/builtin-plugins/clean/index.js +1 -0
  18. package/dist/src/internal/builtin-plugins/clean/index.js.map +1 -1
  19. package/dist/src/internal/builtin-plugins/clean/task-action.d.ts.map +1 -1
  20. package/dist/src/internal/builtin-plugins/clean/task-action.js +2 -1
  21. package/dist/src/internal/builtin-plugins/clean/task-action.js.map +1 -1
  22. package/dist/src/internal/builtin-plugins/clean/type-extensions.d.ts +10 -0
  23. package/dist/src/internal/builtin-plugins/clean/type-extensions.d.ts.map +1 -0
  24. package/dist/src/internal/builtin-plugins/clean/type-extensions.js +2 -0
  25. package/dist/src/internal/builtin-plugins/clean/type-extensions.js.map +1 -0
  26. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.d.ts +37 -0
  27. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.d.ts.map +1 -0
  28. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js +364 -0
  29. package/dist/src/internal/builtin-plugins/coverage/coverage-manager.js.map +1 -0
  30. package/dist/src/internal/builtin-plugins/coverage/exports.d.ts +2 -0
  31. package/dist/src/internal/builtin-plugins/coverage/exports.d.ts.map +1 -0
  32. package/dist/src/internal/builtin-plugins/coverage/exports.js +2 -0
  33. package/dist/src/internal/builtin-plugins/coverage/exports.js.map +1 -0
  34. package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts +12 -0
  35. package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts.map +1 -0
  36. package/dist/src/internal/builtin-plugins/coverage/helpers.js +35 -0
  37. package/dist/src/internal/builtin-plugins/coverage/helpers.js.map +1 -0
  38. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/clean.d.ts +4 -0
  39. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/clean.d.ts.map +1 -0
  40. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/clean.js +9 -0
  41. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/clean.js.map +1 -0
  42. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.d.ts +4 -0
  43. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.d.ts.map +1 -0
  44. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.js +24 -0
  45. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/hre.js.map +1 -0
  46. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.d.ts +4 -0
  47. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.d.ts.map +1 -0
  48. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js +89 -0
  49. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js.map +1 -0
  50. package/dist/src/internal/builtin-plugins/coverage/index.d.ts +1 -0
  51. package/dist/src/internal/builtin-plugins/coverage/index.d.ts.map +1 -1
  52. package/dist/src/internal/builtin-plugins/coverage/index.js +17 -6
  53. package/dist/src/internal/builtin-plugins/coverage/index.js.map +1 -1
  54. package/dist/src/internal/builtin-plugins/coverage/type-extensions.d.ts +7 -0
  55. package/dist/src/internal/builtin-plugins/coverage/type-extensions.d.ts.map +1 -0
  56. package/dist/src/internal/builtin-plugins/coverage/type-extensions.js +2 -0
  57. package/dist/src/internal/builtin-plugins/coverage/type-extensions.js.map +1 -0
  58. package/dist/src/internal/builtin-plugins/coverage/types.d.ts +19 -0
  59. package/dist/src/internal/builtin-plugins/coverage/types.d.ts.map +1 -0
  60. package/dist/src/internal/builtin-plugins/coverage/types.js +2 -0
  61. package/dist/src/internal/builtin-plugins/coverage/types.js.map +1 -0
  62. package/dist/src/internal/builtin-plugins/flatten/task-action.d.ts.map +1 -1
  63. package/dist/src/internal/builtin-plugins/flatten/task-action.js +17 -9
  64. package/dist/src/internal/builtin-plugins/flatten/task-action.js.map +1 -1
  65. package/dist/src/internal/builtin-plugins/index.d.ts +1 -1
  66. package/dist/src/internal/builtin-plugins/index.d.ts.map +1 -1
  67. package/dist/src/internal/builtin-plugins/index.js +2 -2
  68. package/dist/src/internal/builtin-plugins/index.js.map +1 -1
  69. package/dist/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.js +2 -2
  70. package/dist/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.js.map +1 -1
  71. package/dist/src/internal/builtin-plugins/network-manager/base-provider.d.ts.map +1 -1
  72. package/dist/src/internal/builtin-plugins/network-manager/base-provider.js +2 -8
  73. package/dist/src/internal/builtin-plugins/network-manager/base-provider.js.map +1 -1
  74. package/dist/src/internal/builtin-plugins/network-manager/chain-descriptors.d.ts +3 -0
  75. package/dist/src/internal/builtin-plugins/network-manager/chain-descriptors.d.ts.map +1 -0
  76. package/dist/src/internal/builtin-plugins/network-manager/chain-descriptors.js +550 -0
  77. package/dist/src/internal/builtin-plugins/network-manager/chain-descriptors.js.map +1 -0
  78. package/dist/src/internal/builtin-plugins/network-manager/config-override.d.ts +0 -12
  79. package/dist/src/internal/builtin-plugins/network-manager/config-override.d.ts.map +1 -1
  80. package/dist/src/internal/builtin-plugins/network-manager/config-override.js +0 -31
  81. package/dist/src/internal/builtin-plugins/network-manager/config-override.js.map +1 -1
  82. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.d.ts +4 -15
  83. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.d.ts.map +1 -1
  84. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js +35 -184
  85. package/dist/src/internal/builtin-plugins/network-manager/config-resolution.js.map +1 -1
  86. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-context.js +2 -2
  87. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-context.js.map +1 -1
  88. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts +7 -3
  89. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
  90. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +51 -21
  91. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
  92. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.d.ts.map +1 -1
  93. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.js +7 -1
  94. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.js.map +1 -1
  95. package/dist/src/internal/builtin-plugins/network-manager/edr/types/coverage.d.ts +4 -0
  96. package/dist/src/internal/builtin-plugins/network-manager/edr/types/coverage.d.ts.map +1 -0
  97. package/dist/src/internal/builtin-plugins/network-manager/edr/types/coverage.js +2 -0
  98. package/dist/src/internal/builtin-plugins/network-manager/edr/types/coverage.js.map +1 -0
  99. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.d.ts +20 -4
  100. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.d.ts.map +1 -1
  101. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.js +79 -25
  102. package/dist/src/internal/builtin-plugins/network-manager/edr/types/hardfork.js.map +1 -1
  103. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts +10 -9
  104. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts.map +1 -1
  105. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +82 -85
  106. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
  107. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/hardfork.d.ts +3 -2
  108. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/hardfork.d.ts.map +1 -1
  109. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/hardfork.js +9 -4
  110. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/hardfork.js.map +1 -1
  111. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/config.d.ts.map +1 -1
  112. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/config.js +3 -2
  113. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/config.js.map +1 -1
  114. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/hre.js +5 -4
  115. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/hre.js.map +1 -1
  116. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/network.js +2 -2
  117. package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/network.js.map +1 -1
  118. package/dist/src/internal/builtin-plugins/network-manager/http-provider.d.ts.map +1 -1
  119. package/dist/src/internal/builtin-plugins/network-manager/http-provider.js +4 -4
  120. package/dist/src/internal/builtin-plugins/network-manager/http-provider.js.map +1 -1
  121. package/dist/src/internal/builtin-plugins/network-manager/index.d.ts.map +1 -1
  122. package/dist/src/internal/builtin-plugins/network-manager/index.js +3 -1
  123. package/dist/src/internal/builtin-plugins/network-manager/index.js.map +1 -1
  124. package/dist/src/internal/builtin-plugins/network-manager/json-rpc.d.ts.map +1 -1
  125. package/dist/src/internal/builtin-plugins/network-manager/json-rpc.js +2 -2
  126. package/dist/src/internal/builtin-plugins/network-manager/json-rpc.js.map +1 -1
  127. package/dist/src/internal/builtin-plugins/network-manager/network-manager.d.ts +4 -4
  128. package/dist/src/internal/builtin-plugins/network-manager/network-manager.d.ts.map +1 -1
  129. package/dist/src/internal/builtin-plugins/network-manager/network-manager.js +47 -14
  130. package/dist/src/internal/builtin-plugins/network-manager/network-manager.js.map +1 -1
  131. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/hd-wallet-handler.d.ts +4 -0
  132. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/hd-wallet-handler.d.ts.map +1 -1
  133. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/hd-wallet-handler.js +4 -0
  134. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/hd-wallet-handler.js.map +1 -1
  135. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.d.ts.map +1 -1
  136. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.js +73 -48
  137. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.js.map +1 -1
  138. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/sender.js +1 -1
  139. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/sender.js.map +1 -1
  140. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/chain-id/chain-id-handler.js +1 -1
  141. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers/chain-id/chain-id-handler.js.map +1 -1
  142. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.d.ts +3 -0
  143. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.d.ts.map +1 -1
  144. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.js +3 -0
  145. package/dist/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.js.map +1 -1
  146. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/authorization-list.d.ts +14 -0
  147. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/authorization-list.d.ts.map +1 -0
  148. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/authorization-list.js +15 -0
  149. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/authorization-list.js.map +1 -0
  150. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/rpc-parity.d.ts +3 -0
  151. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/rpc-parity.d.ts.map +1 -0
  152. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/rpc-parity.js +15 -0
  153. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/rpc-parity.js.map +1 -0
  154. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/tx-request.d.ts +8 -0
  155. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/tx-request.d.ts.map +1 -1
  156. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/tx-request.js +2 -0
  157. package/dist/src/internal/builtin-plugins/network-manager/rpc/types/tx-request.js.map +1 -1
  158. package/dist/src/internal/builtin-plugins/network-manager/rpc/validate-params.js +3 -3
  159. package/dist/src/internal/builtin-plugins/network-manager/rpc/validate-params.js.map +1 -1
  160. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts +56 -12
  161. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/config.d.ts.map +1 -1
  162. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.d.ts +8 -0
  163. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.d.ts.map +1 -1
  164. package/dist/src/internal/builtin-plugins/network-manager/type-extensions/hooks.js.map +1 -1
  165. package/dist/src/internal/builtin-plugins/network-manager/type-validation.d.ts.map +1 -1
  166. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js +141 -36
  167. package/dist/src/internal/builtin-plugins/network-manager/type-validation.js.map +1 -1
  168. package/dist/src/internal/builtin-plugins/node/index.d.ts.map +1 -1
  169. package/dist/src/internal/builtin-plugins/node/index.js +6 -3
  170. package/dist/src/internal/builtin-plugins/node/index.js.map +1 -1
  171. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.d.ts.map +1 -1
  172. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js +1 -0
  173. package/dist/src/internal/builtin-plugins/node/json-rpc/handler.js.map +1 -1
  174. package/dist/src/internal/builtin-plugins/node/task-action.d.ts.map +1 -1
  175. package/dist/src/internal/builtin-plugins/node/task-action.js +12 -9
  176. package/dist/src/internal/builtin-plugins/node/task-action.js.map +1 -1
  177. package/dist/src/internal/builtin-plugins/run/task-action.js +1 -1
  178. package/dist/src/internal/builtin-plugins/run/task-action.js.map +1 -1
  179. package/dist/src/internal/builtin-plugins/solidity/build-results.d.ts +0 -20
  180. package/dist/src/internal/builtin-plugins/solidity/build-results.d.ts.map +1 -1
  181. package/dist/src/internal/builtin-plugins/solidity/build-results.js +3 -69
  182. package/dist/src/internal/builtin-plugins/solidity/build-results.js.map +1 -1
  183. package/dist/src/internal/builtin-plugins/solidity/build-system/artifacts.d.ts +1 -1
  184. package/dist/src/internal/builtin-plugins/solidity/build-system/artifacts.d.ts.map +1 -1
  185. package/dist/src/internal/builtin-plugins/solidity/build-system/artifacts.js +13 -7
  186. package/dist/src/internal/builtin-plugins/solidity/build-system/artifacts.js.map +1 -1
  187. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
  188. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +56 -35
  189. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
  190. package/dist/src/internal/builtin-plugins/solidity/build-system/cache.d.ts +5 -0
  191. package/dist/src/internal/builtin-plugins/solidity/build-system/cache.d.ts.map +1 -1
  192. package/dist/src/internal/builtin-plugins/solidity/build-system/cache.js +10 -3
  193. package/dist/src/internal/builtin-plugins/solidity/build-system/cache.js.map +1 -1
  194. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job.d.ts +3 -3
  195. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job.d.ts.map +1 -1
  196. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job.js +88 -65
  197. package/dist/src/internal/builtin-plugins/solidity/build-system/compilation-job.js.map +1 -1
  198. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.d.ts +2 -2
  199. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.d.ts.map +1 -1
  200. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js +74 -44
  201. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js.map +1 -1
  202. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.d.ts.map +1 -1
  203. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.js +5 -4
  204. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.js.map +1 -1
  205. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/index.d.ts.map +1 -1
  206. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/index.js +1 -1
  207. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/index.js.map +1 -1
  208. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-runner.js +2 -1
  209. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-runner.js.map +1 -1
  210. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.js +1 -1
  211. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.js.map +1 -1
  212. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph-building.d.ts +1 -5
  213. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph-building.d.ts.map +1 -1
  214. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph-building.js +39 -8
  215. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph-building.js.map +1 -1
  216. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.d.ts +19 -7
  217. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.d.ts.map +1 -1
  218. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.js +93 -36
  219. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.js.map +1 -1
  220. package/dist/src/internal/builtin-plugins/solidity/build-system/read-source-file.d.ts +3 -0
  221. package/dist/src/internal/builtin-plugins/solidity/build-system/read-source-file.d.ts.map +1 -0
  222. package/dist/src/internal/builtin-plugins/solidity/build-system/read-source-file.js +7 -0
  223. package/dist/src/internal/builtin-plugins/solidity/build-system/read-source-file.js.map +1 -0
  224. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts +19 -26
  225. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts.map +1 -1
  226. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.js +647 -922
  227. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.js.map +1 -1
  228. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/error-messages.d.ts +5 -0
  229. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/error-messages.d.ts.map +1 -0
  230. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/error-messages.js +153 -0
  231. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/error-messages.js.map +1 -0
  232. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/npm-module-parsing.d.ts +23 -0
  233. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/npm-module-parsing.d.ts.map +1 -0
  234. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/npm-module-parsing.js +37 -0
  235. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/npm-module-parsing.js.map +1 -0
  236. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts +31 -0
  237. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts.map +1 -0
  238. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js +411 -0
  239. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js.map +1 -0
  240. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remappings.d.ts +9 -1
  241. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remappings.d.ts.map +1 -1
  242. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remappings.js +15 -6
  243. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remappings.js.map +1 -1
  244. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/source-name-utils.d.ts +25 -0
  245. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/source-name-utils.d.ts.map +1 -0
  246. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/source-name-utils.js +38 -0
  247. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/source-name-utils.js.map +1 -0
  248. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.d.ts +183 -55
  249. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.d.ts.map +1 -1
  250. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.js +8 -1
  251. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.js.map +1 -1
  252. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts +20 -0
  253. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts.map +1 -0
  254. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.js +62 -0
  255. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.js.map +1 -0
  256. package/dist/src/internal/builtin-plugins/solidity/build-system/root-paths-utils.d.ts +2 -2
  257. package/dist/src/internal/builtin-plugins/solidity/build-system/root-paths-utils.d.ts.map +1 -1
  258. package/dist/src/internal/builtin-plugins/solidity/build-system/root-paths-utils.js +4 -4
  259. package/dist/src/internal/builtin-plugins/solidity/build-system/root-paths-utils.js.map +1 -1
  260. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.d.ts.map +1 -1
  261. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.js +11 -9
  262. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.js.map +1 -1
  263. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.d.ts.map +1 -1
  264. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.js +2 -0
  265. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-info.js.map +1 -1
  266. package/dist/src/internal/builtin-plugins/solidity/config.d.ts.map +1 -1
  267. package/dist/src/internal/builtin-plugins/solidity/config.js +4 -9
  268. package/dist/src/internal/builtin-plugins/solidity/config.js.map +1 -1
  269. package/dist/src/internal/builtin-plugins/solidity/index.d.ts.map +1 -1
  270. package/dist/src/internal/builtin-plugins/solidity/index.js +8 -1
  271. package/dist/src/internal/builtin-plugins/solidity/index.js.map +1 -1
  272. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.d.ts +1 -0
  273. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.d.ts.map +1 -1
  274. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.js +3 -2
  275. package/dist/src/internal/builtin-plugins/solidity/tasks/compile.js.map +1 -1
  276. package/dist/src/internal/builtin-plugins/solidity/type-extensions.d.ts +26 -2
  277. package/dist/src/internal/builtin-plugins/solidity/type-extensions.d.ts.map +1 -1
  278. package/dist/src/internal/builtin-plugins/solidity/type-extensions.js.map +1 -1
  279. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.d.ts +20 -0
  280. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.d.ts.map +1 -0
  281. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.js +79 -0
  282. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.js.map +1 -0
  283. package/dist/src/internal/builtin-plugins/solidity-test/formatters.d.ts +1 -1
  284. package/dist/src/internal/builtin-plugins/solidity-test/formatters.d.ts.map +1 -1
  285. package/dist/src/internal/builtin-plugins/solidity-test/formatters.js +3 -2
  286. package/dist/src/internal/builtin-plugins/solidity-test/formatters.js.map +1 -1
  287. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts +1 -1
  288. package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts.map +1 -1
  289. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js +2 -1
  290. package/dist/src/internal/builtin-plugins/solidity-test/helpers.js.map +1 -1
  291. package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/test.d.ts +4 -0
  292. package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/test.d.ts.map +1 -0
  293. package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/test.js +16 -0
  294. package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/test.js.map +1 -0
  295. package/dist/src/internal/builtin-plugins/solidity-test/index.d.ts.map +1 -1
  296. package/dist/src/internal/builtin-plugins/solidity-test/index.js +12 -0
  297. package/dist/src/internal/builtin-plugins/solidity-test/index.js.map +1 -1
  298. package/dist/src/internal/builtin-plugins/solidity-test/reporter.d.ts +1 -1
  299. package/dist/src/internal/builtin-plugins/solidity-test/reporter.d.ts.map +1 -1
  300. package/dist/src/internal/builtin-plugins/solidity-test/reporter.js +40 -23
  301. package/dist/src/internal/builtin-plugins/solidity-test/reporter.js.map +1 -1
  302. package/dist/src/internal/builtin-plugins/solidity-test/runner.d.ts +1 -1
  303. package/dist/src/internal/builtin-plugins/solidity-test/runner.d.ts.map +1 -1
  304. package/dist/src/internal/builtin-plugins/solidity-test/runner.js +7 -5
  305. package/dist/src/internal/builtin-plugins/solidity-test/runner.js.map +1 -1
  306. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.d.ts +3 -0
  307. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.d.ts.map +1 -0
  308. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.js +57 -0
  309. package/dist/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.js.map +1 -0
  310. package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts +2 -0
  311. package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
  312. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +26 -11
  313. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
  314. package/dist/src/internal/builtin-plugins/telemetry/index.d.ts.map +1 -0
  315. package/dist/src/internal/builtin-plugins/telemetry/index.js +20 -0
  316. package/dist/src/internal/builtin-plugins/telemetry/index.js.map +1 -0
  317. package/dist/src/internal/builtin-plugins/telemetry/task-action.d.ts +8 -0
  318. package/dist/src/internal/builtin-plugins/telemetry/task-action.d.ts.map +1 -0
  319. package/dist/src/internal/builtin-plugins/telemetry/task-action.js +25 -0
  320. package/dist/src/internal/builtin-plugins/telemetry/task-action.js.map +1 -0
  321. package/dist/src/internal/builtin-plugins/test/index.d.ts +1 -0
  322. package/dist/src/internal/builtin-plugins/test/index.d.ts.map +1 -1
  323. package/dist/src/internal/builtin-plugins/test/index.js +13 -0
  324. package/dist/src/internal/builtin-plugins/test/index.js.map +1 -1
  325. package/dist/src/internal/builtin-plugins/test/task-action.d.ts +2 -0
  326. package/dist/src/internal/builtin-plugins/test/task-action.d.ts.map +1 -1
  327. package/dist/src/internal/builtin-plugins/test/task-action.js +63 -5
  328. package/dist/src/internal/builtin-plugins/test/task-action.js.map +1 -1
  329. package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts +21 -0
  330. package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts.map +1 -0
  331. package/dist/src/internal/builtin-plugins/test/type-extensions.js +2 -0
  332. package/dist/src/internal/builtin-plugins/test/type-extensions.js.map +1 -0
  333. package/dist/src/internal/cli/error-handler.d.ts.map +1 -1
  334. package/dist/src/internal/cli/error-handler.js +0 -3
  335. package/dist/src/internal/cli/error-handler.js.map +1 -1
  336. package/dist/src/internal/cli/help/utils.d.ts.map +1 -1
  337. package/dist/src/internal/cli/help/utils.js +15 -1
  338. package/dist/src/internal/cli/help/utils.js.map +1 -1
  339. package/dist/src/internal/cli/init/init.d.ts.map +1 -1
  340. package/dist/src/internal/cli/init/init.js +18 -17
  341. package/dist/src/internal/cli/init/init.js.map +1 -1
  342. package/dist/src/internal/cli/init/package-manager.js +2 -2
  343. package/dist/src/internal/cli/init/package-manager.js.map +1 -1
  344. package/dist/src/internal/cli/init/prompt.js +1 -1
  345. package/dist/src/internal/cli/init/prompt.js.map +1 -1
  346. package/dist/src/internal/cli/main.d.ts +7 -1
  347. package/dist/src/internal/cli/main.d.ts.map +1 -1
  348. package/dist/src/internal/cli/main.js +40 -17
  349. package/dist/src/internal/cli/main.js.map +1 -1
  350. package/dist/src/internal/cli/telemetry/analytics/analytics.d.ts +1 -1
  351. package/dist/src/internal/cli/telemetry/analytics/analytics.d.ts.map +1 -1
  352. package/dist/src/internal/cli/telemetry/analytics/analytics.js +7 -7
  353. package/dist/src/internal/cli/telemetry/analytics/analytics.js.map +1 -1
  354. package/dist/src/internal/cli/telemetry/analytics/types.d.ts +3 -3
  355. package/dist/src/internal/cli/telemetry/analytics/types.d.ts.map +1 -1
  356. package/dist/src/internal/cli/telemetry/sentry/anonymizer.d.ts +1 -1
  357. package/dist/src/internal/cli/telemetry/sentry/init.d.ts +13 -0
  358. package/dist/src/internal/cli/telemetry/sentry/init.d.ts.map +1 -0
  359. package/dist/src/internal/cli/telemetry/sentry/init.js +75 -0
  360. package/dist/src/internal/cli/telemetry/sentry/init.js.map +1 -0
  361. package/dist/src/internal/cli/telemetry/sentry/integrations/onuncaughtexception.d.ts +6 -0
  362. package/dist/src/internal/cli/telemetry/sentry/integrations/onuncaughtexception.d.ts.map +1 -0
  363. package/dist/src/internal/cli/telemetry/sentry/integrations/onuncaughtexception.js +32 -0
  364. package/dist/src/internal/cli/telemetry/sentry/integrations/onuncaughtexception.js.map +1 -0
  365. package/dist/src/internal/cli/telemetry/sentry/integrations/onunhandledrejection.d.ts +7 -0
  366. package/dist/src/internal/cli/telemetry/sentry/integrations/onunhandledrejection.d.ts.map +1 -0
  367. package/dist/src/internal/cli/telemetry/sentry/integrations/onunhandledrejection.js +35 -0
  368. package/dist/src/internal/cli/telemetry/sentry/integrations/onunhandledrejection.js.map +1 -0
  369. package/dist/src/internal/cli/telemetry/sentry/reporter.js +7 -5
  370. package/dist/src/internal/cli/telemetry/sentry/reporter.js.map +1 -1
  371. package/dist/src/internal/cli/telemetry/sentry/subprocess.js +7 -3
  372. package/dist/src/internal/cli/telemetry/sentry/subprocess.js.map +1 -1
  373. package/dist/src/internal/cli/telemetry/sentry/transports/fetch.d.ts +10 -0
  374. package/dist/src/internal/cli/telemetry/sentry/transports/fetch.d.ts.map +1 -0
  375. package/dist/src/internal/cli/telemetry/sentry/transports/fetch.js +31 -0
  376. package/dist/src/internal/cli/telemetry/sentry/transports/fetch.js.map +1 -0
  377. package/dist/src/internal/cli/telemetry/sentry/{transport.d.ts → transports/subprocess.d.ts} +1 -1
  378. package/dist/src/internal/cli/telemetry/sentry/transports/subprocess.d.ts.map +1 -0
  379. package/dist/src/internal/cli/telemetry/sentry/{transport.js → transports/subprocess.js} +4 -4
  380. package/dist/src/internal/cli/telemetry/sentry/transports/subprocess.js.map +1 -0
  381. package/dist/src/internal/cli/telemetry/sentry/vendor/debug-build.d.ts +7 -0
  382. package/dist/src/internal/cli/telemetry/sentry/vendor/debug-build.d.ts.map +1 -0
  383. package/dist/src/internal/cli/telemetry/sentry/vendor/debug-build.js +8 -0
  384. package/dist/src/internal/cli/telemetry/sentry/vendor/debug-build.js.map +1 -0
  385. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/context.d.ts +21 -0
  386. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/context.d.ts.map +1 -0
  387. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/context.js +398 -0
  388. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/context.js.map +1 -0
  389. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.d.ts +18 -0
  390. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.d.ts.map +1 -0
  391. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.js +349 -0
  392. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.js.map +1 -0
  393. package/dist/src/internal/cli/telemetry/sentry/vendor/utils/module.d.ts +3 -0
  394. package/dist/src/internal/cli/telemetry/sentry/vendor/utils/module.d.ts.map +1 -0
  395. package/dist/src/internal/cli/telemetry/sentry/vendor/utils/module.js +46 -0
  396. package/dist/src/internal/cli/telemetry/sentry/vendor/utils/module.js.map +1 -0
  397. package/dist/src/internal/cli/telemetry/telemetry-permissions.d.ts +5 -15
  398. package/dist/src/internal/cli/telemetry/telemetry-permissions.d.ts.map +1 -1
  399. package/dist/src/internal/cli/telemetry/telemetry-permissions.js +29 -65
  400. package/dist/src/internal/cli/telemetry/telemetry-permissions.js.map +1 -1
  401. package/dist/src/internal/config-loading.d.ts.map +1 -1
  402. package/dist/src/internal/config-loading.js +49 -11
  403. package/dist/src/internal/config-loading.js.map +1 -1
  404. package/dist/src/internal/core/arguments.d.ts +3 -3
  405. package/dist/src/internal/core/arguments.d.ts.map +1 -1
  406. package/dist/src/internal/core/arguments.js +14 -10
  407. package/dist/src/internal/core/arguments.js.map +1 -1
  408. package/dist/src/internal/core/async-mutex.d.ts.map +1 -1
  409. package/dist/src/internal/core/async-mutex.js +0 -1
  410. package/dist/src/internal/core/async-mutex.js.map +1 -1
  411. package/dist/src/internal/core/config-validation.d.ts.map +1 -1
  412. package/dist/src/internal/core/config-validation.js +16 -1
  413. package/dist/src/internal/core/config-validation.js.map +1 -1
  414. package/dist/src/internal/core/config.d.ts +1 -1
  415. package/dist/src/internal/core/config.d.ts.map +1 -1
  416. package/dist/src/internal/core/config.js +7 -2
  417. package/dist/src/internal/core/config.js.map +1 -1
  418. package/dist/src/internal/core/configuration-variables.d.ts +3 -0
  419. package/dist/src/internal/core/configuration-variables.d.ts.map +1 -1
  420. package/dist/src/internal/core/configuration-variables.js +15 -9
  421. package/dist/src/internal/core/configuration-variables.js.map +1 -1
  422. package/dist/src/internal/core/global-options.d.ts +2 -2
  423. package/dist/src/internal/core/global-options.d.ts.map +1 -1
  424. package/dist/src/internal/core/global-options.js +2 -2
  425. package/dist/src/internal/core/global-options.js.map +1 -1
  426. package/dist/src/internal/core/hook-manager.d.ts +1 -0
  427. package/dist/src/internal/core/hook-manager.d.ts.map +1 -1
  428. package/dist/src/internal/core/hook-manager.js +7 -2
  429. package/dist/src/internal/core/hook-manager.js.map +1 -1
  430. package/dist/src/internal/core/hre.d.ts +2 -0
  431. package/dist/src/internal/core/hre.d.ts.map +1 -1
  432. package/dist/src/internal/core/hre.js +4 -1
  433. package/dist/src/internal/core/hre.js.map +1 -1
  434. package/dist/src/internal/core/plugins/detect-plugin-npm-dependency-problems.d.ts +3 -3
  435. package/dist/src/internal/core/plugins/detect-plugin-npm-dependency-problems.d.ts.map +1 -1
  436. package/dist/src/internal/core/plugins/detect-plugin-npm-dependency-problems.js +6 -6
  437. package/dist/src/internal/core/plugins/detect-plugin-npm-dependency-problems.js.map +1 -1
  438. package/dist/src/internal/core/plugins/resolve-plugin-list.js +2 -2
  439. package/dist/src/internal/core/plugins/resolve-plugin-list.js.map +1 -1
  440. package/dist/src/internal/core/tasks/builders.d.ts +0 -1
  441. package/dist/src/internal/core/tasks/builders.d.ts.map +1 -1
  442. package/dist/src/internal/core/tasks/builders.js +2 -6
  443. package/dist/src/internal/core/tasks/builders.js.map +1 -1
  444. package/dist/src/internal/core/tasks/resolved-task.d.ts.map +1 -1
  445. package/dist/src/internal/core/tasks/resolved-task.js +5 -5
  446. package/dist/src/internal/core/tasks/resolved-task.js.map +1 -1
  447. package/dist/src/internal/core/tasks/task-manager.js +7 -7
  448. package/dist/src/internal/core/tasks/task-manager.js.map +1 -1
  449. package/dist/src/internal/core/tasks/validations.d.ts.map +1 -1
  450. package/dist/src/internal/core/tasks/validations.js +8 -8
  451. package/dist/src/internal/core/tasks/validations.js.map +1 -1
  452. package/dist/src/internal/{hre-intialization.d.ts → hre-initialization.d.ts} +2 -2
  453. package/dist/src/internal/hre-initialization.d.ts.map +1 -0
  454. package/dist/src/internal/{hre-intialization.js → hre-initialization.js} +2 -2
  455. package/dist/src/internal/hre-initialization.js.map +1 -0
  456. package/dist/src/lsp-helpers.d.ts +5 -0
  457. package/dist/src/lsp-helpers.d.ts.map +1 -0
  458. package/dist/src/lsp-helpers.js +4 -0
  459. package/dist/src/lsp-helpers.js.map +1 -0
  460. package/dist/src/types/arguments.d.ts +5 -1
  461. package/dist/src/types/arguments.d.ts.map +1 -1
  462. package/dist/src/types/arguments.js +2 -0
  463. package/dist/src/types/arguments.js.map +1 -1
  464. package/dist/src/types/artifacts.d.ts +4 -4
  465. package/dist/src/types/artifacts.d.ts.map +1 -1
  466. package/dist/src/types/config.d.ts +2 -0
  467. package/dist/src/types/config.d.ts.map +1 -1
  468. package/dist/src/types/hooks.d.ts +8 -0
  469. package/dist/src/types/hooks.d.ts.map +1 -1
  470. package/dist/src/types/hre.d.ts +2 -1
  471. package/dist/src/types/hre.d.ts.map +1 -1
  472. package/dist/src/types/network.d.ts +6 -1
  473. package/dist/src/types/network.d.ts.map +1 -1
  474. package/dist/src/types/providers.d.ts +6 -6
  475. package/dist/src/types/solidity/build-system.d.ts +3 -3
  476. package/dist/src/types/solidity/compilation-job.d.ts +1 -1
  477. package/dist/src/types/solidity/compilation-job.d.ts.map +1 -1
  478. package/dist/src/types/solidity/compiler-io.d.ts +4 -4
  479. package/dist/src/types/solidity/compiler-io.d.ts.map +1 -1
  480. package/dist/src/types/solidity/dependency-graph.d.ts +17 -10
  481. package/dist/src/types/solidity/dependency-graph.d.ts.map +1 -1
  482. package/dist/src/types/solidity/errors.d.ts +269 -0
  483. package/dist/src/types/solidity/errors.d.ts.map +1 -0
  484. package/dist/src/types/solidity/errors.js +118 -0
  485. package/dist/src/types/solidity/errors.js.map +1 -0
  486. package/dist/src/types/solidity/resolved-file.d.ts +23 -23
  487. package/dist/src/types/solidity/resolved-file.d.ts.map +1 -1
  488. package/dist/src/types/solidity/resolved-file.js.map +1 -1
  489. package/dist/src/types/solidity/solidity-artifacts.d.ts +5 -3
  490. package/dist/src/types/solidity/solidity-artifacts.d.ts.map +1 -1
  491. package/dist/src/types/solidity.d.ts +1 -0
  492. package/dist/src/types/solidity.d.ts.map +1 -1
  493. package/dist/src/types/solidity.js +1 -0
  494. package/dist/src/types/solidity.js.map +1 -1
  495. package/dist/src/types/tasks.d.ts +0 -4
  496. package/dist/src/types/tasks.d.ts.map +1 -1
  497. package/dist/src/types/utils.d.ts +6 -0
  498. package/dist/src/types/utils.d.ts.map +1 -1
  499. package/dist/src/utils/contract-names.d.ts +45 -0
  500. package/dist/src/utils/contract-names.d.ts.map +1 -0
  501. package/dist/src/utils/contract-names.js +60 -0
  502. package/dist/src/utils/contract-names.js.map +1 -0
  503. package/package.json +21 -22
  504. package/src/hre.ts +2 -1
  505. package/src/index.ts +1 -1
  506. package/src/internal/builtin-global-options.ts +2 -2
  507. package/src/internal/builtin-plugins/artifacts/artifact-manager.ts +19 -9
  508. package/src/internal/builtin-plugins/artifacts/hook-handlers/hre.ts +2 -2
  509. package/src/internal/builtin-plugins/clean/index.ts +2 -0
  510. package/src/internal/builtin-plugins/clean/task-action.ts +3 -1
  511. package/src/internal/builtin-plugins/clean/type-extensions.ts +10 -0
  512. package/src/internal/builtin-plugins/coverage/coverage-manager.ts +544 -0
  513. package/src/internal/builtin-plugins/coverage/exports.ts +5 -0
  514. package/src/internal/builtin-plugins/coverage/helpers.ts +50 -0
  515. package/src/internal/builtin-plugins/coverage/hook-handlers/clean.ts +12 -0
  516. package/src/internal/builtin-plugins/coverage/hook-handlers/hre.ts +34 -0
  517. package/src/internal/builtin-plugins/coverage/hook-handlers/solidity.ts +136 -0
  518. package/src/internal/builtin-plugins/coverage/index.ts +18 -6
  519. package/src/internal/builtin-plugins/coverage/type-extensions.ts +6 -0
  520. package/src/internal/builtin-plugins/coverage/types.ts +21 -0
  521. package/src/internal/builtin-plugins/flatten/task-action.ts +25 -10
  522. package/src/internal/builtin-plugins/index.ts +3 -3
  523. package/src/internal/builtin-plugins/network-manager/accounts/derive-private-keys.ts +2 -2
  524. package/src/internal/builtin-plugins/network-manager/base-provider.ts +2 -10
  525. package/src/internal/builtin-plugins/network-manager/chain-descriptors.ts +556 -0
  526. package/src/internal/builtin-plugins/network-manager/config-override.ts +0 -42
  527. package/src/internal/builtin-plugins/network-manager/config-resolution.ts +59 -217
  528. package/src/internal/builtin-plugins/network-manager/edr/edr-context.ts +4 -4
  529. package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +83 -31
  530. package/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-solidity-errors.ts +8 -1
  531. package/src/internal/builtin-plugins/network-manager/edr/types/coverage.ts +3 -0
  532. package/src/internal/builtin-plugins/network-manager/edr/types/hardfork.ts +76 -8
  533. package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +122 -101
  534. package/src/internal/builtin-plugins/network-manager/edr/utils/hardfork.ts +19 -5
  535. package/src/internal/builtin-plugins/network-manager/hook-handlers/config.ts +16 -6
  536. package/src/internal/builtin-plugins/network-manager/hook-handlers/hre.ts +7 -7
  537. package/src/internal/builtin-plugins/network-manager/hook-handlers/network.ts +2 -2
  538. package/src/internal/builtin-plugins/network-manager/http-provider.ts +9 -5
  539. package/src/internal/builtin-plugins/network-manager/index.ts +3 -1
  540. package/src/internal/builtin-plugins/network-manager/json-rpc.ts +9 -4
  541. package/src/internal/builtin-plugins/network-manager/network-manager.ts +85 -42
  542. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/hd-wallet-handler.ts +4 -0
  543. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/local-accounts.ts +121 -63
  544. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/accounts/sender.ts +1 -1
  545. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers/chain-id/chain-id-handler.ts +1 -1
  546. package/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.ts +3 -0
  547. package/src/internal/builtin-plugins/network-manager/rpc/types/authorization-list.ts +31 -0
  548. package/src/internal/builtin-plugins/network-manager/rpc/types/rpc-parity.ts +24 -0
  549. package/src/internal/builtin-plugins/network-manager/rpc/types/tx-request.ts +10 -0
  550. package/src/internal/builtin-plugins/network-manager/rpc/validate-params.ts +3 -3
  551. package/src/internal/builtin-plugins/network-manager/type-extensions/config.ts +78 -30
  552. package/src/internal/builtin-plugins/network-manager/type-extensions/hooks.ts +12 -0
  553. package/src/internal/builtin-plugins/network-manager/type-validation.ts +192 -54
  554. package/src/internal/builtin-plugins/node/index.ts +6 -3
  555. package/src/internal/builtin-plugins/node/json-rpc/handler.ts +2 -0
  556. package/src/internal/builtin-plugins/node/task-action.ts +11 -12
  557. package/src/internal/builtin-plugins/run/task-action.ts +1 -1
  558. package/src/internal/builtin-plugins/solidity/build-results.ts +3 -110
  559. package/src/internal/builtin-plugins/solidity/build-system/artifacts.ts +32 -9
  560. package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +73 -51
  561. package/src/internal/builtin-plugins/solidity/build-system/cache.ts +11 -4
  562. package/src/internal/builtin-plugins/solidity/build-system/compilation-job.ts +134 -85
  563. package/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.ts +108 -69
  564. package/src/internal/builtin-plugins/solidity/build-system/compiler/downloader.ts +11 -6
  565. package/src/internal/builtin-plugins/solidity/build-system/compiler/index.ts +6 -3
  566. package/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-runner.ts +2 -1
  567. package/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.ts +3 -3
  568. package/src/internal/builtin-plugins/solidity/build-system/dependency-graph-building.ts +72 -17
  569. package/src/internal/builtin-plugins/solidity/build-system/dependency-graph.ts +135 -38
  570. package/src/internal/builtin-plugins/solidity/build-system/read-source-file.ts +16 -0
  571. package/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.ts +921 -1376
  572. package/src/internal/builtin-plugins/solidity/build-system/resolver/error-messages.ts +223 -0
  573. package/src/internal/builtin-plugins/solidity/build-system/resolver/npm-module-parsing.ts +60 -0
  574. package/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.ts +670 -0
  575. package/src/internal/builtin-plugins/solidity/build-system/resolver/remappings.ts +18 -9
  576. package/src/internal/builtin-plugins/solidity/build-system/resolver/source-name-utils.ts +42 -0
  577. package/src/internal/builtin-plugins/solidity/build-system/resolver/types.ts +240 -56
  578. package/src/internal/builtin-plugins/solidity/build-system/resolver/utils.ts +89 -0
  579. package/src/internal/builtin-plugins/solidity/build-system/root-paths-utils.ts +4 -4
  580. package/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.ts +13 -9
  581. package/src/internal/builtin-plugins/solidity/build-system/solc-info.ts +2 -0
  582. package/src/internal/builtin-plugins/solidity/config.ts +4 -9
  583. package/src/internal/builtin-plugins/solidity/index.ts +8 -1
  584. package/src/internal/builtin-plugins/solidity/tasks/compile.ts +5 -2
  585. package/src/internal/builtin-plugins/solidity/type-extensions.ts +56 -2
  586. package/src/internal/builtin-plugins/solidity-test/edr-artifacts.ts +134 -0
  587. package/src/internal/builtin-plugins/solidity-test/formatters.ts +8 -2
  588. package/src/internal/builtin-plugins/solidity-test/helpers.ts +2 -0
  589. package/src/internal/builtin-plugins/solidity-test/hook-handlers/test.ts +23 -0
  590. package/src/internal/builtin-plugins/solidity-test/index.ts +13 -0
  591. package/src/internal/builtin-plugins/solidity-test/reporter.ts +46 -27
  592. package/src/internal/builtin-plugins/solidity-test/runner.ts +19 -4
  593. package/src/internal/builtin-plugins/solidity-test/stack-trace-solidity-errors.ts +85 -0
  594. package/src/internal/builtin-plugins/solidity-test/task-action.ts +38 -16
  595. package/src/internal/builtin-plugins/telemetry/index.ts +23 -0
  596. package/src/internal/builtin-plugins/telemetry/task-action.ts +45 -0
  597. package/src/internal/builtin-plugins/test/index.ts +14 -0
  598. package/src/internal/builtin-plugins/test/task-action.ts +111 -5
  599. package/src/internal/builtin-plugins/test/type-extensions.ts +28 -0
  600. package/src/internal/cli/error-handler.ts +0 -3
  601. package/src/internal/cli/help/utils.ts +19 -2
  602. package/src/internal/cli/init/init.ts +33 -23
  603. package/src/internal/cli/init/package-manager.ts +2 -2
  604. package/src/internal/cli/init/prompt.ts +1 -1
  605. package/src/internal/cli/main.ts +60 -21
  606. package/src/internal/cli/telemetry/analytics/analytics.ts +11 -11
  607. package/src/internal/cli/telemetry/analytics/types.ts +3 -3
  608. package/src/internal/cli/telemetry/sentry/anonymizer.ts +1 -1
  609. package/src/internal/cli/telemetry/sentry/init.ts +117 -0
  610. package/src/internal/cli/telemetry/sentry/integrations/onuncaughtexception.ts +40 -0
  611. package/src/internal/cli/telemetry/sentry/integrations/onunhandledrejection.ts +49 -0
  612. package/src/internal/cli/telemetry/sentry/reporter.ts +10 -6
  613. package/src/internal/cli/telemetry/sentry/subprocess.ts +8 -4
  614. package/src/internal/cli/telemetry/sentry/transports/fetch.ts +53 -0
  615. package/src/internal/cli/telemetry/sentry/{transport.ts → transports/subprocess.ts} +4 -3
  616. package/src/internal/cli/telemetry/sentry/vendor/debug-build.ts +10 -0
  617. package/src/internal/cli/telemetry/sentry/vendor/integrations/context.ts +478 -0
  618. package/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.ts +415 -0
  619. package/src/internal/cli/telemetry/sentry/vendor/utils/module.ts +61 -0
  620. package/src/internal/cli/telemetry/telemetry-permissions.ts +35 -84
  621. package/src/internal/config-loading.ts +75 -18
  622. package/src/internal/core/arguments.ts +16 -10
  623. package/src/internal/core/async-mutex.ts +0 -1
  624. package/src/internal/core/config-validation.ts +20 -1
  625. package/src/internal/core/config.ts +14 -2
  626. package/src/internal/core/configuration-variables.ts +26 -11
  627. package/src/internal/core/global-options.ts +5 -3
  628. package/src/internal/core/hook-manager.ts +18 -2
  629. package/src/internal/core/hre.ts +6 -1
  630. package/src/internal/core/plugins/detect-plugin-npm-dependency-problems.ts +11 -8
  631. package/src/internal/core/plugins/resolve-plugin-list.ts +2 -2
  632. package/src/internal/core/tasks/builders.ts +13 -12
  633. package/src/internal/core/tasks/resolved-task.ts +10 -7
  634. package/src/internal/core/tasks/task-manager.ts +7 -7
  635. package/src/internal/core/tasks/validations.ts +10 -8
  636. package/src/internal/{hre-intialization.ts → hre-initialization.ts} +1 -1
  637. package/src/lsp-helpers.ts +9 -0
  638. package/src/types/arguments.ts +4 -0
  639. package/src/types/artifacts.ts +4 -4
  640. package/src/types/config.ts +2 -0
  641. package/src/types/hooks.ts +15 -0
  642. package/src/types/hre.ts +2 -1
  643. package/src/types/network.ts +10 -4
  644. package/src/types/providers.ts +6 -6
  645. package/src/types/solidity/build-system.ts +3 -3
  646. package/src/types/solidity/compilation-job.ts +1 -1
  647. package/src/types/solidity/compiler-io.ts +4 -4
  648. package/src/types/solidity/dependency-graph.ts +18 -10
  649. package/src/types/solidity/errors.ts +357 -0
  650. package/src/types/solidity/resolved-file.ts +23 -24
  651. package/src/types/solidity/solidity-artifacts.ts +5 -3
  652. package/src/types/solidity.ts +1 -0
  653. package/src/types/tasks.ts +0 -5
  654. package/src/types/utils.ts +7 -0
  655. package/src/utils/contract-names.ts +80 -0
  656. package/templates/01-node-test-runner-viem/README.md +1 -1
  657. package/templates/01-node-test-runner-viem/gitignore +3 -0
  658. package/templates/01-node-test-runner-viem/hardhat.config.ts +4 -29
  659. package/templates/01-node-test-runner-viem/package.json +5 -9
  660. package/templates/01-node-test-runner-viem/scripts/check-predeploy.ts +8 -2
  661. package/templates/01-node-test-runner-viem/scripts/send-op-tx.ts +4 -3
  662. package/templates/01-node-test-runner-viem/test/Counter.ts +20 -6
  663. package/templates/02-mocha-ethers/gitignore +3 -0
  664. package/templates/02-mocha-ethers/hardhat.config.ts +4 -33
  665. package/templates/02-mocha-ethers/package.json +6 -11
  666. package/templates/02-mocha-ethers/scripts/check-predeploy.ts +8 -2
  667. package/templates/02-mocha-ethers/scripts/send-op-tx.ts +4 -1
  668. package/templates/02-mocha-ethers/test/Counter.ts +48 -45
  669. package/dist/src/internal/builtin-plugins/coverage/task-action.d.ts +0 -2
  670. package/dist/src/internal/builtin-plugins/coverage/task-action.d.ts.map +0 -1
  671. package/dist/src/internal/builtin-plugins/coverage/task-action.js +0 -5
  672. package/dist/src/internal/builtin-plugins/coverage/task-action.js.map +0 -1
  673. package/dist/src/internal/builtin-plugins/solidity/build-system/debug-utils.d.ts +0 -4
  674. package/dist/src/internal/builtin-plugins/solidity/build-system/debug-utils.d.ts.map +0 -1
  675. package/dist/src/internal/builtin-plugins/solidity/build-system/debug-utils.js +0 -60
  676. package/dist/src/internal/builtin-plugins/solidity/build-system/debug-utils.js.map +0 -1
  677. package/dist/src/internal/builtin-plugins/solidity/build-system/resolved-file.d.ts +0 -22
  678. package/dist/src/internal/builtin-plugins/solidity/build-system/resolved-file.d.ts.map +0 -1
  679. package/dist/src/internal/builtin-plugins/solidity/build-system/resolved-file.js +0 -41
  680. package/dist/src/internal/builtin-plugins/solidity/build-system/resolved-file.js.map +0 -1
  681. package/dist/src/internal/builtin-plugins/verify/index.d.ts.map +0 -1
  682. package/dist/src/internal/builtin-plugins/verify/index.js +0 -12
  683. package/dist/src/internal/builtin-plugins/verify/index.js.map +0 -1
  684. package/dist/src/internal/builtin-plugins/verify/task-action.d.ts +0 -2
  685. package/dist/src/internal/builtin-plugins/verify/task-action.d.ts.map +0 -1
  686. package/dist/src/internal/builtin-plugins/verify/task-action.js +0 -5
  687. package/dist/src/internal/builtin-plugins/verify/task-action.js.map +0 -1
  688. package/dist/src/internal/cli/prompt/prompt.d.ts +0 -9
  689. package/dist/src/internal/cli/prompt/prompt.d.ts.map +0 -1
  690. package/dist/src/internal/cli/prompt/prompt.js +0 -43
  691. package/dist/src/internal/cli/prompt/prompt.js.map +0 -1
  692. package/dist/src/internal/cli/telemetry/sentry/transport.d.ts.map +0 -1
  693. package/dist/src/internal/cli/telemetry/sentry/transport.js.map +0 -1
  694. package/dist/src/internal/hre-intialization.d.ts.map +0 -1
  695. package/dist/src/internal/hre-intialization.js.map +0 -1
  696. package/src/internal/builtin-plugins/coverage/task-action.ts +0 -9
  697. package/src/internal/builtin-plugins/solidity/build-system/debug-utils.ts +0 -80
  698. package/src/internal/builtin-plugins/solidity/build-system/resolved-file.ts +0 -66
  699. package/src/internal/builtin-plugins/verify/index.ts +0 -15
  700. package/src/internal/builtin-plugins/verify/task-action.ts +0 -9
  701. package/src/internal/cli/prompt/prompt.ts +0 -53
  702. /package/dist/src/internal/builtin-plugins/{verify → telemetry}/index.d.ts +0 -0
@@ -1,4 +1,18 @@
1
- import type { Remapping, Resolver } from "./types.js";
1
+ import type {
2
+ Resolver,
3
+ RemappedNpmPackagesGraphJson,
4
+ Remapping,
5
+ ResolvedNpmUserRemapping,
6
+ ResolvedUserRemapping,
7
+ Result,
8
+ } from "./types.js";
9
+ import type {
10
+ ImportResolutionError,
11
+ NpmRootResolutionError,
12
+ ProjectRootResolutionError,
13
+ ResolvedFileReference,
14
+ UserRemappingReference,
15
+ } from "../../../../../types/solidity/errors.js";
2
16
  import type {
3
17
  ResolvedNpmPackage,
4
18
  ResolvedFile,
@@ -9,1591 +23,1122 @@ import type {
9
23
 
10
24
  import path from "node:path";
11
25
 
12
- import {
13
- HardhatError,
14
- assertHardhatInvariant,
15
- } from "@nomicfoundation/hardhat-errors";
16
- import { ensureError } from "@nomicfoundation/hardhat-utils/error";
17
- import {
18
- FileNotFoundError,
19
- exists,
20
- getFileTrueCase,
21
- readJsonFile,
22
- readUtf8File,
23
- } from "@nomicfoundation/hardhat-utils/fs";
24
- import {
25
- findClosestPackageJson,
26
- findDependencyPackageJson,
27
- } from "@nomicfoundation/hardhat-utils/package";
28
- import { shortenPath } from "@nomicfoundation/hardhat-utils/path";
26
+ import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors";
27
+ import { exists } from "@nomicfoundation/hardhat-utils/fs";
29
28
  import { analyze } from "@nomicfoundation/solidity-analyzer";
30
- import * as resolve from "resolve.exports";
31
29
 
30
+ import {
31
+ ImportResolutionErrorType,
32
+ RootResolutionErrorType,
33
+ } from "../../../../../types/solidity/errors.js";
32
34
  import { ResolvedFileType } from "../../../../../types/solidity/resolved-file.js";
33
35
  import { AsyncMutex } from "../../../../core/async-mutex.js";
34
- import {
35
- NpmPackageResolvedFileImplementation,
36
- ProjectResolvedFileImplementation,
37
- } from "../resolved-file.js";
38
36
 
37
+ import { parseNpmDirectImport } from "./npm-module-parsing.js";
39
38
  import {
40
- applyValidRemapping,
41
- parseRemappingString,
42
- selectBestRemapping,
43
- } from "./remappings.js";
44
-
45
- // Things to note:
46
- // - This resolver assumes that the root of the project is the folder with the
47
- // closest package.json to the config file.
48
- // - Each file system file is resolved to a single ResolvedFile, with a unique
49
- // source name.
50
- // - Files within the project have their relative path as their source name.
51
- // - Files within npm packages have source names that start with `npm/` and
52
- // contain the package name and version. e.g. `npm/package@1.2.3/path.sol`.
53
- // - Files within npm packages that are part of a monorepo are resolved like
54
- // npm pacakges, but with the version `local`.
55
- // - This resolver fails if an import has a casing different from that of the
56
- // file system.
57
- // - We do not allow users to remap the imports present in files within npm
58
- // packages, by forbidding user remappings with context and starting with
59
- // `npm/`.
60
- // - We do allow users to remap imports of non-npm files, including remmapping
61
- // them into npm packages.
62
- // - Every import in an npm file is either relative or remapped by a remapping
63
- // generated by the resolver.
64
- // - A direct import (i.e. not relative) is considered to be local within the
65
- // the project/package if it is a bare file name (not in a directory), or if
66
- // the first directory exists in the project/package.
67
- // - The direct import "hardhat/console.sol" is a special case and it is never
68
- // considered to be local. And we only remap `hardhat/console.sol`.
69
- // - Local imports within the project may be remapped by user remappings, but
70
- // not by the resolver.
71
- // - Imports into npm packages are always remapped, if not by the user, by the
72
- // resolver.
73
- // - Direct local improts within npm package are always remapped by the
74
- // resolver.
75
-
76
- /**
77
- * A user remapping, parsed, and with its npm package resolved, if any.
78
- */
79
- interface ResolvedUserRemapping {
80
- rawFormat: string;
81
- context: string;
82
- prefix: string;
83
- target: string;
84
- targetNpmPackage?: ResolvedNpmPackage;
85
- }
39
+ isResolvedUserRemapping,
40
+ RemappedNpmPackagesGraphImplementation,
41
+ } from "./remapped-npm-packages-graph.js";
42
+ import { applyValidRemapping, formatRemapping } from "./remappings.js";
43
+ import {
44
+ fsPathToSourceNamePath,
45
+ sourceNamePathJoin,
46
+ sourceNamePathToFsPath,
47
+ } from "./source-name-utils.js";
48
+ import { UserRemappingType } from "./types.js";
49
+ import {
50
+ PathValidationErrorType,
51
+ resolveSubpathWithPackageExports,
52
+ validateFsPath,
53
+ } from "./utils.js";
86
54
 
87
- /**
88
- * A sentinel value that represents the root of the Hardhat project.
89
- */
90
- const PROJECT_ROOT_SENTINEL: unique symbol = Symbol();
55
+ const NPM_PACKAGES_WITH_SIMULATED_PACKAGE_EXPORTS = new Set(["forge-std"]);
91
56
 
92
57
  export class ResolverImplementation implements Resolver {
93
58
  readonly #projectRoot: string;
94
- readonly #userRemappings: ResolvedUserRemapping[];
59
+ readonly #npmPackageGraph: RemappedNpmPackagesGraphImplementation;
60
+ readonly #hhProjectPackage: ResolvedNpmPackage;
61
+ readonly #readUtf8File: (absPath: string) => Promise<string>;
95
62
 
96
63
  /**
97
64
  * IMPORTANT: This mutex must be acquired before writing to any of the mutable
98
- * fields of this class. We do this by using the mutex in the public methods,
99
- * which don't call each other.
100
- */
101
- readonly #mutex = new AsyncMutex();
102
-
103
- /**
104
- * A map of all the npm dependencies used in the project, and their
105
- * dependencies.
65
+ * fields of this class.
106
66
  *
107
- * This is more complex than you may expect, as we have to handle:
108
- *
109
- * - The Hardhat project itself, which is treated differently than npm
110
- * packages, and is represented by the value `PROJECT_ROOT_SENTINEL`.
111
- * - The case where a package is installed with a different name than the
112
- * package's name in its `package.json`. We refer to the name with which
113
- * the package is installed as the "installation name".
114
- * - Imports from monorepo packages into the Hardhat project.
67
+ * We do this by using the mutex in the public methods, which don't call each
68
+ * other.
115
69
  */
116
- readonly #dependencyMaps: Map<
117
- ResolvedNpmPackage | typeof PROJECT_ROOT_SENTINEL,
118
- Map<
119
- string, // The installation-name of the package that is being imported
120
- ResolvedNpmPackage | typeof PROJECT_ROOT_SENTINEL // The package imported with that name
121
- >
122
- > = new Map();
70
+ readonly #mutex = new AsyncMutex();
123
71
 
124
72
  /**
125
- * A map of all the prefixes that an npm package needs to set as remappings
126
- * to avoid being affected by a user remapping.
127
- *
128
- * For example, if a package `foo` has an import `import "dep/File.sol";`,
129
- * and the user remaps `dep/=nope/`, it could break `foo`'s import.
130
- *
131
- * To avoid this situation we set all the prefixes that `foo` needs unaffected
132
- * by the user remapping, with a higher precedence than user remappings.
133
- */
134
- readonly #localPrefixesByPackage: Map<ResolvedNpmPackage, Set<string>> =
73
+ * We use this map to ensure that we only resolve each file once.
74
+ **/
75
+ readonly #resolvedFileByInputSourceName: Map<string, ResolvedFile> =
135
76
  new Map();
136
77
 
137
78
  /**
138
- * We use this map to ensure that we only resolve each file once.
139
- **/
140
- readonly #resolvedFileBySourceName: Map<string, ResolvedFile> = new Map();
79
+ * A fake `<root>.sol` file that we use to resolve npm roots using
80
+ * the same logic we use for imports.
81
+ */
82
+ readonly #fakeRootFile: ProjectResolvedFile;
141
83
 
142
84
  /**
143
- * Creates a new Resolver.
85
+ * Creates a new resolver.
144
86
  *
145
87
  * @param projectRoot The absolute path to the Hardhat project root.
146
- * @param userRemappingStrings The remappings provided by the user.
88
+ * @param readUtf8File A function that reads a UTF-8 file.
89
+ * @returns The resolver or the user remapping errors found.
147
90
  */
148
91
  public static async create(
149
92
  projectRoot: string,
150
- userRemappingStrings: string[],
93
+ readUtf8File: (absPath: string) => Promise<string>,
151
94
  ): Promise<Resolver> {
152
- const userRemappings = await Promise.all(
153
- userRemappingStrings.map((remappingString) =>
154
- validateAndResolveUserRemapping(projectRoot, remappingString),
155
- ),
156
- );
95
+ const map =
96
+ await RemappedNpmPackagesGraphImplementation.create(projectRoot);
157
97
 
158
- return new ResolverImplementation(projectRoot, userRemappings);
98
+ return new ResolverImplementation(projectRoot, map, readUtf8File);
159
99
  }
160
100
 
161
101
  private constructor(
162
102
  projectRoot: string,
163
- userRemappings: ResolvedUserRemapping[],
103
+ npmPackagesGraph: RemappedNpmPackagesGraphImplementation,
104
+ readUtf8File: (absPath: string) => Promise<string>,
164
105
  ) {
165
106
  this.#projectRoot = projectRoot;
166
- this.#userRemappings = userRemappings;
167
- this.#dependencyMaps.set(PROJECT_ROOT_SENTINEL, new Map());
107
+ this.#npmPackageGraph = npmPackagesGraph;
108
+ this.#hhProjectPackage = npmPackagesGraph.getHardhatProjectPackage();
109
+ this.#readUtf8File = readUtf8File;
110
+
111
+ const fakeRootFileName = "<fake-root-do-not-use>.sol";
112
+ this.#fakeRootFile = {
113
+ type: ResolvedFileType.PROJECT_FILE,
114
+ inputSourceName: sourceNamePathJoin(
115
+ this.#hhProjectPackage.inputSourceNameRoot,
116
+ fakeRootFileName,
117
+ ),
118
+ fsPath: path.join(this.#projectRoot, fakeRootFileName),
119
+ content: {
120
+ importPaths: [],
121
+ text: "",
122
+ versionPragmas: [],
123
+ },
124
+ package: this.#hhProjectPackage,
125
+ };
168
126
  }
169
127
 
170
128
  public async resolveProjectFile(
171
129
  absoluteFilePath: string,
172
- ): Promise<ProjectResolvedFile> {
130
+ ): Promise<Result<ProjectResolvedFile, ProjectRootResolutionError>> {
173
131
  return this.#mutex.exclusiveRun(async () => {
174
- if (!absoluteFilePath.startsWith(this.#projectRoot)) {
175
- throw new HardhatError(
176
- HardhatError.ERRORS.SOLIDITY.RESOLVING_INCORRECT_FILE_AS_PROJECT_FILE,
177
- {
178
- file: shortenPath(absoluteFilePath),
179
- },
180
- );
181
- }
132
+ return this.#resolveProjectFile(absoluteFilePath);
133
+ });
134
+ }
182
135
 
183
- const relativeFilePath = path.relative(
184
- this.#projectRoot,
185
- absoluteFilePath,
186
- );
136
+ public async resolveNpmDependencyFileAsRoot(
137
+ npmModule: string,
138
+ ): Promise<
139
+ Result<
140
+ { file: NpmPackageResolvedFile; remapping?: ResolvedNpmUserRemapping },
141
+ NpmRootResolutionError
142
+ >
143
+ > {
144
+ return this.#mutex.exclusiveRun(async () => {
145
+ return this.#resolveNpmDependencyFileAsRoot(npmModule);
146
+ });
147
+ }
187
148
 
188
- // We first check if the file has already been resolved.
189
- //
190
- // Note that it may have received the right path, but with the wrong
191
- // casing. We don't care at this point, as it would just mean a cache
192
- // miss, and we proceed to get the right casing in that case.
193
- //
194
- // However, as most of the time these absolute paths are read from the file
195
- // system, they'd have the right casing in general.
196
- //
197
- // If we need to fetch the right casing, we'd have to recheck the cache,
198
- // to avoid re-resolving the file.
199
- let sourceName = fsPathToSourceNamePath(relativeFilePath);
200
- const existing = this.#resolvedFileBySourceName.get(sourceName);
201
-
202
- if (existing !== undefined) {
203
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
204
- The cache is type-unsafe, but we are sure this is a ProjectResolvedFile */
205
- return existing as ProjectResolvedFile;
206
- }
149
+ public async resolveImport(
150
+ from: ResolvedFile,
151
+ importPath: string,
152
+ ): Promise<
153
+ Result<
154
+ { file: ResolvedFile; remapping?: Remapping | ResolvedUserRemapping },
155
+ ImportResolutionError
156
+ >
157
+ > {
158
+ return this.#mutex.exclusiveRun(async () =>
159
+ this.#resolveImport(from, importPath),
160
+ );
161
+ }
207
162
 
208
- let trueCaseFsPath: string;
209
- try {
210
- trueCaseFsPath = await getFileTrueCase(
211
- this.#projectRoot,
212
- relativeFilePath,
213
- );
214
- } catch (error) {
215
- ensureError(error, FileNotFoundError);
163
+ async #resolveProjectFile(
164
+ absoluteFilePath: string,
165
+ ): Promise<Result<ProjectResolvedFile, ProjectRootResolutionError>> {
166
+ if (!absoluteFilePath.startsWith(this.#projectRoot)) {
167
+ return {
168
+ success: false,
169
+ error: {
170
+ type: RootResolutionErrorType.PROJECT_ROOT_FILE_NOT_IN_PROJECT,
171
+ absoluteFilePath,
172
+ },
173
+ };
174
+ }
216
175
 
217
- throw new HardhatError(
218
- HardhatError.ERRORS.SOLIDITY.RESOLVING_NONEXISTENT_PROJECT_FILE,
219
- { file: shortenPath(absoluteFilePath) },
220
- error,
221
- );
222
- }
176
+ const relativeFilePath = path.relative(this.#projectRoot, absoluteFilePath);
223
177
 
224
- // Now that we have the correct casing, we "fix" the source name.
225
- sourceName = fsPathToSourceNamePath(trueCaseFsPath);
178
+ // We first check if the file has already been resolved.
179
+ //
180
+ // Note that it may have received the right path, but with the wrong
181
+ // casing. We don't care at this point, as it would just mean a cache
182
+ // miss, and we proceed to get the right casing in that case.
183
+ //
184
+ // However, as most of the time these absolute paths are read from the file
185
+ // system, they'd have the right casing in general.
186
+ //
187
+ // If we need to fetch the right casing, we'd have to recheck the cache,
188
+ // to avoid re-resolving the file.
189
+ let inputSourceName = sourceNamePathJoin(
190
+ this.#hhProjectPackage.inputSourceNameRoot,
191
+ fsPathToSourceNamePath(relativeFilePath),
192
+ );
226
193
 
227
- // Maybe it was already resolved, so we need to check with the right
228
- // casing
229
- const resolvedWithTheRightCasing =
230
- this.#resolvedFileBySourceName.get(sourceName);
231
- if (resolvedWithTheRightCasing !== undefined) {
232
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
233
- -- If it was, it's a ProjectResolvedFile */
234
- return resolvedWithTheRightCasing as ProjectResolvedFile;
235
- }
194
+ const existing = this.#resolvedFileByInputSourceName.get(inputSourceName);
236
195
 
237
- const fsPathWithTheRightCasing = path.join(
238
- this.#projectRoot,
239
- trueCaseFsPath,
240
- );
196
+ if (existing !== undefined) {
197
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
198
+ The cache is type-unsafe, but we are sure this is a ProjectResolvedFile
199
+ because of how its input source name is created */
200
+ const existingProjectResolvedFile = existing as ProjectResolvedFile;
201
+
202
+ return {
203
+ success: true,
204
+ value: existingProjectResolvedFile,
205
+ };
206
+ }
241
207
 
242
- const resolvedFile: ProjectResolvedFile =
243
- new ProjectResolvedFileImplementation({
244
- sourceName,
245
- fsPath: fsPathWithTheRightCasing,
246
- content: await readFileContent(fsPathWithTheRightCasing),
247
- });
208
+ if (relativeFilePath.startsWith("node_modules" + path.sep)) {
209
+ return {
210
+ success: false,
211
+ error: {
212
+ type: RootResolutionErrorType.PROJECT_ROOT_FILE_IN_NODE_MODULES,
213
+ absoluteFilePath,
214
+ },
215
+ };
216
+ }
248
217
 
249
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
218
+ const pathValidation = await validateFsPath(
219
+ this.#projectRoot,
220
+ relativeFilePath,
221
+ );
250
222
 
251
- return resolvedFile;
252
- });
253
- }
223
+ let realCasingRelativePath = relativeFilePath;
224
+ if (pathValidation.success === false) {
225
+ if (pathValidation.error.type === PathValidationErrorType.DOESNT_EXIST) {
226
+ return {
227
+ success: false,
228
+ error: {
229
+ type: RootResolutionErrorType.PROJECT_ROOT_FILE_DOESNT_EXIST,
230
+ absoluteFilePath,
231
+ },
232
+ };
233
+ }
254
234
 
255
- public async resolveNpmDependencyFileAsRoot(
256
- npmModule: string,
257
- ): Promise<NpmPackageResolvedFile> {
258
- return this.#mutex.exclusiveRun(async () => {
259
- const parsedNpmModule = this.#parseNpmDirectImport(npmModule);
235
+ // Now that we have the correct casing, we "fix" the input source name.
236
+ realCasingRelativePath = pathValidation.error.correctCasing;
237
+ inputSourceName = sourceNamePathJoin(
238
+ this.#hhProjectPackage.inputSourceNameRoot,
239
+ fsPathToSourceNamePath(realCasingRelativePath),
240
+ );
241
+ }
260
242
 
261
- if (parsedNpmModule === undefined) {
262
- throw new HardhatError(
263
- HardhatError.ERRORS.SOLIDITY.RESOLVE_NPM_FILE_WITH_INVALID_FORMAT,
264
- { module: npmModule },
265
- );
266
- }
243
+ // Maybe it was already resolved, so we need to check with the right
244
+ // casing
245
+ const resolvedWithTheRightCasing =
246
+ this.#resolvedFileByInputSourceName.get(inputSourceName);
247
+ if (resolvedWithTheRightCasing !== undefined) {
248
+ const resolvedWithTheRightCasingProjectResolvedFile =
249
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
250
+ -- Same as above, we know it's a project file because of its input
251
+ source name */
252
+ resolvedWithTheRightCasing as ProjectResolvedFile;
253
+
254
+ return {
255
+ success: true,
256
+ value: resolvedWithTheRightCasingProjectResolvedFile,
257
+ };
258
+ }
267
259
 
268
- if (await this.#isDirectImportLocal(this.#projectRoot, npmModule)) {
269
- const directory =
270
- this.#getDirectImportLocalDesambiguationPrefix(npmModule);
260
+ const fsPathWithTheRightCasing = path.join(
261
+ this.#projectRoot,
262
+ realCasingRelativePath,
263
+ );
271
264
 
272
- throw new HardhatError(
273
- HardhatError.ERRORS.SOLIDITY.RESOLVE_NPM_FILE_CLASHES_WITH_LOCAL_FILES,
274
- {
275
- module: npmModule,
276
- directory,
277
- },
278
- );
279
- }
265
+ const resolvedFile = await this.#buildResolvedFile({
266
+ npmPackage: this.#hhProjectPackage,
267
+ fsPath: fsPathWithTheRightCasing,
268
+ inputSourceName,
269
+ });
280
270
 
281
- const modulePackageName = parsedNpmModule.package;
271
+ this.#resolvedFileByInputSourceName.set(inputSourceName, resolvedFile);
282
272
 
283
- const npmPackage = await this.#resolveNpmPackage({
284
- from: PROJECT_ROOT_SENTINEL,
285
- packageName: modulePackageName,
286
- });
273
+ /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
274
+ We know it's a project file, because we created it. */
275
+ const resolvedFileAsProjectFile = resolvedFile as ProjectResolvedFile;
287
276
 
288
- assertHardhatInvariant(
289
- npmPackage !== PROJECT_ROOT_SENTINEL,
290
- "Resolving a local file as if it were an npm module",
291
- );
277
+ return {
278
+ success: true,
279
+ value: resolvedFileAsProjectFile,
280
+ };
281
+ }
292
282
 
293
- const subpath = parsedNpmModule.subpath;
294
- const resolvedSubpath = resolveSubpath(npmPackage, subpath);
283
+ public toJSON(): {
284
+ resolvedFileBySourceName: Record<string, ResolvedFile>;
285
+ remappedNpmPackagesGraph: RemappedNpmPackagesGraphJson;
286
+ } {
287
+ return {
288
+ resolvedFileBySourceName: Object.fromEntries(
289
+ this.#resolvedFileByInputSourceName.entries(),
290
+ ),
291
+ remappedNpmPackagesGraph: this.#npmPackageGraph.toJSON(),
292
+ };
293
+ }
295
294
 
296
- const relativeFsPath = sourceNamePathToFsPath(resolvedSubpath);
297
- let trueCaseFsPath: string;
298
- try {
299
- trueCaseFsPath = await getFileTrueCase(
300
- npmPackage.rootFsPath,
301
- relativeFsPath,
302
- );
303
- } catch (error) {
304
- ensureError(error, FileNotFoundError);
295
+ async #resolveNpmDependencyFileAsRoot(
296
+ npmModule: string,
297
+ ): Promise<
298
+ Result<
299
+ { file: NpmPackageResolvedFile; remapping?: ResolvedNpmUserRemapping },
300
+ NpmRootResolutionError
301
+ >
302
+ > {
303
+ // We want to be sure that the resolution of npm root files is treated
304
+ // exactly like imports, so we use a fake root file and resolve the
305
+ // npmModule as if it were a directImport inside of it.
306
+ //
307
+ // NOTE: As we use a public method here, we don't acquire the mutex,
308
+ // but we don't modify the state in this method itself.
309
+ const parsedNpmModule = parseNpmDirectImport(npmModule);
310
+
311
+ if (parsedNpmModule === undefined) {
312
+ return {
313
+ success: false,
314
+ error: {
315
+ type: RootResolutionErrorType.NPM_ROOT_FILE_NAME_WITH_INVALID_FORMAT,
316
+ npmModule,
317
+ },
318
+ };
319
+ }
305
320
 
306
- throw new HardhatError(
307
- HardhatError.ERRORS.SOLIDITY.RESOLVE_NON_EXISTENT_NPM_ROOT,
308
- { module: npmModule },
309
- error,
310
- );
311
- }
321
+ const result = await this.#resolveImport(this.#fakeRootFile, npmModule);
312
322
 
313
- if (relativeFsPath !== trueCaseFsPath) {
314
- throw new HardhatError(
315
- HardhatError.ERRORS.SOLIDITY.RESOLVE_WRONG_CASING_NPM_ROOT,
316
- { module: npmModule },
317
- );
318
- }
323
+ if (result.success === false) {
324
+ return {
325
+ success: false,
326
+ error: this.#importResolutionErrorToNpmRootResolutionError(
327
+ npmModule,
328
+ result.error,
329
+ ),
330
+ };
331
+ }
319
332
 
320
- const sourceName = sourceNamePathJoin(
321
- npmPackageToRootSourceName(npmPackage.name, npmPackage.version),
322
- // We use the subpath (pre-resolution) to create source names
323
- subpath,
324
- );
333
+ const resolvedFile = result.value.file;
325
334
 
326
- const resolved = this.#resolvedFileBySourceName.get(sourceName);
335
+ assertHardhatInvariant(
336
+ result.value.remapping !== undefined,
337
+ "We must have a remapping here, becase we either resolved though a user remapping, or npm",
338
+ );
327
339
 
328
- if (resolved !== undefined) {
329
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
330
- -- If it was, it's a ProjectResolvedFile */
331
- return resolved as NpmPackageResolvedFile;
332
- }
340
+ // If resolving this fake import results in using a user remapping, we
341
+ // need to return it.
342
+ //
343
+ // If instead, if using a generated remapping for that import, we don't
344
+ // return it, as this is not a real import.
345
+ const remapping = isResolvedUserRemapping(result.value.remapping)
346
+ ? result.value.remapping
347
+ : undefined;
348
+
349
+ // This could happen due to a user remapping
350
+ if (resolvedFile.type !== ResolvedFileType.NPM_PACKAGE_FILE) {
351
+ assertHardhatInvariant(
352
+ remapping !== undefined,
353
+ "Expected user remapping to be present if the import resolved to a local file",
354
+ );
333
355
 
334
- const fsPath = path.join(npmPackage.rootFsPath, trueCaseFsPath);
356
+ return {
357
+ success: false,
358
+ error: {
359
+ type: RootResolutionErrorType.NPM_ROOT_FILE_RESOLVES_TO_PROJECT_FILE,
360
+ npmModule,
361
+ userRemapping: {
362
+ originalUserRemapping: remapping.originalFormat,
363
+ actualUserRemapping: formatRemapping(remapping),
364
+ remappingSource: remapping.source,
365
+ },
366
+ resolvedFileFsPath: resolvedFile.fsPath,
367
+ },
368
+ };
369
+ }
335
370
 
336
- const resolvedFile: NpmPackageResolvedFile =
337
- new NpmPackageResolvedFileImplementation({
338
- sourceName,
339
- fsPath,
340
- content: await readFileContent(fsPath),
341
- package: npmPackage,
342
- });
371
+ // By this point, we know if that we have a user remapping, it's into an
372
+ // npm package, because otherwise we would have returned an error.
373
+ // We need to do this invariant assertion here, because otherwise TS will
374
+ // complain.
375
+ let remappingReuslt: ResolvedNpmUserRemapping | undefined;
376
+ if (remapping !== undefined) {
377
+ assertHardhatInvariant(
378
+ remapping.type === UserRemappingType.NPM,
379
+ "If we have a user remapping, it must be a npm remapping",
380
+ );
343
381
 
344
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
382
+ remappingReuslt = remapping;
383
+ }
345
384
 
346
- return resolvedFile;
347
- });
385
+ return {
386
+ success: true,
387
+ value: {
388
+ file: resolvedFile,
389
+ remapping: remappingReuslt,
390
+ },
391
+ };
348
392
  }
349
393
 
350
- public async resolveImport(
394
+ async #resolveImport(
351
395
  from: ResolvedFile,
352
396
  importPath: string,
353
- ): Promise<ResolvedFile> {
354
- return this.#mutex.exclusiveRun(async () => {
355
- let directImport = importPath;
397
+ ): Promise<
398
+ Result<
399
+ {
400
+ file: ResolvedFile;
401
+ remapping?: Remapping | ResolvedUserRemapping;
402
+ },
403
+ ImportResolutionError
404
+ >
405
+ > {
406
+ // Imports shouldn't include windows separators
407
+ if (importPath.includes("\\")) {
408
+ return {
409
+ success: false,
410
+ error: {
411
+ type: ImportResolutionErrorType.IMPORT_WITH_WINDOWS_PATH_SEPARATORS,
412
+ fromFsPath: from.fsPath,
413
+ importPath,
414
+ },
415
+ };
416
+ }
356
417
 
357
- if (path.sep !== "/" && importPath.includes(path.sep)) {
358
- throw new HardhatError(
359
- HardhatError.ERRORS.SOLIDITY.IMPORT_PATH_WITH_WINDOWS_SEPARATOR,
360
- {
418
+ const isRelativeImport =
419
+ importPath.startsWith("./") || importPath.startsWith("../");
420
+
421
+ const directImport = isRelativeImport
422
+ ? sourceNamePathJoin(path.dirname(from.inputSourceName), importPath)
423
+ : importPath;
424
+
425
+ if (isRelativeImport) {
426
+ // If the import is relative, it shouldn't leave its package
427
+ if (!directImport.startsWith(from.package.inputSourceNameRoot)) {
428
+ return {
429
+ success: false,
430
+ error: {
431
+ type: ImportResolutionErrorType.ILLEGAL_RELATIVE_IMPORT,
432
+ fromFsPath: from.fsPath,
361
433
  importPath,
362
- from: shortenPath(from.fsPath),
363
434
  },
364
- );
435
+ };
365
436
  }
366
437
 
367
- if (importPath.startsWith("./") || importPath.startsWith("../")) {
368
- directImport = sourceNamePathJoin(
369
- path.dirname(from.sourceName),
370
- importPath,
371
- );
372
-
373
- if (from.type === ResolvedFileType.NPM_PACKAGE_FILE) {
374
- if (!directImport.startsWith(from.package.rootSourceName)) {
375
- throw new HardhatError(
376
- HardhatError.ERRORS.SOLIDITY.ILLEGAL_PACKAGE_IMPORT,
377
- {
378
- importPath,
379
- from: shortenPath(from.fsPath),
380
- },
381
- );
382
- }
383
- } else {
384
- if (directImport.startsWith("../")) {
385
- throw new HardhatError(
386
- HardhatError.ERRORS.SOLIDITY.ILEGALL_PROJECT_IMPORT,
387
- {
388
- importPath,
389
- from: shortenPath(from.fsPath),
390
- },
391
- );
392
- }
393
- }
438
+ // It also shouldn't get into its package's node_modules
439
+ if (
440
+ directImport.startsWith(
441
+ sourceNamePathJoin(from.package.inputSourceNameRoot, "node_modules"),
442
+ )
443
+ ) {
444
+ return {
445
+ success: false,
446
+ error: {
447
+ type: ImportResolutionErrorType.RELATIVE_IMPORT_INTO_NODE_MODULES,
448
+ fromFsPath: from.fsPath,
449
+ importPath,
450
+ },
451
+ };
394
452
  }
453
+ }
395
454
 
396
- switch (from.type) {
397
- case ResolvedFileType.PROJECT_FILE:
398
- return this.#resolveImportFromProjectFile({
399
- from,
400
- importPath,
401
- directImport,
402
- });
455
+ // Now, we get the best user remapping, if there's any.
456
+ const bestUserRemappingResult =
457
+ await this.#npmPackageGraph.selectBestUserRemapping(from, directImport);
403
458
 
404
- case ResolvedFileType.NPM_PACKAGE_FILE:
405
- return this.#resolveImportFromNpmPackageFile({
406
- from,
459
+ if (bestUserRemappingResult.success === false) {
460
+ return {
461
+ success: false,
462
+ error: {
463
+ type: ImportResolutionErrorType.IMPORT_WITH_REMAPPING_ERRORS,
464
+ fromFsPath: from.fsPath,
465
+ importPath,
466
+ remappingErrors: bestUserRemappingResult.error,
467
+ },
468
+ };
469
+ }
470
+
471
+ const bestUserRemapping = bestUserRemappingResult.value;
472
+
473
+ if (isRelativeImport) {
474
+ // Relative imports should be resolved based on the file system, so
475
+ // they should not be affected by user remapping.
476
+ if (bestUserRemapping !== undefined) {
477
+ return {
478
+ success: false,
479
+ error: {
480
+ type: ImportResolutionErrorType.RELATIVE_IMPORT_CLASHES_WITH_USER_REMAPPING,
481
+ fromFsPath: from.fsPath,
407
482
  importPath,
408
483
  directImport,
409
- });
484
+ userRemapping: this.#buildUserRemappingReference({
485
+ userRemapping: bestUserRemapping,
486
+ }),
487
+ },
488
+ };
410
489
  }
411
- });
412
- }
413
490
 
414
- public getRemappings(): Remapping[] {
415
- const userRemappings = this.#userRemappings.map((remapping) => ({
416
- context: remapping.context,
417
- prefix: remapping.prefix,
418
- target: remapping.target,
419
- }));
420
-
421
- const remappings: Remapping[] = [];
422
-
423
- for (const [
424
- thePackage,
425
- dependenciesMap,
426
- ] of this.#dependencyMaps.entries()) {
427
- let context: string;
428
-
429
- if (thePackage === PROJECT_ROOT_SENTINEL) {
430
- context = "";
431
- } else {
432
- context = thePackage.rootSourceName;
491
+ return this.#resolveRelativeImport({
492
+ from,
493
+ importPath,
494
+ directImport,
495
+ });
496
+ } else {
497
+ if (bestUserRemapping !== undefined) {
498
+ // If the import isn't relative, and there's a user remapping, we
499
+ // prioritize that.
500
+ return this.#resolveUserRemappedImport({
501
+ from,
502
+ importPath,
503
+ directImport,
504
+ remapping: bestUserRemapping,
505
+ });
433
506
  }
434
507
 
435
- for (const [importedPackage, dependency] of dependenciesMap.entries()) {
436
- // As `hardhat/console.sol` is always resolved through npm, even if the
437
- // `hardhat/` folder exists in the root of the package/project, we
438
- // only remap that file.
439
- //
440
- // We should revisit this if we exported more solidity files in the
441
- // hardhat package in the future.
442
- //
443
- // Also note that we are using the importedPackageName here, and not
444
- // the dependency's name, and that's because we always resolve 'hardhat'
445
- // as the hh package itself. If someone installs another package as
446
- // "hardhat", it may break.
447
- if (
448
- dependency !== PROJECT_ROOT_SENTINEL &&
449
- importedPackage === "hardhat"
450
- ) {
451
- const prefix = importedPackage + "/console.sol";
452
- const target = dependency.rootSourceName + "console.sol";
453
-
454
- remappings.push({ context, prefix, target });
455
- } else {
456
- const prefix = importedPackage + "/";
457
-
458
- const target =
459
- dependency === PROJECT_ROOT_SENTINEL
460
- ? ""
461
- : dependency.rootSourceName;
462
-
463
- // If a dependency is being remapped by the user using the same
464
- // prefix, we don't want to override it, as it can cause problems
465
- // when a file from that dependency is also treated as a root.
466
- //
467
- // For example, if the user sets this remapping
468
- // "forge-std/=npm/forge-std@1.9.4/src/" and for some reason also
469
- // compiles "forge-std/src/Test.sol" as a root.
470
- //
471
- // Without this check, we would have two remappings in the solc input:
472
- // "forge-std/=npm/forge-std@1.9.4/src/"
473
- // "forge-std/=npm/forge-std@1.9.4/"
474
- // and the latter would win, leading to a compilation error.
475
- if (thePackage === PROJECT_ROOT_SENTINEL) {
476
- if (this.#userRemappings.some((r) => r.prefix === prefix)) {
477
- continue;
478
- }
479
- }
480
-
481
- remappings.push({ context, prefix, target });
482
- }
508
+ // Otherwise it should be resolved through npm
509
+ const npmResolutionResult = await this.#resolveImportThroughNpm({
510
+ from,
511
+ importPath,
512
+ directImport,
513
+ });
514
+
515
+ if (npmResolutionResult.success === true) {
516
+ return { success: true, value: npmResolutionResult.value };
483
517
  }
484
- }
485
518
 
486
- // TODO: Always order this in a consistent way
487
- for (const [packageSourceName, prefixes] of this.#localPrefixesByPackage) {
488
- for (const prefix of prefixes) {
489
- remappings.push({
490
- context: packageSourceName.rootSourceName,
491
- prefix,
492
- target: packageSourceName.rootSourceName + prefix,
519
+ // If the npm resolution fails because the package was not installed, or
520
+ // because the import was invalid, we try to detect if the user was
521
+ // trying to use a direct import (i.e. not relative) to import a local
522
+ // file.
523
+ //
524
+ // We do this to improve the error message that we generate, and suggest
525
+ // a user remapping if they insist on using direct imports.
526
+ if (
527
+ npmResolutionResult.error.type ===
528
+ ImportResolutionErrorType.IMPORT_OF_UNINSTALLED_PACKAGE ||
529
+ npmResolutionResult.error.type ===
530
+ ImportResolutionErrorType.IMPORT_WITH_INVALID_NPM_SYNTAX
531
+ ) {
532
+ const improvedError = await this.#tryToGenerateDirectLocalImportError({
533
+ from,
534
+ importPath,
493
535
  });
536
+
537
+ if (improvedError !== undefined) {
538
+ return {
539
+ success: false,
540
+ error: improvedError,
541
+ };
542
+ }
494
543
  }
495
- }
496
544
 
497
- // We sort the remappings acording to the remappings selection rules, plus
498
- // the targets, which shouldn't be needed.
499
- remappings
500
- .sort((a, b) => a.target.localeCompare(b.target))
501
- .sort((a, b) => a.target.length - b.target.length)
502
- .sort((a, b) => a.prefix.localeCompare(b.prefix))
503
- .sort((a, b) => a.prefix.length - b.prefix.length)
504
- .sort((a, b) => a.context.localeCompare(b.context))
505
- .sort((a, b) => a.context.length - b.context.length);
506
-
507
- return [...userRemappings, ...remappings];
545
+ return npmResolutionResult;
546
+ }
508
547
  }
509
548
 
510
- // >>>>>>>>>> BEGIN SECTION: Import resolution selection
511
- //
512
- // The private methods in this section are in charge of selecting which import
513
- // resolution technique to use, but they don't create any ResolvedFile.
514
- //
515
- // These techniques are:
516
- // 1. Resolving an import to a project file
517
- // 2. Resolving an import remapped by the user into an npm package
518
- // 3. Resolving an import from an npm package to one of its own files with a
519
- // relative import
520
- // 4. Resolving an import from an npm package to one of its own files with a
521
- // direct import — This case is different from 3, as without especial care
522
- // it could be affected by one of the user remappings.
523
- // 5. Resolving an import to a different npm package using our own remappings
524
-
525
- /**
526
- * Resolves an import from a project file.
527
- *
528
- * This method applies the user remappings, if necessary, and uses the
529
- * appropriate resolution technique.
530
- *
531
- * @param from The file from which the import is being resolved.
532
- * @param importPath The import path, as written in the source code.
533
- * @param directImport The direct import path, after resolving relative paths,
534
- * but before applying any remapping.
535
- */
536
- async #resolveImportFromProjectFile({
549
+ async #resolveRelativeImport({
537
550
  from,
538
551
  importPath,
539
552
  directImport,
540
553
  }: {
541
- from: ProjectResolvedFile;
542
- directImport: string;
554
+ from: ResolvedFile;
543
555
  importPath: string;
544
- }): Promise<ResolvedFile> {
545
- const bestUserRemapping = selectBestRemapping(
546
- from.sourceName,
547
- directImport,
548
- this.#userRemappings,
549
- );
556
+ directImport: string;
557
+ }): Promise<Result<{ file: ResolvedFile }, ImportResolutionError>> {
558
+ const inputSourceName = directImport;
550
559
 
551
- if (bestUserRemapping !== undefined) {
552
- return this.#resolveUserRemappedImportFromProjectFile({
553
- from,
554
- importPath,
555
- directImport,
556
- remapping: bestUserRemapping,
557
- });
560
+ const existing = this.#resolvedFileByInputSourceName.get(inputSourceName);
561
+ if (existing !== undefined) {
562
+ return { success: true, value: { file: existing } };
558
563
  }
559
564
 
560
- if (await this.#isDirectImportLocal(this.#projectRoot, directImport)) {
561
- return this.#resolveImportToProjectFile({
562
- from,
563
- importPath,
564
- fsPathWithinTheProject: sourceNamePathToFsPath(directImport),
565
- });
566
- }
565
+ const relativeSourceNamePath = this.#getRelativeSourceNamePath({
566
+ npmPackage: from.package,
567
+ fileInputSourceName: inputSourceName,
568
+ });
567
569
 
568
- return this.#resolveImportThroughNpm({
570
+ const relativeFsPath = sourceNamePathToFsPath(relativeSourceNamePath);
571
+
572
+ return this.#commonImportResolution({
569
573
  from,
570
574
  importPath,
571
- directImport,
575
+ npmPackage: from.package,
576
+ inputSourceName,
577
+ relativeFsPathWithinPackage: relativeFsPath,
578
+ subpath: relativeSourceNamePath,
572
579
  });
573
580
  }
574
581
 
575
582
  /**
576
- * Resolves an import from a project file that is affected by a user
577
- * remapping.
578
- *
579
- * Note that this method must only be called with the best user remapping
580
- * applicable to the import, as defined by solc. Otherwise, it's behavior will
581
- * be misleading.
582
- *
583
- * @param from The file from which the import is being resolved.
584
- * @param importPath The import path, as written in the source code.
585
- * @param directImport The direct import path, after resolving relative paths,
586
- * but before applying any remapping.
587
- * @param remapping The user remapping that will be applied.
583
+ * Resolves a user remapped import.
584
+ * @returns The resolved file, or an error. If successful, the remapping is
585
+ * always present, and of type `ResolvedUserRemapping`.
588
586
  */
589
- async #resolveUserRemappedImportFromProjectFile({
587
+ async #resolveUserRemappedImport({
590
588
  from,
591
589
  importPath,
592
590
  directImport,
593
591
  remapping,
594
592
  }: {
595
- from: ProjectResolvedFile;
593
+ from: ResolvedFile;
596
594
  importPath: string;
597
595
  directImport: string;
598
596
  remapping: ResolvedUserRemapping;
599
- }): Promise<ResolvedFile> {
597
+ }): Promise<
598
+ Result<
599
+ { file: ResolvedFile; remapping?: Remapping | ResolvedUserRemapping },
600
+ ImportResolutionError
601
+ >
602
+ > {
600
603
  const remappedDirectImport = applyValidRemapping(directImport, remapping);
601
604
 
602
- // Special case, where a user remapping's target is an npm pacakge
603
- if (remapping.targetNpmPackage !== undefined) {
604
- return this.#resolveImportToNpmPackageRemappedByUser({
605
- from,
606
- importPath,
607
- directImport: remappedDirectImport,
608
- remapping: {
609
- // This weird syntax is because TS doesn't realize that
610
- // bestUserRemapping is Required<ResolvedUserRemapping> here
611
- ...remapping,
612
- targetNpmPackage: remapping.targetNpmPackage,
613
- },
614
- });
605
+ const inputSourceName = remappedDirectImport;
606
+ const existing =
607
+ this.#resolvedFileByInputSourceName.get(remappedDirectImport);
608
+ if (existing !== undefined) {
609
+ return { success: true, value: { file: existing, remapping } };
615
610
  }
616
611
 
617
- if (
618
- !(await this.#isDirectImportLocal(
619
- this.#projectRoot,
620
- remappedDirectImport,
621
- ))
622
- ) {
623
- throw new HardhatError(
624
- HardhatError.ERRORS.SOLIDITY.ILLEGAL_PROJECT_IMPORT_AFTER_REMAPPING,
625
- {
626
- importPath,
627
- from: shortenPath(from.fsPath),
628
- remapping: remapping.rawFormat,
629
- remappedDirectImport,
630
- },
631
- );
632
- }
612
+ const fromNpmPackage =
613
+ from.type === ResolvedFileType.NPM_PACKAGE_FILE
614
+ ? from.package
615
+ : this.#hhProjectPackage;
616
+
617
+ // We get the npm package that's the target of the remapping. If none
618
+ // is present, that's because it's remapping to a local file, so it's
619
+ // the fromNpmPackage.
620
+ const targetNpmPackage =
621
+ remapping.type === UserRemappingType.NPM
622
+ ? remapping.targetNpmPackage.package
623
+ : fromNpmPackage;
624
+
625
+ // A user remapping is created based on the fs path in the package, so
626
+ // we can get the relative path based on the input source name root of the
627
+ // target package.
628
+ const relativeSourceNamePath = this.#getRelativeSourceNamePath({
629
+ npmPackage: targetNpmPackage,
630
+ fileInputSourceName: inputSourceName,
631
+ });
633
632
 
634
- return this.#resolveImportToProjectFile({
633
+ const relativeFsPath = sourceNamePathToFsPath(relativeSourceNamePath);
634
+
635
+ return this.#commonImportResolution({
635
636
  from,
636
637
  importPath,
637
- fsPathWithinTheProject: sourceNamePathToFsPath(remappedDirectImport),
638
+ npmPackage: targetNpmPackage,
639
+ inputSourceName,
640
+ relativeFsPathWithinPackage: relativeFsPath,
641
+ subpath: relativeSourceNamePath,
642
+ userRemapping: remapping,
638
643
  });
639
644
  }
640
645
 
641
646
  /**
642
- * Resolves an import from an npm file.
643
- *
644
- * This method does not apply any remapping that may be present in the npm
645
- * package.
646
- *
647
- * @param from The file from which the import is being resolved.
648
- * @param importPath The import path, as written in the source code.
649
- * @param directImport The direct import path, after resolving relative paths,
650
- * but without applying any remapping.
647
+ * Resolves an import through npm.
648
+ * @returns The resolved file, or an error. If successful, the remapping is
649
+ * always present.
651
650
  */
652
- async #resolveImportFromNpmPackageFile({
651
+ async #resolveImportThroughNpm({
653
652
  from,
654
653
  importPath,
655
654
  directImport,
656
655
  }: {
657
- from: NpmPackageResolvedFile;
658
- directImport: string;
656
+ from: ResolvedFile;
659
657
  importPath: string;
660
- }): Promise<ResolvedFile> {
661
- // If we wanted to apply its own remappings, this would be the place.
662
- // Initially we won't support it.
663
- if (directImport.startsWith(from.package.rootSourceName)) {
664
- return this.#resolveRelativeImportFromNpmPackage({
665
- from,
666
- importPath,
667
- directImport,
668
- });
658
+ directImport: string;
659
+ }): Promise<
660
+ Result<
661
+ { file: ResolvedFile; remapping?: Remapping | ResolvedUserRemapping },
662
+ ImportResolutionError
663
+ >
664
+ > {
665
+ const parsedDirectImport = parseNpmDirectImport(directImport);
666
+
667
+ if (parsedDirectImport === undefined) {
668
+ return {
669
+ success: false,
670
+ error: {
671
+ type: ImportResolutionErrorType.IMPORT_WITH_INVALID_NPM_SYNTAX,
672
+ fromFsPath: from.fsPath,
673
+ importPath,
674
+ },
675
+ };
676
+ }
677
+
678
+ const fromNpmPackage =
679
+ from.type === ResolvedFileType.NPM_PACKAGE_FILE
680
+ ? from.package
681
+ : this.#hhProjectPackage;
682
+
683
+ const installationName = parsedDirectImport.package;
684
+
685
+ const dependencyResolution =
686
+ await this.#npmPackageGraph.resolveDependencyByInstallationName(
687
+ fromNpmPackage,
688
+ installationName,
689
+ );
690
+
691
+ if (dependencyResolution === undefined) {
692
+ return {
693
+ success: false,
694
+ error: {
695
+ type: ImportResolutionErrorType.IMPORT_OF_UNINSTALLED_PACKAGE,
696
+ fromFsPath: from.fsPath,
697
+ importPath,
698
+ installationName: parsedDirectImport.package,
699
+ },
700
+ };
669
701
  }
670
702
 
671
- // This was already a direct import, and may be to the same package.
672
- // As we allow this imports in the local project files, we should also allow
673
- // them on npm packages. If we don't projects won't be easily distributable
674
- // through npm, even if they don't use remappings.
703
+ const dependency = dependencyResolution.package;
704
+
705
+ const subpath = parsedDirectImport.subpath;
706
+
707
+ let resolvedSubpath: string | undefined;
675
708
  if (
676
- await this.#isDirectImportLocal(from.package.rootFsPath, directImport)
709
+ dependency.exports !== undefined ||
710
+ NPM_PACKAGES_WITH_SIMULATED_PACKAGE_EXPORTS.has(dependency.name)
677
711
  ) {
678
- const resolvedFile = await this.#resolveLocalImportFromNpmPackage({
679
- from,
680
- importPath,
681
- directImport,
682
- });
712
+ const dependencyWithPackageExports = {
713
+ ...dependency,
714
+ exports: dependency.exports ?? {
715
+ "./*.sol": "./src/*.sol",
716
+ },
717
+ };
683
718
 
684
- let prefixesNeededByPackage = this.#localPrefixesByPackage.get(
685
- from.package,
719
+ const pathResolutionResult = resolveSubpathWithPackageExports(
720
+ dependencyWithPackageExports,
721
+ subpath,
686
722
  );
687
723
 
688
- if (prefixesNeededByPackage === undefined) {
689
- prefixesNeededByPackage = new Set();
690
- this.#localPrefixesByPackage.set(from.package, prefixesNeededByPackage);
724
+ if (pathResolutionResult.success === false) {
725
+ return {
726
+ success: false,
727
+ error: {
728
+ type: ImportResolutionErrorType.IMPORT_OF_NON_EXPORTED_NPM_FILE,
729
+ fromFsPath: from.fsPath,
730
+ importPath,
731
+ ...this.#buildResolvedFileReference({
732
+ npmPackage: dependency,
733
+ subpath,
734
+ }),
735
+ },
736
+ };
691
737
  }
692
738
 
693
- prefixesNeededByPackage.add(
694
- this.#getDirectImportLocalDesambiguationPrefix(directImport),
695
- );
696
-
697
- return resolvedFile;
739
+ resolvedSubpath = pathResolutionResult.value;
698
740
  }
699
741
 
700
- return this.#resolveImportThroughNpm({
701
- from,
702
- importPath,
703
- directImport,
704
- });
705
- }
742
+ const inputSourceName = sourceNamePathJoin(
743
+ dependency.inputSourceNameRoot,
744
+ resolvedSubpath ?? subpath,
745
+ );
706
746
 
707
- /**
708
- * This method resolves an import that has to go through the npm resolution
709
- * process and selects the appropriate technique to resolve it.
710
- *
711
- * This method does not apply nor define any remapping, but it populates the
712
- * `#dependencyMaps` with dependencies that each package uses, so that we can
713
- * create all the necessary remappings at the end of the resolution process.
714
- *
715
- * @param from The file from which the import is being resolved.
716
- * @param importPath The import path, as written in the source code.
717
- * @param directImport The direct import path, after resolving relative paths,
718
- * but without applying any remapping.
719
- */
720
- async #resolveImportThroughNpm({
721
- from,
722
- importPath,
723
- directImport,
724
- }: {
725
- from: ResolvedFile;
726
- importPath: string;
727
- directImport: string;
728
- }): Promise<ResolvedFile> {
729
- const parsedDirectImport = this.#parseNpmDirectImport(directImport);
747
+ // There are two types of remappings that we may use for npm imports.
748
+ //
749
+ // One is a generic remapping from fromNpmPackage to dependency using
750
+ // installationName.
751
+ //
752
+ // The other one, while more verbose, is a remapping specifically from
753
+ // forNpmPackage into inputSourceName, using directImport.
754
+ //
755
+ // We use the second one when applying package.exports, and it changes the
756
+ // subpath of the file.
757
+ const remapping =
758
+ resolvedSubpath !== undefined && resolvedSubpath !== subpath
759
+ ? await this.#npmPackageGraph.generateRemappingIntoNpmFile(
760
+ fromNpmPackage,
761
+ directImport,
762
+ inputSourceName,
763
+ )
764
+ : dependencyResolution.generatedRemapping;
730
765
 
731
- if (parsedDirectImport === undefined) {
732
- throw new HardhatError(HardhatError.ERRORS.SOLIDITY.INVALID_NPM_IMPORT, {
733
- importPath,
734
- from: shortenPath(from.fsPath),
735
- });
766
+ const existing = this.#resolvedFileByInputSourceName.get(inputSourceName);
767
+ if (existing !== undefined) {
768
+ return {
769
+ success: true,
770
+ value: {
771
+ file: existing,
772
+ remapping,
773
+ },
774
+ };
736
775
  }
737
776
 
738
- const dependency = await this.#resolveNpmPackageForImport({
739
- from,
740
- importPath,
741
- importPackageName: parsedDirectImport.package,
742
- });
743
-
744
- if (dependency === PROJECT_ROOT_SENTINEL) {
745
- return this.#resolveImportToProjectFile({
746
- from,
747
- importPath,
748
- // If we import a file through npm and end up in the Hardhat project,
749
- // we are going to remap the importPackageName to "", so that the path
750
- // section of the parsed direct import should be the relative path.
751
- fsPathWithinTheProject: sourceNamePathToFsPath(
752
- parsedDirectImport.subpath,
753
- ),
754
- });
755
- }
777
+ const relativePath = resolvedSubpath ?? subpath;
778
+ const relativeFsPathWithinPackage = sourceNamePathToFsPath(relativePath);
756
779
 
757
- return this.#resolveImportToNpmPackage({
780
+ return this.#commonImportResolution({
758
781
  from,
759
782
  importPath,
760
- importedPackage: dependency,
761
- subpath: parsedDirectImport.subpath,
783
+ npmPackage: dependency,
784
+ inputSourceName,
785
+ relativeFsPathWithinPackage,
786
+ subpath,
787
+ generatedRemapping: remapping,
788
+ packageExportsResolvedSubpath: resolvedSubpath,
762
789
  });
763
790
  }
764
791
 
765
- // >>>>>>>>>> END SECTION: Import resolution selection
766
-
767
- // >>>>>>>>>> BEGIN SECTION: Import resolution techniques
768
- //
769
- // The private methods in this section implement the different import
770
- // import resolution techniques, which have been explained in the previous
771
- // section.
772
-
773
792
  /**
774
- * This method implements the import resolution technique number 1: Importing
775
- * a file that is within the project. Note that this method applies both to
776
- * imports from project files as well as imports from npm packages that may
777
- * have the project as a dependency.
778
- *
779
- * @param from The file from which the import is being resolved.
780
- * @param importPath The import path, as written in the source code.
781
- * @param pathWithinTheProject The path within the project to import, after
782
- * normalizing relative paths, applying user remappings and/or stripping the
783
- * npm package name.
793
+ * Once the other methods selected which file to import, the rest of the logic
794
+ * is shared in this method.
784
795
  */
785
- async #resolveImportToProjectFile({
796
+ async #commonImportResolution({
786
797
  from,
787
798
  importPath,
788
- fsPathWithinTheProject,
799
+ npmPackage,
800
+ inputSourceName,
801
+ relativeFsPathWithinPackage,
802
+ subpath,
803
+ userRemapping,
804
+ generatedRemapping,
805
+ packageExportsResolvedSubpath,
789
806
  }: {
790
807
  from: ResolvedFile;
791
808
  importPath: string;
792
- fsPathWithinTheProject: string;
793
- }): Promise<ProjectResolvedFile> {
794
- const sourceName = fsPathToSourceNamePath(fsPathWithinTheProject);
795
- const existing = this.#resolvedFileBySourceName.get(sourceName);
796
- if (existing !== undefined) {
797
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
798
- The cache is type-unsafe, but we are sure this is a ProjectResolvedFile */
799
- return existing as ProjectResolvedFile;
800
- }
801
-
802
- // This is a project file, so if it was imported from a local file, this
803
- // is the direct import, without any remapping or necessary consideration.
804
- // If this was imported from an npm package, we are remapping the package
805
- // name of the import to "", so that the direct import is also the same as
806
- // the relative path.
807
- await this.#validateExistanceAndCasingOfImport({
808
- from,
809
- importPath,
810
- relativeFsPathToValidate: fsPathWithinTheProject,
811
- absoluteFsPathToValidateFrom: this.#projectRoot,
812
- });
813
-
814
- const fsPath = path.join(this.#projectRoot, fsPathWithinTheProject);
815
-
816
- const resolvedFile: ProjectResolvedFile =
817
- new ProjectResolvedFileImplementation({
818
- sourceName,
819
- fsPath,
820
- content: await readFileContent(fsPath),
821
- });
822
-
823
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
824
-
825
- return resolvedFile;
826
- }
827
-
828
- /**
829
- * This method implements the import resolution technique number 2: A project
830
- * file has an import that should be resolved to a file in an npm package due
831
- * to a user remapping.
832
- *
833
- * @param from The file from which the import is being resolved.
834
- * @param importPath The import path, as written in the source code.
835
- * @param directImport The direct import path, after resolving relative paths,
836
- * and applying the user remapping.
837
- * @param remapping The remapping that was applied.
838
- */
839
- async #resolveImportToNpmPackageRemappedByUser({
840
- from,
841
- importPath,
842
- directImport,
843
- remapping,
844
- }: {
845
- from: ProjectResolvedFile;
846
- importPath: string;
847
- directImport: string;
848
- remapping: Required<ResolvedUserRemapping>;
849
- }): Promise<NpmPackageResolvedFile> {
850
- const sourceName = directImport;
851
- const existing = this.#resolvedFileBySourceName.get(sourceName);
852
- if (existing !== undefined) {
853
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
854
- The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */
855
- return existing as NpmPackageResolvedFile;
856
- }
857
-
858
- const subpath = path.relative(
859
- remapping.targetNpmPackage.rootSourceName,
860
- directImport,
809
+ npmPackage: ResolvedNpmPackage;
810
+ inputSourceName: string;
811
+ relativeFsPathWithinPackage: string;
812
+ subpath: string;
813
+ userRemapping?: ResolvedUserRemapping;
814
+ generatedRemapping?: Remapping;
815
+ packageExportsResolvedSubpath?: string;
816
+ }): Promise<
817
+ Result<
818
+ { file: ResolvedFile; remapping?: Remapping | ResolvedUserRemapping },
819
+ ImportResolutionError
820
+ >
821
+ > {
822
+ const pathValidation = await validateFsPath(
823
+ npmPackage.rootFsPath,
824
+ relativeFsPathWithinPackage,
861
825
  );
862
- const resolvedSubpath = resolveSubpath(remapping.targetNpmPackage, subpath);
863
826
 
864
- // We don't add the dependency to `this.#dependencyMaps` because we
865
- // don't need a new remapping for this package, as it's already
866
- // remapped by the user.
827
+ if (pathValidation.success === false) {
828
+ if (pathValidation.error.type === PathValidationErrorType.DOESNT_EXIST) {
829
+ return {
830
+ success: false,
831
+ error: {
832
+ type: ImportResolutionErrorType.IMPORT_DOESNT_EXIST,
833
+ fromFsPath: from.fsPath,
834
+ importPath,
835
+ ...this.#buildResolvedFileReference({
836
+ npmPackage,
837
+ subpath,
838
+ userRemapping,
839
+ packageExportsResolvedSubpath,
840
+ }),
841
+ },
842
+ };
843
+ }
867
844
 
868
- await this.#validateExistanceAndCasingOfImport({
869
- from,
870
- importPath,
871
- relativeFsPathToValidate: sourceNamePathToFsPath(resolvedSubpath),
872
- absoluteFsPathToValidateFrom: remapping.targetNpmPackage.rootFsPath,
873
- usingPackageExports: remapping.targetNpmPackage.exports !== undefined,
874
- });
845
+ return {
846
+ success: false,
847
+ error: {
848
+ type: ImportResolutionErrorType.IMPORT_INVALID_CASING,
849
+ fromFsPath: from.fsPath,
850
+ importPath,
851
+ ...this.#buildResolvedFileReference({
852
+ npmPackage,
853
+ subpath,
854
+ userRemapping,
855
+ packageExportsResolvedSubpath,
856
+ }),
857
+ correctCasing: fsPathToSourceNamePath(
858
+ pathValidation.error.correctCasing,
859
+ ),
860
+ },
861
+ };
862
+ }
875
863
 
876
864
  const fsPath = path.join(
877
- remapping.targetNpmPackage.rootFsPath,
878
- resolvedSubpath,
865
+ npmPackage.rootFsPath,
866
+ relativeFsPathWithinPackage,
879
867
  );
880
868
 
881
- const resolvedFile: NpmPackageResolvedFile =
882
- new NpmPackageResolvedFileImplementation({
883
- sourceName,
884
- fsPath,
885
- content: await readFileContent(fsPath),
886
- package: remapping.targetNpmPackage,
887
- });
869
+ const resolvedFile = await this.#buildResolvedFile({
870
+ npmPackage,
871
+ fsPath,
872
+ inputSourceName,
873
+ });
888
874
 
889
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
875
+ this.#resolvedFileByInputSourceName.set(inputSourceName, resolvedFile);
890
876
 
891
- return resolvedFile;
877
+ return {
878
+ success: true,
879
+ value: {
880
+ file: resolvedFile,
881
+ // We only call this function with one of the two, but userRemappings
882
+ // have priority in general, so writing it this way is safer.
883
+ remapping: userRemapping ?? generatedRemapping,
884
+ },
885
+ };
892
886
  }
893
887
 
894
- /**
895
- * This method implements the import resolution technique number 3: A file
896
- * from an npm package is importing another file from the same package with a
897
- * relative import.
898
- *
899
- * @param from The file from which the import is being resolved.
900
- * @param importPath The import path, as written in the source code.
901
- * @param directImport The direct import path, after resolving relative paths.
902
- * It must start with the package's root source name.
903
- */
904
- async #resolveRelativeImportFromNpmPackage({
888
+ async #tryToGenerateDirectLocalImportError({
905
889
  from,
906
890
  importPath,
907
- directImport,
908
891
  }: {
909
- from: NpmPackageResolvedFile;
910
- directImport: string;
892
+ from: ResolvedFile;
911
893
  importPath: string;
912
- }): Promise<NpmPackageResolvedFile> {
913
- const sourceName = directImport;
914
- const existing = this.#resolvedFileBySourceName.get(sourceName);
915
- if (existing !== undefined) {
916
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
917
- The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */
918
- return existing as NpmPackageResolvedFile;
894
+ }): Promise<ImportResolutionError | undefined> {
895
+ let baseDir = path.dirname(from.fsPath);
896
+ const firstDir = importPath.substring(0, importPath.indexOf("/"));
897
+ // If there's no directory separator, or the import is just a directory
898
+ // we don't suggest a remapping
899
+ if (firstDir === "" || firstDir.length === importPath.length - 1) {
900
+ return undefined;
919
901
  }
920
902
 
921
- const relativePath = sourceNamePathToFsPath(
922
- path.relative(from.package.rootSourceName, directImport),
923
- );
903
+ while (baseDir.startsWith(from.package.rootFsPath)) {
904
+ const firstDirPath = path.join(baseDir, firstDir);
924
905
 
925
- await this.#validateExistanceAndCasingOfImport({
926
- from,
927
- importPath,
928
- relativeFsPathToValidate: relativePath,
929
- absoluteFsPathToValidateFrom: from.package.rootFsPath,
930
- });
931
-
932
- const filePath = path.join(from.package.rootFsPath, relativePath);
906
+ if (await exists(firstDirPath)) {
907
+ const baseDirSourceName = fsPathToSourceNamePath(
908
+ path.relative(from.package.rootFsPath, baseDir),
909
+ );
933
910
 
934
- const resolvedFile: NpmPackageResolvedFile =
935
- new NpmPackageResolvedFileImplementation({
936
- sourceName,
937
- fsPath: filePath,
938
- content: await readFileContent(filePath),
939
- package: from.package,
940
- });
911
+ const context =
912
+ from.package === this.#hhProjectPackage
913
+ ? baseDirSourceName !== ""
914
+ ? baseDirSourceName + "/"
915
+ : ""
916
+ : sourceNamePathJoin(
917
+ from.package.inputSourceNameRoot,
918
+ baseDirSourceName + "/",
919
+ );
920
+
921
+ const prefix = firstDir + "/";
922
+
923
+ const target =
924
+ from.package === this.#hhProjectPackage
925
+ ? prefix
926
+ : sourceNamePathJoin(from.package.inputSourceNameRoot, prefix);
927
+
928
+ return {
929
+ type: ImportResolutionErrorType.DIRECT_IMPORT_TO_LOCAL_FILE,
930
+ fromFsPath: from.fsPath,
931
+ importPath,
932
+ suggestedRemapping: formatRemapping({
933
+ context,
934
+ prefix,
935
+ target,
936
+ }),
937
+ };
938
+ }
941
939
 
942
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
940
+ baseDir = path.dirname(baseDir);
941
+ }
943
942
 
944
- return resolvedFile;
943
+ return undefined;
945
944
  }
946
945
 
947
- /**
948
- * This method implements the import resolution technique number 4: A file
949
- * from an npm package is importing another file from the same package with a
950
- * direct import.
951
- *
952
- * For example, a file `node_modules/foo/File.sol` imports
953
- * `node_modules/foo/bar/File2.sol` with the direct import `bar/File2.sol`.
954
- *
955
- * @param from The file from which the import is being resolved.
956
- * @param importPath The import path, as written in the source code.
957
- * @param directImport The direct import path, after resolving relative paths.
958
- * The direct import must be considered local within the package, according to
959
- * the rules of the `#isDirectImportLocal` method.
960
- */
961
- async #resolveLocalImportFromNpmPackage({
962
- from,
963
- importPath,
964
- directImport,
946
+ async #buildResolvedFile({
947
+ inputSourceName,
948
+ fsPath,
949
+ npmPackage,
965
950
  }: {
966
- from: NpmPackageResolvedFile;
967
- directImport: string;
968
- importPath: string;
969
- }): Promise<NpmPackageResolvedFile> {
970
- const sourceName = from.package.rootSourceName + directImport;
971
- const existing = this.#resolvedFileBySourceName.get(sourceName);
972
- if (existing !== undefined) {
973
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
974
- The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */
975
- return existing as NpmPackageResolvedFile;
976
- }
977
-
978
- const relativeFsPath = sourceNamePathToFsPath(directImport);
979
-
980
- await this.#validateExistanceAndCasingOfImport({
981
- from,
982
- importPath,
983
- relativeFsPathToValidate: relativeFsPath,
984
- absoluteFsPathToValidateFrom: from.package.rootFsPath,
985
- });
986
-
987
- const fsPath = path.join(from.package.rootFsPath, relativeFsPath);
988
-
989
- const resolvedFile: NpmPackageResolvedFile =
990
- new NpmPackageResolvedFileImplementation({
991
- sourceName,
992
- fsPath,
993
- content: await readFileContent(fsPath),
994
- package: from.package,
995
- });
996
-
997
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
998
-
999
- return resolvedFile;
951
+ inputSourceName: string;
952
+ fsPath: string;
953
+ npmPackage: ResolvedNpmPackage;
954
+ }): Promise<ResolvedFile> {
955
+ const content = await this.#readFileContent({ absolutePath: fsPath });
956
+
957
+ return {
958
+ type:
959
+ npmPackage === this.#hhProjectPackage
960
+ ? ResolvedFileType.PROJECT_FILE
961
+ : ResolvedFileType.NPM_PACKAGE_FILE,
962
+ inputSourceName,
963
+ fsPath,
964
+ content,
965
+ package: npmPackage,
966
+ };
1000
967
  }
1001
968
 
1002
- /**
1003
- * This method implements the import resolution technique number 5: A file,
1004
- * within the project or from an npm pacakge, is importing a file from a
1005
- * different npm package.
1006
- *
1007
- * Note: This is not meant to support imports into the Hardhat project.
1008
- *
1009
- * @param from The file from which the import is being resolved.
1010
- * @param importPath The import path, as written in the source code.
1011
- * @param importedPackage The NpmPackage that is being imported.
1012
- * @param subpath The path to the file to import, within the
1013
- * package. That means, after parsing the direct import, and stripping the
1014
- * package part, before resolving package exports.
1015
- */
1016
- async #resolveImportToNpmPackage({
1017
- from,
1018
- importPath,
1019
- importedPackage,
969
+ #buildResolvedFileReference({
970
+ npmPackage: targetNpmPackage,
1020
971
  subpath,
972
+ userRemapping,
973
+ packageExportsResolvedSubpath,
1021
974
  }: {
1022
- from: ResolvedFile;
1023
- importPath: string;
1024
- importedPackage: ResolvedNpmPackage;
975
+ npmPackage: ResolvedNpmPackage;
1025
976
  subpath: string;
1026
- }): Promise<NpmPackageResolvedFile> {
1027
- const sourceName = importedPackage.rootSourceName + subpath;
1028
-
1029
- const existing = this.#resolvedFileBySourceName.get(sourceName);
1030
- if (existing !== undefined) {
1031
- /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions --
1032
- The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */
1033
- return existing as NpmPackageResolvedFile;
1034
- }
1035
-
1036
- // We use the subpath (pre-resolution) to create source names
1037
- const resolvedSubpath = resolveSubpath(importedPackage, subpath);
1038
-
1039
- await this.#validateExistanceAndCasingOfImport({
1040
- from,
1041
- importPath,
1042
- relativeFsPathToValidate: sourceNamePathToFsPath(resolvedSubpath),
1043
- absoluteFsPathToValidateFrom: importedPackage.rootFsPath,
1044
- usingPackageExports: importedPackage.exports !== undefined,
1045
- });
1046
-
1047
- const fsPath = path.join(importedPackage.rootFsPath, resolvedSubpath);
1048
-
1049
- const resolvedFile: NpmPackageResolvedFile =
1050
- new NpmPackageResolvedFileImplementation({
1051
- sourceName,
1052
- fsPath,
1053
- content: await readFileContent(fsPath),
1054
- package: importedPackage,
1055
- });
1056
-
1057
- this.#resolvedFileBySourceName.set(sourceName, resolvedFile);
1058
-
1059
- return resolvedFile;
977
+ userRemapping?: ResolvedUserRemapping;
978
+ packageExportsResolvedSubpath?: string;
979
+ }): ResolvedFileReference {
980
+ return {
981
+ resolvedFileType:
982
+ targetNpmPackage === this.#hhProjectPackage
983
+ ? ResolvedFileType.PROJECT_FILE
984
+ : ResolvedFileType.NPM_PACKAGE_FILE,
985
+ npmPackage: {
986
+ name: targetNpmPackage.name,
987
+ version: targetNpmPackage.version,
988
+ rootFsPath: targetNpmPackage.rootFsPath,
989
+ },
990
+ userRemapping:
991
+ userRemapping === undefined
992
+ ? undefined
993
+ : this.#buildUserRemappingReference({ userRemapping }),
994
+ subpath,
995
+ packageExportsResolvedSubpath,
996
+ };
1060
997
  }
1061
998
 
1062
- // >>>>>>>>>> END SECTION: Import resolution techniques
1063
-
1064
- /**
1065
- * Resolves an npm package as a dependency of another one.
1066
- *
1067
- * @param from The package to resolve the dependency from.
1068
- * @param packageName The name of the package that should be resolved as a
1069
- * dependency.
1070
- * @returns A ResolvedNpmPackage or PROJECT_ROOT_SENTINEL.
1071
- */
1072
- async #resolveNpmPackage({
1073
- from,
1074
- packageName,
999
+ #buildUserRemappingReference({
1000
+ userRemapping,
1075
1001
  }: {
1076
- from: ResolvedNpmPackage | typeof PROJECT_ROOT_SENTINEL;
1077
- packageName: string;
1078
- }): Promise<ResolvedNpmPackage | typeof PROJECT_ROOT_SENTINEL> {
1079
- let dependenciesMap = this.#dependencyMaps.get(from);
1080
- if (dependenciesMap === undefined) {
1081
- dependenciesMap = new Map();
1082
- this.#dependencyMaps.set(from, dependenciesMap);
1083
- }
1084
-
1085
- const dependency = dependenciesMap.get(packageName);
1086
- if (dependency !== undefined) {
1087
- return dependency;
1088
- }
1089
-
1090
- const baseResolutionDirectory =
1091
- from === PROJECT_ROOT_SENTINEL ? this.#projectRoot : from.rootFsPath;
1092
-
1093
- // TODO: This is a quick fix for Hardhat's own package.json, for the alpha
1094
- // release. We should find a better way to handle this.
1095
- // We also need to figure out a way to test this inside the monorepo,
1096
- // without the package `hardhat` in the top-level `node_modules` folder
1097
- // interfering with the resolution.
1098
-
1099
- const packageJsonPath =
1100
- packageName === "hardhat"
1101
- ? await findClosestPackageJson(import.meta.dirname)
1102
- : await findDependencyPackageJson(baseResolutionDirectory, packageName);
1103
-
1104
- if (packageJsonPath === undefined) {
1105
- throw new HardhatError(
1106
- HardhatError.ERRORS.SOLIDITY.NPM_DEPEDNDENCY_NOT_INSTALLED,
1107
- {
1108
- from:
1109
- from === PROJECT_ROOT_SENTINEL
1110
- ? "your project"
1111
- : `"${shortenPath(from.rootFsPath)}"`,
1112
- packageName,
1113
- },
1114
- );
1115
- }
1116
-
1117
- if (isPackageJsonFromProject(packageJsonPath, this.#projectRoot)) {
1118
- dependenciesMap.set(packageName, PROJECT_ROOT_SENTINEL);
1119
- return PROJECT_ROOT_SENTINEL;
1120
- }
1121
-
1122
- const packageJson = await readJsonFile<{
1123
- name: string;
1124
- version: string;
1125
- exports?: resolve.Exports;
1126
- }>(packageJsonPath);
1127
-
1128
- const name = packageJson.name;
1129
- const version = isPackageJsonFromMonorepo(
1130
- packageJsonPath,
1131
- this.#projectRoot,
1132
- )
1133
- ? "local"
1134
- : packageJson.version;
1135
-
1136
- const npmPackage: ResolvedNpmPackage = {
1137
- name,
1138
- version,
1139
- exports: packageJson.exports,
1140
- rootFsPath: path.dirname(packageJsonPath),
1141
- rootSourceName: npmPackageToRootSourceName(name, version),
1002
+ userRemapping: ResolvedUserRemapping;
1003
+ }): UserRemappingReference {
1004
+ return {
1005
+ originalUserRemapping: userRemapping.originalFormat,
1006
+ actualUserRemapping: formatRemapping(userRemapping),
1007
+ remappingSource: userRemapping.source,
1142
1008
  };
1143
-
1144
- dependenciesMap.set(packageName, npmPackage);
1145
- return npmPackage;
1146
1009
  }
1147
1010
 
1148
1011
  /**
1149
- * Resolves the npm package imported by the importPath in the from file.
1150
- *
1151
- * @param from The file from which the import is being resolved.
1152
- * @param importPath The import path, as written in the source code.
1153
- * @param importPackageName The name of the package to import, as present in
1154
- * the importPath, and not necessarily the name of the package in the
1155
- * package.json.
1156
- * @returns A ResolvedNpmPackage or PROJECT_ROOT_SENTINEL.
1012
+ * Returns the relative input source name from the npmPackage's input source name root.
1013
+ * @param nmpPackage The package
1014
+ * @param fileInputSourceName The file's input source name.
1157
1015
  */
1158
- async #resolveNpmPackageForImport({
1159
- from,
1160
- importPath,
1161
- importPackageName,
1016
+ #getRelativeSourceNamePath({
1017
+ npmPackage: nmpPackage,
1018
+ fileInputSourceName,
1162
1019
  }: {
1163
- from: ResolvedFile;
1164
- importPath: string;
1165
- importPackageName: string;
1166
- }): Promise<ResolvedNpmPackage | typeof PROJECT_ROOT_SENTINEL> {
1167
- try {
1168
- return await this.#resolveNpmPackage({
1169
- from:
1170
- from.type === ResolvedFileType.PROJECT_FILE
1171
- ? PROJECT_ROOT_SENTINEL
1172
- : from.package,
1173
- packageName: importPackageName,
1174
- });
1175
- } catch (error) {
1176
- ensureError(error);
1020
+ npmPackage: ResolvedNpmPackage;
1021
+ fileInputSourceName: string;
1022
+ }) {
1023
+ return fileInputSourceName.substring(
1024
+ nmpPackage.inputSourceNameRoot.length + 1,
1025
+ );
1026
+ }
1177
1027
 
1178
- if (
1179
- HardhatError.isHardhatError(
1180
- error,
1181
- HardhatError.ERRORS.SOLIDITY.NPM_DEPEDNDENCY_NOT_INSTALLED,
1182
- )
1183
- ) {
1184
- throw new HardhatError(
1185
- HardhatError.ERRORS.SOLIDITY.IMPORTED_NPM_DEPENDENCY_NOT_INSTALLED,
1186
- {
1187
- from: shortenPath(from.fsPath),
1188
- importPath,
1189
- },
1190
- error,
1028
+ #importResolutionErrorToNpmRootResolutionError(
1029
+ npmModule: string,
1030
+ error: ImportResolutionError,
1031
+ ): NpmRootResolutionError {
1032
+ switch (error.type) {
1033
+ /* c8 ignore start */
1034
+ case ImportResolutionErrorType.ILLEGAL_RELATIVE_IMPORT: {
1035
+ assertHardhatInvariant(
1036
+ false,
1037
+ "This could not happen, as we validated that the module name is a valid npm module",
1191
1038
  );
1192
1039
  }
1193
-
1194
- throw error;
1195
- }
1196
- }
1197
-
1198
- /**
1199
- * This method returns true if a direct import should be considered an import
1200
- * to a local file when evaluated in the context of the Hardhat project.
1201
- */
1202
- async #isDirectImportLocal(
1203
- projectOrPackageRootFsPath: string,
1204
- directImport: string,
1205
- ): Promise<boolean> {
1206
- if (directImport === "hardhat/console.sol") {
1207
- return false;
1208
- }
1209
-
1210
- const slash = directImport.indexOf("/");
1211
-
1212
- // If it's a file in the root directory
1213
- if (slash === -1) {
1214
- return true;
1215
- }
1216
-
1217
- const firstDirectory = directImport.substring(0, slash);
1218
-
1219
- // TODO: Cache this?
1220
- return exists(path.join(projectOrPackageRootFsPath, firstDirectory));
1221
- }
1222
-
1223
- /**
1224
- * Returns the prefix used to desambiguate a directImport by
1225
- * #isDirectImportLocal to determine if its local.
1226
- *
1227
- * For example, the prefix for `foo/bar/File.sol`, this returns `foo/`.
1228
- *
1229
- * NOTE: This method does not support `hardhat/console.sol`, as that's a
1230
- * special case, which is never considered local.
1231
- */
1232
- #getDirectImportLocalDesambiguationPrefix(directImport: string): string {
1233
- const slash = directImport.indexOf("/");
1234
-
1235
- // If it's a file in the root directory
1236
- if (slash === -1) {
1237
- return directImport;
1238
- }
1239
-
1240
- const firstDirectory = directImport.substring(0, slash + 1);
1241
-
1242
- return firstDirectory;
1243
- }
1244
-
1245
- /**
1246
- * This is an utility method that validates the existance and casing of an
1247
- * imported file as part of the different resolution techniques.
1248
- *
1249
- * `from` and `importPath` are used to provide a user-friendly error message,
1250
- * but the actual validation is done using `relativePathToValidate` and
1251
- * `absolutePathToValidateFrom`.
1252
- *
1253
- * @param from The file with the import.
1254
- * @param importPath The import path, as written in the source code.
1255
- * @param relativePathToValidate The relative path to validate its existance.
1256
- * @param absolutePathToValidateFrom The absolute path from in which the
1257
- * relative path is.
1258
- * @param usingPackageExports Whether the import is using package exports,
1259
- * which controls which kind of error is thrown.
1260
- */
1261
- async #validateExistanceAndCasingOfImport({
1262
- from,
1263
- importPath,
1264
- relativeFsPathToValidate,
1265
- absoluteFsPathToValidateFrom,
1266
- usingPackageExports,
1267
- }: {
1268
- from: ResolvedFile;
1269
- importPath: string;
1270
- relativeFsPathToValidate: string;
1271
- absoluteFsPathToValidateFrom: string;
1272
- usingPackageExports?: boolean;
1273
- }) {
1274
- let trueCaseFsPath: string;
1275
- try {
1276
- trueCaseFsPath = await getFileTrueCase(
1277
- absoluteFsPathToValidateFrom,
1278
- relativeFsPathToValidate,
1279
- );
1280
- } catch (error) {
1281
- ensureError(error, FileNotFoundError);
1282
-
1283
- throw new HardhatError(
1284
- HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST,
1285
- { importPath, from: shortenPath(from.fsPath) },
1286
- error,
1287
- );
1288
- }
1289
-
1290
- if (relativeFsPathToValidate !== trueCaseFsPath) {
1291
- // If we are using package exports, we need to throw a special error,
1292
- // as we can't compute the correct casing.
1293
- if (usingPackageExports === true) {
1294
- throw new HardhatError(
1295
- HardhatError.ERRORS.SOLIDITY.IMPORTED_PACKAGE_EXPORTS_FILE_WITH_INCORRECT_CASING,
1296
- {
1297
- importPath,
1298
- from: shortenPath(from.fsPath),
1299
- },
1040
+ case ImportResolutionErrorType.RELATIVE_IMPORT_CLASHES_WITH_USER_REMAPPING: {
1041
+ assertHardhatInvariant(
1042
+ false,
1043
+ "This should never happen: An npm root file must not be a relative import",
1300
1044
  );
1301
1045
  }
1302
-
1303
- throw new HardhatError(
1304
- HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_WITH_INCORRECT_CASING,
1305
- {
1306
- importPath,
1307
- from: shortenPath(from.fsPath),
1308
- correctCasing: fsPathToSourceNamePath(trueCaseFsPath),
1309
- },
1310
- );
1311
- }
1312
- }
1313
-
1314
- /**
1315
- * Parses a direct import as if it were an npm import, returning `undefined`
1316
- * if the format is invalid.
1317
- *
1318
- * Note: The returned subpath is not an fs path, and always use path.posix.sep
1319
- */
1320
- #parseNpmDirectImport(directImport: string):
1321
- | {
1322
- package: string;
1323
- subpath: string;
1046
+ /* c8 ignore end */
1047
+ case ImportResolutionErrorType.IMPORT_WITH_INVALID_NPM_SYNTAX:
1048
+ case ImportResolutionErrorType.IMPORT_WITH_WINDOWS_PATH_SEPARATORS:
1049
+ case ImportResolutionErrorType.RELATIVE_IMPORT_INTO_NODE_MODULES: {
1050
+ return {
1051
+ type: RootResolutionErrorType.NPM_ROOT_FILE_NAME_WITH_INVALID_FORMAT,
1052
+ npmModule,
1053
+ };
1324
1054
  }
1325
- | undefined {
1326
- // NOTE: We assume usage of path.posix.sep in the direct import
1327
- const directImportPattern =
1328
- /^(?<package>(?:@[a-z0-9-~._]+\/)?[a-z0-9-~][a-z0-9-~._]*)\/(?<path>.*)$/;
1329
-
1330
- const match = directImportPattern.exec(directImport);
1331
-
1332
- if (match === null) {
1333
- return undefined;
1334
- }
1335
-
1336
- assertHardhatInvariant(
1337
- match.groups !== undefined,
1338
- "Groups should be defined because they are part of the pattern",
1339
- );
1340
-
1341
- return { package: match.groups.package, subpath: match.groups.path };
1342
- }
1343
- }
1344
-
1345
- async function validateAndResolveUserRemapping(
1346
- projectRoot: string,
1347
- remappingString: string,
1348
- ): Promise<ResolvedUserRemapping> {
1349
- const remapping = parseRemappingString(remappingString);
1350
-
1351
- if (remapping === undefined) {
1352
- throw new HardhatError(
1353
- HardhatError.ERRORS.SOLIDITY.REMAPPING_WITH_INVALID_SYNTAX,
1354
- {
1355
- remapping: remappingString,
1356
- },
1357
- );
1358
- }
1359
-
1360
- if (remapping.context.startsWith("npm/")) {
1361
- throw new HardhatError(
1362
- HardhatError.ERRORS.SOLIDITY.USER_REMAPPING_WITH_NPM_CONTEXT,
1363
- { remapping: remappingString },
1364
- );
1365
- }
1366
-
1367
- if (!remapping.target.startsWith("npm/")) {
1368
- return { ...remapping, rawFormat: remappingString };
1369
- }
1370
-
1371
- const parsed = parseNpmRemappingTarget(remapping.target);
1372
-
1373
- if (parsed === undefined) {
1374
- throw new HardhatError(
1375
- HardhatError.ERRORS.SOLIDITY.REMAPPING_WITH_INVALID_SYNTAX,
1376
- { remapping: remappingString },
1377
- );
1378
- }
1379
-
1380
- const { packageName, packageVersion } = parsed;
1381
-
1382
- const dependencyPackageJsonPath = await findDependencyPackageJson(
1383
- projectRoot,
1384
- packageName,
1385
- );
1386
-
1387
- if (dependencyPackageJsonPath === undefined) {
1388
- throw new HardhatError(
1389
- HardhatError.ERRORS.SOLIDITY.REMAPPING_TO_UNINSTALLED_PACKAGE,
1390
- { remapping: remappingString, package: packageName },
1391
- );
1392
- }
1393
-
1394
- if (isPackageJsonFromMonorepo(dependencyPackageJsonPath, projectRoot)) {
1395
- if (packageVersion !== "local") {
1396
- throw new HardhatError(
1397
- HardhatError.ERRORS.SOLIDITY.REMAPPING_NPM_PACKAGE_AS_MONOREPO,
1398
- {
1399
- remapping: remappingString,
1400
- pacakge: packageName,
1401
- version: packageVersion,
1402
- },
1403
- );
1404
- }
1405
- }
1055
+ case ImportResolutionErrorType.IMPORT_DOESNT_EXIST: {
1056
+ assertHardhatInvariant(
1057
+ error.npmPackage !== undefined,
1058
+ "We should have a npm package if the import doesn't exist, as we know are doing an npm import",
1059
+ );
1406
1060
 
1407
- if (isPackageJsonFromProject(dependencyPackageJsonPath, projectRoot)) {
1408
- throw new HardhatError(
1409
- HardhatError.ERRORS.SOLIDITY.REMAPPING_HARDHAT_PROJECT_AS_MONOREPO_PACKAGE,
1410
- { remapping: remappingString, package: packageName },
1411
- );
1412
- }
1061
+ return {
1062
+ type: RootResolutionErrorType.NPM_ROOT_FILE_DOESNT_EXIST_WITHIN_ITS_PACKAGE,
1063
+ npmModule,
1064
+ userRemapping: error.userRemapping,
1065
+ npmPackage: error.npmPackage,
1066
+ resolvedFileType: error.resolvedFileType,
1067
+ subpath: error.subpath,
1068
+ packageExportsResolvedSubpath: error.packageExportsResolvedSubpath,
1069
+ };
1070
+ }
1071
+ case ImportResolutionErrorType.IMPORT_INVALID_CASING: {
1072
+ assertHardhatInvariant(
1073
+ error.npmPackage !== undefined,
1074
+ "We should have a npm package if the import doesn't exist, as we know are doing an npm import",
1075
+ );
1413
1076
 
1414
- const npmPackage: ResolvedNpmPackage = {
1415
- name: packageName,
1416
- version: packageVersion,
1417
- rootFsPath: path.dirname(dependencyPackageJsonPath),
1418
- rootSourceName: npmPackageToRootSourceName(packageName, packageVersion),
1419
- };
1420
-
1421
- if (isPackageJsonFromNpmPackage(dependencyPackageJsonPath)) {
1422
- const dependencyPackageJson = await readJsonFile<{
1423
- version: string;
1424
- exports: resolve.Exports;
1425
- }>(dependencyPackageJsonPath);
1426
-
1427
- if (dependencyPackageJson.version !== packageVersion) {
1428
- throw new HardhatError(
1429
- HardhatError.ERRORS.SOLIDITY.REMAPPING_INCORRECT_VERSION,
1430
- {
1431
- remapping: remappingString,
1432
- package: packageName,
1433
- expectedVersion: packageVersion,
1434
- actualVersion: dependencyPackageJson.version,
1435
- },
1436
- );
1077
+ return {
1078
+ type: RootResolutionErrorType.NPM_ROOT_FILE_WITH_INCORRRECT_CASING,
1079
+ npmModule,
1080
+ correctCasing: error.correctCasing,
1081
+ userRemapping: error.userRemapping,
1082
+ npmPackage: error.npmPackage,
1083
+ resolvedFileType: error.resolvedFileType,
1084
+ subpath: error.subpath,
1085
+ packageExportsResolvedSubpath: error.packageExportsResolvedSubpath,
1086
+ };
1087
+ }
1088
+ case ImportResolutionErrorType.IMPORT_OF_UNINSTALLED_PACKAGE: {
1089
+ return {
1090
+ type: RootResolutionErrorType.NPM_ROOT_FILE_OF_UNINSTALLED_PACKAGE,
1091
+ npmModule,
1092
+ installationName: error.installationName,
1093
+ };
1094
+ }
1095
+ case ImportResolutionErrorType.IMPORT_WITH_REMAPPING_ERRORS: {
1096
+ return {
1097
+ type: RootResolutionErrorType.NPM_ROOT_FILE_RESOLUTION_WITH_REMAPPING_ERRORS,
1098
+ npmModule,
1099
+ remappingErrors: error.remappingErrors,
1100
+ };
1101
+ }
1102
+ case ImportResolutionErrorType.IMPORT_OF_NON_EXPORTED_NPM_FILE: {
1103
+ return {
1104
+ type: RootResolutionErrorType.NPM_ROOT_FILE_NON_EXPORTED_FILE,
1105
+ npmModule,
1106
+ userRemapping: error.userRemapping,
1107
+ npmPackage: error.npmPackage,
1108
+ resolvedFileType: error.resolvedFileType,
1109
+ subpath: error.subpath,
1110
+ packageExportsResolvedSubpath: error.packageExportsResolvedSubpath,
1111
+ };
1112
+ }
1113
+ case ImportResolutionErrorType.DIRECT_IMPORT_TO_LOCAL_FILE: {
1114
+ return {
1115
+ type: RootResolutionErrorType.NPM_ROOT_FILE_RESOLVES_TO_PROJECT_FILE,
1116
+ npmModule,
1117
+ userRemapping: undefined,
1118
+ resolvedFileFsPath: path.join(
1119
+ this.#hhProjectPackage.rootFsPath,
1120
+ npmModule,
1121
+ ),
1122
+ };
1123
+ }
1437
1124
  }
1438
-
1439
- npmPackage.exports = dependencyPackageJson.exports;
1440
1125
  }
1441
1126
 
1442
- return {
1443
- ...remapping,
1444
- targetNpmPackage: npmPackage,
1445
- rawFormat: remappingString,
1446
- };
1447
- }
1448
-
1449
- function parseNpmRemappingTarget(remappingTarget: string):
1450
- | {
1451
- packageName: string;
1452
- packageVersion: string;
1453
- }
1454
- | undefined {
1455
- const npmTargetPattern =
1456
- /^npm\/(?<package>(?:@[a-z0-9-~._]+\/)?[a-z0-9-~][a-z0-9-~._]*)@(?<version>local|\d+\.\d+\.\d+)\//;
1457
-
1458
- const match = npmTargetPattern.exec(remappingTarget);
1459
-
1460
- if (match === null) {
1461
- return undefined;
1462
- }
1463
-
1464
- assertHardhatInvariant(
1465
- match.groups !== undefined,
1466
- "Groups should be defined because they are part of the pattern",
1467
- );
1468
-
1469
- return {
1470
- packageName: match.groups.package,
1471
- packageVersion: match.groups.version,
1472
- };
1473
- }
1474
-
1475
- function npmPackageToRootSourceName(name: string, version: string): string {
1476
- return `npm/${name}@${version}/`;
1477
- }
1478
-
1479
- function isPackageJsonFromMonorepo(
1480
- packageJsonFsPath: string,
1481
- projectRoot: string,
1482
- ): boolean {
1483
- return (
1484
- !packageJsonFsPath.includes("node_modules") &&
1485
- !packageJsonFsPath.startsWith(projectRoot)
1486
- );
1487
- }
1488
-
1489
- function isPackageJsonFromProject(
1490
- packageJsonFsPath: string,
1491
- projectRoot: string,
1492
- ): boolean {
1493
- return (
1494
- !packageJsonFsPath.includes("node_modules") &&
1495
- packageJsonFsPath.startsWith(projectRoot)
1496
- );
1497
- }
1498
-
1499
- function isPackageJsonFromNpmPackage(packageJsonFsPath: string): boolean {
1500
- return packageJsonFsPath.includes("node_modules");
1501
- }
1502
-
1503
- /**
1504
- * Transforms an fs path into a sourceName or import path, by normalizing their
1505
- * path separators to /.
1506
- *
1507
- * Note that source
1508
- *
1509
- * Note: This function is exported for testing purposes, but it's not meant to
1510
- * be used outside of the resolver.
1511
- */
1512
- export function fsPathToSourceNamePath(fsPath: string): string {
1513
- if (path.sep === "/") {
1514
- return fsPath;
1515
- }
1516
-
1517
- return fsPath.replace(/\\/g, "/");
1518
- }
1519
-
1520
- /**
1521
- * Transforms a sourceName or import path into an fs path, by normalizing their
1522
- * path separators to /.
1523
- *
1524
- * Note: This function is exported for testing purposes, but it's not meant to
1525
- * be used outside of the resolver.
1526
- */
1527
- export function sourceNamePathToFsPath(sourceNamePath: string): string {
1528
- if (path.sep === "/") {
1529
- return sourceNamePath;
1530
- }
1531
-
1532
- return sourceNamePath.replace(/\//g, "\\");
1533
- }
1534
-
1535
- /**
1536
- * The equivalent of path.join but for sourceName or import paths, not fs paths.
1537
- */
1538
- function sourceNamePathJoin(...parts: string[]): string {
1539
- return fsPathToSourceNamePath(path.join(...parts));
1540
- }
1541
-
1542
- /**
1543
- * Reads and analyzes the file at the given absolute path.
1544
- */
1545
- async function readFileContent(absolutePath: string): Promise<FileContent> {
1546
- const text = await readUtf8File(absolutePath);
1547
- const { imports, versionPragmas } = analyze(text);
1548
-
1549
- return {
1550
- text,
1551
- importPaths: imports,
1552
- versionPragmas,
1553
- };
1554
- }
1555
-
1556
- /**
1557
- * Resolves a subpath for a given package, when it uses package#exports
1558
- * @param npmPackage
1559
- * @param subpath
1560
- * @returns
1561
- */
1562
- function resolveSubpath(
1563
- npmPackage: ResolvedNpmPackage,
1564
- subpath: string,
1565
- ): string {
1566
- if (npmPackage.exports === undefined) {
1567
- return subpath;
1568
- }
1569
- try {
1570
- // As we are resolving Solidity files, the conditions don't really apply,
1571
- // and Solidity package authors don't use them either.
1572
- //
1573
- // We use `resolve.exports` with the appropiate options so that it only
1574
- // takes the `"default"` condition into account.
1575
- const resolveOutput = resolve.exports(npmPackage, subpath, {
1576
- browser: false,
1577
- conditions: [],
1578
- require: false,
1579
- unsafe: true,
1580
- });
1581
-
1582
- assertHardhatInvariant(
1583
- resolveOutput !== undefined,
1584
- "resolve.exports should always return a result when package.exports exist",
1585
- );
1586
-
1587
- const resolvedSubpath = resolveOutput[0].slice(2); // skip the leading './'
1588
-
1589
- return resolvedSubpath.replace(/\/|\\/g, path.sep); // use fs path separator
1590
- } catch (error) {
1591
- ensureError(error, Error);
1592
-
1593
- throw new HardhatError(
1594
- HardhatError.ERRORS.SOLIDITY.RESOLVE_NOT_EXPORTED_NPM_FILE,
1595
- { module: `${npmPackage.name}/${subpath}` },
1596
- error,
1597
- );
1127
+ /**
1128
+ * Reads and analyzes the file at the given absolute path.
1129
+ */
1130
+ async #readFileContent({
1131
+ absolutePath,
1132
+ }: {
1133
+ absolutePath: string;
1134
+ }): Promise<FileContent> {
1135
+ const text = await this.#readUtf8File(absolutePath);
1136
+ const { imports, versionPragmas } = analyze(text);
1137
+
1138
+ return {
1139
+ text,
1140
+ importPaths: imports,
1141
+ versionPragmas,
1142
+ };
1598
1143
  }
1599
1144
  }