prisma-mock 0.12.2 → 1.0.0-alpha.1
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/lib/client.d.ts +6 -0
- package/lib/client.js +131 -0
- package/lib/defaults/autoincrement.d.ts +3 -0
- package/lib/defaults/cuid.d.ts +2 -0
- package/lib/defaults/index.d.ts +5 -0
- package/lib/defaults/now.d.ts +2 -0
- package/lib/defaults/uuid.d.ts +2 -0
- package/lib/delegate.d.ts +48 -0
- package/lib/delegate.js +10 -14
- package/lib/errors.d.ts +9 -0
- package/lib/errors.js +6 -7
- package/lib/index.d.ts +73 -0
- package/lib/index.js +6 -125
- package/lib/indexes.d.ts +15 -0
- package/lib/indexes.js +1 -1
- package/lib/legacy.d.ts +76 -0
- package/lib/legacy.js +24 -0
- package/lib/types.d.ts +27 -0
- package/lib/utils/deepCopy.d.ts +1 -0
- package/lib/utils/deepEqual.d.ts +1 -0
- package/lib/utils/fieldHelpers.d.ts +13 -0
- package/lib/utils/getNestedValue.d.ts +1 -0
- package/lib/utils/getWhereOnIds.d.ts +2 -0
- package/lib/utils/pad.d.ts +1 -0
- package/lib/utils/queryMatching.d.ts +13 -0
- package/lib/utils/queryMatching.js +10 -11
- package/lib/utils/shallowCompare.d.ts +5 -0
- package/package.json +19 -3
- package/prisma-dmmf-generator.mjs +25 -0
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Prisma, PrismaClient } from "@prisma/client";
|
|
2
|
+
import { MockPrismaOptions, PrismaMockData } from "./types";
|
|
3
|
+
declare const createPrismaMock: <PClient extends PrismaClient<Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>, P extends typeof Prisma>(prisma: P, options?: MockPrismaOptions<P>) => P & {
|
|
4
|
+
$getInternalState: () => Required<Partial<{ [key in import("./types").IsTable<Uncapitalize<import("./types").IsString<keyof PClient>>>]: import("./types").PrismaList<PClient, key>; }>>;
|
|
5
|
+
};
|
|
6
|
+
export default createPrismaMock;
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const delegate_1 = require("./delegate");
|
|
7
|
+
const indexes_1 = __importDefault(require("./indexes"));
|
|
8
|
+
const deepCopy_1 = require("./utils/deepCopy");
|
|
9
|
+
const fieldHelpers_1 = require("./utils/fieldHelpers");
|
|
10
|
+
// Creates a mock Prisma client.
|
|
11
|
+
// @param prisma - The Prisma namespace or client constructor.
|
|
12
|
+
// @param options - Options for configuring the mock client:
|
|
13
|
+
// - data: Initial mock data for your models (default: {}).
|
|
14
|
+
// - caseInsensitive: If true, string matching is case-insensitive (default: false).
|
|
15
|
+
// - enableIndexes: If true, enables index lookups for performance (default: false).
|
|
16
|
+
// - mockClient: Optionally provide your own mock client (jest-mock-extended or vitest-mock-extended) instance to use.
|
|
17
|
+
// @returns A mock Prisma client with all model methods and access to internal state.
|
|
18
|
+
const createPrismaMock = (prisma, options = {
|
|
19
|
+
datamodel: prisma.dmmf.datamodel,
|
|
20
|
+
caseInsensitive: false,
|
|
21
|
+
enableIndexes: false,
|
|
22
|
+
data: {}
|
|
23
|
+
}) => {
|
|
24
|
+
// Reference object to hold the mock data state
|
|
25
|
+
let ref = {
|
|
26
|
+
data: options.data || {},
|
|
27
|
+
};
|
|
28
|
+
// Initialize the mock client (either use provided one or create new)
|
|
29
|
+
let client = options.mockClient ? options.mockClient : {};
|
|
30
|
+
/**
|
|
31
|
+
* Helper function to implement mock methods consistently
|
|
32
|
+
* @param name - Method name to mock
|
|
33
|
+
* @param fnc - Function implementation
|
|
34
|
+
*/
|
|
35
|
+
const mockImplementation = (name, fnc) => {
|
|
36
|
+
if (options.mockClient) {
|
|
37
|
+
client[name].mockImplementation(fnc);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
client[name] = fnc;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
// Create indexes if enabled in options
|
|
44
|
+
const indexes = (0, indexes_1.default)(!!options.enableIndexes, prisma);
|
|
45
|
+
// Determine if case-insensitive matching should be used
|
|
46
|
+
const caseInsensitive = options.caseInsensitive || false;
|
|
47
|
+
// Mock $transaction method for handling database transactions
|
|
48
|
+
mockImplementation("$transaction", async (actions) => {
|
|
49
|
+
const res = [];
|
|
50
|
+
if (Array.isArray(actions)) {
|
|
51
|
+
// Handle array of promises (parallel execution)
|
|
52
|
+
for (const action of actions) {
|
|
53
|
+
res.push(await action);
|
|
54
|
+
}
|
|
55
|
+
return res;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Handle callback function (serial execution with rollback on error)
|
|
59
|
+
const snapshot = (0, deepCopy_1.deepCopy)(ref.data);
|
|
60
|
+
try {
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
return await actions(client);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
// Rollback data on error
|
|
66
|
+
ref.data = snapshot;
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
// Mock connection methods
|
|
72
|
+
mockImplementation("$connect", async () => { });
|
|
73
|
+
mockImplementation("$disconnect", async () => { });
|
|
74
|
+
mockImplementation("$use", async () => {
|
|
75
|
+
throw new Error("$use is not yet implemented in prisma-mock");
|
|
76
|
+
});
|
|
77
|
+
// Create delegate functions for model operations
|
|
78
|
+
const Delegate = (0, delegate_1.createDelegate)({ ref, prisma, datamodel: options.datamodel, caseInsensitive, indexes });
|
|
79
|
+
// Initialize each model in the datamodel
|
|
80
|
+
prisma.dmmf.datamodel.models.forEach((model) => {
|
|
81
|
+
if (!model)
|
|
82
|
+
return;
|
|
83
|
+
// Convert model name to camelCase for consistency
|
|
84
|
+
const c = (0, fieldHelpers_1.getCamelCase)(model.name);
|
|
85
|
+
// Initialize empty array for model if it doesn't exist
|
|
86
|
+
if (!ref.data[c]) {
|
|
87
|
+
ref.data = {
|
|
88
|
+
...(ref.data || {}),
|
|
89
|
+
[c]: [],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Remove multi-field IDs from the data structure
|
|
93
|
+
ref.data = (0, fieldHelpers_1.removeMultiFieldIds)(model, ref.data);
|
|
94
|
+
// Set up indexes for each field in the model
|
|
95
|
+
model.fields.forEach((field) => {
|
|
96
|
+
const isPrimaryKey = !!model.primaryKey?.fields.includes(field.name);
|
|
97
|
+
indexes.addIndexFieldIfNeeded(c, field, isPrimaryKey);
|
|
98
|
+
});
|
|
99
|
+
// Update indexes with existing data
|
|
100
|
+
ref.data[c].forEach((item) => {
|
|
101
|
+
indexes.updateItem(c, item, null);
|
|
102
|
+
});
|
|
103
|
+
// Create delegate functions for this model
|
|
104
|
+
const objs = Delegate(c, model);
|
|
105
|
+
// Bind delegate functions to the client
|
|
106
|
+
Object.keys(objs).forEach((fncName) => {
|
|
107
|
+
// Skip private methods (those starting with underscore)
|
|
108
|
+
if (fncName.indexOf("_") === 0)
|
|
109
|
+
return;
|
|
110
|
+
// Initialize model namespace if it doesn't exist
|
|
111
|
+
if (!client[c])
|
|
112
|
+
client[c] = {};
|
|
113
|
+
// Bind the delegate function to the client
|
|
114
|
+
if (options.mockClient) {
|
|
115
|
+
client[c][fncName].mockImplementation(async (...params) => {
|
|
116
|
+
return objs[fncName](...params);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
client[c][fncName] = async (...params) => {
|
|
121
|
+
return objs[fncName](...params);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
// Add method to access internal state for testing/debugging
|
|
127
|
+
client['$getInternalState'] = () => ref.data;
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
return client;
|
|
130
|
+
};
|
|
131
|
+
exports.default = createPrismaMock;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
import { PrismaMockData } from "../types";
|
|
3
|
+
export default function createAutoincrement(): <P>(prop: string, field: Prisma.DMMF.Field, data?: Partial<{ [key in import("../types").IsTable<Uncapitalize<import("../types").IsString<keyof P>>>]: import("../types").PrismaList<P, key>; }>) => Number | BigInt;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
import { PrismaMockData } from "../types";
|
|
3
|
+
export default function createHandleDefault(): <P>(prop: string, field: Prisma.DMMF.Field, ref: {
|
|
4
|
+
data: Partial<{ [key in import("../types").IsTable<Uncapitalize<import("../types").IsString<keyof P>>>]: import("../types").PrismaList<P, key>; }>;
|
|
5
|
+
}) => any;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
import createIndexes from "./indexes";
|
|
3
|
+
import { CreateArgs } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a delegate function that handles Prisma-like operations for a specific model
|
|
6
|
+
* This is the main factory function that generates model-specific CRUD operations
|
|
7
|
+
*/
|
|
8
|
+
export declare const createDelegate: <P extends typeof Prisma>({ ref, prisma, datamodel, caseInsensitive, indexes }: {
|
|
9
|
+
ref: any;
|
|
10
|
+
prisma: P;
|
|
11
|
+
datamodel: P["dmmf"]["datamodel"];
|
|
12
|
+
caseInsensitive: boolean;
|
|
13
|
+
indexes: ReturnType<typeof createIndexes>;
|
|
14
|
+
}) => (prop: string, model: Prisma.DMMF.Model) => {
|
|
15
|
+
aggregate: (args: any) => any;
|
|
16
|
+
groupBy: (args: any) => any[];
|
|
17
|
+
findOne: (args: any) => any;
|
|
18
|
+
findUnique: (args: any) => any;
|
|
19
|
+
findUniqueOrThrow: (args: any) => any;
|
|
20
|
+
findMany: (args: any) => any[];
|
|
21
|
+
findFirst: (args: any) => any;
|
|
22
|
+
findFirstOrThrow: (args: any) => any;
|
|
23
|
+
create: (args: CreateArgs) => any;
|
|
24
|
+
createMany: (args: any) => {
|
|
25
|
+
count: any;
|
|
26
|
+
};
|
|
27
|
+
createManyAndReturn: (args: any) => any;
|
|
28
|
+
delete: (args: any) => any;
|
|
29
|
+
update: (args: any) => any;
|
|
30
|
+
deleteMany: (args: any) => {
|
|
31
|
+
count: number;
|
|
32
|
+
};
|
|
33
|
+
updateMany: (args: any) => {
|
|
34
|
+
count: number;
|
|
35
|
+
};
|
|
36
|
+
updateManyAndReturn: (args: any) => any[];
|
|
37
|
+
/**
|
|
38
|
+
* Upsert operation: update if exists, create if not
|
|
39
|
+
*/
|
|
40
|
+
upsert(args: any): any;
|
|
41
|
+
/**
|
|
42
|
+
* Count operation: returns the number of records matching the criteria
|
|
43
|
+
*/
|
|
44
|
+
count(args: any): number;
|
|
45
|
+
_sortFunc: (orderBy: any) => (a: any, b: any) => any;
|
|
46
|
+
_findMany: (args: any) => any[];
|
|
47
|
+
_createMany: (args: any) => any;
|
|
48
|
+
};
|
package/lib/delegate.js
CHANGED
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createDelegate = void 0;
|
|
7
|
-
const client_1 = require("@prisma/client");
|
|
8
7
|
const defaults_1 = __importDefault(require("./defaults"));
|
|
9
8
|
const errors_1 = require("./errors");
|
|
10
9
|
const fieldHelpers_1 = require("./utils/fieldHelpers");
|
|
@@ -15,10 +14,7 @@ const getWhereOnIds_1 = __importDefault(require("./utils/getWhereOnIds"));
|
|
|
15
14
|
* Creates a delegate function that handles Prisma-like operations for a specific model
|
|
16
15
|
* This is the main factory function that generates model-specific CRUD operations
|
|
17
16
|
*/
|
|
18
|
-
const createDelegate = (ref,
|
|
19
|
-
datamodel, // Prisma datamodel definition
|
|
20
|
-
caseInsensitive, // Whether string comparisons should be case insensitive
|
|
21
|
-
indexes) => {
|
|
17
|
+
const createDelegate = ({ ref, prisma, datamodel = prisma.dmmf.datamodel, caseInsensitive, indexes }) => {
|
|
22
18
|
// Initialize default value handler
|
|
23
19
|
const handleDefaults = (0, defaults_1.default)();
|
|
24
20
|
// Store many-to-many relationship data separately from the main data store
|
|
@@ -52,7 +48,7 @@ indexes) => {
|
|
|
52
48
|
return Delegate(name, otherModel);
|
|
53
49
|
};
|
|
54
50
|
// Create matching function for WHERE clauses
|
|
55
|
-
const matchFnc = (0, queryMatching_1.default)({ getFieldRelationshipWhere, getDelegateForFieldName, model, datamodel, caseInsensitive });
|
|
51
|
+
const matchFnc = (0, queryMatching_1.default)({ prisma, getFieldRelationshipWhere, getDelegateForFieldName, model, datamodel, caseInsensitive });
|
|
56
52
|
/**
|
|
57
53
|
* Sorting function that handles both simple and nested orderBy clauses
|
|
58
54
|
* Supports multiple sort criteria and nested relation sorting
|
|
@@ -71,7 +67,7 @@ indexes) => {
|
|
|
71
67
|
// Validate that only one sort field is provided
|
|
72
68
|
const keys = Object.keys(orderBy);
|
|
73
69
|
if (keys.length > 1) {
|
|
74
|
-
(0, errors_1.throwValidationError)(`Argument orderBy of needs exactly one argument, but you provided ${keys.join(" and ")}. Please choose one.`);
|
|
70
|
+
(0, errors_1.throwValidationError)(prisma, `Argument orderBy of needs exactly one argument, but you provided ${keys.join(" and ")}. Please choose one.`);
|
|
75
71
|
}
|
|
76
72
|
// Create include function to handle nested relations during sorting
|
|
77
73
|
const incl = includes({
|
|
@@ -138,7 +134,7 @@ indexes) => {
|
|
|
138
134
|
if (isCreating && (field.isUnique || field.isId)) {
|
|
139
135
|
const existing = findOne({ where: { [field.name]: inputFieldData } });
|
|
140
136
|
if (existing) {
|
|
141
|
-
(0, errors_1.throwKnownError)(`Unique constraint failed on the fields: (\`${field.name}\`)`, { code: 'P2002', meta: { target: [field.name] } });
|
|
137
|
+
(0, errors_1.throwKnownError)(prisma, `Unique constraint failed on the fields: (\`${field.name}\`)`, { code: 'P2002', meta: { target: [field.name] } });
|
|
142
138
|
}
|
|
143
139
|
}
|
|
144
140
|
// Handle relation fields (object type)
|
|
@@ -155,7 +151,7 @@ indexes) => {
|
|
|
155
151
|
where
|
|
156
152
|
})).filter(Boolean);
|
|
157
153
|
if (items.length !== inputFieldData.set.length) {
|
|
158
|
-
(0, errors_1.throwKnownError)(`An operation failed because it depends on one or more records that were required but not found. Expected ${inputFieldData.set.length} records to be connected, found only ${items.length}.`);
|
|
154
|
+
(0, errors_1.throwKnownError)(prisma, `An operation failed because it depends on one or more records that were required but not found. Expected ${inputFieldData.set.length} records to be connected, found only ${items.length}.`);
|
|
159
155
|
}
|
|
160
156
|
// Update many-to-many data store
|
|
161
157
|
const idField = model?.fields.find((f) => f.isId)?.name;
|
|
@@ -200,7 +196,7 @@ indexes) => {
|
|
|
200
196
|
return (0, shallowCompare_1.shallowCompare)(target, valueToMatch);
|
|
201
197
|
});
|
|
202
198
|
if (!matchingRow) {
|
|
203
|
-
(0, errors_1.throwKnownError)("An operation failed because it depends on one or more records that were required but not found. {cause}");
|
|
199
|
+
(0, errors_1.throwKnownError)(prisma, "An operation failed because it depends on one or more records that were required but not found. {cause}");
|
|
204
200
|
}
|
|
205
201
|
}
|
|
206
202
|
connectionValue = matchingRow[keyToGet];
|
|
@@ -525,7 +521,7 @@ indexes) => {
|
|
|
525
521
|
const findOrThrow = (args) => {
|
|
526
522
|
const found = findOne(args);
|
|
527
523
|
if (!found) {
|
|
528
|
-
(0, errors_1.throwKnownError)(`No ${prop.slice(0, 1).toUpperCase()}${prop.slice(1)} found`);
|
|
524
|
+
(0, errors_1.throwKnownError)(prisma, `No ${prop.slice(0, 1).toUpperCase()}${prop.slice(1)} found`);
|
|
529
525
|
}
|
|
530
526
|
return found;
|
|
531
527
|
};
|
|
@@ -589,7 +585,7 @@ indexes) => {
|
|
|
589
585
|
res = res.map((item) => {
|
|
590
586
|
const newItem = {};
|
|
591
587
|
Object.keys(item).forEach((key) => {
|
|
592
|
-
if (item[key] ===
|
|
588
|
+
if (item[key] === prisma.JsonNull || item[key] === prisma.DbNull) {
|
|
593
589
|
newItem[key] = null;
|
|
594
590
|
}
|
|
595
591
|
else {
|
|
@@ -840,7 +836,7 @@ indexes) => {
|
|
|
840
836
|
if (!hasMatch) {
|
|
841
837
|
if (args.skipForeignKeysChecks)
|
|
842
838
|
return;
|
|
843
|
-
(0, errors_1.throwKnownError)("An operation failed because it depends on one or more records that were required but not found. Record to update not found.", { meta: { cause: "Record to update not found." } });
|
|
839
|
+
(0, errors_1.throwKnownError)(prisma, "An operation failed because it depends on one or more records that were required but not found. Record to update not found.", { meta: { cause: "Record to update not found." } });
|
|
844
840
|
}
|
|
845
841
|
ref.data = {
|
|
846
842
|
...ref.data,
|
|
@@ -1079,7 +1075,7 @@ indexes) => {
|
|
|
1079
1075
|
delete: (args) => {
|
|
1080
1076
|
const item = findOne(args);
|
|
1081
1077
|
if (!item) {
|
|
1082
|
-
(0, errors_1.throwKnownError)("An operation failed because it depends on one or more records that were required but not found. Record to delete does not exist.", { meta: { cause: "Record to delete does not exist." } });
|
|
1078
|
+
(0, errors_1.throwKnownError)(prisma, "An operation failed because it depends on one or more records that were required but not found. Record to delete does not exist.", { meta: { cause: "Record to delete does not exist." } });
|
|
1083
1079
|
}
|
|
1084
1080
|
const deleted = deleteMany(args);
|
|
1085
1081
|
if (deleted.length) {
|
package/lib/errors.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
export declare const throwKnownError: (prisma: typeof Prisma, message: string, { code, meta }?: {
|
|
3
|
+
code?: string;
|
|
4
|
+
meta?: any;
|
|
5
|
+
}) => void;
|
|
6
|
+
export declare const throwValidationError: (prisma: typeof Prisma, message: string, { code, meta }?: {
|
|
7
|
+
code?: string;
|
|
8
|
+
meta?: any;
|
|
9
|
+
}) => void;
|
package/lib/errors.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.throwValidationError = exports.throwKnownError = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const clientVersion = client_1.Prisma.prismaVersion.client;
|
|
4
|
+
const throwPrismaError = (prisma, message, { code = "P2025", meta } = {}, errorClass = prisma.PrismaClientKnownRequestError) => {
|
|
5
|
+
const clientVersion = prisma.prismaVersion.client;
|
|
7
6
|
// PrismaClientKnownRequestError prototype changed in version 4.7.0
|
|
8
7
|
// from: constructor(message: string, code: string, clientVersion: string, meta?: any)
|
|
9
8
|
// to: constructor(message: string, { code, clientVersion, meta, batchRequestIdx }: KnownErrorParams)
|
|
@@ -26,11 +25,11 @@ const throwPrismaError = (message, { code = "P2025", meta } = {}, errorClass = c
|
|
|
26
25
|
error.meta = meta;
|
|
27
26
|
throw error;
|
|
28
27
|
};
|
|
29
|
-
const throwKnownError = (message, { code = "P2025", meta } = {}) => {
|
|
30
|
-
throwPrismaError(message, { code, meta },
|
|
28
|
+
const throwKnownError = (prisma, message, { code = "P2025", meta } = {}) => {
|
|
29
|
+
throwPrismaError(prisma, message, { code, meta }, prisma.PrismaClientKnownRequestError);
|
|
31
30
|
};
|
|
32
31
|
exports.throwKnownError = throwKnownError;
|
|
33
|
-
const throwValidationError = (message, { code = "P2025", meta } = {}) => {
|
|
34
|
-
throwPrismaError(message, { code, meta },
|
|
32
|
+
const throwValidationError = (prisma, message, { code = "P2025", meta } = {}) => {
|
|
33
|
+
throwPrismaError(prisma, message, { code, meta }, prisma.PrismaClientValidationError);
|
|
35
34
|
};
|
|
36
35
|
exports.throwValidationError = throwValidationError;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Prisma } from "@prisma/client/default";
|
|
2
|
+
import { MockPrismaOptions } from "./types";
|
|
3
|
+
export default function createPrismaClient(options?: MockPrismaOptions<typeof Prisma>): typeof Prisma & {
|
|
4
|
+
$getInternalState: () => Required<Partial<{
|
|
5
|
+
account: Partial<{
|
|
6
|
+
name: string;
|
|
7
|
+
id: number;
|
|
8
|
+
sort: number;
|
|
9
|
+
}>[];
|
|
10
|
+
user: Partial<{
|
|
11
|
+
name: string;
|
|
12
|
+
id: number;
|
|
13
|
+
sort: number;
|
|
14
|
+
accountId: number;
|
|
15
|
+
role: import(".prisma/client").$Enums.Role;
|
|
16
|
+
clicks: number;
|
|
17
|
+
deleted: boolean;
|
|
18
|
+
uniqueField: string;
|
|
19
|
+
age: number;
|
|
20
|
+
}>[];
|
|
21
|
+
stripe: Partial<{
|
|
22
|
+
id: number;
|
|
23
|
+
sort: number;
|
|
24
|
+
accountId: number;
|
|
25
|
+
customerId: string;
|
|
26
|
+
active: boolean;
|
|
27
|
+
}>[];
|
|
28
|
+
answers: Partial<{
|
|
29
|
+
id: number;
|
|
30
|
+
title: string;
|
|
31
|
+
}>[];
|
|
32
|
+
userAnswers: Partial<{
|
|
33
|
+
value: string;
|
|
34
|
+
answerId: number;
|
|
35
|
+
userId: number;
|
|
36
|
+
}>[];
|
|
37
|
+
element: Partial<{
|
|
38
|
+
value: string;
|
|
39
|
+
userId: number;
|
|
40
|
+
e_id: number;
|
|
41
|
+
json: Prisma.JsonValue;
|
|
42
|
+
}>[];
|
|
43
|
+
document: Partial<{
|
|
44
|
+
name: string;
|
|
45
|
+
id: string;
|
|
46
|
+
}>[];
|
|
47
|
+
post: Partial<{
|
|
48
|
+
id: number;
|
|
49
|
+
title: string;
|
|
50
|
+
published: boolean;
|
|
51
|
+
authorId: number;
|
|
52
|
+
updated: Date;
|
|
53
|
+
created: Date;
|
|
54
|
+
}>[];
|
|
55
|
+
pet: Partial<{
|
|
56
|
+
name: string;
|
|
57
|
+
id: number;
|
|
58
|
+
ownerId: number;
|
|
59
|
+
}>[];
|
|
60
|
+
toy: Partial<{
|
|
61
|
+
name: string;
|
|
62
|
+
id: number;
|
|
63
|
+
ownerId: number;
|
|
64
|
+
}>[];
|
|
65
|
+
transaction: Partial<{
|
|
66
|
+
id: string;
|
|
67
|
+
initiator: string;
|
|
68
|
+
}>[];
|
|
69
|
+
dbGeneratedId: Partial<{
|
|
70
|
+
id: string;
|
|
71
|
+
}>[];
|
|
72
|
+
}>>;
|
|
73
|
+
};
|
package/lib/index.js
CHANGED
|
@@ -3,128 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* Creates a mock Prisma client with the specified data and options
|
|
13
|
-
* @param data - Initial mock data for the Prisma models
|
|
14
|
-
* @param datamodel - Prisma datamodel (defaults to Prisma.dmmf.datamodel)
|
|
15
|
-
* @param mockClient - Optional existing mock client to extend
|
|
16
|
-
* @param options - Configuration options for the mock client
|
|
17
|
-
* @returns A mock Prisma client with all model methods and internal state access
|
|
18
|
-
*/
|
|
19
|
-
const createPrismaMock = (data = {}, datamodel = client_1.Prisma.dmmf.datamodel, mockClient, options = {
|
|
20
|
-
caseInsensitive: false,
|
|
21
|
-
enableIndexes: false,
|
|
22
|
-
}) => {
|
|
23
|
-
// Reference object to hold the mock data state
|
|
24
|
-
let ref = {
|
|
25
|
-
data,
|
|
26
|
-
};
|
|
27
|
-
// Initialize the mock client (either use provided one or create new)
|
|
28
|
-
let client = mockClient ? mockClient : {};
|
|
29
|
-
/**
|
|
30
|
-
* Helper function to implement mock methods consistently
|
|
31
|
-
* @param name - Method name to mock
|
|
32
|
-
* @param fnc - Function implementation
|
|
33
|
-
*/
|
|
34
|
-
const mockImplementation = (name, fnc) => {
|
|
35
|
-
if (mockClient) {
|
|
36
|
-
client[name].mockImplementation(fnc);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
client[name] = fnc;
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
// Create indexes if enabled in options
|
|
43
|
-
const indexes = (0, indexes_1.default)(!!options.enableIndexes);
|
|
44
|
-
// Determine if case-insensitive matching should be used
|
|
45
|
-
const caseInsensitive = options.caseInsensitive || false;
|
|
46
|
-
// Mock $transaction method for handling database transactions
|
|
47
|
-
mockImplementation("$transaction", async (actions) => {
|
|
48
|
-
const res = [];
|
|
49
|
-
if (Array.isArray(actions)) {
|
|
50
|
-
// Handle array of promises (parallel execution)
|
|
51
|
-
for (const action of actions) {
|
|
52
|
-
res.push(await action);
|
|
53
|
-
}
|
|
54
|
-
return res;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
// Handle callback function (serial execution with rollback on error)
|
|
58
|
-
const snapshot = (0, deepCopy_1.deepCopy)(ref.data);
|
|
59
|
-
try {
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
return await actions(client);
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
// Rollback data on error
|
|
65
|
-
ref.data = snapshot;
|
|
66
|
-
throw error;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
// Mock connection methods
|
|
71
|
-
mockImplementation("$connect", async () => { });
|
|
72
|
-
mockImplementation("$disconnect", async () => { });
|
|
73
|
-
mockImplementation("$use", async () => {
|
|
74
|
-
throw new Error("$use is not yet implemented in prisma-mock");
|
|
75
|
-
});
|
|
76
|
-
// Create delegate functions for model operations
|
|
77
|
-
const Delegate = (0, delegate_1.createDelegate)(ref, datamodel, caseInsensitive, indexes);
|
|
78
|
-
// Initialize each model in the datamodel
|
|
79
|
-
datamodel.models.forEach((model) => {
|
|
80
|
-
if (!model)
|
|
81
|
-
return;
|
|
82
|
-
// Convert model name to camelCase for consistency
|
|
83
|
-
const c = (0, fieldHelpers_1.getCamelCase)(model.name);
|
|
84
|
-
// Initialize empty array for model if it doesn't exist
|
|
85
|
-
if (!ref.data[c]) {
|
|
86
|
-
ref.data = {
|
|
87
|
-
...(ref.data || {}),
|
|
88
|
-
[c]: [],
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
// Remove multi-field IDs from the data structure
|
|
92
|
-
ref.data = (0, fieldHelpers_1.removeMultiFieldIds)(model, ref.data);
|
|
93
|
-
// Set up indexes for each field in the model
|
|
94
|
-
model.fields.forEach((field) => {
|
|
95
|
-
const isPrimaryKey = !!model.primaryKey?.fields.includes(field.name);
|
|
96
|
-
indexes.addIndexFieldIfNeeded(c, field, isPrimaryKey);
|
|
97
|
-
});
|
|
98
|
-
// Update indexes with existing data
|
|
99
|
-
ref.data[c].forEach((item) => {
|
|
100
|
-
indexes.updateItem(c, item, null);
|
|
101
|
-
});
|
|
102
|
-
// Create delegate functions for this model
|
|
103
|
-
const objs = Delegate(c, model);
|
|
104
|
-
// Bind delegate functions to the client
|
|
105
|
-
Object.keys(objs).forEach((fncName) => {
|
|
106
|
-
// Skip private methods (those starting with underscore)
|
|
107
|
-
if (fncName.indexOf("_") === 0)
|
|
108
|
-
return;
|
|
109
|
-
// Initialize model namespace if it doesn't exist
|
|
110
|
-
if (!client[c])
|
|
111
|
-
client[c] = {};
|
|
112
|
-
// Bind the delegate function to the client
|
|
113
|
-
if (mockClient) {
|
|
114
|
-
client[c][fncName].mockImplementation(async (...params) => {
|
|
115
|
-
return objs[fncName](...params);
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
client[c][fncName] = async (...params) => {
|
|
120
|
-
return objs[fncName](...params);
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
// Add method to access internal state for testing/debugging
|
|
126
|
-
client['$getInternalState'] = () => ref.data;
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
return client;
|
|
129
|
-
};
|
|
130
|
-
exports.default = createPrismaMock;
|
|
6
|
+
const default_1 = require("@prisma/client/default");
|
|
7
|
+
const client_1 = __importDefault(require("./client"));
|
|
8
|
+
function createPrismaClient(options) {
|
|
9
|
+
return (0, client_1.default)(default_1.Prisma, options);
|
|
10
|
+
}
|
|
11
|
+
exports.default = createPrismaClient;
|
package/lib/indexes.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
/**
|
|
3
|
+
* Creates an indexing system for Prisma mock data to improve query performance.
|
|
4
|
+
* This module maintains in-memory indexes on specified fields to enable fast lookups
|
|
5
|
+
* instead of scanning all records.
|
|
6
|
+
*
|
|
7
|
+
* @param isEnabled - Whether indexing is enabled. When false, all operations are no-ops.
|
|
8
|
+
* @returns Object containing methods for managing indexes and performing indexed lookups
|
|
9
|
+
*/
|
|
10
|
+
export default function createIndexes(isEnabled: boolean, prisma: typeof Prisma): {
|
|
11
|
+
addIndexFieldIfNeeded: (tableName: string, field: Prisma.DMMF.Field, isPrimary: boolean) => void;
|
|
12
|
+
getIndexedItems: (tableName: string, where: any) => any;
|
|
13
|
+
updateItem: (tableName: string, item: any, oldItem: any | null) => void;
|
|
14
|
+
deleteItemByField: (tableName: string, field: Prisma.DMMF.Field, item: any) => void;
|
|
15
|
+
};
|
package/lib/indexes.js
CHANGED
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
8
8
|
* @param isEnabled - Whether indexing is enabled. When false, all operations are no-ops.
|
|
9
9
|
* @returns Object containing methods for managing indexes and performing indexed lookups
|
|
10
10
|
*/
|
|
11
|
-
function createIndexes(isEnabled = true) {
|
|
11
|
+
function createIndexes(isEnabled = true, prisma) {
|
|
12
12
|
// Main data structures for storing indexed data
|
|
13
13
|
// items: tableName -> fieldName -> fieldValue -> array of items with that value
|
|
14
14
|
let items = {};
|
package/lib/legacy.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Prisma, PrismaClient } from "@prisma/client";
|
|
2
|
+
import { DeepMockApi, MockPrismaOptions, PrismaMockData } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use default export instead
|
|
5
|
+
*/
|
|
6
|
+
export default function createPrismaClient(data?: PrismaMockData<PrismaClient>, datamodel?: Prisma.DMMF.Datamodel, mockClient?: DeepMockApi, options?: Omit<MockPrismaOptions<typeof Prisma>, "data">): typeof Prisma & {
|
|
7
|
+
$getInternalState: () => Required<Partial<{
|
|
8
|
+
account: Partial<{
|
|
9
|
+
name: string;
|
|
10
|
+
id: number;
|
|
11
|
+
sort: number;
|
|
12
|
+
}>[];
|
|
13
|
+
user: Partial<{
|
|
14
|
+
name: string;
|
|
15
|
+
id: number;
|
|
16
|
+
sort: number;
|
|
17
|
+
accountId: number;
|
|
18
|
+
role: import(".prisma/client").$Enums.Role;
|
|
19
|
+
clicks: number;
|
|
20
|
+
deleted: boolean;
|
|
21
|
+
uniqueField: string;
|
|
22
|
+
age: number;
|
|
23
|
+
}>[];
|
|
24
|
+
stripe: Partial<{
|
|
25
|
+
id: number;
|
|
26
|
+
sort: number;
|
|
27
|
+
accountId: number;
|
|
28
|
+
customerId: string;
|
|
29
|
+
active: boolean;
|
|
30
|
+
}>[];
|
|
31
|
+
answers: Partial<{
|
|
32
|
+
id: number;
|
|
33
|
+
title: string;
|
|
34
|
+
}>[];
|
|
35
|
+
userAnswers: Partial<{
|
|
36
|
+
value: string;
|
|
37
|
+
answerId: number;
|
|
38
|
+
userId: number;
|
|
39
|
+
}>[];
|
|
40
|
+
element: Partial<{
|
|
41
|
+
value: string;
|
|
42
|
+
userId: number;
|
|
43
|
+
e_id: number;
|
|
44
|
+
json: Prisma.JsonValue;
|
|
45
|
+
}>[];
|
|
46
|
+
document: Partial<{
|
|
47
|
+
name: string;
|
|
48
|
+
id: string;
|
|
49
|
+
}>[];
|
|
50
|
+
post: Partial<{
|
|
51
|
+
id: number;
|
|
52
|
+
title: string;
|
|
53
|
+
published: boolean;
|
|
54
|
+
authorId: number;
|
|
55
|
+
updated: Date;
|
|
56
|
+
created: Date;
|
|
57
|
+
}>[];
|
|
58
|
+
pet: Partial<{
|
|
59
|
+
name: string;
|
|
60
|
+
id: number;
|
|
61
|
+
ownerId: number;
|
|
62
|
+
}>[];
|
|
63
|
+
toy: Partial<{
|
|
64
|
+
name: string;
|
|
65
|
+
id: number;
|
|
66
|
+
ownerId: number;
|
|
67
|
+
}>[];
|
|
68
|
+
transaction: Partial<{
|
|
69
|
+
id: string;
|
|
70
|
+
initiator: string;
|
|
71
|
+
}>[];
|
|
72
|
+
dbGeneratedId: Partial<{
|
|
73
|
+
id: string;
|
|
74
|
+
}>[];
|
|
75
|
+
}>>;
|
|
76
|
+
};
|
package/lib/legacy.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const client_1 = require("@prisma/client");
|
|
7
|
+
const client_2 = __importDefault(require("./client"));
|
|
8
|
+
const jest_mock_extended_1 = require("jest-mock-extended");
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use default export instead
|
|
11
|
+
*/
|
|
12
|
+
function createPrismaClient(data = {}, datamodel, mockClient, options) {
|
|
13
|
+
if (datamodel !== client_1.Prisma.dmmf.datamodel) {
|
|
14
|
+
throw new Error("datamodel !== Prisma.dmmf.datamodel is not supported, please use createPrismaMock instead");
|
|
15
|
+
}
|
|
16
|
+
let client = (0, client_2.default)(client_1.Prisma, {
|
|
17
|
+
data,
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
mockClient: mockClient || (0, jest_mock_extended_1.mockDeep)(),
|
|
20
|
+
...options
|
|
21
|
+
});
|
|
22
|
+
return client;
|
|
23
|
+
}
|
|
24
|
+
exports.default = createPrismaClient;
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
export type DeepMockApi = {
|
|
3
|
+
mockImplementation: (fnc: any) => void;
|
|
4
|
+
};
|
|
5
|
+
export type UnwrapPromise<P extends any> = P extends Promise<infer R> ? R : P;
|
|
6
|
+
export type PrismaDelegate = {
|
|
7
|
+
findUnique: (...args: Array<any>) => Promise<any>;
|
|
8
|
+
};
|
|
9
|
+
export type IsTable<S> = S extends `\$${infer fnc}` ? never : S;
|
|
10
|
+
export type IsString<S extends any> = S extends string ? S : never;
|
|
11
|
+
export type PrismaList<P extends {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
}, K extends string> = P[K] extends PrismaDelegate ? Array<Partial<UnwrapPromise<ReturnType<P[K]["findUnique"]>>>> : never;
|
|
14
|
+
export type PrismaMockData<P> = Partial<{
|
|
15
|
+
[key in IsTable<Uncapitalize<IsString<keyof P>>>]: PrismaList<P, key>;
|
|
16
|
+
}>;
|
|
17
|
+
export type Where = any;
|
|
18
|
+
export type Item = any;
|
|
19
|
+
export type Args = any;
|
|
20
|
+
export type CreateArgs = any;
|
|
21
|
+
export type MockPrismaOptions<P extends typeof Prisma> = {
|
|
22
|
+
datamodel: P["dmmf"]["datamodel"];
|
|
23
|
+
mockClient?: DeepMockApi;
|
|
24
|
+
caseInsensitive?: boolean;
|
|
25
|
+
enableIndexes?: boolean;
|
|
26
|
+
data?: any;
|
|
27
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepCopy<T>(source: T): T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepEqual(a: any, b: any): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
import { Item } from "../types";
|
|
3
|
+
export declare function isFieldDefault(f: Prisma.DMMF.FieldDefault | readonly Prisma.DMMF.FieldDefaultScalar[] | Prisma.DMMF.FieldDefaultScalar): f is Prisma.DMMF.FieldDefault;
|
|
4
|
+
export declare function isDefinedWithValue<T extends object>(v: T, key: string): boolean;
|
|
5
|
+
export declare const getCamelCase: (name: any) => any;
|
|
6
|
+
export declare const removeMultiFieldIds: (model: Prisma.DMMF.Model, data: any) => any;
|
|
7
|
+
export declare const createGetFieldRelationshipWhere: (datamodel: Omit<Prisma.DMMF.Datamodel, 'indexes'>, manyToManyData: {
|
|
8
|
+
[relationName: string]: {
|
|
9
|
+
[type: string]: any;
|
|
10
|
+
}[];
|
|
11
|
+
}) => (item: any, field: Prisma.DMMF.Field, model: Prisma.DMMF.Model) => {
|
|
12
|
+
[x: string]: any;
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function getNestedValue(keys: string[], values: any): any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function pad(s: string, size: number): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Prisma } from "@prisma/client";
|
|
2
|
+
import { createGetFieldRelationshipWhere } from "./fieldHelpers";
|
|
3
|
+
import { Where } from "../types";
|
|
4
|
+
type Props = {
|
|
5
|
+
getFieldRelationshipWhere: ReturnType<typeof createGetFieldRelationshipWhere>;
|
|
6
|
+
getDelegateForFieldName: (field: Prisma.DMMF.Field["type"]) => any;
|
|
7
|
+
model: Prisma.DMMF.Model;
|
|
8
|
+
datamodel: Omit<Prisma.DMMF.Datamodel, 'indexes'>;
|
|
9
|
+
caseInsensitive: boolean;
|
|
10
|
+
prisma: typeof Prisma;
|
|
11
|
+
};
|
|
12
|
+
export default function createMatch({ prisma, getFieldRelationshipWhere, getDelegateForFieldName, model, datamodel, caseInsensitive }: Props): (where: Where) => (item: any) => boolean;
|
|
13
|
+
export {};
|
|
@@ -3,12 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const client_1 = require("@prisma/client");
|
|
7
6
|
const deepEqual_1 = require("./deepEqual");
|
|
8
7
|
const shallowCompare_1 = require("./shallowCompare");
|
|
9
8
|
const getNestedValue_1 = __importDefault(require("./getNestedValue"));
|
|
10
9
|
const fieldHelpers_1 = require("./fieldHelpers");
|
|
11
|
-
function createMatch({ getFieldRelationshipWhere, getDelegateForFieldName, model, datamodel, caseInsensitive }) {
|
|
10
|
+
function createMatch({ prisma, getFieldRelationshipWhere, getDelegateForFieldName, model, datamodel, caseInsensitive }) {
|
|
12
11
|
const matchItem = (child, item, where) => {
|
|
13
12
|
let val = item[child];
|
|
14
13
|
const filter = where[child];
|
|
@@ -134,16 +133,16 @@ function createMatch({ getFieldRelationshipWhere, getDelegateForFieldName, model
|
|
|
134
133
|
}
|
|
135
134
|
if ("equals" in matchFilter && match) {
|
|
136
135
|
// match = deepEqual(matchFilter.equals, val)
|
|
137
|
-
if (matchFilter.equals ===
|
|
138
|
-
if (val ===
|
|
136
|
+
if (matchFilter.equals === prisma.DbNull) {
|
|
137
|
+
if (val === prisma.DbNull) {
|
|
139
138
|
}
|
|
140
|
-
match = val ===
|
|
139
|
+
match = val === prisma.DbNull;
|
|
141
140
|
}
|
|
142
|
-
else if (matchFilter.equals ===
|
|
143
|
-
match = val ===
|
|
141
|
+
else if (matchFilter.equals === prisma.AnyNull) {
|
|
142
|
+
match = val === prisma.DbNull || val === prisma.JsonNull;
|
|
144
143
|
}
|
|
145
144
|
else {
|
|
146
|
-
if (val ===
|
|
145
|
+
if (val === prisma.DbNull) {
|
|
147
146
|
match = false;
|
|
148
147
|
}
|
|
149
148
|
else {
|
|
@@ -205,11 +204,11 @@ function createMatch({ getFieldRelationshipWhere, getDelegateForFieldName, model
|
|
|
205
204
|
match = matchFilter.in.includes(val);
|
|
206
205
|
}
|
|
207
206
|
if ("not" in matchFilter && match) {
|
|
208
|
-
if (matchFilter.not ===
|
|
209
|
-
match = val !==
|
|
207
|
+
if (matchFilter.not === prisma.DbNull) {
|
|
208
|
+
match = val !== prisma.DbNull;
|
|
210
209
|
}
|
|
211
210
|
else {
|
|
212
|
-
if (val ===
|
|
211
|
+
if (val === prisma.DbNull) {
|
|
213
212
|
match = false;
|
|
214
213
|
}
|
|
215
214
|
else {
|
package/package.json
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prisma-mock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
4
|
"description": "Mock prisma for unit testing database",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/demonsters/prisma-mock.git"
|
|
9
9
|
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"prisma-mock": "./prisma-dmmf-generator.mjs"
|
|
12
|
+
},
|
|
10
13
|
"license": "MIT",
|
|
11
14
|
"types": "lib/",
|
|
12
15
|
"files": [
|
|
13
16
|
"lib/"
|
|
14
17
|
],
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./lib/index.d.ts",
|
|
21
|
+
"default": "./lib/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./legacy": {
|
|
24
|
+
"types": "./lib/legacy.d.ts",
|
|
25
|
+
"default": "./lib/legacy.js"
|
|
26
|
+
},
|
|
27
|
+
"./client": {
|
|
28
|
+
"types": "./lib/client.d.ts",
|
|
29
|
+
"default": "./lib/client.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
15
32
|
"devDependencies": {
|
|
16
33
|
"@changesets/cli": "^2.29.5",
|
|
17
34
|
"@prisma/client": "6.11.1",
|
|
@@ -42,6 +59,5 @@
|
|
|
42
59
|
},
|
|
43
60
|
"dependencies": {
|
|
44
61
|
"jest-mock-extended": "^3.0.6"
|
|
45
|
-
}
|
|
46
|
-
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
62
|
+
}
|
|
47
63
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeFile } from "fs/promises"
|
|
3
|
+
import helper from "@prisma/generator-helper"
|
|
4
|
+
|
|
5
|
+
helper.generatorHandler({
|
|
6
|
+
onManifest: () => ({
|
|
7
|
+
prettyName: "prisma-mock",
|
|
8
|
+
version: "1.0.0",
|
|
9
|
+
}),
|
|
10
|
+
onGenerate({ generator, dmmf }) {
|
|
11
|
+
if (!generator.output?.value)
|
|
12
|
+
throw new Error("Missing output path in generator configuration")
|
|
13
|
+
|
|
14
|
+
const exports = Object.entries(dmmf.datamodel).reduce(
|
|
15
|
+
(acc, [k, v], idx, arr) =>
|
|
16
|
+
acc +
|
|
17
|
+
`export const ${k} = ${JSON.stringify(v, null, 2)};\n${
|
|
18
|
+
arr[idx + 1] ? "\n" : ""
|
|
19
|
+
}`,
|
|
20
|
+
""
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
return writeFile(generator.output.value, exports, "utf8")
|
|
24
|
+
},
|
|
25
|
+
})
|