zenstack-kit 0.1.12 → 0.1.14

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.
@@ -1,5 +1,5 @@
1
1
  import type { KyselyDialect } from "../../sql/kysely-adapter.js";
2
- import type { SchemaSnapshot, SchemaTable, SchemaColumn } from "../../schema/snapshot.js";
2
+ import type { SchemaSnapshot, SchemaTable, SchemaColumn, SchemaEnum } from "../../schema/snapshot.js";
3
3
  export declare function diffSchemas(previous: SchemaSnapshot | null, current: SchemaSnapshot): {
4
4
  addedModels: SchemaTable[];
5
5
  removedModels: SchemaTable[];
@@ -83,6 +83,13 @@ export declare function diffSchemas(previous: SchemaSnapshot | null, current: Sc
83
83
  from: string;
84
84
  to: string;
85
85
  }>;
86
+ addedEnums: SchemaEnum[];
87
+ removedEnums: SchemaEnum[];
88
+ alteredEnums: {
89
+ enumName: string;
90
+ addedValues: string[];
91
+ removedValues: string[];
92
+ }[];
86
93
  };
87
94
  type PrismaDiff = ReturnType<typeof diffSchemas>;
88
95
  export declare function applyRenameMappings(diff: PrismaDiff, renameTables?: Array<{
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/migrations/prisma/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAyK1F,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAAE,OAAO,EAAE,cAAc;;;;mBAsB5C,MAAM;gBAAU,YAAY;;;mBAC1B,MAAM;gBAAU,YAAY;;;mBAEvD,MAAM;oBACL,MAAM;kBACR,YAAY;iBACb,YAAY;;;mBAGV,MAAM;oBACL;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAGpC,MAAM;oBACL;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAGpC,MAAM;eACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAG/B,MAAM;eACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAG/B,MAAM;oBACL;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7B;;;mBAGU,MAAM;oBACL;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7B;;;mBAGU,MAAM;mBACN;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;kBACpC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;mBAiCxB,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;oBAClC,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;EAE/E;AAED,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAkGjD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAM,EACtD,aAAa,GAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAM,GACrE,UAAU,CA8FZ;AA2CD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACpC,OAAO,EAAE,aAAa,GACrB;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAkNlC"}
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/migrations/prisma/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AA4KtG,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAAE,OAAO,EAAE,cAAc;;;;mBAsB5C,MAAM;gBAAU,YAAY;;;mBAC1B,MAAM;gBAAU,YAAY;;;mBAEvD,MAAM;oBACL,MAAM;kBACR,YAAY;iBACb,YAAY;;;mBAGV,MAAM;oBACL;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAGpC,MAAM;oBACL;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAGpC,MAAM;eACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAG/B,MAAM;eACV;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;;mBAG/B,MAAM;oBACL;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7B;;;mBAGU,MAAM;oBACL;YACV,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,eAAe,EAAE,MAAM,CAAC;YACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;SAC7B;;;mBAGU,MAAM;mBACN;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;kBACpC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,EAAE,CAAA;SAAE;;mBA4ExB,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;oBAClC,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;;;;kBA/ClE,MAAM;qBACH,MAAM,EAAE;uBACN,MAAM,EAAE;;EAkD1B;AAED,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAkGjD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAM,EACtD,aAAa,GAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAM,GACrE,UAAU,CA8FZ;AA2CD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EACpC,OAAO,EAAE,aAAa,GACrB;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAuPlC"}
@@ -1,4 +1,4 @@
1
- import { compileCreateTable, compileDropTable, compileAddColumn, compileDropColumn, compileRenameTable, compileRenameColumn, compileCreateIndex, compileDropIndex, compileAddUniqueConstraint, compileDropConstraint, compileAddForeignKeyConstraint, compileAddPrimaryKeyConstraint, compileAlterColumn, } from "../../sql/compiler.js";
1
+ import { compileCreateTable, compileDropTable, compileAddColumn, compileDropColumn, compileRenameTable, compileRenameColumn, compileCreateIndex, compileDropIndex, compileAddUniqueConstraint, compileDropConstraint, compileAddForeignKeyConstraint, compileAddPrimaryKeyConstraint, compileAlterColumn, compileCreateEnum, compileDropEnum, compileAddEnumValue, } from "../../sql/compiler.js";
2
2
  function diffTableChanges(previousModel, currentModel, tableName) {
3
3
  const addedFields = [];
4
4
  const removedFields = [];
@@ -140,6 +140,37 @@ export function diffSchemas(previous, current) {
140
140
  removedForeignKeys.push(...modelDiff.removedForeignKeys);
141
141
  primaryKeyChanges.push(...modelDiff.primaryKeyChanges);
142
142
  }
143
+ // Diff enums
144
+ const previousEnums = new Map();
145
+ const currentEnums = new Map();
146
+ (previous?.enums ?? []).forEach((e) => previousEnums.set(e.name, e));
147
+ (current.enums ?? []).forEach((e) => currentEnums.set(e.name, e));
148
+ const addedEnums = [];
149
+ const removedEnums = [];
150
+ const alteredEnums = [];
151
+ for (const [enumName, enumDef] of currentEnums.entries()) {
152
+ if (!previousEnums.has(enumName)) {
153
+ addedEnums.push(enumDef);
154
+ }
155
+ }
156
+ for (const [enumName, enumDef] of previousEnums.entries()) {
157
+ if (!currentEnums.has(enumName)) {
158
+ removedEnums.push(enumDef);
159
+ }
160
+ }
161
+ // Check for altered enums (added/removed values)
162
+ for (const [enumName, currentEnum] of currentEnums.entries()) {
163
+ const previousEnum = previousEnums.get(enumName);
164
+ if (!previousEnum)
165
+ continue;
166
+ const prevValues = new Set(previousEnum.values);
167
+ const currValues = new Set(currentEnum.values);
168
+ const addedValues = currentEnum.values.filter((v) => !prevValues.has(v));
169
+ const removedValues = previousEnum.values.filter((v) => !currValues.has(v));
170
+ if (addedValues.length > 0 || removedValues.length > 0) {
171
+ alteredEnums.push({ enumName, addedValues, removedValues });
172
+ }
173
+ }
143
174
  return {
144
175
  addedModels,
145
176
  removedModels,
@@ -155,6 +186,9 @@ export function diffSchemas(previous, current) {
155
186
  primaryKeyChanges,
156
187
  renamedTables: [],
157
188
  renamedColumns: [],
189
+ addedEnums,
190
+ removedEnums,
191
+ alteredEnums,
158
192
  };
159
193
  }
160
194
  function columnsSignature(columns) {
@@ -329,6 +363,32 @@ export function buildSqlStatements(diff, dialect) {
329
363
  const up = [];
330
364
  const down = [];
331
365
  const compileOpts = { dialect };
366
+ // Create enums FIRST (before tables that use them)
367
+ for (const enumDef of diff.addedEnums) {
368
+ const sql = compileCreateEnum(enumDef, compileOpts);
369
+ if (sql) {
370
+ up.push(sql);
371
+ const dropSql = compileDropEnum(enumDef.name, compileOpts);
372
+ if (dropSql)
373
+ down.unshift(dropSql);
374
+ }
375
+ }
376
+ // Add new values to existing enums
377
+ for (const altered of diff.alteredEnums) {
378
+ for (const value of altered.addedValues) {
379
+ const sql = compileAddEnumValue(altered.enumName, value, compileOpts);
380
+ if (sql) {
381
+ up.push(sql);
382
+ // Note: PostgreSQL doesn't support removing enum values easily,
383
+ // so we don't add a down migration for added values
384
+ }
385
+ }
386
+ // Note: Removing enum values in PostgreSQL requires recreating the type
387
+ // which is complex and potentially data-losing. We skip this for now.
388
+ if (altered.removedValues.length > 0 && dialect === "postgres") {
389
+ up.push(`-- WARNING: Removing enum values (${altered.removedValues.join(", ")}) from "${altered.enumName}" requires manual migration`);
390
+ }
391
+ }
332
392
  // Table renames
333
393
  for (const rename of diff.renamedTables) {
334
394
  up.push(compileRenameTable(rename.from, rename.to, compileOpts));
@@ -438,5 +498,15 @@ export function buildSqlStatements(diff, dialect) {
438
498
  up.push(compileAddForeignKeyConstraint(tableName, foreignKey.name, foreignKey.columns, foreignKey.referencedTable, foreignKey.referencedColumns, compileOpts));
439
499
  down.unshift(compileDropConstraint(tableName, foreignKey.name, compileOpts));
440
500
  }
501
+ // Drop enums LAST (after tables that use them are dropped)
502
+ for (const enumDef of diff.removedEnums) {
503
+ const sql = compileDropEnum(enumDef.name, compileOpts);
504
+ if (sql) {
505
+ up.push(sql);
506
+ const createSql = compileCreateEnum(enumDef, compileOpts);
507
+ if (createSql)
508
+ down.unshift(createSql);
509
+ }
510
+ }
441
511
  return { up, down };
442
512
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/schema/pull.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEnF,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,8BAA8B;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AA8lBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA4C1E"}
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/schema/pull.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEnF,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,8BAA8B;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAsqBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAkD1E"}
@@ -91,7 +91,9 @@ function buildDatasourceBlock(dialect) {
91
91
  ].join("\n");
92
92
  }
93
93
  function buildModelBlock(options) {
94
- const { table, foreignKeys, indexes, primaryKeys, allTables, columnDefaults } = options;
94
+ const { table, foreignKeys, indexes, primaryKeys, allTables, columnDefaults, enums = [] } = options;
95
+ // Build a map of enum names for quick lookup
96
+ const enumNames = new Set(enums.map((e) => e.name));
95
97
  const modelName = toPascalCase(table.name) || "Model";
96
98
  const fieldLines = [];
97
99
  // Get primary key columns for this table
@@ -170,7 +172,18 @@ function buildModelBlock(options) {
170
172
  for (const column of sortedColumns) {
171
173
  const fieldName = toCamelCase(column.name) || column.name;
172
174
  const mapped = fieldName !== column.name;
173
- const { type, isArray } = normalizeType(column.dataType);
175
+ // Check if the column type is an enum (PostgreSQL stores udt_name for enum types)
176
+ const rawDataType = column.dataType.replace(/\[\]$/, ""); // Remove array suffix
177
+ const isEnumType = enumNames.has(rawDataType);
178
+ const isArray = column.dataType.endsWith("[]");
179
+ let type;
180
+ if (isEnumType) {
181
+ type = toPascalCase(rawDataType);
182
+ }
183
+ else {
184
+ const normalized = normalizeType(column.dataType);
185
+ type = normalized.type;
186
+ }
174
187
  const optional = column.isNullable ? "?" : "";
175
188
  const modifiers = [];
176
189
  const isPkColumn = pkColumns.has(column.name);
@@ -483,6 +496,44 @@ async function extractColumnDefaults(db, dialect, tableNames) {
483
496
  }
484
497
  return defaultsByTable;
485
498
  }
499
+ async function extractEnums(db, dialect) {
500
+ const enums = [];
501
+ if (dialect === "postgres") {
502
+ // Query PostgreSQL system catalogs for enum types
503
+ const result = await sql `
504
+ SELECT
505
+ t.typname as enum_name,
506
+ e.enumlabel as enum_value
507
+ FROM pg_type t
508
+ JOIN pg_enum e ON t.oid = e.enumtypid
509
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
510
+ WHERE n.nspname = 'public'
511
+ ORDER BY t.typname, e.enumsortorder
512
+ `.execute(db);
513
+ // Group by enum name
514
+ const enumMap = new Map();
515
+ for (const row of result.rows) {
516
+ if (!enumMap.has(row.enum_name)) {
517
+ enumMap.set(row.enum_name, []);
518
+ }
519
+ enumMap.get(row.enum_name).push(row.enum_value);
520
+ }
521
+ for (const [name, values] of enumMap) {
522
+ enums.push({ name, values });
523
+ }
524
+ }
525
+ // MySQL and SQLite don't have standalone enum types
526
+ // MySQL uses inline ENUM definitions in column types
527
+ return enums;
528
+ }
529
+ function buildEnumBlock(enumInfo) {
530
+ const lines = [`enum ${toPascalCase(enumInfo.name)} {`];
531
+ for (const value of enumInfo.values) {
532
+ lines.push(` ${value}`);
533
+ }
534
+ lines.push("}");
535
+ return lines.join("\n");
536
+ }
486
537
  export async function pullSchema(options) {
487
538
  const { db, destroy } = await createKyselyAdapter({
488
539
  dialect: options.dialect,
@@ -498,15 +549,20 @@ export async function pullSchema(options) {
498
549
  const indexes = await extractIndexes(db, options.dialect, tableNames);
499
550
  const primaryKeys = await extractPrimaryKeys(db, options.dialect, tableNames);
500
551
  const columnDefaultsByTable = await extractColumnDefaults(db, options.dialect, tableNames);
501
- const blocks = filtered.map((table) => buildModelBlock({
552
+ const enums = await extractEnums(db, options.dialect);
553
+ // Build enum blocks
554
+ const enumBlocks = enums.map((e) => buildEnumBlock(e));
555
+ // Build model blocks
556
+ const modelBlocks = filtered.map((table) => buildModelBlock({
502
557
  table,
503
558
  foreignKeys,
504
559
  indexes,
505
560
  primaryKeys,
506
561
  allTables,
507
562
  columnDefaults: columnDefaultsByTable.get(table.name) ?? new Map(),
563
+ enums, // Pass enums for type mapping
508
564
  }));
509
- const schema = [buildDatasourceBlock(options.dialect), ...blocks].join("\n\n");
565
+ const schema = [buildDatasourceBlock(options.dialect), ...enumBlocks, ...modelBlocks].join("\n\n");
510
566
  if (options.writeFile !== false) {
511
567
  await fs.mkdir(path.dirname(options.outputPath), { recursive: true });
512
568
  await fs.writeFile(options.outputPath, schema.trimEnd() + "\n", "utf-8");
@@ -10,6 +10,8 @@ export interface SchemaColumn {
10
10
  isArray: boolean;
11
11
  default?: string | number | boolean;
12
12
  isAutoincrement?: boolean;
13
+ /** If true, type refers to an enum name rather than a SQL type */
14
+ isEnum?: boolean;
13
15
  }
14
16
  export interface SchemaConstraint {
15
17
  name: string;
@@ -33,8 +35,13 @@ export interface SchemaTable {
33
35
  indexes: SchemaIndex[];
34
36
  foreignKeys: SchemaForeignKey[];
35
37
  }
38
+ export interface SchemaEnum {
39
+ name: string;
40
+ values: string[];
41
+ }
36
42
  export interface SchemaSnapshot {
37
43
  tables: SchemaTable[];
44
+ enums: SchemaEnum[];
38
45
  }
39
46
  export interface SchemaSnapshotFile {
40
47
  version: 2;
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/schema/snapshot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;CACxB;AAiUD,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAaxF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,kBAAkB,CAMzE"}
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/schema/snapshot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;CACxB;AAuVD,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAkBxF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,kBAAkB,CAMzE"}
@@ -65,9 +65,20 @@ function getDefaultValue(field) {
65
65
  if (funcName === "now") {
66
66
  return { hasDefault: true, default: "now()" };
67
67
  }
68
- // Return function name for other functions
68
+ // cuid(), uuid(), nanoid() are handled at the application level by ZenStack/Prisma,
69
+ // not at the database level. We mark hasDefault as true so the column isn't
70
+ // required in INSERT statements (the ORM will provide the value).
71
+ if (funcName === "cuid" || funcName === "uuid" || funcName === "nanoid") {
72
+ return { hasDefault: true };
73
+ }
74
+ // Return function name for other functions (dbgenerated, etc.)
69
75
  return { hasDefault: true, default: `${funcName}()` };
70
76
  }
77
+ // Handle enum default values like @default(USER) - these are ReferenceExpr
78
+ if (expr.$type === "ReferenceExpr") {
79
+ const enumValue = expr.target.$refText;
80
+ return { hasDefault: true, default: enumValue };
81
+ }
71
82
  return { hasDefault: true };
72
83
  }
73
84
  function getTableName(model) {
@@ -124,12 +135,12 @@ function buildForeignKeyName(tableName, columns, _referencedTable, _referencedCo
124
135
  function getFieldType(field) {
125
136
  const ref = field.type.reference?.ref;
126
137
  if (ref && isDataModel(ref)) {
127
- return { type: ref.name, isRelation: true };
138
+ return { type: ref.name, isRelation: true, isEnum: false };
128
139
  }
129
140
  if (ref && isEnum(ref)) {
130
- return { type: ref.name, isRelation: false };
141
+ return { type: ref.name, isRelation: false, isEnum: true };
131
142
  }
132
- return { type: field.type.type ?? "String", isRelation: false };
143
+ return { type: field.type.type ?? "String", isRelation: false, isEnum: false };
133
144
  }
134
145
  function getRelationFieldNames(field) {
135
146
  const relationAttr = getAttribute(field, "@relation");
@@ -164,14 +175,16 @@ function parseModel(model) {
164
175
  }
165
176
  const defaultInfo = getDefaultValue(field);
166
177
  const columnName = getColumnName(field);
167
- const sqlType = mapFieldTypeToSQL(typeInfo.type);
178
+ // For enum types, store the enum name directly; for other types, map to SQL type
179
+ const columnType = typeInfo.isEnum ? typeInfo.type : mapFieldTypeToSQL(typeInfo.type);
168
180
  columns.push({
169
181
  name: columnName,
170
- type: sqlType,
182
+ type: columnType,
171
183
  notNull: !field.type.optional,
172
184
  isArray: field.type.array ?? false,
173
185
  default: defaultInfo.default,
174
186
  isAutoincrement: defaultInfo.isAutoincrement,
187
+ isEnum: typeInfo.isEnum || undefined,
175
188
  });
176
189
  }
177
190
  const modelIdAttr = getAttribute(model, "@@id");
@@ -257,6 +270,13 @@ function parseModel(model) {
257
270
  foreignKeys: foreignKeys.sort((a, b) => a.name.localeCompare(b.name)),
258
271
  };
259
272
  }
273
+ function parseEnum(enumDecl) {
274
+ const values = enumDecl.fields.map((field) => field.name);
275
+ return {
276
+ name: enumDecl.name,
277
+ values,
278
+ };
279
+ }
260
280
  export async function generateSchemaSnapshot(schemaPath) {
261
281
  const loadResult = await loadDocument(schemaPath);
262
282
  if (!loadResult.success) {
@@ -267,7 +287,11 @@ export async function generateSchemaSnapshot(schemaPath) {
267
287
  const tables = dataModels
268
288
  .map((model) => parseModel(model))
269
289
  .sort((a, b) => a.name.localeCompare(b.name));
270
- return { tables };
290
+ const enumDecls = loadResult.model.declarations.filter(isEnum);
291
+ const enums = enumDecls
292
+ .map((enumDecl) => parseEnum(enumDecl))
293
+ .sort((a, b) => a.name.localeCompare(b.name));
294
+ return { tables, enums };
271
295
  }
272
296
  export function createSnapshot(schema) {
273
297
  return {
@@ -5,7 +5,7 @@
5
5
  * without requiring a database connection.
6
6
  */
7
7
  import type { KyselyDialect } from "./kysely-adapter.js";
8
- import type { SchemaTable, SchemaColumn } from "../schema/snapshot.js";
8
+ import type { SchemaTable, SchemaColumn, SchemaEnum } from "../schema/snapshot.js";
9
9
  export interface SqlMigration {
10
10
  up: string[];
11
11
  down: string[];
@@ -71,4 +71,23 @@ export declare function compileAlterColumn(tableName: string, columnName: string
71
71
  setDefault?: string | number | boolean;
72
72
  dropDefault?: boolean;
73
73
  }, options: CompileSqlOptions): string[];
74
+ /**
75
+ * Compile a CREATE TYPE ... AS ENUM statement for PostgreSQL
76
+ * For MySQL and SQLite, enums are handled differently (inline or as text)
77
+ */
78
+ export declare function compileCreateEnum(enumDef: SchemaEnum, options: CompileSqlOptions): string | null;
79
+ /**
80
+ * Compile a DROP TYPE statement for PostgreSQL
81
+ */
82
+ export declare function compileDropEnum(enumName: string, options: CompileSqlOptions): string | null;
83
+ /**
84
+ * Compile an ALTER TYPE ... ADD VALUE statement for PostgreSQL
85
+ * Adds a new value to an existing enum type
86
+ */
87
+ export declare function compileAddEnumValue(enumName: string, value: string, options: CompileSqlOptions): string | null;
88
+ /**
89
+ * Map column type considering enum types
90
+ * For enum columns, returns the enum type name (PostgreSQL) or text (other dialects)
91
+ */
92
+ export declare function mapColumnTypeWithEnum(column: SchemaColumn, dialect: KyselyDialect): string;
74
93
  //# sourceMappingURL=compiler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/sql/compiler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/sql/compiler.ts"],"names":[],"mappings":"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"}
@@ -47,10 +47,12 @@ export function compileCreateTable(model, options) {
47
47
  const db = createCompilerDb(options.dialect);
48
48
  let builder = db.schema.createTable(model.name);
49
49
  for (const column of model.columns) {
50
- const columnType = mapColumnType(column.type, options.dialect, {
51
- isArray: column.isArray,
52
- isAutoincrement: column.isAutoincrement,
53
- });
50
+ const columnType = column.isEnum
51
+ ? mapColumnTypeWithEnum(column, options.dialect)
52
+ : mapColumnType(column.type, options.dialect, {
53
+ isArray: column.isArray,
54
+ isAutoincrement: column.isAutoincrement,
55
+ });
54
56
  builder = builder.addColumn(column.name, sql.raw(columnType), (cb) => {
55
57
  // For SERIAL types in PostgreSQL, NOT NULL is implicit and we don't need defaults
56
58
  const isSerialType = column.isAutoincrement && options.dialect === "postgres";
@@ -58,7 +60,7 @@ export function compileCreateTable(model, options) {
58
60
  cb = cb.notNull();
59
61
  }
60
62
  if (column.default !== undefined && !isSerialType) {
61
- cb = cb.defaultTo(sql.raw(formatDefault(column.default, options.dialect)));
63
+ cb = cb.defaultTo(sql.raw(formatDefault(column.default, options.dialect, column)));
62
64
  }
63
65
  return cb;
64
66
  });
@@ -89,10 +91,12 @@ export function compileDropTable(tableName, options) {
89
91
  */
90
92
  export function compileAddColumn(tableName, column, options) {
91
93
  const db = createCompilerDb(options.dialect);
92
- const columnType = mapColumnType(column.type, options.dialect, {
93
- isArray: column.isArray,
94
- isAutoincrement: column.isAutoincrement,
95
- });
94
+ const columnType = column.isEnum
95
+ ? mapColumnTypeWithEnum(column, options.dialect)
96
+ : mapColumnType(column.type, options.dialect, {
97
+ isArray: column.isArray,
98
+ isAutoincrement: column.isAutoincrement,
99
+ });
96
100
  return (db.schema
97
101
  .alterTable(tableName)
98
102
  .addColumn(column.name, sql.raw(columnType), (cb) => {
@@ -101,7 +105,7 @@ export function compileAddColumn(tableName, column, options) {
101
105
  cb = cb.notNull();
102
106
  }
103
107
  if (column.default !== undefined && !isSerialType) {
104
- cb = cb.defaultTo(sql.raw(formatDefault(column.default, options.dialect)));
108
+ cb = cb.defaultTo(sql.raw(formatDefault(column.default, options.dialect, column)));
105
109
  }
106
110
  return cb;
107
111
  })
@@ -251,12 +255,17 @@ function mapColumnType(type, dialect, options) {
251
255
  /**
252
256
  * Format a default value for SQL
253
257
  */
254
- function formatDefault(value, dialect) {
258
+ function formatDefault(value, dialect, column) {
255
259
  if (typeof value === "string") {
256
260
  // Check if it's a function call like now() or autoincrement()
257
261
  if (/^\w+\([^)]*\)$/.test(value)) {
258
262
  return value;
259
263
  }
264
+ // For enum columns in PostgreSQL, we need to cast the default value
265
+ if (column?.isEnum && dialect === "postgres") {
266
+ const escapedValue = value.replace(/'/g, "''");
267
+ return `'${escapedValue}'::"${column.type}"`;
268
+ }
260
269
  // Escape string values
261
270
  return `'${value.replace(/'/g, "''")}'`;
262
271
  }
@@ -268,3 +277,55 @@ function formatDefault(value, dialect) {
268
277
  }
269
278
  return String(value);
270
279
  }
280
+ /**
281
+ * Compile a CREATE TYPE ... AS ENUM statement for PostgreSQL
282
+ * For MySQL and SQLite, enums are handled differently (inline or as text)
283
+ */
284
+ export function compileCreateEnum(enumDef, options) {
285
+ if (options.dialect !== "postgres") {
286
+ // MySQL and SQLite don't have standalone enum types
287
+ return null;
288
+ }
289
+ const values = enumDef.values.map((v) => `'${v.replace(/'/g, "''")}'`).join(", ");
290
+ return `CREATE TYPE "${enumDef.name}" AS ENUM (${values});`;
291
+ }
292
+ /**
293
+ * Compile a DROP TYPE statement for PostgreSQL
294
+ */
295
+ export function compileDropEnum(enumName, options) {
296
+ if (options.dialect !== "postgres") {
297
+ return null;
298
+ }
299
+ return `DROP TYPE IF EXISTS "${enumName}";`;
300
+ }
301
+ /**
302
+ * Compile an ALTER TYPE ... ADD VALUE statement for PostgreSQL
303
+ * Adds a new value to an existing enum type
304
+ */
305
+ export function compileAddEnumValue(enumName, value, options) {
306
+ if (options.dialect !== "postgres") {
307
+ return null;
308
+ }
309
+ const escapedValue = value.replace(/'/g, "''");
310
+ return `ALTER TYPE "${enumName}" ADD VALUE '${escapedValue}';`;
311
+ }
312
+ /**
313
+ * Map column type considering enum types
314
+ * For enum columns, returns the enum type name (PostgreSQL) or text (other dialects)
315
+ */
316
+ export function mapColumnTypeWithEnum(column, dialect) {
317
+ if (column.isEnum) {
318
+ if (dialect === "postgres") {
319
+ // Use the native enum type for PostgreSQL
320
+ const baseType = `"${column.type}"`;
321
+ return column.isArray ? `${baseType}[]` : baseType;
322
+ }
323
+ // For MySQL and SQLite, fall back to text
324
+ return column.isArray ? "text[]" : "text";
325
+ }
326
+ // Use existing type mapping for non-enum columns
327
+ return mapColumnType(column.type, dialect, {
328
+ isArray: column.isArray,
329
+ isAutoincrement: column.isAutoincrement,
330
+ });
331
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zenstack-kit",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "Drizzle-kit like CLI tooling for ZenStack schemas with Kysely support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",