create-vidra-app 0.1.5 → 0.1.6

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 (3) hide show
  1. package/dist/cli.js +464 -204
  2. package/dist/index.js +136 -56
  3. package/package.json +10 -1
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  // src/index.ts
2
2
  import prompts2 from "prompts";
3
- import chalk3 from "chalk";
4
3
  import fs2 from "fs-extra";
5
4
  import path2 from "path";
6
5
  import { randomUUID } from "crypto";
@@ -26,7 +25,17 @@ var parseArgs = (argv) => {
26
25
  const arg = argv[i];
27
26
  if (arg.startsWith("--")) {
28
27
  const [key, val] = arg.slice(2).split("=");
29
- args[key] = val ?? argv[++i] ?? true;
28
+ if (val !== void 0) {
29
+ args[key] = val;
30
+ continue;
31
+ }
32
+ const next = argv[i + 1];
33
+ if (next !== void 0 && !next.startsWith("--")) {
34
+ args[key] = next;
35
+ i++;
36
+ } else {
37
+ args[key] = true;
38
+ }
30
39
  } else {
31
40
  args._.push(arg);
32
41
  }
@@ -36,10 +45,53 @@ var parseArgs = (argv) => {
36
45
 
37
46
  // src/exec.ts
38
47
  import { execSync } from "child_process";
48
+
49
+ // src/theme.ts
39
50
  import chalk from "chalk";
40
- var toText = (value) => {
41
- if (value == null) return "";
42
- return Buffer.isBuffer(value) ? value.toString() : value;
51
+ var lime = chalk.hex("#c8f751");
52
+ var value = chalk.hex("#e8e8ec");
53
+ var dim = chalk.hex("#7a7a86");
54
+ var amber = chalk.hex("#ffcf5c");
55
+ var green = chalk.hex("#86d98f");
56
+ var red = chalk.hex("#ff8585");
57
+ var slate = chalk.hex("#a9b0bd");
58
+ var uiColor = chalk.hex("#6fd3e0");
59
+ var hostColor = chalk.hex("#a48ce8");
60
+ var GLYPH_CHAR = {
61
+ done: "\u2713",
62
+ active: "\u25B8",
63
+ error: "\u2717",
64
+ manual: "?",
65
+ plan: "\u25C6",
66
+ skip: "\u2298"
67
+ };
68
+ var GLYPH_COLOR = {
69
+ done: green,
70
+ active: lime,
71
+ error: red,
72
+ manual: amber,
73
+ plan: slate,
74
+ skip: slate
75
+ };
76
+ var glyph = (name) => GLYPH_COLOR[name](GLYPH_CHAR[name]);
77
+ var wordmark = () => lime("vidra");
78
+ var kv = (label, val, width = 9) => ` ${dim(label.padEnd(width))} ${value(val)}`;
79
+ var row = (opts) => {
80
+ const parts = [` ${glyph(opts.glyph)}`];
81
+ if (opts.label !== void 0) {
82
+ const padded = opts.labelWidth ? opts.label.padEnd(opts.labelWidth) : opts.label;
83
+ parts.push(value(padded));
84
+ }
85
+ if (opts.detail) parts.push(opts.detail);
86
+ return parts.join(" ");
87
+ };
88
+ var footer = (content) => ` ${content}`;
89
+ var fixLine = (cmd, label = "fix:") => ` ${amber(label)} ${lime(cmd)}`;
90
+
91
+ // src/exec.ts
92
+ var toText = (value2) => {
93
+ if (value2 == null) return "";
94
+ return Buffer.isBuffer(value2) ? value2.toString() : value2;
43
95
  };
44
96
  var formatProcessError = (error) => {
45
97
  const err = error;
@@ -50,8 +102,8 @@ var exec = (cmd, cwd) => {
50
102
  try {
51
103
  execSync(cmd, { cwd, stdio: "pipe" });
52
104
  } catch (e) {
53
- console.error(chalk.red(` Command failed: ${cmd}`));
54
- console.error(chalk.dim(formatProcessError(e)));
105
+ console.error(row({ glyph: "error", detail: dim(`command failed: ${cmd}`) }));
106
+ console.error(dim(formatProcessError(e)));
55
107
  process.exit(1);
56
108
  }
57
109
  };
@@ -123,7 +175,6 @@ var applyReplacements = (str, replacements) => {
123
175
  // src/doctor.ts
124
176
  import { execFileSync } from "child_process";
125
177
  import prompts from "prompts";
126
- import chalk2 from "chalk";
127
178
  var DOTNET = process.platform === "win32" ? "dotnet.exe" : "dotnet";
128
179
  var MAUI_DOCS = "https://learn.microsoft.com/dotnet/maui/get-started/installation";
129
180
  var bufToStr = (v) => v == null ? "" : Buffer.isBuffer(v) ? v.toString() : v;
@@ -186,11 +237,16 @@ var isInteractive = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
186
237
  var installWorkload = (csprojPath) => {
187
238
  const args = csprojPath ? ["workload", "restore", csprojPath] : ["workload", "install", "maui"];
188
239
  console.log();
189
- console.log(` ${chalk2.dim(`Running: ${DOTNET} ${args.join(" ")}`)}`);
190
240
  console.log(
191
- ` ${chalk2.dim(
192
- "This can download several hundred MB and take a few minutes."
193
- )}`
241
+ row({
242
+ glyph: "active",
243
+ detail: `${dim("running")} ${value(`${DOTNET} ${args.join(" ")}`)}`
244
+ })
245
+ );
246
+ console.log(
247
+ footer(
248
+ dim("this can download several hundred MB and take a few minutes.")
249
+ )
194
250
  );
195
251
  console.log();
196
252
  try {
@@ -198,13 +254,15 @@ var installWorkload = (csprojPath) => {
198
254
  return true;
199
255
  } catch {
200
256
  console.error();
201
- console.error(` ${chalk2.red("Workload install failed.")}`);
257
+ console.error(row({ glyph: "error", label: "workload install failed" }));
202
258
  console.error(
203
- ` ${chalk2.dim(
204
- "If this is a permissions error, your SDK is in a system location and needs elevation:"
205
- )}`
259
+ footer(
260
+ dim(
261
+ "if this is a permissions error, your SDK is in a system location and needs elevation:"
262
+ )
263
+ )
206
264
  );
207
- console.error(` ${chalk2.cyan("sudo dotnet workload install maui")}`);
265
+ console.error(fixLine("sudo dotnet workload install maui"));
208
266
  console.error();
209
267
  return false;
210
268
  }
@@ -213,9 +271,15 @@ var ensureMauiWorkload = async (opts = {}) => {
213
271
  const dotnet = checkDotnetSdk();
214
272
  if (dotnet.status === "missing") {
215
273
  console.log();
216
- console.log(` ${chalk2.yellow("!")} ${dotnet.name} \u2014 ${dotnet.detail}`);
274
+ console.log(
275
+ row({
276
+ glyph: "error",
277
+ label: dotnet.name,
278
+ detail: dotnet.detail ? dim(dotnet.detail) : void 0
279
+ })
280
+ );
217
281
  if (dotnet.fix) {
218
- console.log(` ${chalk2.dim("fix:")} ${chalk2.cyan(dotnet.fix)}`);
282
+ console.log(fixLine(dotnet.fix));
219
283
  }
220
284
  return false;
221
285
  }
@@ -223,7 +287,11 @@ var ensureMauiWorkload = async (opts = {}) => {
223
287
  if (isMauiWorkloadInstalled()) return true;
224
288
  console.log();
225
289
  console.log(
226
- ` ${chalk2.yellow("!")} The .NET MAUI workload is required but not installed.`
290
+ row({
291
+ glyph: "error",
292
+ label: ".NET MAUI workload",
293
+ detail: dim("required but not installed")
294
+ })
227
295
  );
228
296
  const interactive = opts.interactive ?? isInteractive();
229
297
  if (interactive) {
@@ -241,20 +309,25 @@ var ensureMauiWorkload = async (opts = {}) => {
241
309
  }
242
310
  if (install) {
243
311
  if (installWorkload(opts.csprojPath) && isMauiWorkloadInstalled()) {
244
- console.log(` ${chalk2.green("\u2713")} MAUI workload installed.`);
312
+ console.log(
313
+ row({
314
+ glyph: "done",
315
+ label: ".NET MAUI workload",
316
+ detail: dim("installed")
317
+ })
318
+ );
245
319
  return true;
246
320
  }
247
321
  return false;
248
322
  }
249
323
  }
250
- console.log(
251
- ` ${chalk2.dim("run:")} ${chalk2.cyan("dotnet workload install maui")}`
252
- );
253
- console.log(` ${chalk2.dim("docs:")} ${chalk2.cyan(MAUI_DOCS)}`);
324
+ console.log(fixLine("dotnet workload install maui", "run:"));
325
+ console.log(fixLine(MAUI_DOCS, "docs:"));
254
326
  return false;
255
327
  };
256
328
 
257
329
  // src/index.ts
330
+ var note = (label, body) => ` ${dim(label.padEnd(7))} ${body}`;
258
331
  var __dirname = path2.dirname(fileURLToPath(import.meta.url));
259
332
  var CLI_ROOT = path2.resolve(__dirname, "..");
260
333
  var TEMPLATES_DIR = path2.join(CLI_ROOT, "templates");
@@ -266,8 +339,9 @@ var VIDRA_VERSION = "0.1.0";
266
339
  var SDK_VERSION = "0.1.0";
267
340
  var main = async () => {
268
341
  console.log();
269
- console.log(chalk3.bold(" create-vidra-app"));
270
- console.log(chalk3.dim(" Scaffold a new Vidra application\n"));
342
+ console.log(` create-${lime("vidra")}-app`);
343
+ console.log(footer(dim("scaffold a new vidra application")));
344
+ console.log();
271
345
  const args = parseArgs(process.argv);
272
346
  let projectDir = args._[0];
273
347
  let appId = args["app-id"];
@@ -303,19 +377,20 @@ var main = async () => {
303
377
  }
304
378
  const root = path2.resolve(projectDir);
305
379
  if (fs2.existsSync(root) && fs2.readdirSync(root).length > 0) {
380
+ console.error();
306
381
  console.error(
307
- chalk3.red(
308
- `
309
- Directory "${projectDir}" already exists and is not empty.
310
- `
311
- )
382
+ row({
383
+ glyph: "error",
384
+ detail: dim(`directory "${projectDir}" already exists and is not empty`)
385
+ })
312
386
  );
387
+ console.error();
313
388
  process.exit(1);
314
389
  }
315
390
  console.log();
316
- console.log(` ${chalk3.dim("Project:")} ${chalk3.cyan(projectName)}`);
317
- console.log(` ${chalk3.dim("Directory:")} ${chalk3.cyan(root)}`);
318
- console.log(` ${chalk3.dim("App ID:")} ${chalk3.cyan(appId)}`);
391
+ console.log(kv("project", projectName));
392
+ console.log(kv("directory", root));
393
+ console.log(kv("app id", appId));
319
394
  console.log();
320
395
  const isMonorepo = fs2.existsSync(path2.join(LOCAL_SDK_DIR, "package.json"));
321
396
  const localFeedExists = isMonorepo && fs2.existsSync(LOCAL_FEED_DIR);
@@ -335,42 +410,49 @@ var main = async () => {
335
410
  };
336
411
  const templateDir = path2.join(TEMPLATES_DIR, "react-vite");
337
412
  await scaffoldDir(templateDir, root, replacements);
338
- console.log(chalk3.dim(" Creating solution..."));
413
+ console.log(row({ glyph: "active", detail: dim("creating solution\u2026") }));
339
414
  exec(`dotnet new sln -n ${projectName} --force`, root);
340
415
  const slnFile = fs2.existsSync(path2.join(root, `${projectName}.slnx`)) ? `${projectName}.slnx` : `${projectName}.sln`;
341
416
  exec(
342
417
  `dotnet sln ${slnFile} add src/${projectName}.Host/${projectName}.Host.csproj`,
343
418
  root
344
419
  );
345
- console.log(chalk3.dim(" Installing npm dependencies..."));
420
+ console.log(row({ glyph: "active", detail: dim("installing dependencies\u2026") }));
346
421
  const uiDir = path2.join(root, "ui");
347
422
  const rootNpmOk = tryExec("npm install", root);
348
423
  const uiNpmOk = tryExec("npm install", uiDir);
349
424
  const npmOk = rootNpmOk && uiNpmOk;
350
425
  console.log();
351
- console.log(chalk3.green(" Done! ") + "Your Vidra app is ready.\n");
426
+ console.log(
427
+ row({
428
+ glyph: "done",
429
+ detail: `${dim("your")} ${wordmark()} ${dim("app is ready")}`
430
+ })
431
+ );
432
+ console.log();
352
433
  if (localFeedExists) {
353
- console.log(
354
- chalk3.dim(" NuGet:") + " local feed \u2192 " + chalk3.cyan(LOCAL_FEED_DIR)
355
- );
434
+ console.log(note("nuget", `${dim("local feed \u2192")} ${value(LOCAL_FEED_DIR)}`));
356
435
  } else if (isMonorepo) {
357
436
  console.log(
358
- chalk3.yellow(" Note: ") + "Local NuGet feed not found. Run " + chalk3.cyan("./pack-local.sh") + " in the Vidra repo, then update NuGet.Config."
437
+ row({
438
+ glyph: "manual",
439
+ detail: `${dim("local NuGet feed not found. run")} ${lime("./pack-local.sh")} ${dim("in the vidra repo, then update NuGet.Config.")}`
440
+ })
359
441
  );
360
442
  }
361
443
  if (isMonorepo) {
362
- console.log(
363
- chalk3.dim(" npm: ") + " @vidra-dev/sdk \u2192 " + chalk3.cyan(LOCAL_SDK_DIR)
364
- );
365
- console.log(
366
- chalk3.dim(" npm: ") + " create-vidra-app \u2192 " + chalk3.cyan(LOCAL_CLI_DIR)
367
- );
444
+ console.log(note("npm", `${dim("@vidra-dev/sdk \u2192")} ${value(LOCAL_SDK_DIR)}`));
445
+ console.log(note("npm", `${dim("create-vidra-app \u2192")} ${value(LOCAL_CLI_DIR)}`));
368
446
  }
369
447
  console.log();
370
448
  if (!npmOk) {
371
449
  console.log(
372
- chalk3.yellow(" Note: ") + "`npm install` had errors. Re-run " + chalk3.cyan("npm install") + " in the project root and in " + chalk3.cyan("ui/") + " to retry.\n"
450
+ row({
451
+ glyph: "manual",
452
+ detail: `${dim("npm install had errors. re-run")} ${lime("npm install")} ${dim("in the project root and in")} ${value("ui/")} ${dim("to retry.")}`
453
+ })
373
454
  );
455
+ console.log();
374
456
  }
375
457
  const hostCsproj = path2.join(
376
458
  root,
@@ -379,21 +461,19 @@ var main = async () => {
379
461
  `${projectName}.Host.csproj`
380
462
  );
381
463
  const prereqsReady = await ensureMauiWorkload({ csprojPath: hostCsproj });
382
- console.log(chalk3.bold(" Next steps:\n"));
383
- console.log(` cd ${projectDir}`);
464
+ console.log(footer(dim("next steps")));
465
+ console.log(` ${value(`cd ${projectDir}`)}`);
384
466
  console.log(
385
- ` npm run dev ${chalk3.dim("# starts Vite + MAUI host together")}`
467
+ ` ${value("npm run dev")} ${dim("# starts vite + the MAUI host together")}`
386
468
  );
387
469
  if (!prereqsReady) {
388
470
  console.log(
389
- ` ${chalk3.dim("# tip: run")} ${chalk3.cyan(
390
- "vidra doctor"
391
- )} ${chalk3.dim("to verify your setup first")}`
471
+ ` ${dim("tip: run")} ${lime("vidra doctor")} ${dim("to verify your setup first")}`
392
472
  );
393
473
  }
394
474
  console.log();
395
475
  };
396
476
  main().catch((e) => {
397
- console.error(chalk3.red(e.message));
477
+ console.error(row({ glyph: "error", detail: dim(e.message) }));
398
478
  process.exit(1);
399
479
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vidra-app",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Scaffold a new Vidra application (React + .NET MAUI)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,9 +21,18 @@
21
21
  },
22
22
  "keywords": [
23
23
  "vidra",
24
+ "create-vidra-app",
25
+ "dotnet",
26
+ "csharp",
27
+ "dotnet-maui",
24
28
  "maui",
25
29
  "react",
30
+ "vue",
31
+ "svelte",
26
32
  "cross-platform",
33
+ "desktop",
34
+ "electron-alternative",
35
+ "tauri-alternative",
27
36
  "scaffold",
28
37
  "cli"
29
38
  ],