@hypequery/datasets 0.17.1 → 0.19.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/agent-catalog.d.ts +9 -0
- package/dist/agent-catalog.d.ts.map +1 -1
- package/dist/aggregations.d.ts +2 -0
- package/dist/aggregations.d.ts.map +1 -1
- package/dist/aggregations.js +4 -0
- package/dist/api.type-test.js +40 -1
- package/dist/cache/query-signature.d.ts.map +1 -1
- package/dist/cache/query-signature.js +17 -0
- package/dist/catalog.d.ts +11 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +12 -2
- package/dist/cloud-publishing.d.ts +23 -0
- package/dist/cloud-publishing.d.ts.map +1 -0
- package/dist/cloud-publishing.js +57 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/contract.d.ts +5 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +7 -0
- package/dist/dataset-query.d.ts.map +1 -1
- package/dist/dataset-query.js +6 -1
- package/dist/dataset.d.ts +2 -2
- package/dist/dataset.d.ts.map +1 -1
- package/dist/dataset.js +3 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +15 -4
- package/dist/in-memory-backend.d.ts.map +1 -1
- package/dist/in-memory-backend.js +34 -7
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/measure.d.ts +5 -0
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +5 -0
- package/dist/portable-execution-errors.d.ts +4 -0
- package/dist/portable-execution-errors.d.ts.map +1 -1
- package/dist/portable-execution-errors.js +4 -1
- package/dist/portable-executor.d.ts.map +1 -1
- package/dist/portable-executor.js +6 -3
- package/dist/protocol-adapter.d.ts.map +1 -1
- package/dist/protocol-adapter.js +15 -7
- package/dist/protocol-rehydrate.d.ts +5 -1
- package/dist/protocol-rehydrate.d.ts.map +1 -1
- package/dist/protocol-rehydrate.js +20 -10
- package/dist/query-builder-protocol.d.ts +7 -3
- package/dist/query-builder-protocol.d.ts.map +1 -1
- package/dist/query-planner.d.ts.map +1 -1
- package/dist/query-planner.js +5 -0
- package/dist/relationship-check.d.ts +47 -0
- package/dist/relationship-check.d.ts.map +1 -0
- package/dist/relationship-check.js +59 -0
- package/dist/relationships.d.ts +10 -10
- package/dist/relationships.js +10 -10
- package/dist/semantic-planner.d.ts.map +1 -1
- package/dist/semantic-planner.js +5 -1
- package/dist/semantic-query-schema.d.ts.map +1 -1
- package/dist/semantic-query-schema.js +5 -0
- package/dist/sql-portability.d.ts.map +1 -1
- package/dist/sql-portability.js +88 -19
- package/dist/types.d.ts +39 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/agent-catalog-projection.d.ts +6 -0
- package/dist/utils/agent-catalog-projection.d.ts.map +1 -1
- package/dist/utils/agent-catalog-projection.js +4 -0
- package/dist/utils/approximate-measures.d.ts +10 -0
- package/dist/utils/approximate-measures.d.ts.map +1 -0
- package/dist/utils/approximate-measures.js +15 -0
- package/dist/utils/collect-cloud-datasets.d.ts +3 -0
- package/dist/utils/collect-cloud-datasets.d.ts.map +1 -0
- package/dist/utils/collect-cloud-datasets.js +12 -0
- package/dist/utils/dataset-contract.d.ts.map +1 -1
- package/dist/utils/dataset-contract.js +2 -2
- package/dist/utils/dataset-metric-ref.d.ts.map +1 -1
- package/dist/utils/dataset-metric-ref.js +5 -0
- package/dist/utils/dataset-query-validation.d.ts.map +1 -1
- package/dist/utils/dataset-query-validation.js +6 -3
- package/dist/utils/dataset-time-grains.d.ts +15 -0
- package/dist/utils/dataset-time-grains.d.ts.map +1 -0
- package/dist/utils/dataset-time-grains.js +17 -0
- package/dist/utils/filtered-aggregation-sql.d.ts.map +1 -1
- package/dist/utils/filtered-aggregation-sql.js +1 -0
- package/dist/utils/portable-aggregations.d.ts +14 -0
- package/dist/utils/portable-aggregations.d.ts.map +1 -0
- package/dist/utils/portable-aggregations.js +15 -0
- package/dist/utils/portable-grains.d.ts +22 -0
- package/dist/utils/portable-grains.d.ts.map +1 -0
- package/dist/utils/portable-grains.js +35 -0
- package/dist/utils/portable-semantic-query.d.ts.map +1 -1
- package/dist/utils/portable-semantic-query.js +2 -1
- package/dist/utils/protocol-metric-expressions.d.ts.map +1 -1
- package/dist/utils/protocol-metric-expressions.js +2 -1
- package/dist/utils/relationship-builder-plan.d.ts +6 -3
- package/dist/utils/relationship-builder-plan.d.ts.map +1 -1
- package/dist/utils/relationship-builder-plan.js +13 -5
- package/dist/utils/relationship-key-check.d.ts +43 -0
- package/dist/utils/relationship-key-check.d.ts.map +1 -0
- package/dist/utils/relationship-key-check.js +72 -0
- package/dist/utils/segments.d.ts +31 -0
- package/dist/utils/segments.d.ts.map +1 -0
- package/dist/utils/segments.js +91 -0
- package/dist/utils/semantic-metadata-validation.d.ts.map +1 -1
- package/dist/utils/semantic-metadata-validation.js +22 -1
- package/dist/utils/unsupported-contract-reasons.d.ts +32 -0
- package/dist/utils/unsupported-contract-reasons.d.ts.map +1 -0
- package/dist/utils/unsupported-contract-reasons.js +30 -0
- package/package.json +3 -3
package/dist/agent-catalog.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface AgentCatalogMeasure extends SemanticMetadata {
|
|
|
14
14
|
name: string;
|
|
15
15
|
label?: string;
|
|
16
16
|
description?: string;
|
|
17
|
+
/** Present, as `true`, when the value is an estimate; say so when reporting it. */
|
|
18
|
+
approximate?: true;
|
|
17
19
|
}
|
|
18
20
|
export interface AgentCatalogMetric extends SemanticMetadata {
|
|
19
21
|
name: string;
|
|
@@ -47,9 +49,16 @@ export interface AgentCatalogDataset extends SemanticMetadata {
|
|
|
47
49
|
measures: AgentCatalogMeasure[];
|
|
48
50
|
metrics: AgentCatalogMetric[];
|
|
49
51
|
filters: AgentCatalogFilter[];
|
|
52
|
+
/** Named segments an agent can select; their conditions are never shown. */
|
|
53
|
+
segments?: AgentCatalogSegment[];
|
|
50
54
|
relationships: AgentCatalogRelationship[];
|
|
51
55
|
limits: DatasetLimits;
|
|
52
56
|
}
|
|
57
|
+
export interface AgentCatalogSegment {
|
|
58
|
+
name: string;
|
|
59
|
+
label?: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
}
|
|
53
62
|
export interface AgentSafeCatalog {
|
|
54
63
|
datasets: AgentCatalogDataset[];
|
|
55
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-catalog.d.ts","sourceRoot":"","sources":["../src/agent-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,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,mBAAoB,SAAQ,gBAAgB;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-catalog.d.ts","sourceRoot":"","sources":["../src/agent-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,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,mBAAoB,SAAQ,gBAAgB;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,qBAAqB,EAAE,CAAC;IACpC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,aAAa,EAAE,wBAAwB,EAAE,CAAC;IAC1C,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,6BAA6B;IAC5C,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,+BAA+B,QAAa,CAAC;AAE1D,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAChD,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,cAAc,CAAC,CACtD,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B,2BAA2B,GAC3B,gBAAgB,GAChB,0BAA0B,CAAC;AAE/B;;;;GAIG;AACH,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAA;CAAE,CAAC;AAY5F,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,6BAAkC,GAC1C,gBAAgB,CA4BlB;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,6BAAkC,GAC1C,IAAI,CASN;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,kBAAkB,EAC1B,aAAa,EAAE,gCAAgC,GAC9C,mBAAmB,CAiBrB"}
|
package/dist/aggregations.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ import type { AggregationSpec } from './types.js';
|
|
|
18
18
|
export declare function sum(field: string): AggregationSpec;
|
|
19
19
|
export declare function count(field: string): AggregationSpec;
|
|
20
20
|
export declare function countDistinct(field: string): AggregationSpec;
|
|
21
|
+
/** Estimated distinct count (ClickHouse `uniq`). */
|
|
22
|
+
export declare function approxCountDistinct(field: string): AggregationSpec;
|
|
21
23
|
export declare function avg(field: string): AggregationSpec;
|
|
22
24
|
export declare function min(field: string): AggregationSpec;
|
|
23
25
|
export declare function max(field: string): AggregationSpec;
|
|
@@ -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;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"}
|
|
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,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElE;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
|
@@ -31,6 +31,10 @@ export function count(field) {
|
|
|
31
31
|
export function countDistinct(field) {
|
|
32
32
|
return createAggregation('countDistinct', field);
|
|
33
33
|
}
|
|
34
|
+
/** Estimated distinct count (ClickHouse `uniq`). */
|
|
35
|
+
export function approxCountDistinct(field) {
|
|
36
|
+
return createAggregation('approxCountDistinct', field);
|
|
37
|
+
}
|
|
34
38
|
export function avg(field) {
|
|
35
39
|
return createAggregation('avg', field);
|
|
36
40
|
}
|
package/dist/api.type-test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { add, between, buildCanonicalSemanticQuerySchemas, buildProtocolDeploymentContract, createDatasetClient, dataset, desc, dimension, eq, measure, publishDatasets, rehydrateProtocolDeploymentContract, } from './index.js';
|
|
1
|
+
import { add, between, buildCanonicalSemanticQuerySchemas, buildProtocolDeploymentContract, createDatasetClient, dataset, desc, dimension, eq, measure, publishDatasets, publishToCloud, rehydrateProtocolDeploymentContract, } from './index.js';
|
|
2
2
|
const Orders = dataset('orders', {
|
|
3
3
|
source: 'orders',
|
|
4
4
|
tenantKey: 'tenant_id',
|
|
@@ -21,6 +21,25 @@ const Orders = dataset('orders', {
|
|
|
21
21
|
}),
|
|
22
22
|
},
|
|
23
23
|
});
|
|
24
|
+
const _SegmentedOrders = dataset('segmentedOrders', {
|
|
25
|
+
source: 'orders',
|
|
26
|
+
dimensions: { status: dimension.string() },
|
|
27
|
+
measures: { revenue: measure.sum('amount') },
|
|
28
|
+
segments: { paid: { filters: [eq('status', 'paid')] } },
|
|
29
|
+
});
|
|
30
|
+
const validDatasetSegments = { segments: ['paid'] };
|
|
31
|
+
const validMetricSegments = { segments: ['paid'] };
|
|
32
|
+
void validDatasetSegments;
|
|
33
|
+
void validMetricSegments;
|
|
34
|
+
// @ts-expect-error only declared segment names are accepted.
|
|
35
|
+
const invalidDatasetSegments = { segments: ['paidd'] };
|
|
36
|
+
// @ts-expect-error only declared segment names are accepted on metric queries.
|
|
37
|
+
const invalidMetricSegments = { segments: ['paidd'] };
|
|
38
|
+
// @ts-expect-error a dataset without segments has no selectable segment names.
|
|
39
|
+
const invalidPlainSegments = { segments: ['paid'] };
|
|
40
|
+
void invalidDatasetSegments;
|
|
41
|
+
void invalidMetricSegments;
|
|
42
|
+
void invalidPlainSegments;
|
|
24
43
|
// @ts-expect-error standalone metrics may only target base measures.
|
|
25
44
|
Orders.metric('invalidDerivedMetric', { measure: 'doubledRevenue' });
|
|
26
45
|
dataset('derivedDependency', {
|
|
@@ -85,6 +104,10 @@ const _publishedDatasets = publishDatasets()
|
|
|
85
104
|
metrics: { customers: customerCountMetric },
|
|
86
105
|
})
|
|
87
106
|
.build();
|
|
107
|
+
const _cloudPublication = publishToCloud({
|
|
108
|
+
datasets: { Orders, Customers },
|
|
109
|
+
access: { roles: [], scopes: [] },
|
|
110
|
+
});
|
|
88
111
|
// @ts-expect-error published metrics must belong to the dataset being published.
|
|
89
112
|
publishDatasets().publish(Orders, { metrics: { customerCountMetric } });
|
|
90
113
|
const canonicalSchemas = buildCanonicalSemanticQuerySchemas({
|
|
@@ -182,3 +205,19 @@ void typedAccepted;
|
|
|
182
205
|
void typedClient;
|
|
183
206
|
void typedRuntime;
|
|
184
207
|
void rejectedFactory;
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
// Portable execution exclusions carry a named reason (HQ-45)
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
import { PortableExecutionUnsupportedError as PortableUnsupported, UNSUPPORTED_CONTRACT_REASONS as REASONS, UnsupportedContractFeatureError as ContractFeatureError, } from './index.js';
|
|
212
|
+
const namedReason = REASONS.ambiguousMeasureSql;
|
|
213
|
+
const literalReason = 'HQ_PORTABLE_DATASET_NOT_ACTIVATED';
|
|
214
|
+
// @ts-expect-error an unnamed reason is not an exclusion
|
|
215
|
+
const unnamedReason = 'HQ_PORTABLE_SOMETHING_ELSE';
|
|
216
|
+
const featureReason = new ContractFeatureError('orders', 'metric', 'detail', namedReason).reason;
|
|
217
|
+
// The three-argument constructor stays valid for existing callers.
|
|
218
|
+
const legacyFeatureError = new ContractFeatureError('orders', 'metric', 'detail');
|
|
219
|
+
const executionReason = new PortableUnsupported('message', { reason: literalReason }).reason;
|
|
220
|
+
void unnamedReason;
|
|
221
|
+
void featureReason;
|
|
222
|
+
void legacyFeatureError;
|
|
223
|
+
void executionReason;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-signature.d.ts","sourceRoot":"","sources":["../../src/cache/query-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"query-signature.d.ts","sourceRoot":"","sources":["../../src/cache/query-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,CAAC;AAsF3B,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAkBR;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAmBR"}
|
|
@@ -69,6 +69,21 @@ function tenantSignature(ds, query, context) {
|
|
|
69
69
|
}
|
|
70
70
|
return { key: ds.tenantKey, operator: predicate.operator, value: predicate.value };
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Selected segments keyed by their resolved definitions, not just their names,
|
|
74
|
+
* so editing a segment cannot serve rows cached under the old one. Absent when
|
|
75
|
+
* no segment is selected, which keeps existing signatures unchanged.
|
|
76
|
+
*/
|
|
77
|
+
function segmentSignature(ds, names) {
|
|
78
|
+
if (!names?.length)
|
|
79
|
+
return {};
|
|
80
|
+
return {
|
|
81
|
+
segments: [...new Set(names)].sort().map(name => ({
|
|
82
|
+
name,
|
|
83
|
+
filters: filterSignature(ds.segments?.[name]?.filters),
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
72
87
|
export function buildDatasetQuerySignature(ds, query, context) {
|
|
73
88
|
return stableStringify({
|
|
74
89
|
v: SIGNATURE_VERSION,
|
|
@@ -79,6 +94,7 @@ export function buildDatasetQuerySignature(ds, query, context) {
|
|
|
79
94
|
// `null` distinguishes the "all measures" default from an explicit [].
|
|
80
95
|
measures: query.measures ?? null,
|
|
81
96
|
filters: filterSignature(query.filters),
|
|
97
|
+
...segmentSignature(ds, query.segments),
|
|
82
98
|
orderBy: orderBySignature(query.orderBy),
|
|
83
99
|
by: query.by ?? null,
|
|
84
100
|
limit: query.limit ?? null,
|
|
@@ -98,6 +114,7 @@ export function buildMetricQuerySignature(metric, query, context) {
|
|
|
98
114
|
metricKind: ref.spec.__type,
|
|
99
115
|
dimensions: query.dimensions ?? null,
|
|
100
116
|
filters: filterSignature(query.filters),
|
|
117
|
+
...segmentSignature(ref.dataset, query.segments),
|
|
101
118
|
orderBy: orderBySignature(query.orderBy),
|
|
102
119
|
by: grain ?? null,
|
|
103
120
|
limit: query.limit ?? null,
|
package/dist/catalog.d.ts
CHANGED
|
@@ -19,10 +19,19 @@ export interface MeasureCatalogEntry extends SemanticMetadata {
|
|
|
19
19
|
label?: string;
|
|
20
20
|
description?: string;
|
|
21
21
|
filterCount: number;
|
|
22
|
+
/** Present, as `true`, when the measure returns an estimate. */
|
|
23
|
+
approximate?: true;
|
|
22
24
|
}
|
|
23
25
|
export interface DerivedMeasureCatalogEntry extends SemanticMetadata {
|
|
24
26
|
label?: string;
|
|
25
27
|
description?: string;
|
|
28
|
+
/** Present, as `true`, when any measure the formula uses is approximate. */
|
|
29
|
+
approximate?: true;
|
|
30
|
+
}
|
|
31
|
+
/** A named segment. Its filters stay in the definition and are never catalogued. */
|
|
32
|
+
export interface SegmentCatalogEntry {
|
|
33
|
+
label?: string;
|
|
34
|
+
description?: string;
|
|
26
35
|
}
|
|
27
36
|
export interface FilterCatalogEntry extends SemanticMetadata {
|
|
28
37
|
field: string;
|
|
@@ -72,6 +81,8 @@ export interface DatasetCatalog extends SemanticMetadata {
|
|
|
72
81
|
derivedMeasures?: Record<string, DerivedMeasureCatalogEntry>;
|
|
73
82
|
metrics: Record<string, MetricCatalogEntry>;
|
|
74
83
|
filters: Record<string, FilterCatalogEntry>;
|
|
84
|
+
/** Named segments; absent when the dataset declares none. */
|
|
85
|
+
segments?: Record<string, SegmentCatalogEntry>;
|
|
75
86
|
relationships: Record<string, RelationshipCatalogEntry>;
|
|
76
87
|
limits?: DatasetLimits;
|
|
77
88
|
requiresTenant: boolean;
|
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,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,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,6 @@
|
|
|
1
|
-
import { SEMANTIC_FILTER_OPERATORS
|
|
1
|
+
import { SEMANTIC_FILTER_OPERATORS } from './constants.js';
|
|
2
|
+
import { datasetTimeGrains } from './utils/dataset-time-grains.js';
|
|
3
|
+
import { isApproximateAggregation, isApproximateDerivedMeasure } from './utils/approximate-measures.js';
|
|
2
4
|
import { listGroupableRelationshipFields, listQueryableRelationshipFields, } from './utils/relationship-fields.js';
|
|
3
5
|
import { snapshotSemanticMetadata } from './utils/semantic-metadata.js';
|
|
4
6
|
function dimensionToCatalog(dimension) {
|
|
@@ -24,6 +26,7 @@ function measureToCatalog(measure) {
|
|
|
24
26
|
description: measure.description,
|
|
25
27
|
...snapshotSemanticMetadata(measure),
|
|
26
28
|
filterCount: measure.filters?.length ?? 0,
|
|
29
|
+
...(isApproximateAggregation(measure.aggregation) ? { approximate: true } : {}),
|
|
27
30
|
};
|
|
28
31
|
}
|
|
29
32
|
function filterToCatalog(filter, dimensions) {
|
|
@@ -81,7 +84,7 @@ export function getDatasetCatalog(dataset) {
|
|
|
81
84
|
const measureNames = Object.keys(dataset.measures);
|
|
82
85
|
const derivedMeasureNames = Object.keys(dataset.derivedMeasures ?? {});
|
|
83
86
|
const metricNames = Object.keys(dataset.metrics ?? {});
|
|
84
|
-
const supportedGrains =
|
|
87
|
+
const supportedGrains = [...datasetTimeGrains(dataset)];
|
|
85
88
|
const maxLimit = dataset.limits?.maxResultSize;
|
|
86
89
|
const relationships = Object.fromEntries(Object.entries(dataset.relationships).map(([name, relationship]) => [
|
|
87
90
|
name,
|
|
@@ -112,6 +115,7 @@ export function getDatasetCatalog(dataset) {
|
|
|
112
115
|
...snapshotSemanticMetadata(definition),
|
|
113
116
|
label: definition.label,
|
|
114
117
|
description: definition.description,
|
|
118
|
+
...(isApproximateDerivedMeasure(dataset.measures, definition) ? { approximate: true } : {}),
|
|
115
119
|
},
|
|
116
120
|
])),
|
|
117
121
|
} : {}),
|
|
@@ -119,6 +123,12 @@ export function getDatasetCatalog(dataset) {
|
|
|
119
123
|
name,
|
|
120
124
|
metricToCatalog(metric),
|
|
121
125
|
])),
|
|
126
|
+
...(Object.keys(dataset.segments ?? {}).length > 0 ? {
|
|
127
|
+
segments: Object.fromEntries(Object.entries(dataset.segments).map(([name, segment]) => [name, {
|
|
128
|
+
...(segment.label !== undefined ? { label: segment.label } : {}),
|
|
129
|
+
...(segment.description !== undefined ? { description: segment.description } : {}),
|
|
130
|
+
}])),
|
|
131
|
+
} : {}),
|
|
122
132
|
filters: Object.fromEntries(Object.entries(dataset.filters).map(([name, filter]) => [
|
|
123
133
|
name,
|
|
124
134
|
filterToCatalog(filter, dataset.dimensions),
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ProtocolDeploymentContract } from '@hypequery/protocol';
|
|
2
|
+
import type { AnyDatasetInstance } from './types.js';
|
|
3
|
+
export interface CloudPublishingOptions {
|
|
4
|
+
/** Datasets exposed to Cloud. Relationships are included as supporting datasets. */
|
|
5
|
+
readonly datasets: Readonly<Record<string, AnyDatasetInstance>>;
|
|
6
|
+
/** Explicit policy for every published dataset unless overridden below. */
|
|
7
|
+
readonly access: {
|
|
8
|
+
readonly roles: readonly string[];
|
|
9
|
+
readonly scopes: readonly string[];
|
|
10
|
+
};
|
|
11
|
+
/** Optional stricter or different policy by published dataset name. */
|
|
12
|
+
readonly datasetAccess?: Readonly<Record<string, {
|
|
13
|
+
readonly roles: readonly string[];
|
|
14
|
+
readonly scopes: readonly string[];
|
|
15
|
+
}>>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Declare the dataset-only contract uploaded by `hypequery deploy`.
|
|
19
|
+
* This function performs no network request and requires no Serve API.
|
|
20
|
+
* Export its result as `cloud` from the deployment entrypoint.
|
|
21
|
+
*/
|
|
22
|
+
export declare function publishToCloud(options: CloudPublishingOptions): ProtocolDeploymentContract;
|
|
23
|
+
//# sourceMappingURL=cloud-publishing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-publishing.d.ts","sourceRoot":"","sources":["../src/cloud-publishing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,0BAA0B,EAA+B,MAAM,qBAAqB,CAAC;AAEnG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,MAAM,WAAW,sBAAsB;IACrC,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAChE,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;KACpC,CAAC;IACF,uEAAuE;IACvE,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;KACpC,CAAC,CAAC,CAAC;CACL;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,sBAAsB,GAAG,0BAA0B,CAyD1F"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { buildProtocolDeploymentContract } from './protocol-deployment-adapter.js';
|
|
2
|
+
import { collectCloudDatasets } from './utils/collect-cloud-datasets.js';
|
|
3
|
+
/**
|
|
4
|
+
* Declare the dataset-only contract uploaded by `hypequery deploy`.
|
|
5
|
+
* This function performs no network request and requires no Serve API.
|
|
6
|
+
* Export its result as `cloud` from the deployment entrypoint.
|
|
7
|
+
*/
|
|
8
|
+
export function publishToCloud(options) {
|
|
9
|
+
const entries = Object.entries(options.datasets);
|
|
10
|
+
if (entries.length === 0)
|
|
11
|
+
throw new Error('Cloud publishing requires at least one dataset.');
|
|
12
|
+
if (!options.access || !Array.isArray(options.access.roles)
|
|
13
|
+
|| !Array.isArray(options.access.scopes)) {
|
|
14
|
+
throw new Error('Cloud publishing requires an explicit authenticated access policy.');
|
|
15
|
+
}
|
|
16
|
+
const datasets = new Map();
|
|
17
|
+
const exposed = new Set();
|
|
18
|
+
for (const [, dataset] of entries) {
|
|
19
|
+
collectCloudDatasets(datasets, dataset);
|
|
20
|
+
exposed.add(dataset.name);
|
|
21
|
+
}
|
|
22
|
+
for (const dataset of datasets.values()) {
|
|
23
|
+
const namedMetrics = dataset.metrics;
|
|
24
|
+
if (namedMetrics && Object.keys(namedMetrics).length > 0) {
|
|
25
|
+
throw new Error(`Cloud dataset "${dataset.name}" contains named metrics. `
|
|
26
|
+
+ 'The dataset-only Cloud publisher does not support named metrics yet.');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const name of Object.keys(options.datasetAccess ?? {})) {
|
|
30
|
+
if (!exposed.has(name)) {
|
|
31
|
+
throw new Error(`Cloud access policy names an unpublished dataset: "${name}".`);
|
|
32
|
+
}
|
|
33
|
+
const access = options.datasetAccess?.[name];
|
|
34
|
+
if (!access || !Array.isArray(access.roles) || !Array.isArray(access.scopes)) {
|
|
35
|
+
throw new Error(`Cloud access policy for "${name}" must set roles and scopes.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const endpoints = {};
|
|
39
|
+
for (const dataset of datasets.values()) {
|
|
40
|
+
if (!exposed.has(dataset.name))
|
|
41
|
+
continue;
|
|
42
|
+
const access = options.datasetAccess?.[dataset.name] ?? options.access;
|
|
43
|
+
endpoints[dataset.name] = {
|
|
44
|
+
access: {
|
|
45
|
+
kind: 'authenticated',
|
|
46
|
+
roles: [...new Set(access.roles)].sort(),
|
|
47
|
+
scopes: [...new Set(access.scopes)].sort(),
|
|
48
|
+
},
|
|
49
|
+
tenant: dataset.tenantKey
|
|
50
|
+
? { kind: 'required', mode: 'auto-inject', column: dataset.tenantKey }
|
|
51
|
+
: { kind: 'not-required' },
|
|
52
|
+
maxLimit: dataset.limits?.maxResultSize ?? 1_000,
|
|
53
|
+
path: `/api/analytics/datasets/${dataset.name}/query`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return buildProtocolDeploymentContract([...datasets.values()].sort((left, right) => left.name.localeCompare(right.name)), { endpoints });
|
|
57
|
+
}
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAQrD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAmC,SAAS,EAAE,CAAC;AAEjF;;GAEG;AACH,eAAO,MAAM,yBAAyB,oFAWkB,CAAC;AAEzD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAEvE"}
|
package/dist/constants.js
CHANGED
package/dist/contract.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DatasetCatalogSource, type DimensionCatalogEntry, type MeasureCatalogEntry, type MetricCatalogEntry, type FilterCatalogEntry, type RelationshipCatalogEntry } from './catalog.js';
|
|
1
|
+
import { type DatasetCatalogSource, type DimensionCatalogEntry, type MeasureCatalogEntry, type SegmentCatalogEntry, type MetricCatalogEntry, type FilterCatalogEntry, type RelationshipCatalogEntry } from './catalog.js';
|
|
2
2
|
import type { DatasetDefaults, DatasetFreshness, DatasetLimits, SemanticMetadata } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Version of the semantic contract format. Bump when the serialized shape
|
|
@@ -24,6 +24,8 @@ export interface ContractMeasure extends SemanticMetadata {
|
|
|
24
24
|
sql?: string;
|
|
25
25
|
label?: string;
|
|
26
26
|
description?: string;
|
|
27
|
+
/** Present, as `true`, when the measure returns an estimate. */
|
|
28
|
+
approximate?: true;
|
|
27
29
|
}
|
|
28
30
|
export interface ContractMetric extends SemanticMetadata {
|
|
29
31
|
kind: MetricCatalogEntry['kind'];
|
|
@@ -67,6 +69,8 @@ export interface ContractDataset extends SemanticMetadata {
|
|
|
67
69
|
measures: Record<string, ContractMeasure>;
|
|
68
70
|
metrics: Record<string, ContractMetric>;
|
|
69
71
|
filters: Record<string, ContractFilter>;
|
|
72
|
+
/** Named segments (label and description only); absent when none are declared. */
|
|
73
|
+
segments?: Record<string, SegmentCatalogEntry>;
|
|
70
74
|
relationships: Record<string, ContractRelationship>;
|
|
71
75
|
limits?: DatasetLimits;
|
|
72
76
|
}
|
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,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,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,eAAgB,SAAQ,gBAAgB;IACvD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,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
|
@@ -57,6 +57,12 @@ function datasetToContract(catalog, includeSql) {
|
|
|
57
57
|
measures: sortedRecord(Object.entries(catalog.measures).map(([name, entry]) => [name, measureToContract(entry, includeSql)])),
|
|
58
58
|
metrics: sortedRecord(Object.entries(catalog.metrics).map(([name, entry]) => [name, metricToContract(entry)])),
|
|
59
59
|
filters: sortedRecord(Object.entries(catalog.filters).map(([name, entry]) => [name, filterToContract(entry)])),
|
|
60
|
+
...(catalog.segments !== undefined ? {
|
|
61
|
+
segments: sortedRecord(Object.entries(catalog.segments).map(([name, entry]) => [name, {
|
|
62
|
+
...(entry.label !== undefined ? { label: entry.label } : {}),
|
|
63
|
+
...(entry.description !== undefined ? { description: entry.description } : {}),
|
|
64
|
+
}])),
|
|
65
|
+
} : {}),
|
|
60
66
|
relationships: sortedRecord(Object.entries(catalog.relationships).map(([name, entry]) => [name, relationshipToContract(entry)])),
|
|
61
67
|
...(catalog.limits !== undefined ? { limits: limitsToContract(catalog.limits) } : {}),
|
|
62
68
|
};
|
|
@@ -96,6 +102,7 @@ function measureToContract(entry, includeSql) {
|
|
|
96
102
|
...(entry.label !== undefined ? { label: entry.label } : {}),
|
|
97
103
|
...(entry.description !== undefined ? { description: entry.description } : {}),
|
|
98
104
|
...snapshotSemanticMetadata(entry),
|
|
105
|
+
...(entry.approximate ? { approximate: true } : {}),
|
|
99
106
|
};
|
|
100
107
|
}
|
|
101
108
|
function metricToContract(entry) {
|
|
@@ -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;
|
|
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;AAS7F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAgBxD,MAAM,WAAW,4BAA4B;IAC3C,cAAc,EAAE,uBAAuB,CAAC;IACxC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;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,CAoDlB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAmB7B"}
|
package/dist/dataset-query.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { appendOrderLimitOffset, applyMeasureDefinition, buildDimensionSelectionPlan, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
1
|
+
import { appendOrderLimitOffset, applyMeasureDefinition, buildDimensionSelectionPlan, resolveDimensionExpression, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
2
2
|
import { validateDatasetQueryInput } from './utils/dataset-query-validation.js';
|
|
3
3
|
import { getRuntimeTenantPredicate } from './utils/tenant-runtime.js';
|
|
4
4
|
import { overfetchLimit } from './utils/pagination.js';
|
|
5
5
|
import { applyRelationshipJoins, buildRelationshipBuilderContext, qualifyBaseColumn, } from './utils/relationship-builder-plan.js';
|
|
6
6
|
import { hasSelectedDerivedMeasure, runDerivedDatasetQuery, } from './utils/dataset-derived-query.js';
|
|
7
7
|
import { toDatasetQueryResult } from './utils/dataset-query-result.js';
|
|
8
|
+
import { segmentFilters } from './utils/segments.js';
|
|
8
9
|
export function validateDatasetQuery(ds, query, context) {
|
|
9
10
|
return validateDatasetQueryInput(ds, query, context);
|
|
10
11
|
}
|
|
@@ -39,6 +40,10 @@ export function buildDatasetQueryBuilder(ds, query, options) {
|
|
|
39
40
|
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
40
41
|
qb = qb.where(resolvedField, filter.operator, filter.value);
|
|
41
42
|
}
|
|
43
|
+
// Segments are author-defined, so they bypass the caller filter allow-list.
|
|
44
|
+
for (const filter of segmentFilters(ds, query.segments)) {
|
|
45
|
+
qb = qb.where(resolveDimensionExpression(ds, filter.field, joinCtx), filter.operator, filter.value);
|
|
46
|
+
}
|
|
42
47
|
return appendOrderLimitOffset(qb, query.orderBy, options.skipDefaultOrderBy ? undefined : query.by, options.executionLimit ?? query.limit, query.offset, joinCtx);
|
|
43
48
|
}
|
|
44
49
|
export async function runDatasetQuery(ds, query, options) {
|
package/dist/dataset.d.ts
CHANGED
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
* });
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
import type { DatasetConfig, DatasetInstance, DatasetMeasureDefinition, BaseMeasures, DerivedMeasures, DimensionDefinition, RelationshipDefinition } from './types.js';
|
|
33
|
-
export declare function dataset<TDatasetName extends string, TDimensions extends Record<string, DimensionDefinition>, TDefinitions extends Record<string, DatasetMeasureDefinition> = {}, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never
|
|
32
|
+
import type { DatasetConfig, DatasetInstance, DatasetMeasureDefinition, BaseMeasures, DerivedMeasures, DimensionDefinition, RelationshipDefinition, SegmentDefinition } from './types.js';
|
|
33
|
+
export declare function dataset<TDatasetName extends string, TDimensions extends Record<string, DimensionDefinition>, TDefinitions extends Record<string, DatasetMeasureDefinition> = {}, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never>, const TSegments extends Record<string, SegmentDefinition> = {}>(name: TDatasetName, config: DatasetConfig<TDimensions, TDefinitions, TRelationships, TSegments>): DatasetInstance<TDimensions, BaseMeasures<TDefinitions>, TRelationships, TDatasetName, DerivedMeasures<TDefinitions>, TSegments>;
|
|
34
34
|
//# sourceMappingURL=dataset.d.ts.map
|
package/dist/dataset.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../src/dataset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../src/dataset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EAKtB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAsBpB,wBAAgB,OAAO,CACrB,YAAY,SAAS,MAAM,EAC3B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACvD,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAAG,EAAE,EAClE,cAAc,SAAS,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACrF,KAAK,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,EAAE,EAE9D,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,aAAa,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,CAAC,GAC1E,eAAe,CAAC,WAAW,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,CA+ElI"}
|
package/dist/dataset.js
CHANGED
|
@@ -36,6 +36,7 @@ import { validateDatasetDefinition } from './utils/dataset-definition-validation
|
|
|
36
36
|
import { snapshotSemanticMetadata } from './utils/semantic-metadata.js';
|
|
37
37
|
import { validateSemanticMetadata } from './utils/semantic-metadata-validation.js';
|
|
38
38
|
import { splitDatasetMeasures } from './utils/dataset-measures.js';
|
|
39
|
+
import { normalizeSegments } from './utils/segments.js';
|
|
39
40
|
export function dataset(name, config) {
|
|
40
41
|
// Structural validation runs before anything is normalized, so an invalid
|
|
41
42
|
// model fails at definition time rather than on the first query that reaches
|
|
@@ -75,6 +76,7 @@ export function dataset(name, config) {
|
|
|
75
76
|
},
|
|
76
77
|
tenantKey: config.tenantKey,
|
|
77
78
|
timeKey: config.timeKey,
|
|
79
|
+
...(config.timeGrains === undefined ? {} : { timeGrains: Object.freeze([...config.timeGrains]) }),
|
|
78
80
|
dimensions,
|
|
79
81
|
measures,
|
|
80
82
|
derivedMeasures,
|
|
@@ -82,6 +84,7 @@ export function dataset(name, config) {
|
|
|
82
84
|
relationships,
|
|
83
85
|
limits: config.limits,
|
|
84
86
|
cache: config.cache,
|
|
87
|
+
segments: normalizeSegments(name, { tenantKey: config.tenantKey, dimensions }, config.segments),
|
|
85
88
|
metric,
|
|
86
89
|
};
|
|
87
90
|
return ds;
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AACA;;;;;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;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { protocolMetricCapabilityErrors } from './utils/protocol-metric-capabilities.js';
|
|
2
2
|
import { toQueryBuilderFactory } from './query-builder-protocol.js';
|
|
3
3
|
import { quoteSQLIdentifier, validateSQLIdentifier } from './sql-utils.js';
|
|
4
|
-
import {
|
|
4
|
+
import { unsupportedTimeGrainError } from './utils/dataset-time-grains.js';
|
|
5
5
|
import { validateFilterValue } from './validation.js';
|
|
6
|
-
import { applyAggregationSpec, appendOrderLimitOffset, buildDimensionSelectionPlan, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
6
|
+
import { applyAggregationSpec, appendOrderLimitOffset, buildDimensionSelectionPlan, resolveDimensionExpression, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
7
7
|
import { assertMetricHandle, getMetricGrain, getMetricRef, isTenantScopedFilter, } from './utils/metric-handle.js';
|
|
8
8
|
import { validateDerivedCteGrouping } from './utils/derived-cte-validation.js';
|
|
9
9
|
import { buildDatasetQueryBuilder, runDatasetQuery, validateDatasetQuery, } from './dataset-query.js';
|
|
@@ -19,6 +19,7 @@ import { resolveDatasetCacheRuntime, } from './utils/dataset-cache-policy.js';
|
|
|
19
19
|
import { isQualifiedField, resolveQualifiedField } from './utils/relationship-fields.js';
|
|
20
20
|
import { validateQualifiedFilter, validateRelationshipTenantRuntime, } from './utils/relationship-validation.js';
|
|
21
21
|
import { applyRelationshipJoins, buildRelationshipBuilderContext, qualifyBaseColumn, } from './utils/relationship-builder-plan.js';
|
|
22
|
+
import { segmentFilters, segmentSelectionErrors } from './utils/segments.js';
|
|
22
23
|
function validateQuery(metric, query, context) {
|
|
23
24
|
const errors = protocolMetricCapabilityErrors(metric, query);
|
|
24
25
|
const ref = getMetricRef(metric);
|
|
@@ -97,8 +98,10 @@ function validateQuery(metric, query, context) {
|
|
|
97
98
|
errors.push(`Cannot use "by" grain — dataset "${ds.name}" has no timeKey.`);
|
|
98
99
|
}
|
|
99
100
|
// Validate grain is one the planner can bucket on
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
errors.push(...segmentSelectionErrors(ds, query.segments));
|
|
102
|
+
const grainError = query.by && ds.timeKey ? unsupportedTimeGrainError(ds, query.by) : undefined;
|
|
103
|
+
if (grainError) {
|
|
104
|
+
errors.push(grainError);
|
|
102
105
|
}
|
|
103
106
|
if (query.limit != null && (!Number.isInteger(query.limit) || query.limit < 0)) {
|
|
104
107
|
errors.push(`Invalid limit: expected a non-negative integer.`);
|
|
@@ -273,6 +276,11 @@ export class MetricQueryEngine {
|
|
|
273
276
|
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
274
277
|
qb = qb.where(resolvedField, filter.operator, filter.value);
|
|
275
278
|
}
|
|
279
|
+
// Segments: author-defined, so they resolve dimensions directly rather
|
|
280
|
+
// than through the caller-facing filter allow-list.
|
|
281
|
+
for (const filter of segmentFilters(ds, query.segments)) {
|
|
282
|
+
qb = qb.where(resolveDimensionExpression(ds, filter.field, joinCtx), filter.operator, filter.value);
|
|
283
|
+
}
|
|
276
284
|
// Order, limit, offset
|
|
277
285
|
qb = appendOrderLimitOffset(qb, query.orderBy, grain, query.limit, query.offset, joinCtx);
|
|
278
286
|
return qb;
|
|
@@ -316,6 +324,9 @@ export class MetricQueryEngine {
|
|
|
316
324
|
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
317
325
|
cteBuilder = cteBuilder.where(resolvedField, filter.operator, filter.value);
|
|
318
326
|
}
|
|
327
|
+
for (const filter of segmentFilters(ds, query.segments)) {
|
|
328
|
+
cteBuilder = cteBuilder.where(resolveDimensionExpression(ds, filter.field, joinCtx), filter.operator, filter.value);
|
|
329
|
+
}
|
|
319
330
|
const { sql: cteSql, parameters: cteParams } = cteBuilder.toSQLWithParams();
|
|
320
331
|
const groupingErrors = validateDerivedCteGrouping(cteSql, aggregateAliases, groupByParts);
|
|
321
332
|
if (groupingErrors.length > 0) {
|
|
@@ -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,EAKhB,MAAM,oBAAoB,CAAC;AAG5B,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;
|
|
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;AAG5B,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;AAuV3D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,CAwE7E"}
|