@objectstack/runtime 1.0.4 → 1.0.6
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/.turbo/turbo-build.log +22 -0
- package/CHANGELOG.md +24 -0
- package/dist/index.cjs +1586 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +629 -0
- package/dist/index.d.ts +628 -14
- package/dist/index.js +1549 -16
- package/dist/index.js.map +1 -0
- package/package.json +6 -5
- package/src/api-registry-plugin.ts +15 -3
- package/src/rest-server.ts +3 -5
- package/src/route-manager.ts +2 -1
- package/src/runtime.ts +0 -1
- package/tsconfig.json +4 -9
- package/dist/api-registry-plugin.d.ts +0 -16
- package/dist/api-registry-plugin.js +0 -42
- package/dist/app-plugin.d.ts +0 -18
- package/dist/app-plugin.js +0 -80
- package/dist/app-plugin.test.d.ts +0 -1
- package/dist/app-plugin.test.js +0 -80
- package/dist/driver-plugin.d.ts +0 -23
- package/dist/driver-plugin.js +0 -35
- package/dist/http-dispatcher.d.ts +0 -106
- package/dist/http-dispatcher.js +0 -539
- package/dist/http-dispatcher.test.d.ts +0 -1
- package/dist/http-dispatcher.test.js +0 -79
- package/dist/http-server.d.ts +0 -84
- package/dist/http-server.js +0 -125
- package/dist/middleware.d.ts +0 -111
- package/dist/middleware.js +0 -176
- package/dist/rest-server.d.ts +0 -74
- package/dist/rest-server.js +0 -518
- package/dist/route-manager.d.ts +0 -153
- package/dist/route-manager.js +0 -251
- package/dist/runtime.d.ts +0 -45
- package/dist/runtime.js +0 -50
- package/dist/runtime.test.d.ts +0 -1
- package/dist/runtime.test.js +0 -57
package/dist/route-manager.js
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RouteManager
|
|
3
|
-
*
|
|
4
|
-
* Manages route registration and organization for HTTP servers.
|
|
5
|
-
* Provides:
|
|
6
|
-
* - Route registration with metadata
|
|
7
|
-
* - Route lookup and querying
|
|
8
|
-
* - Bulk route registration
|
|
9
|
-
* - Route grouping by prefix
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* const manager = new RouteManager(server);
|
|
13
|
-
*
|
|
14
|
-
* // Register individual route
|
|
15
|
-
* manager.register({
|
|
16
|
-
* method: 'GET',
|
|
17
|
-
* path: '/api/users/:id',
|
|
18
|
-
* handler: getUserHandler,
|
|
19
|
-
* metadata: {
|
|
20
|
-
* summary: 'Get user by ID',
|
|
21
|
-
* tags: ['users']
|
|
22
|
-
* }
|
|
23
|
-
* });
|
|
24
|
-
*
|
|
25
|
-
* // Register route group
|
|
26
|
-
* manager.group('/api/users', (group) => {
|
|
27
|
-
* group.get('/', listUsersHandler);
|
|
28
|
-
* group.post('/', createUserHandler);
|
|
29
|
-
* group.get('/:id', getUserHandler);
|
|
30
|
-
* });
|
|
31
|
-
*/
|
|
32
|
-
export class RouteManager {
|
|
33
|
-
constructor(server) {
|
|
34
|
-
this.server = server;
|
|
35
|
-
this.routes = new Map();
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Register a route
|
|
39
|
-
* @param entry - Route entry with method, path, handler, and metadata
|
|
40
|
-
*/
|
|
41
|
-
register(entry) {
|
|
42
|
-
// Validate handler type - string handlers not yet supported
|
|
43
|
-
if (typeof entry.handler === 'string') {
|
|
44
|
-
throw new Error(`String-based route handlers are not supported yet. ` +
|
|
45
|
-
`Received handler identifier "${entry.handler}". ` +
|
|
46
|
-
`Please provide a RouteHandler function instead.`);
|
|
47
|
-
}
|
|
48
|
-
const handler = entry.handler;
|
|
49
|
-
const routeEntry = {
|
|
50
|
-
method: entry.method,
|
|
51
|
-
path: entry.path,
|
|
52
|
-
handler,
|
|
53
|
-
metadata: entry.metadata,
|
|
54
|
-
security: entry.security,
|
|
55
|
-
};
|
|
56
|
-
const key = this.getRouteKey(entry.method, entry.path);
|
|
57
|
-
this.routes.set(key, routeEntry);
|
|
58
|
-
// Register with underlying server
|
|
59
|
-
this.registerWithServer(routeEntry);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Register multiple routes
|
|
63
|
-
* @param entries - Array of route entries
|
|
64
|
-
*/
|
|
65
|
-
registerMany(entries) {
|
|
66
|
-
entries.forEach(entry => this.register(entry));
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Unregister a route
|
|
70
|
-
* @param method - HTTP method
|
|
71
|
-
* @param path - Route path
|
|
72
|
-
*/
|
|
73
|
-
unregister(method, path) {
|
|
74
|
-
const key = this.getRouteKey(method, path);
|
|
75
|
-
this.routes.delete(key);
|
|
76
|
-
// Note: Most server frameworks don't support unregistering routes at runtime
|
|
77
|
-
// This just removes it from our registry
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Get route by method and path
|
|
81
|
-
* @param method - HTTP method
|
|
82
|
-
* @param path - Route path
|
|
83
|
-
*/
|
|
84
|
-
get(method, path) {
|
|
85
|
-
const key = this.getRouteKey(method, path);
|
|
86
|
-
return this.routes.get(key);
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Get all routes
|
|
90
|
-
*/
|
|
91
|
-
getAll() {
|
|
92
|
-
return Array.from(this.routes.values());
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Get routes by method
|
|
96
|
-
* @param method - HTTP method
|
|
97
|
-
*/
|
|
98
|
-
getByMethod(method) {
|
|
99
|
-
return this.getAll().filter(route => route.method === method);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Get routes by path prefix
|
|
103
|
-
* @param prefix - Path prefix
|
|
104
|
-
*/
|
|
105
|
-
getByPrefix(prefix) {
|
|
106
|
-
return this.getAll().filter(route => route.path.startsWith(prefix));
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Get routes by tag
|
|
110
|
-
* @param tag - Tag name
|
|
111
|
-
*/
|
|
112
|
-
getByTag(tag) {
|
|
113
|
-
return this.getAll().filter(route => route.metadata?.tags?.includes(tag));
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Create a route group with common prefix
|
|
117
|
-
* @param prefix - Common path prefix
|
|
118
|
-
* @param configure - Function to configure routes in the group
|
|
119
|
-
*/
|
|
120
|
-
group(prefix, configure) {
|
|
121
|
-
const builder = new RouteGroupBuilder(this, prefix);
|
|
122
|
-
configure(builder);
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Get route count
|
|
126
|
-
*/
|
|
127
|
-
count() {
|
|
128
|
-
return this.routes.size;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Clear all routes
|
|
132
|
-
*/
|
|
133
|
-
clear() {
|
|
134
|
-
this.routes.clear();
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Get route key for storage
|
|
138
|
-
*/
|
|
139
|
-
getRouteKey(method, path) {
|
|
140
|
-
return `${method}:${path}`;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Register route with underlying server
|
|
144
|
-
*/
|
|
145
|
-
registerWithServer(entry) {
|
|
146
|
-
const { method, path, handler } = entry;
|
|
147
|
-
switch (method) {
|
|
148
|
-
case 'GET':
|
|
149
|
-
this.server.get(path, handler);
|
|
150
|
-
break;
|
|
151
|
-
case 'POST':
|
|
152
|
-
this.server.post(path, handler);
|
|
153
|
-
break;
|
|
154
|
-
case 'PUT':
|
|
155
|
-
this.server.put(path, handler);
|
|
156
|
-
break;
|
|
157
|
-
case 'DELETE':
|
|
158
|
-
this.server.delete(path, handler);
|
|
159
|
-
break;
|
|
160
|
-
case 'PATCH':
|
|
161
|
-
this.server.patch(path, handler);
|
|
162
|
-
break;
|
|
163
|
-
default:
|
|
164
|
-
throw new Error(`Unsupported HTTP method: ${method}`);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* RouteGroupBuilder
|
|
170
|
-
*
|
|
171
|
-
* Builder for creating route groups with common prefix
|
|
172
|
-
*/
|
|
173
|
-
export class RouteGroupBuilder {
|
|
174
|
-
constructor(manager, prefix) {
|
|
175
|
-
this.manager = manager;
|
|
176
|
-
this.prefix = prefix;
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Register GET route in group
|
|
180
|
-
*/
|
|
181
|
-
get(path, handler, metadata) {
|
|
182
|
-
this.manager.register({
|
|
183
|
-
method: 'GET',
|
|
184
|
-
path: this.resolvePath(path),
|
|
185
|
-
handler,
|
|
186
|
-
metadata,
|
|
187
|
-
});
|
|
188
|
-
return this;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Register POST route in group
|
|
192
|
-
*/
|
|
193
|
-
post(path, handler, metadata) {
|
|
194
|
-
this.manager.register({
|
|
195
|
-
method: 'POST',
|
|
196
|
-
path: this.resolvePath(path),
|
|
197
|
-
handler,
|
|
198
|
-
metadata,
|
|
199
|
-
});
|
|
200
|
-
return this;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Register PUT route in group
|
|
204
|
-
*/
|
|
205
|
-
put(path, handler, metadata) {
|
|
206
|
-
this.manager.register({
|
|
207
|
-
method: 'PUT',
|
|
208
|
-
path: this.resolvePath(path),
|
|
209
|
-
handler,
|
|
210
|
-
metadata,
|
|
211
|
-
});
|
|
212
|
-
return this;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Register PATCH route in group
|
|
216
|
-
*/
|
|
217
|
-
patch(path, handler, metadata) {
|
|
218
|
-
this.manager.register({
|
|
219
|
-
method: 'PATCH',
|
|
220
|
-
path: this.resolvePath(path),
|
|
221
|
-
handler,
|
|
222
|
-
metadata,
|
|
223
|
-
});
|
|
224
|
-
return this;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Register DELETE route in group
|
|
228
|
-
*/
|
|
229
|
-
delete(path, handler, metadata) {
|
|
230
|
-
this.manager.register({
|
|
231
|
-
method: 'DELETE',
|
|
232
|
-
path: this.resolvePath(path),
|
|
233
|
-
handler,
|
|
234
|
-
metadata,
|
|
235
|
-
});
|
|
236
|
-
return this;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Resolve full path with prefix
|
|
240
|
-
*/
|
|
241
|
-
resolvePath(path) {
|
|
242
|
-
// Normalize slashes
|
|
243
|
-
const normalizedPrefix = this.prefix.endsWith('/')
|
|
244
|
-
? this.prefix.slice(0, -1)
|
|
245
|
-
: this.prefix;
|
|
246
|
-
const normalizedPath = path.startsWith('/')
|
|
247
|
-
? path
|
|
248
|
-
: '/' + path;
|
|
249
|
-
return normalizedPrefix + normalizedPath;
|
|
250
|
-
}
|
|
251
|
-
}
|
package/dist/runtime.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { ObjectKernel, Plugin, IHttpServer, ObjectKernelConfig } from '@objectstack/core';
|
|
2
|
-
import { ApiRegistryConfig } from './api-registry-plugin.js';
|
|
3
|
-
export interface RuntimeConfig {
|
|
4
|
-
/**
|
|
5
|
-
* Optional existing server instance (e.g. Hono, Express app)
|
|
6
|
-
* If provided, Runtime will use it as the 'http.server' service.
|
|
7
|
-
* If not provided, Runtime expects a server plugin (like HonoServerPlugin) to be registered manually.
|
|
8
|
-
*/
|
|
9
|
-
server?: IHttpServer;
|
|
10
|
-
/**
|
|
11
|
-
* API Registry Configuration
|
|
12
|
-
*/
|
|
13
|
-
api?: ApiRegistryConfig;
|
|
14
|
-
/**
|
|
15
|
-
* Kernel Configuration
|
|
16
|
-
*/
|
|
17
|
-
kernel?: ObjectKernelConfig;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* ObjectStack Runtime
|
|
21
|
-
*
|
|
22
|
-
* High-level entry point for bootstrapping an ObjectStack application.
|
|
23
|
-
* Wraps ObjectKernel and provides standard orchestration for:
|
|
24
|
-
* - HTTP Server binding
|
|
25
|
-
* - API Registry (REST Routes)
|
|
26
|
-
* - Plugin Management
|
|
27
|
-
*/
|
|
28
|
-
export declare class Runtime {
|
|
29
|
-
readonly kernel: ObjectKernel;
|
|
30
|
-
constructor(config?: RuntimeConfig);
|
|
31
|
-
/**
|
|
32
|
-
* Register a plugin
|
|
33
|
-
*/
|
|
34
|
-
use(plugin: Plugin): this;
|
|
35
|
-
/**
|
|
36
|
-
* Start the runtime
|
|
37
|
-
* 1. Initializes all plugins (init phase)
|
|
38
|
-
* 2. Starts all plugins (start phase)
|
|
39
|
-
*/
|
|
40
|
-
start(): Promise<this>;
|
|
41
|
-
/**
|
|
42
|
-
* Get the kernel instance
|
|
43
|
-
*/
|
|
44
|
-
getKernel(): ObjectKernel;
|
|
45
|
-
}
|
package/dist/runtime.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { ObjectKernel } from '@objectstack/core';
|
|
2
|
-
import { createApiRegistryPlugin } from './api-registry-plugin.js';
|
|
3
|
-
/**
|
|
4
|
-
* ObjectStack Runtime
|
|
5
|
-
*
|
|
6
|
-
* High-level entry point for bootstrapping an ObjectStack application.
|
|
7
|
-
* Wraps ObjectKernel and provides standard orchestration for:
|
|
8
|
-
* - HTTP Server binding
|
|
9
|
-
* - API Registry (REST Routes)
|
|
10
|
-
* - Plugin Management
|
|
11
|
-
*/
|
|
12
|
-
export class Runtime {
|
|
13
|
-
constructor(config = {}) {
|
|
14
|
-
this.kernel = new ObjectKernel(config.kernel);
|
|
15
|
-
// If external server provided, register it immediately
|
|
16
|
-
if (config.server) {
|
|
17
|
-
// If the provided server is not already an HttpServer wrapper, wrap it?
|
|
18
|
-
// Since IHttpServer is the interface, we assume it complies.
|
|
19
|
-
// But HttpServer class in runtime is an adapter.
|
|
20
|
-
// If user passes raw Hono, it won't work unless they wrapped it.
|
|
21
|
-
// We'll assume they pass a compliant IHttpServer.
|
|
22
|
-
this.kernel.registerService('http.server', config.server);
|
|
23
|
-
}
|
|
24
|
-
// Register API Registry by default
|
|
25
|
-
// This plugin is passive (wait for services) so it's safe to add early.
|
|
26
|
-
this.kernel.use(createApiRegistryPlugin(config.api));
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Register a plugin
|
|
30
|
-
*/
|
|
31
|
-
use(plugin) {
|
|
32
|
-
this.kernel.use(plugin);
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Start the runtime
|
|
37
|
-
* 1. Initializes all plugins (init phase)
|
|
38
|
-
* 2. Starts all plugins (start phase)
|
|
39
|
-
*/
|
|
40
|
-
async start() {
|
|
41
|
-
await this.kernel.bootstrap();
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Get the kernel instance
|
|
46
|
-
*/
|
|
47
|
-
getKernel() {
|
|
48
|
-
return this.kernel;
|
|
49
|
-
}
|
|
50
|
-
}
|
package/dist/runtime.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/runtime.test.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { Runtime } from './runtime';
|
|
3
|
-
// Mock ObjectKernel to isolate Runtime logic
|
|
4
|
-
vi.mock('@objectstack/core', async () => {
|
|
5
|
-
const actual = await vi.importActual('@objectstack/core');
|
|
6
|
-
return {
|
|
7
|
-
...actual,
|
|
8
|
-
ObjectKernel: class {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.use = vi.fn();
|
|
11
|
-
this.registerService = vi.fn();
|
|
12
|
-
this.bootstrap = vi.fn().mockResolvedValue(undefined);
|
|
13
|
-
this.getServices = vi.fn().mockReturnValue(new Map());
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
describe('Runtime', () => {
|
|
19
|
-
it('should initialize successfully', () => {
|
|
20
|
-
const runtime = new Runtime();
|
|
21
|
-
expect(runtime).toBeDefined();
|
|
22
|
-
// Should create a kernel
|
|
23
|
-
expect(runtime.getKernel()).toBeDefined();
|
|
24
|
-
});
|
|
25
|
-
it('should register api registry plugin by default', () => {
|
|
26
|
-
const runtime = new Runtime();
|
|
27
|
-
const kernel = runtime.getKernel();
|
|
28
|
-
// Check if use was called (at least once for api registry)
|
|
29
|
-
expect(kernel.use).toHaveBeenCalled();
|
|
30
|
-
});
|
|
31
|
-
it('should register external http server if provided', () => {
|
|
32
|
-
const mockServer = {
|
|
33
|
-
listen: vi.fn(),
|
|
34
|
-
close: vi.fn(),
|
|
35
|
-
get: vi.fn(),
|
|
36
|
-
post: vi.fn(),
|
|
37
|
-
put: vi.fn(),
|
|
38
|
-
delete: vi.fn(),
|
|
39
|
-
patch: vi.fn(),
|
|
40
|
-
use: vi.fn(),
|
|
41
|
-
};
|
|
42
|
-
const runtime = new Runtime({ server: mockServer });
|
|
43
|
-
const kernel = runtime.getKernel();
|
|
44
|
-
expect(kernel.registerService).toHaveBeenCalledWith('http.server', mockServer);
|
|
45
|
-
});
|
|
46
|
-
it('should delegate use() to kernel', () => {
|
|
47
|
-
const runtime = new Runtime();
|
|
48
|
-
const mockPlugin = { name: 'test', init: vi.fn() };
|
|
49
|
-
runtime.use(mockPlugin);
|
|
50
|
-
expect(runtime.getKernel().use).toHaveBeenCalledWith(mockPlugin);
|
|
51
|
-
});
|
|
52
|
-
it('should delegate start() to kernel.bootstrap()', async () => {
|
|
53
|
-
const runtime = new Runtime();
|
|
54
|
-
await runtime.start();
|
|
55
|
-
expect(runtime.getKernel().bootstrap).toHaveBeenCalled();
|
|
56
|
-
});
|
|
57
|
-
});
|