prisma-mock 0.1.8 → 0.2.0
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/README.md +33 -26
- package/lib/defaults/autoincrement.d.ts +4 -0
- package/lib/defaults/autoincrement.js +22 -0
- package/lib/defaults/cuid.d.ts +2 -0
- package/lib/defaults/cuid.js +5 -0
- package/lib/defaults/index.d.ts +4 -0
- package/lib/defaults/index.js +47 -0
- package/lib/defaults/now.d.ts +2 -0
- package/lib/defaults/now.js +4 -0
- package/lib/index.d.ts +4 -2
- package/lib/index.js +357 -188
- package/lib/utils/deepEqual.d.ts +1 -0
- package/lib/utils/deepEqual.js +30 -0
- package/lib/utils/shallowCompare.d.ts +5 -0
- package/lib/utils/shallowCompare.js +11 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
# Prisma Mock
|
|
3
2
|
|
|
4
3
|
This is a mock of the Prisma API intended for unit testing. All the data is stored in memory.
|
|
@@ -19,28 +18,26 @@ beforeEach(async () => {
|
|
|
19
18
|
}
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
|
|
23
21
|
An example how to mock a global prisma instance inside and schema a "db" directory (like blitzjs):
|
|
24
22
|
|
|
25
23
|
```js
|
|
26
|
-
import createPrismaMock from "prisma-mock"
|
|
27
|
-
import { mockDeep, mockReset } from "jest-mock-extended"
|
|
24
|
+
import createPrismaMock from "prisma-mock";
|
|
25
|
+
import { mockDeep, mockReset } from "jest-mock-extended";
|
|
28
26
|
|
|
29
27
|
jest.mock("db", () => ({
|
|
30
28
|
__esModule: true,
|
|
31
|
-
...jest.requireActual(
|
|
32
|
-
default: mockDeep()
|
|
33
|
-
}))
|
|
29
|
+
...jest.requireActual("db"),
|
|
30
|
+
default: mockDeep(),
|
|
31
|
+
}));
|
|
34
32
|
|
|
35
|
-
import db, { Prisma } from "db"
|
|
33
|
+
import db, { Prisma } from "db";
|
|
36
34
|
|
|
37
35
|
beforeEach(() => {
|
|
38
|
-
mockReset(db)
|
|
39
|
-
return createPrismaMock({}, Prisma.dmmf.datamodel, db)
|
|
40
|
-
})
|
|
36
|
+
mockReset(db);
|
|
37
|
+
return createPrismaMock({}, Prisma.dmmf.datamodel, db);
|
|
38
|
+
});
|
|
41
39
|
```
|
|
42
40
|
|
|
43
|
-
|
|
44
41
|
# API
|
|
45
42
|
|
|
46
43
|
```ts
|
|
@@ -61,30 +58,32 @@ createPrismaMock({
|
|
|
61
58
|
{
|
|
62
59
|
id: 1,
|
|
63
60
|
name: "John Doe",
|
|
64
|
-
accountId: 1
|
|
65
|
-
}
|
|
61
|
+
accountId: 1,
|
|
62
|
+
},
|
|
66
63
|
],
|
|
67
64
|
account: [
|
|
68
65
|
{
|
|
69
66
|
id: 1,
|
|
70
67
|
name: "Company",
|
|
71
|
-
}
|
|
72
|
-
]
|
|
73
|
-
})
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
});
|
|
74
71
|
```
|
|
75
72
|
|
|
76
|
-
|
|
77
73
|
## datamodel
|
|
74
|
+
|
|
78
75
|
The datamodel of the prisma client, value of `Prisma.dmmf.datamodel`.
|
|
79
76
|
|
|
80
77
|
## client
|
|
81
|
-
`jest-mock-extended` instance used. If not provided, a new instance is created.
|
|
82
78
|
|
|
79
|
+
`jest-mock-extended` instance used. If not provided, a new instance is created.
|
|
83
80
|
|
|
84
81
|
# Supported features
|
|
82
|
+
|
|
85
83
|
Alot of the functionality is implemented, but parts are missing. Here is a list of the (missing) features:
|
|
86
84
|
|
|
87
85
|
## Model queries
|
|
86
|
+
|
|
88
87
|
- findUnique,
|
|
89
88
|
- findMany,
|
|
90
89
|
- findFirst,
|
|
@@ -99,16 +98,17 @@ Alot of the functionality is implemented, but parts are missing. Here is a list
|
|
|
99
98
|
- TODO: aggregate
|
|
100
99
|
- TODO: groupBy
|
|
101
100
|
|
|
102
|
-
|
|
103
101
|
## Model query options
|
|
102
|
+
|
|
104
103
|
- distinct
|
|
105
104
|
- include
|
|
106
105
|
- where
|
|
107
106
|
- select
|
|
108
107
|
- orderBy
|
|
109
|
-
- TODO: select: _count
|
|
108
|
+
- TODO: select: \_count
|
|
110
109
|
|
|
111
110
|
## Nested queries
|
|
111
|
+
|
|
112
112
|
- create
|
|
113
113
|
- createMany
|
|
114
114
|
- update
|
|
@@ -121,8 +121,8 @@ Alot of the functionality is implemented, but parts are missing. Here is a list
|
|
|
121
121
|
- TODO: connectOrCreate
|
|
122
122
|
- TODO: upsert
|
|
123
123
|
|
|
124
|
-
|
|
125
124
|
## Filter conditions and operators
|
|
125
|
+
|
|
126
126
|
- equals
|
|
127
127
|
- gt
|
|
128
128
|
- gte
|
|
@@ -141,18 +141,22 @@ Alot of the functionality is implemented, but parts are missing. Here is a list
|
|
|
141
141
|
- TODO: mode
|
|
142
142
|
|
|
143
143
|
## Relation filters
|
|
144
|
+
|
|
144
145
|
- some
|
|
145
146
|
- every
|
|
146
147
|
- none
|
|
147
148
|
- TODO: is
|
|
148
149
|
|
|
149
150
|
## Scalar list methods
|
|
151
|
+
|
|
150
152
|
TODO (set, push)
|
|
151
153
|
|
|
152
154
|
## Scalar list filters
|
|
155
|
+
|
|
153
156
|
TODO (has, hasEvery, hasSome, isEmpty, equals)
|
|
154
157
|
|
|
155
158
|
## Atomic number operations
|
|
159
|
+
|
|
156
160
|
- increment
|
|
157
161
|
- decrement
|
|
158
162
|
- multiply
|
|
@@ -160,26 +164,29 @@ TODO (has, hasEvery, hasSome, isEmpty, equals)
|
|
|
160
164
|
- set
|
|
161
165
|
|
|
162
166
|
## JSON filters
|
|
167
|
+
|
|
163
168
|
TODO (path, string_contains, string_starts_with, string_ends_with, array_contains, array_starts_with, array_ends_with)
|
|
164
169
|
|
|
165
170
|
## Attributes
|
|
171
|
+
|
|
166
172
|
- @@id
|
|
167
173
|
- @default
|
|
168
174
|
- @unique (TODO: no error if duplicate)
|
|
169
175
|
- @@unique (TODO: no error if duplicate)
|
|
170
176
|
- @relation
|
|
171
|
-
- TODO:
|
|
177
|
+
- @updatedAt: Partially supported, value is set at creation (TODO: update value on update)
|
|
172
178
|
|
|
173
179
|
## Attribute functions
|
|
180
|
+
|
|
174
181
|
- autoincrement()
|
|
175
182
|
- TODO: auto()
|
|
176
|
-
-
|
|
183
|
+
- cuid()
|
|
177
184
|
- TODO: uuid()
|
|
178
|
-
-
|
|
185
|
+
- now()
|
|
179
186
|
- TODO: dbgenerated()
|
|
180
187
|
|
|
181
188
|
## Referential actions
|
|
189
|
+
|
|
182
190
|
- onDelete (SetNull, Cascade)
|
|
183
191
|
- TODO: onDelete: Restrict, NoAction, SetDefault
|
|
184
192
|
- TODO: onUpdate
|
|
185
|
-
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reset = void 0;
|
|
4
|
+
let autoincrement_cache = {};
|
|
5
|
+
function autoincrement(prop, field, data = {}) {
|
|
6
|
+
const key = `${prop}_${field.name}`;
|
|
7
|
+
let m = autoincrement_cache?.[key];
|
|
8
|
+
if (m === undefined) {
|
|
9
|
+
m = 0;
|
|
10
|
+
data[prop].forEach((item) => {
|
|
11
|
+
m = Math.max(m, item[field.name]);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
m += 1;
|
|
15
|
+
autoincrement_cache[key] = m;
|
|
16
|
+
return m;
|
|
17
|
+
}
|
|
18
|
+
exports.default = autoincrement;
|
|
19
|
+
function reset() {
|
|
20
|
+
autoincrement_cache = {};
|
|
21
|
+
}
|
|
22
|
+
exports.reset = reset;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.ResetDefaults = void 0;
|
|
30
|
+
const autoincrement_1 = __importStar(require("./autoincrement"));
|
|
31
|
+
const cuid_1 = __importDefault(require("./cuid"));
|
|
32
|
+
const now_1 = __importDefault(require("./now"));
|
|
33
|
+
// const registry = new Map<string, (string, Prisma.DMMF.Field, PrismaMockData) => any>();
|
|
34
|
+
const registry = new Map();
|
|
35
|
+
registry.set("autoincrement", autoincrement_1.default);
|
|
36
|
+
registry.set("cuid", cuid_1.default);
|
|
37
|
+
registry.set("now", now_1.default);
|
|
38
|
+
function HandleDefault(prop, field, data) {
|
|
39
|
+
const key = field.default.name;
|
|
40
|
+
const val = registry.get(key)?.(prop, field, data);
|
|
41
|
+
return val;
|
|
42
|
+
}
|
|
43
|
+
exports.default = HandleDefault;
|
|
44
|
+
function ResetDefaults() {
|
|
45
|
+
(0, autoincrement_1.reset)();
|
|
46
|
+
}
|
|
47
|
+
exports.ResetDefaults = ResetDefaults;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Prisma } from
|
|
1
|
+
import { Prisma } from "@prisma/client";
|
|
2
2
|
type UnwrapPromise<P extends any> = P extends Promise<infer R> ? R : P;
|
|
3
3
|
type PrismaDelegate = {
|
|
4
4
|
findUnique: (...args: Array<any>) => Promise<any>;
|
|
@@ -11,5 +11,7 @@ type PrismaList<P extends {
|
|
|
11
11
|
export type PrismaMockData<P> = Partial<{
|
|
12
12
|
[key in IsTable<Uncapitalize<IsString<keyof P>>>]: PrismaList<P, key>;
|
|
13
13
|
}>;
|
|
14
|
-
declare const createPrismaMock: <P>(data?: Partial<{ [key in IsTable<Uncapitalize<IsString<keyof P>>>]: PrismaList<P, key>; }>, datamodel?: Prisma.DMMF.Datamodel, client?: { [K in keyof P]: P[K] extends (...args: infer A) => infer B ? import("jest-mock-extended").CalledWithMock<B, A> & (P[K] extends infer T extends (...args: infer A) => infer B ? { [K_1 in keyof T]: P[K][K_1] extends (...args: infer A_1) => infer B_1 ? import("jest-mock-extended").CalledWithMock<B_1, A_1> & (P[K][K_1] extends infer T_1 extends (...args: infer A_1) => infer B_1 ? { [K_2 in keyof T_1]: P[K][K_1][K_2] extends (...args: infer A_2) => infer B_2 ? import("jest-mock-extended").CalledWithMock<B_2, A_2> & (P[K][K_1][K_2] extends infer T_2 extends (...args: infer A_2) => infer B_2 ? { [K_3 in keyof T_2]: P[K][K_1][K_2][K_3] extends (...args: infer A_3) => infer B_3 ? import("jest-mock-extended").CalledWithMock<B_3, A_3> & (P[K][K_1][K_2][K_3] extends infer T_3 extends (...args: infer A_3) => infer B_3 ? { [K_4 in keyof T_3]: P[K][K_1][K_2][K_3][K_4] extends (...args: infer A_4) => infer B_4 ? import("jest-mock-extended").CalledWithMock<B_4, A_4> & (P[K][K_1][K_2][K_3][K_4] extends infer T_4 extends (...args: infer A_4) => infer B_4 ? { [K_5 in keyof T_4]: P[K][K_1][K_2][K_3][K_4][K_5] extends (...args: infer A_5) => infer B_5 ? import("jest-mock-extended").CalledWithMock<B_5, A_5> & (P[K][K_1][K_2][K_3][K_4][K_5] extends infer T_5 extends (...args: infer A_5) => infer B_5 ? { [K_6 in keyof T_5]: P[K][K_1][K_2][K_3][K_4][K_5][K_6] extends (...args: infer A_6) => infer B_6 ? import("jest-mock-extended").CalledWithMock<B_6, A_6> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6] extends infer T_6 extends (...args: infer A_6) => infer B_6 ? { [K_7 in keyof T_6]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends (...args: infer A_7) => infer B_7 ? import("jest-mock-extended").CalledWithMock<B_7, A_7> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends infer T_7 extends (...args: infer A_7) => infer B_7 ? { [K_8 in keyof T_7]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends (...args: infer A_8) => infer B_8 ? import("jest-mock-extended").CalledWithMock<B_8, A_8> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends infer T_8 extends (...args: infer A_8) => infer B_8 ? { [K_9 in keyof T_8]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends (...args: infer A_9) => infer B_9 ? import("jest-mock-extended").CalledWithMock<B_9, A_9> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends infer T_9 extends (...args: infer A_9) => infer B_9 ? { [K_10 in keyof T_9]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10] extends (...args: infer A_10) => infer B_10 ? any : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5]>; } : never) & P[K][K_1][K_2][K_3][K_4] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4]>; } : never) & P[K][K_1][K_2][K_3] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3]>; } : never) & P[K][K_1][K_2] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2]>; } : never) & P[K][K_1] : import("jest-mock-extended").DeepMockProxy<P[K][K_1]>; } : never) & P[K] : import("jest-mock-extended").DeepMockProxy<P[K]>; } & P
|
|
14
|
+
declare const createPrismaMock: <P>(data?: Partial<{ [key in IsTable<Uncapitalize<IsString<keyof P>>>]: PrismaList<P, key>; }>, datamodel?: Prisma.DMMF.Datamodel, client?: { [K in keyof P]: P[K] extends (...args: infer A) => infer B ? import("jest-mock-extended").CalledWithMock<B, A> & (P[K] extends infer T extends (...args: infer A) => infer B ? { [K_1 in keyof T]: P[K][K_1] extends (...args: infer A_1) => infer B_1 ? import("jest-mock-extended").CalledWithMock<B_1, A_1> & (P[K][K_1] extends infer T_1 extends (...args: infer A_1) => infer B_1 ? { [K_2 in keyof T_1]: P[K][K_1][K_2] extends (...args: infer A_2) => infer B_2 ? import("jest-mock-extended").CalledWithMock<B_2, A_2> & (P[K][K_1][K_2] extends infer T_2 extends (...args: infer A_2) => infer B_2 ? { [K_3 in keyof T_2]: P[K][K_1][K_2][K_3] extends (...args: infer A_3) => infer B_3 ? import("jest-mock-extended").CalledWithMock<B_3, A_3> & (P[K][K_1][K_2][K_3] extends infer T_3 extends (...args: infer A_3) => infer B_3 ? { [K_4 in keyof T_3]: P[K][K_1][K_2][K_3][K_4] extends (...args: infer A_4) => infer B_4 ? import("jest-mock-extended").CalledWithMock<B_4, A_4> & (P[K][K_1][K_2][K_3][K_4] extends infer T_4 extends (...args: infer A_4) => infer B_4 ? { [K_5 in keyof T_4]: P[K][K_1][K_2][K_3][K_4][K_5] extends (...args: infer A_5) => infer B_5 ? import("jest-mock-extended").CalledWithMock<B_5, A_5> & (P[K][K_1][K_2][K_3][K_4][K_5] extends infer T_5 extends (...args: infer A_5) => infer B_5 ? { [K_6 in keyof T_5]: P[K][K_1][K_2][K_3][K_4][K_5][K_6] extends (...args: infer A_6) => infer B_6 ? import("jest-mock-extended").CalledWithMock<B_6, A_6> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6] extends infer T_6 extends (...args: infer A_6) => infer B_6 ? { [K_7 in keyof T_6]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends (...args: infer A_7) => infer B_7 ? import("jest-mock-extended").CalledWithMock<B_7, A_7> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] extends infer T_7 extends (...args: infer A_7) => infer B_7 ? { [K_8 in keyof T_7]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends (...args: infer A_8) => infer B_8 ? import("jest-mock-extended").CalledWithMock<B_8, A_8> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] extends infer T_8 extends (...args: infer A_8) => infer B_8 ? { [K_9 in keyof T_8]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends (...args: infer A_9) => infer B_9 ? import("jest-mock-extended").CalledWithMock<B_9, A_9> & (P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] extends infer T_9 extends (...args: infer A_9) => infer B_9 ? { [K_10 in keyof T_9]: P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10] extends (...args: infer A_10) => infer B_10 ? any : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9][K_10]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8][K_9]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7][K_8]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6][K_7]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5][K_6] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5][K_6]>; } : never) & P[K][K_1][K_2][K_3][K_4][K_5] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4][K_5]>; } : never) & P[K][K_1][K_2][K_3][K_4] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3][K_4]>; } : never) & P[K][K_1][K_2][K_3] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2][K_3]>; } : never) & P[K][K_1][K_2] : import("jest-mock-extended").DeepMockProxy<P[K][K_1][K_2]>; } : never) & P[K][K_1] : import("jest-mock-extended").DeepMockProxy<P[K][K_1]>; } : never) & P[K] : import("jest-mock-extended").DeepMockProxy<P[K]>; } & P, options?: {
|
|
15
|
+
caseInsensitive: boolean;
|
|
16
|
+
}) => P;
|
|
15
17
|
export default createPrismaMock;
|
package/lib/index.js
CHANGED
|
@@ -1,49 +1,65 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
12
24
|
};
|
|
13
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
26
|
const client_1 = require("@prisma/client");
|
|
15
27
|
const runtime_1 = require("@prisma/client/runtime");
|
|
16
28
|
const jest_mock_extended_1 = require("jest-mock-extended");
|
|
17
|
-
const
|
|
29
|
+
const defaults_1 = __importStar(require("./defaults"));
|
|
30
|
+
const shallowCompare_1 = require("./utils/shallowCompare");
|
|
31
|
+
const deepEqual_1 = require("./utils/deepEqual");
|
|
32
|
+
function IsFieldDefault(f) {
|
|
33
|
+
return f.name !== undefined;
|
|
34
|
+
}
|
|
35
|
+
const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_1.mockDeep)(), options = { caseInsensitive: false }) => {
|
|
18
36
|
if (!datamodel || typeof datamodel === "string") {
|
|
19
37
|
datamodel = client_1.Prisma.dmmf.datamodel;
|
|
20
38
|
}
|
|
21
|
-
|
|
39
|
+
(0, defaults_1.ResetDefaults)();
|
|
22
40
|
const getCamelCase = (name) => {
|
|
23
41
|
return name.substr(0, 1).toLowerCase() + name.substr(1);
|
|
24
42
|
};
|
|
25
|
-
const shallowCompare = (a, b) => {
|
|
26
|
-
for (let key in b) {
|
|
27
|
-
if (a[key] !== b[key])
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
return true;
|
|
31
|
-
};
|
|
32
43
|
const removeMultiFieldIds = (model, data) => {
|
|
33
|
-
var _a, _b;
|
|
34
44
|
const c = getCamelCase(model.name);
|
|
35
|
-
const idFields = model.idFields ||
|
|
45
|
+
const idFields = model.idFields || model.primaryKey?.fields;
|
|
36
46
|
const removeId = (ids) => {
|
|
37
|
-
const id = ids.join(
|
|
38
|
-
data =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
const id = ids.join("_");
|
|
48
|
+
data = {
|
|
49
|
+
...data,
|
|
50
|
+
[c]: data[c].map((item) => {
|
|
51
|
+
const { [id]: idVal, ...rest } = item;
|
|
52
|
+
return {
|
|
53
|
+
...rest,
|
|
54
|
+
...idVal,
|
|
55
|
+
};
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
42
58
|
};
|
|
43
|
-
if (
|
|
59
|
+
if (idFields?.length > 1) {
|
|
44
60
|
removeId(idFields);
|
|
45
61
|
}
|
|
46
|
-
if (
|
|
62
|
+
if (model.uniqueFields?.length > 0) {
|
|
47
63
|
for (const uniqueField of model.uniqueFields) {
|
|
48
64
|
removeId(uniqueField);
|
|
49
65
|
}
|
|
@@ -57,15 +73,15 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
57
73
|
[field.relationFromFields[0]]: item[field.relationToFields[0]],
|
|
58
74
|
};
|
|
59
75
|
}
|
|
60
|
-
return
|
|
76
|
+
return {
|
|
61
77
|
[field.relationToFields[0]]: item[field.relationFromFields[0]],
|
|
62
|
-
}
|
|
78
|
+
};
|
|
63
79
|
};
|
|
64
80
|
const getJoinField = (field) => {
|
|
65
|
-
const joinmodel = datamodel.models.find(model => {
|
|
81
|
+
const joinmodel = datamodel.models.find((model) => {
|
|
66
82
|
return model.name === field.type;
|
|
67
83
|
});
|
|
68
|
-
const joinfield = joinmodel
|
|
84
|
+
const joinfield = joinmodel?.fields.find((f) => {
|
|
69
85
|
return f.relationName === field.relationName;
|
|
70
86
|
});
|
|
71
87
|
return joinfield;
|
|
@@ -89,19 +105,21 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
89
105
|
}
|
|
90
106
|
const keys = Object.keys(orderBy);
|
|
91
107
|
if (keys.length > 1) {
|
|
92
|
-
throw new runtime_1.PrismaClientValidationError(`Argument orderBy of needs exactly one argument, but you provided ${keys.join(
|
|
108
|
+
throw new runtime_1.PrismaClientValidationError(`Argument orderBy of needs exactly one argument, but you provided ${keys.join(" and ")}. Please choose one.`);
|
|
93
109
|
}
|
|
94
|
-
const incl = includes({
|
|
110
|
+
const incl = includes({
|
|
111
|
+
include: keys.reduce((acc, key) => ({ ...acc, [key]: true }), {}),
|
|
112
|
+
});
|
|
95
113
|
for (const key of keys) {
|
|
96
114
|
const dir = orderBy[key];
|
|
97
115
|
if (typeof dir === "object") {
|
|
98
|
-
const schema = model.fields.find(field => {
|
|
116
|
+
const schema = model.fields.find((field) => {
|
|
99
117
|
return field.name === key;
|
|
100
118
|
});
|
|
101
119
|
if (!schema) {
|
|
102
120
|
return 0;
|
|
103
121
|
}
|
|
104
|
-
const submodel = datamodel.models.find(model => {
|
|
122
|
+
const submodel = datamodel.models.find((model) => {
|
|
105
123
|
return model.name === schema.type;
|
|
106
124
|
});
|
|
107
125
|
const delegate = Delegate(getCamelCase(schema.type), submodel);
|
|
@@ -132,39 +150,79 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
132
150
|
const nestedUpdate = (args, isCreating, item) => {
|
|
133
151
|
let d = args.data;
|
|
134
152
|
// Get field schema for default values
|
|
135
|
-
const model = datamodel.models.find(model => {
|
|
153
|
+
const model = datamodel.models.find((model) => {
|
|
136
154
|
return getCamelCase(model.name) === prop;
|
|
137
155
|
});
|
|
138
|
-
model.fields.forEach(field => {
|
|
156
|
+
model.fields.forEach((field) => {
|
|
139
157
|
if (d[field.name]) {
|
|
140
158
|
const c = d[field.name];
|
|
141
|
-
if (field.kind ===
|
|
159
|
+
if (field.kind === "object") {
|
|
142
160
|
if (c.connect) {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
const { [field.name]: { connect }, ...rest } = d;
|
|
162
|
+
const connections = connect instanceof Array ? connect : [connect];
|
|
163
|
+
connections.forEach((connect, idx) => {
|
|
164
|
+
const keyToMatch = Object.keys(connect)[0];
|
|
165
|
+
if (field.relationToFields.length > 0) {
|
|
166
|
+
const keyToGet = field.relationToFields[0];
|
|
167
|
+
const targetKey = field.relationFromFields[0];
|
|
168
|
+
let connectionValue = connect[keyToGet];
|
|
169
|
+
if (keyToMatch !== keyToGet) {
|
|
170
|
+
const valueToMatch = connect[keyToMatch];
|
|
171
|
+
const matchingRow = data[getCamelCase(field.type)].find((row) => {
|
|
172
|
+
return row[keyToMatch] === valueToMatch;
|
|
173
|
+
});
|
|
174
|
+
if (!matchingRow) {
|
|
175
|
+
const message = "An operation failed because it depends on one or more records that were required but not found. {cause}";
|
|
176
|
+
const code = "P2025";
|
|
177
|
+
const clientVersion = "1.2.3";
|
|
178
|
+
// PrismaClientKnownRequestError prototype changed in version 4.7.0
|
|
179
|
+
// from: constructor(message: string, code: string, clientVersion: string, meta?: any)
|
|
180
|
+
// to: constructor(message: string, { code, clientVersion, meta, batchRequestIdx }: KnownErrorParams)
|
|
181
|
+
if (runtime_1.PrismaClientKnownRequestError.length === 2) {
|
|
182
|
+
// @ts-ignore
|
|
183
|
+
throw new runtime_1.PrismaClientKnownRequestError(message, {
|
|
184
|
+
code,
|
|
185
|
+
clientVersion,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// @ts-ignore
|
|
189
|
+
throw new runtime_1.PrismaClientKnownRequestError(message, code,
|
|
190
|
+
// @ts-ignore
|
|
191
|
+
clientVersion);
|
|
192
|
+
}
|
|
193
|
+
connectionValue = matchingRow[keyToGet];
|
|
158
194
|
}
|
|
159
|
-
|
|
160
|
-
|
|
195
|
+
d = {
|
|
196
|
+
...rest,
|
|
197
|
+
[targetKey]: connectionValue,
|
|
198
|
+
};
|
|
161
199
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
200
|
+
else {
|
|
201
|
+
d = rest;
|
|
202
|
+
const otherModel = datamodel.models.find((model) => {
|
|
203
|
+
return model.name === field.type;
|
|
204
|
+
});
|
|
205
|
+
const inverse = otherModel.fields.find((otherField) => field.relationName === otherField.relationName);
|
|
206
|
+
const targetKey = inverse.relationToFields[0];
|
|
207
|
+
const fromKey = inverse.relationFromFields[0];
|
|
208
|
+
const delegate = Delegate(getCamelCase(otherModel.name), otherModel);
|
|
209
|
+
delegate.update({
|
|
210
|
+
where: {
|
|
211
|
+
[fromKey]: connect[keyToMatch],
|
|
212
|
+
},
|
|
213
|
+
data: {
|
|
214
|
+
[getCamelCase(inverse.name)]: {
|
|
215
|
+
connect: {
|
|
216
|
+
[targetKey]: d[targetKey],
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
});
|
|
165
223
|
}
|
|
166
224
|
if (c.create || c.createMany) {
|
|
167
|
-
const
|
|
225
|
+
const { [field.name]: create, ...rest } = d;
|
|
168
226
|
d = rest;
|
|
169
227
|
// @ts-ignore
|
|
170
228
|
const name = getCamelCase(field.type);
|
|
@@ -172,29 +230,47 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
172
230
|
const joinfield = getJoinField(field);
|
|
173
231
|
if (field.relationFromFields.length > 0) {
|
|
174
232
|
const item = delegate.create({
|
|
175
|
-
data: create.create
|
|
233
|
+
data: create.create,
|
|
176
234
|
});
|
|
177
|
-
d =
|
|
235
|
+
d = {
|
|
236
|
+
...rest,
|
|
237
|
+
[field.relationFromFields[0]]: item[field.relationToFields[0]],
|
|
238
|
+
};
|
|
178
239
|
}
|
|
179
240
|
else {
|
|
180
|
-
const map = (val) => (
|
|
241
|
+
const map = (val) => ({
|
|
242
|
+
...val,
|
|
243
|
+
[joinfield.name]: {
|
|
181
244
|
connect: joinfield.relationToFields.reduce((prev, cur, index) => {
|
|
182
245
|
let val = d[cur];
|
|
183
246
|
if (!isCreating && !val) {
|
|
184
247
|
val = findOne(args)[cur];
|
|
185
248
|
}
|
|
186
|
-
return
|
|
249
|
+
return {
|
|
250
|
+
...prev,
|
|
251
|
+
[cur]: val,
|
|
252
|
+
};
|
|
187
253
|
}, {}),
|
|
188
|
-
}
|
|
254
|
+
},
|
|
255
|
+
});
|
|
189
256
|
if (c.createMany) {
|
|
190
|
-
delegate.createMany(
|
|
257
|
+
delegate.createMany({
|
|
258
|
+
...c.createMany,
|
|
259
|
+
data: c.createMany.data.map(map),
|
|
260
|
+
});
|
|
191
261
|
}
|
|
192
262
|
else {
|
|
193
263
|
if (Array.isArray(c.create)) {
|
|
194
|
-
delegate.createMany(
|
|
264
|
+
delegate.createMany({
|
|
265
|
+
...c.create,
|
|
266
|
+
data: c.create.map(map),
|
|
267
|
+
});
|
|
195
268
|
}
|
|
196
269
|
else {
|
|
197
|
-
delegate.create(
|
|
270
|
+
delegate.create({
|
|
271
|
+
...create.create,
|
|
272
|
+
data: map(create.create),
|
|
273
|
+
});
|
|
198
274
|
}
|
|
199
275
|
}
|
|
200
276
|
}
|
|
@@ -203,7 +279,7 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
203
279
|
const delegate = Delegate(name, model);
|
|
204
280
|
if (c.updateMany) {
|
|
205
281
|
if (Array.isArray(c.updateMany)) {
|
|
206
|
-
c.updateMany.forEach(updateMany => {
|
|
282
|
+
c.updateMany.forEach((updateMany) => {
|
|
207
283
|
delegate.updateMany(updateMany);
|
|
208
284
|
});
|
|
209
285
|
}
|
|
@@ -213,18 +289,21 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
213
289
|
}
|
|
214
290
|
if (c.update) {
|
|
215
291
|
if (Array.isArray(c.update)) {
|
|
216
|
-
c.update.forEach(update => {
|
|
292
|
+
c.update.forEach((update) => {
|
|
217
293
|
delegate.update(update);
|
|
218
294
|
});
|
|
219
295
|
}
|
|
220
296
|
else {
|
|
221
297
|
const item = findOne(args);
|
|
222
|
-
delegate.update({
|
|
298
|
+
delegate.update({
|
|
299
|
+
data: c.update,
|
|
300
|
+
where: getFieldRelationshipWhere(item, field),
|
|
301
|
+
});
|
|
223
302
|
}
|
|
224
303
|
}
|
|
225
304
|
if (c.deleteMany) {
|
|
226
305
|
if (Array.isArray(c.deleteMany)) {
|
|
227
|
-
c.deleteMany.forEach(where => {
|
|
306
|
+
c.deleteMany.forEach((where) => {
|
|
228
307
|
delegate.deleteMany({ where });
|
|
229
308
|
});
|
|
230
309
|
}
|
|
@@ -234,7 +313,7 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
234
313
|
}
|
|
235
314
|
if (c.delete) {
|
|
236
315
|
if (Array.isArray(c.delete)) {
|
|
237
|
-
c.delete.forEach(where => {
|
|
316
|
+
c.delete.forEach((where) => {
|
|
238
317
|
delegate.delete({ where });
|
|
239
318
|
});
|
|
240
319
|
}
|
|
@@ -244,64 +323,88 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
244
323
|
}
|
|
245
324
|
if (c.disconnect) {
|
|
246
325
|
if (field.relationFromFields.length > 0) {
|
|
247
|
-
d =
|
|
326
|
+
d = {
|
|
327
|
+
...d,
|
|
328
|
+
[field.relationFromFields[0]]: null,
|
|
329
|
+
};
|
|
248
330
|
}
|
|
249
331
|
else {
|
|
250
332
|
const joinfield = getJoinField(field);
|
|
251
333
|
delegate.update({
|
|
252
334
|
data: {
|
|
253
|
-
[joinfield.relationFromFields[0]]: null
|
|
335
|
+
[joinfield.relationFromFields[0]]: null,
|
|
254
336
|
},
|
|
255
337
|
where: {
|
|
256
|
-
[joinfield.relationFromFields[0]]: item[joinfield.relationToFields[0]]
|
|
257
|
-
}
|
|
338
|
+
[joinfield.relationFromFields[0]]: item[joinfield.relationToFields[0]],
|
|
339
|
+
},
|
|
258
340
|
});
|
|
259
341
|
}
|
|
260
342
|
}
|
|
261
|
-
const
|
|
343
|
+
const { [field.name]: _update, ...rest } = d;
|
|
262
344
|
d = rest;
|
|
263
345
|
}
|
|
264
346
|
if (c.increment) {
|
|
265
|
-
d =
|
|
347
|
+
d = {
|
|
348
|
+
...d,
|
|
349
|
+
[field.name]: item[field.name] + c.increment,
|
|
350
|
+
};
|
|
266
351
|
}
|
|
267
352
|
if (c.decrement) {
|
|
268
|
-
d =
|
|
353
|
+
d = {
|
|
354
|
+
...d,
|
|
355
|
+
[field.name]: item[field.name] - c.decrement,
|
|
356
|
+
};
|
|
269
357
|
}
|
|
270
358
|
if (c.multiply) {
|
|
271
|
-
d =
|
|
359
|
+
d = {
|
|
360
|
+
...d,
|
|
361
|
+
[field.name]: item[field.name] * c.multiply,
|
|
362
|
+
};
|
|
272
363
|
}
|
|
273
364
|
if (c.divide) {
|
|
274
|
-
d =
|
|
365
|
+
d = {
|
|
366
|
+
...d,
|
|
367
|
+
[field.name]: item[field.name] / c.divide,
|
|
368
|
+
};
|
|
275
369
|
}
|
|
276
370
|
if (c.set) {
|
|
277
|
-
d =
|
|
371
|
+
d = {
|
|
372
|
+
...d,
|
|
373
|
+
[field.name]: c.set,
|
|
374
|
+
};
|
|
278
375
|
}
|
|
279
376
|
}
|
|
280
377
|
if ((isCreating || d[field.name] === null) &&
|
|
281
378
|
(d[field.name] === null || d[field.name] === undefined)) {
|
|
282
379
|
if (field.hasDefaultValue) {
|
|
283
|
-
if (
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
m = Math.max(m, item[field.name]);
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
m += 1;
|
|
294
|
-
d = Object.assign(Object.assign({}, d), { [field.name]: m });
|
|
295
|
-
autoincrement = Object.assign(Object.assign({}, autoincrement), { [key]: m });
|
|
380
|
+
if (IsFieldDefault(field.default)) {
|
|
381
|
+
const defaultValue = (0, defaults_1.default)(prop, field, data);
|
|
382
|
+
if (defaultValue) {
|
|
383
|
+
d = {
|
|
384
|
+
...d,
|
|
385
|
+
[field.name]: defaultValue,
|
|
386
|
+
};
|
|
296
387
|
}
|
|
297
388
|
}
|
|
298
389
|
else {
|
|
299
|
-
d =
|
|
390
|
+
d = {
|
|
391
|
+
...d,
|
|
392
|
+
[field.name]: field.default,
|
|
393
|
+
};
|
|
300
394
|
}
|
|
301
395
|
}
|
|
396
|
+
else if (field.isUpdatedAt) {
|
|
397
|
+
d = {
|
|
398
|
+
...d,
|
|
399
|
+
[field.name]: new Date(),
|
|
400
|
+
};
|
|
401
|
+
}
|
|
302
402
|
else {
|
|
303
403
|
if (field.kind !== "object") {
|
|
304
|
-
d =
|
|
404
|
+
d = {
|
|
405
|
+
...d,
|
|
406
|
+
[field.name]: null,
|
|
407
|
+
};
|
|
305
408
|
}
|
|
306
409
|
}
|
|
307
410
|
}
|
|
@@ -310,8 +413,7 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
310
413
|
return d;
|
|
311
414
|
};
|
|
312
415
|
const matchItem = (child, item, where) => {
|
|
313
|
-
|
|
314
|
-
const val = item[child];
|
|
416
|
+
let val = item[child];
|
|
315
417
|
const filter = where[child];
|
|
316
418
|
if (child === "OR") {
|
|
317
419
|
return matchOr(item, filter);
|
|
@@ -337,9 +439,9 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
337
439
|
}
|
|
338
440
|
}
|
|
339
441
|
else {
|
|
340
|
-
if (typeof filter ===
|
|
341
|
-
const info = model.fields.find(field => field.name === child);
|
|
342
|
-
if (info
|
|
442
|
+
if (typeof filter === "object") {
|
|
443
|
+
const info = model.fields.find((field) => field.name === child);
|
|
444
|
+
if (info?.relationName) {
|
|
343
445
|
const childName = getCamelCase(info.type);
|
|
344
446
|
let childWhere = {};
|
|
345
447
|
if (filter.every) {
|
|
@@ -354,12 +456,15 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
354
456
|
else {
|
|
355
457
|
childWhere = filter;
|
|
356
458
|
}
|
|
357
|
-
const submodel = datamodel.models.find(model => {
|
|
459
|
+
const submodel = datamodel.models.find((model) => {
|
|
358
460
|
return getCamelCase(model.name) === childName;
|
|
359
461
|
});
|
|
360
462
|
const delegate = Delegate(getCamelCase(childName), submodel);
|
|
361
463
|
const res = delegate.findMany({
|
|
362
|
-
where:
|
|
464
|
+
where: {
|
|
465
|
+
...childWhere,
|
|
466
|
+
...getFieldRelationshipWhere(item, info),
|
|
467
|
+
},
|
|
363
468
|
});
|
|
364
469
|
if (filter.every) {
|
|
365
470
|
if (res.length === 0)
|
|
@@ -368,7 +473,7 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
368
473
|
// matchFnc(getFieldRelationshipWhere(item, info)),
|
|
369
474
|
// )
|
|
370
475
|
const all = delegate.findMany({
|
|
371
|
-
where: getFieldRelationshipWhere(item, info)
|
|
476
|
+
where: getFieldRelationshipWhere(item, info),
|
|
372
477
|
});
|
|
373
478
|
return res.length === all.length;
|
|
374
479
|
}
|
|
@@ -380,16 +485,16 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
380
485
|
}
|
|
381
486
|
return res.length > 0;
|
|
382
487
|
}
|
|
383
|
-
const idFields = model.idFields ||
|
|
384
|
-
if (
|
|
385
|
-
if (child === idFields.join(
|
|
386
|
-
return shallowCompare(item, filter);
|
|
488
|
+
const idFields = model.idFields || model.primaryKey?.fields;
|
|
489
|
+
if (idFields?.length > 1) {
|
|
490
|
+
if (child === idFields.join("_")) {
|
|
491
|
+
return (0, shallowCompare_1.shallowCompare)(item, filter);
|
|
387
492
|
}
|
|
388
493
|
}
|
|
389
|
-
if (
|
|
494
|
+
if (model.uniqueFields?.length > 0) {
|
|
390
495
|
for (const uniqueField of model.uniqueFields) {
|
|
391
|
-
if (child === uniqueField.join(
|
|
392
|
-
return shallowCompare(item, filter);
|
|
496
|
+
if (child === uniqueField.join("_")) {
|
|
497
|
+
return (0, shallowCompare_1.shallowCompare)(item, filter);
|
|
393
498
|
}
|
|
394
499
|
}
|
|
395
500
|
}
|
|
@@ -397,40 +502,53 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
397
502
|
return false;
|
|
398
503
|
}
|
|
399
504
|
let match = true;
|
|
400
|
-
|
|
401
|
-
|
|
505
|
+
const matchFilter = { ...filter };
|
|
506
|
+
if (options.caseInsensitive) {
|
|
507
|
+
val = val.toLowerCase ? val.toLowerCase() : val;
|
|
508
|
+
Object.keys(matchFilter).forEach((key) => {
|
|
509
|
+
const value = matchFilter[key];
|
|
510
|
+
if (value.toLowerCase) {
|
|
511
|
+
matchFilter[key] = value.toLowerCase();
|
|
512
|
+
}
|
|
513
|
+
else if (value instanceof Array) {
|
|
514
|
+
matchFilter[key] = value.map((v) => v.toLowerCase ? v.toLowerCase() : v);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
if ("equals" in matchFilter && match) {
|
|
519
|
+
match = (0, deepEqual_1.deepEqual)(matchFilter.equals, val);
|
|
402
520
|
}
|
|
403
|
-
if (
|
|
404
|
-
match = val.indexOf(
|
|
521
|
+
if ("startsWith" in matchFilter && match) {
|
|
522
|
+
match = val.indexOf(matchFilter.startsWith) === 0;
|
|
405
523
|
}
|
|
406
|
-
if (
|
|
524
|
+
if ("endsWith" in matchFilter && match) {
|
|
407
525
|
match =
|
|
408
|
-
val.indexOf(
|
|
409
|
-
val.length -
|
|
526
|
+
val.indexOf(matchFilter.endsWith) ===
|
|
527
|
+
val.length - matchFilter.endsWith.length;
|
|
410
528
|
}
|
|
411
|
-
if (
|
|
412
|
-
match = val.indexOf(
|
|
529
|
+
if ("contains" in matchFilter && match) {
|
|
530
|
+
match = val.indexOf(matchFilter.contains) > -1;
|
|
413
531
|
}
|
|
414
|
-
if (
|
|
415
|
-
match = val >
|
|
532
|
+
if ("gt" in matchFilter && match) {
|
|
533
|
+
match = val > matchFilter.gt;
|
|
416
534
|
}
|
|
417
|
-
if (
|
|
418
|
-
match = val >=
|
|
535
|
+
if ("gte" in matchFilter && match) {
|
|
536
|
+
match = val >= matchFilter.gte;
|
|
419
537
|
}
|
|
420
|
-
if (
|
|
421
|
-
match = val <
|
|
538
|
+
if ("lt" in matchFilter && match) {
|
|
539
|
+
match = val < matchFilter.lt;
|
|
422
540
|
}
|
|
423
|
-
if (
|
|
424
|
-
match = val <=
|
|
541
|
+
if ("lte" in matchFilter && match) {
|
|
542
|
+
match = val <= matchFilter.lte;
|
|
425
543
|
}
|
|
426
|
-
if (
|
|
427
|
-
match =
|
|
544
|
+
if ("in" in matchFilter && match) {
|
|
545
|
+
match = matchFilter.in.includes(val);
|
|
428
546
|
}
|
|
429
|
-
if (
|
|
430
|
-
match =
|
|
547
|
+
if ("not" in matchFilter && match) {
|
|
548
|
+
match = !(0, deepEqual_1.deepEqual)(matchFilter.not, val);
|
|
431
549
|
}
|
|
432
|
-
if (
|
|
433
|
-
match = !
|
|
550
|
+
if ("notIn" in matchFilter && match) {
|
|
551
|
+
match = !matchFilter.notIn.includes(val);
|
|
434
552
|
}
|
|
435
553
|
if (!match)
|
|
436
554
|
return false;
|
|
@@ -455,13 +573,13 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
455
573
|
const matchOr = (item, where) => {
|
|
456
574
|
return where.some((child) => matchItems(item, child));
|
|
457
575
|
};
|
|
458
|
-
const matchFnc = where => item => {
|
|
576
|
+
const matchFnc = (where) => (item) => {
|
|
459
577
|
if (where) {
|
|
460
578
|
return matchItems(item, where);
|
|
461
579
|
}
|
|
462
580
|
return true;
|
|
463
581
|
};
|
|
464
|
-
const findOne = args => {
|
|
582
|
+
const findOne = (args) => {
|
|
465
583
|
if (!data[prop])
|
|
466
584
|
return null;
|
|
467
585
|
const items = findMany(args);
|
|
@@ -470,13 +588,13 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
470
588
|
}
|
|
471
589
|
return items[0];
|
|
472
590
|
};
|
|
473
|
-
const findMany = args => {
|
|
474
|
-
let res = data[prop].filter(matchFnc(args
|
|
475
|
-
if (args
|
|
591
|
+
const findMany = (args) => {
|
|
592
|
+
let res = data[prop].filter(matchFnc(args?.where)).map(includes(args));
|
|
593
|
+
if (args?.distinct) {
|
|
476
594
|
let values = {};
|
|
477
|
-
res = res.filter(item => {
|
|
595
|
+
res = res.filter((item) => {
|
|
478
596
|
let shouldInclude = true;
|
|
479
|
-
args.distinct.forEach(key => {
|
|
597
|
+
args.distinct.forEach((key) => {
|
|
480
598
|
const vals = values[key] || [];
|
|
481
599
|
if (vals.includes(item[key])) {
|
|
482
600
|
shouldInclude = false;
|
|
@@ -489,41 +607,50 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
489
607
|
return shouldInclude;
|
|
490
608
|
});
|
|
491
609
|
}
|
|
492
|
-
if (args
|
|
493
|
-
res.sort(sortFunc(args
|
|
610
|
+
if (args?.orderBy) {
|
|
611
|
+
res.sort(sortFunc(args?.orderBy));
|
|
494
612
|
}
|
|
495
|
-
if (args
|
|
496
|
-
res = res.map(item => {
|
|
613
|
+
if (args?.select) {
|
|
614
|
+
res = res.map((item) => {
|
|
497
615
|
const newItem = {};
|
|
498
|
-
Object.keys(args.select).forEach(key => (newItem[key] = item[key]));
|
|
616
|
+
Object.keys(args.select).forEach((key) => (newItem[key] = item[key]));
|
|
499
617
|
return newItem;
|
|
500
618
|
});
|
|
501
619
|
}
|
|
502
|
-
if (
|
|
503
|
-
const start =
|
|
504
|
-
const end =
|
|
620
|
+
if (args?.skip !== undefined || args?.take !== undefined) {
|
|
621
|
+
const start = args?.skip !== undefined ? args?.skip : 0;
|
|
622
|
+
const end = args?.take !== undefined ? start + args.take : undefined;
|
|
505
623
|
res = res.slice(start, end);
|
|
506
624
|
}
|
|
507
625
|
return res;
|
|
508
626
|
};
|
|
509
|
-
const updateMany = args => {
|
|
627
|
+
const updateMany = (args) => {
|
|
510
628
|
// if (!Array.isArray(data[prop])) {
|
|
511
629
|
// throw new Error(`${prop} not found in data`)
|
|
512
630
|
// }
|
|
513
|
-
const newItems = data[prop].map(e => {
|
|
631
|
+
const newItems = data[prop].map((e) => {
|
|
514
632
|
if (matchFnc(args.where)(e)) {
|
|
515
633
|
let data = nestedUpdate(args, false, e);
|
|
516
|
-
return
|
|
634
|
+
return {
|
|
635
|
+
...e,
|
|
636
|
+
...data,
|
|
637
|
+
};
|
|
517
638
|
}
|
|
518
639
|
return e;
|
|
519
640
|
});
|
|
520
|
-
data =
|
|
641
|
+
data = {
|
|
642
|
+
...data,
|
|
643
|
+
[prop]: newItems,
|
|
644
|
+
};
|
|
521
645
|
data = removeMultiFieldIds(model, data);
|
|
522
646
|
return data;
|
|
523
647
|
};
|
|
524
|
-
const create = args => {
|
|
648
|
+
const create = (args) => {
|
|
525
649
|
const d = nestedUpdate(args, true, null);
|
|
526
|
-
data =
|
|
650
|
+
data = {
|
|
651
|
+
...data,
|
|
652
|
+
[prop]: [...data[prop], d],
|
|
653
|
+
};
|
|
527
654
|
data = removeMultiFieldIds(model, data);
|
|
528
655
|
let where = {};
|
|
529
656
|
for (const field of model.fields) {
|
|
@@ -531,23 +658,26 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
531
658
|
where[field.name] = d[field.name];
|
|
532
659
|
}
|
|
533
660
|
}
|
|
534
|
-
return findOne(
|
|
661
|
+
return findOne({ where, ...args });
|
|
535
662
|
};
|
|
536
|
-
const deleteMany = args => {
|
|
537
|
-
const model = datamodel.models.find(model => {
|
|
663
|
+
const deleteMany = (args) => {
|
|
664
|
+
const model = datamodel.models.find((model) => {
|
|
538
665
|
return getCamelCase(model.name) === prop;
|
|
539
666
|
});
|
|
540
667
|
const deleted = [];
|
|
541
|
-
data =
|
|
542
|
-
|
|
668
|
+
data = {
|
|
669
|
+
...data,
|
|
670
|
+
[prop]: data[prop].filter((e) => {
|
|
671
|
+
const shouldDelete = matchFnc(args?.where)(e);
|
|
543
672
|
if (shouldDelete) {
|
|
544
673
|
deleted.push(e);
|
|
545
674
|
}
|
|
546
675
|
return !shouldDelete;
|
|
547
|
-
})
|
|
676
|
+
}),
|
|
677
|
+
};
|
|
548
678
|
// Referential Actions
|
|
549
|
-
deleted.forEach(item => {
|
|
550
|
-
model.fields.forEach(field => {
|
|
679
|
+
deleted.forEach((item) => {
|
|
680
|
+
model.fields.forEach((field) => {
|
|
551
681
|
const joinfield = getJoinField(field);
|
|
552
682
|
if (!joinfield)
|
|
553
683
|
return;
|
|
@@ -559,65 +689,83 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
559
689
|
},
|
|
560
690
|
data: {
|
|
561
691
|
[joinfield.relationFromFields[0]]: null,
|
|
562
|
-
}
|
|
692
|
+
},
|
|
563
693
|
});
|
|
564
694
|
}
|
|
565
695
|
else if (joinfield.relationOnDelete === "Cascade") {
|
|
566
696
|
delegate.delete({
|
|
567
697
|
where: {
|
|
568
698
|
[joinfield.relationFromFields[0]]: item[joinfield.relationToFields[0]],
|
|
569
|
-
}
|
|
699
|
+
},
|
|
570
700
|
});
|
|
571
701
|
}
|
|
572
702
|
});
|
|
573
703
|
});
|
|
574
704
|
return deleted;
|
|
575
705
|
};
|
|
576
|
-
const includes = args => item => {
|
|
577
|
-
if ((!
|
|
706
|
+
const includes = (args) => (item) => {
|
|
707
|
+
if ((!args?.include && !args?.select) || !item)
|
|
578
708
|
return item;
|
|
579
709
|
let newItem = item;
|
|
580
|
-
const obj =
|
|
710
|
+
const obj = args?.select || args?.include;
|
|
581
711
|
const keys = Object.keys(obj);
|
|
582
|
-
keys.forEach(key => {
|
|
712
|
+
keys.forEach((key) => {
|
|
583
713
|
// Get field schema for relation info
|
|
584
|
-
const model = datamodel.models.find(model => {
|
|
714
|
+
const model = datamodel.models.find((model) => {
|
|
585
715
|
return getCamelCase(model.name) === prop;
|
|
586
716
|
});
|
|
587
|
-
const schema = model.fields.find(field => {
|
|
717
|
+
const schema = model.fields.find((field) => {
|
|
588
718
|
return field.name === key;
|
|
589
719
|
});
|
|
590
|
-
if (!
|
|
720
|
+
if (!schema?.relationName) {
|
|
591
721
|
return;
|
|
592
722
|
}
|
|
593
723
|
// Get delegate for relation
|
|
594
724
|
const delegate = Delegate(getCamelCase(schema.type), model);
|
|
595
725
|
// Construct arg for relation query
|
|
596
726
|
let subArgs = obj[key] === true ? {} : obj[key];
|
|
597
|
-
subArgs =
|
|
727
|
+
subArgs = {
|
|
728
|
+
...subArgs,
|
|
729
|
+
where: {
|
|
730
|
+
...subArgs.where,
|
|
731
|
+
...getFieldRelationshipWhere(item, schema),
|
|
732
|
+
},
|
|
733
|
+
};
|
|
598
734
|
if (schema.isList) {
|
|
599
735
|
// Add relation
|
|
600
|
-
newItem =
|
|
736
|
+
newItem = {
|
|
737
|
+
...newItem,
|
|
738
|
+
[key]: delegate.findMany(subArgs),
|
|
739
|
+
};
|
|
601
740
|
}
|
|
602
741
|
else {
|
|
603
|
-
newItem =
|
|
742
|
+
newItem = {
|
|
743
|
+
...newItem,
|
|
744
|
+
[key]: delegate.findUnique(subArgs),
|
|
745
|
+
};
|
|
604
746
|
}
|
|
605
747
|
});
|
|
606
748
|
return newItem;
|
|
607
749
|
};
|
|
608
750
|
const update = (args) => {
|
|
609
751
|
let updatedItem;
|
|
610
|
-
const newItems = data[prop].map(e => {
|
|
752
|
+
const newItems = data[prop].map((e) => {
|
|
611
753
|
if (matchFnc(args.where)(e)) {
|
|
612
754
|
let data = nestedUpdate(args, false, e);
|
|
613
|
-
updatedItem =
|
|
755
|
+
updatedItem = {
|
|
756
|
+
...e,
|
|
757
|
+
...data,
|
|
758
|
+
};
|
|
614
759
|
return updatedItem;
|
|
615
760
|
}
|
|
616
761
|
return e;
|
|
617
762
|
});
|
|
618
|
-
data =
|
|
763
|
+
data = {
|
|
764
|
+
...data,
|
|
765
|
+
[prop]: newItems,
|
|
766
|
+
};
|
|
619
767
|
data = removeMultiFieldIds(model, data);
|
|
620
|
-
return findOne(
|
|
768
|
+
return findOne({ ...args, where: updatedItem });
|
|
621
769
|
};
|
|
622
770
|
return {
|
|
623
771
|
findOne,
|
|
@@ -627,11 +775,20 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
627
775
|
create,
|
|
628
776
|
createMany: (args) => {
|
|
629
777
|
args.data.forEach((data) => {
|
|
630
|
-
create(
|
|
778
|
+
create({
|
|
779
|
+
...args,
|
|
780
|
+
data,
|
|
781
|
+
});
|
|
631
782
|
});
|
|
632
783
|
return findMany(args);
|
|
633
784
|
},
|
|
634
|
-
delete:
|
|
785
|
+
delete: (args) => {
|
|
786
|
+
const deleted = deleteMany(args);
|
|
787
|
+
if (deleted.length) {
|
|
788
|
+
return deleted[0];
|
|
789
|
+
}
|
|
790
|
+
return null;
|
|
791
|
+
},
|
|
635
792
|
update,
|
|
636
793
|
deleteMany,
|
|
637
794
|
updateMany: (args) => {
|
|
@@ -641,10 +798,19 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
641
798
|
upsert(args) {
|
|
642
799
|
const res = findOne(args);
|
|
643
800
|
if (res) {
|
|
644
|
-
return update(
|
|
801
|
+
return update({
|
|
802
|
+
...args,
|
|
803
|
+
data: args.update,
|
|
804
|
+
});
|
|
645
805
|
}
|
|
646
806
|
else {
|
|
647
|
-
create(
|
|
807
|
+
create({
|
|
808
|
+
...args,
|
|
809
|
+
data: {
|
|
810
|
+
...args.where,
|
|
811
|
+
...args.create,
|
|
812
|
+
},
|
|
813
|
+
});
|
|
648
814
|
return findOne(args);
|
|
649
815
|
}
|
|
650
816
|
},
|
|
@@ -655,16 +821,19 @@ const createPrismaMock = (data = {}, datamodel, client = (0, jest_mock_extended_
|
|
|
655
821
|
_sortFunc: sortFunc,
|
|
656
822
|
};
|
|
657
823
|
};
|
|
658
|
-
datamodel.models.forEach(model => {
|
|
824
|
+
datamodel.models.forEach((model) => {
|
|
659
825
|
if (!model)
|
|
660
826
|
return;
|
|
661
827
|
const c = getCamelCase(model.name);
|
|
662
828
|
if (!data[c]) {
|
|
663
|
-
data =
|
|
829
|
+
data = {
|
|
830
|
+
...(data || {}),
|
|
831
|
+
[c]: [],
|
|
832
|
+
};
|
|
664
833
|
}
|
|
665
834
|
data = removeMultiFieldIds(model, data);
|
|
666
835
|
const objs = Delegate(c, model);
|
|
667
|
-
Object.keys(objs).forEach(fncName => {
|
|
836
|
+
Object.keys(objs).forEach((fncName) => {
|
|
668
837
|
if (fncName.indexOf("_") === 0)
|
|
669
838
|
return;
|
|
670
839
|
client[c][fncName].mockImplementation(async (...params) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepEqual(a: any, b: any): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deepEqual = void 0;
|
|
4
|
+
// deepEqual
|
|
5
|
+
function deepEqual(a, b) {
|
|
6
|
+
if ((typeof a == 'object' && a != null) &&
|
|
7
|
+
(typeof b == 'object' && b != null)) {
|
|
8
|
+
var count = [0, 0];
|
|
9
|
+
for (var key in a)
|
|
10
|
+
count[0]++;
|
|
11
|
+
for (var key in b)
|
|
12
|
+
count[1]++;
|
|
13
|
+
if (count[0] - count[1] != 0) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
for (var key in a) {
|
|
17
|
+
if (!(key in b) || !deepEqual(a[key], b[key])) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for (var key in b) {
|
|
22
|
+
if (!(key in a) || !deepEqual(b[key], a[key])) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return a === b;
|
|
29
|
+
}
|
|
30
|
+
exports.deepEqual = deepEqual;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shallowCompare = void 0;
|
|
4
|
+
const shallowCompare = (a, b) => {
|
|
5
|
+
for (let key in b) {
|
|
6
|
+
if (a[key] !== b[key])
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return true;
|
|
10
|
+
};
|
|
11
|
+
exports.shallowCompare = shallowCompare;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prisma-mock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Mock prisma for unit testing database",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"repository": "https://github.com/demonsters/prisma-mock",
|
|
@@ -26,5 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@prisma/client": "^3.5.0 || ^4.7.0"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@paralleldrive/cuid2": "^2.0.0"
|
|
29
32
|
}
|
|
30
33
|
}
|