stackkit 0.1.3 → 0.1.4

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 (33) hide show
  1. package/README.md +4 -2
  2. package/dist/cli/add.d.ts +2 -1
  3. package/dist/cli/add.js +317 -105
  4. package/dist/cli/create.js +2 -3
  5. package/dist/cli/doctor.js +0 -4
  6. package/dist/index.js +23 -4
  7. package/dist/lib/conversion/js-conversion.js +1 -1
  8. package/dist/lib/discovery/module-discovery.d.ts +0 -1
  9. package/dist/lib/discovery/module-discovery.js +3 -3
  10. package/dist/lib/generation/code-generator.d.ts +14 -0
  11. package/dist/lib/generation/code-generator.js +55 -24
  12. package/dist/lib/generation/generator-utils.d.ts +11 -0
  13. package/dist/lib/generation/generator-utils.js +116 -0
  14. package/dist/lib/git-utils.js +20 -0
  15. package/dist/lib/project/detect.js +2 -4
  16. package/dist/types/index.d.ts +0 -10
  17. package/modules/auth/authjs/generator.json +10 -0
  18. package/modules/auth/authjs/module.json +0 -9
  19. package/modules/auth/better-auth/files/lib/auth.ts +7 -7
  20. package/modules/auth/better-auth/generator.json +12 -12
  21. package/modules/auth/better-auth/module.json +0 -24
  22. package/modules/database/mongoose/files/models/health.ts +34 -0
  23. package/modules/database/mongoose/generator.json +4 -4
  24. package/modules/database/mongoose/module.json +1 -2
  25. package/modules/database/prisma/files/lib/prisma.ts +2 -1
  26. package/modules/database/prisma/generator.json +33 -8
  27. package/modules/database/prisma/module.json +1 -4
  28. package/package.json +1 -1
  29. package/templates/express/tsconfig.json +2 -23
  30. package/dist/lib/database/database-config.d.ts +0 -6
  31. package/dist/lib/database/database-config.js +0 -9
  32. package/modules/database/mongoose/files/models/User.ts +0 -34
  33. /package/modules/database/mongoose/files/lib/{db.ts → mongoose.ts} +0 -0
@@ -123,7 +123,7 @@ function getValidDatabaseOptions(databases) {
123
123
  options.push('prisma-postgresql', 'prisma-mongodb', 'prisma-mysql', 'prisma-sqlite');
124
124
  }
125
125
  else if (db.name === 'mongoose') {
126
- options.push('mongoose-mongodb', 'mongoose');
126
+ options.push('mongoose', 'mongoose');
127
127
  }
128
128
  else {
129
129
  // For other databases, add the name directly
@@ -153,7 +153,7 @@ function parseDatabaseOption(dbOption) {
153
153
  const provider = dbOption.split('-')[1];
154
154
  return { database: 'prisma', provider };
155
155
  }
156
- if (dbOption === 'mongoose-mongodb' || dbOption === 'mongoose') {
156
+ if (dbOption === 'mongoose' || dbOption === 'mongoose') {
157
157
  return { database: 'mongoose' };
158
158
  }
159
159
  return { database: dbOption };
@@ -198,7 +198,7 @@ function getDatabaseChoices(databases, framework) {
198
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
200
  else if (db.name === 'mongoose') {
201
- choices.push({ name: 'Mongoose (MongoDB)', value: 'mongoose-mongodb' });
201
+ choices.push({ name: 'Mongoose', value: 'mongoose' });
202
202
  }
203
203
  else {
204
204
  choices.push({ name: db.displayName, value: db.name });
@@ -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
  }
@@ -37,6 +37,7 @@ exports.AdvancedCodeGenerator = void 0;
37
37
  const fs = __importStar(require("fs-extra"));
38
38
  const path = __importStar(require("path"));
39
39
  const package_root_1 = require("../utils/package-root");
40
+ const generator_utils_1 = require("./generator-utils");
40
41
  class AdvancedCodeGenerator {
41
42
  constructor(frameworkConfig) {
42
43
  this.generators = new Map();
@@ -54,18 +55,8 @@ class AdvancedCodeGenerator {
54
55
  if (await fs.pathExists(generatorPath)) {
55
56
  try {
56
57
  const config = await fs.readJson(generatorPath);
57
- const modulePath = path.join(typePath, moduleName, 'module.json');
58
- if (await fs.pathExists(modulePath)) {
59
- try {
60
- const moduleConfig = await fs.readJson(modulePath);
61
- if (moduleConfig.postInstall && Array.isArray(moduleConfig.postInstall)) {
62
- config.postInstall = moduleConfig.postInstall;
63
- }
64
- }
65
- catch {
66
- // Silently skip if module.json is invalid
67
- }
68
- }
58
+ const modulePath = path.join(typePath, moduleName);
59
+ await (0, generator_utils_1.mergeModuleIntoGeneratorConfig)(config, modulePath);
69
60
  this.generators.set(`${type}:${moduleName}`, config);
70
61
  }
71
62
  catch {
@@ -443,19 +434,9 @@ class AdvancedCodeGenerator {
443
434
  content = this.processTemplate(operation.content, context);
444
435
  }
445
436
  else if (operation.source) {
446
- // Find the source file path relative to the module/template directory
447
- const packageRoot = (0, package_root_1.getPackageRoot)();
448
- const modulesPath = path.join(packageRoot, 'modules');
449
- const templatesPath = path.join(packageRoot, 'templates');
450
- const moduleBasePath = operation.generatorType === 'framework'
451
- ? path.join(templatesPath, operation.generator)
452
- : path.join(modulesPath, operation.generatorType, operation.generator);
453
- const sourcePath = path.join(moduleBasePath, 'files', operation.source);
454
- // Check if source file exists
455
- if (await fs.pathExists(sourcePath)) {
456
- // Read source file
437
+ const sourcePath = (0, generator_utils_1.locateOperationSource)(operation.generatorType, operation.generator, operation.source || '');
438
+ if (sourcePath && await fs.pathExists(sourcePath)) {
457
439
  content = await fs.readFile(sourcePath, 'utf-8');
458
- // Process template content
459
440
  content = this.processTemplate(content, context);
460
441
  }
461
442
  else {
@@ -630,6 +611,50 @@ class AdvancedCodeGenerator {
630
611
  packageJson.scripts = { ...(packageJson.scripts || {}), ...allScripts };
631
612
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
632
613
  }
614
+ /**
615
+ * Apply generators to an existing project directory instead of creating a new template.
616
+ * This executes applicable operations and updates package.json in-place.
617
+ */
618
+ async applyToProject(selectedModules, features, projectPath) {
619
+ const context = {
620
+ ...selectedModules,
621
+ features,
622
+ };
623
+ if (selectedModules.database === 'prisma' && !context.prismaProvider) {
624
+ context.prismaProvider = 'postgresql';
625
+ }
626
+ const applicableOperations = [];
627
+ for (const [key, generator] of this.generators) {
628
+ const [genType, name] = key.split(':');
629
+ if (genType === 'framework' && name === selectedModules.framework) {
630
+ // framework
631
+ }
632
+ else if (genType === 'database' && name === selectedModules.database) {
633
+ // database
634
+ }
635
+ else if (genType === 'auth' && name === selectedModules.auth) {
636
+ // auth
637
+ }
638
+ else {
639
+ continue;
640
+ }
641
+ if (generator.postInstall && Array.isArray(generator.postInstall)) {
642
+ this.postInstallCommands.push(...generator.postInstall);
643
+ }
644
+ const items = generator.operations || [];
645
+ for (const item of items) {
646
+ if (this.evaluateCondition(item.condition, context)) {
647
+ applicableOperations.push({ ...item, generator: name, generatorType: genType, priority: generator.priority });
648
+ }
649
+ }
650
+ }
651
+ applicableOperations.sort((a, b) => (a.priority || 0) - (b.priority || 0));
652
+ for (const operation of applicableOperations) {
653
+ await this.executeOperation(operation, context, projectPath);
654
+ }
655
+ await this.generatePackageJson(selectedModules, features, projectPath);
656
+ return this.postInstallCommands;
657
+ }
633
658
  getAvailableGenerators() {
634
659
  const frameworks = [];
635
660
  const databases = [];
@@ -650,5 +675,11 @@ class AdvancedCodeGenerator {
650
675
  }
651
676
  return { frameworks, databases, auths };
652
677
  }
678
+ /**
679
+ * Register a generator config dynamically (used for modules that only provide module.json patches).
680
+ */
681
+ registerGenerator(type, name, config) {
682
+ this.generators.set(`${type}:${name}`, config);
683
+ }
653
684
  }
654
685
  exports.AdvancedCodeGenerator = AdvancedCodeGenerator;
@@ -0,0 +1,11 @@
1
+ import type { GeneratorConfig } from './code-generator';
2
+ import type { ModuleMetadata } from '../../types';
3
+ export declare function mergeModuleIntoGeneratorConfig(config: GeneratorConfig, modulePath: string): Promise<GeneratorConfig>;
4
+ export declare function mergeGeneratorIntoModuleMetadata(metadata: ModuleMetadata, modulePath: string): Promise<ModuleMetadata>;
5
+ export declare function locateOperationSource(generatorType: string, generatorName: string, sourceRel: string): string | null;
6
+ declare const _default: {
7
+ mergeModuleIntoGeneratorConfig: typeof mergeModuleIntoGeneratorConfig;
8
+ mergeGeneratorIntoModuleMetadata: typeof mergeGeneratorIntoModuleMetadata;
9
+ locateOperationSource: typeof locateOperationSource;
10
+ };
11
+ export default _default;
@@ -0,0 +1,116 @@
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.mergeModuleIntoGeneratorConfig = mergeModuleIntoGeneratorConfig;
37
+ exports.mergeGeneratorIntoModuleMetadata = mergeGeneratorIntoModuleMetadata;
38
+ exports.locateOperationSource = locateOperationSource;
39
+ const fs = __importStar(require("fs-extra"));
40
+ const path = __importStar(require("path"));
41
+ const package_root_1 = require("../utils/package-root");
42
+ async function mergeModuleIntoGeneratorConfig(config, modulePath) {
43
+ const modulePathJson = path.join(modulePath, 'module.json');
44
+ if (await fs.pathExists(modulePathJson)) {
45
+ try {
46
+ const moduleConfig = await fs.readJson(modulePathJson);
47
+ if (moduleConfig.postInstall && Array.isArray(moduleConfig.postInstall)) {
48
+ config.postInstall = moduleConfig.postInstall;
49
+ }
50
+ if (moduleConfig.dependencies && typeof moduleConfig.dependencies === 'object') {
51
+ config.dependencies = { ...(config.dependencies || {}), ...moduleConfig.dependencies };
52
+ }
53
+ if (moduleConfig.devDependencies && typeof moduleConfig.devDependencies === 'object') {
54
+ config.devDependencies = { ...(config.devDependencies || {}), ...moduleConfig.devDependencies };
55
+ }
56
+ if (moduleConfig.scripts && typeof moduleConfig.scripts === 'object') {
57
+ config.scripts = { ...(config.scripts || {}), ...moduleConfig.scripts };
58
+ }
59
+ if (moduleConfig.envVars && typeof moduleConfig.envVars === 'object') {
60
+ config.envVars = { ...(config.envVars || {}), ...moduleConfig.envVars };
61
+ }
62
+ }
63
+ catch {
64
+ // ignore invalid module.json
65
+ }
66
+ }
67
+ return config;
68
+ }
69
+ async function mergeGeneratorIntoModuleMetadata(metadata, modulePath) {
70
+ const generatorPath = path.join(modulePath, 'generator.json');
71
+ if (await fs.pathExists(generatorPath)) {
72
+ try {
73
+ const generator = await fs.readJson(generatorPath);
74
+ if (generator.envVars) {
75
+ metadata.envVars = metadata.envVars || [];
76
+ for (const [key, value] of Object.entries(generator.envVars)) {
77
+ metadata.envVars.push({ key, value: value, description: `Environment variable for ${key}`, required: true });
78
+ }
79
+ }
80
+ if (generator.dependencies) {
81
+ metadata.dependencies = { ...metadata.dependencies, ...generator.dependencies };
82
+ }
83
+ if (generator.devDependencies) {
84
+ metadata.devDependencies = { ...metadata.devDependencies, ...generator.devDependencies };
85
+ }
86
+ if (generator.postInstall && Array.isArray(generator.postInstall)) {
87
+ metadata.postInstall = metadata.postInstall || [];
88
+ metadata.postInstall.push(...generator.postInstall);
89
+ }
90
+ }
91
+ catch {
92
+ // ignore invalid generator.json
93
+ }
94
+ }
95
+ return metadata;
96
+ }
97
+ function locateOperationSource(generatorType, generatorName, sourceRel) {
98
+ const packageRoot = (0, package_root_1.getPackageRoot)();
99
+ const modulesPath = path.join(packageRoot, 'modules');
100
+ const templatesPath = path.join(packageRoot, 'templates');
101
+ const moduleBasePath = generatorType === 'framework'
102
+ ? path.join(templatesPath, generatorName)
103
+ : path.join(modulesPath, generatorType, generatorName);
104
+ const sourcePath = path.join(moduleBasePath, 'files', sourceRel);
105
+ try {
106
+ return sourcePath;
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ }
112
+ exports.default = {
113
+ mergeModuleIntoGeneratorConfig,
114
+ mergeGeneratorIntoModuleMetadata,
115
+ locateOperationSource,
116
+ };
@@ -3,7 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.initGit = initGit;
4
4
  const child_process_1 = require("child_process");
5
5
  async function initGit(cwd) {
6
+ try {
7
+ (0, child_process_1.execSync)("git --version", { stdio: "pipe" });
8
+ }
9
+ catch {
10
+ throw new Error("Git is not installed or not available in PATH");
11
+ }
12
+ try {
13
+ (0, child_process_1.execSync)("git status", { cwd, stdio: "pipe" });
14
+ return;
15
+ }
16
+ catch {
17
+ // Not a git repo, proceed with initialization
18
+ }
6
19
  (0, child_process_1.execSync)("git init", { cwd, stdio: "pipe" });
7
20
  (0, child_process_1.execSync)("git add .", { cwd, stdio: "pipe" });
21
+ try {
22
+ (0, child_process_1.execSync)("git diff --cached --quiet", { cwd, stdio: "pipe" });
23
+ return;
24
+ }
25
+ catch {
26
+ // Files are staged, proceed with commit
27
+ }
8
28
  (0, child_process_1.execSync)('git commit -m "Initial commit"', { cwd, stdio: "pipe" });
9
29
  }
@@ -63,14 +63,13 @@ async function detectProjectInfo(targetDir) {
63
63
  language = "js";
64
64
  }
65
65
  else {
66
- // Default to TypeScript if neither exists
67
66
  language = "ts";
68
67
  }
69
68
  // Detect package manager
70
69
  const yarnLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "yarn.lock"));
71
70
  const pnpmLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "pnpm-lock.yaml"));
72
71
  const bunLockExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, "bun.lockb"));
73
- let packageManager = "npm";
72
+ let packageManager = "pnpm";
74
73
  if (pnpmLockExists) {
75
74
  packageManager = "pnpm";
76
75
  }
@@ -84,8 +83,7 @@ async function detectProjectInfo(targetDir) {
84
83
  const hasAuth = !!(packageJson.dependencies?.["next-auth"] ||
85
84
  packageJson.dependencies?.["better-auth"] ||
86
85
  packageJson.dependencies?.["@auth/core"] ||
87
- packageJson.dependencies?.["@kinde-oss/kinde-auth-nextjs"] ||
88
- packageJson.dependencies?.["passport"]);
86
+ packageJson.dependencies?.["@kinde-oss/kinde-auth-nextjs"]);
89
87
  const hasPrisma = !!(packageJson.dependencies?.["@prisma/client"] || packageJson.devDependencies?.["prisma"]);
90
88
  const hasDatabase = hasPrisma ||
91
89
  !!(packageJson.dependencies?.["mongoose"] ||
@@ -28,16 +28,6 @@ export interface ModuleMetadata {
28
28
  };
29
29
  }>;
30
30
  postInstall?: string[];
31
- databaseAdapters?: {
32
- common?: {
33
- dependencies?: Record<string, string>;
34
- devDependencies?: Record<string, string>;
35
- };
36
- providers?: Record<string, Record<string, {
37
- dependencies?: Record<string, string>;
38
- devDependencies?: Record<string, string>;
39
- }>>;
40
- };
41
31
  frameworkConfigs?: Record<string, {
42
32
  dependencies?: Record<string, string>;
43
33
  devDependencies?: Record<string, string>;
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "authjs",
3
+ "type": "auth",
4
+ "priority": 10,
5
+ "operations": [],
6
+ "dependencies": {},
7
+ "devDependencies": {},
8
+ "scripts": {},
9
+ "envVars": {}
10
+ }
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "authjs",
3
3
  "displayName": "Auth.js",
4
- "description": "Authentication with Auth.js (NextAuth.js v5)",
5
4
  "category": "auth",
6
5
  "provider": "authjs",
7
6
  "supportedFrameworks": ["nextjs"],
@@ -10,13 +9,5 @@
10
9
  "databases": ["prisma"],
11
10
  "languages": ["typescript", "javascript"],
12
11
  "packageManagers": ["npm", "yarn", "pnpm", "bun"]
13
- },
14
- "databaseAdapters": {
15
- "common": {
16
- "dependencies": {
17
- "@auth/prisma-adapter": "^2.7.1"
18
- },
19
- "devDependencies": {}
20
- }
21
12
  }
22
13
  }
@@ -1,22 +1,22 @@
1
1
  import { betterAuth } from "better-auth";
2
2
  import { sendEmail } from "./email/email-service";
3
3
  import { getVerificationEmailTemplate, getPasswordResetEmailTemplate } from "./email/email-templates";
4
- {{#if database=='prisma'}}
5
- import { prisma } from "{{framework=='nextjs' ? '@/lib' : '.'}}/prisma";
4
+ {{#if database == 'prisma'}}
5
+ import { prisma } from "{{framework == 'nextjs' ? '@/lib' : '.'}}/prisma";
6
6
  import { prismaAdapter } from "better-auth/adapters/prisma";
7
7
  {{/if}}
8
- {{#if database=='mongoose'}}
9
- import { mongoClient, db } from "{{framework=='nextjs' ? '@/lib' : '.'}}/db";
8
+ {{#if database == 'mongoose'}}
9
+ import { mongoClient, db } from "{{framework == 'nextjs' ? '@/lib' : '.'}}/db";
10
10
  import { mongodbAdapter } from "better-auth/adapters/mongodb";
11
11
  {{/if}}
12
12
 
13
13
  export const auth = betterAuth({
14
- {{#if database=='prisma'}}
14
+ {{#if database == 'prisma'}}
15
15
  database: prismaAdapter(prisma, {
16
- provider: {{prismaProvider}},
16
+ provider: "{{prismaProvider}}",
17
17
  }),
18
18
  {{/if}}
19
- {{#if database=='mongoose'}}
19
+ {{#if database == 'mongoose'}}
20
20
  database: mongodbAdapter(db),
21
21
  {{/if}}
22
22
  user: {
@@ -5,49 +5,42 @@
5
5
  "operations": [
6
6
  {
7
7
  "type": "create-file",
8
- "description": "Create Better Auth configuration file",
9
8
  "source": "lib/auth.ts",
10
9
  "destination": "lib/auth.ts",
11
10
  "condition": { "framework": ["nextjs", "express"] }
12
11
  },
13
12
  {
14
13
  "type": "create-file",
15
- "description": "Create email service for sending emails",
16
14
  "source": "lib/email-service.ts",
17
15
  "destination": "lib/email/email-service.ts",
18
16
  "condition": { "framework": ["nextjs", "express"] }
19
17
  },
20
18
  {
21
19
  "type": "create-file",
22
- "description": "Create email templates",
23
20
  "source": "lib/email-templates.ts",
24
21
  "destination": "lib/email/email-templates.ts",
25
22
  "condition": { "framework": ["nextjs", "express"] }
26
23
  },
27
24
  {
28
25
  "type": "create-file",
29
- "description": "Create Better Auth API routes for Next.js",
30
26
  "source": "api/auth/[...all]/route.ts",
31
27
  "destination": "app/api/auth/[...all]/route.ts",
32
28
  "condition": { "framework": "nextjs" }
33
29
  },
34
30
  {
35
31
  "type": "create-file",
36
- "description": "Create Better Auth client for React",
37
32
  "source": "lib/auth-client.ts",
38
33
  "destination": "lib/auth-client.ts",
39
34
  "condition": { "framework": ["nextjs", "react"] }
40
35
  },
41
36
  {
42
37
  "type": "create-file",
43
- "description": "Create Better Auth middleware for Next.js",
44
38
  "destination": "proxy.ts",
45
39
  "condition": { "framework": "nextjs" },
46
40
  "content": "import { auth } from \"@/lib/auth\";\n\nexport default auth((req) => {\n console.log('middleware', req.auth)\n})\n\nexport const config = {\n matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],\n}"
47
41
  },
48
42
  {
49
43
  "type": "patch-file",
50
- "description": "Add Better Auth schema to Prisma schema",
51
44
  "destination": "prisma/schema.prisma",
52
45
  "condition": { "database": "prisma" },
53
46
  "operations": [
@@ -56,15 +49,22 @@
56
49
  "source": "prisma/schema.prisma"
57
50
  }
58
51
  ]
52
+ },
53
+ {
54
+ "type": "add-dependency",
55
+ "condition": { "framework": ["nextjs", "express"] },
56
+ "dependencies": {
57
+ "nodemailer": "^7.0.12"
58
+ },
59
+ "devDependencies": {
60
+ "@types/nodemailer": "^7.0.5"
61
+ }
59
62
  }
60
63
  ],
61
64
  "dependencies": {
62
- "better-auth": "^1.4.12",
63
- "nodemailer": "^7.0.12"
64
- },
65
- "devDependencies": {
66
- "@types/nodemailer": "^7.0.5"
65
+ "better-auth": "^1.4.12"
67
66
  },
67
+ "devDependencies": {},
68
68
  "scripts": {},
69
69
  "envVars": {
70
70
  "BETTER_AUTH_SECRET": "",
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "better-auth",
3
3
  "displayName": "Better Auth",
4
- "description": "Modern authentication with Better Auth",
5
4
  "category": "auth",
6
5
  "provider": "better-auth",
7
6
  "supportedFrameworks": ["nextjs", "express", "react"],
@@ -10,28 +9,5 @@
10
9
  "databases": ["prisma", "mongoose"],
11
10
  "languages": ["typescript", "javascript"],
12
11
  "packageManagers": ["npm", "yarn", "pnpm", "bun"]
13
- },
14
- "databaseAdapters": {
15
- "prisma-postgresql": {
16
- "dependencies": {
17
- "@prisma/adapter-pg": "^5.0.0",
18
- "pg": "^8.0.0"
19
- }
20
- },
21
- "prisma-mongodb": {
22
- "dependencies": {}
23
- },
24
- "prisma-mysql": {
25
- "dependencies": {
26
- "@prisma/adapter-mariadb": "^5.0.0",
27
- "mysql2": "^3.0.0"
28
- }
29
- },
30
- "prisma-sqlite": {
31
- "dependencies": {
32
- "@prisma/adapter-better-sqlite3": "^5.0.0",
33
- "better-sqlite3": "^9.0.0"
34
- }
35
- }
36
12
  }
37
13
  }
@@ -0,0 +1,34 @@
1
+ import mongoose, { Document, Schema } from "mongoose";
2
+
3
+ export interface IHealth extends Document {
4
+ success: boolean;
5
+ message: string;
6
+ version: string;
7
+ createdAt: Date;
8
+ updatedAt: Date;
9
+ }
10
+
11
+ const healthSchema: Schema = new Schema(
12
+ {
13
+ success: {
14
+ type: Boolean,
15
+ default: true,
16
+ },
17
+ message: {
18
+ type: String,
19
+ required: true,
20
+ },
21
+ version: {
22
+ type: String,
23
+ required: true,
24
+ },
25
+ },
26
+ {
27
+ timestamps: true,
28
+ },
29
+ );
30
+
31
+ // Add indexes for better performance
32
+ healthSchema.index({ createdAt: -1 });
33
+
34
+ export default mongoose.models.Health || mongoose.model<IHealth>("Health", healthSchema);
@@ -5,13 +5,13 @@
5
5
  "operations": [
6
6
  {
7
7
  "type": "create-file",
8
- "source": "lib/db.ts",
9
- "destination": "src/lib/db.ts"
8
+ "source": "lib/mongoose.ts",
9
+ "destination": "src/lib/mongoose.ts"
10
10
  },
11
11
  {
12
12
  "type": "create-file",
13
- "source": "models/User.ts",
14
- "destination": "src/lib/models.ts"
13
+ "source": "models/health.ts",
14
+ "destination": "models/health.ts"
15
15
  }
16
16
  ],
17
17
  "dependencies": {
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "mongoose",
3
- "displayName": "Mongoose (MongoDB)",
4
- "description": "Mongoose ODM for MongoDB database",
3
+ "displayName": "Mongoose",
5
4
  "category": "database",
6
5
  "provider": "mongoose",
7
6
  "database": "mongodb",
@@ -1,4 +1,5 @@
1
- import { PrismaClient } from '@prisma/client'
1
+ import 'dotenv/config'
2
+ import { PrismaClient } from './generated/prisma/client'
2
3
 
3
4
  const globalForPrisma = globalThis as unknown as {
4
5
  prisma: PrismaClient | undefined