import { relations, sql } from "drizzle-orm"; import { foreignKey, index, integer, sqliteTable, text, } from "drizzle-orm/sqlite-core"; import { createInsertSchema, createSelectSchema } from "drizzle-zod"; import { z } from "zod"; import { user } from "./user"; import { file } from "./file"; const defaultSettings: ProjectSettingsSchema = { css: { preprocessor: null, tailwindcss: false, }, js: { transpiler: null, packages: [], }, }; export const project = sqliteTable( "projects", { id: integer("id").primaryKey({ autoIncrement: true }), userId: integer("user_id") .notNull() .references(() => user.id), forkId: integer("fork_id"), slug: text("slug").notNull().unique(), title: text("title").notNull(), visibility: text("visibility", { enum: ["public", "private", "unlisted"], }).default("private"), settings: text("settings", { mode: "json" }) .$type>() .default(defaultSettings), createdAt: text("created_at") .notNull() .default(sql`CURRENT_TIMESTAMP`), deletedAt: text("deleted_at"), }, (table) => ({ forkIdFk: foreignKey({ columns: [table.forkId], foreignColumns: [table.id], name: "project_fork_id_fk", }), visibilityEnum: index("project_visibility_idx").on(table.visibility), }) ); export const projectRelations = relations(project, ({ one, many }) => ({ files: many(file), fork: one(project, { fields: [project.forkId], references: [project.id], }), user: one(user, { fields: [project.userId], references: [user.id], }), })); export const projectSettingsSchema = z.object({ css: z.object({ preprocessor: z.enum(["", "postcss"]).optional().nullable(), tailwindcss: z.boolean().optional().nullable(), }), js: z.object({ transpiler: z.enum(["", "swc"]).optional().nullable(), packages: z .object({ name: z.string().min(1), url: z.string().min(1).url() }) .array(), }), }); export type ProjectSettingsSchema = z.infer; export const insertProjectSchema = createInsertSchema(project, { settings: projectSettingsSchema, }); export const selectProjectSchema = createSelectSchema(project, { settings: projectSettingsSchema.partial(), }); export type ProjectSchema = z.infer;