chromiumly 2.4.0 → 2.5.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.
Files changed (77) hide show
  1. package/README.md +57 -40
  2. package/dist/chromium/converters/converter.d.ts +13 -0
  3. package/dist/chromium/converters/converter.js +10 -0
  4. package/dist/chromium/converters/converter.js.map +1 -1
  5. package/dist/chromium/converters/html.converter.d.ts +32 -6
  6. package/dist/chromium/converters/html.converter.js +30 -9
  7. package/dist/chromium/converters/html.converter.js.map +1 -1
  8. package/dist/chromium/converters/markdown.converter.d.ts +34 -7
  9. package/dist/chromium/converters/markdown.converter.js +32 -16
  10. package/dist/chromium/converters/markdown.converter.js.map +1 -1
  11. package/dist/chromium/converters/url.converter.d.ts +31 -5
  12. package/dist/chromium/converters/url.converter.js +29 -1
  13. package/dist/chromium/converters/url.converter.js.map +1 -1
  14. package/dist/chromium/index.js.map +1 -1
  15. package/dist/chromium/interfaces/converter.types.d.ts +3 -6
  16. package/dist/chromium/utils/converter.utils.d.ts +27 -1
  17. package/dist/chromium/utils/converter.utils.js +48 -21
  18. package/dist/chromium/utils/converter.utils.js.map +1 -1
  19. package/dist/common/constants.js.map +1 -1
  20. package/dist/common/gotenberg.utils.d.ts +18 -0
  21. package/dist/common/gotenberg.utils.js +18 -0
  22. package/dist/common/gotenberg.utils.js.map +1 -1
  23. package/dist/common/index.d.ts +1 -0
  24. package/dist/common/index.js.map +1 -1
  25. package/dist/common/types.d.ts +3 -0
  26. package/dist/common/types.js +3 -0
  27. package/dist/common/types.js.map +1 -0
  28. package/dist/gotenberg.d.ts +8 -0
  29. package/dist/gotenberg.js +8 -0
  30. package/dist/gotenberg.js.map +1 -1
  31. package/dist/libre-office/index.js.map +1 -1
  32. package/dist/libre-office/utils/constants.js +76 -76
  33. package/dist/libre-office/utils/constants.js.map +1 -1
  34. package/dist/libre-office/utils/libre-office.utils.d.ts +19 -4
  35. package/dist/libre-office/utils/libre-office.utils.js +39 -7
  36. package/dist/libre-office/utils/libre-office.utils.js.map +1 -1
  37. package/dist/main.config.d.ts +43 -0
  38. package/dist/main.config.js +43 -0
  39. package/dist/main.config.js.map +1 -1
  40. package/dist/main.js.map +1 -1
  41. package/dist/pdf-engines/index.js.map +1 -1
  42. package/dist/pdf-engines/pdf.engine.d.ts +31 -5
  43. package/dist/pdf-engines/pdf.engine.js +31 -3
  44. package/dist/pdf-engines/pdf.engine.js.map +1 -1
  45. package/dist/pdf-engines/utils/engine.utils.d.ts +12 -3
  46. package/dist/pdf-engines/utils/engine.utils.js +27 -8
  47. package/dist/pdf-engines/utils/engine.utils.js.map +1 -1
  48. package/package.json +8 -7
  49. package/src/chromium/converters/converter.ts +18 -5
  50. package/src/chromium/converters/html.converter.ts +82 -61
  51. package/src/chromium/converters/markdown.converter.ts +86 -69
  52. package/src/chromium/converters/tests/html.converter.test.ts +119 -135
  53. package/src/chromium/converters/tests/markdown.converter.test.ts +131 -150
  54. package/src/chromium/converters/tests/url.converter.test.ts +114 -123
  55. package/src/chromium/converters/url.converter.ts +84 -60
  56. package/src/chromium/index.ts +3 -3
  57. package/src/chromium/interfaces/converter.types.ts +27 -27
  58. package/src/chromium/utils/converter.utils.ts +165 -139
  59. package/src/chromium/utils/tests/converter.utils.test.ts +312 -311
  60. package/src/common/constants.ts +3 -3
  61. package/src/common/gotenberg.utils.ts +36 -17
  62. package/src/common/index.ts +3 -2
  63. package/src/common/tests/gotenberg.utils.test.ts +54 -54
  64. package/src/common/types.ts +3 -0
  65. package/src/gotenberg.ts +13 -4
  66. package/src/libre-office/index.ts +2 -2
  67. package/src/libre-office/interfaces/libre-office.types.ts +2 -2
  68. package/src/libre-office/utils/constants.ts +76 -76
  69. package/src/libre-office/utils/libre-office.utils.ts +72 -37
  70. package/src/libre-office/utils/tests/libre-office.utils.test.ts +100 -68
  71. package/src/main.config.ts +68 -22
  72. package/src/main.ts +3 -3
  73. package/src/pdf-engines/index.ts +1 -1
  74. package/src/pdf-engines/pdf.engine.ts +77 -49
  75. package/src/pdf-engines/tests/pdf.engine.test.ts +94 -94
  76. package/src/pdf-engines/utils/engine.utils.ts +30 -12
  77. package/src/pdf-engines/utils/tests/engine.utils.test.ts +60 -48
@@ -1,80 +1,97 @@
1
- import { constants, createReadStream, PathLike, promises } from "fs";
2
-
3
1
  import FormData from "form-data";
4
2
 
5
- import { GotenbergUtils, PdfFormat } from "../../common";
3
+ import {GotenbergUtils, PdfFormat, PathLikeOrReadStream} from "../../common";
6
4
  import {
7
- EmulatedMediaType,
8
- PageProperties,
5
+ EmulatedMediaType,
6
+ PageProperties,
9
7
  } from "../interfaces/converter.types";
10
- import { ConverterUtils } from "../utils/converter.utils";
11
- import { Converter } from "./converter";
12
- import { ChromiumRoute } from "../../main.config";
8
+ import {ConverterUtils} from "../utils/converter.utils";
9
+ import {Converter} from "./converter";
10
+ import {ChromiumRoute} from "../../main.config";
13
11
 
12
+ /**
13
+ * Class representing a Markdown converter that extends the base Converter class.
14
+ * This class is used to convert HTML with markdown content to PDF using Gotenberg service.
15
+ *
16
+ * @extends Converter
17
+ */
14
18
  export class MarkdownConverter extends Converter {
15
- constructor() {
16
- super(ChromiumRoute.MARKDOWN);
17
- }
19
+ /**
20
+ * Creates an instance of MarkdownConverter.
21
+ * Initializes the converter with the Markdown conversion route.
22
+ */
23
+ constructor() {
24
+ super(ChromiumRoute.MARKDOWN);
25
+ }
18
26
 
19
- async convert({
20
- html,
21
- markdown,
22
- header,
23
- footer,
24
- properties,
25
- pdfFormat,
26
- pdfUA,
27
- emulatedMediaType,
28
- waitDelay,
29
- waitForExpression,
30
- userAgent,
31
- extraHttpHeaders,
32
- failOnConsoleExceptions,
33
- }: {
34
- html: PathLike;
35
- markdown: PathLike;
36
- header?: PathLike;
37
- footer?: PathLike;
38
- properties?: PageProperties;
39
- pdfFormat?: PdfFormat;
40
- pdfUA?: boolean;
41
- emulatedMediaType?: EmulatedMediaType;
42
- waitDelay?: string;
43
- waitForExpression?: string;
44
- userAgent?: string;
45
- extraHttpHeaders?: Record<string, string>;
46
- failOnConsoleExceptions?: boolean;
47
- }): Promise<Buffer> {
48
- const data = new FormData();
27
+ /**
28
+ * Converts HTML with markdown content to PDF.
29
+ *
30
+ * @param {Object} options - Conversion options.
31
+ * @param {PathLikeOrReadStream} options.html - PathLike or ReadStream of the HTML content to be converted.
32
+ * @param {PathLikeOrReadStream} options.markdown - PathLike or ReadStream of the Markdown content to be converted.
33
+ * @param {PathLikeOrReadStream} [options.header] - PathLike or ReadStream of the header HTML content.
34
+ * @param {PathLikeOrReadStream} [options.footer] - PathLike or ReadStream of the footer HTML content.
35
+ * @param {PageProperties} [options.properties] - Page properties for the conversion.
36
+ * @param {PdfFormat} [options.pdfFormat] - PDF format options.
37
+ * @param {boolean} [options.pdfUA] - Indicates whether to generate PDF/UA compliant output.
38
+ * @param {EmulatedMediaType} [options.emulatedMediaType] - Emulated media type for the conversion.
39
+ * @param {string} [options.waitDelay] - Delay before the conversion process starts.
40
+ * @param {string} [options.waitForExpression] - JavaScript expression to wait for before completing the conversion.
41
+ * @param {string} [options.userAgent] - User agent string to use during the conversion.
42
+ * @param {Record<string, string>} [options.extraHttpHeaders] - Additional HTTP headers for the conversion.
43
+ * @param {boolean} [options.failOnConsoleExceptions] - Whether to fail on console exceptions during conversion.
44
+ * @returns {Promise<Buffer>} A Promise resolving to the converted PDF content as a Buffer.
45
+ */
46
+ async convert({
47
+ html,
48
+ markdown,
49
+ header,
50
+ footer,
51
+ properties,
52
+ pdfFormat,
53
+ pdfUA,
54
+ emulatedMediaType,
55
+ waitDelay,
56
+ waitForExpression,
57
+ userAgent,
58
+ extraHttpHeaders,
59
+ failOnConsoleExceptions,
60
+ }: {
61
+ html: PathLikeOrReadStream;
62
+ markdown: PathLikeOrReadStream;
63
+ header?: PathLikeOrReadStream;
64
+ footer?: PathLikeOrReadStream;
65
+ properties?: PageProperties;
66
+ pdfFormat?: PdfFormat;
67
+ pdfUA?: boolean;
68
+ emulatedMediaType?: EmulatedMediaType;
69
+ waitDelay?: string;
70
+ waitForExpression?: string;
71
+ userAgent?: string;
72
+ extraHttpHeaders?: Record<string, string>;
73
+ failOnConsoleExceptions?: boolean;
74
+ }): Promise<Buffer> {
75
+ const data = new FormData();
49
76
 
50
- if (Buffer.isBuffer(html)) {
51
- data.append("files", html, "index.html");
52
- } else {
53
- await promises.access(html, constants.R_OK);
54
- data.append("files", createReadStream(html), "index.html");
55
- }
77
+ await ConverterUtils.addFile(data, html, "index.html");
56
78
 
57
- if (Buffer.isBuffer(markdown)) {
58
- data.append("files", createReadStream(markdown), "file.md");
59
- } else {
60
- await promises.access(markdown, constants.R_OK);
61
- data.append("file.md", createReadStream(markdown));
62
- }
79
+ await ConverterUtils.addFile(data, markdown, "file.md");
63
80
 
64
- ConverterUtils.customize(data, {
65
- header,
66
- footer,
67
- properties,
68
- pdfFormat,
69
- pdfUA,
70
- emulatedMediaType,
71
- waitDelay,
72
- waitForExpression,
73
- userAgent,
74
- extraHttpHeaders,
75
- failOnConsoleExceptions,
76
- });
81
+ await ConverterUtils.customize(data, {
82
+ header,
83
+ footer,
84
+ properties,
85
+ pdfFormat,
86
+ pdfUA,
87
+ emulatedMediaType,
88
+ waitDelay,
89
+ waitForExpression,
90
+ userAgent,
91
+ extraHttpHeaders,
92
+ failOnConsoleExceptions,
93
+ });
77
94
 
78
- return GotenbergUtils.fetch(this.endpoint, data);
79
- }
80
- }
95
+ return GotenbergUtils.fetch(this.endpoint, data);
96
+ }
97
+ }
@@ -1,163 +1,147 @@
1
1
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
- import { createReadStream, promises } from "fs";
2
+ import {createReadStream, promises} from "fs";
3
3
 
4
4
  import fetch from "node-fetch";
5
5
  import FormData from "form-data";
6
6
 
7
- import { PdfFormat } from "../../../common";
8
- import { HtmlConverter } from "../html.converter";
7
+ import {PdfFormat} from "../../../common";
8
+ import {HtmlConverter} from "../html.converter";
9
9
 
10
- const { Response } = jest.requireActual("node-fetch");
10
+ const {Response} = jest.requireActual("node-fetch");
11
11
  jest.mock("node-fetch", () => jest.fn());
12
12
 
13
13
  describe("HtmlConverter", () => {
14
- const mockPromisesAccess = jest.spyOn(promises, "access");
15
- const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
16
- const mockFormDataAppend = jest.spyOn(FormData.prototype, "append");
17
-
18
- const converter = new HtmlConverter();
19
- beforeEach(() => {
20
- (createReadStream as jest.Mock) = jest
21
- .fn()
22
- .mockImplementation((file) => file);
23
- });
24
-
25
- afterEach(() => {
26
- jest.resetAllMocks();
27
- });
28
-
29
- describe("endpoint", () => {
30
- it("should route to Chromium HTML route", () => {
31
- expect(converter.endpoint).toEqual(
32
- "http://localhost:3000/forms/chromium/convert/html"
33
- );
34
- });
35
- });
36
-
37
- describe("convert", () => {
38
- describe("when file exists", () => {
39
- it("should return a buffer", async () => {
40
- mockPromisesAccess.mockResolvedValue();
41
- mockFetch.mockResolvedValue(new Response("content"));
42
- const buffer = await converter.convert({ html: "path/to/index.html" });
43
- expect(buffer).toEqual(Buffer.from("content"));
44
- });
45
- });
14
+ const converter = new HtmlConverter();
46
15
 
47
- describe("when buffer is passed", () => {
48
- it("should return a buffer", async () => {
49
- mockPromisesAccess.mockResolvedValue();
50
- mockFetch.mockResolvedValue(new Response("content"));
51
- const buffer = await converter.convert({
52
- html: Buffer.from("html"),
16
+ describe("endpoint", () => {
17
+ it("should route to Chromium HTML route", () => {
18
+ expect(converter.endpoint).toEqual(
19
+ "http://localhost:3000/forms/chromium/convert/html"
20
+ );
53
21
  });
54
- expect(buffer).toEqual(Buffer.from("content"));
55
- });
56
22
  });
57
23
 
58
- describe("when pdf format parameter is passed", () => {
59
- it("should return a buffer", async () => {
60
- mockPromisesAccess.mockResolvedValue();
61
- mockFetch.mockResolvedValue(new Response("content"));
62
- const buffer = await converter.convert({
63
- html: "path/to/index.html",
64
- pdfFormat: PdfFormat.A_1a,
24
+ describe("convert", () => {
25
+ const mockPromisesAccess = jest.spyOn(promises, "access");
26
+ const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
27
+ const mockFormDataAppend = jest.spyOn(FormData.prototype, "append");
28
+
29
+ beforeEach(() => {
30
+ (createReadStream as jest.Mock) = jest.fn()
65
31
  });
66
- expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
67
- expect(buffer).toEqual(Buffer.from("content"));
68
- });
69
- });
70
32
 
71
- describe("when page properties parameter is passed", () => {
72
- it("should return a buffer", async () => {
73
- mockPromisesAccess.mockResolvedValue();
74
- mockFetch.mockResolvedValue(new Response("content"));
75
- const buffer = await converter.convert({
76
- html: "path/to/index.html",
77
- properties: { size: { width: 8.3, height: 11.7 } },
33
+ afterEach(() => {
34
+ jest.resetAllMocks();
78
35
  });
79
- expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
80
- expect(buffer).toEqual(Buffer.from("content"));
81
- });
82
- });
83
36
 
84
- describe("when header parameter is passed", () => {
85
- it("should return a buffer", async () => {
86
- mockPromisesAccess.mockResolvedValue();
87
- mockFetch.mockResolvedValue(new Response("content"));
88
- const buffer = await converter.convert({
89
- html: "path/to/index.html",
90
- header: "path/to/header.html",
37
+ describe("when html parameter is passed", () => {
38
+ it("should return a buffer", async () => {
39
+ mockFetch.mockResolvedValue(new Response("content"));
40
+ const buffer = await converter.convert({
41
+ html: Buffer.from("data"),
42
+ });
43
+ expect(buffer).toEqual(Buffer.from("content"));
44
+ });
91
45
  });
92
- expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
93
- expect(buffer).toEqual(Buffer.from("content"));
94
- });
95
- });
96
46
 
97
- describe("when footer parameter is passed", () => {
98
- it("should return a buffer", async () => {
99
- mockPromisesAccess.mockResolvedValue();
100
- mockFetch.mockResolvedValue(new Response("content"));
101
- const buffer = await converter.convert({
102
- html: "path/to/index.html",
103
- footer: "path/to/footer.html",
47
+ describe("when pdf format parameter is passed", () => {
48
+ it("should return a buffer", async () => {
49
+ mockFetch.mockResolvedValue(new Response("content"));
50
+ const buffer = await converter.convert({
51
+ html: Buffer.from("data"),
52
+ pdfFormat: PdfFormat.A_1a,
53
+ });
54
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
55
+ expect(buffer).toEqual(Buffer.from("content"));
56
+ });
104
57
  });
105
- expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
106
- expect(buffer).toEqual(Buffer.from("content"));
107
- });
108
- });
109
58
 
110
- describe("when emulatedMediaType parameter is passed", () => {
111
- it("should return a buffer", async () => {
112
- mockPromisesAccess.mockResolvedValue();
113
- mockFetch.mockResolvedValue(new Response("content"));
114
- const buffer = await converter.convert({
115
- html: "path/to/index.html",
116
- emulatedMediaType: "screen",
59
+ describe("when page properties parameter is passed", () => {
60
+ it("should return a buffer", async () => {
61
+ mockFetch.mockResolvedValue(new Response("content"));
62
+ const buffer = await converter.convert({
63
+ html: Buffer.from("data"),
64
+ properties: {size: {width: 8.3, height: 11.7}},
65
+ });
66
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
67
+ expect(buffer).toEqual(Buffer.from("content"));
68
+ });
117
69
  });
118
- expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
119
- expect(buffer).toEqual(Buffer.from("content"));
120
- });
121
- });
122
70
 
123
- describe("when all parameters are passed", () => {
124
- it("should return a buffer", async () => {
125
- mockPromisesAccess.mockResolvedValue();
126
- mockFetch.mockResolvedValue(new Response("content"));
127
- const buffer = await converter.convert({
128
- html: "path/to/index.html",
129
- header: "path/to/header.html",
130
- footer: "path/to/footer.html",
131
- pdfFormat: PdfFormat.A_1a,
132
- emulatedMediaType: "screen",
133
- properties: { size: { width: 8.3, height: 11.7 } },
71
+ describe("when header parameter is passed", () => {
72
+ it("should return a buffer", async () => {
73
+ mockFetch.mockResolvedValue(new Response("content"));
74
+ const buffer = await converter.convert({
75
+ html: Buffer.from("data"),
76
+ header: Buffer.from("header"),
77
+ });
78
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
79
+ expect(buffer).toEqual(Buffer.from("content"));
80
+ });
134
81
  });
135
- expect(mockFormDataAppend).toHaveBeenCalledTimes(7);
136
- expect(buffer).toEqual(Buffer.from("content"));
137
- });
138
- });
139
82
 
140
- describe("when file does not exist", () => {
141
- it("should throw an error", async () => {
142
- const errorMessage =
143
- "ENOENT: no such file or directory, access 'path/to/index.html'";
144
- mockPromisesAccess.mockRejectedValue(new Error(errorMessage));
145
- await expect(() =>
146
- converter.convert({ html: "path/to/index.html" })
147
- ).rejects.toThrow(errorMessage);
148
- });
149
- });
83
+ describe("when footer parameter is passed", () => {
84
+ it("should return a buffer", async () => {
85
+ mockFetch.mockResolvedValue(new Response("content"));
86
+ const buffer = await converter.convert({
87
+ html: Buffer.from("data"),
88
+ footer: Buffer.from("footer"),
89
+ });
90
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
91
+ expect(buffer).toEqual(Buffer.from("content"));
92
+ });
93
+ });
94
+
95
+ describe("when emulatedMediaType parameter is passed", () => {
96
+ it("should return a buffer", async () => {
97
+ mockFetch.mockResolvedValue(new Response("content"));
98
+ const buffer = await converter.convert({
99
+ html: Buffer.from("data"),
100
+ emulatedMediaType: "screen",
101
+ });
102
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
103
+ expect(buffer).toEqual(Buffer.from("content"));
104
+ });
105
+ });
106
+
107
+ describe("when all parameters are passed", () => {
108
+ it("should return a buffer", async () => {
109
+ mockPromisesAccess.mockResolvedValue();
110
+ mockFetch.mockResolvedValue(new Response("content"));
111
+ const buffer = await converter.convert({
112
+ html: Buffer.from("data"),
113
+ header: Buffer.from("header"),
114
+ footer: Buffer.from("footer"),
115
+ pdfFormat: PdfFormat.A_1a,
116
+ emulatedMediaType: "screen",
117
+ properties: {size: {width: 8.3, height: 11.7}},
118
+ });
119
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(7);
120
+ expect(buffer).toEqual(Buffer.from("content"));
121
+ });
122
+ });
123
+
124
+ describe("when file does not exist", () => {
125
+ it("should throw an error", async () => {
126
+ const errorMessage =
127
+ "ENOENT: no such file or directory, access 'path/to/index.html'";
128
+ mockPromisesAccess.mockRejectedValue(new Error(errorMessage));
129
+ await expect(() =>
130
+ converter.convert({html: "path/to/index.html"})
131
+ ).rejects.toThrow(errorMessage);
132
+ });
133
+ });
150
134
 
151
- describe("when fetch request fails", () => {
152
- it("should throw an error", async () => {
153
- const errorMessage =
154
- "FetchError: request to http://localhost:3000/forms/chromium/convert/html failed";
155
- mockPromisesAccess.mockResolvedValue();
156
- mockFetch.mockRejectedValue(new Error(errorMessage));
157
- await expect(() =>
158
- converter.convert({ html: "path/to/index.html" })
159
- ).rejects.toThrow(errorMessage);
160
- });
135
+ describe("when fetch request fails", () => {
136
+ it("should throw an error", async () => {
137
+ const errorMessage =
138
+ "FetchError: request to http://localhost:3000/forms/chromium/convert/html failed";
139
+ mockPromisesAccess.mockResolvedValue();
140
+ mockFetch.mockRejectedValue(new Error(errorMessage));
141
+ await expect(() =>
142
+ converter.convert({html: "path/to/index.html"})
143
+ ).rejects.toThrow(errorMessage);
144
+ });
145
+ });
161
146
  });
162
- });
163
147
  });