@pkgverse/prismock 2.0.1-beta.4 → 2.0.1-beta.6

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
@@ -10,9 +10,9 @@ I haven't personally tested the CJS functionality.
10
10
 
11
11
  ---
12
12
 
13
- This is a mock for `PrismaClient`. It actually reads your `schema.prisma` and generate models based on it.
13
+ This is a mock for `PrismaClient`. It actually reads your `schema.prisma` and generate models based on it. For postgres it also offers a true in-memory database client by using PgLite.
14
14
 
15
- It perfectly simulates Prisma's API and store everything in-memory for fast, isolated, and retry-able unit tests.
15
+ It perfectly simulates Prisma's API and stores everything in-memory for fast, isolated, and retry-able unit tests.
16
16
 
17
17
  It's heavily tested, by comparing the mocked query results with real results from prisma. Tested environments include `MySQL`, `PostgreSQL` and `MongoDB`.
18
18
 
@@ -34,14 +34,24 @@ npm
34
34
  $ npm add --save-dev @pkgverse/prismock
35
35
  ```
36
36
 
37
+ bun
38
+
39
+ ```
40
+ $ bun add -E -D @pkgverse/prismock
41
+ ```
42
+
37
43
  # Usage
38
44
 
39
45
  ```ts
40
46
  import { Prisma, PrismaClient } from "${your_prisma_client_directory}"
41
- import { createPrismockClient } from 'prismock';
47
+ import { getClient } from 'prismock';
42
48
 
43
49
  // Pass in the Prisma namespace, and manually define the type of your prisma client
44
- let mockedClient = await createPrismockClient<PrismaClient>(Prisma)
50
+ let mockedClient = await getClient({
51
+ prismaModule: Prisma,
52
+ prismaClient: PrismaClient,
53
+ schemaPath: "prisma/schema.prisma",
54
+ })
45
55
 
46
56
  // Optionally apply your client extensions to the client
47
57
  mockedClient = applyExtensions(mockedClient)
@@ -49,6 +59,33 @@ mockedClient = applyExtensions(mockedClient)
49
59
 
50
60
  That's it, prisma will be mocked in all your tests (tested with ViTest)
51
61
 
62
+ ## Using PgLite (experimental)
63
+
64
+ If you're using prisma with postgres, you can optionally choose to have the mocked prisma client use PgLite for more 'true-to-life' tests.
65
+
66
+ ```ts
67
+ import { Prisma, PrismaClient } from "${your_prisma_client_directory}"
68
+ import { getClient } from 'prismock';
69
+
70
+ // Pass in the Prisma namespace, and manually define the type of your prisma client
71
+ let mockedClient = await getClient({
72
+ prismaModule: Prisma,
73
+ prismaClient: PrismaClient,
74
+ schemaPath: "prisma/schema.prisma",
75
+ usePgLite: true,
76
+ })
77
+
78
+ // Optionally apply your client extensions to the client
79
+ mockedClient = applyExtensions(mockedClient)
80
+ ```
81
+
82
+ The prisma client will execute everything as it normally would purely in-memory.
83
+
84
+ ⚠️ ### NOTE ⚠️
85
+ The PgLite database is initialized by executing your migration history. It's currently assumed that the migrations directory is in the same directory
86
+ as the schema file, i.e. the directory of the file path you pass in as `schemaPath`. If that's not the case, this will most likely fail.
87
+
88
+
52
89
  ## PrismaClient
53
90
 
54
91
  You can mock the PrismaClient directly in your test, or setupTests ([Example](https://github.com/JQuezada0/prismock/blob/beta/src/__tests__/client/example-prismock.test.ts)):
@@ -62,7 +99,11 @@ vi.mock('@prisma/client', async () => {
62
99
 
63
100
  return {
64
101
  ...actual,
65
- PrismaClient: await actualPrismock.createPrismockClass(actual.Prisma),
102
+ PrismaClient: await actualPrismock.getClientClass({
103
+ prismaModule: actual.Prisma,
104
+ prismaClient: actual.PrismaClient,
105
+ schemaPath: "prisma/schema.prisma",
106
+ }),
66
107
  };
67
108
  });
68
109
  ```
@@ -72,10 +113,14 @@ vi.mock('@prisma/client', async () => {
72
113
  You can instantiate a `PrismockClient` directly and use it in your test, or pass it to a test version of your app.
73
114
 
74
115
  ```ts
75
- import { Prisma } from '${your_prisma_client_directory}';
76
- import { createPrismockClient } from 'prismock';
116
+ import { Prisma, PrismaClient } from '${your_prisma_client_directory}';
117
+ import { getClient } from 'prismock';
77
118
 
78
- const client = await createPrismockClient(Prisma);
119
+ const client = await getClient({
120
+ prismaModule: Prisma,
121
+ PrismaClient,
122
+ schemaPath: "prisma/schema.prisma",
123
+ });
79
124
  ```
80
125
 
81
126
  Then, you will be able to write your tests as if your app was using an in-memory Prisma client.
@@ -89,12 +134,12 @@ See [use with decimal.js](https://github.com/morintd/prismock/blob/master/docs/u
89
134
  Two additional functions are returned compared to the PrismaClient, `getData`, and `reset`.
90
135
 
91
136
  ```ts
92
- const prismock = new PrismockClient();
137
+ const prismock = await getClient({...});
93
138
  prismock.getData(); // { user: [] }
94
139
  ```
95
140
 
96
141
  ```ts
97
- const prismock = new PrismockClient();
142
+ const prismock = await getClient({...});
98
143
  prismock.reset(); // State of prismock back to its original
99
144
  ```
100
145
 
package/dist/index.mjs CHANGED
@@ -4756,7 +4756,7 @@ function updateMany(args, current, delegates, onChange) {
4756
4756
  return toUpdate;
4757
4757
  }
4758
4758
  // node_modules/@prisma/client/package.json
4759
- var version = "6.10.0";
4759
+ var version = "6.12.0";
4760
4760
 
4761
4761
  // src/lib/delegate.ts
4762
4762
  import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
@@ -4869,6 +4869,10 @@ function generateDelegate(model, data, name, properties, delegates, onChange) {
4869
4869
  return delegate;
4870
4870
  }
4871
4871
 
4872
+ // src/lib/client.ts
4873
+ import * as path2 from "path";
4874
+ import * as fs from "fs";
4875
+
4872
4876
  // src/lib/extensions/model.ts
4873
4877
  function applyModelExtensions(client, extensions) {
4874
4878
  if (typeof extensions === "function") {
@@ -5155,9 +5159,6 @@ function applyExtensions(client, extensions) {
5155
5159
  return modelExtended;
5156
5160
  }
5157
5161
 
5158
- // src/lib/client.ts
5159
- import { execSync } from "child_process";
5160
-
5161
5162
  // src/lib/dmmf.ts
5162
5163
  import * as path from "path";
5163
5164
  var PrismaInternals = await import("@prisma/internals");
@@ -5254,10 +5255,12 @@ function generateClient(delegates, getData, setData) {
5254
5255
  };
5255
5256
  }
5256
5257
  function getPgLitePrismockData(options) {
5257
- const rawSql = execSync(`bun prisma migrate diff --from-empty --to-schema-datamodel=${options.schemaPath} --script`, {
5258
- encoding: "utf-8"
5258
+ const schemaPathDir = path2.dirname(options.schemaPath);
5259
+ const migrationsPath = path2.join(schemaPathDir, "migrations");
5260
+ const migrationsDirContents = fs.readdirSync(migrationsPath, {
5261
+ withFileTypes: true
5259
5262
  });
5260
- const sql = rawSql.replace(/((?:CONSTRAINT\s+"[^"]+"\s+)?FOREIGN KEY\s*\([^)]*\)\s*REFERENCES\s+[^\s(]+\s*\([^)]*\))(?![\s\S]*?\bDEFERRABLE\b)/gi, `$1 DEFERRABLE INITIALLY DEFERRED`);
5263
+ const migrationsDir = migrationsDirContents.filter((file) => file.isDirectory());
5261
5264
  const connectionPromise = options.adapter.connect();
5262
5265
  const reset = async () => {
5263
5266
  const connection = await connectionPromise;
@@ -5265,7 +5268,11 @@ function getPgLitePrismockData(options) {
5265
5268
  DROP SCHEMA public CASCADE;
5266
5269
  CREATE SCHEMA public;
5267
5270
  `);
5268
- await connection.executeScript(sql);
5271
+ for (const migration of migrationsDir) {
5272
+ const migrationPath = path2.join(migrationsPath, migration.name, "migration.sql");
5273
+ const migrationContent = await fs.promises.readFile(migrationPath, "utf8");
5274
+ await connection.executeScript(migrationContent);
5275
+ }
5269
5276
  };
5270
5277
  const getData = async () => {
5271
5278
  const data = {};
@@ -5308,7 +5315,10 @@ async function getClient(options) {
5308
5315
  if (options.usePgLite) {
5309
5316
  const { PGlite } = await import("@electric-sql/pglite");
5310
5317
  const { PrismaPGlite } = await import("pglite-prisma-adapter");
5311
- const pglite = new PGlite("memory://");
5318
+ const pglite = new PGlite("memory://", {
5319
+ relaxedDurability: true,
5320
+ initialMemory: 1073741824
5321
+ });
5312
5322
  const adapter = new PrismaPGlite(pglite);
5313
5323
  const prisma2 = new options.prismaClient({
5314
5324
  adapter
@@ -5337,9 +5347,13 @@ async function getClientClass(options) {
5337
5347
  datamodel;
5338
5348
  prismockData;
5339
5349
  constructor(...args) {
5340
- const pglite = new PGlite("memory://");
5350
+ const pglite = new PGlite("memory://", {
5351
+ relaxedDurability: true,
5352
+ initialMemory: 1073741824
5353
+ });
5341
5354
  const adapter = new PrismaPGlite(pglite);
5342
- const prismaOptions = args[0] ?? {};
5355
+ const inputPrismaOptions = args[0] ?? {};
5356
+ const { datasourceUrl: _datasourceUrl, ...prismaOptions } = inputPrismaOptions;
5343
5357
  super({ ...prismaOptions, adapter });
5344
5358
  this.pglite = pglite;
5345
5359
  this.adapter = adapter;
@@ -1,8 +1,11 @@
1
- import type { Prisma, PrismaClient } from "@prisma/client";
1
+ import type { PrismaClient } from "@prisma/client";
2
+ import type { DMMF } from "@prisma/generator-helper";
2
3
  import type * as runtime from "@prisma/client/runtime/library";
3
4
  import type { Delegate } from "./delegate";
4
5
  import { Data } from "./prismock";
5
6
  import { type ExtensionsDefinition } from "./extensions";
7
+ import type { PGlite } from "@electric-sql/pglite";
8
+ import type { PrismaPGlite } from "pglite-prisma-adapter";
6
9
  type GetData = () => Promise<Data>;
7
10
  type SetData = (data: Data) => Promise<void>;
8
11
  export interface PrismockData {
@@ -20,7 +23,7 @@ export declare class Prismock<PC = PrismaClient> {
20
23
  __prismaModule: PrismaModule<PC>;
21
24
  protected constructor(prismaModule: PrismaModule<PC>);
22
25
  static create<PC = PrismaClient>(prismaModule: PrismaModule<PC>): Promise<PrismockClientType<PC>>;
23
- static createDefault(): Promise<PrismaClient<Prisma.PrismaClientOptions, never, runtime.DefaultArgs> & PrismockData>;
26
+ static createDefault(): Promise<PrismaClient<import(".prisma").Prisma.PrismaClientOptions, never, runtime.DefaultArgs> & PrismockData>;
24
27
  reset(): void;
25
28
  private generate;
26
29
  $connect(): Promise<void>;
@@ -31,13 +34,24 @@ export declare class Prismock<PC = PrismaClient> {
31
34
  $executeRawUnsafe(): Promise<number>;
32
35
  $queryRaw(): Promise<never[]>;
33
36
  $queryRawUnsafe(): Promise<never[]>;
34
- $extends(extensionDefs: ExtensionsDefinition): PrismaClient<Prisma.PrismaClientOptions, never, runtime.DefaultArgs>;
37
+ $extends(extensionDefs: ExtensionsDefinition): PrismaClient<import(".prisma").Prisma.PrismaClientOptions, never, runtime.DefaultArgs>;
35
38
  $transaction(args: any): Promise<any>;
36
39
  }
37
40
  export declare function generateClient<T = PrismaClient>(delegates: Record<string, Delegate>, getData: GetData, setData: SetData): PrismockClientType<T>;
38
41
  export type PrismaModule<PC = PrismaClient> = {
39
42
  dmmf: runtime.BaseDMMF;
40
43
  };
44
+ export declare function getPgLitePrismockData(options: {
45
+ schemaPath: string;
46
+ pglite: InstanceType<typeof PGlite>;
47
+ adapter: InstanceType<typeof PrismaPGlite>;
48
+ datamodel: DMMF.Document;
49
+ prismaClient: Record<string, any>;
50
+ }): {
51
+ reset: () => Promise<void>;
52
+ getData: () => Promise<Data>;
53
+ setData: (data: Data) => Promise<void>;
54
+ };
41
55
  type GetClientOptions<PrismaClientClassType extends new (...args: any[]) => any> = {
42
56
  prismaModule: PrismaModule<InstanceType<PrismaClientClassType>>;
43
57
  prismaClient: PrismaClientClassType;
@@ -55,8 +69,8 @@ type GetClientClassOptions<PrismaClientClassType extends new (...args: any[]) =>
55
69
  };
56
70
  type PrismaClientClassMocked<PrismaClientType extends new (...args: any[]) => any> = PrismaClientType extends new (...args: infer Args) => infer Instance ? (new (...args: Args) => Instance & PrismockData) & PrismaClientType : never;
57
71
  export declare function getClientClass<PrismaClientType extends new (...args: any[]) => any>(options: GetClientClassOptions<PrismaClientType>): Promise<PrismaClientClassMocked<PrismaClientType>>;
58
- export declare function getDefaultClient(): Promise<PrismockClientType<PrismaClient<Prisma.PrismaClientOptions, unknown, runtime.InternalArgs>>>;
59
- export declare function getDefaultClientClass(): Promise<(new (optionsArg?: Prisma.Subset<Prisma.PrismaClientOptions, Prisma.PrismaClientOptions> | undefined) => PrismaClient<Prisma.PrismaClientOptions, unknown, runtime.InternalArgs> & PrismockData) & typeof import(".prisma").PrismaClient>;
72
+ export declare function getDefaultClient(): Promise<PrismockClientType<PrismaClient<import(".prisma").Prisma.PrismaClientOptions, unknown, runtime.InternalArgs>>>;
73
+ export declare function getDefaultClientClass(): Promise<(new (optionsArg?: import(".prisma").Prisma.Subset<import(".prisma").Prisma.PrismaClientOptions, import(".prisma").Prisma.PrismaClientOptions> | undefined) => PrismaClient<import(".prisma").Prisma.PrismaClientOptions, unknown, runtime.InternalArgs> & PrismockData) & typeof import(".prisma").PrismaClient>;
60
74
  /**
61
75
  * For backwards compatibility
62
76
  */
@@ -1,5 +1,5 @@
1
1
  import { PrismaClient } from '@prisma/client';
2
- import { DMMF } from '@prisma/generator-helper';
2
+ import { DMMF, type ActiveConnectorType } from '@prisma/generator-helper';
3
3
  import type { Generator } from '@prisma/internals';
4
4
  import { Delegate, DelegateProperties, Item } from './delegate';
5
5
  import { PrismockClientType } from './client';
@@ -12,8 +12,8 @@ type OptionsSync = {
12
12
  export type Data = Record<string, Item[]>;
13
13
  export type Properties = Record<string, DelegateProperties>;
14
14
  export type Delegates = Record<string, Delegate>;
15
- export declare function fetchProvider(schemaPath?: string): Promise<string>;
16
- export declare function getProvider(generator: Generator): import("@prisma/generator").ActiveConnectorType | undefined;
15
+ export declare function fetchProvider(schemaPath?: string): Promise<ActiveConnectorType>;
16
+ export declare function getProvider(generator: Generator): ActiveConnectorType | undefined;
17
17
  export declare function generatePrismock<T = PrismaClient>(options?: Options): Promise<PrismockClientType<T>>;
18
18
  export declare function generatePrismockSync<T = PrismockClientType>(options: OptionsSync): PrismockClientType<T>;
19
19
  export declare function generateDelegates(options: OptionsSync): {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pkgverse/prismock",
3
- "version": "2.0.1-beta.4",
3
+ "version": "2.0.1-beta.6",
4
4
  "description": "A mock for PrismaClient, dedicated to unit testing.",
5
5
  "repository": {
6
6
  "url": "https://github.com/JQuezada0/prismock"
@@ -43,7 +43,7 @@
43
43
  "devDependencies": {
44
44
  "@commitlint/cli": "19.8.1",
45
45
  "@commitlint/config-conventional": "19.8.1",
46
- "@prisma/client": "6.10.0",
46
+ "@prisma/client": "6.12.0",
47
47
  "@semantic-release/changelog": "6.0.3",
48
48
  "@semantic-release/commit-analyzer": "13.0.1",
49
49
  "@semantic-release/git": "10.0.1",
@@ -52,6 +52,7 @@
52
52
  "@semantic-release/release-notes-generator": "14.1.0",
53
53
  "@types/bun": "1.3.3",
54
54
  "@types/node": "22.18.1",
55
+ "@types/pg": "8.15.6",
55
56
  "@typescript-eslint/eslint-plugin": "8.43.0",
56
57
  "@typescript-eslint/parser": "8.43.0",
57
58
  "@typescript/native-preview": "7.0.0-dev.20250910.1",
@@ -68,21 +69,39 @@
68
69
  "eslint-plugin-promise": "7.2.1",
69
70
  "eslint-plugin-react": "7.37.5",
70
71
  "eslint-plugin-testing-library": "7.6.8",
72
+ "eslint-plugin-unused-imports": "4.3.0",
71
73
  "fp-ts": "2.16.11",
72
74
  "fs-jetpack": "5.1.0",
73
75
  "husky": "9.1.7",
74
76
  "lint-staged": "16.1.6",
77
+ "mongodb": "7.0.0",
78
+ "mysql": "2.18.1",
79
+ "mysql2": "3.15.3",
80
+ "pg": "8.16.3",
75
81
  "prettier": "2.8.8",
76
- "prisma": "6.10.0",
82
+ "prisma": "6.12.0",
77
83
  "release-it": "19.0.6",
78
84
  "semantic-release": "24.2.7",
85
+ "slugify": "1.6.6",
79
86
  "ts-node": "10.9.2",
80
87
  "ts-toolbelt": "9.6.0",
81
88
  "tsx": "4.20.6",
82
89
  "typescript-eslint": "8.46.0",
83
- "vitest": "4.0.13",
90
+ "vitest": "4.0.15",
84
91
  "vitest-mock-extended": "3.1.0"
85
92
  },
93
+ "dependencies": {
94
+ "@paralleldrive/cuid2": "2.2.2",
95
+ "@prisma/generator-helper": "6.12.0",
96
+ "@prisma/internals": "6.12.0",
97
+ "@electric-sql/pglite": "0.3.14",
98
+ "pglite-prisma-adapter": "0.6.1",
99
+ "bson": "6.10.4"
100
+ },
101
+ "peerDependencies": {
102
+ "@prisma/client": ">= 6.10.0",
103
+ "prisma": ">= 6.10.0"
104
+ },
86
105
  "files": [
87
106
  "dist/**/*.{cjs,mjs,d.ts}",
88
107
  "!**/*.spec.*",
@@ -98,17 +117,5 @@
98
117
  "*.{ts,tsx}": [
99
118
  "eslint --fix"
100
119
  ]
101
- },
102
- "dependencies": {
103
- "@paralleldrive/cuid2": "2.2.2",
104
- "@prisma/generator-helper": "6.10.0",
105
- "@prisma/internals": "6.10.0",
106
- "@electric-sql/pglite": "0.3.14",
107
- "pglite-prisma-adapter": "0.6.1",
108
- "bson": "6.10.4"
109
- },
110
- "peerDependencies": {
111
- "@prisma/client": ">= 6.10.0",
112
- "prisma": ">= 6.10.0"
113
120
  }
114
121
  }