@housekit/kit 0.1.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/LICENSE +21 -0
- package/README.md +146 -0
- package/dist/commands/check.d.ts +1 -0
- package/dist/commands/drop.d.ts +4 -0
- package/dist/commands/dry-run.d.ts +3 -0
- package/dist/commands/generate.d.ts +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/push.d.ts +5 -0
- package/dist/commands/reset.d.ts +3 -0
- package/dist/commands/schema.d.ts +4 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/truncate.d.ts +4 -0
- package/dist/commands/validate.d.ts +4 -0
- package/dist/config.d.ts +34 -0
- package/dist/db.d.ts +8 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +79 -0
- package/dist/loader.d.ts +5 -0
- package/dist/schema/analyzer.d.ts +35 -0
- package/dist/schema/diff.d.ts +20 -0
- package/dist/schema/parser.d.ts +49 -0
- package/dist/ui.d.ts +32 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pablo Fernandez Ruiz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# HouseKit CLI 🏠⚡️
|
|
2
|
+
|
|
3
|
+
**The modern schema management tool for ClickHouse.**
|
|
4
|
+
|
|
5
|
+
HouseKit CLI brings a modern, streamlined developer experience to the ClickHouse ecosystem. Manage your sharded clusters, analytical tables, and complex materialized views using purely TypeScript—no more manual SQL migration files or structural drift.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/housekit)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🚀 Why HouseKit CLI?
|
|
13
|
+
|
|
14
|
+
- **Declarative Workflows**: Define your source of truth in TypeScript.
|
|
15
|
+
- **Automatic Drift Detection**: Compares your code against the live DB schema instantly.
|
|
16
|
+
- **Blue-Green Deployments**: Safe, zero-downtime structural changes for Materialized Views and Tables.
|
|
17
|
+
- **Cluster Awareness**: First-class support for sharded clusters using `{cluster}` macros and sharding keys.
|
|
18
|
+
- **Zero Runtime Dependencies**: Powered by `jiti` for native TS loading—no pre-compilation or heavy binaries required.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🛠 Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Recommended: install as a dev dependency
|
|
26
|
+
npm install -D @housekit/kit @housekit/orm
|
|
27
|
+
# or
|
|
28
|
+
bun add -D @housekit/kit @housekit/orm
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 📖 The Two Workflows
|
|
34
|
+
|
|
35
|
+
HouseKit supports two distinct ways of working depending on your environment.
|
|
36
|
+
|
|
37
|
+
### 1. Rapid Development: `housekit push`
|
|
38
|
+
Perfect for early-stage projects or local development. It computes the delta between your TS files and the database and applies it immediately.
|
|
39
|
+
- **Safe**: Asks for confirmation before any destructive change.
|
|
40
|
+
- **Fast**: Skips the creation of migration files.
|
|
41
|
+
- **Smart**: Handles column renames and type changes.
|
|
42
|
+
|
|
43
|
+
### 2. Controlled Production: `housekit generate` & `migrate`
|
|
44
|
+
The standard for CI/CD and production environments.
|
|
45
|
+
- **Generate**: Compares your code against a `snapshot.json` and creates a timestamped `.sql` file in your migrations folder.
|
|
46
|
+
- **Migrate**: Executes pending SQL files against the target database, tracking history in `system.migrations`.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 💻 Commands
|
|
51
|
+
|
|
52
|
+
| Command | Description |
|
|
53
|
+
| :--- | :--- |
|
|
54
|
+
| `init` | Bootstraps a new HouseKit project with config and folder structure. |
|
|
55
|
+
| `push` | Syncs local schema directly to the database. Supports `--log-explain`. |
|
|
56
|
+
| `generate` | Creates a new SQL migration file based on schema changes. |
|
|
57
|
+
| `migrate` | Applies pending SQL migrations to the database. |
|
|
58
|
+
| `pull` | **Introspection**: Connects to a DB and generates typed TS schema files. |
|
|
59
|
+
| `schema` | Prints a beautiful, color-coded summary of your tables and types. |
|
|
60
|
+
| `status` | Lists all detected differences between your code and the database. |
|
|
61
|
+
| `validate` | Checks if code and DB are in sync (exit code 1 on drift). Great for CI. |
|
|
62
|
+
| `list` | Summarizes row counts, engines, and sizes for all tables. |
|
|
63
|
+
| `reset` | Wipes the database and restarts from your code schema (Dev only). |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## ⚙️ Configuration
|
|
68
|
+
|
|
69
|
+
Create a `housekit.config.ts` (or `.js`, `.mjs`) in your project root.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import type { HouseKitConfig } from 'housekit';
|
|
73
|
+
|
|
74
|
+
export default {
|
|
75
|
+
// Path to your table/view definitions
|
|
76
|
+
schema: './src/schema',
|
|
77
|
+
|
|
78
|
+
// Where migrations and snapshots will be stored
|
|
79
|
+
out: './housekit',
|
|
80
|
+
|
|
81
|
+
// Multi-database support
|
|
82
|
+
databases: {
|
|
83
|
+
default: {
|
|
84
|
+
host: 'localhost',
|
|
85
|
+
port: 8123,
|
|
86
|
+
database: 'analytics_dev',
|
|
87
|
+
username: 'default',
|
|
88
|
+
password: process.env.CLICKHOUSE_PASSWORD || '',
|
|
89
|
+
},
|
|
90
|
+
production: {
|
|
91
|
+
url: process.env.CLICKHOUSE_PROD_URL,
|
|
92
|
+
database: 'analytics_prod',
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} satisfies HouseKitConfig;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 🏗 Advanced Usage
|
|
101
|
+
|
|
102
|
+
### Working with Clusters
|
|
103
|
+
HouseKit simplifies managing Replicated and Distributed tables across a cluster.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Define a table that lives on a cluster
|
|
107
|
+
export const events = defineTable('events', { ... }, {
|
|
108
|
+
engine: Engine.ReplicatedMergeTree(),
|
|
109
|
+
|
|
110
|
+
// High Portability: Using '{cluster}' tells ClickHouse to use the
|
|
111
|
+
// cluster name defined in the server's configuration macros.
|
|
112
|
+
// This allows the same code to run on 'dev_cluster', 'prod_cluster', etc.
|
|
113
|
+
onCluster: '{cluster}',
|
|
114
|
+
|
|
115
|
+
shardKey: 'user_id',
|
|
116
|
+
orderBy: 'id'
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
When you run `housekit push`, the CLI automatically detects the cluster configuration and executes the `ALTER` or `CREATE` statements across all nodes using the specified macro.
|
|
120
|
+
|
|
121
|
+
### Safe Materialized View Updates
|
|
122
|
+
ClickHouse doesn't allow `ALTER` on Materialized View queries. HouseKit solves this via **Blue-Green Deployments**:
|
|
123
|
+
1. Creates a `__shadow` table with the new query.
|
|
124
|
+
2. Swaps the names atomically using `RENAME`.
|
|
125
|
+
3. Ensures zero data loss during the transition.
|
|
126
|
+
|
|
127
|
+
### Database Introspection (`pull`)
|
|
128
|
+
Have an existing database with 100 tables? Don't write the code by hand.
|
|
129
|
+
```bash
|
|
130
|
+
bunx housekit pull --database production
|
|
131
|
+
```
|
|
132
|
+
This will scan your ClickHouse instance and generate a clean, readable `schema.ts` file with all table definitions, engines, and settings preserved.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 🛡 Security & Best Practices
|
|
137
|
+
|
|
138
|
+
- **Credentials**: Never hardcode passwords. Use `process.env`.
|
|
139
|
+
- **Read-Only Mode**: In `housekit.config.ts`, you can mark databases as `readOnly: true` to prevent accidental `push` or `migrate` calls.
|
|
140
|
+
- **Validation**: Add `housekit validate` to your CI pipeline to ensure no developer forgot to generate a migration before merging.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT © [Pablo Fernandez Ruiz](https://github.com/pablofdezr)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function checkCommand(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateCommand(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function initCommand(): Promise<void>;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface DatabaseConnection {
|
|
2
|
+
host?: string;
|
|
3
|
+
port?: number;
|
|
4
|
+
database: string;
|
|
5
|
+
username?: string;
|
|
6
|
+
password?: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HouseKitConfig {
|
|
10
|
+
/**
|
|
11
|
+
* Path to the directory containing your schema files (.ts or .js).
|
|
12
|
+
* Can be a single path or a mapping for multiple databases.
|
|
13
|
+
*/
|
|
14
|
+
schema: string | Record<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* Directory where SQL migrations and snapshots will be generated.
|
|
17
|
+
*/
|
|
18
|
+
out: string;
|
|
19
|
+
language?: 'ts' | 'js';
|
|
20
|
+
/**
|
|
21
|
+
* ClickHouse connection configuration.
|
|
22
|
+
* Each key represents the database name you will use in the CLI with `--database`.
|
|
23
|
+
*/
|
|
24
|
+
databases: Record<string, DatabaseConnection>;
|
|
25
|
+
}
|
|
26
|
+
export type { HouseKitConfig as default };
|
|
27
|
+
/**
|
|
28
|
+
* Helper to get all database configurations
|
|
29
|
+
*/
|
|
30
|
+
export declare function getDatabaseConfigs(config: HouseKitConfig): Record<string, DatabaseConnection>;
|
|
31
|
+
/**
|
|
32
|
+
* Helper to get schema paths mapped to databases
|
|
33
|
+
*/
|
|
34
|
+
export declare function getSchemaMapping(config: HouseKitConfig): Record<string, string>;
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ClickHouseClient } from '@clickhouse/client';
|
|
2
|
+
import { type HouseKitConfig } from './config';
|
|
3
|
+
export interface ResolvedDatabase {
|
|
4
|
+
name: string;
|
|
5
|
+
client: ClickHouseClient;
|
|
6
|
+
schemaPath?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveDatabase(config: HouseKitConfig, name?: string): ResolvedDatabase;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { createRequire } from "module";
|
|
7
|
+
import { generateCommand } from "./commands/generate";
|
|
8
|
+
import { pushCommand } from "./commands/push";
|
|
9
|
+
import { migrateCommand } from "./commands/migrate";
|
|
10
|
+
import { pullCommand } from "./commands/pull";
|
|
11
|
+
import { schemaCommand } from "./commands/schema";
|
|
12
|
+
import { checkCommand } from "./commands/check";
|
|
13
|
+
import { dropCommand } from "./commands/drop";
|
|
14
|
+
import { truncateCommand } from "./commands/truncate";
|
|
15
|
+
import { dryRunCommand } from "./commands/dry-run";
|
|
16
|
+
import { statusCommand } from "./commands/status";
|
|
17
|
+
import { initCommand } from "./commands/init";
|
|
18
|
+
import { resetCommand } from "./commands/reset";
|
|
19
|
+
import { listCommand } from "./commands/list";
|
|
20
|
+
import { validateCommand } from "./commands/validate";
|
|
21
|
+
import { setGlobalYesMode } from "./ui";
|
|
22
|
+
var program = new Command;
|
|
23
|
+
var require2 = createRequire(import.meta.url);
|
|
24
|
+
var { version } = require2("../package.json");
|
|
25
|
+
program.name("housekit").description("CLI to manage ClickHouse schemas").version(version).option("-y, --yes", "Auto-confirm all prompts");
|
|
26
|
+
program.hook("preAction", (thisCommand) => {
|
|
27
|
+
const opts = thisCommand.optsWithGlobals?.() ?? thisCommand.opts();
|
|
28
|
+
setGlobalYesMode(Boolean(opts.yes));
|
|
29
|
+
});
|
|
30
|
+
function withErrorHandling(fn) {
|
|
31
|
+
return async (...args) => {
|
|
32
|
+
try {
|
|
33
|
+
await fn(...args);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.error(chalk.red(`
|
|
36
|
+
✖ Error: ` + (error.message || String(error))));
|
|
37
|
+
if (process.env.DEBUG) {
|
|
38
|
+
console.error(error);
|
|
39
|
+
}
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
var asciiLogo = [
|
|
45
|
+
"░█░█░█▀█░█░█░█▀▀░█▀▀░█░█░▀█▀░▀█▀",
|
|
46
|
+
"░█▀█░█░█░█░█░▀▀█░█▀▀░█▀▄░░█░░░█░",
|
|
47
|
+
"░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀▀▀░░▀░"
|
|
48
|
+
].join(`
|
|
49
|
+
`);
|
|
50
|
+
program.addHelpText("before", () => [
|
|
51
|
+
chalk.white(asciiLogo),
|
|
52
|
+
"",
|
|
53
|
+
chalk.bold("Housekit — The Modern ORM for ClickHouse"),
|
|
54
|
+
chalk.gray("Build, migrate, introspect, and query ClickHouse schemas with type-safe, ergonomic tooling. Zero friction. Maximum speed.")
|
|
55
|
+
].join(`
|
|
56
|
+
`));
|
|
57
|
+
program.addHelpText("after", () => [
|
|
58
|
+
"",
|
|
59
|
+
chalk.gray("Tips:"),
|
|
60
|
+
chalk.gray(" - Configure your databases in housekit.config.{ts,js}."),
|
|
61
|
+
chalk.gray(" - Use --database to target a specific DB."),
|
|
62
|
+
chalk.gray(' - Try "housekit schema --tables=foo,bar" to inspect specific tables.')
|
|
63
|
+
].join(`
|
|
64
|
+
`));
|
|
65
|
+
program.command("generate").description("Generate SQL migration files based on schema changes").action(withErrorHandling(generateCommand));
|
|
66
|
+
program.command("push").description("Synchronize code schema directly with database").option("-d, --database <name>", "Database to use").option("--log-explain", "Write EXPLAIN plans to .housekit (disabled by default)").option("--auto-upgrade-metadata", "Automatically upgrade housekit metadata to the version declared in code").action(withErrorHandling(pushCommand));
|
|
67
|
+
program.command("dry-run").description("Preview changes that would be applied without executing them").option("-d, --database <name>", "Database to use").action(withErrorHandling(dryRunCommand));
|
|
68
|
+
program.command("migrate").description("Apply generated SQL migrations to the database").option("-d, --database <name>", "Database to use").action(withErrorHandling(migrateCommand));
|
|
69
|
+
program.command("pull").description("Introspect the database schema and generate TS schema files").option("-d, --database <name>", "Database to use").action(withErrorHandling(pullCommand));
|
|
70
|
+
program.command("schema").description("Print current database schema with types").option("-d, --database <name>", "Database to use").option("-t, --tables <tables>", "Table(s) to display, comma-separated", (value) => value.split(",").map((t) => t.trim()).filter(Boolean)).action(withErrorHandling(schemaCommand));
|
|
71
|
+
program.command("check").description("Check migration files for collisions or inconsistencies").action(withErrorHandling(checkCommand));
|
|
72
|
+
program.command("drop").description("Drop tables from the database (requires confirmation)").option("-d, --database <name>", "Database to use").option("-t, --tables <tables>", "Comma-separated list of tables to drop").action(withErrorHandling(dropCommand));
|
|
73
|
+
program.command("truncate").description("Truncate tables (remove all data but keep table structure)").option("-d, --database <name>", "Database to use").option("-t, --tables <tables>", "Comma-separated list of tables to truncate").action(withErrorHandling(truncateCommand));
|
|
74
|
+
program.command("status").description("Show migration status (applied vs pending)").option("-d, --database <name>", "Database to use").action(withErrorHandling(statusCommand));
|
|
75
|
+
program.command("init").description("Initialize a new HouseKit project").action(withErrorHandling(initCommand));
|
|
76
|
+
program.command("reset").description("Reset database by dropping all tables (requires confirmation)").option("-d, --database <name>", "Database to use").action(withErrorHandling(resetCommand));
|
|
77
|
+
program.command("list").description("List all tables in the database with basic information").option("-d, --database <name>", "Database to use").action(withErrorHandling(listCommand));
|
|
78
|
+
program.command("validate").description("Validate that code schema matches the database schema").option("-d, --database <name>", "Database to use").option("--auto-upgrade-metadata", "Automatically upgrade housekit metadata to the version declared in code").action(withErrorHandling(validateCommand));
|
|
79
|
+
program.command("help").description("Show help").action(() => program.outputHelp());
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function loadSchema(schemaPath: string, options?: {
|
|
2
|
+
quiet?: boolean;
|
|
3
|
+
}): Promise<Record<string, any>>;
|
|
4
|
+
export declare function getConfigPath(root?: string): Promise<string>;
|
|
5
|
+
export declare function loadConfig(): Promise<import("./config").HouseKitConfig>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ClickHouseClient } from '@clickhouse/client';
|
|
2
|
+
import { type RemoteTableDescription } from './diff';
|
|
3
|
+
export interface TableAnalysis {
|
|
4
|
+
name: string;
|
|
5
|
+
type: 'create' | 'modify' | 'no_changes';
|
|
6
|
+
adds: string[];
|
|
7
|
+
modifies: string[];
|
|
8
|
+
drops: string[];
|
|
9
|
+
optionChanges: string[];
|
|
10
|
+
destructiveReasons: string[];
|
|
11
|
+
warnings: string[];
|
|
12
|
+
plan: string[];
|
|
13
|
+
shadowPlan: string[] | null;
|
|
14
|
+
rowCount: number;
|
|
15
|
+
table: any;
|
|
16
|
+
remote: RemoteTableDescription | null;
|
|
17
|
+
externallyManaged: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface AnalysisOptions {
|
|
20
|
+
autoUpgradeMetadata?: boolean;
|
|
21
|
+
quiet?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detects schema drift between the local schema and the remote database.
|
|
25
|
+
* Centralizes the logic used by push, dry-run, and validate commands.
|
|
26
|
+
*/
|
|
27
|
+
export declare function detectSchemaDrift(client: ClickHouseClient, localSchema: Record<string, any>, options?: AnalysisOptions): Promise<TableAnalysis[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Fetches the description of a remote table, including its columns, defaults, and options.
|
|
30
|
+
*/
|
|
31
|
+
export declare function describeTable(client: ClickHouseClient, tableName: string, quiet?: boolean): Promise<RemoteTableDescription | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Counts rows in a given table.
|
|
34
|
+
*/
|
|
35
|
+
export declare function countRows(client: ClickHouseClient, tableName: string): Promise<number>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ClickHouseColumn } from '@housekit/orm';
|
|
2
|
+
import type { ParsedCreateOptions } from './parser';
|
|
3
|
+
export type RemoteTableDescription = {
|
|
4
|
+
columns: Record<string, string>;
|
|
5
|
+
defaults: Record<string, string>;
|
|
6
|
+
options: ParsedCreateOptions;
|
|
7
|
+
comment: string | null;
|
|
8
|
+
};
|
|
9
|
+
export declare function diffTable(table: any, localCols: Record<string, ClickHouseColumn>, remote: RemoteTableDescription, opts?: {
|
|
10
|
+
autoUpgradeMetadata?: boolean;
|
|
11
|
+
}): {
|
|
12
|
+
plan: string[];
|
|
13
|
+
destructiveReasons: string[];
|
|
14
|
+
drops: string[];
|
|
15
|
+
warnings: string[];
|
|
16
|
+
shadowPlan: string[] | null;
|
|
17
|
+
adds: string[];
|
|
18
|
+
modifies: string[];
|
|
19
|
+
optionChanges: string[];
|
|
20
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type StatementType = 'CREATE_TABLE' | 'ALTER_ADD_COLUMN' | 'ALTER_MODIFY_COLUMN' | 'ALTER_MODIFY_COMMENT' | 'ALTER_TABLE' | 'DROP_TABLE' | 'UNKNOWN';
|
|
2
|
+
export interface ParsedStatement {
|
|
3
|
+
type: StatementType;
|
|
4
|
+
tableName?: string;
|
|
5
|
+
columnName?: string;
|
|
6
|
+
columnType?: string;
|
|
7
|
+
comment?: string;
|
|
8
|
+
statement: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ParsedIndex {
|
|
11
|
+
name: string;
|
|
12
|
+
expression: string;
|
|
13
|
+
type: string;
|
|
14
|
+
granularity?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ParsedProjection {
|
|
17
|
+
name: string;
|
|
18
|
+
query: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ParsedCreateOptions {
|
|
21
|
+
engine?: string;
|
|
22
|
+
onCluster?: string;
|
|
23
|
+
orderBy?: string;
|
|
24
|
+
partitionBy?: string;
|
|
25
|
+
ttl?: string;
|
|
26
|
+
primaryKey?: string;
|
|
27
|
+
indices?: ParsedIndex[];
|
|
28
|
+
projections?: ParsedProjection[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parses a single SQL statement to extract semantic information.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseStatement(statement: string): ParsedStatement;
|
|
34
|
+
/**
|
|
35
|
+
* Parses a SHOW CREATE TABLE statement into structured options.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseCreate(statement: string): ParsedCreateOptions;
|
|
38
|
+
/**
|
|
39
|
+
* Extracts column definitions from a CREATE TABLE statement.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseColumnsFromCreate(statement: string): Array<{
|
|
42
|
+
name: string;
|
|
43
|
+
definition: string;
|
|
44
|
+
defaultValue?: string;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Analyzes EXPLAIN output for potential performance issues.
|
|
48
|
+
*/
|
|
49
|
+
export declare function analyzeExplain(explainText: string): string[];
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare function format(message: string): string;
|
|
2
|
+
export declare function info(message: string): void;
|
|
3
|
+
export declare function warn(message: string): void;
|
|
4
|
+
export declare function success(message: string): void;
|
|
5
|
+
export declare function error(message: string): void;
|
|
6
|
+
export declare function createSpinner(message: string): import("ora").Ora;
|
|
7
|
+
export declare function setGlobalYesMode(enabled: boolean): void;
|
|
8
|
+
export declare function confirmPrompt(message: string, defaultYes?: boolean): Promise<boolean>;
|
|
9
|
+
export interface ListChoice<T = string> {
|
|
10
|
+
name: string;
|
|
11
|
+
value: T;
|
|
12
|
+
}
|
|
13
|
+
export declare function listPrompt<T = string>(message: string, choices: ListChoice<T>[], defaultValue?: T): Promise<T>;
|
|
14
|
+
export declare function inputPrompt(message: string, defaultValue?: string, validate?: (input: string) => boolean | string): Promise<string>;
|
|
15
|
+
export declare function checkboxPrompt<T = string>(message: string, choices: ListChoice<T>[], defaultSelected?: T[]): Promise<T[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Quote a name (table, column, database, etc.) with double quotes
|
|
18
|
+
*/
|
|
19
|
+
export declare function quoteName(name: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Quote a list of names, separated by commas
|
|
22
|
+
*/
|
|
23
|
+
export declare function quoteList(items: string[]): string;
|
|
24
|
+
/**
|
|
25
|
+
* Format a default value, detecting if it's a SQL expression or literal
|
|
26
|
+
* SQL expressions (like now(), 'USD') are not quoted, literals are quoted
|
|
27
|
+
*/
|
|
28
|
+
export declare function quoteValue(value: string | undefined, defaultType?: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Quote a comment value
|
|
31
|
+
*/
|
|
32
|
+
export declare function quoteComment(comment: string | undefined): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@housekit/kit",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "CLI tool for HouseKit - manage ClickHouse schemas, migrations, and database operations with type-safe workflows.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Pablo Fernandez Ruiz",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/pablofdezr/housekit.git",
|
|
20
|
+
"directory": "packages/kit"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/pablofdezr/housekit#readme",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/pablofdezr/housekit/issues"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"clickhouse",
|
|
28
|
+
"cli",
|
|
29
|
+
"migrations",
|
|
30
|
+
"schema",
|
|
31
|
+
"database",
|
|
32
|
+
"devtools",
|
|
33
|
+
"typescript",
|
|
34
|
+
"orm",
|
|
35
|
+
"housekit"
|
|
36
|
+
],
|
|
37
|
+
"bin": {
|
|
38
|
+
"housekit": "dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist/**/*",
|
|
42
|
+
"LICENSE",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target node --external \"*\" && tsc --project tsconfig.build.json && mv dist/packages/kit/src/* dist/ && rm -rf dist/packages",
|
|
47
|
+
"clean": "rm -rf dist"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@clickhouse/client": "^1.14.0",
|
|
51
|
+
"@housekit/orm": "^0.1.1",
|
|
52
|
+
"chalk": "^5.6.2",
|
|
53
|
+
"cli-table3": "^0.6.5",
|
|
54
|
+
"commander": "^12.0.0",
|
|
55
|
+
"inquirer": "^13.0.1",
|
|
56
|
+
"jiti": "^2.6.1",
|
|
57
|
+
"ora": "^9.0.0",
|
|
58
|
+
"random-word-slugs": "^0.1.7"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"typescript": "^5.0.0",
|
|
62
|
+
"glob": "^10.0.0"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=18.0.0"
|
|
69
|
+
}
|
|
70
|
+
}
|