@donotdev/cli 0.0.17 → 0.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dependencies-matrix.json +166 -58
  2. package/dist/bin/commands/create-app.js +89 -140
  3. package/dist/bin/commands/create-project.js +90 -144
  4. package/dist/bin/dndev.js +9 -6
  5. package/dist/bin/donotdev.js +9 -6
  6. package/dist/index.js +97 -148
  7. package/package.json +1 -1
  8. package/templates/root-consumer/.claude/commands/brainstorm.md.example +15 -1
  9. package/templates/root-consumer/.claude/commands/build.md.example +24 -2
  10. package/templates/root-consumer/.claude/commands/design.md.example +17 -0
  11. package/templates/root-consumer/.claude/commands/polish.md.example +17 -0
  12. package/templates/root-consumer/AI.md.example +50 -18
  13. package/templates/root-consumer/guides/dndev/SETUP_PAGES.md.example +64 -0
  14. package/templates/root-consumer/guides/wai-way/blueprints/0_brainstorm.md.example +1 -1
  15. package/templates/functions-firebase/functions-firebase/README.md.example +0 -123
  16. package/templates/functions-firebase/functions-firebase/build.mjs.example +0 -5
  17. package/templates/functions-firebase/functions-firebase/src/auth/getCustomClaims.ts.example +0 -19
  18. package/templates/functions-firebase/functions-firebase/src/auth/getUserAuthStatus.ts.example +0 -21
  19. package/templates/functions-firebase/functions-firebase/src/auth/index.ts.example +0 -11
  20. package/templates/functions-firebase/functions-firebase/src/auth/removeCustomClaims.ts.example +0 -21
  21. package/templates/functions-firebase/functions-firebase/src/auth/setCustomClaims.ts.example +0 -21
  22. package/templates/functions-firebase/functions-firebase/src/billing/handleStripeWebhook.ts.example +0 -24
  23. package/templates/functions-firebase/functions-firebase/src/billing/index.ts.example +0 -10
  24. package/templates/functions-firebase/functions-firebase/src/billing/processPaymentSuccess.ts.example +0 -14
  25. package/templates/functions-firebase/functions-firebase/src/billing/refreshSubscriptionStatus.ts.example +0 -14
  26. package/templates/functions-firebase/functions-firebase/src/index.ts.example +0 -39
  27. package/templates/functions-firebase/functions-firebase/src/oauth/checkGitHubAccess.ts.example +0 -14
  28. package/templates/functions-firebase/functions-firebase/src/oauth/disconnect.ts.example +0 -14
  29. package/templates/functions-firebase/functions-firebase/src/oauth/exchangeToken.ts.example +0 -14
  30. package/templates/functions-firebase/functions-firebase/src/oauth/getConnections.ts.example +0 -14
  31. package/templates/functions-firebase/functions-firebase/src/oauth/grantGitHubAccess.ts.example +0 -14
  32. package/templates/functions-firebase/functions-firebase/src/oauth/index.ts.example +0 -17
  33. package/templates/functions-firebase/functions-firebase/src/oauth/refreshToken.ts.example +0 -14
  34. package/templates/functions-firebase/functions-firebase/src/oauth/revokeGitHubAccess.ts.example +0 -14
  35. package/templates/functions-firebase/functions-firebase/tsconfig.json.example +0 -21
  36. package/templates/functions-vercel/functions-vercel/README.md.example +0 -116
  37. package/templates/functions-vercel/functions-vercel/build.mjs.example +0 -52
  38. package/templates/functions-vercel/functions-vercel/src/api/auth/getCustomClaims.ts.example +0 -20
  39. package/templates/functions-vercel/functions-vercel/src/api/auth/getUserAuthStatus.ts.example +0 -20
  40. package/templates/functions-vercel/functions-vercel/src/api/auth/removeCustomClaims.ts.example +0 -20
  41. package/templates/functions-vercel/functions-vercel/src/api/auth/setCustomClaims.ts.example +0 -20
  42. package/templates/functions-vercel/functions-vercel/src/api/billing/handleStripeWebhook.ts.example +0 -20
  43. package/templates/functions-vercel/functions-vercel/src/api/billing/processPaymentSuccess.ts.example +0 -20
  44. package/templates/functions-vercel/functions-vercel/src/api/billing/refreshSubscriptionStatus.ts.example +0 -20
  45. package/templates/functions-vercel/functions-vercel/src/api/crud/createEntity.ts.example +0 -20
  46. package/templates/functions-vercel/functions-vercel/src/api/crud/deleteEntity.ts.example +0 -20
  47. package/templates/functions-vercel/functions-vercel/src/api/crud/getEntity.ts.example +0 -20
  48. package/templates/functions-vercel/functions-vercel/src/api/crud/listEntities.ts.example +0 -20
  49. package/templates/functions-vercel/functions-vercel/src/api/crud/updateEntity.ts.example +0 -20
  50. package/templates/functions-vercel/functions-vercel/src/api/oauth/checkGitHubAccess.ts.example +0 -20
  51. package/templates/functions-vercel/functions-vercel/src/api/oauth/disconnect.ts.example +0 -20
  52. package/templates/functions-vercel/functions-vercel/src/api/oauth/exchangeToken.ts.example +0 -20
  53. package/templates/functions-vercel/functions-vercel/src/api/oauth/getConnections.ts.example +0 -20
  54. package/templates/functions-vercel/functions-vercel/src/api/oauth/grantGitHubAccess.ts.example +0 -20
  55. package/templates/functions-vercel/functions-vercel/src/api/oauth/refreshToken.ts.example +0 -20
  56. package/templates/functions-vercel/functions-vercel/src/api/oauth/revokeGitHubAccess.ts.example +0 -20
  57. package/templates/functions-vercel/functions-vercel/tsconfig.json.example +0 -21
  58. package/templates/functions-vercel/functions-vercel/vercel.json.example +0 -14
  59. package/templates/github/github/workflows/firebase-deploy.yml.example +0 -79
  60. /package/templates/functions-firebase/{functions-firebase/.env.example.example → .env.example} +0 -0
  61. /package/templates/functions-vercel/{functions-vercel/.env.example.example → .env.example} +0 -0
@@ -8475,34 +8475,67 @@ var APP_QUESTIONNAIRE = [
8475
8475
  ]
8476
8476
  },
8477
8477
  {
8478
- id: "needsBackend",
8479
- question: "Include backend functions?",
8480
- type: "confirm",
8481
- defaultValue: false
8478
+ id: "host",
8479
+ question: "Where will you host?",
8480
+ type: "select",
8481
+ condition: (answers) => answers.framework !== "expo",
8482
+ defaultValue: (answers) => {
8483
+ return answers.framework === "nextjs" ? "vercel" : "none";
8484
+ },
8485
+ choices: [
8486
+ { title: "None \u2014 no hosting config", value: "none" },
8487
+ { title: "Vercel \u2014 edge CDN + serverless", value: "vercel" },
8488
+ { title: "Firebase Hosting \u2014 Google CDN", value: "firebase" }
8489
+ ]
8490
+ },
8491
+ {
8492
+ id: "functions",
8493
+ question: "Serverless functions?",
8494
+ type: "select",
8495
+ defaultValue: "none",
8496
+ // Choices filtered dynamically based on host
8497
+ choices: [
8498
+ { title: "None", value: "none" },
8499
+ { title: "Vercel Functions \u2014 edge + node.js", value: "vercel" },
8500
+ { title: "Firebase Functions \u2014 Google Cloud", value: "firebase" },
8501
+ { title: "Supabase Edge Functions \u2014 Deno", value: "supabase" }
8502
+ ],
8503
+ choicesFilter: (answers) => {
8504
+ const host = answers.host ?? "none";
8505
+ const framework = answers.framework;
8506
+ if (framework === "expo") return ["none", "firebase", "supabase"];
8507
+ if (host === "firebase") return ["none", "firebase"];
8508
+ if (host === "vercel") return ["none", "vercel", "supabase"];
8509
+ return ["none", "vercel", "firebase", "supabase"];
8510
+ }
8482
8511
  },
8483
8512
  {
8484
- id: "backendPlatform",
8485
- question: "Which backend platform?",
8513
+ id: "backend",
8514
+ question: "Backend / BaaS provider?",
8486
8515
  type: "select",
8487
- dependsOn: "needsBackend",
8488
- condition: (answers) => answers.needsBackend === true,
8489
8516
  defaultValue: (answers) => {
8490
- return answers.framework === "nextjs" ? "vercel" : "firebase";
8517
+ if (answers.functions === "firebase") return "firebase";
8518
+ if (answers.functions === "supabase") return "supabase";
8519
+ return "none";
8491
8520
  },
8492
8521
  choices: [
8522
+ { title: "None \u2014 frontend only", value: "none" },
8493
8523
  {
8494
- title: "Firebase \u2014 Full-stack platform (hosting + functions + auth + firestore)",
8524
+ title: "Firebase \u2014 Auth + Firestore + Storage",
8495
8525
  value: "firebase"
8496
8526
  },
8497
- {
8498
- title: "Vercel \u2014 Serverless functions (edge + node.js)",
8499
- value: "vercel"
8500
- },
8501
8527
  {
8502
8528
  title: "Supabase \u2014 Postgres + Auth + Storage",
8503
8529
  value: "supabase"
8504
8530
  }
8505
- ]
8531
+ ],
8532
+ choicesFilter: (answers) => {
8533
+ const functions = answers.functions ?? "none";
8534
+ if (functions === "firebase") return ["none", "firebase"];
8535
+ if (functions === "supabase") return ["none", "supabase"];
8536
+ if (functions === "vercel") return ["none"];
8537
+ return ["none", "firebase", "supabase"];
8538
+ }
8506
8539
  }
8507
8540
  ];
8508
8541
  var PROJECT_QUESTIONNAIRE = [
@@ -8520,12 +8553,13 @@ var PROJECT_QUESTIONNAIRE = [
8520
8553
  }
8521
8554
  ];
8522
8555
  function aggregateRequirements(answers) {
8556
+ const hasBackend = answers.backend && answers.backend !== "none" || answers.functions && answers.functions !== "none";
8523
8557
  const requirements = {
8524
8558
  entities: [],
8525
8559
  // Entities created in apps/<app>/entities/ (v1), root entities/ for v2
8526
8560
  billing: true,
8527
8561
  // Always on (useStripeBillingSafe handles missing package)
8528
- backend: answers.needsBackend || false,
8562
+ backend: hasBackend,
8529
8563
  features: [],
8530
8564
  template: "vite",
8531
8565
  // Only Vite for now
@@ -8549,6 +8583,10 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
8549
8583
  if (!showWIP) {
8550
8584
  choices = choices.filter((choice) => !choice.wip);
8551
8585
  }
8586
+ if (question.choicesFilter) {
8587
+ const allowed = question.choicesFilter(answers);
8588
+ choices = choices.filter((c) => allowed.includes(c.value));
8589
+ }
8552
8590
  if (choices.length === 0) continue;
8553
8591
  answer = await askFor.selection(question.question, choices);
8554
8592
  break;
@@ -8749,120 +8787,22 @@ init_pathResolver();
8749
8787
 
8750
8788
  // packages/tooling/src/scaffolding/scaffold-matrix.ts
8751
8789
  init_utils();
8752
- var MATRIX = [
8753
- {
8754
- builder: "vite",
8755
- backend: "none",
8756
- baseTemplate: "app-vite",
8757
- overlay: null,
8758
- deployConfig: null,
8759
- functionsTemplate: null
8760
- },
8761
- {
8762
- builder: "vite",
8763
- backend: "firebase",
8764
- baseTemplate: "app-vite",
8765
- overlay: "overlay-firebase",
8766
- deployConfig: "firebase",
8767
- functionsTemplate: "functions-firebase"
8768
- },
8769
- {
8770
- builder: "vite",
8771
- backend: "supabase",
8772
- baseTemplate: "app-vite",
8773
- overlay: "overlay-supabase",
8774
- deployConfig: "vercel-supabase",
8775
- functionsTemplate: "functions-supabase"
8776
- },
8777
- {
8778
- builder: "vite",
8779
- backend: "vercel",
8780
- baseTemplate: "app-vite",
8781
- overlay: "overlay-vercel",
8782
- deployConfig: "vercel-vercel",
8783
- functionsTemplate: "functions-vercel"
8784
- },
8785
- {
8786
- builder: "nextjs",
8787
- backend: "none",
8788
- baseTemplate: "app-next",
8789
- overlay: null,
8790
- deployConfig: null,
8791
- functionsTemplate: null
8792
- },
8793
- {
8794
- builder: "nextjs",
8795
- backend: "firebase",
8796
- baseTemplate: "app-next",
8797
- overlay: "overlay-firebase",
8798
- deployConfig: "firebase",
8799
- functionsTemplate: "functions-firebase"
8800
- },
8801
- {
8802
- builder: "nextjs",
8803
- backend: "supabase",
8804
- baseTemplate: "app-next",
8805
- overlay: "overlay-supabase",
8806
- deployConfig: "vercel-supabase",
8807
- functionsTemplate: "functions-supabase"
8808
- },
8809
- {
8810
- builder: "nextjs",
8811
- backend: "vercel",
8812
- baseTemplate: "app-next",
8813
- overlay: "overlay-vercel",
8814
- deployConfig: "vercel-vercel",
8815
- functionsTemplate: "functions-vercel"
8816
- },
8817
- {
8818
- builder: "expo",
8819
- backend: "none",
8820
- baseTemplate: "app-expo",
8821
- overlay: null,
8822
- deployConfig: null,
8823
- functionsTemplate: null
8824
- },
8825
- {
8826
- builder: "expo",
8827
- backend: "firebase",
8828
- baseTemplate: "app-expo",
8829
- overlay: "overlay-firebase",
8830
- deployConfig: null,
8831
- functionsTemplate: "functions-firebase"
8832
- },
8833
- {
8834
- builder: "expo",
8835
- backend: "supabase",
8836
- baseTemplate: "app-expo",
8837
- overlay: "overlay-supabase",
8838
- deployConfig: null,
8839
- functionsTemplate: "functions-supabase"
8840
- },
8841
- {
8842
- builder: "demo",
8843
- backend: "none",
8844
- baseTemplate: "app-demo",
8845
- overlay: null,
8846
- deployConfig: null,
8847
- functionsTemplate: null
8848
- }
8849
- ];
8850
- function comboKey(builder, backend) {
8851
- return `${builder}-${backend}`;
8790
+ function resolveDeployConfig(host, backend) {
8791
+ if (host === "none") return null;
8792
+ if (host === "firebase") return "firebase";
8793
+ if (backend === "supabase") return "vercel-supabase";
8794
+ return "vercel-vercel";
8852
8795
  }
8853
- var ROWS_BY_KEY = /* @__PURE__ */ new Map();
8854
- for (const row of MATRIX) {
8855
- ROWS_BY_KEY.set(comboKey(row.builder, row.backend), row);
8856
- }
8857
- function getScaffoldRow(builder, backend) {
8858
- const key = comboKey(builder, backend);
8859
- const row = ROWS_BY_KEY.get(key);
8860
- if (!row) {
8861
- throw new Error(
8862
- `Unsupported scaffold combo: ${key}. Supported: ${[...ROWS_BY_KEY.keys()].join(", ")}`
8863
- );
8864
- }
8865
- return row;
8796
+ function getScaffoldParts(builder, host, functions, backend) {
8797
+ const baseTemplate = builder === "nextjs" ? "app-next" : builder === "demo" ? "app-demo" : `app-${builder}`;
8798
+ return {
8799
+ builder,
8800
+ backend,
8801
+ baseTemplate,
8802
+ overlay: backend !== "none" ? `overlay-${backend}` : null,
8803
+ deployConfig: resolveDeployConfig(host, backend),
8804
+ functionsTemplate: functions !== "none" ? `functions-${functions}` : null
8805
+ };
8866
8806
  }
8867
8807
 
8868
8808
  // packages/tooling/src/scaffolding/create-app.ts
@@ -8902,11 +8842,15 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8902
8842
  input: askForInput
8903
8843
  });
8904
8844
  const requirements = aggregateRequirements(answers);
8905
- const defaultPlatform = answers.framework === "nextjs" ? "vercel" : "firebase";
8845
+ const framework = answers.framework || "vite";
8846
+ const host2 = answers.host || "none";
8847
+ const functions2 = answers.functions || "none";
8848
+ const backend2 = answers.backend || "none";
8906
8849
  appConfig = {
8907
- template: answers.framework || "vite",
8908
- needsBackend: answers.needsBackend || false,
8909
- backendPlatform: answers.needsBackend ? answers.backendPlatform || defaultPlatform : void 0,
8850
+ template: framework,
8851
+ host: host2,
8852
+ functions: functions2,
8853
+ backend: backend2,
8910
8854
  needsCRUD: true,
8911
8855
  // Always on
8912
8856
  selectedEntities: [],
@@ -8952,12 +8896,14 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
8952
8896
  s.start(`Creating app: ${appName}`);
8953
8897
  await ensureDir(appDir);
8954
8898
  const builder = appTemplate;
8955
- const backend = appConfig.needsBackend && appConfig.backendPlatform ? appConfig.backendPlatform : "none";
8956
- const row = getScaffoldRow(builder, backend);
8899
+ const host = appConfig.host ?? "none";
8900
+ const functions = appConfig.functions ?? "none";
8901
+ const backend = appConfig.backend ?? "none";
8902
+ const row = getScaffoldParts(builder, host, functions, backend);
8957
8903
  const templateDir = row.baseTemplate;
8958
8904
  const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
8959
8905
  const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
8960
- const backendPlatform = appConfig.backendPlatform ?? "firebase";
8906
+ const backendPlatform = backend !== "none" ? backend : "firebase";
8961
8907
  const deployConfig = row.deployConfig;
8962
8908
  const replacements = {
8963
8909
  projectName: appName,
@@ -9295,11 +9241,13 @@ Happy coding!`,
9295
9241
  }
9296
9242
  async function main(options) {
9297
9243
  try {
9298
- const hasExplicitFlags = options?.builder !== void 0 || options?.functions !== void 0;
9244
+ const hasExplicitFlags = options?.builder !== void 0 || options?.host !== void 0 || options?.functions !== void 0 || options?.backend !== void 0;
9299
9245
  if (hasExplicitFlags && options?.name) {
9300
9246
  const appName = options.name;
9301
9247
  const builder = options.builder || "vite";
9302
- const includeFunctions = options.functions ?? false;
9248
+ const hostOpt = options.host ?? "none";
9249
+ const functionsOpt = options.functions ?? "none";
9250
+ const backendOpt = options.backend ?? "none";
9303
9251
  if (!isValidFileName(appName)) {
9304
9252
  throw new Error(
9305
9253
  `Invalid app name "${appName}". Use only letters, numbers, dashes (-), and underscores (_).`
@@ -9312,8 +9260,9 @@ async function main(options) {
9312
9260
  }
9313
9261
  const appConfig = {
9314
9262
  template: builder === "next" ? "nextjs" : builder === "expo" ? "expo" : "vite",
9315
- needsBackend: includeFunctions,
9316
- backendPlatform: includeFunctions ? "firebase" : void 0,
9263
+ host: hostOpt,
9264
+ functions: functionsOpt,
9265
+ backend: backendOpt,
9317
9266
  needsCRUD: true,
9318
9267
  selectedEntities: [],
9319
9268
  userAuth: "social",
@@ -8795,34 +8795,67 @@ var APP_QUESTIONNAIRE = [
8795
8795
  ]
8796
8796
  },
8797
8797
  {
8798
- id: "needsBackend",
8799
- question: "Include backend functions?",
8800
- type: "confirm",
8801
- defaultValue: false
8798
+ id: "host",
8799
+ question: "Where will you host?",
8800
+ type: "select",
8801
+ condition: (answers) => answers.framework !== "expo",
8802
+ defaultValue: (answers) => {
8803
+ return answers.framework === "nextjs" ? "vercel" : "none";
8804
+ },
8805
+ choices: [
8806
+ { title: "None \u2014 no hosting config", value: "none" },
8807
+ { title: "Vercel \u2014 edge CDN + serverless", value: "vercel" },
8808
+ { title: "Firebase Hosting \u2014 Google CDN", value: "firebase" }
8809
+ ]
8810
+ },
8811
+ {
8812
+ id: "functions",
8813
+ question: "Serverless functions?",
8814
+ type: "select",
8815
+ defaultValue: "none",
8816
+ // Choices filtered dynamically based on host
8817
+ choices: [
8818
+ { title: "None", value: "none" },
8819
+ { title: "Vercel Functions \u2014 edge + node.js", value: "vercel" },
8820
+ { title: "Firebase Functions \u2014 Google Cloud", value: "firebase" },
8821
+ { title: "Supabase Edge Functions \u2014 Deno", value: "supabase" }
8822
+ ],
8823
+ choicesFilter: (answers) => {
8824
+ const host = answers.host ?? "none";
8825
+ const framework = answers.framework;
8826
+ if (framework === "expo") return ["none", "firebase", "supabase"];
8827
+ if (host === "firebase") return ["none", "firebase"];
8828
+ if (host === "vercel") return ["none", "vercel", "supabase"];
8829
+ return ["none", "vercel", "firebase", "supabase"];
8830
+ }
8802
8831
  },
8803
8832
  {
8804
- id: "backendPlatform",
8805
- question: "Which backend platform?",
8833
+ id: "backend",
8834
+ question: "Backend / BaaS provider?",
8806
8835
  type: "select",
8807
- dependsOn: "needsBackend",
8808
- condition: (answers) => answers.needsBackend === true,
8809
8836
  defaultValue: (answers) => {
8810
- return answers.framework === "nextjs" ? "vercel" : "firebase";
8837
+ if (answers.functions === "firebase") return "firebase";
8838
+ if (answers.functions === "supabase") return "supabase";
8839
+ return "none";
8811
8840
  },
8812
8841
  choices: [
8842
+ { title: "None \u2014 frontend only", value: "none" },
8813
8843
  {
8814
- title: "Firebase \u2014 Full-stack platform (hosting + functions + auth + firestore)",
8844
+ title: "Firebase \u2014 Auth + Firestore + Storage",
8815
8845
  value: "firebase"
8816
8846
  },
8817
- {
8818
- title: "Vercel \u2014 Serverless functions (edge + node.js)",
8819
- value: "vercel"
8820
- },
8821
8847
  {
8822
8848
  title: "Supabase \u2014 Postgres + Auth + Storage",
8823
8849
  value: "supabase"
8824
8850
  }
8825
- ]
8851
+ ],
8852
+ choicesFilter: (answers) => {
8853
+ const functions = answers.functions ?? "none";
8854
+ if (functions === "firebase") return ["none", "firebase"];
8855
+ if (functions === "supabase") return ["none", "supabase"];
8856
+ if (functions === "vercel") return ["none"];
8857
+ return ["none", "firebase", "supabase"];
8858
+ }
8826
8859
  }
8827
8860
  ];
8828
8861
  var PROJECT_QUESTIONNAIRE = [
@@ -8840,12 +8873,13 @@ var PROJECT_QUESTIONNAIRE = [
8840
8873
  }
8841
8874
  ];
8842
8875
  function aggregateRequirements(answers) {
8876
+ const hasBackend = answers.backend && answers.backend !== "none" || answers.functions && answers.functions !== "none";
8843
8877
  const requirements = {
8844
8878
  entities: [],
8845
8879
  // Entities created in apps/<app>/entities/ (v1), root entities/ for v2
8846
8880
  billing: true,
8847
8881
  // Always on (useStripeBillingSafe handles missing package)
8848
- backend: answers.needsBackend || false,
8882
+ backend: hasBackend,
8849
8883
  features: [],
8850
8884
  template: "vite",
8851
8885
  // Only Vite for now
@@ -8869,6 +8903,10 @@ async function runQuestionnaire(questions, initialAnswers, showWIP, askFor) {
8869
8903
  if (!showWIP) {
8870
8904
  choices = choices.filter((choice) => !choice.wip);
8871
8905
  }
8906
+ if (question.choicesFilter) {
8907
+ const allowed = question.choicesFilter(answers);
8908
+ choices = choices.filter((c) => allowed.includes(c.value));
8909
+ }
8872
8910
  if (choices.length === 0) continue;
8873
8911
  answer = await askFor.selection(question.question, choices);
8874
8912
  break;
@@ -9069,120 +9107,22 @@ init_pathResolver();
9069
9107
 
9070
9108
  // packages/tooling/src/scaffolding/scaffold-matrix.ts
9071
9109
  init_utils();
9072
- var MATRIX = [
9073
- {
9074
- builder: "vite",
9075
- backend: "none",
9076
- baseTemplate: "app-vite",
9077
- overlay: null,
9078
- deployConfig: null,
9079
- functionsTemplate: null
9080
- },
9081
- {
9082
- builder: "vite",
9083
- backend: "firebase",
9084
- baseTemplate: "app-vite",
9085
- overlay: "overlay-firebase",
9086
- deployConfig: "firebase",
9087
- functionsTemplate: "functions-firebase"
9088
- },
9089
- {
9090
- builder: "vite",
9091
- backend: "supabase",
9092
- baseTemplate: "app-vite",
9093
- overlay: "overlay-supabase",
9094
- deployConfig: "vercel-supabase",
9095
- functionsTemplate: "functions-supabase"
9096
- },
9097
- {
9098
- builder: "vite",
9099
- backend: "vercel",
9100
- baseTemplate: "app-vite",
9101
- overlay: "overlay-vercel",
9102
- deployConfig: "vercel-vercel",
9103
- functionsTemplate: "functions-vercel"
9104
- },
9105
- {
9106
- builder: "nextjs",
9107
- backend: "none",
9108
- baseTemplate: "app-next",
9109
- overlay: null,
9110
- deployConfig: null,
9111
- functionsTemplate: null
9112
- },
9113
- {
9114
- builder: "nextjs",
9115
- backend: "firebase",
9116
- baseTemplate: "app-next",
9117
- overlay: "overlay-firebase",
9118
- deployConfig: "firebase",
9119
- functionsTemplate: "functions-firebase"
9120
- },
9121
- {
9122
- builder: "nextjs",
9123
- backend: "supabase",
9124
- baseTemplate: "app-next",
9125
- overlay: "overlay-supabase",
9126
- deployConfig: "vercel-supabase",
9127
- functionsTemplate: "functions-supabase"
9128
- },
9129
- {
9130
- builder: "nextjs",
9131
- backend: "vercel",
9132
- baseTemplate: "app-next",
9133
- overlay: "overlay-vercel",
9134
- deployConfig: "vercel-vercel",
9135
- functionsTemplate: "functions-vercel"
9136
- },
9137
- {
9138
- builder: "expo",
9139
- backend: "none",
9140
- baseTemplate: "app-expo",
9141
- overlay: null,
9142
- deployConfig: null,
9143
- functionsTemplate: null
9144
- },
9145
- {
9146
- builder: "expo",
9147
- backend: "firebase",
9148
- baseTemplate: "app-expo",
9149
- overlay: "overlay-firebase",
9150
- deployConfig: null,
9151
- functionsTemplate: "functions-firebase"
9152
- },
9153
- {
9154
- builder: "expo",
9155
- backend: "supabase",
9156
- baseTemplate: "app-expo",
9157
- overlay: "overlay-supabase",
9158
- deployConfig: null,
9159
- functionsTemplate: "functions-supabase"
9160
- },
9161
- {
9162
- builder: "demo",
9163
- backend: "none",
9164
- baseTemplate: "app-demo",
9165
- overlay: null,
9166
- deployConfig: null,
9167
- functionsTemplate: null
9168
- }
9169
- ];
9170
- function comboKey(builder, backend) {
9171
- return `${builder}-${backend}`;
9172
- }
9173
- var ROWS_BY_KEY = /* @__PURE__ */ new Map();
9174
- for (const row of MATRIX) {
9175
- ROWS_BY_KEY.set(comboKey(row.builder, row.backend), row);
9110
+ function resolveDeployConfig(host, backend) {
9111
+ if (host === "none") return null;
9112
+ if (host === "firebase") return "firebase";
9113
+ if (backend === "supabase") return "vercel-supabase";
9114
+ return "vercel-vercel";
9176
9115
  }
9177
- function getScaffoldRow(builder, backend) {
9178
- const key = comboKey(builder, backend);
9179
- const row = ROWS_BY_KEY.get(key);
9180
- if (!row) {
9181
- throw new Error(
9182
- `Unsupported scaffold combo: ${key}. Supported: ${[...ROWS_BY_KEY.keys()].join(", ")}`
9183
- );
9184
- }
9185
- return row;
9116
+ function getScaffoldParts(builder, host, functions, backend) {
9117
+ const baseTemplate = builder === "nextjs" ? "app-next" : builder === "demo" ? "app-demo" : `app-${builder}`;
9118
+ return {
9119
+ builder,
9120
+ backend,
9121
+ baseTemplate,
9122
+ overlay: backend !== "none" ? `overlay-${backend}` : null,
9123
+ deployConfig: resolveDeployConfig(host, backend),
9124
+ functionsTemplate: functions !== "none" ? `functions-${functions}` : null
9125
+ };
9186
9126
  }
9187
9127
 
9188
9128
  // packages/tooling/src/scaffolding/create-app.ts
@@ -9222,11 +9162,15 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
9222
9162
  input: askForInput
9223
9163
  });
9224
9164
  const requirements = aggregateRequirements(answers);
9225
- const defaultPlatform = answers.framework === "nextjs" ? "vercel" : "firebase";
9165
+ const framework = answers.framework || "vite";
9166
+ const host2 = answers.host || "none";
9167
+ const functions2 = answers.functions || "none";
9168
+ const backend2 = answers.backend || "none";
9226
9169
  appConfig = {
9227
- template: answers.framework || "vite",
9228
- needsBackend: answers.needsBackend || false,
9229
- backendPlatform: answers.needsBackend ? answers.backendPlatform || defaultPlatform : void 0,
9170
+ template: framework,
9171
+ host: host2,
9172
+ functions: functions2,
9173
+ backend: backend2,
9230
9174
  needsCRUD: true,
9231
9175
  // Always on
9232
9176
  selectedEntities: [],
@@ -9272,12 +9216,14 @@ async function createApp(appName, appConfig, workspaceRoot, templatesRoot) {
9272
9216
  s.start(`Creating app: ${appName}`);
9273
9217
  await ensureDir(appDir);
9274
9218
  const builder = appTemplate;
9275
- const backend = appConfig.needsBackend && appConfig.backendPlatform ? appConfig.backendPlatform : "none";
9276
- const row = getScaffoldRow(builder, backend);
9219
+ const host = appConfig.host ?? "none";
9220
+ const functions = appConfig.functions ?? "none";
9221
+ const backend = appConfig.backend ?? "none";
9222
+ const row = getScaffoldParts(builder, host, functions, backend);
9277
9223
  const templateDir = row.baseTemplate;
9278
9224
  const firebaseProjectId = (appConfig?.firebaseProjectId ?? "").trim() || appName.toLowerCase().replace(/\s+/g, "-");
9279
9225
  const firebaseRegion = appConfig?.firebaseRegion ?? "europe-west1";
9280
- const backendPlatform = appConfig.backendPlatform ?? "firebase";
9226
+ const backendPlatform = backend !== "none" ? backend : "firebase";
9281
9227
  const deployConfig = row.deployConfig;
9282
9228
  const replacements = {
9283
9229
  projectName: appName,
@@ -9627,12 +9573,11 @@ async function collectAppConfig(appName) {
9627
9573
  input: askForInput
9628
9574
  });
9629
9575
  const framework = answers.framework || "vite";
9630
- const needsBackend = answers.needsBackend || false;
9631
- const defaultPlatform = framework === "nextjs" ? "vercel" : "firebase";
9632
9576
  return {
9633
9577
  template: framework,
9634
- needsBackend,
9635
- backendPlatform: needsBackend ? answers.backendPlatform || defaultPlatform : void 0,
9578
+ host: answers.host || "none",
9579
+ functions: answers.functions || "none",
9580
+ backend: answers.backend || "none",
9636
9581
  needsCRUD: false,
9637
9582
  selectedEntities: [],
9638
9583
  userAuth: "none",
@@ -9779,7 +9724,7 @@ async function main(options) {
9779
9724
  Me(`Configuring "${trimmedName}"...`, "\u2699\uFE0F");
9780
9725
  const config = await collectAppConfig(trimmedName);
9781
9726
  appConfigs[trimmedName] = config;
9782
- if (config.needsBackend) anyAppNeedsBackend = true;
9727
+ if (config.backend !== "none" || config.functions !== "none") anyAppNeedsBackend = true;
9783
9728
  }
9784
9729
  let installDemoApp = await askForConfirmation(
9785
9730
  "Would you like to install the demo app? (component showcase)",
@@ -9855,8 +9800,9 @@ async function main(options) {
9855
9800
  log.warn(`Missing config for app "${appName}", using defaults`);
9856
9801
  appConfigs[appName] = {
9857
9802
  template: "vite",
9858
- needsBackend: false,
9859
- backendPlatform: void 0,
9803
+ host: "none",
9804
+ functions: "none",
9805
+ backend: "none",
9860
9806
  needsCRUD: false,
9861
9807
  selectedEntities: [],
9862
9808
  userAuth: "none",
@@ -9904,7 +9850,7 @@ async function main(options) {
9904
9850
  overwrite: true
9905
9851
  });
9906
9852
  const relativeMonorepoPath = executionMode === "development" ? calculateRelativePath(projectDirNormalized, monorepoRoot) : "";
9907
- const primaryPlatform = Object.values(appConfigs).find((c) => c.backendPlatform)?.backendPlatform ?? "firebase";
9853
+ const primaryPlatform = Object.values(appConfigs).find((c) => c.backend !== "none")?.backend ?? "firebase";
9908
9854
  const rootPackageJson = generatePackageJson(
9909
9855
  "consumer-root",
9910
9856
  executionMode,