better-ts-stack 0.1.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.
- package/README.md +83 -0
- package/dist/builder/configGenerator.d.ts +6 -0
- package/dist/builder/configGenerator.d.ts.map +1 -0
- package/dist/builder/configGenerator.js +110 -0
- package/dist/builder/configGenerator.js.map +1 -0
- package/dist/builder/dependencyInstaller.d.ts +3 -0
- package/dist/builder/dependencyInstaller.d.ts.map +1 -0
- package/dist/builder/dependencyInstaller.js +39 -0
- package/dist/builder/dependencyInstaller.js.map +1 -0
- package/dist/builder/fileProcessor.d.ts +6 -0
- package/dist/builder/fileProcessor.d.ts.map +1 -0
- package/dist/builder/fileProcessor.js +108 -0
- package/dist/builder/fileProcessor.js.map +1 -0
- package/dist/builder/gitInitializer.d.ts +2 -0
- package/dist/builder/gitInitializer.d.ts.map +1 -0
- package/dist/builder/gitInitializer.js +52 -0
- package/dist/builder/gitInitializer.js.map +1 -0
- package/dist/builder/index.d.ts +3 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +126 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/builder/moduleSelector.d.ts +9 -0
- package/dist/builder/moduleSelector.d.ts.map +1 -0
- package/dist/builder/moduleSelector.js +29 -0
- package/dist/builder/moduleSelector.js.map +1 -0
- package/dist/builder/templateContext.d.ts +21 -0
- package/dist/builder/templateContext.d.ts.map +1 -0
- package/dist/builder/templateContext.js +47 -0
- package/dist/builder/templateContext.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/intro.d.ts +2 -0
- package/dist/intro.d.ts.map +1 -0
- package/dist/intro.js +27 -0
- package/dist/intro.js.map +1 -0
- package/dist/modules/registry.d.ts +6 -0
- package/dist/modules/registry.d.ts.map +1 -0
- package/dist/modules/registry.js +64 -0
- package/dist/modules/registry.js.map +1 -0
- package/dist/output/nextSteps.d.ts +4 -0
- package/dist/output/nextSteps.d.ts.map +1 -0
- package/dist/output/nextSteps.js +87 -0
- package/dist/output/nextSteps.js.map +1 -0
- package/dist/prompts/backend/index.d.ts +3 -0
- package/dist/prompts/backend/index.d.ts.map +1 -0
- package/dist/prompts/backend/index.js +128 -0
- package/dist/prompts/backend/index.js.map +1 -0
- package/dist/prompts/frontend/index.d.ts +3 -0
- package/dist/prompts/frontend/index.d.ts.map +1 -0
- package/dist/prompts/frontend/index.js +111 -0
- package/dist/prompts/frontend/index.js.map +1 -0
- package/dist/prompts/index.d.ts +4 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +82 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/types/index.d.ts +157 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +81 -0
- package/dist/types/index.js.map +1 -0
- package/dist/validators/index.d.ts +5 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js +73 -0
- package/dist/validators/index.js.map +1 -0
- package/package.json +66 -0
- package/templates/backend/express/.eslintrc.js +24 -0
- package/templates/backend/express/.prettierignore +52 -0
- package/templates/backend/express/.prettierrc +16 -0
- package/templates/backend/express/config.json +42 -0
- package/templates/backend/express/eslint.config.mjs +31 -0
- package/templates/backend/express/gitignore +39 -0
- package/templates/backend/express/src/index.ts +46 -0
- package/templates/backend/express/src/routes/health.ts +12 -0
- package/templates/backend/express/tsconfig.eslint.json +9 -0
- package/templates/backend/express/tsconfig.json +23 -0
- package/templates/frontend/nextjs/app/globals.css +99 -0
- package/templates/frontend/nextjs/app/layout.tsx +34 -0
- package/templates/frontend/nextjs/app/page.tsx.hbs +98 -0
- package/templates/frontend/nextjs/components/ui/button.tsx +51 -0
- package/templates/frontend/nextjs/components/ui/card.tsx +60 -0
- package/templates/frontend/nextjs/components/ui/field.tsx +67 -0
- package/templates/frontend/nextjs/components/ui/input.tsx +18 -0
- package/templates/frontend/nextjs/components.json +19 -0
- package/templates/frontend/nextjs/config.json +33 -0
- package/templates/frontend/nextjs/eslint.config.mjs +11 -0
- package/templates/frontend/nextjs/gitignore +41 -0
- package/templates/frontend/nextjs/lib/utils.ts +6 -0
- package/templates/frontend/nextjs/next.config.ts +8 -0
- package/templates/frontend/nextjs/postcss.config.mjs +7 -0
- package/templates/frontend/nextjs/proxy.ts.hbs +23 -0
- package/templates/frontend/nextjs/public/file.svg +1 -0
- package/templates/frontend/nextjs/public/globe.svg +1 -0
- package/templates/frontend/nextjs/public/next.svg +1 -0
- package/templates/frontend/nextjs/public/vercel.svg +1 -0
- package/templates/frontend/nextjs/public/window.svg +1 -0
- package/templates/frontend/nextjs/tsconfig.json +21 -0
- package/templates/modules/auth/express/config.json +1 -0
- package/templates/modules/auth/express/src/controllers/authController.ts.hbs +81 -0
- package/templates/modules/auth/express/src/lib/jwt.ts.hbs +27 -0
- package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +26 -0
- package/templates/modules/auth/express/src/routes/auth.ts.hbs +19 -0
- package/templates/modules/auth/express/src/services/userStore.ts.hbs +107 -0
- package/templates/modules/auth/nextjs/app/api/auth/[...all]/route.ts +4 -0
- package/templates/modules/auth/nextjs/app/dashboard/page.tsx +96 -0
- package/templates/modules/auth/nextjs/app/sign-in/page.tsx +35 -0
- package/templates/modules/auth/nextjs/app/sign-up/page.tsx +35 -0
- package/templates/modules/auth/nextjs/components/auth/sign-in-form.tsx +132 -0
- package/templates/modules/auth/nextjs/components/auth/sign-out-button.tsx +50 -0
- package/templates/modules/auth/nextjs/components/auth/sign-up-form.tsx +152 -0
- package/templates/modules/auth/nextjs/config.json +31 -0
- package/templates/modules/auth/nextjs/lib/auth-client.ts +3 -0
- package/templates/modules/auth/nextjs/lib/auth-schema.ts +39 -0
- package/templates/modules/auth/nextjs/lib/auth.ts.hbs +35 -0
- package/templates/modules/docker/.dockerignore +13 -0
- package/templates/modules/docker/Dockerfile.hbs +71 -0
- package/templates/modules/docker/config.json +16 -0
- package/templates/modules/docker/docker-compose.yml.hbs +10 -0
- package/templates/modules/drizzle/nextjs/config.json +21 -0
- package/templates/modules/drizzle/nextjs/drizzle.config.ts +13 -0
- package/templates/modules/drizzle/nextjs/lib/db.ts +11 -0
- package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -0
- package/templates/modules/mongoose/config.json +16 -0
- package/templates/modules/mongoose/src/lib/db.ts +43 -0
- package/templates/modules/mongoose/src/lib/db.ts.hbs +56 -0
- package/templates/modules/mongoose/src/models/User.ts +47 -0
- package/templates/modules/prisma/express/config.json +21 -0
- package/templates/modules/prisma/express/prisma/schema.prisma +23 -0
- package/templates/modules/prisma/express/prisma.config.ts +13 -0
- package/templates/modules/prisma/express/src/lib/prisma.ts +37 -0
- package/templates/modules/prisma/nextjs/config.json +23 -0
- package/templates/modules/prisma/nextjs/lib/prisma.ts +18 -0
- package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +90 -0
- package/templates/modules/prisma/nextjs/prisma.config.ts +12 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{{#if useAuth}}
|
|
2
|
+
import { boolean, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
|
3
|
+
|
|
4
|
+
export const user = pgTable("user", {
|
|
5
|
+
id: text("id").primaryKey(),
|
|
6
|
+
name: text("name").notNull(),
|
|
7
|
+
email: text("email").notNull().unique(),
|
|
8
|
+
emailVerified: boolean("email_verified").notNull().default(false),
|
|
9
|
+
image: text("image"),
|
|
10
|
+
createdAt: timestamp("created_at", { withTimezone: true })
|
|
11
|
+
.notNull()
|
|
12
|
+
.defaultNow(),
|
|
13
|
+
updatedAt: timestamp("updated_at", { withTimezone: true })
|
|
14
|
+
.notNull()
|
|
15
|
+
.defaultNow(),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const session = pgTable("session", {
|
|
19
|
+
id: text("id").primaryKey(),
|
|
20
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
|
|
21
|
+
token: text("token").notNull().unique(),
|
|
22
|
+
createdAt: timestamp("created_at", { withTimezone: true })
|
|
23
|
+
.notNull()
|
|
24
|
+
.defaultNow(),
|
|
25
|
+
updatedAt: timestamp("updated_at", { withTimezone: true })
|
|
26
|
+
.notNull()
|
|
27
|
+
.defaultNow(),
|
|
28
|
+
ipAddress: text("ip_address"),
|
|
29
|
+
userAgent: text("user_agent"),
|
|
30
|
+
userId: text("user_id")
|
|
31
|
+
.notNull()
|
|
32
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const account = pgTable("account", {
|
|
36
|
+
id: text("id").primaryKey(),
|
|
37
|
+
accountId: text("account_id").notNull(),
|
|
38
|
+
providerId: text("provider_id").notNull(),
|
|
39
|
+
userId: text("user_id")
|
|
40
|
+
.notNull()
|
|
41
|
+
.references(() => user.id, { onDelete: "cascade" }),
|
|
42
|
+
accessToken: text("access_token"),
|
|
43
|
+
refreshToken: text("refresh_token"),
|
|
44
|
+
idToken: text("id_token"),
|
|
45
|
+
accessTokenExpiresAt: timestamp("access_token_expires_at", {
|
|
46
|
+
withTimezone: true,
|
|
47
|
+
}),
|
|
48
|
+
refreshTokenExpiresAt: timestamp("refresh_token_expires_at", {
|
|
49
|
+
withTimezone: true,
|
|
50
|
+
}),
|
|
51
|
+
scope: text("scope"),
|
|
52
|
+
password: text("password"),
|
|
53
|
+
createdAt: timestamp("created_at", { withTimezone: true })
|
|
54
|
+
.notNull()
|
|
55
|
+
.defaultNow(),
|
|
56
|
+
updatedAt: timestamp("updated_at", { withTimezone: true })
|
|
57
|
+
.notNull()
|
|
58
|
+
.defaultNow(),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export const verification = pgTable("verification", {
|
|
62
|
+
id: text("id").primaryKey(),
|
|
63
|
+
identifier: text("identifier").notNull(),
|
|
64
|
+
value: text("value").notNull(),
|
|
65
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
|
|
66
|
+
createdAt: timestamp("created_at", { withTimezone: true })
|
|
67
|
+
.notNull()
|
|
68
|
+
.defaultNow(),
|
|
69
|
+
updatedAt: timestamp("updated_at", { withTimezone: true })
|
|
70
|
+
.notNull()
|
|
71
|
+
.defaultNow(),
|
|
72
|
+
});
|
|
73
|
+
{{else}}
|
|
74
|
+
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
|
75
|
+
|
|
76
|
+
export const users = pgTable("users", {
|
|
77
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
78
|
+
email: text("email").notNull().unique(),
|
|
79
|
+
name: text("name"),
|
|
80
|
+
password: text("password").notNull(),
|
|
81
|
+
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow(),
|
|
82
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).defaultNow(),
|
|
83
|
+
});
|
|
84
|
+
{{/if}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "mongoose",
|
|
3
|
+
"name": "Mongoose (MongoDB)",
|
|
4
|
+
"description": "MongoDB database integration using Mongoose ODM",
|
|
5
|
+
"type": "database",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"mongoose": "^8.0.0",
|
|
8
|
+
"mongodb": "^6.0.0"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {},
|
|
11
|
+
"scripts": {},
|
|
12
|
+
"envVars": {
|
|
13
|
+
"MONGODB_URI": "mongodb://localhost:27017/myapp"
|
|
14
|
+
},
|
|
15
|
+
"templateFiles": ["src/lib/db.ts.hbs"]
|
|
16
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MongoDB connection configuration
|
|
5
|
+
*/
|
|
6
|
+
const connectDB = async (): Promise<void> => {
|
|
7
|
+
try {
|
|
8
|
+
const mongoUri = process.env.MONGODB_URI;
|
|
9
|
+
|
|
10
|
+
if (!mongoUri) {
|
|
11
|
+
throw new Error("MONGODB_URI environment variable is not defined");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
await mongoose.connect(mongoUri);
|
|
15
|
+
|
|
16
|
+
console.log("MongoDB connected successfully");
|
|
17
|
+
|
|
18
|
+
mongoose.connection.on("error", (error) => {
|
|
19
|
+
console.error("MongoDB connection error:", error);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
mongoose.connection.on("disconnected", () => {
|
|
23
|
+
console.log("MongoDB disconnected");
|
|
24
|
+
});
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error("Failed to connect to MongoDB:", error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Gracefully close MongoDB connection
|
|
33
|
+
*/
|
|
34
|
+
const disconnectDB = async (): Promise<void> => {
|
|
35
|
+
try {
|
|
36
|
+
await mongoose.connection.close();
|
|
37
|
+
console.log("MongoDB connection closed");
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error("Error closing MongoDB connection:", error);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export { connectDB, disconnectDB };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{{#if useAuth}}
|
|
2
|
+
import { MongoClient } from "mongodb";
|
|
3
|
+
|
|
4
|
+
const uri = process.env.MONGODB_URI;
|
|
5
|
+
|
|
6
|
+
if (!uri) {
|
|
7
|
+
throw new Error("MONGODB_URI environment variable is not defined");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const client = new MongoClient(uri);
|
|
11
|
+
export const db = client.db();
|
|
12
|
+
{{else}}
|
|
13
|
+
import mongoose from "mongoose";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* MongoDB connection configuration
|
|
17
|
+
*/
|
|
18
|
+
const connectDB = async (): Promise<void> => {
|
|
19
|
+
try {
|
|
20
|
+
const mongoUri = process.env.MONGODB_URI;
|
|
21
|
+
|
|
22
|
+
if (!mongoUri) {
|
|
23
|
+
throw new Error("MONGODB_URI environment variable is not defined");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
await mongoose.connect(mongoUri);
|
|
27
|
+
|
|
28
|
+
console.log("MongoDB connected successfully");
|
|
29
|
+
|
|
30
|
+
mongoose.connection.on("error", (error) => {
|
|
31
|
+
console.error("MongoDB connection error:", error);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
mongoose.connection.on("disconnected", () => {
|
|
35
|
+
console.log("MongoDB disconnected");
|
|
36
|
+
});
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("Failed to connect to MongoDB:", error);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Gracefully close MongoDB connection
|
|
45
|
+
*/
|
|
46
|
+
const disconnectDB = async (): Promise<void> => {
|
|
47
|
+
try {
|
|
48
|
+
await mongoose.connection.close();
|
|
49
|
+
console.log("MongoDB connection closed");
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("Error closing MongoDB connection:", error);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { connectDB, disconnectDB };
|
|
56
|
+
{{/if}}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import mongoose, { Document, Schema } from "mongoose";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* User document interface
|
|
5
|
+
*/
|
|
6
|
+
export interface IUser extends Document {
|
|
7
|
+
email: string;
|
|
8
|
+
name: string;
|
|
9
|
+
password: string;
|
|
10
|
+
createdAt: Date;
|
|
11
|
+
updatedAt: Date;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* User schema definition
|
|
16
|
+
*/
|
|
17
|
+
const userSchema = new Schema<IUser>(
|
|
18
|
+
{
|
|
19
|
+
email: {
|
|
20
|
+
type: String,
|
|
21
|
+
required: true,
|
|
22
|
+
unique: true,
|
|
23
|
+
lowercase: true,
|
|
24
|
+
trim: true,
|
|
25
|
+
},
|
|
26
|
+
name: {
|
|
27
|
+
type: String,
|
|
28
|
+
required: true,
|
|
29
|
+
trim: true,
|
|
30
|
+
},
|
|
31
|
+
password: {
|
|
32
|
+
type: String,
|
|
33
|
+
required: true,
|
|
34
|
+
minlength: 6,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
timestamps: true,
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* User model
|
|
44
|
+
*/
|
|
45
|
+
const User = mongoose.model<IUser>("User", userSchema);
|
|
46
|
+
|
|
47
|
+
export default User;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "prisma",
|
|
3
|
+
"name": "Prisma ORM",
|
|
4
|
+
"description": "Prisma ORM with PostgreSQL database support",
|
|
5
|
+
"type": "database",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@prisma/adapter-pg": "^7.4.1",
|
|
8
|
+
"@prisma/client": "^7.4.1"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": { "prisma": "^7.4.1" },
|
|
11
|
+
"scripts": {
|
|
12
|
+
"prisma:generate": "prisma generate",
|
|
13
|
+
"prisma:migrate": "prisma migrate dev",
|
|
14
|
+
"prisma:studio": "prisma studio",
|
|
15
|
+
"prisma:seed": "{{#if (eq packageManager 'bun')}}bun prisma/seed.ts{{else}}tsx prisma/seed.ts{{/if}}"
|
|
16
|
+
},
|
|
17
|
+
"envVars": {
|
|
18
|
+
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
|
|
19
|
+
},
|
|
20
|
+
"templateFiles": []
|
|
21
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Prisma schema file
|
|
2
|
+
// Learn more: https://pris.ly/d/prisma-schema
|
|
3
|
+
|
|
4
|
+
generator client {
|
|
5
|
+
provider = "prisma-client-js"
|
|
6
|
+
output = "../app/generated/prisma"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
datasource db {
|
|
10
|
+
provider = "postgresql"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Sample User model
|
|
14
|
+
model User {
|
|
15
|
+
id String @id @default(uuid())
|
|
16
|
+
email String @unique
|
|
17
|
+
name String?
|
|
18
|
+
password String
|
|
19
|
+
createdAt DateTime @default(now())
|
|
20
|
+
updatedAt DateTime @updatedAt
|
|
21
|
+
|
|
22
|
+
@@map("users")
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { defineConfig, env } from "prisma/config";
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
schema: "prisma/schema.prisma",
|
|
6
|
+
migrations: {
|
|
7
|
+
path: "prisma/migrations",
|
|
8
|
+
seed: "tsx prisma/seed.ts",
|
|
9
|
+
},
|
|
10
|
+
datasource: {
|
|
11
|
+
url: env("DATABASE_URL"),
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prisma Client Setup
|
|
3
|
+
* Uses PrismaPg driver adapter for PostgreSQL. Singleton in development to avoid multiple connections.
|
|
4
|
+
* @see https://www.prisma.io/docs/orm/overview/databases/postgresql#pg-and-prismapg
|
|
5
|
+
*/
|
|
6
|
+
import "dotenv/config";
|
|
7
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
|
8
|
+
import { PrismaClient } from "../../app/generated/prisma";
|
|
9
|
+
|
|
10
|
+
const pool = new PrismaPg({
|
|
11
|
+
connectionString: process.env.DATABASE_URL!,
|
|
12
|
+
});
|
|
13
|
+
const prismaClient = new PrismaClient({
|
|
14
|
+
adapter: pool,
|
|
15
|
+
log:
|
|
16
|
+
process.env.NODE_ENV === "development"
|
|
17
|
+
? ["query", "error", "warn"]
|
|
18
|
+
: ["error"],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const globalForPrisma = globalThis as unknown as {
|
|
22
|
+
prisma: PrismaClient | undefined;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const prisma =
|
|
26
|
+
globalForPrisma.prisma ?? prismaClient;
|
|
27
|
+
|
|
28
|
+
if (process.env.NODE_ENV !== "production") {
|
|
29
|
+
globalForPrisma.prisma = prisma;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Gracefully disconnect Prisma on application shutdown
|
|
34
|
+
*/
|
|
35
|
+
export async function disconnectPrisma(): Promise<void> {
|
|
36
|
+
await prisma.$disconnect();
|
|
37
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "prisma",
|
|
3
|
+
"name": "Prisma ORM",
|
|
4
|
+
"description": "Prisma ORM for Next.js with PostgreSQL",
|
|
5
|
+
"type": "database",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@prisma/client": "^7.4.1",
|
|
8
|
+
"@prisma/adapter-pg": "^7.4.1"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"prisma": "^7.4.1",
|
|
12
|
+
"dotenv": "^17.3.1"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"prisma:generate": "prisma generate",
|
|
16
|
+
"prisma:migrate": "prisma migrate dev",
|
|
17
|
+
"prisma:studio": "prisma studio"
|
|
18
|
+
},
|
|
19
|
+
"envVars": {
|
|
20
|
+
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/postgres?schema=public"
|
|
21
|
+
},
|
|
22
|
+
"templateFiles": ["prisma/schema.prisma.hbs"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
|
2
|
+
|
|
3
|
+
import { PrismaClient } from "../generated/client";
|
|
4
|
+
|
|
5
|
+
const globalForPrisma = global as unknown as {
|
|
6
|
+
prisma: PrismaClient;
|
|
7
|
+
};
|
|
8
|
+
const adapter = new PrismaPg({
|
|
9
|
+
connectionString: process.env.DATABASE_URL,
|
|
10
|
+
});
|
|
11
|
+
const prisma =
|
|
12
|
+
globalForPrisma.prisma ||
|
|
13
|
+
new PrismaClient({
|
|
14
|
+
adapter,
|
|
15
|
+
});
|
|
16
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
17
|
+
|
|
18
|
+
export default prisma;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Prisma schema file
|
|
2
|
+
// Learn more: https://pris.ly/d/prisma-schema
|
|
3
|
+
|
|
4
|
+
generator client {
|
|
5
|
+
provider = "prisma-client-js"
|
|
6
|
+
output = "../generated/client"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
datasource db {
|
|
10
|
+
provider = "postgresql"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
{{#if useAuth}}
|
|
14
|
+
|
|
15
|
+
model User {
|
|
16
|
+
id String @id
|
|
17
|
+
name String
|
|
18
|
+
email String
|
|
19
|
+
emailVerified Boolean @default(false)
|
|
20
|
+
image String?
|
|
21
|
+
createdAt DateTime @default(now())
|
|
22
|
+
updatedAt DateTime @updatedAt
|
|
23
|
+
sessions Session[]
|
|
24
|
+
accounts Account[]
|
|
25
|
+
|
|
26
|
+
@@unique([email])
|
|
27
|
+
@@map("user")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
model Session {
|
|
31
|
+
id String @id
|
|
32
|
+
expiresAt DateTime
|
|
33
|
+
token String
|
|
34
|
+
createdAt DateTime @default(now())
|
|
35
|
+
updatedAt DateTime @updatedAt
|
|
36
|
+
ipAddress String?
|
|
37
|
+
userAgent String?
|
|
38
|
+
userId String
|
|
39
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
40
|
+
|
|
41
|
+
@@unique([token])
|
|
42
|
+
@@index([userId])
|
|
43
|
+
@@map("session")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
model Account {
|
|
47
|
+
id String @id
|
|
48
|
+
accountId String
|
|
49
|
+
providerId String
|
|
50
|
+
userId String
|
|
51
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
52
|
+
accessToken String?
|
|
53
|
+
refreshToken String?
|
|
54
|
+
idToken String?
|
|
55
|
+
accessTokenExpiresAt DateTime?
|
|
56
|
+
refreshTokenExpiresAt DateTime?
|
|
57
|
+
scope String?
|
|
58
|
+
password String?
|
|
59
|
+
createdAt DateTime @default(now())
|
|
60
|
+
updatedAt DateTime @updatedAt
|
|
61
|
+
|
|
62
|
+
@@index([userId])
|
|
63
|
+
@@map("account")
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
model Verification {
|
|
67
|
+
id String @id
|
|
68
|
+
identifier String
|
|
69
|
+
value String
|
|
70
|
+
expiresAt DateTime
|
|
71
|
+
createdAt DateTime @default(now())
|
|
72
|
+
updatedAt DateTime @updatedAt
|
|
73
|
+
|
|
74
|
+
@@index([identifier])
|
|
75
|
+
@@map("verification")
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
{{else}}
|
|
79
|
+
// Sample User model
|
|
80
|
+
model User {
|
|
81
|
+
id String @id @default(uuid())
|
|
82
|
+
email String @unique
|
|
83
|
+
name String?
|
|
84
|
+
password String
|
|
85
|
+
createdAt DateTime @default(now())
|
|
86
|
+
updatedAt DateTime @updatedAt
|
|
87
|
+
|
|
88
|
+
@@map("users")
|
|
89
|
+
}
|
|
90
|
+
{{/if}}
|