Initial commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { number, string, z } from 'zod';
|
||||
import type { components } from './openapi/schema';
|
||||
import { arrayCoerce, commonQuerySchema, stringArrayCoerce, stringCoerce } from './common';
|
||||
|
||||
export type Book = components['schemas']['BookRead'];
|
||||
export type BookFile = components['schemas']['FileMetadataRead'];
|
||||
export type BookProgress = components['schemas']['BookProgressRead'];
|
||||
|
||||
export const bookQuerySchema = commonQuerySchema.extend({
|
||||
libraries: stringArrayCoerce,
|
||||
authors: stringArrayCoerce,
|
||||
publishers: stringArrayCoerce,
|
||||
tags: stringArrayCoerce,
|
||||
shelves: stringArrayCoerce,
|
||||
progress: arrayCoerce(z.enum(['unread', 'in_progress', 'read']))
|
||||
.nullable()
|
||||
.optional(),
|
||||
ids: stringArrayCoerce,
|
||||
cacheTimestamp: z.number().optional()
|
||||
});
|
||||
|
||||
const identifiersSchema = z
|
||||
.string()
|
||||
.transform((str, ctx) => {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch (e) {
|
||||
ctx.addIssue({
|
||||
code: 'custom',
|
||||
message: 'Must be a valid JSON string'
|
||||
});
|
||||
return z.NEVER;
|
||||
}
|
||||
})
|
||||
.pipe(
|
||||
z.record(z.string(), z.string()) // Key-value pairs, both strings
|
||||
);
|
||||
|
||||
export const editBookMetadataSchema = z.object({
|
||||
book_id: z.string(),
|
||||
title: string().min(1, 'Title cannot be empty'),
|
||||
subtitle: string().optional(),
|
||||
authors: z.array(z.string()).default([]),
|
||||
tags: z.array(z.string()).default([]),
|
||||
description: z.string().optional(),
|
||||
publisher: z.string().optional(),
|
||||
published_date: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((val) => (val ? new Date(val) : undefined)),
|
||||
series: z.string().optional(),
|
||||
series_position: z.string().optional(),
|
||||
identifiers: identifiersSchema,
|
||||
edition: z.number().optional(),
|
||||
pages: z.number().optional(),
|
||||
language: z.string().optional()
|
||||
});
|
||||
|
||||
export const bookCoverUpload = z.object({
|
||||
book_id: stringCoerce,
|
||||
file: z.file()
|
||||
});
|
||||
|
||||
export const booksUpload = z.object({
|
||||
library_id: stringCoerce,
|
||||
files: z.array(z.file()).min(1, 'At least one file must be uploaded')
|
||||
});
|
||||
|
||||
export const bookFilesUpload = z.object({
|
||||
book_id: stringCoerce,
|
||||
files: z.array(z.file()).min(1, 'At least one file must be uploaded')
|
||||
});
|
||||
|
||||
export const deleteBooksSchema = z.object({
|
||||
book_ids: stringArrayCoerce, // TODO Could also set minimum length of 1
|
||||
delete_files: z.boolean(),
|
||||
library_id: stringCoerce
|
||||
});
|
||||
|
||||
export const bookIdsSchema = z.object({
|
||||
book_ids: stringArrayCoerce // TODO Could also set minimum length of 1
|
||||
});
|
||||
|
||||
export const deleteBookFilesSchema = z.object({
|
||||
book_id: stringCoerce,
|
||||
file_ids: stringArrayCoerce,
|
||||
delete_files: z.boolean()
|
||||
});
|
||||
|
||||
export const updateBookProgressSchema = z.object({
|
||||
book_ids: stringArrayCoerce,
|
||||
progress: number().min(0).max(1),
|
||||
completed: z.boolean().optional().default(false),
|
||||
epub_loc: z.string().optional(),
|
||||
pdf_loc: z.string().optional()
|
||||
});
|
||||
|
||||
export type BookQuery = z.infer<typeof bookQuerySchema>;
|
||||
export type BookEditMetadata = z.infer<typeof editBookMetadataSchema>;
|
||||
export type DeleteBook = z.infer<typeof deleteBooksSchema>;
|
||||
export type BookIds = z.infer<typeof bookIdsSchema>;
|
||||
export type DeleteBookFiles = z.infer<typeof deleteBookFilesSchema>;
|
||||
export type UpdateBookProgress = z.infer<typeof updateBookProgressSchema>;
|
||||
Reference in New Issue
Block a user