generated from coulomb/repo-seed
SDK (@binect/js): - BinectClient with domain sub-clients (documents, sendings, accounts, attachments, invoices) - HTTP Basic Auth, native fetch only (no runtime dependencies) - TypeScript types matching Binect API vocabulary - Status predicates and polling helpers in helpers.ts - Structured error handling (BinectApiError, BinectAuthError) Explorer: - Standalone browser-based API explorer (explorer/index.html) - Interactive testing without code Tests: - Unit tests for client, types, errors, helpers, http - E2E tests for upload/delete and send/cancel workflows Also includes: - Architecture Decision Records (ADRs) - Example DIN 5008 letter PDFs for testing - API specification research notes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
353 lines
9.9 KiB
TypeScript
353 lines
9.9 KiB
TypeScript
import type { HttpClient } from '../http.js';
|
|
import type {
|
|
Document,
|
|
DocumentUploadOptions,
|
|
DocumentUploadRequestBody,
|
|
DocumentTransformation,
|
|
CoverPageOptions,
|
|
DocumentAttribute,
|
|
ListResponse,
|
|
PaginationOptions,
|
|
} from '../types.js';
|
|
|
|
/**
|
|
* Client for document-related API operations.
|
|
* Handles document upload, retrieval, modification, and preview.
|
|
*/
|
|
export class DocumentsClient {
|
|
constructor(private readonly http: HttpClient) {}
|
|
|
|
/**
|
|
* Upload a new document (letter or serial letter).
|
|
* POST /documents
|
|
*
|
|
* @param options - Document upload options including base64-encoded PDF content
|
|
* @returns The created document with validation results
|
|
*/
|
|
async upload(options: DocumentUploadOptions): Promise<Document> {
|
|
// Transform user-friendly options to API request body format
|
|
const requestBody: DocumentUploadRequestBody = {
|
|
content: {
|
|
filename: options.filename,
|
|
content: options.content,
|
|
},
|
|
};
|
|
|
|
// Add options if any are specified
|
|
if (options.simplex !== undefined || options.color !== undefined ||
|
|
options.envelope !== undefined || options.franking !== undefined ||
|
|
options.productionCountry !== undefined) {
|
|
requestBody.options = {
|
|
simplex: options.simplex,
|
|
color: options.color,
|
|
envelope: options.envelope,
|
|
franking: options.franking,
|
|
productionCountry: options.productionCountry,
|
|
};
|
|
}
|
|
|
|
// Add attributes if specified
|
|
if (options.attributes) {
|
|
requestBody.attributes = options.attributes;
|
|
}
|
|
|
|
// Add split params if specified
|
|
if (options.splitToken !== undefined || options.pagesPerLetter !== undefined) {
|
|
requestBody.splitParams = {
|
|
splitToken: options.splitToken,
|
|
splitAfterNumberOfPages: options.pagesPerLetter,
|
|
};
|
|
}
|
|
|
|
// Add response format if specified
|
|
if (options.responseFormat !== undefined) {
|
|
requestBody.responseFormat = options.responseFormat;
|
|
}
|
|
|
|
return this.http.request<Document>({
|
|
method: 'POST',
|
|
path: '/documents',
|
|
body: requestBody,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* List all shippable documents (status 2).
|
|
* GET /documents
|
|
*
|
|
* @param pagination - Optional pagination parameters
|
|
* @returns List of shippable documents
|
|
*/
|
|
async list(pagination?: PaginationOptions): Promise<ListResponse<Document>> {
|
|
return this.http.request<ListResponse<Document>>({
|
|
method: 'GET',
|
|
path: '/documents',
|
|
query: pagination,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* List all documents with errors (status 7).
|
|
* GET /documents/errors
|
|
*
|
|
* @param pagination - Optional pagination parameters
|
|
* @returns List of erroneous documents
|
|
*/
|
|
async listErrors(pagination?: PaginationOptions): Promise<ListResponse<Document>> {
|
|
return this.http.request<ListResponse<Document>>({
|
|
method: 'GET',
|
|
path: '/documents/errors',
|
|
query: pagination,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get a specific document by ID.
|
|
* GET /documents/{documentID}
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns The document details
|
|
*/
|
|
async get(documentId: string): Promise<Document> {
|
|
return this.http.request<Document>({
|
|
method: 'GET',
|
|
path: `/documents/${encodeURIComponent(documentId)}`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Delete a document.
|
|
* DELETE /documents/{documentID}
|
|
*
|
|
* @param documentId - The document ID to delete
|
|
*/
|
|
async delete(documentId: string): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'DELETE',
|
|
path: `/documents/${encodeURIComponent(documentId)}`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get all attributes for a document.
|
|
* GET /documents/{documentID}/attributes
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns Key-value attributes
|
|
*/
|
|
async getAttributes(documentId: string): Promise<Record<string, string>> {
|
|
return this.http.request<Record<string, string>>({
|
|
method: 'GET',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attributes`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Set attributes for a document.
|
|
* POST /documents/{documentID}/attributes
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param attributes - Array of key-value attributes to set
|
|
*/
|
|
async setAttributes(documentId: string, attributes: DocumentAttribute[]): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'POST',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attributes`,
|
|
body: attributes,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get a specific attribute value.
|
|
* GET /documents/{documentID}/attributes/{key}
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param key - The attribute key
|
|
* @returns The attribute value
|
|
*/
|
|
async getAttribute(documentId: string, key: string): Promise<string> {
|
|
return this.http.request<string>({
|
|
method: 'GET',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attributes/${encodeURIComponent(key)}`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Update a specific attribute value.
|
|
* PUT /documents/{documentID}/attributes/{key}
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param key - The attribute key
|
|
* @param value - The new attribute value
|
|
*/
|
|
async updateAttribute(documentId: string, key: string, value: string): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'PUT',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attributes/${encodeURIComponent(key)}`,
|
|
body: { value },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Delete a specific attribute.
|
|
* DELETE /documents/{documentID}/attributes/{key}
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param key - The attribute key to delete
|
|
*/
|
|
async deleteAttribute(documentId: string, key: string): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'DELETE',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attributes/${encodeURIComponent(key)}`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Apply transformations (scaling/offset) to a document.
|
|
* PUT /documents/{documentID}/transformations
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param transformation - Transformation parameters
|
|
* @returns The updated document
|
|
*/
|
|
async applyTransformation(
|
|
documentId: string,
|
|
transformation: DocumentTransformation
|
|
): Promise<Document> {
|
|
return this.http.request<Document>({
|
|
method: 'PUT',
|
|
path: `/documents/${encodeURIComponent(documentId)}/transformations`,
|
|
body: transformation,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Revert transformations to original document.
|
|
* DELETE /documents/{documentID}/transformations
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns The updated document
|
|
*/
|
|
async revertTransformation(documentId: string): Promise<Document> {
|
|
return this.http.request<Document>({
|
|
method: 'DELETE',
|
|
path: `/documents/${encodeURIComponent(documentId)}/transformations`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add a cover page to a document.
|
|
* PUT /documents/{documentID}/coverpage
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param options - Cover page options with base64-encoded PDF
|
|
* @returns The updated document
|
|
*/
|
|
async addCoverPage(documentId: string, options: CoverPageOptions): Promise<Document> {
|
|
return this.http.request<Document>({
|
|
method: 'PUT',
|
|
path: `/documents/${encodeURIComponent(documentId)}/coverpage`,
|
|
body: options,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Remove the cover page from a document.
|
|
* DELETE /documents/{documentID}/coverpage
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns The updated document
|
|
*/
|
|
async removeCoverPage(documentId: string): Promise<Document> {
|
|
return this.http.request<Document>({
|
|
method: 'DELETE',
|
|
path: `/documents/${encodeURIComponent(documentId)}/coverpage`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get PDF preview of a document.
|
|
* GET /documents/{documentID}/pdf
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns Response containing PDF data
|
|
*/
|
|
async getPdf(documentId: string): Promise<Response> {
|
|
return this.http.requestRaw({
|
|
method: 'GET',
|
|
path: `/documents/${encodeURIComponent(documentId)}/pdf`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get PNG preview of a document (first page).
|
|
* GET /documents/{documentID}/png
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns Response containing PNG data
|
|
*/
|
|
async getPng(documentId: string): Promise<Response> {
|
|
return this.http.requestRaw({
|
|
method: 'GET',
|
|
path: `/documents/${encodeURIComponent(documentId)}/png`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get attachments for a document.
|
|
* GET /documents/{documentID}/attachments
|
|
*
|
|
* @param documentId - The document ID
|
|
* @returns Array of attachment IDs
|
|
*/
|
|
async getAttachments(documentId: string): Promise<string[]> {
|
|
return this.http.request<string[]>({
|
|
method: 'GET',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attachments`,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add an attachment to a document.
|
|
* POST /documents/{documentID}/attachments
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param attachmentId - The attachment ID to add
|
|
*/
|
|
async addAttachment(documentId: string, attachmentId: string): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'POST',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attachments`,
|
|
body: { attachmentId },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Update attachments for a document (replace all).
|
|
* PATCH /documents/{documentID}/attachments
|
|
*
|
|
* @param documentId - The document ID
|
|
* @param attachmentIds - Array of attachment IDs
|
|
*/
|
|
async updateAttachments(documentId: string, attachmentIds: string[]): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'PATCH',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attachments`,
|
|
body: { attachmentIds },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Remove all attachments from a document.
|
|
* DELETE /documents/{documentID}/attachments
|
|
*
|
|
* @param documentId - The document ID
|
|
*/
|
|
async removeAttachments(documentId: string): Promise<void> {
|
|
await this.http.request<void>({
|
|
method: 'DELETE',
|
|
path: `/documents/${encodeURIComponent(documentId)}/attachments`,
|
|
});
|
|
}
|
|
}
|