create-izi-noir 0.2.0 → 0.2.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/dist/index.js +186 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import path2 from "path";
|
|
8
8
|
import { execSync } from "child_process";
|
|
9
|
-
import
|
|
9
|
+
import pc4 from "picocolors";
|
|
10
10
|
|
|
11
11
|
// src/prompts/project.ts
|
|
12
12
|
import prompts from "prompts";
|
|
@@ -153,6 +153,149 @@ function createSpinner(message) {
|
|
|
153
153
|
return new Spinner(message);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// src/utils/progress.ts
|
|
157
|
+
import pc3 from "picocolors";
|
|
158
|
+
var THINKING_PHRASES = [
|
|
159
|
+
"Initializing ZK environment",
|
|
160
|
+
"Configuring proof system",
|
|
161
|
+
"Setting up circuit compiler",
|
|
162
|
+
"Preparing cryptographic primitives",
|
|
163
|
+
"Generating project scaffold",
|
|
164
|
+
"Configuring Noir integration",
|
|
165
|
+
"Setting up React components",
|
|
166
|
+
"Preparing WASM bindings"
|
|
167
|
+
];
|
|
168
|
+
var FILE_ICONS = {
|
|
169
|
+
".json": "\u{1F4E6}",
|
|
170
|
+
".ts": "\u{1F4DC}",
|
|
171
|
+
".tsx": "\u269B\uFE0F",
|
|
172
|
+
".css": "\u{1F3A8}",
|
|
173
|
+
".html": "\u{1F310}",
|
|
174
|
+
".md": "\u{1F4DD}",
|
|
175
|
+
".svg": "\u{1F5BC}\uFE0F",
|
|
176
|
+
default: "\u{1F4C4}"
|
|
177
|
+
};
|
|
178
|
+
function getFileIcon(filename) {
|
|
179
|
+
const ext = filename.slice(filename.lastIndexOf("."));
|
|
180
|
+
return FILE_ICONS[ext] || FILE_ICONS.default;
|
|
181
|
+
}
|
|
182
|
+
function sleep(ms) {
|
|
183
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
184
|
+
}
|
|
185
|
+
var ProgressReporter = class {
|
|
186
|
+
currentLine = "";
|
|
187
|
+
thinkingIndex = 0;
|
|
188
|
+
thinkingInterval = null;
|
|
189
|
+
async startThinking() {
|
|
190
|
+
process.stdout.write("\x1B[?25l");
|
|
191
|
+
this.showThinking();
|
|
192
|
+
}
|
|
193
|
+
showThinking() {
|
|
194
|
+
const frames2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
195
|
+
let frameIndex = 0;
|
|
196
|
+
let dotCount = 0;
|
|
197
|
+
this.thinkingInterval = setInterval(() => {
|
|
198
|
+
const frame = pc3.cyan(frames2[frameIndex]);
|
|
199
|
+
const phrase = THINKING_PHRASES[this.thinkingIndex % THINKING_PHRASES.length];
|
|
200
|
+
const dots = ".".repeat(dotCount % 4);
|
|
201
|
+
process.stdout.write(`\r${frame} ${pc3.dim(phrase)}${dots} `);
|
|
202
|
+
frameIndex = (frameIndex + 1) % frames2.length;
|
|
203
|
+
dotCount++;
|
|
204
|
+
if (dotCount % 12 === 0) {
|
|
205
|
+
this.thinkingIndex++;
|
|
206
|
+
}
|
|
207
|
+
}, 80);
|
|
208
|
+
}
|
|
209
|
+
stopThinking() {
|
|
210
|
+
if (this.thinkingInterval) {
|
|
211
|
+
clearInterval(this.thinkingInterval);
|
|
212
|
+
this.thinkingInterval = null;
|
|
213
|
+
}
|
|
214
|
+
process.stdout.write("\r\x1B[K");
|
|
215
|
+
}
|
|
216
|
+
async reportFile(filename, isLast = false) {
|
|
217
|
+
const icon = getFileIcon(filename);
|
|
218
|
+
const line = ` ${icon} ${pc3.dim("created")} ${pc3.white(filename)}`;
|
|
219
|
+
process.stdout.write(" " + icon + " " + pc3.dim("created") + " ");
|
|
220
|
+
for (const char of filename) {
|
|
221
|
+
process.stdout.write(pc3.white(char));
|
|
222
|
+
await sleep(8 + Math.random() * 12);
|
|
223
|
+
}
|
|
224
|
+
process.stdout.write("\n");
|
|
225
|
+
this.currentLine = line;
|
|
226
|
+
}
|
|
227
|
+
async reportDirectory(dirname) {
|
|
228
|
+
process.stdout.write(` \u{1F4C1} ${pc3.dim("mkdir")} ${pc3.blue(dirname)}/
|
|
229
|
+
`);
|
|
230
|
+
await sleep(30);
|
|
231
|
+
}
|
|
232
|
+
showSuccess(message) {
|
|
233
|
+
process.stdout.write("\x1B[?25h");
|
|
234
|
+
console.log();
|
|
235
|
+
console.log(pc3.green("\u2713") + " " + message);
|
|
236
|
+
}
|
|
237
|
+
showError(message) {
|
|
238
|
+
process.stdout.write("\x1B[?25h");
|
|
239
|
+
console.log();
|
|
240
|
+
console.log(pc3.red("\u2717") + " " + message);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
function createProgressReporter() {
|
|
244
|
+
return new ProgressReporter();
|
|
245
|
+
}
|
|
246
|
+
var InstallProgress = class {
|
|
247
|
+
interval = null;
|
|
248
|
+
progress = 0;
|
|
249
|
+
packages = [
|
|
250
|
+
"react",
|
|
251
|
+
"react-dom",
|
|
252
|
+
"vite",
|
|
253
|
+
"@izi-noir/sdk",
|
|
254
|
+
"@noir-lang/acvm_js",
|
|
255
|
+
"@noir-lang/noirc_abi",
|
|
256
|
+
"prism-react-renderer",
|
|
257
|
+
"typescript"
|
|
258
|
+
];
|
|
259
|
+
currentPackage = 0;
|
|
260
|
+
start() {
|
|
261
|
+
process.stdout.write("\x1B[?25l");
|
|
262
|
+
const barWidth = 30;
|
|
263
|
+
const frames2 = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
|
|
264
|
+
let frameIndex = 0;
|
|
265
|
+
this.interval = setInterval(() => {
|
|
266
|
+
const frame = pc3.cyan(frames2[frameIndex]);
|
|
267
|
+
const filled = Math.floor(this.progress / 100 * barWidth);
|
|
268
|
+
const empty = barWidth - filled;
|
|
269
|
+
const bar = pc3.green("\u2588".repeat(filled)) + pc3.dim("\u2591".repeat(empty));
|
|
270
|
+
const pkg = this.packages[this.currentPackage % this.packages.length];
|
|
271
|
+
process.stdout.write(
|
|
272
|
+
`\r${frame} Installing dependencies ${bar} ${pc3.dim(pkg)} `
|
|
273
|
+
);
|
|
274
|
+
frameIndex = (frameIndex + 1) % frames2.length;
|
|
275
|
+
if (this.progress < 95) {
|
|
276
|
+
this.progress += Math.random() * 3;
|
|
277
|
+
if (this.progress > (this.currentPackage + 1) * 12) {
|
|
278
|
+
this.currentPackage++;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}, 100);
|
|
282
|
+
}
|
|
283
|
+
stop(success = true) {
|
|
284
|
+
if (this.interval) {
|
|
285
|
+
clearInterval(this.interval);
|
|
286
|
+
this.interval = null;
|
|
287
|
+
}
|
|
288
|
+
process.stdout.write("\x1B[?25h");
|
|
289
|
+
process.stdout.write("\r\x1B[K");
|
|
290
|
+
const icon = success ? pc3.green("\u2713") : pc3.red("\u2717");
|
|
291
|
+
const message = success ? "Dependencies installed" : "Failed to install dependencies";
|
|
292
|
+
console.log(`${icon} ${message}`);
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
function createInstallProgress() {
|
|
296
|
+
return new InstallProgress();
|
|
297
|
+
}
|
|
298
|
+
|
|
156
299
|
// src/generators/package-json.ts
|
|
157
300
|
function generatePackageJson(options) {
|
|
158
301
|
const isSolana = options.provider === "arkworks";
|
|
@@ -162,7 +305,9 @@ function generatePackageJson(options) {
|
|
|
162
305
|
"@noir-lang/noirc_abi": "1.0.0-beta.13-1d260df.nightly",
|
|
163
306
|
"react": "^18.3.1",
|
|
164
307
|
"react-dom": "^18.3.1",
|
|
165
|
-
"prism-react-renderer": "^2.4.1"
|
|
308
|
+
"prism-react-renderer": "^2.4.1",
|
|
309
|
+
"buffer": "^6.0.3",
|
|
310
|
+
"util": "^0.12.5"
|
|
166
311
|
};
|
|
167
312
|
if (isSolana) {
|
|
168
313
|
dependencies["@solana/wallet-adapter-react"] = "^0.15.0";
|
|
@@ -449,6 +594,7 @@ export default defineConfig({
|
|
|
449
594
|
alias: {
|
|
450
595
|
"@": path.resolve(__dirname, "./src"),
|
|
451
596
|
buffer: "buffer/",
|
|
597
|
+
util: "util/",
|
|
452
598
|
},
|
|
453
599
|
},
|
|
454
600
|
define: {
|
|
@@ -456,7 +602,7 @@ export default defineConfig({
|
|
|
456
602
|
},
|
|
457
603
|
optimizeDeps: {
|
|
458
604
|
exclude: ["@noir-lang/noir_wasm", "@aztec/bb.js", "@izi-noir/sdk"],
|
|
459
|
-
include: ["buffer"],
|
|
605
|
+
include: ["buffer", "util"],
|
|
460
606
|
},
|
|
461
607
|
build: {
|
|
462
608
|
rollupOptions: {
|
|
@@ -1410,28 +1556,31 @@ async function initCommand(projectName, options) {
|
|
|
1410
1556
|
});
|
|
1411
1557
|
}
|
|
1412
1558
|
if (!projectOptions) {
|
|
1413
|
-
console.log(
|
|
1559
|
+
console.log(pc4.yellow("\nOperation cancelled."));
|
|
1414
1560
|
process.exit(0);
|
|
1415
1561
|
}
|
|
1416
1562
|
const projectDir = path2.resolve(process.cwd(), projectOptions.projectName);
|
|
1417
1563
|
if (await directoryExists(projectDir)) {
|
|
1418
1564
|
if (!await isDirectoryEmpty(projectDir)) {
|
|
1419
1565
|
console.log(
|
|
1420
|
-
|
|
1566
|
+
pc4.red(`
|
|
1421
1567
|
Error: Directory "${projectOptions.projectName}" already exists and is not empty.`)
|
|
1422
1568
|
);
|
|
1423
1569
|
process.exit(1);
|
|
1424
1570
|
}
|
|
1425
1571
|
}
|
|
1426
1572
|
console.log();
|
|
1427
|
-
const
|
|
1428
|
-
spinner.start();
|
|
1573
|
+
const progress = createProgressReporter();
|
|
1429
1574
|
try {
|
|
1430
|
-
await
|
|
1431
|
-
|
|
1575
|
+
await progress.startThinking();
|
|
1576
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
1577
|
+
progress.stopThinking();
|
|
1578
|
+
console.log(pc4.bold("\n Scaffolding your ZK project...\n"));
|
|
1579
|
+
await createProjectStructure(projectDir, projectOptions, progress);
|
|
1580
|
+
progress.showSuccess("Project structure created");
|
|
1432
1581
|
} catch (error) {
|
|
1433
|
-
|
|
1434
|
-
console.error(
|
|
1582
|
+
progress.showError("Failed to create project structure");
|
|
1583
|
+
console.error(pc4.red("\n"), error);
|
|
1435
1584
|
process.exit(1);
|
|
1436
1585
|
}
|
|
1437
1586
|
if (!projectOptions.skipGit) {
|
|
@@ -1442,28 +1591,28 @@ Error: Directory "${projectOptions.projectName}" already exists and is not empty
|
|
|
1442
1591
|
gitSpinner.stop(true);
|
|
1443
1592
|
} catch {
|
|
1444
1593
|
gitSpinner.stop(false);
|
|
1445
|
-
console.log(
|
|
1594
|
+
console.log(pc4.yellow(" Warning: Failed to initialize git repository"));
|
|
1446
1595
|
}
|
|
1447
1596
|
}
|
|
1448
1597
|
if (!projectOptions.skipInstall) {
|
|
1449
|
-
const
|
|
1450
|
-
|
|
1598
|
+
const installProgress = createInstallProgress();
|
|
1599
|
+
installProgress.start();
|
|
1451
1600
|
try {
|
|
1452
1601
|
execSync("npm install", { cwd: projectDir, stdio: "ignore" });
|
|
1453
|
-
|
|
1602
|
+
installProgress.stop(true);
|
|
1454
1603
|
} catch {
|
|
1455
|
-
|
|
1456
|
-
console.log(
|
|
1604
|
+
installProgress.stop(false);
|
|
1605
|
+
console.log(pc4.yellow(' Run "npm install" manually.'));
|
|
1457
1606
|
}
|
|
1458
1607
|
}
|
|
1459
1608
|
printSuccessMessage(projectOptions);
|
|
1460
1609
|
}
|
|
1461
|
-
async function createProjectStructure(projectDir, options) {
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1610
|
+
async function createProjectStructure(projectDir, options, progress) {
|
|
1611
|
+
const dirs = ["circuits", "src", "src/components", "src/lib", "public"];
|
|
1612
|
+
for (const dir of dirs) {
|
|
1613
|
+
await ensureDir(path2.join(projectDir, dir));
|
|
1614
|
+
await progress.reportDirectory(dir);
|
|
1615
|
+
}
|
|
1467
1616
|
const files = [
|
|
1468
1617
|
// Root config files
|
|
1469
1618
|
["package.json", generatePackageJson(options)],
|
|
@@ -1499,34 +1648,34 @@ async function createProjectStructure(projectDir, options) {
|
|
|
1499
1648
|
}
|
|
1500
1649
|
files.push(["circuits/index.ts", generateCircuitsIndex(options.template)]);
|
|
1501
1650
|
files.push(["circuits/types.d.ts", generateCircuitTypes()]);
|
|
1502
|
-
|
|
1503
|
-
files
|
|
1504
|
-
|
|
1505
|
-
)
|
|
1506
|
-
|
|
1651
|
+
for (let i = 0; i < files.length; i++) {
|
|
1652
|
+
const [relativePath, content] = files[i];
|
|
1653
|
+
await writeFile(path2.join(projectDir, relativePath), content);
|
|
1654
|
+
await progress.reportFile(relativePath, i === files.length - 1);
|
|
1655
|
+
}
|
|
1507
1656
|
}
|
|
1508
1657
|
function printSuccessMessage(options) {
|
|
1509
1658
|
console.log();
|
|
1510
|
-
console.log(
|
|
1659
|
+
console.log(pc4.green("\u2713") + " Project created successfully!");
|
|
1511
1660
|
console.log();
|
|
1512
1661
|
console.log("Next steps:");
|
|
1513
1662
|
console.log();
|
|
1514
|
-
console.log(
|
|
1663
|
+
console.log(pc4.cyan(` cd ${options.projectName}`));
|
|
1515
1664
|
if (options.skipInstall) {
|
|
1516
|
-
console.log(
|
|
1665
|
+
console.log(pc4.cyan(" npm install"));
|
|
1517
1666
|
}
|
|
1518
|
-
console.log(
|
|
1667
|
+
console.log(pc4.cyan(" npm run dev"));
|
|
1519
1668
|
console.log();
|
|
1520
|
-
console.log("Then open " +
|
|
1669
|
+
console.log("Then open " + pc4.blue("http://localhost:5173") + " in your browser.");
|
|
1521
1670
|
console.log();
|
|
1522
1671
|
console.log("To add circuits:");
|
|
1523
1672
|
console.log();
|
|
1524
|
-
console.log(
|
|
1525
|
-
console.log(
|
|
1526
|
-
console.log(
|
|
1673
|
+
console.log(pc4.dim(" 1. Create a new circuit in circuits/*.ts"));
|
|
1674
|
+
console.log(pc4.dim(" 2. Export it from circuits/index.ts"));
|
|
1675
|
+
console.log(pc4.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
|
|
1527
1676
|
console.log();
|
|
1528
1677
|
console.log(
|
|
1529
|
-
|
|
1678
|
+
pc4.dim("Learn more: ") + pc4.blue("https://github.com/izi-noir/izi-noir")
|
|
1530
1679
|
);
|
|
1531
1680
|
console.log();
|
|
1532
1681
|
}
|