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.
- package/dist/index.js +1 -2
- package/dist/lib/code-generator.d.ts +80 -0
- package/dist/lib/code-generator.js +541 -0
- package/dist/lib/create-project.js +57 -84
- package/dist/lib/framework-utils.d.ts +22 -0
- package/dist/lib/framework-utils.js +74 -0
- package/dist/lib/utils/module-discovery.d.ts +62 -0
- package/dist/lib/utils/module-discovery.js +180 -0
- package/modules/auth/authjs/files/lib/auth.ts +0 -5
- package/modules/auth/authjs/module.json +6 -79
- package/modules/auth/better-auth/files/lib/auth.ts +17 -3
- package/modules/auth/better-auth/files/schemas/prisma-schema.prisma +6 -6
- package/modules/auth/better-auth/generator.json +83 -0
- package/modules/auth/better-auth/module.json +6 -160
- package/modules/database/mongoose/files/lib/db.ts +2 -7
- package/modules/database/mongoose/generator.json +33 -0
- package/modules/database/mongoose/module.json +6 -46
- package/modules/database/prisma/files/lib/prisma.ts +9 -4
- package/modules/database/prisma/generator.json +46 -0
- package/modules/database/prisma/module.json +6 -114
- package/package.json +1 -1
- package/templates/express/template.json +6 -19
- package/templates/nextjs/template.json +5 -1
- package/templates/react-vite/template.json +6 -14
- package/dist/lib/utils/config-utils.d.ts +0 -2
- package/dist/lib/utils/config-utils.js +0 -88
- package/dist/lib/utils/file-utils.d.ts +0 -8
- package/dist/lib/utils/file-utils.js +0 -75
- package/dist/lib/utils/module-utils.d.ts +0 -2
- package/dist/lib/utils/module-utils.js +0 -461
|
@@ -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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 && !
|
|
55
|
-
throw new Error(`Invalid database: ${db}. Valid options: ${
|
|
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 =
|
|
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
|
|
80
|
+
let prismaProvider;
|
|
74
81
|
if (db && db !== "none") {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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: "
|
|
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")
|
|
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
|
-
:
|
|
230
|
-
|
|
231
|
-
auth:
|
|
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
|
-
|
|
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",
|