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

@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 forceCacheRefresh Parameter 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 .env Datei

📦 Installation

npm install @contiva/sap-cpi-client

Quick 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 Logs
  • logFiles, logFileArchives - Log-Dateien
  • businessDocuments, functionalAcknowledgement - B2B Scenarios
  • keyPair, certificate, userCredentials, oAuth2ClientCredentials - Security Content
  • partners, stringParameters, binaryParameters - Partner Directory
  • entries, 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) - Gleichheit
  • notEquals(field, value) - Ungleichheit
  • greaterThan(field, value) - Größer als
  • greaterThanOrEqual(field, value) - Größer oder gleich
  • lessThan(field, value) - Kleiner als
  • lessThanOrEqual(field, value) - Kleiner oder gleich
  • contains(field, value) - Enthält (substringof)
  • startsWith(field, value) - Beginnt mit
  • endsWith(field, value) - Endet mit
  • dateRange(field, start, end?) - Datum-Bereich
  • custom(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) - Authentifizierungsfehler
  • NotFoundError (404) - Ressource nicht gefunden
  • ValidationError (400, 422) - Validierungsfehler
  • RateLimitError (429) - Rate Limit erreicht
  • ServerError (500-599) - Server-Fehler
  • TimeoutError - Request Timeout
  • NetworkError - 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.ts

Beispiel-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 lint

OpenAPI Specs hinzufügen

  1. OpenAPI Spec als .json Datei im import/ Verzeichnis ablegen
  2. Code-Generierung ausführen:
npm run generate

Die 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-Message

Features:

  • ✅ 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 Artifacts

Runtime 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

  1. Clone das Repository
    git clone https://dev.azure.com/contiva/sap-cpi-client/_git/sap-cpi-client
  2. Erstelle einen Feature Branch
    git checkout -b feature/amazing-feature
  3. Implementiere deine Änderungen
    npm run generate  # Falls OpenAPI Specs geändert
    npm run build
    npm run lint
  4. Committe und pushe
    git commit -m 'feat: add amazing feature'
    git push origin feature/amazing-feature
  5. Erstelle einen Pull Request in Azure DevOps

📚 Dokumentation

Projekt-Dokumentation

Externe Ressourcen

🙏 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