如何在 Sanity 中验证上传图像的尺寸?

How can I validate the dimensions of an uploaded image in Sanity?

我在 Sanity (docs) 中有一个 image 类型字段,我需要确保尺寸在特定范围内以避免破坏他们正在访问的网站。 Sanity 提供验证,但图像类型只有“必需”和“自定义”规则,并且传递到自定义验证器的字段信息不包括图像元数据。

如何解决此限制并提供尺寸的 CMS 内验证?

虽然 Sanity 不会将图像元数据传递到验证器,但您可以从提供的资产 ID 中提取图像格式和尺寸信息。根据 this documentation,这是一种受支持且稳定的访问此信息的方式,无需从 Sanity 加载图像对象。

例如,这是传递给 Rule.custom 验证器的第一个参数:

{
  "_type": "image",
  "alt": "Example Image",
  "asset": {
    "_ref": "image-bff149a0b87f5b0e00d9dd364e9ddaa0-700x650-jpg",
    "_type": "reference"
  }
}

获取图像尺寸可以这样完成:

{
  title: "My Image",
  name: "image",
  type: "image",
  options: {
    accept: "image/*",
  },
  validation: Rule => Rule.custom(image => {
    if (!image) return true
    const { dimensions } = decodeAssetId(image.asset._ref)
    return dimensions.width >= 500 || "Image must be wider"
  }
}

const pattern = /^image-([a-f\d]+)-(\d+x\d+)-(\w+)$/

const decodeAssetId = id => {
  const [, assetId, dimensions, format] = pattern.exec(id)
  const [width, height] = dimensions.split("x").map(v => parseInt(v, 10))

  return {
    assetId,
    dimensions: { width, height },
    format,
  }
}

我还将此功能整合到 sanity-pills 库中,这样可以更轻松地执行以下操作:

import { createImageField } from "sanity-pills"

createImageField({
  name: "image",
  validations: {
    required: true,
    minWidth: 500,
    maxHeight: 9000
  },
})