Skip to content

Commit cf7805b

Browse files
refactor: change folder names
1 parent 4426a75 commit cf7805b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+331
-18
lines changed

README.md

Lines changed: 315 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ unadapter provides a consistent interface for database operations, allowing you
4747

4848
I've seen the need for this kind of adapter system in several of my own projects and across the open-source ecosystem. In the future, better-auth might utilize unadapter, bringing this unified adapter structure to a wider range of open-source projects with full ESM support.
4949

50+
## 📦 Installation
51+
52+
```bash
53+
# Using pnpm
54+
pnpm add unadapter
55+
56+
# Using npm
57+
npm install unadapter
58+
59+
# Using yarn
60+
yarn add unadapter
61+
```
62+
63+
You'll also need to install the specific database driver or ORM you plan to use.
64+
5065
## 🧩 Available Adapters
5166

5267
<table>
@@ -92,9 +107,302 @@ I've seen the need for this kind of adapter system in several of my own projects
92107
- 🗺️ Custom field mapping
93108
- 📊 Support for various data types across different database systems
94109

95-
## 📝 License
96110

97-
See the [LICENSE](LICENSE) file for details.
111+
## 🚀 Getting Started
112+
113+
### Basic Usage
114+
115+
```typescript
116+
import { memoryAdapter } from 'unadapter/adapters/memory'
117+
118+
// Create an in-memory database for testing
119+
const db = {
120+
user: [],
121+
session: []
122+
}
123+
124+
// Initialize the adapter
125+
const adapter = memoryAdapter(db)
126+
127+
// Now you can use the adapter to perform database operations
128+
const user = await adapter.create({
129+
model: 'user',
130+
data: {
131+
name: 'John Doe',
132+
133+
emailVerified: true,
134+
createdAt: new Date(),
135+
updatedAt: new Date()
136+
}
137+
})
138+
139+
// Find the user
140+
const foundUser = await adapter.findOne({
141+
model: 'user',
142+
where: [
143+
{
144+
field: 'email',
145+
146+
}
147+
]
148+
})
149+
150+
// Update the user
151+
const updatedUser = await adapter.update({
152+
model: 'user',
153+
where: [
154+
{
155+
field: 'id',
156+
value: user.id
157+
}
158+
],
159+
update: {
160+
name: 'John Smith'
161+
}
162+
})
163+
164+
// Delete the user
165+
await adapter.delete({
166+
model: 'user',
167+
where: [
168+
{
169+
field: 'id',
170+
value: user.id
171+
}
172+
]
173+
})
174+
```
175+
176+
### Using Prisma Adapter
177+
178+
```typescript
179+
import { PrismaClient } from '@prisma/client'
180+
import { prismaAdapter } from 'unadapter/adapters/prisma-adapter'
181+
182+
const prisma = new PrismaClient()
183+
const adapter = prismaAdapter(prisma)
184+
185+
// Now you can use the same adapter interface with Prisma
186+
const user = await adapter.create({
187+
model: 'user',
188+
data: {
189+
name: 'Jane Doe',
190+
191+
emailVerified: true,
192+
createdAt: new Date(),
193+
updatedAt: new Date()
194+
}
195+
})
196+
```
197+
198+
### Using MongoDB Adapter
199+
200+
```typescript
201+
import { MongoClient } from 'mongodb'
202+
import { mongodbAdapter } from 'unadapter/adapters/mongodb'
203+
204+
const client = new MongoClient('mongodb://localhost:27017')
205+
await client.connect()
206+
const db = client.db('myDatabase')
207+
208+
const adapter = mongodbAdapter(db)
209+
210+
// Now you can use the same adapter interface with MongoDB
211+
const user = await adapter.create({
212+
model: 'user',
213+
data: {
214+
name: 'Alex Smith',
215+
216+
emailVerified: false,
217+
createdAt: new Date(),
218+
updatedAt: new Date()
219+
}
220+
})
221+
```
222+
223+
### Using Drizzle Adapter
224+
225+
```typescript
226+
import { drizzle } from 'drizzle-orm/...' // Import appropriate driver
227+
import { drizzleAdapter } from 'unadapter/adapters/drizzle'
228+
229+
const db = drizzle(/* your DB connection */)
230+
const adapter = drizzleAdapter(db, {
231+
provider: 'postgresql', // or 'mysql', 'sqlite'
232+
usePlural: false
233+
})
234+
235+
// Now you can use the same adapter interface with Drizzle
236+
const user = await adapter.create({
237+
model: 'user',
238+
data: {
239+
name: 'Taylor Swift',
240+
241+
emailVerified: true,
242+
createdAt: new Date(),
243+
updatedAt: new Date()
244+
}
245+
})
246+
```
247+
248+
### Using Kysely Adapter
249+
250+
```typescript
251+
import { Kysely } from 'kysely'
252+
import { kyselyAdapter } from 'unadapter/adapters/kysely'
253+
254+
const db = new Kysely(/* your DB connection */)
255+
const adapter = kyselyAdapter(db, {
256+
type: 'postgresql', // or 'mysql', 'sqlite', 'mssql'
257+
usePlural: false
258+
})
259+
260+
// Now you can use the same adapter interface with Kysely
261+
const user = await adapter.create({
262+
model: 'user',
263+
data: {
264+
name: 'Chris Evans',
265+
266+
emailVerified: true,
267+
createdAt: new Date(),
268+
updatedAt: new Date()
269+
}
270+
})
271+
```
272+
273+
## 🔍 API Reference
274+
275+
### Adapter Interface
276+
277+
All adapters implement the following interface:
278+
279+
```typescript
280+
interface Adapter {
281+
id: string;
282+
283+
// Create a new record
284+
create<T>({
285+
model: string,
286+
data: Omit<T, 'id'>,
287+
select?: string[]
288+
}): Promise<T>;
289+
290+
// Find a single record
291+
findOne<T>({
292+
model: string,
293+
where: Where[],
294+
select?: string[]
295+
}): Promise<T | null>;
296+
297+
// Find multiple records
298+
findMany<T>({
299+
model: string,
300+
where?: Where[],
301+
limit?: number,
302+
sortBy?: {
303+
field: string,
304+
direction: 'asc' | 'desc'
305+
},
306+
offset?: number
307+
}): Promise<T[]>;
308+
309+
// Update a record
310+
update<T>({
311+
model: string,
312+
where: Where[],
313+
update: Record<string, any>
314+
}): Promise<T | null>;
315+
316+
// Update multiple records
317+
updateMany({
318+
model: string,
319+
where: Where[],
320+
update: Record<string, any>
321+
}): Promise<number>;
322+
323+
// Delete a record
324+
delete({
325+
model: string,
326+
where: Where[]
327+
}): Promise<void>;
328+
329+
// Delete multiple records
330+
deleteMany({
331+
model: string,
332+
where: Where[]
333+
}): Promise<number>;
334+
335+
// Count records
336+
count({
337+
model: string,
338+
where?: Where[]
339+
}): Promise<number>;
340+
341+
// Additional options
342+
options?: Record<string, any>;
343+
}
344+
```
345+
346+
### Where Clause Interface
347+
348+
The `Where` interface is used for filtering records:
349+
350+
```typescript
351+
interface Where {
352+
field: string;
353+
value?: any;
354+
operator?: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'contains' | 'starts_with' | 'ends_with';
355+
connector?: 'AND' | 'OR';
356+
}
357+
```
358+
359+
### Creating Custom Adapters
360+
361+
You can create your own adapters using the `createAdapter` function:
362+
363+
```typescript
364+
import { createAdapter } from 'unadapter/adapters/create-adapter'
365+
366+
const myCustomAdapter = createAdapter({
367+
config: {
368+
adapterId: 'my-custom-adapter',
369+
adapterName: 'My Custom Adapter',
370+
usePlural: false,
371+
supportsJSON: true,
372+
supportsDates: true,
373+
supportsBooleans: true
374+
},
375+
adapter: ({ options, schema }) => {
376+
// Implement adapter methods
377+
return {
378+
async create({ model, data }) {
379+
// Your implementation here
380+
},
381+
async findOne({ model, where, select }) {
382+
// Your implementation here
383+
},
384+
async findMany({ model, where, limit, sortBy, offset }) {
385+
// Your implementation here
386+
},
387+
async update({ model, where, update }) {
388+
// Your implementation here
389+
},
390+
async updateMany({ model, where, update }) {
391+
// Your implementation here
392+
},
393+
async delete({ model, where }) {
394+
// Your implementation here
395+
},
396+
async deleteMany({ model, where }) {
397+
// Your implementation here
398+
},
399+
async count({ model, where }) {
400+
// Your implementation here
401+
}
402+
}
403+
}
404+
})
405+
```
98406

99407
## 🤝 Contributing
100408

@@ -106,6 +414,11 @@ This project draws inspiration and core concepts from:
106414

107415
- [better-auth](https://github.com/better-auth) - The original adapter architecture that inspired this project
108416

417+
## 📝 License
418+
419+
See the [LICENSE](LICENSE) file for details.
420+
421+
109422
<hr />
110423

111424
<div align="center">

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
"test:coverage": "vitest run --coverage.enabled true",
5555
"test:coverage:badges": "vitest run --coverage.enabled true && node scripts/update-badges.mjs",
5656
"update:badges": "node scripts/update-badges.mjs",
57-
"prisma:normal:push": "prisma db push --schema src/adapters/prisma-adapter/test/normal-tests/schema.prisma --accept-data-loss",
58-
"prisma:number-id:push": "prisma db push --schema src/adapters/prisma-adapter/test/number-id-tests/schema.prisma --accept-data-loss",
57+
"prisma:normal:push": "prisma db push --schema src/adapters/prisma/test/normal-tests/schema.prisma --accept-data-loss",
58+
"prisma:number-id:push": "prisma db push --schema src/adapters/prisma/test/number-id-tests/schema.prisma --accept-data-loss",
5959
"prepare": "npm run build",
6060
"prepublishOnly": "npm run test",
6161
"bumpp": "bumpp package.json",

src/adapters/create-adapter/index.ts renamed to src/adapters/create/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
CleanedWhere,
77
CreateCustomAdapter,
88
} from './types.ts'
9-
import { withApplyDefault } from '../../adapters/utils.ts'
9+
import { withApplyDefault } from '../utils.ts'
1010
import { getAuthTables } from '../../db/get-tables.ts'
1111
import { generateId as defaultGenerateId, logger } from '../../utils/index.ts'
1212
import { safeJSONParse } from '../../utils/json.ts'
File renamed without changes.

src/adapters/drizzle-adapter/drizzle-adapter.ts renamed to src/adapters/drizzle/drizzle-adapter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type {
22
SQL,
33
} from 'drizzle-orm'
44
import type { Where } from '../../types/index.ts'
5-
import type { AdapterDebugLogs } from '../create-adapter/index.ts'
5+
import type { AdapterDebugLogs } from '../create/index.ts'
66
import {
77
and,
88
asc,
@@ -17,7 +17,7 @@ import {
1717
sql,
1818
} from 'drizzle-orm'
1919
import { BetterAuthError } from '../../error/index.ts'
20-
import { createAdapter } from '../create-adapter/index.ts'
20+
import { createAdapter } from '../create/index.ts'
2121

2222
export interface DB {
2323
[key: string]: any
File renamed without changes.

src/adapters/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './create-adapter/index.ts'
1+
export * from './create/index.ts'
File renamed without changes.

src/adapters/kysely-adapter/kysely-adapter.ts renamed to src/adapters/kysely/kysely-adapter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { InsertQueryBuilder, Kysely, UpdateQueryBuilder } from 'kysely'
22
import type { Where } from '../../types/index.ts'
3-
import type { AdapterDebugLogs } from '../create-adapter/index.ts'
3+
import type { AdapterDebugLogs } from '../create/index.ts'
44
import type { KyselyDatabaseType } from './types.ts'
5-
import { createAdapter } from '../create-adapter/index.ts'
5+
import { createAdapter } from '../create/index.ts'
66

77
interface KyselyAdapterConfig {
88
/**
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)