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

@rikology/adonisjs-cloudinary

v0.4.0

Published

Cloudinary integration for AdonisJS v7 — upload, transform, and deliver media through the Cloudinary v2 SDK, with IoC container support, Edge helpers, and an optional FlyDrive bridge.

Downloads

530

Readme

@rikology/adonisjs-cloudinary

License: MIT AdonisJS v7

Cloudinary integration for AdonisJS v7 — upload, transform, and deliver media through the Cloudinary v2 SDK, with first-class IoC container support, Edge templating helpers, and an optional FlyDrive bridge.

Features

  • 🚀 Typed service wrapping the Cloudinary v2 SDK, injectable anywhere via the IoC container
  • 📸 Upload helpers for images, video, and raw files with a single call
  • 🎨 URL transformations generated synchronously, including in Edge templates
  • 🔐 Signed/expiring URLs with Date or Unix-timestamp expiration
  • 🗄️ Optional FlyDrive bridge to use Cloudinary as a Drive disk
  • 🧩 Zero-config Edge helper that registers itself when Edge is installed (and stays out of the way in API-only apps)
  • 📦 Standalone helpers for scripts, workers, and non-AdonisJS projects
  • 🩺 cloudinary:ping ace command to verify your credentials right after install

Documentation

| Topic | Document | | --- | --- | | Install, configure, first upload | Getting Started | | defineConfig, config types, container binding | Configuration | | Full CloudinaryService method reference | Service API | | The cloudinaryUrl Edge global | Edge Helpers | | Using Cloudinary as a FlyDrive disk | Drive Bridge | | Scripts, workers, non-AdonisJS usage | Standalone Helpers | | Raw SDK, Admin/Search API, presets, multi-account | Advanced | | Avatars, galleries, signed URLs, cleanup | Recipes |

Installation

node ace add @rikology/adonisjs-cloudinary

That single command installs the package, publishes config/cloudinary.ts, registers the CloudinaryProvider and the cloudinary:* ace commands in adonisrc.ts, and wires env validation for your CLOUDINARY_* keys.

Prefer the manual route?

# install
npm install @rikology/adonisjs-cloudinary # or: pnpm/yarn/bun add

# then configure
node ace configure @rikology/adonisjs-cloudinary

Verify your credentials are wired up:

node ace cloudinary:ping

Environment variables

Add these to your .env (values from the Cloudinary console):

| Variable | Required | Description | | ----------------------- | -------- | -------------------------- | | CLOUDINARY_CLOUD_NAME | Yes | Your Cloudinary cloud name | | CLOUDINARY_API_KEY | Yes | Your Cloudinary API key | | CLOUDINARY_API_SECRET | Yes | Your Cloudinary API secret |

node ace add / configure auto-registers these in your env validator (start/env.ts). The entry it adds looks like:

import { Env } from '@adonisjs/core/env'

export default await Env.create(new URL('../', import.meta.url), {
  CLOUDINARY_CLOUD_NAME: Env.schema.string(),
  CLOUDINARY_API_KEY: Env.schema.string(),
  CLOUDINARY_API_SECRET: Env.schema.string(),
})

Quick start

Inject the service and upload:

import { inject } from '@adonisjs/core'
import type { CloudinaryService } from '@rikology/adonisjs-cloudinary'

@inject()
export default class UploadsController {
  constructor(protected cloudinary: CloudinaryService) {}

  async store({ request, response }) {
    const file = request.file('avatar')!

    const result = await this.cloudinary.uploadImage(file.tmpPath!, {
      folder: 'avatars',
      transformation: { width: 200, height: 200, crop: 'fill' },
    })

    return response.ok({ url: result.secure_url, publicId: result.public_id })
  }
}

Render a transformed URL in Edge (the cloudinaryUrl global registers itself automatically):

<img
  src="{{ cloudinaryUrl('avatars/photo', { width: 200, height: 200, crop: 'fill' }) }}"
  alt="Avatar"
/>

Service API (summary)

The CloudinaryService is bound to the container as cloudinary. Full reference: Service API.

| Method | Description | | ------------------------------------------ | ----------------------------------------------------- | | sdk | Raw cloudinary v2 object for direct SDK calls | | uploadImage(file, options?) | Upload with resource_type: 'image' | | uploadVideo(file, options?) | Upload with resource_type: 'video' | | uploadFile(file, options?) | Upload with resource_type: 'raw' | | transformUrl(publicId, transformations?) | Generate a delivery URL with optional transformations | | signedUrl(publicId, options?) | Generate a signed URL, optionally with expiresAt | | uploadStream(options?) | Return a cloudinary.uploader.upload_stream() stream | | destroy(publicId, options?) | Delete an asset (defaults resource_type: 'image') |

// Signed URL expiring in 1 hour
const url = cloudinary.signedUrl('private-doc', {
  expiresAt: Date.now() / 1000 + 3600,
})

For scripts and workers without the container:

import { createCloudinaryService, transformUrl } from '@rikology/adonisjs-cloudinary'

const cloudinary = createCloudinaryService({
  cloudName: 'demo',
  apiKey: '123456',
  apiSecret: 'secret',
})

const url = transformUrl('my-image', { cloudName: 'demo', apiKey: 'k', apiSecret: 's' }, { width: 200 })

See Standalone Helpers.

Drive bridge

An optional FlyDrive driver maps Drive operations onto Cloudinary API calls. It's imported from the /drive subpath so it never loads unless you use it:

import { CloudinaryDrive } from '@rikology/adonisjs-cloudinary/drive'
import { createCloudinaryService } from '@rikology/adonisjs-cloudinary'

const cloudinary = createCloudinaryService({
  cloudName: env.get('CLOUDINARY_CLOUD_NAME'),
  apiKey: env.get('CLOUDINARY_API_KEY'),
  apiSecret: env.get('CLOUDINARY_API_SECRET'),
})

const driveConfig = defineConfig({
  default: 'cloudinary',
  services: {
    cloudinary: () => new CloudinaryDrive(cloudinary),
  },
})

Requires the optional flydrive (or @adonisjs/drive) peer dependency. Cloudinary is a media platform, not a byte-level object store — see the Drive Bridge guide for supported/unsupported operations.

Advanced

Need something the wrappers don't cover? The raw SDK is one property away:

const cloudinary = await app.container.make('cloudinary')

// Admin API
await cloudinary.sdk.api.resources({ type: 'upload', prefix: 'avatars/', max_results: 50 })

// Search API
await cloudinary.sdk.search
  .expression('resource_type:image AND tags=featured')
  .sort_by('created_at', 'desc')
  .max_results(30)
  .execute()

// Upload presets
await cloudinary.sdk.uploader.upload(file, { upload_preset: 'my-preset' })

See Advanced for Admin/Search API patterns, upload presets, multi-account strategies, and testing.

Contributing

See CONTRIBUTING.md. Contributions, issues, and feature requests are welcome.

License

MIT © Riko Riswandha Fahmi Prasetyo