better-ts-stack 2.0.0 → 2.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.
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/args.js +2 -2
- package/dist/builder/buildPlanner.js +71 -0
- package/dist/builder/configGenerator.js +9 -7
- package/dist/builder/dependencyInstaller.js +0 -1
- package/dist/builder/fileProcessor.js +47 -44
- package/dist/builder/gitInitializer.js +20 -1
- package/dist/builder/index.js +19 -38
- package/dist/builder/moduleSelector.js +0 -1
- package/dist/builder/templateContext.js +0 -22
- package/dist/index.js +4 -3
- package/dist/modules/registry.js +4 -6
- package/dist/output/nextSteps.js +0 -1
- package/dist/prompts/index.js +0 -1
- package/dist/prompts/stack.js +4 -1
- package/dist/types/index.js +7 -3
- package/dist/ui/index.js +0 -1
- package/dist/ui/messages.js +25 -1
- package/dist/ui/prompts.js +0 -1
- package/dist/ui/theme.js +0 -1
- package/dist/validators/index.js +10 -41
- package/package.json +2 -1
- package/templates/backend/express/.prettierrc +2 -2
- package/templates/backend/express/config.json +1 -5
- package/templates/backend/express/eslint.config.mjs +40 -40
- package/templates/backend/express/gitignore +36 -36
- package/templates/backend/express/src/{index.ts → index.ts.hbs} +28 -29
- package/templates/backend/express/src/routes/health.ts +12 -12
- package/templates/backend/express/tsconfig.json +25 -25
- package/templates/backend/nestjs/.prettierrc +16 -16
- package/templates/backend/nestjs/config.json +1 -4
- package/templates/backend/nestjs/eslint.config.mjs +40 -40
- package/templates/backend/nestjs/gitignore +36 -36
- package/templates/backend/nestjs/nest-cli.json +9 -9
- package/templates/backend/nestjs/src/app.module.ts.hbs +34 -34
- package/templates/backend/nestjs/src/health/health.controller.ts +12 -12
- package/templates/backend/nestjs/src/main.ts +23 -23
- package/templates/backend/nestjs/tsconfig.json +25 -25
- package/templates/frontend/nextjs/components.json +19 -19
- package/templates/frontend/nextjs/config.json +1 -2
- package/templates/frontend/nextjs/gitignore +42 -42
- package/templates/frontend/nextjs/lib/utils.ts +6 -6
- package/templates/frontend/nextjs/proxy.ts.hbs +24 -24
- package/templates/frontend/nextjs/tsconfig.json +34 -34
- package/templates/frontend/tanstack/config.json +1 -4
- package/templates/frontend/tanstack/src/routeTree.gen.ts +68 -68
- package/templates/frontend/tanstack/src/styles/app.css +85 -85
- package/templates/modules/auth/express/config.json +1 -8
- package/templates/modules/auth/express/src/controllers/authController.ts.hbs +116 -116
- package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +26 -26
- package/templates/modules/auth/express/src/services/userStore.ts.hbs +117 -117
- package/templates/modules/auth/nestjs/config.json +1 -5
- package/templates/modules/auth/nestjs/src/auth/auth.controller.ts +46 -46
- package/templates/modules/auth/nestjs/src/auth/auth.guard.ts +36 -36
- package/templates/modules/auth/nestjs/src/auth/auth.module.ts.hbs +22 -22
- package/templates/modules/auth/nestjs/src/auth/auth.schemas.ts +35 -35
- package/templates/modules/auth/nestjs/src/auth/auth.service.ts +70 -70
- package/templates/modules/auth/nestjs/src/auth/jwt.ts +27 -27
- package/templates/modules/auth/nestjs/src/auth/users.service.ts.hbs +144 -144
- package/templates/modules/auth/nestjs/src/auth/zod-validation.pipe.ts +16 -16
- package/templates/modules/auth/nextjs/app/dashboard/page.tsx +96 -96
- package/templates/modules/auth/nextjs/app/sign-in/page.tsx +35 -35
- package/templates/modules/auth/nextjs/app/sign-up/page.tsx +35 -35
- package/templates/modules/auth/nextjs/components/auth/sign-in-form.tsx +132 -132
- package/templates/modules/auth/nextjs/components/auth/sign-out-button.tsx +50 -50
- package/templates/modules/auth/nextjs/components/auth/sign-up-form.tsx +152 -152
- package/templates/modules/auth/nextjs/config.json +2 -15
- package/templates/modules/auth/nextjs/lib/auth-schema.ts +39 -39
- package/templates/modules/auth/nextjs/lib/auth.ts.hbs +37 -37
- package/templates/modules/auth/tanstack/config.json +2 -16
- package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +4 -4
- package/templates/modules/auth/tanstack/src/routeTree.gen.ts +140 -140
- package/templates/modules/docker/.dockerignore +14 -14
- package/templates/modules/docker/Dockerfile.hbs +1 -3
- package/templates/modules/docker/config.json +1 -5
- package/templates/modules/docker/docker-compose.yml.hbs +9 -9
- package/templates/modules/drizzle/express/config.json +1 -2
- package/templates/modules/drizzle/express/drizzle.config.ts +13 -13
- package/templates/modules/drizzle/express/src/lib/db.ts +13 -13
- package/templates/modules/drizzle/express/src/lib/schema.ts +10 -10
- package/templates/modules/drizzle/nestjs/config.json +1 -2
- package/templates/modules/drizzle/nestjs/drizzle.config.ts +13 -13
- package/templates/modules/drizzle/nestjs/src/database/database.module.ts +30 -30
- package/templates/modules/drizzle/nestjs/src/database/schema.ts +10 -10
- package/templates/modules/drizzle/nextjs/config.json +1 -4
- package/templates/modules/drizzle/nextjs/lib/db.ts +13 -13
- package/templates/modules/drizzle/nextjs/lib/schema.ts.hbs +84 -84
- package/templates/modules/drizzle/tanstack/config.json +5 -5
- package/templates/modules/mongoose/express/config.json +1 -2
- package/templates/modules/mongoose/nestjs/config.json +1 -2
- package/templates/modules/mongoose/nestjs/src/users/user.schema.ts +21 -21
- package/templates/modules/mongoose/nextjs/config.json +1 -2
- package/templates/modules/mongoose/nextjs/lib/db.ts +36 -36
- package/templates/modules/mongoose/tanstack/config.json +1 -2
- package/templates/modules/mongoose/tanstack/src/lib/db.ts +37 -37
- package/templates/modules/prisma/express/config.json +0 -1
- package/templates/modules/prisma/express/prisma/schema.prisma +1 -1
- package/templates/modules/prisma/express/prisma.config.ts +12 -12
- package/templates/modules/prisma/express/src/lib/prisma.ts +24 -24
- package/templates/modules/prisma/nestjs/config.json +0 -1
- package/templates/modules/prisma/nestjs/prisma/schema.prisma +23 -23
- package/templates/modules/prisma/nestjs/prisma.config.ts +12 -12
- package/templates/modules/prisma/nestjs/src/prisma/prisma.module.ts +11 -11
- package/templates/modules/prisma/nestjs/src/prisma/prisma.service.ts +17 -17
- package/templates/modules/prisma/nextjs/config.json +0 -1
- package/templates/modules/prisma/nextjs/prisma/schema.prisma.hbs +91 -91
- package/templates/modules/prisma/tanstack/config.json +0 -1
- package/dist/args.d.ts +0 -12
- package/dist/args.d.ts.map +0 -1
- package/dist/args.js.map +0 -1
- package/dist/builder/configGenerator.d.ts +0 -7
- package/dist/builder/configGenerator.d.ts.map +0 -1
- package/dist/builder/configGenerator.js.map +0 -1
- package/dist/builder/dependencyInstaller.d.ts +0 -3
- package/dist/builder/dependencyInstaller.d.ts.map +0 -1
- package/dist/builder/dependencyInstaller.js.map +0 -1
- package/dist/builder/fileProcessor.d.ts +0 -6
- package/dist/builder/fileProcessor.d.ts.map +0 -1
- package/dist/builder/fileProcessor.js.map +0 -1
- package/dist/builder/gitInitializer.d.ts +0 -2
- package/dist/builder/gitInitializer.d.ts.map +0 -1
- package/dist/builder/gitInitializer.js.map +0 -1
- package/dist/builder/index.d.ts +0 -3
- package/dist/builder/index.d.ts.map +0 -1
- package/dist/builder/index.js.map +0 -1
- package/dist/builder/moduleSelector.d.ts +0 -6
- package/dist/builder/moduleSelector.d.ts.map +0 -1
- package/dist/builder/moduleSelector.js.map +0 -1
- package/dist/builder/templateContext.d.ts +0 -6
- package/dist/builder/templateContext.d.ts.map +0 -1
- package/dist/builder/templateContext.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/modules/registry.d.ts +0 -6
- package/dist/modules/registry.d.ts.map +0 -1
- package/dist/modules/registry.js.map +0 -1
- package/dist/output/nextSteps.d.ts +0 -3
- package/dist/output/nextSteps.d.ts.map +0 -1
- package/dist/output/nextSteps.js.map +0 -1
- package/dist/prompts/index.d.ts +0 -4
- package/dist/prompts/index.d.ts.map +0 -1
- package/dist/prompts/index.js.map +0 -1
- package/dist/prompts/stack.d.ts +0 -4
- package/dist/prompts/stack.d.ts.map +0 -1
- package/dist/prompts/stack.js.map +0 -1
- package/dist/types/index.d.ts +0 -137
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/ui/index.d.ts +0 -3
- package/dist/ui/index.d.ts.map +0 -1
- package/dist/ui/index.js.map +0 -1
- package/dist/ui/messages.d.ts +0 -9
- package/dist/ui/messages.d.ts.map +0 -1
- package/dist/ui/messages.js.map +0 -1
- package/dist/ui/prompts.d.ts +0 -20
- package/dist/ui/prompts.d.ts.map +0 -1
- package/dist/ui/prompts.js.map +0 -1
- package/dist/ui/theme.d.ts +0 -9
- package/dist/ui/theme.d.ts.map +0 -1
- package/dist/ui/theme.js.map +0 -1
- package/dist/validators/index.d.ts +0 -6
- package/dist/validators/index.d.ts.map +0 -1
- package/dist/validators/index.js.map +0 -1
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
{{#if useAuth}}
|
|
2
|
-
import { boolean, pgTable, text, timestamp, uniqueIndex } 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
|
-
}, (table) => [uniqueIndex("account_provider_account_id_unique").on(table.providerId, table.accountId)]);
|
|
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}}
|
|
1
|
+
{{#if useAuth}}
|
|
2
|
+
import { boolean, pgTable, text, timestamp, uniqueIndex } 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
|
+
}, (table) => [uniqueIndex("account_provider_account_id_unique").on(table.providerId, table.accountId)]);
|
|
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}}
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"db:studio": "drizzle-kit studio"
|
|
19
19
|
},
|
|
20
20
|
"envVars": {
|
|
21
|
-
"DATABASE_URL": "postgresql://
|
|
21
|
+
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/postgres"
|
|
22
22
|
},
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
}
|
|
23
|
+
"overrides": {
|
|
24
|
+
"esbuild": "^0.28.2"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
|
2
|
-
|
|
3
|
-
@Schema({ timestamps: true })
|
|
4
|
-
export class User {
|
|
5
|
-
@Prop({
|
|
6
|
-
type: String,
|
|
7
|
-
required: true,
|
|
8
|
-
unique: true,
|
|
9
|
-
lowercase: true,
|
|
10
|
-
trim: true,
|
|
11
|
-
})
|
|
12
|
-
email: string;
|
|
13
|
-
|
|
14
|
-
@Prop({ type: String, trim: true })
|
|
15
|
-
name?: string | null;
|
|
16
|
-
|
|
17
|
-
@Prop({ type: String, required: true })
|
|
18
|
-
password: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const UserSchema = SchemaFactory.createForClass(User);
|
|
1
|
+
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
|
|
2
|
+
|
|
3
|
+
@Schema({ timestamps: true })
|
|
4
|
+
export class User {
|
|
5
|
+
@Prop({
|
|
6
|
+
type: String,
|
|
7
|
+
required: true,
|
|
8
|
+
unique: true,
|
|
9
|
+
lowercase: true,
|
|
10
|
+
trim: true,
|
|
11
|
+
})
|
|
12
|
+
email: string;
|
|
13
|
+
|
|
14
|
+
@Prop({ type: String, trim: true })
|
|
15
|
+
name?: string | null;
|
|
16
|
+
|
|
17
|
+
@Prop({ type: String, required: true })
|
|
18
|
+
password: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const UserSchema = SchemaFactory.createForClass(User);
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import mongoose from "mongoose";
|
|
2
|
-
|
|
3
|
-
// Reuse one connection across hot reloads and concurrent requests
|
|
4
|
-
const globalForMongoose = globalThis as unknown as {
|
|
5
|
-
mongooseConnection?: Promise<typeof mongoose>;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Connects Mongoose once and returns the shared connection.
|
|
10
|
-
* Call this in server code before querying Mongoose models.
|
|
11
|
-
*/
|
|
12
|
-
export async function connectDB(): Promise<typeof mongoose> {
|
|
13
|
-
const mongoUri = process.env.MONGODB_URI;
|
|
14
|
-
|
|
15
|
-
if (!mongoUri) {
|
|
16
|
-
throw new Error("MONGODB_URI environment variable is not defined");
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
globalForMongoose.mongooseConnection ??= mongoose
|
|
20
|
-
.connect(mongoUri)
|
|
21
|
-
.catch((error: unknown) => {
|
|
22
|
-
// Let the next call retry instead of caching the failure
|
|
23
|
-
globalForMongoose.mongooseConnection = undefined;
|
|
24
|
-
throw error;
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
return globalForMongoose.mongooseConnection;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Gracefully close the MongoDB connection
|
|
32
|
-
*/
|
|
33
|
-
export async function disconnectDB(): Promise<void> {
|
|
34
|
-
await mongoose.connection.close();
|
|
35
|
-
globalForMongoose.mongooseConnection = undefined;
|
|
36
|
-
}
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
|
|
3
|
+
// Reuse one connection across hot reloads and concurrent requests
|
|
4
|
+
const globalForMongoose = globalThis as unknown as {
|
|
5
|
+
mongooseConnection?: Promise<typeof mongoose>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Connects Mongoose once and returns the shared connection.
|
|
10
|
+
* Call this in server code before querying Mongoose models.
|
|
11
|
+
*/
|
|
12
|
+
export async function connectDB(): Promise<typeof mongoose> {
|
|
13
|
+
const mongoUri = process.env.MONGODB_URI;
|
|
14
|
+
|
|
15
|
+
if (!mongoUri) {
|
|
16
|
+
throw new Error("MONGODB_URI environment variable is not defined");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
globalForMongoose.mongooseConnection ??= mongoose
|
|
20
|
+
.connect(mongoUri)
|
|
21
|
+
.catch((error: unknown) => {
|
|
22
|
+
// Let the next call retry instead of caching the failure
|
|
23
|
+
globalForMongoose.mongooseConnection = undefined;
|
|
24
|
+
throw error;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return globalForMongoose.mongooseConnection;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Gracefully close the MongoDB connection
|
|
32
|
+
*/
|
|
33
|
+
export async function disconnectDB(): Promise<void> {
|
|
34
|
+
await mongoose.connection.close();
|
|
35
|
+
globalForMongoose.mongooseConnection = undefined;
|
|
36
|
+
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import "dotenv/config";
|
|
2
|
-
import mongoose from "mongoose";
|
|
3
|
-
|
|
4
|
-
// Reuse one connection across hot reloads and concurrent requests
|
|
5
|
-
const globalForMongoose = globalThis as unknown as {
|
|
6
|
-
mongooseConnection?: Promise<typeof mongoose>;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Connects Mongoose once and returns the shared connection.
|
|
11
|
-
* Call this in server code before querying Mongoose models.
|
|
12
|
-
*/
|
|
13
|
-
export async function connectDB(): Promise<typeof mongoose> {
|
|
14
|
-
const mongoUri = process.env.MONGODB_URI;
|
|
15
|
-
|
|
16
|
-
if (!mongoUri) {
|
|
17
|
-
throw new Error("MONGODB_URI environment variable is not defined");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
globalForMongoose.mongooseConnection ??= mongoose
|
|
21
|
-
.connect(mongoUri)
|
|
22
|
-
.catch((error: unknown) => {
|
|
23
|
-
// Let the next call retry instead of caching the failure
|
|
24
|
-
globalForMongoose.mongooseConnection = undefined;
|
|
25
|
-
throw error;
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
return globalForMongoose.mongooseConnection;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Gracefully close the MongoDB connection
|
|
33
|
-
*/
|
|
34
|
-
export async function disconnectDB(): Promise<void> {
|
|
35
|
-
await mongoose.connection.close();
|
|
36
|
-
globalForMongoose.mongooseConnection = undefined;
|
|
37
|
-
}
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import mongoose from "mongoose";
|
|
3
|
+
|
|
4
|
+
// Reuse one connection across hot reloads and concurrent requests
|
|
5
|
+
const globalForMongoose = globalThis as unknown as {
|
|
6
|
+
mongooseConnection?: Promise<typeof mongoose>;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Connects Mongoose once and returns the shared connection.
|
|
11
|
+
* Call this in server code before querying Mongoose models.
|
|
12
|
+
*/
|
|
13
|
+
export async function connectDB(): Promise<typeof mongoose> {
|
|
14
|
+
const mongoUri = process.env.MONGODB_URI;
|
|
15
|
+
|
|
16
|
+
if (!mongoUri) {
|
|
17
|
+
throw new Error("MONGODB_URI environment variable is not defined");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
globalForMongoose.mongooseConnection ??= mongoose
|
|
21
|
+
.connect(mongoUri)
|
|
22
|
+
.catch((error: unknown) => {
|
|
23
|
+
// Let the next call retry instead of caching the failure
|
|
24
|
+
globalForMongoose.mongooseConnection = undefined;
|
|
25
|
+
throw error;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return globalForMongoose.mongooseConnection;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Gracefully close the MongoDB connection
|
|
33
|
+
*/
|
|
34
|
+
export async function disconnectDB(): Promise<void> {
|
|
35
|
+
await mongoose.connection.close();
|
|
36
|
+
globalForMongoose.mongooseConnection = undefined;
|
|
37
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
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
|
-
},
|
|
9
|
-
datasource: {
|
|
10
|
-
url: env("DATABASE_URL"),
|
|
11
|
-
},
|
|
12
|
-
});
|
|
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
|
+
},
|
|
9
|
+
datasource: {
|
|
10
|
+
url: env("DATABASE_URL"),
|
|
11
|
+
},
|
|
12
|
+
});
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { PrismaPg } from "@prisma/adapter-pg";
|
|
2
|
-
import "dotenv/config";
|
|
3
|
-
|
|
4
|
-
import { PrismaClient } from "../generated/prisma/client";
|
|
5
|
-
|
|
6
|
-
const globalForPrisma = globalThis as unknown as {
|
|
7
|
-
prisma: PrismaClient | undefined;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const prisma =
|
|
11
|
-
globalForPrisma.prisma ??
|
|
12
|
-
new PrismaClient({
|
|
13
|
-
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL! }),
|
|
14
|
-
log:
|
|
15
|
-
process.env.NODE_ENV === "development"
|
|
16
|
-
? ["query", "error", "warn"]
|
|
17
|
-
: ["error"],
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
21
|
-
|
|
22
|
-
export async function disconnectPrisma(): Promise<void> {
|
|
23
|
-
await prisma.$disconnect();
|
|
24
|
-
}
|
|
1
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
|
2
|
+
import "dotenv/config";
|
|
3
|
+
|
|
4
|
+
import { PrismaClient } from "../generated/prisma/client";
|
|
5
|
+
|
|
6
|
+
const globalForPrisma = globalThis as unknown as {
|
|
7
|
+
prisma: PrismaClient | undefined;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const prisma =
|
|
11
|
+
globalForPrisma.prisma ??
|
|
12
|
+
new PrismaClient({
|
|
13
|
+
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL! }),
|
|
14
|
+
log:
|
|
15
|
+
process.env.NODE_ENV === "development"
|
|
16
|
+
? ["query", "error", "warn"]
|
|
17
|
+
: ["error"],
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
21
|
+
|
|
22
|
+
export async function disconnectPrisma(): Promise<void> {
|
|
23
|
+
await prisma.$disconnect();
|
|
24
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
// Prisma schema file
|
|
2
|
-
// Learn more: https://pris.ly/d/prisma-schema
|
|
3
|
-
|
|
4
|
-
generator client {
|
|
5
|
-
provider = "prisma-client"
|
|
6
|
-
output = "../src/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
|
-
}
|
|
1
|
+
// Prisma schema file
|
|
2
|
+
// Learn more: https://pris.ly/d/prisma-schema
|
|
3
|
+
|
|
4
|
+
generator client {
|
|
5
|
+
provider = "prisma-client"
|
|
6
|
+
output = "../src/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
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
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
|
-
},
|
|
9
|
-
datasource: {
|
|
10
|
-
url: env("DATABASE_URL"),
|
|
11
|
-
},
|
|
12
|
-
});
|
|
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
|
+
},
|
|
9
|
+
datasource: {
|
|
10
|
+
url: env("DATABASE_URL"),
|
|
11
|
+
},
|
|
12
|
+
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Global, Module } from "@nestjs/common";
|
|
2
|
-
|
|
3
|
-
import { PrismaService } from "./prisma.service.js";
|
|
4
|
-
|
|
5
|
-
// Global so any module can inject PrismaService without importing this one
|
|
6
|
-
@Global()
|
|
7
|
-
@Module({
|
|
8
|
-
providers: [PrismaService],
|
|
9
|
-
exports: [PrismaService],
|
|
10
|
-
})
|
|
11
|
-
export class PrismaModule {}
|
|
1
|
+
import { Global, Module } from "@nestjs/common";
|
|
2
|
+
|
|
3
|
+
import { PrismaService } from "./prisma.service.js";
|
|
4
|
+
|
|
5
|
+
// Global so any module can inject PrismaService without importing this one
|
|
6
|
+
@Global()
|
|
7
|
+
@Module({
|
|
8
|
+
providers: [PrismaService],
|
|
9
|
+
exports: [PrismaService],
|
|
10
|
+
})
|
|
11
|
+
export class PrismaModule {}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Injectable, type OnModuleDestroy } from "@nestjs/common";
|
|
2
|
-
import { PrismaPg } from "@prisma/adapter-pg";
|
|
3
|
-
|
|
4
|
-
import { PrismaClient } from "../generated/prisma/client.js";
|
|
5
|
-
|
|
6
|
-
@Injectable()
|
|
7
|
-
export class PrismaService extends PrismaClient implements OnModuleDestroy {
|
|
8
|
-
constructor() {
|
|
9
|
-
super({
|
|
10
|
-
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL! }),
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async onModuleDestroy(): Promise<void> {
|
|
15
|
-
await this.$disconnect();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
1
|
+
import { Injectable, type OnModuleDestroy } from "@nestjs/common";
|
|
2
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
|
3
|
+
|
|
4
|
+
import { PrismaClient } from "../generated/prisma/client.js";
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class PrismaService extends PrismaClient implements OnModuleDestroy {
|
|
8
|
+
constructor() {
|
|
9
|
+
super({
|
|
10
|
+
adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL! }),
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async onModuleDestroy(): Promise<void> {
|
|
15
|
+
await this.$disconnect();
|
|
16
|
+
}
|
|
17
|
+
}
|