@beliq/sdk 0.4.2 → 0.4.4

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 CHANGED
@@ -4,6 +4,48 @@
4
4
  resolves 0.4.x and never reaches 0.5.0. Additive spec syncs ship as patches for
5
5
  that reason, and a minor is reserved for a change that needs consumers to opt in.
6
6
 
7
+ ## 0.4.4 - 2026-10-02
8
+
9
+ - Invoices carry additional supporting documents (BG-24) as
10
+ `supportingDocuments`, at most 50 of them: `id` (BT-122), which BR-52
11
+ requires, `description` (BT-123), `externalLocation` (BT-124) and
12
+ `attachment` (BT-125) with the file as base64 `content`, its `mimeCode` and
13
+ its `filename`. An entry can carry a URL, a file, both or neither. Output is
14
+ a CII `ram:AdditionalReferencedDocument` with type code 916, from the
15
+ Factur-X EN16931 profile up, and a UBL `cac:AdditionalDocumentReference`
16
+ with no document type code (UBL-SR-43 admits none here). Factur-X MINIMUM,
17
+ BASIC_WL and BASIC have no slot for it and drop it after the same checks, as
18
+ do the fatturapa, facturae, eslog and ksef targets. Content that is not
19
+ base64, or that decodes to no bytes, is a 400. On XRechnung BR-DE-22 refuses
20
+ two attachments sharing a `filename`, and DE-R-022 does the same on Peppol
21
+ BIS between two German parties; both compare names as written, so names
22
+ differing only in case pass. An attachment counts toward the 1 MiB body
23
+ limit of `POST /v1/generate`, and base64 takes four bytes for every three of
24
+ the file.
25
+ - The `format` query parameter of `/v1/parse` now describes itself: it is
26
+ checked against the allowed values and otherwise ignored, because the syntax
27
+ is always read from the document itself. `/v1/parse` shares the invoice
28
+ shape and fills neither `supportingDocuments` nor the fields 0.4.3 added.
29
+
30
+ ## 0.4.3 - 2026-09-26
31
+
32
+ Never published to npm: the release job refused the tag, because `package.json`
33
+ read 0.4.2 at the commit it pointed at. 0.4.4 is the first release that carries
34
+ the changes below.
35
+
36
+ - Invoices can name a payee (BG-10) and a tax representative (BG-11), as
37
+ `payee` and `taxRepresentative`, and state `paidAmount` (BT-113) and
38
+ `roundingAmount` (BT-114), from which the API derives the amount due
39
+ (BT-115). A payee with the seller's name or registration identifier is a
40
+ 400. With a payee, UBL output writes `paymentMeans.creditorId` (BT-90) on
41
+ the payee rather than the seller.
42
+ - `typeCode` (BT-3) sets the document type code within `documentType`, such as
43
+ `384` for a corrected invoice. A code from the other document type's half of
44
+ BR-CL-01 is a 400, and the fatturapa, facturae and eslog targets answer 422
45
+ `DOCUMENT_TYPE_STANDARD_MISMATCH`.
46
+ - `precedingInvoiceReference` (BG-3) is written on invoices as well as credit
47
+ notes. `/v1/parse` shares the invoice shape and fills none of the new fields.
48
+
7
49
  ## 0.4.2 - 2026-09-23
8
50
 
9
51
  - Invoices carry allowances and charges at document level (BG-20, BG-21) and
@@ -63,7 +105,7 @@ that reason, and a minor is reserved for a change that needs consumers to opt in
63
105
  - A per-attempt deadline, and transient failures are retried.
64
106
  - The transport defaults are exported from the package entry point, so a caller
65
107
  can read the timeout and retry values the SDK ships with.
66
- - The vendored `openapi.json` is asserted byte-identical to what beliq-api
108
+ - The vendored `openapi.json` is asserted byte-identical to what the API
67
109
  generates, and the drift check is directional in the code rather than only in
68
110
  its comment. Ten Peppol emit error codes, the 413 responses, the verdict
69
111
  verification tier and the `/v1/me` response shape are typed; two error codes
package/README.md CHANGED
@@ -171,7 +171,7 @@ try {
171
171
  `src/generated/schema.ts` is generated from a vendored copy of the published OpenAPI spec (`openapi.json`).
172
172
 
173
173
  ```bash
174
- npm run sync:spec # refresh openapi.json from beliq-api / the live spec
174
+ npm run sync:spec # refresh openapi.json from the live spec (or BELIQ_OPENAPI_PATH)
175
175
  npm run gen:types # regenerate src/generated/schema.ts
176
176
  npm run openapi:check # CI drift guard: fails if the generated types are stale
177
177
  ```
@@ -50,7 +50,7 @@ declare const LIVE_PROFILES: readonly ["basicwl", "en16931", "extended", "extend
50
50
  *
51
51
  * `profile` is not a free enum: the engine pins it per standard and answers a
52
52
  * pair outside the table with `422 PROFILE_STANDARD_MISMATCH`
53
- * (beliq-engine `app/routes/generate.py`, ALLOWED_PROFILES_FOR_STANDARD). A
53
+ * (the engine's ALLOWED_PROFILES_FOR_STANDARD table). A
54
54
  * surface that offers one flat profile list therefore offers values that cannot
55
55
  * succeed: none of the Factur-X granularity values is legal for `xrechnung` or
56
56
  * `peppol-bis`, and `extended-ctc-fr` is the AFNOR XP Z12-012 France CTC overlay
@@ -58,7 +58,7 @@ declare const LIVE_PROFILES: readonly ["basicwl", "en16931", "extended", "extend
58
58
  *
59
59
  * Narrower than the engine's own table in two places, both deliberate: the
60
60
  * `minimum` and `basic` Factur-X profiles are engine-supported but withheld
61
- * (FNFE-MPE source gating, mirroring beliq-types SUPPORTED_FACTURX_PROFILE_IDS),
61
+ * (FNFE-MPE source gating),
62
62
  * and the standards outside LIVE_GENERATE_STANDARDS are absent entirely.
63
63
  *
64
64
  * `scripts/check-profile-drift.mjs` compares this against the engine's table.
@@ -50,7 +50,7 @@ declare const LIVE_PROFILES: readonly ["basicwl", "en16931", "extended", "extend
50
50
  *
51
51
  * `profile` is not a free enum: the engine pins it per standard and answers a
52
52
  * pair outside the table with `422 PROFILE_STANDARD_MISMATCH`
53
- * (beliq-engine `app/routes/generate.py`, ALLOWED_PROFILES_FOR_STANDARD). A
53
+ * (the engine's ALLOWED_PROFILES_FOR_STANDARD table). A
54
54
  * surface that offers one flat profile list therefore offers values that cannot
55
55
  * succeed: none of the Factur-X granularity values is legal for `xrechnung` or
56
56
  * `peppol-bis`, and `extended-ctc-fr` is the AFNOR XP Z12-012 France CTC overlay
@@ -58,7 +58,7 @@ declare const LIVE_PROFILES: readonly ["basicwl", "en16931", "extended", "extend
58
58
  *
59
59
  * Narrower than the engine's own table in two places, both deliberate: the
60
60
  * `minimum` and `basic` Factur-X profiles are engine-supported but withheld
61
- * (FNFE-MPE source gating, mirroring beliq-types SUPPORTED_FACTURX_PROFILE_IDS),
61
+ * (FNFE-MPE source gating),
62
62
  * and the standards outside LIVE_GENERATE_STANDARDS are absent entirely.
63
63
  *
64
64
  * `scripts/check-profile-drift.mjs` compares this against the engine's table.
@@ -1,5 +1,5 @@
1
- import { P as PlainObject } from './constants-BZuNzqbV.cjs';
2
- export { D as DEFAULT_BASE_URL, a as DocumentInput, G as GeneratePreset, L as LIVE_CONVERT_SOURCE_FORMATS, b as LIVE_CONVERT_TARGET_FORMATS, c as LIVE_GENERATE_PRESETS, d as LIVE_GENERATE_STANDARDS, e as LIVE_PARSE_FORMATS, f as LIVE_PROFILES, g as LIVE_PROFILES_BY_STANDARD, h as LIVE_VALIDATE_FORMATS, i as compactQuery, j as decodeUtf8, k as isPlainObject, l as isProfileAllowedForStandard, m as mergeDeep, p as profilesForStandard, s as sniffContentType, t as toBytes } from './constants-BZuNzqbV.cjs';
1
+ import { P as PlainObject } from './constants-CIRzGHqn.cjs';
2
+ export { D as DEFAULT_BASE_URL, a as DocumentInput, G as GeneratePreset, L as LIVE_CONVERT_SOURCE_FORMATS, b as LIVE_CONVERT_TARGET_FORMATS, c as LIVE_GENERATE_PRESETS, d as LIVE_GENERATE_STANDARDS, e as LIVE_PARSE_FORMATS, f as LIVE_PROFILES, g as LIVE_PROFILES_BY_STANDARD, h as LIVE_VALIDATE_FORMATS, i as compactQuery, j as decodeUtf8, k as isPlainObject, l as isProfileAllowedForStandard, m as mergeDeep, p as profilesForStandard, s as sniffContentType, t as toBytes } from './constants-CIRzGHqn.cjs';
3
3
 
4
4
  type Operation = 'me' | 'generate' | 'validate' | 'parse' | 'convert';
5
5
  /** 'json' => parse the `{ success, data }` envelope; 'binary' => return raw bytes. */
package/dist/helpers.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PlainObject } from './constants-BZuNzqbV.js';
2
- export { D as DEFAULT_BASE_URL, a as DocumentInput, G as GeneratePreset, L as LIVE_CONVERT_SOURCE_FORMATS, b as LIVE_CONVERT_TARGET_FORMATS, c as LIVE_GENERATE_PRESETS, d as LIVE_GENERATE_STANDARDS, e as LIVE_PARSE_FORMATS, f as LIVE_PROFILES, g as LIVE_PROFILES_BY_STANDARD, h as LIVE_VALIDATE_FORMATS, i as compactQuery, j as decodeUtf8, k as isPlainObject, l as isProfileAllowedForStandard, m as mergeDeep, p as profilesForStandard, s as sniffContentType, t as toBytes } from './constants-BZuNzqbV.js';
1
+ import { P as PlainObject } from './constants-CIRzGHqn.js';
2
+ export { D as DEFAULT_BASE_URL, a as DocumentInput, G as GeneratePreset, L as LIVE_CONVERT_SOURCE_FORMATS, b as LIVE_CONVERT_TARGET_FORMATS, c as LIVE_GENERATE_PRESETS, d as LIVE_GENERATE_STANDARDS, e as LIVE_PARSE_FORMATS, f as LIVE_PROFILES, g as LIVE_PROFILES_BY_STANDARD, h as LIVE_VALIDATE_FORMATS, i as compactQuery, j as decodeUtf8, k as isPlainObject, l as isProfileAllowedForStandard, m as mergeDeep, p as profilesForStandard, s as sniffContentType, t as toBytes } from './constants-CIRzGHqn.js';
3
3
 
4
4
  type Operation = 'me' | 'generate' | 'validate' | 'parse' | 'convert';
5
5
  /** 'json' => parse the `{ success, data }` envelope; 'binary' => return raw bytes. */
package/dist/index.cjs CHANGED
@@ -332,6 +332,11 @@ async function send(config, req) {
332
332
 
333
333
  // src/client.ts
334
334
  var TEST_KEY_PREFIX = "blq_test_";
335
+ function trimTrailingSlashes(url) {
336
+ let end = url.length;
337
+ while (end > 0 && url[end - 1] === "/") end--;
338
+ return url.slice(0, end);
339
+ }
335
340
  function livemodeHeader(headers) {
336
341
  const raw = headers.get("x-beliq-livemode");
337
342
  if (raw === "true") return true;
@@ -396,7 +401,7 @@ var Beliq = class {
396
401
  this.livemode = !options.apiKey.startsWith(TEST_KEY_PREFIX);
397
402
  this.#config = {
398
403
  apiKey: options.apiKey,
399
- baseUrl: (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, ""),
404
+ baseUrl: trimTrailingSlashes(options.baseUrl ?? DEFAULT_BASE_URL),
400
405
  auth: options.auth ?? "header",
401
406
  fetchImpl,
402
407
  timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,