@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.
- package/README.md +26 -2
- package/dist/bin/cli.js +21 -81
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +72 -116
- package/dist/commands/dev.d.ts +1 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +180 -255
- package/dist/commands/generate-datasets.d.ts +14 -0
- package/dist/commands/generate-datasets.d.ts.map +1 -0
- package/dist/commands/generate-datasets.js +96 -0
- package/dist/commands/generate.d.ts +2 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +112 -167
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +337 -370
- package/dist/generators/clickhouse.d.ts +1 -1
- package/dist/generators/clickhouse.d.ts.map +1 -1
- package/dist/generators/clickhouse.js +10 -269
- package/dist/generators/dataset-generator.d.ts +16 -0
- package/dist/generators/dataset-generator.d.ts.map +1 -0
- package/dist/generators/dataset-generator.js +246 -0
- package/dist/generators/index.js +3 -3
- package/dist/templates/api.d.ts +9 -0
- package/dist/templates/api.d.ts.map +1 -0
- package/dist/templates/api.js +26 -0
- package/dist/templates/auth-scaffold.d.ts +17 -0
- package/dist/templates/auth-scaffold.d.ts.map +1 -0
- package/dist/templates/auth-scaffold.js +41 -0
- package/dist/templates/client.js +10 -1
- package/dist/templates/datasets.d.ts +5 -0
- package/dist/templates/datasets.d.ts.map +1 -0
- package/dist/templates/datasets.js +23 -0
- package/dist/templates/env.js +19 -8
- package/dist/templates/gitignore.js +4 -1
- package/dist/templates/queries.d.ts +3 -0
- package/dist/templates/queries.d.ts.map +1 -1
- package/dist/templates/queries.js +66 -10
- package/dist/test-utils.d.ts +0 -71
- package/dist/test-utils.d.ts.map +1 -1
- package/dist/test-utils.js +12 -137
- package/dist/utils/clickhouse-client.js +10 -57
- package/dist/utils/clickhouse-sql.d.ts +6 -0
- package/dist/utils/clickhouse-sql.d.ts.map +1 -0
- package/dist/utils/clickhouse-sql.js +18 -0
- package/dist/utils/clickhouse-type-utils.d.ts +6 -0
- package/dist/utils/clickhouse-type-utils.d.ts.map +1 -0
- package/dist/utils/clickhouse-type-utils.js +59 -0
- package/dist/utils/dependency-installer.d.ts +4 -2
- package/dist/utils/dependency-installer.d.ts.map +1 -1
- package/dist/utils/dependency-installer.js +93 -170
- package/dist/utils/detect-database.js +84 -195
- package/dist/utils/find-files.d.ts +3 -1
- package/dist/utils/find-files.d.ts.map +1 -1
- package/dist/utils/find-files.js +82 -148
- package/dist/utils/load-api.d.ts.map +1 -1
- package/dist/utils/load-api.js +207 -396
- package/dist/utils/logger.js +38 -42
- package/dist/utils/prompts.d.ts +14 -0
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +170 -219
- package/dist/utils/runtime-guards.d.ts +4 -0
- package/dist/utils/runtime-guards.d.ts.map +1 -0
- package/dist/utils/runtime-guards.js +9 -0
- package/dist/utils/sha256.d.ts +2 -0
- package/dist/utils/sha256.d.ts.map +1 -0
- package/dist/utils/sha256.js +4 -0
- package/package.json +3 -8
- package/dist/utils/error-messages.d.ts +0 -6
- package/dist/utils/error-messages.d.ts.map +0 -1
- package/dist/utils/error-messages.js +0 -19
- package/dist/utils/load-hypequery-config.d.ts +0 -7
- package/dist/utils/load-hypequery-config.d.ts.map +0 -1
- package/dist/utils/load-hypequery-config.js +0 -89
package/dist/utils/logger.js
CHANGED
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
+
error(message) {
|
|
23
23
|
console.error(chalk.red('✗') + ' ' + message);
|
|
24
|
-
}
|
|
24
|
+
}
|
|
25
25
|
/**
|
|
26
26
|
* Warning message with warning symbol
|
|
27
27
|
*/
|
|
28
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
76
|
+
box(lines) {
|
|
77
77
|
if (!this.quiet) {
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
const maxLength = Math.max(...lines.map(l => l.length));
|
|
79
|
+
const border = '─'.repeat(maxLength + 4);
|
|
80
80
|
console.log(' ┌' + border + '┐');
|
|
81
|
-
for (
|
|
82
|
-
|
|
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
|
-
|
|
91
|
+
table(headers, rows) {
|
|
93
92
|
if (!this.quiet) {
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
|
|
100
|
-
.map(
|
|
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 (
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
114
|
+
raw(message) {
|
|
117
115
|
console.log(message);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
export { Logger };
|
|
122
|
-
export var logger = new Logger();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export const logger = new Logger();
|
package/dist/utils/prompts.d.ts
CHANGED
|
@@ -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"}
|
package/dist/utils/prompts.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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 @@
|
|
|
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"}
|