create-fhevm-example 1.2.3 → 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 +72 -146
- package/dist/scripts/add-mode.d.ts +11 -0
- package/dist/scripts/add-mode.d.ts.map +1 -0
- package/dist/{add-mode.js → scripts/add-mode.js} +84 -58
- package/dist/scripts/builders.d.ts +19 -0
- package/dist/scripts/builders.d.ts.map +1 -0
- package/dist/scripts/builders.js +211 -0
- package/dist/{config.d.ts → scripts/config.d.ts} +24 -3
- package/dist/scripts/config.d.ts.map +1 -0
- package/dist/scripts/config.js +465 -0
- package/dist/scripts/doctor.d.ts +11 -0
- package/dist/scripts/doctor.d.ts.map +1 -0
- package/dist/scripts/doctor.js +165 -0
- package/dist/scripts/generate-config.d.ts +9 -0
- package/dist/scripts/generate-config.d.ts.map +1 -0
- package/dist/scripts/generate-config.js +323 -0
- package/dist/scripts/generate-docs.d.ts +10 -0
- package/dist/scripts/generate-docs.d.ts.map +1 -0
- package/dist/scripts/generate-docs.js +190 -0
- package/dist/scripts/index.d.ts +12 -0
- package/dist/scripts/index.d.ts.map +1 -0
- package/dist/scripts/index.js +384 -0
- package/dist/scripts/maintenance.d.ts +13 -0
- package/dist/scripts/maintenance.d.ts.map +1 -0
- package/dist/scripts/maintenance.js +271 -0
- package/dist/{prompts.d.ts → scripts/ui.d.ts} +8 -7
- package/dist/scripts/ui.d.ts.map +1 -0
- package/dist/scripts/ui.js +170 -0
- package/dist/scripts/utils.d.ts +86 -0
- package/dist/scripts/utils.d.ts.map +1 -0
- package/dist/scripts/utils.js +525 -0
- package/package.json +25 -13
- package/dist/add-mode.d.ts +0 -21
- package/dist/add-mode.d.ts.map +0 -1
- package/dist/add-mode.js.map +0 -1
- package/dist/builders.d.ts +0 -30
- package/dist/builders.d.ts.map +0 -1
- package/dist/builders.js +0 -195
- package/dist/builders.js.map +0 -1
- package/dist/commands.d.ts +0 -19
- package/dist/commands.d.ts.map +0 -1
- package/dist/commands.js +0 -91
- package/dist/commands.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -398
- package/dist/config.js.map +0 -1
- package/dist/constants.d.ts +0 -16
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -40
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -337
- package/dist/index.js.map +0 -1
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -79
- package/dist/prompts.js.map +0 -1
- package/dist/ui.d.ts +0 -35
- package/dist/ui.d.ts.map +0 -1
- package/dist/ui.js +0 -155
- package/dist/ui.js.map +0 -1
- package/dist/utils.d.ts +0 -99
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -285
- package/dist/utils.js.map +0 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Auto-Discovery Config Generator - Automatically updates project configuration.
|
|
5
|
+
*
|
|
6
|
+
* Scans the contracts/ directory and generates scripts/config.ts.
|
|
7
|
+
* Extracts metadata from @notice tags and infers category structure.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
43
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
44
|
+
};
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const utils_1 = require("./utils");
|
|
49
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
50
|
+
const ROOT_DIR = path.resolve(__dirname, "..");
|
|
51
|
+
const CONTRACTS_DIR = path.join(ROOT_DIR, "contracts");
|
|
52
|
+
const TEST_DIR = path.join(ROOT_DIR, "test");
|
|
53
|
+
const OUTPUT_FILE = path.join(ROOT_DIR, "scripts/config.ts");
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// Contract Analysis
|
|
56
|
+
// =============================================================================
|
|
57
|
+
function extractNotice(contractPath) {
|
|
58
|
+
const content = fs.readFileSync(contractPath, "utf-8");
|
|
59
|
+
const noticeRegex = /\/\*\*[\s\S]*?@notice\s+([^\n*]+)[\s\S]*?\*\/[\s\S]*?contract\s+\w+/;
|
|
60
|
+
const match = content.match(noticeRegex);
|
|
61
|
+
return match && match[1] ? match[1].trim() : null;
|
|
62
|
+
}
|
|
63
|
+
function readExistingConfig() {
|
|
64
|
+
try {
|
|
65
|
+
if (!fs.existsSync(OUTPUT_FILE)) {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
delete require.cache[require.resolve(OUTPUT_FILE)];
|
|
69
|
+
const config = require(OUTPUT_FILE);
|
|
70
|
+
return config.EXAMPLES || {};
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.warn("⚠️ Could not read existing config, starting fresh");
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function getCategoryFromPath(relativePath) {
|
|
78
|
+
const parts = relativePath.split("/");
|
|
79
|
+
parts.pop();
|
|
80
|
+
if (parts.length === 0)
|
|
81
|
+
return "Uncategorized";
|
|
82
|
+
if (parts.length === 1)
|
|
83
|
+
return (0, utils_1.formatCategoryName)(parts[0]);
|
|
84
|
+
return parts.map(utils_1.formatCategoryName).join(" - ");
|
|
85
|
+
}
|
|
86
|
+
function findTestFile(contractPath) {
|
|
87
|
+
const relativePath = path.relative(CONTRACTS_DIR, contractPath);
|
|
88
|
+
const testPath = path.join(TEST_DIR, relativePath.replace(".sol", ".ts"));
|
|
89
|
+
return fs.existsSync(testPath)
|
|
90
|
+
? `test/${path.relative(TEST_DIR, testPath)}`
|
|
91
|
+
: null;
|
|
92
|
+
}
|
|
93
|
+
function getDocsOutput(contractPath) {
|
|
94
|
+
const relativePath = contractPath
|
|
95
|
+
.replace(/^contracts\//, "")
|
|
96
|
+
.replace(/\.sol$/, "");
|
|
97
|
+
return `docs/${(0, utils_1.toKebabCase)(relativePath)}.md`;
|
|
98
|
+
}
|
|
99
|
+
function scanContracts() {
|
|
100
|
+
const contracts = [];
|
|
101
|
+
const existingConfig = readExistingConfig();
|
|
102
|
+
function scan(dir) {
|
|
103
|
+
const items = fs.readdirSync(dir);
|
|
104
|
+
for (const item of items) {
|
|
105
|
+
const fullPath = path.join(dir, item);
|
|
106
|
+
const stat = fs.statSync(fullPath);
|
|
107
|
+
if (stat.isDirectory() && item !== "mocks") {
|
|
108
|
+
scan(fullPath);
|
|
109
|
+
}
|
|
110
|
+
else if (stat.isFile() && item.endsWith(".sol")) {
|
|
111
|
+
const relativePath = path.relative(CONTRACTS_DIR, fullPath);
|
|
112
|
+
const contractName = item.replace(".sol", "");
|
|
113
|
+
const exampleName = (0, utils_1.contractNameToExampleName)(contractName);
|
|
114
|
+
const category = getCategoryFromPath(relativePath);
|
|
115
|
+
const testPath = findTestFile(fullPath);
|
|
116
|
+
const description = extractNotice(fullPath);
|
|
117
|
+
if (!description) {
|
|
118
|
+
console.warn(`⚠️ No @notice found in ${relativePath}`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!testPath) {
|
|
122
|
+
console.warn(`⚠️ No test file found for ${relativePath}`);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const contractInfo = {
|
|
126
|
+
name: exampleName,
|
|
127
|
+
contractPath: `contracts/${relativePath}`,
|
|
128
|
+
testPath,
|
|
129
|
+
description,
|
|
130
|
+
category,
|
|
131
|
+
title: (0, utils_1.contractNameToTitle)(contractName),
|
|
132
|
+
docsOutput: getDocsOutput(`contracts/${relativePath}`),
|
|
133
|
+
};
|
|
134
|
+
const existingExample = existingConfig[exampleName];
|
|
135
|
+
if (existingExample?.npmDependencies) {
|
|
136
|
+
contractInfo.npmDependencies = existingExample.npmDependencies;
|
|
137
|
+
}
|
|
138
|
+
if (existingExample?.dependencies) {
|
|
139
|
+
contractInfo.dependencies = existingExample.dependencies;
|
|
140
|
+
}
|
|
141
|
+
contracts.push(contractInfo);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
scan(CONTRACTS_DIR);
|
|
146
|
+
return contracts;
|
|
147
|
+
}
|
|
148
|
+
// =============================================================================
|
|
149
|
+
// Config Generation
|
|
150
|
+
// =============================================================================
|
|
151
|
+
function generateExamplesConfig(contracts) {
|
|
152
|
+
const entries = contracts.map((c) => {
|
|
153
|
+
const npmDepsField = c.npmDependencies
|
|
154
|
+
? `\n npmDependencies: ${JSON.stringify(c.npmDependencies, null, 2).replace(/\n/g, "\n ")},`
|
|
155
|
+
: "";
|
|
156
|
+
const depsField = c.dependencies
|
|
157
|
+
? `\n dependencies: ${JSON.stringify(c.dependencies, null, 2).replace(/\n/g, "\n ")},`
|
|
158
|
+
: "";
|
|
159
|
+
return ` "${c.name}": {
|
|
160
|
+
contract: "${c.contractPath}",
|
|
161
|
+
test: "${c.testPath}",${npmDepsField}${depsField}
|
|
162
|
+
description:
|
|
163
|
+
"${c.description}",
|
|
164
|
+
category: "${c.category}",
|
|
165
|
+
docsOutput: "${c.docsOutput}",
|
|
166
|
+
title: "${c.title}"
|
|
167
|
+
}`;
|
|
168
|
+
});
|
|
169
|
+
return `export const EXAMPLES: Record<string, ExampleConfig> = {\n${entries.join(",\n")}\n};`;
|
|
170
|
+
}
|
|
171
|
+
function generateCategoriesConfig(contracts) {
|
|
172
|
+
const categoryMap = {};
|
|
173
|
+
for (const contract of contracts) {
|
|
174
|
+
if (!categoryMap[contract.category]) {
|
|
175
|
+
categoryMap[contract.category] = [];
|
|
176
|
+
}
|
|
177
|
+
categoryMap[contract.category].push(contract);
|
|
178
|
+
}
|
|
179
|
+
const categoryEntries = Object.entries(categoryMap).map(([category, items]) => {
|
|
180
|
+
const categoryKey = category
|
|
181
|
+
.toLowerCase()
|
|
182
|
+
.replace(/\s+/g, "")
|
|
183
|
+
.replace(/-/g, "");
|
|
184
|
+
const contracts = items
|
|
185
|
+
.map((c) => ` {
|
|
186
|
+
sol: "${c.contractPath}",
|
|
187
|
+
test: "${c.testPath}",
|
|
188
|
+
}`)
|
|
189
|
+
.join(",\n");
|
|
190
|
+
return ` ${categoryKey}: {
|
|
191
|
+
name: "${category} Examples",
|
|
192
|
+
contracts: [
|
|
193
|
+
${contracts}
|
|
194
|
+
],
|
|
195
|
+
}`;
|
|
196
|
+
});
|
|
197
|
+
return `export const CATEGORIES: Record<string, CategoryConfig> = {\n${categoryEntries.join(",\n")}\n};`;
|
|
198
|
+
}
|
|
199
|
+
function generateConfigFile(contracts) {
|
|
200
|
+
return `/**
|
|
201
|
+
* ⚠️ AUTO-GENERATED FILE - DO NOT EDIT MANUALLY ⚠️
|
|
202
|
+
*
|
|
203
|
+
* This file is auto-generated by cli/generate-config.ts
|
|
204
|
+
* Run 'npm run generate:config' to regenerate
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
// =============================================================================
|
|
208
|
+
// Types
|
|
209
|
+
// =============================================================================
|
|
210
|
+
|
|
211
|
+
export interface ExampleConfig {
|
|
212
|
+
/** Path to the Solidity contract file */
|
|
213
|
+
contract: string;
|
|
214
|
+
/** Path to the TypeScript test file */
|
|
215
|
+
test: string;
|
|
216
|
+
/** Optional additional contract dependencies */
|
|
217
|
+
dependencies?: string[];
|
|
218
|
+
/** Optional npm packages to install */
|
|
219
|
+
npmDependencies?: Record<string, string>;
|
|
220
|
+
/** Full description for documentation */
|
|
221
|
+
description: string;
|
|
222
|
+
/** Category for grouping */
|
|
223
|
+
category: string;
|
|
224
|
+
/** Output path for generated documentation */
|
|
225
|
+
docsOutput: string;
|
|
226
|
+
/** Title for documentation */
|
|
227
|
+
title: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface CategoryConfig {
|
|
231
|
+
/** Display name */
|
|
232
|
+
name: string;
|
|
233
|
+
/** List of contracts in this category */
|
|
234
|
+
contracts: Array<{ sol: string; test?: string }>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// =============================================================================
|
|
238
|
+
// GitHub Repository Configuration
|
|
239
|
+
// =============================================================================
|
|
240
|
+
|
|
241
|
+
export const REPO_URL = "https://github.com/NecipAkgz/fhevm-example-factory";
|
|
242
|
+
export const REPO_BRANCH = "main";
|
|
243
|
+
|
|
244
|
+
// =============================================================================
|
|
245
|
+
// Example Configurations
|
|
246
|
+
// =============================================================================
|
|
247
|
+
|
|
248
|
+
${generateExamplesConfig(contracts)}
|
|
249
|
+
|
|
250
|
+
// =============================================================================
|
|
251
|
+
// Category Configurations
|
|
252
|
+
// =============================================================================
|
|
253
|
+
|
|
254
|
+
${generateCategoriesConfig(contracts)}
|
|
255
|
+
|
|
256
|
+
// =============================================================================
|
|
257
|
+
// Helper Functions
|
|
258
|
+
// =============================================================================
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Get list of example names
|
|
262
|
+
*/
|
|
263
|
+
export function getExampleNames(): string[] {
|
|
264
|
+
return Object.keys(EXAMPLES);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Get list of category names
|
|
269
|
+
*/
|
|
270
|
+
export function getCategoryNames(): string[] {
|
|
271
|
+
return Object.keys(CATEGORIES);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Get example by name
|
|
276
|
+
*/
|
|
277
|
+
export function getExample(name: string): ExampleConfig | undefined {
|
|
278
|
+
return EXAMPLES[name];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Get category by name
|
|
283
|
+
*/
|
|
284
|
+
export function getCategory(name: string): CategoryConfig | undefined {
|
|
285
|
+
return CATEGORIES[name];
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Generate consistent docs filename with fhe- prefix
|
|
290
|
+
*/
|
|
291
|
+
export function getDocsFileName(exampleName: string): string {
|
|
292
|
+
return exampleName.startsWith("fhe-") ? exampleName : \`fhe-\${exampleName}\`;
|
|
293
|
+
}
|
|
294
|
+
`;
|
|
295
|
+
}
|
|
296
|
+
// =============================================================================
|
|
297
|
+
// Main
|
|
298
|
+
// =============================================================================
|
|
299
|
+
function main() {
|
|
300
|
+
utils_1.log.info(`🔍 Scanning examples in: ${picocolors_1.default.cyan("contracts/")}\n`);
|
|
301
|
+
const contracts = scanContracts();
|
|
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`);
|
|
307
|
+
const categoryCount = {};
|
|
308
|
+
for (const c of contracts) {
|
|
309
|
+
categoryCount[c.category] = (categoryCount[c.category] || 0) + 1;
|
|
310
|
+
}
|
|
311
|
+
utils_1.log.message(picocolors_1.default.bold("📊 Discovery Summary:"));
|
|
312
|
+
for (const [category, count] of Object.entries(categoryCount)) {
|
|
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`);
|
|
314
|
+
}
|
|
315
|
+
utils_1.log.message(`\n📝 Generating: ${picocolors_1.default.cyan(path.relative(ROOT_DIR, OUTPUT_FILE))}...`);
|
|
316
|
+
const configContent = generateConfigFile(contracts);
|
|
317
|
+
fs.writeFileSync(OUTPUT_FILE, configContent);
|
|
318
|
+
utils_1.log.success(`\n✨ Configuration updated successfully!`);
|
|
319
|
+
}
|
|
320
|
+
const isMainModule = process.argv[1]?.includes("generate-config");
|
|
321
|
+
if (isMainModule) {
|
|
322
|
+
main();
|
|
323
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Documentation Generator - Creates GitBook-compatible markdown docs.
|
|
4
|
+
*
|
|
5
|
+
* Processes FHEVM examples to produce structured documentation,
|
|
6
|
+
* including contract descriptions and automated index updates.
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleInteractiveDocs(): Promise<void>;
|
|
9
|
+
export declare function handleDirect(args: string[]): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=generate-docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Documentation Generator - Creates GitBook-compatible markdown docs.
|
|
5
|
+
*
|
|
6
|
+
* Processes FHEVM examples to produce structured documentation,
|
|
7
|
+
* including contract descriptions and automated index updates.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
43
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
44
|
+
};
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.handleInteractiveDocs = handleInteractiveDocs;
|
|
47
|
+
exports.handleDirect = handleDirect;
|
|
48
|
+
const p = __importStar(require("@clack/prompts"));
|
|
49
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const config_1 = require("./config");
|
|
53
|
+
const utils_1 = require("./utils");
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// Documentation Generator
|
|
56
|
+
// =============================================================================
|
|
57
|
+
async function generateDocumentation(exampleName) {
|
|
58
|
+
const rootDir = (0, utils_1.getRootDir)();
|
|
59
|
+
let count = 0;
|
|
60
|
+
const examples = exampleName === "all" ? Object.keys(config_1.EXAMPLES) : [exampleName];
|
|
61
|
+
for (const name of examples) {
|
|
62
|
+
const example = config_1.EXAMPLES[name];
|
|
63
|
+
if (!example)
|
|
64
|
+
continue;
|
|
65
|
+
const contractPath = path.join(rootDir, example.contract);
|
|
66
|
+
const testPath = path.join(rootDir, example.test);
|
|
67
|
+
if (!fs.existsSync(contractPath) || !fs.existsSync(testPath))
|
|
68
|
+
continue;
|
|
69
|
+
const contractContent = fs.readFileSync(contractPath, "utf-8");
|
|
70
|
+
const testContent = fs.readFileSync(testPath, "utf-8");
|
|
71
|
+
const contractName = (0, utils_1.getContractName)(example.contract) || "Contract";
|
|
72
|
+
const testFileName = path.basename(example.test);
|
|
73
|
+
const markdown = (0, utils_1.generateGitBookMarkdown)(example.description, contractContent, testContent, contractName, testFileName);
|
|
74
|
+
const outputPath = example.docsOutput
|
|
75
|
+
? path.join(rootDir, example.docsOutput)
|
|
76
|
+
: path.join(rootDir, "docs", `${(0, config_1.getDocsFileName)(name)}.md`);
|
|
77
|
+
const outputDir = path.dirname(outputPath);
|
|
78
|
+
if (!fs.existsSync(outputDir)) {
|
|
79
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
fs.writeFileSync(outputPath, markdown);
|
|
82
|
+
count++;
|
|
83
|
+
}
|
|
84
|
+
return count;
|
|
85
|
+
}
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// Interactive Mode
|
|
88
|
+
// =============================================================================
|
|
89
|
+
async function handleInteractiveDocs() {
|
|
90
|
+
console.clear();
|
|
91
|
+
p.intro(picocolors_1.default.bgCyan(picocolors_1.default.black(" 📚 Generate Documentation ")));
|
|
92
|
+
const scope = await p.select({
|
|
93
|
+
message: "Generate documentation for:",
|
|
94
|
+
options: [
|
|
95
|
+
{
|
|
96
|
+
value: "all",
|
|
97
|
+
label: "All examples",
|
|
98
|
+
hint: `${Object.keys(config_1.EXAMPLES).length} files`,
|
|
99
|
+
},
|
|
100
|
+
{ value: "single", label: "Single example" },
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
if (p.isCancel(scope)) {
|
|
104
|
+
p.cancel("Operation cancelled.");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
let target = "all";
|
|
108
|
+
if (scope === "single") {
|
|
109
|
+
const example = await p.select({
|
|
110
|
+
message: "Select an example:",
|
|
111
|
+
options: Object.entries(config_1.EXAMPLES).map(([key, config]) => ({
|
|
112
|
+
value: key,
|
|
113
|
+
label: key,
|
|
114
|
+
hint: config.category,
|
|
115
|
+
})),
|
|
116
|
+
});
|
|
117
|
+
if (p.isCancel(example)) {
|
|
118
|
+
p.cancel("Operation cancelled.");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
target = example;
|
|
122
|
+
}
|
|
123
|
+
const s = p.spinner();
|
|
124
|
+
s.start("Generating documentation...");
|
|
125
|
+
try {
|
|
126
|
+
const count = await generateDocumentation(target);
|
|
127
|
+
s.stop(`Generated ${count} documentation file(s)`);
|
|
128
|
+
p.log.success(`📄 Files: ${picocolors_1.default.green(String(count))} documentation file(s)`);
|
|
129
|
+
p.log.info(`📁 Location: ${picocolors_1.default.cyan("docs/")}`);
|
|
130
|
+
if (target !== "all") {
|
|
131
|
+
const docFileName = (0, config_1.getDocsFileName)(target);
|
|
132
|
+
p.log.message(` └─ ${picocolors_1.default.dim(docFileName + ".md")}`);
|
|
133
|
+
}
|
|
134
|
+
p.log.message("");
|
|
135
|
+
p.log.message(picocolors_1.default.dim("💡 Tip: Run 'npm run create:docs' to regenerate all docs"));
|
|
136
|
+
p.outro(picocolors_1.default.green("🎉 Documentation generated!"));
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
s.stop("Failed to generate documentation");
|
|
140
|
+
p.log.error(error instanceof Error ? error.message : String(error));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// =============================================================================
|
|
144
|
+
// QUICK MODE (CLI)
|
|
145
|
+
// =============================================================================
|
|
146
|
+
async function handleDirect(args) {
|
|
147
|
+
const [target] = args;
|
|
148
|
+
if (!target) {
|
|
149
|
+
utils_1.log.info("Generating all documentation...");
|
|
150
|
+
const count = await generateDocumentation("all");
|
|
151
|
+
utils_1.log.success(`✓ Generated ${count} documentation files`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (!config_1.EXAMPLES[target]) {
|
|
155
|
+
utils_1.log.message("Available: " + Object.keys(config_1.EXAMPLES).join(", "));
|
|
156
|
+
(0, utils_1.handleError)(`Unknown example "${target}"`);
|
|
157
|
+
}
|
|
158
|
+
utils_1.log.info(`Generating docs for: ${target}`);
|
|
159
|
+
await generateDocumentation(target);
|
|
160
|
+
utils_1.log.success(`✓ Generated: docs/${(0, config_1.getDocsFileName)(target)}.md`);
|
|
161
|
+
}
|
|
162
|
+
// =============================================================================
|
|
163
|
+
// Help
|
|
164
|
+
// =============================================================================
|
|
165
|
+
function showHelp() {
|
|
166
|
+
utils_1.log.info("📚 FHEVM Documentation Generator");
|
|
167
|
+
utils_1.log.message("");
|
|
168
|
+
utils_1.log.message("Usage:");
|
|
169
|
+
utils_1.log.message(" npm run create:docs Generate all docs");
|
|
170
|
+
utils_1.log.message(" npm run create:docs <example> Generate specific example doc");
|
|
171
|
+
utils_1.log.message("");
|
|
172
|
+
utils_1.log.message("Examples:");
|
|
173
|
+
utils_1.log.dim(" npm run create:docs");
|
|
174
|
+
utils_1.log.dim(" npm run create:docs fhe-counter");
|
|
175
|
+
}
|
|
176
|
+
// =============================================================================
|
|
177
|
+
// Main Entry Point
|
|
178
|
+
// =============================================================================
|
|
179
|
+
async function main() {
|
|
180
|
+
const args = process.argv.slice(2);
|
|
181
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
182
|
+
showHelp();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
await handleDirect(args);
|
|
186
|
+
}
|
|
187
|
+
const isMainModule = process.argv[1]?.includes("generate-docs");
|
|
188
|
+
if (isMainModule) {
|
|
189
|
+
main().catch(console.error);
|
|
190
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* create-fhevm-example - CLI for creating FHEVM example projects
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx create-fhevm-example # Interactive mode
|
|
7
|
+
* npx create-fhevm-example --example <name> # Create single example
|
|
8
|
+
* npx create-fhevm-example --category <name> # Create category project
|
|
9
|
+
* npx create-fhevm-example --add # Add to existing project
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../scripts/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
|