How to convert ReadableStream into ReadStream in NodeJS?
Asked Answered
T

2

10

I'm using nodemailer, and pdfmake to create a pdf, and send it in the email's attachments. I don't have too much experience with file handling in NodeJS, and I can't make it work.

See example where the file is saved. As I've checked the types, createPdfKitDocument returns an extension of NodeJS.ReadableStream.

In nodemailer I can include attachments as Stream or Readable See documentation.

However, I'm not able to send the attachment without saving it, and give the path to the file.

I tried to provide the ReadableStream returned from createPdfKitDocument as is, it result in hanging promise. I tried to wrap it with Readable.from(), it didn't work. I tried to call .read() on the result, and it didn't result in hanging promise, but the pdf cannot be opened.

Any ideas how can I convert a ReadableStream to Readable, or Buffer?

Termination answered 29/1, 2022 at 13:34 Comment(0)
N
5

NodeJS.ReadableStream type streams are used in older NodeJS libraries and versions. You can use the wrap method in Readable to convert NodeJS.ReadableStream to Readable stream.

const { OldReader } = require('./old-api-module.js');
const { Readable } = require('node:stream');
const oreader = new OldReader(); // will return stream of NodeJS.ReadableStream
const myReader = new Readable().wrap(oreader);

myReader.on('readable', () => {
  myReader.read(); // etc.
});

Ref: https://nodejs.org/api/stream.html#stream_readable_wrap_stream. For additional info do refer this as well https://nodejs.org/api/stream.html#compatibility-with-older-nodejs-versions

Naara answered 10/5, 2022 at 15:0 Comment(0)
W
0

Here's a solution (typescript) that worked for me when I was trying to generate PDF files using puppeteer's createPDFStream method, which returns a ReadableStream<Uint8Array>.


import puppeteer, { Browser } from 'puppeteer';
import { Readable } from 'stream';
import { ReadableStream } from 'stream/web';

/**
 * This function renders HTML contents to a PDF file stream
 * @param html HTML string
 */
async function renderToStream(html: string) {
  let browser: Browser;

  try {
    browser = await puppeteer.launch();
    const page = await browser.newPage();

    await page.setContent(html).catch(() => browser.close());

    const webStream = await page.createPDFStream();

    const nodeStream = Readable.fromWeb(webStream as ReadableStream<any>);

    nodeStream.on('end', () => browser.close());

    return nodeStream;
  } catch (err) {
    console.error('PDF rending to stream failed: ', err);

    if (browser) {
      browser.close();
    }
  }
}


Whity answered 19/7 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.