@donotdev/cli 0.0.16 → 0.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dependencies-matrix.json +33 -129
  2. package/dist/bin/commands/bump.js +9 -2
  3. package/dist/bin/commands/create-app.js +195 -40
  4. package/dist/bin/commands/create-project.js +195 -40
  5. package/dist/bin/commands/deploy.js +51 -20
  6. package/dist/bin/commands/doctor.js +249 -56
  7. package/dist/bin/commands/emu.js +18 -20
  8. package/dist/bin/commands/make-admin.js +30 -10
  9. package/dist/bin/commands/setup.js +512 -122
  10. package/dist/bin/commands/type-check.d.ts.map +1 -1
  11. package/dist/bin/commands/type-check.js +7 -3
  12. package/dist/bin/commands/type-check.js.map +1 -1
  13. package/dist/bin/donotdev.js +26 -14
  14. package/dist/index.js +264 -80
  15. package/package.json +1 -1
  16. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +6 -6
  17. package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
  18. package/templates/root-consumer/guides/dndev/SETUP_AUTH.md.example +13 -6
  19. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +149 -1086
  20. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +68 -16
  21. package/templates/root-consumer/guides/dndev/SETUP_FUNCTIONS.md.example +6 -111
  22. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +123 -32
  23. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +108 -91
  24. package/templates/root-consumer/guides/dndev/advanced/EMULATORS.md.example +2 -2
  25. package/dist/bin/commands/firebase-setup.d.ts +0 -6
  26. package/dist/bin/commands/firebase-setup.d.ts.map +0 -1
  27. package/dist/bin/commands/firebase-setup.js +0 -7
  28. package/dist/bin/commands/firebase-setup.js.map +0 -1
  29. package/dist/bin/commands/supabase-setup.d.ts +0 -6
  30. package/dist/bin/commands/supabase-setup.d.ts.map +0 -1
  31. package/dist/bin/commands/supabase-setup.js +0 -7
  32. package/dist/bin/commands/supabase-setup.js.map +0 -1
@@ -8447,7 +8447,9 @@ var init_error_handling = __esm({
8447
8447
  // packages/tooling/src/cli/setup/types.ts
8448
8448
  function computeOverallStatus(steps) {
8449
8449
  const hasFailure = steps.some((s) => s.status === "failed");
8450
- const allSuccess = steps.every((s) => s.status === "success" || s.status === "skipped");
8450
+ const allSuccess = steps.every(
8451
+ (s) => s.status === "success" || s.status === "skipped"
8452
+ );
8451
8453
  if (hasFailure) return "failed";
8452
8454
  if (allSuccess) return "success";
8453
8455
  return "partial";
@@ -8831,9 +8833,17 @@ var init_firebase = __esm({
8831
8833
  const framework = ctx.app?.framework === "nextjs" ? "nextjs" : "vite";
8832
8834
  try {
8833
8835
  await checkPrerequisites();
8834
- steps.push({ name: "Prerequisites", status: "success", message: "Firebase CLI installed and logged in" });
8836
+ steps.push({
8837
+ name: "Prerequisites",
8838
+ status: "success",
8839
+ message: "Firebase CLI installed and logged in"
8840
+ });
8835
8841
  } catch (err) {
8836
- steps.push({ name: "Prerequisites", status: "failed", message: getErrorMessage(err) });
8842
+ steps.push({
8843
+ name: "Prerequisites",
8844
+ status: "failed",
8845
+ message: getErrorMessage(err)
8846
+ });
8837
8847
  return { provider: "firebase", steps, overallStatus: "failed" };
8838
8848
  }
8839
8849
  let projectId;
@@ -8841,38 +8851,78 @@ var init_firebase = __esm({
8841
8851
  const project = await selectOrCreateProject();
8842
8852
  projectId = project.projectId;
8843
8853
  log.info(`Using Firebase project: ${projectId}`);
8844
- steps.push({ name: "Project selection", status: "success", message: `Project: ${projectId}` });
8854
+ steps.push({
8855
+ name: "Project selection",
8856
+ status: "success",
8857
+ message: `Project: ${projectId}`
8858
+ });
8845
8859
  } catch (err) {
8846
- steps.push({ name: "Project selection", status: "failed", message: getErrorMessage(err) });
8860
+ steps.push({
8861
+ name: "Project selection",
8862
+ status: "failed",
8863
+ message: getErrorMessage(err)
8864
+ });
8847
8865
  return { provider: "firebase", steps, overallStatus: "failed" };
8848
8866
  }
8849
8867
  try {
8850
8868
  const sdkConfig = await ensureWebApp(projectId);
8851
- steps.push({ name: "SDK config", status: "success", message: "Web app config retrieved" });
8869
+ steps.push({
8870
+ name: "SDK config",
8871
+ status: "success",
8872
+ message: "Web app config retrieved"
8873
+ });
8852
8874
  if (!ctx.dryRun) {
8853
8875
  writeEnvFile(ctx.appDir, sdkConfig, framework);
8854
- steps.push({ name: "Write .env", status: "success", message: `Firebase config written to ${ctx.appDir}/.env` });
8876
+ steps.push({
8877
+ name: "Write .env",
8878
+ status: "success",
8879
+ message: `Firebase config written to ${ctx.appDir}/.env`
8880
+ });
8855
8881
  } else {
8856
- steps.push({ name: "Write .env", status: "skipped", message: "Dry run \u2014 .env not written" });
8882
+ steps.push({
8883
+ name: "Write .env",
8884
+ status: "skipped",
8885
+ message: "Dry run \u2014 .env not written"
8886
+ });
8857
8887
  }
8858
8888
  } catch (err) {
8859
- steps.push({ name: "SDK config", status: "failed", message: getErrorMessage(err) });
8889
+ steps.push({
8890
+ name: "SDK config",
8891
+ status: "failed",
8892
+ message: getErrorMessage(err)
8893
+ });
8860
8894
  }
8861
8895
  try {
8862
8896
  if (!ctx.dryRun) {
8863
8897
  updateFirebaserc(ctx.projectRoot, projectId);
8864
8898
  }
8865
- steps.push({ name: ".firebaserc", status: ctx.dryRun ? "skipped" : "success", message: "Updated with project ID" });
8899
+ steps.push({
8900
+ name: ".firebaserc",
8901
+ status: ctx.dryRun ? "skipped" : "success",
8902
+ message: "Updated with project ID"
8903
+ });
8866
8904
  } catch (err) {
8867
- steps.push({ name: ".firebaserc", status: "failed", message: getErrorMessage(err) });
8905
+ steps.push({
8906
+ name: ".firebaserc",
8907
+ status: "failed",
8908
+ message: getErrorMessage(err)
8909
+ });
8868
8910
  }
8869
8911
  try {
8870
8912
  if (!ctx.dryRun) {
8871
8913
  updateFirebaseJson(ctx.projectRoot, projectId);
8872
8914
  }
8873
- steps.push({ name: "firebase.json", status: ctx.dryRun ? "skipped" : "success", message: "Placeholders replaced" });
8915
+ steps.push({
8916
+ name: "firebase.json",
8917
+ status: ctx.dryRun ? "skipped" : "success",
8918
+ message: "Placeholders replaced"
8919
+ });
8874
8920
  } catch (err) {
8875
- steps.push({ name: "firebase.json", status: "failed", message: getErrorMessage(err) });
8921
+ steps.push({
8922
+ name: "firebase.json",
8923
+ status: "failed",
8924
+ message: getErrorMessage(err)
8925
+ });
8876
8926
  }
8877
8927
  Me(
8878
8928
  [
@@ -8913,7 +8963,11 @@ var init_firebase = __esm({
8913
8963
  message: "Enable Auth + Firestore in Firebase Console",
8914
8964
  coachingTopic: "firebase-enable-services"
8915
8965
  });
8916
- return { provider: "firebase", steps, overallStatus: computeOverallStatus(steps) };
8966
+ return {
8967
+ provider: "firebase",
8968
+ steps,
8969
+ overallStatus: computeOverallStatus(steps)
8970
+ };
8917
8971
  }
8918
8972
  };
8919
8973
  }
@@ -8922,9 +8976,7 @@ var init_firebase = __esm({
8922
8976
  // packages/tooling/src/utils/supabase-management.ts
8923
8977
  import { execSync } from "node:child_process";
8924
8978
  function extractProjectRef(supabaseUrl) {
8925
- const match = supabaseUrl.match(
8926
- /https?:\/\/([a-z0-9]+)\.supabase\.co/
8927
- );
8979
+ const match = supabaseUrl.match(/https?:\/\/([a-z0-9]+)\.supabase\.co/);
8928
8980
  if (!match?.[1]) {
8929
8981
  throw new Error(
8930
8982
  `Cannot extract project ref from URL: ${supabaseUrl}. Expected format: https://<ref>.supabase.co`
@@ -8958,7 +9010,9 @@ async function cleanupOldEntityMigrations(supabaseDir, latestFile) {
8958
9010
  `${cmd} migration repair --status reverted ${timestamps.join(" ")}`,
8959
9011
  { cwd: projectRoot, stdio: "pipe", env: { ...process.env } }
8960
9012
  );
8961
- log.info(`Repaired ${timestamps.length} old entity migration(s) in remote`);
9013
+ log.info(
9014
+ `Repaired ${timestamps.length} old entity migration(s) in remote`
9015
+ );
8962
9016
  } catch (error2) {
8963
9017
  log.debug(
8964
9018
  `Migration repair skipped: ${error2 instanceof Error ? error2.message : String(error2)}`
@@ -9119,7 +9173,9 @@ var init_base_generator = __esm({
9119
9173
  );
9120
9174
  }
9121
9175
  }
9122
- log.info(`Found ${foundEntities.length} entities: ${foundEntities.join(", ")}`);
9176
+ log.info(
9177
+ `Found ${foundEntities.length} entities: ${foundEntities.join(", ")}`
9178
+ );
9123
9179
  await this.generateAdditionalFiles(result);
9124
9180
  await this.cleanup(result);
9125
9181
  this.logSummary(result);
@@ -9962,7 +10018,10 @@ ${triggerSql}
9962
10018
  const entityFileName = getBasename(entityFilePath, ".ts");
9963
10019
  try {
9964
10020
  const entityModule = await this.importModule(entityFilePath);
9965
- const entity = this.extractEntityFromModule(entityModule, entityFileName);
10021
+ const entity = this.extractEntityFromModule(
10022
+ entityModule,
10023
+ entityFileName
10024
+ );
9966
10025
  if (entity?.name && entity?.collection) {
9967
10026
  entities.push({ entity, fileName: entityFileName });
9968
10027
  }
@@ -10039,7 +10098,11 @@ function writeEnvFile2(appDir, supabaseUrl, supabasePublicKey, framework) {
10039
10098
  }
10040
10099
  const existingLines = existingContent.split("\n");
10041
10100
  const preserved = [];
10042
- const supabaseKeys = /* @__PURE__ */ new Set(["SUPABASE_URL", "SUPABASE_PUBLIC_KEY", "SUPABASE_ANON_KEY"]);
10101
+ const supabaseKeys = /* @__PURE__ */ new Set([
10102
+ "SUPABASE_URL",
10103
+ "SUPABASE_PUBLIC_KEY",
10104
+ "SUPABASE_ANON_KEY"
10105
+ ]);
10043
10106
  for (const line of existingLines) {
10044
10107
  const trimmed = line.trim();
10045
10108
  const isSupabaseVar = [...supabaseKeys].some(
@@ -10132,7 +10195,9 @@ function detectSecretKey(appDir) {
10132
10195
  for (const line of lines) {
10133
10196
  const trimmed = line.trim();
10134
10197
  if (trimmed.startsWith("SUPABASE_SECRET_KEY=") || trimmed.startsWith("SUPABASE_SERVICE_ROLE_KEY=")) {
10135
- const match = trimmed.match(/^SUPABASE_(?:SECRET|SERVICE_ROLE)_KEY=(.+)$/);
10198
+ const match = trimmed.match(
10199
+ /^SUPABASE_(?:SECRET|SERVICE_ROLE)_KEY=(.+)$/
10200
+ );
10136
10201
  if (match && match[1]) {
10137
10202
  return match[1].trim();
10138
10203
  }
@@ -10162,7 +10227,10 @@ async function generateCrudFunction(supabaseDir, projectRoot) {
10162
10227
  const entitiesDir = joinPath(projectRoot, "entities");
10163
10228
  const indexPath = joinPath(entitiesDir, "index.ts");
10164
10229
  if (pathExists(indexPath)) {
10165
- const relativePath = getRelativePathBetween(crudDir, indexPath).replace(/\\/g, "/");
10230
+ const relativePath = getRelativePathBetween(crudDir, indexPath).replace(
10231
+ /\\/g,
10232
+ "/"
10233
+ );
10166
10234
  templateContent = templateContent.replace(
10167
10235
  /\/\/ import \* as entities from '\.\.\/_shared\/entities\.ts';\n/,
10168
10236
  ""
@@ -10278,7 +10346,9 @@ async function main3(options = {}) {
10278
10346
  s.stop("Failed to generate SQL migrations");
10279
10347
  }
10280
10348
  } catch (error2) {
10281
- log.error(`SQL generation failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
10349
+ log.error(
10350
+ `SQL generation failed: ${error2 instanceof Error ? error2.message : String(error2)}`
10351
+ );
10282
10352
  }
10283
10353
  }
10284
10354
  } else {
@@ -10288,7 +10358,9 @@ async function main3(options = {}) {
10288
10358
  try {
10289
10359
  await cleanupOldEntityMigrations(supabaseDir, generatedEntityFile);
10290
10360
  } catch (error2) {
10291
- log.warn(`Could not clean old entity migrations: ${error2 instanceof Error ? error2.message : String(error2)}`);
10361
+ log.warn(
10362
+ `Could not clean old entity migrations: ${error2 instanceof Error ? error2.message : String(error2)}`
10363
+ );
10292
10364
  }
10293
10365
  }
10294
10366
  let migrationsPushed = false;
@@ -10316,7 +10388,9 @@ async function main3(options = {}) {
10316
10388
  try {
10317
10389
  await generateCrudFunction(supabaseDir, projectRoot);
10318
10390
  } catch (error2) {
10319
- log.warn(`Could not patch CRUD function: ${error2 instanceof Error ? error2.message : String(error2)}`);
10391
+ log.warn(
10392
+ `Could not patch CRUD function: ${error2 instanceof Error ? error2.message : String(error2)}`
10393
+ );
10320
10394
  }
10321
10395
  const steps = [];
10322
10396
  steps.push("\u2705 Credentials validated from .env");
@@ -10341,7 +10415,9 @@ async function main3(options = {}) {
10341
10415
  ].join("\n"),
10342
10416
  title
10343
10417
  );
10344
- Se(hasErrors ? "Setup incomplete \u2014 see errors above." : "Supabase setup done.");
10418
+ Se(
10419
+ hasErrors ? "Setup incomplete \u2014 see errors above." : "Supabase setup done."
10420
+ );
10345
10421
  }
10346
10422
  var supabase_default, supabaseWizard;
10347
10423
  var init_supabase = __esm({
@@ -10390,10 +10466,18 @@ var init_supabase = __esm({
10390
10466
  return { provider: "supabase", steps, overallStatus: "failed" };
10391
10467
  }
10392
10468
  const supabaseUrl = existingConfig.url;
10393
- steps.push({ name: "Public credentials", status: "success", message: `URL: ${supabaseUrl}` });
10469
+ steps.push({
10470
+ name: "Public credentials",
10471
+ status: "success",
10472
+ message: `URL: ${supabaseUrl}`
10473
+ });
10394
10474
  const secretKey = detectSecretKey(ctx.appDir);
10395
10475
  if (secretKey) {
10396
- steps.push({ name: "Secret key", status: "success", message: "Detected in functions/.env" });
10476
+ steps.push({
10477
+ name: "Secret key",
10478
+ status: "success",
10479
+ message: "Detected in functions/.env"
10480
+ });
10397
10481
  } else {
10398
10482
  const supabaseDir = joinPath(ctx.appDir, "supabase");
10399
10483
  const functionsEnvPath = joinPath(supabaseDir, "functions", ".env");
@@ -10417,9 +10501,17 @@ var init_supabase = __esm({
10417
10501
  try {
10418
10502
  const projectRef = extractProjectRef(supabaseUrl);
10419
10503
  ensureProjectLinked(ctx.appDir, projectRef);
10420
- steps.push({ name: "CLI link", status: "success", message: "Supabase CLI linked" });
10504
+ steps.push({
10505
+ name: "CLI link",
10506
+ status: "success",
10507
+ message: "Supabase CLI linked"
10508
+ });
10421
10509
  } catch (err) {
10422
- steps.push({ name: "CLI link", status: "failed", message: getErrorMessage(err) });
10510
+ steps.push({
10511
+ name: "CLI link",
10512
+ status: "failed",
10513
+ message: getErrorMessage(err)
10514
+ });
10423
10515
  }
10424
10516
  } else {
10425
10517
  steps.push({ name: "CLI link", status: "skipped", message: "Dry run" });
@@ -10439,7 +10531,11 @@ var init_supabase = __esm({
10439
10531
  message: "Review custom RLS policies in dashboard",
10440
10532
  coachingTopic: "supabase-rls"
10441
10533
  });
10442
- return { provider: "supabase", steps, overallStatus: computeOverallStatus(steps) };
10534
+ return {
10535
+ provider: "supabase",
10536
+ steps,
10537
+ overallStatus: computeOverallStatus(steps)
10538
+ };
10443
10539
  }
10444
10540
  };
10445
10541
  }
@@ -10484,14 +10580,22 @@ var init_vercel = __esm({
10484
10580
  if (!isVercelInstalled()) {
10485
10581
  log.error("Vercel CLI is not installed.");
10486
10582
  log.info("Install it with: npm install -g vercel");
10487
- steps.push({ name: "Vercel CLI", status: "failed", message: "Not installed. Run: npm install -g vercel" });
10583
+ steps.push({
10584
+ name: "Vercel CLI",
10585
+ status: "failed",
10586
+ message: "Not installed. Run: npm install -g vercel"
10587
+ });
10488
10588
  return { provider: "vercel", steps, overallStatus: "failed" };
10489
10589
  }
10490
10590
  steps.push({ name: "Vercel CLI", status: "success", message: "Installed" });
10491
10591
  const token = resolveVercelToken(ctx.appDir);
10492
10592
  if (token) {
10493
10593
  log.success("VERCEL_TOKEN detected \u2014 no login required");
10494
- steps.push({ name: "Auth", status: "success", message: "Token-based auth (VERCEL_TOKEN)" });
10594
+ steps.push({
10595
+ name: "Auth",
10596
+ status: "success",
10597
+ message: "Token-based auth (VERCEL_TOKEN)"
10598
+ });
10495
10599
  } else {
10496
10600
  Me(
10497
10601
  [
@@ -10517,28 +10621,52 @@ var init_vercel = __esm({
10517
10621
  const s = Y2();
10518
10622
  s.start("Linking Vercel project...");
10519
10623
  try {
10520
- const result = spawnSync2("vercel", ["link", "--yes", "--token", token], {
10521
- cwd: ctx.appDir,
10522
- stdio: ["inherit", "pipe", "pipe"],
10523
- encoding: "utf-8",
10524
- timeout: 3e4
10525
- });
10624
+ const result = spawnSync2(
10625
+ "vercel",
10626
+ ["link", "--yes", "--token", token],
10627
+ {
10628
+ cwd: ctx.appDir,
10629
+ stdio: ["inherit", "pipe", "pipe"],
10630
+ encoding: "utf-8",
10631
+ timeout: 3e4
10632
+ }
10633
+ );
10526
10634
  if (result.status === 0) {
10527
10635
  s.stop("Vercel project linked");
10528
- steps.push({ name: "Project link", status: "success", message: "Linked to Vercel project" });
10636
+ steps.push({
10637
+ name: "Project link",
10638
+ status: "success",
10639
+ message: "Linked to Vercel project"
10640
+ });
10529
10641
  } else {
10530
10642
  s.stop("Vercel link failed");
10531
10643
  const stderr = result.stderr?.trim() || "Unknown error";
10532
- steps.push({ name: "Project link", status: "failed", message: stderr });
10644
+ steps.push({
10645
+ name: "Project link",
10646
+ status: "failed",
10647
+ message: stderr
10648
+ });
10533
10649
  }
10534
10650
  } catch (err) {
10535
10651
  s.stop("Vercel link failed");
10536
- steps.push({ name: "Project link", status: "failed", message: getErrorMessage(err) });
10652
+ steps.push({
10653
+ name: "Project link",
10654
+ status: "failed",
10655
+ message: getErrorMessage(err)
10656
+ });
10537
10657
  }
10538
10658
  } else if (!token) {
10539
- steps.push({ name: "Project link", status: "skipped", message: "No token \u2014 cannot link" });
10659
+ steps.push({
10660
+ name: "Project link",
10661
+ status: "skipped",
10662
+ message: "No token \u2014 cannot link"
10663
+ });
10540
10664
  } else {
10541
- steps.push({ name: "Project link", status: "skipped", message: "Dry run" });
10665
+ steps.push({
10666
+ name: "Project link",
10667
+ status: "skipped",
10668
+ message: "Dry run"
10669
+ });
10542
10670
  }
10543
10671
  Me(
10544
10672
  [
@@ -10551,7 +10679,11 @@ var init_vercel = __esm({
10551
10679
  ].join("\n"),
10552
10680
  "Deployment"
10553
10681
  );
10554
- return { provider: "vercel", steps, overallStatus: computeOverallStatus(steps) };
10682
+ return {
10683
+ provider: "vercel",
10684
+ steps,
10685
+ overallStatus: computeOverallStatus(steps)
10686
+ };
10555
10687
  }
10556
10688
  };
10557
10689
  }
@@ -10622,13 +10754,16 @@ var init_stripe = __esm({
10622
10754
  const envPath = joinPath(ctx.appDir, ".env");
10623
10755
  if (pathExists(envPath)) {
10624
10756
  const content = readSync(envPath, { format: "text" });
10625
- if (typeof content === "string" && content.includes("STRIPE_")) return true;
10757
+ if (typeof content === "string" && content.includes("STRIPE_"))
10758
+ return true;
10626
10759
  }
10627
10760
  const pkgPath = joinPath(ctx.appDir, "package.json");
10628
10761
  if (pathExists(pkgPath)) {
10629
10762
  const pkg = readSync(pkgPath, { format: "json" });
10630
10763
  if (pkg && typeof pkg === "object") {
10631
- const deps = { ...pkg.dependencies };
10764
+ const deps = {
10765
+ ...pkg.dependencies
10766
+ };
10632
10767
  if (deps["@donotdev/billing"]) return true;
10633
10768
  }
10634
10769
  }
@@ -10642,7 +10777,11 @@ var init_stripe = __esm({
10642
10777
  const existingPk = readEnvValue(envPath, `${prefix}STRIPE_PUBLISHABLE_KEY`);
10643
10778
  let publishableKey = existingPk;
10644
10779
  if (existingPk && isValidPublishableKey(existingPk)) {
10645
- steps.push({ name: "Publishable key", status: "success", message: "Found in .env" });
10780
+ steps.push({
10781
+ name: "Publishable key",
10782
+ status: "success",
10783
+ message: "Found in .env"
10784
+ });
10646
10785
  } else {
10647
10786
  const pk = await askForInput(
10648
10787
  "Stripe publishable key (pk_test_... or pk_live_...)",
@@ -10654,17 +10793,34 @@ var init_stripe = __esm({
10654
10793
  log.success("Wrote STRIPE_PUBLISHABLE_KEY to .env");
10655
10794
  }
10656
10795
  publishableKey = pk;
10657
- steps.push({ name: "Publishable key", status: "success", message: "Written to .env" });
10796
+ steps.push({
10797
+ name: "Publishable key",
10798
+ status: "success",
10799
+ message: "Written to .env"
10800
+ });
10658
10801
  } else {
10659
- steps.push({ name: "Publishable key", status: "failed", message: "Invalid format \u2014 must start with pk_test_ or pk_live_" });
10802
+ steps.push({
10803
+ name: "Publishable key",
10804
+ status: "failed",
10805
+ message: "Invalid format \u2014 must start with pk_test_ or pk_live_"
10806
+ });
10660
10807
  }
10661
10808
  }
10662
- const functionsEnvPath = joinPath(ctx.appDir, "supabase", "functions", ".env");
10809
+ const functionsEnvPath = joinPath(
10810
+ ctx.appDir,
10811
+ "supabase",
10812
+ "functions",
10813
+ ".env"
10814
+ );
10663
10815
  const altFunctionsEnvPath = joinPath(ctx.appDir, "functions", ".env");
10664
10816
  const secretEnvPath = pathExists(functionsEnvPath) ? functionsEnvPath : altFunctionsEnvPath;
10665
10817
  const existingSk = readEnvValue(secretEnvPath, "STRIPE_SECRET_KEY");
10666
10818
  if (existingSk && isValidSecretKey(existingSk)) {
10667
- steps.push({ name: "Secret key", status: "success", message: "Found in functions/.env" });
10819
+ steps.push({
10820
+ name: "Secret key",
10821
+ status: "success",
10822
+ message: "Found in functions/.env"
10823
+ });
10668
10824
  } else {
10669
10825
  const sk = await ge({
10670
10826
  message: "Stripe secret key (sk_test_... or sk_live_...):"
@@ -10674,14 +10830,26 @@ var init_stripe = __esm({
10674
10830
  writeEnvVar(secretEnvPath, "STRIPE_SECRET_KEY", sk);
10675
10831
  log.success("Wrote STRIPE_SECRET_KEY to functions/.env");
10676
10832
  }
10677
- steps.push({ name: "Secret key", status: "success", message: "Written to functions/.env" });
10833
+ steps.push({
10834
+ name: "Secret key",
10835
+ status: "success",
10836
+ message: "Written to functions/.env"
10837
+ });
10678
10838
  } else {
10679
- steps.push({ name: "Secret key", status: "failed", message: "STRIPE_SECRET_KEY has invalid format" });
10839
+ steps.push({
10840
+ name: "Secret key",
10841
+ status: "failed",
10842
+ message: "STRIPE_SECRET_KEY has invalid format"
10843
+ });
10680
10844
  }
10681
10845
  }
10682
10846
  const existingWh = readEnvValue(secretEnvPath, "STRIPE_WEBHOOK_SECRET");
10683
10847
  if (existingWh && isValidWebhookSecret(existingWh)) {
10684
- steps.push({ name: "Webhook secret", status: "success", message: "Found in functions/.env" });
10848
+ steps.push({
10849
+ name: "Webhook secret",
10850
+ status: "success",
10851
+ message: "Found in functions/.env"
10852
+ });
10685
10853
  } else {
10686
10854
  Me(
10687
10855
  [
@@ -10706,7 +10874,11 @@ var init_stripe = __esm({
10706
10874
  coachingTopic: "stripe-webhook"
10707
10875
  });
10708
10876
  }
10709
- return { provider: "stripe", steps, overallStatus: computeOverallStatus(steps) };
10877
+ return {
10878
+ provider: "stripe",
10879
+ steps,
10880
+ overallStatus: computeOverallStatus(steps)
10881
+ };
10710
10882
  }
10711
10883
  };
10712
10884
  }
@@ -10818,7 +10990,11 @@ var init_oauth = __esm({
10818
10990
  }))
10819
10991
  );
10820
10992
  if (selected.length === 0) {
10821
- steps.push({ name: "OAuth", status: "skipped", message: "No providers selected" });
10993
+ steps.push({
10994
+ name: "OAuth",
10995
+ status: "skipped",
10996
+ message: "No providers selected"
10997
+ });
10822
10998
  return { provider: "oauth", steps, overallStatus: "success" };
10823
10999
  }
10824
11000
  for (const providerId of selected) {
@@ -10843,7 +11019,11 @@ var init_oauth = __esm({
10843
11019
  coachingTopic: `oauth-${provider.id}`
10844
11020
  });
10845
11021
  }
10846
- return { provider: "oauth", steps, overallStatus: computeOverallStatus(steps) };
11022
+ return {
11023
+ provider: "oauth",
11024
+ steps,
11025
+ overallStatus: computeOverallStatus(steps)
11026
+ };
10847
11027
  }
10848
11028
  };
10849
11029
  }
@@ -10868,10 +11048,14 @@ function detectAuthProviders(ctx) {
10868
11048
  if (!pathExists(candidate)) continue;
10869
11049
  const content = readSync(candidate, { format: "text" });
10870
11050
  if (typeof content !== "string") continue;
10871
- if (content.includes("google") || content.includes("Google")) providers.push("google");
10872
- if (content.includes("github") || content.includes("GitHub")) providers.push("github");
10873
- if (content.includes("apple") || content.includes("Apple")) providers.push("apple");
10874
- if (content.includes("facebook") || content.includes("Facebook")) providers.push("facebook");
11051
+ if (content.includes("google") || content.includes("Google"))
11052
+ providers.push("google");
11053
+ if (content.includes("github") || content.includes("GitHub"))
11054
+ providers.push("github");
11055
+ if (content.includes("apple") || content.includes("Apple"))
11056
+ providers.push("apple");
11057
+ if (content.includes("facebook") || content.includes("Facebook"))
11058
+ providers.push("facebook");
10875
11059
  break;
10876
11060
  }
10877
11061
  return [...new Set(providers)];
@@ -10962,7 +11146,11 @@ var init_auth = __esm({
10962
11146
  coachingTopic: "auth-supabase"
10963
11147
  });
10964
11148
  }
10965
- return { provider: "auth", steps, overallStatus: computeOverallStatus(steps) };
11149
+ return {
11150
+ provider: "auth",
11151
+ steps,
11152
+ overallStatus: computeOverallStatus(steps)
11153
+ };
10966
11154
  }
10967
11155
  };
10968
11156
  }
@@ -11007,7 +11195,11 @@ var init_check_env = __esm({
11007
11195
  const envPath = joinPath(ctx.appDir, ".env");
11008
11196
  const examplePath = joinPath(ctx.appDir, ".env.example");
11009
11197
  if (!pathExists(envPath)) {
11010
- results.push({ name: ".env file", status: "fail", message: "Not found \u2014 run dndev setup" });
11198
+ results.push({
11199
+ name: ".env file",
11200
+ status: "fail",
11201
+ message: "Not found \u2014 run dndev setup"
11202
+ });
11011
11203
  return results;
11012
11204
  }
11013
11205
  results.push({ name: ".env file", status: "pass", message: "Found" });
@@ -11055,9 +11247,17 @@ var init_check_env = __esm({
11055
11247
  return /^\.env(\*|\..*)?$/.test(trimmed);
11056
11248
  });
11057
11249
  if (hasEnvIgnore) {
11058
- results.push({ name: ".gitignore", status: "pass", message: ".env is gitignored" });
11250
+ results.push({
11251
+ name: ".gitignore",
11252
+ status: "pass",
11253
+ message: ".env is gitignored"
11254
+ });
11059
11255
  } else {
11060
- results.push({ name: ".gitignore", status: "warn", message: ".env might not be gitignored \u2014 verify manually" });
11256
+ results.push({
11257
+ name: ".gitignore",
11258
+ status: "warn",
11259
+ message: ".env might not be gitignored \u2014 verify manually"
11260
+ });
11061
11261
  }
11062
11262
  }
11063
11263
  }
@@ -11094,12 +11294,24 @@ var init_check_firebase = __esm({
11094
11294
  timeout: 1e4
11095
11295
  });
11096
11296
  if (result.status === 0) {
11097
- results.push({ name: "Firebase CLI", status: "pass", message: result.stdout.trim() });
11297
+ results.push({
11298
+ name: "Firebase CLI",
11299
+ status: "pass",
11300
+ message: result.stdout.trim()
11301
+ });
11098
11302
  } else {
11099
- results.push({ name: "Firebase CLI", status: "fail", message: "Not installed" });
11303
+ results.push({
11304
+ name: "Firebase CLI",
11305
+ status: "fail",
11306
+ message: "Not installed"
11307
+ });
11100
11308
  }
11101
11309
  } catch {
11102
- results.push({ name: "Firebase CLI", status: "fail", message: "Not installed" });
11310
+ results.push({
11311
+ name: "Firebase CLI",
11312
+ status: "fail",
11313
+ message: "Not installed"
11314
+ });
11103
11315
  }
11104
11316
  const rcPath = joinPath(ctx.projectRoot, ".firebaserc");
11105
11317
  if (pathExists(rcPath)) {
@@ -11110,15 +11322,31 @@ var init_check_firebase = __esm({
11110
11322
  const projects = rc?.projects;
11111
11323
  const projectId = projects && typeof projects === "object" ? projects.default : void 0;
11112
11324
  if (projectId && typeof projectId === "string") {
11113
- results.push({ name: ".firebaserc", status: "pass", message: `Project: ${projectId}` });
11325
+ results.push({
11326
+ name: ".firebaserc",
11327
+ status: "pass",
11328
+ message: `Project: ${projectId}`
11329
+ });
11114
11330
  } else {
11115
- results.push({ name: ".firebaserc", status: "warn", message: "No default project set" });
11331
+ results.push({
11332
+ name: ".firebaserc",
11333
+ status: "warn",
11334
+ message: "No default project set"
11335
+ });
11116
11336
  }
11117
11337
  } catch {
11118
- results.push({ name: ".firebaserc", status: "warn", message: "Invalid JSON" });
11338
+ results.push({
11339
+ name: ".firebaserc",
11340
+ status: "warn",
11341
+ message: "Invalid JSON"
11342
+ });
11119
11343
  }
11120
11344
  } else {
11121
- results.push({ name: ".firebaserc", status: "fail", message: "Missing \u2014 run dndev setup firebase" });
11345
+ results.push({
11346
+ name: ".firebaserc",
11347
+ status: "fail",
11348
+ message: "Missing \u2014 run dndev setup firebase"
11349
+ });
11122
11350
  }
11123
11351
  const framework = ctx.app?.framework ?? "vite";
11124
11352
  const prefix = framework === "nextjs" ? "NEXT_PUBLIC_" : "VITE_";
@@ -11126,16 +11354,34 @@ var init_check_firebase = __esm({
11126
11354
  if (pathExists(envPath)) {
11127
11355
  const content = readSync(envPath, { format: "text" });
11128
11356
  if (typeof content === "string") {
11129
- const requiredKeys = ["FIREBASE_API_KEY", "FIREBASE_PROJECT_ID", "FIREBASE_AUTH_DOMAIN"];
11130
- const missing = requiredKeys.filter((key) => !content.includes(`${prefix}${key}=`));
11357
+ const requiredKeys = [
11358
+ "FIREBASE_API_KEY",
11359
+ "FIREBASE_PROJECT_ID",
11360
+ "FIREBASE_AUTH_DOMAIN"
11361
+ ];
11362
+ const missing = requiredKeys.filter(
11363
+ (key) => !content.includes(`${prefix}${key}=`)
11364
+ );
11131
11365
  if (missing.length === 0) {
11132
- results.push({ name: "Firebase .env", status: "pass", message: "All required keys present" });
11366
+ results.push({
11367
+ name: "Firebase .env",
11368
+ status: "pass",
11369
+ message: "All required keys present"
11370
+ });
11133
11371
  } else {
11134
- results.push({ name: "Firebase .env", status: "fail", message: `Missing: ${missing.join(", ")}` });
11372
+ results.push({
11373
+ name: "Firebase .env",
11374
+ status: "fail",
11375
+ message: `Missing: ${missing.join(", ")}`
11376
+ });
11135
11377
  }
11136
11378
  }
11137
11379
  } else {
11138
- results.push({ name: "Firebase .env", status: "fail", message: ".env file not found" });
11380
+ results.push({
11381
+ name: "Firebase .env",
11382
+ status: "fail",
11383
+ message: ".env file not found"
11384
+ });
11139
11385
  }
11140
11386
  const saKeyPaths = [
11141
11387
  joinPath(ctx.appDir, "service-account-key.json"),
@@ -11143,9 +11389,17 @@ var init_check_firebase = __esm({
11143
11389
  ];
11144
11390
  const saFound = saKeyPaths.some((p2) => pathExists(p2));
11145
11391
  if (saFound) {
11146
- results.push({ name: "Service account key", status: "pass", message: "Found" });
11392
+ results.push({
11393
+ name: "Service account key",
11394
+ status: "pass",
11395
+ message: "Found"
11396
+ });
11147
11397
  } else {
11148
- results.push({ name: "Service account key", status: "warn", message: "Not found (needed for deploy/emu)" });
11398
+ results.push({
11399
+ name: "Service account key",
11400
+ status: "warn",
11401
+ message: "Not found (needed for deploy/emu)"
11402
+ });
11149
11403
  }
11150
11404
  return results;
11151
11405
  }
@@ -11183,42 +11437,82 @@ var init_check_supabase = __esm({
11183
11437
  timeout: 1e4
11184
11438
  });
11185
11439
  if (result.status === 0) {
11186
- results.push({ name: "Supabase CLI", status: "pass", message: result.stdout.trim() });
11440
+ results.push({
11441
+ name: "Supabase CLI",
11442
+ status: "pass",
11443
+ message: result.stdout.trim()
11444
+ });
11187
11445
  } else {
11188
- results.push({ name: "Supabase CLI", status: "warn", message: "Not installed (needed for migrations)" });
11446
+ results.push({
11447
+ name: "Supabase CLI",
11448
+ status: "warn",
11449
+ message: "Not installed (needed for migrations)"
11450
+ });
11189
11451
  }
11190
11452
  } catch {
11191
- results.push({ name: "Supabase CLI", status: "warn", message: "Not installed" });
11453
+ results.push({
11454
+ name: "Supabase CLI",
11455
+ status: "warn",
11456
+ message: "Not installed"
11457
+ });
11192
11458
  }
11193
11459
  const configPath = joinPath(ctx.appDir, "supabase", "config.toml");
11194
11460
  if (pathExists(configPath)) {
11195
11461
  results.push({ name: "config.toml", status: "pass", message: "Found" });
11196
11462
  } else {
11197
- results.push({ name: "config.toml", status: "warn", message: "Missing (expected at supabase/config.toml)" });
11463
+ results.push({
11464
+ name: "config.toml",
11465
+ status: "warn",
11466
+ message: "Missing (expected at supabase/config.toml)"
11467
+ });
11198
11468
  }
11199
11469
  const envPath = joinPath(ctx.appDir, ".env");
11200
11470
  if (pathExists(envPath)) {
11201
11471
  const content = readSync(envPath, { format: "text" });
11202
11472
  if (typeof content === "string") {
11203
- const urlMatch = content.match(new RegExp(`${prefix}SUPABASE_URL=(.+)`));
11473
+ const urlMatch = content.match(
11474
+ new RegExp(`${prefix}SUPABASE_URL=(.+)`)
11475
+ );
11204
11476
  const url = urlMatch?.[1]?.trim();
11205
11477
  if (url && isValidSupabaseUrl(url)) {
11206
11478
  results.push({ name: "Supabase URL", status: "pass", message: url });
11207
11479
  } else if (url) {
11208
- results.push({ name: "Supabase URL", status: "fail", message: "Invalid URL format" });
11480
+ results.push({
11481
+ name: "Supabase URL",
11482
+ status: "fail",
11483
+ message: "Invalid URL format"
11484
+ });
11209
11485
  } else {
11210
- results.push({ name: "Supabase URL", status: "fail", message: "Missing in .env" });
11486
+ results.push({
11487
+ name: "Supabase URL",
11488
+ status: "fail",
11489
+ message: "Missing in .env"
11490
+ });
11211
11491
  }
11212
- const keyMatch = content.match(new RegExp(`${prefix}SUPABASE_(?:PUBLIC_KEY|ANON_KEY)=(.+)`));
11492
+ const keyMatch = content.match(
11493
+ new RegExp(`${prefix}SUPABASE_(?:PUBLIC_KEY|ANON_KEY)=(.+)`)
11494
+ );
11213
11495
  const key = keyMatch?.[1]?.trim();
11214
11496
  if (key && isValidPublicKey(key)) {
11215
- results.push({ name: "Supabase public key", status: "pass", message: "Present" });
11497
+ results.push({
11498
+ name: "Supabase public key",
11499
+ status: "pass",
11500
+ message: "Present"
11501
+ });
11216
11502
  } else {
11217
- results.push({ name: "Supabase public key", status: "fail", message: "Missing in .env" });
11503
+ results.push({
11504
+ name: "Supabase public key",
11505
+ status: "fail",
11506
+ message: "Missing in .env"
11507
+ });
11218
11508
  }
11219
11509
  }
11220
11510
  } else {
11221
- results.push({ name: "Supabase .env", status: "fail", message: ".env file not found" });
11511
+ results.push({
11512
+ name: "Supabase .env",
11513
+ status: "fail",
11514
+ message: ".env file not found"
11515
+ });
11222
11516
  }
11223
11517
  const functionsEnvCandidates = [
11224
11518
  joinPath(ctx.appDir, "supabase", "functions", ".env"),
@@ -11230,12 +11524,20 @@ var init_check_supabase = __esm({
11230
11524
  const content = readSync(fenvPath, { format: "text" });
11231
11525
  if (typeof content === "string" && content.match(/SUPABASE_(?:SECRET|SERVICE_ROLE)_KEY=.+/)) {
11232
11526
  secretFound = true;
11233
- results.push({ name: "Secret key", status: "pass", message: `Found in ${fenvPath.split("/").pop()}` });
11527
+ results.push({
11528
+ name: "Secret key",
11529
+ status: "pass",
11530
+ message: `Found in ${fenvPath.split("/").pop()}`
11531
+ });
11234
11532
  break;
11235
11533
  }
11236
11534
  }
11237
11535
  if (!secretFound) {
11238
- results.push({ name: "Secret key", status: "warn", message: "Not found (needed for migrations + deploy)" });
11536
+ results.push({
11537
+ name: "Secret key",
11538
+ status: "warn",
11539
+ message: "Not found (needed for migrations + deploy)"
11540
+ });
11239
11541
  }
11240
11542
  return results;
11241
11543
  }
@@ -11293,7 +11595,8 @@ var init_check_stripe = __esm({
11293
11595
  const envPath = joinPath(ctx.appDir, ".env");
11294
11596
  if (pathExists(envPath)) {
11295
11597
  const content = readSync(envPath, { format: "text" });
11296
- if (typeof content === "string" && content.includes("STRIPE_PUBLISHABLE_KEY")) return true;
11598
+ if (typeof content === "string" && content.includes("STRIPE_PUBLISHABLE_KEY"))
11599
+ return true;
11297
11600
  }
11298
11601
  return false;
11299
11602
  },
@@ -11308,12 +11611,24 @@ var init_check_stripe = __esm({
11308
11611
  if (pk) {
11309
11612
  if (pk.startsWith("pk_test_") || pk.startsWith("pk_live_")) {
11310
11613
  pkMode = pk.startsWith("pk_test_") ? "test" : "live";
11311
- results.push({ name: "Publishable key", status: "pass", message: `Valid (${pkMode} mode)` });
11614
+ results.push({
11615
+ name: "Publishable key",
11616
+ status: "pass",
11617
+ message: `Valid (${pkMode} mode)`
11618
+ });
11312
11619
  } else {
11313
- results.push({ name: "Publishable key", status: "fail", message: "Invalid format \u2014 must start with pk_test_ or pk_live_" });
11620
+ results.push({
11621
+ name: "Publishable key",
11622
+ status: "fail",
11623
+ message: "Invalid format \u2014 must start with pk_test_ or pk_live_"
11624
+ });
11314
11625
  }
11315
11626
  } else {
11316
- results.push({ name: "Publishable key", status: "fail", message: "Missing in .env" });
11627
+ results.push({
11628
+ name: "Publishable key",
11629
+ status: "fail",
11630
+ message: "Missing in .env"
11631
+ });
11317
11632
  }
11318
11633
  let skMode = null;
11319
11634
  if (functionsEnvPath) {
@@ -11321,33 +11636,69 @@ var init_check_stripe = __esm({
11321
11636
  if (sk) {
11322
11637
  if (sk.startsWith("sk_test_") || sk.startsWith("sk_live_") || sk.startsWith("rk_test_") || sk.startsWith("rk_live_")) {
11323
11638
  skMode = sk.includes("_test_") ? "test" : "live";
11324
- results.push({ name: "Secret key", status: "pass", message: `Valid (${skMode} mode)` });
11639
+ results.push({
11640
+ name: "Secret key",
11641
+ status: "pass",
11642
+ message: `Valid (${skMode} mode)`
11643
+ });
11325
11644
  } else {
11326
- results.push({ name: "Secret key", status: "fail", message: "STRIPE_SECRET_KEY has invalid format" });
11645
+ results.push({
11646
+ name: "Secret key",
11647
+ status: "fail",
11648
+ message: "STRIPE_SECRET_KEY has invalid format"
11649
+ });
11327
11650
  }
11328
11651
  } else {
11329
- results.push({ name: "Secret key", status: "warn", message: "Not found in functions/.env" });
11652
+ results.push({
11653
+ name: "Secret key",
11654
+ status: "warn",
11655
+ message: "Not found in functions/.env"
11656
+ });
11330
11657
  }
11331
11658
  } else {
11332
- results.push({ name: "Secret key", status: "warn", message: "No functions/.env found" });
11659
+ results.push({
11660
+ name: "Secret key",
11661
+ status: "warn",
11662
+ message: "No functions/.env found"
11663
+ });
11333
11664
  }
11334
11665
  if (functionsEnvPath) {
11335
11666
  const wh = readEnvValue2(functionsEnvPath, "STRIPE_WEBHOOK_SECRET");
11336
11667
  if (wh) {
11337
11668
  if (wh.startsWith("whsec_")) {
11338
- results.push({ name: "Webhook secret", status: "pass", message: "Valid format" });
11669
+ results.push({
11670
+ name: "Webhook secret",
11671
+ status: "pass",
11672
+ message: "Valid format"
11673
+ });
11339
11674
  } else {
11340
- results.push({ name: "Webhook secret", status: "fail", message: "STRIPE_WEBHOOK_SECRET has invalid format" });
11675
+ results.push({
11676
+ name: "Webhook secret",
11677
+ status: "fail",
11678
+ message: "STRIPE_WEBHOOK_SECRET has invalid format"
11679
+ });
11341
11680
  }
11342
11681
  } else {
11343
- results.push({ name: "Webhook secret", status: "warn", message: "Not found \u2014 webhooks won't verify" });
11682
+ results.push({
11683
+ name: "Webhook secret",
11684
+ status: "warn",
11685
+ message: "Not found \u2014 webhooks won't verify"
11686
+ });
11344
11687
  }
11345
11688
  }
11346
11689
  if (pkMode && skMode) {
11347
11690
  if (pkMode !== skMode) {
11348
- results.push({ name: "Key mode", status: "warn", message: `Publishable key is ${pkMode} but secret key is ${skMode}` });
11691
+ results.push({
11692
+ name: "Key mode",
11693
+ status: "warn",
11694
+ message: `Publishable key is ${pkMode} but secret key is ${skMode}`
11695
+ });
11349
11696
  } else {
11350
- results.push({ name: "Key mode", status: "pass", message: `Both keys are ${pkMode}` });
11697
+ results.push({
11698
+ name: "Key mode",
11699
+ status: "pass",
11700
+ message: `Both keys are ${pkMode}`
11701
+ });
11351
11702
  }
11352
11703
  }
11353
11704
  return results;
@@ -11374,13 +11725,18 @@ var init_check_auth = __esm({
11374
11725
  const pkgPath = joinPath(ctx.appDir, "package.json");
11375
11726
  if (pathExists(pkgPath)) {
11376
11727
  const content = readSync(pkgPath, { format: "text" });
11377
- if (typeof content === "string" && content.includes("@donotdev/auth")) return true;
11728
+ if (typeof content === "string" && content.includes("@donotdev/auth"))
11729
+ return true;
11378
11730
  }
11379
11731
  return false;
11380
11732
  },
11381
11733
  async run(ctx) {
11382
11734
  const results = [];
11383
- results.push({ name: "@donotdev/auth", status: "pass", message: "Installed" });
11735
+ results.push({
11736
+ name: "@donotdev/auth",
11737
+ status: "pass",
11738
+ message: "Installed"
11739
+ });
11384
11740
  const candidates = [
11385
11741
  joinPath(ctx.appDir, "src", "providers.ts"),
11386
11742
  joinPath(ctx.appDir, "src", "providers.tsx"),
@@ -11397,10 +11753,14 @@ var init_check_auth = __esm({
11397
11753
  const content = readSync(providerFile, { format: "text" });
11398
11754
  if (typeof content === "string") {
11399
11755
  const providers = [];
11400
- if (content.includes("email") || content.includes("Email")) providers.push("email");
11401
- if (content.includes("google") || content.includes("Google")) providers.push("google");
11402
- if (content.includes("github") || content.includes("GitHub")) providers.push("github");
11403
- if (content.includes("apple") || content.includes("Apple")) providers.push("apple");
11756
+ if (content.includes("email") || content.includes("Email"))
11757
+ providers.push("email");
11758
+ if (content.includes("google") || content.includes("Google"))
11759
+ providers.push("google");
11760
+ if (content.includes("github") || content.includes("GitHub"))
11761
+ providers.push("github");
11762
+ if (content.includes("apple") || content.includes("Apple"))
11763
+ providers.push("apple");
11404
11764
  if (providers.length > 0) {
11405
11765
  results.push({
11406
11766
  name: "Auth providers",
@@ -11410,7 +11770,11 @@ var init_check_auth = __esm({
11410
11770
  }
11411
11771
  }
11412
11772
  } else {
11413
- results.push({ name: "Providers config", status: "warn", message: "No providers.ts found \u2014 auth may not work" });
11773
+ results.push({
11774
+ name: "Providers config",
11775
+ status: "warn",
11776
+ message: "No providers.ts found \u2014 auth may not work"
11777
+ });
11414
11778
  }
11415
11779
  const hasFirebase = pathExists(joinPath(ctx.projectRoot, ".firebaserc"));
11416
11780
  const hasSupabase = pathExists(joinPath(ctx.appDir, "supabase"));
@@ -11429,7 +11793,11 @@ var init_check_auth = __esm({
11429
11793
  detail: "Run dndev setup auth for setup coaching"
11430
11794
  });
11431
11795
  } else {
11432
- results.push({ name: "Backend", status: "warn", message: "No backend detected for auth" });
11796
+ results.push({
11797
+ name: "Backend",
11798
+ status: "warn",
11799
+ message: "No backend detected for auth"
11800
+ });
11433
11801
  }
11434
11802
  return results;
11435
11803
  }
@@ -11483,7 +11851,9 @@ async function main4(options = {}) {
11483
11851
  let hasFail = false;
11484
11852
  const registry = options.check ? CHECK_REGISTRY.filter((e2) => e2.id === options.check) : CHECK_REGISTRY;
11485
11853
  if (options.check && registry.length === 0) {
11486
- log.error(`Unknown check: ${options.check}. Available: ${CHECK_REGISTRY.map((e2) => e2.id).join(", ")}`);
11854
+ log.error(
11855
+ `Unknown check: ${options.check}. Available: ${CHECK_REGISTRY.map((e2) => e2.id).join(", ")}`
11856
+ );
11487
11857
  Se("Doctor aborted.");
11488
11858
  return 1;
11489
11859
  }
@@ -11517,7 +11887,9 @@ async function main4(options = {}) {
11517
11887
  if (warnings > 0) summaryParts.push(`${warnings} warning(s)`);
11518
11888
  if (fails > 0) summaryParts.push(`${fails} failure(s)`);
11519
11889
  const exitCode = hasFail ? 1 : 0;
11520
- Se(hasFail ? `Health check failed: ${summaryParts.join(", ")}` : `All clear: ${summaryParts.join(", ")}`);
11890
+ Se(
11891
+ hasFail ? `Health check failed: ${summaryParts.join(", ")}` : `All clear: ${summaryParts.join(", ")}`
11892
+ );
11521
11893
  return exitCode;
11522
11894
  }
11523
11895
  var CHECK_REGISTRY, STATUS_ICONS, doctor_default;
@@ -11530,9 +11902,18 @@ var init_doctor = __esm({
11530
11902
  init_pathResolver();
11531
11903
  CHECK_REGISTRY = [
11532
11904
  { id: "env", load: async () => (await Promise.resolve().then(() => (init_check_env(), check_env_exports))).envCheck },
11533
- { id: "firebase", load: async () => (await Promise.resolve().then(() => (init_check_firebase(), check_firebase_exports))).firebaseCheck },
11534
- { id: "supabase", load: async () => (await Promise.resolve().then(() => (init_check_supabase(), check_supabase_exports))).supabaseCheck },
11535
- { id: "stripe", load: async () => (await Promise.resolve().then(() => (init_check_stripe(), check_stripe_exports))).stripeCheck },
11905
+ {
11906
+ id: "firebase",
11907
+ load: async () => (await Promise.resolve().then(() => (init_check_firebase(), check_firebase_exports))).firebaseCheck
11908
+ },
11909
+ {
11910
+ id: "supabase",
11911
+ load: async () => (await Promise.resolve().then(() => (init_check_supabase(), check_supabase_exports))).supabaseCheck
11912
+ },
11913
+ {
11914
+ id: "stripe",
11915
+ load: async () => (await Promise.resolve().then(() => (init_check_stripe(), check_stripe_exports))).stripeCheck
11916
+ },
11536
11917
  { id: "auth", load: async () => (await Promise.resolve().then(() => (init_check_auth(), check_auth_exports))).authCheck }
11537
11918
  ];
11538
11919
  STATUS_ICONS = {
@@ -11570,7 +11951,14 @@ var WIZARD_REGISTRY = {
11570
11951
  oauth: async () => (await Promise.resolve().then(() => (init_oauth(), oauth_exports))).oauthWizard,
11571
11952
  auth: async () => (await Promise.resolve().then(() => (init_auth(), auth_exports))).authWizard
11572
11953
  };
11573
- var WIZARD_ORDER = ["firebase", "supabase", "vercel", "stripe", "auth", "oauth"];
11954
+ var WIZARD_ORDER = [
11955
+ "firebase",
11956
+ "supabase",
11957
+ "vercel",
11958
+ "stripe",
11959
+ "auth",
11960
+ "oauth"
11961
+ ];
11574
11962
  var STATUS_ICONS2 = {
11575
11963
  success: "\u2705",
11576
11964
  // green check
@@ -11637,7 +12025,9 @@ async function main5(options = {}) {
11637
12025
  }
11638
12026
  if (relevant.length === 0) {
11639
12027
  log.warn("No providers detected in this project.");
11640
- log.info(`Available providers: ${Object.keys(WIZARD_REGISTRY).join(", ")}`);
12028
+ log.info(
12029
+ `Available providers: ${Object.keys(WIZARD_REGISTRY).join(", ")}`
12030
+ );
11641
12031
  log.info("Run: dndev setup <provider>");
11642
12032
  Se("Nothing to set up.");
11643
12033
  return 0;