@multitenantkit/adapter-transport-supabase-edge 0.2.1

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.
Files changed (38) hide show
  1. package/README.md +180 -0
  2. package/dist/buildEdgeFunction.d.ts +29 -0
  3. package/dist/buildEdgeFunction.d.ts.map +1 -0
  4. package/dist/buildEdgeFunction.js +150 -0
  5. package/dist/buildEdgeFunction.js.map +1 -0
  6. package/dist/index.d.ts +32 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +34 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/middleware/auth.d.ts +8 -0
  11. package/dist/middleware/auth.d.ts.map +1 -0
  12. package/dist/middleware/auth.js +27 -0
  13. package/dist/middleware/auth.js.map +1 -0
  14. package/dist/middleware/cors.d.ts +10 -0
  15. package/dist/middleware/cors.d.ts.map +1 -0
  16. package/dist/middleware/cors.js +30 -0
  17. package/dist/middleware/cors.js.map +1 -0
  18. package/dist/middleware/index.d.ts +5 -0
  19. package/dist/middleware/index.d.ts.map +1 -0
  20. package/dist/middleware/index.js +6 -0
  21. package/dist/middleware/index.js.map +1 -0
  22. package/dist/middleware/requestId.d.ts +6 -0
  23. package/dist/middleware/requestId.d.ts.map +1 -0
  24. package/dist/middleware/requestId.js +14 -0
  25. package/dist/middleware/requestId.js.map +1 -0
  26. package/dist/middleware/validation.d.ts +31 -0
  27. package/dist/middleware/validation.d.ts.map +1 -0
  28. package/dist/middleware/validation.js +104 -0
  29. package/dist/middleware/validation.js.map +1 -0
  30. package/dist/router.d.ts +53 -0
  31. package/dist/router.d.ts.map +1 -0
  32. package/dist/router.js +96 -0
  33. package/dist/router.js.map +1 -0
  34. package/dist/types.d.ts +90 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +6 -0
  37. package/dist/types.js.map +1 -0
  38. package/package.json +63 -0
package/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # @multitenantkit/adapter-transport-supabase-edge
2
+
3
+ Supabase Edge Functions transport adapter for MultiTenantKit HTTP API.
4
+
5
+ This adapter enables running MultiTenantKit API endpoints as a single Supabase Edge Function with internal routing (the "fat function" pattern).
6
+
7
+ ## Features
8
+
9
+ - **Single Edge Function**: All endpoints run in one function, minimizing cold starts
10
+ - **Native Deno**: Uses `Deno.serve()` directly without additional frameworks
11
+ - **Full Compatibility**: Works with all `@multitenantkit/api-handlers` HandlerPackages
12
+ - **Built-in CORS**: Configurable CORS handling for browser clients
13
+ - **Authentication**: Integrates with `@multitenantkit/adapter-auth-supabase` for JWT validation
14
+ - **Request Validation**: Zod-based validation for body, params, and query
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @multitenantkit/adapter-transport-supabase-edge
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Setup
25
+
26
+ ```typescript
27
+ // supabase/functions/multitenantkit/index.ts
28
+
29
+ import { buildEdgeFunction } from '@multitenantkit/adapter-transport-supabase-edge';
30
+ import { buildHandlers } from '@multitenantkit/api-handlers';
31
+ import { createUseCases } from '@multitenantkit/composition';
32
+ import { SupabaseAuthService } from '@multitenantkit/adapter-auth-supabase';
33
+
34
+ // Initialize your adapters and use cases
35
+ const useCases = createUseCases(adapters);
36
+ const handlers = buildHandlers(useCases);
37
+
38
+ // Create auth service
39
+ const authService = new SupabaseAuthService({
40
+ supabaseUrl: Deno.env.get('SUPABASE_URL')!,
41
+ supabaseServiceKey: Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
42
+ });
43
+
44
+ // Build the Edge Function handler
45
+ const handler = buildEdgeFunction(handlers, authService, {
46
+ basePath: '/multitenantkit',
47
+ cors: {
48
+ allowOrigin: '*',
49
+ allowHeaders: ['authorization', 'x-client-info', 'apikey', 'content-type'],
50
+ allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']
51
+ },
52
+ debug: true // Enable for development
53
+ });
54
+
55
+ // Start the server
56
+ Deno.serve(handler);
57
+ ```
58
+
59
+ ### Configuration Options
60
+
61
+ ```typescript
62
+ interface EdgeFunctionOptions {
63
+ /** Base path prefix for all routes (usually the function name) */
64
+ basePath: string;
65
+
66
+ /** CORS configuration */
67
+ cors?: {
68
+ allowOrigin: string | string[];
69
+ allowHeaders: string[];
70
+ allowMethods: string[];
71
+ maxAge?: number;
72
+ };
73
+
74
+ /** Enable debug logging */
75
+ debug?: boolean;
76
+ }
77
+ ```
78
+
79
+ ## Project Structure
80
+
81
+ For a Supabase project using this adapter:
82
+
83
+ ```
84
+ supabase/
85
+ ├── functions/
86
+ │ ├── import_map.json
87
+ │ ├── _shared/
88
+ │ │ └── multitenantkit.ts # Shared configuration
89
+ │ └── multitenantkit/
90
+ │ └── index.ts # Entry point
91
+ ├── migrations/
92
+ └── config.toml
93
+ ```
94
+
95
+ ### Supabase Config (`config.toml`)
96
+
97
+ ```toml
98
+ [functions.multitenantkit]
99
+ verify_jwt = false # We handle JWT verification ourselves
100
+ ```
101
+
102
+ ## Available Endpoints
103
+
104
+ Once deployed, the following endpoints are available (prefixed with your function path):
105
+
106
+ ### Users
107
+ - `POST /users` - Create user
108
+ - `GET /users/me` - Get current user
109
+ - `PATCH /users/me` - Update current user
110
+ - `DELETE /users/me` - Delete current user
111
+ - `GET /users/me/organizations` - List user's organizations
112
+
113
+ ### Organizations
114
+ - `POST /organizations` - Create organization
115
+ - `GET /organizations/:id` - Get organization
116
+ - `PATCH /organizations/:id` - Update organization
117
+ - `DELETE /organizations/:id` - Delete organization
118
+
119
+ ### Memberships
120
+ - `POST /organizations/:organizationId/memberships` - Add member
121
+ - `GET /organizations/:organizationId/memberships` - List members
122
+ - `GET /organizations/:organizationId/memberships/:memberId` - Get member
123
+ - `PATCH /organizations/:organizationId/memberships/:memberId` - Update member
124
+ - `DELETE /organizations/:organizationId/memberships/:memberId` - Remove member
125
+
126
+ ### Health
127
+ - `GET /health` - Health check endpoint (built-in)
128
+
129
+ ## API Reference
130
+
131
+ ### `buildEdgeFunction(handlers, authService, options)`
132
+
133
+ Creates a Deno.serve() compatible handler function.
134
+
135
+ **Parameters:**
136
+ - `handlers` - Array of HandlerPackages from `@multitenantkit/api-handlers`
137
+ - `authService` - AuthService implementation (e.g., SupabaseAuthService)
138
+ - `options` - Configuration options
139
+
140
+ **Returns:** `(request: Request) => Promise<Response>`
141
+
142
+ ### `EdgeRouter`
143
+
144
+ Low-level router class for advanced use cases.
145
+
146
+ ```typescript
147
+ import { EdgeRouter } from '@multitenantkit/adapter-transport-supabase-edge';
148
+
149
+ const router = new EdgeRouter('/api', handlers);
150
+ const match = router.match('GET', '/api/users/me');
151
+ ```
152
+
153
+ ### Middleware Utilities
154
+
155
+ For custom implementations:
156
+
157
+ ```typescript
158
+ import {
159
+ authenticateRequest,
160
+ buildCorsHeaders,
161
+ handleCorsPreflightRequest,
162
+ getRequestId,
163
+ validateRequest
164
+ } from '@multitenantkit/adapter-transport-supabase-edge';
165
+ ```
166
+
167
+ ## Differences from Express Adapter
168
+
169
+ | Aspect | Express | Supabase Edge |
170
+ |--------|---------|---------------|
171
+ | Runtime | Node.js | Deno |
172
+ | Deploy | Manual | Automatic (Supabase) |
173
+ | Scaling | Manual | Automatic (edge) |
174
+ | CORS | `cors` middleware | Manual headers |
175
+ | Body parsing | `express.json()` | Native `request.json()` |
176
+ | Path params | Express router | Regex matching |
177
+
178
+ ## License
179
+
180
+ MIT
@@ -0,0 +1,29 @@
1
+ import type { AuthService } from '@multitenantkit/api-contracts/shared/ports';
2
+ import type { HandlerPackage } from '@multitenantkit/api-handlers';
3
+ import type { EdgeFunctionOptions } from './types';
4
+ /**
5
+ * Build the Edge Function handler from HandlerPackages
6
+ *
7
+ * This function creates a Deno.serve() compatible handler that:
8
+ * - Routes requests to appropriate handlers
9
+ * - Handles CORS
10
+ * - Authenticates requests
11
+ * - Validates input
12
+ * - Returns consistent responses
13
+ *
14
+ * @param handlers - Array of HandlerPackages from api-handlers
15
+ * @param authService - AuthService implementation (e.g., SupabaseAuthService)
16
+ * @param options - Configuration options
17
+ * @returns Handler function for Deno.serve()
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const handler = buildEdgeFunction(handlers, authService, {
22
+ * basePath: '/multitenantkit'
23
+ * });
24
+ *
25
+ * Deno.serve(handler);
26
+ * ```
27
+ */
28
+ export declare function buildEdgeFunction(handlers: HandlerPackage<unknown, unknown>[], authService: AuthService<unknown>, options: EdgeFunctionOptions): (request: Request) => Promise<Response>;
29
+ //# sourceMappingURL=buildEdgeFunction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildEdgeFunction.d.ts","sourceRoot":"","sources":["../src/buildEdgeFunction.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAQnE,OAAO,KAAK,EAAe,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAwDhE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAC7B,QAAQ,EAAE,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAC5C,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,EACjC,OAAO,EAAE,mBAAmB,GAC7B,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CA0HzC"}
@@ -0,0 +1,150 @@
1
+ // Main builder for Supabase Edge Functions handler
2
+ import { ANONYMOUS_PRINCIPAL } from '@multitenantkit/domain-contracts/shared/auth';
3
+ import { authenticateRequest } from './middleware/auth';
4
+ import { buildCorsHeaders, handleCorsPreflightRequest } from './middleware/cors';
5
+ import { getRequestId } from './middleware/requestId';
6
+ import { validateRequest } from './middleware/validation';
7
+ import { EdgeRouter } from './router';
8
+ /**
9
+ * Default CORS configuration
10
+ */
11
+ const DEFAULT_CORS = {
12
+ allowOrigin: '*',
13
+ allowHeaders: ['authorization', 'x-client-info', 'apikey', 'content-type', 'x-request-id'],
14
+ allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']
15
+ };
16
+ /**
17
+ * Default options for Edge Function
18
+ */
19
+ const DEFAULT_OPTIONS = {
20
+ cors: DEFAULT_CORS,
21
+ debug: false
22
+ };
23
+ /**
24
+ * Build error response with consistent format
25
+ */
26
+ function buildErrorResponse(status, code, message, requestId, corsHeaders, details) {
27
+ const errorBody = {
28
+ code,
29
+ message,
30
+ requestId,
31
+ timestamp: new Date().toISOString()
32
+ };
33
+ if (details) {
34
+ errorBody.details = details;
35
+ }
36
+ return new Response(JSON.stringify({
37
+ error: errorBody
38
+ }), {
39
+ status,
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ 'X-Request-ID': requestId,
43
+ ...corsHeaders
44
+ }
45
+ });
46
+ }
47
+ /**
48
+ * Build the Edge Function handler from HandlerPackages
49
+ *
50
+ * This function creates a Deno.serve() compatible handler that:
51
+ * - Routes requests to appropriate handlers
52
+ * - Handles CORS
53
+ * - Authenticates requests
54
+ * - Validates input
55
+ * - Returns consistent responses
56
+ *
57
+ * @param handlers - Array of HandlerPackages from api-handlers
58
+ * @param authService - AuthService implementation (e.g., SupabaseAuthService)
59
+ * @param options - Configuration options
60
+ * @returns Handler function for Deno.serve()
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const handler = buildEdgeFunction(handlers, authService, {
65
+ * basePath: '/multitenantkit'
66
+ * });
67
+ *
68
+ * Deno.serve(handler);
69
+ * ```
70
+ */
71
+ export function buildEdgeFunction(handlers, authService, options) {
72
+ const opts = { ...DEFAULT_OPTIONS, ...options };
73
+ const corsConfig = opts.cors ?? DEFAULT_CORS;
74
+ const corsHeaders = buildCorsHeaders(corsConfig);
75
+ const router = new EdgeRouter(opts.basePath, handlers);
76
+ return async (request) => {
77
+ const requestId = getRequestId(request);
78
+ try {
79
+ // Handle CORS preflight
80
+ if (request.method === 'OPTIONS') {
81
+ return handleCorsPreflightRequest(corsHeaders);
82
+ }
83
+ const url = new URL(request.url);
84
+ const pathname = url.pathname;
85
+ const method = request.method;
86
+ if (opts.debug) {
87
+ console.log(`📍 ${method} ${pathname} [${requestId}]`);
88
+ }
89
+ // Health check endpoint
90
+ if (pathname === `${opts.basePath}/health` && method === 'GET') {
91
+ return new Response(JSON.stringify({
92
+ status: 'healthy',
93
+ timestamp: new Date().toISOString(),
94
+ requestId
95
+ }), {
96
+ status: 200,
97
+ headers: {
98
+ 'Content-Type': 'application/json',
99
+ 'X-Request-ID': requestId,
100
+ ...corsHeaders
101
+ }
102
+ });
103
+ }
104
+ // Route matching
105
+ const routeMatch = router.match(method, pathname);
106
+ if (!routeMatch) {
107
+ return buildErrorResponse(404, 'NOT_FOUND', `Route ${method} ${pathname} not found`, requestId, corsHeaders);
108
+ }
109
+ const { handler: pkg, params } = routeMatch;
110
+ const handlerPackage = pkg;
111
+ const { route, schema, handler } = handlerPackage;
112
+ // Authentication
113
+ let principal = ANONYMOUS_PRINCIPAL;
114
+ if (route.auth === 'required' || route.auth === 'optional') {
115
+ principal = await authenticateRequest(request, authService);
116
+ // If auth is required but we got anonymous, return 401
117
+ if (route.auth === 'required' && principal === ANONYMOUS_PRINCIPAL) {
118
+ return buildErrorResponse(401, 'UNAUTHORIZED', 'Authentication required', requestId, corsHeaders);
119
+ }
120
+ }
121
+ // Validation
122
+ const validationResult = await validateRequest(request, url, params, schema);
123
+ if (!validationResult.success) {
124
+ return buildErrorResponse(400, 'VALIDATION_ERROR', 'Request validation failed', requestId, corsHeaders, { issues: validationResult.errors });
125
+ }
126
+ // Execute handler
127
+ const result = await handler({
128
+ input: validationResult.data,
129
+ principal,
130
+ requestId
131
+ });
132
+ // Build response
133
+ const responseHeaders = {
134
+ 'Content-Type': 'application/json',
135
+ 'X-Request-ID': requestId,
136
+ ...corsHeaders,
137
+ ...(result.headers || {})
138
+ };
139
+ return new Response(JSON.stringify(result.body), {
140
+ status: result.status,
141
+ headers: responseHeaders
142
+ });
143
+ }
144
+ catch (error) {
145
+ console.error('Edge Function error:', error);
146
+ return buildErrorResponse(500, 'INTERNAL_SERVER_ERROR', 'An unexpected error occurred', requestId, corsHeaders);
147
+ }
148
+ };
149
+ }
150
+ //# sourceMappingURL=buildEdgeFunction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildEdgeFunction.js","sourceRoot":"","sources":["../src/buildEdgeFunction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @module @multitenantkit/adapter-transport-supabase-edge
3
+ *
4
+ * Supabase Edge Functions Transport Adapter for MultiTenantKit
5
+ *
6
+ * This adapter enables running MultiTenantKit API endpoints as a single
7
+ * Supabase Edge Function with internal routing (the "fat function" pattern).
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { buildEdgeFunction } from '@multitenantkit/adapter-transport-supabase-edge';
12
+ * import { buildHandlers } from '@multitenantkit/api-handlers';
13
+ * import { SupabaseAuthService } from '@multitenantkit/adapter-auth-supabase';
14
+ *
15
+ * const handlers = buildHandlers(useCases);
16
+ * const authService = new SupabaseAuthService({ supabaseUrl, supabaseServiceKey });
17
+ *
18
+ * const handler = buildEdgeFunction(handlers, authService, {
19
+ * basePath: '/multitenantkit'
20
+ * });
21
+ *
22
+ * Deno.serve(handler);
23
+ * ```
24
+ */
25
+ export { buildEdgeFunction } from './buildEdgeFunction';
26
+ export { authenticateRequest } from './middleware/auth';
27
+ export { buildCorsHeaders, handleCorsPreflightRequest } from './middleware/cors';
28
+ export { getRequestId } from './middleware/requestId';
29
+ export { validateRequest } from './middleware/validation';
30
+ export { EdgeRouter } from './router';
31
+ export type { CorsOptions, EdgeContext, EdgeFunctionOptions, RouteMatch } from './types';
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @module @multitenantkit/adapter-transport-supabase-edge
3
+ *
4
+ * Supabase Edge Functions Transport Adapter for MultiTenantKit
5
+ *
6
+ * This adapter enables running MultiTenantKit API endpoints as a single
7
+ * Supabase Edge Function with internal routing (the "fat function" pattern).
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { buildEdgeFunction } from '@multitenantkit/adapter-transport-supabase-edge';
12
+ * import { buildHandlers } from '@multitenantkit/api-handlers';
13
+ * import { SupabaseAuthService } from '@multitenantkit/adapter-auth-supabase';
14
+ *
15
+ * const handlers = buildHandlers(useCases);
16
+ * const authService = new SupabaseAuthService({ supabaseUrl, supabaseServiceKey });
17
+ *
18
+ * const handler = buildEdgeFunction(handlers, authService, {
19
+ * basePath: '/multitenantkit'
20
+ * });
21
+ *
22
+ * Deno.serve(handler);
23
+ * ```
24
+ */
25
+ // Main builder
26
+ export { buildEdgeFunction } from './buildEdgeFunction';
27
+ // Middleware utilities (for custom implementations)
28
+ export { authenticateRequest } from './middleware/auth';
29
+ export { buildCorsHeaders, handleCorsPreflightRequest } from './middleware/cors';
30
+ export { getRequestId } from './middleware/requestId';
31
+ export { validateRequest } from './middleware/validation';
32
+ // Router (for advanced use cases)
33
+ export { EdgeRouter } from './router';
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,eAAe;AACf,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,oDAAoD;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,kCAAkC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { AuthService } from '@multitenantkit/api-contracts/shared/ports';
2
+ import { type Principal } from '@multitenantkit/domain-contracts/shared/auth';
3
+ /**
4
+ * Authenticate a request using the provided AuthService
5
+ * Adapts Deno Request headers to the format expected by AuthService
6
+ */
7
+ export declare function authenticateRequest(request: Request, authService: AuthService<unknown>): Promise<Principal>;
8
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAC9E,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAEnG;;;GAGG;AACH,wBAAsB,mBAAmB,CACrC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,GAClC,OAAO,CAAC,SAAS,CAAC,CAqBpB"}
@@ -0,0 +1,27 @@
1
+ // Authentication middleware for Supabase Edge Functions
2
+ import { ANONYMOUS_PRINCIPAL } from '@multitenantkit/domain-contracts/shared/auth';
3
+ /**
4
+ * Authenticate a request using the provided AuthService
5
+ * Adapts Deno Request headers to the format expected by AuthService
6
+ */
7
+ export async function authenticateRequest(request, authService) {
8
+ try {
9
+ // Convert Deno Headers to Record<string, string>
10
+ const headers = {};
11
+ request.headers.forEach((value, key) => {
12
+ headers[key.toLowerCase()] = value;
13
+ });
14
+ // Build auth input (compatible with SupabaseAuthService)
15
+ const authInput = {
16
+ headers,
17
+ cookies: {} // Edge Functions typically use header-based auth
18
+ };
19
+ const principal = await authService.authenticate(authInput);
20
+ return principal || ANONYMOUS_PRINCIPAL;
21
+ }
22
+ catch (error) {
23
+ console.error('Authentication error:', error);
24
+ return ANONYMOUS_PRINCIPAL;
25
+ }
26
+ }
27
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAGxD,OAAO,EAAE,mBAAmB,EAAkB,MAAM,8CAA8C,CAAC;AAEnG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACrC,OAAgB,EAChB,WAAiC;IAEjC,IAAI,CAAC;QACD,iDAAiD;QACjD,MAAM,OAAO,GAA2B,EAAE,CAAC;QAC3C,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACnC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,yDAAyD;QACzD,MAAM,SAAS,GAAG;YACd,OAAO;YACP,OAAO,EAAE,EAAE,CAAC,iDAAiD;SAChE,CAAC;QAEF,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAE5D,OAAO,SAAS,IAAI,mBAAmB,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,mBAAmB,CAAC;IAC/B,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { CorsOptions } from '../types';
2
+ /**
3
+ * Build CORS headers object
4
+ */
5
+ export declare function buildCorsHeaders(options?: CorsOptions): Record<string, string>;
6
+ /**
7
+ * Handle CORS preflight (OPTIONS) request
8
+ */
9
+ export declare function handleCorsPreflightRequest(corsHeaders: Record<string, string>): Response;
10
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAW5C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,WAA0B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAW5F;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,QAAQ,CAExF"}
@@ -0,0 +1,30 @@
1
+ // CORS Handler for Supabase Edge Functions
2
+ /**
3
+ * Default CORS configuration
4
+ */
5
+ const DEFAULT_CORS = {
6
+ allowOrigin: '*',
7
+ allowHeaders: ['authorization', 'x-client-info', 'apikey', 'content-type', 'x-request-id'],
8
+ allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']
9
+ };
10
+ /**
11
+ * Build CORS headers object
12
+ */
13
+ export function buildCorsHeaders(options = DEFAULT_CORS) {
14
+ const origin = Array.isArray(options.allowOrigin)
15
+ ? options.allowOrigin.join(', ')
16
+ : options.allowOrigin;
17
+ return {
18
+ 'Access-Control-Allow-Origin': origin,
19
+ 'Access-Control-Allow-Headers': options.allowHeaders.join(', '),
20
+ 'Access-Control-Allow-Methods': options.allowMethods.join(', '),
21
+ ...(options.maxAge && { 'Access-Control-Max-Age': String(options.maxAge) })
22
+ };
23
+ }
24
+ /**
25
+ * Handle CORS preflight (OPTIONS) request
26
+ */
27
+ export function handleCorsPreflightRequest(corsHeaders) {
28
+ return new Response('ok', { headers: corsHeaders });
29
+ }
30
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAI3C;;GAEG;AACH,MAAM,YAAY,GAAgB;IAC9B,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,CAAC,eAAe,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,CAAC;IAC1F,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC;CACrE,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAuB,YAAY;IAChE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7C,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IAE1B,OAAO;QACH,6BAA6B,EAAE,MAAM;QACrC,8BAA8B,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/D,8BAA8B,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAC/D,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,wBAAwB,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;KAC9E,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmC;IAC1E,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { authenticateRequest } from './auth';
2
+ export { buildCorsHeaders, handleCorsPreflightRequest } from './cors';
3
+ export { getRequestId } from './requestId';
4
+ export { validateRequest } from './validation';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ // Middleware exports for Supabase Edge Functions adapter
2
+ export { authenticateRequest } from './auth';
3
+ export { buildCorsHeaders, handleCorsPreflightRequest } from './cors';
4
+ export { getRequestId } from './requestId';
5
+ export { validateRequest } from './validation';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generate or extract request ID from headers
3
+ * Uses the Web Crypto API (available in Deno) to generate UUIDs
4
+ */
5
+ export declare function getRequestId(request: Request): string;
6
+ //# sourceMappingURL=requestId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestId.d.ts","sourceRoot":"","sources":["../../src/middleware/requestId.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CASrD"}
@@ -0,0 +1,14 @@
1
+ // Request ID middleware for Supabase Edge Functions
2
+ /**
3
+ * Generate or extract request ID from headers
4
+ * Uses the Web Crypto API (available in Deno) to generate UUIDs
5
+ */
6
+ export function getRequestId(request) {
7
+ const existingId = request.headers.get('x-request-id');
8
+ if (existingId) {
9
+ return existingId;
10
+ }
11
+ // Generate new UUID using Web Crypto API (available in Deno)
12
+ return crypto.randomUUID();
13
+ }
14
+ //# sourceMappingURL=requestId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestId.js","sourceRoot":"","sources":["../../src/middleware/requestId.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAgB;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEvD,IAAI,UAAU,EAAE,CAAC;QACb,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,6DAA6D;IAC7D,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { ZodSchema } from 'zod';
2
+ /**
3
+ * Validation schema configuration
4
+ */
5
+ interface ValidationSchemaConfig {
6
+ body?: ZodSchema;
7
+ params?: ZodSchema;
8
+ query?: ZodSchema;
9
+ }
10
+ /**
11
+ * Validation error detail
12
+ */
13
+ interface ValidationError {
14
+ field: string;
15
+ message: string;
16
+ code: string;
17
+ }
18
+ /**
19
+ * Result of validation
20
+ */
21
+ interface ValidationResult {
22
+ success: boolean;
23
+ data?: unknown;
24
+ errors?: ValidationError[];
25
+ }
26
+ /**
27
+ * Validate request using Zod schema
28
+ */
29
+ export declare function validateRequest(request: Request, url: URL, params: Record<string, string>, schema: ZodSchema | ValidationSchemaConfig): Promise<ValidationResult>;
30
+ export {};
31
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/middleware/validation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAErC;;GAEG;AACH,UAAU,sBAAsB;IAC5B,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AACH,UAAU,eAAe;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,UAAU,gBAAgB;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC9B;AA8BD;;GAEG;AACH,wBAAsB,eAAe,CACjC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,SAAS,GAAG,sBAAsB,GAC3C,OAAO,CAAC,gBAAgB,CAAC,CAuF3B"}
@@ -0,0 +1,104 @@
1
+ // Request validation middleware for Supabase Edge Functions
2
+ /**
3
+ * Parse request body as JSON
4
+ */
5
+ async function parseBody(request) {
6
+ try {
7
+ const contentType = request.headers.get('content-type');
8
+ if (contentType?.includes('application/json')) {
9
+ return await request.json();
10
+ }
11
+ return {};
12
+ }
13
+ catch {
14
+ return {};
15
+ }
16
+ }
17
+ /**
18
+ * Parse query parameters from URL
19
+ */
20
+ function parseQuery(url) {
21
+ const query = {};
22
+ url.searchParams.forEach((value, key) => {
23
+ query[key] = value;
24
+ });
25
+ return query;
26
+ }
27
+ /**
28
+ * Validate request using Zod schema
29
+ */
30
+ export async function validateRequest(request, url, params, schema) {
31
+ const errors = [];
32
+ let validatedInput = {};
33
+ const body = await parseBody(request);
34
+ const query = parseQuery(url);
35
+ // Handle simple schema (validates entire request object)
36
+ if ('safeParse' in schema && typeof schema.safeParse === 'function') {
37
+ const requestData = {
38
+ body,
39
+ params,
40
+ query
41
+ };
42
+ const result = schema.safeParse(requestData);
43
+ if (!result.success) {
44
+ return {
45
+ success: false,
46
+ errors: result.error.errors.map((err) => ({
47
+ field: err.path.join('.'),
48
+ message: err.message,
49
+ code: err.code
50
+ }))
51
+ };
52
+ }
53
+ return {
54
+ success: true,
55
+ data: result.data
56
+ };
57
+ }
58
+ // Handle complex schema configuration
59
+ const config = schema;
60
+ if (config.body) {
61
+ const bodyResult = config.body.safeParse(body);
62
+ if (!bodyResult.success) {
63
+ errors.push(...bodyResult.error.errors.map((err) => ({
64
+ field: `body.${err.path.join('.')}`,
65
+ message: err.message,
66
+ code: err.code
67
+ })));
68
+ }
69
+ else {
70
+ validatedInput.body = bodyResult.data;
71
+ }
72
+ }
73
+ if (config.params) {
74
+ const paramsResult = config.params.safeParse(params);
75
+ if (!paramsResult.success) {
76
+ errors.push(...paramsResult.error.errors.map((err) => ({
77
+ field: `params.${err.path.join('.')}`,
78
+ message: err.message,
79
+ code: err.code
80
+ })));
81
+ }
82
+ else {
83
+ validatedInput = { ...validatedInput, ...paramsResult.data };
84
+ }
85
+ }
86
+ if (config.query) {
87
+ const queryResult = config.query.safeParse(query);
88
+ if (!queryResult.success) {
89
+ errors.push(...queryResult.error.errors.map((err) => ({
90
+ field: `query.${err.path.join('.')}`,
91
+ message: err.message,
92
+ code: err.code
93
+ })));
94
+ }
95
+ else {
96
+ validatedInput = { ...validatedInput, ...queryResult.data };
97
+ }
98
+ }
99
+ if (errors.length > 0) {
100
+ return { success: false, errors };
101
+ }
102
+ return { success: true, data: validatedInput };
103
+ }
104
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/middleware/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Edge Function Router
3
+ *
4
+ * Provides Express-style routing for Supabase Edge Functions.
5
+ * Converts HandlerPackages to a routing table with regex-based path matching.
6
+ *
7
+ * @module
8
+ */
9
+ import type { HandlerPackage } from '@multitenantkit/api-handlers';
10
+ import type { RouteMatch } from './types';
11
+ /**
12
+ * Route matcher for Supabase Edge Functions.
13
+ *
14
+ * Converts Express-style paths (e.g., `/users/:id`) to regex patterns
15
+ * and matches incoming requests to the appropriate handlers.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { EdgeRouter } from '@multitenantkit/adapter-transport-supabase-edge';
20
+ *
21
+ * const router = new EdgeRouter('/api', handlers);
22
+ *
23
+ * // Match a request
24
+ * const match = router.match('GET', '/api/organizations/123');
25
+ * if (match) {
26
+ * console.log(match.params); // { id: '123' }
27
+ * // Call match.handler...
28
+ * }
29
+ * ```
30
+ */
31
+ export declare class EdgeRouter {
32
+ private routes;
33
+ private readonly basePath;
34
+ constructor(basePath: string, handlers: HandlerPackage<unknown, unknown>[]);
35
+ /**
36
+ * Register all handler packages as routes
37
+ */
38
+ private registerHandlers;
39
+ /**
40
+ * Convert Express-style path to regex
41
+ * Example: /users/:id → /^\/users\/([^/]+)$/
42
+ */
43
+ private pathToRegex;
44
+ /**
45
+ * Match an incoming request to a registered handler.
46
+ *
47
+ * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH)
48
+ * @param pathname - Full pathname including base path (e.g., '/api/users/123')
49
+ * @returns RouteMatch with handler and extracted params, or null if no match
50
+ */
51
+ match(method: string, pathname: string): RouteMatch | null;
52
+ }
53
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAY1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;IAK1E;;OAEG;IAEH,OAAO,CAAC,gBAAgB;IAcxB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAiBnB;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;CAoB7D"}
package/dist/router.js ADDED
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Edge Function Router
3
+ *
4
+ * Provides Express-style routing for Supabase Edge Functions.
5
+ * Converts HandlerPackages to a routing table with regex-based path matching.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Route matcher for Supabase Edge Functions.
11
+ *
12
+ * Converts Express-style paths (e.g., `/users/:id`) to regex patterns
13
+ * and matches incoming requests to the appropriate handlers.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { EdgeRouter } from '@multitenantkit/adapter-transport-supabase-edge';
18
+ *
19
+ * const router = new EdgeRouter('/api', handlers);
20
+ *
21
+ * // Match a request
22
+ * const match = router.match('GET', '/api/organizations/123');
23
+ * if (match) {
24
+ * console.log(match.params); // { id: '123' }
25
+ * // Call match.handler...
26
+ * }
27
+ * ```
28
+ */
29
+ export class EdgeRouter {
30
+ routes = [];
31
+ basePath;
32
+ constructor(basePath, handlers) {
33
+ this.basePath = basePath;
34
+ this.registerHandlers(handlers);
35
+ }
36
+ /**
37
+ * Register all handler packages as routes
38
+ */
39
+ // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called in constructor - false positive
40
+ registerHandlers(handlers) {
41
+ for (const handler of handlers) {
42
+ const { method, path } = handler.route;
43
+ const { pattern, paramNames } = this.pathToRegex(path);
44
+ this.routes.push({
45
+ method: method.toUpperCase(),
46
+ pattern,
47
+ paramNames,
48
+ handler
49
+ });
50
+ }
51
+ }
52
+ /**
53
+ * Convert Express-style path to regex
54
+ * Example: /users/:id → /^\/users\/([^/]+)$/
55
+ */
56
+ pathToRegex(path) {
57
+ const paramNames = [];
58
+ const fullPath = this.basePath + path;
59
+ const regexStr = fullPath
60
+ .replace(/:[a-zA-Z]+/g, (match) => {
61
+ paramNames.push(match.slice(1)); // Remove ':'
62
+ return '([^/]+)';
63
+ })
64
+ .replace(/\//g, '\\/');
65
+ return {
66
+ pattern: new RegExp(`^${regexStr}$`),
67
+ paramNames
68
+ };
69
+ }
70
+ /**
71
+ * Match an incoming request to a registered handler.
72
+ *
73
+ * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH)
74
+ * @param pathname - Full pathname including base path (e.g., '/api/users/123')
75
+ * @returns RouteMatch with handler and extracted params, or null if no match
76
+ */
77
+ match(method, pathname) {
78
+ for (const route of this.routes) {
79
+ if (route.method !== method.toUpperCase())
80
+ continue;
81
+ const match = pathname.match(route.pattern);
82
+ if (match) {
83
+ const params = {};
84
+ route.paramNames.forEach((name, i) => {
85
+ params[name] = match[i + 1];
86
+ });
87
+ return {
88
+ handler: route.handler,
89
+ params
90
+ };
91
+ }
92
+ }
93
+ return null;
94
+ }
95
+ }
96
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,UAAU;IACX,MAAM,GAAiB,EAAE,CAAC;IACjB,QAAQ,CAAS;IAElC,YAAY,QAAgB,EAAE,QAA4C;QACtE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,oGAAoG;IAC5F,gBAAgB,CAAC,QAA4C;QACjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;YACvC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAEvD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACb,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;gBAC5B,OAAO;gBACP,UAAU;gBACV,OAAO;aACV,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,IAAY;QAC5B,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAEtC,MAAM,QAAQ,GAAG,QAAQ;aACpB,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;YAC9B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa;YAC9C,OAAO,SAAS,CAAC;QACrB,CAAC,CAAC;aACD,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAE3B,OAAO;YACH,OAAO,EAAE,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC;YACpC,UAAU;SACb,CAAC;IACN,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAc,EAAE,QAAgB;QAClC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE;gBAAE,SAAS;YAEpD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,KAAK,EAAE,CAAC;gBACR,MAAM,MAAM,GAA2B,EAAE,CAAC;gBAC1C,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;oBACjC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;gBAEH,OAAO;oBACH,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,MAAM;iBACT,CAAC;YACN,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Types specific to Supabase Edge Functions adapter
3
+ * @module
4
+ */
5
+ import type { Principal } from '@multitenantkit/domain-contracts/shared/auth';
6
+ /**
7
+ * Context passed through the Edge Function pipeline.
8
+ * Contains all request information after parsing and authentication.
9
+ */
10
+ export interface EdgeContext {
11
+ /** The original Deno Request object */
12
+ request: Request;
13
+ /** Unique identifier for this request (from header or generated) */
14
+ requestId: string;
15
+ /** Authenticated principal, or null if not authenticated */
16
+ principal: Principal | null;
17
+ /** Path parameters extracted from the URL (e.g., { id: '123' }) */
18
+ params: Record<string, string>;
19
+ /** Query parameters from the URL */
20
+ query: Record<string, string>;
21
+ /** Parsed request body */
22
+ body: unknown;
23
+ }
24
+ /**
25
+ * CORS (Cross-Origin Resource Sharing) configuration options.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const cors: CorsOptions = {
30
+ * allowOrigin: 'https://myapp.com',
31
+ * allowHeaders: ['authorization', 'content-type'],
32
+ * allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
33
+ * maxAge: 86400 // 24 hours
34
+ * };
35
+ * ```
36
+ */
37
+ export interface CorsOptions {
38
+ /** Allowed origins - can be '*' for all, a single origin, or array of origins */
39
+ allowOrigin: string | string[];
40
+ /** Headers that can be used in the actual request */
41
+ allowHeaders: string[];
42
+ /** HTTP methods allowed when accessing the resource */
43
+ allowMethods: string[];
44
+ /** How long (in seconds) the results of a preflight request can be cached */
45
+ maxAge?: number;
46
+ }
47
+ /**
48
+ * Configuration options for the Edge Function builder.
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const options: EdgeFunctionOptions = {
53
+ * basePath: '/multitenantkit',
54
+ * cors: {
55
+ * allowOrigin: '*',
56
+ * allowHeaders: ['authorization', 'content-type'],
57
+ * allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']
58
+ * },
59
+ * debug: true
60
+ * };
61
+ * ```
62
+ */
63
+ export interface EdgeFunctionOptions {
64
+ /**
65
+ * Base path prefix for all routes.
66
+ * This is typically the Edge Function name (e.g., '/multitenantkit').
67
+ * All handler routes will be prefixed with this path.
68
+ */
69
+ basePath: string;
70
+ /**
71
+ * CORS configuration. If not provided, defaults to allowing all origins.
72
+ */
73
+ cors?: CorsOptions;
74
+ /**
75
+ * Enable debug logging. Logs request method, path, and requestId.
76
+ * @default false
77
+ */
78
+ debug?: boolean;
79
+ }
80
+ /**
81
+ * Result of matching a request to a registered route.
82
+ * Used internally by the router.
83
+ */
84
+ export interface RouteMatch {
85
+ /** The matched HandlerPackage */
86
+ handler: unknown;
87
+ /** Extracted path parameters */
88
+ params: Record<string, string>;
89
+ }
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,WAAW;IACxB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,0BAA0B;IAC1B,IAAI,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IACxB,iFAAiF;IACjF,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC/B,qDAAqD;IACrD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,uDAAuD;IACvD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACvB,iCAAiC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Types specific to Supabase Edge Functions adapter
3
+ * @module
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@multitenantkit/adapter-transport-supabase-edge",
3
+ "version": "0.2.1",
4
+ "type": "module",
5
+ "description": "Supabase Edge Functions transport adapter for MultiTenantKit HTTP API",
6
+ "keywords": [
7
+ "multitenantkit",
8
+ "saas",
9
+ "multi-tenant",
10
+ "multitenancy",
11
+ "adapter",
12
+ "supabase",
13
+ "edge-functions",
14
+ "deno",
15
+ "rest-api",
16
+ "api-server",
17
+ "http",
18
+ "serverless",
19
+ "organizations",
20
+ "teams",
21
+ "users",
22
+ "typescript"
23
+ ],
24
+ "author": "",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/multitenantkit/multitenantkit.git",
29
+ "directory": "packages/adapters/transport/supabase-edge"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/multitenantkit/multitenantkit/issues"
33
+ },
34
+ "homepage": "https://github.com/multitenantkit/multitenantkit#readme",
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "main": "./dist/index.js",
39
+ "types": "./dist/index.d.ts",
40
+ "files": [
41
+ "dist",
42
+ "README.md"
43
+ ],
44
+ "scripts": {
45
+ "build": "tsc --build",
46
+ "clean": "rm -rf dist",
47
+ "type-check": "tsc --noEmit",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "test:coverage": "vitest run --coverage"
51
+ },
52
+ "dependencies": {
53
+ "@multitenantkit/api-contracts": "^0.2.0",
54
+ "@multitenantkit/domain-contracts": "^0.2.0",
55
+ "@multitenantkit/api-handlers": "^0.2.0",
56
+ "zod": "^3.22.0"
57
+ },
58
+ "devDependencies": {
59
+ "@types/node": "^20.0.0",
60
+ "typescript": "^5.0.0",
61
+ "vitest": "^1.0.0"
62
+ }
63
+ }