From 432740ffd581c645ba6c552f4b55e4ec502739c5 Mon Sep 17 00:00:00 2001 From: Inesh Bose Date: Thu, 5 Feb 2026 16:28:43 +0000 Subject: [PATCH] feat(integrations): add prisma adapter --- docs/3.integrations/prisma.md | 19 +- package.json | 8 + pnpm-lock.yaml | 494 ++++++++++++++++++++++-- src/integrations/prisma/_utils.ts | 264 +++++++++++++ src/integrations/prisma/index.ts | 106 +++++ test/integrations/prisma/prisma.test.ts | 94 +++++ test/integrations/prisma/schema.prisma | 15 + 7 files changed, 970 insertions(+), 30 deletions(-) create mode 100644 src/integrations/prisma/_utils.ts create mode 100644 src/integrations/prisma/index.ts create mode 100644 test/integrations/prisma/prisma.test.ts create mode 100644 test/integrations/prisma/schema.prisma diff --git a/docs/3.integrations/prisma.md b/docs/3.integrations/prisma.md index b370bbca..cb6e214c 100644 --- a/docs/3.integrations/prisma.md +++ b/docs/3.integrations/prisma.md @@ -8,7 +8,20 @@ icon: simple-icons:prisma :read-more{to="https://www.prisma.io"} +## Example -::read-more{to="https://github.com/unjs/db0/issues/50"} -An example for this integration is planned. Follow up via [unjs/db0#50](https://github.com/unjs/db0/issues/50). -:: +Initialize your database with Prisma integration: + +```ts [database.ts] +import { createDatabase } from "db0"; +import sqlite from "db0/connectors/better-sqlite3"; +import { prisma } from "db0/integrations/prisma"; +import * as schema from "./schema"; + +// Initialize DB instance with SQLite connector +const db0 = createDatabase(sqlite({ name: 'database.sqlite' })); + +// Create Prisma Client with DB0 adapter +const adapter = prisma(db0); +export const prisma = new PrismaClient({ adapter }); +``` diff --git a/package.json b/package.json index af8793bd..e749fd23 100644 --- a/package.json +++ b/package.json @@ -46,10 +46,13 @@ "@electric-sql/pglite": "^0.3.14", "@libsql/client": "^0.15.15", "@planetscale/database": "^1.19.0", + "@prisma/client": "^7.2.0", + "@prisma/driver-adapter-utils": "^7.2.0", "@types/better-sqlite3": "^7.6.13", "@types/bun": "^1.3.2", "@types/pg": "^8.15.6", "@vitest/coverage-v8": "^4.0.12", + "async-mutex": "^0.5.0", "automd": "^0.4.2", "better-sqlite3": "^12.4.1", "changelogen": "^0.6.2", @@ -64,6 +67,7 @@ "obuild": "^0.4.2", "pg": "^8.16.3", "prettier": "^3.6.2", + "prisma": "^7.2.0", "scule": "^1.3.0", "typescript": "^5.9.3", "vitest": "^4.0.12", @@ -72,6 +76,7 @@ "peerDependencies": { "@electric-sql/pglite": "*", "@libsql/client": "*", + "@prisma/driver-adapter-utils": "*", "better-sqlite3": "*", "drizzle-orm": "*", "mysql2": "*", @@ -81,6 +86,9 @@ "@libsql/client": { "optional": true }, + "@prisma/driver-adapter-utils": { + "optional": true + }, "better-sqlite3": { "optional": true }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dff25f4d..902186f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,6 +24,12 @@ importers: '@planetscale/database': specifier: ^1.19.0 version: 1.19.0 + '@prisma/client': + specifier: ^7.2.0 + version: 7.2.0(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3) + '@prisma/driver-adapter-utils': + specifier: ^7.2.0 + version: 7.2.0 '@types/better-sqlite3': specifier: ^7.6.13 version: 7.6.13 @@ -36,15 +42,18 @@ importers: '@vitest/coverage-v8': specifier: ^4.0.12 version: 4.0.12(vitest@4.0.12(@types/node@24.10.1)(jiti@2.6.1)(yaml@2.7.1)) + async-mutex: + specifier: ^0.5.0 + version: 0.5.0 automd: specifier: ^0.4.2 - version: 0.4.2(magicast@0.5.1) + version: 0.4.2 better-sqlite3: specifier: ^12.4.1 version: 12.4.1 changelogen: specifier: ^0.6.2 - version: 0.6.2(magicast@0.5.1) + version: 0.6.2 db0: specifier: link:. version: 'link:' @@ -53,7 +62,7 @@ importers: version: 17.2.3 drizzle-orm: specifier: ^0.44.7 - version: 0.44.7(@cloudflare/workers-types@4.20251120.0)(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7) + version: 0.44.7(@cloudflare/workers-types@4.20251120.0)(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@prisma/client@7.2.0(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(sqlite3@5.1.7) eslint: specifier: ^9.39.1 version: 9.39.1(jiti@2.6.1) @@ -71,13 +80,16 @@ importers: version: 3.15.3 obuild: specifier: ^0.4.2 - version: 0.4.2(magicast@0.5.1)(typescript@5.9.3) + version: 0.4.2(typescript@5.9.3) pg: specifier: ^8.16.3 version: 8.16.3 prettier: specifier: ^3.6.2 version: 3.6.2 + prisma: + specifier: ^7.2.0 + version: 7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) scule: specifier: ^1.3.0 version: 1.3.0 @@ -95,13 +107,13 @@ importers: devDependencies: db0: specifier: latest - version: 0.3.4(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7))(mysql2@3.15.3)(sqlite3@5.1.7) + version: 0.3.4(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(react@19.2.3)(sqlite3@5.1.7))(mysql2@3.15.3)(sqlite3@5.1.7) drizzle-kit: specifier: ^0.20.14 version: 0.20.18 drizzle-orm: specifier: ^0.29.4 - version: 0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7) + version: 0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(react@19.2.3)(sqlite3@5.1.7) jiti: specifier: ^1.21.0 version: 1.21.7 @@ -137,6 +149,18 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} + '@chevrotain/cst-dts-gen@10.5.0': + resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} + + '@chevrotain/gast@10.5.0': + resolution: {integrity: sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==} + + '@chevrotain/types@10.5.0': + resolution: {integrity: sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==} + + '@chevrotain/utils@10.5.0': + resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} + '@cloudflare/kv-asset-handler@0.4.0': resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} engines: {node: '>=18.0.0'} @@ -187,9 +211,23 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@electric-sql/pglite-socket@0.0.6': + resolution: {integrity: sha512-6RjmgzphIHIBA4NrMGJsjNWK4pu+bCWJlEWlwcxFTVY3WT86dFpKwbZaGWZV6C5Rd7sCk1Z0CI76QEfukLAUXw==} + hasBin: true + peerDependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite-tools@0.2.7': + resolution: {integrity: sha512-9dAccClqxx4cZB+Ar9B+FZ5WgxDc/Xvl9DPrTWv+dYTf0YNubLzi4wHHRGRGhrJv15XwnyKcGOZAP1VXSneSUg==} + peerDependencies: + '@electric-sql/pglite': 0.3.2 + '@electric-sql/pglite@0.3.14': resolution: {integrity: sha512-3DB258dhqdsArOI1fIt7cb9RpUOgcDg5hXWVgVHAeqVQ/qxtFy605QKs4gx6mFq3jWsSPqDN8TgSEsqC3OfV9Q==} + '@electric-sql/pglite@0.3.2': + resolution: {integrity: sha512-zfWWa+V2ViDCY/cmUfRqeWY1yLto+EpxjXnZzenB1TyxsTiXaTWeZFIZw6mac52BsuQm0RjCnisjBtdBaXOI6w==} + '@emnapi/core@1.7.1': resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} @@ -1042,6 +1080,10 @@ packages: cpu: [x64] os: [win32] + '@mrleebo/prisma-ast@0.12.1': + resolution: {integrity: sha512-JwqeCQ1U3fvccttHZq7Tk0m/TMC6WcFAQZdukypW3AzlJYKYTGNVd1ANU2GuhKnv4UQuOFj3oAl0LLG/gxFN1w==} + engines: {node: '>=16'} + '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} @@ -1433,6 +1475,61 @@ packages: '@poppinss/exception@1.2.2': resolution: {integrity: sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==} + '@prisma/client-runtime-utils@7.2.0': + resolution: {integrity: sha512-dn7oB53v0tqkB0wBdMuTNFNPdEbfICEUe82Tn9FoKAhJCUkDH+fmyEp0ClciGh+9Hp2Tuu2K52kth2MTLstvmA==} + + '@prisma/client@7.2.0': + resolution: {integrity: sha512-JdLF8lWZ+LjKGKpBqyAlenxd/kXjd1Abf/xK+6vUA7R7L2Suo6AFTHFRpPSdAKCan9wzdFApsUpSa/F6+t1AtA==} + engines: {node: ^20.19 || ^22.12 || >=24.0} + peerDependencies: + prisma: '*' + typescript: '>=5.4.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + + '@prisma/config@7.2.0': + resolution: {integrity: sha512-qmvSnfQ6l/srBW1S7RZGfjTQhc44Yl3ldvU6y3pgmuLM+83SBDs6UQVgMtQuMRe9J3gGqB0RF8wER6RlXEr6jQ==} + + '@prisma/debug@6.8.2': + resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==} + + '@prisma/debug@7.2.0': + resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} + + '@prisma/dev@0.17.0': + resolution: {integrity: sha512-6sGebe5jxX+FEsQTpjHLzvOGPn6ypFQprcs3jcuIWv1Xp/5v6P/rjfdvAwTkP2iF6pDx2tCd8vGLNWcsWzImTA==} + + '@prisma/driver-adapter-utils@7.2.0': + resolution: {integrity: sha512-gzrUcbI9VmHS24Uf+0+7DNzdIw7keglJsD5m/MHxQOU68OhGVzlphQRobLiDMn8CHNA2XN8uugwKjudVtnfMVQ==} + + '@prisma/engines-version@7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3': + resolution: {integrity: sha512-KezsjCZDsbjNR7SzIiVlUsn9PnLePI7r5uxABlwL+xoerurZTfgQVbIjvjF2sVr3Uc0ZcsnREw3F84HvbggGdA==} + + '@prisma/engines@7.2.0': + resolution: {integrity: sha512-HUeOI/SvCDsHrR9QZn24cxxZcujOjcS3w1oW/XVhnSATAli5SRMOfp/WkG3TtT5rCxDA4xOnlJkW7xkho4nURA==} + + '@prisma/fetch-engine@7.2.0': + resolution: {integrity: sha512-Z5XZztJ8Ap+wovpjPD2lQKnB8nWFGNouCrglaNFjxIWAGWz0oeHXwUJRiclIoSSXN/ptcs9/behptSk8d0Yy6w==} + + '@prisma/get-platform@6.8.2': + resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + + '@prisma/get-platform@7.2.0': + resolution: {integrity: sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA==} + + '@prisma/query-plan-executor@6.18.0': + resolution: {integrity: sha512-jZ8cfzFgL0jReE1R10gT8JLHtQxjWYLiQ//wHmVYZ2rVkFHoh0DT8IXsxcKcFlfKN7ak7k6j0XMNn2xVNyr5cA==} + + '@prisma/studio-core@0.9.0': + resolution: {integrity: sha512-xA2zoR/ADu/NCSQuriBKTh6Ps4XjU0bErkEcgMfnSGh346K1VI7iWKnoq1l2DoxUqiddPHIEWwtxJ6xCHG6W7g==} + peerDependencies: + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + '@rolldown/binding-android-arm64@1.0.0-beta.51': resolution: {integrity: sha512-Ctn8FUXKWWQI9pWC61P1yumS9WjQtelNS9riHwV7oCkknPGaAry4o7eFx2KgoLMnI2BgFJYpW7Im8/zX3BuONg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1846,6 +1943,9 @@ packages: ast-v8-to-istanbul@0.3.8: resolution: {integrity: sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==} + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + automd@0.4.2: resolution: {integrity: sha512-9Gey0OG4gu2IzoLbwRj2fqyntJPbEFox/5KdOgg0zflkzq5lyOapWE324xYOvVdk9hgyjiMvDcT6XUPAIJhmag==} hasBin: true @@ -1914,6 +2014,14 @@ packages: resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} engines: {node: '>=18'} + c12@3.1.0: + resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + c12@3.3.2: resolution: {integrity: sha512-QkikB2X5voO1okL3QsES0N690Sn/K9WokXqUsDQsWy5SnYb+psYQFGA10iy1bZHj3fjISKsI67Q90gruvWWM3A==} peerDependencies: @@ -1962,6 +2070,9 @@ packages: character-reference-invalid@1.1.4: resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + chevrotain@10.5.0: + resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -2102,6 +2213,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + default-browser-id@5.0.1: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} @@ -2147,6 +2262,10 @@ packages: difflib@0.2.4: resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dotenv@17.2.3: resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} engines: {node: '>=12'} @@ -2331,12 +2450,19 @@ packages: oxc-resolver: optional: true + effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + electron-to-chromium@1.5.258: resolution: {integrity: sha512-rHUggNV5jKQ0sSdWwlaRDkFc3/rRJIVnOSe9yR4zrR07m3ZxhP4N27Hlg8VeJGGYgFTxK5NqDmWI4DSH72vIJg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} @@ -2500,6 +2626,10 @@ packages: ext@1.7.0: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2559,6 +2689,10 @@ packages: flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -2586,6 +2720,9 @@ packages: generate-function@2.3.1: resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + get-tsconfig@4.13.0: resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} @@ -2627,6 +2764,9 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + grammex@3.1.12: + resolution: {integrity: sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -2657,6 +2797,9 @@ packages: resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} engines: {node: '>= 6'} + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -2857,6 +3000,10 @@ packages: cpu: [x64, arm64, wasm32, arm] os: [darwin, linux, win32] + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2870,6 +3017,9 @@ packages: lodash.throttle@4.1.1: resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -3152,6 +3302,9 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + perfect-debounce@2.0.0: resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} @@ -3230,6 +3383,10 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + postgres@3.4.7: + resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} + engines: {node: '>=12'} + prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} engines: {node: '>=10'} @@ -3248,6 +3405,19 @@ packages: resolution: {integrity: sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw==} engines: {node: '>=20'} + prisma@7.2.0: + resolution: {integrity: sha512-jSdHWgWOgFF24+nRyyNRVBIgGDQEsMEF8KPHvhBBg3jWyR9fUAK0Nq9ThUmiGlNgq2FA7vSk/ZoCvefod+a8qg==} + engines: {node: ^20.19 || ^22.12 || >=24.0} + hasBin: true + peerDependencies: + better-sqlite3: '>=9.0.0' + typescript: '>=5.4.0' + peerDependenciesMeta: + better-sqlite3: + optional: true + typescript: + optional: true + promise-inflight@1.0.1: resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} peerDependencies: @@ -3263,6 +3433,9 @@ packages: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} @@ -3270,6 +3443,9 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3280,6 +3456,15 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + peerDependencies: + react: ^19.2.3 + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3288,6 +3473,9 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + regexp-to-ast@0.5.0: + resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} + regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true @@ -3296,6 +3484,9 @@ packages: resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true + remeda@2.21.3: + resolution: {integrity: sha512-XXrZdLA10oEOQhLLzEJEiFFSKi21REGAkHdImIb4rt/XXy8ORGXh5HCcpUOsElfPNDb+X6TA/+wkh+p2KffYmg==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -3358,6 +3549,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} @@ -3390,6 +3584,10 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} @@ -3446,6 +3644,9 @@ packages: std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} @@ -3538,6 +3739,10 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + type@2.7.3: resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} @@ -3591,6 +3796,14 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + vite@7.2.4: resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3760,6 +3973,9 @@ packages: youch@4.1.0-beta.10: resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + zeptomatch@2.0.2: + resolution: {integrity: sha512-H33jtSKf8Ijtb5BW6wua3G5DhnFjbFML36eFu+VdOoVY4HD9e7ggjqdM6639B+L87rjnR6Y+XeRzBXZdy52B/g==} + zod@3.22.3: resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} @@ -3790,6 +4006,21 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} + '@chevrotain/cst-dts-gen@10.5.0': + dependencies: + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/gast@10.5.0': + dependencies: + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/types@10.5.0': {} + + '@chevrotain/utils@10.5.0': {} + '@cloudflare/kv-asset-handler@0.4.0': dependencies: mime: 3.0.0 @@ -3821,8 +4052,18 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@electric-sql/pglite-socket@0.0.6(@electric-sql/pglite@0.3.2)': + dependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite-tools@0.2.7(@electric-sql/pglite@0.3.2)': + dependencies: + '@electric-sql/pglite': 0.3.2 + '@electric-sql/pglite@0.3.14': {} + '@electric-sql/pglite@0.3.2': {} + '@emnapi/core@1.7.1': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -4371,6 +4612,11 @@ snapshots: '@libsql/win32-x64-msvc@0.5.22': optional: true + '@mrleebo/prisma-ast@0.12.1': + dependencies: + chevrotain: 10.5.0 + lilconfig: 2.1.0 + '@napi-rs/wasm-runtime@1.0.7': dependencies: '@emnapi/core': 1.7.1 @@ -4621,6 +4867,85 @@ snapshots: '@poppinss/exception@1.2.2': {} + '@prisma/client-runtime-utils@7.2.0': {} + + '@prisma/client@7.2.0(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@prisma/client-runtime-utils': 7.2.0 + optionalDependencies: + prisma: 7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + typescript: 5.9.3 + + '@prisma/config@7.2.0': + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + '@prisma/debug@6.8.2': {} + + '@prisma/debug@7.2.0': {} + + '@prisma/dev@0.17.0(typescript@5.9.3)': + dependencies: + '@electric-sql/pglite': 0.3.2 + '@electric-sql/pglite-socket': 0.0.6(@electric-sql/pglite@0.3.2) + '@electric-sql/pglite-tools': 0.2.7(@electric-sql/pglite@0.3.2) + '@hono/node-server': 1.19.6(hono@4.10.6) + '@mrleebo/prisma-ast': 0.12.1 + '@prisma/get-platform': 6.8.2 + '@prisma/query-plan-executor': 6.18.0 + foreground-child: 3.3.1 + get-port-please: 3.1.2 + hono: 4.10.6 + http-status-codes: 2.3.0 + pathe: 2.0.3 + proper-lockfile: 4.1.2 + remeda: 2.21.3 + std-env: 3.9.0 + valibot: 1.2.0(typescript@5.9.3) + zeptomatch: 2.0.2 + transitivePeerDependencies: + - typescript + + '@prisma/driver-adapter-utils@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + + '@prisma/engines-version@7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3': {} + + '@prisma/engines@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + '@prisma/engines-version': 7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3 + '@prisma/fetch-engine': 7.2.0 + '@prisma/get-platform': 7.2.0 + + '@prisma/fetch-engine@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + '@prisma/engines-version': 7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3 + '@prisma/get-platform': 7.2.0 + + '@prisma/get-platform@6.8.2': + dependencies: + '@prisma/debug': 6.8.2 + + '@prisma/get-platform@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + + '@prisma/query-plan-executor@6.18.0': {} + + '@prisma/studio-core@0.9.0(@types/react@19.1.13)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@types/react': 19.1.13 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + '@rolldown/binding-android-arm64@1.0.0-beta.51': optional: true @@ -5010,10 +5335,14 @@ snapshots: estree-walker: 3.0.3 js-tokens: 9.0.1 - automd@0.4.2(magicast@0.5.1): + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + + automd@0.4.2: dependencies: '@parcel/watcher': 2.5.1 - c12: 3.3.2(magicast@0.5.1) + c12: 3.3.2 citty: 0.1.6 consola: 3.4.2 defu: 6.1.4 @@ -5098,7 +5427,22 @@ snapshots: dependencies: run-applescript: 7.1.0 - c12@3.3.2(magicast@0.5.1): + c12@3.1.0: + dependencies: + chokidar: 4.0.3 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 16.6.1 + exsolve: 1.0.8 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + + c12@3.3.2: dependencies: chokidar: 4.0.3 confbox: 0.2.2 @@ -5112,8 +5456,6 @@ snapshots: perfect-debounce: 2.0.0 pkg-types: 2.3.0 rc9: 2.1.2 - optionalDependencies: - magicast: 0.5.1 cacache@15.3.0: dependencies: @@ -5154,9 +5496,9 @@ snapshots: chalk@5.6.2: {} - changelogen@0.6.2(magicast@0.5.1): + changelogen@0.6.2: dependencies: - c12: 3.3.2(magicast@0.5.1) + c12: 3.3.2 confbox: 0.2.2 consola: 3.4.2 convert-gitmoji: 0.1.5 @@ -5178,6 +5520,15 @@ snapshots: character-reference-invalid@1.1.4: {} + chevrotain@10.5.0: + dependencies: + '@chevrotain/cst-dts-gen': 10.5.0 + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + '@chevrotain/utils': 10.5.0 + lodash: 4.17.21 + regexp-to-ast: 0.5.0 + chokidar@4.0.3: dependencies: readdirp: 4.1.2 @@ -5266,12 +5617,12 @@ snapshots: data-uri-to-buffer@4.0.1: {} - db0@0.3.4(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7))(mysql2@3.15.3)(sqlite3@5.1.7): + db0@0.3.4(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(better-sqlite3@12.4.1)(drizzle-orm@0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(react@19.2.3)(sqlite3@5.1.7))(mysql2@3.15.3)(sqlite3@5.1.7): optionalDependencies: '@electric-sql/pglite': 0.3.14 '@libsql/client': 0.15.15 better-sqlite3: 12.4.1 - drizzle-orm: 0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7) + drizzle-orm: 0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(react@19.2.3)(sqlite3@5.1.7) mysql2: 3.15.3 sqlite3: 5.1.7 @@ -5287,6 +5638,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge-ts@7.1.5: {} + default-browser-id@5.0.1: {} default-browser@5.4.0: @@ -5321,6 +5674,8 @@ snapshots: dependencies: heap: 0.2.7 + dotenv@16.6.1: {} + dotenv@17.2.3: {} dreamopt@0.8.0: @@ -5349,7 +5704,7 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7): + drizzle-orm@0.29.5(@cloudflare/workers-types@4.20251120.0)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(@types/react@19.1.13)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(react@19.2.3)(sqlite3@5.1.7): optionalDependencies: '@cloudflare/workers-types': 4.20251120.0 '@libsql/client': 0.15.15 @@ -5361,29 +5716,41 @@ snapshots: bun-types: 1.3.2(@types/react@19.1.13) mysql2: 3.15.3 pg: 8.16.3 + postgres: 3.4.7 + react: 19.2.3 sqlite3: 5.1.7 - drizzle-orm@0.44.7(@cloudflare/workers-types@4.20251120.0)(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(sqlite3@5.1.7): + drizzle-orm@0.44.7(@cloudflare/workers-types@4.20251120.0)(@electric-sql/pglite@0.3.14)(@libsql/client@0.15.15)(@planetscale/database@1.19.0)(@prisma/client@7.2.0(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3))(@types/better-sqlite3@7.6.13)(@types/pg@8.15.6)(better-sqlite3@12.4.1)(bun-types@1.3.2(@types/react@19.1.13))(mysql2@3.15.3)(pg@8.16.3)(postgres@3.4.7)(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(sqlite3@5.1.7): optionalDependencies: '@cloudflare/workers-types': 4.20251120.0 '@electric-sql/pglite': 0.3.14 '@libsql/client': 0.15.15 '@planetscale/database': 1.19.0 + '@prisma/client': 7.2.0(prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3) '@types/better-sqlite3': 7.6.13 '@types/pg': 8.15.6 better-sqlite3: 12.4.1 bun-types: 1.3.2(@types/react@19.1.13) mysql2: 3.15.3 pg: 8.16.3 + postgres: 3.4.7 + prisma: 7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) sqlite3: 5.1.7 dts-resolver@2.1.3: {} + effect@3.18.4: + dependencies: + '@standard-schema/spec': 1.0.0 + fast-check: 3.23.2 + electron-to-chromium@1.5.258: {} emoji-regex@8.0.0: optional: true + empathic@2.0.0: {} + encoding@0.1.13: dependencies: iconv-lite: 0.6.3 @@ -5687,6 +6054,10 @@ snapshots: dependencies: type: 2.7.3 + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -5740,6 +6111,11 @@ snapshots: flatted@3.3.3: {} + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 @@ -5771,6 +6147,8 @@ snapshots: dependencies: is-property: 1.0.2 + get-port-please@3.1.2: {} + get-tsconfig@4.13.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -5818,8 +6196,9 @@ snapshots: globals@16.5.0: {} - graceful-fs@4.2.11: - optional: true + graceful-fs@4.2.11: {} + + grammex@3.1.12: {} graphemer@1.4.0: {} @@ -5851,6 +6230,8 @@ snapshots: - supports-color optional: true + http-status-codes@2.3.0: {} + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -6032,6 +6413,8 @@ snapshots: '@libsql/linux-x64-musl': 0.5.22 '@libsql/win32-x64-msvc': 0.5.22 + lilconfig@2.1.0: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -6042,6 +6425,8 @@ snapshots: lodash.throttle@4.1.1: {} + lodash@4.17.21: {} + long@5.3.2: {} lru-cache@6.0.0: @@ -6317,9 +6702,9 @@ snapshots: obug@2.1.0: {} - obuild@0.4.2(magicast@0.5.1)(typescript@5.9.3): + obuild@0.4.2(typescript@5.9.3): dependencies: - c12: 3.3.2(magicast@0.5.1) + c12: 3.3.2 consola: 3.4.2 defu: 6.1.4 exsolve: 1.0.8 @@ -6461,6 +6846,8 @@ snapshots: pathe@2.0.3: {} + perfect-debounce@1.0.0: {} + perfect-debounce@2.0.0: {} pg-cloudflare@1.2.7: @@ -6534,6 +6921,8 @@ snapshots: dependencies: xtend: 4.0.2 + postgres@3.4.7: {} + prebuild-install@7.1.3: dependencies: detect-libc: 2.1.2 @@ -6555,6 +6944,23 @@ snapshots: pretty-bytes@7.1.0: {} + prisma@7.2.0(@types/react@19.1.13)(better-sqlite3@12.4.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3): + dependencies: + '@prisma/config': 7.2.0 + '@prisma/dev': 0.17.0(typescript@5.9.3) + '@prisma/engines': 7.2.0 + '@prisma/studio-core': 0.9.0(@types/react@19.1.13)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + mysql2: 3.15.3 + postgres: 3.4.7 + optionalDependencies: + better-sqlite3: 12.4.1 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - magicast + - react + - react-dom + promise-inflight@1.0.1: optional: true @@ -6566,6 +6972,12 @@ snapshots: retry: 0.12.0 optional: true + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + pump@3.0.3: dependencies: end-of-stream: 1.4.5 @@ -6573,6 +6985,8 @@ snapshots: punycode@2.3.1: {} + pure-rand@6.1.0: {} + queue-microtask@1.2.3: {} rc9@2.1.2: @@ -6587,6 +7001,13 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 + react-dom@19.2.3(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + + react@19.2.3: {} + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -6595,18 +7016,23 @@ snapshots: readdirp@4.1.2: {} + regexp-to-ast@0.5.0: {} + regexp-tree@0.1.27: {} regjsparser@0.12.0: dependencies: jsesc: 3.0.2 + remeda@2.21.3: + dependencies: + type-fest: 4.41.0 + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} - retry@0.12.0: - optional: true + retry@0.12.0: {} reusify@1.1.0: {} @@ -6690,6 +7116,8 @@ snapshots: safer-buffer@2.1.2: {} + scheduler@0.27.0: {} + scule@1.3.0: {} semver@7.7.3: {} @@ -6733,8 +7161,9 @@ snapshots: siginfo@2.0.0: {} - signal-exit@3.0.7: - optional: true + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} simple-concat@1.0.1: {} @@ -6802,6 +7231,8 @@ snapshots: std-env@3.10.0: {} + std-env@3.9.0: {} + stoppable@1.1.0: {} string-width@4.2.3: @@ -6886,8 +7317,7 @@ snapshots: dependencies: typescript: 5.9.3 - tslib@2.8.1: - optional: true + tslib@2.8.1: {} tunnel-agent@0.6.0: dependencies: @@ -6897,6 +7327,8 @@ snapshots: dependencies: prelude-ls: 1.2.1 + type-fest@4.41.0: {} + type@2.7.3: {} typescript-eslint@8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): @@ -6956,6 +7388,10 @@ snapshots: util-deprecate@1.0.2: {} + valibot@1.2.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(yaml@2.7.1): dependencies: esbuild: 0.25.12 @@ -7085,4 +7521,8 @@ snapshots: cookie: 1.0.2 youch-core: 0.3.3 + zeptomatch@2.0.2: + dependencies: + grammex: 3.1.12 + zod@3.22.3: {} diff --git a/src/integrations/prisma/_utils.ts b/src/integrations/prisma/_utils.ts new file mode 100644 index 00000000..f425c087 --- /dev/null +++ b/src/integrations/prisma/_utils.ts @@ -0,0 +1,264 @@ +import type { Primitive, SQLDialect } from "../../types.ts"; +import type { SqlQuery, ColumnType } from "@prisma/driver-adapter-utils"; +import { ColumnTypeEnum } from "@prisma/driver-adapter-utils"; + +export const convertDialectColumnToEnum = (dialect: SQLDialect, column: string): ColumnType | null => { + const columnType = column.toUpperCase(); + + switch (dialect) { + case 'postgresql': { + switch (columnType) { + case '': { + return null + } + case 'DECIMAL': { + return ColumnTypeEnum.Numeric + } + case 'FLOAT': { + return ColumnTypeEnum.Float + } + case 'DOUBLE': + case 'DOUBLE PRECISION': + case 'NUMERIC': + case 'REAL': { + return ColumnTypeEnum.Double + } + case 'TINYINT': + case 'SMALLINT': + case 'MEDIUMINT': + case 'INT': + case 'INTEGER': + case 'SERIAL': + case 'INT2': { + return ColumnTypeEnum.Int32 + } + case 'BIGINT': + case 'UNSIGNED BIG INT': + case 'INT8': { + return ColumnTypeEnum.Int64 + } + case 'DATETIME': + case 'TIMESTAMP': { + return ColumnTypeEnum.DateTime + } + case 'TIME': { + return ColumnTypeEnum.Time + } + case 'DATE': { + return ColumnTypeEnum.Date + } + case 'TEXT': + case 'CLOB': + case 'CHARACTER': + case 'VARCHAR': + case 'VARYING CHARACTER': + case 'NCHAR': + case 'NATIVE CHARACTER': + case 'NVARCHAR': { + return ColumnTypeEnum.Text + } + case 'BLOB': { + return ColumnTypeEnum.Bytes + } + case 'BOOLEAN': { + return ColumnTypeEnum.Boolean + } + case 'JSONB': { + return ColumnTypeEnum.Json + } + default: { + return null + } + } + } + case 'libsql': { + switch (columnType) { + case '': { + return null + } + case 'DECIMAL': { + return ColumnTypeEnum.Numeric + } + case 'FLOAT': { + return ColumnTypeEnum.Float + } + case 'DOUBLE': + case 'DOUBLE PRECISION': + case 'NUMERIC': + case 'REAL': { + return ColumnTypeEnum.Double + } + case 'TINYINT': + case 'SMALLINT': + case 'MEDIUMINT': + case 'INT': + case 'INTEGER': + case 'SERIAL': + case 'INT2': { + return ColumnTypeEnum.Int32 + } + case 'BIGINT': + case 'UNSIGNED BIG INT': + case 'INT8': { + return ColumnTypeEnum.Int64 + } + case 'DATETIME': + case 'TIMESTAMP': { + return ColumnTypeEnum.DateTime + } + case 'TIME': { + return ColumnTypeEnum.Time + } + case 'DATE': { + return ColumnTypeEnum.Date + } + case 'TEXT': + case 'CLOB': + case 'CHARACTER': + case 'VARCHAR': + case 'VARYING CHARACTER': + case 'NCHAR': + case 'NATIVE CHARACTER': + case 'NVARCHAR': { + return ColumnTypeEnum.Text + } + case 'BLOB': { + return ColumnTypeEnum.Bytes + } + case 'BOOLEAN': { + return ColumnTypeEnum.Boolean + } + case 'JSONB': { + return ColumnTypeEnum.Json + } + default: { + return null + } + } + } + case 'sqlite': { + switch (columnType) { + case '': { + return null + } + case 'DECIMAL': { + return ColumnTypeEnum.Numeric + } + case 'FLOAT': { + return ColumnTypeEnum.Float + } + case 'DOUBLE': + case 'DOUBLE PRECISION': + case 'NUMERIC': + case 'REAL': { + return ColumnTypeEnum.Double + } + case 'TINYINT': + case 'SMALLINT': + case 'MEDIUMINT': + case 'INT': + case 'INTEGER': + case 'SERIAL': + case 'INT2': { + return ColumnTypeEnum.Int32 + } + case 'BIGINT': + case 'UNSIGNED BIG INT': + case 'INT8': { + return ColumnTypeEnum.Int64 + } + case 'DATETIME': + case 'TIMESTAMP': { + return ColumnTypeEnum.DateTime + } + case 'TIME': { + return ColumnTypeEnum.Time + } + case 'DATE': { + return ColumnTypeEnum.Date + } + case 'TEXT': + case 'CLOB': + case 'CHARACTER': + case 'VARCHAR': + case 'VARYING CHARACTER': + case 'NCHAR': + case 'NATIVE CHARACTER': + case 'NVARCHAR': { + return ColumnTypeEnum.Text + } + case 'BLOB': { + return ColumnTypeEnum.Bytes + } + case 'BOOLEAN': { + return ColumnTypeEnum.Boolean + } + case 'JSONB': { + return ColumnTypeEnum.Json + } + default: { + return null + } + } + } + default: { + return null + } + } +} + +export const getQueryArgs = (query: SqlQuery, options?: Record): Array> => { + return ((query.args || []) as Primitive[]).map((arg: Primitive | Date, i) => { + const argType = query.argTypes[i] + if (arg === null) { + return null + } + + if (typeof arg === 'string' && argType.scalarType === 'int') { + return Number.parseInt(arg) + } + + if (typeof arg === 'string' && argType.scalarType === 'float') { + return Number.parseFloat(arg) + } + + if (typeof arg === 'string' && argType.scalarType === 'decimal') { + // This can lose precision, but SQLite does not have a native decimal type. + // This is how we have historically handled it. + return Number.parseFloat(arg) + } + + if (typeof arg === 'string' && argType.scalarType === 'bigint') { + return BigInt(arg) + } + + if (typeof arg === 'boolean') { + return arg ? 1 : 0 // SQLite does not natively support booleans + } + + if (typeof arg === 'string' && argType.scalarType === 'datetime') { + arg = new Date(arg) + } + + if (arg instanceof Date) { + const format = options?.timestampFormat ?? 'iso8601' + switch (format) { + case 'unixepoch-ms': { + return arg.getTime() + } + case 'iso8601': { + return arg.toISOString().replace('Z', '+00:00') + } + default: { + throw new Error(`Unknown timestamp format: ${format}`) + } + } + } + + if (typeof arg === 'string' && argType.scalarType === 'bytes') { + return Buffer.from(arg, 'base64') + } + + return arg + }) +} diff --git a/src/integrations/prisma/index.ts b/src/integrations/prisma/index.ts new file mode 100644 index 00000000..aac1f449 --- /dev/null +++ b/src/integrations/prisma/index.ts @@ -0,0 +1,106 @@ +import type { Database, SQLDialect, Primitive } from "../../types.ts"; +import type { + IsolationLevel, + SqlDriverAdapter, + SqlQuery, + SqlResultSet, + Transaction, + Provider, + SqlDriverAdapterFactory, +} from "@prisma/driver-adapter-utils"; +import { DriverAdapterError } from "@prisma/driver-adapter-utils"; +import { Mutex } from "async-mutex"; + +const adapterName = "db0"; +const getProviderFromDialect = (dialect: SQLDialect): Provider => { + switch (dialect) { + case "postgresql": { + return "postgres"; + } + case "libsql": { + return "sqlite"; + } + default: { + return dialect; + } + } +}; + +export function prisma(db: Database): SqlDriverAdapterFactory { + const mutex = new Mutex(); + const provider = getProviderFromDialect(db.dialect); + + const adapter: Omit = { + adapterName, + provider, + + executeScript: async function (script: string): Promise { + await db.exec(script); + }, + + dispose: db.dispose, + + queryRaw: async function (params: SqlQuery): Promise { + const stmt = db.prepare(params.sql); + const args = (params.args || []) as Primitive[]; + + return stmt.all(...args).then((result) => { + const columnNames = Object.keys((result as any)[0] || {}); + const rows = (result as any[]).map((row) => + columnNames.map((col) => row[col]), + ); + const columnTypes = columnNames.map(() => 7 as const); + return { columnNames, columnTypes, rows }; + }); + }, + + executeRaw: async function (params: SqlQuery) { + const stmt = db.prepare(params.sql); + const args = (params.args || []) as Primitive[]; + + return stmt + .run(...args) + .then((res) => (res as any).changes || 0); + } + } + + return { + adapterName, + provider, + connect: function (): Promise { + return Promise.resolve({ + ...adapter, + + startTransaction: async function ( + isolationLevel?: IsolationLevel, + ): Promise { + if (provider === 'sqlite' && isolationLevel && isolationLevel !== 'SERIALIZABLE') { + throw new DriverAdapterError({ + kind: 'InvalidIsolationLevel', + level: isolationLevel, + }) + } + + const release = await mutex.acquire(); + const options = { usePhantomQuery: false }; + + db.exec("BEGIN"); + + return { + ...adapter, + options, + + commit: async function () { + release(); + return; + }, + rollback: async function () { + release(); + return; + }, + }; + }, + }); + }, + }; +} diff --git a/test/integrations/prisma/prisma.test.ts b/test/integrations/prisma/prisma.test.ts new file mode 100644 index 00000000..9a35c71a --- /dev/null +++ b/test/integrations/prisma/prisma.test.ts @@ -0,0 +1,94 @@ +import { afterAll, beforeAll, describe, expect, it } from "vitest"; +import { existsSync } from "node:fs"; +import { resolve } from "node:path"; + +import { Database, createDatabase } from "../../../src"; +import { prisma } from "../../../src/integrations/prisma"; +import type { PrismaClient } from "./dist/client"; + +import sqliteConnector from "../../../src/connectors/better-sqlite3"; +import pgConnector from "../../../src/connectors/postgresql"; + +const outputDir = resolve(import.meta.dirname, "./dist"); + +const prismaClientGenerated = existsSync(outputDir); + +describe.runIf(prismaClientGenerated)( + "integrations: prisma: better-sqlite3", + () => { + let prismaClient: PrismaClient; + let db: Database; + + beforeAll(async () => { + db = createDatabase(sqliteConnector({})); + const { PrismaClient } = await import("./dist/client"); + prismaClient = new PrismaClient({ adapter: prisma(db) }); + await db.sql`DROP TABLE IF EXISTS users`; + await db.sql`create table if not exists users ( + id integer primary key autoincrement, + name text + )`; + }); + + it("insert", async () => { + const res = await prismaClient.user.createManyAndReturn({ + data: { name: "John Doe" }, + }); + + expect(res.length).toBe(1); + expect(res[0].name).toBe("John Doe"); + }); + + it("select", async () => { + const res = await prismaClient.user.findMany(); + + expect(res.length).toBe(1); + expect(res[0].name).toBe("John Doe"); + }); + + afterAll(async () => { + await db.sql`DROP TABLE IF EXISTS users`; + }); + }, +); + +describe.runIf(prismaClientGenerated && process.env.POSTGRESQL_URL)( + "integrations: prisma: postgres", + () => { + let prismaClient: PrismaClient; + let db: Database>; + + beforeAll(async () => { + db = createDatabase( + pgConnector({ + url: process.env.POSTGRESQL_URL as string, + }), + ); + + const { PrismaClient } = await import("./dist/client"); + prismaClient = new PrismaClient({ adapter: prisma(db) }); + await db.sql`DROP TABLE IF EXISTS users`; + await db.sql`CREATE TABLE users ("id" INTEGER PRIMARY KEY, "name" TEXT)`; + }); + + it("insert", async () => { + const res = await prismaClient.user.createManyAndReturn({ + data: { id: 1, name: "John Doe" }, + }); + + expect(res.length).toBe(1); + expect(res[0].name).toBe("John Doe"); + }); + + it("select", async () => { + const res = await prismaClient.user.findMany(); + + expect(res.length).toBe(1); + expect(res[0].name).toBe("John Doe"); + }); + + afterAll(async () => { + await db.sql`DROP TABLE IF EXISTS users`; + }); + }, +); diff --git a/test/integrations/prisma/schema.prisma b/test/integrations/prisma/schema.prisma new file mode 100644 index 00000000..626a03fc --- /dev/null +++ b/test/integrations/prisma/schema.prisma @@ -0,0 +1,15 @@ +datasource db { + provider = "sqlite" +} + +generator client { + provider = "prisma-client" + output = "./dist" +} + +model User { + id Int @id @default(autoincrement()) + name String + + @@map("users") +}