create-stackkit-app 0.4.1 → 0.4.2

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 (96) hide show
  1. package/README.md +26 -7
  2. package/dist/lib/create-project.js +88 -5
  3. package/dist/lib/template-composer.js +1 -1
  4. package/modules/auth/better-auth-express/adapters/mongoose-mongodb.ts +13 -0
  5. package/modules/auth/better-auth-express/adapters/prisma-mongodb.ts +15 -0
  6. package/modules/auth/better-auth-express/adapters/prisma-postgresql.ts +15 -0
  7. package/modules/auth/better-auth-express/files/schemas/prisma-mongodb-schema.prisma +72 -0
  8. package/modules/auth/better-auth-express/files/schemas/prisma-postgresql-schema.prisma +72 -0
  9. package/modules/auth/better-auth-express/module.json +26 -3
  10. package/modules/auth/better-auth-nextjs/adapters/mongoose-mongodb.ts +24 -0
  11. package/modules/auth/better-auth-nextjs/adapters/prisma-mongodb.ts +26 -0
  12. package/modules/auth/better-auth-nextjs/adapters/prisma-postgresql.ts +26 -0
  13. package/modules/auth/better-auth-nextjs/files/schemas/prisma-mongodb-schema.prisma +72 -0
  14. package/modules/auth/better-auth-nextjs/files/schemas/prisma-postgresql-schema.prisma +72 -0
  15. package/modules/auth/better-auth-nextjs/module.json +26 -5
  16. package/modules/auth/better-auth-react/module.json +7 -5
  17. package/modules/auth/clerk-express/module.json +23 -8
  18. package/modules/auth/clerk-nextjs/module.json +51 -14
  19. package/modules/auth/clerk-react/module.json +17 -7
  20. package/modules/database/mongoose-mongodb/module.json +44 -6
  21. package/modules/database/prisma-mongodb/files/prisma/schema.prisma +1 -1
  22. package/modules/database/prisma-mongodb/module.json +28 -4
  23. package/modules/database/prisma-postgresql/files/prisma/schema.prisma +1 -1
  24. package/modules/database/prisma-postgresql/module.json +28 -4
  25. package/package.json +1 -1
  26. package/templates/express/.env.example +11 -0
  27. package/templates/express/eslint.config.cjs +42 -0
  28. package/templates/express/package.json +38 -0
  29. package/templates/express/src/app.ts +69 -0
  30. package/templates/express/src/config/env.ts +23 -0
  31. package/templates/{bases/express-base → express}/src/middlewares/error.middleware.ts +9 -3
  32. package/templates/{bases/nextjs-base → nextjs}/app/page.tsx +5 -5
  33. package/templates/react-vite/.env.example +2 -0
  34. package/templates/react-vite/README.md +85 -0
  35. package/templates/{bases/react-vite-base → react-vite}/index.html +1 -0
  36. package/templates/{bases/react-vite-base → react-vite}/package.json +18 -3
  37. package/templates/react-vite/src/api/client.ts +47 -0
  38. package/templates/react-vite/src/api/services/user.service.ts +26 -0
  39. package/templates/react-vite/src/components/ErrorBoundary.tsx +51 -0
  40. package/templates/react-vite/src/components/Layout.tsx +13 -0
  41. package/templates/react-vite/src/components/Loading.tsx +8 -0
  42. package/templates/react-vite/src/components/SEO.tsx +49 -0
  43. package/templates/react-vite/src/config/constants.ts +5 -0
  44. package/templates/react-vite/src/hooks/index.ts +64 -0
  45. package/templates/react-vite/src/index.css +1 -0
  46. package/templates/react-vite/src/lib/queryClient.ts +12 -0
  47. package/templates/react-vite/src/main.tsx +22 -0
  48. package/templates/react-vite/src/pages/About.tsx +74 -0
  49. package/templates/react-vite/src/pages/Home.tsx +45 -0
  50. package/templates/react-vite/src/pages/NotFound.tsx +24 -0
  51. package/templates/react-vite/src/pages/UserProfile.tsx +40 -0
  52. package/templates/react-vite/src/router.tsx +33 -0
  53. package/templates/react-vite/src/types/api.ts +20 -0
  54. package/templates/react-vite/src/utils/helpers.ts +51 -0
  55. package/templates/react-vite/src/utils/storage.ts +35 -0
  56. package/templates/react-vite/src/vite-env.d.ts +11 -0
  57. package/templates/{bases/react-vite-base → react-vite}/template.json +2 -1
  58. package/templates/react-vite/vite.config.ts +13 -0
  59. package/modules/database/drizzle-postgresql/files/drizzle.config.ts +0 -10
  60. package/modules/database/drizzle-postgresql/files/lib/db.ts +0 -7
  61. package/modules/database/drizzle-postgresql/files/lib/schema.ts +0 -8
  62. package/modules/database/drizzle-postgresql/module.json +0 -34
  63. package/templates/bases/express-base/.env.example +0 -2
  64. package/templates/bases/express-base/package.json +0 -23
  65. package/templates/bases/express-base/src/app.ts +0 -34
  66. package/templates/bases/express-base/src/config/env.ts +0 -14
  67. package/templates/bases/react-vite-base/README.md +0 -73
  68. package/templates/bases/react-vite-base/src/App.css +0 -42
  69. package/templates/bases/react-vite-base/src/App.tsx +0 -35
  70. package/templates/bases/react-vite-base/src/index.css +0 -68
  71. package/templates/bases/react-vite-base/src/main.tsx +0 -10
  72. package/templates/bases/react-vite-base/vite.config.ts +0 -7
  73. /package/templates/{bases/express-base → express}/src/server.ts +0 -0
  74. /package/templates/{bases/express-base → express}/template.json +0 -0
  75. /package/templates/{bases/express-base → express}/tsconfig.json +0 -0
  76. /package/templates/{bases/nextjs-base → nextjs}/README.md +0 -0
  77. /package/templates/{bases/nextjs-base → nextjs}/app/favicon.ico +0 -0
  78. /package/templates/{bases/nextjs-base → nextjs}/app/globals.css +0 -0
  79. /package/templates/{bases/nextjs-base → nextjs}/app/layout.tsx +0 -0
  80. /package/templates/{bases/nextjs-base → nextjs}/eslint.config.mjs +0 -0
  81. /package/templates/{bases/nextjs-base → nextjs}/next.config.ts +0 -0
  82. /package/templates/{bases/nextjs-base → nextjs}/package.json +0 -0
  83. /package/templates/{bases/nextjs-base → nextjs}/postcss.config.mjs +0 -0
  84. /package/templates/{bases/nextjs-base → nextjs}/public/file.svg +0 -0
  85. /package/templates/{bases/nextjs-base → nextjs}/public/globe.svg +0 -0
  86. /package/templates/{bases/nextjs-base → nextjs}/public/next.svg +0 -0
  87. /package/templates/{bases/nextjs-base → nextjs}/public/vercel.svg +0 -0
  88. /package/templates/{bases/nextjs-base → nextjs}/public/window.svg +0 -0
  89. /package/templates/{bases/nextjs-base → nextjs}/template.json +0 -0
  90. /package/templates/{bases/nextjs-base → nextjs}/tsconfig.json +0 -0
  91. /package/templates/{bases/react-vite-base → react-vite}/eslint.config.js +0 -0
  92. /package/templates/{bases/react-vite-base → react-vite}/public/vite.svg +0 -0
  93. /package/templates/{bases/react-vite-base → react-vite}/src/assets/react.svg +0 -0
  94. /package/templates/{bases/react-vite-base → react-vite}/tsconfig.app.json +0 -0
  95. /package/templates/{bases/react-vite-base → react-vite}/tsconfig.json +0 -0
  96. /package/templates/{bases/react-vite-base → react-vite}/tsconfig.node.json +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # create-stackkit-app
2
2
 
3
- Create production-ready projects with one command.
3
+ Create production-ready projects with your preferred stack in seconds.
4
4
 
5
5
  ## Usage
6
6
 
@@ -9,12 +9,31 @@ npx create-stackkit-app my-app
9
9
  ```
10
10
 
11
11
  Interactive wizard helps you choose:
12
- - Framework (Next.js, Express, React)
13
- - Database (Prisma, Drizzle, Mongoose)
14
- - Authentication (Better Auth, Auth.js, Clerk, NextAuth)
15
- - Language (TypeScript/JavaScript)
16
- - Package manager (pnpm, npm, yarn)
12
+ - **Framework**: Next.js, Express, or React + Vite
13
+ - **Database**: Prisma (PostgreSQL/MongoDB), Mongoose (MongoDB)
14
+ - **Authentication**: Better Auth, Clerk
15
+ - **Package manager**: pnpm, npm, or yarn
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Create project
21
+ npx create-stackkit-app my-app
22
+
23
+ # Navigate and run
24
+ cd my-app
25
+ npm run dev
26
+ ```
27
+
28
+ ## Features
29
+
30
+ - TypeScript configured
31
+ - ESLint + Prettier set up
32
+ - Tailwind CSS included
33
+ - Database client configured
34
+ - Auth flows ready (if selected)
35
+ - Environment variables templated
17
36
 
18
37
  ## Documentation
19
38
 
20
- See [main repository](https://github.com/tariqul420/stackkit) for full documentation.
39
+ Full documentation available at [stackkit.dev](https://stackkit.dev) or [GitHub](https://github.com/tariqul420/stackkit)
@@ -167,11 +167,11 @@ async function composeTemplate(config, targetDir) {
167
167
  await copyBaseFramework(templatesDir, targetDir, config.framework);
168
168
  // 2. Merge database configuration
169
169
  if (config.database !== 'none') {
170
- await mergeDatabaseConfig(templatesDir, targetDir, config.database);
170
+ await mergeDatabaseConfig(templatesDir, targetDir, config.database, config.framework);
171
171
  }
172
172
  // 3. Merge auth configuration
173
173
  if (config.auth !== 'none') {
174
- await mergeAuthConfig(templatesDir, targetDir, config.framework, config.auth);
174
+ await mergeAuthConfig(templatesDir, targetDir, config.framework, config.auth, config.database);
175
175
  }
176
176
  // 4. Update package.json with project name
177
177
  const packageJsonPath = path_1.default.join(targetDir, 'package.json');
@@ -186,7 +186,7 @@ async function composeTemplate(config, targetDir) {
186
186
  }
187
187
  }
188
188
  async function copyBaseFramework(templatesDir, targetDir, framework) {
189
- const baseDir = path_1.default.join(templatesDir, 'bases', `${framework}-base`);
189
+ const baseDir = path_1.default.join(templatesDir, framework);
190
190
  if (!(await fs_extra_1.default.pathExists(baseDir))) {
191
191
  throw new Error(`Base template not found for framework: ${framework}\n` + `Expected at: ${baseDir}`);
192
192
  }
@@ -197,7 +197,7 @@ async function copyBaseFramework(templatesDir, targetDir, framework) {
197
197
  },
198
198
  });
199
199
  }
200
- async function mergeDatabaseConfig(templatesDir, targetDir, database) {
200
+ async function mergeDatabaseConfig(templatesDir, targetDir, database, framework) {
201
201
  // Use modules directory (sibling to templates)
202
202
  const modulesDir = path_1.default.join(templatesDir, '..', 'modules');
203
203
  const dbModulePath = path_1.default.join(modulesDir, 'database', database);
@@ -239,8 +239,16 @@ async function mergeDatabaseConfig(templatesDir, targetDir, database) {
239
239
  envVars[envVar.key] = envVar.value;
240
240
  }
241
241
  await mergeEnvFile(targetDir, envVars);
242
+ // Apply framework-specific patches from database module
243
+ if (moduleData.frameworkPatches) {
244
+ const frameworkKey = framework === 'react-vite' ? 'react' : framework;
245
+ const patches = moduleData.frameworkPatches[frameworkKey];
246
+ if (patches) {
247
+ await applyFrameworkPatches(targetDir, patches);
248
+ }
249
+ }
242
250
  }
243
- async function mergeAuthConfig(templatesDir, targetDir, framework, auth) {
251
+ async function mergeAuthConfig(templatesDir, targetDir, framework, auth, database = 'none') {
244
252
  // Use modules directory (sibling to templates)
245
253
  const modulesDir = path_1.default.join(templatesDir, '..', 'modules');
246
254
  // Auth modules are now named with framework suffix
@@ -300,6 +308,47 @@ async function mergeAuthConfig(templatesDir, targetDir, framework, auth) {
300
308
  }
301
309
  }
302
310
  }
311
+ // Handle database-specific adapters and schemas
312
+ if (database !== 'none' && moduleData.databaseAdapters) {
313
+ const adapterConfig = moduleData.databaseAdapters[database];
314
+ if (adapterConfig) {
315
+ // Copy adapter file
316
+ if (adapterConfig.adapter) {
317
+ const adapterSource = path_1.default.join(authModulePath, adapterConfig.adapter);
318
+ const adapterFileName = path_1.default.basename(adapterConfig.adapter);
319
+ // Determine destination based on framework
320
+ let adapterDest;
321
+ if (framework === 'nextjs') {
322
+ adapterDest = path_1.default.join(targetDir, 'lib', 'auth.ts');
323
+ }
324
+ else if (framework === 'express') {
325
+ adapterDest = path_1.default.join(targetDir, 'src', 'auth.ts');
326
+ }
327
+ else {
328
+ adapterDest = path_1.default.join(targetDir, 'src', 'lib', 'auth.ts');
329
+ }
330
+ if (await fs_extra_1.default.pathExists(adapterSource)) {
331
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(adapterDest));
332
+ await fs_extra_1.default.copy(adapterSource, adapterDest, { overwrite: true });
333
+ }
334
+ }
335
+ // Copy schema file if it exists
336
+ if (adapterConfig.schema && adapterConfig.schemaDestination) {
337
+ const schemaSource = path_1.default.join(authModulePath, adapterConfig.schema);
338
+ const schemaDest = path_1.default.join(targetDir, adapterConfig.schemaDestination);
339
+ if (await fs_extra_1.default.pathExists(schemaSource)) {
340
+ await fs_extra_1.default.ensureDir(path_1.default.dirname(schemaDest));
341
+ await fs_extra_1.default.copy(schemaSource, schemaDest, { overwrite: true });
342
+ }
343
+ }
344
+ // Merge adapter-specific dependencies
345
+ if (adapterConfig.dependencies) {
346
+ await mergePackageJson(targetDir, {
347
+ dependencies: adapterConfig.dependencies,
348
+ });
349
+ }
350
+ }
351
+ }
303
352
  // Merge package.json with module dependencies
304
353
  await mergePackageJson(targetDir, {
305
354
  dependencies: moduleData.dependencies,
@@ -426,6 +475,40 @@ async function initGit(cwd) {
426
475
  throw new Error('Git initialization failed');
427
476
  }
428
477
  }
478
+ async function applyFrameworkPatches(targetDir, patches) {
479
+ for (const [filename, patchConfig] of Object.entries(patches)) {
480
+ const filePath = path_1.default.join(targetDir, filename);
481
+ if (await fs_extra_1.default.pathExists(filePath)) {
482
+ const fileContent = await fs_extra_1.default.readJson(filePath);
483
+ if (patchConfig.merge) {
484
+ // Deep merge configuration
485
+ const merged = deepMerge(fileContent, patchConfig.merge);
486
+ await fs_extra_1.default.writeJson(filePath, merged, { spaces: 2 });
487
+ }
488
+ }
489
+ }
490
+ }
491
+ function deepMerge(target, source) {
492
+ const output = { ...target };
493
+ for (const key in source) {
494
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
495
+ if (target[key]) {
496
+ output[key] = deepMerge(target[key], source[key]);
497
+ }
498
+ else {
499
+ output[key] = source[key];
500
+ }
501
+ }
502
+ else if (Array.isArray(source[key])) {
503
+ // For arrays, merge uniquely
504
+ output[key] = Array.from(new Set([...(target[key] || []), ...source[key]]));
505
+ }
506
+ else {
507
+ output[key] = source[key];
508
+ }
509
+ }
510
+ return output;
511
+ }
429
512
  function showNextSteps(config) {
430
513
  console.log(chalk_1.default.green.bold(`\n✓ Created ${config.projectName}\n`));
431
514
  console.log(chalk_1.default.bold('Next steps:'));
@@ -17,7 +17,7 @@ class TemplateComposer {
17
17
  const configs = [];
18
18
  const filesToCopy = [];
19
19
  // 1. Load base framework template
20
- const baseConfig = await this.loadConfig(path_1.default.join(this.templatesDir, 'bases', `${framework}-base`));
20
+ const baseConfig = await this.loadConfig(path_1.default.join(this.templatesDir, framework));
21
21
  configs.push(baseConfig);
22
22
  // Copy base files
23
23
  const baseFiles = await this.getBaseFiles(framework);
@@ -0,0 +1,13 @@
1
+ import { betterAuth } from 'better-auth';
2
+ import { mongodbAdapter } from 'better-auth/adapters/mongodb';
3
+ import { client } from './db';
4
+
5
+ export const auth = betterAuth({
6
+ database: mongodbAdapter(client),
7
+ emailAndPassword: {
8
+ enabled: true,
9
+ },
10
+ });
11
+
12
+ export type Session = typeof auth.$Infer.Session;
13
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,15 @@
1
+ import { prismaAdapter } from '@better-auth/prisma';
2
+ import { betterAuth } from 'better-auth';
3
+ import { prisma } from './db';
4
+
5
+ export const auth = betterAuth({
6
+ database: prismaAdapter(prisma, {
7
+ provider: 'mongodb',
8
+ }),
9
+ emailAndPassword: {
10
+ enabled: true,
11
+ },
12
+ });
13
+
14
+ export type Session = typeof auth.$Infer.Session;
15
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,15 @@
1
+ import { prismaAdapter } from '@better-auth/prisma';
2
+ import { betterAuth } from 'better-auth';
3
+ import { prisma } from './db';
4
+
5
+ export const auth = betterAuth({
6
+ database: prismaAdapter(prisma, {
7
+ provider: 'postgresql',
8
+ }),
9
+ emailAndPassword: {
10
+ enabled: true,
11
+ },
12
+ });
13
+
14
+ export type Session = typeof auth.$Infer.Session;
15
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,72 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "mongodb"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ // Better Auth models for MongoDB
11
+ model User {
12
+ id String @id @default(auto()) @map("_id") @db.ObjectId
13
+ name String
14
+ email String
15
+ emailVerified Boolean @default(false)
16
+ image String?
17
+ createdAt DateTime @default(now())
18
+ updatedAt DateTime @updatedAt
19
+ sessions Session[]
20
+ accounts Account[]
21
+ role String @default("USER")
22
+
23
+ @@unique([email])
24
+ @@map("user")
25
+ }
26
+
27
+ model Session {
28
+ id String @id @default(auto()) @map("_id") @db.ObjectId
29
+ expiresAt DateTime
30
+ token String @unique
31
+ createdAt DateTime @default(now())
32
+ updatedAt DateTime @updatedAt
33
+ ipAddress String?
34
+ userAgent String?
35
+ userId String @db.ObjectId
36
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
+
38
+ @@index([userId])
39
+ @@map("session")
40
+ }
41
+
42
+ model Account {
43
+ id String @id @default(auto()) @map("_id") @db.ObjectId
44
+ accountId String
45
+ providerId String
46
+ userId String @db.ObjectId
47
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
48
+ accessToken String?
49
+ refreshToken String?
50
+ idToken String?
51
+ accessTokenExpiresAt DateTime?
52
+ refreshTokenExpiresAt DateTime?
53
+ scope String?
54
+ password String?
55
+ createdAt DateTime @default(now())
56
+ updatedAt DateTime @updatedAt
57
+
58
+ @@index([userId])
59
+ @@map("account")
60
+ }
61
+
62
+ model Verification {
63
+ id String @id @default(auto()) @map("_id") @db.ObjectId
64
+ identifier String
65
+ value String
66
+ expiresAt DateTime
67
+ createdAt DateTime @default(now())
68
+ updatedAt DateTime @updatedAt
69
+
70
+ @@index([identifier])
71
+ @@map("verification")
72
+ }
@@ -0,0 +1,72 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ // Better Auth models for PostgreSQL
11
+ model User {
12
+ id String @id @default(cuid())
13
+ name String
14
+ email String
15
+ emailVerified Boolean @default(false)
16
+ image String?
17
+ createdAt DateTime @default(now())
18
+ updatedAt DateTime @updatedAt
19
+ sessions Session[]
20
+ accounts Account[]
21
+ role String @default("USER")
22
+
23
+ @@unique([email])
24
+ @@map("user")
25
+ }
26
+
27
+ model Session {
28
+ id String @id @default(cuid())
29
+ expiresAt DateTime
30
+ token String @unique
31
+ createdAt DateTime @default(now())
32
+ updatedAt DateTime @updatedAt
33
+ ipAddress String?
34
+ userAgent String?
35
+ userId String
36
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
+
38
+ @@index([userId])
39
+ @@map("session")
40
+ }
41
+
42
+ model Account {
43
+ id String @id @default(cuid())
44
+ accountId String
45
+ providerId String
46
+ userId String
47
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
48
+ accessToken String?
49
+ refreshToken String?
50
+ idToken String?
51
+ accessTokenExpiresAt DateTime?
52
+ refreshTokenExpiresAt DateTime?
53
+ scope String?
54
+ password String?
55
+ createdAt DateTime @default(now())
56
+ updatedAt DateTime @updatedAt
57
+
58
+ @@index([userId])
59
+ @@map("account")
60
+ }
61
+
62
+ model Verification {
63
+ id String @id @default(cuid())
64
+ identifier String
65
+ value String
66
+ expiresAt DateTime
67
+ createdAt DateTime @default(now())
68
+ updatedAt DateTime @updatedAt
69
+
70
+ @@index([identifier])
71
+ @@map("verification")
72
+ }
@@ -1,11 +1,34 @@
1
1
  {
2
- "name": "auth",
2
+ "name": "better-auth-express",
3
3
  "displayName": "Better Auth (Express)",
4
4
  "description": "Modern authentication with Better Auth for Express",
5
5
  "category": "auth",
6
6
  "supportedFrameworks": ["express"],
7
- "dependencies": {
8
- "better-auth": "^1.0.0"
7
+ "databaseAdapters": {
8
+ "prisma-postgresql": {
9
+ "adapter": "adapters/prisma-postgresql.ts",
10
+ "schema": "files/schemas/prisma-postgresql-schema.prisma",
11
+ "schemaDestination": "prisma/schema.prisma",
12
+ "dependencies": {
13
+ "better-auth": "^1.1.4",
14
+ "@better-auth/prisma": "^1.1.4"
15
+ }
16
+ },
17
+ "prisma-mongodb": {
18
+ "adapter": "adapters/prisma-mongodb.ts",
19
+ "schema": "files/schemas/prisma-mongodb-schema.prisma",
20
+ "schemaDestination": "prisma/schema.prisma",
21
+ "dependencies": {
22
+ "better-auth": "^1.1.4",
23
+ "@better-auth/prisma": "^1.1.4"
24
+ }
25
+ },
26
+ "mongoose-mongodb": {
27
+ "adapter": "adapters/mongoose-mongodb.ts",
28
+ "dependencies": {
29
+ "better-auth": "^1.1.4"
30
+ }
31
+ }
9
32
  },
10
33
  "envVars": [
11
34
  {
@@ -0,0 +1,24 @@
1
+ import { client } from '@/lib/db';
2
+ import { betterAuth } from 'better-auth';
3
+ import { mongodbAdapter } from 'better-auth/adapters/mongodb';
4
+
5
+ export const auth = betterAuth({
6
+ database: mongodbAdapter(client),
7
+ emailAndPassword: {
8
+ enabled: true,
9
+ },
10
+ socialProviders: {
11
+ // Uncomment to add OAuth providers
12
+ // google: {
13
+ // clientId: process.env.GOOGLE_CLIENT_ID!,
14
+ // clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
15
+ // },
16
+ // github: {
17
+ // clientId: process.env.GITHUB_CLIENT_ID!,
18
+ // clientSecret: process.env.GITHUB_CLIENT_SECRET!,
19
+ // },
20
+ },
21
+ });
22
+
23
+ export type Session = typeof auth.$Infer.Session;
24
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,26 @@
1
+ import { prisma } from '@/lib/db';
2
+ import { prismaAdapter } from '@better-auth/prisma';
3
+ import { betterAuth } from 'better-auth';
4
+
5
+ export const auth = betterAuth({
6
+ database: prismaAdapter(prisma, {
7
+ provider: 'mongodb',
8
+ }),
9
+ emailAndPassword: {
10
+ enabled: true,
11
+ },
12
+ socialProviders: {
13
+ // Uncomment to add OAuth providers
14
+ // google: {
15
+ // clientId: process.env.GOOGLE_CLIENT_ID!,
16
+ // clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
17
+ // },
18
+ // github: {
19
+ // clientId: process.env.GITHUB_CLIENT_ID!,
20
+ // clientSecret: process.env.GITHUB_CLIENT_SECRET!,
21
+ // },
22
+ },
23
+ });
24
+
25
+ export type Session = typeof auth.$Infer.Session;
26
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,26 @@
1
+ import { prisma } from '@/lib/db';
2
+ import { prismaAdapter } from '@better-auth/prisma';
3
+ import { betterAuth } from 'better-auth';
4
+
5
+ export const auth = betterAuth({
6
+ database: prismaAdapter(prisma, {
7
+ provider: 'postgresql',
8
+ }),
9
+ emailAndPassword: {
10
+ enabled: true,
11
+ },
12
+ socialProviders: {
13
+ // Uncomment to add OAuth providers
14
+ // google: {
15
+ // clientId: process.env.GOOGLE_CLIENT_ID!,
16
+ // clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
17
+ // },
18
+ // github: {
19
+ // clientId: process.env.GITHUB_CLIENT_ID!,
20
+ // clientSecret: process.env.GITHUB_CLIENT_SECRET!,
21
+ // },
22
+ },
23
+ });
24
+
25
+ export type Session = typeof auth.$Infer.Session;
26
+ export type User = typeof auth.$Infer.User;
@@ -0,0 +1,72 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "mongodb"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ // Better Auth models for MongoDB
11
+ model User {
12
+ id String @id @default(auto()) @map("_id") @db.ObjectId
13
+ name String
14
+ email String
15
+ emailVerified Boolean @default(false)
16
+ image String?
17
+ createdAt DateTime @default(now())
18
+ updatedAt DateTime @updatedAt
19
+ sessions Session[]
20
+ accounts Account[]
21
+ role String @default("USER")
22
+
23
+ @@unique([email])
24
+ @@map("user")
25
+ }
26
+
27
+ model Session {
28
+ id String @id @default(auto()) @map("_id") @db.ObjectId
29
+ expiresAt DateTime
30
+ token String @unique
31
+ createdAt DateTime @default(now())
32
+ updatedAt DateTime @updatedAt
33
+ ipAddress String?
34
+ userAgent String?
35
+ userId String @db.ObjectId
36
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
+
38
+ @@index([userId])
39
+ @@map("session")
40
+ }
41
+
42
+ model Account {
43
+ id String @id @default(auto()) @map("_id") @db.ObjectId
44
+ accountId String
45
+ providerId String
46
+ userId String @db.ObjectId
47
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
48
+ accessToken String?
49
+ refreshToken String?
50
+ idToken String?
51
+ accessTokenExpiresAt DateTime?
52
+ refreshTokenExpiresAt DateTime?
53
+ scope String?
54
+ password String?
55
+ createdAt DateTime @default(now())
56
+ updatedAt DateTime @updatedAt
57
+
58
+ @@index([userId])
59
+ @@map("account")
60
+ }
61
+
62
+ model Verification {
63
+ id String @id @default(auto()) @map("_id") @db.ObjectId
64
+ identifier String
65
+ value String
66
+ expiresAt DateTime
67
+ createdAt DateTime @default(now())
68
+ updatedAt DateTime @updatedAt
69
+
70
+ @@index([identifier])
71
+ @@map("verification")
72
+ }
@@ -0,0 +1,72 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ // Better Auth models for PostgreSQL
11
+ model User {
12
+ id String @id @default(cuid())
13
+ name String
14
+ email String
15
+ emailVerified Boolean @default(false)
16
+ image String?
17
+ createdAt DateTime @default(now())
18
+ updatedAt DateTime @updatedAt
19
+ sessions Session[]
20
+ accounts Account[]
21
+ role String @default("USER")
22
+
23
+ @@unique([email])
24
+ @@map("user")
25
+ }
26
+
27
+ model Session {
28
+ id String @id @default(cuid())
29
+ expiresAt DateTime
30
+ token String @unique
31
+ createdAt DateTime @default(now())
32
+ updatedAt DateTime @updatedAt
33
+ ipAddress String?
34
+ userAgent String?
35
+ userId String
36
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
+
38
+ @@index([userId])
39
+ @@map("session")
40
+ }
41
+
42
+ model Account {
43
+ id String @id @default(cuid())
44
+ accountId String
45
+ providerId String
46
+ userId String
47
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
48
+ accessToken String?
49
+ refreshToken String?
50
+ idToken String?
51
+ accessTokenExpiresAt DateTime?
52
+ refreshTokenExpiresAt DateTime?
53
+ scope String?
54
+ password String?
55
+ createdAt DateTime @default(now())
56
+ updatedAt DateTime @updatedAt
57
+
58
+ @@index([userId])
59
+ @@map("account")
60
+ }
61
+
62
+ model Verification {
63
+ id String @id @default(cuid())
64
+ identifier String
65
+ value String
66
+ expiresAt DateTime
67
+ createdAt DateTime @default(now())
68
+ updatedAt DateTime @updatedAt
69
+
70
+ @@index([identifier])
71
+ @@map("verification")
72
+ }