@eldrin-project/eldrin-app-core 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +413 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +585 -2
- package/dist/index.d.ts +585 -2
- package/dist/index.js +399 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -56,20 +56,94 @@ interface MigrationOptions {
|
|
|
56
56
|
/** Callback for logging */
|
|
57
57
|
onLog?: (message: string, level: 'info' | 'warn' | 'error') => void;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Permission declaration in app manifest
|
|
61
|
+
*/
|
|
62
|
+
interface ManifestPermission {
|
|
63
|
+
/** Resource name (e.g., "invoices", "customers") */
|
|
64
|
+
resource: string;
|
|
65
|
+
/** Allowed actions on this resource */
|
|
66
|
+
actions: string[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Group/role declaration in app manifest
|
|
70
|
+
*/
|
|
71
|
+
interface ManifestGroup {
|
|
72
|
+
/** Group identifier (e.g., "admin", "viewer") */
|
|
73
|
+
id: string;
|
|
74
|
+
/** Display name for the group */
|
|
75
|
+
name: string;
|
|
76
|
+
/** Optional description */
|
|
77
|
+
description?: string;
|
|
78
|
+
/** Permissions granted to this group (e.g., ["invoices:read", "invoices:*"]) */
|
|
79
|
+
permissions: string[];
|
|
80
|
+
}
|
|
59
81
|
/**
|
|
60
82
|
* App configuration from eldrin-app.manifest.json
|
|
61
83
|
*/
|
|
62
84
|
interface AppManifest {
|
|
85
|
+
/** App identifier (unique within developer namespace) */
|
|
63
86
|
name: string;
|
|
87
|
+
/** App version (semver) */
|
|
64
88
|
version: string;
|
|
89
|
+
/** Developer ID (namespace owner) */
|
|
90
|
+
developerId?: string;
|
|
91
|
+
/** Display name shown in UI */
|
|
65
92
|
displayName?: string;
|
|
93
|
+
/** Short description */
|
|
66
94
|
description?: string;
|
|
67
|
-
|
|
95
|
+
/** Icon URL or path */
|
|
96
|
+
icon?: string;
|
|
97
|
+
/** Webhook hooks configuration */
|
|
68
98
|
hooks?: Record<string, string>;
|
|
99
|
+
/** Event system configuration */
|
|
69
100
|
events?: {
|
|
101
|
+
/** Event types this app emits */
|
|
70
102
|
emits?: string[];
|
|
103
|
+
/** Event types this app subscribes to */
|
|
71
104
|
subscribes?: string[];
|
|
72
105
|
};
|
|
106
|
+
/**
|
|
107
|
+
* Permission declarations for this app
|
|
108
|
+
*
|
|
109
|
+
* Defines the resources and actions that can be assigned to users.
|
|
110
|
+
* Full permission format: developer_id:app_id:resource:action
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```json
|
|
114
|
+
* {
|
|
115
|
+
* "permissions": [
|
|
116
|
+
* { "resource": "invoices", "actions": ["read", "write", "delete"] },
|
|
117
|
+
* { "resource": "customers", "actions": ["read", "write"] }
|
|
118
|
+
* ]
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
permissions?: ManifestPermission[];
|
|
123
|
+
/**
|
|
124
|
+
* Group/role definitions for this app
|
|
125
|
+
*
|
|
126
|
+
* Groups bundle permissions together for easier assignment.
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```json
|
|
130
|
+
* {
|
|
131
|
+
* "groups": [
|
|
132
|
+
* {
|
|
133
|
+
* "id": "admin",
|
|
134
|
+
* "name": "App Admin",
|
|
135
|
+
* "permissions": ["invoices:*", "customers:*"]
|
|
136
|
+
* },
|
|
137
|
+
* {
|
|
138
|
+
* "id": "viewer",
|
|
139
|
+
* "name": "Viewer",
|
|
140
|
+
* "permissions": ["invoices:read", "customers:read"]
|
|
141
|
+
* }
|
|
142
|
+
* ]
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
groups?: ManifestGroup[];
|
|
73
147
|
}
|
|
74
148
|
/**
|
|
75
149
|
* Options for createApp factory
|
|
@@ -482,4 +556,513 @@ declare function validateMigrationManifest(manifest: MigrationManifest, files: M
|
|
|
482
556
|
errors: string[];
|
|
483
557
|
}>;
|
|
484
558
|
|
|
485
|
-
|
|
559
|
+
/**
|
|
560
|
+
* Event System Types
|
|
561
|
+
* Types for server-side inter-app event communication
|
|
562
|
+
*/
|
|
563
|
+
/**
|
|
564
|
+
* Base event structure
|
|
565
|
+
*/
|
|
566
|
+
interface EldrinEvent<T = unknown> {
|
|
567
|
+
/** Unique event ID (UUID) */
|
|
568
|
+
id: string;
|
|
569
|
+
/** Event type identifier (e.g., "invoice.created") */
|
|
570
|
+
type: string;
|
|
571
|
+
/** App ID that emitted the event */
|
|
572
|
+
source: string;
|
|
573
|
+
/** Event payload data */
|
|
574
|
+
payload: T;
|
|
575
|
+
/** Payload schema version */
|
|
576
|
+
version: number;
|
|
577
|
+
/** Unix timestamp (ms) when event was created */
|
|
578
|
+
timestamp: number;
|
|
579
|
+
/** Optional idempotency key for deduplication */
|
|
580
|
+
idempotencyKey?: string;
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Options for emitting events
|
|
584
|
+
*/
|
|
585
|
+
interface EmitOptions {
|
|
586
|
+
/** Optional key to prevent duplicate events */
|
|
587
|
+
idempotencyKey?: string;
|
|
588
|
+
/** Payload schema version (default: 1) */
|
|
589
|
+
version?: number;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Result from emitting an event
|
|
593
|
+
*/
|
|
594
|
+
interface EmitResult {
|
|
595
|
+
/** ID of the created event */
|
|
596
|
+
eventId: string;
|
|
597
|
+
/** Event type */
|
|
598
|
+
type: string;
|
|
599
|
+
/** True if event was deduplicated (already existed) */
|
|
600
|
+
deduplicated?: boolean;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Event delivery record
|
|
604
|
+
*/
|
|
605
|
+
interface EventDelivery<T = unknown> {
|
|
606
|
+
/** Delivery record ID */
|
|
607
|
+
id: number;
|
|
608
|
+
/** The event being delivered */
|
|
609
|
+
event: EldrinEvent<T>;
|
|
610
|
+
/** Delivery status */
|
|
611
|
+
status: 'pending' | 'delivered' | 'failed';
|
|
612
|
+
/** Number of delivery attempts */
|
|
613
|
+
attempts: number;
|
|
614
|
+
/** Timestamp of last attempt */
|
|
615
|
+
lastAttemptAt?: number;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Result from polling events
|
|
619
|
+
*/
|
|
620
|
+
interface PollResult<T = unknown> {
|
|
621
|
+
/** List of pending event deliveries */
|
|
622
|
+
events: EventDelivery<T>[];
|
|
623
|
+
/** True if there are more events to fetch */
|
|
624
|
+
hasMore: boolean;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Options for polling events
|
|
628
|
+
*/
|
|
629
|
+
interface PollOptions {
|
|
630
|
+
/** Maximum number of events to fetch (default: 10, max: 100) */
|
|
631
|
+
limit?: number;
|
|
632
|
+
/** Only fetch events of these types */
|
|
633
|
+
types?: string[];
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Configuration for the event client
|
|
637
|
+
*/
|
|
638
|
+
interface EventClientConfig {
|
|
639
|
+
/** App ID for this client */
|
|
640
|
+
appId: string;
|
|
641
|
+
/** Base URL of the Eldrin Core worker */
|
|
642
|
+
coreApiUrl: string;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Event handler function type
|
|
646
|
+
*/
|
|
647
|
+
type EventHandler<T = unknown> = (event: EldrinEvent<T>) => Promise<void> | void;
|
|
648
|
+
/**
|
|
649
|
+
* Subscription info returned from the API
|
|
650
|
+
*/
|
|
651
|
+
interface SubscriptionInfo {
|
|
652
|
+
/** Subscription ID */
|
|
653
|
+
id: number;
|
|
654
|
+
/** Event pattern (e.g., "invoice.*") */
|
|
655
|
+
pattern: string;
|
|
656
|
+
/** Delivery mode */
|
|
657
|
+
deliveryMode: 'poll' | 'push';
|
|
658
|
+
/** Whether subscription is enabled */
|
|
659
|
+
enabled: boolean;
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Registered event type info
|
|
663
|
+
*/
|
|
664
|
+
interface RegisteredEventType {
|
|
665
|
+
/** Event type identifier */
|
|
666
|
+
type: string;
|
|
667
|
+
/** App that can emit this event */
|
|
668
|
+
sourceApp: string;
|
|
669
|
+
/** Human-readable description */
|
|
670
|
+
description?: string;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Eldrin Event Client
|
|
675
|
+
* SDK for app workers to emit and consume events
|
|
676
|
+
*/
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Client for interacting with the Eldrin event bus
|
|
680
|
+
*
|
|
681
|
+
* @example
|
|
682
|
+
* ```typescript
|
|
683
|
+
* const events = new EldrinEventClient({
|
|
684
|
+
* appId: 'invoicing',
|
|
685
|
+
* coreApiUrl: 'https://your-eldrin-core.workers.dev'
|
|
686
|
+
* });
|
|
687
|
+
*
|
|
688
|
+
* // Emit an event
|
|
689
|
+
* await events.emit('invoice.created', { invoiceId: 'inv_123', total: 1500 });
|
|
690
|
+
*
|
|
691
|
+
* // Poll for events
|
|
692
|
+
* const pending = await events.poll();
|
|
693
|
+
* for (const delivery of pending.events) {
|
|
694
|
+
* await processEvent(delivery.event);
|
|
695
|
+
* await events.ack(delivery.id);
|
|
696
|
+
* }
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
declare class EldrinEventClient {
|
|
700
|
+
private readonly appId;
|
|
701
|
+
private readonly coreApiUrl;
|
|
702
|
+
constructor(config: EventClientConfig);
|
|
703
|
+
/**
|
|
704
|
+
* Emit an event to the event bus
|
|
705
|
+
*
|
|
706
|
+
* @param type - Event type (must be declared in app's manifest emits)
|
|
707
|
+
* @param payload - Event payload data
|
|
708
|
+
* @param options - Optional emit configuration
|
|
709
|
+
* @returns Result containing the event ID
|
|
710
|
+
* @throws Error if app is not authorized to emit this event type
|
|
711
|
+
*/
|
|
712
|
+
emit<T>(type: string, payload: T, options?: EmitOptions): Promise<EmitResult>;
|
|
713
|
+
/**
|
|
714
|
+
* Poll for pending events
|
|
715
|
+
*
|
|
716
|
+
* @param options - Optional polling configuration
|
|
717
|
+
* @returns List of pending event deliveries
|
|
718
|
+
*/
|
|
719
|
+
poll<T = unknown>(options?: PollOptions): Promise<PollResult<T>>;
|
|
720
|
+
/**
|
|
721
|
+
* Acknowledge successful event processing
|
|
722
|
+
*
|
|
723
|
+
* @param deliveryId - The delivery record ID to acknowledge
|
|
724
|
+
*/
|
|
725
|
+
ack(deliveryId: number): Promise<void>;
|
|
726
|
+
/**
|
|
727
|
+
* Negative acknowledge - event will be retried later
|
|
728
|
+
*
|
|
729
|
+
* @param deliveryId - The delivery record ID
|
|
730
|
+
* @param error - Optional error message for logging
|
|
731
|
+
*/
|
|
732
|
+
nack(deliveryId: number, error?: string): Promise<void>;
|
|
733
|
+
/**
|
|
734
|
+
* Get all registered event types
|
|
735
|
+
*
|
|
736
|
+
* @returns List of all registered event types across all apps
|
|
737
|
+
*/
|
|
738
|
+
getEventTypes(): Promise<RegisteredEventType[]>;
|
|
739
|
+
/**
|
|
740
|
+
* Get subscriptions for this app
|
|
741
|
+
*
|
|
742
|
+
* @returns List of active subscriptions
|
|
743
|
+
*/
|
|
744
|
+
getSubscriptions(): Promise<SubscriptionInfo[]>;
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Environment bindings that may include Eldrin Core URL
|
|
748
|
+
*/
|
|
749
|
+
interface EldrinEnv {
|
|
750
|
+
ELDRIN_CORE_URL?: string;
|
|
751
|
+
[key: string]: unknown;
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Create an event client for use in app workers
|
|
755
|
+
*
|
|
756
|
+
* @param env - Worker environment bindings (must have optional ELDRIN_CORE_URL)
|
|
757
|
+
* @param appId - The app's identifier
|
|
758
|
+
* @returns Configured event client
|
|
759
|
+
*
|
|
760
|
+
* @example
|
|
761
|
+
* ```typescript
|
|
762
|
+
* export default {
|
|
763
|
+
* async fetch(request: Request, env: Env) {
|
|
764
|
+
* const events = createEventClient(env, 'invoicing');
|
|
765
|
+
* await events.emit('invoice.created', { invoiceId: 'inv_123' });
|
|
766
|
+
* }
|
|
767
|
+
* };
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
declare function createEventClient(env: EldrinEnv, appId: string): EldrinEventClient;
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Auth utilities for Eldrin apps
|
|
774
|
+
*
|
|
775
|
+
* Supports two authentication methods:
|
|
776
|
+
*
|
|
777
|
+
* 1. JWT Token (Authorization header):
|
|
778
|
+
* - Direct API calls with JWT token in Authorization: Bearer <token>
|
|
779
|
+
* - JWT is verified using shared secret (JWT_SECRET env var)
|
|
780
|
+
* - Permissions extracted from JWT payload
|
|
781
|
+
*
|
|
782
|
+
* 2. Proxy Headers (X-Eldrin-User-* headers):
|
|
783
|
+
* - Requests proxied through eldrin-core shell
|
|
784
|
+
* - Shell verifies JWT and injects user context headers
|
|
785
|
+
* - Legacy support for proxied requests
|
|
786
|
+
*
|
|
787
|
+
* JWT takes precedence if Authorization header is present.
|
|
788
|
+
*/
|
|
789
|
+
/**
|
|
790
|
+
* Auth context extracted from JWT or shell-injected headers
|
|
791
|
+
*/
|
|
792
|
+
interface AppAuthContext {
|
|
793
|
+
/** User ID */
|
|
794
|
+
userId: string;
|
|
795
|
+
/** User email */
|
|
796
|
+
email: string;
|
|
797
|
+
/** User display name */
|
|
798
|
+
name: string;
|
|
799
|
+
/** Platform roles (admin, editor, viewer) */
|
|
800
|
+
platformRoles: string[];
|
|
801
|
+
/** App-specific permissions (e.g., ["invoices:read", "invoices:write"]) */
|
|
802
|
+
permissions: string[];
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* JWT payload structure (matches eldrin-core JWT format)
|
|
806
|
+
*/
|
|
807
|
+
interface JWTPayload {
|
|
808
|
+
/** User ID */
|
|
809
|
+
sub: string;
|
|
810
|
+
/** Email */
|
|
811
|
+
email: string;
|
|
812
|
+
/** First name */
|
|
813
|
+
firstName: string;
|
|
814
|
+
/** Last name */
|
|
815
|
+
lastName: string;
|
|
816
|
+
/** Platform role names */
|
|
817
|
+
platformRoles: string[];
|
|
818
|
+
/** Platform permission names */
|
|
819
|
+
platformPermissions: string[];
|
|
820
|
+
/**
|
|
821
|
+
* App permissions in compact format
|
|
822
|
+
* Key: "developer_id:app_id", Value: ["resource:action", ...]
|
|
823
|
+
*/
|
|
824
|
+
appPermissions: Record<string, string[]>;
|
|
825
|
+
/** Issued at (timestamp) */
|
|
826
|
+
iat: number;
|
|
827
|
+
/** Expiration (timestamp) */
|
|
828
|
+
exp: number;
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Options for JWT verification
|
|
832
|
+
*/
|
|
833
|
+
interface JWTVerifyOptions {
|
|
834
|
+
/** JWT secret key (from env.JWT_SECRET) */
|
|
835
|
+
secret: string;
|
|
836
|
+
/** App ID for extracting app-specific permissions */
|
|
837
|
+
appId: string;
|
|
838
|
+
/** Developer ID (optional, uses wildcard matching if not provided) */
|
|
839
|
+
developerId?: string;
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Header names used by the shell for auth context injection
|
|
843
|
+
*/
|
|
844
|
+
declare const AUTH_HEADERS: {
|
|
845
|
+
readonly USER_ID: "x-eldrin-user-id";
|
|
846
|
+
readonly USER_EMAIL: "x-eldrin-user-email";
|
|
847
|
+
readonly USER_NAME: "x-eldrin-user-name";
|
|
848
|
+
readonly USER_ROLES: "x-eldrin-user-roles";
|
|
849
|
+
readonly USER_PERMISSIONS: "x-eldrin-user-permissions";
|
|
850
|
+
};
|
|
851
|
+
/**
|
|
852
|
+
* Verify JWT token and extract auth context
|
|
853
|
+
*
|
|
854
|
+
* @example
|
|
855
|
+
* ```typescript
|
|
856
|
+
* export default {
|
|
857
|
+
* async fetch(request: Request, env: Env) {
|
|
858
|
+
* const result = await verifyJWT(request, {
|
|
859
|
+
* secret: env.JWT_SECRET,
|
|
860
|
+
* appId: 'react-todo',
|
|
861
|
+
* });
|
|
862
|
+
*
|
|
863
|
+
* if (!result.success) {
|
|
864
|
+
* return new Response(JSON.stringify({ error: result.error }), {
|
|
865
|
+
* status: 401,
|
|
866
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
867
|
+
* });
|
|
868
|
+
* }
|
|
869
|
+
*
|
|
870
|
+
* // result.auth contains the AppAuthContext
|
|
871
|
+
* console.log('User:', result.auth.email);
|
|
872
|
+
* }
|
|
873
|
+
* }
|
|
874
|
+
* ```
|
|
875
|
+
*/
|
|
876
|
+
declare function verifyJWT(request: Request, options: JWTVerifyOptions): Promise<{
|
|
877
|
+
success: true;
|
|
878
|
+
auth: AppAuthContext;
|
|
879
|
+
} | {
|
|
880
|
+
success: false;
|
|
881
|
+
error: string;
|
|
882
|
+
}>;
|
|
883
|
+
/**
|
|
884
|
+
* Get auth context from JWT token or fall back to proxy headers
|
|
885
|
+
*
|
|
886
|
+
* This is the recommended way to get auth context as it supports both:
|
|
887
|
+
* - Direct API calls with JWT token
|
|
888
|
+
* - Proxied requests with shell-injected headers
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* ```typescript
|
|
892
|
+
* export default {
|
|
893
|
+
* async fetch(request: Request, env: Env) {
|
|
894
|
+
* const auth = await getAuthContextFromJWT(request, {
|
|
895
|
+
* secret: env.JWT_SECRET,
|
|
896
|
+
* appId: 'react-todo',
|
|
897
|
+
* });
|
|
898
|
+
*
|
|
899
|
+
* if (!auth) {
|
|
900
|
+
* return new Response('Unauthorized', { status: 401 });
|
|
901
|
+
* }
|
|
902
|
+
*
|
|
903
|
+
* console.log('User:', auth.email);
|
|
904
|
+
* }
|
|
905
|
+
* }
|
|
906
|
+
* ```
|
|
907
|
+
*/
|
|
908
|
+
declare function getAuthContextFromJWT(request: Request, options: JWTVerifyOptions): Promise<AppAuthContext | null>;
|
|
909
|
+
/**
|
|
910
|
+
* Require JWT authentication - returns auth context or error response
|
|
911
|
+
*
|
|
912
|
+
* @example
|
|
913
|
+
* ```typescript
|
|
914
|
+
* export default {
|
|
915
|
+
* async fetch(request: Request, env: Env) {
|
|
916
|
+
* const auth = await requireJWTAuth(request, {
|
|
917
|
+
* secret: env.JWT_SECRET,
|
|
918
|
+
* appId: 'react-todo',
|
|
919
|
+
* });
|
|
920
|
+
*
|
|
921
|
+
* if (auth instanceof Response) {
|
|
922
|
+
* return auth; // 401 Unauthorized
|
|
923
|
+
* }
|
|
924
|
+
*
|
|
925
|
+
* console.log('User:', auth.email);
|
|
926
|
+
* }
|
|
927
|
+
* }
|
|
928
|
+
* ```
|
|
929
|
+
*/
|
|
930
|
+
declare function requireJWTAuth(request: Request, options: JWTVerifyOptions): Promise<AppAuthContext | Response>;
|
|
931
|
+
/**
|
|
932
|
+
* Require JWT auth with specific permission - returns auth context or error response
|
|
933
|
+
*
|
|
934
|
+
* @example
|
|
935
|
+
* ```typescript
|
|
936
|
+
* export default {
|
|
937
|
+
* async fetch(request: Request, env: Env) {
|
|
938
|
+
* const auth = await requireJWTPermission(request, {
|
|
939
|
+
* secret: env.JWT_SECRET,
|
|
940
|
+
* appId: 'react-todo',
|
|
941
|
+
* }, 'categories', 'create');
|
|
942
|
+
*
|
|
943
|
+
* if (auth instanceof Response) {
|
|
944
|
+
* return auth; // 401 or 403
|
|
945
|
+
* }
|
|
946
|
+
*
|
|
947
|
+
* // User has categories:create permission
|
|
948
|
+
* }
|
|
949
|
+
* }
|
|
950
|
+
* ```
|
|
951
|
+
*/
|
|
952
|
+
declare function requireJWTPermission(request: Request, options: JWTVerifyOptions, resource: string, action: string): Promise<AppAuthContext | Response>;
|
|
953
|
+
/**
|
|
954
|
+
* Extract auth context from request headers (proxy mode)
|
|
955
|
+
*
|
|
956
|
+
* Returns null if the user is not authenticated (no user ID header).
|
|
957
|
+
*
|
|
958
|
+
* @example
|
|
959
|
+
* ```typescript
|
|
960
|
+
* export default {
|
|
961
|
+
* async fetch(request: Request) {
|
|
962
|
+
* const auth = getAuthContext(request);
|
|
963
|
+
* if (!auth) {
|
|
964
|
+
* return new Response('Unauthorized', { status: 401 });
|
|
965
|
+
* }
|
|
966
|
+
* console.log('User:', auth.email);
|
|
967
|
+
* }
|
|
968
|
+
* }
|
|
969
|
+
* ```
|
|
970
|
+
*/
|
|
971
|
+
declare function getAuthContext(request: Request): AppAuthContext | null;
|
|
972
|
+
/**
|
|
973
|
+
* Require authentication - returns auth context or error response
|
|
974
|
+
*
|
|
975
|
+
* @example
|
|
976
|
+
* ```typescript
|
|
977
|
+
* export default {
|
|
978
|
+
* async fetch(request: Request) {
|
|
979
|
+
* const auth = requireAuth(request);
|
|
980
|
+
* if (auth instanceof Response) {
|
|
981
|
+
* return auth; // 401 Unauthorized
|
|
982
|
+
* }
|
|
983
|
+
* // auth is AppAuthContext
|
|
984
|
+
* console.log('User:', auth.email);
|
|
985
|
+
* }
|
|
986
|
+
* }
|
|
987
|
+
* ```
|
|
988
|
+
*/
|
|
989
|
+
declare function requireAuth(request: Request): AppAuthContext | Response;
|
|
990
|
+
/**
|
|
991
|
+
* Check if auth context has a specific permission
|
|
992
|
+
*
|
|
993
|
+
* Supports wildcard matching:
|
|
994
|
+
* - "invoices:*" matches any action on invoices
|
|
995
|
+
* - "*:*" matches all permissions
|
|
996
|
+
*
|
|
997
|
+
* @example
|
|
998
|
+
* ```typescript
|
|
999
|
+
* const auth = getAuthContext(request);
|
|
1000
|
+
* if (auth && hasPermission(auth, 'invoices', 'write')) {
|
|
1001
|
+
* // User can write invoices
|
|
1002
|
+
* }
|
|
1003
|
+
* ```
|
|
1004
|
+
*/
|
|
1005
|
+
declare function hasPermission(auth: AppAuthContext, resource: string, action: string): boolean;
|
|
1006
|
+
/**
|
|
1007
|
+
* Check if auth context has a platform role
|
|
1008
|
+
*
|
|
1009
|
+
* @example
|
|
1010
|
+
* ```typescript
|
|
1011
|
+
* const auth = getAuthContext(request);
|
|
1012
|
+
* if (auth && hasPlatformRole(auth, 'admin')) {
|
|
1013
|
+
* // User is platform admin
|
|
1014
|
+
* }
|
|
1015
|
+
* ```
|
|
1016
|
+
*/
|
|
1017
|
+
declare function hasPlatformRole(auth: AppAuthContext, role: string): boolean;
|
|
1018
|
+
/**
|
|
1019
|
+
* Check if auth context is a platform admin
|
|
1020
|
+
*
|
|
1021
|
+
* Platform admins have full access to all apps and resources.
|
|
1022
|
+
*/
|
|
1023
|
+
declare function isPlatformAdmin(auth: AppAuthContext): boolean;
|
|
1024
|
+
/**
|
|
1025
|
+
* Require a specific permission - returns auth context or error response
|
|
1026
|
+
*
|
|
1027
|
+
* Also grants access if user is a platform admin.
|
|
1028
|
+
*
|
|
1029
|
+
* @example
|
|
1030
|
+
* ```typescript
|
|
1031
|
+
* export default {
|
|
1032
|
+
* async fetch(request: Request) {
|
|
1033
|
+
* const auth = requirePermission(request, 'invoices', 'write');
|
|
1034
|
+
* if (auth instanceof Response) {
|
|
1035
|
+
* return auth; // 401 or 403
|
|
1036
|
+
* }
|
|
1037
|
+
* // User has invoices:write permission
|
|
1038
|
+
* }
|
|
1039
|
+
* }
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
declare function requirePermission(request: Request, resource: string, action: string): AppAuthContext | Response;
|
|
1043
|
+
/**
|
|
1044
|
+
* Require any of the specified permissions - returns auth context or error response
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* ```typescript
|
|
1048
|
+
* const auth = requireAnyPermission(request, [
|
|
1049
|
+
* ['invoices', 'read'],
|
|
1050
|
+
* ['invoices', 'write'],
|
|
1051
|
+
* ]);
|
|
1052
|
+
* ```
|
|
1053
|
+
*/
|
|
1054
|
+
declare function requireAnyPermission(request: Request, permissions: Array<[resource: string, action: string]>): AppAuthContext | Response;
|
|
1055
|
+
/**
|
|
1056
|
+
* Require all of the specified permissions - returns auth context or error response
|
|
1057
|
+
*
|
|
1058
|
+
* @example
|
|
1059
|
+
* ```typescript
|
|
1060
|
+
* const auth = requireAllPermissions(request, [
|
|
1061
|
+
* ['invoices', 'read'],
|
|
1062
|
+
* ['customers', 'read'],
|
|
1063
|
+
* ]);
|
|
1064
|
+
* ```
|
|
1065
|
+
*/
|
|
1066
|
+
declare function requireAllPermissions(request: Request, permissions: Array<[resource: string, action: string]>): AppAuthContext | Response;
|
|
1067
|
+
|
|
1068
|
+
export { AUTH_HEADERS, type AppAuthContext, type AppLifecycle, type AppManifest, CHECKSUM_PREFIX, type CreateAppOptions, type DatabaseContext, DatabaseProvider, type DatabaseProviderProps, type EldrinContext, type EldrinEnv, type EldrinEvent, EldrinEventClient, type EmitOptions, type EmitResult, type EventClientConfig, type EventDelivery, type EventHandler, type GenerateMigrationManifestOptions, type GenerateMigrationManifestResult, type JWTPayload, type JWTVerifyOptions, type LifecycleProps, type ManifestGroup, type ManifestPermission, type MigrationFile, type MigrationFiles, type MigrationManifest, type MigrationManifestEntry, type MigrationOptions, type MigrationRecord, type MigrationResult, type PollOptions, type PollResult, type RegisteredEventType, type RollbackResult, type SubscriptionInfo, calculateChecksum, calculatePrefixedChecksum, createApp, createEventClient, extractTimestamp, generateMigrationManifest, getAuthContext, getAuthContextFromJWT, getMigrationStatus, getRollbackFilename, hasPermission, hasPlatformRole, isPlatformAdmin, isValidMigrationFilename, isValidRollbackFilename, parseSQLStatements, requireAllPermissions, requireAnyPermission, requireAuth, requireJWTAuth, requireJWTPermission, requirePermission, rollbackMigrations, runMigrations, useDatabase, useDatabaseContext, useMigrationsComplete, validateMigrationManifest, verifyChecksum, verifyJWT };
|