@@ -208,6 +208,64 @@ export class ObjectStackClient {
208208 }
209209 } ;
210210
211+ /**
212+ * Analytics Services
213+ */
214+ analytics = {
215+ query : async ( payload : any ) => {
216+ const route = this . getRoute ( 'analytics' ) ;
217+ const res = await this . fetch ( `${ this . baseUrl } ${ route } /query` , {
218+ method : 'POST' ,
219+ body : JSON . stringify ( payload )
220+ } ) ;
221+ return res . json ( ) ;
222+ } ,
223+ meta : async ( cube : string ) => {
224+ const route = this . getRoute ( 'analytics' ) ;
225+ const res = await this . fetch ( `${ this . baseUrl } ${ route } /meta/${ cube } ` ) ;
226+ return res . json ( ) ;
227+ } ,
228+ explain : async ( payload : any ) => {
229+ const route = this . getRoute ( 'analytics' ) ;
230+ const res = await this . fetch ( `${ this . baseUrl } ${ route } /explain` , {
231+ method : 'POST' ,
232+ body : JSON . stringify ( payload )
233+ } ) ;
234+ return res . json ( ) ;
235+ }
236+ } ;
237+
238+ /**
239+ * Hub Management Services
240+ */
241+ hub = {
242+ spaces : {
243+ list : async ( ) => {
244+ const route = this . getRoute ( 'hub' ) ;
245+ const res = await this . fetch ( `${ this . baseUrl } ${ route } /spaces` ) ;
246+ return res . json ( ) ;
247+ } ,
248+ create : async ( payload : any ) => {
249+ const route = this . getRoute ( 'hub' ) ;
250+ const res = await this . fetch ( `${ this . baseUrl } ${ route } /spaces` , {
251+ method : 'POST' ,
252+ body : JSON . stringify ( payload )
253+ } ) ;
254+ return res . json ( ) ;
255+ }
256+ } ,
257+ plugins : {
258+ install : async ( pkg : string , version ?: string ) => {
259+ const route = this . getRoute ( 'hub' ) ;
260+ const res = await this . fetch ( `${ this . baseUrl } ${ route } /plugins/install` , {
261+ method : 'POST' ,
262+ body : JSON . stringify ( { pkg, version } )
263+ } ) ;
264+ return res . json ( ) ;
265+ }
266+ }
267+ } ;
268+
211269 /**
212270 * Data Operations
213271 */
@@ -443,15 +501,24 @@ export class ObjectStackClient {
443501
444502 /**
445503 * Get the conventional route path for a given API endpoint type
446- * ObjectStack uses standard conventions: /api/v1/data, /api/v1/meta , /api/v1/ui
504+ * ObjectStack uses standard conventions: /api/v1/data, /api/v1/metadata , /api/v1/ui
447505 */
448- private getRoute ( type : 'data' | 'metadata' | 'ui' | 'auth' ) : string {
449- // Use conventional ObjectStack API paths
506+ private getRoute ( type : 'data' | 'metadata' | 'ui' | 'auth' | 'analytics' | 'hub' | 'storage' ) : string {
507+ // 1. Use discovered routes if available
508+ if ( this . discoveryInfo ?. routes && ( this . discoveryInfo . routes as any ) [ type ] ) {
509+ return ( this . discoveryInfo . routes as any ) [ type ] ;
510+ }
511+
512+ // 2. Fallback to conventions
513+ // Note: HttpDispatcher expects /metadata, not /meta
450514 const routeMap : Record < string , string > = {
451515 data : '/api/v1/data' ,
452- metadata : '/api/v1/meta ' ,
516+ metadata : '/api/v1/metadata ' ,
453517 ui : '/api/v1/ui' ,
454- auth : '/api/v1/auth'
518+ auth : '/api/v1/auth' ,
519+ analytics : '/api/v1/analytics' ,
520+ hub : '/api/v1/hub' ,
521+ storage : '/api/v1/storage'
455522 } ;
456523
457524 return routeMap [ type ] || `/api/v1/${ type } ` ;
0 commit comments