weshipyou-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/infrastructure/web/server.ts","../src/infrastructure/logging/token-manager.impl.ts","../src/infrastructure/http/axios-http-client.ts","../src/domain/errors/api.error.ts","../src/application/services/auth.service.ts","../src/application/services/account.service.ts","../src/application/services/mobile-recharge.service.ts","../src/application/services/polling.service.ts","../src/application/use-cases/get-rates.use-case.ts","../src/application/use-cases/create-shipment.use-case.ts","../src/domain/validators/account.validator.ts","../src/domain/errors/validation.error.ts","../src/application/use-cases/create-sub-account.use-case.ts","../src/domain/validators/mobile-recharge.validator.ts","../src/application/use-cases/execute-recharge.use-case.ts","../src/application/use-cases/track-shipment.use-case.ts","../src/application/use-cases/handle-webhook.use-case.ts","../src/infrastructure/resilience/circuit-breaker.impl.ts","../src/infrastructure/rate-limiter/express-rate-limiter.impl.ts","../src/infrastructure/observability/otel-tracer.impl.ts","../src/infrastructure/observability/otel-instrumentation.ts","../src/infrastructure/web/express-router.ts","../src/infrastructure/web/auth-guard.middleware.ts","../src/infrastructure/logging/metrics-collector.ts","../src/infrastructure/config/env.validator.ts","../src/domain/validators/webhook.validator.ts","../src/infrastructure/di/bootstrap.ts","../src/infrastructure/resilience/opossum-circuit-breaker.impl.ts","../src/infrastructure/security/helmet-csp.impl.ts","../src/domain/events/webhook.events.ts","../src/application/sagas/shipment-reconciliation.saga.ts","../src/sdk/index.ts"],"sourcesContent":["import { Server } from 'http';\n\nexport interface Shutdownable {\n close(): Promise<void>;\n}\n\nexport function gracefulShutdown(server: Server, deps: Shutdownable[], timeout = 30000): () => Promise<void> {\n return async () => {\n const timer = setTimeout(() => process.exit(1), timeout);\n server.close();\n await Promise.all(deps.map(d => d.close().catch(() => {})));\n clearTimeout(timer);\n process.exit(0);\n };\n}\n","import { ITokenManager } from '../../domain/interfaces/token-manager.interface';\n\nexport class InMemoryTokenManager implements ITokenManager {\n private token: string | null = null;\n private exp: number = 0;\n\n setToken(token: string, exp: number): void {\n this.token = token;\n this.exp = exp;\n }\n\n getToken(): string | null {\n return this.token;\n }\n\n isExpired(): boolean {\n if (!this.exp) return true;\n return (this.exp * 1000) < Date.now();\n }\n\n clear(): void {\n this.token = null;\n this.exp = 0;\n }\n}\n","import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { IHttpClient, HttpRequest, HttpResponse } from '../../domain/interfaces/http-client.interface';\nimport { ITokenManager } from '../../domain/interfaces/token-manager.interface';\nimport { ApiError, RateLimitError, AuthError } from '../../domain/errors/api.error';\nimport { randomUUID } from 'crypto';\nimport pino from 'pino';\n\nconst logger = pino({ level: 'info' });\n\nexport class AxiosHttpClient implements IHttpClient {\n private client: AxiosInstance;\n private tokenManager: ITokenManager;\n private retries: number;\n private baseDelayMs: number;\n private refreshTokenFn?: () => Promise<{ accessToken: string; exp: number }>;\n private refreshPromise: Promise<{ accessToken: string; exp: number }> | null = null;\n private idempotencyPaths: RegExp[];\n private onRateLimit?: (info: { remaining: number; limit: number; reset: number }) => void;\n\n lastRateLimit: { remaining: number; limit: number; reset: number } | null = null;\n\n constructor(\n baseURL: string,\n tokenManager: ITokenManager,\n refreshTokenFn?: () => Promise<{ accessToken: string; exp: number }>,\n retries = 3,\n baseDelayMs = 1000,\n idempotencyPaths: RegExp[] = [/add-funds/i, /mobile-recharges/i, /recharges/i],\n onRateLimit?: (info: { remaining: number; limit: number; reset: number }) => void\n ) {\n this.client = axios.create({ baseURL, timeout: 10000 });\n this.tokenManager = tokenManager;\n this.refreshTokenFn = refreshTokenFn;\n this.retries = retries;\n this.baseDelayMs = baseDelayMs;\n this.idempotencyPaths = idempotencyPaths;\n this.onRateLimit = onRateLimit;\n\n this.client.interceptors.request.use(config => {\n const token = this.tokenManager.getToken();\n if (token && !config.headers['Authorization']) {\n config.headers['Authorization'] = `Bearer ${token}`;\n }\n return config;\n });\n\n this.client.interceptors.response.use(\n res => res,\n async err => {\n const originalRequest = err.config;\n if (err.response?.status === 401 && !originalRequest._retry) {\n originalRequest._retry = true;\n if (this.refreshTokenFn) {\n try {\n if (!this.refreshPromise) {\n this.refreshPromise = this.refreshTokenFn();\n }\n const { accessToken, exp } = await this.refreshPromise;\n this.refreshPromise = null;\n this.tokenManager.setToken(accessToken, exp);\n originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;\n return this.client(originalRequest);\n } catch (refreshErr) {\n this.refreshPromise = null;\n logger.warn('Token refresh failed');\n this.tokenManager.clear();\n throw new AuthError('Session expired');\n }\n }\n }\n\n if (err.response) {\n const { status, data } = err.response;\n if (status === 429) throw new RateLimitError(data?.message);\n if (status >= 400) throw new ApiError(status, data?.message || 'API request failed', data);\n }\n throw err;\n }\n );\n }\n\n getRateLimitInfo(): { remaining: number; limit: number; reset: number } | null {\n return this.lastRateLimit;\n }\n\n async request<T>(config: HttpRequest): Promise<HttpResponse<T>> {\n let attempt = 0;\n while (attempt < this.retries) {\n try {\n const axiosConfig: AxiosRequestConfig = {\n method: config.method.toLowerCase(),\n url: config.url,\n data: config.body,\n headers: { ...config.headers }\n };\n\n if (config.method === 'POST') {\n const matchesIdempotency = this.idempotencyPaths.some(pattern => pattern.test(config.url));\n if (matchesIdempotency) {\n axiosConfig.headers = { ...(axiosConfig.headers || {}), 'Idempotency-Key': randomUUID() };\n }\n }\n\n const response = await this.client.request(axiosConfig);\n\n const remaining = response.headers['x-ratelimit-remaining'];\n const limit = response.headers['x-ratelimit-limit'];\n const reset = response.headers['x-ratelimit-reset'];\n if (remaining !== undefined && limit !== undefined && reset !== undefined) {\n this.lastRateLimit = {\n remaining: Number(remaining),\n limit: Number(limit),\n reset: Number(reset),\n };\n this.onRateLimit?.(this.lastRateLimit);\n }\n\n return {\n status: response.status,\n data: response.data as T,\n headers: response.headers as Record<string, string>\n };\n } catch (error: any) {\n attempt++;\n const isRetryable = error instanceof RateLimitError\n || error?.response?.status >= 500\n || error?.statusCode >= 500;\n if (attempt >= this.retries || !isRetryable) {\n throw error;\n }\n await new Promise(res => setTimeout(res, this.baseDelayMs * Math.pow(2, attempt - 1)));\n }\n }\n throw new Error('Max retries exceeded');\n }\n}\n","export class ApiError extends Error {\n constructor(\n public readonly statusCode: number,\n message: string,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport class AuthError extends ApiError {\n constructor(message = 'Authentication failed') {\n super(401, message);\n }\n}\n\nexport class RateLimitError extends ApiError {\n constructor(message = 'Rate limit exceeded') {\n super(429, message);\n }\n}\n","import { IHttpClient } from '../../domain/interfaces/http-client.interface';\nimport { ITokenManager } from '../../domain/interfaces/token-manager.interface';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\n\nexport interface AuthResponse {\n accessToken: string;\n exp?: number;\n}\n\nexport interface IAuthService {\n authenticate(username: string, password: string, lang?: AcceptLanguage): Promise<AuthResponse>;\n}\n\nexport class AuthService implements IAuthService {\n constructor(\n private readonly httpClient: IHttpClient,\n private readonly tokenManager?: ITokenManager\n ) {}\n\n async authenticate(username: string, password: string, lang = AcceptLanguage.EN_US): Promise<AuthResponse> {\n const response = await this.httpClient.request<AuthResponse>({\n method: 'POST',\n url: '/api/v1/authentication',\n body: { username, password },\n headers: { 'Accept-Language': lang }\n });\n const data = response.data;\n if (this.tokenManager && data.accessToken) {\n this.tokenManager.setToken(data.accessToken, data.exp || 0);\n }\n return data;\n }\n}\n","import { IHttpClient } from '../../domain/interfaces/http-client.interface';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\nimport { AddSubAccountInput } from '../../domain/validators/account.validator';\n\nexport interface IAccountService {\n addSubAccount(payload: AddSubAccountInput, lang?: AcceptLanguage): Promise<unknown>;\n addFunds(payload: {\n paymentMethod?: string;\n accountUid?: string;\n transaction: { zelleTransaction: string; amount: number };\n }, lang?: AcceptLanguage): Promise<unknown>;\n}\n\nexport class AccountService implements IAccountService {\n constructor(private readonly httpClient: IHttpClient) {}\n\n async addSubAccount(payload: AddSubAccountInput, lang = AcceptLanguage.EN_US): Promise<unknown> {\n const res = await this.httpClient.request({\n method: 'POST',\n url: '/api/v1/add-sub-account',\n body: payload as unknown as Record<string, unknown>,\n headers: { 'Accept-Language': lang }\n });\n return res.data;\n }\n\n async addFunds(\n payload: {\n paymentMethod?: string;\n accountUid?: string;\n transaction: { zelleTransaction: string; amount: number };\n },\n lang = AcceptLanguage.EN_US\n ): Promise<unknown> {\n const res = await this.httpClient.request({\n method: 'POST',\n url: '/api/v1/add-funds',\n body: { paymentMethod: 'zelle', ...payload } as unknown as Record<string, unknown>,\n headers: { 'Accept-Language': lang }\n });\n return res.data;\n }\n}\n","import { IHttpClient } from '../../domain/interfaces/http-client.interface';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\nimport { CreateRechargeInput } from '../../domain/validators/mobile-recharge.validator';\n\nexport interface IMobileRechargeService {\n createRecharge(payload: CreateRechargeInput, lang?: AcceptLanguage): Promise<unknown>;\n getRecharges(limit?: number, lang?: AcceptLanguage): Promise<unknown>;\n}\n\nexport class MobileRechargeService implements IMobileRechargeService {\n constructor(private readonly httpClient: IHttpClient) {}\n\n async createRecharge(payload: CreateRechargeInput, lang = AcceptLanguage.EN_US): Promise<unknown> {\n const res = await this.httpClient.request({\n method: 'POST',\n url: '/api/v1/mobile-recharges/recharges',\n body: payload as unknown as Record<string, unknown>,\n headers: { 'Accept-Language': lang }\n });\n return res.data;\n }\n\n async getRecharges(limit = 20, lang = AcceptLanguage.EN_US): Promise<unknown> {\n const res = await this.httpClient.request({\n method: 'GET',\n url: `/api/v1/mobile-recharges/recharges?limit=${encodeURIComponent(String(limit))}`,\n headers: { 'Accept-Language': lang }\n });\n return res.data;\n }\n}\n","import { IPollingService, PollingOptions } from '../../domain/interfaces/polling.interface';\n\nexport class PollingService implements IPollingService {\n async pollUntil<T>(\n fn: () => Promise<T>,\n condition: (result: T) => boolean,\n opts: Partial<PollingOptions> = {}\n ): Promise<T> {\n const { maxAttempts = 5, baseDelayMs = 1000, abortSignal } = opts;\n let attempt = 0;\n\n while (attempt < maxAttempts) {\n if (abortSignal?.aborted) throw new DOMException('Polling aborted', 'AbortError');\n\n const result = await fn();\n if (condition(result)) return result;\n\n attempt++;\n if (attempt >= maxAttempts) throw new Error(`Polling limit reached (${maxAttempts})`);\n\n const delay = baseDelayMs * Math.pow(2, attempt - 1);\n await new Promise(res => setTimeout(res, delay));\n }\n throw new Error('Unreachable polling path');\n }\n}\n","import { IAuthService } from '../services/auth.service';\nimport { IShipmentService } from '../services/shipment.service';\nimport { IRateRequest } from '../../domain/interfaces/shipment.interface';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\n\nexport class GetRatesUseCase {\n constructor(\n private readonly authService: IAuthService,\n private readonly shipmentService: IShipmentService\n ) {}\n\n async execute(\n username: string,\n password: string,\n payload: IRateRequest,\n lang = AcceptLanguage.EN_US\n ): Promise<unknown> {\n await this.authService.authenticate(username, password, lang);\n return this.shipmentService.getRates(payload, lang);\n }\n}\n","import { IAuthService } from '../services/auth.service';\nimport { IShipmentService } from '../services/shipment.service';\nimport { IShipmentRequest } from '../../domain/interfaces/shipment.interface';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\n\nexport class CreateShipmentUseCase {\n constructor(\n private readonly authService: IAuthService,\n private readonly shipmentService: IShipmentService\n ) {}\n\n async execute(\n username: string,\n password: string,\n payload: IShipmentRequest,\n lang = AcceptLanguage.EN_US\n ): Promise<unknown> {\n await this.authService.authenticate(username, password, lang);\n return this.shipmentService.createShipment(payload, lang);\n }\n}\n","import { z } from 'zod';\n\nexport const AddSubAccountSchema = z.object({\n accountUid: z.string().optional(),\n externalAccountNumber: z.string().optional(),\n name: z.string().min(1),\n displayName: z.string().min(1),\n systemUnits: z.enum(['imperial', 'metric']),\n email: z.string().email(),\n notificationEmail: z.string().email(),\n website: z.string().url().optional().or(z.literal('')),\n phone: z.string().min(6),\n emergencyPhone: z.string().min(6),\n taxId: z.string().optional(),\n taxIdCountry: z.object({ isoCode: z.string().length(2) }).optional(),\n isBusiness: z.boolean().default(false),\n allowBankAccountPayments: z.boolean().default(false),\n address: z.object({\n street: z.string(),\n city: z.string(),\n state: z.string(),\n postalCode: z.string(),\n countryIsoCode: z.string().length(2)\n }).optional()\n});\n\nexport type AddSubAccountInput = z.infer<typeof AddSubAccountSchema>;\n","export class ValidationError extends Error {\n constructor(public readonly details: Record<string, string[]>) {\n super('Validation failed');\n this.name = 'ValidationError';\n }\n}\n","import { IAuthService } from '../services/auth.service';\nimport { IAccountService } from '../services/account.service';\nimport { AddSubAccountSchema } from '../../domain/validators/account.validator';\nimport { ValidationError } from '../../domain/errors/validation.error';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\n\nexport class CreateSubAccountUseCase {\n constructor(\n private readonly authService: IAuthService,\n private readonly accountService: IAccountService\n ) {}\n\n async execute(\n username: string,\n password: string,\n payload: unknown,\n lang = AcceptLanguage.EN_US\n ): Promise<unknown> {\n const parsed = AddSubAccountSchema.safeParse(payload);\n if (!parsed.success) {\n throw new ValidationError(parsed.error.flatten().fieldErrors);\n }\n\n await this.authService.authenticate(username, password, lang);\n return this.accountService.addSubAccount(parsed.data, lang);\n }\n}\n","import { z } from 'zod';\n\nexport const CreateRechargeSchema = z.object({\n paymentMethod: z.enum(['zelle', 'credit_card', 'balance']).default('zelle'),\n accountUid: z.string().optional(),\n rechargeable_product: z.object({ id: z.number().int().positive() }),\n scheduleDate: z.string().datetime().optional().nullable(),\n amount: z.number().positive(),\n account_rechargeable_contact: z.object({\n name: z.string().min(1),\n accountNumber: z.string().min(1)\n })\n});\n\nexport type CreateRechargeInput = z.infer<typeof CreateRechargeSchema>;\n","import { IAuthService } from '../services/auth.service';\nimport { IMobileRechargeService } from '../services/mobile-recharge.service';\nimport { CreateRechargeSchema } from '../../domain/validators/mobile-recharge.validator';\nimport { ValidationError } from '../../domain/errors/validation.error';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\n\nexport class ExecuteRechargeUseCase {\n constructor(\n private readonly authService: IAuthService,\n private readonly rechargeService: IMobileRechargeService\n ) {}\n\n async execute(\n username: string,\n password: string,\n payload: unknown,\n lang = AcceptLanguage.EN_US\n ): Promise<unknown> {\n const parsed = CreateRechargeSchema.safeParse(payload);\n if (!parsed.success) {\n throw new ValidationError(parsed.error.flatten().fieldErrors);\n }\n\n await this.authService.authenticate(username, password, lang);\n return this.rechargeService.createRecharge(parsed.data, lang);\n }\n}\n","import { IHttpClient } from '../../domain/interfaces/http-client.interface';\nimport { IPollingService } from '../../domain/interfaces/polling.interface';\nimport { ICircuitBreaker } from '../../domain/interfaces/circuit-breaker.interface';\nimport { AcceptLanguage } from '../../domain/interfaces/language.enum';\n\nexport interface ShipmentStatus {\n id: string;\n status: string;\n trackingNumber?: string;\n updatedAt: string;\n}\n\nexport class TrackShipmentUseCase {\n constructor(\n private readonly httpClient: IHttpClient,\n private readonly pollingService: IPollingService,\n private readonly circuitBreaker: ICircuitBreaker\n ) {}\n\n async execute(\n shipmentId: string,\n targetStatus: string,\n abortSignal?: AbortSignal,\n lang = AcceptLanguage.EN_US\n ) {\n const pollFn = async () => {\n return await this.circuitBreaker.execute<ShipmentStatus>(async () => {\n const res = await this.httpClient.request<ShipmentStatus>({\n method: 'GET',\n url: `/api/v1/shipments/${shipmentId}`,\n headers: { 'Accept-Language': lang }\n });\n return res.data;\n });\n };\n\n return await this.pollingService.pollUntil(\n pollFn,\n (status) => status.status === targetStatus,\n { maxAttempts: 8, baseDelayMs: 2000, abortSignal }\n );\n }\n}\n","import { createHmac, timingSafeEqual } from 'crypto';\nimport { IWebhookHandler, IWebhookEvent } from '../../domain/interfaces/webhook.interface';\n\nexport class HandleWebhookUseCase implements IWebhookHandler {\n constructor(\n private readonly secret: string,\n private readonly algorithm: string = 'sha256'\n ) {}\n\n verifySignature(rawBody: string, signature: string, secret?: string, algorithm?: string): boolean {\n const key = secret || this.secret;\n const algo = algorithm || this.algorithm;\n const expected = createHmac(algo, key).update(rawBody).digest('hex');\n\n if (expected.length !== signature.length) return false;\n\n try {\n return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));\n } catch {\n return false;\n }\n }\n\n async handle(event: IWebhookEvent): Promise<void> {\n console.log(`[Webhook] Received ${event.eventType} at ${event.timestamp}`);\n }\n}\n","import { ICircuitBreaker, CircuitState } from '../../domain/interfaces/circuit-breaker.interface';\n\nexport class CircuitBreaker implements ICircuitBreaker {\n private state: CircuitState = 'CLOSED';\n private failures = 0;\n private failureThreshold: number;\n private resetTimeoutMs: number;\n private lastFailureTime: number | null = null;\n\n constructor(failureThreshold = 5, resetTimeoutMs = 30000) {\n this.failureThreshold = failureThreshold;\n this.resetTimeoutMs = resetTimeoutMs;\n }\n\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n if (this.state === 'OPEN') {\n const now = Date.now();\n if (this.lastFailureTime && now - this.lastFailureTime > this.resetTimeoutMs) {\n this.state = 'HALF-OPEN';\n } else {\n throw new Error('Circuit breaker is OPEN');\n }\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return result;\n } catch (error) {\n this.onFailure();\n throw error;\n }\n }\n\n getState(): CircuitState { return this.state; }\n\n reset(): void {\n this.state = 'CLOSED';\n this.failures = 0;\n this.lastFailureTime = null;\n }\n\n private onSuccess() {\n this.failures = 0;\n if (this.state === 'HALF-OPEN') this.state = 'CLOSED';\n }\n\n private onFailure() {\n this.failures++;\n this.lastFailureTime = Date.now();\n if (this.failures >= this.failureThreshold) this.state = 'OPEN';\n }\n}\n","import { IRateLimiter } from '../../domain/interfaces/rate-limiter.interface';\nimport rateLimit, { Options } from 'express-rate-limit';\nimport { Request, Response, NextFunction } from 'express';\n\nexport class ExpressRateLimiter implements IRateLimiter {\n private limiter: ReturnType<typeof rateLimit>;\n\n constructor(opts: Partial<Options> = {}) {\n this.limiter = rateLimit({\n windowMs: 15 * 60 * 1000,\n max: 100,\n standardHeaders: true,\n legacyHeaders: false,\n ...opts\n });\n }\n\n async consume(_key: string, _tokens = 1): Promise<{ remaining: number; limit: number; retryAfter?: number }> {\n return Promise.resolve({ remaining: 99, limit: 100 });\n }\n\n getMiddleware() {\n return (req: Request, res: Response, next: NextFunction) => this.limiter(req, res, next);\n }\n\n async close(): Promise<void> {\n }\n}\n","import { ITracer, ISpan } from '../../domain/interfaces/tracer.interface';\nimport { trace } from '@opentelemetry/api';\nimport { shutdownOpenTelemetry } from './otel-instrumentation';\n\nexport class OtelTracer implements ITracer {\n private tracer = trace.getTracer('weshipyou-sdk');\n\n startSpan(name: string, attributes?: Record<string, string | number | boolean>): ISpan {\n const span = this.tracer.startSpan(name);\n if (attributes) {\n Object.entries(attributes).forEach(([k, v]) => span.setAttribute(k, v));\n }\n return {\n setAttribute: (k, v) => span.setAttribute(k, v),\n end: () => span.end()\n };\n }\n\n async close(): Promise<void> {\n await shutdownOpenTelemetry();\n }\n}\n","import { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\n\nlet sdk: NodeSDK | null = null;\n\nexport function initOpenTelemetry(serviceName = 'weshipyou-sdk') {\n if (sdk) return sdk;\n\n sdk = new NodeSDK({\n serviceName,\n traceExporter: new OTLPTraceExporter({\n url: process.env.OTEL_ENDPOINT || 'http://localhost:4318/v1/traces'\n }),\n instrumentations: [getNodeAutoInstrumentations()]\n });\n\n sdk.start();\n return sdk;\n}\n\nexport async function shutdownOpenTelemetry() {\n if (sdk) {\n await sdk.shutdown();\n sdk = null;\n }\n}\n","import { Router, Request, Response, NextFunction, RequestHandler } from 'express';\nimport { IRateLimiter } from '../../domain/interfaces/rate-limiter.interface';\nimport { ITracer } from '../../domain/interfaces/tracer.interface';\n\nexport interface RouteHandlers {\n rates: (body: unknown) => Promise<unknown>;\n createShipment: (body: unknown) => Promise<unknown>;\n trackShipment: (id: string, targetStatus: string) => Promise<unknown>;\n webhook: (signature: string, rawBody: string) => Promise<void>;\n}\n\nexport function createRouter(\n rateLimiter: IRateLimiter,\n tracer: ITracer,\n handlers: RouteHandlers,\n authGuard: RequestHandler\n): Router {\n const router = Router();\n\n router.use(rateLimiter.getMiddleware());\n router.use(authGuard);\n\n router.post('/shipments/rates', async (req: Request, res: Response, next: NextFunction) => {\n const span = tracer.startSpan('POST /shipments/rates');\n span.setAttribute('account.id', (req.body as any)?.accountId || 'unknown');\n try {\n const result = await handlers.rates(req.body);\n res.json(result);\n } catch (err) { next(err); } finally { span.end(); }\n });\n\n router.post('/shipments', async (req: Request, res: Response, next: NextFunction) => {\n const span = tracer.startSpan('POST /shipments');\n span.setAttribute('account.id', (req.body as any)?.accountId || 'unknown');\n try {\n const result = await handlers.createShipment(req.body);\n res.status(201).json(result);\n } catch (err) { next(err); } finally { span.end(); }\n });\n\n router.get('/shipments/:id', async (req: Request, res: Response, next: NextFunction) => {\n const span = tracer.startSpan('GET /shipments/:id');\n span.setAttribute('shipment.id', req.params.id as string);\n const controller = new AbortController();\n req.on('close', () => controller.abort());\n try {\n const targetStatus = (req.query.targetStatus as string) || 'delivered';\n const result = await handlers.trackShipment(req.params.id as string, targetStatus);\n res.json(result);\n } catch (err) { next(err); } finally { span.end(); }\n });\n\n router.post('/webhooks', async (req: Request, res: Response, next: NextFunction) => {\n const span = tracer.startSpan('POST /webhooks');\n const sigHeader = req.headers['x-websignature'];\n const sig = Array.isArray(sigHeader) ? sigHeader[0] : sigHeader;\n span.setAttribute('webhook.signature', sig || 'none');\n try {\n if (!sig) return res.status(401).json({ error: 'Missing signature header' });\n await handlers.webhook(sig, JSON.stringify(req.body));\n res.status(200).json({ received: true });\n } catch (err) { next(err); } finally { span.end(); }\n });\n\n return router;\n}\n","import { RequestHandler } from 'express';\n\nexport interface AuthGuardConfig {\n tokenManager: { getToken(): string | null };\n}\n\nexport function createAuthGuard(config: AuthGuardConfig): RequestHandler {\n return (req, res, next) => {\n const authHeader = req.headers['authorization'];\n if (!authHeader || !authHeader.startsWith('Bearer ')) {\n res.status(401).json({ error: 'Missing or invalid Authorization header' });\n return;\n }\n const token = authHeader.slice(7);\n if (!token || token.length < 10) {\n res.status(401).json({ error: 'Invalid token format' });\n return;\n }\n next();\n };\n}\n","export interface MetricsSnapshot {\n totalRequests: number;\n failedRequests: number;\n circuitBreakerTrips: number;\n averageResponseTimeMs: number;\n}\n\nexport class MetricsCollector {\n private totalRequests = 0;\n private failedRequests = 0;\n private circuitBreakerTrips = 0;\n private responseTimes: number[] = [];\n private readonly maxSamples = 1000;\n\n recordRequest(durationMs: number, success: boolean): void {\n this.totalRequests++;\n this.responseTimes.push(durationMs);\n if (this.responseTimes.length > this.maxSamples) {\n this.responseTimes.shift();\n }\n if (!success) this.failedRequests++;\n }\n\n recordCircuitBreakerTrip() {\n this.circuitBreakerTrips++;\n }\n\n snapshot(): MetricsSnapshot {\n const avg = this.responseTimes.length\n ? this.responseTimes.reduce((a, b) => a + b, 0) / this.responseTimes.length\n : 0;\n\n return {\n totalRequests: this.totalRequests,\n failedRequests: this.failedRequests,\n circuitBreakerTrips: this.circuitBreakerTrips,\n averageResponseTimeMs: Math.round(avg)\n };\n }\n\n reset() {\n this.totalRequests = 0;\n this.failedRequests = 0;\n this.circuitBreakerTrips = 0;\n this.responseTimes = [];\n }\n}\n","import { SdkEnvironment } from '../../domain/types/environment.types';\n\nexport function validateEnvironment(baseURL: string, apiKey?: string): { environment: SdkEnvironment; warnings: string[] } {\n const warnings: string[] = [];\n\n let environment: SdkEnvironment;\n if (baseURL.includes('sandbox') || baseURL.includes('staging') || baseURL.includes('test')) {\n environment = 'test';\n } else if (baseURL.includes('weshipyou.com/api/v1')) {\n environment = 'production';\n } else {\n environment = 'production';\n }\n\n if (apiKey) {\n if (apiKey.startsWith('test_') && environment === 'production') {\n warnings.push('API key starts with \"test_\" but environment is production');\n }\n if (apiKey.startsWith('live_') && environment === 'test') {\n warnings.push('API key starts with \"live_\" but environment is test');\n }\n }\n\n return { environment, warnings };\n}\n","import { z } from 'zod';\n\nexport const WebhookPayloadSchema = z.object({\n eventType: z.string().min(1),\n payload: z.record(z.unknown()).default({}),\n timestamp: z.string().datetime().optional(),\n});\n","import { InMemoryTokenManager } from '../logging/token-manager.impl';\nimport { AxiosHttpClient } from '../http/axios-http-client';\nimport { AuthService } from '../../application/services/auth.service';\nimport { ShipmentService } from '../../application/services/shipment.service';\nimport { AccountService } from '../../application/services/account.service';\nimport { MobileRechargeService } from '../../application/services/mobile-recharge.service';\nimport { PollingService } from '../../application/services/polling.service';\nimport { GetRatesUseCase } from '../../application/use-cases/get-rates.use-case';\nimport { CreateShipmentUseCase } from '../../application/use-cases/create-shipment.use-case';\nimport { CreateSubAccountUseCase } from '../../application/use-cases/create-sub-account.use-case';\nimport { ExecuteRechargeUseCase } from '../../application/use-cases/execute-recharge.use-case';\nimport { TrackShipmentUseCase } from '../../application/use-cases/track-shipment.use-case';\nimport { HandleWebhookUseCase } from '../../application/use-cases/handle-webhook.use-case';\nimport { CircuitBreaker } from '../resilience/circuit-breaker.impl';\nimport { ExpressRateLimiter } from '../rate-limiter/express-rate-limiter.impl';\nimport { OtelTracer } from '../observability/otel-tracer.impl';\nimport { initOpenTelemetry } from '../observability/otel-instrumentation';\nimport { createRouter, RouteHandlers } from '../web/express-router';\nimport { createAuthGuard } from '../web/auth-guard.middleware';\nimport { MetricsCollector } from '../logging/metrics-collector';\nimport { IRateLimiter } from '../../domain/interfaces/rate-limiter.interface';\nimport { ITracer } from '../../domain/interfaces/tracer.interface';\nimport { IHttpClient } from '../../domain/interfaces/http-client.interface';\nimport { ICircuitBreaker } from '../../domain/interfaces/circuit-breaker.interface';\nimport { Router } from 'express';\nimport { validateEnvironment } from '../config/env.validator';\nimport { WebhookPayloadSchema } from '../../domain/validators/webhook.validator';\n\nexport interface Services {\n auth: AuthService;\n httpClient: IHttpClient;\n getRates: GetRatesUseCase;\n createShipment: CreateShipmentUseCase;\n createSubAccount: CreateSubAccountUseCase;\n executeRecharge: ExecuteRechargeUseCase;\n trackShipment: TrackShipmentUseCase;\n webhookHandler: HandleWebhookUseCase;\n pollingService: PollingService;\n circuitBreaker: ICircuitBreaker;\n metricsCollector: MetricsCollector;\n rateLimiter: IRateLimiter;\n tracer: ITracer;\n router: Router;\n}\n\nexport interface WebhookConfig {\n secret: string;\n algorithm?: string;\n}\n\nexport function bootstrap(\n baseURL: string,\n webhookConfig?: WebhookConfig | string,\n otelEndpoint?: string\n): Services {\n const { warnings } = validateEnvironment(baseURL);\n warnings.forEach(w => console.warn(w));\n\n if (otelEndpoint) {\n process.env.OTEL_ENDPOINT = otelEndpoint;\n }\n if (process.env.OTEL_ENDPOINT) {\n initOpenTelemetry();\n }\n\n const tokenManager = new InMemoryTokenManager();\n const circuitBreaker = new CircuitBreaker(5, 30000);\n const pollingService = new PollingService();\n const metricsCollector = new MetricsCollector();\n const rateLimiter = new ExpressRateLimiter();\n const tracer = new OtelTracer();\n\n const httpClient = new AxiosHttpClient(\n baseURL,\n tokenManager,\n async () => {\n throw new Error('Auto-refresh credentials not configured');\n }\n );\n\n const authService = new AuthService(httpClient, tokenManager);\n const shipmentService = new ShipmentService(httpClient);\n const accountService = new AccountService(httpClient);\n const rechargeService = new MobileRechargeService(httpClient);\n\n let webhookSecret: string;\n let webhookAlgorithm: string | undefined;\n if (typeof webhookConfig === 'string') {\n webhookSecret = webhookConfig;\n webhookAlgorithm = undefined;\n } else if (webhookConfig) {\n webhookSecret = webhookConfig.secret;\n webhookAlgorithm = webhookConfig.algorithm;\n } else {\n throw new Error('Webhook secret is required');\n }\n const webhookHandler = new HandleWebhookUseCase(webhookSecret, webhookAlgorithm);\n\n const getRates = new GetRatesUseCase(authService, shipmentService);\n const createShipment = new CreateShipmentUseCase(authService, shipmentService);\n const createSubAccount = new CreateSubAccountUseCase(authService, accountService);\n const executeRecharge = new ExecuteRechargeUseCase(authService, rechargeService);\n const trackShipment = new TrackShipmentUseCase(httpClient, pollingService, circuitBreaker);\n\n const handlers: RouteHandlers = {\n rates: (body: unknown) => {\n const req = body as Record<string, unknown>;\n const { username, password, ...payload } = req;\n return getRates.execute(username as string, password as string, payload as any);\n },\n createShipment: (body: unknown) => {\n const req = body as Record<string, unknown>;\n const { username, password, ...payload } = req;\n return createShipment.execute(username as string, password as string, payload as any);\n },\n trackShipment: (id: string, targetStatus: string) =>\n trackShipment.execute(id, targetStatus),\n webhook: async (signature: string, rawBody: string) => {\n if (!webhookHandler.verifySignature(rawBody, signature)) {\n throw new Error('Invalid webhook signature');\n }\n const parsed = JSON.parse(rawBody);\n const validated = WebhookPayloadSchema.parse(parsed);\n await webhookHandler.handle(validated as any);\n }\n };\n\n const router = createRouter(rateLimiter, tracer, handlers, createAuthGuard({ tokenManager }));\n\n return {\n auth: authService,\n httpClient,\n getRates,\n createShipment,\n createSubAccount,\n executeRecharge,\n trackShipment,\n webhookHandler,\n pollingService,\n circuitBreaker,\n metricsCollector,\n rateLimiter,\n tracer,\n router\n };\n}\n","import { ICircuitBreaker, CircuitState } from '../../domain/interfaces/circuit-breaker.interface';\nimport CircuitBreaker from 'opossum';\n\ninterface OpossumInstance {\n fire<T>(...args: unknown[]): Promise<T>;\n reset(): void;\n readonly stats: {\n failures: number;\n successes: number;\n timeouts: number;\n rejects: number;\n };\n}\n\nfunction createBreaker(opts: {\n timeout: number;\n errorThresholdPercentage: number;\n resetTimeout: number;\n}): OpossumInstance {\n const breaker = new CircuitBreaker(\n (fn: unknown) => Promise.resolve((fn as () => unknown)()),\n opts\n );\n return breaker as unknown as OpossumInstance;\n}\n\nexport class OpossumCircuitBreaker implements ICircuitBreaker {\n private breaker: OpossumInstance;\n\n constructor(\n options: {\n timeout?: number;\n errorThresholdPercentage?: number;\n resetTimeout?: number;\n } = {}\n ) {\n this.breaker = createBreaker({\n timeout: 10000,\n errorThresholdPercentage: 50,\n resetTimeout: 30000,\n ...options\n });\n }\n\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n return await this.breaker.fire<T>(fn);\n }\n\n getState(): CircuitState {\n const s = this.breaker.stats;\n const total = s.failures + s.successes;\n if (total === 0) return 'CLOSED';\n const rate = (s.failures / total) * 100;\n if (rate >= 50) return 'OPEN';\n return 'CLOSED';\n }\n\n reset(): void {\n this.breaker.reset();\n }\n\n getMetrics() {\n const s = this.breaker.stats;\n return {\n success: s.successes,\n failure: s.failures,\n timeout: s.timeouts,\n rejection: s.rejects\n };\n }\n}\n","import { ISecurityMiddleware } from '../../domain/interfaces/security.interface';\nimport helmet from 'helmet';\nimport { RequestHandler } from 'express';\n\nexport class HelmetCspMiddleware implements ISecurityMiddleware {\n getHandler(): RequestHandler {\n return helmet({\n contentSecurityPolicy: {\n directives: {\n defaultSrc: [\"'self'\"],\n scriptSrc: [\"'self'\"],\n styleSrc: [\"'self'\", \"'unsafe-inline'\"],\n imgSrc: [\"'self'\", 'data:', 'https:'],\n connectSrc: [\"'self'\", 'https://weshipyou.com'],\n fontSrc: [\"'self'\"],\n objectSrc: [\"'none'\"],\n upgradeInsecureRequests: []\n }\n },\n crossOriginEmbedderPolicy: true,\n crossOriginOpenerPolicy: true,\n crossOriginResourcePolicy: { policy: 'same-site' },\n originAgentCluster: true,\n referrerPolicy: { policy: 'strict-origin-when-cross-origin' },\n strictTransportSecurity: { maxAge: 31536000, includeSubDomains: true },\n xContentTypeOptions: true,\n xDnsPrefetchControl: true,\n xDownloadOptions: true,\n xFrameOptions: { action: 'sameorigin' },\n xPermittedCrossDomainPolicies: { permittedPolicies: 'none' },\n xXssProtection: true\n });\n }\n}\n","import { DomainEvent } from '../interfaces/event-store.interface';\n\nexport class WebhookReceivedEvent implements DomainEvent {\n readonly type = 'webhook.received';\n constructor(\n public readonly eventId: string,\n public readonly aggregateId: string,\n public readonly payload: { eventType: string; signature: string; body: string },\n public readonly timestamp: string = new Date().toISOString(),\n public readonly version: number = 1\n ) {}\n}\n\nexport class WebhookProcessedEvent implements DomainEvent {\n readonly type = 'webhook.processed';\n constructor(\n public readonly eventId: string,\n public readonly aggregateId: string,\n public readonly payload: { eventType: string; success: boolean; error?: string },\n public readonly timestamp: string = new Date().toISOString(),\n public readonly version: number = 1\n ) {}\n}\n","import { randomUUID } from 'crypto';\nimport { IEventStore, DomainEvent } from '../../domain/interfaces/event-store.interface';\nimport { IHttpClient } from '../../domain/interfaces/http-client.interface';\nimport { ShipmentCreatedEvent, ShipmentStatusChangedEvent } from '../../domain/events/shipment.events';\n\nexport class ShipmentReconciliationSaga {\n constructor(\n private readonly eventStore: IEventStore,\n private readonly httpClient: IHttpClient\n ) {}\n\n async onShipmentCreated(event: ShipmentCreatedEvent): Promise<void> {\n await this.eventStore.append(event.aggregateId, [event]);\n }\n\n async onShipmentStatusChanged(event: ShipmentStatusChangedEvent): Promise<void> {\n await this.eventStore.append(event.aggregateId, [\n new ShipmentStatusChangedEvent(\n crypto.randomUUID(),\n event.aggregateId,\n { ...event.payload },\n new Date().toISOString(),\n event.version + 1\n )\n ]);\n }\n\n async onWebhookReceived(event: DomainEvent): Promise<void> {\n if (event.type === 'shipment.status_changed') {\n const reconciled = new ShipmentStatusChangedEvent(\n crypto.randomUUID(),\n event.aggregateId,\n {\n status: (event.payload as Record<string, unknown>).status as string,\n previousStatus: (event.payload as Record<string, unknown>).previousStatus as string,\n updatedAt: new Date().toISOString()\n },\n new Date().toISOString(),\n event.version + 1\n );\n await this.eventStore.append(event.aggregateId, [reconciled]);\n }\n }\n}\n","export type { IHttpClient, HttpRequest, HttpResponse } from '../domain/interfaces/http-client.interface';\nexport type { ITokenManager } from '../domain/interfaces/token-manager.interface';\nexport type { IRateLimiter } from '../domain/interfaces/rate-limiter.interface';\nexport type { ITracer, ISpan } from '../domain/interfaces/tracer.interface';\nexport type { ICircuitBreaker, CircuitState } from '../domain/interfaces/circuit-breaker.interface';\nexport type { IPollingService, PollingOptions } from '../domain/interfaces/polling.interface';\nexport type { IWebhookHandler, IWebhookEvent } from '../domain/interfaces/webhook.interface';\nexport type { IEventStore, DomainEvent } from '../domain/interfaces/event-store.interface';\nexport type { ISecurityMiddleware } from '../domain/interfaces/security.interface';\nexport type { IPaginatedResponse, IQueryPagination } from '../domain/interfaces/pagination.interface';\n\nexport type {\n IRateRequest,\n IShipmentRequest,\n Parcel,\n ParcelItem,\n RatesAddress,\n SenderRecipientBase,\n ShipmentSender,\n ShipmentRecipient,\n Incoterms,\n DimUnit,\n WeightUnit\n} from '../domain/interfaces/shipment.interface';\n\nexport type { ShipmentStatus } from '../application/use-cases/track-shipment.use-case';\n\nexport type { Services, WebhookConfig } from '../infrastructure/di/bootstrap';\nexport type { SdkEnvironment } from '../domain/types/environment.types';\nexport type { Shutdownable } from '../infrastructure/web/server';\nexport { gracefulShutdown } from '../infrastructure/web/server';\n\nexport { bootstrap } from '../infrastructure/di/bootstrap';\nexport { GetRatesUseCase } from '../application/use-cases/get-rates.use-case';\nexport { CreateShipmentUseCase } from '../application/use-cases/create-shipment.use-case';\nexport { UpdateShipmentUseCase } from '../application/use-cases/update-shipment.use-case';\nexport { TrackShipmentUseCase } from '../application/use-cases/track-shipment.use-case';\nexport { HandleWebhookUseCase } from '../application/use-cases/handle-webhook.use-case';\nexport { CreateSubAccountUseCase } from '../application/use-cases/create-sub-account.use-case';\nexport { ExecuteRechargeUseCase } from '../application/use-cases/execute-recharge.use-case';\n\nexport { AuthService } from '../application/services/auth.service';\nexport { ShipmentService } from '../application/services/shipment.service';\nexport { AccountService } from '../application/services/account.service';\nexport { MobileRechargeService } from '../application/services/mobile-recharge.service';\nexport { PollingService } from '../application/services/polling.service';\n\nexport { AxiosHttpClient } from '../infrastructure/http/axios-http-client';\nexport { InMemoryTokenManager } from '../infrastructure/logging/token-manager.impl';\nexport { CircuitBreaker } from '../infrastructure/resilience/circuit-breaker.impl';\nexport { OpossumCircuitBreaker } from '../infrastructure/resilience/opossum-circuit-breaker.impl';\nexport { ExpressRateLimiter } from '../infrastructure/rate-limiter/express-rate-limiter.impl';\nexport { OtelTracer } from '../infrastructure/observability/otel-tracer.impl';\nexport { initOpenTelemetry, shutdownOpenTelemetry } from '../infrastructure/observability/otel-instrumentation';\nexport { SqliteEventStore } from '../infrastructure/event-store/sqlite-event-store.impl';\nexport { HelmetCspMiddleware } from '../infrastructure/security/helmet-csp.impl';\nexport { MetricsCollector } from '../infrastructure/logging/metrics-collector';\n\nexport { ShipmentCreatedEvent, ShipmentUpdatedEvent, ShipmentStatusChangedEvent } from '../domain/events/shipment.events';\nexport { WebhookReceivedEvent, WebhookProcessedEvent } from '../domain/events/webhook.events';\nexport { ShipmentReconciliationSaga } from '../application/sagas/shipment-reconciliation.saga';\n\nexport const SDK_VERSION = '1.0.0';\n"],"mappings":"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","names":["gracefulShutdown","server","deps","timeout","timer","d","InMemoryTokenManager","token","exp","axios","ApiError","statusCode","message","details","AuthError","RateLimitError","randomUUID","pino","logger","AxiosHttpClient","baseURL","tokenManager","refreshTokenFn","retries","baseDelayMs","idempotencyPaths","onRateLimit","axios","config","token","res","err","originalRequest","accessToken","exp","AuthError","status","data","RateLimitError","ApiError","attempt","axiosConfig","pattern","response","remaining","limit","reset","error","isRetryable","AuthService","httpClient","tokenManager","username","password","lang","data","AccountService","httpClient","payload","lang","MobileRechargeService","httpClient","payload","lang","limit","PollingService","fn","condition","opts","maxAttempts","baseDelayMs","abortSignal","attempt","result","delay","res","GetRatesUseCase","authService","shipmentService","username","password","payload","lang","CreateShipmentUseCase","authService","shipmentService","username","password","payload","lang","z","AddSubAccountSchema","ValidationError","details","CreateSubAccountUseCase","authService","accountService","username","password","payload","lang","parsed","AddSubAccountSchema","ValidationError","z","CreateRechargeSchema","ExecuteRechargeUseCase","authService","rechargeService","username","password","payload","lang","parsed","CreateRechargeSchema","ValidationError","TrackShipmentUseCase","httpClient","pollingService","circuitBreaker","shipmentId","targetStatus","abortSignal","lang","pollFn","status","createHmac","timingSafeEqual","HandleWebhookUseCase","secret","algorithm","rawBody","signature","key","algo","expected","event","CircuitBreaker","failureThreshold","resetTimeoutMs","fn","now","result","error","rateLimit","ExpressRateLimiter","opts","_key","_tokens","req","res","next","trace","NodeSDK","getNodeAutoInstrumentations","OTLPTraceExporter","sdk","initOpenTelemetry","serviceName","shutdownOpenTelemetry","OtelTracer","trace","name","attributes","span","k","v","shutdownOpenTelemetry","Router","createRouter","rateLimiter","tracer","handlers","authGuard","router","req","res","next","span","result","err","controller","targetStatus","sigHeader","sig","createAuthGuard","config","req","res","next","authHeader","token","MetricsCollector","durationMs","success","avg","a","b","validateEnvironment","baseURL","apiKey","warnings","environment","z","WebhookPayloadSchema","bootstrap","baseURL","webhookConfig","otelEndpoint","warnings","validateEnvironment","w","initOpenTelemetry","tokenManager","InMemoryTokenManager","circuitBreaker","CircuitBreaker","pollingService","PollingService","metricsCollector","MetricsCollector","rateLimiter","ExpressRateLimiter","tracer","OtelTracer","httpClient","AxiosHttpClient","authService","AuthService","shipmentService","ShipmentService","accountService","AccountService","rechargeService","MobileRechargeService","webhookSecret","webhookAlgorithm","webhookHandler","HandleWebhookUseCase","getRates","GetRatesUseCase","createShipment","CreateShipmentUseCase","createSubAccount","CreateSubAccountUseCase","executeRecharge","ExecuteRechargeUseCase","trackShipment","TrackShipmentUseCase","router","createRouter","body","req","username","password","payload","id","targetStatus","signature","rawBody","parsed","validated","WebhookPayloadSchema","createAuthGuard","CircuitBreaker","createBreaker","opts","fn","OpossumCircuitBreaker","options","s","total","helmet","HelmetCspMiddleware","WebhookReceivedEvent","eventId","aggregateId","payload","timestamp","version","WebhookProcessedEvent","ShipmentReconciliationSaga","eventStore","httpClient","event","ShipmentStatusChangedEvent","reconciled","SDK_VERSION"]}
@@ -0,0 +1,504 @@
1
+ import { z } from 'zod';
2
+ import { Router } from 'express';
3
+
4
+ interface HttpRequest {
5
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
6
+ url: string;
7
+ body?: Record<string, unknown>;
8
+ headers?: Record<string, string>;
9
+ }
10
+ interface HttpResponse<T = unknown> {
11
+ status: number;
12
+ data: T;
13
+ headers: Record<string, string>;
14
+ }
15
+ interface IHttpClient {
16
+ request<T>(config: HttpRequest): Promise<HttpResponse<T>>;
17
+ }
18
+
19
+ interface ITokenManager {
20
+ setToken(token: string, exp: number): void;
21
+ getToken(): string | null;
22
+ isExpired(): boolean;
23
+ clear(): void;
24
+ }
25
+
26
+ declare enum AcceptLanguage {
27
+ EN_US = "en-US",
28
+ ES_ES = "es-ES",
29
+ PT_BR = "pt-BR"
30
+ }
31
+
32
+ interface AuthResponse {
33
+ accessToken: string;
34
+ exp?: number;
35
+ }
36
+ interface IAuthService {
37
+ authenticate(username: string, password: string, lang?: AcceptLanguage): Promise<AuthResponse>;
38
+ }
39
+ declare class AuthService implements IAuthService {
40
+ private readonly httpClient;
41
+ private readonly tokenManager?;
42
+ constructor(httpClient: IHttpClient, tokenManager?: ITokenManager | undefined);
43
+ authenticate(username: string, password: string, lang?: AcceptLanguage): Promise<AuthResponse>;
44
+ }
45
+
46
+ interface PollingOptions {
47
+ maxAttempts: number;
48
+ baseDelayMs: number;
49
+ abortSignal?: AbortSignal;
50
+ }
51
+ interface IPollingService {
52
+ pollUntil<T>(fn: () => Promise<T>, condition: (result: T) => boolean, opts?: Partial<PollingOptions>): Promise<T>;
53
+ }
54
+
55
+ declare class PollingService implements IPollingService {
56
+ pollUntil<T>(fn: () => Promise<T>, condition: (result: T) => boolean, opts?: Partial<PollingOptions>): Promise<T>;
57
+ }
58
+
59
+ interface CityState {
60
+ name: string;
61
+ }
62
+ interface City {
63
+ name: string;
64
+ state: CityState;
65
+ }
66
+ interface RatesAddress {
67
+ city: City;
68
+ street: string;
69
+ postalCode: string;
70
+ }
71
+ interface SenderRecipientBase {
72
+ address: RatesAddress;
73
+ country: {
74
+ isoCode: string;
75
+ };
76
+ }
77
+ type DimUnit = 'cm' | 'in';
78
+ type WeightUnit = 'gm' | 'kg' | 'oz' | 'lb';
79
+ type Incoterms = 'DDU' | 'DDP';
80
+ interface ParcelItemCategory {
81
+ slug: string;
82
+ }
83
+ interface ParcelItemCurrency {
84
+ name: string;
85
+ code: string;
86
+ prefix: string;
87
+ }
88
+ interface ParcelItem {
89
+ sku?: string;
90
+ description: string;
91
+ category: ParcelItemCategory;
92
+ price: number;
93
+ qty: number;
94
+ originCountry?: {
95
+ isoCode: string;
96
+ };
97
+ weight?: number;
98
+ currency: string | ParcelItemCurrency;
99
+ }
100
+ interface Parcel {
101
+ dimUnit: DimUnit;
102
+ width: number;
103
+ length: number;
104
+ height: number;
105
+ weightUnit: WeightUnit;
106
+ weight: number;
107
+ parcel_items: ParcelItem[];
108
+ }
109
+ interface IRateRequest {
110
+ accountId: string;
111
+ totalValue: number;
112
+ incoterms: Incoterms;
113
+ insurance?: boolean;
114
+ sender: SenderRecipientBase;
115
+ recipient: SenderRecipientBase;
116
+ parcels: Parcel[];
117
+ }
118
+ interface ShipmentSender {
119
+ name: string;
120
+ email: string;
121
+ phone: string;
122
+ companyName?: string;
123
+ taxId?: string;
124
+ taxIdCountry?: {
125
+ isoCode: string;
126
+ };
127
+ address: RatesAddress;
128
+ country: {
129
+ isoCode: string;
130
+ };
131
+ }
132
+ interface ShipmentRecipient {
133
+ name: string;
134
+ email: string;
135
+ phone: string;
136
+ companyName?: string;
137
+ taxId?: string;
138
+ taxIdCountry?: {
139
+ isoCode: string;
140
+ };
141
+ address: RatesAddress;
142
+ country: {
143
+ isoCode: string;
144
+ };
145
+ }
146
+ interface IShipmentRequest {
147
+ accountId: string;
148
+ totalValue: number;
149
+ incoterms: Incoterms;
150
+ insurance?: boolean;
151
+ externalReferenceCode?: string;
152
+ externalCustomerId?: string;
153
+ sender: ShipmentSender;
154
+ recipient: ShipmentRecipient;
155
+ parcels: Parcel[];
156
+ }
157
+
158
+ interface IShipmentService {
159
+ getRates(payload: IRateRequest, lang?: AcceptLanguage): Promise<unknown>;
160
+ createShipment(payload: IShipmentRequest, lang?: AcceptLanguage): Promise<unknown>;
161
+ updateShipment(id: string, payload: Partial<IShipmentRequest>, lang?: AcceptLanguage): Promise<unknown>;
162
+ getCountryCategories(countryCode: string, lang?: AcceptLanguage): Promise<unknown>;
163
+ }
164
+ declare class ShipmentService implements IShipmentService {
165
+ private readonly httpClient;
166
+ private categoryCache;
167
+ constructor(httpClient: IHttpClient);
168
+ getRates(payload: IRateRequest, lang?: AcceptLanguage): Promise<unknown>;
169
+ createShipment(payload: IShipmentRequest, lang?: AcceptLanguage): Promise<unknown>;
170
+ updateShipment(id: string, payload: Partial<IShipmentRequest>, lang?: AcceptLanguage): Promise<unknown>;
171
+ getCountryCategories(countryCode: string, lang?: AcceptLanguage): Promise<unknown>;
172
+ }
173
+
174
+ declare class GetRatesUseCase {
175
+ private readonly authService;
176
+ private readonly shipmentService;
177
+ constructor(authService: IAuthService, shipmentService: IShipmentService);
178
+ execute(username: string, password: string, payload: IRateRequest, lang?: AcceptLanguage): Promise<unknown>;
179
+ }
180
+
181
+ declare class CreateShipmentUseCase {
182
+ private readonly authService;
183
+ private readonly shipmentService;
184
+ constructor(authService: IAuthService, shipmentService: IShipmentService);
185
+ execute(username: string, password: string, payload: IShipmentRequest, lang?: AcceptLanguage): Promise<unknown>;
186
+ }
187
+
188
+ declare const AddSubAccountSchema: z.ZodObject<{
189
+ accountUid: z.ZodOptional<z.ZodString>;
190
+ externalAccountNumber: z.ZodOptional<z.ZodString>;
191
+ name: z.ZodString;
192
+ displayName: z.ZodString;
193
+ systemUnits: z.ZodEnum<["imperial", "metric"]>;
194
+ email: z.ZodString;
195
+ notificationEmail: z.ZodString;
196
+ website: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
197
+ phone: z.ZodString;
198
+ emergencyPhone: z.ZodString;
199
+ taxId: z.ZodOptional<z.ZodString>;
200
+ taxIdCountry: z.ZodOptional<z.ZodObject<{
201
+ isoCode: z.ZodString;
202
+ }, "strip", z.ZodTypeAny, {
203
+ isoCode: string;
204
+ }, {
205
+ isoCode: string;
206
+ }>>;
207
+ isBusiness: z.ZodDefault<z.ZodBoolean>;
208
+ allowBankAccountPayments: z.ZodDefault<z.ZodBoolean>;
209
+ address: z.ZodOptional<z.ZodObject<{
210
+ street: z.ZodString;
211
+ city: z.ZodString;
212
+ state: z.ZodString;
213
+ postalCode: z.ZodString;
214
+ countryIsoCode: z.ZodString;
215
+ }, "strip", z.ZodTypeAny, {
216
+ street: string;
217
+ city: string;
218
+ state: string;
219
+ postalCode: string;
220
+ countryIsoCode: string;
221
+ }, {
222
+ street: string;
223
+ city: string;
224
+ state: string;
225
+ postalCode: string;
226
+ countryIsoCode: string;
227
+ }>>;
228
+ }, "strip", z.ZodTypeAny, {
229
+ name: string;
230
+ displayName: string;
231
+ systemUnits: "imperial" | "metric";
232
+ email: string;
233
+ notificationEmail: string;
234
+ phone: string;
235
+ emergencyPhone: string;
236
+ isBusiness: boolean;
237
+ allowBankAccountPayments: boolean;
238
+ accountUid?: string | undefined;
239
+ externalAccountNumber?: string | undefined;
240
+ website?: string | undefined;
241
+ taxId?: string | undefined;
242
+ taxIdCountry?: {
243
+ isoCode: string;
244
+ } | undefined;
245
+ address?: {
246
+ street: string;
247
+ city: string;
248
+ state: string;
249
+ postalCode: string;
250
+ countryIsoCode: string;
251
+ } | undefined;
252
+ }, {
253
+ name: string;
254
+ displayName: string;
255
+ systemUnits: "imperial" | "metric";
256
+ email: string;
257
+ notificationEmail: string;
258
+ phone: string;
259
+ emergencyPhone: string;
260
+ accountUid?: string | undefined;
261
+ externalAccountNumber?: string | undefined;
262
+ website?: string | undefined;
263
+ taxId?: string | undefined;
264
+ taxIdCountry?: {
265
+ isoCode: string;
266
+ } | undefined;
267
+ isBusiness?: boolean | undefined;
268
+ allowBankAccountPayments?: boolean | undefined;
269
+ address?: {
270
+ street: string;
271
+ city: string;
272
+ state: string;
273
+ postalCode: string;
274
+ countryIsoCode: string;
275
+ } | undefined;
276
+ }>;
277
+ type AddSubAccountInput = z.infer<typeof AddSubAccountSchema>;
278
+
279
+ interface IAccountService {
280
+ addSubAccount(payload: AddSubAccountInput, lang?: AcceptLanguage): Promise<unknown>;
281
+ addFunds(payload: {
282
+ paymentMethod?: string;
283
+ accountUid?: string;
284
+ transaction: {
285
+ zelleTransaction: string;
286
+ amount: number;
287
+ };
288
+ }, lang?: AcceptLanguage): Promise<unknown>;
289
+ }
290
+ declare class AccountService implements IAccountService {
291
+ private readonly httpClient;
292
+ constructor(httpClient: IHttpClient);
293
+ addSubAccount(payload: AddSubAccountInput, lang?: AcceptLanguage): Promise<unknown>;
294
+ addFunds(payload: {
295
+ paymentMethod?: string;
296
+ accountUid?: string;
297
+ transaction: {
298
+ zelleTransaction: string;
299
+ amount: number;
300
+ };
301
+ }, lang?: AcceptLanguage): Promise<unknown>;
302
+ }
303
+
304
+ declare class CreateSubAccountUseCase {
305
+ private readonly authService;
306
+ private readonly accountService;
307
+ constructor(authService: IAuthService, accountService: IAccountService);
308
+ execute(username: string, password: string, payload: unknown, lang?: AcceptLanguage): Promise<unknown>;
309
+ }
310
+
311
+ declare const CreateRechargeSchema: z.ZodObject<{
312
+ paymentMethod: z.ZodDefault<z.ZodEnum<["zelle", "credit_card", "balance"]>>;
313
+ accountUid: z.ZodOptional<z.ZodString>;
314
+ rechargeable_product: z.ZodObject<{
315
+ id: z.ZodNumber;
316
+ }, "strip", z.ZodTypeAny, {
317
+ id: number;
318
+ }, {
319
+ id: number;
320
+ }>;
321
+ scheduleDate: z.ZodNullable<z.ZodOptional<z.ZodString>>;
322
+ amount: z.ZodNumber;
323
+ account_rechargeable_contact: z.ZodObject<{
324
+ name: z.ZodString;
325
+ accountNumber: z.ZodString;
326
+ }, "strip", z.ZodTypeAny, {
327
+ name: string;
328
+ accountNumber: string;
329
+ }, {
330
+ name: string;
331
+ accountNumber: string;
332
+ }>;
333
+ }, "strip", z.ZodTypeAny, {
334
+ paymentMethod: "zelle" | "credit_card" | "balance";
335
+ rechargeable_product: {
336
+ id: number;
337
+ };
338
+ amount: number;
339
+ account_rechargeable_contact: {
340
+ name: string;
341
+ accountNumber: string;
342
+ };
343
+ accountUid?: string | undefined;
344
+ scheduleDate?: string | null | undefined;
345
+ }, {
346
+ rechargeable_product: {
347
+ id: number;
348
+ };
349
+ amount: number;
350
+ account_rechargeable_contact: {
351
+ name: string;
352
+ accountNumber: string;
353
+ };
354
+ accountUid?: string | undefined;
355
+ paymentMethod?: "zelle" | "credit_card" | "balance" | undefined;
356
+ scheduleDate?: string | null | undefined;
357
+ }>;
358
+ type CreateRechargeInput = z.infer<typeof CreateRechargeSchema>;
359
+
360
+ interface IMobileRechargeService {
361
+ createRecharge(payload: CreateRechargeInput, lang?: AcceptLanguage): Promise<unknown>;
362
+ getRecharges(limit?: number, lang?: AcceptLanguage): Promise<unknown>;
363
+ }
364
+ declare class MobileRechargeService implements IMobileRechargeService {
365
+ private readonly httpClient;
366
+ constructor(httpClient: IHttpClient);
367
+ createRecharge(payload: CreateRechargeInput, lang?: AcceptLanguage): Promise<unknown>;
368
+ getRecharges(limit?: number, lang?: AcceptLanguage): Promise<unknown>;
369
+ }
370
+
371
+ declare class ExecuteRechargeUseCase {
372
+ private readonly authService;
373
+ private readonly rechargeService;
374
+ constructor(authService: IAuthService, rechargeService: IMobileRechargeService);
375
+ execute(username: string, password: string, payload: unknown, lang?: AcceptLanguage): Promise<unknown>;
376
+ }
377
+
378
+ type CircuitState = 'CLOSED' | 'OPEN' | 'HALF-OPEN';
379
+ interface ICircuitBreaker {
380
+ execute<T>(fn: () => Promise<T>): Promise<T>;
381
+ getState(): CircuitState;
382
+ reset(): void;
383
+ }
384
+
385
+ interface ShipmentStatus {
386
+ id: string;
387
+ status: string;
388
+ trackingNumber?: string;
389
+ updatedAt: string;
390
+ }
391
+ declare class TrackShipmentUseCase {
392
+ private readonly httpClient;
393
+ private readonly pollingService;
394
+ private readonly circuitBreaker;
395
+ constructor(httpClient: IHttpClient, pollingService: IPollingService, circuitBreaker: ICircuitBreaker);
396
+ execute(shipmentId: string, targetStatus: string, abortSignal?: AbortSignal, lang?: AcceptLanguage): Promise<ShipmentStatus>;
397
+ }
398
+
399
+ interface IWebhookEvent {
400
+ eventType: string;
401
+ payload: unknown;
402
+ timestamp: string;
403
+ }
404
+ interface IWebhookHandler {
405
+ verifySignature(rawBody: string, signature: string, secret?: string, algorithm?: string): boolean;
406
+ handle(event: IWebhookEvent): Promise<void>;
407
+ }
408
+
409
+ declare class HandleWebhookUseCase implements IWebhookHandler {
410
+ private readonly secret;
411
+ private readonly algorithm;
412
+ constructor(secret: string, algorithm?: string);
413
+ verifySignature(rawBody: string, signature: string, secret?: string, algorithm?: string): boolean;
414
+ handle(event: IWebhookEvent): Promise<void>;
415
+ }
416
+
417
+ interface MetricsSnapshot {
418
+ totalRequests: number;
419
+ failedRequests: number;
420
+ circuitBreakerTrips: number;
421
+ averageResponseTimeMs: number;
422
+ }
423
+ declare class MetricsCollector {
424
+ private totalRequests;
425
+ private failedRequests;
426
+ private circuitBreakerTrips;
427
+ private responseTimes;
428
+ private readonly maxSamples;
429
+ recordRequest(durationMs: number, success: boolean): void;
430
+ recordCircuitBreakerTrip(): void;
431
+ snapshot(): MetricsSnapshot;
432
+ reset(): void;
433
+ }
434
+
435
+ interface IRateLimiter {
436
+ consume(key: string, tokens?: number): Promise<{
437
+ remaining: number;
438
+ limit: number;
439
+ retryAfter?: number;
440
+ }>;
441
+ getMiddleware(): (req: any, res: any, next: any) => void;
442
+ }
443
+
444
+ interface ITracer {
445
+ startSpan(name: string, attributes?: Record<string, string | number | boolean>): ISpan;
446
+ }
447
+ interface ISpan {
448
+ setAttribute(key: string, value: string | number | boolean): void;
449
+ end(): void;
450
+ }
451
+
452
+ interface Services {
453
+ auth: AuthService;
454
+ httpClient: IHttpClient;
455
+ getRates: GetRatesUseCase;
456
+ createShipment: CreateShipmentUseCase;
457
+ createSubAccount: CreateSubAccountUseCase;
458
+ executeRecharge: ExecuteRechargeUseCase;
459
+ trackShipment: TrackShipmentUseCase;
460
+ webhookHandler: HandleWebhookUseCase;
461
+ pollingService: PollingService;
462
+ circuitBreaker: ICircuitBreaker;
463
+ metricsCollector: MetricsCollector;
464
+ rateLimiter: IRateLimiter;
465
+ tracer: ITracer;
466
+ router: Router;
467
+ }
468
+ interface WebhookConfig {
469
+ secret: string;
470
+ algorithm?: string;
471
+ }
472
+ declare function bootstrap(baseURL: string, webhookConfig?: WebhookConfig | string, otelEndpoint?: string): Services;
473
+
474
+ interface DomainEvent {
475
+ eventId: string;
476
+ aggregateId: string;
477
+ type: string;
478
+ payload: Record<string, unknown>;
479
+ timestamp: string;
480
+ version: number;
481
+ }
482
+ interface IEventStore {
483
+ append(aggregateId: string, events: DomainEvent[]): Promise<void>;
484
+ getByAggregate(aggregateId: string, sinceVersion?: number): Promise<DomainEvent[]>;
485
+ replay(sinceTimestamp?: string, handler?: (event: DomainEvent) => Promise<void>): Promise<void>;
486
+ }
487
+
488
+ declare class SqliteEventStore implements IEventStore {
489
+ private db;
490
+ constructor(dbPath?: string);
491
+ append(aggregateId: string, events: DomainEvent[]): Promise<void>;
492
+ getByAggregate(aggregateId: string, sinceVersion?: number): Promise<DomainEvent[]>;
493
+ replay(sinceTimestamp?: string, handler?: (event: DomainEvent) => Promise<void>): Promise<void>;
494
+ close(): void;
495
+ }
496
+
497
+ declare class UpdateShipmentUseCase {
498
+ private readonly authService;
499
+ private readonly shipmentService;
500
+ constructor(authService: IAuthService, shipmentService: IShipmentService);
501
+ execute(username: string, password: string, shipmentId: string, payload: Partial<IShipmentRequest>, lang?: AcceptLanguage): Promise<unknown>;
502
+ }
503
+
504
+ export { AcceptLanguage as A, type ShipmentSender as B, CreateShipmentUseCase as C, type DomainEvent as D, ExecuteRechargeUseCase as E, ShipmentService as F, GetRatesUseCase as G, type HttpRequest as H, type IHttpClient as I, type ShipmentStatus as J, type WeightUnit as K, bootstrap as L, MetricsCollector as M, type Parcel as P, type RatesAddress as R, SqliteEventStore as S, TrackShipmentUseCase as T, UpdateShipmentUseCase as U, type WebhookConfig as W, type IShipmentRequest as a, type IEventStore as b, type Services as c, type ITokenManager as d, type HttpResponse as e, type ICircuitBreaker as f, type CircuitState as g, type IRateLimiter as h, type ITracer as i, type ISpan as j, AccountService as k, AuthService as l, CreateSubAccountUseCase as m, type DimUnit as n, HandleWebhookUseCase as o, type IPollingService as p, type IRateRequest as q, type IWebhookEvent as r, type IWebhookHandler as s, type Incoterms as t, MobileRechargeService as u, type ParcelItem as v, type PollingOptions as w, PollingService as x, type SenderRecipientBase as y, type ShipmentRecipient as z };