@objectql/server 1.3.1 → 1.5.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 +31 -0
- package/LICENSE +21 -0
- package/dist/adapters/node.js +157 -23
- package/dist/adapters/node.js.map +1 -1
- package/dist/adapters/rest.d.ts +15 -0
- package/dist/adapters/rest.js +252 -0
- package/dist/adapters/rest.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +1 -1
- package/dist/metadata.js +165 -38
- package/dist/metadata.js.map +1 -1
- package/dist/openapi.js +73 -24
- package/dist/openapi.js.map +1 -1
- package/dist/server.d.ts +8 -0
- package/dist/server.js +75 -15
- package/dist/server.js.map +1 -1
- package/dist/studio.d.ts +5 -0
- package/dist/{console.js → studio.js} +35 -23
- package/dist/studio.js.map +1 -0
- package/dist/types.d.ts +49 -1
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -1
- package/package.json +7 -5
- package/src/adapters/node.ts +166 -26
- package/src/adapters/rest.ts +271 -0
- package/src/index.ts +3 -1
- package/src/metadata.ts +180 -38
- package/src/openapi.ts +80 -32
- package/src/server.ts +119 -16
- package/src/{console.ts → studio.ts} +35 -22
- package/src/types.ts +56 -2
- package/test/rest.test.ts +164 -0
- package/tsconfig.json +5 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/console.d.ts +0 -5
- package/dist/console.js.map +0 -1
package/dist/metadata.js
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createMetadataHandler = createMetadataHandler;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
function readBody(req) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
let body = '';
|
|
8
|
+
req.on('data', chunk => body += chunk.toString());
|
|
9
|
+
req.on('end', () => {
|
|
10
|
+
if (!body)
|
|
11
|
+
return resolve({});
|
|
12
|
+
try {
|
|
13
|
+
resolve(JSON.parse(body));
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
reject(e);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
req.on('error', reject);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
4
22
|
/**
|
|
5
23
|
* Creates a handler for metadata endpoints.
|
|
6
|
-
* These endpoints expose information about registered objects.
|
|
24
|
+
* These endpoints expose information about registered objects and other metadata.
|
|
7
25
|
*/
|
|
8
26
|
function createMetadataHandler(app) {
|
|
9
27
|
return async (req, res) => {
|
|
10
28
|
// Parse the URL
|
|
11
29
|
const url = req.url || '';
|
|
30
|
+
const method = req.method;
|
|
12
31
|
// CORS headers for development
|
|
13
32
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
14
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
|
33
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS');
|
|
15
34
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
16
35
|
if (req.method === 'OPTIONS') {
|
|
17
36
|
res.statusCode = 200;
|
|
@@ -19,56 +38,164 @@ function createMetadataHandler(app) {
|
|
|
19
38
|
return;
|
|
20
39
|
}
|
|
21
40
|
try {
|
|
22
|
-
//
|
|
23
|
-
|
|
41
|
+
// Helper to send JSON
|
|
42
|
+
const sendJson = (data, status = 200) => {
|
|
43
|
+
res.setHeader('Content-Type', 'application/json');
|
|
44
|
+
res.statusCode = status;
|
|
45
|
+
res.end(JSON.stringify(data));
|
|
46
|
+
};
|
|
47
|
+
const sendError = (code, message, status = 400) => {
|
|
48
|
+
sendJson({ error: { code, message } }, status);
|
|
49
|
+
};
|
|
50
|
+
// ---------------------------------------------------------
|
|
51
|
+
// 1. List Entries (GET /api/metadata/:type)
|
|
52
|
+
// ---------------------------------------------------------
|
|
53
|
+
// Legacy/Alias: /api/metadata or /api/metadata/objects -> list objects
|
|
54
|
+
if (method === 'GET' && (url === '/api/metadata' || url === '/api/metadata/objects')) {
|
|
24
55
|
const configs = app.getConfigs();
|
|
25
56
|
const objects = Object.values(configs).map(obj => ({
|
|
26
57
|
name: obj.name,
|
|
27
58
|
label: obj.label || obj.name,
|
|
28
59
|
icon: obj.icon,
|
|
29
|
-
|
|
60
|
+
description: obj.description,
|
|
61
|
+
fields: obj.fields || {}
|
|
30
62
|
}));
|
|
31
|
-
|
|
32
|
-
res.statusCode = 200;
|
|
33
|
-
res.end(JSON.stringify({ objects }));
|
|
34
|
-
return;
|
|
63
|
+
return sendJson({ objects });
|
|
35
64
|
}
|
|
36
|
-
//
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
65
|
+
// Generic List: /api/metadata/:type
|
|
66
|
+
const listMatch = url.match(/^\/api\/metadata\/([^\/]+)$/);
|
|
67
|
+
if (method === 'GET' && listMatch) {
|
|
68
|
+
let [, type] = listMatch;
|
|
69
|
+
if (type === 'objects')
|
|
70
|
+
type = 'object'; // Should not hit due to order, but safe to keep.
|
|
71
|
+
const entries = app.metadata.list(type);
|
|
72
|
+
// Return simple list
|
|
73
|
+
return sendJson({
|
|
74
|
+
[type]: entries
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------
|
|
78
|
+
// 2. Get Single Entry (GET /api/metadata/:type/:id)
|
|
79
|
+
// ---------------------------------------------------------
|
|
80
|
+
const detailMatch = url.match(/^\/api\/metadata\/([^\/]+)\/([^\/\?]+)$/);
|
|
81
|
+
if (method === 'GET' && detailMatch) {
|
|
82
|
+
let [, type, id] = detailMatch;
|
|
83
|
+
// Handle Object Special Logic (Field Formatting)
|
|
84
|
+
if (type === 'objects' || type === 'object') {
|
|
85
|
+
const metadata = app.getObject(id);
|
|
86
|
+
if (!metadata) {
|
|
87
|
+
return sendError(types_1.ErrorCode.NOT_FOUND, `Object '${id}' not found`, 404);
|
|
88
|
+
}
|
|
89
|
+
// Convert fields object to array (Standard Object Response)
|
|
90
|
+
const fields = metadata.fields
|
|
91
|
+
? Object.entries(metadata.fields).map(([key, field]) => ({
|
|
92
|
+
name: field.name || key,
|
|
93
|
+
type: field.type,
|
|
94
|
+
label: field.label,
|
|
95
|
+
required: field.required,
|
|
96
|
+
defaultValue: field.defaultValue,
|
|
97
|
+
unique: field.unique,
|
|
98
|
+
options: field.options,
|
|
99
|
+
min: field.min,
|
|
100
|
+
max: field.max,
|
|
101
|
+
min_length: field.min_length,
|
|
102
|
+
max_length: field.max_length,
|
|
103
|
+
regex: field.regex
|
|
104
|
+
}))
|
|
105
|
+
: [];
|
|
106
|
+
return sendJson({
|
|
107
|
+
...metadata,
|
|
108
|
+
fields
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Generic Metadata (View, Form, etc.)
|
|
113
|
+
const content = app.metadata.get(type, id);
|
|
114
|
+
if (!content) {
|
|
115
|
+
return sendError(types_1.ErrorCode.NOT_FOUND, `${type} '${id}' not found`, 404);
|
|
116
|
+
}
|
|
117
|
+
return sendJson(content);
|
|
45
118
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------
|
|
121
|
+
// 3. Update Entry (POST/PUT /api/metadata/:type/:id)
|
|
122
|
+
// ---------------------------------------------------------
|
|
123
|
+
if ((method === 'POST' || method === 'PUT') && detailMatch) {
|
|
124
|
+
let [, type, id] = detailMatch;
|
|
125
|
+
if (type === 'objects')
|
|
126
|
+
type = 'object';
|
|
127
|
+
const body = await readBody(req);
|
|
128
|
+
try {
|
|
129
|
+
await app.updateMetadata(type, id, body);
|
|
130
|
+
return sendJson({ success: true });
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
const isUserError = e.message.startsWith('Cannot update') || e.message.includes('not found');
|
|
134
|
+
return sendError(isUserError ? types_1.ErrorCode.INVALID_REQUEST : types_1.ErrorCode.INTERNAL_ERROR, e.message, isUserError ? 400 : 500);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------
|
|
138
|
+
// 4. Object Sub-resources (Fields, Actions)
|
|
139
|
+
// ---------------------------------------------------------
|
|
140
|
+
// GET /api/metadata/objects/:name/fields/:field
|
|
141
|
+
// Legacy path support.
|
|
142
|
+
const fieldMatch = url.match(/^\/api\/metadata\/objects\/([^\/]+)\/fields\/([^\/\?]+)$/);
|
|
143
|
+
if (method === 'GET' && fieldMatch) {
|
|
144
|
+
const [, objectName, fieldName] = fieldMatch;
|
|
145
|
+
const metadata = app.getObject(objectName);
|
|
146
|
+
if (!metadata)
|
|
147
|
+
return sendError(types_1.ErrorCode.NOT_FOUND, `Object '${objectName}' not found`, 404);
|
|
148
|
+
const field = metadata.fields?.[fieldName];
|
|
149
|
+
if (!field)
|
|
150
|
+
return sendError(types_1.ErrorCode.NOT_FOUND, `Field '${fieldName}' not found`, 404);
|
|
151
|
+
return sendJson({
|
|
152
|
+
name: field.name || fieldName,
|
|
153
|
+
type: field.type,
|
|
154
|
+
label: field.label,
|
|
155
|
+
required: field.required,
|
|
156
|
+
unique: field.unique,
|
|
157
|
+
defaultValue: field.defaultValue,
|
|
158
|
+
options: field.options,
|
|
159
|
+
min: field.min,
|
|
160
|
+
max: field.max,
|
|
161
|
+
min_length: field.min_length,
|
|
162
|
+
max_length: field.max_length,
|
|
163
|
+
regex: field.regex
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
// GET /api/metadata/objects/:name/actions
|
|
167
|
+
const actionsMatch = url.match(/^\/api\/metadata\/objects\/([^\/]+)\/actions$/);
|
|
168
|
+
if (method === 'GET' && actionsMatch) {
|
|
169
|
+
const [, objectName] = actionsMatch;
|
|
170
|
+
const metadata = app.getObject(objectName);
|
|
171
|
+
if (!metadata)
|
|
172
|
+
return sendError(types_1.ErrorCode.NOT_FOUND, `Object '${objectName}' not found`, 404);
|
|
173
|
+
const actions = metadata.actions || {};
|
|
174
|
+
const formattedActions = Object.entries(actions).map(([key, action]) => {
|
|
175
|
+
const actionConfig = action;
|
|
176
|
+
const hasFields = !!actionConfig.fields && Object.keys(actionConfig.fields).length > 0;
|
|
177
|
+
return {
|
|
178
|
+
name: key,
|
|
179
|
+
type: actionConfig.type || (hasFields ? 'record' : 'global'),
|
|
180
|
+
label: actionConfig.label || key,
|
|
181
|
+
params: actionConfig.params || {},
|
|
182
|
+
description: actionConfig.description
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
return sendJson({ actions: formattedActions });
|
|
63
186
|
}
|
|
64
187
|
// Not found
|
|
65
|
-
|
|
66
|
-
res.end('Not Found');
|
|
188
|
+
sendError(types_1.ErrorCode.NOT_FOUND, 'Not Found', 404);
|
|
67
189
|
}
|
|
68
190
|
catch (e) {
|
|
69
191
|
console.error('[Metadata Handler] Error:', e);
|
|
70
192
|
res.statusCode = 500;
|
|
71
|
-
res.end(JSON.stringify({
|
|
193
|
+
res.end(JSON.stringify({
|
|
194
|
+
error: {
|
|
195
|
+
code: types_1.ErrorCode.INTERNAL_ERROR,
|
|
196
|
+
message: 'Internal Server Error'
|
|
197
|
+
}
|
|
198
|
+
}));
|
|
72
199
|
}
|
|
73
200
|
};
|
|
74
201
|
}
|
package/dist/metadata.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../src/metadata.ts"],"names":[],"mappings":"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"}
|
package/dist/openapi.js
CHANGED
|
@@ -6,7 +6,40 @@ function generateOpenAPI(app) {
|
|
|
6
6
|
const objects = registry.list('object');
|
|
7
7
|
const paths = {};
|
|
8
8
|
const schemas = {};
|
|
9
|
-
// 1.
|
|
9
|
+
// 1. JSON-RPC Endpoint
|
|
10
|
+
paths['/api/objectql'] = {
|
|
11
|
+
post: {
|
|
12
|
+
summary: 'JSON-RPC Entry Point',
|
|
13
|
+
description: 'Execute any ObjectQL operation via a JSON body.',
|
|
14
|
+
tags: ['System'],
|
|
15
|
+
requestBody: {
|
|
16
|
+
content: {
|
|
17
|
+
'application/json': {
|
|
18
|
+
schema: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
op: { type: 'string', enum: ['find', 'findOne', 'create', 'update', 'delete', 'count', 'action'] },
|
|
22
|
+
object: { type: 'string' },
|
|
23
|
+
args: { type: 'object' }
|
|
24
|
+
},
|
|
25
|
+
required: ['op', 'object']
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
responses: {
|
|
31
|
+
200: {
|
|
32
|
+
description: 'Operation Result',
|
|
33
|
+
content: {
|
|
34
|
+
'application/json': {
|
|
35
|
+
schema: { type: 'object' } // Dynamic result
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
// 2. Generate Schemas
|
|
10
43
|
for (const obj of objects) {
|
|
11
44
|
const schemaName = obj.name;
|
|
12
45
|
const properties = {};
|
|
@@ -17,29 +50,21 @@ function generateOpenAPI(app) {
|
|
|
17
50
|
type: 'object',
|
|
18
51
|
properties
|
|
19
52
|
};
|
|
20
|
-
// 2. Generate Paths (RPC Style representation for documentation purposes)
|
|
21
|
-
// Since we only have one endpoint, we might document operations as descriptions
|
|
22
|
-
// Or if we support REST style in the future, we would add /object paths here.
|
|
23
|
-
// For now, let's document the "Virtual" REST API that could exist via a gateway
|
|
24
|
-
// OR just document the schema.
|
|
25
|
-
// Let's assume the user might want to see standard CRUD paths even if implementation is RPC,
|
|
26
|
-
// so they can pass it to frontend generators?
|
|
27
|
-
// No, that would be misleading if the server doesn't support it.
|
|
28
|
-
// Let's DOCUMENT the RPC operations as if they were paths,
|
|
29
|
-
// OR clearer: One path /api/objectql with polymorphic body?
|
|
30
|
-
// Swagger UI handles oneOf poorly for top level operations sometimes.
|
|
31
53
|
}
|
|
32
|
-
//
|
|
33
|
-
// Assuming we WILL support REST mapping in this update.
|
|
54
|
+
// 3. REST API Paths
|
|
34
55
|
for (const obj of objects) {
|
|
35
56
|
const name = obj.name;
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
const basePath = `/api/data/${name}`; // Standard REST Path
|
|
58
|
+
// GET /api/data/:name (List)
|
|
59
|
+
paths[basePath] = {
|
|
38
60
|
get: {
|
|
39
|
-
summary: `List ${name}
|
|
61
|
+
summary: `List ${name}`,
|
|
40
62
|
tags: [name],
|
|
41
63
|
parameters: [
|
|
42
|
-
{ name: 'filter', in: 'query', schema: { type: 'string' }, description: 'JSON filter args' }
|
|
64
|
+
{ name: 'filter', in: 'query', schema: { type: 'string' }, description: 'JSON filter args' },
|
|
65
|
+
{ name: 'fields', in: 'query', schema: { type: 'string' }, description: 'Comma-separated fields to return' },
|
|
66
|
+
{ name: 'top', in: 'query', schema: { type: 'integer' }, description: 'Limit' },
|
|
67
|
+
{ name: 'skip', in: 'query', schema: { type: 'integer' }, description: 'Offset' }
|
|
43
68
|
],
|
|
44
69
|
responses: {
|
|
45
70
|
200: {
|
|
@@ -77,26 +102,50 @@ function generateOpenAPI(app) {
|
|
|
77
102
|
}
|
|
78
103
|
}
|
|
79
104
|
};
|
|
80
|
-
//
|
|
81
|
-
paths[
|
|
105
|
+
// /api/data/:name/:id
|
|
106
|
+
paths[`${basePath}/{id}`] = {
|
|
82
107
|
get: {
|
|
83
108
|
summary: `Get ${name}`,
|
|
84
109
|
tags: [name],
|
|
85
110
|
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
86
|
-
responses: {
|
|
111
|
+
responses: {
|
|
112
|
+
200: {
|
|
113
|
+
description: 'Item',
|
|
114
|
+
content: {
|
|
115
|
+
'application/json': {
|
|
116
|
+
schema: { $ref: `#/components/schemas/${name}` }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
87
121
|
},
|
|
88
122
|
patch: {
|
|
89
123
|
summary: `Update ${name}`,
|
|
90
124
|
tags: [name],
|
|
91
125
|
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
92
|
-
requestBody: {
|
|
93
|
-
|
|
126
|
+
requestBody: {
|
|
127
|
+
content: {
|
|
128
|
+
'application/json': {
|
|
129
|
+
schema: {
|
|
130
|
+
type: 'object',
|
|
131
|
+
properties: {
|
|
132
|
+
data: { type: 'object' }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
responses: {
|
|
139
|
+
200: { description: 'Updated' }
|
|
140
|
+
}
|
|
94
141
|
},
|
|
95
142
|
delete: {
|
|
96
143
|
summary: `Delete ${name}`,
|
|
97
144
|
tags: [name],
|
|
98
145
|
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
99
|
-
responses: {
|
|
146
|
+
responses: {
|
|
147
|
+
200: { description: 'Deleted' }
|
|
148
|
+
}
|
|
100
149
|
}
|
|
101
150
|
};
|
|
102
151
|
}
|
package/dist/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":";;AAcA,
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -8,4 +8,12 @@ export declare class ObjectQLServer {
|
|
|
8
8
|
* This is framework-agnostic.
|
|
9
9
|
*/
|
|
10
10
|
handle(req: ObjectQLRequest): Promise<ObjectQLResponse>;
|
|
11
|
+
/**
|
|
12
|
+
* Handle errors and convert them to appropriate error responses
|
|
13
|
+
*/
|
|
14
|
+
private handleError;
|
|
15
|
+
/**
|
|
16
|
+
* Create a standardized error response
|
|
17
|
+
*/
|
|
18
|
+
private errorResponse;
|
|
11
19
|
}
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ObjectQLServer = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
4
5
|
class ObjectQLServer {
|
|
5
6
|
constructor(app) {
|
|
6
7
|
this.app = app;
|
|
@@ -11,6 +12,16 @@ class ObjectQLServer {
|
|
|
11
12
|
*/
|
|
12
13
|
async handle(req) {
|
|
13
14
|
try {
|
|
15
|
+
// Log AI context if provided
|
|
16
|
+
if (req.ai_context) {
|
|
17
|
+
console.log('[ObjectQL AI Context]', {
|
|
18
|
+
object: req.object,
|
|
19
|
+
op: req.op,
|
|
20
|
+
intent: req.ai_context.intent,
|
|
21
|
+
natural_language: req.ai_context.natural_language,
|
|
22
|
+
use_case: req.ai_context.use_case
|
|
23
|
+
});
|
|
24
|
+
}
|
|
14
25
|
// 1. Build Context
|
|
15
26
|
// TODO: integrate with real session/auth
|
|
16
27
|
const contextOptions = {
|
|
@@ -23,9 +34,14 @@ class ObjectQLServer {
|
|
|
23
34
|
// We need to cast or fix the interface. Assuming 'app' behaves like ObjectQL class.
|
|
24
35
|
const app = this.app;
|
|
25
36
|
if (typeof app.createContext !== 'function') {
|
|
26
|
-
|
|
37
|
+
return this.errorResponse(types_1.ErrorCode.INTERNAL_ERROR, "The provided ObjectQL instance does not support createContext.");
|
|
27
38
|
}
|
|
28
39
|
const ctx = app.createContext(contextOptions);
|
|
40
|
+
// Validate object exists
|
|
41
|
+
const objectConfig = app.getObject(req.object);
|
|
42
|
+
if (!objectConfig) {
|
|
43
|
+
return this.errorResponse(types_1.ErrorCode.NOT_FOUND, `Object '${req.object}' not found`);
|
|
44
|
+
}
|
|
29
45
|
const repo = ctx.object(req.object);
|
|
30
46
|
let result;
|
|
31
47
|
switch (req.op) {
|
|
@@ -33,7 +49,13 @@ class ObjectQLServer {
|
|
|
33
49
|
result = await repo.find(req.args);
|
|
34
50
|
break;
|
|
35
51
|
case 'findOne':
|
|
36
|
-
|
|
52
|
+
// Support both string ID and query object
|
|
53
|
+
if (typeof req.args === 'string') {
|
|
54
|
+
result = await repo.findOne({ filters: [['_id', '=', req.args]] });
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
result = await repo.findOne(req.args);
|
|
58
|
+
}
|
|
37
59
|
break;
|
|
38
60
|
case 'create':
|
|
39
61
|
result = await repo.create(req.args);
|
|
@@ -43,33 +65,71 @@ class ObjectQLServer {
|
|
|
43
65
|
break;
|
|
44
66
|
case 'delete':
|
|
45
67
|
result = await repo.delete(req.args.id);
|
|
68
|
+
if (!result) {
|
|
69
|
+
return this.errorResponse(types_1.ErrorCode.NOT_FOUND, `Record with id '${req.args.id}' not found for delete`);
|
|
70
|
+
}
|
|
71
|
+
// Return standardized delete response on success
|
|
72
|
+
result = { id: req.args.id, deleted: true };
|
|
46
73
|
break;
|
|
47
74
|
case 'count':
|
|
48
75
|
result = await repo.count(req.args);
|
|
49
76
|
break;
|
|
50
77
|
case 'action':
|
|
51
|
-
//
|
|
52
|
-
// usually it's on the app level or via special method.
|
|
53
|
-
// For now, let's assume app.executeAction
|
|
78
|
+
// Map generic args to ActionContext
|
|
54
79
|
result = await app.executeAction(req.object, req.args.action, {
|
|
55
|
-
...ctx, // Pass context
|
|
56
|
-
|
|
80
|
+
...ctx, // Pass context (user, etc.)
|
|
81
|
+
id: req.args.id,
|
|
82
|
+
input: req.args.input || req.args.params // Support both for convenience
|
|
57
83
|
});
|
|
58
84
|
break;
|
|
59
85
|
default:
|
|
60
|
-
|
|
86
|
+
return this.errorResponse(types_1.ErrorCode.INVALID_REQUEST, `Unknown operation: ${req.op}`);
|
|
61
87
|
}
|
|
62
88
|
return { data: result };
|
|
63
89
|
}
|
|
64
90
|
catch (e) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
return this.handleError(e);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Handle errors and convert them to appropriate error responses
|
|
96
|
+
*/
|
|
97
|
+
handleError(error) {
|
|
98
|
+
console.error('[ObjectQL Server] Error:', error);
|
|
99
|
+
// Handle validation errors
|
|
100
|
+
if (error.name === 'ValidationError' || error.code === 'VALIDATION_ERROR') {
|
|
101
|
+
return this.errorResponse(types_1.ErrorCode.VALIDATION_ERROR, 'Validation failed', { fields: error.fields || error.details });
|
|
102
|
+
}
|
|
103
|
+
// Handle permission errors
|
|
104
|
+
if (error.name === 'PermissionError' || error.code === 'FORBIDDEN') {
|
|
105
|
+
return this.errorResponse(types_1.ErrorCode.FORBIDDEN, error.message || 'You do not have permission to access this resource', error.details);
|
|
72
106
|
}
|
|
107
|
+
// Handle not found errors
|
|
108
|
+
if (error.name === 'NotFoundError' || error.code === 'NOT_FOUND') {
|
|
109
|
+
return this.errorResponse(types_1.ErrorCode.NOT_FOUND, error.message || 'Resource not found');
|
|
110
|
+
}
|
|
111
|
+
// Handle conflict errors (e.g., unique constraint violations)
|
|
112
|
+
if (error.name === 'ConflictError' || error.code === 'CONFLICT') {
|
|
113
|
+
return this.errorResponse(types_1.ErrorCode.CONFLICT, error.message || 'Resource conflict', error.details);
|
|
114
|
+
}
|
|
115
|
+
// Handle database errors
|
|
116
|
+
if (error.name === 'DatabaseError' || error.code?.startsWith('DB_')) {
|
|
117
|
+
return this.errorResponse(types_1.ErrorCode.DATABASE_ERROR, 'Database operation failed', { originalError: error.message });
|
|
118
|
+
}
|
|
119
|
+
// Default to internal error
|
|
120
|
+
return this.errorResponse(types_1.ErrorCode.INTERNAL_ERROR, error.message || 'An error occurred');
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create a standardized error response
|
|
124
|
+
*/
|
|
125
|
+
errorResponse(code, message, details) {
|
|
126
|
+
return {
|
|
127
|
+
error: {
|
|
128
|
+
code,
|
|
129
|
+
message,
|
|
130
|
+
details
|
|
131
|
+
}
|
|
132
|
+
};
|
|
73
133
|
}
|
|
74
134
|
}
|
|
75
135
|
exports.ObjectQLServer = ObjectQLServer;
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|