create-fhevm-example 1.3.0 → 1.3.2
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/help.d.ts +9 -0
- package/dist/scripts/help.d.ts.map +1 -0
- package/dist/scripts/help.js +73 -0
- package/dist/scripts/index.js +105 -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 +3 -2
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.2",
|
|
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"
|
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
"test:all": "npx ts-node scripts/maintenance.ts test-all",
|
|
19
19
|
"generate:config": "npx ts-node scripts/generate-config.ts",
|
|
20
20
|
"doctor": "npx ts-node scripts/doctor.ts",
|
|
21
|
-
"help:create": "npx ts-node scripts/index.ts --help",
|
|
21
|
+
"help:create": "LOCAL_DEV=1 npx ts-node scripts/index.ts --help",
|
|
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
|
+
"prepare": "git submodule update --init --recursive || true",
|
|
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"
|