@objectstack/objectql 3.2.8 → 3.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @objectstack/objectql@3.2.8 build /home/runner/work/spec/spec/packages/objectql
2
+ > @objectstack/objectql@3.3.0 build /home/runner/work/spec/spec/packages/objectql
3
3
  > tsup --config ../../tsup.config.ts
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- ESM dist/index.mjs 94.28 KB
14
- ESM dist/index.mjs.map 193.23 KB
15
- ESM ⚡️ Build success in 210ms
16
- CJS dist/index.js 96.02 KB
17
- CJS dist/index.js.map 194.53 KB
18
- CJS ⚡️ Build success in 213ms
13
+ CJS dist/index.js 98.69 KB
14
+ CJS dist/index.js.map 199.38 KB
15
+ CJS ⚡️ Build success in 147ms
16
+ ESM dist/index.mjs 96.95 KB
17
+ ESM dist/index.mjs.map 198.08 KB
18
+ ESM ⚡️ Build success in 148ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 24357ms
21
- DTS dist/index.d.mts 77.36 KB
22
- DTS dist/index.d.ts 77.36 KB
20
+ DTS ⚡️ Build success in 25675ms
21
+ DTS dist/index.d.mts 78.59 KB
22
+ DTS dist/index.d.ts 78.59 KB
package/CHANGELOG.md CHANGED
@@ -1,9 +1,29 @@
1
1
  # @objectstack/objectql
2
2
 
3
+ ## 3.3.0
4
+
5
+ ### Patch Changes
6
+
7
+ - @objectstack/spec@3.3.0
8
+ - @objectstack/core@3.3.0
9
+ - @objectstack/types@3.3.0
10
+
11
+ ## 3.2.9
12
+
13
+ ### Patch Changes
14
+
15
+ - c3065dd: fix turso 2
16
+ - @objectstack/spec@3.2.9
17
+ - @objectstack/core@3.2.9
18
+ - @objectstack/types@3.2.9
19
+
3
20
  ## 3.2.8
4
21
 
5
22
  ### Patch Changes
6
23
 
24
+ - Auto-sync all registered object schemas to database on startup: `ObjectQLPlugin.start()` now iterates every object in `SchemaRegistry` and calls `driver.syncSchema()` after driver connections are established. This ensures tables for plugin-registered objects (e.g. `sys_user` from plugin-auth) are created or updated automatically.
25
+ - Added `getDriverForObject(objectName)` public method to `ObjectQL` engine for resolving the responsible driver for a given object.
26
+ - Added optional `syncSchema` method to `DriverInterface` contract, aligning it with the full `IDataDriver` protocol.
7
27
  - @objectstack/spec@3.2.8
8
28
  - @objectstack/core@3.2.8
9
29
  - @objectstack/types@3.2.8
package/dist/index.d.mts CHANGED
@@ -167,8 +167,14 @@ declare class SchemaRegistry {
167
167
  */
168
168
  static resolveObject(fqn: string): ServiceObject | undefined;
169
169
  /**
170
- * Get object by name (FQN or short name with fallback scan).
171
- * For compatibility, tries exact match first, then scans for suffix match.
170
+ * Get object by name (FQN, short name, or physical table name).
171
+ *
172
+ * Resolution order:
173
+ * 1. Exact FQN match (e.g., 'crm__account')
174
+ * 2. Short name fallback (e.g., 'account' → 'crm__account')
175
+ * 3. Physical table name match (e.g., 'sys_user' → 'sys__user')
176
+ * ObjectSchema.create() auto-derives tableName as {namespace}_{name},
177
+ * which uses a single underscore — different from the FQN double underscore.
172
178
  */
173
179
  static getObject(name: string): ServiceObject | undefined;
174
180
  /**
@@ -1683,6 +1689,17 @@ declare class ObjectQL implements IDataEngine {
1683
1689
  * this method directly looks up a driver by its registered name.
1684
1690
  */
1685
1691
  getDriverByName(name: string): DriverInterface | undefined;
1692
+ /**
1693
+ * Get the driver responsible for the given object.
1694
+ *
1695
+ * Resolves datasource binding from the object's schema definition,
1696
+ * falling back to the default driver. This is a public version of
1697
+ * the internal getDriver() used by CRUD operations.
1698
+ *
1699
+ * @param objectName - FQN or short name of the registered object.
1700
+ * @returns The resolved DriverInterface, or undefined if no driver is available.
1701
+ */
1702
+ getDriverForObject(objectName: string): DriverInterface | undefined;
1686
1703
  /**
1687
1704
  * Get a registered driver by datasource name.
1688
1705
  * Alias matching @objectql/core datasource() API.
@@ -1877,6 +1894,17 @@ declare class ObjectQLPlugin implements Plugin {
1877
1894
  * for multi-tenant operations.
1878
1895
  */
1879
1896
  private registerTenantMiddleware;
1897
+ /**
1898
+ * Synchronize all registered object schemas to the database.
1899
+ *
1900
+ * Iterates every object in the SchemaRegistry and calls the
1901
+ * responsible driver's `syncSchema()` for each one. This is
1902
+ * idempotent — drivers must tolerate repeated calls without
1903
+ * duplicating tables or erroring out.
1904
+ *
1905
+ * Drivers that do not implement `syncSchema` are silently skipped.
1906
+ */
1907
+ private syncRegisteredSchemas;
1880
1908
  /**
1881
1909
  * Load metadata from external metadata service into ObjectQL registry
1882
1910
  * This enables ObjectQL to use file-based or remote metadata
package/dist/index.d.ts CHANGED
@@ -167,8 +167,14 @@ declare class SchemaRegistry {
167
167
  */
168
168
  static resolveObject(fqn: string): ServiceObject | undefined;
169
169
  /**
170
- * Get object by name (FQN or short name with fallback scan).
171
- * For compatibility, tries exact match first, then scans for suffix match.
170
+ * Get object by name (FQN, short name, or physical table name).
171
+ *
172
+ * Resolution order:
173
+ * 1. Exact FQN match (e.g., 'crm__account')
174
+ * 2. Short name fallback (e.g., 'account' → 'crm__account')
175
+ * 3. Physical table name match (e.g., 'sys_user' → 'sys__user')
176
+ * ObjectSchema.create() auto-derives tableName as {namespace}_{name},
177
+ * which uses a single underscore — different from the FQN double underscore.
172
178
  */
173
179
  static getObject(name: string): ServiceObject | undefined;
174
180
  /**
@@ -1683,6 +1689,17 @@ declare class ObjectQL implements IDataEngine {
1683
1689
  * this method directly looks up a driver by its registered name.
1684
1690
  */
1685
1691
  getDriverByName(name: string): DriverInterface | undefined;
1692
+ /**
1693
+ * Get the driver responsible for the given object.
1694
+ *
1695
+ * Resolves datasource binding from the object's schema definition,
1696
+ * falling back to the default driver. This is a public version of
1697
+ * the internal getDriver() used by CRUD operations.
1698
+ *
1699
+ * @param objectName - FQN or short name of the registered object.
1700
+ * @returns The resolved DriverInterface, or undefined if no driver is available.
1701
+ */
1702
+ getDriverForObject(objectName: string): DriverInterface | undefined;
1686
1703
  /**
1687
1704
  * Get a registered driver by datasource name.
1688
1705
  * Alias matching @objectql/core datasource() API.
@@ -1877,6 +1894,17 @@ declare class ObjectQLPlugin implements Plugin {
1877
1894
  * for multi-tenant operations.
1878
1895
  */
1879
1896
  private registerTenantMiddleware;
1897
+ /**
1898
+ * Synchronize all registered object schemas to the database.
1899
+ *
1900
+ * Iterates every object in the SchemaRegistry and calls the
1901
+ * responsible driver's `syncSchema()` for each one. This is
1902
+ * idempotent — drivers must tolerate repeated calls without
1903
+ * duplicating tables or erroring out.
1904
+ *
1905
+ * Drivers that do not implement `syncSchema` are silently skipped.
1906
+ */
1907
+ private syncRegisteredSchemas;
1880
1908
  /**
1881
1909
  * Load metadata from external metadata service into ObjectQL registry
1882
1910
  * This enables ObjectQL to use file-based or remote metadata
package/dist/index.js CHANGED
@@ -207,8 +207,14 @@ var SchemaRegistry = class {
207
207
  return merged;
208
208
  }
209
209
  /**
210
- * Get object by name (FQN or short name with fallback scan).
211
- * For compatibility, tries exact match first, then scans for suffix match.
210
+ * Get object by name (FQN, short name, or physical table name).
211
+ *
212
+ * Resolution order:
213
+ * 1. Exact FQN match (e.g., 'crm__account')
214
+ * 2. Short name fallback (e.g., 'account' → 'crm__account')
215
+ * 3. Physical table name match (e.g., 'sys_user' → 'sys__user')
216
+ * ObjectSchema.create() auto-derives tableName as {namespace}_{name},
217
+ * which uses a single underscore — different from the FQN double underscore.
212
218
  */
213
219
  static getObject(name) {
214
220
  const direct = this.resolveObject(name);
@@ -219,6 +225,12 @@ var SchemaRegistry = class {
219
225
  return this.resolveObject(fqn);
220
226
  }
221
227
  }
228
+ for (const fqn of this.objectContributors.keys()) {
229
+ const resolved = this.resolveObject(fqn);
230
+ if (resolved?.tableName === name) {
231
+ return resolved;
232
+ }
233
+ }
222
234
  return void 0;
223
235
  }
224
236
  /**
@@ -1760,7 +1772,7 @@ var _ObjectQL = class _ObjectQL {
1760
1772
  resolveObjectName(name) {
1761
1773
  const schema = SchemaRegistry.getObject(name);
1762
1774
  if (schema) {
1763
- return schema.name;
1775
+ return schema.tableName || schema.name;
1764
1776
  }
1765
1777
  return name;
1766
1778
  }
@@ -2246,6 +2258,23 @@ var _ObjectQL = class _ObjectQL {
2246
2258
  getDriverByName(name) {
2247
2259
  return this.drivers.get(name);
2248
2260
  }
2261
+ /**
2262
+ * Get the driver responsible for the given object.
2263
+ *
2264
+ * Resolves datasource binding from the object's schema definition,
2265
+ * falling back to the default driver. This is a public version of
2266
+ * the internal getDriver() used by CRUD operations.
2267
+ *
2268
+ * @param objectName - FQN or short name of the registered object.
2269
+ * @returns The resolved DriverInterface, or undefined if no driver is available.
2270
+ */
2271
+ getDriverForObject(objectName) {
2272
+ try {
2273
+ return this.getDriver(objectName);
2274
+ } catch {
2275
+ return void 0;
2276
+ }
2277
+ }
2249
2278
  /**
2250
2279
  * Get a registered driver by datasource name.
2251
2280
  * Alias matching @objectql/core datasource() API.
@@ -2643,6 +2672,7 @@ var ObjectQLPlugin = class {
2643
2672
  }
2644
2673
  }
2645
2674
  await this.ql?.init();
2675
+ await this.syncRegisteredSchemas(ctx);
2646
2676
  this.registerAuditHooks(ctx);
2647
2677
  this.registerTenantMiddleware(ctx);
2648
2678
  ctx.logger.info("ObjectQL engine started", {
@@ -2737,6 +2767,56 @@ var ObjectQLPlugin = class {
2737
2767
  });
2738
2768
  ctx.logger.debug("Tenant isolation middleware registered");
2739
2769
  }
2770
+ /**
2771
+ * Synchronize all registered object schemas to the database.
2772
+ *
2773
+ * Iterates every object in the SchemaRegistry and calls the
2774
+ * responsible driver's `syncSchema()` for each one. This is
2775
+ * idempotent — drivers must tolerate repeated calls without
2776
+ * duplicating tables or erroring out.
2777
+ *
2778
+ * Drivers that do not implement `syncSchema` are silently skipped.
2779
+ */
2780
+ async syncRegisteredSchemas(ctx) {
2781
+ if (!this.ql) return;
2782
+ const allObjects = this.ql.registry?.getAllObjects?.() ?? [];
2783
+ if (allObjects.length === 0) return;
2784
+ let synced = 0;
2785
+ let skipped = 0;
2786
+ for (const obj of allObjects) {
2787
+ const driver = this.ql.getDriverForObject(obj.name);
2788
+ if (!driver) {
2789
+ ctx.logger.debug("No driver available for object, skipping schema sync", {
2790
+ object: obj.name
2791
+ });
2792
+ skipped++;
2793
+ continue;
2794
+ }
2795
+ if (typeof driver.syncSchema !== "function") {
2796
+ ctx.logger.debug("Driver does not support syncSchema, skipping", {
2797
+ object: obj.name,
2798
+ driver: driver.name
2799
+ });
2800
+ skipped++;
2801
+ continue;
2802
+ }
2803
+ const tableName = obj.tableName || obj.name;
2804
+ try {
2805
+ await driver.syncSchema(tableName, obj);
2806
+ synced++;
2807
+ } catch (e) {
2808
+ ctx.logger.warn("Failed to sync schema for object", {
2809
+ object: obj.name,
2810
+ tableName,
2811
+ driver: driver.name,
2812
+ error: e instanceof Error ? e.message : String(e)
2813
+ });
2814
+ }
2815
+ }
2816
+ if (synced > 0 || skipped > 0) {
2817
+ ctx.logger.info("Schema sync complete", { synced, skipped, total: allObjects.length });
2818
+ }
2819
+ }
2740
2820
  /**
2741
2821
  * Load metadata from external metadata service into ObjectQL registry
2742
2822
  * This enables ObjectQL to use file-based or remote metadata