create-stackkit-app 0.4.5 → 0.4.6

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.
@@ -10,12 +10,13 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
10
10
  const inquirer_1 = __importDefault(require("inquirer"));
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const validate_npm_package_name_1 = __importDefault(require("validate-npm-package-name"));
13
- const file_utils_1 = require("./utils/file-utils");
14
13
  const git_utils_1 = require("./utils/git-utils");
15
14
  const js_conversion_1 = require("./utils/js-conversion");
16
15
  const logger_1 = require("./utils/logger");
17
- const module_utils_1 = require("./utils/module-utils");
16
+ const code_generator_1 = require("./code-generator");
17
+ const framework_utils_1 = require("./framework-utils");
18
18
  const package_utils_1 = require("./utils/package-utils");
19
+ const module_discovery_1 = require("./utils/module-discovery");
19
20
  async function createProject(projectName, options) {
20
21
  logger_1.logger.newLine();
21
22
  logger_1.logger.log(chalk_1.default.bold.cyan("Create StackKit App"));
@@ -31,30 +32,36 @@ async function createProject(projectName, options) {
31
32
  showNextSteps(config);
32
33
  }
33
34
  async function getProjectConfig(projectName, options) {
35
+ // Discover available modules
36
+ const modulesDir = path_1.default.join(__dirname, "..", "..", "modules");
37
+ const discoveredModules = await (0, module_discovery_1.discoverModules)(modulesDir);
34
38
  if (options && Object.keys(options).length > 0) {
35
39
  if (options.yes || options.y) {
36
40
  return {
37
41
  projectName: projectName || "my-app",
38
42
  framework: "nextjs",
39
43
  database: "prisma",
40
- dbProvider: "postgresql",
44
+ prismaProvider: "postgresql",
41
45
  auth: "better-auth",
42
46
  language: "typescript",
43
47
  packageManager: "pnpm",
44
48
  };
45
49
  }
46
- // Validate options
47
- const validFrameworks = ['nextjs', 'express', 'react-vite'];
50
+ // Validate options using discovered modules
51
+ const validFrameworks = discoveredModules.frameworks.map(f => f.name);
48
52
  const framework = options.framework || options.f;
49
53
  if (framework && !validFrameworks.includes(framework)) {
50
54
  throw new Error(`Invalid framework: ${framework}. Valid options: ${validFrameworks.join(', ')}`);
51
55
  }
52
- const validDatabases = ['prisma-postgresql', 'prisma-mongodb', 'prisma-mysql', 'prisma-sqlite', 'mongoose-mongodb', 'none'];
56
+ const validDatabases = (0, module_discovery_1.getValidDatabaseOptions)(discoveredModules.databases);
57
+ // Also allow base database names like 'prisma', 'mongoose'
58
+ const validBaseDatabases = discoveredModules.databases.map(db => db.name);
59
+ const allValidDatabases = [...validDatabases, ...validBaseDatabases];
53
60
  const db = options.database || options.d;
54
- if (db && !validDatabases.includes(db)) {
55
- throw new Error(`Invalid database: ${db}. Valid options: ${validDatabases.join(', ')}`);
61
+ if (db && !allValidDatabases.includes(db)) {
62
+ throw new Error(`Invalid database: ${db}. Valid options: ${allValidDatabases.filter((v, i, arr) => arr.indexOf(v) === i).join(', ')}`);
56
63
  }
57
- const validAuth = ['better-auth', 'authjs', 'none'];
64
+ const validAuth = (0, module_discovery_1.getValidAuthOptions)(discoveredModules.auth);
58
65
  const authOpt = options.auth || options.a;
59
66
  if (authOpt && !validAuth.includes(authOpt)) {
60
67
  throw new Error(`Invalid auth: ${authOpt}. Valid options: ${validAuth.join(', ')}`);
@@ -70,22 +77,11 @@ async function getProjectConfig(projectName, options) {
70
77
  throw new Error(`Invalid package manager: ${pm}. Valid options: ${validPackageManagers.join(', ')}`);
71
78
  }
72
79
  let database = "none";
73
- let dbProvider;
80
+ let prismaProvider;
74
81
  if (db && db !== "none") {
75
- if (db.startsWith("prisma-")) {
76
- database = "prisma";
77
- const provider = db.split("-")[1];
78
- if (!["postgresql", "mongodb", "mysql", "sqlite"].includes(provider)) {
79
- throw new Error(`Invalid Prisma provider: ${provider}`);
80
- }
81
- dbProvider = provider;
82
- }
83
- else if (db === "mongoose-mongodb") {
84
- database = "mongoose";
85
- }
86
- else {
87
- throw new Error(`Unsupported database: ${db}`);
88
- }
82
+ const parsed = (0, module_discovery_1.parseDatabaseOption)(db);
83
+ database = parsed.database;
84
+ prismaProvider = parsed.provider;
89
85
  }
90
86
  let auth = "none";
91
87
  if (authOpt && authOpt !== "none") {
@@ -94,7 +90,7 @@ async function getProjectConfig(projectName, options) {
94
90
  const finalFramework = (framework || "nextjs");
95
91
  if (finalFramework === "react-vite") {
96
92
  database = "none";
97
- dbProvider = undefined;
93
+ prismaProvider = undefined;
98
94
  }
99
95
  // Validate auth compatibility
100
96
  if (auth === "authjs" && (database !== "prisma" || finalFramework !== "nextjs")) {
@@ -107,12 +103,13 @@ async function getProjectConfig(projectName, options) {
107
103
  projectName: projectName || "my-app",
108
104
  framework: finalFramework,
109
105
  database,
110
- dbProvider,
106
+ prismaProvider,
111
107
  auth,
112
108
  language: (language || "typescript"),
113
109
  packageManager: (pm || "pnpm"),
114
110
  };
115
111
  }
112
+ // Use discovered modules for interactive prompts
116
113
  const answers = (await inquirer_1.default.prompt([
117
114
  {
118
115
  type: "input",
@@ -135,26 +132,21 @@ async function getProjectConfig(projectName, options) {
135
132
  type: "list",
136
133
  name: "framework",
137
134
  message: "Select framework:",
138
- choices: [
139
- { name: "Next.js", value: "nextjs" },
140
- { name: "Express.js", value: "express" },
141
- { name: "React (Vite)", value: "react-vite" },
142
- ],
135
+ choices: discoveredModules.frameworks.map(f => ({
136
+ name: f.displayName,
137
+ value: f.name
138
+ })),
143
139
  },
144
140
  {
145
141
  type: "list",
146
142
  name: "database",
147
143
  message: "Select database/ORM:",
148
144
  when: (answers) => answers.framework !== "react-vite",
149
- choices: [
150
- { name: "Prisma", value: "prisma" },
151
- { name: "Mongoose (MongoDB)", value: "mongoose" },
152
- { name: "None", value: "none" },
153
- ],
145
+ choices: (answers) => (0, module_discovery_1.getDatabaseChoices)(discoveredModules.databases, answers.framework),
154
146
  },
155
147
  {
156
148
  type: "list",
157
- name: "dbProvider",
149
+ name: "prismaProvider",
158
150
  message: "Select database provider for Prisma:",
159
151
  when: (answers) => answers.database === "prisma",
160
152
  choices: [
@@ -168,35 +160,8 @@ async function getProjectConfig(projectName, options) {
168
160
  type: "list",
169
161
  name: "auth",
170
162
  message: "Select authentication:",
171
- when: (answers) => (answers.database !== "none" || answers.framework === "react-vite") && answers.database !== "mongoose",
172
- choices: (answers) => {
173
- if (answers.framework === "react-vite") {
174
- return [
175
- { name: "Better Auth", value: "better-auth" },
176
- { name: "None", value: "none" },
177
- ];
178
- }
179
- if (answers.database === "mongoose") {
180
- return [
181
- { name: "Better Auth", value: "better-auth" },
182
- { name: "None", value: "none" },
183
- ];
184
- }
185
- if (answers.framework === "nextjs" && answers.database === "prisma") {
186
- return [
187
- { name: "Better Auth", value: "better-auth" },
188
- { name: "Auth.js", value: "authjs" },
189
- { name: "None", value: "none" },
190
- ];
191
- }
192
- if (answers.framework === "express" && answers.database === "prisma") {
193
- return [
194
- { name: "Better Auth", value: "better-auth" },
195
- { name: "None", value: "none" },
196
- ];
197
- }
198
- return [{ name: "None", value: "none" }];
199
- },
163
+ when: (answers) => (answers.database !== "none" || answers.framework === "react-vite"),
164
+ choices: (answers) => (0, module_discovery_1.getCompatibleAuthOptions)(discoveredModules.auth, answers.framework, answers.database || "none"),
200
165
  },
201
166
  {
202
167
  type: "list",
@@ -221,14 +186,15 @@ async function getProjectConfig(projectName, options) {
221
186
  default: "pnpm",
222
187
  },
223
188
  ]));
189
+ const parsedDb = answers.database ? (0, module_discovery_1.parseDatabaseOption)(answers.database) : { database: 'none' };
224
190
  return {
225
191
  projectName: (projectName || answers.projectName),
226
192
  framework: answers.framework,
227
193
  database: (answers.framework === "react-vite"
228
194
  ? "none"
229
- : answers.database),
230
- dbProvider: answers.dbProvider,
231
- auth: answers.database === "mongoose" ? "better-auth" : (answers.auth || "none"),
195
+ : parsedDb.database),
196
+ prismaProvider: answers.prismaProvider || parsedDb.provider,
197
+ auth: (answers.auth || "none"),
232
198
  language: answers.language,
233
199
  packageManager: answers.packageManager,
234
200
  };
@@ -284,8 +250,28 @@ async function generateProject(config, targetDir, options) {
284
250
  }
285
251
  async function composeTemplate(config, targetDir) {
286
252
  const templatesDir = path_1.default.join(__dirname, "..", "..", "templates");
253
+ const modulesDir = path_1.default.join(__dirname, "..", "..", "modules");
287
254
  await fs_extra_1.default.ensureDir(targetDir);
288
- await (0, file_utils_1.copyBaseFramework)(templatesDir, targetDir, config.framework);
255
+ // Load framework configuration
256
+ const frameworkConfig = await framework_utils_1.FrameworkUtils.loadFrameworkConfig(config.framework, templatesDir);
257
+ // Initialize advanced code generator
258
+ const generator = new code_generator_1.AdvancedCodeGenerator(frameworkConfig);
259
+ await generator.loadGenerators(modulesDir);
260
+ // Generate project using advanced code generator
261
+ const features = [];
262
+ const postInstallCommands = await generator.generate({
263
+ framework: config.framework,
264
+ database: config.database === 'none' ? undefined : config.database,
265
+ auth: config.auth === 'none' ? undefined : config.auth,
266
+ prismaProvider: config.prismaProvider,
267
+ }, features, targetDir);
268
+ // Update project name in package.json
269
+ const packageJsonPath = path_1.default.join(targetDir, "package.json");
270
+ if (await fs_extra_1.default.pathExists(packageJsonPath)) {
271
+ const packageJson = await fs_extra_1.default.readJson(packageJsonPath);
272
+ packageJson.name = config.projectName;
273
+ await fs_extra_1.default.writeJson(packageJsonPath, packageJson, { spaces: 2 });
274
+ }
289
275
  // Ensure .env exists: if .env.example was copied from the template, create .env from it
290
276
  try {
291
277
  const envExamplePath = path_1.default.join(targetDir, ".env.example");
@@ -298,23 +284,10 @@ async function composeTemplate(config, targetDir) {
298
284
  catch {
299
285
  // non-fatal
300
286
  }
301
- const postInstallCommands = [];
302
- if (config.database !== "none") {
303
- const dbPostInstall = await (0, module_utils_1.mergeDatabaseConfig)(templatesDir, targetDir, config.database, config.framework, config.dbProvider);
304
- postInstallCommands.push(...dbPostInstall);
305
- }
306
- if (config.auth !== "none") {
307
- await (0, module_utils_1.mergeAuthConfig)(templatesDir, targetDir, config.framework, config.auth, config.database, config.dbProvider);
308
- }
309
- const packageJsonPath = path_1.default.join(targetDir, "package.json");
310
- if (await fs_extra_1.default.pathExists(packageJsonPath)) {
311
- const packageJson = await fs_extra_1.default.readJson(packageJsonPath);
312
- packageJson.name = config.projectName;
313
- await fs_extra_1.default.writeJson(packageJsonPath, packageJson, { spaces: 2 });
314
- }
315
287
  if (config.language === "javascript") {
316
288
  await (0, js_conversion_1.convertToJavaScript)(targetDir, config.framework);
317
289
  }
290
+ // For now, return empty array as post-install commands are handled by the generator
318
291
  return postInstallCommands;
319
292
  }
320
293
  function showNextSteps(config) {
@@ -0,0 +1,22 @@
1
+ export interface FrameworkConfig {
2
+ name: string;
3
+ displayName: string;
4
+ compatibility: {
5
+ databases: string[];
6
+ auth: string[];
7
+ };
8
+ }
9
+ export interface ModuleConfig {
10
+ name: string;
11
+ displayName: string;
12
+ type: 'database' | 'auth';
13
+ compatibility?: {
14
+ frameworks?: string[];
15
+ databases?: string[];
16
+ };
17
+ }
18
+ export declare class FrameworkUtils {
19
+ private static frameworkConfigs;
20
+ static loadFrameworkConfig(frameworkName: string, templatesDir: string): Promise<FrameworkConfig>;
21
+ static isCompatible(framework: string, database?: string, auth?: string): boolean;
22
+ }
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FrameworkUtils = void 0;
37
+ const fs = __importStar(require("fs-extra"));
38
+ const path = __importStar(require("path"));
39
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
40
+ class FrameworkUtils {
41
+ static async loadFrameworkConfig(frameworkName, templatesDir) {
42
+ const configPath = path.join(templatesDir, frameworkName, 'template.json');
43
+ if (await fs.pathExists(configPath)) {
44
+ const config = await fs.readJson(configPath);
45
+ this.frameworkConfigs.set(frameworkName, config);
46
+ return config;
47
+ }
48
+ // Default config if no template.json exists
49
+ const defaultConfig = {
50
+ name: frameworkName,
51
+ displayName: frameworkName.charAt(0).toUpperCase() + frameworkName.slice(1),
52
+ compatibility: {
53
+ databases: ['prisma', 'mongoose'],
54
+ auth: ['better-auth', 'authjs'],
55
+ },
56
+ };
57
+ this.frameworkConfigs.set(frameworkName, defaultConfig);
58
+ return defaultConfig;
59
+ }
60
+ static isCompatible(framework, database, auth) {
61
+ const config = this.frameworkConfigs.get(framework);
62
+ if (!config)
63
+ return true; // Assume compatible if no config
64
+ if (database && !config.compatibility.databases.includes(database)) {
65
+ return false;
66
+ }
67
+ if (auth && !config.compatibility.auth.includes(auth)) {
68
+ return false;
69
+ }
70
+ return true;
71
+ }
72
+ }
73
+ exports.FrameworkUtils = FrameworkUtils;
74
+ FrameworkUtils.frameworkConfigs = new Map();
@@ -0,0 +1,62 @@
1
+ export interface ModuleMetadata {
2
+ name: string;
3
+ displayName: string;
4
+ description: string;
5
+ category: string;
6
+ provider?: string;
7
+ supportedFrameworks?: string[];
8
+ databaseAdapters?: Record<string, unknown>;
9
+ frameworkConfigs?: Record<string, unknown>;
10
+ dependencies?: Record<string, unknown>;
11
+ devDependencies?: Record<string, unknown>;
12
+ envVars?: Record<string, unknown>;
13
+ patches?: unknown[];
14
+ postInstall?: string[];
15
+ compatibility?: {
16
+ databases?: string[];
17
+ auth?: string[];
18
+ languages?: string[];
19
+ };
20
+ framework?: string;
21
+ files?: string[];
22
+ scripts?: Record<string, string>;
23
+ jsScripts?: Record<string, string>;
24
+ }
25
+ export interface DiscoveredModules {
26
+ frameworks: ModuleMetadata[];
27
+ databases: ModuleMetadata[];
28
+ auth: ModuleMetadata[];
29
+ }
30
+ /**
31
+ * Discover all available modules from the modules directory
32
+ */
33
+ export declare function discoverModules(modulesDir: string): Promise<DiscoveredModules>;
34
+ /**
35
+ * Get valid database options for CLI
36
+ */
37
+ export declare function getValidDatabaseOptions(databases: ModuleMetadata[]): string[];
38
+ /**
39
+ * Get valid auth options for CLI
40
+ */
41
+ export declare function getValidAuthOptions(authModules: ModuleMetadata[]): string[];
42
+ /**
43
+ * Parse database option into database name and provider
44
+ */
45
+ export declare function parseDatabaseOption(dbOption: string): {
46
+ database: string;
47
+ provider?: string;
48
+ };
49
+ /**
50
+ * Get compatible auth options for given framework and database
51
+ */
52
+ export declare function getCompatibleAuthOptions(authModules: ModuleMetadata[], framework: string, database: string): Array<{
53
+ name: string;
54
+ value: string;
55
+ }>;
56
+ /**
57
+ * Get database choices for inquirer prompts
58
+ */
59
+ export declare function getDatabaseChoices(databases: ModuleMetadata[], framework: string): Array<{
60
+ name: string;
61
+ value: string;
62
+ }>;
@@ -0,0 +1,180 @@
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.discoverModules = discoverModules;
7
+ exports.getValidDatabaseOptions = getValidDatabaseOptions;
8
+ exports.getValidAuthOptions = getValidAuthOptions;
9
+ exports.parseDatabaseOption = parseDatabaseOption;
10
+ exports.getCompatibleAuthOptions = getCompatibleAuthOptions;
11
+ exports.getDatabaseChoices = getDatabaseChoices;
12
+ const fs_extra_1 = __importDefault(require("fs-extra"));
13
+ const path_1 = __importDefault(require("path"));
14
+ /**
15
+ * Discover all available modules from the modules directory
16
+ */
17
+ async function discoverModules(modulesDir) {
18
+ const discovered = {
19
+ frameworks: [],
20
+ databases: [],
21
+ auth: [],
22
+ };
23
+ if (!(await fs_extra_1.default.pathExists(modulesDir))) {
24
+ return discovered;
25
+ }
26
+ // Discover frameworks from templates directory
27
+ const templatesDir = path_1.default.join(modulesDir, '..', 'templates');
28
+ if (await fs_extra_1.default.pathExists(templatesDir)) {
29
+ const frameworkDirs = await fs_extra_1.default.readdir(templatesDir);
30
+ for (const frameworkName of frameworkDirs) {
31
+ const templateJsonPath = path_1.default.join(templatesDir, frameworkName, 'template.json');
32
+ if (await fs_extra_1.default.pathExists(templateJsonPath)) {
33
+ try {
34
+ const templateConfig = await fs_extra_1.default.readJson(templateJsonPath);
35
+ discovered.frameworks.push({
36
+ ...templateConfig,
37
+ name: frameworkName,
38
+ category: 'framework',
39
+ });
40
+ }
41
+ catch {
42
+ // Silently skip invalid templates
43
+ }
44
+ }
45
+ }
46
+ }
47
+ // Discover database modules
48
+ const databaseDir = path_1.default.join(modulesDir, 'database');
49
+ if (await fs_extra_1.default.pathExists(databaseDir)) {
50
+ const dbModules = await fs_extra_1.default.readdir(databaseDir);
51
+ for (const moduleName of dbModules) {
52
+ const modulePath = path_1.default.join(databaseDir, moduleName);
53
+ const moduleJsonPath = path_1.default.join(modulePath, 'module.json');
54
+ if (await fs_extra_1.default.pathExists(moduleJsonPath)) {
55
+ try {
56
+ const metadata = await fs_extra_1.default.readJson(moduleJsonPath);
57
+ discovered.databases.push(metadata);
58
+ }
59
+ catch {
60
+ // Silently skip invalid modules
61
+ }
62
+ }
63
+ }
64
+ }
65
+ // Discover auth modules
66
+ const authDir = path_1.default.join(modulesDir, 'auth');
67
+ if (await fs_extra_1.default.pathExists(authDir)) {
68
+ const authModules = await fs_extra_1.default.readdir(authDir);
69
+ for (const moduleName of authModules) {
70
+ const modulePath = path_1.default.join(authDir, moduleName);
71
+ const moduleJsonPath = path_1.default.join(modulePath, 'module.json');
72
+ if (await fs_extra_1.default.pathExists(moduleJsonPath)) {
73
+ try {
74
+ const metadata = await fs_extra_1.default.readJson(moduleJsonPath);
75
+ discovered.auth.push(metadata);
76
+ }
77
+ catch {
78
+ // Silently skip invalid modules
79
+ }
80
+ }
81
+ }
82
+ }
83
+ return discovered;
84
+ }
85
+ /**
86
+ * Get valid database options for CLI
87
+ */
88
+ function getValidDatabaseOptions(databases) {
89
+ const options = ['none'];
90
+ for (const db of databases) {
91
+ if (db.name === 'prisma') {
92
+ // For Prisma, add provider-specific options
93
+ options.push('prisma-postgresql', 'prisma-mongodb', 'prisma-mysql', 'prisma-sqlite');
94
+ }
95
+ else if (db.name === 'mongoose') {
96
+ options.push('mongoose-mongodb');
97
+ }
98
+ else {
99
+ // For other databases, add the name directly
100
+ options.push(db.name);
101
+ }
102
+ }
103
+ return options;
104
+ }
105
+ /**
106
+ * Get valid auth options for CLI
107
+ */
108
+ function getValidAuthOptions(authModules) {
109
+ const options = ['none'];
110
+ for (const auth of authModules) {
111
+ options.push(auth.name);
112
+ }
113
+ return options;
114
+ }
115
+ /**
116
+ * Parse database option into database name and provider
117
+ */
118
+ function parseDatabaseOption(dbOption) {
119
+ if (dbOption === 'none') {
120
+ return { database: 'none' };
121
+ }
122
+ if (dbOption.startsWith('prisma-')) {
123
+ const provider = dbOption.split('-')[1];
124
+ return { database: 'prisma', provider };
125
+ }
126
+ if (dbOption === 'mongoose-mongodb') {
127
+ return { database: 'mongoose' };
128
+ }
129
+ return { database: dbOption };
130
+ }
131
+ /**
132
+ * Get compatible auth options for given framework and database
133
+ */
134
+ function getCompatibleAuthOptions(authModules, framework, database) {
135
+ const compatible = [];
136
+ for (const auth of authModules) {
137
+ // Check if auth supports the framework
138
+ if (auth.supportedFrameworks && !auth.supportedFrameworks.includes(framework)) {
139
+ continue;
140
+ }
141
+ // Special compatibility rules
142
+ if (auth.name === 'authjs' && (database !== 'prisma' || framework !== 'nextjs')) {
143
+ continue;
144
+ }
145
+ if (auth.name === 'better-auth' && database === 'none' && framework !== 'react-vite') {
146
+ continue;
147
+ }
148
+ compatible.push({
149
+ name: auth.displayName,
150
+ value: auth.name
151
+ });
152
+ }
153
+ // Add "None" at the end
154
+ compatible.push({ name: 'None', value: 'none' });
155
+ return compatible;
156
+ }
157
+ /**
158
+ * Get database choices for inquirer prompts
159
+ */
160
+ function getDatabaseChoices(databases, framework) {
161
+ const choices = [];
162
+ for (const db of databases) {
163
+ // Check framework compatibility
164
+ if (db.supportedFrameworks && !db.supportedFrameworks.includes(framework)) {
165
+ continue;
166
+ }
167
+ if (db.name === 'prisma') {
168
+ 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' });
169
+ }
170
+ else if (db.name === 'mongoose') {
171
+ choices.push({ name: 'Mongoose (MongoDB)', value: 'mongoose-mongodb' });
172
+ }
173
+ else {
174
+ choices.push({ name: db.displayName, value: db.name });
175
+ }
176
+ }
177
+ // Add "None" at the end
178
+ choices.push({ name: 'None', value: 'none' });
179
+ return choices;
180
+ }
@@ -2,7 +2,6 @@ import { NextAuthOptions } from "next-auth";
2
2
  import { PrismaAdapter } from "@auth/prisma-adapter";
3
3
  import { prisma } from "@/lib/prisma";
4
4
  import GoogleProvider from "next-auth/providers/google";
5
- import GitHubProvider from "next-auth/providers/github";
6
5
 
7
6
  export const authOptions: NextAuthOptions = {
8
7
  adapter: PrismaAdapter(prisma),
@@ -11,10 +10,6 @@ export const authOptions: NextAuthOptions = {
11
10
  clientId: process.env.GOOGLE_CLIENT_ID!,
12
11
  clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
13
12
  }),
14
- GitHubProvider({
15
- clientId: process.env.GITHUB_ID!,
16
- clientSecret: process.env.GITHUB_SECRET!,
17
- }),
18
13
  ],
19
14
  session: {
20
15
  strategy: "jwt",