UNPKG

uploadthing

Version:

Learn more: [docs.uploadthing.com](https://docs.uploadthing.com)

301 lines (296 loc) 10.2 kB
import * as S from 'effect/Schema'; import { Schema } from 'effect/Schema'; import { Json, ErrorMessage, JsonObject, Simplify, FileRouterInputConfig, RouteOptions, UploadThingError, MaybePromise } from '@uploadthing/shared'; import * as Standard from '@standard-schema/spec'; type ParseFn<TType> = (input: unknown) => Promise<TType>; type ParserZodEsque<TInput extends Json, TParsedInput> = { _input: TInput; _output: TParsedInput; parseAsync: ParseFn<TParsedInput>; }; type JsonParser<In extends Json, Out = In> = ParserZodEsque<In, Out> | Standard.v1.StandardSchema<In, Out> | S.Schema<Out, In>; declare const FileUploadData_base: S.Class<FileUploadData, { name: typeof S.String; size: typeof S.Number; type: typeof S.String; lastModified: S.optional<typeof S.Number>; }, S.Struct.Encoded<{ name: typeof S.String; size: typeof S.Number; type: typeof S.String; lastModified: S.optional<typeof S.Number>; }>, never, { readonly name: string; } & { readonly size: number; } & { readonly type: string; } & { readonly lastModified?: number | undefined; }, {}, {}>; /** * ============================================================================= * ======================== File Type Hierarchy =============================== * ============================================================================= */ /** * Properties from the web File object, this is what the client sends when initiating an upload */ declare class FileUploadData extends FileUploadData_base { } declare const FileUploadDataWithCustomId_base: S.Class<FileUploadDataWithCustomId, { name: typeof S.String; size: typeof S.Number; type: typeof S.String; lastModified: S.optional<typeof S.Number>; } & { customId: S.NullOr<typeof S.String>; }, { readonly name: string; readonly size: number; readonly type: string; } & { readonly lastModified?: number | undefined; } & { readonly customId: string | null; } & {}, never, { readonly name: string; } & { readonly size: number; } & { readonly type: string; } & { readonly lastModified?: number | undefined; } & { readonly customId: string | null; }, FileUploadData, {}>; /** * `.middleware()` can add a customId to the incoming file data */ declare class FileUploadDataWithCustomId extends FileUploadDataWithCustomId_base { } declare const UploadedFileData_base: S.Class<UploadedFileData, { name: typeof S.String; size: typeof S.Number; type: typeof S.String; lastModified: S.optional<typeof S.Number>; } & { customId: S.NullOr<typeof S.String>; } & { key: typeof S.String; url: typeof S.String; appUrl: typeof S.String; fileHash: typeof S.String; }, { readonly name: string; readonly size: number; readonly type: string; } & { readonly lastModified?: number | undefined; } & { readonly customId: string | null; } & {} & { readonly key: string; readonly url: string; readonly appUrl: string; readonly fileHash: string; } & {}, never, { readonly name: string; } & { readonly size: number; } & { readonly type: string; } & { readonly lastModified?: number | undefined; } & { readonly customId: string | null; } & { readonly key: string; } & { readonly url: string; } & { readonly appUrl: string; } & { readonly fileHash: string; }, FileUploadDataWithCustomId, {}>; /** * When files are uploaded, we get back * - a key * - a direct URL for the file * - an app-specific URL for the file (useful for scoping eg. for optimization allowed origins) * - the hash (md5-hex) of the uploaded file's contents */ declare class UploadedFileData extends UploadedFileData_base { } declare const NewPresignedUrl_base: S.Class<NewPresignedUrl, { url: typeof S.String; key: typeof S.String; customId: S.NullOr<typeof S.String>; name: typeof S.String; }, S.Struct.Encoded<{ url: typeof S.String; key: typeof S.String; customId: S.NullOr<typeof S.String>; name: typeof S.String; }>, never, { readonly name: string; } & { readonly customId: string | null; } & { readonly key: string; } & { readonly url: string; }, {}, {}>; /** * ============================================================================= * ======================== Server Response Schemas ============================ * ============================================================================= */ declare class NewPresignedUrl extends NewPresignedUrl_base { } declare const UploadActionPayload_base: S.Class<UploadActionPayload, { files: S.Array$<typeof FileUploadData>; input: S.Schema<Json>; }, S.Struct.Encoded<{ files: S.Array$<typeof FileUploadData>; input: S.Schema<Json>; }>, never, { readonly files: readonly FileUploadData[]; } & { readonly input: Json; }, {}, {}>; /** * ============================================================================= * ======================== Client Action Payloads ============================ * ============================================================================= */ declare class UploadActionPayload extends UploadActionPayload_base { } /** * Marker used to append a `customId` to the incoming file data in `.middleware()` * @example * ```ts * .middleware((opts) => { * return { * [UTFiles]: opts.files.map((file) => ({ * ...file, * customId: generateId(), * })) * }; * }) * ``` */ declare const UTFiles: unique symbol; declare const unsetMarker: "unsetMarker" & { __brand: "unsetMarker"; }; type UnsetMarker = typeof unsetMarker; type ValidMiddlewareObject = { [UTFiles]?: Partial<FileUploadDataWithCustomId>[]; [key: string]: unknown; }; /** * Different frameworks have different request and response types */ type AdapterFnArgs<TRequest, TResponse, TEvent> = { req: TRequest; res: TResponse; event: TEvent; }; interface AnyParams { _routeOptions: any; _input: { in: any; out: any; }; _metadata: any; _adapterFnArgs: AdapterFnArgs<any, any, any>; _errorShape: any; _errorFn: any; _output: any; } type MiddlewareFn<TInput extends Json | UnsetMarker, TOutput extends ValidMiddlewareObject, TArgs extends AdapterFnArgs<any, any, any>> = (opts: TArgs & { files: Schema.Type<typeof UploadActionPayload>["files"]; input: TInput extends UnsetMarker ? undefined : TInput; }) => MaybePromise<TOutput>; type UploadCompleteFn<TMetadata, TOutput extends JsonObject | void, TArgs extends AdapterFnArgs<any, any, any>> = (opts: TArgs & { metadata: TMetadata; file: UploadedFileData; }) => MaybePromise<TOutput>; type UploadErrorFn<TArgs extends AdapterFnArgs<any, any, any>> = (input: TArgs & { error: UploadThingError; fileKey: string; }) => MaybePromise<void>; interface UploadBuilder<TParams extends AnyParams> { input: <TIn extends Json, TOut>(parser: TParams["_input"]["in"] extends UnsetMarker ? JsonParser<TIn, TOut> : ErrorMessage<"input is already set">) => UploadBuilder<{ _routeOptions: TParams["_routeOptions"]; _input: { in: TIn; out: TOut; }; _metadata: TParams["_metadata"]; _adapterFnArgs: TParams["_adapterFnArgs"]; _errorShape: TParams["_errorShape"]; _errorFn: TParams["_errorFn"]; _output: UnsetMarker; }>; middleware: <TOutput extends ValidMiddlewareObject>(fn: TParams["_metadata"] extends UnsetMarker ? MiddlewareFn<TParams["_input"]["out"], TOutput, TParams["_adapterFnArgs"]> : ErrorMessage<"middleware is already set">) => UploadBuilder<{ _routeOptions: TParams["_routeOptions"]; _input: TParams["_input"]; _metadata: TOutput; _adapterFnArgs: TParams["_adapterFnArgs"]; _errorShape: TParams["_errorShape"]; _errorFn: TParams["_errorFn"]; _output: UnsetMarker; }>; onUploadError: (fn: TParams["_errorFn"] extends UnsetMarker ? UploadErrorFn<TParams["_adapterFnArgs"]> : ErrorMessage<"onUploadError is already set">) => UploadBuilder<{ _routeOptions: TParams["_routeOptions"]; _input: TParams["_input"]; _metadata: TParams["_metadata"]; _adapterFnArgs: TParams["_adapterFnArgs"]; _errorShape: TParams["_errorShape"]; _errorFn: UploadErrorFn<TParams["_adapterFnArgs"]>; _output: UnsetMarker; }>; onUploadComplete: <TOutput extends JsonObject | void>(fn: UploadCompleteFn<Simplify<TParams["_metadata"] extends UnsetMarker ? undefined : Omit<TParams["_metadata"], typeof UTFiles>>, TOutput, TParams["_adapterFnArgs"]>) => FileRoute<{ input: TParams["_input"]["in"] extends UnsetMarker ? undefined : TParams["_input"]["in"]; output: TParams["_routeOptions"]["awaitServerData"] extends false ? null : TOutput extends void | undefined ? null : TOutput; errorShape: TParams["_errorShape"]; }>; } type AnyBuiltUploaderTypes = { input: any; output: any; errorShape: any; }; interface FileRoute<TTypes extends AnyBuiltUploaderTypes> { $types: TTypes; routerConfig: FileRouterInputConfig; routeOptions: RouteOptions; inputParser: JsonParser<any>; middleware: MiddlewareFn<any, ValidMiddlewareObject, any>; onUploadError: UploadErrorFn<any>; errorFormatter: (err: UploadThingError) => any; onUploadComplete: UploadCompleteFn<any, any, any>; } type AnyFileRoute = FileRoute<AnyBuiltUploaderTypes>; /** * Map actionType to the required payload for that action * @todo Look into using @effect/rpc :thinking: */ type UTEvents = { upload: { in: UploadActionPayload; out: ReadonlyArray<NewPresignedUrl>; }; }; /** * Result from the PUT request to the UploadThing Ingest server */ type UploadPutResult<TServerOutput = unknown> = { url: string; appUrl: string; fileHash: string; serverData: TServerOutput; }; export { type AdapterFnArgs, type AnyBuiltUploaderTypes, type AnyFileRoute, type AnyParams, type FileRoute, type UTEvents, UTFiles, type UnsetMarker, type UploadBuilder, type UploadPutResult, type ValidMiddlewareObject };