@taruvi/sdk 1.0.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/.claude/settings.local.json +16 -0
- package/DATAPROVIDER_CONTEXT.md +828 -0
- package/README.md +703 -0
- package/USAGE_EXAMPLE.md +86 -0
- package/package.json +25 -0
- package/src/client.ts +81 -0
- package/src/index.ts +20 -0
- package/src/lib/Database/DatabaseClient.ts +87 -0
- package/src/lib/Database/types.ts +29 -0
- package/src/lib/Function/FunctionsClient.ts +27 -0
- package/src/lib/Function/types.ts +17 -0
- package/src/lib/Secrets/SecretsClient.ts +44 -0
- package/src/lib/Secrets/types.ts +17 -0
- package/src/lib/Settings/SettingsClient.ts +14 -0
- package/src/lib/Settings/types.ts +4 -0
- package/src/lib/Storage/StorageClient.ts +88 -0
- package/src/lib/Storage/types.ts +40 -0
- package/src/lib/auth/AuthClient.ts +64 -0
- package/src/lib/auth/types.ts +9 -0
- package/src/lib/user/UserClient.ts +44 -0
- package/src/lib/user/types.ts +69 -0
- package/src/lib-internal/errors/ErrorClient.ts +12 -0
- package/src/lib-internal/errors/index.ts +25 -0
- package/src/lib-internal/errors/types.ts +105 -0
- package/src/lib-internal/http/HttpClient.ts +96 -0
- package/src/lib-internal/http/types.ts +10 -0
- package/src/lib-internal/routes/AuthRoutes.ts +0 -0
- package/src/lib-internal/routes/DatabaseRoutes.ts +5 -0
- package/src/lib-internal/routes/FunctionRoutes.ts +3 -0
- package/src/lib-internal/routes/RouteBuilder.ts +0 -0
- package/src/lib-internal/routes/SecretsRoutes.ts +5 -0
- package/src/lib-internal/routes/SettingsRoutes.ts +3 -0
- package/src/lib-internal/routes/StorageRoutes.ts +7 -0
- package/src/lib-internal/routes/UserRoutes.ts +9 -0
- package/src/lib-internal/routes/index.ts +0 -0
- package/src/lib-internal/token/TokenClient.ts +30 -0
- package/src/lib-internal/token/types.ts +0 -0
- package/src/types.ts +68 -0
- package/src/utils/enums.ts +12 -0
- package/src/utils/utils.ts +36 -0
- package/tests/mocks/db.json +1 -0
- package/tsconfig.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
# Taruvi SDK
|
|
2
|
+
|
|
3
|
+
> A TypeScript SDK for the Taruvi Platform - Backend-as-a-Service for modern applications
|
|
4
|
+
|
|
5
|
+
[]() []() []()
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Taruvi SDK is a type-safe client library that enables JavaScript/TypeScript applications to interact with the Taruvi Backend-as-a-Service platform. It provides a clean, intuitive API for authentication, user management, data storage, and serverless functions.
|
|
10
|
+
|
|
11
|
+
### Key Features
|
|
12
|
+
|
|
13
|
+
- **Modern Architecture** - Dependency injection pattern, no singletons
|
|
14
|
+
- **Type-Safe** - Full TypeScript support with strict typing
|
|
15
|
+
- **Lazy Loading** - Only bundle the services you use
|
|
16
|
+
- **Tree-Shakeable** - Optimized for minimal bundle size
|
|
17
|
+
- **Testable** - Easy to mock and test with dependency injection
|
|
18
|
+
- **Flexible** - Support for multiple instances and configurations
|
|
19
|
+
- **Multi-Tenant** - Manage multiple apps under a single site
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @taruvi/sdk
|
|
27
|
+
# or
|
|
28
|
+
yarn add @taruvi/sdk
|
|
29
|
+
# or
|
|
30
|
+
pnpm add @taruvi/sdk
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { Client, Auth, User } from '@taruvi/sdk'
|
|
39
|
+
|
|
40
|
+
// 1. Create the main client
|
|
41
|
+
const client = new Client({
|
|
42
|
+
apiKey: 'your-site-api-key',
|
|
43
|
+
appSlug: 'my-app',
|
|
44
|
+
baseUrl: 'https://test-api.taruvi.cloud'
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// 2. Initialize only the services you need
|
|
48
|
+
const auth = new Auth(client)
|
|
49
|
+
const user = new User(client)
|
|
50
|
+
|
|
51
|
+
// 3. Use the services
|
|
52
|
+
await auth.authenticateUser()
|
|
53
|
+
const userData = await user.getUserData()
|
|
54
|
+
console.log(userData.username)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Core Concepts
|
|
60
|
+
|
|
61
|
+
### Dependency Injection Pattern
|
|
62
|
+
|
|
63
|
+
Taruvi SDK uses dependency injection instead of singletons, allowing multiple client instances and better testability.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// Multiple environments
|
|
67
|
+
const prodClient = new Client({ apiKey: '...', appSlug: 'prod', baseUrl: '...' })
|
|
68
|
+
const devClient = new Client({ apiKey: '...', appSlug: 'dev', baseUrl: '...' })
|
|
69
|
+
|
|
70
|
+
// Services use the client they're given
|
|
71
|
+
const prodUser = new User(prodClient)
|
|
72
|
+
const devUser = new User(devClient)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Lazy Service Instantiation
|
|
76
|
+
|
|
77
|
+
Services are manually instantiated, allowing tree-shaking to eliminate unused code.
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Only import what you need
|
|
81
|
+
import { Client, User } from '@taruvi/sdk' // ✅ Auth not bundled
|
|
82
|
+
|
|
83
|
+
const client = new Client({ /* config */ })
|
|
84
|
+
const user = new User(client) // Only User service loaded
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Multi-Tenancy Support
|
|
88
|
+
|
|
89
|
+
Single site can manage multiple apps with isolated data using `appSlug`.
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const customerApp = new Client({
|
|
93
|
+
apiKey: 'site_abc123', // Same site
|
|
94
|
+
appSlug: 'customer-portal', // Customer data
|
|
95
|
+
baseUrl: 'https://test-api.taruvi.cloud'
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const adminApp = new Client({
|
|
99
|
+
apiKey: 'site_abc123', // Same site
|
|
100
|
+
appSlug: 'admin-dashboard', // Admin data (isolated)
|
|
101
|
+
baseUrl: 'https://test-api.taruvi.cloud'
|
|
102
|
+
})
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Services
|
|
108
|
+
|
|
109
|
+
### Auth Service
|
|
110
|
+
|
|
111
|
+
User authentication and session management.
|
|
112
|
+
|
|
113
|
+
**Status**: 🚧 60% Complete
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { Client, Auth } from '@taruvi/sdk'
|
|
117
|
+
|
|
118
|
+
const client = new Client({ /* config */ })
|
|
119
|
+
const auth = new Auth(client)
|
|
120
|
+
|
|
121
|
+
// Authenticate user
|
|
122
|
+
await auth.authenticateUser()
|
|
123
|
+
|
|
124
|
+
// Check authentication status
|
|
125
|
+
const isAuth = await auth.isUserAuthenticated() // true/false
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Available Methods
|
|
129
|
+
- ✅ `authenticateUser()` - Login with email/password
|
|
130
|
+
- ✅ `isUserAuthenticated()` - Check if user has valid session
|
|
131
|
+
- 📋 `signInWithSSO()` - SSO authentication (planned)
|
|
132
|
+
- 📋 `refreshSession()` - Refresh expired token (planned)
|
|
133
|
+
- 📋 `signOut()` - End user session (planned)
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### User Service
|
|
138
|
+
|
|
139
|
+
User profile and management operations.
|
|
140
|
+
|
|
141
|
+
**Status**: ✅ 80% Complete (CRUD functional)
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { Client, User } from '@taruvi/sdk'
|
|
145
|
+
|
|
146
|
+
const client = new Client({ /* config */ })
|
|
147
|
+
const user = new User(client)
|
|
148
|
+
|
|
149
|
+
// Get current user
|
|
150
|
+
const userData = await user.getUserData()
|
|
151
|
+
|
|
152
|
+
// Create new user
|
|
153
|
+
const newUser = await user.createUser({
|
|
154
|
+
username: 'john_doe',
|
|
155
|
+
email: 'john@example.com',
|
|
156
|
+
password: 'secure123'
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
// Update user
|
|
160
|
+
await user.updateUser('john_doe', {
|
|
161
|
+
email: 'newemail@example.com'
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// Delete user
|
|
165
|
+
await user.deleteUser('john_doe')
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Available Methods
|
|
169
|
+
- ✅ `getUserData()` - Fetch current user details
|
|
170
|
+
- ✅ `createUser(data)` - Create new user account
|
|
171
|
+
- ✅ `updateUser(username, data)` - Update user information
|
|
172
|
+
- ✅ `deleteUser(username)` - Delete user account
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Storage Service
|
|
177
|
+
|
|
178
|
+
Query builder for app-specific data tables.
|
|
179
|
+
|
|
180
|
+
**Status**: 🚧 70% Complete (Query builder working)
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { Client, Storage } from '@taruvi/sdk'
|
|
184
|
+
|
|
185
|
+
const client = new Client({ /* config */ })
|
|
186
|
+
const storage = new Storage(client, {})
|
|
187
|
+
|
|
188
|
+
// Get all records from a table
|
|
189
|
+
const allPosts = await storage
|
|
190
|
+
.from('posts')
|
|
191
|
+
.execute()
|
|
192
|
+
|
|
193
|
+
// Get specific record
|
|
194
|
+
const post = await storage
|
|
195
|
+
.from('posts')
|
|
196
|
+
.get('post_123')
|
|
197
|
+
.execute()
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Available Methods
|
|
201
|
+
- ✅ `from(tableName)` - Select table (chainable)
|
|
202
|
+
- ✅ `get(recordId)` - Select specific record (chainable)
|
|
203
|
+
- ✅ `execute()` - Execute the built query
|
|
204
|
+
- 📋 `upload()` - File upload (planned)
|
|
205
|
+
- 📋 `download()` - File download (planned)
|
|
206
|
+
- 📋 `delete()` - Delete files (planned)
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### Settings Service
|
|
211
|
+
|
|
212
|
+
Site configuration and settings.
|
|
213
|
+
|
|
214
|
+
**Status**: ✅ 70% Complete
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { Client, Settings } from '@taruvi/sdk'
|
|
218
|
+
|
|
219
|
+
const client = new Client({ /* config */ })
|
|
220
|
+
const settings = new Settings(client)
|
|
221
|
+
|
|
222
|
+
// Fetch site configuration
|
|
223
|
+
const siteConfig = await settings.get()
|
|
224
|
+
console.log(siteConfig.site_slug)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
### Database Service (Planned)
|
|
230
|
+
|
|
231
|
+
Query builder for database operations.
|
|
232
|
+
|
|
233
|
+
**Status**: 📋 Not Implemented
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { Client, Database } from '@taruvi/sdk'
|
|
237
|
+
|
|
238
|
+
const client = new Client({ /* config */ })
|
|
239
|
+
const database = new Database(client)
|
|
240
|
+
|
|
241
|
+
// Planned API (not yet functional)
|
|
242
|
+
const users = await database
|
|
243
|
+
.from('users')
|
|
244
|
+
.select('*')
|
|
245
|
+
.filter('age', 'gte', 18)
|
|
246
|
+
.execute()
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
### Functions Service (Planned)
|
|
252
|
+
|
|
253
|
+
Serverless function invocation.
|
|
254
|
+
|
|
255
|
+
**Status**: 📋 Not Implemented
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
import { Client, Functions } from '@taruvi/sdk'
|
|
259
|
+
|
|
260
|
+
const client = new Client({ /* config */ })
|
|
261
|
+
const functions = new Functions(client)
|
|
262
|
+
|
|
263
|
+
// Planned API (not yet functional)
|
|
264
|
+
const result = await functions.invoke('my-function', { data: 'value' })
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Configuration
|
|
270
|
+
|
|
271
|
+
### TaruviConfig Interface
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
interface TaruviConfig {
|
|
275
|
+
apiKey: string // Required: Site/organization identifier
|
|
276
|
+
appSlug: string // Required: App identifier (multi-tenant)
|
|
277
|
+
baseUrl: string // Required: API endpoint URL
|
|
278
|
+
token?: string // Optional: Pre-existing session token
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Configuration Examples
|
|
283
|
+
|
|
284
|
+
#### Basic Setup
|
|
285
|
+
```typescript
|
|
286
|
+
const client = new Client({
|
|
287
|
+
apiKey: 'your-site-key',
|
|
288
|
+
appSlug: 'my-app',
|
|
289
|
+
baseUrl: 'https://test-api.taruvi.cloud'
|
|
290
|
+
})
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### With Existing Token
|
|
294
|
+
```typescript
|
|
295
|
+
const client = new Client({
|
|
296
|
+
apiKey: 'your-site-key',
|
|
297
|
+
appSlug: 'my-app',
|
|
298
|
+
baseUrl: 'https://test-api.taruvi.cloud',
|
|
299
|
+
token: 'existing-session-token' // Skip login
|
|
300
|
+
})
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### Multiple Environments
|
|
304
|
+
```typescript
|
|
305
|
+
const config = {
|
|
306
|
+
production: {
|
|
307
|
+
apiKey: process.env.PROD_API_KEY!,
|
|
308
|
+
appSlug: 'prod-app',
|
|
309
|
+
baseUrl: 'https://api.taruvi.cloud'
|
|
310
|
+
},
|
|
311
|
+
development: {
|
|
312
|
+
apiKey: process.env.DEV_API_KEY!,
|
|
313
|
+
appSlug: 'dev-app',
|
|
314
|
+
baseUrl: 'https://dev-api.taruvi.cloud'
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const client = new Client(
|
|
319
|
+
process.env.NODE_ENV === 'production'
|
|
320
|
+
? config.production
|
|
321
|
+
: config.development
|
|
322
|
+
)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Framework Integration
|
|
328
|
+
|
|
329
|
+
### React
|
|
330
|
+
|
|
331
|
+
Create context and custom hooks for app-wide access.
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { createContext, useContext, ReactNode } from 'react'
|
|
335
|
+
import { Client, User, Auth } from '@taruvi/sdk'
|
|
336
|
+
|
|
337
|
+
// Create context
|
|
338
|
+
const TaruviContext = createContext<Client | null>(null)
|
|
339
|
+
|
|
340
|
+
// Provider component
|
|
341
|
+
export function TaruviProvider({ children }: { children: ReactNode }) {
|
|
342
|
+
const client = new Client({
|
|
343
|
+
apiKey: process.env.REACT_APP_TARUVI_API_KEY!,
|
|
344
|
+
appSlug: process.env.REACT_APP_TARUVI_APP_SLUG!,
|
|
345
|
+
baseUrl: process.env.REACT_APP_TARUVI_BASE_URL!
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
return (
|
|
349
|
+
<TaruviContext.Provider value={client}>
|
|
350
|
+
{children}
|
|
351
|
+
</TaruviContext.Provider>
|
|
352
|
+
)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Custom hooks
|
|
356
|
+
export function useTaruvi() {
|
|
357
|
+
const client = useContext(TaruviContext)
|
|
358
|
+
if (!client) throw new Error('useTaruvi must be used within TaruviProvider')
|
|
359
|
+
return client
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export function useAuth() {
|
|
363
|
+
const client = useTaruvi()
|
|
364
|
+
return new Auth(client)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export function useUser() {
|
|
368
|
+
const client = useTaruvi()
|
|
369
|
+
return new User(client)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Usage in component
|
|
373
|
+
function UserProfile() {
|
|
374
|
+
const user = useUser()
|
|
375
|
+
const [data, setData] = useState(null)
|
|
376
|
+
|
|
377
|
+
useEffect(() => {
|
|
378
|
+
user.getUserData().then(setData)
|
|
379
|
+
}, [])
|
|
380
|
+
|
|
381
|
+
return <div>Welcome, {data?.username}!</div>
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Vue 3
|
|
386
|
+
|
|
387
|
+
Use provide/inject with Composition API.
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { provide, inject, InjectionKey } from 'vue'
|
|
391
|
+
import { Client, Auth, User } from '@taruvi/sdk'
|
|
392
|
+
|
|
393
|
+
// Create injection key
|
|
394
|
+
const TaruviKey: InjectionKey<Client> = Symbol('taruvi')
|
|
395
|
+
|
|
396
|
+
// Setup in main app or parent component
|
|
397
|
+
export function setupTaruvi() {
|
|
398
|
+
const client = new Client({
|
|
399
|
+
apiKey: import.meta.env.VITE_TARUVI_API_KEY,
|
|
400
|
+
appSlug: import.meta.env.VITE_TARUVI_APP_SLUG,
|
|
401
|
+
baseUrl: import.meta.env.VITE_TARUVI_BASE_URL
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
provide(TaruviKey, client)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Composables
|
|
408
|
+
export function useTaruvi() {
|
|
409
|
+
const client = inject(TaruviKey)
|
|
410
|
+
if (!client) throw new Error('Taruvi not provided')
|
|
411
|
+
return client
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function useAuth() {
|
|
415
|
+
const client = useTaruvi()
|
|
416
|
+
return new Auth(client)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export function useUser() {
|
|
420
|
+
const client = useTaruvi()
|
|
421
|
+
return new User(client)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Usage in component
|
|
425
|
+
import { ref, onMounted } from 'vue'
|
|
426
|
+
import { useUser } from '@/composables/taruvi'
|
|
427
|
+
|
|
428
|
+
export default {
|
|
429
|
+
setup() {
|
|
430
|
+
const user = useUser()
|
|
431
|
+
const userData = ref(null)
|
|
432
|
+
|
|
433
|
+
onMounted(async () => {
|
|
434
|
+
userData.value = await user.getUserData()
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
return { userData }
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Vanilla JavaScript
|
|
443
|
+
|
|
444
|
+
Direct usage without framework.
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import { Client, Auth, User } from '@taruvi/sdk'
|
|
448
|
+
|
|
449
|
+
// Create client
|
|
450
|
+
const client = new Client({
|
|
451
|
+
apiKey: 'your-key',
|
|
452
|
+
appSlug: 'your-app',
|
|
453
|
+
baseUrl: 'https://test-api.taruvi.cloud'
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
// Initialize services
|
|
457
|
+
const auth = new Auth(client)
|
|
458
|
+
const user = new User(client)
|
|
459
|
+
|
|
460
|
+
// Use services
|
|
461
|
+
async function handleLogin() {
|
|
462
|
+
await auth.authenticateUser()
|
|
463
|
+
|
|
464
|
+
if (await auth.isUserAuthenticated()) {
|
|
465
|
+
const userData = await user.getUserData()
|
|
466
|
+
document.getElementById('username').textContent = userData.username
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
handleLogin()
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## TypeScript Types
|
|
476
|
+
|
|
477
|
+
All public types are exported from the main entry point.
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
import type {
|
|
481
|
+
TaruviConfig,
|
|
482
|
+
UserCreateRequest,
|
|
483
|
+
UserResponse,
|
|
484
|
+
UserDataResponse
|
|
485
|
+
} from '@taruvi/sdk'
|
|
486
|
+
|
|
487
|
+
// Use types in your application
|
|
488
|
+
const config: TaruviConfig = {
|
|
489
|
+
apiKey: 'key',
|
|
490
|
+
appSlug: 'app',
|
|
491
|
+
baseUrl: 'https://test-api.taruvi.cloud'
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const newUser: UserCreateRequest = {
|
|
495
|
+
username: 'john_doe',
|
|
496
|
+
email: 'john@example.com',
|
|
497
|
+
password: 'secure123'
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Architecture
|
|
504
|
+
|
|
505
|
+
### Design Principles
|
|
506
|
+
|
|
507
|
+
The Taruvi SDK follows these architectural principles:
|
|
508
|
+
|
|
509
|
+
1. **Dependency Injection** - No singletons, explicit dependencies
|
|
510
|
+
2. **Lazy Initialization** - Create only what you need
|
|
511
|
+
3. **Internal API Protection** - Internal utilities marked with `@internal`
|
|
512
|
+
4. **Type Safety** - Full TypeScript support with strict mode
|
|
513
|
+
5. **Tree-Shaking** - Unused code is eliminated by bundlers
|
|
514
|
+
|
|
515
|
+
### Project Structure
|
|
516
|
+
|
|
517
|
+
```
|
|
518
|
+
src/
|
|
519
|
+
├── lib/ # Public API (safe to use)
|
|
520
|
+
│ ├── auth/ # Auth service
|
|
521
|
+
│ ├── user/ # User service
|
|
522
|
+
│ ├── storage/ # Storage service
|
|
523
|
+
│ ├── settings/ # Settings service
|
|
524
|
+
│ ├── database/ # Database service (planned)
|
|
525
|
+
│ └── function/ # Functions service (planned)
|
|
526
|
+
│
|
|
527
|
+
├── lib-internal/ # Internal utilities (not public)
|
|
528
|
+
│ ├── http/ # HTTP client wrapper
|
|
529
|
+
│ ├── token/ # Token management
|
|
530
|
+
│ ├── routes/ # API route definitions
|
|
531
|
+
│ ├── errors/ # Error handling
|
|
532
|
+
│ └── utils/ # Helper functions
|
|
533
|
+
│
|
|
534
|
+
├── client.ts # Main Client class
|
|
535
|
+
├── index.ts # Public exports
|
|
536
|
+
└── types.ts # Shared types
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Internal vs Public API
|
|
540
|
+
|
|
541
|
+
**Public API** (safe to use):
|
|
542
|
+
- `Client` - Main client class
|
|
543
|
+
- `Auth`, `User`, `Database`, `Storage`, `Functions` - Service clients
|
|
544
|
+
- `TaruviConfig` - Configuration interface
|
|
545
|
+
- Exported types from `index.ts`
|
|
546
|
+
|
|
547
|
+
**Internal API** (do not use directly):
|
|
548
|
+
- `client.httpClient` - Marked with `@internal`
|
|
549
|
+
- `client.tokenClient` - Marked with `@internal`
|
|
550
|
+
- Files in `lib-internal/` folder
|
|
551
|
+
|
|
552
|
+
> ⚠️ **Warning:** Using internal APIs may break in future versions without notice
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## Testing
|
|
557
|
+
|
|
558
|
+
### Mocking the SDK
|
|
559
|
+
|
|
560
|
+
```typescript
|
|
561
|
+
import { Client, User } from '@taruvi/sdk'
|
|
562
|
+
import { vi, describe, it, expect } from 'vitest'
|
|
563
|
+
|
|
564
|
+
describe('User Service', () => {
|
|
565
|
+
it('should fetch user data', async () => {
|
|
566
|
+
// Mock HttpClient
|
|
567
|
+
const mockHttpClient = {
|
|
568
|
+
get: vi.fn().mockResolvedValue({
|
|
569
|
+
username: 'testuser',
|
|
570
|
+
email: 'test@example.com'
|
|
571
|
+
})
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Mock Client
|
|
575
|
+
const mockClient = {
|
|
576
|
+
httpClient: mockHttpClient,
|
|
577
|
+
getConfig: () => ({
|
|
578
|
+
apiKey: 'test',
|
|
579
|
+
appSlug: 'test',
|
|
580
|
+
baseUrl: 'test'
|
|
581
|
+
})
|
|
582
|
+
} as unknown as Client
|
|
583
|
+
|
|
584
|
+
// Test User service
|
|
585
|
+
const user = new User(mockClient)
|
|
586
|
+
const data = await user.getUserData()
|
|
587
|
+
|
|
588
|
+
expect(data.username).toBe('testuser')
|
|
589
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith('api/users/me/')
|
|
590
|
+
})
|
|
591
|
+
})
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Development Status
|
|
597
|
+
|
|
598
|
+
### Implementation Progress
|
|
599
|
+
|
|
600
|
+
| Service | Status | Progress | Notes |
|
|
601
|
+
|---------|--------|----------|-------|
|
|
602
|
+
| Core Infrastructure | ✅ Complete | 90% | Client, HTTP, Token management |
|
|
603
|
+
| User Service | ✅ Functional | 80% | CRUD operations working |
|
|
604
|
+
| Auth Service | 🚧 Partial | 60% | Basic auth working, SSO planned |
|
|
605
|
+
| Storage Service | 🚧 Partial | 70% | Query builder working |
|
|
606
|
+
| Settings Service | ✅ Functional | 70% | Site config fetching |
|
|
607
|
+
| Database Service | 📋 Planned | 0% | Not yet implemented |
|
|
608
|
+
| Functions Service | 📋 Planned | 0% | Not yet implemented |
|
|
609
|
+
|
|
610
|
+
### Legend
|
|
611
|
+
- ✅ **Complete/Functional**: Ready for production use
|
|
612
|
+
- 🚧 **Partial**: Core functionality works, some features pending
|
|
613
|
+
- 📋 **Planned**: Not yet implemented
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Roadmap
|
|
618
|
+
|
|
619
|
+
### v1.2 (Next Release)
|
|
620
|
+
- [ ] Complete Auth service (SSO, token refresh, sign out)
|
|
621
|
+
- [ ] Add error handling classes
|
|
622
|
+
- [ ] Implement token management (set, clear, expiration)
|
|
623
|
+
- [ ] Add PATCH HTTP method
|
|
624
|
+
- [ ] Add retry logic for failed requests
|
|
625
|
+
|
|
626
|
+
### v1.3 (Future)
|
|
627
|
+
- [ ] Database service with query builder
|
|
628
|
+
- [ ] Functions service for serverless invocation
|
|
629
|
+
- [ ] File upload/download in Storage
|
|
630
|
+
- [ ] Comprehensive test suite
|
|
631
|
+
|
|
632
|
+
### v2.0 (Long-term)
|
|
633
|
+
- [ ] Real-time subscriptions (WebSocket)
|
|
634
|
+
- [ ] Offline support with local caching
|
|
635
|
+
- [ ] Browser DevTools extension
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
## API Reference
|
|
640
|
+
|
|
641
|
+
For complete API documentation, see [adr.md](./adr.md).
|
|
642
|
+
|
|
643
|
+
For usage examples, see [USAGE_EXAMPLE.md](./USAGE_EXAMPLE.md).
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
## Contributing
|
|
648
|
+
|
|
649
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
650
|
+
|
|
651
|
+
### Development Setup
|
|
652
|
+
|
|
653
|
+
```bash
|
|
654
|
+
# Clone repository
|
|
655
|
+
git clone https://github.com/taruvi/taruvi-sdk
|
|
656
|
+
cd taruvi-sdk
|
|
657
|
+
|
|
658
|
+
# Install dependencies
|
|
659
|
+
npm install
|
|
660
|
+
|
|
661
|
+
# Build SDK
|
|
662
|
+
npm run build
|
|
663
|
+
|
|
664
|
+
# Run tests (when available)
|
|
665
|
+
npm test
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
## License
|
|
671
|
+
|
|
672
|
+
MIT License - see [LICENSE](./LICENSE) file for details.
|
|
673
|
+
|
|
674
|
+
---
|
|
675
|
+
|
|
676
|
+
## Support
|
|
677
|
+
|
|
678
|
+
For questions, issues, or feature requests:
|
|
679
|
+
- 📧 Email: support@taruvi.io
|
|
680
|
+
- 🐛 Issues: [GitHub Issues](https://github.com/taruvi/taruvi-sdk/issues)
|
|
681
|
+
- 📖 Docs: [Documentation](https://docs.taruvi.io)
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
685
|
+
## Related Resources
|
|
686
|
+
|
|
687
|
+
- [Architecture Decision Record (ADR)](./adr.md) - Complete architectural documentation
|
|
688
|
+
- [Usage Examples](./USAGE_EXAMPLE.md) - Additional code examples
|
|
689
|
+
- [Taruvi Platform Docs](https://docs.taruvi.io) - Platform documentation
|
|
690
|
+
- [API Reference](https://api-docs.taruvi.io) - REST API documentation
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
## Acknowledgments
|
|
695
|
+
|
|
696
|
+
Inspired by:
|
|
697
|
+
- [Supabase JS](https://github.com/supabase/supabase-js) - Query builder pattern
|
|
698
|
+
- [Appwrite SDK](https://github.com/appwrite/sdk-for-web) - Service architecture
|
|
699
|
+
- [Stripe SDK](https://github.com/stripe/stripe-node) - Client pattern
|
|
700
|
+
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
**Built with ❤️ by the Taruvi Team**
|