github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/lib/remark-plugins/imageUriReplacer.ts (about) 1 import { visit } from "unist-util-visit"; 2 import type { Node } from "unist"; 3 import {objects} from "../api"; 4 5 type ImageUriReplacerOptions = { 6 repo: string; 7 ref: string; 8 path: string; 9 presign: boolean; 10 }; 11 12 const ABSOLUTE_URL_REGEX = /^(https?):\/\/.*/; 13 const qs = (queryParts: { [key: string]: string }) => { 14 const parts = Object.keys(queryParts).map((key) => [key, queryParts[key]]); 15 return new URLSearchParams(parts).toString(); 16 }; 17 export const getImageUrl = async ( 18 repo: string, 19 ref: string, 20 path: string, 21 presign: boolean, 22 ): Promise<string> => { 23 if (presign) { 24 try { 25 const obj = await objects.getStat(repo, ref, path, true); 26 return obj.physical_address; 27 } catch(e) { 28 console.error("failed to fetch presigned URL", e); 29 return "" 30 } 31 } 32 33 const query = qs({ path }); 34 return `/api/v1/repositories/${encodeURIComponent( 35 repo 36 )}/refs/${encodeURIComponent(ref)}/objects?${query}`; 37 }; 38 39 const imageUriReplacer = 40 (options: ImageUriReplacerOptions) => async (tree: Node) => { 41 // eslint-disable-next-line @typescript-eslint/no-explicit-any 42 const promises: any[] = []; 43 visit(tree, "image", visitor); 44 await Promise.all(promises); 45 46 function visitor(node: Node & { url: string }) { 47 if (node.url.startsWith("lakefs://")) { 48 const [repo, ref, ...imgPath] = node.url.split("/").slice(2); 49 const p = getImageUrl(repo, ref, imgPath.join("/"), options.presign).then((url) => node.url = url); 50 promises.push(p); 51 } else if (!node.url.match(ABSOLUTE_URL_REGEX)) { 52 // If the image is not an absolute URL, we assume it's a relative path 53 // relative to repo and ref 54 if (node.url.startsWith("/")) { 55 node.url = node.url.slice(1); 56 } 57 // relative to MD file location 58 if (node.url.startsWith("./")) { 59 node.url = `${options.path.split("/").slice(0, -1)}/${node.url.slice( 60 2 61 )}`; 62 } 63 const p = getImageUrl(options.repo, options.ref, node.url, options.presign).then((url) => node.url = url); 64 promises.push(p); 65 } 66 } 67 }; 68 69 export default imageUriReplacer;