@objectstack/core 1.0.2 → 1.0.5
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 +58 -0
- package/CHANGELOG.md +25 -0
- package/dist/index.cjs +4294 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1777 -0
- package/dist/index.d.ts +1776 -21
- package/dist/index.js +4246 -23
- package/dist/index.js.map +1 -0
- package/package.json +4 -4
- package/tsconfig.json +1 -3
- package/dist/api-registry-plugin.d.ts +0 -54
- package/dist/api-registry-plugin.d.ts.map +0 -1
- package/dist/api-registry-plugin.js +0 -53
- package/dist/api-registry-plugin.test.d.ts +0 -2
- package/dist/api-registry-plugin.test.d.ts.map +0 -1
- package/dist/api-registry-plugin.test.js +0 -334
- package/dist/api-registry.d.ts +0 -259
- package/dist/api-registry.d.ts.map +0 -1
- package/dist/api-registry.js +0 -600
- package/dist/api-registry.test.d.ts +0 -2
- package/dist/api-registry.test.d.ts.map +0 -1
- package/dist/api-registry.test.js +0 -957
- package/dist/contracts/data-engine.d.ts +0 -62
- package/dist/contracts/data-engine.d.ts.map +0 -1
- package/dist/contracts/data-engine.js +0 -1
- package/dist/contracts/http-server.d.ts +0 -119
- package/dist/contracts/http-server.d.ts.map +0 -1
- package/dist/contracts/http-server.js +0 -11
- package/dist/contracts/logger.d.ts +0 -63
- package/dist/contracts/logger.d.ts.map +0 -1
- package/dist/contracts/logger.js +0 -1
- package/dist/dependency-resolver.d.ts +0 -62
- package/dist/dependency-resolver.d.ts.map +0 -1
- package/dist/dependency-resolver.js +0 -317
- package/dist/dependency-resolver.test.d.ts +0 -2
- package/dist/dependency-resolver.test.d.ts.map +0 -1
- package/dist/dependency-resolver.test.js +0 -241
- package/dist/health-monitor.d.ts +0 -65
- package/dist/health-monitor.d.ts.map +0 -1
- package/dist/health-monitor.js +0 -269
- package/dist/health-monitor.test.d.ts +0 -2
- package/dist/health-monitor.test.d.ts.map +0 -1
- package/dist/health-monitor.test.js +0 -68
- package/dist/hot-reload.d.ts +0 -79
- package/dist/hot-reload.d.ts.map +0 -1
- package/dist/hot-reload.js +0 -313
- package/dist/index.d.ts.map +0 -1
- package/dist/kernel-base.d.ts +0 -84
- package/dist/kernel-base.d.ts.map +0 -1
- package/dist/kernel-base.js +0 -219
- package/dist/kernel.d.ts +0 -113
- package/dist/kernel.d.ts.map +0 -1
- package/dist/kernel.js +0 -472
- package/dist/kernel.test.d.ts +0 -2
- package/dist/kernel.test.d.ts.map +0 -1
- package/dist/kernel.test.js +0 -414
- package/dist/lite-kernel.d.ts +0 -55
- package/dist/lite-kernel.d.ts.map +0 -1
- package/dist/lite-kernel.js +0 -112
- package/dist/lite-kernel.test.d.ts +0 -2
- package/dist/lite-kernel.test.d.ts.map +0 -1
- package/dist/lite-kernel.test.js +0 -161
- package/dist/logger.d.ts +0 -71
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -312
- package/dist/logger.test.d.ts +0 -2
- package/dist/logger.test.d.ts.map +0 -1
- package/dist/logger.test.js +0 -92
- package/dist/plugin-loader.d.ts +0 -164
- package/dist/plugin-loader.d.ts.map +0 -1
- package/dist/plugin-loader.js +0 -319
- package/dist/plugin-loader.test.d.ts +0 -2
- package/dist/plugin-loader.test.d.ts.map +0 -1
- package/dist/plugin-loader.test.js +0 -348
- package/dist/qa/adapter.d.ts +0 -14
- package/dist/qa/adapter.d.ts.map +0 -1
- package/dist/qa/adapter.js +0 -1
- package/dist/qa/http-adapter.d.ts +0 -16
- package/dist/qa/http-adapter.d.ts.map +0 -1
- package/dist/qa/http-adapter.js +0 -107
- package/dist/qa/index.d.ts +0 -4
- package/dist/qa/index.d.ts.map +0 -1
- package/dist/qa/index.js +0 -3
- package/dist/qa/runner.d.ts +0 -27
- package/dist/qa/runner.d.ts.map +0 -1
- package/dist/qa/runner.js +0 -157
- package/dist/security/index.d.ts +0 -17
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -17
- package/dist/security/permission-manager.d.ts +0 -96
- package/dist/security/permission-manager.d.ts.map +0 -1
- package/dist/security/permission-manager.js +0 -235
- package/dist/security/permission-manager.test.d.ts +0 -2
- package/dist/security/permission-manager.test.d.ts.map +0 -1
- package/dist/security/permission-manager.test.js +0 -220
- package/dist/security/plugin-config-validator.d.ts +0 -79
- package/dist/security/plugin-config-validator.d.ts.map +0 -1
- package/dist/security/plugin-config-validator.js +0 -166
- package/dist/security/plugin-config-validator.test.d.ts +0 -2
- package/dist/security/plugin-config-validator.test.d.ts.map +0 -1
- package/dist/security/plugin-config-validator.test.js +0 -223
- package/dist/security/plugin-permission-enforcer.d.ts +0 -154
- package/dist/security/plugin-permission-enforcer.d.ts.map +0 -1
- package/dist/security/plugin-permission-enforcer.js +0 -323
- package/dist/security/plugin-permission-enforcer.test.d.ts +0 -2
- package/dist/security/plugin-permission-enforcer.test.d.ts.map +0 -1
- package/dist/security/plugin-permission-enforcer.test.js +0 -205
- package/dist/security/plugin-signature-verifier.d.ts +0 -96
- package/dist/security/plugin-signature-verifier.d.ts.map +0 -1
- package/dist/security/plugin-signature-verifier.js +0 -250
- package/dist/security/sandbox-runtime.d.ts +0 -115
- package/dist/security/sandbox-runtime.d.ts.map +0 -1
- package/dist/security/sandbox-runtime.js +0 -311
- package/dist/security/security-scanner.d.ts +0 -92
- package/dist/security/security-scanner.d.ts.map +0 -1
- package/dist/security/security-scanner.js +0 -273
- package/dist/types.d.ts +0 -89
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/env.d.ts +0 -20
- package/dist/utils/env.d.ts.map +0 -1
- package/dist/utils/env.js +0 -46
- package/dist/utils/env.test.d.ts +0 -2
- package/dist/utils/env.test.d.ts.map +0 -1
- package/dist/utils/env.test.js +0 -52
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectstack/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Microkernel Core for ObjectStack",
|
|
6
6
|
"type": "module",
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"@types/node": "^25.1.0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"pino": "^
|
|
15
|
+
"pino": "^10.3.0",
|
|
16
16
|
"pino-pretty": "^10.3.0",
|
|
17
17
|
"zod": "^4.3.6",
|
|
18
|
-
"@objectstack/spec": "1.0.
|
|
18
|
+
"@objectstack/spec": "1.0.5"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"pino": "^8.0.0"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
|
-
"build": "
|
|
29
|
+
"build": "tsup --config ../../tsup.config.ts",
|
|
30
30
|
"test": "vitest run",
|
|
31
31
|
"test:watch": "vitest"
|
|
32
32
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from './types.js';
|
|
2
|
-
import type { ConflictResolutionStrategy } from '@objectstack/spec/api';
|
|
3
|
-
/**
|
|
4
|
-
* API Registry Plugin Configuration
|
|
5
|
-
*/
|
|
6
|
-
export interface ApiRegistryPluginConfig {
|
|
7
|
-
/**
|
|
8
|
-
* Conflict resolution strategy for route conflicts
|
|
9
|
-
* @default 'error'
|
|
10
|
-
*/
|
|
11
|
-
conflictResolution?: ConflictResolutionStrategy;
|
|
12
|
-
/**
|
|
13
|
-
* Registry version
|
|
14
|
-
* @default '1.0.0'
|
|
15
|
-
*/
|
|
16
|
-
version?: string;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* API Registry Plugin
|
|
20
|
-
*
|
|
21
|
-
* Registers the API Registry service in the kernel, making it available
|
|
22
|
-
* to all plugins for endpoint registration and discovery.
|
|
23
|
-
*
|
|
24
|
-
* **Usage:**
|
|
25
|
-
* ```typescript
|
|
26
|
-
* const kernel = new ObjectKernel();
|
|
27
|
-
*
|
|
28
|
-
* // Register API Registry Plugin
|
|
29
|
-
* kernel.use(createApiRegistryPlugin({ conflictResolution: 'priority' }));
|
|
30
|
-
*
|
|
31
|
-
* // In other plugins, access the API Registry
|
|
32
|
-
* const plugin: Plugin = {
|
|
33
|
-
* name: 'my-plugin',
|
|
34
|
-
* init: async (ctx) => {
|
|
35
|
-
* const registry = ctx.getService<ApiRegistry>('api-registry');
|
|
36
|
-
*
|
|
37
|
-
* // Register plugin APIs
|
|
38
|
-
* registry.registerApi({
|
|
39
|
-
* id: 'my_plugin_api',
|
|
40
|
-
* name: 'My Plugin API',
|
|
41
|
-
* type: 'rest',
|
|
42
|
-
* version: 'v1',
|
|
43
|
-
* basePath: '/api/v1/my-plugin',
|
|
44
|
-
* endpoints: [...]
|
|
45
|
-
* });
|
|
46
|
-
* }
|
|
47
|
-
* };
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @param config - Plugin configuration
|
|
51
|
-
* @returns Plugin instance
|
|
52
|
-
*/
|
|
53
|
-
export declare function createApiRegistryPlugin(config?: ApiRegistryPluginConfig): Plugin;
|
|
54
|
-
//# sourceMappingURL=api-registry-plugin.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-registry-plugin.d.ts","sourceRoot":"","sources":["../src/api-registry-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAExD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IAEhD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,GAAE,uBAA4B,GACnC,MAAM,CA2BR"}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { ApiRegistry } from './api-registry.js';
|
|
2
|
-
/**
|
|
3
|
-
* API Registry Plugin
|
|
4
|
-
*
|
|
5
|
-
* Registers the API Registry service in the kernel, making it available
|
|
6
|
-
* to all plugins for endpoint registration and discovery.
|
|
7
|
-
*
|
|
8
|
-
* **Usage:**
|
|
9
|
-
* ```typescript
|
|
10
|
-
* const kernel = new ObjectKernel();
|
|
11
|
-
*
|
|
12
|
-
* // Register API Registry Plugin
|
|
13
|
-
* kernel.use(createApiRegistryPlugin({ conflictResolution: 'priority' }));
|
|
14
|
-
*
|
|
15
|
-
* // In other plugins, access the API Registry
|
|
16
|
-
* const plugin: Plugin = {
|
|
17
|
-
* name: 'my-plugin',
|
|
18
|
-
* init: async (ctx) => {
|
|
19
|
-
* const registry = ctx.getService<ApiRegistry>('api-registry');
|
|
20
|
-
*
|
|
21
|
-
* // Register plugin APIs
|
|
22
|
-
* registry.registerApi({
|
|
23
|
-
* id: 'my_plugin_api',
|
|
24
|
-
* name: 'My Plugin API',
|
|
25
|
-
* type: 'rest',
|
|
26
|
-
* version: 'v1',
|
|
27
|
-
* basePath: '/api/v1/my-plugin',
|
|
28
|
-
* endpoints: [...]
|
|
29
|
-
* });
|
|
30
|
-
* }
|
|
31
|
-
* };
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @param config - Plugin configuration
|
|
35
|
-
* @returns Plugin instance
|
|
36
|
-
*/
|
|
37
|
-
export function createApiRegistryPlugin(config = {}) {
|
|
38
|
-
const { conflictResolution = 'error', version = '1.0.0', } = config;
|
|
39
|
-
return {
|
|
40
|
-
name: 'com.objectstack.core.api-registry',
|
|
41
|
-
version: '1.0.0',
|
|
42
|
-
init: async (ctx) => {
|
|
43
|
-
// Create API Registry instance
|
|
44
|
-
const registry = new ApiRegistry(ctx.logger, conflictResolution, version);
|
|
45
|
-
// Register as a service
|
|
46
|
-
ctx.registerService('api-registry', registry);
|
|
47
|
-
ctx.logger.info('API Registry plugin initialized', {
|
|
48
|
-
conflictResolution,
|
|
49
|
-
version,
|
|
50
|
-
});
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-registry-plugin.test.d.ts","sourceRoot":"","sources":["../src/api-registry-plugin.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
-
import { ObjectKernel } from './kernel';
|
|
3
|
-
import { createApiRegistryPlugin } from './api-registry-plugin';
|
|
4
|
-
import { ApiRegistry } from './api-registry';
|
|
5
|
-
describe('API Registry Plugin', () => {
|
|
6
|
-
let kernel;
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
kernel = new ObjectKernel({
|
|
9
|
-
skipSystemValidation: true
|
|
10
|
-
});
|
|
11
|
-
});
|
|
12
|
-
describe('Plugin Registration', () => {
|
|
13
|
-
it('should register API Registry as a service', async () => {
|
|
14
|
-
await kernel.use(createApiRegistryPlugin());
|
|
15
|
-
await kernel.bootstrap();
|
|
16
|
-
const registry = kernel.getService('api-registry');
|
|
17
|
-
expect(registry).toBeDefined();
|
|
18
|
-
expect(registry).toBeInstanceOf(ApiRegistry);
|
|
19
|
-
await kernel.shutdown();
|
|
20
|
-
});
|
|
21
|
-
it('should register with custom conflict resolution', async () => {
|
|
22
|
-
await kernel.use(createApiRegistryPlugin({
|
|
23
|
-
conflictResolution: 'priority',
|
|
24
|
-
version: '2.0.0',
|
|
25
|
-
}));
|
|
26
|
-
await kernel.bootstrap();
|
|
27
|
-
const registry = kernel.getService('api-registry');
|
|
28
|
-
const snapshot = registry.getRegistry();
|
|
29
|
-
expect(snapshot.conflictResolution).toBe('priority');
|
|
30
|
-
expect(snapshot.version).toBe('2.0.0');
|
|
31
|
-
await kernel.shutdown();
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
describe('Integration with Plugins', () => {
|
|
35
|
-
it('should allow plugins to register APIs', async () => {
|
|
36
|
-
await kernel.use(createApiRegistryPlugin());
|
|
37
|
-
const testPlugin = {
|
|
38
|
-
name: 'test-plugin',
|
|
39
|
-
init: async (ctx) => {
|
|
40
|
-
const registry = ctx.getService('api-registry');
|
|
41
|
-
const api = {
|
|
42
|
-
id: 'test_api',
|
|
43
|
-
name: 'Test API',
|
|
44
|
-
type: 'rest',
|
|
45
|
-
version: 'v1',
|
|
46
|
-
basePath: '/api/test',
|
|
47
|
-
endpoints: [
|
|
48
|
-
{
|
|
49
|
-
id: 'get_test',
|
|
50
|
-
method: 'GET',
|
|
51
|
-
path: '/api/test/hello',
|
|
52
|
-
summary: 'Test endpoint',
|
|
53
|
-
responses: [
|
|
54
|
-
{
|
|
55
|
-
statusCode: 200,
|
|
56
|
-
description: 'Success',
|
|
57
|
-
},
|
|
58
|
-
],
|
|
59
|
-
},
|
|
60
|
-
],
|
|
61
|
-
};
|
|
62
|
-
registry.registerApi(api);
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
await kernel.use(testPlugin);
|
|
66
|
-
await kernel.bootstrap();
|
|
67
|
-
const registry = kernel.getService('api-registry');
|
|
68
|
-
const api = registry.getApi('test_api');
|
|
69
|
-
expect(api).toBeDefined();
|
|
70
|
-
expect(api?.name).toBe('Test API');
|
|
71
|
-
expect(api?.endpoints.length).toBe(1);
|
|
72
|
-
await kernel.shutdown();
|
|
73
|
-
});
|
|
74
|
-
it('should allow multiple plugins to register APIs', async () => {
|
|
75
|
-
await kernel.use(createApiRegistryPlugin());
|
|
76
|
-
const plugin1 = {
|
|
77
|
-
name: 'plugin-1',
|
|
78
|
-
init: async (ctx) => {
|
|
79
|
-
const registry = ctx.getService('api-registry');
|
|
80
|
-
registry.registerApi({
|
|
81
|
-
id: 'api1',
|
|
82
|
-
name: 'API 1',
|
|
83
|
-
type: 'rest',
|
|
84
|
-
version: 'v1',
|
|
85
|
-
basePath: '/api/plugin1',
|
|
86
|
-
endpoints: [
|
|
87
|
-
{
|
|
88
|
-
id: 'endpoint1',
|
|
89
|
-
method: 'GET',
|
|
90
|
-
path: '/api/plugin1/data',
|
|
91
|
-
responses: [],
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
});
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
const plugin2 = {
|
|
98
|
-
name: 'plugin-2',
|
|
99
|
-
init: async (ctx) => {
|
|
100
|
-
const registry = ctx.getService('api-registry');
|
|
101
|
-
registry.registerApi({
|
|
102
|
-
id: 'api2',
|
|
103
|
-
name: 'API 2',
|
|
104
|
-
type: 'graphql',
|
|
105
|
-
version: 'v1',
|
|
106
|
-
basePath: '/graphql',
|
|
107
|
-
endpoints: [
|
|
108
|
-
{
|
|
109
|
-
id: 'query',
|
|
110
|
-
path: '/graphql',
|
|
111
|
-
responses: [],
|
|
112
|
-
},
|
|
113
|
-
],
|
|
114
|
-
});
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
await kernel.use(plugin1);
|
|
118
|
-
await kernel.use(plugin2);
|
|
119
|
-
await kernel.bootstrap();
|
|
120
|
-
const registry = kernel.getService('api-registry');
|
|
121
|
-
const stats = registry.getStats();
|
|
122
|
-
expect(stats.totalApis).toBe(2);
|
|
123
|
-
expect(stats.apisByType.rest).toBe(1);
|
|
124
|
-
expect(stats.apisByType.graphql).toBe(1);
|
|
125
|
-
await kernel.shutdown();
|
|
126
|
-
});
|
|
127
|
-
it('should support API discovery across plugins', async () => {
|
|
128
|
-
await kernel.use(createApiRegistryPlugin());
|
|
129
|
-
const dataPlugin = {
|
|
130
|
-
name: 'data-plugin',
|
|
131
|
-
init: async (ctx) => {
|
|
132
|
-
const registry = ctx.getService('api-registry');
|
|
133
|
-
registry.registerApi({
|
|
134
|
-
id: 'customer_api',
|
|
135
|
-
name: 'Customer API',
|
|
136
|
-
type: 'rest',
|
|
137
|
-
version: 'v1',
|
|
138
|
-
basePath: '/api/v1/customers',
|
|
139
|
-
endpoints: [],
|
|
140
|
-
metadata: {
|
|
141
|
-
status: 'active',
|
|
142
|
-
tags: ['crm', 'data'],
|
|
143
|
-
},
|
|
144
|
-
});
|
|
145
|
-
registry.registerApi({
|
|
146
|
-
id: 'product_api',
|
|
147
|
-
name: 'Product API',
|
|
148
|
-
type: 'rest',
|
|
149
|
-
version: 'v1',
|
|
150
|
-
basePath: '/api/v1/products',
|
|
151
|
-
endpoints: [],
|
|
152
|
-
metadata: {
|
|
153
|
-
status: 'active',
|
|
154
|
-
tags: ['inventory', 'data'],
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
},
|
|
158
|
-
};
|
|
159
|
-
const analyticsPlugin = {
|
|
160
|
-
name: 'analytics-plugin',
|
|
161
|
-
init: async (ctx) => {
|
|
162
|
-
const registry = ctx.getService('api-registry');
|
|
163
|
-
registry.registerApi({
|
|
164
|
-
id: 'analytics_api',
|
|
165
|
-
name: 'Analytics API',
|
|
166
|
-
type: 'rest',
|
|
167
|
-
version: 'v1',
|
|
168
|
-
basePath: '/api/v1/analytics',
|
|
169
|
-
endpoints: [],
|
|
170
|
-
metadata: {
|
|
171
|
-
status: 'beta',
|
|
172
|
-
tags: ['analytics', 'reporting'],
|
|
173
|
-
},
|
|
174
|
-
});
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
await kernel.use(dataPlugin);
|
|
178
|
-
await kernel.use(analyticsPlugin);
|
|
179
|
-
await kernel.bootstrap();
|
|
180
|
-
const registry = kernel.getService('api-registry');
|
|
181
|
-
// Find all data APIs
|
|
182
|
-
const dataApis = registry.findApis({ tags: ['data'] });
|
|
183
|
-
expect(dataApis.total).toBe(2);
|
|
184
|
-
// Find active APIs
|
|
185
|
-
const activeApis = registry.findApis({ status: 'active' });
|
|
186
|
-
expect(activeApis.total).toBe(2);
|
|
187
|
-
// Find CRM APIs
|
|
188
|
-
const crmApis = registry.findApis({ tags: ['crm'] });
|
|
189
|
-
expect(crmApis.total).toBe(1);
|
|
190
|
-
expect(crmApis.apis[0].id).toBe('customer_api');
|
|
191
|
-
await kernel.shutdown();
|
|
192
|
-
});
|
|
193
|
-
it('should handle route conflicts based on strategy', async () => {
|
|
194
|
-
await kernel.use(createApiRegistryPlugin({
|
|
195
|
-
conflictResolution: 'priority',
|
|
196
|
-
}));
|
|
197
|
-
const corePlugin = {
|
|
198
|
-
name: 'core-plugin',
|
|
199
|
-
init: async (ctx) => {
|
|
200
|
-
const registry = ctx.getService('api-registry');
|
|
201
|
-
registry.registerApi({
|
|
202
|
-
id: 'core_api',
|
|
203
|
-
name: 'Core API',
|
|
204
|
-
type: 'rest',
|
|
205
|
-
version: 'v1',
|
|
206
|
-
basePath: '/api',
|
|
207
|
-
endpoints: [
|
|
208
|
-
{
|
|
209
|
-
id: 'core_endpoint',
|
|
210
|
-
method: 'GET',
|
|
211
|
-
path: '/api/data/:object',
|
|
212
|
-
priority: 900, // High priority
|
|
213
|
-
summary: 'Core data endpoint',
|
|
214
|
-
responses: [],
|
|
215
|
-
},
|
|
216
|
-
],
|
|
217
|
-
});
|
|
218
|
-
},
|
|
219
|
-
};
|
|
220
|
-
const pluginOverride = {
|
|
221
|
-
name: 'plugin-override',
|
|
222
|
-
init: async (ctx) => {
|
|
223
|
-
const registry = ctx.getService('api-registry');
|
|
224
|
-
registry.registerApi({
|
|
225
|
-
id: 'plugin_api',
|
|
226
|
-
name: 'Plugin API',
|
|
227
|
-
type: 'rest',
|
|
228
|
-
version: 'v1',
|
|
229
|
-
basePath: '/api',
|
|
230
|
-
endpoints: [
|
|
231
|
-
{
|
|
232
|
-
id: 'plugin_endpoint',
|
|
233
|
-
method: 'GET',
|
|
234
|
-
path: '/api/data/:object',
|
|
235
|
-
priority: 300, // Lower priority
|
|
236
|
-
summary: 'Plugin data endpoint',
|
|
237
|
-
responses: [],
|
|
238
|
-
},
|
|
239
|
-
],
|
|
240
|
-
});
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
await kernel.use(corePlugin);
|
|
244
|
-
await kernel.use(pluginOverride);
|
|
245
|
-
await kernel.bootstrap();
|
|
246
|
-
const registry = kernel.getService('api-registry');
|
|
247
|
-
const result = registry.findEndpointByRoute('GET', '/api/data/:object');
|
|
248
|
-
// Core API should win due to higher priority
|
|
249
|
-
expect(result?.api.id).toBe('core_api');
|
|
250
|
-
expect(result?.endpoint.id).toBe('core_endpoint');
|
|
251
|
-
await kernel.shutdown();
|
|
252
|
-
});
|
|
253
|
-
it('should support cleanup on plugin unload', async () => {
|
|
254
|
-
await kernel.use(createApiRegistryPlugin());
|
|
255
|
-
const dynamicPlugin = {
|
|
256
|
-
name: 'dynamic-plugin',
|
|
257
|
-
init: async (ctx) => {
|
|
258
|
-
const registry = ctx.getService('api-registry');
|
|
259
|
-
registry.registerApi({
|
|
260
|
-
id: 'dynamic_api',
|
|
261
|
-
name: 'Dynamic API',
|
|
262
|
-
type: 'rest',
|
|
263
|
-
version: 'v1',
|
|
264
|
-
basePath: '/api/dynamic',
|
|
265
|
-
endpoints: [
|
|
266
|
-
{
|
|
267
|
-
id: 'test',
|
|
268
|
-
method: 'GET',
|
|
269
|
-
path: '/api/dynamic/test',
|
|
270
|
-
responses: [],
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
});
|
|
274
|
-
},
|
|
275
|
-
destroy: async () => {
|
|
276
|
-
// In a real scenario, this would use ctx to access registry
|
|
277
|
-
// For now, we'll test the registry's unregister capability
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
await kernel.use(dynamicPlugin);
|
|
281
|
-
await kernel.bootstrap();
|
|
282
|
-
const registry = kernel.getService('api-registry');
|
|
283
|
-
expect(registry.getApi('dynamic_api')).toBeDefined();
|
|
284
|
-
// Unregister the API
|
|
285
|
-
registry.unregisterApi('dynamic_api');
|
|
286
|
-
expect(registry.getApi('dynamic_api')).toBeUndefined();
|
|
287
|
-
await kernel.shutdown();
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
describe('API Registry Lifecycle', () => {
|
|
291
|
-
it('should be available during plugin start phase', async () => {
|
|
292
|
-
await kernel.use(createApiRegistryPlugin());
|
|
293
|
-
let registryAvailable = false;
|
|
294
|
-
const testPlugin = {
|
|
295
|
-
name: 'test-plugin',
|
|
296
|
-
init: async () => {
|
|
297
|
-
// Init phase
|
|
298
|
-
},
|
|
299
|
-
start: async (ctx) => {
|
|
300
|
-
// Start phase - registry should be available
|
|
301
|
-
const registry = ctx.getService('api-registry');
|
|
302
|
-
registryAvailable = registry !== undefined;
|
|
303
|
-
},
|
|
304
|
-
};
|
|
305
|
-
await kernel.use(testPlugin);
|
|
306
|
-
await kernel.bootstrap();
|
|
307
|
-
expect(registryAvailable).toBe(true);
|
|
308
|
-
await kernel.shutdown();
|
|
309
|
-
});
|
|
310
|
-
it('should provide consistent registry across all plugins', async () => {
|
|
311
|
-
await kernel.use(createApiRegistryPlugin());
|
|
312
|
-
let registry1;
|
|
313
|
-
let registry2;
|
|
314
|
-
const plugin1 = {
|
|
315
|
-
name: 'plugin-1',
|
|
316
|
-
init: async (ctx) => {
|
|
317
|
-
registry1 = ctx.getService('api-registry');
|
|
318
|
-
},
|
|
319
|
-
};
|
|
320
|
-
const plugin2 = {
|
|
321
|
-
name: 'plugin-2',
|
|
322
|
-
init: async (ctx) => {
|
|
323
|
-
registry2 = ctx.getService('api-registry');
|
|
324
|
-
},
|
|
325
|
-
};
|
|
326
|
-
await kernel.use(plugin1);
|
|
327
|
-
await kernel.use(plugin2);
|
|
328
|
-
await kernel.bootstrap();
|
|
329
|
-
// Same registry instance should be shared
|
|
330
|
-
expect(registry1).toBe(registry2);
|
|
331
|
-
await kernel.shutdown();
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
});
|