create-stackkit-app 0.4.0 → 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 (109) hide show
  1. package/README.md +25 -11
  2. package/dist/lib/create-project.js +88 -8
  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 +3 -3
  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/express/src/middlewares/error.middleware.ts +18 -0
  32. package/templates/express/src/server.ts +8 -0
  33. package/templates/{bases/express-base → express}/template.json +1 -1
  34. package/templates/express/tsconfig.json +14 -0
  35. package/templates/{bases/nextjs-base → nextjs}/app/page.tsx +5 -5
  36. package/templates/{bases/nextjs-base → nextjs}/template.json +1 -1
  37. package/templates/react-vite/.env.example +2 -0
  38. package/templates/react-vite/README.md +85 -0
  39. package/templates/react-vite/eslint.config.js +23 -0
  40. package/templates/{bases/react-vite-base → react-vite}/index.html +2 -1
  41. package/templates/react-vite/package.json +45 -0
  42. package/templates/react-vite/public/vite.svg +1 -0
  43. package/templates/react-vite/src/api/client.ts +47 -0
  44. package/templates/react-vite/src/api/services/user.service.ts +26 -0
  45. package/templates/react-vite/src/assets/react.svg +1 -0
  46. package/templates/react-vite/src/components/ErrorBoundary.tsx +51 -0
  47. package/templates/react-vite/src/components/Layout.tsx +13 -0
  48. package/templates/react-vite/src/components/Loading.tsx +8 -0
  49. package/templates/react-vite/src/components/SEO.tsx +49 -0
  50. package/templates/react-vite/src/config/constants.ts +5 -0
  51. package/templates/react-vite/src/hooks/index.ts +64 -0
  52. package/templates/react-vite/src/index.css +1 -0
  53. package/templates/react-vite/src/lib/queryClient.ts +12 -0
  54. package/templates/react-vite/src/main.tsx +22 -0
  55. package/templates/react-vite/src/pages/About.tsx +74 -0
  56. package/templates/react-vite/src/pages/Home.tsx +45 -0
  57. package/templates/react-vite/src/pages/NotFound.tsx +24 -0
  58. package/templates/react-vite/src/pages/UserProfile.tsx +40 -0
  59. package/templates/react-vite/src/router.tsx +33 -0
  60. package/templates/react-vite/src/types/api.ts +20 -0
  61. package/templates/react-vite/src/utils/helpers.ts +51 -0
  62. package/templates/react-vite/src/utils/storage.ts +35 -0
  63. package/templates/react-vite/src/vite-env.d.ts +11 -0
  64. package/templates/react-vite/template.json +20 -0
  65. package/templates/{bases/react-vite-base/tsconfig.json → react-vite/tsconfig.app.json} +10 -3
  66. package/templates/react-vite/tsconfig.json +7 -0
  67. package/templates/react-vite/tsconfig.node.json +26 -0
  68. package/templates/react-vite/vite.config.ts +13 -0
  69. package/modules/auth/authjs-express/files/lib/auth.ts +0 -40
  70. package/modules/auth/authjs-express/files/routes/auth.ts +0 -12
  71. package/modules/auth/authjs-express/module.json +0 -39
  72. package/modules/auth/authjs-nextjs/files/api/auth/[...nextauth]/route.ts +0 -3
  73. package/modules/auth/authjs-nextjs/files/lib/auth.ts +0 -43
  74. package/modules/auth/authjs-nextjs/module.json +0 -38
  75. package/modules/auth/nextauth/files/app-router/api/auth/[...nextauth]/route.ts +0 -6
  76. package/modules/auth/nextauth/files/lib/auth.ts +0 -82
  77. package/modules/auth/nextauth/files/pages-router/api/auth/[...nextauth].ts +0 -4
  78. package/modules/auth/nextauth/module.json +0 -50
  79. package/modules/database/drizzle-postgresql/files/drizzle.config.ts +0 -10
  80. package/modules/database/drizzle-postgresql/files/lib/db.ts +0 -7
  81. package/modules/database/drizzle-postgresql/files/lib/schema.ts +0 -8
  82. package/modules/database/drizzle-postgresql/module.json +0 -34
  83. package/templates/bases/express-base/.env.example +0 -2
  84. package/templates/bases/express-base/package.json +0 -23
  85. package/templates/bases/express-base/src/index.ts +0 -27
  86. package/templates/bases/express-base/tsconfig.json +0 -17
  87. package/templates/bases/nextjs-base/package-lock.json +0 -6538
  88. package/templates/bases/react-vite-base/package.json +0 -27
  89. package/templates/bases/react-vite-base/src/App.css +0 -14
  90. package/templates/bases/react-vite-base/src/App.tsx +0 -23
  91. package/templates/bases/react-vite-base/src/index.css +0 -68
  92. package/templates/bases/react-vite-base/src/main.tsx +0 -10
  93. package/templates/bases/react-vite-base/src/vite-env.d.ts +0 -1
  94. package/templates/bases/react-vite-base/template.json +0 -5
  95. package/templates/bases/react-vite-base/vite.config.ts +0 -7
  96. /package/templates/{bases/nextjs-base → nextjs}/README.md +0 -0
  97. /package/templates/{bases/nextjs-base → nextjs}/app/favicon.ico +0 -0
  98. /package/templates/{bases/nextjs-base → nextjs}/app/globals.css +0 -0
  99. /package/templates/{bases/nextjs-base → nextjs}/app/layout.tsx +0 -0
  100. /package/templates/{bases/nextjs-base → nextjs}/eslint.config.mjs +0 -0
  101. /package/templates/{bases/nextjs-base → nextjs}/next.config.ts +0 -0
  102. /package/templates/{bases/nextjs-base → nextjs}/package.json +0 -0
  103. /package/templates/{bases/nextjs-base → nextjs}/postcss.config.mjs +0 -0
  104. /package/templates/{bases/nextjs-base → nextjs}/public/file.svg +0 -0
  105. /package/templates/{bases/nextjs-base → nextjs}/public/globe.svg +0 -0
  106. /package/templates/{bases/nextjs-base → nextjs}/public/next.svg +0 -0
  107. /package/templates/{bases/nextjs-base → nextjs}/public/vercel.svg +0 -0
  108. /package/templates/{bases/nextjs-base → nextjs}/public/window.svg +0 -0
  109. /package/templates/{bases/nextjs-base → nextjs}/tsconfig.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
 
@@ -8,18 +8,32 @@ Create production-ready projects with one command.
8
8
  npx create-stackkit-app my-app
9
9
  ```
10
10
 
11
- Interactive wizard for:
12
- - **Framework**: Next.js, Express, React (Vite)
13
- - **Database**: Prisma, Drizzle, Mongoose, or none
14
- - **Auth**: Auth.js, Better Auth, Clerk, or none
15
- - **Language**: TypeScript or JavaScript
11
+ Interactive wizard helps you choose:
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
16
 
17
- ## Development
17
+ ## Quick Start
18
18
 
19
19
  ```bash
20
- pnpm install
21
- pnpm build
22
- npx . test-app
20
+ # Create project
21
+ npx create-stackkit-app my-app
22
+
23
+ # Navigate and run
24
+ cd my-app
25
+ npm run dev
23
26
  ```
24
27
 
25
- See [main README](../../README.md) for full documentation.
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
36
+
37
+ ## Documentation
38
+
39
+ Full documentation available at [stackkit.dev](https://stackkit.dev) or [GitHub](https://github.com/tariqul420/stackkit)
@@ -84,8 +84,6 @@ async function getProjectConfig(projectName) {
84
84
  // Next.js apps
85
85
  if (answers.framework === 'nextjs') {
86
86
  return [
87
- { name: 'Auth.js v5', value: 'authjs-nextjs' },
88
- { name: 'NextAuth.js', value: 'nextauth' },
89
87
  { name: 'Better Auth', value: 'better-auth-nextjs' },
90
88
  { name: 'Clerk', value: 'clerk-nextjs' },
91
89
  { name: 'None', value: 'none' },
@@ -94,7 +92,6 @@ async function getProjectConfig(projectName) {
94
92
  // Express apps
95
93
  if (answers.framework === 'express') {
96
94
  return [
97
- { name: 'Auth.js', value: 'authjs-express' },
98
95
  { name: 'Better Auth', value: 'better-auth-express' },
99
96
  { name: 'Clerk', value: 'clerk-express' },
100
97
  { name: 'None', value: 'none' },
@@ -170,11 +167,11 @@ async function composeTemplate(config, targetDir) {
170
167
  await copyBaseFramework(templatesDir, targetDir, config.framework);
171
168
  // 2. Merge database configuration
172
169
  if (config.database !== 'none') {
173
- await mergeDatabaseConfig(templatesDir, targetDir, config.database);
170
+ await mergeDatabaseConfig(templatesDir, targetDir, config.database, config.framework);
174
171
  }
175
172
  // 3. Merge auth configuration
176
173
  if (config.auth !== 'none') {
177
- await mergeAuthConfig(templatesDir, targetDir, config.framework, config.auth);
174
+ await mergeAuthConfig(templatesDir, targetDir, config.framework, config.auth, config.database);
178
175
  }
179
176
  // 4. Update package.json with project name
180
177
  const packageJsonPath = path_1.default.join(targetDir, 'package.json');
@@ -189,7 +186,7 @@ async function composeTemplate(config, targetDir) {
189
186
  }
190
187
  }
191
188
  async function copyBaseFramework(templatesDir, targetDir, framework) {
192
- const baseDir = path_1.default.join(templatesDir, 'bases', `${framework}-base`);
189
+ const baseDir = path_1.default.join(templatesDir, framework);
193
190
  if (!(await fs_extra_1.default.pathExists(baseDir))) {
194
191
  throw new Error(`Base template not found for framework: ${framework}\n` + `Expected at: ${baseDir}`);
195
192
  }
@@ -200,7 +197,7 @@ async function copyBaseFramework(templatesDir, targetDir, framework) {
200
197
  },
201
198
  });
202
199
  }
203
- async function mergeDatabaseConfig(templatesDir, targetDir, database) {
200
+ async function mergeDatabaseConfig(templatesDir, targetDir, database, framework) {
204
201
  // Use modules directory (sibling to templates)
205
202
  const modulesDir = path_1.default.join(templatesDir, '..', 'modules');
206
203
  const dbModulePath = path_1.default.join(modulesDir, 'database', database);
@@ -242,8 +239,16 @@ async function mergeDatabaseConfig(templatesDir, targetDir, database) {
242
239
  envVars[envVar.key] = envVar.value;
243
240
  }
244
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
+ }
245
250
  }
246
- async function mergeAuthConfig(templatesDir, targetDir, framework, auth) {
251
+ async function mergeAuthConfig(templatesDir, targetDir, framework, auth, database = 'none') {
247
252
  // Use modules directory (sibling to templates)
248
253
  const modulesDir = path_1.default.join(templatesDir, '..', 'modules');
249
254
  // Auth modules are now named with framework suffix
@@ -303,6 +308,47 @@ async function mergeAuthConfig(templatesDir, targetDir, framework, auth) {
303
308
  }
304
309
  }
305
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
+ }
306
352
  // Merge package.json with module dependencies
307
353
  await mergePackageJson(targetDir, {
308
354
  dependencies: moduleData.dependencies,
@@ -429,6 +475,40 @@ async function initGit(cwd) {
429
475
  throw new Error('Git initialization failed');
430
476
  }
431
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
+ }
432
512
  function showNextSteps(config) {
433
513
  console.log(chalk_1.default.green.bold(`\n✓ Created ${config.projectName}\n`));
434
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
+ }