@hypequery/clickhouse 0.0.0-canary-20260306132943
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/LICENSE +201 -0
- package/README-CLI.md +123 -0
- package/README.md +316 -0
- package/dist/cli/bin.js +285 -0
- package/dist/cli/generate-types.d.ts +5 -0
- package/dist/cli/generate-types.js +218 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +2 -0
- package/dist/core/cache/cache-manager.d.ts +4 -0
- package/dist/core/cache/cache-manager.d.ts.map +1 -0
- package/dist/core/cache/cache-manager.js +176 -0
- package/dist/core/cache/controller.d.ts +15 -0
- package/dist/core/cache/controller.d.ts.map +1 -0
- package/dist/core/cache/controller.js +58 -0
- package/dist/core/cache/key.d.ts +11 -0
- package/dist/core/cache/key.d.ts.map +1 -0
- package/dist/core/cache/key.js +26 -0
- package/dist/core/cache/providers/memory-lru.d.ts +31 -0
- package/dist/core/cache/providers/memory-lru.d.ts.map +1 -0
- package/dist/core/cache/providers/memory-lru.js +156 -0
- package/dist/core/cache/providers/noop.d.ts +7 -0
- package/dist/core/cache/providers/noop.d.ts.map +1 -0
- package/dist/core/cache/providers/noop.js +11 -0
- package/dist/core/cache/runtime-context.d.ts +30 -0
- package/dist/core/cache/runtime-context.d.ts.map +1 -0
- package/dist/core/cache/runtime-context.js +58 -0
- package/dist/core/cache/serialization.d.ts +6 -0
- package/dist/core/cache/serialization.d.ts.map +1 -0
- package/dist/core/cache/serialization.js +166 -0
- package/dist/core/cache/types.d.ts +52 -0
- package/dist/core/cache/types.d.ts.map +1 -0
- package/dist/core/cache/types.js +1 -0
- package/dist/core/cache/utils.d.ts +9 -0
- package/dist/core/cache/utils.d.ts.map +1 -0
- package/dist/core/cache/utils.js +30 -0
- package/dist/core/connection.d.ts +112 -0
- package/dist/core/connection.d.ts.map +1 -0
- package/dist/core/connection.js +150 -0
- package/dist/core/cross-filter.d.ts +73 -0
- package/dist/core/cross-filter.d.ts.map +1 -0
- package/dist/core/cross-filter.js +142 -0
- package/dist/core/env/auto-client.browser.d.ts +3 -0
- package/dist/core/env/auto-client.browser.d.ts.map +1 -0
- package/dist/core/env/auto-client.browser.js +3 -0
- package/dist/core/env/auto-client.d.ts +9 -0
- package/dist/core/env/auto-client.d.ts.map +1 -0
- package/dist/core/env/auto-client.js +21 -0
- package/dist/core/features/aggregations.d.ts +98 -0
- package/dist/core/features/aggregations.d.ts.map +1 -0
- package/dist/core/features/aggregations.js +36 -0
- package/dist/core/features/analytics.d.ts +81 -0
- package/dist/core/features/analytics.d.ts.map +1 -0
- package/dist/core/features/analytics.js +45 -0
- package/dist/core/features/cross-filtering.d.ts +11 -0
- package/dist/core/features/cross-filtering.d.ts.map +1 -0
- package/dist/core/features/cross-filtering.js +90 -0
- package/dist/core/features/executor.d.ts +21 -0
- package/dist/core/features/executor.d.ts.map +1 -0
- package/dist/core/features/executor.js +146 -0
- package/dist/core/features/filtering.d.ts +99 -0
- package/dist/core/features/filtering.d.ts.map +1 -0
- package/dist/core/features/filtering.js +118 -0
- package/dist/core/features/joins.d.ts +26 -0
- package/dist/core/features/joins.d.ts.map +1 -0
- package/dist/core/features/joins.js +17 -0
- package/dist/core/features/query-modifiers.d.ts +116 -0
- package/dist/core/features/query-modifiers.d.ts.map +1 -0
- package/dist/core/features/query-modifiers.js +51 -0
- package/dist/core/formatters/sql-formatter.d.ts +9 -0
- package/dist/core/formatters/sql-formatter.d.ts.map +1 -0
- package/dist/core/formatters/sql-formatter.js +131 -0
- package/dist/core/join-relationships.d.ts +51 -0
- package/dist/core/join-relationships.d.ts.map +1 -0
- package/dist/core/join-relationships.js +54 -0
- package/dist/core/query-builder.d.ts +236 -0
- package/dist/core/query-builder.d.ts.map +1 -0
- package/dist/core/query-builder.js +495 -0
- package/dist/core/tests/index.d.ts +2 -0
- package/dist/core/tests/index.d.ts.map +1 -0
- package/dist/core/tests/index.js +1 -0
- package/dist/core/tests/integration/setup.d.ts +48 -0
- package/dist/core/tests/integration/setup.d.ts.map +1 -0
- package/dist/core/tests/integration/setup.js +349 -0
- package/dist/core/tests/integration/test-config.d.ts +15 -0
- package/dist/core/tests/integration/test-config.d.ts.map +1 -0
- package/dist/core/tests/integration/test-config.js +14 -0
- package/dist/core/tests/integration/test-data.json +190 -0
- package/dist/core/tests/test-utils.d.ts +44 -0
- package/dist/core/tests/test-utils.d.ts.map +1 -0
- package/dist/core/tests/test-utils.js +65 -0
- package/dist/core/types/builder-state.d.ts +27 -0
- package/dist/core/types/builder-state.d.ts.map +1 -0
- package/dist/core/types/builder-state.js +1 -0
- package/dist/core/types/select-types.d.ts +33 -0
- package/dist/core/types/select-types.d.ts.map +1 -0
- package/dist/core/types/select-types.js +1 -0
- package/dist/core/types/type-helpers.d.ts +5 -0
- package/dist/core/types/type-helpers.d.ts.map +1 -0
- package/dist/core/types/type-helpers.js +1 -0
- package/dist/core/utils/logger.d.ts +43 -0
- package/dist/core/utils/logger.d.ts.map +1 -0
- package/dist/core/utils/logger.js +104 -0
- package/dist/core/utils/predicate-builder.d.ts +33 -0
- package/dist/core/utils/predicate-builder.d.ts.map +1 -0
- package/dist/core/utils/predicate-builder.js +95 -0
- package/dist/core/utils/sql-expressions.d.ts +77 -0
- package/dist/core/utils/sql-expressions.d.ts.map +1 -0
- package/dist/core/utils/sql-expressions.js +54 -0
- package/dist/core/utils/streaming-helpers.d.ts +2 -0
- package/dist/core/utils/streaming-helpers.d.ts.map +1 -0
- package/dist/core/utils/streaming-helpers.js +137 -0
- package/dist/core/utils.d.ts +3 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +29 -0
- package/dist/core/validators/filter-validator.d.ts +9 -0
- package/dist/core/validators/filter-validator.d.ts.map +1 -0
- package/dist/core/validators/filter-validator.js +19 -0
- package/dist/core/validators/value-validator.d.ts +7 -0
- package/dist/core/validators/value-validator.d.ts.map +1 -0
- package/dist/core/validators/value-validator.js +47 -0
- package/dist/formatters/index.d.ts +2 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/types/base.d.ts +50 -0
- package/dist/types/base.d.ts.map +1 -0
- package/dist/types/base.js +1 -0
- package/dist/types/clickhouse-types.d.ts +17 -0
- package/dist/types/clickhouse-types.d.ts.map +1 -0
- package/dist/types/clickhouse-types.js +1 -0
- package/dist/types/filters.d.ts +53 -0
- package/dist/types/filters.d.ts.map +1 -0
- package/dist/types/filters.js +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/schema.d.ts +19 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +1 -0
- package/package.json +90 -0
package/dist/cli/bin.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { ClickHouseConnection } from '../core/connection.js';
|
|
4
|
+
import { generateTypes } from './generate-types.js';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import dotenv from 'dotenv';
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
|
|
9
|
+
// Load environment variables from the current directory
|
|
10
|
+
dotenv.config();
|
|
11
|
+
|
|
12
|
+
// ANSI color codes for prettier output
|
|
13
|
+
const colors = {
|
|
14
|
+
reset: '\x1b[0m',
|
|
15
|
+
bright: '\x1b[1m',
|
|
16
|
+
dim: '\x1b[2m',
|
|
17
|
+
green: '\x1b[32m',
|
|
18
|
+
yellow: '\x1b[33m',
|
|
19
|
+
blue: '\x1b[34m',
|
|
20
|
+
red: '\x1b[31m',
|
|
21
|
+
cyan: '\x1b[36m'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Display a colorful banner with the tool name
|
|
26
|
+
*/
|
|
27
|
+
function showBanner() {
|
|
28
|
+
console.log(`
|
|
29
|
+
${colors.bright}${colors.cyan}hypequery TypeScript Generator${colors.reset}
|
|
30
|
+
${colors.dim}Generate TypeScript types from your ClickHouse database schema${colors.reset}
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Show help information for the CLI
|
|
36
|
+
*/
|
|
37
|
+
function showHelp() {
|
|
38
|
+
console.log(`
|
|
39
|
+
${colors.bright}Usage:${colors.reset}
|
|
40
|
+
npx hypequery-generate-types [options]
|
|
41
|
+
|
|
42
|
+
${colors.bright}Options:${colors.reset}
|
|
43
|
+
--output=<path> Path where TypeScript definitions will be saved (default: "./generated-schema.ts")
|
|
44
|
+
--host=<url> ClickHouse server URL (default: http://localhost:8123)
|
|
45
|
+
--username=<user> ClickHouse username (default: default)
|
|
46
|
+
--password=<password> ClickHouse password
|
|
47
|
+
--database=<db> ClickHouse database name (default: default)
|
|
48
|
+
--include-tables=<tables> Comma-separated list of tables to include (default: all)
|
|
49
|
+
--exclude-tables=<tables> Comma-separated list of tables to exclude (default: none)
|
|
50
|
+
--secure Use HTTPS/TLS for connection
|
|
51
|
+
--help, -h Show this help text
|
|
52
|
+
|
|
53
|
+
${colors.dim}Note: All options support both formats: --option=value or --option value${colors.reset}
|
|
54
|
+
|
|
55
|
+
${colors.bright}Environment variables:${colors.reset}
|
|
56
|
+
CLICKHOUSE_HOST ClickHouse server URL
|
|
57
|
+
VITE_CLICKHOUSE_HOST Alternative variable for Vite projects
|
|
58
|
+
NEXT_PUBLIC_CLICKHOUSE_HOST Alternative variable for Next.js projects
|
|
59
|
+
|
|
60
|
+
CLICKHOUSE_USER ClickHouse username
|
|
61
|
+
VITE_CLICKHOUSE_USER Alternative variable for Vite projects
|
|
62
|
+
NEXT_PUBLIC_CLICKHOUSE_USER Alternative variable for Next.js projects
|
|
63
|
+
|
|
64
|
+
CLICKHOUSE_PASSWORD ClickHouse password
|
|
65
|
+
VITE_CLICKHOUSE_PASSWORD Alternative variable for Vite projects
|
|
66
|
+
NEXT_PUBLIC_CLICKHOUSE_PASSWORD Alternative variable for Next.js projects
|
|
67
|
+
|
|
68
|
+
CLICKHOUSE_DATABASE ClickHouse database name
|
|
69
|
+
VITE_CLICKHOUSE_DATABASE Alternative variable for Vite projects
|
|
70
|
+
NEXT_PUBLIC_CLICKHOUSE_DATABASE Alternative variable for Next.js projects
|
|
71
|
+
|
|
72
|
+
${colors.bright}Examples:${colors.reset}
|
|
73
|
+
npx hypequery-generate-types
|
|
74
|
+
npx hypequery-generate-types --output=./src/types/db-schema.ts
|
|
75
|
+
npx hypequery-generate-types --output ./src/types/db-schema.ts
|
|
76
|
+
npx hypequery-generate-types --host=https://your-instance.clickhouse.cloud:8443 --secure
|
|
77
|
+
npx hypequery-generate-types --host http://localhost:8123 --username default --password password --database my_db
|
|
78
|
+
npx hypequery-generate-types --include-tables=users,orders,products
|
|
79
|
+
npx hypequery-generate-types --include-tables users,orders,products
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Parse command line arguments into a configuration object
|
|
85
|
+
*/
|
|
86
|
+
function parseArguments(args) {
|
|
87
|
+
const config = {
|
|
88
|
+
output: './generated-schema.ts',
|
|
89
|
+
includeTables: [],
|
|
90
|
+
excludeTables: [],
|
|
91
|
+
secure: false
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Helper function to extract value from --param=value format
|
|
95
|
+
function getParamValue(arg, paramName) {
|
|
96
|
+
if (arg.startsWith(`${paramName}=`)) {
|
|
97
|
+
return arg.substring(paramName.length + 1); // +1 for the '=' character
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Helper function to get next argument as value
|
|
103
|
+
function getNextArgValue(args, index) {
|
|
104
|
+
return args[index + 1];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Parameter handlers map
|
|
108
|
+
const paramHandlers = {
|
|
109
|
+
'--output': (value) => config.output = value,
|
|
110
|
+
'--host': (value) => config.host = value,
|
|
111
|
+
'--username': (value) => config.username = value,
|
|
112
|
+
'--password': (value) => config.password = value,
|
|
113
|
+
'--database': (value) => config.database = value,
|
|
114
|
+
'--include-tables': (value) => config.includeTables = value.split(','),
|
|
115
|
+
'--exclude-tables': (value) => config.excludeTables = value.split(',')
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < args.length; i++) {
|
|
119
|
+
const arg = args[i];
|
|
120
|
+
let handled = false;
|
|
121
|
+
|
|
122
|
+
// Handle parameters with values
|
|
123
|
+
for (const [paramName, handler] of Object.entries(paramHandlers)) {
|
|
124
|
+
// Check for --param=value format
|
|
125
|
+
const value = getParamValue(arg, paramName);
|
|
126
|
+
if (value !== null) {
|
|
127
|
+
handler(value);
|
|
128
|
+
handled = true;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check for --param value format
|
|
133
|
+
if (arg === paramName) {
|
|
134
|
+
const nextValue = getNextArgValue(args, i);
|
|
135
|
+
if (nextValue && !nextValue.startsWith('-')) {
|
|
136
|
+
handler(nextValue);
|
|
137
|
+
i++; // Skip the next argument since we consumed it
|
|
138
|
+
handled = true;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Handle boolean flags
|
|
145
|
+
if (!handled) {
|
|
146
|
+
if (arg === '--secure') {
|
|
147
|
+
config.secure = true;
|
|
148
|
+
} else if (arg === '--help' || arg === '-h') {
|
|
149
|
+
config.showHelp = true;
|
|
150
|
+
} else if (!arg.startsWith('-') && !config.output) {
|
|
151
|
+
// For backwards compatibility, treat the first non-flag argument as the output path
|
|
152
|
+
config.output = arg;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return config;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Main CLI function
|
|
162
|
+
*/
|
|
163
|
+
async function main() {
|
|
164
|
+
showBanner();
|
|
165
|
+
|
|
166
|
+
// Process command line arguments
|
|
167
|
+
const args = process.argv.slice(2);
|
|
168
|
+
const config = parseArguments(args);
|
|
169
|
+
|
|
170
|
+
// Check for help flag
|
|
171
|
+
if (config.showHelp) {
|
|
172
|
+
showHelp();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
// Get connection parameters from args and environment variables
|
|
178
|
+
const host = config.host ||
|
|
179
|
+
process.env.CLICKHOUSE_HOST ||
|
|
180
|
+
process.env.VITE_CLICKHOUSE_HOST ||
|
|
181
|
+
process.env.NEXT_PUBLIC_CLICKHOUSE_HOST ||
|
|
182
|
+
'http://localhost:8123';
|
|
183
|
+
|
|
184
|
+
const username = config.username ||
|
|
185
|
+
process.env.CLICKHOUSE_USER ||
|
|
186
|
+
process.env.VITE_CLICKHOUSE_USER ||
|
|
187
|
+
process.env.NEXT_PUBLIC_CLICKHOUSE_USER ||
|
|
188
|
+
'default';
|
|
189
|
+
|
|
190
|
+
const password = config.password ||
|
|
191
|
+
process.env.CLICKHOUSE_PASSWORD ||
|
|
192
|
+
process.env.VITE_CLICKHOUSE_PASSWORD ||
|
|
193
|
+
process.env.NEXT_PUBLIC_CLICKHOUSE_PASSWORD;
|
|
194
|
+
|
|
195
|
+
const database = config.database ||
|
|
196
|
+
process.env.CLICKHOUSE_DATABASE ||
|
|
197
|
+
process.env.VITE_CLICKHOUSE_DATABASE ||
|
|
198
|
+
process.env.NEXT_PUBLIC_CLICKHOUSE_DATABASE ||
|
|
199
|
+
'default';
|
|
200
|
+
|
|
201
|
+
console.log(`${colors.dim}Connecting to ClickHouse at ${colors.reset}${colors.bright}${host}${colors.reset}`);
|
|
202
|
+
console.log(`${colors.dim}Database: ${colors.reset}${colors.bright}${database}${colors.reset}`);
|
|
203
|
+
|
|
204
|
+
// Configure connection
|
|
205
|
+
const connectionConfig = {
|
|
206
|
+
host,
|
|
207
|
+
username,
|
|
208
|
+
password,
|
|
209
|
+
database,
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// Add secure connection options if needed
|
|
213
|
+
if (config.secure || host.startsWith('https://')) {
|
|
214
|
+
connectionConfig.secure = true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Initialize connection
|
|
218
|
+
ClickHouseConnection.initialize(connectionConfig);
|
|
219
|
+
|
|
220
|
+
console.log(`${colors.dim}Generating TypeScript definitions...${colors.reset}`);
|
|
221
|
+
|
|
222
|
+
// Ensure directory exists
|
|
223
|
+
const dir = path.dirname(path.resolve(config.output));
|
|
224
|
+
await fs.mkdir(dir, { recursive: true });
|
|
225
|
+
|
|
226
|
+
// Generate types
|
|
227
|
+
await generateTypes(config.output, {
|
|
228
|
+
includeTables: config.includeTables.length > 0 ? config.includeTables : undefined,
|
|
229
|
+
excludeTables: config.excludeTables.length > 0 ? config.excludeTables : undefined
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
console.log(`${colors.green}✓ Success! ${colors.reset}Types generated at ${colors.bright}${path.resolve(config.output)}${colors.reset}`);
|
|
233
|
+
console.log(`
|
|
234
|
+
${colors.dim}To use these types in your project:${colors.reset}
|
|
235
|
+
|
|
236
|
+
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
237
|
+
import { IntrospectedSchema } from '${config.output.replace(/\.ts$/, '')}';
|
|
238
|
+
|
|
239
|
+
const db = createQueryBuilder<IntrospectedSchema>({
|
|
240
|
+
host: '${host}',
|
|
241
|
+
username: '${username}',
|
|
242
|
+
password: '********',
|
|
243
|
+
database: '${database}'
|
|
244
|
+
});
|
|
245
|
+
`);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error(`${colors.red}✗ Error generating types: ${colors.reset}${error.message}`);
|
|
248
|
+
|
|
249
|
+
// Provide more helpful error messages for common issues
|
|
250
|
+
if (error.message && error.message.includes('ECONNREFUSED')) {
|
|
251
|
+
console.error(`
|
|
252
|
+
${colors.yellow}Connection refused.${colors.reset} Please check:
|
|
253
|
+
- Is ClickHouse running at the specified host?
|
|
254
|
+
- Do you need to provide authentication credentials?
|
|
255
|
+
- Are there any network/firewall restrictions?
|
|
256
|
+
- For cloud instances, did you include the port (usually 8443) and use HTTPS?
|
|
257
|
+
`);
|
|
258
|
+
} else if (error.message && error.message.includes('Authentication failed')) {
|
|
259
|
+
console.error(`
|
|
260
|
+
${colors.yellow}Authentication failed.${colors.reset} Please check:
|
|
261
|
+
- Are your username and password correct?
|
|
262
|
+
- For ClickHouse Cloud, did you use the correct credentials from your cloud dashboard?
|
|
263
|
+
- Does the user have sufficient permissions?
|
|
264
|
+
`);
|
|
265
|
+
} else if (error.message && error.message.includes('database does not exist')) {
|
|
266
|
+
console.error(`
|
|
267
|
+
${colors.yellow}Database not found.${colors.reset} Please check:
|
|
268
|
+
- Is the database name correct?
|
|
269
|
+
- Does the database exist in your ClickHouse instance?
|
|
270
|
+
`);
|
|
271
|
+
} else if (error.message && error.message.includes('certificate')) {
|
|
272
|
+
console.error(`
|
|
273
|
+
${colors.yellow}SSL/TLS certificate issue.${colors.reset} For secure connections:
|
|
274
|
+
- Try adding the --secure flag
|
|
275
|
+
- For ClickHouse Cloud, make sure you're using https:// and port 8443
|
|
276
|
+
`);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
console.error(`${colors.dim}For more information, use --help flag.${colors.reset}`);
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Execute the main function
|
|
285
|
+
main();
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { ClickHouseConnection } from '../core/connection.js';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import dotenv from 'dotenv';
|
|
5
|
+
|
|
6
|
+
// Load environment variables from the current directory
|
|
7
|
+
dotenv.config();
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} ColumnInfo
|
|
11
|
+
* @property {string} name - The name of the column
|
|
12
|
+
* @property {string} type - The ClickHouse type of the column
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} GenerateTypesOptions
|
|
17
|
+
* @property {string[]} [includeTables] - List of tables to include
|
|
18
|
+
* @property {string[]} [excludeTables] - List of tables to exclude
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Converts ClickHouse types to TypeScript types
|
|
23
|
+
* @param {string} type - The ClickHouse type to convert
|
|
24
|
+
* @returns {string} - The corresponding TypeScript type
|
|
25
|
+
*/
|
|
26
|
+
const clickhouseToTsType = (type) => {
|
|
27
|
+
if (type.startsWith('Array(')) {
|
|
28
|
+
const innerType = type.slice(6, -1);
|
|
29
|
+
return `Array<${clickhouseToTsType(innerType)}>`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Handle Nullable types
|
|
33
|
+
if (type.startsWith('Nullable(')) {
|
|
34
|
+
const innerType = type.slice(9, -1);
|
|
35
|
+
return `${clickhouseToTsType(innerType)} | null`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Handle Map types
|
|
39
|
+
if (type.startsWith('Map(')) {
|
|
40
|
+
// Extract key and value types from Map(KeyType, ValueType)
|
|
41
|
+
const mapContent = type.slice(4, -1); // Remove 'Map(' and ')'
|
|
42
|
+
const commaIndex = mapContent.lastIndexOf(',');
|
|
43
|
+
if (commaIndex !== -1) {
|
|
44
|
+
const keyType = mapContent.substring(0, commaIndex).trim();
|
|
45
|
+
const valueType = mapContent.substring(commaIndex + 1).trim();
|
|
46
|
+
|
|
47
|
+
// Handle different key types
|
|
48
|
+
let keyTsType = 'string';
|
|
49
|
+
if (keyType === 'LowCardinality(String)') {
|
|
50
|
+
keyTsType = 'string';
|
|
51
|
+
} else if (keyType.includes('Int') || keyType.includes('UInt')) {
|
|
52
|
+
keyTsType = 'number';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Handle different value types
|
|
56
|
+
let valueTsType = 'unknown';
|
|
57
|
+
if (valueType.startsWith('Array(')) {
|
|
58
|
+
const innerType = valueType.slice(6, -1);
|
|
59
|
+
valueTsType = `Array<${clickhouseToTsType(innerType)}>`;
|
|
60
|
+
} else if (valueType.startsWith('Nullable(')) {
|
|
61
|
+
const innerType = valueType.slice(9, -1);
|
|
62
|
+
valueTsType = `${clickhouseToTsType(innerType)} | null`;
|
|
63
|
+
} else {
|
|
64
|
+
valueTsType = clickhouseToTsType(valueType);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return `Record<${keyTsType}, ${valueTsType}>`;
|
|
68
|
+
}
|
|
69
|
+
return 'Record<string, unknown>';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
switch (type.toLowerCase()) {
|
|
73
|
+
case 'string':
|
|
74
|
+
case 'fixedstring':
|
|
75
|
+
return 'string';
|
|
76
|
+
case 'int8':
|
|
77
|
+
case 'int16':
|
|
78
|
+
case 'int32':
|
|
79
|
+
case 'uint8':
|
|
80
|
+
case 'int64':
|
|
81
|
+
case 'uint16':
|
|
82
|
+
case 'uint32':
|
|
83
|
+
case 'uint64':
|
|
84
|
+
return 'number';
|
|
85
|
+
case 'uint128':
|
|
86
|
+
case 'uint256':
|
|
87
|
+
case 'int128':
|
|
88
|
+
case 'int256':
|
|
89
|
+
return 'string';
|
|
90
|
+
case 'float32':
|
|
91
|
+
case 'float64':
|
|
92
|
+
case 'decimal':
|
|
93
|
+
return 'number';
|
|
94
|
+
case 'datetime':
|
|
95
|
+
case 'datetime64':
|
|
96
|
+
return 'string'; // Use string for datetime
|
|
97
|
+
case 'date':
|
|
98
|
+
case 'date32':
|
|
99
|
+
return 'string'; // Use string for date
|
|
100
|
+
case 'bool':
|
|
101
|
+
case 'boolean':
|
|
102
|
+
return 'boolean';
|
|
103
|
+
default:
|
|
104
|
+
// For complex types or unknown types, return string as a safe default
|
|
105
|
+
return 'string';
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Generates TypeScript type definitions from the ClickHouse database schema
|
|
111
|
+
* @param {string} outputPath - The file path where the type definitions will be written
|
|
112
|
+
* @param {GenerateTypesOptions} [options] - Options for type generation
|
|
113
|
+
* @returns {Promise<void>}
|
|
114
|
+
*/
|
|
115
|
+
export async function generateTypes(outputPath, options = {}) {
|
|
116
|
+
const client = ClickHouseConnection.getClient();
|
|
117
|
+
const { includeTables = [], excludeTables = [] } = options;
|
|
118
|
+
|
|
119
|
+
// Get all tables
|
|
120
|
+
const tablesQuery = await client.query({
|
|
121
|
+
query: 'SHOW TABLES',
|
|
122
|
+
format: 'JSONEachRow'
|
|
123
|
+
});
|
|
124
|
+
let tables = await tablesQuery.json();
|
|
125
|
+
|
|
126
|
+
// Filter tables if includeTables or excludeTables are specified
|
|
127
|
+
if (includeTables.length > 0) {
|
|
128
|
+
tables = tables.filter(table => includeTables.includes(table.name));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (excludeTables.length > 0) {
|
|
132
|
+
tables = tables.filter(table => !excludeTables.includes(table.name));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// If no tables remain after filtering, log a warning
|
|
136
|
+
if (tables.length === 0) {
|
|
137
|
+
console.warn('Warning: No tables match the filter criteria. Check your include/exclude options.');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let typeDefinitions = `// Generated by @hypequery/clickhouse
|
|
141
|
+
// This file defines TypeScript types based on your ClickHouse database schema
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Schema interface for use with createQueryBuilder<IntrospectedSchema>()
|
|
145
|
+
* The string literals represent ClickHouse data types for each column
|
|
146
|
+
*/
|
|
147
|
+
export interface IntrospectedSchema {`;
|
|
148
|
+
|
|
149
|
+
// Get columns for each table
|
|
150
|
+
for (const table of tables) {
|
|
151
|
+
const columnsQuery = await client.query({
|
|
152
|
+
query: `DESCRIBE TABLE ${table.name}`,
|
|
153
|
+
format: 'JSONEachRow'
|
|
154
|
+
});
|
|
155
|
+
const columns = await columnsQuery.json();
|
|
156
|
+
typeDefinitions += `\n ${table.name}: {`;
|
|
157
|
+
for (const column of columns) {
|
|
158
|
+
const clickHouseType = column.type.replace(/'/g, "\\'"); // Escape single quotes, e.g. `DateTime('UTC')`
|
|
159
|
+
typeDefinitions += `\n '${column.name}': '${clickHouseType}';`;
|
|
160
|
+
}
|
|
161
|
+
typeDefinitions += '\n };';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
typeDefinitions += '\n}\n';
|
|
165
|
+
|
|
166
|
+
// Also generate a type-safe record type for each table
|
|
167
|
+
typeDefinitions += `\n// Type-safe record types for each table\n`;
|
|
168
|
+
for (const table of tables) {
|
|
169
|
+
const columnsQuery = await client.query({
|
|
170
|
+
query: `DESCRIBE TABLE ${table.name}`,
|
|
171
|
+
format: 'JSONEachRow'
|
|
172
|
+
});
|
|
173
|
+
const columns = await columnsQuery.json();
|
|
174
|
+
|
|
175
|
+
typeDefinitions += `export interface ${capitalizeFirstLetter(table.name)}Record {`;
|
|
176
|
+
for (const column of columns) {
|
|
177
|
+
const tsType = clickhouseToTsType(column.type).replace(/'/g, '');
|
|
178
|
+
typeDefinitions += `\n '${column.name}': ${tsType};`;
|
|
179
|
+
}
|
|
180
|
+
typeDefinitions += '\n}\n\n';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Add a usage example
|
|
184
|
+
typeDefinitions += `
|
|
185
|
+
/**
|
|
186
|
+
* Usage example:
|
|
187
|
+
*
|
|
188
|
+
* import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
189
|
+
* import { IntrospectedSchema } from './path-to-this-file';
|
|
190
|
+
*
|
|
191
|
+
* // Create a type-safe query builder
|
|
192
|
+
* const db = createQueryBuilder<IntrospectedSchema>();
|
|
193
|
+
*
|
|
194
|
+
* // Now you have full type safety and autocomplete
|
|
195
|
+
* const results = await db
|
|
196
|
+
* .table('${tables.length > 0 ? tables[0].name : 'table_name'}')
|
|
197
|
+
* .select(['column1', 'column2'])
|
|
198
|
+
* .where('column1', 'eq', 'value')
|
|
199
|
+
* .execute();
|
|
200
|
+
*/
|
|
201
|
+
`;
|
|
202
|
+
|
|
203
|
+
// Ensure the output directory exists
|
|
204
|
+
const outputDir = path.dirname(path.resolve(outputPath));
|
|
205
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
206
|
+
|
|
207
|
+
// Write the file
|
|
208
|
+
await fs.writeFile(path.resolve(outputPath), typeDefinitions);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Capitalize the first letter of a string
|
|
213
|
+
* @param {string} str - The string to capitalize
|
|
214
|
+
* @returns {string} - The capitalized string
|
|
215
|
+
*/
|
|
216
|
+
function capitalizeFirstLetter(str) {
|
|
217
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
218
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { QueryBuilder, ExecuteOptions } from '../query-builder.js';
|
|
2
|
+
import type { AnyBuilderState, SchemaDefinition } from '../types/builder-state.js';
|
|
3
|
+
export declare function executeWithCache<Schema extends SchemaDefinition<Schema>, State extends AnyBuilderState>(builder: QueryBuilder<Schema, State>, options?: ExecuteOptions): Promise<State['output'][]>;
|
|
4
|
+
//# sourceMappingURL=cache-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.d.ts","sourceRoot":"","sources":["../../../src/core/cache/cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AA6DnF,wBAAsB,gBAAgB,CACpC,MAAM,SAAS,gBAAgB,CAAC,MAAM,CAAC,EACvC,KAAK,SAAS,eAAe,EAE7B,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EACpC,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CA0J5B"}
|