You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

@nomicfoundation/hardhat-utils

Package Overview
Dependencies
Maintainers
2
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nomicfoundation/hardhat-utils - npm Package Compare versions

Comparing version
3.0.3
to
3.0.4
+103
dist/src/format.d.ts
export type TableRow = string[];
export interface TableDivider {
type: "divider";
}
export type TableItem = TableRow | TableDivider;
export declare const divider: TableDivider;
/**
* Formats an array of rows and dividers into a table string.
*
* @param items An array of table rows (string arrays) and dividers.
* Dividers are objects with type: "divider" and will be rendered as table dividers.
* @returns The formatted table as a string, ready to be rendered.
*
* @example
* ```ts
* formatTable([
* ["Name", "Age"],
* divider,
* ["Alice", "30"],
* ["Bob", "25"],
* divider,
* ["Average", "27.5"]
* ]);
*
* // =>
* // | Name | Age |
* // | ------- | ---- |
* // | Alice | 30 |
* // | Bob | 25 |
* // | ------- | ---- |
* // | Average | 27.5 |
* ```
*/
export declare function formatTable(items: TableItem[]): string;
export interface TableTitleV2 {
type: "title";
text: string;
}
export interface TableSectionHeaderV2 {
type: "section-header";
text: string;
}
export interface TableHeaderV2 {
type: "header";
cells: string[];
}
export interface TableRowV2 {
type: "row";
cells: string[];
}
export type TableItemV2 = TableTitleV2 | TableSectionHeaderV2 | TableHeaderV2 | TableRowV2;
/**
* Formats an array of titles, section headers, headers, and rows into a table
* string with box-drawing characters.
*
* Features:
* - Titles are centered in a standalone box with double borders (╔═╗)
* - Section headers group related content with automatic closing
* - Headers and rows can have different numbers of cells
* - Rows with fewer cells than max columns are handled with special rendering
*
* @param items An array of table items (titles, section headers, headers, and rows).
* Sections are automatically closed when a new section-header or title appears, or
* at the end of the table.
* @returns The formatted table as a string, ready to be rendered.
*
* @example
* ```ts
* formatTableV2([
* { type: "title", text: "My Table" },
* { type: "section-header", text: "User Data" },
* { type: "header", cells: ["Name", "Age", "City"] },
* { type: "row", cells: ["Alice", "30", "NYC"] },
* { type: "row", cells: ["Bob", "25", "LA"] },
* { type: "section-header", text: "Summary" },
* { type: "header", cells: ["Total", "Count"] },
* { type: "row", cells: ["55", "2"] }
* ]);
*
* // =>
* // ╔═══════════════════╗
* // ║ My Table ║
* // ╚═══════════════════╝
* // ╔═══════════════════╗
* // ║ User Data ║
* // ╟───────┬─────┬─────╢
* // ║ Name │ Age │ City║
* // ╟───────┼─────┼─────╢
* // ║ Alice │ 30 │ NYC ║
* // ╟───────┼─────┼─────╢
* // ║ Bob │ 25 │ LA ║
* // ╚═══════╧═════╧═════╝
* // ╔═══════════════════╗
* // ║ Summary ║
* // ╟───────┬───────────╢
* // ║ Total │ Count ║
* // ╟───────┼───────────╢
* // ║ 55 │ 2 ║
* // ╚═══════╧═══════════╝
* ```
*/
export declare function formatTableV2(items: TableItemV2[]): string;
//# sourceMappingURL=format.d.ts.map
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/format.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC;AAChC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;CACjB;AACD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEhD,eAAO,MAAM,OAAO,EAAE,YAAkC,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,CA8CtD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,MAAM,WAAW,GACnB,YAAY,GACZ,oBAAoB,GACpB,aAAa,GACb,UAAU,CAAC;AAEf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAgG1D"}
import { getColumnWidths, getContentWidth, getHeadingWidth, getStringWidth, renderContentLine, renderHeaderOpen, renderRowSeparator, renderSectionClose, } from "./internal/format.js";
export const divider = { type: "divider" };
/**
* Formats an array of rows and dividers into a table string.
*
* @param items An array of table rows (string arrays) and dividers.
* Dividers are objects with type: "divider" and will be rendered as table dividers.
* @returns The formatted table as a string, ready to be rendered.
*
* @example
* ```ts
* formatTable([
* ["Name", "Age"],
* divider,
* ["Alice", "30"],
* ["Bob", "25"],
* divider,
* ["Average", "27.5"]
* ]);
*
* // =>
* // | Name | Age |
* // | ------- | ---- |
* // | Alice | 30 |
* // | Bob | 25 |
* // | ------- | ---- |
* // | Average | 27.5 |
* ```
*/
export function formatTable(items) {
const widths = [];
const dataRows = [];
for (const item of items) {
if (Array.isArray(item)) {
dataRows.push([...item]);
}
}
// Calculate maximum width for each column
for (const row of dataRows) {
for (let i = 0; i < row.length; i++) {
while (i >= widths.length) {
widths.push(0);
}
widths[i] = Math.max(widths[i], getStringWidth(row[i]));
}
}
const dividerRow = widths.map((width) => "-".repeat(width));
const outputRows = [];
for (const item of items) {
if (Array.isArray(item)) {
const row = [...item];
// Pad the row to match the number of columns
while (row.length < widths.length) {
row.push("");
}
outputRows.push(row);
}
else {
outputRows.push([...dividerRow]);
}
}
outputRows.forEach((row) => {
for (let i = 0; i < row.length; i++) {
const displayWidth = getStringWidth(row[i]);
const actualLength = row[i].length;
// Adjust padding to account for difference between display width and actual length
row[i] = row[i].padEnd(widths[i] + actualLength - displayWidth);
}
});
return outputRows.map((row) => `| ${row.join(" | ")} |`).join("\n");
}
/**
* Formats an array of titles, section headers, headers, and rows into a table
* string with box-drawing characters.
*
* Features:
* - Titles are centered in a standalone box with double borders (╔═╗)
* - Section headers group related content with automatic closing
* - Headers and rows can have different numbers of cells
* - Rows with fewer cells than max columns are handled with special rendering
*
* @param items An array of table items (titles, section headers, headers, and rows).
* Sections are automatically closed when a new section-header or title appears, or
* at the end of the table.
* @returns The formatted table as a string, ready to be rendered.
*
* @example
* ```ts
* formatTableV2([
* { type: "title", text: "My Table" },
* { type: "section-header", text: "User Data" },
* { type: "header", cells: ["Name", "Age", "City"] },
* { type: "row", cells: ["Alice", "30", "NYC"] },
* { type: "row", cells: ["Bob", "25", "LA"] },
* { type: "section-header", text: "Summary" },
* { type: "header", cells: ["Total", "Count"] },
* { type: "row", cells: ["55", "2"] }
* ]);
*
* // =>
* // ╔═══════════════════╗
* // ║ My Table ║
* // ╚═══════════════════╝
* // ╔═══════════════════╗
* // ║ User Data ║
* // ╟───────┬─────┬─────╢
* // ║ Name │ Age │ City║
* // ╟───────┼─────┼─────╢
* // ║ Alice │ 30 │ NYC ║
* // ╟───────┼─────┼─────╢
* // ║ Bob │ 25 │ LA ║
* // ╚═══════╧═════╧═════╝
* // ╔═══════════════════╗
* // ║ Summary ║
* // ╟───────┬───────────╢
* // ║ Total │ Count ║
* // ╟───────┼───────────╢
* // ║ 55 │ 2 ║
* // ╚═══════╧═══════════╝
* ```
*/
export function formatTableV2(items) {
if (items.length === 0) {
return "";
}
const columnWidths = getColumnWidths(items);
const contentWidth = getContentWidth(columnWidths);
const headingWidth = getHeadingWidth(items);
// If heading is wider than content, expand last column to fit
if (headingWidth > contentWidth && columnWidths.length > 0) {
const extraSpace = headingWidth - contentWidth;
columnWidths[columnWidths.length - 1] += extraSpace;
}
const tableWidth = Math.max(contentWidth, headingWidth);
const lines = [];
let previousCellCount = 0; // Keep track of previous row/header cell count
let inSection = false;
for (let i = 0; i < items.length; i++) {
const [previous, current] = [items[i - 1], items[i]];
if (current.type === "title") {
if (inSection) {
lines.push(renderSectionClose(columnWidths, previousCellCount));
inSection = false;
}
lines.push("╔" + "═".repeat(tableWidth) + "╗");
const titleDisplayWidth = getStringWidth(current.text);
const titleActualLength = current.text.length;
const centeredTitle = current.text
.padStart((tableWidth + titleDisplayWidth) / 2 +
(titleActualLength - titleDisplayWidth))
.padEnd(tableWidth + (titleActualLength - titleDisplayWidth));
lines.push("║" + centeredTitle + "║");
lines.push("╚" + "═".repeat(tableWidth) + "╝");
}
else if (current.type === "section-header") {
if (inSection) {
lines.push(renderSectionClose(columnWidths, previousCellCount));
}
lines.push("╔" + "═".repeat(tableWidth) + "╗");
const headerDisplayWidth = getStringWidth(current.text);
const headerActualLength = current.text.length;
const paddedHeader = current.text.padEnd(tableWidth - 2 + (headerActualLength - headerDisplayWidth));
lines.push("║ " + paddedHeader + " ║");
inSection = true;
}
else if (current.type === "header") {
const currentCellCount = current.cells.length;
const innerJoiner = previous !== undefined && previous.type === "section-header"
? "┬"
: "┼";
const needsTransition = previous !== undefined &&
previous.type !== "section-header" &&
currentCellCount < previousCellCount;
lines.push(renderHeaderOpen(columnWidths, currentCellCount, innerJoiner, needsTransition));
lines.push(renderContentLine(current.cells, columnWidths, currentCellCount));
previousCellCount = currentCellCount;
}
else if (current.type === "row") {
const currentCellCount = current.cells.length;
// Only add separator if previous wasn't a row
if (previous === undefined || previous.type !== "row") {
lines.push(renderRowSeparator(columnWidths, currentCellCount));
}
lines.push(renderContentLine(current.cells, columnWidths, currentCellCount));
previousCellCount = currentCellCount;
}
}
if (inSection) {
lines.push(renderSectionClose(columnWidths, previousCellCount));
}
return lines.join("\n");
}
//# sourceMappingURL=format.js.map
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/format.ts"],"names":[],"mappings":"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"}
import type { TableItemV2 } from "../format.js";
/**
* Calculate the display width of a string by removing ANSI escape codes.
*
* NOTE: This implementation only removes basic ANSI color/style codes and may
* not handle all escape sequences (e.g., cursor movement, complex control
* sequences).
*/
export declare function getStringWidth(str: string): number;
/**
* Calculates the minimum width needed by each column in the table
* to fit its content (accounting for ANSI color codes).
*/
export declare function getColumnWidths(items: TableItemV2[]): number[];
/**
* Calculates the inner width needed to fit the rows and headers
* (excludes borders, which are added during rendering).
*
* Each column is padded by 1 space on each side, and columns are
* separated by " │ " (3 spaces).
*/
export declare function getContentWidth(columnWidths: number[]): number;
/**
* Calculates the inner width needed to fit titles and section headers
* (excludes borders, which are added during rendering).
*
* Each title/header is padded by 1 space on each side.
* Accounts for ANSI color codes.
*/
export declare function getHeadingWidth(items: TableItemV2[]): number;
/**
* Calculates the width needed for unused columns when a row/header has fewer
* cells than the total column count (e.g., if table has 6 columns but row
* only has 2 cells, calculates space for the remaining 4 columns).
*/
export declare function getUnusedColumnsWidth(columnWidths: number[], previousCellCount: number): number;
/**
* Renders a horizontal rule segment by repeating a character for each column
* with padding, joined by a separator (e.g., "─────┼─────┼─────").
*/
export declare function renderRuleSegment(columnWidths: number[], char: string, joiner: string): string;
/**
* Renders a complete horizontal rule with left and right borders
* (e.g., "╟─────┼─────┼─────╢").
*/
export declare function renderHorizontalRule(leftBorder: string, columnWidths: number[], char: string, joiner: string, rightBorder: string): string;
/**
* Renders a content line containing cells from either a header or row.
*
* Handles two cases:
* - Full width: When all columns are used, cells are separated by " │ " and
* line ends with " ║" (e.g., "║ cell1 │ cell2 │ cell3 ║")
* - Short line: When fewer columns are used, active cells are followed by
* " │ " and empty space, ending with "║" (e.g., "║ cell1 │ cell2 │ ║")
*
* Accounts for ANSI color codes when padding cells.
*/
export declare function renderContentLine(cells: string[], columnWidths: number[], currentCellCount: number): string;
/**
* Renders the horizontal rule that appears above a header row.
*
* Handles three cases:
* - Transition rule: When going from more columns to fewer, shows ┴ marks
* where columns collapse (e.g., "╟───┼───┼───┴───┴───╢")
* - Full width: When header uses all columns (e.g., "╟───┬───┬───╢" or "╟───┼───┼───╢")
* - Short header: When header uses fewer columns than max (e.g., "╟───┬─────────╢")
*
* The innerJoiner determines the separator character: ┬ after section-header, ┼ otherwise.
*/
export declare function renderHeaderOpen(columnWidths: number[], currentCellCount: number, innerJoiner: string, needsTransition: boolean): string;
/**
* Renders the horizontal rule that appears above a row.
*
* Handles two cases:
* - Full width: When row uses all columns, renders with ┼ joiners and
* ends with ╢ (e.g., "╟───┼───┼───╢")
* - Short row: When row uses fewer columns, renders active columns with
* ┼ joiners, ends with ┤, then fills remaining space and ends with ║
* (e.g., "╟───┼───┤ ║")
*/
export declare function renderRowSeparator(columnWidths: number[], currentCellCount: number): string;
/**
* Renders the section's bottom border, placing ╧ marks under column
* separators where the last row/header had cells (e.g., if the last row
* looked like "║ a │ b │ ║", the bottom border would be
* "╚═══╧═══╧═══════╝").
*/
export declare function renderSectionClose(columnWidths: number[], previousCellCount: number): string;
//# sourceMappingURL=format.d.ts.map
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/internal/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAY9D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,CAM9D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAQ5D;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EAAE,EACtB,iBAAiB,EAAE,MAAM,GACxB,MAAM,CAGR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,MAAM,CAIR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EAAE,EACf,YAAY,EAAE,MAAM,EAAE,EACtB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAmCR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EAAE,EACtB,gBAAgB,EAAE,MAAM,EACxB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,OAAO,GACvB,MAAM,CA2BR;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EAAE,EACtB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAkBR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EAAE,EACtB,iBAAiB,EAAE,MAAM,GACxB,MAAM,CAcR"}
/**
* Calculate the display width of a string by removing ANSI escape codes.
*
* NOTE: This implementation only removes basic ANSI color/style codes and may
* not handle all escape sequences (e.g., cursor movement, complex control
* sequences).
*/
export function getStringWidth(str) {
// Remove ANSI escape codes if present
const stripped = str.replace(/\u001b\[[0-9;]*m/g, "");
return stripped.length;
}
/**
* Calculates the minimum width needed by each column in the table
* to fit its content (accounting for ANSI color codes).
*/
export function getColumnWidths(items) {
const columnWidths = [];
for (const item of items) {
if (item.type === "row" || item.type === "header") {
item.cells.forEach((cell, i) => {
columnWidths[i] = Math.max(columnWidths[i] ?? 0, getStringWidth(cell));
});
}
}
return columnWidths;
}
/**
* Calculates the inner width needed to fit the rows and headers
* (excludes borders, which are added during rendering).
*
* Each column is padded by 1 space on each side, and columns are
* separated by " │ " (3 spaces).
*/
export function getContentWidth(columnWidths) {
return (columnWidths.reduce((sum, w) => sum + w, 0) +
(columnWidths.length - 1) * 3 +
2);
}
/**
* Calculates the inner width needed to fit titles and section headers
* (excludes borders, which are added during rendering).
*
* Each title/header is padded by 1 space on each side.
* Accounts for ANSI color codes.
*/
export function getHeadingWidth(items) {
let headingWidth = 0;
for (const item of items) {
if (item.type === "section-header" || item.type === "title") {
headingWidth = Math.max(headingWidth, getStringWidth(item.text) + 2);
}
}
return headingWidth;
}
/**
* Calculates the width needed for unused columns when a row/header has fewer
* cells than the total column count (e.g., if table has 6 columns but row
* only has 2 cells, calculates space for the remaining 4 columns).
*/
export function getUnusedColumnsWidth(columnWidths, previousCellCount) {
const remainingWidths = columnWidths.slice(previousCellCount);
return remainingWidths.reduce((sum, w) => sum + w + 3, 0) - 3;
}
/**
* Renders a horizontal rule segment by repeating a character for each column
* with padding, joined by a separator (e.g., "─────┼─────┼─────").
*/
export function renderRuleSegment(columnWidths, char, joiner) {
return columnWidths.map((w) => char.repeat(w + 2)).join(joiner);
}
/**
* Renders a complete horizontal rule with left and right borders
* (e.g., "╟─────┼─────┼─────╢").
*/
export function renderHorizontalRule(leftBorder, columnWidths, char, joiner, rightBorder) {
return (leftBorder + renderRuleSegment(columnWidths, char, joiner) + rightBorder);
}
/**
* Renders a content line containing cells from either a header or row.
*
* Handles two cases:
* - Full width: When all columns are used, cells are separated by " │ " and
* line ends with " ║" (e.g., "║ cell1 │ cell2 │ cell3 ║")
* - Short line: When fewer columns are used, active cells are followed by
* " │ " and empty space, ending with "║" (e.g., "║ cell1 │ cell2 │ ║")
*
* Accounts for ANSI color codes when padding cells.
*/
export function renderContentLine(cells, columnWidths, currentCellCount) {
if (currentCellCount === columnWidths.length) {
return ("║ " +
cells
.map((cell, j) => {
const displayWidth = getStringWidth(cell);
const actualLength = cell.length;
// Adjust padding to account for ANSI escape codes
return cell.padEnd(columnWidths[j] + actualLength - displayWidth);
})
.join(" │ ") +
" ║");
}
else {
const usedWidths = columnWidths.slice(0, currentCellCount);
const remainingWidth = getUnusedColumnsWidth(columnWidths, currentCellCount);
return ("║ " +
cells
.map((cell, j) => {
const displayWidth = getStringWidth(cell);
const actualLength = cell.length;
// Adjust padding to account for ANSI escape codes
return cell.padEnd(usedWidths[j] + actualLength - displayWidth);
})
.join(" │ ") +
" │ " +
" ".repeat(remainingWidth + 1) +
"║");
}
}
/**
* Renders the horizontal rule that appears above a header row.
*
* Handles three cases:
* - Transition rule: When going from more columns to fewer, shows ┴ marks
* where columns collapse (e.g., "╟───┼───┼───┴───┴───╢")
* - Full width: When header uses all columns (e.g., "╟───┬───┬───╢" or "╟───┼───┼───╢")
* - Short header: When header uses fewer columns than max (e.g., "╟───┬─────────╢")
*
* The innerJoiner determines the separator character: ┬ after section-header, ┼ otherwise.
*/
export function renderHeaderOpen(columnWidths, currentCellCount, innerJoiner, needsTransition) {
if (needsTransition) {
const usedWidths = columnWidths.slice(0, currentCellCount);
const collapsingWidths = columnWidths.slice(currentCellCount);
return ("╟" +
renderRuleSegment(usedWidths, "─", "┼") +
"┼" +
renderRuleSegment(collapsingWidths, "─", "┴") +
"╢");
}
else if (currentCellCount === columnWidths.length) {
return renderHorizontalRule("╟", columnWidths, "─", innerJoiner, "╢");
}
else {
const usedWidths = columnWidths.slice(0, currentCellCount);
const remainingWidth = getUnusedColumnsWidth(columnWidths, currentCellCount);
return ("╟" +
renderRuleSegment(usedWidths, "─", innerJoiner) +
innerJoiner +
"─".repeat(remainingWidth + 2) +
"╢");
}
}
/**
* Renders the horizontal rule that appears above a row.
*
* Handles two cases:
* - Full width: When row uses all columns, renders with ┼ joiners and
* ends with ╢ (e.g., "╟───┼───┼───╢")
* - Short row: When row uses fewer columns, renders active columns with
* ┼ joiners, ends with ┤, then fills remaining space and ends with ║
* (e.g., "╟───┼───┤ ║")
*/
export function renderRowSeparator(columnWidths, currentCellCount) {
if (currentCellCount === columnWidths.length) {
return renderHorizontalRule("╟", columnWidths, "─", "┼", "╢");
}
else {
// Short row - ends with ┤ instead of ╢
const usedWidths = columnWidths.slice(0, currentCellCount);
const remainingWidth = getUnusedColumnsWidth(columnWidths, currentCellCount);
return ("╟" +
renderRuleSegment(usedWidths, "─", "┼") +
"┤" +
" ".repeat(remainingWidth + 2) +
"║");
}
}
/**
* Renders the section's bottom border, placing ╧ marks under column
* separators where the last row/header had cells (e.g., if the last row
* looked like "║ a │ b │ ║", the bottom border would be
* "╚═══╧═══╧═══════╝").
*/
export function renderSectionClose(columnWidths, previousCellCount) {
if (previousCellCount === columnWidths.length) {
return renderHorizontalRule("╚", columnWidths, "═", "╧", "╝");
}
else {
const usedWidths = columnWidths.slice(0, previousCellCount);
const unusedWidth = getUnusedColumnsWidth(columnWidths, previousCellCount);
return ("╚" +
renderRuleSegment(usedWidths, "═", "╧") +
"╧" +
renderRuleSegment([unusedWidth], "═", "") +
"╝");
}
}
//# sourceMappingURL=format.js.map
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/internal/format.ts"],"names":[],"mappings":"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"}
export declare function panicErrorCodeToReason(errorCode: bigint): string | undefined;
//# sourceMappingURL=panic-errors.d.ts.map
{"version":3,"file":"panic-errors.d.ts","sourceRoot":"","sources":["../../../src/internal/panic-errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAsB5E"}
export function panicErrorCodeToReason(errorCode) {
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- we are only covering some of the integer range
switch (errorCode) {
case 0x1n:
return "Assertion error";
case 0x11n:
return "Arithmetic operation overflowed outside of an unchecked block";
case 0x12n:
return "Division or modulo division by zero";
case 0x21n:
return "Tried to convert a value into an enum, but the value was too big or negative";
case 0x22n:
return "Incorrectly encoded storage byte array";
case 0x31n:
return ".pop() was called on an empty array";
case 0x32n:
return "Array accessed at an out-of-bounds or negative index";
case 0x41n:
return "Too much memory was allocated, or an array was created that is too large";
case 0x51n:
return "Called a zero-initialized variable of internal function type";
}
}
//# sourceMappingURL=panic-errors.js.map
{"version":3,"file":"panic-errors.js","sourceRoot":"","sources":["../../../src/internal/panic-errors.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,4HAA4H;IAC5H,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,IAAI;YACP,OAAO,iBAAiB,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,+DAA+D,CAAC;QACzE,KAAK,KAAK;YACR,OAAO,qCAAqC,CAAC;QAC/C,KAAK,KAAK;YACR,OAAO,8EAA8E,CAAC;QACxF,KAAK,KAAK;YACR,OAAO,wCAAwC,CAAC;QAClD,KAAK,KAAK;YACR,OAAO,qCAAqC,CAAC;QAC/C,KAAK,KAAK;YACR,OAAO,sDAAsD,CAAC;QAChE,KAAK,KAAK;YACR,OAAO,0EAA0E,CAAC;QACpF,KAAK,KAAK;YACR,OAAO,8DAA8D,CAAC;IAC1E,CAAC;AACH,CAAC"}
import {
getColumnWidths,
getContentWidth,
getHeadingWidth,
getStringWidth,
renderContentLine,
renderHeaderOpen,
renderRowSeparator,
renderSectionClose,
} from "./internal/format.js";
export type TableRow = string[];
export interface TableDivider {
type: "divider";
}
export type TableItem = TableRow | TableDivider;
export const divider: TableDivider = { type: "divider" };
/**
* Formats an array of rows and dividers into a table string.
*
* @param items An array of table rows (string arrays) and dividers.
* Dividers are objects with type: "divider" and will be rendered as table dividers.
* @returns The formatted table as a string, ready to be rendered.
*
* @example
* ```ts
* formatTable([
* ["Name", "Age"],
* divider,
* ["Alice", "30"],
* ["Bob", "25"],
* divider,
* ["Average", "27.5"]
* ]);
*
* // =>
* // | Name | Age |
* // | ------- | ---- |
* // | Alice | 30 |
* // | Bob | 25 |
* // | ------- | ---- |
* // | Average | 27.5 |
* ```
*/
export function formatTable(items: TableItem[]): string {
const widths: number[] = [];
const dataRows: string[][] = [];
for (const item of items) {
if (Array.isArray(item)) {
dataRows.push([...item]);
}
}
// Calculate maximum width for each column
for (const row of dataRows) {
for (let i = 0; i < row.length; i++) {
while (i >= widths.length) {
widths.push(0);
}
widths[i] = Math.max(widths[i], getStringWidth(row[i]));
}
}
const dividerRow = widths.map((width) => "-".repeat(width));
const outputRows: string[][] = [];
for (const item of items) {
if (Array.isArray(item)) {
const row = [...item];
// Pad the row to match the number of columns
while (row.length < widths.length) {
row.push("");
}
outputRows.push(row);
} else {
outputRows.push([...dividerRow]);
}
}
outputRows.forEach((row) => {
for (let i = 0; i < row.length; i++) {
const displayWidth = getStringWidth(row[i]);
const actualLength = row[i].length;
// Adjust padding to account for difference between display width and actual length
row[i] = row[i].padEnd(widths[i] + actualLength - displayWidth);
}
});
return outputRows.map((row) => `| ${row.join(" | ")} |`).join("\n");
}
export interface TableTitleV2 {
type: "title";
text: string;
}
export interface TableSectionHeaderV2 {
type: "section-header";
text: string;
}
export interface TableHeaderV2 {
type: "header";
cells: string[];
}
export interface TableRowV2 {
type: "row";
cells: string[];
}
export type TableItemV2 =
| TableTitleV2
| TableSectionHeaderV2
| TableHeaderV2
| TableRowV2;
/**
* Formats an array of titles, section headers, headers, and rows into a table
* string with box-drawing characters.
*
* Features:
* - Titles are centered in a standalone box with double borders (╔═╗)
* - Section headers group related content with automatic closing
* - Headers and rows can have different numbers of cells
* - Rows with fewer cells than max columns are handled with special rendering
*
* @param items An array of table items (titles, section headers, headers, and rows).
* Sections are automatically closed when a new section-header or title appears, or
* at the end of the table.
* @returns The formatted table as a string, ready to be rendered.
*
* @example
* ```ts
* formatTableV2([
* { type: "title", text: "My Table" },
* { type: "section-header", text: "User Data" },
* { type: "header", cells: ["Name", "Age", "City"] },
* { type: "row", cells: ["Alice", "30", "NYC"] },
* { type: "row", cells: ["Bob", "25", "LA"] },
* { type: "section-header", text: "Summary" },
* { type: "header", cells: ["Total", "Count"] },
* { type: "row", cells: ["55", "2"] }
* ]);
*
* // =>
* // ╔═══════════════════╗
* // ║ My Table ║
* // ╚═══════════════════╝
* // ╔═══════════════════╗
* // ║ User Data ║
* // ╟───────┬─────┬─────╢
* // ║ Name │ Age │ City║
* // ╟───────┼─────┼─────╢
* // ║ Alice │ 30 │ NYC ║
* // ╟───────┼─────┼─────╢
* // ║ Bob │ 25 │ LA ║
* // ╚═══════╧═════╧═════╝
* // ╔═══════════════════╗
* // ║ Summary ║
* // ╟───────┬───────────╢
* // ║ Total │ Count ║
* // ╟───────┼───────────╢
* // ║ 55 │ 2 ║
* // ╚═══════╧═══════════╝
* ```
*/
export function formatTableV2(items: TableItemV2[]): string {
if (items.length === 0) {
return "";
}
const columnWidths = getColumnWidths(items);
const contentWidth = getContentWidth(columnWidths);
const headingWidth = getHeadingWidth(items);
// If heading is wider than content, expand last column to fit
if (headingWidth > contentWidth && columnWidths.length > 0) {
const extraSpace = headingWidth - contentWidth;
columnWidths[columnWidths.length - 1] += extraSpace;
}
const tableWidth = Math.max(contentWidth, headingWidth);
const lines: string[] = [];
let previousCellCount = 0; // Keep track of previous row/header cell count
let inSection = false;
for (let i = 0; i < items.length; i++) {
const [previous, current] = [items[i - 1], items[i]];
if (current.type === "title") {
if (inSection) {
lines.push(renderSectionClose(columnWidths, previousCellCount));
inSection = false;
}
lines.push("╔" + "═".repeat(tableWidth) + "╗");
const titleDisplayWidth = getStringWidth(current.text);
const titleActualLength = current.text.length;
const centeredTitle = current.text
.padStart(
(tableWidth + titleDisplayWidth) / 2 +
(titleActualLength - titleDisplayWidth),
)
.padEnd(tableWidth + (titleActualLength - titleDisplayWidth));
lines.push("║" + centeredTitle + "║");
lines.push("╚" + "═".repeat(tableWidth) + "╝");
} else if (current.type === "section-header") {
if (inSection) {
lines.push(renderSectionClose(columnWidths, previousCellCount));
}
lines.push("╔" + "═".repeat(tableWidth) + "╗");
const headerDisplayWidth = getStringWidth(current.text);
const headerActualLength = current.text.length;
const paddedHeader = current.text.padEnd(
tableWidth - 2 + (headerActualLength - headerDisplayWidth),
);
lines.push("║ " + paddedHeader + " ║");
inSection = true;
} else if (current.type === "header") {
const currentCellCount = current.cells.length;
const innerJoiner =
previous !== undefined && previous.type === "section-header"
? "┬"
: "┼";
const needsTransition =
previous !== undefined &&
previous.type !== "section-header" &&
currentCellCount < previousCellCount;
lines.push(
renderHeaderOpen(
columnWidths,
currentCellCount,
innerJoiner,
needsTransition,
),
);
lines.push(
renderContentLine(current.cells, columnWidths, currentCellCount),
);
previousCellCount = currentCellCount;
} else if (current.type === "row") {
const currentCellCount = current.cells.length;
// Only add separator if previous wasn't a row
if (previous === undefined || previous.type !== "row") {
lines.push(renderRowSeparator(columnWidths, currentCellCount));
}
lines.push(
renderContentLine(current.cells, columnWidths, currentCellCount),
);
previousCellCount = currentCellCount;
}
}
if (inSection) {
lines.push(renderSectionClose(columnWidths, previousCellCount));
}
return lines.join("\n");
}
import type { TableItemV2 } from "../format.js";
/**
* Calculate the display width of a string by removing ANSI escape codes.
*
* NOTE: This implementation only removes basic ANSI color/style codes and may
* not handle all escape sequences (e.g., cursor movement, complex control
* sequences).
*/
export function getStringWidth(str: string): number {
// Remove ANSI escape codes if present
const stripped = str.replace(/\u001b\[[0-9;]*m/g, "");
return stripped.length;
}
/**
* Calculates the minimum width needed by each column in the table
* to fit its content (accounting for ANSI color codes).
*/
export function getColumnWidths(items: TableItemV2[]): number[] {
const columnWidths: number[] = [];
for (const item of items) {
if (item.type === "row" || item.type === "header") {
item.cells.forEach((cell, i) => {
columnWidths[i] = Math.max(columnWidths[i] ?? 0, getStringWidth(cell));
});
}
}
return columnWidths;
}
/**
* Calculates the inner width needed to fit the rows and headers
* (excludes borders, which are added during rendering).
*
* Each column is padded by 1 space on each side, and columns are
* separated by " │ " (3 spaces).
*/
export function getContentWidth(columnWidths: number[]): number {
return (
columnWidths.reduce((sum, w) => sum + w, 0) +
(columnWidths.length - 1) * 3 +
2
);
}
/**
* Calculates the inner width needed to fit titles and section headers
* (excludes borders, which are added during rendering).
*
* Each title/header is padded by 1 space on each side.
* Accounts for ANSI color codes.
*/
export function getHeadingWidth(items: TableItemV2[]): number {
let headingWidth = 0;
for (const item of items) {
if (item.type === "section-header" || item.type === "title") {
headingWidth = Math.max(headingWidth, getStringWidth(item.text) + 2);
}
}
return headingWidth;
}
/**
* Calculates the width needed for unused columns when a row/header has fewer
* cells than the total column count (e.g., if table has 6 columns but row
* only has 2 cells, calculates space for the remaining 4 columns).
*/
export function getUnusedColumnsWidth(
columnWidths: number[],
previousCellCount: number,
): number {
const remainingWidths = columnWidths.slice(previousCellCount);
return remainingWidths.reduce((sum, w) => sum + w + 3, 0) - 3;
}
/**
* Renders a horizontal rule segment by repeating a character for each column
* with padding, joined by a separator (e.g., "─────┼─────┼─────").
*/
export function renderRuleSegment(
columnWidths: number[],
char: string,
joiner: string,
): string {
return columnWidths.map((w) => char.repeat(w + 2)).join(joiner);
}
/**
* Renders a complete horizontal rule with left and right borders
* (e.g., "╟─────┼─────┼─────╢").
*/
export function renderHorizontalRule(
leftBorder: string,
columnWidths: number[],
char: string,
joiner: string,
rightBorder: string,
): string {
return (
leftBorder + renderRuleSegment(columnWidths, char, joiner) + rightBorder
);
}
/**
* Renders a content line containing cells from either a header or row.
*
* Handles two cases:
* - Full width: When all columns are used, cells are separated by " │ " and
* line ends with " ║" (e.g., "║ cell1 │ cell2 │ cell3 ║")
* - Short line: When fewer columns are used, active cells are followed by
* " │ " and empty space, ending with "║" (e.g., "║ cell1 │ cell2 │ ║")
*
* Accounts for ANSI color codes when padding cells.
*/
export function renderContentLine(
cells: string[],
columnWidths: number[],
currentCellCount: number,
): string {
if (currentCellCount === columnWidths.length) {
return (
"║ " +
cells
.map((cell, j) => {
const displayWidth = getStringWidth(cell);
const actualLength = cell.length;
// Adjust padding to account for ANSI escape codes
return cell.padEnd(columnWidths[j] + actualLength - displayWidth);
})
.join(" │ ") +
" ║"
);
} else {
const usedWidths = columnWidths.slice(0, currentCellCount);
const remainingWidth = getUnusedColumnsWidth(
columnWidths,
currentCellCount,
);
return (
"║ " +
cells
.map((cell, j) => {
const displayWidth = getStringWidth(cell);
const actualLength = cell.length;
// Adjust padding to account for ANSI escape codes
return cell.padEnd(usedWidths[j] + actualLength - displayWidth);
})
.join(" │ ") +
" │ " +
" ".repeat(remainingWidth + 1) +
"║"
);
}
}
/**
* Renders the horizontal rule that appears above a header row.
*
* Handles three cases:
* - Transition rule: When going from more columns to fewer, shows ┴ marks
* where columns collapse (e.g., "╟───┼───┼───┴───┴───╢")
* - Full width: When header uses all columns (e.g., "╟───┬───┬───╢" or "╟───┼───┼───╢")
* - Short header: When header uses fewer columns than max (e.g., "╟───┬─────────╢")
*
* The innerJoiner determines the separator character: ┬ after section-header, ┼ otherwise.
*/
export function renderHeaderOpen(
columnWidths: number[],
currentCellCount: number,
innerJoiner: string,
needsTransition: boolean,
): string {
if (needsTransition) {
const usedWidths = columnWidths.slice(0, currentCellCount);
const collapsingWidths = columnWidths.slice(currentCellCount);
return (
"╟" +
renderRuleSegment(usedWidths, "─", "┼") +
"┼" +
renderRuleSegment(collapsingWidths, "─", "┴") +
"╢"
);
} else if (currentCellCount === columnWidths.length) {
return renderHorizontalRule("╟", columnWidths, "─", innerJoiner, "╢");
} else {
const usedWidths = columnWidths.slice(0, currentCellCount);
const remainingWidth = getUnusedColumnsWidth(
columnWidths,
currentCellCount,
);
return (
"╟" +
renderRuleSegment(usedWidths, "─", innerJoiner) +
innerJoiner +
"─".repeat(remainingWidth + 2) +
"╢"
);
}
}
/**
* Renders the horizontal rule that appears above a row.
*
* Handles two cases:
* - Full width: When row uses all columns, renders with ┼ joiners and
* ends with ╢ (e.g., "╟───┼───┼───╢")
* - Short row: When row uses fewer columns, renders active columns with
* ┼ joiners, ends with ┤, then fills remaining space and ends with ║
* (e.g., "╟───┼───┤ ║")
*/
export function renderRowSeparator(
columnWidths: number[],
currentCellCount: number,
): string {
if (currentCellCount === columnWidths.length) {
return renderHorizontalRule("╟", columnWidths, "─", "┼", "╢");
} else {
// Short row - ends with ┤ instead of ╢
const usedWidths = columnWidths.slice(0, currentCellCount);
const remainingWidth = getUnusedColumnsWidth(
columnWidths,
currentCellCount,
);
return (
"╟" +
renderRuleSegment(usedWidths, "─", "┼") +
"┤" +
" ".repeat(remainingWidth + 2) +
"║"
);
}
}
/**
* Renders the section's bottom border, placing ╧ marks under column
* separators where the last row/header had cells (e.g., if the last row
* looked like "║ a │ b │ ║", the bottom border would be
* "╚═══╧═══╧═══════╝").
*/
export function renderSectionClose(
columnWidths: number[],
previousCellCount: number,
): string {
if (previousCellCount === columnWidths.length) {
return renderHorizontalRule("╚", columnWidths, "═", "╧", "╝");
} else {
const usedWidths = columnWidths.slice(0, previousCellCount);
const unusedWidth = getUnusedColumnsWidth(columnWidths, previousCellCount);
return (
"╚" +
renderRuleSegment(usedWidths, "═", "╧") +
"╧" +
renderRuleSegment([unusedWidth], "═", "") +
"╝"
);
}
}
export function panicErrorCodeToReason(errorCode: bigint): string | undefined {
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- we are only covering some of the integer range
switch (errorCode) {
case 0x1n:
return "Assertion error";
case 0x11n:
return "Arithmetic operation overflowed outside of an unchecked block";
case 0x12n:
return "Division or modulo division by zero";
case 0x21n:
return "Tried to convert a value into an enum, but the value was too big or negative";
case 0x22n:
return "Incorrectly encoded storage byte array";
case 0x31n:
return ".pop() was called on an empty array";
case 0x32n:
return "Array accessed at an out-of-bounds or negative index";
case 0x41n:
return "Too much memory was allocated, or an array was created that is too large";
case 0x51n:
return "Called a zero-initialized variable of internal function type";
}
}
+6
-0
# @nomicfoundation/hardhat-utils
## 3.0.4
### Patch Changes
- d1969e7: Added support for showing gas statistics after running nodejs tests ([#7472](https://github.com/NomicFoundation/hardhat/issues/7428)).
## 3.0.3

@@ -4,0 +10,0 @@

@@ -0,2 +1,15 @@

/**
* Converts a Solidity panic error code into a human-readable revert message.
*
* Solidity defines a set of standardized panic codes (0x01, 0x11, etc.)
* that represent specific runtime errors (e.g. arithmetic overflow).
* This function looks up the corresponding reason string and formats it
* into a message similar to what clients like Hardhat or ethers.js display.
*
* @param errorCode The panic error code returned by the EVM as a bigint.
* @returns A formatted message string:
* - `"reverted with panic code <hex> (<reason>)"` if the code is recognized.
* - `"reverted with unknown panic code <hex>"` if the code is not recognized.
*/
export declare function panicErrorCodeToMessage(errorCode: bigint): string;
//# sourceMappingURL=panic-errors.d.ts.map
+1
-1

@@ -1,1 +0,1 @@

{"version":3,"file":"panic-errors.d.ts","sourceRoot":"","sources":["../../src/panic-errors.ts"],"names":[],"mappings":"AAEA,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQjE"}
{"version":3,"file":"panic-errors.d.ts","sourceRoot":"","sources":["../../src/panic-errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQjE"}
import { numberToHexString } from "./hex.js";
import { panicErrorCodeToReason } from "./internal/panic-errors.js";
/**
* Converts a Solidity panic error code into a human-readable revert message.
*
* Solidity defines a set of standardized panic codes (0x01, 0x11, etc.)
* that represent specific runtime errors (e.g. arithmetic overflow).
* This function looks up the corresponding reason string and formats it
* into a message similar to what clients like Hardhat or ethers.js display.
*
* @param errorCode The panic error code returned by the EVM as a bigint.
* @returns A formatted message string:
* - `"reverted with panic code <hex> (<reason>)"` if the code is recognized.
* - `"reverted with unknown panic code <hex>"` if the code is not recognized.
*/
export function panicErrorCodeToMessage(errorCode) {

@@ -9,25 +23,2 @@ const reason = panicErrorCodeToReason(errorCode);

}
function panicErrorCodeToReason(errorCode) {
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- we are only covering some of the integer range
switch (errorCode) {
case 0x1n:
return "Assertion error";
case 0x11n:
return "Arithmetic operation overflowed outside of an unchecked block";
case 0x12n:
return "Division or modulo division by zero";
case 0x21n:
return "Tried to convert a value into an enum, but the value was too big or negative";
case 0x22n:
return "Incorrectly encoded storage byte array";
case 0x31n:
return ".pop() was called on an empty array";
case 0x32n:
return "Array accessed at an out-of-bounds or negative index";
case 0x41n:
return "Too much memory was allocated, or an array was created that is too large";
case 0x51n:
return "Called a zero-initialized variable of internal function type";
}
}
//# sourceMappingURL=panic-errors.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"panic-errors.js","sourceRoot":"","sources":["../../src/panic-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAEjD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,4BAA4B,iBAAiB,CAAC,SAAS,CAAC,KAAK,MAAM,GAAG,CAAC;IAChF,CAAC;IAED,OAAO,oCAAoC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,sBAAsB,CAAC,SAAiB;IAC/C,4HAA4H;IAC5H,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,IAAI;YACP,OAAO,iBAAiB,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,+DAA+D,CAAC;QACzE,KAAK,KAAK;YACR,OAAO,qCAAqC,CAAC;QAC/C,KAAK,KAAK;YACR,OAAO,8EAA8E,CAAC;QACxF,KAAK,KAAK;YACR,OAAO,wCAAwC,CAAC;QAClD,KAAK,KAAK;YACR,OAAO,qCAAqC,CAAC;QAC/C,KAAK,KAAK;YACR,OAAO,sDAAsD,CAAC;QAChE,KAAK,KAAK;YACR,OAAO,0EAA0E,CAAC;QACpF,KAAK,KAAK;YACR,OAAO,8DAA8D,CAAC;IAC1E,CAAC;AACH,CAAC"}
{"version":3,"file":"panic-errors.js","sourceRoot":"","sources":["../../src/panic-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAEjD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,4BAA4B,iBAAiB,CAAC,SAAS,CAAC,KAAK,MAAM,GAAG,CAAC;IAChF,CAAC;IAED,OAAO,oCAAoC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;AAC5E,CAAC"}
{
"name": "@nomicfoundation/hardhat-utils",
"version": "3.0.3",
"version": "3.0.4",
"description": "Utilities for Hardhat and its plugins",

@@ -26,2 +26,3 @@ "homepage": "https://github.com/nomicfoundation/hardhat/tree/v-next/v-next/hardhat-utils",

"./eth": "./dist/src/eth.js",
"./format": "./dist/src/format.js",
"./fs": "./dist/src/fs.js",

@@ -28,0 +29,0 @@ "./global-dir": "./dist/src/global-dir.js",

import { numberToHexString } from "./hex.js";
import { panicErrorCodeToReason } from "./internal/panic-errors.js";
/**
* Converts a Solidity panic error code into a human-readable revert message.
*
* Solidity defines a set of standardized panic codes (0x01, 0x11, etc.)
* that represent specific runtime errors (e.g. arithmetic overflow).
* This function looks up the corresponding reason string and formats it
* into a message similar to what clients like Hardhat or ethers.js display.
*
* @param errorCode The panic error code returned by the EVM as a bigint.
* @returns A formatted message string:
* - `"reverted with panic code <hex> (<reason>)"` if the code is recognized.
* - `"reverted with unknown panic code <hex>"` if the code is not recognized.
*/
export function panicErrorCodeToMessage(errorCode: bigint): string {

@@ -12,25 +26,1 @@ const reason = panicErrorCodeToReason(errorCode);

}
function panicErrorCodeToReason(errorCode: bigint): string | undefined {
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- we are only covering some of the integer range
switch (errorCode) {
case 0x1n:
return "Assertion error";
case 0x11n:
return "Arithmetic operation overflowed outside of an unchecked block";
case 0x12n:
return "Division or modulo division by zero";
case 0x21n:
return "Tried to convert a value into an enum, but the value was too big or negative";
case 0x22n:
return "Incorrectly encoded storage byte array";
case 0x31n:
return ".pop() was called on an empty array";
case 0x32n:
return "Array accessed at an out-of-bounds or negative index";
case 0x41n:
return "Too much memory was allocated, or an array was created that is too large";
case 0x51n:
return "Called a zero-initialized variable of internal function type";
}
}