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.
Files changed (43) hide show
  1. package/README.md +5 -3
  2. package/dist/cli/add.d.ts +2 -1
  3. package/dist/cli/add.js +325 -102
  4. package/dist/cli/create.d.ts +2 -2
  5. package/dist/cli/create.js +96 -30
  6. package/dist/cli/doctor.js +25 -17
  7. package/dist/cli/list.js +14 -2
  8. package/dist/index.js +22 -3
  9. package/dist/lib/conversion/js-conversion.js +2 -2
  10. package/dist/lib/discovery/module-discovery.d.ts +0 -1
  11. package/dist/lib/discovery/module-discovery.js +35 -35
  12. package/dist/lib/env/env-editor.js +1 -1
  13. package/dist/lib/framework/framework-utils.d.ts +1 -1
  14. package/dist/lib/framework/framework-utils.js +3 -3
  15. package/dist/lib/generation/code-generator.d.ts +18 -4
  16. package/dist/lib/generation/code-generator.js +212 -147
  17. package/dist/lib/generation/generator-utils.d.ts +11 -0
  18. package/dist/lib/generation/generator-utils.js +124 -0
  19. package/dist/lib/git-utils.js +20 -0
  20. package/dist/lib/project/detect.js +2 -4
  21. package/dist/lib/utils/package-root.js +2 -2
  22. package/dist/types/index.d.ts +0 -10
  23. package/modules/auth/authjs/generator.json +10 -0
  24. package/modules/auth/authjs/module.json +0 -9
  25. package/modules/auth/better-auth/files/lib/auth.ts +38 -31
  26. package/modules/auth/better-auth/files/prisma/schema.prisma +3 -3
  27. package/modules/auth/better-auth/generator.json +58 -28
  28. package/modules/auth/better-auth/module.json +0 -24
  29. package/modules/database/mongoose/files/models/health.ts +34 -0
  30. package/modules/database/mongoose/generator.json +27 -8
  31. package/modules/database/mongoose/module.json +1 -2
  32. package/modules/database/prisma/files/lib/prisma.ts +27 -21
  33. package/modules/database/prisma/files/prisma.config.ts +17 -0
  34. package/modules/database/prisma/generator.json +79 -15
  35. package/modules/database/prisma/module.json +1 -4
  36. package/package.json +1 -1
  37. package/templates/express/src/server.ts +9 -3
  38. package/templates/express/tsconfig.json +2 -23
  39. package/templates/nextjs/lib/env.ts +1 -1
  40. package/dist/lib/database/database-config.d.ts +0 -6
  41. package/dist/lib/database/database-config.js +0 -9
  42. package/modules/database/mongoose/files/models/User.ts +0 -34
  43. /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)(), 'modules')); // package root
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, '..', 'templates');
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, 'template.json');
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: 'framework',
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, 'database');
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 === 'prisma')
66
+ if (a === "prisma")
67
67
  return -1;
68
- if (b === 'prisma')
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, 'module.json');
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, 'auth');
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, 'module.json');
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 = ['none'];
119
+ const options = ["none"];
120
120
  for (const db of databases) {
121
- if (db.name === 'prisma') {
121
+ if (db.name === "prisma") {
122
122
  // For Prisma, add provider-specific options
123
- options.push('prisma-postgresql', 'prisma-mongodb', 'prisma-mysql', 'prisma-sqlite');
123
+ options.push("prisma-postgresql", "prisma-mongodb", "prisma-mysql", "prisma-sqlite");
124
124
  }
125
- else if (db.name === 'mongoose') {
126
- options.push('mongoose-mongodb', 'mongoose');
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 = ['none'];
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 === 'none') {
150
- return { database: 'none' };
149
+ if (dbOption === "none") {
150
+ return { database: "none" };
151
151
  }
152
- if (dbOption.startsWith('prisma-')) {
153
- const provider = dbOption.split('-')[1];
154
- return { database: 'prisma', provider };
152
+ if (dbOption.startsWith("prisma-")) {
153
+ const provider = dbOption.split("-")[1];
154
+ return { database: "prisma", provider };
155
155
  }
156
- if (dbOption === 'mongoose-mongodb' || dbOption === 'mongoose') {
157
- return { database: 'mongoose' };
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 === 'authjs' && (database !== 'prisma' || framework !== 'nextjs')) {
172
+ if (auth.name === "authjs" && (database !== "prisma" || framework !== "nextjs")) {
173
173
  continue;
174
174
  }
175
- if (auth.name === 'better-auth' && database === 'none' && framework !== 'react') {
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: 'None', value: 'none' });
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 === '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' });
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 === 'mongoose') {
201
- choices.push({ name: 'Mongoose (MongoDB)', value: 'mongoose-mongodb' });
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: 'None', value: 'none' });
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" ? (variable.value || "") : (variable.value || "");
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`;
@@ -9,7 +9,7 @@ export interface FrameworkConfig {
9
9
  export interface ModuleConfig {
10
10
  name: string;
11
11
  displayName: string;
12
- type: 'database' | 'auth';
12
+ type: "database" | "auth";
13
13
  compatibility?: {
14
14
  frameworks?: string[];
15
15
  databases?: string[];
@@ -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, 'template.json');
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: ['prisma', 'mongoose'],
54
- auth: ['better-auth', 'authjs'],
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 '../framework/framework-utils';
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: 'create-file' | 'patch-file' | 'add-dependency' | 'add-script' | 'add-env' | 'run-command';
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: 'add-import' | 'add-code' | 'replace-code' | 'add-to-top' | 'add-to-bottom';
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: 'framework' | 'database' | 'auth';
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
  }