@adonisjs/attachment-lite

中文文档
1.0.8发布于 2023/09/22MITTypeScriptCommonJS近 30 天下载 2279

将您 Lucid 模型上的任何字段转换为附件数据类型

中文使用文档
文档目录14 节
  1. 怎么样?
  2. 特征
  3. 先决条件
  4. 设置
  5. 使用量
  6. 处理更新
  7. 处理删除
  8. 指定磁盘
  9. 指定子文件夹
  10. 正在生成 URL
  11. 生成 API 响应的 URL
  12. 预计算 URL
  13. 按要求预先计算
  14. 与模范工厂使用附件升

附件字节


github-actions-image npm-image license-image typescript-image

一个简单,有意见的软件包,可以将您 Lucid 模型上的任何一栏转换为附件数据类型.

附件列表允许您在数据库中存储用户上传文件的引用 。 它不需要任何额外的数据库表格,并将文件元数据作为JSON存储在同一列.

怎么样?

这个 attachment-lite 软件包是 媒体图书馆办法的替代办法我相信媒体库在创建CMS时是很棒的.

然而,许多应用如SAAS产品或社区论坛不需要媒体图书馆.

例如,Twitter或dev.to等网站没有媒体库部分,用于上传和选择图片. 相反,这些平台上的图像与资源紧密结合.

当你在Twitter上更新你的配置图像时,旧的图像会消失,而新的图像会出现. 没有图像的中央画廊可以选择配置图片.

一个很长的故事告诉你 attachment-lite 软件包是管理应用程序中一次性文件上传的绝佳解决方案.

特征

  • 将数据库中的任何一栏转换为附件数据类型.
  • 不需要额外的数据库表格。 文件元数据作为JSON存储在同一列内.
  • 当指定新文件时,将自动从磁盘上删除旧文件.
  • 优雅地处理失败案件。 如果模型无法持续, 将不存储文件 .
  • 同样,如果模型在更新过程中无法持续或删除失败,则不会删除旧文件.

先决条件

这个 attachment-lite 需要软件包 @adonisjs/lucid >= v16.3.1 财务报告和审定财务报表 @adonisjs/core >= 5.3.4。 。 。 .

而且,它依赖于 AdonisJS 驱动器 用于在磁盘上写入文件.

设置

从 npm 登记册中安装软件包如下 .

npm i @adonisjs/attachment-lite

接下来,通过运行以下 A 命令来配置软件包.

node ace configure @adonisjs/attachment-lite

使用量

图像元数据大小往往会超过允许的 SQL 长度 String 数据类型。 因此,建议创建/修改将保留元数据的列,以便使用 JSON 数据类型.

如果您是第一次创建列, 请务必使用 JSON 数据类型 。 示例

  // 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
    })
  }

如果您已经拥有存储图像路径/ URL 的列, 您需要创建新的迁移并更改列定义为 JSON 数据类型 。 示例

# 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
    })
  }

接下来,在模型中导入 attachment 装饰者和 AttachmentContract 界面.

确定不要使用 @column 使用时的装饰符 @attachment 装饰师.

import { BaseModel } from '@ioc:Adonis/Lucid/Orm'
import {
  attachment,
  AttachmentContract
} from '@ioc:Adonis/Addons/AttachmentLite'

class User extends BaseModel {
  @attachment()
  public avatar: AttachmentContract
}

现在可以从用户上传文件创建附件如下 .

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()
  }
}

这个 Attachment.fromFile 从用户上传文件创建附件类实例 。 当将模型坚持到数据库时,附件-lite会将文件写入磁盘.

处理更新

您可以用新上传的用户文件来更新属性, 包将注意去掉旧文件并存储新文件.

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

class UsersController {
  public update({ request }: HttpContextContract) {
    const user = await User.firstOrFail()
    const avatar = request.file('avatar')!

    user.avatar = Attachment.fromFile(avatar)

    // Old file will be removed from the disk as well.
    await user.save()
  }
}

同样,指定 null 要删除文件,而不指定新文件的模型属性值.

另外,确保您更新模型上的属性类型 null 还有.

class User extends BaseModel {
  @attachment()
  public avatar: AttachmentContract | null
}
const user = await User.first()
user.avatar = null

// Removes the file from the disk
await user.save()

处理删除

在删除模型实例后,所有相关附件都会从磁盘中被移除.

注意: 要删除文件, 需要使用附件列表 modelInstance.delete 方法。 使用 delete 。查询构建器将无法工作.

const user = await User.first()

// Removes any attachments related to this user
await user.delete()

指定磁盘

默认情况下,所有文件都会从默认磁盘中写入/删除. 然而,您可以在使用自定义磁盘时指定 attachment 装饰师.

这个 disk 属性价值从未持续到数据库。 这意味着,如果你首先定义磁盘为 s3,上传一些文件,然后将磁盘值更改为 gcs,软件包将使用 gcs 磁盘.

class User extends BaseModel {
  @attachment({ disk: 's3' })
  public avatar: AttachmentContract
}

指定子文件夹

您也可以通过定义 folder 财产如下.

class User extends BaseModel {
  @attachment({ folder: 'avatars' })
  public avatar: AttachmentContract
}

正在生成 URL

您可以使用该附件生成给定附件的 URL getUrl 或者说 getSignedUrl 方法。 。 。 它们与 驱动方法,只是不需要指定文件名.

await user.avatar.getSignedUrl({ expiresIn: '30mins' })

生成 API 响应的 URL

Drive API生成URL的方法是同步的,而将一个模型序列化到JSON则是同步的. 因此,不是在序列化一个模型时创建URL.

// ❌ Does not work

const users = await User.all()
users.map((user) => {
  user.avatar.url = await user.avatar.getSignedUrl()
  return user
})

要处理此使用大小写, 您可以选择预计算 URL

预计算 URL

启用 preComputeUrl 在 SELECT 查询后预先计算 URL的旗帜。 例如:

class User extends BaseModel {
  @attachment({ preComputeUrl: true })
  public avatar: AttachmentContract
}

获取结果

const users = await User.all()
users[0].avatar.url // pre computed already 

查找结果

const user = await User.findOrFail(1)
user.avatar.url // pre computed already 

接地结果

const users = await User.query.paginate(1)
users[0].avatar.url // pre computed already 

这个 preComputeUrl 属性将生成 URL并设置在附件类实例上。 另外,当磁盘是 私营,当磁盘是 公开。 。 。 .

按要求预先计算

我们建议不要允许 preComputeUrl 选项,当您只需要一个或两个查询而不能在应用程序的其余部分使用URL时.

对于这些查询,您可以手动计算控制器内的URL. 这里有一个小的帮助方法,你可以直接在模型上放入.

class User extends BaseModel {
  public static async preComputeUrls(models: User | User[]) {
    if (Array.isArray(models)) {
      await Promise.all(models.map((model) => this.preComputeUrls(model)))
      return
    }

    await models.avatar?.computeUrl()
    await models.coverImage?.computeUrl()
  }
}

现用如下.

const users = await User.all()
await User.preComputeUrls(users)

return users

或者一个用户

const user = await User.findOrFail(1)
await User.preComputeUrls(user)

return user

与模范工厂使用附件升

附件 lite 首选使用多部分请求机构来坚持用户上传文件. 然而,你也可以构建一个实例: Attachment 手动分类并使用 AdonisJS 驱动器来粘住相应的文件.

在下面的例子中,我们创建了一个附件类的例子来代表邮报封面图像.

import Post from 'App/Models/Post'
import Drive from '@ioc:Adonis/Core/Drive'
import { file } from '@ioc:Adonis/Core/Helpers'
import Factory from '@ioc:Adonis/Lucid/Factory'
import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'

export default Factory.define(Post, async ({ faker }) => {
  /**
   * Step 1: Create an instance of attachment
   */
  const coverImage = new Attachment({
    extname: 'png',
    mimeType: 'image/png',
    size: 10 * 1000,
    name: `${faker.random.alphaNumeric(10)}.png`,
  })

  /**
   * Step 2: Mark image as persisted, this will disable the
   * functions of attachment lite that looks for multipart
   * body and attempts to write the file from the stream
   */
  coverImage.isPersisted = true

  /**
   * Step 3: Persist the file using Drive.
   */
  await Drive.put(coverImage.name, (await file.generatePng('1mb')).contents)

  return {
    title: faker.lorem.words(5),
    coverImage: coverImage,
  }
}).build()

版本与发布记录

@adonisjs/attachment-lite 共发布 9 个版本,首次发布于 2021/10/01;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.0.8latest2023/09/223 年前
1.0.72022/05/274 年前
1.0.62022/05/184 年前
1.0.52022/05/114 年前
1.0.42022/04/104 年前
1.0.32022/04/094 年前

关于 @adonisjs/attachment-lite 的常见问题

@adonisjs/attachment-lite 是什么?

将您 Lucid 模型上的任何字段转换为附件数据类型

如何安装 @adonisjs/attachment-lite?

在项目目录运行 npm install @adonisjs/attachment-lite,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@adonisjs/core(^5.3.0)、@adonisjs/lucid(^17.0.0 || ^18.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@adonisjs/attachment-lite 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@adonisjs/attachment-lite 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@adonisjs/attachment-lite 可以商用吗?

@adonisjs/attachment-lite 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@adonisjs/attachment-lite 的下载量有多少?

根据 npm 官方下载统计,@adonisjs/attachment-lite 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,279 次,日均约 76 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adonisjs/attachment-lite 还在维护吗?

最新版本 1.0.8 发布于 2023/09/22(3 年前);至今共发布 9 个版本,其中过去 12 个月发布了 0 个;首次发布于 2021/10/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。