@donotdev/cli 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dependencies-matrix.json +234 -114
  2. package/dist/bin/commands/build.js +9 -3
  3. package/dist/bin/commands/bump.js +119 -100
  4. package/dist/bin/commands/cacheout.js +9 -3
  5. package/dist/bin/commands/create-app.js +60 -34
  6. package/dist/bin/commands/create-project.js +61 -34
  7. package/dist/bin/commands/deploy.js +22 -14
  8. package/dist/bin/commands/dev.js +9 -3
  9. package/dist/bin/commands/emu.js +9 -3
  10. package/dist/bin/commands/format.js +9 -3
  11. package/dist/bin/commands/lint.js +9 -3
  12. package/dist/bin/commands/make-admin.d.ts +11 -0
  13. package/dist/bin/commands/make-admin.d.ts.map +1 -0
  14. package/dist/bin/commands/make-admin.js +12 -0
  15. package/dist/bin/commands/make-admin.js.map +1 -0
  16. package/dist/bin/commands/preview.js +9 -3
  17. package/dist/bin/commands/sync-secrets.js +9 -3
  18. package/dist/index.js +72 -44
  19. package/package.json +1 -1
  20. package/templates/app-demo/index.html.example +4 -0
  21. package/templates/app-demo/src/App.tsx.example +28 -10
  22. package/templates/app-demo/src/config/app.ts.example +56 -0
  23. package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +5 -5
  24. package/templates/app-next/src/app/ClientLayout.tsx.example +5 -4
  25. package/templates/app-next/src/app/layout.tsx.example +17 -25
  26. package/templates/app-next/src/globals.css.example +10 -7
  27. package/templates/app-next/src/locales/dndev_en.json.example +68 -0
  28. package/templates/app-next/src/pages/locales/example_en.json.example +5 -0
  29. package/templates/app-vite/index.html.example +3 -0
  30. package/templates/app-vite/src/App.tsx.example +1 -1
  31. package/templates/app-vite/src/globals.css.example +14 -6
  32. package/templates/app-vite/src/locales/dndev_en.json.example +68 -0
  33. package/templates/functions-firebase/README.md.example +25 -0
  34. package/templates/functions-firebase/tsconfig.json.example +3 -13
  35. package/templates/functions-vercel/tsconfig.json.example +1 -13
  36. package/templates/root-consumer/firebase.json.example +1 -1
  37. package/templates/root-consumer/guides/AGENT_START_HERE.md.example +229 -7
  38. package/templates/root-consumer/guides/COMPONENTS_ADV.md.example +456 -0
  39. package/templates/root-consumer/guides/COMPONENTS_ATOMIC.md.example +43 -1
  40. package/templates/root-consumer/guides/COMPONENTS_UI.md.example +6 -0
  41. package/templates/root-consumer/guides/INDEX.md.example +3 -0
  42. package/templates/root-consumer/guides/SETUP_APP_CONFIG.md.example +5 -2
  43. package/templates/root-consumer/guides/SETUP_BILLING.md.example +44 -4
  44. package/templates/root-consumer/guides/SETUP_CRUD.md.example +1244 -0
  45. package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +52 -0
  46. package/templates/root-consumer/guides/SETUP_I18N.md.example +145 -6
  47. package/templates/root-consumer/guides/SETUP_LAYOUTS.md.example +18 -0
  48. package/templates/root-consumer/guides/SETUP_PAGES.md.example +25 -0
  49. package/templates/root-consumer/guides/SETUP_PWA.md.example +213 -0
  50. package/templates/root-consumer/guides/USE_ROUTING.md.example +503 -0
  51. package/templates/root-consumer/vercel.json.example +315 -20
  52. package/templates/app-demo/src/Routes.tsx.example +0 -20
  53. package/templates/app-vite/src/Routes.tsx.example +0 -16
  54. package/templates/app-vite/src/pages/locales/README.md.example +0 -1
@@ -7425,11 +7425,17 @@ var init_PathResolver = __esm({
7425
7425
  /**
7426
7426
  * Get path to empty.js module for optional dependency aliasing
7427
7427
  * Used by Vite and Turbopack to alias missing optional deps
7428
- * @returns Absolute path to empty.js
7428
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7429
+ * @returns Package specifier or absolute path to empty.js
7429
7430
  */
7430
- getEmptyModulePath() {
7431
+ getEmptyModulePath(returnPackageSpecifier = false) {
7432
+ if (returnPackageSpecifier) {
7433
+ return "@donotdev/core/empty";
7434
+ }
7435
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7436
+ if (resolved) return resolved;
7431
7437
  const thisDir = dirname(fileURLToPath(import.meta.url));
7432
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7438
+ return this.normalizePath(join(thisDir, "../empty.js"));
7433
7439
  }
7434
7440
  // === PRIVATE METHODS ===
7435
7441
  /**
@@ -7489,10 +7495,6 @@ import {
7489
7495
  resolve as resolve2,
7490
7496
  isAbsolute as pathIsAbsolute
7491
7497
  } from "node:path";
7492
- import { fileURLToPath as fileURLToPath2 } from "node:url";
7493
- function getDirnameFromUrl(importMetaUrl) {
7494
- return dirname2(fileURLToPath2(importMetaUrl));
7495
- }
7496
7498
  function detectExecutionMode() {
7497
7499
  const currentDir = process.cwd();
7498
7500
  const toolingPath = joinPath(currentDir, PACKAGE_PATHS.TOOLING);
@@ -7505,10 +7507,6 @@ function detectExecutionMode() {
7505
7507
  }
7506
7508
  return "published";
7507
7509
  }
7508
- function getCliRootFromBundle() {
7509
- const currentDir = getDirnameFromUrl(import.meta.url);
7510
- return normalizePath(currentDir, "..", "..", "..");
7511
- }
7512
7510
  function globSync(pattern, options = {}) {
7513
7511
  const patterns = Array.isArray(pattern) ? pattern : [pattern];
7514
7512
  const cwd = options.cwd || pathResolverInstance.getAppRoot() || process.cwd();
@@ -7566,7 +7564,7 @@ var init_pathResolver = __esm({
7566
7564
 
7567
7565
  // packages/tooling/src/bundler/utils.ts
7568
7566
  import { createRequire as createRequire3 } from "node:module";
7569
- import { fileURLToPath as fileURLToPath3 } from "node:url";
7567
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
7570
7568
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
7571
7569
  import { Buffer as Buffer2 } from "node:buffer";
7572
7570
  import process from "node:process";
@@ -7575,7 +7573,7 @@ var init_utils = __esm({
7575
7573
  "packages/tooling/src/bundler/utils.ts"() {
7576
7574
  "use strict";
7577
7575
  require2 = createRequire3(import.meta.url);
7578
- __filename = fileURLToPath3(import.meta.url);
7576
+ __filename = fileURLToPath2(import.meta.url);
7579
7577
  __dirname = dirname3(__filename);
7580
7578
  if (typeof globalThis !== "undefined") {
7581
7579
  globalThis.require = require2;
@@ -7617,52 +7615,60 @@ async function askForConfirmation(message, defaultValue = false) {
7617
7615
  // packages/tooling/src/utils/matrix.ts
7618
7616
  init_utils();
7619
7617
  init_pathResolver();
7618
+ import { createRequire as createRequire4 } from "node:module";
7620
7619
  var cachedMatrix = null;
7621
7620
  function getMatrixPath(mode) {
7621
+ try {
7622
+ const require3 = createRequire4(import.meta.url);
7623
+ const resolved = require3.resolve("@donotdev/cli/dependencies-matrix.json");
7624
+ if (pathExists(resolved)) {
7625
+ return resolved;
7626
+ }
7627
+ } catch {
7628
+ }
7622
7629
  const executionMode = mode || detectExecutionMode();
7623
7630
  if (executionMode === "development") {
7624
7631
  const repoRoot = getRepoRoot();
7625
- const devPath = normalizePath(
7626
- repoRoot,
7627
- "packages/cli/dependencies-matrix.json"
7628
- );
7629
- if (!pathExists(devPath)) {
7630
- throw new Error(`[DEV] Matrix not found at: ${devPath}`);
7632
+ if (repoRoot) {
7633
+ const devPath = normalizePath(
7634
+ repoRoot,
7635
+ "packages/cli/dependencies-matrix.json"
7636
+ );
7637
+ if (pathExists(devPath)) {
7638
+ return devPath;
7639
+ }
7631
7640
  }
7632
- return devPath;
7633
- }
7634
- const cliPackagePath = getCliRootFromBundle();
7635
- const matrixPath = joinPath(cliPackagePath, "dependencies-matrix.json");
7636
- if (!pathExists(matrixPath)) {
7637
- throw new Error(`[PROD] Matrix not found at: ${matrixPath}`);
7638
7641
  }
7639
- return matrixPath;
7642
+ return null;
7640
7643
  }
7641
7644
  function getCliVersion(mode) {
7645
+ try {
7646
+ const require3 = createRequire4(import.meta.url);
7647
+ const packageJsonPath = require3.resolve("@donotdev/cli/package.json");
7648
+ const pkg = readSync(packageJsonPath, { format: "json" });
7649
+ return String(pkg?.version || "0.0.0");
7650
+ } catch {
7651
+ }
7642
7652
  const executionMode = mode || detectExecutionMode();
7643
7653
  if (executionMode === "development") {
7644
7654
  const repoRoot = getRepoRoot();
7645
7655
  const cliPackageJson = joinPath(repoRoot, "packages/cli/package.json");
7646
- if (!pathExists(cliPackageJson)) {
7647
- throw new Error(`[DEV] CLI package.json not found at: ${cliPackageJson}`);
7656
+ if (pathExists(cliPackageJson)) {
7657
+ const pkg = readSync(cliPackageJson, { format: "json" });
7658
+ return String(pkg?.version || "0.0.0");
7648
7659
  }
7649
- const pkg2 = readSync(cliPackageJson, { format: "json" });
7650
- return String(pkg2?.version || "0.0.0");
7651
- }
7652
- const cliPackagePath = getCliRootFromBundle();
7653
- const packageJsonPath = joinPath(cliPackagePath, "package.json");
7654
- if (!pathExists(packageJsonPath)) {
7655
- throw new Error(`[PROD] CLI package.json not found at: ${packageJsonPath}`);
7656
7660
  }
7657
- const pkg = readSync(packageJsonPath, { format: "json" });
7658
- return String(pkg?.version || "0.0.0");
7661
+ return "0.0.0";
7659
7662
  }
7660
7663
  function loadMatrix(mode) {
7661
7664
  if (cachedMatrix) return cachedMatrix;
7662
7665
  const matrixPath = getMatrixPath(mode);
7666
+ if (!matrixPath) {
7667
+ return null;
7668
+ }
7663
7669
  const content = readSync(matrixPath, { format: "json" });
7664
7670
  if (!content) {
7665
- throw new Error(`Failed to read dependencies-matrix.json at ${matrixPath}`);
7671
+ return null;
7666
7672
  }
7667
7673
  cachedMatrix = {
7668
7674
  matrix: content,
@@ -7680,9 +7686,10 @@ function flattenGroups(groups) {
7680
7686
  return flat;
7681
7687
  }
7682
7688
  function getMigrationGuide(currentMajor, targetMajor, mode) {
7683
- const { matrix } = loadMatrix(mode);
7689
+ const matrixResult = loadMatrix(mode);
7690
+ if (!matrixResult) return void 0;
7684
7691
  const key = `${currentMajor}.0\u2192${targetMajor}.0`;
7685
- return matrix.migrationGuides?.[key];
7692
+ return matrixResult.matrix.migrationGuides?.[key];
7686
7693
  }
7687
7694
 
7688
7695
  // packages/tooling/src/utils/package-deps.ts
@@ -7772,7 +7779,7 @@ async function queryNpmVersions(packages) {
7772
7779
  function detectProjectDeps(files) {
7773
7780
  const frameworkPkgs = /* @__PURE__ */ new Set();
7774
7781
  const externalDeps = /* @__PURE__ */ new Set();
7775
- const currentVersions = /* @__PURE__ */ new Map();
7782
+ const packageOccurrences = /* @__PURE__ */ new Map();
7776
7783
  for (const file of files) {
7777
7784
  const pkg = parsePackageJson(file);
7778
7785
  if (!pkg) continue;
@@ -7784,9 +7791,10 @@ function detectProjectDeps(files) {
7784
7791
  if (!deps) continue;
7785
7792
  for (const [name, version] of Object.entries(deps)) {
7786
7793
  const key = `${name}:${field}`;
7787
- if (!currentVersions.has(key)) {
7788
- currentVersions.set(key, { version, field, file });
7794
+ if (!packageOccurrences.has(key)) {
7795
+ packageOccurrences.set(key, []);
7789
7796
  }
7797
+ packageOccurrences.get(key).push({ version, field, file });
7790
7798
  if (name.startsWith("@donotdev/")) {
7791
7799
  frameworkPkgs.add(name);
7792
7800
  } else {
@@ -7795,7 +7803,7 @@ function detectProjectDeps(files) {
7795
7803
  }
7796
7804
  }
7797
7805
  }
7798
- return { frameworkPkgs, externalDeps, currentVersions };
7806
+ return { frameworkPkgs, externalDeps, packageOccurrences };
7799
7807
  }
7800
7808
  async function main(options = {}) {
7801
7809
  const { dryRun } = options;
@@ -7816,16 +7824,21 @@ async function main(options = {}) {
7816
7824
  return 0;
7817
7825
  }
7818
7826
  log.info(`Found ${files.length} package.json file(s)`);
7819
- const { frameworkPkgs, externalDeps, currentVersions } = detectProjectDeps(files);
7827
+ const { frameworkPkgs, externalDeps, packageOccurrences } = detectProjectDeps(files);
7820
7828
  log.info(`Found ${frameworkPkgs.size} @donotdev/* package(s)`);
7821
7829
  log.info(`Found ${externalDeps.size} external dep(s)`);
7822
7830
  log.info("Querying npm...");
7823
7831
  const npmVersions = await queryNpmVersions(Array.from(frameworkPkgs));
7824
- const { matrix } = loadMatrix();
7825
- const matrixVersions = flattenGroups(matrix.groups);
7832
+ const matrixResult = loadMatrix();
7833
+ const matrixVersions = matrixResult ? flattenGroups(matrixResult.matrix.groups) : {};
7834
+ if (!matrixResult && externalDeps.size > 0) {
7835
+ log.info(
7836
+ "Matrix not found - only updating @donotdev/* packages (external deps skipped)"
7837
+ );
7838
+ }
7826
7839
  const updates = [];
7827
7840
  const majorUpdates = [];
7828
- for (const [key, current] of currentVersions) {
7841
+ for (const [key, occurrences] of packageOccurrences) {
7829
7842
  const [name, field] = key.split(":");
7830
7843
  if (name === "@donotdev/templates") continue;
7831
7844
  let latest;
@@ -7835,29 +7848,33 @@ async function main(options = {}) {
7835
7848
  latest = matrixVersions[name];
7836
7849
  }
7837
7850
  if (!latest) continue;
7838
- const cmp = compareVersions(current.version, latest);
7839
- if (cmp.equal || cmp.ahead) continue;
7840
- const update = {
7841
- pkg: name,
7842
- field,
7843
- current: current.version,
7844
- latest,
7845
- file: current.file,
7846
- isMajor: cmp.isMajor
7847
- };
7848
- if (cmp.isMajor) {
7849
- const currentMajor = Number(
7850
- normalizeVersion(current.version).split(".")[0]
7851
- );
7852
- const latestMajor = Number(normalizeVersion(latest).split(".")[0]);
7853
- const guide = getMigrationGuide(currentMajor, latestMajor);
7854
- if (guide) {
7855
- update.migrationPath = guide.path;
7856
- update.breakingChanges = guide.breakingChanges;
7851
+ for (const occurrence of occurrences) {
7852
+ const normalizedCurrent = normalizeVersion(occurrence.version);
7853
+ const normalizedLatest = normalizeVersion(latest);
7854
+ const cmp = compareVersions(normalizedCurrent, normalizedLatest);
7855
+ if (cmp.equal || cmp.ahead) continue;
7856
+ const update = {
7857
+ pkg: name,
7858
+ field,
7859
+ current: occurrence.version,
7860
+ latest,
7861
+ file: occurrence.file,
7862
+ isMajor: cmp.isMajor
7863
+ };
7864
+ if (cmp.isMajor) {
7865
+ const currentMajor = Number(normalizedCurrent.split(".")[0]);
7866
+ const latestMajor = Number(normalizedLatest.split(".")[0]);
7867
+ if (matrixResult) {
7868
+ const guide = getMigrationGuide(currentMajor, latestMajor);
7869
+ if (guide) {
7870
+ update.migrationPath = guide.path;
7871
+ update.breakingChanges = guide.breakingChanges;
7872
+ }
7873
+ }
7874
+ majorUpdates.push(update);
7875
+ } else {
7876
+ updates.push(update);
7857
7877
  }
7858
- majorUpdates.push(update);
7859
- } else {
7860
- updates.push(update);
7861
7878
  }
7862
7879
  }
7863
7880
  if (updates.length === 0 && majorUpdates.length === 0) {
@@ -7894,20 +7911,13 @@ ${majorUpdates.length} major update(s) available (manual review required):`
7894
7911
  let shouldApply = false;
7895
7912
  if (dryRun) {
7896
7913
  log.info("\n[DRY RUN] Would update package.json files:");
7897
- for (const file of files) {
7898
- const pkg = parsePackageJson(file);
7899
- if (!pkg) continue;
7900
- for (const u2 of updates) {
7901
- for (const field of [
7902
- "dependencies",
7903
- "devDependencies",
7904
- "peerDependencies"
7905
- ]) {
7906
- if (pkg[field]?.[u2.pkg]) {
7907
- log.info(` ${file}: ${u2.pkg} \u2192 ^${u2.latest}`);
7908
- }
7909
- }
7910
- }
7914
+ for (const u2 of updates) {
7915
+ const relativeFile = appRoot ? getRelativePathBetween(appRoot, u2.file) : u2.file;
7916
+ const normalizedLatest = normalizeVersion(u2.latest);
7917
+ const displayLatest = ensureCaretPrefix(normalizedLatest);
7918
+ log.info(
7919
+ ` ${relativeFile}: ${u2.pkg} ${u2.current} \u2192 ${displayLatest} (${u2.field})`
7920
+ );
7911
7921
  }
7912
7922
  log.info("\n[DRY RUN] No files modified");
7913
7923
  } else {
@@ -7916,32 +7926,41 @@ ${majorUpdates.length} major update(s) available (manual review required):`
7916
7926
  );
7917
7927
  shouldApply = await askForConfirmation("Apply updates?", true);
7918
7928
  if (shouldApply) {
7919
- const updatedFiles = /* @__PURE__ */ new Set();
7920
- for (const file of files) {
7929
+ const updatedFiles = /* @__PURE__ */ new Map();
7930
+ for (const u2 of updates) {
7931
+ if (!updatedFiles.has(u2.file)) {
7932
+ updatedFiles.set(u2.file, /* @__PURE__ */ new Set());
7933
+ }
7934
+ updatedFiles.get(u2.file).add(`${u2.pkg}:${u2.field}`);
7935
+ }
7936
+ for (const [file, packageKeys] of updatedFiles) {
7921
7937
  const pkg = parsePackageJson(file);
7922
7938
  if (!pkg) continue;
7923
7939
  let changed = false;
7924
- for (const u2 of updates) {
7925
- for (const field of [
7926
- "dependencies",
7927
- "devDependencies",
7928
- "peerDependencies"
7929
- ]) {
7930
- const deps = pkg[field];
7931
- if (deps?.[u2.pkg]) {
7932
- deps[u2.pkg] = ensureCaretPrefix(u2.latest);
7933
- changed = true;
7934
- }
7940
+ for (const packageKey of packageKeys) {
7941
+ const [pkgName, field] = packageKey.split(":");
7942
+ const update = updates.find(
7943
+ (u2) => u2.file === file && u2.pkg === pkgName && u2.field === field
7944
+ );
7945
+ if (!update) continue;
7946
+ const deps = pkg[field];
7947
+ if (deps?.[pkgName]) {
7948
+ const normalizedLatest = normalizeVersion(update.latest);
7949
+ deps[pkgName] = ensureCaretPrefix(normalizedLatest);
7950
+ changed = true;
7935
7951
  }
7936
7952
  }
7937
7953
  if (changed) {
7938
7954
  writePackageJson(file, pkg);
7939
- updatedFiles.add(file);
7955
+ const relativeFile = appRoot ? getRelativePathBetween(appRoot, file) : file;
7956
+ log.info(`Updated: ${relativeFile}`);
7940
7957
  }
7941
7958
  }
7942
7959
  if (updatedFiles.size > 0) {
7943
- log.success(`
7944
- Done. Run "bun install" to apply.`);
7960
+ log.success(
7961
+ `
7962
+ Done. Updated ${updatedFiles.size} file(s). Run "bun install" to apply.`
7963
+ );
7945
7964
  }
7946
7965
  } else {
7947
7966
  log.info("\nUpdates not applied");
@@ -7141,11 +7141,17 @@ var init_PathResolver = __esm({
7141
7141
  /**
7142
7142
  * Get path to empty.js module for optional dependency aliasing
7143
7143
  * Used by Vite and Turbopack to alias missing optional deps
7144
- * @returns Absolute path to empty.js
7144
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7145
+ * @returns Package specifier or absolute path to empty.js
7145
7146
  */
7146
- getEmptyModulePath() {
7147
+ getEmptyModulePath(returnPackageSpecifier = false) {
7148
+ if (returnPackageSpecifier) {
7149
+ return "@donotdev/core/empty";
7150
+ }
7151
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7152
+ if (resolved) return resolved;
7147
7153
  const thisDir = dirname(fileURLToPath(import.meta.url));
7148
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7154
+ return this.normalizePath(join(thisDir, "../empty.js"));
7149
7155
  }
7150
7156
  // === PRIVATE METHODS ===
7151
7157
  /**
@@ -7687,11 +7687,17 @@ var init_PathResolver = __esm({
7687
7687
  /**
7688
7688
  * Get path to empty.js module for optional dependency aliasing
7689
7689
  * Used by Vite and Turbopack to alias missing optional deps
7690
- * @returns Absolute path to empty.js
7690
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7691
+ * @returns Package specifier or absolute path to empty.js
7691
7692
  */
7692
- getEmptyModulePath() {
7693
+ getEmptyModulePath(returnPackageSpecifier = false) {
7694
+ if (returnPackageSpecifier) {
7695
+ return "@donotdev/core/empty";
7696
+ }
7697
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7698
+ if (resolved) return resolved;
7693
7699
  const thisDir = dirname(fileURLToPath(import.meta.url));
7694
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7700
+ return this.normalizePath(join(thisDir, "../empty.js"));
7695
7701
  }
7696
7702
  // === PRIVATE METHODS ===
7697
7703
  /**
@@ -8432,52 +8438,60 @@ async function updateRootPackageJson(rootDir, appNames) {
8432
8438
  // packages/tooling/src/utils/matrix.ts
8433
8439
  init_utils();
8434
8440
  init_pathResolver();
8441
+ import { createRequire as createRequire4 } from "node:module";
8435
8442
  var cachedMatrix = null;
8436
8443
  function getMatrixPath(mode) {
8444
+ try {
8445
+ const require3 = createRequire4(import.meta.url);
8446
+ const resolved = require3.resolve("@donotdev/cli/dependencies-matrix.json");
8447
+ if (pathExists(resolved)) {
8448
+ return resolved;
8449
+ }
8450
+ } catch {
8451
+ }
8437
8452
  const executionMode = mode || detectExecutionMode();
8438
8453
  if (executionMode === "development") {
8439
8454
  const repoRoot = getRepoRoot();
8440
- const devPath = normalizePath(
8441
- repoRoot,
8442
- "packages/cli/dependencies-matrix.json"
8443
- );
8444
- if (!pathExists(devPath)) {
8445
- throw new Error(`[DEV] Matrix not found at: ${devPath}`);
8455
+ if (repoRoot) {
8456
+ const devPath = normalizePath(
8457
+ repoRoot,
8458
+ "packages/cli/dependencies-matrix.json"
8459
+ );
8460
+ if (pathExists(devPath)) {
8461
+ return devPath;
8462
+ }
8446
8463
  }
8447
- return devPath;
8448
8464
  }
8449
- const cliPackagePath = getCliRootFromBundle();
8450
- const matrixPath = joinPath(cliPackagePath, "dependencies-matrix.json");
8451
- if (!pathExists(matrixPath)) {
8452
- throw new Error(`[PROD] Matrix not found at: ${matrixPath}`);
8453
- }
8454
- return matrixPath;
8465
+ return null;
8455
8466
  }
8456
8467
  function getCliVersion(mode) {
8468
+ try {
8469
+ const require3 = createRequire4(import.meta.url);
8470
+ const packageJsonPath = require3.resolve("@donotdev/cli/package.json");
8471
+ const pkg = readSync(packageJsonPath, { format: "json" });
8472
+ return String(pkg?.version || "0.0.0");
8473
+ } catch {
8474
+ }
8457
8475
  const executionMode = mode || detectExecutionMode();
8458
8476
  if (executionMode === "development") {
8459
8477
  const repoRoot = getRepoRoot();
8460
8478
  const cliPackageJson = joinPath(repoRoot, "packages/cli/package.json");
8461
- if (!pathExists(cliPackageJson)) {
8462
- throw new Error(`[DEV] CLI package.json not found at: ${cliPackageJson}`);
8479
+ if (pathExists(cliPackageJson)) {
8480
+ const pkg = readSync(cliPackageJson, { format: "json" });
8481
+ return String(pkg?.version || "0.0.0");
8463
8482
  }
8464
- const pkg2 = readSync(cliPackageJson, { format: "json" });
8465
- return String(pkg2?.version || "0.0.0");
8466
8483
  }
8467
- const cliPackagePath = getCliRootFromBundle();
8468
- const packageJsonPath = joinPath(cliPackagePath, "package.json");
8469
- if (!pathExists(packageJsonPath)) {
8470
- throw new Error(`[PROD] CLI package.json not found at: ${packageJsonPath}`);
8471
- }
8472
- const pkg = readSync(packageJsonPath, { format: "json" });
8473
- return String(pkg?.version || "0.0.0");
8484
+ return "0.0.0";
8474
8485
  }
8475
8486
  function loadMatrix(mode) {
8476
8487
  if (cachedMatrix) return cachedMatrix;
8477
8488
  const matrixPath = getMatrixPath(mode);
8489
+ if (!matrixPath) {
8490
+ return null;
8491
+ }
8478
8492
  const content = readSync(matrixPath, { format: "json" });
8479
8493
  if (!content) {
8480
- throw new Error(`Failed to read dependencies-matrix.json at ${matrixPath}`);
8494
+ return null;
8481
8495
  }
8482
8496
  cachedMatrix = {
8483
8497
  matrix: content,
@@ -8627,7 +8641,7 @@ function generateScripts(templateName, options) {
8627
8641
  const scripts = {};
8628
8642
  if (templateName.includes("vite")) {
8629
8643
  scripts.dev = "vite";
8630
- scripts.build = "tsc --noEmit && cross-env NODE_ENV=production VITE_NODE_POLYFILL=true vite build";
8644
+ scripts.build = "vite build";
8631
8645
  scripts.preview = "vite preview";
8632
8646
  scripts.lint = "eslint src/";
8633
8647
  scripts["type-check"] = "tsc --noEmit";
@@ -8661,7 +8675,13 @@ function generateScripts(templateName, options) {
8661
8675
  return scripts;
8662
8676
  }
8663
8677
  function generatePackageJson(templateName, mode, options = {}) {
8664
- const { matrix, cliVersion } = loadMatrix(mode);
8678
+ const matrixResult = loadMatrix(mode);
8679
+ if (!matrixResult) {
8680
+ throw new Error(
8681
+ "dependencies-matrix.json not found. This command requires the matrix file."
8682
+ );
8683
+ }
8684
+ const { matrix, cliVersion } = matrixResult;
8665
8685
  const template = matrix.templateMapping?.[templateName];
8666
8686
  if (!template) {
8667
8687
  throw new Error(`Template "${templateName}" not found in matrix`);
@@ -8711,14 +8731,19 @@ function generatePackageJson(templateName, mode, options = {}) {
8711
8731
  result.peerDependencies = peerDependencies;
8712
8732
  }
8713
8733
  if (templateName === "consumer-root") {
8714
- result.packageManager = "bun@1.3.3";
8715
- result.engines = { node: ">=20.0.0", bun: ">=1.1.0" };
8734
+ result.packageManager = "bun@1.3.5";
8735
+ result.engines = { node: ">=24.0.0", bun: ">=1.3.0" };
8716
8736
  result.workspaces = ["apps/*", "entities"];
8717
8737
  }
8718
8738
  if (templateName === "entities") {
8719
8739
  result.main = "./index.ts";
8720
8740
  result.types = "./index.ts";
8721
8741
  }
8742
+ if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("functions")) {
8743
+ if (!dependencies.entities) {
8744
+ dependencies.entities = "workspace:*";
8745
+ }
8746
+ }
8722
8747
  if (templateName.includes("functions")) {
8723
8748
  result.engines = { node: "20" };
8724
8749
  if (options.appName) {
@@ -8841,7 +8866,8 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8841
8866
  firebaseProjectId: appName.toLowerCase(),
8842
8867
  firebaseSecretName: appName.toUpperCase().replace(/-/g, "_"),
8843
8868
  monorepoRelativePath: "../../packages/tooling",
8844
- appTemplate
8869
+ appTemplate,
8870
+ isNextjs: appTemplate === "nextjs"
8845
8871
  };
8846
8872
  const templateSourceDir = joinPath(templatesRoot, templateDir);
8847
8873
  const templateFiles = await glob("**/*", {
@@ -8934,7 +8960,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8934
8960
  await replacePlaceholders(firebaseJsonDest, replacements);
8935
8961
  }
8936
8962
  }
8937
- if (appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
8963
+ if (appTemplate === "nextjs" || appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
8938
8964
  const vercelJsonSource = joinPath(
8939
8965
  deploymentTemplateDir,
8940
8966
  "vercel.json.example"