chromiumly 2.0.8 → 2.2.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/dist/chromium/converters/html.converter.d.ts +5 -2
- package/dist/chromium/converters/html.converter.js +20 -14
- package/dist/chromium/converters/html.converter.js.map +1 -1
- package/dist/chromium/converters/markdown.converter.d.ts +5 -2
- package/dist/chromium/converters/markdown.converter.js +22 -16
- package/dist/chromium/converters/markdown.converter.js.map +1 -1
- package/dist/chromium/converters/url.converter.d.ts +7 -2
- package/dist/chromium/converters/url.converter.js +21 -14
- package/dist/chromium/converters/url.converter.js.map +1 -1
- package/dist/chromium/interfaces/converter.types.d.ts +1 -0
- package/dist/common/constants.js +1 -1
- package/dist/common/constants.js.map +1 -1
- package/dist/gotenberg.d.ts +0 -1
- package/dist/gotenberg.js +11 -2
- package/dist/gotenberg.js.map +1 -1
- package/dist/libre-office/utils/libre-office.utils.js +7 -12
- package/dist/libre-office/utils/libre-office.utils.js.map +1 -1
- package/dist/main.config.js +2 -2
- package/dist/main.config.js.map +1 -1
- package/dist/pdf-engines/utils/engine.utils.js +7 -12
- package/dist/pdf-engines/utils/engine.utils.js.map +1 -1
- package/package.json +16 -15
- package/src/chromium/converters/html.converter.ts +37 -14
- package/src/chromium/converters/markdown.converter.ts +37 -16
- package/src/chromium/converters/tests/html.converter.test.ts +60 -3
- package/src/chromium/converters/tests/markdown.converter.test.ts +68 -4
- package/src/chromium/converters/tests/url.converter.test.ts +71 -4
- package/src/chromium/converters/url.converter.ts +37 -14
- package/src/chromium/interfaces/converter.types.ts +2 -0
- package/src/gotenberg.ts +13 -1
- package/src/libre-office/utils/libre-office.utils.ts +7 -11
- package/src/libre-office/utils/tests/libre-office.utils.test.ts +5 -4
- package/src/pdf-engines/tests/pdf.engine.test.ts +56 -18
- package/src/pdf-engines/utils/engine.utils.ts +7 -11
- package/src/pdf-engines/utils/tests/engine.utils.test.ts +5 -4
|
@@ -3,13 +3,16 @@
|
|
|
3
3
|
import { PathLike } from "fs";
|
|
4
4
|
import { PdfFormat } from "../../common";
|
|
5
5
|
import { IConverter } from "../interfaces/converter.interface";
|
|
6
|
-
import { PageProperties } from "../interfaces/converter.types";
|
|
6
|
+
import { EmulatedMediaType, PageProperties } from "../interfaces/converter.types";
|
|
7
7
|
import { Converter } from "./converter";
|
|
8
8
|
export declare class HtmlConverter extends Converter implements IConverter {
|
|
9
9
|
constructor();
|
|
10
|
-
convert({ html, properties, pdfFormat, }: {
|
|
10
|
+
convert({ html, header, footer, properties, pdfFormat, emulatedMediaType, }: {
|
|
11
11
|
html: PathLike;
|
|
12
|
+
header?: PathLike;
|
|
13
|
+
footer?: PathLike;
|
|
12
14
|
properties?: PageProperties;
|
|
13
15
|
pdfFormat?: PdfFormat;
|
|
16
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
14
17
|
}): Promise<Buffer>;
|
|
15
18
|
}
|
|
@@ -12,23 +12,29 @@ class HtmlConverter extends converter_1.Converter {
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super(main_config_1.ChromiumRoute.HTML);
|
|
14
14
|
}
|
|
15
|
-
convert({ html, properties, pdfFormat, }) {
|
|
15
|
+
convert({ html, header, footer, properties, pdfFormat, emulatedMediaType, }) {
|
|
16
16
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
data.append("pdfFormat", pdfFormat);
|
|
22
|
-
}
|
|
23
|
-
data.append("index.html", (0, fs_1.createReadStream)(html));
|
|
24
|
-
if (properties) {
|
|
25
|
-
converter_utils_1.ConverterUtils.injectPageProperties(data, properties);
|
|
26
|
-
}
|
|
27
|
-
return common_1.GotenbergUtils.fetch(this.endpoint, data);
|
|
17
|
+
yield fs_1.promises.access(html, fs_1.constants.R_OK);
|
|
18
|
+
const data = new form_data_1.default();
|
|
19
|
+
if (pdfFormat) {
|
|
20
|
+
data.append("pdfFormat", pdfFormat);
|
|
28
21
|
}
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
data.append("index.html", (0, fs_1.createReadStream)(html));
|
|
23
|
+
if (header) {
|
|
24
|
+
yield fs_1.promises.access(header, fs_1.constants.R_OK);
|
|
25
|
+
data.append("header.html", (0, fs_1.createReadStream)(header));
|
|
31
26
|
}
|
|
27
|
+
if (footer) {
|
|
28
|
+
yield fs_1.promises.access(footer, fs_1.constants.R_OK);
|
|
29
|
+
data.append("footer.html", (0, fs_1.createReadStream)(footer));
|
|
30
|
+
}
|
|
31
|
+
if (emulatedMediaType) {
|
|
32
|
+
data.append("emulatedMediaType", emulatedMediaType);
|
|
33
|
+
}
|
|
34
|
+
if (properties) {
|
|
35
|
+
converter_utils_1.ConverterUtils.injectPageProperties(data, properties);
|
|
36
|
+
}
|
|
37
|
+
return common_1.GotenbergUtils.fetch(this.endpoint, data);
|
|
32
38
|
});
|
|
33
39
|
}
|
|
34
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.converter.js","sourceRoot":"","sources":["../../../src/chromium/converters/html.converter.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AAErE,kEAAiC;AAEjC,yCAAyD;
|
|
1
|
+
{"version":3,"file":"html.converter.js","sourceRoot":"","sources":["../../../src/chromium/converters/html.converter.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AAErE,kEAAiC;AAEjC,yCAAyD;AAMzD,8DAA0D;AAC1D,2CAAwC;AACxC,mDAAkD;AAElD,MAAa,aAAc,SAAQ,qBAAS;IAC1C;QACE,KAAK,CAAC,2BAAa,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEK,OAAO,CAAC,EACZ,IAAI,EACJ,MAAM,EACN,MAAM,EACN,UAAU,EACV,SAAS,EACT,iBAAiB,GAQlB;;YACC,MAAM,aAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,IAAI,mBAAQ,EAAE,CAAC;YAE5B,IAAI,SAAS,EAAE;gBACb,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;aACrC;YAED,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,IAAA,qBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;YAElD,IAAI,MAAM,EAAE;gBACV,MAAM,aAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAA,qBAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;aACtD;YAED,IAAI,MAAM,EAAE;gBACV,MAAM,aAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAA,qBAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;aACtD;YAED,IAAI,iBAAiB,EAAE;gBACrB,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;aACrD;YAED,IAAI,UAAU,EAAE;gBACd,gCAAc,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;aACvD;YAED,OAAO,uBAAc,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;KAAA;CACF;AAjDD,sCAiDC"}
|
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
import { PathLike } from "fs";
|
|
4
4
|
import { PdfFormat } from "../../common";
|
|
5
5
|
import { IConverter } from "../interfaces/converter.interface";
|
|
6
|
-
import { PageProperties } from "../interfaces/converter.types";
|
|
6
|
+
import { EmulatedMediaType, PageProperties } from "../interfaces/converter.types";
|
|
7
7
|
import { Converter } from "./converter";
|
|
8
8
|
export declare class MarkdownConverter extends Converter implements IConverter {
|
|
9
9
|
constructor();
|
|
10
|
-
convert({ html, markdown, properties, pdfFormat, }: {
|
|
10
|
+
convert({ html, markdown, header, footer, properties, pdfFormat, emulatedMediaType, }: {
|
|
11
11
|
html: PathLike;
|
|
12
12
|
markdown: PathLike;
|
|
13
|
+
header?: PathLike;
|
|
14
|
+
footer?: PathLike;
|
|
13
15
|
properties?: PageProperties;
|
|
14
16
|
pdfFormat?: PdfFormat;
|
|
17
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
15
18
|
}): Promise<Buffer>;
|
|
16
19
|
}
|
|
@@ -12,25 +12,31 @@ class MarkdownConverter extends converter_1.Converter {
|
|
|
12
12
|
constructor() {
|
|
13
13
|
super(main_config_1.ChromiumRoute.MARKDOWN);
|
|
14
14
|
}
|
|
15
|
-
convert({ html, markdown, properties, pdfFormat, }) {
|
|
15
|
+
convert({ html, markdown, header, footer, properties, pdfFormat, emulatedMediaType, }) {
|
|
16
16
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
data.append("pdfFormat", pdfFormat);
|
|
23
|
-
}
|
|
24
|
-
data.append("index.html", (0, fs_1.createReadStream)(html));
|
|
25
|
-
data.append("file.md", (0, fs_1.createReadStream)(markdown));
|
|
26
|
-
if (properties) {
|
|
27
|
-
converter_utils_1.ConverterUtils.injectPageProperties(data, properties);
|
|
28
|
-
}
|
|
29
|
-
return common_1.GotenbergUtils.fetch(this.endpoint, data);
|
|
17
|
+
yield fs_1.promises.access(html, fs_1.constants.R_OK);
|
|
18
|
+
yield fs_1.promises.access(markdown, fs_1.constants.R_OK);
|
|
19
|
+
const data = new form_data_1.default();
|
|
20
|
+
if (pdfFormat) {
|
|
21
|
+
data.append("pdfFormat", pdfFormat);
|
|
30
22
|
}
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
data.append("index.html", (0, fs_1.createReadStream)(html));
|
|
24
|
+
data.append("file.md", (0, fs_1.createReadStream)(markdown));
|
|
25
|
+
if (header) {
|
|
26
|
+
yield fs_1.promises.access(header, fs_1.constants.R_OK);
|
|
27
|
+
data.append("header.html", (0, fs_1.createReadStream)(header));
|
|
33
28
|
}
|
|
29
|
+
if (footer) {
|
|
30
|
+
yield fs_1.promises.access(footer, fs_1.constants.R_OK);
|
|
31
|
+
data.append("footer.html", (0, fs_1.createReadStream)(footer));
|
|
32
|
+
}
|
|
33
|
+
if (emulatedMediaType) {
|
|
34
|
+
data.append("emulatedMediaType", emulatedMediaType);
|
|
35
|
+
}
|
|
36
|
+
if (properties) {
|
|
37
|
+
converter_utils_1.ConverterUtils.injectPageProperties(data, properties);
|
|
38
|
+
}
|
|
39
|
+
return common_1.GotenbergUtils.fetch(this.endpoint, data);
|
|
34
40
|
});
|
|
35
41
|
}
|
|
36
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.converter.js","sourceRoot":"","sources":["../../../src/chromium/converters/markdown.converter.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AAErE,kEAAiC;AAEjC,yCAAyD;
|
|
1
|
+
{"version":3,"file":"markdown.converter.js","sourceRoot":"","sources":["../../../src/chromium/converters/markdown.converter.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AAErE,kEAAiC;AAEjC,yCAAyD;AAMzD,8DAA0D;AAC1D,2CAAwC;AACxC,mDAAkD;AAElD,MAAa,iBAAkB,SAAQ,qBAAS;IAC9C;QACE,KAAK,CAAC,2BAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAEK,OAAO,CAAC,EACZ,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,MAAM,EACN,UAAU,EACV,SAAS,EACT,iBAAiB,GASlB;;YACC,MAAM,aAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,aAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,IAAI,GAAG,IAAI,mBAAQ,EAAE,CAAC;YAC5B,IAAI,SAAS,EAAE;gBACb,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;aACrC;YACD,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,IAAA,qBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAA,qBAAgB,EAAC,QAAQ,CAAC,CAAC,CAAC;YAEnD,IAAI,MAAM,EAAE;gBACV,MAAM,aAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAA,qBAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;aACtD;YAED,IAAI,MAAM,EAAE;gBACV,MAAM,aAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAA,qBAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;aACtD;YAED,IAAI,iBAAiB,EAAE;gBACrB,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;aACrD;YAED,IAAI,UAAU,EAAE;gBACd,gCAAc,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;aACvD;YAED,OAAO,uBAAc,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;KAAA;CACF;AAnDD,8CAmDC"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import { PathLike } from "fs";
|
|
2
4
|
import { PdfFormat } from "../../common";
|
|
3
5
|
import { IConverter } from "../interfaces/converter.interface";
|
|
4
|
-
import { PageProperties } from "../interfaces/converter.types";
|
|
6
|
+
import { EmulatedMediaType, PageProperties } from "../interfaces/converter.types";
|
|
5
7
|
import { Converter } from "./converter";
|
|
6
8
|
export declare class UrlConverter extends Converter implements IConverter {
|
|
7
9
|
constructor();
|
|
8
|
-
convert({ url, properties, pdfFormat, }: {
|
|
10
|
+
convert({ url, header, footer, properties, pdfFormat, emulatedMediaType, }: {
|
|
9
11
|
url: string;
|
|
12
|
+
header?: PathLike;
|
|
13
|
+
footer?: PathLike;
|
|
10
14
|
properties?: PageProperties;
|
|
11
15
|
pdfFormat?: PdfFormat;
|
|
16
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
12
17
|
}): Promise<Buffer>;
|
|
13
18
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UrlConverter = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const fs_1 = require("fs");
|
|
5
6
|
const url_1 = require("url");
|
|
6
7
|
const form_data_1 = tslib_1.__importDefault(require("form-data"));
|
|
7
8
|
const common_1 = require("../../common");
|
|
@@ -12,23 +13,29 @@ class UrlConverter extends converter_1.Converter {
|
|
|
12
13
|
constructor() {
|
|
13
14
|
super(main_config_1.ChromiumRoute.URL);
|
|
14
15
|
}
|
|
15
|
-
convert({ url, properties, pdfFormat, }) {
|
|
16
|
+
convert({ url, header, footer, properties, pdfFormat, emulatedMediaType, }) {
|
|
16
17
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
data.append("pdfFormat", pdfFormat);
|
|
22
|
-
}
|
|
23
|
-
data.append("url", _url.href);
|
|
24
|
-
if (properties) {
|
|
25
|
-
converter_utils_1.ConverterUtils.injectPageProperties(data, properties);
|
|
26
|
-
}
|
|
27
|
-
return common_1.GotenbergUtils.fetch(this.endpoint, data);
|
|
18
|
+
const _url = new url_1.URL(url);
|
|
19
|
+
const data = new form_data_1.default();
|
|
20
|
+
if (pdfFormat) {
|
|
21
|
+
data.append("pdfFormat", pdfFormat);
|
|
28
22
|
}
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
data.append("url", _url.href);
|
|
24
|
+
if (header) {
|
|
25
|
+
yield fs_1.promises.access(header, fs_1.constants.R_OK);
|
|
26
|
+
data.append("header.html", (0, fs_1.createReadStream)(header));
|
|
31
27
|
}
|
|
28
|
+
if (footer) {
|
|
29
|
+
yield fs_1.promises.access(footer, fs_1.constants.R_OK);
|
|
30
|
+
data.append("footer.html", (0, fs_1.createReadStream)(footer));
|
|
31
|
+
}
|
|
32
|
+
if (emulatedMediaType) {
|
|
33
|
+
data.append("emulatedMediaType", emulatedMediaType);
|
|
34
|
+
}
|
|
35
|
+
if (properties) {
|
|
36
|
+
converter_utils_1.ConverterUtils.injectPageProperties(data, properties);
|
|
37
|
+
}
|
|
38
|
+
return common_1.GotenbergUtils.fetch(this.endpoint, data);
|
|
32
39
|
});
|
|
33
40
|
}
|
|
34
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.converter.js","sourceRoot":"","sources":["../../../src/chromium/converters/url.converter.ts"],"names":[],"mappings":";;;;AAAA,6BAA0B;AAE1B,kEAAiC;AAEjC,yCAAyD;
|
|
1
|
+
{"version":3,"file":"url.converter.js","sourceRoot":"","sources":["../../../src/chromium/converters/url.converter.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AAErE,6BAA0B;AAE1B,kEAAiC;AAEjC,yCAAyD;AAMzD,8DAA0D;AAC1D,2CAAwC;AACxC,mDAAkD;AAElD,MAAa,YAAa,SAAQ,qBAAS;IACzC;QACE,KAAK,CAAC,2BAAa,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAEK,OAAO,CAAC,EACZ,GAAG,EACH,MAAM,EACN,MAAM,EACN,UAAU,EACV,SAAS,EACT,iBAAiB,GAQlB;;YACC,MAAM,IAAI,GAAG,IAAI,SAAG,CAAC,GAAG,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,IAAI,mBAAQ,EAAE,CAAC;YAC5B,IAAI,SAAS,EAAE;gBACb,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;aACrC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAE9B,IAAI,MAAM,EAAE;gBACV,MAAM,aAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAA,qBAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;aACtD;YAED,IAAI,MAAM,EAAE;gBACV,MAAM,aAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAA,qBAAgB,EAAC,MAAM,CAAC,CAAC,CAAC;aACtD;YAED,IAAI,iBAAiB,EAAE;gBACrB,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;aACrD;YAED,IAAI,UAAU,EAAE;gBACd,gCAAc,CAAC,oBAAoB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;aACvD;YACD,OAAO,uBAAc,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;KAAA;CACF;AA/CD,oCA+CC"}
|
package/dist/common/constants.js
CHANGED
|
@@ -6,5 +6,5 @@ var PdfFormat;
|
|
|
6
6
|
PdfFormat["A_1a"] = "PDF/A-1a";
|
|
7
7
|
PdfFormat["A_2b"] = "PDF/A-2b";
|
|
8
8
|
PdfFormat["A_3b"] = "PDF/A-3b";
|
|
9
|
-
})(PdfFormat
|
|
9
|
+
})(PdfFormat || (exports.PdfFormat = PdfFormat = {}));
|
|
10
10
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,8BAAiB,CAAA;IACjB,8BAAiB,CAAA;IACjB,8BAAiB,CAAA;AACnB,CAAC,EAJW,SAAS,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":";;;AAAA,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,8BAAiB,CAAA;IACjB,8BAAiB,CAAA;IACjB,8BAAiB,CAAA;AACnB,CAAC,EAJW,SAAS,yBAAT,SAAS,QAIpB"}
|
package/dist/gotenberg.d.ts
CHANGED
package/dist/gotenberg.js
CHANGED
|
@@ -3,10 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Gotenberg = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
process.env.SUPPRESS_NO_CONFIG_WARNING = "y";
|
|
6
|
-
require("dotenv
|
|
6
|
+
const dotenv = tslib_1.__importStar(require("dotenv"));
|
|
7
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
8
|
const config_1 = tslib_1.__importDefault(require("config"));
|
|
9
|
+
// Load endpoint from environment-specific file (e.g., .env.development)
|
|
10
|
+
const envFile = `.env.${process.env.NODE_ENV}`;
|
|
11
|
+
const envFileFallback = ".env";
|
|
12
|
+
const dotenvConfig = dotenv.config({ path: path.resolve(envFile) });
|
|
13
|
+
// Fallback to loading the default environment file.
|
|
14
|
+
if (dotenvConfig.error) {
|
|
15
|
+
dotenv.config({ path: path.resolve(envFileFallback) });
|
|
16
|
+
}
|
|
8
17
|
class Gotenberg {
|
|
9
18
|
}
|
|
10
|
-
Gotenberg.endpoint = process.env.GOTENBERG_ENDPOINT || config_1.default.get("gotenberg.endpoint");
|
|
11
19
|
exports.Gotenberg = Gotenberg;
|
|
20
|
+
Gotenberg.endpoint = process.env.GOTENBERG_ENDPOINT || config_1.default.get("gotenberg.endpoint");
|
|
12
21
|
//# sourceMappingURL=gotenberg.js.map
|
package/dist/gotenberg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gotenberg.js","sourceRoot":"","sources":["../src/gotenberg.ts"],"names":[],"mappings":";;;;AAAA,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,GAAG,CAAC;AAE7C,
|
|
1
|
+
{"version":3,"file":"gotenberg.js","sourceRoot":"","sources":["../src/gotenberg.ts"],"names":[],"mappings":";;;;AAAA,OAAO,CAAC,GAAG,CAAC,0BAA0B,GAAG,GAAG,CAAC;AAE7C,uDAAiC;AACjC,mDAA6B;AAC7B,4DAA4B;AAE5B,wEAAwE;AACxE,MAAM,OAAO,GAAG,QAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC/C,MAAM,eAAe,GAAG,MAAM,CAAC;AAE/B,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAEpE,oDAAoD;AACpD,IAAI,YAAY,CAAC,KAAK,EAAE;IACtB,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;CACxD;AAED,MAAa,SAAS;;AAAtB,8BAGC;AAFe,kBAAQ,GACpB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,gBAAM,CAAC,GAAG,CAAS,oBAAoB,CAAC,CAAC"}
|
|
@@ -10,19 +10,14 @@ class LibreOfficeUtils {
|
|
|
10
10
|
static injectFiles(files, data) {
|
|
11
11
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
12
12
|
for (const file of files) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
data.append(filename, (0, fs_1.createReadStream)(file));
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
throw new Error(`${extension} is not supported`);
|
|
22
|
-
}
|
|
13
|
+
yield fs_1.promises.access(file, fs_1.constants.R_OK);
|
|
14
|
+
const filename = path_1.default.basename(file.toString());
|
|
15
|
+
const extension = path_1.default.extname(filename);
|
|
16
|
+
if (constants_1.LIBRE_OFFICE_EXTENSIONS.includes(extension)) {
|
|
17
|
+
data.append(filename, (0, fs_1.createReadStream)(file));
|
|
23
18
|
}
|
|
24
|
-
|
|
25
|
-
throw
|
|
19
|
+
else {
|
|
20
|
+
throw new Error(`${extension} is not supported`);
|
|
26
21
|
}
|
|
27
22
|
}
|
|
28
23
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libre-office.utils.js","sourceRoot":"","sources":["../../../src/libre-office/utils/libre-office.utils.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AACrE,wDAAwB;AAIxB,yCAA8C;AAC9C,2CAAsD;AAGtD,MAAa,gBAAgB;IACpB,MAAM,CAAO,WAAW,CAAC,KAAiB,EAAE,IAAc;;YAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,
|
|
1
|
+
{"version":3,"file":"libre-office.utils.js","sourceRoot":"","sources":["../../../src/libre-office/utils/libre-office.utils.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AACrE,wDAAwB;AAIxB,yCAA8C;AAC9C,2CAAsD;AAGtD,MAAa,gBAAgB;IACpB,MAAM,CAAO,WAAW,CAAC,KAAiB,EAAE,IAAc;;YAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,MAAM,aAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC5C,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAChD,MAAM,SAAS,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzC,IAAI,mCAAuB,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;oBAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAA,qBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;iBAC/C;qBAAM;oBACL,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,mBAAmB,CAAC,CAAC;iBAClD;aACF;QACH,CAAC;KAAA;IAEM,MAAM,CAAC,oBAAoB,CAChC,IAAc,EACd,cAA8B;QAE9B,IAAI,cAAc,CAAC,SAAS,EAAE;YAC5B,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;SAC5D;QAED,IAAI,cAAc,CAAC,gBAAgB,EAAE;YACnC,uBAAc,CAAC,MAAM,CACnB,cAAc,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC;gBACtC,cAAc,CAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC;gBACtC,cAAc,CAAC,gBAAgB,CAAC,EAAE;oBAChC,cAAc,CAAC,gBAAgB,CAAC,IAAI,EACxC,0BAA0B,CAC3B,CAAC;YAEF,IAAI,CAAC,MAAM,CACT,kBAAkB,EAClB,GAAG,cAAc,CAAC,gBAAgB,CAAC,IAAI,IAAI,cAAc,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAChF,CAAC;SACH;IACH,CAAC;CACF;AArCD,4CAqCC"}
|
package/dist/main.config.js
CHANGED
|
@@ -7,7 +7,7 @@ var ChromiumRoute;
|
|
|
7
7
|
ChromiumRoute["URL"] = "url";
|
|
8
8
|
ChromiumRoute["HTML"] = "html";
|
|
9
9
|
ChromiumRoute["MARKDOWN"] = "markdown";
|
|
10
|
-
})(ChromiumRoute
|
|
10
|
+
})(ChromiumRoute || (exports.ChromiumRoute = ChromiumRoute = {}));
|
|
11
11
|
var PdfEngineRoute;
|
|
12
12
|
(function (PdfEngineRoute) {
|
|
13
13
|
PdfEngineRoute["MERGE"] = "merge";
|
|
@@ -18,6 +18,7 @@ var LibreOfficeRoute;
|
|
|
18
18
|
})(LibreOfficeRoute || (LibreOfficeRoute = {}));
|
|
19
19
|
class Chromiumly {
|
|
20
20
|
}
|
|
21
|
+
exports.Chromiumly = Chromiumly;
|
|
21
22
|
Chromiumly.GOTENBERG_ENDPOINT = gotenberg_1.Gotenberg.endpoint;
|
|
22
23
|
Chromiumly.CHROMIUM_PATH = "forms/chromium/convert";
|
|
23
24
|
Chromiumly.PDF_ENGINES_PATH = "forms/pdfengines";
|
|
@@ -33,5 +34,4 @@ Chromiumly.PDF_ENGINE_ROUTES = {
|
|
|
33
34
|
Chromiumly.LIBRE_OFFICE_ROUTES = {
|
|
34
35
|
convert: LibreOfficeRoute.CONVERT,
|
|
35
36
|
};
|
|
36
|
-
exports.Chromiumly = Chromiumly;
|
|
37
37
|
//# sourceMappingURL=main.config.js.map
|
package/dist/main.config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.config.js","sourceRoot":"","sources":["../src/main.config.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAExC,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,4BAAW,CAAA;IACX,8BAAa,CAAA;IACb,sCAAqB,CAAA;AACvB,CAAC,EAJW,aAAa,
|
|
1
|
+
{"version":3,"file":"main.config.js","sourceRoot":"","sources":["../src/main.config.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAExC,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,4BAAW,CAAA;IACX,8BAAa,CAAA;IACb,sCAAqB,CAAA;AACvB,CAAC,EAJW,aAAa,6BAAb,aAAa,QAIxB;AAED,IAAK,cAEJ;AAFD,WAAK,cAAc;IACjB,iCAAe,CAAA;AACjB,CAAC,EAFI,cAAc,KAAd,cAAc,QAElB;AAED,IAAK,gBAEJ;AAFD,WAAK,gBAAgB;IACnB,uCAAmB,CAAA;AACrB,CAAC,EAFI,gBAAgB,KAAhB,gBAAgB,QAEpB;AACD,MAAa,UAAU;;AAAvB,gCAoBC;AAnBwB,6BAAkB,GAAG,qBAAS,CAAC,QAAQ,CAAC;AAExC,wBAAa,GAAG,wBAAwB,CAAC;AACzC,2BAAgB,GAAG,kBAAkB,CAAC;AACtC,4BAAiB,GAAG,mBAAmB,CAAC;AAExC,0BAAe,GAAG;IACvC,GAAG,EAAE,aAAa,CAAC,GAAG;IACtB,IAAI,EAAE,aAAa,CAAC,IAAI;IACxB,QAAQ,EAAE,aAAa,CAAC,QAAQ;CACjC,CAAC;AAEqB,4BAAiB,GAAG;IACzC,KAAK,EAAE,cAAc,CAAC,KAAK;CAC5B,CAAC;AAEqB,8BAAmB,GAAG;IAC3C,OAAO,EAAE,gBAAgB,CAAC,OAAO;CAClC,CAAC"}
|
|
@@ -8,19 +8,14 @@ class PDFEngineUtils {
|
|
|
8
8
|
static injectFiles(files, data) {
|
|
9
9
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
10
10
|
for (const file of files) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
data.append(filename, (0, fs_1.createReadStream)(file));
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
throw new Error(`${extension} is not supported`);
|
|
20
|
-
}
|
|
11
|
+
yield fs_1.promises.access(file, fs_1.constants.R_OK);
|
|
12
|
+
const filename = path_1.default.basename(file.toString());
|
|
13
|
+
const extension = path_1.default.extname(filename);
|
|
14
|
+
if (extension === ".pdf") {
|
|
15
|
+
data.append(filename, (0, fs_1.createReadStream)(file));
|
|
21
16
|
}
|
|
22
|
-
|
|
23
|
-
throw
|
|
17
|
+
else {
|
|
18
|
+
throw new Error(`${extension} is not supported`);
|
|
24
19
|
}
|
|
25
20
|
}
|
|
26
21
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.utils.js","sourceRoot":"","sources":["../../../src/pdf-engines/utils/engine.utils.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AACrE,wDAAwB;AAIxB,MAAa,cAAc;IAClB,MAAM,CAAO,WAAW,CAAC,KAAiB,EAAE,IAAc;;YAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,
|
|
1
|
+
{"version":3,"file":"engine.utils.js","sourceRoot":"","sources":["../../../src/pdf-engines/utils/engine.utils.ts"],"names":[],"mappings":";;;;AAAA,2BAAqE;AACrE,wDAAwB;AAIxB,MAAa,cAAc;IAClB,MAAM,CAAO,WAAW,CAAC,KAAiB,EAAE,IAAc;;YAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;gBACxB,MAAM,aAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,cAAS,CAAC,IAAI,CAAC,CAAC;gBAC5C,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAChD,MAAM,SAAS,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBACzC,IAAI,SAAS,KAAK,MAAM,EAAE;oBACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAA,qBAAgB,EAAC,IAAI,CAAC,CAAC,CAAC;iBAC/C;qBAAM;oBACL,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,mBAAmB,CAAC,CAAC;iBAClD;aACF;QACH,CAAC;KAAA;CACF;AAbD,wCAaC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chromiumly",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "A lightweight Typescript library that interacts with Gotenberg's different modules to convert a variety of document formats to PDF files.",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"types": "dist/main.d.ts",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"author": "Taha Cherfia <taha.cherfia@gmail.com>",
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"engines": {
|
|
18
|
-
"node": ">=
|
|
18
|
+
"node": ">=16.x"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
21
21
|
"gotenberg",
|
|
@@ -32,26 +32,27 @@
|
|
|
32
32
|
"test": "jest --runInBand --ci --coverage --reporters=default --reporters=jest-junit"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@babel/preset-typescript": "7.
|
|
36
|
-
"@types/config": "3.3.
|
|
35
|
+
"@babel/preset-typescript": "7.23.2",
|
|
36
|
+
"@types/config": "3.3.2",
|
|
37
37
|
"@types/dotenv": "8.2.0",
|
|
38
38
|
"@types/form-data": "2.5.0",
|
|
39
|
-
"@types/jest": "29.
|
|
40
|
-
"@types/node": "
|
|
41
|
-
"@types/node-fetch": "2.6.
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "
|
|
43
|
-
"@typescript-eslint/parser": "
|
|
44
|
-
"eslint": "8.
|
|
45
|
-
"jest": "29.
|
|
39
|
+
"@types/jest": "29.5.7",
|
|
40
|
+
"@types/node": "20.8.10",
|
|
41
|
+
"@types/node-fetch": "2.6.8",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "6.9.1",
|
|
43
|
+
"@typescript-eslint/parser": "6.9.1",
|
|
44
|
+
"eslint": "8.52.0",
|
|
45
|
+
"jest": "29.7.0",
|
|
46
46
|
"jest-junit": "16.0.0",
|
|
47
|
-
"ts-jest": "29.1.
|
|
47
|
+
"ts-jest": "29.1.1",
|
|
48
48
|
"ts-node": "10.9.1",
|
|
49
|
-
"
|
|
49
|
+
"tslib": "2.6.2",
|
|
50
|
+
"typescript": "5.2.2"
|
|
50
51
|
},
|
|
51
52
|
"dependencies": {
|
|
52
53
|
"config": "3.3.9",
|
|
53
|
-
"dotenv": "16.
|
|
54
|
+
"dotenv": "16.3.1",
|
|
54
55
|
"form-data": "4.0.0",
|
|
55
|
-
"node-fetch": "2.
|
|
56
|
+
"node-fetch": "2.7.0"
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -4,7 +4,10 @@ import FormData from "form-data";
|
|
|
4
4
|
|
|
5
5
|
import { GotenbergUtils, PdfFormat } from "../../common";
|
|
6
6
|
import { IConverter } from "../interfaces/converter.interface";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
EmulatedMediaType,
|
|
9
|
+
PageProperties,
|
|
10
|
+
} from "../interfaces/converter.types";
|
|
8
11
|
import { ConverterUtils } from "../utils/converter.utils";
|
|
9
12
|
import { Converter } from "./converter";
|
|
10
13
|
import { ChromiumRoute } from "../../main.config";
|
|
@@ -16,26 +19,46 @@ export class HtmlConverter extends Converter implements IConverter {
|
|
|
16
19
|
|
|
17
20
|
async convert({
|
|
18
21
|
html,
|
|
22
|
+
header,
|
|
23
|
+
footer,
|
|
19
24
|
properties,
|
|
20
25
|
pdfFormat,
|
|
26
|
+
emulatedMediaType,
|
|
21
27
|
}: {
|
|
22
28
|
html: PathLike;
|
|
29
|
+
header?: PathLike;
|
|
30
|
+
footer?: PathLike;
|
|
23
31
|
properties?: PageProperties;
|
|
24
32
|
pdfFormat?: PdfFormat;
|
|
33
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
25
34
|
}): Promise<Buffer> {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
await promises.access(html, constants.R_OK);
|
|
36
|
+
const data = new FormData();
|
|
37
|
+
|
|
38
|
+
if (pdfFormat) {
|
|
39
|
+
data.append("pdfFormat", pdfFormat);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
data.append("index.html", createReadStream(html));
|
|
43
|
+
|
|
44
|
+
if (header) {
|
|
45
|
+
await promises.access(header, constants.R_OK);
|
|
46
|
+
data.append("header.html", createReadStream(header));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (footer) {
|
|
50
|
+
await promises.access(footer, constants.R_OK);
|
|
51
|
+
data.append("footer.html", createReadStream(footer));
|
|
39
52
|
}
|
|
53
|
+
|
|
54
|
+
if (emulatedMediaType) {
|
|
55
|
+
data.append("emulatedMediaType", emulatedMediaType);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (properties) {
|
|
59
|
+
ConverterUtils.injectPageProperties(data, properties);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return GotenbergUtils.fetch(this.endpoint, data);
|
|
40
63
|
}
|
|
41
64
|
}
|
|
@@ -4,7 +4,10 @@ import FormData from "form-data";
|
|
|
4
4
|
|
|
5
5
|
import { GotenbergUtils, PdfFormat } from "../../common";
|
|
6
6
|
import { IConverter } from "../interfaces/converter.interface";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
EmulatedMediaType,
|
|
9
|
+
PageProperties,
|
|
10
|
+
} from "../interfaces/converter.types";
|
|
8
11
|
import { ConverterUtils } from "../utils/converter.utils";
|
|
9
12
|
import { Converter } from "./converter";
|
|
10
13
|
import { ChromiumRoute } from "../../main.config";
|
|
@@ -17,29 +20,47 @@ export class MarkdownConverter extends Converter implements IConverter {
|
|
|
17
20
|
async convert({
|
|
18
21
|
html,
|
|
19
22
|
markdown,
|
|
23
|
+
header,
|
|
24
|
+
footer,
|
|
20
25
|
properties,
|
|
21
26
|
pdfFormat,
|
|
27
|
+
emulatedMediaType,
|
|
22
28
|
}: {
|
|
23
29
|
html: PathLike;
|
|
24
30
|
markdown: PathLike;
|
|
31
|
+
header?: PathLike;
|
|
32
|
+
footer?: PathLike;
|
|
25
33
|
properties?: PageProperties;
|
|
26
34
|
pdfFormat?: PdfFormat;
|
|
35
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
27
36
|
}): Promise<Buffer> {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
data.append("pdfFormat", pdfFormat);
|
|
34
|
-
}
|
|
35
|
-
data.append("index.html", createReadStream(html));
|
|
36
|
-
data.append("file.md", createReadStream(markdown));
|
|
37
|
-
if (properties) {
|
|
38
|
-
ConverterUtils.injectPageProperties(data, properties);
|
|
39
|
-
}
|
|
40
|
-
return GotenbergUtils.fetch(this.endpoint, data);
|
|
41
|
-
} catch (error) {
|
|
42
|
-
throw error;
|
|
37
|
+
await promises.access(html, constants.R_OK);
|
|
38
|
+
await promises.access(markdown, constants.R_OK);
|
|
39
|
+
const data = new FormData();
|
|
40
|
+
if (pdfFormat) {
|
|
41
|
+
data.append("pdfFormat", pdfFormat);
|
|
43
42
|
}
|
|
43
|
+
data.append("index.html", createReadStream(html));
|
|
44
|
+
data.append("file.md", createReadStream(markdown));
|
|
45
|
+
|
|
46
|
+
if (header) {
|
|
47
|
+
await promises.access(header, constants.R_OK);
|
|
48
|
+
data.append("header.html", createReadStream(header));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (footer) {
|
|
52
|
+
await promises.access(footer, constants.R_OK);
|
|
53
|
+
data.append("footer.html", createReadStream(footer));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (emulatedMediaType) {
|
|
57
|
+
data.append("emulatedMediaType", emulatedMediaType);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (properties) {
|
|
61
|
+
ConverterUtils.injectPageProperties(data, properties);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return GotenbergUtils.fetch(this.endpoint, data);
|
|
44
65
|
}
|
|
45
66
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
import { createReadStream, promises } from "fs";
|
|
2
3
|
|
|
3
4
|
import fetch from "node-fetch";
|
|
4
5
|
import FormData from "form-data";
|
|
@@ -51,7 +52,7 @@ describe("HtmlConverter", () => {
|
|
|
51
52
|
html: "path/to/index.html",
|
|
52
53
|
pdfFormat: PdfFormat.A_1a,
|
|
53
54
|
});
|
|
54
|
-
expect(mockFormDataAppend).
|
|
55
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
55
56
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
56
57
|
});
|
|
57
58
|
});
|
|
@@ -64,7 +65,63 @@ describe("HtmlConverter", () => {
|
|
|
64
65
|
html: "path/to/index.html",
|
|
65
66
|
properties: { size: { width: 8.3, height: 11.7 } },
|
|
66
67
|
});
|
|
67
|
-
expect(mockFormDataAppend).
|
|
68
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
|
|
69
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("when header parameter is passed", () => {
|
|
74
|
+
it("should return a buffer", async () => {
|
|
75
|
+
mockPromisesAccess.mockResolvedValue();
|
|
76
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
77
|
+
const buffer = await converter.convert({
|
|
78
|
+
html: "path/to/index.html",
|
|
79
|
+
header: "path/to/header.html",
|
|
80
|
+
});
|
|
81
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
82
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe("when footer parameter is passed", () => {
|
|
87
|
+
it("should return a buffer", async () => {
|
|
88
|
+
mockPromisesAccess.mockResolvedValue();
|
|
89
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
90
|
+
const buffer = await converter.convert({
|
|
91
|
+
html: "path/to/index.html",
|
|
92
|
+
footer: "path/to/footer.html",
|
|
93
|
+
});
|
|
94
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
95
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe("when emulatedMediaType parameter is passed", () => {
|
|
100
|
+
it("should return a buffer", async () => {
|
|
101
|
+
mockPromisesAccess.mockResolvedValue();
|
|
102
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
103
|
+
const buffer = await converter.convert({
|
|
104
|
+
html: "path/to/index.html",
|
|
105
|
+
emulatedMediaType: "screen",
|
|
106
|
+
});
|
|
107
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
108
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe("when all parameters are passed", () => {
|
|
113
|
+
it("should return a buffer", async () => {
|
|
114
|
+
mockPromisesAccess.mockResolvedValue();
|
|
115
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
116
|
+
const buffer = await converter.convert({
|
|
117
|
+
html: "path/to/index.html",
|
|
118
|
+
header: "path/to/header.html",
|
|
119
|
+
footer: "path/to/footer.html",
|
|
120
|
+
pdfFormat: PdfFormat.A_1a,
|
|
121
|
+
emulatedMediaType: "screen",
|
|
122
|
+
properties: { size: { width: 8.3, height: 11.7 } },
|
|
123
|
+
});
|
|
124
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(7);
|
|
68
125
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
69
126
|
});
|
|
70
127
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1
2
|
import { createReadStream, promises } from "fs";
|
|
2
3
|
|
|
3
|
-
import fetch from "node-fetch";
|
|
4
4
|
import FormData from "form-data";
|
|
5
|
+
import fetch from "node-fetch";
|
|
5
6
|
|
|
6
7
|
import { PdfFormat } from "../../../common";
|
|
7
8
|
import { MarkdownConverter } from "../markdown.converter";
|
|
@@ -29,7 +30,9 @@ describe("MarkdownConverter", () => {
|
|
|
29
30
|
|
|
30
31
|
describe("convert", () => {
|
|
31
32
|
beforeEach(() => {
|
|
32
|
-
(createReadStream as jest.Mock) = jest
|
|
33
|
+
(createReadStream as jest.Mock) = jest
|
|
34
|
+
.fn()
|
|
35
|
+
.mockImplementation((file) => file);
|
|
33
36
|
});
|
|
34
37
|
|
|
35
38
|
describe("when file exists", () => {
|
|
@@ -53,7 +56,7 @@ describe("MarkdownConverter", () => {
|
|
|
53
56
|
markdown: "path/to/file.md",
|
|
54
57
|
pdfFormat: PdfFormat.A_2b,
|
|
55
58
|
});
|
|
56
|
-
expect(mockFormDataAppend).
|
|
59
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
|
|
57
60
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
58
61
|
});
|
|
59
62
|
});
|
|
@@ -67,7 +70,68 @@ describe("MarkdownConverter", () => {
|
|
|
67
70
|
markdown: "path/to/file.md",
|
|
68
71
|
properties: { size: { width: 8.3, height: 11.7 } },
|
|
69
72
|
});
|
|
70
|
-
expect(mockFormDataAppend).
|
|
73
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(4);
|
|
74
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("when header parameter is passed", () => {
|
|
79
|
+
it("should return a buffer", async () => {
|
|
80
|
+
mockPromisesAccess.mockResolvedValue();
|
|
81
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
82
|
+
const buffer = await converter.convert({
|
|
83
|
+
html: "path/to/index.html",
|
|
84
|
+
markdown: "path/to/file.md",
|
|
85
|
+
header: "path/to/header.html",
|
|
86
|
+
});
|
|
87
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
|
|
88
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("when footer parameter is passed", () => {
|
|
93
|
+
it("should return a buffer", async () => {
|
|
94
|
+
mockPromisesAccess.mockResolvedValue();
|
|
95
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
96
|
+
const buffer = await converter.convert({
|
|
97
|
+
html: "path/to/index.html",
|
|
98
|
+
markdown: "path/to/file.md",
|
|
99
|
+
footer: "path/to/footer.html",
|
|
100
|
+
});
|
|
101
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
|
|
102
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe("when emulatedMediaType parameter is passed", () => {
|
|
107
|
+
it("should return a buffer", async () => {
|
|
108
|
+
mockPromisesAccess.mockResolvedValue();
|
|
109
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
110
|
+
const buffer = await converter.convert({
|
|
111
|
+
html: "path/to/index.html",
|
|
112
|
+
markdown: "path/to/file.md",
|
|
113
|
+
emulatedMediaType: "screen",
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
|
|
117
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe("when all parameters are passed", () => {
|
|
122
|
+
it("should return a buffer", async () => {
|
|
123
|
+
mockPromisesAccess.mockResolvedValue();
|
|
124
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
125
|
+
const buffer = await converter.convert({
|
|
126
|
+
html: "path/to/index.html",
|
|
127
|
+
markdown: "path/to/file.md",
|
|
128
|
+
header: "path/to/header.html",
|
|
129
|
+
footer: "path/to/footer.html",
|
|
130
|
+
pdfFormat: PdfFormat.A_1a,
|
|
131
|
+
emulatedMediaType: "screen",
|
|
132
|
+
properties: { size: { width: 8.3, height: 11.7 } },
|
|
133
|
+
});
|
|
134
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(8);
|
|
71
135
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
72
136
|
});
|
|
73
137
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
import { createReadStream, promises } from "fs";
|
|
2
3
|
import FormData from "form-data";
|
|
4
|
+
import fetch from "node-fetch";
|
|
3
5
|
|
|
4
6
|
import { PdfFormat } from "../../../common";
|
|
5
7
|
import { UrlConverter } from "../url.converter";
|
|
@@ -10,9 +12,16 @@ jest.mock("node-fetch", () => jest.fn());
|
|
|
10
12
|
describe("HtmlConverter", () => {
|
|
11
13
|
const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
|
|
12
14
|
const mockFormDataAppend = jest.spyOn(FormData.prototype, "append");
|
|
15
|
+
const mockPromisesAccess = jest.spyOn(promises, "access");
|
|
13
16
|
|
|
14
17
|
const converter = new UrlConverter();
|
|
15
18
|
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
(createReadStream as jest.Mock) = jest
|
|
21
|
+
.fn()
|
|
22
|
+
.mockImplementation((file) => file);
|
|
23
|
+
});
|
|
24
|
+
|
|
16
25
|
afterEach(() => {
|
|
17
26
|
jest.resetAllMocks();
|
|
18
27
|
});
|
|
@@ -36,6 +45,34 @@ describe("HtmlConverter", () => {
|
|
|
36
45
|
});
|
|
37
46
|
});
|
|
38
47
|
|
|
48
|
+
describe("when header parameter is passed", () => {
|
|
49
|
+
it("should return a buffer", async () => {
|
|
50
|
+
mockFetch.mockResolvedValueOnce(new Response("content"));
|
|
51
|
+
mockPromisesAccess.mockResolvedValue();
|
|
52
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
53
|
+
const buffer = await converter.convert({
|
|
54
|
+
url: "http://www.example.com/",
|
|
55
|
+
header: "path/to/header.html",
|
|
56
|
+
});
|
|
57
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
58
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("when footer parameter is passed", () => {
|
|
63
|
+
it("should return a buffer", async () => {
|
|
64
|
+
mockFetch.mockResolvedValueOnce(new Response("content"));
|
|
65
|
+
mockPromisesAccess.mockResolvedValue();
|
|
66
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
67
|
+
const buffer = await converter.convert({
|
|
68
|
+
url: "http://www.example.com/",
|
|
69
|
+
footer: "path/to/footer.html",
|
|
70
|
+
});
|
|
71
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
72
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
39
76
|
describe("when pdf format parameter is passed", () => {
|
|
40
77
|
it("should return a buffer", async () => {
|
|
41
78
|
mockFetch.mockResolvedValueOnce(new Response("content"));
|
|
@@ -43,7 +80,7 @@ describe("HtmlConverter", () => {
|
|
|
43
80
|
url: "http://www.example.com/",
|
|
44
81
|
pdfFormat: PdfFormat.A_3b,
|
|
45
82
|
});
|
|
46
|
-
expect(mockFormDataAppend).
|
|
83
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
47
84
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
48
85
|
});
|
|
49
86
|
});
|
|
@@ -55,7 +92,37 @@ describe("HtmlConverter", () => {
|
|
|
55
92
|
url: "http://www.example.com/",
|
|
56
93
|
properties: { size: { width: 8.3, height: 11.7 } },
|
|
57
94
|
});
|
|
58
|
-
expect(mockFormDataAppend).
|
|
95
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
|
|
96
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe("when emulatedMediaType parameter is passed", () => {
|
|
101
|
+
it("should return a buffer", async () => {
|
|
102
|
+
mockPromisesAccess.mockResolvedValue();
|
|
103
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
104
|
+
const buffer = await converter.convert({
|
|
105
|
+
url: "http://www.example.com/",
|
|
106
|
+
emulatedMediaType: "screen",
|
|
107
|
+
});
|
|
108
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
109
|
+
expect(buffer).toEqual(Buffer.from("content"));
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("when all parameters are passed", () => {
|
|
114
|
+
it("should return a buffer", async () => {
|
|
115
|
+
mockPromisesAccess.mockResolvedValue();
|
|
116
|
+
mockFetch.mockResolvedValue(new Response("content"));
|
|
117
|
+
const buffer = await converter.convert({
|
|
118
|
+
url: "http://www.example.com/",
|
|
119
|
+
header: "path/to/header.html",
|
|
120
|
+
footer: "path/to/footer.html",
|
|
121
|
+
pdfFormat: PdfFormat.A_1a,
|
|
122
|
+
emulatedMediaType: "screen",
|
|
123
|
+
properties: { size: { width: 8.3, height: 11.7 } },
|
|
124
|
+
});
|
|
125
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(7);
|
|
59
126
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
60
127
|
});
|
|
61
128
|
});
|
|
@@ -64,7 +131,7 @@ describe("HtmlConverter", () => {
|
|
|
64
131
|
it("should throw an error", async () => {
|
|
65
132
|
await expect(() =>
|
|
66
133
|
converter.convert({ url: "invalid url" })
|
|
67
|
-
).rejects.toThrow("Invalid URL
|
|
134
|
+
).rejects.toThrow("Invalid URL");
|
|
68
135
|
});
|
|
69
136
|
});
|
|
70
137
|
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
import { PathLike, constants, createReadStream, promises } from "fs";
|
|
2
|
+
|
|
1
3
|
import { URL } from "url";
|
|
2
4
|
|
|
3
5
|
import FormData from "form-data";
|
|
4
6
|
|
|
5
7
|
import { GotenbergUtils, PdfFormat } from "../../common";
|
|
6
8
|
import { IConverter } from "../interfaces/converter.interface";
|
|
7
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
EmulatedMediaType,
|
|
11
|
+
PageProperties,
|
|
12
|
+
} from "../interfaces/converter.types";
|
|
8
13
|
import { ConverterUtils } from "../utils/converter.utils";
|
|
9
14
|
import { Converter } from "./converter";
|
|
10
15
|
import { ChromiumRoute } from "../../main.config";
|
|
@@ -16,26 +21,44 @@ export class UrlConverter extends Converter implements IConverter {
|
|
|
16
21
|
|
|
17
22
|
async convert({
|
|
18
23
|
url,
|
|
24
|
+
header,
|
|
25
|
+
footer,
|
|
19
26
|
properties,
|
|
20
27
|
pdfFormat,
|
|
28
|
+
emulatedMediaType,
|
|
21
29
|
}: {
|
|
22
30
|
url: string;
|
|
31
|
+
header?: PathLike;
|
|
32
|
+
footer?: PathLike;
|
|
23
33
|
properties?: PageProperties;
|
|
24
34
|
pdfFormat?: PdfFormat;
|
|
35
|
+
emulatedMediaType?: EmulatedMediaType;
|
|
25
36
|
}): Promise<Buffer> {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
37
|
+
const _url = new URL(url);
|
|
38
|
+
const data = new FormData();
|
|
39
|
+
if (pdfFormat) {
|
|
40
|
+
data.append("pdfFormat", pdfFormat);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
data.append("url", _url.href);
|
|
44
|
+
|
|
45
|
+
if (header) {
|
|
46
|
+
await promises.access(header, constants.R_OK);
|
|
47
|
+
data.append("header.html", createReadStream(header));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (footer) {
|
|
51
|
+
await promises.access(footer, constants.R_OK);
|
|
52
|
+
data.append("footer.html", createReadStream(footer));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (emulatedMediaType) {
|
|
56
|
+
data.append("emulatedMediaType", emulatedMediaType);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (properties) {
|
|
60
|
+
ConverterUtils.injectPageProperties(data, properties);
|
|
39
61
|
}
|
|
62
|
+
return GotenbergUtils.fetch(this.endpoint, data);
|
|
40
63
|
}
|
|
41
64
|
}
|
package/src/gotenberg.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
process.env.SUPPRESS_NO_CONFIG_WARNING = "y";
|
|
2
2
|
|
|
3
|
-
import "dotenv
|
|
3
|
+
import * as dotenv from "dotenv";
|
|
4
|
+
import * as path from "path";
|
|
4
5
|
import config from "config";
|
|
5
6
|
|
|
7
|
+
// Load endpoint from environment-specific file (e.g., .env.development)
|
|
8
|
+
const envFile = `.env.${process.env.NODE_ENV}`;
|
|
9
|
+
const envFileFallback = ".env";
|
|
10
|
+
|
|
11
|
+
const dotenvConfig = dotenv.config({ path: path.resolve(envFile) });
|
|
12
|
+
|
|
13
|
+
// Fallback to loading the default environment file.
|
|
14
|
+
if (dotenvConfig.error) {
|
|
15
|
+
dotenv.config({ path: path.resolve(envFileFallback) });
|
|
16
|
+
}
|
|
17
|
+
|
|
6
18
|
export class Gotenberg {
|
|
7
19
|
public static endpoint: string =
|
|
8
20
|
process.env.GOTENBERG_ENDPOINT || config.get<string>("gotenberg.endpoint");
|
|
@@ -10,17 +10,13 @@ import { PageProperties } from "../interfaces/libre-office.types";
|
|
|
10
10
|
export class LibreOfficeUtils {
|
|
11
11
|
public static async injectFiles(files: PathLike[], data: FormData) {
|
|
12
12
|
for (const file of files) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
throw new Error(`${extension} is not supported`);
|
|
21
|
-
}
|
|
22
|
-
} catch (error) {
|
|
23
|
-
throw error;
|
|
13
|
+
await promises.access(file, constants.R_OK);
|
|
14
|
+
const filename = path.basename(file.toString());
|
|
15
|
+
const extension = path.extname(filename);
|
|
16
|
+
if (LIBRE_OFFICE_EXTENSIONS.includes(extension)) {
|
|
17
|
+
data.append(filename, createReadStream(file));
|
|
18
|
+
} else {
|
|
19
|
+
throw new Error(`${extension} is not supported`);
|
|
24
20
|
}
|
|
25
21
|
}
|
|
26
22
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
2
|
import { promises, createReadStream } from "fs";
|
|
3
|
+
import { LibreOfficeUtils } from "../libre-office.utils";
|
|
3
4
|
|
|
4
5
|
import FormData from "form-data";
|
|
5
6
|
|
|
@@ -26,7 +27,7 @@ describe("LibreOfficeUtils", () => {
|
|
|
26
27
|
["path/to/file.docx", "path/to/file.bib"],
|
|
27
28
|
data
|
|
28
29
|
);
|
|
29
|
-
expect(mockFormDataAppend).
|
|
30
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
30
31
|
});
|
|
31
32
|
});
|
|
32
33
|
|
|
@@ -64,7 +65,7 @@ describe("LibreOfficeUtils", () => {
|
|
|
64
65
|
LibreOfficeUtils.injectPageProperties(data, {
|
|
65
66
|
landscape: true,
|
|
66
67
|
});
|
|
67
|
-
expect(mockFormDataAppend).
|
|
68
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
68
69
|
expect(data.append).toHaveBeenCalledWith("landscape", "true");
|
|
69
70
|
});
|
|
70
71
|
});
|
|
@@ -76,7 +77,7 @@ describe("LibreOfficeUtils", () => {
|
|
|
76
77
|
LibreOfficeUtils.injectPageProperties(data, {
|
|
77
78
|
nativePageRanges: { from: 1, to: 6 },
|
|
78
79
|
});
|
|
79
|
-
expect(mockFormDataAppend).
|
|
80
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
80
81
|
expect(data.append).toHaveBeenCalledWith("nativePageRanges", "1-6");
|
|
81
82
|
});
|
|
82
83
|
});
|
|
@@ -1,21 +1,18 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
import { createReadStream, promises } from "fs";
|
|
3
|
+
import FormData from "form-data";
|
|
4
|
+
import fs from "fs/promises";
|
|
5
|
+
import fetch from "node-fetch";
|
|
1
6
|
import path from "path";
|
|
2
7
|
|
|
3
|
-
import { PDFEngine } from "./../pdf.engine";
|
|
4
8
|
import { PdfFormat } from "../../common";
|
|
5
|
-
|
|
6
|
-
import { promises, createReadStream } from "fs";
|
|
7
|
-
|
|
8
|
-
import fetch from "node-fetch";
|
|
9
|
-
import FormData from "form-data";
|
|
9
|
+
import { PDFEngine } from "../pdf.engine";
|
|
10
10
|
|
|
11
11
|
const { Response } = jest.requireActual("node-fetch");
|
|
12
12
|
jest.mock("node-fetch", () => jest.fn());
|
|
13
13
|
|
|
14
14
|
describe("PDFEngine", () => {
|
|
15
|
-
const mockProcessCwd = jest.spyOn(process, "cwd");
|
|
16
15
|
const mockPromisesAccess = jest.spyOn(promises, "access");
|
|
17
|
-
const mockPromisesMkDir = jest.spyOn(promises, "mkdir");
|
|
18
|
-
const mockPromisesWriteFile = jest.spyOn(promises, "writeFile");
|
|
19
16
|
const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
|
|
20
17
|
const mockFormDataAppend = jest.spyOn(FormData.prototype, "append");
|
|
21
18
|
|
|
@@ -38,7 +35,7 @@ describe("PDFEngine", () => {
|
|
|
38
35
|
files: ["path/to/file.docx", "path/to/file.bib"],
|
|
39
36
|
});
|
|
40
37
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
41
|
-
expect(mockFormDataAppend).
|
|
38
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
42
39
|
});
|
|
43
40
|
});
|
|
44
41
|
|
|
@@ -53,7 +50,7 @@ describe("PDFEngine", () => {
|
|
|
53
50
|
merge: true,
|
|
54
51
|
});
|
|
55
52
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
56
|
-
expect(mockFormDataAppend).
|
|
53
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(5);
|
|
57
54
|
});
|
|
58
55
|
});
|
|
59
56
|
});
|
|
@@ -66,19 +63,60 @@ describe("PDFEngine", () => {
|
|
|
66
63
|
files: ["path/to/file.pdf", "path/to/another-file.pdf"],
|
|
67
64
|
});
|
|
68
65
|
expect(buffer).toEqual(Buffer.from("content"));
|
|
69
|
-
expect(mockFormDataAppend).
|
|
66
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
70
67
|
});
|
|
71
68
|
});
|
|
72
69
|
|
|
73
70
|
describe("generate", () => {
|
|
71
|
+
const mockFilename = "test.pdf";
|
|
72
|
+
const mockBuffer = Buffer.from("mock pdf content");
|
|
73
|
+
|
|
74
|
+
afterAll(() => {
|
|
75
|
+
jest.restoreAllMocks();
|
|
76
|
+
});
|
|
77
|
+
|
|
74
78
|
it("should generate a PDF file", async () => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
const mockGeneratedDir = path.join(process.cwd(), "__generated__");
|
|
80
|
+
const mockGeneratedFilePath = path.join(mockGeneratedDir, mockFilename);
|
|
81
|
+
|
|
82
|
+
const mockPromisesMkDir = jest
|
|
83
|
+
.spyOn(fs, "mkdir")
|
|
84
|
+
.mockResolvedValueOnce(mockGeneratedDir);
|
|
85
|
+
|
|
86
|
+
const mockPromisesWriteFile = jest
|
|
87
|
+
.spyOn(fs, "writeFile")
|
|
88
|
+
.mockResolvedValueOnce();
|
|
89
|
+
|
|
90
|
+
await PDFEngine.generate(mockFilename, mockBuffer);
|
|
91
|
+
|
|
92
|
+
expect(mockPromisesMkDir).toHaveBeenCalledWith(mockGeneratedDir, {
|
|
93
|
+
recursive: true,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
expect(mockPromisesWriteFile).toHaveBeenCalledWith(
|
|
97
|
+
mockGeneratedFilePath,
|
|
98
|
+
mockBuffer
|
|
81
99
|
);
|
|
82
100
|
});
|
|
101
|
+
|
|
102
|
+
it("should handle errors during file generation", async () => {
|
|
103
|
+
jest
|
|
104
|
+
.spyOn(fs, "mkdir")
|
|
105
|
+
.mockRejectedValueOnce(new Error("Cannot create directory"));
|
|
106
|
+
|
|
107
|
+
await expect(
|
|
108
|
+
PDFEngine.generate(mockFilename, mockBuffer)
|
|
109
|
+
).rejects.toThrow("Cannot create directory");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should handle errors during file writing", async () => {
|
|
113
|
+
jest
|
|
114
|
+
.spyOn(fs, "writeFile")
|
|
115
|
+
.mockRejectedValueOnce(new Error("Failed to write to file"));
|
|
116
|
+
|
|
117
|
+
await expect(
|
|
118
|
+
PDFEngine.generate(mockFilename, mockBuffer)
|
|
119
|
+
).rejects.toThrow("Failed to write to file");
|
|
120
|
+
});
|
|
83
121
|
});
|
|
84
122
|
});
|
|
@@ -6,17 +6,13 @@ import FormData from "form-data";
|
|
|
6
6
|
export class PDFEngineUtils {
|
|
7
7
|
public static async injectFiles(files: PathLike[], data: FormData) {
|
|
8
8
|
for (const file of files) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
throw new Error(`${extension} is not supported`);
|
|
17
|
-
}
|
|
18
|
-
} catch (error) {
|
|
19
|
-
throw error;
|
|
9
|
+
await promises.access(file, constants.R_OK);
|
|
10
|
+
const filename = path.basename(file.toString());
|
|
11
|
+
const extension = path.extname(filename);
|
|
12
|
+
if (extension === ".pdf") {
|
|
13
|
+
data.append(filename, createReadStream(file));
|
|
14
|
+
} else {
|
|
15
|
+
throw new Error(`${extension} is not supported`);
|
|
20
16
|
}
|
|
21
17
|
}
|
|
22
18
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
+
import { createReadStream, promises } from "fs";
|
|
4
3
|
import FormData from "form-data";
|
|
5
4
|
|
|
5
|
+
import { PDFEngineUtils } from "./../engine.utils";
|
|
6
|
+
|
|
6
7
|
describe("PDFEngineUtils", () => {
|
|
7
8
|
const mockPromisesAccess = jest.spyOn(promises, "access");
|
|
8
9
|
const mockFormDataAppend = jest.spyOn(FormData.prototype, "append");
|
|
@@ -26,7 +27,7 @@ describe("PDFEngineUtils", () => {
|
|
|
26
27
|
["path/to/file.pdf", "path/to/another-file.pdf"],
|
|
27
28
|
data
|
|
28
29
|
);
|
|
29
|
-
expect(mockFormDataAppend).
|
|
30
|
+
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
30
31
|
});
|
|
31
32
|
});
|
|
32
33
|
|