Files
binect-js/src/types.ts
tegwick 397cd10a09 Add convenience helpers and improve documentation
- Add isInProduction() helper for checking status 3 or 4
- Add getErrorSummary() helper for extracting error messages
- Add fetchAllPages() pagination helper for auto-pagination
- Add comprehensive JSDoc to ListResponse interface
- Create ADR-001 documenting decision not to add listAll() method

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-16 22:30:36 +01:00

470 lines
9.8 KiB
TypeScript

/**
* Binect API Type Definitions
* Based on API specification v0.9.9
*/
// ============================================================================
// Enums
// ============================================================================
/**
* Document status codes as defined by the Binect API
*/
export enum DocumentStatus {
/** Document is being prepared/validated */
IN_PREPARATION = 1,
/** Document is ready to be shipped */
SHIPPABLE = 2,
/** Document is in production queue */
PRODUCTION_QUEUE = 3,
/** Document is being printed */
PRINTING = 4,
/** Document has been sent */
SENT = 5,
/** Document was canceled */
CANCELED = 6,
/** Document has errors */
ERRONEOUS = 7,
}
/**
* Envelope type options
*/
export enum EnvelopeType {
DINLANG = 'DINLANG',
C4 = 'C4',
}
/**
* Franking type options
*/
export enum FrankingType {
UNSPECIFIED = 'UNSPECIFIED',
STANDARD_FRANKING = 'STANDARD_FRANKING',
DV_FRANKING = 'DV_FRANKING',
}
/**
* Production country options
*/
export enum ProductionCountry {
UNSPECIFIED = 'UNSPECIFIED',
DE = 'DE',
AT = 'AT',
}
/**
* Response format options for document upload
*/
export enum ResponseFormat {
/** Complete validation results (default) */
FULL = 'FULL',
/** Minimal response; validation runs asynchronously */
SHORT = 'SHORT',
}
// ============================================================================
// Request Types
// ============================================================================
/**
* Options for uploading a document
*/
export interface DocumentUploadOptions {
/** Base64-encoded PDF content */
content: string;
/** Filename for the document (optional) */
filename?: string;
/** Whether to print in color (default: false) */
color?: boolean;
/** Whether to print simplex/single-sided (default: false, meaning duplex) */
simplex?: boolean;
/** Envelope type */
envelope?: EnvelopeType;
/** Franking type */
franking?: FrankingType;
/** Production country */
productionCountry?: ProductionCountry;
/** Response format */
responseFormat?: ResponseFormat;
/** Number of pages per letter for serial letter splitting */
pagesPerLetter?: number;
/** Token for serial letter splitting */
splitToken?: string;
/** Custom attributes as key-value pairs */
attributes?: DocumentAttribute[];
}
/**
* Internal API request body for document upload
* @internal
*/
export interface DocumentUploadRequestBody {
content: {
filename?: string;
content: string;
};
options?: {
simplex?: boolean;
color?: boolean;
envelope?: EnvelopeType;
franking?: FrankingType;
productionCountry?: ProductionCountry;
};
attributes?: DocumentAttribute[];
splitParams?: {
splitToken?: string;
splitAfterNumberOfPages?: number;
};
responseFormat?: ResponseFormat;
}
/**
* Options for uploading and immediately sending a document
*/
export interface DocumentUploadAndSendOptions extends DocumentUploadOptions {
/** Send immediately after upload */
send?: boolean;
}
/**
* Transformation parameters for document scaling/offset
*/
export interface DocumentTransformation {
/** Horizontal offset in mm */
offsetX?: number;
/** Vertical offset in mm */
offsetY?: number;
/** Scale factor (1.0 = 100%) */
scale?: number;
}
/**
* Cover page parameters
*/
export interface CoverPageOptions {
/** Base64-encoded PDF content for cover page */
content: string;
}
/**
* Key-value attribute
*/
export interface DocumentAttribute {
key: string;
value: string;
}
/**
* Pagination options for list endpoints
*/
export interface PaginationOptions {
/** Maximum number of results to return */
limit?: number;
/** Number of results to skip */
offset?: number;
/** Index signature for compatibility with query parameters */
[key: string]: number | undefined;
}
/**
* Options for announcing documents for sending
*/
export interface SendingAnnounceOptions {
/** Document IDs to announce */
documentIds: string[];
}
/**
* Options for canceling sendings
*/
export interface SendingCancelOptions {
/** Document IDs to cancel */
documentIds: string[];
}
/**
* Personal data update options
*/
export interface PersonalDataUpdate {
company?: string;
firstName?: string;
lastName?: string;
street?: string;
houseNumber?: string;
zipCode?: string;
city?: string;
country?: string;
phone?: string;
email?: string;
}
/**
* Account print options
*/
export interface AccountPrintOptions {
color?: boolean;
duplex?: boolean;
envelope?: EnvelopeType;
franking?: FrankingType;
productionCountry?: ProductionCountry;
}
/**
* Attachment upload options
*/
export interface AttachmentUploadOptions {
/** Base64-encoded PDF content */
content: string;
/** Name for the attachment */
name?: string;
}
// ============================================================================
// Response Types
// ============================================================================
/**
* Validation message from document processing
*/
export interface ValidationMessage {
type: 'INFO' | 'WARNING' | 'ERROR';
code: string;
message: string;
page?: number;
}
/**
* Address extracted from document
*/
export interface ExtractedAddress {
name?: string;
company?: string;
street?: string;
houseNumber?: string;
zipCode?: string;
city?: string;
country?: string;
}
/**
* Price information from API
*/
export interface PriceInfo {
priceBeforeTax: number;
priceAfterTax: number;
unit: 'EUROCENT' | string;
taxInPercent: number;
}
/**
* Document status from API
*/
export interface DocumentStatusInfo {
code: DocumentStatus;
text: string;
}
/**
* Letter data from API response
*/
export interface LetterData {
recipientAddress?: string;
price?: PriceInfo;
international?: boolean;
options?: {
simplex?: boolean;
color?: boolean;
franking?: FrankingType;
productionCountry?: ProductionCountry;
envelope?: EnvelopeType;
};
attributes?: DocumentAttribute[];
attachments?: string[];
}
/**
* Letter from API response
*/
export interface Letter {
letterType?: string;
letterData?: LetterData;
errors?: ValidationMessage[];
}
/**
* Document response from API
*/
export interface Document {
/** Document ID (numeric) */
id: number;
/** Filename of uploaded document */
filename?: string;
/** Number of pages in document */
numberOfPages: number;
/** Document status */
status: DocumentStatusInfo;
/** Type of document */
documentType?: 'LETTER' | 'SERIALLETTER' | string;
/** Letter details (for single letters) */
letter?: Letter;
/** Array of letters (for serial letters) */
letters?: Letter[];
}
/**
* Response structure for paginated list operations.
*
* @remarks
* The actual data is in the `items` array, not `data` or `results`.
*
* @example
* ```typescript
* const response = await client.documents.list();
*
* // Access the documents array via `items`
* for (const doc of response.items) {
* console.log(doc.filename, doc.status.text);
* }
*
* // Pagination information
* console.log(`Showing ${response.items.length} of ${response.total} documents`);
*
* // Check if more pages exist
* const hasMore = response.offset + response.items.length < response.total;
* ```
*/
export interface ListResponse<T> {
/** Array of items returned by the query */
items: T[];
/** Total number of items matching the query (across all pages) */
total: number;
/** Maximum number of items per page */
limit: number;
/** Number of items skipped (for pagination) */
offset: number;
}
/**
* Attachment response from API
*/
export interface Attachment {
attachmentId: string;
name: string;
pageCount: number;
createdAt: string;
}
/**
* Sending/shipment response from API
*/
export interface Sending {
documentId: string;
status: DocumentStatus;
price?: number;
trackingId?: string;
shippedAt?: string;
deliveredAt?: string;
}
/**
* Account balance/credit information
*/
export interface AccountInfo {
credit: number;
currency: string;
debitornumber: string;
}
/**
* Personal data response
*/
export interface PersonalData {
company?: string;
firstName?: string;
lastName?: string;
street?: string;
houseNumber?: string;
zipCode?: string;
city?: string;
country?: string;
phone?: string;
email?: string;
debitornumber: string;
}
/**
* Coworker information
*/
export interface Coworker {
debitornumber: string;
firstName?: string;
lastName?: string;
email?: string;
}
/**
* Journal/transaction entry
*/
export interface JournalEntry {
date: string;
description: string;
amount: number;
balance: number;
documentId?: string;
}
/**
* Invoice summary
*/
export interface Invoice {
invoiceNumber: string;
date: string;
amount: number;
currency: string;
}
/**
* Invoice detail with transactions
*/
export interface InvoiceDetail extends Invoice {
entries: JournalEntry[];
}
/**
* Batch status check response
*/
export interface BatchStatusResponse {
statuses: Record<string, DocumentStatus>;
}
// ============================================================================
// Error Types
// ============================================================================
/**
* API error response structure
*/
export interface ApiErrorResponse {
error?: string;
message?: string;
details?: string[];
validationErrors?: ValidationMessage[];
}
// ============================================================================
// Client Configuration
// ============================================================================
/**
* Configuration options for BinectClient
*/
export interface BinectClientConfig {
/** Binect username (email) */
username: string;
/** Binect password */
password: string;
/** Base URL override (default: https://app.binect.de/binectapi/v1) */
baseUrl?: string;
}