@hypequery/cli 1.3.1 → 1.5.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 +61 -10
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +24 -1
- package/dist/commands/deployment.d.ts +11 -0
- package/dist/commands/deployment.d.ts.map +1 -0
- package/dist/commands/deployment.js +84 -0
- package/dist/commands/generate.d.ts +1 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +22 -3
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +180 -41
- package/dist/generators/chdb.d.ts +13 -0
- package/dist/generators/chdb.d.ts.map +1 -0
- package/dist/generators/chdb.js +17 -0
- package/dist/generators/dataset-generator.d.ts +2 -0
- package/dist/generators/dataset-generator.d.ts.map +1 -1
- package/dist/generators/dataset-generator.js +1 -1
- package/dist/generators/index.d.ts +2 -1
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +2 -0
- package/dist/templates/client.d.ts +7 -2
- package/dist/templates/client.d.ts.map +1 -1
- package/dist/templates/client.js +23 -2
- package/dist/templates/gitignore.d.ts +1 -1
- package/dist/templates/gitignore.d.ts.map +1 -1
- package/dist/templates/gitignore.js +20 -6
- package/dist/utils/chdb-client.d.ts +36 -0
- package/dist/utils/chdb-client.d.ts.map +1 -0
- package/dist/utils/chdb-client.js +122 -0
- package/dist/utils/dependency-installer.d.ts +3 -2
- package/dist/utils/dependency-installer.d.ts.map +1 -1
- package/dist/utils/dependency-installer.js +8 -3
- package/dist/utils/detect-database.d.ts +11 -4
- package/dist/utils/detect-database.d.ts.map +1 -1
- package/dist/utils/detect-database.js +23 -5
- package/dist/utils/prompts.d.ts +6 -8
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +31 -24
- package/package.json +5 -4
- package/dist/utils/clickhouse-sql.d.ts +0 -6
- package/dist/utils/clickhouse-sql.d.ts.map +0 -1
- package/dist/utils/clickhouse-sql.js +0 -18
package/README.md
CHANGED
|
@@ -4,9 +4,10 @@ CLI for scaffolding and running the main hypequery path.
|
|
|
4
4
|
|
|
5
5
|
Use it to:
|
|
6
6
|
|
|
7
|
-
- generate schema types from ClickHouse
|
|
7
|
+
- generate schema types from ClickHouse or embedded chDB
|
|
8
8
|
- scaffold `analytics/` files
|
|
9
9
|
- run the local dev server with docs
|
|
10
|
+
- build and validate portable deployment contracts
|
|
10
11
|
|
|
11
12
|
## Quick Start
|
|
12
13
|
|
|
@@ -36,27 +37,36 @@ npx hypequery init
|
|
|
36
37
|
|
|
37
38
|
It will:
|
|
38
39
|
|
|
39
|
-
-
|
|
40
|
+
- connect to ClickHouse or start an embedded chDB session
|
|
41
|
+
- generate schema types when the database is available
|
|
40
42
|
- create client and query files
|
|
41
|
-
- write `.env` values
|
|
42
|
-
- update `.gitignore
|
|
43
|
-
- install scaffold dependencies, including `zod`
|
|
43
|
+
- write `.env` values for ClickHouse connections
|
|
44
|
+
- update `.gitignore`, including a project-local persistent chDB directory
|
|
45
|
+
- install scaffold dependencies, including `zod` and the selected database adapter
|
|
44
46
|
|
|
45
47
|
Options:
|
|
46
48
|
|
|
47
49
|
- `--path <path>`: output directory, default `analytics/`
|
|
48
50
|
- `--style <style>`: `queries` (default) or `datasets`
|
|
51
|
+
- `--database <type>`: `clickhouse` (default) or `chdb`
|
|
52
|
+
- `--chdb-path <path>`: persistent chDB data directory; omit for an in-memory session
|
|
49
53
|
- `--auth <mode>`: `none` (default) or `context`
|
|
50
54
|
- `--all-tables`: with `--style datasets`, scaffold every table
|
|
51
55
|
- `--tables <names>`: with `--style datasets`, scaffold these comma-separated tables
|
|
52
56
|
- `--exclude-tables <names>`: with `--style datasets`, exclude these comma-separated tables
|
|
53
57
|
- `--no-example`: skip the example query
|
|
54
|
-
- `--no-interactive`:
|
|
58
|
+
- `--no-interactive`: skip prompts; ClickHouse connection details come from env vars
|
|
55
59
|
- `--force`: overwrite existing scaffold files
|
|
56
|
-
- `--skip-connection`: skip testing the
|
|
60
|
+
- `--skip-connection`: skip testing the selected database before scaffolding
|
|
57
61
|
|
|
58
62
|
Set `HYPEQUERY_SKIP_INSTALL=1` to skip the automatic dependency install.
|
|
59
63
|
|
|
64
|
+
To scaffold against persistent embedded chDB without server credentials:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npx hypequery init --database chdb --chdb-path ./analytics.chdb --no-interactive
|
|
68
|
+
```
|
|
69
|
+
|
|
60
70
|
### `hypequery dev`
|
|
61
71
|
|
|
62
72
|
Runs the local serve runtime with docs and hot reload.
|
|
@@ -78,7 +88,7 @@ The CLI understands TypeScript entry files directly, so `analytics/queries.ts` w
|
|
|
78
88
|
|
|
79
89
|
### `hypequery generate`
|
|
80
90
|
|
|
81
|
-
Regenerates schema types from ClickHouse.
|
|
91
|
+
Regenerates schema types from ClickHouse or embedded chDB.
|
|
82
92
|
|
|
83
93
|
```bash
|
|
84
94
|
npx hypequery generate
|
|
@@ -89,7 +99,14 @@ Options:
|
|
|
89
99
|
- `--output <path>`: default `analytics/schema.ts`
|
|
90
100
|
- `--path <path>`: analytics directory (derives `<path>/schema.ts`)
|
|
91
101
|
- `--tables <names>`: comma-separated table list
|
|
92
|
-
- `--database <type>`:
|
|
102
|
+
- `--database <type>`: `clickhouse` or `chdb`; chDB generation must be selected explicitly
|
|
103
|
+
- `--chdb-path <path>`: persistent chDB data directory; omit for an in-memory session
|
|
104
|
+
|
|
105
|
+
For a persistent chDB scaffold, pass the same path used by `init`:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx hypequery generate --database chdb --chdb-path ./analytics.chdb
|
|
109
|
+
```
|
|
93
110
|
|
|
94
111
|
`hypequery generate:types` is an alias for `hypequery generate`.
|
|
95
112
|
|
|
@@ -119,9 +136,42 @@ npx hypequery generate:manifest analytics/api.ts --output analytics/hypequery-ma
|
|
|
119
136
|
The output is the exact serializable JSON returned by `api.manifest()`, including
|
|
120
137
|
semantic keys such as `dataset:orders`.
|
|
121
138
|
|
|
139
|
+
### `hypequery deployment:build`
|
|
140
|
+
|
|
141
|
+
Builds deployment metadata for an exported HypeQuery API and writes the
|
|
142
|
+
artifact with its identity sidecar.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npx hypequery deployment:build analytics/api.ts \
|
|
146
|
+
--runtime-artifact 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The runtime artifact digest is required when named Serve handlers cannot be
|
|
150
|
+
lowered to a portable implementation. Dataset-only APIs can omit it.
|
|
151
|
+
|
|
152
|
+
Options:
|
|
153
|
+
|
|
154
|
+
- `--output <path>`: default `analytics/hypequery-deployment.json`
|
|
155
|
+
- `--runtime <runtime>`: `node` (default) or `python`
|
|
156
|
+
- `--runtime-artifact <sha256>`: lowercase SHA-256 of the built runtime artifact
|
|
157
|
+
- `--entrypoint-prefix <prefix>`: default `queries`
|
|
158
|
+
- `--hash-output <path>`: default `<output>.sha256`
|
|
159
|
+
|
|
160
|
+
The identity sidecar is not compatible with `sha256sum -c`. Use
|
|
161
|
+
`deployment:validate` to validate the artifact and report its identity.
|
|
162
|
+
|
|
163
|
+
### `hypequery deployment:validate`
|
|
164
|
+
|
|
165
|
+
Validates an existing deployment artifact and reports its datasets, queries,
|
|
166
|
+
runtime artifacts, and identity.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npx hypequery deployment:validate analytics/hypequery-deployment.json
|
|
170
|
+
```
|
|
171
|
+
|
|
122
172
|
## Non-interactive Setup
|
|
123
173
|
|
|
124
|
-
`hypequery init --no-interactive` reads:
|
|
174
|
+
For ClickHouse, `hypequery init --no-interactive` reads:
|
|
125
175
|
|
|
126
176
|
- `CLICKHOUSE_URL` or deprecated `CLICKHOUSE_HOST`
|
|
127
177
|
- `CLICKHOUSE_DATABASE`
|
|
@@ -133,6 +183,7 @@ semantic keys such as `dataset:orders`.
|
|
|
133
183
|
- generated scaffold files use NodeNext-safe local `.js` imports
|
|
134
184
|
- `CLICKHOUSE_URL` is now the preferred connection variable
|
|
135
185
|
- the CLI bundles the ClickHouse driver for schema generation
|
|
186
|
+
- chDB runs in memory unless `--chdb-path` is provided; persistent paths must be reused by later `generate` commands
|
|
136
187
|
|
|
137
188
|
## Docs
|
|
138
189
|
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAa9B,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAKpE;AAwJD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,7 @@ import { devCommand } from './commands/dev.js';
|
|
|
6
6
|
import { generateCommand } from './commands/generate.js';
|
|
7
7
|
import { generateDatasetsCommand } from './commands/generate-datasets.js';
|
|
8
8
|
import { generateManifestCommand } from './commands/generate-manifest.js';
|
|
9
|
+
import { buildDeploymentCommand, validateDeploymentCommand, } from './commands/deployment.js';
|
|
9
10
|
const program = new Command();
|
|
10
11
|
function getCliVersion() {
|
|
11
12
|
try {
|
|
@@ -43,7 +44,8 @@ function addTypeGenerationOptions(command) {
|
|
|
43
44
|
.option('-o, --output <path>', 'Output file (default: analytics/schema.ts)')
|
|
44
45
|
.option('--path <path>', 'Analytics directory (derives <path>/schema.ts)')
|
|
45
46
|
.option('--tables <names>', 'Only generate for specific tables (comma-separated)')
|
|
46
|
-
.option('--database <type>', 'Database driver to use (default: auto-detect)')
|
|
47
|
+
.option('--database <type>', 'Database driver to use: clickhouse or chdb (default: auto-detect)')
|
|
48
|
+
.option('--chdb-path <path>', 'Embedded chDB data directory (with --database chdb; omit for in-memory)');
|
|
47
49
|
}
|
|
48
50
|
// Init command
|
|
49
51
|
program
|
|
@@ -51,6 +53,8 @@ program
|
|
|
51
53
|
.description('Initialize a new hypequery project')
|
|
52
54
|
.option('--path <path>', 'Output directory (default: analytics/)')
|
|
53
55
|
.option('--style <style>', 'Scaffold style: queries or datasets')
|
|
56
|
+
.option('--database <type>', 'Database driver: clickhouse (default) or chdb for embedded, zero-server ClickHouse')
|
|
57
|
+
.option('--chdb-path <path>', 'Embedded chDB data directory (with --database chdb; omit for in-memory)')
|
|
54
58
|
.option('--auth <mode>', 'Auth scaffold mode: none or context')
|
|
55
59
|
.option('--all-tables', 'Generate datasets for all discovered tables when using --style datasets')
|
|
56
60
|
.option('--tables <names>', 'Generate datasets for specific tables when using --style datasets (comma-separated)')
|
|
@@ -105,6 +109,23 @@ program
|
|
|
105
109
|
.action(runCommand(async (api, options) => {
|
|
106
110
|
await generateManifestCommand(api, options);
|
|
107
111
|
}));
|
|
112
|
+
program
|
|
113
|
+
.command('deployment:build <api>')
|
|
114
|
+
.description('Build a validated, canonical deployment contract and identity')
|
|
115
|
+
.option('-o, --output <path>', 'Output JSON file (default: analytics/hypequery-deployment.json)')
|
|
116
|
+
.option('--runtime <runtime>', 'Runtime for non-portable handlers: node or python (default: node)')
|
|
117
|
+
.option('--runtime-artifact <sha256>', 'SHA-256 identity of the built runtime artifact')
|
|
118
|
+
.option('--entrypoint-prefix <prefix>', 'Runtime entrypoint prefix (default: queries)')
|
|
119
|
+
.option('--hash-output <path>', 'Deployment identity sidecar path (default: <output>.sha256)')
|
|
120
|
+
.action(runCommand(async (api, options) => {
|
|
121
|
+
await buildDeploymentCommand(api, options);
|
|
122
|
+
}));
|
|
123
|
+
program
|
|
124
|
+
.command('deployment:validate <artifact>')
|
|
125
|
+
.description('Validate a deployment contract and report its identity')
|
|
126
|
+
.action(runCommand(async (artifact) => {
|
|
127
|
+
await validateDeploymentCommand(artifact);
|
|
128
|
+
}));
|
|
108
129
|
// Help command
|
|
109
130
|
program
|
|
110
131
|
.command('help [command]')
|
|
@@ -135,6 +156,8 @@ program.on('--help', () => {
|
|
|
135
156
|
console.log(' hypequery generate:types --output analytics/schema.ts');
|
|
136
157
|
console.log(' hypequery generate:datasets');
|
|
137
158
|
console.log(' hypequery generate:manifest analytics/api.ts --output analytics/hypequery-manifest.json');
|
|
159
|
+
console.log(' hypequery deployment:build analytics/api.ts --runtime-artifact <sha256>');
|
|
160
|
+
console.log(' hypequery deployment:validate analytics/hypequery-deployment.json');
|
|
138
161
|
console.log('');
|
|
139
162
|
console.log('Docs: https://hypequery.com/docs');
|
|
140
163
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ProtocolDeploymentContract } from '@hypequery/protocol';
|
|
2
|
+
export interface BuildDeploymentOptions {
|
|
3
|
+
output?: string;
|
|
4
|
+
runtime?: 'node' | 'python';
|
|
5
|
+
runtimeArtifact?: string;
|
|
6
|
+
entrypointPrefix?: string;
|
|
7
|
+
hashOutput?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildDeploymentCommand(apiPath: string | undefined, options?: BuildDeploymentOptions): Promise<ProtocolDeploymentContract>;
|
|
10
|
+
export declare function validateDeploymentCommand(artifactPath: string | undefined): Promise<ProtocolDeploymentContract>;
|
|
11
|
+
//# sourceMappingURL=deployment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../src/commands/deployment.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,qBAAqB,CAAC;AAM7B,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA8BD,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,0BAA0B,CAAC,CAuCrC;AAED,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,OAAO,CAAC,0BAA0B,CAAC,CAoCrC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { prepareProtocolDeploymentContract, } from '@hypequery/protocol';
|
|
4
|
+
import { loadApiModule } from '../utils/load-api.js';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
const SHA256_PATTERN = /^[0-9a-f]{64}$/;
|
|
7
|
+
function runtimeArtifact(options) {
|
|
8
|
+
if (options.runtimeArtifact === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (!SHA256_PATTERN.test(options.runtimeArtifact)) {
|
|
11
|
+
throw new Error('--runtime-artifact must be a lowercase 64-character SHA-256 digest.');
|
|
12
|
+
}
|
|
13
|
+
const runtime = options.runtime ?? 'node';
|
|
14
|
+
if (runtime !== 'node' && runtime !== 'python') {
|
|
15
|
+
throw new Error('--runtime must be either node or python.');
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
runtime,
|
|
19
|
+
artifactSha256: options.runtimeArtifact,
|
|
20
|
+
...(options.entrypointPrefix !== undefined
|
|
21
|
+
? { entrypointPrefix: options.entrypointPrefix }
|
|
22
|
+
: {}),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export async function buildDeploymentCommand(apiPath, options = {}) {
|
|
26
|
+
if (!apiPath) {
|
|
27
|
+
throw new Error('Missing API module path.\n\n'
|
|
28
|
+
+ 'Usage: hypequery deployment:build analytics/api.ts');
|
|
29
|
+
}
|
|
30
|
+
const artifact = runtimeArtifact(options);
|
|
31
|
+
const api = await loadApiModule(apiPath);
|
|
32
|
+
if (typeof api.deploymentContract !== 'function') {
|
|
33
|
+
throw new Error(`Invalid API module: ${apiPath}\n\n`
|
|
34
|
+
+ 'The exported API must provide deploymentContract(). '
|
|
35
|
+
+ 'Upgrade @hypequery/serve and export the value returned by createAPI() or serve().');
|
|
36
|
+
}
|
|
37
|
+
const contract = api.deploymentContract(artifact ? { runtimeArtifact: artifact } : {});
|
|
38
|
+
const prepared = prepareProtocolDeploymentContract(contract);
|
|
39
|
+
const { canonical, contract: validated, identity: digest } = prepared;
|
|
40
|
+
const outputPath = options.output ?? 'analytics/hypequery-deployment.json';
|
|
41
|
+
const hashOutputPath = options.hashOutput ?? `${outputPath}.sha256`;
|
|
42
|
+
const identitySidecar = [
|
|
43
|
+
'# Hypequery deployment identity v1; not a file checksum or sha256sum input.',
|
|
44
|
+
'# SHA-256(UTF-8("hypequery:deployment:v1") || 0x00 || RFC 8785 canonical bytes); '
|
|
45
|
+
+ 'the output newline is excluded.',
|
|
46
|
+
`${digest} ${path.basename(outputPath)}`,
|
|
47
|
+
'',
|
|
48
|
+
].join('\n');
|
|
49
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
50
|
+
await mkdir(path.dirname(hashOutputPath), { recursive: true });
|
|
51
|
+
await writeFile(outputPath, `${canonical}\n`, 'utf8');
|
|
52
|
+
await writeFile(hashOutputPath, identitySidecar, 'utf8');
|
|
53
|
+
logger.success(`Deployment contract written to ${outputPath}`);
|
|
54
|
+
logger.info(`Identity: ${digest}`);
|
|
55
|
+
return validated;
|
|
56
|
+
}
|
|
57
|
+
export async function validateDeploymentCommand(artifactPath) {
|
|
58
|
+
if (!artifactPath) {
|
|
59
|
+
throw new Error('Missing deployment artifact path.\n\n'
|
|
60
|
+
+ 'Usage: hypequery deployment:validate analytics/hypequery-deployment.json');
|
|
61
|
+
}
|
|
62
|
+
let input;
|
|
63
|
+
try {
|
|
64
|
+
input = JSON.parse(await readFile(artifactPath, 'utf8'));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
throw new Error(`Invalid deployment JSON: ${artifactPath}\n\n`
|
|
68
|
+
+ (error instanceof Error ? error.message : String(error)));
|
|
69
|
+
}
|
|
70
|
+
let prepared;
|
|
71
|
+
try {
|
|
72
|
+
prepared = prepareProtocolDeploymentContract(input);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw new Error(`Invalid deployment contract: ${artifactPath}\n\n`
|
|
76
|
+
+ (error instanceof Error ? error.message : String(error)));
|
|
77
|
+
}
|
|
78
|
+
const { contract, identity: digest } = prepared;
|
|
79
|
+
logger.success(`Valid deployment contract: ${artifactPath}`);
|
|
80
|
+
logger.info(`${contract.datasets.length} datasets, ${contract.queries.length} queries, `
|
|
81
|
+
+ `${contract.artifacts.length} runtime artifacts`);
|
|
82
|
+
logger.info(`Identity: ${digest}`);
|
|
83
|
+
return contract;
|
|
84
|
+
}
|
|
@@ -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;
|
|
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,iBAoJlE"}
|
|
@@ -3,6 +3,7 @@ import ora from 'ora';
|
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { findSchemaFile } from '../utils/find-files.js';
|
|
5
5
|
import { detectDatabase, getTableCount } from '../utils/detect-database.js';
|
|
6
|
+
import { ensureChdbInstalled } from '../utils/chdb-client.js';
|
|
6
7
|
import { getTypeGenerator } from '../generators/index.js';
|
|
7
8
|
import { redactConnectionUrl } from '../utils/redact-connection-url.js';
|
|
8
9
|
export async function generateCommand(options = {}) {
|
|
@@ -33,20 +34,38 @@ export async function generateCommand(options = {}) {
|
|
|
33
34
|
: undefined;
|
|
34
35
|
const requestedDbType = options.database;
|
|
35
36
|
const dbType = requestedDbType ?? (await detectDatabase());
|
|
37
|
+
const chdbPath = dbType === 'chdb' ? options.chdbPath : undefined;
|
|
38
|
+
if (dbType === 'chdb' && !requestedDbType) {
|
|
39
|
+
throw new Error('chDB generation must be explicit. Re-run with --database chdb and add --chdb-path <dir> for persistent storage.');
|
|
40
|
+
}
|
|
36
41
|
logger.newline();
|
|
37
42
|
logger.header(options.commandName ?? 'hypequery generate');
|
|
38
43
|
const spinner = ora(`Connecting to ${dbType}...`).start();
|
|
44
|
+
let activeSpinner = spinner;
|
|
45
|
+
let failureMessage = dbType === 'chdb'
|
|
46
|
+
? 'Failed to start embedded chDB'
|
|
47
|
+
: 'Failed to generate types';
|
|
39
48
|
try {
|
|
40
49
|
const generator = getTypeGenerator(dbType);
|
|
50
|
+
// Surface a missing chdb install as the connection failure it is —
|
|
51
|
+
// getTableCount swallows errors, so without this probe the spinner
|
|
52
|
+
// would report a successful connection and 0 tables before type
|
|
53
|
+
// generation fails.
|
|
54
|
+
if (dbType === 'chdb') {
|
|
55
|
+
await ensureChdbInstalled();
|
|
56
|
+
}
|
|
41
57
|
// Get table count
|
|
42
|
-
const tableCount = await getTableCount(dbType);
|
|
43
|
-
spinner.succeed(`Connected to ${dbType === 'clickhouse' ? 'ClickHouse' : dbType}`);
|
|
58
|
+
const tableCount = await getTableCount(dbType, { chdbPath });
|
|
59
|
+
spinner.succeed(`Connected to ${dbType === 'clickhouse' ? 'ClickHouse' : dbType === 'chdb' ? 'embedded chDB' : dbType}`);
|
|
44
60
|
logger.success(`Found ${tableCount} tables`);
|
|
45
61
|
// Generate types
|
|
46
62
|
const typeSpinner = ora('Generating types...').start();
|
|
63
|
+
activeSpinner = typeSpinner;
|
|
64
|
+
failureMessage = 'Failed to generate types';
|
|
47
65
|
await generator({
|
|
48
66
|
outputPath,
|
|
49
67
|
includeTables: parsedTables,
|
|
68
|
+
chdbPath,
|
|
50
69
|
});
|
|
51
70
|
typeSpinner.succeed(`Generated types for ${tableCount} tables`);
|
|
52
71
|
logger.success(`Updated ${path.relative(process.cwd(), outputPath)}`);
|
|
@@ -55,7 +74,7 @@ export async function generateCommand(options = {}) {
|
|
|
55
74
|
logger.newline();
|
|
56
75
|
}
|
|
57
76
|
catch (error) {
|
|
58
|
-
|
|
77
|
+
activeSpinner.fail(failureMessage);
|
|
59
78
|
logger.newline();
|
|
60
79
|
if (error instanceof Error) {
|
|
61
80
|
logger.error(error.message);
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAWL,KAAK,SAAS,EACf,MAAM,qBAAqB,CAAC;AAe7B,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAQzF,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AA4JD,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,iBAyZ1D"}
|