@housekit/orm 0.1.17 → 0.1.21

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/index.js CHANGED
@@ -192,8 +192,8 @@ class BinaryReader {
192
192
  return new Date(Number(ms));
193
193
  }
194
194
  readNullable(reader) {
195
- const isNull = this.readUInt8();
196
- if (isNull === 1)
195
+ const isNull2 = this.readUInt8();
196
+ if (isNull2 === 1)
197
197
  return null;
198
198
  return reader();
199
199
  }
@@ -2157,6 +2157,144 @@ function generateRandom(structure, randomSeed, maxStringLength = 10, maxArrayLen
2157
2157
  };
2158
2158
  }
2159
2159
 
2160
+ // src/modules/conditional.ts
2161
+ function ifNull(col, alt) {
2162
+ return sql`ifNull(${col}, ${alt})`;
2163
+ }
2164
+ function sqlIf(condition, trueVal, falseVal) {
2165
+ return sql`if(${condition}, ${trueVal}, ${falseVal})`;
2166
+ }
2167
+ function multiIf(...args) {
2168
+ if (args.length < 3) {
2169
+ throw new Error("multiIf requires at least 3 arguments: condition, value, default");
2170
+ }
2171
+ if (args.length % 2 === 0) {
2172
+ throw new Error("multiIf requires an odd number of arguments: condition-value pairs plus a default value");
2173
+ }
2174
+ const params = args.map((arg) => sql`${arg}`).join(", ");
2175
+ return sql`multiIf(${params})`;
2176
+ }
2177
+ function caseWhen() {
2178
+ return new CaseWhenBuilder;
2179
+ }
2180
+
2181
+ class CaseWhenBuilder {
2182
+ conditions = [];
2183
+ values = [];
2184
+ defaultValue;
2185
+ when(condition, value) {
2186
+ this.conditions.push(condition);
2187
+ this.values.push(value);
2188
+ return this;
2189
+ }
2190
+ otherwise(value) {
2191
+ this.defaultValue = value;
2192
+ return this.build();
2193
+ }
2194
+ build() {
2195
+ if (!this.defaultValue) {
2196
+ throw new Error("CaseWhenBuilder requires a default value via .otherwise()");
2197
+ }
2198
+ const args = [];
2199
+ for (let i = 0;i < this.conditions.length; i++) {
2200
+ args.push(this.conditions[i]);
2201
+ args.push(this.values[i]);
2202
+ }
2203
+ args.push(this.defaultValue);
2204
+ return multiIf(...args);
2205
+ }
2206
+ }
2207
+ function coalesce(...args) {
2208
+ const chunks = ["coalesce("];
2209
+ const params = [];
2210
+ args.forEach((arg, i) => {
2211
+ params.push(arg);
2212
+ if (i < args.length - 1) {
2213
+ chunks.push(", ");
2214
+ }
2215
+ });
2216
+ chunks.push(")");
2217
+ return new SQL(chunks, params);
2218
+ }
2219
+ function greatest(...args) {
2220
+ const chunks = ["greatest("];
2221
+ const params = [];
2222
+ args.forEach((arg, i) => {
2223
+ params.push(arg);
2224
+ if (i < args.length - 1) {
2225
+ chunks.push(", ");
2226
+ }
2227
+ });
2228
+ chunks.push(")");
2229
+ return new SQL(chunks, params);
2230
+ }
2231
+ function least(...args) {
2232
+ const chunks = ["least("];
2233
+ const params = [];
2234
+ args.forEach((arg, i) => {
2235
+ params.push(arg);
2236
+ if (i < args.length - 1) {
2237
+ chunks.push(", ");
2238
+ }
2239
+ });
2240
+ chunks.push(")");
2241
+ return new SQL(chunks, params);
2242
+ }
2243
+ function isNull(col) {
2244
+ return sql`${col} IS NULL`;
2245
+ }
2246
+ function isNotNull(col) {
2247
+ return sql`${col} IS NOT NULL`;
2248
+ }
2249
+ function nullIf(condition, col) {
2250
+ return sql`nullIf(${col}, ${condition})`;
2251
+ }
2252
+ function nullIfEqual(col, value) {
2253
+ return sql`nullIf(${col}, ${value})`;
2254
+ }
2255
+ function not(expr) {
2256
+ return sql`NOT (${expr})`;
2257
+ }
2258
+ function and(...exprs) {
2259
+ const filtered = exprs.filter((e) => !!e);
2260
+ if (filtered.length === 0)
2261
+ return;
2262
+ if (filtered.length === 1)
2263
+ return filtered[0];
2264
+ const finalChunks = ["("];
2265
+ const finalParams = [];
2266
+ filtered.forEach((e, i) => {
2267
+ finalParams.push(e);
2268
+ if (i < filtered.length - 1) {
2269
+ finalChunks.push(") AND (");
2270
+ } else {
2271
+ finalChunks.push(")");
2272
+ }
2273
+ });
2274
+ return new SQL(finalChunks, finalParams);
2275
+ }
2276
+ function or(...exprs) {
2277
+ const filtered = exprs.filter((e) => !!e);
2278
+ if (filtered.length === 0)
2279
+ return;
2280
+ if (filtered.length === 1)
2281
+ return filtered[0];
2282
+ const finalChunks = ["("];
2283
+ const finalParams = [];
2284
+ filtered.forEach((e, i) => {
2285
+ finalParams.push(e);
2286
+ if (i < filtered.length - 1) {
2287
+ finalChunks.push(") OR (");
2288
+ } else {
2289
+ finalChunks.push(")");
2290
+ }
2291
+ });
2292
+ return new SQL(finalChunks, finalParams);
2293
+ }
2294
+ function xor(expr1, expr2) {
2295
+ return sql`xor(${expr1}, ${expr2})`;
2296
+ }
2297
+
2160
2298
  // src/utils/lru-cache.ts
2161
2299
  class LRUCache {
2162
2300
  map = new Map;
@@ -2731,6 +2869,7 @@ class QueryCompiler {
2731
2869
  class ClickHouseQueryBuilder {
2732
2870
  client;
2733
2871
  _select = null;
2872
+ _selectResolver = null;
2734
2873
  _table = null;
2735
2874
  _prewhere = null;
2736
2875
  _sample = null;
@@ -2753,7 +2892,17 @@ class ClickHouseQueryBuilder {
2753
2892
  }
2754
2893
  select(fields) {
2755
2894
  if (fields) {
2895
+ if (typeof fields === "function") {
2896
+ if (!this._table) {
2897
+ this._selectResolver = fields;
2898
+ return this;
2899
+ }
2900
+ this._select = fields(this._table.$columns);
2901
+ this._selectResolver = null;
2902
+ return this;
2903
+ }
2756
2904
  this._select = fields;
2905
+ this._selectResolver = null;
2757
2906
  return this;
2758
2907
  }
2759
2908
  return this;
@@ -2767,16 +2916,48 @@ class ClickHouseQueryBuilder {
2767
2916
  if (defaultFinal !== undefined) {
2768
2917
  this._final = Boolean(defaultFinal);
2769
2918
  }
2919
+ this.resolveSelect();
2770
2920
  return this;
2771
2921
  }
2772
2922
  fromSubquery(subquery, alias) {
2773
2923
  this._table = this.createSubqueryTable(alias, subquery);
2774
2924
  this._final = false;
2925
+ this.resolveSelect();
2775
2926
  return this;
2776
2927
  }
2928
+ resolveSelect() {
2929
+ if (!this._selectResolver)
2930
+ return;
2931
+ if (!this._table) {
2932
+ throw new Error("Call .from() before using callback select");
2933
+ }
2934
+ this._select = this._selectResolver(this._table.$columns);
2935
+ this._selectResolver = null;
2936
+ }
2777
2937
  where(expression) {
2778
- if (expression) {
2938
+ if (!expression)
2939
+ return this;
2940
+ if (typeof expression === "object" && "toSQL" in expression) {
2779
2941
  this._where = expression;
2942
+ return this;
2943
+ }
2944
+ if (typeof expression === "object") {
2945
+ const table = this._table;
2946
+ if (!table)
2947
+ return this;
2948
+ const chunks = [];
2949
+ const columns = table.$columns || table;
2950
+ for (const [key, value] of Object.entries(expression)) {
2951
+ const column = table[key] || columns?.[key];
2952
+ if (column) {
2953
+ chunks.push(eq(column, value));
2954
+ }
2955
+ }
2956
+ if (chunks.length > 0) {
2957
+ const combined = chunks.length === 1 ? chunks[0] : and(...chunks);
2958
+ if (combined)
2959
+ this._where = combined;
2960
+ }
2780
2961
  }
2781
2962
  return this;
2782
2963
  }
@@ -3012,6 +3193,7 @@ class ClickHouseQueryBuilder {
3012
3193
  return buildTable(alias);
3013
3194
  }
3014
3195
  getState() {
3196
+ this.resolveSelect();
3015
3197
  return {
3016
3198
  select: this._select,
3017
3199
  table: this._table,
@@ -3728,8 +3910,8 @@ class BinaryWriter {
3728
3910
  const ticks = typeof value === "number" ? BigInt(Math.round(value * multiplier)) : BigInt(Math.round(value.getTime() * multiplier / 1000));
3729
3911
  this.writeInt64(ticks);
3730
3912
  }
3731
- writeNullable(isNull) {
3732
- this.writeUInt8(isNull ? 1 : 0);
3913
+ writeNullable(isNull2) {
3914
+ this.writeUInt8(isNull2 ? 1 : 0);
3733
3915
  }
3734
3916
  writeArrayLength(length) {
3735
3917
  this.writeUInt64(length);
@@ -4329,7 +4511,7 @@ var globalBatcher = (client) => {
4329
4511
  };
4330
4512
 
4331
4513
  // src/builders/insert.ts
4332
- import { v4 as uuidv42, v7 as uuidv7 } from "uuid";
4514
+ import { v1 as uuidv1, v4 as uuidv42, v6 as uuidv6, v7 as uuidv7 } from "uuid";
4333
4515
 
4334
4516
  class BinaryTransform extends Transform2 {
4335
4517
  serializer;
@@ -4379,6 +4561,7 @@ class ClickHouseInsertBuilder {
4379
4561
  _batchSize = 1000;
4380
4562
  _batchConfig = null;
4381
4563
  _forceJson = false;
4564
+ _returning = false;
4382
4565
  constructor(client, table) {
4383
4566
  this.client = client;
4384
4567
  this.table = table;
@@ -4394,6 +4577,13 @@ class ClickHouseInsertBuilder {
4394
4577
  this._values = value;
4395
4578
  return this;
4396
4579
  }
4580
+ async insert(data) {
4581
+ return this.values(data);
4582
+ }
4583
+ returning() {
4584
+ this._returning = true;
4585
+ return this;
4586
+ }
4397
4587
  syncInsert() {
4398
4588
  this._async = false;
4399
4589
  return this;
@@ -4459,6 +4649,23 @@ class ClickHouseInsertBuilder {
4459
4649
  throw new Error("❌ No values to insert");
4460
4650
  }
4461
4651
  const plan = buildInsertPlan(this.table);
4652
+ if (this._returning) {
4653
+ if (this._batchConfig) {
4654
+ throw new Error("❌ returning() cannot be used with background batching");
4655
+ }
4656
+ const { processedRows, resultRows } = await this.collectReturningRows(plan);
4657
+ const stream = Readable.from(processedRows, { objectMode: true });
4658
+ await this.client.insert({
4659
+ table: this.table.$table,
4660
+ values: stream,
4661
+ format: "JSONEachRow",
4662
+ clickhouse_settings: {
4663
+ async_insert: this._async ? 1 : 0,
4664
+ wait_for_async_insert: this._waitForAsync ? 1 : 0
4665
+ }
4666
+ });
4667
+ return resultRows;
4668
+ }
4462
4669
  if (this._batchConfig && !this._forceJson) {
4463
4670
  const batcher = globalBatcher(this.client);
4464
4671
  const rowIterator = this.processRows(plan);
@@ -4474,6 +4681,7 @@ class ClickHouseInsertBuilder {
4474
4681
  } else {
4475
4682
  await this.executeJsonInsert(plan, tableName, format);
4476
4683
  }
4684
+ return;
4477
4685
  }
4478
4686
  resolveFormat(plan) {
4479
4687
  if (this._format !== "auto") {
@@ -4566,13 +4774,73 @@ class ClickHouseInsertBuilder {
4566
4774
  yield processedRow;
4567
4775
  }
4568
4776
  }
4777
+ async collectReturningRows(plan) {
4778
+ const processedRows = [];
4779
+ const resultRows = [];
4780
+ const values2 = this._values;
4781
+ const iterable = values2 instanceof Readable ? values2 : Array.isArray(values2) ? values2 : isIterable(values2) ? values2 : isAsyncIterable(values2) ? values2 : [values2];
4782
+ for await (const row of iterable) {
4783
+ const processed = processRowWithPlan(row, plan, "json");
4784
+ for (const col of plan.columns) {
4785
+ if (processed[col.columnName] !== undefined)
4786
+ continue;
4787
+ const expr = col.column.meta?.defaultExpr;
4788
+ if (!expr)
4789
+ continue;
4790
+ const resolved = this.resolveClientDefaultExpr(expr);
4791
+ if (resolved !== undefined) {
4792
+ processed[col.columnName] = col.transform(resolved);
4793
+ }
4794
+ }
4795
+ this.assertReturningRow(row, processed, plan);
4796
+ processedRows.push(processed);
4797
+ const resultRow = {};
4798
+ for (const col of plan.columns) {
4799
+ const value = processed[col.columnName];
4800
+ resultRow[col.propKey] = value;
4801
+ }
4802
+ resultRows.push(resultRow);
4803
+ }
4804
+ return { processedRows, resultRows };
4805
+ }
4806
+ assertReturningRow(rawRow, processed, plan) {
4807
+ for (const col of plan.columns) {
4808
+ const hasValue = rawRow[col.propKey] !== undefined || rawRow[col.columnName] !== undefined;
4809
+ if (hasValue)
4810
+ continue;
4811
+ if (processed[col.columnName] !== undefined) {
4812
+ continue;
4813
+ }
4814
+ if (col.defaultFn || col.autoUUIDVersion !== null && !col.useServerUUID || col.hasDefault) {
4815
+ continue;
4816
+ }
4817
+ if (col.useServerUUID || col.column.meta?.defaultExpr) {
4818
+ throw new Error(`❌ returning() cannot infer column '${col.columnName}' because it uses a server-side default. Provide a value or remove the default expression.`);
4819
+ }
4820
+ }
4821
+ }
4822
+ resolveClientDefaultExpr(expr) {
4823
+ const normalized = expr.replace(/\s+/g, "").toLowerCase();
4824
+ if (normalized === "now()" || normalized === "now64()" || normalized.startsWith("now64(")) {
4825
+ return new Date;
4826
+ }
4827
+ if (normalized === "generateuuidv4()")
4828
+ return uuidv42();
4829
+ if (normalized === "generateuuidv7()")
4830
+ return uuidv7();
4831
+ if (normalized === "generateuuidv1()")
4832
+ return uuidv1();
4833
+ if (normalized === "generateuuidv6()")
4834
+ return uuidv6();
4835
+ return;
4836
+ }
4569
4837
  async then(onfulfilled, onrejected) {
4570
4838
  try {
4571
- await this.execute();
4839
+ const result = await this.execute();
4572
4840
  if (onfulfilled) {
4573
- return Promise.resolve(onfulfilled());
4841
+ return Promise.resolve(onfulfilled(result));
4574
4842
  }
4575
- return Promise.resolve();
4843
+ return Promise.resolve(result);
4576
4844
  } catch (error) {
4577
4845
  if (onrejected) {
4578
4846
  return Promise.resolve(onrejected(error));
@@ -4833,159 +5101,21 @@ function wrapClientWithLogger(client, logger) {
4833
5101
  return wrapped;
4834
5102
  }
4835
5103
 
4836
- // src/modules/conditional.ts
4837
- function ifNull(col, alt) {
4838
- return sql`ifNull(${col}, ${alt})`;
4839
- }
4840
- function sqlIf(condition, trueVal, falseVal) {
4841
- return sql`if(${condition}, ${trueVal}, ${falseVal})`;
4842
- }
4843
- function multiIf(...args) {
4844
- if (args.length < 3) {
4845
- throw new Error("multiIf requires at least 3 arguments: condition, value, default");
4846
- }
4847
- if (args.length % 2 === 0) {
4848
- throw new Error("multiIf requires an odd number of arguments: condition-value pairs plus a default value");
4849
- }
4850
- const params = args.map((arg) => sql`${arg}`).join(", ");
4851
- return sql`multiIf(${params})`;
4852
- }
4853
- function caseWhen() {
4854
- return new CaseWhenBuilder;
5104
+ // src/relational.ts
5105
+ function buildJoinCondition(fields, references) {
5106
+ if (!fields || !references || fields.length === 0 || references.length === 0)
5107
+ return null;
5108
+ const pairs = fields.map((f, i) => sql`${f} = ${references[i]}`);
5109
+ const filtered = pairs.filter((p) => Boolean(p));
5110
+ if (filtered.length === 0)
5111
+ return null;
5112
+ if (filtered.length === 1)
5113
+ return filtered[0];
5114
+ return and(...filtered) || null;
4855
5115
  }
4856
-
4857
- class CaseWhenBuilder {
4858
- conditions = [];
4859
- values = [];
4860
- defaultValue;
4861
- when(condition, value) {
4862
- this.conditions.push(condition);
4863
- this.values.push(value);
4864
- return this;
4865
- }
4866
- otherwise(value) {
4867
- this.defaultValue = value;
4868
- return this.build();
4869
- }
4870
- build() {
4871
- if (!this.defaultValue) {
4872
- throw new Error("CaseWhenBuilder requires a default value via .otherwise()");
4873
- }
4874
- const args = [];
4875
- for (let i = 0;i < this.conditions.length; i++) {
4876
- args.push(this.conditions[i]);
4877
- args.push(this.values[i]);
4878
- }
4879
- args.push(this.defaultValue);
4880
- return multiIf(...args);
4881
- }
4882
- }
4883
- function coalesce(...args) {
4884
- const chunks = ["coalesce("];
4885
- const params = [];
4886
- args.forEach((arg, i) => {
4887
- params.push(arg);
4888
- if (i < args.length - 1) {
4889
- chunks.push(", ");
4890
- }
4891
- });
4892
- chunks.push(")");
4893
- return new SQL(chunks, params);
4894
- }
4895
- function greatest(...args) {
4896
- const chunks = ["greatest("];
4897
- const params = [];
4898
- args.forEach((arg, i) => {
4899
- params.push(arg);
4900
- if (i < args.length - 1) {
4901
- chunks.push(", ");
4902
- }
4903
- });
4904
- chunks.push(")");
4905
- return new SQL(chunks, params);
4906
- }
4907
- function least(...args) {
4908
- const chunks = ["least("];
4909
- const params = [];
4910
- args.forEach((arg, i) => {
4911
- params.push(arg);
4912
- if (i < args.length - 1) {
4913
- chunks.push(", ");
4914
- }
4915
- });
4916
- chunks.push(")");
4917
- return new SQL(chunks, params);
4918
- }
4919
- function isNull(col) {
4920
- return sql`${col} IS NULL`;
4921
- }
4922
- function isNotNull(col) {
4923
- return sql`${col} IS NOT NULL`;
4924
- }
4925
- function nullIf(condition, col) {
4926
- return sql`nullIf(${col}, ${condition})`;
4927
- }
4928
- function nullIfEqual(col, value) {
4929
- return sql`nullIf(${col}, ${value})`;
4930
- }
4931
- function not(expr) {
4932
- return sql`NOT (${expr})`;
4933
- }
4934
- function and(...exprs) {
4935
- const filtered = exprs.filter((e) => !!e);
4936
- if (filtered.length === 0)
4937
- return;
4938
- if (filtered.length === 1)
4939
- return filtered[0];
4940
- const finalChunks = ["("];
4941
- const finalParams = [];
4942
- filtered.forEach((e, i) => {
4943
- finalParams.push(e);
4944
- if (i < filtered.length - 1) {
4945
- finalChunks.push(") AND (");
4946
- } else {
4947
- finalChunks.push(")");
4948
- }
4949
- });
4950
- return new SQL(finalChunks, finalParams);
4951
- }
4952
- function or(...exprs) {
4953
- const filtered = exprs.filter((e) => !!e);
4954
- if (filtered.length === 0)
4955
- return;
4956
- if (filtered.length === 1)
4957
- return filtered[0];
4958
- const finalChunks = ["("];
4959
- const finalParams = [];
4960
- filtered.forEach((e, i) => {
4961
- finalParams.push(e);
4962
- if (i < filtered.length - 1) {
4963
- finalChunks.push(") OR (");
4964
- } else {
4965
- finalChunks.push(")");
4966
- }
4967
- });
4968
- return new SQL(finalChunks, finalParams);
4969
- }
4970
- function xor(expr1, expr2) {
4971
- return sql`xor(${expr1}, ${expr2})`;
4972
- }
4973
-
4974
- // src/relational.ts
4975
- function buildJoinCondition(fields, references) {
4976
- if (!fields || !references || fields.length === 0 || references.length === 0)
4977
- return null;
4978
- const pairs = fields.map((f, i) => sql`${f} = ${references[i]}`);
4979
- const filtered = pairs.filter((p) => Boolean(p));
4980
- if (filtered.length === 0)
4981
- return null;
4982
- if (filtered.length === 1)
4983
- return filtered[0];
4984
- return and(...filtered) || null;
4985
- }
4986
- function isDistributedTable(tableDef) {
4987
- const options = tableDef.$options;
4988
- return !!(options?.onCluster || options?.shardKey);
5116
+ function isDistributedTable(tableDef) {
5117
+ const options = tableDef.$options;
5118
+ return !!(options?.onCluster || options?.shardKey);
4989
5119
  }
4990
5120
  function buildRelationalAPI(client, schema) {
4991
5121
  if (!schema)
@@ -5207,7 +5337,7 @@ function createHousekitClient(config) {
5207
5337
  const builder = new ClickHouseQueryBuilder(client);
5208
5338
  if (!fieldsOrTable)
5209
5339
  return builder.select();
5210
- if (typeof fieldsOrTable === "object" && fieldsOrTable !== null && "$table" in fieldsOrTable && "$columns" in fieldsOrTable) {
5340
+ if (typeof fieldsOrTable === "object" && fieldsOrTable !== null && "$table" in fieldsOrTable) {
5211
5341
  return builder.select().from(fieldsOrTable);
5212
5342
  }
5213
5343
  return builder.select(fieldsOrTable);
@@ -5260,6 +5390,105 @@ function createHousekitClient(config) {
5260
5390
  return baseClient;
5261
5391
  }
5262
5392
  var createClientFromConfigObject = createHousekitClient;
5393
+
5394
+ // src/codegen/zod.ts
5395
+ import { z } from "zod";
5396
+ function mapClickHouseTypeToZod(column) {
5397
+ const type = column.type.toLowerCase();
5398
+ let zodType;
5399
+ if (type.startsWith("nullable(")) {
5400
+ const innerType = column.type.slice("nullable(".length, -1);
5401
+ const innerColumn = new ClickHouseColumn(column.name, innerType);
5402
+ zodType = mapClickHouseTypeToZod(innerColumn).nullable();
5403
+ } else if (type.startsWith("array(")) {
5404
+ const innerType = column.type.slice("array(".length, -1);
5405
+ const innerColumn = new ClickHouseColumn(column.name, innerType);
5406
+ zodType = z.array(mapClickHouseTypeToZod(innerColumn));
5407
+ } else if (type.startsWith("fixedstring")) {
5408
+ zodType = z.string();
5409
+ } else if (type.startsWith("enum")) {
5410
+ if (column.meta?.enumValues) {
5411
+ zodType = z.enum(column.meta.enumValues);
5412
+ } else {
5413
+ zodType = z.string();
5414
+ }
5415
+ } else if (type.startsWith("datetime64")) {
5416
+ zodType = z.date();
5417
+ } else if (type.startsWith("decimal")) {
5418
+ zodType = z.string().refine((val) => !isNaN(parseFloat(val)), {
5419
+ message: "Must be a valid decimal number string"
5420
+ });
5421
+ } else {
5422
+ switch (type) {
5423
+ case "uuid":
5424
+ case "string":
5425
+ case "json":
5426
+ case "ipv4":
5427
+ case "ipv6":
5428
+ zodType = z.string();
5429
+ break;
5430
+ case "int8":
5431
+ case "uint8":
5432
+ case "int16":
5433
+ case "uint16":
5434
+ case "int32":
5435
+ case "uint32":
5436
+ case "float32":
5437
+ case "float64":
5438
+ zodType = z.number();
5439
+ break;
5440
+ case "int64":
5441
+ case "uint64":
5442
+ case "int128":
5443
+ case "uint128":
5444
+ case "int256":
5445
+ case "uint256":
5446
+ zodType = z.bigint();
5447
+ break;
5448
+ case "boolean":
5449
+ case "bool":
5450
+ zodType = z.boolean();
5451
+ break;
5452
+ case "date":
5453
+ case "datetime":
5454
+ zodType = z.date();
5455
+ break;
5456
+ default:
5457
+ zodType = z.string();
5458
+ break;
5459
+ }
5460
+ }
5461
+ if (column.isNull && !type.startsWith("nullable(")) {
5462
+ zodType = zodType.nullable();
5463
+ }
5464
+ return zodType;
5465
+ }
5466
+ function generateSelectSchema(table) {
5467
+ const shape = {};
5468
+ for (const key in table.$columns) {
5469
+ if (Object.prototype.hasOwnProperty.call(table.$columns, key)) {
5470
+ const column = table.$columns[key];
5471
+ shape[key] = mapClickHouseTypeToZod(column);
5472
+ }
5473
+ }
5474
+ return z.object(shape);
5475
+ }
5476
+ function generateInsertSchema(table) {
5477
+ const shape = {};
5478
+ for (const key in table.$columns) {
5479
+ if (Object.prototype.hasOwnProperty.call(table.$columns, key)) {
5480
+ const column = table.$columns[key];
5481
+ let zodType = mapClickHouseTypeToZod(column);
5482
+ const isOptionalBySchema = !column.isNull && (column.meta?.default !== undefined || column.meta?.defaultFn !== undefined || column.meta?.defaultExpr !== undefined || column.meta?.autoGenerate !== undefined);
5483
+ const isOptionalByNullable = column.isNull;
5484
+ if (isOptionalBySchema || isOptionalByNullable) {
5485
+ zodType = zodType.optional();
5486
+ } else {}
5487
+ shape[key] = zodType;
5488
+ }
5489
+ }
5490
+ return z.object(shape);
5491
+ }
5263
5492
  // src/modules/array.ts
5264
5493
  function arrayJoin(separator, col) {
5265
5494
  if (col) {
@@ -6266,7 +6495,21 @@ var t = {
6266
6495
  ring: (name) => new ClickHouseColumn(name, "Ring"),
6267
6496
  polygon: (name) => new ClickHouseColumn(name, "Polygon"),
6268
6497
  multiPolygon: (name) => new ClickHouseColumn(name, "MultiPolygon"),
6269
- enum: (name, values2) => new ClickHouseColumn(name, "String", true, { enumValues: values2 })
6498
+ enum: (name, values2) => new ClickHouseColumn(name, "String", true, { enumValues: values2 }),
6499
+ timestamps: () => ({
6500
+ created_at: new ClickHouseColumn("created_at", "DateTime").default("now()"),
6501
+ updated_at: new ClickHouseColumn("updated_at", "DateTime").default("now()")
6502
+ }),
6503
+ primaryUuid: (name) => {
6504
+ const colName = name ?? "id";
6505
+ return {
6506
+ [colName]: new ClickHouseColumn(colName, "UUID").autoGenerate().primaryKey().default("generateUUIDv4()")
6507
+ };
6508
+ },
6509
+ softDeletes: () => ({
6510
+ is_deleted: new ClickHouseColumn("is_deleted", "Bool").default(false),
6511
+ deleted_at: new ClickHouseColumn("deleted_at", "DateTime").nullable()
6512
+ })
6270
6513
  };
6271
6514
  function defineTable(tableName, columnsOrCallback, options) {
6272
6515
  const columns = typeof columnsOrCallback === "function" ? columnsOrCallback(t) : columnsOrCallback;
@@ -6303,104 +6546,6 @@ function relations(table2, relationsBuilder) {
6303
6546
  table2.$relations = rels;
6304
6547
  return rels;
6305
6548
  }
6306
- // src/codegen/zod.ts
6307
- import { z } from "zod";
6308
- function mapClickHouseTypeToZod(column) {
6309
- const type = column.type.toLowerCase();
6310
- let zodType;
6311
- if (type.startsWith("nullable(")) {
6312
- const innerType = column.type.slice("nullable(".length, -1);
6313
- const innerColumn = new ClickHouseColumn(column.name, innerType);
6314
- zodType = mapClickHouseTypeToZod(innerColumn).nullable();
6315
- } else if (type.startsWith("array(")) {
6316
- const innerType = column.type.slice("array(".length, -1);
6317
- const innerColumn = new ClickHouseColumn(column.name, innerType);
6318
- zodType = z.array(mapClickHouseTypeToZod(innerColumn));
6319
- } else if (type.startsWith("fixedstring")) {
6320
- zodType = z.string();
6321
- } else if (type.startsWith("enum")) {
6322
- if (column.meta?.enumValues) {
6323
- zodType = z.enum(column.meta.enumValues);
6324
- } else {
6325
- zodType = z.string();
6326
- }
6327
- } else if (type.startsWith("datetime64")) {
6328
- zodType = z.date();
6329
- } else if (type.startsWith("decimal")) {
6330
- zodType = z.string().refine((val) => !isNaN(parseFloat(val)), {
6331
- message: "Must be a valid decimal number string"
6332
- });
6333
- } else {
6334
- switch (type) {
6335
- case "uuid":
6336
- case "string":
6337
- case "json":
6338
- case "ipv4":
6339
- case "ipv6":
6340
- zodType = z.string();
6341
- break;
6342
- case "int8":
6343
- case "uint8":
6344
- case "int16":
6345
- case "uint16":
6346
- case "int32":
6347
- case "uint32":
6348
- case "float32":
6349
- case "float64":
6350
- zodType = z.number();
6351
- break;
6352
- case "int64":
6353
- case "uint64":
6354
- case "int128":
6355
- case "uint128":
6356
- case "int256":
6357
- case "uint256":
6358
- zodType = z.bigint();
6359
- break;
6360
- case "boolean":
6361
- case "bool":
6362
- zodType = z.boolean();
6363
- break;
6364
- case "date":
6365
- case "datetime":
6366
- zodType = z.date();
6367
- break;
6368
- default:
6369
- zodType = z.string();
6370
- break;
6371
- }
6372
- }
6373
- if (column.isNull && !type.startsWith("nullable(")) {
6374
- zodType = zodType.nullable();
6375
- }
6376
- return zodType;
6377
- }
6378
- function generateSelectSchema(table2) {
6379
- const shape = {};
6380
- for (const key in table2.$columns) {
6381
- if (Object.prototype.hasOwnProperty.call(table2.$columns, key)) {
6382
- const column = table2.$columns[key];
6383
- shape[key] = mapClickHouseTypeToZod(column);
6384
- }
6385
- }
6386
- return z.object(shape);
6387
- }
6388
- function generateInsertSchema(table2) {
6389
- const shape = {};
6390
- for (const key in table2.$columns) {
6391
- if (Object.prototype.hasOwnProperty.call(table2.$columns, key)) {
6392
- const column = table2.$columns[key];
6393
- let zodType = mapClickHouseTypeToZod(column);
6394
- const isOptionalBySchema = !column.isNull && (column.meta?.default !== undefined || column.meta?.defaultFn !== undefined || column.meta?.defaultExpr !== undefined || column.meta?.autoGenerate !== undefined);
6395
- const isOptionalByNullable = column.isNull;
6396
- if (isOptionalBySchema || isOptionalByNullable) {
6397
- zodType = zodType.optional();
6398
- } else {}
6399
- shape[key] = zodType;
6400
- }
6401
- }
6402
- return z.object(shape);
6403
- }
6404
6549
  // src/index.ts
6405
6550
  async function createClientFromConfig(databaseName = "default") {
6406
6551
  const config = await loadConfig();
@@ -6416,6 +6561,18 @@ async function createClientFromConfig(databaseName = "default") {
6416
6561
  };
6417
6562
  return createClientFromConfigObject(clientConfig);
6418
6563
  }
6564
+ function housekit(config, options) {
6565
+ return createHousekitClient({
6566
+ ...config,
6567
+ schema: options?.schema
6568
+ });
6569
+ }
6570
+ function createSchema(table2) {
6571
+ return {
6572
+ select: generateSelectSchema(table2),
6573
+ insert: generateInsertSchema(table2)
6574
+ };
6575
+ }
6419
6576
  async function loadConfig() {
6420
6577
  const root = process.cwd();
6421
6578
  const extensions = ["ts", "js", "mjs", "cjs"];
@@ -6725,6 +6882,7 @@ export {
6725
6882
  htmlEscape,
6726
6883
  housekitMetadataSchemas,
6727
6884
  housekitMetadataDefaults,
6885
+ housekit,
6728
6886
  hdfs,
6729
6887
  hasAny,
6730
6888
  hasAll,
@@ -6794,6 +6952,7 @@ export {
6794
6952
  dateDiff,
6795
6953
  dateAdd,
6796
6954
  createdAt,
6955
+ createSchema,
6797
6956
  createMigrationBridge,
6798
6957
  createHousekitClient,
6799
6958
  createClients,