1- import { serve } from '@hono/node-server' ;
2- import { serveStatic } from '@hono/node-server/serve-static' ;
3- import { Hono } from 'hono' ;
4- import { cors } from 'hono/cors' ;
5- import { logger } from 'hono/logger' ;
61import {
72 Plugin ,
83 PluginContext ,
94 ObjectStackRuntimeProtocol
105} from '@objectstack/runtime' ;
6+ // Use the new IHttpServer interface
7+ import { IHttpServer } from '@objectstack/spec/api' ;
8+ import { HonoHttpServer } from './adapter' ;
119
1210export interface HonoPluginOptions {
1311 port ?: number ;
@@ -19,41 +17,28 @@ export interface HonoPluginOptions {
1917 *
2018 * Provides HTTP server capabilities using Hono framework.
2119 * Registers routes for ObjectStack Runtime Protocol.
22- *
23- * Dependencies: None (can work standalone)
24- * Services:
25- * - 'http-server': Hono app instance
26- *
27- * @example
28- * const server = new HonoServerPlugin({ port: 3000 });
29- * kernel.use(server);
3020 */
3121export class HonoServerPlugin implements Plugin {
3222 name = 'com.objectstack.server.hono' ;
3323 version = '1.0.0' ;
3424
3525 private options : HonoPluginOptions ;
36- private app : Hono ;
37- private server : any ;
26+ private server : HonoHttpServer ;
3827
3928 constructor ( options : HonoPluginOptions = { } ) {
4029 this . options = {
4130 port : 3000 ,
4231 ...options
4332 } ;
44- this . app = new Hono ( ) ;
33+ this . server = new HonoHttpServer ( this . options . port , this . options . staticRoot ) ;
4534 }
4635
4736 /**
4837 * Init phase - Setup HTTP server and register as service
4938 */
5039 async init ( ctx : PluginContext ) {
51- // Middleware
52- this . app . use ( '*' , logger ( ) ) ;
53- this . app . use ( '*' , cors ( ) ) ;
54-
55- // Register HTTP server service
56- ctx . registerService ( 'http-server' , this . app ) ;
40+ // Register HTTP server service as IHttpServer
41+ ctx . registerService ( 'http-server' , this . server ) ;
5742 ctx . logger . log ( '[HonoServerPlugin] HTTP server service registered' ) ;
5843 }
5944
@@ -73,7 +58,8 @@ export class HonoServerPlugin implements Plugin {
7358 getService : ( name : string ) => {
7459 if ( name === 'objectql' ) return objectql ;
7560 throw new Error ( `[HonoPlugin] Service ${ name } not found` ) ;
76- }
61+ } ,
62+ getAllPlugins : ( ) => [ ] // Mock
7763 } as any ) ;
7864
7965 } catch ( e ) {
@@ -83,80 +69,68 @@ export class HonoServerPlugin implements Plugin {
8369 // Register protocol routes if available
8470 if ( protocol ) {
8571 const p = protocol ! ;
86- this . app . get ( '/api/v1' , ( c ) => c . json ( p . getDiscovery ( ) ) ) ;
72+ this . server . get ( '/api/v1' , ( req , res ) => res . json ( p . getDiscovery ( ) ) ) ;
8773
8874 // Meta Protocol
89- this . app . get ( '/api/v1/meta' , ( c ) => c . json ( p . getMetaTypes ( ) ) ) ;
90- this . app . get ( '/api/v1/meta/:type' , ( c ) => c . json ( p . getMetaItems ( c . req . param ( ' type' ) ) ) ) ;
91- this . app . get ( '/api/v1/meta/:type/:name' , ( c ) => {
75+ this . server . get ( '/api/v1/meta' , ( req , res ) => res . json ( p . getMetaTypes ( ) ) ) ;
76+ this . server . get ( '/api/v1/meta/:type' , ( req , res ) => res . json ( p . getMetaItems ( req . params . type ) ) ) ;
77+ this . server . get ( '/api/v1/meta/:type/:name' , ( req , res ) => {
9278 try {
93- return c . json ( p . getMetaItem ( c . req . param ( ' type' ) , c . req . param ( ' name' ) ) ) ;
79+ res . json ( p . getMetaItem ( req . params . type , req . params . name ) ) ;
9480 } catch ( e :any ) {
95- return c . json ( { error : e . message } , 404 ) ;
81+ res . status ( 404 ) . json ( { error : e . message } ) ;
9682 }
9783 } ) ;
9884
9985 // Data Protocol
100- this . app . get ( '/api/v1/data/:object' , async ( c ) => {
101- try { return c . json ( await p . findData ( c . req . param ( ' object' ) , c . req . query ( ) ) ) ; }
102- catch ( e :any ) { return c . json ( { error :e . message } , 400 ) ; }
86+ this . server . get ( '/api/v1/data/:object' , async ( req , res ) => {
87+ try { res . json ( await p . findData ( req . params . object , req . query ) ) ; }
88+ catch ( e :any ) { res . status ( 400 ) . json ( { error :e . message } ) ; }
10389 } ) ;
104- this . app . get ( '/api/v1/data/:object/:id' , async ( c ) => {
105- try { return c . json ( await p . getData ( c . req . param ( ' object' ) , c . req . param ( 'id' ) ) ) ; }
106- catch ( e :any ) { return c . json ( { error :e . message } , 404 ) ; }
90+ this . server . get ( '/api/v1/data/:object/:id' , async ( req , res ) => {
91+ try { res . json ( await p . getData ( req . params . object , req . params . id ) ) ; }
92+ catch ( e :any ) { res . status ( 404 ) . json ( { error :e . message } ) ; }
10793 } ) ;
108- this . app . post ( '/api/v1/data/:object' , async ( c ) => {
109- try { return c . json ( await p . createData ( c . req . param ( ' object' ) , await c . req . json ( ) ) , 201 ) ; }
110- catch ( e :any ) { return c . json ( { error :e . message } , 400 ) ; }
94+ this . server . post ( '/api/v1/data/:object' , async ( req , res ) => {
95+ try { res . status ( 201 ) . json ( await p . createData ( req . params . object , req . body ) ) ; }
96+ catch ( e :any ) { res . status ( 400 ) . json ( { error :e . message } ) ; }
11197 } ) ;
112- this . app . patch ( '/api/v1/data/:object/:id' , async ( c ) => {
113- try { return c . json ( await p . updateData ( c . req . param ( ' object' ) , c . req . param ( 'id' ) , await c . req . json ( ) ) ) ; }
114- catch ( e :any ) { return c . json ( { error :e . message } , 400 ) ; }
98+ this . server . patch ( '/api/v1/data/:object/:id' , async ( req , res ) => {
99+ try { res . json ( await p . updateData ( req . params . object , req . params . id , req . body ) ) ; }
100+ catch ( e :any ) { res . status ( 400 ) . json ( { error :e . message } ) ; }
115101 } ) ;
116- this . app . delete ( '/api/v1/data/:object/:id' , async ( c ) => {
117- try { return c . json ( await p . deleteData ( c . req . param ( ' object' ) , c . req . param ( 'id' ) ) ) ; }
118- catch ( e :any ) { return c . json ( { error :e . message } , 400 ) ; }
102+ this . server . delete ( '/api/v1/data/:object/:id' , async ( req , res ) => {
103+ try { res . json ( await p . deleteData ( req . params . object , req . params . id ) ) ; }
104+ catch ( e :any ) { res . status ( 400 ) . json ( { error :e . message } ) ; }
119105 } ) ;
120106
121107 // UI Protocol
122108 // @ts -ignore
123- this . app . get ( '/api/v1/ui/view/:object' , ( c ) => {
109+ this . server . get ( '/api/v1/ui/view/:object' , ( req , res ) => {
124110 try {
125- const viewType = ( c . req . query ( 'type' ) as 'list' | 'form' ) || 'list' ;
126- return c . json ( p . getUiView ( c . req . param ( 'object' ) , viewType ) ) ;
111+ const viewType = ( req . query . type ) || 'list' ;
112+ const qt = Array . isArray ( viewType ) ? viewType [ 0 ] : viewType ;
113+ res . json ( p . getUiView ( req . params . object , qt as any ) ) ;
127114 }
128- catch ( e :any ) { return c . json ( { error :e . message } , 404 ) ; }
115+ catch ( e :any ) { res . status ( 404 ) . json ( { error :e . message } ) ; }
129116 } ) ;
130117 }
131118
132- // Static files
133- if ( this . options . staticRoot ) {
134- this . app . get ( '/' , serveStatic ( { root : this . options . staticRoot , path : 'index.html' } ) ) ;
135- this . app . get ( '/*' , serveStatic ( { root : this . options . staticRoot } ) ) ;
136- }
137-
138119 // Start server on kernel:ready hook
139- ctx . hook ( 'kernel:ready' , ( ) => {
140- const port = this . options . port ;
120+ ctx . hook ( 'kernel:ready' , async ( ) => {
121+ const port = this . options . port || 3000 ;
141122 ctx . logger . log ( '[HonoServerPlugin] Starting server...' ) ;
142- ctx . logger . log ( `✅ Server is running on http://localhost:${ port } ` ) ;
143123
144- this . server = serve ( {
145- fetch : this . app . fetch ,
146- port
147- } ) ;
124+ await this . server . listen ( port ) ;
125+ ctx . logger . log ( `✅ Server is running on http://localhost:${ port } ` ) ;
148126 } ) ;
149127 }
150128
151129 /**
152130 * Destroy phase - Stop server
153131 */
154132 async destroy ( ) {
155- // Note: Hono's serve function may not return a server with close method
156- // This is a best-effort cleanup
157- if ( this . server && typeof this . server . close === 'function' ) {
158- this . server . close ( ) ;
159- console . log ( '[HonoServerPlugin] Server stopped' ) ;
160- }
133+ this . server . close ( ) ;
134+ console . log ( '[HonoServerPlugin] Server stopped' ) ;
161135 }
162136}
0 commit comments