@izumisy/kyrage 1.0.0 → 1.2.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.
@@ -0,0 +1 @@
1
+ import{createConsola as r}from"consola";var s=r({stdout:process.stderr}),e={stdout:o=>console.log(o),reporter:{...s}},g={stdout:()=>{},reporter:{info:()=>{},warn:()=>{},success:()=>{},log:()=>{},error:()=>{}}};export{e as a,g as b};
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ type DatabaseValue = z.infer<typeof databaseSchema>;
29
29
  declare const devDatabaseSchema: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
30
30
  container: z.ZodObject<{
31
31
  image: z.ZodString;
32
+ name: z.ZodOptional<z.ZodString>;
32
33
  }, z.core.$strip>;
33
34
  }, z.core.$strip>, z.ZodObject<{
34
35
  connectionString: z.ZodString;
@@ -149,10 +150,10 @@ tableExpBuilder?: (builder: ExpressionBuilders<T>) => ReadonlyArray<ReturnType<E
149
150
  foreignKeys: DefinedForeignKeyConstraint[];
150
151
  };
151
152
  type DefinedTable = ReturnType<typeof defineTable> & {
152
- indexes: DefinedIndex[];
153
- primaryKeys: DefinedPrimaryKeyConstraint[];
154
- uniques: DefinedUniqueConstraint[];
155
- foreignKeys: DefinedForeignKeyConstraint[];
153
+ indexes: ReadonlyArray<DefinedIndex>;
154
+ primaryKeys: ReadonlyArray<DefinedPrimaryKeyConstraint>;
155
+ uniques: ReadonlyArray<DefinedUniqueConstraint>;
156
+ foreignKeys: ReadonlyArray<DefinedForeignKeyConstraint>;
156
157
  };
157
158
  type DefinedTables = ReadonlyArray<DefinedTable>;
158
159
  type DefineConfigProp = {
@@ -164,6 +165,7 @@ declare const defineConfig: (config: DefineConfigProp) => {
164
165
  readonly dev: {
165
166
  container: {
166
167
  image: string;
168
+ name?: string | undefined;
167
169
  };
168
170
  } | {
169
171
  connectionString: string;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import"./chunk-EY62Q3Z2.js";var f=(t,r)=>r.length===1?`${t}_${r[0]}_primary_key`:`pk_${t}_${r.join("_")}`,c=(t,r)=>r.length===1?`${t}_${r[0]}_unique`:`uq_${t}_${r.join("_")}`,p=(t,r)=>`idx_${t}_${r.join("_")}`,g=(t,r)=>`fk_${t}_${r.join("_")}`,l={primaryKey:f,unique:c,index:p,foreignKey:g};var D=(t,r)=>({type:t,notNull:r?.notNull,primaryKey:r?.primaryKey,unique:r?.unique,defaultSql:r?.defaultSql}),K=(t,r,y)=>{let a=e=>{if(e.length===0)throw new Error("At least one column must be specified.")},u=(e,n)=>`${e}_${t}_${n.join("_")}`,i=y?y({index:(e,n)=>(a(e),{kind:"index",name:n?.name??u("idx",e),columns:e,unique:n?.unique??!1}),primaryKey:(e,n)=>(a(e),{kind:"primaryKey",name:n?.name??u("pk",e),columns:e}),unique:(e,n)=>(a(e),{kind:"unique",name:n?.name??u("uq",e),columns:e}),reference:(e,n,m,o)=>{let s=Array.isArray(e)?e:[e],d=Array.isArray(m)?m:[m];return a(s),a(d),{kind:"foreignKey",name:o?.name??l.foreignKey(t,s),columns:s,referencedTable:n.tableName,referencedColumns:d,onDelete:o?.onDelete,onUpdate:o?.onUpdate}}}):[];return{tableName:t,columns:r,indexes:i.filter(e=>e.kind==="index"),primaryKeys:i.filter(e=>e.kind==="primaryKey"),uniques:i.filter(e=>e.kind==="unique"),foreignKeys:i.filter(e=>e.kind==="foreignKey")}},q=t=>{let r=new Map,y=new Map,a=new Map,u=new Map;for(let i of t.tables){let e=i.tableName;for(let n of i.indexes??[])r.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns,unique:n.unique});for(let n of i.primaryKeys??[])y.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns});for(let n of i.uniques??[])a.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns});for(let n of i.foreignKeys??[])u.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns,referencedTable:n.referencedTable,referencedColumns:n.referencedColumns,onDelete:n.onDelete,onUpdate:n.onUpdate});for(let[n,m]of Object.entries(i.columns)){if(m.primaryKey){let o=l.primaryKey(e,[n]),s=`${e}:${o}`;y.has(s)||y.set(s,{table:e,name:o,columns:[n]})}if(m.unique){let o=l.unique(e,[n]),s=`${e}:${o}`;a.has(s)||a.set(s,{table:e,name:o,columns:[n]})}}}return{...t,dev:t.dev,indexes:Array.from(r.values()),primaryKeyConstraints:Array.from(y.values()),uniqueConstraints:Array.from(a.values()),foreignKeyConstraints:Array.from(u.values())}};export{D as column,q as defineConfig,K as defineTable};
1
+ import"./chunk-EY62Q3Z2.js";var f=(t,r)=>r.length===1?`${t}_${r[0]}_primary_key`:`pk_${t}_${r.join("_")}`,c=(t,r)=>r.length===1?`${t}_${r[0]}_unique`:`uq_${t}_${r.join("_")}`,p=(t,r)=>`idx_${t}_${r.join("_")}`,g=(t,r)=>`fk_${t}_${r.join("_")}`,m={primaryKey:f,unique:c,index:p,foreignKey:g};var D=(t,r)=>({type:t,notNull:r?.notNull,primaryKey:r?.primaryKey,unique:r?.unique,defaultSql:r?.defaultSql}),K=(t,r,y)=>{let i=e=>{if(e.length===0)throw new Error("At least one column must be specified.")},l=(e,n)=>`${e}_${t}_${n.join("_")}`,a=y?y({index:(e,n)=>(i(e),{kind:"index",name:n?.name??l("idx",e),columns:e,unique:n?.unique??!1}),primaryKey:(e,n)=>(i(e),{kind:"primaryKey",name:n?.name??l("pk",e),columns:e}),unique:(e,n)=>(i(e),{kind:"unique",name:n?.name??l("uq",e),columns:e}),reference:(e,n,u,o)=>{let s=Array.isArray(e)?e:[e],d=Array.isArray(u)?u:[u];return i(s),i(d),{kind:"foreignKey",name:o?.name??m.foreignKey(t,s),columns:s,referencedTable:n.tableName,referencedColumns:d,onDelete:o?.onDelete,onUpdate:o?.onUpdate}}}):[];return{tableName:t,columns:r,indexes:a.filter(e=>e.kind==="index"),primaryKeys:a.filter(e=>e.kind==="primaryKey"),uniques:a.filter(e=>e.kind==="unique"),foreignKeys:a.filter(e=>e.kind==="foreignKey")}},R=t=>{let r=new Map,y=new Map,i=new Map,l=new Map;for(let a of t.tables){let e=a.tableName;for(let n of a.indexes??[])r.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns,unique:n.unique});for(let n of a.primaryKeys??[])y.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns});for(let n of a.uniques??[])i.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns});for(let n of a.foreignKeys??[])l.set(`${e}:${n.name}`,{table:e,name:n.name,columns:n.columns,referencedTable:n.referencedTable,referencedColumns:n.referencedColumns,onDelete:n.onDelete,onUpdate:n.onUpdate});for(let[n,u]of Object.entries(a.columns)){if(u.primaryKey){let o=m.primaryKey(e,[n]),s=`${e}:${o}`;y.has(s)||y.set(s,{table:e,name:o,columns:[n]})}if(u.unique){let o=m.unique(e,[n]),s=`${e}:${o}`;i.has(s)||i.set(s,{table:e,name:o,columns:[n]})}}}return{...t,dev:t.dev,indexes:Array.from(r.values()),primaryKeyConstraints:Array.from(y.values()),uniqueConstraints:Array.from(i.values()),foreignKeyConstraints:Array.from(l.values())}};export{D as column,R as defineConfig,K as defineTable};
@@ -0,0 +1 @@
1
+ import{a,b}from"./chunk-3M6BYRKC.js";import"./chunk-EY62Q3Z2.js";export{a as defaultConsolaLogger,b as nullLogger};
package/dist/main.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as C,b as x}from"./chunk-EY62Q3Z2.js";import{defineCommand as z,runMain as Et}from"citty";import{Kysely as fe,MysqlDialect as be,PostgresDialect as he,SqliteDialect as _e}from"kysely";import{Pool as J}from"pg";import{createPool as Ce}from"mysql2";import xe from"better-sqlite3";import{PostgresAdapter as de,PostgresDialect as ye}from"kysely";var q=class extends de{async acquireMigrationLock(t,n){await t.selectFrom(n.lockTable).selectAll().forUpdate().execute()}},K=class extends ye{createAdapter(){return new q}};import{DummyDriver as ge}from"kysely";var A=class extends ge{constructor(n){super();this.queries=n}async acquireConnection(){return new k(this.queries)}},k=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_"))return{rows:[]};this.queries.push(t)}else(n==="CreateIndexNode"||n==="DropIndexNode")&&this.queries.push(t);return{rows:[]}}async*streamQuery(){}};var Ee=e=>{switch(e.dialect){case"cockroachdb":return new K({pool:new J({connectionString:e.connectionString})});case"postgres":return new he({pool:new J({connectionString:e.connectionString})});case"mysql":return new be({pool:Ce(e.connectionString)});case"sqlite":return new _e({database:new xe(e.connectionString)});default:throw new Error(`Unsupported dialect: ${e.dialect}`)}},D=e=>new I({databaseProps:e.database,options:e.options}),I=class{constructor(t){this.constructorProps=t}getDB(t){let n=Ee(this.constructorProps.databaseProps);return new $({dialect:{createAdapter:()=>n.createAdapter(),createDriver:()=>n.createDriver(),createIntrospector:a=>n.createIntrospector(a),createQueryCompiler:()=>n.createQueryCompiler()}},{isPlan:t?.plan===!0})}getDialect(){return this.constructorProps.databaseProps.dialect}},$=class extends fe{constructor(n,a){let o=[];super({dialect:{...n.dialect,createDriver:()=>a.isPlan?new A(o):n.dialect.createDriver()}});this.plannedQueries=[];this.plannedQueries=o}getPlannedQueries(){return this.plannedQueries}};var Y="1.0.0";import{Migrator as Qe}from"kysely";import{DEFAULT_MIGRATION_TABLE as Z,isColumnDataType as Se,sql as ne}from"kysely";import{readdir as Te,readFile as Oe}from"fs/promises";import{join as we}from"path";import T from"zod";import u from"zod";var S=u.object({type:u.string()}).catchall(u.any()),E=u.object({table:u.string(),name:u.string()}),j=u.object({table:u.string(),column:u.string()}),M=u.object({...E.shape,columns:u.array(u.string()).readonly()}),U=u.object({...E.shape,columns:u.array(u.string()).readonly()}),G=u.enum(["cascade","set null","set default","restrict","no action"]),L=u.object({...E.shape,columns:u.array(u.string()).readonly(),referencedTable:u.string(),referencedColumns:u.array(u.string()).readonly(),onDelete:G.optional(),onUpdate:G.optional()}),X=u.discriminatedUnion("type",[u.object({type:u.literal("create_table"),table:u.string(),columns:u.record(u.string(),S)}),u.object({type:u.literal("drop_table"),table:u.string()}),u.object({...j.shape,type:u.literal("add_column"),attributes:S}),u.object({...j.shape,type:u.literal("drop_column"),attributes:S}),u.object({...j.shape,type:u.literal("alter_column"),before:S,after:S}),u.object({...E.shape,type:u.literal("create_index"),columns:u.array(u.string()).readonly(),unique:u.boolean()}),u.object({...E.shape,type:u.literal("drop_index")}),u.object({...M.shape,type:u.literal("create_primary_key_constraint")}),u.object({...E.shape,type:u.literal("drop_primary_key_constraint")}),u.object({...U.shape,type:u.literal("create_unique_constraint")}),u.object({...E.shape,type:u.literal("drop_unique_constraint")}),u.object({...L.shape,type:u.literal("create_foreign_key_constraint")}),u.object({...E.shape,type:u.literal("drop_foreign_key_constraint")})]),f={createTable:(e,t)=>({type:"create_table",table:e,columns:t}),dropTable:e=>({type:"drop_table",table:e}),addColumn:(e,t)=>({...e,type:"add_column",attributes:t}),dropColumn:(e,t)=>({...e,type:"drop_column",attributes:t}),alterColumn:(e,t,n)=>({...e,type:"alter_column",before:t,after:n}),createIndex:e=>({...e,type:"create_index"}),dropIndex:e=>({...e,type:"drop_index"}),createPrimaryKeyConstraint:e=>({...e,type:"create_primary_key_constraint"}),dropPrimaryKeyConstraint:e=>({...e,type:"drop_primary_key_constraint"}),createUniqueConstraint:e=>({...e,type:"create_unique_constraint"}),dropUniqueConstraint:e=>({...e,type:"drop_unique_constraint"}),createForeignKeyConstraint:(e,t)=>({...e,...t,type:"create_foreign_key_constraint"}),dropForeignKeyConstraint:e=>({...e,type:"drop_foreign_key_constraint"})};var O="migrations",Ke=T.object({operations:T.array(X).readonly()}),Ae=T.object({id:T.string(),version:T.string(),diff:Ke}),F=async()=>{try{let t=(await Te(O)).filter(n=>n.endsWith(".json")).map(async n=>Ae.parse(JSON.parse(await Oe(we(O,n),"utf-8"))));return await Promise.all(t)}catch(e){if(e instanceof Object&&"code"in e&&e.code==="ENOENT")return[];throw e}},v=async e=>{var m=[];try{let t=C(m,e.getDB(),!0);let n=await F();let a=(await t.introspection.getTables({withInternalKyselyTables:!0})).map(r=>r.name);if(!a.includes(Z))return n;let o=await t.selectFrom(Z).select(["name","timestamp"]).$narrowType().execute();return n.filter(r=>!o.some(p=>p.name===r.id))}catch(s){var i=s,c=!0}finally{var d=x(m,i,c);d&&await d}},ae=e=>({getMigrations:async()=>{let t=await e.migrationsResolver(),n={};return t.forEach(a=>{n[a.id]={up:async()=>{await ve(e.db,a.diff)}}}),n}});async function ve(e,t){let n=We(t.operations);for(let a of n)await Pe(e,a)}async function Pe(e,t){switch(t.type){case"create_table":return Re(e,t);case"drop_table":return qe(e,t);case"add_column":return ke(e,t);case"drop_column":return Ie(e,t);case"alter_column":return $e(e,t);case"create_index":return je(e,t);case"drop_index":return Me(e,t);case"create_primary_key_constraint":return Ue(e,t);case"drop_primary_key_constraint":return Le(e,t);case"create_unique_constraint":return Fe(e,t);case"drop_unique_constraint":return Be(e,t);case"create_foreign_key_constraint":return He(e,t);case"drop_foreign_key_constraint":return Ve(e,t);default:throw new Error(`Unknown operation type: ${t.type}`)}}async function Re(e,t){let n=e.schema.createTable(t.table);for(let[a,o]of Object.entries(t.columns)){let m=o.type;B(m),n=n.addColumn(a,m,s=>{let i=s;return o.notNull&&(i=i.notNull()),typeof o.defaultSql=="string"&&(i=i.defaultTo(ne.raw(o.defaultSql))),i})}await n.execute()}async function qe(e,t){await e.schema.dropTable(t.table).execute()}async function ke(e,t){let n=t.attributes.type;B(n),await e.schema.alterTable(t.table).addColumn(t.column,n,a=>{let o=a;return t.attributes.notNull&&(o=o.notNull()),typeof t.attributes.defaultSql=="string"&&(o=o.defaultTo(ne.raw(t.attributes.defaultSql))),o}).execute()}async function Ie(e,t){await e.schema.alterTable(t.table).dropColumn(t.column).execute()}async function $e(e,t){let{table:n,column:a,before:o,after:m}=t;if(o.type!==m.type){let s=m.type;B(s),await e.schema.alterTable(n).alterColumn(a,i=>i.setDataType(s)).execute()}m.notNull!==o.notNull&&(m.notNull?await e.schema.alterTable(n).alterColumn(a,s=>s.setNotNull()).execute():await e.schema.alterTable(n).alterColumn(a,s=>s.dropNotNull()).execute())}async function je(e,t){let n=e.schema.createIndex(t.name).on(t.table);for(let a of t.columns)n=n.column(a);t.unique&&(n=n.unique()),await n.execute()}async function Me(e,t){await e.schema.dropIndex(t.name).execute()}async function Ue(e,t){await e.schema.alterTable(t.table).addPrimaryKeyConstraint(t.name,t.columns).execute()}async function Le(e,t){await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}async function Fe(e,t){await e.schema.alterTable(t.table).addUniqueConstraint(t.name,t.columns).execute()}async function Be(e,t){await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}async function He(e,t){let n=e.schema.alterTable(t.table).addForeignKeyConstraint(t.name,t.columns,t.referencedTable,t.referencedColumns);t.onDelete&&(n=n.onDelete(t.onDelete)),t.onUpdate&&(n=n.onUpdate(t.onUpdate)),await n.execute()}async function Ve(e,t){await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}var B=e=>{if(!Se(e))throw new Error(`Unsupported data type: ${e}`)},ee={drop_foreign_key_constraint:0,drop_unique_constraint:1,drop_primary_key_constraint:2,drop_index:3,drop_column:4,drop_table:5,create_table:6,add_column:7,alter_column:8,create_index:9,create_primary_key_constraint:10,create_unique_constraint:11,create_foreign_key_constraint:12},We=e=>e.slice().sort((t,n)=>{let a=ee[t.type],o=ee[n.type];return a!==o?a-o:te(t).localeCompare(te(n))});function te(e){return e.table}import{format as ze}from"sql-formatter";var w=async e=>{var i=[];try{let{reporter:t}=e.logger;let n=C(i,e.client.getDB({plan:e.options.plan}),!0);let a=new Qe({db:n,provider:ae({db:n,migrationsResolver:async()=>e.options.plan?await v(e.client):await F(),options:{plan:e.options.plan}})});let{results:o,error:m}=await a.migrateToLatest();let s=n.getPlannedQueries();if(s.length>0){s.forEach(l=>{e.logger.stdout(e.options.pretty?ze(l.sql):l.sql)});return}o&&o.length>0?o.forEach(l=>{l.status==="Error"?t.error(`Migration failed: ${l.migrationName}`):l.status==="Success"&&t.success(`Migration applied: ${l.migrationName}`)}):t.info("No migrations to run");if(m)throw m instanceof Error?m:new Error(`Migration error: ${m}`)}catch(c){var d=c,r=!0}finally{var p=x(i,d,r);p&&await p}};import{createConsola as Je}from"consola";var Ye=Je({stdout:process.stderr}),re={stdout:e=>console.log(e),reporter:{...Ye}},oe={stdout:()=>{},reporter:{info:()=>{},warn:()=>{},success:()=>{},log:()=>{},error:()=>{}}};import{mkdir as lt,writeFile as mt}from"fs/promises";import*as y from"ramda";var N=()=>({added:(e,t,n)=>y.pipe(y.difference(t),y.map(n))(e),removed:(e,t,n)=>y.pipe(y.difference(e),y.map(n))(t),changed:(e,t,n,a)=>y.pipe(y.intersection(e),y.filter(n),y.map(a))(t)}),P=y.prop("name"),Ge=y.eqBy(e=>[e.type,e.notNull??!1,e.primaryKey??!1,e.unique??!1]);function Xe(e,t){let n=[],a=N(),o=e.columns,m=t.columns,s=Object.keys(o),i=Object.keys(m);return a.added(s,i,c=>({column:c,attributes:m[c]})).forEach(c=>{n.push(f.addColumn({table:e.name,column:c.column},c.attributes))}),a.removed(s,i,c=>({column:c,attributes:o[c]})).forEach(c=>{n.push(f.dropColumn({table:e.name,column:c.column},c.attributes))}),a.changed(s,i,c=>!Ge(o[c],m[c]),c=>({column:c,before:o[c],after:m[c]})).forEach(c=>{n.push(f.alterColumn({table:e.name,column:c.column},c.before,c.after))}),n}function Ze(e){let{current:t,ideal:n}=e,a=[],o=N(),m=y.map(P,t),s=y.map(P,n);return o.added(m,s,i=>n.find(d=>d.name===i)).forEach(i=>{a.push(f.createTable(i.name,i.columns))}),o.removed(m,s,y.identity).forEach(i=>{a.push(f.dropTable(i))}),y.filter(i=>n.some(c=>c.name===i.name))(t).forEach(i=>{let c=n.find(d=>d.name===i.name);a.push(...Xe(i,c))}),a}function et(e){let{current:t,ideal:n}=e,a=[],o=N(),m=r=>`${r.table}:${r.name}`,s=new Map(t.map(r=>[m(r),r])),i=new Map(n.map(r=>[m(r),r])),c=Array.from(s.keys()),d=Array.from(i.keys());return o.added(c,d,r=>i.get(r)).forEach(r=>{a.push(f.createIndex(r))}),o.removed(c,d,r=>{let p=s.get(r);return{table:p.table,name:p.name}}).forEach(r=>{a.push(f.dropIndex(r))}),o.changed(c,d,r=>{let p=s.get(r),l=i.get(r);return!y.equals(p.columns,l.columns)||p.unique!==l.unique},r=>{let p=s.get(r),l=i.get(r);return{current:p,ideal:l}}).forEach(({current:r,ideal:p})=>{a.push(f.dropIndex(r)),a.push(f.createIndex(p))}),a}function tt(e){let{current:t,ideal:n}=e,a=[],o=N(),m=r=>`${r.table}:${r.name}`,s=new Map(t.map(r=>[m(r),r])),i=new Map(n.map(r=>[m(r),r])),c=Array.from(s.keys()),d=Array.from(i.keys());return o.added(c,d,r=>i.get(r)).forEach(r=>{a.push(f.createPrimaryKeyConstraint(r))}),o.removed(c,d,r=>{let p=s.get(r);return{table:p.table,name:p.name}}).forEach(r=>{a.push(f.dropPrimaryKeyConstraint(r))}),o.changed(c,d,r=>{let p=s.get(r),l=i.get(r);return!y.equals(p.columns,l.columns)},r=>{let p=s.get(r),l=i.get(r);return{current:p,ideal:l}}).forEach(({current:r,ideal:p})=>{a.push(f.dropPrimaryKeyConstraint(r)),a.push(f.createPrimaryKeyConstraint(p))}),a}function nt(e){let{current:t,ideal:n}=e,a=[],o=N(),m=r=>`${r.table}:${r.name}`,s=new Map(t.map(r=>[m(r),r])),i=new Map(n.map(r=>[m(r),r])),c=Array.from(s.keys()),d=Array.from(i.keys());return o.added(c,d,r=>i.get(r)).forEach(r=>{a.push(f.createUniqueConstraint(r))}),o.removed(c,d,r=>{let p=s.get(r);return{table:p.table,name:p.name}}).forEach(r=>{a.push(f.dropUniqueConstraint(r))}),o.changed(c,d,r=>{let p=s.get(r),l=i.get(r);return!y.equals(p.columns,l.columns)},r=>{let p=s.get(r),l=i.get(r);return{current:p,ideal:l}}).forEach(({current:r,ideal:p})=>{a.push(f.dropUniqueConstraint(r)),a.push(f.createUniqueConstraint(p))}),a}function at(e){let t=[],n=N(),a=e.current.map(P),o=e.ideal.map(P);t.push(...n.added(a,o,s=>{let i=e.ideal.find(p=>p.name===s),{table:c,name:d,...r}=i;return f.createForeignKeyConstraint({table:c,name:d},r)})),t.push(...n.removed(a,o,s=>{let i=e.current.find(c=>c.name===s);return f.dropForeignKeyConstraint(i)}));let m=s=>{let i=e.current.find(d=>d.name===s),c=e.ideal.find(d=>d.name===s);return!i||!c?!1:!(y.equals(i.columns,c.columns)&&i.referencedTable===c.referencedTable&&y.equals(i.referencedColumns,c.referencedColumns)&&i.onDelete===c.onDelete&&i.onUpdate===c.onUpdate)};return t.push(...n.changed(a,o,m,s=>{let i=e.current.find(l=>l.name===s),c=e.ideal.find(l=>l.name===s),{table:d,name:r,...p}=c;return[f.dropForeignKeyConstraint(i),f.createForeignKeyConstraint({table:d,name:r},p)]}).flat()),t}function ie(e){let t=Ze({current:e.current.tables,ideal:e.ideal.tables}),n=et({current:e.current.indexes,ideal:e.ideal.indexes}),a=tt({current:e.current.primaryKeyConstraints,ideal:e.ideal.primaryKeyConstraints}),o=nt({current:e.current.uniqueConstraints,ideal:e.ideal.uniqueConstraints}),m=at({current:e.current.foreignKeyConstraints,ideal:e.ideal.foreignKeyConstraints});return{operations:[...t,...n,...a,...o,...m]}}import{sql as H}from"kysely";var rt={bool:"boolean",int2:"smallint",int4:"integer",int8:"bigint"},ot=e=>rt[e]??e,se=e=>({introspectTables:async()=>{var i=[];try{let o=e.client;let m=C(i,o.getDB(),!0);let{rows:s}=await H`
1
+ import{a as ie,b as L}from"./chunk-3M6BYRKC.js";import{a as _,b as x}from"./chunk-EY62Q3Z2.js";import{defineCommand as Vt,runMain as zt}from"citty";var se="1.2.0";import{defineCommand as pt}from"citty";import y from"zod";import{loadConfig as we}from"c12";import u from"zod";var T=u.object({type:u.string()}).catchall(u.any()),D=u.object({table:u.string(),name:u.string()}),B=u.object({table:u.string(),column:u.string()}),F=u.object({...D.shape,columns:u.array(u.string()).readonly()}),H=u.object({...D.shape,columns:u.array(u.string()).readonly()}),ce=u.enum(["cascade","set null","set default","restrict","no action"]),W=u.object({...D.shape,columns:u.array(u.string()).readonly(),referencedTable:u.string(),referencedColumns:u.array(u.string()).readonly(),onDelete:ce.optional(),onUpdate:ce.optional()}),le=u.discriminatedUnion("type",[u.object({type:u.literal("create_table"),table:u.string(),columns:u.record(u.string(),T)}),u.object({type:u.literal("drop_table"),table:u.string()}),u.object({...B.shape,type:u.literal("add_column"),attributes:T}),u.object({...B.shape,type:u.literal("drop_column"),attributes:T}),u.object({...B.shape,type:u.literal("alter_column"),before:T,after:T}),u.object({...D.shape,type:u.literal("create_index"),columns:u.array(u.string()).readonly(),unique:u.boolean()}),u.object({...D.shape,type:u.literal("drop_index")}),u.object({...F.shape,type:u.literal("create_primary_key_constraint")}),u.object({...D.shape,type:u.literal("drop_primary_key_constraint")}),u.object({...H.shape,type:u.literal("create_unique_constraint")}),u.object({...D.shape,type:u.literal("drop_unique_constraint")}),u.object({...W.shape,type:u.literal("create_foreign_key_constraint")}),u.object({...D.shape,type:u.literal("drop_foreign_key_constraint")})]),f={createTable:(e,t)=>({type:"create_table",table:e,columns:t}),dropTable:e=>({type:"drop_table",table:e}),addColumn:(e,t)=>({...e,type:"add_column",attributes:t}),dropColumn:(e,t)=>({...e,type:"drop_column",attributes:t}),alterColumn:(e,t,n)=>({...e,type:"alter_column",before:t,after:n}),createIndex:e=>({...e,type:"create_index"}),dropIndex:e=>({...e,type:"drop_index"}),createPrimaryKeyConstraint:e=>({...e,type:"create_primary_key_constraint"}),dropPrimaryKeyConstraint:e=>({...e,type:"drop_primary_key_constraint"}),createUniqueConstraint:e=>({...e,type:"create_unique_constraint"}),dropUniqueConstraint:e=>({...e,type:"drop_unique_constraint"}),createForeignKeyConstraint:(e,t)=>({...e,...t,type:"create_foreign_key_constraint"}),dropForeignKeyConstraint:e=>({...e,type:"drop_foreign_key_constraint"})};var ve=y.object({type:y.string(),primaryKey:y.boolean().optional().default(!1),notNull:y.boolean().optional().default(!1),unique:y.boolean().optional().default(!1),defaultSql:y.string().optional()}),Te=y.object({tableName:y.string(),columns:y.record(y.string(),ve)}),Oe=y.object({...D.shape,columns:y.array(y.string()).readonly(),unique:y.boolean().default(!1)}),Ae=y.enum(["postgres","cockroachdb","mysql","sqlite"]),Ke=y.object({dialect:Ae,connectionString:y.string()}),Re=y.union([y.object({container:y.object({image:y.string(),name:y.string().optional()})}),y.object({connectionString:y.string()})]).optional(),qe=y.object({database:Ke,dev:Re,tables:y.array(Te).readonly(),indexes:y.array(Oe).readonly(),primaryKeyConstraints:y.array(F).readonly(),uniqueConstraints:y.array(H).readonly(),foreignKeyConstraints:y.array(W).readonly()}),me=async()=>{let e=await we({name:"kyrage"});return qe.parse(e.config)};import{Kysely as $e,MysqlDialect as Me,PostgresDialect as je,SqliteDialect as Ue}from"kysely";import{Pool as ue}from"pg";import{createPool as Le}from"mysql2";import Be from"better-sqlite3";import{PostgresAdapter as Pe,PostgresDialect as Ie}from"kysely";var Q=class extends Pe{async acquireMigrationLock(t,n){await t.selectFrom(n.lockTable).selectAll().forUpdate().execute()}},P=class extends Ie{createAdapter(){return new Q}};import{DummyDriver as ke}from"kysely";var I=class extends ke{constructor(n){super();this.queries=n}async acquireConnection(){return new V(this.queries)}},V=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_"))return{rows:[]};this.queries.push(t)}else(n==="CreateIndexNode"||n==="DropIndexNode")&&this.queries.push(t);return{rows:[]}}async*streamQuery(){}};var Fe=e=>{switch(e.dialect){case"cockroachdb":return new P({pool:new ue({connectionString:e.connectionString})});case"postgres":return new je({pool:new ue({connectionString:e.connectionString})});case"mysql":return new Me({pool:Le(e.connectionString)});case"sqlite":return new Ue({database:new Be(e.connectionString)});default:throw new Error(`Unsupported dialect: ${e.dialect}`)}},k=e=>new z({databaseProps:e.database,options:e.options}),z=class{constructor(t){this.constructorProps=t}getDB(t){let n=Fe(this.constructorProps.databaseProps);return new J({dialect:{createAdapter:()=>n.createAdapter(),createDriver:()=>n.createDriver(),createIntrospector:a=>n.createIntrospector(a),createQueryCompiler:()=>n.createQueryCompiler()}},{isPlan:t?.plan===!0})}getDialect(){return this.constructorProps.databaseProps.dialect}},J=class extends $e{constructor(n,a){let o=[];super({dialect:{...n.dialect,createDriver:()=>a.isPlan?new I(o):n.dialect.createDriver()}});this.plannedQueries=[];this.plannedQueries=o}getPlannedQueries(){return this.plannedQueries}};async function S(){let e=await me();return{client:k({database:e.database}),logger:ie,config:e}}import{Migrator as dt}from"kysely";import{DEFAULT_MIGRATION_TABLE as pe,isColumnDataType as He,sql as ye}from"kysely";import{readdir as We,readFile as Qe}from"fs/promises";import{join as Ve}from"path";import O from"zod";var w="migrations",ze=O.object({operations:O.array(le).readonly()}),Je=O.object({id:O.string(),version:O.string(),diff:ze}),Y=async()=>{try{let t=(await We(w)).filter(n=>n.endsWith(".json")).map(async n=>Je.parse(JSON.parse(await Qe(Ve(w,n),"utf-8"))));return await Promise.all(t)}catch(e){if(e instanceof Object&&"code"in e&&e.code==="ENOENT")return[];throw e}},E=async e=>{var l=[];try{let t=_(l,e.getDB(),!0);let n=await Y();let a=(await t.introspection.getTables({withInternalKyselyTables:!0})).map(r=>r.name);if(!a.includes(pe))return n;let o=await t.selectFrom(pe).select(["name","timestamp"]).$narrowType().execute();return n.filter(r=>!o.some(p=>p.name===r.id))}catch(c){var i=c,s=!0}finally{var d=x(l,i,s);d&&await d}},ge=e=>({getMigrations:async()=>{let t=await e.migrationsResolver(),n={};return t.forEach(a=>{n[a.id]={up:async()=>{await Ye(e.db,a.diff)}}}),n}});async function Ye(e,t){let n=ut(t.operations);for(let a of n)await Ge(e,a)}async function Ge(e,t){switch(t.type){case"create_table":return Xe(e,t);case"drop_table":return Ze(e,t);case"add_column":return et(e,t);case"drop_column":return tt(e,t);case"alter_column":return nt(e,t);case"create_index":return at(e,t);case"drop_index":return rt(e,t);case"create_primary_key_constraint":return ot(e,t);case"drop_primary_key_constraint":return it(e,t);case"create_unique_constraint":return st(e,t);case"drop_unique_constraint":return ct(e,t);case"create_foreign_key_constraint":return lt(e,t);case"drop_foreign_key_constraint":return mt(e,t);default:throw new Error(`Unknown operation type: ${t.type}`)}}async function Xe(e,t){let n=e.schema.createTable(t.table);for(let[a,o]of Object.entries(t.columns)){let l=o.type;G(l),n=n.addColumn(a,l,c=>{let i=c;return o.notNull&&(i=i.notNull()),typeof o.defaultSql=="string"&&(i=i.defaultTo(ye.raw(o.defaultSql))),i})}await n.execute()}async function Ze(e,t){await e.schema.dropTable(t.table).execute()}async function et(e,t){let n=t.attributes.type;G(n),await e.schema.alterTable(t.table).addColumn(t.column,n,a=>{let o=a;return t.attributes.notNull&&(o=o.notNull()),typeof t.attributes.defaultSql=="string"&&(o=o.defaultTo(ye.raw(t.attributes.defaultSql))),o}).execute()}async function tt(e,t){await e.schema.alterTable(t.table).dropColumn(t.column).execute()}async function nt(e,t){let{table:n,column:a,before:o,after:l}=t;if(o.type!==l.type){let c=l.type;G(c),await e.schema.alterTable(n).alterColumn(a,i=>i.setDataType(c)).execute()}l.notNull!==o.notNull&&(l.notNull?await e.schema.alterTable(n).alterColumn(a,c=>c.setNotNull()).execute():await e.schema.alterTable(n).alterColumn(a,c=>c.dropNotNull()).execute())}async function at(e,t){let n=e.schema.createIndex(t.name).on(t.table);for(let a of t.columns)n=n.column(a);t.unique&&(n=n.unique()),await n.execute()}async function rt(e,t){await e.schema.dropIndex(t.name).execute()}async function ot(e,t){await e.schema.alterTable(t.table).addPrimaryKeyConstraint(t.name,t.columns).execute()}async function it(e,t){await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}async function st(e,t){await e.schema.alterTable(t.table).addUniqueConstraint(t.name,t.columns).execute()}async function ct(e,t){await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}async function lt(e,t){let n=e.schema.alterTable(t.table).addForeignKeyConstraint(t.name,t.columns,t.referencedTable,t.referencedColumns);t.onDelete&&(n=n.onDelete(t.onDelete)),t.onUpdate&&(n=n.onUpdate(t.onUpdate)),await n.execute()}async function mt(e,t){await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}var G=e=>{if(!He(e))throw new Error(`Unsupported data type: ${e}`)},de={drop_foreign_key_constraint:0,drop_unique_constraint:1,drop_primary_key_constraint:2,drop_index:3,drop_column:4,drop_table:5,create_table:6,add_column:7,alter_column:8,create_index:9,create_primary_key_constraint:10,create_unique_constraint:11,create_foreign_key_constraint:12},ut=e=>e.slice().sort((t,n)=>{let a=de[t.type],o=de[n.type];return a!==o?a-o:t.table.localeCompare(n.table)});import{format as yt}from"sql-formatter";async function A(e,t){var r=[];try{let{client:n,logger:a}=e;let{reporter:o}=a;let l=_(r,n.getDB({plan:t.plan}),!0);let c=new dt({db:l,provider:ge({db:l,migrationsResolver:async()=>t.plan?await E(n):await Y(),options:{plan:t.plan}})});let{results:i,error:s}=await c.migrateToLatest();let d=l.getPlannedQueries();if(d.length>0){d.forEach(b=>{a.stdout(t.pretty?yt(b.sql):b.sql)});return}i&&i.length>0?i.forEach(b=>{b.status==="Error"?o.error(`Migration failed: ${b.migrationName}`):b.status==="Success"&&o.success(`Migration applied: ${b.migrationName}`)}):o.info("No migrations to run");if(s)throw s instanceof Error?s:new Error(`Migration error: ${s}`)}catch(p){var m=p,h=!0}finally{var C=x(r,m,h);C&&await C}}var fe=pt({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 t=await S();await A(t,{plan:e.args.plan,pretty:e.args.pretty})}catch(t){let{defaultConsolaLogger:n}=await import("./logger-SE7G5AMI.js");n.reporter.error(t),process.exit(1)}}});import{defineCommand as At}from"citty";import{mkdir as Kt,writeFile as Rt,unlink as qt}from"fs/promises";import{join as Pt}from"path";import*as g from"ramda";var v=()=>({added:(e,t,n)=>g.pipe(g.difference(t),g.map(n))(e),removed:(e,t,n)=>g.pipe(g.difference(e),g.map(n))(t),changed:(e,t,n,a)=>g.pipe(g.intersection(e),g.filter(n),g.map(a))(t)}),$=g.prop("name"),gt=g.eqBy(e=>[e.type,e.notNull??!1,e.primaryKey??!1,e.unique??!1]);function ft(e,t){let n=[],a=v(),o=e.columns,l=t.columns,c=Object.keys(o),i=Object.keys(l);return a.added(c,i,s=>({column:s,attributes:l[s]})).forEach(s=>{n.push(f.addColumn({table:e.name,column:s.column},s.attributes))}),a.removed(c,i,s=>({column:s,attributes:o[s]})).forEach(s=>{n.push(f.dropColumn({table:e.name,column:s.column},s.attributes))}),a.changed(c,i,s=>!gt(o[s],l[s]),s=>({column:s,before:o[s],after:l[s]})).forEach(s=>{n.push(f.alterColumn({table:e.name,column:s.column},s.before,s.after))}),n}function bt(e){let{current:t,ideal:n}=e,a=[],o=v(),l=g.map($,t),c=g.map($,n);return o.added(l,c,i=>n.find(d=>d.name===i)).forEach(i=>{a.push(f.createTable(i.name,i.columns))}),o.removed(l,c,g.identity).forEach(i=>{a.push(f.dropTable(i))}),g.filter(i=>n.some(s=>s.name===i.name))(t).forEach(i=>{let s=n.find(d=>d.name===i.name);a.push(...ft(i,s))}),a}function Ct(e){let{current:t,ideal:n}=e,a=[],o=v(),l=r=>`${r.table}:${r.name}`,c=new Map(t.map(r=>[l(r),r])),i=new Map(n.map(r=>[l(r),r])),s=Array.from(c.keys()),d=Array.from(i.keys());return o.added(s,d,r=>i.get(r)).forEach(r=>{a.push(f.createIndex(r))}),o.removed(s,d,r=>{let p=c.get(r);return{table:p.table,name:p.name}}).forEach(r=>{a.push(f.dropIndex(r))}),o.changed(s,d,r=>{let p=c.get(r),m=i.get(r);return!g.equals(p.columns,m.columns)||p.unique!==m.unique},r=>{let p=c.get(r),m=i.get(r);return{current:p,ideal:m}}).forEach(({current:r,ideal:p})=>{a.push(f.dropIndex(r)),a.push(f.createIndex(p))}),a}function ht(e){let{current:t,ideal:n}=e,a=[],o=v(),l=r=>`${r.table}:${r.name}`,c=new Map(t.map(r=>[l(r),r])),i=new Map(n.map(r=>[l(r),r])),s=Array.from(c.keys()),d=Array.from(i.keys());return o.added(s,d,r=>i.get(r)).forEach(r=>{a.push(f.createPrimaryKeyConstraint(r))}),o.removed(s,d,r=>{let p=c.get(r);return{table:p.table,name:p.name}}).forEach(r=>{a.push(f.dropPrimaryKeyConstraint(r))}),o.changed(s,d,r=>{let p=c.get(r),m=i.get(r);return!g.equals(p.columns,m.columns)},r=>{let p=c.get(r),m=i.get(r);return{current:p,ideal:m}}).forEach(({current:r,ideal:p})=>{a.push(f.dropPrimaryKeyConstraint(r)),a.push(f.createPrimaryKeyConstraint(p))}),a}function _t(e){let{current:t,ideal:n}=e,a=[],o=v(),l=r=>`${r.table}:${r.name}`,c=new Map(t.map(r=>[l(r),r])),i=new Map(n.map(r=>[l(r),r])),s=Array.from(c.keys()),d=Array.from(i.keys());return o.added(s,d,r=>i.get(r)).forEach(r=>{a.push(f.createUniqueConstraint(r))}),o.removed(s,d,r=>{let p=c.get(r);return{table:p.table,name:p.name}}).forEach(r=>{a.push(f.dropUniqueConstraint(r))}),o.changed(s,d,r=>{let p=c.get(r),m=i.get(r);return!g.equals(p.columns,m.columns)},r=>{let p=c.get(r),m=i.get(r);return{current:p,ideal:m}}).forEach(({current:r,ideal:p})=>{a.push(f.dropUniqueConstraint(r)),a.push(f.createUniqueConstraint(p))}),a}function xt(e){let t=[],n=v(),a=e.current.map($),o=e.ideal.map($);t.push(...n.added(a,o,c=>{let i=e.ideal.find(p=>p.name===c),{table:s,name:d,...r}=i;return f.createForeignKeyConstraint({table:s,name:d},r)})),t.push(...n.removed(a,o,c=>{let i=e.current.find(s=>s.name===c);return f.dropForeignKeyConstraint(i)}));let l=c=>{let i=e.current.find(d=>d.name===c),s=e.ideal.find(d=>d.name===c);return!i||!s?!1:!(g.equals(i.columns,s.columns)&&i.referencedTable===s.referencedTable&&g.equals(i.referencedColumns,s.referencedColumns)&&i.onDelete===s.onDelete&&i.onUpdate===s.onUpdate)};return t.push(...n.changed(a,o,l,c=>{let i=e.current.find(m=>m.name===c),s=e.ideal.find(m=>m.name===c),{table:d,name:r,...p}=s;return[f.dropForeignKeyConstraint(i),f.createForeignKeyConstraint({table:d,name:r},p)]}).flat()),t}function be(e){let t=bt({current:e.current.tables,ideal:e.ideal.tables}),n=Ct({current:e.current.indexes,ideal:e.ideal.indexes}),a=ht({current:e.current.primaryKeyConstraints,ideal:e.ideal.primaryKeyConstraints}),o=_t({current:e.current.uniqueConstraints,ideal:e.ideal.uniqueConstraints}),l=xt({current:e.current.foreignKeyConstraints,ideal:e.ideal.foreignKeyConstraints});return{operations:[...t,...n,...a,...o,...l]}}import{sql as X}from"kysely";var Dt={bool:"boolean",int2:"smallint",int4:"integer",int8:"bigint"},St=e=>Dt[e]??e,Ce=e=>({introspectTables:async()=>{var i=[];try{let o=e.client;let l=_(i,o.getDB(),!0);let{rows:c}=await X`
2
2
  SELECT
3
3
  n.nspname AS table_schema,
4
4
  c.relname AS table_name,
@@ -18,7 +18,7 @@ import{a as C,b as x}from"./chunk-EY62Q3Z2.js";import{defineCommand as z,runMain
18
18
  AND a.attnum > 0
19
19
  AND NOT a.attisdropped
20
20
  ORDER BY c.relname, a.attnum;
21
- `.$castTo().execute(m);return s.map(l=>({schema:l.table_schema,table:l.table_name,name:l.column_name,default:l.column_default,characterMaximumLength:l.character_maximum_length}))}catch(c){var d=c,r=!0}finally{var p=x(i,d,r);p&&await p}},introspectIndexes:async()=>{var i=[];try{let o=e.client;let m=C(i,o.getDB(),!0);let{rows:s}=await H`
21
+ `.$castTo().execute(l);return c.map(m=>({schema:m.table_schema,table:m.table_name,name:m.column_name,default:m.column_default,characterMaximumLength:m.character_maximum_length}))}catch(s){var d=s,r=!0}finally{var p=x(i,d,r);p&&await p}},introspectIndexes:async()=>{var i=[];try{let o=e.client;let l=_(i,o.getDB(),!0);let{rows:c}=await X`
22
22
  SELECT
23
23
  t.relname AS table_name,
24
24
  i.relname AS index_name,
@@ -38,7 +38,7 @@ import{a as C,b as x}from"./chunk-EY62Q3Z2.js";import{defineCommand as z,runMain
38
38
  AND con.contype IN ('p', 'u')
39
39
  )
40
40
  GROUP BY t.relname, i.relname, pg_index.indisunique, pg_index.indisprimary, i.oid;
41
- `.$castTo().execute(m);return s.map(l=>({table:l.table_name,name:l.index_name,columns:l.column_names,unique:l.is_unique}))}catch(c){var d=c,r=!0}finally{var p=x(i,d,r);p&&await p}},introspectConstraints:async()=>{var i=[];try{let o=e.client;let m=C(i,o.getDB(),!0);let{rows:s}=await H`
41
+ `.$castTo().execute(l);return c.map(m=>({table:m.table_name,name:m.index_name,columns:m.column_names,unique:m.is_unique}))}catch(s){var d=s,r=!0}finally{var p=x(i,d,r);p&&await p}},introspectConstraints:async()=>{var i=[];try{let o=e.client;let l=_(i,o.getDB(),!0);let{rows:c}=await X`
42
42
  SELECT
43
43
  n.nspname AS schema,
44
44
  t.relname AS table,
@@ -94,8 +94,8 @@ import{a as C,b as x}from"./chunk-EY62Q3Z2.js";import{defineCommand as z,runMain
94
94
  GROUP BY n.nspname, t.relname, c.conname, c.contype, c.oid, c.conkey, t.oid,
95
95
  rt.relname, c.confkey, c.confdeltype, c.confupdtype
96
96
  ORDER BY t.relname, c.conname;
97
- `.$castTo().execute(m);return{primaryKey:s.filter(l=>l.type==="PRIMARY KEY"),unique:s.filter(l=>l.type==="UNIQUE"),foreignKey:s.filter(l=>l.type==="FOREIGN KEY").map(l=>{let{referenced_table:_,referenced_columns:b,on_delete:h,on_update:ue,...pe}=l;return{...pe,referencedTable:_,referencedColumns:b,onDelete:h,onUpdate:ue}})}}catch(c){var d=c,r=!0}finally{var p=x(i,d,r);p&&await p}},convertTypeName:ot});var it=e=>{let t=e.getDialect();switch(t){case"postgres":case"cockroachdb":return se({client:e});default:throw new Error(`Unsupported dialect: ${t}`)}},ce=e=>{let t=it(e);return{getTables:async()=>{var m=[];try{let n=C(m,e.getDB(),!0);let a=await n.introspection.getTables();let o=await t.introspectTables();return a.map(r=>{let p=Object.fromEntries(r.columns.map(l=>{let b=o.filter(h=>h.table===r.name&&h.name===l.name)[0]||{};return[l.name,{schema:r.schema,table:r.name,name:l.name,dataType:t.convertTypeName(l.dataType),default:b.default??null,characterMaximumLength:b.characterMaximumLength??null,notNull:!l.isNullable}]}));return{schema:r.schema,name:r.name,columns:p}})}catch(s){var i=s,c=!0}finally{var d=x(m,i,c);d&&await d}},getIndexes:async()=>(await t.introspectIndexes()).filter(n=>!n.table.startsWith("kysely_")),getConstraints:async()=>{let n=await t.introspectConstraints(),a=n.primaryKey.filter(s=>!s.table.startsWith("kysely_")),o=n.unique.filter(s=>!s.table.startsWith("kysely_")),m=n.foreignKey.filter(s=>!s.table.startsWith("kysely_"));return{primaryKey:a,unique:o,foreignKey:m}}}};import{PostgreSqlContainer as st}from"@testcontainers/postgresql";import{CockroachDbContainer as ct}from"@testcontainers/cockroachdb";var V=class{constructor(t,n){this.image=t;this.dialect=n}async start(){let n=await this.getContainer().start();return{dialect:this.dialect,connectionString:n.getConnectionUri()}}async stop(){}getContainer(){if(this.image.includes("postgres"))return new st(this.image);if(this.image.includes("cockroach"))return new ct(this.image);throw new Error(`Unsupported container image: ${this.image}`)}},W=class{constructor(t,n){this.connectionString=t;this.dialect=n}async start(){return{dialect:this.dialect,connectionString:this.connectionString}}async stop(){}},le=(e,t)=>{if("connectionString"in e)return new W(e.connectionString,t);if("container"in e)return new V(e.container.image,t);throw new Error("Invalid dev database configuration")};var me=async e=>{let{reporter:t}=e.logger,{client:n,cleanup:a}=await ut(e);try{if(!e.options.dev&&!e.options.ignorePending){let s=await v(e.client);if(s.length>0){t.warn([`There are pending migrations: ${s.map(i=>i.id).join(", ")}`,"Please apply them first before generating a new migration.","Otherwise, use --ignore-pending to skip this check."].join(`
98
- `));return}}let o=await pt({client:n,config:e.config});if(!o){t.info("No changes detected, no migration needed.");return}dt(e.logger,o.diff);let m=`${O}/${o.id}.json`;await lt(O,{recursive:!0}),await mt(m,JSON.stringify(o,null,2)),t.success(`Migration file generated: ${m}`),e.options.apply&&(e.options.dev?t.warn("--apply flag is ignored when using --dev. Use 'kyrage apply' to apply to production database."):await w({client:e.client,logger:e.logger,options:{plan:e.options.plan,pretty:!1}}))}finally{await a()}},ut=async e=>{let{reporter:t}=e.logger;if(!e.options.dev)return{client:e.client,cleanup:async()=>{}};if(!e.config.dev)throw new Error("Dev database configuration is required when using --dev flag");t.info("\u{1F680} Starting dev database for migration generation...");let n=le(e.config.dev,e.config.database.dialect),a=await n.start();t.success(`Dev database started: ${a.dialect}`);let o=D({database:a});return await w({client:o,logger:oe,options:{plan:!1,pretty:!1}}),{client:o,cleanup:async()=>{await n.stop(),t.success("Dev database stopped")}}},pt=async e=>{let{client:t,config:n}=e,a=ce(t),o=await a.getTables(),m=await a.getConstraints(),s=(l,_)=>b=>b.some(h=>h.table===l&&h.columns.length===1&&h.columns[0]===_),i=o.map(l=>({name:l.name,columns:Object.fromEntries(Object.entries(l.columns).map(([_,b])=>{let h=s(l.name,_);return[_,{type:b.dataType,notNull:b.notNull,primaryKey:h(m.primaryKey),unique:h(m.unique),defaultSql:b.default??void 0}]}))})),c=n.tables.map(l=>({name:l.tableName,columns:Object.fromEntries(Object.entries(l.columns).map(([_,b])=>[_,{...b,notNull:b.primaryKey||b.notNull}]))})),d=await a.getIndexes(),r=ie({current:{tables:i,indexes:d,primaryKeyConstraints:m.primaryKey,uniqueConstraints:m.unique,foreignKeyConstraints:m.foreignKey},ideal:{tables:c,indexes:n.indexes.map(l=>({table:l.table,name:l.name,columns:l.columns,unique:l.unique})),primaryKeyConstraints:n.primaryKeyConstraints||[],uniqueConstraints:n.uniqueConstraints||[],foreignKeyConstraints:n.foreignKeyConstraints||[]}});return r.operations.length===0?null:{version:"1",id:Date.now()+"",diff:r}},dt=(e,t)=>{let n=[];t.operations.forEach(a=>{switch(a.type){case"create_table":n.push(`-- create_table: ${a.table}`),Object.entries(a.columns).forEach(([o,m])=>{n.push(` -> column: ${o} (${JSON.stringify(m)})`)});break;case"drop_table":n.push(`-- remove_table: ${a.table}`);break;case"add_column":n.push([`-- add_column: ${a.table}.${a.column}`,` -> to: ${JSON.stringify(a.attributes)}`].join(`
97
+ `.$castTo().execute(l);return{primaryKey:c.filter(m=>m.type==="PRIMARY KEY"),unique:c.filter(m=>m.type==="UNIQUE"),foreignKey:c.filter(m=>m.type==="FOREIGN KEY").map(m=>{let{referenced_table:h,referenced_columns:C,on_delete:b,on_update:q,...N}=m;return{...N,referencedTable:h,referencedColumns:C,onDelete:b,onUpdate:q}})}}catch(s){var d=s,r=!0}finally{var p=x(i,d,r);p&&await p}},convertTypeName:St});var Et=e=>{let t=e.getDialect();switch(t){case"postgres":case"cockroachdb":return Ce({client:e});default:throw new Error(`Unsupported dialect: ${t}`)}},he=e=>{let t=Et(e);return{getTables:async()=>{var l=[];try{let n=_(l,e.getDB(),!0);let a=await n.introspection.getTables();let o=await t.introspectTables();return a.map(r=>{let p=Object.fromEntries(r.columns.map(m=>{let C=o.filter(b=>b.table===r.name&&b.name===m.name)[0]||{};return[m.name,{schema:r.schema,table:r.name,name:m.name,dataType:t.convertTypeName(m.dataType),default:C.default??null,characterMaximumLength:C.characterMaximumLength??null,notNull:!m.isNullable}]}));return{schema:r.schema,name:r.name,columns:p}})}catch(c){var i=c,s=!0}finally{var d=x(l,i,s);d&&await d}},getIndexes:async()=>(await t.introspectIndexes()).filter(n=>!n.table.startsWith("kysely_")),getConstraints:async()=>{let n=await t.introspectConstraints(),a=n.primaryKey.filter(c=>!c.table.startsWith("kysely_")),o=n.unique.filter(c=>!c.table.startsWith("kysely_")),l=n.foreignKey.filter(c=>!c.table.startsWith("kysely_"));return{primaryKey:a,unique:o,foreignKey:l}}}};import{PostgreSqlContainer as Nt}from"@testcontainers/postgresql";import{CockroachDbContainer as wt}from"@testcontainers/cockroachdb";import{getContainerRuntimeClient as ae}from"testcontainers";var Z="kyrage.dialect",re="kyrage.managed",_e="kyrage.managed-by",xe=async e=>(await(await ae()).container.list()).some(a=>a.Labels[re]==="true"&&a.Labels[_e]==="dev-start"&&a.Labels[Z]===e&&a.State==="running"),vt=async()=>{let e=await ae(),n=(await e.container.list()).filter(a=>a.Labels[re]==="true").map(a=>a.Id);await Promise.allSettled(n.map(async a=>e.container.getById(a).remove({force:!0})))},Tt=new Error("Dev database is not started or unavailable"),M=class{constructor(t,n){this.options=t;this.startedContainer=null;let a=n(),o=this.options.manageType||"one-off";a.withLabels({[Z]:this.options.dialect,[re]:"true",[_e]:o}),o==="dev-start"&&a.withReuse(),this.options.containerName&&a.withName(this.options.containerName),this.container=a}async findRunningContainer(){return(await ae()).container.fetchByLabel(Z,this.options.dialect,{status:["running"]})}async exists(){return!!await this.findRunningContainer()}async start(){this.startedContainer=await this.container.start()}getConnectionString(){if(!this.startedContainer)throw Tt;return this.startedContainer.getConnectionUri()}async stop(){this.startedContainer&&(await this.startedContainer.stop(),this.startedContainer=null)}async remove(){await vt(),this.startedContainer=null}async getStatus(){let t=await this.findRunningContainer();if(!t)return null;let n=await t.inspect();return{type:"container",imageName:n.Config.Image,containerID:n.Id}}},ee=class extends M{constructor(t){super(t,()=>new Nt(t.image))}},te=class extends M{constructor(t){super(t,()=>new wt(t.image))}},ne=class{constructor(t){this.connectionString=t}async start(){}async stop(){}async remove(){}async exists(){return!0}getConnectionString(){return this.connectionString}async getStatus(){return{type:"connectionString"}}},K=(e,t,n)=>{if("connectionString"in e)return new ne(e.connectionString);if("container"in e){let a={dialect:t,image:e.container.image,containerName:n==="dev-start"?e.container.name:void 0,manageType:n};switch(t){case"postgres":return new ee(a);case"cockroachdb":return new te(a);default:throw new Error(`Unsupported dialect for container: ${t}`)}}else throw new Error("Invalid dev database configuration")};async function Ot(e,t){let{config:n}=e,a=n.database.dialect;switch(t.mode){case"dev-start":{let o="dev-start",l=K(n.dev,a,o);return{manager:l,containerType:o,result:{reused:await l.exists()}}}case"generate-dev":{let o=await xe(a),l=o?"dev-start":"one-off";return{manager:K(n.dev,a,l),containerType:l,result:{reused:o}}}}}async function j(e,t){let{config:n}=e,a=t.logger||L,{reporter:o}=a;if(!n.dev)throw new Error("Dev database configuration is required");let{manager:l,containerType:c,result:i}=await Ot(e,t);i.reused?o.info("\u{1F504} Reusing existing dev database..."):o.info("\u{1F680} Starting dev database..."),await l.start(),o.success(`Dev database started: ${n.database.dialect}`);let s=k({database:{dialect:n.database.dialect,connectionString:l.getConnectionString()}}),d=await E(s);return d.length>0?(o.info(`\u{1F504} Applying ${d.length} pending migrations...`),await A({client:s,logger:L,config:n},{plan:!1,pretty:!1}),o.success(`Applied ${d.length} migrations`)):o.info("No pending migrations found"),{client:s,manager:l,cleanup:async()=>{switch(t.mode){case"dev-start":o.success("Persistent dev database ready: "+n.database.dialect);break;case"generate-dev":c==="dev-start"?o.info("Dev start container remains running"):(await l.stop(),o.success("Temporary dev database stopped"));break}}}}async function It(e,t){let{logger:n,config:a}=e,{reporter:o}=n;t.squash&&await kt(e);let{client:l,cleanup:c}=t.dev?await j(e,{mode:"generate-dev",logger:n}):{client:e.client,cleanup:async()=>{}};try{if(!t.ignorePending){let r=await E(l);if(r.length>0)if(t.dev)o.info(`Dev database has ${r.length} pending migrations. These will be applied automatically as baseline.`);else{o.warn([`There are pending migrations: ${r.map(p=>p.id).join(", ")}`,"Please apply them first before generating a new migration.","Otherwise, use --ignore-pending to skip this check."].join(`
98
+ `));return}}let i=await $t({client:l,config:a});if(!i){o.info("No changes detected, no migration needed.");return}Mt(n,i.diff);let s=`${w}/${i.id}.json`;await Kt(w,{recursive:!0}),await Rt(s,JSON.stringify(i,null,2));let d=t.squash?`Generated squashed migration: ${s}`:`Migration file generated: ${s}`;o.success(d),t.dev&&await A({...e,client:l},{plan:!1,pretty:!1})}finally{await c()}}var kt=async e=>{let{client:t,logger:n}=e,{reporter:a}=n,o=await E(t);if(o.length===0){a.info("No pending migrations found, nothing to squash.");return}a.info(`Found ${o.length} pending migrations to squash:`),o.forEach(c=>{a.info(` - ${c.id}.json`)});let l=o.map(c=>Pt(w,`${c.id}.json`));try{await Promise.all(l.map(c=>qt(c))),a.success(`\u{1F5D1}\uFE0F Removed ${l.length} pending migration files`)}catch(c){throw new Error(`Failed to remove pending migration files: ${c}`)}},$t=async e=>{let{client:t,config:n}=e,a=he(t),o=await a.getTables(),l=await a.getConstraints(),c=(m,h)=>C=>C.some(b=>b.table===m&&b.columns.length===1&&b.columns[0]===h),i=o.map(m=>({name:m.name,columns:Object.fromEntries(Object.entries(m.columns).map(([h,C])=>{let b=c(m.name,h),N=l.primaryKey.some(U=>U.table===m.name&&U.columns.length>1&&U.columns.includes(h))?!0:C.notNull;return[h,{type:C.dataType,notNull:N,primaryKey:b(l.primaryKey),unique:b(l.unique),defaultSql:C.default??void 0}]}))})),s=n.tables.map(m=>({name:m.tableName,columns:Object.fromEntries(Object.entries(m.columns).map(([h,C])=>{let b=(n.primaryKeyConstraints??[]).some(N=>N.table===m.tableName&&N.columns.includes(h)),q=C.primaryKey||C.notNull||b;return[h,{...C,notNull:q}]}))})),d=await a.getIndexes(),r=be({current:{tables:i,indexes:d,primaryKeyConstraints:l.primaryKey,uniqueConstraints:l.unique,foreignKeyConstraints:l.foreignKey},ideal:{tables:s,indexes:n.indexes.map(m=>({table:m.table,name:m.name,columns:m.columns,unique:m.unique})),primaryKeyConstraints:n.primaryKeyConstraints||[],uniqueConstraints:n.uniqueConstraints||[],foreignKeyConstraints:n.foreignKeyConstraints||[]}});return r.operations.length===0?null:{version:"1",id:Date.now()+"",diff:r}},Mt=(e,t)=>{let n=[];t.operations.forEach(a=>{switch(a.type){case"create_table":n.push(`-- create_table: ${a.table}`),Object.entries(a.columns).forEach(([o,l])=>{n.push(` -> column: ${o} (${JSON.stringify(l)})`)});break;case"drop_table":n.push(`-- remove_table: ${a.table}`);break;case"add_column":n.push([`-- add_column: ${a.table}.${a.column}`,` -> to: ${JSON.stringify(a.attributes)}`].join(`
99
99
  `));break;case"drop_column":n.push(`-- remove_column: ${a.table}.${a.column}`);break;case"alter_column":n.push([`-- change_column: ${a.table}.${a.column}`,` -> from: ${JSON.stringify(a.before)}`,` -> to: ${JSON.stringify(a.after)}`].join(`
100
100
  `));break;case"create_index":n.push(`-- create_index: ${a.table}.${a.name} (${a.columns.join(", ")})${a.unique?" [unique]":""}`);break;case"drop_index":n.push(`-- drop_index: ${a.table}.${a.name}`);break;case"create_primary_key_constraint":n.push(`-- create_primary_key_constraint: ${a.table}.${a.name} (${a.columns.join(", ")})`);break;case"drop_primary_key_constraint":n.push(`-- drop_primary_key_constraint: ${a.table}.${a.name}`);break;case"create_unique_constraint":n.push(`-- create_unique_constraint: ${a.table}.${a.name} (${a.columns.join(", ")})`);break;case"drop_unique_constraint":n.push(`-- drop_unique_constraint: ${a.table}.${a.name}`);break;case"create_foreign_key_constraint":n.push(`-- create_foreign_key_constraint: ${a.table}.${a.name} (${a.columns.join(", ")}) -> ${a.referencedTable} (${a.referencedColumns.join(", ")})${a.onDelete?` ON DELETE ${a.onDelete.toUpperCase()}`:""}${a.onUpdate?` ON UPDATE ${a.onUpdate.toUpperCase()}`:""}`);break;case"drop_foreign_key_constraint":n.push(`-- drop_foreign_key_constraint: ${a.table}.${a.name}`);break;default:break}}),e.reporter.log(n.join(`
101
- `))};import g from"zod";import{loadConfig as yt}from"c12";var gt=g.object({type:g.string(),primaryKey:g.boolean().optional().default(!1),notNull:g.boolean().optional().default(!1),unique:g.boolean().optional().default(!1),defaultSql:g.string().optional()}),ft=g.object({tableName:g.string(),columns:g.record(g.string(),gt)}),bt=g.object({...E.shape,columns:g.array(g.string()).readonly(),unique:g.boolean().default(!1)}),ht=g.enum(["postgres","cockroachdb","mysql","sqlite"]),_t=g.object({dialect:ht,connectionString:g.string()}),Ct=g.union([g.object({container:g.object({image:g.string()})}),g.object({connectionString:g.string()})]).optional(),xt=g.object({database:_t,dev:Ct,tables:g.array(ft).readonly(),indexes:g.array(bt).readonly(),primaryKeyConstraints:g.array(M).readonly(),uniqueConstraints:g.array(U).readonly(),foreignKeyConstraints:g.array(L).readonly()}),Q=async()=>{let e=await yt({name:"kyrage"});return xt.parse(e.config)};var R=re,Nt=z({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},dev:{type:"boolean",description:"Use dev database for safe migration generation",default:!1}},run:async e=>{try{let t=await Q(),n=D({database:t.database});await me({client:n,logger:R,config:t,options:{ignorePending:e.args["ignore-pending"],apply:e.args.apply,plan:e.args.plan,dev:e.args.dev}})}catch(t){R.reporter.error(t),process.exit(1)}}}),Dt=z({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 t=await Q(),n=D({database:t.database});await w({client:n,logger:R,options:{plan:e.args.plan,pretty:e.args.pretty}})}catch(t){R.reporter.error(t),process.exit(1)}}}),St=z({meta:{name:"kyrage",version:Y,description:"Kysely migration CLI with declarative schema"},subCommands:{apply:Dt,generate:Nt}});Et(St);
101
+ `))},De=At({meta:{name:"generate",description:"Generate migration files based on the current schema"},args:{"ignore-pending":{type:"boolean",description:"Ignore pending migrations and generate a new one",default:!1},dev:{type:"boolean",description:"Use dev database for safe migration generation",default:!1},squash:{type:"boolean",description:"Consolidate pending migrations into a single migration file",default:!1}},run:async e=>{try{let t=await S();await It(t,{ignorePending:e.args["ignore-pending"],dev:e.args.dev,squash:e.args.squash})}catch(t){let{defaultConsolaLogger:n}=await import("./logger-SE7G5AMI.js");n.reporter.error(t),process.exit(1)}}});import{defineCommand as R}from"citty";async function jt(e){let{manager:t,logger:n}=e,a=await t.getStatus();if(!a||a.type!=="container"){n.reporter.info("No running dev containers found");return}n.reporter.info(`Running: ${a.containerID} (${a.imageName})`)}async function Ut(e){let{manager:t,logger:n}=e;if(!await t.exists()){n.reporter.info("No running dev containers found");return}await t.start(),console.log(t.getConnectionString())}async function Lt(e){let{manager:t,logger:n}=e;if(!await t.exists()){n.reporter.info("No dev containers found");return}await t.remove(),n.reporter.success("Cleaned up dev containers")}async function Bt(e){let{logger:t}=e,{reporter:n}=t,{manager:a}=await j(e,{mode:"dev-start",logger:t});n.success(`\u2728 Dev database ready: ${a.getConnectionString()}`)}async function oe(){let e=await S();if(!e.config.dev||!("container"in e.config.dev))throw new Error("No dev database container configuration found");let t=K(e.config.dev,e.config.database.dialect,"dev-start");return{...e,manager:t}}var Ft=R({meta:{name:"start",description:"Start development database with migrations applied"},run:async()=>{try{let e=await S();await Bt(e)}catch(e){let{defaultConsolaLogger:t}=await import("./logger-SE7G5AMI.js");t.reporter.error(e),process.exit(1)}}}),Ht=R({meta:{name:"status",description:"Show status of kyrage dev container"},run:async()=>{try{let e=await oe();await jt(e)}catch(e){let{defaultConsolaLogger:t}=await import("./logger-SE7G5AMI.js");t.reporter.error(e),process.exit(1)}}}),Wt=R({meta:{name:"get-url",description:"Print connection URL for running dev container"},run:async()=>{try{let e=await oe();await Ut(e)}catch(e){let{defaultConsolaLogger:t}=await import("./logger-SE7G5AMI.js");t.reporter.error(e),process.exit(1)}}}),Qt=R({meta:{name:"clean",description:"Remove all kyrage dev containers"},run:async()=>{try{let e=await oe();await Lt(e)}catch(e){let{defaultConsolaLogger:t}=await import("./logger-SE7G5AMI.js");t.reporter.error(e),process.exit(1)}}}),Se=R({meta:{name:"dev",description:"Manage development database containers"},subCommands:{start:Ft,status:Ht,"get-url":Wt,clean:Qt}});var Jt=Vt({meta:{name:"kyrage",version:se,description:"Kysely migration CLI with declarative schema"},subCommands:{apply:fe,generate:De,dev:Se}});zt(Jt);
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@izumisy/kyrage",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "1.0.0",
5
+ "version": "1.2.0",
6
6
  "description": "A minimal, schema-based declarative migration tool for Node.js ecosystem",
7
7
  "author": "Seiya Izumi (https://github.com/IzumiSy)",
8
8
  "license": "MIT",
@@ -43,15 +43,15 @@
43
43
  "ramda": "^0.31.3",
44
44
  "sql-formatter": "^15.6.6",
45
45
  "testcontainers": "^11.5.1",
46
- "zod": "^4.0.17"
46
+ "zod": "^4.1.5"
47
47
  },
48
48
  "devDependencies": {
49
- "@swc/core": "^1.13.3",
49
+ "@swc/core": "^1.13.5",
50
50
  "@types/better-sqlite3": "^7.6.13",
51
51
  "@types/node": "^24.3.0",
52
52
  "@types/pg": "^8.15.5",
53
53
  "@types/ramda": "^0.31.0",
54
- "memfs": "^4.36.0",
54
+ "memfs": "^4.38.2",
55
55
  "prettier": "^3.6.2",
56
56
  "tsup": "^8.5.0",
57
57
  "typescript": "^5.9.2",