@donotdev/cli 0.0.5 → 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 (48) hide show
  1. package/dependencies-matrix.json +57 -33
  2. package/dist/bin/commands/build.js +9 -3
  3. package/dist/bin/commands/bump.js +19 -7
  4. package/dist/bin/commands/cacheout.js +9 -3
  5. package/dist/bin/commands/create-app.js +21 -7
  6. package/dist/bin/commands/create-project.js +22 -7
  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 +33 -17
  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-next/src/app/ClientLayout.tsx.example +4 -3
  24. package/templates/app-next/src/app/layout.tsx.example +17 -25
  25. package/templates/app-next/src/globals.css.example +10 -7
  26. package/templates/app-next/src/locales/dndev_en.json.example +68 -0
  27. package/templates/app-next/src/pages/locales/example_en.json.example +5 -0
  28. package/templates/app-vite/index.html.example +3 -0
  29. package/templates/app-vite/src/globals.css.example +14 -6
  30. package/templates/app-vite/src/locales/dndev_en.json.example +68 -0
  31. package/templates/functions-firebase/README.md.example +25 -0
  32. package/templates/functions-firebase/tsconfig.json.example +3 -13
  33. package/templates/functions-vercel/tsconfig.json.example +1 -13
  34. package/templates/root-consumer/firebase.json.example +1 -1
  35. package/templates/root-consumer/guides/COMPONENTS_ADV.md.example +456 -360
  36. package/templates/root-consumer/guides/COMPONENTS_ATOMIC.md.example +42 -0
  37. package/templates/root-consumer/guides/INDEX.md.example +3 -0
  38. package/templates/root-consumer/guides/SETUP_APP_CONFIG.md.example +5 -2
  39. package/templates/root-consumer/guides/SETUP_BILLING.md.example +44 -4
  40. package/templates/root-consumer/guides/SETUP_CRUD.md.example +1244 -0
  41. package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +52 -0
  42. package/templates/root-consumer/guides/SETUP_PAGES.md.example +17 -0
  43. package/templates/root-consumer/guides/SETUP_PWA.md.example +213 -0
  44. package/templates/root-consumer/guides/USE_ROUTING.md.example +503 -0
  45. package/templates/root-consumer/vercel.json.example +315 -20
  46. package/templates/app-demo/src/Routes.tsx.example +0 -20
  47. package/templates/app-vite/src/Routes.tsx.example +0 -16
  48. package/templates/app-vite/src/pages/locales/README.md.example +0 -1
@@ -2,7 +2,7 @@
2
2
  "$schema": "./dependencies-matrix.schema.json",
3
3
  "version": "0.0.5",
4
4
  "description": "Centralized dependency versions for DoNotDev framework. Single source of truth for all external dependencies. ⚠️ SYNC REQUIRED: When adding/removing @donotdev/* feature packages (auth, billing, crud, oauth), also update packages/core/config/constants.js BUNDLING.optionalFeatures array.",
5
- "lastUpdated": "2026-01-13",
5
+ "lastUpdated": "2026-01-16",
6
6
  "migrationGuides": {
7
7
  "0.0→0.1": {
8
8
  "path": "docs/migration/v0.0-to-v0.1.md",
@@ -17,67 +17,67 @@
17
17
  "@donotdev/adv-comps": {
18
18
  "description": "Advanced components package",
19
19
  "packages": {
20
- "@donotdev/adv-comps": "^0.0.7"
20
+ "@donotdev/adv-comps": "^0.0.8"
21
21
  }
22
22
  },
23
23
  "@donotdev/auth": {
24
24
  "description": "Authentication package",
25
25
  "packages": {
26
- "@donotdev/auth": "^0.0.4"
26
+ "@donotdev/auth": "^0.0.5"
27
27
  }
28
28
  },
29
29
  "@donotdev/billing": {
30
30
  "description": "Billing package",
31
31
  "packages": {
32
- "@donotdev/billing": "^0.0.4"
32
+ "@donotdev/billing": "^0.0.5"
33
33
  }
34
34
  },
35
35
  "@donotdev/components": {
36
36
  "description": "UI components package",
37
37
  "packages": {
38
- "@donotdev/components": "^0.0.10"
38
+ "@donotdev/components": "^0.0.12"
39
39
  }
40
40
  },
41
41
  "@donotdev/core": {
42
42
  "description": "Core framework package",
43
43
  "packages": {
44
- "@donotdev/core": "^0.0.9"
44
+ "@donotdev/core": "^0.0.12"
45
45
  }
46
46
  },
47
47
  "@donotdev/crud": {
48
48
  "description": "CRUD operations package",
49
49
  "packages": {
50
- "@donotdev/crud": "^0.0.4"
50
+ "@donotdev/crud": "^0.0.5"
51
51
  }
52
52
  },
53
53
  "@donotdev/firebase": {
54
54
  "description": "Firebase provider package",
55
55
  "packages": {
56
- "@donotdev/firebase": "^0.0.4"
56
+ "@donotdev/firebase": "^0.0.5"
57
57
  }
58
58
  },
59
59
  "@donotdev/functions": {
60
60
  "description": "Firebase Functions package",
61
61
  "packages": {
62
- "@donotdev/functions": "^0.0.4"
62
+ "@donotdev/functions": "^0.0.5"
63
63
  }
64
64
  },
65
65
  "@donotdev/oauth": {
66
66
  "description": "OAuth package",
67
67
  "packages": {
68
- "@donotdev/oauth": "^0.0.4"
68
+ "@donotdev/oauth": "^0.0.5"
69
69
  }
70
70
  },
71
71
  "@donotdev/templates": {
72
72
  "description": "Page templates package",
73
73
  "packages": {
74
- "@donotdev/templates": "^0.0.4"
74
+ "@donotdev/templates": "^0.0.6"
75
75
  }
76
76
  },
77
77
  "@donotdev/ui": {
78
78
  "description": "UI and routing package",
79
79
  "packages": {
80
- "@donotdev/ui": "^0.0.6"
80
+ "@donotdev/ui": "^0.0.8"
81
81
  }
82
82
  },
83
83
  "react": {
@@ -90,16 +90,16 @@
90
90
  "i18n": {
91
91
  "description": "i18n libraries - auto-installed as transitive deps",
92
92
  "packages": {
93
- "i18next": "^25.7.3",
93
+ "i18next": "^25.7.4",
94
94
  "i18next-browser-languagedetector": "^8.2.0",
95
95
  "i18next-http-backend": "^3.0.2",
96
- "react-i18next": "^16.5.1"
96
+ "react-i18next": "^16.5.2"
97
97
  }
98
98
  },
99
99
  "zustand": {
100
100
  "description": "State management - consumers install for custom stores",
101
101
  "packages": {
102
- "zustand": "^5.0.8"
102
+ "zustand": "^5.0.10"
103
103
  }
104
104
  },
105
105
  "react-query": {
@@ -172,7 +172,11 @@
172
172
  },
173
173
  "forms": {
174
174
  "packages": {
175
- "react-hook-form": "^7.68.0",
175
+ "react-hook-form": "^7.71.0"
176
+ }
177
+ },
178
+ "forms-resolvers": {
179
+ "packages": {
176
180
  "@hookform/resolvers": "^5.2.2"
177
181
  }
178
182
  },
@@ -182,7 +186,9 @@
182
186
  }
183
187
  },
184
188
  "markdown": {
189
+ "description": "Markdown parsing - marked for speed, html-react-parser for SSR",
185
190
  "packages": {
191
+ "html-react-parser": "^5.2.11",
186
192
  "marked": "^17.0.1"
187
193
  }
188
194
  },
@@ -196,6 +202,12 @@
196
202
  "firebase": "^12.5.0"
197
203
  }
198
204
  },
205
+ "browser-image-compression": {
206
+ "description": "Image compression library for browser",
207
+ "packages": {
208
+ "browser-image-compression": "^2.0.2"
209
+ }
210
+ },
199
211
  "stripe": {
200
212
  "packages": {
201
213
  "stripe": "^20.1.0"
@@ -214,8 +226,8 @@
214
226
  },
215
227
  "vercel-deps": {
216
228
  "packages": {
217
- "next": "^16.0.7",
218
- "vercel": "^50.1.3"
229
+ "next": "^16.1.4",
230
+ "vercel": "^50.3.0"
219
231
  }
220
232
  },
221
233
  "esbuild": {
@@ -262,7 +274,7 @@
262
274
  "@vitejs/plugin-react": "^5.1.1",
263
275
  "react-refresh": "^0.18.0",
264
276
  "@vitejs/plugin-basic-ssl": "^2.1.0",
265
- "vite-tsconfig-paths": "^6.0.3",
277
+ "vite-tsconfig-paths": "^6.0.4",
266
278
  "@rollup/plugin-strip": "^3.0.4",
267
279
  "rollup-plugin-visualizer": "^6.0.5",
268
280
  "vite-plugin-pwa": "1.2.0"
@@ -270,12 +282,12 @@
270
282
  },
271
283
  "vite-deps-minimal": {
272
284
  "packages": {
273
- "vite-tsconfig-paths": "^6.0.3"
285
+ "vite-tsconfig-paths": "^6.0.4"
274
286
  }
275
287
  },
276
288
  "next": {
277
289
  "packages": {
278
- "next": "^16.0.7"
290
+ "next": "^16.1.4"
279
291
  }
280
292
  },
281
293
  "typescript": {
@@ -285,12 +297,12 @@
285
297
  },
286
298
  "monitoring": {
287
299
  "packages": {
288
- "@sentry/react": "^10.25.0"
300
+ "@sentry/react": "^10.33.0"
289
301
  }
290
302
  },
291
303
  "monitoring-node": {
292
304
  "packages": {
293
- "@sentry/node": "^10.25.0"
305
+ "@sentry/node": "^10.33.0"
294
306
  }
295
307
  },
296
308
  "postcss": {
@@ -308,26 +320,32 @@
308
320
  },
309
321
  "types": {
310
322
  "packages": {
311
- "@types/node": "^24.10.4",
312
- "@types/react": "^19.2.7",
323
+ "@types/node": "^24.10.8",
324
+ "@types/react": "^19.2.8",
313
325
  "@types/react-dom": "^19.2.3"
314
326
  }
315
327
  },
316
328
  "root-consumer-tooling": {
317
329
  "packages": {
318
- "turbo": "^2.7.2",
330
+ "turbo": "^2.7.4",
319
331
  "sharp": "^0.34.5"
320
332
  }
321
333
  },
322
334
  "vercel": {
323
335
  "packages": {
324
- "vercel": "^50.1.3"
336
+ "vercel": "^50.3.0"
325
337
  }
326
338
  },
327
339
  "@donotdev/cli": {
328
340
  "description": "Cli package",
329
341
  "packages": {
330
- "@donotdev/cli": "^0.0.4"
342
+ "@donotdev/cli": "^0.0.6"
343
+ }
344
+ },
345
+ "react-easy-crop": {
346
+ "description": "Image cropping - auto-installed as transitive dep for crud",
347
+ "packages": {
348
+ "react-easy-crop": "^5.5.6"
331
349
  }
332
350
  }
333
351
  },
@@ -383,8 +401,7 @@
383
401
  ],
384
402
  "dependencies": [
385
403
  "forms",
386
- "seo",
387
- "markdown"
404
+ "seo"
388
405
  ],
389
406
  "peerDependenciesMeta": {
390
407
  "@donotdev/crud": {
@@ -408,7 +425,9 @@
408
425
  "@donotdev/crud": {
409
426
  "dependencies": [
410
427
  "@donotdev/components",
411
- "@donotdev/core"
428
+ "@donotdev/core",
429
+ "react-easy-crop",
430
+ "forms-resolvers"
412
431
  ],
413
432
  "peerDependencies": [
414
433
  "@donotdev/firebase",
@@ -420,6 +439,9 @@
420
439
  ]
421
440
  },
422
441
  "@donotdev/firebase": {
442
+ "dependencies": [
443
+ "browser-image-compression"
444
+ ],
423
445
  "peerDependencies": [
424
446
  "firebase"
425
447
  ]
@@ -447,7 +469,8 @@
447
469
  "react",
448
470
  "validation",
449
471
  "i18n",
450
- "forms"
472
+ "forms",
473
+ "forms-resolvers"
451
474
  ]
452
475
  },
453
476
  "@donotdev/utils": {
@@ -524,6 +547,7 @@
524
547
  "@donotdev/crud",
525
548
  "@donotdev/ui",
526
549
  "forms",
550
+ "forms-resolvers",
527
551
  "markdown"
528
552
  ],
529
553
  "peerDependencies": [
@@ -775,4 +799,4 @@
775
799
  "rule": "If imported in code that gets bundled → dependencies. If externalized in esbuild → devDependencies. If optional/consumer-provided → peerDependencies"
776
800
  }
777
801
  }
778
- }
802
+ }
@@ -7532,11 +7532,17 @@ var init_PathResolver = __esm({
7532
7532
  /**
7533
7533
  * Get path to empty.js module for optional dependency aliasing
7534
7534
  * Used by Vite and Turbopack to alias missing optional deps
7535
- * @returns Absolute path to empty.js
7535
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7536
+ * @returns Package specifier or absolute path to empty.js
7536
7537
  */
7537
- getEmptyModulePath() {
7538
+ getEmptyModulePath(returnPackageSpecifier = false) {
7539
+ if (returnPackageSpecifier) {
7540
+ return "@donotdev/core/empty";
7541
+ }
7542
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7543
+ if (resolved) return resolved;
7538
7544
  const thisDir = dirname(fileURLToPath(import.meta.url));
7539
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7545
+ return this.normalizePath(join(thisDir, "../empty.js"));
7540
7546
  }
7541
7547
  // === PRIVATE METHODS ===
7542
7548
  /**
@@ -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
  /**
@@ -7826,7 +7832,9 @@ async function main(options = {}) {
7826
7832
  const matrixResult = loadMatrix();
7827
7833
  const matrixVersions = matrixResult ? flattenGroups(matrixResult.matrix.groups) : {};
7828
7834
  if (!matrixResult && externalDeps.size > 0) {
7829
- log.info("Matrix not found - only updating @donotdev/* packages (external deps skipped)");
7835
+ log.info(
7836
+ "Matrix not found - only updating @donotdev/* packages (external deps skipped)"
7837
+ );
7830
7838
  }
7831
7839
  const updates = [];
7832
7840
  const majorUpdates = [];
@@ -7907,7 +7915,9 @@ ${majorUpdates.length} major update(s) available (manual review required):`
7907
7915
  const relativeFile = appRoot ? getRelativePathBetween(appRoot, u2.file) : u2.file;
7908
7916
  const normalizedLatest = normalizeVersion(u2.latest);
7909
7917
  const displayLatest = ensureCaretPrefix(normalizedLatest);
7910
- log.info(` ${relativeFile}: ${u2.pkg} ${u2.current} \u2192 ${displayLatest} (${u2.field})`);
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 {
@@ -7947,8 +7957,10 @@ ${majorUpdates.length} major update(s) available (manual review required):`
7947
7957
  }
7948
7958
  }
7949
7959
  if (updatedFiles.size > 0) {
7950
- log.success(`
7951
- Done. Updated ${updatedFiles.size} file(s). Run "bun install" to apply.`);
7960
+ log.success(
7961
+ `
7962
+ Done. Updated ${updatedFiles.size} file(s). Run "bun install" to apply.`
7963
+ );
7952
7964
  }
7953
7965
  } else {
7954
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
  /**
@@ -8635,7 +8641,7 @@ function generateScripts(templateName, options) {
8635
8641
  const scripts = {};
8636
8642
  if (templateName.includes("vite")) {
8637
8643
  scripts.dev = "vite";
8638
- scripts.build = "tsc --noEmit && cross-env NODE_ENV=production VITE_NODE_POLYFILL=true vite build";
8644
+ scripts.build = "vite build";
8639
8645
  scripts.preview = "vite preview";
8640
8646
  scripts.lint = "eslint src/";
8641
8647
  scripts["type-check"] = "tsc --noEmit";
@@ -8671,7 +8677,9 @@ function generateScripts(templateName, options) {
8671
8677
  function generatePackageJson(templateName, mode, options = {}) {
8672
8678
  const matrixResult = loadMatrix(mode);
8673
8679
  if (!matrixResult) {
8674
- throw new Error("dependencies-matrix.json not found. This command requires the matrix file.");
8680
+ throw new Error(
8681
+ "dependencies-matrix.json not found. This command requires the matrix file."
8682
+ );
8675
8683
  }
8676
8684
  const { matrix, cliVersion } = matrixResult;
8677
8685
  const template = matrix.templateMapping?.[templateName];
@@ -8731,6 +8739,11 @@ function generatePackageJson(templateName, mode, options = {}) {
8731
8739
  result.main = "./index.ts";
8732
8740
  result.types = "./index.ts";
8733
8741
  }
8742
+ if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("functions")) {
8743
+ if (!dependencies.entities) {
8744
+ dependencies.entities = "workspace:*";
8745
+ }
8746
+ }
8734
8747
  if (templateName.includes("functions")) {
8735
8748
  result.engines = { node: "20" };
8736
8749
  if (options.appName) {
@@ -8853,7 +8866,8 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8853
8866
  firebaseProjectId: appName.toLowerCase(),
8854
8867
  firebaseSecretName: appName.toUpperCase().replace(/-/g, "_"),
8855
8868
  monorepoRelativePath: "../../packages/tooling",
8856
- appTemplate
8869
+ appTemplate,
8870
+ isNextjs: appTemplate === "nextjs"
8857
8871
  };
8858
8872
  const templateSourceDir = joinPath(templatesRoot, templateDir);
8859
8873
  const templateFiles = await glob("**/*", {
@@ -8946,7 +8960,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8946
8960
  await replacePlaceholders(firebaseJsonDest, replacements);
8947
8961
  }
8948
8962
  }
8949
- if (appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
8963
+ if (appTemplate === "nextjs" || appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
8950
8964
  const vercelJsonSource = joinPath(
8951
8965
  deploymentTemplateDir,
8952
8966
  "vercel.json.example"
@@ -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
  /**
@@ -8776,7 +8782,7 @@ function generateScripts(templateName, options) {
8776
8782
  const scripts = {};
8777
8783
  if (templateName.includes("vite")) {
8778
8784
  scripts.dev = "vite";
8779
- scripts.build = "tsc --noEmit && cross-env NODE_ENV=production VITE_NODE_POLYFILL=true vite build";
8785
+ scripts.build = "vite build";
8780
8786
  scripts.preview = "vite preview";
8781
8787
  scripts.lint = "eslint src/";
8782
8788
  scripts["type-check"] = "tsc --noEmit";
@@ -8812,7 +8818,9 @@ function generateScripts(templateName, options) {
8812
8818
  function generatePackageJson(templateName, mode, options = {}) {
8813
8819
  const matrixResult = loadMatrix(mode);
8814
8820
  if (!matrixResult) {
8815
- throw new Error("dependencies-matrix.json not found. This command requires the matrix file.");
8821
+ throw new Error(
8822
+ "dependencies-matrix.json not found. This command requires the matrix file."
8823
+ );
8816
8824
  }
8817
8825
  const { matrix, cliVersion } = matrixResult;
8818
8826
  const template = matrix.templateMapping?.[templateName];
@@ -8872,6 +8880,11 @@ function generatePackageJson(templateName, mode, options = {}) {
8872
8880
  result.main = "./index.ts";
8873
8881
  result.types = "./index.ts";
8874
8882
  }
8883
+ if (templateName.includes("vite") || templateName.includes("nextjs") || templateName.includes("functions")) {
8884
+ if (!dependencies.entities) {
8885
+ dependencies.entities = "workspace:*";
8886
+ }
8887
+ }
8875
8888
  if (templateName.includes("functions")) {
8876
8889
  result.engines = { node: "20" };
8877
8890
  if (options.appName) {
@@ -8994,7 +9007,8 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8994
9007
  firebaseProjectId: appName.toLowerCase(),
8995
9008
  firebaseSecretName: appName.toUpperCase().replace(/-/g, "_"),
8996
9009
  monorepoRelativePath: "../../packages/tooling",
8997
- appTemplate
9010
+ appTemplate,
9011
+ isNextjs: appTemplate === "nextjs"
8998
9012
  };
8999
9013
  const templateSourceDir = joinPath(templatesRoot, templateDir);
9000
9014
  const templateFiles = await glob("**/*", {
@@ -9087,7 +9101,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
9087
9101
  await replacePlaceholders(firebaseJsonDest, replacements);
9088
9102
  }
9089
9103
  }
9090
- if (appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
9104
+ if (appTemplate === "nextjs" || appConfig.needsBackend && appConfig.backendPlatform === "vercel") {
9091
9105
  const vercelJsonSource = joinPath(
9092
9106
  deploymentTemplateDir,
9093
9107
  "vercel.json.example"
@@ -9460,6 +9474,7 @@ async function main(options) {
9460
9474
  setupGithubActions: false,
9461
9475
  monorepoRelativePath: relativeMonorepoPath,
9462
9476
  appTemplate: "vite",
9477
+ isNextjs: false,
9463
9478
  firebaseProjectId: projectName.toLowerCase(),
9464
9479
  firebaseSecretName: projectName.toUpperCase().replace(/-/g, "_"),
9465
9480
  needsAuth,
@@ -7616,11 +7616,17 @@ var init_PathResolver = __esm({
7616
7616
  /**
7617
7617
  * Get path to empty.js module for optional dependency aliasing
7618
7618
  * Used by Vite and Turbopack to alias missing optional deps
7619
- * @returns Absolute path to empty.js
7619
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7620
+ * @returns Package specifier or absolute path to empty.js
7620
7621
  */
7621
- getEmptyModulePath() {
7622
+ getEmptyModulePath(returnPackageSpecifier = false) {
7623
+ if (returnPackageSpecifier) {
7624
+ return "@donotdev/core/empty";
7625
+ }
7626
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7627
+ if (resolved) return resolved;
7622
7628
  const thisDir = dirname(fileURLToPath(import.meta.url));
7623
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7629
+ return this.normalizePath(join(thisDir, "../empty.js"));
7624
7630
  }
7625
7631
  // === PRIVATE METHODS ===
7626
7632
  /**
@@ -7795,13 +7801,14 @@ import {
7795
7801
  function readdirSync2(dirPath, options) {
7796
7802
  return pathResolverInstance.readdirSync(dirPath, options);
7797
7803
  }
7798
- var pathResolverInstance, normalizePath, pathExists, readSync, writeSync, removeSync, statSync2, ensureDirSync, joinPath;
7804
+ var pathResolverInstance, resolvePackage, normalizePath, pathExists, readSync, writeSync, removeSync, statSync2, ensureDirSync, joinPath;
7799
7805
  var init_pathResolver = __esm({
7800
7806
  "packages/tooling/src/utils/pathResolver.ts"() {
7801
7807
  "use strict";
7802
7808
  init_utils();
7803
7809
  init_PathResolver();
7804
7810
  pathResolverInstance = PathResolver.getInstance({ debug: false });
7811
+ resolvePackage = (spec, from) => pathResolverInstance.resolvePackage(spec, from || null);
7805
7812
  normalizePath = (...pathSegments) => {
7806
7813
  return pathResolverInstance.normalizePath(join2(...pathSegments));
7807
7814
  };
@@ -7924,12 +7931,7 @@ function executeFirebaseCommand(args, options) {
7924
7931
  env: deployEnv
7925
7932
  };
7926
7933
  let result;
7927
- if (process.platform === "win32") {
7928
- const firebaseCmd = "C:\\Program Files\\nodejs\\firebase.cmd";
7929
- result = spawnSync(firebaseCmd, args, { ...spawnOptions, shell: false });
7930
- } else {
7931
- result = spawnSync("firebase", args, { ...spawnOptions, shell: true });
7932
- }
7934
+ result = spawnSync("firebase", args, { ...spawnOptions, shell: true });
7933
7935
  if (result.error) {
7934
7936
  return {
7935
7937
  success: false,
@@ -8680,11 +8682,15 @@ async function deployFunctions(appDir, serviceAccountPath, projectId, config) {
8680
8682
  }
8681
8683
  const s = Y2();
8682
8684
  s.start("Validating function dependencies...");
8683
- const nodeModulesPath = joinPath(functionsDir, "node_modules");
8684
8685
  const requiredPackages = ["firebase-functions", "firebase-admin"];
8685
- const missingPackages = requiredPackages.filter(
8686
- (pkg) => !pathExists(joinPath(nodeModulesPath, pkg))
8687
- );
8686
+ const missingPackages = requiredPackages.filter((pkg) => {
8687
+ try {
8688
+ resolvePackage(pkg, functionsDir);
8689
+ return false;
8690
+ } catch {
8691
+ return true;
8692
+ }
8693
+ });
8688
8694
  if (missingPackages.length > 0) {
8689
8695
  s.stop("Missing dependencies");
8690
8696
  throw new DoNotDevError(
@@ -8699,6 +8705,8 @@ To fix this, run:
8699
8705
  }
8700
8706
  s.stop("Dependencies validated");
8701
8707
  prepareFunctionsForDeployment(functionsDir, config.verbose);
8708
+ log.debug("Waiting for file system sync...");
8709
+ await new Promise((resolve4) => setTimeout(resolve4, 1e3));
8702
8710
  try {
8703
8711
  if (!config.skipBuild) {
8704
8712
  const s2 = Y2();
@@ -7439,11 +7439,17 @@ var init_PathResolver = __esm({
7439
7439
  /**
7440
7440
  * Get path to empty.js module for optional dependency aliasing
7441
7441
  * Used by Vite and Turbopack to alias missing optional deps
7442
- * @returns Absolute path to empty.js
7442
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7443
+ * @returns Package specifier or absolute path to empty.js
7443
7444
  */
7444
- getEmptyModulePath() {
7445
+ getEmptyModulePath(returnPackageSpecifier = false) {
7446
+ if (returnPackageSpecifier) {
7447
+ return "@donotdev/core/empty";
7448
+ }
7449
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7450
+ if (resolved) return resolved;
7445
7451
  const thisDir = dirname(fileURLToPath(import.meta.url));
7446
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7452
+ return this.normalizePath(join(thisDir, "../empty.js"));
7447
7453
  }
7448
7454
  // === PRIVATE METHODS ===
7449
7455
  /**
@@ -7522,11 +7522,17 @@ var init_PathResolver = __esm({
7522
7522
  /**
7523
7523
  * Get path to empty.js module for optional dependency aliasing
7524
7524
  * Used by Vite and Turbopack to alias missing optional deps
7525
- * @returns Absolute path to empty.js
7525
+ * @param returnPackageSpecifier - If true, returns package specifier '@donotdev/core/empty' for Turbopack. If false, returns absolute path for Vite.
7526
+ * @returns Package specifier or absolute path to empty.js
7526
7527
  */
7527
- getEmptyModulePath() {
7528
+ getEmptyModulePath(returnPackageSpecifier = false) {
7529
+ if (returnPackageSpecifier) {
7530
+ return "@donotdev/core/empty";
7531
+ }
7532
+ const resolved = this.resolvePackage("@donotdev/core/empty");
7533
+ if (resolved) return resolved;
7528
7534
  const thisDir = dirname(fileURLToPath(import.meta.url));
7529
- return this.normalizePath(join(thisDir, "../vite/empty.js"));
7535
+ return this.normalizePath(join(thisDir, "../empty.js"));
7530
7536
  }
7531
7537
  // === PRIVATE METHODS ===
7532
7538
  /**