@stackforge-eu/factur-x 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +287 -0
  3. package/README.md +264 -0
  4. package/dist/index.cjs +1320 -0
  5. package/dist/index.d.cts +1336 -0
  6. package/dist/index.d.ts +1336 -0
  7. package/dist/index.js +1285 -0
  8. package/package.json +81 -0
  9. package/schema/README.md +39 -0
  10. package/schema/basic/FACTUR-X_BASIC.xsd +20 -0
  11. package/schema/basic/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd +86 -0
  12. package/schema/basic/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +249 -0
  13. package/schema/basic/FACTUR-X_BASIC_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd +60 -0
  14. package/schema/basic-wl/FACTUR-X_BASIC-WL.xsd +20 -0
  15. package/schema/basic-wl/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd +86 -0
  16. package/schema/basic-wl/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +196 -0
  17. package/schema/basic-wl/FACTUR-X_BASIC-WL_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd +53 -0
  18. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B.xsd +25 -0
  19. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_EDIFICAS-EU_AccountingAccountType_D11A.xsd +18 -0
  20. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_EDIFICAS-EU_AccountingAmountType_D11A.xsd +17 -0
  21. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_ISO_ISO3AlphaCurrencyCode_2012-08-31.xsd +191 -0
  22. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_ActionCode_D22A.xsd +130 -0
  23. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_AddressType_D22A.xsd +19 -0
  24. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_AdjustmentReasonDescriptionCode_D22A.xsd +116 -0
  25. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_AllowanceChargeIdentificationCode_D22A.xsd +116 -0
  26. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_AllowanceChargeReasonCode_D22A.xsd +116 -0
  27. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_AutomaticDataCaptureMethodCode_D22A.xsd +21 -0
  28. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_CargoOperationalCategoryCode_D22A.xsd +36 -0
  29. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_CargoTypeCode_1996Rev2Final.xsd +20 -0
  30. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_CommodityIdentificationCode_D22A.xsd +12 -0
  31. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_CommunicationMeansTypeCode_D22A.xsd +58 -0
  32. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_ContactFunctionCode_D22A.xsd +114 -0
  33. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DangerousGoodsPackingCode_D22A.xsd +15 -0
  34. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DangerousGoodsRegulationCode_D22A.xsd +35 -0
  35. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DateOnlyFormatCode_D21B.xsd +21 -0
  36. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DeliveryTermsCode_2020.xsd +24 -0
  37. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DeliveryTermsFunctionCode_D22A.xsd +19 -0
  38. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DimensionTypeCode_D22A.xsd +35 -0
  39. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DocumentNameCode_Accounting_D22A.xsd +35 -0
  40. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DocumentNameCode_D22A.xsd +819 -0
  41. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DocumentStatusCode_D22A.xsd +61 -0
  42. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DutyTaxFeeTypeCode_D22A.xsd +67 -0
  43. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_DutyorTaxorFeeCategoryCode_D22A.xsd +33 -0
  44. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_EventTimeReferenceCodePaymentTermsEvent_D22A.xsd +16 -0
  45. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_EventTimeReferenceCode_D22A.xsd +76 -0
  46. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_FreightChargeQuantityUnitBasisCode_D22A.xsd +12 -0
  47. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_FreightChargeTariffCode_D22A.xsd +25 -0
  48. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_GoodsTypeCode_D22A.xsd +12 -0
  49. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_GoodsTypeExtensionCode_D22A.xsd +12 -0
  50. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_LocationFunctionCode_D22A.xsd +326 -0
  51. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_MeasurementUnitCommonCodeLinear_4.xsd +17 -0
  52. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_MeasurementUnitCommonCodeVolume_4.xsd +18 -0
  53. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_MeasurementUnitCommonCodeWeight_4.xsd +15 -0
  54. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_MessageFunctionCode_D22A.xsd +84 -0
  55. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PackageTypeCode_2006.xsd +416 -0
  56. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PackagingMarkingCode_D22A.xsd +63 -0
  57. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PartyRoleCode_ChargePaying_D22A.xsd +32 -0
  58. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PartyRoleCode_D22A.xsd +635 -0
  59. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PaymentGuaranteeMeansCode_D22A.xsd +23 -0
  60. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PaymentMeansChannelCode_D22A.xsd +27 -0
  61. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PaymentMeansCode_D22A.xsd +94 -0
  62. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PaymentTermsTypeCode_D22A.xsd +90 -0
  63. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_PriceTypeCode_D22A.xsd +50 -0
  64. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_ReferenceTypeCode_D22A.xsd +828 -0
  65. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_SealConditionCode_D22A.xsd +16 -0
  66. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_SealingPartyRoleCode_D22A.xsd +18 -0
  67. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_StatusCode_D22A.xsd +527 -0
  68. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_StatusDescriptionCode_AccountingDebitCredit_D22A.xsd +18 -0
  69. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TimeOnlyFormatCode_D21B.xsd +16 -0
  70. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TimePointFormatCode_D21B.xsd +17 -0
  71. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TransportEquipmentCategoryCode_D22A.xsd +107 -0
  72. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TransportEquipmentFullnessCode_D22A.xsd +24 -0
  73. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TransportMeansTypeCode_2007.xsd +145 -0
  74. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TransportModeCode_2.xsd +21 -0
  75. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TransportMovementStageCode_D22A.xsd +41 -0
  76. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_codelist_standard_UNECE_TransportPaymentArrangementCode_D22A.xsd +15 -0
  77. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd +818 -0
  78. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +6176 -0
  79. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd +144 -0
  80. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_identifierlist_standard_ISO_ISOTwo-letterCountryCode_SecondEdition2006.xsd +260 -0
  81. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_identifierlist_standard_UNECE_FreightCostCode_4.xsd +1722 -0
  82. package/schema/cii-d22b/CrossIndustryInvoice_100pD22B_urn_un_unece_uncefact_identifierlist_standard_UNECE_PaymentTermsDescriptionIdentifier_D22A.xsd +18 -0
  83. package/schema/en16931/FACTUR-X_EN16931.xsd +20 -0
  84. package/schema/en16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd +94 -0
  85. package/schema/en16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +318 -0
  86. package/schema/en16931/FACTUR-X_EN16931_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd +84 -0
  87. package/schema/extended/FACTUR-X_EXTENDED.xsd +20 -0
  88. package/schema/extended/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd +142 -0
  89. package/schema/extended/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +475 -0
  90. package/schema/extended/FACTUR-X_EXTENDED_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd +101 -0
  91. package/schema/minimum/FACTUR-X_MINIMUM.xsd +20 -0
  92. package/schema/minimum/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_QualifiedDataType_100.xsd +30 -0
  93. package/schema/minimum/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_ReusableAggregateBusinessInformationEntity_100.xsd +86 -0
  94. package/schema/minimum/FACTUR-X_MINIMUM_urn_un_unece_uncefact_data_standard_UnqualifiedDataType_100.xsd +38 -0
package/dist/index.js ADDED
@@ -0,0 +1,1285 @@
1
+ import * as path2 from 'path';
2
+ import path2__default from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import * as fs from 'fs';
5
+ import { AFRelationship, PDFDocument, PDFName, PDFDict, PDFStream, PDFRawStream, decodePDFRawStream, PDFArray, PDFRef, PDFString, PDFHexString } from 'pdf-lib';
6
+
7
+ // node_modules/tsup/assets/esm_shims.js
8
+ var getFilename = () => fileURLToPath(import.meta.url);
9
+ var getDirname = () => path2__default.dirname(getFilename());
10
+ var __dirname$1 = /* @__PURE__ */ getDirname();
11
+
12
+ // src/types/input.ts
13
+ var DocumentTypeCode = /* @__PURE__ */ ((DocumentTypeCode2) => {
14
+ DocumentTypeCode2["REQUEST_FOR_PAYMENT"] = "71";
15
+ DocumentTypeCode2["DEBIT_NOTE_GOODS_SERVICES"] = "80";
16
+ DocumentTypeCode2["CREDIT_NOTE_GOODS_SERVICES"] = "81";
17
+ DocumentTypeCode2["METERED_SERVICES_INVOICE"] = "82";
18
+ DocumentTypeCode2["CREDIT_NOTE_FINANCIAL_ADJUSTMENTS"] = "83";
19
+ DocumentTypeCode2["DEBIT_NOTE_FINANCIAL_ADJUSTMENTS"] = "84";
20
+ DocumentTypeCode2["TAX_NOTIFICATION"] = "102";
21
+ DocumentTypeCode2["INVOICING_DATA_SHEET"] = "130";
22
+ DocumentTypeCode2["DIRECT_PAYMENT_VALUATION"] = "202";
23
+ DocumentTypeCode2["PROVISIONAL_PAYMENT_VALUATION"] = "203";
24
+ DocumentTypeCode2["PAYMENT_VALUATION"] = "204";
25
+ DocumentTypeCode2["INTERIM_APPLICATION_FOR_PAYMENT"] = "211";
26
+ DocumentTypeCode2["FINAL_PAYMENT_REQUEST"] = "218";
27
+ DocumentTypeCode2["PAYMENT_REQUEST_COMPLETED_UNITS"] = "219";
28
+ DocumentTypeCode2["SELF_BILLED_CREDIT_NOTE"] = "261";
29
+ DocumentTypeCode2["CONSOLIDATED_CREDIT_NOTE"] = "262";
30
+ DocumentTypeCode2["PRICE_VARIATION_INVOICE"] = "295";
31
+ DocumentTypeCode2["CREDIT_NOTE_PRICE_VARIATION"] = "296";
32
+ DocumentTypeCode2["DELCREDERE_CREDIT_NOTE"] = "308";
33
+ DocumentTypeCode2["PROFORMA_INVOICE"] = "325";
34
+ DocumentTypeCode2["PARTIAL_INVOICE"] = "326";
35
+ DocumentTypeCode2["COMMERCIAL_INVOICE_PACKING_LIST"] = "331";
36
+ DocumentTypeCode2["COMMERCIAL_INVOICE"] = "380";
37
+ DocumentTypeCode2["CREDIT_NOTE"] = "381";
38
+ DocumentTypeCode2["COMMISSION_NOTE"] = "382";
39
+ DocumentTypeCode2["DEBIT_NOTE"] = "383";
40
+ DocumentTypeCode2["CORRECTED_INVOICE"] = "384";
41
+ DocumentTypeCode2["CONSOLIDATED_INVOICE"] = "385";
42
+ DocumentTypeCode2["PREPAYMENT_INVOICE"] = "386";
43
+ DocumentTypeCode2["HIRE_INVOICE"] = "387";
44
+ DocumentTypeCode2["TAX_INVOICE"] = "388";
45
+ DocumentTypeCode2["SELF_BILLED_INVOICE"] = "389";
46
+ DocumentTypeCode2["DELCREDERE_INVOICE"] = "390";
47
+ DocumentTypeCode2["FACTORED_INVOICE"] = "393";
48
+ DocumentTypeCode2["LEASE_INVOICE"] = "394";
49
+ DocumentTypeCode2["CONSIGNMENT_INVOICE"] = "395";
50
+ DocumentTypeCode2["FACTORED_CREDIT_NOTE"] = "396";
51
+ DocumentTypeCode2["OCR_PAYMENT_CREDIT_NOTE"] = "420";
52
+ DocumentTypeCode2["DEBIT_ADVICE"] = "456";
53
+ DocumentTypeCode2["REVERSAL_OF_DEBIT"] = "457";
54
+ DocumentTypeCode2["REVERSAL_OF_CREDIT"] = "458";
55
+ DocumentTypeCode2["SELF_BILLED_CORRECTIVE_INVOICE"] = "471";
56
+ DocumentTypeCode2["FACTORED_CORRECTIVE_INVOICE"] = "472";
57
+ DocumentTypeCode2["SELF_BILLED_FACTORED_CORRECTIVE_INVOICE"] = "473";
58
+ DocumentTypeCode2["SELF_BILLED_PREPAYMENT_INVOICE"] = "500";
59
+ DocumentTypeCode2["SELF_BILLED_FACTORED_INVOICE"] = "501";
60
+ DocumentTypeCode2["SELF_BILLED_FACTORED_CREDIT_NOTE"] = "502";
61
+ DocumentTypeCode2["PREPAYMENT_CREDIT_NOTE"] = "503";
62
+ DocumentTypeCode2["SELF_BILLED_DEBIT_NOTE"] = "527";
63
+ DocumentTypeCode2["FORWARDERS_CREDIT_NOTE"] = "532";
64
+ DocumentTypeCode2["FORWARDERS_INVOICE_DISCREPANCY_REPORT"] = "553";
65
+ DocumentTypeCode2["INSURERS_INVOICE"] = "575";
66
+ DocumentTypeCode2["FORWARDERS_INVOICE"] = "623";
67
+ DocumentTypeCode2["PORT_CHARGES_DOCUMENTS"] = "633";
68
+ DocumentTypeCode2["INVOICE_INFO_ACCOUNTING"] = "751";
69
+ DocumentTypeCode2["FREIGHT_INVOICE"] = "780";
70
+ DocumentTypeCode2["CLAIM_NOTIFICATION"] = "817";
71
+ DocumentTypeCode2["CONSULAR_INVOICE"] = "870";
72
+ DocumentTypeCode2["PARTIAL_CONSTRUCTION_INVOICE"] = "875";
73
+ DocumentTypeCode2["PARTIAL_FINAL_CONSTRUCTION_INVOICE"] = "876";
74
+ DocumentTypeCode2["FINAL_CONSTRUCTION_INVOICE"] = "877";
75
+ return DocumentTypeCode2;
76
+ })(DocumentTypeCode || {});
77
+ var UnitCode = /* @__PURE__ */ ((UnitCode2) => {
78
+ UnitCode2["UNIT"] = "C62";
79
+ UnitCode2["EACH"] = "EA";
80
+ UnitCode2["PIECE"] = "H87";
81
+ UnitCode2["NUMBER_OF_ARTICLES"] = "NAR";
82
+ UnitCode2["PAIR"] = "PR";
83
+ UnitCode2["SET"] = "SET";
84
+ UnitCode2["DOZEN"] = "DZN";
85
+ UnitCode2["LOT"] = "LOT";
86
+ UnitCode2["HUNDRED"] = "CEN";
87
+ UnitCode2["THOUSAND"] = "MIL";
88
+ UnitCode2["MINUTE"] = "MIN";
89
+ UnitCode2["HOUR"] = "HUR";
90
+ UnitCode2["DAY"] = "DAY";
91
+ UnitCode2["WEEK"] = "WEE";
92
+ UnitCode2["MONTH"] = "MON";
93
+ UnitCode2["YEAR"] = "ANN";
94
+ UnitCode2["GRAM"] = "GRM";
95
+ UnitCode2["KILOGRAM"] = "KGM";
96
+ UnitCode2["TONNE"] = "TNE";
97
+ UnitCode2["MILLIMETRE"] = "MMT";
98
+ UnitCode2["CENTIMETRE"] = "CMT";
99
+ UnitCode2["METRE"] = "MTR";
100
+ UnitCode2["KILOMETRE"] = "KMT";
101
+ UnitCode2["SQUARE_METRE"] = "MTK";
102
+ UnitCode2["MILLILITRE"] = "MLT";
103
+ UnitCode2["LITRE"] = "LTR";
104
+ UnitCode2["CUBIC_METRE"] = "MTQ";
105
+ UnitCode2["KILOWATT_HOUR"] = "KWH";
106
+ UnitCode2["MEGAWATT_HOUR"] = "MWH";
107
+ UnitCode2["PACKAGE"] = "XPK";
108
+ UnitCode2["PALLET"] = "XPX";
109
+ UnitCode2["BOX"] = "XBX";
110
+ UnitCode2["CARTON"] = "XCT";
111
+ UnitCode2["BYTE"] = "AD";
112
+ UnitCode2["KILOBYTE"] = "2P";
113
+ UnitCode2["MEGABYTE"] = "4L";
114
+ UnitCode2["GIGABYTE"] = "E34";
115
+ UnitCode2["TERABYTE"] = "E35";
116
+ UnitCode2["PETABYTE"] = "E36";
117
+ UnitCode2["BYTE_PER_SECOND"] = "P93";
118
+ UnitCode2["KILOBYTE_PER_SECOND"] = "P94";
119
+ UnitCode2["LUMP_SUM"] = "LS";
120
+ UnitCode2["PERCENT"] = "P1";
121
+ UnitCode2["SHEET"] = "ST";
122
+ UnitCode2["ROLL"] = "RO";
123
+ return UnitCode2;
124
+ })(UnitCode || {});
125
+
126
+ // src/flavors/constants.ts
127
+ var Profile = /* @__PURE__ */ ((Profile2) => {
128
+ Profile2["MINIMUM"] = "MINIMUM";
129
+ Profile2["BASIC_WL"] = "BASIC_WL";
130
+ Profile2["BASIC"] = "BASIC";
131
+ Profile2["EN16931"] = "EN16931";
132
+ Profile2["EXTENDED"] = "EXTENDED";
133
+ return Profile2;
134
+ })(Profile || {});
135
+ var Flavor = /* @__PURE__ */ ((Flavor2) => {
136
+ Flavor2["FACTUR_X"] = "factur-x";
137
+ Flavor2["ZUGFERD"] = "zugferd";
138
+ Flavor2["XRECHNUNG"] = "xrechnung";
139
+ Flavor2["CHRONO_PRO"] = "chrono-pro";
140
+ return Flavor2;
141
+ })(Flavor || {});
142
+ var PROFILE_URNS = {
143
+ MINIMUM: "urn:factur-x.eu:1p0:minimum",
144
+ BASIC_WL: "urn:factur-x.eu:1p0:basicwl",
145
+ BASIC: "urn:factur-x.eu:1p0:basic",
146
+ EN16931: "urn:factur-x.eu:1p0:en16931",
147
+ EXTENDED: "urn:factur-x.eu:1p0:extended"
148
+ };
149
+ var FLAVOR_DEFAULT_TYPE_CODES = {
150
+ ["factur-x" /* FACTUR_X */]: "380" /* COMMERCIAL_INVOICE */,
151
+ ["zugferd" /* ZUGFERD */]: "380" /* COMMERCIAL_INVOICE */,
152
+ ["xrechnung" /* XRECHNUNG */]: "380" /* COMMERCIAL_INVOICE */,
153
+ ["chrono-pro" /* CHRONO_PRO */]: "380" /* COMMERCIAL_INVOICE */
154
+ };
155
+ var PROFILE_SCHEMA_DIRS = {
156
+ MINIMUM: "minimum",
157
+ BASIC_WL: "basic-wl",
158
+ BASIC: "basic",
159
+ EN16931: "en16931",
160
+ EXTENDED: "extended"
161
+ };
162
+ var PROFILE_MAIN_XSD = {
163
+ MINIMUM: "FACTUR-X_MINIMUM.xsd",
164
+ BASIC_WL: "FACTUR-X_BASIC-WL.xsd",
165
+ BASIC: "FACTUR-X_BASIC.xsd",
166
+ EN16931: "FACTUR-X_EN16931.xsd",
167
+ EXTENDED: "FACTUR-X_EXTENDED.xsd"
168
+ };
169
+
170
+ // src/flavors/registry.ts
171
+ var ALL_PROFILES = [
172
+ "MINIMUM" /* MINIMUM */,
173
+ "BASIC_WL" /* BASIC_WL */,
174
+ "BASIC" /* BASIC */,
175
+ "EN16931" /* EN16931 */,
176
+ "EXTENDED" /* EXTENDED */
177
+ ];
178
+ var CHRONO_PRO_PROFILES = [
179
+ "MINIMUM" /* MINIMUM */,
180
+ "BASIC_WL" /* BASIC_WL */,
181
+ "BASIC" /* BASIC */,
182
+ "EN16931" /* EN16931 */
183
+ ];
184
+ var FLAVOR_CONFIGS = {
185
+ ["factur-x" /* FACTUR_X */]: {
186
+ name: "Factur-X",
187
+ supportedProfiles: ALL_PROFILES,
188
+ defaultTypeCode: "380" /* COMMERCIAL_INVOICE */,
189
+ attachmentFilename: "factur-x.xml",
190
+ embedInPdf: true,
191
+ description: "French/German hybrid invoice format based on EN 16931."
192
+ },
193
+ ["zugferd" /* ZUGFERD */]: {
194
+ name: "ZUGFeRD",
195
+ supportedProfiles: ALL_PROFILES,
196
+ defaultTypeCode: "380" /* COMMERCIAL_INVOICE */,
197
+ attachmentFilename: "factur-x.xml",
198
+ embedInPdf: true,
199
+ description: "German electronic invoice format. ZUGFeRD 2.4 uses factur-x.xml."
200
+ },
201
+ ["xrechnung" /* XRECHNUNG */]: {
202
+ name: "XRechnung",
203
+ supportedProfiles: ["EN16931" /* EN16931 */],
204
+ defaultTypeCode: "380" /* COMMERCIAL_INVOICE */,
205
+ businessProcessUrn: "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
206
+ attachmentFilename: "xrechnung.xml",
207
+ embedInPdf: false,
208
+ description: "German government invoice format. XML only, no PDF embedding."
209
+ },
210
+ ["chrono-pro" /* CHRONO_PRO */]: {
211
+ name: "Chrono Pro",
212
+ supportedProfiles: CHRONO_PRO_PROFILES,
213
+ defaultTypeCode: "380" /* COMMERCIAL_INVOICE */,
214
+ attachmentFilename: "factur-x.xml",
215
+ embedInPdf: true,
216
+ description: "Belgian e-invoicing solution using Factur-X subset."
217
+ }
218
+ };
219
+ function getFlavorConfig(flavor) {
220
+ return FLAVOR_CONFIGS[flavor];
221
+ }
222
+ function validateFlavorProfile(flavor, profile) {
223
+ const config = FLAVOR_CONFIGS[flavor];
224
+ if (!config.supportedProfiles.includes(profile)) {
225
+ throw new Error(
226
+ `Profile "${profile}" is not supported for flavor "${flavor}". Supported: ${config.supportedProfiles.join(", ")}.`
227
+ );
228
+ }
229
+ }
230
+ function resolveTypeCode(input, flavor) {
231
+ const inputTypeCode = input.document?.typeCode;
232
+ if (inputTypeCode) {
233
+ return inputTypeCode;
234
+ }
235
+ return FLAVOR_CONFIGS[flavor].defaultTypeCode;
236
+ }
237
+ function resolveBusinessProcessUrn(input, flavor) {
238
+ const inputBusinessProcessId = input.document?.businessProcessId;
239
+ if (inputBusinessProcessId) {
240
+ return inputBusinessProcessId;
241
+ }
242
+ return FLAVOR_CONFIGS[flavor].businessProcessUrn;
243
+ }
244
+
245
+ // src/core/xml-builder.ts
246
+ var PROFILE_LEVEL = {
247
+ MINIMUM: 0,
248
+ BASIC_WL: 1,
249
+ BASIC: 2,
250
+ EN16931: 3,
251
+ EXTENDED: 4
252
+ };
253
+ function atLeast(current, minimum) {
254
+ return PROFILE_LEVEL[current] >= PROFILE_LEVEL[minimum];
255
+ }
256
+ function escapeXml(value) {
257
+ return value.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
258
+ }
259
+ function formatDate(isoDate) {
260
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(isoDate)) {
261
+ throw new Error(`Invalid date format "${isoDate}": expected YYYY-MM-DD (e.g. "2025-03-15").`);
262
+ }
263
+ return isoDate.replace(/-/g, "");
264
+ }
265
+ function fmtAmt(n) {
266
+ if (!Number.isFinite(n)) {
267
+ throw new Error(`Invalid amount value: ${n}. Expected a finite number.`);
268
+ }
269
+ return n.toFixed(2);
270
+ }
271
+ function tag(name, content, attrs) {
272
+ const a = attrs ? Object.entries(attrs).map(([k, v]) => ` ${k}="${escapeXml(v)}"`).join("") : "";
273
+ return `<${name}${a}>${content}</${name}>`;
274
+ }
275
+ function dateEl(wrapper, isoDate) {
276
+ return tag(wrapper, tag("udt:DateTimeString", formatDate(isoDate), { format: "102" }));
277
+ }
278
+ function buildAddress(addr) {
279
+ let x = "";
280
+ if (addr.postalCode) x += tag("ram:PostcodeCode", escapeXml(addr.postalCode));
281
+ x += tag("ram:LineOne", escapeXml(addr.line1));
282
+ if (addr.line2) x += tag("ram:LineTwo", escapeXml(addr.line2));
283
+ if (addr.line3) x += tag("ram:LineThree", escapeXml(addr.line3));
284
+ x += tag("ram:CityName", escapeXml(addr.city));
285
+ x += tag("ram:CountryID", escapeXml(addr.country));
286
+ if (addr.subdivision) x += tag("ram:CountrySubDivisionName", escapeXml(addr.subdivision));
287
+ return tag("ram:PostalTradeAddress", x);
288
+ }
289
+ function buildContact(c) {
290
+ let x = "";
291
+ if (c.name) x += tag("ram:PersonName", escapeXml(c.name));
292
+ if (c.department) x += tag("ram:DepartmentName", escapeXml(c.department));
293
+ if (c.phone)
294
+ x += tag("ram:TelephoneUniversalCommunication", tag("ram:CompleteNumber", escapeXml(c.phone)));
295
+ if (c.email) x += tag("ram:EmailURIUniversalCommunication", tag("ram:URIID", escapeXml(c.email)));
296
+ return tag("ram:DefinedTradeContact", x);
297
+ }
298
+ function buildParty(p, profile) {
299
+ let x = "";
300
+ if (p.id) {
301
+ const ids = Array.isArray(p.id) ? p.id : [p.id];
302
+ for (const id of ids) x += tag("ram:ID", escapeXml(id));
303
+ }
304
+ if (p.globalId) x += tag("ram:GlobalID", escapeXml(p.globalId));
305
+ x += tag("ram:Name", escapeXml(p.name));
306
+ if (p.description && atLeast(profile, "EN16931" /* EN16931 */))
307
+ x += tag("ram:Description", escapeXml(p.description));
308
+ if (p.legalOrganization) {
309
+ let lo = "";
310
+ if (p.legalOrganization.id) lo += tag("ram:ID", escapeXml(p.legalOrganization.id));
311
+ if (p.legalOrganization.tradingName)
312
+ lo += tag("ram:TradingBusinessName", escapeXml(p.legalOrganization.tradingName));
313
+ x += tag("ram:SpecifiedLegalOrganization", lo);
314
+ }
315
+ if (p.contact && atLeast(profile, "EN16931" /* EN16931 */)) x += buildContact(p.contact);
316
+ if (p.address && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) x += buildAddress(p.address);
317
+ if (p.electronicAddress)
318
+ x += tag("ram:URIUniversalCommunication", tag("ram:URIID", escapeXml(p.electronicAddress)));
319
+ if (p.taxRegistrations) {
320
+ for (const tr of p.taxRegistrations) {
321
+ x += tag(
322
+ "ram:SpecifiedTaxRegistration",
323
+ tag("ram:ID", escapeXml(tr.id), { schemeID: tr.schemeId ?? "VA" })
324
+ );
325
+ }
326
+ }
327
+ return x;
328
+ }
329
+ function buildLineItem(line, profile) {
330
+ let doc = tag("ram:LineID", escapeXml(line.id));
331
+ if (line.note) doc += tag("ram:IncludedNote", tag("ram:Content", escapeXml(line.note)));
332
+ let prod = "";
333
+ if (line.standardIdentifier) prod += tag("ram:GlobalID", escapeXml(line.standardIdentifier));
334
+ if (line.sellerAssignedId) prod += tag("ram:SellerAssignedID", escapeXml(line.sellerAssignedId));
335
+ if (line.buyerAssignedId) prod += tag("ram:BuyerAssignedID", escapeXml(line.buyerAssignedId));
336
+ prod += tag("ram:Name", escapeXml(line.name));
337
+ if (line.description) prod += tag("ram:Description", escapeXml(line.description));
338
+ if (line.originCountry && atLeast(profile, "EN16931" /* EN16931 */))
339
+ prod += tag("ram:OriginTradeCountry", tag("ram:ID", escapeXml(line.originCountry)));
340
+ let agree = "";
341
+ if (line.buyerOrderLineId && atLeast(profile, "EN16931" /* EN16931 */))
342
+ agree += tag(
343
+ "ram:BuyerOrderReferencedDocument",
344
+ tag("ram:LineID", escapeXml(line.buyerOrderLineId))
345
+ );
346
+ if (line.grossUnitPrice !== void 0)
347
+ agree += tag(
348
+ "ram:GrossPriceProductTradePrice",
349
+ tag("ram:ChargeAmount", fmtAmt(line.grossUnitPrice))
350
+ );
351
+ agree += tag("ram:NetPriceProductTradePrice", tag("ram:ChargeAmount", fmtAmt(line.unitPrice)));
352
+ const unitCode = line.unitCode ?? "C62" /* UNIT */;
353
+ const delivery = tag("ram:BilledQuantity", line.quantity.toString(), {
354
+ unitCode
355
+ });
356
+ let settle = "";
357
+ if (line.vatCategoryCode || line.vatRatePercent !== void 0) {
358
+ let tx = tag("ram:TypeCode", "VAT");
359
+ if (line.vatCategoryCode) tx += tag("ram:CategoryCode", escapeXml(line.vatCategoryCode));
360
+ if (line.vatRatePercent !== void 0)
361
+ tx += tag("ram:RateApplicablePercent", line.vatRatePercent.toString());
362
+ settle += tag("ram:ApplicableTradeTax", tx);
363
+ }
364
+ const lineTotal = line.lineTotal ?? line.quantity * line.unitPrice;
365
+ settle += tag(
366
+ "ram:SpecifiedTradeSettlementLineMonetarySummation",
367
+ tag("ram:LineTotalAmount", fmtAmt(lineTotal))
368
+ );
369
+ return tag(
370
+ "ram:IncludedSupplyChainTradeLineItem",
371
+ tag("ram:AssociatedDocumentLineDocument", doc) + tag("ram:SpecifiedTradeProduct", prod) + tag("ram:SpecifiedLineTradeAgreement", agree) + tag("ram:SpecifiedLineTradeDelivery", delivery) + tag("ram:SpecifiedLineTradeSettlement", settle)
372
+ );
373
+ }
374
+ function buildAllowanceCharge(ac) {
375
+ let x = tag("ram:ChargeIndicator", tag("ram:Indicator", ac.isCharge ? "true" : "false"));
376
+ if (ac.percent !== void 0) x += tag("ram:CalculationPercent", ac.percent.toString());
377
+ if (ac.baseAmount !== void 0) x += tag("ram:BasisAmount", fmtAmt(ac.baseAmount));
378
+ x += tag("ram:ActualAmount", fmtAmt(ac.amount));
379
+ if (ac.reasonCode) x += tag("ram:ReasonCode", escapeXml(ac.reasonCode));
380
+ if (ac.reason) x += tag("ram:Reason", escapeXml(ac.reason));
381
+ if (ac.vatCategoryCode || ac.vatRatePercent !== void 0) {
382
+ let tx = tag("ram:TypeCode", "VAT");
383
+ if (ac.vatCategoryCode) tx += tag("ram:CategoryCode", escapeXml(ac.vatCategoryCode));
384
+ if (ac.vatRatePercent !== void 0)
385
+ tx += tag("ram:RateApplicablePercent", ac.vatRatePercent.toString());
386
+ x += tag("ram:CategoryTradeTax", tx);
387
+ }
388
+ return tag("ram:SpecifiedTradeAllowanceCharge", x);
389
+ }
390
+ function buildVatBreakdown(vb) {
391
+ let x = tag("ram:CalculatedAmount", fmtAmt(vb.taxAmount));
392
+ x += tag("ram:TypeCode", "VAT");
393
+ if (vb.exemptionReason) x += tag("ram:ExemptionReason", escapeXml(vb.exemptionReason));
394
+ x += tag("ram:BasisAmount", fmtAmt(vb.taxableAmount));
395
+ x += tag("ram:CategoryCode", escapeXml(vb.categoryCode));
396
+ if (vb.exemptionReasonCode)
397
+ x += tag("ram:ExemptionReasonCode", escapeXml(vb.exemptionReasonCode));
398
+ x += tag("ram:RateApplicablePercent", vb.ratePercent.toString());
399
+ return tag("ram:ApplicableTradeTax", x);
400
+ }
401
+ function buildMonetarySummation(t, profile) {
402
+ let x = "";
403
+ if (atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
404
+ x += tag("ram:LineTotalAmount", fmtAmt(t.lineTotal));
405
+ if (t.chargeTotal !== void 0) x += tag("ram:ChargeTotalAmount", fmtAmt(t.chargeTotal));
406
+ if (t.allowanceTotal !== void 0)
407
+ x += tag("ram:AllowanceTotalAmount", fmtAmt(t.allowanceTotal));
408
+ }
409
+ x += tag("ram:TaxBasisTotalAmount", fmtAmt(t.taxBasisTotal));
410
+ x += tag("ram:TaxTotalAmount", fmtAmt(t.taxTotal), {
411
+ currencyID: t.currency
412
+ });
413
+ x += tag("ram:GrandTotalAmount", fmtAmt(t.grandTotal));
414
+ if (atLeast(profile, "BASIC_WL" /* BASIC_WL */) && t.prepaidAmount !== void 0)
415
+ x += tag("ram:TotalPrepaidAmount", fmtAmt(t.prepaidAmount));
416
+ x += tag("ram:DuePayableAmount", fmtAmt(t.duePayableAmount));
417
+ return tag("ram:SpecifiedTradeSettlementHeaderMonetarySummation", x);
418
+ }
419
+ function buildXml(input, profile, flavor) {
420
+ if (!input) {
421
+ throw new Error('buildXml: "input" is required.');
422
+ }
423
+ if (!profile) {
424
+ throw new Error('buildXml: "profile" is required (e.g. Profile.EN16931).');
425
+ }
426
+ if (!input.document) {
427
+ throw new Error('buildXml: "input.document" is required (id, issueDate, etc.).');
428
+ }
429
+ if (!input.seller) {
430
+ throw new Error('buildXml: "input.seller" is required (seller name and details).');
431
+ }
432
+ if (!input.buyer) {
433
+ throw new Error('buildXml: "input.buyer" is required (buyer name and details).');
434
+ }
435
+ if (!input.totals) {
436
+ throw new Error('buildXml: "input.totals" is required (monetary totals).');
437
+ }
438
+ const { document: doc, seller, buyer, totals, payment } = input;
439
+ const fl = flavor ?? "factur-x" /* FACTUR_X */;
440
+ const typeCode = resolveTypeCode(input, fl);
441
+ let ctx = "";
442
+ if (doc.businessProcessId)
443
+ ctx += tag(
444
+ "ram:BusinessProcessSpecifiedDocumentContextParameter",
445
+ tag("ram:ID", escapeXml(doc.businessProcessId))
446
+ );
447
+ ctx += tag(
448
+ "ram:GuidelineSpecifiedDocumentContextParameter",
449
+ tag("ram:ID", PROFILE_URNS[profile])
450
+ );
451
+ let edoc = tag("ram:ID", escapeXml(doc.id));
452
+ if (doc.name && atLeast(profile, "EXTENDED" /* EXTENDED */)) edoc += tag("ram:Name", escapeXml(doc.name));
453
+ edoc += tag("ram:TypeCode", typeCode);
454
+ edoc += dateEl("ram:IssueDateTime", doc.issueDate);
455
+ if (doc.language && atLeast(profile, "EXTENDED" /* EXTENDED */))
456
+ edoc += tag("ram:LanguageID", escapeXml(doc.language));
457
+ if (doc.notes && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
458
+ for (const note of doc.notes) {
459
+ let n = tag("ram:Content", escapeXml(note.content));
460
+ if (note.subjectCode) n += tag("ram:SubjectCode", escapeXml(note.subjectCode));
461
+ edoc += tag("ram:IncludedNote", n);
462
+ }
463
+ }
464
+ let tx = "";
465
+ if (atLeast(profile, "BASIC" /* BASIC */) && input.lines) {
466
+ for (const line of input.lines) tx += buildLineItem(line, profile);
467
+ }
468
+ let agree = "";
469
+ if (doc.buyerReference) agree += tag("ram:BuyerReference", escapeXml(doc.buyerReference));
470
+ agree += tag("ram:SellerTradeParty", buildParty(seller, profile));
471
+ agree += tag("ram:BuyerTradeParty", buildParty(buyer, profile));
472
+ if (input.sellerTaxRepresentative && atLeast(profile, "BASIC_WL" /* BASIC_WL */))
473
+ agree += tag(
474
+ "ram:SellerTaxRepresentativeTradeParty",
475
+ buildParty(input.sellerTaxRepresentative, profile)
476
+ );
477
+ if (input.references && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
478
+ for (const ref of input.references) {
479
+ const refType = ref.type ?? "order";
480
+ if (refType === "preceding" || refType === "despatch") continue;
481
+ const inner = tag("ram:IssuerAssignedID", escapeXml(ref.id)) + (ref.issueDate ? dateEl("ram:FormattedIssueDateTime", ref.issueDate) : "");
482
+ switch (refType) {
483
+ case "order":
484
+ agree += tag("ram:BuyerOrderReferencedDocument", inner);
485
+ break;
486
+ case "contract":
487
+ agree += tag("ram:ContractReferencedDocument", inner);
488
+ break;
489
+ case "seller-order":
490
+ if (atLeast(profile, "EN16931" /* EN16931 */))
491
+ agree += tag("ram:SellerOrderReferencedDocument", inner);
492
+ break;
493
+ case "project":
494
+ if (atLeast(profile, "EN16931" /* EN16931 */))
495
+ agree += tag("ram:SpecifiedProcuringProject", tag("ram:ID", escapeXml(ref.id)));
496
+ break;
497
+ }
498
+ }
499
+ }
500
+ tx += tag("ram:ApplicableHeaderTradeAgreement", agree);
501
+ let del = "";
502
+ if (input.delivery && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
503
+ if (input.delivery.partyName || input.delivery.location) {
504
+ let sp = "";
505
+ if (input.delivery.partyName) sp += tag("ram:Name", escapeXml(input.delivery.partyName));
506
+ if (input.delivery.location) sp += buildAddress(input.delivery.location);
507
+ del += tag("ram:ShipToTradeParty", sp);
508
+ }
509
+ if (input.delivery.date)
510
+ del += tag(
511
+ "ram:ActualDeliverySupplyChainEvent",
512
+ dateEl("ram:OccurrenceDateTime", input.delivery.date)
513
+ );
514
+ if (input.delivery.despatchAdviceReference)
515
+ del += tag(
516
+ "ram:DespatchAdviceReferencedDocument",
517
+ tag("ram:IssuerAssignedID", escapeXml(input.delivery.despatchAdviceReference))
518
+ );
519
+ }
520
+ if (input.references && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
521
+ for (const ref of input.references) {
522
+ if (ref.type === "despatch") {
523
+ let inner = tag("ram:IssuerAssignedID", escapeXml(ref.id));
524
+ if (ref.issueDate) inner += dateEl("ram:FormattedIssueDateTime", ref.issueDate);
525
+ del += tag("ram:DespatchAdviceReferencedDocument", inner);
526
+ }
527
+ }
528
+ }
529
+ tx += tag("ram:ApplicableHeaderTradeDelivery", del);
530
+ let sett = "";
531
+ if (payment?.creditorReference && atLeast(profile, "BASIC_WL" /* BASIC_WL */))
532
+ sett += tag("ram:CreditorReferenceID", escapeXml(payment.creditorReference));
533
+ if (payment?.paymentReference && atLeast(profile, "BASIC_WL" /* BASIC_WL */))
534
+ sett += tag("ram:PaymentReference", escapeXml(payment.paymentReference));
535
+ if (totals.taxCurrency) sett += tag("ram:TaxCurrencyCode", escapeXml(totals.taxCurrency));
536
+ sett += tag("ram:InvoiceCurrencyCode", escapeXml(totals.currency));
537
+ if (input.payee && atLeast(profile, "BASIC_WL" /* BASIC_WL */))
538
+ sett += tag("ram:PayeeTradeParty", buildParty(input.payee, profile));
539
+ if (payment?.meansCode && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
540
+ let pm = tag("ram:TypeCode", escapeXml(payment.meansCode));
541
+ if (payment.iban || payment.accountId || payment.accountName) {
542
+ let acct = "";
543
+ if (payment.iban) acct += tag("ram:IBANID", escapeXml(payment.iban));
544
+ if (payment.accountId) acct += tag("ram:ProprietaryID", escapeXml(payment.accountId));
545
+ if (payment.accountName && atLeast(profile, "EN16931" /* EN16931 */))
546
+ acct += tag("ram:AccountName", escapeXml(payment.accountName));
547
+ pm += tag("ram:PayeePartyCreditorFinancialAccount", acct);
548
+ }
549
+ if (payment.bic && atLeast(profile, "EN16931" /* EN16931 */))
550
+ pm += tag(
551
+ "ram:PayeeSpecifiedCreditorFinancialInstitution",
552
+ tag("ram:BICID", escapeXml(payment.bic))
553
+ );
554
+ if (payment.debtorIban)
555
+ pm += tag(
556
+ "ram:PayerPartyDebtorFinancialAccount",
557
+ tag("ram:IBANID", escapeXml(payment.debtorIban))
558
+ );
559
+ sett += tag("ram:SpecifiedTradeSettlementPaymentMeans", pm);
560
+ }
561
+ if (input.vatBreakdown && atLeast(profile, "BASIC_WL" /* BASIC_WL */))
562
+ for (const vb of input.vatBreakdown) sett += buildVatBreakdown(vb);
563
+ if (input.billingPeriod && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
564
+ let bp = "";
565
+ if (input.billingPeriod.startDate)
566
+ bp += dateEl("ram:StartDateTime", input.billingPeriod.startDate);
567
+ if (input.billingPeriod.endDate) bp += dateEl("ram:EndDateTime", input.billingPeriod.endDate);
568
+ sett += tag("ram:BillingSpecifiedPeriod", bp);
569
+ }
570
+ if (input.allowancesCharges && atLeast(profile, "BASIC_WL" /* BASIC_WL */))
571
+ for (const ac of input.allowancesCharges) sett += buildAllowanceCharge(ac);
572
+ const dueDate = payment?.dueDate ?? doc.dueDate;
573
+ if (atLeast(profile, "BASIC_WL" /* BASIC_WL */) && (payment?.termsDescription || dueDate || payment?.mandateId)) {
574
+ let pt = "";
575
+ if (payment?.termsDescription)
576
+ pt += tag("ram:Description", escapeXml(payment.termsDescription));
577
+ if (dueDate) pt += dateEl("ram:DueDateDateTime", dueDate);
578
+ if (payment?.mandateId) pt += tag("ram:DirectDebitMandateID", escapeXml(payment.mandateId));
579
+ sett += tag("ram:SpecifiedTradePaymentTerms", pt);
580
+ }
581
+ sett += buildMonetarySummation(totals, profile);
582
+ if (input.references && atLeast(profile, "BASIC_WL" /* BASIC_WL */)) {
583
+ for (const ref of input.references) {
584
+ if (ref.type === "preceding") {
585
+ let inner = tag("ram:IssuerAssignedID", escapeXml(ref.id));
586
+ if (ref.issueDate) inner += dateEl("ram:FormattedIssueDateTime", ref.issueDate);
587
+ sett += tag("ram:InvoiceReferencedDocument", inner);
588
+ }
589
+ }
590
+ }
591
+ tx += tag("ram:ApplicableHeaderTradeSettlement", sett);
592
+ return '<?xml version="1.0" encoding="UTF-8"?><rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100">' + tag("rsm:ExchangedDocumentContext", ctx) + tag("rsm:ExchangedDocument", edoc) + tag("rsm:SupplyChainTradeTransaction", tx) + "</rsm:CrossIndustryInvoice>";
593
+ }
594
+
595
+ // src/validation/profile-validator.ts
596
+ var PROFILE_LEVEL2 = {
597
+ MINIMUM: 0,
598
+ BASIC_WL: 1,
599
+ BASIC: 2,
600
+ EN16931: 3,
601
+ EXTENDED: 4
602
+ };
603
+ function addError(errors, field, message, profile) {
604
+ errors.push({ field, message, profile });
605
+ }
606
+ function validateInput(input, profile) {
607
+ const errors = [];
608
+ const level = PROFILE_LEVEL2[profile];
609
+ const req = (minProfile) => level >= PROFILE_LEVEL2[minProfile];
610
+ if (!input.document) {
611
+ addError(errors, "document", "Document is required", "MINIMUM" /* MINIMUM */);
612
+ } else {
613
+ if (req("MINIMUM" /* MINIMUM */)) {
614
+ if (!input.document.id) {
615
+ addError(errors, "document.id", "Document ID is required", "MINIMUM" /* MINIMUM */);
616
+ }
617
+ if (!input.document.issueDate) {
618
+ addError(errors, "document.issueDate", "Document issue date is required", "MINIMUM" /* MINIMUM */);
619
+ }
620
+ }
621
+ }
622
+ if (!input.seller) {
623
+ addError(errors, "seller", "Seller is required", "MINIMUM" /* MINIMUM */);
624
+ } else {
625
+ if (req("MINIMUM" /* MINIMUM */) && !input.seller.name) {
626
+ addError(errors, "seller.name", "Seller name is required", "MINIMUM" /* MINIMUM */);
627
+ }
628
+ if (req("BASIC_WL" /* BASIC_WL */)) {
629
+ if (!input.seller.address) {
630
+ addError(
631
+ errors,
632
+ "seller.address",
633
+ "Seller address is required for BASIC_WL",
634
+ "BASIC_WL" /* BASIC_WL */
635
+ );
636
+ } else if (!input.seller.address.country) {
637
+ addError(
638
+ errors,
639
+ "seller.address.country",
640
+ "Seller address country is required for BASIC_WL",
641
+ "BASIC_WL" /* BASIC_WL */
642
+ );
643
+ }
644
+ }
645
+ }
646
+ if (!input.buyer) {
647
+ addError(errors, "buyer", "Buyer is required", "MINIMUM" /* MINIMUM */);
648
+ } else {
649
+ if (req("MINIMUM" /* MINIMUM */) && !input.buyer.name) {
650
+ addError(errors, "buyer.name", "Buyer name is required", "MINIMUM" /* MINIMUM */);
651
+ }
652
+ if (req("BASIC_WL" /* BASIC_WL */)) {
653
+ if (!input.buyer.address) {
654
+ addError(
655
+ errors,
656
+ "buyer.address",
657
+ "Buyer address is required for BASIC_WL",
658
+ "BASIC_WL" /* BASIC_WL */
659
+ );
660
+ } else if (!input.buyer.address.country) {
661
+ addError(
662
+ errors,
663
+ "buyer.address.country",
664
+ "Buyer address country is required for BASIC_WL",
665
+ "BASIC_WL" /* BASIC_WL */
666
+ );
667
+ }
668
+ }
669
+ }
670
+ if (!input.totals) {
671
+ addError(errors, "totals", "Totals are required", "MINIMUM" /* MINIMUM */);
672
+ } else {
673
+ if (req("MINIMUM" /* MINIMUM */)) {
674
+ if (input.totals.taxBasisTotal == null) {
675
+ addError(errors, "totals.taxBasisTotal", "Tax basis total is required", "MINIMUM" /* MINIMUM */);
676
+ }
677
+ if (input.totals.grandTotal == null) {
678
+ addError(errors, "totals.grandTotal", "Grand total is required", "MINIMUM" /* MINIMUM */);
679
+ }
680
+ if (input.totals.duePayableAmount == null) {
681
+ addError(
682
+ errors,
683
+ "totals.duePayableAmount",
684
+ "Due payable amount is required",
685
+ "MINIMUM" /* MINIMUM */
686
+ );
687
+ }
688
+ if (!input.totals.currency) {
689
+ addError(errors, "totals.currency", "Currency is required", "MINIMUM" /* MINIMUM */);
690
+ }
691
+ }
692
+ if (req("BASIC_WL" /* BASIC_WL */)) {
693
+ if (input.totals.lineTotal == null) {
694
+ addError(
695
+ errors,
696
+ "totals.lineTotal",
697
+ "Line total is required for BASIC_WL",
698
+ "BASIC_WL" /* BASIC_WL */
699
+ );
700
+ }
701
+ if (input.totals.taxTotal == null) {
702
+ addError(errors, "totals.taxTotal", "Tax total is required for BASIC_WL", "BASIC_WL" /* BASIC_WL */);
703
+ }
704
+ }
705
+ }
706
+ if (req("BASIC_WL" /* BASIC_WL */)) {
707
+ const vat = input.vatBreakdown;
708
+ if (!vat || vat.length === 0) {
709
+ addError(
710
+ errors,
711
+ "vatBreakdown",
712
+ "VAT breakdown with at least one entry is required for BASIC_WL",
713
+ "BASIC_WL" /* BASIC_WL */
714
+ );
715
+ } else {
716
+ vat.forEach((entry, i) => {
717
+ if (!entry.categoryCode) {
718
+ addError(
719
+ errors,
720
+ `vatBreakdown[${i}].categoryCode`,
721
+ "VAT breakdown entry categoryCode is required",
722
+ "BASIC_WL" /* BASIC_WL */
723
+ );
724
+ }
725
+ if (entry.ratePercent == null) {
726
+ addError(
727
+ errors,
728
+ `vatBreakdown[${i}].ratePercent`,
729
+ "VAT breakdown entry ratePercent is required",
730
+ "BASIC_WL" /* BASIC_WL */
731
+ );
732
+ }
733
+ if (entry.taxableAmount == null) {
734
+ addError(
735
+ errors,
736
+ `vatBreakdown[${i}].taxableAmount`,
737
+ "VAT breakdown entry taxableAmount is required",
738
+ "BASIC_WL" /* BASIC_WL */
739
+ );
740
+ }
741
+ if (entry.taxAmount == null) {
742
+ addError(
743
+ errors,
744
+ `vatBreakdown[${i}].taxAmount`,
745
+ "VAT breakdown entry taxAmount is required",
746
+ "BASIC_WL" /* BASIC_WL */
747
+ );
748
+ }
749
+ });
750
+ }
751
+ }
752
+ if (req("BASIC" /* BASIC */)) {
753
+ const lines = input.lines;
754
+ if (!lines || lines.length === 0) {
755
+ addError(errors, "lines", "At least one invoice line is required for BASIC", "BASIC" /* BASIC */);
756
+ } else {
757
+ lines.forEach((line, i) => {
758
+ if (!line.id) {
759
+ addError(errors, `lines[${i}].id`, "Line ID is required", "BASIC" /* BASIC */);
760
+ }
761
+ if (!line.name) {
762
+ addError(errors, `lines[${i}].name`, "Line name is required", "BASIC" /* BASIC */);
763
+ }
764
+ if (line.quantity == null) {
765
+ addError(errors, `lines[${i}].quantity`, "Line quantity is required", "BASIC" /* BASIC */);
766
+ }
767
+ if (line.unitPrice == null) {
768
+ addError(errors, `lines[${i}].unitPrice`, "Line unit price is required", "BASIC" /* BASIC */);
769
+ }
770
+ });
771
+ }
772
+ }
773
+ if (req("EN16931" /* EN16931 */) && input.lines && input.lines.length > 0) {
774
+ input.lines.forEach((line, i) => {
775
+ if (line.vatCategoryCode == null || line.vatCategoryCode === "") {
776
+ addError(
777
+ errors,
778
+ `lines[${i}].vatCategoryCode`,
779
+ "Line VAT category code is required for EN16931",
780
+ "EN16931" /* EN16931 */
781
+ );
782
+ }
783
+ if (line.vatRatePercent == null) {
784
+ addError(
785
+ errors,
786
+ `lines[${i}].vatRatePercent`,
787
+ "Line VAT rate percent is required for EN16931",
788
+ "EN16931" /* EN16931 */
789
+ );
790
+ }
791
+ });
792
+ }
793
+ return {
794
+ valid: errors.length === 0,
795
+ errors
796
+ };
797
+ }
798
+ function findSchemaDir(startDir) {
799
+ let dir = startDir;
800
+ for (let i = 0; i < 6; i++) {
801
+ const candidate = path2.join(dir, "schema");
802
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
803
+ return candidate;
804
+ }
805
+ const parent = path2.dirname(dir);
806
+ if (parent === dir) break;
807
+ dir = parent;
808
+ }
809
+ throw new Error(
810
+ "Could not auto-detect the schema directory. Pass `schemaBasePath` pointing to the folder that contains `schema/`."
811
+ );
812
+ }
813
+ function resolveXsdPath(profile, schemaBasePath) {
814
+ const base = schemaBasePath ? path2.join(schemaBasePath, "schema") : findSchemaDir(__dirname$1);
815
+ const profileDir = path2.join(base, PROFILE_SCHEMA_DIRS[profile]);
816
+ const xsdFile = path2.join(profileDir, PROFILE_MAIN_XSD[profile]);
817
+ if (!fs.existsSync(xsdFile)) {
818
+ throw new Error(
819
+ `XSD schema file not found: ${xsdFile}. Ensure the schema files are installed with the package.`
820
+ );
821
+ }
822
+ return xsdFile;
823
+ }
824
+ async function validateXsd(xml, profile, options) {
825
+ const xsdPath = resolveXsdPath(profile, options?.schemaBasePath);
826
+ const {
827
+ XmlDocument,
828
+ XsdValidator,
829
+ XmlValidateError,
830
+ xmlRegisterInputProvider,
831
+ XmlBufferInputProvider
832
+ } = await import('libxml2-wasm');
833
+ const schemaDir = path2.dirname(xsdPath);
834
+ const files = fs.readdirSync(schemaDir).filter((f) => f.endsWith(".xsd"));
835
+ const buffers = {};
836
+ for (const file of files) {
837
+ const filePath = path2.join(schemaDir, file);
838
+ buffers[filePath] = fs.readFileSync(filePath);
839
+ buffers[`file://${filePath}`] = buffers[filePath];
840
+ buffers[file] = buffers[filePath];
841
+ }
842
+ const provider = new XmlBufferInputProvider(buffers);
843
+ xmlRegisterInputProvider(provider);
844
+ let xsdDoc;
845
+ let validator;
846
+ let xmlDoc;
847
+ try {
848
+ const xsdContent = fs.readFileSync(xsdPath, "utf-8");
849
+ xsdDoc = XmlDocument.fromString(xsdContent, { url: `file://${xsdPath}` });
850
+ validator = XsdValidator.fromDoc(xsdDoc);
851
+ xmlDoc = XmlDocument.fromString(xml);
852
+ validator.validate(xmlDoc);
853
+ return { valid: true, errors: [] };
854
+ } catch (err) {
855
+ if (err instanceof XmlValidateError) {
856
+ const errors = (err.details ?? []).map((d) => ({
857
+ message: d.message,
858
+ line: d.line,
859
+ column: d.col
860
+ }));
861
+ if (errors.length === 0) {
862
+ errors.push({ message: err.message || "XSD validation failed" });
863
+ }
864
+ return { valid: false, errors };
865
+ }
866
+ throw err;
867
+ } finally {
868
+ xmlDoc?.dispose();
869
+ validator?.dispose();
870
+ xsdDoc?.dispose();
871
+ }
872
+ }
873
+ var AF_RELATIONSHIP_MAP = {
874
+ Alternative: AFRelationship.Alternative,
875
+ Data: AFRelationship.Data,
876
+ Source: AFRelationship.Source
877
+ };
878
+ function resolveAfRelationship(profile, override) {
879
+ if (override) return AF_RELATIONSHIP_MAP[override];
880
+ switch (profile) {
881
+ case "MINIMUM" /* MINIMUM */:
882
+ case "BASIC_WL" /* BASIC_WL */:
883
+ return AFRelationship.Data;
884
+ default:
885
+ return AFRelationship.Alternative;
886
+ }
887
+ }
888
+ function buildXmpMetadata(opts) {
889
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
890
+ return `<?xpacket begin="\uFEFF" id="W5M0MpCehiHzreSzNTczkc9d"?>
891
+ <x:xmpmeta xmlns:x="adobe:ns:meta/">
892
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
893
+
894
+ <rdf:Description rdf:about=""
895
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
896
+ <dc:title>
897
+ <rdf:Alt>
898
+ <rdf:li xml:lang="x-default">${esc(opts.title)}</rdf:li>
899
+ </rdf:Alt>
900
+ </dc:title>
901
+ <dc:creator>
902
+ <rdf:Seq>
903
+ <rdf:li>${esc(opts.author)}</rdf:li>
904
+ </rdf:Seq>
905
+ </dc:creator>
906
+ <dc:description>
907
+ <rdf:Alt>
908
+ <rdf:li xml:lang="x-default">${esc(opts.subject)}</rdf:li>
909
+ </rdf:Alt>
910
+ </dc:description>
911
+ </rdf:Description>
912
+
913
+ <rdf:Description rdf:about=""
914
+ xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
915
+ <pdf:Producer>${esc(opts.producer)}</pdf:Producer>
916
+ </rdf:Description>
917
+
918
+ <rdf:Description rdf:about=""
919
+ xmlns:xmp="http://ns.adobe.com/xap/1.0/">
920
+ <xmp:CreatorTool>${esc(opts.creator)}</xmp:CreatorTool>
921
+ <xmp:CreateDate>${opts.createDate}</xmp:CreateDate>
922
+ <xmp:ModifyDate>${opts.modifyDate}</xmp:ModifyDate>
923
+ </rdf:Description>
924
+
925
+ <rdf:Description rdf:about=""
926
+ xmlns:pdfaid="http://www.aiim.org/pdfa/ns/id/">
927
+ <pdfaid:part>3</pdfaid:part>
928
+ <pdfaid:conformance>B</pdfaid:conformance>
929
+ </rdf:Description>
930
+
931
+ <rdf:Description rdf:about=""
932
+ xmlns:pdfaExtension="http://www.aiim.org/pdfa/ns/extension/"
933
+ xmlns:pdfaSchema="http://www.aiim.org/pdfa/ns/schema#"
934
+ xmlns:pdfaProperty="http://www.aiim.org/pdfa/ns/property#">
935
+ <pdfaExtension:schemas>
936
+ <rdf:Bag>
937
+ <rdf:li rdf:parseType="Resource">
938
+ <pdfaSchema:schema>Factur-X PDFA Extension Schema</pdfaSchema:schema>
939
+ <pdfaSchema:namespaceURI>urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#</pdfaSchema:namespaceURI>
940
+ <pdfaSchema:prefix>fx</pdfaSchema:prefix>
941
+ <pdfaSchema:property>
942
+ <rdf:Seq>
943
+ <rdf:li rdf:parseType="Resource">
944
+ <pdfaProperty:name>DocumentFileName</pdfaProperty:name>
945
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
946
+ <pdfaProperty:category>external</pdfaProperty:category>
947
+ <pdfaProperty:description>Name of the embedded XML invoice file</pdfaProperty:description>
948
+ </rdf:li>
949
+ <rdf:li rdf:parseType="Resource">
950
+ <pdfaProperty:name>DocumentType</pdfaProperty:name>
951
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
952
+ <pdfaProperty:category>external</pdfaProperty:category>
953
+ <pdfaProperty:description>INVOICE</pdfaProperty:description>
954
+ </rdf:li>
955
+ <rdf:li rdf:parseType="Resource">
956
+ <pdfaProperty:name>ConformanceLevel</pdfaProperty:name>
957
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
958
+ <pdfaProperty:category>external</pdfaProperty:category>
959
+ <pdfaProperty:description>Factur-X conformance level</pdfaProperty:description>
960
+ </rdf:li>
961
+ <rdf:li rdf:parseType="Resource">
962
+ <pdfaProperty:name>Version</pdfaProperty:name>
963
+ <pdfaProperty:valueType>Text</pdfaProperty:valueType>
964
+ <pdfaProperty:category>external</pdfaProperty:category>
965
+ <pdfaProperty:description>Version of the Factur-X XML schema</pdfaProperty:description>
966
+ </rdf:li>
967
+ </rdf:Seq>
968
+ </pdfaSchema:property>
969
+ </rdf:li>
970
+ </rdf:Bag>
971
+ </pdfaExtension:schemas>
972
+ </rdf:Description>
973
+
974
+ <rdf:Description rdf:about=""
975
+ xmlns:fx="urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#">
976
+ <fx:DocumentFileName>${esc(opts.documentFileName)}</fx:DocumentFileName>
977
+ <fx:DocumentType>INVOICE</fx:DocumentType>
978
+ <fx:ConformanceLevel>${esc(opts.conformanceLevel)}</fx:ConformanceLevel>
979
+ <fx:Version>1.0</fx:Version>
980
+ </rdf:Description>
981
+
982
+ </rdf:RDF>
983
+ </x:xmpmeta>
984
+ <?xpacket end="w"?>`;
985
+ }
986
+ async function embedFacturX(options) {
987
+ const {
988
+ pdf,
989
+ profile,
990
+ flavor = "factur-x" /* FACTUR_X */,
991
+ validateBeforeEmbed = true,
992
+ validateXsd: runXsdValidation = false,
993
+ addPdfA3Metadata = true,
994
+ meta
995
+ } = options;
996
+ if (!options.xml && !options.input) {
997
+ throw new Error('Either "xml" or "input" must be provided to embedFacturX.');
998
+ }
999
+ validateFlavorProfile(flavor, profile);
1000
+ const flavorConfig = getFlavorConfig(flavor);
1001
+ let xml = options.xml;
1002
+ let validation;
1003
+ let xsdValidation;
1004
+ if (!xml) {
1005
+ const input = options.input;
1006
+ if (validateBeforeEmbed) {
1007
+ validation = validateInput(input, profile);
1008
+ if (!validation.valid) {
1009
+ throw new Error(
1010
+ `Input validation failed for profile "${profile}":
1011
+ ` + validation.errors.map((e) => ` - ${e.field}: ${e.message}`).join("\n")
1012
+ );
1013
+ }
1014
+ }
1015
+ xml = buildXml(input, profile, flavor);
1016
+ }
1017
+ if (runXsdValidation) {
1018
+ xsdValidation = await validateXsd(xml, profile);
1019
+ if (!xsdValidation.valid) {
1020
+ throw new Error(
1021
+ `XSD validation failed for profile "${profile}":
1022
+ ` + xsdValidation.errors.map((e) => ` - ${e.message}`).join("\n")
1023
+ );
1024
+ }
1025
+ }
1026
+ const pdfDoc = await PDFDocument.load(pdf, { updateMetadata: false });
1027
+ const xmlBytes = new TextEncoder().encode(xml);
1028
+ const afRel = resolveAfRelationship(profile, options.afRelationship);
1029
+ await pdfDoc.attach(xmlBytes, flavorConfig.attachmentFilename, {
1030
+ mimeType: "text/xml",
1031
+ afRelationship: afRel,
1032
+ description: "Factur-X Invoice"
1033
+ });
1034
+ const now = /* @__PURE__ */ new Date();
1035
+ const title = meta?.title ?? "Factur-X Invoice";
1036
+ const author = meta?.author ?? "";
1037
+ const subject = meta?.subject ?? "";
1038
+ const creator = meta?.creator ?? "factur-x";
1039
+ const producer = "factur-x (pdf-lib)";
1040
+ pdfDoc.setTitle(title);
1041
+ if (author) pdfDoc.setAuthor(author);
1042
+ if (subject) pdfDoc.setSubject(subject);
1043
+ pdfDoc.setCreator(creator);
1044
+ pdfDoc.setProducer(producer);
1045
+ pdfDoc.setCreationDate(now);
1046
+ pdfDoc.setModificationDate(now);
1047
+ if (addPdfA3Metadata) {
1048
+ const isoDate = now.toISOString();
1049
+ const xmpXml = buildXmpMetadata({
1050
+ title,
1051
+ author,
1052
+ subject,
1053
+ creator,
1054
+ producer,
1055
+ createDate: isoDate,
1056
+ modifyDate: isoDate,
1057
+ documentFileName: flavorConfig.attachmentFilename,
1058
+ conformanceLevel: profile
1059
+ });
1060
+ const xmpBytes = new TextEncoder().encode(xmpXml);
1061
+ const metadataStream = pdfDoc.context.stream(xmpBytes, {
1062
+ Type: "Metadata",
1063
+ Subtype: "XML",
1064
+ Length: xmpBytes.length
1065
+ });
1066
+ const metadataRef = pdfDoc.context.register(metadataStream);
1067
+ pdfDoc.catalog.set(PDFName.of("Metadata"), metadataRef);
1068
+ }
1069
+ const resultPdf = await pdfDoc.save();
1070
+ return {
1071
+ pdf: resultPdf,
1072
+ xml,
1073
+ ...validation ? { validation } : {},
1074
+ ...xsdValidation ? { xsdValidation } : {}
1075
+ };
1076
+ }
1077
+ var KNOWN_ATTACHMENT_NAMES = [
1078
+ "factur-x.xml",
1079
+ "xrechnung.xml",
1080
+ "zugferd-invoice.xml",
1081
+ "ZUGFeRD-invoice.xml"
1082
+ ];
1083
+ function decodePdfString(obj) {
1084
+ if (obj instanceof PDFString) return obj.decodeText();
1085
+ if (obj instanceof PDFHexString) return obj.decodeText();
1086
+ if (typeof obj === "string") return obj;
1087
+ return void 0;
1088
+ }
1089
+ function resolve(doc, obj) {
1090
+ if (obj instanceof PDFRef) return doc.context.lookup(obj);
1091
+ return obj;
1092
+ }
1093
+ function detectProfile(xml) {
1094
+ const profileMap = {
1095
+ "urn:factur-x.eu:1p0:minimum": "MINIMUM" /* MINIMUM */,
1096
+ "urn:factur-x.eu:1p0:basicwl": "BASIC_WL" /* BASIC_WL */,
1097
+ "urn:factur-x.eu:1p0:basic": "BASIC" /* BASIC */,
1098
+ "urn:factur-x.eu:1p0:en16931": "EN16931" /* EN16931 */,
1099
+ "urn:factur-x.eu:1p0:extended": "EXTENDED" /* EXTENDED */,
1100
+ "urn:cen.eu:en16931:2017": "EN16931" /* EN16931 */,
1101
+ "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0": "EN16931" /* EN16931 */,
1102
+ "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_2.3": "EN16931" /* EN16931 */,
1103
+ "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_2.2": "EN16931" /* EN16931 */
1104
+ };
1105
+ for (const [urn, profile] of Object.entries(profileMap)) {
1106
+ if (xml.includes(urn)) return profile;
1107
+ }
1108
+ return void 0;
1109
+ }
1110
+ async function extractXml(pdf, options) {
1111
+ const pdfDoc = await PDFDocument.load(pdf, { updateMetadata: false });
1112
+ const catalog = pdfDoc.catalog;
1113
+ const namesDict = resolve(pdfDoc, catalog.get(PDFName.of("Names")));
1114
+ if (!(namesDict instanceof PDFDict)) {
1115
+ throw new Error("PDF does not contain a Names dictionary \u2014 no embedded files found.");
1116
+ }
1117
+ const embeddedFilesObj = resolve(pdfDoc, namesDict.get(PDFName.of("EmbeddedFiles")));
1118
+ if (!(embeddedFilesObj instanceof PDFDict)) {
1119
+ throw new Error("PDF does not contain an EmbeddedFiles name tree.");
1120
+ }
1121
+ const targetNames = options?.filename ? [options.filename] : KNOWN_ATTACHMENT_NAMES;
1122
+ const entries = collectNameTreeEntries(pdfDoc, embeddedFilesObj);
1123
+ for (const [name, fileSpecRef] of entries) {
1124
+ if (!targetNames.some((t) => name.toLowerCase() === t.toLowerCase())) {
1125
+ continue;
1126
+ }
1127
+ const fileSpec = resolve(pdfDoc, fileSpecRef);
1128
+ if (!(fileSpec instanceof PDFDict)) continue;
1129
+ const efDict = resolve(pdfDoc, fileSpec.get(PDFName.of("EF")));
1130
+ if (!(efDict instanceof PDFDict)) continue;
1131
+ const streamRef = efDict.get(PDFName.of("F"));
1132
+ const stream = resolve(pdfDoc, streamRef);
1133
+ if (!(stream instanceof PDFStream)) continue;
1134
+ const rawBytes = stream instanceof PDFRawStream ? decodePDFRawStream(stream).decode() : stream.getContents();
1135
+ const xml = new TextDecoder("utf-8").decode(rawBytes);
1136
+ const profile = detectProfile(xml);
1137
+ return { xml, filename: name, profile };
1138
+ }
1139
+ throw new Error(
1140
+ `No Factur-X / ZUGFeRD XML attachment found in PDF. Searched for: ${targetNames.join(", ")}.`
1141
+ );
1142
+ }
1143
+ function collectNameTreeEntries(doc, node) {
1144
+ const results = [];
1145
+ const namesArray = resolve(doc, node.get(PDFName.of("Names")));
1146
+ if (namesArray instanceof PDFArray) {
1147
+ for (let i = 0; i < namesArray.size(); i += 2) {
1148
+ const keyObj = resolve(doc, namesArray.get(i));
1149
+ const valObj = namesArray.get(i + 1);
1150
+ const key = decodePdfString(keyObj);
1151
+ if (key != null) {
1152
+ results.push([key, valObj]);
1153
+ }
1154
+ }
1155
+ }
1156
+ const kidsArray = resolve(doc, node.get(PDFName.of("Kids")));
1157
+ if (kidsArray instanceof PDFArray) {
1158
+ for (let i = 0; i < kidsArray.size(); i++) {
1159
+ const kid = resolve(doc, kidsArray.get(i));
1160
+ if (kid instanceof PDFDict) {
1161
+ results.push(...collectNameTreeEntries(doc, kid));
1162
+ }
1163
+ }
1164
+ }
1165
+ return results;
1166
+ }
1167
+
1168
+ // src/core/xrechnung.ts
1169
+ function toXRechnung(input, options) {
1170
+ const profile = options?.profile ?? "EN16931" /* EN16931 */;
1171
+ const validate = options?.validate ?? true;
1172
+ validateFlavorProfile("xrechnung" /* XRECHNUNG */, profile);
1173
+ let validation;
1174
+ if (validate) {
1175
+ validation = validateInput(input, profile);
1176
+ if (!validation.valid) {
1177
+ throw new Error(
1178
+ `Input validation failed for XRechnung (profile "${profile}"):
1179
+ ` + validation.errors.map((e) => ` - ${e.field}: ${e.message}`).join("\n")
1180
+ );
1181
+ }
1182
+ }
1183
+ const enrichedInput = {
1184
+ ...input,
1185
+ document: {
1186
+ ...input.document,
1187
+ businessProcessId: resolveBusinessProcessUrn(input, "xrechnung" /* XRECHNUNG */)
1188
+ }
1189
+ };
1190
+ const xml = buildXml(enrichedInput, profile, "xrechnung" /* XRECHNUNG */);
1191
+ return {
1192
+ xml,
1193
+ ...validation ? { validation } : {}
1194
+ };
1195
+ }
1196
+ /**
1197
+ * Factur-X Input Object Types
1198
+ *
1199
+ * These types define the structured input for invoice generation across
1200
+ * all supported profiles (MINIMUM → EXTENDED) and flavors (factur-x,
1201
+ * zugferd, xrechnung, chrono-pro).
1202
+ *
1203
+ * Fields are annotated with their EN 16931 Business Term (BT) mapping
1204
+ * and the minimum profile level at which they become relevant.
1205
+ *
1206
+ * @module types/input
1207
+ * @see docs/INPUT_OBJECT_SPECIFICATION.md
1208
+ * @see https://fnfe-mpe.org/factur-x/
1209
+ * @license EUPL-1.2
1210
+ */
1211
+ /**
1212
+ * XSD Schema Validation
1213
+ *
1214
+ * Validates generated CII XML against the official Factur-X / ZUGFeRD XSD
1215
+ * schemas using {@link https://github.com/jameslan/libxml2-wasm | libxml2-wasm}
1216
+ * (WebAssembly port of libxml2).
1217
+ *
1218
+ * Schema files are shipped with the package in `schema/` and loaded at
1219
+ * validation time. Because `libxml2-wasm` is ESM-only, this module uses
1220
+ * dynamic `import()` so the package stays consumable from both CJS and ESM.
1221
+ *
1222
+ * @module validation/xsd-validator
1223
+ * @license EUPL-1.2
1224
+ */
1225
+ /**
1226
+ * Factur-X PDF Embedding
1227
+ *
1228
+ * Embeds structured invoice XML into a PDF document and ensures
1229
+ * PDF/A-3 compliance via XMP metadata.
1230
+ *
1231
+ * @module core/embed
1232
+ * @license EUPL-1.2
1233
+ */
1234
+ /**
1235
+ * Factur-X / ZUGFeRD XML Extraction from PDF
1236
+ *
1237
+ * Reads an embedded CII XML attachment from a PDF document.
1238
+ * Supports detection of all standard attachment filenames
1239
+ * (`factur-x.xml`, `xrechnung.xml`, `zugferd-invoice.xml`, `ZUGFeRD-invoice.xml`).
1240
+ *
1241
+ * @module core/extract
1242
+ * @license EUPL-1.2
1243
+ */
1244
+ /**
1245
+ * XRechnung Generation
1246
+ *
1247
+ * Generates standalone CII XML for German B2G (XRechnung) use.
1248
+ * XRechnung is a pure-XML format (no PDF embedding) that conforms
1249
+ * to EN 16931 with additional PEPPOL/German government requirements.
1250
+ *
1251
+ * @module core/xrechnung
1252
+ * @license EUPL-1.2
1253
+ */
1254
+ /**
1255
+ * Factur-X — Embed Structured Invoices into PDF
1256
+ *
1257
+ * Generate Factur-X, ZUGFeRD, and XRechnung compliant invoice XML
1258
+ * from a typed input object, validate it against XSD schemas, and
1259
+ * embed it into PDF/A-3 documents — or output standalone XRechnung XML.
1260
+ * Also extracts existing XML from Factur-X/ZUGFeRD PDFs.
1261
+ *
1262
+ * @packageDocumentation
1263
+ * @license EUPL-1.2
1264
+ *
1265
+ * @example
1266
+ * ```ts
1267
+ * import { embedFacturX, toXRechnung, extractXml } from '@stackforge-eu/factur-x';
1268
+ *
1269
+ * // Embed Factur-X XML into an existing PDF
1270
+ * const result = await embedFacturX({
1271
+ * pdf: existingPdfBytes,
1272
+ * input: invoiceData,
1273
+ * profile: Profile.EN16931,
1274
+ * flavor: Flavor.ZUGFERD,
1275
+ * });
1276
+ *
1277
+ * // Generate XRechnung XML (no PDF)
1278
+ * const { xml } = toXRechnung(invoiceData);
1279
+ *
1280
+ * // Extract XML from an existing PDF
1281
+ * const { xml: extracted, profile } = await extractXml(pdfBytes);
1282
+ * ```
1283
+ */
1284
+
1285
+ export { DocumentTypeCode, FLAVOR_CONFIGS, FLAVOR_DEFAULT_TYPE_CODES, Flavor, PROFILE_MAIN_XSD, PROFILE_SCHEMA_DIRS, PROFILE_URNS, Profile, UnitCode, buildXml, embedFacturX, escapeXml, extractXml, getFlavorConfig, resolveBusinessProcessUrn, resolveTypeCode, toXRechnung, validateFlavorProfile, validateInput, validateXsd };