@picobase_app/client 0.1.0
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 +233 -0
- package/dist/index.d.mts +491 -0
- package/dist/index.d.ts +491 -0
- package/dist/index.js +531 -0
- package/dist/index.mjs +485 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# @picobase_app/client
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for PicoBase — add auth, database, realtime, and file storage to your app.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @picobase_app/client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { createClient } from '@picobase_app/client'
|
|
15
|
+
|
|
16
|
+
const pb = createClient('https://myapp.picobase.com', 'pbk_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Get your URL and API key from the [PicoBase dashboard](https://picobase.com/dashboard).
|
|
20
|
+
|
|
21
|
+
## Authentication
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Sign up a new user
|
|
25
|
+
const { token, record } = await pb.auth.signUp({
|
|
26
|
+
email: 'user@example.com',
|
|
27
|
+
password: 'securepassword',
|
|
28
|
+
name: 'Jane Doe',
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
// Sign in
|
|
32
|
+
const { token, record } = await pb.auth.signIn({
|
|
33
|
+
email: 'user@example.com',
|
|
34
|
+
password: 'securepassword',
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// OAuth (Google, GitHub, etc. — configure providers in the dashboard)
|
|
38
|
+
const { token, record } = await pb.auth.signInWithOAuth({
|
|
39
|
+
provider: 'google',
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Check current user
|
|
43
|
+
const user = pb.auth.user // RecordModel | null
|
|
44
|
+
const isValid = pb.auth.isValid // boolean
|
|
45
|
+
|
|
46
|
+
// Listen to auth changes
|
|
47
|
+
const unsubscribe = pb.auth.onStateChange((event, record) => {
|
|
48
|
+
// event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED'
|
|
49
|
+
console.log(event, record?.email)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Password reset
|
|
53
|
+
await pb.auth.requestPasswordReset('user@example.com')
|
|
54
|
+
|
|
55
|
+
// Sign out
|
|
56
|
+
pb.auth.signOut()
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Database (Collections)
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// List records with pagination, filtering, and sorting
|
|
63
|
+
const result = await pb.collection('posts').getList(1, 20, {
|
|
64
|
+
filter: 'published = true',
|
|
65
|
+
sort: '-created',
|
|
66
|
+
expand: 'author',
|
|
67
|
+
})
|
|
68
|
+
// result.items, result.totalItems, result.totalPages
|
|
69
|
+
|
|
70
|
+
// Get a single record
|
|
71
|
+
const post = await pb.collection('posts').getOne('RECORD_ID')
|
|
72
|
+
|
|
73
|
+
// Find first match
|
|
74
|
+
const admin = await pb.collection('users').getFirstListItem('role = "admin"')
|
|
75
|
+
|
|
76
|
+
// Get all records (auto-paginates — use with caution on large collections)
|
|
77
|
+
const allPosts = await pb.collection('posts').getFullList({
|
|
78
|
+
filter: 'published = true',
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Create
|
|
82
|
+
const newPost = await pb.collection('posts').create({
|
|
83
|
+
title: 'Hello World',
|
|
84
|
+
content: 'My first post',
|
|
85
|
+
published: true,
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// Update
|
|
89
|
+
const updated = await pb.collection('posts').update('RECORD_ID', {
|
|
90
|
+
title: 'Updated Title',
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Delete
|
|
94
|
+
await pb.collection('posts').delete('RECORD_ID')
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### TypeScript generics
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
interface Post {
|
|
101
|
+
id: string
|
|
102
|
+
title: string
|
|
103
|
+
content: string
|
|
104
|
+
published: boolean
|
|
105
|
+
created: string
|
|
106
|
+
updated: string
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const posts = await pb.collection<Post>('posts').getList(1, 20)
|
|
110
|
+
// posts.items is Post[]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### File uploads
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
const formData = new FormData()
|
|
117
|
+
formData.append('title', 'Photo post')
|
|
118
|
+
formData.append('image', fileInput.files[0])
|
|
119
|
+
|
|
120
|
+
const record = await pb.collection('posts').create(formData)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Realtime
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Subscribe to all changes on a collection
|
|
127
|
+
const unsubscribe = await pb.collection('posts').subscribe((event) => {
|
|
128
|
+
console.log(event.action, event.record) // 'create' | 'update' | 'delete'
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
// Subscribe to a specific record
|
|
132
|
+
const unsubscribe = await pb.collection('posts').subscribeOne('RECORD_ID', (event) => {
|
|
133
|
+
console.log(event.action, event.record)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// Unsubscribe
|
|
137
|
+
await unsubscribe()
|
|
138
|
+
|
|
139
|
+
// Or use the realtime module directly
|
|
140
|
+
const unsub = await pb.realtime.subscribe('posts', (event) => {
|
|
141
|
+
console.log(event)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
// Disconnect all realtime subscriptions
|
|
145
|
+
await pb.realtime.disconnectAll()
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## File Storage
|
|
149
|
+
|
|
150
|
+
PocketBase stores files as fields on records. Use the storage module to get URLs.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const user = await pb.collection('users').getOne('USER_ID')
|
|
154
|
+
|
|
155
|
+
// Get file URL
|
|
156
|
+
const url = pb.storage.getFileUrl(user, 'avatar.jpg')
|
|
157
|
+
|
|
158
|
+
// Get thumbnail
|
|
159
|
+
const thumb = pb.storage.getFileUrl(user, 'avatar.jpg', { thumb: '100x100' })
|
|
160
|
+
|
|
161
|
+
// Protected files — get a temporary token first
|
|
162
|
+
const token = await pb.storage.getFileToken()
|
|
163
|
+
const protectedUrl = pb.storage.getFileUrl(user, 'document.pdf', { token })
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Advanced
|
|
167
|
+
|
|
168
|
+
### Custom auth collection
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// If you use a custom auth collection instead of 'users'
|
|
172
|
+
pb.auth.setCollection('members')
|
|
173
|
+
await pb.auth.signIn({ email: 'member@example.com', password: 'pass' })
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Raw PocketBase access
|
|
177
|
+
|
|
178
|
+
The underlying PocketBase SDK instance is exposed for advanced use cases.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// Access the PocketBase client directly
|
|
182
|
+
const health = await pb.pb.health.check()
|
|
183
|
+
|
|
184
|
+
// Custom API endpoint
|
|
185
|
+
const result = await pb.send('/api/custom-endpoint', { method: 'POST', body: { foo: 'bar' } })
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Cold-start handling
|
|
189
|
+
|
|
190
|
+
PicoBase instances may be paused when idle. The SDK automatically retries with exponential backoff (2s, 4s, 8s) when it receives a 503 response. You can configure this:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const pb = createClient('https://myapp.picobase.com', 'pbk_...', {
|
|
194
|
+
maxColdStartRetries: 5, // default: 3
|
|
195
|
+
})
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Error handling
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { PicoBaseError, InstanceUnavailableError, AuthorizationError } from '@picobase_app/client'
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
await pb.collection('posts').getList()
|
|
205
|
+
} catch (err) {
|
|
206
|
+
if (err instanceof AuthorizationError) {
|
|
207
|
+
// Invalid API key
|
|
208
|
+
} else if (err instanceof InstanceUnavailableError) {
|
|
209
|
+
// Instance not available after retries
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## API Reference
|
|
215
|
+
|
|
216
|
+
### `createClient(url, apiKey, options?)`
|
|
217
|
+
|
|
218
|
+
| Parameter | Type | Description |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| `url` | `string` | Your PicoBase instance URL |
|
|
221
|
+
| `apiKey` | `string` | API key from the dashboard (starts with `pbk_`) |
|
|
222
|
+
| `options.maxColdStartRetries` | `number` | Max retries on 503. Default: `3` |
|
|
223
|
+
| `options.lang` | `string` | Accept-Language header. Default: `'en-US'` |
|
|
224
|
+
|
|
225
|
+
### Modules
|
|
226
|
+
|
|
227
|
+
| Module | Access | Description |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| `pb.auth` | `PicoBaseAuth` | Sign up, sign in, OAuth, session management |
|
|
230
|
+
| `pb.collection(name)` | `PicoBaseCollection` | CRUD operations on a collection |
|
|
231
|
+
| `pb.realtime` | `PicoBaseRealtime` | Realtime subscriptions |
|
|
232
|
+
| `pb.storage` | `PicoBaseStorage` | File URLs and tokens |
|
|
233
|
+
| `pb.pb` | `PocketBase` | Underlying PocketBase SDK instance |
|