11import { NextRequest , NextResponse } from 'next/server' ;
2- import { type ObjectKernel } from '@objectstack/runtime' ;
2+ import { type ObjectKernel , HttpDispatcher } from '@objectstack/runtime' ;
33
44export interface NextAdapterOptions {
55 kernel : ObjectKernel ;
@@ -12,85 +12,46 @@ export interface NextAdapterOptions {
1212 */
1313export function createRouteHandler ( options : NextAdapterOptions ) {
1414 const kernel = options . kernel as any ;
15+ const dispatcher = new HttpDispatcher ( options . kernel ) ;
1516
1617 const success = ( data : any , meta ?: any ) => NextResponse . json ( { success : true , data, meta } ) ;
1718 const error = ( msg : string , code : number = 500 ) => NextResponse . json ( { success : false , error : { message : msg , code } } , { status : code } ) ;
1819
1920 return async function handler ( req : NextRequest , { params } : { params : { objectstack : string [ ] } } ) {
20- const segments = params . objectstack || [ ] ;
21+ const resolvedParams = await Promise . resolve ( params ) ;
22+ const segments = resolvedParams . objectstack || [ ] ;
2123 const method = req . method ;
2224
23- // Parse path: /api/...segments...
24- // e.g., /api/graphql
25- // /api/metadata
26- // /api/data/contacts/query
27-
2825 // --- 0. Discovery Endpoint ---
2926 if ( segments . length === 0 && method === 'GET' ) {
30- const prefix = options . prefix || '/api' ;
31- const services = ( kernel as any ) . services || { } ;
32- const hasGraphQL = ! ! ( services [ 'graphql' ] || ( kernel as any ) . graphql ) ;
33- const hasSearch = ! ! services [ 'search' ] ;
34- const hasWebSockets = ! ! services [ 'realtime' ] ;
35- const hasFiles = ! ! ( services [ 'file-storage' ] || services [ 'storage' ] ?. supportsFiles ) ;
36-
37- return NextResponse . json ( {
38- name : 'ObjectOS' ,
39- version : '1.0.0' ,
40- environment : process . env . NODE_ENV || 'development' ,
41- routes : {
42- data : `${ prefix } /data` ,
43- metadata : `${ prefix } /metadata` ,
44- auth : `${ prefix } /auth` ,
45- graphql : hasGraphQL ? `${ prefix } /graphql` : undefined ,
46- storage : hasFiles ? `${ prefix } /storage` : undefined ,
47- } ,
48- features : {
49- graphql : hasGraphQL ,
50- search : hasSearch ,
51- websockets : hasWebSockets ,
52- files : hasFiles ,
53- } ,
54- } ) ;
27+ return NextResponse . json ( dispatcher . getDiscoveryInfo ( options . prefix || '/api' ) ) ;
5528 }
5629
5730 // --- 1. Auth (Generic Auth Handler) ---
5831 if ( segments [ 0 ] === 'auth' ) {
59- const authService = ( kernel as any ) . getService ?.( 'auth' ) || ( kernel as any ) . services ?. [ 'auth' ] ;
60- if ( authService && authService . handler ) {
61- return authService . handler ( req ) ;
62- }
63-
64- // Fallback for /api/auth/login
65- if ( segments [ 1 ] === 'login' && method === 'POST' ) {
66- try {
67- // Clone request body because it might be consumed by handler above? No, we checked availability.
68- const body = await req . json ( ) ;
69- const data = await kernel . broker . call ( 'auth.login' , body , { request : req } ) ;
70- return NextResponse . json ( data ) ;
71- } catch ( e : any ) {
72- return error ( e . message , e . statusCode || 500 ) ;
73- }
32+ const subPath = segments . slice ( 1 ) . join ( '/' ) ;
33+ try {
34+ const body = method === 'POST' ? await req . json ( ) . catch ( ( ) => ( { } ) ) : { } ;
35+ const result = await dispatcher . handleAuth ( subPath , method , body , { request : req } ) ;
36+ if ( result . handled ) {
37+ if ( result . response ) {
38+ return NextResponse . json ( result . response . body , { status : result . response . status } ) ;
39+ }
40+ if ( result . result ) return result . result ;
41+ }
42+ return error ( 'Auth provider not configured' , 404 ) ;
43+ } catch ( e : any ) {
44+ return error ( e . message , e . statusCode || 500 ) ;
7445 }
75- return error ( 'Auth provider not configured' , 404 ) ;
7646 }
7747
7848 try {
7949 const rawRequest = req ;
8050
81- // 0. Auth
82- if ( segments [ 0 ] === 'auth' ) {
83- if ( segments [ 1 ] === 'login' && method === 'POST' ) {
84- const body = await req . json ( ) as any ;
85- const data = await kernel . broker . call ( 'auth.login' , body , { request : rawRequest } ) ;
86- return NextResponse . json ( data ) ;
87- }
88- }
89-
9051 // 1. GraphQL
9152 if ( segments [ 0 ] === 'graphql' && method === 'POST' ) {
92- const body = await req . json ( ) as any ;
93- const result = await kernel . graphql ( body . query , body . variables , { request : rawRequest } ) ;
53+ const body = await req . json ( ) ;
54+ const result = await dispatcher . handleGraphQL ( body , { request : rawRequest } ) ;
9455 return NextResponse . json ( result ) ;
9556 }
9657
@@ -142,7 +103,7 @@ export function createRouteHandler(options: NextAdapterOptions) {
142103 if ( segments . length === 2 && method === 'POST' ) {
143104 const body = await req . json ( ) ;
144105 const data = await kernel . broker . call ( 'data.create' , { object : objectName , data : body } , { request : rawRequest } ) ;
145- return success ( data ) ; // 201 not easy with helper, but ok
106+ return success ( data ) ;
146107 }
147108
148109 // GET /data/:objectName/:id
0 commit comments