@donotdev/cli 0.0.17 → 0.0.19
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 +67 -60
- package/dist/bin/commands/coach.js +8177 -0
- package/dist/bin/commands/create-app.js +94 -145
- package/dist/bin/commands/create-project.js +98 -149
- package/dist/bin/commands/deploy.js +81 -59
- package/dist/bin/commands/doctor.js +243 -698
- package/dist/bin/commands/emu.js +2 -2
- package/dist/bin/commands/format.js +4 -1
- package/dist/bin/commands/get-demo.js +8351 -0
- package/dist/bin/commands/make-admin.js +773 -152
- package/dist/bin/commands/setup.js +519 -1711
- package/dist/bin/commands/staging.js +17852 -0
- package/dist/bin/commands/sync-secrets.js +2 -11
- package/dist/bin/commands/type-check.js +7733 -1713
- package/dist/bin/dndev.js +913 -182
- package/dist/bin/donotdev.js +913 -182
- package/dist/index.js +191 -211
- package/package.json +1 -1
- package/templates/app-demo/index.html.example +147 -10
- package/templates/app-demo/src/App.tsx.example +7 -13
- package/templates/app-demo/src/config/app.ts.example +12 -48
- package/templates/app-demo/src/entities/product.ts.example +38 -0
- package/templates/app-demo/src/globals.css.example +5 -1
- package/templates/app-demo/src/main.tsx.example +13 -7
- package/templates/app-demo/src/pages/ChangelogPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/DashboardPage.tsx.example +15 -0
- package/templates/app-demo/src/pages/HomePage.tsx.example +3 -77
- package/templates/app-demo/src/pages/PricingPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/ProductsPage.tsx.example +17 -0
- package/templates/app-demo/src/pages/ProfilePage.tsx.example +16 -0
- package/templates/app-demo/src/pages/SettingsPage.tsx.example +15 -0
- package/templates/app-demo/src/pages/ShowcaseDetailPage.tsx.example +112 -0
- package/templates/app-demo/src/pages/ShowcasePage.tsx.example +91 -0
- package/templates/app-demo/src/pages/legal/LegalPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/legal/PrivacyPage.tsx.example +14 -0
- package/templates/app-demo/src/pages/legal/TermsPage.tsx.example +14 -0
- package/templates/app-demo/tsconfig.json.example +1 -1
- package/templates/app-demo/vite.config.ts.example +23 -48
- package/templates/app-expo/README.md.example +1 -1
- package/templates/app-expo/app/index.tsx.example +1 -1
- package/templates/app-vite/src/pages/HomePage.tsx.example +8 -10
- package/templates/overlay-firebase/env.fragment.example +1 -1
- package/templates/overlay-firebase/env.fragment.expo.example +1 -1
- package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
- package/templates/overlay-supabase/env.fragment.example +1 -1
- package/templates/overlay-supabase/env.fragment.expo.example +1 -1
- package/templates/overlay-supabase/env.fragment.nextjs.example +1 -1
- package/templates/overlay-vercel/env.fragment.example +1 -1
- package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
- package/templates/root-consumer/.claude/commands/brainstorm.md.example +15 -1
- package/templates/root-consumer/.claude/commands/build.md.example +24 -2
- package/templates/root-consumer/.claude/commands/design.md.example +17 -0
- package/templates/root-consumer/.claude/commands/polish.md.example +17 -0
- package/templates/root-consumer/AI.md.example +54 -21
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +21 -6
- package/templates/root-consumer/guides/dndev/COMPONENTS_ADV.md.example +16 -179
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +19 -21
- package/templates/root-consumer/guides/dndev/GOTCHAS.md.example +14 -3
- package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_BLOG.md.example +19 -2
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +35 -1
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +17 -12
- package/templates/root-consumer/guides/dndev/SETUP_LAYOUTS.md.example +32 -0
- package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +1 -1
- package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +74 -6
- package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +17 -12
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +37 -16
- package/templates/root-consumer/guides/dndev/USE_ROUTING.md.example +18 -18
- package/templates/root-consumer/guides/dndev/essences_reference.css.example +119 -2
- package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +1 -1
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +14 -0
- package/templates/root-consumer/guides/wai-way/blueprints/2_entities.md.example +6 -0
- package/templates/root-consumer/guides/wai-way/blueprints/3_compose.md.example +14 -0
- package/templates/root-consumer/guides/wai-way/entity_patterns.md.example +4 -5
- package/templates/root-consumer/guides/wai-way/page_patterns.md.example +2 -2
- package/dist/bin/commands/agent-setup.d.ts +0 -6
- package/dist/bin/commands/agent-setup.d.ts.map +0 -1
- package/dist/bin/commands/agent-setup.js.map +0 -1
- package/dist/bin/commands/build.d.ts +0 -11
- package/dist/bin/commands/build.d.ts.map +0 -1
- package/dist/bin/commands/build.js.map +0 -1
- package/dist/bin/commands/bump.d.ts +0 -11
- package/dist/bin/commands/bump.d.ts.map +0 -1
- package/dist/bin/commands/bump.js.map +0 -1
- package/dist/bin/commands/cacheout.d.ts +0 -11
- package/dist/bin/commands/cacheout.d.ts.map +0 -1
- package/dist/bin/commands/cacheout.js.map +0 -1
- package/dist/bin/commands/create-app.d.ts +0 -11
- package/dist/bin/commands/create-app.d.ts.map +0 -1
- package/dist/bin/commands/create-app.js.map +0 -1
- package/dist/bin/commands/create-project.d.ts +0 -11
- package/dist/bin/commands/create-project.d.ts.map +0 -1
- package/dist/bin/commands/create-project.js.map +0 -1
- package/dist/bin/commands/deploy.d.ts +0 -11
- package/dist/bin/commands/deploy.d.ts.map +0 -1
- package/dist/bin/commands/deploy.js.map +0 -1
- package/dist/bin/commands/dev.d.ts +0 -11
- package/dist/bin/commands/dev.d.ts.map +0 -1
- package/dist/bin/commands/dev.js.map +0 -1
- package/dist/bin/commands/doctor.d.ts +0 -6
- package/dist/bin/commands/doctor.d.ts.map +0 -1
- package/dist/bin/commands/doctor.js.map +0 -1
- package/dist/bin/commands/emu.d.ts +0 -11
- package/dist/bin/commands/emu.d.ts.map +0 -1
- package/dist/bin/commands/emu.js.map +0 -1
- package/dist/bin/commands/format.d.ts +0 -11
- package/dist/bin/commands/format.d.ts.map +0 -1
- package/dist/bin/commands/format.js.map +0 -1
- package/dist/bin/commands/make-admin.d.ts +0 -11
- package/dist/bin/commands/make-admin.d.ts.map +0 -1
- package/dist/bin/commands/make-admin.js.map +0 -1
- package/dist/bin/commands/preview.d.ts +0 -11
- package/dist/bin/commands/preview.d.ts.map +0 -1
- package/dist/bin/commands/preview.js.map +0 -1
- package/dist/bin/commands/setup.d.ts +0 -6
- package/dist/bin/commands/setup.d.ts.map +0 -1
- package/dist/bin/commands/setup.js.map +0 -1
- package/dist/bin/commands/sync-secrets.d.ts +0 -11
- package/dist/bin/commands/sync-secrets.d.ts.map +0 -1
- package/dist/bin/commands/sync-secrets.js.map +0 -1
- package/dist/bin/commands/type-check.d.ts +0 -14
- package/dist/bin/commands/type-check.d.ts.map +0 -1
- package/dist/bin/commands/type-check.js.map +0 -1
- package/dist/bin/commands/wai.d.ts +0 -11
- package/dist/bin/commands/wai.d.ts.map +0 -1
- package/dist/bin/commands/wai.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/templates/app-demo/src/components/ThemeToggle.tsx.example +0 -48
- package/templates/app-demo/src/pages/DetailPage.tsx.example +0 -103
- package/templates/app-demo/src/pages/FullPage.tsx.example +0 -142
- package/templates/app-demo/src/pages/components/DemoLayout.tsx.example +0 -266
- package/templates/app-demo/src/pages/components/LayoutRoute.tsx.example +0 -20
- package/templates/functions-firebase/functions-firebase/README.md.example +0 -123
- package/templates/functions-firebase/functions-firebase/build.mjs.example +0 -5
- package/templates/functions-firebase/functions-firebase/src/auth/getCustomClaims.ts.example +0 -19
- package/templates/functions-firebase/functions-firebase/src/auth/getUserAuthStatus.ts.example +0 -21
- package/templates/functions-firebase/functions-firebase/src/auth/index.ts.example +0 -11
- package/templates/functions-firebase/functions-firebase/src/auth/removeCustomClaims.ts.example +0 -21
- package/templates/functions-firebase/functions-firebase/src/auth/setCustomClaims.ts.example +0 -21
- package/templates/functions-firebase/functions-firebase/src/billing/handleStripeWebhook.ts.example +0 -24
- package/templates/functions-firebase/functions-firebase/src/billing/index.ts.example +0 -10
- package/templates/functions-firebase/functions-firebase/src/billing/processPaymentSuccess.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/billing/refreshSubscriptionStatus.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/index.ts.example +0 -39
- package/templates/functions-firebase/functions-firebase/src/oauth/checkGitHubAccess.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/oauth/disconnect.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/oauth/exchangeToken.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/oauth/getConnections.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/oauth/grantGitHubAccess.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/oauth/index.ts.example +0 -17
- package/templates/functions-firebase/functions-firebase/src/oauth/refreshToken.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/src/oauth/revokeGitHubAccess.ts.example +0 -14
- package/templates/functions-firebase/functions-firebase/tsconfig.json.example +0 -21
- package/templates/functions-vercel/functions-vercel/README.md.example +0 -116
- package/templates/functions-vercel/functions-vercel/build.mjs.example +0 -52
- package/templates/functions-vercel/functions-vercel/src/api/auth/getCustomClaims.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/auth/getUserAuthStatus.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/auth/removeCustomClaims.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/auth/setCustomClaims.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/billing/handleStripeWebhook.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/billing/processPaymentSuccess.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/billing/refreshSubscriptionStatus.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/crud/createEntity.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/crud/deleteEntity.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/crud/getEntity.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/crud/listEntities.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/crud/updateEntity.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/checkGitHubAccess.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/disconnect.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/exchangeToken.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/getConnections.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/grantGitHubAccess.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/refreshToken.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/src/api/oauth/revokeGitHubAccess.ts.example +0 -20
- package/templates/functions-vercel/functions-vercel/tsconfig.json.example +0 -21
- package/templates/functions-vercel/functions-vercel/vercel.json.example +0 -14
- package/templates/github/github/workflows/firebase-deploy.yml.example +0 -79
- /package/templates/functions-firebase/{functions-firebase/.env.example.example → .env.example} +0 -0
- /package/templates/functions-vercel/{functions-vercel/.env.example.example → .env.example} +0 -0
|
@@ -8795,34 +8795,67 @@ var APP_QUESTIONNAIRE = [
|
|
|
8795
8795
|
]
|
|
8796
8796
|
},
|
|
8797
8797
|
{
|
|
8798
|
-
id: "
|
|
8799
|
-
question: "
|
|
8800
|
-
type: "
|
|
8801
|
-
|
|
8798
|
+
id: "host",
|
|
8799
|
+
question: "Where will you host?",
|
|
8800
|
+
type: "select",
|
|
8801
|
+
condition: (answers) => answers.framework !== "expo",
|
|
8802
|
+
defaultValue: (answers) => {
|
|
8803
|
+
return answers.framework === "nextjs" ? "vercel" : "none";
|
|
8804
|
+
},
|
|
8805
|
+
choices: [
|
|
8806
|
+
{ title: "None \u2014 no hosting config", value: "none" },
|
|
8807
|
+
{ title: "Vercel \u2014 edge CDN + serverless", value: "vercel" },
|
|
8808
|
+
{ title: "Firebase Hosting \u2014 Google CDN", value: "firebase" }
|
|
8809
|
+
]
|
|
8810
|
+
},
|
|
8811
|
+
{
|
|
8812
|
+
id: "functions",
|
|
8813
|
+
question: "Serverless functions?",
|
|
8814
|
+
type: "select",
|
|
8815
|
+
defaultValue: "none",
|
|
8816
|
+
// Choices filtered dynamically based on host
|
|
8817
|
+
choices: [
|
|
8818
|
+
{ title: "None", value: "none" },
|
|
8819
|
+
{ title: "Vercel Functions \u2014 edge + node.js", value: "vercel" },
|
|
8820
|
+
{ title: "Firebase Functions \u2014 Google Cloud", value: "firebase" },
|
|
8821
|
+
{ title: "Supabase Edge Functions \u2014 Deno", value: "supabase" }
|
|
8822
|
+
],
|
|
8823
|
+
choicesFilter: (answers) => {
|
|
8824
|
+
const host = answers.host ?? "none";
|
|
8825
|
+
const framework = answers.framework;
|
|
8826
|
+
if (framework === "expo") return ["none", "firebase", "supabase"];
|
|
8827
|
+
if (host === "firebase") return ["none", "firebase"];
|
|
8828
|
+
if (host === "vercel") return ["none", "vercel", "supabase"];
|
|
8829
|
+
return ["none", "vercel", "firebase", "supabase"];
|
|
8830
|
+
}
|
|
8802
8831
|
},
|
|
8803
8832
|
{
|
|
8804
|
-
id: "
|
|
8805
|
-
question: "
|
|
8833
|
+
id: "backend",
|
|
8834
|
+
question: "Backend / BaaS provider?",
|
|
8806
8835
|
type: "select",
|
|
8807
|
-
dependsOn: "needsBackend",
|
|
8808
|
-
condition: (answers) => answers.needsBackend === true,
|
|
8809
8836
|
defaultValue: (answers) => {
|
|
8810
|
-
|
|
8837
|
+
if (answers.functions === "firebase") return "firebase";
|
|
8838
|
+
if (answers.functions === "supabase") return "supabase";
|
|
8839
|
+
return "none";
|
|
8811
8840
|
},
|
|
8812
8841
|
choices: [
|
|
8842
|
+
{ title: "None \u2014 frontend only", value: "none" },
|
|
8813
8843
|
{
|
|
8814
|
-
title: "Firebase \u2014
|
|
8844
|
+
title: "Firebase \u2014 Auth + Firestore + Storage",
|
|
8815
8845
|
value: "firebase"
|
|
8816
8846
|
},
|
|
8817
|
-
{
|
|
8818
|
-
title: "Vercel \u2014 Serverless functions (edge + node.js)",
|
|
8819
|
-
value: "vercel"
|
|
8820
|
-
},
|
|
8821
8847
|
{
|
|
8822
8848
|
title: "Supabase \u2014 Postgres + Auth + Storage",
|
|
8823
8849
|
value: "supabase"
|
|
8824
8850
|
}
|
|
8825
|
-
]
|
|
8851
|
+
],
|
|
8852
|
+
choicesFilter: (answers) => {
|
|
8853
|
+
const functions = answers.functions ?? "none";
|
|
8854
|
+
if (functions === "firebase") return ["none", "firebase"];
|
|
8855
|
+
if (functions === "supabase") return ["none", "supabase"];
|
|
8856
|
+
if (functions === "vercel") return ["none"];
|
|
8857
|
+
return ["none", "firebase", "supabase"];
|
|
8858
|
+
}
|
|
8826
8859
|
}
|
|
8827
8860
|
];
|
|
8828
8861
|
var PROJECT_QUESTIONNAIRE = [
|
|
@@ -8840,12 +8873,13 @@ var PROJECT_QUESTIONNAIRE = [
|
|
|
8840
8873
|
}
|
|
8841
8874
|
];
|
|
8842
8875
|
function aggregateRequirements(answers) {
|
|
8876
|
+
const hasBackend = answers.backend && answers.backend !== "none" || answers.functions && answers.functions !== "none";
|
|
8843
8877
|
const requirements = {
|
|
8844
8878
|
entities: [],
|
|
8845
8879
|
// Entities created in apps/<app>/entities/ (v1), root entities/ for v2
|
|
8846
8880
|
billing: true,
|
|
8847
8881
|
// Always on (useStripeBillingSafe handles missing package)
|
|
8848
|
-
backend:
|
|
8882
|
+
backend: hasBackend,
|
|
8849
8883
|
features: [],
|
|
8850
8884
|
template: "vite",
|
|
8851
8885
|
// Only Vite for now
|
|
@@ -8869,6 +8903,10 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
|
|
|
8869
8903
|
if (!showWIP) {
|
|
8870
8904
|
choices = choices.filter((choice) => !choice.wip);
|
|
8871
8905
|
}
|
|
8906
|
+
if (question.choicesFilter) {
|
|
8907
|
+
const allowed = question.choicesFilter(answers);
|
|
8908
|
+
choices = choices.filter((c) => allowed.includes(c.value));
|
|
8909
|
+
}
|
|
8872
8910
|
if (choices.length === 0) continue;
|
|
8873
8911
|
answer = await askFor.selection(question.question, choices);
|
|
8874
8912
|
break;
|
|
@@ -8931,10 +8969,10 @@ function generateScripts(templateName, options) {
|
|
|
8931
8969
|
scripts.lint = "eslint .";
|
|
8932
8970
|
scripts["type-check"] = "tsc --noEmit";
|
|
8933
8971
|
} else if (templateName === "consumer-root") {
|
|
8934
|
-
scripts.dev = "
|
|
8972
|
+
scripts.dev = "dndev dev";
|
|
8935
8973
|
scripts.build = "turbo run build";
|
|
8936
8974
|
scripts.lint = "turbo run lint";
|
|
8937
|
-
scripts["type-check"] = "
|
|
8975
|
+
scripts["type-check"] = "dndev tc";
|
|
8938
8976
|
} else if (templateName.includes("functions")) {
|
|
8939
8977
|
scripts.build = "node build.mjs";
|
|
8940
8978
|
scripts["build:tsc"] = "tsc";
|
|
@@ -8945,9 +8983,9 @@ function generateScripts(templateName, options) {
|
|
|
8945
8983
|
scripts.dev = "vercel dev";
|
|
8946
8984
|
}
|
|
8947
8985
|
} else if (templateName === "demo") {
|
|
8948
|
-
scripts.dev = "
|
|
8949
|
-
scripts.build = "tsc --noEmit &&
|
|
8950
|
-
scripts.preview = "
|
|
8986
|
+
scripts.dev = "vite";
|
|
8987
|
+
scripts.build = "tsc --noEmit && vite build --mode production";
|
|
8988
|
+
scripts.preview = "vite preview";
|
|
8951
8989
|
scripts["type-check"] = "tsc --noEmit";
|
|
8952
8990
|
} else if (templateName === "entities") {
|
|
8953
8991
|
}
|
|
@@ -9069,120 +9107,22 @@ init_pathResolver();
|
|
|
9069
9107
|
|
|
9070
9108
|
// packages/tooling/src/scaffolding/scaffold-matrix.ts
|
|
9071
9109
|
init_utils();
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
overlay: null,
|
|
9078
|
-
deployConfig: null,
|
|
9079
|
-
functionsTemplate: null
|
|
9080
|
-
},
|
|
9081
|
-
{
|
|
9082
|
-
builder: "vite",
|
|
9083
|
-
backend: "firebase",
|
|
9084
|
-
baseTemplate: "app-vite",
|
|
9085
|
-
overlay: "overlay-firebase",
|
|
9086
|
-
deployConfig: "firebase",
|
|
9087
|
-
functionsTemplate: "functions-firebase"
|
|
9088
|
-
},
|
|
9089
|
-
{
|
|
9090
|
-
builder: "vite",
|
|
9091
|
-
backend: "supabase",
|
|
9092
|
-
baseTemplate: "app-vite",
|
|
9093
|
-
overlay: "overlay-supabase",
|
|
9094
|
-
deployConfig: "vercel-supabase",
|
|
9095
|
-
functionsTemplate: "functions-supabase"
|
|
9096
|
-
},
|
|
9097
|
-
{
|
|
9098
|
-
builder: "vite",
|
|
9099
|
-
backend: "vercel",
|
|
9100
|
-
baseTemplate: "app-vite",
|
|
9101
|
-
overlay: "overlay-vercel",
|
|
9102
|
-
deployConfig: "vercel-vercel",
|
|
9103
|
-
functionsTemplate: "functions-vercel"
|
|
9104
|
-
},
|
|
9105
|
-
{
|
|
9106
|
-
builder: "nextjs",
|
|
9107
|
-
backend: "none",
|
|
9108
|
-
baseTemplate: "app-next",
|
|
9109
|
-
overlay: null,
|
|
9110
|
-
deployConfig: null,
|
|
9111
|
-
functionsTemplate: null
|
|
9112
|
-
},
|
|
9113
|
-
{
|
|
9114
|
-
builder: "nextjs",
|
|
9115
|
-
backend: "firebase",
|
|
9116
|
-
baseTemplate: "app-next",
|
|
9117
|
-
overlay: "overlay-firebase",
|
|
9118
|
-
deployConfig: "firebase",
|
|
9119
|
-
functionsTemplate: "functions-firebase"
|
|
9120
|
-
},
|
|
9121
|
-
{
|
|
9122
|
-
builder: "nextjs",
|
|
9123
|
-
backend: "supabase",
|
|
9124
|
-
baseTemplate: "app-next",
|
|
9125
|
-
overlay: "overlay-supabase",
|
|
9126
|
-
deployConfig: "vercel-supabase",
|
|
9127
|
-
functionsTemplate: "functions-supabase"
|
|
9128
|
-
},
|
|
9129
|
-
{
|
|
9130
|
-
builder: "nextjs",
|
|
9131
|
-
backend: "vercel",
|
|
9132
|
-
baseTemplate: "app-next",
|
|
9133
|
-
overlay: "overlay-vercel",
|
|
9134
|
-
deployConfig: "vercel-vercel",
|
|
9135
|
-
functionsTemplate: "functions-vercel"
|
|
9136
|
-
},
|
|
9137
|
-
{
|
|
9138
|
-
builder: "expo",
|
|
9139
|
-
backend: "none",
|
|
9140
|
-
baseTemplate: "app-expo",
|
|
9141
|
-
overlay: null,
|
|
9142
|
-
deployConfig: null,
|
|
9143
|
-
functionsTemplate: null
|
|
9144
|
-
},
|
|
9145
|
-
{
|
|
9146
|
-
builder: "expo",
|
|
9147
|
-
backend: "firebase",
|
|
9148
|
-
baseTemplate: "app-expo",
|
|
9149
|
-
overlay: "overlay-firebase",
|
|
9150
|
-
deployConfig: null,
|
|
9151
|
-
functionsTemplate: "functions-firebase"
|
|
9152
|
-
},
|
|
9153
|
-
{
|
|
9154
|
-
builder: "expo",
|
|
9155
|
-
backend: "supabase",
|
|
9156
|
-
baseTemplate: "app-expo",
|
|
9157
|
-
overlay: "overlay-supabase",
|
|
9158
|
-
deployConfig: null,
|
|
9159
|
-
functionsTemplate: "functions-supabase"
|
|
9160
|
-
},
|
|
9161
|
-
{
|
|
9162
|
-
builder: "demo",
|
|
9163
|
-
backend: "none",
|
|
9164
|
-
baseTemplate: "app-demo",
|
|
9165
|
-
overlay: null,
|
|
9166
|
-
deployConfig: null,
|
|
9167
|
-
functionsTemplate: null
|
|
9168
|
-
}
|
|
9169
|
-
];
|
|
9170
|
-
function comboKey(builder, backend) {
|
|
9171
|
-
return `${builder}-${backend}`;
|
|
9110
|
+
function resolveDeployConfig(host, backend) {
|
|
9111
|
+
if (host === "none") return null;
|
|
9112
|
+
if (host === "firebase") return "firebase";
|
|
9113
|
+
if (backend === "supabase") return "vercel-supabase";
|
|
9114
|
+
return "vercel-vercel";
|
|
9172
9115
|
}
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
);
|
|
9184
|
-
}
|
|
9185
|
-
return row;
|
|
9116
|
+
function getScaffoldParts(builder, host, functions, backend) {
|
|
9117
|
+
const baseTemplate = builder === "nextjs" ? "app-next" : builder === "demo" ? "app-demo" : `app-${builder}`;
|
|
9118
|
+
return {
|
|
9119
|
+
builder,
|
|
9120
|
+
backend,
|
|
9121
|
+
baseTemplate,
|
|
9122
|
+
overlay: backend !== "none" ? `overlay-${backend}` : null,
|
|
9123
|
+
deployConfig: resolveDeployConfig(host, backend),
|
|
9124
|
+
functionsTemplate: functions !== "none" ? `functions-${functions}` : null
|
|
9125
|
+
};
|
|
9186
9126
|
}
|
|
9187
9127
|
|
|
9188
9128
|
// packages/tooling/src/scaffolding/create-app.ts
|
|
@@ -9222,11 +9162,15 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9222
9162
|
input: askForInput
|
|
9223
9163
|
});
|
|
9224
9164
|
const requirements = aggregateRequirements(answers);
|
|
9225
|
-
const
|
|
9165
|
+
const framework = answers.framework || "vite";
|
|
9166
|
+
const host2 = answers.host || "none";
|
|
9167
|
+
const functions2 = answers.functions || "none";
|
|
9168
|
+
const backend2 = answers.backend || "none";
|
|
9226
9169
|
appConfig = {
|
|
9227
|
-
template:
|
|
9228
|
-
|
|
9229
|
-
|
|
9170
|
+
template: framework,
|
|
9171
|
+
host: host2,
|
|
9172
|
+
functions: functions2,
|
|
9173
|
+
backend: backend2,
|
|
9230
9174
|
needsCRUD: true,
|
|
9231
9175
|
// Always on
|
|
9232
9176
|
selectedEntities: [],
|
|
@@ -9272,12 +9216,14 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9272
9216
|
s.start(`Creating app: ${appName}`);
|
|
9273
9217
|
await ensureDir(appDir);
|
|
9274
9218
|
const builder = appTemplate;
|
|
9275
|
-
const
|
|
9276
|
-
const
|
|
9219
|
+
const host = appConfig.host ?? "none";
|
|
9220
|
+
const functions = appConfig.functions ?? "none";
|
|
9221
|
+
const backend = appConfig.backend ?? "none";
|
|
9222
|
+
const row = getScaffoldParts(builder, host, functions, backend);
|
|
9277
9223
|
const templateDir = row.baseTemplate;
|
|
9278
9224
|
const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
|
|
9279
9225
|
const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
|
|
9280
|
-
const backendPlatform =
|
|
9226
|
+
const backendPlatform = backend !== "none" ? backend : "firebase";
|
|
9281
9227
|
const deployConfig = row.deployConfig;
|
|
9282
9228
|
const replacements = {
|
|
9283
9229
|
projectName: appName,
|
|
@@ -9627,12 +9573,11 @@ async function collectAppConfig(appName) {
|
|
|
9627
9573
|
input: askForInput
|
|
9628
9574
|
});
|
|
9629
9575
|
const framework = answers.framework || "vite";
|
|
9630
|
-
const needsBackend = answers.needsBackend || false;
|
|
9631
|
-
const defaultPlatform = framework === "nextjs" ? "vercel" : "firebase";
|
|
9632
9576
|
return {
|
|
9633
9577
|
template: framework,
|
|
9634
|
-
|
|
9635
|
-
|
|
9578
|
+
host: answers.host || "none",
|
|
9579
|
+
functions: answers.functions || "none",
|
|
9580
|
+
backend: answers.backend || "none",
|
|
9636
9581
|
needsCRUD: false,
|
|
9637
9582
|
selectedEntities: [],
|
|
9638
9583
|
userAuth: "none",
|
|
@@ -9779,7 +9724,8 @@ async function main(options) {
|
|
|
9779
9724
|
Me(`Configuring "${trimmedName}"...`, "\u2699\uFE0F");
|
|
9780
9725
|
const config = await collectAppConfig(trimmedName);
|
|
9781
9726
|
appConfigs[trimmedName] = config;
|
|
9782
|
-
if (config.
|
|
9727
|
+
if (config.backend !== "none" || config.functions !== "none")
|
|
9728
|
+
anyAppNeedsBackend = true;
|
|
9783
9729
|
}
|
|
9784
9730
|
let installDemoApp = await askForConfirmation(
|
|
9785
9731
|
"Would you like to install the demo app? (component showcase)",
|
|
@@ -9855,8 +9801,9 @@ async function main(options) {
|
|
|
9855
9801
|
log.warn(`Missing config for app "${appName}", using defaults`);
|
|
9856
9802
|
appConfigs[appName] = {
|
|
9857
9803
|
template: "vite",
|
|
9858
|
-
|
|
9859
|
-
|
|
9804
|
+
host: "none",
|
|
9805
|
+
functions: "none",
|
|
9806
|
+
backend: "none",
|
|
9860
9807
|
needsCRUD: false,
|
|
9861
9808
|
selectedEntities: [],
|
|
9862
9809
|
userAuth: "none",
|
|
@@ -9904,7 +9851,9 @@ async function main(options) {
|
|
|
9904
9851
|
overwrite: true
|
|
9905
9852
|
});
|
|
9906
9853
|
const relativeMonorepoPath = executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "";
|
|
9907
|
-
const primaryPlatform = Object.values(appConfigs).find(
|
|
9854
|
+
const primaryPlatform = Object.values(appConfigs).find(
|
|
9855
|
+
(c) => c.backend !== "none"
|
|
9856
|
+
)?.backend ?? "firebase";
|
|
9908
9857
|
const rootPackageJson = generatePackageJson(
|
|
9909
9858
|
"consumer-root",
|
|
9910
9859
|
executionMode,
|
|
@@ -7847,7 +7847,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
7847
7847
|
function readdirSync2(dirPath, options) {
|
|
7848
7848
|
return pathResolverInstance.readdirSync(dirPath, options);
|
|
7849
7849
|
}
|
|
7850
|
-
var pathResolverInstance, resolvePackage, normalizePath, pathExists, readSync,
|
|
7850
|
+
var pathResolverInstance, resolvePackage, normalizePath, pathExists, readSync, writeSync, removeSync, statSync2, ensureDirSync, getRelativePathBetween, getDirname, joinPath;
|
|
7851
7851
|
var init_pathResolver = __esm({
|
|
7852
7852
|
"packages/tooling/src/utils/pathResolver.ts"() {
|
|
7853
7853
|
"use strict";
|
|
@@ -7860,12 +7860,9 @@ var init_pathResolver = __esm({
|
|
|
7860
7860
|
};
|
|
7861
7861
|
pathExists = (filePath, silent = false) => pathResolverInstance.pathExists(filePath, silent);
|
|
7862
7862
|
readSync = (filePath, options) => pathResolverInstance.readSync(filePath, options);
|
|
7863
|
-
write = async (filePath, content, options) => pathResolverInstance.write(filePath, content, options);
|
|
7864
7863
|
writeSync = (filePath, content, options) => pathResolverInstance.writeSync(filePath, content, options);
|
|
7865
|
-
remove = async (path) => pathResolverInstance.remove(path);
|
|
7866
7864
|
removeSync = (path) => pathResolverInstance.removeSync(path);
|
|
7867
7865
|
statSync2 = (filePath) => pathResolverInstance.statSync(filePath);
|
|
7868
|
-
ensureDir = async (dirPath) => pathResolverInstance.ensureDir(dirPath);
|
|
7869
7866
|
ensureDirSync = (dirPath) => pathResolverInstance.ensureDirSync(dirPath);
|
|
7870
7867
|
getRelativePathBetween = (from, to) => {
|
|
7871
7868
|
return normalizePath(relative2(from, to));
|
|
@@ -8181,21 +8178,21 @@ function getCLIInstallInstructions(tool) {
|
|
|
8181
8178
|
]
|
|
8182
8179
|
},
|
|
8183
8180
|
[CLI_TOOLS.YARN]: {
|
|
8184
|
-
win32: ["
|
|
8185
|
-
darwin: ["
|
|
8186
|
-
linux: ["
|
|
8181
|
+
win32: ["bun install -g yarn", "Or: choco install yarn"],
|
|
8182
|
+
darwin: ["bun install -g yarn", "Or: brew install yarn"],
|
|
8183
|
+
linux: ["bun install -g yarn", "Or check your package manager"]
|
|
8187
8184
|
},
|
|
8188
8185
|
[CLI_TOOLS.FIREBASE]: {
|
|
8189
8186
|
win32: [
|
|
8190
|
-
"
|
|
8187
|
+
"bun install -g firebase-tools",
|
|
8191
8188
|
"Or download standalone binary: https://firebase.google.com/docs/cli#windows-standalone-binary"
|
|
8192
8189
|
],
|
|
8193
8190
|
darwin: [
|
|
8194
|
-
"
|
|
8191
|
+
"bun install -g firebase-tools",
|
|
8195
8192
|
"Or: brew install firebase-cli"
|
|
8196
8193
|
],
|
|
8197
8194
|
linux: [
|
|
8198
|
-
"
|
|
8195
|
+
"bun install -g firebase-tools",
|
|
8199
8196
|
"Or check your package manager (dnf, apt, pacman, etc.)"
|
|
8200
8197
|
]
|
|
8201
8198
|
},
|
|
@@ -8212,25 +8209,25 @@ function getCLIInstallInstructions(tool) {
|
|
|
8212
8209
|
]
|
|
8213
8210
|
},
|
|
8214
8211
|
[CLI_TOOLS.VERCEL]: {
|
|
8215
|
-
win32: ["
|
|
8212
|
+
win32: ["bun install -g vercel", "Or: bunx vercel (no install)"],
|
|
8216
8213
|
darwin: [
|
|
8217
|
-
"
|
|
8214
|
+
"bun install -g vercel",
|
|
8218
8215
|
"Or: brew install vercel",
|
|
8219
|
-
"Or:
|
|
8216
|
+
"Or: bunx vercel"
|
|
8220
8217
|
],
|
|
8221
|
-
linux: ["
|
|
8218
|
+
linux: ["bun install -g vercel", "Or: bunx vercel"]
|
|
8222
8219
|
},
|
|
8223
8220
|
[CLI_TOOLS.SENTRY_CLI]: {
|
|
8224
8221
|
win32: [
|
|
8225
|
-
"
|
|
8222
|
+
"bun install -g @sentry/cli",
|
|
8226
8223
|
"Or download from: https://github.com/getsentry/sentry-cli/releases"
|
|
8227
8224
|
],
|
|
8228
8225
|
darwin: [
|
|
8229
|
-
"
|
|
8226
|
+
"bun install -g @sentry/cli",
|
|
8230
8227
|
"Or: brew install getsentry/tools/sentry-cli"
|
|
8231
8228
|
],
|
|
8232
8229
|
linux: [
|
|
8233
|
-
"
|
|
8230
|
+
"bun install -g @sentry/cli",
|
|
8234
8231
|
"Or: curl -sL https://sentry.io/get-cli/ | bash"
|
|
8235
8232
|
]
|
|
8236
8233
|
},
|
|
@@ -8259,9 +8256,9 @@ function getCLIInstallInstructions(tool) {
|
|
|
8259
8256
|
]
|
|
8260
8257
|
},
|
|
8261
8258
|
[CLI_TOOLS.TSX]: {
|
|
8262
|
-
win32: ["
|
|
8263
|
-
darwin: ["
|
|
8264
|
-
linux: ["
|
|
8259
|
+
win32: ["bun install -g tsx"],
|
|
8260
|
+
darwin: ["bun install -g tsx"],
|
|
8261
|
+
linux: ["bun install -g tsx"]
|
|
8265
8262
|
}
|
|
8266
8263
|
};
|
|
8267
8264
|
const platformInstructions = instructions[tool]?.[platform] || instructions[tool]?.linux || [];
|
|
@@ -8356,14 +8353,27 @@ function readEnvVar(filePath, varName) {
|
|
|
8356
8353
|
}
|
|
8357
8354
|
return null;
|
|
8358
8355
|
}
|
|
8359
|
-
function
|
|
8360
|
-
if (process.env
|
|
8361
|
-
const
|
|
8362
|
-
if (fromEnv) return fromEnv;
|
|
8363
|
-
const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), "VERCEL_TOKEN");
|
|
8356
|
+
function resolveVercelVar(appDir, varName) {
|
|
8357
|
+
if (process.env[varName]) return process.env[varName];
|
|
8358
|
+
const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), varName);
|
|
8364
8359
|
if (fromLocal) return fromLocal;
|
|
8360
|
+
const fromEnv = readEnvVar(joinPath(appDir, ".env"), varName);
|
|
8361
|
+
if (fromEnv) return fromEnv;
|
|
8365
8362
|
return null;
|
|
8366
8363
|
}
|
|
8364
|
+
function resolveVercelCredentials(appDir) {
|
|
8365
|
+
const token = resolveVercelVar(appDir, "VERCEL_TOKEN");
|
|
8366
|
+
const orgId = resolveVercelVar(appDir, "VERCEL_ORG_ID");
|
|
8367
|
+
const projectId = resolveVercelVar(appDir, "VERCEL_PROJECT_ID");
|
|
8368
|
+
const missing = [];
|
|
8369
|
+
if (!token) missing.push("VERCEL_TOKEN");
|
|
8370
|
+
if (!orgId) missing.push("VERCEL_ORG_ID");
|
|
8371
|
+
if (!projectId) missing.push("VERCEL_PROJECT_ID");
|
|
8372
|
+
if (missing.length > 0) return { missing };
|
|
8373
|
+
return {
|
|
8374
|
+
credentials: { token, orgId, projectId }
|
|
8375
|
+
};
|
|
8376
|
+
}
|
|
8367
8377
|
var init_vercel_token = __esm({
|
|
8368
8378
|
"packages/tooling/src/cli/setup/vercel-token.ts"() {
|
|
8369
8379
|
"use strict";
|
|
@@ -15943,10 +15953,7 @@ async function setFirebaseSecret(key, value, projectId, dryRun = false, cwd) {
|
|
|
15943
15953
|
}
|
|
15944
15954
|
try {
|
|
15945
15955
|
log.info(`Setting Firebase secret: ${key} (project: ${finalProjectId})`);
|
|
15946
|
-
const
|
|
15947
|
-
await ensureDir(tempDir);
|
|
15948
|
-
const tempFile = joinPath(tempDir, `secret-${key}-${Date.now()}.txt`);
|
|
15949
|
-
await write(tempFile, value);
|
|
15956
|
+
const tempFile = "";
|
|
15950
15957
|
try {
|
|
15951
15958
|
const args = ["functions:secrets:set", key, "--project", finalProjectId];
|
|
15952
15959
|
const firebaseCmd = process.platform === "win32" ? "firebase.cmd" : "firebase";
|
|
@@ -16021,9 +16028,6 @@ ${errorOutput}`
|
|
|
16021
16028
|
}
|
|
16022
16029
|
log.success(`Firebase secret ${key} set successfully`);
|
|
16023
16030
|
} finally {
|
|
16024
|
-
if (pathExists(tempFile)) {
|
|
16025
|
-
await remove(tempFile);
|
|
16026
|
-
}
|
|
16027
16031
|
}
|
|
16028
16032
|
} catch (err) {
|
|
16029
16033
|
log.error(`Failed to set Firebase secret ${key}:`, err);
|
|
@@ -16601,33 +16605,39 @@ init_cli_output();
|
|
|
16601
16605
|
init_vercel_token();
|
|
16602
16606
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
16603
16607
|
async function deployVercelFrontend(appDir, _config) {
|
|
16604
|
-
const
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
|
|
16608
|
-
|
|
16609
|
-
|
|
16610
|
-
const args = ["vercel", "--prod", "--yes"];
|
|
16611
|
-
if (token) {
|
|
16612
|
-
args.push("--token", token);
|
|
16608
|
+
const result = resolveVercelCredentials(appDir);
|
|
16609
|
+
if (result.missing) {
|
|
16610
|
+
throw new Error(
|
|
16611
|
+
`Missing Vercel credentials in .env.local: ${result.missing.join(", ")}
|
|
16612
|
+
Add them to apps/<app>/.env.local \u2014 see guides/dndev/SETUP_VERCEL.md`
|
|
16613
|
+
);
|
|
16613
16614
|
}
|
|
16614
|
-
|
|
16615
|
-
|
|
16615
|
+
const { token, orgId, projectId } = result.credentials;
|
|
16616
|
+
log.debug("Using Vercel credentials from .env (token-based auth)");
|
|
16617
|
+
log.info("Deploying to Vercel...");
|
|
16618
|
+
const deployResult = spawnSync3(
|
|
16619
|
+
"bunx",
|
|
16620
|
+
["vercel", "deploy", "--prod", "--yes", "--token", token],
|
|
16621
|
+
{
|
|
16616
16622
|
cwd: appDir,
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
|
|
16625
|
-
);
|
|
16623
|
+
// stdout piped to capture deployment URL, stderr inherits for progress
|
|
16624
|
+
stdio: ["inherit", "pipe", "inherit"],
|
|
16625
|
+
encoding: "utf-8",
|
|
16626
|
+
env: {
|
|
16627
|
+
...process.env,
|
|
16628
|
+
VERCEL_ORG_ID: orgId,
|
|
16629
|
+
VERCEL_PROJECT_ID: projectId
|
|
16630
|
+
}
|
|
16626
16631
|
}
|
|
16627
|
-
|
|
16628
|
-
|
|
16629
|
-
|
|
16630
|
-
|
|
16632
|
+
);
|
|
16633
|
+
if (deployResult.status !== 0) {
|
|
16634
|
+
throw new Error(`vercel deploy exited with code ${deployResult.status}`);
|
|
16635
|
+
}
|
|
16636
|
+
const deployUrl = deployResult.stdout?.trim();
|
|
16637
|
+
if (deployUrl) {
|
|
16638
|
+
log.success(`Production: ${deployUrl}`);
|
|
16639
|
+
} else {
|
|
16640
|
+
log.success("Frontend deployed to Vercel");
|
|
16631
16641
|
}
|
|
16632
16642
|
}
|
|
16633
16643
|
|
|
@@ -16989,7 +16999,7 @@ async function deployFunctions(appDir, serviceAccountPath, projectId, config) {
|
|
|
16989
16999
|
|
|
16990
17000
|
To fix this, run:
|
|
16991
17001
|
cd ${functionsDir}
|
|
16992
|
-
|
|
17002
|
+
bun install --production`,
|
|
16993
17003
|
"file-not-found",
|
|
16994
17004
|
{ context: { missingPackages, functionsDir } }
|
|
16995
17005
|
);
|
|
@@ -17354,7 +17364,19 @@ function detectProvider(appDir) {
|
|
|
17354
17364
|
const supabaseFunctionsDir = joinPath(supabaseDir, "functions");
|
|
17355
17365
|
const supabaseMigrationsDir = joinPath(supabaseDir, "migrations");
|
|
17356
17366
|
const hasFirebase = pathExists(firebaseJsonPath);
|
|
17357
|
-
|
|
17367
|
+
let hasSupabase = pathExists(supabaseDir) || pathExists(supabaseConfigPath);
|
|
17368
|
+
if (!hasSupabase) {
|
|
17369
|
+
try {
|
|
17370
|
+
const envPath = joinPath(appDir, ".env");
|
|
17371
|
+
if (pathExists(envPath)) {
|
|
17372
|
+
const envContent = readSync(envPath);
|
|
17373
|
+
if (envContent.match(/VITE_SUPABASE_URL=.+/)) {
|
|
17374
|
+
hasSupabase = true;
|
|
17375
|
+
}
|
|
17376
|
+
}
|
|
17377
|
+
} catch {
|
|
17378
|
+
}
|
|
17379
|
+
}
|
|
17358
17380
|
let provider = "unknown";
|
|
17359
17381
|
if (hasFirebase && hasSupabase) {
|
|
17360
17382
|
provider = "both";
|
|
@@ -17718,7 +17740,7 @@ async function main2(options = {}) {
|
|
|
17718
17740
|
if (shouldDeployVercelFrontend) {
|
|
17719
17741
|
requireCLI(
|
|
17720
17742
|
CLI_TOOLS.VERCEL,
|
|
17721
|
-
"Vercel CLI is required to deploy the frontend.\nInstall:
|
|
17743
|
+
"Vercel CLI is required to deploy the frontend.\nInstall: bun install -g vercel"
|
|
17722
17744
|
);
|
|
17723
17745
|
}
|
|
17724
17746
|
if (shouldDeployFirebaseFrontend && serviceAccountPath && config.project) {
|