@hypequery/datasets 0.8.0 → 0.10.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/aggregations.d.ts +12 -0
- package/dist/aggregations.d.ts.map +1 -1
- package/dist/aggregations.js +32 -0
- package/dist/api.type-test.js +6 -0
- package/dist/catalog.d.ts +8 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +18 -6
- package/dist/contract.d.ts +7 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +5 -1
- package/dist/dataset-query.d.ts.map +1 -1
- package/dist/dataset-query.js +8 -5
- package/dist/dataset.d.ts +4 -3
- package/dist/dataset.d.ts.map +1 -1
- package/dist/dataset.js +5 -4
- package/dist/executor.d.ts +7 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +39 -10
- package/dist/field.d.ts +4 -4
- package/dist/field.d.ts.map +1 -1
- package/dist/in-memory-backend.d.ts +5 -0
- package/dist/in-memory-backend.d.ts.map +1 -1
- package/dist/in-memory-backend.js +118 -2
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/measure.d.ts +20 -0
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +51 -0
- package/dist/query-builder-protocol.d.ts +22 -0
- package/dist/query-builder-protocol.d.ts.map +1 -1
- package/dist/query-planner.d.ts +7 -6
- package/dist/query-planner.d.ts.map +1 -1
- package/dist/query-planner.js +98 -37
- package/dist/relationships.d.ts +9 -9
- package/dist/relationships.d.ts.map +1 -1
- package/dist/semantic-plan.d.ts +54 -9
- package/dist/semantic-plan.d.ts.map +1 -1
- package/dist/semantic-plan.js +9 -0
- package/dist/semantic-planner.d.ts.map +1 -1
- package/dist/semantic-planner.js +73 -5
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +29 -18
- package/dist/types.d.ts +38 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/dataset-normalization.d.ts +1 -1
- package/dist/utils/dataset-normalization.d.ts.map +1 -1
- package/dist/utils/dataset-normalization.js +13 -1
- package/dist/utils/dataset-query-validation.d.ts.map +1 -1
- package/dist/utils/dataset-query-validation.js +50 -12
- package/dist/utils/dataset-validation.d.ts.map +1 -1
- package/dist/utils/dataset-validation.js +21 -1
- package/dist/utils/filtered-aggregation-sql.d.ts +2 -1
- package/dist/utils/filtered-aggregation-sql.d.ts.map +1 -1
- package/dist/utils/filtered-aggregation-sql.js +13 -4
- package/dist/utils/relationship-builder-plan.d.ts +56 -0
- package/dist/utils/relationship-builder-plan.d.ts.map +1 -0
- package/dist/utils/relationship-builder-plan.js +92 -0
- package/dist/utils/relationship-fields.d.ts +62 -0
- package/dist/utils/relationship-fields.d.ts.map +1 -0
- package/dist/utils/relationship-fields.js +98 -0
- package/dist/utils/relationship-validation.d.ts +15 -0
- package/dist/utils/relationship-validation.d.ts.map +1 -0
- package/dist/utils/relationship-validation.js +29 -0
- package/package.json +1 -1
package/dist/aggregations.d.ts
CHANGED
|
@@ -21,4 +21,16 @@ export declare function countDistinct(field: string): AggregationSpec;
|
|
|
21
21
|
export declare function avg(field: string): AggregationSpec;
|
|
22
22
|
export declare function min(field: string): AggregationSpec;
|
|
23
23
|
export declare function max(field: string): AggregationSpec;
|
|
24
|
+
/** Approximate percentile of a numeric field at `level` in [0, 1]. */
|
|
25
|
+
export declare function percentile(field: string, level: number): AggregationSpec;
|
|
26
|
+
/** Median — sugar for `percentile(field, 0.5)`. */
|
|
27
|
+
export declare function median(field: string): AggregationSpec;
|
|
28
|
+
/** Value of `field` on the row where `by` is greatest. */
|
|
29
|
+
export declare function argMax(field: string, by: string): AggregationSpec;
|
|
30
|
+
/** Value of `field` on the row where `by` is smallest. */
|
|
31
|
+
export declare function argMin(field: string, by: string): AggregationSpec;
|
|
32
|
+
/** Sample standard deviation. */
|
|
33
|
+
export declare function stddev(field: string): AggregationSpec;
|
|
34
|
+
/** Sample variance. */
|
|
35
|
+
export declare function variance(field: string): AggregationSpec;
|
|
24
36
|
//# sourceMappingURL=aggregations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregations.d.ts","sourceRoot":"","sources":["../src/aggregations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"aggregations.d.ts","sourceRoot":"","sources":["../src/aggregations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAWnE,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAE5D;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAGxE;AAED,mDAAmD;AACnD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,iCAAiC;AACjC,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEvD"}
|
package/dist/aggregations.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* });
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
|
+
import { validatePercentileLevel } from './measure.js';
|
|
17
18
|
function createAggregation(aggregation, field) {
|
|
18
19
|
return {
|
|
19
20
|
__type: 'aggregation_spec',
|
|
@@ -39,3 +40,34 @@ export function min(field) {
|
|
|
39
40
|
export function max(field) {
|
|
40
41
|
return createAggregation('max', field);
|
|
41
42
|
}
|
|
43
|
+
/** Approximate percentile of a numeric field at `level` in [0, 1]. */
|
|
44
|
+
export function percentile(field, level) {
|
|
45
|
+
validatePercentileLevel(level);
|
|
46
|
+
return { ...createAggregation('percentile', field), level };
|
|
47
|
+
}
|
|
48
|
+
/** Median — sugar for `percentile(field, 0.5)`. */
|
|
49
|
+
export function median(field) {
|
|
50
|
+
return percentile(field, 0.5);
|
|
51
|
+
}
|
|
52
|
+
/** Value of `field` on the row where `by` is greatest. */
|
|
53
|
+
export function argMax(field, by) {
|
|
54
|
+
if (typeof by !== 'string' || by.trim().length === 0) {
|
|
55
|
+
throw new Error('argMax(field, by) requires a "by" field.');
|
|
56
|
+
}
|
|
57
|
+
return { ...createAggregation('argMax', field), argField: by };
|
|
58
|
+
}
|
|
59
|
+
/** Value of `field` on the row where `by` is smallest. */
|
|
60
|
+
export function argMin(field, by) {
|
|
61
|
+
if (typeof by !== 'string' || by.trim().length === 0) {
|
|
62
|
+
throw new Error('argMin(field, by) requires a "by" field.');
|
|
63
|
+
}
|
|
64
|
+
return { ...createAggregation('argMin', field), argField: by };
|
|
65
|
+
}
|
|
66
|
+
/** Sample standard deviation. */
|
|
67
|
+
export function stddev(field) {
|
|
68
|
+
return createAggregation('stddev', field);
|
|
69
|
+
}
|
|
70
|
+
/** Sample variance. */
|
|
71
|
+
export function variance(field) {
|
|
72
|
+
return createAggregation('variance', field);
|
|
73
|
+
}
|
package/dist/api.type-test.js
CHANGED
|
@@ -80,7 +80,13 @@ const builderFactory = {
|
|
|
80
80
|
avg: () => builderFactory.table('orders'),
|
|
81
81
|
min: () => builderFactory.table('orders'),
|
|
82
82
|
max: () => builderFactory.table('orders'),
|
|
83
|
+
argMax: () => builderFactory.table('orders'),
|
|
84
|
+
argMin: () => builderFactory.table('orders'),
|
|
85
|
+
quantile: () => builderFactory.table('orders'),
|
|
86
|
+
stddev: () => builderFactory.table('orders'),
|
|
87
|
+
variance: () => builderFactory.table('orders'),
|
|
83
88
|
where: () => builderFactory.table('orders'),
|
|
89
|
+
leftJoin: () => builderFactory.table('orders'),
|
|
84
90
|
groupBy: () => builderFactory.table('orders'),
|
|
85
91
|
orderBy: () => builderFactory.table('orders'),
|
|
86
92
|
limit: () => builderFactory.table('orders'),
|
package/dist/catalog.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export interface DimensionCatalogEntry {
|
|
|
11
11
|
export interface MeasureCatalogEntry {
|
|
12
12
|
aggregation: MeasureDefinition['aggregation'];
|
|
13
13
|
field: string;
|
|
14
|
+
/** Second column for argMax/argMin. */
|
|
15
|
+
argField?: string;
|
|
16
|
+
/** Percentile level in [0, 1]. */
|
|
17
|
+
level?: number;
|
|
14
18
|
sql?: string;
|
|
15
19
|
label?: string;
|
|
16
20
|
description?: string;
|
|
@@ -41,7 +45,8 @@ export interface RelationshipCatalogEntry {
|
|
|
41
45
|
target: string;
|
|
42
46
|
from: string;
|
|
43
47
|
to: string;
|
|
44
|
-
|
|
48
|
+
queryable: boolean;
|
|
49
|
+
fields: string[];
|
|
45
50
|
}
|
|
46
51
|
export interface DatasetCatalog {
|
|
47
52
|
name: string;
|
|
@@ -63,6 +68,8 @@ export type DatasetCatalogMap = Record<string, DatasetCatalog>;
|
|
|
63
68
|
export type DatasetCatalogSource = AnyDatasetInstance & {
|
|
64
69
|
metrics?: Record<string, MetricHandle>;
|
|
65
70
|
};
|
|
71
|
+
/** All queryable relationship field names (`<relationship>.<dimension>`) a catalog advertises. */
|
|
72
|
+
export declare function getQueryableRelationshipFields(catalog: DatasetCatalog): string[];
|
|
66
73
|
export declare function getDatasetCatalog(dataset: DatasetCatalogSource): DatasetCatalog;
|
|
67
74
|
export declare function getDatasetCatalogs(datasets: Record<string, DatasetCatalogSource>): DatasetCatalogMap;
|
|
68
75
|
//# sourceMappingURL=catalog.d.ts.map
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/catalog.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SEMANTIC_FILTER_OPERATORS, SUPPORTED_TIME_GRAINS } from './constants.js';
|
|
2
|
+
import { listQueryableRelationshipFields } from './utils/relationship-fields.js';
|
|
2
3
|
function dimensionToCatalog(dimension) {
|
|
3
4
|
return {
|
|
4
5
|
type: dimension.fieldType,
|
|
@@ -14,6 +15,8 @@ function measureToCatalog(measure) {
|
|
|
14
15
|
return {
|
|
15
16
|
aggregation: measure.aggregation,
|
|
16
17
|
field: measure.field,
|
|
18
|
+
argField: measure.argField,
|
|
19
|
+
level: measure.level,
|
|
17
20
|
sql: measure.sql,
|
|
18
21
|
label: measure.label,
|
|
19
22
|
description: measure.description,
|
|
@@ -45,21 +48,32 @@ function metricToCatalog(metric) {
|
|
|
45
48
|
requires: contract.requires,
|
|
46
49
|
};
|
|
47
50
|
}
|
|
48
|
-
function relationshipToCatalog(relationship) {
|
|
51
|
+
function relationshipToCatalog(name, relationship) {
|
|
49
52
|
return {
|
|
50
53
|
kind: relationship.kind,
|
|
51
54
|
target: relationship.target().name,
|
|
52
55
|
from: relationship.from,
|
|
53
56
|
to: relationship.to,
|
|
54
|
-
|
|
57
|
+
queryable: relationship.kind !== 'hasMany',
|
|
58
|
+
fields: listQueryableRelationshipFields(name, relationship),
|
|
55
59
|
};
|
|
56
60
|
}
|
|
61
|
+
/** All queryable relationship field names (`<relationship>.<dimension>`) a catalog advertises. */
|
|
62
|
+
export function getQueryableRelationshipFields(catalog) {
|
|
63
|
+
return Object.values(catalog.relationships)
|
|
64
|
+
.filter(relationship => relationship.queryable)
|
|
65
|
+
.flatMap(relationship => relationship.fields);
|
|
66
|
+
}
|
|
57
67
|
export function getDatasetCatalog(dataset) {
|
|
58
68
|
const dimensionNames = Object.keys(dataset.dimensions);
|
|
59
69
|
const measureNames = Object.keys(dataset.measures);
|
|
60
70
|
const metricNames = Object.keys(dataset.metrics ?? {});
|
|
61
71
|
const supportedGrains = dataset.timeKey ? [...SUPPORTED_TIME_GRAINS] : [];
|
|
62
72
|
const maxLimit = dataset.limits?.maxResultSize;
|
|
73
|
+
const relationships = Object.fromEntries(Object.entries(dataset.relationships).map(([name, relationship]) => [
|
|
74
|
+
name,
|
|
75
|
+
relationshipToCatalog(name, relationship),
|
|
76
|
+
]));
|
|
63
77
|
return {
|
|
64
78
|
name: dataset.name,
|
|
65
79
|
source: dataset.source,
|
|
@@ -81,10 +95,7 @@ export function getDatasetCatalog(dataset) {
|
|
|
81
95
|
name,
|
|
82
96
|
filterToCatalog(filter, dataset.dimensions),
|
|
83
97
|
])),
|
|
84
|
-
relationships
|
|
85
|
-
name,
|
|
86
|
-
relationshipToCatalog(relationship),
|
|
87
|
-
])),
|
|
98
|
+
relationships,
|
|
88
99
|
limits: dataset.limits,
|
|
89
100
|
requiresTenant: !!dataset.tenantKey,
|
|
90
101
|
supportedGrains,
|
|
@@ -92,6 +103,7 @@ export function getDatasetCatalog(dataset) {
|
|
|
92
103
|
...dimensionNames,
|
|
93
104
|
...measureNames,
|
|
94
105
|
...metricNames,
|
|
106
|
+
...Object.values(relationships).flatMap(relationship => relationship.fields),
|
|
95
107
|
...(dataset.timeKey ? ['period'] : []),
|
|
96
108
|
],
|
|
97
109
|
maxLimit,
|
package/dist/contract.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { DatasetLimits } from './types.js';
|
|
|
4
4
|
* Version of the semantic contract format. Bump when the serialized shape
|
|
5
5
|
* changes in a way that snapshot consumers must account for.
|
|
6
6
|
*/
|
|
7
|
-
export declare const SEMANTIC_CONTRACT_VERSION =
|
|
7
|
+
export declare const SEMANTIC_CONTRACT_VERSION = 2;
|
|
8
8
|
export interface ContractDimension {
|
|
9
9
|
type: DimensionCatalogEntry['type'];
|
|
10
10
|
column?: string;
|
|
@@ -17,6 +17,10 @@ export interface ContractDimension {
|
|
|
17
17
|
export interface ContractMeasure {
|
|
18
18
|
aggregation: MeasureCatalogEntry['aggregation'];
|
|
19
19
|
field: string;
|
|
20
|
+
/** Second column for argMax/argMin. */
|
|
21
|
+
argField?: string;
|
|
22
|
+
/** Percentile level in [0, 1]. */
|
|
23
|
+
level?: number;
|
|
20
24
|
sql?: string;
|
|
21
25
|
label?: string;
|
|
22
26
|
description?: string;
|
|
@@ -45,6 +49,8 @@ export interface ContractRelationship {
|
|
|
45
49
|
target: string;
|
|
46
50
|
from: string;
|
|
47
51
|
to: string;
|
|
52
|
+
queryable: boolean;
|
|
53
|
+
fields: string[];
|
|
48
54
|
}
|
|
49
55
|
export interface ContractDataset {
|
|
50
56
|
name: string;
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjC,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
package/dist/contract.js
CHANGED
|
@@ -6,7 +6,7 @@ import { sortedRecord, uniqueSorted } from './utils/canonical-json.js';
|
|
|
6
6
|
* Version of the semantic contract format. Bump when the serialized shape
|
|
7
7
|
* changes in a way that snapshot consumers must account for.
|
|
8
8
|
*/
|
|
9
|
-
export const SEMANTIC_CONTRACT_VERSION =
|
|
9
|
+
export const SEMANTIC_CONTRACT_VERSION = 2;
|
|
10
10
|
/**
|
|
11
11
|
* Builds a deterministic semantic contract from dataset instances.
|
|
12
12
|
*
|
|
@@ -72,6 +72,8 @@ function measureToContract(entry, includeSql) {
|
|
|
72
72
|
return {
|
|
73
73
|
aggregation: entry.aggregation,
|
|
74
74
|
field: entry.field,
|
|
75
|
+
...(entry.argField !== undefined ? { argField: entry.argField } : {}),
|
|
76
|
+
...(entry.level !== undefined ? { level: entry.level } : {}),
|
|
75
77
|
...(includeSql && entry.sql !== undefined ? { sql: normalizeSql(entry.sql) } : {}),
|
|
76
78
|
...(entry.label !== undefined ? { label: entry.label } : {}),
|
|
77
79
|
...(entry.description !== undefined ? { description: entry.description } : {}),
|
|
@@ -106,6 +108,8 @@ function relationshipToContract(entry) {
|
|
|
106
108
|
target: entry.target,
|
|
107
109
|
from: entry.from,
|
|
108
110
|
to: entry.to,
|
|
111
|
+
queryable: entry.queryable,
|
|
112
|
+
fields: uniqueSorted(entry.fields),
|
|
109
113
|
};
|
|
110
114
|
}
|
|
111
115
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset-query.d.ts","sourceRoot":"","sources":["../src/dataset-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAQ7F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"dataset-query.d.ts","sourceRoot":"","sources":["../src/dataset-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAQ7F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAyBxD,MAAM,WAAW,4BAA4B;IAC3C,cAAc,EAAE,uBAAuB,CAAC;IACxC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAElB;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,4BAA4B,GACpC,gBAAgB,CA4ClB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAa7B"}
|
package/dist/dataset-query.js
CHANGED
|
@@ -2,6 +2,7 @@ import { appendOrderLimitOffset, applyMeasureDefinition, buildDimensionSelection
|
|
|
2
2
|
import { validateDatasetQueryInput } from './utils/dataset-query-validation.js';
|
|
3
3
|
import { getRuntimeTenantId, getRuntimeTenantPredicate, } from './utils/tenant-runtime.js';
|
|
4
4
|
import { applyPagination, overfetchLimit } from './utils/pagination.js';
|
|
5
|
+
import { applyRelationshipJoins, buildRelationshipBuilderContext, qualifyBaseColumn, } from './utils/relationship-builder-plan.js';
|
|
5
6
|
function toResultMeta(qb, timingMs, context) {
|
|
6
7
|
return {
|
|
7
8
|
sql: qb.toSQLWithParams().sql,
|
|
@@ -17,14 +18,16 @@ export function buildDatasetQueryBuilder(ds, query, options) {
|
|
|
17
18
|
if (!validation.valid) {
|
|
18
19
|
throw new Error(`Invalid dataset query: ${validation.errors.join('; ')}`);
|
|
19
20
|
}
|
|
21
|
+
const joinCtx = buildRelationshipBuilderContext(ds, query, options.context);
|
|
20
22
|
let qb = options.builderFactory.table(ds.source);
|
|
21
|
-
|
|
23
|
+
qb = applyRelationshipJoins(qb, joinCtx);
|
|
24
|
+
const { selectParts, groupByParts } = buildDimensionSelectionPlan(ds, query.dimensions ?? [], query.by, joinCtx);
|
|
22
25
|
const measureNames = query.measures ?? Object.keys(ds.measures);
|
|
23
26
|
if (selectParts.length > 0) {
|
|
24
27
|
qb = qb.select(selectParts);
|
|
25
28
|
}
|
|
26
29
|
for (const measureName of measureNames) {
|
|
27
|
-
qb = applyMeasureDefinition(qb, ds, measureName, ds.measures[measureName]);
|
|
30
|
+
qb = applyMeasureDefinition(qb, ds, measureName, ds.measures[measureName], joinCtx);
|
|
28
31
|
}
|
|
29
32
|
if (groupByParts.length > 0) {
|
|
30
33
|
qb = qb.groupBy(groupByParts);
|
|
@@ -32,13 +35,13 @@ export function buildDatasetQueryBuilder(ds, query, options) {
|
|
|
32
35
|
const tenantColumn = resolveTenantFilterColumn(ds, options.context);
|
|
33
36
|
const tenantPredicate = getRuntimeTenantPredicate(options.context);
|
|
34
37
|
if (tenantPredicate && tenantColumn) {
|
|
35
|
-
qb = qb.where(tenantColumn, tenantPredicate.operator, tenantPredicate.value);
|
|
38
|
+
qb = qb.where(qualifyBaseColumn(joinCtx, tenantColumn), tenantPredicate.operator, tenantPredicate.value);
|
|
36
39
|
}
|
|
37
40
|
for (const filter of query.filters ?? []) {
|
|
38
|
-
const resolvedField = resolveFilterField(ds, filter.field);
|
|
41
|
+
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
39
42
|
qb = qb.where(resolvedField, filter.operator, filter.value);
|
|
40
43
|
}
|
|
41
|
-
return appendOrderLimitOffset(qb, query.orderBy, query.by, options.executionLimit ?? query.limit, query.offset);
|
|
44
|
+
return appendOrderLimitOffset(qb, query.orderBy, query.by, options.executionLimit ?? query.limit, query.offset, joinCtx);
|
|
42
45
|
}
|
|
43
46
|
export async function runDatasetQuery(ds, query, options) {
|
|
44
47
|
const start = Date.now();
|
package/dist/dataset.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dataset() — creates a typed semantic model over a physical table.
|
|
3
3
|
*
|
|
4
|
-
* Relationships are modeled on the dataset
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Relationships are modeled on the dataset. To-one relationships (`belongsTo`,
|
|
5
|
+
* `hasOne`) are queryable one hop deep as `<relationship>.<dimension>` and
|
|
6
|
+
* execute as LEFT JOINs; `hasMany` relationships remain metadata-only to avoid
|
|
7
|
+
* fan-out corrupting aggregates.
|
|
7
8
|
*
|
|
8
9
|
* @example
|
|
9
10
|
* ```ts
|
package/dist/dataset.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../src/dataset.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../src/dataset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EAKvB,MAAM,YAAY,CAAC;AAkBpB,wBAAgB,OAAO,CACrB,YAAY,SAAS,MAAM,EAC3B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACvD,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC3E,cAAc,SAAS,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAErF,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,cAAc,CAAC,GAC5D,eAAe,CAAC,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,CAAC,CA2DvE"}
|
package/dist/dataset.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dataset() — creates a typed semantic model over a physical table.
|
|
3
3
|
*
|
|
4
|
-
* Relationships are modeled on the dataset
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Relationships are modeled on the dataset. To-one relationships (`belongsTo`,
|
|
5
|
+
* `hasOne`) are queryable one hop deep as `<relationship>.<dimension>` and
|
|
6
|
+
* execute as LEFT JOINs; `hasMany` relationships remain metadata-only to avoid
|
|
7
|
+
* fan-out corrupting aggregates.
|
|
7
8
|
*
|
|
8
9
|
* @example
|
|
9
10
|
* ```ts
|
|
@@ -35,7 +36,7 @@ export function dataset(name, config) {
|
|
|
35
36
|
const dimensions = normalizeDimensions(config);
|
|
36
37
|
const measures = normalizeMeasures(config.measures);
|
|
37
38
|
const filters = normalizeFilters(dimensions, config.filters);
|
|
38
|
-
const relationships = normalizeRelationships(config.relationships);
|
|
39
|
+
const relationships = normalizeRelationships(config.relationships, config.source);
|
|
39
40
|
function metric(metricName, metricConfig) {
|
|
40
41
|
if (isDerivedMetricConfig(metricConfig)) {
|
|
41
42
|
validateDerivedMetric(ds, metricName, metricConfig);
|
package/dist/executor.d.ts
CHANGED
|
@@ -17,7 +17,13 @@ export interface MetricQueryEngineOptions {
|
|
|
17
17
|
export interface CreateDatasetClientOptions {
|
|
18
18
|
/** Query builder factory for executing semantic metric and dataset queries. */
|
|
19
19
|
queryBuilder?: QueryBuilderFactoryInput;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Semantic backend for executing neutral semantic plans.
|
|
22
|
+
*
|
|
23
|
+
* @deprecated Use `queryBuilder` instead — the query-builder path is
|
|
24
|
+
* canonical. The plan/backend path is frozen (bug fixes only) and will not
|
|
25
|
+
* gain new features.
|
|
26
|
+
*/
|
|
21
27
|
backend?: SemanticBackend;
|
|
22
28
|
/**
|
|
23
29
|
* Result-cache defaults for this client. Results are keyed by the canonical
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAGhB,kBAAkB,EAClB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAEV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAgB7E,OAAO,EAIL,KAAK,4BAA4B,EAClC,MAAM,oBAAoB,CAAC;AAW5B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* stays database-agnostic via query-builder and backend protocol interfaces.
|
|
6
6
|
*/
|
|
7
7
|
import { toQueryBuilderFactory } from './query-builder-protocol.js';
|
|
8
|
-
import { validateSQLIdentifier } from './sql-utils.js';
|
|
8
|
+
import { quoteSQLIdentifier, validateSQLIdentifier } from './sql-utils.js';
|
|
9
9
|
import { SUPPORTED_TIME_GRAINS, isSupportedTimeGrain } from './constants.js';
|
|
10
10
|
import { validateFilterValue } from './validation.js';
|
|
11
11
|
import { applyAggregationSpec, appendOrderLimitOffset, buildDimensionSelectionPlan, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
@@ -17,6 +17,9 @@ import { getRuntimeTenantId, getRuntimeTenantPredicate, validateTenantRuntime, }
|
|
|
17
17
|
import { applyPagination, overfetchLimit } from './utils/pagination.js';
|
|
18
18
|
import { SemanticQueryCache, } from './cache/semantic-query-cache.js';
|
|
19
19
|
import { buildDatasetQuerySignature, buildMetricQuerySignature, } from './cache/query-signature.js';
|
|
20
|
+
import { isQualifiedField, resolveQualifiedField } from './utils/relationship-fields.js';
|
|
21
|
+
import { validateQualifiedFilter } from './utils/relationship-validation.js';
|
|
22
|
+
import { applyRelationshipJoins, buildRelationshipBuilderContext, qualifyBaseColumn, } from './utils/relationship-builder-plan.js';
|
|
20
23
|
function validateQuery(metric, query, context) {
|
|
21
24
|
const errors = [];
|
|
22
25
|
const ref = getMetricRef(metric);
|
|
@@ -40,12 +43,26 @@ function validateQuery(metric, query, context) {
|
|
|
40
43
|
}
|
|
41
44
|
// Validate dimensions
|
|
42
45
|
for (const dim of query.dimensions ?? []) {
|
|
46
|
+
if (isQualifiedField(dim)) {
|
|
47
|
+
const resolution = resolveQualifiedField(ds, dim);
|
|
48
|
+
if (resolution?.error) {
|
|
49
|
+
errors.push(resolution.error);
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
43
53
|
if (!dimensionNames.includes(dim)) {
|
|
44
54
|
errors.push(`Unknown dimension "${dim}". Available: ${dimensionNames.join(', ')}`);
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
57
|
// Validate filters
|
|
48
58
|
for (const filter of query.filters ?? []) {
|
|
59
|
+
if (isQualifiedField(filter.field)) {
|
|
60
|
+
const filterError = validateQualifiedFilter(ds, filter, context);
|
|
61
|
+
if (filterError) {
|
|
62
|
+
errors.push(filterError);
|
|
63
|
+
}
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
49
66
|
if (!filterNames.includes(filter.field)) {
|
|
50
67
|
errors.push(`Unknown filter field "${filter.field}". Available: ${filterNames.join(', ')}`);
|
|
51
68
|
continue;
|
|
@@ -206,13 +223,15 @@ export class MetricQueryEngine {
|
|
|
206
223
|
}
|
|
207
224
|
buildBaseQuery(ref, spec, ds, query, grain, context) {
|
|
208
225
|
const activeBuilderFactory = resolveBuilderFactory(context, this.builderFactory);
|
|
226
|
+
const joinCtx = buildRelationshipBuilderContext(ds, query, context);
|
|
209
227
|
let qb = activeBuilderFactory.table(ds.source);
|
|
210
|
-
|
|
228
|
+
qb = applyRelationshipJoins(qb, joinCtx);
|
|
229
|
+
const { selectParts, groupByParts } = buildDimensionSelectionPlan(ds, query.dimensions ?? [], grain, joinCtx);
|
|
211
230
|
if (selectParts.length > 0) {
|
|
212
231
|
qb = qb.select(selectParts);
|
|
213
232
|
}
|
|
214
233
|
// Aggregation (appends to select, auto-sets groupBy on non-agg columns)
|
|
215
|
-
qb = applyAggregationSpec(qb, ds, spec, ref.name);
|
|
234
|
+
qb = applyAggregationSpec(qb, ds, spec, ref.name, joinCtx);
|
|
216
235
|
// Explicit groupBy (ensures period + dims are grouped even if aggregation auto-groupBy misses them)
|
|
217
236
|
if (groupByParts.length > 0) {
|
|
218
237
|
qb = qb.groupBy(groupByParts);
|
|
@@ -221,26 +240,28 @@ export class MetricQueryEngine {
|
|
|
221
240
|
const tenantColumn = resolveTenantFilterColumn(ds, context);
|
|
222
241
|
const tenantPredicate = getRuntimeTenantPredicate(context);
|
|
223
242
|
if (tenantPredicate && tenantColumn) {
|
|
224
|
-
qb = qb.where(tenantColumn, tenantPredicate.operator, tenantPredicate.value);
|
|
243
|
+
qb = qb.where(qualifyBaseColumn(joinCtx, tenantColumn), tenantPredicate.operator, tenantPredicate.value);
|
|
225
244
|
}
|
|
226
245
|
// User filters
|
|
227
246
|
for (const filter of query.filters ?? []) {
|
|
228
247
|
if (isTenantScopedFilter(ds, filter, context)) {
|
|
229
248
|
throw new Error(`Cannot filter on tenant field "${filter.field}" when runtime tenancy enforcement is active.`);
|
|
230
249
|
}
|
|
231
|
-
const resolvedField = resolveFilterField(ds, filter.field);
|
|
250
|
+
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
232
251
|
qb = qb.where(resolvedField, filter.operator, filter.value);
|
|
233
252
|
}
|
|
234
253
|
// Order, limit, offset
|
|
235
|
-
qb = appendOrderLimitOffset(qb, query.orderBy, grain, query.limit, query.offset);
|
|
254
|
+
qb = appendOrderLimitOffset(qb, query.orderBy, grain, query.limit, query.offset, joinCtx);
|
|
236
255
|
return qb;
|
|
237
256
|
}
|
|
238
257
|
buildDerivedSQLViaBuilder(ref, spec, query, grain, context) {
|
|
239
258
|
const activeBuilderFactory = resolveBuilderFactory(context, this.builderFactory);
|
|
240
259
|
const ds = ref.dataset;
|
|
260
|
+
const joinCtx = buildRelationshipBuilderContext(ds, query, context);
|
|
241
261
|
// Build the CTE inner query using the builder
|
|
242
262
|
let cteBuilder = activeBuilderFactory.table(ds.source);
|
|
243
|
-
|
|
263
|
+
cteBuilder = applyRelationshipJoins(cteBuilder, joinCtx);
|
|
264
|
+
const { selectParts, groupByParts } = buildDimensionSelectionPlan(ds, query.dimensions ?? [], grain, joinCtx);
|
|
244
265
|
if (selectParts.length > 0) {
|
|
245
266
|
cteBuilder = cteBuilder.select(selectParts);
|
|
246
267
|
}
|
|
@@ -252,7 +273,7 @@ export class MetricQueryEngine {
|
|
|
252
273
|
if (baseSpec.__type !== 'aggregation_spec') {
|
|
253
274
|
throw new Error(`Derived metric "${ref.name}" references non-base metric "${alias}".`);
|
|
254
275
|
}
|
|
255
|
-
cteBuilder = applyAggregationSpec(cteBuilder, ds, baseSpec, alias);
|
|
276
|
+
cteBuilder = applyAggregationSpec(cteBuilder, ds, baseSpec, alias, joinCtx);
|
|
256
277
|
refAliases[alias] = alias;
|
|
257
278
|
aggregateAliases.push(alias);
|
|
258
279
|
}
|
|
@@ -263,13 +284,13 @@ export class MetricQueryEngine {
|
|
|
263
284
|
const tenantColumn = resolveTenantFilterColumn(ds, context);
|
|
264
285
|
const tenantPredicate = getRuntimeTenantPredicate(context);
|
|
265
286
|
if (tenantPredicate && tenantColumn) {
|
|
266
|
-
cteBuilder = cteBuilder.where(tenantColumn, tenantPredicate.operator, tenantPredicate.value);
|
|
287
|
+
cteBuilder = cteBuilder.where(qualifyBaseColumn(joinCtx, tenantColumn), tenantPredicate.operator, tenantPredicate.value);
|
|
267
288
|
}
|
|
268
289
|
for (const filter of query.filters ?? []) {
|
|
269
290
|
if (isTenantScopedFilter(ds, filter, context)) {
|
|
270
291
|
throw new Error(`Cannot filter on tenant field "${filter.field}" when runtime tenancy enforcement is active.`);
|
|
271
292
|
}
|
|
272
|
-
const resolvedField = resolveFilterField(ds, filter.field);
|
|
293
|
+
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
273
294
|
cteBuilder = cteBuilder.where(resolvedField, filter.operator, filter.value);
|
|
274
295
|
}
|
|
275
296
|
const { sql: cteSql, parameters: cteParams } = cteBuilder.toSQLWithParams();
|
|
@@ -283,6 +304,11 @@ export class MetricQueryEngine {
|
|
|
283
304
|
if (grain)
|
|
284
305
|
outerSelectParts.push('period');
|
|
285
306
|
for (const dim of query.dimensions ?? []) {
|
|
307
|
+
// Joined dimensions surface from the CTE under their quoted qualified alias.
|
|
308
|
+
if (joinCtx && isQualifiedField(dim)) {
|
|
309
|
+
outerSelectParts.push(quoteSQLIdentifier(dim));
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
286
312
|
validateSQLIdentifier(dim, 'dimension name');
|
|
287
313
|
outerSelectParts.push(dim);
|
|
288
314
|
}
|
|
@@ -293,6 +319,9 @@ export class MetricQueryEngine {
|
|
|
293
319
|
// ORDER BY
|
|
294
320
|
if (query.orderBy && query.orderBy.length > 0) {
|
|
295
321
|
const orderParts = query.orderBy.map(o => {
|
|
322
|
+
if (joinCtx && isQualifiedField(o.field)) {
|
|
323
|
+
return `${quoteSQLIdentifier(o.field)} ${o.direction.toUpperCase()}`;
|
|
324
|
+
}
|
|
296
325
|
validateSQLIdentifier(o.field, 'order by field');
|
|
297
326
|
return `${o.field} ${o.direction.toUpperCase()}`;
|
|
298
327
|
});
|
package/dist/field.d.ts
CHANGED
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { DimensionDefinition, DimensionOptions } from './types.js';
|
|
19
19
|
export declare const dimension: {
|
|
20
|
-
readonly string: (opts?:
|
|
21
|
-
readonly number: (opts?:
|
|
22
|
-
readonly boolean: (opts?:
|
|
23
|
-
readonly timestamp: (opts?:
|
|
20
|
+
readonly string: <TOptions extends DimensionOptions | undefined = undefined>(opts?: TOptions | undefined) => DimensionDefinition<"string"> & (TOptions extends DimensionOptions ? TOptions : object);
|
|
21
|
+
readonly number: <TOptions extends DimensionOptions | undefined = undefined>(opts?: TOptions | undefined) => DimensionDefinition<"number"> & (TOptions extends DimensionOptions ? TOptions : object);
|
|
22
|
+
readonly boolean: <TOptions extends DimensionOptions | undefined = undefined>(opts?: TOptions | undefined) => DimensionDefinition<"boolean"> & (TOptions extends DimensionOptions ? TOptions : object);
|
|
23
|
+
readonly timestamp: <TOptions extends DimensionOptions | undefined = undefined>(opts?: TOptions | undefined) => DimensionDefinition<"timestamp"> & (TOptions extends DimensionOptions ? TOptions : object);
|
|
24
24
|
};
|
|
25
25
|
//# sourceMappingURL=field.d.ts.map
|
package/dist/field.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAa,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../src/field.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAa,MAAM,YAAY,CAAC;AAiBnF,eAAO,MAAM,SAAS;sBAdZ,QAAQ,SAAS,gBAAgB,GAAG,SAAS;sBAA7C,QAAQ,SAAS,gBAAgB,GAAG,SAAS;uBAA7C,QAAQ,SAAS,gBAAgB,GAAG,SAAS;yBAA7C,QAAQ,SAAS,gBAAgB,GAAG,SAAS;CAmB7C,CAAC"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { SemanticBackend } from './semantic-plan.js';
|
|
2
2
|
export type InMemoryTable = Array<Record<string, unknown>>;
|
|
3
3
|
export type InMemoryTables = Record<string, InMemoryTable>;
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated The plan/backend execution path is frozen (bug fixes only); this
|
|
6
|
+
* backend remains as the test harness for that path. New code should use
|
|
7
|
+
* `createDatasetClient({ queryBuilder })`.
|
|
8
|
+
*/
|
|
4
9
|
export declare function createInMemoryBackend(tables: InMemoryTables): SemanticBackend;
|
|
5
10
|
//# sourceMappingURL=in-memory-backend.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-backend.d.ts","sourceRoot":"","sources":["../src/in-memory-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,eAAe,
|
|
1
|
+
{"version":3,"file":"in-memory-backend.d.ts","sourceRoot":"","sources":["../src/in-memory-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,eAAe,EAKhB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AA0U3D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,CAwE7E"}
|