@ecency/render-helper 2.5.7 → 2.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,10 +51,26 @@ declare function catchPostImage(obj: Entry | string, width?: number, height?: nu
51
51
  declare function getPostBodySummary(obj: Entry | string, length?: number, platform?: 'ios' | 'android' | 'web'): string;
52
52
 
53
53
  declare function setProxyBase(p: string): void;
54
+ interface ProxifyOptions {
55
+ /**
56
+ * Request a tiny blurred LQIP placeholder. The proxy resizes to ~20px and
57
+ * gaussian-blurs it (a few hundred bytes), for use behind the real image
58
+ * while it loads.
59
+ */
60
+ blur?: boolean;
61
+ /**
62
+ * Route on-host uploads through the /p/ proxy even when no width/height is
63
+ * requested, so the server still negotiates WebP/AVIF via the Accept header
64
+ * (instead of streaming the original bytes from direct-serve). Use for
65
+ * displayed `<img>` sources; leave off for OG/social images, where the
66
+ * original format is safest.
67
+ */
68
+ forceProxy?: boolean;
69
+ }
54
70
  /**
55
71
  * @param _format - @deprecated Ignored. Always uses 'match' — format is handled server-side via Accept header.
56
72
  */
57
- declare function proxifyImageSrc(url?: string, width?: number, height?: number, _format?: string): string;
73
+ declare function proxifyImageSrc(url?: string, width?: number, height?: number, _format?: string, opts?: ProxifyOptions): string;
58
74
  /**
59
75
  * Builds a srcset string with multiple width variants for responsive images.
60
76
  * Uses the image proxy's width parameter to serve appropriately sized images.
@@ -85,4 +101,4 @@ declare function isValidPermlink(permlink: string): boolean;
85
101
  */
86
102
  declare function simpleMarkdownToHTML(input: string): string;
87
103
 
88
- export { type Entry, IMAGE_SIZES, type RenderOptions, SECTION_LIST, type SeoContext, buildSrcSet, catchPostImage, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
104
+ export { type Entry, IMAGE_SIZES, type ProxifyOptions, type RenderOptions, SECTION_LIST, type SeoContext, buildSrcSet, catchPostImage, isValidPermlink, getPostBodySummary as postBodySummary, proxifyImageSrc, markdown2Html as renderPostBody, setCacheSize, setProxyBase, setSlowRenderThresholdMs, simpleMarkdownToHTML };
@@ -475,9 +475,11 @@ function setProxyBase(p2) {
475
475
  function getProxyBase() {
476
476
  return proxyBase;
477
477
  }
478
+ var PROXY_P_PREFIXES = () => [`${proxyBase}/p/`, "https://images.ecency.com/p/"];
478
479
  function extractPHash(url) {
479
- if (url.startsWith(`${proxyBase}/p/`)) {
480
- const [hash] = url.split("/p/")[1].split("?");
480
+ const prefix = PROXY_P_PREFIXES().find((p2) => url.startsWith(p2));
481
+ if (prefix) {
482
+ const [hash] = url.slice(prefix.length).split("?");
481
483
  return hash.replace(/\.(webp|png)$/, "");
482
484
  }
483
485
  return null;
@@ -493,17 +495,18 @@ function getLatestUrl(str) {
493
495
  const [last] = [...str.replace(/https?:\/\//g, "\n$&").trim().split("\n")].reverse();
494
496
  return last;
495
497
  }
496
- function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
498
+ function proxifyImageSrc(url, width = 0, height = 0, _format = "match", opts = {}) {
497
499
  if (!url || typeof url !== "string" || !isValidUrl(url)) {
498
500
  return "";
499
501
  }
502
+ const routeThroughProxy = width > 0 || height > 0 || !!opts.blur || !!opts.forceProxy;
500
503
  if (url.indexOf("https://images.hive.blog/") === 0 && url.indexOf("https://images.hive.blog/D") !== 0) {
501
504
  return url.replace("https://images.hive.blog", proxyBase);
502
505
  }
503
506
  if (url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0) {
504
507
  return url.replace("https://steemitimages.com", proxyBase);
505
508
  }
506
- if (url.indexOf("https://images.ecency.com/") === 0) {
509
+ if (url.indexOf("https://images.ecency.com/") === 0 && !routeThroughProxy) {
507
510
  return url.replace("https://images.ecency.com", proxyBase);
508
511
  }
509
512
  const realUrl = getLatestUrl(url);
@@ -518,6 +521,9 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
518
521
  if (height > 0) {
519
522
  options.height = height;
520
523
  }
524
+ if (opts.blur) {
525
+ options.blur = 1;
526
+ }
521
527
  const qs = querystring.stringify(options);
522
528
  if (pHash) {
523
529
  return `${proxyBase}/p/${pHash}?${qs}`;
@@ -578,7 +584,7 @@ function img(el, state) {
578
584
  const base = trimTrailingSlash(getProxyBase());
579
585
  const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
580
586
  if (shouldReplace && !hasAlreadyProxied) {
581
- const proxified = proxifyImageSrc(decodedSrc);
587
+ const proxified = proxifyImageSrc(decodedSrc, 0, 0, "match", { forceProxy: true });
582
588
  if (proxified) {
583
589
  el.setAttribute("src", proxified);
584
590
  const srcset = buildSrcSet(decodedSrc);
@@ -598,7 +604,7 @@ function img(el, state) {
598
604
  }
599
605
  }
600
606
  function createImageHTML(src, isLCP) {
601
- const proxified = proxifyImageSrc(src);
607
+ const proxified = proxifyImageSrc(src, 0, 0, "match", { forceProxy: true });
602
608
  if (!proxified) return "";
603
609
  const base = trimTrailingSlash(getProxyBase());
604
610
  const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);