@hypequery/clickhouse 2.0.0 → 2.0.2

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.
Files changed (83) hide show
  1. package/dist/core/features/aggregations.d.ts +27 -1
  2. package/dist/core/features/aggregations.d.ts.map +1 -1
  3. package/dist/core/features/aggregations.js +43 -3
  4. package/dist/core/query-builder.d.ts +1 -0
  5. package/dist/core/query-builder.d.ts.map +1 -1
  6. package/dist/core/query-builder.js +3 -0
  7. package/dist/core/tests/integration/setup.d.ts +2 -10
  8. package/dist/core/tests/integration/setup.d.ts.map +1 -1
  9. package/dist/core/tests/integration/setup.js +30 -251
  10. package/dist/core/utils.d.ts.map +1 -1
  11. package/dist/core/utils.js +2 -1
  12. package/dist/datasets.d.ts +41 -0
  13. package/dist/datasets.d.ts.map +1 -0
  14. package/dist/datasets.js +387 -0
  15. package/dist/migrations/config/index.d.ts +3 -0
  16. package/dist/migrations/config/index.d.ts.map +1 -0
  17. package/dist/migrations/config/index.js +1 -0
  18. package/dist/migrations/config/types.d.ts +45 -0
  19. package/dist/migrations/config/types.d.ts.map +1 -0
  20. package/dist/migrations/config/types.js +28 -0
  21. package/dist/migrations/diff/diff.d.ts +11 -0
  22. package/dist/migrations/diff/diff.d.ts.map +1 -0
  23. package/dist/migrations/diff/diff.js +240 -0
  24. package/dist/migrations/diff/index.d.ts +3 -0
  25. package/dist/migrations/diff/index.d.ts.map +1 -0
  26. package/dist/migrations/diff/index.js +1 -0
  27. package/dist/migrations/diff/types.d.ts +74 -0
  28. package/dist/migrations/diff/types.d.ts.map +1 -0
  29. package/dist/migrations/diff/types.js +1 -0
  30. package/dist/migrations/introspect/index.d.ts +3 -0
  31. package/dist/migrations/introspect/index.d.ts.map +1 -0
  32. package/dist/migrations/introspect/index.js +1 -0
  33. package/dist/migrations/introspect/pull-schema.d.ts +23 -0
  34. package/dist/migrations/introspect/pull-schema.d.ts.map +1 -0
  35. package/dist/migrations/introspect/pull-schema.js +135 -0
  36. package/dist/migrations/plan/index.d.ts +3 -0
  37. package/dist/migrations/plan/index.d.ts.map +1 -0
  38. package/dist/migrations/plan/index.js +1 -0
  39. package/dist/migrations/plan/plan.d.ts +12 -0
  40. package/dist/migrations/plan/plan.d.ts.map +1 -0
  41. package/dist/migrations/plan/plan.js +416 -0
  42. package/dist/migrations/plan/types.d.ts +93 -0
  43. package/dist/migrations/plan/types.d.ts.map +1 -0
  44. package/dist/migrations/plan/types.js +1 -0
  45. package/dist/migrations/schema/column.d.ts +71 -0
  46. package/dist/migrations/schema/column.d.ts.map +1 -0
  47. package/dist/migrations/schema/column.js +123 -0
  48. package/dist/migrations/schema/define.d.ts +24 -0
  49. package/dist/migrations/schema/define.d.ts.map +1 -0
  50. package/dist/migrations/schema/define.js +47 -0
  51. package/dist/migrations/schema/index.d.ts +4 -0
  52. package/dist/migrations/schema/index.d.ts.map +1 -0
  53. package/dist/migrations/schema/index.js +2 -0
  54. package/dist/migrations/schema/types.d.ts +74 -0
  55. package/dist/migrations/schema/types.d.ts.map +1 -0
  56. package/dist/migrations/schema/types.js +1 -0
  57. package/dist/migrations/snapshot/index.d.ts +3 -0
  58. package/dist/migrations/snapshot/index.d.ts.map +1 -0
  59. package/dist/migrations/snapshot/index.js +1 -0
  60. package/dist/migrations/snapshot/serialize.d.ts +21 -0
  61. package/dist/migrations/snapshot/serialize.d.ts.map +1 -0
  62. package/dist/migrations/snapshot/serialize.js +127 -0
  63. package/dist/migrations/snapshot/types.d.ts +47 -0
  64. package/dist/migrations/snapshot/types.d.ts.map +1 -0
  65. package/dist/migrations/snapshot/types.js +1 -0
  66. package/dist/migrations/sql/index.d.ts +4 -0
  67. package/dist/migrations/sql/index.d.ts.map +1 -0
  68. package/dist/migrations/sql/index.js +2 -0
  69. package/dist/migrations/sql/render.d.ts +10 -0
  70. package/dist/migrations/sql/render.d.ts.map +1 -0
  71. package/dist/migrations/sql/render.js +347 -0
  72. package/dist/migrations/sql/types.d.ts +53 -0
  73. package/dist/migrations/sql/types.d.ts.map +1 -0
  74. package/dist/migrations/sql/types.js +1 -0
  75. package/dist/migrations/sql/write.d.ts +10 -0
  76. package/dist/migrations/sql/write.d.ts.map +1 -0
  77. package/dist/migrations/sql/write.js +35 -0
  78. package/dist/semantic-backend.d.ts +7 -0
  79. package/dist/semantic-backend.d.ts.map +1 -0
  80. package/dist/semantic-backend.js +208 -0
  81. package/dist/types/base.d.ts +1 -0
  82. package/dist/types/base.d.ts.map +1 -1
  83. package/package.json +1 -1
@@ -0,0 +1,123 @@
1
+ import { isSQLExpression } from '../../dataset/sql-tag.js';
2
+ /**
3
+ * Immutable builder for ClickHouse column definitions.
4
+ *
5
+ * Each modifier returns a new builder so reusable column fragments can be shared
6
+ * safely without later calls mutating earlier definitions.
7
+ */
8
+ export class ClickHouseColumnBuilder {
9
+ columnType;
10
+ defaultExpression;
11
+ constructor(columnType, defaultExpression) {
12
+ this.columnType = columnType;
13
+ this.defaultExpression = defaultExpression;
14
+ }
15
+ /**
16
+ * Adds a column default.
17
+ *
18
+ * Primitive values are rendered as SQL literals. Use the `sql` template tag for
19
+ * database expressions such as `sql\`now()\``.
20
+ */
21
+ default(expression) {
22
+ return new ClickHouseColumnBuilder(this.columnType, toDefaultValue(expression));
23
+ }
24
+ /**
25
+ * Wraps this column type in `Nullable(...)`.
26
+ */
27
+ nullable() {
28
+ return new ClickHouseColumnBuilder({ kind: 'nullable', inner: this.columnType }, this.defaultExpression);
29
+ }
30
+ /**
31
+ * Wraps this column type in `LowCardinality(...)`.
32
+ */
33
+ lowCardinality() {
34
+ return new ClickHouseColumnBuilder({ kind: 'low_cardinality', inner: this.columnType }, this.defaultExpression);
35
+ }
36
+ /**
37
+ * Materializes the builder into a named column definition for a table AST.
38
+ */
39
+ build(name) {
40
+ return {
41
+ name,
42
+ type: this.columnType,
43
+ ...(this.defaultExpression !== undefined ? { default: this.defaultExpression } : {}),
44
+ };
45
+ }
46
+ /**
47
+ * Returns the underlying type AST for nested type builders.
48
+ */
49
+ toColumnType() {
50
+ return this.columnType;
51
+ }
52
+ }
53
+ /**
54
+ * Factory helpers for common ClickHouse column types.
55
+ *
56
+ * Examples:
57
+ * `column.String().default('pending')`, `column.Nullable('String')`,
58
+ * `column.DateTime('UTC')`.
59
+ */
60
+ export const column = {
61
+ Int8: () => named('Int8'),
62
+ Int16: () => named('Int16'),
63
+ Int32: () => named('Int32'),
64
+ Int64: () => named('Int64'),
65
+ Int128: () => named('Int128'),
66
+ Int256: () => named('Int256'),
67
+ UInt8: () => named('UInt8'),
68
+ UInt16: () => named('UInt16'),
69
+ UInt32: () => named('UInt32'),
70
+ UInt64: () => named('UInt64'),
71
+ UInt128: () => named('UInt128'),
72
+ UInt256: () => named('UInt256'),
73
+ Float32: () => named('Float32'),
74
+ Float64: () => named('Float64'),
75
+ Decimal: (precision, scale) => named('Decimal', precision, scale),
76
+ String: () => named('String'),
77
+ FixedString: (length) => named('FixedString', length),
78
+ Date: () => named('Date'),
79
+ DateTime: (timezone) => timezone ? named('DateTime', timezone) : named('DateTime'),
80
+ DateTime64: (precision, timezone) => timezone ? named('DateTime64', precision, timezone) : named('DateTime64', precision),
81
+ UUID: () => named('UUID'),
82
+ JSON: () => named('JSON'),
83
+ LowCardinality: (inner) => new ClickHouseColumnBuilder({
84
+ kind: 'low_cardinality',
85
+ inner: normalizeNestedColumnType(inner),
86
+ }),
87
+ Nullable: (inner) => new ClickHouseColumnBuilder({
88
+ kind: 'nullable',
89
+ inner: normalizeNestedColumnType(inner),
90
+ }),
91
+ };
92
+ function named(name, ...argumentsList) {
93
+ const type = {
94
+ kind: 'named',
95
+ name,
96
+ ...(argumentsList.length > 0 ? { arguments: argumentsList } : {}),
97
+ };
98
+ return new ClickHouseColumnBuilder(type);
99
+ }
100
+ function normalizeNestedColumnType(input) {
101
+ if (typeof input === 'string') {
102
+ return {
103
+ kind: 'named',
104
+ name: input,
105
+ };
106
+ }
107
+ if (input instanceof ClickHouseColumnBuilder) {
108
+ return input.toColumnType();
109
+ }
110
+ return input;
111
+ }
112
+ function toDefaultValue(input) {
113
+ if (isSQLExpression(input)) {
114
+ return {
115
+ kind: 'sql',
116
+ value: input,
117
+ };
118
+ }
119
+ return {
120
+ kind: 'literal',
121
+ value: input,
122
+ };
123
+ }
@@ -0,0 +1,24 @@
1
+ import type { ClickHouseMaterializedViewDefinition, ClickHouseMaterializedViewInputDefinition, ClickHouseSchemaAst, ClickHouseSchemaDefinition, ClickHouseTableDefinition, ClickHouseTableInputDefinition } from './types.js';
2
+ /**
3
+ * Creates a schema AST from the tables and materialized views declared in code.
4
+ *
5
+ * The returned AST is intentionally not SQL yet. It is serialized into a stable
6
+ * snapshot first, then diffed against a previous snapshot to generate migrations.
7
+ */
8
+ export declare function defineSchema(definition: ClickHouseSchemaDefinition): ClickHouseSchemaAst;
9
+ /**
10
+ * Defines a ClickHouse table for the migration DSL.
11
+ *
12
+ * Column builders are keyed by their final column names, which keeps the schema
13
+ * definition compact while preserving enough structure for snapshot diffing.
14
+ */
15
+ export declare function defineTable(name: string, definition: ClickHouseTableInputDefinition): ClickHouseTableDefinition;
16
+ /**
17
+ * Defines a ClickHouse materialized view and records its source-table dependency.
18
+ *
19
+ * The `from` and `to` fields may reference table definitions directly or use table
20
+ * names. Dependencies are used by the renderer to drop and recreate views around
21
+ * table mutations that could otherwise break stored SELECT definitions.
22
+ */
23
+ export declare function defineMaterializedView(name: string, definition: ClickHouseMaterializedViewInputDefinition): ClickHouseMaterializedViewDefinition;
24
+ //# sourceMappingURL=define.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../src/migrations/schema/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oCAAoC,EACpC,yCAAyC,EACzC,mBAAmB,EACnB,0BAA0B,EAC1B,yBAAyB,EACzB,8BAA8B,EAC/B,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,0BAA0B,GAAG,mBAAmB,CAOxF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,8BAA8B,GACzC,yBAAyB,CAQ3B;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,yCAAyC,GACpD,oCAAoC,CAUtC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Creates a schema AST from the tables and materialized views declared in code.
3
+ *
4
+ * The returned AST is intentionally not SQL yet. It is serialized into a stable
5
+ * snapshot first, then diffed against a previous snapshot to generate migrations.
6
+ */
7
+ export function defineSchema(definition) {
8
+ return {
9
+ tables: [...definition.tables],
10
+ ...(definition.materializedViews !== undefined
11
+ ? { materializedViews: [...definition.materializedViews] }
12
+ : {}),
13
+ };
14
+ }
15
+ /**
16
+ * Defines a ClickHouse table for the migration DSL.
17
+ *
18
+ * Column builders are keyed by their final column names, which keeps the schema
19
+ * definition compact while preserving enough structure for snapshot diffing.
20
+ */
21
+ export function defineTable(name, definition) {
22
+ return {
23
+ kind: 'table',
24
+ name,
25
+ columns: Object.entries(definition.columns).map(([columnName, builder]) => builder.build(columnName)),
26
+ engine: definition.engine,
27
+ ...(definition.settings !== undefined ? { settings: definition.settings } : {}),
28
+ };
29
+ }
30
+ /**
31
+ * Defines a ClickHouse materialized view and records its source-table dependency.
32
+ *
33
+ * The `from` and `to` fields may reference table definitions directly or use table
34
+ * names. Dependencies are used by the renderer to drop and recreate views around
35
+ * table mutations that could otherwise break stored SELECT definitions.
36
+ */
37
+ export function defineMaterializedView(name, definition) {
38
+ return {
39
+ kind: 'materialized_view',
40
+ name,
41
+ from: typeof definition.from === 'string' ? definition.from : definition.from.name,
42
+ ...(definition.to !== undefined
43
+ ? { to: typeof definition.to === 'string' ? definition.to : definition.to.name }
44
+ : {}),
45
+ select: definition.select,
46
+ };
47
+ }
@@ -0,0 +1,4 @@
1
+ export { column, ClickHouseColumnBuilder } from './column.js';
2
+ export { defineMaterializedView, defineSchema, defineTable } from './define.js';
3
+ export type { ClickHouseColumnBuilderLike, ClickHouseColumnDefaultValue, ClickHouseColumnDefinition, ClickHouseColumnType, ClickHouseDefaultInput, ClickHouseLowCardinalityColumnType, ClickHouseLiteralDefaultValue, ClickHouseMaterializedViewDefinition, ClickHouseMaterializedViewInputDefinition, ClickHouseNamedColumnType, ClickHouseNullableColumnType, ClickHouseSqlDefaultValue, ClickHouseSchemaAst, ClickHouseSchemaDefinition, ClickHouseSqlExpression, ClickHouseTableDefinition, ClickHouseTableInputDefinition, ClickHouseTableEngine, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migrations/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhF,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,oBAAoB,EACpB,sBAAsB,EACtB,kCAAkC,EAClC,6BAA6B,EAC7B,oCAAoC,EACpC,yCAAyC,EACzC,yBAAyB,EACzB,4BAA4B,EAC5B,yBAAyB,EACzB,mBAAmB,EACnB,0BAA0B,EAC1B,uBAAuB,EACvB,yBAAyB,EACzB,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { column, ClickHouseColumnBuilder } from './column.js';
2
+ export { defineMaterializedView, defineSchema, defineTable } from './define.js';
@@ -0,0 +1,74 @@
1
+ import type { SQLExpression } from '../../dataset/sql-tag.js';
2
+ export type ClickHouseSqlExpression = string | SQLExpression;
3
+ export type ClickHouseDefaultInput = string | number | boolean | null | SQLExpression;
4
+ export interface ClickHouseSchemaAst {
5
+ tables: ClickHouseTableDefinition[];
6
+ materializedViews?: ClickHouseMaterializedViewDefinition[];
7
+ }
8
+ export interface ClickHouseSchemaDefinition {
9
+ tables: ClickHouseTableDefinition[];
10
+ materializedViews?: ClickHouseMaterializedViewDefinition[];
11
+ }
12
+ export interface ClickHouseTableDefinition {
13
+ kind: 'table';
14
+ name: string;
15
+ columns: ClickHouseColumnDefinition[];
16
+ engine: ClickHouseTableEngine;
17
+ settings?: Record<string, string | number | boolean>;
18
+ }
19
+ export interface ClickHouseTableInputDefinition {
20
+ columns: Record<string, ClickHouseColumnBuilderLike>;
21
+ engine: ClickHouseTableEngine;
22
+ settings?: Record<string, string | number | boolean>;
23
+ }
24
+ export interface ClickHouseColumnDefinition {
25
+ name: string;
26
+ type: ClickHouseColumnType;
27
+ default?: ClickHouseColumnDefaultValue;
28
+ }
29
+ export interface ClickHouseColumnBuilderLike {
30
+ build(name: string): ClickHouseColumnDefinition;
31
+ }
32
+ export type ClickHouseColumnDefaultValue = ClickHouseLiteralDefaultValue | ClickHouseSqlDefaultValue;
33
+ export interface ClickHouseLiteralDefaultValue {
34
+ kind: 'literal';
35
+ value: string | number | boolean | null;
36
+ }
37
+ export interface ClickHouseSqlDefaultValue {
38
+ kind: 'sql';
39
+ value: ClickHouseSqlExpression;
40
+ }
41
+ export type ClickHouseColumnType = ClickHouseNamedColumnType | ClickHouseNullableColumnType | ClickHouseLowCardinalityColumnType;
42
+ export interface ClickHouseNamedColumnType {
43
+ kind: 'named';
44
+ name: string;
45
+ arguments?: Array<string | number>;
46
+ }
47
+ export interface ClickHouseNullableColumnType {
48
+ kind: 'nullable';
49
+ inner: ClickHouseColumnType;
50
+ }
51
+ export interface ClickHouseLowCardinalityColumnType {
52
+ kind: 'low_cardinality';
53
+ inner: ClickHouseColumnType;
54
+ }
55
+ export interface ClickHouseTableEngine {
56
+ type: string;
57
+ orderBy?: ClickHouseSqlExpression[];
58
+ partitionBy?: ClickHouseSqlExpression;
59
+ primaryKey?: ClickHouseSqlExpression[];
60
+ sampleBy?: ClickHouseSqlExpression;
61
+ }
62
+ export interface ClickHouseMaterializedViewDefinition {
63
+ kind: 'materialized_view';
64
+ name: string;
65
+ from: string;
66
+ to?: string;
67
+ select: ClickHouseSqlExpression;
68
+ }
69
+ export interface ClickHouseMaterializedViewInputDefinition {
70
+ from: string | ClickHouseTableDefinition;
71
+ to?: string | ClickHouseTableDefinition;
72
+ select: ClickHouseSqlExpression;
73
+ }
74
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/migrations/schema/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export { hashSnapshot, serializeSchemaToSnapshot, snapshotToStableJson, } from './serialize.js';
2
+ export type { Snapshot, SnapshotColumn, SnapshotColumnDefault, SnapshotDependencyEdge, SnapshotMaterializedView, SnapshotTable, SnapshotTableEngine, } from './types.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migrations/snapshot/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,QAAQ,EACR,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export { hashSnapshot, serializeSchemaToSnapshot, snapshotToStableJson, } from './serialize.js';
@@ -0,0 +1,21 @@
1
+ import type { ClickHouseSchemaAst } from '../schema/types.js';
2
+ import type { Snapshot } from './types.js';
3
+ type SnapshotWithoutHash = Omit<Snapshot, 'contentHash'>;
4
+ /**
5
+ * Converts a schema AST into a deterministic ClickHouse snapshot.
6
+ *
7
+ * Snapshot serialization normalizes ordering, SQL-expression whitespace, type
8
+ * wrappers, settings, and materialized-view dependencies before computing the
9
+ * content hash used by migration metadata.
10
+ */
11
+ export declare function serializeSchemaToSnapshot(schema: ClickHouseSchemaAst): Snapshot;
12
+ /**
13
+ * Serializes a snapshot with stable formatting for writing to disk and hashing.
14
+ */
15
+ export declare function snapshotToStableJson(snapshot: Snapshot | SnapshotWithoutHash): string;
16
+ /**
17
+ * Computes the SHA-256 content hash for a normalized snapshot.
18
+ */
19
+ export declare function hashSnapshot(snapshot: Snapshot | SnapshotWithoutHash): string;
20
+ export {};
21
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../../src/migrations/snapshot/serialize.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,mBAAmB,EAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,QAAQ,EAMT,MAAM,YAAY,CAAC;AAEpB,KAAK,mBAAmB,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,mBAAmB,GAAG,QAAQ,CA6D/E;AAgBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,mBAAmB,GAAG,MAAM,CAErF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,mBAAmB,GAAG,MAAM,CAE7E"}
@@ -0,0 +1,127 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { isSQLExpression } from '../../dataset/sql-tag.js';
3
+ /**
4
+ * Converts a schema AST into a deterministic ClickHouse snapshot.
5
+ *
6
+ * Snapshot serialization normalizes ordering, SQL-expression whitespace, type
7
+ * wrappers, settings, and materialized-view dependencies before computing the
8
+ * content hash used by migration metadata.
9
+ */
10
+ export function serializeSchemaToSnapshot(schema) {
11
+ const snapshot = {
12
+ version: 1,
13
+ dialect: 'clickhouse',
14
+ tables: [...schema.tables]
15
+ .sort((left, right) => left.name.localeCompare(right.name))
16
+ .map((table) => ({
17
+ name: table.name,
18
+ columns: [...table.columns]
19
+ .sort((left, right) => left.name.localeCompare(right.name))
20
+ .map((column) => ({
21
+ name: column.name,
22
+ type: normalizeColumnType(column.type),
23
+ ...(column.default !== undefined
24
+ ? { default: normalizeColumnDefault(column.default) }
25
+ : {}),
26
+ })),
27
+ engine: {
28
+ type: table.engine.type,
29
+ orderBy: (table.engine.orderBy ?? []).map(normalizeSqlExpression),
30
+ ...(table.engine.partitionBy !== undefined
31
+ ? { partitionBy: normalizeSqlExpression(table.engine.partitionBy) }
32
+ : {}),
33
+ primaryKey: (table.engine.primaryKey ?? []).map(normalizeSqlExpression),
34
+ ...(table.engine.sampleBy !== undefined
35
+ ? { sampleBy: normalizeSqlExpression(table.engine.sampleBy) }
36
+ : {}),
37
+ },
38
+ settings: Object.fromEntries(Object.entries(table.settings ?? {})
39
+ .sort(([left], [right]) => left.localeCompare(right))
40
+ .map(([key, value]) => [key, String(value)])),
41
+ })),
42
+ materializedViews: [...(schema.materializedViews ?? [])]
43
+ .sort((left, right) => left.name.localeCompare(right.name))
44
+ .map((view) => ({
45
+ name: view.name,
46
+ from: view.from,
47
+ ...(view.to !== undefined ? { to: view.to } : {}),
48
+ select: normalizeSqlExpression(view.select),
49
+ })),
50
+ dependencies: [...(schema.materializedViews ?? [])]
51
+ .sort((left, right) => left.name.localeCompare(right.name))
52
+ .map((view) => ({
53
+ from: view.from,
54
+ to: view.name,
55
+ kind: 'table_to_materialized_view',
56
+ })),
57
+ };
58
+ return {
59
+ ...snapshot,
60
+ contentHash: hashSnapshot(snapshot),
61
+ };
62
+ }
63
+ function normalizeColumnDefault(defaultValue) {
64
+ if (defaultValue.kind === 'literal') {
65
+ return {
66
+ kind: 'literal',
67
+ value: defaultValue.value,
68
+ };
69
+ }
70
+ return {
71
+ kind: 'sql',
72
+ value: normalizeSqlExpression(defaultValue.value),
73
+ };
74
+ }
75
+ /**
76
+ * Serializes a snapshot with stable formatting for writing to disk and hashing.
77
+ */
78
+ export function snapshotToStableJson(snapshot) {
79
+ return JSON.stringify(snapshot, null, 2);
80
+ }
81
+ /**
82
+ * Computes the SHA-256 content hash for a normalized snapshot.
83
+ */
84
+ export function hashSnapshot(snapshot) {
85
+ return createHash('sha256').update(snapshotToStableJson(snapshot)).digest('hex');
86
+ }
87
+ function normalizeColumnType(type) {
88
+ switch (type.kind) {
89
+ case 'named': {
90
+ const args = type.arguments?.length ? `(${type.arguments.join(', ')})` : '';
91
+ return `${type.name}${args}`;
92
+ }
93
+ case 'nullable':
94
+ return `Nullable(${normalizeColumnType(type.inner)})`;
95
+ case 'low_cardinality':
96
+ return `LowCardinality(${normalizeColumnType(type.inner)})`;
97
+ default: {
98
+ const exhaustiveCheck = type;
99
+ return exhaustiveCheck;
100
+ }
101
+ }
102
+ }
103
+ function normalizeSqlExpression(expression) {
104
+ const sql = typeof expression === 'string'
105
+ ? expression
106
+ : isSQLExpression(expression)
107
+ ? expression.sql
108
+ : String(expression);
109
+ const lines = sql
110
+ .replace(/\r\n/g, '\n')
111
+ .split('\n')
112
+ .map(line => line.replace(/\s+$/g, ''));
113
+ while (lines.length > 0 && lines[0].trim() === '') {
114
+ lines.shift();
115
+ }
116
+ while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
117
+ lines.pop();
118
+ }
119
+ const indents = lines
120
+ .filter(line => line.trim().length > 0)
121
+ .map(line => line.match(/^\s*/)?.[0].length ?? 0);
122
+ const minIndent = indents.length > 0 ? Math.min(...indents) : 0;
123
+ return lines
124
+ .map(line => line.slice(minIndent))
125
+ .join('\n')
126
+ .trim();
127
+ }
@@ -0,0 +1,47 @@
1
+ export interface Snapshot {
2
+ version: 1;
3
+ dialect: 'clickhouse';
4
+ tables: SnapshotTable[];
5
+ materializedViews: SnapshotMaterializedView[];
6
+ dependencies: SnapshotDependencyEdge[];
7
+ contentHash: string;
8
+ }
9
+ export interface SnapshotTable {
10
+ name: string;
11
+ columns: SnapshotColumn[];
12
+ engine: SnapshotTableEngine;
13
+ settings: Record<string, string>;
14
+ }
15
+ export interface SnapshotColumn {
16
+ name: string;
17
+ type: string;
18
+ default?: SnapshotColumnDefault;
19
+ }
20
+ export type SnapshotColumnDefault = SnapshotLiteralColumnDefault | SnapshotSqlColumnDefault;
21
+ export interface SnapshotLiteralColumnDefault {
22
+ kind: 'literal';
23
+ value: string | number | boolean | null;
24
+ }
25
+ export interface SnapshotSqlColumnDefault {
26
+ kind: 'sql';
27
+ value: string;
28
+ }
29
+ export interface SnapshotTableEngine {
30
+ type: string;
31
+ orderBy: string[];
32
+ partitionBy?: string;
33
+ primaryKey: string[];
34
+ sampleBy?: string;
35
+ }
36
+ export interface SnapshotMaterializedView {
37
+ name: string;
38
+ from: string;
39
+ to?: string;
40
+ select: string;
41
+ }
42
+ export interface SnapshotDependencyEdge {
43
+ from: string;
44
+ to: string;
45
+ kind: 'table_to_materialized_view';
46
+ }
47
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/migrations/snapshot/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iBAAiB,EAAE,wBAAwB,EAAE,CAAC;IAC9C,YAAY,EAAE,sBAAsB,EAAE,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC;AAED,MAAM,MAAM,qBAAqB,GAAG,4BAA4B,GAAG,wBAAwB,CAAC;AAE5F,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,4BAA4B,CAAC;CACpC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export { renderMigrationArtifacts } from './render.js';
2
+ export { writeMigrationArtifacts } from './write.js';
3
+ export type { MigrationMeta, RenderMigrationArtifactsInput, RenderMigrationArtifactsOptions, RenderMigrationArtifactsResult, WriteMigrationArtifactsOptions, WriteMigrationArtifactsResult, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migrations/sql/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAErD,YAAY,EACV,aAAa,EACb,6BAA6B,EAC7B,+BAA+B,EAC/B,8BAA8B,EAC9B,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { renderMigrationArtifacts } from './render.js';
2
+ export { writeMigrationArtifacts } from './write.js';
@@ -0,0 +1,10 @@
1
+ import type { RenderMigrationArtifactsInput, RenderMigrationArtifactsOptions, RenderMigrationArtifactsResult } from './types.js';
2
+ /**
3
+ * Renders a snapshot diff into reviewable migration artifacts.
4
+ *
5
+ * The renderer produces forward SQL, best-effort reverse SQL, and metadata. It
6
+ * also sequences dependent materialized views around table mutations so stored
7
+ * view SELECT definitions are dropped and recreated with the target snapshot.
8
+ */
9
+ export declare function renderMigrationArtifacts(input: RenderMigrationArtifactsInput, options: RenderMigrationArtifactsOptions): RenderMigrationArtifactsResult;
10
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/migrations/sql/render.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAEV,6BAA6B,EAC7B,+BAA+B,EAC/B,8BAA8B,EAG/B,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,6BAA6B,EACpC,OAAO,EAAE,+BAA+B,GACvC,8BAA8B,CAkDhC"}