create-stackforge 0.0.1

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 (165) hide show
  1. package/README.md +125 -0
  2. package/bin/cli.js +2 -0
  3. package/dist/cli.js +3148 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/npm-registry-F7EVX3RR.js +18 -0
  6. package/dist/npm-registry-F7EVX3RR.js.map +1 -0
  7. package/package.json +74 -0
  8. package/templates/api/graphql/client-usage.jsx +14 -0
  9. package/templates/api/graphql/client-usage.tsx +14 -0
  10. package/templates/api/graphql/client.js +12 -0
  11. package/templates/api/graphql/client.ts +12 -0
  12. package/templates/api/graphql/route.js +32 -0
  13. package/templates/api/graphql/route.ts +23 -0
  14. package/templates/api/graphql/schema.graphql +13 -0
  15. package/templates/api/graphql/vite-server.js +27 -0
  16. package/templates/api/graphql/vite-server.ts +27 -0
  17. package/templates/api/rest/client-usage.jsx +14 -0
  18. package/templates/api/rest/client-usage.tsx +14 -0
  19. package/templates/api/rest/client.js +4 -0
  20. package/templates/api/rest/client.ts +4 -0
  21. package/templates/api/rest/route.js +3 -0
  22. package/templates/api/rest/route.ts +3 -0
  23. package/templates/api/rest/users-route.js +11 -0
  24. package/templates/api/rest/users-route.ts +11 -0
  25. package/templates/api/rest/vite-server.js +15 -0
  26. package/templates/api/rest/vite-server.ts +15 -0
  27. package/templates/api/trpc/client-usage.jsx +26 -0
  28. package/templates/api/trpc/client-usage.tsx +26 -0
  29. package/templates/api/trpc/client-vite.js +15 -0
  30. package/templates/api/trpc/client-vite.ts +16 -0
  31. package/templates/api/trpc/client.js +13 -0
  32. package/templates/api/trpc/client.ts +14 -0
  33. package/templates/api/trpc/root.ts +11 -0
  34. package/templates/api/trpc/route.js +12 -0
  35. package/templates/api/trpc/route.ts +12 -0
  36. package/templates/api/trpc/trpc.ts +6 -0
  37. package/templates/api/trpc/vite-server.js +9 -0
  38. package/templates/api/trpc/vite-server.ts +9 -0
  39. package/templates/auth/clerk-protected-page.jsx +11 -0
  40. package/templates/auth/clerk-protected-page.tsx +11 -0
  41. package/templates/auth/clerk-protected.jsx +11 -0
  42. package/templates/auth/clerk-protected.tsx +11 -0
  43. package/templates/auth/clerk-signin.jsx +11 -0
  44. package/templates/auth/clerk-signin.tsx +11 -0
  45. package/templates/auth/clerk.README.md +8 -0
  46. package/templates/auth/nextauth-options.js +3 -0
  47. package/templates/auth/nextauth-options.ts +5 -0
  48. package/templates/auth/nextauth-protected-page.jsx +12 -0
  49. package/templates/auth/nextauth-protected-page.tsx +12 -0
  50. package/templates/auth/nextauth-protected.jsx +12 -0
  51. package/templates/auth/nextauth-protected.tsx +12 -0
  52. package/templates/auth/nextauth-route.ts +6 -0
  53. package/templates/auth/nextauth-signin.jsx +15 -0
  54. package/templates/auth/nextauth-signin.tsx +15 -0
  55. package/templates/auth/nextauth.README.md +10 -0
  56. package/templates/auth/supabase-protected-page.jsx +13 -0
  57. package/templates/auth/supabase-protected-page.tsx +13 -0
  58. package/templates/auth/supabase-protected.jsx +13 -0
  59. package/templates/auth/supabase-protected.tsx +13 -0
  60. package/templates/auth/supabase-signin.jsx +25 -0
  61. package/templates/auth/supabase-signin.tsx +25 -0
  62. package/templates/auth/supabase-vite-signin.jsx +20 -0
  63. package/templates/auth/supabase-vite-signin.tsx +20 -0
  64. package/templates/auth/supabase.README.md +9 -0
  65. package/templates/database/drizzle/client.js +8 -0
  66. package/templates/database/drizzle/client.ts +8 -0
  67. package/templates/database/drizzle/drizzle.config.ts +6 -0
  68. package/templates/database/drizzle/example.js +6 -0
  69. package/templates/database/drizzle/example.ts +6 -0
  70. package/templates/database/drizzle/schema.ts +6 -0
  71. package/templates/database/mongoose/connection.js +13 -0
  72. package/templates/database/mongoose/connection.ts +13 -0
  73. package/templates/database/mongoose/model.js +7 -0
  74. package/templates/database/mongoose/model.ts +7 -0
  75. package/templates/database/prisma/client.js +3 -0
  76. package/templates/database/prisma/client.ts +3 -0
  77. package/templates/database/prisma/example.js +5 -0
  78. package/templates/database/prisma/example.ts +7 -0
  79. package/templates/database/prisma/schema.prisma +13 -0
  80. package/templates/database/providers/neon.README.md +9 -0
  81. package/templates/database/providers/supabase.README.md +9 -0
  82. package/templates/database/typeorm/data-source.js +15 -0
  83. package/templates/database/typeorm/data-source.ts +15 -0
  84. package/templates/database/typeorm/entity.js +10 -0
  85. package/templates/database/typeorm/entity.ts +10 -0
  86. package/templates/database/typeorm/migrations/README.md +5 -0
  87. package/templates/database/usage/drizzle-users.js +6 -0
  88. package/templates/database/usage/drizzle-users.ts +6 -0
  89. package/templates/database/usage/mongoose-users.js +5 -0
  90. package/templates/database/usage/mongoose-users.ts +5 -0
  91. package/templates/database/usage/prisma-users.js +5 -0
  92. package/templates/database/usage/prisma-users.ts +5 -0
  93. package/templates/database/usage/typeorm-users.js +9 -0
  94. package/templates/database/usage/typeorm-users.ts +9 -0
  95. package/templates/features/analytics/README.md +9 -0
  96. package/templates/features/analytics/posthog.js +7 -0
  97. package/templates/features/analytics/posthog.ts +9 -0
  98. package/templates/features/email/README.md +17 -0
  99. package/templates/features/email/resend.js +3 -0
  100. package/templates/features/email/resend.ts +3 -0
  101. package/templates/features/error-tracking/README.md +9 -0
  102. package/templates/features/error-tracking/sentry.js +7 -0
  103. package/templates/features/error-tracking/sentry.ts +7 -0
  104. package/templates/features/payments/README.md +17 -0
  105. package/templates/features/payments/stripe.js +5 -0
  106. package/templates/features/payments/stripe.ts +5 -0
  107. package/templates/features/storage/README.md +12 -0
  108. package/templates/features/storage/storage.js +5 -0
  109. package/templates/features/storage/storage.ts +5 -0
  110. package/templates/nextjs/app/actions.js +6 -0
  111. package/templates/nextjs/app/actions.ts +6 -0
  112. package/templates/nextjs/app/examples-page.jsx +16 -0
  113. package/templates/nextjs/app/examples-page.tsx +16 -0
  114. package/templates/nextjs/app/layout.jsx +7 -0
  115. package/templates/nextjs/app/layout.tsx +7 -0
  116. package/templates/nextjs/app/page.jsx +12 -0
  117. package/templates/nextjs/app/page.tsx +12 -0
  118. package/templates/nextjs/next.config.js +4 -0
  119. package/templates/nextjs/next.config.ts +7 -0
  120. package/templates/shared/.editorconfig +8 -0
  121. package/templates/ui/antd.README.md +7 -0
  122. package/templates/ui/antd.theme.js +5 -0
  123. package/templates/ui/antd.theme.ts +7 -0
  124. package/templates/ui/button.jsx +13 -0
  125. package/templates/ui/button.tsx +13 -0
  126. package/templates/ui/chakra.README.md +7 -0
  127. package/templates/ui/chakra.theme.js +8 -0
  128. package/templates/ui/chakra.theme.ts +8 -0
  129. package/templates/ui/components.json +14 -0
  130. package/templates/ui/demo-antd.jsx +5 -0
  131. package/templates/ui/demo-antd.tsx +5 -0
  132. package/templates/ui/demo-chakra.jsx +5 -0
  133. package/templates/ui/demo-chakra.tsx +5 -0
  134. package/templates/ui/demo-mantine.jsx +5 -0
  135. package/templates/ui/demo-mantine.tsx +5 -0
  136. package/templates/ui/demo-mui.jsx +5 -0
  137. package/templates/ui/demo-mui.tsx +5 -0
  138. package/templates/ui/demo-nextui.jsx +5 -0
  139. package/templates/ui/demo-nextui.tsx +5 -0
  140. package/templates/ui/demo-shadcn.jsx +5 -0
  141. package/templates/ui/demo-shadcn.tsx +5 -0
  142. package/templates/ui/demo-tailwind.jsx +3 -0
  143. package/templates/ui/demo-tailwind.tsx +3 -0
  144. package/templates/ui/mantine.README.md +7 -0
  145. package/templates/ui/mantine.theme.js +3 -0
  146. package/templates/ui/mantine.theme.ts +3 -0
  147. package/templates/ui/mui.README.md +7 -0
  148. package/templates/ui/mui.theme.js +7 -0
  149. package/templates/ui/mui.theme.ts +7 -0
  150. package/templates/ui/nextui.README.md +7 -0
  151. package/templates/ui/nextui.theme.js +1 -0
  152. package/templates/ui/nextui.theme.ts +1 -0
  153. package/templates/ui/postcss.config.js +1 -0
  154. package/templates/ui/shadcn.README.md +1 -0
  155. package/templates/ui/styles.css +3 -0
  156. package/templates/ui/tailwind.config.js +6 -0
  157. package/templates/ui/utils.js +3 -0
  158. package/templates/ui/utils.ts +3 -0
  159. package/templates/vite/App.jsx +12 -0
  160. package/templates/vite/App.tsx +12 -0
  161. package/templates/vite/index.html +12 -0
  162. package/templates/vite/main.jsx +12 -0
  163. package/templates/vite/main.tsx +12 -0
  164. package/templates/vite/vite-env.d.ts +1 -0
  165. package/templates/vite/vite.config.ts +12 -0
@@ -0,0 +1,8 @@
1
+ # Clerk
2
+
3
+ Files:
4
+ - `middleware.*` Clerk middleware
5
+ - `auth/protected.*` example server component
6
+
7
+ Next steps:
8
+ - Set `CLERK_SECRET_KEY` and `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` in `.env`
@@ -0,0 +1,3 @@
1
+ export const authOptions = {
2
+ providers: []
3
+ };
@@ -0,0 +1,5 @@
1
+ import type { NextAuthOptions } from 'next-auth';
2
+
3
+ export const authOptions: NextAuthOptions = {
4
+ providers: []
5
+ };
@@ -0,0 +1,12 @@
1
+ import { getServerSession } from 'next-auth';
2
+ import { authOptions } from '../../../auth/auth-options';
3
+
4
+ export default async function ProtectedPage() {
5
+ const session = await getServerSession(authOptions);
6
+ return (
7
+ <div>
8
+ <h1>Protected</h1>
9
+ <pre>{JSON.stringify(session, null, 2)}</pre>
10
+ </div>
11
+ );
12
+ }
@@ -0,0 +1,12 @@
1
+ import { getServerSession } from 'next-auth';
2
+ import { authOptions } from '../../../auth/auth-options';
3
+
4
+ export default async function ProtectedPage() {
5
+ const session = await getServerSession(authOptions);
6
+ return (
7
+ <div>
8
+ <h1>Protected</h1>
9
+ <pre>{JSON.stringify(session, null, 2)}</pre>
10
+ </div>
11
+ );
12
+ }
@@ -0,0 +1,12 @@
1
+ import { getServerSession } from 'next-auth';
2
+ import { authOptions } from './auth-options';
3
+
4
+ export default async function ProtectedPage() {
5
+ const session = await getServerSession(authOptions);
6
+ return (
7
+ <div>
8
+ <h1>Protected</h1>
9
+ <pre>{JSON.stringify(session, null, 2)}</pre>
10
+ </div>
11
+ );
12
+ }
@@ -0,0 +1,12 @@
1
+ import { getServerSession } from 'next-auth';
2
+ import { authOptions } from './auth-options';
3
+
4
+ export default async function ProtectedPage() {
5
+ const session = await getServerSession(authOptions);
6
+ return (
7
+ <div>
8
+ <h1>Protected</h1>
9
+ <pre>{JSON.stringify(session, null, 2)}</pre>
10
+ </div>
11
+ );
12
+ }
@@ -0,0 +1,6 @@
1
+ import NextAuth from 'next-auth';
2
+ import { authOptions } from '../../../../auth/auth-options';
3
+
4
+ const handler = NextAuth(authOptions);
5
+
6
+ export { handler as GET, handler as POST };
@@ -0,0 +1,15 @@
1
+ export default function SignInPage() {
2
+ return (
3
+ <main>
4
+ <h1>Sign in</h1>
5
+ <p>
6
+ Use the default NextAuth sign-in:
7
+ <a href="/api/auth/signin"> /api/auth/signin</a>
8
+ </p>
9
+ <p>
10
+ Sign out:
11
+ <a href="/api/auth/signout"> /api/auth/signout</a>
12
+ </p>
13
+ </main>
14
+ );
15
+ }
@@ -0,0 +1,15 @@
1
+ export default function SignInPage() {
2
+ return (
3
+ <main>
4
+ <h1>Sign in</h1>
5
+ <p>
6
+ Use the default NextAuth sign-in:
7
+ <a href="/api/auth/signin"> /api/auth/signin</a>
8
+ </p>
9
+ <p>
10
+ Sign out:
11
+ <a href="/api/auth/signout"> /api/auth/signout</a>
12
+ </p>
13
+ </main>
14
+ );
15
+ }
@@ -0,0 +1,10 @@
1
+ # NextAuth
2
+
3
+ Files:
4
+ - `auth/auth-options.*` base config
5
+ - `app/api/auth/[...nextauth]/route.*` API route
6
+ - `auth/protected.*` example server component
7
+
8
+ Next steps:
9
+ - Add providers to `auth/auth-options.*`
10
+ - Set `NEXTAUTH_SECRET` and `NEXTAUTH_URL` in `.env`
@@ -0,0 +1,13 @@
1
+ import { createSupabaseServerClient } from '../../../src/lib/supabase-server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const supabase = createSupabaseServerClient();
5
+ const { data } = await supabase.auth.getUser();
6
+
7
+ return (
8
+ <div>
9
+ <h1>Protected</h1>
10
+ <pre>{JSON.stringify(data, null, 2)}</pre>
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,13 @@
1
+ import { createSupabaseServerClient } from '../../../src/lib/supabase-server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const supabase = createSupabaseServerClient();
5
+ const { data } = await supabase.auth.getUser();
6
+
7
+ return (
8
+ <div>
9
+ <h1>Protected</h1>
10
+ <pre>{JSON.stringify(data, null, 2)}</pre>
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,13 @@
1
+ import { createSupabaseServerClient } from '../src/lib/supabase-server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const supabase = createSupabaseServerClient();
5
+ const { data } = await supabase.auth.getUser();
6
+
7
+ return (
8
+ <div>
9
+ <h1>Protected</h1>
10
+ <pre>{JSON.stringify(data, null, 2)}</pre>
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,13 @@
1
+ import { createSupabaseServerClient } from '../src/lib/supabase-server';
2
+
3
+ export default async function ProtectedPage() {
4
+ const supabase = createSupabaseServerClient();
5
+ const { data } = await supabase.auth.getUser();
6
+
7
+ return (
8
+ <div>
9
+ <h1>Protected</h1>
10
+ <pre>{JSON.stringify(data, null, 2)}</pre>
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,25 @@
1
+ "use client";
2
+
3
+ import { useState } from 'react';
4
+ import { supabase } from '../../../src/lib/supabase';
5
+
6
+ export default function SignInPage() {
7
+ const [email, setEmail] = useState('');
8
+ const [password, setPassword] = useState('');
9
+
10
+ async function handleSubmit(e) {
11
+ e.preventDefault();
12
+ await supabase.auth.signInWithPassword({ email, password });
13
+ }
14
+
15
+ return (
16
+ <main>
17
+ <h1>Sign in</h1>
18
+ <form onSubmit={handleSubmit}>
19
+ <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email" />
20
+ <input value={password} onChange={(e) => setPassword(e.target.value)} type="password" placeholder="password" />
21
+ <button type="submit">Sign in</button>
22
+ </form>
23
+ </main>
24
+ );
25
+ }
@@ -0,0 +1,25 @@
1
+ "use client";
2
+
3
+ import { useState } from 'react';
4
+ import { supabase } from '../../../src/lib/supabase';
5
+
6
+ export default function SignInPage() {
7
+ const [email, setEmail] = useState('');
8
+ const [password, setPassword] = useState('');
9
+
10
+ async function handleSubmit(e: React.FormEvent) {
11
+ e.preventDefault();
12
+ await supabase.auth.signInWithPassword({ email, password });
13
+ }
14
+
15
+ return (
16
+ <main>
17
+ <h1>Sign in</h1>
18
+ <form onSubmit={handleSubmit}>
19
+ <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email" />
20
+ <input value={password} onChange={(e) => setPassword(e.target.value)} type="password" placeholder="password" />
21
+ <button type="submit">Sign in</button>
22
+ </form>
23
+ </main>
24
+ );
25
+ }
@@ -0,0 +1,20 @@
1
+ import { useState } from 'react';
2
+ import { supabase } from '../lib/supabase';
3
+
4
+ export function SupabaseSignIn() {
5
+ const [email, setEmail] = useState('');
6
+ const [password, setPassword] = useState('');
7
+
8
+ async function handleSubmit(e) {
9
+ e.preventDefault();
10
+ await supabase.auth.signInWithPassword({ email, password });
11
+ }
12
+
13
+ return (
14
+ <form onSubmit={handleSubmit}>
15
+ <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email" />
16
+ <input value={password} onChange={(e) => setPassword(e.target.value)} type="password" placeholder="password" />
17
+ <button type="submit">Sign in</button>
18
+ </form>
19
+ );
20
+ }
@@ -0,0 +1,20 @@
1
+ import { useState } from 'react';
2
+ import { supabase } from '../lib/supabase';
3
+
4
+ export function SupabaseSignIn() {
5
+ const [email, setEmail] = useState('');
6
+ const [password, setPassword] = useState('');
7
+
8
+ async function handleSubmit(e: React.FormEvent) {
9
+ e.preventDefault();
10
+ await supabase.auth.signInWithPassword({ email, password });
11
+ }
12
+
13
+ return (
14
+ <form onSubmit={handleSubmit}>
15
+ <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email" />
16
+ <input value={password} onChange={(e) => setPassword(e.target.value)} type="password" placeholder="password" />
17
+ <button type="submit">Sign in</button>
18
+ </form>
19
+ );
20
+ }
@@ -0,0 +1,9 @@
1
+ # Supabase Auth
2
+
3
+ Files:
4
+ - `src/lib/supabase.*` client
5
+ - `src/lib/supabase-server.*` server client
6
+ - `auth/protected.*` example server component
7
+
8
+ Next steps:
9
+ - Set `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` in `.env`
@@ -0,0 +1,8 @@
1
+ import { drizzle } from 'drizzle-orm/node-postgres';
2
+ import { Pool } from 'pg';
3
+
4
+ const pool = new Pool({
5
+ connectionString: process.env.DATABASE_URL
6
+ });
7
+
8
+ export const db = drizzle(pool);
@@ -0,0 +1,8 @@
1
+ import { drizzle } from 'drizzle-orm/node-postgres';
2
+ import { Pool } from 'pg';
3
+
4
+ const pool = new Pool({
5
+ connectionString: process.env.DATABASE_URL
6
+ });
7
+
8
+ export const db = drizzle(pool);
@@ -0,0 +1,6 @@
1
+ import type { Config } from 'drizzle-kit';
2
+
3
+ export default {
4
+ schema: './drizzle/schema.ts',
5
+ out: './drizzle/migrations'
6
+ } satisfies Config;
@@ -0,0 +1,6 @@
1
+ import { db } from './client';
2
+ import { users } from './schema';
3
+
4
+ export async function listUsers() {
5
+ return db.select().from(users);
6
+ }
@@ -0,0 +1,6 @@
1
+ import { db } from './client';
2
+ import { users } from './schema';
3
+
4
+ export async function listUsers() {
5
+ return db.select().from(users);
6
+ }
@@ -0,0 +1,6 @@
1
+ import { pgTable, serial, varchar } from 'drizzle-orm/pg-core';
2
+
3
+ export const users = pgTable('users', {
4
+ id: serial('id').primaryKey(),
5
+ name: varchar('name', { length: 255 }).notNull()
6
+ });
@@ -0,0 +1,13 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const MONGOOSE_URI = process.env.DATABASE_URL || '';
4
+
5
+ export async function connectMongoose() {
6
+ if (!MONGOOSE_URI) {
7
+ throw new Error('DATABASE_URL is not set');
8
+ }
9
+
10
+ if (mongoose.connection.readyState === 1) return;
11
+
12
+ await mongoose.connect(MONGOOSE_URI);
13
+ }
@@ -0,0 +1,13 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ const MONGOOSE_URI = process.env.DATABASE_URL || '';
4
+
5
+ export async function connectMongoose(): Promise<void> {
6
+ if (!MONGOOSE_URI) {
7
+ throw new Error('DATABASE_URL is not set');
8
+ }
9
+
10
+ if (mongoose.connection.readyState === 1) return;
11
+
12
+ await mongoose.connect(MONGOOSE_URI);
13
+ }
@@ -0,0 +1,7 @@
1
+ import { Schema, model } from 'mongoose';
2
+
3
+ const userSchema = new Schema({
4
+ name: { type: String, required: true }
5
+ });
6
+
7
+ export const User = model('User', userSchema);
@@ -0,0 +1,7 @@
1
+ import { Schema, model } from 'mongoose';
2
+
3
+ const userSchema = new Schema({
4
+ name: { type: String, required: true }
5
+ });
6
+
7
+ export const User = model('User', userSchema);
@@ -0,0 +1,3 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+
3
+ export const prisma = new PrismaClient();
@@ -0,0 +1,3 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+
3
+ export const prisma = new PrismaClient();
@@ -0,0 +1,5 @@
1
+ import { prisma } from './client';
2
+
3
+ export async function listUsers() {
4
+ return prisma.user.findMany();
5
+ }
@@ -0,0 +1,7 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+
3
+ const prisma = new PrismaClient();
4
+
5
+ export async function listUsers() {
6
+ return prisma.user.findMany();
7
+ }
@@ -0,0 +1,13 @@
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ datasource db {
6
+ provider = "postgresql"
7
+ url = env("DATABASE_URL")
8
+ }
9
+
10
+ model User {
11
+ id Int @id @default(autoincrement())
12
+ name String
13
+ }
@@ -0,0 +1,9 @@
1
+ # Neon (Serverless Postgres)
2
+
3
+ Configure:
4
+ - DATABASE_URL
5
+ - NEON_API_KEY
6
+ - NEON_PROJECT_ID
7
+
8
+ Notes:
9
+ - Uses @neondatabase/serverless + pg client.
@@ -0,0 +1,9 @@
1
+ # Supabase (Postgres)
2
+
3
+ Configure:
4
+ - DATABASE_URL
5
+ - SUPABASE_URL
6
+ - SUPABASE_ANON_KEY
7
+
8
+ Notes:
9
+ - Uses @supabase/supabase-js for client access.
@@ -0,0 +1,15 @@
1
+ import 'reflect-metadata';
2
+ import { DataSource } from 'typeorm';
3
+ import { User } from './entities/User';
4
+
5
+ const DATABASE_URL = process.env.DATABASE_URL || '';
6
+
7
+ export const AppDataSource = new DataSource({
8
+ type: '{{typeormType}}',
9
+ url: DATABASE_URL,
10
+ synchronize: false,
11
+ logging: false,
12
+ entities: [User],
13
+ migrations: ['{{migrationsPath}}'],
14
+ subscribers: []
15
+ });
@@ -0,0 +1,15 @@
1
+ import 'reflect-metadata';
2
+ import { DataSource } from 'typeorm';
3
+ import { User } from './entities/User';
4
+
5
+ const DATABASE_URL = process.env.DATABASE_URL || '';
6
+
7
+ export const AppDataSource = new DataSource({
8
+ type: '{{typeormType}}',
9
+ url: DATABASE_URL,
10
+ synchronize: false,
11
+ logging: false,
12
+ entities: [User],
13
+ migrations: ['{{migrationsPath}}'],
14
+ subscribers: []
15
+ });
@@ -0,0 +1,10 @@
1
+ import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
2
+
3
+ @Entity()
4
+ export class User {
5
+ @PrimaryGeneratedColumn()
6
+ id;
7
+
8
+ @Column()
9
+ name;
10
+ }
@@ -0,0 +1,10 @@
1
+ import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
2
+
3
+ @Entity()
4
+ export class User {
5
+ @PrimaryGeneratedColumn()
6
+ id!: number;
7
+
8
+ @Column()
9
+ name!: string;
10
+ }
@@ -0,0 +1,5 @@
1
+ TypeORM migration files will be generated here.
2
+
3
+ Example:
4
+ - Generate: npx typeorm migration:generate src/db/migrations/Init -d src/db/data-source.ts
5
+ - Run: npx typeorm migration:run -d src/db/data-source.ts
@@ -0,0 +1,6 @@
1
+ import { db } from '../../drizzle/client';
2
+ import { users } from '../../drizzle/schema';
3
+
4
+ export async function listUsers() {
5
+ return db.select().from(users);
6
+ }
@@ -0,0 +1,6 @@
1
+ import { db } from '../../drizzle/client';
2
+ import { users } from '../../drizzle/schema';
3
+
4
+ export async function listUsers() {
5
+ return db.select().from(users);
6
+ }
@@ -0,0 +1,5 @@
1
+ import { User } from '../mongoose-model';
2
+
3
+ export async function listUsers() {
4
+ return User.find().lean();
5
+ }
@@ -0,0 +1,5 @@
1
+ import { User } from '../mongoose-model';
2
+
3
+ export async function listUsers() {
4
+ return User.find().lean();
5
+ }
@@ -0,0 +1,5 @@
1
+ import { prisma } from '../prisma';
2
+
3
+ export async function listUsers() {
4
+ return prisma.user.findMany();
5
+ }
@@ -0,0 +1,5 @@
1
+ import { prisma } from '../prisma';
2
+
3
+ export async function listUsers() {
4
+ return prisma.user.findMany();
5
+ }
@@ -0,0 +1,9 @@
1
+ import { AppDataSource } from '../data-source';
2
+ import { User } from '../entities/User';
3
+
4
+ export async function listUsers() {
5
+ if (!AppDataSource.isInitialized) {
6
+ await AppDataSource.initialize();
7
+ }
8
+ return AppDataSource.getRepository(User).find();
9
+ }
@@ -0,0 +1,9 @@
1
+ import { AppDataSource } from '../data-source';
2
+ import { User } from '../entities/User';
3
+
4
+ export async function listUsers() {
5
+ if (!AppDataSource.isInitialized) {
6
+ await AppDataSource.initialize();
7
+ }
8
+ return AppDataSource.getRepository(User).find();
9
+ }
@@ -0,0 +1,9 @@
1
+ # Analytics
2
+
3
+ This project includes PostHog for analytics.
4
+
5
+ Configure:
6
+ - Add `NEXT_PUBLIC_POSTHOG_KEY` and `NEXT_PUBLIC_POSTHOG_HOST`
7
+
8
+ Usage:
9
+ - Import the client from `src/lib/posthog.ts`.
@@ -0,0 +1,7 @@
1
+ import posthog from 'posthog-js';
2
+
3
+ posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY || '', {
4
+ api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com'
5
+ });
6
+
7
+ export { posthog };
@@ -0,0 +1,9 @@
1
+ import posthog from 'posthog-js';
2
+
3
+ export function initPosthog() {
4
+ if (typeof window === 'undefined') return;
5
+ const key = process.env.NEXT_PUBLIC_POSTHOG_KEY || '';
6
+ const host = process.env.NEXT_PUBLIC_POSTHOG_HOST || 'https://app.posthog.com';
7
+ if (!key) return;
8
+ posthog.init(key, { api_host: host });
9
+ }
@@ -0,0 +1,17 @@
1
+ # Email (Resend)
2
+
3
+ ## Setup
4
+ 1. Add RESEND_API_KEY to .env.
5
+ 2. Client lives at src/lib/resend.ts.
6
+
7
+ ## Example
8
+ ```ts
9
+ import { resend } from '@/lib/resend';
10
+
11
+ await resend.emails.send({
12
+ from: 'you@example.com',
13
+ to: 'user@example.com',
14
+ subject: 'Welcome',
15
+ html: '<strong>Hello</strong>'
16
+ });
17
+ ```
@@ -0,0 +1,3 @@
1
+ import { Resend } from 'resend';
2
+
3
+ export const resend = new Resend(process.env.RESEND_API_KEY || '');
@@ -0,0 +1,3 @@
1
+ import { Resend } from 'resend';
2
+
3
+ export const resend = new Resend(process.env.RESEND_API_KEY || '');