@beliq/sdk 0.1.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/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/constants-bWOXCmJD.d.cts +22 -0
- package/dist/constants-bWOXCmJD.d.ts +22 -0
- package/dist/helpers.cjs +200 -0
- package/dist/helpers.d.cts +44 -0
- package/dist/helpers.d.ts +44 -0
- package/dist/helpers.js +160 -0
- package/dist/index.cjs +367 -0
- package/dist/index.d.cts +985 -0
- package/dist/index.d.ts +985 -0
- package/dist/index.js +332 -0
- package/package.json +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) beliq
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# @beliq/sdk
|
|
2
|
+
|
|
3
|
+
Official Node/TypeScript SDK for the [beliq](https://beliq.eu) e-invoicing compliance API. Generate, validate, parse, and convert EN 16931 invoices (XRechnung, ZUGFeRD, Factur-X, Peppol BIS) against authority-pinned, nightly-drift-checked rules.
|
|
4
|
+
|
|
5
|
+
beliq produces and checks the compliant document. Transmission (Peppol, PDP, KSeF, SDI), archiving, and tax-authority reporting stay with your access point.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @beliq/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires Node >= 20.15. Ships ESM and CommonJS builds with bundled type declarations.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Beliq } from '@beliq/sdk';
|
|
19
|
+
|
|
20
|
+
const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });
|
|
21
|
+
|
|
22
|
+
// Account, plan, and quota context (no quota cost).
|
|
23
|
+
const account = await beliq.me();
|
|
24
|
+
|
|
25
|
+
// Generate an XRechnung document from an EN 16931 invoice object.
|
|
26
|
+
const generated = await beliq.generate({
|
|
27
|
+
standard: 'xrechnung',
|
|
28
|
+
verify: true,
|
|
29
|
+
invoice: {
|
|
30
|
+
number: 'INV-2026-001',
|
|
31
|
+
issueDate: '2026-01-15',
|
|
32
|
+
currencyCode: 'EUR',
|
|
33
|
+
seller: { name: 'Seller GmbH', address: { city: 'Berlin', postalCode: '10115', countryCode: 'DE' } },
|
|
34
|
+
buyer: { name: 'Buyer GmbH', address: { city: 'Munich', postalCode: '80331', countryCode: 'DE' } },
|
|
35
|
+
lines: [{ description: 'Consulting', quantity: 10, unitCode: 'HUR', unitPrice: 100, lineTotal: 1000, vatRate: 19, vatCategoryCode: 'S' }],
|
|
36
|
+
totalNetAmount: 1000,
|
|
37
|
+
totalTaxAmount: 190,
|
|
38
|
+
totalGrossAmount: 1190,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
console.log(generated.xml, generated.meta.schematronVersion);
|
|
42
|
+
|
|
43
|
+
// Validate any document against authority-pinned rules.
|
|
44
|
+
const result = await beliq.validate(generated.xml!, { format: 'auto' });
|
|
45
|
+
if (!result.valid) {
|
|
46
|
+
for (const issue of result.errors) console.log(issue.ruleId, issue.message);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Authentication
|
|
51
|
+
|
|
52
|
+
Create an API key in the beliq dashboard under API Keys, then pass it to the client:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
new Beliq({ apiKey: 'blq_...' }); // sends X-API-Key (default)
|
|
56
|
+
new Beliq({ apiKey: 'blq_...', auth: 'bearer' }); // sends Authorization: Bearer
|
|
57
|
+
new Beliq({ apiKey: 'blq_...', baseUrl: 'https://staging.beliq.eu' });
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
| Method | Endpoint | Input | Returns |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| `me()` | GET /v1/me | none | `AccountInfo` (no quota cost) |
|
|
65
|
+
| `generate(input)` | POST /v1/generate | EN 16931 invoice object | `{ contentType, bytes, xml?, meta }` |
|
|
66
|
+
| `validate(document, options?)` | POST /v1/validate | XML or PDF | `ValidationResult` |
|
|
67
|
+
| `parse(document, options?)` | POST /v1/parse | XML or PDF | `ParseResult` |
|
|
68
|
+
| `convert(document, options)` | POST /v1/convert | XML or PDF | `{ contentType, bytes, meta }` |
|
|
69
|
+
|
|
70
|
+
`document` accepts a `string`, `Uint8Array`, `Buffer`, `ArrayBuffer`, or typed array. The content type is sniffed from the bytes (PDF vs XML) unless you pass `options.contentType`. `generate` and `convert` return raw document bytes plus the response-header metadata (`schematronVersion`, `pdfKind`, `sourceFormat`/`targetFormat`, `lostElements`, `conversionTools`); for an XML output, `generate` also decodes `xml`.
|
|
71
|
+
|
|
72
|
+
Every option enum is typed from the OpenAPI spec, so wrong values fail at compile time. Errors throw `BeliqApiError` with a typed `.code`, HTTP `.status`, and any `.details`:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import { BeliqApiError } from '@beliq/sdk';
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
await beliq.validate('not xml');
|
|
79
|
+
} catch (err) {
|
|
80
|
+
if (err instanceof BeliqApiError) console.log(err.code, err.status, err.message);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Types stay in sync with the API
|
|
85
|
+
|
|
86
|
+
`src/generated/schema.ts` is generated from a vendored copy of the published OpenAPI spec (`openapi.json`).
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm run sync:spec # refresh openapi.json from beliq-api / the live spec
|
|
90
|
+
npm run gen:types # regenerate src/generated/schema.ts
|
|
91
|
+
npm run openapi:check # CI drift guard: fails if the generated types are stale
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The vendored spec is committed so builds are reproducible; nothing is fetched from the network at build time.
|
|
95
|
+
|
|
96
|
+
## Development
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm install
|
|
100
|
+
npm run build # tsup: dual ESM + CJS + d.ts
|
|
101
|
+
npm run typecheck
|
|
102
|
+
npm run lint
|
|
103
|
+
npm test # unit tests (no network)
|
|
104
|
+
BELIQ_API_KEY=blq_xxx npm run test:integration # hits the live API; draws quota
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Publishing
|
|
108
|
+
|
|
109
|
+
Released to npm as [`@beliq/sdk`](https://www.npmjs.com/package/@beliq/sdk). Releases run from `.github/workflows/release.yml` via npm Trusted Publishing (OIDC, with provenance): push a `v*.*.*` tag to publish. No npm token is stored in the repo.
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
MIT
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type PlainObject = Record<string, unknown>;
|
|
2
|
+
declare function isPlainObject(value: unknown): value is PlainObject;
|
|
3
|
+
/** Deep-merge `source` into `target` (source wins). Arrays and scalars overwrite. */
|
|
4
|
+
declare function mergeDeep(target: PlainObject, source: PlainObject): PlainObject;
|
|
5
|
+
/** Drop undefined/empty entries so optional query params are omitted, not sent blank. */
|
|
6
|
+
declare function compactQuery(query: PlainObject): PlainObject;
|
|
7
|
+
/** Document bytes a caller may pass to validate/parse/convert. */
|
|
8
|
+
type DocumentInput = string | Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
9
|
+
declare function toBytes(input: DocumentInput): Uint8Array;
|
|
10
|
+
declare function decodeUtf8(bytes: Uint8Array): string;
|
|
11
|
+
/** Sniff `application/pdf` vs `application/xml` from the leading bytes. */
|
|
12
|
+
declare function sniffContentType(bytes: Uint8Array): string;
|
|
13
|
+
|
|
14
|
+
declare const DEFAULT_BASE_URL = "https://api.beliq.eu";
|
|
15
|
+
declare const LIVE_GENERATE_STANDARDS: readonly ["xrechnung", "zugferd", "facturx", "peppol-bis"];
|
|
16
|
+
declare const LIVE_PROFILES: readonly ["basicwl", "en16931", "extended", "extended-ctc-fr"];
|
|
17
|
+
declare const LIVE_VALIDATE_FORMATS: readonly ["auto", "cii", "ubl"];
|
|
18
|
+
declare const LIVE_PARSE_FORMATS: readonly ["auto", "cii", "ubl"];
|
|
19
|
+
declare const LIVE_CONVERT_SOURCE_FORMATS: readonly ["auto", "cii", "ubl", "zugferd", "facturx", "xrechnung", "peppol-bis"];
|
|
20
|
+
declare const LIVE_CONVERT_TARGET_FORMATS: readonly ["cii", "ubl", "zugferd", "facturx", "xrechnung", "peppol-bis"];
|
|
21
|
+
|
|
22
|
+
export { DEFAULT_BASE_URL as D, LIVE_CONVERT_SOURCE_FORMATS as L, type PlainObject as P, type DocumentInput as a, LIVE_CONVERT_TARGET_FORMATS as b, LIVE_GENERATE_STANDARDS as c, LIVE_PARSE_FORMATS as d, LIVE_PROFILES as e, LIVE_VALIDATE_FORMATS as f, compactQuery as g, decodeUtf8 as h, isPlainObject as i, mergeDeep as m, sniffContentType as s, toBytes as t };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type PlainObject = Record<string, unknown>;
|
|
2
|
+
declare function isPlainObject(value: unknown): value is PlainObject;
|
|
3
|
+
/** Deep-merge `source` into `target` (source wins). Arrays and scalars overwrite. */
|
|
4
|
+
declare function mergeDeep(target: PlainObject, source: PlainObject): PlainObject;
|
|
5
|
+
/** Drop undefined/empty entries so optional query params are omitted, not sent blank. */
|
|
6
|
+
declare function compactQuery(query: PlainObject): PlainObject;
|
|
7
|
+
/** Document bytes a caller may pass to validate/parse/convert. */
|
|
8
|
+
type DocumentInput = string | Uint8Array | ArrayBuffer | ArrayBufferView;
|
|
9
|
+
declare function toBytes(input: DocumentInput): Uint8Array;
|
|
10
|
+
declare function decodeUtf8(bytes: Uint8Array): string;
|
|
11
|
+
/** Sniff `application/pdf` vs `application/xml` from the leading bytes. */
|
|
12
|
+
declare function sniffContentType(bytes: Uint8Array): string;
|
|
13
|
+
|
|
14
|
+
declare const DEFAULT_BASE_URL = "https://api.beliq.eu";
|
|
15
|
+
declare const LIVE_GENERATE_STANDARDS: readonly ["xrechnung", "zugferd", "facturx", "peppol-bis"];
|
|
16
|
+
declare const LIVE_PROFILES: readonly ["basicwl", "en16931", "extended", "extended-ctc-fr"];
|
|
17
|
+
declare const LIVE_VALIDATE_FORMATS: readonly ["auto", "cii", "ubl"];
|
|
18
|
+
declare const LIVE_PARSE_FORMATS: readonly ["auto", "cii", "ubl"];
|
|
19
|
+
declare const LIVE_CONVERT_SOURCE_FORMATS: readonly ["auto", "cii", "ubl", "zugferd", "facturx", "xrechnung", "peppol-bis"];
|
|
20
|
+
declare const LIVE_CONVERT_TARGET_FORMATS: readonly ["cii", "ubl", "zugferd", "facturx", "xrechnung", "peppol-bis"];
|
|
21
|
+
|
|
22
|
+
export { DEFAULT_BASE_URL as D, LIVE_CONVERT_SOURCE_FORMATS as L, type PlainObject as P, type DocumentInput as a, LIVE_CONVERT_TARGET_FORMATS as b, LIVE_GENERATE_STANDARDS as c, LIVE_PARSE_FORMATS as d, LIVE_PROFILES as e, LIVE_VALIDATE_FORMATS as f, compactQuery as g, decodeUtf8 as h, isPlainObject as i, mergeDeep as m, sniffContentType as s, toBytes as t };
|
package/dist/helpers.cjs
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/helpers.ts
|
|
21
|
+
var helpers_exports = {};
|
|
22
|
+
__export(helpers_exports, {
|
|
23
|
+
DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
|
|
24
|
+
LIVE_CONVERT_SOURCE_FORMATS: () => LIVE_CONVERT_SOURCE_FORMATS,
|
|
25
|
+
LIVE_CONVERT_TARGET_FORMATS: () => LIVE_CONVERT_TARGET_FORMATS,
|
|
26
|
+
LIVE_GENERATE_STANDARDS: () => LIVE_GENERATE_STANDARDS,
|
|
27
|
+
LIVE_PARSE_FORMATS: () => LIVE_PARSE_FORMATS,
|
|
28
|
+
LIVE_PROFILES: () => LIVE_PROFILES,
|
|
29
|
+
LIVE_VALIDATE_FORMATS: () => LIVE_VALIDATE_FORMATS,
|
|
30
|
+
buildRequest: () => buildRequest,
|
|
31
|
+
compactQuery: () => compactQuery,
|
|
32
|
+
decodeUtf8: () => decodeUtf8,
|
|
33
|
+
isPlainObject: () => isPlainObject,
|
|
34
|
+
mergeDeep: () => mergeDeep,
|
|
35
|
+
sniffContentType: () => sniffContentType,
|
|
36
|
+
toBytes: () => toBytes
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(helpers_exports);
|
|
39
|
+
|
|
40
|
+
// src/internal.ts
|
|
41
|
+
function isPlainObject(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
function mergeDeep(target, source) {
|
|
45
|
+
const out = { ...target };
|
|
46
|
+
for (const [key, value] of Object.entries(source)) {
|
|
47
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
48
|
+
if (isPlainObject(value) && isPlainObject(out[key])) {
|
|
49
|
+
out[key] = mergeDeep(out[key], value);
|
|
50
|
+
} else {
|
|
51
|
+
out[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
function compactQuery(query) {
|
|
57
|
+
const out = {};
|
|
58
|
+
for (const [key, value] of Object.entries(query)) {
|
|
59
|
+
if (value === void 0 || value === "") continue;
|
|
60
|
+
out[key] = value;
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
function toBytes(input) {
|
|
65
|
+
if (typeof input === "string") return new TextEncoder().encode(input);
|
|
66
|
+
if (input instanceof Uint8Array) return input;
|
|
67
|
+
if (input instanceof ArrayBuffer) return new Uint8Array(input);
|
|
68
|
+
if (ArrayBuffer.isView(input)) {
|
|
69
|
+
return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
70
|
+
}
|
|
71
|
+
throw new TypeError("beliq: document must be a string, Uint8Array, ArrayBuffer, or typed array");
|
|
72
|
+
}
|
|
73
|
+
function decodeUtf8(bytes) {
|
|
74
|
+
return new TextDecoder("utf-8").decode(bytes);
|
|
75
|
+
}
|
|
76
|
+
var PDF_MAGIC = [37, 80, 68, 70, 45];
|
|
77
|
+
function sniffContentType(bytes) {
|
|
78
|
+
const isPdf = bytes.length >= PDF_MAGIC.length && PDF_MAGIC.every((b, i) => bytes[i] === b);
|
|
79
|
+
return isPdf ? "application/pdf" : "application/xml";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/buildRequest.ts
|
|
83
|
+
function isFacturxFamily(standardOrFormat) {
|
|
84
|
+
return standardOrFormat === "facturx" || standardOrFormat === "zugferd";
|
|
85
|
+
}
|
|
86
|
+
function withAdvancedQuery(query, advanced) {
|
|
87
|
+
const base = compactQuery(query);
|
|
88
|
+
const merged = advanced && Object.keys(advanced).length > 0 ? mergeDeep(base, advanced) : base;
|
|
89
|
+
return merged;
|
|
90
|
+
}
|
|
91
|
+
function buildRequest(params) {
|
|
92
|
+
switch (params.operation) {
|
|
93
|
+
case "me":
|
|
94
|
+
return { method: "GET", path: "/v1/me", outputKind: "json" };
|
|
95
|
+
case "generate": {
|
|
96
|
+
const body = {
|
|
97
|
+
standard: params.standard,
|
|
98
|
+
output: params.output ?? "xml",
|
|
99
|
+
invoice: params.invoice ?? {}
|
|
100
|
+
};
|
|
101
|
+
if (params.profile) body.profile = params.profile;
|
|
102
|
+
if (params.facturxProfile && isFacturxFamily(params.standard)) {
|
|
103
|
+
body.facturxProfile = params.facturxProfile;
|
|
104
|
+
}
|
|
105
|
+
if (typeof params.verify === "boolean") body.verify = params.verify;
|
|
106
|
+
if (params.template) body.template = params.template;
|
|
107
|
+
if (params.pdfTemplateId) body.pdfTemplateId = params.pdfTemplateId;
|
|
108
|
+
const merged = params.advanced && Object.keys(params.advanced).length > 0 ? mergeDeep(body, params.advanced) : body;
|
|
109
|
+
return {
|
|
110
|
+
method: "POST",
|
|
111
|
+
path: "/v1/generate",
|
|
112
|
+
jsonBody: merged,
|
|
113
|
+
contentType: "application/json",
|
|
114
|
+
outputKind: "binary"
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
case "validate": {
|
|
118
|
+
const query = { format: params.validateFormat };
|
|
119
|
+
if (typeof params.franceCtc === "boolean") query.franceCtc = params.franceCtc;
|
|
120
|
+
return {
|
|
121
|
+
method: "POST",
|
|
122
|
+
path: "/v1/validate",
|
|
123
|
+
query: withAdvancedQuery(query, params.advanced),
|
|
124
|
+
rawBody: params.rawBody,
|
|
125
|
+
contentType: params.rawContentType ?? "application/xml",
|
|
126
|
+
outputKind: "json"
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
case "parse":
|
|
130
|
+
return {
|
|
131
|
+
method: "POST",
|
|
132
|
+
path: "/v1/parse",
|
|
133
|
+
query: withAdvancedQuery({ format: params.parseFormat }, params.advanced),
|
|
134
|
+
rawBody: params.rawBody,
|
|
135
|
+
contentType: params.rawContentType ?? "application/xml",
|
|
136
|
+
outputKind: "json"
|
|
137
|
+
};
|
|
138
|
+
case "convert": {
|
|
139
|
+
const query = {
|
|
140
|
+
sourceFormat: params.sourceFormat,
|
|
141
|
+
targetFormat: params.targetFormat
|
|
142
|
+
};
|
|
143
|
+
if (params.targetProfile && isFacturxFamily(params.targetFormat)) {
|
|
144
|
+
query.targetProfile = params.targetProfile;
|
|
145
|
+
}
|
|
146
|
+
if (typeof params.dropFranceCtcOverlay === "boolean") {
|
|
147
|
+
query.dropFranceCtcOverlay = params.dropFranceCtcOverlay;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
method: "POST",
|
|
151
|
+
path: "/v1/convert",
|
|
152
|
+
query: withAdvancedQuery(query, params.advanced),
|
|
153
|
+
rawBody: params.rawBody,
|
|
154
|
+
contentType: params.rawContentType ?? "application/xml",
|
|
155
|
+
outputKind: "binary"
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/constants.ts
|
|
162
|
+
var DEFAULT_BASE_URL = "https://api.beliq.eu";
|
|
163
|
+
var LIVE_GENERATE_STANDARDS = ["xrechnung", "zugferd", "facturx", "peppol-bis"];
|
|
164
|
+
var LIVE_PROFILES = ["basicwl", "en16931", "extended", "extended-ctc-fr"];
|
|
165
|
+
var LIVE_VALIDATE_FORMATS = ["auto", "cii", "ubl"];
|
|
166
|
+
var LIVE_PARSE_FORMATS = ["auto", "cii", "ubl"];
|
|
167
|
+
var LIVE_CONVERT_SOURCE_FORMATS = [
|
|
168
|
+
"auto",
|
|
169
|
+
"cii",
|
|
170
|
+
"ubl",
|
|
171
|
+
"zugferd",
|
|
172
|
+
"facturx",
|
|
173
|
+
"xrechnung",
|
|
174
|
+
"peppol-bis"
|
|
175
|
+
];
|
|
176
|
+
var LIVE_CONVERT_TARGET_FORMATS = [
|
|
177
|
+
"cii",
|
|
178
|
+
"ubl",
|
|
179
|
+
"zugferd",
|
|
180
|
+
"facturx",
|
|
181
|
+
"xrechnung",
|
|
182
|
+
"peppol-bis"
|
|
183
|
+
];
|
|
184
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
185
|
+
0 && (module.exports = {
|
|
186
|
+
DEFAULT_BASE_URL,
|
|
187
|
+
LIVE_CONVERT_SOURCE_FORMATS,
|
|
188
|
+
LIVE_CONVERT_TARGET_FORMATS,
|
|
189
|
+
LIVE_GENERATE_STANDARDS,
|
|
190
|
+
LIVE_PARSE_FORMATS,
|
|
191
|
+
LIVE_PROFILES,
|
|
192
|
+
LIVE_VALIDATE_FORMATS,
|
|
193
|
+
buildRequest,
|
|
194
|
+
compactQuery,
|
|
195
|
+
decodeUtf8,
|
|
196
|
+
isPlainObject,
|
|
197
|
+
mergeDeep,
|
|
198
|
+
sniffContentType,
|
|
199
|
+
toBytes
|
|
200
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { P as PlainObject } from './constants-bWOXCmJD.cjs';
|
|
2
|
+
export { D as DEFAULT_BASE_URL, a as DocumentInput, L as LIVE_CONVERT_SOURCE_FORMATS, b as LIVE_CONVERT_TARGET_FORMATS, c as LIVE_GENERATE_STANDARDS, d as LIVE_PARSE_FORMATS, e as LIVE_PROFILES, f as LIVE_VALIDATE_FORMATS, g as compactQuery, h as decodeUtf8, i as isPlainObject, m as mergeDeep, s as sniffContentType, t as toBytes } from './constants-bWOXCmJD.cjs';
|
|
3
|
+
|
|
4
|
+
type Operation = 'me' | 'generate' | 'validate' | 'parse' | 'convert';
|
|
5
|
+
/** 'json' => parse the `{ success, data }` envelope; 'binary' => return raw bytes. */
|
|
6
|
+
type OutputKind = 'json' | 'binary';
|
|
7
|
+
type QueryValue = string | number | boolean;
|
|
8
|
+
interface BuildParams {
|
|
9
|
+
operation: Operation;
|
|
10
|
+
standard?: string;
|
|
11
|
+
profile?: string;
|
|
12
|
+
output?: 'xml' | 'pdf';
|
|
13
|
+
facturxProfile?: string;
|
|
14
|
+
invoice?: PlainObject;
|
|
15
|
+
verify?: boolean;
|
|
16
|
+
template?: string;
|
|
17
|
+
pdfTemplateId?: string;
|
|
18
|
+
rawBody?: Uint8Array;
|
|
19
|
+
rawContentType?: string;
|
|
20
|
+
validateFormat?: string;
|
|
21
|
+
franceCtc?: boolean;
|
|
22
|
+
parseFormat?: string;
|
|
23
|
+
sourceFormat?: string;
|
|
24
|
+
targetFormat?: string;
|
|
25
|
+
targetProfile?: string;
|
|
26
|
+
dropFranceCtcOverlay?: boolean;
|
|
27
|
+
/** Deep-merged into the request body (generate) or query (raw-input ops). */
|
|
28
|
+
advanced?: PlainObject;
|
|
29
|
+
}
|
|
30
|
+
interface BuiltRequest {
|
|
31
|
+
method: 'GET' | 'POST';
|
|
32
|
+
path: string;
|
|
33
|
+
query?: Record<string, QueryValue>;
|
|
34
|
+
/** Set for generate (JSON request body). */
|
|
35
|
+
jsonBody?: PlainObject;
|
|
36
|
+
/** Set for validate/parse/convert (raw document bytes). */
|
|
37
|
+
rawBody?: Uint8Array;
|
|
38
|
+
/** Request content type; absent for GET. */
|
|
39
|
+
contentType?: string;
|
|
40
|
+
outputKind: OutputKind;
|
|
41
|
+
}
|
|
42
|
+
declare function buildRequest(params: BuildParams): BuiltRequest;
|
|
43
|
+
|
|
44
|
+
export { type BuildParams, type BuiltRequest, type Operation, type OutputKind, PlainObject, type QueryValue, buildRequest };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { P as PlainObject } from './constants-bWOXCmJD.js';
|
|
2
|
+
export { D as DEFAULT_BASE_URL, a as DocumentInput, L as LIVE_CONVERT_SOURCE_FORMATS, b as LIVE_CONVERT_TARGET_FORMATS, c as LIVE_GENERATE_STANDARDS, d as LIVE_PARSE_FORMATS, e as LIVE_PROFILES, f as LIVE_VALIDATE_FORMATS, g as compactQuery, h as decodeUtf8, i as isPlainObject, m as mergeDeep, s as sniffContentType, t as toBytes } from './constants-bWOXCmJD.js';
|
|
3
|
+
|
|
4
|
+
type Operation = 'me' | 'generate' | 'validate' | 'parse' | 'convert';
|
|
5
|
+
/** 'json' => parse the `{ success, data }` envelope; 'binary' => return raw bytes. */
|
|
6
|
+
type OutputKind = 'json' | 'binary';
|
|
7
|
+
type QueryValue = string | number | boolean;
|
|
8
|
+
interface BuildParams {
|
|
9
|
+
operation: Operation;
|
|
10
|
+
standard?: string;
|
|
11
|
+
profile?: string;
|
|
12
|
+
output?: 'xml' | 'pdf';
|
|
13
|
+
facturxProfile?: string;
|
|
14
|
+
invoice?: PlainObject;
|
|
15
|
+
verify?: boolean;
|
|
16
|
+
template?: string;
|
|
17
|
+
pdfTemplateId?: string;
|
|
18
|
+
rawBody?: Uint8Array;
|
|
19
|
+
rawContentType?: string;
|
|
20
|
+
validateFormat?: string;
|
|
21
|
+
franceCtc?: boolean;
|
|
22
|
+
parseFormat?: string;
|
|
23
|
+
sourceFormat?: string;
|
|
24
|
+
targetFormat?: string;
|
|
25
|
+
targetProfile?: string;
|
|
26
|
+
dropFranceCtcOverlay?: boolean;
|
|
27
|
+
/** Deep-merged into the request body (generate) or query (raw-input ops). */
|
|
28
|
+
advanced?: PlainObject;
|
|
29
|
+
}
|
|
30
|
+
interface BuiltRequest {
|
|
31
|
+
method: 'GET' | 'POST';
|
|
32
|
+
path: string;
|
|
33
|
+
query?: Record<string, QueryValue>;
|
|
34
|
+
/** Set for generate (JSON request body). */
|
|
35
|
+
jsonBody?: PlainObject;
|
|
36
|
+
/** Set for validate/parse/convert (raw document bytes). */
|
|
37
|
+
rawBody?: Uint8Array;
|
|
38
|
+
/** Request content type; absent for GET. */
|
|
39
|
+
contentType?: string;
|
|
40
|
+
outputKind: OutputKind;
|
|
41
|
+
}
|
|
42
|
+
declare function buildRequest(params: BuildParams): BuiltRequest;
|
|
43
|
+
|
|
44
|
+
export { type BuildParams, type BuiltRequest, type Operation, type OutputKind, PlainObject, type QueryValue, buildRequest };
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// src/internal.ts
|
|
2
|
+
function isPlainObject(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function mergeDeep(target, source) {
|
|
6
|
+
const out = { ...target };
|
|
7
|
+
for (const [key, value] of Object.entries(source)) {
|
|
8
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
9
|
+
if (isPlainObject(value) && isPlainObject(out[key])) {
|
|
10
|
+
out[key] = mergeDeep(out[key], value);
|
|
11
|
+
} else {
|
|
12
|
+
out[key] = value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
17
|
+
function compactQuery(query) {
|
|
18
|
+
const out = {};
|
|
19
|
+
for (const [key, value] of Object.entries(query)) {
|
|
20
|
+
if (value === void 0 || value === "") continue;
|
|
21
|
+
out[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
function toBytes(input) {
|
|
26
|
+
if (typeof input === "string") return new TextEncoder().encode(input);
|
|
27
|
+
if (input instanceof Uint8Array) return input;
|
|
28
|
+
if (input instanceof ArrayBuffer) return new Uint8Array(input);
|
|
29
|
+
if (ArrayBuffer.isView(input)) {
|
|
30
|
+
return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
|
|
31
|
+
}
|
|
32
|
+
throw new TypeError("beliq: document must be a string, Uint8Array, ArrayBuffer, or typed array");
|
|
33
|
+
}
|
|
34
|
+
function decodeUtf8(bytes) {
|
|
35
|
+
return new TextDecoder("utf-8").decode(bytes);
|
|
36
|
+
}
|
|
37
|
+
var PDF_MAGIC = [37, 80, 68, 70, 45];
|
|
38
|
+
function sniffContentType(bytes) {
|
|
39
|
+
const isPdf = bytes.length >= PDF_MAGIC.length && PDF_MAGIC.every((b, i) => bytes[i] === b);
|
|
40
|
+
return isPdf ? "application/pdf" : "application/xml";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/buildRequest.ts
|
|
44
|
+
function isFacturxFamily(standardOrFormat) {
|
|
45
|
+
return standardOrFormat === "facturx" || standardOrFormat === "zugferd";
|
|
46
|
+
}
|
|
47
|
+
function withAdvancedQuery(query, advanced) {
|
|
48
|
+
const base = compactQuery(query);
|
|
49
|
+
const merged = advanced && Object.keys(advanced).length > 0 ? mergeDeep(base, advanced) : base;
|
|
50
|
+
return merged;
|
|
51
|
+
}
|
|
52
|
+
function buildRequest(params) {
|
|
53
|
+
switch (params.operation) {
|
|
54
|
+
case "me":
|
|
55
|
+
return { method: "GET", path: "/v1/me", outputKind: "json" };
|
|
56
|
+
case "generate": {
|
|
57
|
+
const body = {
|
|
58
|
+
standard: params.standard,
|
|
59
|
+
output: params.output ?? "xml",
|
|
60
|
+
invoice: params.invoice ?? {}
|
|
61
|
+
};
|
|
62
|
+
if (params.profile) body.profile = params.profile;
|
|
63
|
+
if (params.facturxProfile && isFacturxFamily(params.standard)) {
|
|
64
|
+
body.facturxProfile = params.facturxProfile;
|
|
65
|
+
}
|
|
66
|
+
if (typeof params.verify === "boolean") body.verify = params.verify;
|
|
67
|
+
if (params.template) body.template = params.template;
|
|
68
|
+
if (params.pdfTemplateId) body.pdfTemplateId = params.pdfTemplateId;
|
|
69
|
+
const merged = params.advanced && Object.keys(params.advanced).length > 0 ? mergeDeep(body, params.advanced) : body;
|
|
70
|
+
return {
|
|
71
|
+
method: "POST",
|
|
72
|
+
path: "/v1/generate",
|
|
73
|
+
jsonBody: merged,
|
|
74
|
+
contentType: "application/json",
|
|
75
|
+
outputKind: "binary"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
case "validate": {
|
|
79
|
+
const query = { format: params.validateFormat };
|
|
80
|
+
if (typeof params.franceCtc === "boolean") query.franceCtc = params.franceCtc;
|
|
81
|
+
return {
|
|
82
|
+
method: "POST",
|
|
83
|
+
path: "/v1/validate",
|
|
84
|
+
query: withAdvancedQuery(query, params.advanced),
|
|
85
|
+
rawBody: params.rawBody,
|
|
86
|
+
contentType: params.rawContentType ?? "application/xml",
|
|
87
|
+
outputKind: "json"
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
case "parse":
|
|
91
|
+
return {
|
|
92
|
+
method: "POST",
|
|
93
|
+
path: "/v1/parse",
|
|
94
|
+
query: withAdvancedQuery({ format: params.parseFormat }, params.advanced),
|
|
95
|
+
rawBody: params.rawBody,
|
|
96
|
+
contentType: params.rawContentType ?? "application/xml",
|
|
97
|
+
outputKind: "json"
|
|
98
|
+
};
|
|
99
|
+
case "convert": {
|
|
100
|
+
const query = {
|
|
101
|
+
sourceFormat: params.sourceFormat,
|
|
102
|
+
targetFormat: params.targetFormat
|
|
103
|
+
};
|
|
104
|
+
if (params.targetProfile && isFacturxFamily(params.targetFormat)) {
|
|
105
|
+
query.targetProfile = params.targetProfile;
|
|
106
|
+
}
|
|
107
|
+
if (typeof params.dropFranceCtcOverlay === "boolean") {
|
|
108
|
+
query.dropFranceCtcOverlay = params.dropFranceCtcOverlay;
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
method: "POST",
|
|
112
|
+
path: "/v1/convert",
|
|
113
|
+
query: withAdvancedQuery(query, params.advanced),
|
|
114
|
+
rawBody: params.rawBody,
|
|
115
|
+
contentType: params.rawContentType ?? "application/xml",
|
|
116
|
+
outputKind: "binary"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/constants.ts
|
|
123
|
+
var DEFAULT_BASE_URL = "https://api.beliq.eu";
|
|
124
|
+
var LIVE_GENERATE_STANDARDS = ["xrechnung", "zugferd", "facturx", "peppol-bis"];
|
|
125
|
+
var LIVE_PROFILES = ["basicwl", "en16931", "extended", "extended-ctc-fr"];
|
|
126
|
+
var LIVE_VALIDATE_FORMATS = ["auto", "cii", "ubl"];
|
|
127
|
+
var LIVE_PARSE_FORMATS = ["auto", "cii", "ubl"];
|
|
128
|
+
var LIVE_CONVERT_SOURCE_FORMATS = [
|
|
129
|
+
"auto",
|
|
130
|
+
"cii",
|
|
131
|
+
"ubl",
|
|
132
|
+
"zugferd",
|
|
133
|
+
"facturx",
|
|
134
|
+
"xrechnung",
|
|
135
|
+
"peppol-bis"
|
|
136
|
+
];
|
|
137
|
+
var LIVE_CONVERT_TARGET_FORMATS = [
|
|
138
|
+
"cii",
|
|
139
|
+
"ubl",
|
|
140
|
+
"zugferd",
|
|
141
|
+
"facturx",
|
|
142
|
+
"xrechnung",
|
|
143
|
+
"peppol-bis"
|
|
144
|
+
];
|
|
145
|
+
export {
|
|
146
|
+
DEFAULT_BASE_URL,
|
|
147
|
+
LIVE_CONVERT_SOURCE_FORMATS,
|
|
148
|
+
LIVE_CONVERT_TARGET_FORMATS,
|
|
149
|
+
LIVE_GENERATE_STANDARDS,
|
|
150
|
+
LIVE_PARSE_FORMATS,
|
|
151
|
+
LIVE_PROFILES,
|
|
152
|
+
LIVE_VALIDATE_FORMATS,
|
|
153
|
+
buildRequest,
|
|
154
|
+
compactQuery,
|
|
155
|
+
decodeUtf8,
|
|
156
|
+
isPlainObject,
|
|
157
|
+
mergeDeep,
|
|
158
|
+
sniffContentType,
|
|
159
|
+
toBytes
|
|
160
|
+
};
|