stackkit 0.1.3 → 0.1.5
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 +5 -3
- package/dist/cli/add.d.ts +2 -1
- package/dist/cli/add.js +325 -102
- package/dist/cli/create.d.ts +2 -2
- package/dist/cli/create.js +96 -30
- package/dist/cli/doctor.js +25 -17
- package/dist/cli/list.js +14 -2
- package/dist/index.js +22 -3
- package/dist/lib/conversion/js-conversion.js +2 -2
- package/dist/lib/discovery/module-discovery.d.ts +0 -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 +18 -4
- package/dist/lib/generation/code-generator.js +212 -147
- package/dist/lib/generation/generator-utils.d.ts +11 -0
- package/dist/lib/generation/generator-utils.js +124 -0
- package/dist/lib/git-utils.js +20 -0
- package/dist/lib/project/detect.js +2 -4
- package/dist/lib/utils/package-root.js +2 -2
- package/dist/types/index.d.ts +0 -10
- package/modules/auth/authjs/generator.json +10 -0
- package/modules/auth/authjs/module.json +0 -9
- package/modules/auth/better-auth/files/lib/auth.ts +38 -31
- package/modules/auth/better-auth/files/prisma/schema.prisma +3 -3
- package/modules/auth/better-auth/generator.json +58 -28
- package/modules/auth/better-auth/module.json +0 -24
- package/modules/database/mongoose/files/models/health.ts +34 -0
- package/modules/database/mongoose/generator.json +27 -8
- package/modules/database/mongoose/module.json +1 -2
- package/modules/database/prisma/files/lib/prisma.ts +27 -21
- package/modules/database/prisma/files/prisma.config.ts +17 -0
- package/modules/database/prisma/generator.json +79 -15
- package/modules/database/prisma/module.json +1 -4
- package/package.json +1 -1
- package/templates/express/src/server.ts +9 -3
- package/templates/express/tsconfig.json +2 -23
- package/templates/nextjs/lib/env.ts +1 -1
- package/dist/lib/database/database-config.d.ts +0 -6
- package/dist/lib/database/database-config.js +0 -9
- package/modules/database/mongoose/files/models/User.ts +0 -34
- /package/modules/database/mongoose/files/lib/{db.ts → mongoose.ts} +0 -0
|
@@ -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>;
|
|
@@ -75,9 +75,23 @@ export declare class AdvancedCodeGenerator {
|
|
|
75
75
|
private executeAddEnv;
|
|
76
76
|
private executeRunCommand;
|
|
77
77
|
private generatePackageJson;
|
|
78
|
+
/**
|
|
79
|
+
* Apply generators to an existing project directory instead of creating a new template.
|
|
80
|
+
* This executes applicable operations and updates package.json in-place.
|
|
81
|
+
*/
|
|
82
|
+
applyToProject(selectedModules: {
|
|
83
|
+
framework: string;
|
|
84
|
+
database?: string;
|
|
85
|
+
auth?: string;
|
|
86
|
+
prismaProvider?: string;
|
|
87
|
+
}, features: string[], projectPath: string): Promise<string[]>;
|
|
78
88
|
getAvailableGenerators(): {
|
|
79
89
|
frameworks: string[];
|
|
80
90
|
databases: string[];
|
|
81
91
|
auths: string[];
|
|
82
92
|
};
|
|
93
|
+
/**
|
|
94
|
+
* Register a generator config dynamically (used for modules that only provide module.json patches).
|
|
95
|
+
*/
|
|
96
|
+
registerGenerator(type: "framework" | "database" | "auth", name: string, config: GeneratorConfig): void;
|
|
83
97
|
}
|