create-krispya 0.10.0 → 0.12.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/cli.cjs CHANGED
@@ -9,7 +9,7 @@ const node_module = require('node:module');
9
9
  const node_path = require('node:path');
10
10
  const node_process = require('node:process');
11
11
  const undici = require('undici');
12
- const workspace = require('./shared/create-krispya.DTHeUlq4.cjs');
12
+ const workspace = require('./shared/create-krispya.FNrYi_5V.cjs');
13
13
  const Conf = require('conf');
14
14
  const promises = require('fs/promises');
15
15
  const fs = require('fs');
@@ -20,15 +20,15 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
20
20
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
21
21
 
22
22
  function _interopNamespaceCompat(e) {
23
- if (e && typeof e === 'object' && 'default' in e) return e;
24
- const n = Object.create(null);
25
- if (e) {
26
- for (const k in e) {
27
- n[k] = e[k];
28
- }
23
+ if (e && typeof e === 'object' && 'default' in e) return e;
24
+ const n = Object.create(null);
25
+ if (e) {
26
+ for (const k in e) {
27
+ n[k] = e[k];
29
28
  }
30
- n.default = e;
31
- return n;
29
+ }
30
+ n.default = e;
31
+ return n;
32
32
  }
33
33
 
34
34
  const p__namespace = /*#__PURE__*/_interopNamespaceCompat(p);
@@ -52,6 +52,7 @@ function formatConfigSummary(options, inherited) {
52
52
  const baseTemplate = options.template ? workspace.getBaseTemplate(options.template) : "vanilla";
53
53
  if (baseTemplate === "react") {
54
54
  lines.push(formatRow("Framework", "React"));
55
+ lines.push(formatRow("\u21B3 React compiler", workspace.shouldEnableReactCompiler(options) ? "yes" : "no"));
55
56
  } else if (baseTemplate === "r3f") {
56
57
  lines.push(formatRow("Framework", "React Three Fiber"));
57
58
  }
@@ -90,9 +91,7 @@ function formatConfigSummary(options, inherited) {
90
91
  const testing = options.testing ?? (projectType === "library" ? "vitest" : "none");
91
92
  lines.push(formatRow("Testing", testing));
92
93
  if (!inherited) {
93
- lines.push(
94
- formatRow("Editor config", options.ide === "none" ? "generic" : "generic + vscode")
95
- );
94
+ lines.push(formatRow("Editor config", options.ide === "none" ? "generic" : "generic + vscode"));
96
95
  const configStrategy = options.configStrategy ?? "stealth";
97
96
  lines.push(formatRow("Config strategy", configStrategy));
98
97
  }
@@ -556,7 +555,7 @@ async function promptForOptions(name, presets) {
556
555
  let projectName = name;
557
556
  if (!projectName) {
558
557
  const nameResult = await p__namespace.text({
559
- message: "What is your project named?",
558
+ message: "Project name:",
560
559
  placeholder: workspace.generateRandomName(),
561
560
  defaultValue: workspace.generateRandomName(),
562
561
  validate: (value) => {
@@ -570,7 +569,7 @@ async function promptForOptions(name, presets) {
570
569
  projectName = nameResult;
571
570
  }
572
571
  const projectType = await p__namespace.select({
573
- message: "Project type",
572
+ message: "Project type:",
574
573
  options: [
575
574
  { value: "app", label: "Application" },
576
575
  { value: "library", label: "Library" },
@@ -599,11 +598,11 @@ function presetsToInheritedSettings(presets) {
599
598
  }
600
599
  async function promptForPackageOptions(projectName, projectType, inheritedSettings, presets) {
601
600
  const templateSelection = await p__namespace.select({
602
- message: "Select a template",
601
+ message: "Select a template:",
603
602
  options: [
604
- { value: "vanilla", label: "Vanilla" },
605
- { value: "react", label: "React", hint: "experimental" },
606
- { value: "r3f", label: "React Three Fiber", hint: "experimental" }
603
+ { value: "vanilla", label: color__default.yellow("Vanilla") },
604
+ { value: "react", label: color__default.cyan("React"), hint: "experimental" },
605
+ { value: "r3f", label: color__default.magenta("React Three Fiber"), hint: "experimental" }
607
606
  ],
608
607
  initialValue: presets?.template ? workspace.getBaseTemplate(presets.template) : "vanilla"
609
608
  });
@@ -837,10 +836,7 @@ async function getWorkspacePackages(monorepoRoot) {
837
836
  for (const entry of entries) {
838
837
  if (!entry.isDirectory()) continue;
839
838
  try {
840
- const content = await promises$1.readFile(
841
- node_path.join(packagesDir, entry.name, "package.json"),
842
- "utf-8"
843
- );
839
+ const content = await promises$1.readFile(node_path.join(packagesDir, entry.name, "package.json"), "utf-8");
844
840
  const pkg = JSON.parse(content);
845
841
  if (pkg.name) names.push(pkg.name);
846
842
  } catch {
@@ -1117,9 +1113,7 @@ async function handleFixCommand(options) {
1117
1113
  spinner.start("Fixing workspace...");
1118
1114
  try {
1119
1115
  const files = {};
1120
- const tsConfigExists = await fileExists$1(
1121
- node_path.join(monorepoRoot, ".config/typescript/package.json")
1122
- );
1116
+ const tsConfigExists = await fileExists$1(node_path.join(monorepoRoot, ".config/typescript/package.json"));
1123
1117
  if (!tsConfigExists) {
1124
1118
  workspace.renderTypescriptConfigPackage(files);
1125
1119
  }
@@ -1127,9 +1121,7 @@ async function handleFixCommand(options) {
1127
1121
  const oxlintExists = await fileExists$1(node_path.join(monorepoRoot, ".config/oxlint/package.json"));
1128
1122
  if (!oxlintExists) workspace.renderOxlintConfigPackage(files);
1129
1123
  } else if (linter === "eslint") {
1130
- const eslintPkgExists = await fileExists$1(
1131
- node_path.join(monorepoRoot, ".config/eslint/package.json")
1132
- );
1124
+ const eslintPkgExists = await fileExists$1(node_path.join(monorepoRoot, ".config/eslint/package.json"));
1133
1125
  if (!eslintPkgExists) {
1134
1126
  if (existingConfigs.eslintConfigPath) {
1135
1127
  await migrateEslintConfig(monorepoRoot, files);
@@ -1142,9 +1134,7 @@ async function handleFixCommand(options) {
1142
1134
  const oxfmtExists = await fileExists$1(node_path.join(monorepoRoot, ".config/oxfmt/package.json"));
1143
1135
  if (!oxfmtExists) workspace.renderOxfmtConfigPackage(files);
1144
1136
  } else if (formatter === "prettier") {
1145
- const prettierPkgExists = await fileExists$1(
1146
- node_path.join(monorepoRoot, ".config/prettier/package.json")
1147
- );
1137
+ const prettierPkgExists = await fileExists$1(node_path.join(monorepoRoot, ".config/prettier/package.json"));
1148
1138
  if (!prettierPkgExists) {
1149
1139
  if (existingConfigs.prettierConfigPath) {
1150
1140
  await migratePrettierConfig(monorepoRoot, files);
@@ -1206,9 +1196,7 @@ async function handleFixCommand(options) {
1206
1196
  console.log(color__default.dim(` Generated ${pkgName}`));
1207
1197
  }
1208
1198
  const vscodeSettingsExists = await fileExists$1(node_path.join(monorepoRoot, ".vscode/settings.json"));
1209
- const vscodeExtensionsExists = await fileExists$1(
1210
- node_path.join(monorepoRoot, ".vscode/extensions.json")
1211
- );
1199
+ const vscodeExtensionsExists = await fileExists$1(node_path.join(monorepoRoot, ".vscode/extensions.json"));
1212
1200
  const vscodeExists = vscodeSettingsExists && vscodeExtensionsExists;
1213
1201
  if (!vscodeExists) {
1214
1202
  let addVscode = false;
@@ -1264,10 +1252,37 @@ async function handleFixCommand(options) {
1264
1252
  }
1265
1253
  }
1266
1254
 
1255
+ function detectViteTemplate(pkg) {
1256
+ if (!hasPackage(pkg, "vite")) return void 0;
1257
+ if (hasPackage(pkg, "@react-three/fiber")) return "r3f";
1258
+ if (hasPackage(pkg, "react") || hasPackage(pkg, "@vitejs/plugin-react")) return "react";
1259
+ return "vanilla";
1260
+ }
1261
+ function renderExpectedViteConfig(template) {
1262
+ const isReact = template === "react" || template === "r3f";
1263
+ const useReactCompiler = template === "react";
1264
+ const codeSnippets = isReact ? {
1265
+ "vite-config-import": [
1266
+ useReactCompiler ? "import react, { reactCompilerPreset } from '@vitejs/plugin-react';" : "import react from '@vitejs/plugin-react';",
1267
+ ...useReactCompiler ? ["import babel from '@rolldown/plugin-babel';"] : []
1268
+ ]
1269
+ } : {};
1270
+ const viteConfig = {
1271
+ base: "./"
1272
+ };
1273
+ if (isReact) {
1274
+ viteConfig.plugins = useReactCompiler ? ["$raw:react()", "$raw:babel({ presets: [reactCompilerPreset()] })"] : ["$raw:react()"];
1275
+ }
1276
+ if (template === "r3f") {
1277
+ viteConfig.resolve = { dedupe: ["three"] };
1278
+ }
1279
+ return workspace.renderViteConfig({ viteConfig, codeSnippets });
1280
+ }
1267
1281
  async function detectCurrentConfig(root, isMonorepo = true) {
1268
1282
  let name = root.split(/[/\\]/).pop() ?? "workspace";
1269
1283
  let packageManager = "pnpm";
1270
1284
  let hasTypecheck = false;
1285
+ let viteTemplate;
1271
1286
  try {
1272
1287
  const pkgPath = path.join(root, "package.json");
1273
1288
  const content = await promises.readFile(pkgPath, "utf-8");
@@ -1279,6 +1294,7 @@ async function detectCurrentConfig(root, isMonorepo = true) {
1279
1294
  packageManager = pkgJson.packageManager.split("@")[0] ?? packageManager;
1280
1295
  }
1281
1296
  hasTypecheck = pkgJson.scripts?.typecheck != null;
1297
+ viteTemplate = detectViteTemplate(pkgJson);
1282
1298
  } catch {
1283
1299
  }
1284
1300
  const tooling = await workspace.detectTooling(root);
@@ -1290,7 +1306,8 @@ async function detectCurrentConfig(root, isMonorepo = true) {
1290
1306
  packageManager,
1291
1307
  isMonorepo,
1292
1308
  configStrategy,
1293
- hasTypecheck
1309
+ hasTypecheck,
1310
+ viteTemplate
1294
1311
  };
1295
1312
  }
1296
1313
  async function detectSinglePackageConfigStrategy(root) {
@@ -1354,6 +1371,9 @@ async function planExpectedFiles(config) {
1354
1371
  content: workspace.toPrettierIgnoreContent()
1355
1372
  };
1356
1373
  }
1374
+ if (!isMonorepo && config.viteTemplate != null) {
1375
+ rootConfig["vite.config.ts"] = renderExpectedViteConfig(config.viteTemplate);
1376
+ }
1357
1377
  if (linter === "biome" || formatter === "biome") {
1358
1378
  const biomeVersion = workspace.getResolvedPackageVersion(versions, "@biomejs/biome");
1359
1379
  const biomeConfig = {
@@ -1597,6 +1617,11 @@ function hasPackage(pkg, name) {
1597
1617
  function sortPackageMap(packageMap) {
1598
1618
  return Object.fromEntries(Object.entries(packageMap).sort(([a], [b]) => a.localeCompare(b)));
1599
1619
  }
1620
+ function addMissingDevDependency(pkg, devDependencies, name) {
1621
+ if (!hasPackage(pkg, name)) {
1622
+ devDependencies[name] = workspace.formatResolvedPackageVersion({}, name);
1623
+ }
1624
+ }
1600
1625
  async function detectTypeScriptPackage(root, pkg) {
1601
1626
  if (hasPackage(pkg, "typescript")) return true;
1602
1627
  return await fileExists(path.join(root, "tsconfig.json")) || await fileExists(path.join(root, "tsconfig.app.json")) || await fileExists(path.join(root, ".config/tsconfig.app.json"));
@@ -1659,6 +1684,14 @@ async function getExpectedPackageDevDependencies(root, config, pkg) {
1659
1684
  if (shouldAddOxlintTypeAwareBackend) {
1660
1685
  nextDevDependencies["oxlint-tsgolint"] = workspace.formatResolvedPackageVersion({}, "oxlint-tsgolint");
1661
1686
  }
1687
+ if (!config.isMonorepo && config.viteTemplate === "react") {
1688
+ addMissingDevDependency(pkg, nextDevDependencies, "@babel/core");
1689
+ addMissingDevDependency(pkg, nextDevDependencies, "@rolldown/plugin-babel");
1690
+ addMissingDevDependency(pkg, nextDevDependencies, "babel-plugin-react-compiler");
1691
+ if (await detectTypeScriptPackage(root, pkg)) {
1692
+ addMissingDevDependency(pkg, nextDevDependencies, "@types/babel__core");
1693
+ }
1694
+ }
1662
1695
  return sortPackageMap(nextDevDependencies);
1663
1696
  }
1664
1697
  async function getPackageJsonScriptUpdates(root, config) {
@@ -1907,9 +1940,7 @@ async function collectUpdateCategories(projectRoot, config, isMonorepo) {
1907
1940
  category: "package-json",
1908
1941
  label: "package.json",
1909
1942
  changes: packageJsonScriptChanges,
1910
- hasUserModifications: packageJsonScriptChanges.some(
1911
- (change) => change.status === "modified"
1912
- )
1943
+ hasUserModifications: packageJsonScriptChanges.some((change) => change.status === "modified")
1913
1944
  });
1914
1945
  }
1915
1946
  const oxlintConfigChanges = await getOxlintConfigReplacementUpdates(projectRoot, config);
@@ -1928,9 +1959,7 @@ async function collectUpdateCategories(projectRoot, config, isMonorepo) {
1928
1959
  category: "workspace-config",
1929
1960
  label: "Workspace Config",
1930
1961
  changes: workspaceConfigChanges,
1931
- hasUserModifications: workspaceConfigChanges.some(
1932
- (change) => change.status === "modified"
1933
- )
1962
+ hasUserModifications: workspaceConfigChanges.some((change) => change.status === "modified")
1934
1963
  });
1935
1964
  }
1936
1965
  }
@@ -1970,9 +1999,7 @@ async function processUpdateCategory(category, projectRoot, options) {
1970
1999
  if (changesToApply.length > 0) {
1971
2000
  await applyUpdates(changesToApply, projectRoot);
1972
2001
  const addedCount = changesToApply.filter((change) => change.status === "added").length;
1973
- const updatedFilesCount = changesToApply.filter(
1974
- (change) => change.status === "modified"
1975
- ).length;
2002
+ const updatedFilesCount = changesToApply.filter((change) => change.status === "modified").length;
1976
2003
  const parts = [];
1977
2004
  if (addedCount > 0) parts.push(`added ${addedCount}`);
1978
2005
  if (updatedFilesCount > 0) parts.push(`updated ${updatedFilesCount}`);
@@ -2399,10 +2426,7 @@ async function main() {
2399
2426
  ).option(
2400
2427
  "--node-version <version>",
2401
2428
  'set Node.js version for engines.node field (default: "latest")'
2402
- ).option("--workspace", "Add package to current monorepo workspace (non-interactive)").option("--dir <directory>", "Target directory for --workspace (default: apps/ or packages/)").option("--clear-config", "Clear saved preferences").option("--config-path", "Print the path to the config file").option("--check", "Check if current directory is in a valid monorepo workspace").option("--fix", "Fix monorepo by generating missing .config packages").option("--update", "Update monorepo workspace to latest configuration").option("-y, --yes", "Non-interactive mode - accept all prompts").option(
2403
- "--path <directory>",
2404
- "Run in specified directory instead of current working directory"
2405
- ).action(async (name, options) => {
2429
+ ).option("--workspace", "Add package to current monorepo workspace (non-interactive)").option("--dir <directory>", "Target directory for --workspace (default: apps/ or packages/)").option("--clear-config", "Clear saved preferences").option("--config-path", "Print the path to the config file").option("--check", "Check if current directory is in a valid monorepo workspace").option("--fix", "Fix monorepo by generating missing .config packages").option("--update", "Update monorepo workspace to latest configuration").option("-y, --yes", "Non-interactive mode - accept all prompts").option("--path <directory>", "Run in specified directory instead of current working directory").action(async (name, options) => {
2406
2430
  if (options.path) {
2407
2431
  process.chdir(options.path);
2408
2432
  }
@@ -2464,9 +2488,7 @@ async function main() {
2464
2488
  }
2465
2489
  if (options.dir && !options.workspace) {
2466
2490
  console.error(color__default.red("Error:") + " --dir requires --workspace flag");
2467
- console.log(
2468
- color__default.dim(" Example: pnpm create krispya my-lib --workspace --dir examples")
2469
- );
2491
+ console.log(color__default.dim(" Example: pnpm create krispya my-lib --workspace --dir examples"));
2470
2492
  process.exit(1);
2471
2493
  }
2472
2494
  if (options.workspace) {
package/dist/cli.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { P as ProjectType, e as LibraryBundler, Q as Template, p as PackageManagerName, I as Ide } from './shared/create-krispya.to8NBxeJ.cjs';
2
+ import { P as ProjectType, e as LibraryBundler, Q as Template, p as PackageManagerName, I as Ide } from './shared/create-krispya.CcQTepKu.cjs';
3
3
 
4
4
  interface CliOptions {
5
5
  type?: ProjectType;
package/dist/cli.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { P as ProjectType, e as LibraryBundler, Q as Template, p as PackageManagerName, I as Ide } from './shared/create-krispya.to8NBxeJ.mjs';
2
+ import { P as ProjectType, e as LibraryBundler, Q as Template, p as PackageManagerName, I as Ide } from './shared/create-krispya.CcQTepKu.mjs';
3
3
 
4
4
  interface CliOptions {
5
5
  type?: ProjectType;
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- import { P as ProjectType, e as LibraryBundler, Q as Template, p as PackageManagerName, I as Ide } from './shared/create-krispya.to8NBxeJ.js';
2
+ import { P as ProjectType, e as LibraryBundler, Q as Template, p as PackageManagerName, I as Ide } from './shared/create-krispya.CcQTepKu.js';
3
3
 
4
4
  interface CliOptions {
5
5
  type?: ProjectType;
package/dist/cli.mjs CHANGED
@@ -7,7 +7,7 @@ import { createRequire } from 'node:module';
7
7
  import { resolve, join as join$1, dirname } from 'node:path';
8
8
  import { cwd } from 'node:process';
9
9
  import { fetch } from 'undici';
10
- import { q as getEngineName, a as getBaseTemplate, b as getLanguageFromTemplate, s as getPackageManagerName, g as generateRandomName, A as ALL_AI_PLATFORMS, t as AI_PLATFORM_LABELS, x as AI_PLATFORM_HINTS, d as detectTooling, y as parsePackageManager, z as parseEngine, p as parseWorkspaceYamlContent, B as renderTypescriptConfigPackage, C as renderOxlintConfigPackage, D as renderEslintConfigPackage, E as renderOxfmtConfigPackage, F as renderPrettierConfigPackage, G as resolveMonorepoRootPackageVersions, H as getResolvedPackageVersion, I as renderVscodeFiles, J as renderAiFiles, K as renderVscodeFiles$1, L as renderEditorConfig, M as renderGitignore, N as toPrettierIgnoreContent, O as mergePackageJsonScripts, P as packageJsonScripts, Q as resolveDefaultPackageJsonScripts, R as formatResolvedPackageVersion, S as renderOxlintConfig, k as planProject, r as resolveProjectPlanInput, v as validatePackageName, o as resolveWorkspacePlanInput, l as planWorkspace } from './shared/create-krispya.DKKVmsqH.mjs';
10
+ import { t as getEngineName, a as getBaseTemplate, s as shouldEnableReactCompiler, b as getLanguageFromTemplate, x as getPackageManagerName, g as generateRandomName, A as ALL_AI_PLATFORMS, y as AI_PLATFORM_LABELS, z as AI_PLATFORM_HINTS, d as detectTooling, B as parsePackageManager, C as parseEngine, p as parseWorkspaceYamlContent, D as renderTypescriptConfigPackage, E as renderOxlintConfigPackage, F as renderEslintConfigPackage, G as renderOxfmtConfigPackage, H as renderPrettierConfigPackage, I as resolveMonorepoRootPackageVersions, J as getResolvedPackageVersion, K as renderVscodeFiles, L as renderAiFiles, M as renderVscodeFiles$1, N as renderEditorConfig, O as renderGitignore, P as toPrettierIgnoreContent, Q as mergePackageJsonScripts, R as renderViteConfig, S as packageJsonScripts, T as resolveDefaultPackageJsonScripts, U as formatResolvedPackageVersion, V as renderOxlintConfig, l as planProject, r as resolveProjectPlanInput, v as validatePackageName, q as resolveWorkspacePlanInput, n as planWorkspace } from './shared/create-krispya.DZWMfM2v.mjs';
11
11
  import Conf from 'conf';
12
12
  import { access, constants, readFile as readFile$1, mkdir as mkdir$1, writeFile as writeFile$1 } from 'fs/promises';
13
13
  import { constants as constants$2 } from 'fs';
@@ -31,6 +31,7 @@ function formatConfigSummary(options, inherited) {
31
31
  const baseTemplate = options.template ? getBaseTemplate(options.template) : "vanilla";
32
32
  if (baseTemplate === "react") {
33
33
  lines.push(formatRow("Framework", "React"));
34
+ lines.push(formatRow("\u21B3 React compiler", shouldEnableReactCompiler(options) ? "yes" : "no"));
34
35
  } else if (baseTemplate === "r3f") {
35
36
  lines.push(formatRow("Framework", "React Three Fiber"));
36
37
  }
@@ -69,9 +70,7 @@ function formatConfigSummary(options, inherited) {
69
70
  const testing = options.testing ?? (projectType === "library" ? "vitest" : "none");
70
71
  lines.push(formatRow("Testing", testing));
71
72
  if (!inherited) {
72
- lines.push(
73
- formatRow("Editor config", options.ide === "none" ? "generic" : "generic + vscode")
74
- );
73
+ lines.push(formatRow("Editor config", options.ide === "none" ? "generic" : "generic + vscode"));
75
74
  const configStrategy = options.configStrategy ?? "stealth";
76
75
  lines.push(formatRow("Config strategy", configStrategy));
77
76
  }
@@ -535,7 +534,7 @@ async function promptForOptions(name, presets) {
535
534
  let projectName = name;
536
535
  if (!projectName) {
537
536
  const nameResult = await p.text({
538
- message: "What is your project named?",
537
+ message: "Project name:",
539
538
  placeholder: generateRandomName(),
540
539
  defaultValue: generateRandomName(),
541
540
  validate: (value) => {
@@ -549,7 +548,7 @@ async function promptForOptions(name, presets) {
549
548
  projectName = nameResult;
550
549
  }
551
550
  const projectType = await p.select({
552
- message: "Project type",
551
+ message: "Project type:",
553
552
  options: [
554
553
  { value: "app", label: "Application" },
555
554
  { value: "library", label: "Library" },
@@ -578,11 +577,11 @@ function presetsToInheritedSettings(presets) {
578
577
  }
579
578
  async function promptForPackageOptions(projectName, projectType, inheritedSettings, presets) {
580
579
  const templateSelection = await p.select({
581
- message: "Select a template",
580
+ message: "Select a template:",
582
581
  options: [
583
- { value: "vanilla", label: "Vanilla" },
584
- { value: "react", label: "React", hint: "experimental" },
585
- { value: "r3f", label: "React Three Fiber", hint: "experimental" }
582
+ { value: "vanilla", label: color.yellow("Vanilla") },
583
+ { value: "react", label: color.cyan("React"), hint: "experimental" },
584
+ { value: "r3f", label: color.magenta("React Three Fiber"), hint: "experimental" }
586
585
  ],
587
586
  initialValue: presets?.template ? getBaseTemplate(presets.template) : "vanilla"
588
587
  });
@@ -816,10 +815,7 @@ async function getWorkspacePackages(monorepoRoot) {
816
815
  for (const entry of entries) {
817
816
  if (!entry.isDirectory()) continue;
818
817
  try {
819
- const content = await readFile(
820
- join$1(packagesDir, entry.name, "package.json"),
821
- "utf-8"
822
- );
818
+ const content = await readFile(join$1(packagesDir, entry.name, "package.json"), "utf-8");
823
819
  const pkg = JSON.parse(content);
824
820
  if (pkg.name) names.push(pkg.name);
825
821
  } catch {
@@ -1096,9 +1092,7 @@ async function handleFixCommand(options) {
1096
1092
  spinner.start("Fixing workspace...");
1097
1093
  try {
1098
1094
  const files = {};
1099
- const tsConfigExists = await fileExists$1(
1100
- join$1(monorepoRoot, ".config/typescript/package.json")
1101
- );
1095
+ const tsConfigExists = await fileExists$1(join$1(monorepoRoot, ".config/typescript/package.json"));
1102
1096
  if (!tsConfigExists) {
1103
1097
  renderTypescriptConfigPackage(files);
1104
1098
  }
@@ -1106,9 +1100,7 @@ async function handleFixCommand(options) {
1106
1100
  const oxlintExists = await fileExists$1(join$1(monorepoRoot, ".config/oxlint/package.json"));
1107
1101
  if (!oxlintExists) renderOxlintConfigPackage(files);
1108
1102
  } else if (linter === "eslint") {
1109
- const eslintPkgExists = await fileExists$1(
1110
- join$1(monorepoRoot, ".config/eslint/package.json")
1111
- );
1103
+ const eslintPkgExists = await fileExists$1(join$1(monorepoRoot, ".config/eslint/package.json"));
1112
1104
  if (!eslintPkgExists) {
1113
1105
  if (existingConfigs.eslintConfigPath) {
1114
1106
  await migrateEslintConfig(monorepoRoot, files);
@@ -1121,9 +1113,7 @@ async function handleFixCommand(options) {
1121
1113
  const oxfmtExists = await fileExists$1(join$1(monorepoRoot, ".config/oxfmt/package.json"));
1122
1114
  if (!oxfmtExists) renderOxfmtConfigPackage(files);
1123
1115
  } else if (formatter === "prettier") {
1124
- const prettierPkgExists = await fileExists$1(
1125
- join$1(monorepoRoot, ".config/prettier/package.json")
1126
- );
1116
+ const prettierPkgExists = await fileExists$1(join$1(monorepoRoot, ".config/prettier/package.json"));
1127
1117
  if (!prettierPkgExists) {
1128
1118
  if (existingConfigs.prettierConfigPath) {
1129
1119
  await migratePrettierConfig(monorepoRoot, files);
@@ -1185,9 +1175,7 @@ async function handleFixCommand(options) {
1185
1175
  console.log(color.dim(` Generated ${pkgName}`));
1186
1176
  }
1187
1177
  const vscodeSettingsExists = await fileExists$1(join$1(monorepoRoot, ".vscode/settings.json"));
1188
- const vscodeExtensionsExists = await fileExists$1(
1189
- join$1(monorepoRoot, ".vscode/extensions.json")
1190
- );
1178
+ const vscodeExtensionsExists = await fileExists$1(join$1(monorepoRoot, ".vscode/extensions.json"));
1191
1179
  const vscodeExists = vscodeSettingsExists && vscodeExtensionsExists;
1192
1180
  if (!vscodeExists) {
1193
1181
  let addVscode = false;
@@ -1243,10 +1231,37 @@ async function handleFixCommand(options) {
1243
1231
  }
1244
1232
  }
1245
1233
 
1234
+ function detectViteTemplate(pkg) {
1235
+ if (!hasPackage(pkg, "vite")) return void 0;
1236
+ if (hasPackage(pkg, "@react-three/fiber")) return "r3f";
1237
+ if (hasPackage(pkg, "react") || hasPackage(pkg, "@vitejs/plugin-react")) return "react";
1238
+ return "vanilla";
1239
+ }
1240
+ function renderExpectedViteConfig(template) {
1241
+ const isReact = template === "react" || template === "r3f";
1242
+ const useReactCompiler = template === "react";
1243
+ const codeSnippets = isReact ? {
1244
+ "vite-config-import": [
1245
+ useReactCompiler ? "import react, { reactCompilerPreset } from '@vitejs/plugin-react';" : "import react from '@vitejs/plugin-react';",
1246
+ ...useReactCompiler ? ["import babel from '@rolldown/plugin-babel';"] : []
1247
+ ]
1248
+ } : {};
1249
+ const viteConfig = {
1250
+ base: "./"
1251
+ };
1252
+ if (isReact) {
1253
+ viteConfig.plugins = useReactCompiler ? ["$raw:react()", "$raw:babel({ presets: [reactCompilerPreset()] })"] : ["$raw:react()"];
1254
+ }
1255
+ if (template === "r3f") {
1256
+ viteConfig.resolve = { dedupe: ["three"] };
1257
+ }
1258
+ return renderViteConfig({ viteConfig, codeSnippets });
1259
+ }
1246
1260
  async function detectCurrentConfig(root, isMonorepo = true) {
1247
1261
  let name = root.split(/[/\\]/).pop() ?? "workspace";
1248
1262
  let packageManager = "pnpm";
1249
1263
  let hasTypecheck = false;
1264
+ let viteTemplate;
1250
1265
  try {
1251
1266
  const pkgPath = join(root, "package.json");
1252
1267
  const content = await readFile$1(pkgPath, "utf-8");
@@ -1258,6 +1273,7 @@ async function detectCurrentConfig(root, isMonorepo = true) {
1258
1273
  packageManager = pkgJson.packageManager.split("@")[0] ?? packageManager;
1259
1274
  }
1260
1275
  hasTypecheck = pkgJson.scripts?.typecheck != null;
1276
+ viteTemplate = detectViteTemplate(pkgJson);
1261
1277
  } catch {
1262
1278
  }
1263
1279
  const tooling = await detectTooling(root);
@@ -1269,7 +1285,8 @@ async function detectCurrentConfig(root, isMonorepo = true) {
1269
1285
  packageManager,
1270
1286
  isMonorepo,
1271
1287
  configStrategy,
1272
- hasTypecheck
1288
+ hasTypecheck,
1289
+ viteTemplate
1273
1290
  };
1274
1291
  }
1275
1292
  async function detectSinglePackageConfigStrategy(root) {
@@ -1333,6 +1350,9 @@ async function planExpectedFiles(config) {
1333
1350
  content: toPrettierIgnoreContent()
1334
1351
  };
1335
1352
  }
1353
+ if (!isMonorepo && config.viteTemplate != null) {
1354
+ rootConfig["vite.config.ts"] = renderExpectedViteConfig(config.viteTemplate);
1355
+ }
1336
1356
  if (linter === "biome" || formatter === "biome") {
1337
1357
  const biomeVersion = getResolvedPackageVersion(versions, "@biomejs/biome");
1338
1358
  const biomeConfig = {
@@ -1576,6 +1596,11 @@ function hasPackage(pkg, name) {
1576
1596
  function sortPackageMap(packageMap) {
1577
1597
  return Object.fromEntries(Object.entries(packageMap).sort(([a], [b]) => a.localeCompare(b)));
1578
1598
  }
1599
+ function addMissingDevDependency(pkg, devDependencies, name) {
1600
+ if (!hasPackage(pkg, name)) {
1601
+ devDependencies[name] = formatResolvedPackageVersion({}, name);
1602
+ }
1603
+ }
1579
1604
  async function detectTypeScriptPackage(root, pkg) {
1580
1605
  if (hasPackage(pkg, "typescript")) return true;
1581
1606
  return await fileExists(join(root, "tsconfig.json")) || await fileExists(join(root, "tsconfig.app.json")) || await fileExists(join(root, ".config/tsconfig.app.json"));
@@ -1638,6 +1663,14 @@ async function getExpectedPackageDevDependencies(root, config, pkg) {
1638
1663
  if (shouldAddOxlintTypeAwareBackend) {
1639
1664
  nextDevDependencies["oxlint-tsgolint"] = formatResolvedPackageVersion({}, "oxlint-tsgolint");
1640
1665
  }
1666
+ if (!config.isMonorepo && config.viteTemplate === "react") {
1667
+ addMissingDevDependency(pkg, nextDevDependencies, "@babel/core");
1668
+ addMissingDevDependency(pkg, nextDevDependencies, "@rolldown/plugin-babel");
1669
+ addMissingDevDependency(pkg, nextDevDependencies, "babel-plugin-react-compiler");
1670
+ if (await detectTypeScriptPackage(root, pkg)) {
1671
+ addMissingDevDependency(pkg, nextDevDependencies, "@types/babel__core");
1672
+ }
1673
+ }
1641
1674
  return sortPackageMap(nextDevDependencies);
1642
1675
  }
1643
1676
  async function getPackageJsonScriptUpdates(root, config) {
@@ -1886,9 +1919,7 @@ async function collectUpdateCategories(projectRoot, config, isMonorepo) {
1886
1919
  category: "package-json",
1887
1920
  label: "package.json",
1888
1921
  changes: packageJsonScriptChanges,
1889
- hasUserModifications: packageJsonScriptChanges.some(
1890
- (change) => change.status === "modified"
1891
- )
1922
+ hasUserModifications: packageJsonScriptChanges.some((change) => change.status === "modified")
1892
1923
  });
1893
1924
  }
1894
1925
  const oxlintConfigChanges = await getOxlintConfigReplacementUpdates(projectRoot, config);
@@ -1907,9 +1938,7 @@ async function collectUpdateCategories(projectRoot, config, isMonorepo) {
1907
1938
  category: "workspace-config",
1908
1939
  label: "Workspace Config",
1909
1940
  changes: workspaceConfigChanges,
1910
- hasUserModifications: workspaceConfigChanges.some(
1911
- (change) => change.status === "modified"
1912
- )
1941
+ hasUserModifications: workspaceConfigChanges.some((change) => change.status === "modified")
1913
1942
  });
1914
1943
  }
1915
1944
  }
@@ -1949,9 +1978,7 @@ async function processUpdateCategory(category, projectRoot, options) {
1949
1978
  if (changesToApply.length > 0) {
1950
1979
  await applyUpdates(changesToApply, projectRoot);
1951
1980
  const addedCount = changesToApply.filter((change) => change.status === "added").length;
1952
- const updatedFilesCount = changesToApply.filter(
1953
- (change) => change.status === "modified"
1954
- ).length;
1981
+ const updatedFilesCount = changesToApply.filter((change) => change.status === "modified").length;
1955
1982
  const parts = [];
1956
1983
  if (addedCount > 0) parts.push(`added ${addedCount}`);
1957
1984
  if (updatedFilesCount > 0) parts.push(`updated ${updatedFilesCount}`);
@@ -2378,10 +2405,7 @@ async function main() {
2378
2405
  ).option(
2379
2406
  "--node-version <version>",
2380
2407
  'set Node.js version for engines.node field (default: "latest")'
2381
- ).option("--workspace", "Add package to current monorepo workspace (non-interactive)").option("--dir <directory>", "Target directory for --workspace (default: apps/ or packages/)").option("--clear-config", "Clear saved preferences").option("--config-path", "Print the path to the config file").option("--check", "Check if current directory is in a valid monorepo workspace").option("--fix", "Fix monorepo by generating missing .config packages").option("--update", "Update monorepo workspace to latest configuration").option("-y, --yes", "Non-interactive mode - accept all prompts").option(
2382
- "--path <directory>",
2383
- "Run in specified directory instead of current working directory"
2384
- ).action(async (name, options) => {
2408
+ ).option("--workspace", "Add package to current monorepo workspace (non-interactive)").option("--dir <directory>", "Target directory for --workspace (default: apps/ or packages/)").option("--clear-config", "Clear saved preferences").option("--config-path", "Print the path to the config file").option("--check", "Check if current directory is in a valid monorepo workspace").option("--fix", "Fix monorepo by generating missing .config packages").option("--update", "Update monorepo workspace to latest configuration").option("-y, --yes", "Non-interactive mode - accept all prompts").option("--path <directory>", "Run in specified directory instead of current working directory").action(async (name, options) => {
2385
2409
  if (options.path) {
2386
2410
  process.chdir(options.path);
2387
2411
  }
@@ -2443,9 +2467,7 @@ async function main() {
2443
2467
  }
2444
2468
  if (options.dir && !options.workspace) {
2445
2469
  console.error(color.red("Error:") + " --dir requires --workspace flag");
2446
- console.log(
2447
- color.dim(" Example: pnpm create krispya my-lib --workspace --dir examples")
2448
- );
2470
+ console.log(color.dim(" Example: pnpm create krispya my-lib --workspace --dir examples"));
2449
2471
  process.exit(1);
2450
2472
  }
2451
2473
  if (options.workspace) {
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const workspace = require('./shared/create-krispya.DTHeUlq4.cjs');
3
+ const workspace = require('./shared/create-krispya.FNrYi_5V.cjs');
4
4
  require('fs/promises');
5
5
  require('fs');
6
6
  require('path');
@@ -44,6 +44,7 @@ exports.getLanguageFromTemplate = workspace.getLanguageFromTemplate;
44
44
  exports.getLatestNodeVersion = workspace.getLatestNodeVersion;
45
45
  exports.getLatestNpmCliVersion = workspace.getLatestNpmCliVersion;
46
46
  exports.getLatestNpmMajorVersion = workspace.getLatestNpmMajorVersion;
47
+ exports.getLatestNpmMajorVersionAtOrBelow = workspace.getLatestNpmMajorVersionAtOrBelow;
47
48
  exports.getLatestNpmVersion = workspace.getLatestNpmVersion;
48
49
  exports.getLatestPnpmVersion = workspace.getLatestPnpmVersion;
49
50
  exports.getLatestYarnVersion = workspace.getLatestYarnVersion;
@@ -54,6 +55,7 @@ exports.planWorkspace = workspace.planWorkspace;
54
55
  exports.projectPlanInputToOptions = workspace.projectPlanInputToOptions;
55
56
  exports.resolveProjectPlanInput = workspace.resolveProjectPlanInput;
56
57
  exports.resolveWorkspacePlanInput = workspace.resolveWorkspacePlanInput;
58
+ exports.shouldEnableReactCompiler = workspace.shouldEnableReactCompiler;
57
59
  exports.unique = workspace.unique;
58
60
  exports.validatePackageName = workspace.validatePackageName;
59
61
  exports.workspacePlanInputToMonorepoParams = workspace.workspacePlanInputToMonorepoParams;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FormatterMetaConfig, L as LinterMetaConfig, V as VirtualFileMap, C as CodeInjectionLocation, P as ProjectType, a as ConfigStrategy, E as EngineSpec, b as PackageVersions, c as Linter, d as Formatter, T as Testing, e as LibraryBundler, I as Ide, f as PackageManagerSpec, g as ProjectPlanInput, h as ProjectOptions, A as AiPlatform, W as WorkspacePlanInput } from './shared/create-krispya.to8NBxeJ.cjs';
2
- export { i as AiAgentsMetaConfig, B as BaseTemplate, D as DependencyVersionOptions, j as EditorMetaConfig, k as EngineName, l as FeatureSelections, m as FileRenderer, n as LibraryBundlerMetaConfig, o as PackageManagerMetaConfig, p as PackageManagerName, q as PlanBuilder, r as PlanDreiOptions, s as PlanFiberOptions, t as PlanGithubPagesOptions, u as PlanHandleOptions, v as PlanKootaOptions, w as PlanLevaOptions, x as PlanOffscreenOptions, y as PlanPostprocessingOptions, z as PlanRapierOptions, G as PlanTriplexOptions, H as PlanUikitOptions, J as PlanViverseOptions, K as PlanXrOptions, M as PlanZustandOptions, N as ProjectMetaConfig, O as ProjectPlanContext, Q as Template, R as TestingMetaConfig, S as ToolConfig, U as TypeScriptMetaConfig, X as VersionRangePrefix, Y as VirtualFile, Z as WorkspacePlanContext, _ as getBaseTemplate, $ as getLanguageFromTemplate } from './shared/create-krispya.to8NBxeJ.cjs';
1
+ import { F as FormatterMetaConfig, L as LinterMetaConfig, V as VirtualFileMap, C as CodeInjectionLocation, P as ProjectType, a as ConfigStrategy, E as EngineSpec, b as PackageVersions, c as Linter, d as Formatter, T as Testing, e as LibraryBundler, I as Ide, f as PackageManagerSpec, g as ProjectPlanInput, h as ProjectOptions, A as AiPlatform, W as WorkspacePlanInput } from './shared/create-krispya.CcQTepKu.cjs';
2
+ export { i as AiAgentsMetaConfig, B as BaseTemplate, D as DependencyVersionOptions, j as EditorMetaConfig, k as EngineName, l as FeatureSelections, m as FileRenderer, n as LibraryBundlerMetaConfig, o as PackageManagerMetaConfig, p as PackageManagerName, q as PlanBuilder, r as PlanDreiOptions, s as PlanFiberOptions, t as PlanGithubPagesOptions, u as PlanHandleOptions, v as PlanKootaOptions, w as PlanLevaOptions, x as PlanOffscreenOptions, y as PlanPostprocessingOptions, z as PlanRapierOptions, G as PlanTriplexOptions, H as PlanUikitOptions, J as PlanViverseOptions, K as PlanXrOptions, M as PlanZustandOptions, N as ProjectMetaConfig, O as ProjectPlanContext, Q as Template, R as TestingMetaConfig, S as ToolConfig, U as TypeScriptMetaConfig, X as VersionRangePrefix, Y as VirtualFile, Z as WorkspacePlanContext, _ as getBaseTemplate, $ as getLanguageFromTemplate, a0 as shouldEnableReactCompiler } from './shared/create-krispya.CcQTepKu.cjs';
3
3
 
4
4
  type MetaConfig = {
5
5
  formatter: FormatterMetaConfig;
@@ -118,6 +118,10 @@ declare function getLatestNpmVersion(packageName: string, fallback: string): Pro
118
118
  * Fetches the latest npm version within a specific major version.
119
119
  */
120
120
  declare function getLatestNpmMajorVersion(packageName: string, majorVersion: string, fallback: string): Promise<string>;
121
+ /**
122
+ * Fetches the latest npm version within the requested major, falling back to lower majors.
123
+ */
124
+ declare function getLatestNpmMajorVersionAtOrBelow(packageName: string, majorVersion: string, fallback: string): Promise<string>;
121
125
  declare function getLatestPnpmVersion(): Promise<string>;
122
126
  declare function getLatestYarnVersion(): Promise<string>;
123
127
  declare function getLatestNpmCliVersion(): Promise<string>;
@@ -125,5 +129,5 @@ declare function getLatestNodeVersion(): Promise<string>;
125
129
 
126
130
  declare function parseWorkspaceYamlContent(content: string): string[];
127
131
 
128
- export { AiPlatform, CodeInjectionLocation, ConfigStrategy, EngineSpec, Formatter, FormatterMetaConfig, Ide, LibraryBundler, Linter, LinterMetaConfig, PackageManagerSpec, PackageVersions, ProjectOptions, ProjectPlanInput, ProjectType, Testing, VirtualFileMap, WorkspacePlanInput, detectTooling, generateRandomName, getLatestNodeVersion, getLatestNpmCliVersion, getLatestNpmMajorVersion, getLatestNpmVersion, getLatestPnpmVersion, getLatestYarnVersion, merge, mergePartialPlans, parseWorkspaceYamlContent, planProject, planWorkspace, projectPlanInputToOptions, resolveProjectPlanInput, resolveWorkspacePlanInput, unique, validatePackageName, workspacePlanInputToMonorepoParams };
132
+ export { AiPlatform, CodeInjectionLocation, ConfigStrategy, EngineSpec, Formatter, FormatterMetaConfig, Ide, LibraryBundler, Linter, LinterMetaConfig, PackageManagerSpec, PackageVersions, ProjectOptions, ProjectPlanInput, ProjectType, Testing, VirtualFileMap, WorkspacePlanInput, detectTooling, generateRandomName, getLatestNodeVersion, getLatestNpmCliVersion, getLatestNpmMajorVersion, getLatestNpmMajorVersionAtOrBelow, getLatestNpmVersion, getLatestPnpmVersion, getLatestYarnVersion, merge, mergePartialPlans, parseWorkspaceYamlContent, planProject, planWorkspace, projectPlanInputToOptions, resolveProjectPlanInput, resolveWorkspacePlanInput, unique, validatePackageName, workspacePlanInputToMonorepoParams };
129
133
  export type { DetectedTooling, MetaConfig, PartialPlan, ProjectContext, ProjectPlan, ToolSelections };