Git Product home page Git Product logo

attachment-lite's People

Contributors

hbatalhastch avatar justdare avatar ndianabasi avatar romainlanz avatar thetutlage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

attachment-lite's Issues

Allow creation of attachments outside the context of a file sent via HTTP request

Why this feature is required (specific use-cases will be appreciated)?

Many apps manage files that come from other sources than an HTTP request, for example an app might create invoices in a scheduled task, or process videos in a background job. And currently Attachment.fromFile() requires a MultipartFileContract file to be passed in, which currently can only be obtained by using request.file or request.files which of course are available only in HTTP requests, if we could pass a NodeJS Buffer, or create an object compatible with MultipartFileContract from a Buffer, this would be solved

Have you tried any other work arounds?

Yes, currently it's possible to do this by creating the file manually using Adonis Drive and creating the attachment using Attachment.fromDbResponse with a fake db response object.

Are you willing to work on it with little guidance?

Yes

Files in temp folder are not deleted after uploading to S3.

File is not deleted after uploading to S3. The uploaded files are also stored in the temp folder.

Package version

1.0.4

Node.js and npm version

Nodejs - v14.18.1
npm - 6.14.15

Sample Code (to reproduce the issue)

Use S3 as disk and upload a file. The same file will exist in the temp folder .

Ability to override serialize, prepare and consume options on attachment decorator

At the moment it is impossible to override the following column options on the attachment decorator: serialize, prepare and consume.

I've found the code where the options are configured here:
Screen Shot 2023-01-18 at 1 02 19 PM

I think the column options should take priority in the spread so we may override them if we choose.

Why this feature is required (specific use-cases will be appreciated)?

Ability to override serialize, prepare and consume options on the attachment() decorator for more advances serialization cases (ie. omit or not based on model $sideloaded values).

Have you tried any other work arounds?

No it is impossible to use custom serialize, prepare and consume options on the attachment() decorator as of right now.

Are you willing to work on it with little guidance?

Absolutely. Easy change.

preComputeUrl is giving out wrong URL

Package version

1.0.7 and 1.0.8

Node.js and npm version

Node.js version = 18.12.0
npm version = 8.19.2

Sample Code (to reproduce the issue)

@attachment({ disk: 's3', folder: 'profiles', preComputeUrl: true })
public avatar?: AttachmentContract | null

Problem

The preComputeUrl is giving out the url like this - "https://endpoint/bucket,fileName".
The URL is missing "/" between the bucket name and fileName.
I am sorry if the format is wrong.

Pre-signed URL saved on model expired

Package version

"@adonisjs/attachment-lite": "^1.0.4",

Node.js and npm version

Nodejs - v14.18.1
npm - 6.14.15

I'm using with preComputedUrl on private s3 disk to get signed url. The problem is that when a new model is created, the pre-signed url will be saved into the model.
Because of the expiry on pre-signed url, the url is no longer valid on next access. Is there a way to refresh pre-signed url.
Is it intended behavior or am I doing wrong.
Thanks.

Model `save` function does not return the model anymore

When a model contains the attachment decorator the save function of the model internally calls the saveWithAttachments function of the decorator and returns undefined instead of Promise<Model>.

Package version

v1.0.7

Node.js and npm version

Node.js: v18.15.0
npm: v9.5.0

Sample Code (to reproduce the issue)

Add the attachment decorator to a model.

attachementLite.setOptions should override @attachment options

Why this feature is required (specific use-cases will be appreciated)?

Sometimes you want to set disk/folder options for an attachment on the fly. For example, here I'm setting the folder option based on key, refId & entity

import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'
import { AuthContract } from '@ioc:Adonis/Addons/Auth'
import { TransactionClientContract } from '@ioc:Adonis/Lucid/Database'
import Entity from 'App/Models/System/Entity'
import Media from 'App/Models/System/Media'
import StoreMediaValidator from 'App/Validators/System/StoreMediaValidator'
import Env from '@ioc:Adonis/Core/Env'

export default class StoreMedia {
  public static async handle(
    { file, key, refId, entity }: StoreMediaValidator['schema']['props'],
    auth: AuthContract,
    client?: TransactionClientContract
  ) {
    const folder = `${Env.get('NODE_ENV')}/${entity}/${refId}/${key}`
    return await Media.create(
      {
        file: Attachment.fromFile(file).setOptions({ folder }),
        key,
        refId,
        entity: Entity[entity],
        createdBy: auth.user?.id
      },
      { client }
    )
  }
}

In this case the folder defaults to the one specified on the @attachment decorator in my Media model.

Have you tried any other work arounds?

Yes, I tried Attachment.fromFile(file).setOptions({ folder }).save() which uploads to the correct folder but I could not retrieve the correct path in order to persist it in the DB.

Are you willing to work on it with little guidance?

Yes, of course. Happy to take this on ๐Ÿ˜Š

Pre compute URL with expiresIn option.

Why this feature is required (specific use-cases will be appreciated)?

Currently we cannot set custom expire time for signed url with preCompute option. Is it possible to add expiresIn option when using pre computed url.

Have you tried any other work arounds?

Not yet.

Are you willing to work on it with little guidance?

Yes.

Unavoidable errors when DB response is `null`

Prerequisites

I've noticed a persistent and unavoidable error when DB response is null. In a typical usage of the addon, not all attachment column will return the expected format which is parse-able by the add-on. Some columns will contain null values. The add-on current fails when null values are encountered.

The issue can be traced to these lines:

const attributes = typeof response === 'string' ? JSON.parse(response) : response
/**
* Validate the db response
*/
REQUIRED_ATTRIBUTES.forEach((attribute) => {
if (attributes[attribute] === undefined) {
throw new Exception(
`Cannot create attachment from database response. Missing attribute "${attribute}"`
)
}
})

When attributes is null, the Array.forEach call fails. A suggestion is for the add-on to provide a no-op when null is encountered.

Package version

1.0.1

Node.js and npm version

Node: 14.18.2. NPM: 6.14.15

Sample Code (to reproduce the issue)

const attributes = typeof response === 'string' ? JSON.parse(response) : response
/**
* Validate the db response
*/
REQUIRED_ATTRIBUTES.forEach((attribute) => {
if (attributes[attribute] === undefined) {
throw new Exception(
`Cannot create attachment from database response. Missing attribute "${attribute}"`
)
}
})

BONUS (a sample repo to reproduce the issue)

`computeUrl` function not working without `preComputeUrl` config set

The README states that I can use the computeUrl function to compute URL on demand. This does not work however because the function only computes the URL when the preComputeUrl config is set.

Package version

v1.0.7

Node.js and npm version

Node.js: v18.15.0
npm: v9.5.0

Sample Code (to reproduce the issue)

DO NOT set the preComputeUrl property on the decorator config and use the computeUrl function.
The URL is not set on the attachment.

Error: existingFile.setOptions is not a function

Package version

1.0.7

Node.js and npm version

v20.5.1

Sample Code (to reproduce the issue)

import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'

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

    user.avatar = Attachment.fromFile(avatar)
    await user.save()
  }
}

BONUS (a sample repo to reproduce the issue)

[07:43:22.223] ERROR (adonis/941667): existingFile.setOptions is not a function
    err: {
      "type": "TypeError",
      "message": "existingFile.setOptions is not a function",
      "stack":
          TypeError: existingFile.setOptions is not a function
              at persistAttachment (/xxx/adonis/node_modules/@adonisjs/attachment-lite/build/src/Attachment/decorator.js:45:26)
              at /xxx/adonis/node_modules/@adonisjs/attachment-lite/build/src/Attachment/decorator.js:83:80
              at Array.map (<anonymous>)
              at Proxy.saveWithAttachments (/xxx/adonis/node_modules/@adonisjs/attachment-lite/build/src/Attachment/decorator.js:83:55)
              at UserController.avatar (/xxx/adonis/app/Controllers/UserController.ts:128:23)
              at processTicksAndRejections (node:internal/process/task_queues:95:5)
              at Object.PreCompiler.runRouteHandler [as fn] (/xxx/adonis/node_modules/@adonisjs/http-server/build/src/Server/PreCompiler/index.js:47:31)
              at AuthMiddleware.handle (/xxx/adonis/app/Middleware/Auth.ts:76:5)
              at SilentAuthMiddleware.handle (/xxx/adonis/app/Middleware/SilentAuth.ts:19:5)
              at Server.handleRequest (/xxx/adonis/node_modules/@adonisjs/http-server/build/src/Server/index.js:108:13)
      "status": 500
    }

Pre compute on demand not work

Following the README:
[...] We recommend not enabling the preComputeUrl option when you need the URL for just one or two queries and not within the rest of your application. [...]

But, in file Attachment/index.ts on line 233, the computeUrl() mehtod return nothing if the options.preComputeUrl is undefined or false

if (!this.options?.preComputeUrl) {
return
}

Package version

1.0.7

Node.js and npm version

node: v14.18.2
npm: 6.14.15

Sample Code (to reproduce the issue)

Same code of README

Is there a way to rename saved files?

Would be nice to specify names/prefixes for uploaded images.

Something like this

data.avatar = Attachment.fromFile(avatar, {name: new Date().getTime() + '-avatar'} );

Attachment's name is undefined

Whenever I make an attachment from an uploaded file the name is always undefined, which causes an error on getUrl() and likely other methods. From what I can tell in the code the fromFile method never sets the name?

Package version

1.0.7

Node.js and npm version

v18.16.0 and 9.5.1

Sample Code (to reproduce the issue)

const att = Attachment.fromFile(someFile);

console.log(att.name); // undefined

console.log(att.getUrl()); // error

Image conversion after uploading

Package version

1.0.7

Node.js and npm version

18.16.0, pnpm 8.2.0

Sample Code (to reproduce the issue)

Users often upload very large photos as avatars and we want to resize it and convert to webp to save storage space. However, Attachment only created from the MultipartFileContract that is directly from request. Even I override the file with converted webp, it still store file info of previous PNG/JPG.

const tempFile = await file();
await sharp(avatar.tmpPath).webp().toFile(tempFile.path);
await rename(tempFile.path, avatar.tmpPath);
auth.user!.avatar = Attachment.fromFile(avatar);

Is here a good practice to do image conversion with Attachment? Thanks!

BONUS (a sample repo to reproduce the issue)

How to use Factory with a model that implements Attachment Lite?

Hi there! I've been having trouble recently with using model factories because of how we can create Attachment objects.
I cannot create an Attachment object because:

  1. The image is not on the database
  2. I cannot create a MultipartFile object myself apparently

I'm wondering if there's any other way to create an Attachment object? ๐Ÿ˜ƒ If not, you could guide me on what I could PR to help fix this issue?
Thank you.

No mention on how to create column in database

Confusing for first time user to use the package since the documentation never mention anything about creating a column in migration for the model

It should mention to add a column in migration with the type json and example like the following

import BaseSchema from '@ioc:Adonis/Lucid/Schema'

export default class UsersSchema extends BaseSchema {
  protected tableName = 'users'

  public async up() {
    this.schema.createTable(this.tableName, (table) => {
      table.uuid('id').primary()
      table.string('email', 255).unique().notNullable()
      table.string('password', 180).notNullable()
      table.string('username', 32).unique().notNullable()
      table.string('remember_me_token').nullable()
      __table.json('avatar').nullable()__
      table.string('description', 255).nullable()

      /**
       * Uses timestampz for PostgreSQL and DATETIME2 for MSSQL
       */
      table.timestamp('created_at', { useTz: true }).notNullable()
      table.timestamp('updated_at', { useTz: true }).notNullable()
    })
  }

  public async down() {
    this.schema.dropTable(this.tableName)
  }
}

[Adonis Responsive Attachment] preComputeUrls dosn't work when using Database query

Package version

https://github.com/ndianabasi/adonis-responsive-attachment V 1.3.0

Node.js and npm version

Node version: v16.11.0
Npm version: 8.0.0

The error

When getting images from the databases, you can use Image.query() or Database.from(Image.table).

When using Database.from(Image.table), your SGBD return usable timestamp, so it can help to use this method. But, with version V 1.3.0 of this packages, the image's url dosn't compute when using Database.from(Image.table) as you can see below

Sample Code (to reproduce the issue)

Images models:

@responsiveAttachment({
    folder: 'images',
    preComputeUrls: true,
    breakpoints: {
      medium: 'off',
      large: 'off',
      thumbmail: 'off',
    },
  })
  public data: ResponsiveAttachmentContract

Query to fetch an image

  public async show({ params }: HttpContextContract) {
    const image = await Image.findOrFail(params.id)
    return image
  }

Return this result:

{
    "folder_id": 9,
    "id": 1000,
    "title": "IMG_7740.png",
    "data": {
        "name": "images/original_cl3od91bf000argxi5zmohrc5.png",
        "size": 23187.75,
        "hash": "cl3od91bf000argxi5zmohrc5",
        "width": 3861,
        "format": "png",
        "height": 2574,
        "extname": "png",
        "mimeType": "image/png",
        "breakpoints": {
            "thumbnail": {
                "name": "images/thumbnail_cl3od91bf000argxi5zmohrc5.png",
                "hash": "cl3od91bf000argxi5zmohrc5",
                "extname": "png",
                "mimeType": "image/png",
                "format": "png",
                "width": 234,
                "height": 156,
                "size": 96.57,
                "url": "/uploads/images/thumbnail_cl3od91bf000argxi5zmohrc5.png"
            },
            "small": {
                "name": "images/small_cl3od91bf000argxi5zmohrc5.png",
                "hash": "cl3od91bf000argxi5zmohrc5",
                "extname": "png",
                "mimeType": "image/png",
                "format": "png",
                "width": 500,
                "height": 333,
                "size": 428.04,
                "url": "/uploads/images/small_cl3od91bf000argxi5zmohrc5.png"
            }
        },
        "url": "/uploads/images/original_cl3od91bf000argxi5zmohrc5.png"
    },
    "raw": null,
    "created_at": "2022-05-27T13:33:58.194+02:00",
    "updated_at": "2022-05-27T13:33:58.194+02:00"
}

But if you're using this method to fetch from db:

  public async show({ params }: HttpContextContract) {
    const image = await Database.from(Image.table).where('id', params.id).first()    
    return image
  }

The result is:

{
    "folder_id": 9,
    "id": 1000,
    "title": "IMG_7740.png",
    "data": {
        "name": "images/original_cl3od91bf000argxi5zmohrc5.png",
        "size": 23187.75,
        "hash": "cl3od91bf000argxi5zmohrc5",
        "width": 3861,
        "format": "png",
        "height": 2574,
        "extname": "png",
        "mimeType": "image/png",
        "breakpoints": {
            "thumbnail": {
                "name": "images/thumbnail_cl3od91bf000argxi5zmohrc5.png",
                "hash": "cl3od91bf000argxi5zmohrc5",
                "extname": "png",
                "mimeType": "image/png",
                "format": "png",
                "width": 234,
                "height": 156,
                "size": 96.57
            },
            "small": {
                "name": "images/small_cl3od91bf000argxi5zmohrc5.png",
                "hash": "cl3od91bf000argxi5zmohrc5",
                "extname": "png",
                "mimeType": "image/png",
                "format": "png",
                "width": 500,
                "height": 333,
                "size": 428.04
            }
        }
    },
    "raw": null,
    "created_at": "2022-05-27T11:33:58.194Z",
    "updated_at": "2022-05-27T11:33:58.194Z"
}

There is no URL, and the timestamp are TZ

I'm really sorry if this is normal, but, it worked on previous version 1.2.2 so i thought something happened since then

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.