1
- import type { ExportedHandler , ExecutionContext } from '@cloudflare/workers-types' ;
1
+ import { ExportedHandler , ExecutionContext } from '@cloudflare/workers-types' ;
2
2
import { WorkerEntrypoint } from 'cloudflare:workers' ;
3
3
4
4
// Types
@@ -11,6 +11,23 @@ enum HandlerType {
11
11
WORKER_ENTRYPOINT
12
12
}
13
13
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
+
14
31
/**
15
32
* Configuration options for the OAuth Provider
16
33
*/
@@ -27,13 +44,13 @@ export interface OAuthProviderOptions {
27
44
* This handler will receive the authenticated user properties in ctx.props.
28
45
* Can be either an ExportedHandler object with a fetch method or a class extending WorkerEntrypoint.
29
46
*/
30
- apiHandler : ExportedHandler | ( new ( ctx : ExecutionContext , env : any ) => WorkerEntrypoint ) ;
47
+ apiHandler : ExportedHandlerWithFetch | ( new ( ctx : ExecutionContext , env : any ) => WorkerEntrypointWithFetch ) ;
31
48
32
49
/**
33
50
* Handler for all non-API requests or API requests without a valid token.
34
51
* Can be either an ExportedHandler object with a fetch method or a class extending WorkerEntrypoint.
35
52
*/
36
- defaultHandler : ExportedHandler | ( new ( ctx : ExecutionContext , env : any ) => WorkerEntrypoint ) ;
53
+ defaultHandler : ExportedHandler | ( new ( ctx : ExecutionContext , env : any ) => WorkerEntrypointWithFetch ) ;
37
54
38
55
/**
39
56
* URL of the OAuth authorization endpoint where users can grant permissions.
@@ -563,19 +580,19 @@ class OAuthProviderImpl {
563
580
options : OAuthProviderOptions ;
564
581
565
582
/**
566
- * Represents the type of a handler (ExportedHandler or WorkerEntrypoint)
583
+ * Represents the validated type of a handler (ExportedHandler or WorkerEntrypoint)
567
584
*/
568
- private apiHandlerType : HandlerType ;
569
- private defaultHandlerType : HandlerType ;
585
+ private typedApiHandler : TypedHandler
586
+ private typedDefaultHandler : TypedHandler
570
587
571
588
/**
572
589
* Creates a new OAuth provider instance
573
590
* @param options - Configuration options for the provider
574
591
*/
575
592
constructor ( options : OAuthProviderOptions ) {
576
593
// 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' ) ;
579
596
580
597
// Validate that the endpoints are either absolute paths or full URLs
581
598
if ( Array . isArray ( options . apiRoute ) ) {
@@ -626,15 +643,15 @@ class OAuthProviderImpl {
626
643
* @returns The type of the handler (EXPORTED_HANDLER or WORKER_ENTRYPOINT)
627
644
* @throws TypeError if the handler is invalid
628
645
*/
629
- private validateHandler ( handler : any , name : string ) : HandlerType {
646
+ private validateHandler ( handler : any , name : string ) : TypedHandler {
630
647
if ( typeof handler === 'object' && handler !== null && typeof handler . fetch === 'function' ) {
631
648
// It's an ExportedHandler object
632
- return HandlerType . EXPORTED_HANDLER ;
649
+ return { type : HandlerType . EXPORTED_HANDLER , handler }
633
650
}
634
651
635
652
// Check if it's a class constructor extending WorkerEntrypoint
636
653
if ( typeof handler === 'function' && handler . prototype instanceof WorkerEntrypoint ) {
637
- return HandlerType . WORKER_ENTRYPOINT ;
654
+ return { type : HandlerType . WORKER_ENTRYPOINT , handler }
638
655
}
639
656
640
657
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 {
704
721
705
722
// Call the default handler based on its type
706
723
// 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 ) {
708
725
// 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 ) ;
711
727
} else {
712
728
// 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 ) ;
715
730
return handler . fetch ( request ) ;
716
731
}
717
732
}
@@ -1614,14 +1629,12 @@ class OAuthProviderImpl {
1614
1629
}
1615
1630
1616
1631
// Call the API handler based on its type
1617
- if ( this . apiHandlerType === HandlerType . EXPORTED_HANDLER ) {
1632
+ if ( this . typedApiHandler . type === HandlerType . EXPORTED_HANDLER ) {
1618
1633
// 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 ) ;
1621
1635
} else {
1622
1636
// 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 ) ;
1625
1638
return handler . fetch ( request ) ;
1626
1639
}
1627
1640
}
0 commit comments