@objectstack/objectql 4.0.3 → 4.0.4

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/index.mjs CHANGED
@@ -696,7 +696,10 @@ var ObjectStackProtocolImplementation = class {
696
696
  const services = this.getServicesRegistry?.();
697
697
  const metadataService = services?.get("metadata");
698
698
  if (metadataService && typeof metadataService.list === "function") {
699
- const runtimeItems = await metadataService.list(request.type);
699
+ let runtimeItems = await metadataService.list(request.type);
700
+ if (packageId && runtimeItems && runtimeItems.length > 0) {
701
+ runtimeItems = runtimeItems.filter((item) => item?._packageId === packageId);
702
+ }
700
703
  if (runtimeItems && runtimeItems.length > 0) {
701
704
  const itemMap = /* @__PURE__ */ new Map();
702
705
  for (const item of items) {
@@ -1515,6 +1518,10 @@ var _ObjectQL = class _ObjectQL {
1515
1518
  constructor(hostContext = {}) {
1516
1519
  this.drivers = /* @__PURE__ */ new Map();
1517
1520
  this.defaultDriver = null;
1521
+ // Datasource mapping rules (imported from defineStack)
1522
+ this.datasourceMapping = [];
1523
+ // Package manifests registry (for defaultDatasource lookup)
1524
+ this.manifests = /* @__PURE__ */ new Map();
1518
1525
  // Per-object hooks with priority support
1519
1526
  this.hooks = /* @__PURE__ */ new Map([
1520
1527
  ["beforeFind", []],
@@ -1712,6 +1719,9 @@ var _ObjectQL = class _ObjectQL {
1712
1719
  const id = manifest.id || manifest.name;
1713
1720
  const namespace = manifest.namespace;
1714
1721
  this.logger.debug("Registering package manifest", { id, namespace });
1722
+ if (id) {
1723
+ this.manifests.set(id, manifest);
1724
+ }
1715
1725
  SchemaRegistry.installPackage(manifest);
1716
1726
  this.logger.debug("Installed Package", { id: manifest.id, name: manifest.name, namespace });
1717
1727
  if (manifest.objects) {
@@ -1966,27 +1976,99 @@ var _ObjectQL = class _ObjectQL {
1966
1976
  }
1967
1977
  /**
1968
1978
  * Helper to get the target driver
1979
+ *
1980
+ * Resolution priority (first match wins):
1981
+ * 1. Object's explicit `datasource` field (if not 'default')
1982
+ * 2. DatasourceMapping rules (namespace/package/pattern matching)
1983
+ * 3. Package's `defaultDatasource` from manifest
1984
+ * 4. Global default driver
1969
1985
  */
1970
1986
  getDriver(objectName) {
1971
1987
  const object = SchemaRegistry.getObject(objectName);
1972
- if (object) {
1973
- const datasourceName = object.datasource || "default";
1974
- if (datasourceName === "default") {
1975
- if (this.defaultDriver && this.drivers.has(this.defaultDriver)) {
1976
- return this.drivers.get(this.defaultDriver);
1977
- }
1978
- } else {
1979
- if (this.drivers.has(datasourceName)) {
1980
- return this.drivers.get(datasourceName);
1988
+ if (object?.datasource && object.datasource !== "default") {
1989
+ if (this.drivers.has(object.datasource)) {
1990
+ return this.drivers.get(object.datasource);
1991
+ }
1992
+ throw new Error(`[ObjectQL] Datasource '${object.datasource}' configured for object '${objectName}' is not registered.`);
1993
+ }
1994
+ const mappedDatasource = this.resolveDatasourceFromMapping(objectName, object);
1995
+ if (mappedDatasource && this.drivers.has(mappedDatasource)) {
1996
+ this.logger.debug("Resolved datasource from mapping", {
1997
+ object: objectName,
1998
+ datasource: mappedDatasource
1999
+ });
2000
+ return this.drivers.get(mappedDatasource);
2001
+ }
2002
+ const fqn = object?.name || objectName;
2003
+ const owner = SchemaRegistry.getObjectOwner(fqn);
2004
+ if (owner?.packageId) {
2005
+ const manifest = this.manifests.get(owner.packageId);
2006
+ if (manifest?.defaultDatasource && manifest.defaultDatasource !== "default") {
2007
+ if (this.drivers.has(manifest.defaultDatasource)) {
2008
+ this.logger.debug("Resolved datasource from package manifest", {
2009
+ object: objectName,
2010
+ package: owner.packageId,
2011
+ datasource: manifest.defaultDatasource
2012
+ });
2013
+ return this.drivers.get(manifest.defaultDatasource);
1981
2014
  }
1982
- throw new Error(`[ObjectQL] Datasource '${datasourceName}' configured for object '${objectName}' is not registered.`);
1983
2015
  }
1984
2016
  }
1985
- if (this.defaultDriver) {
2017
+ if (this.defaultDriver && this.drivers.has(this.defaultDriver)) {
1986
2018
  return this.drivers.get(this.defaultDriver);
1987
2019
  }
1988
2020
  throw new Error(`[ObjectQL] No driver available for object '${objectName}'`);
1989
2021
  }
2022
+ /**
2023
+ * Resolve datasource from mapping rules
2024
+ *
2025
+ * Rules are evaluated in order (or by priority if specified).
2026
+ * First matching rule wins.
2027
+ */
2028
+ resolveDatasourceFromMapping(objectName, object) {
2029
+ if (!this.datasourceMapping || this.datasourceMapping.length === 0) {
2030
+ return null;
2031
+ }
2032
+ const sortedRules = [...this.datasourceMapping].sort((a, b) => {
2033
+ const aPriority = a.priority ?? 1e3;
2034
+ const bPriority = b.priority ?? 1e3;
2035
+ return aPriority - bPriority;
2036
+ });
2037
+ for (const rule of sortedRules) {
2038
+ if (rule.namespace && object?.namespace === rule.namespace) {
2039
+ return rule.datasource;
2040
+ }
2041
+ if (rule.package && object?.packageId === rule.package) {
2042
+ return rule.datasource;
2043
+ }
2044
+ if (rule.objectPattern && this.matchPattern(objectName, rule.objectPattern)) {
2045
+ return rule.datasource;
2046
+ }
2047
+ if (rule.default) {
2048
+ return rule.datasource;
2049
+ }
2050
+ }
2051
+ return null;
2052
+ }
2053
+ /**
2054
+ * Simple glob pattern matching
2055
+ * Supports * (any chars) and ? (single char)
2056
+ */
2057
+ matchPattern(objectName, pattern) {
2058
+ const regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
2059
+ const regex = new RegExp(`^${regexPattern}$`);
2060
+ return regex.test(objectName);
2061
+ }
2062
+ /**
2063
+ * Set datasource mapping rules
2064
+ * Called by ObjectQLPlugin during bootstrap
2065
+ */
2066
+ setDatasourceMapping(rules) {
2067
+ this.datasourceMapping = rules;
2068
+ this.logger.info("Datasource mapping rules configured", {
2069
+ ruleCount: rules.length
2070
+ });
2071
+ }
1990
2072
  /**
1991
2073
  * Initialize the engine and all registered drivers
1992
2074
  */