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
@@ -0,0 +1,45 @@
1
+ import { SEO } from '../components/SEO';
2
+
3
+ export default function Home() {
4
+ return (
5
+ <>
6
+ <SEO title="Home" />
7
+ <div className="flex min-h-screen items-center justify-center bg-black">
8
+ <main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-black sm:items-start">
9
+ <div className="text-2xl font-bold text-white">Stackkit</div>
10
+
11
+ <div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
12
+ <h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-zinc-50">
13
+ To get started, edit the Home.tsx file.
14
+ </h1>
15
+ <p className="max-w-md text-lg leading-8 text-zinc-400">
16
+ This template includes React Router, TanStack Query, Axios, and Tailwind CSS. Check
17
+ out the{' '}
18
+ <a href="/about" className="font-medium text-zinc-50 hover:underline">
19
+ About
20
+ </a>{' '}
21
+ page to learn more about the included features.
22
+ </p>
23
+ </div>
24
+
25
+ <div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
26
+ <a
27
+ className="flex h-12 w-full items-center justify-center rounded-full bg-white text-black px-5 transition-colors hover:bg-zinc-200 md:w-39.5"
28
+ href="https://react.dev"
29
+ target="_blank"
30
+ rel="noopener noreferrer"
31
+ >
32
+ Get Started
33
+ </a>
34
+ <a
35
+ className="flex h-12 w-full items-center justify-center rounded-full px-5 transition-colors hover:border-transparent bg-zinc-900 md:w-39.5 dark:text-white text-black"
36
+ href="/about"
37
+ >
38
+ Documentation
39
+ </a>
40
+ </div>
41
+ </main>
42
+ </div>
43
+ </>
44
+ );
45
+ }
@@ -0,0 +1,24 @@
1
+ import { Link } from 'react-router';
2
+ import { SEO } from '../components/SEO';
3
+
4
+ export default function NotFound() {
5
+ return (
6
+ <>
7
+ <SEO title="404 - Page Not Found" description="The page you're looking for doesn't exist" />
8
+
9
+ <div className="flex min-h-screen items-center justify-center bg-black">
10
+ <div className="text-center px-6">
11
+ <h1 className="text-8xl font-bold text-white mb-4">404</h1>
12
+ <h2 className="text-3xl font-semibold text-zinc-50 mb-4">Page Not Found</h2>
13
+ <p className="text-lg text-zinc-400 mb-8">The page you're looking for doesn't exist.</p>
14
+ <Link
15
+ to="/"
16
+ className="inline-flex h-12 items-center justify-center rounded-full bg-white text-black px-8 font-medium transition-colors hover:bg-zinc-200"
17
+ >
18
+ Go Home
19
+ </Link>
20
+ </div>
21
+ </div>
22
+ </>
23
+ );
24
+ }
@@ -0,0 +1,40 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { useLoaderData, useParams } from 'react-router';
3
+ import { userService } from '../api/services/user.service';
4
+
5
+ type User = { id?: string; name?: string; email?: string; avatar?: string; [key: string]: any };
6
+
7
+ export default function UserProfile() {
8
+ const loaderUser = useLoaderData() as User | undefined;
9
+ const { userId } = useParams();
10
+
11
+ const { data: user = loaderUser ?? {} } = useQuery({
12
+ queryKey: ['user', userId],
13
+ queryFn: async () => {
14
+ if (!userId) throw new Error('Missing user id');
15
+ return await userService.getUser(userId);
16
+ },
17
+ initialData: loaderUser,
18
+ staleTime: 1000 * 60,
19
+ });
20
+
21
+ return (
22
+ <div className="min-h-screen bg-black text-white flex items-center justify-center">
23
+ <div className="max-w-xl p-8 bg-zinc-900 rounded-md shadow">
24
+ <div className="flex items-center gap-4">
25
+ {user.avatar ? (
26
+ <img src={user.avatar} alt={user.name} className="w-16 h-16 rounded-full" />
27
+ ) : (
28
+ <div className="w-16 h-16 rounded-full bg-zinc-700 flex items-center justify-center text-xl">
29
+ {user.name?.[0] ?? 'U'}
30
+ </div>
31
+ )}
32
+ <div>
33
+ <h2 className="text-2xl font-semibold">{user.name}</h2>
34
+ <p className="text-sm text-zinc-400">{user.email}</p>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ );
40
+ }
@@ -0,0 +1,33 @@
1
+ import { createBrowserRouter } from 'react-router';
2
+ import { userService } from './api/services/user.service';
3
+ import { ErrorBoundary } from './components/ErrorBoundary';
4
+ import Layout from './components/Layout';
5
+ import About from './pages/About';
6
+ import Home from './pages/Home';
7
+ import NotFound from './pages/NotFound';
8
+ import UserProfile from './pages/UserProfile';
9
+
10
+ export const router = createBrowserRouter([
11
+ {
12
+ path: '/',
13
+ Component: Layout,
14
+ errorElement: <ErrorBoundary />,
15
+ children: [
16
+ { index: true, Component: Home },
17
+ { path: 'about', Component: About },
18
+ {
19
+ path: 'users/:userId',
20
+ loader: async ({ params }) => {
21
+ const id = params.userId;
22
+ if (!id) throw new Response('Missing user id', { status: 400 });
23
+ const user = await userService.getUser(id);
24
+ return user;
25
+ },
26
+ Component: UserProfile,
27
+ },
28
+ { path: '*', Component: NotFound },
29
+ ],
30
+ },
31
+ ]);
32
+
33
+ export default router;
@@ -0,0 +1,20 @@
1
+ export interface ApiResponse<T = unknown> {
2
+ data: T;
3
+ message?: string;
4
+ status: number;
5
+ }
6
+
7
+ export interface PaginatedResponse<T> {
8
+ data: T[];
9
+ total: number;
10
+ page: number;
11
+ pageSize: number;
12
+ totalPages: number;
13
+ }
14
+
15
+ export interface ApiError {
16
+ message: string;
17
+ code?: string;
18
+ status?: number;
19
+ errors?: Record<string, string[]>;
20
+ }
@@ -0,0 +1,51 @@
1
+ export function cn(...classes: (string | boolean | undefined | null)[]): string {
2
+ return classes.filter(Boolean).join(' ');
3
+ }
4
+
5
+ export function formatDate(date: Date | string): string {
6
+ const d = typeof date === 'string' ? new Date(date) : date;
7
+ return d.toLocaleDateString('en-US', {
8
+ year: 'numeric',
9
+ month: 'long',
10
+ day: 'numeric',
11
+ });
12
+ }
13
+
14
+ export function truncate(str: string, maxLength: number): string {
15
+ if (str.length <= maxLength) return str;
16
+ return str.slice(0, maxLength) + '...';
17
+ }
18
+
19
+ export function delay(ms: number): Promise<void> {
20
+ return new Promise((resolve) => setTimeout(resolve, ms));
21
+ }
22
+
23
+ export function debounce<T extends (...args: never[]) => unknown>(
24
+ func: T,
25
+ wait: number
26
+ ): (...args: Parameters<T>) => void {
27
+ let timeout: ReturnType<typeof setTimeout> | null = null;
28
+
29
+ return function executedFunction(...args: Parameters<T>) {
30
+ const later = () => {
31
+ timeout = null;
32
+ func(...args);
33
+ };
34
+
35
+ if (timeout) clearTimeout(timeout);
36
+ timeout = setTimeout(later, wait);
37
+ };
38
+ }
39
+
40
+ export function capitalize(str: string): string {
41
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
42
+ }
43
+
44
+ export function slugify(str: string): string {
45
+ return str
46
+ .toLowerCase()
47
+ .trim()
48
+ .replace(/[^\w\s-]/g, '')
49
+ .replace(/[\s_-]+/g, '-')
50
+ .replace(/^-+|-+$/g, '');
51
+ }
@@ -0,0 +1,35 @@
1
+ export const storage = {
2
+ get: <T>(key: string, defaultValue?: T): T | null => {
3
+ try {
4
+ const item = localStorage.getItem(key);
5
+ return item ? JSON.parse(item) : (defaultValue ?? null);
6
+ } catch (error) {
7
+ console.error('Error reading from localStorage:', error);
8
+ return defaultValue ?? null;
9
+ }
10
+ },
11
+
12
+ set: <T>(key: string, value: T): void => {
13
+ try {
14
+ localStorage.setItem(key, JSON.stringify(value));
15
+ } catch (error) {
16
+ console.error('Error writing to localStorage:', error);
17
+ }
18
+ },
19
+
20
+ remove: (key: string): void => {
21
+ try {
22
+ localStorage.removeItem(key);
23
+ } catch (error) {
24
+ console.error('Error removing from localStorage:', error);
25
+ }
26
+ },
27
+
28
+ clear: (): void => {
29
+ try {
30
+ localStorage.clear();
31
+ } catch (error) {
32
+ console.error('Error clearing localStorage:', error);
33
+ }
34
+ },
35
+ };
@@ -0,0 +1,11 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_API_URL: string;
5
+ readonly VITE_APP_NAME?: string;
6
+ readonly VITE_APP_VERSION?: string;
7
+ }
8
+
9
+ interface ImportMeta {
10
+ readonly env: ImportMetaEnv;
11
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "react-vite-base",
3
+ "displayName": "React (Vite)",
4
+ "framework": "react-vite",
5
+ "description": "Production-ready React 19 + Vite with TypeScript, Router, TanStack Query, and more",
6
+ "files": [
7
+ "src/",
8
+ "public/",
9
+ ".env.example",
10
+ ".gitignore",
11
+ "eslint.config.js",
12
+ "index.html",
13
+ "package.json",
14
+ "README.md",
15
+ "tsconfig.json",
16
+ "tsconfig.app.json",
17
+ "tsconfig.node.json",
18
+ "vite.config.ts"
19
+ ]
20
+ }
@@ -1,19 +1,26 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES2020",
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "ES2022",
4
5
  "useDefineForClassFields": true,
5
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
6
7
  "module": "ESNext",
8
+ "types": ["vite/client"],
7
9
  "skipLibCheck": true,
10
+
11
+ /* Bundler mode */
8
12
  "moduleResolution": "bundler",
9
13
  "allowImportingTsExtensions": true,
10
- "isolatedModules": true,
14
+ "verbatimModuleSyntax": true,
11
15
  "moduleDetection": "force",
12
16
  "noEmit": true,
13
17
  "jsx": "react-jsx",
18
+
19
+ /* Linting */
14
20
  "strict": true,
15
21
  "noUnusedLocals": true,
16
22
  "noUnusedParameters": true,
23
+ "erasableSyntaxOnly": true,
17
24
  "noFallthroughCasesInSwitch": true,
18
25
  "noUncheckedSideEffectImports": true
19
26
  },
@@ -0,0 +1,7 @@
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4
+ "target": "ES2023",
5
+ "lib": ["ES2023"],
6
+ "module": "ESNext",
7
+ "types": ["node"],
8
+ "skipLibCheck": true,
9
+
10
+ /* Bundler mode */
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "verbatimModuleSyntax": true,
14
+ "moduleDetection": "force",
15
+ "noEmit": true,
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "erasableSyntaxOnly": true,
22
+ "noFallthroughCasesInSwitch": true,
23
+ "noUncheckedSideEffectImports": true
24
+ },
25
+ "include": ["vite.config.ts"]
26
+ }
@@ -0,0 +1,13 @@
1
+ import tailwindcss from '@tailwindcss/vite';
2
+ import react from '@vitejs/plugin-react';
3
+ import path from 'path';
4
+ import { defineConfig } from 'vite';
5
+
6
+ export default defineConfig({
7
+ plugins: [react(), tailwindcss()],
8
+ resolve: {
9
+ alias: {
10
+ '@': path.resolve(__dirname, './src'),
11
+ },
12
+ },
13
+ });
@@ -1,40 +0,0 @@
1
- import Credentials from '@auth/core/providers/credentials';
2
-
3
- export const authConfig = {
4
- secret: process.env.AUTH_SECRET,
5
- trustHost: true,
6
- providers: [
7
- // GitHub OAuth Provider
8
- // Uncomment and add GITHUB_ID and GITHUB_SECRET to .env
9
- // GitHub({
10
- // clientId: process.env.GITHUB_ID!,
11
- // clientSecret: process.env.GITHUB_SECRET!,
12
- // }),
13
-
14
- // Google OAuth Provider
15
- // Uncomment and add GOOGLE_ID and GOOGLE_SECRET to .env
16
- // Google({
17
- // clientId: process.env.GOOGLE_ID!,
18
- // clientSecret: process.env.GOOGLE_SECRET!,
19
- // }),
20
-
21
- // Credentials Provider (email/password)
22
- Credentials({
23
- credentials: {
24
- email: { label: 'Email', type: 'email' },
25
- password: { label: 'Password', type: 'password' },
26
- },
27
- authorize: async (credentials) => {
28
- // Add your own authentication logic here
29
- if (credentials?.email === 'demo@example.com' && credentials?.password === 'demo') {
30
- return {
31
- id: '1',
32
- name: 'Demo User',
33
- email: 'demo@example.com',
34
- };
35
- }
36
- return null;
37
- },
38
- }),
39
- ],
40
- };
@@ -1,12 +0,0 @@
1
- import { Auth } from '@auth/core';
2
- import { Router } from 'express';
3
- import { authConfig } from '../lib/auth';
4
-
5
- const router = Router();
6
-
7
- router.all('/auth/*', async (req, res) => {
8
- const response = await Auth(req, authConfig);
9
- return res.status(response.status).json(response.body);
10
- });
11
-
12
- export default router;
@@ -1,39 +0,0 @@
1
- {
2
- "name": "auth",
3
- "displayName": "Auth.js (Express)",
4
- "description": "Authentication with Auth.js for Express",
5
- "category": "auth",
6
- "supportedFrameworks": ["express"],
7
- "dependencies": {
8
- "@auth/express": "^0.7.6",
9
- "@auth/core": "^0.37.4"
10
- },
11
- "envVars": [
12
- {
13
- "key": "AUTH_SECRET",
14
- "value": "",
15
- "description": "Secret for encrypting tokens. Generate with: openssl rand -base64 32",
16
- "required": true
17
- },
18
- {
19
- "key": "AUTH_TRUST_HOST",
20
- "value": "true",
21
- "description": "Trust the host header (required for Express)",
22
- "required": true
23
- }
24
- ],
25
- "patches": [
26
- {
27
- "type": "create-file",
28
- "description": "Create Auth.js configuration",
29
- "source": "lib/auth.ts",
30
- "destination": "src/lib/auth.ts"
31
- },
32
- {
33
- "type": "create-file",
34
- "description": "Create auth routes",
35
- "source": "routes/auth.ts",
36
- "destination": "src/routes/auth.ts"
37
- }
38
- ]
39
- }
@@ -1,3 +0,0 @@
1
- import { handlers } from '@/lib/auth';
2
-
3
- export const { GET, POST } = handlers;
@@ -1,43 +0,0 @@
1
- import NextAuth from 'next-auth';
2
- import Credentials from 'next-auth/providers/credentials';
3
-
4
- export const { handlers, signIn, signOut, auth } = NextAuth({
5
- providers: [
6
- // GitHub OAuth Provider
7
- // Uncomment and add GITHUB_ID and GITHUB_SECRET to .env
8
- // GitHub({
9
- // clientId: process.env.GITHUB_ID!,
10
- // clientSecret: process.env.GITHUB_SECRET!,
11
- // }),
12
-
13
- // Google OAuth Provider
14
- // Uncomment and add GOOGLE_ID and GOOGLE_SECRET to .env
15
- // Google({
16
- // clientId: process.env.GOOGLE_ID!,
17
- // clientSecret: process.env.GOOGLE_SECRET!,
18
- // }),
19
-
20
- // Credentials Provider (email/password)
21
- Credentials({
22
- credentials: {
23
- email: { label: 'Email', type: 'email' },
24
- password: { label: 'Password', type: 'password' },
25
- },
26
- authorize: async (credentials) => {
27
- // Add your own authentication logic here
28
- // This is just a demo - DO NOT use in production
29
- if (credentials?.email === 'demo@example.com' && credentials?.password === 'demo') {
30
- return {
31
- id: '1',
32
- name: 'Demo User',
33
- email: 'demo@example.com',
34
- };
35
- }
36
- return null;
37
- },
38
- }),
39
- ],
40
- pages: {
41
- signIn: '/auth/signin',
42
- },
43
- });
@@ -1,38 +0,0 @@
1
- {
2
- "name": "auth",
3
- "displayName": "Auth.js v5 (Next.js)",
4
- "description": "Modern authentication with Auth.js v5 (NextAuth successor)",
5
- "category": "auth",
6
- "supportedFrameworks": ["nextjs"],
7
- "dependencies": {
8
- "next-auth": "^5.0.0-beta.25"
9
- },
10
- "envVars": [
11
- {
12
- "key": "AUTH_SECRET",
13
- "value": "",
14
- "description": "Secret for encrypting tokens. Generate with: openssl rand -base64 32",
15
- "required": true
16
- },
17
- {
18
- "key": "AUTH_URL",
19
- "value": "http://localhost:3000",
20
- "description": "Canonical URL of your site (change in production)",
21
- "required": false
22
- }
23
- ],
24
- "patches": [
25
- {
26
- "type": "create-file",
27
- "description": "Create Auth.js configuration",
28
- "source": "lib/auth.ts",
29
- "destination": "{{lib}}/auth.ts"
30
- },
31
- {
32
- "type": "create-file",
33
- "description": "Create Auth.js API route",
34
- "source": "api/auth/[...nextauth]/route.ts",
35
- "destination": "{{router}}/api/auth/[...nextauth]/route.ts"
36
- }
37
- ]
38
- }
@@ -1,6 +0,0 @@
1
- import { authOptions } from '@/lib/auth';
2
- import NextAuth from 'next-auth';
3
-
4
- const handler = NextAuth(authOptions);
5
-
6
- export { handler as GET, handler as POST };
@@ -1,82 +0,0 @@
1
- import { AuthOptions } from 'next-auth';
2
- import CredentialsProvider from 'next-auth/providers/credentials';
3
-
4
- /**
5
- * NextAuth.js Configuration
6
- *
7
- * Configure authentication providers and options here.
8
- * See: https://next-auth.js.org/configuration/options
9
- */
10
- export const authOptions: AuthOptions = {
11
- providers: [
12
- // GitHub OAuth Provider
13
- // Uncomment and add GITHUB_ID and GITHUB_SECRET to .env
14
- // GithubProvider({
15
- // clientId: process.env.GITHUB_ID!,
16
- // clientSecret: process.env.GITHUB_SECRET!,
17
- // }),
18
-
19
- // Google OAuth Provider
20
- // Uncomment and add GOOGLE_ID and GOOGLE_SECRET to .env
21
- // GoogleProvider({
22
- // clientId: process.env.GOOGLE_ID!,
23
- // clientSecret: process.env.GOOGLE_SECRET!,
24
- // }),
25
-
26
- // Credentials Provider (email/password)
27
- // Replace with your own authentication logic
28
- CredentialsProvider({
29
- name: 'Credentials',
30
- credentials: {
31
- email: { label: 'Email', type: 'email', placeholder: 'user@example.com' },
32
- password: { label: 'Password', type: 'password' },
33
- },
34
- async authorize(credentials) {
35
- // Add your own authentication logic here
36
- // This is just a demo - DO NOT use in production
37
- if (credentials?.email === 'demo@example.com' && credentials?.password === 'demo') {
38
- return {
39
- id: '1',
40
- name: 'Demo User',
41
- email: 'demo@example.com',
42
- };
43
- }
44
- return null;
45
- },
46
- }),
47
- ],
48
-
49
- // Database adapter (optional)
50
- // Uncomment to persist sessions in database
51
- // adapter: PrismaAdapter(prisma),
52
-
53
- session: {
54
- strategy: 'jwt',
55
- },
56
-
57
- pages: {
58
- signIn: '/auth/signin',
59
- // signOut: '/auth/signout',
60
- // error: '/auth/error',
61
- // verifyRequest: '/auth/verify-request',
62
- // newUser: '/auth/new-user'
63
- },
64
-
65
- callbacks: {
66
- async jwt({ token, user }) {
67
- if (user) {
68
- token.id = user.id;
69
- }
70
- return token;
71
- },
72
- async session({ session, token }) {
73
- if (session.user) {
74
- session.user.id = token.id as string;
75
- }
76
- return session;
77
- },
78
- },
79
-
80
- // Enable debug messages in development
81
- debug: process.env.NODE_ENV === 'development',
82
- };
@@ -1,4 +0,0 @@
1
- import { authOptions } from '@/lib/auth';
2
- import NextAuth from 'next-auth';
3
-
4
- export default NextAuth(authOptions);