kysely-gen 0.5.0 → 0.6.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 +73 -11
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -44402,7 +44402,7 @@ function canMap(obj, opt) {
44402
44402
  }
44403
44403
 
44404
44404
  // src/cli.ts
44405
- import { writeFile } from "fs/promises";
44405
+ import { readFile, writeFile } from "fs/promises";
44406
44406
  import { resolve } from "path";
44407
44407
 
44408
44408
  // src/ast/serialize.ts
@@ -44644,16 +44644,53 @@ function singularize(str) {
44644
44644
  }
44645
44645
 
44646
44646
  // src/transform/enum.ts
44647
- function getEnumTypeName(enumMeta, defaultSchema = "public") {
44647
+ function getEnumKey(enumMeta) {
44648
+ return `${enumMeta.schema}.${enumMeta.name}`;
44649
+ }
44650
+ function getBaseName(enumMeta, defaultSchema = "public") {
44648
44651
  if (enumMeta.schema === defaultSchema) {
44649
44652
  return toPascalCase(enumMeta.name);
44650
44653
  }
44651
44654
  return toPascalCase(enumMeta.schema) + toPascalCase(enumMeta.name);
44652
44655
  }
44653
- function transformEnum(enumMetadata, defaultSchema = "public") {
44656
+ function getFullName(enumMeta) {
44657
+ return toPascalCase(enumMeta.schema) + toPascalCase(enumMeta.name);
44658
+ }
44659
+
44660
+ class EnumNameResolver {
44661
+ nameMap;
44662
+ constructor(enums, defaultSchema = "public") {
44663
+ this.nameMap = new Map;
44664
+ const baseNames = new Map;
44665
+ for (const enumMeta of enums) {
44666
+ const baseName = getBaseName(enumMeta, defaultSchema);
44667
+ const existing = baseNames.get(baseName) ?? [];
44668
+ existing.push(enumMeta);
44669
+ baseNames.set(baseName, existing);
44670
+ }
44671
+ for (const [, enumsWithSameName] of baseNames) {
44672
+ if (enumsWithSameName.length === 1) {
44673
+ const enumMeta = enumsWithSameName[0];
44674
+ this.nameMap.set(getEnumKey(enumMeta), getBaseName(enumMeta, defaultSchema));
44675
+ } else {
44676
+ for (const enumMeta of enumsWithSameName) {
44677
+ this.nameMap.set(getEnumKey(enumMeta), getFullName(enumMeta));
44678
+ }
44679
+ }
44680
+ }
44681
+ }
44682
+ getName(enumMeta) {
44683
+ return this.nameMap.get(getEnumKey(enumMeta));
44684
+ }
44685
+ }
44686
+ function getEnumTypeName(enumMeta, defaultSchema = "public") {
44687
+ return getBaseName(enumMeta, defaultSchema);
44688
+ }
44689
+ function transformEnum(enumMetadata, resolver) {
44690
+ const name = resolver ? resolver.getName(enumMetadata) : getEnumTypeName(enumMetadata);
44654
44691
  return {
44655
44692
  kind: "typeAlias",
44656
- name: getEnumTypeName(enumMetadata, defaultSchema),
44693
+ name,
44657
44694
  type: {
44658
44695
  kind: "union",
44659
44696
  types: enumMetadata.values.map((value) => ({
@@ -44677,8 +44714,8 @@ function toCamelCase(str) {
44677
44714
  }
44678
44715
 
44679
44716
  // src/transform/table.ts
44680
- function transformTable(table, enums, mapType, options, unknownTypes) {
44681
- const properties = table.columns.map((column) => transformColumn(column, enums, mapType, options, unknownTypes));
44717
+ function transformTable(table, enums, enumResolver, mapType, options, unknownTypes) {
44718
+ const properties = table.columns.map((column) => transformColumn(column, enums, enumResolver, mapType, options, unknownTypes));
44682
44719
  return {
44683
44720
  kind: "interface",
44684
44721
  name: toPascalCase(singularize(table.name)),
@@ -44686,11 +44723,11 @@ function transformTable(table, enums, mapType, options, unknownTypes) {
44686
44723
  exported: true
44687
44724
  };
44688
44725
  }
44689
- function transformColumn(column, enums, mapType, options, unknownTypes) {
44726
+ function transformColumn(column, enums, enumResolver, mapType, options, unknownTypes) {
44690
44727
  const matchingEnum = enums.find((e) => e.name === column.dataType && e.schema === (column.dataTypeSchema ?? "public"));
44691
44728
  let type;
44692
44729
  if (matchingEnum) {
44693
- const enumTypeName = getEnumTypeName(matchingEnum);
44730
+ const enumTypeName = enumResolver.getName(matchingEnum);
44694
44731
  type = { kind: "reference", name: enumTypeName };
44695
44732
  if (column.isNullable) {
44696
44733
  type = {
@@ -45820,13 +45857,14 @@ function transformDatabase(metadata, options) {
45820
45857
  exported: true
45821
45858
  });
45822
45859
  }
45860
+ const enumResolver = new EnumNameResolver(metadata.enums);
45823
45861
  for (const enumMetadata of metadata.enums) {
45824
- declarations.push(transformEnum(enumMetadata));
45862
+ declarations.push(transformEnum(enumMetadata, enumResolver));
45825
45863
  }
45826
45864
  const filteredTables = filterTables(metadata.tables, options);
45827
45865
  const tableInterfaces = [];
45828
45866
  for (const table of filteredTables) {
45829
- tableInterfaces.push(transformTable(table, metadata.enums, mapType, options, unknownTypes));
45867
+ tableInterfaces.push(transformTable(table, metadata.enums, enumResolver, mapType, options, unknownTypes));
45830
45868
  }
45831
45869
  declarations.push(...tableInterfaces);
45832
45870
  declarations.push(createDBInterface(filteredTables, options));
@@ -45874,7 +45912,7 @@ function detectDialect(connectionString) {
45874
45912
 
45875
45913
  // src/cli.ts
45876
45914
  var program2 = new Command;
45877
- program2.name("kysely-gen").description("Generate Kysely types from your database").version("0.1.0").option("-o, --out <path>", "Output file path", "./db.d.ts").option("-s, --schema <name>", "Schema to introspect (can be specified multiple times)", collect, []).option("--url <connection-string>", "Database connection string (overrides DATABASE_URL env)").option("-d, --dialect <name>", "Database dialect (postgres, mysql, sqlite). Auto-detected from URL if not specified").option("--camel-case", "Convert column and table names to camelCase (use with Kysely CamelCasePlugin)").option("--include-pattern <pattern>", "Only include tables matching glob pattern (schema.table format)", collect, []).option("--exclude-pattern <pattern>", "Exclude tables matching glob pattern (schema.table format)", collect, []).option("--print", "Output to stdout instead of writing to file").action(async (options) => {
45915
+ program2.name("kysely-gen").description("Generate Kysely types from your database").version("0.1.0").option("-o, --out <path>", "Output file path", "./db.d.ts").option("-s, --schema <name>", "Schema to introspect (can be specified multiple times)", collect, []).option("--url <connection-string>", "Database connection string (overrides DATABASE_URL env)").option("-d, --dialect <name>", "Database dialect (postgres, mysql, sqlite). Auto-detected from URL if not specified").option("--camel-case", "Convert column and table names to camelCase (use with Kysely CamelCasePlugin)").option("--include-pattern <pattern>", "Only include tables matching glob pattern (schema.table format)", collect, []).option("--exclude-pattern <pattern>", "Exclude tables matching glob pattern (schema.table format)", collect, []).option("--print", "Output to stdout instead of writing to file").option("--verify", "Verify types match existing file (exit 1 if different)").action(async (options) => {
45878
45916
  try {
45879
45917
  await generate(options);
45880
45918
  } catch (error2) {
@@ -45893,6 +45931,10 @@ function collect(value, previous) {
45893
45931
  async function generate(options) {
45894
45932
  const printMode = options.print === true;
45895
45933
  const log = printMode ? (...args) => console.error(...args) : (...args) => console.log(...args);
45934
+ if (options.verify && options.print) {
45935
+ console.error(source_default.red("Error: Cannot use --verify with --print"));
45936
+ process.exit(1);
45937
+ }
45896
45938
  const databaseUrl = options.url || process.env.DATABASE_URL;
45897
45939
  if (!databaseUrl) {
45898
45940
  console.error(source_default.red("Error: DATABASE_URL environment variable is required"));
@@ -45964,6 +46006,26 @@ async function generate(options) {
45964
46006
  excludePattern: options.excludePattern.length > 0 ? options.excludePattern : undefined
45965
46007
  });
45966
46008
  const code = serialize(astProgram);
46009
+ if (options.verify) {
46010
+ const absolutePath = resolve(outputPath);
46011
+ const existing = await readFile(absolutePath, "utf-8").catch(() => null);
46012
+ if (existing === null) {
46013
+ spinner.fail(`File not found: ${source_default.cyan(absolutePath)}`);
46014
+ await db.destroy();
46015
+ process.exit(1);
46016
+ }
46017
+ if (existing === code) {
46018
+ spinner.succeed("Types are up-to-date");
46019
+ await db.destroy();
46020
+ process.exit(0);
46021
+ }
46022
+ spinner.fail("Types are out of date");
46023
+ log("");
46024
+ log(source_default.yellow("Generated types differ from existing file."));
46025
+ log(source_default.dim("Run kysely-gen to update."));
46026
+ await db.destroy();
46027
+ process.exit(1);
46028
+ }
45967
46029
  if (printMode) {
45968
46030
  spinner.succeed("Types generated");
45969
46031
  process.stdout.write(code);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kysely-gen",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Database type generator for Kysely - Supports PostgreSQL, MySQL, and SQLite",
5
5
  "type": "module",
6
6
  "license": "MIT",