@hypequery/cli 1.16.4 → 1.17.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/dist/bin/cli.js +8 -2
- package/dist/cli.js +1 -1
- package/dist/commands/generate-datasets.d.ts.map +1 -1
- package/dist/commands/generate-datasets.js +26 -8
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +8 -3
- package/dist/generators/chdb.d.ts +1 -1
- package/dist/generators/chdb.d.ts.map +1 -1
- package/dist/generators/chdb.js +1 -1
- package/dist/generators/clickhouse.d.ts +1 -1
- package/dist/generators/clickhouse.d.ts.map +1 -1
- package/dist/generators/clickhouse.js +1 -1
- package/dist/generators/dataset-generator.d.ts +7 -1
- package/dist/generators/dataset-generator.d.ts.map +1 -1
- package/dist/generators/dataset-generator.js +9 -0
- package/dist/generators/index.d.ts +1 -1
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +2 -2
- package/dist/typegen/generate-types.d.ts +2 -1
- package/dist/typegen/generate-types.d.ts.map +1 -1
- package/dist/typegen/generate-types.js +16 -4
- package/dist/utils/env-files.d.ts +13 -0
- package/dist/utils/env-files.d.ts.map +1 -0
- package/dist/utils/env-files.js +19 -0
- package/package.json +4 -4
package/dist/bin/cli.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { program } from '../cli.js';
|
|
3
|
+
import { envFiles } from '../utils/env-files.js';
|
|
3
4
|
async function loadEnv() {
|
|
4
5
|
try {
|
|
5
6
|
const dotenvx = await import('@dotenvx/dotenvx');
|
|
6
7
|
if (dotenvx?.config && typeof dotenvx.config.load === 'function') {
|
|
7
8
|
await dotenvx.config.load();
|
|
8
|
-
|
|
9
|
+
// Deliberately falls through to the dotenv cascade below. dotenvx has
|
|
10
|
+
// already set whatever it found, and dotenv will not overwrite it, so this
|
|
11
|
+
// only fills in files dotenvx does not read (notably `.env.local`).
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
catch {
|
|
@@ -13,7 +16,10 @@ async function loadEnv() {
|
|
|
13
16
|
}
|
|
14
17
|
try {
|
|
15
18
|
const { config } = await import('dotenv');
|
|
16
|
-
|
|
19
|
+
for (const path of envFiles(process.env.NODE_ENV)) {
|
|
20
|
+
// Missing files are a no-op.
|
|
21
|
+
config({ path });
|
|
22
|
+
}
|
|
17
23
|
}
|
|
18
24
|
catch {
|
|
19
25
|
// dotenv is optional; continue if not available
|
package/dist/cli.js
CHANGED
|
@@ -138,7 +138,7 @@ addTypeGenerationOptions(program.command('generate:types'))
|
|
|
138
138
|
program
|
|
139
139
|
.command('generate:datasets')
|
|
140
140
|
.description('Generate dataset definitions from ClickHouse schema')
|
|
141
|
-
.option('-o, --output <path>', 'Output file (default:
|
|
141
|
+
.option('-o, --output <path>', 'Output file (default: analytics/datasets.ts)')
|
|
142
142
|
.option('--path <path>', 'Analytics directory (derives <path>/datasets.ts)')
|
|
143
143
|
.option('--tables <names>', 'Only generate for specific tables (comma-separated)')
|
|
144
144
|
.option('--exclude-tables <names>', 'Exclude specific tables (comma-separated)')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-datasets.d.ts","sourceRoot":"","sources":["../../src/commands/generate-datasets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"generate-datasets.d.ts","sourceRoot":"","sources":["../../src/commands/generate-datasets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAqBD,wBAAsB,uBAAuB,CAAC,OAAO,GAAE,uBAA4B,iBA0GlF"}
|
|
@@ -10,6 +10,15 @@ import { logger } from '../utils/logger.js';
|
|
|
10
10
|
import { getTableCount } from '../utils/detect-database.js';
|
|
11
11
|
import { generateDatasets } from '../generators/dataset-generator.js';
|
|
12
12
|
import { redactConnectionUrl } from '../utils/redact-connection-url.js';
|
|
13
|
+
/**
|
|
14
|
+
* Turns the written path into something pasteable into an import statement:
|
|
15
|
+
* strips the `.ts` extension and makes it explicitly relative.
|
|
16
|
+
*/
|
|
17
|
+
function toImportSpecifier(relativePath) {
|
|
18
|
+
const withoutExtension = relativePath.replace(/\.tsx?$/, '');
|
|
19
|
+
const normalized = withoutExtension.split(path.sep).join('/');
|
|
20
|
+
return normalized.startsWith('.') ? normalized : `./${normalized}`;
|
|
21
|
+
}
|
|
13
22
|
function parseTableList(value) {
|
|
14
23
|
const parsed = value
|
|
15
24
|
?.split(',')
|
|
@@ -27,8 +36,9 @@ export async function generateDatasetsCommand(options = {}) {
|
|
|
27
36
|
outputPath = path.resolve(process.cwd(), options.path, 'datasets.ts');
|
|
28
37
|
}
|
|
29
38
|
else {
|
|
30
|
-
//
|
|
31
|
-
|
|
39
|
+
// Sibling of `hypequery generate`, which writes analytics/schema.ts. Keeping
|
|
40
|
+
// both commands in one directory is what the docs have always described.
|
|
41
|
+
outputPath = path.join(process.cwd(), 'analytics', 'datasets.ts');
|
|
32
42
|
}
|
|
33
43
|
const parsedTables = parseTableList(options.tables);
|
|
34
44
|
const excludedTables = parseTableList(options.excludeTables);
|
|
@@ -39,30 +49,38 @@ export async function generateDatasetsCommand(options = {}) {
|
|
|
39
49
|
// Get table count
|
|
40
50
|
const tableCount = await getTableCount('clickhouse');
|
|
41
51
|
spinner.succeed('Connected to ClickHouse');
|
|
42
|
-
logger.success(
|
|
52
|
+
logger.success(parsedTables
|
|
53
|
+
? `Found ${tableCount} tables, filtering to ${parsedTables.length}`
|
|
54
|
+
: `Found ${tableCount} tables`);
|
|
43
55
|
// Generate datasets
|
|
44
56
|
const datasetSpinner = ora('Generating dataset definitions...').start();
|
|
45
|
-
await generateDatasets({
|
|
57
|
+
const generated = await generateDatasets({
|
|
46
58
|
outputPath,
|
|
47
59
|
includeTables: parsedTables,
|
|
48
60
|
excludeTables: excludedTables,
|
|
49
61
|
});
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
const generatedTables = generated?.tables ?? parsedTables ?? [];
|
|
63
|
+
const generatedCount = generatedTables.length || tableCount;
|
|
64
|
+
datasetSpinner.succeed(`Generated dataset definitions for ${generatedCount} ${generatedCount === 1 ? 'table' : 'tables'}`);
|
|
65
|
+
const relativeOutput = path.relative(process.cwd(), outputPath);
|
|
66
|
+
logger.success(`Created ${relativeOutput}`);
|
|
52
67
|
logger.newline();
|
|
53
68
|
logger.header('Next steps:');
|
|
54
69
|
logger.indent('1. Review and customize the generated datasets');
|
|
55
70
|
logger.indent('2. Import datasets in your application code');
|
|
56
71
|
logger.indent('3. Create an analytics client and start querying!');
|
|
57
72
|
logger.newline();
|
|
73
|
+
// Built from what was actually written, so the snippet can be pasted as-is.
|
|
74
|
+
const importPath = toImportSpecifier(relativeOutput);
|
|
75
|
+
const firstTable = generatedTables[0] ?? 'orders';
|
|
58
76
|
logger.info('Example usage:');
|
|
59
|
-
logger.indent(
|
|
77
|
+
logger.indent(`import { datasets } from '${importPath}';`);
|
|
60
78
|
logger.indent('import { createDatasetClient } from \'@hypequery/datasets\';');
|
|
61
79
|
logger.indent('import { createQueryBuilder } from \'@hypequery/clickhouse\';');
|
|
62
80
|
logger.indent('');
|
|
63
81
|
logger.indent('const db = createQueryBuilder({ url, username, password, database });');
|
|
64
82
|
logger.indent('const analytics = createDatasetClient({ queryBuilder: db });');
|
|
65
|
-
logger.indent(
|
|
83
|
+
logger.indent(`const rowCount = datasets['${firstTable}'].metric('rowCount', { measure: 'totalCount' });`);
|
|
66
84
|
logger.indent('const result = await analytics.execute(rowCount);');
|
|
67
85
|
logger.newline();
|
|
68
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK/F,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,eAAe,CAAC,OAAO,GAAE,eAAoB,
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK/F,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,eAAe,CAAC,OAAO,GAAE,eAAoB,iBA6JlE"}
|
|
@@ -57,17 +57,22 @@ export async function generateCommand(options = {}) {
|
|
|
57
57
|
// Get table count
|
|
58
58
|
const tableCount = await getTableCount(dbType, { chdbPath });
|
|
59
59
|
spinner.succeed(`Connected to ${dbType === 'clickhouse' ? 'ClickHouse' : dbType === 'chdb' ? 'embedded chDB' : dbType}`);
|
|
60
|
-
logger.success(
|
|
60
|
+
logger.success(parsedTables
|
|
61
|
+
? `Found ${tableCount} tables, applying --tables filter`
|
|
62
|
+
: `Found ${tableCount} tables`);
|
|
61
63
|
// Generate types
|
|
62
64
|
const typeSpinner = ora('Generating types...').start();
|
|
63
65
|
activeSpinner = typeSpinner;
|
|
64
66
|
failureMessage = 'Failed to generate types';
|
|
65
|
-
await generator({
|
|
67
|
+
const generatedTables = await generator({
|
|
66
68
|
outputPath,
|
|
67
69
|
includeTables: parsedTables,
|
|
68
70
|
chdbPath,
|
|
69
71
|
});
|
|
70
|
-
|
|
72
|
+
// The generator returns what it actually wrote after applying filters.
|
|
73
|
+
// Requested names may contain duplicates or tables that do not exist.
|
|
74
|
+
const generatedCount = generatedTables.length;
|
|
75
|
+
typeSpinner.succeed(`Generated types for ${generatedCount} ${generatedCount === 1 ? 'table' : 'tables'}`);
|
|
71
76
|
logger.success(`Updated ${path.relative(process.cwd(), outputPath)}`);
|
|
72
77
|
logger.newline();
|
|
73
78
|
logger.header('Types regenerated successfully!');
|
|
@@ -9,5 +9,5 @@ export interface ChdbGeneratorOptions {
|
|
|
9
9
|
* DESCRIBE TABLE) is identical on the embedded engine — but the client seam
|
|
10
10
|
* is backed by a chDB session instead of an HTTP connection.
|
|
11
11
|
*/
|
|
12
|
-
export declare function generateChdbTypes(options: ChdbGeneratorOptions): Promise<
|
|
12
|
+
export declare function generateChdbTypes(options: ChdbGeneratorOptions): Promise<string[]>;
|
|
13
13
|
//# sourceMappingURL=chdb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chdb.d.ts","sourceRoot":"","sources":["../../src/generators/chdb.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"chdb.d.ts","sourceRoot":"","sources":["../../src/generators/chdb.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,qBAUpE"}
|
package/dist/generators/chdb.js
CHANGED
|
@@ -13,5 +13,5 @@ export async function generateChdbTypes(options) {
|
|
|
13
13
|
...(options.includeTables ? { includeTables: options.includeTables } : {}),
|
|
14
14
|
...(options.excludeTables ? { excludeTables: options.excludeTables } : {}),
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
return generateTypes(options.outputPath, generatorOptions);
|
|
17
17
|
}
|
|
@@ -5,5 +5,5 @@ export interface ClickHouseGeneratorOptions {
|
|
|
5
5
|
excludeTables?: string[];
|
|
6
6
|
}
|
|
7
7
|
export { clickhouseToTsType };
|
|
8
|
-
export declare function generateClickHouseTypes(options: ClickHouseGeneratorOptions): Promise<
|
|
8
|
+
export declare function generateClickHouseTypes(options: ClickHouseGeneratorOptions): Promise<string[]>;
|
|
9
9
|
//# sourceMappingURL=clickhouse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../src/generators/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAGnB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,0BAA0B,
|
|
1
|
+
{"version":3,"file":"clickhouse.d.ts","sourceRoot":"","sources":["../../src/generators/clickhouse.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAGnB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,0BAA0B,qBAUhF"}
|
|
@@ -9,5 +9,5 @@ export async function generateClickHouseTypes(options) {
|
|
|
9
9
|
...(options.includeTables ? { includeTables: options.includeTables } : {}),
|
|
10
10
|
...(options.excludeTables ? { excludeTables: options.excludeTables } : {}),
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
return generateTypes(options.outputPath, generatorOptions);
|
|
13
13
|
}
|
|
@@ -14,5 +14,11 @@ export interface DatasetGeneratorOptions {
|
|
|
14
14
|
/**
|
|
15
15
|
* Generate dataset definitions from ClickHouse schema
|
|
16
16
|
*/
|
|
17
|
-
export declare function generateDatasets(options: DatasetGeneratorOptions): Promise<
|
|
17
|
+
export declare function generateDatasets(options: DatasetGeneratorOptions): Promise<{
|
|
18
|
+
tables: string[];
|
|
19
|
+
exports: {
|
|
20
|
+
table: string;
|
|
21
|
+
exportName: string;
|
|
22
|
+
}[];
|
|
23
|
+
}>;
|
|
18
24
|
//# sourceMappingURL=dataset-generator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset-generator.d.ts","sourceRoot":"","sources":["../../src/generators/dataset-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AAG1E,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,8BAA8B,CAAC;CACzC;AAuPD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB
|
|
1
|
+
{"version":3,"file":"dataset-generator.d.ts","sourceRoot":"","sources":["../../src/generators/dataset-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AAG1E,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,8BAA8B,CAAC;CACzC;AAuPD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB;;;;;;GAmEtE"}
|
|
@@ -243,4 +243,13 @@ ${tables.map((table) => ` ${table.name}: ${tableToPascalCase(table.name)}Datase
|
|
|
243
243
|
await fs.mkdir(outputDir, { recursive: true });
|
|
244
244
|
// Write the file
|
|
245
245
|
await fs.writeFile(path.resolve(options.outputPath), output);
|
|
246
|
+
// Returned so the CLI can report what it actually generated, and print an
|
|
247
|
+
// example that matches the file rather than a hardcoded placeholder.
|
|
248
|
+
return {
|
|
249
|
+
tables: tables.map((table) => table.name),
|
|
250
|
+
exports: tables.map((table) => ({
|
|
251
|
+
table: table.name,
|
|
252
|
+
exportName: `${tableToPascalCase(table.name)}Dataset`,
|
|
253
|
+
})),
|
|
254
|
+
};
|
|
246
255
|
}
|
|
@@ -2,7 +2,7 @@ import type { DatabaseType } from '../utils/detect-database.js';
|
|
|
2
2
|
import type { ClickHouseGeneratorOptions } from './clickhouse.js';
|
|
3
3
|
import type { ChdbGeneratorOptions } from './chdb.js';
|
|
4
4
|
export type TypeGeneratorOptions = ClickHouseGeneratorOptions & ChdbGeneratorOptions;
|
|
5
|
-
type GeneratorFn = (options: TypeGeneratorOptions) => Promise<
|
|
5
|
+
type GeneratorFn = (options: TypeGeneratorOptions) => Promise<string[]>;
|
|
6
6
|
export declare function getTypeGenerator(dbType: DatabaseType): GeneratorFn;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,GAAG,oBAAoB,CAAC;AAErF,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,GAAG,oBAAoB,CAAC;AAErF,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,oBAAoB,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAiBxE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,CAYlE"}
|
package/dist/generators/index.js
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
const generators = {
|
|
6
6
|
clickhouse: async (options) => {
|
|
7
7
|
const { generateClickHouseTypes } = await import('./clickhouse.js');
|
|
8
|
-
|
|
8
|
+
return generateClickHouseTypes(options);
|
|
9
9
|
},
|
|
10
10
|
chdb: async (options) => {
|
|
11
11
|
const { generateChdbTypes } = await import('./chdb.js');
|
|
12
|
-
|
|
12
|
+
return generateChdbTypes(options);
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
15
|
export function getTypeGenerator(dbType) {
|
|
@@ -41,6 +41,7 @@ export declare function generateTypeDefinitions(client: TypeGenerationClickHouse
|
|
|
41
41
|
/**
|
|
42
42
|
* Generates TypeScript type definitions from the ClickHouse database schema and
|
|
43
43
|
* writes them to `outputPath`, creating the containing directory if needed.
|
|
44
|
+
* Returns the names of the tables represented in the generated file.
|
|
44
45
|
*/
|
|
45
|
-
export declare function generateTypes(outputPath: string, options: GenerateTypesOptions): Promise<
|
|
46
|
+
export declare function generateTypes(outputPath: string, options: GenerateTypesOptions): Promise<string[]>;
|
|
46
47
|
//# sourceMappingURL=generate-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../../src/typegen/generate-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,aAAa,CAAA;KAAE,GAAG,OAAO,CAAC;QAChE,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;KAChD,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qCAAqC;IACrC,MAAM,EAAE,8BAA8B,CAAC;IACvC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../../src/typegen/generate-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,aAAa,CAAA;KAAE,GAAG,OAAO,CAAC;QAChE,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;KAChD,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qCAAqC;IACrC,MAAM,EAAE,8BAA8B,CAAC;IACvC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AA2HD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,8BAA8B,EACtC,OAAO,GAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAM,GACjD,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,MAAM,EAAE,CAAC,CAYnB"}
|
|
@@ -29,7 +29,7 @@ async function describeTable(client, tableName) {
|
|
|
29
29
|
/**
|
|
30
30
|
* Generates the TypeScript type definition source from a ClickHouse client.
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
async function buildTypeDefinitions(client, options = {}) {
|
|
33
33
|
const { includeTables = [], excludeTables = [], generatedBy = 'hypequery', includeUsageExample = true, } = options;
|
|
34
34
|
// Get all tables
|
|
35
35
|
const tablesQuery = await client.query({
|
|
@@ -98,18 +98,30 @@ export interface IntrospectedSchema {`;
|
|
|
98
98
|
*/
|
|
99
99
|
`;
|
|
100
100
|
}
|
|
101
|
-
return
|
|
101
|
+
return {
|
|
102
|
+
contents: typeDefinitions,
|
|
103
|
+
tableNames: tables.map((table) => table.name),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Generates the TypeScript type definition source from a ClickHouse client.
|
|
108
|
+
*/
|
|
109
|
+
export async function generateTypeDefinitions(client, options = {}) {
|
|
110
|
+
const generated = await buildTypeDefinitions(client, options);
|
|
111
|
+
return generated.contents;
|
|
102
112
|
}
|
|
103
113
|
/**
|
|
104
114
|
* Generates TypeScript type definitions from the ClickHouse database schema and
|
|
105
115
|
* writes them to `outputPath`, creating the containing directory if needed.
|
|
116
|
+
* Returns the names of the tables represented in the generated file.
|
|
106
117
|
*/
|
|
107
118
|
export async function generateTypes(outputPath, options) {
|
|
108
119
|
const { client, ...definitionOptions } = options;
|
|
109
|
-
const
|
|
120
|
+
const generated = await buildTypeDefinitions(client, definitionOptions);
|
|
110
121
|
// Ensure the output directory exists
|
|
111
122
|
const outputDir = path.dirname(path.resolve(outputPath));
|
|
112
123
|
await fs.mkdir(outputDir, { recursive: true });
|
|
113
124
|
// Write the file
|
|
114
|
-
await fs.writeFile(path.resolve(outputPath),
|
|
125
|
+
await fs.writeFile(path.resolve(outputPath), generated.contents);
|
|
126
|
+
return generated.tableNames;
|
|
115
127
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env files the CLI loads, in precedence order, most specific first.
|
|
3
|
+
*
|
|
4
|
+
* This mirrors the cascade Next.js and Vite use. `dotenv` never overwrites a
|
|
5
|
+
* variable that is already set, so loading in this order means earlier entries
|
|
6
|
+
* win, and a real `process.env` value beats every file.
|
|
7
|
+
*
|
|
8
|
+
* `.env.local` matters in particular: it is the file those frameworks read, so
|
|
9
|
+
* without it a project could have working app credentials and a CLI that could
|
|
10
|
+
* not connect — with an error that never mentions the env file.
|
|
11
|
+
*/
|
|
12
|
+
export declare function envFiles(nodeEnv: string | undefined): string[];
|
|
13
|
+
//# sourceMappingURL=env-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-files.d.ts","sourceRoot":"","sources":["../../src/utils/env-files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAO9D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Env files the CLI loads, in precedence order, most specific first.
|
|
3
|
+
*
|
|
4
|
+
* This mirrors the cascade Next.js and Vite use. `dotenv` never overwrites a
|
|
5
|
+
* variable that is already set, so loading in this order means earlier entries
|
|
6
|
+
* win, and a real `process.env` value beats every file.
|
|
7
|
+
*
|
|
8
|
+
* `.env.local` matters in particular: it is the file those frameworks read, so
|
|
9
|
+
* without it a project could have working app credentials and a CLI that could
|
|
10
|
+
* not connect — with an error that never mentions the env file.
|
|
11
|
+
*/
|
|
12
|
+
export function envFiles(nodeEnv) {
|
|
13
|
+
return [
|
|
14
|
+
...(nodeEnv ? [`.env.${nodeEnv}.local`] : []),
|
|
15
|
+
'.env.local',
|
|
16
|
+
...(nodeEnv ? [`.env.${nodeEnv}`] : []),
|
|
17
|
+
'.env',
|
|
18
|
+
];
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "CLI for scaffolding type-safe ClickHouse analytics, semantic datasets, React manifests, and deployments",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"clickhouse",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"open": "^10.0.0",
|
|
31
31
|
"ora": "^8.0.1",
|
|
32
32
|
"prompts": "^2.4.2",
|
|
33
|
-
"@hypequery/
|
|
34
|
-
"@hypequery/
|
|
33
|
+
"@hypequery/protocol": "0.11.0",
|
|
34
|
+
"@hypequery/deployment": "0.7.3"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
37
|
"@napi-rs/keyring": "1.3.0"
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@vitest/coverage-v8": "^3.2.6",
|
|
46
46
|
"typescript": "^5.7.3",
|
|
47
47
|
"vitest": "^3.2.6",
|
|
48
|
-
"@hypequery/serve": "0.
|
|
48
|
+
"@hypequery/serve": "0.16.0"
|
|
49
49
|
},
|
|
50
50
|
"repository": {
|
|
51
51
|
"type": "git",
|