Skip to content

Commit 546a9e0

Browse files
committed
Fix type issues on calling defaultHandler
1 parent 941684c commit 546a9e0

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

src/oauth-provider.ts

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ExportedHandler, ExecutionContext } from '@cloudflare/workers-types';
1+
import { ExportedHandler, ExecutionContext } from '@cloudflare/workers-types';
22
import { WorkerEntrypoint } from 'cloudflare:workers';
33

44
// Types
@@ -11,6 +11,23 @@ enum HandlerType {
1111
WORKER_ENTRYPOINT
1212
}
1313

14+
/**
15+
* Discriminated union type for handlers
16+
*/
17+
type TypedHandler = {
18+
type: HandlerType.EXPORTED_HANDLER,
19+
handler: ExportedHandlerWithFetch
20+
} | {
21+
type: HandlerType.WORKER_ENTRYPOINT,
22+
handler: new (ctx: ExecutionContext, env: any) => WorkerEntrypointWithFetch
23+
};
24+
25+
/**
26+
* Aliases for either type of Handler that makes .fetch required
27+
*/
28+
type ExportedHandlerWithFetch = ExportedHandler & Pick<Required<ExportedHandler>, 'fetch'>
29+
type WorkerEntrypointWithFetch = WorkerEntrypoint & Pick<Required<WorkerEntrypoint>, 'fetch'>
30+
1431
/**
1532
* Configuration options for the OAuth Provider
1633
*/
@@ -27,13 +44,13 @@ export interface OAuthProviderOptions {
2744
* This handler will receive the authenticated user properties in ctx.props.
2845
* Can be either an ExportedHandler object with a fetch method or a class extending WorkerEntrypoint.
2946
*/
30-
apiHandler: ExportedHandler | (new (ctx: ExecutionContext, env: any) => WorkerEntrypoint);
47+
apiHandler: ExportedHandlerWithFetch | (new (ctx: ExecutionContext, env: any) => WorkerEntrypointWithFetch);
3148

3249
/**
3350
* Handler for all non-API requests or API requests without a valid token.
3451
* Can be either an ExportedHandler object with a fetch method or a class extending WorkerEntrypoint.
3552
*/
36-
defaultHandler: ExportedHandler | (new (ctx: ExecutionContext, env: any) => WorkerEntrypoint);
53+
defaultHandler: ExportedHandler | (new (ctx: ExecutionContext, env: any) => WorkerEntrypointWithFetch);
3754

3855
/**
3956
* URL of the OAuth authorization endpoint where users can grant permissions.
@@ -563,19 +580,19 @@ class OAuthProviderImpl {
563580
options: OAuthProviderOptions;
564581

565582
/**
566-
* Represents the type of a handler (ExportedHandler or WorkerEntrypoint)
583+
* Represents the validated type of a handler (ExportedHandler or WorkerEntrypoint)
567584
*/
568-
private apiHandlerType: HandlerType;
569-
private defaultHandlerType: HandlerType;
585+
private typedApiHandler: TypedHandler
586+
private typedDefaultHandler: TypedHandler
570587

571588
/**
572589
* Creates a new OAuth provider instance
573590
* @param options - Configuration options for the provider
574591
*/
575592
constructor(options: OAuthProviderOptions) {
576593
// Validate and determine handler types
577-
this.apiHandlerType = this.validateHandler(options.apiHandler, 'apiHandler');
578-
this.defaultHandlerType = this.validateHandler(options.defaultHandler, 'defaultHandler');
594+
this.typedApiHandler = this.validateHandler(options.apiHandler, 'apiHandler');
595+
this.typedDefaultHandler = this.validateHandler(options.defaultHandler, 'defaultHandler');
579596

580597
// Validate that the endpoints are either absolute paths or full URLs
581598
if (Array.isArray(options.apiRoute)) {
@@ -626,15 +643,15 @@ class OAuthProviderImpl {
626643
* @returns The type of the handler (EXPORTED_HANDLER or WORKER_ENTRYPOINT)
627644
* @throws TypeError if the handler is invalid
628645
*/
629-
private validateHandler(handler: any, name: string): HandlerType {
646+
private validateHandler(handler: any, name: string): TypedHandler {
630647
if (typeof handler === 'object' && handler !== null && typeof handler.fetch === 'function') {
631648
// It's an ExportedHandler object
632-
return HandlerType.EXPORTED_HANDLER;
649+
return { type:HandlerType.EXPORTED_HANDLER, handler }
633650
}
634651

635652
// Check if it's a class constructor extending WorkerEntrypoint
636653
if (typeof handler === 'function' && handler.prototype instanceof WorkerEntrypoint) {
637-
return HandlerType.WORKER_ENTRYPOINT;
654+
return { type: HandlerType.WORKER_ENTRYPOINT, handler }
638655
}
639656

640657
throw new TypeError(`${name} must be either an ExportedHandler object with a fetch method or a class extending WorkerEntrypoint`);
@@ -704,14 +721,12 @@ class OAuthProviderImpl {
704721

705722
// Call the default handler based on its type
706723
// Note: We don't add CORS headers to default handler responses
707-
if (this.defaultHandlerType === HandlerType.EXPORTED_HANDLER) {
724+
if (this.typedDefaultHandler.type === HandlerType.EXPORTED_HANDLER) {
708725
// It's an object with a fetch method
709-
// @ts-ignore
710-
return (this.options.defaultHandler! as ExportedHandler).fetch(request, env, ctx);
726+
return this.typedDefaultHandler.handler.fetch(request as Parameters<ExportedHandlerWithFetch['fetch']>[0], env, ctx);
711727
} else {
712728
// It's a WorkerEntrypoint class - instantiate it with ctx and env in that order
713-
const handler = new (this.options.defaultHandler as new (ctx: ExecutionContext, env: any) => WorkerEntrypoint)(ctx, env);
714-
// @ts-ignore
729+
const handler = new this.typedDefaultHandler.handler(ctx, env);
715730
return handler.fetch(request);
716731
}
717732
}
@@ -1614,14 +1629,12 @@ class OAuthProviderImpl {
16141629
}
16151630

16161631
// Call the API handler based on its type
1617-
if (this.apiHandlerType === HandlerType.EXPORTED_HANDLER) {
1632+
if (this.typedApiHandler.type === HandlerType.EXPORTED_HANDLER) {
16181633
// It's an object with a fetch method
1619-
// @ts-ignore
1620-
return (this.options.apiHandler as ExportedHandler).fetch(request, env, ctx);
1634+
return this.typedApiHandler.handler.fetch(request as Parameters<ExportedHandlerWithFetch['fetch']>[0], env, ctx);
16211635
} else {
16221636
// It's a WorkerEntrypoint class - instantiate it with ctx and env in that order
1623-
const handler = new (this.options.apiHandler as new (ctx: ExecutionContext, env: any) => WorkerEntrypoint)(ctx, env);
1624-
// @ts-ignore
1637+
const handler = new this.typedApiHandler.handler(ctx, env);
16251638
return handler.fetch(request);
16261639
}
16271640
}

0 commit comments

Comments
 (0)