{"version":3,"file":"index.cjs","sources":["../../../src/plugins/image/index.ts"],"sourcesContent":["import { isSupportedType, warnOnce } from \"../../utils\";\nimport { type DocxImageData, type RemarkDocxPlugin } from \"../../types\";\nimport type * as mdast from \"mdast\";\nimport { visit } from \"unist-util-visit\";\nimport { imageSize } from \"image-size\";\n\ntype LoadFn = (url: string) => Promise<ArrayBuffer>;\n\ntype SvgToPngFn = (options: {\n  buffer: ArrayBuffer;\n  width: number;\n  height: number;\n}) => Promise<ArrayBuffer>;\n\nconst loadWithFetch: LoadFn = async (url) => {\n  const res = await fetch(url);\n  return res.arrayBuffer();\n};\n\n/**\n * @internal\n */\nexport const browserSvgToPng: SvgToPngFn = async ({\n  buffer,\n  width,\n  height,\n}) => {\n  const svgBlob = new Blob([buffer], { type: \"image/svg+xml\" });\n  const url = URL.createObjectURL(svgBlob);\n\n  try {\n    const img = new Image();\n    img.src = url;\n    await img.decode();\n\n    const dpr = window.devicePixelRatio;\n\n    const canvas = document.createElement(\"canvas\");\n    const scaledWidth = width * dpr;\n    const scaledHeight = height * dpr;\n    canvas.width = scaledWidth;\n    canvas.height = scaledHeight;\n    const ctx = canvas.getContext(\"2d\")!;\n    ctx.drawImage(img, 0, 0, scaledWidth, scaledHeight);\n\n    return new Promise<ArrayBuffer>((resolve) => {\n      canvas.toBlob((blob) => {\n        blob!.arrayBuffer().then(resolve);\n      }, \"image/png\");\n    });\n  } finally {\n    URL.revokeObjectURL(url);\n  }\n};\n\nexport interface ImagePluginOptions {\n  /**\n   * A function to resolve image data from url.\n   * @default {@link loadWithFetch}\n   */\n  load?: LoadFn;\n  /**\n   * A function to convert SVG to PNG. According to the docx specifications, embedding SVG images also requires including PNG.\n   * @default {@link browserSvgToPng}, which handles conversion only on browser\n   */\n  fallbackSvg?: SvgToPngFn;\n}\n\n/**\n * A plugin to render \"image\" nodes\n */\nexport const imagePlugin = ({\n  load = loadWithFetch,\n  fallbackSvg = browserSvgToPng,\n}: ImagePluginOptions = {}): RemarkDocxPlugin => {\n  const cache = new Map<string, DocxImageData>();\n\n  const maxCacheLength = 100;\n\n  return async ({ root, definition, images }) => {\n    const imageList: (mdast.Image | mdast.Definition)[] = [];\n    visit(root, \"image\", (node) => {\n      imageList.push(node);\n    });\n    visit(root, \"imageReference\", (node) => {\n      const maybeImage = definition(node.identifier)!;\n      if (maybeImage) {\n        imageList.push(maybeImage);\n      }\n    });\n\n    if (imageList.length !== 0) {\n      const promises = new Map<string, Promise<void>>();\n      imageList.forEach(({ url }) => {\n        if (images.has(url)) {\n          return;\n        }\n        if (cache.has(url)) {\n          images.set(url, cache.get(url)!);\n          return;\n        }\n        if (!promises.has(url)) {\n          promises.set(\n            url,\n            (async () => {\n              let data: ArrayBuffer;\n              try {\n                data = await load(url);\n              } catch (e) {\n                warnOnce(`Failed to load image: ${url} ${e}`);\n                return;\n              }\n\n              const { width, height, type } = imageSize(new Uint8Array(data));\n              if (!isSupportedType(type)) {\n                warnOnce(`Not supported image type: ${type}`);\n                return;\n              }\n\n              if (type === \"svg\") {\n                try {\n                  const fallback = await fallbackSvg({\n                    buffer: data,\n                    width,\n                    height,\n                  });\n                  const docxImage: DocxImageData = {\n                    type,\n                    width,\n                    height,\n                    data,\n                    fallback,\n                  };\n                  images.set(url, docxImage);\n                  cache.set(url, docxImage);\n                } catch (e) {\n                  warnOnce(`Failed to create fallback image: ${url} ${e}`);\n                  return;\n                }\n              } else {\n                const docxImage: DocxImageData = { type, width, height, data };\n                images.set(url, docxImage);\n                cache.set(url, docxImage);\n              }\n            })(),\n          );\n        }\n      });\n\n      await Promise.all(promises.values());\n    }\n\n    if (cache.size > maxCacheLength) {\n      let deleteCount = cache.size - maxCacheLength;\n      for (const key of cache.keys()) {\n        cache.delete(key);\n        deleteCount--;\n        if (deleteCount <= 0) {\n          break;\n        }\n      }\n    }\n\n    return {};\n  };\n};\n"],"names":["visit","warnOnce","imageSize","isSupportedType"],"mappings":"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"}