mindee 1.4.0 → 2.0.0
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/CHANGELOG.md +33 -19
- package/README.md +43 -127
- package/bin/mindee +3 -0
- package/dist/package.json +70 -0
- package/dist/src/api/endpoint.d.ts +29 -0
- package/dist/src/api/endpoint.js +148 -0
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.js +18 -0
- package/dist/src/api/response.d.ts +52 -0
- package/dist/src/api/response.js +107 -0
- package/dist/src/cli.d.ts +1 -0
- package/dist/src/cli.js +117 -0
- package/dist/src/client.d.ts +48 -0
- package/dist/src/client.js +134 -0
- package/dist/src/constants.d.ts +13 -0
- package/dist/src/constants.js +54 -0
- package/dist/src/documents/custom.d.ts +14 -0
- package/dist/src/documents/custom.js +48 -0
- package/dist/src/documents/document.d.ts +38 -0
- package/dist/src/documents/document.js +60 -0
- package/dist/src/documents/documentConfig.d.ts +44 -0
- package/dist/src/documents/documentConfig.js +121 -0
- package/dist/src/documents/financialDocument.d.ts +32 -0
- package/dist/src/documents/financialDocument.js +130 -0
- package/dist/src/documents/index.d.ts +12 -0
- package/dist/src/documents/index.js +20 -0
- package/dist/src/documents/invoice.d.ts +37 -0
- package/dist/src/documents/invoice.js +303 -0
- package/dist/src/documents/passport.d.ts +36 -0
- package/dist/src/documents/passport.js +218 -0
- package/dist/src/documents/receipt.d.ts +24 -0
- package/dist/src/documents/receipt.js +157 -0
- package/dist/src/errors/handler.d.ts +7 -0
- package/dist/src/errors/handler.js +18 -0
- package/dist/src/fields/amount.d.ts +13 -0
- package/dist/src/fields/amount.js +34 -0
- package/dist/src/fields/companyRegistration.d.ts +6 -0
- package/dist/src/fields/companyRegistration.js +11 -0
- package/dist/src/fields/customDocs.d.ts +42 -0
- package/dist/src/fields/customDocs.js +61 -0
- package/dist/src/fields/date.d.ts +12 -0
- package/dist/src/fields/date.js +25 -0
- package/dist/src/fields/field.d.ts +74 -0
- package/dist/src/fields/field.js +106 -0
- package/dist/src/fields/fullText.d.ts +24 -0
- package/dist/src/fields/fullText.js +89 -0
- package/dist/src/fields/index.d.ts +11 -0
- package/dist/src/fields/index.js +27 -0
- package/dist/src/fields/locale.d.ts +13 -0
- package/dist/src/fields/locale.js +40 -0
- package/dist/src/fields/orientation.d.ts +10 -0
- package/dist/src/fields/orientation.js +22 -0
- package/dist/src/fields/paymentDetails.d.ts +31 -0
- package/dist/src/fields/paymentDetails.js +58 -0
- package/dist/src/fields/tax.d.ts +30 -0
- package/dist/src/fields/tax.js +51 -0
- package/dist/src/geometry.d.ts +59 -0
- package/dist/src/geometry.js +113 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +12 -0
- package/dist/src/inputs.d.ts +69 -0
- package/dist/src/inputs.js +223 -0
- package/dist/src/logger.d.ts +20 -0
- package/dist/src/logger.js +35 -0
- package/package.json +38 -28
- package/mindee/api/financialDocument.js +0 -47
- package/mindee/api/index.js +0 -5
- package/mindee/api/invoice.js +0 -53
- package/mindee/api/object.js +0 -82
- package/mindee/api/receipt.js +0 -39
- package/mindee/api/request.js +0 -72
- package/mindee/api/response.js +0 -80
- package/mindee/documents/document.js +0 -69
- package/mindee/documents/fields/amount.js +0 -25
- package/mindee/documents/fields/date.js +0 -29
- package/mindee/documents/fields/field.js +0 -86
- package/mindee/documents/fields/index.js +0 -7
- package/mindee/documents/fields/locale.js +0 -30
- package/mindee/documents/fields/orientation.js +0 -24
- package/mindee/documents/fields/paymentDetails.js +0 -52
- package/mindee/documents/fields/tax.js +0 -47
- package/mindee/documents/financialDocument.js +0 -269
- package/mindee/documents/index.js +0 -5
- package/mindee/documents/invoice.js +0 -456
- package/mindee/documents/receipt.js +0 -287
- package/mindee/errors/handler.js +0 -16
- package/mindee/index.js +0 -39
- package/mindee/inputs.js +0 -181
- package/mindee/logger.js +0 -34
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PassportResponse = exports.FinancialDocResponse = exports.ReceiptResponse = exports.InvoiceResponse = exports.StandardProductResponse = exports.CustomResponse = exports.Response = void 0;
|
|
4
|
+
const documents_1 = require("../documents");
|
|
5
|
+
const fields_1 = require("../fields");
|
|
6
|
+
/**
|
|
7
|
+
* Base class for all responses.
|
|
8
|
+
*/
|
|
9
|
+
class Response {
|
|
10
|
+
constructor(params) {
|
|
11
|
+
this.pages = [];
|
|
12
|
+
this.httpResponse = params.httpResponse;
|
|
13
|
+
this.documentType = params.documentType;
|
|
14
|
+
this.inputFile = params.input;
|
|
15
|
+
}
|
|
16
|
+
getPageText(httpDataDocument, pageId) {
|
|
17
|
+
const pageText = new fields_1.FullText();
|
|
18
|
+
if ("ocr" in httpDataDocument &&
|
|
19
|
+
Object.keys(httpDataDocument.ocr).length > 0) {
|
|
20
|
+
pageText.words =
|
|
21
|
+
httpDataDocument.ocr["mvision-v1"].pages[pageId].all_words;
|
|
22
|
+
}
|
|
23
|
+
return pageText;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.Response = Response;
|
|
27
|
+
/**
|
|
28
|
+
* Class for all constructed (API Builder) endpoint responses.
|
|
29
|
+
*/
|
|
30
|
+
class CustomResponse extends Response {
|
|
31
|
+
constructor(params) {
|
|
32
|
+
super(params);
|
|
33
|
+
if (!params.error) {
|
|
34
|
+
this.formatResponse();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
formatResponse() {
|
|
38
|
+
const httpDataDocument = this.httpResponse.data.document;
|
|
39
|
+
httpDataDocument.inference.pages.forEach((apiPage) => {
|
|
40
|
+
this.pages.push(new documents_1.CustomDocument({
|
|
41
|
+
apiPrediction: apiPage.prediction,
|
|
42
|
+
inputFile: this.inputFile,
|
|
43
|
+
pageId: apiPage.id,
|
|
44
|
+
documentType: this.documentType,
|
|
45
|
+
}));
|
|
46
|
+
});
|
|
47
|
+
this.document = new documents_1.CustomDocument({
|
|
48
|
+
apiPrediction: httpDataDocument.inference.prediction,
|
|
49
|
+
inputFile: this.inputFile,
|
|
50
|
+
documentType: this.documentType,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.CustomResponse = CustomResponse;
|
|
55
|
+
/**
|
|
56
|
+
* Generic class for all standard (Off-the-Shelf) endpoint responses.
|
|
57
|
+
*/
|
|
58
|
+
class StandardProductResponse extends Response {
|
|
59
|
+
constructor(documentClass, params) {
|
|
60
|
+
super(params);
|
|
61
|
+
this.documentClass = documentClass;
|
|
62
|
+
if (!params.error) {
|
|
63
|
+
this.formatResponse();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
formatResponse() {
|
|
67
|
+
const httpDataDocument = this.httpResponse.data.document;
|
|
68
|
+
httpDataDocument.inference.pages.forEach((apiPage) => {
|
|
69
|
+
const pageText = this.getPageText(httpDataDocument, apiPage.id);
|
|
70
|
+
this.pages.push(new this.documentClass({
|
|
71
|
+
apiPrediction: apiPage.prediction,
|
|
72
|
+
inputFile: this.inputFile,
|
|
73
|
+
pageId: apiPage.id,
|
|
74
|
+
fullText: pageText,
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
this.document = new this.documentClass({
|
|
78
|
+
apiPrediction: httpDataDocument.inference.prediction,
|
|
79
|
+
inputFile: this.inputFile,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.StandardProductResponse = StandardProductResponse;
|
|
84
|
+
class InvoiceResponse extends StandardProductResponse {
|
|
85
|
+
constructor(params) {
|
|
86
|
+
super(documents_1.Invoice, params);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.InvoiceResponse = InvoiceResponse;
|
|
90
|
+
class ReceiptResponse extends StandardProductResponse {
|
|
91
|
+
constructor(params) {
|
|
92
|
+
super(documents_1.Receipt, params);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.ReceiptResponse = ReceiptResponse;
|
|
96
|
+
class FinancialDocResponse extends StandardProductResponse {
|
|
97
|
+
constructor(params) {
|
|
98
|
+
super(documents_1.FinancialDocument, params);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.FinancialDocResponse = FinancialDocResponse;
|
|
102
|
+
class PassportResponse extends StandardProductResponse {
|
|
103
|
+
constructor(params) {
|
|
104
|
+
super(documents_1.Passport, params);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.PassportResponse = PassportResponse;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function cli(): void;
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.cli = void 0;
|
|
13
|
+
const commander_1 = require("commander");
|
|
14
|
+
const documents_1 = require("./documents");
|
|
15
|
+
const api_1 = require("./api");
|
|
16
|
+
const client_1 = require("./client");
|
|
17
|
+
const constants_1 = require("./constants");
|
|
18
|
+
const program = new commander_1.Command();
|
|
19
|
+
const COMMAND_INVOICE = "invoice";
|
|
20
|
+
const COMMAND_RECEIPT = "receipt";
|
|
21
|
+
const COMMAND_PASSPORT = "passport";
|
|
22
|
+
const COMMAND_FINANCIAL = "financial";
|
|
23
|
+
const COMMAND_CUSTOM = "custom";
|
|
24
|
+
const CLI_COMMAND_CONFIG = new Map([
|
|
25
|
+
[COMMAND_INVOICE, constants_1.ProductConfigs.getByDocType(documents_1.DOC_TYPE_INVOICE)],
|
|
26
|
+
[COMMAND_RECEIPT, constants_1.ProductConfigs.getByDocType(documents_1.DOC_TYPE_RECEIPT)],
|
|
27
|
+
[COMMAND_PASSPORT, constants_1.ProductConfigs.getByDocType(documents_1.DOC_TYPE_PASSPORT)],
|
|
28
|
+
[COMMAND_FINANCIAL, constants_1.ProductConfigs.getByDocType(documents_1.DOC_TYPE_FINANCIAL)],
|
|
29
|
+
[COMMAND_CUSTOM, constants_1.ProductConfigs.getByDocType(documents_1.DOC_TYPE_CUSTOM)],
|
|
30
|
+
]);
|
|
31
|
+
function predictCall(command, inputPath, options) {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
const conf = CLI_COMMAND_CONFIG.get(command);
|
|
34
|
+
if (conf === undefined) {
|
|
35
|
+
throw new Error(`Invalid document type ${command}`);
|
|
36
|
+
}
|
|
37
|
+
const mindeeClient = new client_1.Client({
|
|
38
|
+
apiKey: options.apiKey,
|
|
39
|
+
debug: options.debug,
|
|
40
|
+
});
|
|
41
|
+
if (command === COMMAND_CUSTOM) {
|
|
42
|
+
mindeeClient.addEndpoint({
|
|
43
|
+
accountName: options.user,
|
|
44
|
+
documentType: options.documentType,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const doc = mindeeClient.docFromPath(inputPath);
|
|
48
|
+
const params = {
|
|
49
|
+
docType: command === COMMAND_CUSTOM ? options.documentType : conf.docType,
|
|
50
|
+
username: command === COMMAND_CUSTOM ? options.user : api_1.STANDARD_API_OWNER,
|
|
51
|
+
cutPages: options.cutPages,
|
|
52
|
+
fullText: options.fullText,
|
|
53
|
+
};
|
|
54
|
+
// Tried setting the response by using the responseClass property in constants.PRODUCTS_CONFIG
|
|
55
|
+
// This compiled, but threw an exception:
|
|
56
|
+
// TypeError: responseType is not a constructor
|
|
57
|
+
//
|
|
58
|
+
// So using a switch to explicitly set the response class parameter. Ugly, but works.
|
|
59
|
+
// Improvements welcome!
|
|
60
|
+
let response;
|
|
61
|
+
switch (command) {
|
|
62
|
+
case COMMAND_INVOICE:
|
|
63
|
+
response = yield doc.parse(api_1.InvoiceResponse, params);
|
|
64
|
+
break;
|
|
65
|
+
case COMMAND_RECEIPT:
|
|
66
|
+
response = yield doc.parse(api_1.ReceiptResponse, params);
|
|
67
|
+
break;
|
|
68
|
+
case COMMAND_FINANCIAL:
|
|
69
|
+
response = yield doc.parse(api_1.FinancialDocResponse, params);
|
|
70
|
+
break;
|
|
71
|
+
case COMMAND_PASSPORT:
|
|
72
|
+
response = yield doc.parse(api_1.PassportResponse, params);
|
|
73
|
+
break;
|
|
74
|
+
case COMMAND_CUSTOM:
|
|
75
|
+
response = yield doc.parse(api_1.CustomResponse, params);
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
throw `Unhandled command: ${command}`;
|
|
79
|
+
}
|
|
80
|
+
if (response.document) {
|
|
81
|
+
console.log(`\n${response.document}`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
function cli() {
|
|
86
|
+
program.name("mindee");
|
|
87
|
+
program.option("-d, --debug", "high verbosity mode");
|
|
88
|
+
CLI_COMMAND_CONFIG.forEach((info, name) => {
|
|
89
|
+
const prog = program.command(name);
|
|
90
|
+
prog.description(info.description);
|
|
91
|
+
prog.option("-k, --api-key <api_key>", "API key for document endpoint");
|
|
92
|
+
prog.option("-C, --no-cut-pages", "Don't cut document pages");
|
|
93
|
+
if (info.fullText) {
|
|
94
|
+
prog.option("-t, --full-text", "Include full document text in response");
|
|
95
|
+
}
|
|
96
|
+
if (name === COMMAND_CUSTOM) {
|
|
97
|
+
prog.requiredOption("-u, --user <username>", "API account name for the endpoint");
|
|
98
|
+
prog.option("-v, --version <version>", "API account name for the endpoint");
|
|
99
|
+
prog.argument("<endpoint_name>", "API endpoint name");
|
|
100
|
+
}
|
|
101
|
+
prog.argument("<input_path>", "Full path to the file");
|
|
102
|
+
if (name === COMMAND_CUSTOM) {
|
|
103
|
+
prog.action((endpointName, inputPath, options, command) => {
|
|
104
|
+
const allOptions = Object.assign(Object.assign(Object.assign({}, program.opts()), options), { documentType: endpointName });
|
|
105
|
+
predictCall(command.name(), inputPath, allOptions);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
prog.action((inputPath, options, command) => {
|
|
110
|
+
const allOptions = Object.assign(Object.assign(Object.assign({}, program.opts()), options), { endpointName: undefined });
|
|
111
|
+
predictCall(command.name(), inputPath, allOptions);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
program.parse(process.argv);
|
|
116
|
+
}
|
|
117
|
+
exports.cli = cli;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Input } from "./inputs";
|
|
3
|
+
import { Response } from "./api";
|
|
4
|
+
import { Document } from "./documents";
|
|
5
|
+
import { DocumentConfig, responseSig } from "./documents/documentConfig";
|
|
6
|
+
import { ReadStream } from "fs";
|
|
7
|
+
declare type DocConfigs = Map<string[], DocumentConfig>;
|
|
8
|
+
interface PredictOptions {
|
|
9
|
+
docType?: string;
|
|
10
|
+
username?: string;
|
|
11
|
+
cutPages?: boolean;
|
|
12
|
+
fullText?: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare class DocumentClient {
|
|
15
|
+
inputDoc: Input;
|
|
16
|
+
docConfigs: DocConfigs;
|
|
17
|
+
constructor(inputDoc: Input, docConfigs: DocConfigs);
|
|
18
|
+
parse<RespType extends Response<Document>>(responseClass: responseSig<RespType>, params?: PredictOptions): Promise<RespType>;
|
|
19
|
+
protected getDocType(responseClass: string): string;
|
|
20
|
+
}
|
|
21
|
+
interface customConfigParams {
|
|
22
|
+
accountName: string;
|
|
23
|
+
documentType: string;
|
|
24
|
+
version?: string;
|
|
25
|
+
}
|
|
26
|
+
interface ClientOptions {
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
throwOnError?: boolean;
|
|
29
|
+
debug?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Mindee Client
|
|
33
|
+
*/
|
|
34
|
+
export declare class Client {
|
|
35
|
+
readonly docConfigs: DocConfigs;
|
|
36
|
+
protected apiKey: string;
|
|
37
|
+
/**
|
|
38
|
+
* @param options
|
|
39
|
+
*/
|
|
40
|
+
constructor(options?: ClientOptions);
|
|
41
|
+
protected addStandardEndpoints(): void;
|
|
42
|
+
addEndpoint({ accountName, documentType, version, }: customConfigParams): this;
|
|
43
|
+
docFromPath(inputPath: string): DocumentClient;
|
|
44
|
+
docFromBase64(inputString: string, filename: string): DocumentClient;
|
|
45
|
+
docFromStream(inputStream: ReadStream, filename: string): DocumentClient;
|
|
46
|
+
docFromBytes(inputBytes: string, filename: string): DocumentClient;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.Client = void 0;
|
|
13
|
+
const inputs_1 = require("./inputs");
|
|
14
|
+
const api_1 = require("./api");
|
|
15
|
+
const documents_1 = require("./documents");
|
|
16
|
+
const documentConfig_1 = require("./documents/documentConfig");
|
|
17
|
+
const handler_1 = require("./errors/handler");
|
|
18
|
+
const logger_1 = require("./logger");
|
|
19
|
+
const constants_1 = require("./constants");
|
|
20
|
+
class DocumentClient {
|
|
21
|
+
constructor(inputDoc, docConfigs) {
|
|
22
|
+
this.inputDoc = inputDoc;
|
|
23
|
+
this.docConfigs = docConfigs;
|
|
24
|
+
}
|
|
25
|
+
parse(responseClass, params = {
|
|
26
|
+
docType: "",
|
|
27
|
+
username: "",
|
|
28
|
+
cutPages: true,
|
|
29
|
+
fullText: false,
|
|
30
|
+
}) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
// seems like there should be a better way of doing this
|
|
33
|
+
const fullText = (params === null || params === void 0 ? void 0 : params.fullText) !== undefined ? params.fullText : false;
|
|
34
|
+
const cutPages = (params === null || params === void 0 ? void 0 : params.cutPages) !== undefined ? params.cutPages : true;
|
|
35
|
+
const docType = params.docType === undefined || params.docType === ""
|
|
36
|
+
? this.getDocType(responseClass.name)
|
|
37
|
+
: params.docType;
|
|
38
|
+
const found = [];
|
|
39
|
+
this.docConfigs.forEach((config, configKey) => {
|
|
40
|
+
if (configKey[1] === docType) {
|
|
41
|
+
found.push(configKey);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
if (found.length === 0) {
|
|
45
|
+
throw `Document type not configured: '${docType}'`;
|
|
46
|
+
}
|
|
47
|
+
let configKey = [];
|
|
48
|
+
if (found.length === 1) {
|
|
49
|
+
configKey = found[0];
|
|
50
|
+
}
|
|
51
|
+
else if (params.username) {
|
|
52
|
+
configKey = [params.username, docType];
|
|
53
|
+
}
|
|
54
|
+
const docConfig = this.docConfigs.get(configKey);
|
|
55
|
+
if (docConfig === undefined) {
|
|
56
|
+
// TODO: raise error printing all usernames
|
|
57
|
+
throw `Couldn't find the config '${configKey}'`;
|
|
58
|
+
}
|
|
59
|
+
return yield docConfig.predict(responseClass, {
|
|
60
|
+
inputDoc: this.inputDoc,
|
|
61
|
+
includeWords: fullText,
|
|
62
|
+
cutPages: cutPages,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
getDocType(responseClass) {
|
|
67
|
+
return constants_1.ProductConfigs.getByResponseClassName(responseClass).docType;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Mindee Client
|
|
72
|
+
*/
|
|
73
|
+
class Client {
|
|
74
|
+
/**
|
|
75
|
+
* @param options
|
|
76
|
+
*/
|
|
77
|
+
constructor(options) {
|
|
78
|
+
const throwOnError = (options === null || options === void 0 ? void 0 : options.throwOnError) === undefined ? true : options.throwOnError;
|
|
79
|
+
const debug = (options === null || options === void 0 ? void 0 : options.debug) === undefined ? false : options.debug;
|
|
80
|
+
this.apiKey = (options === null || options === void 0 ? void 0 : options.apiKey) === undefined ? "" : options.apiKey;
|
|
81
|
+
this.docConfigs = new Map();
|
|
82
|
+
handler_1.errorHandler.throwOnError = throwOnError;
|
|
83
|
+
logger_1.logger.level =
|
|
84
|
+
(debug !== null && debug !== void 0 ? debug : process.env.MINDEE_DEBUG)
|
|
85
|
+
? logger_1.LOG_LEVELS["debug"]
|
|
86
|
+
: logger_1.LOG_LEVELS["warn"];
|
|
87
|
+
logger_1.logger.debug("Client initialized");
|
|
88
|
+
this.addStandardEndpoints();
|
|
89
|
+
}
|
|
90
|
+
// TODO: init only those endpoints we actually need.
|
|
91
|
+
addStandardEndpoints() {
|
|
92
|
+
this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.DOC_TYPE_INVOICE], new documentConfig_1.InvoiceConfig(this.apiKey));
|
|
93
|
+
this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.DOC_TYPE_RECEIPT], new documentConfig_1.ReceiptConfig(this.apiKey));
|
|
94
|
+
this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.DOC_TYPE_FINANCIAL], new documentConfig_1.FinancialDocConfig(this.apiKey));
|
|
95
|
+
this.docConfigs.set([api_1.STANDARD_API_OWNER, documents_1.DOC_TYPE_PASSPORT], new documentConfig_1.PassportConfig(this.apiKey));
|
|
96
|
+
}
|
|
97
|
+
addEndpoint({ accountName, documentType, version = "1", }) {
|
|
98
|
+
this.docConfigs.set([accountName, documentType], new documentConfig_1.CustomDocConfig({
|
|
99
|
+
accountName: accountName,
|
|
100
|
+
documentType: documentType,
|
|
101
|
+
version: version,
|
|
102
|
+
apiKey: this.apiKey,
|
|
103
|
+
}));
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
docFromPath(inputPath) {
|
|
107
|
+
const doc = new inputs_1.PathInput({
|
|
108
|
+
inputPath: inputPath,
|
|
109
|
+
});
|
|
110
|
+
return new DocumentClient(doc, this.docConfigs);
|
|
111
|
+
}
|
|
112
|
+
docFromBase64(inputString, filename) {
|
|
113
|
+
const doc = new inputs_1.Base64Input({
|
|
114
|
+
inputString: inputString,
|
|
115
|
+
filename: filename,
|
|
116
|
+
});
|
|
117
|
+
return new DocumentClient(doc, this.docConfigs);
|
|
118
|
+
}
|
|
119
|
+
docFromStream(inputStream, filename) {
|
|
120
|
+
const doc = new inputs_1.StreamInput({
|
|
121
|
+
inputStream: inputStream,
|
|
122
|
+
filename: filename,
|
|
123
|
+
});
|
|
124
|
+
return new DocumentClient(doc, this.docConfigs);
|
|
125
|
+
}
|
|
126
|
+
docFromBytes(inputBytes, filename) {
|
|
127
|
+
const doc = new inputs_1.BytesInput({
|
|
128
|
+
inputBytes: inputBytes,
|
|
129
|
+
filename: filename,
|
|
130
|
+
});
|
|
131
|
+
return new DocumentClient(doc, this.docConfigs);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.Client = Client;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Response } from "./api";
|
|
2
|
+
import { Document } from "./documents";
|
|
3
|
+
export interface ProductConfig {
|
|
4
|
+
description: string;
|
|
5
|
+
docType: string;
|
|
6
|
+
responseClass: typeof Response<Document>;
|
|
7
|
+
fullText: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class ProductConfigs {
|
|
10
|
+
private static configs;
|
|
11
|
+
static getByResponseClassName(responseClass: string): ProductConfig;
|
|
12
|
+
static getByDocType(docType: string): ProductConfig;
|
|
13
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProductConfigs = void 0;
|
|
4
|
+
const api_1 = require("./api");
|
|
5
|
+
const documents_1 = require("./documents");
|
|
6
|
+
class ProductConfigs {
|
|
7
|
+
static getByResponseClassName(responseClass) {
|
|
8
|
+
const config = this.configs.find((element) => element.responseClass.name === responseClass);
|
|
9
|
+
if (config === undefined) {
|
|
10
|
+
throw `Unknown response class: ${responseClass}`;
|
|
11
|
+
}
|
|
12
|
+
return config;
|
|
13
|
+
}
|
|
14
|
+
static getByDocType(docType) {
|
|
15
|
+
const config = this.configs.find((element) => element.docType === docType);
|
|
16
|
+
if (config === undefined) {
|
|
17
|
+
throw `Unknown document type: ${docType}`;
|
|
18
|
+
}
|
|
19
|
+
return config;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.ProductConfigs = ProductConfigs;
|
|
23
|
+
ProductConfigs.configs = [
|
|
24
|
+
{
|
|
25
|
+
description: "Invoice",
|
|
26
|
+
docType: documents_1.DOC_TYPE_INVOICE,
|
|
27
|
+
responseClass: api_1.InvoiceResponse,
|
|
28
|
+
fullText: true,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
description: "Expense Receipt",
|
|
32
|
+
docType: documents_1.DOC_TYPE_RECEIPT,
|
|
33
|
+
responseClass: api_1.ReceiptResponse,
|
|
34
|
+
fullText: true,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
description: "Passport",
|
|
38
|
+
docType: documents_1.DOC_TYPE_PASSPORT,
|
|
39
|
+
responseClass: api_1.PassportResponse,
|
|
40
|
+
fullText: false,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
description: "Financial Document (receipt or invoice)",
|
|
44
|
+
docType: documents_1.DOC_TYPE_FINANCIAL,
|
|
45
|
+
responseClass: api_1.FinancialDocResponse,
|
|
46
|
+
fullText: true,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
description: "A custom document",
|
|
50
|
+
docType: documents_1.DOC_TYPE_CUSTOM,
|
|
51
|
+
responseClass: api_1.CustomResponse,
|
|
52
|
+
fullText: false,
|
|
53
|
+
},
|
|
54
|
+
];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Document, DocumentConstructorProps } from "./document";
|
|
2
|
+
import { ClassificationField, ListField } from "../fields";
|
|
3
|
+
import { stringDict } from "../fields/field";
|
|
4
|
+
export interface CustomDocConstructorProps extends DocumentConstructorProps {
|
|
5
|
+
documentType: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class CustomDocument extends Document {
|
|
8
|
+
fields: Map<string, ListField>;
|
|
9
|
+
classifications: Map<string, ClassificationField>;
|
|
10
|
+
readonly documentType: string;
|
|
11
|
+
constructor({ inputFile, apiPrediction, pageId, documentType, }: CustomDocConstructorProps);
|
|
12
|
+
protected setField(fieldName: string, apiPrediction: stringDict, pageId: number | undefined): void;
|
|
13
|
+
toString(): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomDocument = void 0;
|
|
4
|
+
const document_1 = require("./document");
|
|
5
|
+
const fields_1 = require("../fields");
|
|
6
|
+
class CustomDocument extends document_1.Document {
|
|
7
|
+
constructor({ inputFile, apiPrediction, pageId, documentType, }) {
|
|
8
|
+
super(inputFile, pageId);
|
|
9
|
+
this.fields = new Map();
|
|
10
|
+
this.classifications = new Map();
|
|
11
|
+
this.documentType = documentType;
|
|
12
|
+
Object.keys(apiPrediction).forEach((fieldName) => {
|
|
13
|
+
this.setField(fieldName, apiPrediction, pageId);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
setField(fieldName, apiPrediction, pageId) {
|
|
17
|
+
// Currently, two types of fields possible in a custom API response:
|
|
18
|
+
// fields having a list of values, and classification fields.
|
|
19
|
+
const fieldPrediction = apiPrediction[fieldName];
|
|
20
|
+
if (fieldPrediction["values"] !== undefined) {
|
|
21
|
+
// Only value lists have the 'values' attribute.
|
|
22
|
+
this.fields.set(fieldName, new fields_1.ListField({
|
|
23
|
+
prediction: fieldPrediction,
|
|
24
|
+
pageId: pageId,
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
else if (fieldPrediction["value"] !== undefined) {
|
|
28
|
+
// Only classifications have the 'value' attribute.
|
|
29
|
+
this.classifications.set(fieldName, new fields_1.ClassificationField({ prediction: fieldPrediction }));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw "Unknown API field type";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
toString() {
|
|
36
|
+
let outStr = `----- ${this.documentType} -----`;
|
|
37
|
+
outStr += `\nFilename: ${this.filename}`.trimEnd();
|
|
38
|
+
this.classifications.forEach((fieldData, name) => {
|
|
39
|
+
outStr += `\n${name}: ${fieldData}`.trimEnd();
|
|
40
|
+
});
|
|
41
|
+
this.fields.forEach((fieldData, name) => {
|
|
42
|
+
outStr += `\n${name}: ${fieldData}`.trimEnd();
|
|
43
|
+
});
|
|
44
|
+
outStr += "\n----------------------\n";
|
|
45
|
+
return outStr;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.CustomDocument = CustomDocument;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Input } from "../inputs";
|
|
2
|
+
import { FullText } from "../fields";
|
|
3
|
+
export interface DocumentConstructorProps {
|
|
4
|
+
apiPrediction: {
|
|
5
|
+
[index: string]: any;
|
|
6
|
+
};
|
|
7
|
+
inputFile?: Input;
|
|
8
|
+
pageId?: number;
|
|
9
|
+
fullText?: FullText;
|
|
10
|
+
}
|
|
11
|
+
export declare class Document {
|
|
12
|
+
checklist: {
|
|
13
|
+
[index: string]: boolean;
|
|
14
|
+
};
|
|
15
|
+
mimeType: string | undefined;
|
|
16
|
+
filename: string;
|
|
17
|
+
filepath: string | undefined;
|
|
18
|
+
fullText?: FullText;
|
|
19
|
+
pageId?: number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Takes a list of Documents and return one Document where
|
|
22
|
+
* each field is set with the maximum probability field
|
|
23
|
+
* @param {Input} inputFile - input file given to parse the document
|
|
24
|
+
* @param {number} pageId - Page ID for multi-page document
|
|
25
|
+
* @param {FullText} fullText - full OCR extracted text
|
|
26
|
+
*/
|
|
27
|
+
constructor(inputFile?: Input, pageId?: number, fullText?: FullText);
|
|
28
|
+
clone(): any;
|
|
29
|
+
/** return true if all checklist of the document if true */
|
|
30
|
+
checkAll(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Takes a list of Documents and return one Document where
|
|
33
|
+
* each field is set with the maximum probability field
|
|
34
|
+
* @param {Array<Document>} documents - A list of Documents
|
|
35
|
+
*/
|
|
36
|
+
static mergePages(documents: any): any;
|
|
37
|
+
static cleanOutString(outStr: string): string;
|
|
38
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Document = void 0;
|
|
4
|
+
class Document {
|
|
5
|
+
/**
|
|
6
|
+
* Takes a list of Documents and return one Document where
|
|
7
|
+
* each field is set with the maximum probability field
|
|
8
|
+
* @param {Input} inputFile - input file given to parse the document
|
|
9
|
+
* @param {number} pageId - Page ID for multi-page document
|
|
10
|
+
* @param {FullText} fullText - full OCR extracted text
|
|
11
|
+
*/
|
|
12
|
+
constructor(inputFile, pageId, fullText) {
|
|
13
|
+
this.filename = "";
|
|
14
|
+
this.filepath = undefined;
|
|
15
|
+
this.pageId = pageId;
|
|
16
|
+
if (inputFile !== undefined) {
|
|
17
|
+
this.filepath = inputFile.filepath;
|
|
18
|
+
this.filename = inputFile.filename;
|
|
19
|
+
this.mimeType = inputFile.mimeType;
|
|
20
|
+
}
|
|
21
|
+
this.fullText = fullText;
|
|
22
|
+
this.checklist = {};
|
|
23
|
+
}
|
|
24
|
+
clone() {
|
|
25
|
+
return JSON.parse(JSON.stringify(this));
|
|
26
|
+
}
|
|
27
|
+
/** return true if all checklist of the document if true */
|
|
28
|
+
checkAll() {
|
|
29
|
+
return Object.values(this.checklist).every((item) => item);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Takes a list of Documents and return one Document where
|
|
33
|
+
* each field is set with the maximum probability field
|
|
34
|
+
* @param {Array<Document>} documents - A list of Documents
|
|
35
|
+
*/
|
|
36
|
+
static mergePages(documents) {
|
|
37
|
+
var _a, _b;
|
|
38
|
+
const finalDocument = documents[0].clone();
|
|
39
|
+
const attributes = Object.getOwnPropertyNames(finalDocument);
|
|
40
|
+
for (const document of documents) {
|
|
41
|
+
for (const attribute of attributes) {
|
|
42
|
+
if (Array.isArray(document === null || document === void 0 ? void 0 : document[attribute])) {
|
|
43
|
+
finalDocument[attribute] = ((_a = finalDocument[attribute]) === null || _a === void 0 ? void 0 : _a.length)
|
|
44
|
+
? finalDocument[attribute]
|
|
45
|
+
: document === null || document === void 0 ? void 0 : document[attribute];
|
|
46
|
+
}
|
|
47
|
+
else if (((_b = document === null || document === void 0 ? void 0 : document[attribute]) === null || _b === void 0 ? void 0 : _b.confidence) >
|
|
48
|
+
finalDocument[attribute].confidence) {
|
|
49
|
+
finalDocument[attribute] = document === null || document === void 0 ? void 0 : document[attribute];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return finalDocument;
|
|
54
|
+
}
|
|
55
|
+
static cleanOutString(outStr) {
|
|
56
|
+
const lines = / \n/gm;
|
|
57
|
+
return outStr.replace(lines, "\n");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.Document = Document;
|