156 lines
4.9 KiB
TypeScript
156 lines
4.9 KiB
TypeScript
import * as v from "valibot";
|
|
|
|
export const fileSchema = v.object({
|
|
id: v.string(),
|
|
filename: v.string(),
|
|
originalName: v.string(),
|
|
mimeType: v.string(),
|
|
size: v.pipe(v.number(), v.integer()),
|
|
hash: v.string(),
|
|
bucketName: v.string(),
|
|
objectKey: v.string(),
|
|
r2Url: v.string(),
|
|
visibility: v.string(),
|
|
userId: v.string(),
|
|
metadata: v.optional(v.record(v.string(), v.any())),
|
|
tags: v.optional(v.array(v.string())),
|
|
status: v.string(),
|
|
processingError: v.optional(v.string()),
|
|
uploadedAt: v.date(),
|
|
lastAccessedAt: v.optional(v.date()),
|
|
expiresAt: v.optional(v.date()),
|
|
createdAt: v.date(),
|
|
updatedAt: v.date(),
|
|
});
|
|
|
|
export type File = v.InferOutput<typeof fileSchema>;
|
|
export type Files = File[];
|
|
|
|
export const fileUploadRequestSchema = v.object({
|
|
visibility: v.optional(v.string()),
|
|
metadata: v.optional(v.record(v.string(), v.any())),
|
|
tags: v.optional(v.array(v.string())),
|
|
processImage: v.optional(v.boolean()),
|
|
processDocument: v.optional(v.boolean()),
|
|
processVideo: v.optional(v.boolean()),
|
|
});
|
|
export type FileUploadRequest = v.InferOutput<typeof fileUploadRequestSchema>;
|
|
|
|
export const fileFiltersSchema = v.object({
|
|
userId: v.string(),
|
|
mimeType: v.optional(v.string()),
|
|
visibility: v.optional(v.string()),
|
|
status: v.optional(v.string()),
|
|
search: v.optional(v.string()),
|
|
tags: v.optional(v.array(v.string())),
|
|
});
|
|
export type FileFilters = v.InferOutput<typeof fileFiltersSchema>;
|
|
|
|
export const paginationOptionsSchema = v.object({
|
|
page: v.pipe(v.number(), v.integer()),
|
|
pageSize: v.pipe(v.number(), v.integer()),
|
|
sortBy: v.optional(v.string()),
|
|
sortOrder: v.optional(v.string()),
|
|
});
|
|
export type PaginationOptions = v.InferOutput<typeof paginationOptionsSchema>;
|
|
|
|
export const PaginatedFilesSchema = v.object({
|
|
data: v.array(fileSchema),
|
|
total: v.pipe(v.number(), v.integer()),
|
|
page: v.pipe(v.number(), v.integer()),
|
|
pageSize: v.pipe(v.number(), v.integer()),
|
|
totalPages: v.pipe(v.number(), v.integer()),
|
|
});
|
|
export type PaginatedFiles = v.InferOutput<typeof PaginatedFilesSchema>;
|
|
|
|
export const getFilesSchema = v.object({
|
|
filters: fileFiltersSchema,
|
|
pagination: paginationOptionsSchema,
|
|
});
|
|
export type GetFiles = v.InferOutput<typeof getFilesSchema>;
|
|
|
|
export const presignedUploadRequestSchema = v.object({
|
|
filename: v.string(),
|
|
mimeType: v.string(),
|
|
size: v.pipe(v.number(), v.integer()),
|
|
visibility: v.optional(v.string()),
|
|
});
|
|
export type PresignedUploadRequest = v.InferOutput<
|
|
typeof presignedUploadRequestSchema
|
|
>;
|
|
|
|
export const presignedUploadResponseSchema = v.object({
|
|
uploadUrl: v.string(),
|
|
downloadUrl: v.optional(v.string()),
|
|
expiresIn: v.pipe(v.number(), v.integer()),
|
|
fileId: v.string(),
|
|
objectKey: v.string(),
|
|
fields: v.optional(v.record(v.string(), v.any())),
|
|
});
|
|
export type PresignedUploadResponse = v.InferOutput<
|
|
typeof presignedUploadResponseSchema
|
|
>;
|
|
|
|
export const presignedFileAccessResponseSchema = v.object({
|
|
url: v.string(),
|
|
expiresIn: v.pipe(v.number(), v.integer()),
|
|
});
|
|
export type PresignedFileAccessResponse = v.InferOutput<
|
|
typeof presignedFileAccessResponseSchema
|
|
>;
|
|
|
|
export const fileUploadResultSchema = v.object({
|
|
success: v.boolean(),
|
|
file: v.optional(fileSchema),
|
|
uploadId: v.optional(v.string()),
|
|
error: v.optional(v.string()),
|
|
});
|
|
export type FileUploadResult = v.InferOutput<typeof fileUploadResultSchema>;
|
|
|
|
export const bulkFileIdsSchema = v.object({
|
|
fileIds: v.array(v.string()),
|
|
});
|
|
export type BulkFileIds = v.InferOutput<typeof bulkFileIdsSchema>;
|
|
|
|
export const fileUpdateRequestSchema = v.object({
|
|
filename: v.optional(v.string()),
|
|
visibility: v.optional(v.string()),
|
|
metadata: v.optional(v.record(v.string(), v.any())),
|
|
tags: v.optional(v.array(v.string())),
|
|
});
|
|
export type FileUpdateRequest = v.InferOutput<typeof fileUpdateRequestSchema>;
|
|
|
|
export const fileShareRequestSchema = v.object({
|
|
userId: v.string(),
|
|
permissions: v.object({
|
|
canRead: v.optional(v.boolean()),
|
|
canWrite: v.optional(v.boolean()),
|
|
canDelete: v.optional(v.boolean()),
|
|
canShare: v.optional(v.boolean()),
|
|
}),
|
|
expiresAt: v.optional(v.date()),
|
|
});
|
|
export type FileShareRequest = v.InferOutput<typeof fileShareRequestSchema>;
|
|
|
|
//
|
|
// Frontend specific models
|
|
//
|
|
export const clientFileFiltersSchema = v.object({
|
|
mimeType: v.optional(v.string()),
|
|
visibility: v.optional(v.string()),
|
|
status: v.optional(v.string()),
|
|
search: v.optional(v.string()),
|
|
tags: v.optional(v.array(v.string())),
|
|
});
|
|
export type ClientFileFilters = v.InferOutput<typeof clientFileFiltersSchema>;
|
|
|
|
export const clientPaginationOptionsSchema = v.object({
|
|
page: v.pipe(v.number(), v.integer()),
|
|
pageSize: v.pipe(v.number(), v.integer()),
|
|
sortBy: v.string(),
|
|
sortOrder: v.picklist(["asc", "desc"]),
|
|
});
|
|
export type ClientPaginationOptions = v.InferOutput<
|
|
typeof clientPaginationOptionsSchema
|
|
>;
|