@donotdev/cli 0.0.16 → 0.0.18
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 +38 -26
- package/dist/bin/commands/bump.js +9 -2
- package/dist/bin/commands/create-app.js +185 -81
- package/dist/bin/commands/create-project.js +186 -85
- package/dist/bin/commands/deploy.js +51 -20
- package/dist/bin/commands/doctor.js +249 -56
- package/dist/bin/commands/emu.js +18 -20
- package/dist/bin/commands/make-admin.js +30 -10
- package/dist/bin/commands/setup.js +512 -122
- package/dist/bin/commands/type-check.d.ts.map +1 -1
- package/dist/bin/commands/type-check.js +7 -3
- package/dist/bin/commands/type-check.js.map +1 -1
- package/dist/bin/dndev.js +9 -6
- package/dist/bin/donotdev.js +35 -20
- package/dist/index.js +262 -129
- package/package.json +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 +50 -18
- package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +6 -6
- package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
- package/templates/root-consumer/guides/dndev/SETUP_AUTH.md.example +13 -6
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +149 -1086
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +68 -16
- package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +6 -111
- package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +64 -0
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +123 -32
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +108 -91
- package/templates/root-consumer/guides/dndev/advanced/EMULATORS.md.example +2 -2
- package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +1 -1
- package/dist/bin/commands/firebase-setup.d.ts +0 -6
- package/dist/bin/commands/firebase-setup.d.ts.map +0 -1
- package/dist/bin/commands/firebase-setup.js +0 -7
- package/dist/bin/commands/firebase-setup.js.map +0 -1
- package/dist/bin/commands/supabase-setup.d.ts +0 -6
- package/dist/bin/commands/supabase-setup.d.ts.map +0 -1
- package/dist/bin/commands/supabase-setup.js +0 -7
- package/dist/bin/commands/supabase-setup.js.map +0 -1
- 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
package/dist/index.js
CHANGED
|
@@ -8469,7 +8469,14 @@ function readServiceAccountKey(filePath) {
|
|
|
8469
8469
|
throw new DoNotDevError(
|
|
8470
8470
|
`Invalid service account key: missing required fields`,
|
|
8471
8471
|
DO_NOT_DEV_ERROR_CODES.CONFIG_INVALID,
|
|
8472
|
-
{
|
|
8472
|
+
{
|
|
8473
|
+
context: {
|
|
8474
|
+
filePath,
|
|
8475
|
+
missingFields: ["project_id", "private_key", "client_email"].filter(
|
|
8476
|
+
(f) => !key[f]
|
|
8477
|
+
)
|
|
8478
|
+
}
|
|
8479
|
+
}
|
|
8473
8480
|
);
|
|
8474
8481
|
}
|
|
8475
8482
|
return content;
|
|
@@ -8876,9 +8883,7 @@ function getCLIInstallInstructions(tool) {
|
|
|
8876
8883
|
"Or: winget install Supabase.CLI",
|
|
8877
8884
|
"Or download from: https://github.com/supabase/cli/releases"
|
|
8878
8885
|
],
|
|
8879
|
-
darwin: [
|
|
8880
|
-
"brew install supabase/tap/supabase"
|
|
8881
|
-
],
|
|
8886
|
+
darwin: ["brew install supabase/tap/supabase"],
|
|
8882
8887
|
linux: [
|
|
8883
8888
|
"brew install supabase/tap/supabase",
|
|
8884
8889
|
"Or see: https://supabase.com/docs/guides/cli"
|
|
@@ -8886,7 +8891,11 @@ function getCLIInstallInstructions(tool) {
|
|
|
8886
8891
|
},
|
|
8887
8892
|
[CLI_TOOLS.VERCEL]: {
|
|
8888
8893
|
win32: ["npm install -g vercel", "Or: npx vercel (no install)"],
|
|
8889
|
-
darwin: [
|
|
8894
|
+
darwin: [
|
|
8895
|
+
"npm install -g vercel",
|
|
8896
|
+
"Or: brew install vercel",
|
|
8897
|
+
"Or: npx vercel"
|
|
8898
|
+
],
|
|
8890
8899
|
linux: ["npm install -g vercel", "Or: npx vercel"]
|
|
8891
8900
|
},
|
|
8892
8901
|
[CLI_TOOLS.SENTRY_CLI]: {
|
|
@@ -17034,7 +17043,9 @@ async function deploySupabaseFunctions(appDir, config) {
|
|
|
17034
17043
|
const supabaseDir = joinPath(appDir, "supabase");
|
|
17035
17044
|
const functionsDir = joinPath(supabaseDir, "functions");
|
|
17036
17045
|
if (!pathExists(functionsDir)) {
|
|
17037
|
-
log.warn(
|
|
17046
|
+
log.warn(
|
|
17047
|
+
"No supabase/functions/ directory found. Skipping Supabase functions deployment."
|
|
17048
|
+
);
|
|
17038
17049
|
return;
|
|
17039
17050
|
}
|
|
17040
17051
|
requireCLI(
|
|
@@ -17050,10 +17061,14 @@ async function deploySupabaseFunctions(appDir, config) {
|
|
|
17050
17061
|
return pathExists(indexPath);
|
|
17051
17062
|
});
|
|
17052
17063
|
if (functionDirs.length === 0) {
|
|
17053
|
-
log.warn(
|
|
17064
|
+
log.warn(
|
|
17065
|
+
"No Edge Functions found in supabase/functions/. Skipping deployment."
|
|
17066
|
+
);
|
|
17054
17067
|
return;
|
|
17055
17068
|
}
|
|
17056
|
-
log.info(
|
|
17069
|
+
log.info(
|
|
17070
|
+
`Found ${functionDirs.length} Edge Function(s): ${functionDirs.join(", ")}`
|
|
17071
|
+
);
|
|
17057
17072
|
const s = Y2();
|
|
17058
17073
|
for (const functionName of functionDirs) {
|
|
17059
17074
|
s.start(`Deploying Edge Function: ${functionName}...`);
|
|
@@ -17072,7 +17087,12 @@ async function deploySupabaseFunctions(appDir, config) {
|
|
|
17072
17087
|
throw new DoNotDevError(
|
|
17073
17088
|
`Failed to deploy Supabase Edge Function: ${functionName}`,
|
|
17074
17089
|
"deployment-failed",
|
|
17075
|
-
{
|
|
17090
|
+
{
|
|
17091
|
+
context: {
|
|
17092
|
+
functionName,
|
|
17093
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
17094
|
+
}
|
|
17095
|
+
}
|
|
17076
17096
|
);
|
|
17077
17097
|
}
|
|
17078
17098
|
}
|
|
@@ -17892,10 +17912,7 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
|
|
|
17892
17912
|
// packages/tooling/src/apps/emu-supabase.ts
|
|
17893
17913
|
init_utils();
|
|
17894
17914
|
init_cli_output();
|
|
17895
|
-
import {
|
|
17896
|
-
spawn as spawn3,
|
|
17897
|
-
execSync as execSync5
|
|
17898
|
-
} from "node:child_process";
|
|
17915
|
+
import { spawn as spawn3, execSync as execSync5 } from "node:child_process";
|
|
17899
17916
|
import { platform as platform3 } from "node:os";
|
|
17900
17917
|
function isDockerRunning() {
|
|
17901
17918
|
try {
|
|
@@ -17945,7 +17962,10 @@ async function startSupabase(app, _projectRoot) {
|
|
|
17945
17962
|
if (!childProcess.pid) return;
|
|
17946
17963
|
if (isWindows) {
|
|
17947
17964
|
try {
|
|
17948
|
-
execSync5(`taskkill /F /T /PID ${childProcess.pid}`, {
|
|
17965
|
+
execSync5(`taskkill /F /T /PID ${childProcess.pid}`, {
|
|
17966
|
+
stdio: "ignore",
|
|
17967
|
+
timeout: 2e3
|
|
17968
|
+
});
|
|
17949
17969
|
} catch {
|
|
17950
17970
|
}
|
|
17951
17971
|
} else {
|
|
@@ -17975,10 +17995,7 @@ async function startSupabase(app, _projectRoot) {
|
|
|
17975
17995
|
// packages/tooling/src/apps/emu-vercel.ts
|
|
17976
17996
|
init_utils();
|
|
17977
17997
|
init_cli_output();
|
|
17978
|
-
import {
|
|
17979
|
-
spawn as spawn4,
|
|
17980
|
-
execSync as execSync6
|
|
17981
|
-
} from "node:child_process";
|
|
17998
|
+
import { spawn as spawn4, execSync as execSync6 } from "node:child_process";
|
|
17982
17999
|
import { platform as platform4 } from "node:os";
|
|
17983
18000
|
async function startVercel(app, _projectRoot) {
|
|
17984
18001
|
log.info(`Starting Vercel dev server for ${app.name}...
|
|
@@ -17991,20 +18008,19 @@ async function startVercel(app, _projectRoot) {
|
|
|
17991
18008
|
return 1;
|
|
17992
18009
|
}
|
|
17993
18010
|
const isWindows = platform4() === "win32";
|
|
17994
|
-
const childProcess = spawn4(
|
|
17995
|
-
"
|
|
17996
|
-
|
|
17997
|
-
|
|
17998
|
-
|
|
17999
|
-
cwd: app.path,
|
|
18000
|
-
shell: isWindows
|
|
18001
|
-
}
|
|
18002
|
-
);
|
|
18011
|
+
const childProcess = spawn4("vercel", ["dev"], {
|
|
18012
|
+
stdio: "inherit",
|
|
18013
|
+
cwd: app.path,
|
|
18014
|
+
shell: isWindows
|
|
18015
|
+
});
|
|
18003
18016
|
const cleanup = () => {
|
|
18004
18017
|
if (!childProcess.pid) return;
|
|
18005
18018
|
if (isWindows) {
|
|
18006
18019
|
try {
|
|
18007
|
-
execSync6(`taskkill /F /T /PID ${childProcess.pid}`, {
|
|
18020
|
+
execSync6(`taskkill /F /T /PID ${childProcess.pid}`, {
|
|
18021
|
+
stdio: "ignore",
|
|
18022
|
+
timeout: 2e3
|
|
18023
|
+
});
|
|
18008
18024
|
} catch {
|
|
18009
18025
|
}
|
|
18010
18026
|
} else {
|
|
@@ -18051,7 +18067,9 @@ async function main3(options) {
|
|
|
18051
18067
|
switch (app.platform) {
|
|
18052
18068
|
case "firebase": {
|
|
18053
18069
|
if (!app.hasFunctions) {
|
|
18054
|
-
log.error(
|
|
18070
|
+
log.error(
|
|
18071
|
+
`App "${app.name}" has Firebase config but no functions directory.`
|
|
18072
|
+
);
|
|
18055
18073
|
log.error('Use "dndev dev" for apps without backend functions.\n');
|
|
18056
18074
|
return 1;
|
|
18057
18075
|
}
|
|
@@ -18518,7 +18536,11 @@ function getMatrixPath(mode) {
|
|
|
18518
18536
|
const executionMode = mode || detectExecutionMode();
|
|
18519
18537
|
if (executionMode === "development") {
|
|
18520
18538
|
const templatesRoot = getTemplatesRoot();
|
|
18521
|
-
const devPath = normalizePath(
|
|
18539
|
+
const devPath = normalizePath(
|
|
18540
|
+
templatesRoot,
|
|
18541
|
+
"..",
|
|
18542
|
+
"dependencies-matrix.json"
|
|
18543
|
+
);
|
|
18522
18544
|
if (pathExists(devPath)) {
|
|
18523
18545
|
return devPath;
|
|
18524
18546
|
}
|
|
@@ -18595,34 +18617,67 @@ var APP_QUESTIONNAIRE = [
|
|
|
18595
18617
|
]
|
|
18596
18618
|
},
|
|
18597
18619
|
{
|
|
18598
|
-
id: "
|
|
18599
|
-
question: "
|
|
18600
|
-
type: "
|
|
18601
|
-
|
|
18620
|
+
id: "host",
|
|
18621
|
+
question: "Where will you host?",
|
|
18622
|
+
type: "select",
|
|
18623
|
+
condition: (answers) => answers.framework !== "expo",
|
|
18624
|
+
defaultValue: (answers) => {
|
|
18625
|
+
return answers.framework === "nextjs" ? "vercel" : "none";
|
|
18626
|
+
},
|
|
18627
|
+
choices: [
|
|
18628
|
+
{ title: "None \u2014 no hosting config", value: "none" },
|
|
18629
|
+
{ title: "Vercel \u2014 edge CDN + serverless", value: "vercel" },
|
|
18630
|
+
{ title: "Firebase Hosting \u2014 Google CDN", value: "firebase" }
|
|
18631
|
+
]
|
|
18632
|
+
},
|
|
18633
|
+
{
|
|
18634
|
+
id: "functions",
|
|
18635
|
+
question: "Serverless functions?",
|
|
18636
|
+
type: "select",
|
|
18637
|
+
defaultValue: "none",
|
|
18638
|
+
// Choices filtered dynamically based on host
|
|
18639
|
+
choices: [
|
|
18640
|
+
{ title: "None", value: "none" },
|
|
18641
|
+
{ title: "Vercel Functions \u2014 edge + node.js", value: "vercel" },
|
|
18642
|
+
{ title: "Firebase Functions \u2014 Google Cloud", value: "firebase" },
|
|
18643
|
+
{ title: "Supabase Edge Functions \u2014 Deno", value: "supabase" }
|
|
18644
|
+
],
|
|
18645
|
+
choicesFilter: (answers) => {
|
|
18646
|
+
const host = answers.host ?? "none";
|
|
18647
|
+
const framework = answers.framework;
|
|
18648
|
+
if (framework === "expo") return ["none", "firebase", "supabase"];
|
|
18649
|
+
if (host === "firebase") return ["none", "firebase"];
|
|
18650
|
+
if (host === "vercel") return ["none", "vercel", "supabase"];
|
|
18651
|
+
return ["none", "vercel", "firebase", "supabase"];
|
|
18652
|
+
}
|
|
18602
18653
|
},
|
|
18603
18654
|
{
|
|
18604
|
-
id: "
|
|
18605
|
-
question: "
|
|
18655
|
+
id: "backend",
|
|
18656
|
+
question: "Backend / BaaS provider?",
|
|
18606
18657
|
type: "select",
|
|
18607
|
-
dependsOn: "needsBackend",
|
|
18608
|
-
condition: (answers) => answers.needsBackend === true,
|
|
18609
18658
|
defaultValue: (answers) => {
|
|
18610
|
-
|
|
18659
|
+
if (answers.functions === "firebase") return "firebase";
|
|
18660
|
+
if (answers.functions === "supabase") return "supabase";
|
|
18661
|
+
return "none";
|
|
18611
18662
|
},
|
|
18612
18663
|
choices: [
|
|
18664
|
+
{ title: "None \u2014 frontend only", value: "none" },
|
|
18613
18665
|
{
|
|
18614
|
-
title: "Firebase \u2014
|
|
18666
|
+
title: "Firebase \u2014 Auth + Firestore + Storage",
|
|
18615
18667
|
value: "firebase"
|
|
18616
18668
|
},
|
|
18617
|
-
{
|
|
18618
|
-
title: "Vercel \u2014 Serverless functions (edge + node.js)",
|
|
18619
|
-
value: "vercel"
|
|
18620
|
-
},
|
|
18621
18669
|
{
|
|
18622
18670
|
title: "Supabase \u2014 Postgres + Auth + Storage",
|
|
18623
18671
|
value: "supabase"
|
|
18624
18672
|
}
|
|
18625
|
-
]
|
|
18673
|
+
],
|
|
18674
|
+
choicesFilter: (answers) => {
|
|
18675
|
+
const functions = answers.functions ?? "none";
|
|
18676
|
+
if (functions === "firebase") return ["none", "firebase"];
|
|
18677
|
+
if (functions === "supabase") return ["none", "supabase"];
|
|
18678
|
+
if (functions === "vercel") return ["none"];
|
|
18679
|
+
return ["none", "firebase", "supabase"];
|
|
18680
|
+
}
|
|
18626
18681
|
}
|
|
18627
18682
|
];
|
|
18628
18683
|
var PROJECT_QUESTIONNAIRE = [
|
|
@@ -18640,12 +18695,13 @@ var PROJECT_QUESTIONNAIRE = [
|
|
|
18640
18695
|
}
|
|
18641
18696
|
];
|
|
18642
18697
|
function aggregateRequirements(answers) {
|
|
18698
|
+
const hasBackend = answers.backend && answers.backend !== "none" || answers.functions && answers.functions !== "none";
|
|
18643
18699
|
const requirements = {
|
|
18644
18700
|
entities: [],
|
|
18645
18701
|
// Entities created in apps/<app>/entities/ (v1), root entities/ for v2
|
|
18646
18702
|
billing: true,
|
|
18647
18703
|
// Always on (useStripeBillingSafe handles missing package)
|
|
18648
|
-
backend:
|
|
18704
|
+
backend: hasBackend,
|
|
18649
18705
|
features: [],
|
|
18650
18706
|
template: "vite",
|
|
18651
18707
|
// Only Vite for now
|
|
@@ -18669,6 +18725,10 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
|
|
|
18669
18725
|
if (!showWIP) {
|
|
18670
18726
|
choices = choices.filter((choice) => !choice.wip);
|
|
18671
18727
|
}
|
|
18728
|
+
if (question.choicesFilter) {
|
|
18729
|
+
const allowed = question.choicesFilter(answers);
|
|
18730
|
+
choices = choices.filter((c) => allowed.includes(c.value));
|
|
18731
|
+
}
|
|
18672
18732
|
if (choices.length === 0) continue;
|
|
18673
18733
|
answer = await askFor.selection(question.question, choices);
|
|
18674
18734
|
break;
|
|
@@ -18689,7 +18749,12 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
|
|
|
18689
18749
|
async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
|
|
18690
18750
|
const s = Y2();
|
|
18691
18751
|
s.start("Deploying frontend to Firebase Hosting...");
|
|
18692
|
-
const args = buildFirebaseDeployArgs(
|
|
18752
|
+
const args = buildFirebaseDeployArgs(
|
|
18753
|
+
"hosting",
|
|
18754
|
+
projectId,
|
|
18755
|
+
config.debug,
|
|
18756
|
+
config.force ?? true
|
|
18757
|
+
);
|
|
18693
18758
|
const result = executeFirebaseCommand(args, {
|
|
18694
18759
|
cwd: appDir,
|
|
18695
18760
|
serviceAccountPath,
|
|
@@ -18736,7 +18801,9 @@ async function deployVercelFrontend(appDir, _config) {
|
|
|
18736
18801
|
if (result.status !== 0) {
|
|
18737
18802
|
s.stop("Vercel deployment failed");
|
|
18738
18803
|
const errOutput = result.stderr?.trim();
|
|
18739
|
-
throw new Error(
|
|
18804
|
+
throw new Error(
|
|
18805
|
+
errOutput || `Vercel deploy exited with code ${result.status}`
|
|
18806
|
+
);
|
|
18740
18807
|
}
|
|
18741
18808
|
s.stop("Frontend deployed to Vercel");
|
|
18742
18809
|
} catch (err) {
|
|
@@ -19193,7 +19260,12 @@ async function deployRules(appDir, serviceAccountPath, projectId, config, option
|
|
|
19193
19260
|
const targetNames = targets.join(", ");
|
|
19194
19261
|
const s = Y2();
|
|
19195
19262
|
s.start(`Deploying ${targetNames}...`);
|
|
19196
|
-
const args = buildFirebaseDeployArgs(
|
|
19263
|
+
const args = buildFirebaseDeployArgs(
|
|
19264
|
+
targets,
|
|
19265
|
+
projectId,
|
|
19266
|
+
config.debug,
|
|
19267
|
+
config.force ?? true
|
|
19268
|
+
);
|
|
19197
19269
|
const result = executeFirebaseCommand(args, {
|
|
19198
19270
|
cwd: appDir,
|
|
19199
19271
|
serviceAccountPath,
|
|
@@ -19567,13 +19639,17 @@ async function main6(options = {}) {
|
|
|
19567
19639
|
const availableApps = detectAvailableApps();
|
|
19568
19640
|
if (availableApps.length === 0) {
|
|
19569
19641
|
if (providerInfo.hasSupabase && !providerInfo.hasFirebase) {
|
|
19570
|
-
log.info(
|
|
19642
|
+
log.info(
|
|
19643
|
+
"Supabase project detected. Deploying Supabase resources..."
|
|
19644
|
+
);
|
|
19571
19645
|
} else {
|
|
19572
19646
|
log.info("No apps with firebase.json or supabase/ directory found.");
|
|
19573
19647
|
log.info(
|
|
19574
19648
|
"To deploy, ensure your app has a firebase.json or supabase/ configuration."
|
|
19575
19649
|
);
|
|
19576
|
-
log.info(
|
|
19650
|
+
log.info(
|
|
19651
|
+
"Run from a DoNotDev project, or create one with: dndev init"
|
|
19652
|
+
);
|
|
19577
19653
|
return;
|
|
19578
19654
|
}
|
|
19579
19655
|
}
|
|
@@ -19853,12 +19929,7 @@ async function main6(options = {}) {
|
|
|
19853
19929
|
}
|
|
19854
19930
|
}
|
|
19855
19931
|
}
|
|
19856
|
-
await deployFunctions(
|
|
19857
|
-
appDir,
|
|
19858
|
-
serviceAccountPath,
|
|
19859
|
-
config.project,
|
|
19860
|
-
config
|
|
19861
|
-
);
|
|
19932
|
+
await deployFunctions(appDir, serviceAccountPath, config.project, config);
|
|
19862
19933
|
}
|
|
19863
19934
|
if (shouldDeployFirebaseRules && serviceAccountPath && config.project && appProviderInfo.firebaseConfig) {
|
|
19864
19935
|
await deployRules(appDir, serviceAccountPath, config.project, config, {
|
|
@@ -20081,34 +20152,22 @@ init_pathResolver();
|
|
|
20081
20152
|
|
|
20082
20153
|
// packages/tooling/src/scaffolding/scaffold-matrix.ts
|
|
20083
20154
|
init_utils();
|
|
20084
|
-
|
|
20085
|
-
|
|
20086
|
-
|
|
20087
|
-
|
|
20088
|
-
|
|
20089
|
-
{ builder: "nextjs", backend: "none", baseTemplate: "app-next", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
20090
|
-
{ builder: "nextjs", backend: "firebase", baseTemplate: "app-next", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
20091
|
-
{ builder: "nextjs", backend: "supabase", baseTemplate: "app-next", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: "functions-supabase" },
|
|
20092
|
-
{ builder: "nextjs", backend: "vercel", baseTemplate: "app-next", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
20093
|
-
{ builder: "expo", backend: "none", baseTemplate: "app-expo", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
20094
|
-
{ builder: "expo", backend: "firebase", baseTemplate: "app-expo", overlay: "overlay-firebase", deployConfig: null, functionsTemplate: "functions-firebase" },
|
|
20095
|
-
{ builder: "expo", backend: "supabase", baseTemplate: "app-expo", overlay: "overlay-supabase", deployConfig: null, functionsTemplate: "functions-supabase" },
|
|
20096
|
-
{ builder: "demo", backend: "none", baseTemplate: "app-demo", overlay: null, deployConfig: null, functionsTemplate: null }
|
|
20097
|
-
];
|
|
20098
|
-
function comboKey(builder, backend) {
|
|
20099
|
-
return `${builder}-${backend}`;
|
|
20100
|
-
}
|
|
20101
|
-
var ROWS_BY_KEY = /* @__PURE__ */ new Map();
|
|
20102
|
-
for (const row of MATRIX) {
|
|
20103
|
-
ROWS_BY_KEY.set(comboKey(row.builder, row.backend), row);
|
|
20155
|
+
function resolveDeployConfig(host, backend) {
|
|
20156
|
+
if (host === "none") return null;
|
|
20157
|
+
if (host === "firebase") return "firebase";
|
|
20158
|
+
if (backend === "supabase") return "vercel-supabase";
|
|
20159
|
+
return "vercel-vercel";
|
|
20104
20160
|
}
|
|
20105
|
-
function
|
|
20106
|
-
const
|
|
20107
|
-
|
|
20108
|
-
|
|
20109
|
-
|
|
20110
|
-
|
|
20111
|
-
|
|
20161
|
+
function getScaffoldParts(builder, host, functions, backend) {
|
|
20162
|
+
const baseTemplate = builder === "nextjs" ? "app-next" : builder === "demo" ? "app-demo" : `app-${builder}`;
|
|
20163
|
+
return {
|
|
20164
|
+
builder,
|
|
20165
|
+
backend,
|
|
20166
|
+
baseTemplate,
|
|
20167
|
+
overlay: backend !== "none" ? `overlay-${backend}` : null,
|
|
20168
|
+
deployConfig: resolveDeployConfig(host, backend),
|
|
20169
|
+
functionsTemplate: functions !== "none" ? `functions-${functions}` : null
|
|
20170
|
+
};
|
|
20112
20171
|
}
|
|
20113
20172
|
|
|
20114
20173
|
// packages/tooling/src/scaffolding/create-app.ts
|
|
@@ -20148,11 +20207,15 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20148
20207
|
input: askForInput
|
|
20149
20208
|
});
|
|
20150
20209
|
const requirements = aggregateRequirements(answers);
|
|
20151
|
-
const
|
|
20210
|
+
const framework = answers.framework || "vite";
|
|
20211
|
+
const host2 = answers.host || "none";
|
|
20212
|
+
const functions2 = answers.functions || "none";
|
|
20213
|
+
const backend2 = answers.backend || "none";
|
|
20152
20214
|
appConfig = {
|
|
20153
|
-
template:
|
|
20154
|
-
|
|
20155
|
-
|
|
20215
|
+
template: framework,
|
|
20216
|
+
host: host2,
|
|
20217
|
+
functions: functions2,
|
|
20218
|
+
backend: backend2,
|
|
20156
20219
|
needsCRUD: true,
|
|
20157
20220
|
// Always on
|
|
20158
20221
|
selectedEntities: [],
|
|
@@ -20198,12 +20261,14 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20198
20261
|
s.start(`Creating app: ${appName}`);
|
|
20199
20262
|
await ensureDir(appDir);
|
|
20200
20263
|
const builder = appTemplate;
|
|
20201
|
-
const
|
|
20202
|
-
const
|
|
20264
|
+
const host = appConfig.host ?? "none";
|
|
20265
|
+
const functions = appConfig.functions ?? "none";
|
|
20266
|
+
const backend = appConfig.backend ?? "none";
|
|
20267
|
+
const row = getScaffoldParts(builder, host, functions, backend);
|
|
20203
20268
|
const templateDir = row.baseTemplate;
|
|
20204
20269
|
const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
|
|
20205
20270
|
const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
|
|
20206
|
-
const backendPlatform =
|
|
20271
|
+
const backendPlatform = backend !== "none" ? backend : "firebase";
|
|
20207
20272
|
const deployConfig = row.deployConfig;
|
|
20208
20273
|
const replacements = {
|
|
20209
20274
|
projectName: appName,
|
|
@@ -20262,13 +20327,16 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20262
20327
|
const variantFile = `src/config/providers.${appTemplate}.ts.example`;
|
|
20263
20328
|
if (overlayFiles.includes(variantFile)) continue;
|
|
20264
20329
|
}
|
|
20265
|
-
const providersVariant = file.match(
|
|
20330
|
+
const providersVariant = file.match(
|
|
20331
|
+
/^src\/config\/providers\.(\w+)\.ts\.example$/
|
|
20332
|
+
);
|
|
20266
20333
|
if (providersVariant) {
|
|
20267
20334
|
if (providersVariant[1] !== appTemplate) continue;
|
|
20268
20335
|
const destPath2 = joinPath(appDir, "src/config/providers.ts");
|
|
20269
20336
|
await ensureDir(getDirname(destPath2));
|
|
20270
20337
|
await copy(joinPath(overlayDir, file), destPath2, { overwrite: true });
|
|
20271
|
-
if (await isTextFile(destPath2))
|
|
20338
|
+
if (await isTextFile(destPath2))
|
|
20339
|
+
await replacePlaceholders(destPath2, replacements);
|
|
20272
20340
|
continue;
|
|
20273
20341
|
}
|
|
20274
20342
|
const sourcePath = joinPath(overlayDir, file);
|
|
@@ -20293,16 +20361,28 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20293
20361
|
}
|
|
20294
20362
|
if (deployConfig === "vercel-supabase") {
|
|
20295
20363
|
const vercelPath = joinPath(appDir, "vercel.json");
|
|
20296
|
-
const headersFragmentPath = joinPath(
|
|
20364
|
+
const headersFragmentPath = joinPath(
|
|
20365
|
+
overlayDir,
|
|
20366
|
+
"vercel.headers.example"
|
|
20367
|
+
);
|
|
20297
20368
|
const fullVercelPath = joinPath(overlayDir, "vercel.json.example");
|
|
20298
20369
|
if (pathExists(vercelPath) && pathExists(headersFragmentPath)) {
|
|
20299
20370
|
const vercelJson = readSync(vercelPath, { format: "json" });
|
|
20300
|
-
const headersFragment = readSync(headersFragmentPath, {
|
|
20301
|
-
|
|
20302
|
-
|
|
20371
|
+
const headersFragment = readSync(headersFragmentPath, {
|
|
20372
|
+
format: "json"
|
|
20373
|
+
});
|
|
20374
|
+
vercelJson.headers = [
|
|
20375
|
+
...vercelJson.headers ?? [],
|
|
20376
|
+
...headersFragment
|
|
20377
|
+
];
|
|
20378
|
+
await write(vercelPath, vercelJson, {
|
|
20379
|
+
format: "json",
|
|
20380
|
+
overwrite: true
|
|
20381
|
+
});
|
|
20303
20382
|
} else if (pathExists(fullVercelPath)) {
|
|
20304
20383
|
await copy(fullVercelPath, vercelPath);
|
|
20305
|
-
if (await isTextFile(vercelPath))
|
|
20384
|
+
if (await isTextFile(vercelPath))
|
|
20385
|
+
await replacePlaceholders(vercelPath, replacements);
|
|
20306
20386
|
}
|
|
20307
20387
|
}
|
|
20308
20388
|
}
|
|
@@ -20322,9 +20402,13 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20322
20402
|
});
|
|
20323
20403
|
if (row.functionsTemplate) {
|
|
20324
20404
|
const functionsTemplateName = row.functionsTemplate;
|
|
20325
|
-
const functionsTemplateExists = pathExists(
|
|
20405
|
+
const functionsTemplateExists = pathExists(
|
|
20406
|
+
joinPath(templatesRoot, functionsTemplateName)
|
|
20407
|
+
);
|
|
20326
20408
|
if (!functionsTemplateExists) {
|
|
20327
|
-
log.warn(
|
|
20409
|
+
log.warn(
|
|
20410
|
+
`Functions template "${functionsTemplateName}" not found \u2014 skipping functions scaffolding.`
|
|
20411
|
+
);
|
|
20328
20412
|
} else {
|
|
20329
20413
|
const isSupabaseFunctions = functionsTemplateName === "functions-supabase";
|
|
20330
20414
|
const functionsRootDir = isSupabaseFunctions ? appDir : joinPath(appDir, "functions");
|
|
@@ -20332,7 +20416,10 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20332
20416
|
const functionsPackageJson = generatePackageJson(
|
|
20333
20417
|
functionsTemplateName,
|
|
20334
20418
|
executionMode,
|
|
20335
|
-
{
|
|
20419
|
+
{
|
|
20420
|
+
appName,
|
|
20421
|
+
platform: row.functionsTemplate.replace("functions-", "")
|
|
20422
|
+
}
|
|
20336
20423
|
);
|
|
20337
20424
|
const packageJsonPath2 = joinPath(functionsRootDir, "package.json");
|
|
20338
20425
|
await ensureDir(functionsRootDir);
|
|
@@ -20368,13 +20455,19 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20368
20455
|
}
|
|
20369
20456
|
const deploymentTemplateDir = joinPath(templatesRoot, "root-consumer");
|
|
20370
20457
|
if (deployConfig === "firebase") {
|
|
20371
|
-
const firebaseJsonSource = joinPath(
|
|
20458
|
+
const firebaseJsonSource = joinPath(
|
|
20459
|
+
deploymentTemplateDir,
|
|
20460
|
+
"firebase.json.example"
|
|
20461
|
+
);
|
|
20372
20462
|
if (pathExists(firebaseJsonSource)) {
|
|
20373
20463
|
await copy(firebaseJsonSource, joinPath(appDir, "firebase.json"));
|
|
20374
20464
|
const firebaseJsonDest = joinPath(appDir, "firebase.json");
|
|
20375
|
-
if (await isTextFile(firebaseJsonDest))
|
|
20465
|
+
if (await isTextFile(firebaseJsonDest))
|
|
20466
|
+
await replacePlaceholders(firebaseJsonDest, replacements);
|
|
20376
20467
|
if (appTemplate === "nextjs") {
|
|
20377
|
-
const firebaseJson = readSync(firebaseJsonDest, {
|
|
20468
|
+
const firebaseJson = readSync(firebaseJsonDest, {
|
|
20469
|
+
format: "json"
|
|
20470
|
+
});
|
|
20378
20471
|
if (firebaseJson.hosting?.rewrites) {
|
|
20379
20472
|
firebaseJson.hosting.rewrites = firebaseJson.hosting.rewrites.filter(
|
|
20380
20473
|
(r2) => r2.destination !== "/index.html"
|
|
@@ -20383,17 +20476,28 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20383
20476
|
if (firebaseJson.hosting) {
|
|
20384
20477
|
firebaseJson.hosting.public = "out";
|
|
20385
20478
|
}
|
|
20386
|
-
await write(firebaseJsonDest, firebaseJson, {
|
|
20479
|
+
await write(firebaseJsonDest, firebaseJson, {
|
|
20480
|
+
format: "json",
|
|
20481
|
+
overwrite: true
|
|
20482
|
+
});
|
|
20387
20483
|
}
|
|
20388
20484
|
}
|
|
20389
|
-
const firebasercSource = joinPath(
|
|
20485
|
+
const firebasercSource = joinPath(
|
|
20486
|
+
deploymentTemplateDir,
|
|
20487
|
+
".firebaserc.example"
|
|
20488
|
+
);
|
|
20390
20489
|
if (pathExists(firebasercSource)) {
|
|
20391
20490
|
await copy(firebasercSource, joinPath(appDir, ".firebaserc"));
|
|
20392
20491
|
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
20393
|
-
if (await isTextFile(firebasercDest))
|
|
20492
|
+
if (await isTextFile(firebasercDest))
|
|
20493
|
+
await replacePlaceholders(firebasercDest, replacements);
|
|
20394
20494
|
}
|
|
20395
20495
|
if (row.functionsTemplate === "functions-firebase") {
|
|
20396
|
-
for (const example of [
|
|
20496
|
+
for (const example of [
|
|
20497
|
+
"firestore.rules.example",
|
|
20498
|
+
"firestore.indexes.json.example",
|
|
20499
|
+
"storage.rules.example"
|
|
20500
|
+
]) {
|
|
20397
20501
|
const src = joinPath(deploymentTemplateDir, example);
|
|
20398
20502
|
if (pathExists(src)) {
|
|
20399
20503
|
await copy(src, joinPath(appDir, example.replace(".example", "")));
|
|
@@ -20409,11 +20513,22 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20409
20513
|
{
|
|
20410
20514
|
source: "functions",
|
|
20411
20515
|
codebase: "default",
|
|
20412
|
-
ignore: [
|
|
20516
|
+
ignore: [
|
|
20517
|
+
"node_modules",
|
|
20518
|
+
".git",
|
|
20519
|
+
"firebase-debug.log",
|
|
20520
|
+
"firebase-debug.*.log",
|
|
20521
|
+
"**/.*",
|
|
20522
|
+
"**/*.test.ts",
|
|
20523
|
+
"**/__tests__/**"
|
|
20524
|
+
],
|
|
20413
20525
|
runtime: "nodejs22"
|
|
20414
20526
|
}
|
|
20415
20527
|
],
|
|
20416
|
-
firestore: {
|
|
20528
|
+
firestore: {
|
|
20529
|
+
rules: "firestore.rules",
|
|
20530
|
+
indexes: "firestore.indexes.json"
|
|
20531
|
+
},
|
|
20417
20532
|
storage: { rules: "storage.rules" },
|
|
20418
20533
|
emulators: {
|
|
20419
20534
|
auth: { port: 9099 },
|
|
@@ -20423,15 +20538,26 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20423
20538
|
ui: { enabled: true, port: 4e3 }
|
|
20424
20539
|
}
|
|
20425
20540
|
};
|
|
20426
|
-
await write(firebaseJsonPath, expoFirebaseJson, {
|
|
20541
|
+
await write(firebaseJsonPath, expoFirebaseJson, {
|
|
20542
|
+
format: "json",
|
|
20543
|
+
overwrite: true
|
|
20544
|
+
});
|
|
20427
20545
|
}
|
|
20428
|
-
const firebasercSource = joinPath(
|
|
20546
|
+
const firebasercSource = joinPath(
|
|
20547
|
+
deploymentTemplateDir,
|
|
20548
|
+
".firebaserc.example"
|
|
20549
|
+
);
|
|
20429
20550
|
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
20430
20551
|
if (pathExists(firebasercSource) && !pathExists(firebasercDest)) {
|
|
20431
20552
|
await copy(firebasercSource, firebasercDest);
|
|
20432
|
-
if (await isTextFile(firebasercDest))
|
|
20433
|
-
|
|
20434
|
-
|
|
20553
|
+
if (await isTextFile(firebasercDest))
|
|
20554
|
+
await replacePlaceholders(firebasercDest, replacements);
|
|
20555
|
+
}
|
|
20556
|
+
for (const example of [
|
|
20557
|
+
"firestore.rules.example",
|
|
20558
|
+
"firestore.indexes.json.example",
|
|
20559
|
+
"storage.rules.example"
|
|
20560
|
+
]) {
|
|
20435
20561
|
const src = joinPath(deploymentTemplateDir, example);
|
|
20436
20562
|
const dest = joinPath(appDir, example.replace(".example", ""));
|
|
20437
20563
|
if (pathExists(src) && !pathExists(dest)) {
|
|
@@ -20440,11 +20566,15 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
20440
20566
|
}
|
|
20441
20567
|
}
|
|
20442
20568
|
if (deployConfig === "vercel-vercel") {
|
|
20443
|
-
const vercelJsonSource = joinPath(
|
|
20569
|
+
const vercelJsonSource = joinPath(
|
|
20570
|
+
deploymentTemplateDir,
|
|
20571
|
+
"vercel.json.example"
|
|
20572
|
+
);
|
|
20444
20573
|
if (pathExists(vercelJsonSource)) {
|
|
20445
20574
|
await copy(vercelJsonSource, joinPath(appDir, "vercel.json"));
|
|
20446
20575
|
const vercelJsonDest = joinPath(appDir, "vercel.json");
|
|
20447
|
-
if (await isTextFile(vercelJsonDest))
|
|
20576
|
+
if (await isTextFile(vercelJsonDest))
|
|
20577
|
+
await replacePlaceholders(vercelJsonDest, replacements);
|
|
20448
20578
|
}
|
|
20449
20579
|
}
|
|
20450
20580
|
const backendInfo = row.functionsTemplate ? ` with ${row.functionsTemplate.replace("functions-", "")} functions` : "";
|
|
@@ -20476,11 +20606,13 @@ Happy coding!`,
|
|
|
20476
20606
|
}
|
|
20477
20607
|
async function main8(options) {
|
|
20478
20608
|
try {
|
|
20479
|
-
const hasExplicitFlags = options?.builder !== void 0 || options?.functions !== void 0;
|
|
20609
|
+
const hasExplicitFlags = options?.builder !== void 0 || options?.host !== void 0 || options?.functions !== void 0 || options?.backend !== void 0;
|
|
20480
20610
|
if (hasExplicitFlags && options?.name) {
|
|
20481
20611
|
const appName = options.name;
|
|
20482
20612
|
const builder = options.builder || "vite";
|
|
20483
|
-
const
|
|
20613
|
+
const hostOpt = options.host ?? "none";
|
|
20614
|
+
const functionsOpt = options.functions ?? "none";
|
|
20615
|
+
const backendOpt = options.backend ?? "none";
|
|
20484
20616
|
if (!isValidFileName(appName)) {
|
|
20485
20617
|
throw new Error(
|
|
20486
20618
|
`Invalid app name "${appName}". Use only letters, numbers, dashes (-), and underscores (_).`
|
|
@@ -20493,8 +20625,9 @@ async function main8(options) {
|
|
|
20493
20625
|
}
|
|
20494
20626
|
const appConfig = {
|
|
20495
20627
|
template: builder === "next" ? "nextjs" : builder === "expo" ? "expo" : "vite",
|
|
20496
|
-
|
|
20497
|
-
|
|
20628
|
+
host: hostOpt,
|
|
20629
|
+
functions: functionsOpt,
|
|
20630
|
+
backend: backendOpt,
|
|
20498
20631
|
needsCRUD: true,
|
|
20499
20632
|
selectedEntities: [],
|
|
20500
20633
|
userAuth: "social",
|
|
@@ -20526,12 +20659,11 @@ async function collectAppConfig(appName) {
|
|
|
20526
20659
|
input: askForInput
|
|
20527
20660
|
});
|
|
20528
20661
|
const framework = answers.framework || "vite";
|
|
20529
|
-
const needsBackend = answers.needsBackend || false;
|
|
20530
|
-
const defaultPlatform = framework === "nextjs" ? "vercel" : "firebase";
|
|
20531
20662
|
return {
|
|
20532
20663
|
template: framework,
|
|
20533
|
-
|
|
20534
|
-
|
|
20664
|
+
host: answers.host || "none",
|
|
20665
|
+
functions: answers.functions || "none",
|
|
20666
|
+
backend: answers.backend || "none",
|
|
20535
20667
|
needsCRUD: false,
|
|
20536
20668
|
selectedEntities: [],
|
|
20537
20669
|
userAuth: "none",
|
|
@@ -20678,7 +20810,7 @@ async function main9(options) {
|
|
|
20678
20810
|
Me(`Configuring "${trimmedName}"...`, "\u2699\uFE0F");
|
|
20679
20811
|
const config = await collectAppConfig(trimmedName);
|
|
20680
20812
|
appConfigs[trimmedName] = config;
|
|
20681
|
-
if (config.
|
|
20813
|
+
if (config.backend !== "none" || config.functions !== "none") anyAppNeedsBackend = true;
|
|
20682
20814
|
}
|
|
20683
20815
|
let installDemoApp = await askForConfirmation(
|
|
20684
20816
|
"Would you like to install the demo app? (component showcase)",
|
|
@@ -20754,8 +20886,9 @@ async function main9(options) {
|
|
|
20754
20886
|
log.warn(`Missing config for app "${appName}", using defaults`);
|
|
20755
20887
|
appConfigs[appName] = {
|
|
20756
20888
|
template: "vite",
|
|
20757
|
-
|
|
20758
|
-
|
|
20889
|
+
host: "none",
|
|
20890
|
+
functions: "none",
|
|
20891
|
+
backend: "none",
|
|
20759
20892
|
needsCRUD: false,
|
|
20760
20893
|
selectedEntities: [],
|
|
20761
20894
|
userAuth: "none",
|
|
@@ -20803,7 +20936,7 @@ async function main9(options) {
|
|
|
20803
20936
|
overwrite: true
|
|
20804
20937
|
});
|
|
20805
20938
|
const relativeMonorepoPath = executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "";
|
|
20806
|
-
const primaryPlatform = Object.values(appConfigs).find((c) => c.
|
|
20939
|
+
const primaryPlatform = Object.values(appConfigs).find((c) => c.backend !== "none")?.backend ?? "firebase";
|
|
20807
20940
|
const rootPackageJson = generatePackageJson(
|
|
20808
20941
|
"consumer-root",
|
|
20809
20942
|
executionMode,
|