chromiumly 3.3.0 → 3.3.2
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 +1 -0
- package/dist/chromium/converters/html.converter.js +1 -1
- package/dist/pdf-engines/utils/pdf-engines.utils.js +5 -5
- package/dist/pdf-engines/utils/pdf-engines.utils.js.map +1 -1
- package/package.json +13 -10
- package/src/.prettierrc.yml +0 -4
- package/src/chromium/converters/converter.ts +0 -22
- package/src/chromium/converters/html.converter.ts +0 -134
- package/src/chromium/converters/markdown.converter.ts +0 -129
- package/src/chromium/converters/tests/html.converter.test.ts +0 -190
- package/src/chromium/converters/tests/markdown.converter.test.ts +0 -187
- package/src/chromium/converters/tests/url.converter.test.ts +0 -164
- package/src/chromium/converters/url.converter.ts +0 -125
- package/src/chromium/index.ts +0 -6
- package/src/chromium/interfaces/common.types.ts +0 -15
- package/src/chromium/interfaces/converter.types.ts +0 -45
- package/src/chromium/interfaces/screenshot.types.ts +0 -15
- package/src/chromium/screenshots/html.screenshot.ts +0 -105
- package/src/chromium/screenshots/markdown.screenshot.ts +0 -100
- package/src/chromium/screenshots/screenshot.ts +0 -22
- package/src/chromium/screenshots/tests/html.screenshot.test.ts +0 -192
- package/src/chromium/screenshots/tests/markdown.screenshot.test.ts +0 -176
- package/src/chromium/screenshots/tests/url.screenshot.test.ts +0 -166
- package/src/chromium/screenshots/url.screenshot.ts +0 -96
- package/src/chromium/utils/converter.utils.ts +0 -187
- package/src/chromium/utils/screenshot.utils.ts +0 -127
- package/src/chromium/utils/tests/converter.utils.test.ts +0 -496
- package/src/chromium/utils/tests/screenshot.utils.test.ts +0 -338
- package/src/common/constants.ts +0 -9
- package/src/common/gotenberg.utils.ts +0 -86
- package/src/common/index.ts +0 -3
- package/src/common/tests/gotenberg.utils.test.ts +0 -141
- package/src/common/types.ts +0 -7
- package/src/gotenberg.ts +0 -54
- package/src/libre-office/index.ts +0 -1
- package/src/libre-office/interfaces/libre-office.types.ts +0 -156
- package/src/libre-office/libre-office.ts +0 -61
- package/src/libre-office/tests/libre-office.test.ts +0 -56
- package/src/libre-office/utils/constants.ts +0 -132
- package/src/libre-office/utils/libre-office.utils.ts +0 -128
- package/src/libre-office/utils/tests/libre-office.utils.test.ts +0 -156
- package/src/main.config.ts +0 -157
- package/src/main.ts +0 -13
- package/src/pdf-engines/index.ts +0 -1
- package/src/pdf-engines/interfaces/pdf-engines.types.ts +0 -10
- package/src/pdf-engines/pdf-engines.ts +0 -156
- package/src/pdf-engines/tests/pdf.engine.test.ts +0 -163
- package/src/pdf-engines/utils/pdf-engines.utils.ts +0 -68
- package/src/pdf-engines/utils/tests/pdf-engines.utils.test.ts +0 -71
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2
|
-
import FormData from 'form-data';
|
|
3
|
-
import { ScreenshotUtils } from './../screenshot.utils';
|
|
4
|
-
|
|
5
|
-
describe('GotenbergUtils', () => {
|
|
6
|
-
const mockFormDataAppend = jest.spyOn(FormData.prototype, 'append');
|
|
7
|
-
const data = new FormData();
|
|
8
|
-
|
|
9
|
-
afterEach(() => {
|
|
10
|
-
jest.resetAllMocks();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
describe('addImageProperties', () => {
|
|
14
|
-
describe('Image format', () => {
|
|
15
|
-
describe('when format parameter is set', () => {
|
|
16
|
-
it('should append format to data', () => {
|
|
17
|
-
ScreenshotUtils.addImageProperties(data, {
|
|
18
|
-
format: 'png'
|
|
19
|
-
});
|
|
20
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
21
|
-
expect(data.append).toHaveBeenCalledWith('format', 'png');
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe('Image background', () => {
|
|
27
|
-
describe('when omitBackground parameter is set', () => {
|
|
28
|
-
it('should append omitBackground to data', () => {
|
|
29
|
-
ScreenshotUtils.addImageProperties(data, {
|
|
30
|
-
format: 'png',
|
|
31
|
-
omitBackground: true
|
|
32
|
-
});
|
|
33
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
34
|
-
expect(data.append).toHaveBeenCalledWith('format', 'png');
|
|
35
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
36
|
-
2,
|
|
37
|
-
'omitBackground',
|
|
38
|
-
'true'
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('Image quality', () => {
|
|
45
|
-
describe('when quality parameter is set', () => {
|
|
46
|
-
it('should append quality to data', () => {
|
|
47
|
-
ScreenshotUtils.addImageProperties(data, {
|
|
48
|
-
format: 'jpeg',
|
|
49
|
-
quality: 50
|
|
50
|
-
});
|
|
51
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
52
|
-
expect(data.append).toHaveBeenCalledWith('format', 'jpeg');
|
|
53
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
54
|
-
2,
|
|
55
|
-
'quality',
|
|
56
|
-
50
|
|
57
|
-
);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('Image width', () => {
|
|
63
|
-
describe('when width parameter is set', () => {
|
|
64
|
-
it('should append width to data', () => {
|
|
65
|
-
ScreenshotUtils.addImageProperties(data, {
|
|
66
|
-
format: 'jpeg',
|
|
67
|
-
width: 800
|
|
68
|
-
});
|
|
69
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
70
|
-
expect(data.append).toHaveBeenCalledWith('format', 'jpeg');
|
|
71
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
72
|
-
2,
|
|
73
|
-
'width',
|
|
74
|
-
800
|
|
75
|
-
);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe('Image height', () => {
|
|
81
|
-
describe('when height parameter is set', () => {
|
|
82
|
-
it('should append height to data', () => {
|
|
83
|
-
ScreenshotUtils.addImageProperties(data, {
|
|
84
|
-
format: 'jpeg',
|
|
85
|
-
height: 600
|
|
86
|
-
});
|
|
87
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
88
|
-
expect(data.append).toHaveBeenCalledWith('format', 'jpeg');
|
|
89
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
90
|
-
2,
|
|
91
|
-
'height',
|
|
92
|
-
600
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
describe('Image clip', () => {
|
|
99
|
-
describe('when clip parameter is set', () => {
|
|
100
|
-
it('should append clip to data', () => {
|
|
101
|
-
ScreenshotUtils.addImageProperties(data, {
|
|
102
|
-
format: 'png',
|
|
103
|
-
clip: true
|
|
104
|
-
});
|
|
105
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(2);
|
|
106
|
-
expect(data.append).toHaveBeenCalledWith('format', 'png');
|
|
107
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
108
|
-
2,
|
|
109
|
-
'clip',
|
|
110
|
-
'true'
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
describe('customize', () => {
|
|
118
|
-
describe('when no option is passed', () => {
|
|
119
|
-
it('should not append anything', async () => {
|
|
120
|
-
await ScreenshotUtils.customize(data, {});
|
|
121
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(0);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('when header parameter is passed', () => {
|
|
126
|
-
it('should append header', async () => {
|
|
127
|
-
await ScreenshotUtils.customize(data, {
|
|
128
|
-
header: Buffer.from('header')
|
|
129
|
-
});
|
|
130
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
131
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
132
|
-
'files',
|
|
133
|
-
Buffer.from('header'),
|
|
134
|
-
'header.html'
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('when footer parameter is passed', () => {
|
|
140
|
-
it('should append footer', async () => {
|
|
141
|
-
await ScreenshotUtils.customize(data, {
|
|
142
|
-
footer: Buffer.from('footer')
|
|
143
|
-
});
|
|
144
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
145
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
146
|
-
'files',
|
|
147
|
-
Buffer.from('footer'),
|
|
148
|
-
'footer.html'
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
describe('when emulatedMediaType parameter is passed', () => {
|
|
154
|
-
it('should append emulatedMediaType', async () => {
|
|
155
|
-
await ScreenshotUtils.customize(data, {
|
|
156
|
-
emulatedMediaType: 'screen'
|
|
157
|
-
});
|
|
158
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
159
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
160
|
-
'emulatedMediaType',
|
|
161
|
-
'screen'
|
|
162
|
-
);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('when waitDelay parameter is passed', () => {
|
|
167
|
-
it('should append waitDelay', async () => {
|
|
168
|
-
await ScreenshotUtils.customize(data, {
|
|
169
|
-
waitDelay: '5s'
|
|
170
|
-
});
|
|
171
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
172
|
-
expect(data.append).toHaveBeenCalledWith('waitDelay', '5s');
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
describe('when waitForExpression parameter is passed', () => {
|
|
177
|
-
it('should append waitForExpression', async () => {
|
|
178
|
-
await ScreenshotUtils.customize(data, {
|
|
179
|
-
waitForExpression: "document.readyState === 'complete'"
|
|
180
|
-
});
|
|
181
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
182
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
183
|
-
'waitForExpression',
|
|
184
|
-
"document.readyState === 'complete'"
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
describe('when extraHttpHeaders parameter is passed', () => {
|
|
190
|
-
it('should append extraHttpHeaders', async () => {
|
|
191
|
-
const extraHttpHeaders = {
|
|
192
|
-
'X-Custom-Header': 'value'
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
await ScreenshotUtils.customize(data, {
|
|
196
|
-
extraHttpHeaders
|
|
197
|
-
});
|
|
198
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
199
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
200
|
-
'extraHttpHeaders',
|
|
201
|
-
JSON.stringify(extraHttpHeaders)
|
|
202
|
-
);
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
describe('when failOnConsoleExceptions parameter is passed', () => {
|
|
207
|
-
it('should append failOnConsoleExceptions', async () => {
|
|
208
|
-
await ScreenshotUtils.customize(data, {
|
|
209
|
-
failOnConsoleExceptions: true
|
|
210
|
-
});
|
|
211
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
212
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
213
|
-
'failOnConsoleExceptions',
|
|
214
|
-
'true'
|
|
215
|
-
);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('when failOnHttpStatusCodes parameter is passed', () => {
|
|
220
|
-
it('should append failOnHttpStatusCodes', async () => {
|
|
221
|
-
await ScreenshotUtils.customize(data, {
|
|
222
|
-
failOnHttpStatusCodes: [499, 599]
|
|
223
|
-
});
|
|
224
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
225
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
226
|
-
'failOnHttpStatusCodes',
|
|
227
|
-
JSON.stringify([499, 599])
|
|
228
|
-
);
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
describe('when skipNetworkIdleEvent parameter is passed', () => {
|
|
233
|
-
it('should append skipNetworkIdleEvent', async () => {
|
|
234
|
-
await ScreenshotUtils.customize(data, {
|
|
235
|
-
skipNetworkIdleEvent: true
|
|
236
|
-
});
|
|
237
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
238
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
239
|
-
'skipNetworkIdleEvent',
|
|
240
|
-
'true'
|
|
241
|
-
);
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
describe('when optimizeForSpeed parameter is passed', () => {
|
|
246
|
-
it('should append optimizeForSpeed', async () => {
|
|
247
|
-
await ScreenshotUtils.customize(data, {
|
|
248
|
-
optimizeForSpeed: true
|
|
249
|
-
});
|
|
250
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
251
|
-
expect(data.append).toHaveBeenCalledWith(
|
|
252
|
-
'optimizeForSpeed',
|
|
253
|
-
'true'
|
|
254
|
-
);
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
describe('when all options are passed', () => {
|
|
259
|
-
it('should append all options', async () => {
|
|
260
|
-
await ScreenshotUtils.customize(data, {
|
|
261
|
-
header: Buffer.from('header.html'),
|
|
262
|
-
footer: Buffer.from('footer.html'),
|
|
263
|
-
emulatedMediaType: 'screen',
|
|
264
|
-
failOnHttpStatusCodes: [499, 599],
|
|
265
|
-
skipNetworkIdleEvent: true,
|
|
266
|
-
failOnConsoleExceptions: true,
|
|
267
|
-
properties: {
|
|
268
|
-
format: 'jpeg',
|
|
269
|
-
quality: 50
|
|
270
|
-
},
|
|
271
|
-
waitDelay: '5s',
|
|
272
|
-
waitForExpression: "document.readyState === 'complete'",
|
|
273
|
-
extraHttpHeaders: { 'X-Custom-Header': 'value' },
|
|
274
|
-
optimizeForSpeed: true
|
|
275
|
-
});
|
|
276
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(12);
|
|
277
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
278
|
-
1,
|
|
279
|
-
'files',
|
|
280
|
-
Buffer.from('header.html'),
|
|
281
|
-
'header.html'
|
|
282
|
-
);
|
|
283
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
284
|
-
2,
|
|
285
|
-
'files',
|
|
286
|
-
Buffer.from('footer.html'),
|
|
287
|
-
'footer.html'
|
|
288
|
-
);
|
|
289
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
290
|
-
3,
|
|
291
|
-
'emulatedMediaType',
|
|
292
|
-
'screen'
|
|
293
|
-
);
|
|
294
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
295
|
-
4,
|
|
296
|
-
'format',
|
|
297
|
-
'jpeg'
|
|
298
|
-
);
|
|
299
|
-
expect(data.append).toHaveBeenNthCalledWith(5, 'quality', 50);
|
|
300
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
301
|
-
6,
|
|
302
|
-
'waitDelay',
|
|
303
|
-
'5s'
|
|
304
|
-
);
|
|
305
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
306
|
-
7,
|
|
307
|
-
'waitForExpression',
|
|
308
|
-
"document.readyState === 'complete'"
|
|
309
|
-
);
|
|
310
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
311
|
-
8,
|
|
312
|
-
'extraHttpHeaders',
|
|
313
|
-
JSON.stringify({ 'X-Custom-Header': 'value' })
|
|
314
|
-
);
|
|
315
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
316
|
-
9,
|
|
317
|
-
'failOnHttpStatusCodes',
|
|
318
|
-
JSON.stringify([499, 599])
|
|
319
|
-
);
|
|
320
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
321
|
-
10,
|
|
322
|
-
'failOnConsoleExceptions',
|
|
323
|
-
'true'
|
|
324
|
-
);
|
|
325
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
326
|
-
11,
|
|
327
|
-
'skipNetworkIdleEvent',
|
|
328
|
-
'true'
|
|
329
|
-
);
|
|
330
|
-
expect(data.append).toHaveBeenNthCalledWith(
|
|
331
|
-
12,
|
|
332
|
-
'optimizeForSpeed',
|
|
333
|
-
'true'
|
|
334
|
-
);
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
});
|
package/src/common/constants.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export enum PdfFormat {
|
|
2
|
-
/**
|
|
3
|
-
* @deprecated Starting from Gotenberg version 7.6, LibreOffice no longer provides support for PDF/A-1a.
|
|
4
|
-
* @see {@link https://gotenberg.dev/docs/troubleshooting#pdfa-1a}
|
|
5
|
-
*/
|
|
6
|
-
A_1a = 'PDF/A-1a',
|
|
7
|
-
A_2b = 'PDF/A-2b',
|
|
8
|
-
A_3b = 'PDF/A-3b'
|
|
9
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { constants, createReadStream, ReadStream, promises } from 'fs';
|
|
2
|
-
import FormData from 'form-data';
|
|
3
|
-
import fetch from 'node-fetch';
|
|
4
|
-
import { PathLikeOrReadStream } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Utility class for common tasks related to the Gotenberg service.
|
|
8
|
-
*/
|
|
9
|
-
export class GotenbergUtils {
|
|
10
|
-
/**
|
|
11
|
-
* Asserts that a condition is true; otherwise, throws an error with the specified message.
|
|
12
|
-
*
|
|
13
|
-
* @param {boolean} condition - The condition to assert.
|
|
14
|
-
* @param {string} message - The error message to throw if the condition is false.
|
|
15
|
-
* @throws {Error} Throws an error with the specified message if the condition is false.
|
|
16
|
-
*/
|
|
17
|
-
public static assert(
|
|
18
|
-
condition: boolean,
|
|
19
|
-
message: string
|
|
20
|
-
): asserts condition {
|
|
21
|
-
if (!condition) {
|
|
22
|
-
throw new Error(message);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Performs a POST request to the specified Gotenberg endpoint with the provided FormData.
|
|
28
|
-
*
|
|
29
|
-
* @param {string} endpoint - The Gotenberg endpoint URL.
|
|
30
|
-
* @param {string} username - The username for basic authentication.
|
|
31
|
-
* @param {string} password - The password for basic authentication.
|
|
32
|
-
* @param {FormData} data - The FormData object to be sent in the POST request.
|
|
33
|
-
* @returns {Promise<Buffer>} A Promise that resolves to the response body as a Buffer.
|
|
34
|
-
* @throws {Error} Throws an error if the HTTP response status is not OK.
|
|
35
|
-
*/
|
|
36
|
-
public static async fetch(
|
|
37
|
-
endpoint: string,
|
|
38
|
-
data: FormData,
|
|
39
|
-
username?: string,
|
|
40
|
-
password?: string
|
|
41
|
-
): Promise<Buffer> {
|
|
42
|
-
const headers: Record<string, string> = { ...data.getHeaders() };
|
|
43
|
-
|
|
44
|
-
if (username && password) {
|
|
45
|
-
const authHeader =
|
|
46
|
-
'Basic ' +
|
|
47
|
-
Buffer.from(username + ':' + password).toString('base64');
|
|
48
|
-
headers['Authorization'] = authHeader;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const response = await fetch(endpoint, {
|
|
52
|
-
method: 'post',
|
|
53
|
-
body: data,
|
|
54
|
-
headers
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
if (!response.ok) {
|
|
58
|
-
throw new Error(`${response.status} ${response.statusText}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return response.buffer();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Adds a file to the FormData object.
|
|
66
|
-
*
|
|
67
|
-
* @param {FormData} data - The FormData object to which the file will be added.
|
|
68
|
-
* @param {PathLikeOrReadStream} file - The file to be added (either a PathLike or a ReadStream).
|
|
69
|
-
* @param {string} name - The name to be used for the file in the FormData.
|
|
70
|
-
* @returns {Promise<void>} A Promise that resolves once the file has been added.
|
|
71
|
-
*/
|
|
72
|
-
public static async addFile(
|
|
73
|
-
data: FormData,
|
|
74
|
-
file: PathLikeOrReadStream,
|
|
75
|
-
name: string
|
|
76
|
-
) {
|
|
77
|
-
if (Buffer.isBuffer(file)) {
|
|
78
|
-
data.append('files', file, name);
|
|
79
|
-
} else if (file instanceof ReadStream) {
|
|
80
|
-
data.append('files', file, name);
|
|
81
|
-
} else {
|
|
82
|
-
await promises.access(file, constants.R_OK);
|
|
83
|
-
data.append('files', createReadStream(file), name);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
package/src/common/index.ts
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { createReadStream, promises } from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import fetch from 'node-fetch';
|
|
4
|
-
import FormData from 'form-data';
|
|
5
|
-
|
|
6
|
-
import { GotenbergUtils } from './../gotenberg.utils';
|
|
7
|
-
|
|
8
|
-
const { Response, FetchError } = jest.requireActual('node-fetch');
|
|
9
|
-
|
|
10
|
-
jest.mock('node-fetch', () => jest.fn());
|
|
11
|
-
|
|
12
|
-
describe('GotenbergUtils', () => {
|
|
13
|
-
const mockFormDataAppend = jest.spyOn(FormData.prototype, 'append');
|
|
14
|
-
const data = new FormData();
|
|
15
|
-
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
jest.resetAllMocks();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('assert', () => {
|
|
21
|
-
const errorMessage = 'error message';
|
|
22
|
-
describe('when condition is true', () => {
|
|
23
|
-
it('should pass', () => {
|
|
24
|
-
expect(() =>
|
|
25
|
-
GotenbergUtils.assert(true, errorMessage)
|
|
26
|
-
).not.toThrow();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
describe('when condition is false', () => {
|
|
30
|
-
it('should return error message', () => {
|
|
31
|
-
expect(() =>
|
|
32
|
-
GotenbergUtils.assert(false, errorMessage)
|
|
33
|
-
).toThrow(errorMessage);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('fetch', () => {
|
|
39
|
-
const mockFetch = fetch as jest.MockedFunction<typeof fetch>;
|
|
40
|
-
const data = new FormData();
|
|
41
|
-
const endpoint = 'http://localhost:3000/forms/chromium/convert/html';
|
|
42
|
-
const basicAuthUsername = 'username';
|
|
43
|
-
const basicAuthPassword = 'pass';
|
|
44
|
-
|
|
45
|
-
describe('when fetch request succeeds', () => {
|
|
46
|
-
it('should return a buffer', async () => {
|
|
47
|
-
mockFetch.mockResolvedValueOnce(new Response('content'));
|
|
48
|
-
const response = await GotenbergUtils.fetch(
|
|
49
|
-
endpoint,
|
|
50
|
-
data,
|
|
51
|
-
basicAuthUsername,
|
|
52
|
-
basicAuthPassword
|
|
53
|
-
);
|
|
54
|
-
await expect(response).toEqual(Buffer.from('content'));
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('when fetch request fails', () => {
|
|
59
|
-
describe('when there is a known error', () => {
|
|
60
|
-
it('should throw an error', async () => {
|
|
61
|
-
const errorMessage =
|
|
62
|
-
'FetchError: request to http://localhost:3000/forms/chromium/convert/html failed';
|
|
63
|
-
mockFetch.mockRejectedValueOnce(
|
|
64
|
-
new FetchError(errorMessage)
|
|
65
|
-
);
|
|
66
|
-
await expect(() =>
|
|
67
|
-
GotenbergUtils.fetch(
|
|
68
|
-
endpoint,
|
|
69
|
-
data,
|
|
70
|
-
basicAuthUsername,
|
|
71
|
-
basicAuthPassword
|
|
72
|
-
)
|
|
73
|
-
).rejects.toThrow(errorMessage);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe('when there is an unknown error', () => {
|
|
78
|
-
it('should throw an error', async () => {
|
|
79
|
-
mockFetch.mockResolvedValueOnce(
|
|
80
|
-
new Response(
|
|
81
|
-
{},
|
|
82
|
-
{
|
|
83
|
-
status: 500,
|
|
84
|
-
statusText: 'Internal server error'
|
|
85
|
-
}
|
|
86
|
-
)
|
|
87
|
-
);
|
|
88
|
-
await expect(() =>
|
|
89
|
-
GotenbergUtils.fetch(
|
|
90
|
-
endpoint,
|
|
91
|
-
data,
|
|
92
|
-
basicAuthUsername,
|
|
93
|
-
basicAuthPassword
|
|
94
|
-
)
|
|
95
|
-
).rejects.toThrow('500 Internal server error');
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe('addFile', () => {
|
|
102
|
-
const mockPromisesAccess = jest.spyOn(promises, 'access');
|
|
103
|
-
const __tmp__ = path.resolve(process.cwd(), '__tmp__');
|
|
104
|
-
const filePath = path.resolve(__tmp__, 'file.html');
|
|
105
|
-
|
|
106
|
-
beforeAll(async () => {
|
|
107
|
-
mockPromisesAccess.mockResolvedValue();
|
|
108
|
-
await promises.mkdir(path.resolve(__tmp__), { recursive: true });
|
|
109
|
-
await promises.writeFile(filePath, 'data');
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
afterAll(async () => {
|
|
113
|
-
await promises.rm(path.resolve(__tmp__), { recursive: true });
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe('when file is passed as read stream', () => {
|
|
117
|
-
it('should append file to data', async () => {
|
|
118
|
-
const file = createReadStream(filePath);
|
|
119
|
-
await GotenbergUtils.addFile(data, file, 'file');
|
|
120
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
121
|
-
expect(data.append).toHaveBeenCalledWith('files', file, 'file');
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('when file is passed as path', () => {
|
|
126
|
-
it('should append file to data', async () => {
|
|
127
|
-
await GotenbergUtils.addFile(data, filePath, 'file');
|
|
128
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
describe('when file is passed as buffer', () => {
|
|
133
|
-
it('should append file to data', async () => {
|
|
134
|
-
const file = Buffer.from('data');
|
|
135
|
-
await GotenbergUtils.addFile(data, file, 'file');
|
|
136
|
-
expect(mockFormDataAppend).toHaveBeenCalledTimes(1);
|
|
137
|
-
expect(data.append).toHaveBeenCalledWith('files', file, 'file');
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
});
|
package/src/common/types.ts
DELETED
package/src/gotenberg.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
process.env.SUPPRESS_NO_CONFIG_WARNING = 'y';
|
|
2
|
-
|
|
3
|
-
import * as dotenv from 'dotenv';
|
|
4
|
-
import * as path from 'path';
|
|
5
|
-
import config from 'config';
|
|
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
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Class representing configuration for interacting with Gotenberg service.
|
|
20
|
-
*/
|
|
21
|
-
export class Gotenberg {
|
|
22
|
-
/**
|
|
23
|
-
* The endpoint for the Gotenberg service.
|
|
24
|
-
* @type {string}
|
|
25
|
-
*/
|
|
26
|
-
static get endpoint(): string | undefined {
|
|
27
|
-
const hasEndpoint = config.has('gotenberg.endpoint');
|
|
28
|
-
return hasEndpoint
|
|
29
|
-
? config.get<string>('gotenberg.endpoint')
|
|
30
|
-
: process.env.GOTENBERG_ENDPOINT;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The username for basic authentication with the Gotenberg service.
|
|
35
|
-
* @type {string | undefined}
|
|
36
|
-
*/
|
|
37
|
-
static get username(): string | undefined {
|
|
38
|
-
const hasUsername = config.has('gotenberg.api.basicAuth.username');
|
|
39
|
-
return hasUsername
|
|
40
|
-
? config.get<string>('gotenberg.api.basicAuth.username')
|
|
41
|
-
: process.env.GOTENBERG_API_BASIC_AUTH_USERNAME;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* The password for basic authentication with the Gotenberg service.
|
|
46
|
-
* @type {string | undefined}
|
|
47
|
-
*/
|
|
48
|
-
static get password(): string | undefined {
|
|
49
|
-
const hasPassword = config.has('gotenberg.api.basicAuth.password');
|
|
50
|
-
return hasPassword
|
|
51
|
-
? config.get<string>('gotenberg.api.basicAuth.password')
|
|
52
|
-
: process.env.GOTENBERG_API_BASIC_AUTH_PASSWORD;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { LibreOffice } from './libre-office';
|