@casekit/orm2 0.0.0-20250322230249

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 (275) hide show
  1. package/build/builders/buildCount.d.ts +23 -0
  2. package/build/builders/buildCount.js +63 -0
  3. package/build/builders/buildCount.test.d.ts +1 -0
  4. package/build/builders/buildCount.test.js +144 -0
  5. package/build/builders/buildCreate.d.ts +5 -0
  6. package/build/builders/buildCreate.js +28 -0
  7. package/build/builders/buildCreate.test.d.ts +1 -0
  8. package/build/builders/buildCreate.test.js +47 -0
  9. package/build/builders/buildDelete.d.ts +5 -0
  10. package/build/builders/buildDelete.js +28 -0
  11. package/build/builders/buildDelete.test.d.ts +1 -0
  12. package/build/builders/buildDelete.test.js +108 -0
  13. package/build/builders/buildFind.d.ts +8 -0
  14. package/build/builders/buildFind.js +185 -0
  15. package/build/builders/buildFind.test.d.ts +1 -0
  16. package/build/builders/buildFind.test.js +263 -0
  17. package/build/builders/buildUpdate.d.ts +5 -0
  18. package/build/builders/buildUpdate.js +34 -0
  19. package/build/builders/buildUpdate.test.d.ts +1 -0
  20. package/build/builders/buildUpdate.test.js +130 -0
  21. package/build/builders/buildWhere.d.ts +6 -0
  22. package/build/builders/buildWhere.js +63 -0
  23. package/build/builders/buildWhere.test.d.ts +1 -0
  24. package/build/builders/buildWhere.test.js +154 -0
  25. package/build/builders/types.d.ts +87 -0
  26. package/build/builders/types.js +1 -0
  27. package/build/connection.d.ts +31 -0
  28. package/build/connection.js +206 -0
  29. package/build/index.d.ts +10 -0
  30. package/build/index.js +5 -0
  31. package/build/operators.d.ts +59 -0
  32. package/build/operators.js +44 -0
  33. package/build/orm.count.d.ts +14 -0
  34. package/build/orm.count.js +22 -0
  35. package/build/orm.createMany.d.ts +5 -0
  36. package/build/orm.createMany.js +26 -0
  37. package/build/orm.createOne.d.ts +5 -0
  38. package/build/orm.createOne.js +34 -0
  39. package/build/orm.d.ts +81 -0
  40. package/build/orm.deleteMany.d.ts +5 -0
  41. package/build/orm.deleteMany.js +26 -0
  42. package/build/orm.deleteOne.d.ts +5 -0
  43. package/build/orm.deleteOne.js +32 -0
  44. package/build/orm.findMany.d.ts +8 -0
  45. package/build/orm.findMany.js +64 -0
  46. package/build/orm.findOne.d.ts +5 -0
  47. package/build/orm.findOne.js +20 -0
  48. package/build/orm.js +243 -0
  49. package/build/orm.restrict.d.ts +6 -0
  50. package/build/orm.restrict.js +52 -0
  51. package/build/orm.updateMany.d.ts +5 -0
  52. package/build/orm.updateMany.js +29 -0
  53. package/build/orm.updateOne.d.ts +5 -0
  54. package/build/orm.updateOne.js +35 -0
  55. package/build/sql/countToSql.d.ts +3 -0
  56. package/build/sql/countToSql.js +11 -0
  57. package/build/sql/countToSql.test.d.ts +1 -0
  58. package/build/sql/countToSql.test.js +218 -0
  59. package/build/sql/createToSql.d.ts +3 -0
  60. package/build/sql/createToSql.js +27 -0
  61. package/build/sql/createToSql.test.d.ts +1 -0
  62. package/build/sql/createToSql.test.js +186 -0
  63. package/build/sql/deleteToSql.d.ts +3 -0
  64. package/build/sql/deleteToSql.js +15 -0
  65. package/build/sql/deleteToSql.test.d.ts +1 -0
  66. package/build/sql/deleteToSql.test.js +93 -0
  67. package/build/sql/findToSql.d.ts +3 -0
  68. package/build/sql/findToSql.js +33 -0
  69. package/build/sql/findToSql.test.d.ts +1 -0
  70. package/build/sql/findToSql.test.js +409 -0
  71. package/build/sql/updateToSql.d.ts +3 -0
  72. package/build/sql/updateToSql.js +16 -0
  73. package/build/sql/updateToSql.test.d.ts +1 -0
  74. package/build/sql/updateToSql.test.js +165 -0
  75. package/build/sql/util.d.ts +11 -0
  76. package/build/sql/util.js +36 -0
  77. package/build/sql/util.test.d.ts +1 -0
  78. package/build/sql/util.test.js +163 -0
  79. package/build/tests/connection.test.d.ts +1 -0
  80. package/build/tests/connection.test.js +304 -0
  81. package/build/tests/datatypes.test.d.ts +1 -0
  82. package/build/tests/datatypes.test.js +239 -0
  83. package/build/tests/operators.test.d.ts +1 -0
  84. package/build/tests/operators.test.js +125 -0
  85. package/build/tests/orm.count.middleware.test.d.ts +1 -0
  86. package/build/tests/orm.count.middleware.test.js +132 -0
  87. package/build/tests/orm.count.test-d.d.ts +1 -0
  88. package/build/tests/orm.count.test-d.js +60 -0
  89. package/build/tests/orm.count.test.d.ts +1 -0
  90. package/build/tests/orm.count.test.js +151 -0
  91. package/build/tests/orm.createMany.middleware.test.d.ts +1 -0
  92. package/build/tests/orm.createMany.middleware.test.js +63 -0
  93. package/build/tests/orm.createMany.test-d.d.ts +1 -0
  94. package/build/tests/orm.createMany.test-d.js +131 -0
  95. package/build/tests/orm.createMany.test.d.ts +1 -0
  96. package/build/tests/orm.createMany.test.js +392 -0
  97. package/build/tests/orm.createOne.middleware.test.d.ts +1 -0
  98. package/build/tests/orm.createOne.middleware.test.js +54 -0
  99. package/build/tests/orm.createOne.test-d.d.ts +1 -0
  100. package/build/tests/orm.createOne.test-d.js +113 -0
  101. package/build/tests/orm.createOne.test.d.ts +1 -0
  102. package/build/tests/orm.createOne.test.js +268 -0
  103. package/build/tests/orm.deleteMany.middleware.test.d.ts +1 -0
  104. package/build/tests/orm.deleteMany.middleware.test.js +77 -0
  105. package/build/tests/orm.deleteMany.test-d.d.ts +1 -0
  106. package/build/tests/orm.deleteMany.test-d.js +179 -0
  107. package/build/tests/orm.deleteMany.test.d.ts +1 -0
  108. package/build/tests/orm.deleteMany.test.js +394 -0
  109. package/build/tests/orm.deleteOne.middleware.test.d.ts +1 -0
  110. package/build/tests/orm.deleteOne.middleware.test.js +61 -0
  111. package/build/tests/orm.deleteOne.test-d.d.ts +1 -0
  112. package/build/tests/orm.deleteOne.test-d.js +179 -0
  113. package/build/tests/orm.deleteOne.test.d.ts +1 -0
  114. package/build/tests/orm.deleteOne.test.js +360 -0
  115. package/build/tests/orm.findMany.includeManyToMany.test.d.ts +1 -0
  116. package/build/tests/orm.findMany.includeManyToMany.test.js +335 -0
  117. package/build/tests/orm.findMany.includeManyToOne.test.d.ts +1 -0
  118. package/build/tests/orm.findMany.includeManyToOne.test.js +286 -0
  119. package/build/tests/orm.findMany.includeOneToMany.test.d.ts +1 -0
  120. package/build/tests/orm.findMany.includeOneToMany.test.js +530 -0
  121. package/build/tests/orm.findMany.middleware.test.d.ts +1 -0
  122. package/build/tests/orm.findMany.middleware.test.js +66 -0
  123. package/build/tests/orm.findMany.offsetLimit.test.d.ts +1 -0
  124. package/build/tests/orm.findMany.offsetLimit.test.js +108 -0
  125. package/build/tests/orm.findMany.orderBy.test.d.ts +1 -0
  126. package/build/tests/orm.findMany.orderBy.test.js +304 -0
  127. package/build/tests/orm.findMany.select.test.d.ts +1 -0
  128. package/build/tests/orm.findMany.select.test.js +278 -0
  129. package/build/tests/orm.findMany.test-d.d.ts +1 -0
  130. package/build/tests/orm.findMany.test-d.js +374 -0
  131. package/build/tests/orm.findMany.where.test.d.ts +1 -0
  132. package/build/tests/orm.findMany.where.test.js +383 -0
  133. package/build/tests/orm.findOne.middleware.test.d.ts +1 -0
  134. package/build/tests/orm.findOne.middleware.test.js +57 -0
  135. package/build/tests/orm.findOne.test-d.d.ts +1 -0
  136. package/build/tests/orm.findOne.test-d.js +377 -0
  137. package/build/tests/orm.findOne.test.d.ts +1 -0
  138. package/build/tests/orm.findOne.test.js +247 -0
  139. package/build/tests/orm.restrict.test-d.d.ts +1 -0
  140. package/build/tests/orm.restrict.test-d.js +105 -0
  141. package/build/tests/orm.restrict.test.d.ts +1 -0
  142. package/build/tests/orm.restrict.test.js +259 -0
  143. package/build/tests/orm.transact.test.d.ts +1 -0
  144. package/build/tests/orm.transact.test.js +48 -0
  145. package/build/tests/orm.updateMany.middleware.test.d.ts +1 -0
  146. package/build/tests/orm.updateMany.middleware.test.js +72 -0
  147. package/build/tests/orm.updateMany.test.d.ts +1 -0
  148. package/build/tests/orm.updateMany.test.js +210 -0
  149. package/build/tests/orm.updateOne.middleware.test.d.ts +1 -0
  150. package/build/tests/orm.updateOne.middleware.test.js +62 -0
  151. package/build/tests/orm.updateOne.test.d.ts +1 -0
  152. package/build/tests/orm.updateOne.test.js +209 -0
  153. package/build/tests/util/db.d.ts +1571 -0
  154. package/build/tests/util/db.js +10 -0
  155. package/build/tests/util/logger.d.ts +19 -0
  156. package/build/tests/util/logger.js +40 -0
  157. package/build/types/BaseFindParams.d.ts +1 -0
  158. package/build/types/BaseFindParams.js +1 -0
  159. package/build/types/CountParams.d.ts +16 -0
  160. package/build/types/CountParams.js +1 -0
  161. package/build/types/CountParams.test-d.d.ts +1 -0
  162. package/build/types/CountParams.test-d.js +89 -0
  163. package/build/types/CreateManyParams.d.ts +11 -0
  164. package/build/types/CreateManyParams.js +1 -0
  165. package/build/types/CreateManyParams.test-d.d.ts +1 -0
  166. package/build/types/CreateManyParams.test-d.js +83 -0
  167. package/build/types/CreateManyResult.d.ts +5 -0
  168. package/build/types/CreateManyResult.js +1 -0
  169. package/build/types/CreateManyResult.test-d.d.ts +1 -0
  170. package/build/types/CreateManyResult.test-d.js +22 -0
  171. package/build/types/CreateOneParams.d.ts +11 -0
  172. package/build/types/CreateOneParams.js +1 -0
  173. package/build/types/CreateOneParams.test-d.d.ts +1 -0
  174. package/build/types/CreateOneParams.test-d.js +56 -0
  175. package/build/types/CreateOneResult.d.ts +5 -0
  176. package/build/types/CreateOneResult.js +1 -0
  177. package/build/types/CreateOneResult.test-d.d.ts +1 -0
  178. package/build/types/CreateOneResult.test-d.js +23 -0
  179. package/build/types/CreateValues.d.ts +6 -0
  180. package/build/types/CreateValues.js +1 -0
  181. package/build/types/CreateValues.test-d.d.ts +1 -0
  182. package/build/types/CreateValues.test-d.js +60 -0
  183. package/build/types/DeleteManyResult.d.ts +5 -0
  184. package/build/types/DeleteManyResult.js +1 -0
  185. package/build/types/DeleteManyResult.test-d.d.ts +1 -0
  186. package/build/types/DeleteManyResult.test-d.js +23 -0
  187. package/build/types/DeleteOneResult.d.ts +5 -0
  188. package/build/types/DeleteOneResult.js +1 -0
  189. package/build/types/DeleteOneResult.test-d.d.ts +1 -0
  190. package/build/types/DeleteOneResult.test-d.js +23 -0
  191. package/build/types/DeleteParams.d.ts +7 -0
  192. package/build/types/DeleteParams.js +1 -0
  193. package/build/types/DeleteParams.test-d.d.ts +1 -0
  194. package/build/types/DeleteParams.test-d.js +46 -0
  195. package/build/types/FindParams.d.ts +22 -0
  196. package/build/types/FindParams.js +1 -0
  197. package/build/types/FindParams.test-d.d.ts +1 -0
  198. package/build/types/FindParams.test-d.js +107 -0
  199. package/build/types/FindResult.d.ts +13 -0
  200. package/build/types/FindResult.js +1 -0
  201. package/build/types/FindResult.test-d.d.ts +1 -0
  202. package/build/types/FindResult.test-d.js +30 -0
  203. package/build/types/IncludeClause.d.ts +5 -0
  204. package/build/types/IncludeClause.js +1 -0
  205. package/build/types/IncludeClause.test-d.d.ts +1 -0
  206. package/build/types/IncludeClause.test-d.js +69 -0
  207. package/build/types/Middleware.d.ts +51 -0
  208. package/build/types/Middleware.js +37 -0
  209. package/build/types/OptionalValues.d.ts +4 -0
  210. package/build/types/OptionalValues.js +1 -0
  211. package/build/types/OptionalValues.test-d.d.ts +1 -0
  212. package/build/types/OptionalValues.test-d.js +12 -0
  213. package/build/types/OrderByClause.d.ts +9 -0
  214. package/build/types/OrderByClause.js +1 -0
  215. package/build/types/OrderByClause.test-d.d.ts +1 -0
  216. package/build/types/OrderByClause.test-d.js +44 -0
  217. package/build/types/RequiredValues.d.ts +4 -0
  218. package/build/types/RequiredValues.js +1 -0
  219. package/build/types/RequiredValues.test-d.d.ts +1 -0
  220. package/build/types/RequiredValues.test-d.js +22 -0
  221. package/build/types/RestrictModels.d.ts +23 -0
  222. package/build/types/RestrictModels.js +1 -0
  223. package/build/types/RestrictModels.test-d.d.ts +1 -0
  224. package/build/types/RestrictModels.test-d.js +44 -0
  225. package/build/types/ReturningClause.d.ts +3 -0
  226. package/build/types/ReturningClause.js +1 -0
  227. package/build/types/ReturningClause.test-d.d.ts +1 -0
  228. package/build/types/ReturningClause.test-d.js +15 -0
  229. package/build/types/SelectClause.d.ts +3 -0
  230. package/build/types/SelectClause.js +1 -0
  231. package/build/types/SelectClause.test-d.d.ts +1 -0
  232. package/build/types/SelectClause.test-d.js +15 -0
  233. package/build/types/UpdateManyResult.d.ts +5 -0
  234. package/build/types/UpdateManyResult.js +1 -0
  235. package/build/types/UpdateManyResult.test-d.d.ts +1 -0
  236. package/build/types/UpdateManyResult.test-d.js +15 -0
  237. package/build/types/UpdateOneResult.d.ts +5 -0
  238. package/build/types/UpdateOneResult.js +1 -0
  239. package/build/types/UpdateOneResult.test-d.d.ts +1 -0
  240. package/build/types/UpdateOneResult.test-d.js +15 -0
  241. package/build/types/UpdateParams.d.ts +9 -0
  242. package/build/types/UpdateParams.js +1 -0
  243. package/build/types/UpdateParams.test-d.d.ts +1 -0
  244. package/build/types/UpdateParams.test-d.js +29 -0
  245. package/build/types/UpdateValues.d.ts +6 -0
  246. package/build/types/UpdateValues.js +1 -0
  247. package/build/types/UpdateValues.test-d.d.ts +1 -0
  248. package/build/types/UpdateValues.test-d.js +33 -0
  249. package/build/types/WhereClause.d.ts +29 -0
  250. package/build/types/WhereClause.js +1 -0
  251. package/build/types/WhereClause.test-d.d.ts +1 -0
  252. package/build/types/WhereClause.test-d.js +137 -0
  253. package/build/util/getIncludedToManySubqueries.d.ts +12 -0
  254. package/build/util/getIncludedToManySubqueries.js +63 -0
  255. package/build/util/getIncludedToManySubqueries.test.d.ts +1 -0
  256. package/build/util/getIncludedToManySubqueries.test.js +121 -0
  257. package/build/util/getLateralJoinValues.d.ts +4 -0
  258. package/build/util/getLateralJoinValues.js +30 -0
  259. package/build/util/getLateralJoinValues.test.d.ts +1 -0
  260. package/build/util/getLateralJoinValues.test.js +99 -0
  261. package/build/util/hasClauses.d.ts +1 -0
  262. package/build/util/hasClauses.js +9 -0
  263. package/build/util/hasClauses.test.d.ts +1 -0
  264. package/build/util/hasClauses.test.js +15 -0
  265. package/build/util/makeTableAlias.d.ts +1 -0
  266. package/build/util/makeTableAlias.js +10 -0
  267. package/build/util/makeTableAlias.test.d.ts +1 -0
  268. package/build/util/makeTableAlias.test.js +18 -0
  269. package/build/util/resultSchema.d.ts +10 -0
  270. package/build/util/resultSchema.js +42 -0
  271. package/build/util/rowToObject.d.ts +8 -0
  272. package/build/util/rowToObject.js +10 -0
  273. package/build/util/rowToObject.test.d.ts +1 -0
  274. package/build/util/rowToObject.test.js +68 -0
  275. package/package.json +67 -0
@@ -0,0 +1,268 @@
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, test, } from "vitest";
2
+ import { config } from "@casekit/orm2-fixtures";
3
+ import { orm } from "../orm.js";
4
+ import { mockLogger } from "./util/logger.js";
5
+ describe("createOne", () => {
6
+ const logger = mockLogger();
7
+ let db;
8
+ beforeEach(() => {
9
+ logger.clear();
10
+ });
11
+ beforeAll(async () => {
12
+ db = orm({ ...config, logger });
13
+ await db.connect();
14
+ });
15
+ afterAll(async () => {
16
+ await db.close();
17
+ });
18
+ test("creates a record with full values and returns specified fields", async () => {
19
+ await db.transact(async (db) => {
20
+ const user = await db.createOne("user", {
21
+ values: {
22
+ id: 1,
23
+ name: "Test User",
24
+ email: "user@example.com",
25
+ role: "user",
26
+ },
27
+ returning: ["id", "name", "role"],
28
+ });
29
+ expect(user).toEqual({
30
+ id: 1,
31
+ name: "Test User",
32
+ role: "user",
33
+ });
34
+ // Verify record was actually created
35
+ const foundUser = await db.findOne("user", {
36
+ select: ["id", "name", "role"],
37
+ where: { id: 1 },
38
+ });
39
+ expect(foundUser).toEqual(user);
40
+ }, { rollback: true });
41
+ });
42
+ test("creates record with minimal values using defaults", async () => {
43
+ await db.transact(async (db) => {
44
+ const user = await db.createOne("user", {
45
+ values: {
46
+ id: 1,
47
+ name: "Test User",
48
+ email: "user@example.com",
49
+ role: "user",
50
+ },
51
+ returning: ["id", "name", "deletedAt"],
52
+ });
53
+ expect(user.deletedAt).toBeNull();
54
+ }, { rollback: true });
55
+ });
56
+ test("returns row count when no returning clause specified", async () => {
57
+ await db.transact(async (db) => {
58
+ const result = await db.createOne("user", {
59
+ values: {
60
+ id: 1,
61
+ name: "Test User",
62
+ email: "user@example.com",
63
+ role: "user",
64
+ },
65
+ });
66
+ expect(result).toBe(1);
67
+ // Verify record was created
68
+ const user = await db.findOne("user", {
69
+ select: ["id"],
70
+ where: { id: 1 },
71
+ });
72
+ expect(user).toEqual({ id: 1 });
73
+ }, { rollback: true });
74
+ });
75
+ test("throws error on constraint violation", async () => {
76
+ await db.transact(async (db) => {
77
+ const email = "test@example.com";
78
+ // Create first user
79
+ await db.createOne("user", {
80
+ values: {
81
+ id: 1,
82
+ name: "First User",
83
+ email,
84
+ role: "user",
85
+ },
86
+ });
87
+ // Try to create another user with same email
88
+ await expect(db.createOne("user", {
89
+ values: {
90
+ id: 2,
91
+ name: "Second User",
92
+ email, // Duplicate email with same deletedAt (null)
93
+ role: "user",
94
+ },
95
+ })).rejects.toThrow(/duplicate key value/);
96
+ }, { rollback: true });
97
+ });
98
+ test("handles onConflict do nothing with returning clause", async () => {
99
+ await db.transact(async (db) => {
100
+ const email = "test@example.com";
101
+ const user1 = await db.createOne("user", {
102
+ values: {
103
+ id: 1,
104
+ name: "Original User",
105
+ email,
106
+ role: "user",
107
+ },
108
+ returning: ["id", "name"],
109
+ });
110
+ // Try to create user with same email
111
+ const user2 = await db.createOne("user", {
112
+ values: {
113
+ id: 1, // Same ID
114
+ name: "Duplicate User",
115
+ email,
116
+ role: "user",
117
+ },
118
+ onConflict: { do: "nothing" },
119
+ returning: ["id", "name"],
120
+ });
121
+ expect(user2).toBeNull();
122
+ const originalUser = await db.findOne("user", {
123
+ select: ["id", "name"],
124
+ where: { id: user1.id },
125
+ });
126
+ expect(originalUser.name).toBe("Original User");
127
+ }, { rollback: true });
128
+ });
129
+ test("handles onConflict do nothing without returning clause", async () => {
130
+ await db.transact(async (db) => {
131
+ const email = "test@example.com";
132
+ await db.createOne("user", {
133
+ values: {
134
+ id: 1,
135
+ name: "Original User",
136
+ email,
137
+ role: "user",
138
+ },
139
+ });
140
+ // Try to create user with same email
141
+ const result = await db.createOne("user", {
142
+ values: {
143
+ id: 1,
144
+ name: "Duplicate User",
145
+ email,
146
+ role: "user",
147
+ },
148
+ onConflict: { do: "nothing" },
149
+ });
150
+ expect(result).toBe(0);
151
+ }, { rollback: true });
152
+ });
153
+ test("handles enum fields in values", async () => {
154
+ await db.transact(async (db) => {
155
+ const user = await db.createOne("user", {
156
+ values: {
157
+ id: 1,
158
+ name: "Test User",
159
+ email: "test@example.com",
160
+ role: "admin",
161
+ },
162
+ returning: ["id", "name", "role"],
163
+ });
164
+ expect(user).toEqual({
165
+ id: 1,
166
+ name: "Test User",
167
+ role: "admin",
168
+ });
169
+ const foundUser = await db.findOne("user", {
170
+ select: ["id", "name", "role"],
171
+ where: { id: 1 },
172
+ });
173
+ expect(foundUser.role).toBe("admin");
174
+ }, { rollback: true });
175
+ });
176
+ test("handles array and JSON fields in values", async () => {
177
+ await db.transact(async (db) => {
178
+ const user = await db.createOne("user", {
179
+ values: {
180
+ id: 1,
181
+ name: "Test User",
182
+ email: "test@example.com",
183
+ role: "user",
184
+ },
185
+ returning: ["id"],
186
+ });
187
+ const post = await db.createOne("post", {
188
+ values: {
189
+ title: "Test Post",
190
+ content: "Test Content",
191
+ authorId: user.id,
192
+ tags: ["test", "example", "tags"],
193
+ metadata: {
194
+ foo: "a",
195
+ bar: [
196
+ { baz: "good", quux: true },
197
+ { baz: "bad", quux: false },
198
+ ],
199
+ },
200
+ },
201
+ returning: ["id", "title", "tags", "metadata"],
202
+ });
203
+ expect(post).toEqual({
204
+ id: expect.any(Number),
205
+ title: "Test Post",
206
+ tags: ["test", "example", "tags"],
207
+ metadata: {
208
+ foo: "a",
209
+ bar: [
210
+ { baz: "good", quux: true },
211
+ { baz: "bad", quux: false },
212
+ ],
213
+ },
214
+ });
215
+ const foundPost = await db.findOne("post", {
216
+ select: ["id", "title", "tags", "metadata"],
217
+ where: { id: post.id },
218
+ });
219
+ expect(foundPost.tags).toEqual(["test", "example", "tags"]);
220
+ expect(foundPost.metadata).toEqual({
221
+ foo: "a",
222
+ bar: [
223
+ { baz: "good", quux: true },
224
+ { baz: "bad", quux: false },
225
+ ],
226
+ });
227
+ }, { rollback: true });
228
+ });
229
+ // TODO comment back in once relationships are implemented
230
+ test.skip("can create post with relationship to user", async () => {
231
+ await db.transact(async (db) => {
232
+ // Create a user first
233
+ const user = await db.createOne("user", {
234
+ values: {
235
+ id: 1,
236
+ name: "Test User",
237
+ email: "test@example.com",
238
+ role: "user",
239
+ },
240
+ returning: ["id"],
241
+ });
242
+ // Create a post for the user
243
+ const post = await db.createOne("post", {
244
+ values: {
245
+ title: "First Post",
246
+ content: "Hello World",
247
+ authorId: user.id,
248
+ },
249
+ returning: ["id", "title", "authorId"],
250
+ });
251
+ expect(post.authorId).toBe(user.id);
252
+ expect(post).toHaveProperty("title");
253
+ expect(post).toHaveProperty("id");
254
+ // Verify the relationship works
255
+ const userWithPost = await db.findOne("user", {
256
+ select: ["id"],
257
+ include: {
258
+ posts: {
259
+ select: ["id", "title"],
260
+ },
261
+ },
262
+ where: { id: user.id },
263
+ });
264
+ expect(userWithPost.posts).toHaveLength(1);
265
+ expect(userWithPost.posts[0].title).toBe("First Post");
266
+ }, { rollback: true });
267
+ });
268
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,77 @@
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, test, vi, } from "vitest";
2
+ import { config } from "@casekit/orm2-fixtures";
3
+ import { $in } from "../operators.js";
4
+ import { orm } from "../orm.js";
5
+ import { mockLogger } from "./util/logger.js";
6
+ describe("orm.deleteMany: middleware", () => {
7
+ const logger = mockLogger();
8
+ let db;
9
+ beforeEach(() => {
10
+ logger.clear();
11
+ });
12
+ beforeAll(async () => {
13
+ db = orm({ ...config, logger });
14
+ await db.connect();
15
+ });
16
+ afterAll(async () => {
17
+ await db.close();
18
+ });
19
+ describe("deleteMany middleware", () => {
20
+ test("it allows overriding the orm's deleteMany method", async () => {
21
+ await db.transact(async (db) => {
22
+ // Create test users to delete
23
+ await db.createMany("user", {
24
+ values: [
25
+ {
26
+ id: 1,
27
+ name: "Test User 1",
28
+ email: "test1@example.com",
29
+ role: "user",
30
+ },
31
+ {
32
+ id: 2,
33
+ name: "Test User 2",
34
+ email: "test2@example.com",
35
+ role: "user",
36
+ },
37
+ ],
38
+ returning: ["id"],
39
+ });
40
+ const stub = vi.fn();
41
+ const dbWithMiddleware = db.middleware([
42
+ {
43
+ deleteMany: (db, table, query) => {
44
+ stub("called stub in middleware 1");
45
+ return db.deleteMany(table, query);
46
+ },
47
+ },
48
+ {
49
+ deleteMany: (db, table, query) => {
50
+ stub("called stub in middleware 2");
51
+ return db.deleteMany(table, query);
52
+ },
53
+ },
54
+ ]);
55
+ const result = await dbWithMiddleware.deleteMany("user", {
56
+ where: { id: { [$in]: [1, 2] } },
57
+ returning: ["id", "name"],
58
+ });
59
+ expect(result).toHaveLength(2);
60
+ expect(result).toEqual(expect.arrayContaining([
61
+ expect.objectContaining({
62
+ id: 1,
63
+ name: "Test User 1",
64
+ }),
65
+ expect.objectContaining({
66
+ id: 2,
67
+ name: "Test User 2",
68
+ }),
69
+ ]));
70
+ expect(stub.mock.calls).toEqual([
71
+ ["called stub in middleware 1"],
72
+ ["called stub in middleware 2"],
73
+ ]);
74
+ }, { rollback: true });
75
+ });
76
+ });
77
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,179 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ import { $gt, $is, $like, $or } from "../operators.js";
3
+ import { createTestDB } from "./util/db.js";
4
+ describe("deleteMany", () => {
5
+ const { db } = createTestDB();
6
+ test("returns array of records when returning clause is specified", () => {
7
+ expectTypeOf(db.deleteMany("post", {
8
+ where: { id: 1 },
9
+ returning: ["id", "title", "content"],
10
+ })).resolves.toEqualTypeOf();
11
+ });
12
+ test("returns number when no returning clause specified", () => {
13
+ expectTypeOf(db.deleteMany("post", {
14
+ where: { id: 1 },
15
+ })).resolves.toEqualTypeOf();
16
+ });
17
+ test("handles nullable fields in returning clause", () => {
18
+ expectTypeOf(db.deleteMany("post", {
19
+ where: { id: 1 },
20
+ returning: ["deletedAt"],
21
+ })).resolves.toEqualTypeOf();
22
+ });
23
+ test("handles array fields in where and returning clauses", () => {
24
+ expectTypeOf(db.deleteMany("post", {
25
+ where: {
26
+ tags: ["news", "tech"],
27
+ id: 1,
28
+ },
29
+ returning: ["tags", "id"],
30
+ })).resolves.toEqualTypeOf();
31
+ });
32
+ test("handles JSON fields in where and returning clauses", async () => {
33
+ // Test returning JSON fields
34
+ expectTypeOf(db.deleteMany("post", {
35
+ where: { id: 1 },
36
+ returning: ["metadata"],
37
+ })).resolves.toEqualTypeOf();
38
+ // Test user preferences JSON field
39
+ expectTypeOf(db.deleteMany("user", {
40
+ where: { id: 1 },
41
+ returning: ["preferences"],
42
+ })).resolves.toEqualTypeOf();
43
+ expectTypeOf(db.deleteMany("post", {
44
+ where: {
45
+ metadata: {
46
+ foo: "a",
47
+ bar: [
48
+ {
49
+ baz: "good",
50
+ quux: true,
51
+ },
52
+ ],
53
+ },
54
+ },
55
+ returning: ["metadata"],
56
+ })).resolves.toEqualTypeOf();
57
+ await db.deleteMany("post", {
58
+ where: {
59
+ metadata: {
60
+ // @ts-expect-error invalid enum value in JSON
61
+ foo: "invalid",
62
+ bar: [],
63
+ },
64
+ },
65
+ });
66
+ });
67
+ test("handles complex where clauses", () => {
68
+ expectTypeOf(db.deleteMany("post", {
69
+ where: {
70
+ id: { [$gt]: 100 },
71
+ [$or]: [
72
+ { title: { [$like]: "test%" } },
73
+ { tags: ["news", "tech"] },
74
+ ],
75
+ publishedAt: { [$is]: null },
76
+ },
77
+ returning: ["id"],
78
+ })).resolves.toEqualTypeOf();
79
+ });
80
+ test("enforces where clause is required", async () => {
81
+ // @ts-expect-error where clause is required
82
+ await db.deleteMany("post", {
83
+ returning: ["id"],
84
+ });
85
+ });
86
+ test("prevents invalid field names in where clause", async () => {
87
+ await db.deleteMany("post", {
88
+ where: {
89
+ // @ts-expect-error invalid field name
90
+ invalid: 1,
91
+ },
92
+ });
93
+ });
94
+ test("prevents invalid field names in returning clause", async () => {
95
+ await db.deleteMany("post", {
96
+ where: { id: 1 },
97
+ // @ts-expect-error invalid field name
98
+ returning: ["invalid"],
99
+ });
100
+ });
101
+ test("prevents invalid model names", async () => {
102
+ // @ts-expect-error invalid model name
103
+ await db.deleteMany("invalid", {
104
+ where: { id: 1 },
105
+ });
106
+ });
107
+ test("prevents invalid operator usage", async () => {
108
+ await db.deleteMany("post", {
109
+ where: {
110
+ // @ts-expect-error $like cannot be used with number
111
+ id: { [$like]: 100 },
112
+ },
113
+ });
114
+ });
115
+ test("handles enum fields in where and returning clauses", async () => {
116
+ // Test enum in where clause
117
+ expectTypeOf(db.deleteMany("user", {
118
+ where: { role: "admin" },
119
+ returning: ["role", "id"],
120
+ })).resolves.toEqualTypeOf();
121
+ // Test enum in JSON structure
122
+ expectTypeOf(db.deleteMany("post", {
123
+ where: {
124
+ metadata: {
125
+ foo: "a",
126
+ bar: [
127
+ {
128
+ baz: "good",
129
+ quux: true,
130
+ },
131
+ ],
132
+ },
133
+ },
134
+ returning: ["metadata"],
135
+ })).resolves.toEqualTypeOf();
136
+ await db.deleteMany("user", {
137
+ where: {
138
+ // @ts-expect-error invalid enum value for role
139
+ role: "superadmin",
140
+ },
141
+ });
142
+ await db.deleteMany("post", {
143
+ where: {
144
+ metadata: {
145
+ // @ts-expect-error invalid enum value in JSON metadata
146
+ foo: "invalid",
147
+ bar: [],
148
+ },
149
+ },
150
+ });
151
+ });
152
+ test("enforces field type constraints in where clause", async () => {
153
+ await db.deleteMany("post", {
154
+ where: {
155
+ // @ts-expect-error id must be number
156
+ id: "1",
157
+ },
158
+ });
159
+ await db.deleteMany("post", {
160
+ where: {
161
+ // @ts-expect-error tags must be string[]
162
+ tags: "tag1",
163
+ },
164
+ });
165
+ await db.deleteMany("user", {
166
+ where: {
167
+ // @ts-expect-error role must be "user" | "admin"
168
+ role: "superuser",
169
+ },
170
+ });
171
+ });
172
+ test("returned arrays contain deeply readonly objects", async () => {
173
+ const result = await db.deleteMany("post", {
174
+ where: { id: 1 },
175
+ returning: ["metadata"],
176
+ });
177
+ expectTypeOf(result).toEqualTypeOf();
178
+ });
179
+ });
@@ -0,0 +1 @@
1
+ export {};