Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b58a8b64e | |||
| 7f1513f170 | |||
| c2c64b0be9 | |||
| 1cf5c7a8c0 | |||
| d1d7bbb526 | |||
| c299b63f63 | |||
| 020778a9d4 | |||
| 8a15bd69c8 | |||
| 2677573022 | |||
| 4167947a87 |
@@ -6,8 +6,8 @@
|
||||
[](https://www.npmjs.com/package/gotenberg-js-client)
|
||||

|
||||
|
||||
A simple JS/TS client for interacting with a [Gotenberg](https://thecodingmachine.github.io/gotenberg/) API.<br>
|
||||
[Gotenberg](https://thecodingmachine.github.io/gotenberg/) is a Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.
|
||||
A simple JS/TS client for interacting with a [Gotenberg](https://gotenberg.dev/) API.<br>
|
||||
[Gotenberg](https://gotenberg.dev/) is a Docker-powered stateless API for converting HTML, Markdown and Office documents to PDF.
|
||||
|
||||
- HTML and Markdown conversions using Google Chrome headless
|
||||
- Office conversions (.txt, .rtf, .docx, .doc, .odt, .pptx, .ppt, .odp and so on) using [unoconv](https://github.com/dagwieers/unoconv)
|
||||
@@ -26,6 +26,19 @@ Or using `npm`
|
||||
$ npm install --save gotenberg-js-client
|
||||
```
|
||||
|
||||
## NB ⚠️
|
||||
|
||||
This library is not yet fully compatible with Gotenberg 7.<br/>
|
||||
You can find more info in [this comment](https://github.com/yumauri/gotenberg-js-client/issues/32#issuecomment-981140727).
|
||||
|
||||
There are three main issues:
|
||||
|
||||
- Gotenberg 7 has introduced new concept of conversion modules, thus, changing conversion URLs, so now they are different, than ones, this library creates. This can be sidestepped using custom connection string or adjusting URL manually (see [this comment](https://github.com/yumauri/gotenberg-js-client/issues/32#issuecomment-981140727)).
|
||||
- New modules has some new possibilities/parameters, which are impossible to pass, using this library. This can be sidestepped using `adjust`, and casting to `any`, if you use TypeScript (see [this issue](https://github.com/yumauri/gotenberg-js-client/issues/33) for reference).
|
||||
- Gotenberg 7 can potentially has many many different custom conversion modules, you can even write your own one. You can combine p.1 and p.2 to use any module with any path with any parameters, but I guess it will look not good. But it should work nonetheless.
|
||||
|
||||
So, nothing you can live without, but there are some inconveniences. For a while ;)
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gotenberg-js-client",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.4",
|
||||
"description": "A simple JS/TS for interacting with a Gotenberg API",
|
||||
"author": "Victor Didenko <yumaa.verdin@gmail.com> (https://yumaa.name)",
|
||||
"license": "MIT",
|
||||
@@ -25,7 +25,7 @@
|
||||
{
|
||||
"path": "pkg/dist-node/index.js",
|
||||
"webpack": false,
|
||||
"limit": "4229 B"
|
||||
"limit": "4293 B"
|
||||
}
|
||||
],
|
||||
"@pika/pack": {
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ export function post(
|
||||
|
||||
req.on('error', reject)
|
||||
req.on('response', (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
||||
resolve(res)
|
||||
} else {
|
||||
let error = res.statusCode + ' ' + res.statusMessage
|
||||
@@ -74,7 +74,7 @@ export function get(this: object | null, url: string): Promise<NodeJS.ReadableSt
|
||||
|
||||
req.on('error', reject)
|
||||
req.on('response', (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
||||
resolve(res)
|
||||
} else {
|
||||
res.resume() // ignore response body
|
||||
|
||||
@@ -81,14 +81,17 @@ export const isIterable = (
|
||||
|
||||
/**
|
||||
* Check, if given argument is simple string, and presumably is is just file name
|
||||
* I hope no one will wants to use filename longer than 50 symbols :)
|
||||
*/
|
||||
const fileNameRE = /^[\p{L}\w\s\(\).,-]+\.[A-Za-z0-9]+$/u // tslint:disable-line no-empty-character-class
|
||||
const MIN_FILE_NAME_LENGTH = 3
|
||||
const MAX_FILE_NAME_LENGTH = 50
|
||||
const filenameRE = /.+\..+/
|
||||
const filenameReservedRE = /[<>:"/\\|?*\u0000-\u001F]/g
|
||||
const windowsReservedNameRE = /^(con|prn|aux|nul|com\d|lpt\d)$/i
|
||||
const MAX_FILE_NAME_LENGTH = 255
|
||||
export const isFileName = (x: Source | undefined | null) =>
|
||||
isString(x) &&
|
||||
!x.startsWith('file:') && // in ideal world there should be `!isFileUri(x)`, but TypeScript sucks here
|
||||
x.length >= MIN_FILE_NAME_LENGTH &&
|
||||
x.length <= MAX_FILE_NAME_LENGTH &&
|
||||
fileNameRE.test(x)
|
||||
x !== '.' &&
|
||||
x !== '..' &&
|
||||
!x.startsWith('file:') && // in ideal world there should be `!isFileUri(x)`, but TypeScript sucks here
|
||||
!filenameReservedRE.test(x) &&
|
||||
!windowsReservedNameRE.test(x) &&
|
||||
filenameRE.test(x)
|
||||
|
||||
@@ -53,7 +53,8 @@ test('Test `isFileName` function', function () {
|
||||
expect(isFileName('Screenshot 2021-12-24 at 09.16.20.png')).toBe(true) // <-
|
||||
expect(isFileName('.test.png')).toBe(true) // <-
|
||||
expect(isFileName('.png')).toBe(false)
|
||||
expect(isFileName('🙀.png')).toBe(false)
|
||||
expect(isFileName('🙀.png')).toBe(true) // <-
|
||||
expect(isFileName('ces La esencia del cristianismo Dios es persona (jóvenes).docx')).toBe(true) // <-
|
||||
expect(isFileName(url)).toBe(false)
|
||||
expect(isFileName(array)).toBe(false)
|
||||
expect(isFileName(map)).toBe(false)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
import { createWriteStream } from 'fs'
|
||||
import { pipe, gotenberg, convert, url, to, please } from '../../src'
|
||||
|
||||
// need to run Gotenberg like this
|
||||
// docker run --rm -p 3500:3000 gotenberg/gotenberg:7
|
||||
|
||||
pipe(
|
||||
gotenberg(`http://localhost:3500/forms/chromium`),
|
||||
// gotenberg(`https://demo.gotenberg.dev/forms/chromium`),
|
||||
convert,
|
||||
url,
|
||||
to({ margins: [0, 0, 0, 0] }),
|
||||
(request) => {
|
||||
;(request.fields as any).url = request.fields.remoteURL
|
||||
delete request.fields.remoteURL
|
||||
return request
|
||||
},
|
||||
please
|
||||
)(`https://www.google.com`)
|
||||
.then((pdf) => pdf.pipe(createWriteStream(`${__dirname}/google.pdf`)))
|
||||
.catch(console.error)
|
||||
|
||||
// pipe(
|
||||
// gotenberg(''),
|
||||
// convert, // it is save to remove this line, if you want
|
||||
// html,
|
||||
// adjust({
|
||||
// // manually adjust endpoint, because
|
||||
// // gotenberg:7 has different conversion endpoints
|
||||
// url: 'http://localhost:3500/forms/chromium/convert/html',
|
||||
|
||||
// // manually adjust for fields
|
||||
// fields: {
|
||||
// printBackground: true,
|
||||
// // `printBackground` is not valid field for gotenberg:6
|
||||
// // so we have to cast to any, otherwise typescript will complain
|
||||
// } as any,
|
||||
// }),
|
||||
// please
|
||||
// )('<html><body bgcolor="blue">test</body></html>')
|
||||
// .then((pdf) => pdf.pipe(createWriteStream(`${__dirname}/html_with_bg.pdf`)))
|
||||
// .catch(console.error)
|
||||
@@ -0,0 +1,29 @@
|
||||
import { createWriteStream } from 'fs'
|
||||
import { pipe, gotenberg, convert, url, to, please } from '../../src'
|
||||
import got from 'got'
|
||||
|
||||
// need to run Gotenberg like this
|
||||
// docker run --rm -p 3500:3000 gotenberg/gotenberg:7
|
||||
|
||||
// const got = await import('got')
|
||||
|
||||
// you can pass any config for your client
|
||||
// as third argument in `gotenberg` function
|
||||
const client = {
|
||||
post: (url, body, headers) => Promise.resolve(got.post({ url, body, headers, isStream: true })),
|
||||
}
|
||||
|
||||
pipe(
|
||||
gotenberg(`http://localhost:3500/forms/chromium`, client),
|
||||
convert,
|
||||
url,
|
||||
to({ margins: [0, 0, 0, 0] }),
|
||||
(request) => {
|
||||
;(request.fields as any).url = request.fields.remoteURL
|
||||
delete request.fields.remoteURL
|
||||
return request
|
||||
},
|
||||
please
|
||||
)(`https://www.google.com`)
|
||||
.then((pdf) => pdf.pipe(createWriteStream(`${__dirname}/google_via_got.pdf`)))
|
||||
.catch(console.error)
|
||||
@@ -0,0 +1,30 @@
|
||||
import fs from 'fs'
|
||||
import * as got from '../../src'
|
||||
|
||||
// need to run Gotenberg like this
|
||||
// docker run --rm -p 3500:3000 gotenberg/gotenberg:7
|
||||
|
||||
got
|
||||
.pipe(
|
||||
got.gotenberg(''),
|
||||
got.merge,
|
||||
got.adjust({
|
||||
// manually adjust endpoint, because
|
||||
// gotenberg:7 has different one
|
||||
url: 'http://localhost:3500/forms/libreoffice/convert',
|
||||
|
||||
// manually adjust for fields
|
||||
fields: {
|
||||
merge: true,
|
||||
// `merge` is not valid field for gotenberg:6
|
||||
// so we have to cast to any, otherwise typescript will complain
|
||||
} as any, // if you don't use typescript, just remove `as any` casting
|
||||
}),
|
||||
got.please
|
||||
)({
|
||||
'in1.docx': `file://${__dirname}/in1.docx`,
|
||||
'in2.docx': `file://${__dirname}/in2.docx`,
|
||||
'in3.docx': `file://${__dirname}/in3.docx`,
|
||||
})
|
||||
.then((pdf) => pdf.pipe(fs.createWriteStream(`${__dirname}/out1.pdf`)))
|
||||
.catch(console.error)
|
||||
Reference in New Issue
Block a user