create-izi-noir 0.2.0 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +181 -35
  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";
@@ -1410,28 +1553,31 @@ async function initCommand(projectName, options) {
1410
1553
  });
1411
1554
  }
1412
1555
  if (!projectOptions) {
1413
- console.log(pc3.yellow("\nOperation cancelled."));
1556
+ console.log(pc4.yellow("\nOperation cancelled."));
1414
1557
  process.exit(0);
1415
1558
  }
1416
1559
  const projectDir = path2.resolve(process.cwd(), projectOptions.projectName);
1417
1560
  if (await directoryExists(projectDir)) {
1418
1561
  if (!await isDirectoryEmpty(projectDir)) {
1419
1562
  console.log(
1420
- pc3.red(`
1563
+ pc4.red(`
1421
1564
  Error: Directory "${projectOptions.projectName}" already exists and is not empty.`)
1422
1565
  );
1423
1566
  process.exit(1);
1424
1567
  }
1425
1568
  }
1426
1569
  console.log();
1427
- const spinner = createSpinner("Creating project structure...");
1428
- spinner.start();
1570
+ const progress = createProgressReporter();
1429
1571
  try {
1430
- await createProjectStructure(projectDir, projectOptions);
1431
- spinner.stop(true);
1572
+ await progress.startThinking();
1573
+ await new Promise((r) => setTimeout(r, 800));
1574
+ progress.stopThinking();
1575
+ console.log(pc4.bold("\n Scaffolding your ZK project...\n"));
1576
+ await createProjectStructure(projectDir, projectOptions, progress);
1577
+ progress.showSuccess("Project structure created");
1432
1578
  } catch (error) {
1433
- spinner.stop(false);
1434
- console.error(pc3.red("\nFailed to create project structure:"), error);
1579
+ progress.showError("Failed to create project structure");
1580
+ console.error(pc4.red("\n"), error);
1435
1581
  process.exit(1);
1436
1582
  }
1437
1583
  if (!projectOptions.skipGit) {
@@ -1442,28 +1588,28 @@ Error: Directory "${projectOptions.projectName}" already exists and is not empty
1442
1588
  gitSpinner.stop(true);
1443
1589
  } catch {
1444
1590
  gitSpinner.stop(false);
1445
- console.log(pc3.yellow(" Warning: Failed to initialize git repository"));
1591
+ console.log(pc4.yellow(" Warning: Failed to initialize git repository"));
1446
1592
  }
1447
1593
  }
1448
1594
  if (!projectOptions.skipInstall) {
1449
- const installSpinner = createSpinner("Installing dependencies...");
1450
- installSpinner.start();
1595
+ const installProgress = createInstallProgress();
1596
+ installProgress.start();
1451
1597
  try {
1452
1598
  execSync("npm install", { cwd: projectDir, stdio: "ignore" });
1453
- installSpinner.stop(true);
1599
+ installProgress.stop(true);
1454
1600
  } catch {
1455
- installSpinner.stop(false);
1456
- console.log(pc3.yellow(' Warning: Failed to install dependencies. Run "npm install" manually.'));
1601
+ installProgress.stop(false);
1602
+ console.log(pc4.yellow(' Run "npm install" manually.'));
1457
1603
  }
1458
1604
  }
1459
1605
  printSuccessMessage(projectOptions);
1460
1606
  }
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"));
1607
+ async function createProjectStructure(projectDir, options, progress) {
1608
+ const dirs = ["circuits", "src", "src/components", "src/lib", "public"];
1609
+ for (const dir of dirs) {
1610
+ await ensureDir(path2.join(projectDir, dir));
1611
+ await progress.reportDirectory(dir);
1612
+ }
1467
1613
  const files = [
1468
1614
  // Root config files
1469
1615
  ["package.json", generatePackageJson(options)],
@@ -1499,34 +1645,34 @@ async function createProjectStructure(projectDir, options) {
1499
1645
  }
1500
1646
  files.push(["circuits/index.ts", generateCircuitsIndex(options.template)]);
1501
1647
  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
- );
1648
+ for (let i = 0; i < files.length; i++) {
1649
+ const [relativePath, content] = files[i];
1650
+ await writeFile(path2.join(projectDir, relativePath), content);
1651
+ await progress.reportFile(relativePath, i === files.length - 1);
1652
+ }
1507
1653
  }
1508
1654
  function printSuccessMessage(options) {
1509
1655
  console.log();
1510
- console.log(pc3.green("\u2713") + " Project created successfully!");
1656
+ console.log(pc4.green("\u2713") + " Project created successfully!");
1511
1657
  console.log();
1512
1658
  console.log("Next steps:");
1513
1659
  console.log();
1514
- console.log(pc3.cyan(` cd ${options.projectName}`));
1660
+ console.log(pc4.cyan(` cd ${options.projectName}`));
1515
1661
  if (options.skipInstall) {
1516
- console.log(pc3.cyan(" npm install"));
1662
+ console.log(pc4.cyan(" npm install"));
1517
1663
  }
1518
- console.log(pc3.cyan(" npm run dev"));
1664
+ console.log(pc4.cyan(" npm run dev"));
1519
1665
  console.log();
1520
- console.log("Then open " + pc3.blue("http://localhost:5173") + " in your browser.");
1666
+ console.log("Then open " + pc4.blue("http://localhost:5173") + " in your browser.");
1521
1667
  console.log();
1522
1668
  console.log("To add circuits:");
1523
1669
  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"));
1670
+ console.log(pc4.dim(" 1. Create a new circuit in circuits/*.ts"));
1671
+ console.log(pc4.dim(" 2. Export it from circuits/index.ts"));
1672
+ console.log(pc4.dim(" 3. Add it to CIRCUITS array in src/App.tsx"));
1527
1673
  console.log();
1528
1674
  console.log(
1529
- pc3.dim("Learn more: ") + pc3.blue("https://github.com/izi-noir/izi-noir")
1675
+ pc4.dim("Learn more: ") + pc4.blue("https://github.com/izi-noir/izi-noir")
1530
1676
  );
1531
1677
  console.log();
1532
1678
  }
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.1",
4
4
  "description": "CLI to scaffold IZI-NOIR ZK projects",
5
5
  "type": "module",
6
6
  "bin": {