/** * Canonical file schemas and types for SDK API inputs. * * These helpers model the file objects that Superblocks injects for FilePicker * inputs. Use the minimal file-ref contract when you want to pass files by * reference to storage integrations, and the readable file contract when your * API needs to call `readContentsAsync()` or `readContents()`. */ import { z } from "zod"; const readableAsyncMethodSchema = z.custom< (mode?: string) => Promise >((value) => typeof value === "function", { message: "Expected readContentsAsync to be a function", }); const readableSyncMethodSchema = z.custom<(mode?: string) => string | Buffer>( (value) => typeof value === "function", { message: "Expected readContents to be a function", }, ); /** * Minimal file reference contract. * * Good for by-reference uploads where the storage plugin resolves the file * bytes using `$superblocksId`, such as S3 or GCS `uploadMultipleObjects()`. */ export const fileRefSchema = z.object({ name: z.string(), type: z.string().optional(), $superblocksId: z.string(), }); /** * Runtime-readable file contract. * * Good for APIs that need to inspect file contents in code via * `readContentsAsync()` or `readContents()`. */ export const readableFileSchema = fileRefSchema .extend({ size: z.number().optional(), extension: z.string().optional(), previewUrl: z.string().optional(), readContentsAsync: readableAsyncMethodSchema, readContents: readableSyncMethodSchema, }) .passthrough(); export type FileRef = z.infer; export type ReadableFile = z.infer;