Last active
July 22, 2022 00:41
-
-
Save Utzel-Butzel/d70df2a60b2de503fb9c9aa226cb73ba to your computer and use it in GitHub Desktop.
A rehype plugin for mdx (markdown) to add metadata and cloudinary information to images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Cloudinary } from "cloudinary-core"; | |
import { getImage } from "../../lib/api"; | |
import urlGenerator from "../../lib/cloudinaryHelper"; | |
function searchTreeWrapper(element, matchingTitle) { | |
var result = []; | |
const searchTree = (element, matchingTitle) => { | |
if (element.name == matchingTitle) { | |
result.push(element); | |
} else if (element.children != null) { | |
var i; | |
for (i = 0; i < element.children.length; i++) { | |
searchTree(element.children[i], matchingTitle); | |
} | |
} | |
}; | |
searchTree(element, matchingTitle); | |
return result; | |
} | |
async function probeImage(id) { | |
const res = await getImage(id); | |
return res; | |
} | |
async function probe(src) { | |
// Use function to get cloud_name and name from cloudinary image url | |
const { cloudName, name, isVideo } = urlGenerator(src); | |
var cl = new Cloudinary({ cloud_name: cloudName, secure: false }); | |
const url = cl.url(name, { | |
protocol: "https:", | |
width: 300, | |
flags: ["getinfo"], | |
}); | |
const res = await fetch(url, { | |
method: "GET", | |
}); | |
const result = await res.json(); | |
return { width: result.input.width, height: result.input.height }; | |
} | |
const rehypeImage = (options) => async (tree) => { | |
const options_ = options || {}; | |
const baseUrl = options_.baseUrl; | |
const imageNodes = searchTreeWrapper(tree, "CloudinaryImage"); | |
const validImageNodes = imageNodes; | |
await Promise.all( | |
validImageNodes.map(async (node) => { | |
try { | |
const id = node.attributes.find((a) => a.name === "id"); | |
// Getting image meta from Content Management | |
const info = await probeImage(id.value); | |
const dimensions = (await probe(info.image.publicUrl, baseUrl)) || {}; | |
const attributes = { | |
...dimensions, | |
...info.image, | |
src: info.image.publicUrl, | |
}; | |
const newAttributes = Object.entries(attributes).map(([i, a]) => { | |
return { | |
type: "mdxJsxAttribute", | |
name: i, | |
value: a, | |
}; | |
}); | |
node.attributes = [...node.attributes, ...newAttributes]; | |
} catch (error) { | |
console.log( | |
`Error: [rehype-cloudinary-img-size] error getting the dimensions of`, | |
error | |
); | |
throw new Error( | |
`Error: [rehype-cloudinary-img-size] error getting the dimensions of` | |
); | |
} | |
}) | |
); | |
}; | |
export default rehypeImage; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment