@diamondslab/diamonds-hardhat-foundry 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/foundry.d.ts +11 -0
  3. package/dist/foundry.d.ts.map +1 -0
  4. package/dist/foundry.js +104 -0
  5. package/dist/foundry.js.map +1 -0
  6. package/dist/framework/DeploymentManager.d.ts +48 -0
  7. package/dist/framework/DeploymentManager.d.ts.map +1 -0
  8. package/dist/framework/DeploymentManager.js +145 -0
  9. package/dist/framework/DeploymentManager.js.map +1 -0
  10. package/dist/framework/ForgeFuzzingFramework.d.ts +57 -0
  11. package/dist/framework/ForgeFuzzingFramework.d.ts.map +1 -0
  12. package/dist/framework/ForgeFuzzingFramework.js +119 -0
  13. package/dist/framework/ForgeFuzzingFramework.js.map +1 -0
  14. package/dist/framework/HelperGenerator.d.ts +27 -0
  15. package/dist/framework/HelperGenerator.d.ts.map +1 -0
  16. package/dist/framework/HelperGenerator.js +195 -0
  17. package/dist/framework/HelperGenerator.js.map +1 -0
  18. package/dist/index.d.ts +10 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/tasks/deploy.d.ts +2 -0
  22. package/dist/tasks/deploy.d.ts.map +1 -0
  23. package/dist/tasks/deploy.js +82 -0
  24. package/dist/tasks/deploy.js.map +1 -0
  25. package/dist/tasks/generate-helpers.d.ts +2 -0
  26. package/dist/tasks/generate-helpers.d.ts.map +1 -0
  27. package/dist/tasks/generate-helpers.js +66 -0
  28. package/dist/tasks/generate-helpers.js.map +1 -0
  29. package/dist/tasks/init.d.ts +2 -0
  30. package/dist/tasks/init.d.ts.map +1 -0
  31. package/dist/tasks/init.js +78 -0
  32. package/dist/tasks/init.js.map +1 -0
  33. package/dist/tasks/test.d.ts +2 -0
  34. package/dist/tasks/test.d.ts.map +1 -0
  35. package/dist/tasks/test.js +83 -0
  36. package/dist/tasks/test.js.map +1 -0
  37. package/dist/templates/DiamondDeployment.sol.template +38 -0
  38. package/dist/templates/ExampleFuzzTest.t.sol.template +109 -0
  39. package/dist/templates/ExampleIntegrationTest.t.sol.template +79 -0
  40. package/dist/templates/ExampleUnitTest.t.sol.template +59 -0
  41. package/dist/types/config.d.ts +41 -0
  42. package/dist/types/config.d.ts.map +1 -0
  43. package/dist/types/config.js +19 -0
  44. package/dist/types/config.js.map +1 -0
  45. package/dist/types/hardhat.d.ts +21 -0
  46. package/dist/types/hardhat.d.ts.map +1 -0
  47. package/dist/types/hardhat.js +8 -0
  48. package/dist/types/hardhat.js.map +1 -0
  49. package/dist/utils/foundry.d.ts +59 -0
  50. package/dist/utils/foundry.d.ts.map +1 -0
  51. package/dist/utils/foundry.js +164 -0
  52. package/dist/utils/foundry.js.map +1 -0
  53. package/dist/utils/logger.d.ts +38 -0
  54. package/dist/utils/logger.d.ts.map +1 -0
  55. package/dist/utils/logger.js +66 -0
  56. package/dist/utils/logger.js.map +1 -0
  57. package/dist/utils/validation.d.ts +33 -0
  58. package/dist/utils/validation.d.ts.map +1 -0
  59. package/dist/utils/validation.js +131 -0
  60. package/dist/utils/validation.js.map +1 -0
  61. package/package.json +4 -3
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFoundryVersion = exports.isFoundryInstalled = exports.compileForge = exports.runForgeTest = exports.execForgeAsync = exports.execForgeSync = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const logger_1 = require("./logger");
6
+ /**
7
+ * Execute a Foundry command synchronously
8
+ * @param command - The foundry command (e.g., "forge test")
9
+ * @param args - Command arguments
10
+ * @param options - Execution options
11
+ */
12
+ function execForgeSync(command, args = [], options = {}) {
13
+ const fullCommand = `${command} ${args.join(" ")}`;
14
+ logger_1.Logger.step(`Running: ${fullCommand}`);
15
+ try {
16
+ const output = (0, child_process_1.execSync)(fullCommand, {
17
+ cwd: options.cwd || process.cwd(),
18
+ stdio: options.stdio || "pipe",
19
+ encoding: "utf-8",
20
+ });
21
+ return output;
22
+ }
23
+ catch (error) {
24
+ logger_1.Logger.error(`Forge command failed: ${error.message}`);
25
+ if (error.stdout)
26
+ logger_1.Logger.info(error.stdout);
27
+ if (error.stderr)
28
+ logger_1.Logger.error(error.stderr);
29
+ throw error;
30
+ }
31
+ }
32
+ exports.execForgeSync = execForgeSync;
33
+ /**
34
+ * Execute a Foundry command asynchronously
35
+ * @param command - The foundry command (e.g., "forge")
36
+ * @param args - Command arguments
37
+ * @param options - Execution options
38
+ */
39
+ async function execForgeAsync(command, args = [], options = {}) {
40
+ logger_1.Logger.step(`Running: ${command} ${args.join(" ")}`);
41
+ return new Promise((resolve, reject) => {
42
+ const child = (0, child_process_1.spawn)(command, args, {
43
+ cwd: options.cwd || process.cwd(),
44
+ shell: true,
45
+ });
46
+ let stdout = "";
47
+ let stderr = "";
48
+ child.stdout?.on("data", (data) => {
49
+ const text = data.toString();
50
+ stdout += text;
51
+ if (options.verbose) {
52
+ process.stdout.write(text);
53
+ }
54
+ });
55
+ child.stderr?.on("data", (data) => {
56
+ const text = data.toString();
57
+ stderr += text;
58
+ if (options.verbose) {
59
+ process.stderr.write(text);
60
+ }
61
+ });
62
+ child.on("close", (code) => {
63
+ resolve({ stdout, stderr, exitCode: code || 0 });
64
+ });
65
+ child.on("error", (error) => {
66
+ logger_1.Logger.error(`Failed to spawn ${command}: ${error.message}`);
67
+ reject(error);
68
+ });
69
+ });
70
+ }
71
+ exports.execForgeAsync = execForgeAsync;
72
+ /**
73
+ * Run forge test with specified options
74
+ * @param options - Test execution options
75
+ */
76
+ async function runForgeTest(options) {
77
+ const args = ["test"];
78
+ if (options.matchTest) {
79
+ args.push("--match-test", options.matchTest);
80
+ }
81
+ if (options.matchContract) {
82
+ args.push("--match-contract", options.matchContract);
83
+ }
84
+ if (options.verbosity) {
85
+ args.push("-" + "v".repeat(options.verbosity));
86
+ }
87
+ if (options.gasReport) {
88
+ args.push("--gas-report");
89
+ }
90
+ try {
91
+ const result = await execForgeAsync("forge", args, {
92
+ cwd: options.cwd,
93
+ verbose: true,
94
+ });
95
+ const success = result.exitCode === 0;
96
+ if (success) {
97
+ logger_1.Logger.success("Forge tests passed!");
98
+ }
99
+ else {
100
+ logger_1.Logger.error("Forge tests failed");
101
+ }
102
+ return { success, output: result.stdout + result.stderr };
103
+ }
104
+ catch (error) {
105
+ logger_1.Logger.error(`Test execution failed: ${error.message}`);
106
+ return { success: false, output: error.message };
107
+ }
108
+ }
109
+ exports.runForgeTest = runForgeTest;
110
+ /**
111
+ * Compile Forge contracts
112
+ * @param options - Compilation options
113
+ */
114
+ async function compileForge(options) {
115
+ logger_1.Logger.step("Compiling Forge contracts...");
116
+ try {
117
+ const result = await execForgeAsync("forge", ["build"], {
118
+ cwd: options.cwd,
119
+ verbose: options.verbose,
120
+ });
121
+ const success = result.exitCode === 0;
122
+ if (success) {
123
+ logger_1.Logger.success("Forge compilation successful!");
124
+ }
125
+ else {
126
+ logger_1.Logger.error("Forge compilation failed");
127
+ }
128
+ return { success, output: result.stdout + result.stderr };
129
+ }
130
+ catch (error) {
131
+ logger_1.Logger.error(`Compilation failed: ${error.message}`);
132
+ return { success: false, output: error.message };
133
+ }
134
+ }
135
+ exports.compileForge = compileForge;
136
+ /**
137
+ * Check if Foundry is installed
138
+ */
139
+ function isFoundryInstalled() {
140
+ try {
141
+ (0, child_process_1.execSync)("forge --version", { stdio: "pipe" });
142
+ return true;
143
+ }
144
+ catch {
145
+ return false;
146
+ }
147
+ }
148
+ exports.isFoundryInstalled = isFoundryInstalled;
149
+ /**
150
+ * Get Foundry version
151
+ */
152
+ function getFoundryVersion() {
153
+ try {
154
+ const output = (0, child_process_1.execSync)("forge --version", { encoding: "utf-8", stdio: "pipe" });
155
+ // Extract version from output like "forge 0.2.0 (abc123 2024-01-01T00:00:00.000000000Z)"
156
+ const match = output.match(/forge\s+([\d.]+)/);
157
+ return match ? match[1] : null;
158
+ }
159
+ catch {
160
+ return null;
161
+ }
162
+ }
163
+ exports.getFoundryVersion = getFoundryVersion;
164
+ //# sourceMappingURL=foundry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundry.js","sourceRoot":"","sources":["../../src/utils/foundry.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync, spawn } from \"child_process\";\nimport { Logger } from \"./logger\";\n\n/**\n * Execute a Foundry command synchronously\n * @param command - The foundry command (e.g., \"forge test\")\n * @param args - Command arguments\n * @param options - Execution options\n */\nexport function execForgeSync(\n command: string,\n args: string[] = [],\n options: { cwd?: string; stdio?: \"inherit\" | \"pipe\" } = {}\n): string {\n const fullCommand = `${command} ${args.join(\" \")}`;\n Logger.step(`Running: ${fullCommand}`);\n\n try {\n const output = execSync(fullCommand, {\n cwd: options.cwd || process.cwd(),\n stdio: options.stdio || \"pipe\",\n encoding: \"utf-8\",\n });\n\n return output;\n } catch (error: any) {\n Logger.error(`Forge command failed: ${error.message}`);\n if (error.stdout) Logger.info(error.stdout);\n if (error.stderr) Logger.error(error.stderr);\n throw error;\n }\n}\n\n/**\n * Execute a Foundry command asynchronously\n * @param command - The foundry command (e.g., \"forge\")\n * @param args - Command arguments\n * @param options - Execution options\n */\nexport async function execForgeAsync(\n command: string,\n args: string[] = [],\n options: { cwd?: string; verbose?: boolean } = {}\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n Logger.step(`Running: ${command} ${args.join(\" \")}`);\n\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd || process.cwd(),\n shell: true,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (data) => {\n const text = data.toString();\n stdout += text;\n if (options.verbose) {\n process.stdout.write(text);\n }\n });\n\n child.stderr?.on(\"data\", (data) => {\n const text = data.toString();\n stderr += text;\n if (options.verbose) {\n process.stderr.write(text);\n }\n });\n\n child.on(\"close\", (code) => {\n resolve({ stdout, stderr, exitCode: code || 0 });\n });\n\n child.on(\"error\", (error) => {\n Logger.error(`Failed to spawn ${command}: ${error.message}`);\n reject(error);\n });\n });\n}\n\n/**\n * Run forge test with specified options\n * @param options - Test execution options\n */\nexport async function runForgeTest(options: {\n matchTest?: string;\n matchContract?: string;\n verbosity?: number;\n gasReport?: boolean;\n cwd?: string;\n env?: Record<string, string>;\n}): Promise<{ success: boolean; output: string }> {\n const args: string[] = [\"test\"];\n\n if (options.matchTest) {\n args.push(\"--match-test\", options.matchTest);\n }\n\n if (options.matchContract) {\n args.push(\"--match-contract\", options.matchContract);\n }\n\n if (options.verbosity) {\n args.push(\"-\" + \"v\".repeat(options.verbosity));\n }\n\n if (options.gasReport) {\n args.push(\"--gas-report\");\n }\n\n try {\n const result = await execForgeAsync(\"forge\", args, {\n cwd: options.cwd,\n verbose: true,\n });\n\n const success = result.exitCode === 0;\n \n if (success) {\n Logger.success(\"Forge tests passed!\");\n } else {\n Logger.error(\"Forge tests failed\");\n }\n\n return { success, output: result.stdout + result.stderr };\n } catch (error: any) {\n Logger.error(`Test execution failed: ${error.message}`);\n return { success: false, output: error.message };\n }\n}\n\n/**\n * Compile Forge contracts\n * @param options - Compilation options\n */\nexport async function compileForge(options: {\n cwd?: string;\n verbose?: boolean;\n}): Promise<{ success: boolean; output: string }> {\n Logger.step(\"Compiling Forge contracts...\");\n\n try {\n const result = await execForgeAsync(\"forge\", [\"build\"], {\n cwd: options.cwd,\n verbose: options.verbose,\n });\n\n const success = result.exitCode === 0;\n \n if (success) {\n Logger.success(\"Forge compilation successful!\");\n } else {\n Logger.error(\"Forge compilation failed\");\n }\n\n return { success, output: result.stdout + result.stderr };\n } catch (error: any) {\n Logger.error(`Compilation failed: ${error.message}`);\n return { success: false, output: error.message };\n }\n}\n\n/**\n * Check if Foundry is installed\n */\nexport function isFoundryInstalled(): boolean {\n try {\n execSync(\"forge --version\", { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get Foundry version\n */\nexport function getFoundryVersion(): string | null {\n try {\n const output = execSync(\"forge --version\", { encoding: \"utf-8\", stdio: \"pipe\" });\n // Extract version from output like \"forge 0.2.0 (abc123 2024-01-01T00:00:00.000000000Z)\"\n const match = output.match(/forge\\s+([\\d.]+)/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Logger utility for colored console output
3
+ */
4
+ export declare class Logger {
5
+ /**
6
+ * Log an info message in cyan
7
+ */
8
+ static info(message: string): void;
9
+ /**
10
+ * Log a success message in green
11
+ */
12
+ static success(message: string): void;
13
+ /**
14
+ * Log a warning message in yellow
15
+ */
16
+ static warn(message: string): void;
17
+ /**
18
+ * Log an error message in red
19
+ */
20
+ static error(message: string): void;
21
+ /**
22
+ * Log a step message in blue
23
+ */
24
+ static step(message: string): void;
25
+ /**
26
+ * Log a verbose/debug message in gray
27
+ */
28
+ static debug(message: string): void;
29
+ /**
30
+ * Log a highlighted message in magenta
31
+ */
32
+ static highlight(message: string): void;
33
+ /**
34
+ * Create a formatted section header
35
+ */
36
+ static section(title: string): void;
37
+ }
38
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAOpC"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Logger = void 0;
7
+ const picocolors_1 = __importDefault(require("picocolors"));
8
+ /**
9
+ * Logger utility for colored console output
10
+ */
11
+ class Logger {
12
+ /**
13
+ * Log an info message in cyan
14
+ */
15
+ static info(message) {
16
+ console.log(picocolors_1.default.cyan(`ℹ ${message}`));
17
+ }
18
+ /**
19
+ * Log a success message in green
20
+ */
21
+ static success(message) {
22
+ console.log(picocolors_1.default.green(`✓ ${message}`));
23
+ }
24
+ /**
25
+ * Log a warning message in yellow
26
+ */
27
+ static warn(message) {
28
+ console.log(picocolors_1.default.yellow(`⚠ ${message}`));
29
+ }
30
+ /**
31
+ * Log an error message in red
32
+ */
33
+ static error(message) {
34
+ console.log(picocolors_1.default.red(`✗ ${message}`));
35
+ }
36
+ /**
37
+ * Log a step message in blue
38
+ */
39
+ static step(message) {
40
+ console.log(picocolors_1.default.blue(`→ ${message}`));
41
+ }
42
+ /**
43
+ * Log a verbose/debug message in gray
44
+ */
45
+ static debug(message) {
46
+ console.log(picocolors_1.default.gray(` ${message}`));
47
+ }
48
+ /**
49
+ * Log a highlighted message in magenta
50
+ */
51
+ static highlight(message) {
52
+ console.log(picocolors_1.default.magenta(`★ ${message}`));
53
+ }
54
+ /**
55
+ * Create a formatted section header
56
+ */
57
+ static section(title) {
58
+ console.log("");
59
+ console.log(picocolors_1.default.bold(picocolors_1.default.cyan(`${"=".repeat(60)}`)));
60
+ console.log(picocolors_1.default.bold(picocolors_1.default.cyan(` ${title}`)));
61
+ console.log(picocolors_1.default.bold(picocolors_1.default.cyan(`${"=".repeat(60)}`)));
62
+ console.log("");
63
+ }
64
+ }
65
+ exports.Logger = Logger;
66
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AAEpC;;GAEG;AACH,MAAa,MAAM;IACjB;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAe;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAe;QAC5B,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAe;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,MAAM,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAe;QAC1B,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAe;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAe;QAC1B,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,OAAe;QAC9B,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,OAAO,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,IAAI,CAAC,oBAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,IAAI,CAAC,oBAAU,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,IAAI,CAAC,oBAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;CACF;AA5DD,wBA4DC","sourcesContent":["import picocolors from \"picocolors\";\n\n/**\n * Logger utility for colored console output\n */\nexport class Logger {\n /**\n * Log an info message in cyan\n */\n static info(message: string): void {\n console.log(picocolors.cyan(`ℹ ${message}`));\n }\n\n /**\n * Log a success message in green\n */\n static success(message: string): void {\n console.log(picocolors.green(`✓ ${message}`));\n }\n\n /**\n * Log a warning message in yellow\n */\n static warn(message: string): void {\n console.log(picocolors.yellow(`⚠ ${message}`));\n }\n\n /**\n * Log an error message in red\n */\n static error(message: string): void {\n console.log(picocolors.red(`✗ ${message}`));\n }\n\n /**\n * Log a step message in blue\n */\n static step(message: string): void {\n console.log(picocolors.blue(`→ ${message}`));\n }\n\n /**\n * Log a verbose/debug message in gray\n */\n static debug(message: string): void {\n console.log(picocolors.gray(` ${message}`));\n }\n\n /**\n * Log a highlighted message in magenta\n */\n static highlight(message: string): void {\n console.log(picocolors.magenta(`★ ${message}`));\n }\n\n /**\n * Create a formatted section header\n */\n static section(title: string): void {\n console.log(\"\");\n console.log(picocolors.bold(picocolors.cyan(`${\"=\".repeat(60)}`)));\n console.log(picocolors.bold(picocolors.cyan(` ${title}`)));\n console.log(picocolors.bold(picocolors.cyan(`${\"=\".repeat(60)}`)));\n console.log(\"\");\n }\n}\n"]}
@@ -0,0 +1,33 @@
1
+ import { DiamondsFoundryConfig } from "../types/config";
2
+ /**
3
+ * Validation utilities for diamonds-hardhat-foundry plugin
4
+ */
5
+ /**
6
+ * Check if Foundry is installed
7
+ */
8
+ export declare function validateFoundryInstallation(): boolean;
9
+ /**
10
+ * Check if Foundry is installed and throw error if not
11
+ */
12
+ export declare function requireFoundry(): void;
13
+ /**
14
+ * Check if a peer dependency is installed
15
+ */
16
+ export declare function validatePeerDependency(packageName: string): boolean;
17
+ /**
18
+ * Check if required peer dependencies are installed
19
+ */
20
+ export declare function validatePeerDependencies(): void;
21
+ /**
22
+ * Validate and merge user config with defaults
23
+ */
24
+ export declare function validateConfig(userConfig?: Partial<DiamondsFoundryConfig>): Required<DiamondsFoundryConfig>;
25
+ /**
26
+ * Check if a directory exists
27
+ */
28
+ export declare function validateDirectoryExists(path: string): boolean;
29
+ /**
30
+ * Validate output directory doesn't have conflicts
31
+ */
32
+ export declare function validateOutputDirectory(path: string, force?: boolean): void;
33
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGxE;;GAEG;AAEH;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAOrD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAMrC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAOnE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAqB/C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,UAAU,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GAC1C,QAAQ,CAAC,qBAAqB,CAAC,CA+CjC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,OAAe,GACrB,IAAI,CAMN"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateOutputDirectory = exports.validateDirectoryExists = exports.validateConfig = exports.validatePeerDependencies = exports.validatePeerDependency = exports.requireFoundry = exports.validateFoundryInstallation = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const fs_1 = require("fs");
6
+ const config_1 = require("../types/config");
7
+ const logger_1 = require("./logger");
8
+ /**
9
+ * Validation utilities for diamonds-hardhat-foundry plugin
10
+ */
11
+ /**
12
+ * Check if Foundry is installed
13
+ */
14
+ function validateFoundryInstallation() {
15
+ try {
16
+ (0, child_process_1.execSync)("forge --version", { stdio: "ignore" });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ exports.validateFoundryInstallation = validateFoundryInstallation;
24
+ /**
25
+ * Check if Foundry is installed and throw error if not
26
+ */
27
+ function requireFoundry() {
28
+ if (!validateFoundryInstallation()) {
29
+ logger_1.Logger.error("Foundry is not installed or not in PATH");
30
+ logger_1.Logger.info("Install Foundry from: https://getfoundry.sh/");
31
+ throw new Error("Foundry is required but not found");
32
+ }
33
+ }
34
+ exports.requireFoundry = requireFoundry;
35
+ /**
36
+ * Check if a peer dependency is installed
37
+ */
38
+ function validatePeerDependency(packageName) {
39
+ try {
40
+ require.resolve(packageName);
41
+ return true;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ exports.validatePeerDependency = validatePeerDependency;
48
+ /**
49
+ * Check if required peer dependencies are installed
50
+ */
51
+ function validatePeerDependencies() {
52
+ const requiredDeps = [
53
+ "@diamondslab/diamonds",
54
+ "@diamondslab/hardhat-diamonds",
55
+ ];
56
+ const missing = [];
57
+ for (const dep of requiredDeps) {
58
+ if (!validatePeerDependency(dep)) {
59
+ missing.push(dep);
60
+ }
61
+ }
62
+ if (missing.length > 0) {
63
+ logger_1.Logger.error("Missing required peer dependencies:");
64
+ missing.forEach((dep) => logger_1.Logger.error(` - ${dep}`));
65
+ logger_1.Logger.info("\nInstall them with:");
66
+ logger_1.Logger.info(` npm install ${missing.join(" ")}`);
67
+ throw new Error("Missing peer dependencies");
68
+ }
69
+ }
70
+ exports.validatePeerDependencies = validatePeerDependencies;
71
+ /**
72
+ * Validate and merge user config with defaults
73
+ */
74
+ function validateConfig(userConfig) {
75
+ const config = {
76
+ ...config_1.DEFAULT_CONFIG,
77
+ ...userConfig,
78
+ };
79
+ // Validate helpersDir is a string
80
+ if (typeof config.helpersDir !== "string") {
81
+ throw new Error("diamondsFoundry.helpersDir must be a string");
82
+ }
83
+ // Validate generateExamples is boolean
84
+ if (typeof config.generateExamples !== "boolean") {
85
+ throw new Error("diamondsFoundry.generateExamples must be a boolean");
86
+ }
87
+ // Validate exampleTests is array
88
+ if (!Array.isArray(config.exampleTests)) {
89
+ throw new Error("diamondsFoundry.exampleTests must be an array");
90
+ }
91
+ // Validate exampleTests values
92
+ const validTests = ["unit", "integration", "fuzz"];
93
+ for (const test of config.exampleTests) {
94
+ if (!validTests.includes(test)) {
95
+ throw new Error(`Invalid exampleTests value: ${test}. Must be one of: ${validTests.join(", ")}`);
96
+ }
97
+ }
98
+ // Validate defaultNetwork is string
99
+ if (typeof config.defaultNetwork !== "string") {
100
+ throw new Error("diamondsFoundry.defaultNetwork must be a string");
101
+ }
102
+ // Validate reuseDeployment is boolean
103
+ if (typeof config.reuseDeployment !== "boolean") {
104
+ throw new Error("diamondsFoundry.reuseDeployment must be a boolean");
105
+ }
106
+ // Validate forgeTestArgs is array
107
+ if (!Array.isArray(config.forgeTestArgs)) {
108
+ throw new Error("diamondsFoundry.forgeTestArgs must be an array");
109
+ }
110
+ return config;
111
+ }
112
+ exports.validateConfig = validateConfig;
113
+ /**
114
+ * Check if a directory exists
115
+ */
116
+ function validateDirectoryExists(path) {
117
+ return (0, fs_1.existsSync)(path);
118
+ }
119
+ exports.validateDirectoryExists = validateDirectoryExists;
120
+ /**
121
+ * Validate output directory doesn't have conflicts
122
+ */
123
+ function validateOutputDirectory(path, force = false) {
124
+ if (!force && validateDirectoryExists(path)) {
125
+ logger_1.Logger.warn(`Output directory already exists: ${path}`);
126
+ logger_1.Logger.info("Use --force to overwrite");
127
+ throw new Error("Output directory exists");
128
+ }
129
+ }
130
+ exports.validateOutputDirectory = validateOutputDirectory;
131
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport { DEFAULT_CONFIG, DiamondsFoundryConfig } from \"../types/config\";\nimport { Logger } from \"./logger\";\n\n/**\n * Validation utilities for diamonds-hardhat-foundry plugin\n */\n\n/**\n * Check if Foundry is installed\n */\nexport function validateFoundryInstallation(): boolean {\n try {\n execSync(\"forge --version\", { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if Foundry is installed and throw error if not\n */\nexport function requireFoundry(): void {\n if (!validateFoundryInstallation()) {\n Logger.error(\"Foundry is not installed or not in PATH\");\n Logger.info(\"Install Foundry from: https://getfoundry.sh/\");\n throw new Error(\"Foundry is required but not found\");\n }\n}\n\n/**\n * Check if a peer dependency is installed\n */\nexport function validatePeerDependency(packageName: string): boolean {\n try {\n require.resolve(packageName);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if required peer dependencies are installed\n */\nexport function validatePeerDependencies(): void {\n const requiredDeps = [\n \"@diamondslab/diamonds\",\n \"@diamondslab/hardhat-diamonds\",\n ];\n\n const missing: string[] = [];\n\n for (const dep of requiredDeps) {\n if (!validatePeerDependency(dep)) {\n missing.push(dep);\n }\n }\n\n if (missing.length > 0) {\n Logger.error(\"Missing required peer dependencies:\");\n missing.forEach((dep) => Logger.error(` - ${dep}`));\n Logger.info(\"\\nInstall them with:\");\n Logger.info(` npm install ${missing.join(\" \")}`);\n throw new Error(\"Missing peer dependencies\");\n }\n}\n\n/**\n * Validate and merge user config with defaults\n */\nexport function validateConfig(\n userConfig?: Partial<DiamondsFoundryConfig>\n): Required<DiamondsFoundryConfig> {\n const config: Required<DiamondsFoundryConfig> = {\n ...DEFAULT_CONFIG,\n ...userConfig,\n };\n\n // Validate helpersDir is a string\n if (typeof config.helpersDir !== \"string\") {\n throw new Error(\"diamondsFoundry.helpersDir must be a string\");\n }\n\n // Validate generateExamples is boolean\n if (typeof config.generateExamples !== \"boolean\") {\n throw new Error(\"diamondsFoundry.generateExamples must be a boolean\");\n }\n\n // Validate exampleTests is array\n if (!Array.isArray(config.exampleTests)) {\n throw new Error(\"diamondsFoundry.exampleTests must be an array\");\n }\n\n // Validate exampleTests values\n const validTests = [\"unit\", \"integration\", \"fuzz\"];\n for (const test of config.exampleTests) {\n if (!validTests.includes(test)) {\n throw new Error(\n `Invalid exampleTests value: ${test}. Must be one of: ${validTests.join(\", \")}`\n );\n }\n }\n\n // Validate defaultNetwork is string\n if (typeof config.defaultNetwork !== \"string\") {\n throw new Error(\"diamondsFoundry.defaultNetwork must be a string\");\n }\n\n // Validate reuseDeployment is boolean\n if (typeof config.reuseDeployment !== \"boolean\") {\n throw new Error(\"diamondsFoundry.reuseDeployment must be a boolean\");\n }\n\n // Validate forgeTestArgs is array\n if (!Array.isArray(config.forgeTestArgs)) {\n throw new Error(\"diamondsFoundry.forgeTestArgs must be an array\");\n }\n\n return config;\n}\n\n/**\n * Check if a directory exists\n */\nexport function validateDirectoryExists(path: string): boolean {\n return existsSync(path);\n}\n\n/**\n * Validate output directory doesn't have conflicts\n */\nexport function validateOutputDirectory(\n path: string,\n force: boolean = false\n): void {\n if (!force && validateDirectoryExists(path)) {\n Logger.warn(`Output directory already exists: ${path}`);\n Logger.info(\"Use --force to overwrite\");\n throw new Error(\"Output directory exists\");\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diamondslab/diamonds-hardhat-foundry",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Hardhat plugin that integrates Foundry testing with Diamond proxy contracts, providing deployment helpers and fuzzing support",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,12 +35,13 @@
35
35
  "prettier": "prettier \"**/*.{js,md,json}\"",
36
36
  "pretest": "cd ../.. && yarn build",
37
37
  "test": "mocha --recursive \"test/**/*.ts\" --exit",
38
- "build": "tsc --build .",
38
+ "build": "tsc --build . && yarn copy-templates",
39
+ "copy-templates": "mkdir -p dist/templates && cp src/templates/*.template dist/templates/",
39
40
  "prepublishOnly": "yarn build",
40
41
  "clean": "rimraf dist"
41
42
  },
42
43
  "files": [
43
- "dist/src/",
44
+ "dist/",
44
45
  "src/",
45
46
  "contracts/",
46
47
  "LICENSE",