{"_id":"@attestwire/en16931","_rev":"19-2108533e4cf65e940162c72707c782e6","name":"@attestwire/en16931","dist-tags":{"latest":"0.14.0"},"versions":{"0.1.0":{"name":"@attestwire/en16931","version":"0.1.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","peppol","peppol-bis","zugferd","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.1.0","maintainers":[{"name":"attestwire","email":"ben.harborne@gmail.com"}],"homepage":"https://github.com/attestwire/en16931","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"8017af28354dfa39d4de99505d60ff893b96be70","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.1.0.tgz","fileCount":18,"integrity":"sha512-CXb2RfhWDUX8gRSbtEotxyNDqkdOxhOgHeh5dq/qiPNlYw+i3t/qWKrKxQtsLXNS8CCdEdhyuQ5S7a1/wImztA==","signatures":[{"sig":"MEQCIASQJbmW50uSTQ0U1g/nNXVAwA55/e56hGYPefAZ2mipAiBddCQlJx8MiFEhfM6QsfJxO1k+sw18xK/O1ty46hoQ9A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":111271},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"2c6c01dad0a4d2014f63d229c8a60ea4f21421b3","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"attestwire","email":"ben.harborne@gmail.com"},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"11.7.0","description":"Generate and validate EN 16931 e-invoices (XRechnung UBL, Peppol BIS 3.0) with errors that teach the regulation. Zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"25.2.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.1.0_1786304534475_0.553882697300532","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@attestwire/en16931","version":"0.2.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","peppol","peppol-bis","zugferd","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.2.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://github.com/attestwire/en16931","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"9f1723551a23849dd97cdadc466e706094e10351","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.2.0.tgz","fileCount":77,"integrity":"sha512-k17aQC5HhYCzmnm9VGddRzKoC/QRGnx7/OlYX2V5G3psotHYObKK25Sq+12cw0rKhBLKP38jYiGiMA3P20JJAw==","signatures":[{"sig":"MEYCIQDeRswtpq9K7FEHu1kcmMLKOpqwSs4YPYyfaM9KJAhUAgIhAI8J/BTb9rTKVxEqtLE2v0cu3QkUWs1OvRxOjYUUjd1m","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":667630},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"9354f5891b2b80570c650e5c0dd64997dd1f9129","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a38ab642-c4ab-4904-9a27-81ea9568f5ca"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices (XRechnung UBL, Peppol BIS 3.0) with errors that teach the regulation. Zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.2.0_1786371167684_0.06034232703876463","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@attestwire/en16931","version":"0.2.1","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","peppol","peppol-bis","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.2.1","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://github.com/attestwire/en16931","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"b8e6df6df29ff3dce2fcc7c75145003a804d8b61","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.2.1.tgz","fileCount":77,"integrity":"sha512-3sQOb9Ep28czu1V3yW6ZbkG+W2rDU21MhCVo6P9X0FGfttBF02p04m2Dm7JGRKD9RGUPaORsmFKJuKLcWQJTlQ==","signatures":[{"sig":"MEQCIDlW6qNNElgc10yz5JlVbLQnDujq+ER9ISR3/1xtN00cAiAA5MSxBKx3QAg4lreaEGlxXJDMncbXT0pLMMvKSLbD+Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":669136},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"d14fe1bdf90a38cae2530010ce9daf316e2bc38c","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a38ab642-c4ab-4904-9a27-81ea9568f5ca"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices (XRechnung UBL, Peppol BIS 3.0) with errors that teach the regulation. Zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.2.1_1786510773203_0.5072852488516724","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@attestwire/en16931","version":"0.3.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","peppol","peppol-bis","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.3.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://github.com/attestwire/en16931","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"475636febdd782b5d191f7891911beb6acd6c6ca","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.3.0.tgz","fileCount":91,"integrity":"sha512-irzlN4vV5h9syUzNUq8OYrQgK0Nx2W5AQbODnBrtVexsz0Ib5czxV+JXbel8tcOrnpVpWTbmfKsmjqViADM8gQ==","signatures":[{"sig":"MEUCIQCxD7FNk9yQbcXtB86VAf+XJ9CdmwcE5TslvjwvrcD3UQIgaTl+1BfULnyl/zTLBBhQrGLQAZ4Sypb2jrez3UzSaqc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":909290},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"6dea3b7c0c74b6fbda7ee9ff2d975029c00f1248","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a38ab642-c4ab-4904-9a27-81ea9568f5ca"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices (XRechnung UBL, Peppol BIS 3.0) with errors that teach the regulation. Zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.3.0_1786515984108_0.8088243949515741","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@attestwire/en16931","version":"0.4.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","peppol","peppol-bis","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.4.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://github.com/attestwire/en16931","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"138f0b1483dc894f6807f2bb81e02d98717c1ee3","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.4.0.tgz","fileCount":91,"integrity":"sha512-hpa+RVcx4UsjrEVibyBCQEHZXD/uSoChUCMFe1CJnlPXrVbTIc5Jnd1hapFXqKXS7q4DoIMTMIyaj/DKFH6gfA==","signatures":[{"sig":"MEUCIQD4clZIH5Msg7y5YttHtPLHnNmlyDu3nTjuxirQcJ1NjAIgJVNG7nkM3YIgRMj/qbctj99JEr4gDNQSBpR7hby8u3U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":985145},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"9fff87e1c3c52cd46a5126de2da74466c2f529db","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices (XRechnung UBL, Peppol BIS 3.0) with errors that teach the regulation. Zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.4.0_1786654272349_0.6474139213129193","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@attestwire/en16931","version":"0.5.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","peppol","peppol-bis","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.5.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://github.com/attestwire/en16931","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"1247d89f664dac313b7766274156a171722755ae","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.5.0.tgz","fileCount":99,"integrity":"sha512-WUc0vuM5wvSZ7hWZr0T0J5ddwyD+o70/Iic1+oVkUqmJs1XBvmnvl+4ZC3Wnx/CWyPPOXIIpdiFT5ipBqfAAow==","signatures":[{"sig":"MEYCIQCAp58u1owfShKszquH7fHFO809ftOFyBtbFL4CgZzubwIhAKDt6CCAm/xSXUIBGVXi2LydXIx6GQonOyrpN5VmdRnw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1088911},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"ebaa3efb2d9a6fcc41948e95feaa0a6e97c41f96","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices (XRechnung UBL, Peppol BIS 3.0) with errors that teach the regulation. Zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.5.0_1786654405982_0.8110000615420843","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@attestwire/en16931","version":"0.6.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","cii","invoice-validation","peppol","peppol-bis","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.6.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"2e7b21b56dbffb917d6cf2fe69730774785cc335","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.6.0.tgz","fileCount":101,"integrity":"sha512-C+VGg7WWjL1xjg0PCmUx5kJ0oR1ncYkiK2IznjOY3h5P65cVBV4wc2zRcCx0bxUPJ056yDrmEgUwxeIx4HgooA==","signatures":[{"sig":"MEYCIQDLGhKV4UKyNzsfTAHHP5NXtAE6tSoB7dvnLptFTasawwIhAOVNt3q5NFHSRfvQZOsrXw+2hHKl12kValIPLW6Mqao1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1129816},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"070c23c1d083636c36103baf3c446a39e3068513","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","kosit":"./scripts/kosit-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices — UBL 2.1 and UN/CEFACT CII (XRechnung, Peppol BIS 3.0, Factur-X payload) — with errors that teach the regulation. TypeScript, zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.6.0_1786747459321_0.5771892225638591","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@attestwire/en16931","version":"0.7.0","keywords":["en16931","xrechnung","e-invoicing","einvoice","einvoicing","ubl","cii","invoice-validation","peppol","peppol-bis","facturx","invoice","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.7.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"0476afa49fa0b647c442897a0f9fdfb8ea94cba9","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.7.0.tgz","fileCount":109,"integrity":"sha512-6pXd6vO6RxnhDjupDUGvYm52bvpGgKf8nJHZ9mMwjEnlSiyakGBhtzO1nFNH1K6wsU+ReMkcrddEWoAdg8C9Mg==","signatures":[{"sig":"MEUCIDnKdIlyjLJUMjNLVXs37NLFYGopdT2WoVBuFw7RLoKfAiEAvvIU6+jpQGVMwZnU2Qg6OsRTtPYcsCkVoCC1eKE4Ad0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1383780},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"3ee94fa56aecae10ab1d97398f59c27469edfe04","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Generate and validate EN 16931 e-invoices — UBL 2.1 and UN/CEFACT CII (XRechnung, Peppol BIS 3.0, Factur-X payload) — with errors that teach the regulation. TypeScript, zero dependencies.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.7.0_1786774696621_0.3633459146473741","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@attestwire/en16931","version":"0.7.1","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.7.1","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"a0c68b72a2293b916349a4f06c56319a520db93e","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.7.1.tgz","fileCount":109,"integrity":"sha512-xxuPyuB81laIFMQZsE3uU+h41kAnpdc4oSyZHmrVyZc0w5r8gmCPvNx08Js+gXlWz4cNen5okKVMaxylnLukaA==","signatures":[{"sig":"MEQCIAO6JOiai/CeKlP8KItAx64lmCJFeXzs7JD3jVCga+90AiBTOVU55ufa+KryPX6RDjPQR2kLl5yjmNcXbcTCgvBx+A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1385882},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"d019688712886287c5f502896a97a71ce27a4029","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 295 rules, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.7.1_1786845818260_0.8263292712250647","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@attestwire/en16931","version":"0.7.2","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.7.2","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"a55640deb15b7509a014ffe218785c3b703423e1","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.7.2.tgz","fileCount":109,"integrity":"sha512-ETQzLV2Z5tW+K8m1pxK9HYZyLyTBPxFoMT6IiOdoCqCKiy7O8gdFh/vy5JMjg19L2InFYfxim6DWYT9S1Drr+g==","signatures":[{"sig":"MEYCIQDlEwCcKnKjyL9YUT/HKF/6uZIlqUQJCcvDuff9U4ET2gIhANYEKFJjEX3Ql3Nt8Q7C3xAbYN1W1qCrxDO4hQ/SNevT","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1418674},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"0752c7f6380b1845bcc5019dde90274c4b7c11f2","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 295 rules, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.7.2_1786856660362_0.5791197298403168","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"name":"@attestwire/en16931","version":"0.7.3","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.7.3","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"c373d34617752454f3b288ae212aa70224aa031e","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.7.3.tgz","fileCount":112,"integrity":"sha512-tVjj43HJeIchIhM0+t5E+SviDpsac5dBqlS42zKwWBehMxkBKTxvDrfT0dpUSmn3RgVKxxI8KHLQ6e3cES8J3A==","signatures":[{"sig":"MEQCID8jNPCZuzJ/IshVKqu/jPsCr2ze5uYVUJeQrRFx+WUtAiAfpBEGx8MYMLylO0zaVSM/EN2K2R7uBpaThywZ5v4KJA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1483592},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"b77e6bad1f74d1897b44efa4cfb68da7076a54c1","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.0.2","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 295 rules, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.7.3_1786888517023_0.7779027285604965","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@attestwire/en16931","version":"0.8.0","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.8.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"2a407fc385f552cabbc2d5902071a8de2a1e75ac","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.8.0.tgz","fileCount":112,"integrity":"sha512-o3XR+KBKdjACDHl6swY6ZmYWoUQ3tTeqtTPSYwWrjEmMcsXmTMLbBOM0cOe4/4eXb4SKiR5Q/Lz+ILEHFAGLZw==","signatures":[{"sig":"MEUCIGRW4FRpa+GAQALIGN4MRNnrTohIJNll1BDm1RTdVgo+AiEAnp55+3Q2+l6vgh3zpohuVooEii13uETptrEOxo8qnd8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGmRfPrziwp5oNtkgQtUvOGxTT66Bnxh8T07FqGU6yk+AiEAnKklWgE91L+Hs+1nZyF+/yzVAwfdVNu/fsUcU9LTAlo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1477105},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"4839a10f5d1beea30697ac3ee67545e239011149","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 295 rules, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.8.0_1790131035000_0.9418761561415676","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@attestwire/en16931","version":"0.9.0","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.9.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"bin":{"en16931":"dist/bin.js"},"dist":{"shasum":"92dbce052d6624601aa7daca0252b3b9be66f438","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.9.0.tgz","fileCount":118,"integrity":"sha512-WVFLQFY9G1U1VblG4rJ3Cah3Cxjd/I6p9YF/do9VgEscsSOT6/lUzcGTmiz/lhqHcBkDo6KNLzcsXhPuLGMyRA==","signatures":[{"sig":"MEUCIFnGZCouJX2GjCja6NrMiIZA4q7nF2FwKC7d/5A1FGl/AiEAlAULUPN+LJ0wsbStZNbFOy4btbtQdf9rIFURP0qP3hw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIEHyjq3nVL5MIWB/Q3FXGyRNqX0FPBmR3j5RPEFv9N59AiBU0NGQXYP9iX7roIGuQiEkREUa18+hIeLFA9eA9/1WXg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1551792},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"22f6ceb3e2ef1303bbde5439d8d659ece6856409","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:98c8cc3a-77de-4c7a-8fa3-592daa31082a"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 295 rules, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.9.0_1790179164766_0.24080395483942119","host":"s3://npm-registry-packages-npm-production"}},"0.10.0":{"name":"@attestwire/en16931","version":"0.10.0","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.10.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"bin":{"en16931":"dist/bin.js"},"dist":{"shasum":"4599de9701f7fb03a53621d3e1473951fa967bba","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.10.0.tgz","fileCount":122,"integrity":"sha512-XDoTl+aA/gWUJTBz7dg4ePw8Qk31pL5tx7WHqiQozp5GiHCSHNKo8QMZ0g+nTIqutgki2vMDSyeINxZEt3bQ/g==","signatures":[{"sig":"MEUCIFrBE8MxLSY8clIKsVufIVdftIc3h2qjeKPBo9A/6uuaAiEA3gMgcjw2XR2LajrvsNKMbHKMarHFuCUWqlSiHfDVQs4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDmDcCPj4j0Cdp9DRIZcZQa4SK8FR80QAB/3l6RkTfO/AIgC5cYTgpGoNI8l/0k9DdT1iz+9RZ3rospJR76sgSmZGg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.10.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1621501},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"2bb0effc1b0c7dff050da2280db944b4e2cecd0d","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:bdba2680-3746-4006-a012-95782c2cc4dc"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 290 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.10.0_1790226210787_0.8026646392052388","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@attestwire/en16931","version":"0.11.0","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.11.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"bin":{"en16931":"dist/bin.js"},"dist":{"shasum":"9cfa0e77d6c7319c66f09285ee3af49b7c078df0","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.11.0.tgz","fileCount":122,"integrity":"sha512-/l7GCLnn+hUCFPuhqTx6yxvP58RYku/UW1fdElJUdP9Kf/bdy0d5kK+In+/wqmIMt7mPQPCUuQgIvkG5MxZqWg==","signatures":[{"sig":"MEUCIAguWBZ/iLSxgK6R43Xf6Giul2s266BG1ZCl++RMNWZHAiEA1oLh0qwNuZfhnEpXfhcxW9t3DJl/8ZxwgI76i7lKJbc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQD5tDvtx8ZT8wM9yscmu5qMAzLbxhFbydV0+Cl0SKcY0AIhAOuYbJcdMhHia4bE34/d9oPEpjfHfh5cs62aOxMqAY0M","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.11.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1648237},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"1337f6aa9e62a00fcd70a43e9aadd368929f4166","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:bdba2680-3746-4006-a012-95782c2cc4dc"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 290 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.11.0_1790310438247_0.6080119865222853","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@attestwire/en16931","version":"0.12.0","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.12.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"bin":{"en16931":"dist/bin.js"},"dist":{"shasum":"33ce9a32285688816ce030a4c3139d2cd6b24ef7","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.12.0.tgz","fileCount":124,"integrity":"sha512-lx4ieKJDOGWEpcO6AvHuDkfJkrlmokpLPsnxmDBvnRMUDt7bpT5N6o/g76DRxq+8DdyAKYuxtVFB+F9/N9w9fg==","signatures":[{"sig":"MEUCIB6aJ3epJRaUpfPsUelknqAQp6uTyDqwDJYbNvFvBW7XAiEA9jMZi21eG3jUM8Dzqh/aLdGH4mps07KqJ+MH1t6K+jg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIBkNRRcVboX3nOCxhKVnBikZmNYO108TBcDZu433RvZzAiAO3gWHLiuupQbIE+GTHshRkGY/QxNM1YY5Hm/JsaTlnQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.12.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1668359},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"1560473102f7642cf7a040690f402e950f06f31f","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:bdba2680-3746-4006-a012-95782c2cc4dc"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 290 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.18.11"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.12.0_1790346605506_0.7311201805872067","host":"s3://npm-registry-packages-npm-production"}},"0.12.1":{"name":"@attestwire/en16931","version":"0.12.1","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.12.1","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"bin":{"en16931":"dist/bin.js"},"dist":{"shasum":"aced2f48c01d56de89f231a2c573fa1a56a2fcde","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.12.1.tgz","fileCount":124,"integrity":"sha512-Rlol4eRLzCofwdmaLREwgtOY2wUBDggMzjtJQ1THFKqO/Xg/xWdXzHGzfWk8VnGKs0t3OdmaQLcjRGeZI17VMg==","signatures":[{"sig":"MEQCIF2FxtxY8TCyNlKOdhXGiUEKWvWF2cD/1FyZuXPXcUpDAiAiiM3Lll4xC9JfKeF/b+KlSDzTVdG4FrnJxK24cqfS7A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDYIUBAmfDCaSuLlljEJbJHVFBSEF5iLKFfkkNnnCnWnAIgXoTMiKf1pJEPFQURzb0bGGxRYAWCkWci7bHzv406ZXs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.12.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1670600},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"0d68780af698565f283e105bef9f25c8c70b10d8","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:bdba2680-3746-4006-a012-95782c2cc4dc"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 289 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.20.4"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.12.1_1790368639507_0.33338069201449594","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"@attestwire/en16931","version":"0.13.0","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"author":{"name":"Attestwire"},"license":"MIT","_id":"@attestwire/en16931@0.13.0","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"homepage":"https://attestwire.com","bugs":{"url":"https://github.com/attestwire/en16931/issues"},"bin":{"en16931":"dist/bin.js"},"dist":{"shasum":"21b660733a21c9d5edc65e5903aa53d6bb04c811","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.13.0.tgz","fileCount":124,"integrity":"sha512-szmml1Ia2sj7OlPRqOOHCTcbTM9xp/JerCyq5BR6xlJlk8niPFHSe77BmeoPXOFH5ekya+Mv4CC57t79/TyZkg==","signatures":[{"sig":"MEQCIHxt6DR5iWkKWEPL+E9mC73VEfnSrmgb/2CZce00eO1jAiAw+TFafawAQrZ6XsrX8K60Qa7viJkjvRNaUj0eKZQKBw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIHCfnXrwEPZ8OnEMNBAT64xExCqkdFlN49OJa5jO7tLvAiEA4zXw8lVhQJGcjSvMGfX+Y75k6pj0dUd/FBYZ7sncx5I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.13.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1689841},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"1a869edeb275b8368a602fac9d0252855c1bc972","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:bdba2680-3746-4006-a012-95782c2cc4dc"}},"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 294 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.20.4"},"_npmOperationalInternal":{"tmp":"tmp/en16931_0.13.0_1790444159043_0.436712459796641","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"_id":"@attestwire/en16931@0.14.0","bin":{"en16931":"dist/bin.js"},"bugs":{"url":"https://github.com/attestwire/en16931/issues"},"dist":{"shasum":"6cb9b62c7f10fd1c4a3e93ad93c39a586283d8df","tarball":"https://registry.npmjs.org/@attestwire/en16931/-/en16931-0.14.0.tgz","fileCount":146,"integrity":"sha512-2etE0Hg/Y/b9QvcGoEX+tsdddCqBSNpG4Om4zaYX+2+eRBWRVbS/Bhhif5/T2+QWD0HZ5YS+pGK7+BuaMxPOGw==","signatures":[{"sig":"MEUCIQC6QafAaMc9DgXedczeprjMwkrxzxk/vTMzVlFzFLFmbgIgNd1mP8mxiBHMbXz4UeM4SL1XuFr4lVSVT+dLp6EQY5w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDFakiCZW8gxEbAOtospvnGaaLb+XSimYHfM3mKdxINRwIgEe15Xa9zhykF2l5GT82rtvEuKFCZZZoluETwLLWJl8g="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@attestwire%2fen16931@0.14.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1962574},"main":"./dist/index.js","name":"@attestwire/en16931","type":"module","types":"./dist/index.d.ts","author":{"name":"Attestwire"},"engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"0018216239e2c8b0556359f96b0fa7ac7d04ec1f","license":"MIT","scripts":{"test":"vitest run","build":"tsc -p tsconfig.json && tsc -p tsconfig.cli.json","dgfip":"./scripts/dgfip-check.sh","kosit":"./scripts/kosit-check.sh","speed":"node scripts/speed-budget.mjs","peppol":"./scripts/peppol-check.sh","fixtures":"npm run build && node scripts/emit-fixtures.mjs","codelists":"node scripts/build-codelists.mjs","prepublishOnly":"npm run build && npm test"},"version":"0.14.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:bdba2680-3746-4006-a012-95782c2cc4dc"}},"homepage":"https://attestwire.com","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"_npmVersion":"12.1.0","description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 294 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","directories":{},"maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^7.0.2","@types/node":"^22.20.4"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/en16931_0.14.0_1790459051957_0.8707824010066483"}}},"time":{"created":"2026-08-09T19:42:14.249Z","modified":"2026-09-26T21:44:12.351Z","0.1.0":"2026-08-09T19:42:14.665Z","0.2.0":"2026-08-10T14:12:47.883Z","0.2.1":"2026-08-12T04:59:33.374Z","0.3.0":"2026-08-12T06:26:24.249Z","0.4.0":"2026-08-13T20:51:12.502Z","0.5.0":"2026-08-13T20:53:26.179Z","0.6.0":"2026-08-14T22:44:19.506Z","0.7.0":"2026-08-15T06:18:16.781Z","0.7.1":"2026-08-16T02:03:38.403Z","0.7.2":"2026-08-16T05:04:20.531Z","0.7.3":"2026-08-16T13:55:17.160Z","0.8.0":"2026-09-23T02:37:15.121Z","0.9.0":"2026-09-23T15:59:24.848Z","0.10.0":"2026-09-24T05:03:30.893Z","0.11.0":"2026-09-25T04:27:18.351Z","0.12.0":"2026-09-25T14:30:05.624Z","0.12.1":"2026-09-25T20:37:19.593Z","0.13.0":"2026-09-26T17:35:59.154Z","0.14.0":"2026-09-26T21:44:12.064Z"},"bugs":{"url":"https://github.com/attestwire/en16931/issues"},"author":{"name":"Attestwire"},"license":"MIT","homepage":"https://attestwire.com","keywords":["en16931","e-invoice","e-invoicing","einvoice","einvoicing","invoice","validation","validator","invoice-validation","xrechnung","zugferd","factur-x","facturx","peppol","peppol-bis","ubl","cii","schematron","xml","vat","kosit","leitweg-id","compliance","germany","typescript"],"repository":{"url":"git+https://github.com/attestwire/en16931.git","type":"git"},"description":"Validate EN 16931 e-invoices — XRechnung, ZUGFeRD, Factur-X, Peppol BIS 3.0 — and generate the UBL/CII XML. 294 official rules, errors that explain the fix, zero dependencies, runs in the browser, no Java.","maintainers":[{"name":"attestwire","email":"hello@attestwire.com"}],"readme":"# @attestwire/en16931\n\n[![CI](https://github.com/attestwire/en16931/actions/workflows/ci.yml/badge.svg)](https://github.com/attestwire/en16931/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@attestwire/en16931.svg)](https://www.npmjs.com/package/@attestwire/en16931)\n[![dependencies: 0](https://img.shields.io/badge/dependencies-0-brightgreen.svg)](package.json)\n[![types: included](https://img.shields.io/badge/types-included-blue.svg)](https://www.npmjs.com/package/@attestwire/en16931)\n[![licence: MIT](https://img.shields.io/badge/licence-MIT-blue.svg)](LICENSE)\n\n### E-invoice errors you can actually fix.\n\nValidate and generate **XRechnung**, **Peppol BIS Billing 3.0** and the\n**Factur-X / ZUGFeRD** XML (UBL 2.1 and UN/CEFACT CII) straight from TypeScript.\nNo Java, no server, no dependencies, no account. Every rejection names the rule,\nexplains why the regulation wants it, and tells you what to change.\n\n```console\n$ npx @attestwire/en16931 invoice-0142.xml\nFAIL invoice-0142.xml  UBL · xrechnung-ubl\n  ✗ error BR-DE-15 (BT-10)\n    XRechnung requires a buyer reference (BT-10). For German public-sector buyers this is the Leitweg-ID; business buyers may supply any reference, but the field must be present.\n    fix: Ask your client for their Leitweg-ID (public sector) or an order/customer reference, and set buyerReference.\n    at:  /ubl:Invoice/cbc:BuyerReference  (nearest element in the file: <ubl:Invoice>, line 2)\n    https://attestwire.com/rules/BR-DE-15\n  ✗ error BR-DE-7 (BT-43)\n    XRechnung requires the element \"Seller contact email address\" (BT-43). The seller contact group is present but incomplete — BR-DE-5, BR-DE-6 and BR-DE-7 each make one part of it mandatory, so supplying two of the three still fails.\n    fix: Set seller.contact.email to a monitored mailbox — this is where the authority sends invoice queries.\n    at:  /ubl:Invoice/cac:AccountingSupplierParty/cac:Party/cac:Contact/cbc:ElectronicMail  (nearest element in the file: <cac:Contact>, line 44)\n    https://attestwire.com/rules/BR-DE-7\n\n1 document: 0 passed, 1 failed (2 errors, 0 warnings).\n```\n\nFor the same file, the official XRechnung schematron says\n`[BR-DE-15]-Das Element „Buyer reference“ (BT-10) muss übermittelt werden`, and\nthat is all it says. **[Try it in your browser →](https://attestwire.com/playground)**\n(the playground is this package running client-side: your invoice never leaves the tab).\n\n## Why use it\n\n- **Errors that teach.** Each finding carries the official rule id, the business\n  term, the *reason*, a concrete fix, an XPath and a passing example. You can fix\n  the invoice without opening a 400-page standard, and so can your support\n  desk or an LLM.\n- **No JVM, anywhere.** The official validators are Java. This is TypeScript\n  with zero runtime dependencies and no platform API beyond the JavaScript\n  standard library, so the same build runs in Node 18+, Deno, Bun, Cloudflare\n  Workers and the browser. Even the DEFLATE decoder for Factur-X PDFs is written\n  in-repo.\n- **Both syntaxes, both directions.** Generate *and* parse UBL 2.1 and CII D16B\n  from one typed `InvoiceInput`, invoices and credit notes alike, and pull the\n  XML out of a Factur-X or ZUGFeRD PDF.\n- **Checked against the regulator, not against itself.** The generated fixtures\n  are accepted by KoSIT, the German government's validator. Fuzzing, mutation\n  testing and differential runs against KoSIT and the Peppol schematron are how bugs\n  get found here, and every disagreement on record has a name and a reason. See\n  [Conformance](#conformance).\n- **Fast enough to run on every keystroke.** Parsing and validating a typical\n  invoice takes well under a millisecond on a laptop, and a 1,000-line invoice\n  tens of milliseconds. CI fails the build if that regresses.\n- **Private by construction.** Nothing in the library makes a network call. The\n  invoice data stays in your process.\n- **Honest about its edges.** What it does not do is written down, in detail,\n  [below](#not-implemented-yet), not discovered in production.\n\n## What it covers\n\n| Format | Syntax | Generate | Read | Validate |\n| --- | --- | :---: | :---: | :---: |\n| XRechnung 3.0 | UBL 2.1 | ✅ | ✅ | ✅ |\n| XRechnung 3.0 | CII D16B | ✅ | ✅ | ✅ |\n| Peppol BIS Billing 3.0 | UBL 2.1 (CII optional) | ✅ | ✅ | ✅ |\n| Factur-X / ZUGFeRD, EN 16931 profile | CII inside a PDF/A-3 | the XML payload | ✅ from the PDF | ✅ |\n| EN 16931 core | UBL 2.1 or CII D16B | ✅ | ✅ | ✅ |\n\nInvoices and credit notes in all of them. 294 rules of the regulation (EN 16931\ncore, the XRechnung CIUS and Peppol BIS 3.0, including every `BR-CL-*` code list\nin full), plus 27 findings of the library's own (the `ATW-` ids): input the XML\ncould not carry faithfully, what a UBL credit note cannot hold, the business\nfacts it turns into codes, and a Leitweg-ID, IBAN, BIC, SIREN or SIRET with the\nwrong form or check digits ([Identifier checks](#identifier-checks)). Totals are\nalways **computed** from the lines, never echoed, so a generated document cannot\nfail its own arithmetic. It also sorts every finding the way the German BMF\nletter of October 2025 does for the business receiving the invoice\n([Findings for invoice recipients](#findings-for-invoice-recipients)).\n\n## Command line\n\nCheck invoices you already have, no code required:\n\n```bash\nnpx @attestwire/en16931 invoice.xml\nnpx @attestwire/en16931 invoices/          # every .xml and .pdf, recursively\nnpx @attestwire/en16931 factur-x.pdf       # the CII payload, and the PDF around it\n```\n\nExit status is 0 when every document passes, 1 when any fails and 2 on a usage\nerror, so it drops straight into a script or a CI step. A file it cannot read\ncounts as a failure, never a skip. Every finding names the line in your file:\nthe element itself when it is there, and where it belongs when it is missing,\nin the file's own syntax (UBL or CII). `--short` prints one line per finding,\n`--quiet` only failures, `--json` machine-readable output; `--fail-on warning`\nfails on warnings too, `--profile <name>` judges every document against one\nprofile, and `--large` accepts invoices past the default size limits (about\n3,000 lines). `npx @attestwire/en16931 --help` lists the rest.\n\nBesides the rule findings `validateInput` returns, `validate()` and the\ncommand line report a few of their own, about the file rather than the\ninvoice. They carry an `AW-` id and no `docsUrl`, and they are not rules, so\nthey are not in the rule counts: `AW-SIZE` (past the size limits without\n`--large`, or `options.limits` raised), `AW-PDF` (a `.pdf` file that is not a PDF, or a\nPDF with no readable invoice XML inside), `AW-PARSE` (not a UBL or CII\ninvoice, or not the text its encoding says; for a PDF, the XML inside it),\n`AW-PROFILE-SUBSET` (a Factur-X MINIMUM or BASIC WL file, which\ncarries too little to be an EN 16931 invoice; fatal) and `AW-PROFILE-SYNTAX`\n(a `--profile` or `options.profile` for the other syntax; a warning). The\ncommand line alone reports `AW-IO` (the file could not be read). Until 0.10.0\nthe last two were both `AW-PROFILE`, and only the command line reported any\nof them.\n\nA Factur-X or ZUGFeRD PDF adds the container's own findings, about the PDF\naround the invoice XML rather than the XML, and never fatal:\n`AW-PDF-ATTACHMENT` (the XML attachment's name, whether it is the only one,\nits encoding declaration, whether it is CII), `AW-PDF-AF` (where the PDF\nregisters it), `AW-PDF-RELATIONSHIP` (its `/AFRelationship`), `AW-PDF-MIME`\n(its media type), `AW-PDF-XMP` (the XMP metadata: there, readable, claiming\nPDF/A-3, carrying the Factur-X properties) and `AW-PDF-XMP-PROFILE` (the\nprofile the metadata declares, against the one the XML declares). They are\nwarnings, which `--fail-on warning` fails on, or information, which nothing\nfails on. [The container's findings](#the-containers-findings) lists every\ncase.\n\nOn GitHub, the\n[Validate E-Invoice action](https://github.com/attestwire/validate-einvoice-action)\nruns the same engine offline on every pull request, annotates the failing files\nand can emit SARIF:\n\n```yaml\n- uses: attestwire/validate-einvoice-action@v1\n  with:\n    files: invoices/**/*.xml\n```\n\n## Quickstart\n\n```bash\nnpm install @attestwire/en16931\n```\n\n**Which function.** Checking a file you already have (UBL, CII, or a Factur-X /\nZUGFeRD PDF)? Call `validate(bytes)`, shown under [Recipes](#recipes).\nBuilding an invoice from your own data? Fill in an `InvoiceInput` object, check\nit with `validateInput`, as below, and only then write the XML with\n`generateXRechnungUBL` or `generateCii`. The generators do not validate.\n\n### 1. Validate an invoice\n\nA conformant XRechnung, as small as validity allows. Every identifier here is\nsynthetic; the IBAN is the test IBAN used throughout German banking\ndocumentation.\n\n```ts\nimport { validateInput, type InvoiceInput } from \"@attestwire/en16931\";\n\nconst invoice = {\n  profile: \"xrechnung-ubl\",\n  invoiceNumber: \"2026-000142\",\n  issueDate: \"2026-08-09\",\n  currency: \"EUR\",\n  buyerReference: \"04011000-1234512345-06\", // Leitweg-ID\n  deliveryDate: \"2026-08-31\",\n  seller: {\n    name: \"Acme GmbH\",\n    vatId: \"DE123456789\",\n    address: { line1: \"Chausseestr. 1\", city: \"Berlin\", postalCode: \"10115\", countryCode: \"DE\" },\n    electronicAddress: { schemeId: \"0204\", value: \"04011000-1234512345-06\" },\n    contact: { name: \"Buchhaltung\", phone: \"+49 30 1234567\", email: \"rechnungen@acme.example\" },\n  },\n  buyer: {\n    name: \"Stadt Bonn\",\n    address: { line1: \"Berliner Platz 2\", city: \"Bonn\", postalCode: \"53111\", countryCode: \"DE\" },\n    electronicAddress: { schemeId: \"0204\", value: \"04011000-1234512345-06\" },\n  },\n  payment: { meansCode: \"58\", iban: \"DE02120300000000202051\" },\n  lines: [\n    { id: \"1\", description: \"Consulting, August 2026\", quantity: 10, unitCode: \"HUR\", unitPrice: 150, vatCategory: \"S\", vatRate: 19 },\n  ],\n} satisfies InvoiceInput;\n\nconst result = validateInput(invoice);\n\nconsole.log(result.valid, result.errors.length); // true 0\n```\n\nThat object is the whole input contract. Keep the `satisfies InvoiceInput`:\n`profile` is a union of five string literals, and without it TypeScript widens\n`\"xrechnung-ubl\"` to `string` and the call no longer compiles. The same object\nfeeds both generators: `generateXRechnungUBL(invoice)` returns UBL 2.1 XML, and\n`generateCii({ ...invoice, profile: \"xrechnung-cii\" })` returns CII.\n\n### 2. Take one field out\n\nRemove the buyer reference (BT-10, the Leitweg-ID a German public-sector buyer\nrequires) and you get a rejection that names the rule and tells you what to do:\n\n```ts\nconst { buyerReference, ...missingReference } = invoice;\n\nconst rejected = validateInput(missingReference);\n\nconsole.log(rejected.valid, rejected.errors.map((e) => e.rule)); // false [ 'BR-DE-15' ]\n```\n\n`rejected.errors[0]` is this object, in full:\n\n```json\n{\n  \"rule\": \"BR-DE-15\",\n  \"field\": \"BT-10\",\n  \"severity\": \"fatal\",\n  \"message\": \"XRechnung requires a buyer reference (BT-10). For German public-sector buyers this is the Leitweg-ID; business buyers may supply any reference, but the field must be present.\",\n  \"fix\": \"Ask your client for their Leitweg-ID (public sector) or an order/customer reference, and set buyerReference.\",\n  \"example\": \"\\\"buyerReference\\\": \\\"04011000-1234512345-06\\\"\",\n  \"xpath\": \"/ubl:Invoice/cbc:BuyerReference\",\n  \"docsUrl\": \"https://attestwire.com/rules/BR-DE-15\"\n}\n```\n\nBoth snippets, their `console.log` output and that JSON are executed and\ntype-checked against this build on every test run\n(`src/readme-quickstart.test.ts` in the repository), so this page cannot drift\nfrom the library.\n\n## Say what happened, not the code\n\nEN 16931 states VAT as codes. Your system knows that the customer is a\nbusiness in France; the standard wants `AE`, `VATEX-EU-AE` and\n\"Steuerschuldnerschaft des Leistungsempfängers\". State the fact as\n`vatScenario`, and leave out the payment means code when there is an IBAN, and\nthe engine writes the codes:\n\n```ts\nimport { applyDefaults, generateXRechnungUBL, validateInput, type InvoiceFacts } from \"@attestwire/en16931\";\n\nconst facts = {\n  profile: \"xrechnung-ubl\",\n  invoiceNumber: \"2026-000143\",\n  issueDate: \"2026-08-09\",\n  currency: \"EUR\",\n  buyerReference: \"PO-FR-2026-0088\",\n  deliveryDate: \"2026-08-31\",\n  vatScenario: \"intra-eu-services\", // a service to a business in another EU member state\n  seller: {\n    name: \"Acme GmbH\",\n    vatId: \"DE123456789\",\n    address: { line1: \"Chausseestr. 1\", city: \"Berlin\", postalCode: \"10115\", countryCode: \"DE\" },\n    electronicAddress: { schemeId: \"9930\", value: \"DE123456789\" },\n    contact: { name: \"Buchhaltung\", phone: \"+49 30 1234567\", email: \"rechnungen@acme.example\" },\n  },\n  buyer: {\n    name: \"Client Exemple SARL\",\n    vatId: \"FR12345678901\",\n    address: { line1: \"12 rue de la République\", city: \"Lyon\", postalCode: \"69001\", countryCode: \"FR\" },\n    electronicAddress: { schemeId: \"9957\", value: \"FR12345678901\" },\n  },\n  payment: { iban: \"DE02120300000000202051\" }, // no meansCode: a euro payment to a SEPA IBAN is \"58\"\n  lines: [{ id: \"1\", description: \"Consulting, August 2026\", quantity: 8, unitCode: \"HUR\", unitPrice: 175 }],\n} satisfies InvoiceFacts;\n\nconst result = validateInput(facts);\nconsole.log(result.valid, result.information.map((n) => n.rule)); // true [ 'ATW-VAT-SCENARIO-APPLIED', 'ATW-PAYMENT-MEANS-INFERRED' ]\n\nconst { invoice } = applyDefaults(facts);\nconsole.log(invoice.lines[0]?.vatCategory, invoice.vatExemptionReasonCodes); // AE { AE: 'VATEX-EU-AE' }\n\nconst xml = generateXRechnungUBL(facts); // byte for byte generateXRechnungUBL(invoice)\n```\n\n`validateInput`, `generateXRechnungUBL` and `generateCii` all apply\n`applyDefaults` first, so the document is byte for byte the one the explicit\ncodes produce; the test suite proves it for every scenario in both syntaxes.\n`applyDefaults(facts)` gives you that explicit invoice, to store or inspect,\nwith one `information` note per thing it filled in (`ATW-VAT-SCENARIO-APPLIED`,\n`ATW-PAYMENT-MEANS-INFERRED`). The same notes come back in `validateInput`'s\n`information`, which never affects `valid`. `applyVatScenarios` is the VAT half\non its own.\n\n| `vatScenario` | Category, rate | BT-121 | BT-120 for a seller in DE or AT · FR · elsewhere | The invoice must also state |\n| --- | --- | --- | --- | --- |\n| `\"domestic\"` | S, your `vatRate` | — | — | a `vatRate` on each line; it is never guessed |\n| `\"intra-eu-goods\"` | K, 0 | `VATEX-EU-IC` | Steuerfreie innergemeinschaftliche Lieferung · Exonération de TVA, article 262 ter I du CGI · Intra-Community supply | both parties' VAT identifiers, `deliverTo.countryCode`, and `deliveryDate` or `invoicingPeriod` |\n| `\"intra-eu-services\"` | AE, 0 | `VATEX-EU-AE` | Steuerschuldnerschaft des Leistungsempfängers · Autoliquidation · Reverse charge | both parties' VAT identifiers |\n| `\"export\"` | G, 0 | `VATEX-EU-G` | Steuerfreie Ausfuhrlieferung · Exonération de TVA, article 262 I du CGI · Export outside the EU | the seller's VAT identifier |\n| `\"small-business-exemption\"` | E, 0 | `VATEX-FR-FRANCHISE` in France; none in Germany | Steuerbefreiung für Kleinunternehmer gemäß § 19 UStG · TVA non applicable, article 293 B du CGI · refused | a seller in Germany or France, with a tax number or VAT identifier |\n\nA seller in Austria gets the German texts, except that the small-business\nexemption there is not § 19 UStG and is refused, as everywhere outside\nGermany and France.\n\n- **Where it goes.** On the invoice, `vatScenario` is the default for every\n  line, document level allowance and document level charge. On one of those,\n  it overrides the default.\n- **What you state wins.** A `vatCategory`, `vatRate`, or\n  `vatExemptionReasons` / `vatExemptionReasonCodes` entry you give is kept. An\n  item that states a category under the invoice's default keeps it; an item\n  whose own `vatScenario` and own `vatCategory` disagree is the fatal\n  `ATW-VAT-SCENARIO-CONFLICT`, because one of the two is wrong and nothing\n  downstream can tell which.\n- **Missing facts are reported, never invented.** Each is a fatal\n  `ATW-VAT-SCENARIO-FACT-MISSING` naming the scenario and the field, beside\n  the regulation's own finding (`BR-IC-12` and so on) where it has one. The\n  reverse charge asks for both VAT identifiers even though `BR-AE-02` accepts a\n  tax or legal registration number, because Article 226(3) and (4) of the VAT\n  Directive require them. A misspelt scenario is `ATW-VAT-SCENARIO-UNKNOWN`,\n  with the one it most likely meant.\n- **The payment means code** (BT-81) is inferred only when `payment.meansCode`\n  is absent: `\"59\"` for a direct-debit mandate reference on a euro invoice\n  (`\"49\"` otherwise), else, with an IBAN, `\"58\"` for a euro invoice paid to an\n  IBAN in the SEPA scheme (EPC409-09, version 8.0) and `\"30\"` otherwise. An\n  empty string is a stated value, and a file read by `validate()` always\n  states one, so files are judged exactly as before.\n- **It is not a tax engine.** You decide which scenario applies; the engine\n  makes sure that decision is encoded correctly. Domestic reverse charge (such\n  as § 13b UStG), triangulation, distance sales and exempt or zero-rated\n  domestic supplies have no scenario: state their codes as before.\n- **Types.** `InvoiceFacts` is `InvoiceInput` with `vatCategory` and\n  `payment.meansCode` optional. Functions typed `InvoiceInput`, such as\n  `computeTotals`, want the explicit form: `applyDefaults(facts).invoice`.\n\n### The small-business exemption, and where its codes come from\n\nTracker threads show real confusion here, so each choice rests on the source\nthat decides it, and the sources are also cited in `src/vat-scenarios.ts`.\n\n- **Germany, § 19 UStG.** Category E at rate 0, with no BT-121 code: the CEF\n  VATEX list has none for Germany. Category E is KoSIT's own answer\n  ([XRechnung change request 32](https://projekte.kosit.org/xrechnung/xrechnung/-/issues/32),\n  implemented in XRechnung 1.2: BT-118 `E`, BT-119 `0`), and since 1 January\n  2025 § 19 Abs. 1 UStG says outright that the turnover \"ist steuerfrei\". The\n  sources disagree on the wording, and this build follows the most\n  authoritative. KoSIT's request proposed \"Kein Ausweis von Umsatzsteuer, da\n  Kleinunternehmer gemäß § 19 UStG\", and common practice writes \"Gemäß § 19\n  UStG wird keine Umsatzsteuer berechnet.\"; both describe the regime before\n  2025, when the tax was merely not levied. The law now requires a note that\n  \"die Steuerbefreiung für Kleinunternehmer gilt\" (§ 34a Satz 1 Nr. 5 UStDV),\n  and the Federal Ministry of Finance accepts any wording that names that\n  exemption unambiguously (letter of 18 March 2025, III C 3 - S\n  7360/00027/044/105, UStAE 14.7a Abs. 1). The text written is therefore\n  \"Steuerbefreiung für Kleinunternehmer gemäß § 19 UStG\", in the regulation's\n  own words. To write another, set `vatExemptionReasons.E`.\n- **France, franchise en base.** Category E at rate 0, `VATEX-FR-FRANCHISE`\n  (\"France domestic VAT franchise in base\" in the CEF VATEX list, which this\n  build ships for `BR-CL-22`), and the mention \"TVA non applicable, article 293\n  B du CGI\" that BOFiP BOI-TVA-DECLA-40-10-20 § 50 prescribes. No French rule\n  ties the code to a category, so EN 16931 decides, and it leaves only E:\n  `BR-Z-10` forbids any exemption reason on Z, and `BR-O-10` reserves O's for\n  \"not subject to VAT\". At least one vendor documents a mapping to Z; carrying\n  the code there fails `BR-Z-10`.\n- **Anywhere else** the scenario is refused with\n  `ATW-VAT-SCENARIO-UNSUPPORTED`, and nothing is filled in: each member state\n  runs its own scheme with its own wording.\n\n### A credit note from the original\n\n```ts\nimport { createCreditNote } from \"@attestwire/en16931\";\n\nconst creditNote = createCreditNote(invoice, {\n  invoiceNumber: \"2026-G00021\",\n  issueDate: \"2026-09-01\",\n  reason: \"Beratung nicht erbracht.\",\n});\nconsole.log(creditNote.invoiceTypeCode, creditNote.precedingInvoices); // 381 [ { invoiceNumber: '2026-000143', issueDate: '2026-08-09' } ]\n```\n\nThe credit note references the original (BT-25, BT-26), keeps its profile,\nparties, currency, payment details, references and delivery details, and\ncredits the lines you list in `lines` (all of them by default) with their\npositive quantities and amounts: the type code, 381, is what says the money\ngoes back. What belongs to the original's settlement stays behind: the due\ndate, the VAT point date, the paid and rounding amounts, declared totals and\nattachments. Document level allowances and charges, and the VAT total in the\naccounting currency (BT-111), travel only with a full credit, because splitting\nthem over some of the lines is not something a library can decide. A line id\nthe original does not have throws a `RangeError` rather than crediting less\nthan you meant. The generators emit a UBL `CreditNote` or a CII document with\n`TypeCode` 381, as for any credit note.\n\nThe snippets in this section are executed and type-checked on every test run\ntoo (`src/readme-facts.test.ts`).\n\n## Recipes\n\n**Why did my customer's platform reject this file?** Hand it over as it is. UBL,\nCII and Factur-X / ZUGFeRD PDFs are told apart from their bytes, the declared\nencoding is honoured, and every finding says which line of the file it is about:\n\n```ts\nimport { readFile } from \"node:fs/promises\";\nimport { validate } from \"@attestwire/en16931\";\n\nconst result = validate(await readFile(\"invoice.xml\")); // or invoice.pdf\n\nfor (const e of result.errors) console.log(`line ${e.location?.line}`, e.rule, e.fix);\n```\n\n`validate` never throws for anything about the file. A ZIP, an HTML login page\nor a PDF with no invoice inside comes back as one fatal `AW-` finding naming what\nit is, with the reader's own exception in `result.error`. `result.invoice` is the\ninvoice as read, ready for either generator.\n\nDecoding is strict. Bytes that are not valid in the encoding a file declares\nare a finding, never a replacement character, and so is a file converted to\nUTF-8 whose declaration still names a single-byte encoding such as\nISO-8859-1: read as it declares, every \"ß\" in it would be \"ÃŸ\". If you have\nalready decoded the text yourself, pass the string, which is taken as it is.\n\n**Generate the XML.** One model, pick the syntax by picking the function. The\ngenerators write whatever they are given, fatal findings and all, so check\nfirst:\n\n```ts\nimport { generateCii, generateXRechnungUBL, validateInput } from \"@attestwire/en16931\";\n\nconst { valid, errors } = validateInput(invoice);\nif (!valid) throw new Error(errors.map((e) => e.rule).join(\", \"));\n\nconst ubl = generateXRechnungUBL(invoice);                                 // XRechnung UBL\nconst cii = generateCii({ ...invoice, profile: \"facturx-en16931\" });      // Factur-X XML payload\nconst credit = generateXRechnungUBL({ ...invoice, invoiceNumber: \"2026-G00021\", invoiceTypeCode: \"381\" }); // credit note\n```\n\n**Plug it into what you already run:**\n\n| | |\n| --- | --- |\n| **Stripe** | [`examples/stripe`](https://github.com/attestwire/en16931/tree/main/examples/stripe): a finalized Stripe invoice to validated XRechnung or Factur-X XML, in one file you copy. |\n| **Medusa v2** | [`medusa-plugin-einvoice`](https://github.com/attestwire/medusa-plugin-einvoice): XRechnung and Factur-X XML for every order. |\n| **GitHub Actions** | [`validate-einvoice-action`](https://github.com/attestwire/validate-einvoice-action): pull-request annotations, SARIF, fully offline. |\n| **AI agents** | [Attestwire MCP server](https://attestwire.com/mcp): validate, explain and generate from Claude, Cursor or any MCP client. |\n| **No Node at all** | [Hosted API](https://api.attestwire.com/docs): the same engine over HTTP, for PHP, Python, Go or anything else that can POST JSON. |\n| **Any rule, explained** | [Rule reference](https://attestwire.com/rules/): one page per rule, with the reason, the fix and a passing example. Every finding's `docsUrl` points there. |\n\n## How it compares\n\n| | **@attestwire/en16931** | KoSIT validator | Mustang |\n| --- | --- | --- | --- |\n| Runtime | Any JavaScript runtime, browser included | Java | Java |\n| Validates UBL and CII | ✅ | ✅ | ✅ |\n| Generates UBL and CII XML | ✅ | — | ✅ |\n| Reads Factur-X / ZUGFeRD PDFs | ✅ | — | ✅ |\n| Writes Factur-X / ZUGFeRD PDFs | — | — | ✅ |\n| Error output | rule, reason, fix, example, docs link | the schematron's assertion text | the schematron's assertion text |\n| Status | a fast pre-flight, checked against KoSIT | **the reference** German receivers use | established Java library |\n\nUse this package to catch and explain problems early, in the language your\nstack already speaks. Where a receiver's verdict is what counts, run KoSIT too:\n[`scripts/kosit-check.sh`](scripts/kosit-check.sh) does it for you. If you need\nthe PDF/A-3 container written, pair `generateCii` with a PDF/A-3 library or\nMustang.\n\n## Limits worth knowing up front\n\n- **It validates the invoice model, not the XML document.** A file is parsed\n  into `InvoiceInput` and the rules run on that. It is not a schematron, so a\n  document it passes can in principle still be rejected by KoSIT.\n- **It does not write Factur-X or ZUGFeRD PDFs.** It writes the CII XML *payload*\n  and reads the PDF. A file this package produces is a CII XML document, not a\n  Factur-X file. [Why](#the-pdf-read-never-written).\n- **It checks a Factur-X PDF's container, not its PDF/A conformance.** It\n  checks the XML attachment and what the XMP metadata claims, against the\n  formats and against the XML. Whether the file is the PDF/A-3 it claims to\n  be is a question for a PDF/A validator such as veraPDF.\n- **It does not send invoices.** No Peppol access point, no transmission.\n- The full, specific list is in [Not implemented yet](#not-implemented-yet).\n\n---\n\n# Reference\n\n## Teaching errors\n\nThe [quickstart](#2-take-one-field-out) shows one missing field and the object\nit produces. Every finding has that shape, and a rejection is a list of them\nrather than \"validation failed\": drop the `buyerReference`, the `payment` block\nand the seller `contact` from the quickstart invoice and `validateInput` reports\nthree fatal findings (`BR-DE-15`, `BR-DE-1`, `BR-DE-2`), with nothing in\n`warnings` and nothing in `information`. (That count is asserted by\n`src/readme-quickstart.test.ts` (repository) against this build.)\n\nErrors explain the *reason*, not just the requirement. `BR-S-05` does not say\n\"rate must be > 0\"; it says a zero rate with category S is contradictory, and\nthat if no VAT is due the category should be Z, E, AE, K, G or O, each with\ndifferent evidencing requirements.\n\nFindings are separated by severity, because the reference validators separate\nthem: KoSIT's schematron flags each assertion `fatal`, `warning` or\n`information`, and a report that promotes an advisory to an error is as wrong as\none that misses it. `result.valid` reflects fatal rules only, so advisory rules\n(`BR-DE-27`, `BR-DE-28`) never block a build. `result.information` is a third\narray, deliberately kept out of `warnings`: a caller who fails a build on a\nnon-empty `warnings` array should not be stopped by a finding the official\nvalidator raises and then accepts. `BR-DE-TMP-32` (an invoice should state a\ndelivery date) is the rule that needs it.\n\nIf you switch or filter on `severity`, add the third value: a consumer that\nallow-lists `['fatal', 'warning']` will silently drop `information` findings.\nThe union is exported as the type `Severity`, so a `switch` over it that misses\na case fails the build rather than the audit.\n\n## Locations\n\n`validateInput` judges an object, so the `xpath` on its findings is where the\nelement sits in the UBL this library would generate. `validate` judges a file,\nand walks each finding back to the file:\n\n```json\n{\n  \"rule\": \"BR-CL-18\",\n  \"xpath\": \"/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem[2]/ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:CategoryCode\",\n  \"location\": {\n    \"line\": 137,\n    \"column\": 11,\n    \"path\": \"/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:IncludedSupplyChainTradeLineItem[2]/ram:SpecifiedLineTradeSettlement/ram:ApplicableTradeTax/ram:CategoryCode\",\n    \"exact\": true\n  }\n}\n```\n\nThat is the second line's VAT category in `fixtures/xrechnung-cii-extended.xml`\nset to `Q`. `path` uses the prefixes the file declares; `xpath` is the same\nelement when it is found.\n\n- **CII documents get CII paths.** A Factur-X or XRechnung CII finding points at\n  the `ram:` element, not at a `cac:` path that does not exist in the file.\n- **Positions are the file's.** The rules count a document's allowances before\n  its charges; a file that states a charge first still gets the right element.\n- **`exact: false` means \"look here\".** When the element is missing, the\n  location is the element it belongs in, and `xpath` is where it goes. The same\n  happens when the file holds several elements the rule could mean and nothing\n  says which (several VAT breakdown groups, several tax registrations): the\n  location is their parent rather than a guess.\n- **From a PDF**, the line and column are in the embedded XML, and\n  `location.attachment` names it. `toSarif` puts a line in the SARIF region only\n  when it is a line of the file the log names. The container's own `AW-PDF-*`\n  findings are about the PDF around the XML, where a key or an XMP property has\n  no line, so they carry no `location` and their message names the place.\n\n## Identifier checks\n\nEN 16931 asks for a Leitweg-ID, an IBAN or a SIREN and does not recompute\nits check digits (XRechnung's `BR-DE-19` does, for the IBAN of a SEPA\ntransfer), so a mistyped one passes validation and fails later: the portal cannot route the invoice, the bank returns the payment, the\nplatform finds no such company. `validateInput` and `validate` recompute them\nand report five warnings of their own. None is a rule of EN 16931 or of a\nCIUS, so they never change `valid`.\n\n| Finding | What is checked | Where |\n| --- | --- | --- |\n| `ATW-LEITWEG-ID-INVALID` | The form and the ISO/IEC 7064 MOD 97-10 check digits of the Leitweg-ID format specification 2.0.2 (Koordinierungsstelle für IT-Standards, 2021): a coarse address of 2 to 12 digits, an optional fine address of up to 30 letters and digits, two check digits, joined by hyphens. | Any identifier under scheme 0204 (BT-34, BT-49, BT-29, BT-46, BT-30, BT-47, BT-60, BT-61, BT-71). The buyer reference (BT-10) only when it has the complete form of a Leitweg-ID, a coarse address of 2, 3, 5, 8, 9 or 12 digits beginning with a Land code (01 to 16) or 99, on an invoice to a German buyer. |\n| `ATW-IBAN-INVALID` | ISO 13616: the length the SWIFT IBAN Registry gives the country, and the MOD 97-10 check digits, in capitals. | BT-84 under a SEPA credit transfer (58), and any other BT-84 that starts like an IBAN. On an XRechnung SEPA transfer `BR-DE-19` already reports the form and the check digits, so this adds only the length. |\n| `ATW-BIC-INVALID` | ISO 9362: 8 or 11 capital letters and digits, the fifth and sixth a country code. | BT-86, when present. |\n| `ATW-SIREN-INVALID` | Nine digits, the last a Luhn check digit. | Any identifier under scheme 0002. |\n| `ATW-SIRET-INVALID` | Fourteen digits that pass the Luhn check, as the SIREN they begin with must. La Poste's establishments (SIREN 356000000) are INSEE's exception: their digits add up to a multiple of 5. | Any identifier under scheme 0009. |\n\nA business buyer may put any reference in BT-10, which is why it is checked\nonly when it evidently is a Leitweg-ID; `PO-4711` and `2026-07-31` never are.\nTwo identifiers are left alone on purpose. A GLN (scheme 0088) is checked by\n`PEPPOL-COMMON-R040` on `profile: \"peppol-bis-3\"`, at Peppol's severity, and\nnot on other profiles. A VAT identifier's check digits differ by country,\nseveral countries publish none, and whether one exists is for VIES to say;\n`BR-CO-09` checks its country prefix.\n\nThe same checks are exported as yes/no functions, for a form that wants the\nanswer before the invoice exists: `isValidLeitwegId`, `isValidIban`,\n`isValidBic`, `isValidSiren` and `isValidSiret`, with `IBAN_LENGTHS`.\n\n## Findings for invoice recipients\n\nA business that receives an e-invoice in Germany has to decide what each\nfinding means for it. The BMF letter of 15 October 2025 on mandatory\ne-invoicing (III C 2 - S 7287-a/00019/007/243) sorts what a validator reports\nthree ways, and `recipientClass(ruleId)` says which of them a finding is:\n\n| Class | What it covers | The letter |\n| --- | --- | --- |\n| `format` | The file is not a structured e-invoice: not UBL or CII XML (`AW-PARSE`), a PDF with no readable invoice XML (`AW-PDF`), a Factur-X MINIMUM or BASIC WL file (`AW-PROFILE-SUBSET`), or a value the syntax cannot hold. | Rn. 6a: such a file is a \"sonstige Rechnung\", whatever kind of format error it has. |\n| `vat-relevant` | A business rule about content §§ 14 Abs. 4 and 14a UStG require: the parties' names and addresses, the supplier's tax number or VAT identifier, the issue date and invoice number, the quantity and kind of the supply, the date of supply, the net amount per rate, the tax rate and amount or the exemption note, agreed reductions, the reverse-charge note, and the invoice a correction or credit note refers to. | Rn. 35a: a breach of these makes the invoice not \"ordnungsmäßig\". |\n| `formal` | Every other business rule: the buyer reference (`BR-DE-15`), contact data, electronic addresses, payment details, most code-list formalities, the identifier checks above, and the PDF container of a hybrid invoice whose XML was read. | Rn. 35a: business-rule errors about other content are \"umsatzsteuerlich unbeachtlich\". In a hybrid invoice the XML prevails (UStAE 14.4 Abs. 3). |\n\n```ts\nimport { readFile } from \"node:fs/promises\";\nimport { recipientClass, validate } from \"@attestwire/en16931\";\n\nconst result = validate(await readFile(\"invoice.xml\"));\nfor (const f of [...result.errors, ...result.warnings, ...result.information]) {\n  console.log(recipientClass(f.rule), f.rule);\n}\n```\n\nThe class belongs to the rule id, from a table that covers every id this build\nreports, `AW-` and `ATW-` findings included, and a test fails when an id is\nmissing from it. Where one id covers several business terms it takes the more\ncautious class, and an id the table does not know is `vat-relevant`. The code\ncomment in `src/recipient-class.ts` cites the paragraph behind each group.\n\nThis is Attestwire's reading of the letter, not tax advice. The letter is\nexplicit that validation supports the recipient's own check of an invoice for\ncompleteness and correctness and does not replace it, and that an invoice can\ncarry a content error no rule detects, a wrong tax rate being its example. A\n`vat-relevant` class says a finding concerns content the VAT law requires; it\ndoes not settle whether the invoice meets that law, and neither does the\nabsence of findings.\n\n## Reading an existing UBL invoice\n\n`parseUbl` reads a UBL 2.1 `Invoice` **or `CreditNote`** document into the same\n`InvoiceInput` object the rest of this package uses. That is what lets you\nanswer the question people actually arrive with: *my customer's platform\nrejected this file. Why?*\n\nThe document type is detected from the root element, not asked for, and comes\nback in `invoice.invoiceTypeCode`. Feed the result to `generateXRechnungUBL` and\nyou get the same document type out. (The function is still exported under its\nold name, `parseUblInvoice`, which reads credit notes too.)\n\nTo **check** a file, you do not need the reader: `validate` detects the syntax,\nreads it with `parseUbl` or `parseCiiInvoice`, runs the rules and points each\nfinding at its line (see [Recipes](#recipes) and [Locations](#locations)). Call\n`parseUbl` yourself when you want the `InvoiceInput` object, to change a field\nand generate the document again:\n\n```ts\nimport { parseUbl, generateXRechnungUBL, validateInput } from \"@attestwire/en16931\";\n\nconst { invoice, unmapped } = parseUbl(xmlString);\nconst fixed = { ...invoice, buyerReference: \"04011000-1234512345-06\" };\nif (validateInput(fixed).valid) {\n  const corrected = generateXRechnungUBL(fixed);\n}\n\nfor (const item of unmapped) {\n  console.log(item.kind, item.path, item.reason);\n}\n```\n\n**It is a reader, not an authority.** It tells you what is in the document, not\nwhether a receiver will accept it. A file that passes `validate` can still be\nrejected by KoSIT or by a receiving platform: the rules run over what the\nreader understood, not over the XML, and this build is not a schematron. See\n[Not implemented yet](#not-implemented-yet).\n\n### What it reads\n\nEvery element `generateXRechnungUBL` emits, mapped back to the field it came\nfrom. The round trip is tested: for each committed fixture,\n`generateXRechnungUBL(parseUbl(xml).invoice)` returns the identical\ndocument, and the result validates identically, for the credit-note fixtures as\nwell as the invoice ones.\n\nNamespaces are resolved by URI, not by prefix. A document that calls the two\ncommon namespaces `b:` and `a:`, or that puts the root in the default\nnamespace, reads the same as one using `cbc:` and `cac:`. Element order does not\nmatter to the reader.\n\nThe document's own totals (BT-106 to BT-115) are read into `declaredTotals`, so\n`validateInput` checks the document's arithmetic against ours under the\n`BR-CO-*` rules. The VAT breakdown and the line net amounts are recomputed from\nthe lines instead of being stored, because that is how the input model works.\n\n`parseUbl` also returns `customizationId` and `profileId`: BT-24 and\nBT-23 exactly as the document states them. `invoice.profile` is derived from\nBT-24. If BT-24 is missing or unknown, the profile falls back to `en16931` or is\nguessed from the text, and the guess is reported in `unmapped`, because the\nprofile decides which CIUS rules run.\n\n### What it refuses\n\nIt throws instead of returning a half-read invoice. Every error extends\n`ParseError` and carries a stable `code`.\n\n| Error | `code` | When |\n| --- | --- | --- |\n| `UnsupportedSyntaxError` | `unsupported_syntax` | The root element is neither a UBL `Invoice` nor a UBL `CreditNote`. A CII document (ZUGFeRD, Factur-X, XRechnung CII) gets its own message saying so and pointing at `parseCiiInvoice`. |\n| `UnsupportedCreditNoteError` | `unsupported_document_type` | **Never.** Kept exported for compatibility; nothing has thrown it since credit notes became readable. |\n| `XmlSecurityError` | see below | The document hit one of the security limits. |\n| `XmlSyntaxError` | various | The document is not well-formed, or uses a construct outside the accepted subset. |\n\nFactur-X and ZUGFeRD carry this CII inside a PDF/A-3. Since 0.7.0 that container\nis **read**: `extractFacturX` returns the embedded XML, which you hand to\n`parseCiiInvoice`, and what the container says about that XML is checked (see\n[the container's findings](#the-containers-findings)). It is still never\nwritten.\n\n### Security limits\n\nThe XML comes from someone else. The reader is written for the UBL subset and\nrefuses everything outside it, rather than accepting more and hoping.\n\n| Defence | Limit | What it stops |\n| --- | --- | --- |\n| No DTD processing | any `<!DOCTYPE` or `<!ENTITY` in the document is refused (`xml_doctype_forbidden`, `xml_entity_declaration_forbidden`) | **XXE** — an external entity that reads a local file or makes a network request. Also the declaration half of billion-laughs. The check runs on the raw text, so a DOCTYPE inside a CDATA section is refused too. |\n| No custom entity expansion | only `&amp; &lt; &gt; &quot; &apos;` and numeric character references are decoded (`xml_entity_forbidden`) | **Billion laughs.** An unknown entity is refused, never silently dropped — dropping one would change the text of a tax document without saying so. |\n| Depth cap | 100 elements (`xml_too_deep`) | Deeply nested documents. A UBL invoice nests about eight levels. |\n| Size cap | 8,000,000 characters (`xml_too_large`) | Memory exhaustion from a very large upload. |\n| Element cap | 50,000 elements (`xml_too_many_elements`) | A flat document of millions of tiny elements, which passes both caps above. |\n| Attribute cap | 256 per element (`xml_too_many_attributes`) | A root carrying tens of thousands of `xmlns:` declarations, each of which enters the namespace map every descendant lookup uses. |\n\nAll four numbers are the defaults in `DEFAULT_XML_LIMITS` and can be raised per\ncall: `parseUbl(xml, { maxCharacters: 16_000_000 })`.\n\n**What the caps protect, and what they cost.** They are memory limits, chosen\nfrom measurement, not from how big a file \"feels\". Every element in the\nparsed tree retains roughly 250–400 bytes (the object, its four name strings,\nits attribute array and its children array), so it is the element cap, not the\nsize cap, that bounds what a document can make the parser hold: at the default\n50,000 elements the measured worst case is 35 ms and 16.3 MB retained. The size\ncap is set high enough for the documents real validators accept, including\nones whose bulk is a single base64 attachment (a 3.29 MB CEN example parses in\ntwelve milliseconds and retains 0.4 MB).\n\nThe cost is that an unusually large invoice is refused, not parsed. The\nlargest fixture in this repository is under 10 kB and a thousand-line invoice\nlands around 300 kB, so neither cap is a limit ordinary use meets. Base64\nspends four characters per three bytes, so an attachment of about 6 MB fills\nthe default size cap on its own; that is the case to raise `maxCharacters` for,\ndeliberately.\n\n⚠ **Changed in 0.4.0.** The size cap was 10,000,000 characters and the element\ncap 200,000. Measured on Node 22, a legal document at the old size cap retained\nabout 81 MB of heap and about 306 MB of RSS, over the 128 MB a Cloudflare\nWorkers isolate is allowed, so a single such request was killed rather than\nrejected. A 785 kB body already retained about 47 MB. If you run this on a\nserver with real memory and you know why you need it, raise the option.\n\nThe reader also refuses mixed content (an element holding both text and child\nelements), unbound namespace prefixes, and control characters XML 1.0 does not\npermit. Comments and processing instructions are skipped and never acted on: a\nstylesheet instruction cannot make this library fetch anything.\n\n### Nothing is dropped silently\n\nAnything in the document that does not reach the invoice object is returned in\n`unmapped`, with its path, its name, its namespace and its text:\n\n```ts\n{\n  path: \"/ubl:Invoice/cac:AccountingSupplierParty/cac:Party/cbc:WebsiteURI\",\n  name: \"cbc:WebsiteURI\",\n  namespace: \"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\",\n  kind: \"unknown\",\n  reason: \"This parser has no field for this element, so neither it nor anything inside it reached the invoice object.\",\n  text: \"https://example.invalid\"\n}\n```\n\n`kind` separates the two reasons, and they are very different:\n\n- `\"unknown\"`: there is no field for it. **The content is gone from the\n  model.** If it matters to you, read it from the XML yourself.\n- `\"recomputed\"`: the element is understood, but the model derives the value\n  instead of storing it. Line net amounts (BT-131) and the VAT breakdown\n  (BT-116, BT-117) are the whole of this list for a document this package\n  generated. Nothing is lost; the values come back from the lines.\n\nAn unmapped group is reported once, not once per element inside it. A number the\nreader cannot read is reported too (including an empty element, which slipped\nthrough this promise until 0.6.0), and the field is left unset, not guessed at.\n\nFor the six **document totals** that is no longer the end of it. Being left\nunset used to mean nothing compared them and the document validated clean; since\n0.6.0 the reader records what happened in `declaredTotals.defects`, and a total\nthat the document should state and does not fails `BR-12`, `BR-13`, `BR-14` or\n`BR-15`, while one that is present and unreadable (`12,34`, say) fails\n`ATW-DECLARED-TOTAL-NOT-A-NUMBER`. Building an invoice from the JSON model is\nunaffected: omit a total there and the library computes it, as it always has.\n\n### What a real XRechnung from a German portal will hit\n\nHonestly: things this reader does not yet handle.\n\n- **`ubl:SelfBilledInvoice` and `ubl:SelfBilledCreditNote`.** Two more UBL root\n  elements, for documents the buyer issues. Refused by root element. BT-3 `389`\n  and `261` are read and written on the ordinary `Invoice` and `CreditNote`\n  roots, which is what EN 16931's binding asks for. It is the self-billing\n  *workflow*, not the type code, that is out of scope.\n- **`cac:Signature`, `cbc:CopyIndicator`, `cbc:UBLVersionID`** and the other UBL\n  elements that carry no EN 16931 business term. These parse, and appear in\n  `unmapped` as `\"unknown\"`. They are not errors.\n- **Repeated groups the input model holds only once**: a second `cbc:Note`, a\n  second `cac:PartyIdentification`, a second `cac:PaymentMeans`. The first is\n  read; the rest are reported as `\"unknown\"`.\n- **`cac:PaymentTerms` `#SKONTO#` lines.** XRechnung encodes discount terms in\n  the payment-terms text. They are read as text, exactly as written, and are not\n  parsed into fields.\n- **A tax scheme other than `VAT` or `FC`** on a party is reported, not\n  taken for a VAT number.\n\nNothing in that list produces a wrong invoice. Everything in it produces either\na clear refusal or an `unmapped` entry.\n\n## The PDF: read, never written\n\nFactur-X and ZUGFeRD are CII XML inside a PDF/A-3 container. **As of 0.7.0 the\ncontainer is read (extraction); it is still never built.** What the container\nsays about the XML inside it, and what its XMP metadata claims, is checked:\nsee [the container's findings](#the-containers-findings).\n\nTo check one, hand the PDF's bytes to `validate`, which finds the attachment,\nreports where in it each finding is, and adds the container's own findings:\n\n```ts\nimport { readFile } from \"node:fs/promises\";\nimport { validate } from \"@attestwire/en16931\";\n\nconst result = validate(await readFile(\"invoice.pdf\"));\nconsole.log(result.container, result.valid);\n```\n\nThe reader underneath is `extractFacturX`, which pulls the XML attachment out of\na Factur-X, ZUGFeRD or XRechnung-CII PDF, for when you want the XML itself:\n\n```ts\nimport { readFile } from \"node:fs/promises\";\nimport { extractFacturX } from \"@attestwire/en16931\";\n\nconst { xml, attachmentName, findings, xmp } = extractFacturX(await readFile(\"invoice.pdf\"));\n```\n\nIt reads classic cross-reference tables, cross-reference streams and object\nstreams, and inflates `FlateDecode` with a DEFLATE implementation written into\nthis package, so the zero-dependency promise holds and the function stays\nsynchronous. `findings` carries what the container says about the attachment\nand in its metadata, each with a stable `id`; `xmp` is what the metadata states\n(the PDF/A part and level, the Factur-X properties), and `relationship` the\nattachment's `/AFRelationship`. `warnings` carries the attachment notes as\nsentences, exactly as it always has: a non-standard attachment name, a missing\nor wrong `/AFRelationship`, more than one XML attachment. Malformed PDFs raise\na named error with a stable `code`, never a crash.\n\n`xml` is the attachment's UTF-8 text, exactly. Factur-X and ZUGFeRD\nattachments are UTF-8, and a receiver is entitled to read them as UTF-8\nwhatever they declare, so an attachment in another encoding — ISO-8859-1,\nUTF-16 — or whose bytes are not valid in the encoding it names throws\n`FacturXEncodingError`, naming the encoding, rather than coming back with\nreplacement characters. Plain ASCII under another declaration reads the same\neither way and is returned, with a warning. `validate` reports the same\nrefusal as a fatal `AW-PARSE` finding.\n\n### The container's findings\n\nEvery observation about the container has a stable `id` in\n`extractFacturX(...).findings`, and `validate()`, the command line, `--json`,\n`toSarif` and `toJunitXml` report it under the `AW-PDF-*` id beside it:\n\n| `id` | Finding | Severity | When |\n| --- | --- | --- | --- |\n| `attachment_name` | `AW-PDF-ATTACHMENT` | warning | The XML is attached under a name the formats do not define: not `factur-x.xml`, `zugferd-invoice.xml` or `xrechnung.xml`. |\n| `attachment_ambiguous` | `AW-PDF-ATTACHMENT` | warning | Several XML attachments, and none, or more than one, under a standard name: nothing says which is the invoice. |\n| `attachment_extra` | `AW-PDF-ATTACHMENT` | information | Several XML attachments, exactly one under a standard name; that one was read. |\n| `attachment_encoding` | `AW-PDF-ATTACHMENT` | warning | The XML declares an encoding other than UTF-8 and holds only ASCII, so it reads the same today. |\n| `attachment_not_cii` | `AW-PDF-ATTACHMENT` | warning | The attachment is not a CII `CrossIndustryInvoice` (a ZUGFeRD 1.0 document, UBL, or no invoice). |\n| `af_streams_differ` | `AW-PDF-AF` | warning | The EmbeddedFiles name tree and `/AF` list the XML under one name and point at different files. |\n| `af_missing` | `AW-PDF-AF` | warning | The XML is in the name tree and not in the catalog's `/AF` array. |\n| `af_name_tree_missing` | `AW-PDF-AF` | warning | The XML is in `/AF` and not in the name tree. |\n| `relationship_missing` | `AW-PDF-RELATIONSHIP` | warning | No `/AFRelationship`. |\n| `relationship_unexpected` | `AW-PDF-RELATIONSHIP` | warning | An `/AFRelationship` other than Data, Source or Alternative. |\n| `relationship_not_alternative` | `AW-PDF-RELATIONSHIP` | information | Data or Source, and BT-24 declares BASIC, EN 16931, EXTENDED or XRECHNUNG: Factur-X and France accept it, and for invoices in Germany the ZUGFeRD specification requires Alternative. |\n| `mime_not_xml` | `AW-PDF-MIME` | warning | A `/Subtype` that is not an XML media type. |\n| `mime_missing` | `AW-PDF-MIME` | warning | No `/Subtype`. |\n| `xmp_missing` | `AW-PDF-XMP` | warning | No XMP metadata. |\n| `xmp_unreadable` | `AW-PDF-XMP` | warning | Metadata that cannot be read: not a stream, a filter this reader lacks, a limit, not text, not well-formed, not XMP. |\n| `xmp_pdfa_missing` | `AW-PDF-XMP` | warning | No `pdfaid:part`: the file does not claim to be PDF/A. |\n| `xmp_pdfa_part` | `AW-PDF-XMP` | warning | A PDF/A part other than 3. |\n| `xmp_pdfa_conformance` | `AW-PDF-XMP` | warning | PDF/A-3 with no conformance level, or one other than A, B or U. |\n| `xmp_facturx_missing` | `AW-PDF-XMP` | warning | None of the Factur-X properties DocumentType, DocumentFileName, Version and ConformanceLevel. |\n| `xmp_facturx_incomplete` | `AW-PDF-XMP` | warning | Some of them, not all four. |\n| `xmp_facturx_namespace` | `AW-PDF-XMP` | warning | They are in a namespace none of the formats defines, where a reader that matches by namespace does not see them. |\n| `xmp_document_type` | `AW-PDF-XMP` | warning | A DocumentType other than INVOICE. |\n| `xmp_file_name` | `AW-PDF-XMP` | warning | A DocumentFileName that is not the attachment's name. |\n| `xmp_level_unknown` | `AW-PDF-XMP-PROFILE` | warning | A ConformanceLevel the metadata's schema does not define, with the spelling it probably meant. |\n| `xmp_level_mismatch` | `AW-PDF-XMP-PROFILE` | warning | A ConformanceLevel other than the profile BT-24 declares; its field is `BT-24`. |\n\nNone is fatal: each describes a file whose invoice was read, so `valid` never\nmoves for one, and whether another reader finds the invoice depends on how it\nlooks. A warning is a departure from what Factur-X, ZUGFeRD or PDF/A-3 asks of\nthe file, which some reader rejects or misreads (Mustang, the open-source\nZUGFeRD validator, reports most of the metadata ones as errors); information is\nallowed, and asked against only in some places. They carry the fields of every\n`AW-` finding (`rule`, `field`, `severity`, `message`, `fix`) and no\n`location`: a PDF key has no line, so the message names it, and the attachment\nby its name. On a PDF whose XML cannot be read, they come with the fatal\nfinding, and one of them may be why.\n\nThe metadata is read from the catalog's `/Metadata` stream, stored or\n`FlateDecode`d, with this package's own XML reader: a property written as an\nelement or as an attribute of its `rdf:Description`, inside `x:xmpmeta` or\nnot, in the namespace Factur-X defines (which ZUGFeRD uses from 2.1 on) or in\nZUGFeRD 2.0's or 1.0's. Metadata that cannot be read is a finding, never an\nexception.\n\n`relationship_not_alternative` and `xmp_level_mismatch` need the XML's BT-24.\n`validate()` adds them from the BT-24 it reads, so the XML is parsed once; if\nyou extract and parse the XML yourself, `facturXProfileFindings(extraction,\ncustomizationId)` returns them, and `facturXLevel(customizationId)` names the\nprofile a BT-24 declares, as the metadata spells it.\n\n**These are container checks, not a PDF/A verdict.** They read the claims a\nfile makes about itself (the PDF/A part and level it declares, the Factur-X\nproperties, where and how the XML is attached) and check them against the\nformats and against the XML. Whether the file is the PDF/A-3 it claims to be,\nwith its fonts embedded, its colour profile and the extension schema PDF/A\nrequires for the Factur-X properties, is a question for a PDF/A validator such\nas veraPDF, and nothing here answers it.\n\nWriting it is still not implemented, and is not planned here. `generateCii`\nemits the XML: it does not build the container, does not attach the XML under\nthe required name (`factur-x.xml`, or `xrechnung.xml` for the XRECHNUNG\nreference profile), and does not set the `/AFRelationship` value Germany\nrequires (`Alternative`). A file *produced* by this package is a CII XML\ndocument, not a Factur-X or ZUGFeRD document. The asymmetry is deliberate:\nextraction either returns the attachment or throws, while a half-conformant\nPDF/A-3 writer would emit files that look like Factur-X and are not.\n\n## Credit notes\n\nA credit note is one field:\n\n```ts\nconst creditNote = generateXRechnungUBL({\n  ...invoice,                     // the invoice you are crediting\n  invoiceNumber: \"2026-G00021\",   // its own number, from your own sequence\n  invoiceTypeCode: \"381\",         // ← this is the whole API\n  precedingInvoices: [{ invoiceNumber: \"2026-000142\", issueDate: \"2026-08-09\" }],\n});\n// → <ubl:CreditNote xmlns:ubl=\"…:xsd:CreditNote-2\"> … </ubl:CreditNote>\n```\n\nThere is no `generateCreditNote` and no `documentType` flag, because EN 16931\ndoes not have one: BT-3 *is* the discriminant, and a second field would let an\ninput contradict itself. `isCreditNote(input)` exposes the same decision if you\nneed to branch on it yourself.\n\n**State the amounts positively.** The document type conveys the direction of the\nmoney. A credit note carrying negative amounts reverses it back: that is a\n\"negative invoice\", a different (and equally lawful) idiom, and mixing the two\ngets you a document that says the opposite of what you meant. Both schematrons\naccept either, so no validator will catch it; `ATW-CREDIT-NOTE-NEGATIVE-AMOUNTS`\nis a warning here for exactly that reason.\n\nWhat changes in the emitted UBL, and nothing else does:\n\n| | `ubl:Invoice` | `ubl:CreditNote` |\n| --- | --- | --- |\n| Root / namespace | `Invoice`, `…:xsd:Invoice-2` | `CreditNote`, `…:xsd:CreditNote-2` |\n| BT-3 | `cbc:InvoiceTypeCode` | `cbc:CreditNoteTypeCode` |\n| Lines | `cac:InvoiceLine` | `cac:CreditNoteLine` |\n| BT-129 quantity | `cbc:InvoicedQuantity` | `cbc:CreditedQuantity` |\n| BT-9 due date | `cbc:DueDate` | `cac:PaymentMeans/cbc:PaymentDueDate` — the document has no `cbc:DueDate`, and `UBL-CR-412` exempts credit notes from the rule forbidding it here |\n| BT-7 tax point | after `cbc:Note` | before `cbc:CreditNoteTypeCode` |\n| BT-11 project | `cac:ProjectReference` | **no element exists** — dropped, and reported as `ATW-CREDIT-NOTE-PROJECT-REFERENCE-UNBOUND` |\n| BT-25 preceding invoice | `cac:BillingReference/cac:InvoiceDocumentReference` | the same element — EN 16931 binds BG-3 to the *invoice* reference on both documents |\n\nIn **CII** none of that applies: there is one root element for both document\ntypes, so a credit note is `ram:TypeCode` 381 and no other difference at all.\n\nThe rule set does not change either. EN 16931 has one semantic model and binds\nthe same rule ids to both documents, so BR-CO-10 counts the same amounts and\nBR-DE-16 asks the same question. Two rules are worth knowing about:\n\n- **BR-DE-17** admits `381`: XRechnung's eight codes are one list tested against\n  both type-code elements. `261` (self-billed credit note) is a lawful EN 16931\n  code and is *not* one of the eight, so it draws a warning there.\n- **BR-DE-26 does not require a preceding invoice reference on a credit note.**\n  It is widely believed to; the rule's own test names `384` (corrected invoice)\n  and nothing else, on either document type, and KoSIT accepts a credit note with\n  no BG-3 at all. Supplying one is still the ordinary case (the buyer cannot net\n  two documents that do not reference each other), so this build says so at\n  `information` level, the flag the regulator itself reserves for advice, under\n  `ATW-CREDIT-NOTE-NO-PRECEDING-INVOICE`.\n\n**Not covered:** self-billing as a *workflow*, and the UBL `SelfBilledInvoice` /\n`SelfBilledCreditNote` root elements. BT-3 `389` and `261` generate and parse on\nthe ordinary root elements, which is what EN 16931's UBL binding uses; if a\nplatform demands one of those other roots, this package will not produce it.\nDebit notes (`ubl:DebitNote`) are not supported either: EN 16931 has no binding\nfor them.\n\n## CII: XRechnung CII and the Factur-X payload\n\n```ts\nimport { generateCii, parseCiiInvoice } from \"@attestwire/en16931\";\n\nconst xml = generateCii({ ...invoice, profile: \"xrechnung-cii\" });\nconst { invoice: readBack, unmapped } = parseCiiInvoice(xml);\n```\n\n`generateCii` accepts `xrechnung-cii`, `facturx-en16931`, `en16931` and, since\n0.7.0, `peppol-bis-3`. The core profile is syntax-neutral, so you pick the\nsyntax by picking the function. `xrechnung-ubl` is the one profile name that is\ngenuinely UBL-bound, and it throws; `xrechnung-cii` is the name for the same\nrules in this syntax.\n\nEarlier releases refused `peppol-bis-3` here, on the stated grounds that Peppol\nBIS Billing 3.0 has no CII binding. **That was wrong.** OpenPEPPOL ships\n`PEPPOL-EN16931-CII.sch` and a `peppolbis-en16931-01-3.0-cii` build\nconfiguration, and the BIS describes CII D16B (the version this generator\nemits) as *optional*, not absent: UBL is mandatory for every receiver, and CII\nis accepted by receivers who register for it in the SMP. So sending\nPeppol CII is a thing you must agree with your counterparty, not a thing this\nlibrary should have been deciding for you. One behaviour change comes with it:\nunder `peppol-bis-3` the CII generator omits BT-21 (`ram:SubjectCode`), which\n`PEPPOL-EN16931-R002` forbids outright, and `validateInput` now raises `R002` as\na warning so you learn the rule instead of silently losing the field.\n\nCII is not UBL with different names, and four differences are where a UBL habit\nproduces a rejected file:\n\n| | UBL | CII |\n| --- | --- | --- |\n| Dates | `<cbc:IssueDate>2026-08-09</cbc:IssueDate>` | `<ram:IssueDateTime><udt:DateTimeString format=\"102\">20260809</udt:DateTimeString></ram:IssueDateTime>` |\n| Currency | on every amount, as `@currencyID` | once, in `ram:InvoiceCurrencyCode`; only BT-110 and BT-111 carry `@currencyID` |\n| BT-21 note subject | no element — encoded into the note as `#CODE#text` | a real element, `ram:SubjectCode` |\n| BT-90 SEPA creditor id | on the seller party, `schemeID=\"SEPA\"` | on the settlement, `ram:CreditorReferenceID` |\n\nElement order is part of schema validity in both syntaxes, and the two do not\nagree on it. `ram:PostalTradeAddress` puts the post code before the street.\n`ram:SpecifiedTradeSettlementHeaderMonetarySummation` puts charges before\nallowances and the rounding amount before the grand total. A\n`ram:SpecifiedTradeAllowanceCharge` puts the percentage and the base amount\nbefore the amount, and the reason **code** before the reason **text**. Every\nbuilder in `generate-cii.ts` quotes the XSD sequence it follows.\n\n`parseCiiInvoice` is the inverse, and the round trip is tested: for each\ncommitted CII fixture, `generateCii(parseCiiInvoice(xml).invoice)` returns the\nidentical document, and the result validates identically. It shares the hardened\nXML reader with `parseUbl`, including every one of its security limits, and\nresolves everything by namespace URI, not by prefix.\n\nOne thing it cannot tell you: **Factur-X's EN 16931 profile and plain core\nEN 16931 state the same BT-24** (`urn:cen.eu:en16931:2017`), so a\n`facturx-en16931` document reads back with `profile: \"en16931\"`. Nothing is\nlost: the rule set is identical and regenerating produces the same bytes. But if\nyou need the distinction, keep it yourself.\n\n## API\n\n| Export | Purpose |\n| --- | --- |\n| `validate(document, options?)` | An existing file — UBL or CII XML as a string or bytes, or a Factur-X / ZUGFeRD PDF as bytes — → `{ valid, syntax, profile, container, errors, warnings, information, invoice, unmapped, customizationId, profileId, error? }`. The same rules as `validateInput`, and each finding carries a `location` (`line`, `column`, `path`, `exact`) in the caller's file and an `xpath` in its own syntax. A PDF adds [the container's findings](#the-containers-findings) (`AW-PDF-*`, never fatal, no `location`). Options: `profile`, `limits`, `pdfLimits`. New in 0.10.0. |\n| `validateInput(inv)` | Run all input rules. Returns `{ valid, profile, errors, warnings, information }`. Reports **every** finding, not the first. Accepts `InvoiceFacts` too, and judges the explicit invoice `applyDefaults` makes of it. |\n| `generateXRechnungUBL(inv, options?)` | JSON → UBL 2.1 `Invoice` XML string — or `CreditNote`, when `invoiceTypeCode` is a credit-note code. Accepts `InvoiceFacts` too. |\n| `generateCii(inv, options?)` | JSON → UN/CEFACT CII (D16B) `CrossIndustryInvoice` XML string, for `xrechnung-cii`, `facturx-en16931`, `en16931` and `peppol-bis-3`. **XML only — this function never writes a PDF.** Accepts `InvoiceFacts` too. |\n| `applyDefaults(facts)` | `InvoiceFacts` → `{ invoice, notes }`: the explicit `InvoiceInput`, with every `vatScenario` turned into its codes and a missing payment means code inferred from the account, and one `information` note per thing filled in. What `validateInput` and the generators apply first. New in 0.14.0; see [Say what happened, not the code](#say-what-happened-not-the-code). |\n| `applyVatScenarios(facts)` / `VAT_SCENARIOS` | The VAT half of `applyDefaults` on its own, and the five scenario names. |\n| `createCreditNote(original, options)` | An invoice → its credit note: BT-3 381, the reference to the original (BT-25, BT-26), the same parties, currency and payment details, and the lines you choose with their positive amounts. Options: `invoiceNumber`, `issueDate`, `lines`, `reason`. New in 0.14.0. |\n| `extractFacturX(bytes, limits?)` | Factur-X / ZUGFeRD PDF → `{ xml, attachmentName, warnings, findings, relationship?, xmp }`. Reads the embedded-file name tree and the `/AF` array, classic and stream cross-references, object streams and the XMP metadata. `findings` are [the container's findings](#the-containers-findings) that the PDF alone decides, each with a stable `id`; `xmp` is what the metadata states. Extraction only: the container is read, never built. |\n| `facturXProfileFindings(extraction, customizationId)` / `facturXLevel(customizationId)` | The container findings that need the XML's BT-24 (the metadata's profile against BT-24's; Data or Source where Germany asks Alternative), for a caller who parses the XML itself; `validate` adds them already. `facturXLevel` names the profile a BT-24 declares as the XMP metadata spells it (`EN 16931`, `BASIC WL`), or `undefined`. |\n| `toSarif(findings, provenance)` / `toJunitXml(findings, provenance, options?)` | Findings → a SARIF 2.1.0 log object, or a JUnit XML string, for CI. Pure: no clock, no filesystem. |\n| `parseCiiInvoice(xml, options?)` | CII XML → `{ invoice, unmapped, customizationId, profileId }`, the same shape `parseUbl` returns. Reads invoices and credit notes alike — in CII they are one document type. |\n| `CII_GENERATABLE_PROFILES` / type `CiiGeneratableProfile` | The profiles `generateCii` accepts, and the union type of them. |\n| `CII_NAMESPACES` | The four namespace URIs (`rsm`, `ram`, `qdt`, `udt`) a CII invoice uses — for resolving by URI when you walk a document yourself. |\n| `toCiiDate(iso)` / `fromCiiDate(value)` | ISO 8601 ↔ the CII `format=\"102\"` form (`YYYYMMDD`). A value that is not a calendar date passes through untouched rather than being rewritten. |\n| `SUPPORTING_DOCUMENT_TYPE_CODE` / `TENDER_OR_LOT_DOCUMENT_TYPE_CODE` | `\"916\"` and `\"50\"`. In CII one element, `ram:AdditionalReferencedDocument`, carries BG-24, BT-17 **and** BT-18, told apart only by these codes and by `INVOICED_OBJECT_DOCUMENT_TYPE_CODE` (`\"130\"`). |\n| `parseUbl(xml, options?)` | UBL 2.1 `Invoice` **or `CreditNote`** XML → `{ invoice, unmapped, customizationId, profileId }`. Feed `invoice` to `validateInput`. See [Reading an existing UBL invoice](#reading-an-existing-ubl-invoice). |\n| `parseUblInvoice(xml, options?)` | The same function under its pre-0.5.0 name. Kept forever; `parseUbl` is the name to use in new code, since it reads both document types. |\n| `ParseError` and subclasses | What parsing throws instead of returning a half-read invoice: `UnsupportedSyntaxError`, `UnsupportedCreditNoteError`, `XmlSecurityError`, `XmlSyntaxError`. Each carries a stable `code`. |\n| `DEFAULT_XML_LIMITS` / type `XmlLimits` | The size, depth and element caps applied to every","readmeFilename":"README.md"}