Les serveurs de production lisent, téléchargent et écrivent souvent des fichiers vers des services de stockage d'objets compatibles S3 au lieu du système de fichiers local. Historiquement, cela signifie que les API de système de fichiers local que vous utilisez en développement ne peuvent pas être utilisées en production. Lorsque vous utilisez Bun, les choses sont différentes.
L'API S3 de Bun est rapide
Bun fournit des liaisons natives rapides pour interagir avec les services de stockage d'objets compatibles S3. L'API S3 de Bun est conçue pour être simple et similaire aux API Response et Blob de fetch (comme les API de système de fichiers local de Bun).
import { s3, write, S3Client } from "bun";
// Bun.s3 lit les variables d'environnement pour les identifiants
// file() retourne une référence paresseuse à un fichier sur S3
const metadata = s3.file("123.json");
// Télécharger depuis S3 en tant que JSON
const data = await metadata.json();
// Télécharger vers S3
await write(metadata, JSON.stringify({ name: "John", age: 30 }));
// Pré-signer une URL (synchrone - aucune requête réseau nécessaire)
const url = metadata.presign({
acl: "public-read",
expiresIn: 60 * 60 * 24, // 1 jour
});
// Supprimer le fichier
await metadata.delete();S3 est le système de fichiers internet de facto standard. L'API S3 de Bun fonctionne avec les services de stockage compatibles S3 comme :
- AWS S3
- Cloudflare R2
- DigitalOcean Spaces
- MinIO
- Backblaze B2
- ...et tout autre service de stockage compatible S3
Utilisation de base
Il existe plusieurs façons d'interagir avec l'API S3 de Bun.
Bun.S3Client & Bun.s3
Bun.s3 est équivalent à new Bun.S3Client(), s'appuyant sur les variables d'environnement pour les identifiants.
Pour définir explicitement les identifiants, passez-les au constructeur Bun.S3Client.
import { S3Client } from "bun";
const client = new S3Client({
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// sessionToken: "..."
// acl: "public-read",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
// endpoint: "https://<region>.digitaloceanspaces.com", // DigitalOcean Spaces
// endpoint: "http://localhost:9000", // MinIO
});
// Bun.s3 est un singleton global équivalent à `new Bun.S3Client()`Travailler avec des fichiers S3
La méthode file dans S3Client retourne une référence paresseuse à un fichier sur S3.
// Une référence paresseuse à un fichier sur S3
const s3file: S3File = client.file("123.json");Comme Bun.file(path), la méthode file de S3Client est synchrone. Elle n'effectue aucune requête réseau tant que vous n'appelez pas une méthode qui dépend d'une requête réseau.
Lire des fichiers depuis S3
Si vous avez utilisé l'API fetch, vous connaissez les API Response et Blob. S3File étend Blob. Les mêmes méthodes qui fonctionnent sur Blob fonctionnent également sur S3File.
// Lire un S3File en tant que texte
const text = await s3file.text();
// Lire un S3File en tant que JSON
const json = await s3file.json();
// Lire un S3File en tant que ArrayBuffer
const buffer = await s3file.arrayBuffer();
// Obtenir uniquement les 1024 premiers octets
const partial = await s3file.slice(0, 1024).text();
// Streamer le fichier
const stream = s3file.stream();
for await (const chunk of stream) {
console.log(chunk);
}Optimisation de la mémoire
Les méthodes comme text(), json(), bytes(), ou arrayBuffer() évitent de dupliquer la chaîne ou les octets en mémoire lorsque c'est possible.
Si le texte se trouve être en ASCII, Bun transfère directement la chaîne vers JavaScriptCore (le moteur) sans transcodage et sans dupliquer la chaîne en mémoire. Lorsque vous utilisez .bytes() ou .arrayBuffer(), cela évite également de dupliquer les octets en mémoire.
Ces méthodes auxiliaires simplifient non seulement l'API, elles la rendent également plus rapide.
Écriture et téléchargement de fichiers vers S3
L'écriture vers S3 est tout aussi simple.
// Écrire une chaîne (remplaçant le fichier)
await s3file.write("Hello World!");
// Écrire un Buffer (remplaçant le fichier)
await s3file.write(Buffer.from("Hello World!"));
// Écrire une Response (remplaçant le fichier)
await s3file.write(new Response("Hello World!"));
// Écrire avec un type de contenu
await s3file.write(JSON.stringify({ name: "John", age: 30 }), {
type: "application/json",
});
// Écrire en utilisant un writer (streaming)
const writer = s3file.writer({ type: "application/json" });
writer.write("Hello");
writer.write(" World!");
await writer.end();
// Écrire en utilisant Bun.write
await Bun.write(s3file, "Hello World!");Travailler avec des fichiers volumineux (streams)
Bun gère automatiquement les téléchargements multipart pour les fichiers volumineux et fournit des capacités de streaming. La même API qui fonctionne pour les fichiers locaux fonctionne également pour les fichiers S3.
// Écrire un fichier volumineux
const bigFile = Buffer.alloc(10 * 1024 * 1024); // 10 Mo
const writer = s3file.writer({
// Réessayer automatiquement en cas d'erreurs réseau jusqu'à 3 fois
retry: 3,
// Mettre en file d'attente jusqu'à 10 requêtes à la fois
queueSize: 10,
// Télécharger par blocs de 5 Mo
partSize: 5 * 1024 * 1024,
});
for (let i = 0; i < 10; i++) {
writer.write(bigFile);
await writer.flush();
}
await writer.end();Pré-signature d'URL
Lorsque votre service de production doit permettre aux utilisateurs de télécharger des fichiers sur votre serveur, il est souvent plus fiable pour l'utilisateur de télécharger directement vers S3 au lieu que votre serveur agisse comme intermédiaire.
Pour faciliter cela, vous pouvez pré-signer des URL pour des fichiers S3. Cela génère une URL avec une signature qui permet à un utilisateur de télécharger en toute sécurité ce fichier spécifique vers S3, sans exposer vos identifiants ni leur accorder un accès inutile à votre bucket.
Le comportement par défaut est de générer une URL GET qui expire dans 24 heures. Bun tente de déduire le type de contenu à partir de l'extension du fichier. Si la déduction n'est pas possible, il utilisera application/octet-stream par défaut.
import { s3 } from "bun";
// Générer une URL pré-signée qui expire dans 24 heures (par défaut)
const download = s3.presign("my-file.txt"); // GET, text/plain, expire dans 24 heures
const upload = s3.presign("my-file", {
expiresIn: 3600, // 1 heure
method: "PUT",
type: "application/json", // Pas d'extension pour déduire, donc nous pouvons spécifier que le type de contenu est JSON
});
// Vous pouvez appeler .presign() sur une référence de fichier, mais évitez de le faire
// sauf si vous avez déjà une référence (pour éviter l'utilisation de mémoire).
const myFile = s3.file("my-file.txt");
const presignedFile = myFile.presign({
expiresIn: 3600, // 1 heure
});Définir des ACL
Pour définir une ACL (liste de contrôle d'accès) sur une URL pré-signée, passez l'option acl :
const url = s3file.presign({
acl: "public-read",
expiresIn: 3600,
});Vous pouvez passer l'une des ACL suivantes :
| ACL | Explication |
|---|---|
"public-read" | L'objet est lisible par le public. |
"private" | L'objet est lisible uniquement par le propriétaire du bucket. |
"public-read-write" | L'objet est lisible et inscriptible par le public. |
"authenticated-read" | L'objet est lisible par le propriétaire du bucket et les utilisateurs authentifiés. |
"aws-exec-read" | L'objet est lisible par le compte AWS qui a fait la requête. |
"bucket-owner-read" | L'objet est lisible par le propriétaire du bucket. |
"bucket-owner-full-control" | L'objet est lisible et inscriptible par le propriétaire du bucket. |
"log-delivery-write" | L'objet est inscriptible par les services AWS utilisés pour la livraison des journaux. |
Expiration des URL
Pour définir un délai d'expiration pour une URL pré-signée, passez l'option expiresIn.
const url = s3file.presign({
// Secondes
expiresIn: 3600, // 1 heure
// liste de contrôle d'accès
acl: "public-read",
// méthode HTTP
method: "PUT",
});method
Pour définir la méthode HTTP pour une URL pré-signée, passez l'option method.
const url = s3file.presign({
method: "PUT",
// method: "DELETE",
// method: "GET",
// method: "HEAD",
// method: "POST",
// method: "PUT",
});new Response(S3File)
Pour rediriger rapidement les utilisateurs vers une URL pré-signée pour un fichier S3, passez une instance S3File à un objet Response comme corps.
Cela redirigera automatiquement l'utilisateur vers l'URL pré-signée pour le fichier S3, vous économisant ainsi la mémoire, le temps et la bande passante nécessaires pour télécharger le fichier sur votre serveur et le renvoyer à l'utilisateur.
const response = new Response(s3file);
console.log(response);Response (0 KB) {
ok: false,
url: "",
status: 302,
statusText: "",
headers: Headers {
"location": "https://<account-id>.r2.cloudflarestorage.com/...",
},
redirected: true,
bodyUsed: false
}Prise en charge des services compatibles S3
L'implémentation S3 de Bun fonctionne avec tout service de stockage compatible S3. Spécifiez simplement le endpoint approprié :
Utilisation de Bun S3Client avec AWS S3
AWS S3 est le paramètre par défaut. Vous pouvez également passer une option region au lieu d'une option endpoint pour AWS S3.
import { S3Client } from "bun";
// AWS S3
const s3 = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// region: "us-east-1",
});Utilisation de Bun S3Client avec Google Cloud Storage
Pour utiliser le client S3 de Bun avec Google Cloud Storage, définissez endpoint sur "https://storage.googleapis.com" dans le constructeur S3Client.
import { S3Client } from "bun";
// Google Cloud Storage
const gcs = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
endpoint: "https://storage.googleapis.com",
});Utilisation de Bun S3Client avec Cloudflare R2
Pour utiliser le client S3 de Bun avec Cloudflare R2, définissez endpoint sur le endpoint R2 dans le constructeur S3Client. Le endpoint R2 inclut votre ID de compte.
import { S3Client } from "bun";
// CloudFlare R2
const r2 = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
endpoint: "https://<account-id>.r2.cloudflarestorage.com",
});Utilisation de Bun S3Client avec DigitalOcean Spaces
Pour utiliser le client S3 de Bun avec DigitalOcean Spaces, définissez endpoint sur le endpoint DigitalOcean Spaces dans le constructeur S3Client.
import { S3Client } from "bun";
const spaces = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
// region: "nyc3",
endpoint: "https://<region>.digitaloceanspaces.com",
});Utilisation de Bun S3Client avec MinIO
Pour utiliser le client S3 de Bun avec MinIO, définissez endpoint sur l'URL sur laquelle MinIO s'exécute dans le constructeur S3Client.
import { S3Client } from "bun";
const minio = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
// Assurez-vous d'utiliser l'URL de endpoint correcte
// Ce n'est peut-être pas localhost en production !
endpoint: "http://localhost:9000",
});Utilisation de Bun S3Client avec supabase
Pour utiliser le client S3 de Bun avec supabase, définissez endpoint sur le endpoint supabase dans le constructeur S3Client. Le endpoint supabase inclut votre ID de compte et le chemin /storage/v1/s3. Assurez-vous d'activer la connexion via le protocole S3 dans le tableau de bord supabase à l'adresse https://supabase.com/dashboard/project/<account-id>/settings/storage et de définir la région indiquée dans la même section.
import { S3Client } from "bun";
const supabase = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
region: "us-west-1",
endpoint: "https://<account-id>.supabase.co/storage/v1/s3/storage",
});Utilisation de Bun S3Client avec des endpoints de style Virtual Hosted S3
Lors de l'utilisation d'un endpoint de style Virtual Hosted S3, vous devez définir l'option virtualHostedStyle sur true.
NOTE
- Si vous ne spécifiez pas de endpoint, Bun déterminera automatiquement le endpoint AWS S3 en utilisant la région et le bucket fournis. - Si aucune région n'est spécifiée, Bun utilise us-east-1 par défaut. - Si vous fournissez explicitement un endpoint, vous n'avez pas besoin de spécifier un nom de bucket.import { S3Client } from "bun";
// Endpoint AWS S3 déduit de la région et du bucket
const s3 = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
bucket: "my-bucket",
virtualHostedStyle: true,
// endpoint: "https://my-bucket.s3.us-east-1.amazonaws.com",
// region: "us-east-1",
});
// AWS S3
const s3WithEndpoint = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
endpoint: "https://<bucket-name>.s3.<region>.amazonaws.com",
virtualHostedStyle: true,
});
// Cloudflare R2
const r2WithEndpoint = new S3Client({
accessKeyId: "access-key",
secretAccessKey: "secret-key",
endpoint: "https://<bucket-name>.<account-id>.r2.cloudflarestorage.com",
virtualHostedStyle: true,
});Identifiants
Les identifiants sont l'une des parties les plus difficiles de l'utilisation de S3, et nous avons essayé de rendre cela aussi simple que possible. Par défaut, Bun lit les variables d'environnement suivantes pour les identifiants.
| Nom de l'option | Variable d'environnement |
|---|---|
accessKeyId | S3_ACCESS_KEY_ID |
secretAccessKey | S3_SECRET_ACCESS_KEY |
region | S3_REGION |
endpoint | S3_ENDPOINT |
bucket | S3_BUCKET |
sessionToken | S3_SESSION_TOKEN |
Si la variable d'environnement S3_* n'est pas définie, Bun vérifiera également la variable d'environnement AWS_* pour chacune des options ci-dessus.
| Nom de l'option | Variable d'environnement de repli |
|---|---|
accessKeyId | AWS_ACCESS_KEY_ID |
secretAccessKey | AWS_SECRET_ACCESS_KEY |
region | AWS_REGION |
endpoint | AWS_ENDPOINT |
bucket | AWS_BUCKET |
sessionToken | AWS_SESSION_TOKEN |
Ces variables d'environnement sont lues depuis les fichiers .env ou depuis l'environnement du processus au moment de l'initialisation (process.env n'est pas utilisé pour cela).
Ces valeurs par défaut sont remplacées par les options que vous passez à s3.file(credentials), new Bun.S3Client(credentials), ou l'une des méthodes qui acceptent des identifiants. Donc si, par exemple, vous utilisez les mêmes identifiants pour différents buckets, vous pouvez définir les identifiants une fois dans votre fichier .env puis passer bucket: "my-bucket" à la fonction s3.file() sans avoir à spécifier à nouveau tous les identifiants.
Objets S3Client
Lorsque vous n'utilisez pas de variables d'environnement ou que vous utilisez plusieurs buckets, vous pouvez créer un objet S3Client pour définir explicitement les identifiants.
import { S3Client } from "bun";
const client = new S3Client({
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// sessionToken: "..."
endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
// endpoint: "http://localhost:9000", // MinIO
});
// Écrire en utilisant une Response
await file.write(new Response("Hello World!"));
// Pré-signer une URL
const url = file.presign({
expiresIn: 60 * 60 * 24, // 1 jour
acl: "public-read",
});
// Supprimer le fichier
await file.delete();S3Client.prototype.write
Pour télécharger ou écrire un fichier vers S3, appelez write sur l'instance S3Client.
const client = new Bun.S3Client({
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
endpoint: "https://s3.us-east-1.amazonaws.com",
bucket: "my-bucket",
});
await client.write("my-file.txt", "Hello World!");
await client.write("my-file.txt", new Response("Hello World!"));
// équivalent à
// await client.file("my-file.txt").write("Hello World!");S3Client.prototype.delete
Pour supprimer un fichier de S3, appelez delete sur l'instance S3Client.
const client = new Bun.S3Client({
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
});
await client.delete("my-file.txt");
// équivalent à
// await client.file("my-file.txt").delete();S3Client.prototype.exists
Pour vérifier si un fichier existe dans S3, appelez exists sur l'instance S3Client.
const client = new Bun.S3Client({
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
});
const exists = await client.exists("my-file.txt");
// équivalent à
// const exists = await client.file("my-file.txt").exists();S3File
Les instances S3File sont créées en appelant la méthode d'instance S3Client ou la fonction s3.file(). Comme Bun.file(), les instances S3File sont paresseuses. Elles ne se réfèrent pas à quelque chose qui existe nécessairement au moment de la création. C'est pourquoi toutes les méthodes qui n'impliquent pas de requêtes réseau sont entièrement synchrones.
interface S3File extends Blob {
slice(start: number, end?: number): S3File;
exists(): Promise<boolean>;
unlink(): Promise<void>;
presign(options: S3Options): string;
text(): Promise<string>;
json(): Promise<any>;
bytes(): Promise<Uint8Array>;
arrayBuffer(): Promise<ArrayBuffer>;
stream(options: S3Options): ReadableStream;
write(
data: string | Uint8Array | ArrayBuffer | Blob | ReadableStream | Response | Request,
options?: BlobPropertyBag,
): Promise<number>;
exists(options?: S3Options): Promise<boolean>;
unlink(options?: S3Options): Promise<void>;
delete(options?: S3Options): Promise<void>;
presign(options?: S3Options): string;
stat(options?: S3Options): Promise<S3Stat>;
/**
* La taille n'est pas disponible de manière synchrone car elle nécessite une requête réseau.
*
* @deprecated Utilisez `stat()` à la place.
*/
size: NaN;
// ... plus omis pour brièveté
}Comme Bun.file(), S3File étend Blob, donc toutes les méthodes disponibles sur Blob sont également disponibles sur S3File. La même API pour lire des données depuis un fichier local est également disponible pour lire des données depuis S3.
| Méthode | Sortie |
|---|---|
await s3File.text() | string |
await s3File.bytes() | Uint8Array |
await s3File.json() | JSON |
await s3File.stream() | ReadableStream |
await s3File.arrayBuffer() | ArrayBuffer |
Cela signifie que l'utilisation d'instances S3File avec fetch(), Response, et d'autres API web qui acceptent des instances Blob fonctionne simplement.
Lectures partielles avec slice
Pour lire une plage partielle d'un fichier, vous pouvez utiliser la méthode slice.
const partial = s3file.slice(0, 1024);
// Lire la plage partielle en tant que Uint8Array
const bytes = await partial.bytes();
// Lire la plage partielle en tant que chaîne
const text = await partial.text();En interne, cela fonctionne en utilisant l'en-tête HTTP Range pour demander uniquement les octets que vous souhaitez. Cette méthode slice est la même que Blob.prototype.slice.
Suppression de fichiers depuis S3
Pour supprimer un fichier de S3, vous pouvez utiliser la méthode delete.
await s3file.delete();
// await s3File.unlink();delete est la même chose que unlink.
Codes d'erreur
Lorsque l'API S3 de Bun lance une erreur, elle aura une propriété code qui correspond à l'une des valeurs suivantes :
ERR_S3_MISSING_CREDENTIALSERR_S3_INVALID_METHODERR_S3_INVALID_PATHERR_S3_INVALID_ENDPOINTERR_S3_INVALID_SIGNATUREERR_S3_INVALID_SESSION_TOKEN
Lorsque le service de stockage d'objets S3 retourne une erreur (c'est-à-dire, pas Bun), ce sera une instance S3Error (une instance Error avec le nom "S3Error").
Méthodes statiques S3Client
La classe S3Client fournit plusieurs méthodes statiques pour interagir avec S3.
S3Client.write (statique)
Pour écrire des données directement vers un chemin dans le bucket, vous pouvez utiliser la méthode statique S3Client.write.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
};
// Écrire une chaîne
await S3Client.write("my-file.txt", "Hello World");
// Écrire du JSON avec un type
await S3Client.write("data.json", JSON.stringify({ hello: "world" }), {
...credentials,
type: "application/json",
});
// Écrire depuis fetch
const res = await fetch("https://example.com/data");
await S3Client.write("data.bin", res, credentials);
// Écrire avec ACL
await S3Client.write("public.html", html, {
...credentials,
acl: "public-read",
type: "text/html",
});Ceci est équivalent à appeler new S3Client(credentials).write("my-file.txt", "Hello World").
S3Client.presign (statique)
Pour générer une URL pré-signée pour un fichier S3, vous pouvez utiliser la méthode statique S3Client.presign.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
};
const url = S3Client.presign("my-file.txt", {
...credentials,
expiresIn: 3600,
});Ceci est équivalent à appeler new S3Client(credentials).presign("my-file.txt", { expiresIn: 3600 }).
S3Client.list (statique)
Pour lister certains ou tous (jusqu'à 1 000) objets dans un bucket, vous pouvez utiliser la méthode statique S3Client.list.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
};
// Lister (jusqu'à) 1000 objets dans le bucket
const allObjects = await S3Client.list(null, credentials);
// Lister (jusqu'à) 500 objets sous le préfixe `uploads/`, avec le champ owner pour chaque objet
const uploads = await S3Client.list({
prefix: 'uploads/',
maxKeys: 500,
fetchOwner: true,
}, credentials);
// Vérifier si plus de résultats sont disponibles
if (uploads.isTruncated) {
// Lister le lot suivant d'objets sous le préfixe `uploads/`
const moreUploads = await S3Client.list({
prefix: 'uploads/',
maxKeys: 500,
startAfter: uploads.contents!.at(-1).key
fetchOwner: true,
}, credentials);
}Ceci est équivalent à appeler new S3Client(credentials).list().
S3Client.exists (statique)
Pour vérifier si un fichier S3 existe, vous pouvez utiliser la méthode statique S3Client.exists.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
};
const exists = await S3Client.exists("my-file.txt", credentials);La même méthode fonctionne également sur les instances S3File.
import { s3 } from "bun";
const s3file = s3.file("my-file.txt", {
// ...credentials,
});
const exists = await s3file.exists();S3Client.size (statique)
Pour vérifier rapidement la taille d'un fichier S3 sans le télécharger, vous pouvez utiliser la méthode statique S3Client.size.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
};
const bytes = await S3Client.size("my-file.txt", credentials);Ceci est équivalent à appeler new S3Client(credentials).size("my-file.txt").
S3Client.stat (statique)
Pour obtenir la taille, l'etag et d'autres métadonnées d'un fichier S3, vous pouvez utiliser la méthode statique S3Client.stat.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
// endpoint: "https://<account-id>.r2.cloudflarestorage.com", // Cloudflare R2
};
const stat = await S3Client.stat("my-file.txt", credentials);{
etag: "\"7a30b741503c0b461cc14157e2df4ad8\"",
lastModified: 2025-01-07T00:19:10.000Z,
size: 1024,
type: "text/plain;charset=utf-8",
}S3Client.delete (statique)
Pour supprimer un fichier S3, vous pouvez utiliser la méthode statique S3Client.delete.
import { S3Client } from "bun";
const credentials = {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
bucket: "my-bucket",
// endpoint: "https://s3.us-east-1.amazonaws.com",
};
await S3Client.delete("my-file.txt", credentials);
// équivalent à
// await new S3Client(credentials).delete("my-file.txt");
// S3Client.unlink est un alias de S3Client.delete
await S3Client.unlink("my-file.txt", credentials);Protocole s3://
Pour faciliter l'utilisation du même code pour les fichiers locaux et les fichiers S3, le protocole s3:// est pris en charge dans fetch et Bun.file().
const response = await fetch("s3://my-bucket/my-file.txt");
const file = Bun.file("s3://my-bucket/my-file.txt");Vous pouvez également passer des options s3 aux fonctions fetch et Bun.file.
const response = await fetch("s3://my-bucket/my-file.txt", {
s3: {
accessKeyId: "your-access-key",
secretAccessKey: "your-secret-key",
endpoint: "https://s3.us-east-1.amazonaws.com",
},
headers: {
range: "bytes=0-1023",
},
});UTF-8, UTF-16 et BOM (byte order mark)
Comme Response et Blob, S3File suppose l'encodage UTF-8 par défaut.
Lors de l'appel de l'une des méthodes text() ou json() sur un S3File :
- Lorsqu'une marque d'ordre des octets UTF-16 (BOM) est détectée, elle sera traitée comme UTF-16. JavaScriptCore prend nativement en charge UTF-16, il saute donc le processus de transcodage UTF-8 (et supprime le BOM). C'est plutôt bon, mais cela signifie que si vous avez des caractères de paires substitut invalides dans votre chaîne UTF-16, ils seront transmis à JavaScriptCore (comme le code source).
- Lorsqu'un BOM UTF-8 est détecté, il est supprimé avant que la chaîne ne soit transmise à JavaScriptCore et les points de code UTF-8 invalides sont remplacés par le caractère de remplacement Unicode (
\uFFFD). - UTF-32 n'est pas pris en charge.