JSPM

  • Created
  • Published
  • Downloads 910
  • Score
    100M100P100Q105929F
  • License MIT

Turn any field on your Lucid model to an attachment data type

Package Exports

  • @jrmc/adonis-attachment
  • @jrmc/adonis-attachment/attachment_provider
  • @jrmc/adonis-attachment/converters/autodetect_converter
  • @jrmc/adonis-attachment/converters/converter
  • @jrmc/adonis-attachment/converters/document_converter
  • @jrmc/adonis-attachment/converters/image_converter
  • @jrmc/adonis-attachment/converters/pdf_converter
  • @jrmc/adonis-attachment/converters/video_thumbnail_converter
  • @jrmc/adonis-attachment/decorators
  • @jrmc/adonis-attachment/mixins
  • @jrmc/adonis-attachment/services/main
  • @jrmc/adonis-attachment/types/attachment
  • @jrmc/adonis-attachment/types/config
  • @jrmc/adonis-attachment/types/converter
  • @jrmc/adonis-attachment/types/input
  • @jrmc/adonis-attachment/types/mixin

Readme

AdonisJS attachment

This package is currently development and will replace attachment-advanced for AdonisJS 6.

Project sample : adonis-starter-kit

Roadmap

  • attachment file by file system
  • save meta data
  • variantes
    • images
    • documents thumbnail
    • videos thumbnail
  • command regenerate
  • adonis-drive/flydrive
  • jobs queue
  • edge component
  • serialize

File sytem

Upload file in public folder.

Meta data list (if available)

  • extension name
  • size
  • dimension (width, height)
  • created date
  • orientation
  • mime type
  • gps

Variants

Configure differents images sizes and formats

Regenerate (coming soon)

Regenerate variantes files

Drive (coming soon)

Use drive for private file and cloud services

Jobs queue (coming soon)

Couple with a job queue (recommended, optional)

Setup

Install and configure the package:

node ace add @jrmc/adonis-attachment

Or:

npm i @jrmc/adonis-attachment
node ace configure @jrmc/adonis-attachment

Usage

Often times, the size of the image metadata could exceed the allowable length of an SQL String data type. So, it is recommended to create/modify the column which will hold the metadata to use a JSON data type.

If you are creating the column for the first time, make sure that you use the JSON data type. Example:

  // Within the migration file

  protected tableName = 'users'

  public async up() {
    this.schema.createTable(this.tableName, (table) => {
      table.increments()
      table.json('avatar') // <-- Use a JSON data type
    })
  }

If you already have a column for storing image paths/URLs, you need to create a new migration and alter the column definition to a JSON data type. Example:

# Create a new migration file
node ace make:migration change_avatar_column_to_json --table=users
  // Within the migration file

  protected tableName = 'users'

  public async up() {
    this.schema.alterTable(this.tableName, (table) => {
      table.json('avatar').alter() // <-- Alter the column definition
    })
  }

Next, in the model, import the attachment decorator, Attachmentable mixin and the Attachment type from the package.

Make sure NOT to use the @column decorator when using the @attachment decorator.

import { BaseModel } from '@adonisjs/lucid/orm'
import { compose } from '@adonisjs/core/helpers'
import { attachment, Attachmentable } from '@jrmc/adonis-attachment'
import type { Attachment } from '@jrmc/adonis-attachment/types/attachment'

class User extends compose(BaseModel, Attachmentable) {
  @attachment()
  declare avatar: Attachment
}

Now you can create an attachment from the user uploaded file as follows.

import { attachmentManager } from '@jrmc/adonis-attachment'

class UsersController {
  public store({ request }: HttpContext) {
    const avatar = request.file('avatar')!
    const user = new User()

    user.avatar = await attachmentManager.createFromFile(avatar)
    // user.avatar = await attachmentManager.createFromBuffer(buffer, 'photo.jpg')
    await user.save()
  }
}

Specifying subfolder

You can also store files inside the subfolder by defining the folder property as follows.

class User extends BaseModel {
  @attachment({ folder: 'uploads/avatars' })
  declare avatar: Attachment
}

Specifying variants

It is possible to limit the variants on an attachment

class User extends BaseModel {
  @attachment({
    variants: ['thumbnail', 'medium', 'large']
  })
  declare avatar: Attachment
}

URLs

user.avatar.getUrl()
user.avatar.getUrl('thumbnail')
// or await user.avatar.getVariant('thumbnail').getUrl()
<img src="{{ user.avatar.getUrl('thumbnail') }}" loading="lazy" alt="" />

by serialize

user.avatar.toJSON()
<img :src="user.avatar.thumbnail" loading="lazy" alt="" />

Configuration

Configuration for variants files (config/attachment.ts)

import { defineConfig } from '@jrmc/adonis-attachment'
import app from '@adonisjs/core/services/app'
import sharp from 'sharp'

export default defineConfig({
  basePath: app.publicPath(),
  converters: [
    {
      key: 'thumbnail',
      converter: () => import('@jrmc/adonis-attachment/converters/image_converter'),
      options: {
        resize: 300,
        format: 'webp',
      }
    },
    {
      key: 'medium',
      converter: () => import('@jrmc/adonis-attachment/converters/image_converter'),
      options: {
        format: 'jpeg',
        resize: { // https://sharp.pixelplumbing.com/api-resize
          width: 400,
          height: 400,
          fit: sharp.fit.cover,
          position: 'top'
        },
      }
    },
    {
      key: 'large',
      converter: () => import('@jrmc/adonis-attachment/converters/image_converter'),
      options: {
        resize: 1024,
        format: {
          format: 'png',
          options: {
            quality: 80
          }
        }

      }
    },
    {
      key: 'preview',
      converter: () => import('@jrmc/adonis-attachment/converters/video_thumbnail_converter'),
      options: {
        format: 'jpeg',
        resize: 720
      }
    },
  ]
})

Variants images are generates by sharp module

Options resize is number or object(options) details in documentation : sharp api resize

Options format is string or object [ format, options ] details in documentation : sharp api outpout

npm install sharp

Variants thumbnail videos are generate by fluent-ffmpeg By default, image format is PNG and size is video size. options attribute use image_converter (and sharp)

npm install fluent-ffmpeg