kysely-gen 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +487 -117
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -9984,6 +9984,153 @@ var source_default = chalk;
9984
9984
  // node_modules/ora/index.js
9985
9985
  import process8 from "node:process";
9986
9986
 
9987
+ // node_modules/chalk/source/index.js
9988
+ var { stdout: stdoutColor2, stderr: stderrColor2 } = supports_color_default;
9989
+ var GENERATOR2 = Symbol("GENERATOR");
9990
+ var STYLER2 = Symbol("STYLER");
9991
+ var IS_EMPTY2 = Symbol("IS_EMPTY");
9992
+ var levelMapping2 = [
9993
+ "ansi",
9994
+ "ansi",
9995
+ "ansi256",
9996
+ "ansi16m"
9997
+ ];
9998
+ var styles3 = Object.create(null);
9999
+ var applyOptions2 = (object, options = {}) => {
10000
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
10001
+ throw new Error("The `level` option should be an integer from 0 to 3");
10002
+ }
10003
+ const colorLevel = stdoutColor2 ? stdoutColor2.level : 0;
10004
+ object.level = options.level === undefined ? colorLevel : options.level;
10005
+ };
10006
+ var chalkFactory2 = (options) => {
10007
+ const chalk2 = (...strings) => strings.join(" ");
10008
+ applyOptions2(chalk2, options);
10009
+ Object.setPrototypeOf(chalk2, createChalk2.prototype);
10010
+ return chalk2;
10011
+ };
10012
+ function createChalk2(options) {
10013
+ return chalkFactory2(options);
10014
+ }
10015
+ Object.setPrototypeOf(createChalk2.prototype, Function.prototype);
10016
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
10017
+ styles3[styleName] = {
10018
+ get() {
10019
+ const builder = createBuilder2(this, createStyler2(style.open, style.close, this[STYLER2]), this[IS_EMPTY2]);
10020
+ Object.defineProperty(this, styleName, { value: builder });
10021
+ return builder;
10022
+ }
10023
+ };
10024
+ }
10025
+ styles3.visible = {
10026
+ get() {
10027
+ const builder = createBuilder2(this, this[STYLER2], true);
10028
+ Object.defineProperty(this, "visible", { value: builder });
10029
+ return builder;
10030
+ }
10031
+ };
10032
+ var getModelAnsi2 = (model, level, type, ...arguments_) => {
10033
+ if (model === "rgb") {
10034
+ if (level === "ansi16m") {
10035
+ return ansi_styles_default[type].ansi16m(...arguments_);
10036
+ }
10037
+ if (level === "ansi256") {
10038
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
10039
+ }
10040
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
10041
+ }
10042
+ if (model === "hex") {
10043
+ return getModelAnsi2("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
10044
+ }
10045
+ return ansi_styles_default[type][model](...arguments_);
10046
+ };
10047
+ var usedModels2 = ["rgb", "hex", "ansi256"];
10048
+ for (const model of usedModels2) {
10049
+ styles3[model] = {
10050
+ get() {
10051
+ const { level } = this;
10052
+ return function(...arguments_) {
10053
+ const styler = createStyler2(getModelAnsi2(model, levelMapping2[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER2]);
10054
+ return createBuilder2(this, styler, this[IS_EMPTY2]);
10055
+ };
10056
+ }
10057
+ };
10058
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
10059
+ styles3[bgModel] = {
10060
+ get() {
10061
+ const { level } = this;
10062
+ return function(...arguments_) {
10063
+ const styler = createStyler2(getModelAnsi2(model, levelMapping2[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER2]);
10064
+ return createBuilder2(this, styler, this[IS_EMPTY2]);
10065
+ };
10066
+ }
10067
+ };
10068
+ }
10069
+ var proto2 = Object.defineProperties(() => {}, {
10070
+ ...styles3,
10071
+ level: {
10072
+ enumerable: true,
10073
+ get() {
10074
+ return this[GENERATOR2].level;
10075
+ },
10076
+ set(level) {
10077
+ this[GENERATOR2].level = level;
10078
+ }
10079
+ }
10080
+ });
10081
+ var createStyler2 = (open, close, parent) => {
10082
+ let openAll;
10083
+ let closeAll;
10084
+ if (parent === undefined) {
10085
+ openAll = open;
10086
+ closeAll = close;
10087
+ } else {
10088
+ openAll = parent.openAll + open;
10089
+ closeAll = close + parent.closeAll;
10090
+ }
10091
+ return {
10092
+ open,
10093
+ close,
10094
+ openAll,
10095
+ closeAll,
10096
+ parent
10097
+ };
10098
+ };
10099
+ var createBuilder2 = (self, _styler, _isEmpty) => {
10100
+ const builder = (...arguments_) => applyStyle2(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
10101
+ Object.setPrototypeOf(builder, proto2);
10102
+ builder[GENERATOR2] = self;
10103
+ builder[STYLER2] = _styler;
10104
+ builder[IS_EMPTY2] = _isEmpty;
10105
+ return builder;
10106
+ };
10107
+ var applyStyle2 = (self, string) => {
10108
+ if (self.level <= 0 || !string) {
10109
+ return self[IS_EMPTY2] ? "" : string;
10110
+ }
10111
+ let styler = self[STYLER2];
10112
+ if (styler === undefined) {
10113
+ return string;
10114
+ }
10115
+ const { openAll, closeAll } = styler;
10116
+ if (string.includes("\x1B")) {
10117
+ while (styler !== undefined) {
10118
+ string = stringReplaceAll(string, styler.close, styler.open);
10119
+ styler = styler.parent;
10120
+ }
10121
+ }
10122
+ const lfIndex = string.indexOf(`
10123
+ `);
10124
+ if (lfIndex !== -1) {
10125
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
10126
+ }
10127
+ return openAll + string + closeAll;
10128
+ };
10129
+ Object.defineProperties(createChalk2.prototype, styles3);
10130
+ var chalk2 = createChalk2();
10131
+ var chalkStderr2 = createChalk2({ level: stderrColor2 ? stderrColor2.level : 0 });
10132
+ var source_default2 = chalk2;
10133
+
9987
10134
  // node_modules/cli-cursor/index.js
9988
10135
  import process5 from "node:process";
9989
10136
 
@@ -12413,7 +12560,7 @@ class Ora {
12413
12560
  const { frames } = this.#spinner;
12414
12561
  let frame = frames[this.#frameIndex];
12415
12562
  if (this.color) {
12416
- frame = source_default[this.color](frame);
12563
+ frame = source_default2[this.color](frame);
12417
12564
  }
12418
12565
  const fullPrefixText = this.#getFullPrefixText(this.#prefixText, " ");
12419
12566
  const fullText = typeof this.text === "string" ? " " + this.text : "";
@@ -12573,11 +12720,11 @@ function isPlainObject(obj) {
12573
12720
  if (Object.getPrototypeOf(obj) === null) {
12574
12721
  return true;
12575
12722
  }
12576
- let proto2 = obj;
12577
- while (Object.getPrototypeOf(proto2) !== null) {
12578
- proto2 = Object.getPrototypeOf(proto2);
12723
+ let proto3 = obj;
12724
+ while (Object.getPrototypeOf(proto3) !== null) {
12725
+ proto3 = Object.getPrototypeOf(proto3);
12579
12726
  }
12580
- return Object.getPrototypeOf(obj) === proto2;
12727
+ return Object.getPrototypeOf(obj) === proto3;
12581
12728
  }
12582
12729
  function getLast(arr) {
12583
12730
  return arr[arr.length - 1];
@@ -22330,25 +22477,51 @@ function serializeType(node) {
22330
22477
  return serializeReference(node);
22331
22478
  case "raw":
22332
22479
  return serializeRaw(node);
22480
+ case "tuple":
22481
+ return serializeTuple(node);
22482
+ case "conditional":
22483
+ return serializeConditional(node);
22484
+ case "keyof":
22485
+ return serializeKeyof(node);
22486
+ case "indexAccess":
22487
+ return serializeIndexAccess(node);
22488
+ case "infer":
22489
+ return serializeInfer(node);
22333
22490
  }
22334
22491
  }
22335
22492
  function serializePrimitive(node) {
22336
22493
  return node.value;
22337
22494
  }
22495
+ function escapeString(value) {
22496
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
22497
+ }
22338
22498
  function serializeLiteral(node) {
22339
22499
  if (typeof node.value === "string") {
22340
- return `'${node.value}'`;
22500
+ return `'${escapeString(node.value)}'`;
22341
22501
  }
22342
22502
  return String(node.value);
22343
22503
  }
22504
+ function needsParens(node, context) {
22505
+ if (context === "union" && node.kind === "intersection")
22506
+ return true;
22507
+ if (context === "intersection" && node.kind === "union")
22508
+ return true;
22509
+ if (context === "array" && (node.kind === "union" || node.kind === "intersection"))
22510
+ return true;
22511
+ return false;
22512
+ }
22513
+ function serializeWithParens(node, context) {
22514
+ const serialized = serializeType(node);
22515
+ return needsParens(node, context) ? `(${serialized})` : serialized;
22516
+ }
22344
22517
  function serializeUnion(node) {
22345
- return node.types.map(serializeType).join(" | ");
22518
+ return node.types.map((t) => serializeWithParens(t, "union")).join(" | ");
22346
22519
  }
22347
22520
  function serializeIntersection(node) {
22348
- return node.types.map(serializeType).join(" & ");
22521
+ return node.types.map((t) => serializeWithParens(t, "intersection")).join(" & ");
22349
22522
  }
22350
22523
  function serializeArray(node) {
22351
- return `${serializeType(node.elementType)}[]`;
22524
+ return `${serializeWithParens(node.elementType, "array")}[]`;
22352
22525
  }
22353
22526
  function serializeGeneric(node) {
22354
22527
  const typeArgs = node.typeArguments.map(serializeType).join(", ");
@@ -22360,10 +22533,103 @@ function serializeReference(node) {
22360
22533
  function serializeRaw(node) {
22361
22534
  return node.value;
22362
22535
  }
22536
+ function serializeTuple(node) {
22537
+ return `[${node.elements.map(serializeType).join(", ")}]`;
22538
+ }
22539
+ function serializeConditional(node) {
22540
+ const check = serializeType(node.checkType);
22541
+ const ext = serializeType(node.extendsType);
22542
+ const trueType = serializeType(node.trueType);
22543
+ const falseType = serializeType(node.falseType);
22544
+ return `${check} extends ${ext} ? ${trueType} : ${falseType}`;
22545
+ }
22546
+ function serializeKeyof(node) {
22547
+ return `keyof ${serializeType(node.type)}`;
22548
+ }
22549
+ function serializeIndexAccess(node) {
22550
+ return `${serializeType(node.objectType)}[${serializeType(node.indexType)}]`;
22551
+ }
22552
+ function serializeInfer(node) {
22553
+ return `infer ${node.name}`;
22554
+ }
22555
+ var RESERVED_WORDS = new Set([
22556
+ "break",
22557
+ "case",
22558
+ "catch",
22559
+ "class",
22560
+ "const",
22561
+ "continue",
22562
+ "debugger",
22563
+ "default",
22564
+ "delete",
22565
+ "do",
22566
+ "else",
22567
+ "enum",
22568
+ "export",
22569
+ "extends",
22570
+ "false",
22571
+ "finally",
22572
+ "for",
22573
+ "function",
22574
+ "if",
22575
+ "import",
22576
+ "in",
22577
+ "instanceof",
22578
+ "new",
22579
+ "null",
22580
+ "return",
22581
+ "super",
22582
+ "switch",
22583
+ "this",
22584
+ "throw",
22585
+ "true",
22586
+ "try",
22587
+ "typeof",
22588
+ "var",
22589
+ "void",
22590
+ "while",
22591
+ "with",
22592
+ "yield",
22593
+ "let",
22594
+ "static",
22595
+ "implements",
22596
+ "interface",
22597
+ "package",
22598
+ "private",
22599
+ "protected",
22600
+ "public",
22601
+ "await",
22602
+ "abstract",
22603
+ "as",
22604
+ "async",
22605
+ "declare",
22606
+ "from",
22607
+ "get",
22608
+ "is",
22609
+ "module",
22610
+ "namespace",
22611
+ "of",
22612
+ "require",
22613
+ "set",
22614
+ "type"
22615
+ ]);
22616
+ function needsQuotes(name) {
22617
+ if (RESERVED_WORDS.has(name))
22618
+ return true;
22619
+ if (/^\d/.test(name))
22620
+ return true;
22621
+ if (!/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name))
22622
+ return true;
22623
+ return false;
22624
+ }
22625
+ function serializePropertyName(name) {
22626
+ return needsQuotes(name) ? `'${escapeString(name)}'` : name;
22627
+ }
22363
22628
  function serializeProperty(node, indent = " ") {
22364
22629
  const optional = node.optional ? "?" : "";
22365
22630
  const readonly = node.readonly ? "readonly " : "";
22366
- return `${indent}${readonly}${node.name}${optional}: ${serializeType(node.type)};`;
22631
+ const propName = serializePropertyName(node.name);
22632
+ return `${indent}${readonly}${propName}${optional}: ${serializeType(node.type)};`;
22367
22633
  }
22368
22634
  function serializeInterface(node) {
22369
22635
  const exported = node.exported ? "export " : "";
@@ -22401,14 +22667,15 @@ function serialize(program2) {
22401
22667
 
22402
22668
  // src/introspect/postgres.ts
22403
22669
  async function introspectDatabase(db, options) {
22404
- const [domains, partitions, baseTables, materializedViews, enums] = await Promise.all([
22670
+ const [domains, partitions, baseTables, regularViews, materializedViews, enums] = await Promise.all([
22405
22671
  introspectDomains(db),
22406
22672
  introspectPartitions(db),
22407
22673
  introspectTables(db, options.schemas),
22674
+ introspectViews(db, options.schemas),
22408
22675
  introspectMaterializedViews(db, options.schemas),
22409
22676
  introspectEnums(db, options.schemas)
22410
22677
  ]);
22411
- const tables = [...baseTables, ...materializedViews].map((table) => {
22678
+ const tables = [...baseTables, ...regularViews, ...materializedViews].map((table) => {
22412
22679
  const isPartition = partitions.some((partition) => partition.schema === table.schema && partition.name === table.name);
22413
22680
  return {
22414
22681
  ...table,
@@ -22434,6 +22701,7 @@ async function introspectTables(db, schemas) {
22434
22701
  c.udt_name,
22435
22702
  c.udt_schema,
22436
22703
  c.is_nullable,
22704
+ c.is_identity,
22437
22705
  c.column_default,
22438
22706
  pg_catalog.col_description(
22439
22707
  (c.table_schema||'.'||c.table_name)::regclass::oid,
@@ -22483,6 +22751,67 @@ async function introspectTables(db, schemas) {
22483
22751
  }
22484
22752
  return Array.from(tableMap.values());
22485
22753
  }
22754
+ async function introspectViews(db, schemas) {
22755
+ const rawColumns = await sql`
22756
+ SELECT
22757
+ c.table_schema,
22758
+ c.table_name,
22759
+ c.column_name,
22760
+ c.data_type,
22761
+ c.udt_name,
22762
+ c.udt_schema,
22763
+ c.is_nullable,
22764
+ c.is_identity,
22765
+ c.column_default,
22766
+ pg_catalog.col_description(
22767
+ (c.table_schema||'.'||c.table_name)::regclass::oid,
22768
+ c.ordinal_position
22769
+ ) as column_comment
22770
+ FROM information_schema.columns c
22771
+ INNER JOIN information_schema.tables t
22772
+ ON c.table_schema = t.table_schema
22773
+ AND c.table_name = t.table_name
22774
+ WHERE t.table_type = 'VIEW'
22775
+ AND c.table_schema = ANY(${schemas})
22776
+ ORDER BY c.table_schema, c.table_name, c.ordinal_position
22777
+ `.execute(db);
22778
+ const tableMap = new Map;
22779
+ for (const row of rawColumns.rows) {
22780
+ const tableKey = `${row.table_schema}.${row.table_name}`;
22781
+ if (!tableMap.has(tableKey)) {
22782
+ tableMap.set(tableKey, {
22783
+ schema: row.table_schema,
22784
+ name: row.table_name,
22785
+ columns: [],
22786
+ isView: true
22787
+ });
22788
+ }
22789
+ const table = tableMap.get(tableKey);
22790
+ if (table) {
22791
+ const isArray = row.data_type === "ARRAY";
22792
+ let dataType = row.udt_name;
22793
+ if (isArray && dataType.startsWith("_")) {
22794
+ dataType = dataType.slice(1);
22795
+ }
22796
+ const columnMetadata = {
22797
+ name: row.column_name,
22798
+ dataType,
22799
+ dataTypeSchema: row.udt_schema,
22800
+ isNullable: row.is_nullable === "YES",
22801
+ isAutoIncrement: false,
22802
+ hasDefaultValue: row.column_default !== null
22803
+ };
22804
+ if (isArray) {
22805
+ columnMetadata.isArray = true;
22806
+ }
22807
+ if (row.column_comment) {
22808
+ columnMetadata.comment = row.column_comment;
22809
+ }
22810
+ table.columns.push(columnMetadata);
22811
+ }
22812
+ }
22813
+ return Array.from(tableMap.values());
22814
+ }
22486
22815
  async function introspectMaterializedViews(db, schemas) {
22487
22816
  const rawColumns = await sql`
22488
22817
  SELECT
@@ -22495,12 +22824,15 @@ async function introspectMaterializedViews(db, schemas) {
22495
22824
  t.typname AS data_type,
22496
22825
  t.typname AS udt_name,
22497
22826
  tn.nspname AS udt_schema,
22827
+ t.typcategory,
22828
+ et.typname AS element_type,
22498
22829
  col_description(c.oid, a.attnum) AS column_comment
22499
22830
  FROM pg_class c
22500
22831
  JOIN pg_namespace n ON n.oid = c.relnamespace
22501
22832
  JOIN pg_attribute a ON a.attrelid = c.oid
22502
22833
  JOIN pg_type t ON t.oid = a.atttypid
22503
22834
  JOIN pg_namespace tn ON tn.oid = t.typnamespace
22835
+ LEFT JOIN pg_type et ON t.typelem = et.oid AND t.typcategory = 'A'
22504
22836
  LEFT JOIN pg_attrdef ad ON ad.adrelid = c.oid AND ad.adnum = a.attnum
22505
22837
  WHERE c.relkind = 'm'
22506
22838
  AND a.attnum > 0
@@ -22521,25 +22853,18 @@ async function introspectMaterializedViews(db, schemas) {
22521
22853
  }
22522
22854
  const table = tableMap.get(tableKey);
22523
22855
  if (table) {
22524
- const isArray = row.data_type.startsWith("_");
22525
- let dataType = row.udt_name;
22526
- if (isArray) {
22527
- dataType = dataType.slice(1);
22528
- }
22856
+ const isArray = row.typcategory === "A";
22857
+ const dataType = isArray && row.element_type ? row.element_type : row.udt_name;
22529
22858
  const columnMetadata = {
22530
22859
  name: row.column_name,
22531
22860
  dataType,
22532
22861
  dataTypeSchema: row.udt_schema,
22533
22862
  isNullable: row.is_nullable === "YES",
22534
22863
  isAutoIncrement: row.column_default?.includes("nextval") ?? false,
22535
- hasDefaultValue: row.column_default !== null
22864
+ hasDefaultValue: row.column_default !== null,
22865
+ ...isArray && { isArray: true },
22866
+ ...row.column_comment && { comment: row.column_comment }
22536
22867
  };
22537
- if (isArray) {
22538
- columnMetadata.isArray = true;
22539
- }
22540
- if (row.column_comment) {
22541
- columnMetadata.comment = row.column_comment;
22542
- }
22543
22868
  table.columns.push(columnMetadata);
22544
22869
  }
22545
22870
  }
@@ -22607,6 +22932,9 @@ async function introspectEnums(db, schemas) {
22607
22932
  }));
22608
22933
  }
22609
22934
  function isAutoIncrementColumn(column) {
22935
+ if (column.is_identity === "YES") {
22936
+ return true;
22937
+ }
22610
22938
  if (!column.column_default) {
22611
22939
  return false;
22612
22940
  }
@@ -22622,51 +22950,8 @@ function parsePostgresArray(value) {
22622
22950
  return [value];
22623
22951
  }
22624
22952
 
22625
- // src/transform.ts
22953
+ // src/transform/filter.ts
22626
22954
  var import_micromatch = __toESM(require_micromatch(), 1);
22627
-
22628
- // src/utils/case-converter.ts
22629
- class CaseConverter extends CamelCasePlugin {
22630
- toCamelCase(str) {
22631
- return this.camelCase(str);
22632
- }
22633
- }
22634
- function toCamelCase(str) {
22635
- return new CaseConverter().toCamelCase(str);
22636
- }
22637
-
22638
- // src/transform.ts
22639
- function transformDatabase(metadata, options) {
22640
- const declarations = [];
22641
- declarations.push({
22642
- kind: "import",
22643
- imports: ["ColumnType"],
22644
- from: "kysely",
22645
- typeOnly: true
22646
- });
22647
- declarations.push({
22648
- kind: "typeAlias",
22649
- name: "Generated<T>",
22650
- type: {
22651
- kind: "raw",
22652
- value: `T extends ColumnType<infer S, infer I, infer U>
22653
- ? ColumnType<S, I | undefined, U>
22654
- : ColumnType<T, T | undefined, T>`
22655
- },
22656
- exported: true
22657
- });
22658
- for (const enumMetadata of metadata.enums) {
22659
- declarations.push(transformEnum(enumMetadata));
22660
- }
22661
- const filteredTables = filterTables(metadata.tables, options);
22662
- const tableInterfaces = [];
22663
- for (const table of filteredTables) {
22664
- tableInterfaces.push(transformTable(table, metadata.enums, options));
22665
- }
22666
- declarations.push(...tableInterfaces);
22667
- declarations.push(createDBInterface(filteredTables, options));
22668
- return { declarations };
22669
- }
22670
22955
  function filterTables(tables, options) {
22671
22956
  if (!options || !options.includePattern && !options.excludePattern) {
22672
22957
  return tables;
@@ -22684,10 +22969,29 @@ function filterTables(tables, options) {
22684
22969
  return true;
22685
22970
  });
22686
22971
  }
22687
- function transformEnum(enumMetadata) {
22972
+
22973
+ // src/transform/utils.ts
22974
+ function toPascalCase(str) {
22975
+ return str.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
22976
+ }
22977
+ function singularize(str) {
22978
+ if (str.endsWith("s")) {
22979
+ return str.slice(0, -1);
22980
+ }
22981
+ return str;
22982
+ }
22983
+
22984
+ // src/transform/enum.ts
22985
+ function getEnumTypeName(enumMeta, defaultSchema = "public") {
22986
+ if (enumMeta.schema === defaultSchema) {
22987
+ return toPascalCase(enumMeta.name);
22988
+ }
22989
+ return toPascalCase(enumMeta.schema) + toPascalCase(enumMeta.name);
22990
+ }
22991
+ function transformEnum(enumMetadata, defaultSchema = "public") {
22688
22992
  return {
22689
22993
  kind: "typeAlias",
22690
- name: toPascalCase(enumMetadata.name),
22994
+ name: getEnumTypeName(enumMetadata, defaultSchema),
22691
22995
  type: {
22692
22996
  kind: "union",
22693
22997
  types: enumMetadata.values.map((value) => ({
@@ -22698,44 +23002,19 @@ function transformEnum(enumMetadata) {
22698
23002
  exported: true
22699
23003
  };
22700
23004
  }
22701
- function transformTable(table, enums, options) {
22702
- const properties = table.columns.map((column) => transformColumn(column, enums, options));
22703
- return {
22704
- kind: "interface",
22705
- name: toPascalCase(singularize(table.name)),
22706
- properties,
22707
- exported: true
22708
- };
22709
- }
22710
- function transformColumn(column, enums, options) {
22711
- const matchingEnum = enums.find((e) => e.name === column.dataType);
22712
- let type;
22713
- if (matchingEnum) {
22714
- const enumTypeName = toPascalCase(matchingEnum.name);
22715
- type = { kind: "reference", name: enumTypeName };
22716
- if (column.isNullable) {
22717
- type = {
22718
- kind: "union",
22719
- types: [type, { kind: "primitive", value: "null" }]
22720
- };
22721
- }
22722
- } else {
22723
- type = mapPostgresType(column.dataType, column.isNullable, column.isArray);
22724
- }
22725
- if (column.isAutoIncrement) {
22726
- type = {
22727
- kind: "generic",
22728
- name: "Generated",
22729
- typeArguments: [type]
22730
- };
23005
+
23006
+ // src/utils/case-converter.ts
23007
+ class CaseConverter extends CamelCasePlugin {
23008
+ toCamelCase(str) {
23009
+ return this.camelCase(str);
22731
23010
  }
22732
- const columnName = options?.camelCase ? toCamelCase(column.name) : column.name;
22733
- return {
22734
- name: columnName,
22735
- type,
22736
- optional: false
22737
- };
22738
23011
  }
23012
+ var caseConverter = new CaseConverter;
23013
+ function toCamelCase(str) {
23014
+ return caseConverter.toCamelCase(str);
23015
+ }
23016
+
23017
+ // src/transform/type-mapper.ts
22739
23018
  function createColumnType(selectType, insertType, updateType) {
22740
23019
  const typeArguments = [selectType];
22741
23020
  if (insertType) {
@@ -22750,10 +23029,10 @@ function createColumnType(selectType, insertType, updateType) {
22750
23029
  typeArguments
22751
23030
  };
22752
23031
  }
22753
- function mapPostgresType(pgType, isNullable, isArray) {
23032
+ function mapPostgresType(pgType, isNullable, isArray, unknownTypes) {
22754
23033
  if (isArray || pgType.endsWith("[]")) {
22755
23034
  const baseTypeName = pgType.endsWith("[]") ? pgType.slice(0, -2) : pgType;
22756
- const elementType = mapPostgresType(baseTypeName, false, false);
23035
+ const elementType = mapPostgresType(baseTypeName, false, false, unknownTypes);
22757
23036
  const arrayType = {
22758
23037
  kind: "array",
22759
23038
  elementType
@@ -22844,6 +23123,10 @@ function mapPostgresType(pgType, isNullable, isArray) {
22844
23123
  break;
22845
23124
  case "time":
22846
23125
  case "timetz":
23126
+ case "interval":
23127
+ baseType = { kind: "primitive", value: "string" };
23128
+ break;
23129
+ case "money":
22847
23130
  baseType = { kind: "primitive", value: "string" };
22848
23131
  break;
22849
23132
  case "json":
@@ -22853,7 +23136,18 @@ function mapPostgresType(pgType, isNullable, isArray) {
22853
23136
  case "bytea":
22854
23137
  baseType = { kind: "primitive", value: "Buffer" };
22855
23138
  break;
23139
+ case "int4range":
23140
+ case "int8range":
23141
+ case "numrange":
23142
+ case "daterange":
23143
+ case "tsrange":
23144
+ case "tstzrange":
23145
+ baseType = { kind: "primitive", value: "string" };
23146
+ break;
22856
23147
  default:
23148
+ if (unknownTypes) {
23149
+ unknownTypes.add(pgType);
23150
+ }
22857
23151
  baseType = { kind: "primitive", value: "unknown" };
22858
23152
  }
22859
23153
  if (isNullable) {
@@ -22864,6 +23158,46 @@ function mapPostgresType(pgType, isNullable, isArray) {
22864
23158
  }
22865
23159
  return baseType;
22866
23160
  }
23161
+
23162
+ // src/transform/table.ts
23163
+ function transformTable(table, enums, options, unknownTypes) {
23164
+ const properties = table.columns.map((column) => transformColumn(column, enums, options, unknownTypes));
23165
+ return {
23166
+ kind: "interface",
23167
+ name: toPascalCase(singularize(table.name)),
23168
+ properties,
23169
+ exported: true
23170
+ };
23171
+ }
23172
+ function transformColumn(column, enums, options, unknownTypes) {
23173
+ const matchingEnum = enums.find((e) => e.name === column.dataType && e.schema === (column.dataTypeSchema ?? "public"));
23174
+ let type;
23175
+ if (matchingEnum) {
23176
+ const enumTypeName = getEnumTypeName(matchingEnum);
23177
+ type = { kind: "reference", name: enumTypeName };
23178
+ if (column.isNullable) {
23179
+ type = {
23180
+ kind: "union",
23181
+ types: [type, { kind: "primitive", value: "null" }]
23182
+ };
23183
+ }
23184
+ } else {
23185
+ type = mapPostgresType(column.dataType, column.isNullable, column.isArray, unknownTypes);
23186
+ }
23187
+ if (column.isAutoIncrement) {
23188
+ type = {
23189
+ kind: "generic",
23190
+ name: "Generated",
23191
+ typeArguments: [type]
23192
+ };
23193
+ }
23194
+ const columnName = options?.camelCase ? toCamelCase(column.name) : column.name;
23195
+ return {
23196
+ name: columnName,
23197
+ type,
23198
+ optional: false
23199
+ };
23200
+ }
22867
23201
  function createDBInterface(tables, options) {
22868
23202
  const properties = tables.map((table) => {
22869
23203
  const tableName = options?.camelCase ? toCamelCase(table.name) : table.name;
@@ -22883,14 +23217,43 @@ function createDBInterface(tables, options) {
22883
23217
  exported: true
22884
23218
  };
22885
23219
  }
22886
- function toPascalCase(str) {
22887
- return str.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
22888
- }
22889
- function singularize(str) {
22890
- if (str.endsWith("s")) {
22891
- return str.slice(0, -1);
23220
+
23221
+ // src/transform/index.ts
23222
+ function transformDatabase(metadata, options) {
23223
+ const declarations = [];
23224
+ const unknownTypes = new Set;
23225
+ declarations.push({
23226
+ kind: "import",
23227
+ imports: ["ColumnType"],
23228
+ from: "kysely",
23229
+ typeOnly: true
23230
+ });
23231
+ declarations.push({
23232
+ kind: "typeAlias",
23233
+ name: "Generated<T>",
23234
+ type: {
23235
+ kind: "raw",
23236
+ value: `T extends ColumnType<infer S, infer I, infer U>
23237
+ ? ColumnType<S, I | undefined, U>
23238
+ : ColumnType<T, T | undefined, T>`
23239
+ },
23240
+ exported: true
23241
+ });
23242
+ for (const enumMetadata of metadata.enums) {
23243
+ declarations.push(transformEnum(enumMetadata));
22892
23244
  }
22893
- return str;
23245
+ const filteredTables = filterTables(metadata.tables, options);
23246
+ const tableInterfaces = [];
23247
+ for (const table of filteredTables) {
23248
+ tableInterfaces.push(transformTable(table, metadata.enums, options, unknownTypes));
23249
+ }
23250
+ declarations.push(...tableInterfaces);
23251
+ declarations.push(createDBInterface(filteredTables, options));
23252
+ const warnings = Array.from(unknownTypes).map((pgType) => ({
23253
+ type: "unknown_type",
23254
+ pgType
23255
+ }));
23256
+ return { program: { declarations }, warnings };
22894
23257
  }
22895
23258
 
22896
23259
  // src/cli.ts
@@ -22956,7 +23319,7 @@ async function generate(options) {
22956
23319
  }
22957
23320
  spinner.succeed(`Found ${source_default.bold(tableCount)} tables and ${source_default.bold(enumCount)} enums`);
22958
23321
  spinner.start("Generating TypeScript types...");
22959
- const program3 = transformDatabase(metadata, {
23322
+ const { program: program3, warnings } = transformDatabase(metadata, {
22960
23323
  camelCase: options.camelCase,
22961
23324
  includePattern: options.includePattern.length > 0 ? options.includePattern : undefined,
22962
23325
  excludePattern: options.excludePattern.length > 0 ? options.excludePattern : undefined
@@ -22965,9 +23328,16 @@ async function generate(options) {
22965
23328
  const absolutePath = resolve(outputPath);
22966
23329
  await writeFile(absolutePath, code, "utf-8");
22967
23330
  spinner.succeed(`Types written to ${source_default.cyan(absolutePath)}`);
23331
+ if (warnings.length > 0) {
23332
+ console.log("");
23333
+ console.log(source_default.yellow("Warnings:"));
23334
+ for (const w of warnings) {
23335
+ console.log(source_default.dim(` Unknown type '${w.pgType}' mapped to 'unknown'`));
23336
+ }
23337
+ }
22968
23338
  await db.destroy();
22969
23339
  console.log("");
22970
- console.log(source_default.green("\u2713 Done!"));
23340
+ console.log(source_default.green("Done!"));
22971
23341
  console.log("");
22972
23342
  }
22973
23343
  function maskPassword(url) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kysely-gen",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Modern PostgreSQL type generator for Kysely - Built with Bun and TDD",
5
5
  "type": "module",
6
6
  "license": "MIT",