@hypequery/cli 0.0.8 → 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,122 @@
1
+ import chalk from 'chalk';
2
+ /**
3
+ * Calm, professional CLI logger
4
+ * Follows Vercel-style output: informative, actionable, no noise
5
+ */
6
+ var Logger = /** @class */ (function () {
7
+ function Logger(quiet) {
8
+ if (quiet === void 0) { quiet = false; }
9
+ this.quiet = quiet;
10
+ }
11
+ /**
12
+ * Success message with checkmark
13
+ */
14
+ Logger.prototype.success = function (message) {
15
+ if (!this.quiet) {
16
+ console.log(chalk.green('✓') + ' ' + message);
17
+ }
18
+ };
19
+ /**
20
+ * Error message with X mark
21
+ */
22
+ Logger.prototype.error = function (message) {
23
+ console.error(chalk.red('✗') + ' ' + message);
24
+ };
25
+ /**
26
+ * Warning message with warning symbol
27
+ */
28
+ Logger.prototype.warn = function (message) {
29
+ if (!this.quiet) {
30
+ console.warn(chalk.yellow('⚠') + ' ' + message);
31
+ }
32
+ };
33
+ /**
34
+ * Info message (no symbol)
35
+ */
36
+ Logger.prototype.info = function (message) {
37
+ if (!this.quiet) {
38
+ console.log(' ' + message);
39
+ }
40
+ };
41
+ /**
42
+ * Reload/change message
43
+ */
44
+ Logger.prototype.reload = function (message) {
45
+ if (!this.quiet) {
46
+ console.log(chalk.blue('↻') + ' ' + message);
47
+ }
48
+ };
49
+ /**
50
+ * Section header
51
+ */
52
+ Logger.prototype.header = function (message) {
53
+ if (!this.quiet) {
54
+ console.log('\n' + chalk.bold(message) + '\n');
55
+ }
56
+ };
57
+ /**
58
+ * Empty line
59
+ */
60
+ Logger.prototype.newline = function () {
61
+ if (!this.quiet) {
62
+ console.log();
63
+ }
64
+ };
65
+ /**
66
+ * Indented message (for sub-items)
67
+ */
68
+ Logger.prototype.indent = function (message) {
69
+ if (!this.quiet) {
70
+ console.log(' ' + message);
71
+ }
72
+ };
73
+ /**
74
+ * Boxed URL output
75
+ */
76
+ Logger.prototype.box = function (lines) {
77
+ if (!this.quiet) {
78
+ var maxLength = Math.max.apply(Math, lines.map(function (l) { return l.length; }));
79
+ var border = '─'.repeat(maxLength + 4);
80
+ console.log(' ┌' + border + '┐');
81
+ for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
82
+ var line = lines_1[_i];
83
+ var padding = ' '.repeat(maxLength - line.length);
84
+ console.log(' │ ' + line + padding + ' │');
85
+ }
86
+ console.log(' └' + border + '┘');
87
+ }
88
+ };
89
+ /**
90
+ * Table output (for dev server stats)
91
+ */
92
+ Logger.prototype.table = function (headers, rows) {
93
+ if (!this.quiet) {
94
+ var columnWidths_1 = headers.map(function (header, i) {
95
+ var maxContentWidth = Math.max.apply(Math, rows.map(function (row) { return (row[i] || '').length; }));
96
+ return Math.max(header.length, maxContentWidth);
97
+ });
98
+ // Header
99
+ var headerRow = headers
100
+ .map(function (h, i) { return h.padEnd(columnWidths_1[i]); })
101
+ .join(' ');
102
+ console.log(' ' + chalk.bold(headerRow));
103
+ // Rows
104
+ for (var _i = 0, rows_1 = rows; _i < rows_1.length; _i++) {
105
+ var row = rows_1[_i];
106
+ var formattedRow = row
107
+ .map(function (cell, i) { return cell.padEnd(columnWidths_1[i]); })
108
+ .join(' ');
109
+ console.log(' ' + formattedRow);
110
+ }
111
+ }
112
+ };
113
+ /**
114
+ * Raw console.log (bypass quiet mode)
115
+ */
116
+ Logger.prototype.raw = function (message) {
117
+ console.log(message);
118
+ };
119
+ return Logger;
120
+ }());
121
+ export { Logger };
122
+ export var logger = new Logger();
@@ -0,0 +1,39 @@
1
+ import type { DatabaseType } from './detect-database.js';
2
+ /**
3
+ * Prompt for database type selection
4
+ */
5
+ export declare function promptDatabaseType(): Promise<DatabaseType | null>;
6
+ /**
7
+ * Prompt for ClickHouse connection details
8
+ */
9
+ export declare function promptClickHouseConnection(): Promise<{
10
+ host: string;
11
+ database: string;
12
+ username: string;
13
+ password: string;
14
+ } | null>;
15
+ /**
16
+ * Prompt for output directory
17
+ */
18
+ export declare function promptOutputDirectory(): Promise<string>;
19
+ /**
20
+ * Prompt for example query generation
21
+ */
22
+ export declare function promptGenerateExample(): Promise<boolean>;
23
+ /**
24
+ * Prompt for table selection (for example query)
25
+ */
26
+ export declare function promptTableSelection(tables: string[]): Promise<string | null>;
27
+ /**
28
+ * Confirm overwrite of existing files
29
+ */
30
+ export declare function confirmOverwrite(files: string[]): Promise<boolean>;
31
+ /**
32
+ * Retry prompt for failed operations
33
+ */
34
+ export declare function promptRetry(message: string): Promise<boolean>;
35
+ /**
36
+ * Ask if user wants to continue without DB connection
37
+ */
38
+ export declare function promptContinueWithoutDb(): Promise<boolean>;
39
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAMzD;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAavE;AAED;;GAEG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAAC,CAkCR;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CA6B7D;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAS9D;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0BnF;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CASxE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASnE;AAED;;GAEG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC,CAShE"}
@@ -0,0 +1,282 @@
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
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
38
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
39
+ if (ar || !(i in from)) {
40
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
41
+ ar[i] = from[i];
42
+ }
43
+ }
44
+ return to.concat(ar || Array.prototype.slice.call(from));
45
+ };
46
+ import prompts from 'prompts';
47
+ import { logger } from './logger.js';
48
+ // Configure prompts to not exit on cancel
49
+ prompts.override({ onCancel: function () { } });
50
+ /**
51
+ * Prompt for database type selection
52
+ */
53
+ export function promptDatabaseType() {
54
+ return __awaiter(this, void 0, void 0, function () {
55
+ var response;
56
+ return __generator(this, function (_a) {
57
+ switch (_a.label) {
58
+ case 0: return [4 /*yield*/, prompts({
59
+ type: 'select',
60
+ name: 'database',
61
+ message: 'Which database are you using?',
62
+ choices: [
63
+ { title: 'ClickHouse', value: 'clickhouse' },
64
+ { title: 'BigQuery (coming soon)', value: 'bigquery', disabled: true },
65
+ ],
66
+ initial: 0,
67
+ })];
68
+ case 1:
69
+ response = _a.sent();
70
+ return [2 /*return*/, response.database || null];
71
+ }
72
+ });
73
+ });
74
+ }
75
+ /**
76
+ * Prompt for ClickHouse connection details
77
+ */
78
+ export function promptClickHouseConnection() {
79
+ return __awaiter(this, void 0, void 0, function () {
80
+ var response;
81
+ var _a, _b, _c, _d;
82
+ return __generator(this, function (_e) {
83
+ switch (_e.label) {
84
+ case 0: return [4 /*yield*/, prompts([
85
+ {
86
+ type: 'text',
87
+ name: 'host',
88
+ message: 'ClickHouse host (or skip to configure later):',
89
+ initial: (_a = process.env.CLICKHOUSE_HOST) !== null && _a !== void 0 ? _a : '',
90
+ },
91
+ {
92
+ type: 'text',
93
+ name: 'database',
94
+ message: 'Database:',
95
+ initial: (_b = process.env.CLICKHOUSE_DATABASE) !== null && _b !== void 0 ? _b : '',
96
+ },
97
+ {
98
+ type: 'text',
99
+ name: 'username',
100
+ message: 'Username:',
101
+ initial: (_c = process.env.CLICKHOUSE_USERNAME) !== null && _c !== void 0 ? _c : '',
102
+ },
103
+ {
104
+ type: 'password',
105
+ name: 'password',
106
+ message: 'Password:',
107
+ initial: (_d = process.env.CLICKHOUSE_PASSWORD) !== null && _d !== void 0 ? _d : '',
108
+ },
109
+ ])];
110
+ case 1:
111
+ response = _e.sent();
112
+ // If user cancelled or skipped
113
+ if (!response.host) {
114
+ return [2 /*return*/, null];
115
+ }
116
+ return [2 /*return*/, response];
117
+ }
118
+ });
119
+ });
120
+ }
121
+ /**
122
+ * Prompt for output directory
123
+ */
124
+ export function promptOutputDirectory() {
125
+ return __awaiter(this, void 0, void 0, function () {
126
+ var response, customResponse;
127
+ return __generator(this, function (_a) {
128
+ switch (_a.label) {
129
+ case 0: return [4 /*yield*/, prompts({
130
+ type: 'select',
131
+ name: 'directory',
132
+ message: 'Where should we create your analytics files?',
133
+ choices: [
134
+ { title: 'analytics/ (recommended)', value: 'analytics' },
135
+ { title: 'src/analytics/', value: 'src/analytics' },
136
+ { title: 'Custom path...', value: 'custom' },
137
+ ],
138
+ initial: 0,
139
+ })];
140
+ case 1:
141
+ response = _a.sent();
142
+ if (!response.directory) {
143
+ return [2 /*return*/, 'analytics']; // Default fallback
144
+ }
145
+ if (!(response.directory === 'custom')) return [3 /*break*/, 3];
146
+ return [4 /*yield*/, prompts({
147
+ type: 'text',
148
+ name: 'path',
149
+ message: 'Enter custom path:',
150
+ initial: 'analytics',
151
+ })];
152
+ case 2:
153
+ customResponse = _a.sent();
154
+ return [2 /*return*/, customResponse.path || 'analytics'];
155
+ case 3: return [2 /*return*/, response.directory];
156
+ }
157
+ });
158
+ });
159
+ }
160
+ /**
161
+ * Prompt for example query generation
162
+ */
163
+ export function promptGenerateExample() {
164
+ return __awaiter(this, void 0, void 0, function () {
165
+ var response;
166
+ var _a;
167
+ return __generator(this, function (_b) {
168
+ switch (_b.label) {
169
+ case 0: return [4 /*yield*/, prompts({
170
+ type: 'confirm',
171
+ name: 'generate',
172
+ message: 'Generate an example query?',
173
+ initial: true,
174
+ })];
175
+ case 1:
176
+ response = _b.sent();
177
+ return [2 /*return*/, (_a = response.generate) !== null && _a !== void 0 ? _a : false];
178
+ }
179
+ });
180
+ });
181
+ }
182
+ /**
183
+ * Prompt for table selection (for example query)
184
+ */
185
+ export function promptTableSelection(tables) {
186
+ return __awaiter(this, void 0, void 0, function () {
187
+ var choices, response;
188
+ return __generator(this, function (_a) {
189
+ switch (_a.label) {
190
+ case 0:
191
+ if (tables.length === 0) {
192
+ return [2 /*return*/, null];
193
+ }
194
+ // Warn if showing truncated list
195
+ if (tables.length > 10) {
196
+ logger.warn("Showing first 10 of ".concat(tables.length, " tables"));
197
+ logger.indent('You can select a different table by editing the generated file');
198
+ logger.newline();
199
+ }
200
+ choices = __spreadArray(__spreadArray([], tables.slice(0, 10).map(function (table) { return ({ title: table, value: table }); }), true), [
201
+ { title: 'Skip example', value: null },
202
+ ], false);
203
+ return [4 /*yield*/, prompts({
204
+ type: 'select',
205
+ name: 'table',
206
+ message: 'Which table should we use for the example?',
207
+ choices: choices,
208
+ initial: 0,
209
+ })];
210
+ case 1:
211
+ response = _a.sent();
212
+ return [2 /*return*/, response.table];
213
+ }
214
+ });
215
+ });
216
+ }
217
+ /**
218
+ * Confirm overwrite of existing files
219
+ */
220
+ export function confirmOverwrite(files) {
221
+ return __awaiter(this, void 0, void 0, function () {
222
+ var response;
223
+ var _a;
224
+ return __generator(this, function (_b) {
225
+ switch (_b.label) {
226
+ case 0: return [4 /*yield*/, prompts({
227
+ type: 'confirm',
228
+ name: 'overwrite',
229
+ message: "The following files will be overwritten:\n".concat(files.map(function (f) { return " \u2022 ".concat(f); }).join('\n'), "\n\nContinue?"),
230
+ initial: false,
231
+ })];
232
+ case 1:
233
+ response = _b.sent();
234
+ return [2 /*return*/, (_a = response.overwrite) !== null && _a !== void 0 ? _a : false];
235
+ }
236
+ });
237
+ });
238
+ }
239
+ /**
240
+ * Retry prompt for failed operations
241
+ */
242
+ export function promptRetry(message) {
243
+ return __awaiter(this, void 0, void 0, function () {
244
+ var response;
245
+ var _a;
246
+ return __generator(this, function (_b) {
247
+ switch (_b.label) {
248
+ case 0: return [4 /*yield*/, prompts({
249
+ type: 'confirm',
250
+ name: 'retry',
251
+ message: message,
252
+ initial: true,
253
+ })];
254
+ case 1:
255
+ response = _b.sent();
256
+ return [2 /*return*/, (_a = response.retry) !== null && _a !== void 0 ? _a : false];
257
+ }
258
+ });
259
+ });
260
+ }
261
+ /**
262
+ * Ask if user wants to continue without DB connection
263
+ */
264
+ export function promptContinueWithoutDb() {
265
+ return __awaiter(this, void 0, void 0, function () {
266
+ var response;
267
+ var _a;
268
+ return __generator(this, function (_b) {
269
+ switch (_b.label) {
270
+ case 0: return [4 /*yield*/, prompts({
271
+ type: 'confirm',
272
+ name: 'continue',
273
+ message: 'Continue setup without database connection?',
274
+ initial: true,
275
+ })];
276
+ case 1:
277
+ response = _b.sent();
278
+ return [2 /*return*/, (_a = response.continue) !== null && _a !== void 0 ? _a : false];
279
+ }
280
+ });
281
+ });
282
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypequery/cli",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Command-line interface for hypequery",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -36,7 +36,7 @@
36
36
  "typescript": "^5.7.3",
37
37
  "vitest": "^2.1.6",
38
38
  "@hypequery/clickhouse": "1.5.0",
39
- "@hypequery/serve": "0.0.7"
39
+ "@hypequery/serve": "0.0.9"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"