Openstatus www.openstatus.dev
at 4c0f4c00a38753a5d0dfd7e7b7b7706dec6f1503 80 lines 2.6 kB view raw
1import { createSelectSchema } from "drizzle-zod"; 2import { z } from "zod"; 3 4import { allPlans } from "../plan/config"; 5import { limitsSchema } from "../plan/schema"; 6import { workspacePlans, workspaceRole } from "./constants"; 7import { workspace } from "./workspace"; 8 9export const workspacePlanSchema = z.enum(workspacePlans); 10export const workspaceRoleSchema = z.enum(workspaceRole); 11 12/** 13 * Workspace schema with limits and plan 14 */ 15export const selectWorkspaceSchema = createSelectSchema(workspace) 16 .extend({ 17 limits: z.string().transform((val) => { 18 try { 19 const parsed = JSON.parse(val); 20 21 // Only validate properties that are actually present in the parsed object 22 // This avoids triggering .prefault() for missing properties 23 const validated: Record<string, unknown> = {}; 24 const limitsShape = limitsSchema.shape; 25 26 for (const key in parsed) { 27 if (key in limitsShape) { 28 // Validate only the properties that exist in the parsed object 29 const propertySchema = limitsShape[key as keyof typeof limitsShape]; 30 const result = propertySchema.safeParse(parsed[key]); 31 if (result.success) { 32 validated[key] = result.data; 33 } else { 34 console.warn(`Invalid value for limits.${key}:`, result.error); 35 // Skip invalid properties instead of failing entirely 36 } 37 } 38 // Unknown properties are ignored 39 } 40 41 return validated; 42 } catch (error) { 43 console.error("Error parsing limits:", error); 44 return {}; 45 } 46 }), 47 plan: z 48 .enum(workspacePlans) 49 .nullable() 50 .prefault("free") 51 .transform((val) => val ?? "free"), 52 // REMINDER: workspace usage 53 usage: z 54 .object({ 55 monitors: z.number().prefault(0), 56 notifications: z.number().prefault(0), 57 pages: z.number().prefault(0), 58 // checks: z.number().default(0), 59 }) 60 .nullish(), 61 }) 62 .transform((val) => { 63 return { 64 ...val, 65 limits: limitsSchema.parse({ 66 ...allPlans[val.plan].limits, 67 /** 68 * override the default plan limits 69 * allows us to set custom limits for a workspace 70 */ 71 ...val.limits, 72 }), 73 }; 74 }); 75 76export const insertWorkspaceSchema = createSelectSchema(workspace); 77 78export type Workspace = z.infer<typeof selectWorkspaceSchema>; 79export type WorkspacePlan = z.infer<typeof workspacePlanSchema>; 80export type WorkspaceRole = z.infer<typeof workspaceRoleSchema>;