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.
Files changed (2) hide show
  1. package/dist/index.js +186 -37
  2. 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 pc3 from "picocolors";
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(pc3.yellow("\nOperation cancelled."));
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
- pc3.red(`
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 spinner = createSpinner("Creating project structure...");
1428
- spinner.start();
1573
+ const progress = createProgressReporter();
1429
1574
  try {
1430
- await createProjectStructure(projectDir, projectOptions);
1431
- spinner.stop(true);
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
- spinner.stop(false);
1434
- console.error(pc3.red("\nFailed to create project structure:"), 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(pc3.yellow(" Warning: Failed to initialize git repository"));
1594
+ console.log(pc4.yellow(" Warning: Failed to initialize git repository"));
1446
1595
  }
1447
1596
  }
1448
1597
  if (!projectOptions.skipInstall) {
1449
- const installSpinner = createSpinner("Installing dependencies...");
1450
- installSpinner.start();
1598
+ const installProgress = createInstallProgress();
1599
+ installProgress.start();
1451
1600
  try {
1452
1601
  execSync("npm install", { cwd: projectDir, stdio: "ignore" });
1453
- installSpinner.stop(true);
1602
+ installProgress.stop(true);
1454
1603
  } catch {
1455
- installSpinner.stop(false);
1456
- console.log(pc3.yellow(' Warning: Failed to install dependencies. Run "npm install" manually.'));
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
- await ensureDir(path2.join(projectDir, "circuits"));
1463
- await ensureDir(path2.join(projectDir, "src"));
1464
- await ensureDir(path2.join(projectDir, "src", "components"));
1465
- await ensureDir(path2.join(projectDir, "src", "lib"));
1466
- await ensureDir(path2.join(projectDir, "public"));
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
- await Promise.all(
1503
- files.map(
1504
- ([relativePath, content]) => writeFile(path2.join(projectDir, relativePath), content)
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(pc3.green("\u2713") + " Project created successfully!");
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(pc3.cyan(` cd ${options.projectName}`));
1663
+ console.log(pc4.cyan(` cd ${options.projectName}`));
1515
1664
  if (options.skipInstall) {
1516
- console.log(pc3.cyan(" npm install"));
1665
+ console.log(pc4.cyan(" npm install"));
1517
1666
  }
1518
- console.log(pc3.cyan(" npm run dev"));
1667
+ console.log(pc4.cyan(" npm run dev"));
1519
1668
  console.log();
1520
- console.log("Then open " + pc3.blue("http://localhost:5173") + " in your browser.");
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(pc3.dim(" 1. Create a new circuit in circuits/*.ts"));
1525
- console.log(pc3.dim(" 2. Export it from circuits/index.ts"));
1526
- console.log(pc3.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
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
- pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir/izi-noir")
1678
+ pc4.dim("Learn more: ") + pc4.blue("https://github.com/izi-noir/izi-noir")
1530
1679
  );
1531
1680
  console.log();
1532
1681
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-izi-noir",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "CLI to scaffold IZI-NOIR ZK projects",
5
5
  "type": "module",
6
6
  "bin": {