@hypequery/cli 1.1.1 → 1.2.0
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 +71 -149
- package/dist/bin/cli.js +21 -81
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +74 -105
- 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 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +337 -390
- 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 +213 -0
- package/dist/generators/index.js +4 -4
- 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.d.ts +2 -1
- package/dist/templates/env.d.ts.map +1 -1
- package/dist/templates/env.js +19 -6
- 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 -9
- package/dist/test-utils.d.ts +0 -72
- package/dist/test-utils.d.ts.map +1 -1
- package/dist/test-utils.js +12 -138
- package/dist/utils/clickhouse-client.js +11 -58
- 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 +5 -1
- package/dist/utils/dependency-installer.d.ts.map +1 -1
- package/dist/utils/dependency-installer.js +117 -134
- 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 -5
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +170 -244
- 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 +4 -4
- 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
|
@@ -1,8 +1,3 @@
|
|
|
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
1
|
/**
|
|
7
2
|
* Prompt for ClickHouse connection details
|
|
8
3
|
*/
|
|
@@ -16,6 +11,8 @@ export declare function promptClickHouseConnection(): Promise<{
|
|
|
16
11
|
* Prompt for output directory
|
|
17
12
|
*/
|
|
18
13
|
export declare function promptOutputDirectory(): Promise<string>;
|
|
14
|
+
export type InitStyle = 'queries' | 'datasets';
|
|
15
|
+
export declare function promptInitStyle(): Promise<InitStyle>;
|
|
19
16
|
/**
|
|
20
17
|
* Prompt for example query generation
|
|
21
18
|
*/
|
|
@@ -24,6 +21,10 @@ export declare function promptGenerateExample(): Promise<boolean>;
|
|
|
24
21
|
* Prompt for table selection (for example query)
|
|
25
22
|
*/
|
|
26
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[]>;
|
|
27
28
|
/**
|
|
28
29
|
* Confirm overwrite of existing files
|
|
29
30
|
*/
|
|
@@ -36,4 +37,12 @@ export declare function promptRetry(message: string): Promise<boolean>;
|
|
|
36
37
|
* Ask if user wants to continue without DB connection
|
|
37
38
|
*/
|
|
38
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>;
|
|
39
48
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"
|
|
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,283 +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
|
-
/**
|
|
52
|
-
* Prompt for database type selection
|
|
53
|
-
*/
|
|
54
|
-
export function promptDatabaseType() {
|
|
55
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
56
|
-
var response;
|
|
57
|
-
return __generator(this, function (_a) {
|
|
58
|
-
switch (_a.label) {
|
|
59
|
-
case 0: return [4 /*yield*/, prompts({
|
|
60
|
-
type: 'select',
|
|
61
|
-
name: 'database',
|
|
62
|
-
message: 'Which database are you using?',
|
|
63
|
-
choices: [
|
|
64
|
-
{ title: 'ClickHouse', value: 'clickhouse' },
|
|
65
|
-
{ title: 'BigQuery (coming soon)', value: 'bigquery', disabled: true },
|
|
66
|
-
],
|
|
67
|
-
initial: 0,
|
|
68
|
-
})];
|
|
69
|
-
case 1:
|
|
70
|
-
response = _a.sent();
|
|
71
|
-
return [2 /*return*/, response.database || null];
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
6
|
/**
|
|
77
7
|
* Prompt for ClickHouse connection details
|
|
78
8
|
*/
|
|
79
|
-
export function promptClickHouseConnection() {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
case 1:
|
|
112
|
-
response = _e.sent();
|
|
113
|
-
// If user cancelled or skipped
|
|
114
|
-
if (!response.host) {
|
|
115
|
-
return [2 /*return*/, null];
|
|
116
|
-
}
|
|
117
|
-
return [2 /*return*/, response];
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
});
|
|
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;
|
|
121
41
|
}
|
|
122
42
|
/**
|
|
123
43
|
* Prompt for output directory
|
|
124
44
|
*/
|
|
125
|
-
export function promptOutputDirectory() {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (!(response.directory === 'custom')) return [3 /*break*/, 3];
|
|
147
|
-
return [4 /*yield*/, prompts({
|
|
148
|
-
type: 'text',
|
|
149
|
-
name: 'path',
|
|
150
|
-
message: 'Enter custom path:',
|
|
151
|
-
initial: 'analytics',
|
|
152
|
-
})];
|
|
153
|
-
case 2:
|
|
154
|
-
customResponse = _a.sent();
|
|
155
|
-
return [2 /*return*/, customResponse.path || 'analytics'];
|
|
156
|
-
case 3: return [2 /*return*/, response.directory];
|
|
157
|
-
}
|
|
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',
|
|
158
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,
|
|
159
81
|
});
|
|
82
|
+
return response.style ?? 'queries';
|
|
160
83
|
}
|
|
161
84
|
/**
|
|
162
85
|
* Prompt for example query generation
|
|
163
86
|
*/
|
|
164
|
-
export function promptGenerateExample() {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
case 0: return [4 /*yield*/, prompts({
|
|
171
|
-
type: 'confirm',
|
|
172
|
-
name: 'generate',
|
|
173
|
-
message: 'Generate an example query?',
|
|
174
|
-
initial: true,
|
|
175
|
-
})];
|
|
176
|
-
case 1:
|
|
177
|
-
response = _b.sent();
|
|
178
|
-
return [2 /*return*/, (_a = response.generate) !== null && _a !== void 0 ? _a : false];
|
|
179
|
-
}
|
|
180
|
-
});
|
|
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,
|
|
181
93
|
});
|
|
94
|
+
return response.generate ?? false;
|
|
182
95
|
}
|
|
183
96
|
/**
|
|
184
97
|
* Prompt for table selection (for example query)
|
|
185
98
|
*/
|
|
186
|
-
export function promptTableSelection(tables) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
name: 'table',
|
|
207
|
-
message: 'Which table should we use for the example?',
|
|
208
|
-
choices: choices,
|
|
209
|
-
initial: 0,
|
|
210
|
-
})];
|
|
211
|
-
case 1:
|
|
212
|
-
response = _a.sent();
|
|
213
|
-
return [2 /*return*/, response.table];
|
|
214
|
-
}
|
|
215
|
-
});
|
|
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,
|
|
216
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 ?? [];
|
|
217
149
|
}
|
|
218
150
|
/**
|
|
219
151
|
* Confirm overwrite of existing files
|
|
220
152
|
*/
|
|
221
|
-
export function confirmOverwrite(files) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
case 0: return [4 /*yield*/, prompts({
|
|
228
|
-
type: 'confirm',
|
|
229
|
-
name: 'overwrite',
|
|
230
|
-
message: "The following files will be overwritten:\n".concat(files.map(function (f) { return " \u2022 ".concat(f); }).join('\n'), "\n\nContinue?"),
|
|
231
|
-
initial: false,
|
|
232
|
-
})];
|
|
233
|
-
case 1:
|
|
234
|
-
response = _b.sent();
|
|
235
|
-
return [2 /*return*/, (_a = response.overwrite) !== null && _a !== void 0 ? _a : false];
|
|
236
|
-
}
|
|
237
|
-
});
|
|
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,
|
|
238
159
|
});
|
|
160
|
+
return response.overwrite ?? false;
|
|
239
161
|
}
|
|
240
162
|
/**
|
|
241
163
|
* Retry prompt for failed operations
|
|
242
164
|
*/
|
|
243
|
-
export function promptRetry(message) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
case 0: return [4 /*yield*/, prompts({
|
|
250
|
-
type: 'confirm',
|
|
251
|
-
name: 'retry',
|
|
252
|
-
message: message,
|
|
253
|
-
initial: true,
|
|
254
|
-
})];
|
|
255
|
-
case 1:
|
|
256
|
-
response = _b.sent();
|
|
257
|
-
return [2 /*return*/, (_a = response.retry) !== null && _a !== void 0 ? _a : false];
|
|
258
|
-
}
|
|
259
|
-
});
|
|
165
|
+
export async function promptRetry(message) {
|
|
166
|
+
const response = await prompts({
|
|
167
|
+
type: 'confirm',
|
|
168
|
+
name: 'retry',
|
|
169
|
+
message,
|
|
170
|
+
initial: true,
|
|
260
171
|
});
|
|
172
|
+
return response.retry ?? false;
|
|
261
173
|
}
|
|
262
174
|
/**
|
|
263
175
|
* Ask if user wants to continue without DB connection
|
|
264
176
|
*/
|
|
265
|
-
export function promptContinueWithoutDb() {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
})
|
|
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,
|
|
282
207
|
});
|
|
208
|
+
return response.confirm ?? false;
|
|
283
209
|
}
|