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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@applica-software-guru/crud-client

v1.1.46

Published

Libreria per l'accesso ai servizi REST di Applica.

Readme

Libreria per l'accesso ai servizi REST di Applica.

| Info | Dettagli | | --------------- | ------------------------------------------------------- | | Ultima versione | 1.0.* | | Autore | Roberto Conte Rosito | | Repository | https://bitbucket.org/applicaguru/crud-client | | Pipeline | https://bitbucket.org/applicaguru/crud-client/pipelines |

Prefazione

La libreria @applica-software-guru/crud-client è un client REST che consente l'accesso ai servizi REST di Applica. La sua implementazione si basa sui principi e le linee guida definite all'interno del progetto React-Admin

Installazione

Per installare la libreria:

npm install @applica-software-guru/crud-client

Configurazione

Configurazione Base

import { ApplicaDataProvider, createAttachmentsParser } from '@applica-software-guru/crud-client';
import { createAuthProvider, MemoryStorage } from '@applica-software-guru/iam-client';
import { HttpError } from 'ra-core';

const apiUrl = 'https://api.applica.guru/api';
const storage = new MemoryStorage();
const authProvider = createAuthProvider({ apiUrl, storage });

const dataProvider = new ApplicaDataProvider({
  apiUrl,
  HttpErrorClass: HttpError,
  getHeaders: async () => await authProvider.getHeaders(),
  getToken: async () => await authProvider.getToken(),
  attachmentsParser: createAttachmentsParser()
});

Configurazione Avanzata

const dataProvider = new ApplicaDataProvider({
  apiUrl: 'https://api.applica.guru/api',
  HttpErrorClass: HttpError,
  getHeaders: async () => await authProvider.getHeaders(),
  getToken: async () => await authProvider.getToken(),
  attachmentsParser: createAttachmentsParser(),

  // Opzionale: modalità mobile
  mobile: false, // default: false

  // Opzionale: timeout di default per tutte le richieste (in millisecondi)
  timeout: 30000, // default: 30000 (30 secondi)

  // Opzionale: funzione per preparare i dati prima dell'invio
  prepareData: (data, resource, params) => {
    // Personalizza i dati prima dell'invio
    return data;
  }
});

Configurazione per Applicazioni Mobile

Se lavori su un'applicazione mobile devi necessariamente creare il data provider in questo modo:

const dataProvider = new ApplicaDataProvider({
  apiUrl,
  // ... altre configurazioni
  mobile: true
});

In modalità mobile, il dataProvider adotta comportamenti diversi per le chiamate di creazione e modifica dei record:

  • Utilizza chiamate REST pure invece di FormData
  • La gestione degli upload dei file viene gestita separatamente

API Reference

Il dataProvider implementa tutte le operazioni CRUD standard di React-Admin, estese con funzionalità specifiche di Applica.

🕒 Timeout Support: Tutte le operazioni supportano un parametro timeout opzionale che sovrascrive il timeout globale configurato nel provider. Questo permette di personalizzare il timeout per ogni singola richiesta in base alle necessità specifiche dell'operazione.

Operazioni CRUD Standard

getList

Recupera una lista paginata di record con supporto per filtri e ordinamento.

const result = await dataProvider.getList('entities/user', {
  pagination: {
    page: 1,
    perPage: 10
  },
  sort: {
    field: 'name',
    order: 'ASC' // o 'DESC'
  },
  filter: {
    name__like: 'Giovanni',
    id__gt: 10,
    active__is: true,
    keyword: 'search term' // ricerca globale
  },
  // Opzionale: timeout specifico per questa richiesta
  timeout: 5000 // 5 secondi
});

// Risultato:
// {
//   data: [...], // array di record
//   total: 150   // numero totale di record
// }

Operatori di filtro supportati:

  • __like: ricerca LIKE
  • __eq: uguaglianza esatta
  • __gt: maggiore di
  • __gte: maggiore o uguale
  • __lt: minore di
  • __lte: minore o uguale
  • __is: valore booleano
  • __in: valore in array

getOne

Recupera un singolo record per ID.

const result = await dataProvider.getOne('entities/user', {
  id: 1,
  timeout: 3000 // timeout opzionale
});

// Risultato:
// {
//   data: { id: 1, name: 'Roberto', ... }
// }

getMany

Recupera più record specificando i loro ID.

const result = await dataProvider.getMany('entities/user', {
  ids: [1, 2, 3],
  timeout: 4000
});

// Risultato:
// {
//   data: [
//     { id: 1, name: 'Roberto' },
//     { id: 2, name: 'Mario' },
//     { id: 3, name: 'Luigi' }
//   ]
// }

getManyReference

Recupera record che referenziano un altro record.

const result = await dataProvider.getManyReference('entities/post', {
  target: 'author_id',
  id: 123, // ID dell'autore
  pagination: { page: 1, perPage: 10 },
  sort: { field: 'title', order: 'ASC' },
  filter: { published: true },
  timeout: 6000
});

create

Crea un nuovo record. Supporta upload di file e allegati.

const result = await dataProvider.create('entities/user', {
  data: {
    name: 'Nuovo Utente',
    email: '[email protected]',
    avatar: fileObject, // File object per upload
    documents: [file1, file2] // Array di file
  },
  timeout: 10000 // timeout più lungo per upload
});

// Risultato:
// {
//   data: { id: 456, name: 'Nuovo Utente', ... }
// }

update

Aggiorna un record esistente.

const result = await dataProvider.update('entities/user', {
  id: 1,
  data: {
    name: 'Nome Aggiornato',
    email: '[email protected]'
  },
  previousData: { id: 1, name: 'Vecchio Nome', ... }, // richiesto da React-Admin
  timeout: 8000
});

updateMany

Aggiorna più record contemporaneamente.

const result = await dataProvider.updateMany('entities/user', {
  ids: [1, 2, 3],
  data: {
    status: 'active'
  },
  rows: [
    // dati specifici per ogni record (opzionale)
    { id: 1, name: 'Roberto' },
    { id: 2, name: 'Mario' },
    { id: 3, name: 'Luigi' }
  ],
  timeout: 15000
});

delete

Elimina un record.

const result = await dataProvider.delete('entities/user', {
  id: 1,
  timeout: 5000
});

deleteMany

Elimina più record contemporaneamente.

const result = await dataProvider.deleteMany('entities/user', {
  ids: [1, 2, 3],
  timeout: 10000
});

Operazioni Estese

get

Esegue una chiamata GET generica. Supporta timeout configurabile per richiesta.

// Chiamata GET di base
const result = await dataProvider.get('users', {
  name: 'Roberto',
  active: true
});

// Con timeout personalizzato
const result = await dataProvider.get('users', {
  name: 'Roberto',
  active: true,
  timeout: 5000 // 5 secondi per questa richiesta
});

post

Esegue una chiamata POST generica. Supporta timeout configurabile per richiesta.

import { stringify } from 'query-string';

// Chiamata POST di base
const result = await dataProvider.post(`users?${stringify({ k: 'f' })}`, {
  id: 1,
  name: 'Roberto'
});

// Con timeout personalizzato
const result = await dataProvider.post('users', {
  id: 1,
  name: 'Roberto',
  timeout: 10000 // 10 secondi per questa richiesta
});

getFile

Scarica un file dal server mantenendo l'autenticazione.

const fileUrl = await dataProvider.getFile('/attachments/post/1/picture/1');

// Utilizzo per download
const link = document.createElement('a');
link.href = fileUrl;
link.download = 'filename.jpg';
link.click();

getApiUrl

Ottiene l'URL base dell'API configurato.

const apiUrl = dataProvider.getApiUrl();
console.log(apiUrl); // 'https://api.applica.guru/api'

Gestione Timeout

Ogni operazione supporta un timeout configurabile a livello di singola richiesta, che sovrascrive il timeout di default del provider.

Timeout di Default

const dataProvider = new ApplicaDataProvider({
  // ... altre configurazioni
  timeout: 30000 // 30 secondi per tutte le richieste
});

Timeout per Richiesta Specifica

// Timeout specifico sovrascrive quello di default
await dataProvider.getList('users', {
  pagination: { page: 1, perPage: 10 },
  timeout: 5000 // Solo questa richiesta avrà timeout di 5 secondi
});

// Timeout per operazioni di upload (solitamente più lunghi)
await dataProvider.create('documents', {
  data: { file: largeFileObject },
  timeout: 60000 // 1 minuto per upload di file grandi
});

Gestione Errori di Timeout

try {
  const result = await dataProvider.getList('users', {
    pagination: { page: 1, perPage: 10 },
    timeout: 1000 // timeout molto breve
  });
} catch (error) {
  if (error.message === 'error.request_timeout') {
    console.log('La richiesta è andata in timeout');
    // Gestisci l'errore di timeout
  }
}

Gestione Timeout Globale vs Locale

Il sistema di timeout del dataProvider funziona su due livelli: globale e locale.

Timeout Globale

Il timeout globale è configurato una sola volta durante l'istanziazione del dataProvider e si applica a tutte le richieste come valore di default. È particolarmente utile per:

  • Definire un timeout standard per tutta l'applicazione
  • Evitare di specificare il timeout per ogni singola chiamata
  • Gestire connessioni lente o instabili con un valore appropriato
// Configurazione globale - si applica a tutte le operazioni
const dataProvider = new ApplicaDataProvider({
  apiUrl: 'https://api.applica.guru/api',
  timeout: 15000 // 15 secondi per TUTTE le richieste
  // ... altre configurazioni
});

// Tutte queste chiamate useranno il timeout di 15 secondi
await dataProvider.getList('users', { pagination: { page: 1, perPage: 10 } });
await dataProvider.getOne('users', { id: 1 });
await dataProvider.create('users', { data: { name: 'Roberto' } });

Timeout Locale

Il timeout locale è specificato per ogni singola operazione e sovrascrive il timeout globale solo per quella chiamata specifica. È ideale per:

  • Operazioni che richiedono più tempo (upload di file, export di dati)
  • Operazioni critiche che necessitano di risposta rapida
  • Adattare il timeout in base al tipo di operazione
// Il dataProvider ha un timeout globale di 15 secondi
const dataProvider = new ApplicaDataProvider({
  timeout: 15000 // timeout globale
  // ...
});

// Timeout locale: questa chiamata aspetterà solo 3 secondi
await dataProvider.getList('users', {
  pagination: { page: 1, perPage: 10 },
  timeout: 3000 // SOVRASCRIVE il timeout globale per questa chiamata
});

// Upload con timeout esteso: questa chiamata aspetterà 2 minuti
await dataProvider.create('documents', {
  data: { file: largeFile },
  timeout: 120000 // SOVRASCRIVE il timeout globale per questa chiamata
});

// Questa chiamata userà il timeout globale di 15 secondi (nessun timeout locale specificato)
await dataProvider.getOne('users', { id: 1 });

Strategia di Timeout Consigliata

// Configurazione ottimale per la maggior parte delle applicazioni
const dataProvider = new ApplicaDataProvider({
  timeout: 30000 // 30 secondi come default sicuro
  // ...
});

// Operazioni veloci - timeout ridotto
await dataProvider.getOne('config', { id: 1, timeout: 5000 });

// Operazioni normali - usa il timeout globale
await dataProvider.getList('users', { pagination: { page: 1, perPage: 10 } });

// Upload/download - timeout esteso
await dataProvider.create('files', {
  data: { file: bigFile },
  timeout: 300000 // 5 minuti per file molto grandi
});

// Operazioni critiche real-time - timeout molto breve
await dataProvider.get('system/status', { timeout: 2000 });

// Chiamate POST personalizzate con timeout
await dataProvider.post('analytics/report', {
  startDate: '2024-01-01',
  endDate: '2024-12-31',
  timeout: 45000 // 45 secondi per report complessi
});

La precedenza è sempre: Timeout Locale > Timeout Globale > Default di Sistema (30 secondi)

Operazioni che supportano timeout personalizzato:

  • getList, getOne, getMany, getManyReference - Tutte le operazioni di lettura
  • create, update, updateMany - Tutte le operazioni di scrittura
  • delete, deleteMany - Tutte le operazioni di eliminazione
  • get, post - Chiamate generiche GET e POST

Gestione File e Allegati

Il dataProvider include supporto integrato per il caricamento di file e allegati.

Parser per Allegati

import { createAttachmentsParser } from '@applica-software-guru/crud-client';

// Configurazione di base
const attachmentsParser = createAttachmentsParser();

// Configurazione personalizzata
const customAttachmentsParser = createAttachmentsParser({
  images: ['avatar', 'thumbnail', 'banner'],
  files: ['document', 'pdf', 'contract'],
  attachments: ['gallery'] // array di file
});

Upload di File

const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const result = await dataProvider.create('entities/document', {
  data: {
    title: 'Documento Importante',
    file: file, // File object
    images: [image1, image2], // Array di immagini
    metadata: {
      category: 'important'
    }
  }
});

Gestione Errori

Il dataProvider utilizza una classe di errore configurabile per gestire gli errori HTTP.

import { HttpError } from 'ra-core';

const dataProvider = new ApplicaDataProvider({
  // ... altre configurazioni
  HttpErrorClass: HttpError
});

Codici di Errore Standard

  • 401: iam.error.unauthorized - Non autorizzato
  • 403: iam.error.forbidden - Accesso negato
  • 404: error.not_found - Risorsa non trovata
  • 408: error.request_timeout - Timeout richiesta
  • Errori di validazione: error.validation
  • Errori generici: error.generic

Gestione degli Errori

try {
  const result = await dataProvider.getOne('users', { id: 999 });
} catch (error) {
  switch (error.message) {
    case 'iam.error.unauthorized':
      // Reindirizza al login
      break;
    case 'error.not_found':
      // Mostra messaggio "utente non trovato"
      break;
    case 'error.request_timeout':
      // Mostra opzione per ritentare
      break;
    default:
      // Errore generico
      console.error('Errore:', error);
  }
}

Utilizzo con React-Admin

Il dataProvider è completamente compatibile con React-Admin:

import { Admin, Resource } from 'react-admin';
import { ApplicaDataProvider } from '@applica-software-guru/crud-client';

const dataProvider = new ApplicaDataProvider({
  // configurazione...
});

function App() {
  return (
    <Admin dataProvider={dataProvider}>
      <Resource name="users" list={UserList} edit={UserEdit} create={UserCreate} />
    </Admin>
  );
}

Migrazione dalla Versione Precedente

Se stai utilizzando la funzione deprecata createDataProvider, migra alla nuova sintassi:

// DEPRECATO ❌
import { createDataProvider } from '@applica-software-guru/crud-client';
const dataProvider = createDataProvider(config);

// NUOVO ✅
import { ApplicaDataProvider } from '@applica-software-guru/crud-client';
const dataProvider = new ApplicaDataProvider(config);

Esempi Avanzati

Configurazione Completa per Produzione

import { ApplicaDataProvider, createAttachmentsParser } from '@applica-software-guru/crud-client';
import { createAuthProvider, MemoryStorage } from '@applica-software-guru/iam-client';
import { HttpError } from 'ra-core';

const apiUrl = process.env.REACT_APP_API_URL;
const storage = new MemoryStorage();
const authProvider = createAuthProvider({ apiUrl, storage });

const dataProvider = new ApplicaDataProvider({
  apiUrl,
  HttpErrorClass: HttpError,
  getHeaders: async () => await authProvider.getHeaders(),
  getToken: async () => await authProvider.getToken(),
  attachmentsParser: createAttachmentsParser({
    images: ['avatar', 'banner', 'thumbnail'],
    files: ['cv', 'document', 'contract'],
    attachments: ['gallery', 'portfolio']
  }),
  timeout: 15000, // 15 secondi timeout di default
  prepareData: (data, resource, params) => {
    // Aggiungi timestamp a tutti i record
    return {
      ...data,
      updatedAt: new Date().toISOString()
    };
  }
});

export { dataProvider, authProvider };

Gestione Avanzata degli Upload

// Upload con progress tracking
const uploadDocument = async (file, onProgress) => {
  try {
    const result = await dataProvider.create('documents', {
      data: {
        title: file.name,
        file: file,
        category: 'user-upload'
      },
      timeout: 120000 // 2 minuti per file grandi
    });

    onProgress(100);
    return result;
  } catch (error) {
    if (error.message === 'error.request_timeout') {
      throw new Error('Upload timeout - il file potrebbe essere troppo grande');
    }
    throw error;
  }
};