1- import { Hono } from 'hono'
1+ import { Context , Hono } from 'hono'
22import { createMiddleware } from 'hono/factory'
33import { validator } from 'hono/validator'
44
@@ -12,41 +12,54 @@ import { exportTableToCsvRoute } from './export/csv'
1212import { importDumpRoute } from './import/dump'
1313import { importTableFromJsonRoute } from './import/json'
1414import { importTableFromCsvRoute } from './import/csv'
15- import { handleStudioRequest } from './studio'
1615import { corsPreflight } from './cors'
1716import { handleApiRequest } from './api'
17+ import { StarbasePlugin , StarbasePluginRegistry } from './plugin'
1818
1919export interface StarbaseDBConfiguration {
2020 outerbaseApiKey ?: string
2121 role : 'admin' | 'client'
2222 features ?: {
2323 allowlist ?: boolean
2424 rls ?: boolean
25- studio ?: boolean
2625 rest ?: boolean
2726 websocket ?: boolean
2827 export ?: boolean
2928 import ?: boolean
3029 }
31- studio ?: {
32- username : string
33- password : string
34- apiKey : string
30+ }
31+
32+ type HonoContext = {
33+ Variables : {
34+ config : StarbaseDBConfiguration
35+ dataSource : DataSource
36+ operations : {
37+ executeQuery : typeof executeQuery
38+ executeTransaction : typeof executeTransaction
39+ }
3540 }
3641}
3742
43+ const app = new Hono < HonoContext > ( )
44+
45+ export type StarbaseApp = typeof app
46+ export type StarbaseContext = Context < HonoContext >
47+
3848export class StarbaseDB {
3949 private dataSource : DataSource
4050 private config : StarbaseDBConfiguration
4151 private liteREST : LiteREST
52+ private plugins : StarbasePlugin [ ]
4253
4354 constructor ( options : {
4455 dataSource : DataSource
4556 config : StarbaseDBConfiguration
57+ plugins ?: StarbasePlugin [ ]
4658 } ) {
4759 this . dataSource = options . dataSource
4860 this . config = options . config
4961 this . liteREST = new LiteREST ( this . dataSource , this . config )
62+ this . plugins = options . plugins || [ ]
5063
5164 if (
5265 this . dataSource . source === 'external' &&
@@ -110,8 +123,16 @@ export class StarbaseDB {
110123 request : Request ,
111124 ctx : ExecutionContext
112125 ) : Promise < Response > {
113- const app = new Hono ( )
114- const isUpgrade = request . headers . get ( 'Upgrade' ) === 'websocket'
126+ // Add context to the request
127+ app . use ( '*' , async ( c , next ) => {
128+ c . set ( 'config' , this . config )
129+ c . set ( 'dataSource' , this . dataSource )
130+ c . set ( 'operations' , {
131+ executeQuery,
132+ executeTransaction,
133+ } )
134+ return next ( )
135+ } )
115136
116137 // Non-blocking operation to remove expired cache entries from our DO
117138 ctx . waitUntil ( this . expireCache ( ) )
@@ -130,22 +151,15 @@ export class StarbaseDB {
130151 )
131152 } )
132153
133- // CORS preflight handler.
134- app . options ( '*' , ( ) => corsPreflight ( ) )
154+ const registry = new StarbasePluginRegistry ( {
155+ app,
156+ plugins : this . plugins ,
157+ } )
135158
136- if ( this . getFeature ( 'studio' ) && this . config . studio ) {
137- app . get ( '/studio' , async ( c ) => {
138- return handleStudioRequest ( request , {
139- username : this . config . studio ! . username ,
140- password : this . config . studio ! . password ,
141- apiKey : this . config . studio ! . apiKey ,
142- } )
143- } )
144- }
159+ await registry . init ( )
145160
146- if ( isUpgrade && this . getFeature ( 'websocket' ) ) {
147- app . all ( '/socket' , ( ) => this . clientConnected ( ) )
148- }
161+ // CORS preflight handler.
162+ app . options ( '*' , ( ) => corsPreflight ( ) )
149163
150164 app . post ( '/query/raw' , async ( c ) => this . queryRoute ( c . req . raw , true ) )
151165 app . post ( '/query' , async ( c ) => this . queryRoute ( c . req . raw , false ) )
@@ -310,32 +324,6 @@ export class StarbaseDB {
310324 }
311325 }
312326
313- private clientConnected ( ) {
314- const webSocketPair = new WebSocketPair ( )
315- const [ client , server ] = Object . values ( webSocketPair )
316-
317- server . accept ( )
318- server . addEventListener ( 'message' , ( event ) => {
319- const { sql, params, action } = JSON . parse ( event . data as string )
320-
321- if ( action === 'query' ) {
322- const executeQueryWrapper = async ( ) => {
323- const response = await executeQuery ( {
324- sql,
325- params,
326- isRaw : false ,
327- dataSource : this . dataSource ,
328- config : this . config ,
329- } )
330- server . send ( JSON . stringify ( response ) )
331- }
332- executeQueryWrapper ( )
333- }
334- } )
335-
336- return new Response ( null , { status : 101 , webSocket : client } )
337- }
338-
339327 /**
340328 *
341329 */
0 commit comments