@objectql/core 1.0.0 → 1.1.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 +11 -0
- package/README.md +53 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.js +31 -50
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +5 -0
- package/dist/loader.js +17 -203
- package/dist/loader.js.map +1 -1
- package/dist/registry.d.ts +4 -0
- package/dist/registry.js +8 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -2
- package/src/index.ts +37 -27
- package/src/loader.ts +17 -189
- package/src/registry.ts +6 -0
- package/src/types.ts +6 -0
- package/test/dynamic.test.ts +34 -0
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @objectql/core
|
|
2
|
+
|
|
3
|
+
The core ORM and runtime engine for ObjectQL. This package handles object querying, CRUD operations, database driver coordination, and transaction management.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Unified Query Language**: A generic way to query data across different databases (SQL, Mongo, etc.).
|
|
8
|
+
- **Repository Pattern**: `ObjectRepository` for managing object records.
|
|
9
|
+
- **Driver Agnostic**: Abstraction layer for database drivers.
|
|
10
|
+
- **Dynamic Schema**: Loads object definitions from `@objectql/metadata`.
|
|
11
|
+
- **Hooks & Actions**: Runtime logic injection.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @objectql/core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { ObjectQL } from '@objectql/core';
|
|
23
|
+
import { MetadataRegistry } from '@objectql/metadata';
|
|
24
|
+
// Import a driver, e.g., @objectql/driver-knex
|
|
25
|
+
|
|
26
|
+
const objectql = new ObjectQL({
|
|
27
|
+
datasources: {
|
|
28
|
+
default: new MyDriver({ ... })
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
await objectql.init();
|
|
33
|
+
|
|
34
|
+
// Use context for operations
|
|
35
|
+
const ctx = objectql.createContext({ userId: 'u-1' });
|
|
36
|
+
const projects = await ctx.object('project').find({
|
|
37
|
+
filters: [['status', '=', 'active']]
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Shared Metadata
|
|
42
|
+
|
|
43
|
+
You can pass an existing `MetadataRegistry` (e.g., from a low-code platform loader) to ObjectQL:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const registry = new MetadataRegistry();
|
|
47
|
+
// ... pre-load metadata ...
|
|
48
|
+
|
|
49
|
+
const objectql = new ObjectQL({
|
|
50
|
+
registry: registry,
|
|
51
|
+
datasources: { ... }
|
|
52
|
+
});
|
|
53
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -3,15 +3,20 @@ export * from './types';
|
|
|
3
3
|
export * from './driver';
|
|
4
4
|
export * from './repository';
|
|
5
5
|
export * from './query';
|
|
6
|
+
export * from './registry';
|
|
7
|
+
export * from './loader';
|
|
6
8
|
import { ObjectConfig } from './metadata';
|
|
7
9
|
import { ObjectQLContext, ObjectQLContextOptions, IObjectQL, ObjectQLConfig } from './types';
|
|
8
10
|
import { Driver } from './driver';
|
|
11
|
+
import { MetadataRegistry } from './registry';
|
|
9
12
|
export declare class ObjectQL implements IObjectQL {
|
|
10
|
-
|
|
13
|
+
metadata: MetadataRegistry;
|
|
14
|
+
private loader;
|
|
11
15
|
private datasources;
|
|
12
16
|
constructor(config: ObjectQLConfig);
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
addPackage(name: string): void;
|
|
18
|
+
removePackage(name: string): void;
|
|
19
|
+
loadFromDirectory(dir: string, packageName?: string): void;
|
|
15
20
|
createContext(options: ObjectQLContextOptions): ObjectQLContext;
|
|
16
21
|
registerObject(object: ObjectConfig): void;
|
|
17
22
|
getObject(name: string): ObjectConfig | undefined;
|
package/dist/index.js
CHANGED
|
@@ -10,45 +10,26 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
12
|
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
36
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
15
|
};
|
|
38
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
17
|
exports.ObjectQL = void 0;
|
|
40
|
-
const path = __importStar(require("path"));
|
|
41
18
|
__exportStar(require("./metadata"), exports);
|
|
42
19
|
__exportStar(require("./types"), exports);
|
|
43
20
|
__exportStar(require("./driver"), exports);
|
|
44
21
|
__exportStar(require("./repository"), exports);
|
|
45
22
|
__exportStar(require("./query"), exports);
|
|
23
|
+
__exportStar(require("./registry"), exports);
|
|
24
|
+
__exportStar(require("./loader"), exports);
|
|
46
25
|
const repository_1 = require("./repository");
|
|
47
26
|
const loader_1 = require("./loader");
|
|
27
|
+
const registry_1 = require("./registry");
|
|
48
28
|
class ObjectQL {
|
|
49
29
|
constructor(config) {
|
|
50
|
-
this.objects = {};
|
|
51
30
|
this.datasources = {};
|
|
31
|
+
this.metadata = config.registry || new registry_1.MetadataRegistry();
|
|
32
|
+
this.loader = new loader_1.MetadataLoader(this.metadata);
|
|
52
33
|
this.datasources = config.datasources;
|
|
53
34
|
if (config.objects) {
|
|
54
35
|
for (const [key, obj] of Object.entries(config.objects)) {
|
|
@@ -57,25 +38,18 @@ class ObjectQL {
|
|
|
57
38
|
}
|
|
58
39
|
if (config.packages) {
|
|
59
40
|
for (const name of config.packages) {
|
|
60
|
-
|
|
61
|
-
this.loadFromPackage(name);
|
|
62
|
-
}
|
|
63
|
-
catch (e) {
|
|
64
|
-
this.loadFromDirectory(name);
|
|
65
|
-
}
|
|
41
|
+
this.addPackage(name);
|
|
66
42
|
}
|
|
67
43
|
}
|
|
68
44
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const packageDir = path.dirname(entryPath);
|
|
72
|
-
this.loadFromDirectory(packageDir);
|
|
45
|
+
addPackage(name) {
|
|
46
|
+
this.loader.loadPackage(name);
|
|
73
47
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
48
|
+
removePackage(name) {
|
|
49
|
+
this.metadata.unregisterPackage(name);
|
|
50
|
+
}
|
|
51
|
+
loadFromDirectory(dir, packageName) {
|
|
52
|
+
this.loader.load(dir, packageName);
|
|
79
53
|
}
|
|
80
54
|
createContext(options) {
|
|
81
55
|
const ctx = {
|
|
@@ -97,13 +71,11 @@ class ObjectQL {
|
|
|
97
71
|
trx = await driver.beginTransaction();
|
|
98
72
|
}
|
|
99
73
|
catch (e) {
|
|
100
|
-
// If beginTransaction fails, fail.
|
|
101
74
|
throw e;
|
|
102
75
|
}
|
|
103
76
|
const trxCtx = {
|
|
104
77
|
...ctx,
|
|
105
78
|
transactionHandle: trx,
|
|
106
|
-
// Nested transaction simply reuses the current one (flat transaction)
|
|
107
79
|
transaction: async (cb) => cb(trxCtx)
|
|
108
80
|
};
|
|
109
81
|
try {
|
|
@@ -133,13 +105,22 @@ class ObjectQL {
|
|
|
133
105
|
}
|
|
134
106
|
}
|
|
135
107
|
}
|
|
136
|
-
this.
|
|
108
|
+
this.metadata.register('object', {
|
|
109
|
+
type: 'object',
|
|
110
|
+
id: object.name,
|
|
111
|
+
content: object
|
|
112
|
+
});
|
|
137
113
|
}
|
|
138
114
|
getObject(name) {
|
|
139
|
-
return this.
|
|
115
|
+
return this.metadata.get('object', name);
|
|
140
116
|
}
|
|
141
117
|
getConfigs() {
|
|
142
|
-
|
|
118
|
+
const result = {};
|
|
119
|
+
const objects = this.metadata.list('object');
|
|
120
|
+
for (const obj of objects) {
|
|
121
|
+
result[obj.name] = obj;
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
143
124
|
}
|
|
144
125
|
datasource(name) {
|
|
145
126
|
const driver = this.datasources[name];
|
|
@@ -150,11 +131,11 @@ class ObjectQL {
|
|
|
150
131
|
}
|
|
151
132
|
async init() {
|
|
152
133
|
const ctx = this.createContext({ isSystem: true });
|
|
153
|
-
|
|
154
|
-
|
|
134
|
+
const objects = this.metadata.list('object');
|
|
135
|
+
for (const obj of objects) {
|
|
155
136
|
if (obj.data && obj.data.length > 0) {
|
|
156
|
-
console.log(`Initializing data for object ${
|
|
157
|
-
const repo = ctx.object(
|
|
137
|
+
console.log(`Initializing data for object ${obj.name}...`);
|
|
138
|
+
const repo = ctx.object(obj.name);
|
|
158
139
|
for (const record of obj.data) {
|
|
159
140
|
try {
|
|
160
141
|
if (record._id) {
|
|
@@ -164,10 +145,10 @@ class ObjectQL {
|
|
|
164
145
|
}
|
|
165
146
|
}
|
|
166
147
|
await repo.create(record);
|
|
167
|
-
console.log(`Inserted init data for ${
|
|
148
|
+
console.log(`Inserted init data for ${obj.name}: ${record._id || 'unknown id'}`);
|
|
168
149
|
}
|
|
169
150
|
catch (e) {
|
|
170
|
-
console.error(`Failed to insert init data for ${
|
|
151
|
+
console.error(`Failed to insert init data for ${obj.name}:`, e);
|
|
171
152
|
}
|
|
172
153
|
}
|
|
173
154
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,6CAA2B;AAC3B,0CAAwB;AACxB,2CAAyB;AACzB,+CAA6B;AAC7B,0CAAwB;AACxB,6CAA2B;AAC3B,2CAAyB;AAIzB,6CAAgD;AAEhD,qCAA0C;AAC1C,yCAA8C;AAE9C,MAAa,QAAQ;IAKjB,YAAY,MAAsB;QAF1B,gBAAW,GAA2B,EAAE,CAAC;QAG7C,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,2BAAgB,EAAE,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,IAAI,uBAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;IAED,UAAU,CAAC,IAAY;QACnB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAGD,aAAa,CAAC,IAAY;QACtB,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,iBAAiB,CAAC,GAAW,EAAE,WAAoB;QAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvC,CAAC;IAED,aAAa,CAAC,OAA+B;QACzC,MAAM,GAAG,GAAoB;YACzB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACrB,OAAO,IAAI,6BAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACjD,CAAC;YACD,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;gBAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;gBAC3C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;oBACrC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAED,IAAI,GAAQ,CAAC;gBACb,IAAI,CAAC;oBACD,GAAG,GAAG,MAAM,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACT,MAAM,CAAC,CAAC;gBACZ,CAAC;gBAED,MAAM,MAAM,GAAoB;oBAC5B,GAAG,GAAG;oBACN,iBAAiB,EAAE,GAAG;oBACtB,WAAW,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC;iBACxC,CAAC;gBAEF,IAAI,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;oBACtC,IAAI,MAAM,CAAC,iBAAiB;wBAAE,MAAM,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;oBAClE,OAAO,MAAM,CAAC;gBAClB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,MAAM,CAAC,mBAAmB;wBAAE,MAAM,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;oBACtE,MAAM,KAAK,CAAC;gBAChB,CAAC;YACN,CAAC;YACD,IAAI,EAAE,GAAG,EAAE;gBACN,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,CAAC;SACJ,CAAC;QACF,OAAO,GAAG,CAAC;IACf,CAAC;IAED,cAAc,CAAC,MAAoB;QAC/B,mBAAmB;QACnB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBACd,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;gBACrB,CAAC;YACL,CAAC;QACL,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE;YAC7B,IAAI,EAAE,QAAQ;YACd,EAAE,EAAE,MAAM,CAAC,IAAI;YACf,OAAO,EAAE,MAAM;SAClB,CAAC,CAAC;IACP,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAe,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,UAAU;QACN,MAAM,MAAM,GAAiC,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAe,QAAQ,CAAC,CAAC;QAC3D,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,UAAU,CAAC,IAAY;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,aAAa,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,IAAI;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAe,QAAQ,CAAC,CAAC;QAC3D,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,gCAAgC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC;gBAC3D,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAClC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC5B,IAAI,CAAC;wBACD,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;4BACZ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;4BAChD,IAAI,QAAQ,EAAE,CAAC;gCACX,SAAS;4BACb,CAAC;wBACN,CAAC;wBACD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;wBAC1B,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,IAAI,YAAY,EAAE,CAAC,CAAC;oBACrF,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACT,OAAO,CAAC,KAAK,CAAC,kCAAkC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;oBACpE,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AA7ID,4BA6IC"}
|
package/dist/loader.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import { MetadataRegistry } from './registry';
|
|
1
2
|
import { ObjectConfig } from './types';
|
|
3
|
+
import { MetadataLoader as BaseLoader } from '@objectql/metadata';
|
|
4
|
+
export declare class MetadataLoader extends BaseLoader {
|
|
5
|
+
constructor(registry: MetadataRegistry);
|
|
6
|
+
}
|
|
2
7
|
export declare function loadObjectConfigs(dir: string): Record<string, ObjectConfig>;
|
package/dist/loader.js
CHANGED
|
@@ -1,210 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataLoader = void 0;
|
|
36
4
|
exports.loadObjectConfigs = loadObjectConfigs;
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// 1. Load YAML Configs
|
|
44
|
-
const files = glob.sync(['**/*.object.yml', '**/*.object.yaml'], {
|
|
45
|
-
cwd: dir,
|
|
46
|
-
absolute: true
|
|
47
|
-
});
|
|
48
|
-
for (const file of files) {
|
|
49
|
-
try {
|
|
50
|
-
const content = fs.readFileSync(file, 'utf8');
|
|
51
|
-
const doc = yaml.load(content);
|
|
52
|
-
if (doc.name && doc.fields) {
|
|
53
|
-
configs[doc.name] = doc;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
for (const [key, value] of Object.entries(doc)) {
|
|
57
|
-
if (typeof value === 'object' && value.fields) {
|
|
58
|
-
configs[key] = value;
|
|
59
|
-
if (!configs[key].name)
|
|
60
|
-
configs[key].name = key;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch (e) {
|
|
66
|
-
console.error(`Error loading object config from ${file}:`, e);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// 2. Load Hooks (.hook.js, .hook.ts)
|
|
70
|
-
// We only load .js if running in node, or .ts if ts-node/register is present.
|
|
71
|
-
// simpler: look for both, require will handle extension resolution if we are careful.
|
|
72
|
-
// Actually, in `dist` we only find .js. In `src` (test) we find .ts.
|
|
73
|
-
const hookFiles = glob.sync(['**/*.hook.{js,ts}'], {
|
|
74
|
-
cwd: dir,
|
|
75
|
-
absolute: true
|
|
76
|
-
});
|
|
77
|
-
for (const file of hookFiles) {
|
|
78
|
-
try {
|
|
79
|
-
// Check if we should ignore .ts if .js exists?
|
|
80
|
-
// Or assume env handles it.
|
|
81
|
-
// If we are in `dist`, `src` shouldn't be there usually.
|
|
82
|
-
const hookModule = require(file);
|
|
83
|
-
// Default export or named exports?
|
|
84
|
-
// Convention: export const listenTo = 'objectName';
|
|
85
|
-
// or filename based: 'project.hook.js' -> 'project' (flaky)
|
|
86
|
-
let objectName = hookModule.listenTo;
|
|
87
|
-
if (!objectName) {
|
|
88
|
-
// Try to guess from filename?
|
|
89
|
-
// project.hook.ts -> project
|
|
90
|
-
const basename = path.basename(file);
|
|
91
|
-
const match = basename.match(/^(.+)\.hook\.(ts|js)$/);
|
|
92
|
-
if (match) {
|
|
93
|
-
objectName = match[1];
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (objectName && configs[objectName]) {
|
|
97
|
-
if (!configs[objectName].listeners) {
|
|
98
|
-
configs[objectName].listeners = {};
|
|
99
|
-
}
|
|
100
|
-
const listeners = configs[objectName].listeners;
|
|
101
|
-
// Merge exported functions into listeners
|
|
102
|
-
// Common hooks: beforeFind, afterFind, beforeCreate, etc.
|
|
103
|
-
const hookNames = [
|
|
104
|
-
'beforeFind', 'afterFind',
|
|
105
|
-
'beforeCreate', 'afterCreate',
|
|
106
|
-
'beforeUpdate', 'afterUpdate',
|
|
107
|
-
'beforeDelete', 'afterDelete'
|
|
108
|
-
];
|
|
109
|
-
for (const name of hookNames) {
|
|
110
|
-
if (typeof hookModule[name] === 'function') {
|
|
111
|
-
listeners[name] = hookModule[name];
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
// Support default export having listeners object?
|
|
115
|
-
if (hookModule.default && typeof hookModule.default === 'object') {
|
|
116
|
-
Object.assign(listeners, hookModule.default);
|
|
117
|
-
}
|
|
118
|
-
// Load Actions
|
|
119
|
-
// Convention: export const actions = { myAction: (ctx, params) => ... }
|
|
120
|
-
// OR export function myAction(ctx, params) ... (Ambiguous with hooks? No, hooks have explicit names)
|
|
121
|
-
// Safer: look for `actions` export.
|
|
122
|
-
if (hookModule.actions && typeof hookModule.actions === 'object') {
|
|
123
|
-
if (!configs[objectName].actions) {
|
|
124
|
-
configs[objectName].actions = {};
|
|
125
|
-
}
|
|
126
|
-
for (const [actionName, handler] of Object.entries(hookModule.actions)) {
|
|
127
|
-
// We might have metadata from YAML already
|
|
128
|
-
if (!configs[objectName].actions[actionName]) {
|
|
129
|
-
configs[objectName].actions[actionName] = {};
|
|
130
|
-
}
|
|
131
|
-
// Attach handler
|
|
132
|
-
configs[objectName].actions[actionName].handler = handler;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
console.error(`Error loading hook from ${file}:`, e);
|
|
139
|
-
}
|
|
5
|
+
const registry_1 = require("./registry");
|
|
6
|
+
const metadata_1 = require("@objectql/metadata");
|
|
7
|
+
class MetadataLoader extends metadata_1.MetadataLoader {
|
|
8
|
+
constructor(registry) {
|
|
9
|
+
super(registry);
|
|
10
|
+
(0, metadata_1.registerObjectQLPlugins)(this);
|
|
140
11
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (!Array.isArray(data)) {
|
|
151
|
-
console.warn(`Data file ${file} does not contain an array. Skipping.`);
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
// Guess object name from filename
|
|
155
|
-
// project.data.yml -> project
|
|
156
|
-
const basename = path.basename(file);
|
|
157
|
-
const objectName = basename.replace(/\.data\.ya?ml$/, '');
|
|
158
|
-
if (configs[objectName]) {
|
|
159
|
-
configs[objectName].data = data;
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
// Maybe the object config hasn't been found yet?
|
|
163
|
-
// loadObjectConfigs runs glob for objects first, so configs should be populated.
|
|
164
|
-
console.warn(`Found data for unknown object '${objectName}' in ${file}`);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch (e) {
|
|
168
|
-
console.error(`Error loading data from ${file}:`, e);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// 4. Load Actions (.action.js, .action.ts)
|
|
172
|
-
const actionFiles = glob.sync(['**/*.action.{js,ts}'], {
|
|
173
|
-
cwd: dir,
|
|
174
|
-
absolute: true
|
|
175
|
-
});
|
|
176
|
-
for (const file of actionFiles) {
|
|
177
|
-
try {
|
|
178
|
-
const actionModule = require(file);
|
|
179
|
-
let objectName = actionModule.listenTo;
|
|
180
|
-
if (!objectName) {
|
|
181
|
-
const basename = path.basename(file);
|
|
182
|
-
const match = basename.match(/^(.+)\.action\.(ts|js)$/);
|
|
183
|
-
if (match) {
|
|
184
|
-
objectName = match[1];
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
if (objectName && configs[objectName]) {
|
|
188
|
-
if (!configs[objectName].actions) {
|
|
189
|
-
configs[objectName].actions = {};
|
|
190
|
-
}
|
|
191
|
-
// Treat all exported functions as actions
|
|
192
|
-
for (const [key, value] of Object.entries(actionModule)) {
|
|
193
|
-
if (key === 'listenTo')
|
|
194
|
-
continue;
|
|
195
|
-
if (typeof value === 'function') {
|
|
196
|
-
if (!configs[objectName].actions[key]) {
|
|
197
|
-
configs[objectName].actions[key] = {};
|
|
198
|
-
}
|
|
199
|
-
configs[objectName].actions[key].handler = value;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
catch (e) {
|
|
205
|
-
console.error(`Error loading action from ${file}:`, e);
|
|
206
|
-
}
|
|
12
|
+
}
|
|
13
|
+
exports.MetadataLoader = MetadataLoader;
|
|
14
|
+
function loadObjectConfigs(dir) {
|
|
15
|
+
const registry = new registry_1.MetadataRegistry();
|
|
16
|
+
const loader = new MetadataLoader(registry);
|
|
17
|
+
loader.load(dir);
|
|
18
|
+
const result = {};
|
|
19
|
+
for (const obj of registry.list('object')) {
|
|
20
|
+
result[obj.name] = obj;
|
|
207
21
|
}
|
|
208
|
-
return
|
|
22
|
+
return result;
|
|
209
23
|
}
|
|
210
24
|
//# sourceMappingURL=loader.js.map
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":";;;AAWA,8CASC;AApBD,yCAA8C;AAE9C,iDAA2F;AAE3F,MAAa,cAAe,SAAQ,yBAAU;IAC1C,YAAY,QAA0B;QAClC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAA,kCAAuB,EAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACJ;AALD,wCAKC;AAED,SAAgB,iBAAiB,CAAC,GAAW;IACzC,MAAM,QAAQ,GAAG,IAAI,2BAAgB,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,MAAM,MAAM,GAAiC,EAAE,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAe,QAAQ,CAAC,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataRegistry = void 0;
|
|
4
|
+
const metadata_1 = require("@objectql/metadata");
|
|
5
|
+
class MetadataRegistry extends metadata_1.MetadataRegistry {
|
|
6
|
+
}
|
|
7
|
+
exports.MetadataRegistry = MetadataRegistry;
|
|
8
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":";;;AAAA,iDAAgF;AAGhF,MAAa,gBAAiB,SAAQ,2BAAY;CAEjD;AAFD,4CAEC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,8 +2,11 @@ import { ObjectRepository } from "./repository";
|
|
|
2
2
|
import { ObjectConfig } from "./metadata";
|
|
3
3
|
import { Driver } from "./driver";
|
|
4
4
|
import { UnifiedQuery, FilterCriterion } from "./query";
|
|
5
|
+
import { MetadataRegistry } from "./registry";
|
|
5
6
|
export { ObjectConfig } from "./metadata";
|
|
7
|
+
export { MetadataRegistry } from "./registry";
|
|
6
8
|
export interface ObjectQLConfig {
|
|
9
|
+
registry?: MetadataRegistry;
|
|
7
10
|
datasources: Record<string, Driver>;
|
|
8
11
|
objects?: Record<string, ObjectConfig>;
|
|
9
12
|
packages?: string[];
|
|
@@ -13,6 +16,9 @@ export interface IObjectQL {
|
|
|
13
16
|
getConfigs(): Record<string, ObjectConfig>;
|
|
14
17
|
datasource(name: string): Driver;
|
|
15
18
|
init(): Promise<void>;
|
|
19
|
+
addPackage(name: string): void;
|
|
20
|
+
removePackage(name: string): void;
|
|
21
|
+
metadata: MetadataRegistry;
|
|
16
22
|
}
|
|
17
23
|
export interface HookContext<T = any> {
|
|
18
24
|
ctx: ObjectQLContext;
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataRegistry = void 0;
|
|
4
|
+
var registry_1 = require("./registry");
|
|
5
|
+
Object.defineProperty(exports, "MetadataRegistry", { enumerable: true, get: function () { return registry_1.MetadataRegistry; } });
|
|
3
6
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAOA,uCAA8C;AAArC,4GAAA,gBAAgB,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@objectql/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"test": "jest"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"
|
|
11
|
+
"@objectql/metadata": "*",
|
|
12
|
+
"fast-glob": "^3.3.2",
|
|
12
13
|
"js-yaml": "^4.1.1"
|
|
13
14
|
}
|
|
14
15
|
}
|