@izumisy/kyrage 1.5.8 → 1.6.1

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.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import z from "zod";
2
2
  import { ColumnDataType } from "kysely";
3
-
4
3
  //#region src/config/loader.d.ts
5
4
  declare const columnSchema: z.ZodObject<{
6
5
  type: z.ZodString;
@@ -19,39 +18,44 @@ declare const indexSchema: z.ZodObject<{
19
18
  type IndexSchema = z.infer<typeof indexSchema>;
20
19
  declare const databaseSchema: z.ZodObject<{
21
20
  dialect: z.ZodEnum<{
22
- postgres: "postgres";
23
21
  cockroachdb: "cockroachdb";
22
+ postgres: "postgres";
23
+ sqlite: "sqlite";
24
24
  }>;
25
25
  connectionString: z.ZodString;
26
26
  }, z.core.$strip>;
27
27
  type DatabaseValue = z.infer<typeof databaseSchema>;
28
28
  declare const devDatabaseSchema: z.ZodUnion<readonly [z.ZodObject<{
29
- container: z.ZodObject<{
29
+ container: z.ZodDefault<z.ZodObject<{
30
30
  image: z.ZodDefault<z.ZodString>;
31
31
  name: z.ZodOptional<z.ZodString>;
32
- }, z.core.$strip>;
32
+ }, z.core.$strip>>;
33
+ }, z.core.$strip>, z.ZodObject<{
34
+ file: z.ZodDefault<z.ZodObject<{
35
+ name: z.ZodDefault<z.ZodString>;
36
+ }, z.core.$strip>>;
33
37
  }, z.core.$strip>]>;
34
38
  type DevDatabaseValue = z.infer<typeof devDatabaseSchema>;
35
39
  //#endregion
36
40
  //#region src/operations/shared/types.d.ts
37
41
  declare const primaryKeyConstraintSchema: z.ZodObject<{
38
- columns: z.ZodReadonly<z.ZodArray<z.ZodString>>;
39
42
  table: z.ZodString;
40
43
  name: z.ZodString;
44
+ columns: z.ZodReadonly<z.ZodArray<z.ZodString>>;
41
45
  }, z.core.$strip>;
42
46
  type PrimaryKeyConstraintSchema = z.infer<typeof primaryKeyConstraintSchema>;
43
47
  declare const uniqueConstraintSchema: z.ZodObject<{
44
- columns: z.ZodReadonly<z.ZodArray<z.ZodString>>;
45
48
  table: z.ZodString;
46
49
  name: z.ZodString;
50
+ columns: z.ZodReadonly<z.ZodArray<z.ZodString>>;
47
51
  }, z.core.$strip>;
48
52
  type UniqueConstraintSchema = z.infer<typeof uniqueConstraintSchema>;
49
53
  declare const referentialActionsSchema: z.ZodEnum<{
50
54
  cascade: "cascade";
51
- "set null": "set null";
52
- "set default": "set default";
53
- restrict: "restrict";
54
55
  "no action": "no action";
56
+ restrict: "restrict";
57
+ "set default": "set default";
58
+ "set null": "set null";
55
59
  }>;
56
60
  type ReferentialActions = z.infer<typeof referentialActionsSchema>;
57
61
  //#endregion
@@ -59,7 +63,7 @@ type ReferentialActions = z.infer<typeof referentialActionsSchema>;
59
63
  /**
60
64
  * Defines a column in a table.
61
65
  */
62
- declare const column: (type: ColumnDataType, options?: Partial<Omit<ColumnValue, "type">>) => {
66
+ export declare const column: (type: ColumnDataType, options?: Partial<Omit<ColumnValue, "type">>) => {
63
67
  type: ColumnDataType;
64
68
  notNull: boolean | undefined;
65
69
  primaryKey: boolean | undefined;
@@ -127,22 +131,7 @@ type ExpressionBuilders<T extends Record<string, DefinedColumn>> = {
127
131
  /**
128
132
  * Defines a table with its columns and optional expression builders.
129
133
  */
130
- declare const defineTable: <T extends Record<string, DefinedColumn>>(
131
- /**
132
- * The name of the table.
133
- */
134
- name: string,
135
- /**
136
- * The columns in the table.
137
- */
138
- columns: T,
139
- /**
140
- * The expression builders for the table.
141
- *
142
- * This is where you can define additional indexes, constraints, or other
143
- * database-specific features for the table.
144
- */
145
- tableExpBuilder?: (builder: ExpressionBuilders<T>) => ReadonlyArray<ReturnType<ExpressionBuilders<T>["index"]> | ReturnType<ExpressionBuilders<T>["primaryKey"]> | ReturnType<ExpressionBuilders<T>["unique"]> | ReturnType<ExpressionBuilders<T>["reference"]>>) => {
134
+ export declare const defineTable: <T extends Record<string, DefinedColumn>>(name: string, columns: T, tableExpBuilder?: (builder: ExpressionBuilders<T>) => ReadonlyArray<ReturnType<ExpressionBuilders<T>["index"]> | ReturnType<ExpressionBuilders<T>["primaryKey"]> | ReturnType<ExpressionBuilders<T>["unique"]> | ReturnType<ExpressionBuilders<T>["reference"]>>) => {
146
135
  tableName: string;
147
136
  columns: T;
148
137
  indexes: DefinedIndex[];
@@ -150,20 +139,26 @@ tableExpBuilder?: (builder: ExpressionBuilders<T>) => ReadonlyArray<ReturnType<E
150
139
  uniques: DefinedUniqueConstraint[];
151
140
  foreignKeys: DefinedForeignKeyConstraint[];
152
141
  };
153
- type DefinedTable = ReturnType<typeof defineTable> & {
142
+ export type DefinedTable = ReturnType<typeof defineTable> & {
154
143
  indexes: ReadonlyArray<DefinedIndex>;
155
144
  primaryKeys: ReadonlyArray<DefinedPrimaryKeyConstraint>;
156
145
  uniques: ReadonlyArray<DefinedUniqueConstraint>;
157
146
  foreignKeys: ReadonlyArray<DefinedForeignKeyConstraint>;
158
147
  };
159
- type DefinedTables = ReadonlyArray<DefinedTable>;
160
- type DefineConfigProp = {
148
+ export type DefinedTables = ReadonlyArray<DefinedTable>;
149
+ export type DefineConfigProp = {
161
150
  database: DatabaseValue;
162
151
  dev?: DevDatabaseValue;
163
152
  tables: DefinedTables;
164
153
  };
165
- declare const defineConfig: (config: DefineConfigProp) => {
154
+ export declare const defineConfig: (config: DefineConfigProp) => {
155
+ readonly database: DatabaseValue;
156
+ readonly tables: DefinedTables;
166
157
  readonly dev: {
158
+ file: {
159
+ name: string;
160
+ };
161
+ } | {
167
162
  container: {
168
163
  image: string;
169
164
  name?: string | undefined;
@@ -176,27 +171,24 @@ declare const defineConfig: (config: DefineConfigProp) => {
176
171
  name: string;
177
172
  }[];
178
173
  readonly primaryKeyConstraints: {
179
- columns: readonly string[];
180
174
  table: string;
181
175
  name: string;
176
+ columns: readonly string[];
182
177
  }[];
183
178
  readonly uniqueConstraints: {
184
- columns: readonly string[];
185
179
  table: string;
186
180
  name: string;
181
+ columns: readonly string[];
187
182
  }[];
188
183
  readonly foreignKeyConstraints: {
184
+ table: string;
185
+ name: string;
189
186
  columns: readonly string[];
190
187
  referencedTable: string;
191
188
  referencedColumns: readonly string[];
192
- table: string;
193
- name: string;
194
- onDelete?: "cascade" | "set null" | "set default" | "restrict" | "no action" | undefined;
195
- onUpdate?: "cascade" | "set null" | "set default" | "restrict" | "no action" | undefined;
189
+ onDelete?: "cascade" | "no action" | "restrict" | "set default" | "set null" | undefined;
190
+ onUpdate?: "cascade" | "no action" | "restrict" | "set default" | "set null" | undefined;
196
191
  inline?: boolean | undefined;
197
192
  }[];
198
- readonly database: DatabaseValue;
199
- readonly tables: DefinedTables;
200
193
  };
201
- //#endregion
202
- export { DefineConfigProp, DefinedTable, DefinedTables, column, defineConfig, defineTable };
194
+ //#endregion
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const e={primaryKey:(e,t)=>t.length===1?`${e}_${t[0]}_primary_key`:`pk_${e}_${t.join(`_`)}`,unique:(e,t)=>t.length===1?`${e}_${t[0]}_unique`:`uq_${e}_${t.join(`_`)}`,index:(e,t)=>`idx_${e}_${t.join(`_`)}`,foreignKey:(e,t)=>`fk_${e}_${t.join(`_`)}`},t=(e,t)=>({type:e,notNull:t?.notNull,primaryKey:t?.primaryKey,unique:t?.unique,defaultSql:t?.defaultSql}),n=(t,n,r)=>{let i=e=>{if(e.length===0)throw Error(`At least one column must be specified.`)},a=(e,n)=>`${e}_${t}_${n.join(`_`)}`,o=r?r({index:(e,t)=>(i(e),{kind:`index`,name:t?.name??a(`idx`,e),columns:e,unique:t?.unique??!1}),primaryKey:(e,t)=>(i(e),{kind:`primaryKey`,name:t?.name??a(`pk`,e),columns:e}),unique:(e,t)=>(i(e),{kind:`unique`,name:t?.name??a(`uq`,e),columns:e}),reference:(n,r,a,o)=>{let s=Array.isArray(n)?n:[n],c=Array.isArray(a)?a:[a];return i(s),i(c),{kind:`foreignKey`,name:o?.name??e.foreignKey(t,s),columns:s,referencedTable:r.tableName,referencedColumns:c,onDelete:o?.onDelete,onUpdate:o?.onUpdate,inline:o?.inline??!0}}}):[];return{tableName:t,columns:n,indexes:o.filter(e=>e.kind===`index`),primaryKeys:o.filter(e=>e.kind===`primaryKey`),uniques:o.filter(e=>e.kind===`unique`),foreignKeys:o.filter(e=>e.kind===`foreignKey`)}},r=t=>{let n=new Map,r=new Map,i=new Map,a=new Map;for(let o of t.tables){let t=o.tableName;for(let e of o.indexes??[])n.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns,unique:e.unique});for(let e of o.primaryKeys??[])r.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns});for(let e of o.uniques??[])i.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns});for(let e of o.foreignKeys??[])a.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns,referencedTable:e.referencedTable,referencedColumns:e.referencedColumns,onDelete:e.onDelete,onUpdate:e.onUpdate,inline:e.inline});for(let[n,a]of Object.entries(o.columns)){if(a.primaryKey){let i=e.primaryKey(t,[n]),a=`${t}:${i}`;r.has(a)||r.set(a,{table:t,name:i,columns:[n]})}if(a.unique){let r=e.unique(t,[n]),a=`${t}:${r}`;i.has(a)||i.set(a,{table:t,name:r,columns:[n]})}}}return{...t,dev:t.dev,indexes:Array.from(n.values()),primaryKeyConstraints:Array.from(r.values()),uniqueConstraints:Array.from(i.values()),foreignKeyConstraints:Array.from(a.values())}};export{t as column,r as defineConfig,n as defineTable};
1
+ import{t as e}from"./naming-DSgOe9tq.mjs";const t=(e,t)=>({type:e,notNull:t?.notNull,primaryKey:t?.primaryKey,unique:t?.unique,defaultSql:t?.defaultSql}),n=(t,n,r)=>{let i=e=>{if(e.length===0)throw Error(`At least one column must be specified.`)},a=(e,n)=>`${e}_${t}_${n.join(`_`)}`,o=r?r({index:(e,t)=>(i(e),{kind:`index`,name:t?.name??a(`idx`,e),columns:e,unique:t?.unique??!1}),primaryKey:(e,t)=>(i(e),{kind:`primaryKey`,name:t?.name??a(`pk`,e),columns:e}),unique:(e,t)=>(i(e),{kind:`unique`,name:t?.name??a(`uq`,e),columns:e}),reference:(n,r,a,o)=>{let s=Array.isArray(n)?n:[n],c=Array.isArray(a)?a:[a];return i(s),i(c),{kind:`foreignKey`,name:o?.name??e.foreignKey(t,s),columns:s,referencedTable:r.tableName,referencedColumns:c,onDelete:o?.onDelete,onUpdate:o?.onUpdate,inline:o?.inline??!0}}}):[];return{tableName:t,columns:n,indexes:o.filter(e=>e.kind===`index`),primaryKeys:o.filter(e=>e.kind===`primaryKey`),uniques:o.filter(e=>e.kind===`unique`),foreignKeys:o.filter(e=>e.kind===`foreignKey`)}},r=t=>{let n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map,a=/* @__PURE__ */ new Map;for(let o of t.tables){let t=o.tableName;for(let e of o.indexes??[])n.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns,unique:e.unique});for(let e of o.primaryKeys??[])r.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns});for(let e of o.uniques??[])i.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns});for(let e of o.foreignKeys??[])a.set(`${t}:${e.name}`,{table:t,name:e.name,columns:e.columns,referencedTable:e.referencedTable,referencedColumns:e.referencedColumns,onDelete:e.onDelete,onUpdate:e.onUpdate,inline:e.inline});for(let[n,a]of Object.entries(o.columns)){if(a.primaryKey){let i=e.primaryKey(t,[n]),a=`${t}:${i}`;r.has(a)||r.set(a,{table:t,name:i,columns:[n]})}if(a.unique){let r=e.unique(t,[n]),a=`${t}:${r}`;i.has(a)||i.set(a,{table:t,name:r,columns:[n]})}}}return{...t,dev:t.dev,indexes:Array.from(n.values()),primaryKeyConstraints:Array.from(r.values()),uniqueConstraints:Array.from(i.values()),foreignKeyConstraints:Array.from(a.values())}};export{t as column,r as defineConfig,n as defineTable};
package/dist/main.d.mts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import{defineCommand as e,runMain as t}from"citty";import n from"zod";import{loadConfig as r}from"c12";import{getContainerRuntimeClient as i}from"testcontainers";import{DEFAULT_MIGRATION_TABLE as a,DummyDriver as o,Kysely as s,Migrator as c,PostgresAdapter as l,PostgresDialect as u,isColumnDataType as ee,sql as d}from"kysely";import{Pool as f}from"pg";import{PostgreSqlContainer as te}from"@testcontainers/postgresql";import*as p from"ramda";import{CockroachDbContainer as ne}from"@testcontainers/cockroachdb";import{createConsola as re}from"consola";import*as ie from"fs/promises";import{join as m}from"path";import{CycleError as ae,Graph as oe,topologicalSort as se}from"graph-data-structure";import{format as ce}from"sql-formatter";var le=`1.5.8`;const h=n.object({type:n.string()}).catchall(n.any()),g=n.object({table:n.string(),name:n.string()}),_=n.object({table:n.string(),column:n.string()}),ue=n.object({...g.shape,columns:n.array(n.string()).readonly()}),de=n.object({...g.shape,columns:n.array(n.string()).readonly()}),v=n.enum([`cascade`,`set null`,`set default`,`restrict`,`no action`]),fe=n.object({...g.shape,columns:n.array(n.string()).readonly(),referencedTable:n.string(),referencedColumns:n.array(n.string()).readonly(),onDelete:v.optional(),onUpdate:v.optional(),inline:n.boolean().optional()}),y=e=>n.object({container:n.object({image:n.string().default(e.defaultImage),name:n.string().optional()})});var b=class{constructor(e,t){this.dialect=e,this.containerFactory=t}async setup(e,t){return new pe({dialect:this.dialect,manageType:t,containerName:e.container.name,containerFactory:()=>this.containerFactory(e.container.image)})}async hasExisting(e){return e===`dev-start`?w(this.dialect):!1}async cleanup(){await T()}};const x=`kyrage.dialect`,S=`kyrage.managed`,C=`kyrage.managed-by`;var pe=class{constructor(e){this.options=e,this.startedContainer=null,this.container=this.setupContainer()}setupContainer(){let e=this.options.containerFactory();return e.withLabels({[x]:this.options.dialect,[S]:`true`,[C]:this.options.manageType}),this.options.manageType===`dev-start`&&e.withReuse(),this.options.containerName&&e.withName(this.options.containerName),e}async start(){this.startedContainer=await this.container.start()}async stop(){this.startedContainer&&=(await this.startedContainer.stop(),null)}async remove(){await T(),this.startedContainer=null}getConnectionString(){if(!this.startedContainer)throw Error(`Container is not started`);return this.startedContainer.getConnectionUri()}async getStatus(){let e=await(await i()).container.fetchByLabel(x,this.options.dialect,{status:[`running`]});if(e){let t=await e.inspect();return{type:`container`,imageName:t.Config.Image,containerID:t.Id}}return{type:`unavailable`}}async isAvailable(){return(await this.getStatus()).type===`container`}};const w=async e=>(await(await i()).container.list()).some(t=>t.Labels[S]===`true`&&t.Labels[C]===`dev-start`&&t.Labels[x]===e&&t.State===`running`),T=async()=>{let e=await i(),t=(await e.container.list()).filter(e=>e.Labels[S]===`true`).map(e=>e.Id);await Promise.allSettled(t.map(async t=>e.container.getById(t).remove({force:!0})))},me=n.object({type:n.string(),primaryKey:n.boolean().optional().default(!1),notNull:n.boolean().optional().default(!1),unique:n.boolean().optional().default(!1),defaultSql:n.string().optional()}),he=n.object({tableName:n.string(),columns:n.record(n.string(),me)}),ge=n.object({...g.shape,columns:n.array(n.string()).readonly(),unique:n.boolean().default(!1)}),_e=n.enum([`postgres`,`cockroachdb`]),ve=n.object({dialect:_e,connectionString:n.string()}),ye=n.union([y({defaultImage:``})]),be=n.object({database:ve,dev:ye.optional(),tables:n.array(he).readonly(),indexes:n.array(ge).readonly(),primaryKeyConstraints:n.array(ue).readonly(),uniqueConstraints:n.array(de).readonly(),foreignKeyConstraints:n.array(fe).readonly()}),xe=async()=>{let e=await r({name:`kyrage`});return be.parse(e.config)},Se=(e,t)=>{let n=e=>t=>p.any(p.whereEq({name:t.name,table:t.table}),e),[r,i]=p.partition(n(e.uniqueConstraints),t.constraints.unique),[a,o]=p.partition(n(e.indexes),t.indexes),s=p.reject(n(a),i),c=p.reject(n(r),o);return{indexes:[...a,...c],uniqueConstraints:[...r,...s]}};var Ce=class{getName(){return`postgres`}createKyselyDialect(e){return new u({pool:new f({connectionString:e})})}createIntrospectionDriver(e){return{convertTypeName:D,introspect:E(e)}}createDevDatabaseProvider(){return new b(this.getName(),e=>new te(e))}parseDevDatabaseConfig(e){return y({defaultImage:`postgres:16`}).parse(e)}async hasReusableDevDatabase(){return w(this.getName())}};const E=e=>async t=>{await using n=e.getDB();let[r,i,a]=await Promise.all([we(n),Te(n),Ee(n)]),{indexes:o,uniqueConstraints:s}=Se(t.config,{indexes:i,constraints:a});return{tables:r,indexes:o,constraints:{...a,unique:s}}},D=e=>({bool:`boolean`,int2:`smallint`,int4:`integer`,int8:`bigint`})[e]??e,we=async e=>{let{rows:t}=await d`
1
+ import{n as e}from"./naming-DSgOe9tq.mjs";import{defineCommand as t,runMain as n}from"citty";import r from"zod";import{loadConfig as i}from"c12";import{getContainerRuntimeClient as a}from"testcontainers";import*as o from"fs/promises";import*as s from"path";import{join as c}from"path";import*as l from"os";import{DEFAULT_MIGRATION_TABLE as u,DummyDriver as ee,Kysely as te,Migrator as ne,PostgresAdapter as re,PostgresDialect as d,SqliteDialect as ie,isColumnDataType as ae,sql as f}from"kysely";import{Pool as p}from"pg";import{PostgreSqlContainer as oe}from"@testcontainers/postgresql";import*as m from"ramda";import{CockroachDbContainer as se}from"@testcontainers/cockroachdb";import ce from"better-sqlite3";import{createConsola as le}from"consola";import{CycleError as ue,Graph as de,topologicalSort as fe}from"graph-data-structure";import{format as pe}from"sql-formatter";var me=`1.6.1`;const h=r.object({type:r.string()}).catchall(r.any()),g=r.object({table:r.string(),name:r.string()}),_=r.object({table:r.string(),column:r.string()}),he=r.object({...g.shape,columns:r.array(r.string()).readonly()}),v=r.object({...g.shape,columns:r.array(r.string()).readonly()}),y=r.enum([`cascade`,`set null`,`set default`,`restrict`,`no action`]),b=r.object({...g.shape,columns:r.array(r.string()).readonly(),referencedTable:r.string(),referencedColumns:r.array(r.string()).readonly(),onDelete:y.optional(),onUpdate:y.optional(),inline:r.boolean().optional()}),x=e=>r.object({container:r.object({image:r.string().default(e.defaultImage),name:r.string().optional()}).default({image:e.defaultImage})});var S=class{constructor(e,t){this.dialect=e,this.containerFactory=t}async setup(e,t){return new _e({dialect:this.dialect,manageType:t,containerName:e.container.name,containerFactory:()=>this.containerFactory(e.container.image)})}async hasExisting(e){return e===`dev-start`&&C(this.dialect)}async cleanup(){await ve()}};const ge=`kyrage.managed`;var _e=class{constructor(e){this.options=e,this.startedContainer=null,this.container=this.setupContainer()}setupContainer(){let e=this.options.containerFactory();return e.withLabels({"kyrage.dialect":this.options.dialect,[ge]:`true`,"kyrage.managed-by":this.options.manageType}),this.options.manageType===`dev-start`&&e.withReuse(),this.options.containerName&&e.withName(this.options.containerName),e}async start(){this.startedContainer=await this.container.start()}async stop(){this.startedContainer&&=(await this.startedContainer.stop(),null)}async remove(){await ve(),this.startedContainer=null}getConnectionString(){if(!this.startedContainer)throw Error(`Container is not started`);return this.startedContainer.getConnectionUri()}async getStatus(){if(!this.startedContainer)return{type:`unavailable`};let e=await a();try{let t=await e.container.getById(this.startedContainer.getId()).inspect();return t.State.Running?{type:`container`,imageName:t.Config.Image,containerID:t.Id}:{type:`unavailable`}}catch{return{type:`unavailable`}}}async isAvailable(){return(await this.getStatus()).type===`container`}};const C=async e=>(await(await a()).container.list()).some(t=>t.Labels[`kyrage.managed`]===`true`&&t.Labels[`kyrage.managed-by`]===`dev-start`&&t.Labels[`kyrage.dialect`]===e&&t.State===`running`),ve=async()=>{let e=await a(),t=(await e.container.list()).filter(e=>e.Labels[ge]===`true`).map(e=>e.Id);await Promise.allSettled(t.map(async t=>e.container.getById(t).remove({force:!0})))},w=`default`,T=()=>r.object({file:r.object({name:r.string().default(w)}).default({name:w})});var ye=class{async setup(e,t){return new be({manageType:t,name:e.file?.name})}async hasExisting(e){if(e===`dev-start`){let e=this.getDevStartPath();try{return await o.access(e),!0}catch{return!1}}return!1}getDevStartPath(e){let t=e||w;return s.join(l.tmpdir(),`kyrage___dev-${t}.db`)}async cleanup(){try{let e=l.tmpdir(),t=(await o.readdir(e)).filter(e=>e.startsWith(`kyrage___dev-`));await Promise.allSettled(t.map(t=>o.unlink(s.join(e,t))))}catch{}}},be=class{constructor(e){this.options=e,this.connectionString=null,this.filePath=null}async start(){if(this.options.manageType===`dev-start`)this.filePath=this.getDevStartPath(),this.connectionString=this.filePath;else{let e=s.join(l.tmpdir(),`kyrage-test-${Date.now()}-${Math.random().toString(36).slice(2)}.db`);this.filePath=e,this.connectionString=e}}async stop(){if(this.options.manageType===`one-off`&&this.filePath){try{await o.unlink(this.filePath)}catch{}this.filePath=null,this.connectionString=null}}async remove(){if(this.filePath)try{await o.unlink(this.filePath)}catch{}this.connectionString=null,this.filePath=null}getConnectionString(){if(!this.connectionString)throw Error(`File database is not started`);return this.connectionString}async getStatus(){return this.connectionString?this.connectionString===`:memory:`?{type:`file`,filePath:`:memory:`,mode:`memory`}:{type:`file`,filePath:this.connectionString,mode:`file`}:{type:`unavailable`}}async isAvailable(){return(await this.getStatus()).type===`file`}getDevStartPath(){let e=this.options.name||w;return s.join(l.tmpdir(),`kyrage___dev-${e}.db`)}};const xe=r.object({type:r.string(),primaryKey:r.boolean().optional().default(!1),notNull:r.boolean().optional().default(!1),unique:r.boolean().optional().default(!1),defaultSql:r.string().optional()}),Se=r.object({tableName:r.string(),columns:r.record(r.string(),xe)}),Ce=r.object({...g.shape,columns:r.array(r.string()).readonly(),unique:r.boolean().default(!1)}),we=r.enum([`postgres`,`cockroachdb`,`sqlite`]),Te=r.object({dialect:we,connectionString:r.string()}),Ee=r.union([x({defaultImage:``}),T()]),De=r.object({database:Te,dev:Ee.optional(),tables:r.array(Se).readonly(),indexes:r.array(Ce).readonly(),primaryKeyConstraints:r.array(he).readonly(),uniqueConstraints:r.array(v).readonly(),foreignKeyConstraints:r.array(b).readonly()}),Oe=async()=>{let e=await i({name:`kyrage`});return De.parse(e.config)},ke=(e,t)=>{let n=e=>t=>m.any(m.whereEq({name:t.name,table:t.table}),e),[r,i]=m.partition(n(e.uniqueConstraints),t.constraints.unique),[a,o]=m.partition(n(e.indexes),t.indexes),s=m.reject(n(a),i),c=m.reject(n(r),o);return{indexes:[...a,...c],uniqueConstraints:[...r,...s]}};var Ae=class{getName(){return`postgres`}createKyselyDialect(e){return new d({pool:new p({connectionString:e})})}createIntrospectionDriver(e){return{convertTypeName:D,introspect:E(e)}}createDevDatabaseProvider(){return new S(this.getName(),e=>new oe(e))}parseDevDatabaseConfig(e){return x({defaultImage:`postgres:16`}).parse(e)}async hasReusableDevDatabase(){return C(this.getName())}};const E=e=>async t=>{await using n=e.getDB();let[r,i,a]=await Promise.all([je(n),Me(n),Ne(n)]),{indexes:o,uniqueConstraints:s}=ke(t.config,{indexes:i,constraints:a});return{tables:r,indexes:o,constraints:{...a,unique:s}}},D=e=>({bool:`boolean`,int2:`smallint`,int4:`integer`,int8:`bigint`})[e]??e,je=async e=>{let{rows:t}=await f`
2
2
  SELECT
3
3
  n.nspname AS table_schema,
4
4
  c.relname AS table_name,
@@ -18,7 +18,7 @@ import{defineCommand as e,runMain as t}from"citty";import n from"zod";import{loa
18
18
  AND a.attnum > 0
19
19
  AND NOT a.attisdropped
20
20
  ORDER BY c.relname, a.attnum;
21
- `.$castTo().execute(e);return t.map(e=>({schema:e.table_schema,table:e.table_name,name:e.column_name,default:e.column_default,characterMaximumLength:e.character_maximum_length?Number(e.character_maximum_length):null}))},Te=async e=>{let{rows:t}=await d`
21
+ `.$castTo().execute(e);return t.map(e=>({schema:e.table_schema,table:e.table_name,name:e.column_name,default:e.column_default,characterMaximumLength:e.character_maximum_length?Number(e.character_maximum_length):null}))},Me=async e=>{let{rows:t}=await f`
22
22
  SELECT
23
23
  t.relname AS table_name,
24
24
  c.relname AS index_name,
@@ -33,7 +33,7 @@ import{defineCommand as e,runMain as t}from"citty";import n from"zod";import{loa
33
33
  AND n.nspname = 'public'
34
34
  AND NOT i.indisprimary
35
35
  GROUP BY t.relname, c.relname, i.indisunique, i.indisprimary, c.oid;
36
- `.$castTo().execute(e);return t.map(e=>({table:e.table_name,name:e.index_name,columns:e.column_names,unique:e.is_unique}))},Ee=async e=>{let{rows:t}=await d`
36
+ `.$castTo().execute(e);return t.map(e=>({table:e.table_name,name:e.index_name,columns:e.column_names,unique:e.is_unique}))},Ne=async e=>{let{rows:t}=await f`
37
37
  SELECT
38
38
  n.nspname AS schema,
39
39
  t.relname AS table,
@@ -89,8 +89,40 @@ import{defineCommand as e,runMain as t}from"citty";import n from"zod";import{loa
89
89
  GROUP BY n.nspname, t.relname, c.conname, c.contype, c.oid, c.conkey, t.oid,
90
90
  rt.relname, c.confkey, c.confdeltype, c.confupdtype
91
91
  ORDER BY t.relname, c.conname;
92
- `.$castTo().execute(e);return{primaryKey:t.filter(e=>e.type===`PRIMARY KEY`),unique:t.filter(e=>e.type===`UNIQUE`),foreignKey:t.filter(e=>e.type===`FOREIGN KEY`).map(e=>{let{referenced_table:t,referenced_columns:n,on_delete:r,on_update:i,...a}=e;return{...a,referencedTable:t,referencedColumns:n,onDelete:r,onUpdate:i}})}};var De=class{getName(){return`cockroachdb`}createKyselyDialect(e){return new ke({pool:new f({connectionString:e})})}createIntrospectionDriver(e){let t=[`rowid`];return{convertTypeName:D,introspect:async n=>{let r=await E(e)(n);return{tables:r.tables.filter(e=>!t.includes(e.name)),indexes:r.indexes,constraints:r.constraints}}}}createDevDatabaseProvider(){return new b(this.getName(),e=>new ne(e))}parseDevDatabaseConfig(e){return y({defaultImage:`cockroachdb/cockroach:latest-v24.3`}).parse(e)}async hasReusableDevDatabase(){return w(this.getName())}},Oe=class extends l{async acquireMigrationLock(e,t){await e.selectFrom(t.lockTable).selectAll().forUpdate().execute()}},ke=class extends u{createAdapter(){return new Oe}};const Ae={postgres:new Ce,cockroachdb:new De},O=e=>{let t=Ae[e];if(!t)throw Error(`Unsupported dialect: ${e}`);return t};var je=class extends o{constructor(e){super(),this.queries=e}async acquireConnection(){return new Me(this.queries)}},Me=class{constructor(e){this.queries=e}async executeQuery(e){let t=e.query.kind;if(t===`CreateTableNode`||t===`DropTableNode`||t===`AlterTableNode`){if(e.query.table.table.identifier.name.startsWith(`kysely_`))return{rows:[]};this.queries.push(e)}else (t===`CreateIndexNode`||t===`DropIndexNode`)&&this.queries.push(e);return{rows:[]}}async*streamQuery(){}};const k=e=>new Ne({databaseProps:e.database,options:e.options});var Ne=class{constructor(e){this.constructorProps=e}getDB(e){let t=O(this.constructorProps.databaseProps.dialect).createKyselyDialect(this.constructorProps.databaseProps.connectionString);return new Pe({dialect:{createAdapter:()=>t.createAdapter(),createDriver:()=>t.createDriver(),createIntrospector:e=>t.createIntrospector(e),createQueryCompiler:()=>t.createQueryCompiler()}},{isPlan:e?.plan===!0})}getDialect(){return this.constructorProps.databaseProps.dialect}},Pe=class extends s{constructor(e,t){let n=[];super({dialect:{...e.dialect,createDriver:()=>t.isPlan?new je(n):e.dialect.createDriver()}}),this.plannedQueries=[],this.plannedQueries=n}getPlannedQueries(){return this.plannedQueries}};const A={stdout:e=>console.log(e),reporter:{...re({stdout:process.stderr})}},j={stdout:()=>void 0,reporter:{info:()=>void 0,warn:()=>void 0,success:()=>void 0,log:()=>void 0,error:()=>void 0}};async function M(){let e=await xe();return{client:k({database:e.database}),logger:A,fs:ie,config:e}}const N=e=>{if(!ee(e))throw Error(`Unsupported data type: ${e}`)},P=e=>e,Fe=P({typeName:`create_table`,schema:n.object({type:n.literal(`create_table`),table:n.string(),columns:n.record(n.string(),h)}),execute:async(e,t)=>{let n=e.schema.createTable(t.table);n=F(n,t.columns),await n.execute()}}),Ie=(e,t)=>({type:`create_table`,table:e,columns:t});function F(e,t){let n=e;for(let[e,r]of Object.entries(t)){let t=r.type;N(t),n=n.addColumn(e,t,e=>{let t=e;return r.notNull&&(t=t.notNull()),typeof r.defaultSql==`string`&&(t=t.defaultTo(d.raw(r.defaultSql))),t})}return n}const Le=P({typeName:`create_table_with_constraints`,schema:n.object({type:n.literal(`create_table_with_constraints`),table:n.string(),columns:n.record(n.string(),h),constraints:n.object({primaryKey:n.object({name:n.string(),columns:n.array(n.string()).readonly()}).optional(),unique:n.array(n.object({name:n.string(),columns:n.array(n.string()).readonly()})).readonly().optional(),foreignKeys:n.array(n.object({name:n.string(),columns:n.array(n.string()).readonly(),referencedTable:n.string(),referencedColumns:n.array(n.string()).readonly(),onDelete:v.optional(),onUpdate:v.optional(),inline:n.boolean().optional()})).readonly().optional()}).optional()}),execute:async(e,t)=>{let n=e.schema.createTable(t.table);if(n=F(n,t.columns),t.constraints){let{primaryKey:e,unique:r,foreignKeys:i}=t.constraints;if(e&&(n=n.addPrimaryKeyConstraint(e.name,e.columns)),r)for(let e of r)n=n.addUniqueConstraint(e.name,e.columns);if(i)for(let e of i)n=n.addForeignKeyConstraint(e.name,e.columns,e.referencedTable,e.referencedColumns,t=>{let n=t;return e.onDelete&&(n=n.onDelete(e.onDelete)),e.onUpdate&&(n=n.onUpdate(e.onUpdate)),n})}await n.execute()}}),Re=(e,t,n)=>({type:`create_table_with_constraints`,table:e,columns:t,constraints:{primaryKey:n?.primaryKey,unique:n?.unique??[],foreignKeys:n?.foreignKeys??[]}}),ze=P({typeName:`drop_table`,schema:n.object({type:n.literal(`drop_table`),table:n.string()}),execute:async(e,t)=>{await e.schema.dropTable(t.table).execute()}}),Be=e=>({type:`drop_table`,table:e}),Ve=P({typeName:`add_column`,schema:n.object({..._.shape,type:n.literal(`add_column`),attributes:h}),execute:async(e,t)=>{let n=t.attributes.type;N(n),await e.schema.alterTable(t.table).addColumn(t.column,n,e=>{let n=e;return t.attributes.notNull&&(n=n.notNull()),typeof t.attributes.defaultSql==`string`&&(n=n.defaultTo(d.raw(t.attributes.defaultSql))),n}).execute()}}),He=(e,t)=>({...e,type:`add_column`,attributes:t}),Ue=P({typeName:`drop_column`,schema:n.object({..._.shape,type:n.literal(`drop_column`),attributes:h}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropColumn(t.column).execute()}}),We=(e,t)=>({...e,type:`drop_column`,attributes:t}),Ge=P({typeName:`alter_column`,schema:n.object({..._.shape,type:n.literal(`alter_column`),before:h,after:h}),execute:async(e,t)=>{let{table:n,column:r,before:i,after:a}=t;if(i.type!==a.type){let t=a.type;N(t),await e.schema.alterTable(n).alterColumn(r,e=>e.setDataType(t)).execute()}a.notNull!==i.notNull&&(a.notNull?await e.schema.alterTable(n).alterColumn(r,e=>e.setNotNull()).execute():await e.schema.alterTable(n).alterColumn(r,e=>e.dropNotNull()).execute())}}),Ke=(e,t,n)=>({...e,type:`alter_column`,before:t,after:n}),qe=P({typeName:`create_index`,schema:n.object({...g.shape,type:n.literal(`create_index`),columns:n.array(n.string()).readonly(),unique:n.boolean()}),execute:async(e,t)=>{let n=e.schema.createIndex(t.name).on(t.table);for(let e of t.columns)n=n.column(e);t.unique&&(n=n.unique()),await n.execute()}}),I=e=>({...e,type:`create_index`}),Je=P({typeName:`drop_index`,schema:n.object({...g.shape,type:n.literal(`drop_index`)}),execute:async(e,t)=>{await e.schema.dropIndex(t.name).execute()}}),L=e=>({...e,type:`drop_index`}),Ye=P({typeName:`create_primary_key_constraint`,schema:n.object({...ue.shape,type:n.literal(`create_primary_key_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).addPrimaryKeyConstraint(t.name,t.columns).execute()}}),R=e=>({...e,type:`create_primary_key_constraint`}),Xe=P({typeName:`drop_primary_key_constraint`,schema:n.object({...g.shape,type:n.literal(`drop_primary_key_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}}),z=e=>({...e,type:`drop_primary_key_constraint`}),Ze=P({typeName:`create_unique_constraint`,schema:n.object({...de.shape,type:n.literal(`create_unique_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).addUniqueConstraint(t.name,t.columns).execute()}}),B=e=>({...e,type:`create_unique_constraint`}),Qe=P({typeName:`drop_unique_constraint`,schema:n.object({...g.shape,type:n.literal(`drop_unique_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}}),V=e=>({...e,type:`drop_unique_constraint`}),$e=P({typeName:`create_foreign_key_constraint`,schema:n.object({...fe.shape,type:n.literal(`create_foreign_key_constraint`)}),execute:async(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()}}),H=(e,t)=>({...e,...t,type:`create_foreign_key_constraint`}),et=P({typeName:`drop_foreign_key_constraint`,schema:n.object({...g.shape,type:n.literal(`drop_foreign_key_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}}),U=e=>({...e,type:`drop_foreign_key_constraint`}),W=[Le,Fe,ze,Ve,Ue,Ge,qe,Je,Ye,Xe,Ze,Qe,$e,et],tt=n.union(W.map(e=>e.schema));async function nt(e,t){return await rt(t.type)(e,t)}function rt(e){let t=W.find(t=>t.typeName===e);if(!t)throw Error(`Unknown operation type: ${e}`);return t.execute}const it=e=>{let t=new Set;return e.forEach(e=>{e.type===`drop_table`&&t.add(e.table)}),t.size===0?e:e.filter(e=>e.type===`drop_table`?!0:!t.has(e.table))},at=e=>{let t=new Set;if(e.forEach(e=>{e.type===`create_table`&&t.add(e.table)}),t.size===0)return e;let n=new Map,r=new Map,i=[];e.forEach(e=>{e.type===`create_table`&&n.set(e.table,e)}),e.forEach(e=>{switch(e.type){case`create_table`:return;case`create_primary_key_constraint`:case`create_unique_constraint`:if(t.has(e.table)){let t=r.get(e.table)||[];r.set(e.table,[...t,e])}else i.push(e);break;case`create_foreign_key_constraint`:if(t.has(e.table)&&e.inline!==!1){let t=n.get(e.table),i=e.columns.filter(e=>!(e in t.columns));if(i.length>0)throw Error(`Foreign key constraint "${e.name}" references non-existent columns: ${i.join(`, `)}`);let a=r.get(e.table)||[];r.set(e.table,[...a,e])}else i.push(e);break;default:i.push(e);break}});let a=[];return n.forEach((e,t)=>{let n=r.get(t)||[];if(n.length===0){a.push(e);return}let i={unique:[],foreignKeys:[]};n.forEach(e=>{switch(e.type){case`create_primary_key_constraint`:i.primaryKey=e;break;case`create_unique_constraint`:i.unique.push(e);break;case`create_foreign_key_constraint`:i.foreignKeys.push(e);break}}),a.push(Re(e.table,e.columns,i))}),[...a,...i]},ot=e=>{let t=new Set;return e.forEach(e=>{(e.type===`drop_unique_constraint`||e.type===`drop_primary_key_constraint`)&&t.add(`${e.table}.${e.name}`)}),e.filter(e=>{if(e.type===`drop_index`){let n=`${e.table}.${e.name}`;if(t.has(n))return!1}return!0})},G=e=>`table`in e?e.table:null,st=e=>{let t=new Set;return e.forEach(e=>{let n=G(e);n&&t.add(n)}),t},ct=e=>{switch(e.type){case`create_foreign_key_constraint`:return[{table:e.table,referencedTable:e.referencedTable}];case`create_table_with_constraints`:return(e.constraints?.foreignKeys||[]).map(t=>({table:e.table,referencedTable:t.referencedTable}));default:return[]}},lt=e=>{let t=new oe;return e.forEach(e=>ct(e).forEach(n=>{n.table!==n.referencedTable&&(e.type!==`create_foreign_key_constraint`||e.inline!==!1)&&t.addEdge(n.referencedTable,n.table)})),t},ut=(e,t)=>{try{let n=se(lt(t)),r=new Set(n);return[...Array.from(e).filter(e=>!r.has(e)).sort(),...n]}catch(e){throw e instanceof ae?Error(`Circular dependency detected in foreign key constraints. Please resolve this by setting 'inline: false' for one of the foreign key constraints in each circular relationship.`):e}},dt=e=>new Map(e.map((e,t)=>[e,t])),ft=e=>(t,n)=>{let r=K[t.type],i=K[n.type];if(r!==i)return r-i;let a=G(t),o=G(n);if(a&&o){let t=e.get(a)??2**53-1,n=e.get(o)??2**53-1;if(t!==n)return t-n}return(a||``).localeCompare(o||``)},K={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_with_constraints:6,create_table:7,add_column:8,alter_column:9,create_index:10,create_primary_key_constraint:11,create_unique_constraint:12,create_foreign_key_constraint:13},pt=p.pipe(it,at,ot,e=>p.sort(ft(p.pipe(st,t=>ut(t,e),dt)(e)),e)),mt=e=>({getMigrations:async()=>{let t=await e.migrationsResolver(),n={};return t.forEach(e=>{n[e.id]={up:async t=>{for(let n of pt(e.diff.operations))await nt(t,n)}}}),n}}),ht=n.object({operations:n.array(tt).readonly()}),gt=n.object({id:n.string(),version:n.string(),diff:ht}),q=`migrations`,_t=async e=>{let{fs:t}=e;try{let e=(await t.readdir(q)).filter(e=>e.endsWith(`.json`)).map(async e=>gt.parse(JSON.parse(await t.readFile(m(q,e),`utf-8`))));return await Promise.all(e)}catch(e){if(e instanceof Object&&`code`in e&&e.code===`ENOENT`)return[];throw e}},J=async e=>{let{client:t,fs:n}=e;await using r=t.getDB();let i=await _t({fs:n});if(!(await r.introspection.getTables({withInternalKyselyTables:!0})).map(e=>e.name).includes(a))return i;let o=await r.selectFrom(a).select([`name`,`timestamp`]).$narrowType().execute();return i.filter(e=>!o.some(t=>t.name===e.id))};async function Y(e,t){let{client:n,logger:r}=e,{reporter:i}=r;await using a=n.getDB({plan:t.plan});let{results:o,error:s}=await new c({db:a,provider:mt({migrationsResolver:async()=>t.plan?await J(e):await _t(e),options:{plan:t.plan}})}).migrateToLatest(),l=a.getPlannedQueries();if(l.length>0){l.forEach(e=>{r.stdout(t.pretty?ce(e.sql):e.sql)});return}if(o&&o.length>0?o.forEach(e=>{e.status===`Error`?i.error(`Migration failed: ${e.migrationName}`):e.status===`Success`&&i.success(`Migration applied: ${e.migrationName}`)}):i.info(`No migrations to run`),s)throw s instanceof Error?s:Error(`Migration error: ${s}`)}const vt=e({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{await Y(await M(),{plan:e.args.plan,pretty:e.args.pretty})}catch(e){A.reporter.error(e),process.exit(1)}}}),X=()=>({added:(e,t,n)=>p.pipe(p.difference(t),p.map(n))(e),removed:(e,t,n)=>p.pipe(p.difference(e),p.map(n))(t),changed:(e,t,n,r)=>p.pipe(p.intersection(e),p.filter(n),p.map(r))(t)}),Z=p.prop(`name`),yt=p.eqBy(e=>[e.type,e.notNull??!1,e.primaryKey??!1,e.unique??!1]);function bt(e,t){let n=[],r=X(),i=e.columns,a=t.columns,o=Object.keys(i),s=Object.keys(a);return r.added(o,s,e=>({column:e,attributes:a[e]})).forEach(t=>{n.push(He({table:e.name,column:t.column},t.attributes))}),r.removed(o,s,e=>({column:e,attributes:i[e]})).forEach(t=>{n.push(We({table:e.name,column:t.column},t.attributes))}),r.changed(o,s,e=>!yt(i[e],a[e]),e=>({column:e,before:i[e],after:a[e]})).forEach(t=>{n.push(Ke({table:e.name,column:t.column},t.before,t.after))}),n}function xt(e){let{current:t,ideal:n}=e,r=[],i=X(),a=p.map(Z,t),o=p.map(Z,n);return i.added(a,o,e=>n.find(t=>t.name===e)).forEach(e=>{r.push(Ie(e.name,e.columns))}),i.removed(a,o,p.identity).forEach(e=>{r.push(Be(e))}),p.filter(e=>n.some(t=>t.name===e.name))(t).forEach(e=>{let t=n.find(t=>t.name===e.name);r.push(...bt(e,t))}),r}function St(e){let{current:t,ideal:n}=e,r=[],i=X(),a=e=>`${e.table}:${e.name}`,o=new Map(t.map(e=>[a(e),e])),s=new Map(n.map(e=>[a(e),e])),c=Array.from(o.keys()),l=Array.from(s.keys());return i.added(c,l,e=>s.get(e)).forEach(e=>{r.push(I(e))}),i.removed(c,l,e=>{let t=o.get(e);return{table:t.table,name:t.name}}).forEach(e=>{r.push(L(e))}),i.changed(c,l,e=>{let t=o.get(e),n=s.get(e);return!p.equals(t.columns,n.columns)||t.unique!==n.unique},e=>({current:o.get(e),ideal:s.get(e)})).forEach(({current:e,ideal:t})=>{r.push(L(e)),r.push(I(t))}),r}function Ct(e){let{current:t,ideal:n}=e,r=[],i=X(),a=e=>`${e.table}:${e.name}`,o=new Map(t.map(e=>[a(e),e])),s=new Map(n.map(e=>[a(e),e])),c=Array.from(o.keys()),l=Array.from(s.keys());return i.added(c,l,e=>s.get(e)).forEach(e=>{r.push(R(e))}),i.removed(c,l,e=>{let t=o.get(e);return{table:t.table,name:t.name}}).forEach(e=>{r.push(z(e))}),i.changed(c,l,e=>{let t=o.get(e),n=s.get(e);return!p.equals(t.columns,n.columns)},e=>({current:o.get(e),ideal:s.get(e)})).forEach(({current:e,ideal:t})=>{r.push(z(e)),r.push(R(t))}),r}function wt(e){let{current:t,ideal:n}=e,r=[],i=X(),a=e=>`${e.table}:${e.name}`,o=new Map(t.map(e=>[a(e),e])),s=new Map(n.map(e=>[a(e),e])),c=Array.from(o.keys()),l=Array.from(s.keys());return i.added(c,l,e=>s.get(e)).forEach(e=>{r.push(B(e))}),i.removed(c,l,e=>{let t=o.get(e);return{table:t.table,name:t.name}}).forEach(e=>{r.push(V(e))}),i.changed(c,l,e=>{let t=o.get(e),n=s.get(e);return!p.equals(t.columns,n.columns)},e=>({current:o.get(e),ideal:s.get(e)})).forEach(({current:e,ideal:t})=>{r.push(V(e)),r.push(B(t))}),r}function Tt(e){let t=[],n=X(),r=e.current.map(Z),i=e.ideal.map(Z);return t.push(...n.added(r,i,t=>{let{table:n,name:r,...i}=e.ideal.find(e=>e.name===t);return H({table:n,name:r},i)})),t.push(...n.removed(r,i,t=>U(e.current.find(e=>e.name===t)))),t.push(...n.changed(r,i,t=>{let n=e.current.find(e=>e.name===t),r=e.ideal.find(e=>e.name===t);return!n||!r?!1:!(p.equals(n.columns,r.columns)&&n.referencedTable===r.referencedTable&&p.equals(n.referencedColumns,r.referencedColumns)&&n.onDelete===r.onDelete&&n.onUpdate===r.onUpdate)},t=>{let n=e.current.find(e=>e.name===t),{table:r,name:i,...a}=e.ideal.find(e=>e.name===t);return[U(n),H({table:r,name:i},a)]}).flat()),t}function Et(e){let t=xt({current:e.current.tables,ideal:e.ideal.tables}),n=St({current:e.current.indexes,ideal:e.ideal.indexes}),r=Ct({current:e.current.primaryKeyConstraints,ideal:e.ideal.primaryKeyConstraints}),i=wt({current:e.current.uniqueConstraints,ideal:e.ideal.uniqueConstraints}),a=Tt({current:e.current.foreignKeyConstraints,ideal:e.ideal.foreignKeyConstraints});return{operations:[...t,...n,...r,...i,...a]}}const Dt=e=>{let t=O(e.getDialect()).createIntrospectionDriver(e);return{introspect:async n=>{await using r=e.getDB();let i=await r.introspection.getTables(),{tables:a,indexes:o,constraints:s}=await t.introspect({config:n}),c=()=>i.map(e=>{let n={};for(let r of e.columns){let i=a.find(t=>t.table===e.name&&t.name===r.name);i&&(n[r.name]={schema:e.schema,table:e.name,name:r.name,dataType:t.convertTypeName(r.dataType),default:i.default??null,characterMaximumLength:i.characterMaximumLength??null,notNull:!r.isNullable})}return{schema:e.schema,name:e.name,columns:n}}),l=e=>!e.table.startsWith(`kysely_`);return{tables:c(),indexes:o.filter(l),constraints:{primaryKey:s.primaryKey.filter(l),unique:s.unique.filter(l),foreignKey:s.foreignKey.filter(l)}}}}},Q=async(e,t,n)=>{let r=O(t);return{manageType:n,instance:await r.createDevDatabaseProvider().setup(r.parseDevDatabaseConfig(e),n)}};async function Ot(e,t){let{config:n}=e,r=O(n.database.dialect);switch(t.mode){case`dev-start`:{let{instance:e,manageType:t}=await Q(n.dev,n.database.dialect,`dev-start`);return{manageType:t,manager:e,result:{reused:await e.isAvailable()}}}case`generate-dev`:{let e=await r.hasReusableDevDatabase(),{instance:t,manageType:i}=await Q(n.dev,n.database.dialect,e?`dev-start`:`one-off`);return{manageType:i,manager:t,result:{reused:e}}}}}async function kt(e,t){let{config:n}=e,{reporter:r}=t.logger||j;if(!n.dev)throw Error(`Dev database configuration is required`);let{manageType:i,manager:a,result:o}=await Ot(e,t);o.reused?r.info(`🔄 Reusing existing dev database...`):r.info(`🚀 Starting dev database...`),await a.start(),r.success(`Dev database started: ${n.database.dialect}`);let s=k({database:{dialect:n.database.dialect,connectionString:a.getConnectionString()}}),c=await J(e);return c.length>0?(r.info(`🔄 Applying ${c.length} pending migrations...`),await Y({client:s,logger:j,fs:e.fs,config:n},{plan:!1,pretty:!1}),r.success(`Applied ${c.length} migrations`)):r.info(`No pending migrations found`),{client:s,manager:a,cleanup:async()=>{switch(t.mode){case`dev-start`:r.success(`Persistent dev database ready: `+n.database.dialect);break;case`generate-dev`:i===`dev-start`?r.info(`Dev start container remains running`):(await a.stop(),r.success(`Temporary dev database stopped`));break}}}}async function At(e,t){let{logger:n,config:r,fs:i}=e,{reporter:a}=n;t.squash&&await jt(e);let{client:o,cleanup:s}=t.dev?await kt(e,{mode:`generate-dev`,logger:n}):{client:e.client,cleanup:async()=>void 0};try{if(!t.ignorePending){let n=await J(e);if(n.length>0)if(t.dev)a.info(`Dev database has ${n.length} pending migrations. These will be applied automatically as baseline.`);else{a.warn([`There are pending migrations: ${n.map(e=>e.id).join(`, `)}`,`Please apply them first before generating a new migration.`,`Otherwise, use --ignore-pending to skip this check.`].join(`
93
- `));return}}let s=await Mt({client:o,config:r});if(!s){a.info(`No changes detected, no migration needed.`);return}Nt(n,s.diff);let c=`${q}/${s.id}.json`;await i.mkdir(q,{recursive:!0}),await i.writeFile(c,JSON.stringify(s,null,2));let l=t.squash?`Generated squashed migration: ${c}`:`Migration file generated: ${c}`;a.success(l),t.dev&&await Y({...e,client:o},{plan:!1,pretty:!1})}finally{await s()}}const jt=async e=>{let{logger:t,fs:n}=e,{reporter:r}=t,i=await J(e);if(i.length===0){r.info(`No pending migrations found, nothing to squash.`);return}r.info(`Found ${i.length} pending migrations to squash:`),i.forEach(e=>{r.info(` - ${e.id}.json`)});let a=i.map(e=>m(q,`${e.id}.json`));try{await Promise.all(a.map(e=>n.unlink(e))),r.success(`🗑️ Removed ${a.length} pending migration files`)}catch(e){throw Error(`Failed to remove pending migration files: ${e}`)}},Mt=async e=>{let{client:t,config:n}=e,{tables:r,indexes:i,constraints:a}=await Dt(t).introspect(n),o=(e,t)=>n=>n.some(n=>n.table===e&&n.columns.length===1&&n.columns[0]===t),s=r.map(e=>({name:e.name,columns:Object.fromEntries(Object.entries(e.columns).map(([t,n])=>{let r=o(e.name,t),i=r(a.primaryKey),s=r(a.unique),c=a.primaryKey.some(n=>n.table===e.name&&n.columns.length>1&&n.columns.includes(t))?!0:n.notNull;return[t,{type:n.dataType,notNull:c,defaultSql:n.default??void 0,primaryKey:i,unique:s}]}))})),c=n.tables.map(e=>({name:e.tableName,columns:Object.fromEntries(Object.entries(e.columns).map(([t,r])=>{let i=(n.primaryKeyConstraints??[]).some(n=>n.table===e.tableName&&n.columns.includes(t)),a=r.primaryKey||r.notNull||i;return[t,{...r,notNull:a}]}))})),l=Et({current:{tables:s,indexes:i,uniqueConstraints:a.unique,primaryKeyConstraints:a.primaryKey,foreignKeyConstraints:a.foreignKey},ideal:{...n,tables:c}});return l.operations.length===0?null:{version:`1`,id:Date.now()+``,diff:l}},Nt=(e,t)=>{let n=[];t.operations.forEach(e=>{switch(e.type){case`create_table`:n.push(`-- create_table: ${e.table}`),Object.entries(e.columns).forEach(([e,t])=>{n.push(` -> column: ${e} (${JSON.stringify(t)})`)});break;case`drop_table`:n.push(`-- remove_table: ${e.table}`);break;case`add_column`:n.push([`-- add_column: ${e.table}.${e.column}`,` -> to: ${JSON.stringify(e.attributes)}`].join(`
92
+ `.$castTo().execute(e);return{primaryKey:t.filter(e=>e.type===`PRIMARY KEY`),unique:t.filter(e=>e.type===`UNIQUE`),foreignKey:t.filter(e=>e.type===`FOREIGN KEY`).map(e=>{let{referenced_table:t,referenced_columns:n,on_delete:r,on_update:i,...a}=e;return{...a,referencedTable:t,referencedColumns:n,onDelete:r,onUpdate:i}})}};var Pe=class{getName(){return`cockroachdb`}createKyselyDialect(e){return new Ie({pool:new p({connectionString:e})})}createIntrospectionDriver(e){let t=[`rowid`];return{convertTypeName:D,introspect:async n=>{let r=await E(e)(n);return{tables:r.tables.filter(e=>!t.includes(e.name)),indexes:r.indexes,constraints:r.constraints}}}}createDevDatabaseProvider(){return new S(this.getName(),e=>new se(e))}parseDevDatabaseConfig(e){return x({defaultImage:`cockroachdb/cockroach:latest-v24.3`}).parse(e)}async hasReusableDevDatabase(){return C(this.getName())}},Fe=class extends re{async acquireMigrationLock(e,t){await e.selectFrom(t.lockTable).selectAll().forUpdate().execute()}},Ie=class extends d{createAdapter(){return new Fe}},Le=class{getName(){return`sqlite`}createKyselyDialect(e){return new ie({database:new ce(e)})}createIntrospectionDriver(e){return{convertTypeName:ze,introspect:Re(e)}}createDevDatabaseProvider(){return new ye}parseDevDatabaseConfig(e){return T().parse(e)}async hasReusableDevDatabase(){return!1}};const Re=e=>async t=>{await using n=e.getDB();let[r,i,a]=await Promise.all([Be(n),Ve(n),He(n)]),{indexes:o,uniqueConstraints:s}=ke(t.config,{indexes:i,constraints:a});return{tables:r,indexes:o,constraints:{...a,unique:s}}},ze=e=>{let t={INTEGER:`integer`,TEXT:`text`,REAL:`real`,BLOB:`blob`,NUMERIC:`numeric`,INT8:`bigint`,BOOLEAN:`boolean`,VARCHAR:`varchar`,CHAR:`char`,UUID:`uuid`},n=e.match(/^(varchar|char)\((\d+)\)$/i);if(n)return n[1].toLowerCase();let r=e.toUpperCase();return t[r]?t[r]:e.toLowerCase()},Be=async e=>{let{rows:t}=await f`
93
+ SELECT name FROM sqlite_master
94
+ WHERE type = 'table'
95
+ AND name NOT LIKE 'sqlite_%'
96
+ AND name != 'kysely_migration'
97
+ AND name != 'kysely_migration_lock'
98
+ `.$castTo().execute(e),n=[];for(let r of t){let{rows:t}=await f`
99
+ SELECT * FROM pragma_table_info(${r.name})
100
+ `.$castTo().execute(e);n.push(...t.map(e=>{let t=null,n=e.type.match(/^(?:varchar|char)\((\d+)\)$/i);return n&&(t=parseInt(n[1],10)),{schema:`public`,table:r.name,name:e.name,default:e.dflt_value,characterMaximumLength:t}}))}return n},Ve=async e=>{let{rows:t}=await f`
101
+ SELECT name FROM sqlite_master
102
+ WHERE type = 'table'
103
+ AND name NOT LIKE 'sqlite_%'
104
+ AND name != 'kysely_migration'
105
+ AND name != 'kysely_migration_lock'
106
+ `.$castTo().execute(e),n=[];for(let r of t){let{rows:t}=await f`
107
+ SELECT * FROM pragma_index_list(${r.name})
108
+ `.$castTo().execute(e);for(let i of t)if(i.origin===`c`){let{rows:t}=await f`
109
+ SELECT * FROM pragma_index_info(${i.name})
110
+ `.$castTo().execute(e);n.push({table:r.name,name:i.name,columns:t.map(e=>e.name),unique:i.unique===1})}}return n.sort((e,t)=>e.table===t.table?e.name.localeCompare(t.name):e.table.localeCompare(t.table))},He=async t=>{let{rows:n}=await f`
111
+ SELECT name, sql FROM sqlite_master
112
+ WHERE type = 'table'
113
+ AND name NOT LIKE 'sqlite_%'
114
+ AND name != 'kysely_migration'
115
+ AND name != 'kysely_migration_lock'
116
+ `.$castTo().execute(t),r=[],i=[],a=[];for(let o of n){let{rows:n}=await f`
117
+ SELECT * FROM pragma_table_info(${o.name})
118
+ `.$castTo().execute(t),s=n.filter(e=>e.pk>0).sort((e,t)=>e.pk-t.pk).map(e=>e.name);s.length>0&&r.push({schema:`public`,table:o.name,name:e(o.name,s),type:`PRIMARY KEY`,columns:s,on_delete:null,on_update:null,referenced_columns:null,referenced_table:null});let{rows:c}=await f`
119
+ SELECT * FROM pragma_foreign_key_list(${o.name})
120
+ `.$castTo().execute(t),l=c.reduce((e,t)=>(e[t.id]||(e[t.id]=[]),e[t.id].push(t),e),{});Object.entries(l).forEach(([,e])=>{let t=e.map(e=>e.from),n=e.length>0&&e[0].from?`fk_${e[0].from}`:`fk_${o.name}_${e[0].table}`;a.push({schema:`public`,table:o.name,name:n,type:`FOREIGN KEY`,columns:t,referencedTable:e[0].table,referencedColumns:e.map(e=>e.to),onDelete:Ue(e[0].on_delete),onUpdate:Ue(e[0].on_update)})});let{rows:u}=await f`
121
+ SELECT * FROM pragma_index_list(${o.name})
122
+ `.$castTo().execute(t);for(let e of u)if(e.unique===1&&e.origin===`u`){let{rows:n}=await f`
123
+ SELECT * FROM pragma_index_info(${e.name})
124
+ `.$castTo().execute(t),r=n.map(e=>e.name),a=r.length===1?`${o.name}_${r[0]}_unique`:`uq_${o.name}_${r.join(`_`)}`;i.push({schema:`public`,table:o.name,name:a,type:`UNIQUE`,columns:r,on_delete:null,on_update:null,referenced_columns:null,referenced_table:null})}}return{primaryKey:r.sort((e,t)=>e.table===t.table?e.name.localeCompare(t.name):e.table.localeCompare(t.table)),unique:i.sort((e,t)=>e.table===t.table?e.name.localeCompare(t.name):e.table.localeCompare(t.table)),foreignKey:a.sort((e,t)=>e.table===t.table?e.name.localeCompare(t.name):e.table.localeCompare(t.table))}},Ue=e=>({CASCADE:`cascade`,"SET NULL":`set null`,"SET DEFAULT":`set default`,RESTRICT:`restrict`,"NO ACTION":`no action`})[e.toUpperCase()],We={postgres:new Ae,cockroachdb:new Pe,sqlite:new Le},O=e=>{let t=We[e];if(!t)throw Error(`Unsupported dialect: ${e}`);return t};var Ge=class extends ee{constructor(e){super(),this.queries=e}async acquireConnection(){return new Ke(this.queries)}},Ke=class{constructor(e){this.queries=e}async executeQuery(e){let t=e.query.kind;if(t===`CreateTableNode`||t===`DropTableNode`||t===`AlterTableNode`){if(e.query.table.table.identifier.name.startsWith(`kysely_`))return{rows:[]};this.queries.push(e)}else(t===`CreateIndexNode`||t===`DropIndexNode`)&&this.queries.push(e);return{rows:[]}}async*streamQuery(){}};const qe=e=>new Je({databaseProps:e.database,options:e.options});var Je=class{constructor(e){this.constructorProps=e}getDB(e){let t=O(this.constructorProps.databaseProps.dialect).createKyselyDialect(this.constructorProps.databaseProps.connectionString);return new Ye({dialect:{createAdapter:()=>t.createAdapter(),createDriver:()=>t.createDriver(),createIntrospector:e=>t.createIntrospector(e),createQueryCompiler:()=>t.createQueryCompiler()}},{isPlan:e?.plan===!0})}getDialect(){return this.constructorProps.databaseProps.dialect}},Ye=class extends te{constructor(e,t){let n=[];super({dialect:{...e.dialect,createDriver:()=>t.isPlan?new Ge(n):e.dialect.createDriver()}}),this.plannedQueries=[],this.plannedQueries=n}getPlannedQueries(){return this.plannedQueries}};const k={stdout:e=>console.log(e),reporter:{...le({stdout:process.stderr})}},A={stdout:()=>void 0,reporter:{info:()=>void 0,warn:()=>void 0,success:()=>void 0,log:()=>void 0,error:()=>void 0}};async function j(){let e=await Oe();return{client:qe({database:e.database}),logger:k,fs:o,config:e}}const M=e=>{if(!ae(e))throw Error(`Unsupported data type: ${e}`)},N=e=>e,Xe=N({typeName:`create_table`,schema:r.object({type:r.literal(`create_table`),table:r.string(),columns:r.record(r.string(),h)}),execute:async(e,t)=>{let n=e.schema.createTable(t.table);n=P(n,t.columns),await n.execute()}}),Ze=(e,t)=>({type:`create_table`,table:e,columns:t});function P(e,t){let n=e;for(let[e,r]of Object.entries(t)){let t=r.type;M(t),n=n.addColumn(e,t,e=>{let t=e;return r.notNull&&(t=t.notNull()),typeof r.defaultSql==`string`&&(t=t.defaultTo(f.raw(r.defaultSql))),t})}return n}const Qe=N({typeName:`create_table_with_constraints`,schema:r.object({type:r.literal(`create_table_with_constraints`),table:r.string(),columns:r.record(r.string(),h),constraints:r.object({primaryKey:r.object({name:r.string(),columns:r.array(r.string()).readonly()}).optional(),unique:r.array(r.object({name:r.string(),columns:r.array(r.string()).readonly()})).readonly().optional(),foreignKeys:r.array(r.object({name:r.string(),columns:r.array(r.string()).readonly(),referencedTable:r.string(),referencedColumns:r.array(r.string()).readonly(),onDelete:y.optional(),onUpdate:y.optional(),inline:r.boolean().optional()})).readonly().optional()}).optional()}),execute:async(e,t)=>{let n=e.schema.createTable(t.table);if(n=P(n,t.columns),t.constraints){let{primaryKey:e,unique:r,foreignKeys:i}=t.constraints;if(e&&(n=n.addPrimaryKeyConstraint(e.name,e.columns)),r)for(let e of r)n=n.addUniqueConstraint(e.name,e.columns);if(i)for(let e of i)n=n.addForeignKeyConstraint(e.name,e.columns,e.referencedTable,e.referencedColumns,t=>{let n=t;return e.onDelete&&(n=n.onDelete(e.onDelete)),e.onUpdate&&(n=n.onUpdate(e.onUpdate)),n})}await n.execute()}}),$e=(e,t,n)=>({type:`create_table_with_constraints`,table:e,columns:t,constraints:{primaryKey:n?.primaryKey,unique:n?.unique??[],foreignKeys:n?.foreignKeys??[]}}),et=N({typeName:`drop_table`,schema:r.object({type:r.literal(`drop_table`),table:r.string()}),execute:async(e,t)=>{await e.schema.dropTable(t.table).execute()}}),tt=e=>({type:`drop_table`,table:e}),nt=N({typeName:`add_column`,schema:r.object({..._.shape,type:r.literal(`add_column`),attributes:h}),execute:async(e,t)=>{let n=t.attributes.type;M(n),await e.schema.alterTable(t.table).addColumn(t.column,n,e=>{let n=e;return t.attributes.notNull&&(n=n.notNull()),typeof t.attributes.defaultSql==`string`&&(n=n.defaultTo(f.raw(t.attributes.defaultSql))),n}).execute()}}),rt=(e,t)=>({...e,type:`add_column`,attributes:t}),it=N({typeName:`drop_column`,schema:r.object({..._.shape,type:r.literal(`drop_column`),attributes:h}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropColumn(t.column).execute()}}),at=(e,t)=>({...e,type:`drop_column`,attributes:t}),ot=N({typeName:`alter_column`,schema:r.object({..._.shape,type:r.literal(`alter_column`),before:h,after:h}),execute:async(e,t)=>{let{table:n,column:r,before:i,after:a}=t;if(i.type!==a.type){let t=a.type;M(t),await e.schema.alterTable(n).alterColumn(r,e=>e.setDataType(t)).execute()}a.notNull!==i.notNull&&(a.notNull?await e.schema.alterTable(n).alterColumn(r,e=>e.setNotNull()).execute():await e.schema.alterTable(n).alterColumn(r,e=>e.dropNotNull()).execute())}}),st=(e,t,n)=>({...e,type:`alter_column`,before:t,after:n}),ct=N({typeName:`create_index`,schema:r.object({...g.shape,type:r.literal(`create_index`),columns:r.array(r.string()).readonly(),unique:r.boolean()}),execute:async(e,t)=>{let n=e.schema.createIndex(t.name).on(t.table);for(let e of t.columns)n=n.column(e);t.unique&&(n=n.unique()),await n.execute()}}),F=e=>({...e,type:`create_index`}),lt=N({typeName:`drop_index`,schema:r.object({...g.shape,type:r.literal(`drop_index`)}),execute:async(e,t)=>{await e.schema.dropIndex(t.name).execute()}}),I=e=>({...e,type:`drop_index`}),ut=N({typeName:`create_primary_key_constraint`,schema:r.object({...he.shape,type:r.literal(`create_primary_key_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).addPrimaryKeyConstraint(t.name,t.columns).execute()}}),L=e=>({...e,type:`create_primary_key_constraint`}),dt=N({typeName:`drop_primary_key_constraint`,schema:r.object({...g.shape,type:r.literal(`drop_primary_key_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}}),R=e=>({...e,type:`drop_primary_key_constraint`}),ft=N({typeName:`create_unique_constraint`,schema:r.object({...v.shape,type:r.literal(`create_unique_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).addUniqueConstraint(t.name,t.columns).execute()}}),z=e=>({...e,type:`create_unique_constraint`}),pt=N({typeName:`drop_unique_constraint`,schema:r.object({...g.shape,type:r.literal(`drop_unique_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}}),B=e=>({...e,type:`drop_unique_constraint`}),mt=N({typeName:`create_foreign_key_constraint`,schema:r.object({...b.shape,type:r.literal(`create_foreign_key_constraint`)}),execute:async(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()}}),V=(e,t)=>({...e,...t,type:`create_foreign_key_constraint`}),ht=N({typeName:`drop_foreign_key_constraint`,schema:r.object({...g.shape,type:r.literal(`drop_foreign_key_constraint`)}),execute:async(e,t)=>{await e.schema.alterTable(t.table).dropConstraint(t.name).execute()}}),H=e=>({...e,type:`drop_foreign_key_constraint`}),U=[Qe,Xe,et,nt,it,ot,ct,lt,ut,dt,ft,pt,mt,ht],gt=r.union(U.map(e=>e.schema));async function _t(e,t){return await vt(t.type)(e,t)}function vt(e){let t=U.find(t=>t.typeName===e);if(!t)throw Error(`Unknown operation type: ${e}`);return t.execute}const yt=e=>{let t=/* @__PURE__ */ new Set;return e.forEach(e=>{e.type===`drop_table`&&t.add(e.table)}),t.size===0?e:e.filter(e=>e.type===`drop_table`||!t.has(e.table))},bt=e=>{let t=/* @__PURE__ */ new Set;if(e.forEach(e=>{e.type===`create_table`&&t.add(e.table)}),t.size===0)return e;let n=/* @__PURE__ */ new Map,r=/* @__PURE__ */ new Map,i=[];e.forEach(e=>{e.type===`create_table`&&n.set(e.table,e)}),e.forEach(e=>{switch(e.type){case`create_table`:return;case`create_primary_key_constraint`:case`create_unique_constraint`:if(t.has(e.table)){let t=r.get(e.table)||[];r.set(e.table,[...t,e])}else i.push(e);break;case`create_foreign_key_constraint`:if(t.has(e.table)&&e.inline!==!1){let t=n.get(e.table),i=e.columns.filter(e=>!(e in t.columns));if(i.length>0)throw Error(`Foreign key constraint "${e.name}" references non-existent columns: ${i.join(`, `)}`);let a=r.get(e.table)||[];r.set(e.table,[...a,e])}else i.push(e);break;default:i.push(e)}});let a=[];return n.forEach((e,t)=>{let n=r.get(t)||[];if(n.length===0){a.push(e);return}let i={unique:[],foreignKeys:[]};n.forEach(e=>{switch(e.type){case`create_primary_key_constraint`:i.primaryKey=e;break;case`create_unique_constraint`:i.unique.push(e);break;case`create_foreign_key_constraint`:i.foreignKeys.push(e)}}),a.push($e(e.table,e.columns,i))}),[...a,...i]},xt=e=>{let t=/* @__PURE__ */ new Set;return e.forEach(e=>{(e.type===`drop_unique_constraint`||e.type===`drop_primary_key_constraint`)&&t.add(`${e.table}.${e.name}`)}),e.filter(e=>{if(e.type===`drop_index`){let n=`${e.table}.${e.name}`;if(t.has(n))return!1}return!0})},W=e=>`table`in e?e.table:null,St=e=>{let t=/* @__PURE__ */ new Set;return e.forEach(e=>{let n=W(e);n&&t.add(n)}),t},Ct=e=>{switch(e.type){case`create_foreign_key_constraint`:return[{table:e.table,referencedTable:e.referencedTable}];case`create_table_with_constraints`:return(e.constraints?.foreignKeys||[]).map(t=>({table:e.table,referencedTable:t.referencedTable}));default:return[]}},wt=e=>{let t=new de;return e.forEach(e=>Ct(e).forEach(n=>{n.table!==n.referencedTable&&(e.type!==`create_foreign_key_constraint`||e.inline!==!1)&&t.addEdge(n.referencedTable,n.table)})),t},Tt=(e,t)=>{try{let n=wt(t),r=fe(n),i=new Set(r);return[...Array.from(e).filter(e=>!i.has(e)).sort(),...r]}catch(e){throw e instanceof ue?Error(`Circular dependency detected in foreign key constraints. Please resolve this by setting 'inline: false' for one of the foreign key constraints in each circular relationship.`):e}},Et=e=>new Map(e.map((e,t)=>[e,t])),Dt=e=>(t,n)=>{let r=G[t.type],i=G[n.type];if(r!==i)return r-i;let a=W(t),o=W(n);if(a&&o){let t=e.get(a)??2**53-1,n=e.get(o)??2**53-1;if(t!==n)return t-n}return(a||``).localeCompare(o||``)},G={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_with_constraints:6,create_table:7,add_column:8,alter_column:9,create_index:10,create_primary_key_constraint:11,create_unique_constraint:12,create_foreign_key_constraint:13},Ot=m.pipe(yt,bt,xt,e=>m.sort(Dt(m.pipe(St,t=>Tt(t,e),Et)(e)),e)),kt=e=>({getMigrations:async()=>{let t=await e.migrationsResolver(),n={};return t.forEach(e=>{n[e.id]={up:async t=>{for(let n of Ot(e.diff.operations))await _t(t,n)}}}),n}}),At=r.object({operations:r.array(gt).readonly()}),jt=r.object({id:r.string(),version:r.string(),diff:At}),K=`migrations`,q=async e=>{let{fs:t}=e;try{let e=(await t.readdir(K)).filter(e=>e.endsWith(`.json`)).map(async e=>jt.parse(JSON.parse(await t.readFile(c(K,e),`utf-8`))));return await Promise.all(e)}catch(e){if(e instanceof Object&&`code`in e&&e.code===`ENOENT`)return[];throw e}},J=async e=>{let{client:t,fs:n}=e;await using r=t.getDB();let i=await q({fs:n});if(!(await r.introspection.getTables({withInternalKyselyTables:!0})).map(e=>e.name).includes(u))return i;let a=await r.selectFrom(u).select([`name`,`timestamp`]).$narrowType().execute();return i.filter(e=>!a.some(t=>t.name===e.id))};async function Y(e,t){let{client:n,logger:r}=e,{reporter:i}=r;await using a=n.getDB({plan:t.plan});let o=kt({migrationsResolver:async()=>t.plan?await J(e):await q(e),options:{plan:t.plan}}),{results:s,error:c}=await new ne({db:a,provider:o}).migrateToLatest(),l=a.getPlannedQueries();if(l.length>0){l.forEach(e=>{r.stdout(t.pretty?pe(e.sql):e.sql)});return}if(s&&s.length>0?s.forEach(e=>{e.status===`Error`?i.error(`Migration failed: ${e.migrationName}`):e.status===`Success`&&i.success(`Migration applied: ${e.migrationName}`)}):i.info(`No migrations to run`),c)throw c instanceof Error?c:Error(`Migration error: ${c}`)}const Mt=t({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{await Y(await j(),{plan:e.args.plan,pretty:e.args.pretty})}catch(e){k.reporter.error(e),process.exit(1)}}}),X=()=>({added:(e,t,n)=>m.pipe(m.difference(t),m.map(n))(e),removed:(e,t,n)=>m.pipe(m.difference(e),m.map(n))(t),changed:(e,t,n,r)=>m.pipe(m.intersection(e),m.filter(n),m.map(r))(t)}),Z=m.prop(`name`),Nt=m.eqBy(e=>[e.type,e.notNull??!1,e.primaryKey??!1,e.unique??!1]);function Pt(e,t){let n=[],r=X(),i=e.columns,a=t.columns,o=Object.keys(i),s=Object.keys(a);return r.added(o,s,e=>({column:e,attributes:a[e]})).forEach(t=>{n.push(rt({table:e.name,column:t.column},t.attributes))}),r.removed(o,s,e=>({column:e,attributes:i[e]})).forEach(t=>{n.push(at({table:e.name,column:t.column},t.attributes))}),r.changed(o,s,e=>!Nt(i[e],a[e]),e=>({column:e,before:i[e],after:a[e]})).forEach(t=>{n.push(st({table:e.name,column:t.column},t.before,t.after))}),n}function Ft(e){let{current:t,ideal:n}=e,r=[],i=X(),a=m.map(Z,t),o=m.map(Z,n);return i.added(a,o,e=>n.find(t=>t.name===e)).forEach(e=>{r.push(Ze(e.name,e.columns))}),i.removed(a,o,m.identity).forEach(e=>{r.push(tt(e))}),m.filter(e=>n.some(t=>t.name===e.name))(t).forEach(e=>{let t=n.find(t=>t.name===e.name);r.push(...Pt(e,t))}),r}function It(e){let{current:t,ideal:n}=e,r=[],i=X(),a=e=>`${e.table}:${e.name}`,o=new Map(t.map(e=>[a(e),e])),s=new Map(n.map(e=>[a(e),e])),c=Array.from(o.keys()),l=Array.from(s.keys());return i.added(c,l,e=>s.get(e)).forEach(e=>{r.push(F(e))}),i.removed(c,l,e=>{let t=o.get(e);return{table:t.table,name:t.name}}).forEach(e=>{r.push(I(e))}),i.changed(c,l,e=>{let t=o.get(e),n=s.get(e);return!m.equals(t.columns,n.columns)||t.unique!==n.unique},e=>({current:o.get(e),ideal:s.get(e)})).forEach(({current:e,ideal:t})=>{r.push(I(e)),r.push(F(t))}),r}function Lt(e){let{current:t,ideal:n}=e,r=[],i=X(),a=e=>`${e.table}:${e.name}`,o=new Map(t.map(e=>[a(e),e])),s=new Map(n.map(e=>[a(e),e])),c=Array.from(o.keys()),l=Array.from(s.keys());return i.added(c,l,e=>s.get(e)).forEach(e=>{r.push(L(e))}),i.removed(c,l,e=>{let t=o.get(e);return{table:t.table,name:t.name}}).forEach(e=>{r.push(R(e))}),i.changed(c,l,e=>{let t=o.get(e),n=s.get(e);return!m.equals(t.columns,n.columns)},e=>({current:o.get(e),ideal:s.get(e)})).forEach(({current:e,ideal:t})=>{r.push(R(e)),r.push(L(t))}),r}function Rt(e){let{current:t,ideal:n}=e,r=[],i=X(),a=e=>`${e.table}:${e.name}`,o=new Map(t.map(e=>[a(e),e])),s=new Map(n.map(e=>[a(e),e])),c=Array.from(o.keys()),l=Array.from(s.keys());return i.added(c,l,e=>s.get(e)).forEach(e=>{r.push(z(e))}),i.removed(c,l,e=>{let t=o.get(e);return{table:t.table,name:t.name}}).forEach(e=>{r.push(B(e))}),i.changed(c,l,e=>{let t=o.get(e),n=s.get(e);return!m.equals(t.columns,n.columns)},e=>({current:o.get(e),ideal:s.get(e)})).forEach(({current:e,ideal:t})=>{r.push(B(e)),r.push(z(t))}),r}function zt(e){let t=[],n=X(),r=e.current.map(Z),i=e.ideal.map(Z);return t.push(...n.added(r,i,t=>{let{table:n,name:r,...i}=e.ideal.find(e=>e.name===t);return V({table:n,name:r},i)})),t.push(...n.removed(r,i,t=>{let n=e.current.find(e=>e.name===t);return H(n)})),t.push(...n.changed(r,i,t=>{let n=e.current.find(e=>e.name===t),r=e.ideal.find(e=>e.name===t);return!n||!r?!1:!(m.equals(n.columns,r.columns)&&n.referencedTable===r.referencedTable&&m.equals(n.referencedColumns,r.referencedColumns)&&n.onDelete===r.onDelete&&n.onUpdate===r.onUpdate)},t=>{let n=e.current.find(e=>e.name===t),{table:r,name:i,...a}=e.ideal.find(e=>e.name===t);return[H(n),V({table:r,name:i},a)]}).flat()),t}function Bt(e){let t=Ft({current:e.current.tables,ideal:e.ideal.tables}),n=It({current:e.current.indexes,ideal:e.ideal.indexes}),r=Lt({current:e.current.primaryKeyConstraints,ideal:e.ideal.primaryKeyConstraints}),i=Rt({current:e.current.uniqueConstraints,ideal:e.ideal.uniqueConstraints}),a=zt({current:e.current.foreignKeyConstraints,ideal:e.ideal.foreignKeyConstraints});return{operations:[...t,...n,...r,...i,...a]}}const Vt=e=>{let t=O(e.getDialect()).createIntrospectionDriver(e);return{introspect:async n=>{await using r=e.getDB();let i=await r.introspection.getTables(),{tables:a,indexes:o,constraints:s}=await t.introspect({config:n}),c=/* @__PURE__ */ new Set;for(let e of s.primaryKey)for(let t of e.columns)c.add(`${e.table}.${t}`);let l=()=>i.map(e=>{let n={};for(let r of e.columns){let i=a.find(t=>t.table===e.name&&t.name===r.name);if(!i)continue;let o=c.has(`${e.name}.${r.name}`);n[r.name]={schema:e.schema??`public`,table:e.name,name:r.name,dataType:t.convertTypeName(r.dataType),default:i.default??null,characterMaximumLength:i.characterMaximumLength??null,notNull:!r.isNullable||o}}return{schema:e.schema??`public`,name:e.name,columns:n}}),u=e=>!e.table.startsWith(`kysely_`);return{tables:l(),indexes:o.filter(u),constraints:{primaryKey:s.primaryKey.filter(u),unique:s.unique.filter(u),foreignKey:s.foreignKey.filter(u)}}}}},Q=async(e,t,n)=>{let r=O(t);return{manageType:n,instance:await r.createDevDatabaseProvider().setup(r.parseDevDatabaseConfig(e),n)}};async function Ht(e,t){let{config:n}=e,r=O(n.database.dialect);switch(t.mode){case`dev-start`:{let e=await r.hasReusableDevDatabase(),{instance:t,manageType:i}=await Q(n.dev,n.database.dialect,`dev-start`);return{manageType:i,manager:t,result:{reused:e}}}case`generate-dev`:{let e=await r.hasReusableDevDatabase(),{instance:t,manageType:i}=await Q(n.dev,n.database.dialect,e?`dev-start`:`one-off`);return{manageType:i,manager:t,result:{reused:e}}}}}async function Ut(e,t){let{config:n}=e,{reporter:r}=t.logger||A;if(!n.dev)throw Error(`Dev database configuration is required`);let{manageType:i,manager:a,result:o}=await Ht(e,t);o.reused?r.info(`🔄 Reusing existing dev database...`):r.info(`🚀 Starting dev database...`),await a.start(),r.success(`Dev database started: ${n.database.dialect}`);let s=qe({database:{dialect:n.database.dialect,connectionString:a.getConnectionString()}}),c=await J(e);return c.length>0?(r.info(`🔄 Applying ${c.length} pending migrations...`),await Y({client:s,logger:A,fs:e.fs,config:n},{plan:!1,pretty:!1}),r.success(`Applied ${c.length} migrations`)):r.info(`No pending migrations found`),{client:s,manager:a,cleanup:async()=>{switch(t.mode){case`dev-start`:r.success(`Persistent dev database ready: `+n.database.dialect);break;case`generate-dev`:i===`dev-start`?r.info(`Dev start container remains running`):(await a.stop(),r.success(`Temporary dev database stopped`))}}}}async function Wt(e,t){let{logger:n,config:r,fs:i}=e,{reporter:a}=n;t.squash&&await Gt(e);let{client:o,cleanup:s}=t.dev?await Ut(e,{mode:`generate-dev`,logger:n}):{client:e.client,cleanup:async()=>void 0};try{if(!t.ignorePending){let n=await J(e);if(n.length>0){if(t.dev)a.info(`Dev database has ${n.length} pending migrations. These will be applied automatically as baseline.`);else{a.warn([`There are pending migrations: ${n.map(e=>e.id).join(`, `)}`,`Please apply them first before generating a new migration.`,`Otherwise, use --ignore-pending to skip this check.`].join(`
125
+ `));return}}}let s=await Kt({client:o,config:r});if(!s){a.info(`No changes detected, no migration needed.`);return}qt(n,s.diff);let c=`${K}/${s.id}.json`;await i.mkdir(K,{recursive:!0}),await i.writeFile(c,JSON.stringify(s,null,2));let l=t.squash?`Generated squashed migration: ${c}`:`Migration file generated: ${c}`;a.success(l),t.dev&&await Y({...e,client:o},{plan:!1,pretty:!1})}finally{await s()}}const Gt=async e=>{let{logger:t,fs:n}=e,{reporter:r}=t,i=await J(e);if(i.length===0){r.info(`No pending migrations found, nothing to squash.`);return}r.info(`Found ${i.length} pending migrations to squash:`),i.forEach(e=>{r.info(` - ${e.id}.json`)});let a=i.map(e=>c(K,`${e.id}.json`));try{await Promise.all(a.map(e=>n.unlink(e))),r.success(`🗑️ Removed ${a.length} pending migration files`)}catch(e){throw Error(`Failed to remove pending migration files: ${e}`)}},Kt=async e=>{let{client:t,config:n}=e,{tables:r,indexes:i,constraints:a}=await Vt(t).introspect(n),o=(e,t)=>n=>n.some(n=>n.table===e&&n.columns.length===1&&n.columns[0]===t),s=r.map(e=>({name:e.name,columns:Object.fromEntries(Object.entries(e.columns).map(([t,n])=>{let r=o(e.name,t),i=r(a.primaryKey),s=r(a.unique),c=a.primaryKey.some(n=>n.table===e.name&&n.columns.length>1&&n.columns.includes(t))?!0:n.notNull;return[t,{type:n.dataType,notNull:c,defaultSql:n.default??void 0,primaryKey:i,unique:s}]}))})),c=n.tables.map(e=>({name:e.tableName,columns:Object.fromEntries(Object.entries(e.columns).map(([t,r])=>{let i=(n.primaryKeyConstraints??[]).some(n=>n.table===e.tableName&&n.columns.includes(t)),a=r.primaryKey||r.notNull||i;return[t,{...r,notNull:a}]}))})),l=Bt({current:{tables:s,indexes:i,uniqueConstraints:a.unique,primaryKeyConstraints:a.primaryKey,foreignKeyConstraints:a.foreignKey},ideal:{...n,tables:c}});return l.operations.length===0?null:{version:`1`,id:Date.now()+``,diff:l}},qt=(e,t)=>{let n=[];t.operations.forEach(e=>{switch(e.type){case`create_table`:n.push(`-- create_table: ${e.table}`),Object.entries(e.columns).forEach(([e,t])=>{n.push(` -> column: ${e} (${JSON.stringify(t)})`)});break;case`drop_table`:n.push(`-- remove_table: ${e.table}`);break;case`add_column`:n.push([`-- add_column: ${e.table}.${e.column}`,` -> to: ${JSON.stringify(e.attributes)}`].join(`
94
126
  `));break;case`drop_column`:n.push(`-- remove_column: ${e.table}.${e.column}`);break;case`alter_column`:n.push([`-- change_column: ${e.table}.${e.column}`,` -> from: ${JSON.stringify(e.before)}`,` -> to: ${JSON.stringify(e.after)}`].join(`
95
- `));break;case`create_index`:n.push(`-- create_index: ${e.table}.${e.name} (${e.columns.join(`, `)})${e.unique?` [unique]`:``}`);break;case`drop_index`:n.push(`-- drop_index: ${e.table}.${e.name}`);break;case`create_primary_key_constraint`:n.push(`-- create_primary_key_constraint: ${e.table}.${e.name} (${e.columns.join(`, `)})`);break;case`drop_primary_key_constraint`:n.push(`-- drop_primary_key_constraint: ${e.table}.${e.name}`);break;case`create_unique_constraint`:n.push(`-- create_unique_constraint: ${e.table}.${e.name} (${e.columns.join(`, `)})`);break;case`drop_unique_constraint`:n.push(`-- drop_unique_constraint: ${e.table}.${e.name}`);break;case`create_foreign_key_constraint`:n.push(`-- create_foreign_key_constraint: ${e.table}.${e.name} (${e.columns.join(`, `)}) -> ${e.referencedTable} (${e.referencedColumns.join(`, `)})${e.onDelete?` ON DELETE ${e.onDelete.toUpperCase()}`:``}${e.onUpdate?` ON UPDATE ${e.onUpdate.toUpperCase()}`:``}`);break;case`drop_foreign_key_constraint`:n.push(`-- drop_foreign_key_constraint: ${e.table}.${e.name}`);break;default:break}}),e.reporter.log(n.join(`
96
- `))},Pt=e({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{await At(await M(),{ignorePending:e.args[`ignore-pending`],dev:e.args.dev,squash:e.args.squash})}catch(e){A.reporter.error(e),process.exit(1)}}});async function Ft(e){let{manager:t,logger:n}=e,r=await t.getStatus();if(!r||r.type!==`container`){n.reporter.info(`No running dev containers found`);return}n.reporter.info(`Running: ${r.containerID} (${r.imageName})`)}async function It(e){let{manager:t,logger:n}=e;if(!await t.isAvailable()){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.isAvailable()){n.reporter.info(`No dev containers found`);return}await t.remove(),n.reporter.success(`Cleaned up dev containers`)}async function Rt(e){let{logger:t}=e,{reporter:n}=t,{manager:r}=await kt(e,{mode:`dev-start`,logger:t});n.success(`✨ Dev database ready: ${r.getConnectionString()}`)}async function $(){let e=await M();if(!e.config.dev)throw Error(`No dev database configuration found`);let{instance:t}=await Q(e.config.dev,e.config.database.dialect,`dev-start`);return{...e,manager:t}}const zt=e({meta:{name:`start`,description:`Start development database with migrations applied`},run:async()=>{try{await Rt(await M())}catch(e){A.reporter.error(e),process.exit(1)}}}),Bt=e({meta:{name:`status`,description:`Show status of kyrage dev container`},run:async()=>{try{await Ft(await $())}catch(e){A.reporter.error(e),process.exit(1)}}}),Vt=e({meta:{name:`get-url`,description:`Print connection URL for running dev container`},run:async()=>{try{await It(await $())}catch(e){A.reporter.error(e),process.exit(1)}}}),Ht=e({meta:{name:`clean`,description:`Remove all kyrage dev containers`},run:async()=>{try{await Lt(await $())}catch(e){A.reporter.error(e),process.exit(1)}}}),Ut=e({meta:{name:`dev`,description:`Manage development database containers`},subCommands:{start:zt,status:Bt,"get-url":Vt,clean:Ht}});t(e({meta:{name:`kyrage`,version:le,description:`Kysely migration CLI with declarative schema`},subCommands:{apply:vt,generate:Pt,dev:Ut}}));export{};
127
+ `));break;case`create_index`:n.push(`-- create_index: ${e.table}.${e.name} (${e.columns.join(`, `)})${e.unique?` [unique]`:``}`);break;case`drop_index`:n.push(`-- drop_index: ${e.table}.${e.name}`);break;case`create_primary_key_constraint`:n.push(`-- create_primary_key_constraint: ${e.table}.${e.name} (${e.columns.join(`, `)})`);break;case`drop_primary_key_constraint`:n.push(`-- drop_primary_key_constraint: ${e.table}.${e.name}`);break;case`create_unique_constraint`:n.push(`-- create_unique_constraint: ${e.table}.${e.name} (${e.columns.join(`, `)})`);break;case`drop_unique_constraint`:n.push(`-- drop_unique_constraint: ${e.table}.${e.name}`);break;case`create_foreign_key_constraint`:n.push(`-- create_foreign_key_constraint: ${e.table}.${e.name} (${e.columns.join(`, `)}) -> ${e.referencedTable} (${e.referencedColumns.join(`, `)})${e.onDelete?` ON DELETE ${e.onDelete.toUpperCase()}`:``}${e.onUpdate?` ON UPDATE ${e.onUpdate.toUpperCase()}`:``}`);break;case`drop_foreign_key_constraint`:n.push(`-- drop_foreign_key_constraint: ${e.table}.${e.name}`)}}),e.reporter.log(n.join(`
128
+ `))},Jt=t({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{await Wt(await j(),{ignorePending:e.args[`ignore-pending`],dev:e.args.dev,squash:e.args.squash})}catch(e){k.reporter.error(e),process.exit(1)}}});async function Yt(e){let{manager:t,logger:n}=e,r=await t.getStatus();if(!r||r.type!==`container`){n.reporter.info(`No running dev containers found`);return}n.reporter.info(`Running: ${r.containerID} (${r.imageName})`)}async function Xt(e){let{manager:t,logger:n}=e;if(!await t.isAvailable()){n.reporter.info(`No running dev containers found`);return}await t.start(),console.log(t.getConnectionString())}async function Zt(e){let{manager:t,logger:n}=e;if(!await t.isAvailable()){n.reporter.info(`No dev containers found`);return}await t.remove(),n.reporter.success(`Cleaned up dev containers`)}async function Qt(e){let{logger:t}=e,{reporter:n}=t,{manager:r}=await Ut(e,{mode:`dev-start`,logger:t});n.success(`✨ Dev database ready: ${r.getConnectionString()}`)}async function $(){let e=await j();if(!e.config.dev)throw Error(`No dev database configuration found`);let{instance:t}=await Q(e.config.dev,e.config.database.dialect,`dev-start`);return{...e,manager:t}}const $t=t({meta:{name:`start`,description:`Start development database with migrations applied`},run:async()=>{try{await Qt(await j())}catch(e){k.reporter.error(e),process.exit(1)}}}),en=t({meta:{name:`status`,description:`Show status of kyrage dev container`},run:async()=>{try{await Yt(await $())}catch(e){k.reporter.error(e),process.exit(1)}}}),tn=t({meta:{name:`get-url`,description:`Print connection URL for running dev container`},run:async()=>{try{await Xt(await $())}catch(e){k.reporter.error(e),process.exit(1)}}}),nn=t({meta:{name:`clean`,description:`Remove all kyrage dev containers`},run:async()=>{try{await Zt(await $())}catch(e){k.reporter.error(e),process.exit(1)}}}),rn=t({meta:{name:`dev`,description:`Manage development database containers`},subCommands:{start:$t,status:en,"get-url":tn,clean:nn}}),an=t({meta:{name:`kyrage`,version:me,description:`Kysely migration CLI with declarative schema`},subCommands:{apply:Mt,generate:Jt,dev:rn}});n(an);export{};
@@ -0,0 +1 @@
1
+ const e=(e,t)=>t.length===1?`${e}_${t[0]}_primary_key`:`pk_${e}_${t.join(`_`)}`,t={primaryKey:e,unique:(e,t)=>t.length===1?`${e}_${t[0]}_unique`:`uq_${e}_${t.join(`_`)}`,index:(e,t)=>`idx_${e}_${t.join(`_`)}`,foreignKey:(e,t)=>`fk_${e}_${t.join(`_`)}`};export{e as n,t};
package/package.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "name": "@izumisy/kyrage",
3
3
  "private": false,
4
4
  "type": "module",
5
- "version": "1.5.8",
6
- "description": "A minimal, schema-based declarative migration tool for Node.js ecosystem",
5
+ "version": "1.6.1",
6
+ "description": "A minimal, database-agnostic, schema-based declarative migration tool for Node.js ecosystem",
7
7
  "author": "Seiya Izumi (https://github.com/IzumiSy)",
8
8
  "license": "MIT",
9
9
  "repository": {
@@ -30,32 +30,32 @@
30
30
  "kyrage": "./dist/main.mjs"
31
31
  },
32
32
  "dependencies": {
33
- "@testcontainers/cockroachdb": "^11.11.0",
34
- "@testcontainers/postgresql": "^11.11.0",
35
- "better-sqlite3": "^12.6.2",
36
- "c12": "^3.3.3",
37
- "citty": "^0.1.6",
33
+ "@testcontainers/cockroachdb": "^12.0.3",
34
+ "@testcontainers/postgresql": "^12.0.3",
35
+ "better-sqlite3": "^12.11.1",
36
+ "c12": "^3.3.4",
37
+ "citty": "^0.2.1",
38
38
  "consola": "^3.4.2",
39
39
  "graph-data-structure": "^4.5.0",
40
40
  "kysely": "^0.28.9",
41
- "mysql2": "^3.16.0",
42
- "pg": "^8.16.3",
41
+ "mysql2": "^3.20.0",
42
+ "pg": "^8.20.0",
43
43
  "ramda": "^0.32.0",
44
- "sql-formatter": "^15.7.0",
45
- "testcontainers": "^11.11.0",
46
- "zod": "^4.3.5"
44
+ "sql-formatter": "^15.7.3",
45
+ "testcontainers": "^12.0.3",
46
+ "zod": "^4.4.3"
47
47
  },
48
48
  "devDependencies": {
49
- "@swc/core": "^1.15.10",
49
+ "@swc/core": "^1.15.18",
50
50
  "@types/better-sqlite3": "^7.6.13",
51
51
  "@types/node": "^25",
52
- "@types/pg": "^8.16.0",
52
+ "@types/pg": "^8.20.0",
53
53
  "@types/ramda": "^0.31.1",
54
- "memfs": "^4.49.0",
54
+ "memfs": "^4.56.11",
55
55
  "prettier": "^3",
56
- "tsdown": "^0.19.0",
57
- "typescript": "^5",
58
- "vitest": "^4.0.16"
56
+ "tsdown": "^0.23.0",
57
+ "typescript": "^7",
58
+ "vitest": "^4.1.2"
59
59
  },
60
60
  "scripts": {
61
61
  "dev": "NODE_ENV=development tsdown --watch",