@casekit/orm 0.0.1-alpha.15 → 0.0.1-alpha.17

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 (218) hide show
  1. package/lib/orm.query.test.d.ts +2 -0
  2. package/lib/orm.query.test.d.ts.map +1 -0
  3. package/lib/orm.query.test.js +22 -0
  4. package/lib/orm.query.test.js.map +1 -0
  5. package/lib/queries/findMany.d.ts.map +1 -1
  6. package/lib/queries/findMany.js +3 -3
  7. package/lib/queries/findMany.js.map +1 -1
  8. package/package.json +3 -6
  9. package/src/Connection.ts +65 -0
  10. package/src/errors.ts +18 -0
  11. package/src/index.ts +16 -0
  12. package/src/logger.ts +3 -0
  13. package/src/migrate/commands/implode.ts +46 -0
  14. package/src/migrate/index.ts +1 -0
  15. package/src/migrate/migrator.ts +24 -0
  16. package/src/migrate/sql/createExtensionsSql.test.ts +26 -0
  17. package/src/migrate/sql/createExtensionsSql.ts +16 -0
  18. package/src/migrate/sql/createForeignKeyConstraintSql.test.ts +50 -0
  19. package/src/migrate/sql/createForeignKeyConstraintSql.ts +44 -0
  20. package/src/migrate/sql/createSchemasSql.test.ts +81 -0
  21. package/src/migrate/sql/createSchemasSql.ts +15 -0
  22. package/src/migrate/sql/createTableSql.properties.ts +38 -0
  23. package/src/migrate/sql/createTableSql.test.ts +74 -0
  24. package/src/migrate/sql/createTableSql.ts +53 -0
  25. package/src/migrate/sql/createUniqueConstraintSql.ts +27 -0
  26. package/src/migrate/sql/dropSchemasSql.ts +15 -0
  27. package/src/migrate/sql/dropTableSql.ts +13 -0
  28. package/src/orm.query.test.ts +28 -0
  29. package/src/orm.ts +370 -0
  30. package/src/pull/index.ts +1 -0
  31. package/src/pull/introspect/getForeignKeys.ts +64 -0
  32. package/src/pull/introspect/getPrimaryKeys.ts +26 -0
  33. package/src/pull/introspect/getTables.ts +51 -0
  34. package/src/pull/introspect/getUniqueConstraints.ts +39 -0
  35. package/src/pull/parse/parseCreateUniqueIndexStatement.test.ts +14 -0
  36. package/src/pull/parse/parseCreateUniqueIndexStatement.ts +19 -0
  37. package/src/pull/pull.ts +78 -0
  38. package/src/pull/render/renderModel.test.ts +144 -0
  39. package/src/pull/render/renderModel.ts +141 -0
  40. package/src/pull/render/renderModelsIndex.ts +24 -0
  41. package/src/pull/render/renderRelations.ts +77 -0
  42. package/src/pull/render/renderRelationsIndex.ts +24 -0
  43. package/src/pull/types/ColumnMeta.ts +10 -0
  44. package/src/pull/types/ForeignKey.ts +6 -0
  45. package/src/pull/types/PrimaryKey.ts +6 -0
  46. package/src/pull/types/UniqueConstraint.ts +8 -0
  47. package/src/pull/util/format.ts +17 -0
  48. package/src/pull/util/quote.ts +7 -0
  49. package/src/pull/util/unquote.ts +9 -0
  50. package/src/queries/clauses/IncludeClause.ts +39 -0
  51. package/src/queries/clauses/LateralByClause.ts +4 -0
  52. package/src/queries/clauses/ReturningClause.ts +7 -0
  53. package/src/queries/clauses/SelectClause.ts +7 -0
  54. package/src/queries/clauses/WhereClause.ts +16 -0
  55. package/src/queries/clauses/helpers/OptionalColumn.ts +18 -0
  56. package/src/queries/clauses/helpers/OptionalParams.ts +14 -0
  57. package/src/queries/clauses/helpers/RequiredColumn.ts +8 -0
  58. package/src/queries/clauses/helpers/RequiredParams.ts +14 -0
  59. package/src/queries/clauses/include/IncludedRelationModel.ts +13 -0
  60. package/src/queries/clauses/include/IncludedRelationName.ts +11 -0
  61. package/src/queries/clauses/include/IncludedRelationQuery.ts +20 -0
  62. package/src/queries/clauses/where/buildWhereClause.ts +121 -0
  63. package/src/queries/clauses/where/buildWhereClauses.test.ts +145 -0
  64. package/src/queries/clauses/where/buildWhereClauses.ts +45 -0
  65. package/src/queries/clauses/where/operators.ts +13 -0
  66. package/src/queries/clauses/where/types/WhereClauseValue.ts +39 -0
  67. package/src/queries/count/buildCount.ts +77 -0
  68. package/src/queries/count/countToSql.ts +66 -0
  69. package/src/queries/count/tests/count.test.ts +35 -0
  70. package/src/queries/count/types/BaseCountParams.ts +11 -0
  71. package/src/queries/count/types/CountBuilder.ts +45 -0
  72. package/src/queries/count/types/CountParams.ts +27 -0
  73. package/src/queries/count.ts +33 -0
  74. package/src/queries/create/buildCreate.ts +67 -0
  75. package/src/queries/create/createResultSchema.ts +24 -0
  76. package/src/queries/create/createToSql.ts +44 -0
  77. package/src/queries/create/tests/createMany.varied-keys.test.ts +28 -0
  78. package/src/queries/create/tests/createOne.test-d.ts +116 -0
  79. package/src/queries/create/tests/createOne.test.ts +197 -0
  80. package/src/queries/create/types/BaseCreateManyParams.ts +7 -0
  81. package/src/queries/create/types/BaseCreateOneParams.ts +7 -0
  82. package/src/queries/create/types/CreateManyParams.ts +15 -0
  83. package/src/queries/create/types/CreateManyResult.ts +17 -0
  84. package/src/queries/create/types/CreateOneParams.ts +22 -0
  85. package/src/queries/create/types/CreateOneResult.ts +17 -0
  86. package/src/queries/createMany.ts +38 -0
  87. package/src/queries/createOne.ts +27 -0
  88. package/src/queries/delete/buildDelete.ts +56 -0
  89. package/src/queries/delete/deleteResultSchema.ts +23 -0
  90. package/src/queries/delete/deleteToSql.ts +48 -0
  91. package/src/queries/delete/tests/deleteOne.test.ts +108 -0
  92. package/src/queries/delete/types/BaseDeleteParams.ts +9 -0
  93. package/src/queries/delete/types/DeleteManyResult.ts +16 -0
  94. package/src/queries/delete/types/DeleteOneResult.ts +16 -0
  95. package/src/queries/delete/types/DeleteParams.ts +12 -0
  96. package/src/queries/deleteMany.ts +33 -0
  97. package/src/queries/deleteOne.ts +32 -0
  98. package/src/queries/find/buildFind.ts +138 -0
  99. package/src/queries/find/findResultSchema.ts +32 -0
  100. package/src/queries/find/findToSql.test.ts +123 -0
  101. package/src/queries/find/findToSql.ts +141 -0
  102. package/src/queries/find/getIncludedManyToManyRelations.ts +49 -0
  103. package/src/queries/find/getIncludedOneToManyRelations.ts +44 -0
  104. package/src/queries/find/tests/findMany.include.test.ts +107 -0
  105. package/src/queries/find/tests/findMany.limit.test-d.ts +75 -0
  106. package/src/queries/find/tests/findMany.limit.test.ts +176 -0
  107. package/src/queries/find/tests/findMany.nullable-relations.test.ts +127 -0
  108. package/src/queries/find/tests/findMany.orderBy.test-d.ts +84 -0
  109. package/src/queries/find/tests/findMany.orderBy.test.ts +184 -0
  110. package/src/queries/find/tests/findMany.select.test-d.ts +117 -0
  111. package/src/queries/find/tests/findMany.select.test.ts +188 -0
  112. package/src/queries/find/tests/findMany.too-deep.test-d.ts +154 -0
  113. package/src/queries/find/tests/findMany.where.test-d.ts +85 -0
  114. package/src/queries/find/tests/findMany.where.test.ts +76 -0
  115. package/src/queries/find/tests/middleware.find.where.test.ts +467 -0
  116. package/src/queries/find/types/BaseFindParams.ts +18 -0
  117. package/src/queries/find/types/FindBuilder.ts +73 -0
  118. package/src/queries/find/types/FindManyParams.ts +24 -0
  119. package/src/queries/find/types/FindManyResult.ts +13 -0
  120. package/src/queries/find/types/FindOneParams.ts +17 -0
  121. package/src/queries/find/types/FindOneResult.ts +50 -0
  122. package/src/queries/findMany.ts +138 -0
  123. package/src/queries/findOne.ts +30 -0
  124. package/src/queries/middleware/Middleware.ts +53 -0
  125. package/src/queries/middleware/ValuesMiddleware.ts +9 -0
  126. package/src/queries/middleware/WhereMiddleware.ts +16 -0
  127. package/src/queries/update/buildUpdate.ts +76 -0
  128. package/src/queries/update/tests/updateOne.test.ts +118 -0
  129. package/src/queries/update/types/BaseUpdateParams.ts +10 -0
  130. package/src/queries/update/types/UpdateManyResult.ts +16 -0
  131. package/src/queries/update/types/UpdateOneResult.ts +16 -0
  132. package/src/queries/update/types/UpdateParams.ts +14 -0
  133. package/src/queries/update/types/UpdateValues.ts +12 -0
  134. package/src/queries/update/updateResultSchema.ts +23 -0
  135. package/src/queries/update/updateToSql.ts +43 -0
  136. package/src/queries/updateMany.ts +33 -0
  137. package/src/queries/updateOne.ts +33 -0
  138. package/src/queries/util/hasConditions.test.ts +36 -0
  139. package/src/queries/util/hasConditions.ts +14 -0
  140. package/src/queries/util/rowToObject.test.ts +76 -0
  141. package/src/queries/util/rowToObject.ts +13 -0
  142. package/src/queries/util/tableAlias.test.ts +20 -0
  143. package/src/queries/util/tableAlias.ts +10 -0
  144. package/src/schema/populate/composeMiddleware.ts +51 -0
  145. package/src/schema/populate/populateConfiguration.ts +48 -0
  146. package/src/schema/populate/populateModel.ts +98 -0
  147. package/src/schema/populate/suggestedColumnSchema.ts +62 -0
  148. package/src/schema/types/base/BaseColumn.ts +10 -0
  149. package/src/schema/types/base/BaseConfiguration.ts +14 -0
  150. package/src/schema/types/base/BaseModel.ts +12 -0
  151. package/src/schema/types/base/BaseModels.ts +3 -0
  152. package/src/schema/types/base/BaseOrm.ts +8 -0
  153. package/src/schema/types/base/BaseRelation.ts +19 -0
  154. package/src/schema/types/base/BaseRelations.ts +3 -0
  155. package/src/schema/types/constraints/ForeignKey.ts +13 -0
  156. package/src/schema/types/constraints/UniqueConstraint.ts +9 -0
  157. package/src/schema/types/helpers/ColumnName.ts +6 -0
  158. package/src/schema/types/helpers/ColumnType.ts +23 -0
  159. package/src/schema/types/helpers/Columns.ts +3 -0
  160. package/src/schema/types/helpers/HasDefault.ts +11 -0
  161. package/src/schema/types/helpers/IsNullable.ts +7 -0
  162. package/src/schema/types/helpers/IsProvided.ts +8 -0
  163. package/src/schema/types/helpers/IsSerial.ts +10 -0
  164. package/src/schema/types/helpers/ModelName.ts +6 -0
  165. package/src/schema/types/loose/LooseColumnDefinition.ts +80 -0
  166. package/src/schema/types/loose/LooseModelDefinition.ts +47 -0
  167. package/src/schema/types/loose/LooseModelDefinitions.ts +3 -0
  168. package/src/schema/types/loose/LooseRelationDefinition.ts +10 -0
  169. package/src/schema/types/loose/LooseRelationsDefinition.ts +8 -0
  170. package/src/schema/types/loose/LooseRelationsDefinitions.ts +7 -0
  171. package/src/schema/types/postgres/DataType.ts +65 -0
  172. package/src/schema/types/relations/ManyToManyRelation.ts +15 -0
  173. package/src/schema/types/relations/ManyToOneRelation.ts +14 -0
  174. package/src/schema/types/relations/OneToManyRelation.ts +12 -0
  175. package/src/schema/types/strict/ColumnDefinition.ts +81 -0
  176. package/src/schema/types/strict/ModelDefinition.ts +47 -0
  177. package/src/schema/types/strict/ModelDefinitions.ts +3 -0
  178. package/src/schema/types/strict/RelationDefinition.ts +13 -0
  179. package/src/schema/types/strict/RelationsDefinition.ts +8 -0
  180. package/src/schema/types/strict/RelationsDefinitions.ts +7 -0
  181. package/src/schema/validate/validateConfiguration.ts +9 -0
  182. package/src/schema/validate/validateModel.ts +32 -0
  183. package/src/sql/SQLStatement.test.ts +112 -0
  184. package/src/sql/SQLStatement.ts +86 -0
  185. package/src/sql/index.ts +2 -0
  186. package/src/sql/sql.ts +47 -0
  187. package/src/test/db/index.ts +27 -0
  188. package/src/test/db/models/foo.model.ts +24 -0
  189. package/src/test/db/models/foo.relations.ts +4 -0
  190. package/src/test/db/models/post.model.ts +34 -0
  191. package/src/test/db/models/post.relations.ts +21 -0
  192. package/src/test/db/models/tenant.model.ts +14 -0
  193. package/src/test/db/models/tenant.relations.ts +22 -0
  194. package/src/test/db/models/tenantUser.model.ts +23 -0
  195. package/src/test/db/models/tenantUser.relations.ts +15 -0
  196. package/src/test/db/models/user.model.ts +29 -0
  197. package/src/test/db/models/user.relations.ts +38 -0
  198. package/src/test/db/models.ts +15 -0
  199. package/src/test/db/relations.ts +13 -0
  200. package/src/test/gen/column.ts +39 -0
  201. package/src/test/gen/index.ts +2 -0
  202. package/src/test/gen/model.ts +58 -0
  203. package/src/test/gen/sqldate.ts +8 -0
  204. package/src/test/globalSetup.ts +6 -0
  205. package/src/test/seed/index.ts +75 -0
  206. package/src/test/util/withRollback.ts +18 -0
  207. package/src/test/util/withTransaction.ts +19 -0
  208. package/src/types/ColumnName.ts +6 -0
  209. package/src/types/ColumnType.ts +20 -0
  210. package/src/types/Configuration.ts +21 -0
  211. package/src/types/ModelType.ts +20 -0
  212. package/src/types/util/DeepRequired.ts +7 -0
  213. package/src/types/util/DisallowExtraKeys.ts +5 -0
  214. package/src/types/util/NonEmptyArray.ts +1 -0
  215. package/src/types/util/Simplify.ts +8 -0
  216. package/src/util/ensureArray.ts +4 -0
  217. package/src/util/interleave.test.ts +35 -0
  218. package/src/util/interleave.ts +8 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=orm.query.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm.query.test.d.ts","sourceRoot":"","sources":["../src/orm.query.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { db } from "./test/db";
3
+ import { seed } from "./test/seed";
4
+ describe("orm.query", () => {
5
+ test("allows arbitrary sql queries to be run against the database", async () => {
6
+ await db.transact(async (db) => {
7
+ await seed(db, {
8
+ users: [
9
+ {
10
+ username: "Russell",
11
+ tenants: [{ name: "Popova Park", posts: 6 }],
12
+ },
13
+ ],
14
+ });
15
+ const result = await db.query `
16
+ select count(1)::int as total from casekit.post;
17
+ `;
18
+ expect(result[0]).toEqual({ total: 6 });
19
+ }, { rollback: true });
20
+ });
21
+ });
22
+ //# sourceMappingURL=orm.query.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm.query.test.js","sourceRoot":"","sources":["../src/orm.query.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACvB,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,EAAE,CAAC,QAAQ,CACb,KAAK,EAAE,EAAE,EAAE,EAAE;YACT,MAAM,IAAI,CAAC,EAAE,EAAE;gBACX,KAAK,EAAE;oBACH;wBACI,QAAQ,EAAE,SAAS;wBACnB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;qBAC/C;iBACJ;aACJ,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,CAAmB;;iBAE/C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,EAAE,CACrB,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"findMany.d.ts","sourceRoot":"","sources":["../../src/queries/findMany.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,eAAO,MAAM,QAAQ,SACX,UAAU,UACR,iBAAiB,KACtB,MAAM,SACF,cAAc,uCAkHxB,CAAC"}
1
+ {"version":3,"file":"findMany.d.ts","sourceRoot":"","sources":["../../src/queries/findMany.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQ3C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,eAAO,MAAM,QAAQ,SACX,UAAU,UACR,iBAAiB,KACtB,MAAM,SACF,cAAc,uCAsHxB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { dropRight, get, groupBy, set } from "lodash-es";
1
+ import { dropRight, get, groupBy, set, uniq } from "lodash-es";
2
2
  import hash from "object-hash";
3
3
  import { OrmError } from "../errors";
4
4
  import { logger } from "../logger";
@@ -28,7 +28,7 @@ export const findMany = async (conn, config, m, query) => {
28
28
  const fk = ensureArray(relation.foreignKey);
29
29
  const lateralBy = fk.map((c, index) => ({
30
30
  column: c,
31
- values: results.map((result) => get(result, [...dropRight(path, 1), pk[index]])),
31
+ values: uniq(results.map((result) => get(result, [...dropRight(path, 1), pk[index]]))),
32
32
  }));
33
33
  return findMany(conn, config, relation.model, {
34
34
  ...query,
@@ -61,7 +61,7 @@ export const findMany = async (conn, config, m, query) => {
61
61
  const fk = ensureArray(relation.foreignKey);
62
62
  const lateralBy = fk.map((c, index) => ({
63
63
  column: c,
64
- values: results.map((result) => get(result, [...dropRight(path, 1), pk[index]])),
64
+ values: uniq(results.map((result) => get(result, [...dropRight(path, 1), pk[index]]))),
65
65
  }));
66
66
  return findMany(conn, config, relation.through, {
67
67
  select: ensureArray(relation.foreignKey),
@@ -1 +1 @@
1
- {"version":3,"file":"findMany.js","sourceRoot":"","sources":["../../src/queries/findMany.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"findMany.js","sourceRoot":"","sources":["../../src/queries/findMany.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@casekit/orm",
3
- "version": "0.0.1-alpha.15",
3
+ "version": "0.0.1-alpha.17",
4
4
  "description": "A simple ORM",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -9,11 +9,8 @@
9
9
  ".": "./lib/index.js"
10
10
  },
11
11
  "files": [
12
- "./lib/*",
13
- "!./lib/**.test.js",
14
- "!./lib/**.test.js.map",
15
- "!./lib/**.test.d.ts",
16
- "!./lib/**.test.d.ts.map"
12
+ "./src/*",
13
+ "./lib/*"
17
14
  ],
18
15
  "keywords": [],
19
16
  "author": "",
@@ -0,0 +1,65 @@
1
+ import pg, { QueryResultRow } from "pg";
2
+ import pgfmt from "pg-format";
3
+ import * as uuid from "uuid";
4
+
5
+ import { SQLStatement } from "./sql";
6
+
7
+ export class Connection {
8
+ constructor(
9
+ private pool: pg.Pool,
10
+ private client?: pg.PoolClient,
11
+ ) {}
12
+
13
+ public query = async <T extends QueryResultRow>(query: SQLStatement) => {
14
+ if (this.client) {
15
+ return this.client.query<T>(query);
16
+ } else {
17
+ return this.pool.query(query);
18
+ }
19
+ };
20
+
21
+ public transact = async <T>(
22
+ fn: (conn: Connection) => Promise<T>,
23
+ { rollback = false }: { rollback?: boolean } = {},
24
+ ) => {
25
+ if (this.client) {
26
+ const savepoint = uuid.v4();
27
+ try {
28
+ await this.client.query(pgfmt("SAVEPOINT %I", savepoint));
29
+ const result = await fn(this);
30
+ if (rollback) {
31
+ await this.client.query(
32
+ pgfmt("ROLLBACK TO SAVEPOINT %I", savepoint),
33
+ );
34
+ } else {
35
+ await this.client.query(
36
+ pgfmt("RELEASE SAVEPOINT %I", savepoint),
37
+ );
38
+ }
39
+ return result;
40
+ } catch (e) {
41
+ await this.client.query(
42
+ pgfmt("ROLLBACK TO SAVEPOINT %I", savepoint),
43
+ );
44
+ throw e;
45
+ }
46
+ } else {
47
+ const client = await this.pool.connect();
48
+ try {
49
+ await client.query("BEGIN");
50
+ const result = await fn(new Connection(this.pool, client));
51
+ if (rollback) {
52
+ await client.query("ROLLBACK");
53
+ } else {
54
+ await client.query("COMMIT");
55
+ }
56
+ return result;
57
+ } catch (e) {
58
+ await client.query("ROLLBACK");
59
+ throw e;
60
+ } finally {
61
+ client.release();
62
+ }
63
+ }
64
+ };
65
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { BaseModel } from "./schema/types/base/BaseModel";
2
+
3
+ type OrmErrorMeta = {
4
+ model?: [string, BaseModel];
5
+ data?: Record<string, unknown>;
6
+ };
7
+
8
+ export class OrmError extends Error {
9
+ meta: OrmErrorMeta | undefined;
10
+
11
+ constructor(message: string, meta?: OrmErrorMeta) {
12
+ super();
13
+ this.message = message;
14
+ this.meta = meta;
15
+ }
16
+ }
17
+
18
+ export class InvalidModelDefinitionError extends OrmError {}
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ export { OrmError } from "./errors";
2
+ export { migrator, type Migrator } from "./migrate";
3
+ export { Orm, orm } from "./orm";
4
+ export { pull } from "./pull";
5
+ export * from "./queries/clauses/where/operators";
6
+ export { type Middleware } from "./queries/middleware/Middleware";
7
+ /**
8
+ * TODO find a way to use the strict definitions here
9
+ * without destroying VS Code autocomplete performance
10
+ */
11
+ export { type LooseModelDefinition as ModelDefinition } from "./schema/types/loose/LooseModelDefinition";
12
+ export { type LooseRelationsDefinition as RelationsDefinition } from "./schema/types/loose/LooseRelationsDefinition";
13
+ export { SQLStatement, sql } from "./sql";
14
+ export type { ColumnName } from "./types/ColumnName";
15
+ export type { ColumnType } from "./types/ColumnType";
16
+ export type { ModelType } from "./types/ModelType";
package/src/logger.ts ADDED
@@ -0,0 +1,3 @@
1
+ import pino from "pino";
2
+
3
+ export const logger = pino({ enabled: process.env.NODE_ENV !== "test" });
@@ -0,0 +1,46 @@
1
+ import { BaseOrm } from "../../schema/types/base/BaseOrm";
2
+ import { SQLStatement } from "../../sql";
3
+ import { createExtensionsSql } from "../sql/createExtensionsSql";
4
+ import { createForeignKeyConstraintSql } from "../sql/createForeignKeyConstraintSql";
5
+ import { createSchemasSql } from "../sql/createSchemasSql";
6
+ import { createTableSql } from "../sql/createTableSql";
7
+ import { createUniqueConstraintSql } from "../sql/createUniqueConstraintSql";
8
+ import { dropSchemasSql } from "../sql/dropSchemasSql";
9
+
10
+ export const implode = async (
11
+ db: BaseOrm,
12
+ { dryRun, output }: { dryRun: boolean; output: boolean },
13
+ ) => {
14
+ const statement = new SQLStatement();
15
+
16
+ statement.push(dropSchemasSql(db), "\n");
17
+ statement.push(createSchemasSql(db), "\n");
18
+ statement.push(createExtensionsSql(db), "\n");
19
+
20
+ for (const model of Object.values(db.models)) {
21
+ statement.push(createTableSql(model), "\n");
22
+ for (const constraint of model.uniqueConstraints) {
23
+ statement.push(createUniqueConstraintSql(model, constraint), "\n");
24
+ }
25
+ }
26
+
27
+ for (const model of Object.values(db.models)) {
28
+ for (const foreignKey of model.foreignKeys) {
29
+ statement.push(
30
+ createForeignKeyConstraintSql(model, foreignKey),
31
+ "\n",
32
+ );
33
+ }
34
+ }
35
+
36
+ if (output || process.env.ORM_VERBOSE_LOGGING) console.log(statement.text);
37
+
38
+ if (!dryRun) {
39
+ try {
40
+ await db.connection.query(statement);
41
+ } catch (e) {
42
+ console.log(e);
43
+ throw e;
44
+ }
45
+ }
46
+ };
@@ -0,0 +1 @@
1
+ export { type Migrator, migrator } from "./migrator";
@@ -0,0 +1,24 @@
1
+ import { Orm } from "..";
2
+ import { BaseOrm } from "../schema/types/base/BaseOrm";
3
+ import { LooseModelDefinitions } from "../schema/types/loose/LooseModelDefinitions";
4
+ import { LooseRelationsDefinitions } from "../schema/types/loose/LooseRelationsDefinitions";
5
+ import { implode } from "./commands/implode";
6
+
7
+ export class Migrator {
8
+ public db: BaseOrm;
9
+
10
+ constructor(db: BaseOrm) {
11
+ this.db = db;
12
+ }
13
+
14
+ public async implode(opts = { dryRun: true, output: true }) {
15
+ await implode(this.db, opts);
16
+ }
17
+ }
18
+
19
+ export const migrator = <
20
+ Models extends LooseModelDefinitions,
21
+ Relations extends LooseRelationsDefinitions<Models>,
22
+ >(
23
+ db: Orm<Models, Relations>,
24
+ ) => new Migrator(db as BaseOrm);
@@ -0,0 +1,26 @@
1
+ import { unindent } from "@casekit/unindent";
2
+
3
+ import pg from "pg";
4
+ import { describe, expect, test } from "vitest";
5
+
6
+ import { orm } from "../../orm";
7
+ import { createExtensionsSql } from "./createExtensionsSql";
8
+
9
+ describe("createExtensionsSql", () => {
10
+ test("it generates a CREATE EXTENSION command for each extension", () => {
11
+ const db = orm({
12
+ extensions: ["uuid-ossp", "postgis"],
13
+ models: {},
14
+ pool: new pg.Pool(),
15
+ });
16
+ expect(createExtensionsSql(db)?.text).toEqual(unindent`
17
+ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
18
+ CREATE EXTENSION IF NOT EXISTS postgis;
19
+ `);
20
+ });
21
+
22
+ test("if no extensions are specified, it returns null", () => {
23
+ const db = orm({ models: {}, pool: new pg.Pool() });
24
+ expect(createExtensionsSql(db)).toEqual(null);
25
+ });
26
+ });
@@ -0,0 +1,16 @@
1
+ import pgfmt from "pg-format";
2
+
3
+ import { BaseOrm } from "../../schema/types/base/BaseOrm";
4
+ import { SQLStatement } from "../../sql";
5
+
6
+ export const createExtensionsSql = (db: BaseOrm): SQLStatement | null => {
7
+ if (db.config.extensions?.length === 0) return null;
8
+
9
+ return (
10
+ new SQLStatement(
11
+ db.config.extensions
12
+ ?.map((e) => pgfmt("CREATE EXTENSION IF NOT EXISTS %I;", e))
13
+ .join("\n"),
14
+ ) ?? null
15
+ );
16
+ };
@@ -0,0 +1,50 @@
1
+ import { unindent } from "@casekit/unindent";
2
+
3
+ import pg from "pg";
4
+ import { describe, expect, test } from "vitest";
5
+
6
+ import { ModelDefinition, orm, sql } from "../../";
7
+ import { createForeignKeyConstraintSql } from "./createForeignKeyConstraintSql";
8
+
9
+ describe("createForeignKeyConstraintSql", () => {
10
+ test("it generates an ALTER TABLE command for the specified foreign key constraint", () => {
11
+ const foo = {
12
+ schema: "casekit",
13
+ columns: {
14
+ id: { type: "uuid" },
15
+ barId: {
16
+ name: "bar_id",
17
+ type: "uuid",
18
+ references: { table: "bar", column: "id" },
19
+ },
20
+ bazId: {
21
+ name: "baz_id",
22
+ type: "uuid",
23
+ references: { table: "baz", column: "id" },
24
+ },
25
+ },
26
+ foreignKeys: [
27
+ {
28
+ columns: ["bar_id", "baz_id"],
29
+ references: {
30
+ table: "quux",
31
+ columns: ["bar_id", "baz_id"],
32
+ },
33
+ onUpdate: sql`CASCADE`,
34
+ },
35
+ ],
36
+ } as const satisfies ModelDefinition;
37
+
38
+ const db = orm({ models: { foo }, pool: new pg.Pool() });
39
+
40
+ const result = db.models.foo.foreignKeys
41
+ .map((fk) => createForeignKeyConstraintSql(db.models.foo, fk).text)
42
+ .join("\n");
43
+
44
+ expect(result).toEqual(unindent`
45
+ ALTER TABLE casekit.foo ADD CONSTRAINT foo_bar_id_baz_id_fkey FOREIGN KEY (bar_id, baz_id) REFERENCES casekit.quux (bar_id, baz_id) ON UPDATE CASCADE;
46
+ ALTER TABLE casekit.foo ADD CONSTRAINT foo_bar_id_fkey FOREIGN KEY (bar_id) REFERENCES casekit.bar (id);
47
+ ALTER TABLE casekit.foo ADD CONSTRAINT foo_baz_id_fkey FOREIGN KEY (baz_id) REFERENCES casekit.baz (id);
48
+ `);
49
+ });
50
+ });
@@ -0,0 +1,44 @@
1
+ import pgfmt from "pg-format";
2
+
3
+ import { SQLStatement } from "../..";
4
+ import { BaseModel } from "../../schema/types/base/BaseModel";
5
+ import { ForeignKey } from "../../schema/types/constraints/ForeignKey";
6
+
7
+ export const createForeignKeyConstraintSql = (
8
+ model: BaseModel,
9
+ constraint: ForeignKey,
10
+ ) => {
11
+ const statement = new SQLStatement();
12
+ statement.push(
13
+ pgfmt(`ALTER TABLE %I.%I ADD CONSTRAINT `, model.schema, model.table),
14
+ );
15
+
16
+ statement.push(
17
+ pgfmt("%I", [model.table, ...constraint.columns, "fkey"].join("_")),
18
+ );
19
+
20
+ statement.push(pgfmt(` FOREIGN KEY (`, model.schema, model.table));
21
+ statement.push(constraint.columns.map((c) => pgfmt("%I", c)).join(", "));
22
+ statement.push(")");
23
+ statement.push(
24
+ pgfmt(
25
+ ` REFERENCES %I.%I (`,
26
+ constraint.references.schema,
27
+ constraint.references.table,
28
+ ),
29
+ );
30
+ statement.push(
31
+ constraint.references.columns.map((c) => pgfmt("%I", c)).join(", "),
32
+ );
33
+ statement.push(")");
34
+ if (constraint.onDelete) {
35
+ statement.push(` ON DELETE `);
36
+ statement.push(constraint.onDelete);
37
+ }
38
+ if (constraint.onUpdate) {
39
+ statement.push(` ON UPDATE `);
40
+ statement.push(constraint.onUpdate);
41
+ }
42
+ statement.push(";");
43
+ return statement;
44
+ };
@@ -0,0 +1,81 @@
1
+ import { unindent } from "@casekit/unindent";
2
+
3
+ import pg from "pg";
4
+ import { describe, expect, test } from "vitest";
5
+ import { z } from "zod";
6
+
7
+ import { ModelDefinition, orm } from "../../";
8
+ import { createSchemasSql } from "./createSchemasSql";
9
+
10
+ describe("createSchemaSql", () => {
11
+ test("it generates a CREATE SCHEMA command for each unique schema used", () => {
12
+ const a = {
13
+ schema: "foo",
14
+ columns: {
15
+ id: { type: "uuid", zodSchema: z.string() },
16
+ },
17
+ } as const satisfies ModelDefinition;
18
+
19
+ const b = {
20
+ schema: "bar",
21
+ columns: {
22
+ id: { type: "uuid", zodSchema: z.string() },
23
+ },
24
+ } as const satisfies ModelDefinition;
25
+
26
+ const db = orm({ models: { a, b }, pool: new pg.Pool() });
27
+ expect(createSchemasSql(db).text).toEqual(unindent`
28
+ CREATE SCHEMA IF NOT EXISTS foo;
29
+ CREATE SCHEMA IF NOT EXISTS bar;
30
+ `);
31
+ });
32
+
33
+ test("it pulls schema from the config if not specified on the model", () => {
34
+ const a = {
35
+ columns: {
36
+ id: { type: "uuid", zodSchema: z.string() },
37
+ },
38
+ } as const satisfies ModelDefinition;
39
+
40
+ const b = {
41
+ schema: "bar",
42
+ columns: {
43
+ id: { type: "uuid", zodSchema: z.string() },
44
+ },
45
+ } as const satisfies ModelDefinition;
46
+
47
+ const db = orm({
48
+ schema: "foo",
49
+ models: { a, b },
50
+ pool: new pg.Pool(),
51
+ });
52
+ expect(createSchemasSql(db).text).toEqual(unindent`
53
+ CREATE SCHEMA IF NOT EXISTS foo;
54
+ CREATE SCHEMA IF NOT EXISTS bar;
55
+ `);
56
+ });
57
+
58
+ test("if no schema is specified at all, it tries to create the public schema", () => {
59
+ const a = {
60
+ columns: {
61
+ id: { type: "uuid", zodSchema: z.string() },
62
+ },
63
+ } as const satisfies ModelDefinition;
64
+
65
+ const b = {
66
+ schema: "bar",
67
+ columns: {
68
+ id: { type: "uuid", zodSchema: z.string() },
69
+ },
70
+ } as const satisfies ModelDefinition;
71
+
72
+ const db = orm({
73
+ models: { a, b },
74
+ pool: new pg.Pool(),
75
+ });
76
+ expect(createSchemasSql(db).text).toEqual(unindent`
77
+ CREATE SCHEMA IF NOT EXISTS public;
78
+ CREATE SCHEMA IF NOT EXISTS bar;
79
+ `);
80
+ });
81
+ });
@@ -0,0 +1,15 @@
1
+ import { uniq } from "lodash-es";
2
+ import pgfmt from "pg-format";
3
+
4
+ import { BaseOrm } from "../../schema/types/base/BaseOrm";
5
+ import { SQLStatement } from "../../sql";
6
+
7
+ export const createSchemasSql = (db: BaseOrm): SQLStatement => {
8
+ const schemas = uniq(Object.values(db.models).map((m) => m.schema));
9
+
10
+ return new SQLStatement(
11
+ schemas
12
+ .map((s) => pgfmt("CREATE SCHEMA IF NOT EXISTS %I;", s))
13
+ .join("\n"),
14
+ );
15
+ };
@@ -0,0 +1,38 @@
1
+ import { test } from "@fast-check/vitest";
2
+ import { isEqual } from "lodash-es";
3
+ import pg from "pg";
4
+ import pgfmt from "pg-format";
5
+
6
+ import { orm } from "../..";
7
+ import * as gen from "../../test/gen";
8
+ import { withRollback } from "../../test/util/withRollback";
9
+ import { createSchemasSql } from "./createSchemasSql";
10
+ import { createTableSql } from "./createTableSql";
11
+
12
+ test.prop([gen.model()])("should generate valid DDL", async (model) => {
13
+ return await withRollback(async (client) => {
14
+ const db = orm({
15
+ models: { model },
16
+ relations: { model: {} },
17
+
18
+ pool: new pg.Pool(),
19
+ });
20
+
21
+ // create the schema
22
+ await client.query(createSchemasSql(db));
23
+
24
+ // create the table
25
+ await client.query(createTableSql(db.models.model));
26
+
27
+ // select from the newly created table so we can check it's there
28
+ const result = await client.query(
29
+ pgfmt("select * from %I.%I", model.schema, model.table),
30
+ );
31
+
32
+ // the selected fields should match the ones defined in the model
33
+ return isEqual(
34
+ result.fields.map((f) => f.name),
35
+ Object.values(model.columns).map((c) => c.name),
36
+ );
37
+ });
38
+ });
@@ -0,0 +1,74 @@
1
+ import { unindent } from "@casekit/unindent";
2
+
3
+ import { snakeCase, uniqueId } from "lodash-es";
4
+ import pg from "pg";
5
+ import { describe, expect, test } from "vitest";
6
+ import { z } from "zod";
7
+
8
+ import { ModelDefinition, orm } from "../..";
9
+ import { sql } from "../../sql";
10
+ import { db } from "../../test/db";
11
+ import { createTableSql } from "./createTableSql";
12
+
13
+ describe("createTableSql", () => {
14
+ test("it generates a CREATE TABLE command", () => {
15
+ expect(createTableSql(db.models.user).text).toEqual(unindent`
16
+ CREATE TABLE casekit."user" (
17
+ id uuid NOT NULL DEFAULT uuid_generate_v4(),
18
+ username text NOT NULL,
19
+ invited_by_id uuid,
20
+ created_at timestamp,
21
+ updated_at timestamp,
22
+ deleted_at timestamp,
23
+ PRIMARY KEY (id)
24
+ );
25
+ `);
26
+ });
27
+
28
+ test("the generated DDL successfully creates a table", async () => {
29
+ const table = uniqueId("table-");
30
+ const post = {
31
+ table,
32
+ columns: {
33
+ id: {
34
+ zodSchema: z.string().uuid(),
35
+ type: "uuid",
36
+ default: sql`uuid_generate_v4()`,
37
+ },
38
+ title: {
39
+ zodSchema: z.string(),
40
+ type: "text",
41
+ default: "My first post",
42
+ },
43
+ content: { zodSchema: z.string(), type: "text" },
44
+ publishedAt: {
45
+ zodSchema: z.date(),
46
+ type: "timestamp",
47
+ nullable: true,
48
+ },
49
+ },
50
+ } as const satisfies ModelDefinition;
51
+ await orm({
52
+ models: { post },
53
+ relations: { post: {} },
54
+ naming: { column: snakeCase },
55
+ pool: new pg.Pool(),
56
+ }).transact(
57
+ async (db) => {
58
+ await db.connection.query(createTableSql(db.models.post));
59
+
60
+ const result = await db.connection.query(
61
+ sql`select * from public.%I`.withIdentifiers(table),
62
+ );
63
+
64
+ expect(result.fields.map((f) => f.name)).toEqual([
65
+ "id",
66
+ "title",
67
+ "content",
68
+ "published_at",
69
+ ]);
70
+ },
71
+ { rollback: true },
72
+ );
73
+ });
74
+ });