@objectstack/runtime 0.9.2 → 1.0.0
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 +16 -0
- package/dist/api-registry-plugin.d.ts +16 -0
- package/dist/api-registry-plugin.js +42 -0
- package/dist/app-plugin.d.ts +2 -2
- package/dist/app-plugin.js +61 -61
- package/dist/app-plugin.test.d.ts +1 -0
- package/dist/app-plugin.test.js +80 -0
- package/dist/driver-plugin.d.ts +2 -2
- package/dist/driver-plugin.js +14 -14
- package/dist/http-dispatcher.d.ts +106 -0
- package/dist/http-dispatcher.js +515 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/runtime.d.ts +45 -0
- package/dist/runtime.js +50 -0
- package/dist/runtime.test.d.ts +1 -0
- package/dist/runtime.test.js +57 -0
- package/package.json +9 -6
- package/src/api-registry-plugin.ts +58 -0
- package/src/app-plugin.test.ts +102 -0
- package/src/app-plugin.ts +2 -2
- package/src/driver-plugin.ts +2 -2
- package/src/http-dispatcher.ts +600 -0
- package/src/index.ts +8 -0
- package/src/runtime.test.ts +65 -0
- package/src/runtime.ts +78 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @objectstack/runtime
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Major version release for ObjectStack Protocol v1.0.
|
|
8
|
+
- Stabilized Protocol Definitions
|
|
9
|
+
- Enhanced Runtime Plugin Support
|
|
10
|
+
- Fixed Type Compliance across Monorepo
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
- @objectstack/spec@1.0.0
|
|
16
|
+
- @objectstack/core@1.0.0
|
|
17
|
+
- @objectstack/types@1.0.0
|
|
18
|
+
|
|
3
19
|
## 0.9.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Plugin } from '@objectstack/core';
|
|
2
|
+
import { RestServerConfig } from '@objectstack/spec/api';
|
|
3
|
+
export interface ApiRegistryConfig {
|
|
4
|
+
serverServiceName?: string;
|
|
5
|
+
protocolServiceName?: string;
|
|
6
|
+
api?: RestServerConfig;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* ApiRegistryPlugin
|
|
10
|
+
*
|
|
11
|
+
* Responsibilities:
|
|
12
|
+
* 1. Consumes 'http.server' (or configured service)
|
|
13
|
+
* 2. Consumes 'protocol' (ObjectStackProtocol)
|
|
14
|
+
* 3. Instantiates RestServer to auto-generate routes
|
|
15
|
+
*/
|
|
16
|
+
export declare function createApiRegistryPlugin(config?: ApiRegistryConfig): Plugin;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { RestServer } from './rest-server.js';
|
|
2
|
+
/**
|
|
3
|
+
* ApiRegistryPlugin
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* 1. Consumes 'http.server' (or configured service)
|
|
7
|
+
* 2. Consumes 'protocol' (ObjectStackProtocol)
|
|
8
|
+
* 3. Instantiates RestServer to auto-generate routes
|
|
9
|
+
*/
|
|
10
|
+
export function createApiRegistryPlugin(config = {}) {
|
|
11
|
+
return {
|
|
12
|
+
name: 'com.objectstack.runtime.api-registry',
|
|
13
|
+
version: '1.0.0',
|
|
14
|
+
init: async (ctx) => {
|
|
15
|
+
// No service registration, this is a consumer plugin
|
|
16
|
+
},
|
|
17
|
+
start: async (ctx) => {
|
|
18
|
+
const serverService = config.serverServiceName || 'http.server';
|
|
19
|
+
const protocolService = config.protocolServiceName || 'protocol';
|
|
20
|
+
const server = ctx.getService(serverService);
|
|
21
|
+
const protocol = ctx.getService(protocolService);
|
|
22
|
+
if (!server) {
|
|
23
|
+
ctx.logger.warn(`ApiRegistryPlugin: HTTP Server service '${serverService}' not found. REST routes skipped.`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!protocol) {
|
|
27
|
+
ctx.logger.warn(`ApiRegistryPlugin: Protocol service '${protocolService}' not found. REST routes skipped.`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
ctx.logger.info('Hydrating REST API from Protocol...');
|
|
31
|
+
try {
|
|
32
|
+
const restServer = new RestServer(server, protocol, config.api);
|
|
33
|
+
restServer.registerRoutes();
|
|
34
|
+
ctx.logger.info('REST API successfully registered');
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
ctx.logger.error('Failed to register REST API routes', { error: err.message });
|
|
38
|
+
throw err;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
package/dist/app-plugin.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ export declare class AppPlugin implements Plugin {
|
|
|
13
13
|
version?: string;
|
|
14
14
|
private bundle;
|
|
15
15
|
constructor(bundle: any);
|
|
16
|
-
init(ctx: PluginContext)
|
|
17
|
-
start(ctx: PluginContext)
|
|
16
|
+
init: (ctx: PluginContext) => Promise<void>;
|
|
17
|
+
start: (ctx: PluginContext) => Promise<void>;
|
|
18
18
|
}
|
package/dist/app-plugin.js
CHANGED
|
@@ -9,6 +9,67 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export class AppPlugin {
|
|
11
11
|
constructor(bundle) {
|
|
12
|
+
this.init = async (ctx) => {
|
|
13
|
+
const sys = this.bundle.manifest || this.bundle;
|
|
14
|
+
const appId = sys.id || sys.name;
|
|
15
|
+
ctx.logger.info('Registering App Service', {
|
|
16
|
+
appId,
|
|
17
|
+
pluginName: this.name,
|
|
18
|
+
version: this.version
|
|
19
|
+
});
|
|
20
|
+
// Register the app manifest as a service
|
|
21
|
+
// ObjectQLPlugin will discover this and call ql.registerApp()
|
|
22
|
+
const serviceName = `app.${appId}`;
|
|
23
|
+
// Merge manifest with the bundle to ensure objects/apps are accessible at root
|
|
24
|
+
// This supports both Legacy Manifests and new Stack Definitions
|
|
25
|
+
const servicePayload = this.bundle.manifest
|
|
26
|
+
? { ...this.bundle.manifest, ...this.bundle }
|
|
27
|
+
: this.bundle;
|
|
28
|
+
ctx.registerService(serviceName, servicePayload);
|
|
29
|
+
};
|
|
30
|
+
this.start = async (ctx) => {
|
|
31
|
+
const sys = this.bundle.manifest || this.bundle;
|
|
32
|
+
const appId = sys.id || sys.name;
|
|
33
|
+
// Execute Runtime Step
|
|
34
|
+
// Retrieve ObjectQL engine from services
|
|
35
|
+
// We cast to any/ObjectQL because ctx.getService returns unknown
|
|
36
|
+
const ql = ctx.getService('objectql');
|
|
37
|
+
if (!ql) {
|
|
38
|
+
ctx.logger.warn('ObjectQL engine service not found', {
|
|
39
|
+
appName: this.name,
|
|
40
|
+
appId
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
ctx.logger.debug('Retrieved ObjectQL engine service', { appId });
|
|
45
|
+
const runtime = this.bundle.default || this.bundle;
|
|
46
|
+
if (runtime && typeof runtime.onEnable === 'function') {
|
|
47
|
+
ctx.logger.info('Executing runtime.onEnable', {
|
|
48
|
+
appName: this.name,
|
|
49
|
+
appId
|
|
50
|
+
});
|
|
51
|
+
// Construct the Host Context (mirroring old ObjectQL.use logic)
|
|
52
|
+
const hostContext = {
|
|
53
|
+
...ctx,
|
|
54
|
+
ql,
|
|
55
|
+
logger: ctx.logger,
|
|
56
|
+
drivers: {
|
|
57
|
+
register: (driver) => {
|
|
58
|
+
ctx.logger.debug('Registering driver via app runtime', {
|
|
59
|
+
driverName: driver.name,
|
|
60
|
+
appId
|
|
61
|
+
});
|
|
62
|
+
ql.registerDriver(driver);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
await runtime.onEnable(hostContext);
|
|
67
|
+
ctx.logger.debug('Runtime.onEnable completed', { appId });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
ctx.logger.debug('No runtime.onEnable function found', { appId });
|
|
71
|
+
}
|
|
72
|
+
};
|
|
12
73
|
this.bundle = bundle;
|
|
13
74
|
// Support both direct manifest (legacy) and Stack Definition (nested manifest)
|
|
14
75
|
const sys = bundle.manifest || bundle;
|
|
@@ -16,65 +77,4 @@ export class AppPlugin {
|
|
|
16
77
|
this.name = `plugin.app.${appId}`;
|
|
17
78
|
this.version = sys.version;
|
|
18
79
|
}
|
|
19
|
-
async init(ctx) {
|
|
20
|
-
const sys = this.bundle.manifest || this.bundle;
|
|
21
|
-
const appId = sys.id || sys.name;
|
|
22
|
-
ctx.logger.info('Registering App Service', {
|
|
23
|
-
appId,
|
|
24
|
-
pluginName: this.name,
|
|
25
|
-
version: this.version
|
|
26
|
-
});
|
|
27
|
-
// Register the app manifest as a service
|
|
28
|
-
// ObjectQLPlugin will discover this and call ql.registerApp()
|
|
29
|
-
const serviceName = `app.${appId}`;
|
|
30
|
-
// Merge manifest with the bundle to ensure objects/apps are accessible at root
|
|
31
|
-
// This supports both Legacy Manifests and new Stack Definitions
|
|
32
|
-
const servicePayload = this.bundle.manifest
|
|
33
|
-
? { ...this.bundle.manifest, ...this.bundle }
|
|
34
|
-
: this.bundle;
|
|
35
|
-
ctx.registerService(serviceName, servicePayload);
|
|
36
|
-
}
|
|
37
|
-
async start(ctx) {
|
|
38
|
-
const sys = this.bundle.manifest || this.bundle;
|
|
39
|
-
const appId = sys.id || sys.name;
|
|
40
|
-
// Execute Runtime Step
|
|
41
|
-
// Retrieve ObjectQL engine from services
|
|
42
|
-
// We cast to any/ObjectQL because ctx.getService returns unknown
|
|
43
|
-
const ql = ctx.getService('objectql');
|
|
44
|
-
if (!ql) {
|
|
45
|
-
ctx.logger.warn('ObjectQL engine service not found', {
|
|
46
|
-
appName: this.name,
|
|
47
|
-
appId
|
|
48
|
-
});
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
ctx.logger.debug('Retrieved ObjectQL engine service', { appId });
|
|
52
|
-
const runtime = this.bundle.default || this.bundle;
|
|
53
|
-
if (runtime && typeof runtime.onEnable === 'function') {
|
|
54
|
-
ctx.logger.info('Executing runtime.onEnable', {
|
|
55
|
-
appName: this.name,
|
|
56
|
-
appId
|
|
57
|
-
});
|
|
58
|
-
// Construct the Host Context (mirroring old ObjectQL.use logic)
|
|
59
|
-
const hostContext = {
|
|
60
|
-
...ctx,
|
|
61
|
-
ql,
|
|
62
|
-
logger: ctx.logger,
|
|
63
|
-
drivers: {
|
|
64
|
-
register: (driver) => {
|
|
65
|
-
ctx.logger.debug('Registering driver via app runtime', {
|
|
66
|
-
driverName: driver.name,
|
|
67
|
-
appId
|
|
68
|
-
});
|
|
69
|
-
ql.registerDriver(driver);
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
await runtime.onEnable(hostContext);
|
|
74
|
-
ctx.logger.debug('Runtime.onEnable completed', { appId });
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
ctx.logger.debug('No runtime.onEnable function found', { appId });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
80
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { AppPlugin } from './app-plugin';
|
|
3
|
+
describe('AppPlugin', () => {
|
|
4
|
+
let mockContext;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
mockContext = {
|
|
7
|
+
logger: {
|
|
8
|
+
info: vi.fn(),
|
|
9
|
+
error: vi.fn(),
|
|
10
|
+
warn: vi.fn(),
|
|
11
|
+
debug: vi.fn()
|
|
12
|
+
},
|
|
13
|
+
registerService: vi.fn(),
|
|
14
|
+
getService: vi.fn(),
|
|
15
|
+
getServices: vi.fn()
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
it('should initialize with manifest info', () => {
|
|
19
|
+
const bundle = {
|
|
20
|
+
id: 'com.test.app',
|
|
21
|
+
name: 'Test App',
|
|
22
|
+
version: '1.0.0'
|
|
23
|
+
};
|
|
24
|
+
const plugin = new AppPlugin(bundle);
|
|
25
|
+
expect(plugin.name).toBe('plugin.app.com.test.app');
|
|
26
|
+
expect(plugin.version).toBe('1.0.0');
|
|
27
|
+
});
|
|
28
|
+
it('should handle nested stack definition manifest', () => {
|
|
29
|
+
const bundle = {
|
|
30
|
+
manifest: {
|
|
31
|
+
id: 'com.test.stack',
|
|
32
|
+
version: '2.0.0'
|
|
33
|
+
},
|
|
34
|
+
objects: []
|
|
35
|
+
};
|
|
36
|
+
const plugin = new AppPlugin(bundle);
|
|
37
|
+
expect(plugin.name).toBe('plugin.app.com.test.stack');
|
|
38
|
+
expect(plugin.version).toBe('2.0.0');
|
|
39
|
+
});
|
|
40
|
+
it('registerService should register raw manifest in init phase', async () => {
|
|
41
|
+
const bundle = {
|
|
42
|
+
id: 'com.test.simple',
|
|
43
|
+
objects: []
|
|
44
|
+
};
|
|
45
|
+
const plugin = new AppPlugin(bundle);
|
|
46
|
+
await plugin.init(mockContext);
|
|
47
|
+
expect(mockContext.registerService).toHaveBeenCalledWith('app.com.test.simple', bundle);
|
|
48
|
+
});
|
|
49
|
+
it('start should do nothing if no runtime hooks', async () => {
|
|
50
|
+
const bundle = { id: 'com.test.static' };
|
|
51
|
+
const plugin = new AppPlugin(bundle);
|
|
52
|
+
vi.mocked(mockContext.getService).mockReturnValue({}); // Mock ObjectQL exists
|
|
53
|
+
await plugin.start(mockContext);
|
|
54
|
+
// Only logs, no errors
|
|
55
|
+
expect(mockContext.logger.debug).toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
it('start should invoke onEnable if present', async () => {
|
|
58
|
+
const onEnableSpy = vi.fn();
|
|
59
|
+
const bundle = {
|
|
60
|
+
id: 'com.test.code',
|
|
61
|
+
onEnable: onEnableSpy
|
|
62
|
+
};
|
|
63
|
+
const plugin = new AppPlugin(bundle);
|
|
64
|
+
// Mock ObjectQL engine
|
|
65
|
+
const mockQL = { registry: {} };
|
|
66
|
+
vi.mocked(mockContext.getService).mockReturnValue(mockQL);
|
|
67
|
+
await plugin.start(mockContext);
|
|
68
|
+
expect(onEnableSpy).toHaveBeenCalled();
|
|
69
|
+
// Check context passed to onEnable
|
|
70
|
+
const callArg = onEnableSpy.mock.calls[0][0];
|
|
71
|
+
expect(callArg.ql).toBe(mockQL);
|
|
72
|
+
});
|
|
73
|
+
it('start should warn if objectql not found', async () => {
|
|
74
|
+
const bundle = { id: 'com.test.warn' };
|
|
75
|
+
const plugin = new AppPlugin(bundle);
|
|
76
|
+
vi.mocked(mockContext.getService).mockReturnValue(undefined); // No ObjectQL
|
|
77
|
+
await plugin.start(mockContext);
|
|
78
|
+
expect(mockContext.logger.warn).toHaveBeenCalledWith(expect.stringContaining('ObjectQL engine service not found'), expect.any(Object));
|
|
79
|
+
});
|
|
80
|
+
});
|
package/dist/driver-plugin.d.ts
CHANGED
|
@@ -18,6 +18,6 @@ export declare class DriverPlugin implements Plugin {
|
|
|
18
18
|
version: string;
|
|
19
19
|
private driver;
|
|
20
20
|
constructor(driver: any, driverName?: string);
|
|
21
|
-
init(ctx: PluginContext)
|
|
22
|
-
start(ctx: PluginContext)
|
|
21
|
+
init: (ctx: PluginContext) => Promise<void>;
|
|
22
|
+
start: (ctx: PluginContext) => Promise<void>;
|
|
23
23
|
}
|
package/dist/driver-plugin.js
CHANGED
|
@@ -15,21 +15,21 @@
|
|
|
15
15
|
export class DriverPlugin {
|
|
16
16
|
constructor(driver, driverName) {
|
|
17
17
|
this.version = '1.0.0';
|
|
18
|
+
this.init = async (ctx) => {
|
|
19
|
+
// Register driver as a service instead of directly to objectql
|
|
20
|
+
const serviceName = `driver.${this.driver.name || 'unknown'}`;
|
|
21
|
+
ctx.registerService(serviceName, this.driver);
|
|
22
|
+
ctx.logger.info('Driver service registered', {
|
|
23
|
+
serviceName,
|
|
24
|
+
driverName: this.driver.name,
|
|
25
|
+
driverVersion: this.driver.version
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
this.start = async (ctx) => {
|
|
29
|
+
// Drivers don't need start phase, initialization happens in init
|
|
30
|
+
ctx.logger.debug('Driver plugin started', { driverName: this.driver.name || 'unknown' });
|
|
31
|
+
};
|
|
18
32
|
this.driver = driver;
|
|
19
33
|
this.name = `com.objectstack.driver.${driverName || driver.name || 'unknown'}`;
|
|
20
34
|
}
|
|
21
|
-
async init(ctx) {
|
|
22
|
-
// Register driver as a service instead of directly to objectql
|
|
23
|
-
const serviceName = `driver.${this.driver.name || 'unknown'}`;
|
|
24
|
-
ctx.registerService(serviceName, this.driver);
|
|
25
|
-
ctx.logger.info('Driver service registered', {
|
|
26
|
-
serviceName,
|
|
27
|
-
driverName: this.driver.name,
|
|
28
|
-
driverVersion: this.driver.version
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
async start(ctx) {
|
|
32
|
-
// Drivers don't need start phase, initialization happens in init
|
|
33
|
-
ctx.logger.debug('Driver plugin started', { driverName: this.driver.name || 'unknown' });
|
|
34
|
-
}
|
|
35
35
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ObjectKernel } from '@objectstack/core';
|
|
2
|
+
export interface HttpProtocolContext {
|
|
3
|
+
request: any;
|
|
4
|
+
response?: any;
|
|
5
|
+
}
|
|
6
|
+
export interface HttpDispatcherResult {
|
|
7
|
+
handled: boolean;
|
|
8
|
+
response?: {
|
|
9
|
+
status: number;
|
|
10
|
+
body?: any;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
};
|
|
13
|
+
result?: any;
|
|
14
|
+
}
|
|
15
|
+
export declare class HttpDispatcher {
|
|
16
|
+
private kernel;
|
|
17
|
+
constructor(kernel: ObjectKernel);
|
|
18
|
+
private success;
|
|
19
|
+
private error;
|
|
20
|
+
private ensureBroker;
|
|
21
|
+
/**
|
|
22
|
+
* Generates the discovery JSON response for the API root
|
|
23
|
+
*/
|
|
24
|
+
getDiscoveryInfo(prefix: string): {
|
|
25
|
+
name: string;
|
|
26
|
+
version: string;
|
|
27
|
+
environment: string;
|
|
28
|
+
routes: {
|
|
29
|
+
data: string;
|
|
30
|
+
metadata: string;
|
|
31
|
+
auth: string;
|
|
32
|
+
graphql: string | undefined;
|
|
33
|
+
storage: string | undefined;
|
|
34
|
+
analytics: string | undefined;
|
|
35
|
+
hub: string | undefined;
|
|
36
|
+
};
|
|
37
|
+
features: {
|
|
38
|
+
graphql: boolean;
|
|
39
|
+
search: boolean;
|
|
40
|
+
websockets: boolean;
|
|
41
|
+
files: boolean;
|
|
42
|
+
analytics: boolean;
|
|
43
|
+
hub: boolean;
|
|
44
|
+
};
|
|
45
|
+
locale: {
|
|
46
|
+
default: string;
|
|
47
|
+
supported: string[];
|
|
48
|
+
timezone: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Handles GraphQL requests
|
|
53
|
+
*/
|
|
54
|
+
handleGraphQL(body: {
|
|
55
|
+
query: string;
|
|
56
|
+
variables?: any;
|
|
57
|
+
}, context: HttpProtocolContext): Promise<any>;
|
|
58
|
+
/**
|
|
59
|
+
* Handles Auth requests
|
|
60
|
+
* path: sub-path after /auth/
|
|
61
|
+
*/
|
|
62
|
+
handleAuth(path: string, method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
63
|
+
/**
|
|
64
|
+
* Handles Metadata requests
|
|
65
|
+
* Standard: /metadata/:type/:name
|
|
66
|
+
* Fallback for backward compat: /metadata (all objects), /metadata/:objectName (get object)
|
|
67
|
+
*/
|
|
68
|
+
handleMetadata(path: string, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Handles Data requests
|
|
71
|
+
* path: sub-path after /data/ (e.g. "contacts", "contacts/123", "contacts/query")
|
|
72
|
+
*/
|
|
73
|
+
handleData(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Handles Analytics requests
|
|
76
|
+
* path: sub-path after /analytics/
|
|
77
|
+
*/
|
|
78
|
+
handleAnalytics(path: string, method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Handles Hub requests
|
|
81
|
+
* path: sub-path after /hub/
|
|
82
|
+
*/
|
|
83
|
+
handleHub(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Handles Storage requests
|
|
86
|
+
* path: sub-path after /storage/
|
|
87
|
+
*/
|
|
88
|
+
handleStorage(path: string, method: string, file: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
89
|
+
/**
|
|
90
|
+
* Handles Automation requests
|
|
91
|
+
* path: sub-path after /automation/
|
|
92
|
+
*/
|
|
93
|
+
handleAutomation(path: string, method: string, body: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
94
|
+
private getServicesMap;
|
|
95
|
+
private getService;
|
|
96
|
+
private capitalize;
|
|
97
|
+
/**
|
|
98
|
+
* Main Dispatcher Entry Point
|
|
99
|
+
* Routes the request to the appropriate handler based on path and precedence
|
|
100
|
+
*/
|
|
101
|
+
dispatch(method: string, path: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
102
|
+
/**
|
|
103
|
+
* Handles Custom API Endpoints defined in metadata
|
|
104
|
+
*/
|
|
105
|
+
handleApiEndpoint(path: string, method: string, body: any, query: any, context: HttpProtocolContext): Promise<HttpDispatcherResult>;
|
|
106
|
+
}
|