docs: Update TypeScript SDK README with new API structure and improve authentication implementation

- Update README to reflect new modular API structure (subscribers, usage, payments, ratingPlans, system, graphql modules)
- Add Architecture section documenting SDK module organization
- Update all code examples to use new API module paths (sdk.subscribers instead of sdk.subscribersService)
- Remove deprecated methods (getSubscriberByImsi, terminateSubscriber, eSIM management, billing/invoices)
- Add GraphQL query execution examples
- Simplify usage examples to focus
This commit is contained in:
nutcas3
2026-04-25 04:51:06 +03:00
parent fbc6acae11
commit 8c4f4e17da
2 changed files with 216 additions and 70 deletions
+84 -51
View File
@@ -2,6 +2,22 @@
A comprehensive TypeScript SDK for integrating with the Telecom Platform API. This SDK provides a clean, type-safe interface for managing subscribers, monitoring usage, handling payments, and receiving real-time updates.
## Architecture
The SDK is organized into modular components:
- `auth.ts` - Authentication provider handling API keys and JWT tokens
- `api/` - Directory containing API modules:
- `http-client.ts` - HTTP client with retry logic
- `subscribers.ts` - Subscriber management API
- `usage.ts` - Usage tracking API
- `payments.ts` - Payment processing API
- `rating-plans.ts` - Rating plan management API
- `system.ts` - System monitoring API
- `graphql.ts` - GraphQL query execution
- `websocket.ts` - WebSocket client for real-time updates
- `types.ts` - Type definitions and interfaces
## Installation
```bash
@@ -74,22 +90,17 @@ const sdk = TelecomSDK.initialize({
```typescript
// List subscribers
const subscribers = await sdk.subscribersService.listSubscribers({
const subscribers = await sdk.subscribers.listSubscribers({
page: 1,
pageSize: 20,
status: 'active',
organizationId: 'org-123',
search: 'John Doe',
});
// Get subscriber by ID
const subscriber = await sdk.subscribersService.getSubscriber(123);
// Get subscriber by IMSI
const subscriber = await sdk.subscribersService.getSubscriberByImsi('123456789012345');
const subscriber = await sdk.subscribers.getSubscriber(123);
// Create new subscriber
const newSubscriber = await sdk.subscribersService.createSubscriber({
const newSubscriber = await sdk.subscribers.createSubscriber({
msisdn: '+1234567890',
firstName: 'John',
lastName: 'Doe',
@@ -98,70 +109,96 @@ const newSubscriber = await sdk.subscribersService.createSubscriber({
});
// Update subscriber
const updated = await sdk.subscribersService.updateSubscriber(123, {
const updated = await sdk.subscribers.updateSubscriber(123, {
firstName: 'Jane',
email: '[email protected]',
});
// Delete subscriber
await sdk.subscribersService.deleteSubscriber(123);
await sdk.subscribers.deleteSubscriber(123);
// Suspend subscriber
await sdk.subscribersService.suspendSubscriber(123);
await sdk.subscribers.suspendSubscriber(123);
// Activate subscriber
await sdk.subscribersService.activateSubscriber(123);
// Terminate subscriber
await sdk.subscribersService.terminateSubscriber(123);
await sdk.subscribers.activateSubscriber(123);
```
### Account Management
### Usage Management
```typescript
// Get subscriber account
const account = await sdk.subscribersService.getSubscriberAccount('123456789012345');
// Get usage stats
const stats = await sdk.usage.getStats(1, '2024-01-01', '2024-01-31');
// Top up balance
const updatedAccount = await sdk.subscribersService.topUpBalance('123456789012345', {
amount: 1000, // $10.00 in cents
paymentMethodId: 'pm_123',
// List usage events
const events = await sdk.usage.listEvents({
subscriberId: 1,
usageType: 'data',
page: 1,
pageSize: 50,
});
// Get usage statistics
const stats = await sdk.subscribersService.getUsageStats('123456789012345', 'monthly');
// Get real-time usage
const realtime = await sdk.subscribersService.getRealTimeUsage('123456789012345');
const realtime = await sdk.usage.getRealTimeUsage(1);
```
### eSIM Management
### Payment Management
```typescript
// Provision eSIM profile
const esim = await sdk.subscribersService.provisionESIM('123456789012345');
// Create payment transaction
const transaction = await sdk.payments.createTransaction({
subscriberId: 1,
amount: 25.00,
currency: 'USD',
gateway: 'stripe',
metadata: { description: 'Monthly plan' }
});
// Activate eSIM profile
await sdk.subscribersService.activateESIM('123456789012345', esim.profileId);
// Get transaction
const transaction = await sdk.payments.getTransaction('txn-123');
// Deactivate eSIM profile
await sdk.subscribersService.deactivateESIM('123456789012345', esim.profileId);
// Get eSIM status
const status = await sdk.subscribersService.getESIMStatus('123456789012345');
// List transactions
const transactions = await sdk.payments.listTransactions({
subscriberId: 1,
status: 'completed',
page: 1,
pageSize: 50,
});
```
### Billing & Invoices
### Rating Plans
```typescript
// Get subscriber invoices
const invoices = await sdk.subscribersService.getInvoices('123456789012345');
// List rating plans
const plans = await sdk.ratingPlans.list();
// Get specific invoice
const invoice = await sdk.subscribersService.getInvoice('inv_123');
// Get specific plan
const plan = await sdk.ratingPlans.get('plan-123');
```
// Download invoice PDF
const pdfBlob = await sdk.subscribersService.downloadInvoicePDF('inv_123');
### System Management
```typescript
// Get system stats
const stats = await sdk.system.getStats();
// Get health status
const health = await sdk.system.getHealth();
```
### GraphQL
```typescript
// Execute GraphQL query
const result = await sdk.graphql.execute(`
query GetSubscribers($first: Int) {
subscribers(first: $first) {
id
firstName
lastName
}
}
`, { first: 10 });
```
### Real-time Updates
@@ -208,17 +245,13 @@ sdk.disconnectWebSocket();
```typescript
// Get system statistics
const stats = await sdk.getSystemStats();
const stats = await sdk.system.getStats();
console.log('Active sessions:', stats.activeSessions);
console.log('Total accounts:', stats.totalAccounts);
// Get health status
const health = await sdk.getHealthStatus();
const health = await sdk.system.getHealth();
console.log('Redis connected:', health.redisConnected);
// Test connection
const test = await sdk.testConnection();
console.log('API status:', test.status);
```
## Error Handling
@@ -227,7 +260,7 @@ The SDK provides comprehensive error handling with detailed error information:
```typescript
try {
const subscriber = await sdk.subscribersService.getSubscriber(123);
const subscriber = await sdk.subscribers.getSubscriber(123);
} catch (error) {
console.error('Error:', error.code);
console.error('Message:', error.message);
@@ -263,7 +296,7 @@ The SDK is fully typed with TypeScript. All methods have proper type definitions
import { Subscriber, SubscriberStatus, UsageType } from '@telecom-platform/sdk';
// Types are automatically inferred
const subscriber: Subscriber = await sdk.subscribersService.getSubscriber(123);
const subscriber: Subscriber = await sdk.subscribers.getSubscriber(123);
const status: SubscriberStatus = subscriber.status;
```
+132 -19
View File
@@ -112,11 +112,14 @@ export class AuthProvider {
return this.tokenExpiry > Math.floor(Date.now() / 1000);
}
private base64UrlEncode(str: string): string {
return btoa(str)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
private base64UrlEncode(data: string | Uint8Array): string {
let binary: string;
if (typeof data === 'string') {
binary = btoa(data);
} else {
binary = btoa(String.fromCharCode(...data));
}
return binary.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
private base64UrlDecode(str: string): string {
@@ -128,22 +131,132 @@ export class AuthProvider {
}
private sign(data: string, secret: string): string {
// Simple HMAC-SHA256 implementation
// In production, use a proper crypto library like crypto-js or Web Crypto API
const hmac = this.simpleHMACSHA256(data, secret);
return this.base64UrlEncode(hmac);
// HMAC-SHA256 implementation
// In production, use crypto-js: import CryptoJS from 'crypto-js';
// const hash = CryptoJS.HmacSHA256(data, secret).toString(CryptoJS.enc.Base64);
// For SDK compatibility without external dependencies, using reference implementation
return this.syncHMACSHA256(data, secret);
}
private simpleHMACSHA256(message: string, key: string): string {
// This is a simplified implementation for demonstration
// In production, use a proper crypto library
let hash = 0;
const str = message + key;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
private syncHMACSHA256(message: string, key: string): string {
// HMAC-SHA256 implementation for environments without crypto support
// This is a reference implementation - in production use crypto-js or similar
const encoder = new TextEncoder();
const keyBytes = encoder.encode(key);
const messageBytes = encoder.encode(message);
// Pad key to 64 bytes (block size for SHA-256)
const block = 64;
const paddedKey = new Uint8Array(block);
paddedKey.set(keyBytes.slice(0, block));
// XOR with inner pad (0x36) and outer pad (0x5c)
const innerPad = new Uint8Array(block);
const outerPad = new Uint8Array(block);
for (let i = 0; i < block; i++) {
innerPad[i] = paddedKey[i] ^ 0x36;
outerPad[i] = paddedKey[i] ^ 0x5c;
}
return Math.abs(hash).toString(16).padStart(64, '0');
// Inner hash: H((K ^ ipad) || message)
const innerCombined = new Uint8Array(block + messageBytes.length);
innerCombined.set(innerPad);
innerCombined.set(messageBytes, block);
const innerHash = this.sha256(innerCombined);
// Outer hash: H((K ^ opad) || inner_hash)
const outerCombined = new Uint8Array(block + innerHash.length);
outerCombined.set(outerPad);
outerCombined.set(innerHash, block);
const result = this.sha256(outerCombined);
return this.base64UrlEncode(result);
}
private sha256(data: Uint8Array): Uint8Array {
// SHA-256 implementation
// In production, use a proper crypto library
// This is a reference implementation
const h = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];
// Pad data
const len = data.length * 8;
const k = Math.ceil((len + 65) / 512) * 512;
const padded = new Uint8Array(k / 8);
padded.set(data);
padded[data.length] = 0x80;
const view = new DataView(padded.buffer);
view.setUint32(padded.length - 4, Math.floor(len / 0x100000000), true);
view.setUint32(padded.length - 8, len >>> 0, true);
// Process blocks (simplified - in production use proper implementation)
for (let i = 0; i < padded.length; i += 64) {
const w = new Uint32Array(64);
for (let j = 0; j < 16; j++) {
w[j] = view.getUint32(i + j * 4, true);
}
let [a, b, c, d, e, f, g, hVal] = h;
for (let j = 0; j < 64; j++) {
if (j >= 16) {
w[j] = this.sigma1(w[j - 2]) + w[j - 7] + this.sigma0(w[j - 15]) + w[j - 16];
}
const t1 = hVal + this.ep1(e) + this.ch(e, f, g) + this.k[j] + w[j];
const t2 = this.ep0(a) + this.maj(a, b, c);
[hVal, g, f, e, d, c, b, a] = [g, f, e, d + t1, c, b, a, t1 + t2];
}
h[0] += a; h[1] += b; h[2] += c; h[3] += d;
h[4] += e; h[5] += f; h[6] += g; h[7] += hVal;
}
const result = new Uint8Array(32);
const resultView = new DataView(result.buffer);
for (let i = 0; i < 8; i++) {
resultView.setUint32(i * 4, h[i], true);
}
return result;
}
private rotr(x: number, n: number): number {
return (x >>> n) | (x << (32 - n));
}
private ep0(x: number): number {
return this.rotr(x, 2) ^ this.rotr(x, 13) ^ this.rotr(x, 22);
}
private ep1(x: number): number {
return this.rotr(x, 6) ^ this.rotr(x, 11) ^ this.rotr(x, 25);
}
private sigma0(x: number): number {
return this.rotr(x, 7) ^ this.rotr(x, 18) ^ (x >>> 3);
}
private sigma1(x: number): number {
return this.rotr(x, 17) ^ this.rotr(x, 19) ^ (x >>> 10);
}
private ch(x: number, y: number, z: number): number {
return (x & y) ^ (~x & z);
}
private maj(x: number, y: number, z: number): number {
return (x & y) ^ (x & z) ^ (y & z);
}
private k = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
}