@donotdev/cli 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dependencies-matrix.json +25 -7
- package/dist/bin/commands/build.js +156 -158
- package/dist/bin/commands/bump.js +153 -153
- package/dist/bin/commands/cacheout.js +154 -154
- package/dist/bin/commands/create-app.js +184 -156
- package/dist/bin/commands/create-project.js +154 -154
- package/dist/bin/commands/deploy.js +470 -470
- package/dist/bin/commands/dev.js +155 -155
- package/dist/bin/commands/emu.js +155 -155
- package/dist/bin/commands/format.js +154 -154
- package/dist/bin/commands/lint.js +157 -154
- package/dist/bin/commands/preview.js +155 -155
- package/dist/bin/commands/sync-secrets.js +155 -155
- package/dist/bin/commands/wai.d.ts +11 -0
- package/dist/bin/commands/wai.d.ts.map +1 -0
- package/dist/bin/commands/wai.js +12 -0
- package/dist/bin/commands/wai.js.map +1 -0
- package/dist/bin/dndev.js +24 -8
- package/dist/bin/donotdev.js +24 -8
- package/dist/index.js +524 -497
- package/package.json +1 -1
- package/templates/app-demo/src/config/app.ts.example +12 -0
- package/templates/app-next/src/config/app.ts.example +75 -48
- package/templates/app-vite/index.html.example +71 -37
- package/templates/app-vite/src/config/app.ts.example +75 -47
- package/templates/app-vite/src/pages/FormPageExample.tsx.example +152 -0
- package/templates/app-vite/src/pages/HomePage.tsx.example +81 -134
- package/templates/app-vite/src/pages/ListPageExample.tsx.example +88 -0
- package/templates/functions-firebase/build.mjs.example +8 -1
- package/templates/functions-firebase/functions-firebase/build.mjs.example +8 -1
- package/templates/functions-firebase/functions-firebase/src/index.ts.example +19 -25
- package/templates/functions-firebase/functions.config.js.example +35 -0
- package/templates/root-consumer/entities/ExampleEntity.ts.example +223 -0
- package/templates/root-consumer/entities/demo.ts.example +562 -0
- package/templates/root-consumer/entities/index.ts.example +15 -0
- package/templates/root-consumer/guides/{AGENT_START_HERE.md.example → dndev/AGENT_START_HERE.md.example} +22 -0
- package/templates/root-consumer/guides/dndev/COMPONENTS_CRUD.md.example +231 -0
- package/templates/root-consumer/guides/{SETUP_AUTH.md.example → dndev/SETUP_AUTH.md.example} +30 -0
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +473 -0
- package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +116 -0
- package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +404 -0
- package/templates/root-consumer/guides/wai-way/agents/architect.md.example +78 -0
- package/templates/root-consumer/guides/wai-way/agents/builder.md.example +87 -0
- package/templates/root-consumer/guides/wai-way/agents/extractor.md.example +325 -0
- package/templates/root-consumer/guides/wai-way/agents/polisher.md.example +100 -0
- package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +281 -0
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +77 -0
- package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +104 -0
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +124 -0
- package/templates/root-consumer/guides/wai-way/blueprints/4_configure.md.example +165 -0
- package/templates/root-consumer/guides/wai-way/context_map.json.example +95 -0
- package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +840 -0
- package/templates/root-consumer/guides/wai-way/page_patterns.md.example +686 -0
- package/templates/root-consumer/guides/wai-way/presets_guide.md.example +217 -0
- package/templates/root-consumer/guides/wai-way/spec_template.md.example +312 -0
- package/templates/functions-firebase/functions-firebase/src/crud/createEntity.ts.example +0 -19
- package/templates/functions-firebase/functions-firebase/src/crud/deleteEntity.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/crud/getEntity.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/crud/index.ts.example +0 -12
- package/templates/functions-firebase/functions-firebase/src/crud/listEntities.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/crud/updateEntity.ts.example +0 -14
- package/templates/root-consumer/guides/COMPONENTS_CRUD.md.example +0 -70
- package/templates/root-consumer/guides/SETUP_CRUD.md.example +0 -1244
- package/templates/root-consumer/guides/SETUP_FUNCTIONS.md.example +0 -114
- /package/templates/root-consumer/guides/{COMPONENTS_ADV.md.example → dndev/COMPONENTS_ADV.md.example} +0 -0
- /package/templates/root-consumer/guides/{COMPONENTS_ATOMIC.md.example → dndev/COMPONENTS_ATOMIC.md.example} +0 -0
- /package/templates/root-consumer/guides/{COMPONENTS_UI.md.example → dndev/COMPONENTS_UI.md.example} +0 -0
- /package/templates/root-consumer/guides/{ENV_SETUP.md.example → dndev/ENV_SETUP.md.example} +0 -0
- /package/templates/root-consumer/guides/{INDEX.md.example → dndev/INDEX.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_APP_CONFIG.md.example → dndev/SETUP_APP_CONFIG.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_BILLING.md.example → dndev/SETUP_BILLING.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_I18N.md.example → dndev/SETUP_I18N.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_LAYOUTS.md.example → dndev/SETUP_LAYOUTS.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_OAUTH.md.example → dndev/SETUP_OAUTH.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_PAGES.md.example → dndev/SETUP_PAGES.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_PWA.md.example → dndev/SETUP_PWA.md.example} +0 -0
- /package/templates/root-consumer/guides/{SETUP_THEMES.md.example → dndev/SETUP_THEMES.md.example} +0 -0
- /package/templates/root-consumer/guides/{USE_ROUTING.md.example → dndev/USE_ROUTING.md.example} +0 -0
- /package/templates/root-consumer/guides/{advanced → dndev/advanced}/APP_CHECK.md.example +0 -0
- /package/templates/root-consumer/guides/{advanced → dndev/advanced}/COOKIE_REFERENCE.md.example +0 -0
- /package/templates/root-consumer/guides/{advanced → dndev/advanced}/EMULATORS.md.example +0 -0
- /package/templates/root-consumer/guides/{advanced → dndev/advanced}/VERSION_CONTROL.md.example +0 -0
package/dist/index.js
CHANGED
|
@@ -1088,155 +1088,6 @@ var init_cli_output = __esm({
|
|
|
1088
1088
|
}
|
|
1089
1089
|
});
|
|
1090
1090
|
|
|
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
1091
|
// node_modules/.bun/fast-glob@3.3.3/node_modules/fast-glob/out/utils/array.js
|
|
1241
1092
|
var require_array = __commonJS({
|
|
1242
1093
|
"node_modules/.bun/fast-glob@3.3.3/node_modules/fast-glob/out/utils/array.js"(exports) {
|
|
@@ -6821,69 +6672,218 @@ var require_out4 = __commonJS({
|
|
|
6821
6672
|
}
|
|
6822
6673
|
});
|
|
6823
6674
|
|
|
6824
|
-
// packages/core/config/
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
}
|
|
6835
|
-
|
|
6836
|
-
|
|
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
|
-
});
|
|
6675
|
+
// packages/core/config/constants.js
|
|
6676
|
+
function getPatternsFor(type, repoRoot = null) {
|
|
6677
|
+
const patterns = SCAN_PATTERNS[type];
|
|
6678
|
+
if (!patterns) {
|
|
6679
|
+
throw new Error(`Unknown pattern type: ${type}`);
|
|
6680
|
+
}
|
|
6681
|
+
if (repoRoot && patterns.framework) {
|
|
6682
|
+
return {
|
|
6683
|
+
...patterns,
|
|
6684
|
+
framework: patterns.framework.map((pattern) => `${repoRoot}/${pattern}`)
|
|
6685
|
+
};
|
|
6686
|
+
}
|
|
6687
|
+
return patterns;
|
|
6843
6688
|
}
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6689
|
+
function getGlobOptionsFor(type) {
|
|
6690
|
+
return GLOB_OPTIONS[type] || GLOB_OPTIONS.base;
|
|
6691
|
+
}
|
|
6692
|
+
var I18N_PATHS, SCAN_PATTERNS, GLOB_OPTIONS;
|
|
6693
|
+
var init_constants = __esm({
|
|
6694
|
+
"packages/core/config/constants.js"() {
|
|
6847
6695
|
"use strict";
|
|
6848
6696
|
init_utils();
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6697
|
+
I18N_PATHS = {
|
|
6698
|
+
// Monorepo source structure (locales at root, not in src/)
|
|
6699
|
+
SOURCE_ROOT: "packages/core/i18n",
|
|
6700
|
+
SOURCE_LOCALES: "packages/core/i18n/locales",
|
|
6701
|
+
SOURCE_EAGER: "packages/core/i18n/locales/eager",
|
|
6702
|
+
SOURCE_LAZY: "packages/core/i18n/locales/lazy",
|
|
6703
|
+
// Published structure (same as source - no flattening needed)
|
|
6704
|
+
PUBLISHED_ROOT: "i18n",
|
|
6705
|
+
PUBLISHED_LOCALES: "i18n/locales",
|
|
6706
|
+
PUBLISHED_EAGER: "i18n/locales/eager",
|
|
6707
|
+
PUBLISHED_LAZY: "i18n/locales/lazy"
|
|
6856
6708
|
};
|
|
6857
|
-
|
|
6858
|
-
|
|
6709
|
+
SCAN_PATTERNS = {
|
|
6710
|
+
routes: {
|
|
6711
|
+
consumer: ["src/**/*Page.tsx", "src/pages/**/*Page.tsx"],
|
|
6712
|
+
exclude: [
|
|
6713
|
+
"**/node_modules/**",
|
|
6714
|
+
"**/dist/**",
|
|
6715
|
+
"**/build/**",
|
|
6716
|
+
"**/*.test.tsx",
|
|
6717
|
+
"**/*.stories.tsx"
|
|
6718
|
+
],
|
|
6719
|
+
extensions: [".tsx"]
|
|
6859
6720
|
},
|
|
6860
|
-
|
|
6721
|
+
css: {
|
|
6722
|
+
consumer: ["src/**/*.css"],
|
|
6723
|
+
themes: ["src/**/*.css"],
|
|
6724
|
+
extensions: [".css", ".scss", ".sass"],
|
|
6725
|
+
framework: [
|
|
6726
|
+
"packages/ui/src/**/*.css",
|
|
6727
|
+
"packages/core/components/src/**/*.css",
|
|
6728
|
+
"packages/core/templates/src/**/*.css"
|
|
6729
|
+
]
|
|
6861
6730
|
},
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6731
|
+
i18n: {
|
|
6732
|
+
eager: ["src/locales/*_*.json"],
|
|
6733
|
+
lazy: ["src/**/locales/*_*.json", "!src/locales/*_*.json"],
|
|
6734
|
+
framework: {
|
|
6735
|
+
eager: [`${I18N_PATHS.SOURCE_EAGER}/*_*.json`],
|
|
6736
|
+
lazy: [`${I18N_PATHS.SOURCE_LAZY}/*_*.json`]
|
|
6737
|
+
},
|
|
6738
|
+
extensions: [".json"]
|
|
6739
|
+
},
|
|
6740
|
+
assets: {
|
|
6741
|
+
consumer: ["public/**/*"],
|
|
6742
|
+
fallback: ["manifest.json"],
|
|
6743
|
+
modern: [
|
|
6744
|
+
"logo.svg",
|
|
6745
|
+
"favicon.svg",
|
|
6746
|
+
"apple-touch-icon.png",
|
|
6747
|
+
"android-chrome-192x192.png",
|
|
6748
|
+
"android-chrome-512x512.png"
|
|
6749
|
+
],
|
|
6750
|
+
patterns: [
|
|
6751
|
+
"favicon.svg",
|
|
6752
|
+
"favicon.ico",
|
|
6753
|
+
"favicon-*.png",
|
|
6754
|
+
"logo.svg",
|
|
6755
|
+
"logo.png",
|
|
6756
|
+
"logo.webp",
|
|
6757
|
+
"logo.avif",
|
|
6758
|
+
"apple-touch-icon*.png",
|
|
6759
|
+
"android-chrome-*.png",
|
|
6760
|
+
"manifest.json"
|
|
6761
|
+
],
|
|
6762
|
+
fonts: ["fonts/**/*.woff2", "fonts/**/*.woff", "fonts/**/*.ttf"],
|
|
6763
|
+
framework: ["packages/ui/assets/**/*"]
|
|
6764
|
+
},
|
|
6765
|
+
pwa: {
|
|
6766
|
+
consumer: [
|
|
6767
|
+
"public/manifest.json",
|
|
6768
|
+
"public/service-worker.js",
|
|
6769
|
+
"public/sw.js",
|
|
6770
|
+
"public/icon-192x192.png",
|
|
6771
|
+
"public/icon-512x512.png",
|
|
6772
|
+
"public/favicon.ico",
|
|
6773
|
+
"public/favicon.svg",
|
|
6774
|
+
"public/apple-touch-icon.png",
|
|
6775
|
+
"public/logo.svg"
|
|
6776
|
+
],
|
|
6777
|
+
exclude: ["**/node_modules/**", "**/dist/**", "**/build/**"],
|
|
6778
|
+
extensions: [".json", ".js", ".png", ".svg", ".ico"],
|
|
6779
|
+
framework: ["packages/ui/assets/**/*"]
|
|
6780
|
+
},
|
|
6781
|
+
globalIgnore: [
|
|
6782
|
+
"**/node_modules/**",
|
|
6783
|
+
"**/dist/**",
|
|
6784
|
+
"**/build/**",
|
|
6785
|
+
"**/.git/**",
|
|
6786
|
+
"**/coverage/**",
|
|
6787
|
+
"**/test/**"
|
|
6788
|
+
]
|
|
6789
|
+
};
|
|
6790
|
+
GLOB_OPTIONS = {
|
|
6791
|
+
base: {
|
|
6792
|
+
absolute: true,
|
|
6793
|
+
onlyFiles: true,
|
|
6794
|
+
ignore: SCAN_PATTERNS.globalIgnore
|
|
6795
|
+
},
|
|
6796
|
+
css: {
|
|
6797
|
+
absolute: true,
|
|
6798
|
+
onlyFiles: true,
|
|
6799
|
+
ignore: [...SCAN_PATTERNS.globalIgnore, "**/*.test.css"]
|
|
6800
|
+
},
|
|
6801
|
+
routes: {
|
|
6802
|
+
absolute: true,
|
|
6803
|
+
onlyFiles: true,
|
|
6804
|
+
ignore: [
|
|
6805
|
+
...SCAN_PATTERNS.globalIgnore,
|
|
6806
|
+
"**/*.test.tsx",
|
|
6807
|
+
"**/*.stories.tsx"
|
|
6808
|
+
]
|
|
6809
|
+
},
|
|
6810
|
+
i18n: {
|
|
6811
|
+
absolute: true,
|
|
6812
|
+
onlyFiles: true,
|
|
6813
|
+
ignore: SCAN_PATTERNS.globalIgnore
|
|
6814
|
+
},
|
|
6815
|
+
assets: {
|
|
6816
|
+
absolute: true,
|
|
6817
|
+
onlyFiles: true,
|
|
6818
|
+
ignore: SCAN_PATTERNS.globalIgnore
|
|
6819
|
+
}
|
|
6820
|
+
};
|
|
6821
|
+
}
|
|
6822
|
+
});
|
|
6823
|
+
|
|
6824
|
+
// packages/core/config/utils/PathResolver.ts
|
|
6825
|
+
import * as fs from "node:fs";
|
|
6826
|
+
import { createRequire } from "node:module";
|
|
6827
|
+
import {
|
|
6828
|
+
resolve,
|
|
6829
|
+
join,
|
|
6830
|
+
dirname,
|
|
6831
|
+
relative,
|
|
6832
|
+
normalize,
|
|
6833
|
+
sep,
|
|
6834
|
+
extname
|
|
6835
|
+
} from "node:path";
|
|
6836
|
+
import { fileURLToPath } from "node:url";
|
|
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
|
+
});
|
|
6843
|
+
}
|
|
6844
|
+
var import_fast_glob, constants, log2, PACKAGE_PATHS, PathResolver;
|
|
6845
|
+
var init_PathResolver = __esm({
|
|
6846
|
+
"packages/core/config/utils/PathResolver.ts"() {
|
|
6847
|
+
"use strict";
|
|
6848
|
+
init_utils();
|
|
6849
|
+
import_fast_glob = __toESM(require_out4(), 1);
|
|
6850
|
+
init_constants();
|
|
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
|
|
6856
|
+
};
|
|
6857
|
+
log2 = {
|
|
6858
|
+
error: (message, error2) => {
|
|
6859
|
+
},
|
|
6860
|
+
warn: (message, error2) => {
|
|
6861
|
+
},
|
|
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
6887
|
};
|
|
6888
6888
|
PathResolver = class _PathResolver {
|
|
6889
6889
|
static _instance = null;
|
|
@@ -8289,11 +8289,11 @@ var init_pathResolver = __esm({
|
|
|
8289
8289
|
});
|
|
8290
8290
|
|
|
8291
8291
|
// packages/tooling/src/bundler/utils.ts
|
|
8292
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
8292
8293
|
import { createRequire as createRequire3 } from "node:module";
|
|
8293
|
-
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8294
8294
|
import { dirname as dirname3, resolve as resolve3 } from "node:path";
|
|
8295
|
-
import { Buffer as Buffer2 } from "node:buffer";
|
|
8296
8295
|
import process from "node:process";
|
|
8296
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8297
8297
|
var require2, __filename, __dirname;
|
|
8298
8298
|
var init_utils = __esm({
|
|
8299
8299
|
"packages/tooling/src/bundler/utils.ts"() {
|
|
@@ -8327,7 +8327,6 @@ import { spawnSync, execSync } from "node:child_process";
|
|
|
8327
8327
|
// packages/tooling/src/utils/app-selector.ts
|
|
8328
8328
|
init_utils();
|
|
8329
8329
|
init_dist2();
|
|
8330
|
-
init_cli_output();
|
|
8331
8330
|
|
|
8332
8331
|
// packages/tooling/src/utils/app-detection.ts
|
|
8333
8332
|
init_utils();
|
|
@@ -8415,6 +8414,7 @@ function analyzeApp(appPath, appName) {
|
|
|
8415
8414
|
}
|
|
8416
8415
|
|
|
8417
8416
|
// packages/tooling/src/utils/app-selector.ts
|
|
8417
|
+
init_cli_output();
|
|
8418
8418
|
async function selectApp(projectRoot, appName) {
|
|
8419
8419
|
const apps = detectApps(projectRoot);
|
|
8420
8420
|
if (apps.length === 0) {
|
|
@@ -8449,10 +8449,6 @@ async function selectApp(projectRoot, appName) {
|
|
|
8449
8449
|
return apps.find((a) => a.name === selected) || null;
|
|
8450
8450
|
}
|
|
8451
8451
|
|
|
8452
|
-
// packages/tooling/src/apps/build.ts
|
|
8453
|
-
init_errors();
|
|
8454
|
-
init_cli_output();
|
|
8455
|
-
|
|
8456
8452
|
// packages/tooling/src/utils/cli-input.ts
|
|
8457
8453
|
init_utils();
|
|
8458
8454
|
init_dist2();
|
|
@@ -8516,6 +8512,8 @@ async function askForMultiSelection(message, choices, defaultIndices = []) {
|
|
|
8516
8512
|
}
|
|
8517
8513
|
|
|
8518
8514
|
// packages/tooling/src/apps/build.ts
|
|
8515
|
+
init_cli_output();
|
|
8516
|
+
init_errors();
|
|
8519
8517
|
init_pathResolver();
|
|
8520
8518
|
function validateFirebaseJson(appDir) {
|
|
8521
8519
|
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
@@ -8708,8 +8706,8 @@ async function main() {
|
|
|
8708
8706
|
// packages/tooling/src/apps/dev.ts
|
|
8709
8707
|
init_utils();
|
|
8710
8708
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
8711
|
-
init_errors();
|
|
8712
8709
|
init_cli_output();
|
|
8710
|
+
init_errors();
|
|
8713
8711
|
init_pathResolver();
|
|
8714
8712
|
|
|
8715
8713
|
// packages/tooling/src/utils/spawn-utils.ts
|
|
@@ -8896,8 +8894,8 @@ async function main2() {
|
|
|
8896
8894
|
// packages/tooling/src/apps/emu.ts
|
|
8897
8895
|
init_utils();
|
|
8898
8896
|
import { spawnSync as spawnSync4, execSync as execSync3 } from "node:child_process";
|
|
8899
|
-
init_errors();
|
|
8900
8897
|
init_cli_output();
|
|
8898
|
+
init_errors();
|
|
8901
8899
|
init_pathResolver();
|
|
8902
8900
|
init_pathResolver();
|
|
8903
8901
|
function discoverFirebaseProjectId(appPath) {
|
|
@@ -9201,8 +9199,8 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
|
|
|
9201
9199
|
// packages/tooling/src/apps/preview.ts
|
|
9202
9200
|
init_utils();
|
|
9203
9201
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
9204
|
-
init_errors();
|
|
9205
9202
|
init_cli_output();
|
|
9203
|
+
init_errors();
|
|
9206
9204
|
init_pathResolver();
|
|
9207
9205
|
async function main4() {
|
|
9208
9206
|
const args = process.argv.slice(2);
|
|
@@ -9250,10 +9248,11 @@ async function main4() {
|
|
|
9250
9248
|
|
|
9251
9249
|
// packages/tooling/src/apps/deploy.ts
|
|
9252
9250
|
init_utils();
|
|
9253
|
-
init_cli_output();
|
|
9254
|
-
init_cli_output();
|
|
9255
9251
|
import { execSync as execSync5 } from "node:child_process";
|
|
9256
9252
|
|
|
9253
|
+
// packages/tooling/src/apps/deploy-frontend.ts
|
|
9254
|
+
init_utils();
|
|
9255
|
+
|
|
9257
9256
|
// packages/tooling/src/utils/cli-tools.ts
|
|
9258
9257
|
init_utils();
|
|
9259
9258
|
init_dist2();
|
|
@@ -9503,18 +9502,10 @@ function requireCLI(tool, additionalContext) {
|
|
|
9503
9502
|
return true;
|
|
9504
9503
|
}
|
|
9505
9504
|
|
|
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
9505
|
// packages/tooling/src/utils/create-utils.ts
|
|
9515
9506
|
init_utils();
|
|
9516
|
-
init_pathResolver();
|
|
9517
9507
|
init_cli_output();
|
|
9508
|
+
init_pathResolver();
|
|
9518
9509
|
async function copyTemplateFiles(sourceDir, destDir, replacements) {
|
|
9519
9510
|
if (!pathExists(sourceDir)) {
|
|
9520
9511
|
log.warn(`Warning: Template directory does not exist: ${sourceDir}`);
|
|
@@ -9976,272 +9967,30 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
|
|
|
9976
9967
|
return answers;
|
|
9977
9968
|
}
|
|
9978
9969
|
|
|
9979
|
-
// packages/tooling/src/apps/deploy-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
const
|
|
9984
|
-
|
|
9985
|
-
|
|
9970
|
+
// packages/tooling/src/apps/deploy-frontend.ts
|
|
9971
|
+
async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
|
|
9972
|
+
const s = Y2();
|
|
9973
|
+
s.start("Deploying frontend to Firebase Hosting...");
|
|
9974
|
+
const args = buildFirebaseDeployArgs("hosting", projectId, config.debug);
|
|
9975
|
+
const result = executeFirebaseCommand(args, {
|
|
9976
|
+
cwd: appDir,
|
|
9977
|
+
serviceAccountPath,
|
|
9978
|
+
projectId,
|
|
9979
|
+
debug: config.debug
|
|
9980
|
+
});
|
|
9981
|
+
if (result.error) {
|
|
9982
|
+
s.stop("Deployment failed");
|
|
9983
|
+
throw result.error;
|
|
9986
9984
|
}
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
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 } }
|
|
9985
|
+
if (!result.success) {
|
|
9986
|
+
s.stop("Deployment failed");
|
|
9987
|
+
handleDeploymentFailure(
|
|
9988
|
+
result,
|
|
9989
|
+
`firebase ${args.join(" ")}`,
|
|
9990
|
+
serviceAccountPath
|
|
10004
9991
|
);
|
|
10005
9992
|
}
|
|
10006
|
-
|
|
10007
|
-
}
|
|
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
|
-
}
|
|
10028
|
-
};
|
|
10029
|
-
}
|
|
10030
|
-
try {
|
|
10031
|
-
const keyData = readSync(keyPath, { format: "json" });
|
|
10032
|
-
if (!keyData) {
|
|
10033
|
-
return {
|
|
10034
|
-
valid: false,
|
|
10035
|
-
info: {
|
|
10036
|
-
path: keyPath,
|
|
10037
|
-
projectId: "",
|
|
10038
|
-
clientEmail: "",
|
|
10039
|
-
valid: false,
|
|
10040
|
-
errors: ["Service account key file is empty or invalid JSON"]
|
|
10041
|
-
}
|
|
10042
|
-
};
|
|
10043
|
-
}
|
|
10044
|
-
if (!keyData.project_id) {
|
|
10045
|
-
errors.push("Missing required field: project_id");
|
|
10046
|
-
}
|
|
10047
|
-
if (!keyData.private_key) {
|
|
10048
|
-
errors.push("Missing required field: private_key");
|
|
10049
|
-
}
|
|
10050
|
-
if (!keyData.client_email) {
|
|
10051
|
-
errors.push("Missing required field: client_email");
|
|
10052
|
-
}
|
|
10053
|
-
if (errors.length > 0) {
|
|
10054
|
-
return {
|
|
10055
|
-
valid: false,
|
|
10056
|
-
info: {
|
|
10057
|
-
path: keyPath,
|
|
10058
|
-
projectId: keyData.project_id || "",
|
|
10059
|
-
clientEmail: keyData.client_email || "",
|
|
10060
|
-
valid: false,
|
|
10061
|
-
errors
|
|
10062
|
-
}
|
|
10063
|
-
};
|
|
10064
|
-
}
|
|
10065
|
-
return {
|
|
10066
|
-
valid: true,
|
|
10067
|
-
info: {
|
|
10068
|
-
path: keyPath,
|
|
10069
|
-
projectId: keyData.project_id,
|
|
10070
|
-
clientEmail: keyData.client_email,
|
|
10071
|
-
valid: true,
|
|
10072
|
-
errors: []
|
|
10073
|
-
}
|
|
10074
|
-
};
|
|
10075
|
-
} catch (error2) {
|
|
10076
|
-
return {
|
|
10077
|
-
valid: false,
|
|
10078
|
-
info: {
|
|
10079
|
-
path: keyPath,
|
|
10080
|
-
projectId: "",
|
|
10081
|
-
clientEmail: "",
|
|
10082
|
-
valid: false,
|
|
10083
|
-
errors: [
|
|
10084
|
-
`Invalid JSON format: ${error2 instanceof DoNotDevError ? error2.message : error2 instanceof Error ? error2.message : String(error2)}`
|
|
10085
|
-
]
|
|
10086
|
-
}
|
|
10087
|
-
};
|
|
10088
|
-
}
|
|
10089
|
-
}
|
|
10090
|
-
function validateFirebaseJson2(appDir) {
|
|
10091
|
-
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
10092
|
-
if (!pathExists(firebaseJsonPath)) {
|
|
10093
|
-
return {
|
|
10094
|
-
valid: false,
|
|
10095
|
-
hasHosting: false,
|
|
10096
|
-
hasFunctions: false,
|
|
10097
|
-
errors: [`firebase.json not found at: ${firebaseJsonPath}`]
|
|
10098
|
-
};
|
|
10099
|
-
}
|
|
10100
|
-
try {
|
|
10101
|
-
const config = readSync(firebaseJsonPath, { format: "json" });
|
|
10102
|
-
if (!config) {
|
|
10103
|
-
throw new Error(
|
|
10104
|
-
`firebase.json is empty or invalid JSON at ${firebaseJsonPath}`
|
|
10105
|
-
);
|
|
10106
|
-
}
|
|
10107
|
-
const hasHosting = !!config.hosting;
|
|
10108
|
-
const hasFunctions = !!config.functions && Array.isArray(config.functions);
|
|
10109
|
-
return {
|
|
10110
|
-
valid: true,
|
|
10111
|
-
projectId: config.projectId,
|
|
10112
|
-
hasHosting,
|
|
10113
|
-
hasFunctions,
|
|
10114
|
-
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");
|
|
9993
|
+
s.stop("Frontend deployed successfully");
|
|
10245
9994
|
}
|
|
10246
9995
|
|
|
10247
9996
|
// packages/tooling/src/apps/deploy-functions.ts
|
|
@@ -10451,7 +10200,254 @@ To fix this, run:
|
|
|
10451
10200
|
}
|
|
10452
10201
|
}
|
|
10453
10202
|
|
|
10203
|
+
// packages/tooling/src/apps/deploy-utils.ts
|
|
10204
|
+
init_utils();
|
|
10205
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
10206
|
+
init_pathResolver();
|
|
10207
|
+
function detectAvailableApps() {
|
|
10208
|
+
const currentDir = process.cwd();
|
|
10209
|
+
const appsDir = joinPath(currentDir, "apps");
|
|
10210
|
+
if (!pathExists(appsDir)) {
|
|
10211
|
+
return [];
|
|
10212
|
+
}
|
|
10213
|
+
return readdirSync2(appsDir).filter((item) => {
|
|
10214
|
+
const itemPath = joinPath(appsDir, item);
|
|
10215
|
+
const stat = statSync2(itemPath);
|
|
10216
|
+
return stat?.isDirectory() === true;
|
|
10217
|
+
}).filter((app) => {
|
|
10218
|
+
const firebaseJsonPath = joinPath(appsDir, app, "firebase.json");
|
|
10219
|
+
return pathExists(firebaseJsonPath);
|
|
10220
|
+
}).sort();
|
|
10221
|
+
}
|
|
10222
|
+
function detectAppDir(appName) {
|
|
10223
|
+
const currentDir = process.cwd();
|
|
10224
|
+
const appDir = joinPath(currentDir, "apps", appName);
|
|
10225
|
+
if (!pathExists(appDir)) {
|
|
10226
|
+
throw new DoNotDevError(
|
|
10227
|
+
`App directory not found: ${appDir}`,
|
|
10228
|
+
"file-not-found",
|
|
10229
|
+
{ context: { appName, expectedPath: appDir } }
|
|
10230
|
+
);
|
|
10231
|
+
}
|
|
10232
|
+
return appDir;
|
|
10233
|
+
}
|
|
10234
|
+
function validateServiceAccount(appDir) {
|
|
10235
|
+
const rootKeyPath = joinPath(appDir, "service-account-key.json");
|
|
10236
|
+
const functionsDir = joinPath(appDir, "functions");
|
|
10237
|
+
const functionsKeyPath = joinPath(functionsDir, "service-account-key.json");
|
|
10238
|
+
const keyPath = pathExists(rootKeyPath) ? rootKeyPath : functionsKeyPath;
|
|
10239
|
+
const errors = [];
|
|
10240
|
+
if (!pathExists(keyPath)) {
|
|
10241
|
+
return {
|
|
10242
|
+
valid: false,
|
|
10243
|
+
info: {
|
|
10244
|
+
path: keyPath,
|
|
10245
|
+
projectId: "",
|
|
10246
|
+
clientEmail: "",
|
|
10247
|
+
valid: false,
|
|
10248
|
+
errors: [
|
|
10249
|
+
`Service account key file not found. Checked:`,
|
|
10250
|
+
` - ${rootKeyPath}`,
|
|
10251
|
+
` - ${functionsKeyPath}`
|
|
10252
|
+
]
|
|
10253
|
+
}
|
|
10254
|
+
};
|
|
10255
|
+
}
|
|
10256
|
+
try {
|
|
10257
|
+
const keyData = readSync(keyPath, { format: "json" });
|
|
10258
|
+
if (!keyData) {
|
|
10259
|
+
return {
|
|
10260
|
+
valid: false,
|
|
10261
|
+
info: {
|
|
10262
|
+
path: keyPath,
|
|
10263
|
+
projectId: "",
|
|
10264
|
+
clientEmail: "",
|
|
10265
|
+
valid: false,
|
|
10266
|
+
errors: ["Service account key file is empty or invalid JSON"]
|
|
10267
|
+
}
|
|
10268
|
+
};
|
|
10269
|
+
}
|
|
10270
|
+
if (!keyData.project_id) {
|
|
10271
|
+
errors.push("Missing required field: project_id");
|
|
10272
|
+
}
|
|
10273
|
+
if (!keyData.private_key) {
|
|
10274
|
+
errors.push("Missing required field: private_key");
|
|
10275
|
+
}
|
|
10276
|
+
if (!keyData.client_email) {
|
|
10277
|
+
errors.push("Missing required field: client_email");
|
|
10278
|
+
}
|
|
10279
|
+
if (errors.length > 0) {
|
|
10280
|
+
return {
|
|
10281
|
+
valid: false,
|
|
10282
|
+
info: {
|
|
10283
|
+
path: keyPath,
|
|
10284
|
+
projectId: keyData.project_id || "",
|
|
10285
|
+
clientEmail: keyData.client_email || "",
|
|
10286
|
+
valid: false,
|
|
10287
|
+
errors
|
|
10288
|
+
}
|
|
10289
|
+
};
|
|
10290
|
+
}
|
|
10291
|
+
return {
|
|
10292
|
+
valid: true,
|
|
10293
|
+
info: {
|
|
10294
|
+
path: keyPath,
|
|
10295
|
+
projectId: keyData.project_id,
|
|
10296
|
+
clientEmail: keyData.client_email,
|
|
10297
|
+
valid: true,
|
|
10298
|
+
errors: []
|
|
10299
|
+
}
|
|
10300
|
+
};
|
|
10301
|
+
} catch (error2) {
|
|
10302
|
+
return {
|
|
10303
|
+
valid: false,
|
|
10304
|
+
info: {
|
|
10305
|
+
path: keyPath,
|
|
10306
|
+
projectId: "",
|
|
10307
|
+
clientEmail: "",
|
|
10308
|
+
valid: false,
|
|
10309
|
+
errors: [
|
|
10310
|
+
`Invalid JSON format: ${error2 instanceof DoNotDevError ? error2.message : error2 instanceof Error ? error2.message : String(error2)}`
|
|
10311
|
+
]
|
|
10312
|
+
}
|
|
10313
|
+
};
|
|
10314
|
+
}
|
|
10315
|
+
}
|
|
10316
|
+
function validateFirebaseJson2(appDir) {
|
|
10317
|
+
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
10318
|
+
if (!pathExists(firebaseJsonPath)) {
|
|
10319
|
+
return {
|
|
10320
|
+
valid: false,
|
|
10321
|
+
hasHosting: false,
|
|
10322
|
+
hasFunctions: false,
|
|
10323
|
+
errors: [`firebase.json not found at: ${firebaseJsonPath}`]
|
|
10324
|
+
};
|
|
10325
|
+
}
|
|
10326
|
+
try {
|
|
10327
|
+
const config = readSync(firebaseJsonPath, { format: "json" });
|
|
10328
|
+
if (!config) {
|
|
10329
|
+
throw new Error(
|
|
10330
|
+
`firebase.json is empty or invalid JSON at ${firebaseJsonPath}`
|
|
10331
|
+
);
|
|
10332
|
+
}
|
|
10333
|
+
const hasHosting = !!config.hosting;
|
|
10334
|
+
const hasFunctions = !!config.functions && Array.isArray(config.functions);
|
|
10335
|
+
return {
|
|
10336
|
+
valid: true,
|
|
10337
|
+
projectId: config.projectId,
|
|
10338
|
+
hasHosting,
|
|
10339
|
+
hasFunctions,
|
|
10340
|
+
errors: []
|
|
10341
|
+
};
|
|
10342
|
+
} catch (error2) {
|
|
10343
|
+
return {
|
|
10344
|
+
valid: false,
|
|
10345
|
+
hasHosting: false,
|
|
10346
|
+
hasFunctions: false,
|
|
10347
|
+
errors: [
|
|
10348
|
+
`Invalid JSON format: ${error2 instanceof DoNotDevError ? error2.message : error2 instanceof Error ? error2.message : String(error2)}`
|
|
10349
|
+
]
|
|
10350
|
+
};
|
|
10351
|
+
}
|
|
10352
|
+
}
|
|
10353
|
+
function validateBuild(appDir) {
|
|
10354
|
+
const distPath = joinPath(appDir, "dist");
|
|
10355
|
+
if (!pathExists(distPath)) {
|
|
10356
|
+
return { exists: false, isEmpty: true, path: distPath };
|
|
10357
|
+
}
|
|
10358
|
+
try {
|
|
10359
|
+
const files = readdirSync2(distPath);
|
|
10360
|
+
return {
|
|
10361
|
+
exists: true,
|
|
10362
|
+
isEmpty: files.length === 0,
|
|
10363
|
+
path: distPath
|
|
10364
|
+
};
|
|
10365
|
+
} catch {
|
|
10366
|
+
return { exists: true, isEmpty: true, path: distPath };
|
|
10367
|
+
}
|
|
10368
|
+
}
|
|
10369
|
+
async function showServiceAccountError(info2, projectId) {
|
|
10370
|
+
const consoleUrl = projectId ? `https://console.firebase.google.com/project/${projectId}/settings/serviceaccounts/adminsdk` : "https://console.firebase.google.com/project/YOUR_PROJECT/settings/serviceaccounts/adminsdk";
|
|
10371
|
+
const errorList = info2.errors.map((e2) => `\u2022 ${e2}`).join("\n");
|
|
10372
|
+
Me(
|
|
10373
|
+
`${errorList}
|
|
10374
|
+
|
|
10375
|
+
Why it matters:
|
|
10376
|
+
Firebase CLI needs service account credentials to deploy.
|
|
10377
|
+
Without valid credentials, deployment will fail.
|
|
10378
|
+
|
|
10379
|
+
How to fix:
|
|
10380
|
+
1. Go to Firebase Console:
|
|
10381
|
+
${consoleUrl}
|
|
10382
|
+
2. Click "Generate New Private Key"
|
|
10383
|
+
3. Save the JSON file as: ${info2.path}
|
|
10384
|
+
4. Required IAM roles:
|
|
10385
|
+
\u2022 Firebase Hosting Admin (for frontend)
|
|
10386
|
+
\u2022 Cloud Functions Admin (for functions)
|
|
10387
|
+
\u2022 Or Firebase Admin (covers both)`,
|
|
10388
|
+
"Service Account Error"
|
|
10389
|
+
);
|
|
10390
|
+
if (projectId) {
|
|
10391
|
+
const shouldOpen = await askForConfirmation(
|
|
10392
|
+
"Open Firebase Console now?",
|
|
10393
|
+
true
|
|
10394
|
+
);
|
|
10395
|
+
if (shouldOpen) {
|
|
10396
|
+
try {
|
|
10397
|
+
const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
10398
|
+
spawnSync7(openCommand, [consoleUrl], { shell: true });
|
|
10399
|
+
log.success("Opening Firebase Console...");
|
|
10400
|
+
} catch {
|
|
10401
|
+
log.warn("Could not open browser. Please open the URL manually.");
|
|
10402
|
+
}
|
|
10403
|
+
}
|
|
10404
|
+
}
|
|
10405
|
+
}
|
|
10406
|
+
function showFirebaseJsonError(errors, appDir, deploymentType) {
|
|
10407
|
+
const errorList = errors.map((e2) => `\u2022 ${e2}`).join("\n");
|
|
10408
|
+
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
10409
|
+
let configExample = "";
|
|
10410
|
+
if (deploymentType === "frontend" || deploymentType === "both") {
|
|
10411
|
+
configExample += `
|
|
10412
|
+
Hosting config:
|
|
10413
|
+
{ "hosting": { "public": "dist", ... } }`;
|
|
10414
|
+
}
|
|
10415
|
+
if (deploymentType === "functions" || deploymentType === "both") {
|
|
10416
|
+
configExample += `
|
|
10417
|
+
Functions config:
|
|
10418
|
+
{ "functions": [{ "source": "functions", ... }] }`;
|
|
10419
|
+
}
|
|
10420
|
+
Me(
|
|
10421
|
+
`${errorList}
|
|
10422
|
+
|
|
10423
|
+
Why it matters:
|
|
10424
|
+
firebase.json defines your deployment configuration.
|
|
10425
|
+
Without it, Firebase CLI doesn't know what to deploy.
|
|
10426
|
+
|
|
10427
|
+
How to fix:
|
|
10428
|
+
1. Ensure firebase.json exists at: ${firebaseJsonPath}
|
|
10429
|
+
2. Add required configuration:${configExample}`,
|
|
10430
|
+
"Firebase Configuration Error"
|
|
10431
|
+
);
|
|
10432
|
+
}
|
|
10433
|
+
function clearFirebaseCache(appDir) {
|
|
10434
|
+
const firebaseCacheDir = joinPath(appDir, ".firebase");
|
|
10435
|
+
if (pathExists(firebaseCacheDir)) {
|
|
10436
|
+
log.info("Clearing Firebase cache...");
|
|
10437
|
+
const removed = safeRemove(firebaseCacheDir, { silent: true });
|
|
10438
|
+
if (removed) {
|
|
10439
|
+
log.success("Firebase cache cleared");
|
|
10440
|
+
} else {
|
|
10441
|
+
log.warn("Could not clear Firebase cache (non-critical)");
|
|
10442
|
+
}
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
|
|
10454
10446
|
// packages/tooling/src/apps/deploy.ts
|
|
10447
|
+
init_cli_output();
|
|
10448
|
+
init_cli_output();
|
|
10449
|
+
init_errors();
|
|
10450
|
+
init_pathResolver();
|
|
10455
10451
|
async function main5(options = {}) {
|
|
10456
10452
|
const config = {
|
|
10457
10453
|
app: options.app,
|
|
@@ -10660,9 +10656,9 @@ Service Account: ${serviceAccountResult.info.clientEmail}`,
|
|
|
10660
10656
|
|
|
10661
10657
|
// packages/tooling/src/apps/sync-secrets.ts
|
|
10662
10658
|
init_utils();
|
|
10663
|
-
init_errors();
|
|
10664
|
-
init_cli_output();
|
|
10665
10659
|
import { spawnSync as spawnSync8 } from "node:child_process";
|
|
10660
|
+
init_cli_output();
|
|
10661
|
+
init_errors();
|
|
10666
10662
|
init_pathResolver();
|
|
10667
10663
|
function parseEnvFile(filePath) {
|
|
10668
10664
|
if (!pathExists(filePath)) {
|
|
@@ -11488,9 +11484,37 @@ Happy coding!`,
|
|
|
11488
11484
|
);
|
|
11489
11485
|
}
|
|
11490
11486
|
}
|
|
11491
|
-
async function main7() {
|
|
11487
|
+
async function main7(options) {
|
|
11492
11488
|
try {
|
|
11493
|
-
|
|
11489
|
+
const hasCliOptions = options?.name || options?.builder !== void 0;
|
|
11490
|
+
if (hasCliOptions && options?.name) {
|
|
11491
|
+
const appName = options.name;
|
|
11492
|
+
const builder = options.builder || "vite";
|
|
11493
|
+
const includeFunctions = options.functions ?? false;
|
|
11494
|
+
if (!isValidFileName(appName)) {
|
|
11495
|
+
throw new Error(
|
|
11496
|
+
`Invalid app name "${appName}". Use only letters, numbers, dashes (-), and underscores (_).`
|
|
11497
|
+
);
|
|
11498
|
+
}
|
|
11499
|
+
if (isReservedAppName(appName)) {
|
|
11500
|
+
throw new Error(
|
|
11501
|
+
`App name "${appName}" is reserved for framework demos. Please choose a different name.`
|
|
11502
|
+
);
|
|
11503
|
+
}
|
|
11504
|
+
const appConfig = {
|
|
11505
|
+
template: builder === "next" ? "nextjs" : "vite",
|
|
11506
|
+
needsBackend: includeFunctions,
|
|
11507
|
+
backendPlatform: includeFunctions ? "firebase" : void 0,
|
|
11508
|
+
needsCRUD: true,
|
|
11509
|
+
selectedEntities: [],
|
|
11510
|
+
userAuth: "social",
|
|
11511
|
+
billing: true,
|
|
11512
|
+
features: []
|
|
11513
|
+
};
|
|
11514
|
+
await createApp(appName, appConfig);
|
|
11515
|
+
} else {
|
|
11516
|
+
await createApp();
|
|
11517
|
+
}
|
|
11494
11518
|
} catch (error2) {
|
|
11495
11519
|
log.error("\n\u274C Error creating app:", error2);
|
|
11496
11520
|
throw error2;
|
|
@@ -11978,8 +12002,8 @@ async function main8(options) {
|
|
|
11978
12002
|
|
|
11979
12003
|
// packages/tooling/src/quality/format.ts
|
|
11980
12004
|
init_utils();
|
|
11981
|
-
init_errors();
|
|
11982
12005
|
init_cli_output();
|
|
12006
|
+
init_errors();
|
|
11983
12007
|
init_pathResolver();
|
|
11984
12008
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
11985
12009
|
import { EOL } from "node:os";
|
|
@@ -12554,8 +12578,8 @@ ${stderr}` : "");
|
|
|
12554
12578
|
|
|
12555
12579
|
// packages/tooling/src/quality/lint.ts
|
|
12556
12580
|
init_utils();
|
|
12557
|
-
init_errors();
|
|
12558
12581
|
init_cli_output();
|
|
12582
|
+
init_errors();
|
|
12559
12583
|
init_pathResolver();
|
|
12560
12584
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
12561
12585
|
async function main10(options = {}) {
|
|
@@ -12578,6 +12602,9 @@ async function main10(options = {}) {
|
|
|
12578
12602
|
if (options.debug) {
|
|
12579
12603
|
eslintArgs.push("--debug");
|
|
12580
12604
|
}
|
|
12605
|
+
if (options.quiet) {
|
|
12606
|
+
eslintArgs.push("--quiet");
|
|
12607
|
+
}
|
|
12581
12608
|
if (options.debug || options.verbose) {
|
|
12582
12609
|
log.debug(`Linting code${fix ? " and fixing issues" : ""}...`);
|
|
12583
12610
|
log.debug(` Working directory: ${cwd}`);
|
|
@@ -12614,8 +12641,8 @@ async function main10(options = {}) {
|
|
|
12614
12641
|
|
|
12615
12642
|
// packages/tooling/src/maintenance/cacheout.ts
|
|
12616
12643
|
init_utils();
|
|
12617
|
-
init_errors();
|
|
12618
12644
|
init_cli_output();
|
|
12645
|
+
init_errors();
|
|
12619
12646
|
init_pathResolver();
|
|
12620
12647
|
async function findCacheItems(targetDir, verbose) {
|
|
12621
12648
|
const matches = /* @__PURE__ */ new Set();
|