mindee 1.0.6 → 1.0.7

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.
@@ -0,0 +1,35 @@
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
+ class Client {
7
+ /**
8
+ * @param {string} receiptToken - Receipt Expense Token from Mindee dashboard
9
+ * @param {string} invoiceToken - Invoice Token from Mindee dashboard
10
+ * @param {boolean} throwOnError - Throw if an error is send from the API / SDK (true by default)
11
+ * @param {boolean} debug - Enable debug logging (disable by default)
12
+ */
13
+ constructor({
14
+ receiptToken = undefined,
15
+ invoiceToken = undefined,
16
+ throwOnError = true,
17
+ debug = undefined,
18
+ } = {}) {
19
+ this.receiptToken = receiptToken || process.env.MINDEE_RECEIPT_TOKEN;
20
+ this.invoiceToken = invoiceToken || process.env.MINDEE_INVOICE_TOKEN;
21
+ errorHandler.throwOnError = throwOnError;
22
+ logger.level = debug ?? process.env.MINDEE_DEBUG ? "debug" : "warn";
23
+ this.receipt = new APIReceipt(this.receiptToken);
24
+ this.invoice = new APIInvoice(this.invoiceToken);
25
+ this.financialDocument = new APIFinancialDocument(
26
+ this.invoiceToken,
27
+ this.receiptToken
28
+ );
29
+ }
30
+ }
31
+
32
+ exports.Client = Client;
33
+ exports.documents = require("./documents");
34
+ exports.api = require("./api");
35
+ 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 magic = require("stream-mmmagic");
6
+ const concat = require("concat-stream");
7
+ const { Base64Encode } = require("base64-stream");
8
+ const ReadableStreamClone = require("readable-stream-clone");
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: in case of base64 file, only jpeg file is supported
25
+ * NB: dummy is only used for tests purposes
26
+ * @param {String} filename - File name of the input
27
+ * @param {Boolean} cut_pdf: Automatically reconstruct pdf with more than 4 pages
28
+ * NB: Because of async calls, init() should be called after creating the object
29
+ */
30
+ constructor({ file, filename = undefined, inputType, allowCutPdf = true }) {
31
+ // Check if inputType is valid
32
+ if (!this.ALLOWED_INPUT_TYPE.includes(inputType)) {
33
+ errorHandler.throw(
34
+ new Error(
35
+ `The input type is invalid. It should be \
36
+ ${this.ALLOWED_INPUT_TYPE.toString()}`
37
+ )
38
+ );
39
+ }
40
+ this.file = file;
41
+ this.filename = filename;
42
+ this.inputType = inputType;
43
+ this.allowCutPdf = allowCutPdf;
44
+ }
45
+
46
+ async init() {
47
+ if (this.inputType === "base64") this.initBase64();
48
+ else if (this.inputType === "path") await this.initFile();
49
+ else if (this.inputType === "stream") await this.initStream();
50
+ else this.initDummy();
51
+ }
52
+
53
+ initBase64() {
54
+ this.fileObject = this.file;
55
+ this.filepath = undefined;
56
+ this.fileExtension = undefined;
57
+ }
58
+
59
+ async initFile() {
60
+ this.fileObject = await fs.readFile(this.file);
61
+ this.filepath = this.file;
62
+ this.filename = this.filename || path.basename(this.file);
63
+
64
+ // Check if file type is valid
65
+ const filetype = this.filename.split(".").pop();
66
+ if (!(filetype in this.MIMETYPES)) {
67
+ errorHandler.throw(
68
+ new Error(
69
+ `File type is not allowed. It must be ${Object.keys(
70
+ this.MIMETYPES
71
+ ).toString()}`
72
+ )
73
+ );
74
+ }
75
+ this.fileExtension = this.MIMETYPES[filetype];
76
+
77
+ if (this.fileExtension === "application/pdf" && this.allowCutPdf == true) {
78
+ await this.cutPdf();
79
+ }
80
+ }
81
+
82
+ async initStream() {
83
+ this.fileObject = this.file;
84
+ this.filename = this.filename || "stream";
85
+ this.filepath = undefined;
86
+
87
+ //Copy the ReadableStream
88
+ const stream = new ReadableStreamClone(this.fileObject);
89
+ this.fileObject = new ReadableStreamClone(this.fileObject);
90
+
91
+ const [mime, output] = await magic.promise(stream);
92
+
93
+ if (mime.type === "application/pdf" && this.allowCutPdf == true) {
94
+ await this.cutPdf();
95
+ }
96
+ }
97
+
98
+ initDummy() {
99
+ this.fileObject = "";
100
+ this.filename = "";
101
+ this.filepath = "";
102
+ this.fileExtension = "";
103
+ }
104
+
105
+ /**
106
+ * Convert ReadableStream to Base64 encoded String
107
+ *
108
+ * @param {*} stream ReadableStream to encode
109
+ * @returns Base64 encoded String
110
+ */
111
+ async streamToBase64(stream) {
112
+ return await new Promise((resolve, reject) => {
113
+ const base64 = new Base64Encode();
114
+
115
+ const cbConcat = (base64) => {
116
+ resolve(base64);
117
+ };
118
+
119
+ stream
120
+ .pipe(base64)
121
+ .pipe(concat(cbConcat))
122
+ .on("error", (error) => {
123
+ reject(error);
124
+ });
125
+ });
126
+ }
127
+
128
+ /** Cut PDF if pages > 5 */
129
+ async cutPdf() {
130
+ // convert document to PDFDocument & cut CUT_PDF_SIZE - 1 first pages and last page
131
+ let pdfDocument;
132
+
133
+ if (this.filename == "stream") {
134
+ pdfDocument = await PDFDocument.load(
135
+ await this.streamToBase64(this.fileObject)
136
+ );
137
+ } else {
138
+ pdfDocument = await PDFDocument.load(this.fileObject);
139
+ }
140
+
141
+ const splitedPdfDocument = await PDFDocument.create();
142
+ const pdfLength = pdfDocument.getPageCount();
143
+ if (pdfLength <= this.CUT_PDF_SIZE) return;
144
+ const pagesNumbers = [
145
+ ...Array(this.CUT_PDF_SIZE - 1).keys(),
146
+ pdfLength - 1,
147
+ ];
148
+ const pages = await splitedPdfDocument.copyPages(pdfDocument, pagesNumbers);
149
+ pages.forEach((page) => splitedPdfDocument.addPage(page));
150
+ const data = await splitedPdfDocument.save();
151
+ this.fileObject = Buffer.from(data);
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.6",
3
+ "version": "1.0.7",
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,14 +34,19 @@
34
34
  "prettier": "^2.2.0"
35
35
  },
36
36
  "dependencies": {
37
+ "base64-stream": "^1.0.0",
38
+ "concat-stream": "^2.0.0",
37
39
  "form-data": "^3.0.0",
38
- "pdf-lib": "^1.13.0"
40
+ "pdf-lib": "^1.13.0",
41
+ "readable-stream-clone": "^0.0.7",
42
+ "stream-mmmagic": "^2.3.0"
39
43
  },
40
44
  "keywords": [
41
45
  "javascript",
42
46
  "mindee",
43
47
  "api",
44
48
  "SDK",
45
- "nodejs"
49
+ "nodejs",
50
+ "OCR"
46
51
  ]
47
52
  }