dstndatabase
v0.2.1
Published
Client SDK for the DSTN Database REST API - rows, RPCs, project auth (signup/signin/magic link) and storage (buckets, upload, files).
Maintainers
Readme
DSTN Database
Client SDK pour l'API REST DSTN Database — lire, insérer, mettre à jour et supprimer des lignes, et appeler des routines, avec des clés anon (lecture) et service_role (écriture).
Le package est publié sous deux noms équivalents :
npm install dstndatabasenpm install dstndatabase-client
Installation
npm install dstndatabase
# ou
npm install dstndatabase-clientZéro dépendance, compatible navigateur (fetch) et Node.js ≥ 18.
Récupérer vos clés
Dans le dashboard DSTN : Projet → API. Vous y trouvez :
projectUrl— la base du projet, ex.https://api.example.com/api/projects/mon-projetanonKey— lecture seule (GET) — utilisable dans le navigateurserviceRoleKey— accès complet (POST/PATCH/DELETE/RPC) — côté serveur uniquement
Utilisation rapide
import { SupavoltClient } from 'dstndatabase';
const client = new SupavoltClient({
baseUrl: 'https://api.example.com/api/projects/mon-projet',
anonKey: 'eyJ...', // clé anon (lecture)
serviceRoleKey: process.env.SERVICE_ROLE_KEY, // optionnel, serveur seulement
});
// Lire des lignes (clé anon)
const products = await client.getRows('products', {
limit: 10,
order: 'created_at.desc',
filters: { category: 'tshirt' },
});
console.log(products);
// Insérer une ligne (clé service_role, côté serveur)
await client.insertRow('products', { name: 'Hoodie', price: 29.99 });
// Mettre à jour par clé primaire
await client.updateRow('products', 42, { price: 24.99 });
// Supprimer
await client.deleteRow('products', 42);
// Appeler une routine SQL
await client.rpc('get_products_by_category', { category: 'tshirt' });En ESM / React, vous pouvez aussi instancier une seule fois et l'exporter :
// lib/supavolt.ts
import { SupavoltClient } from 'dstndatabase';
export const supavolt = new SupavoltClient(
import.meta.env.VITE_SUPAVOLT_URL!,
import.meta.env.VITE_SUPAVOLT_ANON!,
import.meta.env.VITE_SUPAVOLT_SERVICE_ROLE, // optionnel
);API
new SupavoltClient(config) ou new SupavoltClient(baseUrl, anonKey, serviceRoleKey?)
| Argument | Type | Description |
| --- | --- | --- |
| config.baseUrl | string | URL de base du projet (.../api/projects/{slug}) |
| config.anonKey | string | Clé lecture seule (GET) |
| config.serviceRoleKey | string | Clé écriture (optionnelle, serveur) |
getRows<T>(table, params?) → Promise<T[]>
| Paramètre | Type | Description |
| --- | --- | --- |
| select | string \| string[] | Colonnes à renvoyer |
| limit | number | Max de lignes (défaut 100) |
| offset | number | Pagination |
| order | string \| {column, direction} | ex. "price.asc" ou {column:'price', direction:'desc'} |
| filters | Record<string, string\|number\|boolean> | Égalité stricte : { category: 'tshirt' } |
insertRow<T>(table, data) → Promise<{message, data}>
Insère une ligne. Retourne 201 avec { message, data }.
updateRow<T>(table, id, data) → Promise<{message, data}>
Met à jour la ligne dont la clé primaire vaut id (détectée automatiquement côté serveur).
deleteRow(table, id) → Promise<{message}>
Supprime la ligne dont la clé primaire vaut id.
rpc<T>(routineName, args?) → Promise<T>
Appelle une routine SQL stockée du projet.
Authentification des utilisateurs du projet
Endpoints publics — aucune clé API requise :
// Inscription
const { user, accessToken } = await client.signup('[email protected]', 'motdepasse');
// Connexion
const { accessToken } = await client.signin('[email protected]', 'motdepasse');
// Lien magique
const { magicLinkUrl } = await client.signInWithMagicLink('[email protected]');
const token = magicLinkUrl.split('token=')[1];
const session = await client.verifyMagicLink(token);| Méthode | Signature | Description |
| --- | --- | --- |
| signup(email, password) | Promise<{user, accessToken}> | Crée un compte (auth_users du projet) |
| signin(email, password) | Promise<{user, accessToken}> | Connecte un compte existant |
| signInWithMagicLink(email) | Promise<{message, magicLinkUrl}> | Envoie un lien magique |
| verifyMagicLink(token) | Promise<{user, accessToken}> | Échange le token du lien contre une session |
L'accessToken est un JWT signé avec le secret du projet (auth_jwt_secret).
Stockage
// Lister les buckets (clé anon)
const buckets = await client.listBuckets();
// Créer un bucket (service_role, serveur)
await client.createBucket('avatars', { access: 'public' });
// Navigateur — passer un File/Blob
await client.upload('avatars', input.files[0]);
// Node — passer un Buffer + nom de fichier
await client.upload('avatars', await fs.readFile('logo.png'), 'logo.png', 'image/png');
// Objets + URL signée
const objects = await client.listObjects(bucketId);
const { url } = await client.getSignedUrl(objectId);
// Suppressions (service_role, serveur)
await client.deleteObject(objectId);
await client.deleteBucket(bucketId);| Méthode | Signature | Clé |
| --- | --- | --- |
| listBuckets() | Promise<StorageBucket[]> | anon |
| createBucket(name, {access?}) | Promise<StorageBucket> | service_role |
| deleteBucket(bucketId) | Promise<{message}> | service_role |
| listObjects(bucketId) | Promise<StorageObject[]> | anon |
| upload(bucketId, file, name?, mimeType?) | Promise<StorageObject> | service_role |
| deleteObject(objectId) | Promise<{message}> | service_role |
| getSignedUrl(objectId) | Promise<{url}> | anon |
Les fichiers des buckets publics sont servis directement par l'installation
(…/storage-files/…), les buckets privés via l'URL signée.
Gestion des erreurs
Toutes les méthodes rejettent une SupavoltError avec status et message :
import { SupavoltClient, SupavoltError } from 'dstndatabase';
try {
await client.getRows('users');
} catch (e) {
if (e instanceof SupavoltError) {
console.error(e.status, e.message);
}
}| Status | Signification |
| --- | --- |
| 401 | Clé manquante ou invalide |
| 403 | Mauvaise clé (ex. anon sur une écriture) ou slug ne correspondant pas |
| 400 | Requête invalide (ex. table sans clé primaire) |
| 404 | Projet/table introuvable |
| 429 | Quota mensuel du plan atteint (maxApiCallsPerMonth) |
Sécurité
serviceRoleKeyne doit jamais être exposé côté client (navigateur, mobile). Utilisez-la uniquement dans votre backend (Node, etc.).- Les écritures (
insertRow,updateRow,deleteRow,rpc) refusent la cléanon(403).
Endpoints couverts
| Méthode | Endpoint | SDK |
| --- | --- | --- |
| GET | {base}/rest/{table} | getRows |
| POST | {base}/rest/{table} | insertRow |
| PATCH | {base}/rest/{table}/{id} | updateRow |
| DELETE | {base}/rest/{table}/{id} | deleteRow |
| POST | {base}/rpc/{routine} | rpc |
| POST | {base}/auth/signup | signup |
| POST | {base}/auth/signin | signin |
| POST | {base}/auth/magic-link | signInWithMagicLink |
| GET | {base}/auth/magic-link/verify?token= | verifyMagicLink |
| GET | {base}/storage/buckets | listBuckets |
| POST | {base}/storage/buckets | createBucket |
| DELETE | {base}/storage/buckets/{id} | deleteBucket |
| GET | {base}/storage/buckets/{id}/objects | listObjects |
| POST | {base}/storage/buckets/{id}/upload | upload |
| DELETE | {base}/storage/objects/{id} | deleteObject |
| GET | {base}/storage/objects/{id}/signed-url | getSignedUrl |
License
MIT
