@taruvi/sdk 1.0.1 → 1.0.3

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.
@@ -0,0 +1,733 @@
1
+ # Taruvi SDK - AI Implementation Guide
2
+
3
+ > Quick reference for implementing Taruvi SDK features with copy-paste examples from production code
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @taruvi-io/sdk
9
+ ```
10
+
11
+ ## Core Setup
12
+
13
+ ### 1. Initialize Client
14
+
15
+ ```typescript
16
+ import { Client } from '@taruvi-io/sdk'
17
+
18
+ const taruviClient = new Client({
19
+ apiKey: "your-site-api-key",
20
+ appSlug: "your-app-slug",
21
+ baseUrl: "https://taruvi-site.taruvi.cloud"
22
+ })
23
+ ```
24
+
25
+ ### 2. Pass to Components (React)
26
+
27
+ ```typescript
28
+ // App.tsx
29
+ <Route path="/page" element={<MyPage taruviClient={taruviClient} />} />
30
+
31
+ // MyPage.tsx
32
+ interface MyPageProps {
33
+ taruviClient: Client;
34
+ }
35
+
36
+ export default function MyPage({ taruviClient }: MyPageProps) {
37
+ // Use SDK here
38
+ }
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Auth Service
44
+
45
+ ### Check Authentication
46
+
47
+ ```typescript
48
+ import { Auth } from '@taruvi-io/sdk'
49
+
50
+ const auth = new Auth(taruviClient)
51
+ const isAuthenticated = await auth.isUserAuthenticated() // Returns boolean
52
+ ```
53
+
54
+ ### Login Flow
55
+
56
+ ```typescript
57
+ import { useEffect } from "react"
58
+ import { Auth } from '@taruvi-io/sdk'
59
+
60
+ export default function Login({ taruviClient }) {
61
+ const auth = new Auth(taruviClient)
62
+
63
+ useEffect(() => {
64
+ const checkAuthAndRedirect = async () => {
65
+ const isAuthenticated = await auth.isUserAuthenticated()
66
+
67
+ if (isAuthenticated) {
68
+ window.location.href = "/dashboard"
69
+ } else {
70
+ await auth.authenticateUser()
71
+ }
72
+ }
73
+
74
+ checkAuthAndRedirect()
75
+ }, [])
76
+
77
+ return <div>Checking authentication...</div>
78
+ }
79
+ ```
80
+
81
+ ---
82
+
83
+ ## User Service
84
+
85
+ ### Get Current User
86
+
87
+ ```typescript
88
+ import { User } from '@taruvi-io/sdk'
89
+
90
+ const user = new User(taruviClient)
91
+ const userData = await user.getUserData()
92
+
93
+ console.log(userData.data.username)
94
+ console.log(userData.data.email)
95
+ console.log(userData.data.full_name)
96
+ ```
97
+
98
+ ### Create User (Registration)
99
+
100
+ ```typescript
101
+ import { User } from '@taruvi-io/sdk'
102
+
103
+ const user = new User(taruviClient)
104
+
105
+ const newUser = await user.createUser({
106
+ username: "john_doe",
107
+ email: "john@example.com",
108
+ password: "secure123",
109
+ confirm_password: "secure123",
110
+ first_name: "John",
111
+ last_name: "Doe",
112
+ is_active: true,
113
+ is_staff: false,
114
+ attributes: ""
115
+ })
116
+ ```
117
+
118
+ ### Update User
119
+
120
+ ```typescript
121
+ const user = new User(taruviClient)
122
+
123
+ await user.updateUser("john_doe", {
124
+ email: "newemail@example.com",
125
+ first_name: "Johnny"
126
+ })
127
+ ```
128
+
129
+ ### Delete User
130
+
131
+ ```typescript
132
+ const user = new User(taruviClient)
133
+ await user.deleteUser("john_doe")
134
+ ```
135
+
136
+ ### Complete Registration Form Example
137
+
138
+ ```typescript
139
+ import { useState } from "react"
140
+ import { User } from "@taruvi-io/sdk"
141
+ import { useNavigate } from "react-router"
142
+
143
+ export default function Register({ taruviClient }) {
144
+ const navigate = useNavigate()
145
+ const [formData, setFormData] = useState({
146
+ username: "",
147
+ email: "",
148
+ password: "",
149
+ confirm_password: "",
150
+ first_name: "",
151
+ last_name: "",
152
+ is_active: true,
153
+ is_staff: false
154
+ })
155
+ const [error, setError] = useState("")
156
+ const [loading, setLoading] = useState(false)
157
+
158
+ const handleSubmit = async (e) => {
159
+ e.preventDefault()
160
+
161
+ if (formData.password !== formData.confirm_password) {
162
+ setError("Passwords do not match")
163
+ return
164
+ }
165
+
166
+ setLoading(true)
167
+ try {
168
+ const userClient = new User(taruviClient)
169
+ await userClient.createUser(formData)
170
+ navigate("/login")
171
+ } catch (err) {
172
+ setError(err.message || "Failed to create user")
173
+ } finally {
174
+ setLoading(false)
175
+ }
176
+ }
177
+
178
+ return (
179
+ <form onSubmit={handleSubmit}>
180
+ <input
181
+ name="username"
182
+ value={formData.username}
183
+ onChange={(e) => setFormData({...formData, username: e.target.value})}
184
+ required
185
+ />
186
+ {/* Add other fields */}
187
+ <button type="submit" disabled={loading}>
188
+ {loading ? "Creating..." : "Register"}
189
+ </button>
190
+ {error && <div>{error}</div>}
191
+ </form>
192
+ )
193
+ }
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Database Service (CRUD Operations)
199
+
200
+ ### Fetch All Records
201
+
202
+ ```typescript
203
+ import { Database } from '@taruvi-io/sdk'
204
+
205
+ const db = new Database(taruviClient)
206
+ const response = await db.from("accounts").execute()
207
+
208
+ if (response.data) {
209
+ console.log(response.data) // Array of records
210
+ }
211
+ ```
212
+
213
+ ### Fetch Single Record
214
+
215
+ ```typescript
216
+ const db = new Database(taruviClient)
217
+ const record = await db.from("accounts").get("record-id").execute()
218
+ ```
219
+
220
+ ### Update Record
221
+
222
+ ```typescript
223
+ const db = new Database(taruviClient)
224
+ await db.from("accounts").get("record-id").update({
225
+ name: "Updated Name",
226
+ status: "active"
227
+ }).execute()
228
+ ```
229
+
230
+ ### Delete Record
231
+
232
+ ```typescript
233
+ const db = new Database(taruviClient)
234
+ await db.from("accounts").delete("record-id").execute()
235
+ ```
236
+
237
+ ### Filter Records
238
+
239
+ ```typescript
240
+ const db = new Database(taruviClient)
241
+ const filtered = await db
242
+ .from("accounts")
243
+ .filter({
244
+ status: "active",
245
+ country: "USA"
246
+ })
247
+ .execute()
248
+ ```
249
+
250
+ ### Complete CRUD Example (CRM Table)
251
+
252
+ ```typescript
253
+ import { useEffect, useState } from 'react'
254
+ import { Database } from '@taruvi-io/sdk'
255
+
256
+ export default function CrmTable({ taruviClient }) {
257
+ const [contacts, setContacts] = useState([])
258
+
259
+ const fetchContacts = async () => {
260
+ const db = new Database(taruviClient)
261
+ const response = await db.from("accounts").execute()
262
+ if (response.data) {
263
+ setContacts(response.data)
264
+ }
265
+ }
266
+
267
+ useEffect(() => {
268
+ fetchContacts()
269
+ }, [])
270
+
271
+ const handleDelete = async (id) => {
272
+ const db = new Database(taruviClient)
273
+ await db.from("accounts").delete(id).execute()
274
+ fetchContacts() // Refresh
275
+ }
276
+
277
+ const handleUpdate = async (id, data) => {
278
+ const db = new Database(taruviClient)
279
+ await db.from("accounts").get(id).update(data).execute()
280
+ fetchContacts() // Refresh
281
+ }
282
+
283
+ return (
284
+ <table>
285
+ {contacts.map(contact => (
286
+ <tr key={contact.id}>
287
+ <td>{contact.name}</td>
288
+ <td>
289
+ <button onClick={() => handleUpdate(contact.id, { status: 'updated' })}>
290
+ Edit
291
+ </button>
292
+ <button onClick={() => handleDelete(contact.id)}>
293
+ Delete
294
+ </button>
295
+ </td>
296
+ </tr>
297
+ ))}
298
+ </table>
299
+ )
300
+ }
301
+ ```
302
+
303
+ ---
304
+
305
+ ## Storage Service (File Management)
306
+
307
+ ### List Files in Bucket
308
+
309
+ ```typescript
310
+ import { Storage } from '@taruvi-io/sdk'
311
+
312
+ const storage = new Storage(taruviClient, {})
313
+ const files = await storage.from("documents").execute()
314
+
315
+ console.log(files.data) // Array of file objects
316
+ ```
317
+
318
+ ### Upload Files
319
+
320
+ ```typescript
321
+ const storage = new Storage(taruviClient, {})
322
+
323
+ const filesData = {
324
+ files: [file1, file2], // File objects from input
325
+ metadatas: [{ name: "file1" }, { name: "file2" }],
326
+ paths: ["file1.pdf", "file2.pdf"]
327
+ }
328
+
329
+ await storage.from("documents").upload(filesData).execute()
330
+ ```
331
+
332
+ ### Delete File
333
+
334
+ ```typescript
335
+ const storage = new Storage(taruviClient, {})
336
+ await storage.from("documents").delete("path/to/file.pdf").execute()
337
+ ```
338
+
339
+ ### Update File Metadata
340
+
341
+ ```typescript
342
+ const storage = new Storage(taruviClient, {})
343
+ await storage
344
+ .from("documents")
345
+ .update("path/to/file.pdf", {
346
+ filename: "newname.pdf",
347
+ visibility: "public",
348
+ metadata: { category: "reports" }
349
+ })
350
+ .execute()
351
+ ```
352
+
353
+ ### Filter Files
354
+
355
+ ```typescript
356
+ const storage = new Storage(taruviClient, {})
357
+ const filtered = await storage
358
+ .from("documents")
359
+ .filter({
360
+ search: "invoice",
361
+ visibility: "public",
362
+ mimetype_category: "document",
363
+ min_size: 1024,
364
+ ordering: "-created_at"
365
+ })
366
+ .execute()
367
+ ```
368
+
369
+ ### Complete File Upload Example
370
+
371
+ ```typescript
372
+ import { useState, useRef } from 'react'
373
+ import { Storage } from '@taruvi-io/sdk'
374
+
375
+ export default function FileUploader({ taruviClient }) {
376
+ const [files, setFiles] = useState([])
377
+ const [uploading, setUploading] = useState(false)
378
+ const fileInputRef = useRef(null)
379
+
380
+ const handleFileSelect = (e) => {
381
+ const selectedFiles = Array.from(e.target.files)
382
+ setFiles(selectedFiles)
383
+ }
384
+
385
+ const uploadFiles = async () => {
386
+ if (files.length === 0) return
387
+
388
+ setUploading(true)
389
+ try {
390
+ const storage = new Storage(taruviClient, {})
391
+
392
+ const uploadData = {
393
+ files: files,
394
+ metadatas: files.map(f => ({ name: f.name })),
395
+ paths: files.map(f => f.name)
396
+ }
397
+
398
+ await storage.from("documents").upload(uploadData).execute()
399
+
400
+ alert("Upload successful!")
401
+ setFiles([])
402
+ } catch (error) {
403
+ alert("Upload failed: " + error.message)
404
+ } finally {
405
+ setUploading(false)
406
+ }
407
+ }
408
+
409
+ return (
410
+ <div>
411
+ <input
412
+ ref={fileInputRef}
413
+ type="file"
414
+ multiple
415
+ onChange={handleFileSelect}
416
+ />
417
+ <button onClick={uploadFiles} disabled={uploading || files.length === 0}>
418
+ {uploading ? "Uploading..." : `Upload ${files.length} file(s)`}
419
+ </button>
420
+ </div>
421
+ )
422
+ }
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Functions Service (Serverless)
428
+
429
+ ### Execute Function (Sync)
430
+
431
+ ```typescript
432
+ import { Functions } from '@taruvi-io/sdk'
433
+
434
+ const functions = new Functions(taruviClient)
435
+
436
+ const result = await functions.execute("my-function", {
437
+ async: false,
438
+ params: {
439
+ key1: "value1",
440
+ key2: 123
441
+ }
442
+ })
443
+
444
+ console.log(result.data) // Function response
445
+ ```
446
+
447
+ ### Execute Function (Async)
448
+
449
+ ```typescript
450
+ const functions = new Functions(taruviClient)
451
+
452
+ const result = await functions.execute("long-running-task", {
453
+ async: true,
454
+ params: { data: "value" }
455
+ })
456
+
457
+ console.log(result.invocation.invocation_id) // Track async execution
458
+ console.log(result.invocation.celery_task_id)
459
+ console.log(result.invocation.status)
460
+ ```
461
+
462
+ ### Complete Function Executor Example
463
+
464
+ ```typescript
465
+ import { useState } from 'react'
466
+ import { Functions } from '@taruvi-io/sdk'
467
+
468
+ export default function FunctionExecutor({ taruviClient }) {
469
+ const [functionSlug, setFunctionSlug] = useState("")
470
+ const [params, setParams] = useState({})
471
+ const [isAsync, setIsAsync] = useState(false)
472
+ const [result, setResult] = useState(null)
473
+ const [loading, setLoading] = useState(false)
474
+
475
+ const executeFunction = async () => {
476
+ setLoading(true)
477
+ try {
478
+ const functions = new Functions(taruviClient)
479
+ const response = await functions.execute(functionSlug, {
480
+ async: isAsync,
481
+ params: params
482
+ })
483
+ setResult(response)
484
+ } catch (error) {
485
+ console.error(error)
486
+ } finally {
487
+ setLoading(false)
488
+ }
489
+ }
490
+
491
+ return (
492
+ <div>
493
+ <input
494
+ placeholder="Function slug"
495
+ value={functionSlug}
496
+ onChange={(e) => setFunctionSlug(e.target.value)}
497
+ />
498
+ <label>
499
+ <input
500
+ type="checkbox"
501
+ checked={isAsync}
502
+ onChange={(e) => setIsAsync(e.target.checked)}
503
+ />
504
+ Async
505
+ </label>
506
+ <button onClick={executeFunction} disabled={loading}>
507
+ Execute
508
+ </button>
509
+ {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
510
+ </div>
511
+ )
512
+ }
513
+ ```
514
+
515
+ ---
516
+
517
+ ## Settings Service
518
+
519
+ ### Get Site Settings
520
+
521
+ ```typescript
522
+ import { Settings } from '@taruvi-io/sdk'
523
+
524
+ const settings = new Settings(taruviClient)
525
+ const config = await settings.get()
526
+
527
+ console.log(config) // Site configuration object
528
+ ```
529
+
530
+ ### Update Setting
531
+
532
+ ```typescript
533
+ const settings = new Settings(taruviClient)
534
+ await settings.update("setting_key", { value: "new_value" }).execute()
535
+ ```
536
+
537
+ ---
538
+
539
+ ## Secrets Service
540
+
541
+ ### List Secrets
542
+
543
+ ```typescript
544
+ import { Secrets } from '@taruvi-io/sdk'
545
+
546
+ const secrets = new Secrets(taruviClient)
547
+ const result = await secrets.list().execute()
548
+
549
+ console.log(result.items) // Array of secrets
550
+ ```
551
+
552
+ ### Update Secret
553
+
554
+ ```typescript
555
+ const secrets = new Secrets(taruviClient)
556
+
557
+ await secrets.update("MY_SECRET", {
558
+ value: {
559
+ hostname: "db.example.com",
560
+ port_number: 3306,
561
+ username: "admin",
562
+ password: "secret123"
563
+ },
564
+ tags: ["mysql", "production"],
565
+ secret_type: "Mysql"
566
+ }).execute()
567
+ ```
568
+
569
+ ---
570
+
571
+ ## Common Patterns
572
+
573
+ ### Loading States
574
+
575
+ ```typescript
576
+ const [data, setData] = useState(null)
577
+ const [loading, setLoading] = useState(true)
578
+ const [error, setError] = useState(null)
579
+
580
+ useEffect(() => {
581
+ const fetchData = async () => {
582
+ setLoading(true)
583
+ try {
584
+ const db = new Database(taruviClient)
585
+ const response = await db.from("table").execute()
586
+ setData(response.data)
587
+ } catch (err) {
588
+ setError(err.message)
589
+ } finally {
590
+ setLoading(false)
591
+ }
592
+ }
593
+ fetchData()
594
+ }, [])
595
+
596
+ if (loading) return <div>Loading...</div>
597
+ if (error) return <div>Error: {error}</div>
598
+ return <div>{/* Render data */}</div>
599
+ ```
600
+
601
+ ### Error Handling
602
+
603
+ ```typescript
604
+ try {
605
+ const user = new User(taruviClient)
606
+ await user.createUser(data)
607
+ } catch (error) {
608
+ if (error.response?.status === 400) {
609
+ console.error("Validation error:", error.response.data)
610
+ } else if (error.response?.status === 401) {
611
+ console.error("Unauthorized")
612
+ } else {
613
+ console.error("Unknown error:", error.message)
614
+ }
615
+ }
616
+ ```
617
+
618
+ ### Refresh Data After Mutation
619
+
620
+ ```typescript
621
+ const [items, setItems] = useState([])
622
+
623
+ const fetchItems = async () => {
624
+ const db = new Database(taruviClient)
625
+ const response = await db.from("items").execute()
626
+ setItems(response.data || [])
627
+ }
628
+
629
+ const deleteItem = async (id) => {
630
+ const db = new Database(taruviClient)
631
+ await db.from("items").delete(id).execute()
632
+ await fetchItems() // Refresh list
633
+ }
634
+
635
+ const updateItem = async (id, data) => {
636
+ const db = new Database(taruviClient)
637
+ await db.from("items").get(id).update(data).execute()
638
+ await fetchItems() // Refresh list
639
+ }
640
+ ```
641
+
642
+ ---
643
+
644
+ ## TypeScript Types
645
+
646
+ ### Import Types
647
+
648
+ ```typescript
649
+ import type {
650
+ TaruviConfig,
651
+ UserCreateRequest,
652
+ UserResponse,
653
+ UserDataResponse,
654
+ FunctionRequest,
655
+ FunctionResponse,
656
+ StorageFilters,
657
+ DatabaseFilters
658
+ } from '@taruvi-io/sdk'
659
+ ```
660
+
661
+ ### Type Usage
662
+
663
+ ```typescript
664
+ const config: TaruviConfig = {
665
+ apiKey: "key",
666
+ appSlug: "app",
667
+ baseUrl: "https://api.taruvi.cloud"
668
+ }
669
+
670
+ const userData: UserCreateRequest = {
671
+ username: "john",
672
+ email: "john@example.com",
673
+ password: "pass123",
674
+ confirm_password: "pass123",
675
+ first_name: "John",
676
+ last_name: "Doe"
677
+ }
678
+ ```
679
+
680
+ ---
681
+
682
+ ## Quick Reference
683
+
684
+ | Service | Import | Purpose |
685
+ |---------|--------|---------|
686
+ | `Client` | `import { Client }` | Main SDK client |
687
+ | `Auth` | `import { Auth }` | Authentication |
688
+ | `User` | `import { User }` | User management |
689
+ | `Database` | `import { Database }` | App data CRUD |
690
+ | `Storage` | `import { Storage }` | File management |
691
+ | `Functions` | `import { Functions }` | Serverless functions |
692
+ | `Settings` | `import { Settings }` | Site configuration |
693
+ | `Secrets` | `import { Secrets }` | Sensitive data |
694
+
695
+ ---
696
+
697
+ ## Chaining Pattern
698
+
699
+ All query-building services use method chaining:
700
+
701
+ ```typescript
702
+ // Database
703
+ await db.from("table").get("id").update(data).execute()
704
+ await db.from("table").filter({ status: "active" }).execute()
705
+
706
+ // Storage
707
+ await storage.from("bucket").delete("path").execute()
708
+ await storage.from("bucket").filter({ search: "query" }).execute()
709
+ ```
710
+
711
+ **Always call `.execute()` at the end to run the query!**
712
+
713
+ ---
714
+
715
+ ## Environment Variables
716
+
717
+ ```env
718
+ VITE_TARUVI_API_KEY=your-api-key
719
+ VITE_TARUVI_APP_SLUG=your-app
720
+ VITE_TARUVI_BASE_URL=https://taruvi-site.taruvi.cloud
721
+ ```
722
+
723
+ ```typescript
724
+ const client = new Client({
725
+ apiKey: import.meta.env.VITE_TARUVI_API_KEY,
726
+ appSlug: import.meta.env.VITE_TARUVI_APP_SLUG,
727
+ baseUrl: import.meta.env.VITE_TARUVI_BASE_URL
728
+ })
729
+ ```
730
+
731
+ ---
732
+
733
+ **Generated from production code examples • Last updated: 2025-12-15**