stackkit 0.1.4 → 0.1.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/README.md +1 -1
- package/dist/cli/add.js +146 -105
- package/dist/cli/create.d.ts +2 -2
- package/dist/cli/create.js +94 -27
- package/dist/cli/doctor.js +42 -17
- package/dist/cli/list.js +14 -2
- package/dist/index.js +16 -16
- package/dist/lib/conversion/js-conversion.js +1 -1
- package/dist/lib/discovery/module-discovery.js +35 -35
- package/dist/lib/env/env-editor.js +1 -1
- package/dist/lib/framework/framework-utils.d.ts +1 -1
- package/dist/lib/framework/framework-utils.js +3 -3
- package/dist/lib/generation/code-generator.d.ts +5 -5
- package/dist/lib/generation/code-generator.js +166 -132
- package/dist/lib/generation/generator-utils.d.ts +2 -2
- package/dist/lib/generation/generator-utils.js +28 -15
- package/dist/lib/utils/package-root.js +2 -2
- package/modules/auth/authjs/generator.json +1 -2
- package/modules/auth/better-auth/files/lib/auth.ts +37 -30
- package/modules/auth/better-auth/files/prisma/schema.prisma +3 -3
- package/modules/auth/better-auth/generator.json +46 -16
- package/modules/database/mongoose/generator.json +23 -4
- package/modules/database/prisma/files/lib/prisma.ts +26 -21
- package/modules/database/prisma/files/prisma.config.ts +17 -0
- package/modules/database/prisma/generator.json +50 -11
- package/package.json +3 -1
- package/templates/express/src/server.ts +9 -3
- package/templates/express/tsconfig.json +2 -2
- package/templates/nextjs/lib/env.ts +1 -1
package/dist/cli/doctor.js
CHANGED
|
@@ -96,7 +96,7 @@ async function runDoctorChecks() {
|
|
|
96
96
|
const gitCheck = await checkGitRepo(projectRoot);
|
|
97
97
|
checks.push(gitCheck);
|
|
98
98
|
const conflicts = checkConflicts(authModules, databaseModules);
|
|
99
|
-
conflicts.forEach(conflict => {
|
|
99
|
+
conflicts.forEach((conflict) => {
|
|
100
100
|
checks.push({
|
|
101
101
|
status: "warning",
|
|
102
102
|
message: conflict,
|
|
@@ -118,8 +118,11 @@ async function runDoctorChecks() {
|
|
|
118
118
|
},
|
|
119
119
|
files: {
|
|
120
120
|
envExample: await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, ".env.example")),
|
|
121
|
-
env: await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, ".env")) ||
|
|
122
|
-
|
|
121
|
+
env: (await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, ".env"))) ||
|
|
122
|
+
(await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, ".env.local"))),
|
|
123
|
+
prismaSchema: databaseModules.includes("prisma")
|
|
124
|
+
? await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, "prisma", "schema.prisma"))
|
|
125
|
+
: undefined,
|
|
123
126
|
authRoutes: authModules.length > 0 ? await checkAuthRoutesExist(projectRoot, projectType) : undefined,
|
|
124
127
|
tsconfig: await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, "tsconfig.json")),
|
|
125
128
|
eslintConfig: await checkEslintConfigExists(projectRoot),
|
|
@@ -132,9 +135,9 @@ async function runDoctorChecks() {
|
|
|
132
135
|
conflicts,
|
|
133
136
|
checks,
|
|
134
137
|
summary: {
|
|
135
|
-
errors: checks.filter(c => c.status === "error").length,
|
|
136
|
-
warnings: checks.filter(c => c.status === "warning").length,
|
|
137
|
-
suggestions: generateSuggestions(),
|
|
138
|
+
errors: checks.filter((c) => c.status === "error").length,
|
|
139
|
+
warnings: checks.filter((c) => c.status === "warning").length,
|
|
140
|
+
suggestions: generateSuggestions(authModules, databaseModules),
|
|
138
141
|
},
|
|
139
142
|
};
|
|
140
143
|
return report;
|
|
@@ -232,7 +235,9 @@ async function checkKeyFiles(projectRoot, projectType, authModules, databaseModu
|
|
|
232
235
|
const envExampleExists = await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, ".env.example"));
|
|
233
236
|
checks.push({
|
|
234
237
|
status: envExampleExists ? "success" : "warning",
|
|
235
|
-
message: envExampleExists
|
|
238
|
+
message: envExampleExists
|
|
239
|
+
? ".env.example file found"
|
|
240
|
+
: ".env.example file missing (recommended for documentation)",
|
|
236
241
|
});
|
|
237
242
|
if (databaseModules.includes("prisma")) {
|
|
238
243
|
const schemaExists = await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, "prisma", "schema.prisma"));
|
|
@@ -245,7 +250,9 @@ async function checkKeyFiles(projectRoot, projectType, authModules, databaseModu
|
|
|
245
250
|
const authRoutesExist = await checkAuthRoutesExist(projectRoot, projectType);
|
|
246
251
|
checks.push({
|
|
247
252
|
status: authRoutesExist ? "success" : "warning",
|
|
248
|
-
message: authRoutesExist
|
|
253
|
+
message: authRoutesExist
|
|
254
|
+
? "Auth routes configured"
|
|
255
|
+
: "Auth routes not found (may need configuration)",
|
|
249
256
|
});
|
|
250
257
|
}
|
|
251
258
|
return checks;
|
|
@@ -254,6 +261,7 @@ async function checkAuthRoutesExist(projectRoot, projectType) {
|
|
|
254
261
|
if (projectType !== "nextjs")
|
|
255
262
|
return true; // Skip for non-Next.js
|
|
256
263
|
const possiblePaths = [
|
|
264
|
+
// NextAuth routes
|
|
257
265
|
"app/api/auth/[...nextauth]/route.ts",
|
|
258
266
|
"app/api/auth/[...nextauth]/route.js",
|
|
259
267
|
"src/app/api/auth/[...nextauth]/route.ts",
|
|
@@ -262,6 +270,11 @@ async function checkAuthRoutesExist(projectRoot, projectType) {
|
|
|
262
270
|
"pages/api/auth/[...nextauth].js",
|
|
263
271
|
"src/pages/api/auth/[...nextauth].ts",
|
|
264
272
|
"src/pages/api/auth/[...nextauth].js",
|
|
273
|
+
// Better Auth routes
|
|
274
|
+
"app/api/auth/[...all]/route.ts",
|
|
275
|
+
"app/api/auth/[...all]/route.js",
|
|
276
|
+
"src/app/api/auth/[...all]/route.ts",
|
|
277
|
+
"src/app/api/auth/[...all]/route.js",
|
|
265
278
|
];
|
|
266
279
|
for (const routePath of possiblePaths) {
|
|
267
280
|
if (await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, routePath))) {
|
|
@@ -300,8 +313,11 @@ async function checkEnvFiles(projectRoot, authModules, databaseModules) {
|
|
|
300
313
|
});
|
|
301
314
|
return { checks, envStatus: { missing: requiredKeys, present: [] } };
|
|
302
315
|
}
|
|
303
|
-
const envLines = envContent
|
|
304
|
-
|
|
316
|
+
const envLines = envContent
|
|
317
|
+
.split("\n")
|
|
318
|
+
.map((line) => line.trim())
|
|
319
|
+
.filter((line) => line && !line.startsWith("#"));
|
|
320
|
+
const envVars = new Set(envLines.map((line) => line.split("=")[0]));
|
|
305
321
|
for (const key of requiredKeys) {
|
|
306
322
|
if (envVars.has(key)) {
|
|
307
323
|
present.push(key);
|
|
@@ -346,7 +362,9 @@ async function checkConfigFiles(projectRoot, projectType, packageJson) {
|
|
|
346
362
|
status: eslintExists ? "success" : "warning",
|
|
347
363
|
message: eslintExists ? MESSAGES.ESLINT_CONFIG_FOUND : MESSAGES.ESLINT_CONFIG_MISSING,
|
|
348
364
|
});
|
|
349
|
-
const hasBuildScript = packageJson.scripts &&
|
|
365
|
+
const hasBuildScript = packageJson.scripts &&
|
|
366
|
+
typeof packageJson.scripts === "object" &&
|
|
367
|
+
"build" in packageJson.scripts;
|
|
350
368
|
checks.push({
|
|
351
369
|
status: hasBuildScript ? "success" : "warning",
|
|
352
370
|
message: hasBuildScript ? MESSAGES.BUILD_SCRIPT_FOUND : MESSAGES.BUILD_SCRIPT_MISSING,
|
|
@@ -360,8 +378,10 @@ async function checkDependencies(packageJson) {
|
|
|
360
378
|
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
361
379
|
for (const [name, version] of Object.entries(deps || {})) {
|
|
362
380
|
if (typeof version === "string" && (version.startsWith("^") || version.startsWith("~"))) {
|
|
381
|
+
// Assume up to date if using flexible versioning
|
|
363
382
|
}
|
|
364
383
|
else {
|
|
384
|
+
// Assume outdated if using exact versions (simplified check)
|
|
365
385
|
outdated.push(name);
|
|
366
386
|
}
|
|
367
387
|
}
|
|
@@ -394,11 +414,16 @@ async function checkEslintConfigExists(projectRoot) {
|
|
|
394
414
|
}
|
|
395
415
|
return false;
|
|
396
416
|
}
|
|
397
|
-
function generateSuggestions() {
|
|
417
|
+
function generateSuggestions(authModules, databaseModules) {
|
|
398
418
|
const suggestions = [];
|
|
419
|
+
// Show suggestions based on what's missing
|
|
420
|
+
if (authModules.length === 0) {
|
|
421
|
+
suggestions.push("stackkit add auth - Add authentication module");
|
|
422
|
+
}
|
|
423
|
+
if (databaseModules.length === 0) {
|
|
424
|
+
suggestions.push("stackkit add db - Add database module");
|
|
425
|
+
}
|
|
399
426
|
// Always show available commands
|
|
400
|
-
suggestions.push("stackkit add auth - Add authentication module");
|
|
401
|
-
suggestions.push("stackkit add db - Add database module");
|
|
402
427
|
suggestions.push("stackkit list - View available modules");
|
|
403
428
|
return suggestions;
|
|
404
429
|
}
|
|
@@ -521,7 +546,7 @@ function printDoctorReport(report, verbose) {
|
|
|
521
546
|
// Conflicts
|
|
522
547
|
if (report.conflicts.length > 0) {
|
|
523
548
|
logger_1.logger.log(chalk_1.default.bold("Conflicts"));
|
|
524
|
-
report.conflicts.forEach(conflict => {
|
|
549
|
+
report.conflicts.forEach((conflict) => {
|
|
525
550
|
logger_1.logger.warn(conflict);
|
|
526
551
|
});
|
|
527
552
|
logger_1.logger.newLine();
|
|
@@ -529,7 +554,7 @@ function printDoctorReport(report, verbose) {
|
|
|
529
554
|
// Detailed checks if verbose
|
|
530
555
|
if (verbose) {
|
|
531
556
|
logger_1.logger.log(chalk_1.default.bold("Detailed Checks"));
|
|
532
|
-
report.checks.forEach(check => {
|
|
557
|
+
report.checks.forEach((check) => {
|
|
533
558
|
if (check.status === "success") {
|
|
534
559
|
logger_1.logger.success(check.message);
|
|
535
560
|
}
|
|
@@ -552,7 +577,7 @@ function printDoctorReport(report, verbose) {
|
|
|
552
577
|
logger_1.logger.newLine();
|
|
553
578
|
if (report.summary.suggestions.length > 0) {
|
|
554
579
|
logger_1.logger.log(chalk_1.default.bold("Suggestions"));
|
|
555
|
-
report.summary.suggestions.forEach(suggestion => {
|
|
580
|
+
report.summary.suggestions.forEach((suggestion) => {
|
|
556
581
|
logger_1.logger.log(` • ${suggestion}`);
|
|
557
582
|
});
|
|
558
583
|
}
|
package/dist/cli/list.js
CHANGED
|
@@ -52,10 +52,22 @@ async function listCommand(options) {
|
|
|
52
52
|
logger_1.logger.log(` ${chalk_1.default.gray(categoryPrefix)} ${chalk_1.default.yellow(formatCategoryName(category))} ${chalk_1.default.dim(`(${mods.length})`)}`);
|
|
53
53
|
mods.forEach((mod, modIndex) => {
|
|
54
54
|
const isLastMod = modIndex === mods.length - 1;
|
|
55
|
-
const modPrefix = isLastCategory
|
|
55
|
+
const modPrefix = isLastCategory
|
|
56
|
+
? isLastMod
|
|
57
|
+
? " └──"
|
|
58
|
+
: " ├──"
|
|
59
|
+
: isLastMod
|
|
60
|
+
? "│ └──"
|
|
61
|
+
: "│ ├──";
|
|
56
62
|
logger_1.logger.log(` ${chalk_1.default.gray(modPrefix)} ${chalk_1.default.green(mod.displayName)}`);
|
|
57
63
|
if (mod.category === "database" && mod.name === "prisma") {
|
|
58
|
-
const providerPrefix = isLastCategory
|
|
64
|
+
const providerPrefix = isLastCategory
|
|
65
|
+
? isLastMod
|
|
66
|
+
? " └──"
|
|
67
|
+
: " ├──"
|
|
68
|
+
: isLastMod
|
|
69
|
+
? "│ └──"
|
|
70
|
+
: "│ ├──";
|
|
59
71
|
logger_1.logger.log(` ${chalk_1.default.gray(providerPrefix)} ${chalk_1.default.dim("Providers: PostgreSQL, MongoDB, MySQL, SQLite")}`);
|
|
60
72
|
}
|
|
61
73
|
});
|
package/dist/index.js
CHANGED
|
@@ -11,28 +11,28 @@ const program = new commander_1.Command();
|
|
|
11
11
|
program
|
|
12
12
|
.name("stackkit")
|
|
13
13
|
.description("CLI for creating and managing StackKit projects")
|
|
14
|
-
.version("0.1.
|
|
14
|
+
.version("0.1.6")
|
|
15
15
|
.configureHelp({
|
|
16
16
|
subcommandTerm: (cmd) => {
|
|
17
17
|
const name = cmd.name();
|
|
18
|
-
if (name ===
|
|
19
|
-
return
|
|
20
|
-
if (name ===
|
|
21
|
-
return
|
|
22
|
-
if (name ===
|
|
23
|
-
return
|
|
24
|
-
if (name ===
|
|
25
|
-
return
|
|
26
|
-
if (name ===
|
|
27
|
-
return
|
|
28
|
-
return name +
|
|
29
|
-
}
|
|
18
|
+
if (name === "create")
|
|
19
|
+
return "create [project-name] [options]";
|
|
20
|
+
if (name === "add")
|
|
21
|
+
return "add <module> [options]";
|
|
22
|
+
if (name === "doctor")
|
|
23
|
+
return "doctor [options]";
|
|
24
|
+
if (name === "list")
|
|
25
|
+
return "list [options]";
|
|
26
|
+
if (name === "help")
|
|
27
|
+
return "help [command]";
|
|
28
|
+
return name + " [options]";
|
|
29
|
+
},
|
|
30
30
|
});
|
|
31
31
|
// Create command
|
|
32
32
|
program
|
|
33
|
-
.command(
|
|
33
|
+
.command("create [project-name]")
|
|
34
34
|
.description("Create a new StackKit project")
|
|
35
|
-
.usage(
|
|
35
|
+
.usage("[project-name] [options]")
|
|
36
36
|
.option("-f, --framework <framework>", "Framework: nextjs, express, react")
|
|
37
37
|
.option("-d, --database <database>", "Database: prisma, mongoose, none")
|
|
38
38
|
.option("--prisma-provider <provider>", "Prisma provider: postgresql, mongodb, mysql, sqlite")
|
|
@@ -55,7 +55,7 @@ program
|
|
|
55
55
|
program
|
|
56
56
|
.command("add [module]")
|
|
57
57
|
.description("Add a module or category to your existing project")
|
|
58
|
-
.usage(
|
|
58
|
+
.usage("[module] [options]")
|
|
59
59
|
.option("--provider <provider>", "Specific provider/variant to use")
|
|
60
60
|
.option("--force", "Overwrite existing files")
|
|
61
61
|
.option("--dry-run", "Show what would be changed without making changes")
|
|
@@ -10,7 +10,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
10
10
|
const package_root_1 = require("../utils/package-root");
|
|
11
11
|
const baseDirs = {
|
|
12
12
|
express: "./src",
|
|
13
|
-
|
|
13
|
+
react: "./src",
|
|
14
14
|
nextjs: ".",
|
|
15
15
|
};
|
|
16
16
|
async function convertToJavaScript(targetDir, framework) {
|
|
@@ -25,7 +25,7 @@ async function discoverModules(modulesDir) {
|
|
|
25
25
|
const candidates = [];
|
|
26
26
|
if (modulesDir)
|
|
27
27
|
candidates.push(modulesDir);
|
|
28
|
-
candidates.push(path_1.default.join((0, package_root_1.getPackageRoot)(),
|
|
28
|
+
candidates.push(path_1.default.join((0, package_root_1.getPackageRoot)(), "modules")); // package root
|
|
29
29
|
let resolvedModulesDir;
|
|
30
30
|
for (const c of candidates) {
|
|
31
31
|
if (await fs_extra_1.default.pathExists(c)) {
|
|
@@ -37,18 +37,18 @@ async function discoverModules(modulesDir) {
|
|
|
37
37
|
return discovered;
|
|
38
38
|
modulesDir = resolvedModulesDir;
|
|
39
39
|
// Discover frameworks from templates directory
|
|
40
|
-
const templatesDir = path_1.default.join(modulesDir,
|
|
40
|
+
const templatesDir = path_1.default.join(modulesDir, "..", "templates");
|
|
41
41
|
if (await fs_extra_1.default.pathExists(templatesDir)) {
|
|
42
42
|
const frameworkDirs = await fs_extra_1.default.readdir(templatesDir);
|
|
43
43
|
for (const frameworkName of frameworkDirs) {
|
|
44
|
-
const templateJsonPath = path_1.default.join(templatesDir, frameworkName,
|
|
44
|
+
const templateJsonPath = path_1.default.join(templatesDir, frameworkName, "template.json");
|
|
45
45
|
if (await fs_extra_1.default.pathExists(templateJsonPath)) {
|
|
46
46
|
try {
|
|
47
|
-
const templateConfig = await fs_extra_1.default.readJson(templateJsonPath);
|
|
47
|
+
const templateConfig = (await fs_extra_1.default.readJson(templateJsonPath));
|
|
48
48
|
discovered.frameworks.push({
|
|
49
49
|
...templateConfig,
|
|
50
50
|
name: frameworkName,
|
|
51
|
-
category:
|
|
51
|
+
category: "framework",
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
catch {
|
|
@@ -58,23 +58,23 @@ async function discoverModules(modulesDir) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
// Discover database modules
|
|
61
|
-
const databaseDir = path_1.default.join(modulesDir,
|
|
61
|
+
const databaseDir = path_1.default.join(modulesDir, "database");
|
|
62
62
|
if (await fs_extra_1.default.pathExists(databaseDir)) {
|
|
63
63
|
const dbModules = await fs_extra_1.default.readdir(databaseDir);
|
|
64
64
|
// Sort to ensure consistent order: prisma first, then others
|
|
65
65
|
dbModules.sort((a, b) => {
|
|
66
|
-
if (a ===
|
|
66
|
+
if (a === "prisma")
|
|
67
67
|
return -1;
|
|
68
|
-
if (b ===
|
|
68
|
+
if (b === "prisma")
|
|
69
69
|
return 1;
|
|
70
70
|
return a.localeCompare(b);
|
|
71
71
|
});
|
|
72
72
|
for (const moduleName of dbModules) {
|
|
73
73
|
const modulePath = path_1.default.join(databaseDir, moduleName);
|
|
74
|
-
const moduleJsonPath = path_1.default.join(modulePath,
|
|
74
|
+
const moduleJsonPath = path_1.default.join(modulePath, "module.json");
|
|
75
75
|
if (await fs_extra_1.default.pathExists(moduleJsonPath)) {
|
|
76
76
|
try {
|
|
77
|
-
const metadata = await fs_extra_1.default.readJson(moduleJsonPath);
|
|
77
|
+
const metadata = (await fs_extra_1.default.readJson(moduleJsonPath));
|
|
78
78
|
// Ensure name/displayName fallbacks
|
|
79
79
|
if (!metadata.name)
|
|
80
80
|
metadata.name = moduleName;
|
|
@@ -89,15 +89,15 @@ async function discoverModules(modulesDir) {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
// Discover auth modules
|
|
92
|
-
const authDir = path_1.default.join(modulesDir,
|
|
92
|
+
const authDir = path_1.default.join(modulesDir, "auth");
|
|
93
93
|
if (await fs_extra_1.default.pathExists(authDir)) {
|
|
94
94
|
const authModules = await fs_extra_1.default.readdir(authDir);
|
|
95
95
|
for (const moduleName of authModules) {
|
|
96
96
|
const modulePath = path_1.default.join(authDir, moduleName);
|
|
97
|
-
const moduleJsonPath = path_1.default.join(modulePath,
|
|
97
|
+
const moduleJsonPath = path_1.default.join(modulePath, "module.json");
|
|
98
98
|
if (await fs_extra_1.default.pathExists(moduleJsonPath)) {
|
|
99
99
|
try {
|
|
100
|
-
const metadata = await fs_extra_1.default.readJson(moduleJsonPath);
|
|
100
|
+
const metadata = (await fs_extra_1.default.readJson(moduleJsonPath));
|
|
101
101
|
if (!metadata.name)
|
|
102
102
|
metadata.name = moduleName;
|
|
103
103
|
if (!metadata.displayName)
|
|
@@ -116,14 +116,14 @@ async function discoverModules(modulesDir) {
|
|
|
116
116
|
* Get valid database options for CLI
|
|
117
117
|
*/
|
|
118
118
|
function getValidDatabaseOptions(databases) {
|
|
119
|
-
const options = [
|
|
119
|
+
const options = ["none"];
|
|
120
120
|
for (const db of databases) {
|
|
121
|
-
if (db.name ===
|
|
121
|
+
if (db.name === "prisma") {
|
|
122
122
|
// For Prisma, add provider-specific options
|
|
123
|
-
options.push(
|
|
123
|
+
options.push("prisma-postgresql", "prisma-mongodb", "prisma-mysql", "prisma-sqlite");
|
|
124
124
|
}
|
|
125
|
-
else if (db.name ===
|
|
126
|
-
options.push(
|
|
125
|
+
else if (db.name === "mongoose") {
|
|
126
|
+
options.push("mongoose", "mongoose");
|
|
127
127
|
}
|
|
128
128
|
else {
|
|
129
129
|
// For other databases, add the name directly
|
|
@@ -136,7 +136,7 @@ function getValidDatabaseOptions(databases) {
|
|
|
136
136
|
* Get valid auth options for CLI
|
|
137
137
|
*/
|
|
138
138
|
function getValidAuthOptions(authModules) {
|
|
139
|
-
const options = [
|
|
139
|
+
const options = ["none"];
|
|
140
140
|
for (const auth of authModules) {
|
|
141
141
|
options.push(auth.name);
|
|
142
142
|
}
|
|
@@ -146,15 +146,15 @@ function getValidAuthOptions(authModules) {
|
|
|
146
146
|
* Parse database option into database name and provider
|
|
147
147
|
*/
|
|
148
148
|
function parseDatabaseOption(dbOption) {
|
|
149
|
-
if (dbOption ===
|
|
150
|
-
return { database:
|
|
149
|
+
if (dbOption === "none") {
|
|
150
|
+
return { database: "none" };
|
|
151
151
|
}
|
|
152
|
-
if (dbOption.startsWith(
|
|
153
|
-
const provider = dbOption.split(
|
|
154
|
-
return { database:
|
|
152
|
+
if (dbOption.startsWith("prisma-")) {
|
|
153
|
+
const provider = dbOption.split("-")[1];
|
|
154
|
+
return { database: "prisma", provider };
|
|
155
155
|
}
|
|
156
|
-
if (dbOption ===
|
|
157
|
-
return { database:
|
|
156
|
+
if (dbOption === "mongoose" || dbOption === "mongoose") {
|
|
157
|
+
return { database: "mongoose" };
|
|
158
158
|
}
|
|
159
159
|
return { database: dbOption };
|
|
160
160
|
}
|
|
@@ -169,19 +169,19 @@ function getCompatibleAuthOptions(authModules, framework, database) {
|
|
|
169
169
|
continue;
|
|
170
170
|
}
|
|
171
171
|
// Special compatibility rules
|
|
172
|
-
if (auth.name ===
|
|
172
|
+
if (auth.name === "authjs" && (database !== "prisma" || framework !== "nextjs")) {
|
|
173
173
|
continue;
|
|
174
174
|
}
|
|
175
|
-
if (auth.name ===
|
|
175
|
+
if (auth.name === "better-auth" && database === "none" && framework !== "react") {
|
|
176
176
|
continue;
|
|
177
177
|
}
|
|
178
178
|
compatible.push({
|
|
179
179
|
name: auth.displayName,
|
|
180
|
-
value: auth.name
|
|
180
|
+
value: auth.name,
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
183
|
// Add "None" at the end
|
|
184
|
-
compatible.push({ name:
|
|
184
|
+
compatible.push({ name: "None", value: "none" });
|
|
185
185
|
return compatible;
|
|
186
186
|
}
|
|
187
187
|
/**
|
|
@@ -194,17 +194,17 @@ function getDatabaseChoices(databases, framework) {
|
|
|
194
194
|
if (db.supportedFrameworks && !db.supportedFrameworks.includes(framework)) {
|
|
195
195
|
continue;
|
|
196
196
|
}
|
|
197
|
-
if (db.name ===
|
|
198
|
-
choices.push({ name:
|
|
197
|
+
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" });
|
|
199
199
|
}
|
|
200
|
-
else if (db.name ===
|
|
201
|
-
choices.push({ name:
|
|
200
|
+
else if (db.name === "mongoose") {
|
|
201
|
+
choices.push({ name: "Mongoose", value: "mongoose" });
|
|
202
202
|
}
|
|
203
203
|
else {
|
|
204
204
|
choices.push({ name: db.displayName, value: db.name });
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
// Add "None" at the end
|
|
208
|
-
choices.push({ name:
|
|
208
|
+
choices.push({ name: "None", value: "none" });
|
|
209
209
|
return choices;
|
|
210
210
|
}
|
|
@@ -63,7 +63,7 @@ async function appendToEnvFile(filePath, variables, fileType, options = {}) {
|
|
|
63
63
|
content += "\n";
|
|
64
64
|
content += `${ENV_MARKER_START} Added by StackKit\n`;
|
|
65
65
|
for (const variable of newVariables) {
|
|
66
|
-
const value = fileType === "example" ?
|
|
66
|
+
const value = fileType === "example" ? variable.value || "" : variable.value || "";
|
|
67
67
|
content += `${variable.key}=${value}\n`;
|
|
68
68
|
}
|
|
69
69
|
content += `${ENV_MARKER_END}\n`;
|
|
@@ -39,7 +39,7 @@ const path = __importStar(require("path"));
|
|
|
39
39
|
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
40
40
|
class FrameworkUtils {
|
|
41
41
|
static async loadFrameworkConfig(frameworkName, templatesDir) {
|
|
42
|
-
const configPath = path.join(templatesDir, frameworkName,
|
|
42
|
+
const configPath = path.join(templatesDir, frameworkName, "template.json");
|
|
43
43
|
if (await fs.pathExists(configPath)) {
|
|
44
44
|
const config = await fs.readJson(configPath);
|
|
45
45
|
this.frameworkConfigs.set(frameworkName, config);
|
|
@@ -50,8 +50,8 @@ class FrameworkUtils {
|
|
|
50
50
|
name: frameworkName,
|
|
51
51
|
displayName: frameworkName.charAt(0).toUpperCase() + frameworkName.slice(1),
|
|
52
52
|
compatibility: {
|
|
53
|
-
databases: [
|
|
54
|
-
auth: [
|
|
53
|
+
databases: ["prisma", "mongoose"],
|
|
54
|
+
auth: ["better-auth", "authjs"],
|
|
55
55
|
},
|
|
56
56
|
};
|
|
57
57
|
this.frameworkConfigs.set(frameworkName, defaultConfig);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FrameworkConfig } from
|
|
1
|
+
import { FrameworkConfig } from "../framework/framework-utils";
|
|
2
2
|
export interface GenerationContext {
|
|
3
3
|
framework: string;
|
|
4
4
|
database?: string;
|
|
@@ -13,7 +13,7 @@ export interface TemplateCondition {
|
|
|
13
13
|
features?: string[];
|
|
14
14
|
}
|
|
15
15
|
export interface Operation {
|
|
16
|
-
type:
|
|
16
|
+
type: "create-file" | "patch-file" | "add-dependency" | "add-script" | "add-env" | "run-command";
|
|
17
17
|
description?: string;
|
|
18
18
|
condition?: TemplateCondition;
|
|
19
19
|
priority?: number;
|
|
@@ -28,7 +28,7 @@ export interface Operation {
|
|
|
28
28
|
command?: string;
|
|
29
29
|
}
|
|
30
30
|
export interface PatchOperation {
|
|
31
|
-
type:
|
|
31
|
+
type: "add-import" | "add-code" | "replace-code" | "add-to-top" | "add-to-bottom";
|
|
32
32
|
condition?: TemplateCondition;
|
|
33
33
|
imports?: string[];
|
|
34
34
|
code?: string;
|
|
@@ -40,7 +40,7 @@ export interface PatchOperation {
|
|
|
40
40
|
}
|
|
41
41
|
export interface GeneratorConfig {
|
|
42
42
|
name: string;
|
|
43
|
-
type:
|
|
43
|
+
type: "framework" | "database" | "auth";
|
|
44
44
|
priority: number;
|
|
45
45
|
operations?: Operation[];
|
|
46
46
|
dependencies?: Record<string, string>;
|
|
@@ -93,5 +93,5 @@ export declare class AdvancedCodeGenerator {
|
|
|
93
93
|
/**
|
|
94
94
|
* Register a generator config dynamically (used for modules that only provide module.json patches).
|
|
95
95
|
*/
|
|
96
|
-
registerGenerator(type:
|
|
96
|
+
registerGenerator(type: "framework" | "database" | "auth", name: string, config: GeneratorConfig): void;
|
|
97
97
|
}
|