hardhat 3.1.10 → 3.1.11

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 (186) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts +2 -2
  3. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts.map +1 -1
  4. package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.js.map +1 -1
  5. package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.d.ts.map +1 -1
  6. package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.js.map +1 -1
  7. package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts +3 -5
  8. package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts.map +1 -1
  9. package/dist/src/internal/builtin-plugins/coverage/helpers.js +7 -19
  10. package/dist/src/internal/builtin-plugins/coverage/helpers.js.map +1 -1
  11. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.d.ts +7 -0
  12. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.d.ts.map +1 -0
  13. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.js +42 -0
  14. package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.js.map +1 -0
  15. package/dist/src/internal/builtin-plugins/coverage/index.d.ts.map +1 -1
  16. package/dist/src/internal/builtin-plugins/coverage/index.js +1 -0
  17. package/dist/src/internal/builtin-plugins/coverage/index.js.map +1 -1
  18. package/dist/src/internal/builtin-plugins/gas-analytics/helpers.d.ts +3 -5
  19. package/dist/src/internal/builtin-plugins/gas-analytics/helpers.d.ts.map +1 -1
  20. package/dist/src/internal/builtin-plugins/gas-analytics/helpers.js +7 -19
  21. package/dist/src/internal/builtin-plugins/gas-analytics/helpers.js.map +1 -1
  22. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.d.ts +7 -0
  23. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.d.ts.map +1 -0
  24. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.js +42 -0
  25. package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.js.map +1 -0
  26. package/dist/src/internal/builtin-plugins/gas-analytics/index.d.ts.map +1 -1
  27. package/dist/src/internal/builtin-plugins/gas-analytics/index.js +1 -0
  28. package/dist/src/internal/builtin-plugins/gas-analytics/index.js.map +1 -1
  29. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
  30. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +17 -20
  31. package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
  32. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.d.ts +1 -1
  33. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.d.ts.map +1 -1
  34. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.js +2 -2
  35. package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.js.map +1 -1
  36. package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.d.ts +0 -2
  37. package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.d.ts.map +1 -1
  38. package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.js +0 -6
  39. package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.js.map +1 -1
  40. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts +1 -3
  41. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts.map +1 -1
  42. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +0 -49
  43. package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
  44. package/dist/src/internal/builtin-plugins/solidity/build-results.d.ts +2 -2
  45. package/dist/src/internal/builtin-plugins/solidity/build-results.d.ts.map +1 -1
  46. package/dist/src/internal/builtin-plugins/solidity/build-results.js +2 -2
  47. package/dist/src/internal/builtin-plugins/solidity/build-results.js.map +1 -1
  48. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts +1 -0
  49. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
  50. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +13 -5
  51. package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
  52. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js +1 -1
  53. package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js.map +1 -1
  54. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.d.ts +1 -1
  55. package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.js +1 -1
  56. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts +2 -1
  57. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts.map +1 -1
  58. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts +13 -1
  59. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts.map +1 -1
  60. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js +30 -5
  61. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js.map +1 -1
  62. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.d.ts +3 -12
  63. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.d.ts.map +1 -1
  64. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.js.map +1 -1
  65. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts +1 -1
  66. package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts.map +1 -1
  67. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.d.ts +8 -6
  68. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.d.ts.map +1 -1
  69. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.js +103 -27
  70. package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.js.map +1 -1
  71. package/dist/src/internal/builtin-plugins/solidity/config.js +2 -2
  72. package/dist/src/internal/builtin-plugins/solidity/config.js.map +1 -1
  73. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.d.ts.map +1 -1
  74. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js +5 -0
  75. package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js.map +1 -1
  76. package/dist/src/internal/builtin-plugins/solidity/tasks/build.js +1 -1
  77. package/dist/src/internal/builtin-plugins/solidity/tasks/build.js.map +1 -1
  78. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.d.ts +1 -1
  79. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.d.ts.map +1 -1
  80. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.js +1 -1
  81. package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.js.map +1 -1
  82. package/dist/src/internal/builtin-plugins/solidity-test/runner.d.ts +1 -1
  83. package/dist/src/internal/builtin-plugins/solidity-test/runner.js +1 -1
  84. package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
  85. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +16 -27
  86. package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
  87. package/dist/src/internal/builtin-plugins/telemetry/task-action.d.ts.map +1 -1
  88. package/dist/src/internal/builtin-plugins/telemetry/task-action.js +3 -2
  89. package/dist/src/internal/builtin-plugins/telemetry/task-action.js.map +1 -1
  90. package/dist/src/internal/builtin-plugins/test/task-action.d.ts.map +1 -1
  91. package/dist/src/internal/builtin-plugins/test/task-action.js +40 -13
  92. package/dist/src/internal/builtin-plugins/test/task-action.js.map +1 -1
  93. package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts +27 -0
  94. package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts.map +1 -1
  95. package/dist/src/internal/cli/banner-manager.d.ts +26 -0
  96. package/dist/src/internal/cli/banner-manager.d.ts.map +1 -0
  97. package/dist/src/internal/cli/banner-manager.js +146 -0
  98. package/dist/src/internal/cli/banner-manager.js.map +1 -0
  99. package/dist/src/internal/cli/init/init.d.ts.map +1 -1
  100. package/dist/src/internal/cli/init/init.js +8 -0
  101. package/dist/src/internal/cli/init/init.js.map +1 -1
  102. package/dist/src/internal/cli/main.d.ts.map +1 -1
  103. package/dist/src/internal/cli/main.js +18 -1
  104. package/dist/src/internal/cli/main.js.map +1 -1
  105. package/dist/src/internal/cli/telemetry/analytics/subprocess.js +2 -0
  106. package/dist/src/internal/cli/telemetry/analytics/subprocess.js.map +1 -1
  107. package/dist/src/internal/cli/telemetry/sentry/anonymize-paths.js +1 -1
  108. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.d.ts +1 -1
  109. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.d.ts.map +1 -1
  110. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.js +47 -38
  111. package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.js.map +1 -1
  112. package/dist/src/internal/core/user-interruptions.js +1 -1
  113. package/dist/src/types/artifacts.d.ts +32 -3
  114. package/dist/src/types/artifacts.d.ts.map +1 -1
  115. package/dist/src/types/network.d.ts +1 -1
  116. package/dist/src/types/solidity/build-system.d.ts +56 -10
  117. package/dist/src/types/solidity/build-system.d.ts.map +1 -1
  118. package/dist/src/types/solidity/build-system.js +26 -2
  119. package/dist/src/types/solidity/build-system.js.map +1 -1
  120. package/dist/src/types/solidity/resolved-file.d.ts +2 -2
  121. package/dist/src/types/tasks.d.ts +8 -0
  122. package/dist/src/types/tasks.d.ts.map +1 -1
  123. package/dist/src/types/tasks.js.map +1 -1
  124. package/dist/src/types/test.d.ts +11 -0
  125. package/dist/src/types/test.d.ts.map +1 -1
  126. package/dist/src/types/utils.d.ts +16 -0
  127. package/dist/src/types/utils.d.ts.map +1 -1
  128. package/dist/src/utils/result.d.ts +33 -0
  129. package/dist/src/utils/result.d.ts.map +1 -0
  130. package/dist/src/utils/result.js +43 -0
  131. package/dist/src/utils/result.js.map +1 -0
  132. package/package.json +4 -3
  133. package/src/internal/builtin-plugins/artifacts/artifact-manager.ts +4 -1
  134. package/src/internal/builtin-plugins/artifacts/hook-handlers/hre.ts +4 -1
  135. package/src/internal/builtin-plugins/coverage/helpers.ts +11 -29
  136. package/src/internal/builtin-plugins/coverage/hook-handlers/test.ts +68 -0
  137. package/src/internal/builtin-plugins/coverage/index.ts +1 -0
  138. package/src/internal/builtin-plugins/gas-analytics/helpers.ts +11 -29
  139. package/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.ts +68 -0
  140. package/src/internal/builtin-plugins/gas-analytics/index.ts +1 -0
  141. package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +21 -28
  142. package/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.ts +5 -2
  143. package/src/internal/builtin-plugins/network-manager/edr/type-validation.ts +0 -13
  144. package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +0 -64
  145. package/src/internal/builtin-plugins/solidity/build-results.ts +3 -1
  146. package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +15 -5
  147. package/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.ts +1 -1
  148. package/src/internal/builtin-plugins/solidity/build-system/dependency-graph.ts +1 -1
  149. package/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.ts +1 -1
  150. package/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.ts +36 -6
  151. package/src/internal/builtin-plugins/solidity/build-system/resolver/types.ts +3 -9
  152. package/src/internal/builtin-plugins/solidity/build-system/resolver/utils.ts +1 -1
  153. package/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.ts +125 -28
  154. package/src/internal/builtin-plugins/solidity/config.ts +2 -2
  155. package/src/internal/builtin-plugins/solidity/hook-handlers/hre.ts +8 -0
  156. package/src/internal/builtin-plugins/solidity/tasks/build.ts +1 -1
  157. package/src/internal/builtin-plugins/solidity-test/edr-artifacts.ts +2 -2
  158. package/src/internal/builtin-plugins/solidity-test/runner.ts +1 -1
  159. package/src/internal/builtin-plugins/solidity-test/task-action.ts +36 -38
  160. package/src/internal/builtin-plugins/telemetry/task-action.ts +4 -2
  161. package/src/internal/builtin-plugins/test/task-action.ts +71 -25
  162. package/src/internal/builtin-plugins/test/type-extensions.ts +42 -0
  163. package/src/internal/cli/banner-manager.ts +234 -0
  164. package/src/internal/cli/init/init.ts +8 -0
  165. package/src/internal/cli/main.ts +19 -1
  166. package/src/internal/cli/telemetry/analytics/subprocess.ts +2 -0
  167. package/src/internal/cli/telemetry/sentry/anonymize-paths.ts +1 -1
  168. package/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.ts +98 -50
  169. package/src/internal/core/user-interruptions.ts +1 -1
  170. package/src/types/artifacts.ts +40 -3
  171. package/src/types/hre.ts +1 -1
  172. package/src/types/network.ts +1 -1
  173. package/src/types/solidity/build-system.ts +75 -14
  174. package/src/types/solidity/resolved-file.ts +2 -2
  175. package/src/types/tasks.ts +10 -0
  176. package/src/types/test.ts +12 -0
  177. package/src/types/utils.ts +14 -0
  178. package/src/utils/result.ts +57 -0
  179. package/templates/hardhat-3/01-node-test-runner-viem/package.json +9 -9
  180. package/templates/hardhat-3/02-mocha-ethers/package.json +10 -10
  181. package/templates/hardhat-3/03-minimal/package.json +1 -1
  182. package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.d.ts +0 -19
  183. package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.d.ts.map +0 -1
  184. package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.js +0 -2
  185. package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.js.map +0 -1
  186. package/src/internal/builtin-plugins/network-manager/edr/types/output.ts +0 -19
@@ -1,15 +1,15 @@
1
1
  /* eslint-disable -- This file is vendored from https://github.com/getsentry/sentry-javascript/blob/9.4.0/packages/node/src/integrations/contextlines.ts */
2
2
 
3
- import { createReadStream } from 'node:fs';
4
- import { createInterface } from 'node:readline';
5
- import type { Event, IntegrationFn, StackFrame } from '@sentry/core';
6
- import { LRUMap, defineIntegration, logger, snipLine } from '@sentry/core';
7
- import { DEBUG_BUILD } from '../debug-build.js';
3
+ import { createReadStream } from "node:fs";
4
+ import { createInterface } from "node:readline";
5
+ import type { Event, IntegrationFn, StackFrame } from "@sentry/core";
6
+ import { LRUMap, defineIntegration, logger, snipLine } from "@sentry/core";
7
+ import { DEBUG_BUILD } from "../debug-build.js";
8
8
 
9
9
  const LRU_FILE_CONTENTS_CACHE = new LRUMap<string, Record<number, string>>(10);
10
10
  const LRU_FILE_CONTENTS_FS_READ_FAILED = new LRUMap<string, 1>(20);
11
11
  const DEFAULT_LINES_OF_CONTEXT = 7;
12
- const INTEGRATION_NAME = 'ContextLines';
12
+ const INTEGRATION_NAME = "ContextLines";
13
13
  // Determines the upper bound of lineno/colno that we will attempt to read. Large colno values are likely to be
14
14
  // minified code while large lineno values are likely to be bundled code.
15
15
  // Exported for testing purposes.
@@ -36,7 +36,11 @@ export function resetFileContentCache(): void {
36
36
  /**
37
37
  * Get or init map value
38
38
  */
39
- function emplace<T extends LRUMap<K, V>, K extends string, V>(map: T, key: K, contents: V): V {
39
+ function emplace<T extends LRUMap<K, V>, K extends string, V>(
40
+ map: T,
41
+ key: K,
42
+ contents: V,
43
+ ): V {
40
44
  const value = map.get(key);
41
45
 
42
46
  if (value === undefined) {
@@ -49,18 +53,18 @@ function emplace<T extends LRUMap<K, V>, K extends string, V>(map: T, key: K, co
49
53
 
50
54
  /**
51
55
  * Determines if context lines should be skipped for a file.
52
- * - .min.(mjs|cjs|js) files are and not useful since they dont point to the original source
56
+ * - .min.(mjs|cjs|js) files are and not useful since they don't point to the original source
53
57
  * - node: prefixed modules are part of the runtime and cannot be resolved to a file
54
58
  * - data: skip json, wasm and inline js https://nodejs.org/api/esm.html#data-imports
55
59
  */
56
60
  function shouldSkipContextLinesForFile(path: string): boolean {
57
61
  // Test the most common prefix and extension first. These are the ones we
58
62
  // are most likely to see in user applications and are the ones we can break out of first.
59
- if (path.startsWith('node:')) return true;
60
- if (path.endsWith('.min.js')) return true;
61
- if (path.endsWith('.min.cjs')) return true;
62
- if (path.endsWith('.min.mjs')) return true;
63
- if (path.startsWith('data:')) return true;
63
+ if (path.startsWith("node:")) return true;
64
+ if (path.endsWith(".min.js")) return true;
65
+ if (path.endsWith(".min.cjs")) return true;
66
+ if (path.endsWith(".min.mjs")) return true;
67
+ if (path.startsWith("data:")) return true;
64
68
  return false;
65
69
  }
66
70
 
@@ -68,14 +72,19 @@ function shouldSkipContextLinesForFile(path: string): boolean {
68
72
  * Determines if we should skip contextlines based off the max lineno and colno values.
69
73
  */
70
74
  function shouldSkipContextLinesForFrame(frame: StackFrame): boolean {
71
- if (frame.lineno !== undefined && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
72
- if (frame.colno !== undefined && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
75
+ if (frame.lineno !== undefined && frame.lineno > MAX_CONTEXTLINES_LINENO)
76
+ return true;
77
+ if (frame.colno !== undefined && frame.colno > MAX_CONTEXTLINES_COLNO)
78
+ return true;
73
79
  return false;
74
80
  }
75
81
  /**
76
82
  * Checks if we have all the contents that we need in the cache.
77
83
  */
78
- function rangeExistsInContentCache(file: string, range: ReadlineRange): boolean {
84
+ function rangeExistsInContentCache(
85
+ file: string,
86
+ range: ReadlineRange,
87
+ ): boolean {
79
88
  const contents = LRU_FILE_CONTENTS_CACHE.get(file);
80
89
  if (contents === undefined) return false;
81
90
 
@@ -92,7 +101,10 @@ function rangeExistsInContentCache(file: string, range: ReadlineRange): boolean
92
101
  * Creates contiguous ranges of lines to read from a file. In the case where context lines overlap,
93
102
  * the ranges are merged to create a single range.
94
103
  */
95
- function makeLineReaderRanges(lines: number[], linecontext: number): ReadlineRange[] {
104
+ function makeLineReaderRanges(
105
+ lines: number[],
106
+ linecontext: number,
107
+ ): ReadlineRange[] {
96
108
  if (!lines.length) {
97
109
  return [];
98
110
  }
@@ -100,7 +112,7 @@ function makeLineReaderRanges(lines: number[], linecontext: number): ReadlineRan
100
112
  let i = 0;
101
113
  const line = lines[0];
102
114
 
103
- if (typeof line !== 'number') {
115
+ if (typeof line !== "number") {
104
116
  return [];
105
117
  }
106
118
 
@@ -115,7 +127,7 @@ function makeLineReaderRanges(lines: number[], linecontext: number): ReadlineRan
115
127
 
116
128
  // If the next line falls into the current range, extend the current range to lineno + linecontext.
117
129
  const next = lines[i + 1];
118
- if (typeof next !== 'number') {
130
+ if (typeof next !== "number") {
119
131
  break;
120
132
  }
121
133
  if (next <= current[1]) {
@@ -134,13 +146,17 @@ function makeLineReaderRanges(lines: number[], linecontext: number): ReadlineRan
134
146
  /**
135
147
  * Extracts lines from a file and stores them in a cache.
136
148
  */
137
- function getContextLinesFromFile(path: string, ranges: ReadlineRange[], output: Record<number, string>): Promise<void> {
149
+ function getContextLinesFromFile(
150
+ path: string,
151
+ ranges: ReadlineRange[],
152
+ output: Record<number, string>,
153
+ ): Promise<void> {
138
154
  return new Promise((resolve, _reject) => {
139
155
  // It is important *not* to have any async code between createInterface and the 'line' event listener
140
156
  // as it will cause the 'line' event to
141
157
  // be emitted before the listener is attached.
142
158
  const stream = createReadStream(path);
143
- const lineReaded = createInterface({
159
+ const lineRead = createInterface({
144
160
  input: stream,
145
161
  });
146
162
 
@@ -170,18 +186,18 @@ function getContextLinesFromFile(path: string, ranges: ReadlineRange[], output:
170
186
  // Mark file path as failed to read and prevent multiple read attempts.
171
187
  LRU_FILE_CONTENTS_FS_READ_FAILED.set(path, 1);
172
188
  DEBUG_BUILD && logger.error(`Failed to read file: ${path}. Error: ${e}`);
173
- lineReaded.close();
174
- lineReaded.removeAllListeners();
189
+ lineRead.close();
190
+ lineRead.removeAllListeners();
175
191
  destroyStreamAndResolve();
176
192
  }
177
193
 
178
194
  // We need to handle the error event to prevent the process from crashing in < Node 16
179
195
  // https://github.com/nodejs/node/pull/31603
180
- stream.on('error', onStreamError);
181
- lineReaded.on('error', onStreamError);
182
- lineReaded.on('close', destroyStreamAndResolve);
196
+ stream.on("error", onStreamError);
197
+ lineRead.on("error", onStreamError);
198
+ lineRead.on("close", destroyStreamAndResolve);
183
199
 
184
- lineReaded.on('line', line => {
200
+ lineRead.on("line", (line) => {
185
201
  lineNumber++;
186
202
  if (lineNumber < rangeStart) return;
187
203
 
@@ -191,16 +207,16 @@ function getContextLinesFromFile(path: string, ranges: ReadlineRange[], output:
191
207
  if (lineNumber >= rangeEnd) {
192
208
  if (currentRangeIndex === ranges.length - 1) {
193
209
  // We need to close the file stream and remove listeners, else the reader will continue to run our listener;
194
- lineReaded.close();
195
- lineReaded.removeAllListeners();
210
+ lineRead.close();
211
+ lineRead.removeAllListeners();
196
212
  return;
197
213
  }
198
214
  currentRangeIndex++;
199
215
  const range = ranges[currentRangeIndex];
200
216
  if (range === undefined) {
201
217
  // This should never happen as it means we have a bug in the context.
202
- lineReaded.close();
203
- lineReaded.removeAllListeners();
218
+ lineRead.close();
219
+ lineRead.removeAllListeners();
204
220
  return;
205
221
  }
206
222
  rangeStart = range[0];
@@ -217,7 +233,10 @@ function getContextLinesFromFile(path: string, ranges: ReadlineRange[], output:
217
233
  * failing reads from happening.
218
234
  */
219
235
 
220
- async function addSourceContext(event: Event, contextLines: number): Promise<Event> {
236
+ async function addSourceContext(
237
+ event: Event,
238
+ contextLines: number,
239
+ ): Promise<Event> {
221
240
  // keep a lookup map of which files we've already enqueued to read,
222
241
  // so we don't enqueue the same file multiple times which would cause multiple i/o reads
223
242
  const filesToLines: Record<string, number[]> = {};
@@ -236,8 +255,8 @@ async function addSourceContext(event: Event, contextLines: number): Promise<Eve
236
255
 
237
256
  if (
238
257
  !frame ||
239
- typeof filename !== 'string' ||
240
- typeof frame.lineno !== 'number' ||
258
+ typeof filename !== "string" ||
259
+ typeof frame.lineno !== "number" ||
241
260
  shouldSkipContextLinesForFile(filename) ||
242
261
  shouldSkipContextLinesForFrame(frame)
243
262
  ) {
@@ -258,7 +277,7 @@ async function addSourceContext(event: Event, contextLines: number): Promise<Eve
258
277
 
259
278
  const readlinePromises: Promise<void>[] = [];
260
279
  for (const file of files) {
261
- // If we failed to read this before, dont try reading it again.
280
+ // If we failed to read this before, don't try reading it again.
262
281
  if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(file)) {
263
282
  continue;
264
283
  }
@@ -272,7 +291,7 @@ async function addSourceContext(event: Event, contextLines: number): Promise<Eve
272
291
  filesToLineRanges.sort((a, b) => a - b);
273
292
  // Check if the contents are already in the cache and if we can avoid reading the file again.
274
293
  const ranges = makeLineReaderRanges(filesToLineRanges, contextLines);
275
- if (ranges.every(r => rangeExistsInContentCache(file, r))) {
294
+ if (ranges.every((r) => rangeExistsInContentCache(file, r))) {
276
295
  continue;
277
296
  }
278
297
 
@@ -282,15 +301,25 @@ async function addSourceContext(event: Event, contextLines: number): Promise<Eve
282
301
 
283
302
  // The promise rejections are caught in order to prevent them from short circuiting Promise.all
284
303
  await Promise.all(readlinePromises).catch(() => {
285
- DEBUG_BUILD && logger.log('Failed to read one or more source files and resolve context lines');
304
+ DEBUG_BUILD &&
305
+ logger.log(
306
+ "Failed to read one or more source files and resolve context lines",
307
+ );
286
308
  });
287
309
 
288
310
  // Perform the same loop as above, but this time we can assume all files are in the cache
289
311
  // and attempt to add source context to frames.
290
312
  if (contextLines > 0 && event.exception?.values) {
291
313
  for (const exception of event.exception.values) {
292
- if (exception.stacktrace?.frames && exception.stacktrace.frames.length > 0) {
293
- addSourceContextToFrames(exception.stacktrace.frames, contextLines, LRU_FILE_CONTENTS_CACHE);
314
+ if (
315
+ exception.stacktrace?.frames &&
316
+ exception.stacktrace.frames.length > 0
317
+ ) {
318
+ addSourceContextToFrames(
319
+ exception.stacktrace.frames,
320
+ contextLines,
321
+ LRU_FILE_CONTENTS_CACHE,
322
+ );
294
323
  }
295
324
  }
296
325
  }
@@ -307,7 +336,11 @@ function addSourceContextToFrames(
307
336
  ): void {
308
337
  for (const frame of frames) {
309
338
  // Only add context if we have a filename and it hasn't already been added
310
- if (frame.filename && frame.context_line === undefined && typeof frame.lineno === 'number') {
339
+ if (
340
+ frame.filename &&
341
+ frame.context_line === undefined &&
342
+ typeof frame.lineno === "number"
343
+ ) {
311
344
  const contents = cache.get(frame.filename);
312
345
  if (contents === undefined) {
313
346
  continue;
@@ -340,29 +373,34 @@ export function addContextToFrame(
340
373
  // When there is no line number in the frame, attaching context is nonsensical and will even break grouping.
341
374
  // We already check for lineno before calling this, but since StackFrame lineno ism optional, we check it again.
342
375
  if (frame.lineno === undefined || contents === undefined) {
343
- DEBUG_BUILD && logger.error('Cannot resolve context for frame with no lineno or file contents');
376
+ DEBUG_BUILD &&
377
+ logger.error(
378
+ "Cannot resolve context for frame with no lineno or file contents",
379
+ );
344
380
  return;
345
381
  }
346
382
 
347
383
  frame.pre_context = [];
348
384
  for (let i = makeRangeStart(lineno, contextLines); i < lineno; i++) {
349
- // We always expect the start context as line numbers cannot be negative. If we dont find a line, then
385
+ // We always expect the start context as line numbers cannot be negative. If we don't find a line, then
350
386
  // something went wrong somewhere. Clear the context and return without adding any linecontext.
351
387
  const line = contents[i];
352
388
  if (line === undefined) {
353
389
  clearLineContext(frame);
354
- DEBUG_BUILD && logger.error(`Could not find line ${i} in file ${frame.filename}`);
390
+ DEBUG_BUILD &&
391
+ logger.error(`Could not find line ${i} in file ${frame.filename}`);
355
392
  return;
356
393
  }
357
394
 
358
395
  frame.pre_context.push(line);
359
396
  }
360
397
 
361
- // We should always have the context line. If we dont, something went wrong, so we clear the context and return
398
+ // We should always have the context line. If we don't, something went wrong, so we clear the context and return
362
399
  // without adding any linecontext.
363
400
  if (contents[lineno] === undefined) {
364
401
  clearLineContext(frame);
365
- DEBUG_BUILD && logger.error(`Could not find line ${lineno} in file ${frame.filename}`);
402
+ DEBUG_BUILD &&
403
+ logger.error(`Could not find line ${lineno} in file ${frame.filename}`);
366
404
  return;
367
405
  }
368
406
 
@@ -371,7 +409,7 @@ export function addContextToFrame(
371
409
  const end = makeRangeEnd(lineno, contextLines);
372
410
  frame.post_context = [];
373
411
  for (let i = lineno + 1; i <= end; i++) {
374
- // Since we dont track when the file ends, we cant clear the context if we dont find a line as it could
412
+ // Since we don't track when the file ends, we cant clear the context if we don't find a line as it could
375
413
  // just be that we reached the end of the file.
376
414
  const line = contents[i];
377
415
  if (line === undefined) {
@@ -393,13 +431,21 @@ function makeRangeEnd(line: number, linecontext: number): number {
393
431
  return line + linecontext;
394
432
  }
395
433
  // Determine start and end indices for context range (inclusive);
396
- function makeContextRange(line: number, linecontext: number): [start: number, end: number] {
434
+ function makeContextRange(
435
+ line: number,
436
+ linecontext: number,
437
+ ): [start: number, end: number] {
397
438
  return [makeRangeStart(line, linecontext), makeRangeEnd(line, linecontext)];
398
439
  }
399
440
 
400
441
  /** Exported only for tests, as a type-safe variant. */
401
- export const _contextLinesIntegration: any = ((options: ContextLinesOptions = {}) => {
402
- const contextLines = options.frameContextLines !== undefined ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT;
442
+ export const _contextLinesIntegration: any = ((
443
+ options: ContextLinesOptions = {},
444
+ ) => {
445
+ const contextLines =
446
+ options.frameContextLines !== undefined
447
+ ? options.frameContextLines
448
+ : DEFAULT_LINES_OF_CONTEXT;
403
449
 
404
450
  return {
405
451
  name: INTEGRATION_NAME,
@@ -412,4 +458,6 @@ export const _contextLinesIntegration: any = ((options: ContextLinesOptions = {}
412
458
  /**
413
459
  * Capture the lines before and after the frame's context.
414
460
  */
415
- export const contextLinesIntegration: any = defineIntegration(_contextLinesIntegration);
461
+ export const contextLinesIntegration: any = defineIntegration(
462
+ _contextLinesIntegration,
463
+ );
@@ -121,7 +121,7 @@ async function defaultRequestSecretInput(
121
121
 
122
122
  assertHardhatInvariant(
123
123
  rlAsAny.output !== undefined,
124
- "Espected readline output to be defined",
124
+ "Expected readline output to be defined",
125
125
  );
126
126
 
127
127
  // We show the initial message as is
@@ -1,4 +1,5 @@
1
1
  import type { SolidityBuildInfo } from "./solidity/solidity-artifacts.js";
2
+ import type { NonNeverKeys } from "./utils.js";
2
3
 
3
4
  /**
4
5
  * A map of bare contract names and fully qualified contract names to their
@@ -17,6 +18,37 @@ export type GetArtifactByName<ContractNameT extends string> =
17
18
  ? ArtifactMap[ContractNameT]
18
19
  : Artifact;
19
20
 
21
+ /**
22
+ * A type that represents the contract names (bare and fully qualified) of all
23
+ * the artifacts that have been built in a project. This enables the
24
+ * autocomplete of the TS Language Server to list the actual contracts, without
25
+ * leading to a compilation error for general strings, so it doesn't fail
26
+ * before `hardhat build` is run.
27
+ *
28
+ * This is meant to be used in functions like this:
29
+ * @example
30
+ * ```
31
+ * function doSomething<ContractNameT extends ArtifactContractNames>(
32
+ * contractName: ContractNameT,
33
+ * ...
34
+ * ): DoSomethingReturnType<ContractNameT> {
35
+ * }
36
+ */
37
+ export type ArtifactContractNames = keyof ArtifactMap extends never
38
+ ? string
39
+ : NonNeverKeys<ArtifactMap>;
40
+
41
+ /**
42
+ * A type that represents a string that should match an artifact contract name,
43
+ * but it doesn't fail if the string is not a contract name. It's mostly used
44
+ * to offer autocompletion.
45
+ *
46
+ * @see {@link ArtifactContractNames}
47
+ */
48
+ export type StringWithArtifactContractNamesAutocompletion =
49
+ | ArtifactContractNames
50
+ | (string & {});
51
+
20
52
  /**
21
53
  * The ArtifactManager is responsible for reading and writing artifacts from
22
54
  * the Hardhat build system.
@@ -28,13 +60,18 @@ export interface ArtifactManager {
28
60
  * @param contractNameOrFullyQualifiedName The name of the contract.
29
61
  * It can be a contract bare contract name (e.g. "Token") if it's
30
62
  * unique in your project, or a fully qualified contract name
31
- * (e.g. "contract/token.sol:Token") otherwise.
63
+ * (e.g. "contract/token.sol:Token") otherwise. TypeScript's language server
64
+ * autocompletes the names of the contracts that have already been built. If
65
+ * your contract name isn't in the list, you can still use it, and/or run
66
+ * `hardhat build` to get it in the list.
32
67
  *
33
68
  * @throws Throws an error if a non-unique contract name is used,
34
69
  * indicating which fully qualified names can be used instead.
35
70
  * @throws Throws an error if the artifact doesn't exist.
36
71
  */
37
- readArtifact<ContractNameT extends string>(
72
+ readArtifact<
73
+ ContractNameT extends StringWithArtifactContractNamesAutocompletion,
74
+ >(
38
75
  contractNameOrFullyQualifiedName: ContractNameT,
39
76
  ): Promise<GetArtifactByName<ContractNameT>>;
40
77
 
@@ -239,7 +276,7 @@ export interface LinkReferences {
239
276
  * is the id of the AST node that represents the variable.
240
277
  */
241
278
  export interface ImmutableReferences {
242
- [immuatableId: string]: Array<{ start: number; length: number }>;
279
+ [immutableId: string]: Array<{ start: number; length: number }>;
243
280
  }
244
281
 
245
282
  /**
package/src/types/hre.ts CHANGED
@@ -15,7 +15,7 @@ export interface HardhatRuntimeEnvironment {
15
15
  readonly hardhat: string;
16
16
  readonly edr: string;
17
17
  };
18
- // These fields are defined using module agumentation despite being part of
18
+ // These fields are defined using module augmentation despite being part of
19
19
  // Hardhat's core:
20
20
  // readonly hooks: HookManager;
21
21
  // readonly tasks: TaskManager;
@@ -10,7 +10,7 @@ import type { EthereumProvider } from "./providers.js";
10
10
  export type ChainType = GenericChainType | "l1" | "op";
11
11
 
12
12
  /**
13
- * The most generic chanin type.
13
+ * The most generic chain type.
14
14
  */
15
15
  export type GenericChainType = "generic";
16
16
 
@@ -72,7 +72,7 @@ export type RunCompilationJobOptions = Pick<
72
72
  */
73
73
  export interface CompileBuildInfoOptions {
74
74
  /**
75
- * If `true`, this option foces the build system to recompile the build info,
75
+ * If `true`, this option forces the build system to recompile the build info,
76
76
  * even if its output is cached.
77
77
  */
78
78
  force?: boolean;
@@ -84,26 +84,70 @@ export interface CompileBuildInfoOptions {
84
84
  }
85
85
 
86
86
  export enum CompilationJobCreationErrorReason {
87
- NO_COMPATIBLE_SOLC_VERSION_FOUND = "NO_COMPATIBLE_SOLC_VERSION_FOUND",
87
+ /**
88
+ * The root file's own pragmas are incompatible with all configured compilers.
89
+ */
88
90
  NO_COMPATIBLE_SOLC_VERSION_WITH_ROOT = "NO_COMPATIBLE_SOLC_VERSION_WITH_ROOT",
89
- INCOMPATIBLE_OVERRIDDEN_SOLC_VERSION = "INCOMPATIBLE_OVERRIDDEN_SOLC_VERSION",
91
+
92
+ /**
93
+ * A dependency's own pragmas are incompatible with all configured compilers.
94
+ */
95
+ NO_COMPATIBLE_SOLC_VERSION_WITH_DEPENDENCY = "NO_COMPATIBLE_SOLC_VERSION_WITH_DEPENDENCY",
96
+
97
+ /**
98
+ * Root and a transitive import path have contradictory pragmas (invalid range / empty intersection).
99
+ */
90
100
  IMPORT_OF_INCOMPATIBLE_FILE = "IMPORT_OF_INCOMPATIBLE_FILE",
101
+
102
+ /**
103
+ * Root and a transitive import path have a valid range but no configured compiler satisfies it.
104
+ */
105
+ NO_COMPATIBLE_SOLC_VERSION_FOR_TRANSITIVE_IMPORT_PATH = "NO_COMPATIBLE_SOLC_VERSION_FOR_TRANSITIVE_IMPORT_PATH",
106
+
107
+ /**
108
+ * The override version doesn't satisfy the root file's own pragmas.
109
+ */
110
+ INCOMPATIBLE_OVERRIDDEN_SOLC_VERSION = "INCOMPATIBLE_OVERRIDDEN_SOLC_VERSION",
111
+
112
+ /**
113
+ * A dependency's pragmas are incompatible with the override version.
114
+ */
115
+ OVERRIDDEN_SOLC_VERSION_INCOMPATIBLE_WITH_DEPENDENCY = "OVERRIDDEN_SOLC_VERSION_INCOMPATIBLE_WITH_DEPENDENCY",
116
+
117
+ /**
118
+ * Generic fallback — no single compiler works for root + all dependencies.
119
+ */
120
+ NO_COMPATIBLE_SOLC_VERSION_FOUND = "NO_COMPATIBLE_SOLC_VERSION_FOUND",
91
121
  }
92
122
 
93
123
  export interface BaseCompilationJobCreationError {
124
+ success: false;
94
125
  buildProfile: string;
95
126
  rootFilePath: string;
96
127
  formattedReason: string;
97
128
  }
98
129
 
99
- export interface CompilationJobCreationErrorNoCompatibleSolcVersionFound
130
+ export interface CompilationJobCreationErrorNoCompatibleSolcVersionWithRoot
100
131
  extends BaseCompilationJobCreationError {
101
132
  reason: CompilationJobCreationErrorReason.NO_COMPATIBLE_SOLC_VERSION_WITH_ROOT;
102
133
  }
103
134
 
104
- export interface CompilationJobCreationErrorIncompatibleOverriddenSolcVersion
135
+ export interface CompilationJobCreationErrorNoCompatibleSolcVersionWithDependency
105
136
  extends BaseCompilationJobCreationError {
106
- reason: CompilationJobCreationErrorReason.INCOMPATIBLE_OVERRIDDEN_SOLC_VERSION;
137
+ reason: CompilationJobCreationErrorReason.NO_COMPATIBLE_SOLC_VERSION_WITH_DEPENDENCY;
138
+ incompatibleImportPath: string[];
139
+ }
140
+
141
+ export interface CompilationJobCreationErrorImportOfIncompatibleFile
142
+ extends BaseCompilationJobCreationError {
143
+ reason: CompilationJobCreationErrorReason.IMPORT_OF_INCOMPATIBLE_FILE;
144
+ incompatibleImportPath: string[];
145
+ }
146
+
147
+ export interface CompilationJobCreationErrorNoCompatibleSolcVersionForTransitiveImportPath
148
+ extends BaseCompilationJobCreationError {
149
+ reason: CompilationJobCreationErrorReason.NO_COMPATIBLE_SOLC_VERSION_FOR_TRANSITIVE_IMPORT_PATH;
150
+ incompatibleImportPath: string[];
107
151
  }
108
152
 
109
153
  export interface CompilationJobCreationErrorIncompatibleOverriddenSolcVersion
@@ -111,24 +155,25 @@ export interface CompilationJobCreationErrorIncompatibleOverriddenSolcVersion
111
155
  reason: CompilationJobCreationErrorReason.INCOMPATIBLE_OVERRIDDEN_SOLC_VERSION;
112
156
  }
113
157
 
114
- export interface CompilationJobCreationErrorIportOfIncompatibleFile
158
+ export interface CompilationJobCreationErrorOverriddenSolcVersionIncompatibleWithDependency
115
159
  extends BaseCompilationJobCreationError {
116
- reason: CompilationJobCreationErrorReason.IMPORT_OF_INCOMPATIBLE_FILE;
117
- // The path of absolute files imported, starting from the root, that take you
118
- // to the first file with an incompatible version pragma.
160
+ reason: CompilationJobCreationErrorReason.OVERRIDDEN_SOLC_VERSION_INCOMPATIBLE_WITH_DEPENDENCY;
119
161
  incompatibleImportPath: string[];
120
162
  }
121
163
 
122
- export interface NoCompatibleSolcVersionFound
164
+ export interface CompilationJobCreationErrorNoCompatibleSolcVersionFound
123
165
  extends BaseCompilationJobCreationError {
124
166
  reason: CompilationJobCreationErrorReason.NO_COMPATIBLE_SOLC_VERSION_FOUND;
125
167
  }
126
168
 
127
169
  export type CompilationJobCreationError =
128
- | CompilationJobCreationErrorNoCompatibleSolcVersionFound
129
- | CompilationJobCreationErrorIportOfIncompatibleFile
170
+ | CompilationJobCreationErrorNoCompatibleSolcVersionWithRoot
171
+ | CompilationJobCreationErrorNoCompatibleSolcVersionWithDependency
172
+ | CompilationJobCreationErrorImportOfIncompatibleFile
173
+ | CompilationJobCreationErrorNoCompatibleSolcVersionForTransitiveImportPath
130
174
  | CompilationJobCreationErrorIncompatibleOverriddenSolcVersion
131
- | NoCompatibleSolcVersionFound;
175
+ | CompilationJobCreationErrorOverriddenSolcVersionIncompatibleWithDependency
176
+ | CompilationJobCreationErrorNoCompatibleSolcVersionFound;
132
177
 
133
178
  /**
134
179
  * The restult of building a file.
@@ -174,6 +219,11 @@ export interface CacheHitInfo {
174
219
  * The keys in the maps of this interface are Root File Paths, which means either absolute paths or `npm:<package>/<file>` URIs.
175
220
  */
176
221
  export interface GetCompilationJobsResult {
222
+ /**
223
+ * A flag to distinguish between a successful and a failed result.
224
+ */
225
+ success: true;
226
+
177
227
  /**
178
228
  * Map from root file path to compilation job for files that need compilation.
179
229
  */
@@ -239,12 +289,23 @@ export interface SolidityBuildSystem {
239
289
  * @param options The options to use when building the files.
240
290
  * @returns An `Map` of the files to their build results, or an error if
241
291
  * there was a problem when trying to create the necessary compilation jobs.
292
+ * @see `isSuccessfulBuildResult` to check if the build result is successful.
242
293
  */
243
294
  build(
244
295
  rootFilePaths: string[],
245
296
  options?: BuildOptions,
246
297
  ): Promise<CompilationJobCreationError | Map<string, FileBuildResult>>;
247
298
 
299
+ /**
300
+ * Returns true if the given build result is successful.
301
+ *
302
+ * @param buildResult Result of the `build` method.
303
+ * @returns True if the build result is successful.
304
+ */
305
+ isSuccessfulBuildResult(
306
+ buildResult: CompilationJobCreationError | Map<string, FileBuildResult>,
307
+ ): buildResult is Map<string, FileBuildResult>;
308
+
248
309
  /**
249
310
  * Returns the CompilationJobs that would be used to build the provided files.
250
311
  *
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export interface ResolvedNpmPackage {
5
5
  /**
6
- * The name of the package, potentially scopde.
6
+ * The name of the package, potentially scoped.
7
7
  */
8
8
  name: string;
9
9
 
@@ -103,7 +103,7 @@ export interface NpmPackageResolvedFile {
103
103
  }
104
104
 
105
105
  /**
106
- * The resolult of resolving a file or import using a Resolver.
106
+ * The result of resolving a file or import using a Resolver.
107
107
  */
108
108
  export type ResolvedFile = ProjectResolvedFile | NpmPackageResolvedFile;
109
109
 
@@ -5,6 +5,8 @@ import type {
5
5
  PositionalArgumentDefinition,
6
6
  } from "./arguments.js";
7
7
  import type { HardhatRuntimeEnvironment } from "./hre.js";
8
+ /* eslint-disable-next-line @typescript-eslint/no-unused-vars -- used in JSDoc {@link} */
9
+ import type { Result } from "./utils.js";
8
10
 
9
11
  // We add the TaskManager to the HRE with a module augmentation to avoid
10
12
  // introducing a circular dependency that would look like this:
@@ -209,6 +211,10 @@ export interface NewTaskDefinitionBuilder<
209
211
  *
210
212
  * This method cannot be used together with {@link setInlineAction} on the same
211
213
  * task. Use one or the other.
214
+ *
215
+ * Task actions may return a {@link Result} to signal success or failure.
216
+ * If a task returns a failed `Result`, the CLI will set the process exit code
217
+ * to 1.
212
218
  */
213
219
  setAction(
214
220
  action: LazyActionObject<NewTaskActionFunction<TaskArgumentsT>>,
@@ -225,6 +231,10 @@ export interface NewTaskDefinitionBuilder<
225
231
  *
226
232
  * This method cannot be used together with {@link setAction} on the same
227
233
  * task. Use one or the other.
234
+ *
235
+ * Task actions may return a {@link Result} to signal success or failure.
236
+ * If a task returns a failed `Result`, the CLI will set the process exit code
237
+ * to 1.
228
238
  */
229
239
  setInlineAction(
230
240
  inlineAction: NewTaskActionFunction<TaskArgumentsT>,
package/src/types/test.ts CHANGED
@@ -5,3 +5,15 @@ export interface HardhatTestUserConfig {}
5
5
  /* eslint-disable-next-line @typescript-eslint/no-empty-interface -- Empty
6
6
  interface allow plugins to extend the Test configuration for Hardhat. */
7
7
  export interface HardhatTestConfig {}
8
+
9
+ /**
10
+ * Summary of a test run, containing counts of test outcomes and optional
11
+ * failure output.
12
+ */
13
+ export interface TestSummary {
14
+ failed: number;
15
+ passed: number;
16
+ skipped: number;
17
+ todo: number;
18
+ failureOutput?: string;
19
+ }