@beliq/sdk 0.3.0 → 0.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/README.md +28 -2
- package/dist/index.cjs +10 -4
- package/dist/index.d.cts +109 -46
- package/dist/index.d.ts +109 -46
- package/dist/index.js +10 -4
- package/examples/invoice.json +64 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -26,13 +26,33 @@ const account = await beliq.me();
|
|
|
26
26
|
const generated = await beliq.generate({
|
|
27
27
|
standard: 'xrechnung',
|
|
28
28
|
verify: true,
|
|
29
|
+
// The XRechnung CIUS asks for more than plain EN 16931: a seller contact
|
|
30
|
+
// (BR-DE-2), payment instructions (BR-DE-1), a VAT breakdown (BR-CO-18) and an
|
|
31
|
+
// electronic address for each party. examples/invoice.json is this same shape.
|
|
29
32
|
invoice: {
|
|
30
33
|
number: 'INV-2026-001',
|
|
31
34
|
issueDate: '2026-01-15',
|
|
32
35
|
currencyCode: 'EUR',
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
buyerReference: '04011000-12345-06',
|
|
37
|
+
seller: {
|
|
38
|
+
name: 'Seller GmbH',
|
|
39
|
+
vatId: 'DE123456789',
|
|
40
|
+
contactName: 'Anna Muster',
|
|
41
|
+
email: 'billing@seller.example',
|
|
42
|
+
phone: '+49 30 1234567',
|
|
43
|
+
address: { street: 'Hauptstr. 1', city: 'Berlin', postalCode: '10115', countryCode: 'DE' },
|
|
44
|
+
peppol: { schemeId: '9930', id: 'DE123456789' },
|
|
45
|
+
},
|
|
46
|
+
buyer: {
|
|
47
|
+
name: 'Buyer GmbH',
|
|
48
|
+
vatId: 'DE987654321',
|
|
49
|
+
email: 'ap@buyer.example',
|
|
50
|
+
address: { street: 'Marktweg 2', city: 'Munich', postalCode: '80331', countryCode: 'DE' },
|
|
51
|
+
peppol: { schemeId: '9930', id: 'DE987654321' },
|
|
52
|
+
},
|
|
35
53
|
lines: [{ description: 'Consulting', quantity: 10, unitCode: 'HUR', unitPrice: 100, lineTotal: 1000, vatRate: 19, vatCategoryCode: 'S' }],
|
|
54
|
+
taxSummary: [{ vatCategoryCode: 'S', vatRate: 19, taxableAmount: 1000, taxAmount: 190 }],
|
|
55
|
+
paymentMeans: { typeCode: '58', iban: 'DE89370400440532013000' },
|
|
36
56
|
totalNetAmount: 1000,
|
|
37
57
|
totalTaxAmount: 190,
|
|
38
58
|
totalGrossAmount: 1190,
|
|
@@ -88,6 +108,11 @@ costs you a second document.
|
|
|
88
108
|
the work may still be running on beliq's side, so retrying risks producing a
|
|
89
109
|
second document rather than recovering the first.
|
|
90
110
|
|
|
111
|
+
A `429` carrying `QUOTA_EXCEEDED` is not retried either. `RATE_LIMITED` and
|
|
112
|
+
`ACCOUNT_THROTTLED` clear on their own, but a spent monthly allowance only returns
|
|
113
|
+
when your billing window turns, so the error is raised straight away and names the
|
|
114
|
+
cause instead of sleeping against it.
|
|
115
|
+
|
|
91
116
|
The default deadline is generous because beliq runs the full Schematron rule set
|
|
92
117
|
over each document, and a generate or validate can legitimately take tens of
|
|
93
118
|
seconds. If you lower it, keep it above the latency you actually see: a deadline
|
|
@@ -160,6 +185,7 @@ npm install
|
|
|
160
185
|
npm run build # tsup: dual ESM + CJS + d.ts
|
|
161
186
|
npm run typecheck
|
|
162
187
|
npm run lint
|
|
188
|
+
npm run scrub:check # no em-dash in any tracked file
|
|
163
189
|
npm test # unit tests (no network)
|
|
164
190
|
BELIQ_API_KEY=blq_xxx npm run test:integration # hits the live API; draws quota
|
|
165
191
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -255,6 +255,11 @@ var LIVE_CONVERT_TARGET_FORMATS = [
|
|
|
255
255
|
|
|
256
256
|
// src/transport.ts
|
|
257
257
|
var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 502, 503]);
|
|
258
|
+
var QUOTA_EXHAUSTED_CODE = "QUOTA_EXCEEDED";
|
|
259
|
+
function isRetryable(status, code) {
|
|
260
|
+
if (!RETRYABLE_STATUSES.has(status)) return false;
|
|
261
|
+
return !(status === 429 && code === QUOTA_EXHAUSTED_CODE);
|
|
262
|
+
}
|
|
258
263
|
var MAX_RETRY_AFTER_MS = 3e4;
|
|
259
264
|
var BACKOFF_BASE_MS = 500;
|
|
260
265
|
function authHeaders(config) {
|
|
@@ -302,12 +307,13 @@ async function send(config, req) {
|
|
|
302
307
|
});
|
|
303
308
|
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
304
309
|
if (res.ok) return { status: res.status, headers: res.headers, bytes };
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
310
|
+
const apiError = errorFromResponse(res.status, bytes);
|
|
311
|
+
lastError = apiError;
|
|
312
|
+
if (!isRetryable(apiError.status, apiError.code) || attempt === config.maxRetries) {
|
|
313
|
+
throw apiError;
|
|
308
314
|
}
|
|
309
315
|
} catch (err) {
|
|
310
|
-
if (err instanceof BeliqApiError && !
|
|
316
|
+
if (err instanceof BeliqApiError && !isRetryable(err.status, err.code)) throw err;
|
|
311
317
|
if (controller.signal.aborted) {
|
|
312
318
|
throw new BeliqApiError(
|
|
313
319
|
`beliq: request to ${req.path} exceeded ${config.timeoutMs}ms`,
|