mindee 1.0.3 → 1.0.8

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 (50) 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 +43 -9
  5. package/README.md +11 -8
  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/financialDocument.js +2 -2
  19. package/examples/invoice.js +21 -4
  20. package/examples/receipt.js +3 -3
  21. package/lib/api/financialDocument.js +14 -10
  22. package/lib/api/invoice.js +29 -10
  23. package/lib/api/receipt.js +14 -10
  24. package/lib/api/request.js +8 -8
  25. package/lib/inputs.js +78 -24
  26. package/mindee/api/financialDocument.js +45 -0
  27. package/mindee/api/index.js +5 -0
  28. package/mindee/api/invoice.js +53 -0
  29. package/mindee/api/object.js +82 -0
  30. package/mindee/api/receipt.js +39 -0
  31. package/mindee/api/request.js +67 -0
  32. package/mindee/api/response.js +62 -0
  33. package/mindee/documents/document.js +65 -0
  34. package/mindee/documents/fields/amount.js +25 -0
  35. package/mindee/documents/fields/date.js +29 -0
  36. package/mindee/documents/fields/field.js +89 -0
  37. package/mindee/documents/fields/index.js +7 -0
  38. package/mindee/documents/fields/locale.js +30 -0
  39. package/mindee/documents/fields/orientation.js +24 -0
  40. package/mindee/documents/fields/paymentDetails.js +52 -0
  41. package/mindee/documents/fields/tax.js +47 -0
  42. package/mindee/documents/financialDocument.js +204 -0
  43. package/mindee/documents/index.js +5 -0
  44. package/mindee/documents/invoice.js +395 -0
  45. package/mindee/documents/receipt.js +272 -0
  46. package/mindee/errors/handler.js +16 -0
  47. package/mindee/index.js +36 -0
  48. package/mindee/inputs.js +155 -0
  49. package/mindee/logger.js +33 -0
  50. package/package.json +9 -5
@@ -5,7 +5,7 @@ const mindeeClient = new Client();
5
5
 
6
6
  // parsing receipt from picture
7
7
  mindeeClient.financialDocument
8
- .parse("./documents/receipts/receipt.jpg")
8
+ .parse({ input: "./documents/receipts/receipt.jpg" })
9
9
  .then((res) => {
10
10
  console.log("Success !");
11
11
  console.log(res.financialDocuments);
@@ -21,7 +21,7 @@ const base64 = fs.readFileSync("./documents/receipts/receipt.jpg", {
21
21
  encoding: "base64",
22
22
  });
23
23
  mindeeClient.financialDocument
24
- .parse(base64, "base64")
24
+ .parse({ input: base64, inputType: "base64" })
25
25
  .then((res) => {
26
26
  console.log("Success !");
27
27
  console.log(res.financialDocuments);
@@ -6,11 +6,25 @@ const mindeeClient = new Client();
6
6
 
7
7
  // parsing invoice from pdf
8
8
  mindeeClient.invoice
9
- .parse("./documents/invoices/invoice.pdf")
9
+ .parse({ input: "./documents/invoices/invoice.pdf" })
10
10
  .then((res) => {
11
11
  console.log("Success !");
12
12
  console.log(res.invoices);
13
13
  console.log(res.invoice);
14
+ console.log(res.documentType);
15
+ })
16
+ .catch((err) => {
17
+ console.error(err);
18
+ });
19
+
20
+ // parsing credit note from pdf
21
+ mindeeClient.invoice
22
+ .parse({ input: "./documents/invoices/credit_note.pdf" })
23
+ .then((res) => {
24
+ console.log("Success !");
25
+ console.log(res.invoices);
26
+ console.log(res.invoice);
27
+ console.log(res.documentType);
14
28
  })
15
29
  .catch((err) => {
16
30
  console.error(err);
@@ -18,9 +32,10 @@ mindeeClient.invoice
18
32
 
19
33
  // // parsing invoice from multiple page pdf
20
34
  mindeeClient.invoice
21
- .parse("./documents/invoices/invoice_6p.pdf")
35
+ .parse({ input: "./documents/invoices/invoice_6p.pdf" })
22
36
  .then((res) => {
23
37
  console.log("Success !");
38
+ console.log(res.documentType);
24
39
  console.log(res.invoices);
25
40
  console.log(res.invoice);
26
41
  })
@@ -33,9 +48,10 @@ const base64 = fs.readFileSync("./documents/invoices/invoice.pdf", {
33
48
  encoding: "base64",
34
49
  });
35
50
  mindeeClient.invoice
36
- .parse(base64, "base64")
51
+ .parse({ input: base64, inputType: "base64" })
37
52
  .then((res) => {
38
53
  console.log("Success !");
54
+ console.log(res.documentType);
39
55
  console.log(res.invoices);
40
56
  console.log(res.invoice);
41
57
  })
@@ -46,9 +62,10 @@ mindeeClient.invoice
46
62
  // parsing invoice from stream
47
63
  const stream = fs.createReadStream("./documents/invoices/invoice.pdf");
48
64
  mindeeClient.invoice
49
- .parse(stream, "stream")
65
+ .parse({ input: stream, inputType: "stream" })
50
66
  .then((res) => {
51
67
  console.log("Success !");
68
+ console.log(res.documentType);
52
69
  console.log(res.invoices);
53
70
  console.log(res.invoice);
54
71
  })
@@ -6,7 +6,7 @@ const mindeeClient = new Client();
6
6
 
7
7
  // parsing receipt from picture
8
8
  mindeeClient.receipt
9
- .parse("./documents/receipts/receipt.jpg")
9
+ .parse({ input: "./documents/receipts/receipt.jpg" })
10
10
  .then((res) => {
11
11
  console.log("Success !");
12
12
  console.log(res.receipts);
@@ -21,7 +21,7 @@ const base64 = fs.readFileSync("./documents/receipts/receipt.jpg", {
21
21
  encoding: "base64",
22
22
  });
23
23
  mindeeClient.receipt
24
- .parse(base64, "base64")
24
+ .parse({ input: base64, inputType: "base64" })
25
25
  .then((res) => {
26
26
  console.log("Success !");
27
27
  console.log(res.receipts);
@@ -34,7 +34,7 @@ mindeeClient.receipt
34
34
  // parsing receipt from stream
35
35
  const stream = fs.createReadStream("./documents/receipts/receipt.jpg");
36
36
  mindeeClient.receipt
37
- .parse(stream, "stream")
37
+ .parse({ input: stream, inputType: "stream" })
38
38
  .then((res) => {
39
39
  console.log("Success !");
40
40
  console.log(res.receipts);
@@ -24,21 +24,25 @@ class APIFinancialDocument extends APIObject {
24
24
  */
25
25
 
26
26
 
27
- parse(file) {
28
- var _arguments = arguments,
29
- _superprop_getParse = () => super.parse,
27
+ parse(_ref) {
28
+ var _superprop_getParse = () => super.parse,
30
29
  _superprop_get_request = () => super._request,
31
30
  _this = this;
32
31
 
33
32
  return _asyncToGenerator(function* () {
34
- var inputType = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : "path";
35
- var version = _arguments.length > 2 && _arguments[2] !== undefined ? _arguments[2] : "3";
36
- var cutPdf = _arguments.length > 3 && _arguments[3] !== undefined ? _arguments[3] : true;
37
- var includeWords = _arguments.length > 4 && _arguments[4] !== undefined ? _arguments[4] : false;
33
+ var {
34
+ input,
35
+ inputType = "path",
36
+ filename = undefined,
37
+ version = "3",
38
+ cutPdf = true,
39
+ includeWords = false
40
+ } = _ref;
38
41
  var inputFile = new Input({
39
- file,
40
- inputType,
41
- cutPdf
42
+ file: input,
43
+ inputType: inputType,
44
+ filename: filename,
45
+ allowCutPdf: cutPdf
42
46
  });
43
47
  _this.apiToken = inputFile.fileExtension === "pdf" ? _this.invoiceToken : _this.receiptToken;
44
48
  yield inputFile.init();
@@ -24,30 +24,49 @@ class APIInvoice extends APIObject {
24
24
  */
25
25
 
26
26
 
27
- parse(file) {
28
- var _arguments = arguments,
29
- _superprop_getParse = () => super.parse,
27
+ parse(_ref) {
28
+ var _superprop_getParse = () => super.parse,
30
29
  _superprop_get_request = () => super._request,
31
30
  _this = this;
32
31
 
33
32
  return _asyncToGenerator(function* () {
34
- var inputType = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : "path";
35
- var version = _arguments.length > 2 && _arguments[2] !== undefined ? _arguments[2] : "2";
36
- var cutPdf = _arguments.length > 3 && _arguments[3] !== undefined ? _arguments[3] : true;
37
- var includeWords = _arguments.length > 4 && _arguments[4] !== undefined ? _arguments[4] : false;
33
+ var {
34
+ input,
35
+ inputType = "path",
36
+ filename = undefined,
37
+ version = "2",
38
+ cutPdf = true,
39
+ includeWords = false
40
+ } = _ref;
38
41
 
39
42
  _superprop_getParse().call(_this);
40
43
 
41
44
  var inputFile = new Input({
42
- file,
43
- inputType,
44
- cutPdf
45
+ file: input,
46
+ inputType: inputType,
47
+ filename: filename,
48
+ allowCutPdf: cutPdf
45
49
  });
46
50
  yield inputFile.init();
47
51
  var url = "v".concat(version, "/predict");
48
52
  return yield _superprop_get_request().call(_this, url, inputFile, includeWords);
49
53
  })();
50
54
  }
55
+ /**
56
+ @param {String} inputFile - Input object
57
+ @param {} response - HTTP response
58
+ @param {Document} documentType - Document class in {"Receipt", "Invoice", "Financial_document"}
59
+ @returns {Response}
60
+ */
61
+
62
+
63
+ wrapResponse(inputFile, response, documentType) {
64
+ var _result$httpResponse$, _result$httpResponse$2, _result$httpResponse$3, _result$httpResponse$4, _result$httpResponse$5;
65
+
66
+ var result = super.wrapResponse(inputFile, response, documentType);
67
+ result.documentType = ((_result$httpResponse$ = result.httpResponse.data) === null || _result$httpResponse$ === void 0 ? void 0 : (_result$httpResponse$2 = _result$httpResponse$.predictions) === null || _result$httpResponse$2 === void 0 ? void 0 : (_result$httpResponse$3 = _result$httpResponse$2[0]) === null || _result$httpResponse$3 === void 0 ? void 0 : (_result$httpResponse$4 = _result$httpResponse$3.document_type) === null || _result$httpResponse$4 === void 0 ? void 0 : (_result$httpResponse$5 = _result$httpResponse$4.value) === null || _result$httpResponse$5 === void 0 ? void 0 : _result$httpResponse$5.toLowerCase()) || result.documentType;
68
+ return result;
69
+ }
51
70
 
52
71
  }
53
72
 
@@ -24,24 +24,28 @@ class APIReceipt extends APIObject {
24
24
  */
25
25
 
26
26
 
27
- parse(file) {
28
- var _arguments = arguments,
29
- _superprop_getParse = () => super.parse,
27
+ parse(_ref) {
28
+ var _superprop_getParse = () => super.parse,
30
29
  _superprop_get_request = () => super._request,
31
30
  _this = this;
32
31
 
33
32
  return _asyncToGenerator(function* () {
34
- var inputType = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : "path";
35
- var version = _arguments.length > 2 && _arguments[2] !== undefined ? _arguments[2] : "3";
36
- var cutPdf = _arguments.length > 3 && _arguments[3] !== undefined ? _arguments[3] : true;
37
- var includeWords = _arguments.length > 4 && _arguments[4] !== undefined ? _arguments[4] : false;
33
+ var {
34
+ input,
35
+ inputType = "path",
36
+ filename = undefined,
37
+ version = "3",
38
+ cutPdf = true,
39
+ includeWords = false
40
+ } = _ref;
38
41
 
39
42
  _superprop_getParse().call(_this);
40
43
 
41
44
  var inputFile = new Input({
42
- file,
43
- inputType,
44
- cutPdf
45
+ file: input,
46
+ inputType: inputType,
47
+ filename: filename,
48
+ allowCutPdf: cutPdf
45
49
  });
46
50
  yield inputFile.init();
47
51
  var url = "v".concat(version, "/predict");
@@ -25,17 +25,13 @@ var request = function request(url, method, headers, input) {
25
25
  var body;
26
26
  headers["User-Agent"] = "mindee-node/".concat(sdkVersion, " node/").concat(process.version);
27
27
 
28
- if (input.inputType === "path") {
28
+ if (["path", "stream"].includes(input.inputType)) {
29
29
  var fileParams = {
30
30
  filename: input.filename
31
31
  };
32
32
  form.append("file", input.fileObject, fileParams);
33
33
  if (includeWords) form.append("include_mvision", "true");
34
34
  headers = _objectSpread(_objectSpread({}, headers), form.getHeaders());
35
- } else if (input.inputType === "stream") {
36
- form.append("file", input.fileObject);
37
- if (includeWords) form.append("include_mvision", "true");
38
- headers = _objectSpread(_objectSpread({}, headers), form.getHeaders());
39
35
  } else if (input.inputType === "base64") {
40
36
  var body_obj = {
41
37
  file: input.fileObject
@@ -59,9 +55,13 @@ var request = function request(url, method, headers, input) {
59
55
  responseBody += chunk;
60
56
  });
61
57
  res.on("end", function () {
62
- resolve(_objectSpread(_objectSpread({}, res), {}, {
63
- data: JSON.parse(responseBody)
64
- }));
58
+ try {
59
+ resolve(_objectSpread(_objectSpread({}, res), {}, {
60
+ data: JSON.parse(responseBody)
61
+ }));
62
+ } catch (error) {
63
+ console.log(responseBody);
64
+ }
65
65
  });
66
66
  });
67
67
  req.on("error", err => {
package/lib/inputs.js CHANGED
@@ -16,11 +16,20 @@ var {
16
16
  PDFDocument
17
17
  } = require("pdf-lib");
18
18
 
19
+ var concat = require("concat-stream");
20
+
21
+ var {
22
+ Base64Encode
23
+ } = require("base64-stream");
24
+
25
+ var fileType = require("file-type");
26
+
27
+ var ArrayBufferEncode = require("base64-arraybuffer");
28
+
19
29
  class Input {
20
30
  /**
21
31
  * @param {(String | Buffer)} file - the file that will be read. Either path or base64 string, or a steam
22
32
  * @param {String} inputType - the type of input used in file ("base64", "path", "dummy").
23
- * NB: in case of base64 file, only jpeg file is supported
24
33
  * NB: dummy is only used for tests purposes
25
34
  * @param {String} filename - File name of the input
26
35
  * @param {Boolean} cut_pdf: Automatically reconstruct pdf with more than 4 pages
@@ -61,45 +70,60 @@ class Input {
61
70
  var _this = this;
62
71
 
63
72
  return _asyncToGenerator(function* () {
64
- if (_this.inputType === "base64") _this.initBase64();else if (_this.inputType === "path") yield _this.initFile();else if (_this.inputType === "stream") yield _this.initStream();else _this.initDummy();
73
+ if (_this.inputType === "base64") yield _this.initBase64();else if (_this.inputType === "path") yield _this.initFile();else if (_this.inputType === "stream") yield _this.initStream();else _this.initDummy();
65
74
  })();
66
75
  }
67
76
 
68
77
  initBase64() {
69
- this.fileObject = this.file;
70
- this.filepath = undefined;
71
- this.fileExtension = undefined;
78
+ var _this2 = this;
79
+
80
+ return _asyncToGenerator(function* () {
81
+ _this2.fileObject = _this2.file;
82
+ _this2.filepath = undefined;
83
+ _this2.fileExtension = undefined;
84
+
85
+ if (_this2.allowCutPdf == true) {
86
+ var typeOfFile = yield fileType.fromBuffer(Buffer.from(_this2.fileObject, "base64"));
87
+
88
+ if (typeOfFile === undefined) {
89
+ console.error("Cannot detect mime type of: ".concat(_this2.fileObject));
90
+ } else if (typeOfFile.mime === "application/pdf") {
91
+ yield _this2.cutPdf();
92
+ }
93
+ }
94
+ })();
72
95
  }
73
96
 
74
97
  initFile() {
75
- var _this2 = this;
98
+ var _this3 = this;
76
99
 
77
100
  return _asyncToGenerator(function* () {
78
- _this2.fileObject = yield fs.readFile(_this2.file);
79
- _this2.filepath = _this2.file;
80
- _this2.filename = path.basename(_this2.file); // Check if file type is valid
101
+ _this3.fileObject = yield fs.readFile(_this3.file);
102
+ _this3.filepath = _this3.file;
103
+ _this3.filename = _this3.filename || path.basename(_this3.file); // Check if file type is valid
81
104
 
82
- var filetype = _this2.filename.split(".").pop();
105
+ var filetype = _this3.filename.split(".").pop();
83
106
 
84
- if (!(filetype in _this2.MIMETYPES)) {
85
- errorHandler.throw(new Error("File type is not allowed. It must be ".concat(Object.keys(_this2.MIMETYPES).toString())));
107
+ if (!(filetype in _this3.MIMETYPES)) {
108
+ errorHandler.throw(new Error("File type is not allowed. It must be ".concat(Object.keys(_this3.MIMETYPES).toString())));
86
109
  }
87
110
 
88
- _this2.fileExtension = _this2.MIMETYPES[filetype];
111
+ _this3.fileExtension = _this3.MIMETYPES[filetype];
89
112
 
90
- if (_this2.fileExtension === "application/pdf" && _this2.allowCutPdf == true) {
91
- yield _this2.cutPdf();
113
+ if (_this3.fileExtension === "application/pdf" && _this3.allowCutPdf == true) {
114
+ yield _this3.cutPdf();
92
115
  }
93
116
  })();
94
117
  }
95
118
 
96
119
  initStream() {
97
- var _this3 = this;
120
+ var _this4 = this;
98
121
 
99
122
  return _asyncToGenerator(function* () {
100
- _this3.fileObject = _this3.file;
101
- _this3.filepath = undefined;
102
- _this3.filename = undefined;
123
+ var file = yield _this4.streamToBase64(_this4.file);
124
+ _this4.file = file;
125
+ _this4.inputType = "base64";
126
+ yield _this4.initBase64();
103
127
  })();
104
128
  }
105
129
 
@@ -109,23 +133,53 @@ class Input {
109
133
  this.filepath = "";
110
134
  this.fileExtension = "";
111
135
  }
136
+ /**
137
+ * Convert ReadableStream to Base64 encoded String
138
+ *
139
+ * @param {*} stream ReadableStream to encode
140
+ * @returns Base64 encoded String
141
+ */
142
+
143
+
144
+ streamToBase64(stream) {
145
+ return _asyncToGenerator(function* () {
146
+ return new Promise((resolve, reject) => {
147
+ var base64 = new Base64Encode();
148
+
149
+ var cbConcat = base64 => {
150
+ resolve(base64);
151
+ };
152
+
153
+ stream.pipe(base64).pipe(concat(cbConcat)).on("error", error => {
154
+ reject(error);
155
+ });
156
+ });
157
+ })();
158
+ }
112
159
  /** Cut PDF if pages > 5 */
113
160
 
114
161
 
115
162
  cutPdf() {
116
- var _this4 = this;
163
+ var _this5 = this;
117
164
 
118
165
  return _asyncToGenerator(function* () {
119
166
  // convert document to PDFDocument & cut CUT_PDF_SIZE - 1 first pages and last page
120
- var pdfDocument = yield PDFDocument.load(_this4.fileObject);
167
+ var pdfDocument = yield PDFDocument.load(_this5.fileObject, {
168
+ ignoreEncryption: true
169
+ });
121
170
  var splitedPdfDocument = yield PDFDocument.create();
122
171
  var pdfLength = pdfDocument.getPageCount();
123
- if (pdfLength <= _this4.CUT_PDF_SIZE) return;
124
- var pagesNumbers = [...Array(_this4.CUT_PDF_SIZE - 1).keys(), pdfLength - 1];
172
+ if (pdfLength <= _this5.CUT_PDF_SIZE) return;
173
+ var pagesNumbers = [...Array(_this5.CUT_PDF_SIZE - 1).keys(), pdfLength - 1];
125
174
  var pages = yield splitedPdfDocument.copyPages(pdfDocument, pagesNumbers);
126
175
  pages.forEach(page => splitedPdfDocument.addPage(page));
127
176
  var data = yield splitedPdfDocument.save();
128
- _this4.fileObject = Buffer.from(data);
177
+
178
+ if (_this5.inputType === "path") {
179
+ _this5.fileObject = Buffer.from(data);
180
+ } else if (_this5.inputType === "base64") {
181
+ _this5.fileObject = ArrayBufferEncode.encode(data);
182
+ }
129
183
  })();
130
184
  }
131
185
 
@@ -0,0 +1,45 @@
1
+ const APIObject = require("./object");
2
+ const Input = require("../inputs");
3
+
4
+ class APIFinancialDocument extends APIObject {
5
+ constructor(invoiceToken, receiptToken) {
6
+ super(undefined, "financialDocument");
7
+ this.invoiceToken = invoiceToken;
8
+ this.receiptToken = receiptToken;
9
+ }
10
+
11
+ /**
12
+ * @param {String} file: Receipt filepath (allowed jpg, png, tiff, pdf)
13
+ * @param {String} inputType: String in {'path', 'stream', 'base64'}
14
+ * @param {Boolean} includeWords: extract all words into http_response
15
+ * @param {String} version: expense_receipt api version
16
+ * @param {Boolean} cutPdf: Automatically reconstruct pdf with more than 4 pages
17
+ * @returns {Response} Wrapped response with Receipts objects parsed
18
+ */
19
+ async parse({
20
+ input,
21
+ inputType = "path",
22
+ filename = undefined,
23
+ version = "3",
24
+ cutPdf = true,
25
+ includeWords = false,
26
+ }) {
27
+ const inputFile = new Input({
28
+ file: input,
29
+ inputType: inputType,
30
+ filename: filename,
31
+ allowCutPdf: cutPdf,
32
+ });
33
+ this.apiToken =
34
+ inputFile.fileExtension === "pdf" ? this.invoiceToken : this.receiptToken;
35
+ await inputFile.init();
36
+ const url =
37
+ inputFile.fileExtension === "pdf"
38
+ ? "/invoices/v1/predict"
39
+ : "/expense_receipts/v3/predict";
40
+ super.parse();
41
+ return await super._request(url, inputFile, version, includeWords);
42
+ }
43
+ }
44
+
45
+ module.exports = APIFinancialDocument;
@@ -0,0 +1,5 @@
1
+ exports.APIObject = require("./object");
2
+ exports.APIReceipt = require("./receipt");
3
+ exports.Response = require("./response");
4
+ exports.Request = require("./response");
5
+ exports.Invoice = require("./invoice");
@@ -0,0 +1,53 @@
1
+ const APIObject = require("./object");
2
+ const Input = require("../inputs");
3
+
4
+ class APIInvoice extends APIObject {
5
+ constructor(apiToken = undefined) {
6
+ super(apiToken, "invoice");
7
+ this.baseUrl = `${this.baseUrl}/invoices/`;
8
+ }
9
+
10
+ /**
11
+ * @param {Boolean} includeWords: , extract all words into http_response
12
+ * @param {Boolean} cutPdf: Automatically reconstruct pdf with more than 4 pages
13
+ * @param {String} inputType: String in {'path', 'stream', 'base64'}
14
+ * @param {String} file: Receipt filepath (allowed jpg, png, tiff, pdf)
15
+ * @param {String} version: expense_receipt api version
16
+ * @returns {Response} Wrapped response with Receipts objects parsed
17
+ */
18
+ async parse({
19
+ input,
20
+ inputType = "path",
21
+ filename = undefined,
22
+ version = "2",
23
+ cutPdf = true,
24
+ includeWords = false,
25
+ }) {
26
+ super.parse();
27
+ const inputFile = new Input({
28
+ file: input,
29
+ inputType: inputType,
30
+ filename: filename,
31
+ allowCutPdf: cutPdf,
32
+ });
33
+ await inputFile.init();
34
+ const url = `v${version}/predict`;
35
+ return await super._request(url, inputFile, includeWords);
36
+ }
37
+
38
+ /**
39
+ @param {String} inputFile - Input object
40
+ @param {} response - HTTP response
41
+ @param {Document} documentType - Document class in {"Receipt", "Invoice", "Financial_document"}
42
+ @returns {Response}
43
+ */
44
+ wrapResponse(inputFile, response, documentType) {
45
+ let result = super.wrapResponse(inputFile, response, documentType);
46
+ result.documentType =
47
+ result.httpResponse.data?.predictions?.[0]?.document_type?.value?.toLowerCase() ||
48
+ result.documentType;
49
+ return result;
50
+ }
51
+ }
52
+
53
+ module.exports = APIInvoice;
@@ -0,0 +1,82 @@
1
+ const Response = require("./response");
2
+ const errorHandler = require("../errors/handler");
3
+ const request = require("./request");
4
+
5
+ /**
6
+ * Base class for APIs (APIReceipt & APIInvoice)
7
+ * @param {String} apiToken - Token of the API used for parsing document
8
+ * @param {String} apiName - Name of the API used for parsing document
9
+ */
10
+ class APIObject {
11
+ constructor(apiToken = undefined, apiName = "") {
12
+ this.apiToken = apiToken;
13
+ this.baseUrl = "https://api.mindee.net/products";
14
+ this.apiName = apiName;
15
+ }
16
+
17
+ /**
18
+ */
19
+ parse() {
20
+ if (!this.apiToken) {
21
+ errorHandler.throw({
22
+ error: new Error(
23
+ `Missing API token for ${this.apiName}. \
24
+ Have you create a mindee Client with a ${this.apiName}Token in parameters ?`
25
+ ),
26
+ });
27
+ }
28
+ }
29
+
30
+ /**
31
+ @param {String} url - API url for request
32
+ @param {Input} inputFile - input file for API
33
+ @param {Boolean} includeWords - Include Mindee vision words in Response
34
+ @returns {Response}
35
+ */
36
+ async _request(url, inputFile, includeWords = false) {
37
+ const headers = {
38
+ "X-Inferuser-Token": this.apiToken,
39
+ };
40
+ const response = await request(
41
+ `${this.baseUrl}${url}`,
42
+ "POST",
43
+ headers,
44
+ inputFile,
45
+ includeWords
46
+ );
47
+ return this.wrapResponse(inputFile, response, this.apiName);
48
+ }
49
+
50
+ /**
51
+ @param {String} inputFile - Input object
52
+ @param {} response - HTTP response
53
+ @param {Document} documentType - Document class in {"Receipt", "Invoice", "Financial_document"}
54
+ @returns {Response}
55
+ */
56
+ wrapResponse(inputFile, response, documentType) {
57
+ if (response.statusCode != 200) {
58
+ const errorMessage = JSON.stringify(response.data, null, 4);
59
+ errorHandler.throw(
60
+ new Error(
61
+ `${this.apiName} API ${response.statusCode} HTTP error: ${errorMessage}`
62
+ ),
63
+ false
64
+ );
65
+ return new Response({
66
+ httpResponse: response,
67
+ documentType: documentType,
68
+ document: undefined,
69
+ input: inputFile,
70
+ error: true,
71
+ });
72
+ }
73
+ return new Response({
74
+ httpResponse: response,
75
+ documentType: documentType,
76
+ document: inputFile,
77
+ input: inputFile,
78
+ });
79
+ }
80
+ }
81
+
82
+ module.exports = APIObject;
@@ -0,0 +1,39 @@
1
+ const APIObject = require("./object");
2
+ const Input = require("../inputs");
3
+
4
+ class APIReceipt extends APIObject {
5
+ constructor(apiToken = undefined) {
6
+ super(apiToken, "receipt");
7
+ this.baseUrl = `${this.baseUrl}/expense_receipts/`;
8
+ }
9
+
10
+ /**
11
+ * @param {String} file: Receipt filepath (allowed jpg, png, tiff, pdf)
12
+ * @param {String} inputType: String in {'path', 'stream', 'base64'}
13
+ * @param {Boolean} includeWords: extract all words into http_response
14
+ * @param {String} version: expense_receipt api version
15
+ * @param {Boolean} cutPdf: Automatically reconstruct pdf with more than 4 pages
16
+ * @returns {Response} Wrapped response with Receipts objects parsed
17
+ */
18
+ async parse({
19
+ input,
20
+ inputType = "path",
21
+ filename = undefined,
22
+ version = "3",
23
+ cutPdf = true,
24
+ includeWords = false,
25
+ }) {
26
+ super.parse();
27
+ const inputFile = new Input({
28
+ file: input,
29
+ inputType: inputType,
30
+ filename: filename,
31
+ allowCutPdf: cutPdf,
32
+ });
33
+ await inputFile.init();
34
+ const url = `v${version}/predict`;
35
+ return await super._request(url, inputFile, includeWords);
36
+ }
37
+ }
38
+
39
+ module.exports = APIReceipt;