@taxora/sdk 1.3.0 → 1.4.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.
- package/CHANGELOG.md +15 -0
- package/README.md +7 -0
- package/dist/index.cjs +79 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -2
- package/dist/index.d.ts +47 -2
- package/dist/index.js +76 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/endpoints/AuthEndpoint.ts","../src/dto/Token.ts","../src/enums/LoginIdentifier.ts","../src/exceptions/TaxoraException.ts","../src/exceptions/AuthenticationException.ts","../src/exceptions/apiErrorMessage.ts","../src/exceptions/HttpException.ts","../src/http/RetryPolicy.ts","../src/http/withRetries.ts","../src/dto/CompanyResource.ts","../src/endpoints/CompanyEndpoint.ts","../src/enums/ComplianceEnrollmentStatus.ts","../src/enums/ComplianceService.ts","../src/dto/ComplianceEnrollment.ts","../src/dto/ComplianceEnrollmentPage.ts","../src/enums/ComplianceTaxReportState.ts","../src/dto/ComplianceTaxReport.ts","../src/dto/ComplianceTaxReportPage.ts","../src/enums/ComplianceDocumentType.ts","../src/enums/ComplianceTransactionState.ts","../src/enums/ComplianceTransactionType.ts","../src/dto/ComplianceTransaction.ts","../src/dto/ComplianceTransactionPage.ts","../src/dto/ImportResult.ts","../src/enums/PeppolLookupStatus.ts","../src/dto/PeppolLookupResult.ts","../src/dto/RegistryCompany.ts","../src/dto/RevenueStatistics.ts","../src/dto/SireneLookupResult.ts","../src/dto/VatRates.ts","../src/exceptions/ValidationException.ts","../src/support/NorwegianOrgNumber.ts","../src/endpoints/EReportingEndpoint.ts","../src/enums/SmartEnrichmentMode.ts","../src/enums/SmartEnrichmentStatus.ts","../src/dto/SmartEnrichmentResource.ts","../src/dto/SmartEnrichmentJob.ts","../src/dto/SmartEnrichmentHistoryRow.ts","../src/dto/SmartEnrichmentHistoryPage.ts","../src/dto/SmartEnrichmentStatistics.ts","../src/endpoints/SmartEnrichmentEndpoint.ts","../src/enums/VatState.ts","../src/dto/CompanyAddress.ts","../src/dto/ScoreBreakdown.ts","../src/dto/ProviderDocumentLine.ts","../src/dto/ProviderDocument.ts","../src/dto/VatResource.ts","../src/dto/VatCollection.ts","../src/dto/VatCertificateExport.ts","../src/dto/VatValidationAddressInput.ts","../src/endpoints/VatEndpoint.ts","../src/enums/Environment.ts","../src/http/FetchHttpClient.ts","../src/http/InMemoryTokenStorage.ts","../src/http/AuthRetryHttpClient.ts","../src/version.ts","../src/http/SdkVersionHttpClient.ts","../src/client/TaxoraClient.ts","../src/client/TaxoraClientFactory.ts","../src/enums/ApiVersion.ts","../src/enums/Language.ts","../src/webhooks/WebhookSignature.ts"],"sourcesContent":["// Client\nexport { TaxoraClient } from './client/TaxoraClient.js';\nexport { TaxoraClientFactory } from './client/TaxoraClientFactory.js';\nexport type { TaxoraClientOptions } from './client/TaxoraClient.js';\n\n// Endpoints\nexport { AuthEndpoint } from './endpoints/AuthEndpoint.js';\nexport { CompanyEndpoint } from './endpoints/CompanyEndpoint.js';\nexport { VatEndpoint } from './endpoints/VatEndpoint.js';\nexport { SmartEnrichmentEndpoint } from './endpoints/SmartEnrichmentEndpoint.js';\nexport type {\n SmartEnrichmentInput,\n SmartEnrichmentUsage,\n SmartEnrichmentUsageHistoryEntry,\n SmartEnrichmentExportOptions,\n SmartEnrichmentStatisticsOptions,\n SmartEnrichmentWaitOptions,\n} from './endpoints/SmartEnrichmentEndpoint.js';\nexport { EReportingEndpoint } from './endpoints/EReportingEndpoint.js';\nexport type {\n RevenueStatisticsFilters,\n EReportingInterval,\n ComplianceEnterpriseSize,\n ComplianceTypeOperation,\n ComplianceTransactionRequestType,\n ComplianceTransactionRequestState,\n ComplianceTaxReportRequestState,\n ComplianceRequestService,\n CreateComplianceEnrollmentInput,\n CreateNorwayEnrollmentInput,\n NorwayEnrollmentInput,\n ComplianceTransactionBuyerInput,\n CreateComplianceTransactionInput,\n UpdateComplianceTransactionInput,\n ComplianceInvoiceLineInput,\n ComplianceInvoiceTaxInput,\n ComplianceTransactionFilters,\n EReportingAccessRequestInput,\n} from './endpoints/EReportingEndpoint.js';\n\n// DTOs\nexport { Token } from './dto/Token.js';\nexport { ScoreBreakdown } from './dto/ScoreBreakdown.js';\nexport { CompanyAddress } from './dto/CompanyAddress.js';\nexport type { CompanyResource } from './dto/CompanyResource.js';\nexport { VatValidationAddressInput } from './dto/VatValidationAddressInput.js';\nexport { ProviderDocumentLine } from './dto/ProviderDocumentLine.js';\nexport { ProviderDocument } from './dto/ProviderDocument.js';\nexport { VatResource } from './dto/VatResource.js';\nexport { VatCollection } from './dto/VatCollection.js';\nexport { VatCertificateExport } from './dto/VatCertificateExport.js';\nexport { SmartEnrichmentResource } from './dto/SmartEnrichmentResource.js';\nexport type { SmartEnrichmentProviderVerdict, SmartEnrichmentAddressQuality } from './dto/SmartEnrichmentResource.js';\nexport { SmartEnrichmentJob } from './dto/SmartEnrichmentJob.js';\nexport { SmartEnrichmentHistoryRow } from './dto/SmartEnrichmentHistoryRow.js';\nexport type { SmartEnrichmentHistoryInput } from './dto/SmartEnrichmentHistoryRow.js';\nexport { SmartEnrichmentHistoryPage } from './dto/SmartEnrichmentHistoryPage.js';\nexport type { SmartEnrichmentHistoryStats } from './dto/SmartEnrichmentHistoryPage.js';\nexport { SmartEnrichmentStatistics } from './dto/SmartEnrichmentStatistics.js';\nexport type {\n SmartEnrichmentStatisticsInterval,\n SmartEnrichmentStatisticsRange,\n SmartEnrichmentStatisticsTotals,\n SmartEnrichmentTimeBucket,\n SmartEnrichmentSourceBreakdown,\n SmartEnrichmentOutcomeBreakdown,\n SmartEnrichmentConfidenceBucket,\n} from './dto/SmartEnrichmentStatistics.js';\nexport { RevenueStatistics } from './dto/RevenueStatistics.js';\nexport type {\n RevenueTotals,\n RevenueTimeBucket,\n RevenueTypeBreakdown,\n RevenueCountryBreakdown,\n RevenueStateBreakdown,\n RevenueCurrencyBreakdown,\n} from './dto/RevenueStatistics.js';\nexport { ComplianceEnrollment } from './dto/ComplianceEnrollment.js';\nexport { ComplianceEnrollmentPage } from './dto/ComplianceEnrollmentPage.js';\nexport { ComplianceTransaction } from './dto/ComplianceTransaction.js';\nexport type {\n ComplianceTransactionInvoiceLine,\n ComplianceTransactionInvoiceLineTax,\n} from './dto/ComplianceTransaction.js';\nexport { ComplianceTransactionPage } from './dto/ComplianceTransactionPage.js';\nexport { ComplianceTaxReport } from './dto/ComplianceTaxReport.js';\nexport { ComplianceTaxReportPage } from './dto/ComplianceTaxReportPage.js';\nexport { SireneLookupResult } from './dto/SireneLookupResult.js';\nexport { RegistryCompany } from './dto/RegistryCompany.js';\nexport { PeppolLookupResult } from './dto/PeppolLookupResult.js';\nexport { VatRates } from './dto/VatRates.js';\nexport type { VatRate } from './dto/VatRates.js';\nexport { ImportResult } from './dto/ImportResult.js';\n\n// Enums\nexport { Environment, getBaseUrl } from './enums/Environment.js';\nexport type { Environment as EnvironmentType } from './enums/Environment.js';\nexport { ApiVersion } from './enums/ApiVersion.js';\nexport { Language } from './enums/Language.js';\nexport { LoginIdentifier } from './enums/LoginIdentifier.js';\nexport { VatState, getFailedVatStates, describeVatState } from './enums/VatState.js';\nexport {\n SmartEnrichmentStatus,\n toSmartEnrichmentStatus,\n describeSmartEnrichmentStatus,\n} from './enums/SmartEnrichmentStatus.js';\nexport {\n SmartEnrichmentMode,\n toSmartEnrichmentMode,\n describeSmartEnrichmentMode,\n} from './enums/SmartEnrichmentMode.js';\nexport {\n ComplianceEnrollmentStatus,\n toComplianceEnrollmentStatus,\n describeComplianceEnrollmentStatus,\n} from './enums/ComplianceEnrollmentStatus.js';\nexport {\n ComplianceTransactionState,\n toComplianceTransactionState,\n describeComplianceTransactionState,\n} from './enums/ComplianceTransactionState.js';\nexport {\n ComplianceTransactionType,\n toComplianceTransactionType,\n describeComplianceTransactionType,\n} from './enums/ComplianceTransactionType.js';\nexport {\n ComplianceTaxReportState,\n toComplianceTaxReportState,\n describeComplianceTaxReportState,\n} from './enums/ComplianceTaxReportState.js';\nexport { ComplianceService, toComplianceService, describeComplianceService } from './enums/ComplianceService.js';\nexport {\n ComplianceDocumentType,\n toComplianceDocumentType,\n describeComplianceDocumentType,\n} from './enums/ComplianceDocumentType.js';\nexport { PeppolLookupStatus, toPeppolLookupStatus, describePeppolLookupStatus } from './enums/PeppolLookupStatus.js';\n\n// Helpers\nexport { NorwegianOrgNumber } from './support/NorwegianOrgNumber.js';\n\n// Webhooks\nexport {\n verifyWebhookSignature,\n constructWebhookEvent,\n parseWebhookSignatureHeader,\n computeWebhookSignature,\n generateWebhookSignatureHeader,\n WebhookSignatureVerificationError,\n WEBHOOK_SIGNATURE_HEADER,\n WEBHOOK_ID_HEADER,\n DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n} from './webhooks/WebhookSignature.js';\nexport type {\n WebhookRawBody,\n WebhookSignatureHeaderInput,\n WebhookVerifyOptions,\n WebhookSignatureErrorReason,\n ParsedWebhookSignatureHeader,\n} from './webhooks/WebhookSignature.js';\nexport type {\n WebhookEventType,\n WebhookEventEnvelope,\n TaxoraWebhookEvent,\n VatWebhookObject,\n ComplianceLedgerWebhookObject,\n ComplianceTransactionWebhookObject,\n EnrichmentCompletedWebhookObject,\n EnrichmentUpdatedWebhookObject,\n TestWebhookObject,\n VatValidatedEvent,\n VatStateChangedEvent,\n ComplianceLedgerStateChangedEvent,\n ComplianceTransactionStateChangedEvent,\n EnrichmentCompletedEvent,\n EnrichmentUpdatedEvent,\n WebhookTestEvent,\n} from './webhooks/WebhookEvent.js';\n\n// Exceptions\nexport { TaxoraException } from './exceptions/TaxoraException.js';\nexport { AuthenticationException } from './exceptions/AuthenticationException.js';\nexport { HttpException } from './exceptions/HttpException.js';\nexport { ValidationException } from './exceptions/ValidationException.js';\nexport { describeApiError } from './exceptions/apiErrorMessage.js';\n\n// Retries\nexport { RetryPolicy, type RetryPolicyOptions } from './http/RetryPolicy.js';\n\n// HTTP\nexport type { TokenStorageInterface } from './http/TokenStorageInterface.js';\nexport { InMemoryTokenStorage } from './http/InMemoryTokenStorage.js';\nexport type { HttpClientInterface } from './http/HttpClientInterface.js';\nexport { FetchHttpClient } from './http/FetchHttpClient.js';\nexport { AuthRetryHttpClient } from './http/AuthRetryHttpClient.js';\n","import { hostname } from 'os';\nimport { Token } from '../dto/Token.js';\nimport { LoginIdentifier } from '../enums/LoginIdentifier.js';\nimport { AuthenticationException } from '../exceptions/AuthenticationException.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nexport class AuthEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n async login(\n identifier: string,\n password: string,\n device?: string,\n loginIdentifier: LoginIdentifier = LoginIdentifier.EMAIL,\n ): Promise<Token> {\n const deviceName = device ?? hostname();\n\n const body: Record<string, string> = {\n identifier: loginIdentifier,\n password,\n device_name: deviceName,\n };\n\n if (loginIdentifier === LoginIdentifier.CLIENT_ID) {\n body['client_id'] = identifier;\n } else {\n body['email'] = identifier;\n }\n\n const data = await withRetries(this.retryPolicy, 'login', async () => {\n const response = await this.httpClient.request('POST', `${this.baseUrl}/auth/login`, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n });\n\n const responseText = await response.text();\n\n if (response.status === 401) {\n throw new AuthenticationException('Authentication failed: invalid credentials', {\n status: 401,\n body: responseText,\n });\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n return this.parseResponse(responseText, response.status);\n });\n\n const token = Token.fromArray(data);\n this.tokenStorage.set(token);\n return token;\n }\n\n async loginWithClientId(clientId: string, password: string, device?: string): Promise<Token> {\n return this.login(clientId, password, device, LoginIdentifier.CLIENT_ID);\n }\n\n async refresh(): Promise<Token> {\n const storedToken = this.tokenStorage.get();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n\n if (storedToken) {\n headers['Authorization'] = `Bearer ${storedToken.accessToken}`;\n }\n\n const data = await withRetries(this.retryPolicy, 'token refresh', async () => {\n const response = await this.httpClient.request('POST', `${this.baseUrl}/auth/refresh`, { headers });\n const responseText = await response.text();\n\n if (response.status === 401) {\n throw new AuthenticationException('Token refresh failed: unauthorized', { status: 401, body: responseText });\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n return this.parseResponse(responseText, response.status);\n });\n\n const token = Token.fromArray(data);\n this.tokenStorage.set(token);\n return token;\n }\n\n private parseResponse(responseText: string, statusCode: number): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', statusCode, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', statusCode, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && typeof obj['data'] === 'object' && obj['data'] !== null) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n}\n","export class Token {\n constructor(\n public readonly accessToken: string,\n public readonly tokenType: string,\n public readonly expiresAt: Date,\n ) {}\n\n isExpired(bufferSeconds = 15): boolean {\n return new Date(Date.now() + bufferSeconds * 1000) >= this.expiresAt;\n }\n\n static fromArray(data: Record<string, unknown>): Token {\n let accessToken = String(data['access_token'] ?? '');\n if (accessToken.startsWith('Bearer ')) {\n accessToken = accessToken.slice(7);\n }\n\n const tokenType = String(data['token_type'] ?? 'Bearer');\n const expiresIn = typeof data['expires_in'] === 'number' ? data['expires_in'] : 3600;\n const expiresAt = new Date(Date.now() + expiresIn * 1000);\n\n return new Token(accessToken, tokenType, expiresAt);\n }\n\n toArray(): { access_token: string; token_type: string; expires_at: string } {\n return {\n access_token: this.accessToken,\n token_type: this.tokenType,\n expires_at: this.expiresAt.toISOString(),\n };\n }\n}\n","export const LoginIdentifier = {\n EMAIL: 'email',\n CLIENT_ID: 'client_id',\n} as const;\n\nexport type LoginIdentifier = (typeof LoginIdentifier)[keyof typeof LoginIdentifier];\n","export class TaxoraException extends Error {\n public readonly context: Record<string, unknown>;\n\n constructor(message: string, context: Record<string, unknown> = {}) {\n super(message);\n this.name = 'TaxoraException';\n this.context = context;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { TaxoraException } from './TaxoraException.js';\n\nexport class AuthenticationException extends TaxoraException {\n public readonly statusCode = 401;\n\n constructor(message: string, context: Record<string, unknown> = {}) {\n super(message, context);\n this.name = 'AuthenticationException';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Derives a short, human readable exception message from an API response body.\n *\n * A response body is never used verbatim as an exception message: the gateways\n * in front of the API (DigitalOcean App Platform, load balancers, proxies)\n * answer 5xx with a full HTML error page, and that page would otherwise end up\n * in every log line and stack trace of the integrating application.\n *\n * Only the human readable message of a JSON error body is used; everything else\n * (HTML, empty bodies, binary payloads) falls back to the HTTP status line. The\n * untouched body always stays available via `HttpException.getResponseBody()`.\n */\n\nconst MAX_LENGTH = 500;\n\n/** Plain text bodies are only surfaced when they are this short. */\nconst MAX_PLAIN_LENGTH = 200;\n\nconst REASON_PHRASES: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 413: 'Payload Too Large',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n};\n\n/**\n * The message for a failed request: the API message when the body carries one,\n * otherwise a description of the HTTP status.\n */\nexport function describeApiError(body: string | null | undefined, statusCode: number): string {\n return jsonErrorMessage(body) ?? plainErrorMessage(body) ?? statusErrorMessage(statusCode);\n}\n\n/**\n * The failure detail without the surrounding sentence: the API message when\n * there is one, otherwise just the status (\"HTTP 504 Gateway Timeout\").\n */\nexport function detailApiError(body: string | null | undefined, statusCode: number): string {\n return jsonErrorMessage(body) ?? plainErrorMessage(body) ?? statusPhrase(statusCode);\n}\n\n/** The human readable message of a JSON error body, or null. */\nexport function jsonErrorMessage(body: string | null | undefined): string | null {\n if (body === null || body === undefined || body.trim() === '') return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n return null;\n }\n\n if (typeof parsed !== 'object' || parsed === null) return null;\n const payload = parsed as Record<string, unknown>;\n\n for (const key of ['message', 'error']) {\n const value = payload[key];\n if (typeof value === 'string') {\n const message = sanitize(value);\n if (message !== null) return message;\n }\n }\n\n const errors = payload['errors'];\n if (typeof errors === 'object' && errors !== null) {\n return fromErrorBag(errors as Record<string, unknown>);\n }\n\n return null;\n}\n\nexport function statusErrorMessage(statusCode: number): string {\n return `Taxora API request failed (${statusPhrase(statusCode)}).`;\n}\n\n/** e.g. \"HTTP 504 Gateway Timeout\". */\nexport function statusPhrase(statusCode: number): string {\n const phrase = REASON_PHRASES[statusCode];\n\n return `HTTP ${statusCode}${phrase ? ` ${phrase}` : ''}`;\n}\n\n/**\n * A short body without any markup (e.g. \"upstream request timeout\") is safe to\n * surface as is; anything longer or HTML/JSON shaped is not.\n */\nfunction plainErrorMessage(body: string | null | undefined): string | null {\n if (body === null || body === undefined) return null;\n\n const value = body.replace(/\\s+/g, ' ').trim();\n if (value === '' || value.length > MAX_PLAIN_LENGTH) return null;\n if (value.includes('<') || value.includes('{')) return null;\n\n return value;\n}\n\nfunction fromErrorBag(errors: Record<string, unknown>): string | null {\n for (const [field, messages] of Object.entries(errors)) {\n for (const message of Array.isArray(messages) ? messages : [messages]) {\n if (typeof message !== 'string') continue;\n const sanitized = sanitize(message);\n if (sanitized === null) continue;\n\n return field !== '' ? `${field}: ${sanitized}` : sanitized;\n }\n }\n\n return null;\n}\n\n/** Single line, length capped, never an HTML document. */\nfunction sanitize(value: string): string | null {\n const collapsed = value.replace(/\\s+/g, ' ').trim();\n if (collapsed === '') return null;\n if (/<!doctype\\s+html|<html[\\s>]/i.test(collapsed)) return null;\n\n return collapsed.length > MAX_LENGTH ? `${collapsed.slice(0, MAX_LENGTH - 1)}…` : collapsed;\n}\n","import { TaxoraException } from './TaxoraException.js';\nimport { detailApiError } from './apiErrorMessage.js';\n\nexport class HttpException extends TaxoraException {\n public readonly statusCode: number;\n public readonly responseBody: string;\n /** Raw `Retry-After` header of the failed response, when it carried one. */\n public readonly retryAfter: string | null;\n\n constructor(\n message: string,\n statusCode: number,\n responseBody: string,\n context: Record<string, unknown> = {},\n retryAfter: string | null = null,\n ) {\n super(message, context);\n this.name = 'HttpException';\n this.statusCode = statusCode;\n this.responseBody = responseBody;\n this.retryAfter = retryAfter;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * The final failure after the SDK retried a transient gateway error, e.g.\n * \"Taxora VAT validation failed after 3 attempts (HTTP 504 Gateway Timeout).\"\n */\n static afterAttempts(operation: string, attempts: number, last: HttpException): HttpException {\n const detail = detailApiError(last.getResponseBody(), last.getStatusCode());\n\n return new HttpException(\n `Taxora ${operation} failed after ${attempts} attempts (${detail}).`,\n last.getStatusCode(),\n last.getResponseBody(),\n { ...last.context, attempts, cause: last },\n last.getRetryAfter(),\n );\n }\n\n getStatusCode(): number {\n return this.statusCode;\n }\n\n getResponseBody(): string {\n return this.responseBody;\n }\n\n getRetryAfter(): string | null {\n return this.retryAfter;\n }\n}\n","/**\n * How the SDK retries transient failures.\n *\n * Only gateway-level failures are retried by default (502/503/504): those come\n * from the infrastructure in front of the API, not from the API itself, and a\n * second attempt a moment later usually succeeds. Everything else — 4xx, and any\n * answer the API produced itself — is surfaced immediately.\n *\n * On top of that, a 429 is retried when the API answers with a `Retry-After`\n * telling us how long to wait, and connection-level failures (reset connection,\n * client-side timeout, DNS hiccup) are retried as well — those never reached the\n * API's answer either.\n *\n * Retries are opt-in per operation and are only applied to read-only calls\n * (lookups, downloads, polling). Calls that change state or cost quota — booking\n * a transaction, starting an enrichment job, triggering a certificate export —\n * are never retried automatically, because a gateway timeout does not tell us\n * whether the API already processed the request.\n */\nexport interface RetryPolicyOptions {\n /** Total attempts including the first one (1 disables retrying). */\n maxAttempts?: number;\n initialDelayMs?: number;\n backoffMultiplier?: number;\n maxDelayMs?: number;\n retryableStatusCodes?: number[];\n /** Honour a `Retry-After` header instead of the backoff, and retry a 429 that carries one. */\n respectRetryAfter?: boolean;\n /** Longest wait accepted from `Retry-After`; a longer one means we give up instead of blocking. */\n maxRetryAfterMs?: number;\n /** Retry connection-level failures (reset connection, client-side timeout, DNS hiccup). */\n retryOnNetworkErrors?: boolean;\n /** Receives the delay in milliseconds; defaults to setTimeout. */\n sleeper?: (delayMs: number) => Promise<void> | void;\n}\n\nexport const DEFAULT_RETRYABLE_STATUS_CODES = [502, 503, 504];\n\n/** Retried only when the response tells us how long to wait. */\nconst RETRY_AFTER_ONLY_STATUS_CODES = [429];\n\n/** Node/undici error codes that mean \"the request never got an answer\". */\nconst NETWORK_ERROR_CODES = new Set([\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'ECONNABORTED',\n 'EPIPE',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n 'EHOSTUNREACH',\n 'ENETUNREACH',\n 'ENETDOWN',\n 'UND_ERR_CONNECT_TIMEOUT',\n 'UND_ERR_HEADERS_TIMEOUT',\n 'UND_ERR_BODY_TIMEOUT',\n 'UND_ERR_SOCKET',\n]);\n\nexport class RetryPolicy {\n public readonly maxAttempts: number;\n public readonly initialDelayMs: number;\n public readonly backoffMultiplier: number;\n public readonly maxDelayMs: number;\n public readonly retryableStatusCodes: number[];\n public readonly respectRetryAfter: boolean;\n public readonly maxRetryAfterMs: number;\n public readonly retryOnNetworkErrors: boolean;\n private readonly sleeper: ((delayMs: number) => Promise<void> | void) | undefined;\n\n constructor(options: RetryPolicyOptions = {}) {\n this.maxAttempts = options.maxAttempts ?? 3;\n this.initialDelayMs = options.initialDelayMs ?? 500;\n this.backoffMultiplier = options.backoffMultiplier ?? 2;\n this.maxDelayMs = options.maxDelayMs ?? 5000;\n this.retryableStatusCodes = options.retryableStatusCodes ?? DEFAULT_RETRYABLE_STATUS_CODES;\n this.respectRetryAfter = options.respectRetryAfter ?? true;\n this.maxRetryAfterMs = options.maxRetryAfterMs ?? 10_000;\n this.retryOnNetworkErrors = options.retryOnNetworkErrors ?? true;\n this.sleeper = options.sleeper;\n\n if (this.maxAttempts < 1) throw new Error('maxAttempts must be at least 1.');\n if (this.initialDelayMs < 0 || this.maxDelayMs < 0) throw new Error('Delays must not be negative.');\n if (this.backoffMultiplier < 1) throw new Error('backoffMultiplier must be at least 1.');\n }\n\n /** No retrying at all — every failure is surfaced on the first attempt. */\n static disabled(): RetryPolicy {\n return new RetryPolicy({ maxAttempts: 1 });\n }\n\n /** Retry immediately, without waiting (mainly useful in tests). */\n static withoutDelay(maxAttempts = 3): RetryPolicy {\n return new RetryPolicy({ maxAttempts, initialDelayMs: 0, maxDelayMs: 0 });\n }\n\n isRetryable(statusCode: number, retryAfterHeader?: string | null): boolean {\n const retryAfterMs = this.retryAfterMs(retryAfterHeader);\n\n // The API asked for a longer pause than we are willing to block for: hand the\n // caller its 429/503 now instead of sitting on the request.\n if (retryAfterMs !== null && retryAfterMs > this.maxRetryAfterMs) return false;\n\n if (this.retryableStatusCodes.includes(statusCode)) return true;\n\n return retryAfterMs !== null && RETRY_AFTER_ONLY_STATUS_CODES.includes(statusCode);\n }\n\n /** @param attempt Number of attempts made so far (1 = the first one just failed). */\n shouldRetry(statusCode: number, attempt: number, retryAfterHeader?: string | null): boolean {\n return attempt < this.maxAttempts && this.isRetryable(statusCode, retryAfterHeader);\n }\n\n /**\n * A connection-level failure: the request never got an answer, so repeating it\n * is as safe as repeating a gateway timeout.\n */\n isRetryableError(error: unknown): boolean {\n if (!this.retryOnNetworkErrors || !(error instanceof Error)) return false;\n\n if (error.name === 'AbortError' || error.name === 'TimeoutError') return true;\n\n const code = (error as { code?: unknown }).code ?? (error.cause as { code?: unknown } | undefined)?.code;\n if (typeof code === 'string' && NETWORK_ERROR_CODES.has(code)) return true;\n\n // Node's fetch reports every transport problem as `TypeError: fetch failed`.\n return error instanceof TypeError && /fetch failed|network|failed to fetch/i.test(error.message);\n }\n\n shouldRetryError(error: unknown, attempt: number): boolean {\n return attempt < this.maxAttempts && this.isRetryableError(error);\n }\n\n /**\n * The wait the API asked for, in milliseconds — seconds or HTTP-date form — or\n * null when there is none, it cannot be parsed, or the header is ignored.\n */\n retryAfterMs(header: string | null | undefined, now: Date = new Date()): number | null {\n if (!this.respectRetryAfter || header === null || header === undefined) return null;\n\n const value = header.trim();\n if (value === '') return null;\n\n if (/^\\d+$/.test(value)) return Number(value) * 1000;\n\n const date = Date.parse(value);\n if (Number.isNaN(date)) return null;\n\n return Math.max(0, date - now.getTime());\n }\n\n /** The wait before the next attempt: what the API asked for, else exponential backoff. */\n delayMsForAttempt(attempt: number, retryAfterHeader?: string | null): number {\n const retryAfterMs = this.retryAfterMs(retryAfterHeader);\n if (retryAfterMs !== null) return Math.min(retryAfterMs, this.maxRetryAfterMs);\n\n if (this.initialDelayMs === 0) return 0;\n\n const delay = Math.round(this.initialDelayMs * this.backoffMultiplier ** Math.max(0, attempt - 1));\n\n return Math.max(0, Math.min(delay, this.maxDelayMs));\n }\n\n async sleepBeforeRetry(attempt: number, retryAfterHeader?: string | null): Promise<void> {\n const delayMs = this.delayMsForAttempt(attempt, retryAfterHeader);\n if (delayMs <= 0) return;\n\n if (this.sleeper) {\n await this.sleeper(delayMs);\n\n return;\n }\n\n await new Promise<void>((resolve) => setTimeout(resolve, delayMs));\n }\n}\n","import { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { type RetryPolicy } from './RetryPolicy.js';\n\n/**\n * Runs `request` and retries it while the gateway in front of the API keeps\n * failing. Wrap only read-only operations in this: a 502/503/504 does not tell\n * us whether the API already processed the request, so anything that changes\n * state or costs quota must fail fast instead.\n *\n * @param operation Short label used in the final error message, e.g. \"VAT validation\".\n */\nexport async function withRetries<T>(policy: RetryPolicy, operation: string, request: () => Promise<T>): Promise<T> {\n let attempt = 1;\n\n for (;;) {\n try {\n return await request();\n } catch (error) {\n if (!(error instanceof HttpException)) {\n // Connection reset, client-side timeout, DNS hiccup: no answer ever\n // arrived, so this is as safe to repeat as a gateway timeout. The\n // transport error is rethrown unchanged once we give up, so callers keep\n // seeing their HTTP client's own error.\n if (!policy.shouldRetryError(error, attempt)) throw error;\n\n await policy.sleepBeforeRetry(attempt);\n attempt++;\n continue;\n }\n\n const retryAfter = error.getRetryAfter();\n\n if (!policy.shouldRetry(error.getStatusCode(), attempt, retryAfter)) {\n throw attempt > 1 && policy.isRetryable(error.getStatusCode(), retryAfter)\n ? HttpException.afterAttempts(operation, attempt, error)\n : error;\n }\n\n await policy.sleepBeforeRetry(attempt, retryAfter);\n attempt++;\n }\n }\n}\n\n/**\n * Same idea one level lower: retries a request that answers with a transient\n * gateway status instead of throwing. Used for plain GETs, which are safe to\n * repeat by definition. When the attempts are used up, the gateway status is\n * turned into the same \"failed after N attempts\" error as withRetries().\n */\nexport async function withResponseRetries(\n policy: RetryPolicy,\n operation: string,\n send: () => Promise<Response>,\n): Promise<Response> {\n let attempt = 1;\n\n for (;;) {\n let response: Response;\n try {\n response = await send();\n } catch (error) {\n // Same reasoning as in withRetries(): a transport failure never reached an\n // answer, and is rethrown unchanged once the attempts are used up.\n if (!policy.shouldRetryError(error, attempt)) throw error;\n\n await policy.sleepBeforeRetry(attempt);\n attempt++;\n continue;\n }\n\n const retryAfter = response.headers.get('retry-after');\n\n if (!policy.shouldRetry(response.status, attempt, retryAfter)) {\n if (attempt > 1 && policy.isRetryable(response.status, retryAfter)) {\n const body = await response.text();\n const last = new HttpException(describeApiError(body, response.status), response.status, body, {}, retryAfter);\n\n throw HttpException.afterAttempts(operation, attempt, last);\n }\n\n return response;\n }\n\n await policy.sleepBeforeRetry(attempt, retryAfter);\n attempt++;\n }\n}\n","export interface CompanyResource {\n id?: number;\n uuid?: string;\n name?: string;\n vat_uid?: string;\n address_line_1?: string | null;\n address_line_2?: string | null;\n street?: string | null;\n zip_code?: string | null;\n city?: string | null;\n country_code?: string | null;\n email?: string;\n phone_number?: string | null;\n api_rate_limit: number;\n vat_rate_limit: number;\n /**\n * @deprecated Use api_rate_limit and vat_rate_limit instead.\n */\n rate_limit?: number;\n state?: string;\n source?: string;\n [key: string]: unknown;\n}\n\nexport function normalizeCompanyResource(data: Record<string, unknown>): CompanyResource {\n const apiRateLimit = typeof data['api_rate_limit'] === 'number' ? data['api_rate_limit'] : undefined;\n const vatRateLimit = typeof data['vat_rate_limit'] === 'number' ? data['vat_rate_limit'] : undefined;\n const legacyRateLimit = typeof data['rate_limit'] === 'number' ? data['rate_limit'] : undefined;\n\n return {\n ...data,\n api_rate_limit: apiRateLimit ?? legacyRateLimit ?? 0,\n vat_rate_limit: vatRateLimit ?? legacyRateLimit ?? 0,\n };\n}\n","import { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { normalizeCompanyResource, type CompanyResource } from '../dto/CompanyResource.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nexport class CompanyEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n async get(): Promise<CompanyResource> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n\n // Read-only, so transient gateway failures are retried (see RetryPolicy).\n return withRetries(this.retryPolicy, 'company request', async () => {\n const response = await this.httpClient.request('GET', `${this.baseUrl}/company`, { headers });\n const responseText = await response.text();\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && typeof obj['data'] === 'object' && obj['data'] !== null) {\n return normalizeCompanyResource(obj['data'] as Record<string, unknown>);\n }\n\n return normalizeCompanyResource(obj);\n });\n }\n}\n","export const ComplianceEnrollmentStatus = {\n PENDING_DATA: 'pending_data',\n ACCOUNT_CREATED: 'account_created',\n REGIME_ACTIVATED: 'regime_activated',\n READY: 'ready',\n SUSPENDED: 'suspended',\n ERROR_ACCOUNT: 'error_account',\n ERROR_ACTIVATION: 'error_activation',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceEnrollmentStatus = (typeof ComplianceEnrollmentStatus)[keyof typeof ComplianceEnrollmentStatus];\n\nconst VALUES: readonly string[] = Object.values(ComplianceEnrollmentStatus);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceEnrollmentStatus(value: unknown): ComplianceEnrollmentStatus {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceEnrollmentStatus;\n }\n }\n return ComplianceEnrollmentStatus.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceEnrollmentStatus, string> = {\n [ComplianceEnrollmentStatus.PENDING_DATA]: 'Awaiting merchant data before provisioning can start.',\n [ComplianceEnrollmentStatus.ACCOUNT_CREATED]: 'Provider account exists. Regime not yet activated.',\n [ComplianceEnrollmentStatus.REGIME_ACTIVATED]:\n 'Compliance regime activated at provider. Ready to submit transactions.',\n [ComplianceEnrollmentStatus.READY]: 'Enrollment fully active and reporting.',\n [ComplianceEnrollmentStatus.SUSPENDED]: 'Enrollment temporarily suspended.',\n [ComplianceEnrollmentStatus.ERROR_ACCOUNT]: 'Provider account creation failed.',\n [ComplianceEnrollmentStatus.ERROR_ACTIVATION]: 'Regime activation at provider failed.',\n [ComplianceEnrollmentStatus.UNKNOWN]: 'Unknown status.',\n};\n\nexport function describeComplianceEnrollmentStatus(status: ComplianceEnrollmentStatus): string {\n return DESCRIPTIONS[status];\n}\n","/**\n * The compliance service an enrollment books for its country: French DGFiP\n * e-reporting, or e-invoicing (e.g. Norway EHF / Peppol BIS 3.0). Each country\n * and service is unlocked and billed separately.\n */\nexport const ComplianceService = {\n E_REPORTING: 'e_reporting',\n E_INVOICING: 'e_invoicing',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceService = (typeof ComplianceService)[keyof typeof ComplianceService];\n\nconst VALUES: readonly string[] = Object.values(ComplianceService);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceService(value: unknown): ComplianceService {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceService;\n }\n }\n return ComplianceService.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceService, string> = {\n [ComplianceService.E_REPORTING]: 'E-reporting of transaction data to the tax authority (France: DGFiP Flux 10).',\n [ComplianceService.E_INVOICING]: 'Structured e-invoices delivered to the buyer (Norway: EHF / Peppol BIS 3.0).',\n [ComplianceService.UNKNOWN]: 'Unknown service.',\n};\n\nexport function describeComplianceService(service: ComplianceService): string {\n return DESCRIPTIONS[service];\n}\n","import { type ComplianceEnrollmentStatus, toComplianceEnrollmentStatus } from '../enums/ComplianceEnrollmentStatus.js';\nimport { ComplianceService, toComplianceService } from '../enums/ComplianceService.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\n/**\n * A compliance enrollment — the merchant's provisioned account for one country\n * and service (GET/POST /compliance/enrollments), e.g. France e-reporting\n * (regime \"dgfip_flux10\") or Norway e-invoicing (regime \"peppol_bis3\").\n */\nexport class ComplianceEnrollment {\n constructor(\n public readonly id: number,\n public readonly companyId: number,\n public readonly country: string,\n public readonly regime: string,\n public readonly provider: string,\n public readonly status: ComplianceEnrollmentStatus,\n public readonly statusLabel: string,\n public readonly statusError: string | null,\n public readonly providerAccountId: string | null,\n public readonly taxId: string | null,\n public readonly companyRegisterId: string | null,\n public readonly companyRegisterScheme: string | null,\n public readonly regimeConfig: Record<string, unknown> | null,\n /** First date transactions are reported for (YYYY-MM-DD). */\n public readonly reportingStartDate: string | null,\n public readonly notificationEmail: string | null,\n public readonly autoSend: boolean,\n public readonly createdAt: string | null,\n public readonly updatedAt: string | null,\n /** Booked service (\"e_reporting\" / \"e_invoicing\"); `unknown` when an older server omits it. */\n public readonly service: ComplianceService = ComplianceService.UNKNOWN,\n ) {}\n\n static fromArray(data: Record<string, unknown>): ComplianceEnrollment {\n const regimeConfig =\n typeof data['regime_config'] === 'object' &&\n data['regime_config'] !== null &&\n !Array.isArray(data['regime_config'])\n ? (data['regime_config'] as Record<string, unknown>)\n : null;\n\n return new ComplianceEnrollment(\n asNumber(data['id']),\n asNumber(data['company_id']),\n asString(data['country']),\n asString(data['regime']),\n asString(data['provider']),\n toComplianceEnrollmentStatus(data['status']),\n asString(data['status_label']),\n asNullableString(data['status_error']),\n asNullableString(data['provider_account_id']),\n asNullableString(data['tax_id']),\n asNullableString(data['company_register_id']),\n asNullableString(data['company_register_scheme']),\n regimeConfig,\n asNullableString(data['reporting_start_date']),\n asNullableString(data['notification_email']),\n data['auto_send'] === true,\n asNullableString(data['created_at']),\n asNullableString(data['updated_at']),\n toComplianceService(data['service']),\n );\n }\n}\n","import { ComplianceEnrollment } from './ComplianceEnrollment.js';\n\n/**\n * A paginated page of compliance enrollments (GET /compliance/enrollments).\n */\nexport class ComplianceEnrollmentPage implements Iterable<ComplianceEnrollment> {\n constructor(\n public readonly rows: ComplianceEnrollment[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n ) {}\n\n static fromResponse(payload: unknown): ComplianceEnrollmentPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(ComplianceEnrollment.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n return new ComplianceEnrollmentPage(\n rows,\n num(meta['current_page'], 1),\n num(meta['per_page'], rows.length),\n num(meta['total'], rows.length),\n num(meta['last_page'], 1),\n );\n }\n\n [Symbol.iterator](): Iterator<ComplianceEnrollment> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","export const ComplianceTaxReportState = {\n NEW: 'new',\n SENT: 'sent',\n ACKNOWLEDGED: 'acknowledged',\n REGISTERED: 'registered',\n REFUSED: 'refused',\n ERROR: 'error',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceTaxReportState = (typeof ComplianceTaxReportState)[keyof typeof ComplianceTaxReportState];\n\nconst VALUES: readonly string[] = Object.values(ComplianceTaxReportState);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceTaxReportState(value: unknown): ComplianceTaxReportState {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceTaxReportState;\n }\n }\n return ComplianceTaxReportState.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceTaxReportState, string> = {\n [ComplianceTaxReportState.NEW]: 'Created at provider, waiting for the daily ledger batch.',\n [ComplianceTaxReportState.SENT]: 'Ledger transmitted to PPF.',\n [ComplianceTaxReportState.ACKNOWLEDGED]: 'PPF acknowledged receipt of the ledger.',\n [ComplianceTaxReportState.REGISTERED]: 'Accepted by DGFiP (CDV 300).',\n [ComplianceTaxReportState.REFUSED]: 'Rejected by DGFiP (CDV 301).',\n [ComplianceTaxReportState.ERROR]: 'Transmission or PPF error.',\n [ComplianceTaxReportState.UNKNOWN]: 'Unknown state.',\n};\n\nexport function describeComplianceTaxReportState(state: ComplianceTaxReportState): string {\n return DESCRIPTIONS[state];\n}\n","import { type ComplianceTaxReportState, toComplianceTaxReportState } from '../enums/ComplianceTaxReportState.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\nfunction asNullableNumber(value: unknown): number | null {\n return typeof value === 'number' ? value : null;\n}\n\n/**\n * Monetary values are kept as the decimal strings returned by the API (no\n * Number conversion) to preserve precision.\n */\nfunction asMoney(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return '0.00';\n}\n\n/**\n * A DGFiP tax report tracking one transaction through the aggregated daily\n * ledger lifecycle (GET /compliance/tax-reports).\n */\nexport class ComplianceTaxReport {\n constructor(\n public readonly id: number,\n public readonly companyId: number,\n public readonly complianceTransactionId: number | null,\n public readonly ledgerId: number | null,\n public readonly country: string,\n public readonly regime: string,\n public readonly state: ComplianceTaxReportState,\n public readonly stateLabel: string,\n /** True once the report reached a final state (registered, refused or error). */\n public readonly isTerminal: boolean,\n public readonly providerTaxReportId: string | null,\n public readonly providerLedgerId: string | null,\n public readonly baseAmount: string,\n public readonly taxAmount: string,\n public readonly totalAmount: string,\n public readonly refusalReason: string | null,\n public readonly registeredAt: string | null,\n public readonly refusedAt: string | null,\n public readonly createdAt: string | null,\n public readonly updatedAt: string | null,\n ) {}\n\n static fromArray(data: Record<string, unknown>): ComplianceTaxReport {\n return new ComplianceTaxReport(\n asNumber(data['id']),\n asNumber(data['company_id']),\n asNullableNumber(data['compliance_transaction_id']),\n asNullableNumber(data['ledger_id']),\n asString(data['country']),\n asString(data['regime']),\n toComplianceTaxReportState(data['state']),\n asString(data['state_label']),\n data['is_terminal'] === true,\n asNullableString(data['provider_tax_report_id']),\n asNullableString(data['provider_ledger_id']),\n asMoney(data['base_amount']),\n asMoney(data['tax_amount']),\n asMoney(data['total_amount']),\n asNullableString(data['refusal_reason']),\n asNullableString(data['registered_at']),\n asNullableString(data['refused_at']),\n asNullableString(data['created_at']),\n asNullableString(data['updated_at']),\n );\n }\n}\n","import { ComplianceTaxReport } from './ComplianceTaxReport.js';\n\n/**\n * A paginated page of compliance tax reports (GET /compliance/tax-reports).\n */\nexport class ComplianceTaxReportPage implements Iterable<ComplianceTaxReport> {\n constructor(\n public readonly rows: ComplianceTaxReport[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n ) {}\n\n static fromResponse(payload: unknown): ComplianceTaxReportPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(ComplianceTaxReport.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n return new ComplianceTaxReportPage(\n rows,\n num(meta['current_page'], 1),\n num(meta['per_page'], rows.length),\n num(meta['total'], rows.length),\n num(meta['last_page'], 1),\n );\n }\n\n [Symbol.iterator](): Iterator<ComplianceTaxReport> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","/** Kind of document a compliance transaction represents. */\nexport const ComplianceDocumentType = {\n INVOICE: 'invoice',\n CREDIT_NOTE: 'credit_note',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceDocumentType = (typeof ComplianceDocumentType)[keyof typeof ComplianceDocumentType];\n\nconst VALUES: readonly string[] = Object.values(ComplianceDocumentType);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceDocumentType(value: unknown): ComplianceDocumentType {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceDocumentType;\n }\n }\n return ComplianceDocumentType.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceDocumentType, string> = {\n [ComplianceDocumentType.INVOICE]: 'Commercial invoice.',\n [ComplianceDocumentType.CREDIT_NOTE]: 'Credit note correcting a previously issued invoice.',\n [ComplianceDocumentType.UNKNOWN]: 'Unknown document type.',\n};\n\nexport function describeComplianceDocumentType(type: ComplianceDocumentType): string {\n return DESCRIPTIONS[type];\n}\n","export const ComplianceTransactionState = {\n PENDING: 'pending',\n SENDING: 'sending',\n SUBMITTED: 'submitted',\n ERROR: 'error',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceTransactionState = (typeof ComplianceTransactionState)[keyof typeof ComplianceTransactionState];\n\nconst VALUES: readonly string[] = Object.values(ComplianceTransactionState);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceTransactionState(value: unknown): ComplianceTransactionState {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceTransactionState;\n }\n }\n return ComplianceTransactionState.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceTransactionState, string> = {\n [ComplianceTransactionState.PENDING]: 'Recorded locally, not yet submitted to the provider.',\n [ComplianceTransactionState.SENDING]: 'Submission to the provider in progress.',\n [ComplianceTransactionState.SUBMITTED]: 'Successfully submitted to the provider.',\n [ComplianceTransactionState.ERROR]: 'Submission failed. See submissionError.',\n [ComplianceTransactionState.UNKNOWN]: 'Unknown state.',\n};\n\nexport function describeComplianceTransactionState(state: ComplianceTransactionState): string {\n return DESCRIPTIONS[state];\n}\n","export const ComplianceTransactionType = {\n B2C_OUTBOUND: 'b2c_outbound',\n B2B_DOMESTIC_OUTBOUND: 'b2b_domestic_outbound',\n B2B_DOMESTIC_INBOUND: 'b2b_domestic_inbound',\n CROSSBORDER_OUTBOUND: 'crossborder_outbound',\n CROSSBORDER_INBOUND: 'crossborder_inbound',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceTransactionType = (typeof ComplianceTransactionType)[keyof typeof ComplianceTransactionType];\n\nconst VALUES: readonly string[] = Object.values(ComplianceTransactionType);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceTransactionType(value: unknown): ComplianceTransactionType {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceTransactionType;\n }\n }\n return ComplianceTransactionType.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceTransactionType, string> = {\n [ComplianceTransactionType.B2C_OUTBOUND]: 'Sale to a private person in the merchant country (DGFiP Flux 10.3).',\n [ComplianceTransactionType.B2B_DOMESTIC_OUTBOUND]: 'Sale to a domestic business (DGFiP Flux 1, Phase 2).',\n [ComplianceTransactionType.B2B_DOMESTIC_INBOUND]: 'Purchase from a domestic business (DGFiP Flux 1, Phase 2).',\n [ComplianceTransactionType.CROSSBORDER_OUTBOUND]: 'Sale to a non-domestic business (DGFiP Flux 10.1).',\n [ComplianceTransactionType.CROSSBORDER_INBOUND]: 'Purchase from a non-domestic supplier (DGFiP Flux 10.1).',\n [ComplianceTransactionType.UNKNOWN]: 'Unknown transaction type.',\n};\n\nexport function describeComplianceTransactionType(type: ComplianceTransactionType): string {\n return DESCRIPTIONS[type];\n}\n","import { ComplianceTaxReport } from './ComplianceTaxReport.js';\nimport { ComplianceDocumentType, toComplianceDocumentType } from '../enums/ComplianceDocumentType.js';\nimport { type ComplianceTransactionState, toComplianceTransactionState } from '../enums/ComplianceTransactionState.js';\nimport { type ComplianceTransactionType, toComplianceTransactionType } from '../enums/ComplianceTransactionType.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\n/**\n * Monetary values are kept as the decimal strings returned by the API (no\n * Number conversion) to preserve precision.\n */\nfunction asMoney(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return '0.00';\n}\n\nfunction asNullableNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '' && Number.isFinite(Number(value))) return Number(value);\n return null;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asRecordList(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value) ? value.filter((row): row is Record<string, unknown> => asRecord(row) !== null) : [];\n}\n\n/** One tax of a stored invoice line (provider shape, as recorded at creation/update). */\nexport interface ComplianceTransactionInvoiceLineTax {\n name: string;\n percent: number | null;\n category: string | null;\n /** VATEX exemption code for category \"E\". */\n comment: string | null;\n}\n\n/** One stored invoice line (`provider_payload.invoice.invoice_lines_attributes`). */\nexport interface ComplianceTransactionInvoiceLine {\n description: string;\n quantity: number | null;\n /** Unit price as a precision-safe decimal string. */\n price: string;\n /** UN/ECE unit code, e.g. 9 (each). */\n unit: number | null;\n taxes: ComplianceTransactionInvoiceLineTax[];\n}\n\nfunction toInvoiceLines(providerPayload: unknown): ComplianceTransactionInvoiceLine[] {\n const invoice = asRecord(asRecord(providerPayload)?.['invoice']);\n\n return asRecordList(invoice?.['invoice_lines_attributes']).map((line) => ({\n description: asString(line['description']),\n quantity: asNullableNumber(line['quantity']),\n price: asMoney(line['price']),\n unit: asNullableNumber(line['unit']),\n taxes: asRecordList(line['taxes_attributes']).map((tax) => ({\n name: asString(tax['name']),\n percent: asNullableNumber(tax['percent']),\n category: asNullableString(tax['category']),\n comment: asNullableString(tax['comment']),\n })),\n }));\n}\n\n/**\n * A recorded compliance transaction (GET/POST /compliance/transactions) — an\n * e-reported transaction (France) or an e-invoice / credit note (Norway).\n *\n * The e-invoicing fields at the end of the constructor are optional so DTOs\n * built from older servers (or by hand) stay valid.\n */\nexport class ComplianceTransaction {\n constructor(\n public readonly id: number,\n public readonly companyId: number,\n public readonly complianceEnrollmentId: number,\n public readonly country: string,\n public readonly regime: string,\n public readonly transactionType: ComplianceTransactionType,\n public readonly transactionTypeLabel: string,\n public readonly state: ComplianceTransactionState,\n public readonly stateLabel: string,\n public readonly invoiceNumber: string,\n /** Invoice date (YYYY-MM-DD). */\n public readonly invoiceDate: string | null,\n public readonly dueDate: string | null,\n public readonly currency: string,\n public readonly subtotal: string,\n public readonly taxAmount: string,\n public readonly total: string,\n public readonly counterpartyName: string | null,\n public readonly counterpartyCountry: string | null,\n public readonly counterpartyVatNumber: string | null,\n public readonly isPaid: boolean,\n public readonly paidAt: string | null,\n public readonly providerInvoiceId: string | null,\n public readonly submissionError: string | null,\n public readonly reportedAt: string | null,\n /** Associated DGFiP tax report; undefined when the API did not include it. */\n public readonly taxReport: ComplianceTaxReport | undefined,\n public readonly createdAt: string | null,\n public readonly updatedAt: string | null,\n /** Buyer's company register id (Norway: 9-digit organisation number). */\n public readonly counterpartyRegisterId: string | null = null,\n public readonly counterpartyAddress: string | null = null,\n public readonly counterpartyCity: string | null = null,\n public readonly counterpartyPostalcode: string | null = null,\n public readonly counterpartyEmail: string | null = null,\n public readonly buyerReference: string | null = null,\n /** \"invoice\" or \"credit_note\" (older servers without the field → \"invoice\"). */\n public readonly documentType: ComplianceDocumentType = ComplianceDocumentType.INVOICE,\n /** Number of the invoice a credit note corrects. */\n public readonly amendedNumber: string | null = null,\n /** Date of the invoice a credit note corrects (YYYY-MM-DD). */\n public readonly amendedDate: string | null = null,\n /**\n * Latest provider-side delivery state (e.g. \"sent\", \"accepted\", \"refused\",\n * \"paid\") — richer than `state` for e-invoicing, where delivery continues\n * after submission. Free-form string; null until the provider reports one.\n */\n public readonly providerState: string | null = null,\n /** The stored invoice lines (empty when the server does not include them). */\n public readonly invoiceLines: ComplianceTransactionInvoiceLine[] = [],\n ) {}\n\n get isCreditNote(): boolean {\n return this.documentType === ComplianceDocumentType.CREDIT_NOTE;\n }\n\n static fromArray(data: Record<string, unknown>): ComplianceTransaction {\n const taxReport =\n typeof data['tax_report'] === 'object' && data['tax_report'] !== null && !Array.isArray(data['tax_report'])\n ? ComplianceTaxReport.fromArray(data['tax_report'] as Record<string, unknown>)\n : undefined;\n\n return new ComplianceTransaction(\n asNumber(data['id']),\n asNumber(data['company_id']),\n asNumber(data['compliance_enrollment_id']),\n asString(data['country']),\n asString(data['regime']),\n toComplianceTransactionType(data['transaction_type']),\n asString(data['transaction_type_label']),\n toComplianceTransactionState(data['state']),\n asString(data['state_label']),\n asString(data['invoice_number']),\n asNullableString(data['invoice_date']),\n asNullableString(data['due_date']),\n asString(data['currency'], 'EUR'),\n asMoney(data['subtotal']),\n asMoney(data['tax_amount']),\n asMoney(data['total']),\n asNullableString(data['counterparty_name']),\n asNullableString(data['counterparty_country']),\n asNullableString(data['counterparty_vat_number']),\n data['is_paid'] === true,\n asNullableString(data['paid_at']),\n asNullableString(data['provider_invoice_id']),\n asNullableString(data['submission_error']),\n asNullableString(data['reported_at']),\n taxReport,\n asNullableString(data['created_at']),\n asNullableString(data['updated_at']),\n asNullableString(data['counterparty_register_id']),\n asNullableString(data['counterparty_address']),\n asNullableString(data['counterparty_city']),\n asNullableString(data['counterparty_postalcode']),\n asNullableString(data['counterparty_email']),\n asNullableString(data['buyer_reference']),\n data['document_type'] === undefined || data['document_type'] === null\n ? ComplianceDocumentType.INVOICE\n : toComplianceDocumentType(data['document_type']),\n asNullableString(data['amended_number']),\n asNullableString(data['amended_date']),\n asNullableString(data['provider_state']),\n toInvoiceLines(data['provider_payload']),\n );\n }\n}\n","import { ComplianceTransaction } from './ComplianceTransaction.js';\n\n/**\n * A paginated page of compliance transactions (GET /compliance/transactions).\n */\nexport class ComplianceTransactionPage implements Iterable<ComplianceTransaction> {\n constructor(\n public readonly rows: ComplianceTransaction[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n ) {}\n\n static fromResponse(payload: unknown): ComplianceTransactionPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(ComplianceTransaction.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n return new ComplianceTransactionPage(\n rows,\n num(meta['current_page'], 1),\n num(meta['per_page'], rows.length),\n num(meta['total'], rows.length),\n num(meta['last_page'], 1),\n );\n }\n\n [Symbol.iterator](): Iterator<ComplianceTransaction> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","/**\n * Result of a CSV transaction import (POST /compliance/transactions/import).\n */\nexport class ImportResult {\n constructor(\n /** Number of transactions created from the file. */\n public readonly created: number,\n /** Rows skipped because a matching transaction already exists (idempotent re-upload). */\n public readonly skippedDuplicates: number,\n /** Row-level errors, e.g. \"Row 3 (INV-1): invalid transaction_type 'x'\". */\n public readonly errors: string[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): ImportResult {\n const errors = (Array.isArray(data['errors']) ? (data['errors'] as unknown[]) : []).filter(\n (row): row is string => typeof row === 'string',\n );\n\n const num = (value: unknown): number => (typeof value === 'number' ? value : 0);\n\n return new ImportResult(num(data['created']), num(data['skipped_duplicates']), errors);\n }\n}\n","/**\n * Outcome of a Peppol directory lookup (GET /compliance/peppol-lookup). The\n * directory resolves asynchronously — `pending` means ask again in a few seconds.\n */\nexport const PeppolLookupStatus = {\n REACHABLE: 'reachable',\n NOT_REACHABLE: 'not_reachable',\n PENDING: 'pending',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type PeppolLookupStatus = (typeof PeppolLookupStatus)[keyof typeof PeppolLookupStatus];\n\nconst VALUES: readonly string[] = Object.values(PeppolLookupStatus);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toPeppolLookupStatus(value: unknown): PeppolLookupStatus {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as PeppolLookupStatus;\n }\n }\n return PeppolLookupStatus.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<PeppolLookupStatus, string> = {\n [PeppolLookupStatus.REACHABLE]: 'The participant is registered on Peppol and can receive e-invoices.',\n [PeppolLookupStatus.NOT_REACHABLE]: 'The participant is not registered on Peppol.',\n [PeppolLookupStatus.PENDING]: 'The directory lookup is still resolving — ask again in a few seconds.',\n [PeppolLookupStatus.UNKNOWN]: 'Unknown lookup status.',\n};\n\nexport function describePeppolLookupStatus(status: PeppolLookupStatus): string {\n return DESCRIPTIONS[status];\n}\n","import {\n type PeppolLookupStatus,\n PeppolLookupStatus as Status,\n toPeppolLookupStatus,\n} from '../enums/PeppolLookupStatus.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * Whether a participant can receive e-invoices over Peppol\n * (GET /compliance/peppol-lookup). For Norway, `reachable === true` means the\n * buyer is registered in ELMA and must receive an EHF e-invoice.\n */\nexport class PeppolLookupResult {\n constructor(\n public readonly status: PeppolLookupStatus,\n /** null while the lookup is still `pending`. */\n public readonly reachable: boolean | null,\n public readonly country: string,\n /** Peppol identifier scheme, e.g. \"0192\" for Norwegian organisation numbers. */\n public readonly scheme: string,\n /** Participant identifier, e.g. the organisation number. */\n public readonly id: string,\n /** Peppol document types the participant accepts, e.g. \"xml.ubl.invoice.bis3\". */\n public readonly documentTypes: string[],\n public readonly transportTypeCode: string | null,\n public readonly checkedAt: string | null,\n ) {}\n\n /** True while the directory is still resolving — ask again in a few seconds. */\n get isPending(): boolean {\n return this.status === Status.PENDING;\n }\n\n static fromArray(data: Record<string, unknown>): PeppolLookupResult {\n const documentTypes = Array.isArray(data['document_types'])\n ? (data['document_types'] as unknown[]).filter((t): t is string => typeof t === 'string')\n : [];\n\n return new PeppolLookupResult(\n toPeppolLookupStatus(data['status']),\n typeof data['reachable'] === 'boolean' ? data['reachable'] : null,\n asString(data['country']),\n asString(data['scheme']),\n asString(data['id']),\n documentTypes,\n asNullableString(data['transport_type_code']),\n asNullableString(data['checked_at']),\n );\n }\n}\n","function asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * A company from a national company register (GET /compliance/registry-lookup) —\n * for Norway the Brønnøysund Enhetsregisteret. Maps onto the Norway enrollment\n * input and the buyer fields of a Norwegian e-invoice.\n */\nexport class RegistryCompany {\n constructor(\n /** 9-digit Norwegian organisation number. */\n public readonly orgNumber: string,\n public readonly companyName: string,\n /** Legal form, e.g. \"AS\" or \"ASA\". */\n public readonly organisationForm: string | null,\n /** Registered for VAT (Merverdiavgiftsregisteret). */\n public readonly vatRegistered: boolean,\n /** \"NO…MVA\" VAT number; null when not VAT-registered. */\n public readonly vatNumber: string | null,\n /** Registered in Foretaksregisteret (adds \"Foretaksregisteret\" to invoices). */\n public readonly enterpriseRegister: boolean,\n public readonly bankrupt: boolean,\n public readonly underLiquidation: boolean,\n public readonly address: string | null,\n public readonly postalcode: string | null,\n public readonly city: string | null,\n /** 2-char ISO 3166-1 alpha-2 code, e.g. \"NO\". */\n public readonly country: string,\n ) {}\n\n static fromArray(data: Record<string, unknown>): RegistryCompany {\n return new RegistryCompany(\n asString(data['org_number']),\n asString(data['company_name']),\n asNullableString(data['organisation_form']),\n data['vat_registered'] === true,\n asNullableString(data['vat_number']),\n data['enterprise_register'] === true,\n data['bankrupt'] === true,\n data['under_liquidation'] === true,\n asNullableString(data['address']),\n asNullableString(data['postalcode']),\n asNullableString(data['city']),\n asString(data['country']),\n );\n }\n}\n","/**\n * DTOs for the e-reporting revenue statistics endpoint\n * (GET /compliance/revenue-statistics).\n *\n * Monetary values are kept as the 4-decimal strings returned by the API (no\n * Number conversion) to preserve precision. All headline figures are expressed\n * in `primaryCurrency`; when `isMultiCurrency` is true, `byCurrency` lists every\n * currency present in the range.\n */\n\nexport interface RevenueTotals {\n count: number;\n subtotal: string;\n taxAmount: string;\n total: string;\n}\n\nexport interface RevenueTimeBucket extends RevenueTotals {\n /** Period key: \"2026-01-15\" (day), \"2026-03\" (ISO year-week) or \"2026-01\" (month). */\n bucket: string;\n}\n\nexport interface RevenueTypeBreakdown {\n type: string;\n typeLabel: string;\n count: number;\n total: string;\n}\n\nexport interface RevenueCountryBreakdown {\n /** Counterparty country code; \"unknown\" groups transactions with no partner country. */\n country: string;\n count: number;\n total: string;\n}\n\nexport interface RevenueStateBreakdown {\n state: string;\n stateLabel: string;\n count: number;\n total: string;\n}\n\nexport interface RevenueCurrencyBreakdown extends RevenueTotals {\n currency: string;\n}\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\nfunction asMoney(value: unknown): string {\n return typeof value === 'string' ? value : '0.0000';\n}\n\nfunction asRecords(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null);\n}\n\nfunction toTotals(data: Record<string, unknown>): RevenueTotals {\n return {\n count: asNumber(data['count']),\n subtotal: asMoney(data['subtotal']),\n taxAmount: asMoney(data['tax_amount']),\n total: asMoney(data['total']),\n };\n}\n\nexport class RevenueStatistics {\n constructor(\n public readonly dateFrom: string | undefined,\n public readonly dateTo: string | undefined,\n public readonly interval: string | undefined,\n public readonly primaryCurrency: string,\n public readonly isMultiCurrency: boolean,\n public readonly totals: RevenueTotals,\n public readonly timeSeries: RevenueTimeBucket[],\n public readonly byType: RevenueTypeBreakdown[],\n public readonly byCountry: RevenueCountryBreakdown[],\n public readonly byState: RevenueStateBreakdown[],\n public readonly byCurrency: RevenueCurrencyBreakdown[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): RevenueStatistics {\n const range =\n typeof data['range'] === 'object' && data['range'] !== null ? (data['range'] as Record<string, unknown>) : {};\n\n const totals = toTotals(\n typeof data['totals'] === 'object' && data['totals'] !== null ? (data['totals'] as Record<string, unknown>) : {},\n );\n\n const timeSeries: RevenueTimeBucket[] = asRecords(data['time_series']).map((row) => ({\n bucket: asString(row['bucket']),\n ...toTotals(row),\n }));\n\n const byType: RevenueTypeBreakdown[] = asRecords(data['by_type']).map((row) => ({\n type: asString(row['type']),\n typeLabel: asString(row['type_label']),\n count: asNumber(row['count']),\n total: asMoney(row['total']),\n }));\n\n const byCountry: RevenueCountryBreakdown[] = asRecords(data['by_country']).map((row) => ({\n country: asString(row['country'], 'unknown'),\n count: asNumber(row['count']),\n total: asMoney(row['total']),\n }));\n\n const byState: RevenueStateBreakdown[] = asRecords(data['by_state']).map((row) => ({\n state: asString(row['state']),\n stateLabel: asString(row['state_label']),\n count: asNumber(row['count']),\n total: asMoney(row['total']),\n }));\n\n const byCurrency: RevenueCurrencyBreakdown[] = asRecords(data['by_currency']).map((row) => ({\n currency: asString(row['currency']),\n ...toTotals(row),\n }));\n\n return new RevenueStatistics(\n asString(range['date_from']) || undefined,\n asString(range['date_to']) || undefined,\n asString(range['interval']) || undefined,\n asString(data['primary_currency'], 'EUR'),\n data['is_multi_currency'] === true,\n totals,\n timeSeries,\n byType,\n byCountry,\n byState,\n byCurrency,\n );\n }\n}\n","function asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * Company data resolved from the French SIRENE registry\n * (GET /compliance/sirene-lookup). Maps 1:1 onto the createEnrollment input.\n */\nexport class SireneLookupResult {\n constructor(\n public readonly companyName: string,\n public readonly siren: string,\n public readonly siret: string | null,\n /** 2-digit NAF division, e.g. \"47\". */\n public readonly nafCode: string | null,\n /** Full NAF/APE code, e.g. \"47.11D\". */\n public readonly nafFull: string | null,\n /** Mapped enterprise size (\"micro\", \"pme\", \"eti\" or \"ge\"); null when unmappable. */\n public readonly enterpriseSize: string | null,\n public readonly address: string | null,\n public readonly city: string | null,\n public readonly postalcode: string | null,\n ) {}\n\n static fromArray(data: Record<string, unknown>): SireneLookupResult {\n return new SireneLookupResult(\n asString(data['company_name']),\n asString(data['siren']),\n asNullableString(data['siret']),\n asNullableString(data['naf_code']),\n asNullableString(data['naf_full']),\n asNullableString(data['enterprise_size']),\n asNullableString(data['address']),\n asNullableString(data['city']),\n asNullableString(data['postalcode']),\n );\n }\n}\n","/**\n * One VAT rate / DGFiP tax category offered for a reporting country.\n */\nexport interface VatRate {\n /** VAT percentage, e.g. 20 or 5.5. */\n percent: number;\n /** DGFiP tax category code (S/AA/AAA/K/G/AE/E/Z). */\n category: string;\n /** i18n key for the rate label, e.g. \"fr_standard\". */\n labelKey: string;\n /** Default tax designation prefilled into invoice lines, e.g. \"TVA\". */\n taxName: string;\n /** True when a VATEX exemption code is mandatory in the line's `comment` (category E). */\n requiresVatex: boolean;\n}\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\n/**\n * The canonical VAT rates & DGFiP tax categories for a reporting country\n * (GET /compliance/vat-rates).\n */\nexport class VatRates {\n constructor(\n public readonly country: string,\n public readonly currency: string,\n public readonly rates: VatRate[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): VatRates {\n const rates: VatRate[] = (Array.isArray(data['rates']) ? (data['rates'] as unknown[]) : [])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map((row) => ({\n percent: asNumber(row['percent']),\n category: asString(row['category']),\n labelKey: asString(row['label_key']),\n taxName: asString(row['tax_name']),\n requiresVatex: row['requires_vatex'] === true,\n }));\n\n return new VatRates(asString(data['country']), asString(data['currency'], 'EUR'), rates);\n }\n}\n","import { TaxoraException } from './TaxoraException.js';\n\nexport class ValidationException extends TaxoraException {\n public readonly statusCode = 422;\n private readonly errors: Record<string, string[]>;\n\n constructor(message: string, errors: Record<string, string[]>, context: Record<string, unknown> = {}) {\n super(message, context);\n this.name = 'ValidationException';\n this.errors = errors;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n getErrors(): Record<string, string[]> {\n return this.errors;\n }\n}\n","const WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2] as const;\n\n/**\n * Norwegian organisation number (organisasjonsnummer): 9 digits, the last one a\n * modulus-11 check digit (weights 3,2,7,6,5,4,3,2). It is also the Peppol\n * participant identifier under scheme 0192 and — with the \"NO\" prefix and \"MVA\"\n * suffix — the Norwegian VAT number.\n *\n * Mirrors the backend's validation, so invalid numbers are rejected before a\n * request is sent.\n */\nexport const NorwegianOrgNumber = {\n /** Peppol identifier scheme for Norwegian organisation numbers. */\n PEPPOL_SCHEME: '0192',\n\n /**\n * Strips whitespace, dots, dashes, a \"0192:\" Peppol scheme prefix, the \"NO\"\n * prefix and the \"MVA\" suffix: \"NO 923 609 016 MVA\", \"923609016MVA\" and\n * \"923 609 016\" all become \"923609016\". Does not validate.\n */\n normalize(value: string | null | undefined): string {\n let v = (value ?? '')\n .trim()\n .toUpperCase()\n .replace(/[\\s.-]/g, '');\n\n if (v.startsWith('0192:')) v = v.slice(5);\n if (v.startsWith('NO')) v = v.slice(2);\n if (v.endsWith('MVA')) v = v.slice(0, -3);\n\n return v;\n },\n\n /** True when the (normalized) value is 9 digits with a valid mod-11 check digit. */\n isValid(value: string | null | undefined): boolean {\n const digits = NorwegianOrgNumber.normalize(value);\n if (!/^\\d{9}$/.test(digits)) return false;\n\n let sum = 0;\n for (let i = 0; i < WEIGHTS.length; i++) {\n sum += Number(digits[i]) * WEIGHTS[i]!;\n }\n\n let check = 11 - (sum % 11);\n if (check === 11) check = 0;\n\n // Remainder 1 → check digit 10 is impossible; such numbers are never issued.\n return check !== 10 && check === Number(digits[8]);\n },\n\n /** \"NO923609016MVA\" — the Norwegian VAT number of an MVA-registered entity. Does not validate. */\n toVatNumber(value: string): string {\n return `NO${NorwegianOrgNumber.normalize(value)}MVA`;\n },\n} as const;\n","import { ComplianceEnrollment } from '../dto/ComplianceEnrollment.js';\nimport { ComplianceEnrollmentPage } from '../dto/ComplianceEnrollmentPage.js';\nimport { ComplianceTaxReport } from '../dto/ComplianceTaxReport.js';\nimport { ComplianceTaxReportPage } from '../dto/ComplianceTaxReportPage.js';\nimport { ComplianceTransaction } from '../dto/ComplianceTransaction.js';\nimport { ComplianceTransactionPage } from '../dto/ComplianceTransactionPage.js';\nimport { ImportResult } from '../dto/ImportResult.js';\nimport { PeppolLookupResult } from '../dto/PeppolLookupResult.js';\nimport { RegistryCompany } from '../dto/RegistryCompany.js';\nimport { RevenueStatistics } from '../dto/RevenueStatistics.js';\nimport { SireneLookupResult } from '../dto/SireneLookupResult.js';\nimport { VatRates } from '../dto/VatRates.js';\nimport { type ComplianceService } from '../enums/ComplianceService.js';\nimport { type ComplianceTaxReportState } from '../enums/ComplianceTaxReportState.js';\nimport { type ComplianceTransactionState } from '../enums/ComplianceTransactionState.js';\nimport { type ComplianceTransactionType } from '../enums/ComplianceTransactionType.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport { ValidationException } from '../exceptions/ValidationException.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withResponseRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\nimport { NorwegianOrgNumber } from '../support/NorwegianOrgNumber.js';\n\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst NAF_CODE_REGEX = /^\\d{2}$/;\nconst COUNTRY_REGEX = /^[A-Za-z]{2}$/;\nconst PEPPOL_SCHEME_REGEX = /^\\d{4}$/;\n\n/** Time-series bucket size accepted by the revenue statistics endpoint. */\nexport type EReportingInterval = 'day' | 'week' | 'month';\n\n/** Enterprise size categories accepted by the DGFiP enrollment. */\nexport type ComplianceEnterpriseSize = 'micro' | 'pme' | 'eti' | 'ge';\n\n/** Type of operations the enrolled company performs. */\nexport type ComplianceTypeOperation = 'services' | 'goods' | 'mixed';\n\n/** Services accepted on the request side (the tolerant `unknown` is response-only). */\nexport type ComplianceRequestService = Exclude<ComplianceService, 'unknown'>;\n\n/** Transaction types accepted on the request side (the tolerant `unknown` is response-only). */\nexport type ComplianceTransactionRequestType = Exclude<ComplianceTransactionType, 'unknown'>;\n\n/** Transaction states accepted as filters (the tolerant `unknown` is response-only). */\nexport type ComplianceTransactionRequestState = Exclude<ComplianceTransactionState, 'unknown'>;\n\n/** Tax report states accepted as filters (the tolerant `unknown` is response-only). */\nexport type ComplianceTaxReportRequestState = Exclude<ComplianceTaxReportState, 'unknown'>;\n\nconst INTERVALS: readonly EReportingInterval[] = ['day', 'week', 'month'];\nconst SERVICES: readonly ComplianceRequestService[] = ['e_reporting', 'e_invoicing'];\nconst ENTERPRISE_SIZES: readonly ComplianceEnterpriseSize[] = ['micro', 'pme', 'eti', 'ge'];\nconst TYPE_OPERATIONS: readonly ComplianceTypeOperation[] = ['services', 'goods', 'mixed'];\nconst TRANSACTION_TYPES: readonly ComplianceTransactionRequestType[] = [\n 'b2c_outbound',\n 'b2b_domestic_outbound',\n 'b2b_domestic_inbound',\n 'crossborder_outbound',\n 'crossborder_inbound',\n];\n\nexport interface RevenueStatisticsFilters {\n dateFrom?: Date | string;\n dateTo?: Date | string;\n /** Time-series bucket size. Defaults to \"month\" server-side. */\n interval?: EReportingInterval;\n transactionType?: ComplianceTransactionRequestType;\n state?: ComplianceTransactionRequestState;\n}\n\n/**\n * France (DGFiP e-reporting) enrollment — the original createEnrollment() input.\n * For Norway use {@link CreateNorwayEnrollmentInput} (or createNorwayEnrollment()).\n */\nexport interface CreateComplianceEnrollmentInput {\n /** Reporting country (2-char ISO 3166-1 alpha-2). Defaults server-side (FR). \"NO\" selects the Norway input. */\n country?: string;\n /** Service to book. Defaults server-side to the country's default service (FR: \"e_reporting\"). */\n service?: ComplianceRequestService;\n /** Compliance regime, e.g. \"dgfip_flux10\". Defaults server-side. */\n regime?: string;\n /** 14-digit SIRET. Required unless `siren` is set. */\n siret?: string;\n /** 9-digit SIREN. Required unless `siret` is set. */\n siren?: string;\n vatNumber?: string;\n companyName?: string;\n address?: string;\n city?: string;\n postalcode?: string;\n province?: string;\n /** Notification email for the provider account. */\n email: string;\n /** 2-digit NAF division, e.g. \"47\". */\n nafCode: string;\n enterpriseSize: ComplianceEnterpriseSize;\n typeOperation: ComplianceTypeOperation;\n /** First date transactions are reported for (Date or strict YYYY-MM-DD). */\n reportingStartDate: Date | string;\n /** When false, only the provider account is created — the DGFiP regime is NOT activated. Defaults to true server-side. */\n autoActivate?: boolean;\n}\n\n/**\n * Norway e-invoicing (EHF / Peppol BIS 3.0) enrollment: registers the company\n * as a Peppol participant so it can send (and optionally receive) e-invoices.\n * Prefill it from registryLookup('NO', …).\n */\nexport interface CreateNorwayEnrollmentInput {\n country: 'NO';\n /** Service to book. Defaults server-side to \"e_invoicing\" (the only service for NO). */\n service?: ComplianceRequestService;\n /** Compliance regime. Defaults server-side (\"peppol_bis3\"). */\n regime?: string;\n /**\n * 9-digit Norwegian organisation number (mod-11 check digit). Spaces, a \"NO\"\n * prefix and an \"MVA\" suffix are accepted and stripped before sending.\n */\n orgNumber: string;\n companyName: string;\n address: string;\n city: string;\n postalcode: string;\n /** Notification email for the provider account. */\n email: string;\n vatNumber?: string;\n province?: string;\n /** Registered in Merverdiavgiftsregisteret (adds \"MVA\" to invoices). Defaults to true server-side. */\n vatRegistered?: boolean;\n /** Registered in Foretaksregisteret (adds \"Foretaksregisteret\" to invoices). Defaults to false server-side. */\n enterpriseRegister?: boolean;\n /** Also register to RECEIVE e-invoices over Peppol. Defaults to false server-side. */\n reception?: boolean;\n /** Country of the legal entity when it differs from NO (2-char ISO 3166-1 alpha-2). */\n legalCountry?: string;\n /** Optional first date transactions are recorded for (Date or strict YYYY-MM-DD). */\n reportingStartDate?: Date | string;\n /** When false, only the provider account is created — the Peppol registration is NOT activated. Defaults to true server-side. */\n autoActivate?: boolean;\n}\n\n/** createNorwayEnrollment() input — the Norway input without the fixed `country`. */\nexport type NorwayEnrollmentInput = Omit<CreateNorwayEnrollmentInput, 'country'>;\n\nexport interface ComplianceInvoiceTaxInput {\n /** Tax designation, e.g. \"TVA\". */\n name: string;\n /** VAT percentage, e.g. 20 or 5.5. */\n percent: number;\n /** DGFiP tax category code (S/AA/AAA/K/G/AE/E/Z) — see getVatRates(). */\n category: string;\n /** VATEX exemption code; required when `category` is \"E\". */\n comment?: string;\n}\n\nexport interface ComplianceInvoiceLineInput {\n description: string;\n quantity: number;\n price: number;\n /** UN/ECE unit code, e.g. 9 (each). */\n unit?: number;\n /** At least one tax per line. */\n taxes: ComplianceInvoiceTaxInput[];\n}\n\n/**\n * Buyer and document fields interpreted per country. For Norway (EHF / Peppol)\n * `counterpartyRegisterId` (the buyer's organisation number) and\n * `counterpartyName` are required unless `providerContactId` is set, the\n * transaction type must be \"b2b_domestic_outbound\", and a credit note needs\n * `amendedNumber`. The SDK does not know the enrollment's country — those rules\n * are enforced server-side (422).\n */\nexport interface ComplianceTransactionBuyerInput {\n /** Buyer's company register id (Norway: 9-digit organisation number; \"NO…MVA\" is accepted). Max 30 chars. */\n counterpartyRegisterId?: string;\n counterpartyAddress?: string;\n counterpartyCity?: string;\n counterpartyPostalcode?: string;\n /** Buyer's email address. */\n counterpartyEmail?: string;\n /** Buyer reference (Peppol BuyerReference); max 100 chars. Norway defaults it to the buyer's org number. */\n buyerReference?: string;\n /** Issue the document as a credit note. */\n isCreditNote?: boolean;\n /** Number of the invoice a credit note corrects (max 50 chars). */\n amendedNumber?: string;\n /** Date of the invoice a credit note corrects (Date or strict YYYY-MM-DD). */\n amendedDate?: Date | string;\n /** Free-text note printed on the invoice (max 1000 chars). */\n extraInfo?: string;\n}\n\nexport interface CreateComplianceTransactionInput extends ComplianceTransactionBuyerInput {\n complianceEnrollmentId: number;\n transactionType: ComplianceTransactionRequestType;\n invoiceNumber: string;\n /** Invoice date (Date or strict YYYY-MM-DD). */\n invoiceDate: Date | string;\n subtotal: number;\n total: number;\n /** At least one invoice line, each with at least one tax. */\n invoiceLines: ComplianceInvoiceLineInput[];\n dueDate?: Date | string;\n /** 3-char ISO 4217 code. Defaults to EUR server-side. */\n currency?: string;\n taxAmount?: number;\n counterpartyName?: string;\n /** 2-char ISO 3166-1 alpha-2 code. */\n counterpartyCountry?: string;\n counterpartyVatNumber?: string;\n providerContactId?: string;\n /** Payment means code; required for cross-border outbound. */\n paymentMethod?: number;\n remittanceInformation?: string;\n paymentMethodText?: string;\n paymentTerms?: string;\n /** When false, the transaction is only recorded — submission is deferred. Defaults to true server-side. */\n submitNow?: boolean;\n}\n\nexport interface UpdateComplianceTransactionInput extends ComplianceTransactionBuyerInput {\n transactionType?: ComplianceTransactionRequestType;\n invoiceNumber?: string;\n invoiceDate?: Date | string;\n dueDate?: Date | string;\n /** 3-char ISO 4217 code. */\n currency?: string;\n subtotal?: number;\n taxAmount?: number;\n total?: number;\n counterpartyName?: string;\n /** 2-char ISO 3166-1 alpha-2 code. */\n counterpartyCountry?: string;\n counterpartyVatNumber?: string;\n providerContactId?: string;\n /** When set: at least one invoice line, each with at least one tax. */\n invoiceLines?: ComplianceInvoiceLineInput[];\n paymentMethod?: number;\n remittanceInformation?: string;\n paymentMethodText?: string;\n paymentTerms?: string;\n}\n\nexport interface ComplianceTransactionFilters {\n /** Inclusive lower bound on the invoice date (Date or strict YYYY-MM-DD). */\n dateFrom?: Date | string;\n /** Inclusive upper bound on the invoice date (Date or strict YYYY-MM-DD). */\n dateTo?: Date | string;\n state?: ComplianceTransactionRequestState;\n transactionType?: ComplianceTransactionRequestType;\n /** Only transactions of this enrollment. */\n complianceEnrollmentId?: number;\n /** Only transactions of this country (2-char ISO 3166-1 alpha-2). */\n country?: string;\n page?: number;\n /** Page size (1-100, default 25 server-side). */\n perPage?: number;\n}\n\nexport interface EReportingAccessRequestInput {\n name?: string;\n email?: string;\n company?: string;\n phone?: string;\n message?: string;\n /** Locale for the confirmation mail, e.g. \"de\" or \"en\". */\n language?: string;\n /** The service being requested. Defaults server-side to \"e_reporting\". */\n service?: ComplianceRequestService;\n /** The countries the service is requested for (2-char ISO codes), e.g. [\"NO\"]. */\n countries?: string[];\n}\n\n/**\n * E-Reporting / Compliance endpoints (per-country services).\n *\n * - France — e-reporting (DGFiP Flux 10): sireneLookup() to prefill company\n * data, createEnrollment() to provision the provider account, then\n * createTransaction() / importTransactions() to record invoices and\n * listTaxReports() to track their DGFiP lifecycle.\n * - Norway — e-invoicing (EHF / Peppol BIS 3.0): registryLookup('NO', …) to\n * prefill company/buyer data, createNorwayEnrollment() to register as a Peppol\n * participant, peppolLookup('NO', …) to check a buyer is reachable, then\n * createTransaction() to send invoices and credit notes.\n *\n * Each country/service is unlocked (and billed) separately; enrolling for a\n * service the company does not have yields a 403 with code `service_not_active`.\n * All routes except requestEReportingAccess() require compliance access on the\n * account.\n */\nexport class EReportingEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n // ---------------------------------------------------------------------\n // Enrollments\n // ---------------------------------------------------------------------\n\n /**\n * Create a compliance enrollment and provision the provider account. By\n * default the country regime is activated right away (France: DGFiP tax\n * report setting; Norway: Peppol registration); pass `autoActivate: false`\n * to only create the account.\n *\n * The input shape depends on `country`: omitted/\"FR\" takes the France input\n * (unchanged, backwards compatible), \"NO\" the Norway input — see also the\n * createNorwayEnrollment() shortcut.\n *\n * Errors: 403 (HttpException, body code `service_not_active`) when the company\n * lacks the requested service; on provider failure 502 (HttpException) — the\n * enrollment is then persisted in `error_account`/`error_activation` state so\n * provisioning can be retried.\n */\n async createEnrollment(\n input: CreateComplianceEnrollmentInput | CreateNorwayEnrollmentInput,\n ): Promise<ComplianceEnrollment> {\n if (this.isNorwayEnrollmentInput(input)) {\n return this.createEnrollmentFromBody(this.buildNorwayEnrollmentBody(input));\n }\n\n this.validateEnrollmentInput(input);\n\n const body: Record<string, unknown> = {\n email: input.email,\n naf_code: input.nafCode,\n enterprise_size: input.enterpriseSize,\n type_operation: input.typeOperation,\n reporting_start_date: this.formatDate(input.reportingStartDate),\n };\n if (input.country !== undefined) body['country'] = input.country;\n if (input.service !== undefined) body['service'] = input.service;\n if (input.regime !== undefined) body['regime'] = input.regime;\n if (input.siret !== undefined) body['siret'] = input.siret;\n if (input.siren !== undefined) body['siren'] = input.siren;\n if (input.vatNumber !== undefined) body['vat_number'] = input.vatNumber;\n if (input.companyName !== undefined) body['company_name'] = input.companyName;\n if (input.address !== undefined) body['address'] = input.address;\n if (input.city !== undefined) body['city'] = input.city;\n if (input.postalcode !== undefined) body['postalcode'] = input.postalcode;\n if (input.province !== undefined) body['province'] = input.province;\n if (input.autoActivate !== undefined) body['auto_activate'] = input.autoActivate;\n\n return this.createEnrollmentFromBody(body);\n }\n\n /**\n * Enroll the company for Norway e-invoicing (EHF / Peppol BIS 3.0) — shortcut\n * for createEnrollment({ country: 'NO', ... }). The organisation number is\n * checked (mod-11) and normalized to 9 digits before sending.\n */\n async createNorwayEnrollment(input: NorwayEnrollmentInput): Promise<ComplianceEnrollment> {\n return this.createEnrollment({ ...input, country: 'NO' });\n }\n\n /** Paginated list of the company's enrollments (newest first). `perPage` is capped at 100 server-side. */\n async listEnrollments(page = 1, perPage = 25): Promise<ComplianceEnrollmentPage> {\n const params = new URLSearchParams();\n params.set('page', String(page));\n params.set('per_page', String(perPage));\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/enrollments?${params.toString()}`);\n // Double envelope: { success, data: { data: [...], meta: {...} } } — parseJsonResponse\n // unwraps the outer `data`; fromResponse reads the inner rows + pagination meta.\n return ComplianceEnrollmentPage.fromResponse(await this.parseJsonResponse(response));\n }\n\n /** Get a single enrollment by id. */\n async getEnrollment(id: number): Promise<ComplianceEnrollment> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/enrollments/${id}`);\n const data = await this.parseJsonResponse(response);\n return ComplianceEnrollment.fromArray(data);\n }\n\n /**\n * Look up company data by SIRET, SIREN or French VAT number via the French\n * SIRENE registry — ideal for prefilling createEnrollment().\n *\n * Rate-limited to 3 requests/minute per user (protects the external French\n * government API); exceeding it yields a 429 (mapped to an HttpException).\n */\n async sireneLookup(q: string): Promise<SireneLookupResult> {\n if (q.trim() === '') {\n throw new TaxoraException('q must not be empty.');\n }\n\n const params = new URLSearchParams();\n params.set('q', q);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/sirene-lookup?${params.toString()}`);\n const data = await this.parseJsonResponse(response);\n return SireneLookupResult.fromArray(data);\n }\n\n /**\n * Look up companies in a national company register — currently Norway\n * (Brønnøysund Enhetsregisteret). `q` is an organisation number, a \"NO…MVA\"\n * VAT number or a company name; an exact number match yields one result.\n * Ideal for prefilling createNorwayEnrollment() and the buyer fields of an\n * e-invoice. For France use sireneLookup().\n *\n * Errors: 404 (HttpException) when nothing is found, 422 (ValidationException)\n * on invalid input / unsupported country, 429 (HttpException) when the\n * per-user rate limit (30/min) is exceeded.\n */\n async registryLookup(country: string, q: string): Promise<RegistryCompany[]> {\n const normalizedCountry = this.normalizeLookupCountry(country);\n const query = q.trim();\n if (query === '') {\n throw new TaxoraException('q must not be empty.');\n }\n if (normalizedCountry === 'NO') {\n const digits = NorwegianOrgNumber.normalize(query);\n if (/^\\d{9}$/.test(digits) && !NorwegianOrgNumber.isValid(digits)) {\n throw new TaxoraException(`Invalid Norwegian organisation number \"${query}\" (check digit).`);\n }\n }\n\n const params = new URLSearchParams();\n params.set('country', normalizedCountry);\n params.set('q', query);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/registry-lookup?${params.toString()}`);\n const data = await this.parseJsonResponse(response);\n const results = Array.isArray(data['results']) ? (data['results'] as unknown[]) : [];\n\n return results\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null && !Array.isArray(row))\n .map((row) => RegistryCompany.fromArray(row));\n }\n\n /**\n * Check whether a participant (typically the buyer) can receive e-invoices\n * over Peppol. For Norway pass the organisation number (scheme defaults to\n * \"0192\"): `reachable === true` means the buyer is registered in ELMA and must\n * receive an EHF e-invoice. The directory resolves asynchronously —\n * `status === 'pending'` (`reachable === null`) means ask again in a few\n * seconds. Free of charge; definite answers are cached for 24h server-side.\n *\n * A Norwegian organisation number is checked (mod-11) and normalized before\n * sending. Errors: 422 (ValidationException) on invalid input, 502\n * (HttpException) on provider failure.\n */\n async peppolLookup(country: string, id: string, scheme?: string): Promise<PeppolLookupResult> {\n const normalizedCountry = this.normalizeLookupCountry(country);\n let participantId = id.trim();\n if (participantId === '') {\n throw new TaxoraException('id must not be empty.');\n }\n if (scheme !== undefined && !PEPPOL_SCHEME_REGEX.test(scheme)) {\n throw new TaxoraException('scheme must be a 4-digit Peppol identifier scheme, e.g. \"0192\".');\n }\n if (normalizedCountry === 'NO' && (scheme === undefined || scheme === NorwegianOrgNumber.PEPPOL_SCHEME)) {\n if (!NorwegianOrgNumber.isValid(participantId)) {\n throw new TaxoraException(`Invalid Norwegian organisation number \"${participantId}\".`);\n }\n participantId = NorwegianOrgNumber.normalize(participantId);\n }\n\n const params = new URLSearchParams();\n params.set('country', normalizedCountry);\n params.set('id', participantId);\n if (scheme !== undefined) params.set('scheme', scheme);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/peppol-lookup?${params.toString()}`);\n const data = await this.parseJsonResponse(response);\n return PeppolLookupResult.fromArray(data);\n }\n\n // ---------------------------------------------------------------------\n // Transactions\n // ---------------------------------------------------------------------\n\n /**\n * Record and (by default) submit a Flux 10 transaction. Pass `submitNow: false`\n * to only record it — submission can be triggered later via submitTransaction().\n *\n * Immediate per-invoice submission requires the e-invoicing feature on the\n * account; in pure e-reporting mode the transaction is only recorded and\n * reported via the aggregated daily ledgers.\n *\n * Creation is idempotent on the invoice's natural key (enrollment, type,\n * invoice number, invoice date, counterparty VAT): a re-sent create returns\n * the existing transaction with HTTP 200 instead of creating a duplicate.\n *\n * On provider failure the API responds 502 (mapped to an HttpException).\n */\n async createTransaction(input: CreateComplianceTransactionInput): Promise<ComplianceTransaction> {\n this.validateId(input.complianceEnrollmentId, 'complianceEnrollmentId');\n this.validateTransactionType(input.transactionType);\n this.validateInvoiceNumber(input.invoiceNumber);\n this.validateInvoiceLines(input.invoiceLines);\n this.validateOptionalCodes(input);\n this.validateBuyerFields(input);\n\n const body: Record<string, unknown> = {\n compliance_enrollment_id: input.complianceEnrollmentId,\n transaction_type: input.transactionType,\n invoice_number: input.invoiceNumber,\n invoice_date: this.formatDate(input.invoiceDate),\n subtotal: input.subtotal,\n total: input.total,\n invoice_lines_attributes: this.buildInvoiceLines(input.invoiceLines),\n };\n this.applyOptionalTransactionFields(body, input);\n if (input.submitNow !== undefined) body['submit_now'] = input.submitNow;\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/transactions`, body);\n // 201 = created, 200 = idempotent replay of an already-recorded invoice.\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /** Paginated list of the company's transactions (newest invoice date first), filterable by date / state / type / enrollment / country. */\n async listTransactions(filters: ComplianceTransactionFilters = {}): Promise<ComplianceTransactionPage> {\n if (filters.complianceEnrollmentId !== undefined) {\n this.validateId(filters.complianceEnrollmentId, 'complianceEnrollmentId');\n }\n if (filters.country !== undefined && !COUNTRY_REGEX.test(filters.country)) {\n throw new TaxoraException('country must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n\n const params = new URLSearchParams();\n if (filters.dateFrom !== undefined) params.set('date_from', this.formatDate(filters.dateFrom));\n if (filters.dateTo !== undefined) params.set('date_to', this.formatDate(filters.dateTo));\n if (filters.state !== undefined) params.set('state', filters.state);\n if (filters.transactionType !== undefined) params.set('transaction_type', filters.transactionType);\n if (filters.complianceEnrollmentId !== undefined) {\n params.set('compliance_enrollment_id', String(filters.complianceEnrollmentId));\n }\n if (filters.country !== undefined) params.set('country', filters.country.toUpperCase());\n if (filters.page !== undefined) params.set('page', String(filters.page));\n if (filters.perPage !== undefined) params.set('per_page', String(filters.perPage));\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/compliance/transactions${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n return ComplianceTransactionPage.fromResponse(await this.parseJsonResponse(response));\n }\n\n /** Get a single transaction by id (includes its tax report when one exists). */\n async getTransaction(id: number): Promise<ComplianceTransaction> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/transactions/${id}`);\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /** Update a still-pending transaction. Only the provided fields are sent; already-submitted transactions are rejected with 422. */\n async updateTransaction(id: number, input: UpdateComplianceTransactionInput): Promise<ComplianceTransaction> {\n this.validateId(id, 'id');\n if (input.transactionType !== undefined) this.validateTransactionType(input.transactionType);\n if (input.invoiceNumber !== undefined) this.validateInvoiceNumber(input.invoiceNumber);\n if (input.invoiceLines !== undefined) this.validateInvoiceLines(input.invoiceLines);\n this.validateOptionalCodes(input);\n this.validateBuyerFields(input);\n\n const body: Record<string, unknown> = {};\n if (input.transactionType !== undefined) body['transaction_type'] = input.transactionType;\n if (input.invoiceNumber !== undefined) body['invoice_number'] = input.invoiceNumber;\n if (input.invoiceDate !== undefined) body['invoice_date'] = this.formatDate(input.invoiceDate);\n if (input.subtotal !== undefined) body['subtotal'] = input.subtotal;\n if (input.total !== undefined) body['total'] = input.total;\n if (input.invoiceLines !== undefined) body['invoice_lines_attributes'] = this.buildInvoiceLines(input.invoiceLines);\n this.applyOptionalTransactionFields(body, input);\n\n const response = await this.sendRequest('PUT', `${this.baseUrl}/compliance/transactions/${id}`, body);\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /** Delete a still-pending transaction. Already-submitted transactions are rejected with 422. */\n async deleteTransaction(id: number): Promise<void> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('DELETE', `${this.baseUrl}/compliance/transactions/${id}`);\n await this.assertNoContentResponse(response);\n }\n\n /**\n * Submit (or retry) an existing `pending`/`error` transaction to the provider.\n * Replays the invoice lines stored at creation, so they don't have to be re-sent.\n *\n * Requires the e-invoicing feature on the account — pure e-reporting customers\n * get a 422 (transactions are reported via the aggregated daily ledgers instead).\n *\n * On provider failure the API responds 502 (mapped to an HttpException);\n * already-submitted transactions are rejected with 422.\n */\n async submitTransaction(id: number): Promise<ComplianceTransaction> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/transactions/${id}/submit`);\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /**\n * Bulk-import transactions from a semicolon-separated CSV (one row per invoice\n * line; rows sharing an invoice_number are grouped into one transaction).\n * Required columns: invoice_number, invoice_date, transaction_type, subtotal,\n * total, line_description, line_quantity, line_price, tax_name, tax_percent,\n * tax_category.\n *\n * The import is idempotent: re-uploading the same file skips rows whose\n * invoice already exists (reported via `skippedDuplicates`).\n */\n async importTransactions(\n enrollmentId: number,\n csvContent: string,\n filename = 'transactions.csv',\n ): Promise<ImportResult> {\n this.validateId(enrollmentId, 'enrollmentId');\n if (csvContent.trim() === '') {\n throw new TaxoraException('csvContent must not be empty.');\n }\n\n const form = new FormData();\n form.set('compliance_enrollment_id', String(enrollmentId));\n form.set('file', new Blob([csvContent], { type: 'text/csv' }), filename);\n\n const response = await this.sendMultipartRequest('POST', `${this.baseUrl}/compliance/transactions/import`, form);\n const data = await this.parseJsonResponse(response);\n return ImportResult.fromArray(data);\n }\n\n // ---------------------------------------------------------------------\n // Analytics, configuration & reports\n // ---------------------------------------------------------------------\n\n /**\n * Aggregated turnover statistics for the authenticated company's e-reporting\n * transactions. All arguments are optional — the API defaults to the last 12\n * months and a monthly interval.\n */\n async getRevenueStatistics(filters: RevenueStatisticsFilters = {}): Promise<RevenueStatistics> {\n if (filters.interval !== undefined && !INTERVALS.includes(filters.interval)) {\n throw new TaxoraException(\n `Invalid statistics interval \"${String(filters.interval)}\". Expected one of: ${INTERVALS.join(', ')}.`,\n );\n }\n\n const params = new URLSearchParams();\n if (filters.dateFrom !== undefined) params.set('date_from', this.formatDate(filters.dateFrom));\n if (filters.dateTo !== undefined) params.set('date_to', this.formatDate(filters.dateTo));\n if (filters.interval !== undefined) params.set('interval', filters.interval);\n if (filters.transactionType !== undefined) params.set('transaction_type', filters.transactionType);\n if (filters.state !== undefined) params.set('state', filters.state);\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/compliance/revenue-statistics${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n\n return RevenueStatistics.fromArray(data);\n }\n\n /**\n * The canonical VAT rates & DGFiP tax categories for a reporting country\n * (the seller's reporting-country rates, not the counterparty's). Falls back\n * to the configured default country (FR) when none/unknown is given.\n */\n async getVatRates(country?: string): Promise<VatRates> {\n const params = new URLSearchParams();\n if (country !== undefined) params.set('country', country);\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/compliance/vat-rates${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n return VatRates.fromArray(data);\n }\n\n /** Paginated list of the company's tax reports (newest first), optionally filtered by state. */\n async listTaxReports(\n page = 1,\n perPage = 25,\n state?: ComplianceTaxReportRequestState,\n ): Promise<ComplianceTaxReportPage> {\n const params = new URLSearchParams();\n params.set('page', String(page));\n params.set('per_page', String(perPage));\n if (state !== undefined) params.set('state', state);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/tax-reports?${params.toString()}`);\n return ComplianceTaxReportPage.fromResponse(await this.parseJsonResponse(response));\n }\n\n /** Get a single tax report by id. */\n async getTaxReport(id: number): Promise<ComplianceTaxReport> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/tax-reports/${id}`);\n const data = await this.parseJsonResponse(response);\n return ComplianceTaxReport.fromArray(data);\n }\n\n /**\n * Request activation of the E-Reporting feature for the account. This route\n * is deliberately NOT gated by compliance access — it exists precisely for\n * accounts that do not have the feature yet. The authenticated user's\n * name/email take precedence over the form values server-side.\n *\n * Note: unlike the other compliance routes, validation failures here are\n * returned as HTTP 400 (surfaced as HttpException), not 422.\n */\n async requestEReportingAccess(input: EReportingAccessRequestInput = {}): Promise<void> {\n if (input.service !== undefined) this.validateService(input.service);\n if (input.countries !== undefined) {\n input.countries.forEach((country, index) => {\n if (!COUNTRY_REGEX.test(country)) {\n throw new TaxoraException(`countries[${index}] must be a 2-character ISO 3166-1 alpha-2 code.`);\n }\n });\n }\n\n const body: Record<string, unknown> = {};\n if (input.name !== undefined) body['name'] = input.name;\n if (input.email !== undefined) body['email'] = input.email;\n if (input.company !== undefined) body['company'] = input.company;\n if (input.phone !== undefined) body['phone'] = input.phone;\n if (input.message !== undefined) body['message'] = input.message;\n if (input.language !== undefined) body['language'] = input.language;\n if (input.service !== undefined) body['service'] = input.service;\n if (input.countries !== undefined) body['countries'] = input.countries.map((c) => c.toUpperCase());\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/e-reporting-request`, body);\n await this.parseJsonResponse(response);\n }\n\n // ---------------------------------------------------------------------\n // Input validation (fail fast, before any request is sent)\n // ---------------------------------------------------------------------\n\n private validateEnrollmentInput(input: CreateComplianceEnrollmentInput): void {\n if (input.siret === undefined && input.siren === undefined) {\n throw new TaxoraException('Either siret or siren is required.');\n }\n if (input.siret !== undefined && input.siret.length !== 14) {\n throw new TaxoraException('siret must be exactly 14 characters.');\n }\n if (input.siren !== undefined && input.siren.length !== 9) {\n throw new TaxoraException('siren must be exactly 9 characters.');\n }\n if (input.email.trim() === '' || !input.email.includes('@')) {\n throw new TaxoraException('email must be a valid email address.');\n }\n if (!NAF_CODE_REGEX.test(input.nafCode)) {\n throw new TaxoraException('nafCode must be exactly 2 digits, e.g. \"47\".');\n }\n if (!ENTERPRISE_SIZES.includes(input.enterpriseSize)) {\n throw new TaxoraException(\n `Invalid enterpriseSize \"${String(input.enterpriseSize)}\". Expected one of: ${ENTERPRISE_SIZES.join(', ')}.`,\n );\n }\n if (!TYPE_OPERATIONS.includes(input.typeOperation)) {\n throw new TaxoraException(\n `Invalid typeOperation \"${String(input.typeOperation)}\". Expected one of: ${TYPE_OPERATIONS.join(', ')}.`,\n );\n }\n if (input.country !== undefined && input.country.length !== 2) {\n throw new TaxoraException('country must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n if (input.service !== undefined) this.validateService(input.service);\n }\n\n private isNorwayEnrollmentInput(\n input: CreateComplianceEnrollmentInput | CreateNorwayEnrollmentInput,\n ): input is CreateNorwayEnrollmentInput {\n return typeof input.country === 'string' && input.country.trim().toUpperCase() === 'NO';\n }\n\n /** Validates the Norway input and builds its wire body (org number normalized to 9 digits). */\n private buildNorwayEnrollmentBody(input: CreateNorwayEnrollmentInput): Record<string, unknown> {\n if (typeof input.orgNumber !== 'string' || !NorwegianOrgNumber.isValid(input.orgNumber)) {\n throw new TaxoraException(\n 'orgNumber must be a valid 9-digit Norwegian organisation number (mod-11 check digit).',\n );\n }\n for (const field of ['companyName', 'address', 'city', 'postalcode'] as const) {\n if (typeof input[field] !== 'string' || input[field].trim() === '') {\n throw new TaxoraException(`${field} is required for a Norway enrollment.`);\n }\n }\n this.validateEmail(input.email, 'email');\n if (input.service !== undefined) this.validateService(input.service);\n if (input.legalCountry !== undefined && !COUNTRY_REGEX.test(input.legalCountry)) {\n throw new TaxoraException('legalCountry must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n\n const body: Record<string, unknown> = {\n country: 'NO',\n org_number: NorwegianOrgNumber.normalize(input.orgNumber),\n company_name: input.companyName,\n address: input.address,\n city: input.city,\n postalcode: input.postalcode,\n email: input.email,\n };\n if (input.service !== undefined) body['service'] = input.service;\n if (input.regime !== undefined) body['regime'] = input.regime;\n if (input.vatNumber !== undefined) body['vat_number'] = input.vatNumber;\n if (input.province !== undefined) body['province'] = input.province;\n if (input.vatRegistered !== undefined) body['vat_registered'] = input.vatRegistered;\n if (input.enterpriseRegister !== undefined) body['enterprise_register'] = input.enterpriseRegister;\n if (input.reception !== undefined) body['reception'] = input.reception;\n if (input.legalCountry !== undefined) body['legal_country'] = input.legalCountry.toUpperCase();\n if (input.reportingStartDate !== undefined) {\n body['reporting_start_date'] = this.formatDate(input.reportingStartDate);\n }\n if (input.autoActivate !== undefined) body['auto_activate'] = input.autoActivate;\n\n return body;\n }\n\n private async createEnrollmentFromBody(body: Record<string, unknown>): Promise<ComplianceEnrollment> {\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/enrollments`, body);\n const data = await this.parseJsonResponse(response);\n return ComplianceEnrollment.fromArray(data);\n }\n\n private validateService(service: ComplianceRequestService): void {\n if (!SERVICES.includes(service)) {\n throw new TaxoraException(`Invalid service \"${String(service)}\". Expected one of: ${SERVICES.join(', ')}.`);\n }\n }\n\n private validateEmail(email: string | undefined, name: string): void {\n if (typeof email !== 'string' || email.trim() === '' || !email.includes('@')) {\n throw new TaxoraException(`${name} must be a valid email address.`);\n }\n }\n\n /** Lookup routes take a 2-letter country; the API expects it upper-case. */\n private normalizeLookupCountry(country: string): string {\n const normalized = country.trim().toUpperCase();\n if (!COUNTRY_REGEX.test(normalized)) {\n throw new TaxoraException('country must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n return normalized;\n }\n\n private validateId(id: number, name: string): void {\n if (!Number.isInteger(id) || id <= 0) {\n throw new TaxoraException(`${name} must be a positive integer.`);\n }\n }\n\n private validateTransactionType(type: ComplianceTransactionRequestType): void {\n if (!TRANSACTION_TYPES.includes(type)) {\n throw new TaxoraException(\n `Invalid transactionType \"${String(type)}\". Expected one of: ${TRANSACTION_TYPES.join(', ')}.`,\n );\n }\n }\n\n private validateInvoiceNumber(invoiceNumber: string): void {\n if (invoiceNumber.trim() === '') {\n throw new TaxoraException('invoiceNumber must not be empty.');\n }\n if (invoiceNumber.length > 50) {\n throw new TaxoraException('invoiceNumber must not exceed 50 characters.');\n }\n }\n\n private validateInvoiceLines(lines: ComplianceInvoiceLineInput[]): void {\n if (lines.length === 0) {\n throw new TaxoraException('invoiceLines must contain at least one line.');\n }\n lines.forEach((line, index) => {\n if (line.taxes.length === 0) {\n throw new TaxoraException(`invoiceLines[${index}].taxes must contain at least one tax.`);\n }\n });\n }\n\n private validateOptionalCodes(input: { currency?: string; counterpartyCountry?: string }): void {\n if (input.currency !== undefined && input.currency.length !== 3) {\n throw new TaxoraException('currency must be a 3-character ISO 4217 code.');\n }\n if (input.counterpartyCountry !== undefined && input.counterpartyCountry.length !== 2) {\n throw new TaxoraException('counterpartyCountry must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n }\n\n /**\n * Format checks for the buyer/document fields. Country rules (e.g. the Norway\n * org number being required) depend on the enrollment and stay server-side;\n * a register id is only check-digit validated when the buyer is Norwegian.\n */\n private validateBuyerFields(input: ComplianceTransactionBuyerInput & { counterpartyCountry?: string }): void {\n if (input.counterpartyRegisterId !== undefined) {\n if (input.counterpartyRegisterId.length > 30) {\n throw new TaxoraException('counterpartyRegisterId must not exceed 30 characters.');\n }\n if (\n input.counterpartyCountry?.toUpperCase() === 'NO' &&\n !NorwegianOrgNumber.isValid(input.counterpartyRegisterId)\n ) {\n throw new TaxoraException(\n 'counterpartyRegisterId must be a valid 9-digit Norwegian organisation number (mod-11 check digit).',\n );\n }\n }\n if (input.counterpartyEmail !== undefined) this.validateEmail(input.counterpartyEmail, 'counterpartyEmail');\n if (input.buyerReference !== undefined && input.buyerReference.length > 100) {\n throw new TaxoraException('buyerReference must not exceed 100 characters.');\n }\n if (input.amendedNumber !== undefined && input.amendedNumber.length > 50) {\n throw new TaxoraException('amendedNumber must not exceed 50 characters.');\n }\n if (input.extraInfo !== undefined && input.extraInfo.length > 1000) {\n throw new TaxoraException('extraInfo must not exceed 1000 characters.');\n }\n }\n\n // ---------------------------------------------------------------------\n // Body building (camelCase input → snake_case wire format)\n // ---------------------------------------------------------------------\n\n private buildInvoiceLines(lines: ComplianceInvoiceLineInput[]): Record<string, unknown>[] {\n return lines.map((line) => {\n const built: Record<string, unknown> = {\n description: line.description,\n quantity: line.quantity,\n price: line.price,\n taxes_attributes: line.taxes.map((tax) => {\n const taxBuilt: Record<string, unknown> = {\n name: tax.name,\n percent: tax.percent,\n category: tax.category,\n };\n if (tax.comment !== undefined) taxBuilt['comment'] = tax.comment;\n return taxBuilt;\n }),\n };\n if (line.unit !== undefined) built['unit'] = line.unit;\n return built;\n });\n }\n\n /** Applies the optional scalar fields shared by create and update. */\n private applyOptionalTransactionFields(\n body: Record<string, unknown>,\n input: CreateComplianceTransactionInput | UpdateComplianceTransactionInput,\n ): void {\n if (input.dueDate !== undefined) body['due_date'] = this.formatDate(input.dueDate);\n if (input.currency !== undefined) body['currency'] = input.currency;\n if (input.taxAmount !== undefined) body['tax_amount'] = input.taxAmount;\n if (input.counterpartyName !== undefined) body['counterparty_name'] = input.counterpartyName;\n if (input.counterpartyCountry !== undefined) body['counterparty_country'] = input.counterpartyCountry;\n if (input.counterpartyVatNumber !== undefined) body['counterparty_vat_number'] = input.counterpartyVatNumber;\n if (input.providerContactId !== undefined) body['provider_contact_id'] = input.providerContactId;\n if (input.paymentMethod !== undefined) body['payment_method'] = input.paymentMethod;\n if (input.remittanceInformation !== undefined) body['remittance_information'] = input.remittanceInformation;\n if (input.paymentMethodText !== undefined) body['payment_method_text'] = input.paymentMethodText;\n if (input.paymentTerms !== undefined) body['payment_terms'] = input.paymentTerms;\n if (input.counterpartyRegisterId !== undefined) body['counterparty_register_id'] = input.counterpartyRegisterId;\n if (input.counterpartyAddress !== undefined) body['counterparty_address'] = input.counterpartyAddress;\n if (input.counterpartyCity !== undefined) body['counterparty_city'] = input.counterpartyCity;\n if (input.counterpartyPostalcode !== undefined) body['counterparty_postalcode'] = input.counterpartyPostalcode;\n if (input.counterpartyEmail !== undefined) body['counterparty_email'] = input.counterpartyEmail;\n if (input.buyerReference !== undefined) body['buyer_reference'] = input.buyerReference;\n if (input.isCreditNote !== undefined) body['is_credit_note'] = input.isCreditNote;\n if (input.amendedNumber !== undefined) body['amended_number'] = input.amendedNumber;\n if (input.amendedDate !== undefined) body['amended_date'] = this.formatDate(input.amendedDate);\n if (input.extraInfo !== undefined) body['extra_info'] = input.extraInfo;\n }\n\n // ---------------------------------------------------------------------\n // HTTP plumbing (kept in sync with SmartEnrichmentEndpoint)\n // ---------------------------------------------------------------------\n\n private buildHeaders(withJsonContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n 'x-api-key': this.apiKey,\n };\n if (withJsonContentType) {\n headers['Content-Type'] = 'application/json';\n }\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n return headers;\n }\n\n private async sendRequest(method: string, url: string, body?: Record<string, unknown>): Promise<Response> {\n const options: RequestInit = { headers: this.buildHeaders() };\n if (body) options.body = JSON.stringify(body);\n\n const send = (): Promise<Response> => this.httpClient.request(method, url, options);\n\n // GETs are safe to repeat, so transient gateway failures are retried (see\n // RetryPolicy). Writes are not: a gateway timeout does not tell us whether\n // the API already processed them.\n return method === 'GET' ? withResponseRetries(this.retryPolicy, 'e-reporting request', send) : send();\n }\n\n /** Multipart upload: Content-Type is left to fetch so the boundary is set correctly. */\n private async sendMultipartRequest(method: string, url: string, form: FormData): Promise<Response> {\n return this.httpClient.request(method, url, { headers: this.buildHeaders(false), body: form });\n }\n\n /** Accepts any 2xx response (e.g. 201 on create, 200 on idempotent replay). */\n private async parseJsonResponse(response: Response): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw this.buildValidationException(responseText);\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && typeof obj['data'] === 'object' && obj['data'] !== null) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n\n /** For the 204 delete: keeps the shared 422/HTTP error mapping but never parses a body. */\n private async assertNoContentResponse(response: Response): Promise<void> {\n if (response.status === 204) {\n return;\n }\n\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw this.buildValidationException(responseText);\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n }\n\n /**\n * The backend emits two 422 shapes: Laravel FormRequest failures as\n * `{message, errors: {field: [...]}}` and state-guard errors via returnError()\n * as `{error: \"reason\"}`. Preserve the reason in both cases.\n */\n private buildValidationException(responseText: string): ValidationException {\n let message = 'Validation failed';\n let errors: Record<string, string[]> = {};\n\n try {\n const parsed = JSON.parse(responseText) as Record<string, unknown>;\n if (parsed['errors'] !== null && typeof parsed['errors'] === 'object' && !Array.isArray(parsed['errors'])) {\n errors = parsed['errors'] as Record<string, string[]>;\n }\n if (typeof parsed['message'] === 'string' && parsed['message'] !== '') {\n message = parsed['message'];\n } else if (typeof parsed['error'] === 'string' && parsed['error'] !== '') {\n message = parsed['error'];\n }\n } catch {\n // ignore parse errors\n }\n\n return new ValidationException(message, errors, { responseBody: responseText });\n }\n\n /**\n * Date objects are serialized from their LOCAL date parts — construct them as\n * `new Date('2026-09-01T00:00:00')` (local midnight); a bare `new Date('2026-09-01')`\n * is UTC midnight and shifts a day back in UTC-negative timezones.\n */\n private formatDate(date: Date | string): string {\n if (date instanceof Date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n if (!DATE_REGEX.test(date)) {\n throw new TaxoraException(`Invalid date format: \"${date}\". Expected YYYY-MM-DD.`);\n }\n\n return date;\n }\n}\n","/**\n * How hard a Smart Enrichment lookup is allowed to search.\n *\n * `default` searches with one AI provider and consults a second one only when the first finds\n * nothing — one paid search per lookup in the common case.\n *\n * `complex` has two independent AI providers search from the start, and every VAT number either of\n * them proposes is put through the tax authority's checks until one confirms. Noticeably better on\n * hard lookups — companies whose VAT only appears in a website Impressum — and it costs more per\n * lookup, so it is opt-in per request rather than the default.\n */\nexport const SmartEnrichmentMode = {\n DEFAULT: 'default',\n COMPLEX: 'complex',\n} as const;\n\nexport type SmartEnrichmentMode = (typeof SmartEnrichmentMode)[keyof typeof SmartEnrichmentMode];\n\nconst VALUES: readonly string[] = Object.values(SmartEnrichmentMode);\n\n/**\n * Coercion for values coming back from the API. Returns undefined for anything unrecognized —\n * unlike the status enum there is no `unknown` member to fall back to, and inventing a mode would\n * misreport how a lookup actually ran.\n */\nexport function toSmartEnrichmentMode(value: unknown): SmartEnrichmentMode | undefined {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as SmartEnrichmentMode;\n }\n }\n return undefined;\n}\n\nconst DESCRIPTIONS: Record<SmartEnrichmentMode, string> = {\n [SmartEnrichmentMode.DEFAULT]: 'One provider searches; a second is consulted only if it finds nothing.',\n [SmartEnrichmentMode.COMPLEX]:\n 'Two providers search independently and are cross-checked against the tax authority. Costs more.',\n};\n\nexport function describeSmartEnrichmentMode(mode: SmartEnrichmentMode): string {\n return DESCRIPTIONS[mode];\n}\n","export const SmartEnrichmentStatus = {\n FOUND: 'found',\n NO_VAT_EXISTS: 'no_vat_exists',\n NOT_FOUND: 'not_found',\n PROCESSING: 'processing',\n QUEUED: 'queued',\n COMPLETED: 'completed',\n FAILED: 'failed',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type SmartEnrichmentStatus = (typeof SmartEnrichmentStatus)[keyof typeof SmartEnrichmentStatus];\n\nconst VALUES: readonly string[] = Object.values(SmartEnrichmentStatus);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toSmartEnrichmentStatus(value: unknown): SmartEnrichmentStatus {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as SmartEnrichmentStatus;\n }\n }\n return SmartEnrichmentStatus.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<SmartEnrichmentStatus, string> = {\n [SmartEnrichmentStatus.FOUND]: 'A VAT number was resolved and confirmed.',\n [SmartEnrichmentStatus.NO_VAT_EXISTS]: 'The company was identified but has no VAT number.',\n [SmartEnrichmentStatus.NOT_FOUND]: 'No sufficiently-confident match could be resolved.',\n [SmartEnrichmentStatus.PROCESSING]: 'The lookup is still being processed.',\n [SmartEnrichmentStatus.QUEUED]: 'The job is queued.',\n [SmartEnrichmentStatus.COMPLETED]: 'The job has completed.',\n [SmartEnrichmentStatus.FAILED]: 'The job failed.',\n [SmartEnrichmentStatus.UNKNOWN]: 'Unknown status.',\n};\n\nexport function describeSmartEnrichmentStatus(status: SmartEnrichmentStatus): string {\n return DESCRIPTIONS[status];\n}\n","import { type SmartEnrichmentMode, toSmartEnrichmentMode } from '../enums/SmartEnrichmentMode.js';\nimport { type SmartEnrichmentStatus, toSmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\n\n/** What one AI provider independently concluded, when more than one searched. */\nexport interface SmartEnrichmentProviderVerdict {\n provider: string;\n model: string | null;\n status: string;\n vatNumber: string | null;\n confidence: number | null;\n /** False when the model answered from memory instead of an actual web search. */\n grounded: boolean;\n sourceUrl: string | null;\n}\n\n/**\n * What the API made of the address you submitted. The actionable part is `warnings`:\n * `postal_code_city_mismatch` / `postal_code_unassigned` / `postal_code_format_invalid` mean the\n * postal code in your source record is wrong, and `derivedPlace` is where it actually points —\n * worth writing back into your own data.\n */\nexport interface SmartEnrichmentAddressQuality {\n providedPostalCode: string | null;\n providedCity: string | null;\n postalCodeFormatValid: boolean | null;\n postalCodeAssigned: boolean | null;\n /** False when the postal code was excluded from the search because it could not be trusted. */\n postalCodeTrusted: boolean;\n derivedPlace: string | null;\n cityMatchesPostalCode: boolean | null;\n warnings: string[];\n}\n\n/**\n * Result of resolving one reverse-VAT lookup (company name + address → VAT + confidence).\n * Mirrors the API response item shape (camelCase keys).\n */\nexport class SmartEnrichmentResource {\n constructor(\n public readonly status: SmartEnrichmentStatus,\n public readonly vatNumber: string | undefined,\n public readonly vatType: string | undefined,\n public readonly confidence: number | undefined,\n public readonly matchedCompanyName: string | undefined,\n /** Official/registered address of the matched company, when available. */\n public readonly matchedAddress: string | undefined,\n public readonly country: string | undefined,\n public readonly source: string | undefined,\n /** The search mode this lookup actually ran in. */\n public readonly mode: SmartEnrichmentMode | undefined = undefined,\n /**\n * What each AI provider independently concluded. Populated when more than one searched\n * (complex mode, or a fallback). Two entries reporting the same vatNumber is the strongest\n * confirmation this layer produces.\n */\n public readonly providerVerdicts: SmartEnrichmentProviderVerdict[] = [],\n public readonly addressQuality: SmartEnrichmentAddressQuality | undefined = undefined,\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentResource {\n const str = (key: string): string | undefined => {\n const v = data[key];\n return typeof v === 'string' ? v : undefined;\n };\n const num = (key: string): number | undefined => {\n const v = data[key];\n return typeof v === 'number' ? v : undefined;\n };\n\n const verdicts = data['providerVerdicts'];\n const quality = data['addressQuality'];\n\n return new SmartEnrichmentResource(\n toSmartEnrichmentStatus(data['status']),\n str('vatNumber'),\n str('vatType'),\n num('confidence'),\n str('matchedCompanyName'),\n str('matchedAddress'),\n str('country'),\n str('source'),\n toSmartEnrichmentMode(data['mode']),\n Array.isArray(verdicts)\n ? (verdicts.filter((v) => typeof v === 'object' && v !== null) as SmartEnrichmentProviderVerdict[])\n : [],\n typeof quality === 'object' && quality !== null ? (quality as SmartEnrichmentAddressQuality) : undefined,\n );\n }\n\n toArray(): Record<string, unknown> {\n return {\n status: this.status,\n vatNumber: this.vatNumber ?? null,\n vatType: this.vatType ?? null,\n confidence: this.confidence ?? null,\n matchedCompanyName: this.matchedCompanyName ?? null,\n matchedAddress: this.matchedAddress ?? null,\n country: this.country ?? null,\n source: this.source ?? null,\n mode: this.mode ?? null,\n providerVerdicts: this.providerVerdicts,\n addressQuality: this.addressQuality ?? null,\n };\n }\n}\n","import { SmartEnrichmentResource } from './SmartEnrichmentResource.js';\nimport { SmartEnrichmentStatus, toSmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\n\n/**\n * A Smart Enrichment job — single lookup or bulk batch. Unifies the API's sync and async\n * responses: a confident single lookup comes back already resolved (one result, status\n * `found`); everything else comes back `processing` with a `jobId` to poll.\n */\nexport class SmartEnrichmentJob {\n constructor(\n public readonly jobId: string,\n public readonly status: SmartEnrichmentStatus,\n public readonly itemCount: number | undefined,\n public readonly completedCount: number | undefined,\n public readonly foundCount: number | undefined,\n public readonly results: SmartEnrichmentResource[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentJob {\n const num = (key: string): number | undefined => {\n const v = data[key];\n return typeof v === 'number' ? v : undefined;\n };\n\n let results: SmartEnrichmentResource[] = [];\n\n if (Array.isArray(data['results'])) {\n // Bulk job: array of per-item results.\n results = (data['results'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(SmartEnrichmentResource.fromArray);\n } else if (data['vatNumber'] !== undefined || SmartEnrichmentJob.looksLikeItem(data['status'])) {\n // Flat single response — the payload itself is the (only) result.\n results = [SmartEnrichmentResource.fromArray(data)];\n }\n\n return new SmartEnrichmentJob(\n typeof data['jobId'] === 'string' ? data['jobId'] : '',\n toSmartEnrichmentStatus(data['status']),\n num('itemCount'),\n num('completedCount'),\n num('foundCount'),\n results,\n );\n }\n\n isProcessing(): boolean {\n return this.status === SmartEnrichmentStatus.PROCESSING || this.status === SmartEnrichmentStatus.QUEUED;\n }\n\n /** Convenience for single lookups: the first (or only) result, if any. */\n result(): SmartEnrichmentResource | undefined {\n return this.results[0];\n }\n\n private static looksLikeItem(status: unknown): boolean {\n const s = toSmartEnrichmentStatus(status);\n return (\n s === SmartEnrichmentStatus.FOUND ||\n s === SmartEnrichmentStatus.NO_VAT_EXISTS ||\n s === SmartEnrichmentStatus.NOT_FOUND\n );\n }\n}\n","import { SmartEnrichmentResource } from './SmartEnrichmentResource.js';\nimport { type SmartEnrichmentStatus, toSmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\n\n/**\n * Full first input of a history row (incl. street + postalCode) — everything that was\n * queried, so a detail view needs no second fetch. `query` stays the compact summary.\n */\nexport interface SmartEnrichmentHistoryInput {\n companyName: string | undefined;\n street: string | undefined;\n postalCode: string | undefined;\n city: string | undefined;\n country: string | undefined;\n}\n\n/**\n * One row of Smart Enrichment lookup history (compact summary; full detail via getJob).\n */\nexport class SmartEnrichmentHistoryRow {\n constructor(\n public readonly jobId: string,\n public readonly status: SmartEnrichmentStatus,\n public readonly isBulk: boolean,\n public readonly itemCount: number,\n public readonly foundCount: number,\n public readonly queryCompanyName: string | undefined,\n public readonly queryCountry: string | undefined,\n public readonly queryCity: string | undefined,\n public readonly input: SmartEnrichmentHistoryInput | undefined,\n public readonly result: SmartEnrichmentResource | undefined,\n public readonly createdAt: string | undefined,\n public readonly finishedAt: string | undefined,\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentHistoryRow {\n const str = (value: unknown): string | undefined => (typeof value === 'string' ? value : undefined);\n const query =\n data['query'] !== null && typeof data['query'] === 'object' && !Array.isArray(data['query'])\n ? (data['query'] as Record<string, unknown>)\n : {};\n const inputRaw =\n data['input'] !== null && typeof data['input'] === 'object' && !Array.isArray(data['input'])\n ? (data['input'] as Record<string, unknown>)\n : undefined;\n const input: SmartEnrichmentHistoryInput | undefined = inputRaw\n ? {\n companyName: str(inputRaw['companyName']),\n street: str(inputRaw['street']),\n postalCode: str(inputRaw['postalCode']),\n city: str(inputRaw['city']),\n country: str(inputRaw['country']),\n }\n : undefined;\n const result =\n data['result'] !== null && typeof data['result'] === 'object' && !Array.isArray(data['result'])\n ? SmartEnrichmentResource.fromArray(data['result'] as Record<string, unknown>)\n : undefined;\n\n return new SmartEnrichmentHistoryRow(\n str(data['jobId']) ?? '',\n toSmartEnrichmentStatus(data['status']),\n data['isBulk'] === true,\n typeof data['itemCount'] === 'number' ? data['itemCount'] : 0,\n typeof data['foundCount'] === 'number' ? data['foundCount'] : 0,\n str(query['companyName']),\n str(query['country']),\n str(query['city']),\n input,\n result,\n str(data['createdAt']),\n str(data['finishedAt']),\n );\n }\n}\n","import { SmartEnrichmentHistoryRow } from './SmartEnrichmentHistoryRow.js';\n\n/**\n * Account-wide history tiles — stable regardless of the current search/page filter.\n */\nexport interface SmartEnrichmentHistoryStats {\n total: number;\n found: number;\n}\n\n/**\n * A paginated page of Smart Enrichment lookup history.\n */\nexport class SmartEnrichmentHistoryPage implements Iterable<SmartEnrichmentHistoryRow> {\n constructor(\n public readonly rows: SmartEnrichmentHistoryRow[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n public readonly stats?: SmartEnrichmentHistoryStats,\n ) {}\n\n static fromResponse(payload: unknown): SmartEnrichmentHistoryPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(SmartEnrichmentHistoryRow.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n const statsRaw =\n obj['stats'] !== null && typeof obj['stats'] === 'object' && !Array.isArray(obj['stats'])\n ? (obj['stats'] as Record<string, unknown>)\n : undefined;\n const stats: SmartEnrichmentHistoryStats | undefined = statsRaw\n ? { total: num(statsRaw['total'], 0), found: num(statsRaw['found'], 0) }\n : undefined;\n\n return new SmartEnrichmentHistoryPage(\n rows,\n num(meta['currentPage'], 1),\n num(meta['perPage'], rows.length),\n num(meta['total'], rows.length),\n num(meta['lastPage'], 1),\n stats,\n );\n }\n\n [Symbol.iterator](): Iterator<SmartEnrichmentHistoryRow> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","/**\n * DTOs for the Smart Enrichment statistics endpoint\n * (GET /smart-enrichment/statistics).\n *\n * Read-only aggregation over the company's lookups: headline totals, a time\n * series and breakdowns by source, outcome and confidence band. The API\n * defaults to the last 12 months and a monthly interval.\n */\n\n/** Time-series bucket size accepted by the statistics endpoint. */\nexport type SmartEnrichmentStatisticsInterval = 'day' | 'week' | 'month';\n\nexport interface SmartEnrichmentStatisticsRange {\n dateFrom: string;\n dateTo: string;\n interval: string;\n}\n\nexport interface SmartEnrichmentStatisticsTotals {\n jobs: number;\n items: number;\n found: number;\n /** Share of items that resolved to a VAT number, 0–100. */\n foundRate: number;\n /** Average confidence of found items, 0–100. */\n avgConfidence: number;\n}\n\nexport interface SmartEnrichmentTimeBucket {\n /** Period key: \"2026-01-15\" (day), \"2026-03\" (ISO year-week) or \"2026-01\" (month). */\n bucket: string;\n jobs: number;\n items: number;\n found: number;\n}\n\nexport interface SmartEnrichmentSourceBreakdown {\n source: string;\n jobs: number;\n found: number;\n}\n\nexport interface SmartEnrichmentOutcomeBreakdown {\n outcome: string;\n count: number;\n}\n\nexport interface SmartEnrichmentConfidenceBucket {\n /** Confidence band: \"high\", \"medium\" or \"low\". */\n bucket: string;\n count: number;\n}\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\nfunction asRecords(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null);\n}\n\nexport class SmartEnrichmentStatistics {\n constructor(\n public readonly range: SmartEnrichmentStatisticsRange,\n public readonly totals: SmartEnrichmentStatisticsTotals,\n public readonly timeSeries: SmartEnrichmentTimeBucket[],\n public readonly bySource: SmartEnrichmentSourceBreakdown[],\n public readonly byOutcome: SmartEnrichmentOutcomeBreakdown[],\n public readonly confidenceBuckets: SmartEnrichmentConfidenceBucket[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentStatistics {\n const range = asRecord(data['range']);\n const totals = asRecord(data['totals']);\n\n const timeSeries: SmartEnrichmentTimeBucket[] = asRecords(data['time_series']).map((row) => ({\n bucket: asString(row['bucket']),\n jobs: asNumber(row['jobs']),\n items: asNumber(row['items']),\n found: asNumber(row['found']),\n }));\n\n const bySource: SmartEnrichmentSourceBreakdown[] = asRecords(data['by_source']).map((row) => ({\n source: asString(row['source']),\n jobs: asNumber(row['jobs']),\n found: asNumber(row['found']),\n }));\n\n const byOutcome: SmartEnrichmentOutcomeBreakdown[] = asRecords(data['by_outcome']).map((row) => ({\n outcome: asString(row['outcome']),\n count: asNumber(row['count']),\n }));\n\n const confidenceBuckets: SmartEnrichmentConfidenceBucket[] = asRecords(data['confidence_buckets']).map((row) => ({\n bucket: asString(row['bucket']),\n count: asNumber(row['count']),\n }));\n\n return new SmartEnrichmentStatistics(\n {\n dateFrom: asString(range['date_from']),\n dateTo: asString(range['date_to']),\n interval: asString(range['interval']),\n },\n {\n jobs: asNumber(totals['jobs']),\n items: asNumber(totals['items']),\n found: asNumber(totals['found']),\n foundRate: asNumber(totals['found_rate']),\n avgConfidence: asNumber(totals['avg_confidence']),\n },\n timeSeries,\n bySource,\n byOutcome,\n confidenceBuckets,\n );\n }\n}\n","import { type SmartEnrichmentMode } from '../enums/SmartEnrichmentMode.js';\nimport { SmartEnrichmentJob } from '../dto/SmartEnrichmentJob.js';\nimport { SmartEnrichmentHistoryPage } from '../dto/SmartEnrichmentHistoryPage.js';\nimport { SmartEnrichmentStatistics, type SmartEnrichmentStatisticsInterval } from '../dto/SmartEnrichmentStatistics.js';\nimport { type SmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError, jsonErrorMessage } from '../exceptions/apiErrorMessage.js';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport { ValidationException } from '../exceptions/ValidationException.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withResponseRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nconst STATISTICS_INTERVALS: readonly SmartEnrichmentStatisticsInterval[] = ['day', 'week', 'month'];\n\nconst DEFAULT_POLL_INTERVAL_MS = 2000;\nconst DEFAULT_POLL_TIMEOUT_MS = 120_000;\n\nexport interface SmartEnrichmentInput {\n companyName: string;\n country: string;\n street?: string;\n postalCode?: string;\n city?: string;\n /**\n * Search depth. Omit to use the server default (`default`). `complex` searches with two\n * independent providers and cross-checks them — better hit rate, higher cost per lookup.\n */\n mode?: SmartEnrichmentMode;\n}\n\n/** One recent monthly billing entry, exposed on the usage response for transparency. */\nexport interface SmartEnrichmentUsageHistoryEntry {\n /** Billing period, e.g. \"2026-05\". */\n period: string;\n matches: number;\n /** Amount due for the period as a decimal string, e.g. \"9.60\". */\n amount: string;\n state: 'billed' | 'pending';\n billingType: string | null;\n manualReference: string | null;\n}\n\nexport interface SmartEnrichmentUsage {\n period: string;\n used: number;\n included: number;\n remaining: number;\n overageCount: number;\n overagePrice: number;\n overageAmount: number;\n hardCap: number | null;\n /** Recent monthly billing entries; empty when the API sends none. */\n history: SmartEnrichmentUsageHistoryEntry[];\n}\n\nexport interface SmartEnrichmentExportOptions {\n /** Inclusive lower bound on the job's creation date (YYYY-MM-DD). */\n dateFrom?: string;\n /** Inclusive upper bound on the job's creation date (YYYY-MM-DD). */\n dateTo?: string;\n /** Only include rows with at least this result confidence (0–100). */\n minConfidence?: number;\n /** Only include rows with one of these item statuses (found, no_vat_exists, not_found). */\n status?: SmartEnrichmentStatus[];\n /** Only include rows that resolved to a VAT number. */\n onlyFound?: boolean;\n}\n\nexport interface SmartEnrichmentStatisticsOptions {\n /** Inclusive lower bound (YYYY-MM-DD). Defaults to 12 months ago (server-side). */\n dateFrom?: string;\n /** Inclusive upper bound (YYYY-MM-DD). Defaults to today (server-side). */\n dateTo?: string;\n /** Time-series bucket size. Defaults to \"month\" server-side. */\n interval?: SmartEnrichmentStatisticsInterval;\n}\n\nexport interface SmartEnrichmentWaitOptions {\n /** Delay between polls in milliseconds. Defaults to 2000. */\n pollIntervalMs?: number;\n /** Maximum total time to wait in milliseconds. Defaults to 120000. */\n timeoutMs?: number;\n}\n\n/**\n * Smart Enrichment — reverse VAT lookup (company name + address + country → VAT + confidence).\n *\n * let job = await client.smartEnrichment.lookup({ companyName: 'Example GmbH', country: 'AT' });\n * if (job.isProcessing()) job = await client.smartEnrichment.waitForCompletion(job.jobId);\n * console.log(job.result()?.vatNumber);\n */\nexport class SmartEnrichmentEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n /**\n * Single reverse lookup. Returns a confident result synchronously, or a `processing`\n * job (poll with get(job.jobId) or waitForCompletion(job.jobId)) when deeper resolution\n * is needed.\n */\n async lookup(input: SmartEnrichmentInput): Promise<SmartEnrichmentJob> {\n this.validateInput(input);\n\n const body: Record<string, unknown> = {\n companyName: input.companyName,\n country: input.country,\n };\n if (input.street !== undefined) body['street'] = input.street;\n if (input.postalCode !== undefined) body['postalCode'] = input.postalCode;\n if (input.city !== undefined) body['city'] = input.city;\n if (input.mode !== undefined) body['mode'] = input.mode;\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/smart-enrichment`, body);\n const data = await this.parseJsonResponse(response, [200, 202]);\n return SmartEnrichmentJob.fromArray(data);\n }\n\n /**\n * Bulk batch — always async. Returns a `processing` job; results arrive via the\n * `enrichment.completed` webhook and are retrievable via get(job.jobId).\n *\n * @param mode Search depth for every row in the batch. A row carrying its own `mode` overrides\n * it, so a caller can pay for `complex` on just the rows that need it.\n */\n async bulkLookup(items: SmartEnrichmentInput[], mode?: SmartEnrichmentMode): Promise<SmartEnrichmentJob> {\n if (items.length === 0) {\n throw new TaxoraException('bulkLookup requires at least one item.');\n }\n items.forEach((item, index) => this.validateInput(item, `items[${index}]`));\n\n const body: Record<string, unknown> = { items };\n if (mode !== undefined) body['mode'] = mode;\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/smart-enrichment/bulk`, body);\n const data = await this.parseJsonResponse(response, [200, 202]);\n return SmartEnrichmentJob.fromArray(data);\n }\n\n /** Poll a job (single or bulk) by its id. */\n async get(jobId: string): Promise<SmartEnrichmentJob> {\n this.validateJobId(jobId);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/smart-enrichment/${encodeURIComponent(jobId)}`);\n const data = await this.parseJsonResponse(response);\n return SmartEnrichmentJob.fromArray(data);\n }\n\n /**\n * Poll get(jobId) until the job is no longer processing (completed, failed or resolved).\n * Throws a TaxoraException when the job does not finish within `timeoutMs`.\n */\n async waitForCompletion(jobId: string, options: SmartEnrichmentWaitOptions = {}): Promise<SmartEnrichmentJob> {\n this.validateJobId(jobId);\n\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const timeoutMs = options.timeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n if (!Number.isFinite(pollIntervalMs) || pollIntervalMs <= 0) {\n throw new TaxoraException('pollIntervalMs must be greater than 0.');\n }\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new TaxoraException('timeoutMs must be greater than 0.');\n }\n\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const job = await this.get(jobId);\n if (!job.isProcessing()) {\n return job;\n }\n if (Date.now() + pollIntervalMs > deadline) {\n throw new TaxoraException(`Smart Enrichment job \"${jobId}\" did not complete within ${timeoutMs}ms.`, {\n jobId,\n timeoutMs,\n });\n }\n await new Promise<void>((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n }\n\n /**\n * Paginated lookup history (newest first). `perPage` is capped at 100 server-side.\n * `search` filters (free-text) over the queried company name and the resolved\n * VAT number / matched company name.\n */\n async history(page = 1, perPage = 25, search?: string): Promise<SmartEnrichmentHistoryPage> {\n const params = new URLSearchParams();\n params.set('page', String(page));\n params.set('perPage', String(perPage));\n if (search !== undefined) params.set('search', search);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/smart-enrichment/history?${params.toString()}`);\n // The history response is { data: [...], meta: {...}, stats: {...} }; parse it whole\n // rather than unwrapping `data` (which would drop the pagination meta).\n return SmartEnrichmentHistoryPage.fromResponse(await this.parseRawJson(response));\n }\n\n /** Current billing-period quota usage, plus recent monthly billing entries. */\n async usage(): Promise<SmartEnrichmentUsage> {\n const response = await this.sendRequest('GET', `${this.baseUrl}/smart-enrichment/usage`);\n const data = await this.parseJsonResponse(response);\n return {\n period: typeof data['period'] === 'string' ? data['period'] : '',\n used: typeof data['used'] === 'number' ? data['used'] : 0,\n included: typeof data['included'] === 'number' ? data['included'] : 0,\n remaining: typeof data['remaining'] === 'number' ? data['remaining'] : 0,\n overageCount: typeof data['overageCount'] === 'number' ? data['overageCount'] : 0,\n overagePrice: typeof data['overagePrice'] === 'number' ? data['overagePrice'] : 0,\n overageAmount: typeof data['overageAmount'] === 'number' ? data['overageAmount'] : 0,\n hardCap: typeof data['hardCap'] === 'number' ? data['hardCap'] : null,\n history: this.parseUsageHistory(data['history']),\n };\n }\n\n /**\n * Export the company's lookups as CSV (bulk-input shape plus the resolved VAT columns;\n * bulk jobs are flattened to one line per input row). Returns the raw CSV text\n * (UTF-8, BOM included by the API so Excel opens umlauts correctly).\n */\n async export(options: SmartEnrichmentExportOptions = {}): Promise<string> {\n const params = new URLSearchParams();\n if (options.dateFrom !== undefined) params.set('date_from', options.dateFrom);\n if (options.dateTo !== undefined) params.set('date_to', options.dateTo);\n if (options.minConfidence !== undefined) params.set('min_confidence', String(options.minConfidence));\n for (const status of options.status ?? []) {\n params.append('status[]', status);\n }\n if (options.onlyFound !== undefined) params.set('only_found', options.onlyFound ? '1' : '0');\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/smart-enrichment/export${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n return this.parseCsvResponse(response);\n }\n\n /**\n * Aggregated lookup statistics: headline totals, a time series and breakdowns by\n * source, outcome and confidence band. The API defaults to the last 12 months\n * and a monthly interval.\n */\n async statistics(options: SmartEnrichmentStatisticsOptions = {}): Promise<SmartEnrichmentStatistics> {\n if (options.interval !== undefined && !STATISTICS_INTERVALS.includes(options.interval)) {\n throw new TaxoraException(\n `Invalid statistics interval \"${String(options.interval)}\". Expected one of: ${STATISTICS_INTERVALS.join(', ')}.`,\n );\n }\n\n const params = new URLSearchParams();\n if (options.dateFrom !== undefined) params.set('date_from', options.dateFrom);\n if (options.dateTo !== undefined) params.set('date_to', options.dateTo);\n if (options.interval !== undefined) params.set('interval', options.interval);\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/smart-enrichment/statistics${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n // The statistics payload is a whole object (range/totals/breakdowns) — no `data` envelope.\n return SmartEnrichmentStatistics.fromArray(await this.parseRawJson(response));\n }\n\n // ---------------------------------------------------------------------\n // Input validation (fail fast, before any request is sent)\n // ---------------------------------------------------------------------\n\n private validateInput(input: SmartEnrichmentInput, context?: string): void {\n const where = context ? ` (${context})` : '';\n if (input.companyName.trim() === '') {\n throw new TaxoraException(`companyName must not be empty${where}.`);\n }\n if (input.country.length !== 2) {\n throw new TaxoraException(`country must be a 2-character ISO 3166-1 alpha-2 code${where}.`);\n }\n }\n\n private validateJobId(jobId: string): void {\n if (jobId.trim() === '') {\n throw new TaxoraException('jobId must not be empty.');\n }\n }\n\n // ---------------------------------------------------------------------\n // HTTP plumbing (kept in sync with VatEndpoint)\n // ---------------------------------------------------------------------\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n return headers;\n }\n\n private async sendRequest(method: string, url: string, body?: Record<string, unknown>): Promise<Response> {\n const options: RequestInit = { headers: this.buildHeaders() };\n if (body) options.body = JSON.stringify(body);\n\n const send = (): Promise<Response> => this.httpClient.request(method, url, options);\n\n // GETs are safe to repeat, so transient gateway failures are retried (see\n // RetryPolicy). Writes are not: a gateway timeout does not tell us whether\n // the API already processed them.\n return method === 'GET' ? withResponseRetries(this.retryPolicy, 'Smart Enrichment request', send) : send();\n }\n\n private async parseJsonResponse(\n response: Response,\n acceptedStatuses: number[] = [200],\n ): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw new ValidationException(\n jsonErrorMessage(responseText) ?? 'Validation failed',\n this.parseValidationErrors(responseText),\n );\n }\n\n if (!response.ok && !acceptedStatuses.includes(response.status)) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && (typeof obj['data'] === 'object' || Array.isArray(obj['data']))) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n\n /**\n * Like parseJsonResponse but returns the whole object WITHOUT unwrapping `data` — used for\n * the paginated history response (where `data` is the row array and `meta`/`stats` must be\n * preserved) and the statistics response.\n */\n private async parseRawJson(response: Response): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw new ValidationException(\n jsonErrorMessage(responseText) ?? 'Validation failed',\n this.parseValidationErrors(responseText),\n );\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n return parsed as Record<string, unknown>;\n }\n\n /**\n * For the CSV export: keeps the shared 422/HTTP error mapping but returns the body\n * verbatim (text/csv) instead of parsing JSON.\n */\n private async parseCsvResponse(response: Response): Promise<string> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw new ValidationException(\n jsonErrorMessage(responseText) ?? 'Validation failed',\n this.parseValidationErrors(responseText),\n );\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n return responseText;\n }\n\n private parseValidationErrors(responseText: string): Record<string, string[]> {\n try {\n const parsed = JSON.parse(responseText) as Record<string, unknown>;\n if (parsed['errors'] !== null && typeof parsed['errors'] === 'object' && !Array.isArray(parsed['errors'])) {\n return parsed['errors'] as Record<string, string[]>;\n }\n } catch {\n // ignore parse errors\n }\n return {};\n }\n\n private parseUsageHistory(value: unknown): SmartEnrichmentUsageHistoryEntry[] {\n if (!Array.isArray(value)) return [];\n\n return value\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map((row) => ({\n period: typeof row['period'] === 'string' ? row['period'] : '',\n matches: typeof row['matches'] === 'number' ? row['matches'] : 0,\n amount: typeof row['amount'] === 'string' ? row['amount'] : '0.00',\n state: row['state'] === 'billed' ? ('billed' as const) : ('pending' as const),\n billingType: typeof row['billingType'] === 'string' ? row['billingType'] : null,\n manualReference: typeof row['manualReference'] === 'string' ? row['manualReference'] : null,\n }));\n }\n}\n","export const VatState = {\n VALID: 'valid',\n INVALID: 'invalid',\n FRAUD: 'fraud',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type VatState = (typeof VatState)[keyof typeof VatState];\n\nexport function getFailedVatStates(): VatState[] {\n return [VatState.INVALID, VatState.FRAUD];\n}\n\nconst DESCRIPTIONS: Record<VatState, string> = {\n [VatState.VALID]: 'The VAT number is valid and active.',\n [VatState.INVALID]: 'The VAT number is invalid or not registered.',\n [VatState.FRAUD]: 'The VAT number has been flagged as potentially fraudulent.',\n [VatState.UNKNOWN]: 'The VAT number state could not be determined.',\n};\n\nexport function describeVatState(state: VatState): string {\n return DESCRIPTIONS[state];\n}\n","interface CompanyAddressProps {\n fullAddress?: string | null;\n name?: string | null;\n street?: string | null;\n postalCode?: string | null;\n city?: string | null;\n state?: string | null;\n country?: string | null;\n raw?: string | null;\n}\n\nexport class CompanyAddress {\n public readonly fullAddress: string | null;\n public readonly name: string | null;\n public readonly street: string | null;\n public readonly postalCode: string | null;\n public readonly city: string | null;\n public readonly state: string | null;\n public readonly country: string | null;\n public readonly raw: string | null;\n\n constructor(props: CompanyAddressProps) {\n this.name = props.name ?? null;\n this.street = props.street ?? null;\n this.postalCode = props.postalCode ?? null;\n this.city = props.city ?? null;\n this.state = props.state ?? null;\n this.country = props.country ?? null;\n this.raw = props.raw ?? null;\n this.fullAddress = props.fullAddress ?? this.assembleFullAddress();\n }\n\n private assembleFullAddress(): string | null {\n const parts = [this.street, this.postalCode, this.city, this.country].filter(Boolean);\n return parts.length > 0 ? parts.join(', ') : null;\n }\n\n static from(value: unknown): CompanyAddress | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return CompanyAddress.fromArray(parsed as Record<string, unknown>, trimmed);\n }\n } catch {\n // Not valid JSON — treat as plain string\n }\n return new CompanyAddress({ raw: trimmed });\n }\n\n if (typeof value === 'object' && !Array.isArray(value)) {\n return CompanyAddress.fromArray(value as Record<string, unknown>, null);\n }\n\n return null;\n }\n\n static fromArray(data: Record<string, unknown>, raw: string | null): CompanyAddress {\n const get = (key: string): string | null => {\n const val = data[key] ?? data[key.replace(/_/g, '-')];\n return typeof val === 'string' && val.trim() ? val.trim() : null;\n };\n\n return new CompanyAddress({\n fullAddress: get('full_address'),\n name: get('name'),\n street: get('street'),\n postalCode: get('postal_code') ?? get('postalCode'),\n city: get('city'),\n state: get('state'),\n country: get('country'),\n raw,\n });\n }\n\n toArray(): Record<string, string | null> {\n return {\n full_address: this.fullAddress,\n name: this.name,\n street: this.street,\n postal_code: this.postalCode,\n city: this.city,\n state: this.state,\n country: this.country,\n };\n }\n\n toString(): string {\n return this.fullAddress ?? this.raw ?? '';\n }\n}\n","export class ScoreBreakdown {\n constructor(\n public readonly stepName: string,\n public readonly scoreContribution: number,\n public readonly metadata: Record<string, unknown>,\n ) {}\n\n static fromArray(data: Record<string, unknown>): ScoreBreakdown {\n return new ScoreBreakdown(\n typeof data['step_name'] === 'string' ? data['step_name'] : '',\n typeof data['score_contribution'] === 'number' ? data['score_contribution'] : 0,\n data['metadata'] !== null && typeof data['metadata'] === 'object' && !Array.isArray(data['metadata'])\n ? (data['metadata'] as Record<string, unknown>)\n : {},\n );\n }\n\n toArray(): { step_name: string; score_contribution: number; metadata: Record<string, unknown> } {\n return {\n step_name: this.stepName,\n score_contribution: this.scoreContribution,\n metadata: this.metadata,\n };\n }\n}\n","export class ProviderDocumentLine {\n constructor(\n public readonly id: number | null,\n public readonly vatUid: string | null,\n public readonly rowNumber: number | null,\n public readonly entryIdentifier: string | null,\n public readonly reference: string | null,\n public readonly meta: Record<string, unknown>,\n ) {}\n\n static fromArray(data: unknown): ProviderDocumentLine | null {\n if (data === null || data === undefined || typeof data !== 'object' || Array.isArray(data)) {\n return null;\n }\n const d = data as Record<string, unknown>;\n\n return new ProviderDocumentLine(\n typeof d['id'] === 'number' ? d['id'] : null,\n typeof d['vat_uid'] === 'string' ? d['vat_uid'] : null,\n typeof d['row_number'] === 'number' ? d['row_number'] : null,\n typeof d['entry_identifier'] === 'string' ? d['entry_identifier'] : null,\n typeof d['reference'] === 'string' ? d['reference'] : null,\n d['meta'] !== null && typeof d['meta'] === 'object' && !Array.isArray(d['meta'])\n ? (d['meta'] as Record<string, unknown>)\n : {},\n );\n }\n\n toArray(): Record<string, unknown> {\n return {\n id: this.id,\n vat_uid: this.vatUid,\n row_number: this.rowNumber,\n entry_identifier: this.entryIdentifier,\n reference: this.reference,\n meta: this.meta,\n };\n }\n}\n","import { ProviderDocumentLine } from './ProviderDocumentLine.js';\n\nexport class ProviderDocument {\n constructor(\n public readonly id: number | null,\n public readonly provider: string | null,\n public readonly documentType: string | null,\n public readonly state: string | null,\n public readonly documentDate: Date | null,\n public readonly mime: string | null,\n public readonly size: number | null,\n public readonly hash: string | null,\n public readonly meta: Record<string, unknown>,\n public readonly line: ProviderDocumentLine | null,\n ) {}\n\n static fromArray(data: unknown): ProviderDocument | null {\n if (data === null || data === undefined || typeof data !== 'object' || Array.isArray(data)) {\n return null;\n }\n const d = data as Record<string, unknown>;\n\n const documentDate =\n typeof d['document_date'] === 'string' && d['document_date'] ? new Date(d['document_date']) : null;\n\n return new ProviderDocument(\n typeof d['id'] === 'number' ? d['id'] : null,\n typeof d['provider'] === 'string' ? d['provider'] : null,\n typeof d['document_type'] === 'string' ? d['document_type'] : null,\n typeof d['state'] === 'string' ? d['state'] : null,\n documentDate,\n typeof d['mime'] === 'string' ? d['mime'] : null,\n typeof d['size'] === 'number' ? d['size'] : null,\n typeof d['hash'] === 'string' ? d['hash'] : null,\n d['meta'] !== null && typeof d['meta'] === 'object' && !Array.isArray(d['meta'])\n ? (d['meta'] as Record<string, unknown>)\n : {},\n ProviderDocumentLine.fromArray(d['line']),\n );\n }\n\n toArray(): Record<string, unknown> {\n return {\n id: this.id,\n provider: this.provider,\n document_type: this.documentType,\n state: this.state,\n document_date: this.documentDate?.toISOString() ?? null,\n mime: this.mime,\n size: this.size,\n hash: this.hash,\n meta: this.meta,\n line: this.line?.toArray() ?? null,\n };\n }\n}\n","import { VatState } from '../enums/VatState.js';\nimport { CompanyAddress } from './CompanyAddress.js';\nimport { ScoreBreakdown } from './ScoreBreakdown.js';\nimport { ProviderDocument } from './ProviderDocument.js';\n\nexport class VatResource {\n constructor(\n public readonly uuid: string | undefined,\n public readonly vatUid: string | undefined,\n public readonly state: VatState | undefined,\n public readonly countryCode: string | undefined,\n public readonly companyName: string | undefined,\n public readonly companyAddress: CompanyAddress | undefined,\n public readonly requestedCompanyName: string | undefined,\n public readonly requestedCompanyNameOriginal: string | undefined,\n public readonly requestedInputAddress: Record<string, string | null> | undefined,\n public readonly checkedAt: Date | undefined,\n public readonly score: number | undefined,\n public readonly scoreSource: string | undefined,\n public readonly scoreAttempts: Array<{ source?: string; score?: number }> | undefined,\n public readonly breakdown: ScoreBreakdown[] | undefined,\n public readonly environment: string | undefined,\n public readonly provider: string | undefined,\n public readonly usedProviders: string[] | undefined,\n public readonly providerValid: boolean | null | undefined,\n public readonly providerVatState: string | undefined,\n public readonly providerNote: string | undefined,\n public readonly providerLastCheckedAt: Date | undefined,\n public readonly hasApiError: boolean | null | undefined,\n public readonly errorMessage: string | null | undefined,\n public readonly nextApiRecheckAt: string | null | undefined,\n public readonly providerDocument: ProviderDocument | undefined,\n ) {}\n\n static fromArray(data: Record<string, unknown>): VatResource {\n const str = (key: string): string | undefined => {\n const v = data[key];\n return typeof v === 'string' ? v : undefined;\n };\n\n const stateRaw = str('state');\n const state =\n stateRaw !== undefined && Object.values(VatState).includes(stateRaw as VatState)\n ? (stateRaw as VatState)\n : undefined;\n\n const checkedAt = str('checked_at') ? new Date(data['checked_at'] as string) : undefined;\n const providerLastCheckedAt = str('provider_last_checked_at')\n ? new Date(data['provider_last_checked_at'] as string)\n : undefined;\n const hasApiError =\n data['has_api_error'] === null\n ? null\n : typeof data['has_api_error'] === 'boolean'\n ? data['has_api_error']\n : undefined;\n const errorMessage =\n data['error_message'] === null\n ? null\n : typeof data['error_message'] === 'string'\n ? data['error_message']\n : undefined;\n const nextApiRecheckAt =\n data['next_api_recheck_at'] === null\n ? null\n : typeof data['next_api_recheck_at'] === 'string'\n ? data['next_api_recheck_at']\n : undefined;\n const providerValid =\n data['provider_valid'] === null\n ? null\n : typeof data['provider_valid'] === 'boolean'\n ? data['provider_valid']\n : undefined;\n\n const breakdown = Array.isArray(data['breakdown'])\n ? (data['breakdown'] as Record<string, unknown>[]).map(ScoreBreakdown.fromArray)\n : undefined;\n\n const usedProviders = Array.isArray(data['used_providers'])\n ? (data['used_providers'] as unknown[]).filter((v): v is string => typeof v === 'string')\n : undefined;\n\n const scoreAttempts = Array.isArray(data['score_attempts'])\n ? (data['score_attempts'] as Record<string, unknown>[])\n : undefined;\n\n const requestedInputAddress =\n data['requested_input_address'] !== null &&\n typeof data['requested_input_address'] === 'object' &&\n !Array.isArray(data['requested_input_address'])\n ? (data['requested_input_address'] as Record<string, string | null>)\n : undefined;\n\n return new VatResource(\n str('uuid'),\n str('vat_uid'),\n state,\n str('country_code'),\n str('company_name'),\n CompanyAddress.from(data['company_address']) ?? undefined,\n str('requested_company_name'),\n str('requested_company_name_original'),\n requestedInputAddress,\n checkedAt,\n typeof data['score'] === 'number' ? data['score'] : undefined,\n str('score_source'),\n scoreAttempts,\n breakdown,\n str('environment'),\n str('provider'),\n usedProviders,\n providerValid,\n str('provider_vat_state'),\n str('provider_note'),\n providerLastCheckedAt,\n hasApiError,\n errorMessage,\n nextApiRecheckAt,\n ProviderDocument.fromArray(data['provider_document']) ?? undefined,\n );\n }\n\n getBackendLink(): string | null {\n if (!this.uuid) return null;\n if (this.environment === 'LIVE') {\n return `https://app.taxora.io/vat/history/${this.uuid}`;\n }\n return `https://app.sandbox.taxora.io/vat/history/${this.uuid}`;\n }\n\n isValid(useProviderState = false): boolean {\n if (useProviderState) {\n return this.isProviderValid();\n }\n\n return this.state === VatState.VALID;\n }\n\n isProviderValid(): boolean {\n if (this.providerValid !== undefined && this.providerValid !== null) {\n return this.providerValid;\n }\n\n return this.providerVatState === VatState.VALID;\n }\n\n toArray(): Record<string, unknown> {\n return {\n uuid: this.uuid,\n vat_uid: this.vatUid,\n state: this.state,\n country_code: this.countryCode,\n company_name: this.companyName,\n company_address: this.companyAddress?.toArray() ?? null,\n requested_company_name: this.requestedCompanyName,\n requested_company_name_original: this.requestedCompanyNameOriginal,\n requested_input_address: this.requestedInputAddress ?? null,\n checked_at: this.checkedAt?.toISOString() ?? null,\n score: this.score ?? null,\n score_source: this.scoreSource ?? null,\n score_attempts: this.scoreAttempts ?? null,\n breakdown: this.breakdown?.map((b) => b.toArray()) ?? null,\n environment: this.environment ?? null,\n provider: this.provider ?? null,\n used_providers: this.usedProviders ?? null,\n provider_valid: this.providerValid ?? null,\n provider_vat_state: this.providerVatState ?? null,\n provider_note: this.providerNote ?? null,\n provider_last_checked_at: this.providerLastCheckedAt?.toISOString() ?? null,\n has_api_error: this.hasApiError ?? null,\n error_message: this.errorMessage ?? null,\n next_api_recheck_at: this.nextApiRecheckAt ?? null,\n provider_document: this.providerDocument?.toArray() ?? null,\n };\n }\n}\n","import { VatResource } from './VatResource.js';\n\nexport class VatCollection implements Iterable<VatResource> {\n private readonly items: VatResource[];\n public readonly self: string | undefined;\n\n constructor(items: VatResource[], self?: string) {\n this.items = items;\n this.self = self;\n }\n\n static fromResponse(data: unknown): VatCollection {\n if (Array.isArray(data)) {\n return new VatCollection((data as Record<string, unknown>[]).map(VatResource.fromArray));\n }\n\n if (typeof data === 'object' && data !== null) {\n const obj = data as Record<string, unknown>;\n const items = Array.isArray(obj['data'])\n ? (obj['data'] as Record<string, unknown>[]).map(VatResource.fromArray)\n : [];\n const self = typeof obj['self'] === 'string' ? obj['self'] : undefined;\n return new VatCollection(items, self);\n }\n\n return new VatCollection([]);\n }\n\n [Symbol.iterator](): Iterator<VatResource> {\n return this.items[Symbol.iterator]();\n }\n\n get length(): number {\n return this.items.length;\n }\n\n all(): VatResource[] {\n return [...this.items];\n }\n}\n","export class VatCertificateExport {\n constructor(\n public readonly exportId: string,\n public readonly message?: string,\n ) {}\n\n static fromArray(data: Record<string, unknown>): VatCertificateExport {\n return new VatCertificateExport(\n typeof data['export_id'] === 'string' ? data['export_id'] : '',\n typeof data['message'] === 'string' ? data['message'] : undefined,\n );\n }\n\n toArray(): { export_id: string; message?: string } {\n const result: { export_id: string; message?: string } = { export_id: this.exportId };\n if (this.message !== undefined) result.message = this.message;\n return result;\n }\n}\n","import { TaxoraException } from '../exceptions/TaxoraException.js';\n\ninterface VatValidationAddressInputProps {\n addressLine1?: string;\n addressLine2?: string;\n postalCode?: string;\n city?: string;\n countryCode?: string;\n}\n\nconst ALLOWED_KEYS = new Set(['address_line_1', 'address_line_2', 'postal_code', 'city', 'country_code']);\n\nexport class VatValidationAddressInput {\n public readonly addressLine1?: string;\n public readonly addressLine2?: string;\n public readonly postalCode?: string;\n public readonly city?: string;\n public readonly countryCode?: string;\n\n constructor(props: VatValidationAddressInputProps) {\n if (props.addressLine1 !== undefined && props.addressLine1.length > 255) {\n throw new TaxoraException('addressLine1 must not exceed 255 characters');\n }\n if (props.addressLine2 !== undefined && props.addressLine2.length > 255) {\n throw new TaxoraException('addressLine2 must not exceed 255 characters');\n }\n if (props.countryCode !== undefined && props.countryCode.length !== 2) {\n throw new TaxoraException('countryCode must be exactly 2 characters (ISO 3166-1 alpha-2)');\n }\n\n this.addressLine1 = props.addressLine1;\n this.addressLine2 = props.addressLine2;\n this.postalCode = props.postalCode;\n this.city = props.city;\n this.countryCode = props.countryCode;\n }\n\n static fromArray(data: Record<string, unknown>): VatValidationAddressInput {\n for (const key of Object.keys(data)) {\n if (!ALLOWED_KEYS.has(key)) {\n throw new TaxoraException(`Unsupported field: \"${key}\". Allowed fields: ${[...ALLOWED_KEYS].join(', ')}`);\n }\n }\n\n const getString = (key: string): string | undefined => {\n const val = data[key];\n if (typeof val !== 'string') return undefined;\n const trimmed = val.trim();\n return trimmed || undefined;\n };\n\n const countryCode = getString('country_code');\n\n return new VatValidationAddressInput({\n addressLine1: getString('address_line_1'),\n addressLine2: getString('address_line_2'),\n postalCode: getString('postal_code'),\n city: getString('city'),\n countryCode: countryCode ? countryCode.toUpperCase() : undefined,\n });\n }\n\n toArray(): Record<string, string> {\n const result: Record<string, string> = {};\n if (this.addressLine1 !== undefined) result['address_line_1'] = this.addressLine1;\n if (this.addressLine2 !== undefined) result['address_line_2'] = this.addressLine2;\n if (this.postalCode !== undefined) result['postal_code'] = this.postalCode;\n if (this.city !== undefined) result['city'] = this.city;\n if (this.countryCode !== undefined) result['country_code'] = this.countryCode;\n return result;\n }\n}\n","import { VatResource } from '../dto/VatResource.js';\nimport { VatCollection } from '../dto/VatCollection.js';\nimport { VatCertificateExport } from '../dto/VatCertificateExport.js';\nimport { VatValidationAddressInput } from '../dto/VatValidationAddressInput.js';\nimport { type Language } from '../enums/Language.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError, jsonErrorMessage } from '../exceptions/apiErrorMessage.js';\nimport { ValidationException } from '../exceptions/ValidationException.js';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport class VatEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n async validate(\n vatUid: string,\n companyName?: string,\n provider?: string,\n addressInput?: VatValidationAddressInput | Record<string, string>,\n ): Promise<VatResource> {\n const body: Record<string, unknown> = { vat_uid: vatUid };\n if (companyName) body['company_name'] = companyName;\n if (provider) body['source'] = provider;\n\n if (addressInput) {\n body['address_input'] = addressInput instanceof VatValidationAddressInput ? addressInput.toArray() : addressInput;\n }\n\n // Read-only lookup, so transient gateway failures are retried (see RetryPolicy).\n return withRetries(this.retryPolicy, 'VAT validation', async () => {\n const response = await this.sendRequest('POST', `${this.baseUrl}/vat/validate`, body);\n const data = await this.parseJsonResponse(response);\n\n return VatResource.fromArray(data);\n });\n }\n\n async validateMultiple(vatUids: string[], companyNames?: string[], provider?: string): Promise<VatCollection> {\n const body: Record<string, unknown> = { vat_uids: vatUids };\n if (companyNames) body['company_names'] = companyNames;\n if (provider) body['source'] = provider;\n\n return withRetries(this.retryPolicy, 'VAT validation', async () => {\n const response = await this.sendRequest('POST', `${this.baseUrl}/vat/validate/multiple`, body);\n const data = await this.parseJsonResponse(response);\n\n return VatCollection.fromResponse(data);\n });\n }\n\n async validateSchema(vatUid: string): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = { vat_uid: vatUid };\n return withRetries(this.retryPolicy, 'VAT schema check', async () => {\n const response = await this.sendRequest('POST', `${this.baseUrl}/vat/validate/schema`, body);\n\n return this.parseJsonResponse(response);\n });\n }\n\n async state(vatUid: string): Promise<VatResource> {\n return withRetries(this.retryPolicy, 'VAT state lookup', async () => {\n const response = await this.sendRequest('GET', `${this.baseUrl}/vat/state/${encodeURIComponent(vatUid)}`);\n const data = await this.parseJsonResponse(response);\n\n return VatResource.fromArray(data);\n });\n }\n\n async history(vatUid?: string): Promise<VatCollection> {\n let url = `${this.baseUrl}/vat/history`;\n if (vatUid) url += `?vat_uid=${encodeURIComponent(vatUid)}`;\n\n return withRetries(this.retryPolicy, 'VAT history request', async () => {\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n\n return VatCollection.fromResponse(data);\n });\n }\n\n async search(term?: string, perPage?: number): Promise<VatCollection> {\n const params = new URLSearchParams();\n if (term) params.set('term', term);\n if (perPage !== undefined) params.set('per_page', String(perPage));\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/vat/search${queryString ? `?${queryString}` : ''}`;\n\n return withRetries(this.retryPolicy, 'VAT search', async () => {\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n\n return VatCollection.fromResponse(data);\n });\n }\n\n async certificate(uuid: string, lang?: Language): Promise<Uint8Array> {\n let url = `${this.baseUrl}/vat/certificate/${encodeURIComponent(uuid)}`;\n if (lang) url += `?lang=${lang}`;\n\n return withRetries(this.retryPolicy, 'VAT certificate download', async () => {\n const response = await this.sendBinaryRequest('GET', url);\n const buffer = await response.arrayBuffer();\n\n return new Uint8Array(buffer);\n });\n }\n\n async certificatesBulkExport(\n fromDate: Date | string,\n toDate: Date | string,\n countries?: string[],\n lang?: Language,\n ): Promise<VatCertificateExport> {\n return this.exportRequest(`${this.baseUrl}/vat/certificates/bulk-export`, fromDate, toDate, countries, lang);\n }\n\n async certificatesListExport(\n fromDate: Date | string,\n toDate: Date | string,\n countries?: string[],\n lang?: Language,\n ): Promise<VatCertificateExport> {\n return this.exportRequest(`${this.baseUrl}/vat/certificates/list-export`, fromDate, toDate, countries, lang);\n }\n\n private async exportRequest(\n url: string,\n fromDate: Date | string,\n toDate: Date | string,\n countries?: string[],\n lang?: Language,\n ): Promise<VatCertificateExport> {\n const from = this.formatDate(fromDate);\n const to = this.formatDate(toDate);\n\n const body: Record<string, unknown> = { from_date: from, to_date: to };\n if (countries && countries.length > 0) body['countries'] = countries;\n if (lang) body['lang'] = lang;\n\n const response = await this.sendRequest('POST', url, body);\n const data = await this.parseJsonResponse(response, [200, 202]);\n\n const exportObj = VatCertificateExport.fromArray(data);\n if (!exportObj.exportId) {\n throw new TaxoraException('Export response is missing export_id');\n }\n\n return exportObj;\n }\n\n async downloadBulkExport(exportId: string): Promise<Uint8Array> {\n const url = `${this.baseUrl}/vat/certificates/bulk-export/${encodeURIComponent(exportId)}/download`;\n\n return withRetries(this.retryPolicy, 'VAT export download', async () => {\n const response = await this.sendBinaryRequest('GET', url);\n const buffer = await response.arrayBuffer();\n\n return new Uint8Array(buffer);\n });\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n return headers;\n }\n\n private async sendRequest(method: string, url: string, body?: Record<string, unknown>): Promise<Response> {\n const options: RequestInit = { headers: this.buildHeaders() };\n if (body) options.body = JSON.stringify(body);\n\n return this.httpClient.request(method, url, options);\n }\n\n private async sendBinaryRequest(method: string, url: string): Promise<Response> {\n const headers = this.buildHeaders();\n delete headers['Content-Type'];\n\n const response = await this.httpClient.request(method, url, { headers });\n if (!response.ok) {\n const text = await response.text();\n throw new HttpException(\n describeApiError(text, response.status),\n response.status,\n text,\n {},\n response.headers.get('retry-after'),\n );\n }\n return response;\n }\n\n private async parseJsonResponse(\n response: Response,\n acceptedStatuses: number[] = [200],\n ): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n let errors: Record<string, string[]> = {};\n try {\n const parsed = JSON.parse(responseText) as Record<string, unknown>;\n if (parsed['errors'] !== null && typeof parsed['errors'] === 'object' && !Array.isArray(parsed['errors'])) {\n errors = parsed['errors'] as Record<string, string[]>;\n }\n } catch {\n // ignore parse errors\n }\n throw new ValidationException(jsonErrorMessage(responseText) ?? 'Validation failed', errors);\n }\n\n if (!response.ok && !acceptedStatuses.includes(response.status)) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && (typeof obj['data'] === 'object' || Array.isArray(obj['data']))) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n\n private formatDate(date: Date | string): string {\n if (date instanceof Date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n if (!DATE_REGEX.test(date)) {\n throw new TaxoraException(`Invalid date format: \"${date}\". Expected YYYY-MM-DD.`);\n }\n\n return date;\n }\n}\n","export const Environment = {\n SANDBOX: 'sandbox',\n PRODUCTION: 'production',\n} as const;\n\nexport type Environment = (typeof Environment)[keyof typeof Environment];\n\nconst BASE_URLS: Record<Environment, string> = {\n [Environment.SANDBOX]: 'https://sandbox.taxora.io/v1',\n [Environment.PRODUCTION]: 'https://api.taxora.io/v1',\n};\n\nexport function getBaseUrl(environment: Environment): string {\n return BASE_URLS[environment];\n}\n","import { type HttpClientInterface } from './HttpClientInterface.js';\n\nexport class FetchHttpClient implements HttpClientInterface {\n async request(method: string, url: string, options: RequestInit = {}): Promise<Response> {\n return fetch(url, { ...options, method });\n }\n}\n","import { type Token } from '../dto/Token.js';\nimport { type TokenStorageInterface } from './TokenStorageInterface.js';\n\nexport class InMemoryTokenStorage implements TokenStorageInterface {\n private token: Token | null = null;\n\n get(): Token | null {\n return this.token;\n }\n\n set(token: Token): void {\n this.token = token;\n }\n\n clear(): void {\n this.token = null;\n }\n}\n","import { type Token } from '../dto/Token.js';\nimport { AuthenticationException } from '../exceptions/AuthenticationException.js';\nimport { type HttpClientInterface } from './HttpClientInterface.js';\nimport { type TokenStorageInterface } from './TokenStorageInterface.js';\n\nconst AUTH_PATH_PATTERN = /\\/auth\\//;\n\n/**\n * HTTP client wrapper that handles:\n * - Preemptive token refresh when the stored token is expired\n * - Automatic retry with a fresh token on 401 responses\n * - Passthrough for /auth/ routes (no interception)\n */\nexport class AuthRetryHttpClient implements HttpClientInterface {\n constructor(\n private readonly inner: HttpClientInterface,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly refreshFn: () => Promise<Token>,\n ) {}\n\n async request(method: string, url: string, options?: RequestInit): Promise<Response> {\n // Auth routes bypass all retry logic\n if (AUTH_PATH_PATTERN.test(url)) {\n return this.inner.request(method, url, options);\n }\n\n // Preemptive refresh if token is expired\n const currentToken = this.tokenStorage.get();\n if (currentToken?.isExpired()) {\n await this.refreshFn();\n }\n\n // Build request with potentially refreshed token\n const updatedOptions = this.injectAuthHeader(options);\n const response = await this.inner.request(method, url, updatedOptions);\n\n // 401: refresh once and retry\n if (response.status === 401) {\n await this.refreshFn();\n const retryOptions = this.injectAuthHeader(options);\n const retryResponse = await this.inner.request(method, url, retryOptions);\n\n if (retryResponse.status === 401) {\n const body = await retryResponse.text();\n throw new AuthenticationException('Authentication failed after token refresh', { status: 401, body });\n }\n\n return retryResponse;\n }\n\n return response;\n }\n\n private injectAuthHeader(options?: RequestInit): RequestInit {\n const token = this.tokenStorage.get();\n if (!token) return options ?? {};\n\n const existing = options?.headers ?? {};\n const headers = { ...(existing as Record<string, string>), Authorization: `Bearer ${token.accessToken}` };\n return { ...(options ?? {}), headers };\n }\n}\n","/**\n * SDK version. Kept in sync with package.json by scripts/tag-release.sh.\n */\nexport const SDK_VERSION = '1.3.0';\n","import { type HttpClientInterface } from './HttpClientInterface.js';\nimport { SDK_VERSION } from '../version.js';\n\nconst SDK_VERSION_HEADER = 'X-Taxora-SDK-Version';\nconst SDK_VERSION_VALUE = `taxora-node/${SDK_VERSION}`;\n\n/**\n * HTTP client wrapper that stamps every outgoing request with the SDK version\n * header so the backend can record which SDK version made the call.\n *\n * Purely additive: it only merges in one header (without overwriting existing\n * ones) and delegates to the inner client.\n */\nexport class SdkVersionHttpClient implements HttpClientInterface {\n constructor(private readonly inner: HttpClientInterface) {}\n\n async request(method: string, url: string, options?: RequestInit): Promise<Response> {\n const existing = options?.headers ?? {};\n const headers = {\n ...(existing as Record<string, string>),\n [SDK_VERSION_HEADER]: SDK_VERSION_VALUE,\n };\n return this.inner.request(method, url, { ...(options ?? {}), headers });\n }\n}\n","import { AuthEndpoint } from '../endpoints/AuthEndpoint.js';\nimport { CompanyEndpoint } from '../endpoints/CompanyEndpoint.js';\nimport { EReportingEndpoint } from '../endpoints/EReportingEndpoint.js';\nimport { SmartEnrichmentEndpoint } from '../endpoints/SmartEnrichmentEndpoint.js';\nimport { VatEndpoint } from '../endpoints/VatEndpoint.js';\nimport { Environment, getBaseUrl } from '../enums/Environment.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { FetchHttpClient } from '../http/FetchHttpClient.js';\nimport { InMemoryTokenStorage } from '../http/InMemoryTokenStorage.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\nimport { AuthRetryHttpClient } from '../http/AuthRetryHttpClient.js';\nimport { SdkVersionHttpClient } from '../http/SdkVersionHttpClient.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\n\nexport interface TaxoraClientOptions {\n apiKey: string;\n environment?: Environment;\n tokenStorage?: TokenStorageInterface;\n httpClient?: HttpClientInterface;\n /** Retry behaviour for transient gateway failures; defaults to 3 attempts with backoff. */\n retryPolicy?: RetryPolicy;\n}\n\nexport class TaxoraClient {\n public readonly auth: AuthEndpoint;\n public readonly vat: VatEndpoint;\n public readonly company: CompanyEndpoint;\n public readonly smartEnrichment: SmartEnrichmentEndpoint;\n public readonly eReporting: EReportingEndpoint;\n public readonly baseUrl: string;\n\n constructor(options: TaxoraClientOptions) {\n const environment = options.environment ?? Environment.SANDBOX;\n const tokenStorage = options.tokenStorage ?? new InMemoryTokenStorage();\n const httpClient = options.httpClient ?? new FetchHttpClient();\n const retryPolicy = options.retryPolicy ?? new RetryPolicy();\n\n // Wrap the transport so every request carries the SDK version header.\n const versionedClient = new SdkVersionHttpClient(httpClient);\n\n this.baseUrl = getBaseUrl(environment);\n\n // Auth endpoint uses the version-stamped client directly — no retry interception for auth routes\n this.auth = new AuthEndpoint(this.baseUrl, options.apiKey, tokenStorage, versionedClient, retryPolicy);\n\n // All other endpoints use the retry-capable client that handles 401 auto-refresh\n const retryClient = new AuthRetryHttpClient(versionedClient, tokenStorage, () => this.auth.refresh());\n\n this.vat = new VatEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);\n this.company = new CompanyEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);\n this.smartEnrichment = new SmartEnrichmentEndpoint(\n this.baseUrl,\n options.apiKey,\n tokenStorage,\n retryClient,\n retryPolicy,\n );\n this.eReporting = new EReportingEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);\n }\n}\n","import { TaxoraClient, type TaxoraClientOptions } from './TaxoraClient.js';\n\nexport class TaxoraClientFactory {\n static create(options: TaxoraClientOptions): TaxoraClient {\n return new TaxoraClient(options);\n }\n}\n","export const ApiVersion = {\n V1: 'v1',\n} as const;\n\nexport type ApiVersion = (typeof ApiVersion)[keyof typeof ApiVersion];\n","export const Language = {\n ENGLISH: 'en',\n GERMAN: 'de',\n} as const;\n\nexport type Language = (typeof Language)[keyof typeof Language];\n","import { createHmac, timingSafeEqual } from 'node:crypto';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport type { TaxoraWebhookEvent } from './WebhookEvent.js';\n\n/** Name of the HTTP header that carries the signature. Node lower-cases it: `req.headers['taxora-signature']`. */\nexport const WEBHOOK_SIGNATURE_HEADER = 'Taxora-Signature';\n\n/** Name of the HTTP header that carries the delivery UUID (stable across retries). */\nexport const WEBHOOK_ID_HEADER = 'Taxora-Webhook-Id';\n\n/** Default maximum age (seconds) of a signed request before it is rejected as a possible replay. */\nexport const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;\n\nconst SCHEME = 'v1';\n\n/** The exact bytes Taxora sent. Never pass a parsed-and-re-serialised object. */\nexport type WebhookRawBody = string | Uint8Array | ArrayBuffer;\n\n/** Header value as frameworks hand it over (Express/Node may give an array for repeated headers). */\nexport type WebhookSignatureHeaderInput = string | readonly string[] | null | undefined;\n\nexport interface WebhookVerifyOptions {\n /**\n * Maximum allowed difference between now and the signature timestamp, in seconds. Default 300.\n * `0` disables the check — not recommended, it re-opens replay attacks.\n */\n tolerance?: number;\n /** Current time in Unix seconds. Only meant for tests. */\n now?: number;\n}\n\nexport type WebhookSignatureErrorReason =\n | 'missing_secret'\n | 'missing_header'\n | 'malformed_header'\n | 'invalid_body'\n | 'timestamp_outside_tolerance'\n | 'no_matching_signature'\n | 'invalid_payload';\n\nexport class WebhookSignatureVerificationError extends TaxoraException {\n public readonly reason: WebhookSignatureErrorReason;\n\n constructor(message: string, reason: WebhookSignatureErrorReason, context: Record<string, unknown> = {}) {\n super(message, { ...context, reason });\n this.name = 'WebhookSignatureVerificationError';\n this.reason = reason;\n }\n}\n\nexport interface ParsedWebhookSignatureHeader {\n timestamp: number;\n /** All `v1` signatures — two during a secret rotation on Taxora's side. */\n signatures: string[];\n}\n\n/** Parses `t=<unix>,v1=<hex>[,v1=<hex>…]`. Unknown schemes are ignored for forward compatibility. */\nexport function parseWebhookSignatureHeader(header: WebhookSignatureHeaderInput): ParsedWebhookSignatureHeader {\n const value = Array.isArray(header) ? header[0] : header;\n if (typeof value !== 'string' || value.trim() === '') {\n throw new WebhookSignatureVerificationError(\n `Missing ${WEBHOOK_SIGNATURE_HEADER} header. Is signing enabled for this webhook endpoint?`,\n 'missing_header',\n );\n }\n\n let timestamp: number | null = null;\n const signatures: string[] = [];\n\n for (const part of value.split(',')) {\n const separator = part.indexOf('=');\n if (separator === -1) continue;\n const key = part.slice(0, separator).trim();\n const val = part.slice(separator + 1).trim();\n\n if (key === 't' && /^\\d+$/.test(val)) {\n timestamp = Number(val);\n } else if (key === SCHEME && /^[0-9a-f]{64}$/i.test(val)) {\n signatures.push(val.toLowerCase());\n }\n }\n\n if (timestamp === null || signatures.length === 0) {\n throw new WebhookSignatureVerificationError(\n `Malformed ${WEBHOOK_SIGNATURE_HEADER} header — expected \"t=<unix>,v1=<hex>\".`,\n 'malformed_header',\n );\n }\n\n return { timestamp, signatures };\n}\n\n/** hex(HMAC-SHA256(secret, `${timestamp}.${rawBody}`)) — the value Taxora puts into `v1=`. */\nexport function computeWebhookSignature(rawBody: WebhookRawBody, timestamp: number, secret: string): string {\n return createHmac('sha256', secret).update(`${timestamp}.`).update(toBytes(rawBody)).digest('hex');\n}\n\n/**\n * Builds a valid `Taxora-Signature` header value for a payload — handy for unit-testing your webhook handler\n * without calling Taxora.\n */\nexport function generateWebhookSignatureHeader(\n rawBody: WebhookRawBody,\n secret: string | readonly string[],\n timestamp: number = Math.floor(Date.now() / 1000),\n): string {\n const secrets = normalizeSecrets(secret);\n return [`t=${timestamp}`, ...secrets.map((s) => `${SCHEME}=${computeWebhookSignature(rawBody, timestamp, s)}`)].join(\n ',',\n );\n}\n\n/**\n * Verifies a Taxora webhook request. Returns `true` or throws {@link WebhookSignatureVerificationError}.\n *\n * - `rawBody` must be the unmodified request body (e.g. `express.raw()`, `await request.text()`).\n * - `secret` may be a list — useful while you rotate the secret on your side.\n * - The comparison is constant-time; the timestamp must be within `tolerance` seconds (default 300).\n */\nexport function verifyWebhookSignature(\n rawBody: WebhookRawBody,\n header: WebhookSignatureHeaderInput,\n secret: string | readonly string[],\n options: WebhookVerifyOptions = {},\n): true {\n const secrets = normalizeSecrets(secret);\n const bytes = toBytes(rawBody);\n const { timestamp, signatures } = parseWebhookSignatureHeader(header);\n\n const tolerance = options.tolerance ?? DEFAULT_WEBHOOK_TOLERANCE_SECONDS;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n if (tolerance > 0 && Math.abs(now - timestamp) > tolerance) {\n throw new WebhookSignatureVerificationError(\n `Timestamp outside the tolerance window (${tolerance}s). Possible replay — or check the server clock.`,\n 'timestamp_outside_tolerance',\n { timestamp, now, tolerance },\n );\n }\n\n const received = signatures.map((s) => Buffer.from(s, 'hex'));\n for (const s of secrets) {\n const expected = Buffer.from(computeWebhookSignature(bytes, timestamp, s), 'hex');\n // Check every pair (no early exit per secret) so timing does not reveal which entry matched.\n let matched = false;\n for (const candidate of received) {\n if (candidate.length === expected.length && timingSafeEqual(candidate, expected)) {\n matched = true;\n }\n }\n if (matched) return true;\n }\n\n throw new WebhookSignatureVerificationError(\n 'No signature matches the expected signature for this payload. Make sure you pass the raw request body ' +\n '(not re-serialised JSON) and the full secret including the \"whsec_\" prefix.',\n 'no_matching_signature',\n );\n}\n\n/**\n * Verifies the signature and returns the parsed, typed event. Throws {@link WebhookSignatureVerificationError}\n * on any problem — respond with HTTP 400 in that case.\n *\n * ```ts\n * app.post('/taxora-webhook', express.raw({ type: 'application/json' }), (req, res) => {\n * const event = constructWebhookEvent(req.body, req.header('Taxora-Signature'), process.env.TAXORA_WEBHOOK_SECRET!);\n * if (event.event === 'vat.validated') { ... }\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function constructWebhookEvent<T extends TaxoraWebhookEvent = TaxoraWebhookEvent>(\n rawBody: WebhookRawBody,\n header: WebhookSignatureHeaderInput,\n secret: string | readonly string[],\n options: WebhookVerifyOptions = {},\n): T {\n verifyWebhookSignature(rawBody, header, secret, options);\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.from(toBytes(rawBody)).toString('utf8'));\n } catch {\n throw new WebhookSignatureVerificationError('Webhook payload is not valid JSON.', 'invalid_payload');\n }\n\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n typeof (parsed as { id?: unknown }).id !== 'string' ||\n typeof (parsed as { event?: unknown }).event !== 'string' ||\n typeof (parsed as { data?: unknown }).data !== 'object'\n ) {\n throw new WebhookSignatureVerificationError(\n 'Webhook payload does not have the expected { id, event, timestamp, data } shape.',\n 'invalid_payload',\n );\n }\n\n return parsed as T;\n}\n\nfunction normalizeSecrets(secret: string | readonly string[]): string[] {\n const list = (typeof secret === 'string' ? [secret] : [...secret]).filter(\n (s): s is string => typeof s === 'string' && s !== '',\n );\n if (list.length === 0) {\n throw new WebhookSignatureVerificationError(\n 'No webhook signing secret given. Copy it from the Taxora dashboard (Developer → Webhooks).',\n 'missing_secret',\n );\n }\n return list;\n}\n\nfunction toBytes(rawBody: WebhookRawBody): Uint8Array {\n if (typeof rawBody === 'string') return Buffer.from(rawBody, 'utf8');\n if (rawBody instanceof Uint8Array) return rawBody;\n if (rawBody instanceof ArrayBuffer) return new Uint8Array(rawBody);\n throw new WebhookSignatureVerificationError(\n 'Webhook body must be the raw request body (string, Buffer or Uint8Array). It looks like it was already ' +\n 'parsed as JSON — use express.raw() / request.text() instead of a JSON body parser.',\n 'invalid_body',\n );\n}\n"],"mappings":"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","names":["VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","asString","asNullableString","asNumber","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","asString","asNullableString","asNumber","asMoney","asNullableNumber","VALUES","DESCRIPTIONS","asString","asNullableString","asString","asNullableString","asString","asNumber","asMoney","asString","asNullableString","asString","asNumber","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","asString","asNumber","asRecord","asRecords","DESCRIPTIONS","DATE_REGEX","parsed"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/endpoints/AuthEndpoint.ts","../src/dto/Token.ts","../src/enums/LoginIdentifier.ts","../src/exceptions/TaxoraException.ts","../src/exceptions/AuthenticationException.ts","../src/exceptions/apiErrorMessage.ts","../src/exceptions/HttpException.ts","../src/http/RetryPolicy.ts","../src/http/withRetries.ts","../src/dto/CompanyResource.ts","../src/endpoints/CompanyEndpoint.ts","../src/enums/ComplianceEnrollmentStatus.ts","../src/enums/ComplianceService.ts","../src/dto/ComplianceEnrollment.ts","../src/dto/ComplianceEnrollmentPage.ts","../src/enums/ComplianceTaxReportState.ts","../src/dto/ComplianceTaxReport.ts","../src/dto/ComplianceTaxReportPage.ts","../src/enums/ComplianceDocumentType.ts","../src/enums/ComplianceTransactionState.ts","../src/enums/ComplianceTransactionType.ts","../src/dto/ComplianceTransaction.ts","../src/dto/ComplianceTransactionPage.ts","../src/dto/ImportResult.ts","../src/enums/PeppolLookupStatus.ts","../src/dto/PeppolLookupResult.ts","../src/dto/RegistryCompany.ts","../src/dto/RevenueStatistics.ts","../src/dto/SireneLookupResult.ts","../src/dto/VatRates.ts","../src/exceptions/ValidationException.ts","../src/support/NorwegianOrgNumber.ts","../src/endpoints/EReportingEndpoint.ts","../src/enums/SmartEnrichmentMode.ts","../src/enums/SmartEnrichmentRejectionReason.ts","../src/enums/SmartEnrichmentStatus.ts","../src/dto/SmartEnrichmentResource.ts","../src/dto/SmartEnrichmentJob.ts","../src/dto/SmartEnrichmentHistoryRow.ts","../src/dto/SmartEnrichmentHistoryPage.ts","../src/dto/SmartEnrichmentStatistics.ts","../src/endpoints/SmartEnrichmentEndpoint.ts","../src/enums/VatState.ts","../src/dto/CompanyAddress.ts","../src/dto/ScoreBreakdown.ts","../src/dto/ProviderDocumentLine.ts","../src/dto/ProviderDocument.ts","../src/dto/VatResource.ts","../src/dto/VatCollection.ts","../src/dto/VatCertificateExport.ts","../src/dto/VatValidationAddressInput.ts","../src/endpoints/VatEndpoint.ts","../src/enums/Environment.ts","../src/http/FetchHttpClient.ts","../src/http/InMemoryTokenStorage.ts","../src/http/AuthRetryHttpClient.ts","../src/version.ts","../src/http/SdkVersionHttpClient.ts","../src/client/TaxoraClient.ts","../src/client/TaxoraClientFactory.ts","../src/enums/ApiVersion.ts","../src/enums/Language.ts","../src/webhooks/WebhookSignature.ts"],"sourcesContent":["// Client\nexport { TaxoraClient } from './client/TaxoraClient.js';\nexport { TaxoraClientFactory } from './client/TaxoraClientFactory.js';\nexport type { TaxoraClientOptions } from './client/TaxoraClient.js';\n\n// Endpoints\nexport { AuthEndpoint } from './endpoints/AuthEndpoint.js';\nexport { CompanyEndpoint } from './endpoints/CompanyEndpoint.js';\nexport { VatEndpoint } from './endpoints/VatEndpoint.js';\nexport { SmartEnrichmentEndpoint } from './endpoints/SmartEnrichmentEndpoint.js';\nexport type {\n SmartEnrichmentInput,\n SmartEnrichmentUsage,\n SmartEnrichmentUsageHistoryEntry,\n SmartEnrichmentExportOptions,\n SmartEnrichmentStatisticsOptions,\n SmartEnrichmentWaitOptions,\n} from './endpoints/SmartEnrichmentEndpoint.js';\nexport { EReportingEndpoint } from './endpoints/EReportingEndpoint.js';\nexport type {\n RevenueStatisticsFilters,\n EReportingInterval,\n ComplianceEnterpriseSize,\n ComplianceTypeOperation,\n ComplianceTransactionRequestType,\n ComplianceTransactionRequestState,\n ComplianceTaxReportRequestState,\n ComplianceRequestService,\n CreateComplianceEnrollmentInput,\n CreateNorwayEnrollmentInput,\n NorwayEnrollmentInput,\n ComplianceTransactionBuyerInput,\n CreateComplianceTransactionInput,\n UpdateComplianceTransactionInput,\n ComplianceInvoiceLineInput,\n ComplianceInvoiceTaxInput,\n ComplianceTransactionFilters,\n EReportingAccessRequestInput,\n} from './endpoints/EReportingEndpoint.js';\n\n// DTOs\nexport { Token } from './dto/Token.js';\nexport { ScoreBreakdown } from './dto/ScoreBreakdown.js';\nexport { CompanyAddress } from './dto/CompanyAddress.js';\nexport type { CompanyResource } from './dto/CompanyResource.js';\nexport { VatValidationAddressInput } from './dto/VatValidationAddressInput.js';\nexport { ProviderDocumentLine } from './dto/ProviderDocumentLine.js';\nexport { ProviderDocument } from './dto/ProviderDocument.js';\nexport { VatResource } from './dto/VatResource.js';\nexport { VatCollection } from './dto/VatCollection.js';\nexport { VatCertificateExport } from './dto/VatCertificateExport.js';\nexport { SmartEnrichmentResource } from './dto/SmartEnrichmentResource.js';\nexport type {\n SmartEnrichmentProviderVerdict,\n SmartEnrichmentAddressQuality,\n SmartEnrichmentRejectedCandidate,\n} from './dto/SmartEnrichmentResource.js';\nexport { SmartEnrichmentJob } from './dto/SmartEnrichmentJob.js';\nexport { SmartEnrichmentHistoryRow } from './dto/SmartEnrichmentHistoryRow.js';\nexport type { SmartEnrichmentHistoryInput } from './dto/SmartEnrichmentHistoryRow.js';\nexport { SmartEnrichmentHistoryPage } from './dto/SmartEnrichmentHistoryPage.js';\nexport type { SmartEnrichmentHistoryStats } from './dto/SmartEnrichmentHistoryPage.js';\nexport { SmartEnrichmentStatistics } from './dto/SmartEnrichmentStatistics.js';\nexport type {\n SmartEnrichmentStatisticsInterval,\n SmartEnrichmentStatisticsRange,\n SmartEnrichmentStatisticsTotals,\n SmartEnrichmentTimeBucket,\n SmartEnrichmentSourceBreakdown,\n SmartEnrichmentOutcomeBreakdown,\n SmartEnrichmentConfidenceBucket,\n} from './dto/SmartEnrichmentStatistics.js';\nexport { RevenueStatistics } from './dto/RevenueStatistics.js';\nexport type {\n RevenueTotals,\n RevenueTimeBucket,\n RevenueTypeBreakdown,\n RevenueCountryBreakdown,\n RevenueStateBreakdown,\n RevenueCurrencyBreakdown,\n} from './dto/RevenueStatistics.js';\nexport { ComplianceEnrollment } from './dto/ComplianceEnrollment.js';\nexport { ComplianceEnrollmentPage } from './dto/ComplianceEnrollmentPage.js';\nexport { ComplianceTransaction } from './dto/ComplianceTransaction.js';\nexport type {\n ComplianceTransactionInvoiceLine,\n ComplianceTransactionInvoiceLineTax,\n} from './dto/ComplianceTransaction.js';\nexport { ComplianceTransactionPage } from './dto/ComplianceTransactionPage.js';\nexport { ComplianceTaxReport } from './dto/ComplianceTaxReport.js';\nexport { ComplianceTaxReportPage } from './dto/ComplianceTaxReportPage.js';\nexport { SireneLookupResult } from './dto/SireneLookupResult.js';\nexport { RegistryCompany } from './dto/RegistryCompany.js';\nexport { PeppolLookupResult } from './dto/PeppolLookupResult.js';\nexport { VatRates } from './dto/VatRates.js';\nexport type { VatRate } from './dto/VatRates.js';\nexport { ImportResult } from './dto/ImportResult.js';\n\n// Enums\nexport { Environment, getBaseUrl } from './enums/Environment.js';\nexport type { Environment as EnvironmentType } from './enums/Environment.js';\nexport { ApiVersion } from './enums/ApiVersion.js';\nexport { Language } from './enums/Language.js';\nexport { LoginIdentifier } from './enums/LoginIdentifier.js';\nexport { VatState, getFailedVatStates, describeVatState } from './enums/VatState.js';\nexport {\n SmartEnrichmentStatus,\n toSmartEnrichmentStatus,\n describeSmartEnrichmentStatus,\n} from './enums/SmartEnrichmentStatus.js';\nexport {\n SmartEnrichmentMode,\n toSmartEnrichmentMode,\n describeSmartEnrichmentMode,\n} from './enums/SmartEnrichmentMode.js';\nexport {\n SmartEnrichmentRejectionReason,\n toSmartEnrichmentRejectionReason,\n describeSmartEnrichmentRejectionReason,\n} from './enums/SmartEnrichmentRejectionReason.js';\nexport {\n ComplianceEnrollmentStatus,\n toComplianceEnrollmentStatus,\n describeComplianceEnrollmentStatus,\n} from './enums/ComplianceEnrollmentStatus.js';\nexport {\n ComplianceTransactionState,\n toComplianceTransactionState,\n describeComplianceTransactionState,\n} from './enums/ComplianceTransactionState.js';\nexport {\n ComplianceTransactionType,\n toComplianceTransactionType,\n describeComplianceTransactionType,\n} from './enums/ComplianceTransactionType.js';\nexport {\n ComplianceTaxReportState,\n toComplianceTaxReportState,\n describeComplianceTaxReportState,\n} from './enums/ComplianceTaxReportState.js';\nexport { ComplianceService, toComplianceService, describeComplianceService } from './enums/ComplianceService.js';\nexport {\n ComplianceDocumentType,\n toComplianceDocumentType,\n describeComplianceDocumentType,\n} from './enums/ComplianceDocumentType.js';\nexport { PeppolLookupStatus, toPeppolLookupStatus, describePeppolLookupStatus } from './enums/PeppolLookupStatus.js';\n\n// Helpers\nexport { NorwegianOrgNumber } from './support/NorwegianOrgNumber.js';\n\n// Webhooks\nexport {\n verifyWebhookSignature,\n constructWebhookEvent,\n parseWebhookSignatureHeader,\n computeWebhookSignature,\n generateWebhookSignatureHeader,\n WebhookSignatureVerificationError,\n WEBHOOK_SIGNATURE_HEADER,\n WEBHOOK_ID_HEADER,\n DEFAULT_WEBHOOK_TOLERANCE_SECONDS,\n} from './webhooks/WebhookSignature.js';\nexport type {\n WebhookRawBody,\n WebhookSignatureHeaderInput,\n WebhookVerifyOptions,\n WebhookSignatureErrorReason,\n ParsedWebhookSignatureHeader,\n} from './webhooks/WebhookSignature.js';\nexport type {\n WebhookEventType,\n WebhookEventEnvelope,\n TaxoraWebhookEvent,\n VatWebhookObject,\n ComplianceLedgerWebhookObject,\n ComplianceTransactionWebhookObject,\n EnrichmentCompletedWebhookObject,\n EnrichmentUpdatedWebhookObject,\n TestWebhookObject,\n VatValidatedEvent,\n VatStateChangedEvent,\n ComplianceLedgerStateChangedEvent,\n ComplianceTransactionStateChangedEvent,\n EnrichmentCompletedEvent,\n EnrichmentUpdatedEvent,\n WebhookTestEvent,\n} from './webhooks/WebhookEvent.js';\n\n// Exceptions\nexport { TaxoraException } from './exceptions/TaxoraException.js';\nexport { AuthenticationException } from './exceptions/AuthenticationException.js';\nexport { HttpException } from './exceptions/HttpException.js';\nexport { ValidationException } from './exceptions/ValidationException.js';\nexport { describeApiError } from './exceptions/apiErrorMessage.js';\n\n// Retries\nexport { RetryPolicy, type RetryPolicyOptions } from './http/RetryPolicy.js';\n\n// HTTP\nexport type { TokenStorageInterface } from './http/TokenStorageInterface.js';\nexport { InMemoryTokenStorage } from './http/InMemoryTokenStorage.js';\nexport type { HttpClientInterface } from './http/HttpClientInterface.js';\nexport { FetchHttpClient } from './http/FetchHttpClient.js';\nexport { AuthRetryHttpClient } from './http/AuthRetryHttpClient.js';\n","import { hostname } from 'os';\nimport { Token } from '../dto/Token.js';\nimport { LoginIdentifier } from '../enums/LoginIdentifier.js';\nimport { AuthenticationException } from '../exceptions/AuthenticationException.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nexport class AuthEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n async login(\n identifier: string,\n password: string,\n device?: string,\n loginIdentifier: LoginIdentifier = LoginIdentifier.EMAIL,\n ): Promise<Token> {\n const deviceName = device ?? hostname();\n\n const body: Record<string, string> = {\n identifier: loginIdentifier,\n password,\n device_name: deviceName,\n };\n\n if (loginIdentifier === LoginIdentifier.CLIENT_ID) {\n body['client_id'] = identifier;\n } else {\n body['email'] = identifier;\n }\n\n const data = await withRetries(this.retryPolicy, 'login', async () => {\n const response = await this.httpClient.request('POST', `${this.baseUrl}/auth/login`, {\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n });\n\n const responseText = await response.text();\n\n if (response.status === 401) {\n throw new AuthenticationException('Authentication failed: invalid credentials', {\n status: 401,\n body: responseText,\n });\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n return this.parseResponse(responseText, response.status);\n });\n\n const token = Token.fromArray(data);\n this.tokenStorage.set(token);\n return token;\n }\n\n async loginWithClientId(clientId: string, password: string, device?: string): Promise<Token> {\n return this.login(clientId, password, device, LoginIdentifier.CLIENT_ID);\n }\n\n async refresh(): Promise<Token> {\n const storedToken = this.tokenStorage.get();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n\n if (storedToken) {\n headers['Authorization'] = `Bearer ${storedToken.accessToken}`;\n }\n\n const data = await withRetries(this.retryPolicy, 'token refresh', async () => {\n const response = await this.httpClient.request('POST', `${this.baseUrl}/auth/refresh`, { headers });\n const responseText = await response.text();\n\n if (response.status === 401) {\n throw new AuthenticationException('Token refresh failed: unauthorized', { status: 401, body: responseText });\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n return this.parseResponse(responseText, response.status);\n });\n\n const token = Token.fromArray(data);\n this.tokenStorage.set(token);\n return token;\n }\n\n private parseResponse(responseText: string, statusCode: number): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', statusCode, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', statusCode, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && typeof obj['data'] === 'object' && obj['data'] !== null) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n}\n","export class Token {\n constructor(\n public readonly accessToken: string,\n public readonly tokenType: string,\n public readonly expiresAt: Date,\n ) {}\n\n isExpired(bufferSeconds = 15): boolean {\n return new Date(Date.now() + bufferSeconds * 1000) >= this.expiresAt;\n }\n\n static fromArray(data: Record<string, unknown>): Token {\n let accessToken = String(data['access_token'] ?? '');\n if (accessToken.startsWith('Bearer ')) {\n accessToken = accessToken.slice(7);\n }\n\n const tokenType = String(data['token_type'] ?? 'Bearer');\n const expiresIn = typeof data['expires_in'] === 'number' ? data['expires_in'] : 3600;\n const expiresAt = new Date(Date.now() + expiresIn * 1000);\n\n return new Token(accessToken, tokenType, expiresAt);\n }\n\n toArray(): { access_token: string; token_type: string; expires_at: string } {\n return {\n access_token: this.accessToken,\n token_type: this.tokenType,\n expires_at: this.expiresAt.toISOString(),\n };\n }\n}\n","export const LoginIdentifier = {\n EMAIL: 'email',\n CLIENT_ID: 'client_id',\n} as const;\n\nexport type LoginIdentifier = (typeof LoginIdentifier)[keyof typeof LoginIdentifier];\n","export class TaxoraException extends Error {\n public readonly context: Record<string, unknown>;\n\n constructor(message: string, context: Record<string, unknown> = {}) {\n super(message);\n this.name = 'TaxoraException';\n this.context = context;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","import { TaxoraException } from './TaxoraException.js';\n\nexport class AuthenticationException extends TaxoraException {\n public readonly statusCode = 401;\n\n constructor(message: string, context: Record<string, unknown> = {}) {\n super(message, context);\n this.name = 'AuthenticationException';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Derives a short, human readable exception message from an API response body.\n *\n * A response body is never used verbatim as an exception message: the gateways\n * in front of the API (DigitalOcean App Platform, load balancers, proxies)\n * answer 5xx with a full HTML error page, and that page would otherwise end up\n * in every log line and stack trace of the integrating application.\n *\n * Only the human readable message of a JSON error body is used; everything else\n * (HTML, empty bodies, binary payloads) falls back to the HTTP status line. The\n * untouched body always stays available via `HttpException.getResponseBody()`.\n */\n\nconst MAX_LENGTH = 500;\n\n/** Plain text bodies are only surfaced when they are this short. */\nconst MAX_PLAIN_LENGTH = 200;\n\nconst REASON_PHRASES: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Not Found',\n 405: 'Method Not Allowed',\n 408: 'Request Timeout',\n 409: 'Conflict',\n 413: 'Payload Too Large',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n};\n\n/**\n * The message for a failed request: the API message when the body carries one,\n * otherwise a description of the HTTP status.\n */\nexport function describeApiError(body: string | null | undefined, statusCode: number): string {\n return jsonErrorMessage(body) ?? plainErrorMessage(body) ?? statusErrorMessage(statusCode);\n}\n\n/**\n * The failure detail without the surrounding sentence: the API message when\n * there is one, otherwise just the status (\"HTTP 504 Gateway Timeout\").\n */\nexport function detailApiError(body: string | null | undefined, statusCode: number): string {\n return jsonErrorMessage(body) ?? plainErrorMessage(body) ?? statusPhrase(statusCode);\n}\n\n/** The human readable message of a JSON error body, or null. */\nexport function jsonErrorMessage(body: string | null | undefined): string | null {\n if (body === null || body === undefined || body.trim() === '') return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n return null;\n }\n\n if (typeof parsed !== 'object' || parsed === null) return null;\n const payload = parsed as Record<string, unknown>;\n\n for (const key of ['message', 'error']) {\n const value = payload[key];\n if (typeof value === 'string') {\n const message = sanitize(value);\n if (message !== null) return message;\n }\n }\n\n const errors = payload['errors'];\n if (typeof errors === 'object' && errors !== null) {\n return fromErrorBag(errors as Record<string, unknown>);\n }\n\n return null;\n}\n\nexport function statusErrorMessage(statusCode: number): string {\n return `Taxora API request failed (${statusPhrase(statusCode)}).`;\n}\n\n/** e.g. \"HTTP 504 Gateway Timeout\". */\nexport function statusPhrase(statusCode: number): string {\n const phrase = REASON_PHRASES[statusCode];\n\n return `HTTP ${statusCode}${phrase ? ` ${phrase}` : ''}`;\n}\n\n/**\n * A short body without any markup (e.g. \"upstream request timeout\") is safe to\n * surface as is; anything longer or HTML/JSON shaped is not.\n */\nfunction plainErrorMessage(body: string | null | undefined): string | null {\n if (body === null || body === undefined) return null;\n\n const value = body.replace(/\\s+/g, ' ').trim();\n if (value === '' || value.length > MAX_PLAIN_LENGTH) return null;\n if (value.includes('<') || value.includes('{')) return null;\n\n return value;\n}\n\nfunction fromErrorBag(errors: Record<string, unknown>): string | null {\n for (const [field, messages] of Object.entries(errors)) {\n for (const message of Array.isArray(messages) ? messages : [messages]) {\n if (typeof message !== 'string') continue;\n const sanitized = sanitize(message);\n if (sanitized === null) continue;\n\n return field !== '' ? `${field}: ${sanitized}` : sanitized;\n }\n }\n\n return null;\n}\n\n/** Single line, length capped, never an HTML document. */\nfunction sanitize(value: string): string | null {\n const collapsed = value.replace(/\\s+/g, ' ').trim();\n if (collapsed === '') return null;\n if (/<!doctype\\s+html|<html[\\s>]/i.test(collapsed)) return null;\n\n return collapsed.length > MAX_LENGTH ? `${collapsed.slice(0, MAX_LENGTH - 1)}…` : collapsed;\n}\n","import { TaxoraException } from './TaxoraException.js';\nimport { detailApiError } from './apiErrorMessage.js';\n\nexport class HttpException extends TaxoraException {\n public readonly statusCode: number;\n public readonly responseBody: string;\n /** Raw `Retry-After` header of the failed response, when it carried one. */\n public readonly retryAfter: string | null;\n\n constructor(\n message: string,\n statusCode: number,\n responseBody: string,\n context: Record<string, unknown> = {},\n retryAfter: string | null = null,\n ) {\n super(message, context);\n this.name = 'HttpException';\n this.statusCode = statusCode;\n this.responseBody = responseBody;\n this.retryAfter = retryAfter;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * The final failure after the SDK retried a transient gateway error, e.g.\n * \"Taxora VAT validation failed after 3 attempts (HTTP 504 Gateway Timeout).\"\n */\n static afterAttempts(operation: string, attempts: number, last: HttpException): HttpException {\n const detail = detailApiError(last.getResponseBody(), last.getStatusCode());\n\n return new HttpException(\n `Taxora ${operation} failed after ${attempts} attempts (${detail}).`,\n last.getStatusCode(),\n last.getResponseBody(),\n { ...last.context, attempts, cause: last },\n last.getRetryAfter(),\n );\n }\n\n getStatusCode(): number {\n return this.statusCode;\n }\n\n getResponseBody(): string {\n return this.responseBody;\n }\n\n getRetryAfter(): string | null {\n return this.retryAfter;\n }\n}\n","/**\n * How the SDK retries transient failures.\n *\n * Only gateway-level failures are retried by default (502/503/504): those come\n * from the infrastructure in front of the API, not from the API itself, and a\n * second attempt a moment later usually succeeds. Everything else — 4xx, and any\n * answer the API produced itself — is surfaced immediately.\n *\n * On top of that, a 429 is retried when the API answers with a `Retry-After`\n * telling us how long to wait, and connection-level failures (reset connection,\n * client-side timeout, DNS hiccup) are retried as well — those never reached the\n * API's answer either.\n *\n * Retries are opt-in per operation and are only applied to read-only calls\n * (lookups, downloads, polling). Calls that change state or cost quota — booking\n * a transaction, starting an enrichment job, triggering a certificate export —\n * are never retried automatically, because a gateway timeout does not tell us\n * whether the API already processed the request.\n */\nexport interface RetryPolicyOptions {\n /** Total attempts including the first one (1 disables retrying). */\n maxAttempts?: number;\n initialDelayMs?: number;\n backoffMultiplier?: number;\n maxDelayMs?: number;\n retryableStatusCodes?: number[];\n /** Honour a `Retry-After` header instead of the backoff, and retry a 429 that carries one. */\n respectRetryAfter?: boolean;\n /** Longest wait accepted from `Retry-After`; a longer one means we give up instead of blocking. */\n maxRetryAfterMs?: number;\n /** Retry connection-level failures (reset connection, client-side timeout, DNS hiccup). */\n retryOnNetworkErrors?: boolean;\n /** Receives the delay in milliseconds; defaults to setTimeout. */\n sleeper?: (delayMs: number) => Promise<void> | void;\n}\n\nexport const DEFAULT_RETRYABLE_STATUS_CODES = [502, 503, 504];\n\n/** Retried only when the response tells us how long to wait. */\nconst RETRY_AFTER_ONLY_STATUS_CODES = [429];\n\n/** Node/undici error codes that mean \"the request never got an answer\". */\nconst NETWORK_ERROR_CODES = new Set([\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'ECONNABORTED',\n 'EPIPE',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n 'EHOSTUNREACH',\n 'ENETUNREACH',\n 'ENETDOWN',\n 'UND_ERR_CONNECT_TIMEOUT',\n 'UND_ERR_HEADERS_TIMEOUT',\n 'UND_ERR_BODY_TIMEOUT',\n 'UND_ERR_SOCKET',\n]);\n\nexport class RetryPolicy {\n public readonly maxAttempts: number;\n public readonly initialDelayMs: number;\n public readonly backoffMultiplier: number;\n public readonly maxDelayMs: number;\n public readonly retryableStatusCodes: number[];\n public readonly respectRetryAfter: boolean;\n public readonly maxRetryAfterMs: number;\n public readonly retryOnNetworkErrors: boolean;\n private readonly sleeper: ((delayMs: number) => Promise<void> | void) | undefined;\n\n constructor(options: RetryPolicyOptions = {}) {\n this.maxAttempts = options.maxAttempts ?? 3;\n this.initialDelayMs = options.initialDelayMs ?? 500;\n this.backoffMultiplier = options.backoffMultiplier ?? 2;\n this.maxDelayMs = options.maxDelayMs ?? 5000;\n this.retryableStatusCodes = options.retryableStatusCodes ?? DEFAULT_RETRYABLE_STATUS_CODES;\n this.respectRetryAfter = options.respectRetryAfter ?? true;\n this.maxRetryAfterMs = options.maxRetryAfterMs ?? 10_000;\n this.retryOnNetworkErrors = options.retryOnNetworkErrors ?? true;\n this.sleeper = options.sleeper;\n\n if (this.maxAttempts < 1) throw new Error('maxAttempts must be at least 1.');\n if (this.initialDelayMs < 0 || this.maxDelayMs < 0) throw new Error('Delays must not be negative.');\n if (this.backoffMultiplier < 1) throw new Error('backoffMultiplier must be at least 1.');\n }\n\n /** No retrying at all — every failure is surfaced on the first attempt. */\n static disabled(): RetryPolicy {\n return new RetryPolicy({ maxAttempts: 1 });\n }\n\n /** Retry immediately, without waiting (mainly useful in tests). */\n static withoutDelay(maxAttempts = 3): RetryPolicy {\n return new RetryPolicy({ maxAttempts, initialDelayMs: 0, maxDelayMs: 0 });\n }\n\n isRetryable(statusCode: number, retryAfterHeader?: string | null): boolean {\n const retryAfterMs = this.retryAfterMs(retryAfterHeader);\n\n // The API asked for a longer pause than we are willing to block for: hand the\n // caller its 429/503 now instead of sitting on the request.\n if (retryAfterMs !== null && retryAfterMs > this.maxRetryAfterMs) return false;\n\n if (this.retryableStatusCodes.includes(statusCode)) return true;\n\n return retryAfterMs !== null && RETRY_AFTER_ONLY_STATUS_CODES.includes(statusCode);\n }\n\n /** @param attempt Number of attempts made so far (1 = the first one just failed). */\n shouldRetry(statusCode: number, attempt: number, retryAfterHeader?: string | null): boolean {\n return attempt < this.maxAttempts && this.isRetryable(statusCode, retryAfterHeader);\n }\n\n /**\n * A connection-level failure: the request never got an answer, so repeating it\n * is as safe as repeating a gateway timeout.\n */\n isRetryableError(error: unknown): boolean {\n if (!this.retryOnNetworkErrors || !(error instanceof Error)) return false;\n\n if (error.name === 'AbortError' || error.name === 'TimeoutError') return true;\n\n const code = (error as { code?: unknown }).code ?? (error.cause as { code?: unknown } | undefined)?.code;\n if (typeof code === 'string' && NETWORK_ERROR_CODES.has(code)) return true;\n\n // Node's fetch reports every transport problem as `TypeError: fetch failed`.\n return error instanceof TypeError && /fetch failed|network|failed to fetch/i.test(error.message);\n }\n\n shouldRetryError(error: unknown, attempt: number): boolean {\n return attempt < this.maxAttempts && this.isRetryableError(error);\n }\n\n /**\n * The wait the API asked for, in milliseconds — seconds or HTTP-date form — or\n * null when there is none, it cannot be parsed, or the header is ignored.\n */\n retryAfterMs(header: string | null | undefined, now: Date = new Date()): number | null {\n if (!this.respectRetryAfter || header === null || header === undefined) return null;\n\n const value = header.trim();\n if (value === '') return null;\n\n if (/^\\d+$/.test(value)) return Number(value) * 1000;\n\n const date = Date.parse(value);\n if (Number.isNaN(date)) return null;\n\n return Math.max(0, date - now.getTime());\n }\n\n /** The wait before the next attempt: what the API asked for, else exponential backoff. */\n delayMsForAttempt(attempt: number, retryAfterHeader?: string | null): number {\n const retryAfterMs = this.retryAfterMs(retryAfterHeader);\n if (retryAfterMs !== null) return Math.min(retryAfterMs, this.maxRetryAfterMs);\n\n if (this.initialDelayMs === 0) return 0;\n\n const delay = Math.round(this.initialDelayMs * this.backoffMultiplier ** Math.max(0, attempt - 1));\n\n return Math.max(0, Math.min(delay, this.maxDelayMs));\n }\n\n async sleepBeforeRetry(attempt: number, retryAfterHeader?: string | null): Promise<void> {\n const delayMs = this.delayMsForAttempt(attempt, retryAfterHeader);\n if (delayMs <= 0) return;\n\n if (this.sleeper) {\n await this.sleeper(delayMs);\n\n return;\n }\n\n await new Promise<void>((resolve) => setTimeout(resolve, delayMs));\n }\n}\n","import { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { type RetryPolicy } from './RetryPolicy.js';\n\n/**\n * Runs `request` and retries it while the gateway in front of the API keeps\n * failing. Wrap only read-only operations in this: a 502/503/504 does not tell\n * us whether the API already processed the request, so anything that changes\n * state or costs quota must fail fast instead.\n *\n * @param operation Short label used in the final error message, e.g. \"VAT validation\".\n */\nexport async function withRetries<T>(policy: RetryPolicy, operation: string, request: () => Promise<T>): Promise<T> {\n let attempt = 1;\n\n for (;;) {\n try {\n return await request();\n } catch (error) {\n if (!(error instanceof HttpException)) {\n // Connection reset, client-side timeout, DNS hiccup: no answer ever\n // arrived, so this is as safe to repeat as a gateway timeout. The\n // transport error is rethrown unchanged once we give up, so callers keep\n // seeing their HTTP client's own error.\n if (!policy.shouldRetryError(error, attempt)) throw error;\n\n await policy.sleepBeforeRetry(attempt);\n attempt++;\n continue;\n }\n\n const retryAfter = error.getRetryAfter();\n\n if (!policy.shouldRetry(error.getStatusCode(), attempt, retryAfter)) {\n throw attempt > 1 && policy.isRetryable(error.getStatusCode(), retryAfter)\n ? HttpException.afterAttempts(operation, attempt, error)\n : error;\n }\n\n await policy.sleepBeforeRetry(attempt, retryAfter);\n attempt++;\n }\n }\n}\n\n/**\n * Same idea one level lower: retries a request that answers with a transient\n * gateway status instead of throwing. Used for plain GETs, which are safe to\n * repeat by definition. When the attempts are used up, the gateway status is\n * turned into the same \"failed after N attempts\" error as withRetries().\n */\nexport async function withResponseRetries(\n policy: RetryPolicy,\n operation: string,\n send: () => Promise<Response>,\n): Promise<Response> {\n let attempt = 1;\n\n for (;;) {\n let response: Response;\n try {\n response = await send();\n } catch (error) {\n // Same reasoning as in withRetries(): a transport failure never reached an\n // answer, and is rethrown unchanged once the attempts are used up.\n if (!policy.shouldRetryError(error, attempt)) throw error;\n\n await policy.sleepBeforeRetry(attempt);\n attempt++;\n continue;\n }\n\n const retryAfter = response.headers.get('retry-after');\n\n if (!policy.shouldRetry(response.status, attempt, retryAfter)) {\n if (attempt > 1 && policy.isRetryable(response.status, retryAfter)) {\n const body = await response.text();\n const last = new HttpException(describeApiError(body, response.status), response.status, body, {}, retryAfter);\n\n throw HttpException.afterAttempts(operation, attempt, last);\n }\n\n return response;\n }\n\n await policy.sleepBeforeRetry(attempt, retryAfter);\n attempt++;\n }\n}\n","export interface CompanyResource {\n id?: number;\n uuid?: string;\n name?: string;\n vat_uid?: string;\n address_line_1?: string | null;\n address_line_2?: string | null;\n street?: string | null;\n zip_code?: string | null;\n city?: string | null;\n country_code?: string | null;\n email?: string;\n phone_number?: string | null;\n api_rate_limit: number;\n vat_rate_limit: number;\n /**\n * @deprecated Use api_rate_limit and vat_rate_limit instead.\n */\n rate_limit?: number;\n state?: string;\n source?: string;\n [key: string]: unknown;\n}\n\nexport function normalizeCompanyResource(data: Record<string, unknown>): CompanyResource {\n const apiRateLimit = typeof data['api_rate_limit'] === 'number' ? data['api_rate_limit'] : undefined;\n const vatRateLimit = typeof data['vat_rate_limit'] === 'number' ? data['vat_rate_limit'] : undefined;\n const legacyRateLimit = typeof data['rate_limit'] === 'number' ? data['rate_limit'] : undefined;\n\n return {\n ...data,\n api_rate_limit: apiRateLimit ?? legacyRateLimit ?? 0,\n vat_rate_limit: vatRateLimit ?? legacyRateLimit ?? 0,\n };\n}\n","import { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { normalizeCompanyResource, type CompanyResource } from '../dto/CompanyResource.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nexport class CompanyEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n async get(): Promise<CompanyResource> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n\n // Read-only, so transient gateway failures are retried (see RetryPolicy).\n return withRetries(this.retryPolicy, 'company request', async () => {\n const response = await this.httpClient.request('GET', `${this.baseUrl}/company`, { headers });\n const responseText = await response.text();\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && typeof obj['data'] === 'object' && obj['data'] !== null) {\n return normalizeCompanyResource(obj['data'] as Record<string, unknown>);\n }\n\n return normalizeCompanyResource(obj);\n });\n }\n}\n","export const ComplianceEnrollmentStatus = {\n PENDING_DATA: 'pending_data',\n ACCOUNT_CREATED: 'account_created',\n REGIME_ACTIVATED: 'regime_activated',\n READY: 'ready',\n SUSPENDED: 'suspended',\n ERROR_ACCOUNT: 'error_account',\n ERROR_ACTIVATION: 'error_activation',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceEnrollmentStatus = (typeof ComplianceEnrollmentStatus)[keyof typeof ComplianceEnrollmentStatus];\n\nconst VALUES: readonly string[] = Object.values(ComplianceEnrollmentStatus);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceEnrollmentStatus(value: unknown): ComplianceEnrollmentStatus {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceEnrollmentStatus;\n }\n }\n return ComplianceEnrollmentStatus.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceEnrollmentStatus, string> = {\n [ComplianceEnrollmentStatus.PENDING_DATA]: 'Awaiting merchant data before provisioning can start.',\n [ComplianceEnrollmentStatus.ACCOUNT_CREATED]: 'Provider account exists. Regime not yet activated.',\n [ComplianceEnrollmentStatus.REGIME_ACTIVATED]:\n 'Compliance regime activated at provider. Ready to submit transactions.',\n [ComplianceEnrollmentStatus.READY]: 'Enrollment fully active and reporting.',\n [ComplianceEnrollmentStatus.SUSPENDED]: 'Enrollment temporarily suspended.',\n [ComplianceEnrollmentStatus.ERROR_ACCOUNT]: 'Provider account creation failed.',\n [ComplianceEnrollmentStatus.ERROR_ACTIVATION]: 'Regime activation at provider failed.',\n [ComplianceEnrollmentStatus.UNKNOWN]: 'Unknown status.',\n};\n\nexport function describeComplianceEnrollmentStatus(status: ComplianceEnrollmentStatus): string {\n return DESCRIPTIONS[status];\n}\n","/**\n * The compliance service an enrollment books for its country: French DGFiP\n * e-reporting, or e-invoicing (e.g. Norway EHF / Peppol BIS 3.0). Each country\n * and service is unlocked and billed separately.\n */\nexport const ComplianceService = {\n E_REPORTING: 'e_reporting',\n E_INVOICING: 'e_invoicing',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceService = (typeof ComplianceService)[keyof typeof ComplianceService];\n\nconst VALUES: readonly string[] = Object.values(ComplianceService);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceService(value: unknown): ComplianceService {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceService;\n }\n }\n return ComplianceService.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceService, string> = {\n [ComplianceService.E_REPORTING]: 'E-reporting of transaction data to the tax authority (France: DGFiP Flux 10).',\n [ComplianceService.E_INVOICING]: 'Structured e-invoices delivered to the buyer (Norway: EHF / Peppol BIS 3.0).',\n [ComplianceService.UNKNOWN]: 'Unknown service.',\n};\n\nexport function describeComplianceService(service: ComplianceService): string {\n return DESCRIPTIONS[service];\n}\n","import { type ComplianceEnrollmentStatus, toComplianceEnrollmentStatus } from '../enums/ComplianceEnrollmentStatus.js';\nimport { ComplianceService, toComplianceService } from '../enums/ComplianceService.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\n/**\n * A compliance enrollment — the merchant's provisioned account for one country\n * and service (GET/POST /compliance/enrollments), e.g. France e-reporting\n * (regime \"dgfip_flux10\") or Norway e-invoicing (regime \"peppol_bis3\").\n */\nexport class ComplianceEnrollment {\n constructor(\n public readonly id: number,\n public readonly companyId: number,\n public readonly country: string,\n public readonly regime: string,\n public readonly provider: string,\n public readonly status: ComplianceEnrollmentStatus,\n public readonly statusLabel: string,\n public readonly statusError: string | null,\n public readonly providerAccountId: string | null,\n public readonly taxId: string | null,\n public readonly companyRegisterId: string | null,\n public readonly companyRegisterScheme: string | null,\n public readonly regimeConfig: Record<string, unknown> | null,\n /** First date transactions are reported for (YYYY-MM-DD). */\n public readonly reportingStartDate: string | null,\n public readonly notificationEmail: string | null,\n public readonly autoSend: boolean,\n public readonly createdAt: string | null,\n public readonly updatedAt: string | null,\n /** Booked service (\"e_reporting\" / \"e_invoicing\"); `unknown` when an older server omits it. */\n public readonly service: ComplianceService = ComplianceService.UNKNOWN,\n ) {}\n\n static fromArray(data: Record<string, unknown>): ComplianceEnrollment {\n const regimeConfig =\n typeof data['regime_config'] === 'object' &&\n data['regime_config'] !== null &&\n !Array.isArray(data['regime_config'])\n ? (data['regime_config'] as Record<string, unknown>)\n : null;\n\n return new ComplianceEnrollment(\n asNumber(data['id']),\n asNumber(data['company_id']),\n asString(data['country']),\n asString(data['regime']),\n asString(data['provider']),\n toComplianceEnrollmentStatus(data['status']),\n asString(data['status_label']),\n asNullableString(data['status_error']),\n asNullableString(data['provider_account_id']),\n asNullableString(data['tax_id']),\n asNullableString(data['company_register_id']),\n asNullableString(data['company_register_scheme']),\n regimeConfig,\n asNullableString(data['reporting_start_date']),\n asNullableString(data['notification_email']),\n data['auto_send'] === true,\n asNullableString(data['created_at']),\n asNullableString(data['updated_at']),\n toComplianceService(data['service']),\n );\n }\n}\n","import { ComplianceEnrollment } from './ComplianceEnrollment.js';\n\n/**\n * A paginated page of compliance enrollments (GET /compliance/enrollments).\n */\nexport class ComplianceEnrollmentPage implements Iterable<ComplianceEnrollment> {\n constructor(\n public readonly rows: ComplianceEnrollment[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n ) {}\n\n static fromResponse(payload: unknown): ComplianceEnrollmentPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(ComplianceEnrollment.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n return new ComplianceEnrollmentPage(\n rows,\n num(meta['current_page'], 1),\n num(meta['per_page'], rows.length),\n num(meta['total'], rows.length),\n num(meta['last_page'], 1),\n );\n }\n\n [Symbol.iterator](): Iterator<ComplianceEnrollment> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","export const ComplianceTaxReportState = {\n NEW: 'new',\n SENT: 'sent',\n ACKNOWLEDGED: 'acknowledged',\n REGISTERED: 'registered',\n REFUSED: 'refused',\n ERROR: 'error',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceTaxReportState = (typeof ComplianceTaxReportState)[keyof typeof ComplianceTaxReportState];\n\nconst VALUES: readonly string[] = Object.values(ComplianceTaxReportState);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceTaxReportState(value: unknown): ComplianceTaxReportState {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceTaxReportState;\n }\n }\n return ComplianceTaxReportState.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceTaxReportState, string> = {\n [ComplianceTaxReportState.NEW]: 'Created at provider, waiting for the daily ledger batch.',\n [ComplianceTaxReportState.SENT]: 'Ledger transmitted to PPF.',\n [ComplianceTaxReportState.ACKNOWLEDGED]: 'PPF acknowledged receipt of the ledger.',\n [ComplianceTaxReportState.REGISTERED]: 'Accepted by DGFiP (CDV 300).',\n [ComplianceTaxReportState.REFUSED]: 'Rejected by DGFiP (CDV 301).',\n [ComplianceTaxReportState.ERROR]: 'Transmission or PPF error.',\n [ComplianceTaxReportState.UNKNOWN]: 'Unknown state.',\n};\n\nexport function describeComplianceTaxReportState(state: ComplianceTaxReportState): string {\n return DESCRIPTIONS[state];\n}\n","import { type ComplianceTaxReportState, toComplianceTaxReportState } from '../enums/ComplianceTaxReportState.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\nfunction asNullableNumber(value: unknown): number | null {\n return typeof value === 'number' ? value : null;\n}\n\n/**\n * Monetary values are kept as the decimal strings returned by the API (no\n * Number conversion) to preserve precision.\n */\nfunction asMoney(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return '0.00';\n}\n\n/**\n * A DGFiP tax report tracking one transaction through the aggregated daily\n * ledger lifecycle (GET /compliance/tax-reports).\n */\nexport class ComplianceTaxReport {\n constructor(\n public readonly id: number,\n public readonly companyId: number,\n public readonly complianceTransactionId: number | null,\n public readonly ledgerId: number | null,\n public readonly country: string,\n public readonly regime: string,\n public readonly state: ComplianceTaxReportState,\n public readonly stateLabel: string,\n /** True once the report reached a final state (registered, refused or error). */\n public readonly isTerminal: boolean,\n public readonly providerTaxReportId: string | null,\n public readonly providerLedgerId: string | null,\n public readonly baseAmount: string,\n public readonly taxAmount: string,\n public readonly totalAmount: string,\n public readonly refusalReason: string | null,\n public readonly registeredAt: string | null,\n public readonly refusedAt: string | null,\n public readonly createdAt: string | null,\n public readonly updatedAt: string | null,\n ) {}\n\n static fromArray(data: Record<string, unknown>): ComplianceTaxReport {\n return new ComplianceTaxReport(\n asNumber(data['id']),\n asNumber(data['company_id']),\n asNullableNumber(data['compliance_transaction_id']),\n asNullableNumber(data['ledger_id']),\n asString(data['country']),\n asString(data['regime']),\n toComplianceTaxReportState(data['state']),\n asString(data['state_label']),\n data['is_terminal'] === true,\n asNullableString(data['provider_tax_report_id']),\n asNullableString(data['provider_ledger_id']),\n asMoney(data['base_amount']),\n asMoney(data['tax_amount']),\n asMoney(data['total_amount']),\n asNullableString(data['refusal_reason']),\n asNullableString(data['registered_at']),\n asNullableString(data['refused_at']),\n asNullableString(data['created_at']),\n asNullableString(data['updated_at']),\n );\n }\n}\n","import { ComplianceTaxReport } from './ComplianceTaxReport.js';\n\n/**\n * A paginated page of compliance tax reports (GET /compliance/tax-reports).\n */\nexport class ComplianceTaxReportPage implements Iterable<ComplianceTaxReport> {\n constructor(\n public readonly rows: ComplianceTaxReport[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n ) {}\n\n static fromResponse(payload: unknown): ComplianceTaxReportPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(ComplianceTaxReport.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n return new ComplianceTaxReportPage(\n rows,\n num(meta['current_page'], 1),\n num(meta['per_page'], rows.length),\n num(meta['total'], rows.length),\n num(meta['last_page'], 1),\n );\n }\n\n [Symbol.iterator](): Iterator<ComplianceTaxReport> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","/** Kind of document a compliance transaction represents. */\nexport const ComplianceDocumentType = {\n INVOICE: 'invoice',\n CREDIT_NOTE: 'credit_note',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceDocumentType = (typeof ComplianceDocumentType)[keyof typeof ComplianceDocumentType];\n\nconst VALUES: readonly string[] = Object.values(ComplianceDocumentType);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceDocumentType(value: unknown): ComplianceDocumentType {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceDocumentType;\n }\n }\n return ComplianceDocumentType.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceDocumentType, string> = {\n [ComplianceDocumentType.INVOICE]: 'Commercial invoice.',\n [ComplianceDocumentType.CREDIT_NOTE]: 'Credit note correcting a previously issued invoice.',\n [ComplianceDocumentType.UNKNOWN]: 'Unknown document type.',\n};\n\nexport function describeComplianceDocumentType(type: ComplianceDocumentType): string {\n return DESCRIPTIONS[type];\n}\n","export const ComplianceTransactionState = {\n PENDING: 'pending',\n SENDING: 'sending',\n SUBMITTED: 'submitted',\n ERROR: 'error',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceTransactionState = (typeof ComplianceTransactionState)[keyof typeof ComplianceTransactionState];\n\nconst VALUES: readonly string[] = Object.values(ComplianceTransactionState);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceTransactionState(value: unknown): ComplianceTransactionState {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceTransactionState;\n }\n }\n return ComplianceTransactionState.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceTransactionState, string> = {\n [ComplianceTransactionState.PENDING]: 'Recorded locally, not yet submitted to the provider.',\n [ComplianceTransactionState.SENDING]: 'Submission to the provider in progress.',\n [ComplianceTransactionState.SUBMITTED]: 'Successfully submitted to the provider.',\n [ComplianceTransactionState.ERROR]: 'Submission failed. See submissionError.',\n [ComplianceTransactionState.UNKNOWN]: 'Unknown state.',\n};\n\nexport function describeComplianceTransactionState(state: ComplianceTransactionState): string {\n return DESCRIPTIONS[state];\n}\n","export const ComplianceTransactionType = {\n B2C_OUTBOUND: 'b2c_outbound',\n B2B_DOMESTIC_OUTBOUND: 'b2b_domestic_outbound',\n B2B_DOMESTIC_INBOUND: 'b2b_domestic_inbound',\n CROSSBORDER_OUTBOUND: 'crossborder_outbound',\n CROSSBORDER_INBOUND: 'crossborder_inbound',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type ComplianceTransactionType = (typeof ComplianceTransactionType)[keyof typeof ComplianceTransactionType];\n\nconst VALUES: readonly string[] = Object.values(ComplianceTransactionType);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toComplianceTransactionType(value: unknown): ComplianceTransactionType {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as ComplianceTransactionType;\n }\n }\n return ComplianceTransactionType.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<ComplianceTransactionType, string> = {\n [ComplianceTransactionType.B2C_OUTBOUND]: 'Sale to a private person in the merchant country (DGFiP Flux 10.3).',\n [ComplianceTransactionType.B2B_DOMESTIC_OUTBOUND]: 'Sale to a domestic business (DGFiP Flux 1, Phase 2).',\n [ComplianceTransactionType.B2B_DOMESTIC_INBOUND]: 'Purchase from a domestic business (DGFiP Flux 1, Phase 2).',\n [ComplianceTransactionType.CROSSBORDER_OUTBOUND]: 'Sale to a non-domestic business (DGFiP Flux 10.1).',\n [ComplianceTransactionType.CROSSBORDER_INBOUND]: 'Purchase from a non-domestic supplier (DGFiP Flux 10.1).',\n [ComplianceTransactionType.UNKNOWN]: 'Unknown transaction type.',\n};\n\nexport function describeComplianceTransactionType(type: ComplianceTransactionType): string {\n return DESCRIPTIONS[type];\n}\n","import { ComplianceTaxReport } from './ComplianceTaxReport.js';\nimport { ComplianceDocumentType, toComplianceDocumentType } from '../enums/ComplianceDocumentType.js';\nimport { type ComplianceTransactionState, toComplianceTransactionState } from '../enums/ComplianceTransactionState.js';\nimport { type ComplianceTransactionType, toComplianceTransactionType } from '../enums/ComplianceTransactionType.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\n/**\n * Monetary values are kept as the decimal strings returned by the API (no\n * Number conversion) to preserve precision.\n */\nfunction asMoney(value: unknown): string {\n if (typeof value === 'string') return value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n return '0.00';\n}\n\nfunction asNullableNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '' && Number.isFinite(Number(value))) return Number(value);\n return null;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction asRecordList(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value) ? value.filter((row): row is Record<string, unknown> => asRecord(row) !== null) : [];\n}\n\n/** One tax of a stored invoice line (provider shape, as recorded at creation/update). */\nexport interface ComplianceTransactionInvoiceLineTax {\n name: string;\n percent: number | null;\n category: string | null;\n /** VATEX exemption code for category \"E\". */\n comment: string | null;\n}\n\n/** One stored invoice line (`provider_payload.invoice.invoice_lines_attributes`). */\nexport interface ComplianceTransactionInvoiceLine {\n description: string;\n quantity: number | null;\n /** Unit price as a precision-safe decimal string. */\n price: string;\n /** UN/ECE unit code, e.g. 9 (each). */\n unit: number | null;\n taxes: ComplianceTransactionInvoiceLineTax[];\n}\n\nfunction toInvoiceLines(providerPayload: unknown): ComplianceTransactionInvoiceLine[] {\n const invoice = asRecord(asRecord(providerPayload)?.['invoice']);\n\n return asRecordList(invoice?.['invoice_lines_attributes']).map((line) => ({\n description: asString(line['description']),\n quantity: asNullableNumber(line['quantity']),\n price: asMoney(line['price']),\n unit: asNullableNumber(line['unit']),\n taxes: asRecordList(line['taxes_attributes']).map((tax) => ({\n name: asString(tax['name']),\n percent: asNullableNumber(tax['percent']),\n category: asNullableString(tax['category']),\n comment: asNullableString(tax['comment']),\n })),\n }));\n}\n\n/**\n * A recorded compliance transaction (GET/POST /compliance/transactions) — an\n * e-reported transaction (France) or an e-invoice / credit note (Norway).\n *\n * The e-invoicing fields at the end of the constructor are optional so DTOs\n * built from older servers (or by hand) stay valid.\n */\nexport class ComplianceTransaction {\n constructor(\n public readonly id: number,\n public readonly companyId: number,\n public readonly complianceEnrollmentId: number,\n public readonly country: string,\n public readonly regime: string,\n public readonly transactionType: ComplianceTransactionType,\n public readonly transactionTypeLabel: string,\n public readonly state: ComplianceTransactionState,\n public readonly stateLabel: string,\n public readonly invoiceNumber: string,\n /** Invoice date (YYYY-MM-DD). */\n public readonly invoiceDate: string | null,\n public readonly dueDate: string | null,\n public readonly currency: string,\n public readonly subtotal: string,\n public readonly taxAmount: string,\n public readonly total: string,\n public readonly counterpartyName: string | null,\n public readonly counterpartyCountry: string | null,\n public readonly counterpartyVatNumber: string | null,\n public readonly isPaid: boolean,\n public readonly paidAt: string | null,\n public readonly providerInvoiceId: string | null,\n public readonly submissionError: string | null,\n public readonly reportedAt: string | null,\n /** Associated DGFiP tax report; undefined when the API did not include it. */\n public readonly taxReport: ComplianceTaxReport | undefined,\n public readonly createdAt: string | null,\n public readonly updatedAt: string | null,\n /** Buyer's company register id (Norway: 9-digit organisation number). */\n public readonly counterpartyRegisterId: string | null = null,\n public readonly counterpartyAddress: string | null = null,\n public readonly counterpartyCity: string | null = null,\n public readonly counterpartyPostalcode: string | null = null,\n public readonly counterpartyEmail: string | null = null,\n public readonly buyerReference: string | null = null,\n /** \"invoice\" or \"credit_note\" (older servers without the field → \"invoice\"). */\n public readonly documentType: ComplianceDocumentType = ComplianceDocumentType.INVOICE,\n /** Number of the invoice a credit note corrects. */\n public readonly amendedNumber: string | null = null,\n /** Date of the invoice a credit note corrects (YYYY-MM-DD). */\n public readonly amendedDate: string | null = null,\n /**\n * Latest provider-side delivery state (e.g. \"sent\", \"accepted\", \"refused\",\n * \"paid\") — richer than `state` for e-invoicing, where delivery continues\n * after submission. Free-form string; null until the provider reports one.\n */\n public readonly providerState: string | null = null,\n /** The stored invoice lines (empty when the server does not include them). */\n public readonly invoiceLines: ComplianceTransactionInvoiceLine[] = [],\n ) {}\n\n get isCreditNote(): boolean {\n return this.documentType === ComplianceDocumentType.CREDIT_NOTE;\n }\n\n static fromArray(data: Record<string, unknown>): ComplianceTransaction {\n const taxReport =\n typeof data['tax_report'] === 'object' && data['tax_report'] !== null && !Array.isArray(data['tax_report'])\n ? ComplianceTaxReport.fromArray(data['tax_report'] as Record<string, unknown>)\n : undefined;\n\n return new ComplianceTransaction(\n asNumber(data['id']),\n asNumber(data['company_id']),\n asNumber(data['compliance_enrollment_id']),\n asString(data['country']),\n asString(data['regime']),\n toComplianceTransactionType(data['transaction_type']),\n asString(data['transaction_type_label']),\n toComplianceTransactionState(data['state']),\n asString(data['state_label']),\n asString(data['invoice_number']),\n asNullableString(data['invoice_date']),\n asNullableString(data['due_date']),\n asString(data['currency'], 'EUR'),\n asMoney(data['subtotal']),\n asMoney(data['tax_amount']),\n asMoney(data['total']),\n asNullableString(data['counterparty_name']),\n asNullableString(data['counterparty_country']),\n asNullableString(data['counterparty_vat_number']),\n data['is_paid'] === true,\n asNullableString(data['paid_at']),\n asNullableString(data['provider_invoice_id']),\n asNullableString(data['submission_error']),\n asNullableString(data['reported_at']),\n taxReport,\n asNullableString(data['created_at']),\n asNullableString(data['updated_at']),\n asNullableString(data['counterparty_register_id']),\n asNullableString(data['counterparty_address']),\n asNullableString(data['counterparty_city']),\n asNullableString(data['counterparty_postalcode']),\n asNullableString(data['counterparty_email']),\n asNullableString(data['buyer_reference']),\n data['document_type'] === undefined || data['document_type'] === null\n ? ComplianceDocumentType.INVOICE\n : toComplianceDocumentType(data['document_type']),\n asNullableString(data['amended_number']),\n asNullableString(data['amended_date']),\n asNullableString(data['provider_state']),\n toInvoiceLines(data['provider_payload']),\n );\n }\n}\n","import { ComplianceTransaction } from './ComplianceTransaction.js';\n\n/**\n * A paginated page of compliance transactions (GET /compliance/transactions).\n */\nexport class ComplianceTransactionPage implements Iterable<ComplianceTransaction> {\n constructor(\n public readonly rows: ComplianceTransaction[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n ) {}\n\n static fromResponse(payload: unknown): ComplianceTransactionPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(ComplianceTransaction.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n return new ComplianceTransactionPage(\n rows,\n num(meta['current_page'], 1),\n num(meta['per_page'], rows.length),\n num(meta['total'], rows.length),\n num(meta['last_page'], 1),\n );\n }\n\n [Symbol.iterator](): Iterator<ComplianceTransaction> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","/**\n * Result of a CSV transaction import (POST /compliance/transactions/import).\n */\nexport class ImportResult {\n constructor(\n /** Number of transactions created from the file. */\n public readonly created: number,\n /** Rows skipped because a matching transaction already exists (idempotent re-upload). */\n public readonly skippedDuplicates: number,\n /** Row-level errors, e.g. \"Row 3 (INV-1): invalid transaction_type 'x'\". */\n public readonly errors: string[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): ImportResult {\n const errors = (Array.isArray(data['errors']) ? (data['errors'] as unknown[]) : []).filter(\n (row): row is string => typeof row === 'string',\n );\n\n const num = (value: unknown): number => (typeof value === 'number' ? value : 0);\n\n return new ImportResult(num(data['created']), num(data['skipped_duplicates']), errors);\n }\n}\n","/**\n * Outcome of a Peppol directory lookup (GET /compliance/peppol-lookup). The\n * directory resolves asynchronously — `pending` means ask again in a few seconds.\n */\nexport const PeppolLookupStatus = {\n REACHABLE: 'reachable',\n NOT_REACHABLE: 'not_reachable',\n PENDING: 'pending',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type PeppolLookupStatus = (typeof PeppolLookupStatus)[keyof typeof PeppolLookupStatus];\n\nconst VALUES: readonly string[] = Object.values(PeppolLookupStatus);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toPeppolLookupStatus(value: unknown): PeppolLookupStatus {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as PeppolLookupStatus;\n }\n }\n return PeppolLookupStatus.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<PeppolLookupStatus, string> = {\n [PeppolLookupStatus.REACHABLE]: 'The participant is registered on Peppol and can receive e-invoices.',\n [PeppolLookupStatus.NOT_REACHABLE]: 'The participant is not registered on Peppol.',\n [PeppolLookupStatus.PENDING]: 'The directory lookup is still resolving — ask again in a few seconds.',\n [PeppolLookupStatus.UNKNOWN]: 'Unknown lookup status.',\n};\n\nexport function describePeppolLookupStatus(status: PeppolLookupStatus): string {\n return DESCRIPTIONS[status];\n}\n","import {\n type PeppolLookupStatus,\n PeppolLookupStatus as Status,\n toPeppolLookupStatus,\n} from '../enums/PeppolLookupStatus.js';\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * Whether a participant can receive e-invoices over Peppol\n * (GET /compliance/peppol-lookup). For Norway, `reachable === true` means the\n * buyer is registered in ELMA and must receive an EHF e-invoice.\n */\nexport class PeppolLookupResult {\n constructor(\n public readonly status: PeppolLookupStatus,\n /** null while the lookup is still `pending`. */\n public readonly reachable: boolean | null,\n public readonly country: string,\n /** Peppol identifier scheme, e.g. \"0192\" for Norwegian organisation numbers. */\n public readonly scheme: string,\n /** Participant identifier, e.g. the organisation number. */\n public readonly id: string,\n /** Peppol document types the participant accepts, e.g. \"xml.ubl.invoice.bis3\". */\n public readonly documentTypes: string[],\n public readonly transportTypeCode: string | null,\n public readonly checkedAt: string | null,\n ) {}\n\n /** True while the directory is still resolving — ask again in a few seconds. */\n get isPending(): boolean {\n return this.status === Status.PENDING;\n }\n\n static fromArray(data: Record<string, unknown>): PeppolLookupResult {\n const documentTypes = Array.isArray(data['document_types'])\n ? (data['document_types'] as unknown[]).filter((t): t is string => typeof t === 'string')\n : [];\n\n return new PeppolLookupResult(\n toPeppolLookupStatus(data['status']),\n typeof data['reachable'] === 'boolean' ? data['reachable'] : null,\n asString(data['country']),\n asString(data['scheme']),\n asString(data['id']),\n documentTypes,\n asNullableString(data['transport_type_code']),\n asNullableString(data['checked_at']),\n );\n }\n}\n","function asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * A company from a national company register (GET /compliance/registry-lookup) —\n * for Norway the Brønnøysund Enhetsregisteret. Maps onto the Norway enrollment\n * input and the buyer fields of a Norwegian e-invoice.\n */\nexport class RegistryCompany {\n constructor(\n /** 9-digit Norwegian organisation number. */\n public readonly orgNumber: string,\n public readonly companyName: string,\n /** Legal form, e.g. \"AS\" or \"ASA\". */\n public readonly organisationForm: string | null,\n /** Registered for VAT (Merverdiavgiftsregisteret). */\n public readonly vatRegistered: boolean,\n /** \"NO…MVA\" VAT number; null when not VAT-registered. */\n public readonly vatNumber: string | null,\n /** Registered in Foretaksregisteret (adds \"Foretaksregisteret\" to invoices). */\n public readonly enterpriseRegister: boolean,\n public readonly bankrupt: boolean,\n public readonly underLiquidation: boolean,\n public readonly address: string | null,\n public readonly postalcode: string | null,\n public readonly city: string | null,\n /** 2-char ISO 3166-1 alpha-2 code, e.g. \"NO\". */\n public readonly country: string,\n ) {}\n\n static fromArray(data: Record<string, unknown>): RegistryCompany {\n return new RegistryCompany(\n asString(data['org_number']),\n asString(data['company_name']),\n asNullableString(data['organisation_form']),\n data['vat_registered'] === true,\n asNullableString(data['vat_number']),\n data['enterprise_register'] === true,\n data['bankrupt'] === true,\n data['under_liquidation'] === true,\n asNullableString(data['address']),\n asNullableString(data['postalcode']),\n asNullableString(data['city']),\n asString(data['country']),\n );\n }\n}\n","/**\n * DTOs for the e-reporting revenue statistics endpoint\n * (GET /compliance/revenue-statistics).\n *\n * Monetary values are kept as the 4-decimal strings returned by the API (no\n * Number conversion) to preserve precision. All headline figures are expressed\n * in `primaryCurrency`; when `isMultiCurrency` is true, `byCurrency` lists every\n * currency present in the range.\n */\n\nexport interface RevenueTotals {\n count: number;\n subtotal: string;\n taxAmount: string;\n total: string;\n}\n\nexport interface RevenueTimeBucket extends RevenueTotals {\n /** Period key: \"2026-01-15\" (day), \"2026-03\" (ISO year-week) or \"2026-01\" (month). */\n bucket: string;\n}\n\nexport interface RevenueTypeBreakdown {\n type: string;\n typeLabel: string;\n count: number;\n total: string;\n}\n\nexport interface RevenueCountryBreakdown {\n /** Counterparty country code; \"unknown\" groups transactions with no partner country. */\n country: string;\n count: number;\n total: string;\n}\n\nexport interface RevenueStateBreakdown {\n state: string;\n stateLabel: string;\n count: number;\n total: string;\n}\n\nexport interface RevenueCurrencyBreakdown extends RevenueTotals {\n currency: string;\n}\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\nfunction asMoney(value: unknown): string {\n return typeof value === 'string' ? value : '0.0000';\n}\n\nfunction asRecords(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null);\n}\n\nfunction toTotals(data: Record<string, unknown>): RevenueTotals {\n return {\n count: asNumber(data['count']),\n subtotal: asMoney(data['subtotal']),\n taxAmount: asMoney(data['tax_amount']),\n total: asMoney(data['total']),\n };\n}\n\nexport class RevenueStatistics {\n constructor(\n public readonly dateFrom: string | undefined,\n public readonly dateTo: string | undefined,\n public readonly interval: string | undefined,\n public readonly primaryCurrency: string,\n public readonly isMultiCurrency: boolean,\n public readonly totals: RevenueTotals,\n public readonly timeSeries: RevenueTimeBucket[],\n public readonly byType: RevenueTypeBreakdown[],\n public readonly byCountry: RevenueCountryBreakdown[],\n public readonly byState: RevenueStateBreakdown[],\n public readonly byCurrency: RevenueCurrencyBreakdown[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): RevenueStatistics {\n const range =\n typeof data['range'] === 'object' && data['range'] !== null ? (data['range'] as Record<string, unknown>) : {};\n\n const totals = toTotals(\n typeof data['totals'] === 'object' && data['totals'] !== null ? (data['totals'] as Record<string, unknown>) : {},\n );\n\n const timeSeries: RevenueTimeBucket[] = asRecords(data['time_series']).map((row) => ({\n bucket: asString(row['bucket']),\n ...toTotals(row),\n }));\n\n const byType: RevenueTypeBreakdown[] = asRecords(data['by_type']).map((row) => ({\n type: asString(row['type']),\n typeLabel: asString(row['type_label']),\n count: asNumber(row['count']),\n total: asMoney(row['total']),\n }));\n\n const byCountry: RevenueCountryBreakdown[] = asRecords(data['by_country']).map((row) => ({\n country: asString(row['country'], 'unknown'),\n count: asNumber(row['count']),\n total: asMoney(row['total']),\n }));\n\n const byState: RevenueStateBreakdown[] = asRecords(data['by_state']).map((row) => ({\n state: asString(row['state']),\n stateLabel: asString(row['state_label']),\n count: asNumber(row['count']),\n total: asMoney(row['total']),\n }));\n\n const byCurrency: RevenueCurrencyBreakdown[] = asRecords(data['by_currency']).map((row) => ({\n currency: asString(row['currency']),\n ...toTotals(row),\n }));\n\n return new RevenueStatistics(\n asString(range['date_from']) || undefined,\n asString(range['date_to']) || undefined,\n asString(range['interval']) || undefined,\n asString(data['primary_currency'], 'EUR'),\n data['is_multi_currency'] === true,\n totals,\n timeSeries,\n byType,\n byCountry,\n byState,\n byCurrency,\n );\n }\n}\n","function asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\n/**\n * Company data resolved from the French SIRENE registry\n * (GET /compliance/sirene-lookup). Maps 1:1 onto the createEnrollment input.\n */\nexport class SireneLookupResult {\n constructor(\n public readonly companyName: string,\n public readonly siren: string,\n public readonly siret: string | null,\n /** 2-digit NAF division, e.g. \"47\". */\n public readonly nafCode: string | null,\n /** Full NAF/APE code, e.g. \"47.11D\". */\n public readonly nafFull: string | null,\n /** Mapped enterprise size (\"micro\", \"pme\", \"eti\" or \"ge\"); null when unmappable. */\n public readonly enterpriseSize: string | null,\n public readonly address: string | null,\n public readonly city: string | null,\n public readonly postalcode: string | null,\n ) {}\n\n static fromArray(data: Record<string, unknown>): SireneLookupResult {\n return new SireneLookupResult(\n asString(data['company_name']),\n asString(data['siren']),\n asNullableString(data['siret']),\n asNullableString(data['naf_code']),\n asNullableString(data['naf_full']),\n asNullableString(data['enterprise_size']),\n asNullableString(data['address']),\n asNullableString(data['city']),\n asNullableString(data['postalcode']),\n );\n }\n}\n","/**\n * One VAT rate / DGFiP tax category offered for a reporting country.\n */\nexport interface VatRate {\n /** VAT percentage, e.g. 20 or 5.5. */\n percent: number;\n /** DGFiP tax category code (S/AA/AAA/K/G/AE/E/Z). */\n category: string;\n /** i18n key for the rate label, e.g. \"fr_standard\". */\n labelKey: string;\n /** Default tax designation prefilled into invoice lines, e.g. \"TVA\". */\n taxName: string;\n /** True when a VATEX exemption code is mandatory in the line's `comment` (category E). */\n requiresVatex: boolean;\n}\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\n/**\n * The canonical VAT rates & DGFiP tax categories for a reporting country\n * (GET /compliance/vat-rates).\n */\nexport class VatRates {\n constructor(\n public readonly country: string,\n public readonly currency: string,\n public readonly rates: VatRate[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): VatRates {\n const rates: VatRate[] = (Array.isArray(data['rates']) ? (data['rates'] as unknown[]) : [])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map((row) => ({\n percent: asNumber(row['percent']),\n category: asString(row['category']),\n labelKey: asString(row['label_key']),\n taxName: asString(row['tax_name']),\n requiresVatex: row['requires_vatex'] === true,\n }));\n\n return new VatRates(asString(data['country']), asString(data['currency'], 'EUR'), rates);\n }\n}\n","import { TaxoraException } from './TaxoraException.js';\n\nexport class ValidationException extends TaxoraException {\n public readonly statusCode = 422;\n private readonly errors: Record<string, string[]>;\n\n constructor(message: string, errors: Record<string, string[]>, context: Record<string, unknown> = {}) {\n super(message, context);\n this.name = 'ValidationException';\n this.errors = errors;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n getErrors(): Record<string, string[]> {\n return this.errors;\n }\n}\n","const WEIGHTS = [3, 2, 7, 6, 5, 4, 3, 2] as const;\n\n/**\n * Norwegian organisation number (organisasjonsnummer): 9 digits, the last one a\n * modulus-11 check digit (weights 3,2,7,6,5,4,3,2). It is also the Peppol\n * participant identifier under scheme 0192 and — with the \"NO\" prefix and \"MVA\"\n * suffix — the Norwegian VAT number.\n *\n * Mirrors the backend's validation, so invalid numbers are rejected before a\n * request is sent.\n */\nexport const NorwegianOrgNumber = {\n /** Peppol identifier scheme for Norwegian organisation numbers. */\n PEPPOL_SCHEME: '0192',\n\n /**\n * Strips whitespace, dots, dashes, a \"0192:\" Peppol scheme prefix, the \"NO\"\n * prefix and the \"MVA\" suffix: \"NO 923 609 016 MVA\", \"923609016MVA\" and\n * \"923 609 016\" all become \"923609016\". Does not validate.\n */\n normalize(value: string | null | undefined): string {\n let v = (value ?? '')\n .trim()\n .toUpperCase()\n .replace(/[\\s.-]/g, '');\n\n if (v.startsWith('0192:')) v = v.slice(5);\n if (v.startsWith('NO')) v = v.slice(2);\n if (v.endsWith('MVA')) v = v.slice(0, -3);\n\n return v;\n },\n\n /** True when the (normalized) value is 9 digits with a valid mod-11 check digit. */\n isValid(value: string | null | undefined): boolean {\n const digits = NorwegianOrgNumber.normalize(value);\n if (!/^\\d{9}$/.test(digits)) return false;\n\n let sum = 0;\n for (let i = 0; i < WEIGHTS.length; i++) {\n sum += Number(digits[i]) * WEIGHTS[i]!;\n }\n\n let check = 11 - (sum % 11);\n if (check === 11) check = 0;\n\n // Remainder 1 → check digit 10 is impossible; such numbers are never issued.\n return check !== 10 && check === Number(digits[8]);\n },\n\n /** \"NO923609016MVA\" — the Norwegian VAT number of an MVA-registered entity. Does not validate. */\n toVatNumber(value: string): string {\n return `NO${NorwegianOrgNumber.normalize(value)}MVA`;\n },\n} as const;\n","import { ComplianceEnrollment } from '../dto/ComplianceEnrollment.js';\nimport { ComplianceEnrollmentPage } from '../dto/ComplianceEnrollmentPage.js';\nimport { ComplianceTaxReport } from '../dto/ComplianceTaxReport.js';\nimport { ComplianceTaxReportPage } from '../dto/ComplianceTaxReportPage.js';\nimport { ComplianceTransaction } from '../dto/ComplianceTransaction.js';\nimport { ComplianceTransactionPage } from '../dto/ComplianceTransactionPage.js';\nimport { ImportResult } from '../dto/ImportResult.js';\nimport { PeppolLookupResult } from '../dto/PeppolLookupResult.js';\nimport { RegistryCompany } from '../dto/RegistryCompany.js';\nimport { RevenueStatistics } from '../dto/RevenueStatistics.js';\nimport { SireneLookupResult } from '../dto/SireneLookupResult.js';\nimport { VatRates } from '../dto/VatRates.js';\nimport { type ComplianceService } from '../enums/ComplianceService.js';\nimport { type ComplianceTaxReportState } from '../enums/ComplianceTaxReportState.js';\nimport { type ComplianceTransactionState } from '../enums/ComplianceTransactionState.js';\nimport { type ComplianceTransactionType } from '../enums/ComplianceTransactionType.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError } from '../exceptions/apiErrorMessage.js';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport { ValidationException } from '../exceptions/ValidationException.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withResponseRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\nimport { NorwegianOrgNumber } from '../support/NorwegianOrgNumber.js';\n\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst NAF_CODE_REGEX = /^\\d{2}$/;\nconst COUNTRY_REGEX = /^[A-Za-z]{2}$/;\nconst PEPPOL_SCHEME_REGEX = /^\\d{4}$/;\n\n/** Time-series bucket size accepted by the revenue statistics endpoint. */\nexport type EReportingInterval = 'day' | 'week' | 'month';\n\n/** Enterprise size categories accepted by the DGFiP enrollment. */\nexport type ComplianceEnterpriseSize = 'micro' | 'pme' | 'eti' | 'ge';\n\n/** Type of operations the enrolled company performs. */\nexport type ComplianceTypeOperation = 'services' | 'goods' | 'mixed';\n\n/** Services accepted on the request side (the tolerant `unknown` is response-only). */\nexport type ComplianceRequestService = Exclude<ComplianceService, 'unknown'>;\n\n/** Transaction types accepted on the request side (the tolerant `unknown` is response-only). */\nexport type ComplianceTransactionRequestType = Exclude<ComplianceTransactionType, 'unknown'>;\n\n/** Transaction states accepted as filters (the tolerant `unknown` is response-only). */\nexport type ComplianceTransactionRequestState = Exclude<ComplianceTransactionState, 'unknown'>;\n\n/** Tax report states accepted as filters (the tolerant `unknown` is response-only). */\nexport type ComplianceTaxReportRequestState = Exclude<ComplianceTaxReportState, 'unknown'>;\n\nconst INTERVALS: readonly EReportingInterval[] = ['day', 'week', 'month'];\nconst SERVICES: readonly ComplianceRequestService[] = ['e_reporting', 'e_invoicing'];\nconst ENTERPRISE_SIZES: readonly ComplianceEnterpriseSize[] = ['micro', 'pme', 'eti', 'ge'];\nconst TYPE_OPERATIONS: readonly ComplianceTypeOperation[] = ['services', 'goods', 'mixed'];\nconst TRANSACTION_TYPES: readonly ComplianceTransactionRequestType[] = [\n 'b2c_outbound',\n 'b2b_domestic_outbound',\n 'b2b_domestic_inbound',\n 'crossborder_outbound',\n 'crossborder_inbound',\n];\n\nexport interface RevenueStatisticsFilters {\n dateFrom?: Date | string;\n dateTo?: Date | string;\n /** Time-series bucket size. Defaults to \"month\" server-side. */\n interval?: EReportingInterval;\n transactionType?: ComplianceTransactionRequestType;\n state?: ComplianceTransactionRequestState;\n}\n\n/**\n * France (DGFiP e-reporting) enrollment — the original createEnrollment() input.\n * For Norway use {@link CreateNorwayEnrollmentInput} (or createNorwayEnrollment()).\n */\nexport interface CreateComplianceEnrollmentInput {\n /** Reporting country (2-char ISO 3166-1 alpha-2). Defaults server-side (FR). \"NO\" selects the Norway input. */\n country?: string;\n /** Service to book. Defaults server-side to the country's default service (FR: \"e_reporting\"). */\n service?: ComplianceRequestService;\n /** Compliance regime, e.g. \"dgfip_flux10\". Defaults server-side. */\n regime?: string;\n /** 14-digit SIRET. Required unless `siren` is set. */\n siret?: string;\n /** 9-digit SIREN. Required unless `siret` is set. */\n siren?: string;\n vatNumber?: string;\n companyName?: string;\n address?: string;\n city?: string;\n postalcode?: string;\n province?: string;\n /** Notification email for the provider account. */\n email: string;\n /** 2-digit NAF division, e.g. \"47\". */\n nafCode: string;\n enterpriseSize: ComplianceEnterpriseSize;\n typeOperation: ComplianceTypeOperation;\n /** First date transactions are reported for (Date or strict YYYY-MM-DD). */\n reportingStartDate: Date | string;\n /** When false, only the provider account is created — the DGFiP regime is NOT activated. Defaults to true server-side. */\n autoActivate?: boolean;\n}\n\n/**\n * Norway e-invoicing (EHF / Peppol BIS 3.0) enrollment: registers the company\n * as a Peppol participant so it can send (and optionally receive) e-invoices.\n * Prefill it from registryLookup('NO', …).\n */\nexport interface CreateNorwayEnrollmentInput {\n country: 'NO';\n /** Service to book. Defaults server-side to \"e_invoicing\" (the only service for NO). */\n service?: ComplianceRequestService;\n /** Compliance regime. Defaults server-side (\"peppol_bis3\"). */\n regime?: string;\n /**\n * 9-digit Norwegian organisation number (mod-11 check digit). Spaces, a \"NO\"\n * prefix and an \"MVA\" suffix are accepted and stripped before sending.\n */\n orgNumber: string;\n companyName: string;\n address: string;\n city: string;\n postalcode: string;\n /** Notification email for the provider account. */\n email: string;\n vatNumber?: string;\n province?: string;\n /** Registered in Merverdiavgiftsregisteret (adds \"MVA\" to invoices). Defaults to true server-side. */\n vatRegistered?: boolean;\n /** Registered in Foretaksregisteret (adds \"Foretaksregisteret\" to invoices). Defaults to false server-side. */\n enterpriseRegister?: boolean;\n /** Also register to RECEIVE e-invoices over Peppol. Defaults to false server-side. */\n reception?: boolean;\n /** Country of the legal entity when it differs from NO (2-char ISO 3166-1 alpha-2). */\n legalCountry?: string;\n /** Optional first date transactions are recorded for (Date or strict YYYY-MM-DD). */\n reportingStartDate?: Date | string;\n /** When false, only the provider account is created — the Peppol registration is NOT activated. Defaults to true server-side. */\n autoActivate?: boolean;\n}\n\n/** createNorwayEnrollment() input — the Norway input without the fixed `country`. */\nexport type NorwayEnrollmentInput = Omit<CreateNorwayEnrollmentInput, 'country'>;\n\nexport interface ComplianceInvoiceTaxInput {\n /** Tax designation, e.g. \"TVA\". */\n name: string;\n /** VAT percentage, e.g. 20 or 5.5. */\n percent: number;\n /** DGFiP tax category code (S/AA/AAA/K/G/AE/E/Z) — see getVatRates(). */\n category: string;\n /** VATEX exemption code; required when `category` is \"E\". */\n comment?: string;\n}\n\nexport interface ComplianceInvoiceLineInput {\n description: string;\n quantity: number;\n price: number;\n /** UN/ECE unit code, e.g. 9 (each). */\n unit?: number;\n /** At least one tax per line. */\n taxes: ComplianceInvoiceTaxInput[];\n}\n\n/**\n * Buyer and document fields interpreted per country. For Norway (EHF / Peppol)\n * `counterpartyRegisterId` (the buyer's organisation number) and\n * `counterpartyName` are required unless `providerContactId` is set, the\n * transaction type must be \"b2b_domestic_outbound\", and a credit note needs\n * `amendedNumber`. The SDK does not know the enrollment's country — those rules\n * are enforced server-side (422).\n */\nexport interface ComplianceTransactionBuyerInput {\n /** Buyer's company register id (Norway: 9-digit organisation number; \"NO…MVA\" is accepted). Max 30 chars. */\n counterpartyRegisterId?: string;\n counterpartyAddress?: string;\n counterpartyCity?: string;\n counterpartyPostalcode?: string;\n /** Buyer's email address. */\n counterpartyEmail?: string;\n /** Buyer reference (Peppol BuyerReference); max 100 chars. Norway defaults it to the buyer's org number. */\n buyerReference?: string;\n /** Issue the document as a credit note. */\n isCreditNote?: boolean;\n /** Number of the invoice a credit note corrects (max 50 chars). */\n amendedNumber?: string;\n /** Date of the invoice a credit note corrects (Date or strict YYYY-MM-DD). */\n amendedDate?: Date | string;\n /** Free-text note printed on the invoice (max 1000 chars). */\n extraInfo?: string;\n}\n\nexport interface CreateComplianceTransactionInput extends ComplianceTransactionBuyerInput {\n complianceEnrollmentId: number;\n transactionType: ComplianceTransactionRequestType;\n invoiceNumber: string;\n /** Invoice date (Date or strict YYYY-MM-DD). */\n invoiceDate: Date | string;\n subtotal: number;\n total: number;\n /** At least one invoice line, each with at least one tax. */\n invoiceLines: ComplianceInvoiceLineInput[];\n dueDate?: Date | string;\n /** 3-char ISO 4217 code. Defaults to EUR server-side. */\n currency?: string;\n taxAmount?: number;\n counterpartyName?: string;\n /** 2-char ISO 3166-1 alpha-2 code. */\n counterpartyCountry?: string;\n counterpartyVatNumber?: string;\n providerContactId?: string;\n /** Payment means code; required for cross-border outbound. */\n paymentMethod?: number;\n remittanceInformation?: string;\n paymentMethodText?: string;\n paymentTerms?: string;\n /** When false, the transaction is only recorded — submission is deferred. Defaults to true server-side. */\n submitNow?: boolean;\n}\n\nexport interface UpdateComplianceTransactionInput extends ComplianceTransactionBuyerInput {\n transactionType?: ComplianceTransactionRequestType;\n invoiceNumber?: string;\n invoiceDate?: Date | string;\n dueDate?: Date | string;\n /** 3-char ISO 4217 code. */\n currency?: string;\n subtotal?: number;\n taxAmount?: number;\n total?: number;\n counterpartyName?: string;\n /** 2-char ISO 3166-1 alpha-2 code. */\n counterpartyCountry?: string;\n counterpartyVatNumber?: string;\n providerContactId?: string;\n /** When set: at least one invoice line, each with at least one tax. */\n invoiceLines?: ComplianceInvoiceLineInput[];\n paymentMethod?: number;\n remittanceInformation?: string;\n paymentMethodText?: string;\n paymentTerms?: string;\n}\n\nexport interface ComplianceTransactionFilters {\n /** Inclusive lower bound on the invoice date (Date or strict YYYY-MM-DD). */\n dateFrom?: Date | string;\n /** Inclusive upper bound on the invoice date (Date or strict YYYY-MM-DD). */\n dateTo?: Date | string;\n state?: ComplianceTransactionRequestState;\n transactionType?: ComplianceTransactionRequestType;\n /** Only transactions of this enrollment. */\n complianceEnrollmentId?: number;\n /** Only transactions of this country (2-char ISO 3166-1 alpha-2). */\n country?: string;\n page?: number;\n /** Page size (1-100, default 25 server-side). */\n perPage?: number;\n}\n\nexport interface EReportingAccessRequestInput {\n name?: string;\n email?: string;\n company?: string;\n phone?: string;\n message?: string;\n /** Locale for the confirmation mail, e.g. \"de\" or \"en\". */\n language?: string;\n /** The service being requested. Defaults server-side to \"e_reporting\". */\n service?: ComplianceRequestService;\n /** The countries the service is requested for (2-char ISO codes), e.g. [\"NO\"]. */\n countries?: string[];\n}\n\n/**\n * E-Reporting / Compliance endpoints (per-country services).\n *\n * - France — e-reporting (DGFiP Flux 10): sireneLookup() to prefill company\n * data, createEnrollment() to provision the provider account, then\n * createTransaction() / importTransactions() to record invoices and\n * listTaxReports() to track their DGFiP lifecycle.\n * - Norway — e-invoicing (EHF / Peppol BIS 3.0): registryLookup('NO', …) to\n * prefill company/buyer data, createNorwayEnrollment() to register as a Peppol\n * participant, peppolLookup('NO', …) to check a buyer is reachable, then\n * createTransaction() to send invoices and credit notes.\n *\n * Each country/service is unlocked (and billed) separately; enrolling for a\n * service the company does not have yields a 403 with code `service_not_active`.\n * All routes except requestEReportingAccess() require compliance access on the\n * account.\n */\nexport class EReportingEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n // ---------------------------------------------------------------------\n // Enrollments\n // ---------------------------------------------------------------------\n\n /**\n * Create a compliance enrollment and provision the provider account. By\n * default the country regime is activated right away (France: DGFiP tax\n * report setting; Norway: Peppol registration); pass `autoActivate: false`\n * to only create the account.\n *\n * The input shape depends on `country`: omitted/\"FR\" takes the France input\n * (unchanged, backwards compatible), \"NO\" the Norway input — see also the\n * createNorwayEnrollment() shortcut.\n *\n * Errors: 403 (HttpException, body code `service_not_active`) when the company\n * lacks the requested service; on provider failure 502 (HttpException) — the\n * enrollment is then persisted in `error_account`/`error_activation` state so\n * provisioning can be retried.\n */\n async createEnrollment(\n input: CreateComplianceEnrollmentInput | CreateNorwayEnrollmentInput,\n ): Promise<ComplianceEnrollment> {\n if (this.isNorwayEnrollmentInput(input)) {\n return this.createEnrollmentFromBody(this.buildNorwayEnrollmentBody(input));\n }\n\n this.validateEnrollmentInput(input);\n\n const body: Record<string, unknown> = {\n email: input.email,\n naf_code: input.nafCode,\n enterprise_size: input.enterpriseSize,\n type_operation: input.typeOperation,\n reporting_start_date: this.formatDate(input.reportingStartDate),\n };\n if (input.country !== undefined) body['country'] = input.country;\n if (input.service !== undefined) body['service'] = input.service;\n if (input.regime !== undefined) body['regime'] = input.regime;\n if (input.siret !== undefined) body['siret'] = input.siret;\n if (input.siren !== undefined) body['siren'] = input.siren;\n if (input.vatNumber !== undefined) body['vat_number'] = input.vatNumber;\n if (input.companyName !== undefined) body['company_name'] = input.companyName;\n if (input.address !== undefined) body['address'] = input.address;\n if (input.city !== undefined) body['city'] = input.city;\n if (input.postalcode !== undefined) body['postalcode'] = input.postalcode;\n if (input.province !== undefined) body['province'] = input.province;\n if (input.autoActivate !== undefined) body['auto_activate'] = input.autoActivate;\n\n return this.createEnrollmentFromBody(body);\n }\n\n /**\n * Enroll the company for Norway e-invoicing (EHF / Peppol BIS 3.0) — shortcut\n * for createEnrollment({ country: 'NO', ... }). The organisation number is\n * checked (mod-11) and normalized to 9 digits before sending.\n */\n async createNorwayEnrollment(input: NorwayEnrollmentInput): Promise<ComplianceEnrollment> {\n return this.createEnrollment({ ...input, country: 'NO' });\n }\n\n /** Paginated list of the company's enrollments (newest first). `perPage` is capped at 100 server-side. */\n async listEnrollments(page = 1, perPage = 25): Promise<ComplianceEnrollmentPage> {\n const params = new URLSearchParams();\n params.set('page', String(page));\n params.set('per_page', String(perPage));\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/enrollments?${params.toString()}`);\n // Double envelope: { success, data: { data: [...], meta: {...} } } — parseJsonResponse\n // unwraps the outer `data`; fromResponse reads the inner rows + pagination meta.\n return ComplianceEnrollmentPage.fromResponse(await this.parseJsonResponse(response));\n }\n\n /** Get a single enrollment by id. */\n async getEnrollment(id: number): Promise<ComplianceEnrollment> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/enrollments/${id}`);\n const data = await this.parseJsonResponse(response);\n return ComplianceEnrollment.fromArray(data);\n }\n\n /**\n * Look up company data by SIRET, SIREN or French VAT number via the French\n * SIRENE registry — ideal for prefilling createEnrollment().\n *\n * Rate-limited to 3 requests/minute per user (protects the external French\n * government API); exceeding it yields a 429 (mapped to an HttpException).\n */\n async sireneLookup(q: string): Promise<SireneLookupResult> {\n if (q.trim() === '') {\n throw new TaxoraException('q must not be empty.');\n }\n\n const params = new URLSearchParams();\n params.set('q', q);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/sirene-lookup?${params.toString()}`);\n const data = await this.parseJsonResponse(response);\n return SireneLookupResult.fromArray(data);\n }\n\n /**\n * Look up companies in a national company register — currently Norway\n * (Brønnøysund Enhetsregisteret). `q` is an organisation number, a \"NO…MVA\"\n * VAT number or a company name; an exact number match yields one result.\n * Ideal for prefilling createNorwayEnrollment() and the buyer fields of an\n * e-invoice. For France use sireneLookup().\n *\n * Errors: 404 (HttpException) when nothing is found, 422 (ValidationException)\n * on invalid input / unsupported country, 429 (HttpException) when the\n * per-user rate limit (30/min) is exceeded.\n */\n async registryLookup(country: string, q: string): Promise<RegistryCompany[]> {\n const normalizedCountry = this.normalizeLookupCountry(country);\n const query = q.trim();\n if (query === '') {\n throw new TaxoraException('q must not be empty.');\n }\n if (normalizedCountry === 'NO') {\n const digits = NorwegianOrgNumber.normalize(query);\n if (/^\\d{9}$/.test(digits) && !NorwegianOrgNumber.isValid(digits)) {\n throw new TaxoraException(`Invalid Norwegian organisation number \"${query}\" (check digit).`);\n }\n }\n\n const params = new URLSearchParams();\n params.set('country', normalizedCountry);\n params.set('q', query);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/registry-lookup?${params.toString()}`);\n const data = await this.parseJsonResponse(response);\n const results = Array.isArray(data['results']) ? (data['results'] as unknown[]) : [];\n\n return results\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null && !Array.isArray(row))\n .map((row) => RegistryCompany.fromArray(row));\n }\n\n /**\n * Check whether a participant (typically the buyer) can receive e-invoices\n * over Peppol. For Norway pass the organisation number (scheme defaults to\n * \"0192\"): `reachable === true` means the buyer is registered in ELMA and must\n * receive an EHF e-invoice. The directory resolves asynchronously —\n * `status === 'pending'` (`reachable === null`) means ask again in a few\n * seconds. Free of charge; definite answers are cached for 24h server-side.\n *\n * A Norwegian organisation number is checked (mod-11) and normalized before\n * sending. Errors: 422 (ValidationException) on invalid input, 502\n * (HttpException) on provider failure.\n */\n async peppolLookup(country: string, id: string, scheme?: string): Promise<PeppolLookupResult> {\n const normalizedCountry = this.normalizeLookupCountry(country);\n let participantId = id.trim();\n if (participantId === '') {\n throw new TaxoraException('id must not be empty.');\n }\n if (scheme !== undefined && !PEPPOL_SCHEME_REGEX.test(scheme)) {\n throw new TaxoraException('scheme must be a 4-digit Peppol identifier scheme, e.g. \"0192\".');\n }\n if (normalizedCountry === 'NO' && (scheme === undefined || scheme === NorwegianOrgNumber.PEPPOL_SCHEME)) {\n if (!NorwegianOrgNumber.isValid(participantId)) {\n throw new TaxoraException(`Invalid Norwegian organisation number \"${participantId}\".`);\n }\n participantId = NorwegianOrgNumber.normalize(participantId);\n }\n\n const params = new URLSearchParams();\n params.set('country', normalizedCountry);\n params.set('id', participantId);\n if (scheme !== undefined) params.set('scheme', scheme);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/peppol-lookup?${params.toString()}`);\n const data = await this.parseJsonResponse(response);\n return PeppolLookupResult.fromArray(data);\n }\n\n // ---------------------------------------------------------------------\n // Transactions\n // ---------------------------------------------------------------------\n\n /**\n * Record and (by default) submit a Flux 10 transaction. Pass `submitNow: false`\n * to only record it — submission can be triggered later via submitTransaction().\n *\n * Immediate per-invoice submission requires the e-invoicing feature on the\n * account; in pure e-reporting mode the transaction is only recorded and\n * reported via the aggregated daily ledgers.\n *\n * Creation is idempotent on the invoice's natural key (enrollment, type,\n * invoice number, invoice date, counterparty VAT): a re-sent create returns\n * the existing transaction with HTTP 200 instead of creating a duplicate.\n *\n * On provider failure the API responds 502 (mapped to an HttpException).\n */\n async createTransaction(input: CreateComplianceTransactionInput): Promise<ComplianceTransaction> {\n this.validateId(input.complianceEnrollmentId, 'complianceEnrollmentId');\n this.validateTransactionType(input.transactionType);\n this.validateInvoiceNumber(input.invoiceNumber);\n this.validateInvoiceLines(input.invoiceLines);\n this.validateOptionalCodes(input);\n this.validateBuyerFields(input);\n\n const body: Record<string, unknown> = {\n compliance_enrollment_id: input.complianceEnrollmentId,\n transaction_type: input.transactionType,\n invoice_number: input.invoiceNumber,\n invoice_date: this.formatDate(input.invoiceDate),\n subtotal: input.subtotal,\n total: input.total,\n invoice_lines_attributes: this.buildInvoiceLines(input.invoiceLines),\n };\n this.applyOptionalTransactionFields(body, input);\n if (input.submitNow !== undefined) body['submit_now'] = input.submitNow;\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/transactions`, body);\n // 201 = created, 200 = idempotent replay of an already-recorded invoice.\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /** Paginated list of the company's transactions (newest invoice date first), filterable by date / state / type / enrollment / country. */\n async listTransactions(filters: ComplianceTransactionFilters = {}): Promise<ComplianceTransactionPage> {\n if (filters.complianceEnrollmentId !== undefined) {\n this.validateId(filters.complianceEnrollmentId, 'complianceEnrollmentId');\n }\n if (filters.country !== undefined && !COUNTRY_REGEX.test(filters.country)) {\n throw new TaxoraException('country must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n\n const params = new URLSearchParams();\n if (filters.dateFrom !== undefined) params.set('date_from', this.formatDate(filters.dateFrom));\n if (filters.dateTo !== undefined) params.set('date_to', this.formatDate(filters.dateTo));\n if (filters.state !== undefined) params.set('state', filters.state);\n if (filters.transactionType !== undefined) params.set('transaction_type', filters.transactionType);\n if (filters.complianceEnrollmentId !== undefined) {\n params.set('compliance_enrollment_id', String(filters.complianceEnrollmentId));\n }\n if (filters.country !== undefined) params.set('country', filters.country.toUpperCase());\n if (filters.page !== undefined) params.set('page', String(filters.page));\n if (filters.perPage !== undefined) params.set('per_page', String(filters.perPage));\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/compliance/transactions${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n return ComplianceTransactionPage.fromResponse(await this.parseJsonResponse(response));\n }\n\n /** Get a single transaction by id (includes its tax report when one exists). */\n async getTransaction(id: number): Promise<ComplianceTransaction> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/transactions/${id}`);\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /** Update a still-pending transaction. Only the provided fields are sent; already-submitted transactions are rejected with 422. */\n async updateTransaction(id: number, input: UpdateComplianceTransactionInput): Promise<ComplianceTransaction> {\n this.validateId(id, 'id');\n if (input.transactionType !== undefined) this.validateTransactionType(input.transactionType);\n if (input.invoiceNumber !== undefined) this.validateInvoiceNumber(input.invoiceNumber);\n if (input.invoiceLines !== undefined) this.validateInvoiceLines(input.invoiceLines);\n this.validateOptionalCodes(input);\n this.validateBuyerFields(input);\n\n const body: Record<string, unknown> = {};\n if (input.transactionType !== undefined) body['transaction_type'] = input.transactionType;\n if (input.invoiceNumber !== undefined) body['invoice_number'] = input.invoiceNumber;\n if (input.invoiceDate !== undefined) body['invoice_date'] = this.formatDate(input.invoiceDate);\n if (input.subtotal !== undefined) body['subtotal'] = input.subtotal;\n if (input.total !== undefined) body['total'] = input.total;\n if (input.invoiceLines !== undefined) body['invoice_lines_attributes'] = this.buildInvoiceLines(input.invoiceLines);\n this.applyOptionalTransactionFields(body, input);\n\n const response = await this.sendRequest('PUT', `${this.baseUrl}/compliance/transactions/${id}`, body);\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /** Delete a still-pending transaction. Already-submitted transactions are rejected with 422. */\n async deleteTransaction(id: number): Promise<void> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('DELETE', `${this.baseUrl}/compliance/transactions/${id}`);\n await this.assertNoContentResponse(response);\n }\n\n /**\n * Submit (or retry) an existing `pending`/`error` transaction to the provider.\n * Replays the invoice lines stored at creation, so they don't have to be re-sent.\n *\n * Requires the e-invoicing feature on the account — pure e-reporting customers\n * get a 422 (transactions are reported via the aggregated daily ledgers instead).\n *\n * On provider failure the API responds 502 (mapped to an HttpException);\n * already-submitted transactions are rejected with 422.\n */\n async submitTransaction(id: number): Promise<ComplianceTransaction> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/transactions/${id}/submit`);\n const data = await this.parseJsonResponse(response);\n return ComplianceTransaction.fromArray(data);\n }\n\n /**\n * Bulk-import transactions from a semicolon-separated CSV (one row per invoice\n * line; rows sharing an invoice_number are grouped into one transaction).\n * Required columns: invoice_number, invoice_date, transaction_type, subtotal,\n * total, line_description, line_quantity, line_price, tax_name, tax_percent,\n * tax_category.\n *\n * The import is idempotent: re-uploading the same file skips rows whose\n * invoice already exists (reported via `skippedDuplicates`).\n */\n async importTransactions(\n enrollmentId: number,\n csvContent: string,\n filename = 'transactions.csv',\n ): Promise<ImportResult> {\n this.validateId(enrollmentId, 'enrollmentId');\n if (csvContent.trim() === '') {\n throw new TaxoraException('csvContent must not be empty.');\n }\n\n const form = new FormData();\n form.set('compliance_enrollment_id', String(enrollmentId));\n form.set('file', new Blob([csvContent], { type: 'text/csv' }), filename);\n\n const response = await this.sendMultipartRequest('POST', `${this.baseUrl}/compliance/transactions/import`, form);\n const data = await this.parseJsonResponse(response);\n return ImportResult.fromArray(data);\n }\n\n // ---------------------------------------------------------------------\n // Analytics, configuration & reports\n // ---------------------------------------------------------------------\n\n /**\n * Aggregated turnover statistics for the authenticated company's e-reporting\n * transactions. All arguments are optional — the API defaults to the last 12\n * months and a monthly interval.\n */\n async getRevenueStatistics(filters: RevenueStatisticsFilters = {}): Promise<RevenueStatistics> {\n if (filters.interval !== undefined && !INTERVALS.includes(filters.interval)) {\n throw new TaxoraException(\n `Invalid statistics interval \"${String(filters.interval)}\". Expected one of: ${INTERVALS.join(', ')}.`,\n );\n }\n\n const params = new URLSearchParams();\n if (filters.dateFrom !== undefined) params.set('date_from', this.formatDate(filters.dateFrom));\n if (filters.dateTo !== undefined) params.set('date_to', this.formatDate(filters.dateTo));\n if (filters.interval !== undefined) params.set('interval', filters.interval);\n if (filters.transactionType !== undefined) params.set('transaction_type', filters.transactionType);\n if (filters.state !== undefined) params.set('state', filters.state);\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/compliance/revenue-statistics${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n\n return RevenueStatistics.fromArray(data);\n }\n\n /**\n * The canonical VAT rates & DGFiP tax categories for a reporting country\n * (the seller's reporting-country rates, not the counterparty's). Falls back\n * to the configured default country (FR) when none/unknown is given.\n */\n async getVatRates(country?: string): Promise<VatRates> {\n const params = new URLSearchParams();\n if (country !== undefined) params.set('country', country);\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/compliance/vat-rates${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n return VatRates.fromArray(data);\n }\n\n /** Paginated list of the company's tax reports (newest first), optionally filtered by state. */\n async listTaxReports(\n page = 1,\n perPage = 25,\n state?: ComplianceTaxReportRequestState,\n ): Promise<ComplianceTaxReportPage> {\n const params = new URLSearchParams();\n params.set('page', String(page));\n params.set('per_page', String(perPage));\n if (state !== undefined) params.set('state', state);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/tax-reports?${params.toString()}`);\n return ComplianceTaxReportPage.fromResponse(await this.parseJsonResponse(response));\n }\n\n /** Get a single tax report by id. */\n async getTaxReport(id: number): Promise<ComplianceTaxReport> {\n this.validateId(id, 'id');\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/compliance/tax-reports/${id}`);\n const data = await this.parseJsonResponse(response);\n return ComplianceTaxReport.fromArray(data);\n }\n\n /**\n * Request activation of the E-Reporting feature for the account. This route\n * is deliberately NOT gated by compliance access — it exists precisely for\n * accounts that do not have the feature yet. The authenticated user's\n * name/email take precedence over the form values server-side.\n *\n * Note: unlike the other compliance routes, validation failures here are\n * returned as HTTP 400 (surfaced as HttpException), not 422.\n */\n async requestEReportingAccess(input: EReportingAccessRequestInput = {}): Promise<void> {\n if (input.service !== undefined) this.validateService(input.service);\n if (input.countries !== undefined) {\n input.countries.forEach((country, index) => {\n if (!COUNTRY_REGEX.test(country)) {\n throw new TaxoraException(`countries[${index}] must be a 2-character ISO 3166-1 alpha-2 code.`);\n }\n });\n }\n\n const body: Record<string, unknown> = {};\n if (input.name !== undefined) body['name'] = input.name;\n if (input.email !== undefined) body['email'] = input.email;\n if (input.company !== undefined) body['company'] = input.company;\n if (input.phone !== undefined) body['phone'] = input.phone;\n if (input.message !== undefined) body['message'] = input.message;\n if (input.language !== undefined) body['language'] = input.language;\n if (input.service !== undefined) body['service'] = input.service;\n if (input.countries !== undefined) body['countries'] = input.countries.map((c) => c.toUpperCase());\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/e-reporting-request`, body);\n await this.parseJsonResponse(response);\n }\n\n // ---------------------------------------------------------------------\n // Input validation (fail fast, before any request is sent)\n // ---------------------------------------------------------------------\n\n private validateEnrollmentInput(input: CreateComplianceEnrollmentInput): void {\n if (input.siret === undefined && input.siren === undefined) {\n throw new TaxoraException('Either siret or siren is required.');\n }\n if (input.siret !== undefined && input.siret.length !== 14) {\n throw new TaxoraException('siret must be exactly 14 characters.');\n }\n if (input.siren !== undefined && input.siren.length !== 9) {\n throw new TaxoraException('siren must be exactly 9 characters.');\n }\n if (input.email.trim() === '' || !input.email.includes('@')) {\n throw new TaxoraException('email must be a valid email address.');\n }\n if (!NAF_CODE_REGEX.test(input.nafCode)) {\n throw new TaxoraException('nafCode must be exactly 2 digits, e.g. \"47\".');\n }\n if (!ENTERPRISE_SIZES.includes(input.enterpriseSize)) {\n throw new TaxoraException(\n `Invalid enterpriseSize \"${String(input.enterpriseSize)}\". Expected one of: ${ENTERPRISE_SIZES.join(', ')}.`,\n );\n }\n if (!TYPE_OPERATIONS.includes(input.typeOperation)) {\n throw new TaxoraException(\n `Invalid typeOperation \"${String(input.typeOperation)}\". Expected one of: ${TYPE_OPERATIONS.join(', ')}.`,\n );\n }\n if (input.country !== undefined && input.country.length !== 2) {\n throw new TaxoraException('country must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n if (input.service !== undefined) this.validateService(input.service);\n }\n\n private isNorwayEnrollmentInput(\n input: CreateComplianceEnrollmentInput | CreateNorwayEnrollmentInput,\n ): input is CreateNorwayEnrollmentInput {\n return typeof input.country === 'string' && input.country.trim().toUpperCase() === 'NO';\n }\n\n /** Validates the Norway input and builds its wire body (org number normalized to 9 digits). */\n private buildNorwayEnrollmentBody(input: CreateNorwayEnrollmentInput): Record<string, unknown> {\n if (typeof input.orgNumber !== 'string' || !NorwegianOrgNumber.isValid(input.orgNumber)) {\n throw new TaxoraException(\n 'orgNumber must be a valid 9-digit Norwegian organisation number (mod-11 check digit).',\n );\n }\n for (const field of ['companyName', 'address', 'city', 'postalcode'] as const) {\n if (typeof input[field] !== 'string' || input[field].trim() === '') {\n throw new TaxoraException(`${field} is required for a Norway enrollment.`);\n }\n }\n this.validateEmail(input.email, 'email');\n if (input.service !== undefined) this.validateService(input.service);\n if (input.legalCountry !== undefined && !COUNTRY_REGEX.test(input.legalCountry)) {\n throw new TaxoraException('legalCountry must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n\n const body: Record<string, unknown> = {\n country: 'NO',\n org_number: NorwegianOrgNumber.normalize(input.orgNumber),\n company_name: input.companyName,\n address: input.address,\n city: input.city,\n postalcode: input.postalcode,\n email: input.email,\n };\n if (input.service !== undefined) body['service'] = input.service;\n if (input.regime !== undefined) body['regime'] = input.regime;\n if (input.vatNumber !== undefined) body['vat_number'] = input.vatNumber;\n if (input.province !== undefined) body['province'] = input.province;\n if (input.vatRegistered !== undefined) body['vat_registered'] = input.vatRegistered;\n if (input.enterpriseRegister !== undefined) body['enterprise_register'] = input.enterpriseRegister;\n if (input.reception !== undefined) body['reception'] = input.reception;\n if (input.legalCountry !== undefined) body['legal_country'] = input.legalCountry.toUpperCase();\n if (input.reportingStartDate !== undefined) {\n body['reporting_start_date'] = this.formatDate(input.reportingStartDate);\n }\n if (input.autoActivate !== undefined) body['auto_activate'] = input.autoActivate;\n\n return body;\n }\n\n private async createEnrollmentFromBody(body: Record<string, unknown>): Promise<ComplianceEnrollment> {\n const response = await this.sendRequest('POST', `${this.baseUrl}/compliance/enrollments`, body);\n const data = await this.parseJsonResponse(response);\n return ComplianceEnrollment.fromArray(data);\n }\n\n private validateService(service: ComplianceRequestService): void {\n if (!SERVICES.includes(service)) {\n throw new TaxoraException(`Invalid service \"${String(service)}\". Expected one of: ${SERVICES.join(', ')}.`);\n }\n }\n\n private validateEmail(email: string | undefined, name: string): void {\n if (typeof email !== 'string' || email.trim() === '' || !email.includes('@')) {\n throw new TaxoraException(`${name} must be a valid email address.`);\n }\n }\n\n /** Lookup routes take a 2-letter country; the API expects it upper-case. */\n private normalizeLookupCountry(country: string): string {\n const normalized = country.trim().toUpperCase();\n if (!COUNTRY_REGEX.test(normalized)) {\n throw new TaxoraException('country must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n return normalized;\n }\n\n private validateId(id: number, name: string): void {\n if (!Number.isInteger(id) || id <= 0) {\n throw new TaxoraException(`${name} must be a positive integer.`);\n }\n }\n\n private validateTransactionType(type: ComplianceTransactionRequestType): void {\n if (!TRANSACTION_TYPES.includes(type)) {\n throw new TaxoraException(\n `Invalid transactionType \"${String(type)}\". Expected one of: ${TRANSACTION_TYPES.join(', ')}.`,\n );\n }\n }\n\n private validateInvoiceNumber(invoiceNumber: string): void {\n if (invoiceNumber.trim() === '') {\n throw new TaxoraException('invoiceNumber must not be empty.');\n }\n if (invoiceNumber.length > 50) {\n throw new TaxoraException('invoiceNumber must not exceed 50 characters.');\n }\n }\n\n private validateInvoiceLines(lines: ComplianceInvoiceLineInput[]): void {\n if (lines.length === 0) {\n throw new TaxoraException('invoiceLines must contain at least one line.');\n }\n lines.forEach((line, index) => {\n if (line.taxes.length === 0) {\n throw new TaxoraException(`invoiceLines[${index}].taxes must contain at least one tax.`);\n }\n });\n }\n\n private validateOptionalCodes(input: { currency?: string; counterpartyCountry?: string }): void {\n if (input.currency !== undefined && input.currency.length !== 3) {\n throw new TaxoraException('currency must be a 3-character ISO 4217 code.');\n }\n if (input.counterpartyCountry !== undefined && input.counterpartyCountry.length !== 2) {\n throw new TaxoraException('counterpartyCountry must be a 2-character ISO 3166-1 alpha-2 code.');\n }\n }\n\n /**\n * Format checks for the buyer/document fields. Country rules (e.g. the Norway\n * org number being required) depend on the enrollment and stay server-side;\n * a register id is only check-digit validated when the buyer is Norwegian.\n */\n private validateBuyerFields(input: ComplianceTransactionBuyerInput & { counterpartyCountry?: string }): void {\n if (input.counterpartyRegisterId !== undefined) {\n if (input.counterpartyRegisterId.length > 30) {\n throw new TaxoraException('counterpartyRegisterId must not exceed 30 characters.');\n }\n if (\n input.counterpartyCountry?.toUpperCase() === 'NO' &&\n !NorwegianOrgNumber.isValid(input.counterpartyRegisterId)\n ) {\n throw new TaxoraException(\n 'counterpartyRegisterId must be a valid 9-digit Norwegian organisation number (mod-11 check digit).',\n );\n }\n }\n if (input.counterpartyEmail !== undefined) this.validateEmail(input.counterpartyEmail, 'counterpartyEmail');\n if (input.buyerReference !== undefined && input.buyerReference.length > 100) {\n throw new TaxoraException('buyerReference must not exceed 100 characters.');\n }\n if (input.amendedNumber !== undefined && input.amendedNumber.length > 50) {\n throw new TaxoraException('amendedNumber must not exceed 50 characters.');\n }\n if (input.extraInfo !== undefined && input.extraInfo.length > 1000) {\n throw new TaxoraException('extraInfo must not exceed 1000 characters.');\n }\n }\n\n // ---------------------------------------------------------------------\n // Body building (camelCase input → snake_case wire format)\n // ---------------------------------------------------------------------\n\n private buildInvoiceLines(lines: ComplianceInvoiceLineInput[]): Record<string, unknown>[] {\n return lines.map((line) => {\n const built: Record<string, unknown> = {\n description: line.description,\n quantity: line.quantity,\n price: line.price,\n taxes_attributes: line.taxes.map((tax) => {\n const taxBuilt: Record<string, unknown> = {\n name: tax.name,\n percent: tax.percent,\n category: tax.category,\n };\n if (tax.comment !== undefined) taxBuilt['comment'] = tax.comment;\n return taxBuilt;\n }),\n };\n if (line.unit !== undefined) built['unit'] = line.unit;\n return built;\n });\n }\n\n /** Applies the optional scalar fields shared by create and update. */\n private applyOptionalTransactionFields(\n body: Record<string, unknown>,\n input: CreateComplianceTransactionInput | UpdateComplianceTransactionInput,\n ): void {\n if (input.dueDate !== undefined) body['due_date'] = this.formatDate(input.dueDate);\n if (input.currency !== undefined) body['currency'] = input.currency;\n if (input.taxAmount !== undefined) body['tax_amount'] = input.taxAmount;\n if (input.counterpartyName !== undefined) body['counterparty_name'] = input.counterpartyName;\n if (input.counterpartyCountry !== undefined) body['counterparty_country'] = input.counterpartyCountry;\n if (input.counterpartyVatNumber !== undefined) body['counterparty_vat_number'] = input.counterpartyVatNumber;\n if (input.providerContactId !== undefined) body['provider_contact_id'] = input.providerContactId;\n if (input.paymentMethod !== undefined) body['payment_method'] = input.paymentMethod;\n if (input.remittanceInformation !== undefined) body['remittance_information'] = input.remittanceInformation;\n if (input.paymentMethodText !== undefined) body['payment_method_text'] = input.paymentMethodText;\n if (input.paymentTerms !== undefined) body['payment_terms'] = input.paymentTerms;\n if (input.counterpartyRegisterId !== undefined) body['counterparty_register_id'] = input.counterpartyRegisterId;\n if (input.counterpartyAddress !== undefined) body['counterparty_address'] = input.counterpartyAddress;\n if (input.counterpartyCity !== undefined) body['counterparty_city'] = input.counterpartyCity;\n if (input.counterpartyPostalcode !== undefined) body['counterparty_postalcode'] = input.counterpartyPostalcode;\n if (input.counterpartyEmail !== undefined) body['counterparty_email'] = input.counterpartyEmail;\n if (input.buyerReference !== undefined) body['buyer_reference'] = input.buyerReference;\n if (input.isCreditNote !== undefined) body['is_credit_note'] = input.isCreditNote;\n if (input.amendedNumber !== undefined) body['amended_number'] = input.amendedNumber;\n if (input.amendedDate !== undefined) body['amended_date'] = this.formatDate(input.amendedDate);\n if (input.extraInfo !== undefined) body['extra_info'] = input.extraInfo;\n }\n\n // ---------------------------------------------------------------------\n // HTTP plumbing (kept in sync with SmartEnrichmentEndpoint)\n // ---------------------------------------------------------------------\n\n private buildHeaders(withJsonContentType = true): Record<string, string> {\n const headers: Record<string, string> = {\n 'x-api-key': this.apiKey,\n };\n if (withJsonContentType) {\n headers['Content-Type'] = 'application/json';\n }\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n return headers;\n }\n\n private async sendRequest(method: string, url: string, body?: Record<string, unknown>): Promise<Response> {\n const options: RequestInit = { headers: this.buildHeaders() };\n if (body) options.body = JSON.stringify(body);\n\n const send = (): Promise<Response> => this.httpClient.request(method, url, options);\n\n // GETs are safe to repeat, so transient gateway failures are retried (see\n // RetryPolicy). Writes are not: a gateway timeout does not tell us whether\n // the API already processed them.\n return method === 'GET' ? withResponseRetries(this.retryPolicy, 'e-reporting request', send) : send();\n }\n\n /** Multipart upload: Content-Type is left to fetch so the boundary is set correctly. */\n private async sendMultipartRequest(method: string, url: string, form: FormData): Promise<Response> {\n return this.httpClient.request(method, url, { headers: this.buildHeaders(false), body: form });\n }\n\n /** Accepts any 2xx response (e.g. 201 on create, 200 on idempotent replay). */\n private async parseJsonResponse(response: Response): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw this.buildValidationException(responseText);\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && typeof obj['data'] === 'object' && obj['data'] !== null) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n\n /** For the 204 delete: keeps the shared 422/HTTP error mapping but never parses a body. */\n private async assertNoContentResponse(response: Response): Promise<void> {\n if (response.status === 204) {\n return;\n }\n\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw this.buildValidationException(responseText);\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n }\n\n /**\n * The backend emits two 422 shapes: Laravel FormRequest failures as\n * `{message, errors: {field: [...]}}` and state-guard errors via returnError()\n * as `{error: \"reason\"}`. Preserve the reason in both cases.\n */\n private buildValidationException(responseText: string): ValidationException {\n let message = 'Validation failed';\n let errors: Record<string, string[]> = {};\n\n try {\n const parsed = JSON.parse(responseText) as Record<string, unknown>;\n if (parsed['errors'] !== null && typeof parsed['errors'] === 'object' && !Array.isArray(parsed['errors'])) {\n errors = parsed['errors'] as Record<string, string[]>;\n }\n if (typeof parsed['message'] === 'string' && parsed['message'] !== '') {\n message = parsed['message'];\n } else if (typeof parsed['error'] === 'string' && parsed['error'] !== '') {\n message = parsed['error'];\n }\n } catch {\n // ignore parse errors\n }\n\n return new ValidationException(message, errors, { responseBody: responseText });\n }\n\n /**\n * Date objects are serialized from their LOCAL date parts — construct them as\n * `new Date('2026-09-01T00:00:00')` (local midnight); a bare `new Date('2026-09-01')`\n * is UTC midnight and shifts a day back in UTC-negative timezones.\n */\n private formatDate(date: Date | string): string {\n if (date instanceof Date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n if (!DATE_REGEX.test(date)) {\n throw new TaxoraException(`Invalid date format: \"${date}\". Expected YYYY-MM-DD.`);\n }\n\n return date;\n }\n}\n","/**\n * How hard a Smart Enrichment lookup is allowed to search.\n *\n * `default` searches with one AI provider and consults a second one only when the first finds\n * nothing — one paid search per lookup in the common case.\n *\n * `complex` has two independent AI providers search from the start, and every VAT number either of\n * them proposes is put through the tax authority's checks until one confirms. Noticeably better on\n * hard lookups — companies whose VAT only appears in a website Impressum — and it costs more per\n * lookup, so it is opt-in per request rather than the default.\n */\nexport const SmartEnrichmentMode = {\n DEFAULT: 'default',\n COMPLEX: 'complex',\n} as const;\n\nexport type SmartEnrichmentMode = (typeof SmartEnrichmentMode)[keyof typeof SmartEnrichmentMode];\n\nconst VALUES: readonly string[] = Object.values(SmartEnrichmentMode);\n\n/**\n * Coercion for values coming back from the API. Returns undefined for anything unrecognized —\n * unlike the status enum there is no `unknown` member to fall back to, and inventing a mode would\n * misreport how a lookup actually ran.\n */\nexport function toSmartEnrichmentMode(value: unknown): SmartEnrichmentMode | undefined {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as SmartEnrichmentMode;\n }\n }\n return undefined;\n}\n\nconst DESCRIPTIONS: Record<SmartEnrichmentMode, string> = {\n [SmartEnrichmentMode.DEFAULT]: 'One provider searches; a second is consulted only if it finds nothing.',\n [SmartEnrichmentMode.COMPLEX]:\n 'Two providers search independently and are cross-checked against the tax authority. Costs more.',\n};\n\nexport function describeSmartEnrichmentMode(mode: SmartEnrichmentMode): string {\n return DESCRIPTIONS[mode];\n}\n","/**\n * Why a VAT number the research DID find was not returned as the result.\n *\n * Only appears on `not_found` results (see `SmartEnrichmentResource.rejectedCandidates`), so\n * \"a number was found, but the tax authority calls it invalid\" can be told apart from \"nothing\n * was found at all\".\n */\nexport const SmartEnrichmentRejectionReason = {\n /** The tax authority reports the number as not (or no longer) valid. */\n VAT_INVALID: 'vat_invalid',\n /** The number is valid, but registered to a different company. */\n NAME_MISMATCH: 'name_mismatch',\n /** The number could not be tied to the requested company. */\n UNBOUND: 'unbound',\n /** The number could not be checked against the tax authority. */\n UNVERIFIED: 'unverified',\n /** Rejected for another reason. */\n REJECTED: 'rejected',\n /** A reason this SDK version does not know yet. */\n UNKNOWN: 'unknown',\n} as const;\n\nexport type SmartEnrichmentRejectionReason =\n (typeof SmartEnrichmentRejectionReason)[keyof typeof SmartEnrichmentRejectionReason];\n\nconst VALUES: readonly string[] = Object.values(SmartEnrichmentRejectionReason);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toSmartEnrichmentRejectionReason(value: unknown): SmartEnrichmentRejectionReason {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as SmartEnrichmentRejectionReason;\n }\n }\n return SmartEnrichmentRejectionReason.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<SmartEnrichmentRejectionReason, string> = {\n [SmartEnrichmentRejectionReason.VAT_INVALID]: 'The tax authority reports the VAT number as invalid.',\n [SmartEnrichmentRejectionReason.NAME_MISMATCH]: 'The VAT number is registered to a different company.',\n [SmartEnrichmentRejectionReason.UNBOUND]: 'The VAT number could not be tied to the requested company.',\n [SmartEnrichmentRejectionReason.UNVERIFIED]: 'The VAT number could not be verified with the tax authority.',\n [SmartEnrichmentRejectionReason.REJECTED]: 'The VAT number was not confirmed.',\n [SmartEnrichmentRejectionReason.UNKNOWN]: 'Unknown rejection reason.',\n};\n\nexport function describeSmartEnrichmentRejectionReason(reason: SmartEnrichmentRejectionReason): string {\n return DESCRIPTIONS[reason];\n}\n","export const SmartEnrichmentStatus = {\n FOUND: 'found',\n NO_VAT_EXISTS: 'no_vat_exists',\n NOT_FOUND: 'not_found',\n PROCESSING: 'processing',\n QUEUED: 'queued',\n COMPLETED: 'completed',\n FAILED: 'failed',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type SmartEnrichmentStatus = (typeof SmartEnrichmentStatus)[keyof typeof SmartEnrichmentStatus];\n\nconst VALUES: readonly string[] = Object.values(SmartEnrichmentStatus);\n\n/** Tolerant coercion: unrecognized values become `unknown` instead of throwing. */\nexport function toSmartEnrichmentStatus(value: unknown): SmartEnrichmentStatus {\n if (typeof value === 'string') {\n const normalized = value.trim().toLowerCase();\n if (VALUES.includes(normalized)) {\n return normalized as SmartEnrichmentStatus;\n }\n }\n return SmartEnrichmentStatus.UNKNOWN;\n}\n\nconst DESCRIPTIONS: Record<SmartEnrichmentStatus, string> = {\n [SmartEnrichmentStatus.FOUND]: 'A VAT number was resolved and confirmed.',\n [SmartEnrichmentStatus.NO_VAT_EXISTS]: 'The company was identified but has no VAT number.',\n [SmartEnrichmentStatus.NOT_FOUND]: 'No sufficiently-confident match could be resolved.',\n [SmartEnrichmentStatus.PROCESSING]: 'The lookup is still being processed.',\n [SmartEnrichmentStatus.QUEUED]: 'The job is queued.',\n [SmartEnrichmentStatus.COMPLETED]: 'The job has completed.',\n [SmartEnrichmentStatus.FAILED]: 'The job failed.',\n [SmartEnrichmentStatus.UNKNOWN]: 'Unknown status.',\n};\n\nexport function describeSmartEnrichmentStatus(status: SmartEnrichmentStatus): string {\n return DESCRIPTIONS[status];\n}\n","import { type SmartEnrichmentMode, toSmartEnrichmentMode } from '../enums/SmartEnrichmentMode.js';\nimport {\n type SmartEnrichmentRejectionReason,\n toSmartEnrichmentRejectionReason,\n} from '../enums/SmartEnrichmentRejectionReason.js';\nimport { type SmartEnrichmentStatus, toSmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\n\n/** What one AI provider independently concluded, when more than one searched. */\nexport interface SmartEnrichmentProviderVerdict {\n provider: string;\n model: string | null;\n status: string;\n vatNumber: string | null;\n confidence: number | null;\n /** False when the model answered from memory instead of an actual web search. */\n grounded: boolean;\n sourceUrl: string | null;\n}\n\n/**\n * What the API made of the address you submitted. The actionable part is `warnings`:\n * `postal_code_city_mismatch` / `postal_code_unassigned` / `postal_code_format_invalid` mean the\n * postal code in your source record is wrong, and `derivedPlace` is where it actually points —\n * worth writing back into your own data.\n */\nexport interface SmartEnrichmentAddressQuality {\n providedPostalCode: string | null;\n providedCity: string | null;\n postalCodeFormatValid: boolean | null;\n postalCodeAssigned: boolean | null;\n /** False when the postal code was excluded from the search because it could not be trusted. */\n postalCodeTrusted: boolean;\n derivedPlace: string | null;\n cityMatchesPostalCode: boolean | null;\n warnings: string[];\n}\n\n/** A VAT number the research named, but the official check threw out. */\nexport interface SmartEnrichmentRejectedCandidate {\n vatNumber: string;\n reason: SmartEnrichmentRejectionReason;\n}\n\nfunction toRejectedCandidates(value: unknown): SmartEnrichmentRejectedCandidate[] {\n if (!Array.isArray(value)) {\n return [];\n }\n\n const candidates: SmartEnrichmentRejectedCandidate[] = [];\n for (const entry of value) {\n if (typeof entry !== 'object' || entry === null) {\n continue;\n }\n const record = entry as Record<string, unknown>;\n const vatNumber = typeof record['vatNumber'] === 'string' ? record['vatNumber'].trim() : '';\n // An entry without a number carries nothing to report.\n if (vatNumber === '') {\n continue;\n }\n candidates.push({ vatNumber, reason: toSmartEnrichmentRejectionReason(record['reason']) });\n }\n return candidates;\n}\n\n/**\n * Result of resolving one reverse-VAT lookup (company name + address → VAT + confidence).\n * Mirrors the API response item shape (camelCase keys).\n */\nexport class SmartEnrichmentResource {\n constructor(\n public readonly status: SmartEnrichmentStatus,\n public readonly vatNumber: string | undefined,\n public readonly vatType: string | undefined,\n public readonly confidence: number | undefined,\n public readonly matchedCompanyName: string | undefined,\n /** Official/registered address of the matched company, when available. */\n public readonly matchedAddress: string | undefined,\n public readonly country: string | undefined,\n public readonly source: string | undefined,\n /** The search mode this lookup actually ran in. */\n public readonly mode: SmartEnrichmentMode | undefined = undefined,\n /**\n * What each AI provider independently concluded. Populated when more than one searched\n * (complex mode, or a fallback). Two entries reporting the same vatNumber is the strongest\n * confirmation this layer produces.\n */\n public readonly providerVerdicts: SmartEnrichmentProviderVerdict[] = [],\n public readonly addressQuality: SmartEnrichmentAddressQuality | undefined = undefined,\n /**\n * Only on `not_found`: VAT numbers the research DID find but the official check threw out —\n * e.g. one the tax authority reports as invalid. Lets you tell \"found one, it is invalid\"\n * apart from \"found nothing\". Empty for every other status.\n */\n public readonly rejectedCandidates: SmartEnrichmentRejectedCandidate[] = [],\n ) {}\n\n /** True when a VAT number was found but rejected by the official check. */\n hasRejectedCandidates(): boolean {\n return this.rejectedCandidates.length > 0;\n }\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentResource {\n const str = (key: string): string | undefined => {\n const v = data[key];\n return typeof v === 'string' ? v : undefined;\n };\n const num = (key: string): number | undefined => {\n const v = data[key];\n return typeof v === 'number' ? v : undefined;\n };\n\n const verdicts = data['providerVerdicts'];\n const quality = data['addressQuality'];\n\n return new SmartEnrichmentResource(\n toSmartEnrichmentStatus(data['status']),\n str('vatNumber'),\n str('vatType'),\n num('confidence'),\n str('matchedCompanyName'),\n str('matchedAddress'),\n str('country'),\n str('source'),\n toSmartEnrichmentMode(data['mode']),\n Array.isArray(verdicts)\n ? (verdicts.filter((v) => typeof v === 'object' && v !== null) as SmartEnrichmentProviderVerdict[])\n : [],\n typeof quality === 'object' && quality !== null ? (quality as SmartEnrichmentAddressQuality) : undefined,\n toRejectedCandidates(data['rejectedCandidates']),\n );\n }\n\n toArray(): Record<string, unknown> {\n return {\n status: this.status,\n vatNumber: this.vatNumber ?? null,\n vatType: this.vatType ?? null,\n confidence: this.confidence ?? null,\n matchedCompanyName: this.matchedCompanyName ?? null,\n matchedAddress: this.matchedAddress ?? null,\n country: this.country ?? null,\n source: this.source ?? null,\n mode: this.mode ?? null,\n providerVerdicts: this.providerVerdicts,\n addressQuality: this.addressQuality ?? null,\n rejectedCandidates: this.rejectedCandidates.map((c) => ({ vatNumber: c.vatNumber, reason: c.reason })),\n };\n }\n}\n","import { SmartEnrichmentResource } from './SmartEnrichmentResource.js';\nimport { SmartEnrichmentStatus, toSmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\n\n/**\n * A Smart Enrichment job — single lookup or bulk batch. Unifies the API's sync and async\n * responses: a confident single lookup comes back already resolved (one result, status\n * `found`); everything else comes back `processing` with a `jobId` to poll.\n */\nexport class SmartEnrichmentJob {\n constructor(\n public readonly jobId: string,\n public readonly status: SmartEnrichmentStatus,\n public readonly itemCount: number | undefined,\n public readonly completedCount: number | undefined,\n public readonly foundCount: number | undefined,\n public readonly results: SmartEnrichmentResource[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentJob {\n const num = (key: string): number | undefined => {\n const v = data[key];\n return typeof v === 'number' ? v : undefined;\n };\n\n let results: SmartEnrichmentResource[] = [];\n\n if (Array.isArray(data['results'])) {\n // Bulk job: array of per-item results.\n results = (data['results'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(SmartEnrichmentResource.fromArray);\n } else if (data['vatNumber'] !== undefined || SmartEnrichmentJob.looksLikeItem(data['status'])) {\n // Flat single response — the payload itself is the (only) result.\n results = [SmartEnrichmentResource.fromArray(data)];\n }\n\n return new SmartEnrichmentJob(\n typeof data['jobId'] === 'string' ? data['jobId'] : '',\n toSmartEnrichmentStatus(data['status']),\n num('itemCount'),\n num('completedCount'),\n num('foundCount'),\n results,\n );\n }\n\n isProcessing(): boolean {\n return this.status === SmartEnrichmentStatus.PROCESSING || this.status === SmartEnrichmentStatus.QUEUED;\n }\n\n /** Convenience for single lookups: the first (or only) result, if any. */\n result(): SmartEnrichmentResource | undefined {\n return this.results[0];\n }\n\n private static looksLikeItem(status: unknown): boolean {\n const s = toSmartEnrichmentStatus(status);\n return (\n s === SmartEnrichmentStatus.FOUND ||\n s === SmartEnrichmentStatus.NO_VAT_EXISTS ||\n s === SmartEnrichmentStatus.NOT_FOUND\n );\n }\n}\n","import { SmartEnrichmentResource } from './SmartEnrichmentResource.js';\nimport { type SmartEnrichmentStatus, toSmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\n\n/**\n * Full first input of a history row (incl. street + postalCode) — everything that was\n * queried, so a detail view needs no second fetch. `query` stays the compact summary.\n */\nexport interface SmartEnrichmentHistoryInput {\n companyName: string | undefined;\n street: string | undefined;\n postalCode: string | undefined;\n city: string | undefined;\n country: string | undefined;\n}\n\n/**\n * One row of Smart Enrichment lookup history (compact summary; full detail via getJob).\n */\nexport class SmartEnrichmentHistoryRow {\n constructor(\n public readonly jobId: string,\n public readonly status: SmartEnrichmentStatus,\n public readonly isBulk: boolean,\n public readonly itemCount: number,\n public readonly foundCount: number,\n public readonly queryCompanyName: string | undefined,\n public readonly queryCountry: string | undefined,\n public readonly queryCity: string | undefined,\n public readonly input: SmartEnrichmentHistoryInput | undefined,\n public readonly result: SmartEnrichmentResource | undefined,\n public readonly createdAt: string | undefined,\n public readonly finishedAt: string | undefined,\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentHistoryRow {\n const str = (value: unknown): string | undefined => (typeof value === 'string' ? value : undefined);\n const query =\n data['query'] !== null && typeof data['query'] === 'object' && !Array.isArray(data['query'])\n ? (data['query'] as Record<string, unknown>)\n : {};\n const inputRaw =\n data['input'] !== null && typeof data['input'] === 'object' && !Array.isArray(data['input'])\n ? (data['input'] as Record<string, unknown>)\n : undefined;\n const input: SmartEnrichmentHistoryInput | undefined = inputRaw\n ? {\n companyName: str(inputRaw['companyName']),\n street: str(inputRaw['street']),\n postalCode: str(inputRaw['postalCode']),\n city: str(inputRaw['city']),\n country: str(inputRaw['country']),\n }\n : undefined;\n const result =\n data['result'] !== null && typeof data['result'] === 'object' && !Array.isArray(data['result'])\n ? SmartEnrichmentResource.fromArray(data['result'] as Record<string, unknown>)\n : undefined;\n\n return new SmartEnrichmentHistoryRow(\n str(data['jobId']) ?? '',\n toSmartEnrichmentStatus(data['status']),\n data['isBulk'] === true,\n typeof data['itemCount'] === 'number' ? data['itemCount'] : 0,\n typeof data['foundCount'] === 'number' ? data['foundCount'] : 0,\n str(query['companyName']),\n str(query['country']),\n str(query['city']),\n input,\n result,\n str(data['createdAt']),\n str(data['finishedAt']),\n );\n }\n}\n","import { SmartEnrichmentHistoryRow } from './SmartEnrichmentHistoryRow.js';\n\n/**\n * Account-wide history tiles — stable regardless of the current search/page filter.\n */\nexport interface SmartEnrichmentHistoryStats {\n total: number;\n found: number;\n}\n\n/**\n * A paginated page of Smart Enrichment lookup history.\n */\nexport class SmartEnrichmentHistoryPage implements Iterable<SmartEnrichmentHistoryRow> {\n constructor(\n public readonly rows: SmartEnrichmentHistoryRow[],\n public readonly currentPage: number,\n public readonly perPage: number,\n public readonly total: number,\n public readonly lastPage: number,\n public readonly stats?: SmartEnrichmentHistoryStats,\n ) {}\n\n static fromResponse(payload: unknown): SmartEnrichmentHistoryPage {\n const obj =\n payload !== null && typeof payload === 'object' && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n\n const rows = Array.isArray(obj['data'])\n ? (obj['data'] as unknown[])\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map(SmartEnrichmentHistoryRow.fromArray)\n : [];\n\n const meta =\n obj['meta'] !== null && typeof obj['meta'] === 'object' && !Array.isArray(obj['meta'])\n ? (obj['meta'] as Record<string, unknown>)\n : {};\n\n const num = (value: unknown, fallback: number): number => (typeof value === 'number' ? value : fallback);\n\n const statsRaw =\n obj['stats'] !== null && typeof obj['stats'] === 'object' && !Array.isArray(obj['stats'])\n ? (obj['stats'] as Record<string, unknown>)\n : undefined;\n const stats: SmartEnrichmentHistoryStats | undefined = statsRaw\n ? { total: num(statsRaw['total'], 0), found: num(statsRaw['found'], 0) }\n : undefined;\n\n return new SmartEnrichmentHistoryPage(\n rows,\n num(meta['currentPage'], 1),\n num(meta['perPage'], rows.length),\n num(meta['total'], rows.length),\n num(meta['lastPage'], 1),\n stats,\n );\n }\n\n [Symbol.iterator](): Iterator<SmartEnrichmentHistoryRow> {\n return this.rows[Symbol.iterator]();\n }\n\n get length(): number {\n return this.rows.length;\n }\n}\n","/**\n * DTOs for the Smart Enrichment statistics endpoint\n * (GET /smart-enrichment/statistics).\n *\n * Read-only aggregation over the company's lookups: headline totals, a time\n * series and breakdowns by source, outcome and confidence band. The API\n * defaults to the last 12 months and a monthly interval.\n */\n\n/** Time-series bucket size accepted by the statistics endpoint. */\nexport type SmartEnrichmentStatisticsInterval = 'day' | 'week' | 'month';\n\nexport interface SmartEnrichmentStatisticsRange {\n dateFrom: string;\n dateTo: string;\n interval: string;\n}\n\nexport interface SmartEnrichmentStatisticsTotals {\n jobs: number;\n items: number;\n found: number;\n /** Share of items that resolved to a VAT number, 0–100. */\n foundRate: number;\n /** Average confidence of found items, 0–100. */\n avgConfidence: number;\n}\n\nexport interface SmartEnrichmentTimeBucket {\n /** Period key: \"2026-01-15\" (day), \"2026-03\" (ISO year-week) or \"2026-01\" (month). */\n bucket: string;\n jobs: number;\n items: number;\n found: number;\n}\n\nexport interface SmartEnrichmentSourceBreakdown {\n source: string;\n jobs: number;\n found: number;\n}\n\nexport interface SmartEnrichmentOutcomeBreakdown {\n outcome: string;\n count: number;\n}\n\nexport interface SmartEnrichmentConfidenceBucket {\n /** Confidence band: \"high\", \"medium\" or \"low\". */\n bucket: string;\n count: number;\n}\n\nfunction asString(value: unknown, fallback = ''): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nfunction asNumber(value: unknown): number {\n return typeof value === 'number' ? value : Number(value ?? 0) || 0;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\nfunction asRecords(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null);\n}\n\nexport class SmartEnrichmentStatistics {\n constructor(\n public readonly range: SmartEnrichmentStatisticsRange,\n public readonly totals: SmartEnrichmentStatisticsTotals,\n public readonly timeSeries: SmartEnrichmentTimeBucket[],\n public readonly bySource: SmartEnrichmentSourceBreakdown[],\n public readonly byOutcome: SmartEnrichmentOutcomeBreakdown[],\n public readonly confidenceBuckets: SmartEnrichmentConfidenceBucket[],\n ) {}\n\n static fromArray(data: Record<string, unknown>): SmartEnrichmentStatistics {\n const range = asRecord(data['range']);\n const totals = asRecord(data['totals']);\n\n const timeSeries: SmartEnrichmentTimeBucket[] = asRecords(data['time_series']).map((row) => ({\n bucket: asString(row['bucket']),\n jobs: asNumber(row['jobs']),\n items: asNumber(row['items']),\n found: asNumber(row['found']),\n }));\n\n const bySource: SmartEnrichmentSourceBreakdown[] = asRecords(data['by_source']).map((row) => ({\n source: asString(row['source']),\n jobs: asNumber(row['jobs']),\n found: asNumber(row['found']),\n }));\n\n const byOutcome: SmartEnrichmentOutcomeBreakdown[] = asRecords(data['by_outcome']).map((row) => ({\n outcome: asString(row['outcome']),\n count: asNumber(row['count']),\n }));\n\n const confidenceBuckets: SmartEnrichmentConfidenceBucket[] = asRecords(data['confidence_buckets']).map((row) => ({\n bucket: asString(row['bucket']),\n count: asNumber(row['count']),\n }));\n\n return new SmartEnrichmentStatistics(\n {\n dateFrom: asString(range['date_from']),\n dateTo: asString(range['date_to']),\n interval: asString(range['interval']),\n },\n {\n jobs: asNumber(totals['jobs']),\n items: asNumber(totals['items']),\n found: asNumber(totals['found']),\n foundRate: asNumber(totals['found_rate']),\n avgConfidence: asNumber(totals['avg_confidence']),\n },\n timeSeries,\n bySource,\n byOutcome,\n confidenceBuckets,\n );\n }\n}\n","import { type SmartEnrichmentMode } from '../enums/SmartEnrichmentMode.js';\nimport { SmartEnrichmentJob } from '../dto/SmartEnrichmentJob.js';\nimport { SmartEnrichmentHistoryPage } from '../dto/SmartEnrichmentHistoryPage.js';\nimport { SmartEnrichmentStatistics, type SmartEnrichmentStatisticsInterval } from '../dto/SmartEnrichmentStatistics.js';\nimport { type SmartEnrichmentStatus } from '../enums/SmartEnrichmentStatus.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError, jsonErrorMessage } from '../exceptions/apiErrorMessage.js';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport { ValidationException } from '../exceptions/ValidationException.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withResponseRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nconst STATISTICS_INTERVALS: readonly SmartEnrichmentStatisticsInterval[] = ['day', 'week', 'month'];\n\nconst DEFAULT_POLL_INTERVAL_MS = 2000;\nconst DEFAULT_POLL_TIMEOUT_MS = 120_000;\n\nexport interface SmartEnrichmentInput {\n companyName: string;\n country: string;\n street?: string;\n postalCode?: string;\n city?: string;\n /**\n * Search depth. Omit to use the server default (`default`). `complex` searches with two\n * independent providers and cross-checks them — better hit rate, higher cost per lookup.\n */\n mode?: SmartEnrichmentMode;\n}\n\n/** One recent monthly billing entry, exposed on the usage response for transparency. */\nexport interface SmartEnrichmentUsageHistoryEntry {\n /** Billing period, e.g. \"2026-05\". */\n period: string;\n matches: number;\n /** Amount due for the period as a decimal string, e.g. \"9.60\". */\n amount: string;\n state: 'billed' | 'pending';\n billingType: string | null;\n manualReference: string | null;\n}\n\nexport interface SmartEnrichmentUsage {\n period: string;\n used: number;\n included: number;\n remaining: number;\n overageCount: number;\n overagePrice: number;\n overageAmount: number;\n hardCap: number | null;\n /** Recent monthly billing entries; empty when the API sends none. */\n history: SmartEnrichmentUsageHistoryEntry[];\n}\n\nexport interface SmartEnrichmentExportOptions {\n /** Inclusive lower bound on the job's creation date (YYYY-MM-DD). */\n dateFrom?: string;\n /** Inclusive upper bound on the job's creation date (YYYY-MM-DD). */\n dateTo?: string;\n /** Only include rows with at least this result confidence (0–100). */\n minConfidence?: number;\n /** Only include rows with one of these item statuses (found, no_vat_exists, not_found). */\n status?: SmartEnrichmentStatus[];\n /** Only include rows that resolved to a VAT number. */\n onlyFound?: boolean;\n}\n\nexport interface SmartEnrichmentStatisticsOptions {\n /** Inclusive lower bound (YYYY-MM-DD). Defaults to 12 months ago (server-side). */\n dateFrom?: string;\n /** Inclusive upper bound (YYYY-MM-DD). Defaults to today (server-side). */\n dateTo?: string;\n /** Time-series bucket size. Defaults to \"month\" server-side. */\n interval?: SmartEnrichmentStatisticsInterval;\n}\n\nexport interface SmartEnrichmentWaitOptions {\n /** Delay between polls in milliseconds. Defaults to 2000. */\n pollIntervalMs?: number;\n /** Maximum total time to wait in milliseconds. Defaults to 120000. */\n timeoutMs?: number;\n}\n\n/**\n * Smart Enrichment — reverse VAT lookup (company name + address + country → VAT + confidence).\n *\n * let job = await client.smartEnrichment.lookup({ companyName: 'Example GmbH', country: 'AT' });\n * if (job.isProcessing()) job = await client.smartEnrichment.waitForCompletion(job.jobId);\n * console.log(job.result()?.vatNumber);\n */\nexport class SmartEnrichmentEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n /**\n * Single reverse lookup. Returns a confident result synchronously, or a `processing`\n * job (poll with get(job.jobId) or waitForCompletion(job.jobId)) when deeper resolution\n * is needed.\n */\n async lookup(input: SmartEnrichmentInput): Promise<SmartEnrichmentJob> {\n this.validateInput(input);\n\n const body: Record<string, unknown> = {\n companyName: input.companyName,\n country: input.country,\n };\n if (input.street !== undefined) body['street'] = input.street;\n if (input.postalCode !== undefined) body['postalCode'] = input.postalCode;\n if (input.city !== undefined) body['city'] = input.city;\n if (input.mode !== undefined) body['mode'] = input.mode;\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/smart-enrichment`, body);\n const data = await this.parseJsonResponse(response, [200, 202]);\n return SmartEnrichmentJob.fromArray(data);\n }\n\n /**\n * Bulk batch — always async. Returns a `processing` job; results arrive via the\n * `enrichment.completed` webhook and are retrievable via get(job.jobId).\n *\n * @param mode Search depth for every row in the batch. A row carrying its own `mode` overrides\n * it, so a caller can pay for `complex` on just the rows that need it.\n */\n async bulkLookup(items: SmartEnrichmentInput[], mode?: SmartEnrichmentMode): Promise<SmartEnrichmentJob> {\n if (items.length === 0) {\n throw new TaxoraException('bulkLookup requires at least one item.');\n }\n items.forEach((item, index) => this.validateInput(item, `items[${index}]`));\n\n const body: Record<string, unknown> = { items };\n if (mode !== undefined) body['mode'] = mode;\n\n const response = await this.sendRequest('POST', `${this.baseUrl}/smart-enrichment/bulk`, body);\n const data = await this.parseJsonResponse(response, [200, 202]);\n return SmartEnrichmentJob.fromArray(data);\n }\n\n /** Poll a job (single or bulk) by its id. */\n async get(jobId: string): Promise<SmartEnrichmentJob> {\n this.validateJobId(jobId);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/smart-enrichment/${encodeURIComponent(jobId)}`);\n const data = await this.parseJsonResponse(response);\n return SmartEnrichmentJob.fromArray(data);\n }\n\n /**\n * Poll get(jobId) until the job is no longer processing (completed, failed or resolved).\n * Throws a TaxoraException when the job does not finish within `timeoutMs`.\n */\n async waitForCompletion(jobId: string, options: SmartEnrichmentWaitOptions = {}): Promise<SmartEnrichmentJob> {\n this.validateJobId(jobId);\n\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const timeoutMs = options.timeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n if (!Number.isFinite(pollIntervalMs) || pollIntervalMs <= 0) {\n throw new TaxoraException('pollIntervalMs must be greater than 0.');\n }\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new TaxoraException('timeoutMs must be greater than 0.');\n }\n\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const job = await this.get(jobId);\n if (!job.isProcessing()) {\n return job;\n }\n if (Date.now() + pollIntervalMs > deadline) {\n throw new TaxoraException(`Smart Enrichment job \"${jobId}\" did not complete within ${timeoutMs}ms.`, {\n jobId,\n timeoutMs,\n });\n }\n await new Promise<void>((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n }\n\n /**\n * Paginated lookup history (newest first). `perPage` is capped at 100 server-side.\n * `search` filters (free-text) over the queried company name and the resolved\n * VAT number / matched company name.\n */\n async history(page = 1, perPage = 25, search?: string): Promise<SmartEnrichmentHistoryPage> {\n const params = new URLSearchParams();\n params.set('page', String(page));\n params.set('perPage', String(perPage));\n if (search !== undefined) params.set('search', search);\n\n const response = await this.sendRequest('GET', `${this.baseUrl}/smart-enrichment/history?${params.toString()}`);\n // The history response is { data: [...], meta: {...}, stats: {...} }; parse it whole\n // rather than unwrapping `data` (which would drop the pagination meta).\n return SmartEnrichmentHistoryPage.fromResponse(await this.parseRawJson(response));\n }\n\n /** Current billing-period quota usage, plus recent monthly billing entries. */\n async usage(): Promise<SmartEnrichmentUsage> {\n const response = await this.sendRequest('GET', `${this.baseUrl}/smart-enrichment/usage`);\n const data = await this.parseJsonResponse(response);\n return {\n period: typeof data['period'] === 'string' ? data['period'] : '',\n used: typeof data['used'] === 'number' ? data['used'] : 0,\n included: typeof data['included'] === 'number' ? data['included'] : 0,\n remaining: typeof data['remaining'] === 'number' ? data['remaining'] : 0,\n overageCount: typeof data['overageCount'] === 'number' ? data['overageCount'] : 0,\n overagePrice: typeof data['overagePrice'] === 'number' ? data['overagePrice'] : 0,\n overageAmount: typeof data['overageAmount'] === 'number' ? data['overageAmount'] : 0,\n hardCap: typeof data['hardCap'] === 'number' ? data['hardCap'] : null,\n history: this.parseUsageHistory(data['history']),\n };\n }\n\n /**\n * Export the company's lookups as CSV (bulk-input shape plus the resolved VAT columns;\n * bulk jobs are flattened to one line per input row). Returns the raw CSV text\n * (UTF-8, BOM included by the API so Excel opens umlauts correctly).\n */\n async export(options: SmartEnrichmentExportOptions = {}): Promise<string> {\n const params = new URLSearchParams();\n if (options.dateFrom !== undefined) params.set('date_from', options.dateFrom);\n if (options.dateTo !== undefined) params.set('date_to', options.dateTo);\n if (options.minConfidence !== undefined) params.set('min_confidence', String(options.minConfidence));\n for (const status of options.status ?? []) {\n params.append('status[]', status);\n }\n if (options.onlyFound !== undefined) params.set('only_found', options.onlyFound ? '1' : '0');\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/smart-enrichment/export${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n return this.parseCsvResponse(response);\n }\n\n /**\n * Aggregated lookup statistics: headline totals, a time series and breakdowns by\n * source, outcome and confidence band. The API defaults to the last 12 months\n * and a monthly interval.\n */\n async statistics(options: SmartEnrichmentStatisticsOptions = {}): Promise<SmartEnrichmentStatistics> {\n if (options.interval !== undefined && !STATISTICS_INTERVALS.includes(options.interval)) {\n throw new TaxoraException(\n `Invalid statistics interval \"${String(options.interval)}\". Expected one of: ${STATISTICS_INTERVALS.join(', ')}.`,\n );\n }\n\n const params = new URLSearchParams();\n if (options.dateFrom !== undefined) params.set('date_from', options.dateFrom);\n if (options.dateTo !== undefined) params.set('date_to', options.dateTo);\n if (options.interval !== undefined) params.set('interval', options.interval);\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/smart-enrichment/statistics${queryString ? `?${queryString}` : ''}`;\n\n const response = await this.sendRequest('GET', url);\n // The statistics payload is a whole object (range/totals/breakdowns) — no `data` envelope.\n return SmartEnrichmentStatistics.fromArray(await this.parseRawJson(response));\n }\n\n // ---------------------------------------------------------------------\n // Input validation (fail fast, before any request is sent)\n // ---------------------------------------------------------------------\n\n private validateInput(input: SmartEnrichmentInput, context?: string): void {\n const where = context ? ` (${context})` : '';\n if (input.companyName.trim() === '') {\n throw new TaxoraException(`companyName must not be empty${where}.`);\n }\n if (input.country.length !== 2) {\n throw new TaxoraException(`country must be a 2-character ISO 3166-1 alpha-2 code${where}.`);\n }\n }\n\n private validateJobId(jobId: string): void {\n if (jobId.trim() === '') {\n throw new TaxoraException('jobId must not be empty.');\n }\n }\n\n // ---------------------------------------------------------------------\n // HTTP plumbing (kept in sync with VatEndpoint)\n // ---------------------------------------------------------------------\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n return headers;\n }\n\n private async sendRequest(method: string, url: string, body?: Record<string, unknown>): Promise<Response> {\n const options: RequestInit = { headers: this.buildHeaders() };\n if (body) options.body = JSON.stringify(body);\n\n const send = (): Promise<Response> => this.httpClient.request(method, url, options);\n\n // GETs are safe to repeat, so transient gateway failures are retried (see\n // RetryPolicy). Writes are not: a gateway timeout does not tell us whether\n // the API already processed them.\n return method === 'GET' ? withResponseRetries(this.retryPolicy, 'Smart Enrichment request', send) : send();\n }\n\n private async parseJsonResponse(\n response: Response,\n acceptedStatuses: number[] = [200],\n ): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw new ValidationException(\n jsonErrorMessage(responseText) ?? 'Validation failed',\n this.parseValidationErrors(responseText),\n );\n }\n\n if (!response.ok && !acceptedStatuses.includes(response.status)) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && (typeof obj['data'] === 'object' || Array.isArray(obj['data']))) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n\n /**\n * Like parseJsonResponse but returns the whole object WITHOUT unwrapping `data` — used for\n * the paginated history response (where `data` is the row array and `meta`/`stats` must be\n * preserved) and the statistics response.\n */\n private async parseRawJson(response: Response): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw new ValidationException(\n jsonErrorMessage(responseText) ?? 'Validation failed',\n this.parseValidationErrors(responseText),\n );\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n return parsed as Record<string, unknown>;\n }\n\n /**\n * For the CSV export: keeps the shared 422/HTTP error mapping but returns the body\n * verbatim (text/csv) instead of parsing JSON.\n */\n private async parseCsvResponse(response: Response): Promise<string> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n throw new ValidationException(\n jsonErrorMessage(responseText) ?? 'Validation failed',\n this.parseValidationErrors(responseText),\n );\n }\n\n if (!response.ok) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n return responseText;\n }\n\n private parseValidationErrors(responseText: string): Record<string, string[]> {\n try {\n const parsed = JSON.parse(responseText) as Record<string, unknown>;\n if (parsed['errors'] !== null && typeof parsed['errors'] === 'object' && !Array.isArray(parsed['errors'])) {\n return parsed['errors'] as Record<string, string[]>;\n }\n } catch {\n // ignore parse errors\n }\n return {};\n }\n\n private parseUsageHistory(value: unknown): SmartEnrichmentUsageHistoryEntry[] {\n if (!Array.isArray(value)) return [];\n\n return value\n .filter((row): row is Record<string, unknown> => typeof row === 'object' && row !== null)\n .map((row) => ({\n period: typeof row['period'] === 'string' ? row['period'] : '',\n matches: typeof row['matches'] === 'number' ? row['matches'] : 0,\n amount: typeof row['amount'] === 'string' ? row['amount'] : '0.00',\n state: row['state'] === 'billed' ? ('billed' as const) : ('pending' as const),\n billingType: typeof row['billingType'] === 'string' ? row['billingType'] : null,\n manualReference: typeof row['manualReference'] === 'string' ? row['manualReference'] : null,\n }));\n }\n}\n","export const VatState = {\n VALID: 'valid',\n INVALID: 'invalid',\n FRAUD: 'fraud',\n UNKNOWN: 'unknown',\n} as const;\n\nexport type VatState = (typeof VatState)[keyof typeof VatState];\n\nexport function getFailedVatStates(): VatState[] {\n return [VatState.INVALID, VatState.FRAUD];\n}\n\nconst DESCRIPTIONS: Record<VatState, string> = {\n [VatState.VALID]: 'The VAT number is valid and active.',\n [VatState.INVALID]: 'The VAT number is invalid or not registered.',\n [VatState.FRAUD]: 'The VAT number has been flagged as potentially fraudulent.',\n [VatState.UNKNOWN]: 'The VAT number state could not be determined.',\n};\n\nexport function describeVatState(state: VatState): string {\n return DESCRIPTIONS[state];\n}\n","interface CompanyAddressProps {\n fullAddress?: string | null;\n name?: string | null;\n street?: string | null;\n postalCode?: string | null;\n city?: string | null;\n state?: string | null;\n country?: string | null;\n raw?: string | null;\n}\n\nexport class CompanyAddress {\n public readonly fullAddress: string | null;\n public readonly name: string | null;\n public readonly street: string | null;\n public readonly postalCode: string | null;\n public readonly city: string | null;\n public readonly state: string | null;\n public readonly country: string | null;\n public readonly raw: string | null;\n\n constructor(props: CompanyAddressProps) {\n this.name = props.name ?? null;\n this.street = props.street ?? null;\n this.postalCode = props.postalCode ?? null;\n this.city = props.city ?? null;\n this.state = props.state ?? null;\n this.country = props.country ?? null;\n this.raw = props.raw ?? null;\n this.fullAddress = props.fullAddress ?? this.assembleFullAddress();\n }\n\n private assembleFullAddress(): string | null {\n const parts = [this.street, this.postalCode, this.city, this.country].filter(Boolean);\n return parts.length > 0 ? parts.join(', ') : null;\n }\n\n static from(value: unknown): CompanyAddress | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return CompanyAddress.fromArray(parsed as Record<string, unknown>, trimmed);\n }\n } catch {\n // Not valid JSON — treat as plain string\n }\n return new CompanyAddress({ raw: trimmed });\n }\n\n if (typeof value === 'object' && !Array.isArray(value)) {\n return CompanyAddress.fromArray(value as Record<string, unknown>, null);\n }\n\n return null;\n }\n\n static fromArray(data: Record<string, unknown>, raw: string | null): CompanyAddress {\n const get = (key: string): string | null => {\n const val = data[key] ?? data[key.replace(/_/g, '-')];\n return typeof val === 'string' && val.trim() ? val.trim() : null;\n };\n\n return new CompanyAddress({\n fullAddress: get('full_address'),\n name: get('name'),\n street: get('street'),\n postalCode: get('postal_code') ?? get('postalCode'),\n city: get('city'),\n state: get('state'),\n country: get('country'),\n raw,\n });\n }\n\n toArray(): Record<string, string | null> {\n return {\n full_address: this.fullAddress,\n name: this.name,\n street: this.street,\n postal_code: this.postalCode,\n city: this.city,\n state: this.state,\n country: this.country,\n };\n }\n\n toString(): string {\n return this.fullAddress ?? this.raw ?? '';\n }\n}\n","export class ScoreBreakdown {\n constructor(\n public readonly stepName: string,\n public readonly scoreContribution: number,\n public readonly metadata: Record<string, unknown>,\n ) {}\n\n static fromArray(data: Record<string, unknown>): ScoreBreakdown {\n return new ScoreBreakdown(\n typeof data['step_name'] === 'string' ? data['step_name'] : '',\n typeof data['score_contribution'] === 'number' ? data['score_contribution'] : 0,\n data['metadata'] !== null && typeof data['metadata'] === 'object' && !Array.isArray(data['metadata'])\n ? (data['metadata'] as Record<string, unknown>)\n : {},\n );\n }\n\n toArray(): { step_name: string; score_contribution: number; metadata: Record<string, unknown> } {\n return {\n step_name: this.stepName,\n score_contribution: this.scoreContribution,\n metadata: this.metadata,\n };\n }\n}\n","export class ProviderDocumentLine {\n constructor(\n public readonly id: number | null,\n public readonly vatUid: string | null,\n public readonly rowNumber: number | null,\n public readonly entryIdentifier: string | null,\n public readonly reference: string | null,\n public readonly meta: Record<string, unknown>,\n ) {}\n\n static fromArray(data: unknown): ProviderDocumentLine | null {\n if (data === null || data === undefined || typeof data !== 'object' || Array.isArray(data)) {\n return null;\n }\n const d = data as Record<string, unknown>;\n\n return new ProviderDocumentLine(\n typeof d['id'] === 'number' ? d['id'] : null,\n typeof d['vat_uid'] === 'string' ? d['vat_uid'] : null,\n typeof d['row_number'] === 'number' ? d['row_number'] : null,\n typeof d['entry_identifier'] === 'string' ? d['entry_identifier'] : null,\n typeof d['reference'] === 'string' ? d['reference'] : null,\n d['meta'] !== null && typeof d['meta'] === 'object' && !Array.isArray(d['meta'])\n ? (d['meta'] as Record<string, unknown>)\n : {},\n );\n }\n\n toArray(): Record<string, unknown> {\n return {\n id: this.id,\n vat_uid: this.vatUid,\n row_number: this.rowNumber,\n entry_identifier: this.entryIdentifier,\n reference: this.reference,\n meta: this.meta,\n };\n }\n}\n","import { ProviderDocumentLine } from './ProviderDocumentLine.js';\n\nexport class ProviderDocument {\n constructor(\n public readonly id: number | null,\n public readonly provider: string | null,\n public readonly documentType: string | null,\n public readonly state: string | null,\n public readonly documentDate: Date | null,\n public readonly mime: string | null,\n public readonly size: number | null,\n public readonly hash: string | null,\n public readonly meta: Record<string, unknown>,\n public readonly line: ProviderDocumentLine | null,\n ) {}\n\n static fromArray(data: unknown): ProviderDocument | null {\n if (data === null || data === undefined || typeof data !== 'object' || Array.isArray(data)) {\n return null;\n }\n const d = data as Record<string, unknown>;\n\n const documentDate =\n typeof d['document_date'] === 'string' && d['document_date'] ? new Date(d['document_date']) : null;\n\n return new ProviderDocument(\n typeof d['id'] === 'number' ? d['id'] : null,\n typeof d['provider'] === 'string' ? d['provider'] : null,\n typeof d['document_type'] === 'string' ? d['document_type'] : null,\n typeof d['state'] === 'string' ? d['state'] : null,\n documentDate,\n typeof d['mime'] === 'string' ? d['mime'] : null,\n typeof d['size'] === 'number' ? d['size'] : null,\n typeof d['hash'] === 'string' ? d['hash'] : null,\n d['meta'] !== null && typeof d['meta'] === 'object' && !Array.isArray(d['meta'])\n ? (d['meta'] as Record<string, unknown>)\n : {},\n ProviderDocumentLine.fromArray(d['line']),\n );\n }\n\n toArray(): Record<string, unknown> {\n return {\n id: this.id,\n provider: this.provider,\n document_type: this.documentType,\n state: this.state,\n document_date: this.documentDate?.toISOString() ?? null,\n mime: this.mime,\n size: this.size,\n hash: this.hash,\n meta: this.meta,\n line: this.line?.toArray() ?? null,\n };\n }\n}\n","import { VatState } from '../enums/VatState.js';\nimport { CompanyAddress } from './CompanyAddress.js';\nimport { ScoreBreakdown } from './ScoreBreakdown.js';\nimport { ProviderDocument } from './ProviderDocument.js';\n\nexport class VatResource {\n constructor(\n public readonly uuid: string | undefined,\n public readonly vatUid: string | undefined,\n public readonly state: VatState | undefined,\n public readonly countryCode: string | undefined,\n public readonly companyName: string | undefined,\n public readonly companyAddress: CompanyAddress | undefined,\n public readonly requestedCompanyName: string | undefined,\n public readonly requestedCompanyNameOriginal: string | undefined,\n public readonly requestedInputAddress: Record<string, string | null> | undefined,\n public readonly checkedAt: Date | undefined,\n public readonly score: number | undefined,\n public readonly scoreSource: string | undefined,\n public readonly scoreAttempts: Array<{ source?: string; score?: number }> | undefined,\n public readonly breakdown: ScoreBreakdown[] | undefined,\n public readonly environment: string | undefined,\n public readonly provider: string | undefined,\n public readonly usedProviders: string[] | undefined,\n public readonly providerValid: boolean | null | undefined,\n public readonly providerVatState: string | undefined,\n public readonly providerNote: string | undefined,\n public readonly providerLastCheckedAt: Date | undefined,\n public readonly hasApiError: boolean | null | undefined,\n public readonly errorMessage: string | null | undefined,\n public readonly nextApiRecheckAt: string | null | undefined,\n public readonly providerDocument: ProviderDocument | undefined,\n ) {}\n\n static fromArray(data: Record<string, unknown>): VatResource {\n const str = (key: string): string | undefined => {\n const v = data[key];\n return typeof v === 'string' ? v : undefined;\n };\n\n const stateRaw = str('state');\n const state =\n stateRaw !== undefined && Object.values(VatState).includes(stateRaw as VatState)\n ? (stateRaw as VatState)\n : undefined;\n\n const checkedAt = str('checked_at') ? new Date(data['checked_at'] as string) : undefined;\n const providerLastCheckedAt = str('provider_last_checked_at')\n ? new Date(data['provider_last_checked_at'] as string)\n : undefined;\n const hasApiError =\n data['has_api_error'] === null\n ? null\n : typeof data['has_api_error'] === 'boolean'\n ? data['has_api_error']\n : undefined;\n const errorMessage =\n data['error_message'] === null\n ? null\n : typeof data['error_message'] === 'string'\n ? data['error_message']\n : undefined;\n const nextApiRecheckAt =\n data['next_api_recheck_at'] === null\n ? null\n : typeof data['next_api_recheck_at'] === 'string'\n ? data['next_api_recheck_at']\n : undefined;\n const providerValid =\n data['provider_valid'] === null\n ? null\n : typeof data['provider_valid'] === 'boolean'\n ? data['provider_valid']\n : undefined;\n\n const breakdown = Array.isArray(data['breakdown'])\n ? (data['breakdown'] as Record<string, unknown>[]).map(ScoreBreakdown.fromArray)\n : undefined;\n\n const usedProviders = Array.isArray(data['used_providers'])\n ? (data['used_providers'] as unknown[]).filter((v): v is string => typeof v === 'string')\n : undefined;\n\n const scoreAttempts = Array.isArray(data['score_attempts'])\n ? (data['score_attempts'] as Record<string, unknown>[])\n : undefined;\n\n const requestedInputAddress =\n data['requested_input_address'] !== null &&\n typeof data['requested_input_address'] === 'object' &&\n !Array.isArray(data['requested_input_address'])\n ? (data['requested_input_address'] as Record<string, string | null>)\n : undefined;\n\n return new VatResource(\n str('uuid'),\n str('vat_uid'),\n state,\n str('country_code'),\n str('company_name'),\n CompanyAddress.from(data['company_address']) ?? undefined,\n str('requested_company_name'),\n str('requested_company_name_original'),\n requestedInputAddress,\n checkedAt,\n typeof data['score'] === 'number' ? data['score'] : undefined,\n str('score_source'),\n scoreAttempts,\n breakdown,\n str('environment'),\n str('provider'),\n usedProviders,\n providerValid,\n str('provider_vat_state'),\n str('provider_note'),\n providerLastCheckedAt,\n hasApiError,\n errorMessage,\n nextApiRecheckAt,\n ProviderDocument.fromArray(data['provider_document']) ?? undefined,\n );\n }\n\n getBackendLink(): string | null {\n if (!this.uuid) return null;\n if (this.environment === 'LIVE') {\n return `https://app.taxora.io/vat/history/${this.uuid}`;\n }\n return `https://app.sandbox.taxora.io/vat/history/${this.uuid}`;\n }\n\n isValid(useProviderState = false): boolean {\n if (useProviderState) {\n return this.isProviderValid();\n }\n\n return this.state === VatState.VALID;\n }\n\n isProviderValid(): boolean {\n if (this.providerValid !== undefined && this.providerValid !== null) {\n return this.providerValid;\n }\n\n return this.providerVatState === VatState.VALID;\n }\n\n toArray(): Record<string, unknown> {\n return {\n uuid: this.uuid,\n vat_uid: this.vatUid,\n state: this.state,\n country_code: this.countryCode,\n company_name: this.companyName,\n company_address: this.companyAddress?.toArray() ?? null,\n requested_company_name: this.requestedCompanyName,\n requested_company_name_original: this.requestedCompanyNameOriginal,\n requested_input_address: this.requestedInputAddress ?? null,\n checked_at: this.checkedAt?.toISOString() ?? null,\n score: this.score ?? null,\n score_source: this.scoreSource ?? null,\n score_attempts: this.scoreAttempts ?? null,\n breakdown: this.breakdown?.map((b) => b.toArray()) ?? null,\n environment: this.environment ?? null,\n provider: this.provider ?? null,\n used_providers: this.usedProviders ?? null,\n provider_valid: this.providerValid ?? null,\n provider_vat_state: this.providerVatState ?? null,\n provider_note: this.providerNote ?? null,\n provider_last_checked_at: this.providerLastCheckedAt?.toISOString() ?? null,\n has_api_error: this.hasApiError ?? null,\n error_message: this.errorMessage ?? null,\n next_api_recheck_at: this.nextApiRecheckAt ?? null,\n provider_document: this.providerDocument?.toArray() ?? null,\n };\n }\n}\n","import { VatResource } from './VatResource.js';\n\nexport class VatCollection implements Iterable<VatResource> {\n private readonly items: VatResource[];\n public readonly self: string | undefined;\n\n constructor(items: VatResource[], self?: string) {\n this.items = items;\n this.self = self;\n }\n\n static fromResponse(data: unknown): VatCollection {\n if (Array.isArray(data)) {\n return new VatCollection((data as Record<string, unknown>[]).map(VatResource.fromArray));\n }\n\n if (typeof data === 'object' && data !== null) {\n const obj = data as Record<string, unknown>;\n const items = Array.isArray(obj['data'])\n ? (obj['data'] as Record<string, unknown>[]).map(VatResource.fromArray)\n : [];\n const self = typeof obj['self'] === 'string' ? obj['self'] : undefined;\n return new VatCollection(items, self);\n }\n\n return new VatCollection([]);\n }\n\n [Symbol.iterator](): Iterator<VatResource> {\n return this.items[Symbol.iterator]();\n }\n\n get length(): number {\n return this.items.length;\n }\n\n all(): VatResource[] {\n return [...this.items];\n }\n}\n","export class VatCertificateExport {\n constructor(\n public readonly exportId: string,\n public readonly message?: string,\n ) {}\n\n static fromArray(data: Record<string, unknown>): VatCertificateExport {\n return new VatCertificateExport(\n typeof data['export_id'] === 'string' ? data['export_id'] : '',\n typeof data['message'] === 'string' ? data['message'] : undefined,\n );\n }\n\n toArray(): { export_id: string; message?: string } {\n const result: { export_id: string; message?: string } = { export_id: this.exportId };\n if (this.message !== undefined) result.message = this.message;\n return result;\n }\n}\n","import { TaxoraException } from '../exceptions/TaxoraException.js';\n\ninterface VatValidationAddressInputProps {\n addressLine1?: string;\n addressLine2?: string;\n postalCode?: string;\n city?: string;\n countryCode?: string;\n}\n\nconst ALLOWED_KEYS = new Set(['address_line_1', 'address_line_2', 'postal_code', 'city', 'country_code']);\n\nexport class VatValidationAddressInput {\n public readonly addressLine1?: string;\n public readonly addressLine2?: string;\n public readonly postalCode?: string;\n public readonly city?: string;\n public readonly countryCode?: string;\n\n constructor(props: VatValidationAddressInputProps) {\n if (props.addressLine1 !== undefined && props.addressLine1.length > 255) {\n throw new TaxoraException('addressLine1 must not exceed 255 characters');\n }\n if (props.addressLine2 !== undefined && props.addressLine2.length > 255) {\n throw new TaxoraException('addressLine2 must not exceed 255 characters');\n }\n if (props.countryCode !== undefined && props.countryCode.length !== 2) {\n throw new TaxoraException('countryCode must be exactly 2 characters (ISO 3166-1 alpha-2)');\n }\n\n this.addressLine1 = props.addressLine1;\n this.addressLine2 = props.addressLine2;\n this.postalCode = props.postalCode;\n this.city = props.city;\n this.countryCode = props.countryCode;\n }\n\n static fromArray(data: Record<string, unknown>): VatValidationAddressInput {\n for (const key of Object.keys(data)) {\n if (!ALLOWED_KEYS.has(key)) {\n throw new TaxoraException(`Unsupported field: \"${key}\". Allowed fields: ${[...ALLOWED_KEYS].join(', ')}`);\n }\n }\n\n const getString = (key: string): string | undefined => {\n const val = data[key];\n if (typeof val !== 'string') return undefined;\n const trimmed = val.trim();\n return trimmed || undefined;\n };\n\n const countryCode = getString('country_code');\n\n return new VatValidationAddressInput({\n addressLine1: getString('address_line_1'),\n addressLine2: getString('address_line_2'),\n postalCode: getString('postal_code'),\n city: getString('city'),\n countryCode: countryCode ? countryCode.toUpperCase() : undefined,\n });\n }\n\n toArray(): Record<string, string> {\n const result: Record<string, string> = {};\n if (this.addressLine1 !== undefined) result['address_line_1'] = this.addressLine1;\n if (this.addressLine2 !== undefined) result['address_line_2'] = this.addressLine2;\n if (this.postalCode !== undefined) result['postal_code'] = this.postalCode;\n if (this.city !== undefined) result['city'] = this.city;\n if (this.countryCode !== undefined) result['country_code'] = this.countryCode;\n return result;\n }\n}\n","import { VatResource } from '../dto/VatResource.js';\nimport { VatCollection } from '../dto/VatCollection.js';\nimport { VatCertificateExport } from '../dto/VatCertificateExport.js';\nimport { VatValidationAddressInput } from '../dto/VatValidationAddressInput.js';\nimport { type Language } from '../enums/Language.js';\nimport { HttpException } from '../exceptions/HttpException.js';\nimport { describeApiError, jsonErrorMessage } from '../exceptions/apiErrorMessage.js';\nimport { ValidationException } from '../exceptions/ValidationException.js';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\nimport { withRetries } from '../http/withRetries.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\n\nconst DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nexport class VatEndpoint {\n constructor(\n private readonly baseUrl: string,\n private readonly apiKey: string,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly httpClient: HttpClientInterface,\n private readonly retryPolicy: RetryPolicy = new RetryPolicy(),\n ) {}\n\n async validate(\n vatUid: string,\n companyName?: string,\n provider?: string,\n addressInput?: VatValidationAddressInput | Record<string, string>,\n ): Promise<VatResource> {\n const body: Record<string, unknown> = { vat_uid: vatUid };\n if (companyName) body['company_name'] = companyName;\n if (provider) body['source'] = provider;\n\n if (addressInput) {\n body['address_input'] = addressInput instanceof VatValidationAddressInput ? addressInput.toArray() : addressInput;\n }\n\n // Read-only lookup, so transient gateway failures are retried (see RetryPolicy).\n return withRetries(this.retryPolicy, 'VAT validation', async () => {\n const response = await this.sendRequest('POST', `${this.baseUrl}/vat/validate`, body);\n const data = await this.parseJsonResponse(response);\n\n return VatResource.fromArray(data);\n });\n }\n\n async validateMultiple(vatUids: string[], companyNames?: string[], provider?: string): Promise<VatCollection> {\n const body: Record<string, unknown> = { vat_uids: vatUids };\n if (companyNames) body['company_names'] = companyNames;\n if (provider) body['source'] = provider;\n\n return withRetries(this.retryPolicy, 'VAT validation', async () => {\n const response = await this.sendRequest('POST', `${this.baseUrl}/vat/validate/multiple`, body);\n const data = await this.parseJsonResponse(response);\n\n return VatCollection.fromResponse(data);\n });\n }\n\n async validateSchema(vatUid: string): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = { vat_uid: vatUid };\n return withRetries(this.retryPolicy, 'VAT schema check', async () => {\n const response = await this.sendRequest('POST', `${this.baseUrl}/vat/validate/schema`, body);\n\n return this.parseJsonResponse(response);\n });\n }\n\n async state(vatUid: string): Promise<VatResource> {\n return withRetries(this.retryPolicy, 'VAT state lookup', async () => {\n const response = await this.sendRequest('GET', `${this.baseUrl}/vat/state/${encodeURIComponent(vatUid)}`);\n const data = await this.parseJsonResponse(response);\n\n return VatResource.fromArray(data);\n });\n }\n\n async history(vatUid?: string): Promise<VatCollection> {\n let url = `${this.baseUrl}/vat/history`;\n if (vatUid) url += `?vat_uid=${encodeURIComponent(vatUid)}`;\n\n return withRetries(this.retryPolicy, 'VAT history request', async () => {\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n\n return VatCollection.fromResponse(data);\n });\n }\n\n async search(term?: string, perPage?: number): Promise<VatCollection> {\n const params = new URLSearchParams();\n if (term) params.set('term', term);\n if (perPage !== undefined) params.set('per_page', String(perPage));\n\n const queryString = params.toString();\n const url = `${this.baseUrl}/vat/search${queryString ? `?${queryString}` : ''}`;\n\n return withRetries(this.retryPolicy, 'VAT search', async () => {\n const response = await this.sendRequest('GET', url);\n const data = await this.parseJsonResponse(response);\n\n return VatCollection.fromResponse(data);\n });\n }\n\n async certificate(uuid: string, lang?: Language): Promise<Uint8Array> {\n let url = `${this.baseUrl}/vat/certificate/${encodeURIComponent(uuid)}`;\n if (lang) url += `?lang=${lang}`;\n\n return withRetries(this.retryPolicy, 'VAT certificate download', async () => {\n const response = await this.sendBinaryRequest('GET', url);\n const buffer = await response.arrayBuffer();\n\n return new Uint8Array(buffer);\n });\n }\n\n async certificatesBulkExport(\n fromDate: Date | string,\n toDate: Date | string,\n countries?: string[],\n lang?: Language,\n ): Promise<VatCertificateExport> {\n return this.exportRequest(`${this.baseUrl}/vat/certificates/bulk-export`, fromDate, toDate, countries, lang);\n }\n\n async certificatesListExport(\n fromDate: Date | string,\n toDate: Date | string,\n countries?: string[],\n lang?: Language,\n ): Promise<VatCertificateExport> {\n return this.exportRequest(`${this.baseUrl}/vat/certificates/list-export`, fromDate, toDate, countries, lang);\n }\n\n private async exportRequest(\n url: string,\n fromDate: Date | string,\n toDate: Date | string,\n countries?: string[],\n lang?: Language,\n ): Promise<VatCertificateExport> {\n const from = this.formatDate(fromDate);\n const to = this.formatDate(toDate);\n\n const body: Record<string, unknown> = { from_date: from, to_date: to };\n if (countries && countries.length > 0) body['countries'] = countries;\n if (lang) body['lang'] = lang;\n\n const response = await this.sendRequest('POST', url, body);\n const data = await this.parseJsonResponse(response, [200, 202]);\n\n const exportObj = VatCertificateExport.fromArray(data);\n if (!exportObj.exportId) {\n throw new TaxoraException('Export response is missing export_id');\n }\n\n return exportObj;\n }\n\n async downloadBulkExport(exportId: string): Promise<Uint8Array> {\n const url = `${this.baseUrl}/vat/certificates/bulk-export/${encodeURIComponent(exportId)}/download`;\n\n return withRetries(this.retryPolicy, 'VAT export download', async () => {\n const response = await this.sendBinaryRequest('GET', url);\n const buffer = await response.arrayBuffer();\n\n return new Uint8Array(buffer);\n });\n }\n\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n };\n const token = this.tokenStorage.get();\n if (token) {\n headers['Authorization'] = `Bearer ${token.accessToken}`;\n }\n return headers;\n }\n\n private async sendRequest(method: string, url: string, body?: Record<string, unknown>): Promise<Response> {\n const options: RequestInit = { headers: this.buildHeaders() };\n if (body) options.body = JSON.stringify(body);\n\n return this.httpClient.request(method, url, options);\n }\n\n private async sendBinaryRequest(method: string, url: string): Promise<Response> {\n const headers = this.buildHeaders();\n delete headers['Content-Type'];\n\n const response = await this.httpClient.request(method, url, { headers });\n if (!response.ok) {\n const text = await response.text();\n throw new HttpException(\n describeApiError(text, response.status),\n response.status,\n text,\n {},\n response.headers.get('retry-after'),\n );\n }\n return response;\n }\n\n private async parseJsonResponse(\n response: Response,\n acceptedStatuses: number[] = [200],\n ): Promise<Record<string, unknown>> {\n const responseText = await response.text();\n\n if (response.status === 422) {\n let errors: Record<string, string[]> = {};\n try {\n const parsed = JSON.parse(responseText) as Record<string, unknown>;\n if (parsed['errors'] !== null && typeof parsed['errors'] === 'object' && !Array.isArray(parsed['errors'])) {\n errors = parsed['errors'] as Record<string, string[]>;\n }\n } catch {\n // ignore parse errors\n }\n throw new ValidationException(jsonErrorMessage(responseText) ?? 'Validation failed', errors);\n }\n\n if (!response.ok && !acceptedStatuses.includes(response.status)) {\n throw new HttpException(\n describeApiError(responseText, response.status),\n response.status,\n responseText,\n {},\n response.headers.get('retry-after'),\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(responseText);\n } catch {\n throw new HttpException('Invalid JSON response', response.status, responseText);\n }\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new HttpException('Unexpected response format', response.status, responseText);\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj['data'] !== undefined && (typeof obj['data'] === 'object' || Array.isArray(obj['data']))) {\n return obj['data'] as Record<string, unknown>;\n }\n\n return obj;\n }\n\n private formatDate(date: Date | string): string {\n if (date instanceof Date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n if (!DATE_REGEX.test(date)) {\n throw new TaxoraException(`Invalid date format: \"${date}\". Expected YYYY-MM-DD.`);\n }\n\n return date;\n }\n}\n","export const Environment = {\n SANDBOX: 'sandbox',\n PRODUCTION: 'production',\n} as const;\n\nexport type Environment = (typeof Environment)[keyof typeof Environment];\n\nconst BASE_URLS: Record<Environment, string> = {\n [Environment.SANDBOX]: 'https://sandbox.taxora.io/v1',\n [Environment.PRODUCTION]: 'https://api.taxora.io/v1',\n};\n\nexport function getBaseUrl(environment: Environment): string {\n return BASE_URLS[environment];\n}\n","import { type HttpClientInterface } from './HttpClientInterface.js';\n\nexport class FetchHttpClient implements HttpClientInterface {\n async request(method: string, url: string, options: RequestInit = {}): Promise<Response> {\n return fetch(url, { ...options, method });\n }\n}\n","import { type Token } from '../dto/Token.js';\nimport { type TokenStorageInterface } from './TokenStorageInterface.js';\n\nexport class InMemoryTokenStorage implements TokenStorageInterface {\n private token: Token | null = null;\n\n get(): Token | null {\n return this.token;\n }\n\n set(token: Token): void {\n this.token = token;\n }\n\n clear(): void {\n this.token = null;\n }\n}\n","import { type Token } from '../dto/Token.js';\nimport { AuthenticationException } from '../exceptions/AuthenticationException.js';\nimport { type HttpClientInterface } from './HttpClientInterface.js';\nimport { type TokenStorageInterface } from './TokenStorageInterface.js';\n\nconst AUTH_PATH_PATTERN = /\\/auth\\//;\n\n/**\n * HTTP client wrapper that handles:\n * - Preemptive token refresh when the stored token is expired\n * - Automatic retry with a fresh token on 401 responses\n * - Passthrough for /auth/ routes (no interception)\n */\nexport class AuthRetryHttpClient implements HttpClientInterface {\n constructor(\n private readonly inner: HttpClientInterface,\n private readonly tokenStorage: TokenStorageInterface,\n private readonly refreshFn: () => Promise<Token>,\n ) {}\n\n async request(method: string, url: string, options?: RequestInit): Promise<Response> {\n // Auth routes bypass all retry logic\n if (AUTH_PATH_PATTERN.test(url)) {\n return this.inner.request(method, url, options);\n }\n\n // Preemptive refresh if token is expired\n const currentToken = this.tokenStorage.get();\n if (currentToken?.isExpired()) {\n await this.refreshFn();\n }\n\n // Build request with potentially refreshed token\n const updatedOptions = this.injectAuthHeader(options);\n const response = await this.inner.request(method, url, updatedOptions);\n\n // 401: refresh once and retry\n if (response.status === 401) {\n await this.refreshFn();\n const retryOptions = this.injectAuthHeader(options);\n const retryResponse = await this.inner.request(method, url, retryOptions);\n\n if (retryResponse.status === 401) {\n const body = await retryResponse.text();\n throw new AuthenticationException('Authentication failed after token refresh', { status: 401, body });\n }\n\n return retryResponse;\n }\n\n return response;\n }\n\n private injectAuthHeader(options?: RequestInit): RequestInit {\n const token = this.tokenStorage.get();\n if (!token) return options ?? {};\n\n const existing = options?.headers ?? {};\n const headers = { ...(existing as Record<string, string>), Authorization: `Bearer ${token.accessToken}` };\n return { ...(options ?? {}), headers };\n }\n}\n","/**\n * SDK version. Kept in sync with package.json by scripts/tag-release.sh.\n */\nexport const SDK_VERSION = '1.4.0';\n","import { type HttpClientInterface } from './HttpClientInterface.js';\nimport { SDK_VERSION } from '../version.js';\n\nconst SDK_VERSION_HEADER = 'X-Taxora-SDK-Version';\nconst SDK_VERSION_VALUE = `taxora-node/${SDK_VERSION}`;\n\n/**\n * HTTP client wrapper that stamps every outgoing request with the SDK version\n * header so the backend can record which SDK version made the call.\n *\n * Purely additive: it only merges in one header (without overwriting existing\n * ones) and delegates to the inner client.\n */\nexport class SdkVersionHttpClient implements HttpClientInterface {\n constructor(private readonly inner: HttpClientInterface) {}\n\n async request(method: string, url: string, options?: RequestInit): Promise<Response> {\n const existing = options?.headers ?? {};\n const headers = {\n ...(existing as Record<string, string>),\n [SDK_VERSION_HEADER]: SDK_VERSION_VALUE,\n };\n return this.inner.request(method, url, { ...(options ?? {}), headers });\n }\n}\n","import { AuthEndpoint } from '../endpoints/AuthEndpoint.js';\nimport { CompanyEndpoint } from '../endpoints/CompanyEndpoint.js';\nimport { EReportingEndpoint } from '../endpoints/EReportingEndpoint.js';\nimport { SmartEnrichmentEndpoint } from '../endpoints/SmartEnrichmentEndpoint.js';\nimport { VatEndpoint } from '../endpoints/VatEndpoint.js';\nimport { Environment, getBaseUrl } from '../enums/Environment.js';\nimport { type HttpClientInterface } from '../http/HttpClientInterface.js';\nimport { FetchHttpClient } from '../http/FetchHttpClient.js';\nimport { InMemoryTokenStorage } from '../http/InMemoryTokenStorage.js';\nimport { type TokenStorageInterface } from '../http/TokenStorageInterface.js';\nimport { AuthRetryHttpClient } from '../http/AuthRetryHttpClient.js';\nimport { SdkVersionHttpClient } from '../http/SdkVersionHttpClient.js';\nimport { RetryPolicy } from '../http/RetryPolicy.js';\n\nexport interface TaxoraClientOptions {\n apiKey: string;\n environment?: Environment;\n tokenStorage?: TokenStorageInterface;\n httpClient?: HttpClientInterface;\n /** Retry behaviour for transient gateway failures; defaults to 3 attempts with backoff. */\n retryPolicy?: RetryPolicy;\n}\n\nexport class TaxoraClient {\n public readonly auth: AuthEndpoint;\n public readonly vat: VatEndpoint;\n public readonly company: CompanyEndpoint;\n public readonly smartEnrichment: SmartEnrichmentEndpoint;\n public readonly eReporting: EReportingEndpoint;\n public readonly baseUrl: string;\n\n constructor(options: TaxoraClientOptions) {\n const environment = options.environment ?? Environment.SANDBOX;\n const tokenStorage = options.tokenStorage ?? new InMemoryTokenStorage();\n const httpClient = options.httpClient ?? new FetchHttpClient();\n const retryPolicy = options.retryPolicy ?? new RetryPolicy();\n\n // Wrap the transport so every request carries the SDK version header.\n const versionedClient = new SdkVersionHttpClient(httpClient);\n\n this.baseUrl = getBaseUrl(environment);\n\n // Auth endpoint uses the version-stamped client directly — no retry interception for auth routes\n this.auth = new AuthEndpoint(this.baseUrl, options.apiKey, tokenStorage, versionedClient, retryPolicy);\n\n // All other endpoints use the retry-capable client that handles 401 auto-refresh\n const retryClient = new AuthRetryHttpClient(versionedClient, tokenStorage, () => this.auth.refresh());\n\n this.vat = new VatEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);\n this.company = new CompanyEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);\n this.smartEnrichment = new SmartEnrichmentEndpoint(\n this.baseUrl,\n options.apiKey,\n tokenStorage,\n retryClient,\n retryPolicy,\n );\n this.eReporting = new EReportingEndpoint(this.baseUrl, options.apiKey, tokenStorage, retryClient, retryPolicy);\n }\n}\n","import { TaxoraClient, type TaxoraClientOptions } from './TaxoraClient.js';\n\nexport class TaxoraClientFactory {\n static create(options: TaxoraClientOptions): TaxoraClient {\n return new TaxoraClient(options);\n }\n}\n","export const ApiVersion = {\n V1: 'v1',\n} as const;\n\nexport type ApiVersion = (typeof ApiVersion)[keyof typeof ApiVersion];\n","export const Language = {\n ENGLISH: 'en',\n GERMAN: 'de',\n} as const;\n\nexport type Language = (typeof Language)[keyof typeof Language];\n","import { createHmac, timingSafeEqual } from 'node:crypto';\nimport { TaxoraException } from '../exceptions/TaxoraException.js';\nimport type { TaxoraWebhookEvent } from './WebhookEvent.js';\n\n/** Name of the HTTP header that carries the signature. Node lower-cases it: `req.headers['taxora-signature']`. */\nexport const WEBHOOK_SIGNATURE_HEADER = 'Taxora-Signature';\n\n/** Name of the HTTP header that carries the delivery UUID (stable across retries). */\nexport const WEBHOOK_ID_HEADER = 'Taxora-Webhook-Id';\n\n/** Default maximum age (seconds) of a signed request before it is rejected as a possible replay. */\nexport const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;\n\nconst SCHEME = 'v1';\n\n/** The exact bytes Taxora sent. Never pass a parsed-and-re-serialised object. */\nexport type WebhookRawBody = string | Uint8Array | ArrayBuffer;\n\n/** Header value as frameworks hand it over (Express/Node may give an array for repeated headers). */\nexport type WebhookSignatureHeaderInput = string | readonly string[] | null | undefined;\n\nexport interface WebhookVerifyOptions {\n /**\n * Maximum allowed difference between now and the signature timestamp, in seconds. Default 300.\n * `0` disables the check — not recommended, it re-opens replay attacks.\n */\n tolerance?: number;\n /** Current time in Unix seconds. Only meant for tests. */\n now?: number;\n}\n\nexport type WebhookSignatureErrorReason =\n | 'missing_secret'\n | 'missing_header'\n | 'malformed_header'\n | 'invalid_body'\n | 'timestamp_outside_tolerance'\n | 'no_matching_signature'\n | 'invalid_payload';\n\nexport class WebhookSignatureVerificationError extends TaxoraException {\n public readonly reason: WebhookSignatureErrorReason;\n\n constructor(message: string, reason: WebhookSignatureErrorReason, context: Record<string, unknown> = {}) {\n super(message, { ...context, reason });\n this.name = 'WebhookSignatureVerificationError';\n this.reason = reason;\n }\n}\n\nexport interface ParsedWebhookSignatureHeader {\n timestamp: number;\n /** All `v1` signatures — two during a secret rotation on Taxora's side. */\n signatures: string[];\n}\n\n/** Parses `t=<unix>,v1=<hex>[,v1=<hex>…]`. Unknown schemes are ignored for forward compatibility. */\nexport function parseWebhookSignatureHeader(header: WebhookSignatureHeaderInput): ParsedWebhookSignatureHeader {\n const value = Array.isArray(header) ? header[0] : header;\n if (typeof value !== 'string' || value.trim() === '') {\n throw new WebhookSignatureVerificationError(\n `Missing ${WEBHOOK_SIGNATURE_HEADER} header. Is signing enabled for this webhook endpoint?`,\n 'missing_header',\n );\n }\n\n let timestamp: number | null = null;\n const signatures: string[] = [];\n\n for (const part of value.split(',')) {\n const separator = part.indexOf('=');\n if (separator === -1) continue;\n const key = part.slice(0, separator).trim();\n const val = part.slice(separator + 1).trim();\n\n if (key === 't' && /^\\d+$/.test(val)) {\n timestamp = Number(val);\n } else if (key === SCHEME && /^[0-9a-f]{64}$/i.test(val)) {\n signatures.push(val.toLowerCase());\n }\n }\n\n if (timestamp === null || signatures.length === 0) {\n throw new WebhookSignatureVerificationError(\n `Malformed ${WEBHOOK_SIGNATURE_HEADER} header — expected \"t=<unix>,v1=<hex>\".`,\n 'malformed_header',\n );\n }\n\n return { timestamp, signatures };\n}\n\n/** hex(HMAC-SHA256(secret, `${timestamp}.${rawBody}`)) — the value Taxora puts into `v1=`. */\nexport function computeWebhookSignature(rawBody: WebhookRawBody, timestamp: number, secret: string): string {\n return createHmac('sha256', secret).update(`${timestamp}.`).update(toBytes(rawBody)).digest('hex');\n}\n\n/**\n * Builds a valid `Taxora-Signature` header value for a payload — handy for unit-testing your webhook handler\n * without calling Taxora.\n */\nexport function generateWebhookSignatureHeader(\n rawBody: WebhookRawBody,\n secret: string | readonly string[],\n timestamp: number = Math.floor(Date.now() / 1000),\n): string {\n const secrets = normalizeSecrets(secret);\n return [`t=${timestamp}`, ...secrets.map((s) => `${SCHEME}=${computeWebhookSignature(rawBody, timestamp, s)}`)].join(\n ',',\n );\n}\n\n/**\n * Verifies a Taxora webhook request. Returns `true` or throws {@link WebhookSignatureVerificationError}.\n *\n * - `rawBody` must be the unmodified request body (e.g. `express.raw()`, `await request.text()`).\n * - `secret` may be a list — useful while you rotate the secret on your side.\n * - The comparison is constant-time; the timestamp must be within `tolerance` seconds (default 300).\n */\nexport function verifyWebhookSignature(\n rawBody: WebhookRawBody,\n header: WebhookSignatureHeaderInput,\n secret: string | readonly string[],\n options: WebhookVerifyOptions = {},\n): true {\n const secrets = normalizeSecrets(secret);\n const bytes = toBytes(rawBody);\n const { timestamp, signatures } = parseWebhookSignatureHeader(header);\n\n const tolerance = options.tolerance ?? DEFAULT_WEBHOOK_TOLERANCE_SECONDS;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n if (tolerance > 0 && Math.abs(now - timestamp) > tolerance) {\n throw new WebhookSignatureVerificationError(\n `Timestamp outside the tolerance window (${tolerance}s). Possible replay — or check the server clock.`,\n 'timestamp_outside_tolerance',\n { timestamp, now, tolerance },\n );\n }\n\n const received = signatures.map((s) => Buffer.from(s, 'hex'));\n for (const s of secrets) {\n const expected = Buffer.from(computeWebhookSignature(bytes, timestamp, s), 'hex');\n // Check every pair (no early exit per secret) so timing does not reveal which entry matched.\n let matched = false;\n for (const candidate of received) {\n if (candidate.length === expected.length && timingSafeEqual(candidate, expected)) {\n matched = true;\n }\n }\n if (matched) return true;\n }\n\n throw new WebhookSignatureVerificationError(\n 'No signature matches the expected signature for this payload. Make sure you pass the raw request body ' +\n '(not re-serialised JSON) and the full secret including the \"whsec_\" prefix.',\n 'no_matching_signature',\n );\n}\n\n/**\n * Verifies the signature and returns the parsed, typed event. Throws {@link WebhookSignatureVerificationError}\n * on any problem — respond with HTTP 400 in that case.\n *\n * ```ts\n * app.post('/taxora-webhook', express.raw({ type: 'application/json' }), (req, res) => {\n * const event = constructWebhookEvent(req.body, req.header('Taxora-Signature'), process.env.TAXORA_WEBHOOK_SECRET!);\n * if (event.event === 'vat.validated') { ... }\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function constructWebhookEvent<T extends TaxoraWebhookEvent = TaxoraWebhookEvent>(\n rawBody: WebhookRawBody,\n header: WebhookSignatureHeaderInput,\n secret: string | readonly string[],\n options: WebhookVerifyOptions = {},\n): T {\n verifyWebhookSignature(rawBody, header, secret, options);\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.from(toBytes(rawBody)).toString('utf8'));\n } catch {\n throw new WebhookSignatureVerificationError('Webhook payload is not valid JSON.', 'invalid_payload');\n }\n\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n typeof (parsed as { id?: unknown }).id !== 'string' ||\n typeof (parsed as { event?: unknown }).event !== 'string' ||\n typeof (parsed as { data?: unknown }).data !== 'object'\n ) {\n throw new WebhookSignatureVerificationError(\n 'Webhook payload does not have the expected { id, event, timestamp, data } shape.',\n 'invalid_payload',\n );\n }\n\n return parsed as T;\n}\n\nfunction normalizeSecrets(secret: string | readonly string[]): string[] {\n const list = (typeof secret === 'string' ? [secret] : [...secret]).filter(\n (s): s is string => typeof s === 'string' && s !== '',\n );\n if (list.length === 0) {\n throw new WebhookSignatureVerificationError(\n 'No webhook signing secret given. Copy it from the Taxora dashboard (Developer → Webhooks).',\n 'missing_secret',\n );\n }\n return list;\n}\n\nfunction toBytes(rawBody: WebhookRawBody): Uint8Array {\n if (typeof rawBody === 'string') return Buffer.from(rawBody, 'utf8');\n if (rawBody instanceof Uint8Array) return rawBody;\n if (rawBody instanceof ArrayBuffer) return new Uint8Array(rawBody);\n throw new WebhookSignatureVerificationError(\n 'Webhook body must be the raw request body (string, Buffer or Uint8Array). It looks like it was already ' +\n 'parsed as JSON — use express.raw() / request.text() instead of a JSON body parser.',\n 'invalid_body',\n );\n}\n"],"mappings":"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","names":["VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","asString","asNullableString","asNumber","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","asString","asNullableString","asNumber","asMoney","asNullableNumber","VALUES","DESCRIPTIONS","asString","asNullableString","asString","asNullableString","asString","asNumber","asMoney","asString","asNullableString","asString","asNumber","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","VALUES","DESCRIPTIONS","asString","asNumber","asRecord","asRecords","DESCRIPTIONS","DATE_REGEX","parsed"]}
|