deno-fresh-saurpc-lyrics/models.ts

82 lines
2 KiB
TypeScript

import { z } from 'zod'
// shared
export const Identifiable = z.object({
id: z.string().ulid(),
})
export type TIdentifiable = z.infer<typeof Identifiable>
export const Creatable = z.object({
createdAt: z.date(),
})
export type TCreatable = z.infer<typeof Creatable>
export const Updatable = z.object({
updatedAt: z.date(),
})
export type TUpdatable = z.infer<typeof Updatable>
// lyrics
export const Role = z.enum([
'admin', // full permissions
'editor', // edit songs, verses, displays, playlists, etc.
'viewer', // cannot change anything, but can view everything
])
export type TRole = z.infer<typeof Role>
export const Team = Identifiable.merge(Creatable).merge(z.object({
name: z.string(),
members: z.record(z.string().ulid(), z.set(Role)),
}))
export type TTeam = z.infer<typeof Team>
export const User = Identifiable.merge(Creatable).merge(z.object({
username: z.string(),
}))
export type TUser = z.infer<typeof User>
export const AuthUser = User.merge(z.object({
passwordDigest: z.string(),
}))
export type TAuthUser = z.infer<typeof AuthUser>
export function toUser({ passwordDigest: _, ...user }: TAuthUser): TUser {
return user
}
export const Verse = z.object({
content: z.string(),
})
export type TVerse = z.infer<typeof Verse>
export const Map = z.object({
verseKeys: z.array(z.string()),
})
export type TMap = z.infer<typeof Map>
export const Song = Identifiable.merge(z.object({
name: z.string(),
verses: z.record(z.string(), Verse),
maps: z.record(z.string(), Map),
}))
export type TSong = z.infer<typeof Song>
export const PlaylistEntry = z.object({
songId: z.string().ulid(),
mapKey: z.string(),
})
export type TPlaylistEntry = z.infer<typeof PlaylistEntry>
export const Playlist = Identifiable.merge(z.object({
name: z.string(),
entries: z.array(PlaylistEntry),
}))
export type TPlaylist = z.infer<typeof Playlist>
export const Display = Identifiable.merge(z.object({
name: z.string(),
playlistId: z.string().ulid(),
songIndex: z.number(),
}))
export type TDisplay = z.infer<typeof Display>