@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,87 @@
1
+ import { SQLStatement } from "@casekit/sql";
2
+ export type FindBuilder = {
3
+ table: Table;
4
+ columns: SelectedColumn[];
5
+ joins: Join[];
6
+ where?: SQLStatement | null;
7
+ orderBy: OrderBy[];
8
+ limit?: number;
9
+ offset?: number;
10
+ lateralBy?: LateralJoin;
11
+ tableIndex: number;
12
+ for?: "update" | "no key update" | "share" | "key share";
13
+ };
14
+ export type CountBuilder = {
15
+ table: Table;
16
+ joins: Join[];
17
+ where?: SQLStatement | null;
18
+ tableIndex: number;
19
+ for?: "update" | "no key update" | "share" | "key share";
20
+ };
21
+ export type CreateBuilder = {
22
+ table: Table;
23
+ columns: string[];
24
+ values: unknown[][];
25
+ returning: ReturnedColumn[];
26
+ onConflict?: ConflictAction;
27
+ };
28
+ export type UpdateBuilder = {
29
+ table: Table;
30
+ set: [column: string, value: unknown][];
31
+ where: SQLStatement | null;
32
+ returning: ReturnedColumn[];
33
+ };
34
+ export type DeleteBuilder = {
35
+ table: Table;
36
+ where: SQLStatement | null;
37
+ returning: ReturnedColumn[];
38
+ };
39
+ export type Table = {
40
+ schema: string;
41
+ name: string;
42
+ alias: string;
43
+ model: string;
44
+ };
45
+ export type SelectedColumn = {
46
+ table: string;
47
+ name: string;
48
+ alias: string;
49
+ path: string[];
50
+ };
51
+ export type Column = {
52
+ table: string;
53
+ name: string;
54
+ };
55
+ export type OrderBy = {
56
+ column: Column;
57
+ direction: "ASC" | "DESC";
58
+ };
59
+ export type Join = {
60
+ type: "LEFT" | "INNER";
61
+ relation: string;
62
+ table: Table;
63
+ columns: {
64
+ from: Column;
65
+ to: Column;
66
+ }[];
67
+ where?: SQLStatement | null;
68
+ orderBy?: OrderBy[];
69
+ path: string[];
70
+ };
71
+ export type LateralJoin = {
72
+ outerAlias: string;
73
+ innerAlias: string;
74
+ primaryKeys: {
75
+ column: string;
76
+ type: string;
77
+ values: unknown[];
78
+ }[];
79
+ };
80
+ export type ConflictAction = {
81
+ do: "nothing";
82
+ };
83
+ export type ReturnedColumn = {
84
+ name: string;
85
+ alias: string;
86
+ path: string[];
87
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import pg, { QueryResultRow } from "pg";
2
+ import { NormalizedConfig } from "@casekit/orm2-config";
3
+ import { SQLStatement } from "@casekit/sql";
4
+ export declare class Connection {
5
+ protected readonly config: NormalizedConfig;
6
+ protected client: pg.Client | null;
7
+ protected pool: pg.Pool | null;
8
+ protected poolClient: pg.PoolClient | null;
9
+ protected _open: boolean;
10
+ get open(): boolean;
11
+ constructor(config: NormalizedConfig);
12
+ connect(): Promise<void>;
13
+ close(): Promise<void>;
14
+ query<T extends QueryResultRow>(sql: SQLStatement): Promise<pg.QueryResult<T>>;
15
+ startTransaction(): Promise<Transaction>;
16
+ isTransaction(): boolean;
17
+ }
18
+ export declare class Transaction extends Connection {
19
+ private readonly conn;
20
+ private readonly savepoint;
21
+ private readonly nested;
22
+ constructor(config: NormalizedConfig, client?: pg.Client | null, pool?: pg.Pool | null, poolClient?: pg.PoolClient | null, nested?: boolean);
23
+ connect(): Promise<void>;
24
+ close(): Promise<void>;
25
+ query<T extends QueryResultRow>(sql: SQLStatement): Promise<pg.QueryResult<T>>;
26
+ startTransaction(): Promise<Transaction>;
27
+ begin(): Promise<void>;
28
+ rollback(): Promise<void>;
29
+ commit(): Promise<void>;
30
+ isTransaction(): boolean;
31
+ }
@@ -0,0 +1,206 @@
1
+ import pg from "pg";
2
+ import * as uuid from "uuid";
3
+ import { sql } from "@casekit/sql";
4
+ export class Connection {
5
+ config;
6
+ client = null;
7
+ pool = null;
8
+ poolClient = null;
9
+ _open = false;
10
+ get open() {
11
+ return this._open;
12
+ }
13
+ constructor(config) {
14
+ this.config = config;
15
+ }
16
+ async connect() {
17
+ if (this.open) {
18
+ this.config.logger.warn("Tried to connect, but connection is already open");
19
+ return;
20
+ }
21
+ try {
22
+ if (this.config.pool) {
23
+ this.pool = new pg.Pool(this.config.connection ?? undefined);
24
+ }
25
+ else {
26
+ this.client = new pg.Client(this.config.connection ?? undefined);
27
+ await this.client.connect();
28
+ }
29
+ this._open = true;
30
+ }
31
+ catch (e) {
32
+ this.config.logger.error("Error connecting to database", e);
33
+ await this.close();
34
+ throw e;
35
+ }
36
+ }
37
+ async close() {
38
+ if (!this.open) {
39
+ this.config.logger.warn("Tried to close connection, but it is already closed");
40
+ return;
41
+ }
42
+ try {
43
+ if (this.client) {
44
+ await this.client.end();
45
+ }
46
+ if (this.pool) {
47
+ await this.pool.end();
48
+ }
49
+ /* v8 ignore next 3 */
50
+ }
51
+ catch (e) {
52
+ this.config.logger.error("Error closing client", e);
53
+ throw e;
54
+ }
55
+ finally {
56
+ this._open = false;
57
+ }
58
+ }
59
+ async query(sql) {
60
+ try {
61
+ if (!this.open) {
62
+ throw new Error("Tried to run query but not connected");
63
+ }
64
+ else if (this.poolClient) {
65
+ return await this.poolClient.query(sql);
66
+ }
67
+ else if (this.pool) {
68
+ return await this.pool.query(sql);
69
+ }
70
+ else if (this.client) {
71
+ return await this.client.query(sql);
72
+ /* v8 ignore next 3 */
73
+ }
74
+ else {
75
+ throw new Error("Tried to run query but not connected");
76
+ }
77
+ }
78
+ catch (e) {
79
+ this.config.logger.error("Error running query");
80
+ throw e;
81
+ }
82
+ }
83
+ async startTransaction() {
84
+ if (!this.open) {
85
+ /* v8 ignore next */
86
+ throw new Error("Tried to start transaction but not connected");
87
+ }
88
+ const tx = new Transaction(this.config, this.client, this.pool, this.pool ? await this.pool.connect() : null, false);
89
+ await tx.begin();
90
+ return tx;
91
+ }
92
+ isTransaction() {
93
+ return false;
94
+ }
95
+ }
96
+ export class Transaction extends Connection {
97
+ conn;
98
+ savepoint;
99
+ nested;
100
+ constructor(config, client = null, pool = null, poolClient = null, nested = false) {
101
+ /* v8 ignore next 3 */
102
+ if (!client && !poolClient) {
103
+ throw new Error("Tried to start transaction but not connected");
104
+ }
105
+ super(config);
106
+ this.conn = (poolClient ?? client);
107
+ this.client = client;
108
+ this.pool = pool;
109
+ this.poolClient = poolClient;
110
+ this.nested = nested;
111
+ this.savepoint = uuid.v4();
112
+ }
113
+ // eslint-disable-next-line @typescript-eslint/require-await
114
+ async connect() {
115
+ throw new Error("Cannot connect in transaction - already connected");
116
+ }
117
+ // eslint-disable-next-line @typescript-eslint/require-await
118
+ async close() {
119
+ throw new Error("Cannot close connection while in transaction");
120
+ }
121
+ async query(sql) {
122
+ /* v8 ignore start */
123
+ if (!this.open) {
124
+ throw new Error("Tried to run query but transaction is already closed");
125
+ }
126
+ /* v8 ignore stop */
127
+ try {
128
+ return await super.query(sql);
129
+ }
130
+ catch (e) {
131
+ this.config.logger.error("Rolling back transaction due to error", e);
132
+ await this.rollback();
133
+ throw e;
134
+ }
135
+ }
136
+ async startTransaction() {
137
+ if (!this.open) {
138
+ throw new Error("Tried to open nested transaction but parent transaction is closed");
139
+ }
140
+ const tx = new Transaction(this.config, this.client, this.pool, this.poolClient, true);
141
+ await tx.begin();
142
+ return tx;
143
+ }
144
+ async begin() {
145
+ try {
146
+ await this.conn.query(this.nested
147
+ ? sql `SAVEPOINT ${sql.ident(this.savepoint)}`
148
+ : sql `BEGIN`);
149
+ this._open = true;
150
+ /* v8 ignore start */
151
+ }
152
+ catch (e) {
153
+ this.config.logger.error("Error starting transaction", e);
154
+ await this.rollback();
155
+ throw e;
156
+ }
157
+ /* v8 ignore stop */
158
+ }
159
+ async rollback() {
160
+ if (!this.open)
161
+ return;
162
+ try {
163
+ await this.conn.query(this.nested
164
+ ? sql `ROLLBACK TO SAVEPOINT ${sql.ident(this.savepoint)}`
165
+ : sql `ROLLBACK`);
166
+ /* v8 ignore start */
167
+ }
168
+ catch (e) {
169
+ this.config.logger.error("Error rolling back transaction", e);
170
+ throw e;
171
+ /* v8 ignore stop */
172
+ }
173
+ finally {
174
+ this._open = false;
175
+ if (this.poolClient && !this.nested) {
176
+ this.poolClient.release();
177
+ }
178
+ }
179
+ }
180
+ async commit() {
181
+ if (!this.open) {
182
+ throw new Error("Tried to commit transaction but it is closed");
183
+ }
184
+ try {
185
+ await this.conn.query(this.nested
186
+ ? sql `RELEASE SAVEPOINT ${sql.ident(this.savepoint)}`
187
+ : sql `COMMIT`);
188
+ /* v8 ignore start */
189
+ }
190
+ catch (e) {
191
+ this.config.logger.error("Error committing transaction", e);
192
+ await this.rollback();
193
+ throw e;
194
+ /* v8 ignore stop */
195
+ }
196
+ finally {
197
+ this._open = false;
198
+ if (this.poolClient && !this.nested) {
199
+ this.poolClient.release();
200
+ }
201
+ }
202
+ }
203
+ isTransaction() {
204
+ return true;
205
+ }
206
+ }
@@ -0,0 +1,10 @@
1
+ export * as op from "./operators.js";
2
+ export { orm, type Orm } from "./orm.js";
3
+ export type { Config, FieldDefinition, ForeignKeyDefinition, ModelDefinition, ModelDefinitions, ModelType, PostgresDataTypes, RelationDefinition, UniqueConstraintDefinition, } from "@casekit/orm2-schema";
4
+ export type { FindParams } from "./types/FindParams.js";
5
+ export type { FindResult } from "./types/FindResult.js";
6
+ export type { IncludeClause } from "./types/IncludeClause.js";
7
+ export type { OrderByClause } from "./types/OrderByClause.js";
8
+ export type { SelectClause } from "./types/SelectClause.js";
9
+ export type { DefaultOperators, WhereClause } from "./types/WhereClause.js";
10
+ export { SQLStatement, sql } from "@casekit/sql";
package/build/index.js ADDED
@@ -0,0 +1,5 @@
1
+ /* v8 ignore start */
2
+ export * as op from "./operators.js";
3
+ export { orm } from "./orm.js";
4
+ export { SQLStatement, sql } from "@casekit/sql";
5
+ /* v8 ignore stop */
@@ -0,0 +1,59 @@
1
+ export declare const $and: unique symbol;
2
+ export declare const $eq: unique symbol;
3
+ export declare const $gt: unique symbol;
4
+ export declare const $gte: unique symbol;
5
+ export declare const $ilike: unique symbol;
6
+ export declare const $in: unique symbol;
7
+ export declare const $is: unique symbol;
8
+ export declare const $like: unique symbol;
9
+ export declare const $lt: unique symbol;
10
+ export declare const $lte: unique symbol;
11
+ export declare const $ne: unique symbol;
12
+ export declare const $not: unique symbol;
13
+ export declare const $or: unique symbol;
14
+ export declare const defaultOperators: {
15
+ readonly [$eq]: ({ table, column }: {
16
+ table: import("@casekit/sql").SQLStatement;
17
+ column: import("@casekit/sql").SQLStatement;
18
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
19
+ readonly [$gt]: ({ table, column }: {
20
+ table: import("@casekit/sql").SQLStatement;
21
+ column: import("@casekit/sql").SQLStatement;
22
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
23
+ readonly [$gte]: ({ table, column }: {
24
+ table: import("@casekit/sql").SQLStatement;
25
+ column: import("@casekit/sql").SQLStatement;
26
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
27
+ readonly [$ilike]: ({ table, column }: {
28
+ table: import("@casekit/sql").SQLStatement;
29
+ column: import("@casekit/sql").SQLStatement;
30
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
31
+ readonly [$is]: ({ table, column }: {
32
+ table: import("@casekit/sql").SQLStatement;
33
+ column: import("@casekit/sql").SQLStatement;
34
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
35
+ readonly [$like]: ({ table, column }: {
36
+ table: import("@casekit/sql").SQLStatement;
37
+ column: import("@casekit/sql").SQLStatement;
38
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
39
+ readonly [$lt]: ({ table, column }: {
40
+ table: import("@casekit/sql").SQLStatement;
41
+ column: import("@casekit/sql").SQLStatement;
42
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
43
+ readonly [$lte]: ({ table, column }: {
44
+ table: import("@casekit/sql").SQLStatement;
45
+ column: import("@casekit/sql").SQLStatement;
46
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
47
+ readonly [$ne]: ({ table, column }: {
48
+ table: import("@casekit/sql").SQLStatement;
49
+ column: import("@casekit/sql").SQLStatement;
50
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
51
+ readonly [$in]: ({ table, column }: {
52
+ table: import("@casekit/sql").SQLStatement;
53
+ column: import("@casekit/sql").SQLStatement;
54
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
55
+ readonly [$not]: ({ table, column }: {
56
+ table: import("@casekit/sql").SQLStatement;
57
+ column: import("@casekit/sql").SQLStatement;
58
+ }, v: unknown) => import("@casekit/sql").SQLStatement<import("pg").QueryResultRow>;
59
+ };
@@ -0,0 +1,44 @@
1
+ import { sql } from "@casekit/sql";
2
+ export const $and = Symbol("and");
3
+ export const $eq = Symbol("eq");
4
+ export const $gt = Symbol("gt");
5
+ export const $gte = Symbol("gte");
6
+ export const $ilike = Symbol("ilike");
7
+ export const $in = Symbol("in");
8
+ export const $is = Symbol("is");
9
+ export const $like = Symbol("like");
10
+ export const $lt = Symbol("lt");
11
+ export const $lte = Symbol("lte");
12
+ export const $ne = Symbol("ne");
13
+ export const $not = Symbol("not");
14
+ export const $or = Symbol("or");
15
+ export const defaultOperators = {
16
+ [$eq]: ({ table, column }, v) => sql `${table}.${column} = ${v}`,
17
+ [$gt]: ({ table, column }, v) => sql `${table}.${column} > ${v}`,
18
+ [$gte]: ({ table, column }, v) => sql `${table}.${column} >= ${v}`,
19
+ [$ilike]: ({ table, column }, v) => sql `${table}.${column} ILIKE ${v}`,
20
+ [$is]: ({ table, column }, v) => sql `${table}.${column} IS ${v}`,
21
+ [$like]: ({ table, column }, v) => sql `${table}.${column} LIKE ${v}`,
22
+ [$lt]: ({ table, column }, v) => sql `${table}.${column} < ${v}`,
23
+ [$lte]: ({ table, column }, v) => sql `${table}.${column} <= ${v}`,
24
+ [$ne]: ({ table, column }, v) => sql `${table}.${column} != ${v}`,
25
+ [$in]: ({ table, column }, v) => {
26
+ if (!Array.isArray(v))
27
+ throw new Error("Non-array passed to IN clause");
28
+ if (v.length === 0)
29
+ return sql `${table}.${column} IN (NULL)`;
30
+ return sql `${table}.${column} IN (${v.map(sql.value)})`;
31
+ },
32
+ [$not]: ({ table, column }, v) => {
33
+ switch (v) {
34
+ case null:
35
+ return sql `${table}.${column} IS NOT NULL`;
36
+ case true:
37
+ return sql `${table}.${column} IS NOT TRUE`;
38
+ case false:
39
+ return sql `${table}.${column} IS NOT FALSE`;
40
+ default:
41
+ throw new Error("Invalid value passed to $not operator");
42
+ }
43
+ },
44
+ };
@@ -0,0 +1,14 @@
1
+ import { NormalizedConfig } from "@casekit/orm2-config";
2
+ import { ModelDefinition, OperatorDefinitions } from "@casekit/orm2-schema";
3
+ import { Connection } from "./connection.js";
4
+ import { CountParams } from "./types/CountParams.js";
5
+ /**
6
+ * Executes a count query against the database.
7
+ *
8
+ * @param config The normalized ORM configuration
9
+ * @param conn The database connection
10
+ * @param modelName The name of the model to count records for
11
+ * @param query Parameters for the count query, including where and include clauses
12
+ * @returns The number of matching records
13
+ */
14
+ export declare const count: (config: NormalizedConfig, conn: Connection, modelName: string, query: CountParams<Record<string, Required<ModelDefinition>>, OperatorDefinitions, string>) => Promise<number>;
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ import { buildCount } from "./builders/buildCount.js";
3
+ import { countToSql } from "./sql/countToSql.js";
4
+ /**
5
+ * Executes a count query against the database.
6
+ *
7
+ * @param config The normalized ORM configuration
8
+ * @param conn The database connection
9
+ * @param modelName The name of the model to count records for
10
+ * @param query Parameters for the count query, including where and include clauses
11
+ * @returns The number of matching records
12
+ */
13
+ export const count = async (config, conn, modelName, query) => {
14
+ const builder = buildCount(config, modelName, query);
15
+ const statement = countToSql(builder);
16
+ config.logger.info("Executing count", {
17
+ sql: statement.pretty,
18
+ values: statement.values,
19
+ });
20
+ const result = await conn.query(statement);
21
+ return z.coerce.number().parse(result.rows[0]?.["count"] ?? 0);
22
+ };
@@ -0,0 +1,5 @@
1
+ import { NormalizedConfig } from "@casekit/orm2-config";
2
+ import { ModelDefinitions } from "@casekit/orm2-schema";
3
+ import { Connection } from "./connection.js";
4
+ import { CreateManyParams } from "./types/CreateManyParams.js";
5
+ export declare const createMany: (config: NormalizedConfig, conn: Connection, modelName: string, query: CreateManyParams<ModelDefinitions, string>) => Promise<Record<string, unknown>[] | number>;
@@ -0,0 +1,26 @@
1
+ import { buildCreate } from "./builders/buildCreate.js";
2
+ import { createToSql } from "./sql/createToSql.js";
3
+ import { rowToObject } from "./util/rowToObject.js";
4
+ export const createMany = async (config, conn, modelName, query) => {
5
+ if (query.values.length === 0) {
6
+ return query.returning ? [] : 0;
7
+ }
8
+ const builder = buildCreate(config, modelName, query);
9
+ const statement = createToSql(builder);
10
+ config.logger.info("Executing createMany", {
11
+ sql: statement.pretty,
12
+ values: statement.values,
13
+ });
14
+ const tx = await conn.startTransaction();
15
+ try {
16
+ const result = await tx.query(statement);
17
+ await tx.commit();
18
+ return query.returning
19
+ ? result.rows.map((row) => rowToObject(row, builder.returning))
20
+ : (result.rowCount ?? 0);
21
+ }
22
+ catch (e) {
23
+ await tx.rollback();
24
+ throw e;
25
+ }
26
+ };
@@ -0,0 +1,5 @@
1
+ import { NormalizedConfig } from "@casekit/orm2-config";
2
+ import { ModelDefinitions } from "@casekit/orm2-schema";
3
+ import { Connection } from "./connection.js";
4
+ import { CreateOneParams } from "./types/CreateOneParams.js";
5
+ export declare const createOne: (config: NormalizedConfig, conn: Connection, modelName: string, { values, ...query }: CreateOneParams<ModelDefinitions, string>) => Promise<Record<string, unknown> | number | null>;
@@ -0,0 +1,34 @@
1
+ import { buildCreate } from "./builders/buildCreate.js";
2
+ import { createToSql } from "./sql/createToSql.js";
3
+ import { rowToObject } from "./util/rowToObject.js";
4
+ export const createOne = async (config, conn, modelName, { values, ...query }) => {
5
+ const builder = buildCreate(config, modelName, {
6
+ ...query,
7
+ values: [values],
8
+ });
9
+ const statement = createToSql(builder);
10
+ config.logger.info("Executing createOne", {
11
+ sql: statement.pretty,
12
+ values: statement.values,
13
+ });
14
+ const tx = await conn.startTransaction();
15
+ try {
16
+ const result = await tx.query(statement);
17
+ if (!result.rowCount && query.onConflict?.do !== "nothing") {
18
+ throw new Error("createOne failed to create a row");
19
+ }
20
+ await tx.commit();
21
+ if (query.returning) {
22
+ return result.rowCount === 0
23
+ ? null
24
+ : rowToObject(result.rows[0], builder.returning);
25
+ }
26
+ else {
27
+ return result.rowCount;
28
+ }
29
+ }
30
+ catch (e) {
31
+ await tx.rollback();
32
+ throw e;
33
+ }
34
+ };
package/build/orm.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import { QueryResultRow } from "pg";
2
+ import { DeepReadonly } from "ts-essentials";
3
+ import { ZodSchema } from "zod";
4
+ import { NormalizedConfig } from "@casekit/orm2-config";
5
+ import { Config, ModelDefinitions, ModelName, OperatorDefinitions } from "@casekit/orm2-schema";
6
+ import { SQLStatement } from "@casekit/sql";
7
+ import type { Conform, Simplify } from "@casekit/toolbox";
8
+ import { Connection, Transaction } from "./connection.js";
9
+ import { CountParams } from "./types/CountParams.js";
10
+ import { CreateManyParams } from "./types/CreateManyParams.js";
11
+ import { CreateManyResult } from "./types/CreateManyResult.js";
12
+ import { CreateOneParams } from "./types/CreateOneParams.js";
13
+ import { CreateOneResult } from "./types/CreateOneResult.js";
14
+ import { DeleteManyResult } from "./types/DeleteManyResult.js";
15
+ import { DeleteOneResult } from "./types/DeleteOneResult.js";
16
+ import { DeleteParams } from "./types/DeleteParams.js";
17
+ import { FindParams } from "./types/FindParams.js";
18
+ import { FindResult } from "./types/FindResult.js";
19
+ import { Middleware } from "./types/Middleware.js";
20
+ import { RestrictModels } from "./types/RestrictModels.js";
21
+ import { UpdateManyResult } from "./types/UpdateManyResult.js";
22
+ import { UpdateOneResult } from "./types/UpdateOneResult.js";
23
+ import { UpdateParams } from "./types/UpdateParams.js";
24
+ export declare const orm: <const C extends Config>(config: C) => Orm<C>;
25
+ export declare class Orm<const C extends Config = Config, const Models extends ModelDefinitions = C["models"], const Operators extends OperatorDefinitions = C["operators"] extends NonNullable<C["operators"]> ? C["operators"] : {
26
+ where: never;
27
+ }> {
28
+ readonly config: NormalizedConfig;
29
+ private readonly _connection;
30
+ private readonly _middleware;
31
+ constructor(config: NormalizedConfig, connection?: Connection | Transaction, middleware?: Middleware[]);
32
+ connect(): Promise<void>;
33
+ close(): Promise<void>;
34
+ transact<T>(fn: (db: Orm<C>) => Promise<T>, options?: {
35
+ rollback: boolean;
36
+ }): Promise<T>;
37
+ private getNextMiddleware;
38
+ findOne<const M extends ModelName<Models>, const Q extends FindParams<Models, Operators, M>>(modelName: M, query: Conform<FindParams<Models, Operators, M>, Q>): Promise<DeepReadonly<Simplify<FindResult<Models, Operators, M, Q>>>>;
39
+ findMany<const M extends ModelName<Models>, const Q extends FindParams<Models, Operators, M>>(modelName: M, query: Conform<FindParams<Models, Operators, M>, Q>): Promise<DeepReadonly<Simplify<FindResult<Models, Operators, M, Q>>[]>>;
40
+ count<const M extends ModelName<Models>, const Q extends CountParams<Models, Operators, M>>(modelName: M, query: Conform<CountParams<Models, Operators, M>, Q>): Promise<number>;
41
+ createOne<const M extends ModelName<Models>, const Q extends CreateOneParams<Models, M>>(modelName: M, query: Conform<CreateOneParams<Models, M>, Q>): Promise<DeepReadonly<Simplify<CreateOneResult<Models, M, Q>>>>;
42
+ createMany<const M extends ModelName<Models>, const Q extends CreateManyParams<Models, M>>(modelName: M, query: Conform<CreateManyParams<Models, M>, Q>): Promise<DeepReadonly<Simplify<CreateManyResult<Models, M, Q>>>>;
43
+ updateOne<const M extends ModelName<Models>, const Q extends UpdateParams<Models, Operators, M>>(modelName: M, query: Conform<UpdateParams<Models, Operators, M>, Q>): Promise<DeepReadonly<Simplify<UpdateOneResult<Models, Operators, M, Q>>>>;
44
+ updateMany<const M extends ModelName<Models>, const Q extends UpdateParams<Models, Operators, M>>(modelName: M, query: Conform<UpdateParams<Models, Operators, M>, Q>): Promise<DeepReadonly<Simplify<UpdateManyResult<Models, Operators, M, Q>>>>;
45
+ deleteOne<const M extends ModelName<Models>, const Q extends DeleteParams<Models, Operators, M>>(modelName: M, query: Conform<DeleteParams<Models, Operators, M>, Q>): Promise<DeepReadonly<Simplify<DeleteOneResult<Models, Operators, M, Q>>>>;
46
+ deleteMany<const M extends ModelName<Models>, const Q extends DeleteParams<Models, Operators, M>>(modelName: M, query: Conform<DeleteParams<Models, Operators, M>, Q>): Promise<DeepReadonly<Simplify<DeleteManyResult<Models, Operators, M, Q>>>>;
47
+ /**
48
+ * In some parts of your app - e.g. in the non-tenant specific parts of
49
+ * a multi-tenant app, where you don't want to restrict by tenant_id -
50
+ * you may want to only make a subset of models available for querying.
51
+ * This method allows you to do that by creating a restricted copy of
52
+ * the ORM with access only to the models you specify.
53
+ */
54
+ restrict<const Allowed extends [...ModelName<Models>[]]>(allowed: Allowed): Orm<RestrictModels<C, Allowed[number]>>;
55
+ /** Returns a new ORM instance with middleware applied.
56
+ * The new ORM instance shares the same connection as
57
+ * the one it is called on, but the original instance
58
+ * does not have the middleware applied. This means
59
+ * this method can be called multiple times to apply
60
+ * different middleware to different ORM instances.
61
+ */
62
+ middleware(middleware: Middleware[]): Orm<C>;
63
+ /**
64
+ * await db.query(z.object({ foo: z.string() }))`
65
+ * SELECT foo FROM table WHERE foo = ${value}
66
+ * `;
67
+ */
68
+ query<const ResultType extends QueryResultRow = QueryResultRow>(schema: ZodSchema<ResultType>): (fragments: TemplateStringsArray, ...values: unknown[]) => Promise<ResultType[]>;
69
+ /**
70
+ * const statement = sql<{ one: number }>`SELECT 1 as one`;
71
+ * await db.query(statement);
72
+ */
73
+ query<const ResultType extends QueryResultRow = QueryResultRow>(statement: SQLStatement<ResultType>): Promise<ResultType[]>;
74
+ /**
75
+ * await db.query<{ one: number }>`SELECT 1 as one`;
76
+ */
77
+ query<ResultType extends QueryResultRow = QueryResultRow>(fragments: TemplateStringsArray, ...values: unknown[]): Promise<ResultType[]>;
78
+ private queryWithTemplateLiteral;
79
+ private queryWithSQLStatement;
80
+ private queryWithSchema;
81
+ }
@@ -0,0 +1,5 @@
1
+ import { NormalizedConfig } from "@casekit/orm2-config";
2
+ import { ModelDefinitions, OperatorDefinitions } from "@casekit/orm2-schema";
3
+ import { Connection } from "./connection.js";
4
+ import { DeleteParams } from "./types/DeleteParams.js";
5
+ export declare const deleteMany: (config: NormalizedConfig, conn: Connection, modelName: string, query: DeleteParams<ModelDefinitions, OperatorDefinitions, string>) => Promise<Record<string, unknown>[] | number>;