@izumisy/kyrage 0.6.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 +4 -6
- package/dist/index.js +1 -1
- package/dist/main.js +6 -5
- package/package.json +1 -1
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
|
-
|
|
37
|
+
type DefineConfigProp = {
|
|
38
38
|
database: DatabaseValue;
|
|
39
|
-
tables:
|
|
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
|
|
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
|
|
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 b,b as h}from"./chunk-EY62Q3Z2.js";import{defineCommand as M,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
|
|
22
|
-
`));return}}let a=await
|
|
23
|
-
`))}),
|
|
24
|
-
`))})})
|
|
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,7 +2,7 @@
|
|
|
2
2
|
"name": "@izumisy/kyrage",
|
|
3
3
|
"private": false,
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.7.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",
|