mindee 2.1.1 → 3.0.1
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 +16 -0
- package/README.md +30 -9
- package/package.json +3 -2
- package/src/api/endpoint.d.ts +19 -17
- package/src/api/endpoint.js +27 -39
- package/src/api/index.d.ts +2 -2
- package/src/api/index.js +2 -11
- package/src/api/response.d.ts +8 -41
- package/src/api/response.js +18 -89
- package/src/cli.js +46 -12
- package/src/client.d.ts +47 -13
- package/src/client.js +73 -27
- package/src/documents/cropper/cropperV1.d.ts +7 -0
- package/src/documents/{cropper.js → cropper/cropperV1.js} +12 -8
- package/src/documents/custom.d.ts +2 -6
- package/src/documents/custom.js +12 -7
- package/src/documents/document.d.ts +8 -3
- package/src/documents/document.js +11 -5
- package/src/documents/documentConfig.d.ts +20 -34
- package/src/documents/documentConfig.js +33 -57
- package/src/documents/{financialDocument.d.ts → financialDocument/financialDocumentV1.d.ts} +4 -4
- package/src/documents/{financialDocument.js → financialDocument/financialDocumentV1.js} +28 -22
- package/src/documents/fr/idCard/idCardV1.d.ts +3 -0
- package/src/documents/fr/idCard/idCardV1.js +7 -0
- package/src/documents/index.d.ts +15 -13
- package/src/documents/index.js +21 -18
- package/src/documents/{invoice.d.ts → invoice/invoiceV3.d.ts} +4 -4
- package/src/documents/{invoice.js → invoice/invoiceV3.js} +30 -24
- package/src/documents/{passport.d.ts → passport/passportV1.d.ts} +4 -4
- package/src/documents/{passport.js → passport/passportV1.js} +19 -14
- package/src/documents/receipt/receiptV3.d.ts +17 -0
- package/src/documents/{receipt.js → receipt/receiptV3.js} +28 -22
- package/src/documents/receipt/receiptV4.d.ts +27 -0
- package/src/documents/receipt/receiptV4.js +96 -0
- package/src/documents/receipt/tax.d.ts +25 -0
- package/src/documents/receipt/tax.js +40 -0
- package/src/documents/us/bankCheck/bankCheckV1.d.ts +3 -0
- package/src/documents/us/bankCheck/bankCheckV1.js +7 -0
- package/src/errors/MindeeError.d.ts +3 -0
- package/src/errors/MindeeError.js +10 -0
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +5 -0
- package/src/fields/{customDocs.d.ts → apiBuilder.d.ts} +5 -1
- package/src/fields/{customDocs.js → apiBuilder.js} +0 -0
- package/src/fields/index.d.ts +1 -1
- package/src/fields/index.js +4 -4
- package/src/index.d.ts +2 -1
- package/src/index.js +11 -9
- package/src/inputs/base.d.ts +33 -0
- package/src/inputs/base.js +116 -0
- package/src/inputs/index.d.ts +3 -0
- package/src/inputs/index.js +18 -0
- package/src/inputs/pageOptions.d.ts +20 -0
- package/src/inputs/pageOptions.js +8 -0
- package/src/inputs/sources.d.ts +55 -0
- package/src/inputs/sources.js +121 -0
- package/src/pdf/index.d.ts +1 -0
- package/src/pdf/index.js +6 -0
- package/src/pdf/pdfOperation.d.ts +14 -0
- package/src/pdf/pdfOperation.js +69 -0
- package/src/constants.d.ts +0 -13
- package/src/constants.js +0 -60
- package/src/documents/cropper.d.ts +0 -7
- package/src/documents/receipt.d.ts +0 -17
- package/src/inputs.d.ts +0 -69
- package/src/inputs.js +0 -196
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.UrlInput = exports.BytesInput = exports.StreamInput = exports.Base64Input = exports.PathInput = void 0;
|
|
27
|
+
const fs_1 = require("fs");
|
|
28
|
+
const path = __importStar(require("path"));
|
|
29
|
+
const handler_1 = require("../errors/handler");
|
|
30
|
+
const node_buffer_1 = require("node:buffer");
|
|
31
|
+
const logger_1 = require("../logger");
|
|
32
|
+
const base_1 = require("./base");
|
|
33
|
+
class PathInput extends base_1.InputSource {
|
|
34
|
+
constructor({ inputPath }) {
|
|
35
|
+
super({
|
|
36
|
+
inputType: base_1.INPUT_TYPE_PATH,
|
|
37
|
+
});
|
|
38
|
+
this.fileObject = node_buffer_1.Buffer.alloc(0);
|
|
39
|
+
this.inputPath = inputPath;
|
|
40
|
+
this.filename = path.basename(this.inputPath);
|
|
41
|
+
}
|
|
42
|
+
async init() {
|
|
43
|
+
logger_1.logger.debug(`Loading from: ${this.inputPath}`);
|
|
44
|
+
this.fileObject = node_buffer_1.Buffer.from(await fs_1.promises.readFile(this.inputPath));
|
|
45
|
+
this.mimeType = await this.checkMimetype();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.PathInput = PathInput;
|
|
49
|
+
class Base64Input extends base_1.InputSource {
|
|
50
|
+
constructor({ inputString, filename }) {
|
|
51
|
+
super({
|
|
52
|
+
inputType: base_1.INPUT_TYPE_BASE64,
|
|
53
|
+
});
|
|
54
|
+
this.fileObject = node_buffer_1.Buffer.alloc(0);
|
|
55
|
+
this.filename = filename;
|
|
56
|
+
this.inputString = inputString;
|
|
57
|
+
}
|
|
58
|
+
async init() {
|
|
59
|
+
this.fileObject = node_buffer_1.Buffer.from(this.inputString, "base64");
|
|
60
|
+
this.mimeType = await this.checkMimetype();
|
|
61
|
+
// clear out the string
|
|
62
|
+
this.inputString = "";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.Base64Input = Base64Input;
|
|
66
|
+
class StreamInput extends base_1.InputSource {
|
|
67
|
+
constructor({ inputStream, filename }) {
|
|
68
|
+
super({
|
|
69
|
+
inputType: base_1.INPUT_TYPE_STREAM,
|
|
70
|
+
});
|
|
71
|
+
this.fileObject = node_buffer_1.Buffer.alloc(0);
|
|
72
|
+
this.filename = filename;
|
|
73
|
+
this.inputStream = inputStream;
|
|
74
|
+
}
|
|
75
|
+
async init() {
|
|
76
|
+
this.fileObject = await this.stream2buffer(this.inputStream);
|
|
77
|
+
this.mimeType = await this.checkMimetype();
|
|
78
|
+
}
|
|
79
|
+
async stream2buffer(stream) {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
const _buf = Array();
|
|
82
|
+
stream.on("data", (chunk) => _buf.push(chunk));
|
|
83
|
+
stream.on("end", () => resolve(node_buffer_1.Buffer.concat(_buf)));
|
|
84
|
+
stream.on("error", (err) => reject(`Error converting stream - ${err}`));
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.StreamInput = StreamInput;
|
|
89
|
+
class BytesInput extends base_1.InputSource {
|
|
90
|
+
constructor({ inputBytes, filename }) {
|
|
91
|
+
super({
|
|
92
|
+
inputType: base_1.INPUT_TYPE_BYTES,
|
|
93
|
+
});
|
|
94
|
+
this.fileObject = node_buffer_1.Buffer.alloc(0);
|
|
95
|
+
this.filename = filename;
|
|
96
|
+
this.inputBytes = inputBytes;
|
|
97
|
+
}
|
|
98
|
+
async init() {
|
|
99
|
+
this.fileObject = node_buffer_1.Buffer.from(this.inputBytes, "hex");
|
|
100
|
+
this.mimeType = await this.checkMimetype();
|
|
101
|
+
// clear out the string
|
|
102
|
+
this.inputBytes = "";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.BytesInput = BytesInput;
|
|
106
|
+
class UrlInput extends base_1.InputSource {
|
|
107
|
+
constructor({ url }) {
|
|
108
|
+
super({
|
|
109
|
+
inputType: base_1.INPUT_TYPE_URL,
|
|
110
|
+
});
|
|
111
|
+
this.url = url;
|
|
112
|
+
}
|
|
113
|
+
async init() {
|
|
114
|
+
if (!this.url.toLowerCase().startsWith("https")) {
|
|
115
|
+
handler_1.errorHandler.throw(new Error("URL must be HTTPS"));
|
|
116
|
+
}
|
|
117
|
+
this.fileObject = this.url;
|
|
118
|
+
this.filename = "hello.jpg";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.UrlInput = UrlInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { extractPages, countPages, SplitPdf } from "./pdfOperation";
|
package/src/pdf/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countPages = exports.extractPages = void 0;
|
|
4
|
+
var pdfOperation_1 = require("./pdfOperation");
|
|
5
|
+
Object.defineProperty(exports, "extractPages", { enumerable: true, get: function () { return pdfOperation_1.extractPages; } });
|
|
6
|
+
Object.defineProperty(exports, "countPages", { enumerable: true, get: function () { return pdfOperation_1.countPages; } });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { PageOptions } from "../inputs";
|
|
3
|
+
export interface SplitPdf {
|
|
4
|
+
file: Buffer;
|
|
5
|
+
totalPagesRemoved: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Cut pages from a pdf file. If pages index are out of bound, it will throw an error.
|
|
9
|
+
* @param file
|
|
10
|
+
* @param pageOptions
|
|
11
|
+
* @returns the new cutted pdf file.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractPages(file: Buffer, pageOptions: PageOptions): Promise<SplitPdf>;
|
|
14
|
+
export declare function countPages(file: Buffer): Promise<number>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countPages = exports.extractPages = void 0;
|
|
4
|
+
const handler_1 = require("../errors/handler");
|
|
5
|
+
const pdf_lib_1 = require("pdf-lib");
|
|
6
|
+
const inputs_1 = require("../inputs");
|
|
7
|
+
const errors_1 = require("../errors");
|
|
8
|
+
/**
|
|
9
|
+
* Cut pages from a pdf file. If pages index are out of bound, it will throw an error.
|
|
10
|
+
* @param file
|
|
11
|
+
* @param pageOptions
|
|
12
|
+
* @returns the new cutted pdf file.
|
|
13
|
+
*/
|
|
14
|
+
async function extractPages(file, pageOptions) {
|
|
15
|
+
const currentPdf = await pdf_lib_1.PDFDocument.load(file, {
|
|
16
|
+
ignoreEncryption: true,
|
|
17
|
+
});
|
|
18
|
+
const newPdf = await pdf_lib_1.PDFDocument.create();
|
|
19
|
+
if (pageOptions.pageIndexes.length > currentPdf.getPageCount()) {
|
|
20
|
+
handler_1.errorHandler.throw(new errors_1.MindeeError(`The total indexes of pages to cut is superior to the total page count of the file (${currentPdf.getPageCount()}).`));
|
|
21
|
+
}
|
|
22
|
+
if (currentPdf.getPageCount() < pageOptions.onMinPages) {
|
|
23
|
+
return { file: file, totalPagesRemoved: 0 };
|
|
24
|
+
}
|
|
25
|
+
const pageIndexes = [];
|
|
26
|
+
pageOptions.pageIndexes.forEach((pageIndex) => {
|
|
27
|
+
if (pageIndex < 0) {
|
|
28
|
+
pageIndexes.push(currentPdf.getPageCount() - Math.abs(pageIndex));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
pageIndexes.push(pageIndex);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
if (!pageIndexes.every((v) => currentPdf.getPageIndices().includes(v))) {
|
|
35
|
+
handler_1.errorHandler.throw(new errors_1.MindeeError(`Some indexes pages
|
|
36
|
+
(${pageIndexes.join(",")})
|
|
37
|
+
don't exist in the file
|
|
38
|
+
(${currentPdf.getPageIndices().join(", ")})`));
|
|
39
|
+
}
|
|
40
|
+
if (pageOptions.operation === inputs_1.PageOptionsOperation.KeepOnly) {
|
|
41
|
+
const keptPages = await newPdf.copyPages(currentPdf, pageIndexes);
|
|
42
|
+
keptPages.forEach((keptPage) => {
|
|
43
|
+
newPdf.addPage(keptPage);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else if (pageOptions.operation === inputs_1.PageOptionsOperation.Remove) {
|
|
47
|
+
const pagesToKeep = currentPdf
|
|
48
|
+
.getPageIndices()
|
|
49
|
+
.filter((v) => !pageIndexes.includes(v));
|
|
50
|
+
const keptPages = await newPdf.copyPages(currentPdf, pagesToKeep);
|
|
51
|
+
keptPages.forEach((keptPage) => {
|
|
52
|
+
newPdf.addPage(keptPage);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new Error(`The operation ${pageOptions.operation} is not available.`);
|
|
57
|
+
}
|
|
58
|
+
const sumRemovedPages = currentPdf.getPageCount() - newPdf.getPageCount();
|
|
59
|
+
const fileBuffer = Buffer.from(await newPdf.save());
|
|
60
|
+
return { file: fileBuffer, totalPagesRemoved: sumRemovedPages };
|
|
61
|
+
}
|
|
62
|
+
exports.extractPages = extractPages;
|
|
63
|
+
async function countPages(file) {
|
|
64
|
+
const currentPdf = await pdf_lib_1.PDFDocument.load(file, {
|
|
65
|
+
ignoreEncryption: true,
|
|
66
|
+
});
|
|
67
|
+
return currentPdf.getPageCount();
|
|
68
|
+
}
|
|
69
|
+
exports.countPages = countPages;
|
package/src/constants.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
}
|
package/src/constants.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
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
|
-
{
|
|
55
|
-
description: "Cropper",
|
|
56
|
-
docType: documents_1.DOC_TYPE_CROPPER,
|
|
57
|
-
responseClass: api_1.CropperResponse,
|
|
58
|
-
fullText: false,
|
|
59
|
-
},
|
|
60
|
-
];
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Document, DocumentConstructorProps } from "./document";
|
|
2
|
-
import { CropperField } from "../fields";
|
|
3
|
-
export declare class Cropper extends Document {
|
|
4
|
-
cropping: CropperField[];
|
|
5
|
-
constructor({ prediction, orientation, inputFile, pageId, }: DocumentConstructorProps);
|
|
6
|
-
toString(): string;
|
|
7
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Document, DocumentConstructorProps } from "./document";
|
|
2
|
-
import { TaxField, Field, Amount, Locale, DateField } from "../fields";
|
|
3
|
-
export declare class Receipt extends Document {
|
|
4
|
-
#private;
|
|
5
|
-
locale: Locale;
|
|
6
|
-
totalIncl: Amount;
|
|
7
|
-
date: DateField;
|
|
8
|
-
/** Receipt category as seen on the receipt. */
|
|
9
|
-
category: Field;
|
|
10
|
-
merchantName: Field;
|
|
11
|
-
time: Field;
|
|
12
|
-
totalTax: Amount;
|
|
13
|
-
totalExcl: Amount;
|
|
14
|
-
taxes: TaxField[];
|
|
15
|
-
constructor({ prediction, orientation, extras, inputFile, fullText, pageId, }: DocumentConstructorProps);
|
|
16
|
-
toString(): string;
|
|
17
|
-
}
|
package/src/inputs.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import { ReadStream } from "fs";
|
|
4
|
-
import { Buffer } from "node:buffer";
|
|
5
|
-
interface InputProps {
|
|
6
|
-
inputType: string;
|
|
7
|
-
}
|
|
8
|
-
export declare const INPUT_TYPE_STREAM = "stream";
|
|
9
|
-
export declare const INPUT_TYPE_BASE64 = "base64";
|
|
10
|
-
export declare const INPUT_TYPE_BYTES = "bytes";
|
|
11
|
-
export declare const INPUT_TYPE_PATH = "path";
|
|
12
|
-
export declare class Input {
|
|
13
|
-
MAX_DOC_PAGES: number;
|
|
14
|
-
inputType: string;
|
|
15
|
-
filename: string;
|
|
16
|
-
filepath?: string;
|
|
17
|
-
mimeType: string;
|
|
18
|
-
fileObject: Buffer;
|
|
19
|
-
/**
|
|
20
|
-
* @param {String} inputType - the type of input used in file ("base64", "path", "dummy").
|
|
21
|
-
* NB: dummy is only used for tests purposes
|
|
22
|
-
* @param {Boolean} cutPages
|
|
23
|
-
* NB: Because of async calls, init() should be called after creating the object
|
|
24
|
-
*/
|
|
25
|
-
constructor({ inputType }: InputProps);
|
|
26
|
-
init(): Promise<void>;
|
|
27
|
-
isPdf(): boolean;
|
|
28
|
-
checkMimetype(): Promise<string>;
|
|
29
|
-
countPages(): Promise<number>;
|
|
30
|
-
/** Merge PDF pages */
|
|
31
|
-
cutPdf(): Promise<void>;
|
|
32
|
-
}
|
|
33
|
-
interface PathInputProps {
|
|
34
|
-
inputPath: string;
|
|
35
|
-
}
|
|
36
|
-
export declare class PathInput extends Input {
|
|
37
|
-
readonly inputPath: string;
|
|
38
|
-
constructor({ inputPath }: PathInputProps);
|
|
39
|
-
init(): Promise<void>;
|
|
40
|
-
}
|
|
41
|
-
interface Base64InputProps {
|
|
42
|
-
inputString: string;
|
|
43
|
-
filename: string;
|
|
44
|
-
}
|
|
45
|
-
export declare class Base64Input extends Input {
|
|
46
|
-
private inputString;
|
|
47
|
-
constructor({ inputString, filename }: Base64InputProps);
|
|
48
|
-
init(): Promise<void>;
|
|
49
|
-
}
|
|
50
|
-
interface StreamInputProps {
|
|
51
|
-
inputStream: ReadStream;
|
|
52
|
-
filename: string;
|
|
53
|
-
}
|
|
54
|
-
export declare class StreamInput extends Input {
|
|
55
|
-
private inputStream;
|
|
56
|
-
constructor({ inputStream, filename }: StreamInputProps);
|
|
57
|
-
init(): Promise<void>;
|
|
58
|
-
stream2buffer(stream: ReadStream): Promise<Buffer>;
|
|
59
|
-
}
|
|
60
|
-
interface BytesInputProps {
|
|
61
|
-
inputBytes: string;
|
|
62
|
-
filename: string;
|
|
63
|
-
}
|
|
64
|
-
export declare class BytesInput extends Input {
|
|
65
|
-
private inputBytes;
|
|
66
|
-
constructor({ inputBytes, filename }: BytesInputProps);
|
|
67
|
-
init(): Promise<void>;
|
|
68
|
-
}
|
|
69
|
-
export {};
|
package/src/inputs.js
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.BytesInput = exports.StreamInput = exports.Base64Input = exports.PathInput = exports.Input = exports.INPUT_TYPE_PATH = exports.INPUT_TYPE_BYTES = exports.INPUT_TYPE_BASE64 = exports.INPUT_TYPE_STREAM = void 0;
|
|
27
|
-
const fs_1 = require("fs");
|
|
28
|
-
const path = __importStar(require("path"));
|
|
29
|
-
const fileType = __importStar(require("file-type"));
|
|
30
|
-
const handler_1 = require("./errors/handler");
|
|
31
|
-
const pdf_lib_1 = require("pdf-lib");
|
|
32
|
-
const node_buffer_1 = require("node:buffer");
|
|
33
|
-
const logger_1 = require("./logger");
|
|
34
|
-
exports.INPUT_TYPE_STREAM = "stream";
|
|
35
|
-
exports.INPUT_TYPE_BASE64 = "base64";
|
|
36
|
-
exports.INPUT_TYPE_BYTES = "bytes";
|
|
37
|
-
exports.INPUT_TYPE_PATH = "path";
|
|
38
|
-
const MIMETYPES = new Map([
|
|
39
|
-
[".pdf", "application/pdf"],
|
|
40
|
-
[".heic", "image/heic"],
|
|
41
|
-
[".jpg", "image/jpeg"],
|
|
42
|
-
[".jpeg", "image/jpeg"],
|
|
43
|
-
[".png", "image/png"],
|
|
44
|
-
[".tif", "image/tiff"],
|
|
45
|
-
[".tiff", "image/tiff"],
|
|
46
|
-
[".webp", "image/webp"],
|
|
47
|
-
]);
|
|
48
|
-
const ALLOWED_INPUT_TYPES = [
|
|
49
|
-
exports.INPUT_TYPE_STREAM,
|
|
50
|
-
exports.INPUT_TYPE_BASE64,
|
|
51
|
-
exports.INPUT_TYPE_BYTES,
|
|
52
|
-
exports.INPUT_TYPE_PATH,
|
|
53
|
-
];
|
|
54
|
-
class Input {
|
|
55
|
-
/**
|
|
56
|
-
* @param {String} inputType - the type of input used in file ("base64", "path", "dummy").
|
|
57
|
-
* NB: dummy is only used for tests purposes
|
|
58
|
-
* @param {Boolean} cutPages
|
|
59
|
-
* NB: Because of async calls, init() should be called after creating the object
|
|
60
|
-
*/
|
|
61
|
-
constructor({ inputType }) {
|
|
62
|
-
this.MAX_DOC_PAGES = 3;
|
|
63
|
-
this.filename = "";
|
|
64
|
-
this.mimeType = "";
|
|
65
|
-
this.fileObject = node_buffer_1.Buffer.alloc(0);
|
|
66
|
-
// Check if inputType is valid
|
|
67
|
-
if (!ALLOWED_INPUT_TYPES.includes(inputType)) {
|
|
68
|
-
const allowed = Array.from(MIMETYPES.keys()).join(", ");
|
|
69
|
-
handler_1.errorHandler.throw(new Error(`Invalid input type, must be one of ${allowed}.`));
|
|
70
|
-
}
|
|
71
|
-
this.inputType = inputType;
|
|
72
|
-
logger_1.logger.debug(`Loading file from: ${inputType}`);
|
|
73
|
-
}
|
|
74
|
-
async init() {
|
|
75
|
-
throw new Error("not Implemented");
|
|
76
|
-
}
|
|
77
|
-
isPdf() {
|
|
78
|
-
return this.mimeType === "application/pdf";
|
|
79
|
-
}
|
|
80
|
-
async checkMimetype() {
|
|
81
|
-
let mimeType;
|
|
82
|
-
const fileExt = path.extname(this.filename);
|
|
83
|
-
if (fileExt) {
|
|
84
|
-
mimeType = MIMETYPES.get(fileExt.toLowerCase()) || "";
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
const guess = await fileType.fromBuffer(this.fileObject);
|
|
88
|
-
if (guess !== undefined) {
|
|
89
|
-
mimeType = guess.mime;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
throw "Could not determine the MIME type of the file";
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (!mimeType) {
|
|
96
|
-
const allowed = Array.from(MIMETYPES.keys()).join(", ");
|
|
97
|
-
const err = new Error(`Invalid file type, must be one of ${allowed}.`);
|
|
98
|
-
handler_1.errorHandler.throw(err);
|
|
99
|
-
}
|
|
100
|
-
logger_1.logger.debug(`File is of type: ${mimeType}`);
|
|
101
|
-
return mimeType;
|
|
102
|
-
}
|
|
103
|
-
async countPages() {
|
|
104
|
-
const pdfDocument = await pdf_lib_1.PDFDocument.load(this.fileObject, {
|
|
105
|
-
ignoreEncryption: true,
|
|
106
|
-
});
|
|
107
|
-
return pdfDocument.getPageCount();
|
|
108
|
-
}
|
|
109
|
-
/** Merge PDF pages */
|
|
110
|
-
async cutPdf() {
|
|
111
|
-
const currentPdf = await pdf_lib_1.PDFDocument.load(this.fileObject, {
|
|
112
|
-
ignoreEncryption: true,
|
|
113
|
-
});
|
|
114
|
-
const pdfLength = currentPdf.getPageCount();
|
|
115
|
-
if (pdfLength <= this.MAX_DOC_PAGES) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
const newPdf = await pdf_lib_1.PDFDocument.create();
|
|
119
|
-
const pagesNumbers = [0, pdfLength - 2, pdfLength - 1].slice(0, this.MAX_DOC_PAGES);
|
|
120
|
-
logger_1.logger.debug(`Cutting PDF, keeping pages: ${pagesNumbers}`);
|
|
121
|
-
const pages = await newPdf.copyPages(currentPdf, pagesNumbers);
|
|
122
|
-
pages.forEach((page) => newPdf.addPage(page));
|
|
123
|
-
const data = await newPdf.save();
|
|
124
|
-
this.fileObject = node_buffer_1.Buffer.from(data);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
exports.Input = Input;
|
|
128
|
-
class PathInput extends Input {
|
|
129
|
-
constructor({ inputPath }) {
|
|
130
|
-
super({
|
|
131
|
-
inputType: exports.INPUT_TYPE_PATH,
|
|
132
|
-
});
|
|
133
|
-
this.inputPath = inputPath;
|
|
134
|
-
this.filename = path.basename(this.inputPath);
|
|
135
|
-
}
|
|
136
|
-
async init() {
|
|
137
|
-
logger_1.logger.debug(`Loading from: ${this.inputPath}`);
|
|
138
|
-
this.fileObject = node_buffer_1.Buffer.from(await fs_1.promises.readFile(this.inputPath));
|
|
139
|
-
this.mimeType = await this.checkMimetype();
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
exports.PathInput = PathInput;
|
|
143
|
-
class Base64Input extends Input {
|
|
144
|
-
constructor({ inputString, filename }) {
|
|
145
|
-
super({
|
|
146
|
-
inputType: exports.INPUT_TYPE_BASE64,
|
|
147
|
-
});
|
|
148
|
-
this.filename = filename;
|
|
149
|
-
this.inputString = inputString;
|
|
150
|
-
}
|
|
151
|
-
async init() {
|
|
152
|
-
this.fileObject = node_buffer_1.Buffer.from(this.inputString, "base64");
|
|
153
|
-
this.mimeType = await this.checkMimetype();
|
|
154
|
-
// clear out the string
|
|
155
|
-
this.inputString = "";
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
exports.Base64Input = Base64Input;
|
|
159
|
-
class StreamInput extends Input {
|
|
160
|
-
constructor({ inputStream, filename }) {
|
|
161
|
-
super({
|
|
162
|
-
inputType: exports.INPUT_TYPE_STREAM,
|
|
163
|
-
});
|
|
164
|
-
this.filename = filename;
|
|
165
|
-
this.inputStream = inputStream;
|
|
166
|
-
}
|
|
167
|
-
async init() {
|
|
168
|
-
this.fileObject = await this.stream2buffer(this.inputStream);
|
|
169
|
-
this.mimeType = await this.checkMimetype();
|
|
170
|
-
}
|
|
171
|
-
async stream2buffer(stream) {
|
|
172
|
-
return new Promise((resolve, reject) => {
|
|
173
|
-
const _buf = Array();
|
|
174
|
-
stream.on("data", (chunk) => _buf.push(chunk));
|
|
175
|
-
stream.on("end", () => resolve(node_buffer_1.Buffer.concat(_buf)));
|
|
176
|
-
stream.on("error", (err) => reject(`Error converting stream - ${err}`));
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
exports.StreamInput = StreamInput;
|
|
181
|
-
class BytesInput extends Input {
|
|
182
|
-
constructor({ inputBytes, filename }) {
|
|
183
|
-
super({
|
|
184
|
-
inputType: exports.INPUT_TYPE_BYTES,
|
|
185
|
-
});
|
|
186
|
-
this.filename = filename;
|
|
187
|
-
this.inputBytes = inputBytes;
|
|
188
|
-
}
|
|
189
|
-
async init() {
|
|
190
|
-
this.fileObject = node_buffer_1.Buffer.from(this.inputBytes, "hex");
|
|
191
|
-
this.mimeType = await this.checkMimetype();
|
|
192
|
-
// clear out the string
|
|
193
|
-
this.inputBytes = "";
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
exports.BytesInput = BytesInput;
|