stackkit 0.2.0 → 0.2.2

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.
@@ -8,6 +8,7 @@ const chalk_1 = __importDefault(require("chalk"));
8
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const logger_1 = require("../lib/ui/logger");
11
+ const package_root_1 = require("../lib/utils/package-root");
11
12
  // Constants for consistent messaging
12
13
  const MESSAGES = {
13
14
  NO_PACKAGE_JSON: "No package.json found in current directory or any parent directory.",
@@ -211,24 +212,125 @@ function checkNodeVersion() {
211
212
  function detectAuthModules(packageJson) {
212
213
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
213
214
  const modules = [];
214
- if (deps["better-auth"]) {
215
- modules.push("better-auth");
215
+ try {
216
+ const modulesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "modules", "auth");
217
+ if (fs_extra_1.default.existsSync(modulesDir)) {
218
+ const authDirs = fs_extra_1.default.readdirSync(modulesDir);
219
+ for (const authDir of authDirs) {
220
+ try {
221
+ const genPath = path_1.default.join(modulesDir, authDir, "generator.json");
222
+ const modJson = path_1.default.join(modulesDir, authDir, "module.json");
223
+ let pkgNames = [];
224
+ if (fs_extra_1.default.existsSync(genPath)) {
225
+ const gen = JSON.parse(fs_extra_1.default.readFileSync(genPath, "utf-8"));
226
+ if (Array.isArray(gen.operations)) {
227
+ for (const op of gen.operations) {
228
+ if (op.dependencies && typeof op.dependencies === "object") {
229
+ pkgNames.push(...Object.keys(op.dependencies));
230
+ }
231
+ if (op.devDependencies && typeof op.devDependencies === "object") {
232
+ pkgNames.push(...Object.keys(op.devDependencies));
233
+ }
234
+ }
235
+ }
236
+ }
237
+ // Fallback: check module.json provider/name
238
+ let moduleName = authDir;
239
+ if (fs_extra_1.default.existsSync(modJson)) {
240
+ try {
241
+ const m = JSON.parse(fs_extra_1.default.readFileSync(modJson, "utf-8"));
242
+ if (m && m.name)
243
+ moduleName = m.name;
244
+ }
245
+ catch {
246
+ /* ignore */
247
+ }
248
+ }
249
+ for (const pkg of pkgNames) {
250
+ if (deps[pkg]) {
251
+ modules.push(moduleName);
252
+ break;
253
+ }
254
+ }
255
+ }
256
+ catch {
257
+ // ignore per-module errors
258
+ }
259
+ }
260
+ }
216
261
  }
217
- if (deps["next-auth"]) {
218
- modules.push("authjs");
262
+ catch {
263
+ // ignore discovery errors
219
264
  }
220
- return modules;
265
+ // Fallback to original simple checks if nothing found
266
+ if (modules.length === 0) {
267
+ if (deps["better-auth"])
268
+ modules.push("better-auth");
269
+ if (deps["next-auth"])
270
+ modules.push("authjs");
271
+ }
272
+ return Array.from(new Set(modules));
221
273
  }
222
274
  function detectDatabaseModules(packageJson) {
223
275
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
224
276
  const modules = [];
225
- if (deps["@prisma/client"] || deps["prisma"]) {
226
- modules.push("prisma");
277
+ try {
278
+ const modulesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "modules", "database");
279
+ if (fs_extra_1.default.existsSync(modulesDir)) {
280
+ const dbDirs = fs_extra_1.default.readdirSync(modulesDir);
281
+ for (const dbDir of dbDirs) {
282
+ try {
283
+ const genPath = path_1.default.join(modulesDir, dbDir, "generator.json");
284
+ const modJson = path_1.default.join(modulesDir, dbDir, "module.json");
285
+ let pkgNames = [];
286
+ if (fs_extra_1.default.existsSync(genPath)) {
287
+ const gen = JSON.parse(fs_extra_1.default.readFileSync(genPath, "utf-8"));
288
+ if (Array.isArray(gen.operations)) {
289
+ for (const op of gen.operations) {
290
+ if (op.dependencies && typeof op.dependencies === "object") {
291
+ pkgNames.push(...Object.keys(op.dependencies));
292
+ }
293
+ if (op.devDependencies && typeof op.devDependencies === "object") {
294
+ pkgNames.push(...Object.keys(op.devDependencies));
295
+ }
296
+ }
297
+ }
298
+ }
299
+ let moduleName = dbDir;
300
+ if (fs_extra_1.default.existsSync(modJson)) {
301
+ try {
302
+ const m = JSON.parse(fs_extra_1.default.readFileSync(modJson, "utf-8"));
303
+ if (m && m.name)
304
+ moduleName = m.name;
305
+ }
306
+ catch {
307
+ /* ignore */
308
+ }
309
+ }
310
+ for (const pkg of pkgNames) {
311
+ if (deps[pkg]) {
312
+ modules.push(moduleName);
313
+ break;
314
+ }
315
+ }
316
+ }
317
+ catch {
318
+ // ignore per-module errors
319
+ }
320
+ }
321
+ }
322
+ }
323
+ catch {
324
+ // ignore discovery errors
227
325
  }
228
- if (deps["mongoose"]) {
229
- modules.push("mongoose");
326
+ // Fallback to original checks if nothing found
327
+ if (modules.length === 0) {
328
+ if (deps["@prisma/client"] || deps["prisma"])
329
+ modules.push("prisma");
330
+ if (deps["mongoose"])
331
+ modules.push("mongoose");
230
332
  }
231
- return modules;
333
+ return Array.from(new Set(modules));
232
334
  }
233
335
  async function checkKeyFiles(projectRoot, projectType, authModules, databaseModules) {
234
336
  const checks = [];
@@ -260,8 +362,42 @@ async function checkKeyFiles(projectRoot, projectType, authModules, databaseModu
260
362
  async function checkAuthRoutesExist(projectRoot, projectType) {
261
363
  if (projectType !== "nextjs")
262
364
  return true; // Skip for non-Next.js
263
- const possiblePaths = [
264
- // NextAuth routes
365
+ // Build candidate auth route paths from generator.json files in modules/auth
366
+ const candidates = new Set();
367
+ try {
368
+ const authModulesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "modules", "auth");
369
+ if (await fs_extra_1.default.pathExists(authModulesDir)) {
370
+ const authDirs = await fs_extra_1.default.readdir(authModulesDir);
371
+ for (const dir of authDirs) {
372
+ const genPath = path_1.default.join(authModulesDir, dir, "generator.json");
373
+ if (!(await fs_extra_1.default.pathExists(genPath)))
374
+ continue;
375
+ try {
376
+ const gen = await fs_extra_1.default.readJson(genPath);
377
+ if (Array.isArray(gen.operations)) {
378
+ for (const op of gen.operations) {
379
+ if (typeof op.destination === "string")
380
+ candidates.add(op.destination);
381
+ if (Array.isArray(op.operations)) {
382
+ for (const sub of op.operations) {
383
+ if (typeof sub.destination === "string")
384
+ candidates.add(sub.destination);
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+ catch {
391
+ // ignore malformed generator
392
+ }
393
+ }
394
+ }
395
+ }
396
+ catch {
397
+ // ignore discovery errors
398
+ }
399
+ // Fallback to known common paths if generators don't provide any
400
+ const fallback = [
265
401
  "app/api/auth/[...nextauth]/route.ts",
266
402
  "app/api/auth/[...nextauth]/route.js",
267
403
  "src/app/api/auth/[...nextauth]/route.ts",
@@ -270,13 +406,14 @@ async function checkAuthRoutesExist(projectRoot, projectType) {
270
406
  "pages/api/auth/[...nextauth].js",
271
407
  "src/pages/api/auth/[...nextauth].ts",
272
408
  "src/pages/api/auth/[...nextauth].js",
273
- // Better Auth routes
274
409
  "app/api/auth/[...all]/route.ts",
275
410
  "app/api/auth/[...all]/route.js",
276
411
  "src/app/api/auth/[...all]/route.ts",
277
412
  "src/app/api/auth/[...all]/route.js",
278
413
  ];
279
- for (const routePath of possiblePaths) {
414
+ for (const p of fallback)
415
+ candidates.add(p);
416
+ for (const routePath of candidates) {
280
417
  if (await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, routePath))) {
281
418
  return true;
282
419
  }
@@ -288,14 +425,59 @@ async function checkEnvFiles(projectRoot, authModules, databaseModules) {
288
425
  const requiredKeys = [];
289
426
  const missing = [];
290
427
  const present = [];
291
- if (databaseModules.includes("prisma")) {
292
- requiredKeys.push("DATABASE_URL");
293
- }
294
- if (authModules.includes("authjs")) {
295
- requiredKeys.push("NEXTAUTH_SECRET", "NEXTAUTH_URL");
428
+ // Dynamically collect required env keys from generator.json for detected modules
429
+ try {
430
+ const modulesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "modules");
431
+ async function collectEnvKeys(category, name) {
432
+ const genPath = path_1.default.join(modulesDir, category, name, "generator.json");
433
+ if (!(await fs_extra_1.default.pathExists(genPath)))
434
+ return;
435
+ try {
436
+ const gen = await fs_extra_1.default.readJson(genPath);
437
+ if (Array.isArray(gen.operations)) {
438
+ for (const op of gen.operations) {
439
+ if (op.type === "add-env" && op.envVars && typeof op.envVars === "object") {
440
+ for (const k of Object.keys(op.envVars)) {
441
+ if (!requiredKeys.includes(k))
442
+ requiredKeys.push(k);
443
+ }
444
+ }
445
+ // Also check nested operations (e.g., patch-file -> operations)
446
+ if (Array.isArray(op.operations)) {
447
+ for (const sub of op.operations) {
448
+ if (sub.type === "add-env" && sub.envVars && typeof sub.envVars === "object") {
449
+ for (const k of Object.keys(sub.envVars)) {
450
+ if (!requiredKeys.includes(k))
451
+ requiredKeys.push(k);
452
+ }
453
+ }
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ catch {
460
+ // ignore malformed generator
461
+ }
462
+ }
463
+ for (const db of databaseModules) {
464
+ await collectEnvKeys("database", db);
465
+ }
466
+ for (const auth of authModules) {
467
+ await collectEnvKeys("auth", auth);
468
+ }
296
469
  }
297
- if (authModules.includes("better-auth")) {
298
- requiredKeys.push("BETTER_AUTH_SECRET", "BETTER_AUTH_URL");
470
+ catch {
471
+ // fallback to previous minimal checks if discovery fails
472
+ if (databaseModules.includes("prisma")) {
473
+ requiredKeys.push("DATABASE_URL");
474
+ }
475
+ if (authModules.includes("authjs")) {
476
+ requiredKeys.push("NEXTAUTH_SECRET", "NEXTAUTH_URL");
477
+ }
478
+ if (authModules.includes("better-auth")) {
479
+ requiredKeys.push("BETTER_AUTH_SECRET", "BETTER_AUTH_URL");
480
+ }
299
481
  }
300
482
  const envPaths = [".env", ".env.local"];
301
483
  let envContent = "";
package/dist/cli/list.js CHANGED
@@ -7,6 +7,8 @@ exports.listCommand = listCommand;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
8
  const fs_extra_1 = __importDefault(require("fs-extra"));
9
9
  const path_1 = __importDefault(require("path"));
10
+ const module_discovery_1 = require("../lib/discovery/module-discovery");
11
+ const shared_1 = require("../lib/discovery/shared");
10
12
  const logger_1 = require("../lib/ui/logger");
11
13
  const package_root_1 = require("../lib/utils/package-root");
12
14
  async function listCommand(options) {
@@ -34,6 +36,14 @@ async function listCommand(options) {
34
36
  if (showModules) {
35
37
  const modulesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "modules");
36
38
  const modules = await getAvailableModules(modulesDir);
39
+ // Discover modules to derive provider lists dynamically
40
+ let discovered;
41
+ try {
42
+ discovered = await (0, module_discovery_1.discoverModules)(path_1.default.join((0, package_root_1.getPackageRoot)(), "modules"));
43
+ }
44
+ catch {
45
+ discovered = { frameworks: [], databases: [], auth: [] };
46
+ }
37
47
  if (modules.length > 0) {
38
48
  hasModules = true;
39
49
  logger_1.logger.log(chalk_1.default.bold.magenta("MODULES"));
@@ -68,7 +78,33 @@ async function listCommand(options) {
68
78
  : isLastMod
69
79
  ? "│ └──"
70
80
  : "│ ├──";
71
- logger_1.logger.log(` ${chalk_1.default.gray(providerPrefix)} ${chalk_1.default.dim("Providers: PostgreSQL, MongoDB, MySQL, SQLite")}`);
81
+ // Compute provider names from discovered database choices
82
+ const choices = (0, module_discovery_1.getDatabaseChoices)(discovered.databases || [], "nextjs");
83
+ const prismaProviders = choices
84
+ .filter((c) => c.value.startsWith("prisma-"))
85
+ .map((c) => {
86
+ const m = c.name.match(/\(([^)]+)\)/);
87
+ return m ? m[1] : c.name;
88
+ });
89
+ const providersText = prismaProviders.length > 0
90
+ ? prismaProviders.join(", ")
91
+ : (() => {
92
+ const detected = (0, shared_1.getPrismaProvidersFromGenerator)((0, package_root_1.getPackageRoot)()).map((p) => {
93
+ if (p === "postgresql")
94
+ return "PostgreSQL";
95
+ if (p === "mongodb")
96
+ return "MongoDB";
97
+ if (p === "mysql")
98
+ return "MySQL";
99
+ if (p === "sqlite")
100
+ return "SQLite";
101
+ return p;
102
+ });
103
+ return detected.length > 0
104
+ ? detected.join(", ")
105
+ : "PostgreSQL, MongoDB, MySQL, SQLite";
106
+ })();
107
+ logger_1.logger.log(` ${chalk_1.default.gray(providerPrefix)} ${chalk_1.default.dim(`Providers: ${providersText}`)}`);
72
108
  }
73
109
  });
74
110
  });
package/dist/index.js CHANGED
@@ -1,15 +1,113 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  Object.defineProperty(exports, "__esModule", { value: true });
4
37
  const commander_1 = require("commander");
5
- const create_1 = require("./cli/create");
38
+ const fs = __importStar(require("fs"));
39
+ const fs_1 = require("fs");
40
+ const path_1 = require("path");
6
41
  const add_1 = require("./cli/add");
42
+ const create_1 = require("./cli/create");
7
43
  const doctor_1 = require("./cli/doctor");
8
44
  const list_1 = require("./cli/list");
45
+ const shared_1 = require("./lib/discovery/shared");
9
46
  const logger_1 = require("./lib/ui/logger");
10
- const fs_1 = require("fs");
11
- const path_1 = require("path");
47
+ const package_root_1 = require("./lib/utils/package-root");
12
48
  const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, "../package.json"), "utf-8"));
49
+ function buildOptionHints() {
50
+ try {
51
+ const pkgRoot = (0, package_root_1.getPackageRoot)();
52
+ const modulesDir = (0, path_1.join)(pkgRoot, "modules");
53
+ const dbs = [];
54
+ const auths = [];
55
+ if (fs.existsSync((0, path_1.join)(modulesDir, "database"))) {
56
+ for (const d of fs.readdirSync((0, path_1.join)(modulesDir, "database"))) {
57
+ const moduleJson = (0, path_1.join)(modulesDir, "database", d, "module.json");
58
+ if (fs.existsSync(moduleJson)) {
59
+ try {
60
+ const m = JSON.parse((0, fs_1.readFileSync)(moduleJson, "utf-8"));
61
+ if (m && m.name === "prisma") {
62
+ try {
63
+ const providers = (0, shared_1.getPrismaProvidersFromGenerator)((0, package_root_1.getPackageRoot)());
64
+ if (providers.length > 0) {
65
+ for (const p of providers)
66
+ dbs.push(`prisma-${p}`);
67
+ }
68
+ else {
69
+ dbs.push("prisma");
70
+ }
71
+ }
72
+ catch {
73
+ dbs.push("prisma");
74
+ }
75
+ }
76
+ else if (m && m.name) {
77
+ dbs.push(m.name);
78
+ }
79
+ }
80
+ catch {
81
+ /* ignore */
82
+ }
83
+ }
84
+ }
85
+ }
86
+ if (fs.existsSync((0, path_1.join)(modulesDir, "auth"))) {
87
+ for (const a of fs.readdirSync((0, path_1.join)(modulesDir, "auth"))) {
88
+ const moduleJson = (0, path_1.join)(modulesDir, "auth", a, "module.json");
89
+ if (fs.existsSync(moduleJson)) {
90
+ try {
91
+ const m = JSON.parse((0, fs_1.readFileSync)(moduleJson, "utf-8"));
92
+ if (m && m.name)
93
+ auths.push(m.name);
94
+ }
95
+ catch {
96
+ /* ignore */
97
+ }
98
+ }
99
+ }
100
+ }
101
+ return {
102
+ databaseHint: dbs.length > 0 ? dbs.join(", ") : "prisma, mongoose, none",
103
+ authHint: auths.length > 0 ? auths.join(", ") : "better-auth, authjs, none",
104
+ };
105
+ }
106
+ catch {
107
+ return { databaseHint: "prisma, mongoose, none", authHint: "better-auth, authjs, none" };
108
+ }
109
+ }
110
+ const hints = buildOptionHints();
13
111
  const program = new commander_1.Command();
14
112
  program
15
113
  .name("stackkit")
@@ -37,9 +135,9 @@ program
37
135
  .description("Create a new StackKit project")
38
136
  .usage("[project-name] [options]")
39
137
  .option("-f, --framework <framework>", "Framework: nextjs, express, react")
40
- .option("-d, --database <database>", "Database: prisma, mongoose, none")
41
- .option("--prisma-provider <provider>", "Prisma provider: postgresql, mongodb, mysql, sqlite")
42
- .option("-a, --auth <auth>", "Auth: better-auth, authjs, none")
138
+ .option("-d, --database <database>", `Database: ${hints.databaseHint}`)
139
+ .option("--prisma-provider <provider>", "Prisma provider")
140
+ .option("-a, --auth <auth>", `Auth: ${hints.authHint}`)
43
141
  .option("-l, --language <language>", "Language: typescript, javascript")
44
142
  .option("-p, --package-manager <pm>", "Package manager: pnpm, npm, yarn, bun")
45
143
  .option("--skip-install", "Skip dependency installation")
@@ -38,13 +38,6 @@ export declare function getValidDatabaseOptions(databases: ModuleMetadata[]): st
38
38
  * Get valid auth options for CLI
39
39
  */
40
40
  export declare function getValidAuthOptions(authModules: ModuleMetadata[]): string[];
41
- /**
42
- * Parse database option into database name and provider
43
- */
44
- export declare function parseDatabaseOption(dbOption: string): {
45
- database: string;
46
- provider?: string;
47
- };
48
41
  /**
49
42
  * Get compatible auth options for given framework and database
50
43
  */
@@ -6,12 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.discoverModules = discoverModules;
7
7
  exports.getValidDatabaseOptions = getValidDatabaseOptions;
8
8
  exports.getValidAuthOptions = getValidAuthOptions;
9
- exports.parseDatabaseOption = parseDatabaseOption;
10
9
  exports.getCompatibleAuthOptions = getCompatibleAuthOptions;
11
10
  exports.getDatabaseChoices = getDatabaseChoices;
12
11
  const fs_extra_1 = __importDefault(require("fs-extra"));
13
12
  const path_1 = __importDefault(require("path"));
14
13
  const package_root_1 = require("../utils/package-root");
14
+ const shared_1 = require("./shared");
15
15
  /**
16
16
  * Discover all available modules from the modules directory
17
17
  */
@@ -119,11 +119,17 @@ function getValidDatabaseOptions(databases) {
119
119
  const options = ["none"];
120
120
  for (const db of databases) {
121
121
  if (db.name === "prisma") {
122
- // For Prisma, add provider-specific options
123
- options.push("prisma-postgresql", "prisma-mongodb", "prisma-mysql", "prisma-sqlite");
122
+ const providers = (0, shared_1.getPrismaProvidersFromGenerator)();
123
+ if (providers.length > 0) {
124
+ for (const p of providers)
125
+ options.push(`prisma-${p}`);
126
+ }
127
+ else {
128
+ options.push("prisma");
129
+ }
124
130
  }
125
131
  else if (db.name === "mongoose") {
126
- options.push("mongoose", "mongoose");
132
+ options.push("mongoose");
127
133
  }
128
134
  else {
129
135
  // For other databases, add the name directly
@@ -142,22 +148,7 @@ function getValidAuthOptions(authModules) {
142
148
  }
143
149
  return options;
144
150
  }
145
- /**
146
- * Parse database option into database name and provider
147
- */
148
- function parseDatabaseOption(dbOption) {
149
- if (dbOption === "none") {
150
- return { database: "none" };
151
- }
152
- if (dbOption.startsWith("prisma-")) {
153
- const provider = dbOption.split("-")[1];
154
- return { database: "prisma", provider };
155
- }
156
- if (dbOption === "mongoose" || dbOption === "mongoose") {
157
- return { database: "mongoose" };
158
- }
159
- return { database: dbOption };
160
- }
151
+ // parseDatabaseOption moved to shared helpers
161
152
  /**
162
153
  * Get compatible auth options for given framework and database
163
154
  */
@@ -168,11 +159,13 @@ function getCompatibleAuthOptions(authModules, framework, database) {
168
159
  if (auth.supportedFrameworks && !auth.supportedFrameworks.includes(framework)) {
169
160
  continue;
170
161
  }
162
+ // Normalize database option (handle prisma-<provider> values)
163
+ const parsedDb = (0, shared_1.parseDatabaseOption)(database || "").database;
171
164
  // Special compatibility rules
172
- if (auth.name === "authjs" && (database !== "prisma" || framework !== "nextjs")) {
165
+ if (auth.name === "authjs" && (parsedDb !== "prisma" || framework !== "nextjs")) {
173
166
  continue;
174
167
  }
175
- if (auth.name === "better-auth" && database === "none" && framework !== "react") {
168
+ if (auth.name === "better-auth" && parsedDb === "none" && framework !== "react") {
176
169
  continue;
177
170
  }
178
171
  compatible.push({
@@ -195,7 +188,17 @@ function getDatabaseChoices(databases, framework) {
195
188
  continue;
196
189
  }
197
190
  if (db.name === "prisma") {
198
- choices.push({ name: "Prisma (PostgreSQL)", value: "prisma-postgresql" }, { name: "Prisma (MongoDB)", value: "prisma-mongodb" }, { name: "Prisma (MySQL)", value: "prisma-mysql" }, { name: "Prisma (SQLite)", value: "prisma-sqlite" });
191
+ const providers = (0, shared_1.getPrismaProvidersFromGenerator)();
192
+ if (providers.length > 0) {
193
+ for (const p of providers)
194
+ choices.push({
195
+ name: `Prisma (${p.charAt(0).toUpperCase() + p.slice(1)})`,
196
+ value: `prisma-${p}`,
197
+ });
198
+ }
199
+ else {
200
+ choices.push({ name: "Prisma", value: "prisma" });
201
+ }
199
202
  }
200
203
  else if (db.name === "mongoose") {
201
204
  choices.push({ name: "Mongoose", value: "mongoose" });
@@ -0,0 +1,6 @@
1
+ export declare function parseDatabaseOption(dbOption: string): {
2
+ database: string;
3
+ provider?: string;
4
+ };
5
+ export declare function getPrismaProvidersFromGenerator(modulesDir?: string): string[];
6
+ export declare function isPrismaOption(value: string): boolean;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseDatabaseOption = parseDatabaseOption;
7
+ exports.getPrismaProvidersFromGenerator = getPrismaProvidersFromGenerator;
8
+ exports.isPrismaOption = isPrismaOption;
9
+ const path_1 = __importDefault(require("path"));
10
+ const package_root_1 = require("../utils/package-root");
11
+ function parseDatabaseOption(dbOption) {
12
+ if (!dbOption)
13
+ return { database: "none" };
14
+ if (dbOption === "none")
15
+ return { database: "none" };
16
+ if (dbOption.startsWith("prisma-")) {
17
+ const provider = dbOption.split("-")[1];
18
+ return { database: "prisma", provider };
19
+ }
20
+ if (dbOption === "prisma")
21
+ return { database: "prisma" };
22
+ if (dbOption === "mongoose")
23
+ return { database: "mongoose" };
24
+ return { database: dbOption };
25
+ }
26
+ function getPrismaProvidersFromGenerator(modulesDir) {
27
+ const pkgRoot = modulesDir || (0, package_root_1.getPackageRoot)();
28
+ const genPath = path_1.default.join(pkgRoot, "modules", "database", "prisma", "generator.json");
29
+ try {
30
+ const gen = require(genPath);
31
+ const providers = new Set();
32
+ if (Array.isArray(gen.operations)) {
33
+ for (const op of gen.operations) {
34
+ if (op.condition && op.condition.prismaProvider)
35
+ providers.add(String(op.condition.prismaProvider));
36
+ }
37
+ }
38
+ return Array.from(providers);
39
+ }
40
+ catch {
41
+ return [];
42
+ }
43
+ }
44
+ function isPrismaOption(value) {
45
+ if (!value)
46
+ return false;
47
+ if (value === "prisma")
48
+ return true;
49
+ return value.startsWith("prisma-");
50
+ }