mindee 1.0.4 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nyc_output/f57ba3bc-1777-4ecc-81e1-230327c2a401.json +1 -0
- package/.nyc_output/processinfo/f57ba3bc-1777-4ecc-81e1-230327c2a401.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/CHANGELOG.md +42 -8
- package/README.md +1 -1
- package/coverage/coverage.json +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +79 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +171 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +170 -0
- package/coverage/lcov.info +1595 -0
- package/coverage.lcov +1595 -0
- package/examples/documents/invoices/credit_note.pdf +899 -1
- package/examples/invoice.js +17 -0
- package/lib/api/financialDocument.js +3 -3
- package/lib/api/invoice.js +18 -3
- package/lib/api/receipt.js +3 -3
- package/lib/api/request.js +7 -3
- package/lib/inputs.js +78 -24
- package/mindee/api/financialDocument.js +45 -0
- package/mindee/api/index.js +5 -0
- package/mindee/api/invoice.js +53 -0
- package/mindee/api/object.js +82 -0
- package/mindee/api/receipt.js +39 -0
- package/mindee/api/request.js +67 -0
- package/mindee/api/response.js +62 -0
- package/mindee/documents/document.js +69 -0
- package/mindee/documents/fields/amount.js +25 -0
- package/mindee/documents/fields/date.js +29 -0
- package/mindee/documents/fields/field.js +89 -0
- package/mindee/documents/fields/index.js +7 -0
- package/mindee/documents/fields/locale.js +30 -0
- package/mindee/documents/fields/orientation.js +24 -0
- package/mindee/documents/fields/paymentDetails.js +52 -0
- package/mindee/documents/fields/tax.js +47 -0
- package/mindee/documents/financialDocument.js +204 -0
- package/mindee/documents/index.js +5 -0
- package/mindee/documents/invoice.js +395 -0
- package/mindee/documents/receipt.js +272 -0
- package/mindee/errors/handler.js +16 -0
- package/mindee/index.js +36 -0
- package/mindee/inputs.js +155 -0
- package/mindee/logger.js +33 -0
- package/package.json +6 -2
package/mindee/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const errorHandler = require("./errors/handler");
|
|
2
|
+
const logger = require("./logger");
|
|
3
|
+
const APIReceipt = require("./api/receipt");
|
|
4
|
+
const APIInvoice = require("./api/invoice");
|
|
5
|
+
const APIFinancialDocument = require("./api/financialDocument");
|
|
6
|
+
|
|
7
|
+
class Client {
|
|
8
|
+
/**
|
|
9
|
+
* @param {string} receiptToken - Receipt Expense Token from Mindee dashboard
|
|
10
|
+
* @param {string} invoiceToken - Invoice Token from Mindee dashboard
|
|
11
|
+
* @param {boolean} throwOnError - Throw if an error is send from the API / SDK (true by default)
|
|
12
|
+
* @param {boolean} debug - Enable debug logging (disable by default)
|
|
13
|
+
*/
|
|
14
|
+
constructor({
|
|
15
|
+
receiptToken = undefined,
|
|
16
|
+
invoiceToken = undefined,
|
|
17
|
+
throwOnError = true,
|
|
18
|
+
debug = undefined,
|
|
19
|
+
} = {}) {
|
|
20
|
+
this.receiptToken = receiptToken || process.env.MINDEE_RECEIPT_TOKEN;
|
|
21
|
+
this.invoiceToken = invoiceToken || process.env.MINDEE_INVOICE_TOKEN;
|
|
22
|
+
errorHandler.throwOnError = throwOnError;
|
|
23
|
+
logger.level = debug ?? process.env.MINDEE_DEBUG ? "debug" : "warn";
|
|
24
|
+
this.receipt = new APIReceipt(this.receiptToken);
|
|
25
|
+
this.invoice = new APIInvoice(this.invoiceToken);
|
|
26
|
+
this.financialDocument = new APIFinancialDocument(
|
|
27
|
+
this.invoiceToken,
|
|
28
|
+
this.receiptToken
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.Client = Client;
|
|
34
|
+
exports.documents = require("./documents");
|
|
35
|
+
exports.api = require("./api");
|
|
36
|
+
exports.inputs = require("./inputs");
|
package/mindee/inputs.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
const fs = require("fs").promises;
|
|
2
|
+
const errorHandler = require("./errors/handler");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { PDFDocument } = require("pdf-lib");
|
|
5
|
+
const concat = require("concat-stream");
|
|
6
|
+
const { Base64Encode } = require("base64-stream");
|
|
7
|
+
const fileType = require("file-type");
|
|
8
|
+
const ArrayBufferEncode = require("base64-arraybuffer");
|
|
9
|
+
|
|
10
|
+
class Input {
|
|
11
|
+
MIMETYPES = {
|
|
12
|
+
png: "image/png",
|
|
13
|
+
jpg: "image/jpg",
|
|
14
|
+
jpeg: "image/jpeg",
|
|
15
|
+
webp: "image/webp",
|
|
16
|
+
pdf: "application/pdf",
|
|
17
|
+
};
|
|
18
|
+
ALLOWED_INPUT_TYPE = ["base64", "path", "stream", "dummy"];
|
|
19
|
+
CUT_PDF_SIZE = 5;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {(String | Buffer)} file - the file that will be read. Either path or base64 string, or a steam
|
|
23
|
+
* @param {String} inputType - the type of input used in file ("base64", "path", "dummy").
|
|
24
|
+
* NB: dummy is only used for tests purposes
|
|
25
|
+
* @param {String} filename - File name of the input
|
|
26
|
+
* @param {Boolean} cut_pdf: Automatically reconstruct pdf with more than 4 pages
|
|
27
|
+
* NB: Because of async calls, init() should be called after creating the object
|
|
28
|
+
*/
|
|
29
|
+
constructor({ file, filename = undefined, inputType, allowCutPdf = true }) {
|
|
30
|
+
// Check if inputType is valid
|
|
31
|
+
if (!this.ALLOWED_INPUT_TYPE.includes(inputType)) {
|
|
32
|
+
errorHandler.throw(
|
|
33
|
+
new Error(
|
|
34
|
+
`The input type is invalid. It should be \
|
|
35
|
+
${this.ALLOWED_INPUT_TYPE.toString()}`
|
|
36
|
+
)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
this.file = file;
|
|
40
|
+
this.filename = filename;
|
|
41
|
+
this.inputType = inputType;
|
|
42
|
+
this.allowCutPdf = allowCutPdf;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async init() {
|
|
46
|
+
if (this.inputType === "base64") await this.initBase64();
|
|
47
|
+
else if (this.inputType === "path") await this.initFile();
|
|
48
|
+
else if (this.inputType === "stream") await this.initStream();
|
|
49
|
+
else this.initDummy();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async initBase64() {
|
|
53
|
+
this.fileObject = this.file;
|
|
54
|
+
this.filepath = undefined;
|
|
55
|
+
this.fileExtension = undefined;
|
|
56
|
+
|
|
57
|
+
if (this.allowCutPdf == true) {
|
|
58
|
+
const typeOfFile = await fileType.fromBuffer(
|
|
59
|
+
Buffer.from(this.fileObject, "base64")
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (typeOfFile === undefined) {
|
|
63
|
+
console.error(`Cannot detect mime type of: ${this.fileObject}`);
|
|
64
|
+
} else if (typeOfFile.mime === "application/pdf") {
|
|
65
|
+
await this.cutPdf();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async initFile() {
|
|
71
|
+
this.fileObject = await fs.readFile(this.file);
|
|
72
|
+
this.filepath = this.file;
|
|
73
|
+
this.filename = this.filename || path.basename(this.file);
|
|
74
|
+
|
|
75
|
+
// Check if file type is valid
|
|
76
|
+
const filetype = this.filename.split(".").pop();
|
|
77
|
+
if (!(filetype in this.MIMETYPES)) {
|
|
78
|
+
errorHandler.throw(
|
|
79
|
+
new Error(
|
|
80
|
+
`File type is not allowed. It must be ${Object.keys(
|
|
81
|
+
this.MIMETYPES
|
|
82
|
+
).toString()}`
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
this.fileExtension = this.MIMETYPES[filetype];
|
|
87
|
+
|
|
88
|
+
if (this.fileExtension === "application/pdf" && this.allowCutPdf == true) {
|
|
89
|
+
await this.cutPdf();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async initStream() {
|
|
94
|
+
const file = await this.streamToBase64(this.file);
|
|
95
|
+
|
|
96
|
+
this.file = file;
|
|
97
|
+
this.inputType = "base64";
|
|
98
|
+
await this.initBase64();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
initDummy() {
|
|
102
|
+
this.fileObject = "";
|
|
103
|
+
this.filename = "";
|
|
104
|
+
this.filepath = "";
|
|
105
|
+
this.fileExtension = "";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Convert ReadableStream to Base64 encoded String
|
|
110
|
+
*
|
|
111
|
+
* @param {*} stream ReadableStream to encode
|
|
112
|
+
* @returns Base64 encoded String
|
|
113
|
+
*/
|
|
114
|
+
async streamToBase64(stream) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
const base64 = new Base64Encode();
|
|
117
|
+
|
|
118
|
+
const cbConcat = (base64) => {
|
|
119
|
+
resolve(base64);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
stream
|
|
123
|
+
.pipe(base64)
|
|
124
|
+
.pipe(concat(cbConcat))
|
|
125
|
+
.on("error", (error) => {
|
|
126
|
+
reject(error);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Cut PDF if pages > 5 */
|
|
132
|
+
async cutPdf() {
|
|
133
|
+
// convert document to PDFDocument & cut CUT_PDF_SIZE - 1 first pages and last page
|
|
134
|
+
let pdfDocument = await PDFDocument.load(this.fileObject, {
|
|
135
|
+
ignoreEncryption: true,
|
|
136
|
+
});
|
|
137
|
+
const splitedPdfDocument = await PDFDocument.create();
|
|
138
|
+
const pdfLength = pdfDocument.getPageCount();
|
|
139
|
+
if (pdfLength <= this.CUT_PDF_SIZE) return;
|
|
140
|
+
const pagesNumbers = [
|
|
141
|
+
...Array(this.CUT_PDF_SIZE - 1).keys(),
|
|
142
|
+
pdfLength - 1,
|
|
143
|
+
];
|
|
144
|
+
const pages = await splitedPdfDocument.copyPages(pdfDocument, pagesNumbers);
|
|
145
|
+
pages.forEach((page) => splitedPdfDocument.addPage(page));
|
|
146
|
+
const data = await splitedPdfDocument.save();
|
|
147
|
+
if (this.inputType === "path") {
|
|
148
|
+
this.fileObject = Buffer.from(data);
|
|
149
|
+
} else if (this.inputType === "base64") {
|
|
150
|
+
this.fileObject = ArrayBufferEncode.encode(data);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
module.exports = Input;
|
package/mindee/logger.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const LOGGER_LEVELS = {
|
|
2
|
+
debug: 0,
|
|
3
|
+
info: 1,
|
|
4
|
+
warn: 2,
|
|
5
|
+
error: 3,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
class Logger {
|
|
9
|
+
constructor(level = "debug") {
|
|
10
|
+
if (!(level in LOGGER_LEVELS)) level = "debug";
|
|
11
|
+
this.level = LOGGER_LEVELS[level];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
debug(...args) {
|
|
15
|
+
if (this.level <= LOGGER_LEVELS["debug"]) console.debug(args);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
info(...args) {
|
|
19
|
+
if (this.level <= LOGGER_LEVELS["info"]) console.info(args);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
warn(...args) {
|
|
23
|
+
if (this.level <= LOGGER_LEVELS["warn"]) console.warn(args);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
error(...args) {
|
|
27
|
+
if (this.level <= LOGGER_LEVELS["error"]) console.error(args);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const logger = new Logger();
|
|
32
|
+
|
|
33
|
+
module.exports = logger;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindee",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Mindee API SDK for Node.js",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "mindee/index.js",
|
|
6
6
|
"license": "GPL-3.0",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "babel mindee -d lib",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"prettier": "^2.2.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"base64-arraybuffer": "^1.0.1",
|
|
38
|
+
"base64-stream": "^1.0.0",
|
|
39
|
+
"concat-stream": "^2.0.0",
|
|
40
|
+
"file-type": "^16.5.3",
|
|
37
41
|
"form-data": "^3.0.0",
|
|
38
42
|
"pdf-lib": "^1.13.0"
|
|
39
43
|
},
|