beliq-cli 0.2.1 → 0.2.2

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 CHANGED
@@ -24,6 +24,8 @@ beliq convert <file|-> --target-format cii|ubl|zugferd|facturx|xrechnung|peppo
24
24
  beliq me [--json]
25
25
  ```
26
26
 
27
+ `generate --pdf` returns a hybrid PDF/A-3 with the XML embedded for `zugferd` and `facturx`. `xrechnung` and `peppol-bis` have no hybrid form, so `--pdf` returns a visualization with no XML inside it, and their legal document stays the XML.
28
+
27
29
  `validate` accepts an XML document or a ZUGFeRD/Factur-X PDF. A file argument of `-` reads from stdin. Pass several files, a shell glob, or a directory (its `.xml`/`.pdf` files, recursively) to validate a batch: you get a per-file verdict, a summary, and one exit code for the whole run. `--json` prints the raw API result (a report object in batch mode) as the only thing on stdout, so it pipes cleanly.
28
30
 
29
31
  ```bash
@@ -1,4 +1,4 @@
1
- import { LIVE_GENERATE_STANDARDS } from '@beliq/sdk';
1
+ import { LIVE_GENERATE_STANDARDS, isProfileAllowedForStandard, profilesForStandard, } from '@beliq/sdk';
2
2
  import { flagBool, flagStr, oneOf, requirePositional } from '../args.js';
3
3
  import { UsageError } from '../errors.js';
4
4
  import { emitDocument } from './emit.js';
@@ -13,6 +13,15 @@ export async function runGenerate(args, deps, io) {
13
13
  if (!standard) {
14
14
  throw new UsageError(`--standard is required (one of: ${LIVE_GENERATE_STANDARDS.join(', ')})`);
15
15
  }
16
+ // The SDK drops --facturx-profile outside the Factur-X / ZUGFeRD family.
17
+ // Inside it the pair is pinned (extended-ctc-fr is Factur-X only) and the API
18
+ // answers a wrong one with 422, so fail as a usage error before the call.
19
+ const facturxProfile = flagStr(args, 'facturx-profile');
20
+ if (facturxProfile !== undefined &&
21
+ (standard === 'facturx' || standard === 'zugferd') &&
22
+ !isProfileAllowedForStandard(standard, facturxProfile)) {
23
+ throw new UsageError(`--facturx-profile for ${standard} must be one of: ${profilesForStandard(standard).join(', ')}`);
24
+ }
16
25
  const raw = await io.readInput(file);
17
26
  let invoice;
18
27
  try {
@@ -28,7 +37,11 @@ export async function runGenerate(args, deps, io) {
28
37
  standard,
29
38
  invoice,
30
39
  output,
31
- facturxProfile: flagStr(args, 'facturx-profile'),
40
+ facturxProfile: facturxProfile,
41
+ // XRechnung and Peppol BIS have no hybrid PDF, and the API refuses PDF for
42
+ // them unless the request names a visual to render. Factur-X and ZUGFeRD
43
+ // render theirs either way, so this is inert for them.
44
+ template: output === 'pdf' ? 'standard' : undefined,
32
45
  verify: !flagBool(args, 'no-verify'),
33
46
  seal,
34
47
  });
package/dist/help.js CHANGED
@@ -20,6 +20,10 @@ batch: a per-file verdict, a summary, and one exit code for the whole run.
20
20
  generate --seal also returns the document sha256 and validation verdict, so you
21
21
  can prove which rules the document passed; hashing the output reproduces it.
22
22
 
23
+ --pdf gives a hybrid PDF/A-3 with the XML embedded for zugferd and facturx.
24
+ xrechnung and peppol-bis have no hybrid form, so --pdf returns a visualization
25
+ with no XML inside it, and their legal document stays the XML.
26
+
23
27
  Global options:
24
28
  --api-key <key> beliq API key (default: BELIQ_API_KEY)
25
29
  --base-url <url> API base URL (default: BELIQ_BASE_URL, else https://api.beliq.eu)
@@ -0,0 +1,94 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- A minimal CII (UN/CEFACT Cross Industry Invoice) carrying the XRechnung
3
+ guideline id but missing the Buyer reference (BT-10), which XRechnung
4
+ requires (rule BR-DE-15). Used as a known-invalid example for the gated
5
+ live test and for the skill walkthrough. -->
6
+ <rsm:CrossIndustryInvoice
7
+ xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
8
+ xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
9
+ xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
10
+ <rsm:ExchangedDocumentContext>
11
+ <ram:GuidelineSpecifiedDocumentContextParameter>
12
+ <ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>
13
+ </ram:GuidelineSpecifiedDocumentContextParameter>
14
+ </rsm:ExchangedDocumentContext>
15
+ <rsm:ExchangedDocument>
16
+ <ram:ID>INV-2026-001</ram:ID>
17
+ <ram:TypeCode>380</ram:TypeCode>
18
+ <ram:IssueDateTime>
19
+ <udt:DateTimeString format="102">20260115</udt:DateTimeString>
20
+ </ram:IssueDateTime>
21
+ </rsm:ExchangedDocument>
22
+ <rsm:SupplyChainTradeTransaction>
23
+ <ram:IncludedSupplyChainTradeLineItem>
24
+ <ram:AssociatedDocumentLineDocument>
25
+ <ram:LineID>1</ram:LineID>
26
+ </ram:AssociatedDocumentLineDocument>
27
+ <ram:SpecifiedTradeProduct>
28
+ <ram:Name>Consulting</ram:Name>
29
+ </ram:SpecifiedTradeProduct>
30
+ <ram:SpecifiedLineTradeAgreement>
31
+ <ram:NetPriceProductTradePrice>
32
+ <ram:ChargeAmount>100.00</ram:ChargeAmount>
33
+ </ram:NetPriceProductTradePrice>
34
+ </ram:SpecifiedLineTradeAgreement>
35
+ <ram:SpecifiedLineTradeDelivery>
36
+ <ram:BilledQuantity unitCode="HUR">10</ram:BilledQuantity>
37
+ </ram:SpecifiedLineTradeDelivery>
38
+ <ram:SpecifiedLineTradeSettlement>
39
+ <ram:ApplicableTradeTax>
40
+ <ram:TypeCode>VAT</ram:TypeCode>
41
+ <ram:CategoryCode>S</ram:CategoryCode>
42
+ <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
43
+ </ram:ApplicableTradeTax>
44
+ <ram:SpecifiedTradeSettlementLineMonetarySummation>
45
+ <ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
46
+ </ram:SpecifiedTradeSettlementLineMonetarySummation>
47
+ </ram:SpecifiedLineTradeSettlement>
48
+ </ram:IncludedSupplyChainTradeLineItem>
49
+ <ram:ApplicableHeaderTradeAgreement>
50
+ <ram:SellerTradeParty>
51
+ <ram:Name>Seller GmbH</ram:Name>
52
+ <ram:PostalTradeAddress>
53
+ <ram:PostcodeCode>10115</ram:PostcodeCode>
54
+ <ram:CityName>Berlin</ram:CityName>
55
+ <ram:CountryID>DE</ram:CountryID>
56
+ </ram:PostalTradeAddress>
57
+ <ram:SpecifiedTaxRegistration>
58
+ <ram:ID schemeID="VA">DE123456789</ram:ID>
59
+ </ram:SpecifiedTaxRegistration>
60
+ </ram:SellerTradeParty>
61
+ <ram:BuyerTradeParty>
62
+ <ram:Name>Buyer GmbH</ram:Name>
63
+ <ram:PostalTradeAddress>
64
+ <ram:PostcodeCode>80331</ram:PostcodeCode>
65
+ <ram:CityName>Munich</ram:CityName>
66
+ <ram:CountryID>DE</ram:CountryID>
67
+ </ram:PostalTradeAddress>
68
+ </ram:BuyerTradeParty>
69
+ </ram:ApplicableHeaderTradeAgreement>
70
+ <ram:ApplicableHeaderTradeDelivery />
71
+ <ram:ApplicableHeaderTradeSettlement>
72
+ <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
73
+ <ram:ApplicableTradeTax>
74
+ <ram:CalculatedAmount>190.00</ram:CalculatedAmount>
75
+ <ram:TypeCode>VAT</ram:TypeCode>
76
+ <ram:BasisAmount>1000.00</ram:BasisAmount>
77
+ <ram:CategoryCode>S</ram:CategoryCode>
78
+ <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>
79
+ </ram:ApplicableTradeTax>
80
+ <ram:SpecifiedTradePaymentTerms>
81
+ <ram:DueDateDateTime>
82
+ <udt:DateTimeString format="102">20260214</udt:DateTimeString>
83
+ </ram:DueDateDateTime>
84
+ </ram:SpecifiedTradePaymentTerms>
85
+ <ram:SpecifiedTradeSettlementHeaderMonetarySummation>
86
+ <ram:LineTotalAmount>1000.00</ram:LineTotalAmount>
87
+ <ram:TaxBasisTotalAmount>1000.00</ram:TaxBasisTotalAmount>
88
+ <ram:TaxTotalAmount currencyID="EUR">190.00</ram:TaxTotalAmount>
89
+ <ram:GrandTotalAmount>1190.00</ram:GrandTotalAmount>
90
+ <ram:DuePayableAmount>1190.00</ram:DuePayableAmount>
91
+ </ram:SpecifiedTradeSettlementHeaderMonetarySummation>
92
+ </ram:ApplicableHeaderTradeSettlement>
93
+ </rsm:SupplyChainTradeTransaction>
94
+ </rsm:CrossIndustryInvoice>
@@ -0,0 +1,64 @@
1
+ {
2
+ "number": "INV-2026-001",
3
+ "issueDate": "2026-01-15",
4
+ "currencyCode": "EUR",
5
+ "buyerReference": "04011000-12345-06",
6
+ "seller": {
7
+ "name": "Seller GmbH",
8
+ "vatId": "DE123456789",
9
+ "contactName": "Anna Muster",
10
+ "email": "billing@seller.example",
11
+ "phone": "+49 30 1234567",
12
+ "address": {
13
+ "street": "Hauptstr. 1",
14
+ "city": "Berlin",
15
+ "postalCode": "10115",
16
+ "countryCode": "DE"
17
+ },
18
+ "peppol": {
19
+ "schemeId": "9930",
20
+ "id": "DE123456789"
21
+ }
22
+ },
23
+ "buyer": {
24
+ "name": "Buyer GmbH",
25
+ "email": "ap@buyer.example",
26
+ "address": {
27
+ "street": "Marktweg 2",
28
+ "city": "Munich",
29
+ "postalCode": "80331",
30
+ "countryCode": "DE"
31
+ },
32
+ "vatId": "DE987654321",
33
+ "peppol": {
34
+ "schemeId": "9930",
35
+ "id": "DE987654321"
36
+ }
37
+ },
38
+ "lines": [
39
+ {
40
+ "description": "Consulting",
41
+ "quantity": 10,
42
+ "unitCode": "HUR",
43
+ "unitPrice": 100,
44
+ "lineTotal": 1000,
45
+ "vatRate": 19,
46
+ "vatCategoryCode": "S"
47
+ }
48
+ ],
49
+ "taxSummary": [
50
+ {
51
+ "vatCategoryCode": "S",
52
+ "vatRate": 19,
53
+ "taxableAmount": 1000,
54
+ "taxAmount": 190
55
+ }
56
+ ],
57
+ "paymentMeans": {
58
+ "typeCode": "58",
59
+ "iban": "DE89370400440532013000"
60
+ },
61
+ "totalNetAmount": 1000,
62
+ "totalTaxAmount": 190,
63
+ "totalGrossAmount": 1190
64
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beliq-cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "beliq CLI: validate, generate, parse, and convert EU e-invoices (XRechnung, ZUGFeRD, Factur-X, Peppol BIS) against authority-pinned, drift-checked rules, from the terminal or CI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,7 +37,8 @@
37
37
  "beliq": "dist/index.js"
38
38
  },
39
39
  "files": [
40
- "dist"
40
+ "dist",
41
+ "examples"
41
42
  ],
42
43
  "publishConfig": {
43
44
  "provenance": true
@@ -56,7 +57,7 @@
56
57
  "prepublishOnly": "npm run build"
57
58
  },
58
59
  "dependencies": {
59
- "@beliq/sdk": "^0.3.0"
60
+ "@beliq/sdk": "^0.4.0"
60
61
  },
61
62
  "devDependencies": {
62
63
  "@types/node": "^20.14.0",