perf: add prisma json type and zod schema

This commit is contained in:
moonrailgun 2023-11-30 00:43:55 +08:00
parent 89612eff5f
commit 78796af00b
20 changed files with 1703 additions and 70 deletions

View File

@ -82,6 +82,7 @@
"winston": "^3.11.0",
"yup": "^1.2.0",
"zod": "^3.22.2",
"zod-prisma": "^0.5.4",
"zustand": "^4.4.1"
},
"devDependencies": {
@ -112,6 +113,8 @@
"nodemon": "^2.0.22",
"postcss": "^8.4.29",
"prisma": "^5.4.2",
"prisma-json-types-generator": "^3.0.3",
"prisma-zod-generator": "^0.8.13",
"tailwindcss": "^3.3.3",
"tar": "^6.1.15",
"typescript": "^5.2.2",

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,15 @@ generator client {
provider = "prisma-client-js"
}
generator json {
provider = "prisma-json-types-generator"
}
generator zod {
provider = "zod-prisma"
modelSuffix = "ModelSchema"
}
model User {
id String @id @unique @default(cuid()) @db.VarChar(30)
username String @unique @db.VarChar(255)
@ -26,6 +35,7 @@ model Workspace {
id String @id @unique @default(cuid()) @db.VarChar(30)
name String @db.VarChar(100)
dashboardOrder String[]
/// [DashboardLayout]
dashboardLayout Json? @db.Json
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
@ -201,14 +211,16 @@ model TelemetrySession {
}
model TelemetryEvent {
id String @id() @default(cuid()) @db.VarChar(30)
sessionId String @db.Uuid
workspaceId String @db.VarChar(30)
eventName String? @db.VarChar(100)
urlOrigin String @db.VarChar(500)
urlPath String @db.VarChar(500)
payload Json? @db.Json // Other payload info get from query params, should be a object
createdAt DateTime @default(now()) @db.Timestamptz(6)
id String @id() @default(cuid()) @db.VarChar(30)
sessionId String @db.Uuid
workspaceId String @db.VarChar(30)
eventName String? @db.VarChar(100)
urlOrigin String @db.VarChar(500)
urlPath String @db.VarChar(500)
/// [CommonPayload]
payload Json? @db.Json // Other payload info get from query params, should be a object
createdAt DateTime @default(now()) @db.Timestamptz(6)
session TelemetrySession @relation(fields: [sessionId], references: [id], onUpdate: Cascade, onDelete: Cascade)
@ -223,6 +235,7 @@ model Notification {
workspaceId String @db.VarChar(30)
name String @db.VarChar(100)
type String @db.VarChar(100)
/// [CommonPayload]
payload Json @db.Json
createdAt DateTime @default(now()) @db.Timestamptz(6)
@ -243,6 +256,7 @@ model Monitor {
// TODO
// maxRetry Int @default(0) @db.Integer
// retryInterval Int @default(0) @db.Integer
/// [CommonPayload]
payload Json @db.Json
createdAt DateTime @default(now()) @db.Timestamptz(6)
@ -280,6 +294,7 @@ model MonitorData {
model MonitorStatus {
monitorId String @db.VarChar(30)
statusName String @db.VarChar(50)
/// [CommonPayload]
payload Json @db.Json
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)

15
prisma/zod/index.ts Normal file
View File

@ -0,0 +1,15 @@
export * from "./user"
export * from "./workspace"
export * from "./workspacesonusers"
export * from "./website"
export * from "./websitesession"
export * from "./websiteevent"
export * from "./websiteeventdata"
export * from "./websitesessiondata"
export * from "./telemetrysession"
export * from "./telemetryevent"
export * from "./notification"
export * from "./monitor"
export * from "./monitorevent"
export * from "./monitordata"
export * from "./monitorstatus"

45
prisma/zod/monitor.ts Normal file
View File

@ -0,0 +1,45 @@
import * as z from "zod"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteWebsite, RelatedWebsiteModelSchema, CompleteNotification, RelatedNotificationModelSchema, CompleteMonitorEvent, RelatedMonitorEventModelSchema, CompleteMonitorData, RelatedMonitorDataModelSchema, CompleteMonitorStatus, RelatedMonitorStatusModelSchema } from "./index"
// Helper schema for JSON fields
type Literal = boolean | number | string
type Json = Literal | { [key: string]: Json } | Json[]
const literalSchema = z.union([z.string(), z.number(), z.boolean()])
const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))
export const MonitorModelSchema = z.object({
id: z.string(),
workspaceId: z.string(),
name: z.string(),
type: z.string(),
active: z.boolean(),
interval: z.number().int(),
/**
* [CommonPayload]
*/
payload: jsonSchema,
createdAt: z.date(),
})
export interface CompleteMonitor extends z.infer<typeof MonitorModelSchema> {
workspace: CompleteWorkspace
websites: CompleteWebsite[]
notifications: CompleteNotification[]
events: CompleteMonitorEvent[]
datas: CompleteMonitorData[]
status: CompleteMonitorStatus[]
}
/**
* RelatedMonitorModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedMonitorModelSchema: z.ZodSchema<CompleteMonitor> = z.lazy(() => MonitorModelSchema.extend({
workspace: RelatedWorkspaceModelSchema,
websites: RelatedWebsiteModelSchema.array(),
notifications: RelatedNotificationModelSchema.array(),
events: RelatedMonitorEventModelSchema.array(),
datas: RelatedMonitorDataModelSchema.array(),
status: RelatedMonitorStatusModelSchema.array(),
}))

22
prisma/zod/monitordata.ts Normal file
View File

@ -0,0 +1,22 @@
import * as z from "zod"
import { CompleteMonitor, RelatedMonitorModelSchema } from "./index"
export const MonitorDataModelSchema = z.object({
id: z.string(),
monitorId: z.string(),
value: z.number().int(),
createdAt: z.date(),
})
export interface CompleteMonitorData extends z.infer<typeof MonitorDataModelSchema> {
monitor: CompleteMonitor
}
/**
* RelatedMonitorDataModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedMonitorDataModelSchema: z.ZodSchema<CompleteMonitorData> = z.lazy(() => MonitorDataModelSchema.extend({
monitor: RelatedMonitorModelSchema,
}))

View File

@ -0,0 +1,23 @@
import * as z from "zod"
import { CompleteMonitor, RelatedMonitorModelSchema } from "./index"
export const MonitorEventModelSchema = z.object({
id: z.string(),
message: z.string(),
monitorId: z.string(),
type: z.string(),
createdAt: z.date(),
})
export interface CompleteMonitorEvent extends z.infer<typeof MonitorEventModelSchema> {
monitor: CompleteMonitor
}
/**
* RelatedMonitorEventModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedMonitorEventModelSchema: z.ZodSchema<CompleteMonitorEvent> = z.lazy(() => MonitorEventModelSchema.extend({
monitor: RelatedMonitorModelSchema,
}))

View File

@ -0,0 +1,32 @@
import * as z from "zod"
import { CompleteMonitor, RelatedMonitorModelSchema } from "./index"
// Helper schema for JSON fields
type Literal = boolean | number | string
type Json = Literal | { [key: string]: Json } | Json[]
const literalSchema = z.union([z.string(), z.number(), z.boolean()])
const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))
export const MonitorStatusModelSchema = z.object({
monitorId: z.string(),
statusName: z.string(),
/**
* [CommonPayload]
*/
payload: jsonSchema,
createdAt: z.date(),
updatedAt: z.date(),
})
export interface CompleteMonitorStatus extends z.infer<typeof MonitorStatusModelSchema> {
monitor: CompleteMonitor
}
/**
* RelatedMonitorStatusModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedMonitorStatusModelSchema: z.ZodSchema<CompleteMonitorStatus> = z.lazy(() => MonitorStatusModelSchema.extend({
monitor: RelatedMonitorModelSchema,
}))

View File

@ -0,0 +1,35 @@
import * as z from "zod"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteMonitor, RelatedMonitorModelSchema } from "./index"
// Helper schema for JSON fields
type Literal = boolean | number | string
type Json = Literal | { [key: string]: Json } | Json[]
const literalSchema = z.union([z.string(), z.number(), z.boolean()])
const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))
export const NotificationModelSchema = z.object({
id: z.string(),
workspaceId: z.string(),
name: z.string(),
type: z.string(),
/**
* [CommonPayload]
*/
payload: jsonSchema,
createdAt: z.date(),
})
export interface CompleteNotification extends z.infer<typeof NotificationModelSchema> {
workspace: CompleteWorkspace
monitors: CompleteMonitor[]
}
/**
* RelatedNotificationModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedNotificationModelSchema: z.ZodSchema<CompleteNotification> = z.lazy(() => NotificationModelSchema.extend({
workspace: RelatedWorkspaceModelSchema,
monitors: RelatedMonitorModelSchema.array(),
}))

View File

@ -0,0 +1,35 @@
import * as z from "zod"
import { CompleteTelemetrySession, RelatedTelemetrySessionModelSchema } from "./index"
// Helper schema for JSON fields
type Literal = boolean | number | string
type Json = Literal | { [key: string]: Json } | Json[]
const literalSchema = z.union([z.string(), z.number(), z.boolean()])
const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))
export const TelemetryEventModelSchema = z.object({
id: z.string(),
sessionId: z.string(),
workspaceId: z.string(),
eventName: z.string().nullish(),
urlOrigin: z.string(),
urlPath: z.string(),
/**
* [CommonPayload]
*/
payload: jsonSchema,
createdAt: z.date(),
})
export interface CompleteTelemetryEvent extends z.infer<typeof TelemetryEventModelSchema> {
session: CompleteTelemetrySession
}
/**
* RelatedTelemetryEventModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedTelemetryEventModelSchema: z.ZodSchema<CompleteTelemetryEvent> = z.lazy(() => TelemetryEventModelSchema.extend({
session: RelatedTelemetrySessionModelSchema,
}))

View File

@ -0,0 +1,29 @@
import * as z from "zod"
import { CompleteTelemetryEvent, RelatedTelemetryEventModelSchema } from "./index"
export const TelemetrySessionModelSchema = z.object({
id: z.string(),
workspaceId: z.string(),
hostname: z.string().nullish(),
browser: z.string().nullish(),
os: z.string().nullish(),
ip: z.string().nullish(),
country: z.string().nullish(),
subdivision1: z.string().nullish(),
subdivision2: z.string().nullish(),
city: z.string().nullish(),
createdAt: z.date(),
})
export interface CompleteTelemetrySession extends z.infer<typeof TelemetrySessionModelSchema> {
telemetryEvent: CompleteTelemetryEvent[]
}
/**
* RelatedTelemetrySessionModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedTelemetrySessionModelSchema: z.ZodSchema<CompleteTelemetrySession> = z.lazy(() => TelemetrySessionModelSchema.extend({
telemetryEvent: RelatedTelemetryEventModelSchema.array(),
}))

28
prisma/zod/user.ts Normal file
View File

@ -0,0 +1,28 @@
import * as z from "zod"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteWorkspacesOnUsers, RelatedWorkspacesOnUsersModelSchema } from "./index"
export const UserModelSchema = z.object({
id: z.string(),
username: z.string(),
password: z.string(),
role: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
deletedAt: z.date().nullish(),
currentWorkspaceId: z.string(),
})
export interface CompleteUser extends z.infer<typeof UserModelSchema> {
currentWorkspace: CompleteWorkspace
workspaces: CompleteWorkspacesOnUsers[]
}
/**
* RelatedUserModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedUserModelSchema: z.ZodSchema<CompleteUser> = z.lazy(() => UserModelSchema.extend({
currentWorkspace: RelatedWorkspaceModelSchema,
workspaces: RelatedWorkspacesOnUsersModelSchema.array(),
}))

36
prisma/zod/website.ts Normal file
View File

@ -0,0 +1,36 @@
import * as z from "zod"
import { CompleteWorkspace, RelatedWorkspaceModelSchema, CompleteMonitor, RelatedMonitorModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema, CompleteWebsiteEventData, RelatedWebsiteEventDataModelSchema, CompleteWebsiteSessionData, RelatedWebsiteSessionDataModelSchema } from "./index"
export const WebsiteModelSchema = z.object({
id: z.string(),
workspaceId: z.string(),
name: z.string(),
domain: z.string().nullish(),
shareId: z.string().nullish(),
resetAt: z.date().nullish(),
monitorId: z.string().nullish(),
createdAt: z.date(),
updatedAt: z.date(),
deletedAt: z.date().nullish(),
})
export interface CompleteWebsite extends z.infer<typeof WebsiteModelSchema> {
workspace: CompleteWorkspace
monitor?: CompleteMonitor | null
sessions: CompleteWebsiteSession[]
eventData: CompleteWebsiteEventData[]
sessionData: CompleteWebsiteSessionData[]
}
/**
* RelatedWebsiteModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWebsiteModelSchema: z.ZodSchema<CompleteWebsite> = z.lazy(() => WebsiteModelSchema.extend({
workspace: RelatedWorkspaceModelSchema,
monitor: RelatedMonitorModelSchema.nullish(),
sessions: RelatedWebsiteSessionModelSchema.array(),
eventData: RelatedWebsiteEventDataModelSchema.array(),
sessionData: RelatedWebsiteSessionDataModelSchema.array(),
}))

View File

@ -0,0 +1,32 @@
import * as z from "zod"
import { CompleteWebsiteEventData, RelatedWebsiteEventDataModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema } from "./index"
export const WebsiteEventModelSchema = z.object({
id: z.string(),
websiteId: z.string(),
sessionId: z.string(),
urlPath: z.string(),
urlQuery: z.string().nullish(),
referrerPath: z.string().nullish(),
referrerQuery: z.string().nullish(),
referrerDomain: z.string().nullish(),
pageTitle: z.string().nullish(),
eventType: z.number().int(),
eventName: z.string().nullish(),
createdAt: z.date(),
})
export interface CompleteWebsiteEvent extends z.infer<typeof WebsiteEventModelSchema> {
eventData: CompleteWebsiteEventData[]
session: CompleteWebsiteSession
}
/**
* RelatedWebsiteEventModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWebsiteEventModelSchema: z.ZodSchema<CompleteWebsiteEvent> = z.lazy(() => WebsiteEventModelSchema.extend({
eventData: RelatedWebsiteEventDataModelSchema.array(),
session: RelatedWebsiteSessionModelSchema,
}))

View File

@ -0,0 +1,29 @@
import * as z from "zod"
import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteEvent, RelatedWebsiteEventModelSchema } from "./index"
export const WebsiteEventDataModelSchema = z.object({
id: z.string(),
websiteId: z.string(),
websiteEventId: z.string(),
eventKey: z.string(),
stringValue: z.string().nullish(),
numberValue: z.number().nullish(),
dateValue: z.date().nullish(),
dataType: z.number().int(),
createdAt: z.date(),
})
export interface CompleteWebsiteEventData extends z.infer<typeof WebsiteEventDataModelSchema> {
website: CompleteWebsite
websiteEvent: CompleteWebsiteEvent
}
/**
* RelatedWebsiteEventDataModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWebsiteEventDataModelSchema: z.ZodSchema<CompleteWebsiteEventData> = z.lazy(() => WebsiteEventDataModelSchema.extend({
website: RelatedWebsiteModelSchema,
websiteEvent: RelatedWebsiteEventModelSchema,
}))

View File

@ -0,0 +1,36 @@
import * as z from "zod"
import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteEvent, RelatedWebsiteEventModelSchema, CompleteWebsiteSessionData, RelatedWebsiteSessionDataModelSchema } from "./index"
export const WebsiteSessionModelSchema = z.object({
id: z.string(),
websiteId: z.string(),
hostname: z.string().nullish(),
browser: z.string().nullish(),
os: z.string().nullish(),
device: z.string().nullish(),
screen: z.string().nullish(),
language: z.string().nullish(),
ip: z.string().nullish(),
country: z.string().nullish(),
subdivision1: z.string().nullish(),
subdivision2: z.string().nullish(),
city: z.string().nullish(),
createdAt: z.date(),
})
export interface CompleteWebsiteSession extends z.infer<typeof WebsiteSessionModelSchema> {
website: CompleteWebsite
websiteEvent: CompleteWebsiteEvent[]
sessionData: CompleteWebsiteSessionData[]
}
/**
* RelatedWebsiteSessionModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWebsiteSessionModelSchema: z.ZodSchema<CompleteWebsiteSession> = z.lazy(() => WebsiteSessionModelSchema.extend({
website: RelatedWebsiteModelSchema,
websiteEvent: RelatedWebsiteEventModelSchema.array(),
sessionData: RelatedWebsiteSessionDataModelSchema.array(),
}))

View File

@ -0,0 +1,28 @@
import * as z from "zod"
import { CompleteWebsite, RelatedWebsiteModelSchema, CompleteWebsiteSession, RelatedWebsiteSessionModelSchema } from "./index"
export const WebsiteSessionDataModelSchema = z.object({
id: z.string(),
websiteId: z.string(),
sessionId: z.string(),
stringValue: z.string().nullish(),
numberValue: z.number().nullish(),
dateValue: z.date().nullish(),
dataType: z.number().int(),
createdAt: z.date(),
})
export interface CompleteWebsiteSessionData extends z.infer<typeof WebsiteSessionDataModelSchema> {
website: CompleteWebsite
session: CompleteWebsiteSession
}
/**
* RelatedWebsiteSessionDataModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWebsiteSessionDataModelSchema: z.ZodSchema<CompleteWebsiteSessionData> = z.lazy(() => WebsiteSessionDataModelSchema.extend({
website: RelatedWebsiteModelSchema,
session: RelatedWebsiteSessionModelSchema,
}))

41
prisma/zod/workspace.ts Normal file
View File

@ -0,0 +1,41 @@
import * as z from "zod"
import { CompleteWorkspacesOnUsers, RelatedWorkspacesOnUsersModelSchema, CompleteWebsite, RelatedWebsiteModelSchema, CompleteNotification, RelatedNotificationModelSchema, CompleteMonitor, RelatedMonitorModelSchema, CompleteUser, RelatedUserModelSchema } from "./index"
// Helper schema for JSON fields
type Literal = boolean | number | string
type Json = Literal | { [key: string]: Json } | Json[]
const literalSchema = z.union([z.string(), z.number(), z.boolean()])
const jsonSchema: z.ZodSchema<Json> = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]))
export const WorkspaceModelSchema = z.object({
id: z.string(),
name: z.string(),
dashboardOrder: z.string().array(),
/**
* [DashboardLayout]
*/
dashboardLayout: jsonSchema,
createdAt: z.date(),
updatedAt: z.date(),
})
export interface CompleteWorkspace extends z.infer<typeof WorkspaceModelSchema> {
users: CompleteWorkspacesOnUsers[]
websites: CompleteWebsite[]
notifications: CompleteNotification[]
monitors: CompleteMonitor[]
selectedUsers: CompleteUser[]
}
/**
* RelatedWorkspaceModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWorkspaceModelSchema: z.ZodSchema<CompleteWorkspace> = z.lazy(() => WorkspaceModelSchema.extend({
users: RelatedWorkspacesOnUsersModelSchema.array(),
websites: RelatedWebsiteModelSchema.array(),
notifications: RelatedNotificationModelSchema.array(),
monitors: RelatedMonitorModelSchema.array(),
selectedUsers: RelatedUserModelSchema.array(),
}))

View File

@ -0,0 +1,25 @@
import * as z from "zod"
import { CompleteUser, RelatedUserModelSchema, CompleteWorkspace, RelatedWorkspaceModelSchema } from "./index"
export const WorkspacesOnUsersModelSchema = z.object({
userId: z.string(),
workspaceId: z.string(),
role: z.string(),
createdAt: z.date(),
updatedAt: z.date(),
})
export interface CompleteWorkspacesOnUsers extends z.infer<typeof WorkspacesOnUsersModelSchema> {
user: CompleteUser
workspace: CompleteWorkspace
}
/**
* RelatedWorkspacesOnUsersModelSchema contains all relations on your model in addition to the scalars
*
* NOTE: Lazy required in case of potential circular dependencies within schema
*/
export const RelatedWorkspacesOnUsersModelSchema: z.ZodSchema<CompleteWorkspacesOnUsers> = z.lazy(() => WorkspacesOnUsersModelSchema.extend({
user: RelatedUserModelSchema,
workspace: RelatedWorkspaceModelSchema,
}))

View File

@ -1,3 +1,14 @@
export * from './server';
export * from './monitor';
export * from './utils';
export * as schemas from '../../prisma/zod/index';
declare global {
namespace PrismaJson {
type CommonPayload = Record<string, any>;
type DashboardLayout = {
layouts: Record<string, any[]>;
items: any[];
} | null;
}
}