@objectql/core 4.0.5 → 4.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/src/protocol.ts CHANGED
@@ -246,4 +246,46 @@ export class ObjectStackProtocolImplementation implements ObjectStackProtocol {
246
246
  // Not implemented in this shim yet
247
247
  throw new Error('Action execution not implemented in protocol shim');
248
248
  }
249
+
250
+ /**
251
+ * Analytics Query - Execute analytics query
252
+ */
253
+ async analyticsQuery(args: any): Promise<any> {
254
+ throw new Error('analyticsQuery not implemented');
255
+ }
256
+
257
+ /**
258
+ * Get Analytics Metadata
259
+ */
260
+ async getAnalyticsMeta(args: any): Promise<any> {
261
+ throw new Error('getAnalyticsMeta not implemented');
262
+ }
263
+
264
+ /**
265
+ * Trigger Automation
266
+ */
267
+ async triggerAutomation(args: { trigger: string; payload: Record<string, any> }): Promise<{ success: boolean; jobId?: string; result?: any }> {
268
+ throw new Error('triggerAutomation not implemented');
269
+ }
270
+
271
+ /**
272
+ * List Spaces (Hub/Workspace Management)
273
+ */
274
+ async listSpaces(args: any): Promise<any> {
275
+ throw new Error('listSpaces not implemented');
276
+ }
277
+
278
+ /**
279
+ * Create Space (Hub/Workspace Management)
280
+ */
281
+ async createSpace(args: any): Promise<any> {
282
+ throw new Error('createSpace not implemented');
283
+ }
284
+
285
+ /**
286
+ * Install Plugin (Hub/Extension Management)
287
+ */
288
+ async installPlugin(args: any): Promise<any> {
289
+ throw new Error('installPlugin not implemented');
290
+ }
249
291
  }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ /**
10
+ * Mock for @objectstack/core to enable Jest testing
11
+ *
12
+ * Since @objectstack/core@0.9.2 uses ES modules with import.meta,
13
+ * which Jest doesn't support well, we provide this mock for testing.
14
+ */
15
+
16
+ export const createLogger = jest.fn(() => ({
17
+ trace: jest.fn(),
18
+ debug: jest.fn(),
19
+ info: jest.fn(),
20
+ warn: jest.fn(),
21
+ error: jest.fn(),
22
+ fatal: jest.fn(),
23
+ }));
24
+
25
+ export const ObjectKernel = jest.fn();
26
+ export const LiteKernel = jest.fn();
27
+ export const createApiRegistryPlugin = jest.fn();
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ /**
10
+ * Mock for @objectstack/objectql to enable Jest testing
11
+ */
12
+
13
+ export class ObjectQL {
14
+ constructor(public config: any) {}
15
+ async connect() {}
16
+ async disconnect() {}
17
+ }
18
+
19
+ const mockStore = new Map<string, Map<string, any>>();
20
+
21
+ export const SchemaRegistry = {
22
+ register: jest.fn(),
23
+ get: jest.fn(),
24
+ registerItem: jest.fn((type: string, item: any, keyField: string = 'name') => {
25
+ if (!mockStore.has(type)) {
26
+ mockStore.set(type, new Map());
27
+ }
28
+ const key = item[keyField];
29
+ mockStore.get(type)!.set(key, item);
30
+ }),
31
+ unregisterItem: jest.fn((type: string, name: string) => {
32
+ const collection = mockStore.get(type);
33
+ if (collection) {
34
+ collection.delete(name);
35
+ }
36
+ }),
37
+ getItem: jest.fn((type: string, name: string) => {
38
+ return mockStore.get(type)?.get(name);
39
+ }),
40
+ listItems: jest.fn((type: string) => {
41
+ const items = mockStore.get(type);
42
+ return items ? Array.from(items.values()) : [];
43
+ }),
44
+ metadata: mockStore,
45
+ };
@@ -0,0 +1,88 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ import { ObjectGateway } from '../src/gateway';
10
+ import { ApiRequest, ApiResponse, GatewayProtocol } from '@objectql/types';
11
+
12
+ describe('ObjectGateway', () => {
13
+ let gateway: ObjectGateway;
14
+ let mockProtocol: GatewayProtocol;
15
+
16
+ beforeEach(() => {
17
+ gateway = new ObjectGateway();
18
+ mockProtocol = {
19
+ name: 'mock',
20
+ route: jest.fn().mockReturnValue(true),
21
+ handle: jest.fn().mockResolvedValue({ status: 200, body: 'ok' })
22
+ };
23
+ gateway.registerProtocol(mockProtocol);
24
+ });
25
+
26
+ it('should route request to registered protocol', async () => {
27
+ const req: ApiRequest = {
28
+ path: '/test',
29
+ method: 'GET',
30
+ headers: {},
31
+ query: {}
32
+ };
33
+
34
+ const response = await gateway.handle(req);
35
+
36
+ expect(mockProtocol.route).toHaveBeenCalledWith(req);
37
+ expect(mockProtocol.handle).toHaveBeenCalledWith(req);
38
+ expect(response.status).toBe(200);
39
+ });
40
+
41
+ it('should return 404 if no protocol matches', async () => {
42
+ const specializedGateway = new ObjectGateway();
43
+ const response = await specializedGateway.handle({
44
+ path: '/unknown',
45
+ method: 'GET',
46
+ headers: {},
47
+ query: {}
48
+ });
49
+
50
+ expect(response.status).toBe(404);
51
+ expect(response.body.error.code).toBe('PROTOCOL_NOT_FOUND');
52
+ });
53
+
54
+ it('should apply request transformers', async () => {
55
+ const req: ApiRequest = {
56
+ path: '/original',
57
+ method: 'GET',
58
+ headers: {},
59
+ query: {}
60
+ };
61
+
62
+ gateway.addRequestTransform(async (r) => {
63
+ return { ...r, path: '/transformed' };
64
+ });
65
+
66
+ await gateway.handle(req);
67
+
68
+ // Protocol should see the transformed request
69
+ expect(mockProtocol.route).toHaveBeenCalledWith(expect.objectContaining({ path: '/transformed' }));
70
+ });
71
+
72
+ it('should apply response transformers', async () => {
73
+ const req: ApiRequest = {
74
+ path: '/test',
75
+ method: 'GET',
76
+ headers: {},
77
+ query: {}
78
+ };
79
+
80
+ gateway.addResponseTransform(async (res) => {
81
+ return { ...res, headers: { ...res.headers, 'X-Custom': 'Added' } };
82
+ });
83
+
84
+ const response = await gateway.handle(req);
85
+
86
+ expect(response.headers?.['X-Custom']).toBe('Added');
87
+ });
88
+ });