chromiumly 2.6.0 → 2.8.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.
Files changed (111) hide show
  1. package/README.md +147 -42
  2. package/dist/chromium/converters/converter.d.ts +1 -1
  3. package/dist/chromium/converters/converter.js +1 -1
  4. package/dist/chromium/converters/converter.js.map +1 -1
  5. package/dist/chromium/converters/html.converter.d.ts +9 -4
  6. package/dist/chromium/converters/html.converter.js +7 -3
  7. package/dist/chromium/converters/html.converter.js.map +1 -1
  8. package/dist/chromium/converters/markdown.converter.d.ts +9 -4
  9. package/dist/chromium/converters/markdown.converter.js +7 -3
  10. package/dist/chromium/converters/markdown.converter.js.map +1 -1
  11. package/dist/chromium/converters/url.converter.d.ts +9 -4
  12. package/dist/chromium/converters/url.converter.js +6 -2
  13. package/dist/chromium/converters/url.converter.js.map +1 -1
  14. package/dist/chromium/index.d.ts +6 -3
  15. package/dist/chromium/index.js +7 -1
  16. package/dist/chromium/index.js.map +1 -1
  17. package/dist/chromium/interfaces/common.types.d.ts +13 -0
  18. package/dist/chromium/interfaces/common.types.js +3 -0
  19. package/dist/chromium/interfaces/common.types.js.map +1 -0
  20. package/dist/chromium/interfaces/converter.types.d.ts +4 -10
  21. package/dist/chromium/interfaces/screenshot.types.d.ts +10 -0
  22. package/dist/chromium/interfaces/screenshot.types.js +3 -0
  23. package/dist/chromium/interfaces/screenshot.types.js.map +1 -0
  24. package/dist/chromium/screenshots/html.screenshot.d.ts +54 -0
  25. package/dist/chromium/screenshots/html.screenshot.js +67 -0
  26. package/dist/chromium/screenshots/html.screenshot.js.map +1 -0
  27. package/dist/chromium/screenshots/markdown.screenshot.d.ts +52 -0
  28. package/dist/chromium/screenshots/markdown.screenshot.js +66 -0
  29. package/dist/chromium/screenshots/markdown.screenshot.js.map +1 -0
  30. package/dist/chromium/screenshots/screenshot.d.ts +18 -0
  31. package/dist/chromium/screenshots/screenshot.js +21 -0
  32. package/dist/chromium/screenshots/screenshot.js.map +1 -0
  33. package/dist/chromium/screenshots/url.screenshot.d.ts +50 -0
  34. package/dist/chromium/screenshots/url.screenshot.js +66 -0
  35. package/dist/chromium/screenshots/url.screenshot.js.map +1 -0
  36. package/dist/chromium/utils/converter.utils.d.ts +2 -12
  37. package/dist/chromium/utils/converter.utils.js +36 -50
  38. package/dist/chromium/utils/converter.utils.js.map +1 -1
  39. package/dist/chromium/utils/screenshot.utils.d.ts +22 -0
  40. package/dist/chromium/utils/screenshot.utils.js +75 -0
  41. package/dist/chromium/utils/screenshot.utils.js.map +1 -0
  42. package/dist/common/gotenberg.utils.d.ts +11 -1
  43. package/dist/common/gotenberg.utils.js +25 -2
  44. package/dist/common/gotenberg.utils.js.map +1 -1
  45. package/dist/common/index.d.ts +3 -3
  46. package/dist/common/index.js.map +1 -1
  47. package/dist/common/types.d.ts +1 -1
  48. package/dist/gotenberg.js +4 -3
  49. package/dist/gotenberg.js.map +1 -1
  50. package/dist/libre-office/index.d.ts +2 -2
  51. package/dist/libre-office/index.js.map +1 -1
  52. package/dist/libre-office/utils/constants.js +80 -76
  53. package/dist/libre-office/utils/constants.js.map +1 -1
  54. package/dist/libre-office/utils/libre-office.utils.d.ts +3 -3
  55. package/dist/libre-office/utils/libre-office.utils.js +5 -5
  56. package/dist/libre-office/utils/libre-office.utils.js.map +1 -1
  57. package/dist/main.config.d.ts +6 -1
  58. package/dist/main.config.js +11 -6
  59. package/dist/main.config.js.map +1 -1
  60. package/dist/main.d.ts +3 -3
  61. package/dist/main.js +4 -1
  62. package/dist/main.js.map +1 -1
  63. package/dist/pdf-engines/index.d.ts +1 -1
  64. package/dist/pdf-engines/index.js.map +1 -1
  65. package/dist/pdf-engines/pdf.engine.d.ts +3 -3
  66. package/dist/pdf-engines/pdf.engine.js +5 -5
  67. package/dist/pdf-engines/pdf.engine.js.map +1 -1
  68. package/dist/pdf-engines/utils/engine.utils.d.ts +2 -2
  69. package/dist/pdf-engines/utils/engine.utils.js +3 -3
  70. package/dist/pdf-engines/utils/engine.utils.js.map +1 -1
  71. package/package.json +20 -12
  72. package/src/.prettierrc.yml +4 -0
  73. package/src/chromium/converters/converter.ts +2 -2
  74. package/src/chromium/converters/html.converter.ts +37 -27
  75. package/src/chromium/converters/markdown.converter.ts +32 -26
  76. package/src/chromium/converters/tests/html.converter.test.ts +97 -73
  77. package/src/chromium/converters/tests/markdown.converter.test.ts +102 -77
  78. package/src/chromium/converters/tests/url.converter.test.ts +90 -66
  79. package/src/chromium/converters/url.converter.ts +31 -25
  80. package/src/chromium/index.ts +6 -3
  81. package/src/chromium/interfaces/common.types.ts +15 -0
  82. package/src/chromium/interfaces/converter.types.ts +4 -12
  83. package/src/chromium/interfaces/screenshot.types.ts +12 -0
  84. package/src/chromium/screenshots/html.screenshot.ts +100 -0
  85. package/src/chromium/screenshots/markdown.screenshot.ts +95 -0
  86. package/src/chromium/screenshots/screenshot.ts +22 -0
  87. package/src/chromium/screenshots/tests/html.screenshot.test.ts +192 -0
  88. package/src/chromium/screenshots/tests/markdown.screenshot.test.ts +176 -0
  89. package/src/chromium/screenshots/tests/url.screenshot.test.ts +166 -0
  90. package/src/chromium/screenshots/url.screenshot.ts +91 -0
  91. package/src/chromium/utils/converter.utils.ts +67 -60
  92. package/src/chromium/utils/screenshot.utils.ts +115 -0
  93. package/src/chromium/utils/tests/converter.utils.test.ts +250 -168
  94. package/src/chromium/utils/tests/screenshot.utils.test.ts +284 -0
  95. package/src/common/constants.ts +3 -3
  96. package/src/common/gotenberg.utils.ts +39 -8
  97. package/src/common/index.ts +3 -3
  98. package/src/common/tests/gotenberg.utils.test.ts +84 -31
  99. package/src/common/types.ts +2 -2
  100. package/src/gotenberg.ts +9 -9
  101. package/src/libre-office/index.ts +2 -2
  102. package/src/libre-office/utils/constants.ts +80 -76
  103. package/src/libre-office/utils/libre-office.utils.ts +21 -18
  104. package/src/libre-office/utils/tests/libre-office.utils.test.ts +58 -49
  105. package/src/main.config.ts +19 -13
  106. package/src/main.ts +10 -3
  107. package/src/pdf-engines/index.ts +1 -1
  108. package/src/pdf-engines/pdf.engine.ts +23 -19
  109. package/src/pdf-engines/tests/pdf.engine.test.ts +52 -49
  110. package/src/pdf-engines/utils/engine.utils.ts +12 -9
  111. package/src/pdf-engines/utils/tests/engine.utils.test.ts +23 -23
@@ -1,138 +1,162 @@
1
1
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
- import {createReadStream} from "fs";
3
- import FormData from "form-data";
4
- import fetch from "node-fetch";
2
+ import { createReadStream } from 'fs';
3
+ import FormData from 'form-data';
4
+ import fetch from 'node-fetch';
5
5
 
6
- import {PdfFormat} from "../../../common";
7
- import {UrlConverter} from "../url.converter";
6
+ import { PdfFormat } from '../../../common';
7
+ import { UrlConverter } from '../url.converter';
8
8
 
9
- const {Response} = jest.requireActual("node-fetch");
10
- jest.mock("node-fetch", () => jest.fn());
9
+ const { Response } = jest.requireActual('node-fetch');
10
+ jest.mock('node-fetch', () => jest.fn());
11
11
 
12
- describe("HtmlConverter", () => {
12
+ describe('HtmlConverter', () => {
13
13
  const converter = new UrlConverter();
14
14
 
15
- describe("endpoint", () => {
16
- it("should route to Chromium HTML route", () => {
15
+ describe('endpoint', () => {
16
+ it('should route to Chromium HTML route', () => {
17
17
  expect(converter.endpoint).toEqual(
18
- "http://localhost:3000/forms/chromium/convert/url"
18
+ 'http://localhost:3000/forms/chromium/convert/url'
19
19
  );
20
20
  });
21
21
  });
22
22
 
23
- describe("convert", () => {
23
+ describe('convert', () => {
24
24
  const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
25
- const mockFormDataAppend = jest.spyOn(FormData.prototype, "append");
25
+ const mockFormDataAppend = jest.spyOn(FormData.prototype, 'append');
26
26
 
27
27
  beforeEach(() => {
28
- (createReadStream as jest.Mock) = jest.fn()
28
+ (createReadStream as jest.Mock) = jest.fn();
29
29
  });
30
30
 
31
31
  afterEach(() => {
32
32
  jest.resetAllMocks();
33
33
  });
34
34
 
35
- describe("when URL is valid", () => {
36
- it("should return a buffer", async () => {
37
- mockFetch.mockResolvedValueOnce(new Response("content"));
35
+ describe('when URL is valid', () => {
36
+ it('should return a buffer', async () => {
37
+ mockFetch.mockResolvedValueOnce(new Response('content'));
38
38
  const buffer = await converter.convert({
39
- url: "http://www.example.com/",
39
+ url: 'http://www.example.com/'
40
40
  });
41
- expect(buffer).toEqual(Buffer.from("content"));
41
+ expect(buffer).toEqual(Buffer.from('content'));
42
42
  });
43
43
  });
44
44
 
45
- describe("when header parameter is passed", () => {
46
- it("should return a buffer", async () => {
47
- mockFetch.mockResolvedValueOnce(new Response("content"));
45
+ describe('when header parameter is passed', () => {
46
+ it('should return a buffer', async () => {
47
+ mockFetch.mockResolvedValueOnce(new Response('content'));
48
48
  const buffer = await converter.convert({
49
- url: "http://www.example.com/",
50
- header: Buffer.from("header"),
49
+ url: 'http://www.example.com/',
50
+ header: Buffer.from('header')
51
51
  });
52
52
  expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
53
- expect(buffer).toEqual(Buffer.from("content"));
53
+ expect(buffer).toEqual(Buffer.from('content'));
54
54
  });
55
55
  });
56
56
 
57
- describe("when footer parameter is passed", () => {
58
- it("should return a buffer", async () => {
59
- mockFetch.mockResolvedValueOnce(new Response("content"));
57
+ describe('when footer parameter is passed', () => {
58
+ it('should return a buffer', async () => {
59
+ mockFetch.mockResolvedValueOnce(new Response('content'));
60
60
  const buffer = await converter.convert({
61
- url: "http://www.example.com/",
62
- footer: Buffer.from("footer"),
61
+ url: 'http://www.example.com/',
62
+ footer: Buffer.from('footer')
63
63
  });
64
64
  expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
65
- expect(buffer).toEqual(Buffer.from("content"));
65
+ expect(buffer).toEqual(Buffer.from('content'));
66
66
  });
67
67
  });
68
68
 
69
- describe("when pdf format parameter is passed", () => {
70
- it("should return a buffer", async () => {
71
- mockFetch.mockResolvedValueOnce(new Response("content"));
69
+ describe('when pdf format parameter is passed', () => {
70
+ it('should return a buffer', async () => {
71
+ mockFetch.mockResolvedValueOnce(new Response('content'));
72
72
  const buffer = await converter.convert({
73
- url: "http://www.example.com/",
74
- pdfFormat: PdfFormat.A_3b,
73
+ url: 'http://www.example.com/',
74
+ pdfFormat: PdfFormat.A_3b
75
75
  });
76
76
  expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
77
- expect(buffer).toEqual(Buffer.from("content"));
77
+ expect(buffer).toEqual(Buffer.from('content'));
78
78
  });
79
79
  });
80
80
 
81
- describe("when page properties parameter is passed", () => {
82
- it("should return a buffer", async () => {
83
- mockFetch.mockResolvedValueOnce(new Response("content"));
81
+ describe('when page properties parameter is passed', () => {
82
+ it('should return a buffer', async () => {
83
+ mockFetch.mockResolvedValueOnce(new Response('content'));
84
84
  const buffer = await converter.convert({
85
- url: "http://www.example.com/",
86
- properties: {size: {width: 8.3, height: 11.7}},
85
+ url: 'http://www.example.com/',
86
+ properties: { size: { width: 8.3, height: 11.7 } }
87
87
  });
88
88
  expect(mockFormDataAppend).toHaveBeenCalledTimes(3);
89
- expect(buffer).toEqual(Buffer.from("content"));
89
+ expect(buffer).toEqual(Buffer.from('content'));
90
90
  });
91
91
  });
92
92
 
93
- describe("when emulatedMediaType parameter is passed", () => {
94
- it("should return a buffer", async () => {
95
- mockFetch.mockResolvedValue(new Response("content"));
93
+ describe('when emulatedMediaType parameter is passed', () => {
94
+ it('should return a buffer', async () => {
95
+ mockFetch.mockResolvedValue(new Response('content'));
96
96
  const buffer = await converter.convert({
97
- url: "http://www.example.com/",
98
- emulatedMediaType: "screen",
97
+ url: 'http://www.example.com/',
98
+ emulatedMediaType: 'screen'
99
99
  });
100
100
  expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
101
- expect(buffer).toEqual(Buffer.from("content"));
101
+ expect(buffer).toEqual(Buffer.from('content'));
102
102
  });
103
103
  });
104
104
 
105
- describe("when all parameters are passed", () => {
106
- it("should return a buffer", async () => {
107
- mockFetch.mockResolvedValue(new Response("content"));
105
+ describe('when failOnHttpStatusCodes parameter is passed', () => {
106
+ it('should return a buffer', async () => {
107
+ mockFetch.mockResolvedValue(new Response('content'));
108
108
  const buffer = await converter.convert({
109
- url: "http://www.example.com/",
110
- header: Buffer.from("header"),
111
- footer: Buffer.from("footer"),
109
+ url: 'http://www.example.com/',
110
+ failOnHttpStatusCodes: [499, 599]
111
+ });
112
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
113
+ expect(buffer).toEqual(Buffer.from('content'));
114
+ });
115
+ });
116
+
117
+ describe('when skipNetworkIdleEvent parameter is passed', () => {
118
+ it('should return a buffer', async () => {
119
+ mockFetch.mockResolvedValue(new Response('content'));
120
+ const buffer = await converter.convert({
121
+ url: 'http://www.example.com/',
122
+ skipNetworkIdleEvent: true
123
+ });
124
+ expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
125
+ expect(buffer).toEqual(Buffer.from('content'));
126
+ });
127
+ });
128
+
129
+ describe('when all parameters are passed', () => {
130
+ it('should return a buffer', async () => {
131
+ mockFetch.mockResolvedValue(new Response('content'));
132
+ const buffer = await converter.convert({
133
+ url: 'http://www.example.com/',
134
+ header: Buffer.from('header'),
135
+ footer: Buffer.from('footer'),
112
136
  pdfFormat: PdfFormat.A_1a,
113
- emulatedMediaType: "screen",
114
- properties: {size: {width: 8.3, height: 11.7}},
137
+ emulatedMediaType: 'screen',
138
+ properties: { size: { width: 8.3, height: 11.7 } }
115
139
  });
116
140
  expect(mockFormDataAppend).toHaveBeenCalledTimes(7);
117
- expect(buffer).toEqual(Buffer.from("content"));
141
+ expect(buffer).toEqual(Buffer.from('content'));
118
142
  });
119
143
  });
120
144
 
121
- describe("when URL is invalid", () => {
122
- it("should throw an error", async () => {
145
+ describe('when URL is invalid', () => {
146
+ it('should throw an error', async () => {
123
147
  await expect(() =>
124
- converter.convert({url: "invalid url"})
125
- ).rejects.toThrow("Invalid URL");
148
+ converter.convert({ url: 'invalid url' })
149
+ ).rejects.toThrow('Invalid URL');
126
150
  });
127
151
  });
128
152
 
129
- describe("when fetch request fails", () => {
130
- it("should throw an error", async () => {
153
+ describe('when fetch request fails', () => {
154
+ it('should throw an error', async () => {
131
155
  const errorMessage =
132
- "FetchError: request to http://localhost:3000/forms/chromium/convert/html failed";
156
+ 'FetchError: request to http://localhost:3000/forms/chromium/convert/html failed';
133
157
  mockFetch.mockRejectedValueOnce(new Error(errorMessage));
134
158
  await expect(() =>
135
- converter.convert({url: "http://www.example.com/"})
159
+ converter.convert({ url: 'http://www.example.com/' })
136
160
  ).rejects.toThrow(errorMessage);
137
161
  });
138
162
  });
@@ -1,13 +1,11 @@
1
- import {URL} from "url";
2
- import FormData from "form-data";
3
- import {GotenbergUtils, PdfFormat, PathLikeOrReadStream} from "../../common";
4
- import {
5
- EmulatedMediaType,
6
- PageProperties,
7
- } from "../interfaces/converter.types";
8
- import {ConverterUtils} from "../utils/converter.utils";
9
- import {Converter} from "./converter";
10
- import {ChromiumRoute} from "../../main.config";
1
+ import { URL } from 'url';
2
+ import FormData from 'form-data';
3
+ import { GotenbergUtils, PdfFormat, PathLikeOrReadStream } from '../../common';
4
+ import { PageProperties } from '../interfaces/converter.types';
5
+ import { ConverterUtils } from '../utils/converter.utils';
6
+ import { Converter } from './converter';
7
+ import { ChromiumRoute } from '../../main.config';
8
+ import { EmulatedMediaType } from '../interfaces/common.types';
11
9
 
12
10
  /**
13
11
  * Class representing a URL converter that extends the base Converter class.
@@ -39,23 +37,27 @@ export class UrlConverter extends Converter {
39
37
  * @param {string} [options.waitForExpression] - JavaScript expression to wait for before completing the conversion.
40
38
  * @param {string} [options.userAgent] - User agent string to use during the conversion.
41
39
  * @param {Record<string, string>} [options.extraHttpHeaders] - Additional HTTP headers for the conversion.
40
+ * @param {number[]} [options.failOnHttpStatusCodes] - Whether to fail on HTTP status code.
42
41
  * @param {boolean} [options.failOnConsoleExceptions] - Whether to fail on console exceptions during conversion.
42
+ * @param {boolean} [options.skipNetworkIdleEvent] - Whether to skip network idle event.
43
43
  * @returns {Promise<Buffer>} A Promise resolving to the converted PDF content as a Buffer.
44
44
  */
45
45
  async convert({
46
- url,
47
- header,
48
- footer,
49
- properties,
50
- pdfFormat,
51
- pdfUA,
52
- emulatedMediaType,
53
- waitDelay,
54
- waitForExpression,
55
- userAgent,
56
- extraHttpHeaders,
57
- failOnConsoleExceptions,
58
- }: {
46
+ url,
47
+ header,
48
+ footer,
49
+ properties,
50
+ pdfFormat,
51
+ pdfUA,
52
+ emulatedMediaType,
53
+ waitDelay,
54
+ waitForExpression,
55
+ userAgent,
56
+ extraHttpHeaders,
57
+ failOnHttpStatusCodes,
58
+ failOnConsoleExceptions,
59
+ skipNetworkIdleEvent
60
+ }: {
59
61
  url: string;
60
62
  header?: PathLikeOrReadStream;
61
63
  footer?: PathLikeOrReadStream;
@@ -67,12 +69,14 @@ export class UrlConverter extends Converter {
67
69
  waitForExpression?: string;
68
70
  userAgent?: string;
69
71
  extraHttpHeaders?: Record<string, string>;
72
+ failOnHttpStatusCodes?: number[];
70
73
  failOnConsoleExceptions?: boolean;
74
+ skipNetworkIdleEvent?: boolean;
71
75
  }): Promise<Buffer> {
72
76
  const _url = new URL(url);
73
77
  const data = new FormData();
74
78
 
75
- data.append("url", _url.href);
79
+ data.append('url', _url.href);
76
80
 
77
81
  await ConverterUtils.customize(data, {
78
82
  header,
@@ -85,9 +89,11 @@ export class UrlConverter extends Converter {
85
89
  waitForExpression,
86
90
  userAgent,
87
91
  extraHttpHeaders,
92
+ failOnHttpStatusCodes,
88
93
  failOnConsoleExceptions,
94
+ skipNetworkIdleEvent
89
95
  });
90
96
 
91
97
  return GotenbergUtils.fetch(this.endpoint, data);
92
98
  }
93
- }
99
+ }
@@ -1,3 +1,6 @@
1
- export {HtmlConverter} from "./converters/html.converter";
2
- export {MarkdownConverter} from "./converters/markdown.converter";
3
- export {UrlConverter} from "./converters/url.converter";
1
+ export { UrlScreenshot } from './screenshots/url.screenshot';
2
+ export { MarkdownScreenshot } from './screenshots/markdown.screenshot';
3
+ export { HtmlScreenshot } from './screenshots/html.screenshot';
4
+ export { HtmlConverter } from './converters/html.converter';
5
+ export { MarkdownConverter } from './converters/markdown.converter';
6
+ export { UrlConverter } from './converters/url.converter';
@@ -0,0 +1,15 @@
1
+ import { PathLikeOrReadStream } from '../../common';
2
+
3
+ export type EmulatedMediaType = 'screen' | 'print';
4
+
5
+ export type ChromiumOptions = {
6
+ header?: PathLikeOrReadStream;
7
+ footer?: PathLikeOrReadStream;
8
+ emulatedMediaType?: EmulatedMediaType;
9
+ waitDelay?: string; // Duration (e.g, '5s') to wait when loading an HTML document before convertion.
10
+ waitForExpression?: string; // JavaScript's expression to wait before converting an HTML document into PDF until it returns true.
11
+ extraHttpHeaders?: Record<string, string>;
12
+ failOnHttpStatusCodes?: number[]; // Return a 409 Conflict response if the HTTP status code is in the list (default [499,599])
13
+ failOnConsoleExceptions?: boolean; // Return a 409 Conflict response if there are exceptions in the Chromium console (default false)
14
+ skipNetworkIdleEvent?: boolean; // Do not wait for Chromium network to be idle (default false)
15
+ };
@@ -1,4 +1,5 @@
1
- import {PathLikeOrReadStream, PdfFormat} from "../../common";
1
+ import { PdfFormat } from '../../common';
2
+ import { ChromiumOptions } from './common.types';
2
3
 
3
4
  type PageSize = {
4
5
  width: number; // Paper width, in inches (default 8.5)
@@ -13,6 +14,7 @@ type PageMargins = {
13
14
  };
14
15
 
15
16
  export type PageProperties = {
17
+ singlePage?: boolean; // Print the entire content in one single page (default false)
16
18
  size?: PageSize;
17
19
  margins?: PageMargins;
18
20
  preferCssPageSize?: boolean; // Define whether to prefer page size as defined by CSS (default false)
@@ -23,19 +25,9 @@ export type PageProperties = {
23
25
  nativePageRanges?: { from: number; to: number }; // Page ranges to print
24
26
  };
25
27
 
26
- export type EmulatedMediaType = "screen" | "print";
27
-
28
-
29
- export type ConversionOptions = {
30
- header?: PathLikeOrReadStream;
31
- footer?: PathLikeOrReadStream;
28
+ export type ConversionOptions = ChromiumOptions & {
32
29
  properties?: PageProperties;
33
30
  pdfFormat?: PdfFormat;
34
31
  pdfUA?: boolean; // Enable PDF for Universal Access for optimal accessibility (default false)
35
- emulatedMediaType?: EmulatedMediaType;
36
- waitDelay?: string; // Duration (e.g, '5s') to wait when loading an HTML document before converting it into PDF
37
- waitForExpression?: string; // JavaScript's expression to wait before converting an HTML document into PDF until it returns true.
38
32
  userAgent?: string;
39
- extraHttpHeaders?: Record<string, string>;
40
- failOnConsoleExceptions?: boolean; // Return a 409 Conflict response if there are exceptions in the Chromium console (default false)
41
33
  };
@@ -0,0 +1,12 @@
1
+ import { ChromiumOptions } from './common.types';
2
+
3
+ export type ImageProperties = {
4
+ format: 'png' | 'jpeg' | 'webp'; //The image compression format, either "png", "jpeg" or "webp".
5
+ quality?: number; // The compression quality from range 0 to 100 (jpeg only).
6
+ omitBackground?: boolean; // Hide the default white background and allow generating screenshots with transparency.
7
+ };
8
+
9
+ export type ScreenshotOptions = ChromiumOptions & {
10
+ properties?: ImageProperties;
11
+ optimizeForSpeed?: boolean; // Define whether to optimize image encoding for speed, not for resulting size.
12
+ };
@@ -0,0 +1,100 @@
1
+ import FormData from 'form-data';
2
+
3
+ import { GotenbergUtils, PathLikeOrReadStream } from '../../common';
4
+ import { ChromiumRoute } from '../../main.config';
5
+ import { EmulatedMediaType } from '../interfaces/common.types';
6
+ import { ScreenshotUtils } from '../utils/screenshot.utils';
7
+ import { Screenshot } from './screenshot';
8
+ import { ImageProperties } from '../interfaces/screenshot.types';
9
+
10
+ /**
11
+ * Class representing an HTML Screenshot that extends the base Screenshot class.
12
+ * This class is used to screenshot HTML content using Gotenberg service.
13
+ *
14
+ * @extends Screenshot
15
+ */
16
+ export class HtmlScreenshot extends Screenshot {
17
+ /**
18
+ * Creates an instance of HtmlScreenshot.
19
+ * Initializes the Screenshot with the HTML screenshot route.
20
+ */
21
+ constructor() {
22
+ super(ChromiumRoute.HTML);
23
+ }
24
+
25
+ /**
26
+ * Screenshots HTML content.
27
+ *
28
+ * @param {Object} options - Screenshot options.
29
+ * @param {PathLikeOrReadStream} options.html - PathLike or ReadStream of the HTML content to be screenshoted.
30
+ * @param {PathLikeOrReadStream} [options.header] - PathLike or ReadStream of the header HTML content.
31
+ * @param {PathLikeOrReadStream} [options.footer] - PathLike or ReadStream of the footer HTML content.
32
+ * @param {ImageProperties} [options.properties] - Image properties for the screenshot.
33
+ * @param {EmulatedMediaType} [options.emulatedMediaType] - Emulated media type for the screenshot.
34
+ * @param {string} [options.waitDelay] - Delay before the screenshot process starts.
35
+ * @param {string} [options.waitForExpression] - JavaScript expression to wait for before completing the screenshot.
36
+ * @param {Record<string, string>} [options.extraHttpHeaders] - Additional HTTP headers for the screenshot.
37
+ * @param {number []} [options.failOnHttpStatusCodes] - Whether to fail on HTTP status code.
38
+ * @param {boolean} [options.failOnConsoleExceptions] - Whether to fail on console exceptions during screenshot.
39
+ * @param {boolean} [options.skipNetworkIdleEvent] - Whether to skip network idle event.
40
+ * @param {boolean} [options.optimizeForSpeed] - Whether to optimize for speed.
41
+ * @returns {Promise<Buffer>} A Promise resolving to the image buffer.
42
+ */
43
+ async capture({
44
+ html,
45
+ assets,
46
+ header,
47
+ footer,
48
+ properties,
49
+ emulatedMediaType,
50
+ waitDelay,
51
+ waitForExpression,
52
+ extraHttpHeaders,
53
+ failOnConsoleExceptions,
54
+ failOnHttpStatusCodes,
55
+ skipNetworkIdleEvent,
56
+ optimizeForSpeed
57
+ }: {
58
+ html: PathLikeOrReadStream;
59
+ assets?: { file: PathLikeOrReadStream; name: string }[];
60
+ header?: PathLikeOrReadStream;
61
+ footer?: PathLikeOrReadStream;
62
+ properties?: ImageProperties;
63
+ emulatedMediaType?: EmulatedMediaType;
64
+ waitDelay?: string;
65
+ waitForExpression?: string;
66
+ extraHttpHeaders?: Record<string, string>;
67
+ failOnConsoleExceptions?: boolean;
68
+ failOnHttpStatusCodes?: number[];
69
+ skipNetworkIdleEvent?: boolean;
70
+ optimizeForSpeed?: boolean;
71
+ }): Promise<Buffer> {
72
+ const data = new FormData();
73
+
74
+ await GotenbergUtils.addFile(data, html, 'index.html');
75
+
76
+ if (assets?.length) {
77
+ await Promise.all(
78
+ assets.map(({ file, name }) =>
79
+ GotenbergUtils.addFile(data, file, name)
80
+ )
81
+ );
82
+ }
83
+
84
+ await ScreenshotUtils.customize(data, {
85
+ header,
86
+ footer,
87
+ properties,
88
+ emulatedMediaType,
89
+ waitDelay,
90
+ waitForExpression,
91
+ extraHttpHeaders,
92
+ failOnHttpStatusCodes,
93
+ failOnConsoleExceptions,
94
+ skipNetworkIdleEvent,
95
+ optimizeForSpeed
96
+ });
97
+
98
+ return GotenbergUtils.fetch(this.endpoint, data);
99
+ }
100
+ }
@@ -0,0 +1,95 @@
1
+ import FormData from 'form-data';
2
+
3
+ import { GotenbergUtils, PathLikeOrReadStream } from '../../common';
4
+ import { ImageProperties } from '../interfaces/screenshot.types';
5
+ import { ScreenshotUtils } from '../utils/screenshot.utils';
6
+ import { Screenshot } from './screenshot';
7
+ import { ChromiumRoute } from '../../main.config';
8
+ import { EmulatedMediaType } from '../interfaces/common.types';
9
+
10
+ /**
11
+ * Class representing a Markdown screenshot that extends the base Screenshot class.
12
+ * This class is used to screenshots HTML with markdown content using Gotenberg service.
13
+ *
14
+ * @extends Screenshot
15
+ */
16
+ export class MarkdownScreenshot extends Screenshot {
17
+ /**
18
+ * Creates an instance of MarkdownScreenshot.
19
+ * Initializes the Screenshot with the Markdown screenshot route.
20
+ */
21
+ constructor() {
22
+ super(ChromiumRoute.MARKDOWN);
23
+ }
24
+
25
+ /**
26
+ * Screenshots HTML with markdown.
27
+ *
28
+ * @param {Object} options - Screenshot options.
29
+ * @param {PathLikeOrReadStream} options.html - PathLike or ReadStream of the HTML content to be screenshoted.
30
+ * @param {PathLikeOrReadStream} options.markdown - PathLike or ReadStream of the Markdown content to be screenshoted.
31
+ * @param {PathLikeOrReadStream} [options.header] - PathLike or ReadStream of the header HTML content.
32
+ * @param {PathLikeOrReadStream} [options.footer] - PathLike or ReadStream of the footer HTML content.
33
+ * @param {ImageProperties} [options.properties] - Image properties for the screenshot.
34
+ * @param {EmulatedMediaType} [options.emulatedMediaType] - Emulated media type for the screenshot.
35
+ * @param {string} [options.waitDelay] - Delay before the screenshot process starts.
36
+ * @param {string} [options.waitForExpression] - JavaScript expression to wait for before completing the screenshot.
37
+ * @param {Record<string, string>} [options.extraHttpHeaders] - Additional HTTP headers for the screenshot.
38
+ * @param {number []} [options.failOnHttpStatusCodes] - Whether to fail on HTTP status code.
39
+ * @param {boolean} [options.failOnConsoleExceptions] - Whether to fail on console exceptions during screenshot.
40
+ * @param {boolean} [options.skipNetworkIdleEvent] - Whether to skip network idle event.
41
+ * @param {boolean} [options.optimizeForSpeed] - Whether to optimize for speed.
42
+ * @returns {Promise<Buffer>} A Promise resolving to the image buffer.
43
+ */
44
+ async capture({
45
+ html,
46
+ markdown,
47
+ header,
48
+ footer,
49
+ properties,
50
+ emulatedMediaType,
51
+ waitDelay,
52
+ waitForExpression,
53
+ extraHttpHeaders,
54
+ failOnHttpStatusCodes,
55
+ failOnConsoleExceptions,
56
+ skipNetworkIdleEvent,
57
+ optimizeForSpeed
58
+ }: {
59
+ html: PathLikeOrReadStream;
60
+ markdown: PathLikeOrReadStream;
61
+ header?: PathLikeOrReadStream;
62
+ footer?: PathLikeOrReadStream;
63
+ properties?: ImageProperties;
64
+ emulatedMediaType?: EmulatedMediaType;
65
+ waitDelay?: string;
66
+ waitForExpression?: string;
67
+ extraHttpHeaders?: Record<string, string>;
68
+ failOnHttpStatusCodes?: number[];
69
+ failOnConsoleExceptions?: boolean;
70
+ skipNetworkIdleEvent?: boolean;
71
+ optimizeForSpeed?: boolean;
72
+ }): Promise<Buffer> {
73
+ const data = new FormData();
74
+
75
+ await GotenbergUtils.addFile(data, html, 'index.html');
76
+
77
+ await GotenbergUtils.addFile(data, markdown, 'file.md');
78
+
79
+ await ScreenshotUtils.customize(data, {
80
+ header,
81
+ footer,
82
+ properties,
83
+ emulatedMediaType,
84
+ waitDelay,
85
+ waitForExpression,
86
+ extraHttpHeaders,
87
+ failOnHttpStatusCodes,
88
+ failOnConsoleExceptions,
89
+ skipNetworkIdleEvent,
90
+ optimizeForSpeed
91
+ });
92
+
93
+ return GotenbergUtils.fetch(this.endpoint, data);
94
+ }
95
+ }
@@ -0,0 +1,22 @@
1
+ import { Chromiumly, ChromiumRoute } from '../../main.config';
2
+
3
+ /**
4
+ * Abstract class representing a generic screenshot.
5
+ * Concrete screenshot classes should extend this class and implement specific screenshot logic.
6
+ */
7
+ export abstract class Screenshot {
8
+ /**
9
+ * The endpoint URL for the screenshot.
10
+ */
11
+ readonly endpoint: string;
12
+
13
+ /**
14
+ * Creates an instance of the screenshot class.
15
+ * Initializes the endpoint URL based on the provided ChromiumRoute.
16
+ *
17
+ * @param {ChromiumRoute} route - The ChromiumRoute enum value representing the screenshot route.
18
+ */
19
+ constructor(route: ChromiumRoute) {
20
+ this.endpoint = `${Chromiumly.GOTENBERG_ENDPOINT}/${Chromiumly.CHROMIUM_SCREENSHOT_PATH}/${Chromiumly.CHROMIUM_ROUTES[route]}`;
21
+ }
22
+ }