Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

imgbb-uploader

TheRealBarenziah12.8kSEE LICENSE IN TARGARYEN_UNLICENSE1.5.1TypeScript support: included

Lightweight module to upload images through imgBB and other chevereto-based APIs.

imgbb, imgbb-uploader, image upload, picture upload, chevereto, chevereto-free, upload

readme

imgbb-uploader

Lightweight Nodejs module to upload pictures to imgBB (or other chevereto-based APIs) and get display URLs in response.
Primary use is letting imgBB handle the hosting & serving of images.

https://nodei.co/npm/imgbb-uploader.png?downloads=true&downloadRank=true&stars=true Known Vulnerabilities dependencies DeepScan grade Test suite

Install

npm install imgbb-uploader

Compatibility:

Node >= 8 ( Promises/await ) ESM projects are supported from 1.5 onward Care: this module uses fs under the hood. It WON'T work outside the node environment !

Want to use this client-side? Click here

Formats supported by ImgBB API: .jpg, .png,.bmp,.gif, base64, url.

We also support Chevereto v3 & v4!

Did you know? imgBB is based on Chevereto, a software written by rodber that you can easily host yourself.

To use with Chevereto, click here!

Upload to imgBB with two string params (legacy)

const imgbbUploader = require("imgbb-uploader");
/* or use import in ESM projects:
import { imgbbUploader } from "imgbb-uploader"; 
*/

imgbbUploader("your-imgbb-api-key-string", "path/to/your/image.png")
  .then((response) => console.log(response))
  .catch((error) => console.error(error));

.then((response) => console.log(response)) output example :

{
  id: '26Sy9tM',
  title: '5e7599f65f27',
  url_viewer: 'https://ibb.co/26Sy9tM',
  url: 'https://i.ibb.co/z5FrMR2/5e7599f65f27.png',
  display_url: 'https://i.ibb.co/z5FrMR2/5e7599f65f27.png',
  size: 260258,
  time: '1609336605',
  expiration: '0',
  image: {
    filename: '5e7599f65f27.png',
    name: '5e7599f65f27',
    mime: 'image/png',
    extension: 'png',
    url: 'https://i.ibb.co/z5FrMR2/5e7599f65f27.png'
  },
  thumb: {
    filename: '5e7599f65f27.png',
    name: '5e7599f65f27',
    mime: 'image/png',
    extension: 'png',
    url: 'https://i.ibb.co/26Sy9tM/5e7599f65f27.png'
  },
   medium: {
   filename: '5e7599f65f27.png',
    name: '5e7599f65f27',
    mime: 'image/png',
    extension: 'png',
    url: 'https://i.ibb.co/14kK0tt/5e7599f65f27.png'
  },
  delete_url: 'https://ibb.co/26Sy9tM/087a7edaaac26e1c940283df07d0b1d7'
}

Note about imgBB API: the medium Object will only be returned for .png and base64 files !

With options object (more features, yay! )

From version 1.2.0 onward, you can pass an options object as param.
Use it to customize filename and/or a set duration after which the image will be deleted, cf their docs.

The key you'll use for your image depends on its nature. One of these must be defined:

  • imagePath in case of a local file
  • imageUrl in case of an URL string
  • base64string in case of base64-encoded image
const imgbbUploader = require("imgbb-uploader");
/* or use import in ESM projects:
import { imgbbUploader } from "imgbb-uploader"; 
*/

const options = {
  apiKey: process.env.IMGBB_API_KEY, // MANDATORY

  imagePath: "./your/image/path", // OPTIONAL: pass a local file (max 32Mb)

  name: "yourCustomFilename", // OPTIONAL: pass a custom filename to imgBB API

  expiration: 3600 /* OPTIONAL: pass a numeric value in seconds.
  It must be in the 60-15552000 range.
  Enable this to force your image to be deleted after that time. */,

  imageUrl: "https://placekitten.com/500/500", // OPTIONAL: pass an URL to imgBB (max 32Mb)

  base64string:
    "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEklEQVR42mNcLVNbzwAEjDAGACcSA4kB6ARiAAAAAElFTkSuQmCC",
  // OPTIONAL: pass base64-encoded image (max 32Mb)
};

imgbbUploader(options)
  .then((response) => console.log(response))
  .catch((error) => console.error(error));

This module is tiny & totally unlicensed: to better fit your need, please fork away !
Basic instructions for tweaking

Another example: handling buffer with option object

const imgbbUploader = require("imgbb-uploader");

// Some buffer we need to upload
const data = "definitely-not-an-image-binary";

// Some promise of base64 data
const bufferToBase64 = (buffer) =>
  new Promise((resolve) => {
    const buff = new Buffer(buffer);
    const base64string = buff.toString("base64"); // https://nodejs.org/api/buffer.html#buftostringencoding-start-end
    return setTimeout(() => {
      resolve(base64string);
    }, 1000);
  });

// Some async function
const getDisplayUrl = async (buffer, name = "Default-filename") => {
  return await imgbbUploader({
    apiKey: "definitely-not-a-valid-key",
    base64string: await bufferToBase64(buffer),
    name,
  })
    .then((res) => {
      console.log(`Handle success: ${res.url}`);
      return res.url;
    })
    .catch((e) => {
      console.error(`Handle error: ${e}`);
      return "http://placekitten.com/300/300";
    });
};

const myUrl = getDisplayUrl(data, "Dolunay_Obruk-Sama_<3");

Working with directories/arrays

This module don't and won't directly support array uploads. Only you can pick the best solution for your usecase.
For example, to upload local directories of pictures, I enjoy working with fs.readdir.
I usually create an imagesDir.js file wherever it suits me:

module.exports = require("path").join(__dirname);

Then require that elsewhere and use path.join(imagesDir, relevantSubfolder) to dig into directories.
Once there, iterate using fs.readdir and forEach as needed.

If you need more inspiration Stack Overflow should have you covered!

Contributing

Issues & PRs are very welcome!
Get started with local development

CHANGELOG

changelog

1.5.1

1.5.0

ESM support 🚀

While trying to utilise the initial version of phraze module, a sudden realization shocked me. There are people out there who are writing pure ESM nodejs projects, and they do it as it is the most natural thing to do !!!

Despite having fairly painful memories of the UMD (universal module definition) / AMD (asyncronous module definition) / ESM (EcmaScript Modules) / CJS (CommonJS) jungle, I tried to give it another go.
Long story short, it's still far from obvious, but now things are a bit simpler that they once were. ESM seem to have won the heart of the many (in the frontend, it had mine already), on top of being anointed by the holy tc39 by definition.

The main difficulties I've encountered while working on ESM support were:

  • TS being bitchy about the export syntax. To be able to keep the "require" syntax everyone loves, I had to use a little hack
  • Tests duplication. There was no way I'd rewrite & maintain 30+ more tests. So I made an utility that write those tests for me, and that was very fun! 10/10 would write JS with JS again
    For the record, this is the 3rd iteration; before that I had a sweet (but hard to maintain) AWK version, then a glitchy awk-in-js one.
  • jest experimental ESM support. Had several back & forth with babel & ts-jest configs before having a working setup. Fortunately, the size of Jest community, and the quality of it's issue contributors, made it so I could find a working setup without having to dive into their source code. Thanks guys !

Ditch remap-istanbul

GitHub was very annoying flagging me for security issues about this thing absolutely no one interacts with besides me, but yeah. While I had to update Jest to support ESM, I took the chance to ditch it, and generate the coverage report with Jest. Cya remap-istanbul! 👋

1.4.0

Sorry for the wait! It was partially caused by a massive amount of yak shaving around Chevereto CI, like, writing a pure Docker stack, then switching to handmade docker-compose, then to remotely-hosted K(uwu)bernetes stack, all while knowing overall little about Docker & nothing about K(uwu)be

"TDD is a time gain, not a time loss", they said !!!

Well, maybe it's not wrong in the end. Afterall the back and forth allowed me to learn important things about TLS and networks and stuff. And there's no debate about the future developments/bugfixes being made easier!

Some other things that took time was hesitating on the interface. In the end I opted for something that felt balanced between TypeScript constraints, flexibility and ease of use.
I hope Chevereto users will like it, whatever the version they're using! Either way I'm all ears for feedback.

  • Switch from Travis CI to Github Actions

Travis CI today is far from the one I once knew and loved. No hard feelings, but I have to move away to a more OSS-friendly solution. I went with GitHub Actions. For my limited usage it feels like the old Travis: a free, easy to setup, pleasant to use automation solution.
Maybe one day I'll also automate the npm publish stuff with it, seems simple enough.

1.3.5

  • Remove useless dependencies
    I don't know how eslint stuff came here oO

1.3.4

  • Better error handling
    This issue made me realize how wrong was my error handling. Now checking for response.error and returning it if defined. No more "faulty payload" generic (& incorrect) error for imgBB API-related errors (like 'file too big' or 'invalid API key')!

  • Small fix: passing non-number to expiration param should throw a proper Error

  • Chore: npm audit fix to please secoority bots, even if I'm the only one concerned by devDeps and even if nothing had any chance of happening ^o^

  • Run tests in parallel: npm run dev run was too long
    To achieve concurrency I took the easy route of splitting the test suite into separate files. It's not DRY, not very clean (and GitHub will shame me by displaying more JavaScript % than TS) but I read enough bad stuff about Jest test.concurrent to prefer the reliable (and easy) route for now.
    npm run dev is still longer than ever thanks to absolutely inefficient src/__tests__/require/bigFileExplicitThrow.js relying on monkey-developed (thats harsh on monkeys) dependency, but I don't mind since the output of other tests comes faster.

  • Next milestones are: minimizing bundle size, and supporting chevereto-based APIs, hopefully before 2022 !

1.3.3

1.3.2

1.3.1

  • Updated responseObject interface
    Thanks for PR :)

  • While being at it, I had some fun with code coverage, tweaked some package.json scripts and gave a cleaner name to "rebuild.js".
    Intrigued about it, I tried Jest's built-in coverage report, but it pointed to ugly, transpiled JS. Saw two ways to fix this: a parallel Istanbul setup to handle it, or hacking around to make it work with Jest built-in tool. For funsies I took the latter route using remap-istanbul.
    Their readme says: We strongly encourage developers to leverage IstanbulJS, and only use this package (remap-istanbul) when needing to support legacy versions of Istanbul.
    In my case, it seem the Istanbul version in Jest's depencency graph is 0.x, so I opted to use their module for now and leave in-depth Istanbul for later.
    Note: node kept complaning about undefined "VERSION" and circular dependency while running npm run remap, so I ended using --no-warnings flag for it. If curious, feel free to make it --trace-warnings in package.json ;). In the end, it allows to generate two HTML coverage reports after a test pass, one for transpiled code (./coverage/lcov-report), one for source (./coverage/ts-report).

    • Increased code coverage: 98.46% statements covered. Tests will never enter the ".on('error', () => )" callback in the POST function, but I'll feel safer leaving that block. It's not like it's hurting anybody anyway ^o^

    • Updated CONTRIBUTING to reflect that.

1.3.0

Issue #6 brought an interesting feature idea. Took a bit of time because I first had to adapt the module used by the tests (waifu-generator owo).

Everything seem to work as intended.

Took the opportunity to reduce insanity within test code. Not perfect, but still less horrible than before.

Finally, I'm abandoning the idea of making this frontend-compatible some day. I don't want to endorse terrorism, and it's definitely not reasonable to encourage people to throw API keys into their frontends (even free API key - remember this module will stop working the day imgBB stop providing their service).

What I could do, aside writing this in the README, is perhaps redirecting to a working HTML/JS or React snippet, so people looking for a quick solution without any regard for security (for POC/hackathon/pet project) could gain some time.

1.2.0

While issues #3 and #4 were closed by users, they still needed to be adressed.

It's now possible to pass 'expiration' and 'name' params to imgBB API through an options object.

Also, the design of the test was terribly, terribly wrong (I always upload the same file, but imgBB API, by checksum or something, is able to tell, thus always returns my original upload as response. I didn't noticed until toying with name & expiration params, but the test were little more than dead code).

Fixed by making each test generate a random image (wrote another module for that), enabling proper testing for the new option object, & overall increased sanity.

Took the opportunity to write a few more tests; not nearly as rigorous as they should be, but still better than the imgBB API ping of old.

1.1.0

Module overhaul:
Seeing some people found this module useful made me glad, so I decided to give it some love.

  • Becomes dependency-free
    The respectable request module was the only external dependency, but now that's unsupported, as npm install spams everytime, it's problematic.
    While I could have replaced it with Axios, I preferred reinventing that wheel using standard node https. It should hold for the years to come.

  • TypeScript support
    TypeScript is all the rage and I'm still in the process of learning it. That's why I thought it was interesting to make this module TS compatible, without breaking compatibility for the require(); users.

  • Better integration for VSCode
    I've discovered JSDoc since then. It should benefit even non-TypeScript users.

  • Change code style I have semi colons everywhere except in this little module. Fixed that. Long live semi colons :)

  • Upgraded file architecture & CI
    This is the resource that guided me through the TS/Jest stack, it was an interesting adventure.
    I made my best to ensure this update won't break anything for you, but if it is the case, please open an issue :)

Todo:
Write more in CONTRIBUTING.md so this module remains easy to fork & tweak. It may look more bloated than before, but I'm convinced decent documentation should fix it.

Making .mjs import work. Hopefully soon
Supporting browsers (afterall why not)
Supporting passing filename parameter
Supporting arrays (in the very bottom of the list tbh)

1.0.1

Fix README

1.0.0

Replace var and function with proper ES6 syntax & update README