UNPKG

visionary-url

Version:

A lightweight library for generating image URLs with baked-in blurhash placeholders.

352 lines (351 loc) 12.4 kB
var he = Object.defineProperty; var pe = (r, n, o) => n in r ? he(r, n, { enumerable: !0, configurable: !0, writable: !0, value: o }) : r[n] = o; var Y = (r, n, o) => pe(r, typeof n != "symbol" ? n + "" : n, o); import { I as C, B as M, V as J, U, a as K, D as ge } from "./constants-DSuy6aJs.js"; var I = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, _ = {}, Q = { exports: {} }; (function(r, n) { (function(o, a) { r.exports = a(); })(typeof self < "u" ? self : typeof window < "u" ? window : I, function() { var o = "3.7.7", a = o, i = typeof Buffer == "function", f = typeof TextDecoder == "function" ? new TextDecoder() : void 0, d = typeof TextEncoder == "function" ? new TextEncoder() : void 0, m = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", h = Array.prototype.slice.call(m), l = function(e) { var t = {}; return e.forEach(function(s, c) { return t[s] = c; }), t; }(h), F = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/, u = String.fromCharCode.bind(String), B = typeof Uint8Array.from == "function" ? Uint8Array.from.bind(Uint8Array) : function(e) { return new Uint8Array(Array.prototype.slice.call(e, 0)); }, v = function(e) { return e.replace(/=/g, "").replace(/[+\/]/g, function(t) { return t == "+" ? "-" : "_"; }); }, x = function(e) { return e.replace(/[^A-Za-z0-9\+\/]/g, ""); }, y = function(e) { for (var t, s, c, b, p = "", R = e.length % 3, D = 0; D < e.length; ) { if ((s = e.charCodeAt(D++)) > 255 || (c = e.charCodeAt(D++)) > 255 || (b = e.charCodeAt(D++)) > 255) throw new TypeError("invalid character found"); t = s << 16 | c << 8 | b, p += h[t >> 18 & 63] + h[t >> 12 & 63] + h[t >> 6 & 63] + h[t & 63]; } return R ? p.slice(0, R - 3) + "===".substring(R) : p; }, g = typeof btoa == "function" ? function(e) { return btoa(e); } : i ? function(e) { return Buffer.from(e, "binary").toString("base64"); } : y, E = i ? function(e) { return Buffer.from(e).toString("base64"); } : function(e) { for (var t = 4096, s = [], c = 0, b = e.length; c < b; c += t) s.push(u.apply(null, e.subarray(c, c + t))); return g(s.join("")); }, T = function(e, t) { return t === void 0 && (t = !1), t ? v(E(e)) : E(e); }, ie = function(e) { if (e.length < 2) { var t = e.charCodeAt(0); return t < 128 ? e : t < 2048 ? u(192 | t >>> 6) + u(128 | t & 63) : u(224 | t >>> 12 & 15) + u(128 | t >>> 6 & 63) + u(128 | t & 63); } else { var t = 65536 + (e.charCodeAt(0) - 55296) * 1024 + (e.charCodeAt(1) - 56320); return u(240 | t >>> 18 & 7) + u(128 | t >>> 12 & 63) + u(128 | t >>> 6 & 63) + u(128 | t & 63); } }, ue = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g, k = function(e) { return e.replace(ue, ie); }, z = i ? function(e) { return Buffer.from(e, "utf8").toString("base64"); } : d ? function(e) { return E(d.encode(e)); } : function(e) { return g(k(e)); }, A = function(e, t) { return t === void 0 && (t = !1), t ? v(z(e)) : z(e); }, N = function(e) { return A(e, !0); }, se = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g, fe = function(e) { switch (e.length) { case 4: var t = (7 & e.charCodeAt(0)) << 18 | (63 & e.charCodeAt(1)) << 12 | (63 & e.charCodeAt(2)) << 6 | 63 & e.charCodeAt(3), s = t - 65536; return u((s >>> 10) + 55296) + u((s & 1023) + 56320); case 3: return u((15 & e.charCodeAt(0)) << 12 | (63 & e.charCodeAt(1)) << 6 | 63 & e.charCodeAt(2)); default: return u((31 & e.charCodeAt(0)) << 6 | 63 & e.charCodeAt(1)); } }, P = function(e) { return e.replace(se, fe); }, V = function(e) { if (e = e.replace(/\s+/g, ""), !F.test(e)) throw new TypeError("malformed base64."); e += "==".slice(2 - (e.length & 3)); for (var t, s = "", c, b, p = 0; p < e.length; ) t = l[e.charAt(p++)] << 18 | l[e.charAt(p++)] << 12 | (c = l[e.charAt(p++)]) << 6 | (b = l[e.charAt(p++)]), s += c === 64 ? u(t >> 16 & 255) : b === 64 ? u(t >> 16 & 255, t >> 8 & 255) : u(t >> 16 & 255, t >> 8 & 255, t & 255); return s; }, S = typeof atob == "function" ? function(e) { return atob(x(e)); } : i ? function(e) { return Buffer.from(e, "base64").toString("binary"); } : V, W = i ? function(e) { return B(Buffer.from(e, "base64")); } : function(e) { return B(S(e).split("").map(function(t) { return t.charCodeAt(0); })); }, Z = function(e) { return W($(e)); }, le = i ? function(e) { return Buffer.from(e, "base64").toString("utf8"); } : f ? function(e) { return f.decode(W(e)); } : function(e) { return P(S(e)); }, $ = function(e) { return x(e.replace(/[-_]/g, function(t) { return t == "-" ? "+" : "/"; })); }, O = function(e) { return le($(e)); }, ce = function(e) { if (typeof e != "string") return !1; var t = e.replace(/\s+/g, "").replace(/={0,2}$/, ""); return !/[^\s0-9a-zA-Z\+/]/.test(t) || !/[^\s0-9a-zA-Z\-_]/.test(t); }, G = function(e) { return { value: e, enumerable: !1, writable: !0, configurable: !0 }; }, H = function() { var e = function(t, s) { return Object.defineProperty(String.prototype, t, G(s)); }; e("fromBase64", function() { return O(this); }), e("toBase64", function(t) { return A(this, t); }), e("toBase64URI", function() { return A(this, !0); }), e("toBase64URL", function() { return A(this, !0); }), e("toUint8Array", function() { return Z(this); }); }, X = function() { var e = function(t, s) { return Object.defineProperty(Uint8Array.prototype, t, G(s)); }; e("toBase64", function(t) { return T(this, t); }), e("toBase64URI", function() { return T(this, !0); }), e("toBase64URL", function() { return T(this, !0); }); }, de = function() { H(), X(); }, w = { version: o, VERSION: a, atob: S, atobPolyfill: V, btoa: g, btoaPolyfill: y, fromBase64: O, toBase64: A, encode: A, encodeURI: N, encodeURL: N, utob: k, btou: P, decode: O, isValid: ce, fromUint8Array: T, toUint8Array: Z, extendString: H, extendUint8Array: X, extendBuiltins: de }; return w.Base64 = {}, Object.keys(w).forEach(function(e) { return w.Base64[e] = w[e]; }), w; }); })(Q); var be = Q.exports; Object.defineProperty(_, "__esModule", { value: !0 }); var ee = _.decodeBase64Url = te = _.encodeBase64Url = void 0; const re = be, me = (r) => { if (typeof r != "string") throw new Error("encodeBase64Url: input must be a string"); return (0, re.encode)(r).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); }; var te = _.encodeBase64Url = me; const ve = (r) => { if (typeof r != "string") throw new Error("decodeBase64Url: input must be a string"); return (0, re.decode)(r.replace(/-/g, "+").replace(/_/g, "/")); }; ee = _.decodeBase64Url = ve; const xe = (r) => r.filter(Boolean), q = (r) => { try { return new URL(r); } catch { return null; } }, Se = (r) => { switch (r) { case C.AVIF: return { contentType: "image/avif", extension: "avif" }; case C.JPEG: return { contentType: "image/jpeg", extension: "jpg" }; case C.WEBP: return { contentType: "image/webp", extension: "webp" }; default: throw new Error(`formatToContentType: unknown format ${r}`); } }, j = (r = "") => /^[A-Za-z0-9_-]*$/.test(r), Oe = (r, n) => { const o = r / n, a = M; let i = M; return o >= 1.6 && (i = 3), [a, i]; }, ye = (r) => { const { altText: n, bcc: o, blurhash: a, blurhashX: i, blurhashY: f, sourceHeight: d, sourceWidth: m, url: h } = r; if (!h || !m || !d) return new Error("Cannot construct visionary code: missing required url/width/height"); const l = [h, m, d]; return !o || (l.push(o), !a || !i || !f) || (l.push(a, i, f), n && n.length && l.push(n)), L(l); }, L = (r) => te(r.join(J)), ne = (r) => { if (typeof r != "string") return null; const n = r.trim(); if (!n.length || !j(n)) return null; const o = ee(n); if (!o) return null; const a = o.split(J); if (a.length < 3) return null; const [i, f, d, m, h, l, F, u] = a, B = i.trim(); if (!B.length) return console.error("Cannot parse code, empty file id"), null; const v = Number(f.trim()), x = Number(d.trim()); if (isNaN(v) || isNaN(x) || !v || !x) return console.error("Cannot parse Visionary Code: invalid image dimensions", f, d), null; const y = Number(l) ?? 0, g = Number(F) ?? 0; return y < 1 || g < 1 ? (console.error( "Cannot parse Visionary Code: invalid blurhash x, y component dimensions", y, g ), null) : { altText: u, bcc: m, blurhash: h, blurhashX: y, blurhashY: g, sourceHeight: x, sourceWidth: v, url: B }; }; class Ae extends Error { constructor() { super(...arguments); Y(this, "message", "invalid endpoint URL (does it contain http/https?)"); } } const Ue = (r) => r === U.DEBUG, Be = (r) => r === U.DOWNLOAD, we = (r) => r === U.FOLLOW, Ce = (r) => Object.values(C).includes(r), oe = (r) => Object.values(K).includes(r), ae = (r = []) => { const n = {}; for (const o of r) oe(o) ? n.size = K[o] : Ue(o) ? n.debug = !0 : Be(o) ? n.download = !0 : we(o) ? n.follow = !0 : Ce(o) && (n.format = o); return n; }, _e = (r) => { if (!r || typeof r != "object") return null; const n = []; return r.debug && n.push(U.DEBUG), r.download && n.push(U.DOWNLOAD), r.follow && n.push(U.FOLLOW), r.format && r.format !== C.AUTO && n.push(r.format), r.size && oe(r.size) && n.push(r.size), n.length ? n.sort().join(",") : null; }, Re = (r = "") => ae(r.split(",")), Ie = (r) => { if (j(r)) { const o = ne(r); if (o) return { fields: o, options: {} }; } return Ee(r); }, Ee = (r) => { if (!r) return null; const n = r.trim(); if (!n) return null; try { const o = Te(n); if (!o) return null; const { code: a, optionTokens: i } = o, f = ne(a); if (!f) return null; const d = ae(i); return { fields: f, options: d }; } catch (o) { o instanceof Error ? console.error(`Error parsing URL: ${o.message}`, o) : console.error("uncaught error", o); } return null; }, Le = (r, n) => { const o = ye(r); if (o instanceof Error) return null; let a = null; if (n != null && n.endpoint && (a = q(n == null ? void 0 : n.endpoint), !a)) throw new Ae( "Cannot construct URL: bad endpoint. Ensure endpoint starts with http:// or https://" ); a || (a = q(ge)); const i = [a.origin, "image", o], f = n ? _e(n) : null; return f && i.push(f), n != null && n.filename ? i.push(n.filename) : i.push("image.jpg"), i.join("/"); }, Te = (r) => { try { const n = new URL(r), o = xe(n.pathname.split("/")); if (o[0] !== "image" || ![3, 4].includes(o.length)) throw new Error("Unrecognized URL"); const a = o[1].trim(); if (!a.length || !j(a)) throw new Error("URL is not formatted as base64url"); if (o.length === 4) { const i = o[2].split(","); return { code: a, optionTokens: i }; } if (o.length === 3) return { code: a, optionTokens: [] }; } catch { return null; } return null; }; export { C as ImageFormatToken, K as ImageSizeToken, U as UrlOptionToken, Se as formatToContentType, ye as generateVisionaryCode, Le as generateVisionaryUrl, j as isBase64UrlEncoded, Ue as isDebugToken, Be as isDownloadToken, we as isFollowToken, Ce as isImageFormatToken, oe as isImageSizeToken, Re as parseOptionsString, ne as parseVisionaryCode, Ie as parseVisionaryString, Ee as parseVisionaryUrl, Oe as suggestedBlurhashComponentDimensions };