@cf-wasm/og
Version:
Generate Open Graph Images dynamically from HTML/CSS without a browser.
282 lines (280 loc) • 9.04 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/core/font.ts
var font_exports = {};
__export(font_exports, {
BaseFont: () => BaseFont,
CustomFont: () => CustomFont,
FONT_CACHE_MAP: () => FONT_CACHE_MAP,
GOOGLE_FONT_CSS_DEFAULT_USER_AGENT: () => GOOGLE_FONT_CSS_DEFAULT_USER_AGENT,
GoogleFont: () => GoogleFont,
constructGoogleFontCssUrl: () => constructGoogleFontCssUrl,
defaultFont: () => defaultFont,
googleFonts: () => googleFonts,
loadGoogleFont: () => loadGoogleFont
});
module.exports = __toCommonJS(font_exports);
var import_cache = require("./cache.js");
var import_errors = require("./errors.js");
var FONT_CACHE_MAP = /* @__PURE__ */ new Map();
var GOOGLE_FONT_CSS_DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1";
var GoogleFontsUtils = class {
constructor() {
/** Default Google font css loader */
this._defaultCssLoader = async (cssUrl, userAgent) => {
const cssResponse = await import_cache.cache.serve(
cssUrl,
() => fetch(cssUrl, {
headers: {
"User-Agent": userAgent
}
}).then((res) => {
if (!res.ok) {
throw new import_errors.FetchError(`Response was not successful (status: \`${res.status}\`, statusText: \`${res.statusText}\`)`, { response: res });
}
return res;
}).catch((e) => {
throw new import_errors.FetchError(`An error ocurred while fetching \`${cssUrl}\``, {
cause: e,
response: e instanceof import_errors.FetchError ? e.response : void 0
});
})
);
return cssResponse.text();
};
/** Google font css loader */
this._cssLoader = this._defaultCssLoader;
}
/**
* Loads Google font css
*
* @param cssUrl The Google font css url
* @param userAgent The user agent header to be used
*
* @returns On success, the css as string
*/
async loadCss(cssUrl, userAgent = GOOGLE_FONT_CSS_DEFAULT_USER_AGENT) {
let css = await this._cssLoader(cssUrl, userAgent);
if (typeof css === "undefined") {
css = await this._defaultCssLoader(cssUrl, userAgent);
} else if (typeof css !== "string") {
throw new Error("Google font css loader return value must resolve to string");
}
return css;
}
/**
* Sets Google font css loader
*
* @param loader The {@link GoogleFontCssLoader}
*/
setCssLoader(loader) {
if (typeof loader !== "function") {
throw new TypeError("Argument 1 must be a function.");
}
this._cssLoader = loader;
}
};
var googleFonts = new GoogleFontsUtils();
var constructGoogleFontCssUrl = (family, { text, weight = 400, style = "normal", display } = {}) => {
if (typeof family !== "string" || family.trim().length === 0) {
throw new Error("Not a valid font family name was provided");
}
const params = {
family: `${family.replaceAll(" ", "+")}:${style === "italic" ? "ital," : ""}wght@${style === "italic" ? "1," : ""}${weight}`
};
if (text) {
params.text = encodeURIComponent(text);
} else {
params.subset = "latin";
}
if (typeof display === "string") {
params.display = display;
}
const cssUrl = `https://fonts.googleapis.com/css2?${Object.keys(params).map((key) => `${key}=${params[key]}`).join("&")}`;
return cssUrl;
};
var loadGoogleFont = async (family, { text, weight = 400, style = "normal", display } = {}) => {
const cssUrl = constructGoogleFontCssUrl(family, { text, weight, display, style });
const fromMap = FONT_CACHE_MAP.get(cssUrl);
if (fromMap) {
return fromMap;
}
const css = await googleFonts.loadCss(cssUrl);
const fontUrl = css.match(/src: url\((.+)\) format\('(opentype|truetype)'\)/)?.[1];
if (!fontUrl) {
throw new Error("The css does not content source for truetype font.");
}
const fontResponse = await import_cache.cache.serve(
fontUrl,
() => fetch(fontUrl).then((res) => {
if (!res.ok) {
throw new import_errors.FetchError(`Response was not successful (status: ${res.status}, statusText: ${res.statusText})`, { response: res });
}
return res;
}).catch((e) => {
throw new import_errors.FetchError(`An error ocurred while fetching ${fontUrl}`, {
cause: e,
response: e instanceof import_errors.FetchError ? e.response : void 0
});
})
);
const buffer = await fontResponse.arrayBuffer();
FONT_CACHE_MAP.set(cssUrl, buffer);
return buffer;
};
var BaseFont = class {
constructor(name, input, { weight = 400, style = "normal" } = {}) {
this.input = input;
this.name = name;
this.style = style;
this.weight = weight;
}
get data() {
return this.input;
}
};
var CustomFont = class extends BaseFont {
/**
* Creates an instance of {@link CustomFont}
*
* @param name The name of the font (can be used for font-family css property)
* @param input Font data as `ArrayBuffer` or a promise which resolves to `ArrayBuffer`
* @param options
*/
constructor(name, input, options) {
super(name, input, options);
this.input = input;
this.lang = options?.lang;
}
/**
* A promise which resolves to font data as `ArrayBuffer`
*/
get data() {
const fallback = async () => typeof this.input === "function" ? this.input() : this.input;
this.promise = this.promise?.then(null, fallback) ?? fallback();
return this.promise;
}
};
var GoogleFont = class extends BaseFont {
/**
* Creates an instance of {@link GoogleFont}
*
* @param family The name of font family to load
* @param options The {@link GoogleFontOptions}
*/
constructor(family, options = {}) {
super(options.name || family, void 0, options);
this.family = family;
this.text = options.text;
this.input = void 0;
}
/** A promise which resolves to font data as `ArrayBuffer` */
get data() {
const fallback = async () => loadGoogleFont(this.family, {
weight: this.weight,
style: this.style,
text: this.text
});
this.promise = this.promise?.then(null, fallback) ?? fallback();
return this.promise;
}
/**
* Checks whether font can load buffer
*
* @returns On success, true otherwise the error object thrown
*/
async canLoad() {
try {
await this.data;
} catch (e) {
return e;
}
return true;
}
};
var DefaultFont = class {
constructor() {
this._fontShouldResolve = true;
}
/**
* Sets default font for image rendering
*
* @param input {@link FontInput}
*/
set(input) {
if (!input) {
throw new TypeError("Argument 1 type is not acceptable");
}
this._fontShouldResolve = true;
this._fallbackFont = input;
}
/**
* Gets default font buffer for image rendering if it is set
*
* @returns A Promise which resolves to ArrayBuffer if default font is set,
* otherwise undefined
*/
async get() {
const { _fallbackFont, _fontData, _fontShouldResolve } = this;
let buffer;
const fontInput = typeof _fallbackFont === "function" ? _fallbackFont() : _fallbackFont;
if (_fontShouldResolve && fontInput) {
if (fontInput instanceof Promise) {
const result = await fontInput;
if (result instanceof Response) {
buffer = await result.arrayBuffer();
} else {
buffer = result;
}
} else if (fontInput instanceof Response) {
buffer = await fontInput.arrayBuffer();
} else if ("data" in fontInput) {
buffer = await fontInput.data;
} else {
buffer = fontInput;
}
} else if (_fontData) {
buffer = _fontData;
}
this._fontData = buffer;
this._fontShouldResolve = false;
return buffer;
}
/**
* Check whether default font is set or not
*
* @returns true if default font is set, otherwise false
*/
has() {
return Boolean(this._fallbackFont);
}
};
var defaultFont = new DefaultFont();
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
BaseFont,
CustomFont,
FONT_CACHE_MAP,
GOOGLE_FONT_CSS_DEFAULT_USER_AGENT,
GoogleFont,
constructGoogleFontCssUrl,
defaultFont,
googleFonts,
loadGoogleFont
});