npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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-convert

Cleaning 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.

  • readImage is called once for every image the content uses. Return null and the export goes on without that image.
  • The PDF fonts and images travel with the page, so the PDF engine needs no network access.
  • pdfEngine is only needed for pdf. It is a function that takes a PdfJob (the HTML, the files it refers to by name, a footer with Chromium's pageNumber and totalPages classes, and the page size in inches) and returns the PDF. Use gotenberg or write your own with Puppeteer or Playwright.
  • The html export 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 as unsupported.

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. saveImage stores the PDF once, as application/pdf; return null and the import is refused as empty. A PDF Vyva cannot open is refused as unsupported, and one of more than 1000 pages as too-large.

  • A picture becomes a deck of one slide, in the format closest to its shape, with the picture filling it. saveImage stores it like any other image; return null and the import is refused as empty.

  • 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 as unsupported.

    officeEngine takes { file, from, to } and returns the converted file. libreOffice() from @pollium/vyva-convert/libreoffice does that with the soffice on the machine (command changes the path), one conversion per call:

    import { libreOffice } from '@pollium/vyva-convert/libreoffice';
    
    await importFile(upload.bytes, upload.filename, { saveImage, officeEngine: libreOffice() });
  • saveImage stores each image and returns its file id, which must be a UUID. Return null to leave the image out. If it throws, the import fails with your error.

  • Files over 25 MB (maxBytes changes 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 |