@cf-wasm/og
Version:
Generate Open Graph Images dynamically from HTML/CSS without a browser.
1 lines • 3.88 kB
Source Map (JSON)
{"version":3,"file":"asset.cjs","names":["FontDetector","loadEmoji","getIconCode","LANGUAGE_FONT_MAP","loadGoogleFont","ASSET_CACHE_MAP"],"sources":["../../src/core/asset.ts"],"sourcesContent":["import { type EmojiType, getIconCode, loadEmoji } from './emoji';\nimport { loadGoogleFont } from './font';\nimport { FontDetector, LANGUAGE_FONT_MAP } from './language';\nimport { ASSET_CACHE_MAP } from './maps';\nimport type { Font } from './satori';\nimport type { StringWithSuggestions } from './types';\n\n/** Font detector */\nexport const DETECTOR = new FontDetector();\n\n/** Loads dynamic asset requested by satori without caching */\n// `languageCode` will be the detected language code separated using `|` (i.e: `ja-JP|zh-CN|zh-TW|zh-HK`, `devanagari`), `emoji` if it's an Emoji, or `unknown` if not able to tell.\n// `segment` will be the content to render.\nexport async function loadSatoriAsset(\n\tlanguageCode: StringWithSuggestions<'emoji' | 'unknown'>,\n\tsegment: string,\n\temoji?: EmojiType,\n): Promise<string | Font[]> {\n\tif (languageCode === 'emoji') {\n\t\treturn `data:image/svg+xml;base64,${btoa(await loadEmoji(getIconCode(segment), emoji))}`;\n\t}\n\n\tconst codes = languageCode.split('|');\n\tconst names = codes\n\t\t.map((code) => LANGUAGE_FONT_MAP[code as keyof typeof LANGUAGE_FONT_MAP])\n\t\t.filter(Boolean)\n\t\t.flat();\n\n\tif (names.length !== 0) {\n\t\ttry {\n\t\t\tconst textByFont = await DETECTOR.detect(segment, names);\n\t\t\tconst fonts = Object.keys(textByFont);\n\t\t\tconst fontData = await Promise.all(\n\t\t\t\tfonts.map((font) =>\n\t\t\t\t\tloadGoogleFont(font, {\n\t\t\t\t\t\ttext: textByFont[font],\n\t\t\t\t\t\tweight: 400,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\treturn fontData.map((data, index) => ({\n\t\t\t\tname: `satori_${codes[index]}_fallback_${segment}`,\n\t\t\t\tdata,\n\t\t\t\tweight: 400,\n\t\t\t\tstyle: 'normal',\n\t\t\t\tlang: codes[index] === 'unknown' ? undefined : codes[index],\n\t\t\t}));\n\t\t} catch (e) {\n\t\t\tconsole.warn(\n\t\t\t\t`(@cf-wasm/og) [ WARN ] Failed to load dynamic font for segment \\`${segment}\\`.\\n`,\n\t\t\t\te,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn [];\n}\n\n/**\n * Loads dynamic assets requested by satori\n *\n * @param languageCode The language code\n * @param segment The text\n * @param emoji The {@link EmojiType}\n *\n * @returns On success, the asset as either string or {@link Font}\n */\nexport async function loadDynamicAsset(\n\tlanguageCode: StringWithSuggestions<'emoji' | 'unknown'>,\n\tsegment: string,\n\temoji?: EmojiType,\n): Promise<string | Font[]> {\n\t/** Get a key from input */\n\tconst key = JSON.stringify([languageCode, segment]);\n\tif (ASSET_CACHE_MAP.has(key)) {\n\t\tconst cache = ASSET_CACHE_MAP.get(key);\n\t\treturn cache ?? [];\n\t}\n\tconst asset = await loadSatoriAsset(languageCode, segment, emoji);\n\tASSET_CACHE_MAP.set(key, asset);\n\treturn asset;\n}\n"],"mappings":";;;;;;AAQA,MAAa,WAAW,IAAIA,iBAAAA,aAAa;;AAKzC,eAAsB,gBACrB,cACA,SACA,OAC2B;CAC3B,IAAI,iBAAiB,SACpB,OAAO,6BAA6B,KAAK,MAAMC,cAAAA,UAAUC,cAAAA,YAAY,OAAO,GAAG,KAAK,CAAC;CAGtF,MAAM,QAAQ,aAAa,MAAM,GAAG;CACpC,MAAM,QAAQ,MACZ,KAAK,SAASC,iBAAAA,kBAAkB,KAAuC,CAAC,CACxE,OAAO,OAAO,CAAC,CACf,KAAK;CAEP,IAAI,MAAM,WAAW,GACpB,IAAI;EACH,MAAM,aAAa,MAAM,SAAS,OAAO,SAAS,KAAK;EACvD,MAAM,QAAQ,OAAO,KAAK,UAAU;EAUpC,QAAO,MATgB,QAAQ,IAC9B,MAAM,KAAK,SACVC,aAAAA,eAAe,MAAM;GACpB,MAAM,WAAW;GACjB,QAAQ;EACT,CAAC,CACF,CACD,EAAA,CAEgB,KAAK,MAAM,WAAW;GACrC,MAAM,UAAU,MAAM,OAAO,YAAY;GACzC;GACA,QAAQ;GACR,OAAO;GACP,MAAM,MAAM,WAAW,YAAY,KAAA,IAAY,MAAM;EACtD,EAAE;CACH,SAAS,GAAG;EACX,QAAQ,KACP,oEAAoE,QAAQ,QAC5E,CACD;CACD;CAGD,OAAO,CAAC;AACT;;;;;;;;;;AAWA,eAAsB,iBACrB,cACA,SACA,OAC2B;;CAE3B,MAAM,MAAM,KAAK,UAAU,CAAC,cAAc,OAAO,CAAC;CAClD,IAAIC,aAAAA,gBAAgB,IAAI,GAAG,GAE1B,OADcA,aAAAA,gBAAgB,IAAI,GACvB,KAAK,CAAC;CAElB,MAAM,QAAQ,MAAM,gBAAgB,cAAc,SAAS,KAAK;CAChE,aAAA,gBAAgB,IAAI,KAAK,KAAK;CAC9B,OAAO;AACR"}