mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
add mongoose orm to the stack builder (#191)
This commit is contained in:
committed by
GitHub
parent
946f3eb421
commit
437cf9a45a
5
.changeset/floppy-fans-cross.md
Normal file
5
.changeset/floppy-fans-cross.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"create-better-t-stack": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
add mongoose orm support to the stack builder
|
||||||
@@ -40,6 +40,8 @@ export const dependencyVersionMap = {
|
|||||||
"@prisma/client": "^6.7.0",
|
"@prisma/client": "^6.7.0",
|
||||||
prisma: "^6.7.0",
|
prisma: "^6.7.0",
|
||||||
|
|
||||||
|
mongoose: "^8.14.0",
|
||||||
|
|
||||||
"vite-plugin-pwa": "^0.21.2",
|
"vite-plugin-pwa": "^0.21.2",
|
||||||
"@vite-pwa/assets-generator": "^0.2.6",
|
"@vite-pwa/assets-generator": "^0.2.6",
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ export async function setupDatabase(config: ProjectConfig): Promise<void> {
|
|||||||
projectDir: serverDir,
|
projectDir: serverDir,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} else if (orm === "mongoose") {
|
||||||
|
await addPackageDependency({
|
||||||
|
dependencies: ["mongoose"],
|
||||||
|
devDependencies: [],
|
||||||
|
projectDir: serverDir,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (database === "sqlite" && dbSetup === "turso") {
|
if (database === "sqlite" && dbSetup === "turso") {
|
||||||
|
|||||||
@@ -367,6 +367,11 @@ export async function setupAuthTemplate(
|
|||||||
PKG_ROOT,
|
PKG_ROOT,
|
||||||
`templates/auth/server/db/prisma/${db}`,
|
`templates/auth/server/db/prisma/${db}`,
|
||||||
);
|
);
|
||||||
|
} else if (orm === "mongoose") {
|
||||||
|
authDbSrc = path.join(
|
||||||
|
PKG_ROOT,
|
||||||
|
`templates/auth/server/db/mongoose/${db}`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (authDbSrc && (await fs.pathExists(authDbSrc))) {
|
if (authDbSrc && (await fs.pathExists(authDbSrc))) {
|
||||||
await processAndCopyFiles("**/*", authDbSrc, serverAppDir, context);
|
await processAndCopyFiles("**/*", authDbSrc, serverAppDir, context);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ async function main() {
|
|||||||
.option("orm", {
|
.option("orm", {
|
||||||
type: "string",
|
type: "string",
|
||||||
describe: "ORM type",
|
describe: "ORM type",
|
||||||
choices: ["drizzle", "prisma", "none"],
|
choices: ["drizzle", "prisma", "mongoose", "none"],
|
||||||
})
|
})
|
||||||
.option("auth", {
|
.option("auth", {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
@@ -448,13 +448,32 @@ function processAndValidateFlags(
|
|||||||
|
|
||||||
if (effectiveDatabase === "mongodb" && effectiveOrm === "drizzle") {
|
if (effectiveDatabase === "mongodb" && effectiveOrm === "drizzle") {
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
"MongoDB is only available with Prisma. Cannot use --database mongodb with --orm drizzle",
|
"Drizzle ORM is not compatible with MongoDB. Please use --orm prisma or --orm mongoose.",
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
effectiveOrm === "mongoose" &&
|
||||||
|
effectiveDatabase &&
|
||||||
|
effectiveDatabase !== "mongodb"
|
||||||
|
) {
|
||||||
|
consola.fatal(
|
||||||
|
`Mongoose ORM requires MongoDB. Cannot use --orm mongoose with --database ${effectiveDatabase}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.dbSetup && config.dbSetup !== "none") {
|
if (config.dbSetup && config.dbSetup !== "none") {
|
||||||
const dbSetup = config.dbSetup;
|
const dbSetup = config.dbSetup;
|
||||||
|
|
||||||
|
if (!effectiveDatabase || effectiveDatabase === "none") {
|
||||||
|
consola.fatal(
|
||||||
|
`Database setup '--db-setup ${dbSetup}' requires a database. Cannot use when database is 'none'.`,
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (dbSetup === "turso") {
|
if (dbSetup === "turso") {
|
||||||
if (effectiveDatabase && effectiveDatabase !== "sqlite") {
|
if (effectiveDatabase && effectiveDatabase !== "sqlite") {
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
@@ -462,60 +481,45 @@ function processAndValidateFlags(
|
|||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
if (effectiveOrm === "prisma") {
|
if (effectiveOrm !== "drizzle") {
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
"Turso setup is not compatible with Prisma. Cannot use --db-setup turso with --orm prisma",
|
`Turso setup requires Drizzle ORM. Cannot use --db-setup turso with --orm ${effectiveOrm ?? "none"}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
config.database = "sqlite";
|
|
||||||
config.orm = "drizzle";
|
|
||||||
} else if (dbSetup === "prisma-postgres") {
|
} else if (dbSetup === "prisma-postgres") {
|
||||||
if (effectiveDatabase && effectiveDatabase !== "postgres") {
|
if (effectiveDatabase !== "postgres") {
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
`Prisma PostgreSQL setup requires PostgreSQL. Cannot use --db-setup prisma-postgres with --database ${effectiveDatabase}.`,
|
`Prisma PostgreSQL setup requires PostgreSQL. Cannot use --db-setup prisma-postgres with --database ${effectiveDatabase}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
if (
|
if (effectiveOrm !== "prisma") {
|
||||||
effectiveOrm &&
|
|
||||||
effectiveOrm !== "prisma" &&
|
|
||||||
effectiveOrm !== "none"
|
|
||||||
) {
|
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
`Prisma PostgreSQL setup requires Prisma ORM. Cannot use --db-setup prisma-postgres with --orm ${effectiveOrm}.`,
|
`Prisma PostgreSQL setup requires Prisma ORM. Cannot use --db-setup prisma-postgres with --orm ${effectiveOrm}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
config.database = "postgres";
|
|
||||||
config.orm = "prisma";
|
|
||||||
} else if (dbSetup === "mongodb-atlas") {
|
} else if (dbSetup === "mongodb-atlas") {
|
||||||
if (effectiveDatabase && effectiveDatabase !== "mongodb") {
|
if (effectiveDatabase !== "mongodb") {
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
`MongoDB Atlas setup requires MongoDB. Cannot use --db-setup mongodb-atlas with --database ${effectiveDatabase}.`,
|
`MongoDB Atlas setup requires MongoDB. Cannot use --db-setup mongodb-atlas with --database ${effectiveDatabase}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
if (
|
if (effectiveOrm !== "prisma" && effectiveOrm !== "mongoose") {
|
||||||
effectiveOrm &&
|
|
||||||
effectiveOrm !== "prisma" &&
|
|
||||||
effectiveOrm !== "none"
|
|
||||||
) {
|
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
`MongoDB Atlas setup requires Prisma ORM. Cannot use --db-setup mongodb-atlas with --orm ${effectiveOrm}.`,
|
`MongoDB Atlas setup requires Prisma or Mongoose ORM. Cannot use --db-setup mongodb-atlas with --orm ${effectiveOrm}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
config.database = "mongodb";
|
|
||||||
config.orm = "prisma";
|
|
||||||
} else if (dbSetup === "neon") {
|
} else if (dbSetup === "neon") {
|
||||||
if (effectiveDatabase && effectiveDatabase !== "postgres") {
|
if (effectiveDatabase !== "postgres") {
|
||||||
consola.fatal(
|
consola.fatal(
|
||||||
`Neon PostgreSQL setup requires PostgreSQL. Cannot use --db-setup neon with --database ${effectiveDatabase}.`,
|
`Neon PostgreSQL setup requires PostgreSQL. Cannot use --db-setup neon with --database ${effectiveDatabase}.`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
config.database = "postgres";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,24 @@ import pc from "picocolors";
|
|||||||
import { DEFAULT_CONFIG } from "../constants";
|
import { DEFAULT_CONFIG } from "../constants";
|
||||||
import type { ProjectBackend, ProjectDatabase, ProjectOrm } from "../types";
|
import type { ProjectBackend, ProjectDatabase, ProjectOrm } from "../types";
|
||||||
|
|
||||||
|
const ormOptions = {
|
||||||
|
prisma: {
|
||||||
|
value: "prisma" as const,
|
||||||
|
label: "Prisma",
|
||||||
|
hint: "Powerful, feature-rich ORM",
|
||||||
|
},
|
||||||
|
mongoose: {
|
||||||
|
value: "mongoose" as const,
|
||||||
|
label: "Mongoose",
|
||||||
|
hint: "Elegant object modeling tool",
|
||||||
|
},
|
||||||
|
drizzle: {
|
||||||
|
value: "drizzle" as const,
|
||||||
|
label: "Drizzle",
|
||||||
|
hint: "Lightweight and performant TypeScript ORM",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export async function getORMChoice(
|
export async function getORMChoice(
|
||||||
orm: ProjectOrm | undefined,
|
orm: ProjectOrm | undefined,
|
||||||
hasDatabase: boolean,
|
hasDatabase: boolean,
|
||||||
@@ -16,26 +34,16 @@ export async function getORMChoice(
|
|||||||
if (!hasDatabase) return "none";
|
if (!hasDatabase) return "none";
|
||||||
if (orm !== undefined) return orm;
|
if (orm !== undefined) return orm;
|
||||||
|
|
||||||
if (database === "mongodb") {
|
const options = [
|
||||||
log.info("Only Prisma is supported with MongoDB.");
|
...(database === "mongodb"
|
||||||
return "prisma";
|
? [ormOptions.prisma, ormOptions.mongoose]
|
||||||
}
|
: [ormOptions.drizzle, ormOptions.prisma]),
|
||||||
|
];
|
||||||
|
|
||||||
const response = await select<ProjectOrm>({
|
const response = await select<ProjectOrm>({
|
||||||
message: "Select ORM",
|
message: "Select ORM",
|
||||||
options: [
|
options,
|
||||||
{
|
initialValue: database === "mongodb" ? "prisma" : DEFAULT_CONFIG.orm,
|
||||||
value: "drizzle",
|
|
||||||
label: "Drizzle",
|
|
||||||
hint: "lightweight and performant TypeScript ORM",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: "prisma",
|
|
||||||
label: "Prisma",
|
|
||||||
hint: "Powerful, feature-rich ORM",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
initialValue: DEFAULT_CONFIG.orm,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isCancel(response)) {
|
if (isCancel(response)) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export type ProjectDatabase =
|
|||||||
| "mongodb"
|
| "mongodb"
|
||||||
| "mysql"
|
| "mysql"
|
||||||
| "none";
|
| "none";
|
||||||
export type ProjectOrm = "drizzle" | "prisma" | "none";
|
export type ProjectOrm = "drizzle" | "prisma" | "mongoose" | "none";
|
||||||
export type ProjectPackageManager = "npm" | "pnpm" | "bun";
|
export type ProjectPackageManager = "npm" | "pnpm" | "bun";
|
||||||
export type ProjectAddons =
|
export type ProjectAddons =
|
||||||
| "pwa"
|
| "pwa"
|
||||||
|
|||||||
@@ -58,6 +58,31 @@ export const auth = betterAuth({
|
|||||||
});
|
});
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq orm "mongoose")}}
|
||||||
|
import { betterAuth } from "better-auth";
|
||||||
|
import { mongodbAdapter } from "better-auth/adapters/mongodb";
|
||||||
|
{{#if (includes frontend "native")}}
|
||||||
|
import { expo } from "@better-auth/expo";
|
||||||
|
{{/if}}
|
||||||
|
import { client } from "../db";
|
||||||
|
|
||||||
|
export const auth = betterAuth({
|
||||||
|
database: mongodbAdapter(client.db()),
|
||||||
|
trustedOrigins: [
|
||||||
|
process.env.CORS_ORIGIN || "",{{#if (includes frontend "native")}}
|
||||||
|
"my-better-t-app://",{{/if}}
|
||||||
|
],
|
||||||
|
emailAndPassword: {
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
{{~#if (includes frontend "native")}}
|
||||||
|
,
|
||||||
|
plugins: [expo()]
|
||||||
|
{{/if~}}
|
||||||
|
});
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if (eq orm "none")}}
|
{{#if (eq orm "none")}}
|
||||||
import { betterAuth } from "better-auth";
|
import { betterAuth } from "better-auth";
|
||||||
{{#if (includes frontend "native")}}
|
{{#if (includes frontend "native")}}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
const { Schema, model } = mongoose;
|
||||||
|
|
||||||
|
const userSchema = new Schema(
|
||||||
|
{
|
||||||
|
_id: { type: String },
|
||||||
|
name: { type: String, required: true },
|
||||||
|
email: { type: String, required: true, unique: true },
|
||||||
|
emailVerified: { type: Boolean, required: true },
|
||||||
|
image: { type: String },
|
||||||
|
createdAt: { type: Date, required: true },
|
||||||
|
updatedAt: { type: Date, required: true },
|
||||||
|
},
|
||||||
|
{ collection: 'user' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const sessionSchema = new Schema(
|
||||||
|
{
|
||||||
|
_id: { type: String },
|
||||||
|
expiresAt: { type: Date, required: true },
|
||||||
|
token: { type: String, required: true, unique: true },
|
||||||
|
createdAt: { type: Date, required: true },
|
||||||
|
updatedAt: { type: Date, required: true },
|
||||||
|
ipAddress: { type: String },
|
||||||
|
userAgent: { type: String },
|
||||||
|
userId: { type: String, ref: 'User', required: true },
|
||||||
|
},
|
||||||
|
{ collection: 'session' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const accountSchema = new Schema(
|
||||||
|
{
|
||||||
|
_id: { type: String },
|
||||||
|
accountId: { type: String, required: true },
|
||||||
|
providerId: { type: String, required: true },
|
||||||
|
userId: { type: String, ref: 'User', required: true },
|
||||||
|
accessToken: { type: String },
|
||||||
|
refreshToken: { type: String },
|
||||||
|
idToken: { type: String },
|
||||||
|
accessTokenExpiresAt: { type: Date },
|
||||||
|
refreshTokenExpiresAt: { type: Date },
|
||||||
|
scope: { type: String },
|
||||||
|
password: { type: String },
|
||||||
|
createdAt: { type: Date, required: true },
|
||||||
|
updatedAt: { type: Date, required: true },
|
||||||
|
},
|
||||||
|
{ collection: 'account' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const verificationSchema = new Schema(
|
||||||
|
{
|
||||||
|
_id: { type: String },
|
||||||
|
identifier: { type: String, required: true },
|
||||||
|
value: { type: String, required: true },
|
||||||
|
expiresAt: { type: Date, required: true },
|
||||||
|
createdAt: { type: Date },
|
||||||
|
updatedAt: { type: Date },
|
||||||
|
},
|
||||||
|
{ collection: 'verification' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const User = model('User', userSchema);
|
||||||
|
const Session = model('Session', sessionSchema);
|
||||||
|
const Account = model('Account', accountSchema);
|
||||||
|
const Verification = model('Verification', verificationSchema);
|
||||||
|
|
||||||
|
export { User, Session, Account, Verification };
|
||||||
6
apps/cli/templates/db/mongoose/mongodb/src/db/index.ts
Normal file
6
apps/cli/templates/db/mongoose/mongodb/src/db/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
await mongoose.connect(process.env.DATABASE_URL || "");
|
||||||
|
const client = mongoose.connection.getClient();
|
||||||
|
|
||||||
|
export { client };
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
{{#if (eq api "orpc")}}
|
||||||
|
import { z } from "zod";
|
||||||
|
import { publicProcedure } from "../lib/orpc";
|
||||||
|
import { Todo } from "../db/models/todo.model";
|
||||||
|
|
||||||
|
export const todoRouter = {
|
||||||
|
getAll: publicProcedure.handler(async () => {
|
||||||
|
return await Todo.find().lean();
|
||||||
|
}),
|
||||||
|
|
||||||
|
create: publicProcedure
|
||||||
|
.input(z.object({ text: z.string().min(1) }))
|
||||||
|
.handler(async ({ input }) => {
|
||||||
|
const newTodo = await Todo.create({ text: input.text });
|
||||||
|
return newTodo.toObject();
|
||||||
|
}),
|
||||||
|
|
||||||
|
toggle: publicProcedure
|
||||||
|
.input(z.object({ id: z.string(), completed: z.boolean() }))
|
||||||
|
.handler(async ({ input }) => {
|
||||||
|
await Todo.updateOne({ id: input.id }, { completed: input.completed });
|
||||||
|
return { success: true };
|
||||||
|
}),
|
||||||
|
|
||||||
|
delete: publicProcedure
|
||||||
|
.input(z.object({ id: z.string() }))
|
||||||
|
.handler(async ({ input }) => {
|
||||||
|
await Todo.deleteOne({ id: input.id });
|
||||||
|
return { success: true };
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq api "trpc")}}
|
||||||
|
import { z } from "zod";
|
||||||
|
import { router, publicProcedure } from "../lib/trpc";
|
||||||
|
import { Todo } from "../db/models/todo.model";
|
||||||
|
|
||||||
|
export const todoRouter = router({
|
||||||
|
getAll: publicProcedure.query(async () => {
|
||||||
|
return await Todo.find().lean();
|
||||||
|
}),
|
||||||
|
|
||||||
|
create: publicProcedure
|
||||||
|
.input(z.object({ text: z.string().min(1) }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
const newTodo = await Todo.create({ text: input.text });
|
||||||
|
return newTodo.toObject();
|
||||||
|
}),
|
||||||
|
|
||||||
|
toggle: publicProcedure
|
||||||
|
.input(z.object({ id: z.string(), completed: z.boolean() }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await Todo.updateOne({ id: input.id }, { completed: input.completed });
|
||||||
|
return { success: true };
|
||||||
|
}),
|
||||||
|
|
||||||
|
delete: publicProcedure
|
||||||
|
.input(z.object({ id: z.string() }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await Todo.deleteOne({ id: input.id });
|
||||||
|
return { success: true };
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
{{/if}}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
const { Schema, model } = mongoose;
|
||||||
|
|
||||||
|
const todoSchema = new Schema({
|
||||||
|
id: {
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
auto: true,
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
collection: 'todo'
|
||||||
|
});
|
||||||
|
|
||||||
|
const Todo = model('Todo', todoSchema);
|
||||||
|
|
||||||
|
export { Todo };
|
||||||
4
apps/web/public/icon/mongoose.svg
Normal file
4
apps/web/public/icon/mongoose.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 5.4 KiB |
@@ -262,18 +262,39 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
} else if (nextStack.database === "mongodb") {
|
} else if (nextStack.database === "mongodb") {
|
||||||
if (nextStack.orm !== "prisma" && nextStack.orm !== "none") {
|
if (nextStack.orm !== "prisma" && nextStack.orm !== "mongoose") {
|
||||||
notes.database.notes.push(
|
notes.database.notes.push(
|
||||||
"MongoDB requires Prisma ORM. It will be selected.",
|
"MongoDB requires Prisma or Mongoose ORM. Prisma will be selected.",
|
||||||
);
|
|
||||||
notes.orm.notes.push(
|
|
||||||
"MongoDB requires Prisma ORM. It will be selected.",
|
|
||||||
);
|
);
|
||||||
|
notes.orm.notes.push("MongoDB requires Prisma or Mongoose ORM. Prisma will be selected.");
|
||||||
notes.database.hasIssue = true;
|
notes.database.hasIssue = true;
|
||||||
notes.orm.hasIssue = true;
|
notes.orm.hasIssue = true;
|
||||||
nextStack.orm = "prisma";
|
nextStack.orm = "prisma";
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (nextStack.orm === "mongoose") {
|
||||||
|
notes.database.notes.push(
|
||||||
|
"Relational databases are not compatible with Mongoose ORM",
|
||||||
|
);
|
||||||
|
notes.orm.notes.push("Relational databases are not compatible with Mongoose ORM");
|
||||||
|
notes.database.hasIssue = true;
|
||||||
|
notes.orm.hasIssue = true;
|
||||||
|
nextStack.orm = "prisma";
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (nextStack.dbSetup === "mongodb-atlas") {
|
||||||
|
notes.database.notes.push(
|
||||||
|
"Relational databases are not compatible with MongoDB Atlas setup. DB Setup will be reset.",
|
||||||
|
);
|
||||||
|
notes.dbSetup.notes.push(
|
||||||
|
"MongoDB Atlas setup requires MongoDB. It will be reset to 'Basic Setup'.",
|
||||||
|
);
|
||||||
|
notes.database.hasIssue = true;
|
||||||
|
notes.dbSetup.hasIssue = true;
|
||||||
|
nextStack.dbSetup = "none";
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextStack.dbSetup === "turso") {
|
if (nextStack.dbSetup === "turso") {
|
||||||
@@ -331,10 +352,10 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
|
|||||||
nextStack.database = "mongodb";
|
nextStack.database = "mongodb";
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (nextStack.orm !== "prisma") {
|
if (nextStack.orm !== "prisma" && nextStack.orm !== "mongoose") {
|
||||||
notes.dbSetup.notes.push("Requires Prisma ORM. It will be selected.");
|
notes.dbSetup.notes.push("Requires Prisma or Mongoose ORM. Prisma will be selected.");
|
||||||
notes.orm.notes.push(
|
notes.orm.notes.push(
|
||||||
"MongoDB Atlas setup requires Prisma ORM. It will be selected.",
|
"MongoDB Atlas setup requires Prisma or Mongoose ORM. Prisma will be selected.",
|
||||||
);
|
);
|
||||||
notes.dbSetup.hasIssue = true;
|
notes.dbSetup.hasIssue = true;
|
||||||
notes.orm.hasIssue = true;
|
notes.orm.hasIssue = true;
|
||||||
@@ -452,8 +473,6 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
|
|||||||
|
|
||||||
const uniqueIncompatibleExamples = [...new Set(incompatibleExamples)];
|
const uniqueIncompatibleExamples = [...new Set(incompatibleExamples)];
|
||||||
if (uniqueIncompatibleExamples.length > 0) {
|
if (uniqueIncompatibleExamples.length > 0) {
|
||||||
if (isNativeOnly) {
|
|
||||||
} else {
|
|
||||||
if (
|
if (
|
||||||
!isWeb &&
|
!isWeb &&
|
||||||
(uniqueIncompatibleExamples.includes("todo") ||
|
(uniqueIncompatibleExamples.includes("todo") ||
|
||||||
@@ -485,16 +504,15 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
|
|||||||
nextStack.backend === "elysia" &&
|
nextStack.backend === "elysia" &&
|
||||||
uniqueIncompatibleExamples.includes("ai")
|
uniqueIncompatibleExamples.includes("ai")
|
||||||
) {
|
) {
|
||||||
notes.backend.notes.push(
|
notes.backendFramework.notes.push(
|
||||||
"AI example is not compatible with Elysia. It will be removed.",
|
"AI example is not compatible with Elysia. It will be removed.",
|
||||||
);
|
);
|
||||||
notes.examples.notes.push(
|
notes.examples.notes.push(
|
||||||
"AI example is not compatible with Elysia. It will be removed.",
|
"AI example is not compatible with Elysia. It will be removed.",
|
||||||
);
|
);
|
||||||
notes.backend.hasIssue = true;
|
notes.backendFramework.hasIssue = true;
|
||||||
notes.examples.hasIssue = true;
|
notes.examples.hasIssue = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const originalExamplesLength = nextStack.examples.length;
|
const originalExamplesLength = nextStack.examples.length;
|
||||||
nextStack.examples = nextStack.examples.filter(
|
nextStack.examples = nextStack.examples.filter(
|
||||||
@@ -748,9 +766,10 @@ const StackArchitect = () => {
|
|||||||
if (
|
if (
|
||||||
currentStack.database === "mongodb" &&
|
currentStack.database === "mongodb" &&
|
||||||
techId !== "prisma" &&
|
techId !== "prisma" &&
|
||||||
|
techId !== "mongoose" &&
|
||||||
techId !== "none"
|
techId !== "none"
|
||||||
)
|
)
|
||||||
reason = "MongoDB requires the Prisma ORM.";
|
reason = "MongoDB requires the Prisma or Mongoose ORM.";
|
||||||
if (
|
if (
|
||||||
currentStack.dbSetup === "turso" &&
|
currentStack.dbSetup === "turso" &&
|
||||||
techId !== "drizzle" &&
|
techId !== "drizzle" &&
|
||||||
@@ -766,21 +785,23 @@ const StackArchitect = () => {
|
|||||||
if (
|
if (
|
||||||
currentStack.dbSetup === "mongodb-atlas" &&
|
currentStack.dbSetup === "mongodb-atlas" &&
|
||||||
techId !== "prisma" &&
|
techId !== "prisma" &&
|
||||||
|
techId !== "mongoose" &&
|
||||||
techId !== "none"
|
techId !== "none"
|
||||||
)
|
)
|
||||||
reason = "MongoDB Atlas setup requires Prisma ORM.";
|
reason = "MongoDB Atlas setup requires Prisma or Mongoose ORM.";
|
||||||
|
|
||||||
if (techId === "none") {
|
if (techId === "none") {
|
||||||
if (currentStack.database === "mongodb")
|
if (currentStack.database === "mongodb")
|
||||||
reason = "MongoDB requires Prisma ORM.";
|
reason = "MongoDB requires Prisma or Mongoose ORM.";
|
||||||
if (currentStack.dbSetup === "turso")
|
if (currentStack.dbSetup === "turso")
|
||||||
reason = "Turso DB setup requires Drizzle ORM.";
|
reason = "Turso DB setup requires Drizzle ORM.";
|
||||||
if (
|
if (currentStack.dbSetup === "prisma-postgres")
|
||||||
currentStack.dbSetup === "prisma-postgres" ||
|
|
||||||
currentStack.dbSetup === "mongodb-atlas"
|
|
||||||
)
|
|
||||||
reason = "This DB setup requires Prisma ORM.";
|
reason = "This DB setup requires Prisma ORM.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (techId === "mongoose" && (currentStack.database !== "mongodb")) {
|
||||||
|
reason = "Mongoose ORM is not compatible with relational databases.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (catKey === "dbSetup" && techId !== "none") {
|
if (catKey === "dbSetup" && techId !== "none") {
|
||||||
@@ -809,8 +830,8 @@ const StackArchitect = () => {
|
|||||||
currentStack.database !== "none"
|
currentStack.database !== "none"
|
||||||
)
|
)
|
||||||
reason = "Requires MongoDB database.";
|
reason = "Requires MongoDB database.";
|
||||||
if (currentStack.orm !== "prisma" && currentStack.orm !== "none")
|
if (currentStack.orm !== "prisma" && currentStack.orm !== "mongoose" && currentStack.orm !== "none")
|
||||||
reason = "Requires Prisma ORM.";
|
reason = "Requires Prisma or Mongoose ORM.";
|
||||||
} else if (techId === "neon") {
|
} else if (techId === "neon") {
|
||||||
if (
|
if (
|
||||||
currentStack.database !== "postgres" &&
|
currentStack.database !== "postgres" &&
|
||||||
|
|||||||
@@ -192,6 +192,13 @@ export const TECH_OPTIONS = {
|
|||||||
icon: "/icon/prisma.svg",
|
icon: "/icon/prisma.svg",
|
||||||
color: "from-purple-400 to-purple-600",
|
color: "from-purple-400 to-purple-600",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "mongoose",
|
||||||
|
name: "Mongoose",
|
||||||
|
description: "Elegant object modeling tool",
|
||||||
|
icon: "/icon/mongoose.svg",
|
||||||
|
color: "from-blue-400 to-blue-600",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "none",
|
id: "none",
|
||||||
name: "No ORM",
|
name: "No ORM",
|
||||||
|
|||||||
Reference in New Issue
Block a user