@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.
Files changed (70) hide show
  1. package/dependencies-matrix.json +36 -20
  2. package/dist/bin/commands/build.js +69 -52
  3. package/dist/bin/commands/bump.js +7 -13
  4. package/dist/bin/commands/create-app.js +77 -29
  5. package/dist/bin/commands/create-project.js +109 -135
  6. package/dist/bin/commands/deploy.js +97 -45
  7. package/dist/bin/commands/dev.js +43 -24
  8. package/dist/bin/commands/doctor.d.ts +6 -0
  9. package/dist/bin/commands/doctor.d.ts.map +1 -0
  10. package/dist/bin/commands/{lint.js → doctor.js} +1178 -147
  11. package/dist/bin/commands/doctor.js.map +1 -0
  12. package/dist/bin/commands/emu.js +297 -107
  13. package/dist/bin/commands/make-admin.js +77499 -11
  14. package/dist/bin/commands/preview.js +44 -25
  15. package/dist/bin/commands/setup.d.ts +6 -0
  16. package/dist/bin/commands/setup.d.ts.map +1 -0
  17. package/dist/bin/commands/setup.js +11733 -0
  18. package/dist/bin/commands/setup.js.map +1 -0
  19. package/dist/bin/commands/type-check.js +2018 -283
  20. package/dist/bin/dndev.js +54 -58
  21. package/dist/bin/donotdev.js +28 -44
  22. package/dist/index.js +633 -416
  23. package/package.json +2 -2
  24. package/templates/app-expo/.env.example +2 -22
  25. package/templates/app-expo/README.md.example +1 -1
  26. package/templates/app-expo/assets/adaptive-icon.png +0 -0
  27. package/templates/app-expo/assets/favicon.png +0 -0
  28. package/templates/app-expo/assets/icon.png +0 -0
  29. package/templates/app-expo/assets/splash.png +0 -0
  30. package/templates/app-expo/src/config/app.ts.example +46 -0
  31. package/templates/app-expo/src/config/providers.ts.example +7 -0
  32. package/templates/app-next/src/config/providers.ts.example +7 -0
  33. package/templates/app-vite/src/config/providers.ts.example +7 -0
  34. package/templates/app-vite/src/pages/HomePage.tsx.example +1 -1
  35. package/templates/functions-firebase/README.md.example +1 -1
  36. package/templates/functions-firebase/functions-firebase/.env.example.example +1 -1
  37. package/templates/functions-firebase/functions-firebase/README.md.example +1 -1
  38. package/templates/functions-firebase/functions-firebase/tsconfig.json.example +1 -1
  39. package/templates/functions-firebase/functions.config.js.example +1 -1
  40. package/templates/functions-supabase/supabase/config.toml.example +59 -0
  41. package/templates/functions-supabase/supabase/functions/.env.example +13 -0
  42. package/templates/functions-supabase/supabase/functions/deno.json.example +8 -0
  43. package/templates/overlay-firebase/env.fragment.example +1 -1
  44. package/templates/overlay-firebase/env.fragment.expo.example +1 -1
  45. package/templates/overlay-firebase/env.fragment.nextjs.example +1 -1
  46. package/templates/overlay-supabase/env.fragment.example +8 -3
  47. package/templates/overlay-supabase/env.fragment.expo.example +8 -3
  48. package/templates/overlay-supabase/env.fragment.nextjs.example +8 -3
  49. package/templates/overlay-vercel/env.fragment.example +1 -1
  50. package/templates/overlay-vercel/env.fragment.nextjs.example +1 -1
  51. package/templates/root-consumer/AI.md.example +15 -0
  52. package/templates/root-consumer/guides/dndev/AGENT_START_HERE.md.example +2 -2
  53. package/templates/root-consumer/guides/dndev/ENV_SETUP.md.example +6 -6
  54. package/templates/root-consumer/guides/dndev/INDEX.md.example +2 -2
  55. package/templates/root-consumer/guides/dndev/SETUP_APP_CONFIG.md.example +3 -3
  56. package/templates/root-consumer/guides/dndev/SETUP_CRUD.md.example +98 -0
  57. package/templates/root-consumer/guides/dndev/SETUP_FIREBASE.md.example +4 -4
  58. package/templates/root-consumer/guides/dndev/SETUP_OAUTH_PROVIDERS.md.example +60 -0
  59. package/templates/root-consumer/guides/dndev/SETUP_STRIPE.md.example +62 -0
  60. package/templates/root-consumer/guides/dndev/SETUP_SUPABASE.md.example +3 -3
  61. package/templates/root-consumer/guides/dndev/SETUP_VERCEL.md.example +2 -2
  62. package/templates/root-consumer/guides/wai-way/WAI_WAY_CLI.md.example +7 -8
  63. package/templates/root-consumer/guides/wai-way/blueprints/1_scaffold.md.example +9 -5
  64. package/dist/bin/commands/lint.d.ts +0 -11
  65. package/dist/bin/commands/lint.d.ts.map +0 -1
  66. package/dist/bin/commands/lint.js.map +0 -1
  67. package/dist/bin/commands/staging.d.ts +0 -11
  68. package/dist/bin/commands/staging.d.ts.map +0 -1
  69. package/dist/bin/commands/staging.js +0 -12
  70. package/dist/bin/commands/staging.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/bin/commands/doctor.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,IAAI,EAAE,MAAM,mBAAmB,CAAC"}
@@ -7844,50 +7844,7 @@ var init_utils = __esm({
7844
7844
  }
7845
7845
  });
7846
7846
 
7847
- // packages/tooling/src/utils/cli-input.ts
7848
- async function askForMultiSelection(message, choices, defaultIndices = []) {
7849
- const options = choices.map((choice) => ({
7850
- value: choice.value,
7851
- label: choice.title,
7852
- hint: choice.hint
7853
- }));
7854
- const initialValues = defaultIndices.map((i) => choices[i]?.value).filter(Boolean);
7855
- const result = await fe({
7856
- message,
7857
- options,
7858
- initialValues: initialValues.length > 0 ? initialValues : void 0
7859
- });
7860
- if (pD(result)) {
7861
- xe("Operation cancelled.");
7862
- process.exit(0);
7863
- }
7864
- return result;
7865
- }
7866
- var init_cli_input = __esm({
7867
- "packages/tooling/src/utils/cli-input.ts"() {
7868
- "use strict";
7869
- init_utils();
7870
- init_dist2();
7871
- }
7872
- });
7873
-
7874
- // packages/cli/src/bin/commands/emu.ts
7875
- init_utils();
7876
-
7877
- // packages/tooling/src/index.ts
7878
- init_utils();
7879
-
7880
- // packages/tooling/src/cli/index.ts
7881
- init_utils();
7882
-
7883
- // packages/tooling/src/utils/app-selector.ts
7884
- init_utils();
7885
- init_dist2();
7886
-
7887
7847
  // packages/tooling/src/utils/app-detection.ts
7888
- init_utils();
7889
- init_pathResolver();
7890
- init_typed_file_operations();
7891
7848
  function detectApps(projectRoot) {
7892
7849
  const apps = [];
7893
7850
  const appsDir = joinPath(projectRoot, "apps");
@@ -7946,14 +7903,23 @@ function analyzeApp(appPath, appName) {
7946
7903
  const functionsPath = joinPath(appPath, "functions");
7947
7904
  const functionsStat = statSync2(functionsPath);
7948
7905
  const hasFunctions = pathExists(functionsPath) && (functionsStat?.isDirectory() ?? false);
7949
- let platform2;
7950
- if (hasFunctions) {
7951
- const firebaseJsonPath = joinPath(functionsPath, "firebase.json");
7906
+ let platform4;
7907
+ const firebaseJsonInFunctions = hasFunctions && pathExists(joinPath(functionsPath, "firebase.json"));
7908
+ const firebaseJsonInApp = pathExists(joinPath(appPath, "firebase.json"));
7909
+ if (firebaseJsonInFunctions || firebaseJsonInApp) {
7910
+ platform4 = "firebase";
7911
+ }
7912
+ if (!platform4) {
7913
+ const supabaseConfigPath = joinPath(appPath, "supabase", "config.toml");
7914
+ const hasSupabaseDep = !!(packageJson.dependencies?.["@donotdev/supabase"] || packageJson.dependencies?.["@supabase/supabase-js"]);
7915
+ if (pathExists(supabaseConfigPath) || hasSupabaseDep) {
7916
+ platform4 = "supabase";
7917
+ }
7918
+ }
7919
+ if (!platform4) {
7952
7920
  const vercelJsonPath = joinPath(appPath, "vercel.json");
7953
- if (pathExists(firebaseJsonPath)) {
7954
- platform2 = "firebase";
7955
- } else if (pathExists(vercelJsonPath)) {
7956
- platform2 = "vercel";
7921
+ if (pathExists(vercelJsonPath)) {
7922
+ platform4 = "vercel";
7957
7923
  }
7958
7924
  }
7959
7925
  return {
@@ -7964,12 +7930,19 @@ function analyzeApp(appPath, appName) {
7964
7930
  framework,
7965
7931
  hasFunctions,
7966
7932
  functionsPath: hasFunctions ? functionsPath : void 0,
7967
- platform: platform2
7933
+ platform: platform4
7968
7934
  };
7969
7935
  }
7936
+ var init_app_detection = __esm({
7937
+ "packages/tooling/src/utils/app-detection.ts"() {
7938
+ "use strict";
7939
+ init_utils();
7940
+ init_pathResolver();
7941
+ init_typed_file_operations();
7942
+ }
7943
+ });
7970
7944
 
7971
7945
  // packages/tooling/src/utils/app-selector.ts
7972
- init_cli_output();
7973
7946
  async function selectApp(projectRoot, appName) {
7974
7947
  const apps = detectApps(projectRoot);
7975
7948
  if (apps.length === 0) {
@@ -8003,6 +7976,51 @@ async function selectApp(projectRoot, appName) {
8003
7976
  }
8004
7977
  return apps.find((a) => a.name === selected) || null;
8005
7978
  }
7979
+ var init_app_selector = __esm({
7980
+ "packages/tooling/src/utils/app-selector.ts"() {
7981
+ "use strict";
7982
+ init_utils();
7983
+ init_dist2();
7984
+ init_app_detection();
7985
+ init_cli_output();
7986
+ }
7987
+ });
7988
+
7989
+ // packages/tooling/src/utils/cli-input.ts
7990
+ async function askForMultiSelection(message, choices, defaultIndices = []) {
7991
+ const options = choices.map((choice) => ({
7992
+ value: choice.value,
7993
+ label: choice.title,
7994
+ hint: choice.hint
7995
+ }));
7996
+ const initialValues = defaultIndices.map((i) => choices[i]?.value).filter(Boolean);
7997
+ const result = await fe({
7998
+ message,
7999
+ options,
8000
+ initialValues: initialValues.length > 0 ? initialValues : void 0
8001
+ });
8002
+ if (pD(result)) {
8003
+ xe("Operation cancelled.");
8004
+ process.exit(0);
8005
+ }
8006
+ return result;
8007
+ }
8008
+ var init_cli_input = __esm({
8009
+ "packages/tooling/src/utils/cli-input.ts"() {
8010
+ "use strict";
8011
+ init_utils();
8012
+ init_dist2();
8013
+ }
8014
+ });
8015
+
8016
+ // packages/cli/src/bin/commands/emu.ts
8017
+ init_utils();
8018
+
8019
+ // packages/tooling/src/index.ts
8020
+ init_utils();
8021
+
8022
+ // packages/tooling/src/cli/index.ts
8023
+ init_utils();
8006
8024
 
8007
8025
  // packages/tooling/src/utils/spawn-utils.ts
8008
8026
  init_utils();
@@ -8048,18 +8066,23 @@ function createEmulatorEnv(appPath, framework = "vite", options) {
8048
8066
 
8049
8067
  // packages/tooling/src/apps/emu.ts
8050
8068
  init_utils();
8069
+ init_app_selector();
8070
+ init_cli_output();
8071
+ init_errors();
8072
+ init_pathResolver();
8073
+
8074
+ // packages/tooling/src/apps/emu-firebase.ts
8075
+ init_utils();
8076
+ init_cli_input();
8077
+ init_cli_output();
8078
+ init_pathResolver();
8079
+ init_typed_file_operations();
8051
8080
  import {
8052
8081
  spawn,
8053
8082
  spawnSync as spawnSync2,
8054
8083
  execSync as execSync2
8055
8084
  } from "node:child_process";
8056
8085
  import { platform } from "node:os";
8057
- init_cli_input();
8058
- init_cli_output();
8059
- init_errors();
8060
- init_pathResolver();
8061
- init_pathResolver();
8062
- init_typed_file_operations();
8063
8086
  function discoverFirebaseProjectId(appPath) {
8064
8087
  const firebasercPath = joinPath(appPath, ".firebaserc");
8065
8088
  if (pathExists(firebasercPath)) {
@@ -8091,7 +8114,7 @@ function killPorts(ports) {
8091
8114
  pids.add(match[1]);
8092
8115
  }
8093
8116
  }
8094
- for (const pid of pids) {
8117
+ for (const pid of Array.from(pids)) {
8095
8118
  try {
8096
8119
  execSync2(`taskkill /F /PID ${pid}`, { stdio: "ignore" });
8097
8120
  log.debug(`Killed process ${pid} on port ${port}`);
@@ -8153,9 +8176,9 @@ function loadEnvFile(filePath) {
8153
8176
  } catch {
8154
8177
  }
8155
8178
  }
8156
- async function main(options) {
8157
- const args = process.argv.slice(2);
8158
- const debug = options?.debug ?? false;
8179
+ async function startFirebase(app, projectRoot, options = {}) {
8180
+ const debug = options.debug ?? false;
8181
+ let selectedServices = options.selectedServices ?? [];
8159
8182
  const serviceChoices = [
8160
8183
  {
8161
8184
  title: "Auth",
@@ -8178,47 +8201,6 @@ async function main(options) {
8178
8201
  hint: "Stripe webhook forwarding (for payment testing)"
8179
8202
  }
8180
8203
  ];
8181
- let selectedServices = [];
8182
- const appName = args.find(
8183
- (arg) => arg !== "emu" && arg !== "--debug" && !arg.startsWith("--")
8184
- );
8185
- if (options?.services) {
8186
- selectedServices = options.services.split(",").map((s) => s.trim());
8187
- } else {
8188
- const servicesArg = args.find((arg) => arg.startsWith("--services="));
8189
- if (servicesArg) {
8190
- const servicesList = servicesArg.split("=")[1];
8191
- if (servicesList) {
8192
- selectedServices = servicesList.split(",").map((s) => s.trim());
8193
- }
8194
- } else {
8195
- if (options?.auth || args.includes("--auth"))
8196
- selectedServices.push("auth");
8197
- if (args.includes("--functions")) selectedServices.push("functions");
8198
- if (options?.firestore || args.includes("--firestore"))
8199
- selectedServices.push("firestore");
8200
- if (options?.stripe || args.includes("--stripe"))
8201
- selectedServices.push("stripe");
8202
- }
8203
- }
8204
- const validServices = serviceChoices.map((c) => c.value);
8205
- selectedServices = selectedServices.filter((s) => validServices.includes(s));
8206
- const projectRoot = getRepoRoot();
8207
- if (!projectRoot) {
8208
- throw new DoNotDevError(
8209
- "Could not determine repository root",
8210
- "path-resolution-error"
8211
- );
8212
- }
8213
- const app = await selectApp(projectRoot, appName);
8214
- if (!app) {
8215
- return 1;
8216
- }
8217
- if (!app.hasFunctions || app.platform !== "firebase") {
8218
- log.error(`App "${app.name}" does not have Firebase functions.`);
8219
- log.error('Use "dndev dev" for apps without functions.\n');
8220
- return 1;
8221
- }
8222
8204
  log.info(`Starting Firebase emulators + dev server for ${app.name}...
8223
8205
  `);
8224
8206
  if (selectedServices.length === 0) {
@@ -8350,7 +8332,7 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
8350
8332
  const stripeWebhookUrl = `http://localhost:5001/${projectId}/${region}/stripeWebhook`;
8351
8333
  concurrentlyArgs.push(`stripe listen --forward-to ${stripeWebhookUrl}`);
8352
8334
  log.info("");
8353
- log.info("\u2705 Stripe webhook forwarding will start automatically");
8335
+ log.info("Stripe webhook forwarding will start automatically");
8354
8336
  log.info(` Webhook URL: ${stripeWebhookUrl}`);
8355
8337
  log.info(" To trigger test events, run in another terminal:");
8356
8338
  log.info(" stripe trigger checkout.session.completed");
@@ -8372,9 +8354,7 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
8372
8354
  );
8373
8355
  const SIGNAL_EXIT_CODES = {
8374
8356
  SIGINT: 130,
8375
- // 128 + 2
8376
8357
  SIGTERM: 143
8377
- // 128 + 15
8378
8358
  };
8379
8359
  const cleanup = (signal) => {
8380
8360
  if (!childProcess.pid) return;
@@ -8424,11 +8404,221 @@ FIREBASE_AUTH_EMULATOR_HOST=${authEmulatorHost}
8424
8404
  });
8425
8405
  childProcess.on("error", (error2) => {
8426
8406
  handlers.forEach((h2) => h2());
8427
- log.error(`Failed to start emulators: ${error2.message}`);
8407
+ log.error(`Failed to start Firebase emulators: ${error2.message}`);
8428
8408
  resolve4(1);
8429
8409
  });
8430
8410
  });
8431
8411
  }
8412
+
8413
+ // packages/tooling/src/apps/emu-supabase.ts
8414
+ init_utils();
8415
+ init_cli_output();
8416
+ import {
8417
+ spawn as spawn2,
8418
+ execSync as execSync3
8419
+ } from "node:child_process";
8420
+ import { platform as platform2 } from "node:os";
8421
+ function isDockerRunning() {
8422
+ try {
8423
+ execSync3("docker info", { stdio: "pipe", timeout: 5e3 });
8424
+ return true;
8425
+ } catch {
8426
+ return false;
8427
+ }
8428
+ }
8429
+ async function startSupabase(app, _projectRoot) {
8430
+ log.info(`Starting Supabase local stack + dev server for ${app.name}...
8431
+ `);
8432
+ if (!isDockerRunning()) {
8433
+ log.error("Docker is not running. Supabase local dev requires Docker.");
8434
+ log.error("Start Docker Desktop and try again.\n");
8435
+ return 1;
8436
+ }
8437
+ try {
8438
+ execSync3("supabase --version", { stdio: "pipe" });
8439
+ } catch {
8440
+ log.error("Supabase CLI not found. Install it:");
8441
+ log.error(" npm install -g supabase\n");
8442
+ return 1;
8443
+ }
8444
+ const isWindows = platform2() === "win32";
8445
+ const concurrentlyArgs = [
8446
+ "--kill-others-on-fail",
8447
+ "--prefix-colors",
8448
+ "cyan,green",
8449
+ "--prefix",
8450
+ "[{name}]",
8451
+ "--names",
8452
+ "supabase,dev",
8453
+ "supabase start",
8454
+ `bunx turbo dev --filter=${app.packageName}`
8455
+ ];
8456
+ const childProcess = spawn2(
8457
+ "bunx",
8458
+ ["concurrently", ...concurrentlyArgs],
8459
+ {
8460
+ stdio: "inherit",
8461
+ cwd: app.path,
8462
+ shell: isWindows
8463
+ }
8464
+ );
8465
+ const cleanup = () => {
8466
+ if (!childProcess.pid) return;
8467
+ if (isWindows) {
8468
+ try {
8469
+ execSync3(`taskkill /F /T /PID ${childProcess.pid}`, { stdio: "ignore", timeout: 2e3 });
8470
+ } catch {
8471
+ }
8472
+ } else {
8473
+ try {
8474
+ process.kill(childProcess.pid, "SIGTERM");
8475
+ } catch {
8476
+ }
8477
+ }
8478
+ };
8479
+ process.on("SIGINT", () => {
8480
+ cleanup();
8481
+ process.exit(130);
8482
+ });
8483
+ process.on("SIGTERM", () => {
8484
+ cleanup();
8485
+ process.exit(143);
8486
+ });
8487
+ return new Promise((resolve4) => {
8488
+ childProcess.on("exit", (code) => resolve4(code ?? 0));
8489
+ childProcess.on("error", (error2) => {
8490
+ log.error(`Failed to start Supabase local dev: ${error2.message}`);
8491
+ resolve4(1);
8492
+ });
8493
+ });
8494
+ }
8495
+
8496
+ // packages/tooling/src/apps/emu-vercel.ts
8497
+ init_utils();
8498
+ init_cli_output();
8499
+ import {
8500
+ spawn as spawn3,
8501
+ execSync as execSync4
8502
+ } from "node:child_process";
8503
+ import { platform as platform3 } from "node:os";
8504
+ async function startVercel(app, _projectRoot) {
8505
+ log.info(`Starting Vercel dev server for ${app.name}...
8506
+ `);
8507
+ try {
8508
+ execSync4("vercel --version", { stdio: "pipe" });
8509
+ } catch {
8510
+ log.error("Vercel CLI not found. Install it:");
8511
+ log.error(" npm install -g vercel\n");
8512
+ return 1;
8513
+ }
8514
+ const isWindows = platform3() === "win32";
8515
+ const childProcess = spawn3(
8516
+ "vercel",
8517
+ ["dev"],
8518
+ {
8519
+ stdio: "inherit",
8520
+ cwd: app.path,
8521
+ shell: isWindows
8522
+ }
8523
+ );
8524
+ const cleanup = () => {
8525
+ if (!childProcess.pid) return;
8526
+ if (isWindows) {
8527
+ try {
8528
+ execSync4(`taskkill /F /T /PID ${childProcess.pid}`, { stdio: "ignore", timeout: 2e3 });
8529
+ } catch {
8530
+ }
8531
+ } else {
8532
+ try {
8533
+ process.kill(childProcess.pid, "SIGTERM");
8534
+ } catch {
8535
+ }
8536
+ }
8537
+ };
8538
+ process.on("SIGINT", () => {
8539
+ cleanup();
8540
+ process.exit(130);
8541
+ });
8542
+ process.on("SIGTERM", () => {
8543
+ cleanup();
8544
+ process.exit(143);
8545
+ });
8546
+ return new Promise((resolve4) => {
8547
+ childProcess.on("exit", (code) => resolve4(code ?? 0));
8548
+ childProcess.on("error", (error2) => {
8549
+ log.error(`Failed to start Vercel dev: ${error2.message}`);
8550
+ resolve4(1);
8551
+ });
8552
+ });
8553
+ }
8554
+
8555
+ // packages/tooling/src/apps/emu.ts
8556
+ async function main(options) {
8557
+ const args = process.argv.slice(2);
8558
+ const projectRoot = getRepoRoot();
8559
+ if (!projectRoot) {
8560
+ throw new DoNotDevError(
8561
+ "Could not determine repository root",
8562
+ "path-resolution-error"
8563
+ );
8564
+ }
8565
+ const appName = args.find(
8566
+ (arg) => arg !== "emu" && arg !== "--debug" && !arg.startsWith("--")
8567
+ );
8568
+ const app = await selectApp(projectRoot, appName);
8569
+ if (!app) {
8570
+ return 1;
8571
+ }
8572
+ switch (app.platform) {
8573
+ case "firebase": {
8574
+ if (!app.hasFunctions) {
8575
+ log.error(`App "${app.name}" has Firebase config but no functions directory.`);
8576
+ log.error('Use "dndev dev" for apps without backend functions.\n');
8577
+ return 1;
8578
+ }
8579
+ const selectedServices = parseFirebaseServices(args, options);
8580
+ return startFirebase(app, projectRoot, {
8581
+ debug: options?.debug ?? false,
8582
+ selectedServices
8583
+ });
8584
+ }
8585
+ case "supabase":
8586
+ return startSupabase(app, projectRoot);
8587
+ case "vercel":
8588
+ return startVercel(app, projectRoot);
8589
+ default:
8590
+ log.error(`App "${app.name}" does not have a detected backend platform.`);
8591
+ log.error(
8592
+ "Expected: firebase.json (Firebase), supabase/config.toml or @donotdev/supabase (Supabase), or vercel.json (Vercel)."
8593
+ );
8594
+ log.error('Use "dndev dev" for apps without a backend.\n');
8595
+ return 1;
8596
+ }
8597
+ }
8598
+ function parseFirebaseServices(args, options) {
8599
+ const validServices = ["auth", "functions", "firestore", "stripe"];
8600
+ let selectedServices = [];
8601
+ if (options?.services) {
8602
+ selectedServices = options.services.split(",").map((s) => s.trim());
8603
+ } else {
8604
+ const servicesArg = args.find((arg) => arg.startsWith("--services="));
8605
+ if (servicesArg) {
8606
+ const servicesList = servicesArg.split("=")[1];
8607
+ if (servicesList) {
8608
+ selectedServices = servicesList.split(",").map((s) => s.trim());
8609
+ }
8610
+ } else {
8611
+ if (options?.auth || args.includes("--auth"))
8612
+ selectedServices.push("auth");
8613
+ if (args.includes("--functions")) selectedServices.push("functions");
8614
+ if (options?.firestore || args.includes("--firestore"))
8615
+ selectedServices.push("firestore");
8616
+ if (options?.stripe || args.includes("--stripe"))
8617
+ selectedServices.push("stripe");
8618
+ }
8619
+ }
8620
+ return selectedServices.filter((s) => validServices.includes(s));
8621
+ }
8432
8622
  export {
8433
8623
  main
8434
8624
  };