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