prisma-mock 1.0.0-alpha.8 → 1.0.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 CHANGED
@@ -76,34 +76,16 @@ beforeEach(() => {
76
76
  })
77
77
  ```
78
78
 
79
+ ## API
80
+
79
81
  ### Exports
80
82
 
81
83
  The library provides three different exports:
82
84
 
83
85
  - **`prisma-mock`** (default): The recommended way to use the library. Automatically uses the Prisma client from `@prisma/client/default`, so you don't need to pass Prisma as an argument.
84
- - **`prisma-mock/client`**: Use this when you need to explicitly pass the Prisma namespace (try the default export first).
86
+ - **`prisma-mock/client`**: Use this when you need to explicitly pass the Prisma namespace.
85
87
  - **`prisma-mock/legacy`**: The old API for backward compatibility. This export is deprecated but maintained for existing codebases.
86
88
 
87
- ### Legacy Export
88
-
89
- The legacy export maintains the old API signature for backward compatibility:
90
-
91
- ```js
92
- import createPrismaMock from "prisma-mock/legacy"
93
- import { mockDeep } from "jest-mock-extended"
94
-
95
- const client = createPrismaMock(
96
- { user: [{ id: 1, name: "John" }] }, // data
97
- Prisma.dmmf.datamodel, // datamodel (optional)
98
- mockDeep(), // mockClient (optional)
99
- { enableIndexes: true } // options (optional)
100
- )
101
- ```
102
-
103
- **Note**: If you're starting a new project, use the default export instead. The legacy export is only for maintaining existing codebases that haven't migrated yet.
104
-
105
- ## API
106
-
107
89
  ### Default Export (`prisma-mock`)
108
90
 
109
91
  ```ts
@@ -118,6 +100,24 @@ createPrismaMock<P extends PrismaClient = PrismaClient>(
118
100
  ): P & { $getInternalState: () => Required<PrismaMockData<P>> }
119
101
  ```
120
102
 
103
+ ### Parameters
104
+
105
+ - **`options`** (optional): Configuration options (see below)
106
+
107
+ #### Options
108
+
109
+ - **`data`** (optional): Initial mock data for the Prisma models. An object containing keys for tables and values as arrays of objects.
110
+ - **`datamodel`** (optional): The Prisma datamodel, typically `Prisma.dmmf.datamodel` (default).
111
+ - **`mockClient`** (optional): A `jest-mock-extended` or `vitest-mock-extended` instance. If not provided, a plain object is used instead.
112
+ - **`caseInsensitive`** (boolean, default: `false`): If true, all string comparisons are case insensitive
113
+ - **`enableIndexes`** (boolean, default: `true`) If true, enables indexing for better query performance on primary keys, unique fields, and foreign keys
114
+
115
+ ### Return Value
116
+
117
+ Returns a mock Prisma client with all standard model methods plus:
118
+
119
+ - `$getInternalState()`: Method to access the internal data state for testing/debugging
120
+
121
121
  ### Client Export (`prisma-mock/client`)
122
122
 
123
123
  ```ts
@@ -133,30 +133,28 @@ createPrismaMock<PClient extends PrismaClient, P extends typeof Prisma = typeof
133
133
  ): PClient & { $getInternalState: () => Required<PrismaMockData<PClient>> }
134
134
  ```
135
135
 
136
- ### Parameters
137
-
138
- #### Default Export
139
-
140
- - **`options`** (optional): Configuration options (see below)
141
-
142
- #### Client Export
136
+ #### Parameters
143
137
 
144
138
  - **`prisma`** (required): The Prisma namespace (e.g., `Prisma` from `@prisma/client`). This is used to access the datamodel and type information.
145
- - **`options`** (optional): Configuration options (see below)
139
+ - **`options`** (optional): Configuration options. Same as the default export, with the exception of the `datamodel` not being optional.
146
140
 
147
- #### Options
141
+ ### Legacy Export (`prisma-mock/legacy`)
148
142
 
149
- - **`data`** (optional): Initial mock data for the Prisma models. An object containing keys for tables and values as arrays of objects.
150
- - **`datamodel`** (optional): The Prisma datamodel, typically `Prisma.dmmf.datamodel`. Defaults to the Prisma client's datamodel.
151
- - **`mockClient`** (optional): A `jest-mock-extended` or `vitest-mock-extended` instance. If not provided, a plain object is used instead.
152
- - **`caseInsensitive`** (boolean, default: `false`): If true, all string comparisons are case insensitive
153
- - **`enableIndexes`** (boolean, default: `false`) Experimental: If true, enables indexing for better query performance on primary keys, unique fields, and foreign keys
143
+ The legacy export maintains the old API signature for backward compatibility:
154
144
 
155
- ### Return Value
145
+ ```js
146
+ import createPrismaMock from "prisma-mock/legacy"
147
+ import { mockDeep } from "jest-mock-extended"
156
148
 
157
- Returns a mock Prisma client with all standard model methods plus:
149
+ const client = createPrismaMock(
150
+ { user: [{ id: 1, name: "John" }] }, // data
151
+ Prisma.dmmf.datamodel, // datamodel (optional)
152
+ mockDeep(), // mockClient (optional)
153
+ { enableIndexes: true } // options (optional)
154
+ )
155
+ ```
158
156
 
159
- - `$getInternalState()`: Method to access the internal data state for testing/debugging
157
+ **Note**: If you're starting a new project, use the default export instead. The legacy export is only for maintaining existing codebases that haven't migrated yet.
160
158
 
161
159
  ## DMMF Generator
162
160
 
@@ -180,7 +178,7 @@ generator client {
180
178
  provider = "prisma-client-js"
181
179
  }
182
180
 
183
- generator prisma-mock {
181
+ generator dmmf {
184
182
  provider = "prisma-mock"
185
183
  output = "./generated/dmmf"
186
184
  }
@@ -353,19 +351,9 @@ The following features are planned but not yet implemented:
353
351
 
354
352
  ## Performance Features
355
353
 
356
- ### Indexing (Experimental)
357
-
358
- Enable indexing for better query performance:
359
-
360
- ```js
361
- import createPrismaMock from "prisma-mock"
362
-
363
- const client = createPrismaMock({
364
- enableIndexes: true,
365
- })
366
- ```
354
+ ### Indexing
367
355
 
368
- When enabled, indexes are automatically created for:
356
+ Indexing is enabled by default for better query performance. Indexes are automatically created for:
369
357
 
370
358
  - Primary key fields
371
359
  - Unique fields
package/lib/client.js CHANGED
@@ -11,14 +11,15 @@ const fieldHelpers_1 = require("./utils/fieldHelpers");
11
11
  // @param prisma - The Prisma namespace or client constructor.
12
12
  // @param options - Options for configuring the mock client:
13
13
  // - data: Initial mock data for your models (default: {}).
14
+ // - datamodel: The Prisma datamodel, typically `Prisma.dmmf.datamodel`. Defaults to the Prisma client's datamodel.
14
15
  // - caseInsensitive: If true, string matching is case-insensitive (default: false).
15
- // - enableIndexes: If true, enables index lookups for performance (default: false).
16
+ // - enableIndexes: If true, enables index lookups for performance (default: true).
16
17
  // - mockClient: Optionally provide your own mock client (jest-mock-extended or vitest-mock-extended) instance to use.
17
18
  // @returns A mock Prisma client with all model methods and access to internal state.
18
19
  function createPrismaMock(prisma, options = {
19
20
  datamodel: prisma.dmmf?.datamodel,
20
21
  caseInsensitive: false,
21
- enableIndexes: false,
22
+ enableIndexes: true,
22
23
  data: {}
23
24
  }) {
24
25
  // Reference object to hold the mock data state
package/lib/delegate.js CHANGED
@@ -7,9 +7,8 @@ exports.createDelegate = void 0;
7
7
  const defaults_1 = __importDefault(require("./defaults"));
8
8
  const errors_1 = require("./errors");
9
9
  const fieldHelpers_1 = require("./utils/fieldHelpers");
10
- const queryMatching_1 = __importDefault(require("./utils/queryMatching"));
11
- const shallowCompare_1 = require("./utils/shallowCompare");
12
10
  const getWhereOnIds_1 = __importDefault(require("./utils/getWhereOnIds"));
11
+ const queryMatching_1 = __importDefault(require("./utils/queryMatching"));
13
12
  /**
14
13
  * Creates a delegate function that handles Prisma-like operations for a specific model
15
14
  * This is the main factory function that generates model-specific CRUD operations
@@ -41,10 +40,10 @@ const createDelegate = ({ ref, prisma, datamodel = prisma.dmmf.datamodel, caseIn
41
40
  */
42
41
  const Delegate = (prop, model) => {
43
42
  const getDelegateForFieldName = (field) => {
43
+ const name = (0, fieldHelpers_1.getCamelCase)(field);
44
44
  const otherModel = datamodel.models.find((model) => {
45
- return (0, fieldHelpers_1.getCamelCase)(model.name) === (0, fieldHelpers_1.getCamelCase)(field);
45
+ return name === (0, fieldHelpers_1.getCamelCase)(model.name);
46
46
  });
47
- const name = (0, fieldHelpers_1.getCamelCase)(field);
48
47
  return Delegate(name, otherModel);
49
48
  };
50
49
  // Create matching function for WHERE clauses
@@ -174,30 +173,16 @@ const createDelegate = ({ ref, prisma, datamodel = prisma.dmmf.datamodel, caseIn
174
173
  const keyToMatch = Object.keys(connect)[0];
175
174
  const keyToGet = field.relationToFields[0];
176
175
  const targetKey = field.relationFromFields[0];
176
+ const delegate = getDelegateForFieldName(field.type);
177
177
  if (keyToGet && targetKey) {
178
178
  let connectionValue = connect[keyToGet];
179
179
  if (keyToMatch !== keyToGet) {
180
- const valueToMatch = connect[keyToMatch];
181
- let matchingRow = ref.data[(0, fieldHelpers_1.getCamelCase)(field.type)].find((row) => {
182
- return row[keyToMatch] === valueToMatch;
180
+ // Try to find by unique index if direct match fails
181
+ let matchingRow = delegate.findOne({
182
+ where: connect
183
183
  });
184
184
  if (!matchingRow) {
185
- // Try to find by unique index if direct match fails
186
- const refModel = datamodel.models.find((model) => (0, fieldHelpers_1.getCamelCase)(field.type) === (0, fieldHelpers_1.getCamelCase)(model.name));
187
- const uniqueIndexes = refModel.uniqueIndexes.map((index) => {
188
- return {
189
- ...index,
190
- key: index.name ?? index.fields.join("_"),
191
- };
192
- });
193
- const indexKey = uniqueIndexes.find((index) => index.key === keyToMatch);
194
- matchingRow = ref.data[(0, fieldHelpers_1.getCamelCase)(field.type)].find((row) => {
195
- const target = Object.fromEntries(Object.entries(row).filter((row) => indexKey?.fields.includes(row[0]) ?? false));
196
- return (0, shallowCompare_1.shallowCompare)(target, valueToMatch);
197
- });
198
- if (!matchingRow) {
199
- (0, errors_1.throwKnownError)(prisma, "An operation failed because it depends on one or more records that were required but not found. {cause}");
200
- }
185
+ (0, errors_1.throwKnownError)(prisma, "An operation failed because it depends on one or more records that were required but not found. {cause}");
201
186
  }
202
187
  connectionValue = matchingRow[keyToGet];
203
188
  }
@@ -210,11 +195,14 @@ const createDelegate = ({ ref, prisma, datamodel = prisma.dmmf.datamodel, caseIn
210
195
  }
211
196
  else {
212
197
  inputData = rest;
198
+ const newData = {
199
+ ...item,
200
+ ...inputData,
201
+ };
213
202
  const otherModel = datamodel.models.find((model) => {
214
203
  return model.name === field.type;
215
204
  });
216
205
  const otherField = otherModel.fields.find((otherField) => field.relationName === otherField.relationName);
217
- const delegate = getDelegateForFieldName(field.type);
218
206
  const otherTargetKey = otherField.relationToFields[0];
219
207
  if ((!targetKey && !keyToGet) && otherTargetKey) {
220
208
  delegate.update({
@@ -222,9 +210,9 @@ const createDelegate = ({ ref, prisma, datamodel = prisma.dmmf.datamodel, caseIn
222
210
  data: {
223
211
  [(0, fieldHelpers_1.getCamelCase)(otherField.name)]: {
224
212
  connect: {
225
- [otherTargetKey]: inputData[otherTargetKey],
226
- },
227
- },
213
+ [otherTargetKey]: newData[otherTargetKey],
214
+ }
215
+ }
228
216
  }
229
217
  });
230
218
  }
@@ -234,7 +222,7 @@ const createDelegate = ({ ref, prisma, datamodel = prisma.dmmf.datamodel, caseIn
234
222
  [field.type]: delegate.findOne({
235
223
  where: connect
236
224
  }),
237
- [otherField.type]: item || inputData
225
+ [otherField.type]: item || newData
238
226
  });
239
227
  }
240
228
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-mock",
3
- "version": "1.0.0-alpha.8",
3
+ "version": "1.0.0",
4
4
  "description": "Mock prisma for unit testing database",
5
5
  "main": "lib/index.js",
6
6
  "repository": {