@fragno-dev/db 0.0.1 → 0.1.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.
Files changed (200) hide show
  1. package/.turbo/turbo-build.log +137 -13
  2. package/.turbo/turbo-test.log +36 -0
  3. package/CHANGELOG.md +7 -0
  4. package/dist/adapters/adapters.d.ts +18 -0
  5. package/dist/adapters/adapters.d.ts.map +1 -0
  6. package/dist/adapters/drizzle/drizzle-adapter.d.ts +21 -0
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -0
  8. package/dist/adapters/drizzle/drizzle-adapter.js +62 -0
  9. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -0
  10. package/dist/adapters/drizzle/drizzle-query.d.ts +17 -0
  11. package/dist/adapters/drizzle/drizzle-query.d.ts.map +1 -0
  12. package/dist/adapters/drizzle/drizzle-query.js +139 -0
  13. package/dist/adapters/drizzle/drizzle-query.js.map +1 -0
  14. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +9 -0
  15. package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +1 -0
  16. package/dist/adapters/drizzle/drizzle-uow-compiler.js +300 -0
  17. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +1 -0
  18. package/dist/adapters/drizzle/drizzle-uow-decoder.js +82 -0
  19. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +1 -0
  20. package/dist/adapters/drizzle/drizzle-uow-executor.js +125 -0
  21. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +1 -0
  22. package/dist/adapters/drizzle/generate.js +273 -0
  23. package/dist/adapters/drizzle/generate.js.map +1 -0
  24. package/dist/adapters/drizzle/join-column-utils.js +28 -0
  25. package/dist/adapters/drizzle/join-column-utils.js.map +1 -0
  26. package/dist/adapters/drizzle/shared.js +11 -0
  27. package/dist/adapters/drizzle/shared.js.map +1 -0
  28. package/dist/adapters/kysely/kysely-adapter.d.ts +23 -0
  29. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -0
  30. package/dist/adapters/kysely/kysely-adapter.js +119 -0
  31. package/dist/adapters/kysely/kysely-adapter.js.map +1 -0
  32. package/dist/adapters/kysely/kysely-query-builder.js +306 -0
  33. package/dist/adapters/kysely/kysely-query-builder.js.map +1 -0
  34. package/dist/adapters/kysely/kysely-query-compiler.js +67 -0
  35. package/dist/adapters/kysely/kysely-query-compiler.js.map +1 -0
  36. package/dist/adapters/kysely/kysely-query.js +158 -0
  37. package/dist/adapters/kysely/kysely-query.js.map +1 -0
  38. package/dist/adapters/kysely/kysely-uow-compiler.js +139 -0
  39. package/dist/adapters/kysely/kysely-uow-compiler.js.map +1 -0
  40. package/dist/adapters/kysely/kysely-uow-executor.js +89 -0
  41. package/dist/adapters/kysely/kysely-uow-executor.js.map +1 -0
  42. package/dist/adapters/kysely/migration/execute.js +176 -0
  43. package/dist/adapters/kysely/migration/execute.js.map +1 -0
  44. package/dist/fragment.d.ts +54 -0
  45. package/dist/fragment.d.ts.map +1 -0
  46. package/dist/fragment.js +92 -0
  47. package/dist/fragment.js.map +1 -0
  48. package/dist/id.d.ts +2 -0
  49. package/dist/migration-engine/auto-from-schema.js +116 -0
  50. package/dist/migration-engine/auto-from-schema.js.map +1 -0
  51. package/dist/migration-engine/create.d.ts +41 -0
  52. package/dist/migration-engine/create.d.ts.map +1 -0
  53. package/dist/migration-engine/create.js +58 -0
  54. package/dist/migration-engine/create.js.map +1 -0
  55. package/dist/migration-engine/shared.d.ts +90 -0
  56. package/dist/migration-engine/shared.d.ts.map +1 -0
  57. package/dist/migration-engine/shared.js +8 -0
  58. package/dist/migration-engine/shared.js.map +1 -0
  59. package/dist/mod.d.ts +55 -2
  60. package/dist/mod.d.ts.map +1 -1
  61. package/dist/mod.js +111 -2
  62. package/dist/mod.js.map +1 -1
  63. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column-builder.js +108 -0
  64. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column-builder.js.map +1 -0
  65. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column.js +55 -0
  66. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/column.js.map +1 -0
  67. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/entity.js +18 -0
  68. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/entity.js.map +1 -0
  69. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/common.js +183 -0
  70. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/common.js.map +1 -0
  71. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/enum.js +58 -0
  72. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/columns/enum.js.map +1 -0
  73. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/foreign-keys.js +68 -0
  74. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/foreign-keys.js.map +1 -0
  75. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/unique-constraint.js +56 -0
  76. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/unique-constraint.js.map +1 -0
  77. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/utils/array.js +65 -0
  78. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/pg-core/utils/array.js.map +1 -0
  79. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/conditions.js +81 -0
  80. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/conditions.js.map +1 -0
  81. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/select.js +13 -0
  82. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/expressions/select.js.map +1 -0
  83. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/functions/aggregate.js +10 -0
  84. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/functions/aggregate.js.map +1 -0
  85. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/sql.js +372 -0
  86. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/sql/sql.js.map +1 -0
  87. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/subquery.js +23 -0
  88. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/subquery.js.map +1 -0
  89. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.js +62 -0
  90. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.js.map +1 -0
  91. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.utils.js +6 -0
  92. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/table.utils.js.map +1 -0
  93. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing-utils.js +8 -0
  94. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing-utils.js.map +1 -0
  95. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing.js +8 -0
  96. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/tracing.js.map +1 -0
  97. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/view-common.js +6 -0
  98. package/dist/node_modules/.bun/drizzle-orm@0.44.6_4fae081eecb963e2/node_modules/drizzle-orm/view-common.js.map +1 -0
  99. package/dist/query/condition-builder.d.ts +41 -0
  100. package/dist/query/condition-builder.d.ts.map +1 -0
  101. package/dist/query/condition-builder.js +93 -0
  102. package/dist/query/condition-builder.js.map +1 -0
  103. package/dist/query/cursor.d.ts +88 -0
  104. package/dist/query/cursor.d.ts.map +1 -0
  105. package/dist/query/cursor.js +103 -0
  106. package/dist/query/cursor.js.map +1 -0
  107. package/dist/query/orm/orm.d.ts +18 -0
  108. package/dist/query/orm/orm.d.ts.map +1 -0
  109. package/dist/query/orm/orm.js +48 -0
  110. package/dist/query/orm/orm.js.map +1 -0
  111. package/dist/query/query.d.ts +79 -0
  112. package/dist/query/query.d.ts.map +1 -0
  113. package/dist/query/query.js +1 -0
  114. package/dist/query/result-transform.js +155 -0
  115. package/dist/query/result-transform.js.map +1 -0
  116. package/dist/query/unit-of-work.d.ts +435 -0
  117. package/dist/query/unit-of-work.d.ts.map +1 -0
  118. package/dist/query/unit-of-work.js +549 -0
  119. package/dist/query/unit-of-work.js.map +1 -0
  120. package/dist/schema/create.d.ts +273 -116
  121. package/dist/schema/create.d.ts.map +1 -1
  122. package/dist/schema/create.js +410 -222
  123. package/dist/schema/create.js.map +1 -1
  124. package/dist/schema/serialize.js +101 -0
  125. package/dist/schema/serialize.js.map +1 -0
  126. package/dist/schema-generator/schema-generator.d.ts +15 -0
  127. package/dist/schema-generator/schema-generator.d.ts.map +1 -0
  128. package/dist/shared/providers.d.ts +6 -0
  129. package/dist/shared/providers.d.ts.map +1 -0
  130. package/dist/util/import-generator.js +26 -0
  131. package/dist/util/import-generator.js.map +1 -0
  132. package/dist/util/parse.js +15 -0
  133. package/dist/util/parse.js.map +1 -0
  134. package/dist/util/types.d.ts +8 -0
  135. package/dist/util/types.d.ts.map +1 -0
  136. package/package.json +63 -2
  137. package/src/adapters/adapters.ts +22 -0
  138. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +433 -0
  139. package/src/adapters/drizzle/drizzle-adapter.test.ts +122 -0
  140. package/src/adapters/drizzle/drizzle-adapter.ts +118 -0
  141. package/src/adapters/drizzle/drizzle-query.ts +234 -0
  142. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +1084 -0
  143. package/src/adapters/drizzle/drizzle-uow-compiler.ts +546 -0
  144. package/src/adapters/drizzle/drizzle-uow-decoder.ts +165 -0
  145. package/src/adapters/drizzle/drizzle-uow-executor.ts +213 -0
  146. package/src/adapters/drizzle/generate.test.ts +643 -0
  147. package/src/adapters/drizzle/generate.ts +481 -0
  148. package/src/adapters/drizzle/join-column-utils.test.ts +79 -0
  149. package/src/adapters/drizzle/join-column-utils.ts +39 -0
  150. package/src/adapters/drizzle/migrate-drizzle.test.ts +226 -0
  151. package/src/adapters/drizzle/shared.ts +22 -0
  152. package/src/adapters/drizzle/test-utils.ts +56 -0
  153. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +789 -0
  154. package/src/adapters/kysely/kysely-adapter.ts +196 -0
  155. package/src/adapters/kysely/kysely-query-builder.test.ts +1344 -0
  156. package/src/adapters/kysely/kysely-query-builder.ts +611 -0
  157. package/src/adapters/kysely/kysely-query-compiler.ts +124 -0
  158. package/src/adapters/kysely/kysely-query.ts +254 -0
  159. package/src/adapters/kysely/kysely-uow-compiler.test.ts +916 -0
  160. package/src/adapters/kysely/kysely-uow-compiler.ts +271 -0
  161. package/src/adapters/kysely/kysely-uow-executor.ts +149 -0
  162. package/src/adapters/kysely/kysely-uow-joins.test.ts +811 -0
  163. package/src/adapters/kysely/migration/execute-mysql.test.ts +1173 -0
  164. package/src/adapters/kysely/migration/execute-postgres.test.ts +2657 -0
  165. package/src/adapters/kysely/migration/execute.ts +382 -0
  166. package/src/adapters/kysely/migration/kysely-migrator.test.ts +197 -0
  167. package/src/fragment.test.ts +287 -0
  168. package/src/fragment.ts +198 -0
  169. package/src/migration-engine/auto-from-schema.test.ts +118 -58
  170. package/src/migration-engine/auto-from-schema.ts +103 -32
  171. package/src/migration-engine/create.test.ts +34 -46
  172. package/src/migration-engine/create.ts +41 -26
  173. package/src/migration-engine/shared.ts +26 -6
  174. package/src/mod.ts +197 -1
  175. package/src/query/condition-builder.test.ts +379 -0
  176. package/src/query/condition-builder.ts +294 -0
  177. package/src/query/cursor.test.ts +296 -0
  178. package/src/query/cursor.ts +147 -0
  179. package/src/query/orm/orm.ts +92 -0
  180. package/src/query/query-type.test.ts +429 -0
  181. package/src/query/query.ts +200 -0
  182. package/src/query/result-transform.test.ts +795 -0
  183. package/src/query/result-transform.ts +247 -0
  184. package/src/query/unit-of-work-types.test.ts +192 -0
  185. package/src/query/unit-of-work.test.ts +947 -0
  186. package/src/query/unit-of-work.ts +1199 -0
  187. package/src/schema/create.test.ts +653 -110
  188. package/src/schema/create.ts +708 -337
  189. package/src/schema/serialize.test.ts +559 -0
  190. package/src/schema/serialize.ts +359 -0
  191. package/src/schema-generator/schema-generator.ts +12 -0
  192. package/src/shared/config.ts +0 -8
  193. package/src/util/import-generator.ts +28 -0
  194. package/src/util/parse.ts +16 -0
  195. package/src/util/types.ts +4 -0
  196. package/tsconfig.json +1 -1
  197. package/tsdown.config.ts +11 -1
  198. package/vitest.config.ts +3 -0
  199. /package/dist/{cuid.js → id.js} +0 -0
  200. /package/src/{cuid.ts → id.ts} +0 -0
@@ -20,14 +20,17 @@ describe("generateMigrationFromSchema", () => {
20
20
  // Version 0 -> 1: users table created
21
21
  // Version 1 -> 2: posts table created
22
22
  // We want to generate the migration for version 1 -> 2
23
- const operations = generateMigrationFromSchema(mySchema, 1, 2, {
24
- provider: "postgresql",
25
- });
23
+ const operations = generateMigrationFromSchema(mySchema, 1, 2);
26
24
 
27
25
  expect(operations).toHaveLength(1);
28
26
  expect(operations[0]).toMatchObject({
29
27
  type: "create-table",
30
- value: mySchema.tables.posts,
28
+ name: "posts",
29
+ columns: expect.arrayContaining([
30
+ expect.objectContaining({ name: "id" }),
31
+ expect.objectContaining({ name: "title" }),
32
+ expect.objectContaining({ name: "content" }),
33
+ ]),
31
34
  });
32
35
  });
33
36
 
@@ -46,22 +49,32 @@ describe("generateMigrationFromSchema", () => {
46
49
  });
47
50
 
48
51
  // Generate migrations from version 0 to 3 (all three tables)
49
- const operations = generateMigrationFromSchema(mySchema, 0, 3, {
50
- provider: "postgresql",
51
- });
52
+ const operations = generateMigrationFromSchema(mySchema, 0, 3);
52
53
 
53
54
  expect(operations).toHaveLength(3);
54
55
  expect(operations[0]).toMatchObject({
55
56
  type: "create-table",
56
- value: mySchema.tables.users,
57
+ name: "users",
58
+ columns: expect.arrayContaining([
59
+ expect.objectContaining({ name: "id" }),
60
+ expect.objectContaining({ name: "name" }),
61
+ ]),
57
62
  });
58
63
  expect(operations[1]).toMatchObject({
59
64
  type: "create-table",
60
- value: mySchema.tables.posts,
65
+ name: "posts",
66
+ columns: expect.arrayContaining([
67
+ expect.objectContaining({ name: "id" }),
68
+ expect.objectContaining({ name: "title" }),
69
+ ]),
61
70
  });
62
71
  expect(operations[2]).toMatchObject({
63
72
  type: "create-table",
64
- value: mySchema.tables.comments,
73
+ name: "comments",
74
+ columns: expect.arrayContaining([
75
+ expect.objectContaining({ name: "id" }),
76
+ expect.objectContaining({ name: "text" }),
77
+ ]),
65
78
  });
66
79
  });
67
80
 
@@ -74,19 +87,17 @@ describe("generateMigrationFromSchema", () => {
74
87
  .addTable("posts", (t) => {
75
88
  return t.addColumn("id", idColumn()).addColumn("authorId", referenceColumn());
76
89
  })
77
- .addReference("posts", "author", {
78
- columns: ["authorId"],
79
- targetTable: "users",
80
- targetColumns: ["id"],
90
+ .addReference("author", {
91
+ type: "one",
92
+ from: { table: "posts", column: "authorId" },
93
+ to: { table: "users", column: "id" },
81
94
  });
82
95
  });
83
96
 
84
97
  // Version 0 -> 1: users table
85
98
  // Version 1 -> 2: posts table
86
99
  // Version 2 -> 3: author foreign key
87
- const operations = generateMigrationFromSchema(mySchema, 2, 3, {
88
- provider: "postgresql",
89
- });
100
+ const operations = generateMigrationFromSchema(mySchema, 2, 3);
90
101
 
91
102
  expect(operations).toHaveLength(1);
92
103
  expect(operations[0]).toMatchObject({
@@ -98,32 +109,29 @@ describe("generateMigrationFromSchema", () => {
98
109
  if (fkOp.type === "add-foreign-key") {
99
110
  expect(fkOp.value).toMatchObject({
100
111
  name: "posts_users_author_fk",
101
- table: "posts",
102
112
  referencedTable: "users",
103
113
  columns: ["authorId"],
104
- referencedColumns: ["id"],
114
+ referencedColumns: ["_internalId"],
105
115
  });
106
116
  }
107
117
  });
108
118
 
109
- it("should generate add-index operation for indexes defined in createIndex", () => {
119
+ it("should generate add-index operation for indexes added via alterTable", () => {
110
120
  const mySchema = schema((s) => {
111
- return s.addTable("users", (t) => {
112
- return t
113
- .addColumn("id", idColumn())
114
- .addColumn("email", column("string"))
115
- .createIndex("idx_email", ["email"], { unique: true });
116
- });
121
+ return s
122
+ .addTable("users", (t) => {
123
+ return t.addColumn("id", idColumn()).addColumn("email", column("string"));
124
+ })
125
+ .alterTable("users", (t) => {
126
+ return t.createIndex("idx_email", ["email"], { unique: true });
127
+ });
117
128
  });
118
129
 
119
- // Version 0 -> 1: users table
120
- // Version 1 -> 2: email index
121
- const operations = generateMigrationFromSchema(mySchema, 1, 2, {
122
- provider: "postgresql",
123
- });
130
+ const operations = generateMigrationFromSchema(mySchema, 0, 2);
124
131
 
125
- expect(operations).toHaveLength(1);
126
- expect(operations[0]).toMatchObject({
132
+ expect(operations).toHaveLength(2);
133
+ expect(operations[0].type).toBe("create-table");
134
+ expect(operations[1]).toMatchObject({
127
135
  type: "add-index",
128
136
  table: "users",
129
137
  name: "idx_email",
@@ -141,17 +149,15 @@ describe("generateMigrationFromSchema", () => {
141
149
  .addTable("posts", (t) => {
142
150
  return t.addColumn("id", idColumn()).addColumn("authorId", referenceColumn());
143
151
  })
144
- .addReference("posts", "author", {
145
- columns: ["authorId"],
146
- targetTable: "users",
147
- targetColumns: ["id"],
152
+ .addReference("author", {
153
+ type: "one",
154
+ from: { table: "posts", column: "authorId" },
155
+ to: { table: "users", column: "id" },
148
156
  });
149
157
  });
150
158
 
151
159
  // Generate all migrations from scratch
152
- const operations = generateMigrationFromSchema(mySchema, 0, 3, {
153
- provider: "postgresql",
154
- });
160
+ const operations = generateMigrationFromSchema(mySchema, 0, 3);
155
161
 
156
162
  expect(operations).toHaveLength(3);
157
163
  expect(operations[0].type).toBe("create-table");
@@ -163,25 +169,23 @@ describe("generateMigrationFromSchema", () => {
163
169
  const mySchema = schema((s) => {
164
170
  return s
165
171
  .addTable("users", (t) => {
166
- return t
167
- .addColumn("id", idColumn())
168
- .addColumn("email", column("string"))
169
- .createIndex("idx_email", ["email"], { unique: true });
172
+ return t.addColumn("id", idColumn()).addColumn("email", column("string"));
173
+ })
174
+ .alterTable("users", (t) => {
175
+ return t.createIndex("idx_email", ["email"], { unique: true });
170
176
  })
171
177
  .addTable("posts", (t) => {
172
178
  return t.addColumn("id", idColumn()).addColumn("authorId", referenceColumn());
173
179
  })
174
- .addReference("posts", "author", {
175
- columns: ["authorId"],
176
- targetTable: "users",
177
- targetColumns: ["id"],
180
+ .addReference("author", {
181
+ type: "one",
182
+ from: { table: "posts", column: "authorId" },
183
+ to: { table: "users", column: "id" },
178
184
  });
179
185
  });
180
186
 
181
187
  // Generate all migrations from scratch
182
- const operations = generateMigrationFromSchema(mySchema, 0, 4, {
183
- provider: "postgresql",
184
- });
188
+ const operations = generateMigrationFromSchema(mySchema, 0, 4);
185
189
 
186
190
  expect(operations).toHaveLength(4);
187
191
  expect(operations[0].type).toBe("create-table");
@@ -197,9 +201,7 @@ describe("generateMigrationFromSchema", () => {
197
201
  });
198
202
  });
199
203
 
200
- const operations = generateMigrationFromSchema(mySchema, 1, 1, {
201
- provider: "postgresql",
202
- });
204
+ const operations = generateMigrationFromSchema(mySchema, 1, 1);
203
205
 
204
206
  expect(operations).toHaveLength(0);
205
207
  });
@@ -208,7 +210,7 @@ describe("generateMigrationFromSchema", () => {
208
210
  const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
209
211
 
210
212
  expect(() => {
211
- generateMigrationFromSchema(mySchema, 999, 1000, { provider: "postgresql" });
213
+ generateMigrationFromSchema(mySchema, 999, 1000);
212
214
  }).toThrow("fromVersion (999) exceeds schema version (1)");
213
215
  });
214
216
 
@@ -216,7 +218,7 @@ describe("generateMigrationFromSchema", () => {
216
218
  const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
217
219
 
218
220
  expect(() => {
219
- generateMigrationFromSchema(mySchema, 0, 999, { provider: "postgresql" });
221
+ generateMigrationFromSchema(mySchema, 0, 999);
220
222
  }).toThrow("toVersion (999) exceeds schema version (1)");
221
223
  });
222
224
 
@@ -224,7 +226,7 @@ describe("generateMigrationFromSchema", () => {
224
226
  const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
225
227
 
226
228
  expect(() => {
227
- generateMigrationFromSchema(mySchema, 1, 0, { provider: "postgresql" });
229
+ generateMigrationFromSchema(mySchema, 1, 0);
228
230
  }).toThrow("Cannot migrate backwards");
229
231
  });
230
232
 
@@ -232,7 +234,65 @@ describe("generateMigrationFromSchema", () => {
232
234
  const mySchema = schema((s) => s.addTable("users", (t) => t.addColumn("id", idColumn())));
233
235
 
234
236
  expect(() => {
235
- generateMigrationFromSchema(mySchema, -1, 1, { provider: "postgresql" });
237
+ generateMigrationFromSchema(mySchema, -1, 1);
236
238
  }).toThrow("fromVersion cannot be negative");
237
239
  });
240
+
241
+ it("should only create constraints for references, not for referenceColumns", () => {
242
+ const mySchema = schema((s) => {
243
+ return s
244
+ .addTable("posts", (t) => {
245
+ return t
246
+ .addColumn("id", idColumn().defaultTo("auto"))
247
+ .addColumn("title", column("string"))
248
+ .addColumn("content", column("string"))
249
+ .addColumn("userId", referenceColumn());
250
+ })
251
+ .addTable("users", (t) => {
252
+ return t
253
+ .addColumn("id", idColumn().defaultTo("auto"))
254
+ .addColumn("name", column("string"));
255
+ })
256
+ .addReference("author", {
257
+ type: "one",
258
+ from: { table: "posts", column: "userId" },
259
+ to: { table: "users", column: "id" },
260
+ })
261
+ .alterTable("posts", (t) => {
262
+ return t
263
+ .addColumn("summary", column("string").nullable())
264
+ .createIndex("idx_title", ["title"]);
265
+ });
266
+ });
267
+
268
+ const operations = generateMigrationFromSchema(mySchema, 0, mySchema.version);
269
+ expect(operations.map((o) => o.type)).toEqual([
270
+ "create-table",
271
+ "create-table",
272
+ "add-foreign-key",
273
+ "alter-table",
274
+ "add-index",
275
+ ]);
276
+ });
277
+
278
+ it("should not create duplicate foreign key constraints", () => {
279
+ const mySchema = schema((s) => {
280
+ return s
281
+ .addTable("users", (t) => t.addColumn("id", idColumn()))
282
+ .addTable("posts", (t) =>
283
+ t.addColumn("id", idColumn()).addColumn("userId", referenceColumn()),
284
+ )
285
+ .addReference("author", {
286
+ type: "one",
287
+ from: { table: "posts", column: "userId" },
288
+ to: { table: "users", column: "id" },
289
+ });
290
+ });
291
+
292
+ const operations = generateMigrationFromSchema(mySchema, 0, mySchema.version);
293
+
294
+ // Count foreign key operations
295
+ const fkOps = operations.filter((op) => op.type === "add-foreign-key");
296
+ expect(fkOps).toHaveLength(1); // Should be exactly one, not two
297
+ });
238
298
  });
@@ -1,6 +1,5 @@
1
- import { compileForeignKey, type AnySchema } from "../schema/create";
2
- import type { MigrationOperation } from "./shared";
3
- import type { Provider } from "../shared/providers";
1
+ import { type AnySchema } from "../schema/create";
2
+ import type { MigrationOperation, ColumnInfo } from "./shared";
4
3
 
5
4
  /**
6
5
  * Generate migration operations from a schema's operation history
@@ -23,18 +22,13 @@ import type { Provider } from "../shared/providers";
23
22
  * );
24
23
  *
25
24
  * // Generate operations from version 0 to 1 (only creates users table)
26
- * const operations = generateMigrationFromSchema(mySchema, 0, 1, {
27
- * provider: "postgresql"
28
- * });
25
+ * const operations = generateMigrationFromSchema(mySchema, 0, 1);
29
26
  * ```
30
27
  */
31
28
  export function generateMigrationFromSchema(
32
29
  targetSchema: AnySchema,
33
30
  fromVersion: number,
34
31
  toVersion: number,
35
- _options: {
36
- provider: Provider;
37
- },
38
32
  ): MigrationOperation[] {
39
33
  if (fromVersion < 0) {
40
34
  throw new Error(`fromVersion cannot be negative: ${fromVersion}`);
@@ -65,39 +59,116 @@ export function generateMigrationFromSchema(
65
59
 
66
60
  for (const op of relevantOperations) {
67
61
  if (op.type === "add-table") {
62
+ // Collect columns for create-table operation
63
+ const columns: ColumnInfo[] = [];
64
+
65
+ for (const subOp of op.operations) {
66
+ if (subOp.type === "add-column") {
67
+ const col = subOp.column;
68
+ columns.push({
69
+ name: subOp.columnName,
70
+ type: col.type,
71
+ isNullable: col.isNullable,
72
+ role: col.role,
73
+ default: col.default
74
+ ? {
75
+ value: "value" in col.default ? col.default.value : undefined,
76
+ runtime:
77
+ "runtime" in col.default
78
+ ? typeof col.default.runtime === "string"
79
+ ? col.default.runtime
80
+ : undefined
81
+ : undefined,
82
+ }
83
+ : undefined,
84
+ });
85
+ }
86
+ }
87
+
68
88
  migrationOperations.push({
69
89
  type: "create-table",
70
- value: op.table,
90
+ name: op.tableName,
91
+ columns,
71
92
  });
72
- } else if (op.type === "add-reference") {
73
- const table = targetSchema.tables[op.tableName];
74
- if (!table) {
75
- throw new Error(`Table ${op.tableName} not found in schema`);
76
- }
77
93
 
78
- // Find the foreign key that matches this reference
79
- const foreignKey = table.foreignKeys.find(
80
- (fk) => fk.name === `${op.tableName}_${op.config.targetTable}_${op.referenceName}_fk`,
81
- );
94
+ // Add indexes and foreign keys as separate operations
95
+ for (const subOp of op.operations) {
96
+ if (subOp.type === "add-index") {
97
+ migrationOperations.push({
98
+ type: "add-index",
99
+ table: op.tableName,
100
+ name: subOp.name,
101
+ columns: subOp.columns,
102
+ unique: subOp.unique,
103
+ });
104
+ } else if (subOp.type === "add-foreign-key") {
105
+ migrationOperations.push({
106
+ type: "add-foreign-key",
107
+ table: op.tableName,
108
+ value: {
109
+ name: subOp.name,
110
+ columns: subOp.columns,
111
+ referencedTable: subOp.referencedTable,
112
+ referencedColumns: subOp.referencedColumns,
113
+ },
114
+ });
115
+ }
116
+ }
117
+ } else if (op.type === "alter-table") {
118
+ const columnOps = op.operations.filter((o) => o.type === "add-column");
82
119
 
83
- if (!foreignKey) {
84
- throw new Error(
85
- `Foreign key for reference ${op.referenceName} not found in table ${op.tableName}`,
86
- );
120
+ if (columnOps.length > 0) {
121
+ migrationOperations.push({
122
+ type: "alter-table",
123
+ name: op.tableName,
124
+ value: columnOps.map((o) => {
125
+ const col = o.column;
126
+ return {
127
+ type: "create-column" as const,
128
+ value: {
129
+ name: o.columnName,
130
+ type: col.type,
131
+ isNullable: col.isNullable,
132
+ role: col.role,
133
+ default: col.default
134
+ ? {
135
+ value: "value" in col.default ? col.default.value : undefined,
136
+ runtime:
137
+ "runtime" in col.default
138
+ ? typeof col.default.runtime === "string"
139
+ ? col.default.runtime
140
+ : undefined
141
+ : undefined,
142
+ }
143
+ : undefined,
144
+ },
145
+ };
146
+ }),
147
+ });
87
148
  }
88
149
 
150
+ // Add indexes as separate operations
151
+ for (const subOp of op.operations) {
152
+ if (subOp.type === "add-index") {
153
+ migrationOperations.push({
154
+ type: "add-index",
155
+ table: op.tableName,
156
+ name: subOp.name,
157
+ columns: subOp.columns,
158
+ unique: subOp.unique,
159
+ });
160
+ }
161
+ }
162
+ } else if (op.type === "add-reference") {
89
163
  migrationOperations.push({
90
164
  type: "add-foreign-key",
91
165
  table: op.tableName,
92
- value: compileForeignKey(foreignKey),
93
- });
94
- } else if (op.type === "add-index") {
95
- migrationOperations.push({
96
- type: "add-index",
97
- table: op.tableName,
98
- name: op.name,
99
- columns: op.columns,
100
- unique: op.unique,
166
+ value: {
167
+ name: `${op.tableName}_${op.config.to.table}_${op.referenceName}_fk`,
168
+ columns: [op.config.from.column],
169
+ referencedTable: op.config.to.table,
170
+ referencedColumns: [op.config.to.column],
171
+ },
101
172
  });
102
173
  }
103
174
  }