@objectstack/plugin-hono-server 0.9.2 → 1.0.1

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,29 @@
1
1
  # @objectstack/plugin-hono-server
2
2
 
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @objectstack/spec@1.0.1
8
+ - @objectstack/core@1.0.1
9
+ - @objectstack/types@1.0.1
10
+
11
+ ## 1.0.0
12
+
13
+ ### Major Changes
14
+
15
+ - Major version release for ObjectStack Protocol v1.0.
16
+ - Stabilized Protocol Definitions
17
+ - Enhanced Runtime Plugin Support
18
+ - Fixed Type Compliance across Monorepo
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+ - @objectstack/spec@1.0.0
24
+ - @objectstack/core@1.0.0
25
+ - @objectstack/types@1.0.0
26
+
3
27
  ## 0.9.2
4
28
 
5
29
  ### Patch Changes
package/README.md CHANGED
@@ -1,506 +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
- ## 🤖 AI Development Context
6
-
7
- **Role**: HTTP Server Adapter
8
- **Usage**:
9
- - Replaces the default server implementation with Hono.
10
- - Ideal for Edge runtimes (Cloudflare Workers, etc.).
11
-
12
- ## Plugin Capabilities
13
-
14
- This plugin implements the ObjectStack plugin capability protocol:
15
- - **Type**: `adapter`
16
- - **Protocol**: `com.objectstack.protocol.http.v1` (full conformance)
17
- - **Protocol**: `com.objectstack.protocol.api.rest.v1` (full conformance)
18
- - **Provides**: `IHttpServer` interface for HTTP server operations
19
- - **Requires**: `com.objectstack.engine.objectql` (optional) for protocol implementation
20
- - **Extension Points**:
21
- - `middleware` - Register custom HTTP middleware
22
- - `route` - Register custom API routes
23
-
24
- See [objectstack.config.ts](./objectstack.config.ts) for the complete capability manifest.
3
+ HTTP Server adapter for ObjectStack using Hono.
25
4
 
26
5
  ## Features
27
6
 
28
- - 🚀 **High Performance**: Built on Hono, one of the fastest web frameworks
29
- - 🌐 **Universal**: Works in Node.js, Deno, Bun, and edge runtimes
30
- - 🔒 **Type Safe**: Fully typed with TypeScript
31
- - 📡 **REST API**: Complete ObjectStack Runtime Protocol implementation
32
- - 🎯 **Auto-Discovery**: Automatic endpoint registration
33
- - 🔌 **Extensible**: Easy to add custom routes and middleware
34
-
35
- ## Installation
36
-
37
- ```bash
38
- pnpm add @objectstack/plugin-hono-server hono @hono/node-server
39
- ```
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.
40
10
 
41
11
  ## Usage
42
12
 
43
- ### Basic Setup
44
-
45
13
  ```typescript
14
+ import { ObjectKernel } from '@objectstack/core';
46
15
  import { HonoServerPlugin } from '@objectstack/plugin-hono-server';
47
- import { ObjectKernel } from '@objectstack/runtime';
48
-
49
- const kernel = new ObjectKernel();
50
-
51
- // Register the server plugin
52
- kernel.use(new HonoServerPlugin({
53
- port: 3000,
54
- staticRoot: './public' // Optional: serve static files
55
- }));
56
-
57
- await kernel.bootstrap();
58
-
59
- // Server starts automatically when kernel is ready
60
- // API available at: http://localhost:3000/api/v1
61
- ```
62
-
63
- ### With Custom Port
64
-
65
- ```typescript
66
- const plugin = new HonoServerPlugin({
67
- port: process.env.PORT || 8080
68
- });
69
-
70
- kernel.use(plugin);
71
- ```
72
-
73
- ### Configuration Options
74
-
75
- ```typescript
76
- interface HonoPluginOptions {
77
- /**
78
- * HTTP server port
79
- * @default 3000
80
- */
81
- port?: number;
82
-
83
- /**
84
- * Path to static files directory (optional)
85
- */
86
- staticRoot?: string;
87
-
88
- /**
89
- * REST server configuration
90
- * Controls automatic endpoint generation and API behavior
91
- */
92
- restConfig?: RestServerConfig;
93
-
94
- /**
95
- * Whether to register standard ObjectStack CRUD endpoints
96
- * @default true
97
- */
98
- registerStandardEndpoints?: boolean;
99
-
100
- /**
101
- * Whether to load endpoints from API Registry
102
- * When enabled, routes are loaded dynamically from the API Registry
103
- * When disabled, uses legacy static route registration
104
- * @default true
105
- */
106
- useApiRegistry?: boolean;
107
- }
108
- ```
109
-
110
- ### Using API Registry (New in v0.9.0)
111
-
112
- The plugin now integrates with the ObjectStack API Registry for centralized endpoint management:
113
-
114
- ```typescript
115
- import { createApiRegistryPlugin } from '@objectstack/core';
116
- import { HonoServerPlugin } from '@objectstack/plugin-hono-server';
117
-
118
- const kernel = new ObjectKernel();
119
16
 
120
- // 1. Register API Registry Plugin first
121
- kernel.use(createApiRegistryPlugin({
122
- conflictResolution: 'priority' // Handle route conflicts by priority
123
- }));
124
-
125
- // 2. Register Hono Server Plugin
126
- kernel.use(new HonoServerPlugin({
127
- port: 3000,
128
- useApiRegistry: true,
129
- registerStandardEndpoints: true,
130
- restConfig: {
131
- api: {
132
- version: 'v1',
133
- basePath: '/api',
134
- enableCrud: true,
135
- enableMetadata: true,
136
- enableBatch: true
137
- }
138
- }
139
- }));
140
-
141
- await kernel.bootstrap();
142
- ```
143
-
144
- **Benefits of API Registry Integration:**
145
- - 📋 Centralized endpoint registration and discovery
146
- - 🔀 Priority-based route conflict resolution
147
- - 🧩 Support for plugin-registered custom endpoints
148
- - ⚙️ Configurable endpoint generation via `RestServerConfig`
149
- - 🔍 API introspection and documentation generation
150
-
151
- ### Configuring REST Server Behavior
152
-
153
- Use `restConfig` to control which endpoints are automatically generated:
154
-
155
- ```typescript
156
- new HonoServerPlugin({
157
- restConfig: {
158
- api: {
159
- version: 'v2',
160
- basePath: '/api',
161
- enableCrud: true,
162
- enableMetadata: true,
163
- enableBatch: true,
164
- enableDiscovery: true
165
- },
166
- crud: {
167
- dataPrefix: '/data',
168
- operations: {
169
- create: true,
170
- read: true,
171
- update: true,
172
- delete: true,
173
- list: true
174
- }
175
- },
176
- metadata: {
177
- prefix: '/meta',
178
- enableCache: true,
179
- cacheTtl: 3600
180
- },
181
- batch: {
182
- maxBatchSize: 200,
183
- operations: {
184
- createMany: true,
185
- updateMany: true,
186
- deleteMany: true,
187
- upsertMany: true
188
- }
189
- }
190
- }
191
- })
192
- ```
193
-
194
- ### Legacy Mode (Without API Registry)
195
-
196
- If the API Registry plugin is not registered, the server automatically falls back to legacy mode:
197
-
198
- ```typescript
199
- // No API Registry needed for simple setups
200
17
  const kernel = new ObjectKernel();
201
-
202
- kernel.use(new HonoServerPlugin({
203
- port: 3000,
204
- useApiRegistry: false // Explicitly disable API Registry
205
- }));
206
-
207
- await kernel.bootstrap();
208
- // All standard routes registered statically
209
- ```
210
-
211
- ## API Endpoints
212
-
213
- The plugin automatically exposes the following ObjectStack REST API endpoints:
214
-
215
- ### Discovery
216
-
217
- ```http
218
- GET /api/v1
219
- ```
220
-
221
- Returns API discovery information including available endpoints and versions.
222
-
223
- ### Metadata Protocol
224
-
225
- ```http
226
- GET /api/v1/meta
227
- GET /api/v1/meta/:type
228
- GET /api/v1/meta/:type/:name
229
- ```
230
-
231
- Retrieve metadata about objects, views, and other system definitions.
232
-
233
- ### Data Protocol (CRUD Operations)
234
-
235
- ```http
236
- GET /api/v1/data/:object # Find records
237
- GET /api/v1/data/:object/:id # Get record by ID
238
- POST /api/v1/data/:object # Create record
239
- PATCH /api/v1/data/:object/:id # Update record
240
- DELETE /api/v1/data/:object/:id # Delete record
241
- ```
242
-
243
- Example requests:
244
-
245
- ```bash
246
- # Get all users
247
- curl http://localhost:3000/api/v1/data/user
248
-
249
- # Get user by ID
250
- curl http://localhost:3000/api/v1/data/user/123
251
-
252
- # Create a user
253
- curl -X POST http://localhost:3000/api/v1/data/user \
254
- -H "Content-Type: application/json" \
255
- -d '{"name":"John Doe","email":"john@example.com"}'
256
-
257
- # Update a user
258
- curl -X PATCH http://localhost:3000/api/v1/data/user/123 \
259
- -H "Content-Type: application/json" \
260
- -d '{"name":"Jane Doe"}'
261
-
262
- # Delete a user
263
- curl -X DELETE http://localhost:3000/api/v1/data/user/123
264
- ```
265
-
266
- ### UI Protocol
267
-
268
- ```http
269
- GET /api/v1/ui/view/:object?type=list|form
270
- ```
271
-
272
- Retrieve UI view configurations for objects.
273
-
274
- ## Advanced Usage
275
-
276
- ### Accessing the HTTP Server Instance
277
-
278
- The server instance is registered as a service and can be accessed by other plugins:
279
-
280
- ```typescript
281
- export class MyPlugin implements Plugin {
282
- name = 'my-custom-plugin';
283
-
284
- async start(ctx: PluginContext) {
285
- const httpServer = ctx.getService<IHttpServer>('http-server');
286
-
287
- // Add custom routes
288
- httpServer.get('/api/custom', (req, res) => {
289
- res.json({ message: 'Custom endpoint' });
290
- });
291
- }
292
- }
293
- ```
294
-
295
- ### Registering Custom Endpoints via API Registry
296
-
297
- Plugins can register their own endpoints through the API Registry:
298
-
299
- ```typescript
300
- export class MyApiPlugin implements Plugin {
301
- name = 'my-api-plugin';
302
- version = '1.0.0';
303
-
304
- async init(ctx: PluginContext) {
305
- const apiRegistry = ctx.getService<ApiRegistry>('api-registry');
306
-
307
- apiRegistry.registerApi({
308
- id: 'my_custom_api',
309
- name: 'My Custom API',
310
- type: 'rest',
311
- version: 'v1',
312
- basePath: '/api/v1/custom',
313
- endpoints: [
314
- {
315
- id: 'get_custom_data',
316
- method: 'GET',
317
- path: '/api/v1/custom/data',
318
- summary: 'Get custom data',
319
- priority: 500, // Lower than core endpoints (950)
320
- responses: [{
321
- statusCode: 200,
322
- description: 'Custom data retrieved'
323
- }]
324
- }
325
- ],
326
- metadata: {
327
- pluginSource: 'my-api-plugin',
328
- status: 'active',
329
- tags: ['custom']
330
- }
331
- });
332
-
333
- ctx.logger.info('Custom API endpoints registered');
334
- }
335
-
336
- async start(ctx: PluginContext) {
337
- // Bind the actual handler implementation
338
- const httpServer = ctx.getService<IHttpServer>('http-server');
339
-
340
- httpServer.get('/api/v1/custom/data', async (req, res) => {
341
- res.json({ data: 'my custom data' });
342
- });
343
- }
344
- }
345
- ```
346
-
347
- **Note:** The Hono Server Plugin loads routes from the API Registry sorted by priority (highest first), ensuring core endpoints take precedence over plugin endpoints.
348
-
349
- ### Extending with Middleware
350
-
351
- The plugin provides extension points for adding custom middleware:
352
-
353
- ```typescript
354
- // In another plugin's manifest
355
- capabilities: {
356
- extensions: [
357
- {
358
- targetPluginId: 'com.objectstack.server.hono',
359
- extensionPointId: 'com.objectstack.server.hono.extension.middleware',
360
- implementation: './middleware/auth.ts',
361
- priority: 10
362
- }
363
- ]
364
- }
365
- ```
366
-
367
- ### Custom Route Registration
368
-
369
- ```typescript
370
- // In another plugin's manifest
371
- capabilities: {
372
- extensions: [
373
- {
374
- targetPluginId: 'com.objectstack.server.hono',
375
- extensionPointId: 'com.objectstack.server.hono.extension.route',
376
- implementation: './routes/webhooks.ts',
377
- priority: 50
378
- }
379
- ]
380
- }
381
- ```
382
-
383
- ## Architecture
384
-
385
- The Hono Server Plugin follows a clean architecture:
386
-
387
- ```
388
- ┌─────────────────────────────────┐
389
- │ HonoServerPlugin │
390
- │ (Plugin Lifecycle) │
391
- └────────────┬────────────────────┘
392
-
393
- ├─ init() → Register HTTP server service
394
- ├─ start() → Bind routes, start server
395
- └─ destroy() → Stop server
396
-
397
-
398
- ┌─────────────────────┐
399
- │ HonoHttpServer │
400
- │ (Adapter) │
401
- └──────┬──────────────┘
402
-
403
-
404
- ┌─────────────────────┐
405
- │ Hono Framework │
406
- │ (Core Library) │
407
- └─────────────────────┘
408
- ```
409
-
410
- ## Plugin Lifecycle
411
-
412
- 1. **Init Phase**:
413
- - Creates HonoHttpServer instance
414
- - Registers as `http-server` service
415
-
416
- 2. **Start Phase**:
417
- - Retrieves protocol implementation service
418
- - Registers all ObjectStack API routes
419
- - Sets up lifecycle hooks
420
-
421
- 3. **Ready Hook** (`kernel:ready`):
422
- - Starts HTTP server on configured port
423
- - Logs server URL
424
-
425
- 4. **Destroy Phase**:
426
- - Gracefully closes server
427
- - Cleans up resources
428
-
429
- ## Error Handling
430
-
431
- The plugin includes comprehensive error handling:
432
-
433
- ```typescript
434
- // 404 Not Found
435
- GET /api/v1/data/user/999
436
- → { "error": "Record not found" }
437
-
438
- // 400 Bad Request
439
- POST /api/v1/data/user (invalid data)
440
- → { "error": "Validation failed: email is required" }
441
- ```
442
-
443
- ## Production Deployment
444
-
445
- ### Environment Variables
446
-
447
- ```bash
448
- PORT=8080
449
- NODE_ENV=production
18
+ kernel.use(new HonoServerPlugin({ port: 3000 }));
450
19
  ```
451
-
452
- ### Docker Example
453
-
454
- ```dockerfile
455
- FROM node:20-alpine
456
- WORKDIR /app
457
- COPY package.json pnpm-lock.yaml ./
458
- RUN npm install -g pnpm && pnpm install --frozen-lockfile
459
- COPY . .
460
- RUN pnpm build
461
- EXPOSE 8080
462
- CMD ["node", "dist/index.js"]
463
- ```
464
-
465
- ### Serverless Deployment
466
-
467
- Hono works seamlessly with serverless platforms:
468
-
469
- ```typescript
470
- // Cloudflare Workers, Vercel Edge, etc.
471
- export default {
472
- async fetch(request: Request) {
473
- const app = createHonoApp();
474
- return app.fetch(request);
475
- }
476
- }
477
- ```
478
-
479
- ## Performance
480
-
481
- Hono is designed for performance:
482
- - ⚡ One of the fastest web frameworks for Node.js
483
- - 🪶 Minimal overhead and memory footprint
484
- - 🚀 Optimized routing with RegExpRouter
485
- - 📦 Small bundle size (~12KB)
486
-
487
- ## Comparison with Other Adapters
488
-
489
- | Feature | Hono | Express | Fastify |
490
- |---------|------|---------|---------|
491
- | Universal Runtime | ✅ | ❌ | ❌ |
492
- | Edge Support | ✅ | ❌ | ❌ |
493
- | TypeScript | ✅ | Partial | ✅ |
494
- | Performance | Excellent | Good | Excellent |
495
- | Bundle Size | 12KB | 208KB | 28KB |
496
-
497
- ## License
498
-
499
- Apache-2.0
500
-
501
- ## Related Packages
502
-
503
- - [@objectstack/runtime](../../runtime) - ObjectStack Runtime
504
- - [@objectstack/spec](../../spec) - ObjectStack Specifications
505
- - [hono](https://hono.dev/) - Hono Web Framework
506
- - [@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.2",
3
+ "version": "1.0.1",
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.2",
11
- "@objectstack/spec": "0.9.2",
12
- "@objectstack/types": "0.9.2"
11
+ "@objectstack/core": "1.0.1",
12
+ "@objectstack/spec": "1.0.1",
13
+ "@objectstack/types": "1.0.1"
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