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 🙏

© 2024 – Pkg Stats / Ryan Hefner

mailreader

v1.0.0

Published

This module parses RFC 2822 strings. Works on a simplified version of a MIME tree as commonly used in emails. `mailreader` uses [email.js](http://emailjs.org) components.

Downloads

15

Readme

mailreader

This module parses RFC 2822 strings. Works on a simplified version of a MIME tree as commonly used in emails. mailreader uses email.js components.

Here's how mailreader is intended:

  • Receive a mail with the imap-client and get the body parts you're interested in
  • Give them to mailreader for parsing
  • Done.

Build Status

The MIME tree abstraction

To not have to deal with the whole complexity of handling a full-blown mime tree, mailreader uses a simplified version of the most commonly used MIME nodes used in emails.

html

A MIME node with Content-Type: text/html, without Content-Disposition header. Example:

{
    type: 'text',
    raw: 'Content-Transfer-Encoding: 7bit\r\nContent-Type: text/html;\r\n    charset=us-ascii\r\n\r\n<html><body>asd<img src="cid:20154202-BB6F-49D7-A1BB-17E9937B42B5"></body></html>\r\n',
    content: '<html><body>asd<img src="cid:20154202-BB6F-49D7-A1BB-17E9937B42B5"></body></html>'
}

text

A MIME node with Content-Type: text/plain, without Content-Disposition header. Example:

{
    type: 'text',
    raw: 'Content-Type: text/plain; charset=ISO-8859-1\r\n\r\nasdasd\r\n',
    content: 'asdasd'
}

attachment

A MIME node with Content-Disposition header. Example:

{
    type: 'attachment',
    raw: 'Content-Type: image/jpeg; name="myfile.jpg"\r\nContent-Disposition: attachment; filename="myfile.jpg"\r\nContent-Id: <my-content-identifier>\r\nContent-Transfer-Encoding: base64\r\n\r\n ... (a lot of base64) ... \r\n'
    content: [...], // Uint8Array with binary content
    filename: 'myfile.jpg', // the attachment filename, 'attachment' as fallback if not parseable
    mimeType: 'image/jpeg', // the attachment MIME type, application/octet-stream as fallback if not parseable
    id: 'my-content-identifier' // if `Content-Id` header is present, the id can be used to cross-reference it with html body parts
}

signed

A MIME subtree with Content-Type: multipart/signed. Example

{
    type: 'signed',
    raw: 'Content-Type: multipart/signed; boundary="Apple-Mail=_C94D8F86-2AA4-4D9A-A975-F51C8A2937B6"; protocol="application/pgp-signature"; micalg=pgp-sha512\r\n\r\n--Apple-Mail=_C94D8F86-2AA4-4D9A-A975-F51C8A2937B6\r\nContent-Transfer-Encoding: 7bit\r\nContent-Type: text/plain;\r\n    charset=us-ascii\r\n\r\nthis is some signed stuff!\r\n\r\n--Apple-Mail=_C94D8F86-2AA4-4D9A-A975-F51C8A2937B6\r\nContent-Transfer-Encoding: 7bit\r\nContent-Disposition: attachment;\r\n    filename=signature.asc\r\nContent-Type: application/pgp-signature;\r\n    name=signature.asc\r\nContent-Description: Message signed with OpenPGP using GPGMail\r\n\r\n-----BEGIN PGP SIGNATURE-----\r\nComment: GPGTools - https://gpgtools.org\r\n\r\niQEcBAEBCgAGBQJTaJgoAAoJEOHUm+Va/GWKreEIAI9qgTBR1SWciKQXduY2ZyY1\r\n3ymKequbFKyoG6gytrIfeAeMJrTZiySXNvOHMlm852fE0vQFWNXtVf2XW0wp8gHL\r\n9X8rpaKtArQHNXWgWN/23+Ea1A0GsyMaxRQxJgj62BEsQsnGUJDgWhq6T5SDZA+h\r\n1ihy12Xvh4F4P//Nt8az2EmWLCv4KbzGp6LVS5jqVxPncuO5mKYZB3yupXnV2nKA\r\nrijmxCTaTJM2tTcTucxNR7hiYTjY6kCpmaTGg9Aq1iy8+hahZ/ZJndzrIMcg+VEA\r\nclbOS6qREijrtuUDLiK58j4w41vRsOmbMOyGQEYNJ7cXQ793/qDPetY4W2ZtRLk=\r\n=iMlU\r\n-----END PGP SIGNATURE-----\r\n\r\n--Apple-Mail=_C94D8F86-2AA4-4D9A-A975-F51C8A2937B6--\r\n',
    signedMessage: 'Content-Transfer-Encoding: 7bit\r\nContent-Type: text/plain;\r\n    charset=us-ascii\r\n\r\nthis is some signed stuff!\r\n\r\n', //
    signature: '-----BEGIN PGP SIGNATURE-----\r\nComment: GPGTools - https://gpgtools.org\r\n\r\niQEcBAEBCgAGBQJTaJgoAAoJEOHUm+Va/GWKreEIAI9qgTBR1SWciKQXduY2ZyY1\r\n3ymKequbFKyoG6gytrIfeAeMJrTZiySXNvOHMlm852fE0vQFWNXtVf2XW0wp8gHL\r\n9X8rpaKtArQHNXWgWN/23+Ea1A0GsyMaxRQxJgj62BEsQsnGUJDgWhq6T5SDZA+h\r\n1ihy12Xvh4F4P//Nt8az2EmWLCv4KbzGp6LVS5jqVxPncuO5mKYZB3yupXnV2nKA\r\nrijmxCTaTJM2tTcTucxNR7hiYTjY6kCpmaTGg9Aq1iy8+hahZ/ZJndzrIMcg+VEA\r\nclbOS6qREijrtuUDLiK58j4w41vRsOmbMOyGQEYNJ7cXQ793/qDPetY4W2ZtRLk=\r\n=iMlU\r\n-----END PGP SIGNATURE-----\r\n\r\n',
    content: [{
        type: 'text',
        content: 'this is some signed stuff!'
    }]
}

encrypted

A MIME subtree with Content-Type: multipart/signed

{
    type: 'encrypted',
    raw: 'Content-Type: multipart/encrypted;\r\n protocol=\"application/pgp-encrypted\";\r\n boundary=\"MrDkNHd70n0CBWqJqodk50MfrlELiXLgn\"\r\n\r\nThis is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)\r\n--MrDkNHd70n0CBWqJqodk50MfrlELiXLgn\r\nContent-Type: application/pgp-encrypted\r\nContent-Description: PGP/MIME version identification\r\n\r\nVersion: 1\r\n\r\n--MrDkNHd70n0CBWqJqodk50MfrlELiXLgn\r\nContent-Type: application/octet-stream; name=\"encrypted.asc\"\r\nContent-Description: OpenPGP encrypted message\r\nContent-Disposition: inline; filename=\"encrypted.asc\"\r\n\r\n-----BEGIN PGP MESSAGE-----\r\nVersion: GnuPG v1.4.13 (Darwin)\r\nComment: GPGTools - https://gpgtools.org\r\nComment: Using GnuPG with Thunderbird - http://www.enigmail.net/\r\n\r\n ... ciphertext goes here ... \r\n=3OkT\r\n-----END PGP MESSAGE-----\r\n\r\n--MrDkNHd70n0CBWqJqodk50MfrlELiXLgn--',
    content: '-----BEGIN PGP MESSAGE-----\r\nVersion: GnuPG v1.4.13 (Darwin)\r\nComment: GPGTools - https://gpgtools.org\r\nComment: Using GnuPG with Thunderbird - http://www.enigmail.net/\r\n\r\n ... ciphertext goes here ... \r\n=3OkT\r\n-----END PGP MESSAGE-----' // PGP ciphertext
}

Let's parse stuff

var mailreader = require('mailreader');
var email = {
    bodyParts: [{
        type: 'text',
        raw: 'Content-Type: text/plain; charset=ISO-8859-1\r\n\r\nasdasd\r\n'
    }]
};

mailreader.parse(email, function(err, bodyParts) {
    console.log(bodyParts[0].content); // -> 'asdasd'
});

Multithreading

To offload the mail parsing to a web worker, call mailreader.startWorker(path). mailreader has to load dependencies, so there are two options:

  • Use startWorker('[PATH]/mailreader-parser-worker.js') as the entry point for the web worker to load the email.js dependencies via AMD or
  • Build mailreader-parser-worker-browserify.js with browserify and supply the browserified file startWorker('[PATH]/[BROWSERIFIED-FILE].js')

Get your hands dirty

Run the following commands to get started:

npm install && grunt