@objectstack/core 0.9.1 → 0.9.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/{ENHANCED_FEATURES.md → ADVANCED_FEATURES.md} +13 -13
- package/CHANGELOG.md +7 -0
- package/PHASE2_IMPLEMENTATION.md +388 -0
- package/README.md +24 -11
- package/REFACTORING_SUMMARY.md +40 -0
- package/dist/api-registry-plugin.test.js +20 -20
- package/dist/dependency-resolver.d.ts +62 -0
- package/dist/dependency-resolver.d.ts.map +1 -0
- package/dist/dependency-resolver.js +317 -0
- package/dist/dependency-resolver.test.d.ts +2 -0
- package/dist/dependency-resolver.test.d.ts.map +1 -0
- package/dist/dependency-resolver.test.js +241 -0
- package/dist/health-monitor.d.ts +65 -0
- package/dist/health-monitor.d.ts.map +1 -0
- package/dist/health-monitor.js +269 -0
- package/dist/health-monitor.test.d.ts +2 -0
- package/dist/health-monitor.test.d.ts.map +1 -0
- package/dist/health-monitor.test.js +68 -0
- package/dist/hot-reload.d.ts +79 -0
- package/dist/hot-reload.d.ts.map +1 -0
- package/dist/hot-reload.js +313 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/kernel-base.d.ts +2 -2
- package/dist/kernel-base.js +2 -2
- package/dist/kernel.d.ts +79 -31
- package/dist/kernel.d.ts.map +1 -1
- package/dist/kernel.js +383 -73
- package/dist/kernel.test.js +373 -122
- package/dist/lite-kernel.d.ts +55 -0
- package/dist/lite-kernel.d.ts.map +1 -0
- package/dist/lite-kernel.js +112 -0
- package/dist/lite-kernel.test.d.ts +2 -0
- package/dist/lite-kernel.test.d.ts.map +1 -0
- package/dist/lite-kernel.test.js +161 -0
- package/dist/logger.d.ts +2 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +26 -7
- package/dist/plugin-loader.d.ts +11 -0
- package/dist/plugin-loader.d.ts.map +1 -1
- package/dist/plugin-loader.js +34 -10
- package/dist/plugin-loader.test.js +9 -0
- package/dist/security/index.d.ts +3 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +4 -0
- package/dist/security/permission-manager.d.ts +96 -0
- package/dist/security/permission-manager.d.ts.map +1 -0
- package/dist/security/permission-manager.js +235 -0
- package/dist/security/permission-manager.test.d.ts +2 -0
- package/dist/security/permission-manager.test.d.ts.map +1 -0
- package/dist/security/permission-manager.test.js +220 -0
- package/dist/security/sandbox-runtime.d.ts +115 -0
- package/dist/security/sandbox-runtime.d.ts.map +1 -0
- package/dist/security/sandbox-runtime.js +310 -0
- package/dist/security/security-scanner.d.ts +92 -0
- package/dist/security/security-scanner.d.ts.map +1 -0
- package/dist/security/security-scanner.js +273 -0
- package/examples/{enhanced-kernel-example.ts → kernel-features-example.ts} +6 -6
- package/examples/phase2-integration.ts +355 -0
- package/package.json +2 -2
- package/src/api-registry-plugin.test.ts +20 -20
- package/src/dependency-resolver.test.ts +287 -0
- package/src/dependency-resolver.ts +388 -0
- package/src/health-monitor.test.ts +81 -0
- package/src/health-monitor.ts +316 -0
- package/src/hot-reload.ts +388 -0
- package/src/index.ts +6 -1
- package/src/kernel-base.ts +2 -2
- package/src/kernel.test.ts +469 -134
- package/src/kernel.ts +464 -78
- package/src/lite-kernel.test.ts +200 -0
- package/src/lite-kernel.ts +135 -0
- package/src/logger.ts +28 -7
- package/src/plugin-loader.test.ts +10 -1
- package/src/plugin-loader.ts +42 -13
- package/src/security/index.ts +19 -0
- package/src/security/permission-manager.test.ts +256 -0
- package/src/security/permission-manager.ts +336 -0
- package/src/security/sandbox-runtime.ts +432 -0
- package/src/security/security-scanner.ts +365 -0
- package/dist/enhanced-kernel.d.ts +0 -103
- package/dist/enhanced-kernel.d.ts.map +0 -1
- package/dist/enhanced-kernel.js +0 -403
- package/dist/enhanced-kernel.test.d.ts +0 -2
- package/dist/enhanced-kernel.test.d.ts.map +0 -1
- package/dist/enhanced-kernel.test.js +0 -412
- package/src/enhanced-kernel.test.ts +0 -535
- package/src/enhanced-kernel.ts +0 -496
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ObjectKernel Features Example
|
|
3
3
|
*
|
|
4
4
|
* Demonstrates advanced plugin features:
|
|
5
5
|
* - Version compatibility
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
|
-
|
|
15
|
+
ObjectKernel,
|
|
16
16
|
PluginMetadata,
|
|
17
17
|
ServiceLifecycle,
|
|
18
18
|
PluginContext
|
|
@@ -156,7 +156,7 @@ const cachePlugin: PluginMetadata = {
|
|
|
156
156
|
// Example 4: Using Service Factories
|
|
157
157
|
// ============================================================================
|
|
158
158
|
|
|
159
|
-
async function setupServiceFactories(kernel:
|
|
159
|
+
async function setupServiceFactories(kernel: ObjectKernel) {
|
|
160
160
|
// Singleton: Created once, shared across all requests
|
|
161
161
|
kernel.registerServiceFactory(
|
|
162
162
|
'logger-service',
|
|
@@ -197,10 +197,10 @@ async function setupServiceFactories(kernel: EnhancedObjectKernel) {
|
|
|
197
197
|
// ============================================================================
|
|
198
198
|
|
|
199
199
|
async function main() {
|
|
200
|
-
console.log('🚀 Starting
|
|
200
|
+
console.log('🚀 Starting ObjectKernel Advanced Features Example\n');
|
|
201
201
|
|
|
202
|
-
// Create
|
|
203
|
-
const kernel = new
|
|
202
|
+
// Create object kernel with configuration
|
|
203
|
+
const kernel = new ObjectKernel({
|
|
204
204
|
logger: {
|
|
205
205
|
level: 'info',
|
|
206
206
|
format: 'pretty'
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 2 Integration Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to use all Phase 2 components together
|
|
5
|
+
* in a real-world scenario.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
ObjectKernel,
|
|
10
|
+
PluginHealthMonitor,
|
|
11
|
+
HotReloadManager,
|
|
12
|
+
DependencyResolver,
|
|
13
|
+
PluginPermissionManager,
|
|
14
|
+
PluginSandboxRuntime,
|
|
15
|
+
PluginSecurityScanner
|
|
16
|
+
} from '@objectstack/core';
|
|
17
|
+
|
|
18
|
+
import type { Plugin } from '@objectstack/core';
|
|
19
|
+
import type {
|
|
20
|
+
PluginHealthCheck,
|
|
21
|
+
HotReloadConfig,
|
|
22
|
+
PermissionSet,
|
|
23
|
+
SandboxConfig
|
|
24
|
+
} from '@objectstack/spec/system';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Example: Enterprise Plugin Platform with Phase 2 Features
|
|
28
|
+
*/
|
|
29
|
+
export class EnterprisePluginPlatform {
|
|
30
|
+
private kernel: ObjectKernel;
|
|
31
|
+
private healthMonitor: PluginHealthMonitor;
|
|
32
|
+
private hotReload: HotReloadManager;
|
|
33
|
+
private depResolver: DependencyResolver;
|
|
34
|
+
private permManager: PluginPermissionManager;
|
|
35
|
+
private sandbox: PluginSandboxRuntime;
|
|
36
|
+
private scanner: PluginSecurityScanner;
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
// Initialize kernel
|
|
40
|
+
this.kernel = new ObjectKernel({
|
|
41
|
+
logger: {
|
|
42
|
+
level: 'info',
|
|
43
|
+
name: 'EnterprisePluginPlatform',
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Initialize Phase 2 components
|
|
48
|
+
this.healthMonitor = new PluginHealthMonitor(this.kernel.logger);
|
|
49
|
+
this.hotReload = new HotReloadManager(this.kernel.logger);
|
|
50
|
+
this.depResolver = new DependencyResolver(this.kernel.logger);
|
|
51
|
+
this.permManager = new PluginPermissionManager(this.kernel.logger);
|
|
52
|
+
this.sandbox = new PluginSandboxRuntime(this.kernel.logger);
|
|
53
|
+
this.scanner = new PluginSecurityScanner(this.kernel.logger);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Install and configure a plugin with full Phase 2 features
|
|
58
|
+
*/
|
|
59
|
+
async installPlugin(
|
|
60
|
+
plugin: Plugin,
|
|
61
|
+
config: {
|
|
62
|
+
health?: PluginHealthCheck;
|
|
63
|
+
hotReload?: HotReloadConfig;
|
|
64
|
+
permissions?: PermissionSet;
|
|
65
|
+
sandbox?: SandboxConfig;
|
|
66
|
+
securityScan?: boolean;
|
|
67
|
+
}
|
|
68
|
+
): Promise<void> {
|
|
69
|
+
const pluginName = plugin.name;
|
|
70
|
+
const pluginVersion = plugin.version || '1.0.0';
|
|
71
|
+
|
|
72
|
+
this.kernel.logger.info(`Installing plugin: ${pluginName} v${pluginVersion}`);
|
|
73
|
+
|
|
74
|
+
// Step 1: Security Scan
|
|
75
|
+
if (config.securityScan !== false) {
|
|
76
|
+
this.kernel.logger.info('Running security scan...');
|
|
77
|
+
|
|
78
|
+
const scanResult = await this.scanner.scan({
|
|
79
|
+
pluginId: pluginName,
|
|
80
|
+
version: pluginVersion,
|
|
81
|
+
// In real implementation, would provide actual files and dependencies
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!scanResult.passed) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Security scan failed: Score ${scanResult.score}/100, ` +
|
|
87
|
+
`Critical: ${scanResult.summary.critical}, ` +
|
|
88
|
+
`High: ${scanResult.summary.high}`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.kernel.logger.info(
|
|
93
|
+
`Security scan passed: ${scanResult.score}/100`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Step 2: Register Permissions
|
|
98
|
+
if (config.permissions) {
|
|
99
|
+
this.permManager.registerPermissions(pluginName, config.permissions);
|
|
100
|
+
|
|
101
|
+
// Auto-grant all permissions (in production, would prompt user)
|
|
102
|
+
this.permManager.grantAllPermissions(pluginName, 'system');
|
|
103
|
+
|
|
104
|
+
this.kernel.logger.info(
|
|
105
|
+
`Permissions registered: ${config.permissions.permissions.length} permissions`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Step 3: Create Sandbox
|
|
110
|
+
if (config.sandbox) {
|
|
111
|
+
this.sandbox.createSandbox(pluginName, config.sandbox);
|
|
112
|
+
this.kernel.logger.info(`Sandbox created: ${config.sandbox.level} level`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Step 4: Register for Health Monitoring
|
|
116
|
+
if (config.health) {
|
|
117
|
+
this.healthMonitor.registerPlugin(pluginName, config.health);
|
|
118
|
+
this.kernel.logger.info(
|
|
119
|
+
`Health monitoring configured: ${config.health.interval}ms interval`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Step 5: Register for Hot Reload
|
|
124
|
+
if (config.hotReload) {
|
|
125
|
+
this.hotReload.registerPlugin(pluginName, config.hotReload);
|
|
126
|
+
this.kernel.logger.info(
|
|
127
|
+
`Hot reload enabled: ${config.hotReload.stateStrategy} state strategy`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Step 6: Register with Kernel
|
|
132
|
+
this.kernel.use(plugin);
|
|
133
|
+
|
|
134
|
+
this.kernel.logger.info(`Plugin ${pluginName} installed successfully`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Bootstrap the platform
|
|
139
|
+
*/
|
|
140
|
+
async start(): Promise<void> {
|
|
141
|
+
// Bootstrap kernel (will init and start all plugins)
|
|
142
|
+
await this.kernel.bootstrap();
|
|
143
|
+
|
|
144
|
+
// Start health monitoring for all registered plugins
|
|
145
|
+
for (const [pluginName, plugin] of this.kernel['plugins']) {
|
|
146
|
+
if (this.healthMonitor['healthChecks'].has(pluginName)) {
|
|
147
|
+
this.healthMonitor.startMonitoring(pluginName, plugin);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.kernel.logger.info('Platform started successfully');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Shutdown the platform
|
|
156
|
+
*/
|
|
157
|
+
async shutdown(): Promise<void> {
|
|
158
|
+
this.kernel.logger.info('Shutting down platform...');
|
|
159
|
+
|
|
160
|
+
// Stop health monitoring
|
|
161
|
+
this.healthMonitor.shutdown();
|
|
162
|
+
|
|
163
|
+
// Shutdown sandbox
|
|
164
|
+
this.sandbox.shutdown();
|
|
165
|
+
|
|
166
|
+
// Shutdown kernel
|
|
167
|
+
await this.kernel.shutdown();
|
|
168
|
+
|
|
169
|
+
this.kernel.logger.info('Platform shutdown complete');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get platform health status
|
|
174
|
+
*/
|
|
175
|
+
getHealthStatus(): Record<string, any> {
|
|
176
|
+
const statuses = this.healthMonitor.getAllHealthStatuses();
|
|
177
|
+
const summary: Record<string, any> = {
|
|
178
|
+
totalPlugins: statuses.size,
|
|
179
|
+
healthy: 0,
|
|
180
|
+
degraded: 0,
|
|
181
|
+
unhealthy: 0,
|
|
182
|
+
failed: 0,
|
|
183
|
+
plugins: {},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
for (const [pluginName, status] of statuses) {
|
|
187
|
+
summary[status]++;
|
|
188
|
+
summary.plugins[pluginName] = {
|
|
189
|
+
status,
|
|
190
|
+
report: this.healthMonitor.getHealthReport(pluginName),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return summary;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Perform hot reload of a plugin
|
|
199
|
+
*/
|
|
200
|
+
async reloadPlugin(pluginName: string): Promise<void> {
|
|
201
|
+
this.kernel.logger.info(`Hot reloading plugin: ${pluginName}`);
|
|
202
|
+
|
|
203
|
+
const plugin = this.kernel['plugins'].get(pluginName);
|
|
204
|
+
if (!plugin) {
|
|
205
|
+
throw new Error(`Plugin not found: ${pluginName}`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Get current state (simplified - would need plugin cooperation)
|
|
209
|
+
const getState = () => ({
|
|
210
|
+
timestamp: Date.now(),
|
|
211
|
+
// ... plugin state
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Restore state (simplified - would need plugin cooperation)
|
|
215
|
+
const restoreState = (state: Record<string, any>) => {
|
|
216
|
+
this.kernel.logger.info(`Restoring state from ${new Date(state.timestamp)}`);
|
|
217
|
+
// ... restore plugin state
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
await this.hotReload.reloadPlugin(
|
|
221
|
+
pluginName,
|
|
222
|
+
plugin,
|
|
223
|
+
plugin.version || '1.0.0',
|
|
224
|
+
getState,
|
|
225
|
+
restoreState
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
this.kernel.logger.info(`Plugin ${pluginName} reloaded successfully`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Example Usage
|
|
234
|
+
*/
|
|
235
|
+
async function example() {
|
|
236
|
+
const platform = new EnterprisePluginPlatform();
|
|
237
|
+
|
|
238
|
+
// Define a sample plugin
|
|
239
|
+
const myPlugin: Plugin = {
|
|
240
|
+
name: 'com.example.my-plugin',
|
|
241
|
+
version: '1.0.0',
|
|
242
|
+
dependencies: ['com.objectstack.engine.objectql'],
|
|
243
|
+
|
|
244
|
+
async init(ctx) {
|
|
245
|
+
ctx.logger.info('MyPlugin initializing...');
|
|
246
|
+
// Initialize plugin
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
async start(ctx) {
|
|
250
|
+
ctx.logger.info('MyPlugin starting...');
|
|
251
|
+
// Start plugin services
|
|
252
|
+
},
|
|
253
|
+
|
|
254
|
+
async destroy() {
|
|
255
|
+
console.log('MyPlugin destroying...');
|
|
256
|
+
// Cleanup
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// Install plugin with full Phase 2 features
|
|
261
|
+
await platform.installPlugin(myPlugin, {
|
|
262
|
+
// Health monitoring
|
|
263
|
+
health: {
|
|
264
|
+
interval: 30000, // Check every 30 seconds
|
|
265
|
+
timeout: 5000,
|
|
266
|
+
failureThreshold: 3,
|
|
267
|
+
successThreshold: 1,
|
|
268
|
+
autoRestart: true,
|
|
269
|
+
maxRestartAttempts: 3,
|
|
270
|
+
restartBackoff: 'exponential',
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// Hot reload
|
|
274
|
+
hotReload: {
|
|
275
|
+
enabled: true,
|
|
276
|
+
watchPatterns: ['plugins/my-plugin/**/*.ts'],
|
|
277
|
+
debounceDelay: 1000,
|
|
278
|
+
preserveState: true,
|
|
279
|
+
stateStrategy: 'memory',
|
|
280
|
+
shutdownTimeout: 30000,
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
// Permissions
|
|
284
|
+
permissions: {
|
|
285
|
+
permissions: [
|
|
286
|
+
{
|
|
287
|
+
id: 'read-data',
|
|
288
|
+
resource: 'data.object',
|
|
289
|
+
actions: ['read'],
|
|
290
|
+
scope: 'plugin',
|
|
291
|
+
description: 'Read object data',
|
|
292
|
+
required: true,
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: 'write-data',
|
|
296
|
+
resource: 'data.object',
|
|
297
|
+
actions: ['create', 'update'],
|
|
298
|
+
scope: 'plugin',
|
|
299
|
+
description: 'Write object data',
|
|
300
|
+
required: false,
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
defaultGrant: 'prompt',
|
|
304
|
+
},
|
|
305
|
+
|
|
306
|
+
// Sandbox
|
|
307
|
+
sandbox: {
|
|
308
|
+
enabled: true,
|
|
309
|
+
level: 'standard',
|
|
310
|
+
filesystem: {
|
|
311
|
+
mode: 'restricted',
|
|
312
|
+
allowedPaths: ['/app/plugins/my-plugin'],
|
|
313
|
+
deniedPaths: ['/etc', '/root'],
|
|
314
|
+
},
|
|
315
|
+
network: {
|
|
316
|
+
mode: 'restricted',
|
|
317
|
+
allowedHosts: ['api.example.com'],
|
|
318
|
+
maxConnections: 10,
|
|
319
|
+
},
|
|
320
|
+
process: {
|
|
321
|
+
allowSpawn: false,
|
|
322
|
+
},
|
|
323
|
+
memory: {
|
|
324
|
+
maxHeap: 100 * 1024 * 1024, // 100 MB
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
|
|
328
|
+
// Security scanning
|
|
329
|
+
securityScan: true,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Start platform
|
|
333
|
+
await platform.start();
|
|
334
|
+
|
|
335
|
+
// Get health status
|
|
336
|
+
const health = platform.getHealthStatus();
|
|
337
|
+
console.log('Platform Health:', health);
|
|
338
|
+
|
|
339
|
+
// Simulate hot reload after some time
|
|
340
|
+
setTimeout(async () => {
|
|
341
|
+
await platform.reloadPlugin('com.example.my-plugin');
|
|
342
|
+
}, 60000);
|
|
343
|
+
|
|
344
|
+
// Shutdown on SIGINT
|
|
345
|
+
process.on('SIGINT', async () => {
|
|
346
|
+
await platform.shutdown();
|
|
347
|
+
process.exit(0);
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Run example if this file is executed directly (ES Module compatible)
|
|
352
|
+
// Note: In ES modules, use import.meta.url instead of require.main
|
|
353
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
354
|
+
example().catch(console.error);
|
|
355
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/core",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Microkernel Core for ObjectStack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"pino": "^8.17.0",
|
|
15
15
|
"pino-pretty": "^10.3.0",
|
|
16
16
|
"zod": "^4.3.6",
|
|
17
|
-
"@objectstack/spec": "0.9.
|
|
17
|
+
"@objectstack/spec": "0.9.2"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"pino": "^8.0.0"
|
|
@@ -14,7 +14,7 @@ describe('API Registry Plugin', () => {
|
|
|
14
14
|
|
|
15
15
|
describe('Plugin Registration', () => {
|
|
16
16
|
it('should register API Registry as a service', async () => {
|
|
17
|
-
kernel.use(createApiRegistryPlugin());
|
|
17
|
+
await kernel.use(createApiRegistryPlugin());
|
|
18
18
|
await kernel.bootstrap();
|
|
19
19
|
|
|
20
20
|
const registry = kernel.getService<ApiRegistry>('api-registry');
|
|
@@ -25,7 +25,7 @@ describe('API Registry Plugin', () => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('should register with custom conflict resolution', async () => {
|
|
28
|
-
kernel.use(createApiRegistryPlugin({
|
|
28
|
+
await kernel.use(createApiRegistryPlugin({
|
|
29
29
|
conflictResolution: 'priority',
|
|
30
30
|
version: '2.0.0',
|
|
31
31
|
}));
|
|
@@ -42,7 +42,7 @@ describe('API Registry Plugin', () => {
|
|
|
42
42
|
|
|
43
43
|
describe('Integration with Plugins', () => {
|
|
44
44
|
it('should allow plugins to register APIs', async () => {
|
|
45
|
-
kernel.use(createApiRegistryPlugin());
|
|
45
|
+
await kernel.use(createApiRegistryPlugin());
|
|
46
46
|
|
|
47
47
|
const testPlugin: Plugin = {
|
|
48
48
|
name: 'test-plugin',
|
|
@@ -75,7 +75,7 @@ describe('API Registry Plugin', () => {
|
|
|
75
75
|
},
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
kernel.use(testPlugin);
|
|
78
|
+
await kernel.use(testPlugin);
|
|
79
79
|
await kernel.bootstrap();
|
|
80
80
|
|
|
81
81
|
const registry = kernel.getService<ApiRegistry>('api-registry');
|
|
@@ -88,7 +88,7 @@ describe('API Registry Plugin', () => {
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
it('should allow multiple plugins to register APIs', async () => {
|
|
91
|
-
kernel.use(createApiRegistryPlugin());
|
|
91
|
+
await kernel.use(createApiRegistryPlugin());
|
|
92
92
|
|
|
93
93
|
const plugin1: Plugin = {
|
|
94
94
|
name: 'plugin-1',
|
|
@@ -133,8 +133,8 @@ describe('API Registry Plugin', () => {
|
|
|
133
133
|
},
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
kernel.use(plugin1);
|
|
137
|
-
kernel.use(plugin2);
|
|
136
|
+
await kernel.use(plugin1);
|
|
137
|
+
await kernel.use(plugin2);
|
|
138
138
|
await kernel.bootstrap();
|
|
139
139
|
|
|
140
140
|
const registry = kernel.getService<ApiRegistry>('api-registry');
|
|
@@ -147,7 +147,7 @@ describe('API Registry Plugin', () => {
|
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
it('should support API discovery across plugins', async () => {
|
|
150
|
-
kernel.use(createApiRegistryPlugin());
|
|
150
|
+
await kernel.use(createApiRegistryPlugin());
|
|
151
151
|
|
|
152
152
|
const dataPlugin: Plugin = {
|
|
153
153
|
name: 'data-plugin',
|
|
@@ -200,8 +200,8 @@ describe('API Registry Plugin', () => {
|
|
|
200
200
|
},
|
|
201
201
|
};
|
|
202
202
|
|
|
203
|
-
kernel.use(dataPlugin);
|
|
204
|
-
kernel.use(analyticsPlugin);
|
|
203
|
+
await kernel.use(dataPlugin);
|
|
204
|
+
await kernel.use(analyticsPlugin);
|
|
205
205
|
await kernel.bootstrap();
|
|
206
206
|
|
|
207
207
|
const registry = kernel.getService<ApiRegistry>('api-registry');
|
|
@@ -223,7 +223,7 @@ describe('API Registry Plugin', () => {
|
|
|
223
223
|
});
|
|
224
224
|
|
|
225
225
|
it('should handle route conflicts based on strategy', async () => {
|
|
226
|
-
kernel.use(createApiRegistryPlugin({
|
|
226
|
+
await kernel.use(createApiRegistryPlugin({
|
|
227
227
|
conflictResolution: 'priority',
|
|
228
228
|
}));
|
|
229
229
|
|
|
@@ -275,8 +275,8 @@ describe('API Registry Plugin', () => {
|
|
|
275
275
|
},
|
|
276
276
|
};
|
|
277
277
|
|
|
278
|
-
kernel.use(corePlugin);
|
|
279
|
-
kernel.use(pluginOverride);
|
|
278
|
+
await kernel.use(corePlugin);
|
|
279
|
+
await kernel.use(pluginOverride);
|
|
280
280
|
await kernel.bootstrap();
|
|
281
281
|
|
|
282
282
|
const registry = kernel.getService<ApiRegistry>('api-registry');
|
|
@@ -290,7 +290,7 @@ describe('API Registry Plugin', () => {
|
|
|
290
290
|
});
|
|
291
291
|
|
|
292
292
|
it('should support cleanup on plugin unload', async () => {
|
|
293
|
-
kernel.use(createApiRegistryPlugin());
|
|
293
|
+
await kernel.use(createApiRegistryPlugin());
|
|
294
294
|
|
|
295
295
|
const dynamicPlugin: Plugin = {
|
|
296
296
|
name: 'dynamic-plugin',
|
|
@@ -318,7 +318,7 @@ describe('API Registry Plugin', () => {
|
|
|
318
318
|
},
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
-
kernel.use(dynamicPlugin);
|
|
321
|
+
await kernel.use(dynamicPlugin);
|
|
322
322
|
await kernel.bootstrap();
|
|
323
323
|
|
|
324
324
|
const registry = kernel.getService<ApiRegistry>('api-registry');
|
|
@@ -334,7 +334,7 @@ describe('API Registry Plugin', () => {
|
|
|
334
334
|
|
|
335
335
|
describe('API Registry Lifecycle', () => {
|
|
336
336
|
it('should be available during plugin start phase', async () => {
|
|
337
|
-
kernel.use(createApiRegistryPlugin());
|
|
337
|
+
await kernel.use(createApiRegistryPlugin());
|
|
338
338
|
|
|
339
339
|
let registryAvailable = false;
|
|
340
340
|
|
|
@@ -350,7 +350,7 @@ describe('API Registry Plugin', () => {
|
|
|
350
350
|
},
|
|
351
351
|
};
|
|
352
352
|
|
|
353
|
-
kernel.use(testPlugin);
|
|
353
|
+
await kernel.use(testPlugin);
|
|
354
354
|
await kernel.bootstrap();
|
|
355
355
|
|
|
356
356
|
expect(registryAvailable).toBe(true);
|
|
@@ -359,7 +359,7 @@ describe('API Registry Plugin', () => {
|
|
|
359
359
|
});
|
|
360
360
|
|
|
361
361
|
it('should provide consistent registry across all plugins', async () => {
|
|
362
|
-
kernel.use(createApiRegistryPlugin());
|
|
362
|
+
await kernel.use(createApiRegistryPlugin());
|
|
363
363
|
|
|
364
364
|
let registry1: ApiRegistry | undefined;
|
|
365
365
|
let registry2: ApiRegistry | undefined;
|
|
@@ -378,8 +378,8 @@ describe('API Registry Plugin', () => {
|
|
|
378
378
|
},
|
|
379
379
|
};
|
|
380
380
|
|
|
381
|
-
kernel.use(plugin1);
|
|
382
|
-
kernel.use(plugin2);
|
|
381
|
+
await kernel.use(plugin1);
|
|
382
|
+
await kernel.use(plugin2);
|
|
383
383
|
await kernel.bootstrap();
|
|
384
384
|
|
|
385
385
|
// Same registry instance should be shared
|