Client SDK (@storagedb/client)
Rasmiy JavaScript/TypeScript SDK storagedb-ga ulanish, ma'lumotlar bazasi operatsiyalari, autentifikatsiya, storage, va realtime funksiyalari uchun.
O'rnatish va Boshlang'ich sozlama
StorageDB client SDK @storagedb/client npm paketidagi barcha zarorat qiladigan funksiyalarni taqdim etadi. Loyihangizga qo'shing:
npm i @storagedb/client
Client yaratish uchun createClient() funksiyasini ishlating. U Supabase-js ga o'xshaydi. Api URL va API kalit (anon yoki service) zarur:
TypeScript/JavaScript: const { createClient } = require('@storagedb/client'); const db = createClient('https://storage.identify.uz/v1/<REF>', '<ANON_KEY>');
Barcha amallar promise-based. Natija { data, error, ... } qaytaradi. Tizimsiz xatolarni boshqarish uchun har doim error ni tekshiring.
import { createClient } from '@storagedb/client';
const db = createClient(
'https://storage.identify.uz/v1/my-project-ref',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // anon_key
);
// Endi siz db.from(), db.auth, db.storage ishlatishingiz mumkin.curl -X GET 'https://storage.identify.uz/v1/my-ref/rest/v1/todos?select=*' \ -H 'apikey: service_key_value' \ -H 'authorization: Bearer service_key_value'
Jadval so'rovlari (Database Queries)
StorageDB barcha jadvallar bilan PostgREST uslubida ishlashni qo'llab-quvvatlaydi. db.from('table_name') orqali QueryBuilder olasiz. U select, insert, update, delete amallarini qo'llab-quvvatlaydi.
SELECT: .select('*|col1,col2,...', { count: 'exact'|'estimated' })
INSERT: .insert(data) — bir yoki ko'p qatorlarni qo'shadi.
UPDATE: .update(changes) — WHERE shartiga mos qatorlarni o'zgartiradi.
DELETE: .delete() — qatorlarni o'chiradi.
UPSERT: .upsert(data) — mavjud bo'lsa yangilaydi, yo'q bo'lsa qo'shadi.
Filtrlar: .eq(), .neq(), .gt(), .gte(), .lt(), .lte(), .like(), .ilike(), .in(), .is(), .not(), .or(), .textSearch()
Tartib va sahifalash: .order('col', { ascending: false }), .limit(n), .range(from, to), .single()
const { data: todos, error, count } = await db
.from('todos')
.select('*, author(*)', { count: 'exact' })
.eq('done', false)
.order('id', { ascending: false })
.limit(20);
if (error) console.error('Xato:', error.message);
else console.log(`${count} adaslash topildi:`, todos);curl -X GET 'https://storage.identify.uz/v1/my-ref/rest/v1/todos?select=*%2Cauthor(*)&done=eq.false&order=id.desc&limit=20&count=exact' \ -H 'apikey: <ANON_KEY>' \ -H 'authorization: Bearer <ANON_KEY>'
const { data: newTodo, error } = await db
.from('todos')
.insert({
title: 'Dars yozish',
done: false,
user_id: 'usr_123'
})
.single(); // bitta qator qaytaradi
if (error) console.error('Qo\'shish xatosi:', error.message);
else console.log('Qo\'shildi:', newTodo);curl -X POST 'https://storage.identify.uz/v1/my-ref/rest/v1/todos' \
-H 'apikey: <ANON_KEY>' \
-H 'content-type: application/json' \
-H 'prefer: return=representation' \
-d '{"title":"Dars yozish","done":false,"user_id":"usr_123"}'const { data: updated, error } = await db
.from('todos')
.update({ done: true, updated_at: new Date() })
.eq('id', 42)
.single();
if (error) console.error('Update xatosi:', error.message);
else console.log('O\'zgartirildi:', updated);const { data: result, error } = await db
.from('users')
.upsert({
id: 'usr_123',
email: 'user@example.com',
name: 'Ali'
})
.single();
if (error) console.error('Upsert xatosi:', error.message);
else console.log('Natija:', result);// Bir nechta shartlar bilan qidiruv
const { data, error } = await db
.from('posts')
.select('*')
.gte('created_at', '2024-01-01')
.lt('created_at', '2025-01-01')
.ilike('title', '%O\'zbek%') // katalog-siz
.in('status', ['draft', 'published'])
.eq('author_id', 'usr_42')
.order('created_at', { ascending: false });
console.log(`${data?.length} post topildi`);// Postgres full-text search
const { data: results, error } = await db
.from('articles')
.select('id, title, body')
.textSearch('body', 'database search query', { type: 'websearch' })
.limit(10);
if (error) console.error('Qidiruv xatosi:', error.message);
else console.log('Natijalar:', results);Autentifikatsiya (Auth)
StorageDB o'z authentication xizmati bilan birga keladi. db.auth orqali sign up, sign in, sign out, parol tiklash va admin amallarini bajarishingiz mumkin.
signUp: yangi foydalanuvchi ro'yxatdan o'tkazadi. Session yo'q bo'lishi mumkin (email tasdiqlash shart bo'lsa).
signInWithPassword: emailu va parol bilan kirish.
refreshSession: refresh token orqali access token yangilash.
signOut: chiqish va sessiyani tozalash.
getUser: joriy foydalanuvchining ma'lumotlarini olish (access token kerak).
resetPasswordForEmail: parol tiklovchi link yuborish.
admin.* — service_key bilan faqat admin amallar (foydalanuvchilar bo'yicha).
const { data, error } = await db.auth.signUp({
email: 'newuser@example.com',
password: 'SecurePassword123',
data: {
full_name: 'Ali Karimov',
avatar_url: 'https://example.com/avatar.jpg'
}
});
if (error) {
console.error('Ro\'yxatdan o\'tish xatosi:', error.message);
} else {
console.log('Yangi foydalanuvchi:', data.user);
console.log('Sessiya:', data.session); // null bo'lishi mumkin
}curl -X POST 'https://storage.identify.uz/v1/my-ref/auth/v1/signup' \
-H 'apikey: <ANON_KEY>' \
-H 'content-type: application/json' \
-d '{
"email": "newuser@example.com",
"password": "SecurePassword123",
"data": {"full_name": "Ali Karimov"}
}'const { data: session, error } = await db.auth.signInWithPassword({
email: 'user@example.com',
password: 'UserPassword123'
});
if (error) {
console.error('Kirish xatosi:', error.message);
} else {
console.log('Access token:', session.access_token);
console.log('Foydalanuvchi:', session.user);
// Sessiya avtomatik saqlanadi
}curl -X POST 'https://storage.identify.uz/v1/my-ref/auth/v1/token?grant_type=password' \
-H 'apikey: <ANON_KEY>' \
-H 'content-type: application/json' \
-d '{
"email": "user@example.com",
"password": "UserPassword123"
}'const { data: user, error } = await db.auth.getUser();
if (error) {
console.error('Foydalanuvchini olishda xato:', error.message);
} else if (user) {
console.log('Foydalanuvchi ID:', user.id);
console.log('Email:', user.email);
console.log('Metadata:', user.user_metadata);
}const { data: newSession, error } = await db.auth.refreshSession();
if (error) {
console.error('Yangilash xatosi:', error.message);
} else {
console.log('Yangi access token:', newSession.access_token);
// Avtomatik saqlandi
}const { error } = await db.auth.signOut();
if (error) {
console.error('Chiqish xatosi:', error.message);
} else {
console.log('Sessiya to\'g\'ri tuhtatildi');
// Foydalanuvchi bilan bog'langan barcha tokenlar bekor qilindi
}const { error } = await db.auth.resetPasswordForEmail('user@example.com');
if (error) {
console.error('Reset link yuborishda xato:', error.message);
} else {
console.log('Reset link foydalanuvchi emailiga yuborildi');
}// Service key bilan yaratilgan client kerak
const adminDb = createClient('https://...', 'service_key_value');
const { data: users, error } = await adminDb.auth.admin.listUsers();
if (error) {
console.error('Admin xatosi:', error.message);
} else {
console.log('Jami foydalanuvchilar:', users.length);
users.forEach(u => console.log(`- ${u.email}`));
}Storage (Fayllar)
StorageDB storage xizmati S3-ga o'xshash API taqdim etadi. Bucket yaratish, fayllarni yuklash/yuklab olish, public URL olish, va signed URL yaratish mumkin.
db.storage.from(bucket_name) — bucket API olish.
bucket.upload(path, data, opts) — faylni yuklash.
bucket.download(path) — faylni yuklab olish.
bucket.remove(path) — faylni o'chirish.
bucket.getPublicUrl(path) — public bucket uchun to'g'ridan-to'g'ri URL.
bucket.createSignedUrl(path, expiresIn) — vaqtli ro'yxatdan o'tgan URL (private bucket uchun).
db.storage.createBucket(id, opts) — yangi bucket yaratish (admin).
const fileData = new Blob(['Fayl mazmuni'], { type: 'text/plain' });
const { data, error } = await db.storage
.from('my-bucket')
.upload('users/user123/avatar.jpg', fileData, {
contentType: 'image/jpeg'
});
if (error) {
console.error('Upload xatosi:', error.message);
} else {
console.log('Yuklandi:', data.Key); // 'users/user123/avatar.jpg'
}curl -X POST 'https://storage.identify.uz/v1/my-ref/storage/v1/object/my-bucket/users/avatar.jpg' \ -H 'apikey: <ANON_KEY>' \ -H 'content-type: image/jpeg' \ --data-binary @/path/to/avatar.jpg
const { data: blob, error } = await db.storage
.from('my-bucket')
.download('users/user123/avatar.jpg');
if (error) {
console.error('Download xatosi:', error.message);
} else {
// blob `Blob` tipida
const url = URL.createObjectURL(blob);
console.log('Fayl hazirlandi:', url);
}const { publicUrl } = db.storage
.from('public-files')
.getPublicUrl('documents/report.pdf');
console.log('Ochiq URL:', publicUrl);
// https://storage.identify.uz/v1/my-ref/storage/v1/public/public-files/documents/report.pdfconst { data, error } = await db.storage
.from('private-bucket')
.createSignedUrl('secure-docs/contract.pdf', 3600); // 1 soat
if (error) {
console.error('Signed URL xatosi:', error.message);
} else {
console.log('Imzolangan URL:', data.signedUrl);
// Bu URL 1 soat davomida yaroqli
}curl -X POST 'https://storage.identify.uz/v1/my-ref/storage/v1/object/sign/private-bucket/secure-docs/contract.pdf' \
-H 'apikey: <SERVICE_KEY>' \
-H 'content-type: application/json' \
-d '{"expiresIn": 3600}'const { error } = await db.storage
.from('my-bucket')
.remove('users/user123/old-avatar.jpg');
if (error) {
console.error('O\'chirish xatosi:', error.message);
} else {
console.log('Fayl o\'chirildi');
}const adminDb = createClient('https://...', 'service_key_value');
const { data, error } = await adminDb.storage.createBucket('new-bucket', {
public: false // Private bucket
});
if (error) {
console.error('Bucket yaratish xatosi:', error.message);
} else {
console.log('Bucket yaratildi:', data.id);
}RPC (Postgres funksiyalari)
StorageDB bazasida yaratilgan Postgres funksiyalari (stored procedures, functions) RPC orqali chaqiriladi.
db.rpc(function_name, args) — funksiyani chaqirish.
args — funksiya parametrlari (object).
Natija { data, error } qaytaradi. data ning tipi funksiya qaytaradigan qiymati bilan bog'liq.
const { data: result, error } = await db.rpc('calculate_total', {
user_id: 'usr_123',
month: 'January'
});
if (error) {
console.error('RPC xatosi:', error.message);
} else {
console.log('Natija:', result); // server tomondan qaytarilgan qiymat
}curl -X POST 'https://storage.identify.uz/v1/my-ref/rest/v1/rpc/calculate_total' \
-H 'apikey: <ANON_KEY>' \
-H 'content-type: application/json' \
-d '{"user_id": "usr_123", "month": "January"}'interface UserStats {
count: number;
average_age: number;
last_login: string;
}
const { data: stats, error } = await db.rpc<UserStats>('get_user_stats', {
department: 'sales'
});
if (error) {
console.error('Stats xatosi:', error.message);
} else {
console.log(`${stats?.count} foydalanuvchi, O'rta yosh: ${stats?.average_age}`);
}Realtime (Websocket subscription)
StorageDB realtime xizmati PostgreSQL o'zgarishlari, broadcast xabarlari, va presence (kimlar onlayn ekanini) qo'llab-quvvatlaydi.
db.channel(name) — kanal yaratish.
on(event, callback) — Postgres change events: INSERT, UPDATE, DELETE, yoki '*'.
onBroadcast(event, callback) — custom broadcast xabarlari.
onPresenceSync(cb) — presence state yangilanishi.
onPresenceJoin(cb) — foydalanuvchi online bo'lsa.
onPresenceLeave(cb) — foydalanuvchi offline bo'lsa.
subscribe(onStatus?) — WebSocket ulanishni boshlash.
send(event, payload) — topic'ga broadcast yuborish.
track(state) — o'z presence holatini belgilash.
unsubscribe() — disconnectni to'xtatish.
const channel = db.channel('todos')
.on('INSERT', (payload) => {
console.log('Yangi todo qo\'shildi:', payload.record);
})
.on('UPDATE', (payload) => {
console.log('Todo o\'zgartirildi:', payload.record);
console.log('Eski qiymat:', payload.old_record);
})
.on('DELETE', (payload) => {
console.log('Todo o\'chirildi, ID:', payload.record?.id);
})
.subscribe((status) => {
console.log('Kanal holati:', status); // 'SUBSCRIBED' yoki 'ERROR'
});
// Chiqish uchun:
// channel.unsubscribe();const room = db.channel('collaboration-room')
.onBroadcast('cursor', (message) => {
console.log(`Foydalanuvchi kursorin pozitsiyasi:`, message.payload);
})
.subscribe();
// Xabar yuborish
room.send('cursor', { x: 150, y: 200, user_id: 'usr_42' });const chat = db.channel('chat-room')
.onPresenceSync(() => {
const state = chat.presenceState();
console.log('Onlayn foydalanuvchilar:', state);
})
.onPresenceJoin((event) => {
console.log(`${event.key} online bo'ldi`, event.state);
})
.onPresenceLeave((event) => {
console.log(`${event.key} offline bo'ldi`);
})
.subscribe();
// O'z holatini belgilash
chat.track({
user_id: 'usr_123',
name: 'Ali',
status: 'typing'
});
// O'z holatini yangilash
chat.track({ user_id: 'usr_123', name: 'Ali', status: 'away' });
// Chiqish
chat.untrack();Xatolar boshqarish va TypeScript
Barcha SDK operatsiyalari { data, error } formatda qaytaradi. Xatolarni har doim tekshiring.
error null bo'lsa, operatsiya muvaffaqiyatli. Aks holda error.message xatoning tafsilotini o'z ichiga oladi.
QueryResult<T> turini import qilib, select, insert, update, delete amallarining turini belgilashingiz mumkin.
TypeScript barcha callback va parameter turlarni avtomatik bilan tekshiradi.
Service key maxfiy — server tomonda yoki environment variable sifatida saqlang. Anon key brauzer qatlamida foydalanishga xavfsiz.
const { data, error, count } = await db
.from('posts')
.select('*', { count: 'exact' })
.eq('status', 'published');
if (error) {
console.error('Query xatosi:', error.message);
console.error('Kod:', error.code); // 'PGRST...' yoki boshqa
} else if (data) {
console.log(`${count || 0} published post topildi`);
data.forEach(post => console.log(`- ${post.title}`));
} else {
console.log('Ma\'lumot yo\'q');
}interface Todo {
id: number;
title: string;
done: boolean;
created_at: string;
user_id: string;
}
// Strongly typed query
const { data: todos, error } = await db
.from<Todo>('todos')
.select('*')
.eq('user_id', 'usr_123');
if (!error && todos) {
// TypeScript biladi todos Todo[] ekanini
todos.forEach(todo => {
console.log(`✓ ${todo.title}`);
});
}// .env.local
// NEXT_PUBLIC_API_URL=https://storage.identify.uz/v1/my-ref
// NEXT_PUBLIC_ANON_KEY=eyJ...
// SERVICE_KEY=eyJ... (server tomonda faqat)
// lib/db.ts
import { createClient } from '@storagedb/client';
const apiUrl = process.env.NEXT_PUBLIC_API_URL || '';
const key = typeof window === 'undefined'
? process.env.SERVICE_KEY || process.env.NEXT_PUBLIC_ANON_KEY || ''
: process.env.NEXT_PUBLIC_ANON_KEY || '';
export const db = createClient(apiUrl, key);