@objectql/core 1.1.0 → 1.3.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 +15 -6
- package/dist/action.d.ts +7 -0
- package/dist/action.js +23 -0
- package/dist/action.js.map +1 -0
- package/dist/app.d.ts +28 -0
- package/dist/app.js +211 -0
- package/dist/app.js.map +1 -0
- package/dist/driver.d.ts +2 -17
- package/dist/driver.js +52 -0
- package/dist/driver.js.map +1 -1
- package/dist/hook.d.ts +8 -0
- package/dist/hook.js +25 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.d.ts +8 -25
- package/dist/index.js +8 -141
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +9 -4
- package/dist/loader.js +206 -9
- package/dist/loader.js.map +1 -1
- package/dist/object.d.ts +3 -0
- package/dist/object.js +28 -0
- package/dist/object.js.map +1 -0
- package/dist/plugin.d.ts +2 -0
- package/dist/plugin.js +56 -0
- package/dist/plugin.js.map +1 -0
- package/dist/remote.d.ts +8 -0
- package/dist/remote.js +43 -0
- package/dist/remote.js.map +1 -0
- package/dist/repository.d.ts +3 -5
- package/dist/repository.js +107 -112
- package/dist/repository.js.map +1 -1
- package/jest.config.js +3 -0
- package/package.json +11 -7
- package/src/action.ts +40 -0
- package/src/app.ts +257 -0
- package/src/driver.ts +51 -21
- package/src/hook.ts +42 -0
- package/src/index.ts +8 -158
- package/src/loader.ts +184 -9
- package/src/object.ts +26 -0
- package/src/plugin.ts +53 -0
- package/src/remote.ts +50 -0
- package/src/repository.ts +123 -127
- package/test/action.test.ts +58 -0
- package/test/fixtures/project.action.js +8 -0
- package/test/hook.test.ts +60 -0
- package/test/loader.test.ts +1 -8
- package/test/metadata.test.ts +1 -1
- package/test/mock-driver.ts +1 -1
- package/test/remote.test.ts +119 -0
- package/test/repository.test.ts +42 -49
- package/test/utils.ts +54 -0
- package/tsconfig.json +7 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/README.md +0 -53
- package/dist/metadata.d.ts +0 -104
- package/dist/metadata.js +0 -3
- package/dist/metadata.js.map +0 -1
- package/dist/query.d.ts +0 -10
- package/dist/query.js +0 -3
- package/dist/query.js.map +0 -1
- package/dist/registry.d.ts +0 -4
- package/dist/registry.js +0 -8
- package/dist/registry.js.map +0 -1
- package/dist/types.d.ts +0 -83
- package/dist/types.js +0 -6
- package/dist/types.js.map +0 -1
- package/src/metadata.ts +0 -143
- package/src/query.ts +0 -11
- package/src/registry.ts +0 -6
- package/src/types.ts +0 -115
- package/test/fixtures/project.action.ts +0 -6
package/dist/repository.js
CHANGED
|
@@ -25,88 +25,45 @@ class ObjectRepository {
|
|
|
25
25
|
}
|
|
26
26
|
return obj;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Construct HookContext
|
|
37
|
-
const hookContext = {
|
|
38
|
-
ctx: this.context,
|
|
39
|
-
entity: this.objectName,
|
|
40
|
-
op: op,
|
|
41
|
-
utils: {
|
|
42
|
-
restrict: (criterion) => {
|
|
43
|
-
if (op !== 'find' && op !== 'count') {
|
|
44
|
-
throw new Error('utils.restrict is only available in query operations');
|
|
45
|
-
}
|
|
46
|
-
const query = dataOrQuery;
|
|
47
|
-
if (!query.filters) {
|
|
48
|
-
query.filters = [criterion];
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
// Enclose existing filters in implicit AND group by array structure logic or explicit 'and'
|
|
52
|
-
// Implementation depends on how driver parses.
|
|
53
|
-
// Safe approach: filters = [ [criterion], 'and', [existing] ] or similar.
|
|
54
|
-
// For simplicity assuming array of terms means AND:
|
|
55
|
-
query.filters.push(criterion);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
getPreviousDoc: async () => {
|
|
60
|
-
// For update/delete, we might need the ID to find the doc.
|
|
61
|
-
// If doc has ID, use it.
|
|
62
|
-
// This is simplistic; usually 'update' takes 'id', we need to capture it from arguments.
|
|
63
|
-
if (op === 'create')
|
|
64
|
-
return undefined;
|
|
65
|
-
if (dataOrQuery._id || dataOrQuery.id) {
|
|
66
|
-
return this.findOne(dataOrQuery._id || dataOrQuery.id);
|
|
67
|
-
}
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
28
|
+
getHookAPI() {
|
|
29
|
+
return {
|
|
30
|
+
find: (obj, q) => this.context.object(obj).find(q),
|
|
31
|
+
findOne: (obj, id) => this.context.object(obj).findOne(id),
|
|
32
|
+
count: (obj, q) => this.context.object(obj).count(q),
|
|
33
|
+
create: (obj, data) => this.context.object(obj).create(data),
|
|
34
|
+
update: (obj, id, data) => this.context.object(obj).update(id, data),
|
|
35
|
+
delete: (obj, id) => this.context.object(obj).delete(id)
|
|
70
36
|
};
|
|
71
|
-
if (op === 'find' || op === 'count' || op === 'aggregate') {
|
|
72
|
-
hookContext.query = dataOrQuery;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
hookContext.doc = dataOrQuery;
|
|
76
|
-
}
|
|
77
|
-
// Pass ID manually if needed or attach to doc?
|
|
78
|
-
// For strictness, getPreviousDoc needs the ID passed to the operation.
|
|
79
|
-
// We'll rely on "doc" having the data being processed.
|
|
80
|
-
await hookFn(hookContext);
|
|
81
37
|
}
|
|
82
38
|
async find(query = {}) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
await this.executeHookForDoc('afterFind', 'find', item);
|
|
98
|
-
}
|
|
99
|
-
*/
|
|
100
|
-
}
|
|
101
|
-
return results;
|
|
39
|
+
const hookCtx = {
|
|
40
|
+
...this.context,
|
|
41
|
+
objectName: this.objectName,
|
|
42
|
+
operation: 'find',
|
|
43
|
+
api: this.getHookAPI(),
|
|
44
|
+
state: {},
|
|
45
|
+
query
|
|
46
|
+
};
|
|
47
|
+
await this.app.triggerHook('beforeFind', this.objectName, hookCtx);
|
|
48
|
+
// TODO: Apply basic filters like spaceId
|
|
49
|
+
const results = await this.getDriver().find(this.objectName, hookCtx.query || {}, this.getOptions());
|
|
50
|
+
hookCtx.result = results;
|
|
51
|
+
await this.app.triggerHook('afterFind', this.objectName, hookCtx);
|
|
52
|
+
return hookCtx.result;
|
|
102
53
|
}
|
|
103
54
|
async findOne(idOrQuery) {
|
|
104
55
|
if (typeof idOrQuery === 'string' || typeof idOrQuery === 'number') {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
56
|
+
const hookCtx = {
|
|
57
|
+
...this.context,
|
|
58
|
+
objectName: this.objectName,
|
|
59
|
+
operation: 'find',
|
|
60
|
+
api: this.getHookAPI(), state: {}, query: { _id: idOrQuery }
|
|
61
|
+
};
|
|
62
|
+
await this.app.triggerHook('beforeFind', this.objectName, hookCtx);
|
|
63
|
+
const result = await this.getDriver().findOne(this.objectName, idOrQuery, hookCtx.query, this.getOptions());
|
|
64
|
+
hookCtx.result = result;
|
|
65
|
+
await this.app.triggerHook('afterFind', this.objectName, hookCtx);
|
|
66
|
+
return hookCtx.result;
|
|
110
67
|
}
|
|
111
68
|
else {
|
|
112
69
|
const results = await this.find(idOrQuery);
|
|
@@ -114,41 +71,72 @@ class ObjectRepository {
|
|
|
114
71
|
}
|
|
115
72
|
}
|
|
116
73
|
async count(filters) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
74
|
+
const hookCtx = {
|
|
75
|
+
...this.context,
|
|
76
|
+
objectName: this.objectName,
|
|
77
|
+
operation: 'count',
|
|
78
|
+
api: this.getHookAPI(),
|
|
79
|
+
state: {},
|
|
80
|
+
query: filters
|
|
81
|
+
};
|
|
82
|
+
await this.app.triggerHook('beforeCount', this.objectName, hookCtx);
|
|
83
|
+
const result = await this.getDriver().count(this.objectName, hookCtx.query, this.getOptions());
|
|
84
|
+
hookCtx.result = result;
|
|
85
|
+
await this.app.triggerHook('afterCount', this.objectName, hookCtx);
|
|
86
|
+
return hookCtx.result;
|
|
121
87
|
}
|
|
122
88
|
async create(doc) {
|
|
89
|
+
const hookCtx = {
|
|
90
|
+
...this.context,
|
|
91
|
+
objectName: this.objectName,
|
|
92
|
+
operation: 'create',
|
|
93
|
+
state: {},
|
|
94
|
+
api: this.getHookAPI(),
|
|
95
|
+
data: doc
|
|
96
|
+
};
|
|
97
|
+
await this.app.triggerHook('beforeCreate', this.objectName, hookCtx);
|
|
98
|
+
const finalDoc = hookCtx.data || doc;
|
|
123
99
|
const obj = this.getSchema();
|
|
124
100
|
if (this.context.userId)
|
|
125
|
-
|
|
101
|
+
finalDoc.created_by = this.context.userId;
|
|
126
102
|
if (this.context.spaceId)
|
|
127
|
-
|
|
128
|
-
await this.
|
|
129
|
-
|
|
130
|
-
await this.
|
|
131
|
-
return result;
|
|
103
|
+
finalDoc.space_id = this.context.spaceId;
|
|
104
|
+
const result = await this.getDriver().create(this.objectName, finalDoc, this.getOptions());
|
|
105
|
+
hookCtx.result = result;
|
|
106
|
+
await this.app.triggerHook('afterCreate', this.objectName, hookCtx);
|
|
107
|
+
return hookCtx.result;
|
|
132
108
|
}
|
|
133
109
|
async update(id, doc, options) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
110
|
+
const hookCtx = {
|
|
111
|
+
...this.context,
|
|
112
|
+
objectName: this.objectName,
|
|
113
|
+
operation: 'update',
|
|
114
|
+
state: {},
|
|
115
|
+
api: this.getHookAPI(),
|
|
116
|
+
id,
|
|
117
|
+
data: doc,
|
|
118
|
+
isModified: (field) => hookCtx.data ? Object.prototype.hasOwnProperty.call(hookCtx.data, field) : false
|
|
119
|
+
};
|
|
120
|
+
await this.app.triggerHook('beforeUpdate', this.objectName, hookCtx);
|
|
121
|
+
const result = await this.getDriver().update(this.objectName, id, hookCtx.data, this.getOptions(options));
|
|
122
|
+
hookCtx.result = result;
|
|
123
|
+
await this.app.triggerHook('afterUpdate', this.objectName, hookCtx);
|
|
124
|
+
return hookCtx.result;
|
|
145
125
|
}
|
|
146
126
|
async delete(id) {
|
|
147
|
-
const
|
|
148
|
-
|
|
127
|
+
const hookCtx = {
|
|
128
|
+
...this.context,
|
|
129
|
+
objectName: this.objectName,
|
|
130
|
+
operation: 'delete',
|
|
131
|
+
state: {},
|
|
132
|
+
api: this.getHookAPI(),
|
|
133
|
+
id
|
|
134
|
+
};
|
|
135
|
+
await this.app.triggerHook('beforeDelete', this.objectName, hookCtx);
|
|
149
136
|
const result = await this.getDriver().delete(this.objectName, id, this.getOptions());
|
|
150
|
-
|
|
151
|
-
|
|
137
|
+
hookCtx.result = result;
|
|
138
|
+
await this.app.triggerHook('afterDelete', this.objectName, hookCtx);
|
|
139
|
+
return hookCtx.result;
|
|
152
140
|
}
|
|
153
141
|
async aggregate(query) {
|
|
154
142
|
const driver = this.getDriver();
|
|
@@ -169,7 +157,6 @@ class ObjectRepository {
|
|
|
169
157
|
return driver.findOneAndUpdate(this.objectName, filters, update, this.getOptions(options));
|
|
170
158
|
}
|
|
171
159
|
async createMany(data) {
|
|
172
|
-
// TODO: Triggers per record?
|
|
173
160
|
const driver = this.getDriver();
|
|
174
161
|
if (!driver.createMany) {
|
|
175
162
|
// Fallback
|
|
@@ -193,16 +180,24 @@ class ObjectRepository {
|
|
|
193
180
|
throw new Error("Driver does not support deleteMany");
|
|
194
181
|
return driver.deleteMany(this.objectName, filters, this.getOptions());
|
|
195
182
|
}
|
|
196
|
-
async
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
183
|
+
async execute(actionName, id, params) {
|
|
184
|
+
const api = {
|
|
185
|
+
find: (obj, q) => this.context.object(obj).find(q),
|
|
186
|
+
findOne: (obj, id) => this.context.object(obj).findOne(id),
|
|
187
|
+
count: (obj, q) => this.context.object(obj).count(q),
|
|
188
|
+
create: (obj, data) => this.context.object(obj).create(data),
|
|
189
|
+
update: (obj, id, data) => this.context.object(obj).update(id, data),
|
|
190
|
+
delete: (obj, id) => this.context.object(obj).delete(id)
|
|
191
|
+
};
|
|
192
|
+
const ctx = {
|
|
193
|
+
...this.context,
|
|
194
|
+
objectName: this.objectName,
|
|
195
|
+
actionName,
|
|
196
|
+
id,
|
|
197
|
+
input: params,
|
|
198
|
+
api
|
|
199
|
+
};
|
|
200
|
+
return await this.app.executeAction(this.objectName, actionName, ctx);
|
|
206
201
|
}
|
|
207
202
|
}
|
|
208
203
|
exports.ObjectRepository = ObjectRepository;
|
package/dist/repository.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"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"}
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectql/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"fast-glob": "^3.3.2",
|
|
8
|
+
"js-yaml": "^4.1.1",
|
|
9
|
+
"@objectql/types": "1.3.0",
|
|
10
|
+
"@objectql/driver-remote": "0.1.1"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"typescript": "^5.3.0"
|
|
14
|
+
},
|
|
6
15
|
"scripts": {
|
|
7
16
|
"build": "tsc",
|
|
8
17
|
"test": "jest"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"@objectql/metadata": "*",
|
|
12
|
-
"fast-glob": "^3.3.2",
|
|
13
|
-
"js-yaml": "^4.1.1"
|
|
14
18
|
}
|
|
15
|
-
}
|
|
19
|
+
}
|
package/src/action.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ActionContext, ActionHandler, MetadataRegistry } from '@objectql/types';
|
|
2
|
+
|
|
3
|
+
export interface ActionEntry {
|
|
4
|
+
handler: ActionHandler;
|
|
5
|
+
packageName?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function registerActionHelper(
|
|
9
|
+
actions: Record<string, ActionEntry>,
|
|
10
|
+
objectName: string,
|
|
11
|
+
actionName: string,
|
|
12
|
+
handler: ActionHandler,
|
|
13
|
+
packageName?: string
|
|
14
|
+
) {
|
|
15
|
+
const key = `${objectName}:${actionName}`;
|
|
16
|
+
actions[key] = { handler, packageName };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function executeActionHelper(
|
|
20
|
+
metadata: MetadataRegistry,
|
|
21
|
+
runtimeActions: Record<string, ActionEntry>,
|
|
22
|
+
objectName: string,
|
|
23
|
+
actionName: string,
|
|
24
|
+
ctx: ActionContext
|
|
25
|
+
) {
|
|
26
|
+
// 1. Programmatic
|
|
27
|
+
const key = `${objectName}:${actionName}`;
|
|
28
|
+
const actionEntry = runtimeActions[key];
|
|
29
|
+
if (actionEntry) {
|
|
30
|
+
return await actionEntry.handler(ctx);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 2. Registry (File-based)
|
|
34
|
+
const fileActions = metadata.get<any>('action', objectName);
|
|
35
|
+
if (fileActions && typeof fileActions[actionName] === 'function') {
|
|
36
|
+
return await fileActions[actionName](ctx);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
throw new Error(`Action '${actionName}' not found for object '${objectName}'`);
|
|
40
|
+
}
|
package/src/app.ts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MetadataRegistry,
|
|
3
|
+
Driver,
|
|
4
|
+
ObjectConfig,
|
|
5
|
+
ObjectQLContext,
|
|
6
|
+
ObjectQLContextOptions,
|
|
7
|
+
IObjectQL,
|
|
8
|
+
ObjectQLConfig,
|
|
9
|
+
ObjectQLPlugin,
|
|
10
|
+
HookName,
|
|
11
|
+
HookHandler,
|
|
12
|
+
HookContext,
|
|
13
|
+
ActionHandler,
|
|
14
|
+
ActionContext,
|
|
15
|
+
LoaderPlugin
|
|
16
|
+
} from '@objectql/types';
|
|
17
|
+
import { ObjectLoader } from './loader';
|
|
18
|
+
import { ObjectRepository } from './repository';
|
|
19
|
+
import { loadPlugin } from './plugin';
|
|
20
|
+
import { createDriverFromConnection } from './driver';
|
|
21
|
+
import { loadRemoteFromUrl } from './remote';
|
|
22
|
+
import { executeActionHelper, registerActionHelper, ActionEntry } from './action';
|
|
23
|
+
import { registerHookHelper, triggerHookHelper, HookEntry } from './hook';
|
|
24
|
+
import { registerObjectHelper, getConfigsHelper } from './object';
|
|
25
|
+
|
|
26
|
+
export class ObjectQL implements IObjectQL {
|
|
27
|
+
public metadata: MetadataRegistry;
|
|
28
|
+
private loader: ObjectLoader;
|
|
29
|
+
private datasources: Record<string, Driver> = {};
|
|
30
|
+
private remotes: string[] = [];
|
|
31
|
+
private hooks: Record<string, HookEntry[]> = {};
|
|
32
|
+
private actions: Record<string, ActionEntry> = {};
|
|
33
|
+
private pluginsList: ObjectQLPlugin[] = [];
|
|
34
|
+
|
|
35
|
+
// Store config for lazy loading in init()
|
|
36
|
+
private config: ObjectQLConfig;
|
|
37
|
+
|
|
38
|
+
constructor(config: ObjectQLConfig) {
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.metadata = config.registry || new MetadataRegistry();
|
|
41
|
+
this.loader = new ObjectLoader(this.metadata);
|
|
42
|
+
this.datasources = config.datasources || {};
|
|
43
|
+
this.remotes = config.remotes || [];
|
|
44
|
+
|
|
45
|
+
if (config.connection) {
|
|
46
|
+
this.datasources['default'] = createDriverFromConnection(config.connection);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Initialize Plugin List (but don't setup yet)
|
|
50
|
+
if (config.plugins) {
|
|
51
|
+
for (const plugin of config.plugins) {
|
|
52
|
+
if (typeof plugin === 'string') {
|
|
53
|
+
this.use(loadPlugin(plugin));
|
|
54
|
+
} else {
|
|
55
|
+
this.use(plugin);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
addPackage(name: string) {
|
|
62
|
+
this.loader.loadPackage(name);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
use(plugin: ObjectQLPlugin) {
|
|
66
|
+
this.pluginsList.push(plugin);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
removePackage(name: string) {
|
|
70
|
+
this.metadata.unregisterPackage(name);
|
|
71
|
+
|
|
72
|
+
// Remove hooks
|
|
73
|
+
for (const event of Object.keys(this.hooks)) {
|
|
74
|
+
this.hooks[event] = this.hooks[event].filter(h => h.packageName !== name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Remove actions
|
|
78
|
+
for (const key of Object.keys(this.actions)) {
|
|
79
|
+
if (this.actions[key].packageName === name) {
|
|
80
|
+
delete this.actions[key];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
on(event: HookName, objectName: string, handler: HookHandler, packageName?: string) {
|
|
86
|
+
registerHookHelper(this.hooks, event, objectName, handler, packageName);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async triggerHook(event: HookName, objectName: string, ctx: HookContext) {
|
|
90
|
+
await triggerHookHelper(this.metadata, this.hooks, event, objectName, ctx);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
registerAction(objectName: string, actionName: string, handler: ActionHandler, packageName?: string) {
|
|
94
|
+
registerActionHelper(this.actions, objectName, actionName, handler, packageName);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async executeAction(objectName: string, actionName: string, ctx: ActionContext) {
|
|
98
|
+
return await executeActionHelper(this.metadata, this.actions, objectName, actionName, ctx);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
loadFromDirectory(dir: string, packageName?: string) {
|
|
102
|
+
this.loader.load(dir, packageName);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
addLoader(plugin: LoaderPlugin) {
|
|
106
|
+
this.loader.use(plugin);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
createContext(options: ObjectQLContextOptions): ObjectQLContext {
|
|
110
|
+
const ctx: ObjectQLContext = {
|
|
111
|
+
userId: options.userId,
|
|
112
|
+
spaceId: options.spaceId,
|
|
113
|
+
roles: options.roles || [],
|
|
114
|
+
isSystem: options.isSystem,
|
|
115
|
+
object: (name: string) => {
|
|
116
|
+
return new ObjectRepository(name, ctx, this);
|
|
117
|
+
},
|
|
118
|
+
transaction: async (callback) => {
|
|
119
|
+
const driver = this.datasources['default'];
|
|
120
|
+
if (!driver || !driver.beginTransaction) {
|
|
121
|
+
return callback(ctx);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let trx: any;
|
|
125
|
+
try {
|
|
126
|
+
trx = await driver.beginTransaction();
|
|
127
|
+
} catch (e) {
|
|
128
|
+
throw e;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const trxCtx: ObjectQLContext = {
|
|
132
|
+
...ctx,
|
|
133
|
+
transactionHandle: trx,
|
|
134
|
+
transaction: async (cb) => cb(trxCtx)
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const result = await callback(trxCtx);
|
|
139
|
+
if (driver.commitTransaction) await driver.commitTransaction(trx);
|
|
140
|
+
return result;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (driver.rollbackTransaction) await driver.rollbackTransaction(trx);
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
sudo: () => {
|
|
147
|
+
return this.createContext({ ...options, isSystem: true });
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
return ctx;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
registerObject(object: ObjectConfig) {
|
|
154
|
+
registerObjectHelper(this.metadata, object);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
unregisterObject(name: string) {
|
|
158
|
+
this.metadata.unregister('object', name);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
getObject(name: string): ObjectConfig | undefined {
|
|
162
|
+
return this.metadata.get<ObjectConfig>('object', name);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
getConfigs(): Record<string, ObjectConfig> {
|
|
166
|
+
return getConfigsHelper(this.metadata);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
datasource(name: string): Driver {
|
|
170
|
+
const driver = this.datasources[name];
|
|
171
|
+
if (!driver) {
|
|
172
|
+
throw new Error(`Datasource '${name}' not found`);
|
|
173
|
+
}
|
|
174
|
+
return driver;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async init() {
|
|
178
|
+
// 0. Init Plugins (This allows plugins to register custom loaders)
|
|
179
|
+
for (const plugin of this.pluginsList) {
|
|
180
|
+
console.log(`Initializing plugin '${plugin.name}'...`);
|
|
181
|
+
|
|
182
|
+
let app: IObjectQL = this;
|
|
183
|
+
const pkgName = (plugin as any)._packageName;
|
|
184
|
+
|
|
185
|
+
if (pkgName) {
|
|
186
|
+
app = new Proxy(this, {
|
|
187
|
+
get(target, prop) {
|
|
188
|
+
if (prop === 'on') {
|
|
189
|
+
return (event: HookName, obj: string, handler: HookHandler) =>
|
|
190
|
+
target.on(event, obj, handler, pkgName);
|
|
191
|
+
}
|
|
192
|
+
if (prop === 'registerAction') {
|
|
193
|
+
return (obj: string, act: string, handler: ActionHandler) =>
|
|
194
|
+
target.registerAction(obj, act, handler, pkgName);
|
|
195
|
+
}
|
|
196
|
+
const value = (target as any)[prop];
|
|
197
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
await plugin.setup(app);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 1. Load Presets/Packages (Base Layer) - AFTER plugins, so they can use new loaders
|
|
206
|
+
if (this.config.packages) {
|
|
207
|
+
for (const name of this.config.packages) {
|
|
208
|
+
this.addPackage(name);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (this.config.presets) {
|
|
212
|
+
for (const name of this.config.presets) {
|
|
213
|
+
this.addPackage(name);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// 2. Load Local Sources (Application Layer)
|
|
218
|
+
if (this.config.source) {
|
|
219
|
+
const sources = Array.isArray(this.config.source) ? this.config.source : [this.config.source];
|
|
220
|
+
for (const src of sources) {
|
|
221
|
+
this.loader.load(src);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// 3. Load In-Memory Objects (Dynamic Layer)
|
|
226
|
+
if (this.config.objects) {
|
|
227
|
+
for (const [key, obj] of Object.entries(this.config.objects)) {
|
|
228
|
+
this.registerObject(obj);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// 4. Load Remotes
|
|
233
|
+
if (this.remotes.length > 0) {
|
|
234
|
+
console.log(`Loading ${this.remotes.length} remotes...`);
|
|
235
|
+
const results = await Promise.all(this.remotes.map(url => loadRemoteFromUrl(url)));
|
|
236
|
+
for (const res of results) {
|
|
237
|
+
if (res) {
|
|
238
|
+
this.datasources[res.driverName] = res.driver;
|
|
239
|
+
for (const obj of res.objects) {
|
|
240
|
+
this.registerObject(obj);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const objects = this.metadata.list<ObjectConfig>('object');
|
|
247
|
+
|
|
248
|
+
// 5. Init Drivers (e.g. Sync Schema)
|
|
249
|
+
// Let's pass all objects to all configured drivers.
|
|
250
|
+
for (const [name, driver] of Object.entries(this.datasources)) {
|
|
251
|
+
if (driver.init) {
|
|
252
|
+
console.log(`Initializing driver '${name}'...`);
|
|
253
|
+
await driver.init(objects);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|