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.
Files changed (48) hide show
  1. package/.nyc_output/f57ba3bc-1777-4ecc-81e1-230327c2a401.json +1 -0
  2. package/.nyc_output/processinfo/f57ba3bc-1777-4ecc-81e1-230327c2a401.json +1 -0
  3. package/.nyc_output/processinfo/index.json +1 -0
  4. package/CHANGELOG.md +42 -8
  5. package/README.md +1 -1
  6. package/coverage/coverage.json +1 -0
  7. package/coverage/lcov-report/base.css +224 -0
  8. package/coverage/lcov-report/block-navigation.js +79 -0
  9. package/coverage/lcov-report/favicon.png +0 -0
  10. package/coverage/lcov-report/index.html +171 -0
  11. package/coverage/lcov-report/prettify.css +1 -0
  12. package/coverage/lcov-report/prettify.js +2 -0
  13. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  14. package/coverage/lcov-report/sorter.js +170 -0
  15. package/coverage/lcov.info +1595 -0
  16. package/coverage.lcov +1595 -0
  17. package/examples/documents/invoices/credit_note.pdf +899 -1
  18. package/examples/invoice.js +17 -0
  19. package/lib/api/financialDocument.js +3 -3
  20. package/lib/api/invoice.js +18 -3
  21. package/lib/api/receipt.js +3 -3
  22. package/lib/api/request.js +7 -3
  23. package/lib/inputs.js +78 -24
  24. package/mindee/api/financialDocument.js +45 -0
  25. package/mindee/api/index.js +5 -0
  26. package/mindee/api/invoice.js +53 -0
  27. package/mindee/api/object.js +82 -0
  28. package/mindee/api/receipt.js +39 -0
  29. package/mindee/api/request.js +67 -0
  30. package/mindee/api/response.js +62 -0
  31. package/mindee/documents/document.js +69 -0
  32. package/mindee/documents/fields/amount.js +25 -0
  33. package/mindee/documents/fields/date.js +29 -0
  34. package/mindee/documents/fields/field.js +89 -0
  35. package/mindee/documents/fields/index.js +7 -0
  36. package/mindee/documents/fields/locale.js +30 -0
  37. package/mindee/documents/fields/orientation.js +24 -0
  38. package/mindee/documents/fields/paymentDetails.js +52 -0
  39. package/mindee/documents/fields/tax.js +47 -0
  40. package/mindee/documents/financialDocument.js +204 -0
  41. package/mindee/documents/index.js +5 -0
  42. package/mindee/documents/invoice.js +395 -0
  43. package/mindee/documents/receipt.js +272 -0
  44. package/mindee/errors/handler.js +16 -0
  45. package/mindee/index.js +36 -0
  46. package/mindee/inputs.js +155 -0
  47. package/mindee/logger.js +33 -0
  48. package/package.json +6 -2
@@ -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");
@@ -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;
@@ -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.4",
3
+ "version": "1.0.9",
4
4
  "description": "Mindee API SDK for Node.js",
5
- "main": "lib/index.js",
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
  },