@objectstack/plugin-hono-server 1.0.1 → 1.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/plugin-hono-server",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Standard Hono Server Adapter for ObjectStack Runtime",
6
6
  "main": "dist/index.js",
@@ -8,9 +8,11 @@
8
8
  "dependencies": {
9
9
  "@hono/node-server": "^1.2.0",
10
10
  "hono": "^4.0.0",
11
- "@objectstack/core": "1.0.1",
12
- "@objectstack/spec": "1.0.1",
13
- "@objectstack/types": "1.0.1"
11
+ "@objectstack/core": "1.0.2",
12
+ "@objectstack/hono": "1.0.2",
13
+ "@objectstack/runtime": "1.0.2",
14
+ "@objectstack/spec": "1.0.2",
15
+ "@objectstack/types": "1.0.2"
14
16
  },
15
17
  "devDependencies": {
16
18
  "@types/node": "^25.1.0",
package/src/adapter.ts CHANGED
@@ -101,6 +101,14 @@ export class HonoHttpServer implements IHttpServer {
101
101
  }
102
102
  }
103
103
 
104
+ /**
105
+ * Mount a sub-application or router
106
+ */
107
+ mount(path: string, subApp: Hono) {
108
+ this.app.route(path, subApp);
109
+ }
110
+
111
+
104
112
  async listen(port: number) {
105
113
  return new Promise<void>((resolve) => {
106
114
  if (this.staticRoot) {
@@ -1,167 +1,86 @@
1
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
2
2
  import { HonoServerPlugin } from './hono-plugin';
3
- import { PluginContext, ApiRegistry } from '@objectstack/core';
3
+ import { PluginContext } from '@objectstack/core';
4
+ import { createHonoApp } from '@objectstack/hono';
5
+ import { HonoHttpServer } from './adapter';
6
+
7
+ // Mock dependencies
8
+ vi.mock('@objectstack/hono', () => ({
9
+ createHonoApp: vi.fn(),
10
+ }));
11
+
12
+ vi.mock('./adapter', () => ({
13
+ HonoHttpServer: vi.fn(function() {
14
+ return {
15
+ mount: vi.fn(),
16
+ start: vi.fn(),
17
+ stop: vi.fn(),
18
+ getApp: vi.fn()
19
+ };
20
+ })
21
+ }));
4
22
 
5
23
  describe('HonoServerPlugin', () => {
6
24
  let context: any;
7
25
  let logger: any;
8
- let protocol: any;
9
- let apiRegistry: any;
26
+ let kernel: any;
10
27
 
11
28
  beforeEach(() => {
29
+ vi.clearAllMocks();
30
+
12
31
  logger = {
13
32
  info: vi.fn(),
14
33
  debug: vi.fn(),
15
34
  warn: vi.fn(),
16
35
  error: vi.fn()
17
36
  };
18
-
19
- protocol = {
20
- getDiscovery: vi.fn().mockResolvedValue({ version: 'v1', apiName: 'ObjectStack' }),
21
- getMetaTypes: vi.fn().mockResolvedValue({ types: ['object', 'plugin'] }),
22
- getMetaItems: vi.fn().mockResolvedValue({ type: 'object', items: [] }),
23
- findData: vi.fn().mockResolvedValue({ object: 'test', records: [] }),
24
- getData: vi.fn().mockResolvedValue({ object: 'test', id: '1', record: {} }),
25
- createData: vi.fn().mockResolvedValue({ object: 'test', id: '1', record: {} }),
26
- updateData: vi.fn().mockResolvedValue({ object: 'test', id: '1', record: {} }),
27
- deleteData: vi.fn().mockResolvedValue({ object: 'test', id: '1', success: true }),
28
- batchData: vi.fn().mockResolvedValue({ total: 0, succeeded: 0, failed: 0 }),
29
- createManyData: vi.fn().mockResolvedValue({ object: 'test', records: [], count: 0 }),
30
- updateManyData: vi.fn().mockResolvedValue({ total: 0, succeeded: 0, failed: 0 }),
31
- deleteManyData: vi.fn().mockResolvedValue({ total: 0, succeeded: 0, failed: 0 }),
32
- getMetaItemCached: vi.fn().mockResolvedValue({ data: {}, notModified: false }),
33
- getUiView: vi.fn().mockResolvedValue({ object: 'test', type: 'list' })
34
- };
35
37
 
36
- apiRegistry = {
37
- registerApi: vi.fn(),
38
- getRegistry: vi.fn().mockReturnValue({
39
- version: '1.0.0',
40
- conflictResolution: 'error',
41
- apis: [],
42
- totalApis: 0,
43
- totalEndpoints: 0
44
- })
38
+ kernel = {
39
+ getService: vi.fn(),
45
40
  };
46
41
 
47
42
  context = {
48
43
  logger,
49
- getService: vi.fn((service) => {
50
- if (service === 'protocol') return protocol;
51
- if (service === 'api-registry') throw new Error('Not found');
52
- return null;
53
- }),
44
+ getKernel: vi.fn().mockReturnValue(kernel),
54
45
  registerService: vi.fn(),
55
- hook: vi.fn()
46
+ hook: vi.fn(),
47
+ getService: vi.fn()
56
48
  };
57
- });
58
-
59
- it('should initialize and register server', async () => {
60
- const plugin = new HonoServerPlugin();
61
- await plugin.init(context as PluginContext);
62
-
63
- expect(context.registerService).toHaveBeenCalledWith('http-server', expect.anything());
64
- });
65
49
 
66
- it('should register hook on start', async () => {
67
- const plugin = new HonoServerPlugin();
68
- await plugin.init(context as PluginContext);
69
- await plugin.start(context as PluginContext);
70
-
71
- // Should wait for kernel:ready to start server
72
- expect(context.hook).toHaveBeenCalledWith('kernel:ready', expect.any(Function));
73
- });
74
-
75
- it('should register CRUD routes in legacy mode when API Registry not available', async () => {
76
- const plugin = new HonoServerPlugin();
77
- await plugin.init(context as PluginContext);
78
- await plugin.start(context as PluginContext);
79
-
80
- expect(context.getService).toHaveBeenCalledWith('protocol');
81
- expect(context.getService).toHaveBeenCalledWith('api-registry');
82
- expect(logger.debug).toHaveBeenCalledWith('API Registry not found, using legacy route registration');
83
- });
84
-
85
- it('should use API Registry when available', async () => {
86
- context.getService = vi.fn((service) => {
87
- if (service === 'protocol') return protocol;
88
- if (service === 'api-registry') return apiRegistry;
89
- return null;
50
+ (createHonoApp as any).mockReturnValue({
51
+ // Mock Hono App structure if needed
90
52
  });
91
-
92
- const plugin = new HonoServerPlugin();
93
- await plugin.init(context as PluginContext);
94
- await plugin.start(context as PluginContext);
95
-
96
- expect(context.getService).toHaveBeenCalledWith('api-registry');
97
- expect(apiRegistry.registerApi).toHaveBeenCalled();
98
53
  });
99
54
 
100
- it('should register standard endpoints to API Registry', async () => {
101
- context.getService = vi.fn((service) => {
102
- if (service === 'protocol') return protocol;
103
- if (service === 'api-registry') return apiRegistry;
104
- return null;
105
- });
106
-
55
+ it('should initialize and register server', async () => {
107
56
  const plugin = new HonoServerPlugin();
108
57
  await plugin.init(context as PluginContext);
109
- await plugin.start(context as PluginContext);
110
58
 
111
- expect(apiRegistry.registerApi).toHaveBeenCalledWith(
112
- expect.objectContaining({
113
- id: 'objectstack_core_api',
114
- name: 'ObjectStack Core API',
115
- type: 'rest',
116
- version: 'v1'
117
- })
118
- );
59
+ expect(context.registerService).toHaveBeenCalledWith('http-server', expect.any(Object));
60
+ expect(HonoHttpServer).toHaveBeenCalled();
119
61
  });
120
62
 
121
- it('should skip standard endpoint registration when disabled', async () => {
122
- context.getService = vi.fn((service) => {
123
- if (service === 'protocol') return protocol;
124
- if (service === 'api-registry') return apiRegistry;
125
- return null;
126
- });
127
-
128
- const plugin = new HonoServerPlugin({ registerStandardEndpoints: false });
63
+ it('should create and mount Hono app on start', async () => {
64
+ const plugin = new HonoServerPlugin();
129
65
  await plugin.init(context as PluginContext);
130
66
  await plugin.start(context as PluginContext);
131
67
 
132
- expect(apiRegistry.registerApi).not.toHaveBeenCalled();
133
- });
134
-
135
- it('should use legacy routes when useApiRegistry is disabled', async () => {
136
- context.getService = vi.fn((service) => {
137
- if (service === 'protocol') return protocol;
138
- if (service === 'api-registry') return apiRegistry;
139
- return null;
140
- });
141
-
142
- const plugin = new HonoServerPlugin({ useApiRegistry: false });
143
- await plugin.init(context as PluginContext);
144
- await plugin.start(context as PluginContext);
68
+ expect(createHonoApp).toHaveBeenCalledWith(expect.objectContaining({
69
+ kernel: kernel,
70
+ prefix: '/api/v1'
71
+ }));
145
72
 
146
- expect(apiRegistry.getRegistry).not.toHaveBeenCalled();
147
- expect(logger.debug).toHaveBeenCalledWith('Using legacy route registration');
73
+ // Access the mocked server instance
74
+ const serverInstance = (HonoHttpServer as any).mock.instances[0];
75
+ expect(serverInstance.mount).toHaveBeenCalledWith('/', expect.anything());
148
76
  });
149
77
 
150
- it('should respect REST server configuration', async () => {
151
- context.getService = vi.fn((service) => {
152
- if (service === 'protocol') return protocol;
153
- if (service === 'api-registry') return apiRegistry;
154
- return null;
155
- });
156
-
78
+ it('should respect REST server configuration for prefix', async () => {
157
79
  const plugin = new HonoServerPlugin({
158
80
  restConfig: {
159
81
  api: {
160
82
  version: 'v2',
161
- basePath: '/custom',
162
- enableCrud: true,
163
- enableMetadata: true,
164
- enableBatch: true
83
+ basePath: '/custom'
165
84
  }
166
85
  }
167
86
  });
@@ -169,22 +88,20 @@ describe('HonoServerPlugin', () => {
169
88
  await plugin.init(context as PluginContext);
170
89
  await plugin.start(context as PluginContext);
171
90
 
172
- expect(apiRegistry.registerApi).toHaveBeenCalledWith(
173
- expect.objectContaining({
174
- version: 'v2'
175
- })
176
- );
91
+ expect(createHonoApp).toHaveBeenCalledWith(expect.objectContaining({
92
+ prefix: '/custom/v2'
93
+ }));
177
94
  });
178
95
 
179
- it('should handle protocol service not found gracefully', async () => {
180
- context.getService = vi.fn(() => {
181
- throw new Error('Service not found');
96
+ it('should handle errors during app creation', async () => {
97
+ (createHonoApp as any).mockImplementation(() => {
98
+ throw new Error('Creation failed');
182
99
  });
183
100
 
184
101
  const plugin = new HonoServerPlugin();
185
102
  await plugin.init(context as PluginContext);
186
103
  await plugin.start(context as PluginContext);
187
104
 
188
- expect(logger.warn).toHaveBeenCalledWith('Protocol service not found, skipping protocol routes');
105
+ expect(logger.error).toHaveBeenCalledWith('Failed to create standard Hono app', expect.any(Error));
189
106
  });
190
107
  });