npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@trinex/s3m-client

v1.0.1

Published

Client library for s3m

Readme

s3m-client

Una libreria TypeScript per l'upload di file tramite presigned URL su Cloudflare R2.

Caratteristiche

  • ✅ Upload di file tramite presigned URL
  • ✅ Supporto per progress tracking
  • ✅ Gestione degli errori robusta
  • ✅ Supporto per abort signal
  • ✅ Configurazione tramite file JSON
  • ✅ Scritto in TypeScript con tipizzazione completa
  • ✅ Zero dipendenze

Installazione

npm install s3m-client

Configurazione

Crea un file s3m.config.json nella root del tuo progetto:

{
  "baseUrl": "https://your-backend-api.com"
}

Utilizzo

Utilizzo Base

import { createFileUploader } from 's3m-client';

// Carica la configurazione automaticamente
const uploader = await createFileUploader();

// Upload di un file
const fileInput = document.getElementById('file') as HTMLInputElement;
const file = fileInput.files[0];

const result = await uploader.uploadFile(file);

if (result.success) {
  console.log('File caricato con successo!', result.url);
} else {
  console.error('Errore durante l\'upload:', result.error);
}

Utilizzo con Configurazione Manuale

import { createFileUploaderWithConfig } from 's3m-client';

const uploader = createFileUploaderWithConfig({
  baseUrl: 'https://your-backend-api.com'
});

const result = await uploader.uploadFile(file);

Utilizzo con Progress Tracking

import { createFileUploader } from 's3m-client';

const uploader = await createFileUploader();

const result = await uploader.uploadFile(file, {
  onProgress: (progress) => {
    console.log(`Upload progress: ${progress.percentage}%`);
    console.log(`${progress.loaded} / ${progress.total} bytes`);
  }
});

Utilizzo con Abort Signal

import { createFileUploader } from 's3m-client';

const uploader = await createFileUploader();
const controller = new AbortController();

// Annulla l'upload dopo 10 secondi
setTimeout(() => controller.abort(), 10000);

const result = await uploader.uploadFile(file, {
  signal: controller.signal,
  onProgress: (progress) => {
    console.log(`Upload: ${progress.percentage}%`);
  }
});

Utilizzo con Gestione Errori Avanzata

import { createFileUploader, FileUploaderError } from 's3m-client';

try {
  const uploader = await createFileUploader();
  const result = await uploader.uploadFile(file);
  
  if (!result.success) {
    throw new Error(result.error);
  }
  
  console.log('Upload completato:', result.url);
} catch (error) {
  if (error instanceof FileUploaderError) {
    console.error('Errore del file uploader:', error.message);
    console.error('Status code:', error.statusCode);
    console.error('Response:', error.response);
  } else {
    console.error('Errore generico:', error);
  }
}

API Reference

Tipi

FileUploaderConfig

interface FileUploaderConfig {
  baseUrl: string;
}

UploadOptions

interface UploadOptions {
  onProgress?: (progress: UploadProgress) => void;
  signal?: AbortSignal;
}

UploadProgress

interface UploadProgress {
  loaded: number;
  total: number;
  percentage: number;
}

UploadResult

interface UploadResult {
  success: boolean;
  url?: string;
  error?: string;
}

Classi

FileUploaderService

La classe principale per gestire l'upload dei file.

uploadFile(file: File, options?: UploadOptions): Promise<UploadResult>

Carica un file utilizzando il flusso presigned URL.

Parametri:

  • file: Il file da caricare
  • options: Opzioni di upload (opzionale)

Ritorna: Una Promise che risolve con il risultato dell'upload.

FileUploaderError

Classe di errore personalizzata che estende Error.

Proprietà:

  • statusCode?: number - Codice di stato HTTP se disponibile
  • response?: any - Risposta del server se disponibile

Funzioni

createFileUploader(): Promise<FileUploaderService>

Crea un'istanza del servizio caricando automaticamente la configurazione da s3m.config.json.

createFileUploaderWithConfig(config: FileUploaderConfig): FileUploaderService

Crea un'istanza del servizio con una configurazione fornita manualmente.

loadConfig(): Promise<FileUploaderConfig>

Carica la configurazione dal file s3m.config.json.

Come Funziona

  1. Estrazione Metadati: La libreria estrae i metadati del file (nome, dimensione, tipo, ultima modifica)
  2. Richiesta Presigned URL: Effettua una richiesta GET a /s3m/presigned-url con i metadati come query parameters
  3. Upload su R2: Utilizza il presigned URL ricevuto per caricare il file direttamente su Cloudflare R2
  4. Progress Tracking: Monitora il progresso dell'upload tramite XMLHttpRequest

Requisiti Backend

Il tuo backend deve implementare l'endpoint:

GET api/s3m/upload?key={filename}

Risposta attesa (200 OK):

{
  "url": "https://presigned-url-for-r2..."
}

Esempi Completi

Esempio React

import React, { useState } from 'react';
import { createFileUploader, UploadProgress } from 's3m-client';

function FileUploadComponent() {
  const [progress, setProgress] = useState<UploadProgress | null>(null);
  const [uploading, setUploading] = useState(false);

  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    setUploading(true);
    try {
      const uploader = await createFileUploader();
      
      const result = await uploader.uploadFile(file, {
        onProgress: setProgress
      });

      if (result.success) {
        alert('File caricato con successo!');
      } else {
        alert(`Errore: ${result.error}`);
      }
    } catch (error) {
      alert(`Errore: ${error}`);
    } finally {
      setUploading(false);
      setProgress(null);
    }
  };

  return (
    <div>
      <input 
        type="file" 
        onChange={handleFileUpload} 
        disabled={uploading}
      />
      {progress && (
        <div>
          Progress: {progress.percentage}%
        </div>
      )}
    </div>
  );
}

Esempio Vanilla JavaScript

<!DOCTYPE html>
<html>
<head>
    <title>File Upload</title>
</head>
<body>
    <input type="file" id="fileInput">
    <button onclick="uploadFile()">Upload</button>
    <div id="progress"></div>

    <script type="module">
        import { createFileUploader } from './dist/index.js';

        window.uploadFile = async function() {
            const fileInput = document.getElementById('fileInput');
            const progressDiv = document.getElementById('progress');
            const file = fileInput.files[0];
            
            if (!file) return;

            try {
                const uploader = await createFileUploader();
                
                const result = await uploader.uploadFile(file, {
                    onProgress: (progress) => {
                        progressDiv.textContent = `${progress.percentage}%`;
                    }
                });

                if (result.success) {
                    alert('Upload completato!');
                } else {
                    alert('Errore: ' + result.error);
                }
            } catch (error) {
                alert('Errore: ' + error.message);
            }
        };
    </script>
</body>
</html>

Build

npm run build

Questo comando genera i file JavaScript e le definizioni TypeScript nella cartella dist/.

Licenza

MIT

Contributi

I contributi sono benvenuti! Apri una issue o una pull request su GitHub.