@donotdev/cli 0.0.6 → 0.0.8

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 (87) hide show
  1. package/README.md +3 -18
  2. package/dependencies-matrix.json +64 -121
  3. package/dist/bin/commands/build.js +173 -161
  4. package/dist/bin/commands/bump.js +181 -156
  5. package/dist/bin/commands/cacheout.js +188 -171
  6. package/dist/bin/commands/create-app.js +213 -156
  7. package/dist/bin/commands/create-project.js +183 -154
  8. package/dist/bin/commands/deploy.js +491 -477
  9. package/dist/bin/commands/dev.js +176 -160
  10. package/dist/bin/commands/emu.js +181 -165
  11. package/dist/bin/commands/format.js +191 -174
  12. package/dist/bin/commands/lint.js +191 -171
  13. package/dist/bin/commands/preview.js +177 -161
  14. package/dist/bin/commands/sync-secrets.js +172 -158
  15. package/dist/bin/commands/wai.d.ts +11 -0
  16. package/dist/bin/commands/wai.d.ts.map +1 -0
  17. package/dist/bin/commands/wai.js +12 -0
  18. package/dist/bin/commands/wai.js.map +1 -0
  19. package/dist/bin/dndev.js +24 -24
  20. package/dist/bin/donotdev.js +24 -24
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +661 -669
  24. package/dist/index.js.map +1 -1
  25. package/package.json +1 -1
  26. package/templates/app-demo/src/config/app.ts.example +12 -0
  27. package/templates/app-next/src/config/app.ts.example +75 -48
  28. package/templates/app-vite/index.html.example +71 -37
  29. package/templates/app-vite/src/config/app.ts.example +75 -47
  30. package/templates/app-vite/src/pages/FormPageExample.tsx.example +152 -0
  31. package/templates/app-vite/src/pages/HomePage.tsx.example +81 -134
  32. package/templates/app-vite/src/pages/ListPageExample.tsx.example +88 -0
  33. package/templates/functions-firebase/build.mjs.example +8 -1
  34. package/templates/functions-firebase/functions-firebase/build.mjs.example +8 -1
  35. package/templates/functions-firebase/functions-firebase/src/index.ts.example +19 -25
  36. package/templates/functions-firebase/functions.config.js.example +35 -0
  37. package/templates/root-consumer/entities/ExampleEntity.ts.example +223 -0
  38. package/templates/root-consumer/entities/demo.ts.example +576 -0
  39. package/templates/root-consumer/entities/index.ts.example +15 -0
  40. package/templates/root-consumer/eslint.config.js.example +2 -80
  41. package/templates/root-consumer/guides/{AGENT_START_HERE.md.example → dndev/AGENT_START_HERE.md.example} +22 -0
  42. package/templates/root-consumer/guides/dndev/COMPONENTS_CRUD.md.example +231 -0
  43. package/templates/root-consumer/guides/{SETUP_AUTH.md.example → dndev/SETUP_AUTH.md.example} +30 -0
  44. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +539 -0
  45. package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +116 -0
  46. package/templates/root-consumer/guides/{SETUP_I18N.md.example → dndev/SETUP_I18N.md.example} +46 -0
  47. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +404 -0
  48. package/templates/root-consumer/guides/wai-way/agents/architect.md.example +78 -0
  49. package/templates/root-consumer/guides/wai-way/agents/builder.md.example +87 -0
  50. package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +325 -0
  51. package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +100 -0
  52. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +281 -0
  53. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +77 -0
  54. package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +104 -0
  55. package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +124 -0
  56. package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +165 -0
  57. package/templates/root-consumer/guides/wai-way/context_map.json.example +95 -0
  58. package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +840 -0
  59. package/templates/root-consumer/guides/wai-way/page_patterns.md.example +686 -0
  60. package/templates/root-consumer/guides/wai-way/presets_guide.md.example +217 -0
  61. package/templates/root-consumer/guides/wai-way/spec_template.md.example +312 -0
  62. package/templates/functions-firebase/functions-firebase/src/crud/createEntity.ts.example +0 -19
  63. package/templates/functions-firebase/functions-firebase/src/crud/deleteEntity.ts.example +0 -14
  64. package/templates/functions-firebase/functions-firebase/src/crud/getEntity.ts.example +0 -14
  65. package/templates/functions-firebase/functions-firebase/src/crud/index.ts.example +0 -12
  66. package/templates/functions-firebase/functions-firebase/src/crud/listEntities.ts.example +0 -14
  67. package/templates/functions-firebase/functions-firebase/src/crud/updateEntity.ts.example +0 -14
  68. package/templates/root-consumer/guides/COMPONENTS_CRUD.md.example +0 -70
  69. package/templates/root-consumer/guides/SETUP_CRUD.md.example +0 -1244
  70. package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +0 -114
  71. /package/templates/root-consumer/guides/{COMPONENTS_ADV.md.example → dndev/COMPONENTS_ADV.md.example} +0 -0
  72. /package/templates/root-consumer/guides/{COMPONENTS_ATOMIC.md.example → dndev/COMPONENTS_ATOMIC.md.example} +0 -0
  73. /package/templates/root-consumer/guides/{COMPONENTS_UI.md.example → dndev/COMPONENTS_UI.md.example} +0 -0
  74. /package/templates/root-consumer/guides/{ENV_SETUP.md.example → dndev/ENV_SETUP.md.example} +0 -0
  75. /package/templates/root-consumer/guides/{INDEX.md.example → dndev/INDEX.md.example} +0 -0
  76. /package/templates/root-consumer/guides/{SETUP_APP_CONFIG.md.example → dndev/SETUP_APP_CONFIG.md.example} +0 -0
  77. /package/templates/root-consumer/guides/{SETUP_BILLING.md.example → dndev/SETUP_BILLING.md.example} +0 -0
  78. /package/templates/root-consumer/guides/{SETUP_LAYOUTS.md.example → dndev/SETUP_LAYOUTS.md.example} +0 -0
  79. /package/templates/root-consumer/guides/{SETUP_OAUTH.md.example → dndev/SETUP_OAUTH.md.example} +0 -0
  80. /package/templates/root-consumer/guides/{SETUP_PAGES.md.example → dndev/SETUP_PAGES.md.example} +0 -0
  81. /package/templates/root-consumer/guides/{SETUP_PWA.md.example → dndev/SETUP_PWA.md.example} +0 -0
  82. /package/templates/root-consumer/guides/{SETUP_THEMES.md.example → dndev/SETUP_THEMES.md.example} +0 -0
  83. /package/templates/root-consumer/guides/{USE_ROUTING.md.example → dndev/USE_ROUTING.md.example} +0 -0
  84. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/APP_CHECK.md.example +0 -0
  85. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/COOKIE_REFERENCE.md.example +0 -0
  86. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/EMULATORS.md.example +0 -0
  87. /package/templates/root-consumer/guides/{advanced → dndev/advanced}/VERSION_CONTROL.md.example +0 -0
package/dist/index.js CHANGED
@@ -897,6 +897,7 @@ __export(cli_output_exports, {
897
897
  success: () => success,
898
898
  warn: () => warn
899
899
  });
900
+ import "node:os";
900
901
  function supportsColor() {
901
902
  if (process.env.NO_COLOR) return false;
902
903
  if (process.platform === "win32") {
@@ -1088,155 +1089,6 @@ var init_cli_output = __esm({
1088
1089
  }
1089
1090
  });
1090
1091
 
1091
- // packages/core/config/constants.js
1092
- function getPatternsFor(type, repoRoot = null) {
1093
- const patterns = SCAN_PATTERNS[type];
1094
- if (!patterns) {
1095
- throw new Error(`Unknown pattern type: ${type}`);
1096
- }
1097
- if (repoRoot && patterns.framework) {
1098
- return {
1099
- ...patterns,
1100
- framework: patterns.framework.map((pattern) => `${repoRoot}/${pattern}`)
1101
- };
1102
- }
1103
- return patterns;
1104
- }
1105
- function getGlobOptionsFor(type) {
1106
- return GLOB_OPTIONS[type] || GLOB_OPTIONS.base;
1107
- }
1108
- var I18N_PATHS, SCAN_PATTERNS, GLOB_OPTIONS;
1109
- var init_constants = __esm({
1110
- "packages/core/config/constants.js"() {
1111
- "use strict";
1112
- init_utils();
1113
- I18N_PATHS = {
1114
- // Monorepo source structure (locales at root, not in src/)
1115
- SOURCE_ROOT: "packages/core/i18n",
1116
- SOURCE_LOCALES: "packages/core/i18n/locales",
1117
- SOURCE_EAGER: "packages/core/i18n/locales/eager",
1118
- SOURCE_LAZY: "packages/core/i18n/locales/lazy",
1119
- // Published structure (same as source - no flattening needed)
1120
- PUBLISHED_ROOT: "i18n",
1121
- PUBLISHED_LOCALES: "i18n/locales",
1122
- PUBLISHED_EAGER: "i18n/locales/eager",
1123
- PUBLISHED_LAZY: "i18n/locales/lazy"
1124
- };
1125
- SCAN_PATTERNS = {
1126
- routes: {
1127
- consumer: ["src/**/*Page.tsx", "src/pages/**/*Page.tsx"],
1128
- exclude: [
1129
- "**/node_modules/**",
1130
- "**/dist/**",
1131
- "**/build/**",
1132
- "**/*.test.tsx",
1133
- "**/*.stories.tsx"
1134
- ],
1135
- extensions: [".tsx"]
1136
- },
1137
- css: {
1138
- consumer: ["src/**/*.css"],
1139
- themes: ["src/**/*.css"],
1140
- extensions: [".css", ".scss", ".sass"],
1141
- framework: [
1142
- "packages/ui/src/**/*.css",
1143
- "packages/core/components/src/**/*.css",
1144
- "packages/core/templates/src/**/*.css"
1145
- ]
1146
- },
1147
- i18n: {
1148
- eager: ["src/locales/*_*.json"],
1149
- lazy: ["src/**/locales/*_*.json", "!src/locales/*_*.json"],
1150
- framework: {
1151
- eager: [`${I18N_PATHS.SOURCE_EAGER}/*_*.json`],
1152
- lazy: [`${I18N_PATHS.SOURCE_LAZY}/*_*.json`]
1153
- },
1154
- extensions: [".json"]
1155
- },
1156
- assets: {
1157
- consumer: ["public/**/*"],
1158
- fallback: ["manifest.json"],
1159
- modern: [
1160
- "logo.svg",
1161
- "favicon.svg",
1162
- "apple-touch-icon.png",
1163
- "android-chrome-192x192.png",
1164
- "android-chrome-512x512.png"
1165
- ],
1166
- patterns: [
1167
- "favicon.svg",
1168
- "favicon.ico",
1169
- "favicon-*.png",
1170
- "logo.svg",
1171
- "logo.png",
1172
- "logo.webp",
1173
- "logo.avif",
1174
- "apple-touch-icon*.png",
1175
- "android-chrome-*.png",
1176
- "manifest.json"
1177
- ],
1178
- fonts: ["fonts/**/*.woff2", "fonts/**/*.woff", "fonts/**/*.ttf"],
1179
- framework: ["packages/ui/assets/**/*"]
1180
- },
1181
- pwa: {
1182
- consumer: [
1183
- "public/manifest.json",
1184
- "public/service-worker.js",
1185
- "public/sw.js",
1186
- "public/icon-192x192.png",
1187
- "public/icon-512x512.png",
1188
- "public/favicon.ico",
1189
- "public/favicon.svg",
1190
- "public/apple-touch-icon.png",
1191
- "public/logo.svg"
1192
- ],
1193
- exclude: ["**/node_modules/**", "**/dist/**", "**/build/**"],
1194
- extensions: [".json", ".js", ".png", ".svg", ".ico"],
1195
- framework: ["packages/ui/assets/**/*"]
1196
- },
1197
- globalIgnore: [
1198
- "**/node_modules/**",
1199
- "**/dist/**",
1200
- "**/build/**",
1201
- "**/.git/**",
1202
- "**/coverage/**",
1203
- "**/test/**"
1204
- ]
1205
- };
1206
- GLOB_OPTIONS = {
1207
- base: {
1208
- absolute: true,
1209
- onlyFiles: true,
1210
- ignore: SCAN_PATTERNS.globalIgnore
1211
- },
1212
- css: {
1213
- absolute: true,
1214
- onlyFiles: true,
1215
- ignore: [...SCAN_PATTERNS.globalIgnore, "**/*.test.css"]
1216
- },
1217
- routes: {
1218
- absolute: true,
1219
- onlyFiles: true,
1220
- ignore: [
1221
- ...SCAN_PATTERNS.globalIgnore,
1222
- "**/*.test.tsx",
1223
- "**/*.stories.tsx"
1224
- ]
1225
- },
1226
- i18n: {
1227
- absolute: true,
1228
- onlyFiles: true,
1229
- ignore: SCAN_PATTERNS.globalIgnore
1230
- },
1231
- assets: {
1232
- absolute: true,
1233
- onlyFiles: true,
1234
- ignore: SCAN_PATTERNS.globalIgnore
1235
- }
1236
- };
1237
- }
1238
- });
1239
-
1240
1092
  // node_modules/.bun/fast-glob@3.3.3/node_modules/fast-glob/out/utils/array.js
1241
1093
  var require_array = __commonJS({
1242
1094
  "node_modules/.bun/fast-glob@3.3.3/node_modules/fast-glob/out/utils/array.js"(exports) {
@@ -6821,70 +6673,229 @@ var require_out4 = __commonJS({
6821
6673
  }
6822
6674
  });
6823
6675
 
6824
- // packages/core/config/utils/PathResolver.ts
6825
- import { createRequire } from "node:module";
6826
- import {
6827
- resolve,
6828
- join,
6829
- dirname,
6830
- relative,
6831
- normalize,
6832
- sep,
6833
- extname
6834
- } from "node:path";
6835
- import { fileURLToPath } from "node:url";
6836
- import * as fs from "node:fs";
6837
- function safeExecuteAsync(fn, message) {
6838
- return fn().catch((error2) => {
6839
- throw new Error(
6840
- `${message}: ${error2 instanceof Error ? error2.message : String(error2)}`
6841
- );
6842
- });
6676
+ // packages/core/config/constants.js
6677
+ function getPatternsFor(type, repoRoot = null) {
6678
+ const patterns = SCAN_PATTERNS[type];
6679
+ if (!patterns) {
6680
+ throw new Error(`Unknown pattern type: ${type}`);
6681
+ }
6682
+ if (repoRoot && patterns.framework) {
6683
+ return {
6684
+ ...patterns,
6685
+ framework: patterns.framework.map((pattern) => `${repoRoot}/${pattern}`)
6686
+ };
6687
+ }
6688
+ return patterns;
6843
6689
  }
6844
- var import_fast_glob, constants, log2, PACKAGE_PATHS, PathResolver;
6845
- var init_PathResolver = __esm({
6846
- "packages/core/config/utils/PathResolver.ts"() {
6690
+ function getGlobOptionsFor(type) {
6691
+ return GLOB_OPTIONS[type] || GLOB_OPTIONS.base;
6692
+ }
6693
+ var I18N_PATHS, SCAN_PATTERNS, GLOB_OPTIONS;
6694
+ var init_constants = __esm({
6695
+ "packages/core/config/constants.js"() {
6847
6696
  "use strict";
6848
6697
  init_utils();
6849
- init_constants();
6850
- import_fast_glob = __toESM(require_out4(), 1);
6851
- constants = {
6852
- getGlobOptionsFor: getGlobOptionsFor || void 0,
6853
- SCAN_PATTERNS: SCAN_PATTERNS || void 0,
6854
- getPatternsFor: getPatternsFor || void 0,
6855
- I18N_PATHS: I18N_PATHS || void 0
6698
+ I18N_PATHS = {
6699
+ // Monorepo source structure (locales at root, not in src/)
6700
+ SOURCE_ROOT: "packages/core/i18n",
6701
+ SOURCE_LOCALES: "packages/core/i18n/locales",
6702
+ SOURCE_EAGER: "packages/core/i18n/locales/eager",
6703
+ SOURCE_LAZY: "packages/core/i18n/locales/lazy",
6704
+ // Published structure (same as source - no flattening needed)
6705
+ PUBLISHED_ROOT: "i18n",
6706
+ PUBLISHED_LOCALES: "i18n/locales",
6707
+ PUBLISHED_EAGER: "i18n/locales/eager",
6708
+ PUBLISHED_LAZY: "i18n/locales/lazy"
6856
6709
  };
6857
- log2 = {
6858
- error: (message, error2) => {
6710
+ SCAN_PATTERNS = {
6711
+ routes: {
6712
+ consumer: ["src/**/*Page.tsx", "src/pages/**/*Page.tsx"],
6713
+ exclude: [
6714
+ "**/node_modules/**",
6715
+ "**/dist/**",
6716
+ "**/build/**",
6717
+ "**/*.test.tsx",
6718
+ "**/*.stories.tsx"
6719
+ ],
6720
+ extensions: [".tsx"]
6859
6721
  },
6860
- warn: (message, error2) => {
6722
+ css: {
6723
+ consumer: ["src/**/*.css"],
6724
+ themes: ["src/**/*.css"],
6725
+ extensions: [".css", ".scss", ".sass"],
6726
+ framework: [
6727
+ "packages/ui/src/**/*.css",
6728
+ "packages/core/components/src/**/*.css",
6729
+ "packages/core/templates/src/**/*.css"
6730
+ ]
6861
6731
  },
6862
- info: (message) => {
6863
- }
6864
- };
6865
- PACKAGE_PATHS = {
6866
- CLI: "packages/cli",
6867
- COMPONENTS: "packages/core/components",
6868
- CONFIG: "packages/core/config",
6869
- // I18n paths - single source of truth (use I18N_PATHS from constants.js)
6870
- CORE: "packages/core",
6871
- CRUD: "packages/core/crud",
6872
- FEATURES: "packages/features",
6873
- HOOKS: "packages/core/hooks",
6874
- I18N: "packages/core/i18n",
6875
- SCHEMAS: "packages/core/schemas",
6876
- STORES: "packages/core/stores",
6877
- TEMPLATES: "packages/templates",
6878
- TOOLING: "packages/tooling",
6879
- TYPES: "packages/core/types",
6880
- UI: "packages/ui",
6881
- UTILS: "packages/core/utils",
6882
- AUTH: "packages/features/auth",
6883
- BILLING: "packages/features/billing",
6884
- OAUTH: "packages/features/oauth",
6885
- FIREBASE: "packages/providers/firebase",
6886
- FUNCTIONS: "packages/functions"
6887
- };
6732
+ i18n: {
6733
+ eager: ["src/locales/*_*.json"],
6734
+ lazy: [
6735
+ "src/**/locales/*_*.json",
6736
+ "!src/locales/*_*.json",
6737
+ // Auto-detect shared entity translations in monorepos (if exists, use it; if not, no problem)
6738
+ "../../entities/locales/*_*.json"
6739
+ ],
6740
+ // Additional paths from workspace packages (e.g., shared entities)
6741
+ // Consumers can still configure via i18n.additionalPaths in dndev/vite config for custom paths
6742
+ // Example: ['../../packages/shared/locales/*_*.json']
6743
+ additional: [],
6744
+ framework: {
6745
+ eager: [`${I18N_PATHS.SOURCE_EAGER}/*_*.json`],
6746
+ lazy: [`${I18N_PATHS.SOURCE_LAZY}/*_*.json`]
6747
+ },
6748
+ extensions: [".json"]
6749
+ },
6750
+ assets: {
6751
+ consumer: ["public/**/*"],
6752
+ fallback: ["manifest.json"],
6753
+ modern: [
6754
+ "logo.svg",
6755
+ "favicon.svg",
6756
+ "apple-touch-icon.png",
6757
+ "android-chrome-192x192.png",
6758
+ "android-chrome-512x512.png"
6759
+ ],
6760
+ patterns: [
6761
+ "favicon.svg",
6762
+ "favicon.ico",
6763
+ "favicon-*.png",
6764
+ "logo.svg",
6765
+ "logo.png",
6766
+ "logo.webp",
6767
+ "logo.avif",
6768
+ "apple-touch-icon*.png",
6769
+ "android-chrome-*.png",
6770
+ "manifest.json"
6771
+ ],
6772
+ fonts: ["fonts/**/*.woff2", "fonts/**/*.woff", "fonts/**/*.ttf"],
6773
+ framework: ["packages/ui/assets/**/*"]
6774
+ },
6775
+ pwa: {
6776
+ consumer: [
6777
+ "public/manifest.json",
6778
+ "public/service-worker.js",
6779
+ "public/sw.js",
6780
+ "public/icon-192x192.png",
6781
+ "public/icon-512x512.png",
6782
+ "public/favicon.ico",
6783
+ "public/favicon.svg",
6784
+ "public/apple-touch-icon.png",
6785
+ "public/logo.svg"
6786
+ ],
6787
+ exclude: ["**/node_modules/**", "**/dist/**", "**/build/**"],
6788
+ extensions: [".json", ".js", ".png", ".svg", ".ico"],
6789
+ framework: ["packages/ui/assets/**/*"]
6790
+ },
6791
+ globalIgnore: [
6792
+ "**/node_modules/**",
6793
+ "**/dist/**",
6794
+ "**/build/**",
6795
+ "**/.git/**",
6796
+ "**/coverage/**",
6797
+ "**/test/**"
6798
+ ]
6799
+ };
6800
+ GLOB_OPTIONS = {
6801
+ base: {
6802
+ absolute: true,
6803
+ onlyFiles: true,
6804
+ ignore: SCAN_PATTERNS.globalIgnore
6805
+ },
6806
+ css: {
6807
+ absolute: true,
6808
+ onlyFiles: true,
6809
+ ignore: [...SCAN_PATTERNS.globalIgnore, "**/*.test.css"]
6810
+ },
6811
+ routes: {
6812
+ absolute: true,
6813
+ onlyFiles: true,
6814
+ ignore: [
6815
+ ...SCAN_PATTERNS.globalIgnore,
6816
+ "**/*.test.tsx",
6817
+ "**/*.stories.tsx"
6818
+ ]
6819
+ },
6820
+ i18n: {
6821
+ absolute: true,
6822
+ onlyFiles: true,
6823
+ ignore: SCAN_PATTERNS.globalIgnore
6824
+ },
6825
+ assets: {
6826
+ absolute: true,
6827
+ onlyFiles: true,
6828
+ ignore: SCAN_PATTERNS.globalIgnore
6829
+ }
6830
+ };
6831
+ }
6832
+ });
6833
+
6834
+ // packages/core/config/utils/PathResolver.ts
6835
+ import * as fs from "node:fs";
6836
+ import "node:fs";
6837
+ import { createRequire } from "node:module";
6838
+ import {
6839
+ resolve,
6840
+ join,
6841
+ dirname,
6842
+ relative,
6843
+ normalize,
6844
+ sep,
6845
+ extname
6846
+ } from "node:path";
6847
+ import { fileURLToPath } from "node:url";
6848
+ function safeExecuteAsync(fn, message) {
6849
+ return fn().catch((error2) => {
6850
+ throw new Error(
6851
+ `${message}: ${error2 instanceof Error ? error2.message : String(error2)}`
6852
+ );
6853
+ });
6854
+ }
6855
+ var import_fast_glob, constants, log2, PACKAGE_PATHS, PathResolver;
6856
+ var init_PathResolver = __esm({
6857
+ "packages/core/config/utils/PathResolver.ts"() {
6858
+ "use strict";
6859
+ init_utils();
6860
+ import_fast_glob = __toESM(require_out4(), 1);
6861
+ init_constants();
6862
+ constants = {
6863
+ getGlobOptionsFor: getGlobOptionsFor || void 0,
6864
+ SCAN_PATTERNS: SCAN_PATTERNS || void 0,
6865
+ getPatternsFor: getPatternsFor || void 0,
6866
+ I18N_PATHS: I18N_PATHS || void 0
6867
+ };
6868
+ log2 = {
6869
+ error: (message, error2) => {
6870
+ },
6871
+ warn: (message, error2) => {
6872
+ },
6873
+ info: (message) => {
6874
+ }
6875
+ };
6876
+ PACKAGE_PATHS = {
6877
+ CLI: "packages/cli",
6878
+ COMPONENTS: "packages/core/components",
6879
+ CONFIG: "packages/core/config",
6880
+ // I18n paths - single source of truth (use I18N_PATHS from constants.js)
6881
+ CORE: "packages/core",
6882
+ CRUD: "packages/core/crud",
6883
+ FEATURES: "packages/features",
6884
+ HOOKS: "packages/core/hooks",
6885
+ I18N: "packages/core/i18n",
6886
+ SCHEMAS: "packages/core/schemas",
6887
+ STORES: "packages/core/stores",
6888
+ TEMPLATES: "packages/templates",
6889
+ TOOLING: "packages/tooling",
6890
+ TYPES: "packages/core/types",
6891
+ UI: "packages/ui",
6892
+ UTILS: "packages/core/utils",
6893
+ AUTH: "packages/features/auth",
6894
+ BILLING: "packages/features/billing",
6895
+ OAUTH: "packages/features/oauth",
6896
+ FIREBASE: "packages/providers/firebase",
6897
+ FUNCTIONS: "packages/functions"
6898
+ };
6888
6899
  PathResolver = class _PathResolver {
6889
6900
  static _instance = null;
6890
6901
  options;
@@ -8289,11 +8300,12 @@ var init_pathResolver = __esm({
8289
8300
  });
8290
8301
 
8291
8302
  // packages/tooling/src/bundler/utils.ts
8303
+ import { Buffer as Buffer2 } from "node:buffer";
8304
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
8292
8305
  import { createRequire as createRequire3 } from "node:module";
8293
- import { fileURLToPath as fileURLToPath3 } from "node:url";
8294
8306
  import { dirname as dirname3, resolve as resolve3 } from "node:path";
8295
- import { Buffer as Buffer2 } from "node:buffer";
8296
8307
  import process from "node:process";
8308
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
8297
8309
  var require2, __filename, __dirname;
8298
8310
  var init_utils = __esm({
8299
8311
  "packages/tooling/src/bundler/utils.ts"() {
@@ -8327,7 +8339,6 @@ import { spawnSync, execSync } from "node:child_process";
8327
8339
  // packages/tooling/src/utils/app-selector.ts
8328
8340
  init_utils();
8329
8341
  init_dist2();
8330
- init_cli_output();
8331
8342
 
8332
8343
  // packages/tooling/src/utils/app-detection.ts
8333
8344
  init_utils();
@@ -8415,6 +8426,7 @@ function analyzeApp(appPath, appName) {
8415
8426
  }
8416
8427
 
8417
8428
  // packages/tooling/src/utils/app-selector.ts
8429
+ init_cli_output();
8418
8430
  async function selectApp(projectRoot, appName) {
8419
8431
  const apps = detectApps(projectRoot);
8420
8432
  if (apps.length === 0) {
@@ -8449,10 +8461,6 @@ async function selectApp(projectRoot, appName) {
8449
8461
  return apps.find((a) => a.name === selected) || null;
8450
8462
  }
8451
8463
 
8452
- // packages/tooling/src/apps/build.ts
8453
- init_errors();
8454
- init_cli_output();
8455
-
8456
8464
  // packages/tooling/src/utils/cli-input.ts
8457
8465
  init_utils();
8458
8466
  init_dist2();
@@ -8516,6 +8524,8 @@ async function askForMultiSelection(message, choices, defaultIndices = []) {
8516
8524
  }
8517
8525
 
8518
8526
  // packages/tooling/src/apps/build.ts
8527
+ init_cli_output();
8528
+ init_errors();
8519
8529
  init_pathResolver();
8520
8530
  function validateFirebaseJson(appDir) {
8521
8531
  const firebaseJsonPath = joinPath(appDir, "firebase.json");
@@ -8708,8 +8718,8 @@ async function main() {
8708
8718
  // packages/tooling/src/apps/dev.ts
8709
8719
  init_utils();
8710
8720
  import { spawnSync as spawnSync3 } from "node:child_process";
8711
- init_errors();
8712
8721
  init_cli_output();
8722
+ init_errors();
8713
8723
  init_pathResolver();
8714
8724
 
8715
8725
  // packages/tooling/src/utils/spawn-utils.ts
@@ -8896,8 +8906,8 @@ async function main2() {
8896
8906
  // packages/tooling/src/apps/emu.ts
8897
8907
  init_utils();
8898
8908
  import { spawnSync as spawnSync4, execSync as execSync3 } from "node:child_process";
8899
- init_errors();
8900
8909
  init_cli_output();
8910
+ init_errors();
8901
8911
  init_pathResolver();
8902
8912
  init_pathResolver();
8903
8913
  function discoverFirebaseProjectId(appPath) {
@@ -9201,8 +9211,8 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
9201
9211
  // packages/tooling/src/apps/preview.ts
9202
9212
  init_utils();
9203
9213
  import { spawnSync as spawnSync5 } from "node:child_process";
9204
- init_errors();
9205
9214
  init_cli_output();
9215
+ init_errors();
9206
9216
  init_pathResolver();
9207
9217
  async function main4() {
9208
9218
  const args = process.argv.slice(2);
@@ -9250,10 +9260,11 @@ async function main4() {
9250
9260
 
9251
9261
  // packages/tooling/src/apps/deploy.ts
9252
9262
  init_utils();
9253
- init_cli_output();
9254
- init_cli_output();
9255
9263
  import { execSync as execSync5 } from "node:child_process";
9256
9264
 
9265
+ // packages/tooling/src/apps/deploy-frontend.ts
9266
+ init_utils();
9267
+
9257
9268
  // packages/tooling/src/utils/cli-tools.ts
9258
9269
  init_utils();
9259
9270
  init_dist2();
@@ -9503,18 +9514,10 @@ function requireCLI(tool, additionalContext) {
9503
9514
  return true;
9504
9515
  }
9505
9516
 
9506
- // packages/tooling/src/apps/deploy.ts
9507
- init_errors();
9508
- init_pathResolver();
9509
-
9510
- // packages/tooling/src/apps/deploy-utils.ts
9511
- init_utils();
9512
- import { spawnSync as spawnSync7 } from "node:child_process";
9513
-
9514
9517
  // packages/tooling/src/utils/create-utils.ts
9515
9518
  init_utils();
9516
- init_pathResolver();
9517
9519
  init_cli_output();
9520
+ init_pathResolver();
9518
9521
  async function copyTemplateFiles(sourceDir, destDir, replacements) {
9519
9522
  if (!pathExists(sourceDir)) {
9520
9523
  log.warn(`Warning: Template directory does not exist: ${sourceDir}`);
@@ -9976,55 +9979,290 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
9976
9979
  return answers;
9977
9980
  }
9978
9981
 
9979
- // packages/tooling/src/apps/deploy-utils.ts
9980
- init_pathResolver();
9981
- function detectAvailableApps() {
9982
- const currentDir = process.cwd();
9983
- const appsDir = joinPath(currentDir, "apps");
9984
- if (!pathExists(appsDir)) {
9985
- return [];
9982
+ // packages/tooling/src/apps/deploy-frontend.ts
9983
+ async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
9984
+ const s = Y2();
9985
+ s.start("Deploying frontend to Firebase Hosting...");
9986
+ const args = buildFirebaseDeployArgs("hosting", projectId, config.debug);
9987
+ const result = executeFirebaseCommand(args, {
9988
+ cwd: appDir,
9989
+ serviceAccountPath,
9990
+ projectId,
9991
+ debug: config.debug
9992
+ });
9993
+ if (result.error) {
9994
+ s.stop("Deployment failed");
9995
+ throw result.error;
9986
9996
  }
9987
- return readdirSync2(appsDir).filter((item) => {
9988
- const itemPath = joinPath(appsDir, item);
9989
- const stat = statSync2(itemPath);
9990
- return stat?.isDirectory() === true;
9991
- }).filter((app) => {
9992
- const firebaseJsonPath = joinPath(appsDir, app, "firebase.json");
9993
- return pathExists(firebaseJsonPath);
9994
- }).sort();
9995
- }
9996
- function detectAppDir(appName) {
9997
- const currentDir = process.cwd();
9998
- const appDir = joinPath(currentDir, "apps", appName);
9999
- if (!pathExists(appDir)) {
10000
- throw new DoNotDevError(
10001
- `App directory not found: ${appDir}`,
10002
- "file-not-found",
10003
- { context: { appName, expectedPath: appDir } }
9997
+ if (!result.success) {
9998
+ s.stop("Deployment failed");
9999
+ handleDeploymentFailure(
10000
+ result,
10001
+ `firebase ${args.join(" ")}`,
10002
+ serviceAccountPath
10004
10003
  );
10005
10004
  }
10006
- return appDir;
10005
+ s.stop("Frontend deployed successfully");
10007
10006
  }
10008
- function validateServiceAccount(appDir) {
10009
- const rootKeyPath = joinPath(appDir, "service-account-key.json");
10010
- const functionsDir = joinPath(appDir, "functions");
10011
- const functionsKeyPath = joinPath(functionsDir, "service-account-key.json");
10012
- const keyPath = pathExists(rootKeyPath) ? rootKeyPath : functionsKeyPath;
10013
- const errors = [];
10014
- if (!pathExists(keyPath)) {
10015
- return {
10016
- valid: false,
10017
- info: {
10018
- path: keyPath,
10019
- projectId: "",
10020
- clientEmail: "",
10021
- valid: false,
10022
- errors: [
10023
- `Service account key file not found. Checked:`,
10024
- ` - ${rootKeyPath}`,
10025
- ` - ${functionsKeyPath}`
10026
- ]
10027
- }
10007
+
10008
+ // packages/tooling/src/apps/deploy-functions.ts
10009
+ init_utils();
10010
+ import { execSync as execSync4 } from "node:child_process";
10011
+ init_pathResolver();
10012
+ function backupFiles(functionsDir) {
10013
+ const backupDir = joinPath(functionsDir, ".deploy-backup");
10014
+ const packageJsonPath = joinPath(functionsDir, "package.json");
10015
+ const packageLockJsonPath = joinPath(functionsDir, "package-lock.json");
10016
+ try {
10017
+ ensureDirSync(backupDir);
10018
+ const backupPackageJson = joinPath(backupDir, "package.json");
10019
+ const backupPackageLockJson = joinPath(backupDir, "package-lock.json");
10020
+ if (pathExists(packageJsonPath)) {
10021
+ const content = readSync(packageJsonPath, { format: "text" });
10022
+ if (!content) {
10023
+ throw new Error(`Failed to read package.json: ${packageJsonPath}`);
10024
+ }
10025
+ writeSync(backupPackageJson, content, { overwrite: true });
10026
+ }
10027
+ if (pathExists(packageLockJsonPath)) {
10028
+ const content = readSync(packageLockJsonPath, { format: "text" });
10029
+ if (!content) {
10030
+ throw new Error(
10031
+ `Failed to read package-lock.json: ${packageLockJsonPath}`
10032
+ );
10033
+ }
10034
+ writeSync(backupPackageLockJson, content, { overwrite: true });
10035
+ }
10036
+ return {
10037
+ packageJson: backupPackageJson,
10038
+ packageLockJson: backupPackageLockJson
10039
+ };
10040
+ } catch (error2) {
10041
+ log.warn(
10042
+ `Failed to backup files: ${error2 instanceof Error ? error2.message : String(error2)}`
10043
+ );
10044
+ return null;
10045
+ }
10046
+ }
10047
+ function generateCleanPackageJson(functionsDir) {
10048
+ const packageJsonPath = joinPath(functionsDir, "package.json");
10049
+ if (!pathExists(packageJsonPath)) {
10050
+ throw new DoNotDevError(
10051
+ `package.json not found: ${packageJsonPath}`,
10052
+ "file-not-found"
10053
+ );
10054
+ }
10055
+ const packageJson = readSync(packageJsonPath, { format: "json" });
10056
+ if (!packageJson) {
10057
+ throw new Error(
10058
+ `package.json is empty or invalid JSON at ${packageJsonPath}`
10059
+ );
10060
+ }
10061
+ const cleanPackageJson = { ...packageJson };
10062
+ if (cleanPackageJson.dependencies) {
10063
+ cleanPackageJson.dependencies = Object.fromEntries(
10064
+ Object.entries(cleanPackageJson.dependencies).filter(
10065
+ ([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
10066
+ )
10067
+ );
10068
+ }
10069
+ if (cleanPackageJson.devDependencies) {
10070
+ cleanPackageJson.devDependencies = Object.fromEntries(
10071
+ Object.entries(cleanPackageJson.devDependencies).filter(
10072
+ ([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
10073
+ )
10074
+ );
10075
+ }
10076
+ if (cleanPackageJson.scripts?.preinstall) {
10077
+ delete cleanPackageJson.scripts.preinstall;
10078
+ }
10079
+ const content = JSON.stringify(cleanPackageJson, null, 2) + "\n";
10080
+ writeSync(packageJsonPath, content, { overwrite: true });
10081
+ }
10082
+ function prepareFunctionsForDeployment(functionsDir, verbose = false) {
10083
+ const s = Y2();
10084
+ s.start("Preparing functions for deployment...");
10085
+ try {
10086
+ backupFiles(functionsDir);
10087
+ generateCleanPackageJson(functionsDir);
10088
+ safeRemove(joinPath(functionsDir, "package-lock.json"), {
10089
+ logSuccess: true,
10090
+ successMessage: "Removed package-lock.json - Firebase Cloud Build will generate its own"
10091
+ });
10092
+ s.stop("Functions prepared for deployment");
10093
+ } catch (error2) {
10094
+ s.stop("Preparation failed");
10095
+ throw error2;
10096
+ }
10097
+ }
10098
+ function restoreFunctionsAfterDeployment(functionsDir) {
10099
+ const backupDir = joinPath(functionsDir, ".deploy-backup");
10100
+ const backupPackageJson = joinPath(backupDir, "package.json");
10101
+ const backupPackageLockJson = joinPath(backupDir, "package-lock.json");
10102
+ const packageJsonPath = joinPath(functionsDir, "package.json");
10103
+ const packageLockJsonPath = joinPath(functionsDir, "package-lock.json");
10104
+ try {
10105
+ if (pathExists(backupPackageJson)) {
10106
+ const content = readSync(backupPackageJson, { format: "text" });
10107
+ if (!content) {
10108
+ throw new Error(
10109
+ `Failed to read backup package.json: ${backupPackageJson}`
10110
+ );
10111
+ }
10112
+ writeSync(packageJsonPath, content, { overwrite: true });
10113
+ }
10114
+ if (pathExists(backupPackageLockJson)) {
10115
+ const content = readSync(backupPackageLockJson, { format: "text" });
10116
+ if (!content) {
10117
+ throw new Error(
10118
+ `Failed to read backup package-lock.json: ${backupPackageLockJson}`
10119
+ );
10120
+ }
10121
+ writeSync(packageLockJsonPath, content, { overwrite: true });
10122
+ }
10123
+ safeRemove(backupDir, { silent: true });
10124
+ } catch (error2) {
10125
+ log.warn(
10126
+ `Failed to restore files: ${error2 instanceof Error ? error2.message : String(error2)}`
10127
+ );
10128
+ log.warn(` Backup directory: ${backupDir}`);
10129
+ }
10130
+ }
10131
+ async function deployFunctions(appDir, serviceAccountPath, projectId, config) {
10132
+ const functionsDir = joinPath(appDir, "functions");
10133
+ if (!pathExists(functionsDir)) {
10134
+ throw new DoNotDevError(
10135
+ `Functions directory not found: ${functionsDir}`,
10136
+ "file-not-found"
10137
+ );
10138
+ }
10139
+ const s = Y2();
10140
+ s.start("Validating function dependencies...");
10141
+ const requiredPackages = ["firebase-functions", "firebase-admin"];
10142
+ const missingPackages = requiredPackages.filter((pkg) => {
10143
+ try {
10144
+ resolvePackage(pkg, functionsDir);
10145
+ return false;
10146
+ } catch {
10147
+ return true;
10148
+ }
10149
+ });
10150
+ if (missingPackages.length > 0) {
10151
+ s.stop("Missing dependencies");
10152
+ throw new DoNotDevError(
10153
+ `Missing required dependencies: ${missingPackages.join(", ")}
10154
+
10155
+ To fix this, run:
10156
+ cd ${functionsDir}
10157
+ npm install --production`,
10158
+ "file-not-found",
10159
+ { context: { missingPackages, functionsDir } }
10160
+ );
10161
+ }
10162
+ s.stop("Dependencies validated");
10163
+ prepareFunctionsForDeployment(functionsDir, config.verbose);
10164
+ log.debug("Waiting for file system sync...");
10165
+ await new Promise((resolve4) => setTimeout(resolve4, 1e3));
10166
+ try {
10167
+ if (!config.skipBuild) {
10168
+ const s2 = Y2();
10169
+ s2.start("Building functions...");
10170
+ try {
10171
+ execSync4("bun run build", {
10172
+ cwd: functionsDir,
10173
+ stdio: config.verbose ? "inherit" : "pipe"
10174
+ });
10175
+ s2.stop("Functions built");
10176
+ } catch (error2) {
10177
+ s2.stop("Build failed");
10178
+ throw error2;
10179
+ }
10180
+ }
10181
+ s.start("Deploying functions to Firebase...");
10182
+ const firebaseProjectDir = pathExists(joinPath(appDir, "firebase.json")) ? appDir : functionsDir;
10183
+ log.debug(`Using service account: ${serviceAccountPath}`);
10184
+ log.debug(`Firebase project directory: ${firebaseProjectDir}`);
10185
+ const args = buildFirebaseDeployArgs(
10186
+ "functions",
10187
+ projectId,
10188
+ config.debug,
10189
+ config.force
10190
+ );
10191
+ const result = executeFirebaseCommand(args, {
10192
+ cwd: firebaseProjectDir,
10193
+ serviceAccountPath,
10194
+ projectId,
10195
+ debug: config.debug
10196
+ });
10197
+ if (result.error) {
10198
+ s.stop("Deployment failed");
10199
+ throw result.error;
10200
+ }
10201
+ if (!result.success) {
10202
+ s.stop("Deployment failed");
10203
+ handleDeploymentFailure(
10204
+ result,
10205
+ `firebase ${args.join(" ")}`,
10206
+ serviceAccountPath
10207
+ );
10208
+ }
10209
+ s.stop("Functions deployed successfully");
10210
+ } finally {
10211
+ restoreFunctionsAfterDeployment(functionsDir);
10212
+ }
10213
+ }
10214
+
10215
+ // packages/tooling/src/apps/deploy-utils.ts
10216
+ init_utils();
10217
+ import { spawnSync as spawnSync7 } from "node:child_process";
10218
+ init_pathResolver();
10219
+ function detectAvailableApps() {
10220
+ const currentDir = process.cwd();
10221
+ const appsDir = joinPath(currentDir, "apps");
10222
+ if (!pathExists(appsDir)) {
10223
+ return [];
10224
+ }
10225
+ return readdirSync2(appsDir).filter((item) => {
10226
+ const itemPath = joinPath(appsDir, item);
10227
+ const stat = statSync2(itemPath);
10228
+ return stat?.isDirectory() === true;
10229
+ }).filter((app) => {
10230
+ const firebaseJsonPath = joinPath(appsDir, app, "firebase.json");
10231
+ return pathExists(firebaseJsonPath);
10232
+ }).sort();
10233
+ }
10234
+ function detectAppDir(appName) {
10235
+ const currentDir = process.cwd();
10236
+ const appDir = joinPath(currentDir, "apps", appName);
10237
+ if (!pathExists(appDir)) {
10238
+ throw new DoNotDevError(
10239
+ `App directory not found: ${appDir}`,
10240
+ "file-not-found",
10241
+ { context: { appName, expectedPath: appDir } }
10242
+ );
10243
+ }
10244
+ return appDir;
10245
+ }
10246
+ function validateServiceAccount(appDir) {
10247
+ const rootKeyPath = joinPath(appDir, "service-account-key.json");
10248
+ const functionsDir = joinPath(appDir, "functions");
10249
+ const functionsKeyPath = joinPath(functionsDir, "service-account-key.json");
10250
+ const keyPath = pathExists(rootKeyPath) ? rootKeyPath : functionsKeyPath;
10251
+ const errors = [];
10252
+ if (!pathExists(keyPath)) {
10253
+ return {
10254
+ valid: false,
10255
+ info: {
10256
+ path: keyPath,
10257
+ projectId: "",
10258
+ clientEmail: "",
10259
+ valid: false,
10260
+ errors: [
10261
+ `Service account key file not found. Checked:`,
10262
+ ` - ${rootKeyPath}`,
10263
+ ` - ${functionsKeyPath}`
10264
+ ]
10265
+ }
10028
10266
  };
10029
10267
  }
10030
10268
  try {
@@ -10112,346 +10350,116 @@ function validateFirebaseJson2(appDir) {
10112
10350
  hasHosting,
10113
10351
  hasFunctions,
10114
10352
  errors: []
10115
- };
10116
- } catch (error2) {
10117
- return {
10118
- valid: false,
10119
- hasHosting: false,
10120
- hasFunctions: false,
10121
- errors: [
10122
- `Invalid JSON format: ${error2 instanceof DoNotDevError ? error2.message : error2 instanceof Error ? error2.message : String(error2)}`
10123
- ]
10124
- };
10125
- }
10126
- }
10127
- function validateBuild(appDir) {
10128
- const distPath = joinPath(appDir, "dist");
10129
- if (!pathExists(distPath)) {
10130
- return { exists: false, isEmpty: true, path: distPath };
10131
- }
10132
- try {
10133
- const files = readdirSync2(distPath);
10134
- return {
10135
- exists: true,
10136
- isEmpty: files.length === 0,
10137
- path: distPath
10138
- };
10139
- } catch {
10140
- return { exists: true, isEmpty: true, path: distPath };
10141
- }
10142
- }
10143
- async function showServiceAccountError(info2, projectId) {
10144
- const consoleUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/settings/serviceaccounts/adminsdk` : "https://console.firebase.google.com/project/YOUR_PROJECT/settings/serviceaccounts/adminsdk";
10145
- const errorList = info2.errors.map((e2) => `\u2022 ${e2}`).join("\n");
10146
- Me(
10147
- `${errorList}
10148
-
10149
- Why it matters:
10150
- Firebase CLI needs service account credentials to deploy.
10151
- Without valid credentials, deployment will fail.
10152
-
10153
- How to fix:
10154
- 1. Go to Firebase Console:
10155
- ${consoleUrl}
10156
- 2. Click "Generate New Private Key"
10157
- 3. Save the JSON file as: ${info2.path}
10158
- 4. Required IAM roles:
10159
- \u2022 Firebase Hosting Admin (for frontend)
10160
- \u2022 Cloud Functions Admin (for functions)
10161
- \u2022 Or Firebase Admin (covers both)`,
10162
- "Service Account Error"
10163
- );
10164
- if (projectId) {
10165
- const shouldOpen = await askForConfirmation(
10166
- "Open Firebase Console now?",
10167
- true
10168
- );
10169
- if (shouldOpen) {
10170
- try {
10171
- const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
10172
- spawnSync7(openCommand, [consoleUrl], { shell: true });
10173
- log.success("Opening Firebase Console...");
10174
- } catch {
10175
- log.warn("Could not open browser. Please open the URL manually.");
10176
- }
10177
- }
10178
- }
10179
- }
10180
- function showFirebaseJsonError(errors, appDir, deploymentType) {
10181
- const errorList = errors.map((e2) => `\u2022 ${e2}`).join("\n");
10182
- const firebaseJsonPath = joinPath(appDir, "firebase.json");
10183
- let configExample = "";
10184
- if (deploymentType === "frontend" || deploymentType === "both") {
10185
- configExample += `
10186
- Hosting config:
10187
- { "hosting": { "public": "dist", ... } }`;
10188
- }
10189
- if (deploymentType === "functions" || deploymentType === "both") {
10190
- configExample += `
10191
- Functions config:
10192
- { "functions": [{ "source": "functions", ... }] }`;
10193
- }
10194
- Me(
10195
- `${errorList}
10196
-
10197
- Why it matters:
10198
- firebase.json defines your deployment configuration.
10199
- Without it, Firebase CLI doesn't know what to deploy.
10200
-
10201
- How to fix:
10202
- 1. Ensure firebase.json exists at: ${firebaseJsonPath}
10203
- 2. Add required configuration:${configExample}`,
10204
- "Firebase Configuration Error"
10205
- );
10206
- }
10207
- function clearFirebaseCache(appDir) {
10208
- const firebaseCacheDir = joinPath(appDir, ".firebase");
10209
- if (pathExists(firebaseCacheDir)) {
10210
- log.info("Clearing Firebase cache...");
10211
- const removed = safeRemove(firebaseCacheDir, { silent: true });
10212
- if (removed) {
10213
- log.success("Firebase cache cleared");
10214
- } else {
10215
- log.warn("Could not clear Firebase cache (non-critical)");
10216
- }
10217
- }
10218
- }
10219
-
10220
- // packages/tooling/src/apps/deploy-frontend.ts
10221
- init_utils();
10222
- async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
10223
- const s = Y2();
10224
- s.start("Deploying frontend to Firebase Hosting...");
10225
- const args = buildFirebaseDeployArgs("hosting", projectId, config.debug);
10226
- const result = executeFirebaseCommand(args, {
10227
- cwd: appDir,
10228
- serviceAccountPath,
10229
- projectId,
10230
- debug: config.debug
10231
- });
10232
- if (result.error) {
10233
- s.stop("Deployment failed");
10234
- throw result.error;
10235
- }
10236
- if (!result.success) {
10237
- s.stop("Deployment failed");
10238
- handleDeploymentFailure(
10239
- result,
10240
- `firebase ${args.join(" ")}`,
10241
- serviceAccountPath
10242
- );
10243
- }
10244
- s.stop("Frontend deployed successfully");
10245
- }
10246
-
10247
- // packages/tooling/src/apps/deploy-functions.ts
10248
- init_utils();
10249
- import { execSync as execSync4 } from "node:child_process";
10250
- init_pathResolver();
10251
- function backupFiles(functionsDir) {
10252
- const backupDir = joinPath(functionsDir, ".deploy-backup");
10253
- const packageJsonPath = joinPath(functionsDir, "package.json");
10254
- const packageLockJsonPath = joinPath(functionsDir, "package-lock.json");
10255
- try {
10256
- ensureDirSync(backupDir);
10257
- const backupPackageJson = joinPath(backupDir, "package.json");
10258
- const backupPackageLockJson = joinPath(backupDir, "package-lock.json");
10259
- if (pathExists(packageJsonPath)) {
10260
- const content = readSync(packageJsonPath, { format: "text" });
10261
- if (!content) {
10262
- throw new Error(`Failed to read package.json: ${packageJsonPath}`);
10263
- }
10264
- writeSync(backupPackageJson, content, { overwrite: true });
10265
- }
10266
- if (pathExists(packageLockJsonPath)) {
10267
- const content = readSync(packageLockJsonPath, { format: "text" });
10268
- if (!content) {
10269
- throw new Error(
10270
- `Failed to read package-lock.json: ${packageLockJsonPath}`
10271
- );
10272
- }
10273
- writeSync(backupPackageLockJson, content, { overwrite: true });
10274
- }
10275
- return {
10276
- packageJson: backupPackageJson,
10277
- packageLockJson: backupPackageLockJson
10278
- };
10279
- } catch (error2) {
10280
- log.warn(
10281
- `Failed to backup files: ${error2 instanceof Error ? error2.message : String(error2)}`
10282
- );
10283
- return null;
10284
- }
10285
- }
10286
- function generateCleanPackageJson(functionsDir) {
10287
- const packageJsonPath = joinPath(functionsDir, "package.json");
10288
- if (!pathExists(packageJsonPath)) {
10289
- throw new DoNotDevError(
10290
- `package.json not found: ${packageJsonPath}`,
10291
- "file-not-found"
10292
- );
10293
- }
10294
- const packageJson = readSync(packageJsonPath, { format: "json" });
10295
- if (!packageJson) {
10296
- throw new Error(
10297
- `package.json is empty or invalid JSON at ${packageJsonPath}`
10298
- );
10299
- }
10300
- const cleanPackageJson = { ...packageJson };
10301
- if (cleanPackageJson.dependencies) {
10302
- cleanPackageJson.dependencies = Object.fromEntries(
10303
- Object.entries(cleanPackageJson.dependencies).filter(
10304
- ([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
10305
- )
10306
- );
10307
- }
10308
- if (cleanPackageJson.devDependencies) {
10309
- cleanPackageJson.devDependencies = Object.fromEntries(
10310
- Object.entries(cleanPackageJson.devDependencies).filter(
10311
- ([, version]) => !String(version).startsWith("file:") && !String(version).startsWith("workspace:")
10312
- )
10313
- );
10314
- }
10315
- if (cleanPackageJson.scripts?.preinstall) {
10316
- delete cleanPackageJson.scripts.preinstall;
10317
- }
10318
- const content = JSON.stringify(cleanPackageJson, null, 2) + "\n";
10319
- writeSync(packageJsonPath, content, { overwrite: true });
10320
- }
10321
- function prepareFunctionsForDeployment(functionsDir, verbose = false) {
10322
- const s = Y2();
10323
- s.start("Preparing functions for deployment...");
10324
- try {
10325
- backupFiles(functionsDir);
10326
- generateCleanPackageJson(functionsDir);
10327
- safeRemove(joinPath(functionsDir, "package-lock.json"), {
10328
- logSuccess: true,
10329
- successMessage: "Removed package-lock.json - Firebase Cloud Build will generate its own"
10330
- });
10331
- s.stop("Functions prepared for deployment");
10353
+ };
10332
10354
  } catch (error2) {
10333
- s.stop("Preparation failed");
10334
- throw error2;
10355
+ return {
10356
+ valid: false,
10357
+ hasHosting: false,
10358
+ hasFunctions: false,
10359
+ errors: [
10360
+ `Invalid JSON format: ${error2 instanceof DoNotDevError ? error2.message : error2 instanceof Error ? error2.message : String(error2)}`
10361
+ ]
10362
+ };
10335
10363
  }
10336
10364
  }
10337
- function restoreFunctionsAfterDeployment(functionsDir) {
10338
- const backupDir = joinPath(functionsDir, ".deploy-backup");
10339
- const backupPackageJson = joinPath(backupDir, "package.json");
10340
- const backupPackageLockJson = joinPath(backupDir, "package-lock.json");
10341
- const packageJsonPath = joinPath(functionsDir, "package.json");
10342
- const packageLockJsonPath = joinPath(functionsDir, "package-lock.json");
10365
+ function validateBuild(appDir) {
10366
+ const distPath = joinPath(appDir, "dist");
10367
+ if (!pathExists(distPath)) {
10368
+ return { exists: false, isEmpty: true, path: distPath };
10369
+ }
10343
10370
  try {
10344
- if (pathExists(backupPackageJson)) {
10345
- const content = readSync(backupPackageJson, { format: "text" });
10346
- if (!content) {
10347
- throw new Error(
10348
- `Failed to read backup package.json: ${backupPackageJson}`
10349
- );
10350
- }
10351
- writeSync(packageJsonPath, content, { overwrite: true });
10352
- }
10353
- if (pathExists(backupPackageLockJson)) {
10354
- const content = readSync(backupPackageLockJson, { format: "text" });
10355
- if (!content) {
10356
- throw new Error(
10357
- `Failed to read backup package-lock.json: ${backupPackageLockJson}`
10358
- );
10359
- }
10360
- writeSync(packageLockJsonPath, content, { overwrite: true });
10361
- }
10362
- safeRemove(backupDir, { silent: true });
10363
- } catch (error2) {
10364
- log.warn(
10365
- `Failed to restore files: ${error2 instanceof Error ? error2.message : String(error2)}`
10366
- );
10367
- log.warn(` Backup directory: ${backupDir}`);
10371
+ const files = readdirSync2(distPath);
10372
+ return {
10373
+ exists: true,
10374
+ isEmpty: files.length === 0,
10375
+ path: distPath
10376
+ };
10377
+ } catch {
10378
+ return { exists: true, isEmpty: true, path: distPath };
10368
10379
  }
10369
10380
  }
10370
- async function deployFunctions(appDir, serviceAccountPath, projectId, config) {
10371
- const functionsDir = joinPath(appDir, "functions");
10372
- if (!pathExists(functionsDir)) {
10373
- throw new DoNotDevError(
10374
- `Functions directory not found: ${functionsDir}`,
10375
- "file-not-found"
10376
- );
10377
- }
10378
- const s = Y2();
10379
- s.start("Validating function dependencies...");
10380
- const requiredPackages = ["firebase-functions", "firebase-admin"];
10381
- const missingPackages = requiredPackages.filter((pkg) => {
10382
- try {
10383
- resolvePackage(pkg, functionsDir);
10384
- return false;
10385
- } catch {
10386
- return true;
10387
- }
10388
- });
10389
- if (missingPackages.length > 0) {
10390
- s.stop("Missing dependencies");
10391
- throw new DoNotDevError(
10392
- `Missing required dependencies: ${missingPackages.join(", ")}
10381
+ async function showServiceAccountError(info2, projectId) {
10382
+ const consoleUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/settings/serviceaccounts/adminsdk` : "https://console.firebase.google.com/project/YOUR_PROJECT/settings/serviceaccounts/adminsdk";
10383
+ const errorList = info2.errors.map((e2) => `\u2022 ${e2}`).join("\n");
10384
+ Me(
10385
+ `${errorList}
10393
10386
 
10394
- To fix this, run:
10395
- cd ${functionsDir}
10396
- npm install --production`,
10397
- "file-not-found",
10398
- { context: { missingPackages, functionsDir } }
10387
+ Why it matters:
10388
+ Firebase CLI needs service account credentials to deploy.
10389
+ Without valid credentials, deployment will fail.
10390
+
10391
+ How to fix:
10392
+ 1. Go to Firebase Console:
10393
+ ${consoleUrl}
10394
+ 2. Click "Generate New Private Key"
10395
+ 3. Save the JSON file as: ${info2.path}
10396
+ 4. Required IAM roles:
10397
+ \u2022 Firebase Hosting Admin (for frontend)
10398
+ \u2022 Cloud Functions Admin (for functions)
10399
+ \u2022 Or Firebase Admin (covers both)`,
10400
+ "Service Account Error"
10401
+ );
10402
+ if (projectId) {
10403
+ const shouldOpen = await askForConfirmation(
10404
+ "Open Firebase Console now?",
10405
+ true
10399
10406
  );
10400
- }
10401
- s.stop("Dependencies validated");
10402
- prepareFunctionsForDeployment(functionsDir, config.verbose);
10403
- log.debug("Waiting for file system sync...");
10404
- await new Promise((resolve4) => setTimeout(resolve4, 1e3));
10405
- try {
10406
- if (!config.skipBuild) {
10407
- const s2 = Y2();
10408
- s2.start("Building functions...");
10407
+ if (shouldOpen) {
10409
10408
  try {
10410
- execSync4("bun run build", {
10411
- cwd: functionsDir,
10412
- stdio: config.verbose ? "inherit" : "pipe"
10413
- });
10414
- s2.stop("Functions built");
10415
- } catch (error2) {
10416
- s2.stop("Build failed");
10417
- throw error2;
10409
+ const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
10410
+ spawnSync7(openCommand, [consoleUrl], { shell: true });
10411
+ log.success("Opening Firebase Console...");
10412
+ } catch {
10413
+ log.warn("Could not open browser. Please open the URL manually.");
10418
10414
  }
10419
10415
  }
10420
- s.start("Deploying functions to Firebase...");
10421
- const firebaseProjectDir = pathExists(joinPath(appDir, "firebase.json")) ? appDir : functionsDir;
10422
- log.debug(`Using service account: ${serviceAccountPath}`);
10423
- log.debug(`Firebase project directory: ${firebaseProjectDir}`);
10424
- const args = buildFirebaseDeployArgs(
10425
- "functions",
10426
- projectId,
10427
- config.debug,
10428
- config.force
10429
- );
10430
- const result = executeFirebaseCommand(args, {
10431
- cwd: firebaseProjectDir,
10432
- serviceAccountPath,
10433
- projectId,
10434
- debug: config.debug
10435
- });
10436
- if (result.error) {
10437
- s.stop("Deployment failed");
10438
- throw result.error;
10439
- }
10440
- if (!result.success) {
10441
- s.stop("Deployment failed");
10442
- handleDeploymentFailure(
10443
- result,
10444
- `firebase ${args.join(" ")}`,
10445
- serviceAccountPath
10446
- );
10416
+ }
10417
+ }
10418
+ function showFirebaseJsonError(errors, appDir, deploymentType) {
10419
+ const errorList = errors.map((e2) => `\u2022 ${e2}`).join("\n");
10420
+ const firebaseJsonPath = joinPath(appDir, "firebase.json");
10421
+ let configExample = "";
10422
+ if (deploymentType === "frontend" || deploymentType === "both") {
10423
+ configExample += `
10424
+ Hosting config:
10425
+ { "hosting": { "public": "dist", ... } }`;
10426
+ }
10427
+ if (deploymentType === "functions" || deploymentType === "both") {
10428
+ configExample += `
10429
+ Functions config:
10430
+ { "functions": [{ "source": "functions", ... }] }`;
10431
+ }
10432
+ Me(
10433
+ `${errorList}
10434
+
10435
+ Why it matters:
10436
+ firebase.json defines your deployment configuration.
10437
+ Without it, Firebase CLI doesn't know what to deploy.
10438
+
10439
+ How to fix:
10440
+ 1. Ensure firebase.json exists at: ${firebaseJsonPath}
10441
+ 2. Add required configuration:${configExample}`,
10442
+ "Firebase Configuration Error"
10443
+ );
10444
+ }
10445
+ function clearFirebaseCache(appDir) {
10446
+ const firebaseCacheDir = joinPath(appDir, ".firebase");
10447
+ if (pathExists(firebaseCacheDir)) {
10448
+ log.info("Clearing Firebase cache...");
10449
+ const removed = safeRemove(firebaseCacheDir, { silent: true });
10450
+ if (removed) {
10451
+ log.success("Firebase cache cleared");
10452
+ } else {
10453
+ log.warn("Could not clear Firebase cache (non-critical)");
10447
10454
  }
10448
- s.stop("Functions deployed successfully");
10449
- } finally {
10450
- restoreFunctionsAfterDeployment(functionsDir);
10451
10455
  }
10452
10456
  }
10453
10457
 
10454
10458
  // packages/tooling/src/apps/deploy.ts
10459
+ init_cli_output();
10460
+ init_cli_output();
10461
+ init_errors();
10462
+ init_pathResolver();
10455
10463
  async function main5(options = {}) {
10456
10464
  const config = {
10457
10465
  app: options.app,
@@ -10660,9 +10668,9 @@ Service Account: ${serviceAccountResult.info.clientEmail}`,
10660
10668
 
10661
10669
  // packages/tooling/src/apps/sync-secrets.ts
10662
10670
  init_utils();
10663
- init_errors();
10664
- init_cli_output();
10665
10671
  import { spawnSync as spawnSync8 } from "node:child_process";
10672
+ init_cli_output();
10673
+ init_errors();
10666
10674
  init_pathResolver();
10667
10675
  function parseEnvFile(filePath) {
10668
10676
  if (!pathExists(filePath)) {
@@ -11254,6 +11262,23 @@ function generatePackageJson(templateName, mode, options = {}) {
11254
11262
  }
11255
11263
  }
11256
11264
  }
11265
+ if (mode === "published") {
11266
+ const overrides = {};
11267
+ for (const [groupName, group] of Object.entries(matrix.groups || {})) {
11268
+ if (groupName.startsWith("@donotdev/")) {
11269
+ const version = group.packages?.[groupName];
11270
+ if (version) {
11271
+ overrides[groupName] = version.replace(/^\^/, "");
11272
+ }
11273
+ }
11274
+ }
11275
+ if (matrix.overrides) {
11276
+ Object.assign(overrides, matrix.overrides);
11277
+ }
11278
+ if (Object.keys(overrides).length > 0) {
11279
+ result.overrides = overrides;
11280
+ }
11281
+ }
11257
11282
  return result;
11258
11283
  }
11259
11284
 
@@ -11488,9 +11513,37 @@ Happy coding!`,
11488
11513
  );
11489
11514
  }
11490
11515
  }
11491
- async function main7() {
11516
+ async function main7(options) {
11492
11517
  try {
11493
- await createApp();
11518
+ const hasCliOptions = options?.name || options?.builder !== void 0;
11519
+ if (hasCliOptions && options?.name) {
11520
+ const appName = options.name;
11521
+ const builder = options.builder || "vite";
11522
+ const includeFunctions = options.functions ?? false;
11523
+ if (!isValidFileName(appName)) {
11524
+ throw new Error(
11525
+ `Invalid app name "${appName}". Use only letters, numbers, dashes (-), and underscores (_).`
11526
+ );
11527
+ }
11528
+ if (isReservedAppName(appName)) {
11529
+ throw new Error(
11530
+ `App name "${appName}" is reserved for framework demos. Please choose a different name.`
11531
+ );
11532
+ }
11533
+ const appConfig = {
11534
+ template: builder === "next" ? "nextjs" : "vite",
11535
+ needsBackend: includeFunctions,
11536
+ backendPlatform: includeFunctions ? "firebase" : void 0,
11537
+ needsCRUD: true,
11538
+ selectedEntities: [],
11539
+ userAuth: "social",
11540
+ billing: true,
11541
+ features: []
11542
+ };
11543
+ await createApp(appName, appConfig);
11544
+ } else {
11545
+ await createApp();
11546
+ }
11494
11547
  } catch (error2) {
11495
11548
  log.error("\n\u274C Error creating app:", error2);
11496
11549
  throw error2;
@@ -11978,11 +12031,11 @@ async function main8(options) {
11978
12031
 
11979
12032
  // packages/tooling/src/quality/format.ts
11980
12033
  init_utils();
11981
- init_errors();
11982
12034
  init_cli_output();
12035
+ init_errors();
11983
12036
  init_pathResolver();
11984
12037
  import { spawnSync as spawnSync9 } from "node:child_process";
11985
- import { EOL } from "node:os";
12038
+ import { EOL as EOL2 } from "node:os";
11986
12039
  async function main9(options = {}) {
11987
12040
  const dryRun = options.dryRun ?? false;
11988
12041
  const verbose = options.verbose ?? false;
@@ -12100,7 +12153,7 @@ async function addPathComments(files, rootDir, dryRun, verbose) {
12100
12153
  let modified = false;
12101
12154
  if (contentLines.length === 0) {
12102
12155
  if (!dryRun) {
12103
- writeSync(file, `${expectedPathComment}${EOL}`, {
12156
+ writeSync(file, `${expectedPathComment}${EOL2}`, {
12104
12157
  overwrite: true
12105
12158
  });
12106
12159
  }
@@ -12225,7 +12278,7 @@ async function addPathComments(files, rootDir, dryRun, verbose) {
12225
12278
  newLines.push("");
12226
12279
  }
12227
12280
  newLines.push(...contentLines);
12228
- const newContent = newLines.join(EOL);
12281
+ const newContent = newLines.join(EOL2);
12229
12282
  const contentChanged = fileContent !== newContent;
12230
12283
  if (contentChanged) {
12231
12284
  try {
@@ -12552,70 +12605,10 @@ ${stderr}` : "");
12552
12605
  }
12553
12606
  }
12554
12607
 
12555
- // packages/tooling/src/quality/lint.ts
12556
- init_utils();
12557
- init_errors();
12558
- init_cli_output();
12559
- init_pathResolver();
12560
- import { spawnSync as spawnSync10 } from "node:child_process";
12561
- async function main10(options = {}) {
12562
- const fix = options.fix ?? false;
12563
- const cwd = process.cwd();
12564
- const eslintConfigs = [
12565
- "eslint.config.js",
12566
- "eslint.config.mjs",
12567
- "eslint.config.cjs"
12568
- ];
12569
- const hasEslintConfig = eslintConfigs.some(
12570
- (config) => pathExists(joinPath(cwd, config))
12571
- );
12572
- if (!hasEslintConfig) {
12573
- log.info("No eslint.config.js found in current directory. Skipping lint.");
12574
- log.info("To enable linting, create an eslint.config.js file.");
12575
- return 0;
12576
- }
12577
- const eslintArgs = fix ? ["--fix"] : [];
12578
- if (options.debug) {
12579
- eslintArgs.push("--debug");
12580
- }
12581
- if (options.debug || options.verbose) {
12582
- log.debug(`Linting code${fix ? " and fixing issues" : ""}...`);
12583
- log.debug(` Working directory: ${cwd}`);
12584
- log.debug(` ESLint args: ${eslintArgs.join(" ")}`);
12585
- } else {
12586
- log.info(fix ? "Linting and fixing code..." : "Linting code...");
12587
- }
12588
- try {
12589
- const result = spawnSync10("bunx", ["eslint", ".", ...eslintArgs], {
12590
- cwd,
12591
- stdio: "inherit",
12592
- env: process.env,
12593
- shell: true
12594
- });
12595
- const exitCode = result.status ?? 1;
12596
- if (exitCode === 0) {
12597
- if (!options.debug && !options.verbose) {
12598
- log.success("Linting completed successfully");
12599
- }
12600
- } else {
12601
- if (!options.debug && !options.verbose) {
12602
- log.error("Linting found issues (see above for details)");
12603
- }
12604
- }
12605
- return exitCode;
12606
- } catch (err) {
12607
- throw DoNotDevError.from(
12608
- err,
12609
- "Failed to run ESLint",
12610
- "cli-execution-error"
12611
- );
12612
- }
12613
- }
12614
-
12615
12608
  // packages/tooling/src/maintenance/cacheout.ts
12616
12609
  init_utils();
12617
- init_errors();
12618
12610
  init_cli_output();
12611
+ init_errors();
12619
12612
  init_pathResolver();
12620
12613
  async function findCacheItems(targetDir, verbose) {
12621
12614
  const matches = /* @__PURE__ */ new Set();
@@ -12738,7 +12731,7 @@ function removeItem(path, rootDir, dryRun, verbose) {
12738
12731
  return false;
12739
12732
  }
12740
12733
  }
12741
- async function main11(options) {
12734
+ async function main10(options) {
12742
12735
  const opts = options;
12743
12736
  const targetDir = opts.app ? joinPath(process.cwd(), "apps", opts.app) : process.cwd();
12744
12737
  if (opts.app && !pathExists(targetDir)) {
@@ -12787,14 +12780,13 @@ async function main11(options) {
12787
12780
  }
12788
12781
  export {
12789
12782
  main as build,
12790
- main11 as cacheout,
12783
+ main10 as cacheout,
12791
12784
  main7 as createApp,
12792
12785
  main8 as createProject,
12793
12786
  main5 as deploy,
12794
12787
  main2 as dev,
12795
12788
  main3 as emu,
12796
12789
  main9 as format,
12797
- main10 as lint,
12798
12790
  main4 as preview,
12799
12791
  main6 as syncSecrets
12800
12792
  };