@hypequery/clickhouse 1.6.2 → 2.0.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/README-CLI.md +43 -88
- package/README.md +84 -253
- package/dist/cli/bin.js +16 -8
- package/dist/core/adapters/clickhouse-adapter.d.ts.map +1 -1
- package/dist/core/adapters/clickhouse-adapter.js +3 -2
- package/dist/core/cache/cache-manager.d.ts.map +1 -1
- package/dist/core/cache/cache-manager.js +5 -3
- package/dist/core/connection.d.ts +6 -6
- package/dist/core/connection.js +9 -9
- package/dist/core/cross-filter.js +1 -1
- package/dist/core/dialects/clickhouse-dialect.d.ts +2 -2
- package/dist/core/dialects/clickhouse-dialect.d.ts.map +1 -1
- package/dist/core/dialects/clickhouse-dialect.js +39 -22
- package/dist/core/dialects/sql-dialect.d.ts +2 -2
- package/dist/core/dialects/sql-dialect.d.ts.map +1 -1
- package/dist/core/env/auto-client.d.ts.map +1 -1
- package/dist/core/env/auto-client.js +1 -1
- package/dist/core/features/aggregations.d.ts +7 -90
- package/dist/core/features/aggregations.d.ts.map +1 -1
- package/dist/core/features/aggregations.js +19 -7
- package/dist/core/features/analytics.d.ts +5 -870
- package/dist/core/features/analytics.d.ts.map +1 -1
- package/dist/core/features/analytics.js +15 -13
- package/dist/core/features/cross-filtering.d.ts +1 -1
- package/dist/core/features/cross-filtering.d.ts.map +1 -1
- package/dist/core/features/cross-filtering.js +28 -73
- package/dist/core/features/executor.d.ts +1 -1
- package/dist/core/features/executor.d.ts.map +1 -1
- package/dist/core/features/executor.js +9 -11
- package/dist/core/features/filtering.d.ts +5 -91
- package/dist/core/features/filtering.d.ts.map +1 -1
- package/dist/core/features/filtering.js +63 -77
- package/dist/core/features/joins.d.ts +2 -19
- package/dist/core/features/joins.d.ts.map +1 -1
- package/dist/core/features/joins.js +16 -5
- package/dist/core/features/query-modifiers.d.ts +10 -109
- package/dist/core/features/query-modifiers.d.ts.map +1 -1
- package/dist/core/features/query-modifiers.js +64 -18
- package/dist/core/formatters/sql-formatter.d.ts +16 -5
- package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
- package/dist/core/formatters/sql-formatter.js +197 -93
- package/dist/core/join-relationships.d.ts +22 -5
- package/dist/core/join-relationships.d.ts.map +1 -1
- package/dist/core/join-relationships.js +1 -1
- package/dist/core/query-builder.d.ts +63 -12
- package/dist/core/query-builder.d.ts.map +1 -1
- package/dist/core/query-builder.js +210 -153
- package/dist/core/query-node.d.ts +7 -0
- package/dist/core/query-node.d.ts.map +1 -0
- package/dist/core/query-node.js +80 -0
- package/dist/core/tests/integration/setup.d.ts +1 -0
- package/dist/core/tests/integration/setup.d.ts.map +1 -1
- package/dist/core/tests/integration/setup.js +4 -2
- package/dist/core/types/select-types.d.ts +3 -0
- package/dist/core/types/select-types.d.ts.map +1 -1
- package/dist/core/utils/connection-endpoint.d.ts +3 -0
- package/dist/core/utils/connection-endpoint.d.ts.map +1 -0
- package/dist/core/utils/connection-endpoint.js +9 -0
- package/dist/core/utils/filter-application.d.ts +15 -0
- package/dist/core/utils/filter-application.d.ts.map +1 -0
- package/dist/core/utils/filter-application.js +32 -0
- package/dist/core/utils/query-config-compat.d.ts +48 -0
- package/dist/core/utils/query-config-compat.d.ts.map +1 -0
- package/dist/core/utils/query-config-compat.js +137 -0
- package/dist/core/utils/relation-application.d.ts +9 -0
- package/dist/core/utils/relation-application.d.ts.map +1 -0
- package/dist/core/utils/relation-application.js +19 -0
- package/dist/core/utils/relation-validation.d.ts +6 -0
- package/dist/core/utils/relation-validation.d.ts.map +1 -0
- package/dist/core/utils/relation-validation.js +29 -0
- package/dist/core/utils/sql-expressions.d.ts +14 -0
- package/dist/core/utils/sql-expressions.d.ts.map +1 -1
- package/dist/core/utils/sql-expressions.js +40 -0
- package/dist/core/utils/tuple-filter-validation.d.ts +3 -0
- package/dist/core/utils/tuple-filter-validation.d.ts.map +1 -0
- package/dist/core/utils/tuple-filter-validation.js +16 -0
- package/dist/index.d.ts +2 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -8
- package/dist/types/base.d.ts +88 -22
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/filters.d.ts +9 -5
- package/dist/types/filters.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/migrations/config/index.d.ts +0 -3
- package/dist/migrations/config/index.d.ts.map +0 -1
- package/dist/migrations/config/index.js +0 -1
- package/dist/migrations/config/types.d.ts +0 -45
- package/dist/migrations/config/types.d.ts.map +0 -1
- package/dist/migrations/config/types.js +0 -28
- package/dist/migrations/diff/diff.d.ts +0 -11
- package/dist/migrations/diff/diff.d.ts.map +0 -1
- package/dist/migrations/diff/diff.js +0 -240
- package/dist/migrations/diff/index.d.ts +0 -3
- package/dist/migrations/diff/index.d.ts.map +0 -1
- package/dist/migrations/diff/index.js +0 -1
- package/dist/migrations/diff/types.d.ts +0 -74
- package/dist/migrations/diff/types.d.ts.map +0 -1
- package/dist/migrations/diff/types.js +0 -1
- package/dist/migrations/plan/index.d.ts +0 -3
- package/dist/migrations/plan/index.d.ts.map +0 -1
- package/dist/migrations/plan/index.js +0 -1
- package/dist/migrations/plan/plan.d.ts +0 -12
- package/dist/migrations/plan/plan.d.ts.map +0 -1
- package/dist/migrations/plan/plan.js +0 -416
- package/dist/migrations/plan/types.d.ts +0 -93
- package/dist/migrations/plan/types.d.ts.map +0 -1
- package/dist/migrations/plan/types.js +0 -1
- package/dist/migrations/schema/column.d.ts +0 -71
- package/dist/migrations/schema/column.d.ts.map +0 -1
- package/dist/migrations/schema/column.js +0 -123
- package/dist/migrations/schema/define.d.ts +0 -24
- package/dist/migrations/schema/define.d.ts.map +0 -1
- package/dist/migrations/schema/define.js +0 -47
- package/dist/migrations/schema/index.d.ts +0 -4
- package/dist/migrations/schema/index.d.ts.map +0 -1
- package/dist/migrations/schema/index.js +0 -2
- package/dist/migrations/schema/types.d.ts +0 -74
- package/dist/migrations/schema/types.d.ts.map +0 -1
- package/dist/migrations/schema/types.js +0 -1
- package/dist/migrations/snapshot/index.d.ts +0 -3
- package/dist/migrations/snapshot/index.d.ts.map +0 -1
- package/dist/migrations/snapshot/index.js +0 -1
- package/dist/migrations/snapshot/serialize.d.ts +0 -21
- package/dist/migrations/snapshot/serialize.d.ts.map +0 -1
- package/dist/migrations/snapshot/serialize.js +0 -127
- package/dist/migrations/snapshot/types.d.ts +0 -47
- package/dist/migrations/snapshot/types.d.ts.map +0 -1
- package/dist/migrations/snapshot/types.js +0 -1
- package/dist/migrations/sql/index.d.ts +0 -4
- package/dist/migrations/sql/index.d.ts.map +0 -1
- package/dist/migrations/sql/index.js +0 -2
- package/dist/migrations/sql/render.d.ts +0 -10
- package/dist/migrations/sql/render.d.ts.map +0 -1
- package/dist/migrations/sql/render.js +0 -347
- package/dist/migrations/sql/types.d.ts +0 -53
- package/dist/migrations/sql/types.d.ts.map +0 -1
- package/dist/migrations/sql/types.js +0 -1
- package/dist/migrations/sql/write.d.ts +0 -10
- package/dist/migrations/sql/write.d.ts.map +0 -1
- package/dist/migrations/sql/write.js +0 -35
package/README-CLI.md
CHANGED
|
@@ -1,123 +1,78 @@
|
|
|
1
|
-
# hypequery
|
|
1
|
+
# hypequery Type Generator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`hypequery-generate-types` introspects your ClickHouse schema and writes a TypeScript interface you can use with `createQueryBuilder()`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Most users should prefer:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npx hypequery generate
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This file documents the lower-level binary that ships with `@hypequery/clickhouse`.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
8
14
|
|
|
9
15
|
```bash
|
|
10
16
|
npm install @hypequery/clickhouse
|
|
11
17
|
```
|
|
12
18
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
Generate TypeScript types for your ClickHouse database:
|
|
19
|
+
## Usage
|
|
16
20
|
|
|
17
21
|
```bash
|
|
18
22
|
npx hypequery-generate-types
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
1. Connect to your ClickHouse database using environment variables
|
|
23
|
-
2. Introspect all tables in your database
|
|
24
|
-
3. Generate TypeScript definitions in `./generated-schema.ts`
|
|
25
|
+
By default it:
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
- reads ClickHouse connection details from environment variables
|
|
28
|
+
- introspects tables in the target database
|
|
29
|
+
- writes `generated-schema.ts` in the current working directory
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
Custom output path:
|
|
29
32
|
|
|
30
33
|
```bash
|
|
31
34
|
npx hypequery-generate-types ./src/types/db-schema.ts
|
|
32
35
|
```
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
## Environment Variables
|
|
38
|
+
|
|
39
|
+
| Variable | Description |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `CLICKHOUSE_URL` | Preferred ClickHouse URL |
|
|
42
|
+
| `CLICKHOUSE_HOST` | Deprecated alias for `CLICKHOUSE_URL` |
|
|
43
|
+
| `CLICKHOUSE_USER` | ClickHouse username |
|
|
44
|
+
| `CLICKHOUSE_PASSWORD` | ClickHouse password |
|
|
45
|
+
| `CLICKHOUSE_DATABASE` | ClickHouse database |
|
|
46
|
+
|
|
47
|
+
Example:
|
|
35
48
|
|
|
36
49
|
```bash
|
|
37
|
-
|
|
38
|
-
CLICKHOUSE_USER=
|
|
39
|
-
CLICKHOUSE_PASSWORD=
|
|
50
|
+
CLICKHOUSE_URL=http://localhost:8123 \
|
|
51
|
+
CLICKHOUSE_USER=default \
|
|
52
|
+
CLICKHOUSE_PASSWORD=secret \
|
|
40
53
|
CLICKHOUSE_DATABASE=analytics \
|
|
41
|
-
npx hypequery-generate-types
|
|
54
|
+
npx hypequery-generate-types ./analytics/schema.ts
|
|
42
55
|
```
|
|
43
56
|
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
Configure the connection using environment variables:
|
|
47
|
-
|
|
48
|
-
| Variable | Description | Default |
|
|
49
|
-
|----------|-------------|---------|
|
|
50
|
-
| `CLICKHOUSE_HOST` | ClickHouse server URL | `http://localhost:8123` |
|
|
51
|
-
| `CLICKHOUSE_USER` | ClickHouse username | `default` |
|
|
52
|
-
| `CLICKHOUSE_PASSWORD` | ClickHouse password | _(empty)_ |
|
|
53
|
-
| `CLICKHOUSE_DATABASE` | ClickHouse database name | `default` |
|
|
54
|
-
|
|
55
|
-
You can set these in:
|
|
56
|
-
- A `.env` file in your project root
|
|
57
|
-
- Your system environment
|
|
58
|
-
- Directly when running the command
|
|
59
|
-
|
|
60
|
-
## Using Generated Types
|
|
57
|
+
## Using The Generated Types
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
59
|
+
```ts
|
|
65
60
|
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
66
|
-
import { IntrospectedSchema } from './
|
|
61
|
+
import type { IntrospectedSchema } from './analytics/schema.js';
|
|
67
62
|
|
|
68
|
-
// Create a type-safe query builder
|
|
69
63
|
const db = createQueryBuilder<IntrospectedSchema>({
|
|
70
|
-
|
|
71
|
-
username: process.env.CLICKHOUSE_USER
|
|
72
|
-
password: process.env.CLICKHOUSE_PASSWORD,
|
|
73
|
-
database: process.env.CLICKHOUSE_DATABASE
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// Enjoy complete type safety!
|
|
77
|
-
const results = await db
|
|
78
|
-
.table('users') // TypeScript checks table exists
|
|
79
|
-
.select(['id', 'name']) // TypeScript checks columns exist
|
|
80
|
-
.where('id', 'gt', 10) // TypeScript validates types
|
|
81
|
-
.execute();
|
|
82
|
-
|
|
83
|
-
// Results are properly typed
|
|
84
|
-
results.forEach(user => {
|
|
85
|
-
console.log(user.name); // TypeScript knows this is a string
|
|
64
|
+
url: process.env.CLICKHOUSE_URL!,
|
|
65
|
+
username: process.env.CLICKHOUSE_USER!,
|
|
66
|
+
password: process.env.CLICKHOUSE_PASSWORD ?? '',
|
|
67
|
+
database: process.env.CLICKHOUSE_DATABASE!,
|
|
86
68
|
});
|
|
87
69
|
```
|
|
88
70
|
|
|
89
|
-
##
|
|
90
|
-
|
|
91
|
-
Add it to your npm scripts:
|
|
92
|
-
|
|
93
|
-
```json
|
|
94
|
-
{
|
|
95
|
-
"scripts": {
|
|
96
|
-
"generate-types": "hypequery-generate-types ./src/types/db-schema.ts",
|
|
97
|
-
"prebuild": "npm run generate-types",
|
|
98
|
-
"build": "tsc"
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
## Troubleshooting
|
|
104
|
-
|
|
105
|
-
If you encounter issues:
|
|
71
|
+
## Docs
|
|
106
72
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- Check your firewall settings
|
|
73
|
+
- [Quick start](https://hypequery.com/docs/quick-start)
|
|
74
|
+
- [CLI reference](https://hypequery.com/docs/reference/api/cli)
|
|
110
75
|
|
|
111
|
-
|
|
112
|
-
- Verify your username and password
|
|
113
|
-
- Ensure the user has sufficient permissions
|
|
76
|
+
## License
|
|
114
77
|
|
|
115
|
-
|
|
116
|
-
- Confirm you're connecting to the correct database
|
|
117
|
-
- Verify the tables exist in your ClickHouse instance
|
|
118
|
-
|
|
119
|
-
For more help, run:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
npx hypequery-generate-types --help
|
|
123
|
-
```
|
|
78
|
+
Apache-2.0.
|
package/README.md
CHANGED
|
@@ -1,321 +1,152 @@
|
|
|
1
|
-
|
|
2
|
-
<h1>@hypequery/clickhouse</h1>
|
|
3
|
-
<p>A TypeScript-first query builder for ClickHouse and the foundation of the hypequery path.</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>
|
|
1
|
+
# @hypequery/clickhouse
|
|
9
2
|
|
|
3
|
+
Typed ClickHouse query builder for hypequery.
|
|
10
4
|
|
|
11
|
-
|
|
5
|
+
Use it when you want schema-aware queries, typed results, and a fluent API that stays close to how ClickHouse actually works.
|
|
12
6
|
|
|
13
|
-
|
|
7
|
+
## Install
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
Node:
|
|
16
10
|
|
|
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
11
|
```bash
|
|
30
12
|
npm install @hypequery/clickhouse
|
|
31
13
|
```
|
|
32
14
|
|
|
33
|
-
|
|
15
|
+
Browser or shared client setup:
|
|
16
|
+
|
|
34
17
|
```bash
|
|
35
18
|
npm install @hypequery/clickhouse @clickhouse/client-web
|
|
36
19
|
```
|
|
37
20
|
|
|
38
|
-
|
|
39
|
-
- **Manual injection**: Explicitly provide a client instance (required for browser environments)
|
|
40
|
-
- **Auto-detection**: Automatically selects the client for Node.js environments
|
|
21
|
+
`url` is the preferred connection field. `host` is still supported as a deprecated alias.
|
|
41
22
|
|
|
42
23
|
## Quick Start
|
|
43
24
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
1. Generate schema types
|
|
47
|
-
2. Create a typed `db` with `createQueryBuilder(...)`
|
|
48
|
-
3. Build and execute queries locally
|
|
49
|
-
4. Add `@hypequery/serve` later if a query needs a reusable contract or HTTP surface
|
|
50
|
-
|
|
51
|
-
### Node.js Environments
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
25
|
+
```ts
|
|
54
26
|
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
55
|
-
import type { IntrospectedSchema } from './
|
|
27
|
+
import type { IntrospectedSchema } from './analytics/schema.js';
|
|
56
28
|
|
|
57
|
-
// Initialize the query builder
|
|
58
29
|
const db = createQueryBuilder<IntrospectedSchema>({
|
|
59
|
-
|
|
60
|
-
username:
|
|
61
|
-
password: '
|
|
62
|
-
database:
|
|
30
|
+
url: process.env.CLICKHOUSE_URL!,
|
|
31
|
+
username: process.env.CLICKHOUSE_USERNAME!,
|
|
32
|
+
password: process.env.CLICKHOUSE_PASSWORD ?? '',
|
|
33
|
+
database: process.env.CLICKHOUSE_DATABASE!,
|
|
63
34
|
});
|
|
64
35
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
.
|
|
68
|
-
.
|
|
69
|
-
.
|
|
70
|
-
.
|
|
71
|
-
.limit(10)
|
|
36
|
+
const recentOrders = await db
|
|
37
|
+
.table('orders')
|
|
38
|
+
.select(['id', 'user_id', 'total', 'created_at'])
|
|
39
|
+
.where('created_at', 'gte', '2026-01-01')
|
|
40
|
+
.orderBy('created_at', 'DESC')
|
|
41
|
+
.limit(20)
|
|
72
42
|
.execute();
|
|
73
43
|
```
|
|
74
44
|
|
|
75
|
-
|
|
45
|
+
## Main Path
|
|
76
46
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
47
|
+
1. Generate schema types with the CLI
|
|
48
|
+
2. Create a typed `db`
|
|
49
|
+
3. Write and execute queries locally
|
|
50
|
+
4. Promote important queries into `@hypequery/serve` when they need a shared contract or HTTP surface
|
|
81
51
|
|
|
82
|
-
|
|
83
|
-
const client = createClient({
|
|
84
|
-
host: 'your-clickhouse-host',
|
|
85
|
-
username: 'default',
|
|
86
|
-
password: '',
|
|
87
|
-
database: 'default'
|
|
88
|
-
});
|
|
52
|
+
## Common Patterns
|
|
89
53
|
|
|
90
|
-
|
|
91
|
-
const db = createQueryBuilder<IntrospectedSchema>({
|
|
92
|
-
client // Explicitly provide the client
|
|
93
|
-
});
|
|
54
|
+
### Aggregation
|
|
94
55
|
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
.table('
|
|
98
|
-
.select(['
|
|
99
|
-
.
|
|
100
|
-
.
|
|
101
|
-
.
|
|
56
|
+
```ts
|
|
57
|
+
const revenueByRegion = await db
|
|
58
|
+
.table('orders')
|
|
59
|
+
.select(['region'])
|
|
60
|
+
.sum('total', 'revenue')
|
|
61
|
+
.groupBy('region')
|
|
62
|
+
.orderBy('revenue', 'DESC')
|
|
102
63
|
.execute();
|
|
103
64
|
```
|
|
104
65
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
The query builder can cache results with deterministic keys, stale-while-revalidate behavior, and pluggable providers.
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
import { createQueryBuilder, MemoryCacheProvider } from '@hypequery/clickhouse';
|
|
111
|
-
|
|
112
|
-
const db = createQueryBuilder<IntrospectedSchema>({
|
|
113
|
-
host: 'your-clickhouse-host',
|
|
114
|
-
username: 'default',
|
|
115
|
-
password: '',
|
|
116
|
-
database: 'default',
|
|
117
|
-
cache: {
|
|
118
|
-
mode: 'stale-while-revalidate',
|
|
119
|
-
ttlMs: 2_000,
|
|
120
|
-
staleTtlMs: 30_000,
|
|
121
|
-
provider: new MemoryCacheProvider({ maxEntries: 5_000 })
|
|
122
|
-
}
|
|
123
|
-
});
|
|
66
|
+
### Joins
|
|
124
67
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
.
|
|
128
|
-
.
|
|
129
|
-
.
|
|
68
|
+
```ts
|
|
69
|
+
const ordersWithUsers = await db
|
|
70
|
+
.table('orders')
|
|
71
|
+
.innerJoin('users', 'user_id', 'users.id')
|
|
72
|
+
.select(['orders.id', 'users.email', 'orders.total'])
|
|
73
|
+
.where('users.status', 'eq', 'active')
|
|
130
74
|
.execute();
|
|
131
|
-
|
|
132
|
-
// Programmatic invalidation
|
|
133
|
-
await db.cache.invalidateTags(['users']);
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
Use `.cache()` to attach defaults to a fluent chain, pass `execute({ cache: { ... } })` for one-off overrides, or call `db.cache.*` for manual invalidation. For a deep dive on cache modes, invalidation, advanced serialization, and bring-your-own-provider recipes (Redis/Upstash, compression, etc.), see the [Caching guide](https://hypequery.com/docs/caching).
|
|
137
|
-
|
|
138
|
-
## Schema Generation
|
|
139
|
-
|
|
140
|
-
Use the hypequery CLI to generate TypeScript types from your ClickHouse schema:
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
npm install -D @hypequery/cli
|
|
144
|
-
npx hypequery generate
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
This creates a `generated-schema.ts` file that you can import in your application:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
151
|
-
import type { IntrospectedSchema } from './generated-schema';
|
|
152
|
-
|
|
153
|
-
const db = createQueryBuilder<IntrospectedSchema>({
|
|
154
|
-
// connection details
|
|
155
|
-
});
|
|
156
75
|
```
|
|
157
76
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
### Type-Safe Queries
|
|
161
|
-
|
|
162
|
-
hypequery provides full TypeScript support, ensuring your queries are type-safe:
|
|
77
|
+
### ClickHouse-specific features
|
|
163
78
|
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
.select(['
|
|
168
|
-
.
|
|
79
|
+
```ts
|
|
80
|
+
const topProductsPerCategory = await db
|
|
81
|
+
.table('products')
|
|
82
|
+
.select(['category', 'id', 'score'])
|
|
83
|
+
.orderBy('score', 'DESC')
|
|
84
|
+
.limitBy(3, 'category')
|
|
169
85
|
.execute();
|
|
170
|
-
|
|
171
|
-
// Type error if column doesn't exist
|
|
172
|
-
db.table('trips').select(['non_existent_column']); // TypeScript error
|
|
173
86
|
```
|
|
174
87
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
import { CrossFilter } from '@hypequery/clickhouse';
|
|
181
|
-
|
|
182
|
-
// Create a filter
|
|
183
|
-
const filter = new CrossFilter()
|
|
184
|
-
.add({
|
|
185
|
-
column: 'pickup_datetime',
|
|
186
|
-
operator: 'gte',
|
|
187
|
-
value: '2024-01-01'
|
|
188
|
-
})
|
|
189
|
-
.add({
|
|
190
|
-
column: 'total_amount',
|
|
191
|
-
operator: 'gt',
|
|
192
|
-
value: 20
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// Apply to multiple queries
|
|
196
|
-
const query1 = db.table('trips')
|
|
197
|
-
.applyCrossFilters(filter)
|
|
198
|
-
.execute();
|
|
199
|
-
|
|
200
|
-
const query2 = db.table('drivers')
|
|
201
|
-
.applyCrossFilters(filter)
|
|
88
|
+
```ts
|
|
89
|
+
const explodedTags = await db
|
|
90
|
+
.table('products')
|
|
91
|
+
.select(['id', 'tags'])
|
|
92
|
+
.arrayJoin('tags')
|
|
202
93
|
.execute();
|
|
203
94
|
```
|
|
204
95
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
hypequery supports complex queries including joins, aggregations, and subqueries:
|
|
96
|
+
`arrayJoin()` and `leftArrayJoin()` only accept array-typed columns.
|
|
208
97
|
|
|
209
|
-
|
|
210
|
-
// Aggregations
|
|
211
|
-
const stats = await db.table('trips')
|
|
212
|
-
.avg('total_amount')
|
|
213
|
-
.max('trip_distance')
|
|
214
|
-
.count('trip_id')
|
|
215
|
-
.where('pickup_datetime', 'gte', '2024-01-01')
|
|
216
|
-
.execute();
|
|
98
|
+
## Browser Use
|
|
217
99
|
|
|
218
|
-
|
|
219
|
-
const tripsWithDrivers = await db.table('trips')
|
|
220
|
-
.select(['trips.trip_id', 'trips.total_amount', 'drivers.name'])
|
|
221
|
-
.join('drivers', 'trips.driver_id', 'drivers.id')
|
|
222
|
-
.execute();
|
|
100
|
+
In browser environments, create the ClickHouse client explicitly and inject it:
|
|
223
101
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
.where('users.email', 'like', '%@example.com')
|
|
229
|
-
.execute();
|
|
230
|
-
|
|
231
|
-
// Keep literal column inference with selectConst and reuse joined columns in ORDER BY / HAVING
|
|
232
|
-
const sortedTrips = await db.table('trips')
|
|
233
|
-
.innerJoin('users', 'trips.user_id', 'users.id')
|
|
234
|
-
.selectConst('users.email', 'trips.trip_id')
|
|
235
|
-
.groupBy(['users.email', 'trips.trip_id'])
|
|
236
|
-
.having('COUNT(*) > 1')
|
|
237
|
-
.orderBy('users.email', 'DESC')
|
|
238
|
-
.execute();
|
|
239
|
-
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
`selectConst()` preserves literal column names (including aliases like `users.email`), which means TypeScript keeps those identifiers available for downstream `orderBy`, `groupBy`, and `having` calls.
|
|
243
|
-
|
|
244
|
-
**Benefits:**
|
|
245
|
-
- ✅ Works in all environments (Node.js, browser, bundlers)
|
|
246
|
-
- ✅ Explicit control over client configuration
|
|
247
|
-
- ✅ Required for browser environments (require() doesn't work in browsers)
|
|
248
|
-
- ✅ Synchronous API throughout
|
|
102
|
+
```ts
|
|
103
|
+
import { createClient } from '@clickhouse/client-web';
|
|
104
|
+
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
105
|
+
import type { IntrospectedSchema } from './analytics/schema.js';
|
|
249
106
|
|
|
250
|
-
|
|
107
|
+
const client = createClient({
|
|
108
|
+
url: process.env.NEXT_PUBLIC_CLICKHOUSE_URL!,
|
|
109
|
+
username: process.env.NEXT_PUBLIC_CLICKHOUSE_USERNAME!,
|
|
110
|
+
password: process.env.NEXT_PUBLIC_CLICKHOUSE_PASSWORD ?? '',
|
|
111
|
+
database: process.env.NEXT_PUBLIC_CLICKHOUSE_DATABASE!,
|
|
112
|
+
});
|
|
251
113
|
|
|
252
|
-
```typescript
|
|
253
114
|
const db = createQueryBuilder<IntrospectedSchema>({
|
|
254
|
-
|
|
255
|
-
username: 'default',
|
|
256
|
-
password: '',
|
|
257
|
-
database: 'default'
|
|
115
|
+
client,
|
|
258
116
|
});
|
|
259
117
|
```
|
|
260
118
|
|
|
119
|
+
## Schema Generation
|
|
261
120
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
Run the fast feedback loop with:
|
|
121
|
+
The usual path is through the CLI:
|
|
265
122
|
|
|
266
123
|
```bash
|
|
267
|
-
npm
|
|
124
|
+
npm install -D @hypequery/cli
|
|
125
|
+
npx hypequery generate
|
|
268
126
|
```
|
|
269
127
|
|
|
270
|
-
|
|
128
|
+
The package also ships the lower-level generator binary:
|
|
271
129
|
|
|
272
130
|
```bash
|
|
273
|
-
|
|
131
|
+
npx hypequery-generate-types
|
|
274
132
|
```
|
|
275
133
|
|
|
276
|
-
|
|
134
|
+
More details: [README-CLI.md](./README-CLI.md)
|
|
277
135
|
|
|
278
|
-
|
|
136
|
+
## Useful Exports
|
|
279
137
|
|
|
280
|
-
-
|
|
281
|
-
-
|
|
138
|
+
- SQL helpers like `raw`, `rawAs`, `selectExpr`, and `toDateTime`
|
|
139
|
+
- exported time helpers like `toStartOfMinute`, `toStartOfHour`, `toStartOfDay`, `toStartOfWeek`, `toStartOfMonth`, `toStartOfQuarter`, and `toStartOfYear`
|
|
140
|
+
- cache primitives like `MemoryCacheProvider`
|
|
282
141
|
|
|
283
|
-
##
|
|
142
|
+
## Docs
|
|
284
143
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
- [Quick Start](https://hypequery.com/docs/quick-start)
|
|
288
|
-
- [Core Concepts](https://hypequery.com/docs/core-concepts)
|
|
289
|
-
- [Query Building](https://hypequery.com/docs/query-building/basics)
|
|
144
|
+
- [Query builder basics](https://hypequery.com/docs/query-building/basics)
|
|
290
145
|
- [Filtering](https://hypequery.com/docs/query-building/where)
|
|
291
|
-
- [
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
## Troubleshooting
|
|
295
|
-
|
|
296
|
-
### Common Issues
|
|
297
|
-
|
|
298
|
-
- **Connection Errors**: Ensure your ClickHouse server is running and accessible
|
|
299
|
-
- **CORS Issues**: Use a proxy server for browser environments
|
|
300
|
-
- **Type Errors**: Make sure to regenerate your schema types after schema changes
|
|
301
|
-
- **Client Not Found**: Make sure you have installed at least one of the required peer dependencies:
|
|
302
|
-
- `@clickhouse/client` (for Node.js environments)
|
|
303
|
-
- `@clickhouse/client-web` (for browser/universal environments)
|
|
304
|
-
- **Browser Auto-Detection**: Auto-detection doesn't work in browsers because `require()` calls don't work. Use manual injection instead.
|
|
305
|
-
|
|
146
|
+
- [Joins](https://hypequery.com/docs/query-building/joins)
|
|
147
|
+
- [Aggregation](https://hypequery.com/docs/query-building/aggregation)
|
|
148
|
+
- [Connection reference](https://hypequery.com/docs/reference/connection)
|
|
306
149
|
|
|
307
150
|
## License
|
|
308
151
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
## Support
|
|
312
|
-
|
|
313
|
-
- 📚 [Documentation](https://hypequery.com/docs)
|
|
314
|
-
- 🐛 [Issue Tracker](https://github.com/hypequery/hypequery/issues)
|
|
315
|
-
- 💬 [Discussions](https://github.com/hypequery/hypequery/discussions)
|
|
316
|
-
|
|
317
|
-
---
|
|
318
|
-
|
|
319
|
-
<div align="center">
|
|
320
|
-
<sub>Built with ❤️ by the hypequery team</sub>
|
|
321
|
-
</div>
|
|
152
|
+
Apache-2.0.
|
package/dist/cli/bin.js
CHANGED
|
@@ -41,7 +41,8 @@ ${colors.bright}Usage:${colors.reset}
|
|
|
41
41
|
|
|
42
42
|
${colors.bright}Options:${colors.reset}
|
|
43
43
|
--output=<path> Path where TypeScript definitions will be saved (default: "./generated-schema.ts")
|
|
44
|
-
--
|
|
44
|
+
--url=<url> ClickHouse server URL (default: http://localhost:8123)
|
|
45
|
+
--host=<url> Deprecated alias for --url
|
|
45
46
|
--username=<user> ClickHouse username (default: default)
|
|
46
47
|
--password=<password> ClickHouse password
|
|
47
48
|
--database=<db> ClickHouse database name (default: default)
|
|
@@ -53,9 +54,12 @@ ${colors.bright}Options:${colors.reset}
|
|
|
53
54
|
${colors.dim}Note: All options support both formats: --option=value or --option value${colors.reset}
|
|
54
55
|
|
|
55
56
|
${colors.bright}Environment variables:${colors.reset}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
CLICKHOUSE_URL ClickHouse server URL
|
|
58
|
+
VITE_CLICKHOUSE_URL Alternative variable for Vite projects
|
|
59
|
+
NEXT_PUBLIC_CLICKHOUSE_URL Alternative variable for Next.js projects
|
|
60
|
+
CLICKHOUSE_HOST Deprecated alternative
|
|
61
|
+
VITE_CLICKHOUSE_HOST Deprecated alternative for Vite projects
|
|
62
|
+
NEXT_PUBLIC_CLICKHOUSE_HOST Deprecated alternative for Next.js projects
|
|
59
63
|
|
|
60
64
|
CLICKHOUSE_USER ClickHouse username
|
|
61
65
|
VITE_CLICKHOUSE_USER Alternative variable for Vite projects
|
|
@@ -73,8 +77,8 @@ ${colors.bright}Examples:${colors.reset}
|
|
|
73
77
|
npx hypequery-generate-types
|
|
74
78
|
npx hypequery-generate-types --output=./src/types/db-schema.ts
|
|
75
79
|
npx hypequery-generate-types --output ./src/types/db-schema.ts
|
|
76
|
-
npx hypequery-generate-types --
|
|
77
|
-
npx hypequery-generate-types --
|
|
80
|
+
npx hypequery-generate-types --url=https://your-instance.clickhouse.cloud:8443 --secure
|
|
81
|
+
npx hypequery-generate-types --url http://localhost:8123 --username default --password password --database my_db
|
|
78
82
|
npx hypequery-generate-types --include-tables=users,orders,products
|
|
79
83
|
npx hypequery-generate-types --include-tables users,orders,products
|
|
80
84
|
`);
|
|
@@ -107,6 +111,7 @@ function parseArguments(args) {
|
|
|
107
111
|
// Parameter handlers map
|
|
108
112
|
const paramHandlers = {
|
|
109
113
|
'--output': (value) => config.output = value,
|
|
114
|
+
'--url': (value) => config.host = value,
|
|
110
115
|
'--host': (value) => config.host = value,
|
|
111
116
|
'--username': (value) => config.username = value,
|
|
112
117
|
'--password': (value) => config.password = value,
|
|
@@ -176,6 +181,9 @@ async function main() {
|
|
|
176
181
|
try {
|
|
177
182
|
// Get connection parameters from args and environment variables
|
|
178
183
|
const host = config.host ||
|
|
184
|
+
process.env.CLICKHOUSE_URL ||
|
|
185
|
+
process.env.VITE_CLICKHOUSE_URL ||
|
|
186
|
+
process.env.NEXT_PUBLIC_CLICKHOUSE_URL ||
|
|
179
187
|
process.env.CLICKHOUSE_HOST ||
|
|
180
188
|
process.env.VITE_CLICKHOUSE_HOST ||
|
|
181
189
|
process.env.NEXT_PUBLIC_CLICKHOUSE_HOST ||
|
|
@@ -237,7 +245,7 @@ import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
|
237
245
|
import { IntrospectedSchema } from '${config.output.replace(/\.ts$/, '')}';
|
|
238
246
|
|
|
239
247
|
const db = createQueryBuilder<IntrospectedSchema>({
|
|
240
|
-
|
|
248
|
+
url: '${host}',
|
|
241
249
|
username: '${username}',
|
|
242
250
|
password: '********',
|
|
243
251
|
database: '${database}'
|
|
@@ -282,4 +290,4 @@ ${colors.yellow}SSL/TLS certificate issue.${colors.reset} For secure connections
|
|
|
282
290
|
}
|
|
283
291
|
|
|
284
292
|
// Execute the main function
|
|
285
|
-
main();
|
|
293
|
+
main();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clickhouse-adapter.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/clickhouse-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"clickhouse-adapter.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/clickhouse-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA4B5D,qBAAa,iBAAkB,YAAW,eAAe;IAK3C,OAAO,CAAC,MAAM;IAJ1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,MAAM,CAAmB;gBAEb,MAAM,EAAE,gBAAgB;IAKtC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAW5F,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,EAAE,OAAO,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;IAYnH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,MAAM;CAGpD;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CAEjF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isClientConfig } from '../query-builder.js';
|
|
2
2
|
import { substituteParameters } from '../utils.js';
|
|
3
|
+
import { getConnectionEndpoint } from '../utils/connection-endpoint.js';
|
|
3
4
|
import { createJsonEachRowStream } from '../utils/streaming-helpers.js';
|
|
4
5
|
import { getAutoClientModule } from '../env/auto-client.js';
|
|
5
6
|
function createClickHouseClient(config) {
|
|
@@ -13,10 +14,10 @@ function deriveNamespace(config) {
|
|
|
13
14
|
if ('client' in config && config.client) {
|
|
14
15
|
return 'client';
|
|
15
16
|
}
|
|
16
|
-
const
|
|
17
|
+
const endpoint = getConnectionEndpoint(config);
|
|
17
18
|
const database = 'database' in config ? config.database : 'default';
|
|
18
19
|
const username = 'username' in config ? config.username : 'default';
|
|
19
|
-
return `${
|
|
20
|
+
return `${endpoint || 'unknown-host'}|${database || 'default'}|${username || 'default'}`;
|
|
20
21
|
}
|
|
21
22
|
export class ClickHouseAdapter {
|
|
22
23
|
config;
|