@objectql/api 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 ADDED
@@ -0,0 +1,12 @@
1
+ # @objectql/api
2
+
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - first release
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @objectql/core@1.0.0
@@ -0,0 +1,11 @@
1
+ import { Router, Request, Response } from 'express';
2
+ import { IObjectQL, ObjectQLContext } from '@objectql/core';
3
+ export interface ObjectQLServerOptions {
4
+ objectql: IObjectQL;
5
+ getContext?: (req: Request, res: Response) => Promise<ObjectQLContext> | ObjectQLContext;
6
+ swagger?: {
7
+ enabled: boolean;
8
+ path?: string;
9
+ };
10
+ }
11
+ export declare function createObjectQLRouter(options: ObjectQLServerOptions): Router;
package/dist/index.js ADDED
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createObjectQLRouter = createObjectQLRouter;
7
+ const express_1 = require("express");
8
+ const swagger_ui_express_1 = __importDefault(require("swagger-ui-express"));
9
+ const generator_1 = require("./swagger/generator");
10
+ function createObjectQLRouter(options) {
11
+ const router = (0, express_1.Router)();
12
+ const { objectql, getContext, swagger } = options;
13
+ if (swagger && swagger.enabled) {
14
+ const docPath = swagger.path || '/docs';
15
+ const spec = (0, generator_1.generateOpenApiSpec)(objectql);
16
+ router.use(docPath, swagger_ui_express_1.default.serve, swagger_ui_express_1.default.setup(spec));
17
+ console.log(`Swagger UI available at ${docPath}`);
18
+ }
19
+ const getCtx = async (req, res) => {
20
+ if (getContext) {
21
+ return await getContext(req, res);
22
+ }
23
+ return {
24
+ roles: [],
25
+ object: (name) => { throw new Error("Not implemented in default context stub"); },
26
+ transaction: async (cb) => cb({}),
27
+ sudo: () => ({})
28
+ };
29
+ };
30
+ const getRepo = async (req, res, objectName) => {
31
+ const ctx = await getCtx(req, res);
32
+ return ctx.object(objectName);
33
+ };
34
+ // Helper: Parse UnifiedQuery from Request
35
+ const parseQuery = (req) => {
36
+ const query = {};
37
+ const q = req.query;
38
+ // 1. Fields
39
+ if (q.fields) {
40
+ if (typeof q.fields === 'string') {
41
+ query.fields = q.fields.split(',');
42
+ }
43
+ }
44
+ // 2. Filters
45
+ if (q.filters) {
46
+ try {
47
+ if (typeof q.filters === 'string') {
48
+ query.filters = JSON.parse(q.filters);
49
+ }
50
+ }
51
+ catch (e) {
52
+ throw new Error("Invalid filters JSON");
53
+ }
54
+ }
55
+ // 3. Sort
56
+ // Format: ?sort=item1:asc,item2:desc OR ?sort=[["item1","asc"]]
57
+ if (q.sort) {
58
+ if (typeof q.sort === 'string') {
59
+ // Check if JSON
60
+ if (q.sort.startsWith('[')) {
61
+ try {
62
+ query.sort = JSON.parse(q.sort);
63
+ }
64
+ catch { }
65
+ }
66
+ else {
67
+ // split by comma
68
+ query.sort = q.sort.split(',').map(part => {
69
+ const [field, order] = part.split(':');
70
+ return [field, (order || 'asc').toLowerCase() === 'desc' ? 'desc' : 'asc'];
71
+ });
72
+ }
73
+ }
74
+ }
75
+ // 4. Pagination
76
+ if (q.top || q.limit) {
77
+ query.limit = parseInt((q.top || q.limit));
78
+ }
79
+ if (q.skip || q.offset) {
80
+ query.skip = parseInt((q.skip || q.offset));
81
+ }
82
+ // 5. Expand
83
+ // ?expand=items,details OR ?expand={"items":{"fields":["name"]}}
84
+ if (q.expand) {
85
+ if (typeof q.expand === 'string') {
86
+ if (q.expand.startsWith('{')) {
87
+ try {
88
+ query.expand = JSON.parse(q.expand);
89
+ }
90
+ catch { }
91
+ }
92
+ else {
93
+ query.expand = {};
94
+ q.expand.split(',').forEach(field => {
95
+ // Simple expand implies selecting all or default fields
96
+ // UnifiedQuery expects sub-query
97
+ query.expand[field] = {};
98
+ });
99
+ }
100
+ }
101
+ }
102
+ return query;
103
+ };
104
+ // === Special Endpoints (Must come before /:objectName) ===
105
+ router.get('/_schema', async (req, res) => {
106
+ try {
107
+ const configs = objectql.getConfigs();
108
+ res.json(configs);
109
+ }
110
+ catch (e) {
111
+ res.status(500).json({ error: e.message });
112
+ }
113
+ });
114
+ // NONE for now, as :objectName is the root.
115
+ // However, we might want /:objectName/count or /:objectName/aggregate.
116
+ // === Collection Routes ===
117
+ // count
118
+ router.get('/:objectName/count', async (req, res) => {
119
+ try {
120
+ const { objectName } = req.params;
121
+ const repo = await getRepo(req, res, objectName);
122
+ let filters = undefined;
123
+ if (req.query.filters) {
124
+ try {
125
+ filters = JSON.parse(req.query.filters);
126
+ }
127
+ catch {
128
+ return res.status(400).json({ error: "Invalid filters JSON" });
129
+ }
130
+ }
131
+ const count = await repo.count(filters);
132
+ res.json({ count });
133
+ }
134
+ catch (e) {
135
+ res.status(500).json({ error: e.message });
136
+ }
137
+ });
138
+ // aggregate
139
+ router.post('/:objectName/aggregate', async (req, res) => {
140
+ try {
141
+ const { objectName } = req.params;
142
+ const repo = await getRepo(req, res, objectName);
143
+ const pipeline = req.body;
144
+ if (!Array.isArray(pipeline)) {
145
+ return res.status(400).json({ error: "Pipeline must be an array" });
146
+ }
147
+ const result = await repo.aggregate(pipeline);
148
+ res.json(result);
149
+ }
150
+ catch (e) {
151
+ res.status(500).json({ error: e.message });
152
+ }
153
+ });
154
+ // delete many
155
+ router.delete('/:objectName', async (req, res) => {
156
+ try {
157
+ const { objectName } = req.params;
158
+ if (!req.query.filters) {
159
+ return res.status(400).json({ error: "filters parameter is required for bulk delete" });
160
+ }
161
+ const repo = await getRepo(req, res, objectName);
162
+ let filters;
163
+ try {
164
+ filters = JSON.parse(req.query.filters);
165
+ }
166
+ catch {
167
+ return res.status(400).json({ error: "Invalid filters JSON" });
168
+ }
169
+ const result = await repo.deleteMany(filters);
170
+ res.json(result);
171
+ }
172
+ catch (e) {
173
+ res.status(500).json({ error: e.message });
174
+ }
175
+ });
176
+ // list
177
+ router.get('/:objectName', async (req, res) => {
178
+ try {
179
+ const { objectName } = req.params;
180
+ const repo = await getRepo(req, res, objectName);
181
+ const query = parseQuery(req);
182
+ const results = await repo.find(query);
183
+ res.json(results);
184
+ }
185
+ catch (e) {
186
+ res.status(500).json({ error: e.message });
187
+ }
188
+ });
189
+ // create (one or many)
190
+ router.post('/:objectName', async (req, res) => {
191
+ try {
192
+ const { objectName } = req.params;
193
+ const repo = await getRepo(req, res, objectName);
194
+ if (Array.isArray(req.body)) {
195
+ const results = await repo.createMany(req.body);
196
+ res.status(201).json(results);
197
+ }
198
+ else {
199
+ const result = await repo.create(req.body);
200
+ res.status(201).json(result);
201
+ }
202
+ }
203
+ catch (e) {
204
+ res.status(500).json({ error: e.message });
205
+ }
206
+ });
207
+ // === Item Routes ===
208
+ // run action
209
+ router.post('/:objectName/:id/:actionName', async (req, res) => {
210
+ try {
211
+ const { objectName, id, actionName } = req.params;
212
+ const repo = await getRepo(req, res, objectName);
213
+ // Params merging body and id? Usually action needs specific params.
214
+ // Let's pass body as params.
215
+ const params = {
216
+ id,
217
+ ...req.body
218
+ };
219
+ const result = await repo.call(actionName, params);
220
+ res.json(result);
221
+ }
222
+ catch (e) {
223
+ res.status(500).json({ error: e.message });
224
+ }
225
+ });
226
+ router.get('/:objectName/:id', async (req, res) => {
227
+ try {
228
+ const { objectName, id } = req.params;
229
+ const repo = await getRepo(req, res, objectName);
230
+ // Allow expand here too?
231
+ // findOne takes id or query.
232
+ // If expand is needed, we should construct a query with filters: {_id: id}
233
+ if (req.query.expand || req.query.fields) {
234
+ const query = parseQuery(req);
235
+ // Force filter by ID
236
+ // Note: normalized ID vs string ID.
237
+ query.filters = [['_id', '=', id]]; // or 'id' depending on driver
238
+ const results = await repo.find(query);
239
+ if (!results.length) {
240
+ return res.status(404).json({ error: "Not found" });
241
+ }
242
+ return res.json(results[0]);
243
+ }
244
+ const result = await repo.findOne(id);
245
+ if (!result) {
246
+ return res.status(404).json({ error: "Not found" });
247
+ }
248
+ res.json(result);
249
+ }
250
+ catch (e) {
251
+ res.status(500).json({ error: e.message });
252
+ }
253
+ });
254
+ router.put('/:objectName/:id', async (req, res) => {
255
+ try {
256
+ const { objectName, id } = req.params;
257
+ const repo = await getRepo(req, res, objectName);
258
+ const result = await repo.update(id, req.body);
259
+ res.json(result);
260
+ }
261
+ catch (e) {
262
+ res.status(500).json({ error: e.message });
263
+ }
264
+ });
265
+ router.delete('/:objectName/:id', async (req, res) => {
266
+ try {
267
+ const { objectName, id } = req.params;
268
+ const repo = await getRepo(req, res, objectName);
269
+ await repo.delete(id);
270
+ res.status(204).send();
271
+ }
272
+ catch (e) {
273
+ res.status(500).json({ error: e.message });
274
+ }
275
+ });
276
+ return router;
277
+ }
278
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { IObjectQL } from '@objectql/core';
2
+ export declare function generateOpenApiSpec(objectql: IObjectQL): {
3
+ openapi: string;
4
+ info: {
5
+ title: string;
6
+ version: string;
7
+ };
8
+ paths: any;
9
+ components: {
10
+ schemas: any;
11
+ };
12
+ };
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateOpenApiSpec = generateOpenApiSpec;
4
+ function generateOpenApiSpec(objectql) {
5
+ const configs = objectql.getConfigs();
6
+ const paths = {};
7
+ const schemas = {};
8
+ Object.values(configs).forEach((config) => {
9
+ const objectName = config.name;
10
+ const schemaName = objectName;
11
+ // 1. Define Schema
12
+ schemas[schemaName] = {
13
+ type: 'object',
14
+ properties: mapFieldsToProperties(config.fields)
15
+ };
16
+ // 2. Define Paths
17
+ const basePath = `/api/${objectName}`;
18
+ // GET /api/{obj} - List
19
+ paths[basePath] = {
20
+ get: {
21
+ summary: `List ${config.label || objectName}`,
22
+ tags: [config.label || objectName],
23
+ parameters: [
24
+ {
25
+ name: 'fields',
26
+ in: 'query',
27
+ description: 'Comma separated fields to return',
28
+ schema: { type: 'string' }
29
+ },
30
+ {
31
+ name: 'filters',
32
+ in: 'query',
33
+ description: 'JSON string of filters',
34
+ schema: { type: 'string' }
35
+ },
36
+ ],
37
+ responses: {
38
+ 200: {
39
+ description: 'Success',
40
+ content: {
41
+ 'application/json': {
42
+ schema: {
43
+ type: 'array',
44
+ items: { $ref: `#/components/schemas/${schemaName}` }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ },
51
+ // POST /api/{obj} - Create
52
+ post: {
53
+ summary: `Create ${config.label || objectName}`,
54
+ tags: [config.label || objectName],
55
+ requestBody: {
56
+ required: true,
57
+ content: {
58
+ 'application/json': {
59
+ schema: { $ref: `#/components/schemas/${schemaName}` }
60
+ }
61
+ }
62
+ },
63
+ responses: {
64
+ 201: {
65
+ description: 'Created',
66
+ content: {
67
+ 'application/json': {
68
+ schema: { $ref: `#/components/schemas/${schemaName}` }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ };
75
+ // /{id} operations
76
+ const itemPath = `${basePath}/{id}`;
77
+ paths[itemPath] = {
78
+ // GET - Retrieve
79
+ get: {
80
+ summary: `Get ${config.label || objectName}`,
81
+ tags: [config.label || objectName],
82
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
83
+ responses: {
84
+ 200: {
85
+ description: 'Success',
86
+ content: {
87
+ 'application/json': {
88
+ schema: { $ref: `#/components/schemas/${schemaName}` }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ },
94
+ // PUT - Update
95
+ put: {
96
+ summary: `Update ${config.label || objectName}`,
97
+ tags: [config.label || objectName],
98
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
99
+ requestBody: {
100
+ required: true,
101
+ content: {
102
+ 'application/json': {
103
+ schema: {
104
+ type: 'object',
105
+ properties: mapFieldsToProperties(config.fields)
106
+ }
107
+ }
108
+ }
109
+ },
110
+ responses: {
111
+ 200: { description: 'Updated' }
112
+ }
113
+ },
114
+ // DELETE
115
+ delete: {
116
+ summary: `Delete ${config.label || objectName}`,
117
+ tags: [config.label || objectName],
118
+ parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
119
+ responses: {
120
+ 200: { description: 'Deleted' }
121
+ }
122
+ }
123
+ };
124
+ });
125
+ return {
126
+ openapi: '3.0.0',
127
+ info: {
128
+ title: 'ObjectQL API',
129
+ version: '1.0.0',
130
+ },
131
+ paths,
132
+ components: {
133
+ schemas
134
+ }
135
+ };
136
+ }
137
+ function mapFieldsToProperties(fields) {
138
+ const props = {};
139
+ Object.entries(fields).forEach(([key, field]) => {
140
+ props[key] = {
141
+ type: mapType(field.type),
142
+ description: field.label
143
+ };
144
+ });
145
+ // Add _id
146
+ props['_id'] = { type: 'string' };
147
+ return props;
148
+ }
149
+ function mapType(objectType) {
150
+ switch (objectType) {
151
+ case 'number':
152
+ case 'currency':
153
+ return 'number';
154
+ case 'boolean':
155
+ return 'boolean';
156
+ case 'date':
157
+ case 'datetime':
158
+ return 'string'; // format: date-time ideally
159
+ default:
160
+ return 'string';
161
+ }
162
+ }
163
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/swagger/generator.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ testMatch: ['**/test/**/*.test.ts'],
5
+ };
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@objectql/api",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "test": "jest"
9
+ },
10
+ "dependencies": {
11
+ "@objectql/core": "^1.0.0",
12
+ "express": "^4.18.2",
13
+ "swagger-ui-express": "^5.0.1"
14
+ },
15
+ "devDependencies": {
16
+ "@types/express": "^4.17.17",
17
+ "@types/swagger-ui-express": "^4.1.8",
18
+ "typescript": "^5.9.3"
19
+ }
20
+ }