create-vuetify 2.7.3 → 2.8.0

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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/index.ts
2
2
  import { dirname as dirname3, join as join4, resolve as resolve6 } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { mkdirSync as mkdirSync2, rmSync, writeFileSync as writeFileSync2, existsSync as existsSync5 } from "node:fs";
4
+ import { mkdirSync as mkdirSync2, rmSync, writeFileSync as writeFileSync2, existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
5
5
 
6
6
  // src/utils/prompts.ts
7
7
  import { join as join2, resolve as resolve3 } from "node:path";
@@ -774,14 +774,14 @@ async function executeCommand(command, args, options = {}) {
774
774
  var NO_PACKAGE_MANAGER_DETECTED_ERROR_MSG = "No package manager auto-detected.";
775
775
  async function resolveOperationOptions(options = {}) {
776
776
  const cwd2 = options.cwd || process.cwd();
777
- const env = { ...process.env, ...options.env };
777
+ const env2 = { ...process.env, ...options.env };
778
778
  const packageManager2 = (typeof options.packageManager === "string" ? packageManagers.find((pm) => pm.name === options.packageManager) : options.packageManager) || await detectPackageManager(options.cwd || process.cwd());
779
779
  if (!packageManager2) {
780
780
  throw new Error(NO_PACKAGE_MANAGER_DETECTED_ERROR_MSG);
781
781
  }
782
782
  return {
783
783
  cwd: cwd2,
784
- env,
784
+ env: env2,
785
785
  silent: options.silent ?? false,
786
786
  packageManager: packageManager2,
787
787
  dev: options.dev ?? false,
@@ -1053,6 +1053,16 @@ async function initPrompts(context) {
1053
1053
  { title: "Nuxt Recommended (Everything from Default. Enables auto importing & layouts)", value: "nuxt-essentials" }
1054
1054
  ]
1055
1055
  },
1056
+ {
1057
+ name: "vuetifyVersion",
1058
+ type: context.vuetifyVersion ? null : "select",
1059
+ message: "Which Vuetify version would you like to use?",
1060
+ initial: 0,
1061
+ choices: [
1062
+ { title: "Vuetify 3 (Stable)", value: "3.x" },
1063
+ { title: "Vuetify 4 (Beta)", value: "4.x" }
1064
+ ]
1065
+ },
1056
1066
  {
1057
1067
  name: "useTypeScript",
1058
1068
  type: (usePreset) => {
@@ -1175,6 +1185,7 @@ function resolveNonInteractiveContext(context) {
1175
1185
  const useNuxtModule = context.useNuxtModule;
1176
1186
  const useNuxtSSR = context.useNuxtSSR;
1177
1187
  const useNuxtSSRClientHints = context.useNuxtSSRClientHints;
1188
+ const vuetifyVersion = context.vuetifyVersion;
1178
1189
  return {
1179
1190
  cwd: context.cwd,
1180
1191
  projectName,
@@ -1185,14 +1196,15 @@ function resolveNonInteractiveContext(context) {
1185
1196
  usePreset,
1186
1197
  useNuxtModule: useNuxtModule || false,
1187
1198
  useNuxtSSR: useNuxtSSR || false,
1188
- useNuxtSSRClientHints: useNuxtSSRClientHints || false
1199
+ useNuxtSSRClientHints: useNuxtSSRClientHints || false,
1200
+ vuetifyVersion: vuetifyVersion || "3.x"
1189
1201
  };
1190
1202
  }
1191
1203
 
1192
1204
  // package.json
1193
1205
  var package_default = {
1194
1206
  name: "create-vuetify",
1195
- version: "2.7.3",
1207
+ version: "2.8.0",
1196
1208
  author: "Elijah Kotyluk <elijah@elijahkotyluk.com>",
1197
1209
  license: "MIT",
1198
1210
  type: "module",
@@ -1241,10 +1253,11 @@ var package_default = {
1241
1253
  release: "bumpp"
1242
1254
  },
1243
1255
  dependencies: {
1256
+ consola: "^3.4.2",
1244
1257
  kolorist: "^1.8.0",
1245
1258
  magicast: "^0.3.5",
1246
1259
  minimist: "^1.2.8",
1247
- "package-manager-detector": "^1.3.0",
1260
+ "package-manager-detector": "^1.6.0",
1248
1261
  prompts: "^2.4.2",
1249
1262
  tinyexec: "^1.0.1",
1250
1263
  "validate-npm-package-name": "^6.0.2"
@@ -1261,7 +1274,7 @@ var package_default = {
1261
1274
  nypm: "^0.6.2",
1262
1275
  typescript: "^5.9.2"
1263
1276
  },
1264
- packageManager: "pnpm@9.15.9"
1277
+ packageManager: "pnpm@10.26.1"
1265
1278
  };
1266
1279
 
1267
1280
  // src/utils/cli/helpText.ts
@@ -1278,6 +1291,7 @@ Options:
1278
1291
  --nuxt-module Use vuetify-nuxt-module (for Nuxt presets)
1279
1292
  --nuxt-ssr, --ssr Enable Nuxt SSR (for Nuxt presets)
1280
1293
  --nuxt-ssr-client-hints Enable Nuxt SSR Client Hints (for Nuxt presets)
1294
+ --v4 Use Vuetify 4 (Beta)
1281
1295
  -h, --help Show help
1282
1296
  -v, --version Show version
1283
1297
 
@@ -1305,7 +1319,7 @@ import minimist from "minimist";
1305
1319
  var validPresets = ["base", "default", "essentials", "nuxt-base", "nuxt-default", "nuxt-essentials"];
1306
1320
  var validPackageManagers = ["npm", "pnpm", "yarn", "bun", "none"];
1307
1321
  function parseCliArgs(args) {
1308
- const argv = minimist(args, {
1322
+ const argv2 = minimist(args, {
1309
1323
  alias: {
1310
1324
  typescript: ["ts"],
1311
1325
  preset: ["p"],
@@ -1315,6 +1329,7 @@ function parseCliArgs(args) {
1315
1329
  nuxtModule: ["nuxt-module"],
1316
1330
  nuxtSSR: ["nuxt-ssr", "ssr"],
1317
1331
  nuxtSSRClientHints: ["nuxt-ssr-client-hints", "client-hints"],
1332
+ v4: [],
1318
1333
  help: ["h"],
1319
1334
  version: ["v"]
1320
1335
  },
@@ -1325,6 +1340,7 @@ function parseCliArgs(args) {
1325
1340
  "nuxtModule",
1326
1341
  "nuxtSSR",
1327
1342
  "nuxtSSRClientHints",
1343
+ "v4",
1328
1344
  "help",
1329
1345
  "version"
1330
1346
  ],
@@ -1333,25 +1349,26 @@ function parseCliArgs(args) {
1333
1349
  "packageManager"
1334
1350
  ]
1335
1351
  });
1336
- if (argv.preset && !validPresets.includes(argv.preset)) {
1337
- throw new Error(`'${argv.preset}' is not a valid preset. Valid presets are: ${validPresets.join(", ")}.`);
1352
+ if (argv2.preset && !validPresets.includes(argv2.preset)) {
1353
+ throw new Error(`'${argv2.preset}' is not a valid preset. Valid presets are: ${validPresets.join(", ")}.`);
1338
1354
  }
1339
- if (argv.packageManager && !validPackageManagers.includes(argv.packageManager)) {
1340
- throw new Error(`'${argv.packageManager}' is not a valid package manager. Valid options are: ${validPackageManagers.join(", ")}.`);
1355
+ if (argv2.packageManager && !validPackageManagers.includes(argv2.packageManager)) {
1356
+ throw new Error(`'${argv2.packageManager}' is not a valid package manager. Valid options are: ${validPackageManagers.join(", ")}.`);
1341
1357
  }
1342
- const projectName = argv._[0];
1358
+ const projectName = argv2._[0];
1343
1359
  return {
1344
1360
  projectName,
1345
- preset: argv.preset,
1346
- typescript: argv.typescript,
1347
- packageManager: argv.packageManager,
1348
- installDependencies: argv.installDependencies,
1349
- overwrite: argv.overwrite,
1350
- nuxtModule: argv.nuxtModule,
1351
- nuxtSSR: argv.nuxtSSR,
1352
- nuxtSSRClientHints: argv.nuxtSSRClientHints,
1353
- help: argv.help,
1354
- version: argv.version
1361
+ preset: argv2.preset,
1362
+ typescript: argv2.typescript,
1363
+ packageManager: argv2.packageManager,
1364
+ installDependencies: argv2.installDependencies,
1365
+ overwrite: argv2.overwrite,
1366
+ nuxtModule: argv2.nuxtModule,
1367
+ nuxtSSR: argv2.nuxtSSR,
1368
+ nuxtSSRClientHints: argv2.nuxtSSRClientHints,
1369
+ v4: argv2.v4,
1370
+ help: argv2.help,
1371
+ version: argv2.version
1355
1372
  };
1356
1373
  }
1357
1374
  function cliOptionsToContext(cliOptions, cwd2) {
@@ -1365,7 +1382,8 @@ function cliOptionsToContext(cliOptions, cwd2) {
1365
1382
  canOverwrite: cliOptions.overwrite ?? false,
1366
1383
  useNuxtModule: cliOptions.nuxtModule ?? true,
1367
1384
  useNuxtSSR: cliOptions.nuxtSSR ?? true,
1368
- useNuxtSSRClientHints: cliOptions.nuxtSSRClientHints ?? (cliOptions.nuxtModule && cliOptions.nuxtSSR)
1385
+ useNuxtSSRClientHints: cliOptions.nuxtSSRClientHints ?? (cliOptions.nuxtModule && cliOptions.nuxtSSR),
1386
+ vuetifyVersion: cliOptions.v4 ? "4.x" : void 0
1369
1387
  };
1370
1388
  }
1371
1389
 
@@ -1374,90 +1392,8 @@ import { red as red3 } from "kolorist";
1374
1392
 
1375
1393
  // src/utils/banner.ts
1376
1394
  import { blue } from "kolorist";
1377
- function supportsColor() {
1378
- const testText = "test";
1379
- const coloredText = blue(testText);
1380
- return coloredText !== testText;
1381
- }
1382
- function createBanner() {
1383
- if (!supportsColor()) {
1384
- return createPlainBanner();
1385
- }
1386
- return "\x1B[38;2;22;151;246mV\x1B[39m\x1B[38;2;22;147;242mu\x1B[39m\x1B[38;2;22;144;238me\x1B[39m\x1B[38;2;22;140;234mt\x1B[39m\x1B[38;2;23;136;229mi\x1B[39m\x1B[38;2;23;133;225mf\x1B[39m\x1B[38;2;23;129;221my\x1B[39m\x1B[38;2;23;125;217m.\x1B[39m\x1B[38;2;23;121;213mj\x1B[39m\x1B[38;2;23;118;209ms\x1B[39m \x1B[38;2;24;114;204m-\x1B[39m \x1B[38;2;24;110;200mM\x1B[39m\x1B[38;2;24;107;196ma\x1B[39m\x1B[38;2;24;103;192mt\x1B[39m\x1B[38;2;32;110;197me\x1B[39m\x1B[38;2;39;118;202mr\x1B[39m\x1B[38;2;47;125;207mi\x1B[39m\x1B[38;2;54;132;211ma\x1B[39m\x1B[38;2;62;140;216ml\x1B[39m \x1B[38;2;70;147;221mC\x1B[39m\x1B[38;2;77;154;226mo\x1B[39m\x1B[38;2;85;161;231mm\x1B[39m\x1B[38;2;93;169;236mp\x1B[39m\x1B[38;2;100;176;240mo\x1B[39m\x1B[38;2;108;183;245mn\x1B[39m\x1B[38;2;115;191;250me\x1B[39m\x1B[38;2;123;198;255mn\x1B[39m\x1B[38;2;126;199;255mt\x1B[39m \x1B[38;2;129;201;255mF\x1B[39m\x1B[38;2;133;202;255mr\x1B[39m\x1B[38;2;136;204;255ma\x1B[39m\x1B[38;2;139;205;255mm\x1B[39m\x1B[38;2;142;207;255me\x1B[39m\x1B[38;2;145;208;255mw\x1B[39m\x1B[38;2;149;210;255mo\x1B[39m\x1B[38;2;152;211;255mr\x1B[39m\x1B[38;2;155;212;255mk\x1B[39m \x1B[38;2;158;214;255mf\x1B[39m\x1B[38;2;161;215;255mo\x1B[39m\x1B[38;2;164;217;255mr\x1B[39m \x1B[38;2;168;218;255mV\x1B[39m\x1B[38;2;171;220;255mu\x1B[39m\x1B[38;2;174;221;255me\x1B[39m";
1387
- }
1388
- function createPlainBanner() {
1389
- return "Vuetify - Vue Component Framework";
1390
- }
1391
1395
 
1392
- // src/utils/deepMerge.ts
1393
- var isObject = (v) => {
1394
- return v === Object(v) && v !== null && !Array.isArray(v);
1395
- };
1396
- var deepMerge = (...sources) => sources.reduce((acc, curr) => {
1397
- for (const key of Object.keys(curr)) {
1398
- if (Array.isArray(acc[key]) && Array.isArray(curr[key])) {
1399
- acc[key] = Array.from(new Set(acc[key].concat(curr[key])));
1400
- } else if (isObject(acc[key]) && isObject(curr[key])) {
1401
- acc[key] = deepMerge(acc[key], curr[key]);
1402
- } else {
1403
- acc[key] = curr[key];
1404
- }
1405
- }
1406
- return acc;
1407
- }, {});
1408
-
1409
- // src/utils/renderTemplate.ts
1410
- import { copyFileSync, mkdirSync, readdirSync as readdirSync3, readFileSync, statSync, writeFileSync, existsSync as existsSync4 } from "node:fs";
1411
- import { basename as basename2, dirname as dirname2, resolve as resolve5 } from "node:path";
1412
- function mergePkg(source, destination) {
1413
- const target = existsSync4(destination) ? JSON.parse(readFileSync(destination, "utf8")) : {};
1414
- const src = JSON.parse(readFileSync(source, "utf8"));
1415
- const mergedPkg = deepMerge(target, src);
1416
- const keysToSort = ["devDependencies", "dependencies"];
1417
- for (const k of keysToSort) {
1418
- if (mergedPkg[k]) {
1419
- mergedPkg[k] = Object.keys(mergedPkg[k]).toSorted().reduce((a, c) => (a[c] = mergedPkg[k][c], a), {});
1420
- }
1421
- }
1422
- writeFileSync(destination, JSON.stringify(mergedPkg, null, 2) + "\n");
1423
- }
1424
- function renderDirectory(source, destination) {
1425
- mkdirSync(destination, { recursive: true });
1426
- for (const path4 of readdirSync3(source)) {
1427
- renderTemplate(resolve5(source, path4), resolve5(destination, path4));
1428
- }
1429
- }
1430
- function renderFile(source, destination) {
1431
- const filename = basename2(source);
1432
- if (filename.startsWith("_")) {
1433
- destination = resolve5(dirname2(destination), filename.replace("_", "."));
1434
- }
1435
- if (filename === "package.json") {
1436
- mergePkg(source, destination);
1437
- } else {
1438
- copyFileSync(source, destination);
1439
- }
1440
- }
1441
- function renderTemplate(source, destination) {
1442
- if (statSync(source).isDirectory()) {
1443
- renderDirectory(source, destination);
1444
- } else {
1445
- renderFile(source, destination);
1446
- }
1447
- }
1448
-
1449
- // src/utils/nuxt/renderNuxtTemplate.ts
1450
- import fs3 from "node:fs";
1451
- import path3 from "node:path";
1452
- import { spawnSync as spawnSync2 } from "node:child_process";
1453
-
1454
- // src/utils/nuxt/utils.ts
1455
- import process2 from "node:process";
1456
- import path from "node:path";
1457
- import { spawnSync } from "node:child_process";
1458
- import fs from "node:fs";
1459
-
1460
- // node_modules/.pnpm/package-manager-detector@1.3.0/node_modules/package-manager-detector/dist/commands.mjs
1396
+ // node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/commands.mjs
1461
1397
  function dashDashArg(agent, agentCommand) {
1462
1398
  return (args) => {
1463
1399
  if (args.length > 1) {
@@ -1481,6 +1417,7 @@ var npm = {
1481
1417
  "add": ["npm", "i", 0],
1482
1418
  "upgrade": ["npm", "update", 0],
1483
1419
  "upgrade-interactive": null,
1420
+ "dedupe": ["npm", "dedupe", 0],
1484
1421
  "execute": ["npx", 0],
1485
1422
  "execute-local": ["npx", 0],
1486
1423
  "uninstall": ["npm", "uninstall", 0],
@@ -1495,6 +1432,7 @@ var yarn2 = {
1495
1432
  "add": ["yarn", "add", 0],
1496
1433
  "upgrade": ["yarn", "upgrade", 0],
1497
1434
  "upgrade-interactive": ["yarn", "upgrade-interactive", 0],
1435
+ "dedupe": null,
1498
1436
  "execute": ["npx", 0],
1499
1437
  "execute-local": dashDashArg("yarn", "exec"),
1500
1438
  "uninstall": ["yarn", "remove", 0],
@@ -1505,6 +1443,7 @@ var yarnBerry = {
1505
1443
  "frozen": ["yarn", "install", "--immutable", 0],
1506
1444
  "upgrade": ["yarn", "up", 0],
1507
1445
  "upgrade-interactive": ["yarn", "up", "-i", 0],
1446
+ "dedupe": ["yarn", "dedupe", 0],
1508
1447
  "execute": ["yarn", "dlx", 0],
1509
1448
  "execute-local": ["yarn", "exec", 0],
1510
1449
  // Yarn 2+ removed 'global', see https://github.com/yarnpkg/berry/issues/821
@@ -1520,6 +1459,7 @@ var pnpm2 = {
1520
1459
  "add": ["pnpm", "add", 0],
1521
1460
  "upgrade": ["pnpm", "update", 0],
1522
1461
  "upgrade-interactive": ["pnpm", "update", "-i", 0],
1462
+ "dedupe": ["pnpm", "dedupe", 0],
1523
1463
  "execute": ["pnpm", "dlx", 0],
1524
1464
  "execute-local": ["pnpm", "exec", 0],
1525
1465
  "uninstall": ["pnpm", "remove", 0],
@@ -1533,7 +1473,8 @@ var bun = {
1533
1473
  "global": ["bun", "add", "-g", 0],
1534
1474
  "add": ["bun", "add", 0],
1535
1475
  "upgrade": ["bun", "update", 0],
1536
- "upgrade-interactive": ["bun", "update", 0],
1476
+ "upgrade-interactive": ["bun", "update", "-i", 0],
1477
+ "dedupe": null,
1537
1478
  "execute": ["bun", "x", 0],
1538
1479
  "execute-local": ["bun", "x", 0],
1539
1480
  "uninstall": ["bun", "remove", 0],
@@ -1548,6 +1489,7 @@ var deno = {
1548
1489
  "add": ["deno", "add", 0],
1549
1490
  "upgrade": ["deno", "outdated", "--update", 0],
1550
1491
  "upgrade-interactive": ["deno", "outdated", "--update", 0],
1492
+ "dedupe": null,
1551
1493
  "execute": denoExecute(),
1552
1494
  "execute-local": ["deno", "task", "--eval", 0],
1553
1495
  "uninstall": ["deno", "remove", 0],
@@ -1584,80 +1526,7 @@ function constructCommand(value, args) {
1584
1526
  };
1585
1527
  }
1586
1528
 
1587
- // src/utils/nuxt/utils.ts
1588
- function detectPkgInfo() {
1589
- const userAgent2 = process2.env.npm_config_user_agent;
1590
- if (!userAgent2) {
1591
- return void 0;
1592
- }
1593
- const pkgSpec = userAgent2.split(" ")[0];
1594
- const pkgSpecArr = pkgSpec.split("/");
1595
- return {
1596
- name: pkgSpecArr[0],
1597
- version: pkgSpecArr[1]
1598
- };
1599
- }
1600
- function addPackageObject(key, entry, pkg, sort = true) {
1601
- pkg[key] ??= {};
1602
- if (!sort) {
1603
- for (const [name, value] of entry) {
1604
- pkg[key][name] = value;
1605
- }
1606
- return;
1607
- }
1608
- const entries = Object.entries(pkg[key]);
1609
- pkg[key] = {};
1610
- for (const [name, value] of entry) {
1611
- entries.push([name, value]);
1612
- }
1613
- for (const [k, v] of entries.toSorted(([a], [b]) => a.localeCompare(b))) {
1614
- pkg[key][k] = v;
1615
- }
1616
- }
1617
- function runCommand(pmDetection, command, args, cwd2) {
1618
- let runCommand2 = "npm";
1619
- let runArgs = [command];
1620
- if (pmDetection) {
1621
- const prepare = resolveCommand(pmDetection.name, command, args);
1622
- runCommand2 = prepare.command;
1623
- runArgs = prepare.args;
1624
- }
1625
- const run2 = spawnSync(
1626
- runCommand2,
1627
- runArgs.filter(Boolean),
1628
- {
1629
- cwd: cwd2,
1630
- stdio: ["inherit", "inherit", "pipe"],
1631
- shell: true
1632
- }
1633
- );
1634
- if (run2.error) {
1635
- throw run2.error;
1636
- }
1637
- }
1638
- function editFile(file, callback, destination) {
1639
- const content = fs.readFileSync(file, "utf8");
1640
- fs.writeFileSync(destination ?? file, callback(content), "utf8");
1641
- }
1642
- function getPaths(rootPath, templateDir) {
1643
- return [path.join(rootPath, "app"), templateDir];
1644
- }
1645
-
1646
- // src/utils/nuxt/versions.ts
1647
- var versions = {
1648
- "vuetify": "^3.9.1",
1649
- "typescript": "^5.8.3",
1650
- "vue-tsc": "^3.0.1",
1651
- "sass-embedded": "^1.89.2",
1652
- "@vuetify/loader-shared": "^2.1.0",
1653
- "vite-plugin-vuetify": "^2.1.1",
1654
- "vuetify-nuxt-module": "^0.18.7",
1655
- "upath": "^2.0.1",
1656
- "@mdi/font": "^7.4.47",
1657
- "@nuxt/fonts": "^0.11.4"
1658
- };
1659
-
1660
- // node_modules/.pnpm/package-manager-detector@1.3.0/node_modules/package-manager-detector/dist/constants.mjs
1529
+ // node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/constants.mjs
1661
1530
  var AGENTS = [
1662
1531
  "npm",
1663
1532
  "yarn",
@@ -1693,38 +1562,47 @@ var INSTALL_METADATA = {
1693
1562
  "bun.lockb": "bun"
1694
1563
  };
1695
1564
 
1696
- // node_modules/.pnpm/package-manager-detector@1.3.0/node_modules/package-manager-detector/dist/detect.mjs
1697
- import fs2 from "node:fs/promises";
1698
- import path2 from "node:path";
1699
- import process3 from "node:process";
1565
+ // node_modules/.pnpm/package-manager-detector@1.6.0/node_modules/package-manager-detector/dist/detect.mjs
1566
+ import fs from "node:fs/promises";
1567
+ import path from "node:path";
1568
+ import process2 from "node:process";
1700
1569
  async function pathExists(path22, type) {
1701
1570
  try {
1702
- const stat = await fs2.stat(path22);
1571
+ const stat = await fs.stat(path22);
1703
1572
  return type === "file" ? stat.isFile() : stat.isDirectory();
1704
1573
  } catch {
1705
1574
  return false;
1706
1575
  }
1707
1576
  }
1708
- function* lookup(cwd2 = process3.cwd()) {
1709
- let directory = path2.resolve(cwd2);
1710
- const { root } = path2.parse(directory);
1577
+ function getUserAgent() {
1578
+ const userAgent2 = process2.env.npm_config_user_agent;
1579
+ if (!userAgent2) {
1580
+ return null;
1581
+ }
1582
+ const name = userAgent2.split("/")[0];
1583
+ return AGENTS.includes(name) ? name : null;
1584
+ }
1585
+ function* lookup(cwd2 = process2.cwd()) {
1586
+ let directory = path.resolve(cwd2);
1587
+ const { root } = path.parse(directory);
1711
1588
  while (directory && directory !== root) {
1712
1589
  yield directory;
1713
- directory = path2.dirname(directory);
1590
+ directory = path.dirname(directory);
1714
1591
  }
1715
1592
  }
1716
- async function parsePackageJson(filepath, onUnknown) {
1717
- return !filepath || !pathExists(filepath, "file") ? null : await handlePackageManager(filepath, onUnknown);
1593
+ async function parsePackageJson(filepath, options) {
1594
+ if (!filepath || !await pathExists(filepath, "file"))
1595
+ return null;
1596
+ return await handlePackageManager(filepath, options);
1718
1597
  }
1719
1598
  async function detect(options = {}) {
1720
1599
  const {
1721
1600
  cwd: cwd2,
1722
- strategies = ["lockfile", "packageManager-field", "devEngines-field"],
1723
- onUnknown
1601
+ strategies = ["lockfile", "packageManager-field", "devEngines-field"]
1724
1602
  } = options;
1725
1603
  let stopDir;
1726
1604
  if (typeof options.stopDir === "string") {
1727
- const resolved = path2.resolve(options.stopDir);
1605
+ const resolved = path.resolve(options.stopDir);
1728
1606
  stopDir = (dir) => dir === resolved;
1729
1607
  } else {
1730
1608
  stopDir = options.stopDir;
@@ -1734,9 +1612,9 @@ async function detect(options = {}) {
1734
1612
  switch (strategy) {
1735
1613
  case "lockfile": {
1736
1614
  for (const lock of Object.keys(LOCKS)) {
1737
- if (await pathExists(path2.join(directory, lock), "file")) {
1615
+ if (await pathExists(path.join(directory, lock), "file")) {
1738
1616
  const name = LOCKS[lock];
1739
- const result = await parsePackageJson(path2.join(directory, "package.json"), onUnknown);
1617
+ const result = await parsePackageJson(path.join(directory, "package.json"), options);
1740
1618
  if (result)
1741
1619
  return result;
1742
1620
  else
@@ -1747,7 +1625,7 @@ async function detect(options = {}) {
1747
1625
  }
1748
1626
  case "packageManager-field":
1749
1627
  case "devEngines-field": {
1750
- const result = await parsePackageJson(path2.join(directory, "package.json"), onUnknown);
1628
+ const result = await parsePackageJson(path.join(directory, "package.json"), options);
1751
1629
  if (result)
1752
1630
  return result;
1753
1631
  break;
@@ -1755,7 +1633,7 @@ async function detect(options = {}) {
1755
1633
  case "install-metadata": {
1756
1634
  for (const metadata of Object.keys(INSTALL_METADATA)) {
1757
1635
  const fileOrDir = metadata.endsWith("/") ? "dir" : "file";
1758
- if (await pathExists(path2.join(directory, metadata), fileOrDir)) {
1636
+ if (await pathExists(path.join(directory, metadata), fileOrDir)) {
1759
1637
  const name = INSTALL_METADATA[metadata];
1760
1638
  const agent = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name;
1761
1639
  return { name, agent };
@@ -1784,9 +1662,10 @@ function getNameAndVer(pkg) {
1784
1662
  }
1785
1663
  return void 0;
1786
1664
  }
1787
- async function handlePackageManager(filepath, onUnknown) {
1665
+ async function handlePackageManager(filepath, options) {
1788
1666
  try {
1789
- const pkg = JSON.parse(await fs2.readFile(filepath, "utf8"));
1667
+ const content = await fs.readFile(filepath, "utf8");
1668
+ const pkg = options.packageJsonParser ? await options.packageJsonParser(content, filepath) : JSON.parse(content);
1790
1669
  let agent;
1791
1670
  const nameAndVer = getNameAndVer(pkg);
1792
1671
  if (nameAndVer) {
@@ -1804,7 +1683,7 @@ async function handlePackageManager(filepath, onUnknown) {
1804
1683
  agent = name;
1805
1684
  return { name, agent, version };
1806
1685
  } else {
1807
- return onUnknown?.(pkg.packageManager) ?? null;
1686
+ return options.onUnknown?.(pkg.packageManager) ?? null;
1808
1687
  }
1809
1688
  }
1810
1689
  } catch {
@@ -1815,6 +1694,414 @@ function isMetadataYarnClassic(metadataPath) {
1815
1694
  return metadataPath.endsWith(".yarn_integrity");
1816
1695
  }
1817
1696
 
1697
+ // node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs
1698
+ import * as tty from "node:tty";
1699
+ var {
1700
+ env = {},
1701
+ argv = [],
1702
+ platform = ""
1703
+ } = typeof process === "undefined" ? {} : process;
1704
+ var isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
1705
+ var isForced = "FORCE_COLOR" in env || argv.includes("--color");
1706
+ var isWindows = platform === "win32";
1707
+ var isDumbTerminal = env.TERM === "dumb";
1708
+ var isCompatibleTerminal = tty && tty.isatty && tty.isatty(1) && env.TERM && !isDumbTerminal;
1709
+ var isCI = "CI" in env && ("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);
1710
+ var isColorSupported = !isDisabled && (isForced || isWindows && !isDumbTerminal || isCompatibleTerminal || isCI);
1711
+ function replaceClose(index, string, close, replace, head = string.slice(0, Math.max(0, index)) + replace, tail = string.slice(Math.max(0, index + close.length)), next = tail.indexOf(close)) {
1712
+ return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
1713
+ }
1714
+ function clearBleed(index, string, open, close, replace) {
1715
+ return index < 0 ? open + string + close : open + replaceClose(index, string, close, replace) + close;
1716
+ }
1717
+ function filterEmpty(open, close, replace = open, at = open.length + 1) {
1718
+ return (string) => string || !(string === "" || string === void 0) ? clearBleed(
1719
+ ("" + string).indexOf(close, at),
1720
+ string,
1721
+ open,
1722
+ close,
1723
+ replace
1724
+ ) : "";
1725
+ }
1726
+ function init(open, close, replace) {
1727
+ return filterEmpty(`\x1B[${open}m`, `\x1B[${close}m`, replace);
1728
+ }
1729
+ var colorDefs = {
1730
+ reset: init(0, 0),
1731
+ bold: init(1, 22, "\x1B[22m\x1B[1m"),
1732
+ dim: init(2, 22, "\x1B[22m\x1B[2m"),
1733
+ italic: init(3, 23),
1734
+ underline: init(4, 24),
1735
+ inverse: init(7, 27),
1736
+ hidden: init(8, 28),
1737
+ strikethrough: init(9, 29),
1738
+ black: init(30, 39),
1739
+ red: init(31, 39),
1740
+ green: init(32, 39),
1741
+ yellow: init(33, 39),
1742
+ blue: init(34, 39),
1743
+ magenta: init(35, 39),
1744
+ cyan: init(36, 39),
1745
+ white: init(37, 39),
1746
+ gray: init(90, 39),
1747
+ bgBlack: init(40, 49),
1748
+ bgRed: init(41, 49),
1749
+ bgGreen: init(42, 49),
1750
+ bgYellow: init(43, 49),
1751
+ bgBlue: init(44, 49),
1752
+ bgMagenta: init(45, 49),
1753
+ bgCyan: init(46, 49),
1754
+ bgWhite: init(47, 49),
1755
+ blackBright: init(90, 39),
1756
+ redBright: init(91, 39),
1757
+ greenBright: init(92, 39),
1758
+ yellowBright: init(93, 39),
1759
+ blueBright: init(94, 39),
1760
+ magentaBright: init(95, 39),
1761
+ cyanBright: init(96, 39),
1762
+ whiteBright: init(97, 39),
1763
+ bgBlackBright: init(100, 49),
1764
+ bgRedBright: init(101, 49),
1765
+ bgGreenBright: init(102, 49),
1766
+ bgYellowBright: init(103, 49),
1767
+ bgBlueBright: init(104, 49),
1768
+ bgMagentaBright: init(105, 49),
1769
+ bgCyanBright: init(106, 49),
1770
+ bgWhiteBright: init(107, 49)
1771
+ };
1772
+ function createColors(useColor = isColorSupported) {
1773
+ return useColor ? colorDefs : Object.fromEntries(Object.keys(colorDefs).map((key) => [key, String]));
1774
+ }
1775
+ var colors = createColors();
1776
+ function getColor(color, fallback = "reset") {
1777
+ return colors[color] || colors[fallback];
1778
+ }
1779
+ var ansiRegex = [
1780
+ String.raw`[\u001B\u009B][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)`,
1781
+ String.raw`(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))`
1782
+ ].join("|");
1783
+ function stripAnsi(text) {
1784
+ return text.replace(new RegExp(ansiRegex, "g"), "");
1785
+ }
1786
+ var boxStylePresets = {
1787
+ solid: {
1788
+ tl: "\u250C",
1789
+ tr: "\u2510",
1790
+ bl: "\u2514",
1791
+ br: "\u2518",
1792
+ h: "\u2500",
1793
+ v: "\u2502"
1794
+ },
1795
+ double: {
1796
+ tl: "\u2554",
1797
+ tr: "\u2557",
1798
+ bl: "\u255A",
1799
+ br: "\u255D",
1800
+ h: "\u2550",
1801
+ v: "\u2551"
1802
+ },
1803
+ doubleSingle: {
1804
+ tl: "\u2553",
1805
+ tr: "\u2556",
1806
+ bl: "\u2559",
1807
+ br: "\u255C",
1808
+ h: "\u2500",
1809
+ v: "\u2551"
1810
+ },
1811
+ doubleSingleRounded: {
1812
+ tl: "\u256D",
1813
+ tr: "\u256E",
1814
+ bl: "\u2570",
1815
+ br: "\u256F",
1816
+ h: "\u2500",
1817
+ v: "\u2551"
1818
+ },
1819
+ singleThick: {
1820
+ tl: "\u250F",
1821
+ tr: "\u2513",
1822
+ bl: "\u2517",
1823
+ br: "\u251B",
1824
+ h: "\u2501",
1825
+ v: "\u2503"
1826
+ },
1827
+ singleDouble: {
1828
+ tl: "\u2552",
1829
+ tr: "\u2555",
1830
+ bl: "\u2558",
1831
+ br: "\u255B",
1832
+ h: "\u2550",
1833
+ v: "\u2502"
1834
+ },
1835
+ singleDoubleRounded: {
1836
+ tl: "\u256D",
1837
+ tr: "\u256E",
1838
+ bl: "\u2570",
1839
+ br: "\u256F",
1840
+ h: "\u2550",
1841
+ v: "\u2502"
1842
+ },
1843
+ rounded: {
1844
+ tl: "\u256D",
1845
+ tr: "\u256E",
1846
+ bl: "\u2570",
1847
+ br: "\u256F",
1848
+ h: "\u2500",
1849
+ v: "\u2502"
1850
+ }
1851
+ };
1852
+ var defaultStyle = {
1853
+ borderColor: "white",
1854
+ borderStyle: "rounded",
1855
+ valign: "center",
1856
+ padding: 2,
1857
+ marginLeft: 1,
1858
+ marginTop: 1,
1859
+ marginBottom: 1
1860
+ };
1861
+ function box(text, _opts = {}) {
1862
+ const opts = {
1863
+ ..._opts,
1864
+ style: {
1865
+ ...defaultStyle,
1866
+ ..._opts.style
1867
+ }
1868
+ };
1869
+ const textLines = text.split("\n");
1870
+ const boxLines = [];
1871
+ const _color = getColor(opts.style.borderColor);
1872
+ const borderStyle = {
1873
+ ...typeof opts.style.borderStyle === "string" ? boxStylePresets[opts.style.borderStyle] || boxStylePresets.solid : opts.style.borderStyle
1874
+ };
1875
+ if (_color) {
1876
+ for (const key in borderStyle) {
1877
+ borderStyle[key] = _color(
1878
+ borderStyle[key]
1879
+ );
1880
+ }
1881
+ }
1882
+ const paddingOffset = opts.style.padding % 2 === 0 ? opts.style.padding : opts.style.padding + 1;
1883
+ const height = textLines.length + paddingOffset;
1884
+ const width = Math.max(
1885
+ ...textLines.map((line) => stripAnsi(line).length),
1886
+ opts.title ? stripAnsi(opts.title).length : 0
1887
+ ) + paddingOffset;
1888
+ const widthOffset = width + paddingOffset;
1889
+ const leftSpace = opts.style.marginLeft > 0 ? " ".repeat(opts.style.marginLeft) : "";
1890
+ if (opts.style.marginTop > 0) {
1891
+ boxLines.push("".repeat(opts.style.marginTop));
1892
+ }
1893
+ if (opts.title) {
1894
+ const title = _color ? _color(opts.title) : opts.title;
1895
+ const left = borderStyle.h.repeat(
1896
+ Math.floor((width - stripAnsi(opts.title).length) / 2)
1897
+ );
1898
+ const right = borderStyle.h.repeat(
1899
+ width - stripAnsi(opts.title).length - stripAnsi(left).length + paddingOffset
1900
+ );
1901
+ boxLines.push(
1902
+ `${leftSpace}${borderStyle.tl}${left}${title}${right}${borderStyle.tr}`
1903
+ );
1904
+ } else {
1905
+ boxLines.push(
1906
+ `${leftSpace}${borderStyle.tl}${borderStyle.h.repeat(widthOffset)}${borderStyle.tr}`
1907
+ );
1908
+ }
1909
+ const valignOffset = opts.style.valign === "center" ? Math.floor((height - textLines.length) / 2) : opts.style.valign === "top" ? height - textLines.length - paddingOffset : height - textLines.length;
1910
+ for (let i = 0; i < height; i++) {
1911
+ if (i < valignOffset || i >= valignOffset + textLines.length) {
1912
+ boxLines.push(
1913
+ `${leftSpace}${borderStyle.v}${" ".repeat(widthOffset)}${borderStyle.v}`
1914
+ );
1915
+ } else {
1916
+ const line = textLines[i - valignOffset];
1917
+ const left = " ".repeat(paddingOffset);
1918
+ const right = " ".repeat(width - stripAnsi(line).length);
1919
+ boxLines.push(
1920
+ `${leftSpace}${borderStyle.v}${left}${line}${right}${borderStyle.v}`
1921
+ );
1922
+ }
1923
+ }
1924
+ boxLines.push(
1925
+ `${leftSpace}${borderStyle.bl}${borderStyle.h.repeat(widthOffset)}${borderStyle.br}`
1926
+ );
1927
+ if (opts.style.marginBottom > 0) {
1928
+ boxLines.push("".repeat(opts.style.marginBottom));
1929
+ }
1930
+ return boxLines.join("\n");
1931
+ }
1932
+
1933
+ // src/utils/banner.ts
1934
+ function supportsColor() {
1935
+ const testText = "test";
1936
+ const coloredText = blue(testText);
1937
+ return coloredText !== testText;
1938
+ }
1939
+ function createBanner() {
1940
+ if (!supportsColor()) {
1941
+ return createPlainBanner();
1942
+ }
1943
+ return "\x1B[38;2;22;151;246mV\x1B[39m\x1B[38;2;22;147;242mu\x1B[39m\x1B[38;2;22;144;238me\x1B[39m\x1B[38;2;22;140;234mt\x1B[39m\x1B[38;2;23;136;229mi\x1B[39m\x1B[38;2;23;133;225mf\x1B[39m\x1B[38;2;23;129;221my\x1B[39m\x1B[38;2;23;125;217m.\x1B[39m\x1B[38;2;23;121;213mj\x1B[39m\x1B[38;2;23;118;209ms\x1B[39m \x1B[38;2;24;114;204m-\x1B[39m \x1B[38;2;24;110;200mM\x1B[39m\x1B[38;2;24;107;196ma\x1B[39m\x1B[38;2;24;103;192mt\x1B[39m\x1B[38;2;32;110;197me\x1B[39m\x1B[38;2;39;118;202mr\x1B[39m\x1B[38;2;47;125;207mi\x1B[39m\x1B[38;2;54;132;211ma\x1B[39m\x1B[38;2;62;140;216ml\x1B[39m \x1B[38;2;70;147;221mC\x1B[39m\x1B[38;2;77;154;226mo\x1B[39m\x1B[38;2;85;161;231mm\x1B[39m\x1B[38;2;93;169;236mp\x1B[39m\x1B[38;2;100;176;240mo\x1B[39m\x1B[38;2;108;183;245mn\x1B[39m\x1B[38;2;115;191;250me\x1B[39m\x1B[38;2;123;198;255mn\x1B[39m\x1B[38;2;126;199;255mt\x1B[39m \x1B[38;2;129;201;255mF\x1B[39m\x1B[38;2;133;202;255mr\x1B[39m\x1B[38;2;136;204;255ma\x1B[39m\x1B[38;2;139;205;255mm\x1B[39m\x1B[38;2;142;207;255me\x1B[39m\x1B[38;2;145;208;255mw\x1B[39m\x1B[38;2;149;210;255mo\x1B[39m\x1B[38;2;152;211;255mr\x1B[39m\x1B[38;2;155;212;255mk\x1B[39m \x1B[38;2;158;214;255mf\x1B[39m\x1B[38;2;161;215;255mo\x1B[39m\x1B[38;2;164;217;255mr\x1B[39m \x1B[38;2;168;218;255mV\x1B[39m\x1B[38;2;171;220;255mu\x1B[39m\x1B[38;2;174;221;255me\x1B[39m";
1944
+ }
1945
+ function createPlainBanner() {
1946
+ return "Vuetify - Vue Component Framework";
1947
+ }
1948
+ function createBetaBanner() {
1949
+ const packageManager2 = getUserAgent();
1950
+ return box(`${packageManager2 ?? "npm"} create vuetify@beta`, { title: "Try new vuetify-create with better customization and presets support!", style: { borderColor: "blueBright" } });
1951
+ }
1952
+
1953
+ // src/utils/deepMerge.ts
1954
+ var isObject = (v) => {
1955
+ return v === Object(v) && v !== null && !Array.isArray(v);
1956
+ };
1957
+ var deepMerge = (...sources) => sources.reduce((acc, curr) => {
1958
+ for (const key of Object.keys(curr)) {
1959
+ if (Array.isArray(acc[key]) && Array.isArray(curr[key])) {
1960
+ acc[key] = Array.from(new Set(acc[key].concat(curr[key])));
1961
+ } else if (isObject(acc[key]) && isObject(curr[key])) {
1962
+ acc[key] = deepMerge(acc[key], curr[key]);
1963
+ } else {
1964
+ acc[key] = curr[key];
1965
+ }
1966
+ }
1967
+ return acc;
1968
+ }, {});
1969
+
1970
+ // src/utils/renderTemplate.ts
1971
+ import { copyFileSync, mkdirSync, readdirSync as readdirSync3, readFileSync, statSync, writeFileSync, existsSync as existsSync4 } from "node:fs";
1972
+ import { basename as basename2, dirname as dirname2, extname as extname2, resolve as resolve5 } from "node:path";
1973
+ function mergePkg(source, destination) {
1974
+ const target = existsSync4(destination) ? JSON.parse(readFileSync(destination, "utf8")) : {};
1975
+ const src = JSON.parse(readFileSync(source, "utf8"));
1976
+ const mergedPkg = deepMerge(target, src);
1977
+ const keysToSort = ["devDependencies", "dependencies"];
1978
+ for (const k of keysToSort) {
1979
+ if (mergedPkg[k]) {
1980
+ mergedPkg[k] = Object.keys(mergedPkg[k]).toSorted().reduce((a, c) => (a[c] = mergedPkg[k][c], a), {});
1981
+ }
1982
+ }
1983
+ writeFileSync(destination, JSON.stringify(mergedPkg, null, 2) + "\n");
1984
+ }
1985
+ function renderDirectory(source, destination, options) {
1986
+ mkdirSync(destination, { recursive: true });
1987
+ for (const path4 of readdirSync3(source)) {
1988
+ renderTemplate(resolve5(source, path4), resolve5(destination, path4), options);
1989
+ }
1990
+ }
1991
+ var binaryExtensions = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".ico", ".woff", ".woff2", ".ttf", ".eot", ".svg"]);
1992
+ function renderFile(source, destination, options) {
1993
+ const filename = basename2(source);
1994
+ if (filename.startsWith("_")) {
1995
+ destination = resolve5(dirname2(destination), filename.replace("_", "."));
1996
+ }
1997
+ if (filename === "package.json") {
1998
+ mergePkg(source, destination);
1999
+ return;
2000
+ }
2001
+ if (options?.replace && !binaryExtensions.has(extname2(filename))) {
2002
+ let content = readFileSync(source, "utf8");
2003
+ for (const [key, value] of Object.entries(options.replace)) {
2004
+ content = content.replaceAll(key, value);
2005
+ }
2006
+ writeFileSync(destination, content);
2007
+ return;
2008
+ }
2009
+ copyFileSync(source, destination);
2010
+ }
2011
+ function renderTemplate(source, destination, options) {
2012
+ if (statSync(source).isDirectory()) {
2013
+ renderDirectory(source, destination, options);
2014
+ } else {
2015
+ renderFile(source, destination, options);
2016
+ }
2017
+ }
2018
+
2019
+ // src/utils/nuxt/renderNuxtTemplate.ts
2020
+ import fs3 from "node:fs";
2021
+ import path3 from "node:path";
2022
+ import { spawnSync as spawnSync2 } from "node:child_process";
2023
+
2024
+ // src/utils/nuxt/utils.ts
2025
+ import process3 from "node:process";
2026
+ import path2 from "node:path";
2027
+ import { spawnSync } from "node:child_process";
2028
+ import fs2 from "node:fs";
2029
+ function detectPkgInfo() {
2030
+ const userAgent2 = process3.env.npm_config_user_agent;
2031
+ if (!userAgent2) {
2032
+ return void 0;
2033
+ }
2034
+ const pkgSpec = userAgent2.split(" ")[0];
2035
+ const pkgSpecArr = pkgSpec.split("/");
2036
+ return {
2037
+ name: pkgSpecArr[0],
2038
+ version: pkgSpecArr[1]
2039
+ };
2040
+ }
2041
+ function addPackageObject(key, entry, pkg, sort = true) {
2042
+ pkg[key] ??= {};
2043
+ if (!sort) {
2044
+ for (const [name, value] of entry) {
2045
+ pkg[key][name] = value;
2046
+ }
2047
+ return;
2048
+ }
2049
+ const entries = Object.entries(pkg[key]);
2050
+ pkg[key] = {};
2051
+ for (const [name, value] of entry) {
2052
+ entries.push([name, value]);
2053
+ }
2054
+ for (const [k, v] of entries.toSorted(([a], [b]) => a.localeCompare(b))) {
2055
+ pkg[key][k] = v;
2056
+ }
2057
+ }
2058
+ function runCommand(pmDetection, command, args, cwd2) {
2059
+ let runCommand2 = "npm";
2060
+ let runArgs = [command];
2061
+ if (pmDetection) {
2062
+ const prepare = resolveCommand(pmDetection.name, command, args);
2063
+ runCommand2 = prepare.command;
2064
+ runArgs = prepare.args;
2065
+ }
2066
+ const run2 = spawnSync(
2067
+ runCommand2,
2068
+ runArgs.filter(Boolean),
2069
+ {
2070
+ cwd: cwd2,
2071
+ stdio: ["inherit", "inherit", "pipe"],
2072
+ shell: true
2073
+ }
2074
+ );
2075
+ if (run2.error) {
2076
+ throw run2.error;
2077
+ }
2078
+ }
2079
+ function editFile(file, callback, destination) {
2080
+ const content = fs2.readFileSync(file, "utf8");
2081
+ fs2.writeFileSync(destination ?? file, callback(content), "utf8");
2082
+ }
2083
+ function getPaths(rootPath, templateDir) {
2084
+ return [path2.join(rootPath, "app"), templateDir];
2085
+ }
2086
+
2087
+ // src/utils/nuxt/versions.ts
2088
+ var versions = {
2089
+ "vuetify": "^3.11.8",
2090
+ "typescript": "^5.8.3",
2091
+ "vue-tsc": "^3.2.0",
2092
+ "sass-embedded": "^1.89.2",
2093
+ "@vuetify/loader-shared": "^2.1.0",
2094
+ "vite-plugin-vuetify": "^2.1.3",
2095
+ "vuetify-nuxt-module": "^0.19.4",
2096
+ "upath": "^2.0.1",
2097
+ "@mdi/font": "^7.4.47",
2098
+ "@nuxt/fonts": "^0.11.4"
2099
+ };
2100
+ var versionsV4 = {
2101
+ ...versions,
2102
+ vuetify: "^4.0.0-beta.1"
2103
+ };
2104
+
1818
2105
  // src/utils/nuxt/renderNuxtTemplate.ts
1819
2106
  import { generateCode, parseModule } from "magicast";
1820
2107
  import { addNuxtModule, getDefaultExportOptions } from "magicast/helpers";
@@ -1862,11 +2149,13 @@ function configurePackageJson({
1862
2149
  projectName,
1863
2150
  projectRoot,
1864
2151
  useNuxtModule,
1865
- nuxtPreset
2152
+ nuxtPreset,
2153
+ vuetifyVersion
1866
2154
  }) {
1867
2155
  const packageJson = path3.join(projectRoot, "package.json");
1868
2156
  const pkg = JSON.parse(fs3.readFileSync(path3.join(projectRoot, "package.json"), "utf8"));
1869
2157
  pkg.name = projectName;
2158
+ const v = vuetifyVersion === "4.x" ? versionsV4 : versions;
1870
2159
  const scripts = [
1871
2160
  ["prepare", "nuxt prepare"],
1872
2161
  ["typecheck", "nuxt typecheck"]
@@ -1875,22 +2164,22 @@ function configurePackageJson({
1875
2164
  scripts.push(["lint", "eslint ."], ["lint:fix", "eslint . --fix"]);
1876
2165
  }
1877
2166
  const dependencies = [
1878
- ["vuetify", versions.vuetify]
2167
+ ["vuetify", v.vuetify]
1879
2168
  ];
1880
2169
  if (dependencies.length > 0) {
1881
2170
  addPackageObject("dependencies", dependencies, pkg);
1882
2171
  }
1883
2172
  const devDependencies = [
1884
- ["@mdi/font", versions["@mdi/font"]],
1885
- ["@nuxt/fonts", versions["@nuxt/fonts"]],
1886
- ["sass-embedded", versions["sass-embedded"]],
1887
- ["typescript", versions.typescript],
1888
- ["vue-tsc", versions["vue-tsc"]]
2173
+ ["@mdi/font", v["@mdi/font"]],
2174
+ ["@nuxt/fonts", v["@nuxt/fonts"]],
2175
+ ["sass-embedded", v["sass-embedded"]],
2176
+ ["typescript", v.typescript],
2177
+ ["vue-tsc", v["vue-tsc"]]
1889
2178
  ];
1890
2179
  if (useNuxtModule) {
1891
- devDependencies.push(["vuetify-nuxt-module", versions["vuetify-nuxt-module"]]);
2180
+ devDependencies.push(["vuetify-nuxt-module", v["vuetify-nuxt-module"]]);
1892
2181
  } else {
1893
- devDependencies.push(["upath", versions["upath"]], ["@vuetify/loader-shared", versions["@vuetify/loader-shared"]], ["vite-plugin-vuetify", versions["vite-plugin-vuetify"]]);
2182
+ devDependencies.push(["upath", v["upath"]], ["@vuetify/loader-shared", v["@vuetify/loader-shared"]], ["vite-plugin-vuetify", v["vite-plugin-vuetify"]]);
1894
2183
  }
1895
2184
  if (devDependencies.length > 0) {
1896
2185
  addPackageObject("devDependencies", devDependencies, pkg);
@@ -2085,10 +2374,11 @@ function prepareProject(ctx) {
2085
2374
  async function run() {
2086
2375
  const args = process.argv.slice(2).slice();
2087
2376
  const banner = createBanner();
2377
+ const betaBanner = createBetaBanner();
2088
2378
  if (args.length === 0) {
2089
2379
  console.log(`
2090
2380
  ${banner}
2091
- `);
2381
+ ${betaBanner}`);
2092
2382
  const initialContext2 = {
2093
2383
  canOverwrite: false,
2094
2384
  cwd: process.cwd(),
@@ -2109,7 +2399,7 @@ ${banner}
2109
2399
  }
2110
2400
  console.log(`
2111
2401
  ${banner}
2112
- `);
2402
+ ${betaBanner}`);
2113
2403
  const cliContext = cliOptionsToContext(cliOptions, process.cwd());
2114
2404
  const initialContext = {
2115
2405
  cwd: cliContext.cwd,
@@ -2121,7 +2411,8 @@ ${banner}
2121
2411
  installDependencies: cliContext.installDependencies,
2122
2412
  useNuxtModule: cliContext.useNuxtModule,
2123
2413
  useNuxtSSR: cliContext.useNuxtSSR,
2124
- useNuxtSSRClientHints: cliContext.useNuxtSSRClientHints
2414
+ useNuxtSSRClientHints: cliContext.useNuxtSSRClientHints,
2415
+ vuetifyVersion: cliContext.vuetifyVersion
2125
2416
  };
2126
2417
  const finalContext = resolveNonInteractiveContext(initialContext);
2127
2418
  await createProject(finalContext);
@@ -2156,7 +2447,8 @@ async function createProject(finalContext) {
2156
2447
  nuxtPreset: preset,
2157
2448
  useNuxtModule,
2158
2449
  useNuxtSSR,
2159
- useNuxtSSRClientHints
2450
+ useNuxtSSRClientHints,
2451
+ vuetifyVersion: finalContext.vuetifyVersion
2160
2452
  });
2161
2453
  } else {
2162
2454
  mkdirSync2(projectRoot);
@@ -2164,12 +2456,23 @@ async function createProject(finalContext) {
2164
2456
  console.log("\n\u25CC Generating scaffold...");
2165
2457
  const jsOrTs = useTypeScript ? "typescript" : "javascript";
2166
2458
  const templatePath = resolve6(dirname3(fileURLToPath(import.meta.url)), "../template", jsOrTs);
2167
- renderTemplate(resolve6(templatePath, "default"), projectRoot);
2459
+ const replace = {
2460
+ "{{VUETIFY_VERSION}}": finalContext.vuetifyVersion === "4.x" ? "4 (Beta)" : "3"
2461
+ };
2462
+ renderTemplate(resolve6(templatePath, "default"), projectRoot, { replace });
2168
2463
  if (["base", "essentials"].includes(usePreset)) {
2169
- renderTemplate(resolve6(templatePath, "base"), projectRoot);
2464
+ renderTemplate(resolve6(templatePath, "base"), projectRoot, { replace });
2170
2465
  }
2171
2466
  if (["essentials", "recommended"].includes(usePreset)) {
2172
- renderTemplate(resolve6(templatePath, "essentials"), projectRoot);
2467
+ renderTemplate(resolve6(templatePath, "essentials"), projectRoot, { replace });
2468
+ }
2469
+ if (finalContext.vuetifyVersion === "4.x") {
2470
+ const packageJsonPath = resolve6(projectRoot, "package.json");
2471
+ const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
2472
+ if (packageJson.dependencies?.vuetify) {
2473
+ packageJson.dependencies.vuetify = versionsV4.vuetify;
2474
+ }
2475
+ writeFileSync2(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
2173
2476
  }
2174
2477
  if (usePackageManager && installDeps) {
2175
2478
  console.log(`\u25CC Installing dependencies with ${usePackageManager}...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vuetify",
3
- "version": "2.7.3",
3
+ "version": "2.8.0",
4
4
  "author": "Elijah Kotyluk <elijah@elijahkotyluk.com>",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,10 +41,11 @@
41
41
  "components"
42
42
  ],
43
43
  "dependencies": {
44
+ "consola": "^3.4.2",
44
45
  "kolorist": "^1.8.0",
45
46
  "magicast": "^0.3.5",
46
47
  "minimist": "^1.2.8",
47
- "package-manager-detector": "^1.3.0",
48
+ "package-manager-detector": "^1.6.0",
48
49
  "prompts": "^2.4.2",
49
50
  "tinyexec": "^1.0.1",
50
51
  "validate-npm-package-name": "^6.0.2"
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="fill-height" max-width="900">
2
+ <v-container class="fill-height d-flex align-center" max-width="900">
3
3
  <div>
4
4
  <v-img
5
5
  class="mb-4"
@@ -9,7 +9,7 @@
9
9
 
10
10
  <div class="mb-8 text-center">
11
11
  <div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
12
- <h1 class="text-h2 font-weight-bold">Vuetify</h1>
12
+ <h1 class="text-h2 my-0 font-weight-bold">Vuetify</h1>
13
13
  </div>
14
14
 
15
15
  <v-row>
@@ -25,7 +25,7 @@ After completing the installation, your environment is ready for Vuetify develop
25
25
 
26
26
  ## ✨ Features
27
27
 
28
- - 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify 3 for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify 3](https://vuetifyjs.com/en/)
28
+ - 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify {{VUETIFY_VERSION}} for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify {{VUETIFY_VERSION}}](https://vuetifyjs.com/en/)
29
29
  - 🗃️ **State Management**: Integrated with [Pinia](https://pinia.vuejs.org/), the intuitive, modular state management solution for Vue.
30
30
  - 🚦 **Routing and Layouts**: Utilizes Vue Router for SPA navigation and vite-plugin-vue-layouts for organizing Vue file layouts. [Vue Router](https://router.vuejs.org/) | [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts)
31
31
  - ⚡ **Next-Gen Tooling**: Powered by Vite, experience fast cold starts and instant HMR (Hot Module Replacement). [Vite](https://vitejs.dev/)
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <link rel="icon" href="/favicon.ico">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Welcome to Vuetify 3</title>
7
+ <title>Welcome to Vuetify {{VUETIFY_VERSION}}</title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="app"></div>
@@ -10,15 +10,15 @@
10
10
  "dependencies": {
11
11
  "@mdi/font": "7.4.47",
12
12
  "@fontsource/roboto": "5.2.7",
13
- "vue": "^3.5.21",
14
- "vuetify": "^3.10.1"
13
+ "vue": "^3.5.28",
14
+ "vuetify": "^3.11.8"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@vitejs/plugin-vue": "^6.0.1",
18
18
  "sass-embedded": "^1.92.1",
19
19
  "unplugin-fonts": "^1.4.0",
20
20
  "unplugin-vue-components": "^29.0.0",
21
- "vite-plugin-vuetify": "^2.1.2",
21
+ "vite-plugin-vuetify": "^2.1.3",
22
22
  "vite": "^7.1.5"
23
23
  }
24
24
  }
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="fill-height" max-width="900">
2
+ <v-container class="fill-height d-flex align-center" max-width="900">
3
3
  <div>
4
4
  <v-img
5
5
  class="mb-4"
@@ -9,7 +9,7 @@
9
9
 
10
10
  <div class="mb-8 text-center">
11
11
  <div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
12
- <h1 class="text-h2 font-weight-bold">Vuetify</h1>
12
+ <h1 class="text-h2 my-0 font-weight-bold">Vuetify</h1>
13
13
  </div>
14
14
 
15
15
  <v-row>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="fill-height" max-width="900">
2
+ <v-container class="fill-height d-flex align-center" max-width="900">
3
3
  <div>
4
4
  <v-img
5
5
  class="mb-4"
@@ -9,7 +9,7 @@
9
9
 
10
10
  <div class="mb-8 text-center">
11
11
  <div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
12
- <h1 class="text-h2 font-weight-bold">Vuetify</h1>
12
+ <h1 class="text-h2 my-0 font-weight-bold">Vuetify</h1>
13
13
  </div>
14
14
 
15
15
  <v-row>
@@ -25,7 +25,7 @@ After completing the installation, your environment is ready for Vuetify develop
25
25
 
26
26
  ## ✨ Features
27
27
 
28
- - 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify 3 for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify 3](https://vuetifyjs.com/en/)
28
+ - 🖼️ **Optimized Front-End Stack**: Leverage the latest Vue 3 and Vuetify {{VUETIFY_VERSION}} for a modern, reactive UI development experience. [Vue 3](https://v3.vuejs.org/) | [Vuetify {{VUETIFY_VERSION}}](https://vuetifyjs.com/en/)
29
29
  - 🗃️ **State Management**: Integrated with [Pinia](https://pinia.vuejs.org/), the intuitive, modular state management solution for Vue.
30
30
  - 🚦 **Routing and Layouts**: Utilizes Vue Router for SPA navigation and vite-plugin-vue-layouts-next for organizing Vue file layouts. [Vue Router](https://router.vuejs.org/) | [vite-plugin-vue-layouts-next](https://github.com/loicduong/vite-plugin-vue-layouts-next)
31
31
  - 💻 **Enhanced Development Experience**: Benefit from TypeScript's static type checking and the ESLint plugin suite for Vue, ensuring code quality and consistency. [TypeScript](https://www.typescriptlang.org/) | [ESLint Plugin Vue](https://eslint.vuejs.org/)
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <link rel="icon" href="/favicon.ico">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Welcome to Vuetify 3</title>
7
+ <title>Welcome to Vuetify {{VUETIFY_VERSION}}</title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="app"></div>
@@ -12,8 +12,8 @@
12
12
  "dependencies": {
13
13
  "@mdi/font": "7.4.47",
14
14
  "@fontsource/roboto": "5.2.7",
15
- "vue": "^3.5.21",
16
- "vuetify": "^3.10.1"
15
+ "vue": "^3.5.28",
16
+ "vuetify": "^3.11.8"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@tsconfig/node22": "^22.0.0",
@@ -25,8 +25,8 @@
25
25
  "typescript": "~5.9.2",
26
26
  "unplugin-fonts": "^1.4.0",
27
27
  "unplugin-vue-components": "^29.0.0",
28
- "vite-plugin-vuetify": "^2.1.2",
28
+ "vite-plugin-vuetify": "^2.1.3",
29
29
  "vite": "^7.1.5",
30
- "vue-tsc": "^3.0.7"
30
+ "vue-tsc": "^3.2.0"
31
31
  }
32
32
  }
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="fill-height" max-width="900">
2
+ <v-container class="fill-height d-flex align-center" max-width="900">
3
3
  <div>
4
4
  <v-img
5
5
  class="mb-4"
@@ -9,7 +9,7 @@
9
9
 
10
10
  <div class="mb-8 text-center">
11
11
  <div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
12
- <h1 class="text-h2 font-weight-bold">Vuetify</h1>
12
+ <h1 class="text-h2 my-0 font-weight-bold">Vuetify</h1>
13
13
  </div>
14
14
 
15
15
  <v-row>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="fill-height" max-width="900">
2
+ <v-container class="fill-height d-flex align-center" max-width="900">
3
3
  <div>
4
4
  <v-img
5
5
  class="mb-4"
@@ -9,7 +9,7 @@
9
9
 
10
10
  <div class="mb-8 text-center">
11
11
  <div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
12
- <h1 class="text-h2 font-weight-bold">Vuetify</h1>
12
+ <h1 class="text-h2 my-0 font-weight-bold">Vuetify</h1>
13
13
  </div>
14
14
 
15
15
  <v-row>