create-vidra-app 0.1.4 → 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.
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,14 +45,65 @@ 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";
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;
95
+ };
96
+ var formatProcessError = (error) => {
97
+ const err = error;
98
+ const combined = [toText(err.stderr), toText(err.stdout)].map((s) => s.trim()).filter((s) => s.length > 0).join("\n").trim();
99
+ return combined.length > 0 ? combined : err.message ?? String(error);
100
+ };
40
101
  var exec = (cmd, cwd) => {
41
102
  try {
42
103
  execSync(cmd, { cwd, stdio: "pipe" });
43
104
  } catch (e) {
44
- const err = e;
45
- console.error(chalk.red(` Command failed: ${cmd}`));
46
- console.error(chalk.dim(err.stderr?.toString() || err.message));
105
+ console.error(row({ glyph: "error", detail: dim(`command failed: ${cmd}`) }));
106
+ console.error(dim(formatProcessError(e)));
47
107
  process.exit(1);
48
108
  }
49
109
  };
@@ -115,7 +175,6 @@ var applyReplacements = (str, replacements) => {
115
175
  // src/doctor.ts
116
176
  import { execFileSync } from "child_process";
117
177
  import prompts from "prompts";
118
- import chalk2 from "chalk";
119
178
  var DOTNET = process.platform === "win32" ? "dotnet.exe" : "dotnet";
120
179
  var MAUI_DOCS = "https://learn.microsoft.com/dotnet/maui/get-started/installation";
121
180
  var bufToStr = (v) => v == null ? "" : Buffer.isBuffer(v) ? v.toString() : v;
@@ -178,11 +237,16 @@ var isInteractive = () => Boolean(process.stdin.isTTY && process.stdout.isTTY);
178
237
  var installWorkload = (csprojPath) => {
179
238
  const args = csprojPath ? ["workload", "restore", csprojPath] : ["workload", "install", "maui"];
180
239
  console.log();
181
- console.log(` ${chalk2.dim(`Running: ${DOTNET} ${args.join(" ")}`)}`);
182
240
  console.log(
183
- ` ${chalk2.dim(
184
- "This can download several hundred MB and take a few minutes."
185
- )}`
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
+ )
186
250
  );
187
251
  console.log();
188
252
  try {
@@ -190,13 +254,15 @@ var installWorkload = (csprojPath) => {
190
254
  return true;
191
255
  } catch {
192
256
  console.error();
193
- console.error(` ${chalk2.red("Workload install failed.")}`);
257
+ console.error(row({ glyph: "error", label: "workload install failed" }));
194
258
  console.error(
195
- ` ${chalk2.dim(
196
- "If this is a permissions error, your SDK is in a system location and needs elevation:"
197
- )}`
259
+ footer(
260
+ dim(
261
+ "if this is a permissions error, your SDK is in a system location and needs elevation:"
262
+ )
263
+ )
198
264
  );
199
- console.error(` ${chalk2.cyan("sudo dotnet workload install maui")}`);
265
+ console.error(fixLine("sudo dotnet workload install maui"));
200
266
  console.error();
201
267
  return false;
202
268
  }
@@ -205,9 +271,15 @@ var ensureMauiWorkload = async (opts = {}) => {
205
271
  const dotnet = checkDotnetSdk();
206
272
  if (dotnet.status === "missing") {
207
273
  console.log();
208
- 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
+ );
209
281
  if (dotnet.fix) {
210
- console.log(` ${chalk2.dim("fix:")} ${chalk2.cyan(dotnet.fix)}`);
282
+ console.log(fixLine(dotnet.fix));
211
283
  }
212
284
  return false;
213
285
  }
@@ -215,7 +287,11 @@ var ensureMauiWorkload = async (opts = {}) => {
215
287
  if (isMauiWorkloadInstalled()) return true;
216
288
  console.log();
217
289
  console.log(
218
- ` ${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
+ })
219
295
  );
220
296
  const interactive = opts.interactive ?? isInteractive();
221
297
  if (interactive) {
@@ -233,20 +309,25 @@ var ensureMauiWorkload = async (opts = {}) => {
233
309
  }
234
310
  if (install) {
235
311
  if (installWorkload(opts.csprojPath) && isMauiWorkloadInstalled()) {
236
- 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
+ );
237
319
  return true;
238
320
  }
239
321
  return false;
240
322
  }
241
323
  }
242
- console.log(
243
- ` ${chalk2.dim("run:")} ${chalk2.cyan("dotnet workload install maui")}`
244
- );
245
- 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:"));
246
326
  return false;
247
327
  };
248
328
 
249
329
  // src/index.ts
330
+ var note = (label, body) => ` ${dim(label.padEnd(7))} ${body}`;
250
331
  var __dirname = path2.dirname(fileURLToPath(import.meta.url));
251
332
  var CLI_ROOT = path2.resolve(__dirname, "..");
252
333
  var TEMPLATES_DIR = path2.join(CLI_ROOT, "templates");
@@ -258,8 +339,9 @@ var VIDRA_VERSION = "0.1.0";
258
339
  var SDK_VERSION = "0.1.0";
259
340
  var main = async () => {
260
341
  console.log();
261
- console.log(chalk3.bold(" create-vidra-app"));
262
- 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();
263
345
  const args = parseArgs(process.argv);
264
346
  let projectDir = args._[0];
265
347
  let appId = args["app-id"];
@@ -295,19 +377,20 @@ var main = async () => {
295
377
  }
296
378
  const root = path2.resolve(projectDir);
297
379
  if (fs2.existsSync(root) && fs2.readdirSync(root).length > 0) {
380
+ console.error();
298
381
  console.error(
299
- chalk3.red(
300
- `
301
- Directory "${projectDir}" already exists and is not empty.
302
- `
303
- )
382
+ row({
383
+ glyph: "error",
384
+ detail: dim(`directory "${projectDir}" already exists and is not empty`)
385
+ })
304
386
  );
387
+ console.error();
305
388
  process.exit(1);
306
389
  }
307
390
  console.log();
308
- console.log(` ${chalk3.dim("Project:")} ${chalk3.cyan(projectName)}`);
309
- console.log(` ${chalk3.dim("Directory:")} ${chalk3.cyan(root)}`);
310
- 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));
311
394
  console.log();
312
395
  const isMonorepo = fs2.existsSync(path2.join(LOCAL_SDK_DIR, "package.json"));
313
396
  const localFeedExists = isMonorepo && fs2.existsSync(LOCAL_FEED_DIR);
@@ -327,42 +410,49 @@ var main = async () => {
327
410
  };
328
411
  const templateDir = path2.join(TEMPLATES_DIR, "react-vite");
329
412
  await scaffoldDir(templateDir, root, replacements);
330
- console.log(chalk3.dim(" Creating solution..."));
413
+ console.log(row({ glyph: "active", detail: dim("creating solution\u2026") }));
331
414
  exec(`dotnet new sln -n ${projectName} --force`, root);
332
415
  const slnFile = fs2.existsSync(path2.join(root, `${projectName}.slnx`)) ? `${projectName}.slnx` : `${projectName}.sln`;
333
416
  exec(
334
417
  `dotnet sln ${slnFile} add src/${projectName}.Host/${projectName}.Host.csproj`,
335
418
  root
336
419
  );
337
- console.log(chalk3.dim(" Installing npm dependencies..."));
420
+ console.log(row({ glyph: "active", detail: dim("installing dependencies\u2026") }));
338
421
  const uiDir = path2.join(root, "ui");
339
422
  const rootNpmOk = tryExec("npm install", root);
340
423
  const uiNpmOk = tryExec("npm install", uiDir);
341
424
  const npmOk = rootNpmOk && uiNpmOk;
342
425
  console.log();
343
- 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();
344
433
  if (localFeedExists) {
345
- console.log(
346
- chalk3.dim(" NuGet:") + " local feed \u2192 " + chalk3.cyan(LOCAL_FEED_DIR)
347
- );
434
+ console.log(note("nuget", `${dim("local feed \u2192")} ${value(LOCAL_FEED_DIR)}`));
348
435
  } else if (isMonorepo) {
349
436
  console.log(
350
- 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
+ })
351
441
  );
352
442
  }
353
443
  if (isMonorepo) {
354
- console.log(
355
- chalk3.dim(" npm: ") + " @vidra-dev/sdk \u2192 " + chalk3.cyan(LOCAL_SDK_DIR)
356
- );
357
- console.log(
358
- chalk3.dim(" npm: ") + " create-vidra-app \u2192 " + chalk3.cyan(LOCAL_CLI_DIR)
359
- );
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)}`));
360
446
  }
361
447
  console.log();
362
448
  if (!npmOk) {
363
449
  console.log(
364
- 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
+ })
365
454
  );
455
+ console.log();
366
456
  }
367
457
  const hostCsproj = path2.join(
368
458
  root,
@@ -371,21 +461,19 @@ var main = async () => {
371
461
  `${projectName}.Host.csproj`
372
462
  );
373
463
  const prereqsReady = await ensureMauiWorkload({ csprojPath: hostCsproj });
374
- console.log(chalk3.bold(" Next steps:\n"));
375
- console.log(` cd ${projectDir}`);
464
+ console.log(footer(dim("next steps")));
465
+ console.log(` ${value(`cd ${projectDir}`)}`);
376
466
  console.log(
377
- ` npm run dev ${chalk3.dim("# starts Vite + MAUI host together")}`
467
+ ` ${value("npm run dev")} ${dim("# starts vite + the MAUI host together")}`
378
468
  );
379
469
  if (!prereqsReady) {
380
470
  console.log(
381
- ` ${chalk3.dim("# tip: run")} ${chalk3.cyan(
382
- "vidra doctor"
383
- )} ${chalk3.dim("to verify your setup first")}`
471
+ ` ${dim("tip: run")} ${lime("vidra doctor")} ${dim("to verify your setup first")}`
384
472
  );
385
473
  }
386
474
  console.log();
387
475
  };
388
476
  main().catch((e) => {
389
- console.error(chalk3.red(e.message));
477
+ console.error(row({ glyph: "error", detail: dim(e.message) }));
390
478
  process.exit(1);
391
479
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vidra-app",
3
- "version": "0.1.4",
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
  ],
@@ -5,8 +5,8 @@
5
5
  "build": "vidra build",
6
6
  "dev": "vidra dev",
7
7
  "dev:ui": "npm run dev --prefix ui",
8
- "dev:host:macos": "dotnet build -t:Run -f net10.0-maccatalyst src/{{projectName}}.Host/{{projectName}}.Host.csproj",
9
- "dev:host:windows": "dotnet build -t:Run -f net10.0-windows10.0.19041.0 src/{{projectName}}.Host/{{projectName}}.Host.csproj"
8
+ "dev:host:macos": "vidra run --target macos",
9
+ "dev:host:windows": "vidra run --target windows"
10
10
  },
11
11
  "devDependencies": {
12
12
  "create-vidra-app": "{{cliVersion}}"