@objectstack/plugin-hono-server 0.9.1 → 1.0.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @objectstack/plugin-hono-server
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Major version release for ObjectStack Protocol v1.0.
8
+ - Stabilized Protocol Definitions
9
+ - Enhanced Runtime Plugin Support
10
+ - Fixed Type Compliance across Monorepo
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ - @objectstack/spec@1.0.0
16
+ - @objectstack/core@1.0.0
17
+ - @objectstack/types@1.0.0
18
+
19
+ ## 0.9.2
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies
24
+ - @objectstack/spec@0.9.2
25
+ - @objectstack/core@0.9.2
26
+ - @objectstack/types@0.9.2
27
+
3
28
  ## 0.9.1
4
29
 
5
30
  ### Patch Changes
package/README.md CHANGED
@@ -1,499 +1,19 @@
1
1
  # @objectstack/plugin-hono-server
2
2
 
3
- HTTP Server Adapter for ObjectStack Runtime using the [Hono](https://hono.dev/) framework. This plugin provides a production-ready REST API gateway for ObjectStack applications.
4
-
5
- ## Plugin Capabilities
6
-
7
- This plugin implements the ObjectStack plugin capability protocol:
8
- - **Type**: `adapter`
9
- - **Protocol**: `com.objectstack.protocol.http.v1` (full conformance)
10
- - **Protocol**: `com.objectstack.protocol.api.rest.v1` (full conformance)
11
- - **Provides**: `IHttpServer` interface for HTTP server operations
12
- - **Requires**: `com.objectstack.engine.objectql` (optional) for protocol implementation
13
- - **Extension Points**:
14
- - `middleware` - Register custom HTTP middleware
15
- - `route` - Register custom API routes
16
-
17
- See [objectstack.config.ts](./objectstack.config.ts) for the complete capability manifest.
3
+ HTTP Server adapter for ObjectStack using Hono.
18
4
 
19
5
  ## Features
20
6
 
21
- - 🚀 **High Performance**: Built on Hono, one of the fastest web frameworks
22
- - 🌐 **Universal**: Works in Node.js, Deno, Bun, and edge runtimes
23
- - 🔒 **Type Safe**: Fully typed with TypeScript
24
- - 📡 **REST API**: Complete ObjectStack Runtime Protocol implementation
25
- - 🎯 **Auto-Discovery**: Automatic endpoint registration
26
- - 🔌 **Extensible**: Easy to add custom routes and middleware
27
-
28
- ## Installation
29
-
30
- ```bash
31
- pnpm add @objectstack/plugin-hono-server hono @hono/node-server
32
- ```
7
+ - **Fast**: Built on Hono, a high-performance web framework.
8
+ - **Protocol Compliant**: Implements the `IHttpServer` interface required by `@objectstack/runtime`.
9
+ - **Middleware**: Supports standard ObjectStack middleware.
33
10
 
34
11
  ## Usage
35
12
 
36
- ### Basic Setup
37
-
38
13
  ```typescript
14
+ import { ObjectKernel } from '@objectstack/core';
39
15
  import { HonoServerPlugin } from '@objectstack/plugin-hono-server';
40
- import { ObjectKernel } from '@objectstack/runtime';
41
16
 
42
17
  const kernel = new ObjectKernel();
43
-
44
- // Register the server plugin
45
- kernel.use(new HonoServerPlugin({
46
- port: 3000,
47
- staticRoot: './public' // Optional: serve static files
48
- }));
49
-
50
- await kernel.bootstrap();
51
-
52
- // Server starts automatically when kernel is ready
53
- // API available at: http://localhost:3000/api/v1
54
- ```
55
-
56
- ### With Custom Port
57
-
58
- ```typescript
59
- const plugin = new HonoServerPlugin({
60
- port: process.env.PORT || 8080
61
- });
62
-
63
- kernel.use(plugin);
64
- ```
65
-
66
- ### Configuration Options
67
-
68
- ```typescript
69
- interface HonoPluginOptions {
70
- /**
71
- * HTTP server port
72
- * @default 3000
73
- */
74
- port?: number;
75
-
76
- /**
77
- * Path to static files directory (optional)
78
- */
79
- staticRoot?: string;
80
-
81
- /**
82
- * REST server configuration
83
- * Controls automatic endpoint generation and API behavior
84
- */
85
- restConfig?: RestServerConfig;
86
-
87
- /**
88
- * Whether to register standard ObjectStack CRUD endpoints
89
- * @default true
90
- */
91
- registerStandardEndpoints?: boolean;
92
-
93
- /**
94
- * Whether to load endpoints from API Registry
95
- * When enabled, routes are loaded dynamically from the API Registry
96
- * When disabled, uses legacy static route registration
97
- * @default true
98
- */
99
- useApiRegistry?: boolean;
100
- }
101
- ```
102
-
103
- ### Using API Registry (New in v0.9.0)
104
-
105
- The plugin now integrates with the ObjectStack API Registry for centralized endpoint management:
106
-
107
- ```typescript
108
- import { createApiRegistryPlugin } from '@objectstack/core';
109
- import { HonoServerPlugin } from '@objectstack/plugin-hono-server';
110
-
111
- const kernel = new ObjectKernel();
112
-
113
- // 1. Register API Registry Plugin first
114
- kernel.use(createApiRegistryPlugin({
115
- conflictResolution: 'priority' // Handle route conflicts by priority
116
- }));
117
-
118
- // 2. Register Hono Server Plugin
119
- kernel.use(new HonoServerPlugin({
120
- port: 3000,
121
- useApiRegistry: true,
122
- registerStandardEndpoints: true,
123
- restConfig: {
124
- api: {
125
- version: 'v1',
126
- basePath: '/api',
127
- enableCrud: true,
128
- enableMetadata: true,
129
- enableBatch: true
130
- }
131
- }
132
- }));
133
-
134
- await kernel.bootstrap();
135
- ```
136
-
137
- **Benefits of API Registry Integration:**
138
- - 📋 Centralized endpoint registration and discovery
139
- - 🔀 Priority-based route conflict resolution
140
- - 🧩 Support for plugin-registered custom endpoints
141
- - ⚙️ Configurable endpoint generation via `RestServerConfig`
142
- - 🔍 API introspection and documentation generation
143
-
144
- ### Configuring REST Server Behavior
145
-
146
- Use `restConfig` to control which endpoints are automatically generated:
147
-
148
- ```typescript
149
- new HonoServerPlugin({
150
- restConfig: {
151
- api: {
152
- version: 'v2',
153
- basePath: '/api',
154
- enableCrud: true,
155
- enableMetadata: true,
156
- enableBatch: true,
157
- enableDiscovery: true
158
- },
159
- crud: {
160
- dataPrefix: '/data',
161
- operations: {
162
- create: true,
163
- read: true,
164
- update: true,
165
- delete: true,
166
- list: true
167
- }
168
- },
169
- metadata: {
170
- prefix: '/meta',
171
- enableCache: true,
172
- cacheTtl: 3600
173
- },
174
- batch: {
175
- maxBatchSize: 200,
176
- operations: {
177
- createMany: true,
178
- updateMany: true,
179
- deleteMany: true,
180
- upsertMany: true
181
- }
182
- }
183
- }
184
- })
185
- ```
186
-
187
- ### Legacy Mode (Without API Registry)
188
-
189
- If the API Registry plugin is not registered, the server automatically falls back to legacy mode:
190
-
191
- ```typescript
192
- // No API Registry needed for simple setups
193
- const kernel = new ObjectKernel();
194
-
195
- kernel.use(new HonoServerPlugin({
196
- port: 3000,
197
- useApiRegistry: false // Explicitly disable API Registry
198
- }));
199
-
200
- await kernel.bootstrap();
201
- // All standard routes registered statically
202
- ```
203
-
204
- ## API Endpoints
205
-
206
- The plugin automatically exposes the following ObjectStack REST API endpoints:
207
-
208
- ### Discovery
209
-
210
- ```http
211
- GET /api/v1
212
- ```
213
-
214
- Returns API discovery information including available endpoints and versions.
215
-
216
- ### Metadata Protocol
217
-
218
- ```http
219
- GET /api/v1/meta
220
- GET /api/v1/meta/:type
221
- GET /api/v1/meta/:type/:name
222
- ```
223
-
224
- Retrieve metadata about objects, views, and other system definitions.
225
-
226
- ### Data Protocol (CRUD Operations)
227
-
228
- ```http
229
- GET /api/v1/data/:object # Find records
230
- GET /api/v1/data/:object/:id # Get record by ID
231
- POST /api/v1/data/:object # Create record
232
- PATCH /api/v1/data/:object/:id # Update record
233
- DELETE /api/v1/data/:object/:id # Delete record
234
- ```
235
-
236
- Example requests:
237
-
238
- ```bash
239
- # Get all users
240
- curl http://localhost:3000/api/v1/data/user
241
-
242
- # Get user by ID
243
- curl http://localhost:3000/api/v1/data/user/123
244
-
245
- # Create a user
246
- curl -X POST http://localhost:3000/api/v1/data/user \
247
- -H "Content-Type: application/json" \
248
- -d '{"name":"John Doe","email":"john@example.com"}'
249
-
250
- # Update a user
251
- curl -X PATCH http://localhost:3000/api/v1/data/user/123 \
252
- -H "Content-Type: application/json" \
253
- -d '{"name":"Jane Doe"}'
254
-
255
- # Delete a user
256
- curl -X DELETE http://localhost:3000/api/v1/data/user/123
257
- ```
258
-
259
- ### UI Protocol
260
-
261
- ```http
262
- GET /api/v1/ui/view/:object?type=list|form
263
- ```
264
-
265
- Retrieve UI view configurations for objects.
266
-
267
- ## Advanced Usage
268
-
269
- ### Accessing the HTTP Server Instance
270
-
271
- The server instance is registered as a service and can be accessed by other plugins:
272
-
273
- ```typescript
274
- export class MyPlugin implements Plugin {
275
- name = 'my-custom-plugin';
276
-
277
- async start(ctx: PluginContext) {
278
- const httpServer = ctx.getService<IHttpServer>('http-server');
279
-
280
- // Add custom routes
281
- httpServer.get('/api/custom', (req, res) => {
282
- res.json({ message: 'Custom endpoint' });
283
- });
284
- }
285
- }
18
+ kernel.use(new HonoServerPlugin({ port: 3000 }));
286
19
  ```
287
-
288
- ### Registering Custom Endpoints via API Registry
289
-
290
- Plugins can register their own endpoints through the API Registry:
291
-
292
- ```typescript
293
- export class MyApiPlugin implements Plugin {
294
- name = 'my-api-plugin';
295
- version = '1.0.0';
296
-
297
- async init(ctx: PluginContext) {
298
- const apiRegistry = ctx.getService<ApiRegistry>('api-registry');
299
-
300
- apiRegistry.registerApi({
301
- id: 'my_custom_api',
302
- name: 'My Custom API',
303
- type: 'rest',
304
- version: 'v1',
305
- basePath: '/api/v1/custom',
306
- endpoints: [
307
- {
308
- id: 'get_custom_data',
309
- method: 'GET',
310
- path: '/api/v1/custom/data',
311
- summary: 'Get custom data',
312
- priority: 500, // Lower than core endpoints (950)
313
- responses: [{
314
- statusCode: 200,
315
- description: 'Custom data retrieved'
316
- }]
317
- }
318
- ],
319
- metadata: {
320
- pluginSource: 'my-api-plugin',
321
- status: 'active',
322
- tags: ['custom']
323
- }
324
- });
325
-
326
- ctx.logger.info('Custom API endpoints registered');
327
- }
328
-
329
- async start(ctx: PluginContext) {
330
- // Bind the actual handler implementation
331
- const httpServer = ctx.getService<IHttpServer>('http-server');
332
-
333
- httpServer.get('/api/v1/custom/data', async (req, res) => {
334
- res.json({ data: 'my custom data' });
335
- });
336
- }
337
- }
338
- ```
339
-
340
- **Note:** The Hono Server Plugin loads routes from the API Registry sorted by priority (highest first), ensuring core endpoints take precedence over plugin endpoints.
341
-
342
- ### Extending with Middleware
343
-
344
- The plugin provides extension points for adding custom middleware:
345
-
346
- ```typescript
347
- // In another plugin's manifest
348
- capabilities: {
349
- extensions: [
350
- {
351
- targetPluginId: 'com.objectstack.server.hono',
352
- extensionPointId: 'com.objectstack.server.hono.extension.middleware',
353
- implementation: './middleware/auth.ts',
354
- priority: 10
355
- }
356
- ]
357
- }
358
- ```
359
-
360
- ### Custom Route Registration
361
-
362
- ```typescript
363
- // In another plugin's manifest
364
- capabilities: {
365
- extensions: [
366
- {
367
- targetPluginId: 'com.objectstack.server.hono',
368
- extensionPointId: 'com.objectstack.server.hono.extension.route',
369
- implementation: './routes/webhooks.ts',
370
- priority: 50
371
- }
372
- ]
373
- }
374
- ```
375
-
376
- ## Architecture
377
-
378
- The Hono Server Plugin follows a clean architecture:
379
-
380
- ```
381
- ┌─────────────────────────────────┐
382
- │ HonoServerPlugin │
383
- │ (Plugin Lifecycle) │
384
- └────────────┬────────────────────┘
385
-
386
- ├─ init() → Register HTTP server service
387
- ├─ start() → Bind routes, start server
388
- └─ destroy() → Stop server
389
-
390
-
391
- ┌─────────────────────┐
392
- │ HonoHttpServer │
393
- │ (Adapter) │
394
- └──────┬──────────────┘
395
-
396
-
397
- ┌─────────────────────┐
398
- │ Hono Framework │
399
- │ (Core Library) │
400
- └─────────────────────┘
401
- ```
402
-
403
- ## Plugin Lifecycle
404
-
405
- 1. **Init Phase**:
406
- - Creates HonoHttpServer instance
407
- - Registers as `http-server` service
408
-
409
- 2. **Start Phase**:
410
- - Retrieves protocol implementation service
411
- - Registers all ObjectStack API routes
412
- - Sets up lifecycle hooks
413
-
414
- 3. **Ready Hook** (`kernel:ready`):
415
- - Starts HTTP server on configured port
416
- - Logs server URL
417
-
418
- 4. **Destroy Phase**:
419
- - Gracefully closes server
420
- - Cleans up resources
421
-
422
- ## Error Handling
423
-
424
- The plugin includes comprehensive error handling:
425
-
426
- ```typescript
427
- // 404 Not Found
428
- GET /api/v1/data/user/999
429
- → { "error": "Record not found" }
430
-
431
- // 400 Bad Request
432
- POST /api/v1/data/user (invalid data)
433
- → { "error": "Validation failed: email is required" }
434
- ```
435
-
436
- ## Production Deployment
437
-
438
- ### Environment Variables
439
-
440
- ```bash
441
- PORT=8080
442
- NODE_ENV=production
443
- ```
444
-
445
- ### Docker Example
446
-
447
- ```dockerfile
448
- FROM node:20-alpine
449
- WORKDIR /app
450
- COPY package.json pnpm-lock.yaml ./
451
- RUN npm install -g pnpm && pnpm install --frozen-lockfile
452
- COPY . .
453
- RUN pnpm build
454
- EXPOSE 8080
455
- CMD ["node", "dist/index.js"]
456
- ```
457
-
458
- ### Serverless Deployment
459
-
460
- Hono works seamlessly with serverless platforms:
461
-
462
- ```typescript
463
- // Cloudflare Workers, Vercel Edge, etc.
464
- export default {
465
- async fetch(request: Request) {
466
- const app = createHonoApp();
467
- return app.fetch(request);
468
- }
469
- }
470
- ```
471
-
472
- ## Performance
473
-
474
- Hono is designed for performance:
475
- - ⚡ One of the fastest web frameworks for Node.js
476
- - 🪶 Minimal overhead and memory footprint
477
- - 🚀 Optimized routing with RegExpRouter
478
- - 📦 Small bundle size (~12KB)
479
-
480
- ## Comparison with Other Adapters
481
-
482
- | Feature | Hono | Express | Fastify |
483
- |---------|------|---------|---------|
484
- | Universal Runtime | ✅ | ❌ | ❌ |
485
- | Edge Support | ✅ | ❌ | ❌ |
486
- | TypeScript | ✅ | Partial | ✅ |
487
- | Performance | Excellent | Good | Excellent |
488
- | Bundle Size | 12KB | 208KB | 28KB |
489
-
490
- ## License
491
-
492
- Apache-2.0
493
-
494
- ## Related Packages
495
-
496
- - [@objectstack/runtime](../../runtime) - ObjectStack Runtime
497
- - [@objectstack/spec](../../spec) - ObjectStack Specifications
498
- - [hono](https://hono.dev/) - Hono Web Framework
499
- - [@hono/node-server](https://github.com/honojs/node-server) - Node.js adapter for Hono
@@ -37,7 +37,7 @@ export declare class HonoServerPlugin implements Plugin {
37
37
  /**
38
38
  * Init phase - Setup HTTP server and register as service
39
39
  */
40
- init(ctx: PluginContext): Promise<void>;
40
+ init: (ctx: PluginContext) => Promise<void>;
41
41
  /**
42
42
  * Helper to create cache request object from HTTP headers
43
43
  */
@@ -45,7 +45,7 @@ export declare class HonoServerPlugin implements Plugin {
45
45
  /**
46
46
  * Start phase - Bind routes and start listening
47
47
  */
48
- start(ctx: PluginContext): Promise<void>;
48
+ start: (ctx: PluginContext) => Promise<void>;
49
49
  /**
50
50
  * Register standard ObjectStack API endpoints to the API Registry
51
51
  */
@@ -29,7 +29,7 @@ class HonoServerPlugin {
29
29
  /**
30
30
  * Init phase - Setup HTTP server and register as service
31
31
  */
32
- async init(ctx) {
32
+ init = async (ctx) => {
33
33
  ctx.logger.debug('Initializing Hono server plugin', {
34
34
  port: this.options.port,
35
35
  staticRoot: this.options.staticRoot
@@ -37,7 +37,7 @@ class HonoServerPlugin {
37
37
  // Register HTTP server service as IHttpServer
38
38
  ctx.registerService('http-server', this.server);
39
39
  ctx.logger.info('HTTP server service registered', { serviceName: 'http-server' });
40
- }
40
+ };
41
41
  /**
42
42
  * Helper to create cache request object from HTTP headers
43
43
  */
@@ -50,7 +50,7 @@ class HonoServerPlugin {
50
50
  /**
51
51
  * Start phase - Bind routes and start listening
52
52
  */
53
- async start(ctx) {
53
+ start = async (ctx) => {
54
54
  ctx.logger.debug('Starting Hono server plugin');
55
55
  // Get protocol implementation instance
56
56
  let protocol = null;
@@ -93,7 +93,7 @@ class HonoServerPlugin {
93
93
  url: `http://localhost:${port}`
94
94
  });
95
95
  });
96
- }
96
+ };
97
97
  /**
98
98
  * Register standard ObjectStack API endpoints to the API Registry
99
99
  */
@@ -450,6 +450,60 @@ class HonoServerPlugin {
450
450
  ],
451
451
  priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
452
452
  });
453
+ // Analytics Endpoints
454
+ endpoints.push({
455
+ id: 'analytics_query',
456
+ method: 'POST',
457
+ path: `${apiPath}/analytics/query`,
458
+ summary: 'Analytics Query',
459
+ description: 'Execute analytics query',
460
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
461
+ }, {
462
+ id: 'get_analytics_meta',
463
+ method: 'GET',
464
+ path: `${apiPath}/analytics/meta`,
465
+ summary: 'Analytics Metadata',
466
+ description: 'Get analytics cubes definitions',
467
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
468
+ });
469
+ // Automation Endpoints
470
+ endpoints.push({
471
+ id: 'automation_trigger',
472
+ method: 'POST',
473
+ path: `${apiPath}/automation/trigger/:trigger`,
474
+ summary: 'Trigger Automation',
475
+ description: 'Trigger a named automation',
476
+ parameters: [{
477
+ name: 'trigger',
478
+ in: 'path',
479
+ required: true,
480
+ schema: { type: 'string' }
481
+ }],
482
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
483
+ });
484
+ // Hub Endpoints
485
+ endpoints.push({
486
+ id: 'hub_list_spaces',
487
+ method: 'GET',
488
+ path: `${apiPath}/hub/spaces`,
489
+ summary: 'List Spaces',
490
+ description: 'List all Hub spaces',
491
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
492
+ }, {
493
+ id: 'hub_create_space',
494
+ method: 'POST',
495
+ path: `${apiPath}/hub/spaces`,
496
+ summary: 'Create Space',
497
+ description: 'Create a new Hub space',
498
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
499
+ }, {
500
+ id: 'hub_install_plugin',
501
+ method: 'POST',
502
+ path: `${apiPath}/hub/plugins/install`,
503
+ summary: 'Install Plugin',
504
+ description: 'Install a plugin from marketplace',
505
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
506
+ });
453
507
  // Register the API in the registry
454
508
  const apiEntry = {
455
509
  id: 'objectstack_core_api',
@@ -733,6 +787,71 @@ class HonoServerPlugin {
733
787
  ctx.logger.warn('UI view not found', { object: req.params.object });
734
788
  res.status(404).json({ error: e.message });
735
789
  }
790
+ },
791
+ // Analytics
792
+ 'analytics_query': async (req, res) => {
793
+ ctx.logger.info('Analytics query request');
794
+ try {
795
+ const result = await p.analyticsQuery(req.body);
796
+ res.json(result);
797
+ }
798
+ catch (e) {
799
+ ctx.logger.error('Analytics query failed', e);
800
+ res.status(400).json({ error: e.message });
801
+ }
802
+ },
803
+ 'get_analytics_meta': async (req, res) => {
804
+ ctx.logger.info('Analytics meta request');
805
+ try {
806
+ const result = await p.getAnalyticsMeta({});
807
+ res.json(result);
808
+ }
809
+ catch (e) {
810
+ ctx.logger.error('Analytics meta failed', e);
811
+ res.status(500).json({ error: e.message });
812
+ }
813
+ },
814
+ // Automation
815
+ 'automation_trigger': async (req, res) => {
816
+ const trigger = req.params.trigger;
817
+ ctx.logger.info('Automation trigger request', { trigger });
818
+ try {
819
+ const result = await p.triggerAutomation({ trigger, payload: req.body });
820
+ res.json(result);
821
+ }
822
+ catch (e) {
823
+ ctx.logger.error('Automation trigger failed', e, { trigger });
824
+ res.status(500).json({ error: e.message });
825
+ }
826
+ },
827
+ // Hub
828
+ 'hub_list_spaces': async (req, res) => {
829
+ try {
830
+ const result = await p.listSpaces({ ...req.query });
831
+ res.json(result);
832
+ }
833
+ catch (e) {
834
+ res.status(500).json({ error: e.message });
835
+ }
836
+ },
837
+ 'hub_create_space': async (req, res) => {
838
+ try {
839
+ const result = await p.createSpace(req.body);
840
+ res.status(201).json(result);
841
+ }
842
+ catch (e) {
843
+ res.status(500).json({ error: e.message });
844
+ }
845
+ },
846
+ 'hub_install_plugin': async (req, res) => {
847
+ const spaceId = req.params.space_id;
848
+ try {
849
+ const result = await p.installPlugin({ spaceId, ...req.body });
850
+ res.json(result);
851
+ }
852
+ catch (e) {
853
+ res.status(500).json({ error: e.message });
854
+ }
736
855
  }
737
856
  };
738
857
  return handlerMap[endpointId];
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@objectstack/plugin-hono-server",
3
- "version": "0.9.1",
3
+ "version": "1.0.0",
4
+ "license": "Apache-2.0",
4
5
  "description": "Standard Hono Server Adapter for ObjectStack Runtime",
5
6
  "main": "dist/index.js",
6
7
  "types": "dist/index.d.ts",
7
8
  "dependencies": {
8
9
  "@hono/node-server": "^1.2.0",
9
10
  "hono": "^4.0.0",
10
- "@objectstack/core": "0.9.1",
11
- "@objectstack/spec": "0.9.1",
12
- "@objectstack/types": "0.9.1"
11
+ "@objectstack/spec": "1.0.0",
12
+ "@objectstack/types": "1.0.0",
13
+ "@objectstack/core": "1.0.0"
13
14
  },
14
15
  "devDependencies": {
15
16
  "@types/node": "^25.1.0",
@@ -58,7 +58,7 @@ export class HonoServerPlugin implements Plugin {
58
58
  /**
59
59
  * Init phase - Setup HTTP server and register as service
60
60
  */
61
- async init(ctx: PluginContext) {
61
+ init = async (ctx: PluginContext) => {
62
62
  ctx.logger.debug('Initializing Hono server plugin', {
63
63
  port: this.options.port,
64
64
  staticRoot: this.options.staticRoot
@@ -82,7 +82,7 @@ export class HonoServerPlugin implements Plugin {
82
82
  /**
83
83
  * Start phase - Bind routes and start listening
84
84
  */
85
- async start(ctx: PluginContext) {
85
+ start = async (ctx: PluginContext) => {
86
86
  ctx.logger.debug('Starting Hono server plugin');
87
87
 
88
88
  // Get protocol implementation instance
@@ -507,6 +507,72 @@ export class HonoServerPlugin implements Plugin {
507
507
  priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
508
508
  });
509
509
 
510
+ // Analytics Endpoints
511
+ endpoints.push(
512
+ {
513
+ id: 'analytics_query',
514
+ method: 'POST',
515
+ path: `${apiPath}/analytics/query`,
516
+ summary: 'Analytics Query',
517
+ description: 'Execute analytics query',
518
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
519
+ },
520
+ {
521
+ id: 'get_analytics_meta',
522
+ method: 'GET',
523
+ path: `${apiPath}/analytics/meta`,
524
+ summary: 'Analytics Metadata',
525
+ description: 'Get analytics cubes definitions',
526
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
527
+ }
528
+ );
529
+
530
+ // Automation Endpoints
531
+ endpoints.push(
532
+ {
533
+ id: 'automation_trigger',
534
+ method: 'POST',
535
+ path: `${apiPath}/automation/trigger/:trigger`,
536
+ summary: 'Trigger Automation',
537
+ description: 'Trigger a named automation',
538
+ parameters: [{
539
+ name: 'trigger',
540
+ in: 'path',
541
+ required: true,
542
+ schema: { type: 'string' }
543
+ }],
544
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
545
+ }
546
+ );
547
+
548
+ // Hub Endpoints
549
+ endpoints.push(
550
+ {
551
+ id: 'hub_list_spaces',
552
+ method: 'GET',
553
+ path: `${apiPath}/hub/spaces`,
554
+ summary: 'List Spaces',
555
+ description: 'List all Hub spaces',
556
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
557
+ },
558
+ {
559
+ id: 'hub_create_space',
560
+ method: 'POST',
561
+ path: `${apiPath}/hub/spaces`,
562
+ summary: 'Create Space',
563
+ description: 'Create a new Hub space',
564
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
565
+ },
566
+ {
567
+ id: 'hub_install_plugin',
568
+ method: 'POST',
569
+ path: `${apiPath}/hub/plugins/install`,
570
+ summary: 'Install Plugin',
571
+ description: 'Install a plugin from marketplace',
572
+ priority: HonoServerPlugin.DISCOVERY_ENDPOINT_PRIORITY
573
+ }
574
+ );
575
+
510
576
  // Register the API in the registry
511
577
  const apiEntry: ApiRegistryEntryInput = {
512
578
  id: 'objectstack_core_api',
@@ -798,6 +864,65 @@ export class HonoServerPlugin implements Plugin {
798
864
  ctx.logger.warn('UI view not found', { object: req.params.object });
799
865
  res.status(404).json({ error: e.message });
800
866
  }
867
+ },
868
+ // Analytics
869
+ 'analytics_query': async (req: any, res: any) => {
870
+ ctx.logger.info('Analytics query request');
871
+ try {
872
+ const result = await p.analyticsQuery(req.body);
873
+ res.json(result);
874
+ } catch (e: any) {
875
+ ctx.logger.error('Analytics query failed', e);
876
+ res.status(400).json({ error: e.message });
877
+ }
878
+ },
879
+ 'get_analytics_meta': async (req: any, res: any) => {
880
+ ctx.logger.info('Analytics meta request');
881
+ try {
882
+ const result = await p.getAnalyticsMeta({});
883
+ res.json(result);
884
+ } catch (e: any) {
885
+ ctx.logger.error('Analytics meta failed', e);
886
+ res.status(500).json({ error: e.message });
887
+ }
888
+ },
889
+ // Automation
890
+ 'automation_trigger': async (req: any, res: any) => {
891
+ const trigger = req.params.trigger;
892
+ ctx.logger.info('Automation trigger request', { trigger });
893
+ try {
894
+ const result = await p.triggerAutomation({ trigger, payload: req.body });
895
+ res.json(result);
896
+ } catch (e: any) {
897
+ ctx.logger.error('Automation trigger failed', e, { trigger });
898
+ res.status(500).json({ error: e.message });
899
+ }
900
+ },
901
+ // Hub
902
+ 'hub_list_spaces': async (req: any, res: any) => {
903
+ try {
904
+ const result = await p.listSpaces({ ...req.query });
905
+ res.json(result);
906
+ } catch (e: any) {
907
+ res.status(500).json({ error: e.message });
908
+ }
909
+ },
910
+ 'hub_create_space': async (req: any, res: any) => {
911
+ try {
912
+ const result = await p.createSpace(req.body);
913
+ res.status(201).json(result);
914
+ } catch (e: any) {
915
+ res.status(500).json({ error: e.message });
916
+ }
917
+ },
918
+ 'hub_install_plugin': async (req: any, res: any) => {
919
+ const spaceId = req.params.space_id;
920
+ try {
921
+ const result = await p.installPlugin({ spaceId, ...req.body });
922
+ res.json(result);
923
+ } catch (e: any) {
924
+ res.status(500).json({ error: e.message });
925
+ }
801
926
  }
802
927
  };
803
928