Skip to content

Commit d72a427

Browse files
fix: support input transformers (#1043)
1 parent 7ae1ed9 commit d72a427

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

.changeset/large-flowers-allow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"uploadthing": patch
3+
---
4+
5+
fix: support input transformers

packages/react/test/client-generator.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ const router = {
3737
console.log(metadata);
3838
}),
3939

40+
withTransformedInput: f(["image"], { awaitServerData: false })
41+
.input(z.object({ bar: z.number().transform(String) }))
42+
.middleware((opts) => {
43+
expectTypeOf(opts.input.bar).toBeString();
44+
return { string: opts.input.bar };
45+
})
46+
.onUploadComplete(({ metadata }) => {
47+
console.log(metadata);
48+
}),
49+
4050
// Should technically block returning undefined but there was
4151
// so many issues with getting everything to work so we just
4252
// serialize it as null on the other end...... JSON sucks
@@ -100,6 +110,13 @@ it("infers the input correctly", () => {
100110
expectTypeOf<Input>().toEqualTypeOf<{ bar: number }>();
101111
void startUpload(files, { bar: 1 });
102112
});
113+
114+
doNotExecute(() => {
115+
const { startUpload } = useUploadThing("withTransformedInput");
116+
type Input = Parameters<typeof startUpload>[1];
117+
expectTypeOf<Input>().toEqualTypeOf<{ bar: number }>();
118+
void startUpload(files, { bar: 1 });
119+
});
103120
});
104121

105122
it("infers output properly", () => {

packages/uploadthing/src/internal/types.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ export type MiddlewareFnArgs<TRequest, TResponse, TEvent> = {
7070

7171
export interface AnyParams {
7272
_routeOptions: any;
73-
_input: any;
73+
_input: {
74+
in: any;
75+
out: any;
76+
};
7477
_metadata: any; // imaginary field used to bind metadata return type to an Upload resolver
7578
_middlewareArgs: MiddlewareFnArgs<any, any, any>;
7679
_errorShape: any;
@@ -101,12 +104,12 @@ type UploadErrorFn = (input: {
101104

102105
export interface UploadBuilder<TParams extends AnyParams> {
103106
input: <TParser extends JsonParser>(
104-
parser: TParams["_input"] extends UnsetMarker
107+
parser: TParams["_input"]["in"] extends UnsetMarker
105108
? TParser
106109
: ErrorMessage<"input is already set">,
107110
) => UploadBuilder<{
108111
_routeOptions: TParams["_routeOptions"];
109-
_input: TParser["_output"];
112+
_input: { in: TParser["_input"]; out: TParser["_output"] };
110113
_metadata: TParams["_metadata"];
111114
_middlewareArgs: TParams["_middlewareArgs"];
112115
_errorShape: TParams["_errorShape"];
@@ -115,7 +118,11 @@ export interface UploadBuilder<TParams extends AnyParams> {
115118
}>;
116119
middleware: <TOutput extends ValidMiddlewareObject>(
117120
fn: TParams["_metadata"] extends UnsetMarker
118-
? MiddlewareFn<TParams["_input"], TOutput, TParams["_middlewareArgs"]>
121+
? MiddlewareFn<
122+
TParams["_input"]["out"],
123+
TOutput,
124+
TParams["_middlewareArgs"]
125+
>
119126
: ErrorMessage<"middleware is already set">,
120127
) => UploadBuilder<{
121128
_routeOptions: TParams["_routeOptions"];
@@ -156,8 +163,12 @@ export type UploadBuilderDef<TParams extends AnyParams> = {
156163
routerConfig: FileRouterInputConfig;
157164
routeOptions: RouteOptions;
158165
inputParser: JsonParser;
159-
// eslint-disable-next-line @typescript-eslint/ban-types
160-
middleware: MiddlewareFn<TParams["_input"], {}, TParams["_middlewareArgs"]>;
166+
middleware: MiddlewareFn<
167+
TParams["_input"]["out"],
168+
// eslint-disable-next-line @typescript-eslint/ban-types
169+
{},
170+
TParams["_middlewareArgs"]
171+
>;
161172
errorFormatter: (err: UploadThingError) => TParams["_errorShape"];
162173
onUploadError: UploadErrorFn;
163174
};
@@ -220,9 +231,9 @@ export type RouteHandlerOptions<TRouter extends FileRouter> = {
220231
};
221232

222233
export type inferEndpointInput<TUploader extends Uploader<any>> =
223-
TUploader["_def"]["_input"] extends UnsetMarker
234+
TUploader["_def"]["_input"]["in"] extends UnsetMarker
224235
? undefined
225-
: TUploader["_def"]["_input"];
236+
: TUploader["_def"]["_input"]["in"];
226237

227238
export type inferEndpointOutput<TUploader extends AnyUploader> =
228239
TUploader["_def"]["_output"] extends UnsetMarker | void | undefined

packages/uploadthing/src/internal/upload-builder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function internalCreateBuilder<
2323
initDef: Partial<UploadBuilderDef<any>> = {},
2424
): UploadBuilder<{
2525
_routeOptions: TRouteOptions;
26-
_input: UnsetMarker;
26+
_input: { in: UnsetMarker; out: UnsetMarker };
2727
_metadata: UnsetMarker;
2828
_middlewareArgs: TMiddlewareArgs;
2929
_errorShape: TErrorShape;
@@ -99,7 +99,7 @@ export function createBuilder<
9999
config?: TRouteOptions,
100100
): UploadBuilder<{
101101
_routeOptions: TRouteOptions;
102-
_input: UnsetMarker;
102+
_input: { in: UnsetMarker; out: UnsetMarker };
103103
_metadata: UnsetMarker;
104104
_middlewareArgs: TMiddlewareArgs;
105105
_errorShape: TErrorShape;

0 commit comments

Comments
 (0)