@hypequery/clickhouse 1.1.0 → 1.1.1
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 +253 -0
- package/dist/core/cross-filter.d.ts +0 -16
- package/dist/core/cross-filter.d.ts.map +1 -1
- package/dist/core/cross-filter.js +0 -82
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>@hypequery/clickhouse</h1>
|
|
3
|
+
<p>A typescript-first library for building type-safe dashboards with ClickHouse</p>
|
|
4
|
+
|
|
5
|
+
[](https://github.com/hypequery/hypequery/blob/main/LICENSE)
|
|
6
|
+
[](https://badge.fury.io/js/@hypequery%2Fclickhouse)
|
|
7
|
+
[](https://github.com/hypequery/hypequery/stargazers)
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
hypequery is a typescript-first query builder for ClickHouse designed specifically for building type-safe analytics dashboards. Unlike generic SQL query builders, hypequery understands your ClickHouse schema and provides full type checking, making it ideal for data-intensive applications.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- 🎯 **Type-Safe**: Full TypeScript support with types from your ClickHouse schema
|
|
18
|
+
- 🚀 **Performant**: Built for real-time analytics with optimized query generation
|
|
19
|
+
- 🔍 **Cross Filtering**: Powerful cross-filtering capabilities for interactive dashboards
|
|
20
|
+
- 🛠️ **Developer Friendly**: Fluent API design for an intuitive development experience
|
|
21
|
+
- 📱 **Platform Agnostic**: Works in both Node.js and browser environments
|
|
22
|
+
- 🔄 **Schema Generation**: CLI tool to generate TypeScript types from your ClickHouse schema
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
This library requires one of the following ClickHouse clients as a peer dependency:
|
|
27
|
+
|
|
28
|
+
### For Node.js environments
|
|
29
|
+
```bash
|
|
30
|
+
npm install @hypequery/clickhouse @clickhouse/client
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### For browser/universal environments
|
|
34
|
+
```bash
|
|
35
|
+
npm install @hypequery/clickhouse @clickhouse/client-web
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Note**: The library supports multiple client selection strategies:
|
|
39
|
+
- **Manual injection**: Explicitly provide a client instance (required for browser environments)
|
|
40
|
+
- **Auto-detection**: Automatically selects the client for Node.js environments
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### Node.js Environments
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
48
|
+
import type { IntrospectedSchema } from './generated-schema';
|
|
49
|
+
|
|
50
|
+
// Initialize the query builder
|
|
51
|
+
const db = createQueryBuilder<IntrospectedSchema>({
|
|
52
|
+
host: 'your-clickhouse-host',
|
|
53
|
+
username: 'default',
|
|
54
|
+
password: 'your-password',
|
|
55
|
+
database: 'default'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Build and execute a query
|
|
59
|
+
const results = await db
|
|
60
|
+
.table('trips')
|
|
61
|
+
.select(['pickup_datetime', 'dropoff_datetime', 'total_amount'])
|
|
62
|
+
.where('total_amount', '>', 50)
|
|
63
|
+
.orderBy('pickup_datetime', 'DESC')
|
|
64
|
+
.limit(10)
|
|
65
|
+
.execute();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Browser Environments
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
72
|
+
import { createClient } from '@clickhouse/client-web';
|
|
73
|
+
import type { IntrospectedSchema } from './generated-schema';
|
|
74
|
+
|
|
75
|
+
// Create the ClickHouse client explicitly
|
|
76
|
+
const client = createClient({
|
|
77
|
+
host: 'your-clickhouse-host',
|
|
78
|
+
username: 'default',
|
|
79
|
+
password: '',
|
|
80
|
+
database: 'default'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Initialize the query builder with the client
|
|
84
|
+
const db = createQueryBuilder<IntrospectedSchema>({
|
|
85
|
+
client // Explicitly provide the client
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Build and execute a query
|
|
89
|
+
const results = await db
|
|
90
|
+
.table('trips')
|
|
91
|
+
.select(['pickup_datetime', 'dropoff_datetime', 'total_amount'])
|
|
92
|
+
.where('total_amount', '>', 50)
|
|
93
|
+
.orderBy('pickup_datetime', 'DESC')
|
|
94
|
+
.limit(10)
|
|
95
|
+
.execute();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Schema Generation
|
|
99
|
+
|
|
100
|
+
hypequery provides a CLI tool to generate TypeScript types from your ClickHouse schema:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Install globally (optional)
|
|
104
|
+
npm install -g @hypequery/clickhouse
|
|
105
|
+
|
|
106
|
+
# Generate schema types
|
|
107
|
+
npx hypequery-generate-types --host your-clickhouse-host --database your-database
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This creates a `generated-schema.ts` file that you can import in your application:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
114
|
+
import type { IntrospectedSchema } from './generated-schema';
|
|
115
|
+
|
|
116
|
+
const db = createQueryBuilder<IntrospectedSchema>({
|
|
117
|
+
// connection details
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Core Features
|
|
122
|
+
|
|
123
|
+
### Type-Safe Queries
|
|
124
|
+
|
|
125
|
+
hypequery provides full TypeScript support, ensuring your queries are type-safe:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Column names are type-checked
|
|
129
|
+
const query = db.table('trips')
|
|
130
|
+
.select(['pickup_datetime', 'total_amount'])
|
|
131
|
+
.where('total_amount', 'gt', 50)
|
|
132
|
+
.execute();
|
|
133
|
+
|
|
134
|
+
// Type error if column doesn't exist
|
|
135
|
+
db.table('trips').select(['non_existent_column']); // TypeScript error
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Cross Filtering
|
|
139
|
+
|
|
140
|
+
Implement interactive dashboards with cross-filtering support:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { CrossFilter } from '@hypequery/clickhouse';
|
|
144
|
+
|
|
145
|
+
// Create a filter
|
|
146
|
+
const filter = new CrossFilter()
|
|
147
|
+
.add({
|
|
148
|
+
column: 'pickup_datetime',
|
|
149
|
+
operator: 'gte',
|
|
150
|
+
value: '2024-01-01'
|
|
151
|
+
})
|
|
152
|
+
.add({
|
|
153
|
+
column: 'total_amount',
|
|
154
|
+
operator: 'gt',
|
|
155
|
+
value: 20
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Apply to multiple queries
|
|
159
|
+
const query1 = db.table('trips')
|
|
160
|
+
.applyCrossFilters(filter)
|
|
161
|
+
.execute();
|
|
162
|
+
|
|
163
|
+
const query2 = db.table('drivers')
|
|
164
|
+
.applyCrossFilters(filter)
|
|
165
|
+
.execute();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Advanced Queries
|
|
169
|
+
|
|
170
|
+
hypequery supports complex queries including joins, aggregations, and subqueries:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// Aggregations
|
|
174
|
+
const stats = await db.table('trips')
|
|
175
|
+
.avg('total_amount')
|
|
176
|
+
.max('trip_distance')
|
|
177
|
+
.count('trip_id')
|
|
178
|
+
.where('pickup_datetime', 'gte', '2024-01-01')
|
|
179
|
+
.execute();
|
|
180
|
+
|
|
181
|
+
// Joins
|
|
182
|
+
const tripsWithDrivers = await db.table('trips')
|
|
183
|
+
.select(['trips.trip_id', 'trips.total_amount', 'drivers.name'])
|
|
184
|
+
.join('drivers', 'trips.driver_id', 'drivers.id')
|
|
185
|
+
.execute();
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
**Benefits:**
|
|
191
|
+
- ✅ Works in all environments (Node.js, browser, bundlers)
|
|
192
|
+
- ✅ Explicit control over client configuration
|
|
193
|
+
- ✅ Required for browser environments (require() doesn't work in browsers)
|
|
194
|
+
- ✅ Synchronous API throughout
|
|
195
|
+
|
|
196
|
+
#### 2. Auto-Detection with Fallback (Node.js Environments Only)
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
const db = createQueryBuilder<IntrospectedSchema>({
|
|
200
|
+
host: 'your-clickhouse-host',
|
|
201
|
+
username: 'default',
|
|
202
|
+
password: '',
|
|
203
|
+
database: 'default'
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
## Versioning and Release Channels
|
|
209
|
+
|
|
210
|
+
hypequery follows semantic versioning and provides multiple release channels:
|
|
211
|
+
|
|
212
|
+
- **Latest**: Stable releases (`npm install @hypequery/clickhouse`)
|
|
213
|
+
- **Beta**: Pre-release versions (`npm install @hypequery/clickhouse@beta`)
|
|
214
|
+
|
|
215
|
+
## Documentation
|
|
216
|
+
|
|
217
|
+
For detailed documentation and examples, visit our [documentation site](https://hypequery.com/docs).
|
|
218
|
+
|
|
219
|
+
- [Getting Started](https://hypequery.com/docs/installation)
|
|
220
|
+
- [Query Building](https://hypequery.com/docs/guides/query-building)
|
|
221
|
+
- [Filtering](https://hypequery.com/docs/guides/filtering)
|
|
222
|
+
- [Pagination](https://hypequery.com/docs/features/pagination)
|
|
223
|
+
- [API Reference](https://hypequery.com/docs/reference/api)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
## Troubleshooting
|
|
227
|
+
|
|
228
|
+
### Common Issues
|
|
229
|
+
|
|
230
|
+
- **Connection Errors**: Ensure your ClickHouse server is running and accessible
|
|
231
|
+
- **CORS Issues**: Use a proxy server for browser environments
|
|
232
|
+
- **Type Errors**: Make sure to regenerate your schema types after schema changes
|
|
233
|
+
- **Client Not Found**: Make sure you have installed at least one of the required peer dependencies:
|
|
234
|
+
- `@clickhouse/client` (for Node.js environments)
|
|
235
|
+
- `@clickhouse/client-web` (for browser/universal environments)
|
|
236
|
+
- **Browser Auto-Detection**: Auto-detection doesn't work in browsers because `require()` calls don't work. Use manual injection instead.
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
This project is licensed under the Apache-2.0 License - see the [LICENSE](LICENSE) file for details.
|
|
242
|
+
|
|
243
|
+
## Support
|
|
244
|
+
|
|
245
|
+
- 📚 [Documentation](https://hypequery.com/docs)
|
|
246
|
+
- 🐛 [Issue Tracker](https://github.com/hypequery/hypequery/issues)
|
|
247
|
+
- 💬 [Discussions](https://github.com/hypequery/hypequery/discussions)
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
<div align="center">
|
|
252
|
+
<sub>Built with ❤️ by the hypequery team</sub>
|
|
253
|
+
</div>
|
|
@@ -8,17 +8,6 @@ export interface FilterGroup<Schema extends Record<string, Record<string, any>>
|
|
|
8
8
|
direction: 'ASC' | 'DESC';
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
-
export declare const DateRange: {
|
|
12
|
-
readonly TODAY: "today";
|
|
13
|
-
readonly YESTERDAY: "yesterday";
|
|
14
|
-
readonly LAST_7_DAYS: "last_7_days";
|
|
15
|
-
readonly LAST_30_DAYS: "last_30_days";
|
|
16
|
-
readonly THIS_MONTH: "this_month";
|
|
17
|
-
readonly LAST_MONTH: "last_month";
|
|
18
|
-
readonly THIS_QUARTER: "this_quarter";
|
|
19
|
-
readonly YEAR_TO_DATE: "year_to_date";
|
|
20
|
-
};
|
|
21
|
-
export type DateRangeType = typeof DateRange[keyof typeof DateRange];
|
|
22
11
|
/**
|
|
23
12
|
* A type-safe filter builder supporting both simple conditions and complex nested groups.
|
|
24
13
|
* @template Schema - The full database schema type
|
|
@@ -69,11 +58,6 @@ export declare class CrossFilter<Schema extends {
|
|
|
69
58
|
* Type guard to check if an item is a FilterGroup.
|
|
70
59
|
*/
|
|
71
60
|
private isGroup;
|
|
72
|
-
private addDateCondition;
|
|
73
|
-
addDateRange<K extends keyof Schema[TableName]>(column: K extends keyof Schema[TableName] ? Schema[TableName][K] extends 'Date' | 'DateTime' ? K : never : never, range: DateRangeType): this;
|
|
74
|
-
lastNDays<K extends keyof Schema[TableName]>(column: K extends keyof Schema[TableName] ? Schema[TableName][K] extends 'Date' | 'DateTime' ? K : never : never, days: number): this;
|
|
75
|
-
addComparisonPeriod<K extends keyof Schema[TableName]>(column: K extends keyof Schema[TableName] ? Schema[TableName][K] extends 'Date' | 'DateTime' ? K : never : never, currentRange: [Date, Date]): this;
|
|
76
|
-
addYearOverYear<K extends keyof Schema[TableName]>(column: K extends keyof Schema[TableName] ? Schema[TableName][K] extends 'Date' | 'DateTime' ? K : never : never, currentRange: [Date, Date]): this;
|
|
77
61
|
/**
|
|
78
62
|
* Creates a filter for top N records by a value column
|
|
79
63
|
* @param valueColumn - The column to filter and order by
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cross-filter.d.ts","sourceRoot":"","sources":["../../src/core/cross-filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,WAAW,CAC1B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,EACxD,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG;IAE3C,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,KAAK,CACf,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAC9E,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,SAAS,CAAC;QACxB,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;KAC3B,CAAC;CACH;AAED
|
|
1
|
+
{"version":3,"file":"cross-filter.d.ts","sourceRoot":"","sources":["../../src/core/cross-filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,WAAW,CAC1B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,EACxD,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG;IAE3C,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,KAAK,CACf,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAC9E,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,SAAS,CAAC;QACxB,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;KAC3B,CAAC;CACH;AAED;;;;GAIG;AACH,qBAAa,WAAW,CACtB,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,GAAG,GAAG,EAClF,SAAS,SAAS,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC;IAMlD,OAAO,CAAC,MAAM,CAAC;IAH3B,OAAO,CAAC,SAAS,CAAyC;gBAGtC,MAAM,CAAC,EAAE,MAAM,YAAA;IAInC;;;OAGG;IACH,GAAG,CACD,UAAU,SAAS,OAAO,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,EAC3D,EAAE,SAAS,cAAc,EAEzB,SAAS,EAAE,oBAAoB,CAC7B,gBAAgB,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EACpE,MAAM,EACN,MAAM,CAAC,SAAS,CAAC,CAClB,GACA,IAAI;IA0BP;;OAEG;IACH,WAAW,CACT,UAAU,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GACtE,IAAI;IAQP;;;;OAIG;IACH,QAAQ,CACN,eAAe,EAAE,KAAK,CACpB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAC9F,EACD,QAAQ,EAAE,KAAK,GAAG,IAAI,GACrB,IAAI;IAYP;;OAEG;IACH,aAAa,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAIvD;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;;;;OAKG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,CAAC,SAAS,CAAC,EACpC,WAAW,EAAE,CAAC,EACd,CAAC,EAAE,MAAM,EACT,OAAO,GAAE,MAAM,GAAG,KAAc,GAC/B,IAAI;CAmBR"}
|
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
import { FilterValidator } from './validators/filter-validator';
|
|
2
|
-
export const DateRange = {
|
|
3
|
-
TODAY: 'today',
|
|
4
|
-
YESTERDAY: 'yesterday',
|
|
5
|
-
LAST_7_DAYS: 'last_7_days',
|
|
6
|
-
LAST_30_DAYS: 'last_30_days',
|
|
7
|
-
THIS_MONTH: 'this_month',
|
|
8
|
-
LAST_MONTH: 'last_month',
|
|
9
|
-
THIS_QUARTER: 'this_quarter',
|
|
10
|
-
YEAR_TO_DATE: 'year_to_date'
|
|
11
|
-
};
|
|
12
2
|
/**
|
|
13
3
|
* A type-safe filter builder supporting both simple conditions and complex nested groups.
|
|
14
4
|
* @template Schema - The full database schema type
|
|
@@ -120,78 +110,6 @@ export class CrossFilter {
|
|
|
120
110
|
isGroup(item) {
|
|
121
111
|
return typeof item.conditions !== 'undefined';
|
|
122
112
|
}
|
|
123
|
-
addDateCondition(column, value) {
|
|
124
|
-
this.rootGroup.conditions.push({
|
|
125
|
-
column,
|
|
126
|
-
operator: 'between',
|
|
127
|
-
value: [value[0].toISOString(), value[1].toISOString()]
|
|
128
|
-
});
|
|
129
|
-
return this;
|
|
130
|
-
}
|
|
131
|
-
addDateRange(column, range) {
|
|
132
|
-
const now = new Date();
|
|
133
|
-
let start;
|
|
134
|
-
let end;
|
|
135
|
-
switch (range) {
|
|
136
|
-
case 'today':
|
|
137
|
-
start = new Date(now.setHours(0, 0, 0, 0));
|
|
138
|
-
end = new Date(now.setHours(23, 59, 59, 999));
|
|
139
|
-
break;
|
|
140
|
-
case 'yesterday':
|
|
141
|
-
start = new Date(now.setDate(now.getDate() - 1));
|
|
142
|
-
start.setHours(0, 0, 0, 0);
|
|
143
|
-
end = new Date(start);
|
|
144
|
-
end.setHours(23, 59, 59, 999);
|
|
145
|
-
break;
|
|
146
|
-
case 'last_7_days':
|
|
147
|
-
end = new Date(now);
|
|
148
|
-
start = new Date(now.setDate(now.getDate() - 7));
|
|
149
|
-
break;
|
|
150
|
-
case 'last_30_days':
|
|
151
|
-
end = new Date(now);
|
|
152
|
-
start = new Date(now.setDate(now.getDate() - 30));
|
|
153
|
-
break;
|
|
154
|
-
case 'this_month':
|
|
155
|
-
start = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
156
|
-
end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
|
157
|
-
break;
|
|
158
|
-
case 'last_month':
|
|
159
|
-
start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
|
160
|
-
end = new Date(now.getFullYear(), now.getMonth(), 0);
|
|
161
|
-
break;
|
|
162
|
-
case 'this_quarter':
|
|
163
|
-
const quarter = Math.floor(now.getMonth() / 3);
|
|
164
|
-
start = new Date(now.getFullYear(), quarter * 3, 1);
|
|
165
|
-
end = new Date(now.getFullYear(), (quarter + 1) * 3, 0);
|
|
166
|
-
break;
|
|
167
|
-
case 'year_to_date':
|
|
168
|
-
start = new Date(now.getFullYear(), 0, 1);
|
|
169
|
-
end = new Date(now);
|
|
170
|
-
break;
|
|
171
|
-
default:
|
|
172
|
-
throw new Error(`Unsupported date range: ${range}`);
|
|
173
|
-
}
|
|
174
|
-
return this.addDateCondition(column, [start, end]);
|
|
175
|
-
}
|
|
176
|
-
lastNDays(column, days) {
|
|
177
|
-
const end = new Date();
|
|
178
|
-
const start = new Date();
|
|
179
|
-
start.setDate(start.getDate() - days);
|
|
180
|
-
return this.addDateCondition(column, [start, end]);
|
|
181
|
-
}
|
|
182
|
-
addComparisonPeriod(column, currentRange) {
|
|
183
|
-
const periodLength = currentRange[1].getTime() - currentRange[0].getTime();
|
|
184
|
-
const previousStart = new Date(currentRange[0].getTime() - periodLength);
|
|
185
|
-
const previousEnd = new Date(currentRange[1].getTime() - periodLength);
|
|
186
|
-
return this.addDateCondition(column, [previousStart, previousEnd]);
|
|
187
|
-
}
|
|
188
|
-
addYearOverYear(column, currentRange) {
|
|
189
|
-
const previousStart = new Date(currentRange[0]);
|
|
190
|
-
previousStart.setFullYear(previousStart.getFullYear() - 1);
|
|
191
|
-
const previousEnd = new Date(currentRange[1]);
|
|
192
|
-
previousEnd.setFullYear(previousEnd.getFullYear() - 1);
|
|
193
|
-
return this.addDateCondition(column, [previousStart, previousEnd]);
|
|
194
|
-
}
|
|
195
113
|
/**
|
|
196
114
|
* Creates a filter for top N records by a value column
|
|
197
115
|
* @param valueColumn - The column to filter and order by
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createQueryBuilder } from './core/query-builder.js';
|
|
1
|
+
export { createQueryBuilder, QueryBuilder } from './core/query-builder.js';
|
|
2
2
|
export { ClickHouseConnection } from './core/connection.js';
|
|
3
3
|
export { JoinRelationships } from './core/join-relationships.js';
|
|
4
4
|
export type { ClickHouseConfig, ClickHouseHostConfig, ClickHouseClientConfig } from './core/query-builder.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACvE,YAAY,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,eAAe,EACf,QAAQ,EACR,iBAAiB,EAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EACL,GAAG,EACH,KAAK,EACL,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,aAAa,EACb,iBAAiB,EAClB,MAAM,iCAAiC,CAAC"}
|