Skip to content

Commit

Permalink
forward adapter args to callbacks too
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusmarminge committed Nov 5, 2024
1 parent 8e1bcbd commit a77ebee
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 80 deletions.
4 changes: 2 additions & 2 deletions packages/uploadthing/src/effect-platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as Layer from "effect/Layer";
import type { Json } from "@uploadthing/shared";

import { configProvider } from "./internal/config";
import { createRequestHandler, MiddlewareArguments } from "./internal/handler";
import { AdapterArguments, createRequestHandler } from "./internal/handler";
import type { CreateBuilderOptions } from "./internal/upload-builder";
import { createBuilder } from "./internal/upload-builder";
import type { FileRouter, RouteHandlerConfig } from "./types";
Expand Down Expand Up @@ -52,7 +52,7 @@ export const createRouteHandler = <TRouter extends FileRouter>(opts: {

return HttpRouter.provideServiceEffect(
router,
MiddlewareArguments,
AdapterArguments,
Effect.map(HttpServerRequest.HttpServerRequest, (serverRequest) => ({
req: serverRequest,
res: undefined,
Expand Down
4 changes: 2 additions & 2 deletions packages/uploadthing/src/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ import type { FileRouter, RouteHandlerOptions } from "./types";
export { UTFiles } from "./internal/types";
export type { FileRouter };

type MiddlewareArgs = {
type AdapterArgs = {
req: ExpressRequest;
res: ExpressResponse;
event: undefined;
};

export const createUploadthing = <TErrorShape extends Json>(
opts?: CreateBuilderOptions<TErrorShape>,
) => createBuilder<MiddlewareArgs, TErrorShape>(opts);
) => createBuilder<AdapterArgs, TErrorShape>(opts);

export const createRouteHandler = <TRouter extends FileRouter>(
opts: RouteHandlerOptions<TRouter>,
Expand Down
4 changes: 2 additions & 2 deletions packages/uploadthing/src/fastify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import type { FileRouter, RouteHandlerOptions } from "./types";
export { UTFiles } from "./internal/types";
export type { FileRouter };

type MiddlewareArgs = {
type AdapterArgs = {
req: FastifyRequest;
res: FastifyReply;
event: undefined;
};

export const createUploadthing = <TErrorShape extends Json>(
opts?: CreateBuilderOptions<TErrorShape>,
) => createBuilder<MiddlewareArgs, TErrorShape>(opts);
) => createBuilder<AdapterArgs, TErrorShape>(opts);

export const createRouteHandler = <TRouter extends FileRouter>(
fastify: FastifyInstance,
Expand Down
4 changes: 2 additions & 2 deletions packages/uploadthing/src/h3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import type { FileRouter, RouteHandlerOptions } from "./types";
export { UTFiles } from "./internal/types";
export type { FileRouter };

type MiddlewareArgs = { req: undefined; res: undefined; event: H3Event };
type AdapterArgs = { req: undefined; res: undefined; event: H3Event };

export const createUploadthing = <TErrorShape extends Json>(
opts?: CreateBuilderOptions<TErrorShape>,
) => createBuilder<MiddlewareArgs, TErrorShape>(opts);
) => createBuilder<AdapterArgs, TErrorShape>(opts);

export const createRouteHandler = <TRouter extends FileRouter>(
opts: RouteHandlerOptions<TRouter>,
Expand Down
57 changes: 29 additions & 28 deletions packages/uploadthing/src/internal/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
import * as Match from "effect/Match";
import * as Redacted from "effect/Redacted";
import * as S from "effect/Schema";
import * as Schema from "effect/Schema";

import {
fillInputRouteConfig,
Expand Down Expand Up @@ -45,16 +45,16 @@ import {
UploadThingHook,
} from "./shared-schemas";
import { UTFiles } from "./types";
import type { AnyFileRoute, MiddlewareFnArgs, UTEvents } from "./types";
import type { AdapterFnArgs, AnyFileRoute, UTEvents } from "./types";

export class MiddlewareArguments extends Context.Tag(
"uploadthing/MiddlewareArguments",
)<MiddlewareArguments, MiddlewareFnArgs<any, any, any>>() {}
export class AdapterArguments extends Context.Tag(
"uploadthing/AdapterArguments",
)<AdapterArguments, AdapterFnArgs<any, any, any>>() {}

export const makeAdapterHandler = <Args extends any[]>(
makeMiddlewareArgs: (
makeAdapterArgs: (
...args: Args
) => Effect.Effect<MiddlewareFnArgs<any, any, any>>,
) => Effect.Effect<AdapterFnArgs<any, any, any>>,
toRequest: (...args: Args) => Effect.Effect<Request>,
opts: RouteHandlerOptions<FileRouter>,
beAdapter: string,
Expand All @@ -72,10 +72,7 @@ export const makeAdapterHandler = <Args extends any[]>(
Effect.promise(() =>
managed.runPromise(createRequestHandler(opts, beAdapter)),
),
Effect.provideServiceEffect(
MiddlewareArguments,
makeMiddlewareArgs(...args),
),
Effect.provideServiceEffect(AdapterArguments, makeAdapterArgs(...args)),
);

return async (...args: Args) => {
Expand Down Expand Up @@ -121,13 +118,13 @@ export const createRequestHandler = <TRouter extends FileRouter>(
"x-uploadthing-package": fePackage,
"x-uploadthing-version": clientVersion,
} = yield* HttpServerRequest.schemaHeaders(
S.Struct({
"uploadthing-hook": UploadThingHook.pipe(S.optional),
"x-uploadthing-package": S.String.pipe(
S.optionalWith({ default: () => "unknown" }),
Schema.Struct({
"uploadthing-hook": UploadThingHook.pipe(Schema.optional),
"x-uploadthing-package": Schema.String.pipe(
Schema.optionalWith({ default: () => "unknown" }),
),
"x-uploadthing-version": S.String.pipe(
S.optionalWith({ default: () => pkgJson.version }),
"x-uploadthing-version": Schema.String.pipe(
Schema.optionalWith({ default: () => pkgJson.version }),
),
}),
);
Expand All @@ -140,9 +137,9 @@ export const createRequestHandler = <TRouter extends FileRouter>(
}

const { slug, actionType } = yield* HttpRouter.schemaParams(
S.Struct({
actionType: ActionType.pipe(S.optional),
slug: S.String,
Schema.Struct({
actionType: ActionType.pipe(Schema.optional),
slug: Schema.String,
}),
);

Expand Down Expand Up @@ -248,18 +245,20 @@ const handleErrorRequest = (opts: { uploadable: AnyFileRoute }) =>
}

const requestInput = yield* HttpServerRequest.schemaBodyJson(
S.Struct({
fileKey: S.String,
error: S.String,
Schema.Struct({
fileKey: Schema.String,
error: Schema.String,
}),
);
yield* Effect.logDebug("Handling error callback request with input:").pipe(
Effect.annotateLogs("json", requestInput),
);

const adapterArgs = yield* AdapterArguments;
const fiber = yield* Effect.tryPromise({
try: async () =>
uploadable.onUploadError({
...adapterArgs,
error: new UploadThingError({
code: "UPLOAD_FAILED",
message: `Upload failed for ${requestInput.fileKey}: ${requestInput.error}`,
Expand Down Expand Up @@ -312,10 +311,10 @@ const handleCallbackRequest = (opts: {
}

const requestInput = yield* HttpServerRequest.schemaBodyJson(
S.Struct({
status: S.String,
Schema.Struct({
status: Schema.String,
file: UploadedFileData,
metadata: S.Record({ key: S.String, value: S.Unknown }),
metadata: Schema.Record({ key: Schema.String, value: Schema.Unknown }),
}),
);
yield* Effect.logDebug("Handling callback request with input:").pipe(
Expand All @@ -326,10 +325,12 @@ const handleCallbackRequest = (opts: {
* Run `.onUploadComplete` as a daemon to prevent the
* request from UT to potentially timeout.
*/
const adapterArgs = yield* AdapterArguments;
const fiber = yield* Effect.gen(function* () {
const serverData = yield* Effect.tryPromise({
try: async () =>
uploadable.onUploadComplete({
...adapterArgs,
file: requestInput.file,
metadata: requestInput.metadata,
}) as Promise<unknown>,
Expand Down Expand Up @@ -384,7 +385,7 @@ const runRouteMiddleware = (opts: {
uploadable: AnyFileRoute;
}) =>
Effect.gen(function* () {
const middlewareArgs = yield* MiddlewareArguments;
const adapterArgs = yield* AdapterArguments;
const {
json: { files, input },
uploadable,
Expand All @@ -394,7 +395,7 @@ const runRouteMiddleware = (opts: {
const metadata = yield* Effect.tryPromise({
try: async () =>
uploadable.middleware({
...middlewareArgs,
...adapterArgs,
input,
files,
}),
Expand Down
49 changes: 29 additions & 20 deletions packages/uploadthing/src/internal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export type ValidMiddlewareObject = {
/**
* Different frameworks have different request and response types
*/
export type MiddlewareFnArgs<TRequest, TResponse, TEvent> = {
export type AdapterFnArgs<TRequest, TResponse, TEvent> = {
req: TRequest;
res: TResponse;
event: TEvent;
Expand All @@ -61,7 +61,7 @@ export interface AnyParams {
out: any;
};
_metadata: any; // imaginary field used to bind metadata return type to an Upload resolver
_middlewareArgs: MiddlewareFnArgs<any, any, any>;
_adapterFnArgs: AdapterFnArgs<any, any, any>;
_errorShape: any;
_errorFn: any; // used for onUploadError
_output: any;
Expand All @@ -70,23 +70,31 @@ export interface AnyParams {
type MiddlewareFn<
TInput extends Json | UnsetMarker,
TOutput extends ValidMiddlewareObject,
TArgs extends MiddlewareFnArgs<any, any, any>,
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> = (opts: {
metadata: TMetadata;
file: UploadedFileData;
}) => 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 = (input: {
error: UploadThingError;
fileKey: string;
}) => MaybePromise<void>;
type UploadErrorFn<TArgs extends AdapterFnArgs<any, any, any>> = (
input: TArgs & {
error: UploadThingError;
fileKey: string;
},
) => MaybePromise<void>;

export interface UploadBuilder<TParams extends AnyParams> {
input: <TParser extends JsonParser>(
Expand All @@ -97,7 +105,7 @@ export interface UploadBuilder<TParams extends AnyParams> {
_routeOptions: TParams["_routeOptions"];
_input: { in: TParser["_input"]; out: TParser["_output"] };
_metadata: TParams["_metadata"];
_middlewareArgs: TParams["_middlewareArgs"];
_adapterFnArgs: TParams["_adapterFnArgs"];
_errorShape: TParams["_errorShape"];
_errorFn: TParams["_errorFn"];
_output: UnsetMarker;
Expand All @@ -107,29 +115,29 @@ export interface UploadBuilder<TParams extends AnyParams> {
? MiddlewareFn<
TParams["_input"]["out"],
TOutput,
TParams["_middlewareArgs"]
TParams["_adapterFnArgs"]
>
: ErrorMessage<"middleware is already set">,
) => UploadBuilder<{
_routeOptions: TParams["_routeOptions"];
_input: TParams["_input"];
_metadata: TOutput;
_middlewareArgs: TParams["_middlewareArgs"];
_adapterFnArgs: TParams["_adapterFnArgs"];
_errorShape: TParams["_errorShape"];
_errorFn: TParams["_errorFn"];
_output: UnsetMarker;
}>;
onUploadError: (
fn: TParams["_errorFn"] extends UnsetMarker
? UploadErrorFn
? UploadErrorFn<TParams["_adapterFnArgs"]>
: ErrorMessage<"onUploadError is already set">,
) => UploadBuilder<{
_routeOptions: TParams["_routeOptions"];
_input: TParams["_input"];
_metadata: TParams["_metadata"];
_middlewareArgs: TParams["_middlewareArgs"];
_adapterFnArgs: TParams["_adapterFnArgs"];
_errorShape: TParams["_errorShape"];
_errorFn: UploadErrorFn;
_errorFn: UploadErrorFn<TParams["_adapterFnArgs"]>;
_output: UnsetMarker;
}>;
onUploadComplete: <TOutput extends JsonObject | void>(
Expand All @@ -139,7 +147,8 @@ export interface UploadBuilder<TParams extends AnyParams> {
? undefined
: Omit<TParams["_metadata"], typeof UTFiles>
>,
TOutput
TOutput,
TParams["_adapterFnArgs"]
>,
) => FileRoute<{
input: TParams["_input"]["in"] extends UnsetMarker
Expand All @@ -166,9 +175,9 @@ export interface FileRoute<TTypes extends AnyBuiltUploaderTypes> {
routeOptions: RouteOptions;
inputParser: JsonParser;
middleware: MiddlewareFn<any, ValidMiddlewareObject, any>;
onUploadError: UploadErrorFn;
onUploadError: UploadErrorFn<any>;
errorFormatter: (err: UploadThingError) => any;
onUploadComplete: UploadCompleteFn<any, any>;
onUploadComplete: UploadCompleteFn<any, any, any>;
}
export type AnyFileRoute = FileRoute<AnyBuiltUploaderTypes>;

Expand Down
12 changes: 6 additions & 6 deletions packages/uploadthing/src/internal/upload-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import type {

import { defaultErrorFormatter } from "./error-formatter";
import type {
AdapterFnArgs,
AnyBuiltUploaderTypes,
AnyFileRoute,
MiddlewareFnArgs,
UnsetMarker,
UploadBuilder,
} from "./types";

function internalCreateBuilder<
TMiddlewareArgs extends MiddlewareFnArgs<any, any, any>,
TAdapterFnArgs extends AdapterFnArgs<any, any, any>,
TRouteOptions extends RouteOptions,
TErrorShape extends Json = { message: string },
>(
Expand All @@ -24,7 +24,7 @@ function internalCreateBuilder<
_routeOptions: TRouteOptions;
_input: { in: UnsetMarker; out: UnsetMarker };
_metadata: UnsetMarker;
_middlewareArgs: TMiddlewareArgs;
_adapterFnArgs: TAdapterFnArgs;
_errorShape: TErrorShape;
_errorFn: UnsetMarker;
_output: UnsetMarker;
Expand Down Expand Up @@ -92,7 +92,7 @@ export type CreateBuilderOptions<TErrorShape extends Json> = {
};

export function createBuilder<
TMiddlewareArgs extends MiddlewareFnArgs<any, any, any>,
TAdapterFnArgs extends AdapterFnArgs<any, any, any>,
TErrorShape extends Json = { message: string },
>(opts?: CreateBuilderOptions<TErrorShape>) {
return <TRouteOptions extends RouteOptions>(
Expand All @@ -102,12 +102,12 @@ export function createBuilder<
_routeOptions: TRouteOptions;
_input: { in: UnsetMarker; out: UnsetMarker };
_metadata: UnsetMarker;
_middlewareArgs: TMiddlewareArgs;
_adapterFnArgs: TAdapterFnArgs;
_errorShape: TErrorShape;
_errorFn: UnsetMarker;
_output: UnsetMarker;
}> => {
return internalCreateBuilder<TMiddlewareArgs, TRouteOptions, TErrorShape>({
return internalCreateBuilder<TAdapterFnArgs, TRouteOptions, TErrorShape>({
routerConfig: input,
routeOptions: config ?? {},
...opts,
Expand Down
Loading

0 comments on commit a77ebee

Please sign in to comment.