@objectstack/service-analytics 10.0.0 → 10.2.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/index.d.cts CHANGED
@@ -221,6 +221,14 @@ interface AnalyticsServiceConfig {
221
221
  * `StrategyContext.coerceTemporalFilterValue` for the full rationale.
222
222
  */
223
223
  coerceTemporalFilterValue?: (objectName: string, fieldName: string, value: unknown) => unknown;
224
+ /**
225
+ * ADR-0062 D6 — report whether an object is federated (external datasource).
226
+ * Threaded into the StrategyContext so `NativeSQLStrategy` declines external
227
+ * objects (which it would otherwise query against the wrong physical table),
228
+ * routing them to the driver-correct ObjectQL aggregate path instead. See
229
+ * `StrategyContext.isExternalObject`.
230
+ */
231
+ isExternalObject?: (objectName: string) => boolean;
224
232
  /**
225
233
  * ADR-0021 — optional object-graph resolver used when compiling datasets:
226
234
  * `(baseObject, relationshipName) => relatedObjectName | undefined`. When
package/dist/index.d.ts CHANGED
@@ -221,6 +221,14 @@ interface AnalyticsServiceConfig {
221
221
  * `StrategyContext.coerceTemporalFilterValue` for the full rationale.
222
222
  */
223
223
  coerceTemporalFilterValue?: (objectName: string, fieldName: string, value: unknown) => unknown;
224
+ /**
225
+ * ADR-0062 D6 — report whether an object is federated (external datasource).
226
+ * Threaded into the StrategyContext so `NativeSQLStrategy` declines external
227
+ * objects (which it would otherwise query against the wrong physical table),
228
+ * routing them to the driver-correct ObjectQL aggregate path instead. See
229
+ * `StrategyContext.isExternalObject`.
230
+ */
231
+ isExternalObject?: (objectName: string) => boolean;
224
232
  /**
225
233
  * ADR-0021 — optional object-graph resolver used when compiling datasets:
226
234
  * `(baseObject, relationshipName) => relatedObjectName | undefined`. When
package/dist/index.js CHANGED
@@ -320,6 +320,17 @@ var NativeSQLStrategy = class {
320
320
  canHandle(query, ctx) {
321
321
  if (!query.cube) return false;
322
322
  if (query.timeDimensions?.some((td) => !!td.granularity)) return false;
323
+ if (typeof ctx.isExternalObject === "function") {
324
+ const cube = ctx.getCube(query.cube);
325
+ if (cube) {
326
+ if (ctx.isExternalObject(this.extractObjectName(cube))) return false;
327
+ const joinTargets = cube.joins ? Object.values(cube.joins) : [];
328
+ for (const j of joinTargets) {
329
+ const joinedObject = j?.name;
330
+ if (joinedObject && ctx.isExternalObject(joinedObject)) return false;
331
+ }
332
+ }
333
+ }
323
334
  const caps = ctx.queryCapabilities(query.cube);
324
335
  return caps.nativeSql && typeof ctx.executeRawSql === "function";
325
336
  }
@@ -1477,7 +1488,8 @@ var AnalyticsService = class {
1477
1488
  // Prefer a compiled dataset's declared relationships (D-C join allowlist);
1478
1489
  // fall back to any explicitly-configured provider for legacy cubes.
1479
1490
  getAllowedRelationships: (cubeName) => this.datasetRegistry.get(cubeName)?.allowedRelationships ?? config.getAllowedRelationships?.(cubeName),
1480
- coerceTemporalFilterValue: config.coerceTemporalFilterValue
1491
+ coerceTemporalFilterValue: config.coerceTemporalFilterValue,
1492
+ isExternalObject: config.isExternalObject
1481
1493
  };
1482
1494
  const builtIn = [
1483
1495
  new NativeSQLStrategy(),
@@ -2082,6 +2094,13 @@ var AnalyticsServicePlugin = class {
2082
2094
  const f = dataEngine()?.getObject?.(object)?.fields?.[field];
2083
2095
  return f ? { type: f.type, defaultCurrency: f.currencyConfig?.defaultCurrency } : void 0;
2084
2096
  },
2097
+ // ADR-0062 D6 — a federated object carries an `external` block (ADR-0015).
2098
+ // Reported so NativeSQLStrategy declines it (its hand-compiled FROM would
2099
+ // hit the wrong physical table) and the driver-correct ObjectQL path runs.
2100
+ isExternalObject: (objectName) => {
2101
+ const obj = dataEngine()?.getObject?.(objectName);
2102
+ return !!(obj && obj.external != null);
2103
+ },
2085
2104
  draftRowsResolver
2086
2105
  };
2087
2106
  if (autoBridgedReadScope) {