name2mime - A simple node package to get MIME types of file
Tags: node, mime, npm, javascript
Published: 2020-05-23 20:59:25

# Background
So I recently had a client who wanted a [Lambda](https://aws.amazon.com/lambda/) trigger on his [S3](https://aws.amazon.com/s3) bucket which writes some files to a directory in his bucket. Everything was going well, except that the content type of all the files was being set to `application/octet-stream`. So he wanted me to fix this issue such that when we put the object in the bucket, the ContentType gets set to an appropriate one. I thought it'll hardly take an hour. All I'd have to do is to search for a node package, install it and the issue is solved. But nope. NOPE!

# Exiting solutions

1. [mmmagic](https://www.npmjs.com/package/mmmagic):
It's a great package, uses C-language binding behind the scene, takes file buffer as input, and spits out a lot of metadata about a file. 

    **Limitations**: When passed an SVG/DXF, it categorizes them as text/html. 

2. [file-type](https://www.npmjs.com/package/file-type):
It also takes a file buffer as input and returns MIME type. 

    **Limitations**: When passed an SVG/DXF or some other kind of files, it retuns `null/undefined`. 

3. [mime-kind](https://www.npmjs.com/package/mime-kind):
It takes a file buffer and a default value as input and if the file type is not determined, it returns that default value.

    **Limitations**: Same results here, it was assigning that default value for SVF/DXF and some other files.

4. [ext2mime](https://github.com/fabiospampinato/ext2mime):
This one works similar in fashion to the one I created. It takes in files name and spits out its MIME types.

    **Limitations**: The dataset of extensions was very limited and couldn't recognize all kinds of files.

# 600+ extensions supported
No credits to me. Thanks to the good guys at [FreeFormatter](https://www.freeformatter.com/mime-types-list.html). I wrote a simple script in the browser console to extract all the extensions from their site.

```
document.write(JSON.stringify(Array.from(document.getElementsByClassName('bordered-table zebra-striped table-sort')[0].children[1].children).reduce((obj, row) => {
	let objs = {...obj};
	row.children[2].childNodes[0].data.split(', ').map(ext => objs = objs[ext] ? objs : ({...objs, [ext]: {'type': row.children[1].childNodes[0].data, 'name': row.children[0].childNodes[0].data}}))
	return objs;
}, {})))
```

![The Magic Script](https://dev-to-uploads.s3.amazonaws.com/i/nvcar34stxwm9dicvm04.png)

Hit ENTER!

![The MAGIC Itself](https://dev-to-uploads.s3.amazonaws.com/i/o48nig2hluwg5nt7e0zf.png)

# Building the idea into an NPM package
I used [this](https://github.com/flexdinesh/npm-module-boilerplate) amazing boilerplate code to build my NPM package. It already had template for test cases and [Travis-CI](https://travis-ci.org/), so whenever I push my code to github, it automatically runs test cases and updates the status on my repo homepage. Amazing isn't it?

# Installation

```sh
$ npm install name2mime --save
```
or
```sh
$ yarn add name2mime
```

# Sample

```
const getMime = require('name2mime');

const value = getMime('filename.jpg');

console.log(value);

// { type: 'image/jpeg', name: 'JPEG Image' }
```

# For Maintainers & Contributors
### Commands
- `npm run clean` - Remove `lib/` directory
- `npm test` - Run tests with linting and coverage results.
- `npm test:only` - Run tests without linting or coverage.
- `npm test:watch` - You can even re-run tests on file changes!
- `npm test:prod` - Run tests with minified code.
- `npm run test:examples` - Test written examples on pure JS for better understanding module usage.
- `npm run lint` - Run ESlint with airbnb-config
- `npm run cover` - Get coverage report for your code.
- `npm run build` - Babel will transpile ES6 => ES5 and minify the code.
- `npm run prepublish` - Hook for npm. Do all the checks before publishing your module.