create-fhevm-example 1.3.0 → 1.3.1
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.
- package/README.md +10 -10
- package/dist/scripts/add-mode.d.ts +4 -1
- package/dist/scripts/add-mode.d.ts.map +1 -1
- package/dist/scripts/add-mode.js +4 -1
- package/dist/scripts/builders.d.ts +7 -8
- package/dist/scripts/builders.d.ts.map +1 -1
- package/dist/scripts/builders.js +76 -25
- package/dist/scripts/doctor.d.ts +8 -0
- package/dist/scripts/doctor.d.ts.map +1 -1
- package/dist/scripts/doctor.js +8 -0
- package/dist/scripts/generate-config.d.ts +3 -3
- package/dist/scripts/generate-config.js +17 -9
- package/dist/scripts/generate-docs.d.ts +3 -2
- package/dist/scripts/generate-docs.d.ts.map +1 -1
- package/dist/scripts/generate-docs.js +3 -2
- package/dist/scripts/index.js +82 -58
- package/dist/scripts/maintenance.d.ts +5 -4
- package/dist/scripts/maintenance.d.ts.map +1 -1
- package/dist/scripts/maintenance.js +7 -56
- package/dist/scripts/ui.d.ts +3 -10
- package/dist/scripts/ui.d.ts.map +1 -1
- package/dist/scripts/ui.js +3 -30
- package/dist/scripts/utils.d.ts +18 -11
- package/dist/scripts/utils.d.ts.map +1 -1
- package/dist/scripts/utils.js +127 -106
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# create-fhevm-example
|
|
2
|
-
|
|
3
1
|
<p align="center">
|
|
4
2
|
<strong>Create FHEVM example projects with a single command</strong>
|
|
5
3
|
</p>
|
|
@@ -66,14 +64,16 @@ npx create-fhevm-example --example fhe-counter --output ./my-project --install -
|
|
|
66
64
|
|
|
67
65
|
## 📋 CLI Options
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
`--
|
|
72
|
-
`--
|
|
73
|
-
`--
|
|
74
|
-
`--
|
|
75
|
-
`--
|
|
76
|
-
`--
|
|
67
|
+
| Option | Description |
|
|
68
|
+
| :--- | :--- |
|
|
69
|
+
| `--example <name>` | Create a single example project |
|
|
70
|
+
| `--category <name>` | Create a category project |
|
|
71
|
+
| `--add` | Add FHEVM to an existing Hardhat project |
|
|
72
|
+
| `--target <dir>` | Target directory for `--add` mode (default: current dir) |
|
|
73
|
+
| `--output <dir>` | Output directory for new projects |
|
|
74
|
+
| `--install` | Auto-install dependencies after scaffolding |
|
|
75
|
+
| `--test` | Auto-run tests (requires `--install`) |
|
|
76
|
+
| `--help`, `-h` | Show help information |
|
|
77
77
|
|
|
78
78
|
---
|
|
79
79
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Add Mode -
|
|
2
|
+
* Add Mode - Feature for adding FHEVM to existing Hardhat projects.
|
|
3
|
+
*
|
|
4
|
+
* Logic for managing configuration updates, dependency installations,
|
|
5
|
+
* and scaffolding example contracts into established projects.
|
|
3
6
|
*/
|
|
4
7
|
/**
|
|
5
8
|
* Main function to add FHEVM capabilities to an existing Hardhat project
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-mode.d.ts","sourceRoot":"","sources":["../../scripts/add-mode.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"add-mode.d.ts","sourceRoot":"","sources":["../../scripts/add-mode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkRH;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8ElE"}
|
package/dist/scripts/add-mode.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Add Mode -
|
|
3
|
+
* Add Mode - Feature for adding FHEVM to existing Hardhat projects.
|
|
4
|
+
*
|
|
5
|
+
* Logic for managing configuration updates, dependency installations,
|
|
6
|
+
* and scaffolding example contracts into established projects.
|
|
4
7
|
*/
|
|
5
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
9
|
if (k2 === undefined) k2 = k;
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project Builders
|
|
2
|
+
* Project Builders - Core logic for scaffolding FHEVM projects.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Handles the creation of single example projects, category-based
|
|
5
|
+
* project bundles, and specialized test environments.
|
|
5
6
|
*/
|
|
6
7
|
/**
|
|
7
8
|
* Creates a single example project from the template
|
|
8
|
-
* @param exampleName - Name of the example to create
|
|
9
|
-
* @param outputDir - Target directory for the project
|
|
10
|
-
* @param tempRepoPath - Path to cloned template repository
|
|
11
9
|
*/
|
|
12
10
|
export declare function createSingleExample(exampleName: string, outputDir: string, tempRepoPath: string): Promise<void>;
|
|
13
11
|
/**
|
|
14
12
|
* Creates a category project with multiple examples
|
|
15
|
-
* @param categoryName - Name of the category to create
|
|
16
|
-
* @param outputDir - Target directory for the project
|
|
17
|
-
* @param tempRepoPath - Path to cloned template repository
|
|
18
13
|
*/
|
|
19
14
|
export declare function createCategoryProject(categoryName: string, outputDir: string, tempRepoPath: string): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a temporary test project using LOCAL files (used by maintenance.ts)
|
|
17
|
+
*/
|
|
18
|
+
export declare function createLocalTestProject(exampleNames: string[], outputDir: string): Promise<void>;
|
|
20
19
|
//# sourceMappingURL=builders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../scripts/builders.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"builders.d.ts","sourceRoot":"","sources":["../../scripts/builders.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0DH;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAiEf;AAMD;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,YAAY,EAAE,MAAM,EAAE,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAuEf"}
|
package/dist/scripts/builders.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Project Builders
|
|
3
|
+
* Project Builders - Core logic for scaffolding FHEVM projects.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Handles the creation of single example projects, category-based
|
|
6
|
+
* project bundles, and specialized test environments.
|
|
6
7
|
*/
|
|
7
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
9
|
if (k2 === undefined) k2 = k;
|
|
@@ -40,6 +41,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
42
|
exports.createSingleExample = createSingleExample;
|
|
42
43
|
exports.createCategoryProject = createCategoryProject;
|
|
44
|
+
exports.createLocalTestProject = createLocalTestProject;
|
|
43
45
|
const fs = __importStar(require("fs"));
|
|
44
46
|
const path = __importStar(require("path"));
|
|
45
47
|
const config_1 = require("./config");
|
|
@@ -73,13 +75,10 @@ async function initGitRepo(outputDir) {
|
|
|
73
75
|
}
|
|
74
76
|
}
|
|
75
77
|
// =============================================================================
|
|
76
|
-
//
|
|
78
|
+
// Project Scaffolding
|
|
77
79
|
// =============================================================================
|
|
78
80
|
/**
|
|
79
81
|
* Creates a single example project from the template
|
|
80
|
-
* @param exampleName - Name of the example to create
|
|
81
|
-
* @param outputDir - Target directory for the project
|
|
82
|
-
* @param tempRepoPath - Path to cloned template repository
|
|
83
82
|
*/
|
|
84
83
|
async function createSingleExample(exampleName, outputDir, tempRepoPath) {
|
|
85
84
|
const example = config_1.EXAMPLES[exampleName];
|
|
@@ -91,31 +90,23 @@ async function createSingleExample(exampleName, outputDir, tempRepoPath) {
|
|
|
91
90
|
if (!contractName) {
|
|
92
91
|
throw new Error("Could not extract contract name");
|
|
93
92
|
}
|
|
94
|
-
//
|
|
93
|
+
// 1. Copy template and clean up
|
|
95
94
|
(0, utils_1.copyDirectoryRecursive)(templateDir, outputDir);
|
|
96
95
|
(0, utils_1.cleanupTemplate)(outputDir);
|
|
97
|
-
//
|
|
96
|
+
// 2. Download example contract and dependencies
|
|
98
97
|
await (0, utils_1.downloadFileFromGitHub)(example.contract, path.join(outputDir, "contracts", `${contractName}.sol`));
|
|
99
|
-
// Download contract dependencies if specified
|
|
100
98
|
if (example.dependencies) {
|
|
101
99
|
await downloadDependencies(example.dependencies, outputDir);
|
|
102
100
|
}
|
|
103
|
-
//
|
|
101
|
+
// 3. Download test file
|
|
104
102
|
await (0, utils_1.downloadFileFromGitHub)(example.test, path.join(outputDir, "test", path.basename(example.test)));
|
|
105
|
-
//
|
|
103
|
+
// 4. Update deploy script and package.json
|
|
106
104
|
fs.writeFileSync(path.join(outputDir, "deploy", "deploy.ts"), (0, utils_1.generateDeployScript)(contractName));
|
|
107
105
|
(0, utils_1.updateProjectPackageJson)(outputDir, `fhevm-example-${exampleName}`, example.description, example.npmDependencies);
|
|
108
|
-
// Initialize git repository
|
|
109
106
|
await initGitRepo(outputDir);
|
|
110
107
|
}
|
|
111
|
-
// =============================================================================
|
|
112
|
-
// Category Project Builder
|
|
113
|
-
// =============================================================================
|
|
114
108
|
/**
|
|
115
109
|
* Creates a category project with multiple examples
|
|
116
|
-
* @param categoryName - Name of the category to create
|
|
117
|
-
* @param outputDir - Target directory for the project
|
|
118
|
-
* @param tempRepoPath - Path to cloned template repository
|
|
119
110
|
*/
|
|
120
111
|
async function createCategoryProject(categoryName, outputDir, tempRepoPath) {
|
|
121
112
|
const category = config_1.CATEGORIES[categoryName];
|
|
@@ -123,10 +114,10 @@ async function createCategoryProject(categoryName, outputDir, tempRepoPath) {
|
|
|
123
114
|
throw new Error(`Unknown category: ${categoryName}`);
|
|
124
115
|
}
|
|
125
116
|
const templateDir = path.join(tempRepoPath, utils_1.TEMPLATE_DIR_NAME);
|
|
126
|
-
//
|
|
117
|
+
// 1. Copy template and clean up
|
|
127
118
|
(0, utils_1.copyDirectoryRecursive)(templateDir, outputDir);
|
|
128
119
|
(0, utils_1.cleanupTemplate)(outputDir);
|
|
129
|
-
//
|
|
120
|
+
// 2. Download all contracts and tests
|
|
130
121
|
for (const item of category.contracts) {
|
|
131
122
|
const contractName = (0, utils_1.getContractName)(item.sol);
|
|
132
123
|
if (contractName) {
|
|
@@ -136,11 +127,16 @@ async function createCategoryProject(categoryName, outputDir, tempRepoPath) {
|
|
|
136
127
|
await (0, utils_1.downloadFileFromGitHub)(item.test, path.join(outputDir, "test", path.basename(item.test)));
|
|
137
128
|
}
|
|
138
129
|
}
|
|
139
|
-
// Collect
|
|
130
|
+
// 3. Collect and download dependencies
|
|
140
131
|
const allDependencies = new Set();
|
|
141
132
|
const allNpmDependencies = {};
|
|
142
133
|
for (const [exampleName, exampleConfig] of Object.entries(config_1.EXAMPLES)) {
|
|
143
|
-
if
|
|
134
|
+
// Check if example belongs to this category
|
|
135
|
+
const configCategoryLower = exampleConfig.category
|
|
136
|
+
.toLowerCase()
|
|
137
|
+
.replace(/\s+/g, "");
|
|
138
|
+
if (configCategoryLower === categoryName ||
|
|
139
|
+
exampleConfig.category === category.name.replace(" Examples", "")) {
|
|
144
140
|
if (exampleConfig.dependencies) {
|
|
145
141
|
exampleConfig.dependencies.forEach((dep) => allDependencies.add(dep));
|
|
146
142
|
}
|
|
@@ -149,12 +145,67 @@ async function createCategoryProject(categoryName, outputDir, tempRepoPath) {
|
|
|
149
145
|
}
|
|
150
146
|
}
|
|
151
147
|
}
|
|
152
|
-
// Download all collected dependencies
|
|
153
148
|
if (allDependencies.size > 0) {
|
|
154
149
|
await downloadDependencies(Array.from(allDependencies), outputDir);
|
|
155
150
|
}
|
|
156
|
-
//
|
|
151
|
+
// 4. Update package.json
|
|
157
152
|
(0, utils_1.updateProjectPackageJson)(outputDir, `fhevm-examples-${categoryName}`, undefined, allNpmDependencies);
|
|
158
|
-
// Initialize git repository
|
|
159
153
|
await initGitRepo(outputDir);
|
|
160
154
|
}
|
|
155
|
+
// =============================================================================
|
|
156
|
+
// Specialized Builders
|
|
157
|
+
// =============================================================================
|
|
158
|
+
/**
|
|
159
|
+
* Creates a temporary test project using LOCAL files (used by maintenance.ts)
|
|
160
|
+
*/
|
|
161
|
+
async function createLocalTestProject(exampleNames, outputDir) {
|
|
162
|
+
const rootDir = (0, utils_1.getRootDir)();
|
|
163
|
+
const templateDir = (0, utils_1.getTemplateDir)();
|
|
164
|
+
// 1. Setup base project from local template
|
|
165
|
+
(0, utils_1.copyDirectoryRecursive)(templateDir, outputDir);
|
|
166
|
+
(0, utils_1.cleanupTemplate)(outputDir);
|
|
167
|
+
const allNpmDeps = {};
|
|
168
|
+
const allContractDeps = new Set();
|
|
169
|
+
// 2. Copy local example files
|
|
170
|
+
for (const exampleName of exampleNames) {
|
|
171
|
+
const example = config_1.EXAMPLES[exampleName];
|
|
172
|
+
if (!example)
|
|
173
|
+
continue;
|
|
174
|
+
const contractPath = path.join(rootDir, example.contract);
|
|
175
|
+
const testPath = path.join(rootDir, example.test);
|
|
176
|
+
if (fs.existsSync(contractPath)) {
|
|
177
|
+
const contractName = (0, utils_1.getContractName)(example.contract);
|
|
178
|
+
if (contractName) {
|
|
179
|
+
fs.copyFileSync(contractPath, path.join(outputDir, "contracts", `${contractName}.sol`));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (fs.existsSync(testPath)) {
|
|
183
|
+
fs.copyFileSync(testPath, path.join(outputDir, "test", path.basename(example.test)));
|
|
184
|
+
}
|
|
185
|
+
if (example.dependencies) {
|
|
186
|
+
example.dependencies.forEach((dep) => allContractDeps.add(dep));
|
|
187
|
+
}
|
|
188
|
+
if (example.npmDependencies) {
|
|
189
|
+
Object.assign(allNpmDeps, example.npmDependencies);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// 3. Copy dependencies
|
|
193
|
+
for (const depPath of allContractDeps) {
|
|
194
|
+
const depFullPath = path.join(rootDir, depPath);
|
|
195
|
+
if (fs.existsSync(depFullPath)) {
|
|
196
|
+
const relativePath = depPath.replace(/^contracts\//, "");
|
|
197
|
+
const depDestPath = path.join(outputDir, "contracts", relativePath);
|
|
198
|
+
const depDestDir = path.dirname(depDestPath);
|
|
199
|
+
if (!fs.existsSync(depDestDir)) {
|
|
200
|
+
fs.mkdirSync(depDestDir, { recursive: true });
|
|
201
|
+
}
|
|
202
|
+
fs.copyFileSync(depFullPath, depDestPath);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// 4. Finalize project
|
|
206
|
+
(0, utils_1.updateProjectPackageJson)(outputDir, "fhevm-test-project", `Testing ${exampleNames.length} examples`, Object.keys(allNpmDeps).length > 0 ? allNpmDeps : undefined);
|
|
207
|
+
const typesPath = path.join(outputDir, "test", "types.ts");
|
|
208
|
+
if (!fs.existsSync(typesPath)) {
|
|
209
|
+
fs.writeFileSync(typesPath, utils_1.TEST_TYPES_CONTENT);
|
|
210
|
+
}
|
|
211
|
+
}
|
package/dist/scripts/doctor.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* FHEVM Doctor - Environment and project integrity validator
|
|
4
|
+
*
|
|
5
|
+
* Checks:
|
|
6
|
+
* - Node.js version compatibility
|
|
7
|
+
* - Git installation
|
|
8
|
+
* - Config.ts path integrity (validates all example paths)
|
|
9
|
+
*/
|
|
2
10
|
export {};
|
|
3
11
|
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../scripts/doctor.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../scripts/doctor.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG"}
|
package/dist/scripts/doctor.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* FHEVM Doctor - Environment and project integrity validator
|
|
5
|
+
*
|
|
6
|
+
* Checks:
|
|
7
|
+
* - Node.js version compatibility
|
|
8
|
+
* - Git installation
|
|
9
|
+
* - Config.ts path integrity (validates all example paths)
|
|
10
|
+
*/
|
|
3
11
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
12
|
if (k2 === undefined) k2 = k;
|
|
5
13
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Auto-Discovery Config Generator
|
|
3
|
+
* Auto-Discovery Config Generator - Automatically updates project configuration.
|
|
4
4
|
*
|
|
5
|
-
* Scans contracts/ directory and generates config.ts
|
|
6
|
-
* Extracts metadata from @notice tags and
|
|
5
|
+
* Scans the contracts/ directory and generates scripts/config.ts.
|
|
6
|
+
* Extracts metadata from @notice tags and infers category structure.
|
|
7
7
|
*/
|
|
8
8
|
export {};
|
|
9
9
|
//# sourceMappingURL=generate-config.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
/**
|
|
4
|
-
* Auto-Discovery Config Generator
|
|
4
|
+
* Auto-Discovery Config Generator - Automatically updates project configuration.
|
|
5
5
|
*
|
|
6
|
-
* Scans contracts/ directory and generates config.ts
|
|
7
|
-
* Extracts metadata from @notice tags and
|
|
6
|
+
* Scans the contracts/ directory and generates scripts/config.ts.
|
|
7
|
+
* Extracts metadata from @notice tags and infers category structure.
|
|
8
8
|
*/
|
|
9
9
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
@@ -39,10 +39,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
39
|
return result;
|
|
40
40
|
};
|
|
41
41
|
})();
|
|
42
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
43
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
44
|
+
};
|
|
42
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
46
|
const fs = __importStar(require("fs"));
|
|
44
47
|
const path = __importStar(require("path"));
|
|
45
48
|
const utils_1 = require("./utils");
|
|
49
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
46
50
|
const ROOT_DIR = path.resolve(__dirname, "..");
|
|
47
51
|
const CONTRACTS_DIR = path.join(ROOT_DIR, "contracts");
|
|
48
52
|
const TEST_DIR = path.join(ROOT_DIR, "test");
|
|
@@ -293,21 +297,25 @@ export function getDocsFileName(exampleName: string): string {
|
|
|
293
297
|
// Main
|
|
294
298
|
// =============================================================================
|
|
295
299
|
function main() {
|
|
296
|
-
utils_1.log.info(
|
|
300
|
+
utils_1.log.info(`🔍 Scanning examples in: ${picocolors_1.default.cyan("contracts/")}\n`);
|
|
297
301
|
const contracts = scanContracts();
|
|
298
|
-
|
|
302
|
+
if (contracts.length === 0) {
|
|
303
|
+
utils_1.log.error("❌ No valid contracts discovered. Check for @notice tags.");
|
|
304
|
+
process.exit(1);
|
|
305
|
+
}
|
|
306
|
+
utils_1.log.success(`✅ Found ${picocolors_1.default.bold(String(contracts.length))} contracts\n`);
|
|
299
307
|
const categoryCount = {};
|
|
300
308
|
for (const c of contracts) {
|
|
301
309
|
categoryCount[c.category] = (categoryCount[c.category] || 0) + 1;
|
|
302
310
|
}
|
|
303
|
-
utils_1.log.message("📊
|
|
311
|
+
utils_1.log.message(picocolors_1.default.bold("📊 Discovery Summary:"));
|
|
304
312
|
for (const [category, count] of Object.entries(categoryCount)) {
|
|
305
|
-
utils_1.log.message(` ${category}
|
|
313
|
+
utils_1.log.message(` ${picocolors_1.default.dim("•")} ${picocolors_1.default.yellow(category.padEnd(25))} ${picocolors_1.default.cyan(String(count).padStart(2))} examples`);
|
|
306
314
|
}
|
|
307
|
-
utils_1.log.message(
|
|
315
|
+
utils_1.log.message(`\n📝 Generating: ${picocolors_1.default.cyan(path.relative(ROOT_DIR, OUTPUT_FILE))}...`);
|
|
308
316
|
const configContent = generateConfigFile(contracts);
|
|
309
317
|
fs.writeFileSync(OUTPUT_FILE, configContent);
|
|
310
|
-
utils_1.log.success(
|
|
318
|
+
utils_1.log.success(`\n✨ Configuration updated successfully!`);
|
|
311
319
|
}
|
|
312
320
|
const isMainModule = process.argv[1]?.includes("generate-config");
|
|
313
321
|
if (isMainModule) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Documentation Generator - Creates GitBook-compatible markdown docs.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Processes FHEVM examples to produce structured documentation,
|
|
6
|
+
* including contract descriptions and automated index updates.
|
|
6
7
|
*/
|
|
7
8
|
export declare function handleInteractiveDocs(): Promise<void>;
|
|
8
9
|
export declare function handleDirect(args: string[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-docs.d.ts","sourceRoot":"","sources":["../../scripts/generate-docs.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"generate-docs.d.ts","sourceRoot":"","sources":["../../scripts/generate-docs.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAuEH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiE3D;AAMD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhE"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Documentation Generator - Creates GitBook-compatible markdown docs.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Processes FHEVM examples to produce structured documentation,
|
|
7
|
+
* including contract descriptions and automated index updates.
|
|
7
8
|
*/
|
|
8
9
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
10
|
if (k2 === undefined) k2 = k;
|
package/dist/scripts/index.js
CHANGED
|
@@ -133,10 +133,19 @@ async function getProjectConfig() {
|
|
|
133
133
|
p.cancel("Operation cancelled.");
|
|
134
134
|
return null;
|
|
135
135
|
}
|
|
136
|
+
const shouldInstall = await p.confirm({
|
|
137
|
+
message: "Install dependencies and run tests?",
|
|
138
|
+
initialValue: false,
|
|
139
|
+
});
|
|
140
|
+
if (p.isCancel(shouldInstall)) {
|
|
141
|
+
p.cancel("Operation cancelled.");
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
136
144
|
return {
|
|
137
145
|
mode: mode,
|
|
138
146
|
name,
|
|
139
147
|
outputDir: outputDir,
|
|
148
|
+
shouldInstall: shouldInstall,
|
|
140
149
|
};
|
|
141
150
|
}
|
|
142
151
|
/** Scaffolds project and shows completion message */
|
|
@@ -165,17 +174,27 @@ async function scaffoldProject(config) {
|
|
|
165
174
|
p.log.success(`📁 Created: ${picocolors_1.default.cyan(relativePath)}`);
|
|
166
175
|
if (config.mode === "single") {
|
|
167
176
|
const exampleConfig = config_1.EXAMPLES[config.name];
|
|
168
|
-
|
|
177
|
+
if (exampleConfig) {
|
|
178
|
+
p.log.info(`📝 Example: ${picocolors_1.default.yellow(exampleConfig.title)}`);
|
|
179
|
+
}
|
|
169
180
|
}
|
|
170
181
|
else {
|
|
171
182
|
const categoryConfig = config_1.CATEGORIES[config.name];
|
|
172
|
-
|
|
173
|
-
|
|
183
|
+
if (categoryConfig) {
|
|
184
|
+
p.log.info(`📦 Category: ${picocolors_1.default.yellow(categoryConfig.name)}`);
|
|
185
|
+
p.log.info(`📄 Contracts: ${picocolors_1.default.green(String(categoryConfig.contracts.length))}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (config.shouldInstall) {
|
|
189
|
+
p.log.message("");
|
|
190
|
+
await (0, ui_1.runInstallAndTest)(resolvedOutput);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
p.note(`${picocolors_1.default.dim("$")} cd ${relativePath}\n${picocolors_1.default.dim("$")} npm install\n${picocolors_1.default.dim("$")} npm run compile\n${picocolors_1.default.dim("$")} npm run test`, "🚀 Quick Start");
|
|
174
194
|
}
|
|
175
|
-
await (0, ui_1.askInstallAndTest)(resolvedOutput, relativePath);
|
|
176
195
|
}
|
|
177
196
|
catch (error) {
|
|
178
|
-
s.stop("Failed to create project");
|
|
197
|
+
s.stop(picocolors_1.default.red("Failed to create project"));
|
|
179
198
|
p.log.error(error instanceof Error ? error.message : String(error));
|
|
180
199
|
process.exit(1);
|
|
181
200
|
}
|
|
@@ -195,54 +214,6 @@ async function runInteractiveMode() {
|
|
|
195
214
|
return;
|
|
196
215
|
await scaffoldProject(config);
|
|
197
216
|
}
|
|
198
|
-
// =============================================================================
|
|
199
|
-
// QUICK MODE (CLI Arguments)
|
|
200
|
-
// =============================================================================
|
|
201
|
-
function showHelp() {
|
|
202
|
-
console.log(`
|
|
203
|
-
${picocolors_1.default.bgCyan(picocolors_1.default.black(picocolors_1.default.bold(" 🔐 create-fhevm-example ")))}
|
|
204
|
-
${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
|
|
205
|
-
|
|
206
|
-
${picocolors_1.default.cyan(picocolors_1.default.bold("📋 USAGE"))}
|
|
207
|
-
|
|
208
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.dim("→")} Interactive mode ${picocolors_1.default.yellow("(recommended)")}
|
|
209
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Create single example
|
|
210
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Create category project
|
|
211
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--add")} ${picocolors_1.default.dim("→")} Add to existing project
|
|
212
|
-
|
|
213
|
-
${picocolors_1.default.cyan(picocolors_1.default.bold("⚙️ OPTIONS"))}
|
|
214
|
-
|
|
215
|
-
${picocolors_1.default.green("--example")} ${picocolors_1.default.dim("<name>")} Create a single example project
|
|
216
|
-
${picocolors_1.default.green("--category")} ${picocolors_1.default.dim("<name>")} Create a category project
|
|
217
|
-
${picocolors_1.default.green("--add")} Add FHEVM to existing Hardhat project
|
|
218
|
-
${picocolors_1.default.green("--target")} ${picocolors_1.default.dim("<dir>")} Target directory for --add mode
|
|
219
|
-
${picocolors_1.default.green("--output")} ${picocolors_1.default.dim("<dir>")} Output directory
|
|
220
|
-
${picocolors_1.default.green("--install")} Auto-install dependencies
|
|
221
|
-
${picocolors_1.default.green("--test")} Auto-run tests (requires --install)
|
|
222
|
-
${picocolors_1.default.green("--help")}${picocolors_1.default.dim(", -h")} Show this help message
|
|
223
|
-
|
|
224
|
-
${picocolors_1.default.cyan(picocolors_1.default.bold("⚡ EXAMPLES"))}
|
|
225
|
-
|
|
226
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("fhe-counter")}
|
|
227
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("basic")} ${picocolors_1.default.green("--output")} ${picocolors_1.default.blue("./my-project")}
|
|
228
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--add")}
|
|
229
|
-
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("fhe-counter")} ${picocolors_1.default.green("--install")} ${picocolors_1.default.green("--test")}
|
|
230
|
-
|
|
231
|
-
${picocolors_1.default.cyan(picocolors_1.default.bold("📦 AVAILABLE EXAMPLES"))}
|
|
232
|
-
|
|
233
|
-
${picocolors_1.default.dim(Object.keys(config_1.EXAMPLES).slice(0, 10).join(", "))}
|
|
234
|
-
${picocolors_1.default.dim("...")} and ${picocolors_1.default.yellow(String(Object.keys(config_1.EXAMPLES).length - 10))} more
|
|
235
|
-
|
|
236
|
-
${picocolors_1.default.cyan(picocolors_1.default.bold("📁 AVAILABLE CATEGORIES"))}
|
|
237
|
-
|
|
238
|
-
${Object.keys(config_1.CATEGORIES)
|
|
239
|
-
.map((c) => picocolors_1.default.yellow(c))
|
|
240
|
-
.join(", ")}
|
|
241
|
-
|
|
242
|
-
${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
|
|
243
|
-
${picocolors_1.default.dim("📚 Documentation:")} ${picocolors_1.default.blue("https://github.com/NecipAkgz/fhevm-example-factory")}
|
|
244
|
-
`);
|
|
245
|
-
}
|
|
246
217
|
function parseArgs(args) {
|
|
247
218
|
const parsed = {};
|
|
248
219
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -313,25 +284,30 @@ async function runDirectMode(args) {
|
|
|
313
284
|
}
|
|
314
285
|
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "fhevm-"));
|
|
315
286
|
try {
|
|
316
|
-
utils_1.log.info(
|
|
287
|
+
utils_1.log.info(`\n🚀 Creating ${mode}: ${picocolors_1.default.yellow(name)}`);
|
|
288
|
+
utils_1.log.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
317
289
|
utils_1.log.dim("Downloading template...");
|
|
318
290
|
const tempRepoPath = await (0, utils_1.cloneTemplate)(tempDir);
|
|
319
291
|
utils_1.log.dim("Initializing submodules...");
|
|
320
292
|
await (0, utils_1.initSubmodule)(tempRepoPath);
|
|
321
|
-
utils_1.log.dim("
|
|
293
|
+
utils_1.log.dim("Building project...");
|
|
322
294
|
if (mode === "example") {
|
|
323
295
|
await (0, builders_1.createSingleExample)(name, resolved, tempRepoPath);
|
|
324
296
|
}
|
|
325
297
|
else {
|
|
326
298
|
await (0, builders_1.createCategoryProject)(name, resolved, tempRepoPath);
|
|
327
299
|
}
|
|
328
|
-
utils_1.log.success(
|
|
300
|
+
utils_1.log.success(`\n✨ Successfully created: ${picocolors_1.default.cyan(output)}`);
|
|
329
301
|
if (shouldInstall) {
|
|
330
|
-
utils_1.log.dim("
|
|
302
|
+
utils_1.log.dim("Installing dependencies and running tests...");
|
|
331
303
|
await (0, ui_1.runInstallAndTest)(resolved);
|
|
332
304
|
}
|
|
333
305
|
else {
|
|
334
|
-
utils_1.log.dim(
|
|
306
|
+
utils_1.log.message(picocolors_1.default.dim("\nNext steps:"));
|
|
307
|
+
utils_1.log.message(` ${picocolors_1.default.cyan("cd")} ${output}`);
|
|
308
|
+
utils_1.log.message(` ${picocolors_1.default.cyan("npm install")}`);
|
|
309
|
+
utils_1.log.message(` ${picocolors_1.default.cyan("npm run compile")}`);
|
|
310
|
+
utils_1.log.message(` ${picocolors_1.default.cyan("npm run test")}`);
|
|
335
311
|
}
|
|
336
312
|
}
|
|
337
313
|
catch (error) {
|
|
@@ -344,6 +320,54 @@ async function runDirectMode(args) {
|
|
|
344
320
|
}
|
|
345
321
|
}
|
|
346
322
|
// =============================================================================
|
|
323
|
+
// QUICK MODE (CLI Arguments)
|
|
324
|
+
// =============================================================================
|
|
325
|
+
function showHelp() {
|
|
326
|
+
console.log(`
|
|
327
|
+
${picocolors_1.default.bgCyan(picocolors_1.default.black(picocolors_1.default.bold(" 🔐 create-fhevm-example ")))}
|
|
328
|
+
${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
|
|
329
|
+
|
|
330
|
+
${picocolors_1.default.cyan(picocolors_1.default.bold("📋 USAGE"))}
|
|
331
|
+
|
|
332
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.dim("→")} Interactive mode ${picocolors_1.default.yellow("(recommended)")}
|
|
333
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Create single example
|
|
334
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("<name>")} ${picocolors_1.default.dim("→")} Create category project
|
|
335
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--add")} ${picocolors_1.default.dim("→")} Add to existing project
|
|
336
|
+
|
|
337
|
+
${picocolors_1.default.cyan(picocolors_1.default.bold("⚙️ OPTIONS"))}
|
|
338
|
+
|
|
339
|
+
${picocolors_1.default.green("--example")} ${picocolors_1.default.dim("<name>")} Create a single example project
|
|
340
|
+
${picocolors_1.default.green("--category")} ${picocolors_1.default.dim("<name>")} Create a category project
|
|
341
|
+
${picocolors_1.default.green("--add")} Add FHEVM to existing Hardhat project
|
|
342
|
+
${picocolors_1.default.green("--target")} ${picocolors_1.default.dim("<dir>")} Target directory for --add mode
|
|
343
|
+
${picocolors_1.default.green("--output")} ${picocolors_1.default.dim("<dir>")} Output directory
|
|
344
|
+
${picocolors_1.default.green("--install")} Auto-install dependencies
|
|
345
|
+
${picocolors_1.default.green("--test")} Auto-run tests (requires --install)
|
|
346
|
+
${picocolors_1.default.green("--help")}${picocolors_1.default.dim(", -h")} Show this help message
|
|
347
|
+
|
|
348
|
+
${picocolors_1.default.cyan(picocolors_1.default.bold("⚡ EXAMPLES"))}
|
|
349
|
+
|
|
350
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("fhe-counter")}
|
|
351
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--category")} ${picocolors_1.default.yellow("basic")} ${picocolors_1.default.green("--output")} ${picocolors_1.default.blue("./my-project")}
|
|
352
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--add")}
|
|
353
|
+
${picocolors_1.default.dim("$")} ${picocolors_1.default.white("npx create-fhevm-example")} ${picocolors_1.default.green("--example")} ${picocolors_1.default.yellow("fhe-counter")} ${picocolors_1.default.green("--install")} ${picocolors_1.default.green("--test")}
|
|
354
|
+
|
|
355
|
+
${picocolors_1.default.cyan(picocolors_1.default.bold("📦 AVAILABLE EXAMPLES"))}
|
|
356
|
+
|
|
357
|
+
${picocolors_1.default.dim(Object.keys(config_1.EXAMPLES).slice(0, 10).join(", "))}
|
|
358
|
+
${picocolors_1.default.dim("...")} and ${picocolors_1.default.yellow(String(Object.keys(config_1.EXAMPLES).length - 10))} more
|
|
359
|
+
|
|
360
|
+
${picocolors_1.default.cyan(picocolors_1.default.bold("📁 AVAILABLE CATEGORIES"))}
|
|
361
|
+
|
|
362
|
+
${Object.keys(config_1.CATEGORIES)
|
|
363
|
+
.map((c) => picocolors_1.default.yellow(c))
|
|
364
|
+
.join(", ")}
|
|
365
|
+
|
|
366
|
+
${picocolors_1.default.dim("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")}
|
|
367
|
+
${picocolors_1.default.dim("📚 Documentation:")} ${picocolors_1.default.blue("https://github.com/NecipAkgz/fhevm-example-factory")}
|
|
368
|
+
`);
|
|
369
|
+
}
|
|
370
|
+
// =============================================================================
|
|
347
371
|
// MAIN ENTRY POINT
|
|
348
372
|
// =============================================================================
|
|
349
373
|
async function main() {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Maintenance Tools - Utilities for project maintenance and testing.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Includes the test-all runner which allows for efficient testing
|
|
6
|
+
* of multiple examples in a temporary workspace.
|
|
6
7
|
*
|
|
7
8
|
* Usage:
|
|
8
|
-
* npm run test:all
|
|
9
|
-
* npm run test:all fhe-counter,fhe-add
|
|
9
|
+
* npm run test:all # Interactive selection
|
|
10
|
+
* npm run test:all fhe-counter,fhe-add # Direct CLI
|
|
10
11
|
*/
|
|
11
12
|
export declare function testAllExamples(cliExamples?: string[]): Promise<void>;
|
|
12
13
|
//# sourceMappingURL=maintenance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../scripts/maintenance.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"maintenance.d.ts","sourceRoot":"","sources":["../../scripts/maintenance.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAwNH,wBAAsB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC3E"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Maintenance Tools - Utilities for project maintenance and testing.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Includes the test-all runner which allows for efficient testing
|
|
7
|
+
* of multiple examples in a temporary workspace.
|
|
7
8
|
*
|
|
8
9
|
* Usage:
|
|
9
|
-
* npm run test:all
|
|
10
|
-
* npm run test:all fhe-counter,fhe-add
|
|
10
|
+
* npm run test:all # Interactive selection
|
|
11
|
+
* npm run test:all fhe-counter,fhe-add # Direct CLI
|
|
11
12
|
*/
|
|
12
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
14
|
if (k2 === undefined) k2 = k;
|
|
@@ -53,57 +54,7 @@ const fs = __importStar(require("fs"));
|
|
|
53
54
|
const path = __importStar(require("path"));
|
|
54
55
|
const config_1 = require("./config");
|
|
55
56
|
const utils_1 = require("./utils");
|
|
56
|
-
|
|
57
|
-
// Project Builder
|
|
58
|
-
// =============================================================================
|
|
59
|
-
async function createTestProject(exampleNames, outputDir) {
|
|
60
|
-
const rootDir = (0, utils_1.getRootDir)();
|
|
61
|
-
const templateDir = (0, utils_1.getTemplateDir)();
|
|
62
|
-
(0, utils_1.copyDirectoryRecursive)(templateDir, outputDir);
|
|
63
|
-
(0, utils_1.cleanupTemplate)(outputDir);
|
|
64
|
-
const allNpmDeps = {};
|
|
65
|
-
const allContractDeps = new Set();
|
|
66
|
-
for (const exampleName of exampleNames) {
|
|
67
|
-
const example = config_1.EXAMPLES[exampleName];
|
|
68
|
-
if (!example)
|
|
69
|
-
continue;
|
|
70
|
-
const contractPath = path.join(rootDir, example.contract);
|
|
71
|
-
const testPath = path.join(rootDir, example.test);
|
|
72
|
-
if (fs.existsSync(contractPath)) {
|
|
73
|
-
const contractName = (0, utils_1.getContractName)(example.contract);
|
|
74
|
-
if (contractName) {
|
|
75
|
-
fs.copyFileSync(contractPath, path.join(outputDir, "contracts", `${contractName}.sol`));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (fs.existsSync(testPath)) {
|
|
79
|
-
fs.copyFileSync(testPath, path.join(outputDir, "test", path.basename(example.test)));
|
|
80
|
-
}
|
|
81
|
-
if (example.dependencies) {
|
|
82
|
-
example.dependencies.forEach((dep) => allContractDeps.add(dep));
|
|
83
|
-
}
|
|
84
|
-
if (example.npmDependencies) {
|
|
85
|
-
Object.assign(allNpmDeps, example.npmDependencies);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
for (const depPath of allContractDeps) {
|
|
89
|
-
const depFullPath = path.join(rootDir, depPath);
|
|
90
|
-
if (fs.existsSync(depFullPath)) {
|
|
91
|
-
const relativePath = depPath.replace(/^contracts\//, "");
|
|
92
|
-
const depDestPath = path.join(outputDir, "contracts", relativePath);
|
|
93
|
-
const depDestDir = path.dirname(depDestPath);
|
|
94
|
-
if (!fs.existsSync(depDestDir)) {
|
|
95
|
-
fs.mkdirSync(depDestDir, { recursive: true });
|
|
96
|
-
}
|
|
97
|
-
fs.copyFileSync(depFullPath, depDestPath);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// Update package.json using shared utility
|
|
101
|
-
(0, utils_1.updateProjectPackageJson)(outputDir, "fhevm-test-project", `Testing ${exampleNames.length} examples`, Object.keys(allNpmDeps).length > 0 ? allNpmDeps : undefined);
|
|
102
|
-
const typesPath = path.join(outputDir, "test", "types.ts");
|
|
103
|
-
if (!fs.existsSync(typesPath)) {
|
|
104
|
-
fs.writeFileSync(typesPath, utils_1.TEST_TYPES_CONTENT);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
57
|
+
const builders_1 = require("./builders");
|
|
107
58
|
// =============================================================================
|
|
108
59
|
// Example Selection
|
|
109
60
|
// =============================================================================
|
|
@@ -266,7 +217,7 @@ async function testAllExamples(cliExamples) {
|
|
|
266
217
|
try {
|
|
267
218
|
const s = p.spinner();
|
|
268
219
|
s.start("Setting up test project...");
|
|
269
|
-
await
|
|
220
|
+
await (0, builders_1.createLocalTestProject)(examplesToTest, tempDir);
|
|
270
221
|
s.stop(picocolors_1.default.green("✓ Project ready"));
|
|
271
222
|
summary = await runTestPipeline(tempDir, examplesToTest.length);
|
|
272
223
|
}
|
package/dist/scripts/ui.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* User Interface - Prompts
|
|
2
|
+
* User Interface - CLI Prompts and Interaction Logic.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Provides centralized components for user input, selection menus,
|
|
5
|
+
* and standard command execution feedback for the CLI.
|
|
5
6
|
*/
|
|
6
7
|
/**
|
|
7
8
|
* Counts how many examples exist in each category
|
|
@@ -23,12 +24,4 @@ export declare function promptSelectCategoryProject(): Promise<string | symbol>;
|
|
|
23
24
|
* Runs npm install, compile, and test in the project directory
|
|
24
25
|
*/
|
|
25
26
|
export declare function runInstallAndTest(projectPath: string): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Shows quick start commands for the created project
|
|
28
|
-
*/
|
|
29
|
-
export declare function showQuickStart(relativePath: string): void;
|
|
30
|
-
/**
|
|
31
|
-
* Asks user if they want to install and test
|
|
32
|
-
*/
|
|
33
|
-
export declare function askInstallAndTest(resolvedOutput: string, relativePath: string): Promise<void>;
|
|
34
27
|
//# sourceMappingURL=ui.d.ts.map
|
package/dist/scripts/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../scripts/ui.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../scripts/ui.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMjE;AAMD;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAmBrE;AAED;;GAEG;AACH,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAe1B;AAED;;GAEG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CAS5E;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiD1E"}
|
package/dist/scripts/ui.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* User Interface - Prompts
|
|
3
|
+
* User Interface - CLI Prompts and Interaction Logic.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Provides centralized components for user input, selection menus,
|
|
6
|
+
* and standard command execution feedback for the CLI.
|
|
6
7
|
*/
|
|
7
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
9
|
if (k2 === undefined) k2 = k;
|
|
@@ -46,8 +47,6 @@ exports.promptSelectCategory = promptSelectCategory;
|
|
|
46
47
|
exports.promptSelectExampleFromCategory = promptSelectExampleFromCategory;
|
|
47
48
|
exports.promptSelectCategoryProject = promptSelectCategoryProject;
|
|
48
49
|
exports.runInstallAndTest = runInstallAndTest;
|
|
49
|
-
exports.showQuickStart = showQuickStart;
|
|
50
|
-
exports.askInstallAndTest = askInstallAndTest;
|
|
51
50
|
const p = __importStar(require("@clack/prompts"));
|
|
52
51
|
const picocolors_1 = __importDefault(require("picocolors"));
|
|
53
52
|
const config_1 = require("./config");
|
|
@@ -169,29 +168,3 @@ async function runInstallAndTest(projectPath) {
|
|
|
169
168
|
}
|
|
170
169
|
p.log.success(picocolors_1.default.green("🔐 All encryption tests passed!"));
|
|
171
170
|
}
|
|
172
|
-
/**
|
|
173
|
-
* Shows quick start commands for the created project
|
|
174
|
-
*/
|
|
175
|
-
function showQuickStart(relativePath) {
|
|
176
|
-
p.note(`${picocolors_1.default.dim("$")} cd ${relativePath}\n${picocolors_1.default.dim("$")} npm install\n${picocolors_1.default.dim("$")} npm run compile\n${picocolors_1.default.dim("$")} npm run test`, "🚀 Quick Start");
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Asks user if they want to install and test
|
|
180
|
-
*/
|
|
181
|
-
async function askInstallAndTest(resolvedOutput, relativePath) {
|
|
182
|
-
const shouldInstall = await p.confirm({
|
|
183
|
-
message: "Install dependencies and run tests?",
|
|
184
|
-
initialValue: false,
|
|
185
|
-
});
|
|
186
|
-
if (p.isCancel(shouldInstall)) {
|
|
187
|
-
showQuickStart(relativePath);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (shouldInstall) {
|
|
191
|
-
p.log.message("");
|
|
192
|
-
await runInstallAndTest(resolvedOutput);
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
showQuickStart(relativePath);
|
|
196
|
-
}
|
|
197
|
-
}
|
package/dist/scripts/utils.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Shared Utilities - Helper functions for the FHEVM Example Factory.
|
|
3
|
+
*
|
|
4
|
+
* Contains common logic for file system operations, string formatting,
|
|
5
|
+
* error handling, and terminal logging used throughout the project.
|
|
3
6
|
*/
|
|
4
7
|
export type ProjectMode = "single" | "category";
|
|
5
8
|
export declare const CATEGORY_ICON = "\uD83D\uDCC1";
|
|
@@ -45,30 +48,22 @@ export declare const log: {
|
|
|
45
48
|
export declare function handleError(error: unknown, exitCode?: number): never;
|
|
46
49
|
/** Resolves root directory of the project */
|
|
47
50
|
export declare function getRootDir(): string;
|
|
51
|
+
/** Resolves template directory path */
|
|
48
52
|
export declare function getTemplateDir(): string;
|
|
49
|
-
/** Extracts contract name from file path or content */
|
|
50
|
-
export declare function getContractName(contractPathOrContent: string): string | null;
|
|
51
53
|
/** Copies directory recursively, excluding specified directories */
|
|
52
54
|
export declare function copyDirectoryRecursive(source: string, destination: string, excludeDirs?: string[]): void;
|
|
53
55
|
export declare function toKebabCase(str: string): string;
|
|
54
56
|
export declare function contractNameToExampleName(contractName: string): string;
|
|
55
57
|
export declare function contractNameToTitle(contractName: string): string;
|
|
56
58
|
export declare function formatCategoryName(folderName: string): string;
|
|
59
|
+
export declare function getContractName(contractPathOrContent: string): string | null;
|
|
57
60
|
export declare function validateExample(name: string): void;
|
|
58
61
|
export declare function validateCategory(name: string): void;
|
|
59
62
|
export declare function validateDirectoryNotExists(dirPath: string): void;
|
|
60
63
|
export declare function cleanupTemplate(outputDir: string): void;
|
|
61
64
|
export declare function generateDeployScript(contractName: string): string;
|
|
62
65
|
export declare function generateGitBookMarkdown(description: string, contractContent: string, testContent: string, contractName: string, testFileName: string): string;
|
|
63
|
-
/** Downloads a file from GitHub repository */
|
|
64
|
-
export declare function downloadFileFromGitHub(filePath: string, outputPath: string): Promise<void>;
|
|
65
|
-
/** Clones the template repository to temp directory */
|
|
66
|
-
export declare function cloneTemplate(tempDir: string): Promise<string>;
|
|
67
|
-
/** Initializes git submodule for the template */
|
|
68
|
-
export declare function initSubmodule(repoPath: string): Promise<void>;
|
|
69
|
-
/** Updates package.json with project name, description, and npm dependencies */
|
|
70
66
|
export declare function updateProjectPackageJson(outputDir: string, projectName: string, description?: string, npmDependencies?: Record<string, string>): void;
|
|
71
|
-
/** Executes a command and returns output */
|
|
72
67
|
export declare function runCommand(cmd: string, args: string[], cwd: string): Promise<string>;
|
|
73
68
|
export declare function runCommandWithStatus(cmd: string, args: string[], cwd: string): Promise<{
|
|
74
69
|
success: boolean;
|
|
@@ -76,4 +71,16 @@ export declare function runCommandWithStatus(cmd: string, args: string[], cwd: s
|
|
|
76
71
|
}>;
|
|
77
72
|
export declare function extractTestResults(output: string): string | null;
|
|
78
73
|
export declare function extractErrorMessage(output: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Downloads a file from GitHub repository
|
|
76
|
+
*/
|
|
77
|
+
export declare function downloadFileFromGitHub(filePath: string, outputPath: string): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Clones the template repository to temp directory
|
|
80
|
+
*/
|
|
81
|
+
export declare function cloneTemplate(tempDir: string): Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Initializes git submodule for the template
|
|
84
|
+
*/
|
|
85
|
+
export declare function initSubmodule(repoPath: string): Promise<void>;
|
|
79
86
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../scripts/utils.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../scripts/utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEhD,eAAO,MAAM,aAAa,iBAAO,CAAC;AAElC,qDAAqD;AACrD,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,gDAAgD;AAChD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,mDAAmD;AACnD,eAAO,MAAM,YAAY,UAQxB,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,kBAAkB;;;;;;;;;CAS9B,CAAC;AAEF,eAAO,MAAM,cAAc,UAQ1B,CAAC;AAEF,eAAO,MAAM,kBAAkB,yPAS9B,CAAC;AAEF,eAAO,MAAM,cAAc;;;4BAGD,MAAM;6BACL,MAAM;uBACZ,MAAM;;;;CAI1B,CAAC;AAMF,eAAO,MAAM,GAAG;mBACC,MAAM;iBACR,MAAM;gBACP,MAAM;eACP,MAAM;mBACF,MAAM;CACtB,CAAC;AAEF;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAAI,GAAG,KAAK,CAI/D;AAMD,6CAA6C;AAC7C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,uCAAuC;AACvC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAM,EAAiB,GACnC,IAAI,CAoBN;AAMD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAK7D;AAED,wBAAgB,eAAe,CAAC,qBAAqB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqB5E;AAMD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIlD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAInD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIhE;AAMD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAiDvD;AAED,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAkCjE;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,GACnB,MAAM,CA2BR;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACvC,IAAI,CAiBN;AAKD,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA2B/C;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAchE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA4B1D;AAMD;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCpE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BnE"}
|
package/dist/scripts/utils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Shared Utilities - Helper functions for the FHEVM Example Factory.
|
|
4
|
+
*
|
|
5
|
+
* Contains common logic for file system operations, string formatting,
|
|
6
|
+
* error handling, and terminal logging used throughout the project.
|
|
4
7
|
*/
|
|
5
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
9
|
if (k2 === undefined) k2 = k;
|
|
@@ -43,26 +46,26 @@ exports.log = exports.ERROR_MESSAGES = exports.TEST_TYPES_CONTENT = exports.CATE
|
|
|
43
46
|
exports.handleError = handleError;
|
|
44
47
|
exports.getRootDir = getRootDir;
|
|
45
48
|
exports.getTemplateDir = getTemplateDir;
|
|
46
|
-
exports.getContractName = getContractName;
|
|
47
49
|
exports.copyDirectoryRecursive = copyDirectoryRecursive;
|
|
48
50
|
exports.toKebabCase = toKebabCase;
|
|
49
51
|
exports.contractNameToExampleName = contractNameToExampleName;
|
|
50
52
|
exports.contractNameToTitle = contractNameToTitle;
|
|
51
53
|
exports.formatCategoryName = formatCategoryName;
|
|
54
|
+
exports.getContractName = getContractName;
|
|
52
55
|
exports.validateExample = validateExample;
|
|
53
56
|
exports.validateCategory = validateCategory;
|
|
54
57
|
exports.validateDirectoryNotExists = validateDirectoryNotExists;
|
|
55
58
|
exports.cleanupTemplate = cleanupTemplate;
|
|
56
59
|
exports.generateDeployScript = generateDeployScript;
|
|
57
60
|
exports.generateGitBookMarkdown = generateGitBookMarkdown;
|
|
58
|
-
exports.downloadFileFromGitHub = downloadFileFromGitHub;
|
|
59
|
-
exports.cloneTemplate = cloneTemplate;
|
|
60
|
-
exports.initSubmodule = initSubmodule;
|
|
61
61
|
exports.updateProjectPackageJson = updateProjectPackageJson;
|
|
62
62
|
exports.runCommand = runCommand;
|
|
63
63
|
exports.runCommandWithStatus = runCommandWithStatus;
|
|
64
64
|
exports.extractTestResults = extractTestResults;
|
|
65
65
|
exports.extractErrorMessage = extractErrorMessage;
|
|
66
|
+
exports.downloadFileFromGitHub = downloadFileFromGitHub;
|
|
67
|
+
exports.cloneTemplate = cloneTemplate;
|
|
68
|
+
exports.initSubmodule = initSubmodule;
|
|
66
69
|
const fs = __importStar(require("fs"));
|
|
67
70
|
const path = __importStar(require("path"));
|
|
68
71
|
const child_process_1 = require("child_process");
|
|
@@ -148,29 +151,10 @@ function handleError(error, exitCode = 1) {
|
|
|
148
151
|
function getRootDir() {
|
|
149
152
|
return path.resolve(__dirname, "..");
|
|
150
153
|
}
|
|
154
|
+
/** Resolves template directory path */
|
|
151
155
|
function getTemplateDir() {
|
|
152
156
|
return path.join(getRootDir(), exports.TEMPLATE_DIR_NAME);
|
|
153
157
|
}
|
|
154
|
-
/** Extracts contract name from file path or content */
|
|
155
|
-
function getContractName(contractPathOrContent) {
|
|
156
|
-
let content;
|
|
157
|
-
if (contractPathOrContent.includes("contract ") ||
|
|
158
|
-
contractPathOrContent.includes("pragma solidity")) {
|
|
159
|
-
content = contractPathOrContent;
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
const fullPath = contractPathOrContent.startsWith("/")
|
|
163
|
-
? contractPathOrContent
|
|
164
|
-
: path.join(getRootDir(), contractPathOrContent);
|
|
165
|
-
if (!fs.existsSync(fullPath)) {
|
|
166
|
-
const match = contractPathOrContent.match(/([^/]+)\.sol$/);
|
|
167
|
-
return match ? match[1] : null;
|
|
168
|
-
}
|
|
169
|
-
content = fs.readFileSync(fullPath, "utf-8");
|
|
170
|
-
}
|
|
171
|
-
const match = content.match(/^\s*contract\s+(\w+)(?:\s+is\s+|\s*\{)/m);
|
|
172
|
-
return match ? match[1] : null;
|
|
173
|
-
}
|
|
174
158
|
/** Copies directory recursively, excluding specified directories */
|
|
175
159
|
function copyDirectoryRecursive(source, destination, excludeDirs = exports.EXCLUDE_DIRS) {
|
|
176
160
|
if (!fs.existsSync(destination)) {
|
|
@@ -217,6 +201,25 @@ function formatCategoryName(folderName) {
|
|
|
217
201
|
.replace(/-/g, " ")
|
|
218
202
|
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
219
203
|
}
|
|
204
|
+
function getContractName(contractPathOrContent) {
|
|
205
|
+
let content;
|
|
206
|
+
if (contractPathOrContent.includes("contract ") ||
|
|
207
|
+
contractPathOrContent.includes("pragma solidity")) {
|
|
208
|
+
content = contractPathOrContent;
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
const fullPath = contractPathOrContent.startsWith("/")
|
|
212
|
+
? contractPathOrContent
|
|
213
|
+
: path.join(getRootDir(), contractPathOrContent);
|
|
214
|
+
if (!fs.existsSync(fullPath)) {
|
|
215
|
+
const match = contractPathOrContent.match(/([^/]+)\.sol$/);
|
|
216
|
+
return match ? match[1] : null;
|
|
217
|
+
}
|
|
218
|
+
content = fs.readFileSync(fullPath, "utf-8");
|
|
219
|
+
}
|
|
220
|
+
const match = content.match(/^\s*contract\s+(\w+)(?:\s+is\s+|\s*\{)/m);
|
|
221
|
+
return match ? match[1] : null;
|
|
222
|
+
}
|
|
220
223
|
// =============================================================================
|
|
221
224
|
// Validation Functions
|
|
222
225
|
// =============================================================================
|
|
@@ -236,13 +239,17 @@ function validateDirectoryNotExists(dirPath) {
|
|
|
236
239
|
}
|
|
237
240
|
}
|
|
238
241
|
// =============================================================================
|
|
239
|
-
// Template Utilities
|
|
242
|
+
// Template & Scaffolding Utilities
|
|
240
243
|
// =============================================================================
|
|
241
244
|
function cleanupTemplate(outputDir) {
|
|
242
245
|
const gitDir = path.join(outputDir, ".git");
|
|
243
246
|
if (fs.existsSync(gitDir)) {
|
|
244
247
|
fs.rmSync(gitDir, { recursive: true, force: true });
|
|
245
248
|
}
|
|
249
|
+
const githubDir = path.join(outputDir, ".github");
|
|
250
|
+
if (fs.existsSync(githubDir)) {
|
|
251
|
+
fs.rmSync(githubDir, { recursive: true, force: true });
|
|
252
|
+
}
|
|
246
253
|
const templateContract = path.join(outputDir, "contracts", "FHECounter.sol");
|
|
247
254
|
if (fs.existsSync(templateContract)) {
|
|
248
255
|
fs.unlinkSync(templateContract);
|
|
@@ -279,13 +286,26 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
|
|
|
279
286
|
const { deployer } = await hre.getNamedAccounts();
|
|
280
287
|
const { deploy } = hre.deployments;
|
|
281
288
|
|
|
289
|
+
console.log("\\n🚀 Deploying ${contractName}...");
|
|
290
|
+
console.log(\`📍 Network: \${hre.network.name}\`);
|
|
291
|
+
console.log(\`👤 Deployer: \${deployer}\\n\`);
|
|
292
|
+
|
|
282
293
|
const deployed = await deploy("${contractName}", {
|
|
283
294
|
from: deployer,
|
|
284
295
|
args: [],
|
|
285
296
|
log: true,
|
|
286
297
|
});
|
|
287
298
|
|
|
288
|
-
console.log(
|
|
299
|
+
console.log("\\n✅ Deployment Complete!");
|
|
300
|
+
console.log(\`📄 Contract: ${contractName}\`);
|
|
301
|
+
console.log(\`📍 Contract Address: \${deployed.address}\`);
|
|
302
|
+
|
|
303
|
+
if (deployed.newlyDeployed) {
|
|
304
|
+
console.log(\`⛽ Gas Used: \${deployed.receipt?.gasUsed}\`);
|
|
305
|
+
} else {
|
|
306
|
+
console.log("ℹ️ Contract was already deployed");
|
|
307
|
+
}
|
|
308
|
+
console.log("");
|
|
289
309
|
};
|
|
290
310
|
|
|
291
311
|
export default func;
|
|
@@ -315,84 +335,6 @@ function generateGitBookMarkdown(description, contractContent, testContent, cont
|
|
|
315
335
|
markdown += `{% endtabs %}\n`;
|
|
316
336
|
return markdown;
|
|
317
337
|
}
|
|
318
|
-
// =============================================================================
|
|
319
|
-
// GitHub Repository Utilities
|
|
320
|
-
// =============================================================================
|
|
321
|
-
/** Downloads a file from GitHub repository */
|
|
322
|
-
async function downloadFileFromGitHub(filePath, outputPath) {
|
|
323
|
-
const urlParts = config_1.REPO_URL.replace("https://github.com/", "").split("/");
|
|
324
|
-
const owner = urlParts[0];
|
|
325
|
-
const repo = urlParts[1];
|
|
326
|
-
const url = `https://raw.githubusercontent.com/${owner}/${repo}/${config_1.REPO_BRANCH}/${filePath}`;
|
|
327
|
-
const response = await fetch(url);
|
|
328
|
-
if (!response.ok) {
|
|
329
|
-
throw new Error(`Failed to download ${filePath}: ${response.statusText}`);
|
|
330
|
-
}
|
|
331
|
-
const content = await response.text();
|
|
332
|
-
const dir = path.dirname(outputPath);
|
|
333
|
-
if (!fs.existsSync(dir)) {
|
|
334
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
335
|
-
}
|
|
336
|
-
fs.writeFileSync(outputPath, content);
|
|
337
|
-
}
|
|
338
|
-
/** Clones the template repository to temp directory */
|
|
339
|
-
async function cloneTemplate(tempDir) {
|
|
340
|
-
const templatePath = path.join(tempDir, "template");
|
|
341
|
-
return new Promise((resolve, reject) => {
|
|
342
|
-
const cloneUrl = `${config_1.REPO_URL}.git`;
|
|
343
|
-
const args = [
|
|
344
|
-
"clone",
|
|
345
|
-
"--depth=1",
|
|
346
|
-
"--branch",
|
|
347
|
-
config_1.REPO_BRANCH,
|
|
348
|
-
"--single-branch",
|
|
349
|
-
cloneUrl,
|
|
350
|
-
templatePath,
|
|
351
|
-
];
|
|
352
|
-
const child = (0, child_process_1.spawn)("git", args, {
|
|
353
|
-
stdio: "pipe",
|
|
354
|
-
});
|
|
355
|
-
let stderr = "";
|
|
356
|
-
child.stderr?.on("data", (data) => {
|
|
357
|
-
stderr += data.toString();
|
|
358
|
-
});
|
|
359
|
-
child.on("close", (code) => {
|
|
360
|
-
if (code === 0) {
|
|
361
|
-
resolve(templatePath);
|
|
362
|
-
}
|
|
363
|
-
else {
|
|
364
|
-
reject(new Error(`Git clone failed: ${stderr}`));
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
child.on("error", reject);
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
/** Initializes git submodule for the template */
|
|
371
|
-
async function initSubmodule(repoPath) {
|
|
372
|
-
return new Promise((resolve, reject) => {
|
|
373
|
-
const child = (0, child_process_1.spawn)("git", ["submodule", "update", "--init", "--recursive", exports.TEMPLATE_DIR_NAME], {
|
|
374
|
-
cwd: repoPath,
|
|
375
|
-
stdio: "pipe",
|
|
376
|
-
});
|
|
377
|
-
let stderr = "";
|
|
378
|
-
child.stderr?.on("data", (data) => {
|
|
379
|
-
stderr += data.toString();
|
|
380
|
-
});
|
|
381
|
-
child.on("close", (code) => {
|
|
382
|
-
if (code === 0) {
|
|
383
|
-
resolve();
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
reject(new Error(`Submodule init failed: ${stderr}`));
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
child.on("error", reject);
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
// =============================================================================
|
|
393
|
-
// Package.json Utilities
|
|
394
|
-
// =============================================================================
|
|
395
|
-
/** Updates package.json with project name, description, and npm dependencies */
|
|
396
338
|
function updateProjectPackageJson(outputDir, projectName, description, npmDependencies) {
|
|
397
339
|
const packageJsonPath = path.join(outputDir, "package.json");
|
|
398
340
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
@@ -411,7 +353,6 @@ function updateProjectPackageJson(outputDir, projectName, description, npmDepend
|
|
|
411
353
|
// =============================================================================
|
|
412
354
|
// Command Execution Utilities
|
|
413
355
|
// =============================================================================
|
|
414
|
-
/** Executes a command and returns output */
|
|
415
356
|
function runCommand(cmd, args, cwd) {
|
|
416
357
|
return new Promise((resolve, reject) => {
|
|
417
358
|
const child = (0, child_process_1.spawn)(cmd, args, {
|
|
@@ -502,3 +443,83 @@ function extractErrorMessage(output) {
|
|
|
502
443
|
const nonEmptyLines = lines.filter((l) => l.trim().length > 0);
|
|
503
444
|
return nonEmptyLines.slice(-5).join("\n");
|
|
504
445
|
}
|
|
446
|
+
// =============================================================================
|
|
447
|
+
// GitHub Repository Utilities
|
|
448
|
+
// =============================================================================
|
|
449
|
+
/**
|
|
450
|
+
* Downloads a file from GitHub repository
|
|
451
|
+
*/
|
|
452
|
+
async function downloadFileFromGitHub(filePath, outputPath) {
|
|
453
|
+
const urlParts = config_1.REPO_URL.replace("https://github.com/", "").split("/");
|
|
454
|
+
const owner = urlParts[0];
|
|
455
|
+
const repo = urlParts[1];
|
|
456
|
+
const url = `https://raw.githubusercontent.com/${owner}/${repo}/${config_1.REPO_BRANCH}/${filePath}`;
|
|
457
|
+
const response = await fetch(url);
|
|
458
|
+
if (!response.ok) {
|
|
459
|
+
throw new Error(`Failed to download ${filePath}: ${response.statusText}`);
|
|
460
|
+
}
|
|
461
|
+
const content = await response.text();
|
|
462
|
+
const dir = path.dirname(outputPath);
|
|
463
|
+
if (!fs.existsSync(dir)) {
|
|
464
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
465
|
+
}
|
|
466
|
+
fs.writeFileSync(outputPath, content);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Clones the template repository to temp directory
|
|
470
|
+
*/
|
|
471
|
+
async function cloneTemplate(tempDir) {
|
|
472
|
+
const templatePath = path.join(tempDir, "template");
|
|
473
|
+
return new Promise((resolve, reject) => {
|
|
474
|
+
const cloneUrl = `${config_1.REPO_URL}.git`;
|
|
475
|
+
const args = [
|
|
476
|
+
"clone",
|
|
477
|
+
"--depth=1",
|
|
478
|
+
"--branch",
|
|
479
|
+
config_1.REPO_BRANCH,
|
|
480
|
+
"--single-branch",
|
|
481
|
+
cloneUrl,
|
|
482
|
+
templatePath,
|
|
483
|
+
];
|
|
484
|
+
const child = (0, child_process_1.spawn)("git", args, {
|
|
485
|
+
stdio: "pipe",
|
|
486
|
+
});
|
|
487
|
+
let stderr = "";
|
|
488
|
+
child.stderr?.on("data", (data) => {
|
|
489
|
+
stderr += data.toString();
|
|
490
|
+
});
|
|
491
|
+
child.on("close", (code) => {
|
|
492
|
+
if (code === 0) {
|
|
493
|
+
resolve(templatePath);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
reject(new Error(`Git clone failed: ${stderr}`));
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
child.on("error", reject);
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Initializes git submodule for the template
|
|
504
|
+
*/
|
|
505
|
+
async function initSubmodule(repoPath) {
|
|
506
|
+
return new Promise((resolve, reject) => {
|
|
507
|
+
const child = (0, child_process_1.spawn)("git", ["submodule", "update", "--init", "--recursive", exports.TEMPLATE_DIR_NAME], {
|
|
508
|
+
cwd: repoPath,
|
|
509
|
+
stdio: "pipe",
|
|
510
|
+
});
|
|
511
|
+
let stderr = "";
|
|
512
|
+
child.stderr?.on("data", (data) => {
|
|
513
|
+
stderr += data.toString();
|
|
514
|
+
});
|
|
515
|
+
child.on("close", (code) => {
|
|
516
|
+
if (code === 0) {
|
|
517
|
+
resolve();
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
reject(new Error(`Submodule init failed: ${stderr}`));
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
child.on("error", reject);
|
|
524
|
+
});
|
|
525
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fhevm-example",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Create FHEVM example projects with a single command - A comprehensive toolkit for building privacy-preserving smart contracts",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-fhevm-example": "./dist/scripts/index.js"
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"help:docs": "npx ts-node scripts/generate-docs.ts --help",
|
|
23
23
|
"help:test": "npx ts-node scripts/maintenance.ts test-all --help",
|
|
24
24
|
|
|
25
|
+
"postinstall": "git submodule update --init --recursive",
|
|
25
26
|
"prepublishOnly": "npm run build",
|
|
26
27
|
"prepack": "mv README.md GITHUB_README.md && cp NPM_README.md README.md",
|
|
27
28
|
"postpack": "mv GITHUB_README.md README.md"
|