chromiumly 2.6.0 → 2.7.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/README.md +55 -35
- package/dist/chromium/converters/converter.d.ts +1 -1
- package/dist/chromium/converters/converter.js +1 -1
- package/dist/chromium/converters/converter.js.map +1 -1
- package/dist/chromium/converters/html.converter.d.ts +9 -4
- package/dist/chromium/converters/html.converter.js +7 -3
- package/dist/chromium/converters/html.converter.js.map +1 -1
- package/dist/chromium/converters/markdown.converter.d.ts +9 -4
- package/dist/chromium/converters/markdown.converter.js +7 -3
- package/dist/chromium/converters/markdown.converter.js.map +1 -1
- package/dist/chromium/converters/url.converter.d.ts +9 -4
- package/dist/chromium/converters/url.converter.js +6 -2
- package/dist/chromium/converters/url.converter.js.map +1 -1
- package/dist/chromium/index.d.ts +3 -3
- package/dist/chromium/index.js.map +1 -1
- package/dist/chromium/interfaces/common.types.d.ts +13 -0
- package/dist/chromium/interfaces/common.types.js +3 -0
- package/dist/chromium/interfaces/common.types.js.map +1 -0
- package/dist/chromium/interfaces/converter.types.d.ts +4 -10
- package/dist/chromium/utils/converter.utils.d.ts +2 -12
- package/dist/chromium/utils/converter.utils.js +36 -50
- package/dist/chromium/utils/converter.utils.js.map +1 -1
- package/dist/common/gotenberg.utils.d.ts +11 -1
- package/dist/common/gotenberg.utils.js +25 -2
- package/dist/common/gotenberg.utils.js.map +1 -1
- package/dist/common/index.d.ts +3 -3
- package/dist/common/index.js.map +1 -1
- package/dist/common/types.d.ts +1 -1
- package/dist/gotenberg.js +4 -3
- package/dist/gotenberg.js.map +1 -1
- package/dist/libre-office/index.d.ts +2 -2
- package/dist/libre-office/index.js.map +1 -1
- package/dist/libre-office/utils/constants.js +80 -76
- package/dist/libre-office/utils/constants.js.map +1 -1
- package/dist/libre-office/utils/libre-office.utils.d.ts +3 -3
- package/dist/libre-office/utils/libre-office.utils.js +5 -5
- package/dist/libre-office/utils/libre-office.utils.js.map +1 -1
- package/dist/main.config.d.ts +1 -1
- package/dist/main.config.js +6 -6
- package/dist/main.config.js.map +1 -1
- package/dist/main.d.ts +3 -3
- package/dist/main.js.map +1 -1
- package/dist/pdf-engines/index.d.ts +1 -1
- package/dist/pdf-engines/index.js.map +1 -1
- package/dist/pdf-engines/pdf.engine.d.ts +3 -3
- package/dist/pdf-engines/pdf.engine.js +5 -5
- package/dist/pdf-engines/pdf.engine.js.map +1 -1
- package/dist/pdf-engines/utils/engine.utils.d.ts +2 -2
- package/dist/pdf-engines/utils/engine.utils.js +3 -3
- package/dist/pdf-engines/utils/engine.utils.js.map +1 -1
- package/package.json +20 -12
- package/src/.prettierrc.yml +4 -0
- package/src/chromium/converters/converter.ts +2 -2
- package/src/chromium/converters/html.converter.ts +37 -27
- package/src/chromium/converters/markdown.converter.ts +32 -26
- package/src/chromium/converters/tests/html.converter.test.ts +97 -73
- package/src/chromium/converters/tests/markdown.converter.test.ts +102 -77
- package/src/chromium/converters/tests/url.converter.test.ts +90 -66
- package/src/chromium/converters/url.converter.ts +31 -25
- package/src/chromium/index.ts +3 -3
- package/src/chromium/interfaces/common.types.ts +15 -0
- package/src/chromium/interfaces/converter.types.ts +4 -12
- package/src/chromium/utils/converter.utils.ts +67 -60
- package/src/chromium/utils/tests/converter.utils.test.ts +237 -167
- package/src/common/constants.ts +3 -3
- package/src/common/gotenberg.utils.ts +39 -8
- package/src/common/index.ts +3 -3
- package/src/common/tests/gotenberg.utils.test.ts +38 -31
- package/src/common/types.ts +2 -2
- package/src/gotenberg.ts +9 -9
- package/src/libre-office/index.ts +2 -2
- package/src/libre-office/utils/constants.ts +80 -76
- package/src/libre-office/utils/libre-office.utils.ts +21 -18
- package/src/libre-office/utils/tests/libre-office.utils.test.ts +58 -49
- package/src/main.config.ts +13 -13
- package/src/main.ts +3 -3
- package/src/pdf-engines/index.ts +1 -1
- package/src/pdf-engines/pdf.engine.ts +23 -19
- package/src/pdf-engines/tests/pdf.engine.test.ts +52 -49
- package/src/pdf-engines/utils/engine.utils.ts +12 -9
- 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
|
|
3
|
-
import FormData from
|
|
4
|
-
import fetch from
|
|
2
|
+
import { createReadStream } from 'fs';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
import fetch from 'node-fetch';
|
|
5
5
|
|
|
6
|
-
import {PdfFormat} from
|
|
7
|
-
import {UrlConverter} from
|
|
6
|
+
import { PdfFormat } from '../../../common';
|
|
7
|
+
import { UrlConverter } from '../url.converter';
|
|
8
8
|
|
|
9
|
-
const {Response} = jest.requireActual(
|
|
10
|
-
jest.mock(
|
|
9
|
+
const { Response } = jest.requireActual('node-fetch');
|
|
10
|
+
jest.mock('node-fetch', () => jest.fn());
|
|
11
11
|
|
|
12
|
-
describe(
|
|
12
|
+
describe('HtmlConverter', () => {
|
|
13
13
|
const converter = new UrlConverter();
|
|
14
14
|
|
|
15
|
-
describe(
|
|
16
|
-
it(
|
|
15
|
+
describe('endpoint', () => {
|
|
16
|
+
it('should route to Chromium HTML route', () => {
|
|
17
17
|
expect(converter.endpoint).toEqual(
|
|
18
|
-
|
|
18
|
+
'http://localhost:3000/forms/chromium/convert/url'
|
|
19
19
|
);
|
|
20
20
|
});
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
describe(
|
|
23
|
+
describe('convert', () => {
|
|
24
24
|
const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
|
|
25
|
-
const mockFormDataAppend = jest.spyOn(FormData.prototype,
|
|
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(
|
|
36
|
-
it(
|
|
37
|
-
mockFetch.mockResolvedValueOnce(new Response(
|
|
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:
|
|
39
|
+
url: 'http://www.example.com/'
|
|
40
40
|
});
|
|
41
|
-
expect(buffer).toEqual(Buffer.from(
|
|
41
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
describe(
|
|
46
|
-
it(
|
|
47
|
-
mockFetch.mockResolvedValueOnce(new Response(
|
|
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:
|
|
50
|
-
header: Buffer.from(
|
|
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(
|
|
53
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
describe(
|
|
58
|
-
it(
|
|
59
|
-
mockFetch.mockResolvedValueOnce(new Response(
|
|
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:
|
|
62
|
-
footer: Buffer.from(
|
|
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(
|
|
65
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
66
66
|
});
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
describe(
|
|
70
|
-
it(
|
|
71
|
-
mockFetch.mockResolvedValueOnce(new Response(
|
|
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:
|
|
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(
|
|
77
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
describe(
|
|
82
|
-
it(
|
|
83
|
-
mockFetch.mockResolvedValueOnce(new Response(
|
|
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:
|
|
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(
|
|
89
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
90
90
|
});
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
describe(
|
|
94
|
-
it(
|
|
95
|
-
mockFetch.mockResolvedValue(new Response(
|
|
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:
|
|
98
|
-
emulatedMediaType:
|
|
97
|
+
url: 'http://www.example.com/',
|
|
98
|
+
emulatedMediaType: 'screen'
|
|
99
99
|
});
|
|
100
100
|
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
101
|
-
expect(buffer).toEqual(Buffer.from(
|
|
101
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
102
102
|
});
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
-
describe(
|
|
106
|
-
it(
|
|
107
|
-
mockFetch.mockResolvedValue(new Response(
|
|
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:
|
|
110
|
-
|
|
111
|
-
|
|
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:
|
|
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(
|
|
141
|
+
expect(buffer).toEqual(Buffer.from('content'));
|
|
118
142
|
});
|
|
119
143
|
});
|
|
120
144
|
|
|
121
|
-
describe(
|
|
122
|
-
it(
|
|
145
|
+
describe('when URL is invalid', () => {
|
|
146
|
+
it('should throw an error', async () => {
|
|
123
147
|
await expect(() =>
|
|
124
|
-
converter.convert({url:
|
|
125
|
-
).rejects.toThrow(
|
|
148
|
+
converter.convert({ url: 'invalid url' })
|
|
149
|
+
).rejects.toThrow('Invalid URL');
|
|
126
150
|
});
|
|
127
151
|
});
|
|
128
152
|
|
|
129
|
-
describe(
|
|
130
|
-
it(
|
|
153
|
+
describe('when fetch request fails', () => {
|
|
154
|
+
it('should throw an error', async () => {
|
|
131
155
|
const errorMessage =
|
|
132
|
-
|
|
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:
|
|
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
|
|
2
|
-
import FormData from
|
|
3
|
-
import {GotenbergUtils, PdfFormat, PathLikeOrReadStream} from
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from
|
|
8
|
-
import {
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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(
|
|
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
|
+
}
|
package/src/chromium/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {HtmlConverter} from
|
|
2
|
-
export {MarkdownConverter} from
|
|
3
|
-
export {UrlConverter} from
|
|
1
|
+
export { HtmlConverter } from './converters/html.converter';
|
|
2
|
+
export { MarkdownConverter } from './converters/markdown.converter';
|
|
3
|
+
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 {
|
|
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
|
|
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
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import FormData from "form-data";
|
|
1
|
+
import FormData from 'form-data';
|
|
3
2
|
|
|
4
3
|
import {
|
|
5
4
|
ConversionOptions,
|
|
6
|
-
PageProperties
|
|
7
|
-
} from
|
|
8
|
-
import {GotenbergUtils
|
|
9
|
-
import {ReadStream} from "fs";
|
|
5
|
+
PageProperties
|
|
6
|
+
} from '../interfaces/converter.types';
|
|
7
|
+
import { GotenbergUtils } from '../../common';
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
* Utility class for handling common tasks related to conversion.
|
|
@@ -22,94 +20,86 @@ export class ConverterUtils {
|
|
|
22
20
|
data: FormData,
|
|
23
21
|
pageProperties: PageProperties
|
|
24
22
|
): void {
|
|
23
|
+
if (pageProperties.singlePage) {
|
|
24
|
+
data.append('singlePage', String(pageProperties.singlePage));
|
|
25
|
+
}
|
|
26
|
+
|
|
25
27
|
if (pageProperties.size) {
|
|
26
28
|
GotenbergUtils.assert(
|
|
27
|
-
pageProperties.size.width >= 1.0 &&
|
|
28
|
-
|
|
29
|
+
pageProperties.size.width >= 1.0 &&
|
|
30
|
+
pageProperties.size.height >= 1.5,
|
|
31
|
+
'size is smaller than the minimum printing requirements (i.e. 1.0 x 1.5 in)'
|
|
29
32
|
);
|
|
30
33
|
|
|
31
|
-
data.append(
|
|
32
|
-
data.append(
|
|
34
|
+
data.append('paperWidth', pageProperties.size.width);
|
|
35
|
+
data.append('paperHeight', pageProperties.size.height);
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
if (pageProperties.margins) {
|
|
36
39
|
GotenbergUtils.assert(
|
|
37
40
|
pageProperties.margins.top >= 0 &&
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
pageProperties.margins.bottom >= 0 &&
|
|
42
|
+
pageProperties.margins.left >= 0 &&
|
|
43
|
+
pageProperties.margins.left >= 0,
|
|
44
|
+
'negative margins are not allowed'
|
|
42
45
|
);
|
|
43
46
|
|
|
44
|
-
data.append(
|
|
45
|
-
data.append(
|
|
46
|
-
data.append(
|
|
47
|
-
data.append(
|
|
47
|
+
data.append('marginTop', pageProperties.margins.top);
|
|
48
|
+
data.append('marginBottom', pageProperties.margins.bottom);
|
|
49
|
+
data.append('marginLeft', pageProperties.margins.left);
|
|
50
|
+
data.append('marginRight', pageProperties.margins.right);
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
if (pageProperties.preferCssPageSize) {
|
|
51
54
|
data.append(
|
|
52
|
-
|
|
55
|
+
'preferCssPageSize',
|
|
53
56
|
String(pageProperties.preferCssPageSize)
|
|
54
57
|
);
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
if (pageProperties.printBackground) {
|
|
58
|
-
data.append(
|
|
61
|
+
data.append(
|
|
62
|
+
'printBackground',
|
|
63
|
+
String(pageProperties.printBackground)
|
|
64
|
+
);
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
if (pageProperties.omitBackground) {
|
|
62
|
-
data.append(
|
|
68
|
+
data.append(
|
|
69
|
+
'omitBackground',
|
|
70
|
+
String(pageProperties.omitBackground)
|
|
71
|
+
);
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
if (pageProperties.landscape) {
|
|
66
|
-
data.append(
|
|
75
|
+
data.append('landscape', String(pageProperties.landscape));
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
if (pageProperties.scale) {
|
|
70
79
|
GotenbergUtils.assert(
|
|
71
80
|
pageProperties.scale >= 0.1 && pageProperties.scale <= 2.0,
|
|
72
|
-
|
|
81
|
+
'scale is outside of [0.1 - 2] range'
|
|
73
82
|
);
|
|
74
83
|
|
|
75
|
-
data.append(
|
|
84
|
+
data.append('scale', pageProperties.scale);
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
if (pageProperties.nativePageRanges) {
|
|
79
88
|
GotenbergUtils.assert(
|
|
80
89
|
pageProperties.nativePageRanges.from > 0 &&
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
pageProperties.nativePageRanges.to > 0 &&
|
|
91
|
+
pageProperties.nativePageRanges.to >=
|
|
92
|
+
pageProperties.nativePageRanges.from,
|
|
93
|
+
'page ranges syntax error'
|
|
85
94
|
);
|
|
86
95
|
|
|
87
96
|
data.append(
|
|
88
|
-
|
|
97
|
+
'nativePageRanges',
|
|
89
98
|
`${pageProperties.nativePageRanges.from}-${pageProperties.nativePageRanges.to}`
|
|
90
99
|
);
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
102
|
|
|
94
|
-
/**
|
|
95
|
-
* Adds a file to the FormData object.
|
|
96
|
-
*
|
|
97
|
-
* @param {FormData} data - The FormData object to which the file will be added.
|
|
98
|
-
* @param {PathLikeOrReadStream} file - The file to be added (either a PathLike or a ReadStream).
|
|
99
|
-
* @param {string} name - The name to be used for the file in the FormData.
|
|
100
|
-
* @returns {Promise<void>} A Promise that resolves once the file has been added.
|
|
101
|
-
*/
|
|
102
|
-
public static async addFile(data: FormData, file: PathLikeOrReadStream, name: string) {
|
|
103
|
-
if (Buffer.isBuffer(file)) {
|
|
104
|
-
data.append("files", file, name);
|
|
105
|
-
} else if (file instanceof ReadStream) {
|
|
106
|
-
data.append("files", file, name);
|
|
107
|
-
} else {
|
|
108
|
-
await promises.access(file, constants.R_OK);
|
|
109
|
-
data.append("files", createReadStream(file), name);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
103
|
/**
|
|
114
104
|
* Customizes the FormData object based on the provided conversion options.
|
|
115
105
|
*
|
|
@@ -122,25 +112,25 @@ export class ConverterUtils {
|
|
|
122
112
|
options: ConversionOptions
|
|
123
113
|
): Promise<void> {
|
|
124
114
|
if (options.pdfFormat) {
|
|
125
|
-
data.append(
|
|
115
|
+
data.append('pdfa', options.pdfFormat);
|
|
126
116
|
}
|
|
127
117
|
|
|
128
118
|
if (options.pdfUA) {
|
|
129
|
-
data.append(
|
|
119
|
+
data.append('pdfua', String(options.pdfUA));
|
|
130
120
|
}
|
|
131
121
|
|
|
132
122
|
if (options.header) {
|
|
133
|
-
const {header} = options;
|
|
134
|
-
await
|
|
123
|
+
const { header } = options;
|
|
124
|
+
await GotenbergUtils.addFile(data, header, 'header.html');
|
|
135
125
|
}
|
|
136
126
|
|
|
137
127
|
if (options.footer) {
|
|
138
|
-
const {footer} = options;
|
|
139
|
-
await
|
|
128
|
+
const { footer } = options;
|
|
129
|
+
await GotenbergUtils.addFile(data, footer, 'footer.html');
|
|
140
130
|
}
|
|
141
131
|
|
|
142
132
|
if (options.emulatedMediaType) {
|
|
143
|
-
data.append(
|
|
133
|
+
data.append('emulatedMediaType', options.emulatedMediaType);
|
|
144
134
|
}
|
|
145
135
|
|
|
146
136
|
if (options.properties) {
|
|
@@ -148,26 +138,43 @@ export class ConverterUtils {
|
|
|
148
138
|
}
|
|
149
139
|
|
|
150
140
|
if (options.waitDelay) {
|
|
151
|
-
data.append(
|
|
141
|
+
data.append('waitDelay', options.waitDelay);
|
|
152
142
|
}
|
|
153
143
|
|
|
154
144
|
if (options.waitForExpression) {
|
|
155
|
-
data.append(
|
|
145
|
+
data.append('waitForExpression', options.waitForExpression);
|
|
156
146
|
}
|
|
157
147
|
|
|
158
148
|
if (options.userAgent) {
|
|
159
|
-
data.append(
|
|
149
|
+
data.append('userAgent', options.userAgent);
|
|
160
150
|
}
|
|
161
151
|
|
|
162
152
|
if (options.extraHttpHeaders) {
|
|
163
|
-
data.append(
|
|
153
|
+
data.append(
|
|
154
|
+
'extraHttpHeaders',
|
|
155
|
+
JSON.stringify(options.extraHttpHeaders)
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (options.failOnHttpStatusCodes) {
|
|
160
|
+
data.append(
|
|
161
|
+
'failOnHttpStatusCodes',
|
|
162
|
+
JSON.stringify(options.failOnHttpStatusCodes)
|
|
163
|
+
);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
if (options.failOnConsoleExceptions) {
|
|
167
167
|
data.append(
|
|
168
|
-
|
|
168
|
+
'failOnConsoleExceptions',
|
|
169
169
|
String(options.failOnConsoleExceptions)
|
|
170
170
|
);
|
|
171
171
|
}
|
|
172
|
+
|
|
173
|
+
if (options.skipNetworkIdleEvent) {
|
|
174
|
+
data.append(
|
|
175
|
+
'skipNetworkIdleEvent',
|
|
176
|
+
String(options.skipNetworkIdleEvent)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
172
179
|
}
|
|
173
180
|
}
|