export type PrimitiveColumnType = 'String' | 'UInt8' | 'UInt16' | 'UInt32' | 'UInt64' | 'UInt128' | 'UInt256' | 'Int8' | 'Int16' | 'Int32' | 'Int64' | 'Int128' | 'Int256' | 'Float32' | 'Float64' | 'Bool' | 'Boolean' | 'Date' | 'DateTime' | 'DateTime64'; /** * General-purpose compression codecs. Exactly one ends a codec chain. * Level ranges: LZ4HC 1–12 (default 9), ZSTD 1–22 (default 1). */ export type GeneralColumnCodec = { kind: 'NONE' | 'LZ4' | 'T64' | 'GCD' | 'ALP'; } | { kind: 'LZ4HC'; level?: number; } | { kind: 'ZSTD'; level?: number; }; /** * Preprocessing codecs (zero or more) placed before the general codec. * `size` (bytes) defaults to 1 in ClickHouse for Delta / DoubleDelta / Gorilla. */ export type PreprocessingColumnCodec = { kind: 'Delta' | 'DoubleDelta' | 'Gorilla'; size?: 1 | 2 | 4 | 8; } | { kind: 'FPC'; level: number; floatSize: 4 | 8; }; /** * Escape hatch — passes the raw expression through unchanged. Useful for * codecs we haven't typed (new CH versions, experimental codecs) or unusual * arg shapes. Canonicalization is whitespace-only; round-trip may be noisy. */ export interface RawColumnCodec { kind: 'raw'; expression: string; } export type ColumnCodec = GeneralColumnCodec | PreprocessingColumnCodec | RawColumnCodec; /** Single codec or a chain (preprocessors then exactly one general codec). */ export type ColumnCodecSpec = ColumnCodec | ColumnCodec[]; export type ColumnDefaultKind = 'DEFAULT' | 'MATERIALIZED' | 'ALIAS' | 'EPHEMERAL'; /** * Raw ClickHouse SQL, rendered unquoted (trimmed, with SQL comments removed) * where chkit would otherwise render a literal: a column * `default: { expression: 'now64(3)' }` renders `DEFAULT now64(3)`. */ export interface SQLExpression { expression: string; } /** * A column default: a literal (strings are single-quoted, numbers and booleans * render as written) or a {@link SQLExpression} rendered as SQL. */ export type ColumnDefaultValue = string | number | boolean | SQLExpression; export interface ColumnDefinition { name: string; type: PrimitiveColumnType | string; renamedFrom?: string; nullable?: boolean; /** * Value of the column's `defaultKind` clause (`DEFAULT` unless set). * - `'pending'` → `DEFAULT 'pending'` (a string is always a literal) * - `0` / `false` → `DEFAULT 0` / `DEFAULT false` * - `{ expression: 'now64(3)' }` → `DEFAULT now64(3)` (SQL; comments are * dropped when rendered) * * `'fn:now64(3)'` is the legacy spelling of `{ expression: 'now64(3)' }`; * snapshots store both as the `fn:` string. `generate` rejects a plain string * that starts with a function call as the `DEFAULT` of a column that cannot * hold a string (`column_default_looks_like_expression`), and any plain * string on a `MATERIALIZED` or `ALIAS` column (`column_expression_requires_fn`). */ default?: ColumnDefaultValue; /** * How ClickHouse uses `default`: `DEFAULT` (the implicit kind), * `MATERIALIZED`, `ALIAS`, or `EPHEMERAL`. The literal and `{ expression }` * forms of `default` work for every kind: * `{ defaultKind: 'MATERIALIZED', default: { expression: 'toDate(ts)' } }` * renders `MATERIALIZED toDate(ts)`. */ defaultKind?: ColumnDefaultKind; comment?: string; codec?: ColumnCodecSpec; } interface SkipIndexBase { name: string; expression: string; granularity: number; } /** Full-text index. ClickHouse ignores granularity and uses one index per part. */ export interface TextSkipIndex extends Omit { type: 'text'; /** SQL tokenizer, e.g. splitByNonAlpha or splitByString([' ', ';']). */ tokenizer: string; granularity?: number; preprocessor?: string; /** Requires a ClickHouse version that supports postprocessing. */ postprocessor?: string; supportPhraseSearch?: boolean; dictionaryBlockSize?: number; dictionaryBlockFrontcodingCompression?: boolean; postingListBlockSize?: number; postingListCodec?: 'none' | 'bitpacking'; } /** * Skip index with structured, discriminated args per type. Arg signatures * come from ClickHouse MergeTree docs: * - `minmax` — no args * - `set(max_rows)` — required int, 0 = store all unique values * - `bloom_filter([false_positive_rate])` — optional float, default 0.025 * - `tokenbf_v1(size_bytes, n_hash, seed)` — 3 required ints * - `ngrambf_v1(n, size_bytes, n_hash, seed)` — 4 required ints * - `text(tokenizer = ..., ...)` — named parameters, automatic granularity * * ClickHouse 26+ requires `set(0)` not bare `set`; `maxRows` is required * so this is encoded naturally. */ export type SkipIndexDefinition = TextSkipIndex | SkipIndexBase & ({ type: 'minmax'; } | { type: 'set'; maxRows: number; } | { type: 'bloom_filter'; falsePositiveRate?: number; } | { type: 'tokenbf_v1'; sizeBytes: number; hashFunctions: number; randomSeed: number; } | { type: 'ngrambf_v1'; ngramSize: number; sizeBytes: number; hashFunctions: number; randomSeed: number; }); export interface SelectProjectionDefinition { name: string; query: string; } /** * An index-only projection (`PROJECTION p INDEX (a, b) TYPE basic`) has no * SELECT body: it only reorders parts to prune on a secondary key. ClickHouse * currently accepts `basic` as the only index type, but `type` stays a string * so new types work without a DSL change. */ export interface IndexProjectionDefinition { name: string; /** Expression list, e.g. `receiver, sender`. Parenthesized on render. */ index: string; type: string; } export type ProjectionDefinition = SelectProjectionDefinition | IndexProjectionDefinition; export interface TablePlugins { } export interface TableDefinition { kind: 'table'; database: string; name: string; renamedFrom?: { database?: string; name: string; }; columns: ColumnDefinition[]; engine: string; primaryKey: string[]; orderBy: string[]; uniqueKey?: string[]; partitionBy?: string; ttl?: string; settings?: Record; indexes?: SkipIndexDefinition[]; projections?: ProjectionDefinition[]; comment?: string; plugins?: TablePlugins; } /** Omitted primary keys inherit ORDER BY, matching ClickHouse MergeTree semantics. */ export type TableInput = Omit & { primaryKey?: string[]; }; /** Kafka queues do not have MergeTree sorting/storage clauses. */ export type KafkaTableInput = Omit & { engine: 'Kafka' | `Kafka(${string})`; primaryKey?: never; orderBy?: never; partitionBy?: never; uniqueKey?: never; ttl?: never; indexes?: never; projections?: never; }; export interface ViewDefinition { kind: 'view'; database: string; name: string; as: string; comment?: string; } export interface MaterializedViewRefresh { every?: string; after?: string; offset?: string; randomize?: string; dependsOn?: Array<{ database: string; name: string; }>; settings?: Record; append?: boolean; empty?: boolean; } export interface MaterializedViewDefinition { kind: 'materialized_view'; database: string; name: string; to: { database: string; name: string; }; refresh?: MaterializedViewRefresh; as: string; comment?: string; } export interface DictionaryAttribute { name: string; type: PrimitiveColumnType | string; /** DEFAULT / null_value for missing keys. A literal: ClickHouse accepts no expression here. */ default?: string | number | boolean; /** EXPRESSION — computed from source columns. Mutually exclusive with default. */ expression?: string; hierarchical?: boolean; /** Enables bidirectional parent/child lookups. Only valid alongside hierarchical. */ bidirectional?: boolean; injective?: boolean; isObjectId?: boolean; } export interface DictionaryDefinition { kind: 'dictionary'; database: string; name: string; renamedFrom?: { database?: string; name: string; }; attributes: DictionaryAttribute[]; primaryKey: string[]; /** Raw SOURCE(...) body, e.g. `MYSQL(host '...' password '${env}' ...)`. */ source: string; /** Raw LAYOUT(...) body, e.g. `HASHED()` / `COMPLEX_KEY_HASHED()`. */ layout: string; /** Raw LIFETIME(...) body, e.g. `300` / `MIN 300 MAX 360`. */ lifetime: string; /** RANGE(MIN ... MAX ...) — required by RANGE_HASHED / COMPLEX_KEY_RANGE_HASHED layouts. */ range?: { min: string; max: string; }; /** Raw SETTINGS(...) key/value pairs. */ settings?: Record; comment?: string; } export type SchemaDefinition = TableDefinition | ViewDefinition | MaterializedViewDefinition | DictionaryDefinition; export interface ChxCheckConfig { failOnPending?: boolean; failOnChecksumMismatch?: boolean; failOnDrift?: boolean; /** * Treat objects that exist in ClickHouse but are not in your schema * (`extra_object`) as drift. Defaults to `false` so chkit coexists with * unmanaged tables on a shared database — only opt in when chkit is expected * to own the entire database. */ failOnExtraObjects?: boolean; } export interface ChxSafetyConfig { allowDestructive?: boolean; } export interface ChxUserClickHouseConfig { url: string; username?: string; password?: string; database?: string; secure?: boolean; /** * Cluster name for self-managed multi-node clusters. When set, chkit emits * `ON CLUSTER ` on generated DDL and stores its migration journal in a * replicated engine. Leave unset for single-node, ClickHouse Cloud, or * ObsessionDB (SharedMergeTree auto-replicates — `ON CLUSTER` is unnecessary). * Accepts an identifier (e.g. `"my_cluster"`) or a macro (e.g. `"{cluster}"`). */ cluster?: string; } export interface ChxResolvedClickHouseConfig { url: string; username: string; password: string; database: string; secure: boolean; cluster?: string; } export interface ChxInlinePluginRegistration> { plugin: TPlugin; name?: string; enabled?: boolean; options?: TOptions; } export type ChxPluginRegistration = ChxInlinePluginRegistration; export interface ChxUserConfig { /** * Glob patterns for schema files. Mutually exclusive with `entry`. */ schema?: string | string[]; /** * Single project entry module. It is imported once: exported schema * definitions are collected from it, and exported plugin-domain definitions * (for example ingestion pipelines) are collected by their plugins. Mutually * exclusive with `schema`. */ entry?: string; outDir?: string; migrationsDir?: string; metaDir?: string; plugins?: ChxPluginRegistration[]; check?: ChxCheckConfig; safety?: ChxSafetyConfig; clickhouse?: ChxUserClickHouseConfig; } export interface ChxResolvedConfig { schema: string[]; entry?: string; outDir: string; migrationsDir: string; metaDir: string; plugins: ChxPluginRegistration[]; check: Required; safety: Required; clickhouse?: ChxResolvedClickHouseConfig; } export interface ChxConfigEnv { command?: string; mode?: string; } export type ChxConfigFn = (env: ChxConfigEnv) => T | Promise; export type ChxConfigInput = T | ChxConfigFn; export type ChxConfig = ChxUserConfig; export type ResolvedChxConfig = ChxResolvedConfig; export interface SnapshotV1 { version: 1; generatedAt: string; definitions: SchemaDefinition[]; } export type Snapshot = SnapshotV1; export type RiskLevel = 'safe' | 'caution' | 'danger'; export type MigrationOperationType = 'create_database' | 'create_table' | 'drop_table' | 'create_view' | 'drop_view' | 'create_materialized_view' | 'drop_materialized_view' | 'alter_materialized_view_modify_refresh' | 'alter_table_add_column' | 'alter_table_modify_column' | 'alter_table_drop_column' | 'alter_table_rename_column' | 'alter_table_rename_table' | 'alter_table_add_index' | 'alter_table_add_projection' | 'alter_table_modify_setting' | 'alter_table_drop_index' | 'alter_table_drop_projection' | 'alter_table_reset_setting' | 'alter_table_modify_ttl' | 'create_dictionary' | 'drop_dictionary' | 'rename_dictionary'; export interface MigrationOperation { type: MigrationOperationType; key: string; risk: RiskLevel; sql: string; warning?: string; } export interface ColumnRenameSuggestion { kind: 'column'; database: string; table: string; from: string; to: string; confidence: 'high'; reason: string; dropOperationKey: string; addOperationKey: string; confirmationSQL: string; } export interface MigrationPlan { operations: MigrationOperation[]; riskSummary: Record; renameSuggestions: ColumnRenameSuggestion[]; } export type ValidationIssueCode = 'kafka_unsupported_clause' | 'kafka_column_default' | 'kafka_missing_setting' | 'kafka_invalid_setting' | 'kafka_change_requires_replacement' | 'column_kind_change_unsupported' | 'duplicate_object_name' | 'duplicate_column_name' | 'duplicate_index_name' | 'text_index_invalid_parameters' | 'duplicate_projection_name' | 'projection_ambiguous_kind' | 'projection_empty_index' | 'primary_key_missing_column' | 'order_by_missing_column' | 'refresh_requires_every_or_after' | 'refresh_every_after_mutually_exclusive' | 'refresh_interval_format' | 'refresh_append_required_for_replicated_target' | 'refresh_depends_on_requires_every' | 'codec_chain_must_end_with_general' | 'codec_chain_multiple_general' | 'codec_chain_empty' | 'column_default_kind_invalid' | 'column_expression_required' | 'column_expression_requires_fn' | 'column_kind_not_stored' | 'column_ephemeral_in_projection' | 'column_kind_codec_unsupported' | 'column_default_looks_like_expression' | 'column_default_invalid' | 'dictionary_missing_primary_key' | 'dictionary_primary_key_missing_attribute' | 'dictionary_missing_source' | 'dictionary_missing_layout' | 'dictionary_missing_lifetime' | 'dictionary_attribute_default_expression_exclusive' | 'dictionary_range_missing_attribute' | 'dictionary_bidirectional_requires_hierarchical' | 'invalid_identifier'; export interface ValidationIssue { code: ValidationIssueCode; kind: SchemaDefinition['kind']; database: string; name: string; message: string; } export {}; //# sourceMappingURL=model-types.d.ts.map