create-ej-app 4.0.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +1 -1
  2. package/cli.js +4 -0
  3. package/cli.ts +5 -0
  4. package/package.json +4 -4
  5. package/template/new/.env.example +13 -0
  6. package/template/new/components.json +22 -0
  7. package/template/new/drizzle.config.ts +10 -0
  8. package/template/new/eslint.config.mjs +18 -0
  9. package/template/new/next.config.ts +14 -0
  10. package/template/new/package.json +81 -0
  11. package/template/new/postcss.config.mjs +5 -0
  12. package/template/new/prettier.config.mjs +11 -0
  13. package/template/new/public/placeholder.svg +1 -0
  14. package/template/new/src/app/(auth)/login/email-login-form.tsx +97 -0
  15. package/template/new/src/app/(auth)/login/page.tsx +72 -0
  16. package/template/new/src/app/(auth)/login/social-login-buttons.tsx +69 -0
  17. package/template/new/src/app/api/auth/[...all]/route.ts +4 -0
  18. package/template/new/src/app/favicon.ico +0 -0
  19. package/template/new/src/app/globals.css +128 -0
  20. package/template/new/src/app/layout.tsx +50 -0
  21. package/template/new/src/app/page.tsx +3 -0
  22. package/template/new/src/components/loader.tsx +25 -0
  23. package/template/new/src/components/react-query-provider.tsx +12 -0
  24. package/template/new/src/components/screen-size.tsx +40 -0
  25. package/template/new/src/components/theme-toggle.tsx +22 -0
  26. package/template/new/src/components/ui/button.tsx +60 -0
  27. package/template/new/src/components/ui/card.tsx +92 -0
  28. package/template/new/src/components/ui/form.tsx +167 -0
  29. package/template/new/src/components/ui/input.tsx +21 -0
  30. package/template/new/src/components/ui/label.tsx +24 -0
  31. package/template/new/src/components/ui/separator.tsx +28 -0
  32. package/template/new/src/components/ui/sonner.tsx +40 -0
  33. package/template/new/src/db/index.ts +7 -0
  34. package/template/new/src/db/schema.ts +74 -0
  35. package/template/new/src/env.ts +42 -0
  36. package/template/new/src/lib/auth-client.ts +18 -0
  37. package/template/new/src/lib/auth.ts +67 -0
  38. package/template/new/src/lib/cn.ts +4 -0
  39. package/template/new/src/lib/delay.ts +2 -0
  40. package/template/new/src/lib/safe-action.ts +15 -0
  41. package/template/new/src/lib/siteConfig.ts +4 -0
  42. package/template/new/src/lib/toast-message.ts +15 -0
  43. package/template/new/tsconfig.json +49 -0
@@ -0,0 +1,42 @@
1
+ import { createEnv } from '@t3-oss/env-nextjs'
2
+ import { z } from 'zod'
3
+
4
+ export const env = createEnv({
5
+ server: {
6
+ NODE_ENV: z.enum(['development', 'production']),
7
+ ANALYZE: z.string().optional(),
8
+ DATABASE_URL: z.url(),
9
+ BETTER_AUTH_URL: z.url(),
10
+ BETTER_AUTH_SECRET: z.string(),
11
+ BETTER_AUTH_GITHUB_ID: z.string(),
12
+ BETTER_AUTH_GITHUB_SECRET: z.string(),
13
+ BETTER_AUTH_GOOGLE_ID: z.string(),
14
+ BETTER_AUTH_GOOGLE_SECRET: z.string(),
15
+ EMAIL_SERVER_USER: z.string(),
16
+ EMAIL_SERVER_PASSWORD: z.string(),
17
+ EMAIL_SERVER_HOST: z.string(),
18
+ EMAIL_SERVER_PORT: z.string(),
19
+ EMAIL_FROM: z.email()
20
+ },
21
+
22
+ client: {},
23
+
24
+ runtimeEnv: {
25
+ NODE_ENV: process.env.NODE_ENV,
26
+ ANALYZE: process.env.ANALYZE,
27
+ DATABASE_URL: process.env.DATABASE_URL,
28
+ BETTER_AUTH_URL: process.env.BETTER_AUTH_URL,
29
+ BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET,
30
+ BETTER_AUTH_GITHUB_ID: process.env.BETTER_AUTH_GITHUB_ID,
31
+ BETTER_AUTH_GITHUB_SECRET: process.env.BETTER_AUTH_GITHUB_SECRET,
32
+ BETTER_AUTH_GOOGLE_ID: process.env.BETTER_AUTH_GOOGLE_ID,
33
+ BETTER_AUTH_GOOGLE_SECRET: process.env.BETTER_AUTH_GOOGLE_SECRET,
34
+ EMAIL_SERVER_USER: process.env.EMAIL_SERVER_USER,
35
+ EMAIL_SERVER_PASSWORD: process.env.EMAIL_SERVER_PASSWORD,
36
+ EMAIL_SERVER_HOST: process.env.EMAIL_SERVER_HOST,
37
+ EMAIL_SERVER_PORT: process.env.EMAIL_SERVER_PORT,
38
+ EMAIL_FROM: process.env.EMAIL_FROM
39
+ },
40
+
41
+ emptyStringAsUndefined: true
42
+ })
@@ -0,0 +1,18 @@
1
+ 'use client'
2
+
3
+ import {
4
+ inferAdditionalFields,
5
+ lastLoginMethodClient,
6
+ magicLinkClient
7
+ } from 'better-auth/client/plugins'
8
+ import { createAuthClient } from 'better-auth/react'
9
+ import type { auth } from './auth'
10
+
11
+ export const { signIn, signOut, useSession, getLastUsedLoginMethod } =
12
+ createAuthClient({
13
+ plugins: [
14
+ inferAdditionalFields<typeof auth>(),
15
+ magicLinkClient(),
16
+ lastLoginMethodClient()
17
+ ]
18
+ })
@@ -0,0 +1,67 @@
1
+ import { createId } from '@paralleldrive/cuid2'
2
+ import { betterAuth } from 'better-auth'
3
+ import { drizzleAdapter } from 'better-auth/adapters/drizzle'
4
+ import { lastLoginMethod, magicLink } from 'better-auth/plugins'
5
+ import { headers } from 'next/headers'
6
+ import { cache } from 'react'
7
+ import { db } from '~/db'
8
+ import {
9
+ accountsTable,
10
+ sessionsTable,
11
+ usersTable,
12
+ verificationsTable
13
+ } from '~/db/schema'
14
+ import { env } from '~/env'
15
+
16
+ export const auth = betterAuth({
17
+ database: drizzleAdapter(db, {
18
+ provider: 'pg',
19
+ schema: {
20
+ user: usersTable,
21
+ session: sessionsTable,
22
+ account: accountsTable,
23
+ verification: verificationsTable
24
+ }
25
+ }),
26
+ account: {
27
+ accountLinking: {
28
+ enabled: true
29
+ }
30
+ },
31
+ advanced: {
32
+ database: {
33
+ generateId: ({ model }) => `${model}_${createId()}`
34
+ }
35
+ },
36
+ socialProviders: {
37
+ github: {
38
+ prompt: 'select_account',
39
+ clientId: env.BETTER_AUTH_GITHUB_ID,
40
+ clientSecret: env.BETTER_AUTH_GITHUB_SECRET
41
+ },
42
+ google: {
43
+ prompt: 'select_account',
44
+ clientId: env.BETTER_AUTH_GOOGLE_ID,
45
+ clientSecret: env.BETTER_AUTH_GOOGLE_SECRET
46
+ }
47
+ },
48
+ plugins: [
49
+ magicLink({
50
+ sendMagicLink: async ({ email, token, url }) => {
51
+ console.warn('TODO: send email', {
52
+ email,
53
+ token,
54
+ url
55
+ })
56
+ }
57
+ }),
58
+ lastLoginMethod()
59
+ ]
60
+ })
61
+
62
+ export const getAuthSession = cache(
63
+ async () =>
64
+ await auth.api.getSession({
65
+ headers: await headers()
66
+ })
67
+ )
@@ -0,0 +1,4 @@
1
+ import { clsx, type ClassValue } from 'clsx'
2
+ import { twMerge } from 'tailwind-merge'
3
+
4
+ export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs))
@@ -0,0 +1,2 @@
1
+ export const delay = (ms: number) =>
2
+ new Promise(resolve => setTimeout(resolve, ms))
@@ -0,0 +1,15 @@
1
+ import { createSafeActionClient } from 'next-safe-action'
2
+ import { getAuthSession } from './auth'
3
+
4
+ export const actionClient = createSafeActionClient().use(
5
+ async ({ next, ctx }) => {
6
+ const session = await getAuthSession()
7
+
8
+ return next({
9
+ ctx: {
10
+ ...ctx,
11
+ user: session?.user
12
+ }
13
+ })
14
+ }
15
+ )
@@ -0,0 +1,4 @@
1
+ export const siteConfig = {
2
+ name: 'Project Name',
3
+ description: 'Project Description'
4
+ }
@@ -0,0 +1,15 @@
1
+ 'use client'
2
+
3
+ import { toast } from 'sonner'
4
+
5
+ export const toastSuccessMessage = (message: string) =>
6
+ toast.success(message, {
7
+ richColors: true,
8
+ position: 'top-center'
9
+ })
10
+
11
+ export const toastErrorMessage = () =>
12
+ toast.error('Something went wrong. Please try again later.', {
13
+ richColors: true,
14
+ position: 'top-center'
15
+ })
@@ -0,0 +1,49 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
5
+ "allowJs": true,
6
+ "checkJs": true,
7
+ "skipLibCheck": true,
8
+ "strict": true,
9
+ "noImplicitAny": true,
10
+ "strictNullChecks": true,
11
+ "strictFunctionTypes": true,
12
+ "noImplicitThis": true,
13
+ "noUncheckedIndexedAccess": true,
14
+ "noUnusedLocals": true,
15
+ "noUnusedParameters": true,
16
+ "noImplicitReturns": true,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ "noEmit": true,
20
+ "esModuleInterop": true,
21
+ "module": "ESNext",
22
+ "moduleResolution": "bundler",
23
+ "resolveJsonModule": true,
24
+ "isolatedModules": true,
25
+ "jsx": "react-jsx",
26
+ "incremental": true,
27
+ "plugins": [
28
+ {
29
+ "name": "next"
30
+ },
31
+ {
32
+ "name": "workflow"
33
+ }
34
+ ],
35
+ "paths": {
36
+ "~/*": ["./src/*"]
37
+ }
38
+ },
39
+ "include": [
40
+ "next-env.d.ts",
41
+ "**/*.ts",
42
+ "**/*.tsx",
43
+ ".next/types/**/*.ts",
44
+ ".next/dev/types/**/*.ts",
45
+ "**/*.cjs",
46
+ "**/*.mjs"
47
+ ],
48
+ "exclude": ["node_modules"]
49
+ }