amilon-b2b-client
v1.1.0
Published
TypeScript SDK for Amilon B2B API - Modern, type-safe client library
Maintainers
Readme
Amilon B2B API Client
Modern TypeScript SDK per le API Amilon B2B - Type-safe, moderno e facile da usare
📋 Indice
✨ Caratteristiche
- ✅ Type-Safe al 100% - Full TypeScript support con strict mode
- ✅ OAuth2 Password Grant - Autenticazione sicura con username/password
- ✅ Token Refresh Automatico - Gestione automatica JWT token con refresh
- ✅ Retry Logic - Retry automatico con exponential backoff
- ✅ Multi-lingua - Supporto per parametro
culture(it-IT, en-US, etc.) - ✅ Browser & Node.js - Supporto universale (usando axios)
- ✅ Tree-shakeable - Build ottimizzata con ESM + CJS
- ✅ Zero dipendenze runtime - Solo axios come dipendenza
📦 Installazione
npm install amilon-b2b-client
# oppure
yarn add amilon-b2b-client
# oppure
pnpm add amilon-b2b-client🚀 Quick Start
import { AmilonClient } from 'amilon-b2b-client';
// 1. Crea un'istanza del client
const client = new AmilonClient({
ssoURL: 'https://b2bstg-sso.amilon.eu',
baseURL: 'https://b2bstg-webapi.amilon.eu',
auth: {
// OAuth2 Password Grant
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
username: 'your-username',
password: 'your-password',
},
version: '1', // Opzionale, default: '1'
culture: 'it-IT', // Opzionale, default: 'it-IT'
});
// 2. Usa le API
async function example() {
// Ottieni un contratto specifico
const contract = await client.contracts.getById('CONTRACT-123');
console.log('Contratto:', contract);
// Ottieni prodotti del contratto
const products = await client.contracts.getProducts('CONTRACT-123');
console.log('Prodotti:', products);
// Crea un nuovo ordine
const order = await client.orders.create('CONTRACT-123', {
orderRows: [
{ productId: 'PROD-1', quantity: 2 },
{ productId: 'PROD-2', quantity: 1 },
],
});
console.log('Ordine creato:', order);
}
example();⚙️ Configurazione
Configurazione Base
const client = new AmilonClient({
ssoURL: 'https://b2bstg-sso.amilon.eu',
baseURL: 'https://b2bstg-webapi.amilon.eu',
auth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
username: 'your-username',
password: 'your-password',
},
});Configurazione Avanzata
const client = new AmilonClient({
ssoURL: 'https://b2bstg-sso.amilon.eu',
baseURL: 'https://b2bstg-webapi.amilon.eu',
auth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
username: 'your-username',
password: 'your-password',
tokenEndpoint: '/connect/token', // Custom token endpoint (default)
},
version: '1', // API version (default: '1')
culture: 'en-US', // Lingua predefinita (default: 'it-IT')
timeout: 30000, // Timeout richieste (ms, default: 30000)
retries: 3, // Numero di retry su errore (default: 3)
debug: true, // Abilita logging dettagliato
onTokenRefresh: (token) => {
// Callback chiamato dopo il refresh del token
console.log('Token aggiornato:', token);
},
onError: (error) => {
// Callback chiamato su errori
console.error('Errore API:', error);
},
});Variabili d'ambiente
Puoi configurare il client usando variabili d'ambiente:
# .env
AMILON_SSO_URL=https://b2bstg-sso.amilon.eu
AMILON_BASE_URL=https://b2bstg-webapi.amilon.eu
AMILON_CLIENT_ID=your-client-id
AMILON_CLIENT_SECRET=your-client-secret
AMILON_USERNAME=your-username
AMILON_PASSWORD=your-password
AMILON_VERSION=1
AMILON_CULTURE=it-ITimport { AmilonClient } from 'amilon-b2b-client';
const client = new AmilonClient({
ssoURL: process.env.AMILON_SSO_URL!,
baseURL: process.env.AMILON_BASE_URL!,
auth: {
clientId: process.env.AMILON_CLIENT_ID!,
clientSecret: process.env.AMILON_CLIENT_SECRET!,
username: process.env.AMILON_USERNAME!,
password: process.env.AMILON_PASSWORD!,
},
version: process.env.AMILON_VERSION,
culture: process.env.AMILON_CULTURE,
});💼 Utilizzo
Contracts API
// Ottieni contratto per ID
const contract = await client.contracts.getById('CONTRACT-123');
// Ottieni retailers associati al contratto
const retailers = await client.contracts.getRetailers('CONTRACT-123', {
culture: 'it-IT', // Opzionale, sovrascrive default
});
// Ottieni prodotti di un contratto
const products = await client.contracts.getProducts('CONTRACT-123', {
culture: 'it-IT',
});
// Ottieni prodotti con dettagli completi
const productsComplete = await client.contracts.getProductsComplete('CONTRACT-123', {
culture: 'it-IT',
});Orders API
// Crea un nuovo ordine immediato
const order = await client.orders.create('CONTRACT-123', {
externalOrderId: 'MY-ORDER-123', // Opzionale, auto-generato se omesso
orderRows: [
{ productId: 'PROD-1', quantity: 2 },
{ productId: 'PROD-2', quantity: 1 },
],
});
// Ottieni ordine per external order ID
const order = await client.orders.getById('MY-ORDER-123');
// Ottieni ordine con dettagli completi
const orderComplete = await client.orders.getByIdComplete('MY-ORDER-123');Retailers API
// Ottieni categorie retailer
const categories = await client.retailers.getCategories();📚 API Reference
AmilonClient
Il client principale che espone tutti gli endpoint API.
class AmilonClient {
contracts: ContractsApi;
orders: OrdersApi;
retailers: RetailersApi;
constructor(config: AmilonClientConfig);
}
interface AmilonClientConfig {
ssoURL: string; // SSO base URL
baseURL: string; // API base URL
auth: AuthConfig; // Authentication config
version?: string; // API version (default: '1')
culture?: string; // Default culture (default: 'it-IT')
timeout?: number; // Request timeout in ms (default: 30000)
retries?: number; // Number of retries (default: 3)
debug?: boolean; // Enable debug logging
onTokenRefresh?: (token: string) => void; // Token refresh callback
onError?: (error: Error) => void; // Error callback
}
interface AuthConfig {
clientId: string; // OAuth2 client ID
clientSecret: string; // OAuth2 client secret
username: string; // User username
password: string; // User password
tokenEndpoint?: string; // Token endpoint path (default: '/connect/token')
}ContractsApi
Gestione contratti.
interface ContractsApi {
// Ottieni contratto per ID
getById(contractId: string, options?: RequestOptions): Promise<ContractInfoApiResponse>;
// Ottieni retailers del contratto
getRetailers(contractId: string, options?: RequestOptions): Promise<RetailerInfo[]>;
// Ottieni prodotti del contratto
getProducts(contractId: string, options?: RequestOptions): Promise<ProductViewModel[]>;
// Ottieni prodotti con dettagli completi
getProductsComplete(contractId: string, options?: RequestOptions): Promise<ProductCompleteViewModel[]>;
}OrdersApi
Gestione ordini.
interface OrdersApi {
// Crea un nuovo ordine immediato
create(
contractId: string,
order: CreateOrderRequest,
options?: RequestOptions
): Promise<OrderInfoApiResponse>;
// Ottieni ordine per external order ID
getById(externalOrderId: string, options?: RequestOptions): Promise<OrderInfoApiResponse>;
// Ottieni ordine con dettagli completi
getByIdComplete(externalOrderId: string, options?: RequestOptions): Promise<OrderInfoApiResponse>;
}
interface CreateOrderRequest {
externalOrderId?: string; // Optional external order ID
orderRows: OrderRow[]; // Products to order
[key: string]: any; // Additional order data
}
interface OrderRow {
productId: string;
quantity: number;
}RetailersApi
Informazioni retailer.
interface RetailersApi {
// Ottieni categorie retailer
getCategories(options?: RequestOptions): Promise<RetailerCategory[]>;
}Request Options
Tutte le chiamate API supportano opzioni aggiuntive:
interface RequestOptions {
culture?: string; // Override default culture
params?: Record<string, any>; // Additional query parameters
headers?: Record<string, string>; // Additional headers
}🛠️ Sviluppo
Setup
# Clone repository
git clone <repository-url>
cd amilon-b2b-client
# Installa dipendenze
npm install
# Genera types da Swagger
npm run types:generate
# Build
npm run build
# Development mode (watch)
npm run dev
# Run tests
npm testStruttura del Progetto
amilon-b2b-client/
├── src/
│ ├── generated/ # Types auto-generati da Swagger
│ │ └── api-types.ts
│ ├── client/ # API endpoint implementations
│ │ ├── ContractsApi.ts
│ │ ├── OrdersApi.ts
│ │ └── RetailersApi.ts
│ ├── auth/ # Authentication manager
│ │ └── AuthManager.ts
│ ├── types/ # Custom types
│ │ └── config.ts
│ ├── utils/ # Utilities
│ │ ├── http.ts # HTTP client wrapper
│ │ └── errors.ts # Error handling
│ └── index.ts # Main entry point
├── codegen/ # Code generation scripts
│ └── generate-types.js
├── examples/ # Usage examples
├── docs/ # Documentation
│ └── ARCHITECTURE.md
├── package.json
├── tsconfig.json
└── tsup.config.tsGenerazione Types
Nota: La generazione automatica dei types è disponibile ma non ancora attiva. I types sono attualmente definiti manualmente nelle API classes con TODO markers per future generazione da OpenAPI.
Per generare i types automaticamente dallo Swagger (quando disponibile):
npm run types:generateQuesto comando:
- Scarica lo schema OpenAPI da
https://b2bstg-webapi.amilon.eu/swagger/v1/swagger.json - Genera types TypeScript in
src/generated/api-types.ts - I types possono essere usati per sostituire quelli manuali
Build
# Build per produzione
npm run build
# Output:
# - dist/index.js (CommonJS)
# - dist/index.mjs (ESM)
# - dist/index.d.ts (Types)Testing
# Run all tests
npm test
# Watch mode
npm run test:watch
# Type checking
npm run typecheck🏗️ Architettura
Il progetto segue un'architettura modulare e type-safe:
- Type Safety: TypeScript strict mode al 100% con types definiti per ogni endpoint
- Dual Authentication: Separate SSO URL per autenticazione OAuth2 Password Grant
- Custom Client: Client ergonomico con API fluent
- Authentication Layer: Gestione automatica JWT token con refresh trasparente
- HTTP Layer: Wrapper axios con retry logic, exponential backoff e error handling
- Modular APIs: Contracts, Orders e Retailers API separati e composabili
Per dettagli completi sull'architettura, vedi ARCHITECTURE.md.
🤝 Contribuire
Contributi sono benvenuti! Per favore:
- Fork del repository
- Crea un branch per la tua feature (
git checkout -b feature/amazing-feature) - Commit delle modifiche (
git commit -m 'Add amazing feature') - Push al branch (
git push origin feature/amazing-feature) - Apri una Pull Request
📝 License
MIT © [Dani Lipari]
🔗 Links
Made with ❤️ by Dani Lipari
