@profiya/bucket
v1.0.3
Published
Librería ligera para Cloudflare R2 usando AWS SDK
Readme
@profiya/bucket
Librería ligera y moderna para manejar Cloudflare R2 usando AWS SDK v3.
📦 Instalación
npm install @profiya/bucket @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner🚀 Uso Rápido
import { Bucket, S3Client } from '@profiya/bucket';
const S3 = new S3Client({
endpoint: "Your endpoint",
credentials: {
accessKeyId: "Your accessKeyId",
secretAccessKey: "Your secretAccessKey",
},
});
// Inicializar bucket
const bucket = new Bucket(S3, "bucket", "endpoint");
// Configurar URL pública (opcional)
bucket.provideBucketPublicUrl('https://cdn.midominio.com');
// Subir archivo
const result = await bucket.upload(
fileBuffer,
'carpeta/archivo.pdf',
'application/pdf',
{ userId: '123' }
);
console.log(result.publicUrl);
// https://cdn.midominio.com/carpeta/archivo.pdf📖 Ejemplos
Subir desde Node.js
import { readFileSync } from 'fs';
import { Bucket, S3Client } from '@profiya/bucket';
const S3 = new S3Client({
endpoint: "Your endpoint",
credentials: {
accessKeyId: "Your accessKeyId",
secretAccessKey: "Your secretAccessKey",
},
});
// Inicializar bucket
const bucket = new Bucket(S3, "bucket", "endpoint");
const file = readFileSync('./documento.pdf');
const result = await bucket.upload(
file,
'documentos/documento.pdf',
'application/pdf'
);
console.log('Subido:', result.objectKey);Subir desde Express
import express from 'express';
import multer from 'multer';
import { Bucket, S3Client } from '@profiya/bucket';
const app = express();
const upload = multer({ storage: multer.memoryStorage() });
const S3 = new S3Client({
endpoint: "Your endpoint",
credentials: {
accessKeyId: "Your accessKeyId",
secretAccessKey: "Your secretAccessKey",
},
});
// Inicializar bucket
const bucket = new Bucket(S3, "bucket", "endpoint");
app.post('/upload', upload.single('file'), async (req, res) => {
const result = await bucket.upload(
req.file!.buffer,
`uploads/${Date.now()}-${req.file!.originalname}`,
req.file!.mimetype
);
res.json({ url: result.publicUrl });
});Descargar archivo
const object = await bucket.getObject('archivo.pdf');
// Node.js - guardar a disco
import { createWriteStream } from 'fs';
const writeStream = createWriteStream('./descargado.pdf');
object.Body.pipe(writeStream);
// Express - enviar al cliente
app.get('/download/:key', async (req, res) => {
const object = await bucket.getObject(req.params.key);
res.set('Content-Type', object.ContentType!);
object.Body.pipe(res);
});URL Firmada (Signed URL)
// Generar URL temporal (1 hora)
const url = await bucket.getObjectSignedUrl('private/documento.pdf', 3600);
console.log(url);
// https://account.r2.cloudflarestorage.com/bucket/private/documento.pdf?X-Amz-...
// Esta URL es válida por 3600 segundos (1 hora)
// Después de eso, expira automáticamenteListar archivos
const result = await bucket.listObjects(100);
for (const obj of result.objects) {
console.log(`${obj.key} - ${obj.size} bytes`);
}
// Paginación
if (result.isTruncated) {
const nextPage = await bucket.listObjects(100, result.nextContinuationToken);
}Eliminar archivos
// Eliminar uno
await bucket.deleteObject('archivo-viejo.pdf');
// Eliminar múltiples
await bucket.deleteObjects([
'temp/file1.pdf',
'temp/file2.pdf',
'temp/file3.pdf'
]);Copiar archivo
await bucket.copyObject(
'original/documento.pdf',
'backup/documento-copia.pdf'
);Verificar existencia
const exists = await bucket.objectExists('archivo.pdf');
if (exists) {
console.log('El archivo existe');
} else {
console.log('Archivo no encontrado');
}Métodos
upload(contents, destination, mimeType?, metadata?)
Sube un archivo.
Parámetros:
contents:Buffer | Uint8Array | string | Readabledestination:string- Ruta en el bucketmimeType?:string- Tipo MIMEmetadata?:Record<string, string>- Metadata personalizada
Retorna: Promise<UploadFileResponse>
uploadStream(contents, destination, mimeType?, metadata?, onProgress?)
Sube con multipart upload y progreso.
Retorna: Objeto con Body (stream), ContentType, ContentLength, etc.
deleteObject(objectKey)
Elimina un objeto.
headObject(objectKey)
Obtiene metadata sin descargar.
listObjects(maxResults?, continuationToken?)
Lista objetos con paginación.
copyObject(sourceKey, destinationKey)
Copia un objeto.
objectExists(objectKey)
Verifica si existe.
getObjectSignedUrl(objectKey, expiresIn)
Genera URL firmada para GET.
putObjectSignedUrl(objectKey, expiresIn)
Genera URL firmada para PUT.
provideBucketPublicUrl(url)
Configura URL pública.
getPublicUrls()
Obtiene URLs públicas configuradas.
getObjectPublicUrls(objectKey)
Obtiene URLs públicas de un objeto.
getCorsPolicies()
Obtiene políticas CORS del bucket.
🔧 Utilidades
import {
sanitizeFileName,
generateUniqueFileName,
validateMimeType,
validateFileSize,
formatBytes,
getFileExtension,
isImage,
isDocument
} from '@profiya/bucket';
// Generar nombre único
const uniqueName = generateUniqueFileName('mi-archivo.pdf');
// mi-archivo-1704123456789-abc123.pdf
// Formatear bytes
formatBytes(1024000);
// "1000 KB"
// Validar tipo
validateMimeType('image/jpeg', ['image/jpeg', 'image/png']);
// true
// Validar tamaño (max 10MB)
validateFileSize(fileSize, 10 * 1024 * 1024);
// true/falseUsa con dotenv:
import 'dotenv/config';
import { Bucket, S3Client } from '@profiya/bucket';
const S3 = new S3Client({
endpoint: "Your endpoint",
credentials: {
accessKeyId: "Your accessKeyId",
secretAccessKey: "Your secretAccessKey",
},
});
const bucket = new Bucket(S3, "bucket", "endpoint");📝 TypeScript
La librería incluye tipos completos:
import type {
Bucket,
BucketConfig,
UploadFileResponse,
HeadObjectResponse,
ObjectListResponse,
CORSPolicy
} from '@profiya/bucket';🏗️ Build
# Desarrollo (watch mode)
npm run dev
# Build de producción
npm run build
# Los archivos generados estarán en ./dist/
# - index.mjs (ESM)
# - index.cjs (CommonJS)
# - index.umd.js (UMD)
# - index.d.ts (TypeScript types)📦 Formatos disponibles
// ESM (import)
import { Bucket } from '@profiya/bucket';
// CommonJS (require)
const { Bucket } = require('@profiya/bucket');
// UMD (navegador)
<script src="https://unpkg.com/@profiya/bucket"></script>
<script>
const bucket = new R2Bucket.Bucket({...});
</script>🤝 Contribuir
- Fork el repositorio
- Crea tu rama:
git checkout -b feature/nueva-caracteristica - Commit:
git commit -am 'Agrega nueva característica' - Push:
git push origin feature/nueva-caracteristica - Abre un Pull Request
📄 Licencia
MIT
