Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ Network Trash Folder
Temporary Items
.apdisk

### Turborepo
.turbo

### Build output
dist/

### VisualStudioCode template
.vscode/*
!.vscode/settings.json
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
| Package | Description | npm |
|---------|-------------|-----|
| [`@please-auth/waitlist`](./packages/waitlist) | Invite 기반 대기자 명단(waitlist) 플러그인 | [![npm](https://img.shields.io/npm/v/@please-auth/waitlist)](https://www.npmjs.com/package/@please-auth/waitlist) |
| [`@please-auth/firestore`](./packages/firestore) | Cloud Firestore 어댑터 | - |

## Quick Start

Expand Down Expand Up @@ -48,6 +49,18 @@ await auth.waitlist.join({ email: "user@example.com" });
const { data } = await auth.waitlist.status({ token: "lookup-token" });
```

### Firestore Adapter

```typescript
import { betterAuth } from "better-auth";
import { firestoreAdapter } from "@please-auth/firestore";
import { getFirestore } from "firebase-admin/firestore";

const auth = betterAuth({
database: firestoreAdapter({ db: getFirestore() }),
});
```

## Development

### 사전 요구사항
Expand All @@ -60,6 +73,28 @@ const { data } = await auth.waitlist.status({ token: "lookup-token" });
```bash
mise trust
mise install
bun install
```

### 개발

```bash
# 전체 빌드
bun run build

# 전체 타입 체크
bun run check-types

# 전체 테스트
bun run test

# 특정 패키지만
npx turbo run build --filter=@please-auth/firestore
```

### Git Hooks 설정

```bash
mise run setup
```

Expand Down
Empty file added apps/.gitkeep
Empty file.
1,887 changes: 1,788 additions & 99 deletions bun.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['@commitlint/config-conventional', '@commitlint/config-workspace-scopes'],
rules: {
'subject-case': [0],
},
};
5 changes: 5 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import antfu from "@antfu/eslint-config";

export default antfu({
typescript: true,
});
37 changes: 19 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
{
"name": "template",
"version": "1.0.0",
"description": "",
"main": "index.js",
"name": "better-auth",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build": "turbo run build",
"dev": "turbo run dev",
"test": "turbo run test",
"lint": "turbo run lint",
"check-types": "turbo run check-types",
"clean": "turbo run clean"
},
"repository": {
"type": "git",
"url": "git+https://github.com/chatbot-pf/template.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/chatbot-pf/template/issues"
},
"homepage": "https://github.com/chatbot-pf/template#readme",
"dependencies": {},
"devDependencies": {
"@antfu/eslint-config": "^7.7.3",
"@commitlint/cli": "^20.1.0",
"@commitlint/config-conventional": "^20.0.0",
"@commitlint/config-workspace-scopes": "^20.4.3"
"@commitlint/config-workspace-scopes": "^20.4.3",
"@vitest/coverage-istanbul": "^4.1.1",
"eslint": "^10.1.0",
"publint": "^0.3.18",
"turbo": "^2.5.0",
"typescript": "^5.8.0"
},
"packageManager": "bun@1.3.10"
}
Empty file added packages/.gitkeep
Empty file.
94 changes: 94 additions & 0 deletions packages/firestore/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# @please-auth/firestore

[better-auth](https://www.better-auth.com/)용 [Cloud Firestore](https://firebase.google.com/docs/firestore) 어댑터입니다.

## 설치

```bash
bun add @please-auth/firestore
# peer dependencies
bun add better-auth firebase-admin
```

## 사용법

```ts
import { firestoreAdapter } from '@please-auth/firestore'
import { betterAuth } from 'better-auth'
import { getFirestore } from 'firebase-admin/firestore'

const auth = betterAuth({
database: firestoreAdapter({ db: getFirestore() }),
})
```

### `initFirestore` 헬퍼

서버리스 환경에서 안전하게 Firestore 인스턴스를 초기화/재사용합니다.

```ts
import { firestoreAdapter, initFirestore } from '@please-auth/firestore'

const db = initFirestore({ projectId: 'my-project' })

const auth = betterAuth({
database: firestoreAdapter({ db }),
})
```

## 설정 옵션

```ts
firestoreAdapter({
// (필수) Firestore 인스턴스
db: getFirestore(),

// 필드 네이밍 전략: "default" (camelCase) | "snake_case"
namingStrategy: 'default',

// 컬렉션 이름 커스텀
collections: {
users: 'users',
sessions: 'sessions',
accounts: 'accounts',
verifications: 'verifications',
},

// 디버그 로깅
debugLogs: false,
})
```

### `namingStrategy`

| 전략 | 예시 |
|------|------|
| `"default"` | `userId`, `emailVerified`, `createdAt` |
| `"snake_case"` | `user_id`, `email_verified`, `created_at` |

## 기능

- better-auth `CustomAdapter` 인터페이스 완전 구현
- 문서 ID 기반 조회 시 **fast path** (`.doc(id).get()` 직접 호출)
- `updateMany`/`deleteMany`에 **WriteBatch** 사용 (500개 단위 청크)
- `not_in` 10개 이하 시 Firestore 네이티브 `not-in` 쿼리
- `starts_with`는 범위 쿼리 (`>=` / `<`) 트릭 사용
- `contains`/`ends_with`는 클라이언트 사이드 필터링
- OR 커넥터: 그룹별 개별 쿼리 실행 후 병합
- Firestore `Timestamp` → JS `Date` 자동 변환
- `db.runTransaction()` 기반 트랜잭션 지원

## Firestore 인덱스

better-auth의 verification token 조회에 복합 인덱스가 필요할 수 있습니다:

```
Collection: verifications
Fields: identifier ASC, createdAt DESC
```

Firebase Console 또는 `firestore.indexes.json`으로 배포하세요.

## 라이선스

MIT
59 changes: 59 additions & 0 deletions packages/firestore/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "@please-auth/firestore",
"type": "module",
"version": "0.1.0",
"description": "Firestore adapter for better-auth",
"author": "Minsu Lee <amondnet@gmail.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/chatbot-pf/better-auth",
"directory": "packages/firestore"
},
"keywords": [
"better-auth",
"firestore",
"firebase",
"adapter",
"auth"
],
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"test": "vitest run",
"test:watch": "vitest",
"check-types": "tsc --noEmit",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"lint:package": "publint run --strict",
"clean": "rm -rf dist .turbo"
},
"peerDependencies": {
"better-auth": ">=1.0.0",
"firebase-admin": ">=13.0.0"
},
"devDependencies": {
"better-auth": "^1.2.0",
"firebase-admin": "^13.0.0",
"tsup": "^8.4.0",
"vitest": "^3.1.0"
}
}
Loading
Loading