@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,22 @@
1
+ import { ModelDefinitions, ModelName, OperatorDefinitions } from "@casekit/orm2-schema";
2
+ import { IncludeClause } from "./IncludeClause.js";
3
+ import { OrderByClause } from "./OrderByClause.js";
4
+ import { SelectClause } from "./SelectClause.js";
5
+ import { WhereClause } from "./WhereClause.js";
6
+ /**
7
+ * We have a single FindParams type rather than a FindOneParams and FindManyParams type
8
+ * even though it's a bit annoying as it allows you to (incorrectly) specify
9
+ * a limit, offset, and order by in a findOne query. We do this because choosing between
10
+ * the two different types (which we did originally) in a nested include clause makes our
11
+ * types around TEN TIMES as slow for a deeply nested query - and dramatically limits the
12
+ * depth of nesting possible in a query too. It's just not worth it.
13
+ */
14
+ export interface FindParams<Models extends ModelDefinitions, Operators extends OperatorDefinitions, M extends ModelName<Models>> {
15
+ select: SelectClause<Models[M]>;
16
+ include?: IncludeClause<Models, Operators, M>;
17
+ where?: WhereClause<Models, Operators, M>;
18
+ for?: "update" | "no key update" | "share" | "key share";
19
+ limit?: number;
20
+ offset?: number;
21
+ orderBy?: OrderByClause<Models, M>;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,107 @@
1
+ import { describe, test } from "vitest";
2
+ import { $eq } from "#operators.js";
3
+ describe("FindParams", () => {
4
+ test("minimal valid params with just select", () => {
5
+ const _ = {
6
+ select: ["id"],
7
+ };
8
+ });
9
+ test("with include clause", () => {
10
+ const _ = {
11
+ select: ["id", "title"],
12
+ include: { author: { select: ["id", "name"] } },
13
+ };
14
+ });
15
+ test("with where clause", () => {
16
+ const _ = {
17
+ select: ["id"],
18
+ where: { id: { [$eq]: 1 } },
19
+ };
20
+ });
21
+ test("with limit and offset", () => {
22
+ const _ = {
23
+ select: ["id"],
24
+ limit: 10,
25
+ offset: 5,
26
+ };
27
+ });
28
+ test("with order by", () => {
29
+ const _ = {
30
+ select: ["id"],
31
+ orderBy: [["id", "asc"]],
32
+ };
33
+ });
34
+ test("with all optional parameters", () => {
35
+ const _ = {
36
+ select: ["id", "title"],
37
+ include: { author: { select: ["id"] } },
38
+ where: { id: { [$eq]: 1 } },
39
+ limit: 10,
40
+ offset: 5,
41
+ orderBy: [["id", "desc"], "author.name"],
42
+ };
43
+ });
44
+ test("invalid field in select", () => {
45
+ const _ = {
46
+ // @ts-expect-error invalid field
47
+ select: ["id", "invalid"],
48
+ };
49
+ });
50
+ test("invalid relation in include", () => {
51
+ const _ = {
52
+ select: ["id"],
53
+ include: {
54
+ // @ts-expect-error invalid relation
55
+ invalid: { select: ["id"] },
56
+ },
57
+ };
58
+ });
59
+ test("invalid field in where clause", () => {
60
+ const _ = {
61
+ select: ["id"],
62
+ where: {
63
+ // @ts-expect-error invalid field
64
+ invalid: { [$eq]: 1 },
65
+ },
66
+ };
67
+ });
68
+ test("invalid field in order by", () => {
69
+ const _ = {
70
+ select: ["id"],
71
+ orderBy: [
72
+ "id",
73
+ // @ts-expect-error invalid field
74
+ "invalid",
75
+ ],
76
+ };
77
+ });
78
+ test("invalid direction in order by", () => {
79
+ const _ = {
80
+ select: ["id"],
81
+ orderBy: [
82
+ // @ts-expect-error invalid direction
83
+ ["id", "invalid"],
84
+ ],
85
+ };
86
+ });
87
+ test("include when model has no relations", () => {
88
+ const _ = {
89
+ select: ["hex"],
90
+ // @ts-expect-error color has no relations
91
+ include: { posts: { select: ["id"] } },
92
+ };
93
+ });
94
+ test("allows selecting for update clause", () => {
95
+ const _ = {
96
+ select: ["id"],
97
+ for: "update",
98
+ };
99
+ });
100
+ test("invalid `for` clause", () => {
101
+ const _ = {
102
+ select: ["id"],
103
+ // @ts-expect-error invalid for clause
104
+ for: "invalid",
105
+ };
106
+ });
107
+ });
@@ -0,0 +1,13 @@
1
+ import { FieldType, ManyToOneRelationDefinition, ModelDefinitions, ModelName, OperatorDefinitions, RelationDefinition } from "@casekit/orm2-schema";
2
+ import { Simplify } from "@casekit/toolbox";
3
+ import { FindParams } from "./FindParams.js";
4
+ export type RelationModelName<Models extends ModelDefinitions, M extends ModelName<Models>, R extends keyof Models[M]["relations"]> = Models[M]["relations"][R] extends RelationDefinition ? Extract<Models[M]["relations"][R]["model"], ModelName<Models>> : never;
5
+ export type IncludedRelationName<Models extends ModelDefinitions, Operators extends OperatorDefinitions, M extends ModelName<Models>, Q extends FindParams<Models, Operators, M>> = Extract<keyof Q["include"], keyof Models[M]["relations"]>;
6
+ export type IncludedRelationQuery<Models extends ModelDefinitions, Operators extends OperatorDefinitions, M extends ModelName<Models>, R extends keyof Q["include"] & keyof Models[M]["relations"], Q extends FindParams<Models, Operators, M>> = Extract<Q["include"][R], FindParams<Models, Operators, RelationModelName<Models, M, R>>>;
7
+ export type FindResult<Models extends ModelDefinitions, Operators extends OperatorDefinitions, M extends ModelName<Models>, Q extends FindParams<Models, Operators, M>> = Simplify<{
8
+ [C in Q["select"][number]]: FieldType<Models[M], C>;
9
+ } & (undefined extends Q["include"] ? unknown : {
10
+ [R in IncludedRelationName<Models, Operators, M, Q>]: Models[M]["relations"][R] extends {
11
+ optional: true;
12
+ } ? FindResult<Models, Operators, RelationModelName<Models, M, R>, IncludedRelationQuery<Models, Operators, M, R, Q>> | null : Models[M]["relations"][R] extends ManyToOneRelationDefinition ? FindResult<Models, Operators, RelationModelName<Models, M, R>, IncludedRelationQuery<Models, Operators, M, R, Q>> : FindResult<Models, Operators, RelationModelName<Models, M, R>, IncludedRelationQuery<Models, Operators, M, R, Q>>[];
13
+ })>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("FindResult", () => {
3
+ test("simple select fields", () => {
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ test("many-to-one relation returns single object", () => {
7
+ expectTypeOf().toEqualTypeOf();
8
+ });
9
+ test("one-to-many relation returns array", () => {
10
+ expectTypeOf().toEqualTypeOf();
11
+ });
12
+ test("many-to-many relation returns array", () => {
13
+ expectTypeOf().toEqualTypeOf();
14
+ });
15
+ test("optional many-to-one relation can be null", () => {
16
+ expectTypeOf().toEqualTypeOf();
17
+ });
18
+ test("nested relations", () => {
19
+ expectTypeOf().toEqualTypeOf();
20
+ });
21
+ test("array fields", () => {
22
+ expectTypeOf().toEqualTypeOf();
23
+ });
24
+ test("nullable fields", () => {
25
+ expectTypeOf().toEqualTypeOf();
26
+ });
27
+ test("without include clause", () => {
28
+ expectTypeOf().toEqualTypeOf();
29
+ });
30
+ });
@@ -0,0 +1,5 @@
1
+ import { ModelDefinition, ModelDefinitions, ModelName, OperatorDefinitions, RelationDefinitions, RelationName } from "@casekit/orm2-schema";
2
+ import { FindParams } from "./FindParams.js";
3
+ export type IncludeClause<Models extends ModelDefinitions, Operators extends OperatorDefinitions, M extends ModelName<Models>, Model extends ModelDefinition = Models[M], Relations extends RelationDefinitions = Model["relations"] extends undefined ? Record<string, never> : NonNullable<Model["relations"]>> = Models[M]["relations"] extends NonNullable<Models[M]["relations"]> ? {
4
+ [R in RelationName<Model>]?: FindParams<Models, Operators, Extract<Relations[R]["model"], string>>;
5
+ } : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,69 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("IncludeClause", () => {
3
+ test("allows including relations with nested find params", () => {
4
+ const _ = {
5
+ posts: { select: ["id", "title"] },
6
+ friends: { select: ["id", "name"] },
7
+ };
8
+ });
9
+ test("allows deeply nested includes", () => {
10
+ const _ = {
11
+ posts: {
12
+ select: ["id"],
13
+ include: {
14
+ author: {
15
+ select: ["id", "name"],
16
+ },
17
+ },
18
+ },
19
+ };
20
+ });
21
+ test("disallows invalid relations", () => {
22
+ const _ = {
23
+ // @ts-expect-error invalid relation
24
+ invalid: { select: ["id"] },
25
+ };
26
+ });
27
+ test("handles models with no relations", () => {
28
+ expectTypeOf().toEqualTypeOf();
29
+ });
30
+ test("correctly types many-to-one relations", () => {
31
+ const _ = {
32
+ author: { select: ["id"] },
33
+ };
34
+ });
35
+ test("correctly types one-to-many relations", () => {
36
+ const _ = {
37
+ posts: { select: ["id"] },
38
+ };
39
+ });
40
+ test("correctly types many-to-many relations", () => {
41
+ const _ = {
42
+ friends: { select: ["id"] },
43
+ };
44
+ });
45
+ test("requires valid select clause in nested find params", () => {
46
+ const _ = {
47
+ author: {
48
+ // @ts-expect-error invalid field in select
49
+ select: ["invalid"],
50
+ },
51
+ };
52
+ });
53
+ test("allows where clause in nested find params", () => {
54
+ const _ = {
55
+ posts: {
56
+ select: ["id"],
57
+ where: { id: 1 },
58
+ },
59
+ };
60
+ });
61
+ test("allows orderBy in nested find params", () => {
62
+ const _ = {
63
+ posts: {
64
+ select: ["id"],
65
+ orderBy: ["id"],
66
+ },
67
+ };
68
+ });
69
+ });
@@ -0,0 +1,51 @@
1
+ import { NormalizedConfig } from "@casekit/orm2-config";
2
+ import { ModelDefinition, ModelDefinitions, OperatorDefinitions } from "@casekit/orm2-schema";
3
+ import { Orm } from "../orm.js";
4
+ import { CountParams } from "./CountParams.js";
5
+ import { CreateManyParams } from "./CreateManyParams.js";
6
+ import { CreateOneParams } from "./CreateOneParams.js";
7
+ import { CreateValues } from "./CreateValues.js";
8
+ import { DeleteParams } from "./DeleteParams.js";
9
+ import { FindParams } from "./FindParams.js";
10
+ import { UpdateParams } from "./UpdateParams.js";
11
+ import { UpdateValues } from "./UpdateValues.js";
12
+ import { WhereClause } from "./WhereClause.js";
13
+ export type WhereMiddleware = (config: NormalizedConfig, modelName: string, where: WhereClause<ModelDefinitions, OperatorDefinitions, string>) => WhereClause<ModelDefinitions, OperatorDefinitions, string>;
14
+ export type ValuesMiddleware = (config: NormalizedConfig, modelName: string, values: CreateValues<ModelDefinition>) => CreateValues<ModelDefinition>;
15
+ export type SetMiddleware = (config: NormalizedConfig, modelName: string, values: UpdateValues<ModelDefinition>) => UpdateValues<ModelDefinition>;
16
+ export type DeleteOneMiddleware = (db: Orm, modelName: string, params: DeleteParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Record<string, unknown> | number>;
17
+ export type DeleteManyMiddleware = (db: Orm, modelName: string, params: DeleteParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Record<string, unknown>[] | number>;
18
+ export type FindOneMiddleware = (db: Orm, modelName: string, query: FindParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Record<string, unknown>>;
19
+ export type FindManyMiddleware = (db: Orm, modelName: string, query: FindParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Readonly<Record<string, unknown>[]>>;
20
+ export type CountMiddleware = (db: Orm, modelName: string, query: CountParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<number>;
21
+ export type CreateOneMiddleware = (db: Orm, modelName: string, query: CreateOneParams<ModelDefinitions, string>) => Promise<Record<string, unknown> | number>;
22
+ export type CreateManyMiddleware = (db: Orm, modelName: string, query: CreateManyParams<ModelDefinitions, string>) => Promise<Record<string, unknown>[] | number>;
23
+ export type UpdateOneMiddleware = (db: Orm, modelName: string, query: UpdateParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Record<string, unknown> | number | null>;
24
+ export type UpdateManyMiddleware = (db: Orm, modelName: string, query: UpdateParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Record<string, unknown>[] | number | null>;
25
+ export type Middleware = {
26
+ where?: WhereMiddleware;
27
+ set?: SetMiddleware;
28
+ values?: ValuesMiddleware;
29
+ findOne?: FindOneMiddleware;
30
+ findMany?: FindManyMiddleware;
31
+ count?: CountMiddleware;
32
+ createOne?: CreateOneMiddleware;
33
+ createMany?: CreateManyMiddleware;
34
+ updateOne?: UpdateOneMiddleware;
35
+ updateMany?: UpdateManyMiddleware;
36
+ deleteOne?: DeleteOneMiddleware;
37
+ deleteMany?: DeleteManyMiddleware;
38
+ };
39
+ type Organisation = {
40
+ id: string;
41
+ };
42
+ type User = {
43
+ id: string;
44
+ };
45
+ export declare const tenancy: ({ org }: {
46
+ org: Organisation;
47
+ }) => Middleware;
48
+ export declare const userstamps: ({ user }: {
49
+ user: User;
50
+ }) => Middleware;
51
+ export {};
@@ -0,0 +1,37 @@
1
+ import { getModel } from "@casekit/orm2-config";
2
+ export const tenancy = ({ org }) => ({
3
+ where: (config, modelName, where) => {
4
+ if ("organisationId" in getModel(config.models, modelName).fields) {
5
+ return { ...where, organisaitonId: org.id };
6
+ }
7
+ else {
8
+ return where;
9
+ }
10
+ },
11
+ values: (config, modelName, values) => {
12
+ if ("organisationId" in getModel(config.models, modelName).fields) {
13
+ return { ...values, organisationId: org.id };
14
+ }
15
+ else {
16
+ return values;
17
+ }
18
+ },
19
+ });
20
+ export const userstamps = ({ user }) => ({
21
+ values: (config, modelName, values) => {
22
+ if ("createdById" in getModel(config.models, modelName).fields) {
23
+ return { ...values, updatedById: values["createdById"] ?? user.id };
24
+ }
25
+ else {
26
+ return values;
27
+ }
28
+ },
29
+ set: (config, modelName, set) => {
30
+ if ("updatedById" in getModel(config.models, modelName).fields) {
31
+ return { ...set, updatedById: set["updatedById"] ?? user.id };
32
+ }
33
+ else {
34
+ return set;
35
+ }
36
+ },
37
+ });
@@ -0,0 +1,4 @@
1
+ import { FieldType, ModelDefinition, OptionalField } from "@casekit/orm2-schema";
2
+ export type OptionalValues<Model extends ModelDefinition> = OptionalField<Model> extends never ? never : {
3
+ [K in OptionalField<Model>]?: FieldType<Model, K> | null;
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("OptionalValues", () => {
3
+ test("extracts optional fields from model", () => {
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ test("returns never for models with no optional fields", () => {
7
+ expectTypeOf().toEqualTypeOf();
8
+ });
9
+ test("works for models with no required fields", () => {
10
+ expectTypeOf().toEqualTypeOf();
11
+ });
12
+ });
@@ -0,0 +1,9 @@
1
+ import { FieldName, ModelDefinitions, ModelName } from "@casekit/orm2-schema";
2
+ type OrderByField<Models extends ModelDefinitions, M extends ModelName<Models>> = FieldName<Models[M]> | {
3
+ [R in Extract<keyof Models[M]["relations"], string>]: Models[M]["relations"][R] extends {
4
+ type: "N:1";
5
+ model: infer M2 extends ModelName<Models>;
6
+ } ? `${R}.${Extract<keyof Models[M2]["fields"], string>}` : never;
7
+ }[Extract<keyof Models[M]["relations"], string>];
8
+ export type OrderByClause<Models extends ModelDefinitions, M extends ModelName<Models>> = Array<OrderByField<Models, M> | [OrderByField<Models, M>, "asc" | "desc"]>;
9
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { describe, test } from "vitest";
2
+ describe("OrderByClause", () => {
3
+ test("allows ordering by fields of the model", () => {
4
+ const _ = ["title", "id"];
5
+ });
6
+ test("allows ordering by fields on N:1 relations", () => {
7
+ const _ = ["author.name"];
8
+ });
9
+ test("allows specifying a direction", () => {
10
+ const _ = [
11
+ "title",
12
+ "id",
13
+ ["id", "desc"],
14
+ ];
15
+ });
16
+ test("prevents ordering by non-existing fields", () => {
17
+ const _ = [
18
+ "title",
19
+ // @ts-expect-error non-existent field
20
+ "wrong",
21
+ ];
22
+ });
23
+ test("prevents ordering by non-existing relations", () => {
24
+ const _ = [
25
+ "title",
26
+ // @ts-expect-error non-existent relation
27
+ "wrong.name",
28
+ ];
29
+ });
30
+ test("prevents ordering by N:N relations", () => {
31
+ const _ = [
32
+ "name",
33
+ // @ts-expect-error N:N relation
34
+ "posts.title",
35
+ ];
36
+ });
37
+ test("prevents ordering by 1:N relations", () => {
38
+ const _ = [
39
+ "name",
40
+ // @ts-expect-error N:1 relation
41
+ "posts.title",
42
+ ];
43
+ });
44
+ });
@@ -0,0 +1,4 @@
1
+ import { FieldType, ModelDefinition, RequiredField } from "@casekit/orm2-schema";
2
+ export type RequiredValues<Model extends ModelDefinition> = RequiredField<Model> extends never ? never : {
3
+ [K in RequiredField<Model>]: FieldType<Model, K>;
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("RequiredValues", () => {
3
+ test("model with required fields", () => {
4
+ const _ = {
5
+ title: "Title",
6
+ content: "Content",
7
+ authorId: 1,
8
+ };
9
+ });
10
+ test("is never for model with only optional fields", () => {
11
+ expectTypeOf().toEqualTypeOf();
12
+ });
13
+ test("model with serial primary key", () => {
14
+ expectTypeOf().not.toExtend();
15
+ });
16
+ test("model with provided fields", () => {
17
+ expectTypeOf().not.toExtend();
18
+ });
19
+ test("model with nullable fields", () => {
20
+ expectTypeOf().not.toExtend();
21
+ });
22
+ });
@@ -0,0 +1,23 @@
1
+ import { Config, ModelDefinitions, ModelName, RelationDefinitions } from "@casekit/orm2-schema";
2
+ export type RestrictRelation<Relations extends RelationDefinitions, R extends keyof Relations, Allowed extends string> = Relations[R] extends {
3
+ type: "N:N";
4
+ } ? Relations[R] extends {
5
+ model: Allowed;
6
+ through: {
7
+ model: Allowed;
8
+ };
9
+ } ? R : never : Relations[R] extends {
10
+ model: Allowed;
11
+ } ? R : never;
12
+ export type RestrictModel<Models extends ModelDefinitions, Allowed extends ModelName<Models>, M extends ModelName<Models>> = Omit<Models[M], "relations"> & {
13
+ relations: Models[M]["relations"] extends infer Relations extends RelationDefinitions ? keyof {
14
+ [R in keyof Relations as RestrictRelation<Relations, R, Allowed>]: Relations[R];
15
+ } extends never ? undefined : {
16
+ [R in keyof Relations as RestrictRelation<Relations, R, Allowed>]: Relations[R];
17
+ } : undefined;
18
+ };
19
+ export type RestrictModels<C extends Config, Allowed extends ModelName<C["models"]>, Models extends ModelDefinitions = C["models"]> = Omit<C, "models"> & {
20
+ models: {
21
+ [M in Allowed]: RestrictModel<Models, Allowed, M>;
22
+ };
23
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("RestrictModels", () => {
3
+ test("restricts relations to only allowed models", () => {
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ test("excludes relations to non-allowed models", () => {
7
+ expectTypeOf().toEqualTypeOf();
8
+ expectTypeOf().toEqualTypeOf();
9
+ expectTypeOf().toEqualTypeOf();
10
+ });
11
+ test("N:N relations are excluded unless the through model is also allowed", () => {
12
+ // @ts-expect-error - friendship model is not allowed
13
+ const _ = {
14
+ friends: {
15
+ type: "N:N",
16
+ model: "user",
17
+ through: {
18
+ model: "friendship",
19
+ fromRelation: "user",
20
+ toRelation: "friend",
21
+ },
22
+ },
23
+ };
24
+ });
25
+ test("N:N relations are allowed if the through model is also allowed", () => {
26
+ const _ = {
27
+ friends: {
28
+ type: "N:N",
29
+ model: "user",
30
+ through: {
31
+ model: "friendship",
32
+ fromRelation: "user",
33
+ toRelation: "friend",
34
+ },
35
+ },
36
+ friendships: {
37
+ type: "1:N",
38
+ model: "friendship",
39
+ fromField: "id",
40
+ toField: "userId",
41
+ },
42
+ };
43
+ });
44
+ });
@@ -0,0 +1,3 @@
1
+ import { NonEmptyArray } from "ts-essentials";
2
+ import { FieldName, ModelDefinition } from "@casekit/orm2-schema";
3
+ export type ReturningClause<Model extends ModelDefinition> = NonEmptyArray<FieldName<Model>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("ReturningClause", () => {
3
+ test("accepts array of valid field names", () => {
4
+ expectTypeOf().toExtend();
5
+ });
6
+ test("requires at least one field", () => {
7
+ expectTypeOf().not.toExtend();
8
+ });
9
+ test("rejects invalid field names", () => {
10
+ expectTypeOf().not.toExtend();
11
+ });
12
+ test("accepts single field array", () => {
13
+ expectTypeOf().toExtend();
14
+ });
15
+ });
@@ -0,0 +1,3 @@
1
+ import { NonEmptyArray } from "ts-essentials";
2
+ import { FieldName, ModelDefinition } from "@casekit/orm2-schema";
3
+ export type SelectClause<Model extends ModelDefinition> = NonEmptyArray<FieldName<Model>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("SelectClause", () => {
3
+ test("accepts array of valid field names", () => {
4
+ expectTypeOf().toExtend();
5
+ });
6
+ test("requires at least one field", () => {
7
+ expectTypeOf().not.toExtend();
8
+ });
9
+ test("rejects invalid field names", () => {
10
+ expectTypeOf().not.toExtend();
11
+ });
12
+ test("accepts single field array", () => {
13
+ expectTypeOf().toExtend();
14
+ });
15
+ });
@@ -0,0 +1,5 @@
1
+ import { FieldType, ModelDefinitions, ModelName, OperatorDefinitions } from "@casekit/orm2-schema";
2
+ import { UpdateParams } from "./UpdateParams.js";
3
+ export type UpdateManyResult<Models extends ModelDefinitions, Operators extends OperatorDefinitions, M extends ModelName<Models>, Q extends UpdateParams<Models, Operators, M>> = Q["returning"] extends NonNullable<Q["returning"]> ? {
4
+ [C in Q["returning"][number]]: FieldType<Models[M], C>;
5
+ }[] : number;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { describe, expectTypeOf, test } from "vitest";
2
+ describe("UpdateManyResult", () => {
3
+ test("returns count when no returning clause", () => {
4
+ expectTypeOf().toEqualTypeOf();
5
+ });
6
+ test("returns array of selected fields when returning clause present", () => {
7
+ expectTypeOf().toEqualTypeOf();
8
+ });
9
+ test("handles complex field types", () => {
10
+ expectTypeOf().toEqualTypeOf();
11
+ });
12
+ test("does not allow invalid field names in returning clause", () => {
13
+ let _;
14
+ });
15
+ });