fix(core): update
This commit is contained in:
8
ts/00_commitinfo_data.ts
Normal file
8
ts/00_commitinfo_data.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* autocreated commitinfo by @pushrocks/commitinfo
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@fin.cx/xinvoice',
|
||||
version: '1.0.4',
|
||||
description: 'A module for creating, manipulating, and embedding XML data within PDF files for xinvoice packages.'
|
||||
}
|
115
ts/classes.xinvoice.ts
Normal file
115
ts/classes.xinvoice.ts
Normal file
@ -0,0 +1,115 @@
|
||||
import * as plugins from './plugins.js';
|
||||
import * as interfaces from './interfaces.js';
|
||||
import { PDFDocument, PDFDict, PDFName, PDFRawStream } from 'pdf-lib';
|
||||
|
||||
export class XInvoice {
|
||||
public pdfUint8Array: Uint8Array;
|
||||
|
||||
constructor(pdfBuffer: Uint8Array | Buffer) {
|
||||
this.pdfUint8Array = Uint8Array.from(pdfBuffer);
|
||||
}
|
||||
|
||||
public async embedXml(xmlString: string): Promise<void> {
|
||||
try {
|
||||
|
||||
const pdfDoc = await PDFDocument.load(this.pdfUint8Array);
|
||||
|
||||
const xmlBuffer = new TextEncoder().encode(xmlString);
|
||||
pdfDoc.attach(xmlBuffer, plugins.path.basename('invoice.xml'), {
|
||||
mimeType: 'application/xml',
|
||||
description: 'XRechnung XML Invoice',
|
||||
});
|
||||
|
||||
const modifiedPdfBytes = await pdfDoc.save();
|
||||
this.pdfUint8Array = modifiedPdfBytes;
|
||||
console.log(`PDF Buffer updated with new XML attachment!`);
|
||||
} catch (error) {
|
||||
console.error('Error embedding XML into PDF:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reads the xml part and returns parsed structured data
|
||||
* @returns {Promise<interfaces.IXInvoice>} Parsed XML data
|
||||
*/
|
||||
public async getParsedXmlData(): Promise<interfaces.IXInvoice> {
|
||||
try {
|
||||
const pdfBuffer = this.pdfUint8Array;
|
||||
const pdfDoc = await PDFDocument.load(pdfBuffer);
|
||||
|
||||
const namesDict = pdfDoc.catalog.get(PDFName.of('Names')) as PDFDict;
|
||||
if (!namesDict) throw new Error('No Names dictionary found in PDF!');
|
||||
|
||||
const embeddedFilesDict = namesDict.get(PDFName.of('EmbeddedFiles')) as PDFDict;
|
||||
if (!embeddedFilesDict) throw new Error('No EmbeddedFiles dictionary found!');
|
||||
|
||||
const filesSpecDict = embeddedFilesDict.get(PDFName.of('Names')) as PDFDict;
|
||||
if (!filesSpecDict) throw new Error('No files specified in EmbeddedFiles dictionary!');
|
||||
|
||||
let xmlFile: PDFRawStream | undefined = undefined;
|
||||
const entries = filesSpecDict.entries();
|
||||
for (const [key, fileSpecValue] of entries) {
|
||||
const fileSpec = fileSpecValue as PDFDict;
|
||||
const efDict = fileSpec.get(PDFName.of('EF')) as PDFDict;
|
||||
xmlFile = efDict.get(PDFName.of('F')) as PDFRawStream;
|
||||
if (xmlFile) break;
|
||||
}
|
||||
|
||||
if (!xmlFile) throw new Error('XML file stream not found!');
|
||||
|
||||
const xmlBytes = xmlFile.getContents();
|
||||
const xmlContent = new TextDecoder().decode(xmlBytes);
|
||||
console.log(`Read embedded XML: ${xmlContent}`);
|
||||
|
||||
return this.parseXmlToInvoice(xmlContent);
|
||||
} catch (error) {
|
||||
console.error('Error extracting or parsing embedded XML from PDF:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private parseXmlToInvoice(xmlContent: string): interfaces.IXInvoice {
|
||||
// Implement XML parsing logic here
|
||||
// Placeholder return, replace with actual parsing result
|
||||
return {
|
||||
InvoiceNumber: '12345',
|
||||
DateIssued: '2023-04-01',
|
||||
Seller: {
|
||||
Name: 'Seller Co',
|
||||
Address: {
|
||||
Street: '1234 Market St',
|
||||
City: 'Sample City',
|
||||
PostalCode: '12345',
|
||||
Country: 'DE',
|
||||
},
|
||||
Contact: {
|
||||
Email: 'contact@sellerco.com',
|
||||
Phone: '123-456-7890',
|
||||
},
|
||||
},
|
||||
Buyer: {
|
||||
Name: 'Buyer Inc',
|
||||
Address: {
|
||||
Street: '5678 Trade Rd',
|
||||
City: 'Trade City',
|
||||
PostalCode: '67890',
|
||||
Country: 'DE',
|
||||
},
|
||||
Contact: {
|
||||
Email: 'info@buyerinc.com',
|
||||
Phone: '987-654-3210',
|
||||
},
|
||||
},
|
||||
Items: [
|
||||
{
|
||||
Description: 'Item 1',
|
||||
Quantity: 10,
|
||||
UnitPrice: 9.99,
|
||||
TotalPrice: 99.9,
|
||||
},
|
||||
],
|
||||
TotalAmount: 99.9,
|
||||
};
|
||||
}
|
||||
}
|
7
ts/index.ts
Normal file
7
ts/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import * as interfaces from './interfaces.js';
|
||||
|
||||
export {
|
||||
interfaces,
|
||||
}
|
||||
|
||||
export * from './classes.xinvoice.js';
|
33
ts/interfaces.ts
Normal file
33
ts/interfaces.ts
Normal file
@ -0,0 +1,33 @@
|
||||
export interface IXInvoice {
|
||||
InvoiceNumber: string;
|
||||
DateIssued: string; // Date in ISO 8601 format
|
||||
Seller: IParty;
|
||||
Buyer: IParty;
|
||||
Items: IInvoiceItem[];
|
||||
TotalAmount: number;
|
||||
}
|
||||
|
||||
export interface IParty {
|
||||
Name: string;
|
||||
Address: IAddress;
|
||||
Contact: IContact;
|
||||
}
|
||||
|
||||
export interface IAddress {
|
||||
Street: string;
|
||||
City: string;
|
||||
PostalCode: string;
|
||||
Country: string;
|
||||
}
|
||||
|
||||
export interface IContact {
|
||||
Email: string;
|
||||
Phone: string;
|
||||
}
|
||||
|
||||
export interface IInvoiceItem {
|
||||
Description: string;
|
||||
Quantity: number;
|
||||
UnitPrice: number;
|
||||
TotalPrice: number;
|
||||
}
|
20
ts/plugins.ts
Normal file
20
ts/plugins.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// node native
|
||||
import * as path from 'path';
|
||||
|
||||
export {
|
||||
path
|
||||
}
|
||||
|
||||
// @push.rocks scope
|
||||
import * as smartfile from '@push.rocks/smartfile';
|
||||
|
||||
export {
|
||||
smartfile
|
||||
}
|
||||
|
||||
// third party
|
||||
import * as pdfLib from 'pdf-lib';
|
||||
|
||||
export {
|
||||
pdfLib
|
||||
}
|
Reference in New Issue
Block a user