@hypequery/cli 1.1.2 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +26 -2
  2. package/dist/bin/cli.js +21 -81
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +72 -116
  5. package/dist/commands/dev.d.ts +1 -0
  6. package/dist/commands/dev.d.ts.map +1 -1
  7. package/dist/commands/dev.js +180 -255
  8. package/dist/commands/generate-datasets.d.ts +14 -0
  9. package/dist/commands/generate-datasets.d.ts.map +1 -0
  10. package/dist/commands/generate-datasets.js +96 -0
  11. package/dist/commands/generate.d.ts +2 -0
  12. package/dist/commands/generate.d.ts.map +1 -1
  13. package/dist/commands/generate.js +112 -167
  14. package/dist/commands/init.d.ts +7 -0
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +337 -370
  17. package/dist/generators/clickhouse.d.ts +1 -1
  18. package/dist/generators/clickhouse.d.ts.map +1 -1
  19. package/dist/generators/clickhouse.js +10 -269
  20. package/dist/generators/dataset-generator.d.ts +16 -0
  21. package/dist/generators/dataset-generator.d.ts.map +1 -0
  22. package/dist/generators/dataset-generator.js +246 -0
  23. package/dist/generators/index.js +3 -3
  24. package/dist/templates/api.d.ts +9 -0
  25. package/dist/templates/api.d.ts.map +1 -0
  26. package/dist/templates/api.js +26 -0
  27. package/dist/templates/auth-scaffold.d.ts +17 -0
  28. package/dist/templates/auth-scaffold.d.ts.map +1 -0
  29. package/dist/templates/auth-scaffold.js +41 -0
  30. package/dist/templates/client.js +10 -1
  31. package/dist/templates/datasets.d.ts +5 -0
  32. package/dist/templates/datasets.d.ts.map +1 -0
  33. package/dist/templates/datasets.js +23 -0
  34. package/dist/templates/env.js +19 -8
  35. package/dist/templates/gitignore.js +4 -1
  36. package/dist/templates/queries.d.ts +3 -0
  37. package/dist/templates/queries.d.ts.map +1 -1
  38. package/dist/templates/queries.js +66 -10
  39. package/dist/test-utils.d.ts +0 -71
  40. package/dist/test-utils.d.ts.map +1 -1
  41. package/dist/test-utils.js +12 -137
  42. package/dist/utils/clickhouse-client.js +10 -57
  43. package/dist/utils/clickhouse-sql.d.ts +6 -0
  44. package/dist/utils/clickhouse-sql.d.ts.map +1 -0
  45. package/dist/utils/clickhouse-sql.js +18 -0
  46. package/dist/utils/clickhouse-type-utils.d.ts +6 -0
  47. package/dist/utils/clickhouse-type-utils.d.ts.map +1 -0
  48. package/dist/utils/clickhouse-type-utils.js +59 -0
  49. package/dist/utils/dependency-installer.d.ts +4 -2
  50. package/dist/utils/dependency-installer.d.ts.map +1 -1
  51. package/dist/utils/dependency-installer.js +93 -170
  52. package/dist/utils/detect-database.js +84 -195
  53. package/dist/utils/find-files.d.ts +3 -1
  54. package/dist/utils/find-files.d.ts.map +1 -1
  55. package/dist/utils/find-files.js +82 -148
  56. package/dist/utils/load-api.d.ts.map +1 -1
  57. package/dist/utils/load-api.js +207 -396
  58. package/dist/utils/logger.js +38 -42
  59. package/dist/utils/prompts.d.ts +14 -0
  60. package/dist/utils/prompts.d.ts.map +1 -1
  61. package/dist/utils/prompts.js +170 -219
  62. package/dist/utils/runtime-guards.d.ts +4 -0
  63. package/dist/utils/runtime-guards.d.ts.map +1 -0
  64. package/dist/utils/runtime-guards.js +9 -0
  65. package/dist/utils/sha256.d.ts +2 -0
  66. package/dist/utils/sha256.d.ts.map +1 -0
  67. package/dist/utils/sha256.js +4 -0
  68. package/package.json +3 -8
  69. package/dist/utils/error-messages.d.ts +0 -6
  70. package/dist/utils/error-messages.d.ts.map +0 -1
  71. package/dist/utils/error-messages.js +0 -19
  72. package/dist/utils/load-hypequery-config.d.ts +0 -7
  73. package/dist/utils/load-hypequery-config.d.ts.map +0 -1
  74. package/dist/utils/load-hypequery-config.js +0 -89
@@ -3,120 +3,116 @@ import chalk from 'chalk';
3
3
  * Calm, professional CLI logger
4
4
  * Follows Vercel-style output: informative, actionable, no noise
5
5
  */
6
- var Logger = /** @class */ (function () {
7
- function Logger(quiet) {
8
- if (quiet === void 0) { quiet = false; }
6
+ export class Logger {
7
+ quiet;
8
+ constructor(quiet = false) {
9
9
  this.quiet = quiet;
10
10
  }
11
11
  /**
12
12
  * Success message with checkmark
13
13
  */
14
- Logger.prototype.success = function (message) {
14
+ success(message) {
15
15
  if (!this.quiet) {
16
16
  console.log(chalk.green('✓') + ' ' + message);
17
17
  }
18
- };
18
+ }
19
19
  /**
20
20
  * Error message with X mark
21
21
  */
22
- Logger.prototype.error = function (message) {
22
+ error(message) {
23
23
  console.error(chalk.red('✗') + ' ' + message);
24
- };
24
+ }
25
25
  /**
26
26
  * Warning message with warning symbol
27
27
  */
28
- Logger.prototype.warn = function (message) {
28
+ warn(message) {
29
29
  if (!this.quiet) {
30
30
  console.warn(chalk.yellow('⚠') + ' ' + message);
31
31
  }
32
- };
32
+ }
33
33
  /**
34
34
  * Info message (no symbol)
35
35
  */
36
- Logger.prototype.info = function (message) {
36
+ info(message) {
37
37
  if (!this.quiet) {
38
38
  console.log(' ' + message);
39
39
  }
40
- };
40
+ }
41
41
  /**
42
42
  * Reload/change message
43
43
  */
44
- Logger.prototype.reload = function (message) {
44
+ reload(message) {
45
45
  if (!this.quiet) {
46
46
  console.log(chalk.blue('↻') + ' ' + message);
47
47
  }
48
- };
48
+ }
49
49
  /**
50
50
  * Section header
51
51
  */
52
- Logger.prototype.header = function (message) {
52
+ header(message) {
53
53
  if (!this.quiet) {
54
54
  console.log('\n' + chalk.bold(message) + '\n');
55
55
  }
56
- };
56
+ }
57
57
  /**
58
58
  * Empty line
59
59
  */
60
- Logger.prototype.newline = function () {
60
+ newline() {
61
61
  if (!this.quiet) {
62
62
  console.log();
63
63
  }
64
- };
64
+ }
65
65
  /**
66
66
  * Indented message (for sub-items)
67
67
  */
68
- Logger.prototype.indent = function (message) {
68
+ indent(message) {
69
69
  if (!this.quiet) {
70
70
  console.log(' ' + message);
71
71
  }
72
- };
72
+ }
73
73
  /**
74
74
  * Boxed URL output
75
75
  */
76
- Logger.prototype.box = function (lines) {
76
+ box(lines) {
77
77
  if (!this.quiet) {
78
- var maxLength = Math.max.apply(Math, lines.map(function (l) { return l.length; }));
79
- var border = '─'.repeat(maxLength + 4);
78
+ const maxLength = Math.max(...lines.map(l => l.length));
79
+ const border = '─'.repeat(maxLength + 4);
80
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);
81
+ for (const line of lines) {
82
+ const padding = ' '.repeat(maxLength - line.length);
84
83
  console.log(' │ ' + line + padding + ' │');
85
84
  }
86
85
  console.log(' └' + border + '┘');
87
86
  }
88
- };
87
+ }
89
88
  /**
90
89
  * Table output (for dev server stats)
91
90
  */
92
- Logger.prototype.table = function (headers, rows) {
91
+ table(headers, rows) {
93
92
  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; }));
93
+ const columnWidths = headers.map((header, i) => {
94
+ const maxContentWidth = Math.max(...rows.map(row => (row[i] || '').length));
96
95
  return Math.max(header.length, maxContentWidth);
97
96
  });
98
97
  // Header
99
- var headerRow = headers
100
- .map(function (h, i) { return h.padEnd(columnWidths_1[i]); })
98
+ const headerRow = headers
99
+ .map((h, i) => h.padEnd(columnWidths[i]))
101
100
  .join(' ');
102
101
  console.log(' ' + chalk.bold(headerRow));
103
102
  // 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]); })
103
+ for (const row of rows) {
104
+ const formattedRow = row
105
+ .map((cell, i) => cell.padEnd(columnWidths[i]))
108
106
  .join(' ');
109
107
  console.log(' ' + formattedRow);
110
108
  }
111
109
  }
112
- };
110
+ }
113
111
  /**
114
112
  * Raw console.log (bypass quiet mode)
115
113
  */
116
- Logger.prototype.raw = function (message) {
114
+ raw(message) {
117
115
  console.log(message);
118
- };
119
- return Logger;
120
- }());
121
- export { Logger };
122
- export var logger = new Logger();
116
+ }
117
+ }
118
+ export const logger = new Logger();
@@ -11,6 +11,8 @@ export declare function promptClickHouseConnection(): Promise<{
11
11
  * Prompt for output directory
12
12
  */
13
13
  export declare function promptOutputDirectory(): Promise<string>;
14
+ export type InitStyle = 'queries' | 'datasets';
15
+ export declare function promptInitStyle(): Promise<InitStyle>;
14
16
  /**
15
17
  * Prompt for example query generation
16
18
  */
@@ -19,6 +21,10 @@ export declare function promptGenerateExample(): Promise<boolean>;
19
21
  * Prompt for table selection (for example query)
20
22
  */
21
23
  export declare function promptTableSelection(tables: string[]): Promise<string | null>;
24
+ /**
25
+ * Prompt for dataset table selection.
26
+ */
27
+ export declare function promptDatasetTableSelection(tables: string[], defaultTables?: string[]): Promise<string[]>;
22
28
  /**
23
29
  * Confirm overwrite of existing files
24
30
  */
@@ -31,4 +37,12 @@ export declare function promptRetry(message: string): Promise<boolean>;
31
37
  * Ask if user wants to continue without DB connection
32
38
  */
33
39
  export declare function promptContinueWithoutDb(): Promise<boolean>;
40
+ /**
41
+ * Confirm destructive operations (DROP TABLE, DROP COLUMN)
42
+ */
43
+ export declare function confirmDestructiveOperation(operations: string[]): Promise<boolean>;
44
+ /**
45
+ * Confirm mutation operations (type changes that trigger ClickHouse mutations)
46
+ */
47
+ export declare function confirmMutationOperation(): Promise<boolean>;
34
48
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AAQA;;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"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AAQA;;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,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/C,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,CAAC,CAa1D;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,2BAA2B,CAC/C,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,GAAE,MAAM,EAAO,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC,CA2BnB;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;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CASxF;AAED;;GAEG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CASjE"}
@@ -1,258 +1,209 @@
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
1
  import prompts from 'prompts';
47
2
  import { logger } from './logger.js';
48
- var noop = function () { return undefined; };
3
+ const noop = () => undefined;
49
4
  // Configure prompts to not exit on cancel
50
5
  prompts.override({ onCancel: noop });
51
6
  /**
52
7
  * Prompt for ClickHouse connection details
53
8
  */
54
- export function promptClickHouseConnection() {
55
- return __awaiter(this, void 0, void 0, function () {
56
- var response;
57
- var _a, _b, _c, _d, _e;
58
- return __generator(this, function (_f) {
59
- switch (_f.label) {
60
- case 0: return [4 /*yield*/, prompts([
61
- {
62
- type: 'text',
63
- name: 'host',
64
- message: 'ClickHouse URL (or skip to configure later):',
65
- initial: (_b = (_a = process.env.CLICKHOUSE_URL) !== null && _a !== void 0 ? _a : process.env.CLICKHOUSE_HOST) !== null && _b !== void 0 ? _b : '',
66
- },
67
- {
68
- type: 'text',
69
- name: 'database',
70
- message: 'Database:',
71
- initial: (_c = process.env.CLICKHOUSE_DATABASE) !== null && _c !== void 0 ? _c : '',
72
- },
73
- {
74
- type: 'text',
75
- name: 'username',
76
- message: 'Username:',
77
- initial: (_d = process.env.CLICKHOUSE_USERNAME) !== null && _d !== void 0 ? _d : '',
78
- },
79
- {
80
- type: 'password',
81
- name: 'password',
82
- message: 'Password:',
83
- initial: (_e = process.env.CLICKHOUSE_PASSWORD) !== null && _e !== void 0 ? _e : '',
84
- },
85
- ])];
86
- case 1:
87
- response = _f.sent();
88
- // If user cancelled or skipped
89
- if (!response.host) {
90
- return [2 /*return*/, null];
91
- }
92
- return [2 /*return*/, response];
93
- }
94
- });
95
- });
9
+ export async function promptClickHouseConnection() {
10
+ const response = await prompts([
11
+ {
12
+ type: 'text',
13
+ name: 'host',
14
+ message: 'ClickHouse URL (or skip to configure later):',
15
+ initial: process.env.CLICKHOUSE_URL ?? process.env.CLICKHOUSE_HOST ?? '',
16
+ },
17
+ {
18
+ type: 'text',
19
+ name: 'database',
20
+ message: 'Database:',
21
+ initial: process.env.CLICKHOUSE_DATABASE ?? '',
22
+ },
23
+ {
24
+ type: 'text',
25
+ name: 'username',
26
+ message: 'Username:',
27
+ initial: process.env.CLICKHOUSE_USERNAME ?? '',
28
+ },
29
+ {
30
+ type: 'password',
31
+ name: 'password',
32
+ message: 'Password:',
33
+ initial: process.env.CLICKHOUSE_PASSWORD ?? '',
34
+ },
35
+ ]);
36
+ // If user cancelled or skipped
37
+ if (!response.host) {
38
+ return null;
39
+ }
40
+ return response;
96
41
  }
97
42
  /**
98
43
  * Prompt for output directory
99
44
  */
100
- export function promptOutputDirectory() {
101
- return __awaiter(this, void 0, void 0, function () {
102
- var response, customResponse;
103
- return __generator(this, function (_a) {
104
- switch (_a.label) {
105
- case 0: return [4 /*yield*/, prompts({
106
- type: 'select',
107
- name: 'directory',
108
- message: 'Where should we create your analytics files?',
109
- choices: [
110
- { title: 'analytics/ (recommended)', value: 'analytics' },
111
- { title: 'src/analytics/', value: 'src/analytics' },
112
- { title: 'Custom path...', value: 'custom' },
113
- ],
114
- initial: 0,
115
- })];
116
- case 1:
117
- response = _a.sent();
118
- if (!response.directory) {
119
- return [2 /*return*/, 'analytics']; // Default fallback
120
- }
121
- if (!(response.directory === 'custom')) return [3 /*break*/, 3];
122
- return [4 /*yield*/, prompts({
123
- type: 'text',
124
- name: 'path',
125
- message: 'Enter custom path:',
126
- initial: 'analytics',
127
- })];
128
- case 2:
129
- customResponse = _a.sent();
130
- return [2 /*return*/, customResponse.path || 'analytics'];
131
- case 3: return [2 /*return*/, response.directory];
132
- }
45
+ export async function promptOutputDirectory() {
46
+ const response = await prompts({
47
+ type: 'select',
48
+ name: 'directory',
49
+ message: 'Where should we create your analytics files?',
50
+ choices: [
51
+ { title: 'analytics/ (recommended)', value: 'analytics' },
52
+ { title: 'src/analytics/', value: 'src/analytics' },
53
+ { title: 'Custom path...', value: 'custom' },
54
+ ],
55
+ initial: 0,
56
+ });
57
+ if (!response.directory) {
58
+ return 'analytics'; // Default fallback
59
+ }
60
+ if (response.directory === 'custom') {
61
+ const customResponse = await prompts({
62
+ type: 'text',
63
+ name: 'path',
64
+ message: 'Enter custom path:',
65
+ initial: 'analytics',
133
66
  });
67
+ return customResponse.path || 'analytics';
68
+ }
69
+ return response.directory;
70
+ }
71
+ export async function promptInitStyle() {
72
+ const response = await prompts({
73
+ type: 'select',
74
+ name: 'style',
75
+ message: 'Choose your dev API style',
76
+ choices: [
77
+ { title: 'Query builder routes', value: 'queries' },
78
+ { title: 'Datasets semantic API', value: 'datasets' },
79
+ ],
80
+ initial: 0,
134
81
  });
82
+ return response.style ?? 'queries';
135
83
  }
136
84
  /**
137
85
  * Prompt for example query generation
138
86
  */
139
- export function promptGenerateExample() {
140
- return __awaiter(this, void 0, void 0, function () {
141
- var response;
142
- var _a;
143
- return __generator(this, function (_b) {
144
- switch (_b.label) {
145
- case 0: return [4 /*yield*/, prompts({
146
- type: 'confirm',
147
- name: 'generate',
148
- message: 'Generate an example query?',
149
- initial: true,
150
- })];
151
- case 1:
152
- response = _b.sent();
153
- return [2 /*return*/, (_a = response.generate) !== null && _a !== void 0 ? _a : false];
154
- }
155
- });
87
+ export async function promptGenerateExample() {
88
+ const response = await prompts({
89
+ type: 'confirm',
90
+ name: 'generate',
91
+ message: 'Generate an example query?',
92
+ initial: true,
156
93
  });
94
+ return response.generate ?? false;
157
95
  }
158
96
  /**
159
97
  * Prompt for table selection (for example query)
160
98
  */
161
- export function promptTableSelection(tables) {
162
- return __awaiter(this, void 0, void 0, function () {
163
- var choices, response;
164
- return __generator(this, function (_a) {
165
- switch (_a.label) {
166
- case 0:
167
- if (tables.length === 0) {
168
- return [2 /*return*/, null];
169
- }
170
- // Warn if showing truncated list
171
- if (tables.length > 10) {
172
- logger.warn("Showing first 10 of ".concat(tables.length, " tables"));
173
- logger.indent('You can select a different table by editing the generated file');
174
- logger.newline();
175
- }
176
- choices = __spreadArray(__spreadArray([], tables.slice(0, 10).map(function (table) { return ({ title: table, value: table }); }), true), [
177
- { title: 'Skip example', value: null },
178
- ], false);
179
- return [4 /*yield*/, prompts({
180
- type: 'select',
181
- name: 'table',
182
- message: 'Which table should we use for the example?',
183
- choices: choices,
184
- initial: 0,
185
- })];
186
- case 1:
187
- response = _a.sent();
188
- return [2 /*return*/, response.table];
189
- }
190
- });
99
+ export async function promptTableSelection(tables) {
100
+ if (tables.length === 0) {
101
+ return null;
102
+ }
103
+ // Warn if showing truncated list
104
+ if (tables.length > 10) {
105
+ logger.warn(`Showing first 10 of ${tables.length} tables`);
106
+ logger.indent('You can select a different table by editing the generated file');
107
+ logger.newline();
108
+ }
109
+ const choices = [
110
+ ...tables.slice(0, 10).map(table => ({ title: table, value: table })),
111
+ { title: 'Skip example', value: null },
112
+ ];
113
+ const response = await prompts({
114
+ type: 'select',
115
+ name: 'table',
116
+ message: 'Which table should we use for the example?',
117
+ choices,
118
+ initial: 0,
191
119
  });
120
+ return response.table;
121
+ }
122
+ /**
123
+ * Prompt for dataset table selection.
124
+ */
125
+ export async function promptDatasetTableSelection(tables, defaultTables = []) {
126
+ if (tables.length === 0) {
127
+ return [];
128
+ }
129
+ // Warn if showing truncated list
130
+ if (tables.length > 20) {
131
+ logger.warn(`Showing first 20 of ${tables.length} tables`);
132
+ logger.indent('Use --tables or --all-tables for more control in larger databases');
133
+ logger.newline();
134
+ }
135
+ const defaults = new Set(defaultTables);
136
+ const response = await prompts({
137
+ type: 'multiselect',
138
+ name: 'tables',
139
+ message: 'Which tables should we scaffold as datasets?',
140
+ choices: tables.slice(0, 20).map(table => ({
141
+ title: table,
142
+ value: table,
143
+ selected: defaults.has(table),
144
+ })),
145
+ min: 0,
146
+ instructions: false,
147
+ });
148
+ return response.tables ?? [];
192
149
  }
193
150
  /**
194
151
  * Confirm overwrite of existing files
195
152
  */
196
- export function confirmOverwrite(files) {
197
- return __awaiter(this, void 0, void 0, function () {
198
- var response;
199
- var _a;
200
- return __generator(this, function (_b) {
201
- switch (_b.label) {
202
- case 0: return [4 /*yield*/, prompts({
203
- type: 'confirm',
204
- name: 'overwrite',
205
- message: "The following files will be overwritten:\n".concat(files.map(function (f) { return " \u2022 ".concat(f); }).join('\n'), "\n\nContinue?"),
206
- initial: false,
207
- })];
208
- case 1:
209
- response = _b.sent();
210
- return [2 /*return*/, (_a = response.overwrite) !== null && _a !== void 0 ? _a : false];
211
- }
212
- });
153
+ export async function confirmOverwrite(files) {
154
+ const response = await prompts({
155
+ type: 'confirm',
156
+ name: 'overwrite',
157
+ message: `The following files will be overwritten:\n${files.map(f => ` • ${f}`).join('\n')}\n\nContinue?`,
158
+ initial: false,
213
159
  });
160
+ return response.overwrite ?? false;
214
161
  }
215
162
  /**
216
163
  * Retry prompt for failed operations
217
164
  */
218
- export function promptRetry(message) {
219
- return __awaiter(this, void 0, void 0, function () {
220
- var response;
221
- var _a;
222
- return __generator(this, function (_b) {
223
- switch (_b.label) {
224
- case 0: return [4 /*yield*/, prompts({
225
- type: 'confirm',
226
- name: 'retry',
227
- message: message,
228
- initial: true,
229
- })];
230
- case 1:
231
- response = _b.sent();
232
- return [2 /*return*/, (_a = response.retry) !== null && _a !== void 0 ? _a : false];
233
- }
234
- });
165
+ export async function promptRetry(message) {
166
+ const response = await prompts({
167
+ type: 'confirm',
168
+ name: 'retry',
169
+ message,
170
+ initial: true,
235
171
  });
172
+ return response.retry ?? false;
236
173
  }
237
174
  /**
238
175
  * Ask if user wants to continue without DB connection
239
176
  */
240
- export function promptContinueWithoutDb() {
241
- return __awaiter(this, void 0, void 0, function () {
242
- var response;
243
- var _a;
244
- return __generator(this, function (_b) {
245
- switch (_b.label) {
246
- case 0: return [4 /*yield*/, prompts({
247
- type: 'confirm',
248
- name: 'continue',
249
- message: 'Continue setup without database connection?',
250
- initial: true,
251
- })];
252
- case 1:
253
- response = _b.sent();
254
- return [2 /*return*/, (_a = response.continue) !== null && _a !== void 0 ? _a : false];
255
- }
256
- });
177
+ export async function promptContinueWithoutDb() {
178
+ const response = await prompts({
179
+ type: 'confirm',
180
+ name: 'continue',
181
+ message: 'Continue setup without database connection?',
182
+ initial: true,
183
+ });
184
+ return response.continue ?? false;
185
+ }
186
+ /**
187
+ * Confirm destructive operations (DROP TABLE, DROP COLUMN)
188
+ */
189
+ export async function confirmDestructiveOperation(operations) {
190
+ const response = await prompts({
191
+ type: 'confirm',
192
+ name: 'confirm',
193
+ message: `This migration includes ${operations.length} destructive operation(s). Continue?`,
194
+ initial: false,
195
+ });
196
+ return response.confirm ?? false;
197
+ }
198
+ /**
199
+ * Confirm mutation operations (type changes that trigger ClickHouse mutations)
200
+ */
201
+ export async function confirmMutationOperation() {
202
+ const response = await prompts({
203
+ type: 'confirm',
204
+ name: 'confirm',
205
+ message: 'This migration will trigger ClickHouse mutations. Continue?',
206
+ initial: false,
257
207
  });
208
+ return response.confirm ?? false;
258
209
  }
@@ -0,0 +1,4 @@
1
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
2
+ export declare function isNodeErrorWithCode(error: unknown, code: string): error is NodeJS.ErrnoException;
3
+ export declare function isNotFoundError(error: unknown): error is NodeJS.ErrnoException;
4
+ //# sourceMappingURL=runtime-guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-guards.d.ts","sourceRoot":"","sources":["../../src/utils/runtime-guards.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,IAAI,MAAM,CAAC,cAAc,CAEhG;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,cAAc,CAE9E"}
@@ -0,0 +1,9 @@
1
+ export function isRecord(value) {
2
+ return Boolean(value) && typeof value === 'object';
3
+ }
4
+ export function isNodeErrorWithCode(error, code) {
5
+ return isRecord(error) && error.code === code;
6
+ }
7
+ export function isNotFoundError(error) {
8
+ return isNodeErrorWithCode(error, 'ENOENT');
9
+ }
@@ -0,0 +1,2 @@
1
+ export declare function sha256(value: string | Buffer): string;
2
+ //# sourceMappingURL=sha256.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256.d.ts","sourceRoot":"","sources":["../../src/utils/sha256.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,UAE5C"}