@donotdev/cli 0.0.15 → 0.0.16
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 +36 -20
- package/dist/bin/commands/build.js +69 -52
- package/dist/bin/commands/bump.js +7 -13
- package/dist/bin/commands/create-app.js +77 -29
- package/dist/bin/commands/create-project.js +109 -135
- package/dist/bin/commands/deploy.js +97 -45
- package/dist/bin/commands/dev.js +43 -24
- package/dist/bin/commands/doctor.d.ts +6 -0
- package/dist/bin/commands/doctor.d.ts.map +1 -0
- package/dist/bin/commands/{lint.js → doctor.js} +1178 -147
- package/dist/bin/commands/doctor.js.map +1 -0
- package/dist/bin/commands/emu.js +297 -107
- package/dist/bin/commands/make-admin.js +77499 -11
- package/dist/bin/commands/preview.js +44 -25
- package/dist/bin/commands/setup.d.ts +6 -0
- package/dist/bin/commands/setup.d.ts.map +1 -0
- package/dist/bin/commands/setup.js +11733 -0
- package/dist/bin/commands/setup.js.map +1 -0
- package/dist/bin/commands/type-check.js +2018 -283
- package/dist/bin/dndev.js +54 -58
- package/dist/bin/donotdev.js +28 -44
- package/dist/index.js +633 -416
- package/package.json +2 -2
- package/templates/app-expo/.env.example +2 -22
- package/templates/app-expo/README.md.example +1 -1
- package/templates/app-expo/assets/adaptive-icon.png +0 -0
- package/templates/app-expo/assets/favicon.png +0 -0
- package/templates/app-expo/assets/icon.png +0 -0
- package/templates/app-expo/assets/splash.png +0 -0
- package/templates/app-expo/src/config/app.ts.example +46 -0
- package/templates/app-expo/src/config/providers.ts.example +7 -0
- package/templates/app-next/src/config/providers.ts.example +7 -0
- package/templates/app-vite/src/config/providers.ts.example +7 -0
- package/templates/app-vite/src/pages/HomePage.tsx.example +1 -1
- package/templates/functions-firebase/README.md.example +1 -1
- package/templates/functions-firebase/functions-firebase/.env.example.example +1 -1
- package/templates/functions-firebase/functions-firebase/README.md.example +1 -1
- package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
- package/templates/functions-firebase/functions.config.js.example +1 -1
- package/templates/functions-supabase/supabase/config.toml.example +59 -0
- package/templates/functions-supabase/supabase/functions/.env.example +13 -0
- package/templates/functions-supabase/supabase/functions/deno.json.example +8 -0
- 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 +8 -3
- package/templates/overlay-supabase/env.fragment.expo.example +8 -3
- package/templates/overlay-supabase/env.fragment.nextjs.example +8 -3
- package/templates/overlay-vercel/env.fragment.example +1 -1
- package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
- package/templates/root-consumer/AI.md.example +15 -0
- package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +2 -2
- 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_APP_CONFIG.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +98 -0
- package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +4 -4
- package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +60 -0
- package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +62 -0
- package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +3 -3
- package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +2 -2
- package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +7 -8
- package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +9 -5
- package/dist/bin/commands/lint.d.ts +0 -11
- package/dist/bin/commands/lint.d.ts.map +0 -1
- package/dist/bin/commands/lint.js.map +0 -1
- package/dist/bin/commands/staging.d.ts +0 -11
- package/dist/bin/commands/staging.d.ts.map +0 -1
- package/dist/bin/commands/staging.js +0 -12
- package/dist/bin/commands/staging.js.map +0 -1
|
@@ -8713,15 +8713,10 @@ function getMatrixPath(mode) {
|
|
|
8713
8713
|
}
|
|
8714
8714
|
const executionMode = mode || detectExecutionMode();
|
|
8715
8715
|
if (executionMode === "development") {
|
|
8716
|
-
const
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
"packages/cli/dependencies-matrix.json"
|
|
8721
|
-
);
|
|
8722
|
-
if (pathExists(devPath)) {
|
|
8723
|
-
return devPath;
|
|
8724
|
-
}
|
|
8716
|
+
const templatesRoot = getTemplatesRoot();
|
|
8717
|
+
const devPath = normalizePath(templatesRoot, "..", "dependencies-matrix.json");
|
|
8718
|
+
if (pathExists(devPath)) {
|
|
8719
|
+
return devPath;
|
|
8725
8720
|
}
|
|
8726
8721
|
}
|
|
8727
8722
|
return null;
|
|
@@ -8736,8 +8731,8 @@ function getCliVersion(mode) {
|
|
|
8736
8731
|
}
|
|
8737
8732
|
const executionMode = mode || detectExecutionMode();
|
|
8738
8733
|
if (executionMode === "development") {
|
|
8739
|
-
const
|
|
8740
|
-
const cliPackageJson =
|
|
8734
|
+
const templatesRoot = getTemplatesRoot();
|
|
8735
|
+
const cliPackageJson = normalizePath(templatesRoot, "..", "package.json");
|
|
8741
8736
|
if (pathExists(cliPackageJson)) {
|
|
8742
8737
|
const pkg = readSync(cliPackageJson, { format: "json" });
|
|
8743
8738
|
return String(pkg?.version || "0.0.0");
|
|
@@ -9026,7 +9021,7 @@ function generatePackageJson(templateName, mode, options = {}) {
|
|
|
9026
9021
|
}
|
|
9027
9022
|
if (templateName.includes("functions")) {
|
|
9028
9023
|
result.main = "lib/index.js";
|
|
9029
|
-
result.engines = { node: "
|
|
9024
|
+
result.engines = { node: "22" };
|
|
9030
9025
|
if (options.appName) {
|
|
9031
9026
|
const platform = templateName.includes("vercel") ? "Vercel" : "Firebase";
|
|
9032
9027
|
result.description = `${options.appName} ${platform} Functions`;
|
|
@@ -9073,15 +9068,15 @@ init_utils();
|
|
|
9073
9068
|
var MATRIX = [
|
|
9074
9069
|
{ builder: "vite", backend: "none", baseTemplate: "app-vite", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
9075
9070
|
{ builder: "vite", backend: "firebase", baseTemplate: "app-vite", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
9076
|
-
{ builder: "vite", backend: "supabase", baseTemplate: "app-vite", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate:
|
|
9071
|
+
{ builder: "vite", backend: "supabase", baseTemplate: "app-vite", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: "functions-supabase" },
|
|
9077
9072
|
{ builder: "vite", backend: "vercel", baseTemplate: "app-vite", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
9078
9073
|
{ builder: "nextjs", backend: "none", baseTemplate: "app-next", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
9079
9074
|
{ builder: "nextjs", backend: "firebase", baseTemplate: "app-next", overlay: "overlay-firebase", deployConfig: "firebase", functionsTemplate: "functions-firebase" },
|
|
9080
|
-
{ builder: "nextjs", backend: "supabase", baseTemplate: "app-next", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate:
|
|
9075
|
+
{ builder: "nextjs", backend: "supabase", baseTemplate: "app-next", overlay: "overlay-supabase", deployConfig: "vercel-supabase", functionsTemplate: "functions-supabase" },
|
|
9081
9076
|
{ builder: "nextjs", backend: "vercel", baseTemplate: "app-next", overlay: "overlay-vercel", deployConfig: "vercel-vercel", functionsTemplate: "functions-vercel" },
|
|
9082
9077
|
{ builder: "expo", backend: "none", baseTemplate: "app-expo", overlay: null, deployConfig: null, functionsTemplate: null },
|
|
9083
9078
|
{ builder: "expo", backend: "firebase", baseTemplate: "app-expo", overlay: "overlay-firebase", deployConfig: null, functionsTemplate: "functions-firebase" },
|
|
9084
|
-
{ builder: "expo", backend: "supabase", baseTemplate: "app-expo", overlay: "overlay-supabase", deployConfig: null, functionsTemplate:
|
|
9079
|
+
{ builder: "expo", backend: "supabase", baseTemplate: "app-expo", overlay: "overlay-supabase", deployConfig: null, functionsTemplate: "functions-supabase" },
|
|
9085
9080
|
{ builder: "demo", backend: "none", baseTemplate: "app-demo", overlay: null, deployConfig: null, functionsTemplate: null }
|
|
9086
9081
|
];
|
|
9087
9082
|
function comboKey(builder, backend) {
|
|
@@ -9256,7 +9251,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9256
9251
|
if (providersVariant[1] !== appTemplate) continue;
|
|
9257
9252
|
const destPath2 = joinPath(appDir, "src/config/providers.ts");
|
|
9258
9253
|
await ensureDir(getDirname(destPath2));
|
|
9259
|
-
await copy(joinPath(overlayDir, file), destPath2);
|
|
9254
|
+
await copy(joinPath(overlayDir, file), destPath2, { overwrite: true });
|
|
9260
9255
|
if (await isTextFile(destPath2)) await replacePlaceholders(destPath2, replacements);
|
|
9261
9256
|
continue;
|
|
9262
9257
|
}
|
|
@@ -9267,7 +9262,7 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9267
9262
|
}
|
|
9268
9263
|
const destPath = joinPath(appDir, destFileName);
|
|
9269
9264
|
await ensureDir(getDirname(destPath));
|
|
9270
|
-
await copy(sourcePath, destPath);
|
|
9265
|
+
await copy(sourcePath, destPath, { overwrite: true });
|
|
9271
9266
|
if (await isTextFile(destPath)) {
|
|
9272
9267
|
await replacePlaceholders(destPath, replacements);
|
|
9273
9268
|
}
|
|
@@ -9310,23 +9305,26 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9310
9305
|
overwrite: true
|
|
9311
9306
|
});
|
|
9312
9307
|
if (row.functionsTemplate) {
|
|
9313
|
-
const functionsRootDir = joinPath(appDir, "functions");
|
|
9314
9308
|
const functionsTemplateName = row.functionsTemplate;
|
|
9315
9309
|
const functionsTemplateExists = pathExists(joinPath(templatesRoot, functionsTemplateName));
|
|
9316
9310
|
if (!functionsTemplateExists) {
|
|
9317
9311
|
log.warn(`Functions template "${functionsTemplateName}" not found \u2014 skipping functions scaffolding.`);
|
|
9318
9312
|
} else {
|
|
9319
|
-
const
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9313
|
+
const isSupabaseFunctions = functionsTemplateName === "functions-supabase";
|
|
9314
|
+
const functionsRootDir = isSupabaseFunctions ? appDir : joinPath(appDir, "functions");
|
|
9315
|
+
if (!isSupabaseFunctions) {
|
|
9316
|
+
const functionsPackageJson = generatePackageJson(
|
|
9317
|
+
functionsTemplateName,
|
|
9318
|
+
executionMode,
|
|
9319
|
+
{ appName, platform: row.functionsTemplate.replace("functions-", "") }
|
|
9320
|
+
);
|
|
9321
|
+
const packageJsonPath2 = joinPath(functionsRootDir, "package.json");
|
|
9322
|
+
await ensureDir(functionsRootDir);
|
|
9323
|
+
await write(packageJsonPath2, functionsPackageJson, {
|
|
9324
|
+
format: "json",
|
|
9325
|
+
overwrite: true
|
|
9326
|
+
});
|
|
9327
|
+
}
|
|
9330
9328
|
const templateDir2 = joinPath(templatesRoot, functionsTemplateName);
|
|
9331
9329
|
const templateFiles2 = await glob("**/*", {
|
|
9332
9330
|
cwd: templateDir2,
|
|
@@ -9359,6 +9357,18 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9359
9357
|
await copy(firebaseJsonSource, joinPath(appDir, "firebase.json"));
|
|
9360
9358
|
const firebaseJsonDest = joinPath(appDir, "firebase.json");
|
|
9361
9359
|
if (await isTextFile(firebaseJsonDest)) await replacePlaceholders(firebaseJsonDest, replacements);
|
|
9360
|
+
if (appTemplate === "nextjs") {
|
|
9361
|
+
const firebaseJson = readSync(firebaseJsonDest, { format: "json" });
|
|
9362
|
+
if (firebaseJson.hosting?.rewrites) {
|
|
9363
|
+
firebaseJson.hosting.rewrites = firebaseJson.hosting.rewrites.filter(
|
|
9364
|
+
(r2) => r2.destination !== "/index.html"
|
|
9365
|
+
);
|
|
9366
|
+
}
|
|
9367
|
+
if (firebaseJson.hosting) {
|
|
9368
|
+
firebaseJson.hosting.public = "out";
|
|
9369
|
+
}
|
|
9370
|
+
await write(firebaseJsonDest, firebaseJson, { format: "json", overwrite: true });
|
|
9371
|
+
}
|
|
9362
9372
|
}
|
|
9363
9373
|
const firebasercSource = joinPath(deploymentTemplateDir, ".firebaserc.example");
|
|
9364
9374
|
if (pathExists(firebasercSource)) {
|
|
@@ -9375,6 +9385,44 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
|
|
|
9375
9385
|
}
|
|
9376
9386
|
}
|
|
9377
9387
|
}
|
|
9388
|
+
if (!deployConfig && backend === "firebase" && row.functionsTemplate) {
|
|
9389
|
+
const firebaseJsonPath = joinPath(appDir, "firebase.json");
|
|
9390
|
+
if (!pathExists(firebaseJsonPath)) {
|
|
9391
|
+
const expoFirebaseJson = {
|
|
9392
|
+
functions: [
|
|
9393
|
+
{
|
|
9394
|
+
source: "functions",
|
|
9395
|
+
codebase: "default",
|
|
9396
|
+
ignore: ["node_modules", ".git", "firebase-debug.log", "firebase-debug.*.log", "**/.*", "**/*.test.ts", "**/__tests__/**"],
|
|
9397
|
+
runtime: "nodejs22"
|
|
9398
|
+
}
|
|
9399
|
+
],
|
|
9400
|
+
firestore: { rules: "firestore.rules", indexes: "firestore.indexes.json" },
|
|
9401
|
+
storage: { rules: "storage.rules" },
|
|
9402
|
+
emulators: {
|
|
9403
|
+
auth: { port: 9099 },
|
|
9404
|
+
functions: { port: 5001 },
|
|
9405
|
+
firestore: { port: 8080 },
|
|
9406
|
+
storage: { port: 9199 },
|
|
9407
|
+
ui: { enabled: true, port: 4e3 }
|
|
9408
|
+
}
|
|
9409
|
+
};
|
|
9410
|
+
await write(firebaseJsonPath, expoFirebaseJson, { format: "json", overwrite: true });
|
|
9411
|
+
}
|
|
9412
|
+
const firebasercSource = joinPath(deploymentTemplateDir, ".firebaserc.example");
|
|
9413
|
+
const firebasercDest = joinPath(appDir, ".firebaserc");
|
|
9414
|
+
if (pathExists(firebasercSource) && !pathExists(firebasercDest)) {
|
|
9415
|
+
await copy(firebasercSource, firebasercDest);
|
|
9416
|
+
if (await isTextFile(firebasercDest)) await replacePlaceholders(firebasercDest, replacements);
|
|
9417
|
+
}
|
|
9418
|
+
for (const example of ["firestore.rules.example", "firestore.indexes.json.example", "storage.rules.example"]) {
|
|
9419
|
+
const src = joinPath(deploymentTemplateDir, example);
|
|
9420
|
+
const dest = joinPath(appDir, example.replace(".example", ""));
|
|
9421
|
+
if (pathExists(src) && !pathExists(dest)) {
|
|
9422
|
+
await copy(src, dest);
|
|
9423
|
+
}
|
|
9424
|
+
}
|
|
9425
|
+
}
|
|
9378
9426
|
if (deployConfig === "vercel-vercel") {
|
|
9379
9427
|
const vercelJsonSource = joinPath(deploymentTemplateDir, "vercel.json.example");
|
|
9380
9428
|
if (pathExists(vercelJsonSource)) {
|
|
@@ -9417,23 +9465,25 @@ init_cli_input();
|
|
|
9417
9465
|
init_cli_output();
|
|
9418
9466
|
init_pathResolver();
|
|
9419
9467
|
var SHOW_WIP2 = process.env.SHOW_WIP === "true" || process.argv.includes("--wip");
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
}
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
]
|
|
9435
|
-
|
|
9436
|
-
|
|
9468
|
+
async function collectAppConfig(appName) {
|
|
9469
|
+
const answers = await runQuestionnaire(APP_QUESTIONNAIRE, {}, SHOW_WIP2, {
|
|
9470
|
+
selection: askForSelection,
|
|
9471
|
+
confirmation: askForConfirmation,
|
|
9472
|
+
input: askForInput
|
|
9473
|
+
});
|
|
9474
|
+
const framework = answers.framework || "vite";
|
|
9475
|
+
const needsBackend = answers.needsBackend || false;
|
|
9476
|
+
const defaultPlatform = framework === "nextjs" ? "vercel" : "firebase";
|
|
9477
|
+
return {
|
|
9478
|
+
template: framework,
|
|
9479
|
+
needsBackend,
|
|
9480
|
+
backendPlatform: needsBackend ? answers.backendPlatform || defaultPlatform : void 0,
|
|
9481
|
+
needsCRUD: false,
|
|
9482
|
+
selectedEntities: [],
|
|
9483
|
+
userAuth: "none",
|
|
9484
|
+
billing: false,
|
|
9485
|
+
features: []
|
|
9486
|
+
};
|
|
9437
9487
|
}
|
|
9438
9488
|
function calculateRelativePath(from, to) {
|
|
9439
9489
|
try {
|
|
@@ -9546,71 +9596,22 @@ async function main(options) {
|
|
|
9546
9596
|
let appNames = [];
|
|
9547
9597
|
const appConfigs = {};
|
|
9548
9598
|
let anyAppNeedsBackend = false;
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
""
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
if (isReservedAppName(trimmedName)) {
|
|
9556
|
-
log.warn(`'${trimmedName}' is reserved for framework demos.`);
|
|
9557
|
-
} else if (!isValidFileName(trimmedName)) {
|
|
9558
|
-
log.warn(
|
|
9559
|
-
`Invalid app name. Use only letters, numbers, dashes (-), and underscores (_).`
|
|
9560
|
-
);
|
|
9561
|
-
} else {
|
|
9562
|
-
appNames.push(trimmedName);
|
|
9563
|
-
const framework = await askForSelection(
|
|
9564
|
-
`Builder for "${trimmedName}"?`,
|
|
9565
|
-
[
|
|
9566
|
-
{
|
|
9567
|
-
title: "Vite \u2014 SPA/SaaS (client-side rendering, fast dev)",
|
|
9568
|
-
value: "vite"
|
|
9569
|
-
},
|
|
9570
|
-
{
|
|
9571
|
-
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 DoNotDev support: BETA",
|
|
9572
|
-
value: "nextjs"
|
|
9573
|
-
},
|
|
9574
|
-
{
|
|
9575
|
-
title: "Expo \u2014 Mobile app (iOS + Android, single codebase)",
|
|
9576
|
-
value: "expo"
|
|
9577
|
-
}
|
|
9578
|
-
],
|
|
9579
|
-
0
|
|
9580
|
-
);
|
|
9581
|
-
const backendValue = await askForSelection(
|
|
9582
|
-
`Backend for "${trimmedName}"?`,
|
|
9583
|
-
[...BACKEND_CHOICES],
|
|
9584
|
-
getDefaultBackendIndex(framework)
|
|
9585
|
-
);
|
|
9586
|
-
const needsBackend = backendValue !== "none";
|
|
9587
|
-
if (needsBackend) anyAppNeedsBackend = true;
|
|
9588
|
-
appConfigs[trimmedName] = {
|
|
9589
|
-
template: framework,
|
|
9590
|
-
needsBackend,
|
|
9591
|
-
backendPlatform: needsBackend ? backendValue : void 0,
|
|
9592
|
-
needsCRUD: false,
|
|
9593
|
-
selectedEntities: [],
|
|
9594
|
-
userAuth: "none",
|
|
9595
|
-
billing: false,
|
|
9596
|
-
features: []
|
|
9597
|
-
};
|
|
9598
|
-
}
|
|
9599
|
-
}
|
|
9600
|
-
while (appNames.length > 0) {
|
|
9601
|
-
const appName = await askForInput("App name (press Enter to finish)", "");
|
|
9602
|
-
if (!appName || appName.trim() === "") {
|
|
9599
|
+
let isFirstApp = true;
|
|
9600
|
+
while (true) {
|
|
9601
|
+
const prompt = isFirstApp ? "What's your first app name? (press Enter to skip)" : "App name (press Enter to finish)";
|
|
9602
|
+
const appNameInput = await askForInput(prompt, "");
|
|
9603
|
+
if (!appNameInput || appNameInput.trim() === "") {
|
|
9604
|
+
if (isFirstApp) break;
|
|
9603
9605
|
break;
|
|
9604
9606
|
}
|
|
9605
|
-
const trimmedName =
|
|
9607
|
+
const trimmedName = appNameInput.trim();
|
|
9608
|
+
isFirstApp = false;
|
|
9606
9609
|
if (appNames.includes(trimmedName)) {
|
|
9607
9610
|
log.warn(`'${trimmedName}' already exists. Choose a different name.`);
|
|
9608
9611
|
continue;
|
|
9609
9612
|
}
|
|
9610
9613
|
if (isReservedAppName(trimmedName)) {
|
|
9611
|
-
log.warn(
|
|
9612
|
-
`'${trimmedName}' is reserved for framework demos. Choose a different name.`
|
|
9613
|
-
);
|
|
9614
|
+
log.warn(`'${trimmedName}' is reserved for framework demos.`);
|
|
9614
9615
|
continue;
|
|
9615
9616
|
}
|
|
9616
9617
|
if (!isValidFileName(trimmedName)) {
|
|
@@ -9620,37 +9621,10 @@ async function main(options) {
|
|
|
9620
9621
|
continue;
|
|
9621
9622
|
}
|
|
9622
9623
|
appNames.push(trimmedName);
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
title: "Vite \u2014 SPA/SaaS (client-side rendering, fast dev)",
|
|
9628
|
-
value: "vite"
|
|
9629
|
-
},
|
|
9630
|
-
{
|
|
9631
|
-
title: "Next.js \u2014 Static content/SEO (SSR, SSG) \u2014 DoNotDev support: BETA",
|
|
9632
|
-
value: "nextjs"
|
|
9633
|
-
}
|
|
9634
|
-
],
|
|
9635
|
-
0
|
|
9636
|
-
);
|
|
9637
|
-
const backendValue = await askForSelection(
|
|
9638
|
-
`Backend for "${trimmedName}"?`,
|
|
9639
|
-
[...BACKEND_CHOICES],
|
|
9640
|
-
getDefaultBackendIndex(framework)
|
|
9641
|
-
);
|
|
9642
|
-
const needsBackend = backendValue !== "none";
|
|
9643
|
-
if (needsBackend) anyAppNeedsBackend = true;
|
|
9644
|
-
appConfigs[trimmedName] = {
|
|
9645
|
-
template: framework,
|
|
9646
|
-
needsBackend,
|
|
9647
|
-
backendPlatform: needsBackend ? backendValue : void 0,
|
|
9648
|
-
needsCRUD: false,
|
|
9649
|
-
selectedEntities: [],
|
|
9650
|
-
userAuth: "none",
|
|
9651
|
-
billing: false,
|
|
9652
|
-
features: []
|
|
9653
|
-
};
|
|
9624
|
+
Me(`Configuring "${trimmedName}"...`, "\u2699\uFE0F");
|
|
9625
|
+
const config = await collectAppConfig(trimmedName);
|
|
9626
|
+
appConfigs[trimmedName] = config;
|
|
9627
|
+
if (config.needsBackend) anyAppNeedsBackend = true;
|
|
9654
9628
|
}
|
|
9655
9629
|
let installDemoApp = await askForConfirmation(
|
|
9656
9630
|
"Would you like to install the demo app? (component showcase)",
|
|
@@ -8194,15 +8194,15 @@ function getCLIInstallInstructions(tool) {
|
|
|
8194
8194
|
},
|
|
8195
8195
|
[CLI_TOOLS.SUPABASE]: {
|
|
8196
8196
|
win32: [
|
|
8197
|
-
"
|
|
8197
|
+
"scoop install supabase",
|
|
8198
|
+
"Or: winget install Supabase.CLI",
|
|
8198
8199
|
"Or download from: https://github.com/supabase/cli/releases"
|
|
8199
8200
|
],
|
|
8200
8201
|
darwin: [
|
|
8201
|
-
"brew install supabase/tap/supabase"
|
|
8202
|
-
"Or: npm install -g supabase"
|
|
8202
|
+
"brew install supabase/tap/supabase"
|
|
8203
8203
|
],
|
|
8204
8204
|
linux: [
|
|
8205
|
-
"
|
|
8205
|
+
"brew install supabase/tap/supabase",
|
|
8206
8206
|
"Or see: https://supabase.com/docs/guides/cli"
|
|
8207
8207
|
]
|
|
8208
8208
|
},
|
|
@@ -8329,6 +8329,40 @@ var init_cli_tools = __esm({
|
|
|
8329
8329
|
}
|
|
8330
8330
|
});
|
|
8331
8331
|
|
|
8332
|
+
// packages/tooling/src/cli/setup/vercel-token.ts
|
|
8333
|
+
function readEnvVar(filePath, varName) {
|
|
8334
|
+
if (!pathExists(filePath)) return null;
|
|
8335
|
+
const content = readSync(filePath, { format: "text" });
|
|
8336
|
+
if (typeof content !== "string") return null;
|
|
8337
|
+
for (const line of content.split(/\r?\n/)) {
|
|
8338
|
+
const trimmed = line.trim();
|
|
8339
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
8340
|
+
if (trimmed.startsWith(`${varName}=`)) {
|
|
8341
|
+
const val = trimmed.substring(`${varName}=`.length).trim();
|
|
8342
|
+
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
8343
|
+
return val.slice(1, -1);
|
|
8344
|
+
}
|
|
8345
|
+
return val || null;
|
|
8346
|
+
}
|
|
8347
|
+
}
|
|
8348
|
+
return null;
|
|
8349
|
+
}
|
|
8350
|
+
function resolveVercelToken(appDir) {
|
|
8351
|
+
if (process.env.VERCEL_TOKEN) return process.env.VERCEL_TOKEN;
|
|
8352
|
+
const fromEnv = readEnvVar(joinPath(appDir, ".env"), "VERCEL_TOKEN");
|
|
8353
|
+
if (fromEnv) return fromEnv;
|
|
8354
|
+
const fromLocal = readEnvVar(joinPath(appDir, ".env.local"), "VERCEL_TOKEN");
|
|
8355
|
+
if (fromLocal) return fromLocal;
|
|
8356
|
+
return null;
|
|
8357
|
+
}
|
|
8358
|
+
var init_vercel_token = __esm({
|
|
8359
|
+
"packages/tooling/src/cli/setup/vercel-token.ts"() {
|
|
8360
|
+
"use strict";
|
|
8361
|
+
init_utils();
|
|
8362
|
+
init_pathResolver();
|
|
8363
|
+
}
|
|
8364
|
+
});
|
|
8365
|
+
|
|
8332
8366
|
// node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/nodes/identity.js
|
|
8333
8367
|
var require_identity = __commonJS({
|
|
8334
8368
|
"node_modules/.bun/yaml@2.8.2/node_modules/yaml/dist/nodes/identity.js"(exports) {
|
|
@@ -15690,13 +15724,36 @@ var require_dist = __commonJS({
|
|
|
15690
15724
|
}
|
|
15691
15725
|
});
|
|
15692
15726
|
|
|
15727
|
+
// packages/tooling/src/utils/error-handling.ts
|
|
15728
|
+
function isError(error2) {
|
|
15729
|
+
return error2 instanceof Error;
|
|
15730
|
+
}
|
|
15731
|
+
function getErrorMessage(error2) {
|
|
15732
|
+
if (isError(error2)) {
|
|
15733
|
+
return error2.message;
|
|
15734
|
+
}
|
|
15735
|
+
if (typeof error2 === "string") {
|
|
15736
|
+
return error2;
|
|
15737
|
+
}
|
|
15738
|
+
if (error2 && typeof error2 === "object" && "message" in error2) {
|
|
15739
|
+
return String(error2.message);
|
|
15740
|
+
}
|
|
15741
|
+
return String(error2);
|
|
15742
|
+
}
|
|
15743
|
+
var init_error_handling = __esm({
|
|
15744
|
+
"packages/tooling/src/utils/error-handling.ts"() {
|
|
15745
|
+
"use strict";
|
|
15746
|
+
init_utils();
|
|
15747
|
+
}
|
|
15748
|
+
});
|
|
15749
|
+
|
|
15693
15750
|
// packages/tooling/src/apps/sync-secrets.ts
|
|
15694
15751
|
var sync_secrets_exports = {};
|
|
15695
15752
|
__export(sync_secrets_exports, {
|
|
15696
15753
|
default: () => sync_secrets_default,
|
|
15697
15754
|
main: () => main
|
|
15698
15755
|
});
|
|
15699
|
-
import { spawnSync as
|
|
15756
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
15700
15757
|
function parseEnvFile(filePath) {
|
|
15701
15758
|
if (!pathExists(filePath)) {
|
|
15702
15759
|
throw new DoNotDevError(
|
|
@@ -15889,7 +15946,7 @@ async function setFirebaseSecret(key, value, projectId, dryRun = false, cwd) {
|
|
|
15889
15946
|
NODE_OPTIONS: ""
|
|
15890
15947
|
// Clear to avoid conflicts
|
|
15891
15948
|
};
|
|
15892
|
-
const result =
|
|
15949
|
+
const result = spawnSync6(firebaseCmd, args, {
|
|
15893
15950
|
input: value,
|
|
15894
15951
|
encoding: "utf8",
|
|
15895
15952
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -15985,7 +16042,7 @@ function setVercelSecret(key, value, projectId, dryRun = false) {
|
|
|
15985
16042
|
if (projectId) {
|
|
15986
16043
|
args.push("--project", projectId);
|
|
15987
16044
|
}
|
|
15988
|
-
const result =
|
|
16045
|
+
const result = spawnSync6("vercel", args, {
|
|
15989
16046
|
input: value,
|
|
15990
16047
|
encoding: "utf8",
|
|
15991
16048
|
stdio: ["pipe", "inherit", "inherit"]
|
|
@@ -16014,7 +16071,7 @@ function setVercelSecret(key, value, projectId, dryRun = false) {
|
|
|
16014
16071
|
}
|
|
16015
16072
|
function detectGitHubRepo() {
|
|
16016
16073
|
try {
|
|
16017
|
-
const result =
|
|
16074
|
+
const result = spawnSync6("git", ["remote", "get-url", "origin"], {
|
|
16018
16075
|
encoding: "utf8",
|
|
16019
16076
|
stdio: ["pipe", "pipe", "pipe"]
|
|
16020
16077
|
});
|
|
@@ -16042,7 +16099,7 @@ function setGitHubSecret(key, value, repo, dryRun = false) {
|
|
|
16042
16099
|
if (repo) {
|
|
16043
16100
|
args.push("--repo", repo);
|
|
16044
16101
|
}
|
|
16045
|
-
const result =
|
|
16102
|
+
const result = spawnSync6("gh", args, {
|
|
16046
16103
|
input: value,
|
|
16047
16104
|
encoding: "utf8",
|
|
16048
16105
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -16294,7 +16351,7 @@ var deploy_supabase_functions_exports = {};
|
|
|
16294
16351
|
__export(deploy_supabase_functions_exports, {
|
|
16295
16352
|
deploySupabaseFunctions: () => deploySupabaseFunctions
|
|
16296
16353
|
});
|
|
16297
|
-
import { execSync as
|
|
16354
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
16298
16355
|
async function deploySupabaseFunctions(appDir, config) {
|
|
16299
16356
|
const supabaseDir = joinPath(appDir, "supabase");
|
|
16300
16357
|
const functionsDir = joinPath(supabaseDir, "functions");
|
|
@@ -16323,7 +16380,7 @@ async function deploySupabaseFunctions(appDir, config) {
|
|
|
16323
16380
|
for (const functionName of functionDirs) {
|
|
16324
16381
|
s.start(`Deploying Edge Function: ${functionName}...`);
|
|
16325
16382
|
try {
|
|
16326
|
-
|
|
16383
|
+
execSync3(`supabase functions deploy ${functionName}`, {
|
|
16327
16384
|
cwd: supabaseDir,
|
|
16328
16385
|
stdio: config.verbose ? "inherit" : "pipe",
|
|
16329
16386
|
env: {
|
|
@@ -16484,7 +16541,7 @@ function safeRemove(path, options = {}) {
|
|
|
16484
16541
|
|
|
16485
16542
|
// packages/tooling/src/apps/deploy.ts
|
|
16486
16543
|
init_utils();
|
|
16487
|
-
import { execSync as
|
|
16544
|
+
import { execSync as execSync4 } from "node:child_process";
|
|
16488
16545
|
|
|
16489
16546
|
// packages/tooling/src/apps/deploy-frontend.ts
|
|
16490
16547
|
init_utils();
|
|
@@ -16515,15 +16572,31 @@ async function deployFrontend(appDir, serviceAccountPath, projectId, config) {
|
|
|
16515
16572
|
|
|
16516
16573
|
// packages/tooling/src/apps/deploy-vercel-frontend.ts
|
|
16517
16574
|
init_utils();
|
|
16518
|
-
|
|
16575
|
+
init_cli_output();
|
|
16576
|
+
init_vercel_token();
|
|
16577
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
16519
16578
|
async function deployVercelFrontend(appDir, _config) {
|
|
16520
16579
|
const s = Y2();
|
|
16521
16580
|
s.start("Deploying frontend to Vercel...");
|
|
16581
|
+
const token = resolveVercelToken(appDir);
|
|
16582
|
+
if (token) {
|
|
16583
|
+
log.debug("Using VERCEL_TOKEN from .env (token-based auth)");
|
|
16584
|
+
}
|
|
16585
|
+
const args = ["vercel", "--prod", "--yes"];
|
|
16586
|
+
if (token) {
|
|
16587
|
+
args.push("--token", token);
|
|
16588
|
+
}
|
|
16522
16589
|
try {
|
|
16523
|
-
|
|
16590
|
+
const result = spawnSync3("bunx", args, {
|
|
16524
16591
|
cwd: appDir,
|
|
16525
|
-
stdio: "
|
|
16592
|
+
stdio: "pipe",
|
|
16593
|
+
encoding: "utf-8"
|
|
16526
16594
|
});
|
|
16595
|
+
if (result.status !== 0) {
|
|
16596
|
+
s.stop("Vercel deployment failed");
|
|
16597
|
+
const errOutput = result.stderr?.trim();
|
|
16598
|
+
throw new Error(errOutput || `Vercel deploy exited with code ${result.status}`);
|
|
16599
|
+
}
|
|
16527
16600
|
s.stop("Frontend deployed to Vercel");
|
|
16528
16601
|
} catch (err) {
|
|
16529
16602
|
s.stop("Vercel deployment failed");
|
|
@@ -16534,7 +16607,7 @@ async function deployVercelFrontend(appDir, _config) {
|
|
|
16534
16607
|
// packages/tooling/src/apps/deploy-functions.ts
|
|
16535
16608
|
init_utils();
|
|
16536
16609
|
var import_yaml = __toESM(require_dist(), 1);
|
|
16537
|
-
import { execSync as
|
|
16610
|
+
import { execSync as execSync2, spawnSync as spawnSync4 } from "node:child_process";
|
|
16538
16611
|
init_pathResolver();
|
|
16539
16612
|
init_cli_tools();
|
|
16540
16613
|
init_typed_file_operations();
|
|
@@ -16703,7 +16776,7 @@ function updateCloudRunIAM(functionNames, projectId, region, serviceAccountPath,
|
|
|
16703
16776
|
let failCount = 0;
|
|
16704
16777
|
for (const funcName of functionNames) {
|
|
16705
16778
|
try {
|
|
16706
|
-
const result =
|
|
16779
|
+
const result = spawnSync4(
|
|
16707
16780
|
"gcloud",
|
|
16708
16781
|
[
|
|
16709
16782
|
"run",
|
|
@@ -16821,7 +16894,7 @@ async function autoSyncSecrets(functionsDir, projectId, config) {
|
|
|
16821
16894
|
let failCount = 0;
|
|
16822
16895
|
for (const { key, value } of secrets) {
|
|
16823
16896
|
try {
|
|
16824
|
-
const result =
|
|
16897
|
+
const result = spawnSync4(
|
|
16825
16898
|
firebaseCmd,
|
|
16826
16899
|
["functions:secrets:set", key, "--project", projectId],
|
|
16827
16900
|
{
|
|
@@ -16903,7 +16976,7 @@ To fix this, run:
|
|
|
16903
16976
|
const s2 = Y2();
|
|
16904
16977
|
s2.start("Building functions...");
|
|
16905
16978
|
try {
|
|
16906
|
-
|
|
16979
|
+
execSync2("bun run build", {
|
|
16907
16980
|
cwd: functionsDir,
|
|
16908
16981
|
stdio: config.verbose ? "inherit" : "pipe"
|
|
16909
16982
|
});
|
|
@@ -17003,29 +17076,10 @@ async function deployRules(appDir, serviceAccountPath, projectId, config, option
|
|
|
17003
17076
|
|
|
17004
17077
|
// packages/tooling/src/apps/deploy-utils.ts
|
|
17005
17078
|
init_utils();
|
|
17006
|
-
import { spawnSync as
|
|
17079
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
17007
17080
|
init_pathResolver();
|
|
17008
17081
|
init_typed_file_operations();
|
|
17009
|
-
|
|
17010
|
-
// packages/tooling/src/utils/error-handling.ts
|
|
17011
|
-
init_utils();
|
|
17012
|
-
function isError(error2) {
|
|
17013
|
-
return error2 instanceof Error;
|
|
17014
|
-
}
|
|
17015
|
-
function getErrorMessage(error2) {
|
|
17016
|
-
if (isError(error2)) {
|
|
17017
|
-
return error2.message;
|
|
17018
|
-
}
|
|
17019
|
-
if (typeof error2 === "string") {
|
|
17020
|
-
return error2;
|
|
17021
|
-
}
|
|
17022
|
-
if (error2 && typeof error2 === "object" && "message" in error2) {
|
|
17023
|
-
return String(error2.message);
|
|
17024
|
-
}
|
|
17025
|
-
return String(error2);
|
|
17026
|
-
}
|
|
17027
|
-
|
|
17028
|
-
// packages/tooling/src/apps/deploy-utils.ts
|
|
17082
|
+
init_error_handling();
|
|
17029
17083
|
function detectAvailableApps() {
|
|
17030
17084
|
const currentDir = process.cwd();
|
|
17031
17085
|
const appsDir = joinPath(currentDir, "apps");
|
|
@@ -17210,7 +17264,7 @@ How to fix:
|
|
|
17210
17264
|
if (shouldOpen) {
|
|
17211
17265
|
try {
|
|
17212
17266
|
const openCommand = process.platform === "win32" ? "start" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
17213
|
-
|
|
17267
|
+
spawnSync5(openCommand, [consoleUrl], { shell: true });
|
|
17214
17268
|
log.success("Opening Firebase Console...");
|
|
17215
17269
|
} catch {
|
|
17216
17270
|
log.warn("Could not open browser. Please open the URL manually.");
|
|
@@ -17281,7 +17335,7 @@ function detectProvider(appDir) {
|
|
|
17281
17335
|
if (hasFirebase) {
|
|
17282
17336
|
try {
|
|
17283
17337
|
const config = readSync(firebaseJsonPath, { format: "json" });
|
|
17284
|
-
if (config && typeof config === "object"
|
|
17338
|
+
if (config && typeof config === "object") {
|
|
17285
17339
|
const firebaseConfigObj = config;
|
|
17286
17340
|
firebaseConfig = {
|
|
17287
17341
|
projectId: firebaseConfigObj.projectId,
|
|
@@ -17290,8 +17344,6 @@ function detectProvider(appDir) {
|
|
|
17290
17344
|
hasFirestoreRules: !!firebaseConfigObj.firestore?.rules,
|
|
17291
17345
|
hasStorageRules: !!firebaseConfigObj.storage?.rules
|
|
17292
17346
|
};
|
|
17293
|
-
} else {
|
|
17294
|
-
throw new Error("Invalid firebase.json structure");
|
|
17295
17347
|
}
|
|
17296
17348
|
} catch {
|
|
17297
17349
|
firebaseConfig = {
|
|
@@ -17599,7 +17651,7 @@ async function main2(options = {}) {
|
|
|
17599
17651
|
isStaging ? "Building (staging mode)..." : "Building application..."
|
|
17600
17652
|
);
|
|
17601
17653
|
try {
|
|
17602
|
-
|
|
17654
|
+
execSync4(buildCmd, {
|
|
17603
17655
|
cwd: appDir,
|
|
17604
17656
|
stdio: "inherit",
|
|
17605
17657
|
env: {
|