@contiva/sap-cpi-client
v0.1.1
Published
TypeScript client library for SAP Cloud Platform Integration APIs with automatic code generation, caching, and full type safety
Downloads
22
Readme
SAP CPI Client Library
TypeScript Client-Library für SAP Cloud Platform Integration APIs mit automatischer Code-Generierung aus OpenAPI Spezifikationen.
🚀 Features
🎯 Core Features
- ✅ Type-Safe: Vollständig typisierte API-Clients generiert aus OpenAPI Specs
- ✅ OAuth2 & Basic Auth: Unterstützt beide Authentifizierungsmethoden
- ✅ Auto-Generated: Services und Types werden automatisch aus OpenAPI Specs generiert
- ✅ Service Manager: Einfacher Zugriff auf alle Services über
client.services - ✅ Modern: ESM und CommonJS Support mit Tree-Shaking
- ✅ TypeScript 5.0+: Moderne TypeScript Features
💾 Caching System
- ✅ 4 Cache Backends:
node-cache(In-Memory),redis(Azure Redis),file(Persistent),none - ✅ Service-spezifische TTLs: Individuelle Cache-Zeiten pro Service mit Wildcard-Support
- ✅ Hostname-aware Keys: Automatische Trennung von Dev/Test/Prod Cache-Daten
- ✅ Force Refresh: Optional
forceCacheRefreshParameter für alle GET-Methoden - ✅ Token Caching: Automatisches Caching von OAuth2 Access Tokens
- ✅ Persistent Storage: File-based Cache bleibt zwischen Prozess-Neustarts erhalten
📊 OData Features
- ✅ Native OData Support: Collections, Entities, Metadata
- ✅ Filter Builder: Type-safe OData Filter-Konstruktion
- ✅ Pagination: Automatische Paginierung mit async iterators
- ✅ Date Helpers: OData Datum-Formate parsen und formatieren
🔧 Developer Experience
- ✅ Retry Logic: Exponential Backoff bei transienten Fehlern
- ✅ Custom Errors: Spezifische Error-Klassen (AuthError, RateLimitError, etc.)
- ✅ Interceptors: Request/Response Middleware für Logging
- ✅ Environment Config: Einfache Konfiguration via
.envDatei
📦 Installation
npm install @contiva/sap-cpi-clientQuick Reference
// Installation
npm install @contiva/sap-cpi-client
// Einfachste Nutzung
import { createClientFromEnv } from '@contiva/sap-cpi-client/core';
const client = createClientFromEnv();
// API aufrufen
const logs = await client.services.logs.getMessageProcessingLogs();
const packages = await client.services.integrationPackagesDesign.getIntegrationPackages();
// Mit Cache
SAP_CACHE_BACKEND=file // in .env
const freshData = await client.services.logs.getMessageProcessingLogs(
undefined, undefined, undefined, undefined, true // forceCacheRefresh
);🔧 Schnellstart
✅ Empfohlene Verwendung: Service Manager
Wichtig: Direkte Client-Aufrufe (client.get/post/put/delete) sind deprecated!
Verwenden Sie ausschließlich die Service Manager API für typsicheren Zugriff.
import { createClientFromEnv } from '@contiva/sap-cpi-client/core';
// Client aus Umgebungsvariablen erstellen
const client = createClientFromEnv();
// ✅ Empfohlen: Services über client.services verwenden
const logs = await client.services.logs.getMessageProcessingLogs();
const credentials = await client.services.userCredentials.getUserCredentials();
const packages = await client.services.integrationPackagesDesign.getIntegrationPackages();
// Type-safe Zugriff auf typisierte Responses
logs.forEach(log => {
console.log(`${log.MessageGuid}: ${log.Status}`);
});
// ❌ NICHT empfohlen (deprecated):
// const result = await client.get('/MessageProcessingLogs');
// const pkg = await client.post('/IntegrationPackages', data);Mit manueller Konfiguration
import { SapCpiClient } from '@contiva/sap-cpi-client/core';
// OAuth2 Client
const client = new SapCpiClient({
baseUrl: 'https://your-tenant-tmn.it-cpi123.cfapps.eu10.hana.ondemand.com/api/v1',
auth: {
type: 'oauth2',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
tokenUrl: 'https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token',
},
});
// Basic Auth Client
const basicClient = new SapCpiClient({
baseUrl: 'https://...',
auth: {
type: 'basic',
username: 'your-username',
password: 'your-password',
},
});Umgebungsvariablen Setup
Erstellen Sie eine .env Datei:
SAP_CPI_BASE_URL=https://your-tenant.it-cpi123.cfapps.eu10.hana.ondemand.com/api/v1
SAP_CPI_AUTH_TYPE=oauth2
# OAuth2
SAP_CPI_CLIENT_ID=your-client-id
SAP_CPI_CLIENT_SECRET=your-client-secret
SAP_CPI_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token
# Oder Basic Auth
# SAP_CPI_AUTH_TYPE=basic
# SAP_CPI_USERNAME=your-username
# SAP_CPI_PASSWORD=your-password💡 Erweiterte Features
Caching
Die Library unterstützt flexibles Caching für API-Requests mit hostname-aware Cache-Keys für sicheres Multi-Environment-Caching:
# .env - Caching aktivieren
SAP_CACHE_BACKEND=file # 'node-cache' | 'redis' | 'file' | 'none'
SAP_CACHE_DIR=.cache # Nur für file-backend
SAP_CACHE_DEFAULT_TTL=3600 # 1 Stunde
SAP_CACHE_SERVICE_TTL='{"MessageProcessingLogs*":300,"RuntimeArtifacts":300}'// Programmatische Konfiguration
const client = new SapCpiClient({
baseUrl: '...',
auth: { /* ... */ },
cache: {
backend: 'file', // 'none' | 'node-cache' | 'redis' | 'file'
cacheDir: '.cache', // Für file-backend
defaultTtl: 3600, // 1 Stunde
serviceTtl: {
'MessageProcessingLogs*': 300, // 5 Minuten
'RuntimeArtifacts': 300,
},
},
});
// Force Cache Refresh für einzelne Requests
const freshLogs = await client.services.logs.getMessageProcessingLogs(
undefined, undefined, undefined, undefined,
true // forceCacheRefresh
);
// Cache-Management
await client.cache.clear(); // Gesamten Cache leeren
await client.cache.delete('ServiceName', '/path', 'GET'); // Einzelner Eintrag
// Multi-Environment: Jedes System hat separate Cache-Einträge
const devClient = new SapCpiClient({ baseUrl: 'https://dev...' }); // Cache: sapcpi:abc123:...
const prodClient = new SapCpiClient({ baseUrl: 'https://prod...' }); // Cache: sapcpi:def456:...Cache-Backend Vergleich:
| Backend | Persistent | Performance | Use Case |
|---------|-----------|-------------|----------|
| none | ❌ | ⚡⚡⚡ | Development, Debugging |
| node-cache | ❌ | ⚡⚡⚡ | Single-Instance Apps |
| file | ✅ | ⚡⚡ | CI/CD, Multi-Process |
| redis | ✅ | ⚡⚡ | Multi-Instance, Shared Cache |
📖 Detaillierte Dokumentation: Caching Guide
Service Manager
Der Service Manager bietet direkten Zugriff auf alle generierten Services:
const client = createClientFromEnv();
// Message Processing Logs
const logs = await client.services.logs.getMessageProcessingLogs();
// Security Content
const keyPairs = await client.services.keyPair.getKeyPairs();
const certificates = await client.services.certificate.getCertificates();
// Integration Content
const packages = await client.services.integrationPackages.getIntegrationPackages();
// Partner Directory
const partners = await client.services.partners.getPartners();
// Message Store
const entries = await client.services.entries.getEntries();Verfügbare Service-Kategorien:
logs- Message Processing LogslogFiles,logFileArchives- Log-DateienbusinessDocuments,functionalAcknowledgement- B2B ScenarioskeyPair,certificate,userCredentials,oAuth2ClientCredentials- Security Contentpartners,stringParameters,binaryParameters- Partner Directoryentries,variables,numberRanges- Message Store
OData Filter Builder
Type-safe Filter-Erstellung für OData Queries:
import { ODataFilterBuilder, createClientFromEnv } from '@contiva/sap-cpi-client/core';
const client = createClientFromEnv();
// Erstelle Filter
const filter = new ODataFilterBuilder()
.equals('Status', 'FAILED')
.greaterThanOrEqual('LogStart', new Date('2025-01-01'))
.contains('IntegrationFlowName', 'Order')
.build();
// Wende Filter an
const logs = await client.services.logs.getMessageProcessingLogs(
undefined, // $inlinecount
filter, // $filter
['LogStart desc'], // $orderby
);
// Datum-Bereiche
const dateFilter = new ODataFilterBuilder()
.dateRange('LogStart', thirtyDaysAgo, today)
.build();Verfügbare Filter-Methoden:
equals(field, value)- GleichheitnotEquals(field, value)- UngleichheitgreaterThan(field, value)- Größer alsgreaterThanOrEqual(field, value)- Größer oder gleichlessThan(field, value)- Kleiner alslessThanOrEqual(field, value)- Kleiner oder gleichcontains(field, value)- Enthält (substringof)startsWith(field, value)- Beginnt mitendsWith(field, value)- Endet mitdateRange(field, start, end?)- Datum-Bereichcustom(filter)- Eigene Filter-Bedingung
OData Pagination
Automatische Paginierung für große Datenmengen:
import { ODataPaginator, createClientFromEnv } from '@contiva/sap-cpi-client/core';
const client = createClientFromEnv();
// Erstelle Paginator
const paginator = new ODataPaginator(
async (skipToken) => {
return await client.services.logs.getMessageProcessingLogs();
},
{
maxPages: 10,
onPage: (pageNumber, items) => {
console.log(`Seite ${pageNumber}: ${items.length} Logs`);
},
}
);
// Methode 1: Seiten-weise iterieren
for await (const page of paginator) {
page.forEach(log => {
console.log(log.MessageGuid);
});
}
// Methode 2: Alle Daten auf einmal laden
const allLogs = await paginator.loadAll();
console.log(`Insgesamt ${allLogs.length} Logs geladen`);
// Statistiken abrufen
const stats = paginator.getStats();
console.log(`${stats.currentPage} Seiten, ${stats.totalLoaded} Einträge`);OData Date Formatting
Hilfsklassen für OData Datum-Formate:
import {
parseODataDate,
formatODataDate,
toODataDateTime,
createDateRangeFilter
} from '@contiva/sap-cpi-client/core';
// Parse OData Datum
const date = parseODataDate('/Date(1763380800004)/'); // -> Date object
// Formatiere für Ausgabe
const formatted = formatODataDate('/Date(1763380800004)/');
// -> "17.11.2025, 12:00:00"
// Konvertiere zu OData DateTime String
const odataString = toODataDateTime(new Date());
// -> "2025-11-17T12:00:00"
// Erstelle Datum-Bereich Filter
const filter = createDateRangeFilter('LogStart', thirtyDaysAgo, today);
// -> "LogStart ge datetime'2025-10-17T00:00:00' and LogStart le datetime'2025-11-17T23:59:59'"Request/Response Interceptors
Middleware für Logging, Debugging und Custom Logic:
const client = createClientFromEnv();
// Request Interceptor
client.interceptors.request.use((config) => {
console.log(`📤 ${config.method} ${config.url}`);
// Füge Custom Headers hinzu
const headers = config.headers as Record<string, string>;
headers['X-Request-ID'] = generateRequestId();
return { ...config, headers };
});
// Response Interceptor
client.interceptors.response.use((response) => {
console.log(`📥 ${response.status} ${response.statusText}`);
// Logging, Metrics, etc.
logResponseTime(response);
return response;
});
// Interceptors löschen
client.interceptors.request.clear();
client.interceptors.response.clear();Error Handling
Spezifische Error-Klassen für präzise Fehlerbehandlung:
import {
AuthError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError,
TimeoutError,
NetworkError,
} from '@contiva/sap-cpi-client/core';
try {
const logs = await client.services.logs.getMessageProcessingLogs();
} catch (error) {
if (error instanceof AuthError) {
console.error('Authentifizierungsfehler:', error.statusCode);
// Neuanmeldung erforderlich
} else if (error instanceof RateLimitError) {
console.error('Rate Limit erreicht. Retry nach:', error.retryAfter);
// Warte und versuche erneut
} else if (error instanceof TimeoutError) {
console.error('Request Timeout');
// Erhöhe Timeout oder versuche später
} else if (error instanceof NetworkError) {
console.error('Netzwerkfehler:', error.cause);
// Prüfe Verbindung
} else if (error instanceof NotFoundError) {
console.error('Ressource nicht gefunden');
}
}Verfügbare Error-Klassen:
AuthError(401, 403) - AuthentifizierungsfehlerNotFoundError(404) - Ressource nicht gefundenValidationError(400, 422) - ValidierungsfehlerRateLimitError(429) - Rate Limit erreichtServerError(500-599) - Server-FehlerTimeoutError- Request TimeoutNetworkError- Netzwerkfehler
Retry Configuration
Automatische Wiederholungslogik bei transienten Fehlern:
const client = new SapCpiClient({
baseUrl: '...',
auth: { /* ... */ },
retry: {
maxRetries: 3, // Max. Anzahl Wiederholungen
retryDelay: 1000, // Initiale Verzögerung in ms
backoffFactor: 2, // Exponentieller Backoff Faktor
maxRetryDelay: 30000, // Maximale Verzögerung
retryableStatusCodes: [ // Status Codes für Retry
408, // Request Timeout
429, // Too Many Requests
500, // Internal Server Error
502, // Bad Gateway
503, // Service Unavailable
504, // Gateway Timeout
],
},
});Erweiterte Konfiguration
const client = new SapCpiClient({
baseUrl: 'https://...',
auth: { /* ... */ },
// Timeout in Millisekunden
timeout: 60000,
// Token-Cache aktivieren/deaktivieren
enableTokenCache: true,
// Custom Headers für alle Requests
headers: {
'X-Custom-Header': 'value',
'User-Agent': 'My-App/1.0',
},
// Retry Konfiguration
retry: {
maxRetries: 3,
retryDelay: 1000,
backoffFactor: 2,
},
});📚 Beispiele
Alle Beispiele befinden sich im demo/ Verzeichnis:
# Caching Demo
npx tsx demo/caching-example.ts
# Multi-Environment Caching
npx tsx demo/multi-environment-cache-example.ts
# Packages mit Artifacts auflisten
npx tsx demo/list-packages-with-artifacts.tsBeispiel-Code:
// demo/caching-example.ts
import { createClientFromEnv } from '@contiva/sap-cpi-client/core';
const client = createClientFromEnv();
// Erster Request (nicht gecached)
console.time('Erster Request');
const packages1 = await client.services.integrationPackagesDesign.getIntegrationPackages();
console.timeEnd('Erster Request');
// → ~250ms
// Zweiter Request (aus Cache)
console.time('Zweiter Request');
const packages2 = await client.services.integrationPackagesDesign.getIntegrationPackages();
console.timeEnd('Zweiter Request');
// → ~2ms ⚡
// Force Refresh
const freshPackages = await client.services.integrationPackagesDesign.getIntegrationPackages(
undefined, undefined, true // forceCacheRefresh
);🔨 Entwicklung
Projekt Setup
# Dependencies installieren
npm install
# OpenAPI Specs generieren
npm run generate
# Build
npm run build
# Entwicklungsmodus mit Watch
npm run dev
# Tests
npm run test
# Linting
npm run lintOpenAPI Specs hinzufügen
- OpenAPI Spec als
.jsonDatei imimport/Verzeichnis ablegen - Code-Generierung ausführen:
npm run generateDie Generierung erstellt automatisch:
- TypeScript Interfaces aus den OpenAPI Schemas
- Service-Klassen mit typisierten Methoden
- OData Collection und Entity Types
- Index-Dateien für einfache Imports
Projekt-Struktur
sap-cpi-lib/
├── src/
│ ├── core/ # Core-Komponenten
│ │ ├── client.ts # HTTP Client mit Retry
│ │ ├── auth-manager.ts # Authentifizierung
│ │ ├── token-cache.ts # Token Caching
│ │ ├── service-manager.ts # Service Factory
│ │ ├── odata-helpers.ts # OData Utilities
│ │ ├── errors.ts # Error Classes
│ │ ├── types.ts # Core Types
│ │ └── client-factory.ts # Client Factory
│ ├── importer/ # Code-Generator
│ │ ├── granular-generate.ts
│ │ ├── granular-type-generator.ts
│ │ └── granular-service-generator.ts
│ ├── generated/ # Auto-generierter Code
│ │ ├── b2BScenarios/ # B2B Scenarios Services
│ │ ├── integrationContent/ # Integration Content Services
│ │ ├── logFiles/ # Log Files Services
│ │ ├── messageProcessingLogs/ # Message Logs Services
│ │ ├── messageStore/ # Message Store Services
│ │ ├── partnerDirectory/ # Partner Directory Services
│ │ └── securityContent/ # Security Content Services
│ └── index.ts # Haupt-Export
├── import/ # OpenAPI Specs (JSON)
├── demo/ # Beispiel-Scripts
└── dist/ # Kompilierte Ausgabe
├── *.js # CommonJS
├── *.mjs # ES Modules
└── *.d.ts # TypeScript Definitionen🔐 Sicherheit
- Credentials nie im Code: Verwenden Sie Umgebungsvariablen (
.env) - Token Caching: Tokens werden nur im Memory gecacht (nicht persistent)
- HTTPS: Verwenden Sie immer HTTPS URLs
- Token Rotation: OAuth2 Tokens werden automatisch erneuert
- Retry bei Auth-Fehlern: Automatischer Retry mit neuem Token bei 401
🚀 CI/CD & Deployment
Azure DevOps Pipeline
Das Projekt verfügt über eine vollautomatische CI/CD-Pipeline:
# azure-pipelines.yml
Stages:
1. Build & Test → Bei jedem Push/PR
2. Publish → Automatic zu Azure Artifacts (main branch)
3. Tag → Optional mit [release] im Commit-MessageFeatures:
- ✅ Automatisches Build & Lint bei jedem Push
- ✅ Service-Generierung aus OpenAPI Specs
- ✅ Automatisches Publish zu Azure Artifacts
- ✅ Node.js Dependency Caching für schnellere Builds
- ✅ Optional: Automatische Git-Tag-Erstellung
Pipeline-Dokumentation: .azure/pipelines/README.md
Package veröffentlichen
# Version erhöhen
npm version patch # 0.1.0 → 0.1.1
npm version minor # 0.1.0 → 0.2.0
npm version major # 0.1.0 → 1.0.0
# Push mit Tags → triggert Pipeline
git push && git push --tags
# Pipeline published automatisch zu Azure ArtifactsRuntime Support
Die Library unterstützt alle modernen JavaScript Runtimes:
- ✅ Node.js 18+
- ✅ Bun 1.0+
- ✅ Deno (mit npm: Kompatibilität)
- ✅ Browser (mit Bundlern wie Vite, Webpack, etc.)
Package Exports:
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./core": {
"types": "./dist/core/index.d.ts",
"import": "./dist/core/index.mjs",
"require": "./dist/core/index.js"
},
"./services": {
"types": "./dist/services/index.d.ts",
"import": "./dist/services/index.mjs",
"require": "./dist/services/index.js"
}
}
}📄 Lizenz
MIT
🤝 Contributing
Contributions sind willkommen! Öffne ein Issue oder erstelle einen Pull Request im Azure DevOps Repository.
Development Workflow
- Clone das Repository
git clone https://dev.azure.com/contiva/sap-cpi-client/_git/sap-cpi-client - Erstelle einen Feature Branch
git checkout -b feature/amazing-feature - Implementiere deine Änderungen
npm run generate # Falls OpenAPI Specs geändert npm run build npm run lint - Committe und pushe
git commit -m 'feat: add amazing feature' git push origin feature/amazing-feature - Erstelle einen Pull Request in Azure DevOps
📚 Dokumentation
Projekt-Dokumentation
- AZURE_ARTIFACTS.md - Azure Artifacts Setup & Publishing
- .azure/pipelines/README.md - CI/CD Pipeline Dokumentation
- docs/CACHING.md - Umfassender Caching Guide
- docs/SERVICE_CATALOG.md - Übersicht aller Services
- CHANGELOG.md - Release Notes & Änderungen
Externe Ressourcen
- SAP Integration Suite Dokumentation
- SAP CPI API Referenz
- OpenAPI Specification
- OData Protocol
- Azure DevOps Pipelines
- Azure Artifacts
🙏 Danksagungen
Basiert auf den offiziellen SAP Cloud Integration APIs und nutzt moderne TypeScript Best Practices für maximale Type Safety und Developer Experience.
Made with ❤️ for the SAP Integration Community
