@objectql/platform-node 3.0.0 → 4.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/dist/module.js CHANGED
@@ -1,4 +1,11 @@
1
1
  "use strict";
2
+ /**
3
+ * ObjectQL
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
2
9
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
10
  if (k2 === undefined) k2 = k;
4
11
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -1,2 +1,9 @@
1
- import { ObjectQLPlugin } from '@objectql/types';
2
- export declare function loadPlugin(packageName: string): ObjectQLPlugin;
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ import type { PluginDefinition } from '@objectstack/spec';
9
+ export declare function loadPlugin(packageName: string): PluginDefinition;
package/dist/plugin.js CHANGED
@@ -1,4 +1,11 @@
1
1
  "use strict";
2
+ /**
3
+ * ObjectQL
4
+ * Copyright (c) 2026-present ObjectStack Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
2
9
  Object.defineProperty(exports, "__esModule", { value: true });
3
10
  exports.loadPlugin = loadPlugin;
4
11
  function loadPlugin(packageName) {
@@ -10,27 +17,39 @@ function loadPlugin(packageName) {
10
17
  catch (e) {
11
18
  throw new Error(`Failed to resolve plugin '${packageName}': ${e}`);
12
19
  }
20
+ // Helper to check if candidate is a PluginDefinition
21
+ const isPlugin = (candidate) => {
22
+ return candidate && (
23
+ // Check for any lifecycle method
24
+ typeof candidate.onEnable === 'function' ||
25
+ typeof candidate.onDisable === 'function' ||
26
+ typeof candidate.onInstall === 'function' ||
27
+ typeof candidate.onUninstall === 'function' ||
28
+ typeof candidate.onUpgrade === 'function') && (
29
+ // Note: id is optional in PluginDefinition, so we don't require it
30
+ // The spec allows plugins without id (it just defaults to package name)
31
+ candidate.id === undefined || typeof candidate.id === 'string');
32
+ };
13
33
  // Helper to find plugin instance
14
34
  const findPlugin = (candidate) => {
15
35
  if (!candidate)
16
36
  return undefined;
17
- // 1. Try treating as Class
37
+ // 1. Check if it's a PluginDefinition
38
+ if (isPlugin(candidate)) {
39
+ return candidate;
40
+ }
41
+ // 2. Try treating as Class
18
42
  if (typeof candidate === 'function') {
19
43
  try {
20
44
  const inst = new candidate();
21
- if (inst && typeof inst.setup === 'function') {
22
- return inst; // Found it!
45
+ if (isPlugin(inst)) {
46
+ return inst;
23
47
  }
24
48
  }
25
49
  catch (e) {
26
50
  // Not a constructor or instantiation failed
27
51
  }
28
52
  }
29
- // 2. Try treating as Instance
30
- if (candidate && typeof candidate.setup === 'function') {
31
- if (candidate.name)
32
- return candidate;
33
- }
34
53
  return undefined;
35
54
  };
36
55
  // Search in default, module root, and all named exports
@@ -49,8 +68,8 @@ function loadPlugin(packageName) {
49
68
  return instance;
50
69
  }
51
70
  else {
52
- console.error(`[PluginLoader] Failed to find ObjectQLPlugin in '${packageName}'. Exports:`, Object.keys(mod));
53
- throw new Error(`Plugin '${packageName}' must export a class or object implementing ObjectQLPlugin.`);
71
+ console.error(`[PluginLoader] Failed to find plugin in '${packageName}'. Exports:`, Object.keys(mod));
72
+ throw new Error(`Plugin '${packageName}' must export a PluginDefinition with lifecycle hooks (onEnable, onDisable, etc.).`);
54
73
  }
55
74
  }
56
75
  //# sourceMappingURL=plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":";;AAEA,gCAkDC;AAlDD,SAAgB,UAAU,CAAC,WAAmB;IAC1C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5E,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,MAAM,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,iCAAiC;IACjC,MAAM,UAAU,GAAG,CAAC,SAAc,EAA8B,EAAE;QAC1D,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAEjC,2BAA2B;QAC3B,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC7B,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;oBAC3C,OAAO,IAAI,CAAC,CAAC,YAAY;gBAC7B,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,4CAA4C;YAChD,CAAC;QACL,CAAC;QAED,8BAA8B;QAC9B,IAAI,SAAS,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACrD,IAAI,SAAS,CAAC,IAAI;gBAAE,OAAO,SAAS,CAAC;QACzC,CAAC;QACD,OAAO,SAAS,CAAC;IACzB,CAAC,CAAC;IAEF,wDAAwD;IACxD,IAAI,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAE1D,IAAI,CAAC,QAAQ,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,IAAI,GAAG,KAAK,SAAS;gBAAE,SAAS;YAChC,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,IAAI,QAAQ;gBAAE,MAAM;QACxB,CAAC;IACL,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACV,QAAgB,CAAC,YAAY,GAAG,WAAW,CAAC;QAC7C,OAAO,QAAQ,CAAC;IACpB,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,oDAAoD,WAAW,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9G,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,8DAA8D,CAAC,CAAC;IAC1G,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAIH,gCAmEC;AAnED,SAAgB,UAAU,CAAC,WAAmB;IAC1C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5E,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,MAAM,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,qDAAqD;IACrD,MAAM,QAAQ,GAAG,CAAC,SAAc,EAAiC,EAAE;QAC/D,OAAO,SAAS,IAAI;QAChB,iCAAiC;QACjC,OAAO,SAAS,CAAC,QAAQ,KAAK,UAAU;YACxC,OAAO,SAAS,CAAC,SAAS,KAAK,UAAU;YACzC,OAAO,SAAS,CAAC,SAAS,KAAK,UAAU;YACzC,OAAO,SAAS,CAAC,WAAW,KAAK,UAAU;YAC3C,OAAO,SAAS,CAAC,SAAS,KAAK,UAAU,CAC5C,IAAI;QACD,mEAAmE;QACnE,wEAAwE;QACxE,SAAS,CAAC,EAAE,KAAK,SAAS,IAAI,OAAO,SAAS,CAAC,EAAE,KAAK,QAAQ,CACjE,CAAC;IACN,CAAC,CAAC;IAEF,iCAAiC;IACjC,MAAM,UAAU,GAAG,CAAC,SAAc,EAAgC,EAAE;QAC5D,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAEjC,sCAAsC;QACtC,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,2BAA2B;QAC3B,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC7B,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjB,OAAO,IAAI,CAAC;gBAChB,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,4CAA4C;YAChD,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAC;IACzB,CAAC,CAAC;IAEF,wDAAwD;IACxD,IAAI,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;IAE1D,IAAI,CAAC,QAAQ,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC9C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,IAAI,GAAG,KAAK,SAAS;gBAAE,SAAS;YAChC,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,IAAI,QAAQ;gBAAE,MAAM;QACxB,CAAC;IACL,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC;QACV,QAAgB,CAAC,YAAY,GAAG,WAAW,CAAC;QAC7C,OAAO,QAAQ,CAAC;IACpB,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,4CAA4C,WAAW,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACtG,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,oFAAoF,CAAC,CAAC;IAChI,CAAC;AACL,CAAC"}
package/jest.config.js CHANGED
@@ -1,13 +1,29 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  module.exports = {
2
10
  preset: 'ts-jest',
3
11
  testEnvironment: 'node',
4
12
  testMatch: ['**/test/**/*.test.ts'],
5
13
  moduleNameMapper: {
6
14
  '^@objectql/(.*)$': '<rootDir>/../$1/src',
15
+ '^@objectstack/runtime$': '<rootDir>/test/__mocks__/@objectstack/runtime.ts',
7
16
  },
8
17
  transform: {
9
18
  '^.+\\.ts$': ['ts-jest', {
10
19
  isolatedModules: true,
20
+ tsconfig: {
21
+ esModuleInterop: true,
22
+ allowSyntheticDefaultImports: true,
23
+ }
11
24
  }],
12
25
  },
26
+ transformIgnorePatterns: [
27
+ 'node_modules/(?!(@objectstack))',
28
+ ],
13
29
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectql/platform-node",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "Node.js platform utilities for ObjectQL - File system integration, YAML loading, and plugin management",
5
5
  "keywords": [
6
6
  "objectql",
@@ -16,10 +16,11 @@
16
16
  "main": "dist/index.js",
17
17
  "types": "dist/index.d.ts",
18
18
  "dependencies": {
19
+ "@objectstack/spec": "^0.2.0",
19
20
  "fast-glob": "^3.3.2",
20
21
  "js-yaml": "^4.1.1",
21
- "@objectql/types": "3.0.0",
22
- "@objectql/core": "3.0.0"
22
+ "@objectql/types": "4.0.0",
23
+ "@objectql/core": "4.0.0"
23
24
  },
24
25
  "devDependencies": {
25
26
  "typescript": "^5.3.0"
package/src/driver.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import { Driver } from '@objectql/types';
2
10
 
3
11
  export function createDriverFromConnection(connection: string): Driver {
package/src/index.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  export * from './loader';
2
10
  export * from './plugin';
3
11
  export * from './driver';
package/src/loader.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import * as fs from 'fs';
2
10
  import * as glob from 'fast-glob';
3
11
  import * as path from 'path';
@@ -290,7 +298,7 @@ function registerObject(registry: MetadataRegistry, obj: any, file: string, pack
290
298
  // Check for existing object to Merge
291
299
  const existing = registry.getEntry('object', obj.name);
292
300
  if (existing) {
293
- const base = existing.content;
301
+ const base = existing.content as ObjectConfig;
294
302
 
295
303
  // Merge Fields: New fields overwrite old ones
296
304
  if (obj.fields) {
package/src/module.ts CHANGED
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import { ObjectLoader } from './loader';
2
10
  import * as path from 'path';
3
11
  import * as fs from 'fs';
package/src/plugin.ts CHANGED
@@ -1,6 +1,14 @@
1
- import { ObjectQLPlugin } from '@objectql/types';
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
2
8
 
3
- export function loadPlugin(packageName: string): ObjectQLPlugin {
9
+ import type { PluginDefinition } from '@objectstack/spec';
10
+
11
+ export function loadPlugin(packageName: string): PluginDefinition {
4
12
  let mod: any;
5
13
  try {
6
14
  const modulePath = require.resolve(packageName, { paths: [process.cwd()] });
@@ -9,26 +17,43 @@ export function loadPlugin(packageName: string): ObjectQLPlugin {
9
17
  throw new Error(`Failed to resolve plugin '${packageName}': ${e}`);
10
18
  }
11
19
 
20
+ // Helper to check if candidate is a PluginDefinition
21
+ const isPlugin = (candidate: any): candidate is PluginDefinition => {
22
+ return candidate && (
23
+ // Check for any lifecycle method
24
+ typeof candidate.onEnable === 'function' ||
25
+ typeof candidate.onDisable === 'function' ||
26
+ typeof candidate.onInstall === 'function' ||
27
+ typeof candidate.onUninstall === 'function' ||
28
+ typeof candidate.onUpgrade === 'function'
29
+ ) && (
30
+ // Note: id is optional in PluginDefinition, so we don't require it
31
+ // The spec allows plugins without id (it just defaults to package name)
32
+ candidate.id === undefined || typeof candidate.id === 'string'
33
+ );
34
+ };
35
+
12
36
  // Helper to find plugin instance
13
- const findPlugin = (candidate: any): ObjectQLPlugin | undefined => {
37
+ const findPlugin = (candidate: any): PluginDefinition | undefined => {
14
38
  if (!candidate) return undefined;
15
39
 
16
- // 1. Try treating as Class
40
+ // 1. Check if it's a PluginDefinition
41
+ if (isPlugin(candidate)) {
42
+ return candidate;
43
+ }
44
+
45
+ // 2. Try treating as Class
17
46
  if (typeof candidate === 'function') {
18
47
  try {
19
48
  const inst = new candidate();
20
- if (inst && typeof inst.setup === 'function') {
21
- return inst; // Found it!
49
+ if (isPlugin(inst)) {
50
+ return inst;
22
51
  }
23
52
  } catch (e) {
24
53
  // Not a constructor or instantiation failed
25
54
  }
26
55
  }
27
-
28
- // 2. Try treating as Instance
29
- if (candidate && typeof candidate.setup === 'function') {
30
- if (candidate.name) return candidate;
31
- }
56
+
32
57
  return undefined;
33
58
  };
34
59
 
@@ -47,7 +72,7 @@ export function loadPlugin(packageName: string): ObjectQLPlugin {
47
72
  (instance as any)._packageName = packageName;
48
73
  return instance;
49
74
  } else {
50
- console.error(`[PluginLoader] Failed to find ObjectQLPlugin in '${packageName}'. Exports:`, Object.keys(mod));
51
- throw new Error(`Plugin '${packageName}' must export a class or object implementing ObjectQLPlugin.`);
75
+ console.error(`[PluginLoader] Failed to find plugin in '${packageName}'. Exports:`, Object.keys(mod));
76
+ throw new Error(`Plugin '${packageName}' must export a PluginDefinition with lifecycle hooks (onEnable, onDisable, etc.).`);
52
77
  }
53
78
  }
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Mock for @objectstack/runtime
3
+ * This mock is needed because the npm package has issues with Jest
4
+ * and we want to focus on testing ObjectQL's logic, not the kernel integration.
5
+ *
6
+ * For now, this mock delegates to the legacy driver to maintain backward compatibility
7
+ * during the migration phase.
8
+ */
9
+
10
+ // Simple mock implementations of runtime managers
11
+ class MockMetadataRegistry {
12
+ private store = new Map<string, Map<string, any>>();
13
+
14
+ register(type: string, item: any): void {
15
+ if (!this.store.has(type)) {
16
+ this.store.set(type, new Map());
17
+ }
18
+ const typeMap = this.store.get(type)!;
19
+ typeMap.set(item.id || item.name, item);
20
+ }
21
+
22
+ get<T = any>(type: string, id: string): T | undefined {
23
+ const typeMap = this.store.get(type);
24
+ const item = typeMap?.get(id);
25
+ return item?.content as T;
26
+ }
27
+
28
+ list<T = any>(type: string): T[] {
29
+ const typeMap = this.store.get(type);
30
+ if (!typeMap) return [];
31
+ return Array.from(typeMap.values()).map(item => item.content as T);
32
+ }
33
+
34
+ unregister(type: string, id: string): boolean {
35
+ const typeMap = this.store.get(type);
36
+ if (!typeMap) return false;
37
+ return typeMap.delete(id);
38
+ }
39
+
40
+ getTypes(): string[] {
41
+ return Array.from(this.store.keys());
42
+ }
43
+
44
+ getEntry(type: string, id: string): any | undefined {
45
+ const typeMap = this.store.get(type);
46
+ return typeMap ? typeMap.get(id) : undefined;
47
+ }
48
+
49
+ unregisterPackage(packageName: string): void {
50
+ // Simple implementation - in real runtime this would filter by package
51
+ for (const [type, typeMap] of this.store.entries()) {
52
+ const toDelete: string[] = [];
53
+ for (const [id, item] of typeMap.entries()) {
54
+ if (item.packageName === packageName || item.package === packageName) {
55
+ toDelete.push(id);
56
+ }
57
+ }
58
+ toDelete.forEach(id => typeMap.delete(id));
59
+ }
60
+ }
61
+ }
62
+
63
+ class MockHookManager {
64
+ removePackage(packageName: string): void {
65
+ // Mock implementation
66
+ }
67
+
68
+ clear(): void {
69
+ // Mock implementation
70
+ }
71
+ }
72
+
73
+ class MockActionManager {
74
+ removePackage(packageName: string): void {
75
+ // Mock implementation
76
+ }
77
+
78
+ clear(): void {
79
+ // Mock implementation
80
+ }
81
+ }
82
+
83
+ export class ObjectStackKernel {
84
+ public ql: unknown = null;
85
+ public metadata: MockMetadataRegistry;
86
+ public hooks: MockHookManager;
87
+ public actions: MockActionManager;
88
+ private plugins: any[] = [];
89
+ private driver: any = null; // Will be set by the ObjectQL app
90
+
91
+ constructor(plugins: any[] = []) {
92
+ this.plugins = plugins;
93
+ this.metadata = new MockMetadataRegistry();
94
+ this.hooks = new MockHookManager();
95
+ this.actions = new MockActionManager();
96
+ }
97
+
98
+ // Method to set the driver for delegation during migration
99
+ setDriver(driver: any): void {
100
+ this.driver = driver;
101
+ }
102
+
103
+ async start(): Promise<void> {
104
+ // Mock implementation that calls plugin lifecycle methods
105
+ for (const plugin of this.plugins) {
106
+ if (plugin.install) {
107
+ await plugin.install({ engine: this });
108
+ }
109
+ }
110
+ for (const plugin of this.plugins) {
111
+ if (plugin.onStart) {
112
+ await plugin.onStart({ engine: this });
113
+ }
114
+ }
115
+ }
116
+
117
+ async seed(): Promise<void> {
118
+ // Mock implementation
119
+ }
120
+
121
+ async find(objectName: string, query: any): Promise<{ value: Record<string, any>[]; count: number }> {
122
+ // Delegate to driver during migration phase
123
+ if (this.driver) {
124
+ // Convert QueryAST back to UnifiedQuery format for driver
125
+ const unifiedQuery: any = {};
126
+
127
+ if (query.fields) {
128
+ unifiedQuery.fields = query.fields;
129
+ }
130
+ if (query.filters) {
131
+ unifiedQuery.filters = query.filters;
132
+ }
133
+ if (query.sort) {
134
+ unifiedQuery.sort = query.sort.map((s: any) => [s.field, s.order]);
135
+ }
136
+ if (query.top !== undefined) {
137
+ unifiedQuery.limit = query.top;
138
+ }
139
+ if (query.skip !== undefined) {
140
+ unifiedQuery.skip = query.skip;
141
+ }
142
+ if (query.aggregations) {
143
+ unifiedQuery.aggregate = query.aggregations.map((agg: any) => ({
144
+ func: agg.function,
145
+ field: agg.field,
146
+ alias: agg.alias
147
+ }));
148
+ }
149
+ if (query.groupBy) {
150
+ unifiedQuery.groupBy = query.groupBy;
151
+ }
152
+
153
+ const results = await this.driver.find(objectName, unifiedQuery, {});
154
+ return { value: results, count: results.length };
155
+ }
156
+ return { value: [], count: 0 };
157
+ }
158
+
159
+ async get(objectName: string, id: string): Promise<Record<string, any>> {
160
+ // Delegate to driver during migration phase
161
+ if (this.driver) {
162
+ return await this.driver.findOne(objectName, id, {}, {});
163
+ }
164
+ return {};
165
+ }
166
+
167
+ async create(objectName: string, data: any): Promise<Record<string, any>> {
168
+ // Delegate to driver during migration phase
169
+ if (this.driver) {
170
+ return await this.driver.create(objectName, data, {});
171
+ }
172
+ return data;
173
+ }
174
+
175
+ async update(objectName: string, id: string, data: any): Promise<Record<string, any>> {
176
+ // Delegate to driver during migration phase
177
+ if (this.driver) {
178
+ return await this.driver.update(objectName, id, data, {});
179
+ }
180
+ return data;
181
+ }
182
+
183
+ async delete(objectName: string, id: string): Promise<boolean> {
184
+ // Delegate to driver during migration phase
185
+ if (this.driver) {
186
+ await this.driver.delete(objectName, id, {});
187
+ return true;
188
+ }
189
+ return true;
190
+ }
191
+
192
+ getMetadata(objectName: string): any {
193
+ return {};
194
+ }
195
+
196
+ getView(objectName: string, viewType?: 'list' | 'form'): any {
197
+ return null;
198
+ }
199
+ }
200
+
201
+ export class ObjectStackRuntimeProtocol {}
202
+
203
+ export interface RuntimeContext {
204
+ engine: ObjectStackKernel;
205
+ }
206
+
207
+ export interface RuntimePlugin {
208
+ name: string;
209
+ install?: (ctx: RuntimeContext) => void | Promise<void>;
210
+ onStart?: (ctx: RuntimeContext) => void | Promise<void>;
211
+ }
212
+
213
+ // Export MetadataRegistry
214
+ export { MockMetadataRegistry as MetadataRegistry };
215
+
216
+ export interface MetadataItem {
217
+ type: string;
218
+ id: string;
219
+ content: unknown;
220
+ packageName?: string;
221
+ path?: string;
222
+ package?: string;
223
+ }
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import { ObjectQL } from '@objectql/core';
2
10
  import { ObjectLoader } from '../src';
3
11
  import * as path from 'path';
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  module.exports = {
2
10
  listenTo: 'project',
3
11
  closeProject: {
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import { loadObjectConfigs } from '../src/loader';
2
10
  import * as path from 'path';
3
11
 
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import { ObjectQL } from '@objectql/core';
2
10
  import { ObjectConfig } from '@objectql/types';
3
11
  import * as fs from 'fs';
@@ -1,3 +1,11 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  import { Validator } from '@objectql/core';
2
10
  import {
3
11
  ValidationContext,