@hypequery/cli 0.0.7 → 0.0.9

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.
Files changed (61) hide show
  1. package/dist/bin/cli.d.ts +3 -0
  2. package/dist/bin/cli.d.ts.map +1 -0
  3. package/dist/bin/cli.js +86 -0
  4. package/dist/cli.d.ts +4 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +163 -0
  7. package/dist/commands/dev.d.ts +12 -0
  8. package/dist/commands/dev.d.ts.map +1 -0
  9. package/dist/commands/dev.js +265 -0
  10. package/dist/commands/generate.d.ts +8 -0
  11. package/dist/commands/generate.d.ts.map +1 -0
  12. package/dist/commands/generate.js +175 -0
  13. package/dist/commands/init.d.ts +10 -0
  14. package/dist/commands/init.d.ts.map +1 -0
  15. package/dist/commands/init.js +408 -0
  16. package/dist/generators/clickhouse.d.ts +7 -0
  17. package/dist/generators/clickhouse.d.ts.map +1 -0
  18. package/dist/generators/clickhouse.js +229 -0
  19. package/dist/generators/index.d.ts +7 -0
  20. package/dist/generators/index.d.ts.map +1 -0
  21. package/dist/generators/index.js +13 -0
  22. package/dist/templates/client.d.ts +5 -0
  23. package/dist/templates/client.d.ts.map +1 -0
  24. package/dist/templates/client.js +6 -0
  25. package/dist/templates/env.d.ts +14 -0
  26. package/dist/templates/env.d.ts.map +1 -0
  27. package/dist/templates/env.js +37 -0
  28. package/dist/templates/gitignore.d.ts +13 -0
  29. package/dist/templates/gitignore.d.ts.map +1 -0
  30. package/dist/templates/gitignore.js +22 -0
  31. package/dist/templates/queries.d.ts +8 -0
  32. package/dist/templates/queries.d.ts.map +1 -0
  33. package/dist/templates/queries.js +27 -0
  34. package/dist/test-utils.d.ts +86 -0
  35. package/dist/test-utils.d.ts.map +1 -0
  36. package/dist/test-utils.js +153 -0
  37. package/dist/utils/clickhouse-client.d.ts +11 -0
  38. package/dist/utils/clickhouse-client.d.ts.map +1 -0
  39. package/dist/utils/clickhouse-client.js +86 -0
  40. package/dist/utils/dependency-installer.d.ts +2 -0
  41. package/dist/utils/dependency-installer.d.ts.map +1 -0
  42. package/dist/utils/dependency-installer.js +180 -0
  43. package/dist/utils/detect-database.d.ts +21 -0
  44. package/dist/utils/detect-database.d.ts.map +1 -0
  45. package/dist/utils/detect-database.js +224 -0
  46. package/dist/utils/error-messages.d.ts +6 -0
  47. package/dist/utils/error-messages.d.ts.map +1 -0
  48. package/dist/utils/error-messages.js +19 -0
  49. package/dist/utils/find-files.d.ts +21 -0
  50. package/dist/utils/find-files.d.ts.map +1 -0
  51. package/dist/utils/find-files.js +183 -0
  52. package/dist/utils/load-api.d.ts +2 -0
  53. package/dist/utils/load-api.d.ts.map +1 -0
  54. package/dist/utils/load-api.js +400 -0
  55. package/dist/utils/logger.d.ts +54 -0
  56. package/dist/utils/logger.d.ts.map +1 -0
  57. package/dist/utils/logger.js +122 -0
  58. package/dist/utils/prompts.d.ts +39 -0
  59. package/dist/utils/prompts.d.ts.map +1 -0
  60. package/dist/utils/prompts.js +282 -0
  61. package/package.json +2 -2
@@ -0,0 +1,175 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import path from 'node:path';
38
+ import ora from 'ora';
39
+ import { logger } from '../utils/logger.js';
40
+ import { findSchemaFile } from '../utils/find-files.js';
41
+ import { detectDatabase, getTableCount } from '../utils/detect-database.js';
42
+ import { getTypeGenerator } from '../generators/index.js';
43
+ export function generateCommand() {
44
+ return __awaiter(this, arguments, void 0, function (options) {
45
+ var outputPath, existingSchema, parsedTables, requestedDbType, dbType, _a, spinner, generator, tableCount, typeSpinner, error_1;
46
+ if (options === void 0) { options = {}; }
47
+ return __generator(this, function (_b) {
48
+ switch (_b.label) {
49
+ case 0:
50
+ if (!options.output) return [3 /*break*/, 1];
51
+ outputPath = path.resolve(process.cwd(), options.output);
52
+ return [3 /*break*/, 3];
53
+ case 1: return [4 /*yield*/, findSchemaFile()];
54
+ case 2:
55
+ existingSchema = _b.sent();
56
+ if (existingSchema) {
57
+ outputPath = existingSchema;
58
+ }
59
+ else {
60
+ // Default to analytics/schema.ts
61
+ outputPath = path.join(process.cwd(), 'analytics', 'schema.ts');
62
+ }
63
+ _b.label = 3;
64
+ case 3:
65
+ parsedTables = options.tables
66
+ ? options.tables
67
+ .split(',')
68
+ .map(function (table) { return table.trim(); })
69
+ .filter(Boolean)
70
+ : undefined;
71
+ requestedDbType = options.database;
72
+ if (!(requestedDbType !== null && requestedDbType !== void 0)) return [3 /*break*/, 4];
73
+ _a = requestedDbType;
74
+ return [3 /*break*/, 6];
75
+ case 4: return [4 /*yield*/, detectDatabase()];
76
+ case 5:
77
+ _a = (_b.sent());
78
+ _b.label = 6;
79
+ case 6:
80
+ dbType = _a;
81
+ logger.newline();
82
+ logger.header('hypequery generate');
83
+ spinner = ora("Connecting to ".concat(dbType, "...")).start();
84
+ _b.label = 7;
85
+ case 7:
86
+ _b.trys.push([7, 10, , 11]);
87
+ generator = getTypeGenerator(dbType);
88
+ return [4 /*yield*/, getTableCount(dbType)];
89
+ case 8:
90
+ tableCount = _b.sent();
91
+ spinner.succeed("Connected to ".concat(dbType === 'clickhouse' ? 'ClickHouse' : dbType));
92
+ logger.success("Found ".concat(tableCount, " tables"));
93
+ typeSpinner = ora('Generating types...').start();
94
+ return [4 /*yield*/, generator({
95
+ outputPath: outputPath,
96
+ includeTables: parsedTables,
97
+ })];
98
+ case 9:
99
+ _b.sent();
100
+ typeSpinner.succeed("Generated types for ".concat(tableCount, " tables"));
101
+ logger.success("Updated ".concat(path.relative(process.cwd(), outputPath)));
102
+ logger.newline();
103
+ logger.header('Types regenerated successfully!');
104
+ logger.newline();
105
+ return [3 /*break*/, 11];
106
+ case 10:
107
+ error_1 = _b.sent();
108
+ spinner.fail('Failed to generate types');
109
+ logger.newline();
110
+ if (error_1 instanceof Error) {
111
+ logger.error(error_1.message);
112
+ // Provide specific guidance based on error type
113
+ if (error_1.message.includes('ECONNREFUSED')) {
114
+ logger.newline();
115
+ logger.info('This usually means:');
116
+ logger.indent('• ClickHouse is not running');
117
+ logger.indent('• Wrong host/port in configuration');
118
+ logger.indent('• Firewall blocking connection');
119
+ logger.newline();
120
+ logger.info('Check your configuration:');
121
+ logger.indent('CLICKHOUSE_HOST=' + (process.env.CLICKHOUSE_HOST || 'not set'));
122
+ logger.newline();
123
+ logger.info('Docs: https://hypequery.com/docs/troubleshooting#connection-errors');
124
+ }
125
+ else if (error_1.message.includes('ETIMEDOUT') || error_1.message.includes('timeout')) {
126
+ logger.newline();
127
+ logger.info('Database connection timed out');
128
+ logger.newline();
129
+ logger.info('This usually means:');
130
+ logger.indent('• Database is running but not responding');
131
+ logger.indent('• Network latency is too high');
132
+ logger.indent('• Firewall is dropping packets');
133
+ logger.newline();
134
+ logger.info('Try:');
135
+ logger.indent('• Check if database is under heavy load');
136
+ logger.indent('• Verify network connectivity');
137
+ logger.indent('• Check firewall rules');
138
+ }
139
+ else if (error_1.message.toLowerCase().includes('ssl') || error_1.message.toLowerCase().includes('tls')) {
140
+ logger.newline();
141
+ logger.info('SSL/TLS connection error');
142
+ logger.newline();
143
+ logger.info('This usually means:');
144
+ logger.indent('• SSL certificate validation failed');
145
+ logger.indent('• Incorrect SSL configuration');
146
+ logger.newline();
147
+ logger.info('Try:');
148
+ logger.indent('• Check if your connection string requires SSL');
149
+ logger.indent('• Verify SSL certificate is valid');
150
+ logger.indent('• Check SSL-related environment variables');
151
+ }
152
+ else if (error_1.message.toLowerCase().includes('authentication') || error_1.message.toLowerCase().includes('auth')) {
153
+ logger.newline();
154
+ logger.info('Authentication failed');
155
+ logger.newline();
156
+ logger.info('This usually means:');
157
+ logger.indent('• Invalid username or password');
158
+ logger.indent('• User does not have required permissions');
159
+ logger.newline();
160
+ logger.info('Check your configuration:');
161
+ logger.indent('CLICKHOUSE_USERNAME=' + (process.env.CLICKHOUSE_USERNAME || 'not set'));
162
+ logger.indent('CLICKHOUSE_PASSWORD=' + (process.env.CLICKHOUSE_PASSWORD ? '***' : 'not set'));
163
+ }
164
+ }
165
+ else {
166
+ logger.error(String(error_1));
167
+ }
168
+ logger.newline();
169
+ process.exit(1);
170
+ return [3 /*break*/, 11];
171
+ case 11: return [2 /*return*/];
172
+ }
173
+ });
174
+ });
175
+ }
@@ -0,0 +1,10 @@
1
+ export interface InitOptions {
2
+ database?: string;
3
+ path?: string;
4
+ noExample?: boolean;
5
+ noInteractive?: boolean;
6
+ force?: boolean;
7
+ skipConnection?: boolean;
8
+ }
9
+ export declare function initCommand(options?: InitOptions): Promise<void>;
10
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAgFD,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,iBAoO1D"}
@@ -0,0 +1,408 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { mkdir, writeFile, readFile, access } from 'node:fs/promises';
38
+ import path from 'node:path';
39
+ import ora from 'ora';
40
+ import { logger } from '../utils/logger.js';
41
+ import { promptDatabaseType, promptClickHouseConnection, promptOutputDirectory, promptGenerateExample, promptTableSelection, confirmOverwrite, promptRetry, promptContinueWithoutDb, } from '../utils/prompts.js';
42
+ import { validateConnection, getTableCount, getTables, } from '../utils/detect-database.js';
43
+ import { hasEnvFile, hasGitignore } from '../utils/find-files.js';
44
+ import { generateEnvTemplate, appendToEnv } from '../templates/env.js';
45
+ import { generateClientTemplate } from '../templates/client.js';
46
+ import { generateQueriesTemplate } from '../templates/queries.js';
47
+ import { appendToGitignore } from '../templates/gitignore.js';
48
+ import { getTypeGenerator } from '../generators/index.js';
49
+ import { installServeDependencies } from '../utils/dependency-installer.js';
50
+ function determineDatabase(options) {
51
+ return __awaiter(this, void 0, void 0, function () {
52
+ var dbType, _a;
53
+ var _b;
54
+ return __generator(this, function (_c) {
55
+ switch (_c.label) {
56
+ case 0:
57
+ if (!((_b = options.database) !== null && _b !== void 0)) return [3 /*break*/, 1];
58
+ _a = _b;
59
+ return [3 /*break*/, 3];
60
+ case 1: return [4 /*yield*/, promptDatabaseType()];
61
+ case 2:
62
+ _a = (_c.sent());
63
+ _c.label = 3;
64
+ case 3:
65
+ dbType = _a;
66
+ if (!dbType) {
67
+ logger.info('Setup cancelled');
68
+ process.exit(0);
69
+ }
70
+ if (dbType !== 'clickhouse') {
71
+ logger.error("".concat(dbType, " is not yet supported. Only ClickHouse is available."));
72
+ process.exit(1);
73
+ }
74
+ return [2 /*return*/, dbType];
75
+ }
76
+ });
77
+ });
78
+ }
79
+ function resolveConnectionConfig(options) {
80
+ return __awaiter(this, void 0, void 0, function () {
81
+ var required;
82
+ var _a;
83
+ return __generator(this, function (_b) {
84
+ if (options.noInteractive) {
85
+ required = function (key) {
86
+ var value = process.env[key];
87
+ if (!value) {
88
+ throw new Error("Missing ".concat(key, ". Provide ClickHouse connection info via environment variables when using --no-interactive."));
89
+ }
90
+ return value;
91
+ };
92
+ return [2 /*return*/, {
93
+ host: required('CLICKHOUSE_HOST'),
94
+ database: required('CLICKHOUSE_DATABASE'),
95
+ username: required('CLICKHOUSE_USERNAME'),
96
+ password: (_a = process.env.CLICKHOUSE_PASSWORD) !== null && _a !== void 0 ? _a : '',
97
+ }];
98
+ }
99
+ return [2 /*return*/, promptClickHouseConnection()];
100
+ });
101
+ });
102
+ }
103
+ function testConnection(connectionConfig, dbType) {
104
+ return __awaiter(this, void 0, void 0, function () {
105
+ var spinner, isValid, tableCount;
106
+ return __generator(this, function (_a) {
107
+ switch (_a.label) {
108
+ case 0:
109
+ spinner = ora('Testing connection...').start();
110
+ process.env.CLICKHOUSE_HOST = connectionConfig.host;
111
+ process.env.CLICKHOUSE_DATABASE = connectionConfig.database;
112
+ process.env.CLICKHOUSE_USERNAME = connectionConfig.username;
113
+ process.env.CLICKHOUSE_PASSWORD = connectionConfig.password;
114
+ return [4 /*yield*/, validateConnection(dbType)];
115
+ case 1:
116
+ isValid = _a.sent();
117
+ if (!isValid) {
118
+ spinner.fail('Connection failed');
119
+ logger.newline();
120
+ logger.error("Could not connect to ClickHouse at ".concat(connectionConfig.host));
121
+ logger.newline();
122
+ logger.info('Common issues:');
123
+ logger.indent('• Check your host URL includes http:// or https://');
124
+ logger.indent('• Verify username and password');
125
+ logger.indent('• Ensure database exists');
126
+ logger.indent('• Check firewall/network access');
127
+ logger.newline();
128
+ return [2 /*return*/, { hasValidConnection: false, tableCount: 0 }];
129
+ }
130
+ return [4 /*yield*/, getTableCount(dbType)];
131
+ case 2:
132
+ tableCount = _a.sent();
133
+ spinner.succeed("Connected successfully (".concat(tableCount, " tables found)"));
134
+ logger.newline();
135
+ return [2 /*return*/, { hasValidConnection: true, tableCount: tableCount }];
136
+ }
137
+ });
138
+ });
139
+ }
140
+ export function initCommand() {
141
+ return __awaiter(this, arguments, void 0, function (options) {
142
+ var dbType, connectionConfig, hasValidConnection, tableCount, _a, valid, count, retry, continueWithout, outputDir, resolvedOutputDir, filesToCreate, existingFiles, _i, filesToCreate_1, file, _b, shouldOverwrite, generateExample, selectedTable, tables, envPath, envExists, existingEnv, newEnv, envPath, envExists, placeholderConfig, schemaPath, typeSpinner, generator, error_1, clientPath, queriesPath, gitignorePath, gitignoreExists, existingGitignore, newGitignore, exampleQueryKey;
143
+ if (options === void 0) { options = {}; }
144
+ return __generator(this, function (_c) {
145
+ switch (_c.label) {
146
+ case 0:
147
+ logger.newline();
148
+ logger.header('Welcome to hypequery!');
149
+ logger.info("Let's set up your analytics layer.");
150
+ logger.newline();
151
+ return [4 /*yield*/, determineDatabase(options)];
152
+ case 1:
153
+ dbType = _c.sent();
154
+ return [4 /*yield*/, resolveConnectionConfig(options)];
155
+ case 2:
156
+ connectionConfig = _c.sent();
157
+ hasValidConnection = false;
158
+ tableCount = 0;
159
+ if (!!connectionConfig) return [3 /*break*/, 3];
160
+ logger.info('Skipping database connection for now.');
161
+ logger.newline();
162
+ return [3 /*break*/, 8];
163
+ case 3:
164
+ if (!options.skipConnection) return [3 /*break*/, 4];
165
+ logger.info('Skipping database connection test (requested).');
166
+ logger.newline();
167
+ return [3 /*break*/, 8];
168
+ case 4: return [4 /*yield*/, testConnection(connectionConfig, dbType)];
169
+ case 5:
170
+ _a = _c.sent(), valid = _a.hasValidConnection, count = _a.tableCount;
171
+ hasValidConnection = valid;
172
+ tableCount = count;
173
+ if (!!hasValidConnection) return [3 /*break*/, 8];
174
+ return [4 /*yield*/, promptRetry('Try again?')];
175
+ case 6:
176
+ retry = _c.sent();
177
+ if (retry) {
178
+ return [2 /*return*/, initCommand(options)];
179
+ }
180
+ return [4 /*yield*/, promptContinueWithoutDb()];
181
+ case 7:
182
+ continueWithout = _c.sent();
183
+ if (!continueWithout) {
184
+ logger.info('Setup cancelled');
185
+ process.exit(0);
186
+ }
187
+ logger.newline();
188
+ logger.info('Continuing without database connection.');
189
+ logger.info('You can configure the connection later in .env');
190
+ logger.newline();
191
+ connectionConfig = null;
192
+ _c.label = 8;
193
+ case 8:
194
+ outputDir = options.path;
195
+ if (!(!outputDir && !options.noInteractive)) return [3 /*break*/, 10];
196
+ return [4 /*yield*/, promptOutputDirectory()];
197
+ case 9:
198
+ outputDir = _c.sent();
199
+ return [3 /*break*/, 11];
200
+ case 10:
201
+ if (!outputDir) {
202
+ outputDir = 'analytics';
203
+ }
204
+ _c.label = 11;
205
+ case 11:
206
+ resolvedOutputDir = path.resolve(process.cwd(), outputDir);
207
+ filesToCreate = [
208
+ path.join(resolvedOutputDir, 'client.ts'),
209
+ path.join(resolvedOutputDir, 'schema.ts'),
210
+ path.join(resolvedOutputDir, 'queries.ts'),
211
+ ];
212
+ existingFiles = [];
213
+ _i = 0, filesToCreate_1 = filesToCreate;
214
+ _c.label = 12;
215
+ case 12:
216
+ if (!(_i < filesToCreate_1.length)) return [3 /*break*/, 17];
217
+ file = filesToCreate_1[_i];
218
+ _c.label = 13;
219
+ case 13:
220
+ _c.trys.push([13, 15, , 16]);
221
+ return [4 /*yield*/, access(file)];
222
+ case 14:
223
+ _c.sent();
224
+ existingFiles.push(path.relative(process.cwd(), file));
225
+ return [3 /*break*/, 16];
226
+ case 15:
227
+ _b = _c.sent();
228
+ return [3 /*break*/, 16];
229
+ case 16:
230
+ _i++;
231
+ return [3 /*break*/, 12];
232
+ case 17:
233
+ if (!(existingFiles.length > 0 && !options.force)) return [3 /*break*/, 19];
234
+ logger.warn('Files already exist');
235
+ logger.newline();
236
+ return [4 /*yield*/, confirmOverwrite(existingFiles)];
237
+ case 18:
238
+ shouldOverwrite = _c.sent();
239
+ if (!shouldOverwrite) {
240
+ logger.info('Setup cancelled');
241
+ process.exit(0);
242
+ }
243
+ logger.newline();
244
+ _c.label = 19;
245
+ case 19:
246
+ generateExample = !options.noExample && hasValidConnection;
247
+ selectedTable = null;
248
+ if (!(generateExample && !options.noInteractive && hasValidConnection)) return [3 /*break*/, 23];
249
+ return [4 /*yield*/, promptGenerateExample()];
250
+ case 20:
251
+ generateExample = _c.sent();
252
+ if (!generateExample) return [3 /*break*/, 23];
253
+ return [4 /*yield*/, getTables(dbType)];
254
+ case 21:
255
+ tables = _c.sent();
256
+ return [4 /*yield*/, promptTableSelection(tables)];
257
+ case 22:
258
+ selectedTable = _c.sent();
259
+ generateExample = selectedTable !== null;
260
+ _c.label = 23;
261
+ case 23:
262
+ logger.newline();
263
+ // Step 7: Create directory
264
+ return [4 /*yield*/, mkdir(resolvedOutputDir, { recursive: true })];
265
+ case 24:
266
+ // Step 7: Create directory
267
+ _c.sent();
268
+ if (!connectionConfig) return [3 /*break*/, 31];
269
+ envPath = path.join(process.cwd(), '.env');
270
+ return [4 /*yield*/, hasEnvFile()];
271
+ case 25:
272
+ envExists = _c.sent();
273
+ if (!envExists) return [3 /*break*/, 28];
274
+ return [4 /*yield*/, readFile(envPath, 'utf-8')];
275
+ case 26:
276
+ existingEnv = _c.sent();
277
+ newEnv = appendToEnv(existingEnv, generateEnvTemplate(connectionConfig));
278
+ return [4 /*yield*/, writeFile(envPath, newEnv)];
279
+ case 27:
280
+ _c.sent();
281
+ logger.success('Updated .env');
282
+ return [3 /*break*/, 30];
283
+ case 28: return [4 /*yield*/, writeFile(envPath, generateEnvTemplate(connectionConfig))];
284
+ case 29:
285
+ _c.sent();
286
+ logger.success('Created .env');
287
+ _c.label = 30;
288
+ case 30: return [3 /*break*/, 34];
289
+ case 31:
290
+ envPath = path.join(process.cwd(), '.env');
291
+ return [4 /*yield*/, hasEnvFile()];
292
+ case 32:
293
+ envExists = _c.sent();
294
+ placeholderConfig = {
295
+ host: 'YOUR_CLICKHOUSE_HOST',
296
+ database: 'YOUR_DATABASE',
297
+ username: 'YOUR_USERNAME',
298
+ password: 'YOUR_PASSWORD',
299
+ };
300
+ if (!!envExists) return [3 /*break*/, 34];
301
+ return [4 /*yield*/, writeFile(envPath, generateEnvTemplate(placeholderConfig))];
302
+ case 33:
303
+ _c.sent();
304
+ logger.success('Created .env (configure your credentials)');
305
+ _c.label = 34;
306
+ case 34:
307
+ schemaPath = path.join(resolvedOutputDir, 'schema.ts');
308
+ if (!hasValidConnection) return [3 /*break*/, 39];
309
+ typeSpinner = ora('Generating TypeScript types...').start();
310
+ _c.label = 35;
311
+ case 35:
312
+ _c.trys.push([35, 37, , 38]);
313
+ generator = getTypeGenerator('clickhouse');
314
+ return [4 /*yield*/, generator({ outputPath: schemaPath })];
315
+ case 36:
316
+ _c.sent();
317
+ typeSpinner.succeed("Generated TypeScript types (".concat(path.relative(process.cwd(), schemaPath), ")"));
318
+ return [3 /*break*/, 38];
319
+ case 37:
320
+ error_1 = _c.sent();
321
+ typeSpinner.fail('Failed to generate types');
322
+ logger.error(error_1 instanceof Error ? error_1.message : String(error_1));
323
+ process.exit(1);
324
+ return [3 /*break*/, 38];
325
+ case 38: return [3 /*break*/, 41];
326
+ case 39:
327
+ // Create placeholder schema file
328
+ return [4 /*yield*/, writeFile(schemaPath, "// Generated by hypequery\n// Run 'npx hypequery generate' after configuring your database connection\n\nexport interface IntrospectedSchema {\n // Your table types will appear here after generation\n}\n")];
329
+ case 40:
330
+ // Create placeholder schema file
331
+ _c.sent();
332
+ logger.success("Created placeholder schema (".concat(path.relative(process.cwd(), schemaPath), ")"));
333
+ _c.label = 41;
334
+ case 41:
335
+ clientPath = path.join(resolvedOutputDir, 'client.ts');
336
+ return [4 /*yield*/, writeFile(clientPath, generateClientTemplate())];
337
+ case 42:
338
+ _c.sent();
339
+ logger.success("Created ClickHouse client (".concat(path.relative(process.cwd(), clientPath), ")"));
340
+ queriesPath = path.join(resolvedOutputDir, 'queries.ts');
341
+ return [4 /*yield*/, writeFile(queriesPath, generateQueriesTemplate({
342
+ hasExample: generateExample,
343
+ tableName: selectedTable || undefined,
344
+ }))];
345
+ case 43:
346
+ _c.sent();
347
+ logger.success("Created queries file (".concat(path.relative(process.cwd(), queriesPath), ")"));
348
+ if (generateExample && selectedTable) {
349
+ logger.success("Created example query using '".concat(selectedTable, "' table"));
350
+ }
351
+ gitignorePath = path.join(process.cwd(), '.gitignore');
352
+ return [4 /*yield*/, hasGitignore()];
353
+ case 44:
354
+ gitignoreExists = _c.sent();
355
+ if (!gitignoreExists) return [3 /*break*/, 48];
356
+ return [4 /*yield*/, readFile(gitignorePath, 'utf-8')];
357
+ case 45:
358
+ existingGitignore = _c.sent();
359
+ newGitignore = appendToGitignore(existingGitignore);
360
+ if (!(newGitignore !== existingGitignore)) return [3 /*break*/, 47];
361
+ return [4 /*yield*/, writeFile(gitignorePath, newGitignore)];
362
+ case 46:
363
+ _c.sent();
364
+ logger.success('Updated .gitignore');
365
+ _c.label = 47;
366
+ case 47: return [3 /*break*/, 50];
367
+ case 48: return [4 /*yield*/, writeFile(gitignorePath, appendToGitignore(''))];
368
+ case 49:
369
+ _c.sent();
370
+ logger.success('Created .gitignore');
371
+ _c.label = 50;
372
+ case 50:
373
+ // Step 13: Ensure required hypequery packages are installed
374
+ return [4 /*yield*/, installServeDependencies()];
375
+ case 51:
376
+ // Step 13: Ensure required hypequery packages are installed
377
+ _c.sent();
378
+ // Step 14: Success message
379
+ logger.newline();
380
+ logger.header('Setup complete!');
381
+ if (hasValidConnection) {
382
+ logger.info('Try your first query:');
383
+ logger.newline();
384
+ logger.indent("import { api } from './".concat(path.relative(process.cwd(), queriesPath).replace(/\.ts$/, '.js'), "'"));
385
+ exampleQueryKey = generateExample && selectedTable
386
+ ? "".concat(selectedTable.replace(/_([a-z])/g, function (_, l) { return l.toUpperCase(); }), "Query")
387
+ : 'exampleMetric';
388
+ logger.indent("const result = await api.execute('".concat(exampleQueryKey, "')"));
389
+ logger.newline();
390
+ logger.info('Next:');
391
+ logger.indent('npx hypequery dev Start development server');
392
+ logger.newline();
393
+ }
394
+ else {
395
+ logger.info('Next steps:');
396
+ logger.newline();
397
+ logger.indent('1. Configure your database connection in .env');
398
+ logger.indent('2. Run: npx hypequery generate (to generate types)');
399
+ logger.indent('3. Run: npx hypequery dev (to start dev server)');
400
+ logger.newline();
401
+ }
402
+ logger.info('Docs: https://hypequery.com/docs');
403
+ logger.newline();
404
+ return [2 /*return*/];
405
+ }
406
+ });
407
+ });
408
+ }
@@ -0,0 +1,7 @@
1
+ export interface ClickHouseGeneratorOptions {
2
+ outputPath: string;
3
+ includeTables?: string[];
4
+ excludeTables?: string[];
5
+ }
6
+ export declare function generateClickHouseTypes(options: ClickHouseGeneratorOptions): Promise<void>;
7
+ //# sourceMappingURL=clickhouse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../src/generators/clickhouse.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AA4HD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,0BAA0B,iBA0ChF"}