@objectql/core 0.1.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 ADDED
@@ -0,0 +1,18 @@
1
+ # @objectql/core
2
+
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - add metadata loader
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @objectql/metadata@0.2.0
13
+
14
+ ## 1.0.0
15
+
16
+ ### Major Changes
17
+
18
+ - first release
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,17 +3,24 @@ 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
- private objects;
13
+ metadata: MetadataRegistry;
14
+ private loader;
11
15
  private datasources;
12
16
  constructor(config: ObjectQLConfig);
13
- loadFromDirectory(dir: string): void;
17
+ addPackage(name: string): void;
18
+ removePackage(name: string): void;
19
+ loadFromDirectory(dir: string, packageName?: string): void;
14
20
  createContext(options: ObjectQLContextOptions): ObjectQLContext;
15
21
  registerObject(object: ObjectConfig): void;
16
22
  getObject(name: string): ObjectConfig | undefined;
17
23
  getConfigs(): Record<string, ObjectConfig>;
18
24
  datasource(name: string): Driver;
25
+ init(): Promise<void>;
19
26
  }
package/dist/index.js CHANGED
@@ -20,25 +20,37 @@ __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./driver"), exports);
21
21
  __exportStar(require("./repository"), exports);
22
22
  __exportStar(require("./query"), exports);
23
+ __exportStar(require("./registry"), exports);
24
+ __exportStar(require("./loader"), exports);
23
25
  const repository_1 = require("./repository");
24
26
  const loader_1 = require("./loader");
27
+ const registry_1 = require("./registry");
25
28
  class ObjectQL {
26
29
  constructor(config) {
27
- this.objects = {};
28
30
  this.datasources = {};
31
+ this.metadata = config.registry || new registry_1.MetadataRegistry();
32
+ this.loader = new loader_1.MetadataLoader(this.metadata);
29
33
  this.datasources = config.datasources;
30
34
  if (config.objects) {
31
- for (const obj of Object.values(config.objects)) {
35
+ for (const [key, obj] of Object.entries(config.objects)) {
32
36
  this.registerObject(obj);
33
37
  }
34
38
  }
35
- }
36
- loadFromDirectory(dir) {
37
- const objects = (0, loader_1.loadObjectConfigs)(dir);
38
- for (const obj of Object.values(objects)) {
39
- this.registerObject(obj);
39
+ if (config.packages) {
40
+ for (const name of config.packages) {
41
+ this.addPackage(name);
42
+ }
40
43
  }
41
44
  }
45
+ addPackage(name) {
46
+ this.loader.loadPackage(name);
47
+ }
48
+ removePackage(name) {
49
+ this.metadata.unregisterPackage(name);
50
+ }
51
+ loadFromDirectory(dir, packageName) {
52
+ this.loader.load(dir, packageName);
53
+ }
42
54
  createContext(options) {
43
55
  const ctx = {
44
56
  userId: options.userId,
@@ -59,13 +71,11 @@ class ObjectQL {
59
71
  trx = await driver.beginTransaction();
60
72
  }
61
73
  catch (e) {
62
- // If beginTransaction fails, fail.
63
74
  throw e;
64
75
  }
65
76
  const trxCtx = {
66
77
  ...ctx,
67
78
  transactionHandle: trx,
68
- // Nested transaction simply reuses the current one (flat transaction)
69
79
  transaction: async (cb) => cb(trxCtx)
70
80
  };
71
81
  try {
@@ -95,13 +105,22 @@ class ObjectQL {
95
105
  }
96
106
  }
97
107
  }
98
- this.objects[object.name] = object;
108
+ this.metadata.register('object', {
109
+ type: 'object',
110
+ id: object.name,
111
+ content: object
112
+ });
99
113
  }
100
114
  getObject(name) {
101
- return this.objects[name];
115
+ return this.metadata.get('object', name);
102
116
  }
103
117
  getConfigs() {
104
- return this.objects;
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;
105
124
  }
106
125
  datasource(name) {
107
126
  const driver = this.datasources[name];
@@ -110,6 +129,31 @@ class ObjectQL {
110
129
  }
111
130
  return driver;
112
131
  }
132
+ async init() {
133
+ const ctx = this.createContext({ isSystem: true });
134
+ const objects = this.metadata.list('object');
135
+ for (const obj of objects) {
136
+ if (obj.data && obj.data.length > 0) {
137
+ console.log(`Initializing data for object ${obj.name}...`);
138
+ const repo = ctx.object(obj.name);
139
+ for (const record of obj.data) {
140
+ try {
141
+ if (record._id) {
142
+ const existing = await repo.findOne(record._id);
143
+ if (existing) {
144
+ continue;
145
+ }
146
+ }
147
+ await repo.create(record);
148
+ console.log(`Inserted init data for ${obj.name}: ${record._id || 'unknown id'}`);
149
+ }
150
+ catch (e) {
151
+ console.error(`Failed to insert init data for ${obj.name}:`, e);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
113
157
  }
114
158
  exports.ObjectQL = ObjectQL;
115
159
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,0CAAwB;AACxB,2CAAyB;AACzB,+CAA6B;AAC7B,0CAAwB;AAIxB,6CAAgD;AAEhD,qCAA6C;AAE7C,MAAa,QAAQ;IAIjB,YAAY,MAAsB;QAH1B,YAAO,GAAiC,EAAE,CAAC;QAC3C,gBAAW,GAA2B,EAAE,CAAC;QAG7C,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;IACL,CAAC;IAED,iBAAiB,CAAC,GAAW;QACzB,MAAM,OAAO,GAAG,IAAA,0BAAiB,EAAC,GAAG,CAAC,CAAC;QACvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACL,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,mCAAmC;oBACnC,MAAM,CAAC,CAAC;gBACZ,CAAC;gBAED,MAAM,MAAM,GAAoB;oBAC5B,GAAG,GAAG;oBACN,iBAAiB,EAAE,GAAG;oBACtB,sEAAsE;oBACtE,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,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACvC,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,UAAU;QACN,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,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;CACJ;AA9FD,4BA8FC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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,143 +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 fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const yaml = __importStar(require("js-yaml"));
40
- const glob = __importStar(require("fast-glob"));
41
- function loadObjectConfigs(dir) {
42
- const configs = {};
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
- }
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);
68
11
  }
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
- }
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;
140
21
  }
141
- return configs;
22
+ return result;
142
23
  }
143
24
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
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"}
@@ -99,4 +99,6 @@ export interface ObjectConfig {
99
99
  actions?: Record<string, ActionConfig>;
100
100
  /** Lifecycle hooks. */
101
101
  listeners?: ObjectListeners;
102
+ /** Initial data to populate when system starts. */
103
+ data?: any[];
102
104
  }
@@ -0,0 +1,4 @@
1
+ import { MetadataRegistry as BaseRegistry, Metadata } from '@objectql/metadata';
2
+ export { Metadata };
3
+ export declare class MetadataRegistry extends BaseRegistry {
4
+ }
@@ -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,15 +2,23 @@ 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>;
12
+ packages?: string[];
9
13
  }
10
14
  export interface IObjectQL {
11
15
  getObject(name: string): ObjectConfig | undefined;
12
16
  getConfigs(): Record<string, ObjectConfig>;
13
17
  datasource(name: string): Driver;
18
+ init(): Promise<void>;
19
+ addPackage(name: string): void;
20
+ removePackage(name: string): void;
21
+ metadata: MetadataRegistry;
14
22
  }
15
23
  export interface HookContext<T = any> {
16
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": "0.1.0",
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
- "fast-glob": "^3.3.3",
11
+ "@objectql/metadata": "*",
12
+ "fast-glob": "^3.3.2",
12
13
  "js-yaml": "^4.1.1"
13
14
  }
14
15
  }
package/src/index.ts CHANGED
@@ -1,33 +1,53 @@
1
+ import * as path from 'path';
2
+
1
3
  export * from './metadata';
2
4
  export * from './types';
3
5
  export * from './driver';
4
6
  export * from './repository';
5
7
  export * from './query';
8
+ export * from './registry';
9
+ export * from './loader';
6
10
 
7
11
  import { ObjectConfig } from './metadata';
8
12
  import { ObjectQLContext, ObjectQLContextOptions, IObjectQL, ObjectQLConfig } from './types';
9
13
  import { ObjectRepository } from './repository';
10
14
  import { Driver } from './driver';
11
- import { loadObjectConfigs } from './loader';
15
+ import { MetadataLoader } from './loader';
16
+ import { MetadataRegistry } from './registry';
12
17
 
13
18
  export class ObjectQL implements IObjectQL {
14
- private objects: Record<string, ObjectConfig> = {};
19
+ public metadata: MetadataRegistry;
20
+ private loader: MetadataLoader;
15
21
  private datasources: Record<string, Driver> = {};
16
22
 
17
23
  constructor(config: ObjectQLConfig) {
24
+ this.metadata = config.registry || new MetadataRegistry();
25
+ this.loader = new MetadataLoader(this.metadata);
18
26
  this.datasources = config.datasources;
27
+
19
28
  if (config.objects) {
20
- for (const obj of Object.values(config.objects)) {
29
+ for (const [key, obj] of Object.entries(config.objects)) {
21
30
  this.registerObject(obj);
22
31
  }
23
32
  }
33
+ if (config.packages) {
34
+ for (const name of config.packages) {
35
+ this.addPackage(name);
36
+ }
37
+ }
24
38
  }
25
39
 
26
- loadFromDirectory(dir: string) {
27
- const objects = loadObjectConfigs(dir);
28
- for (const obj of Object.values(objects)) {
29
- this.registerObject(obj);
30
- }
40
+ addPackage(name: string) {
41
+ this.loader.loadPackage(name);
42
+ }
43
+
44
+
45
+ removePackage(name: string) {
46
+ this.metadata.unregisterPackage(name);
47
+ }
48
+
49
+ loadFromDirectory(dir: string, packageName?: string) {
50
+ this.loader.load(dir, packageName);
31
51
  }
32
52
 
33
53
  createContext(options: ObjectQLContextOptions): ObjectQLContext {
@@ -50,14 +70,12 @@ export class ObjectQL implements IObjectQL {
50
70
  try {
51
71
  trx = await driver.beginTransaction();
52
72
  } catch (e) {
53
- // If beginTransaction fails, fail.
54
73
  throw e;
55
74
  }
56
75
 
57
76
  const trxCtx: ObjectQLContext = {
58
77
  ...ctx,
59
78
  transactionHandle: trx,
60
- // Nested transaction simply reuses the current one (flat transaction)
61
79
  transaction: async (cb) => cb(trxCtx)
62
80
  };
63
81
 
@@ -86,15 +104,24 @@ export class ObjectQL implements IObjectQL {
86
104
  }
87
105
  }
88
106
  }
89
- this.objects[object.name] = object;
107
+ this.metadata.register('object', {
108
+ type: 'object',
109
+ id: object.name,
110
+ content: object
111
+ });
90
112
  }
91
113
 
92
114
  getObject(name: string): ObjectConfig | undefined {
93
- return this.objects[name];
115
+ return this.metadata.get<ObjectConfig>('object', name);
94
116
  }
95
117
 
96
118
  getConfigs(): Record<string, ObjectConfig> {
97
- return this.objects;
119
+ const result: Record<string, ObjectConfig> = {};
120
+ const objects = this.metadata.list<ObjectConfig>('object');
121
+ for (const obj of objects) {
122
+ result[obj.name] = obj;
123
+ }
124
+ return result;
98
125
  }
99
126
 
100
127
  datasource(name: string): Driver {
@@ -104,4 +131,29 @@ export class ObjectQL implements IObjectQL {
104
131
  }
105
132
  return driver;
106
133
  }
134
+
135
+ async init() {
136
+ const ctx = this.createContext({ isSystem: true });
137
+ const objects = this.metadata.list<ObjectConfig>('object');
138
+ for (const obj of objects) {
139
+ if (obj.data && obj.data.length > 0) {
140
+ console.log(`Initializing data for object ${obj.name}...`);
141
+ const repo = ctx.object(obj.name);
142
+ for (const record of obj.data) {
143
+ try {
144
+ if (record._id) {
145
+ const existing = await repo.findOne(record._id);
146
+ if (existing) {
147
+ continue;
148
+ }
149
+ }
150
+ await repo.create(record);
151
+ console.log(`Inserted init data for ${obj.name}: ${record._id || 'unknown id'}`);
152
+ } catch (e) {
153
+ console.error(`Failed to insert init data for ${obj.name}:`, e);
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
107
159
  }