@hypequery/clickhouse 1.6.0 → 1.6.2
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/README.md +19 -14
- package/dist/cli/generate-types.js +3 -88
- package/dist/cli/type-parsing.js +124 -0
- package/dist/core/adapters/clickhouse-adapter.d.ts +14 -0
- package/dist/core/adapters/clickhouse-adapter.d.ts.map +1 -0
- package/dist/core/adapters/clickhouse-adapter.js +58 -0
- package/dist/core/adapters/database-adapter.d.ts +13 -0
- package/dist/core/adapters/database-adapter.d.ts.map +1 -0
- package/dist/core/adapters/database-adapter.js +1 -0
- package/dist/core/cache/cache-manager.d.ts.map +1 -1
- package/dist/core/cache/cache-manager.js +6 -5
- package/dist/core/dialects/clickhouse-dialect.d.ts +10 -0
- package/dist/core/dialects/clickhouse-dialect.d.ts.map +1 -0
- package/dist/core/dialects/clickhouse-dialect.js +47 -0
- package/dist/core/dialects/sql-dialect.d.ts +11 -0
- package/dist/core/dialects/sql-dialect.d.ts.map +1 -0
- package/dist/core/dialects/sql-dialect.js +1 -0
- package/dist/core/features/aggregations.d.ts +5 -5
- package/dist/core/features/analytics.d.ts +804 -5
- package/dist/core/features/analytics.d.ts.map +1 -1
- package/dist/core/features/analytics.js +6 -9
- package/dist/core/features/executor.d.ts.map +1 -1
- package/dist/core/features/executor.js +26 -53
- package/dist/core/features/filtering.d.ts +5 -5
- package/dist/core/features/joins.d.ts +1 -1
- package/dist/core/features/query-modifiers.d.ts +6 -6
- package/dist/core/query-builder.d.ts +17 -6
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +25 -32
- package/dist/core/tests/integration/setup.d.ts +3 -1
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/test-utils.d.ts.map +1 -1
- package/dist/core/tests/test-utils.js +12 -2
- package/dist/core/types/select-types.d.ts +1 -1
- package/dist/core/types/select-types.d.ts.map +1 -1
- package/dist/core/utils/streaming-helpers.d.ts.map +1 -1
- package/dist/core/utils/streaming-helpers.js +8 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +3 -0
- package/dist/dataset/definition.d.ts +135 -0
- package/dist/dataset/definition.d.ts.map +1 -0
- package/dist/dataset/definition.js +265 -0
- package/dist/dataset/helpers.d.ts +136 -0
- package/dist/dataset/helpers.d.ts.map +1 -0
- package/dist/dataset/helpers.js +189 -0
- package/dist/dataset/index.d.ts +51 -0
- package/dist/dataset/index.d.ts.map +1 -0
- package/dist/dataset/index.js +59 -0
- package/dist/dataset/introspection.d.ts +133 -0
- package/dist/dataset/introspection.d.ts.map +1 -0
- package/dist/dataset/introspection.js +239 -0
- package/dist/dataset/sql-tag.d.ts +51 -0
- package/dist/dataset/sql-tag.d.ts.map +1 -0
- package/dist/dataset/sql-tag.js +86 -0
- package/dist/dataset/types.d.ts +300 -0
- package/dist/dataset/types.d.ts.map +1 -0
- package/dist/dataset/types.js +11 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -15
- package/dist/migrations/config/index.d.ts +3 -0
- package/dist/migrations/config/index.d.ts.map +1 -0
- package/dist/migrations/config/index.js +1 -0
- package/dist/migrations/config/types.d.ts +45 -0
- package/dist/migrations/config/types.d.ts.map +1 -0
- package/dist/migrations/config/types.js +28 -0
- package/dist/migrations/diff/diff.d.ts +11 -0
- package/dist/migrations/diff/diff.d.ts.map +1 -0
- package/dist/migrations/diff/diff.js +240 -0
- package/dist/migrations/diff/index.d.ts +3 -0
- package/dist/migrations/diff/index.d.ts.map +1 -0
- package/dist/migrations/diff/index.js +1 -0
- package/dist/migrations/diff/types.d.ts +74 -0
- package/dist/migrations/diff/types.d.ts.map +1 -0
- package/dist/migrations/diff/types.js +1 -0
- package/dist/migrations/plan/index.d.ts +3 -0
- package/dist/migrations/plan/index.d.ts.map +1 -0
- package/dist/migrations/plan/index.js +1 -0
- package/dist/migrations/plan/plan.d.ts +12 -0
- package/dist/migrations/plan/plan.d.ts.map +1 -0
- package/dist/migrations/plan/plan.js +416 -0
- package/dist/migrations/plan/types.d.ts +93 -0
- package/dist/migrations/plan/types.d.ts.map +1 -0
- package/dist/migrations/plan/types.js +1 -0
- package/dist/migrations/schema/column.d.ts +71 -0
- package/dist/migrations/schema/column.d.ts.map +1 -0
- package/dist/migrations/schema/column.js +123 -0
- package/dist/migrations/schema/define.d.ts +24 -0
- package/dist/migrations/schema/define.d.ts.map +1 -0
- package/dist/migrations/schema/define.js +47 -0
- package/dist/migrations/schema/index.d.ts +4 -0
- package/dist/migrations/schema/index.d.ts.map +1 -0
- package/dist/migrations/schema/index.js +2 -0
- package/dist/migrations/schema/types.d.ts +74 -0
- package/dist/migrations/schema/types.d.ts.map +1 -0
- package/dist/migrations/schema/types.js +1 -0
- package/dist/migrations/snapshot/index.d.ts +3 -0
- package/dist/migrations/snapshot/index.d.ts.map +1 -0
- package/dist/migrations/snapshot/index.js +1 -0
- package/dist/migrations/snapshot/serialize.d.ts +21 -0
- package/dist/migrations/snapshot/serialize.d.ts.map +1 -0
- package/dist/migrations/snapshot/serialize.js +127 -0
- package/dist/migrations/snapshot/types.d.ts +47 -0
- package/dist/migrations/snapshot/types.d.ts.map +1 -0
- package/dist/migrations/snapshot/types.js +1 -0
- package/dist/migrations/sql/index.d.ts +4 -0
- package/dist/migrations/sql/index.d.ts.map +1 -0
- package/dist/migrations/sql/index.js +2 -0
- package/dist/migrations/sql/render.d.ts +10 -0
- package/dist/migrations/sql/render.d.ts.map +1 -0
- package/dist/migrations/sql/render.js +347 -0
- package/dist/migrations/sql/types.d.ts +53 -0
- package/dist/migrations/sql/types.d.ts.map +1 -0
- package/dist/migrations/sql/types.js +1 -0
- package/dist/migrations/sql/write.d.ts +10 -0
- package/dist/migrations/sql/write.d.ts.map +1 -0
- package/dist/migrations/sql/write.js +35 -0
- package/dist/types/base.d.ts +2 -1
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/clickhouse-types.d.ts +7 -2
- package/dist/types/clickhouse-types.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/type-helpers.d.ts +7 -0
- package/dist/types/type-helpers.d.ts.map +1 -0
- package/dist/types/type-helpers.js +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataset Helper Functions
|
|
3
|
+
*
|
|
4
|
+
* Provides declarative helper functions for defining dimensions and metrics:
|
|
5
|
+
* - dimension.string(), dimension.number(), dimension.date(), dimension.boolean()
|
|
6
|
+
* - metric.count(), metric.sum(), metric.avg(), metric.min(), metric.max(), metric.countDistinct(), metric.custom()
|
|
7
|
+
*/
|
|
8
|
+
import { sql } from './sql-tag.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create a dimension definition helper
|
|
11
|
+
*/
|
|
12
|
+
function createDimensionHelper(type) {
|
|
13
|
+
return (columnOrExpression, options) => {
|
|
14
|
+
return {
|
|
15
|
+
sql: columnOrExpression,
|
|
16
|
+
type,
|
|
17
|
+
description: options.description,
|
|
18
|
+
examples: options.examples,
|
|
19
|
+
join: options.join,
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Dimension helper namespace
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* dimensions: {
|
|
29
|
+
* region: dimension.string('region', {
|
|
30
|
+
* description: 'Geographic region',
|
|
31
|
+
* examples: ['US', 'EU', 'APAC']
|
|
32
|
+
* }),
|
|
33
|
+
* orderDate: dimension.date(sql`DATE(created_at)`, {
|
|
34
|
+
* description: 'Order date'
|
|
35
|
+
* }),
|
|
36
|
+
* amount: dimension.number('amount', {
|
|
37
|
+
* description: 'Order amount'
|
|
38
|
+
* })
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export const dimension = {
|
|
43
|
+
/**
|
|
44
|
+
* Create a string dimension
|
|
45
|
+
*/
|
|
46
|
+
string: createDimensionHelper('string'),
|
|
47
|
+
/**
|
|
48
|
+
* Create a number dimension
|
|
49
|
+
*/
|
|
50
|
+
number: createDimensionHelper('number'),
|
|
51
|
+
/**
|
|
52
|
+
* Create a date dimension
|
|
53
|
+
*/
|
|
54
|
+
date: createDimensionHelper('date'),
|
|
55
|
+
/**
|
|
56
|
+
* Create a boolean dimension
|
|
57
|
+
*/
|
|
58
|
+
boolean: createDimensionHelper('boolean'),
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Create a metric definition helper
|
|
62
|
+
*/
|
|
63
|
+
function createMetricHelper(type) {
|
|
64
|
+
return (columnOrExpression, options) => {
|
|
65
|
+
return {
|
|
66
|
+
type,
|
|
67
|
+
sql: columnOrExpression,
|
|
68
|
+
description: options.description,
|
|
69
|
+
format: options.format,
|
|
70
|
+
join: options.join,
|
|
71
|
+
allowFanout: options.allowFanout,
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Metric helper namespace
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* metrics: {
|
|
81
|
+
* revenue: metric.sum('amount', {
|
|
82
|
+
* description: 'Total revenue',
|
|
83
|
+
* format: 'currency'
|
|
84
|
+
* }),
|
|
85
|
+
* orderCount: metric.count({
|
|
86
|
+
* description: 'Total number of orders'
|
|
87
|
+
* }),
|
|
88
|
+
* avgOrderValue: metric.avg('total_amount', {
|
|
89
|
+
* description: 'Average order value',
|
|
90
|
+
* format: 'currency'
|
|
91
|
+
* }),
|
|
92
|
+
* revenuePerCustomer: metric.custom(
|
|
93
|
+
* sql`sum(total_amount) / count(DISTINCT customer_id)`,
|
|
94
|
+
* {
|
|
95
|
+
* description: 'Average revenue per customer',
|
|
96
|
+
* format: 'currency'
|
|
97
|
+
* }
|
|
98
|
+
* )
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export const metric = {
|
|
103
|
+
/**
|
|
104
|
+
* Create a COUNT(*) metric
|
|
105
|
+
*/
|
|
106
|
+
count: (options) => {
|
|
107
|
+
return {
|
|
108
|
+
type: 'count',
|
|
109
|
+
sql: sql `*`,
|
|
110
|
+
description: options.description,
|
|
111
|
+
format: options.format,
|
|
112
|
+
join: options.join,
|
|
113
|
+
allowFanout: options.allowFanout,
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
/**
|
|
117
|
+
* Create a SUM() metric
|
|
118
|
+
*/
|
|
119
|
+
sum: createMetricHelper('sum'),
|
|
120
|
+
/**
|
|
121
|
+
* Create an AVG() metric
|
|
122
|
+
*/
|
|
123
|
+
avg: createMetricHelper('avg'),
|
|
124
|
+
/**
|
|
125
|
+
* Create a MIN() metric
|
|
126
|
+
*/
|
|
127
|
+
min: createMetricHelper('min'),
|
|
128
|
+
/**
|
|
129
|
+
* Create a MAX() metric
|
|
130
|
+
*/
|
|
131
|
+
max: createMetricHelper('max'),
|
|
132
|
+
/**
|
|
133
|
+
* Create a COUNT(DISTINCT) metric
|
|
134
|
+
*/
|
|
135
|
+
countDistinct: createMetricHelper('countDistinct'),
|
|
136
|
+
/**
|
|
137
|
+
* Create a custom metric with a SQL expression
|
|
138
|
+
*/
|
|
139
|
+
custom: createMetricHelper('custom'),
|
|
140
|
+
};
|
|
141
|
+
// =============================================================================
|
|
142
|
+
// VALIDATION HELPERS
|
|
143
|
+
// =============================================================================
|
|
144
|
+
/**
|
|
145
|
+
* Validate that a dimension definition has required metadata
|
|
146
|
+
*/
|
|
147
|
+
export function validateDimensionDefinition(name, definition) {
|
|
148
|
+
if (typeof definition === 'string') {
|
|
149
|
+
// Simple column reference - no validation needed
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (typeof definition === 'object' && definition !== null) {
|
|
153
|
+
const def = definition;
|
|
154
|
+
if (!def.sql) {
|
|
155
|
+
throw new Error(`Dimension '${name}' is missing 'sql' property. ` +
|
|
156
|
+
`Expected a column name (string) or SQLExpression.`);
|
|
157
|
+
}
|
|
158
|
+
if (!def.type) {
|
|
159
|
+
throw new Error(`Dimension '${name}' is missing 'type' property. ` +
|
|
160
|
+
`Expected: 'string', 'number', 'date', or 'boolean'.`);
|
|
161
|
+
}
|
|
162
|
+
if (!def.description) {
|
|
163
|
+
console.warn(`⚠️ Dimension '${name}' is missing 'description'. ` +
|
|
164
|
+
`Descriptions help AI agents understand your data.`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Validate that a metric definition has required metadata
|
|
170
|
+
*/
|
|
171
|
+
export function validateMetricDefinition(name, definition) {
|
|
172
|
+
if (typeof definition !== 'object' || definition === null) {
|
|
173
|
+
throw new Error(`Metric '${name}' must be a MetricDefinition object. ` +
|
|
174
|
+
`Use metric.sum(), metric.count(), etc. helpers.`);
|
|
175
|
+
}
|
|
176
|
+
const def = definition;
|
|
177
|
+
if (!def.type) {
|
|
178
|
+
throw new Error(`Metric '${name}' is missing 'type' property. ` +
|
|
179
|
+
`Expected: 'count', 'sum', 'avg', 'min', 'max', 'countDistinct', or 'custom'.`);
|
|
180
|
+
}
|
|
181
|
+
if (!def.sql) {
|
|
182
|
+
throw new Error(`Metric '${name}' is missing 'sql' property. ` +
|
|
183
|
+
`Expected a column name (string) or SQLExpression.`);
|
|
184
|
+
}
|
|
185
|
+
if (!def.description) {
|
|
186
|
+
console.warn(`⚠️ Metric '${name}' is missing 'description'. ` +
|
|
187
|
+
`Descriptions help AI agents understand your metrics.`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataset API Module
|
|
3
|
+
*
|
|
4
|
+
* Provides a declarative API for defining dynamic datasets with:
|
|
5
|
+
* - Type-safe dimension and metric definitions
|
|
6
|
+
* - SQL expression support via tagged templates
|
|
7
|
+
* - Helper functions for common patterns
|
|
8
|
+
* - Introspection for AI agents
|
|
9
|
+
* - Full TypeScript type inference
|
|
10
|
+
*
|
|
11
|
+
* @module @hypequery/clickhouse/dataset
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { sql, dimension, metric } from '@hypequery/clickhouse/dataset';
|
|
16
|
+
*
|
|
17
|
+
* const datasets = {
|
|
18
|
+
* orders: {
|
|
19
|
+
* name: 'orders',
|
|
20
|
+
* description: 'Customer orders and revenue data',
|
|
21
|
+
* table: 'orders',
|
|
22
|
+
* dimensions: {
|
|
23
|
+
* region: dimension.string('region', {
|
|
24
|
+
* description: 'Geographic region',
|
|
25
|
+
* examples: ['US', 'EU', 'APAC']
|
|
26
|
+
* }),
|
|
27
|
+
* date: dimension.date(sql`DATE(created_at)`, {
|
|
28
|
+
* description: 'Order date'
|
|
29
|
+
* })
|
|
30
|
+
* },
|
|
31
|
+
* metrics: {
|
|
32
|
+
* revenue: metric.sum('amount', {
|
|
33
|
+
* description: 'Total revenue',
|
|
34
|
+
* format: 'currency'
|
|
35
|
+
* }),
|
|
36
|
+
* orderCount: metric.count({
|
|
37
|
+
* description: 'Number of orders'
|
|
38
|
+
* })
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* };
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export { sql, isSQLExpression, toSQLString } from './sql-tag.js';
|
|
45
|
+
export type { SQLExpression } from './sql-tag.js';
|
|
46
|
+
export type { DimensionType, SimpleDimension, DimensionDefinition, Dimension, DimensionsMap, MetricAggregationType, MetricFormat, MetricDefinition, MetricsMap, DatasetDefinition, DatasetsMap, TenantConfig, DatasetLimits, FilterOperator, DateRangeValue, FilterValue, FilterDefinition, Filters, SortDirection, OrderByDimension, OrderByMetric, OrderBy, CacheOptions, DatasetQuery, QueryContext, QueryResultMetadata, QueryResult, InferDimensionType, InferMetricType, InferQueryRowType, InferQueryResult, IntrospectedDimension, IntrospectedMetric, IntrospectedDataset, } from './types.js';
|
|
47
|
+
export { dimension, metric } from './helpers.js';
|
|
48
|
+
export type { DimensionOptions, MetricOptions } from './helpers.js';
|
|
49
|
+
export { validateDatasetDefinition, validateDatasets, normalizeDimension, normalizeDimensions, inferDimensionType, getDimensionSQL, getMetricSQL, getDataset, listDatasets, hasDataset, getDimensionNames, getMetricNames, hasDimension, hasMetric, getDimension, getMetric, } from './definition.js';
|
|
50
|
+
export { introspectDimension, introspectMetric, getDatasetSchema, listDatasets as listDatasetSchemas, getAllDatasetSchemas, summarizeDataset, datasetsToJSON, summarizeAllDatasets, } from './introspection.js';
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dataset/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAMH,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAMlD,YAAY,EAEV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,SAAS,EACT,aAAa,EAGb,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,UAAU,EAGV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EAGb,cAAc,EACd,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,OAAO,EAGP,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,OAAO,EAGP,YAAY,EAGZ,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,WAAW,EAGX,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAGhB,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAMpE,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,SAAS,GACV,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,IAAI,kBAAkB,EAClC,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataset API Module
|
|
3
|
+
*
|
|
4
|
+
* Provides a declarative API for defining dynamic datasets with:
|
|
5
|
+
* - Type-safe dimension and metric definitions
|
|
6
|
+
* - SQL expression support via tagged templates
|
|
7
|
+
* - Helper functions for common patterns
|
|
8
|
+
* - Introspection for AI agents
|
|
9
|
+
* - Full TypeScript type inference
|
|
10
|
+
*
|
|
11
|
+
* @module @hypequery/clickhouse/dataset
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { sql, dimension, metric } from '@hypequery/clickhouse/dataset';
|
|
16
|
+
*
|
|
17
|
+
* const datasets = {
|
|
18
|
+
* orders: {
|
|
19
|
+
* name: 'orders',
|
|
20
|
+
* description: 'Customer orders and revenue data',
|
|
21
|
+
* table: 'orders',
|
|
22
|
+
* dimensions: {
|
|
23
|
+
* region: dimension.string('region', {
|
|
24
|
+
* description: 'Geographic region',
|
|
25
|
+
* examples: ['US', 'EU', 'APAC']
|
|
26
|
+
* }),
|
|
27
|
+
* date: dimension.date(sql`DATE(created_at)`, {
|
|
28
|
+
* description: 'Order date'
|
|
29
|
+
* })
|
|
30
|
+
* },
|
|
31
|
+
* metrics: {
|
|
32
|
+
* revenue: metric.sum('amount', {
|
|
33
|
+
* description: 'Total revenue',
|
|
34
|
+
* format: 'currency'
|
|
35
|
+
* }),
|
|
36
|
+
* orderCount: metric.count({
|
|
37
|
+
* description: 'Number of orders'
|
|
38
|
+
* })
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* };
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
// =============================================================================
|
|
45
|
+
// SQL TAGGED TEMPLATE
|
|
46
|
+
// =============================================================================
|
|
47
|
+
export { sql, isSQLExpression, toSQLString } from './sql-tag.js';
|
|
48
|
+
// =============================================================================
|
|
49
|
+
// HELPERS
|
|
50
|
+
// =============================================================================
|
|
51
|
+
export { dimension, metric } from './helpers.js';
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// DEFINITION UTILITIES
|
|
54
|
+
// =============================================================================
|
|
55
|
+
export { validateDatasetDefinition, validateDatasets, normalizeDimension, normalizeDimensions, inferDimensionType, getDimensionSQL, getMetricSQL, getDataset, listDatasets, hasDataset, getDimensionNames, getMetricNames, hasDimension, hasMetric, getDimension, getMetric, } from './definition.js';
|
|
56
|
+
// =============================================================================
|
|
57
|
+
// INTROSPECTION
|
|
58
|
+
// =============================================================================
|
|
59
|
+
export { introspectDimension, introspectMetric, getDatasetSchema, listDatasets as listDatasetSchemas, getAllDatasetSchemas, summarizeDataset, datasetsToJSON, summarizeAllDatasets, } from './introspection.js';
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataset Introspection API
|
|
3
|
+
*
|
|
4
|
+
* Provides introspection capabilities for datasets, enabling AI agents
|
|
5
|
+
* and other tools to understand the structure and metadata of datasets.
|
|
6
|
+
*
|
|
7
|
+
* Key functions:
|
|
8
|
+
* - getDatasetSchema(): Get full schema for a dataset
|
|
9
|
+
* - listDatasets(): List all available datasets
|
|
10
|
+
* - introspectDimension(): Get metadata for a specific dimension
|
|
11
|
+
* - introspectMetric(): Get metadata for a specific metric
|
|
12
|
+
*/
|
|
13
|
+
import type { DatasetDefinition, DatasetsMap, IntrospectedDataset, IntrospectedDimension, IntrospectedMetric } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Introspect a dimension definition to extract metadata
|
|
16
|
+
*
|
|
17
|
+
* @param dimension - Dimension definition (any format)
|
|
18
|
+
* @returns Introspected dimension metadata
|
|
19
|
+
*/
|
|
20
|
+
export declare function introspectDimension(dimension: DatasetDefinition['dimensions'][string]): IntrospectedDimension;
|
|
21
|
+
/**
|
|
22
|
+
* Introspect a metric definition to extract metadata
|
|
23
|
+
*
|
|
24
|
+
* @param metric - Metric definition
|
|
25
|
+
* @returns Introspected metric metadata
|
|
26
|
+
*/
|
|
27
|
+
export declare function introspectMetric(metric: DatasetDefinition['metrics'][string]): IntrospectedMetric;
|
|
28
|
+
/**
|
|
29
|
+
* Get the complete schema for a dataset (for AI agents)
|
|
30
|
+
*
|
|
31
|
+
* @param datasets - Map of all dataset definitions
|
|
32
|
+
* @param datasetName - Name of the dataset to introspect
|
|
33
|
+
* @returns Introspected dataset schema
|
|
34
|
+
* @throws Error if dataset not found
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const schema = getDatasetSchema(datasets, 'orders');
|
|
39
|
+
* console.log(schema.dimensions.region.description);
|
|
40
|
+
* console.log(schema.metrics.revenue.format);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export declare function getDatasetSchema(datasets: DatasetsMap, datasetName: string): IntrospectedDataset;
|
|
44
|
+
/**
|
|
45
|
+
* List all available datasets
|
|
46
|
+
*
|
|
47
|
+
* @param datasets - Map of all dataset definitions
|
|
48
|
+
* @returns Array of dataset names
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const allDatasets = listDatasets(datasets);
|
|
53
|
+
* // ['orders', 'customers', 'products']
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function listDatasets(datasets: DatasetsMap): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Get introspected schemas for all datasets
|
|
59
|
+
*
|
|
60
|
+
* @param datasets - Map of all dataset definitions
|
|
61
|
+
* @returns Map of dataset names to introspected schemas
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const allSchemas = getAllDatasetSchemas(datasets);
|
|
66
|
+
* for (const [name, schema] of Object.entries(allSchemas)) {
|
|
67
|
+
* console.log(`Dataset: ${name}`);
|
|
68
|
+
* console.log(`Description: ${schema.description}`);
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function getAllDatasetSchemas(datasets: DatasetsMap): Record<string, IntrospectedDataset>;
|
|
73
|
+
/**
|
|
74
|
+
* Generate a human-readable summary of a dataset (for LLMs)
|
|
75
|
+
*
|
|
76
|
+
* @param datasets - Map of all dataset definitions
|
|
77
|
+
* @param datasetName - Name of the dataset to summarize
|
|
78
|
+
* @returns Markdown-formatted summary
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const summary = summarizeDataset(datasets, 'orders');
|
|
83
|
+
* console.log(summary);
|
|
84
|
+
* // # Dataset: orders
|
|
85
|
+
* // Customer orders and revenue data
|
|
86
|
+
* //
|
|
87
|
+
* // ## Dimensions
|
|
88
|
+
* // - region (string): Geographic region
|
|
89
|
+
* // Examples: US, EU, APAC
|
|
90
|
+
* // ...
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare function summarizeDataset(datasets: DatasetsMap, datasetName: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Generate a JSON representation of all datasets (for AI context)
|
|
96
|
+
*
|
|
97
|
+
* @param datasets - Map of all dataset definitions
|
|
98
|
+
* @returns JSON string with all dataset schemas
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const json = datasetsToJSON(datasets);
|
|
103
|
+
* // Send to LLM as context for query generation
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export declare function datasetsToJSON(datasets: DatasetsMap): string;
|
|
107
|
+
/**
|
|
108
|
+
* Get a concise summary of all datasets (for LLM context)
|
|
109
|
+
*
|
|
110
|
+
* @param datasets - Map of all dataset definitions
|
|
111
|
+
* @returns Array of dataset summaries
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const summaries = summarizeAllDatasets(datasets);
|
|
116
|
+
* // [
|
|
117
|
+
* // {
|
|
118
|
+
* // name: 'orders',
|
|
119
|
+
* // description: 'Customer orders and revenue data',
|
|
120
|
+
* // dimensionCount: 5,
|
|
121
|
+
* // metricCount: 4
|
|
122
|
+
* // },
|
|
123
|
+
* // ...
|
|
124
|
+
* // ]
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
export declare function summarizeAllDatasets(datasets: DatasetsMap): Array<{
|
|
128
|
+
name: string;
|
|
129
|
+
description: string;
|
|
130
|
+
dimensionCount: number;
|
|
131
|
+
metricCount: number;
|
|
132
|
+
}>;
|
|
133
|
+
//# sourceMappingURL=introspection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"introspection.d.ts","sourceRoot":"","sources":["../../src/dataset/introspection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAapB;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,GACjD,qBAAqB,CASvB;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAC3C,kBAAkB,CAQpB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,WAAW,EACrB,WAAW,EAAE,MAAM,GAClB,mBAAmB,CAwBrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,EAAE,CAE5D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,GACpB,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAQrC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,WAAW,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,CA0DR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAG5D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,WAAW,GACpB,KAAK,CAAC;IACP,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,CAUD"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dataset Introspection API
|
|
3
|
+
*
|
|
4
|
+
* Provides introspection capabilities for datasets, enabling AI agents
|
|
5
|
+
* and other tools to understand the structure and metadata of datasets.
|
|
6
|
+
*
|
|
7
|
+
* Key functions:
|
|
8
|
+
* - getDatasetSchema(): Get full schema for a dataset
|
|
9
|
+
* - listDatasets(): List all available datasets
|
|
10
|
+
* - introspectDimension(): Get metadata for a specific dimension
|
|
11
|
+
* - introspectMetric(): Get metadata for a specific metric
|
|
12
|
+
*/
|
|
13
|
+
import { getDataset, listDatasets as listDatasetNames, normalizeDimension, getDimensionSQL, getMetricSQL, } from './definition.js';
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// DIMENSION INTROSPECTION
|
|
16
|
+
// =============================================================================
|
|
17
|
+
/**
|
|
18
|
+
* Introspect a dimension definition to extract metadata
|
|
19
|
+
*
|
|
20
|
+
* @param dimension - Dimension definition (any format)
|
|
21
|
+
* @returns Introspected dimension metadata
|
|
22
|
+
*/
|
|
23
|
+
export function introspectDimension(dimension) {
|
|
24
|
+
const normalized = normalizeDimension(dimension);
|
|
25
|
+
return {
|
|
26
|
+
type: normalized.type,
|
|
27
|
+
description: normalized.description || undefined,
|
|
28
|
+
examples: normalized.examples,
|
|
29
|
+
sql: getDimensionSQL(dimension),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// METRIC INTROSPECTION
|
|
34
|
+
// =============================================================================
|
|
35
|
+
/**
|
|
36
|
+
* Introspect a metric definition to extract metadata
|
|
37
|
+
*
|
|
38
|
+
* @param metric - Metric definition
|
|
39
|
+
* @returns Introspected metric metadata
|
|
40
|
+
*/
|
|
41
|
+
export function introspectMetric(metric) {
|
|
42
|
+
return {
|
|
43
|
+
type: 'number',
|
|
44
|
+
aggregationType: metric.type,
|
|
45
|
+
description: metric.description,
|
|
46
|
+
format: metric.format,
|
|
47
|
+
sql: getMetricSQL(metric),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// DATASET INTROSPECTION
|
|
52
|
+
// =============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* Get the complete schema for a dataset (for AI agents)
|
|
55
|
+
*
|
|
56
|
+
* @param datasets - Map of all dataset definitions
|
|
57
|
+
* @param datasetName - Name of the dataset to introspect
|
|
58
|
+
* @returns Introspected dataset schema
|
|
59
|
+
* @throws Error if dataset not found
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const schema = getDatasetSchema(datasets, 'orders');
|
|
64
|
+
* console.log(schema.dimensions.region.description);
|
|
65
|
+
* console.log(schema.metrics.revenue.format);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function getDatasetSchema(datasets, datasetName) {
|
|
69
|
+
const dataset = getDataset(datasets, datasetName);
|
|
70
|
+
// Introspect all dimensions
|
|
71
|
+
const dimensions = {};
|
|
72
|
+
for (const [name, dimension] of Object.entries(dataset.dimensions)) {
|
|
73
|
+
dimensions[name] = introspectDimension(dimension);
|
|
74
|
+
}
|
|
75
|
+
// Introspect all metrics
|
|
76
|
+
const metrics = {};
|
|
77
|
+
for (const [name, metric] of Object.entries(dataset.metrics)) {
|
|
78
|
+
metrics[name] = introspectMetric(metric);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
name: dataset.name,
|
|
82
|
+
description: dataset.description,
|
|
83
|
+
table: dataset.table,
|
|
84
|
+
dimensions,
|
|
85
|
+
metrics,
|
|
86
|
+
tenantRequired: dataset.tenant?.required,
|
|
87
|
+
limits: dataset.limits,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* List all available datasets
|
|
92
|
+
*
|
|
93
|
+
* @param datasets - Map of all dataset definitions
|
|
94
|
+
* @returns Array of dataset names
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const allDatasets = listDatasets(datasets);
|
|
99
|
+
* // ['orders', 'customers', 'products']
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export function listDatasets(datasets) {
|
|
103
|
+
return listDatasetNames(datasets);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get introspected schemas for all datasets
|
|
107
|
+
*
|
|
108
|
+
* @param datasets - Map of all dataset definitions
|
|
109
|
+
* @returns Map of dataset names to introspected schemas
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const allSchemas = getAllDatasetSchemas(datasets);
|
|
114
|
+
* for (const [name, schema] of Object.entries(allSchemas)) {
|
|
115
|
+
* console.log(`Dataset: ${name}`);
|
|
116
|
+
* console.log(`Description: ${schema.description}`);
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export function getAllDatasetSchemas(datasets) {
|
|
121
|
+
const schemas = {};
|
|
122
|
+
for (const name of listDatasetNames(datasets)) {
|
|
123
|
+
schemas[name] = getDatasetSchema(datasets, name);
|
|
124
|
+
}
|
|
125
|
+
return schemas;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Generate a human-readable summary of a dataset (for LLMs)
|
|
129
|
+
*
|
|
130
|
+
* @param datasets - Map of all dataset definitions
|
|
131
|
+
* @param datasetName - Name of the dataset to summarize
|
|
132
|
+
* @returns Markdown-formatted summary
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const summary = summarizeDataset(datasets, 'orders');
|
|
137
|
+
* console.log(summary);
|
|
138
|
+
* // # Dataset: orders
|
|
139
|
+
* // Customer orders and revenue data
|
|
140
|
+
* //
|
|
141
|
+
* // ## Dimensions
|
|
142
|
+
* // - region (string): Geographic region
|
|
143
|
+
* // Examples: US, EU, APAC
|
|
144
|
+
* // ...
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export function summarizeDataset(datasets, datasetName) {
|
|
148
|
+
const schema = getDatasetSchema(datasets, datasetName);
|
|
149
|
+
const lines = [];
|
|
150
|
+
// Header
|
|
151
|
+
lines.push(`# Dataset: ${schema.name}`);
|
|
152
|
+
lines.push(schema.description);
|
|
153
|
+
lines.push('');
|
|
154
|
+
// Dimensions
|
|
155
|
+
lines.push('## Dimensions');
|
|
156
|
+
for (const [name, dimension] of Object.entries(schema.dimensions)) {
|
|
157
|
+
lines.push(`- ${name} (${dimension.type})${dimension.description ? `: ${dimension.description}` : ''}`);
|
|
158
|
+
if (dimension.examples && dimension.examples.length > 0) {
|
|
159
|
+
lines.push(` Examples: ${dimension.examples.join(', ')}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
lines.push('');
|
|
163
|
+
// Metrics
|
|
164
|
+
lines.push('## Metrics');
|
|
165
|
+
for (const [name, metric] of Object.entries(schema.metrics)) {
|
|
166
|
+
lines.push(`- ${name} (${metric.aggregationType})${metric.description ? `: ${metric.description}` : ''}`);
|
|
167
|
+
if (metric.format) {
|
|
168
|
+
lines.push(` Format: ${metric.format}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
lines.push('');
|
|
172
|
+
// Constraints
|
|
173
|
+
if (schema.tenantRequired || schema.limits) {
|
|
174
|
+
lines.push('## Constraints');
|
|
175
|
+
if (schema.tenantRequired) {
|
|
176
|
+
lines.push('- Multi-tenancy: Required');
|
|
177
|
+
}
|
|
178
|
+
if (schema.limits) {
|
|
179
|
+
if (schema.limits.maxDimensions) {
|
|
180
|
+
lines.push(`- Max dimensions: ${schema.limits.maxDimensions}`);
|
|
181
|
+
}
|
|
182
|
+
if (schema.limits.maxMetrics) {
|
|
183
|
+
lines.push(`- Max metrics: ${schema.limits.maxMetrics}`);
|
|
184
|
+
}
|
|
185
|
+
if (schema.limits.maxFilters) {
|
|
186
|
+
lines.push(`- Max filters: ${schema.limits.maxFilters}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
lines.push('');
|
|
190
|
+
}
|
|
191
|
+
return lines.join('\n');
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Generate a JSON representation of all datasets (for AI context)
|
|
195
|
+
*
|
|
196
|
+
* @param datasets - Map of all dataset definitions
|
|
197
|
+
* @returns JSON string with all dataset schemas
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const json = datasetsToJSON(datasets);
|
|
202
|
+
* // Send to LLM as context for query generation
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export function datasetsToJSON(datasets) {
|
|
206
|
+
const schemas = getAllDatasetSchemas(datasets);
|
|
207
|
+
return JSON.stringify(schemas, null, 2);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get a concise summary of all datasets (for LLM context)
|
|
211
|
+
*
|
|
212
|
+
* @param datasets - Map of all dataset definitions
|
|
213
|
+
* @returns Array of dataset summaries
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* const summaries = summarizeAllDatasets(datasets);
|
|
218
|
+
* // [
|
|
219
|
+
* // {
|
|
220
|
+
* // name: 'orders',
|
|
221
|
+
* // description: 'Customer orders and revenue data',
|
|
222
|
+
* // dimensionCount: 5,
|
|
223
|
+
* // metricCount: 4
|
|
224
|
+
* // },
|
|
225
|
+
* // ...
|
|
226
|
+
* // ]
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
export function summarizeAllDatasets(datasets) {
|
|
230
|
+
return listDatasetNames(datasets).map((name) => {
|
|
231
|
+
const schema = getDatasetSchema(datasets, name);
|
|
232
|
+
return {
|
|
233
|
+
name: schema.name,
|
|
234
|
+
description: schema.description,
|
|
235
|
+
dimensionCount: Object.keys(schema.dimensions).length,
|
|
236
|
+
metricCount: Object.keys(schema.metrics).length,
|
|
237
|
+
};
|
|
238
|
+
});
|
|
239
|
+
}
|