@pollium/vyva-convert
v0.4.0
Published
Server-side tools for Vyva content: clean what clients send, import Word, PowerPoint, PDF, OpenDocument, Markdown and image files, and export to PDF, Word, PowerPoint and HTML.
Readme
@pollium/vyva-convert
Server-side tools for Vyva content. It cleans what clients send, imports Word, PowerPoint, PDF, OpenDocument, RTF, Markdown, text and image files, and exports to PDF, Word, PowerPoint and HTML. It runs in Node.
npm install @pollium/vyva-convertCleaning what clients send
import { cleanContent } from '@pollium/vyva-convert/clean-content';
const content = cleanContent(body.content);The cleaner keeps the editor's formatting. It removes scripts, event handlers, unsafe links and any
image that does not point at a file id. Ids that repeat or are not valid get new ones. Each text box is
saved as tall as its text. For a single HTML fragment, use cleanHtml from
@pollium/vyva-convert/clean-html.
Exporting
import { exportContent, isExportFormat } from '@pollium/vyva-convert/export';
import { gotenberg } from '@pollium/vyva-convert/gotenberg';
import { contentDisposition } from '@pollium/vyva-convert/attachment';
if(!isExportFormat(request.params.format)) return reply.code(400).send();
const file = await exportContent(content, request.params.format, {
title: 'Subnetting guide',
language: 'en',
readImage: async (fileId) => {
const stored = await files.find(fileId);
return stored === null ? null : { data: stored.bytes, contentType: stored.contentType };
},
pdfEngine: gotenberg({ url: 'http://gotenberg:3000' })
});
reply.header('content-disposition', contentDisposition('Subnetting guide', file.extension)).type(file.contentType).send(file.data);| Content | Formats |
|---|---|
| Document | pdf, docx, html |
| Deck | pptx, pdf |
| Deck of PDF pages | pdf |
exportFormatsOf(content) lists them, and canExport(content, format) checks one.
readImageis called once for every image the content uses. Returnnulland the export goes on without that image.- The PDF fonts and images travel with the page, so the PDF engine needs no network access.
pdfEngineis only needed forpdf. It is a function that takes aPdfJob(the HTML, the files it refers to by name, a footer with Chromium'spageNumberandtotalPagesclasses, and the page size in inches) and returns the PDF. Usegotenbergor write your own with Puppeteer or Playwright.- The
htmlexport is one self-contained file, with its images and fonts inline. - A deck of PDF pages exports as the original PDF, read through
readImage, with what the slides add printed on top of each page. Pages with nothing added are copied as they are, and a deck nobody drew on never reaches the PDF engine. An encrypted PDF is refused asunsupported.
Importing
import { importFile } from '@pollium/vyva-convert/import';
const { title, content } = await importFile(upload.bytes, upload.filename, {
saveImage: async ({ name, data, contentType }) => (await files.store(name, data, contentType)).id
});The file is recognized by its content, not its name. Word, PowerPoint and OpenDocument files are told apart by what their zip holds, Word 97 and PowerPoint 97 files by the streams they hold, and PDF, RTF, PNG, JPEG, GIF and WebP by their signatures. Only Markdown (
.md) and text (.txt) are recognized by their extension, and only when they are valid UTF-8.Word, Markdown and text files become documents, and PowerPoint files become decks. A deck keeps its theme colors and the font most of its text uses. What its slide master draws comes in locked, behind the slide's own elements, and freeform shapes come in as polygons.
A PDF becomes a deck of its own pages: one slide for each page, at the size of the first page, with that page behind it. Nothing is converted, so it looks exactly like the original.
saveImagestores the PDF once, asapplication/pdf; returnnulland the import is refused asempty. A PDF Vyva cannot open is refused asunsupported, and one of more than 1000 pages astoo-large.A picture becomes a deck of one slide, in the format closest to its shape, with the picture filling it.
saveImagestores it like any other image; returnnulland the import is refused asempty.With
officeEngine, Vyva reads what it cannot read alone. Word 97, OpenDocument text and RTF files are turned into Word, and PowerPoint 97 and OpenDocument presentations into PowerPoint, then imported as those. Without an engine those formats are refused asunsupported.officeEnginetakes{ file, from, to }and returns the converted file.libreOffice()from@pollium/vyva-convert/libreofficedoes that with thesofficeon the machine (commandchanges the path), one conversion per call:import { libreOffice } from '@pollium/vyva-convert/libreoffice'; await importFile(upload.bytes, upload.filename, { saveImage, officeEngine: libreOffice() });saveImagestores each image and returns its file id, which must be a UUID. Returnnullto leave the image out. If it throws, the import fails with your error.Files over 25 MB (
maxByteschanges the limit) and files it cannot read are refused.
Errors
Expected failures are a ConvertError from @pollium/vyva-convert/errors, with a code. Anything else is
a bug or a broken file, so log it.
| Code | Meaning |
|---|---|
| unsupported | The file is not one Vyva imports, or the content cannot be exported in that format |
| too-large | The file, or what it unzips to, is over the limit |
| empty | The file has nothing to import |
| pdf-failed | The PDF engine could not be reached or answered with an error |
| office-failed | officeEngine could not convert the file, or answered with something else |
