@izumisy/kyrage 0.5.0 → 0.7.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.
package/dist/index.d.ts CHANGED
@@ -34,12 +34,10 @@ declare const defineTable: <T extends Record<string, DefinedColumn>>(name: strin
34
34
  };
35
35
  type DefinedTable = ReturnType<typeof defineTable>;
36
36
  type DefinedTables = Array<DefinedTable>;
37
- declare const defineConfig: (config: {
37
+ type DefineConfigProp = {
38
38
  database: DatabaseValue;
39
- tables: DefinedTable[];
40
- }) => {
41
- database: DatabaseValue;
42
- tables: DefinedTable[];
39
+ tables: DefinedTables;
43
40
  };
41
+ declare const defineConfig: (config: DefineConfigProp) => DefineConfigProp;
44
42
 
45
- export { type DefinedTable, type DefinedTables, column, defineConfig, defineTable };
43
+ export { type DefineConfigProp, type DefinedTable, type DefinedTables, column, defineConfig, defineTable };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import"./chunk-EY62Q3Z2.js";var t=(a,e)=>({type:a,notNull:e?.notNull,primaryKey:e?.primaryKey,unique:e?.unique,defaultSql:e?.defaultSql}),l=(a,e)=>({tableName:a,columns:e}),n=a=>a;export{t as column,n as defineConfig,l as defineTable};
1
+ import"./chunk-EY62Q3Z2.js";var a=(t,e)=>({type:t,notNull:e?.notNull,primaryKey:e?.primaryKey,unique:e?.unique,defaultSql:e?.defaultSql}),n=(t,e)=>({tableName:t,columns:e}),l=t=>t;export{a as column,l as defineConfig,n as defineTable};
package/dist/main.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as y,b as h}from"./chunk-EY62Q3Z2.js";import{defineCommand as q,runMain as we}from"citty";import{Kysely as Y,MysqlDialect as G,PostgresDialect as W,SqliteDialect as H}from"kysely";import{Pool as I}from"pg";import{createPool as X}from"mysql2";import Z from"better-sqlite3";import{PostgresAdapter as V,PostgresDialect as J}from"kysely";var v=class extends V{async acquireMigrationLock(t,n){await t.selectFrom(n.lockTable).selectAll().forUpdate().execute()}},N=class extends J{createAdapter(){return new v}};import{DummyDriver as z}from"kysely";var D=class extends z{constructor(n){super();this.queries=n}async acquireConnection(){return new P(this.queries)}},P=class{constructor(t){this.queries=t}async executeQuery(t){let n=t.query.kind;if(n==="CreateTableNode"||n==="DropTableNode"||n==="AlterTableNode"){if(t.query.table.table.identifier.name.startsWith("kysely_migration"))return{rows:[]};this.queries.push(t)}return{rows:[]}}async*streamQuery(){}};var ee=e=>{switch(e.dialect){case"cockroachdb":return new N({pool:new I({connectionString:e.connectionString})});case"postgres":return new W({pool:new I({connectionString:e.connectionString})});case"mysql":return new G({pool:X(e.connectionString)});case"sqlite":return new H({database:new Z(e.connectionString)});default:throw new Error(`Unsupported dialect: ${e.dialect}`)}},S=e=>new E({databaseProps:e.database,options:e.options}),E=class{constructor(t){this.constructorProps=t;this.plannedQueries=[]}getDB(t){let n=ee(this.constructorProps.databaseProps),a=t?.plan===!0;return new Y({dialect:{createAdapter:()=>n.createAdapter(),createDriver:()=>a?new D(this.plannedQueries):n.createDriver(),createIntrospector:i=>n.createIntrospector(i),createQueryCompiler:()=>n.createQueryCompiler()}})}getPlannedQueries(){return this.plannedQueries}getDialect(){return this.constructorProps.databaseProps.dialect}};var O="0.5.0";import{z as c}from"zod";var ae=c.object({type:c.string(),primaryKey:c.boolean().optional().default(!1),notNull:c.boolean().optional().default(!1),unique:c.boolean().optional().default(!1),defaultSql:c.string().optional()}),oe=c.object({tableName:c.string(),columns:c.record(c.string(),ae)}),re=c.object({table:c.string(),columns:c.array(c.string()),unique:c.boolean().optional()}),ie=c.enum(["postgres","cockroachdb","mysql","sqlite"]),se=c.object({dialect:ie,connectionString:c.string()}),R=c.object({database:se,tables:c.array(oe),indexes:c.array(re).optional()}),j=c.object({id:c.string(),version:c.string(),diff:c.any()});import{Migrator as ge}from"kysely";import{isColumnDataType as le,sql as $}from"kysely";import{readdir as ce,readFile as me}from"fs/promises";import{join as pe}from"path";var w="migrations",M=async()=>{try{let t=(await ce(w)).filter(n=>n.endsWith(".json")).map(async n=>j.parse(JSON.parse(await me(pe(w,n),"utf-8"))));return await Promise.all(t)}catch(e){if(e instanceof Object&&"code"in e&&e.code==="ENOENT")return[];throw e}},Q=e=>({getMigrations:async()=>{let t=await M(),n={};return t.forEach(a=>{n[a.id]={up:async()=>{await ue(e.db,a.diff)}}}),n}});async function ue(e,t){for(let n of t.addedTables){let a=e.schema.createTable(n.table);for(let[i,s]of Object.entries(n.columns)){let l=s.type;k(l),a=a.addColumn(i,l,g=>{let o=g;return s.notNull&&(o=o.notNull()),s.primaryKey&&(o=o.primaryKey()),s.unique&&(o=o.unique()),s.defaultSql&&(o=o.defaultTo($.raw(s.defaultSql))),o})}await a.execute()}for(let n of t.removedTables)await e.schema.dropTable(n).execute();for(let n of t.changedTables){for(let a of n.addedColumns){let i=a.attributes.type;k(i),await e.schema.alterTable(n.table).addColumn(a.column,i,s=>{let l=s;return a.attributes.notNull&&(l=l.notNull()),a.attributes.primaryKey&&(l=l.primaryKey()),a.attributes.unique&&(l=l.unique()),a.attributes.defaultSql&&(l=l.defaultTo($.raw(a.attributes.defaultSql))),l}).execute()}for(let a of n.removedColumns)await e.schema.alterTable(n.table).dropColumn(a.column).execute();for(let a of n.changedColumns){if(a.before.type!==a.after.type){let i=a.after.type;k(i),await e.schema.alterTable(n.table).alterColumn(a.column,s=>s.setDataType(i)).execute()}a.after.notNull!==a.before.notNull&&(a.after.notNull?await e.schema.alterTable(n.table).alterColumn(a.column,i=>i.setNotNull()).execute():await e.schema.alterTable(n.table).alterColumn(a.column,i=>i.dropNotNull()).execute())}}}var k=e=>{if(!le(e))throw new Error(`Unsupported data type: ${e}`)};import{createConsola as de}from"consola";var d=de({stdout:process.stderr});var _=async e=>{var l=[];try{let t=y(l,e.client.getDB({plan:e.options.plan}),!0);let n=new ge({db:t,provider:Q({db:t,options:{plan:e.options.plan}})});let{results:a,error:i}=await n.migrateToLatest();let s=e.client.getPlannedQueries();if(s.length>0){s.forEach(r=>{console.log(r.sql)});return}a&&a.length>0?a.forEach(r=>{r.status==="Error"?d.error(`Migration failed: ${r.migrationName}`):r.status==="Success"&&d.success(`Migration applied: ${r.migrationName}`)}):d.info("No migrations to run");i&&(d.error(`Migration error: ${i}`),process.exit(1))}catch(g){var o=g,u=!0}finally{var f=h(l,o,u);f&&await f}};import{mkdir as ye,writeFile as he}from"fs/promises";function K(e){let{current:t,ideal:n}=e,a=t.map(o=>o.name),i=n.map(o=>o.name),s=n.filter(o=>!a.includes(o.name)).map(o=>({table:o.name,columns:o.columns})),l=t.filter(o=>!i.includes(o.name)).map(o=>o.name),g=t.reduce((o,u)=>{let f=n.find(m=>m.name===u.name);if(!f)return o;let r=u.columns,p=f.columns,b=Object.keys(r),T=Object.keys(p),x=T.filter(m=>!b.includes(m)).map(m=>({column:m,attributes:p[m]})),C=b.filter(m=>!T.includes(m)).map(m=>({column:m,attributes:r[m]})),A=b.filter(m=>T.includes(m)&&(r[m].type!==p[m].type||r[m].notNull!==p[m].notNull)).map(m=>({column:m,before:r[m],after:p[m]}));return(x.length>0||C.length>0||A.length>0)&&o.push({table:u.name,addedColumns:x,removedColumns:C,changedColumns:A}),o},[]);return{addedTables:s,removedTables:l,changedTables:g}}import{sql as fe}from"kysely";var B=e=>{let t=async()=>{var g=[];try{let i=e.client;let s=y(g,i.getDB(),!0);let{rows:l}=await fe`
1
+ import{a as y,b}from"./chunk-EY62Q3Z2.js";import{defineCommand as M,runMain as Pe}from"citty";import{Kysely as X,MysqlDialect as Z,PostgresDialect as ee,SqliteDialect as te}from"kysely";import{Pool as R}from"pg";import{createPool as ae}from"mysql2";import ne from"better-sqlite3";import{PostgresAdapter as G,PostgresDialect as W}from"kysely";var P=class extends G{async acquireMigrationLock(n,t){await n.selectFrom(t.lockTable).selectAll().forUpdate().execute()}},x=class extends W{createAdapter(){return new P}};import{DummyDriver as H}from"kysely";var _=class extends H{constructor(t){super();this.queries=t}async acquireConnection(){return new E(this.queries)}},E=class{constructor(n){this.queries=n}async executeQuery(n){let t=n.query.kind;if(t==="CreateTableNode"||t==="DropTableNode"||t==="AlterTableNode"){if(n.query.table.table.identifier.name.startsWith("kysely_"))return{rows:[]};this.queries.push(n)}return{rows:[]}}async*streamQuery(){}};var re=e=>{switch(e.dialect){case"cockroachdb":return new x({pool:new R({connectionString:e.connectionString})});case"postgres":return new ee({pool:new R({connectionString:e.connectionString})});case"mysql":return new Z({pool:ae(e.connectionString)});case"sqlite":return new te({database:new ne(e.connectionString)});default:throw new Error(`Unsupported dialect: ${e.dialect}`)}},S=e=>new q({databaseProps:e.database,options:e.options}),q=class{constructor(n){this.constructorProps=n}getDB(n){let t=re(this.constructorProps.databaseProps);return new k({dialect:{createAdapter:()=>t.createAdapter(),createDriver:()=>t.createDriver(),createIntrospector:a=>t.createIntrospector(a),createQueryCompiler:()=>t.createQueryCompiler()}},{isPlan:n?.plan===!0})}getDialect(){return this.constructorProps.databaseProps.dialect}},k=class extends X{constructor(t,a){let r=[];super({dialect:{...t.dialect,createDriver:()=>a.isPlan?new _(r):t.dialect.createDriver()}});this.plannedQueries=[];this.plannedQueries=r}getPlannedQueries(){return this.plannedQueries}};var O="0.7.0";import{z as m}from"zod";var se=m.object({type:m.string(),primaryKey:m.boolean().optional().default(!1),notNull:m.boolean().optional().default(!1),unique:m.boolean().optional().default(!1),defaultSql:m.string().optional()}),le=m.object({tableName:m.string(),columns:m.record(m.string(),se)}),ce=m.object({table:m.string(),columns:m.array(m.string()),unique:m.boolean().optional()}),me=m.enum(["postgres","cockroachdb","mysql","sqlite"]),ue=m.object({dialect:me,connectionString:m.string()}),K=m.object({database:ue,tables:m.array(le),indexes:m.array(ce).optional()}),j=m.object({id:m.string(),version:m.string(),diff:m.any()});import{Migrator as be}from"kysely";import{DEFAULT_MIGRATION_TABLE as Q,isColumnDataType as pe,sql as B}from"kysely";import{readdir as de,readFile as ge}from"fs/promises";import{join as fe}from"path";var w="migrations",I=async()=>{try{let n=(await de(w)).filter(t=>t.endsWith(".json")).map(async t=>j.parse(JSON.parse(await ge(fe(w,t),"utf-8"))));return await Promise.all(n)}catch(e){if(e instanceof Object&&"code"in e&&e.code==="ENOENT")return[];throw e}},D=async e=>{var s=[];try{let n=y(s,e.getDB(),!0);let t=await I();let a=(await n.introspection.getTables({withInternalKyselyTables:!0})).map(g=>g.name);if(!a.includes(Q))return t;let r=await n.selectFrom(Q).select(["name","timestamp"]).$narrowType().execute();return t.filter(g=>!r.some(o=>o.name===g.id))}catch(u){var p=u,i=!0}finally{var d=b(s,p,i);d&&await d}},L=e=>({getMigrations:async()=>{let n=await e.migrationsResolver(),t={};return n.forEach(a=>{t[a.id]={up:async()=>{await ye(e.db,a.diff)}}}),t}});async function ye(e,n){for(let t of n.addedTables){let a=e.schema.createTable(t.table);for(let[r,s]of Object.entries(t.columns)){let u=s.type;$(u),a=a.addColumn(r,u,p=>{let i=p;return s.notNull&&(i=i.notNull()),s.defaultSql&&(i=i.defaultTo(B.raw(s.defaultSql))),i}),s.primaryKey&&(a=a.addPrimaryKeyConstraint(`${t.table}_${r}_primary_key`,[r])),s.unique&&(a=a.addUniqueConstraint(`${t.table}_${r}_unique`,[r]))}await a.execute()}for(let t of n.removedTables)await e.schema.dropTable(t).execute();for(let t of n.changedTables){for(let a of t.addedColumns){let r=a.attributes.type;$(r),await e.schema.alterTable(t.table).addColumn(a.column,r,s=>{let u=s;return a.attributes.notNull&&(u=u.notNull()),a.attributes.defaultSql&&(u=u.defaultTo(B.raw(a.attributes.defaultSql))),u}).execute(),a.attributes.primaryKey&&await e.schema.alterTable(t.table).addPrimaryKeyConstraint(`${t.table}_${a.column}_primary_key`,[a.column]).execute(),a.attributes.unique&&await e.schema.alterTable(t.table).addUniqueConstraint(`${t.table}_${a.column}_unique`,[a.column]).execute()}for(let a of t.removedColumns)await e.schema.alterTable(t.table).dropColumn(a.column).execute();for(let a of t.changedColumns){if(a.before.type!==a.after.type){let r=a.after.type;$(r),await e.schema.alterTable(t.table).alterColumn(a.column,s=>s.setDataType(r)).execute()}a.after.notNull!==a.before.notNull&&(a.after.notNull?await e.schema.alterTable(t.table).alterColumn(a.column,r=>r.setNotNull()).execute():await e.schema.alterTable(t.table).alterColumn(a.column,r=>r.dropNotNull()).execute()),a.after.primaryKey!==a.before.primaryKey&&(a.after.primaryKey?await e.schema.alterTable(t.table).addPrimaryKeyConstraint(`${t.table}_${a.column}_primary_key`,[a.column]).execute():await e.schema.alterTable(t.table).dropConstraint(`${t.table}_${a.column}_primary_key`).execute()),a.after.unique!==a.before.unique&&(a.after.unique?await e.schema.alterTable(t.table).addUniqueConstraint(`${t.table}_${a.column}_unique`,[a.column]).execute():await e.schema.alterTable(t.table).dropConstraint(`${t.table}_${a.column}_unique`).execute())}}}var $=e=>{if(!pe(e))throw new Error(`Unsupported data type: ${e}`)};import{format as he}from"sql-formatter";var N=async e=>{var p=[];try{let{reporter:n}=e.logger;let t=y(p,e.client.getDB({plan:e.options.plan}),!0);let a=new be({db:t,provider:L({db:t,migrationsResolver:async()=>e.options.plan?await D(e.client):await I(),options:{plan:e.options.plan}})});let{results:r,error:s}=await a.migrateToLatest();let u=t.getPlannedQueries();if(u.length>0){u.forEach(l=>{e.logger.stdout(e.options.pretty?he(l.sql):l.sql)});return}r&&r.length>0?r.forEach(l=>{l.status==="Error"?n.error(`Migration failed: ${l.migrationName}`):l.status==="Success"&&n.success(`Migration applied: ${l.migrationName}`)}):n.info("No migrations to run");s&&(n.error(`Migration error: ${s}`),process.exit(1))}catch(i){var d=i,g=!0}finally{var o=b(p,d,g);o&&await o}};import{createConsola as Ce}from"consola";var Te=Ce({stdout:process.stderr}),U={stdout:e=>console.log(e),reporter:{...Te}};import{mkdir as _e,writeFile as De}from"fs/promises";function z(e){let{current:n,ideal:t}=e,a=n.map(i=>i.name),r=t.map(i=>i.name),s=t.filter(i=>!a.includes(i.name)).map(i=>({table:i.name,columns:i.columns})),u=n.filter(i=>!r.includes(i.name)).map(i=>i.name),p=n.reduce((i,d)=>{let g=t.find(c=>c.name===d.name);if(!g)return i;let o=d.columns,l=g.columns,f=Object.keys(o),C=Object.keys(l),T=C.filter(c=>!f.includes(c)).map(c=>({column:c,attributes:l[c]})),h=f.filter(c=>!C.includes(c)).map(c=>({column:c,attributes:o[c]})),A=f.filter(c=>C.includes(c)&&(o[c].type!==l[c].type||o[c].notNull!==l[c].notNull||o[c].primaryKey!==l[c].primaryKey||o[c].unique!==l[c].unique)).map(c=>({column:c,before:o[c],after:l[c]}));return(T.length>0||h.length>0||A.length>0)&&i.push({table:d.name,addedColumns:T,removedColumns:h,changedColumns:A}),i},[]);return{addedTables:s,removedTables:u,changedTables:p}}import{sql as we}from"kysely";var F=e=>{let n=async()=>{var p=[];try{let r=e.client;let s=y(p,r.getDB(),!0);let{rows:u}=await we`
2
2
  SELECT
3
3
  c.table_schema,
4
4
  c.table_name,
@@ -18,7 +18,8 @@ import{a as y,b as h}from"./chunk-EY62Q3Z2.js";import{defineCommand as q,runMain
18
18
  AND tc.constraint_type IN ('UNIQUE', 'PRIMARY KEY')
19
19
  WHERE c.table_schema = 'public'
20
20
  ORDER BY c.table_name, c.ordinal_position;
21
- `.$castTo().execute(s);return l.map(p=>({schema:p.table_schema,table:p.table_name,name:p.column_name,default:p.column_default,characterMaximumLength:p.character_maximum_length,constraint:{name:p.constraint_name,type:p.constraint_type}}))}catch(o){var u=o,f=!0}finally{var r=h(g,u,f);r&&await r}},n={bool:"boolean",int2:"smallint",int4:"integer",int8:"bigint"};return{introspect:t,convertTypeName:i=>n[i]??i}};var be=e=>{let t=e.getDialect();switch(t){case"postgres":case"cockroachdb":return B({client:e});default:throw new Error(`Unsupported dialect: ${t}`)}},F=e=>{let t=be(e);return{getTables:async()=>{var l=[];try{let a=y(l,e.getDB(),!0);let i=await a.introspection.getTables();let s=await t.introspect();return i.map(r=>{let p=Object.fromEntries(r.columns.map(b=>{let T=s.filter(C=>C.table===r.name&&C.name===b.name),x=T[0]||{};return[b.name,{schema:r.schema,table:r.name,name:b.name,dataType:t.convertTypeName(b.dataType),default:x.default??null,characterMaximumLength:x.characterMaximumLength??null,notNull:!b.isNullable,constraints:T.map(C=>C.constraint)}]}));return{schema:r.schema,name:r.name,columns:p}})}catch(g){var o=g,u=!0}finally{var f=h(l,o,u);f&&await f}}}};var L=async e=>{var s=[];try{let t=y(s,e.client.getDB(),!0);let n=e.config;if(!e.options.ignorePending){let f=await Ce(t);if(f.length>0){d.warn([`There are pending migrations: ${f.map(r=>r.id).join(", ")}`,"Please apply them first before generating a new migration.","Otherwise, use --ignore-pending to skip this check."].join(`
22
- `));return}}let a=await Te({client:e.client,config:n});if(!a){d.info("No changes detected, no migration needed.");return}xe(a.diff);let i=`${w}/${a.id}.json`;await ye(w,{recursive:!0});await he(i,JSON.stringify(a,null,2));d.success(`Migration file generated: ${i}`);e.options.apply&&await _({client:e.client,options:{plan:e.options.plan}})}catch(l){var g=l,o=!0}finally{var u=h(s,g,o);u&&await u}},Ce=async e=>{let t=await e.selectFrom("kysely_migration").select(["name","timestamp"]).$narrowType().execute().catch(()=>[]);return t.length===0?[]:(await M()).filter(i=>!t.some(s=>s.name===i.id))},Te=async e=>{let{client:t,config:n}=e,s=(await F(t).getTables()).map(u=>({name:u.name,columns:Object.fromEntries(Object.entries(u.columns).map(([f,r])=>[f,{type:r.dataType,notNull:r.notNull,primaryKey:!!r.constraints.find(p=>p.type==="PRIMARY KEY"),unique:!!r.constraints.find(p=>p.type==="UNIQUE"),defaultSql:r.default??void 0}]))})),l=n.tables.map(u=>({name:u.tableName,columns:Object.fromEntries(Object.entries(u.columns).map(([f,r])=>[f,{...r,notNull:r.primaryKey||r.notNull}]))})),g=K({current:s,ideal:l});return g.addedTables.length===0&&g.removedTables.length===0&&g.changedTables.length===0?null:{version:"1",id:Date.now()+"",diff:g}},xe=e=>{e.addedTables.length>0&&e.addedTables.forEach(t=>{d.log(`-- create_table: ${t.table}`),Object.entries(t.columns).forEach(([n,a])=>{d.log(` -> column: ${n} (${JSON.stringify(a)})`)})}),e.removedTables.length>0&&e.removedTables.forEach(t=>{d.log(`-- remove_table: ${t}`)}),e.changedTables.length>0&&e.changedTables.forEach(t=>{t.addedColumns.forEach(n=>{d.log([`-- add_column: ${t.table}.${n.column}`,` -> to: ${JSON.stringify(n.attributes)}`].join(`
23
- `))}),t.removedColumns.forEach(n=>{d.log(`-- remove_column: ${t.table}.${n.column})`)}),t.changedColumns.forEach(n=>{d.log([`-- change_column: ${t.table}.${n.column}`,` -> from: ${JSON.stringify(n.before)}`,` -> to: ${JSON.stringify(n.after)}`].join(`
24
- `))})})};import{loadConfig as Ne}from"c12";var U=async()=>{let e=await Ne({name:"kyrage"});return R.parse(e.config)},De=q({meta:{name:"generate",description:"Generate migration files based on the current schema"},args:{apply:{type:"boolean",description:"Apply the migration after generating it",default:!1},plan:{type:"boolean",description:"Plan the migration without applying it (only for --apply)",default:!1},"ignore-pending":{type:"boolean",description:"Ignore pending migrations and generate a new one",default:!1}},run:async e=>{try{let t=await U(),n=S({database:t.database});await L({client:n,config:t,options:{ignorePending:e.args["ignore-pending"],apply:e.args.apply,plan:e.args.plan}})}catch(t){d.error(t),process.exit(1)}}}),_e=q({meta:{name:"apply",description:"Run migrations to sync database schema"},args:{plan:{name:"plan",type:"boolean",description:"Plan the migration without applying it",default:!1}},run:async e=>{try{let t=await U(),n=S({database:t.database});await _({client:n,options:{plan:e.args.plan}})}catch(t){d.error(t),process.exit(1)}}}),ve=q({meta:{name:"kyrage",version:O,description:"Kysely migration CLI with declarative schema"},subCommands:{apply:_e,generate:De}});we(ve);
21
+ `.$castTo().execute(s);return u.map(l=>({schema:l.table_schema,table:l.table_name,name:l.column_name,default:l.column_default,characterMaximumLength:l.character_maximum_length,constraint:{name:l.constraint_name,type:l.constraint_type}}))}catch(i){var d=i,g=!0}finally{var o=b(p,d,g);o&&await o}},t={bool:"boolean",int2:"smallint",int4:"integer",int8:"bigint"};return{introspect:n,convertTypeName:r=>t[r]??r}};var xe=e=>{let n=e.getDialect();switch(n){case"postgres":case"cockroachdb":return F({client:e});default:throw new Error(`Unsupported dialect: ${n}`)}},V=e=>{let n=xe(e);return{getTables:async()=>{var u=[];try{let a=y(u,e.getDB(),!0);let r=await a.introspection.getTables();let s=await n.introspect();return r.map(o=>{let l=Object.fromEntries(o.columns.map(f=>{let C=s.filter(h=>h.table===o.name&&h.name===f.name),T=C[0]||{};return[f.name,{schema:o.schema,table:o.name,name:f.name,dataType:n.convertTypeName(f.dataType),default:T.default??null,characterMaximumLength:T.characterMaximumLength??null,notNull:!f.isNullable,constraints:C.map(h=>h.constraint)}]}));return{schema:o.schema,name:o.name,columns:l}})}catch(p){var i=p,d=!0}finally{var g=b(u,i,d);g&&await g}}}};var J=async e=>{let{reporter:n}=e.logger,t=e.config;if(!e.options.ignorePending){let s=await D(e.client);if(s.length>0){n.warn([`There are pending migrations: ${s.map(u=>u.id).join(", ")}`,"Please apply them first before generating a new migration.","Otherwise, use --ignore-pending to skip this check."].join(`
22
+ `));return}}let a=await Ne({client:e.client,config:t});if(!a){n.info("No changes detected, no migration needed.");return}ve(e.logger,a.diff);let r=`${w}/${a.id}.json`;await _e(w,{recursive:!0}),await De(r,JSON.stringify(a,null,2)),n.success(`Migration file generated: ${r}`),e.options.apply&&await N({client:e.client,logger:e.logger,options:{plan:e.options.plan,pretty:!1}})},Ne=async e=>{let{client:n,config:t}=e,s=(await V(n).getTables()).map(d=>({name:d.name,columns:Object.fromEntries(Object.entries(d.columns).map(([g,o])=>[g,{type:o.dataType,notNull:o.notNull,primaryKey:!!o.constraints.find(l=>l.type==="PRIMARY KEY"),unique:!!o.constraints.find(l=>l.type==="UNIQUE"),defaultSql:o.default??void 0}]))})),u=t.tables.map(d=>({name:d.tableName,columns:Object.fromEntries(Object.entries(d.columns).map(([g,o])=>[g,{...o,notNull:o.primaryKey||o.notNull}]))})),p=z({current:s,ideal:u});return p.addedTables.length===0&&p.removedTables.length===0&&p.changedTables.length===0?null:{version:"1",id:Date.now()+"",diff:p}},ve=(e,n)=>{let t=[];n.addedTables.length>0&&n.addedTables.forEach(a=>{t.push(`-- create_table: ${a.table}`),Object.entries(a.columns).forEach(([r,s])=>{t.push(` -> column: ${r} (${JSON.stringify(s)})`)})}),n.removedTables.length>0&&n.removedTables.forEach(a=>{t.push(`-- remove_table: ${a}`)}),n.changedTables.length>0&&n.changedTables.forEach(a=>{a.addedColumns.forEach(r=>{t.push([`-- add_column: ${a.table}.${r.column}`,` -> to: ${JSON.stringify(r.attributes)}`].join(`
23
+ `))}),a.removedColumns.forEach(r=>{t.push(`-- remove_column: ${a.table}.${r.column}`)}),a.changedColumns.forEach(r=>{t.push([`-- change_column: ${a.table}.${r.column}`,` -> from: ${JSON.stringify(r.before)}`,` -> to: ${JSON.stringify(r.after)}`].join(`
24
+ `))})}),e.reporter.log(t.join(`
25
+ `))};import{loadConfig as Ee}from"c12";var Y=async()=>{let e=await Ee({name:"kyrage"});return K.parse(e.config)},v=U,qe=M({meta:{name:"generate",description:"Generate migration files based on the current schema"},args:{apply:{type:"boolean",description:"Apply the migration after generating it",default:!1},plan:{type:"boolean",description:"Plan the migration without applying it (only for --apply)",default:!1},"ignore-pending":{type:"boolean",description:"Ignore pending migrations and generate a new one",default:!1}},run:async e=>{try{let n=await Y(),t=S({database:n.database});await J({client:t,logger:v,config:n,options:{ignorePending:e.args["ignore-pending"],apply:e.args.apply,plan:e.args.plan}})}catch(n){v.reporter.error(n),process.exit(1)}}}),ke=M({meta:{name:"apply",description:"Run migrations to sync database schema"},args:{plan:{type:"boolean",description:"Plan the migration without applying it",default:!1},pretty:{type:"boolean",description:"Pretty print the migration SQL (only for --plan)",default:!1}},run:async e=>{try{let n=await Y(),t=S({database:n.database});await N({client:t,logger:v,options:{plan:e.args.plan,pretty:e.args.pretty}})}catch(n){v.reporter.error(n),process.exit(1)}}}),Se=M({meta:{name:"kyrage",version:O,description:"Kysely migration CLI with declarative schema"},subCommands:{apply:ke,generate:qe}});Pe(Se);
package/package.json CHANGED
@@ -2,8 +2,21 @@
2
2
  "name": "@izumisy/kyrage",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "0.5.0",
5
+ "version": "0.7.0",
6
6
  "description": "A minimal, schema-based declarative migration tool for Node.js ecosystem",
7
+ "author": "Seiya Izumi (https://github.com/IzumiSy)",
8
+ "license": "MIT",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/IzumiSy/kyrage.git"
12
+ },
13
+ "homepage": "https://github.com/IzumiSy/kyrage",
14
+ "keywords": [
15
+ "migration",
16
+ "database",
17
+ "schema",
18
+ "kysely"
19
+ ],
7
20
  "files": [
8
21
  "dist"
9
22
  ],
@@ -25,6 +38,7 @@
25
38
  "kysely-codegen": "^0.18.5",
26
39
  "mysql2": "^3.14.3",
27
40
  "pg": "^8.16.3",
41
+ "sql-formatter": "^15.6.6",
28
42
  "zod": "^4.0.17"
29
43
  },
30
44
  "devDependencies": {