Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More →
Socket
Sign inDemoInstall
Socket

@storyblok/richtext

Package Overview
Dependencies
Maintainers
8
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@storyblok/richtext - npm Package Compare versions

Comparing version 2.1.0 to 3.0.0

dist/utils/index.d.ts

1

dist/images-optimization.d.ts
import { StoryblokRichTextImageOptimizationOptions } from './types';
export declare function optimizeImage(src: string, options?: boolean | Partial<StoryblokRichTextImageOptimizationOptions>): {

@@ -4,0 +3,0 @@ src: string;

@@ -0,2 +1,2 @@

export * from './richtext';
export * from './types';
export * from './richtext';

@@ -1,3 +0,2 @@

import { StoryblokRichTextOptions, StoryblokRichTextNode } from './types';
import { StoryblokRichTextNode, StoryblokRichTextOptions } from './types';
/**

@@ -8,3 +7,3 @@ * Creates a rich text resolver with the given options.

* @template T
* @param {StoryblokRichTextOptions<T>} [options={}]
* @param {StoryblokRichTextOptions<T>} [options]
* @return {*}

@@ -11,0 +10,0 @@ */

@@ -7,144 +7,182 @@ /**

*/
var o = /* @__PURE__ */ ((e) => (e.DOCUMENT = "doc", e.HEADING = "heading", e.PARAGRAPH = "paragraph", e.QUOTE = "blockquote", e.OL_LIST = "ordered_list", e.UL_LIST = "bullet_list", e.LIST_ITEM = "list_item", e.CODE_BLOCK = "code_block", e.HR = "horizontal_rule", e.BR = "hard_break", e.IMAGE = "image", e.EMOJI = "emoji", e.COMPONENT = "blok", e))(o || {}), u = /* @__PURE__ */ ((e) => (e.BOLD = "bold", e.STRONG = "strong", e.STRIKE = "strike", e.UNDERLINE = "underline", e.ITALIC = "italic", e.CODE = "code", e.LINK = "link", e.ANCHOR = "anchor", e.STYLED = "styled", e.SUPERSCRIPT = "superscript", e.SUBSCRIPT = "subscript", e.TEXT_STYLE = "textStyle", e.HIGHLIGHT = "highlight", e))(u || {}), N = /* @__PURE__ */ ((e) => (e.TEXT = "text", e))(N || {}), _ = /* @__PURE__ */ ((e) => (e.SELF = "_self", e.BLANK = "_blank", e))(_ || {}), A = /* @__PURE__ */ ((e) => (e.URL = "url", e.STORY = "story", e.ASSET = "asset", e.EMAIL = "email", e))(A || {});
function w(e, r) {
if (!r) return { src: e, attrs: {} };
let a = 0, d = 0;
const m = {}, s = [];
function h(c, g, $, n, R) {
typeof c != "number" || c <= g || c >= $ ? console.warn(`[StoryblokRichText] - ${n.charAt(0).toUpperCase() + n.slice(1)} value must be a number between ${g} and ${$} (inclusive)`) : R.push(`${n}(${c})`);
function U(e, r) {
if (!r)
return { src: e, attrs: {} };
let a = 0, R = 0;
const b = {}, l = [];
function d(c, g, S, E, n) {
typeof c != "number" || c <= g || c >= S ? console.warn(`[StoryblokRichText] - ${E.charAt(0).toUpperCase() + E.slice(1)} value must be a number between ${g} and ${S} (inclusive)`) : n.push(`${E}(${c})`);
}
if (typeof r == "object") {
if (typeof r.width == "number" && r.width > 0 ? (m.width = r.width, a = r.width) : console.warn("[StoryblokRichText] - Width value must be a number greater than 0"), r.height && typeof r.height == "number" && r.height > 0 ? (m.height = r.height, d = r.height) : console.warn("[StoryblokRichText] - Height value must be a number greater than 0"), r.loading && ["lazy", "eager"].includes(r.loading) && (m.loading = r.loading), r.class && (m.class = r.class), r.filters) {
const { filters: c } = r || {}, { blur: g, brightness: $, fill: n, format: R, grayscale: O, quality: I, rotate: L } = c || {};
g && h(g, 0, 100, "blur", s), I && h(I, 0, 100, "quality", s), $ && h($, 0, 100, "brightness", s), n && s.push(`fill(${n})`), O && s.push("grayscale()"), L && [0, 90, 180, 270].includes(r.filters.rotate || 0) && s.push(`rotate(${L})`), R && ["webp", "png", "jpeg"].includes(R) && s.push(`format(${R})`);
if (typeof r.width == "number" && r.width > 0 ? (b.width = r.width, a = r.width) : console.warn("[StoryblokRichText] - Width value must be a number greater than 0"), r.height && typeof r.height == "number" && r.height > 0 ? (b.height = r.height, R = r.height) : console.warn("[StoryblokRichText] - Height value must be a number greater than 0"), r.loading && ["lazy", "eager"].includes(r.loading) && (b.loading = r.loading), r.class && (b.class = r.class), r.filters) {
const { filters: c } = r || {}, { blur: g, brightness: S, fill: E, format: n, grayscale: L, quality: T, rotate: v } = c || {};
g && d(g, 0, 100, "blur", l), T && d(T, 0, 100, "quality", l), S && d(S, 0, 100, "brightness", l), E && l.push(`fill(${E})`), L && l.push("grayscale()"), v && [0, 90, 180, 270].includes(r.filters.rotate || 0) && l.push(`rotate(${v})`), n && ["webp", "png", "jpeg"].includes(n) && l.push(`format(${n})`);
}
r.srcset && (m.srcset = r.srcset.map((c) => {
r.srcset && (b.srcset = r.srcset.map((c) => {
if (typeof c == "number")
return `${e}/m/${c}x0/${s.length > 0 ? "filters:" + s.join(":") : ""} ${c}w`;
return `${e}/m/${c}x0/${l.length > 0 ? `filters:${l.join(":")}` : ""} ${c}w`;
if (Array.isArray(c) && c.length === 2) {
const [g, $] = c;
return `${e}/m/${g}x${$}/${s.length > 0 ? "filters:" + s.join(":") : ""} ${g}w`;
const [g, S] = c;
return `${e}/m/${g}x${S}/${l.length > 0 ? `filters:${l.join(":")}` : ""} ${g}w`;
} else {
console.warn("[StoryblokRichText] - srcset entry must be a number or a tuple of two numbers");
return;
}
}).join(", ")), r.sizes && (m.sizes = r.sizes.join(", "));
}).join(", ")), r.sizes && (b.sizes = r.sizes.join(", "));
}
let E = `${e}/m/`;
return a > 0 && d > 0 && (E = `${E}${a}x${d}/`), s.length > 0 && (E = `${E}filters:${s.join(":")}`), {
src: E,
attrs: m
let u = `${e}/m/`;
return a > 0 && R > 0 && (u = `${u}${a}x${R}/`), l.length > 0 && (u = `${u}filters:${l.join(":")}`), {
src: u,
attrs: b
};
}
const x = (e = {}) => Object.keys(e).map((r) => `${r}="${e[r]}"`).join(" "), P = (e = {}) => Object.keys(e).map((r) => `${r}: ${e[r]}`).join("; ");
function U(e) {
var f = /* @__PURE__ */ ((e) => (e.DOCUMENT = "doc", e.HEADING = "heading", e.PARAGRAPH = "paragraph", e.QUOTE = "blockquote", e.OL_LIST = "ordered_list", e.UL_LIST = "bullet_list", e.LIST_ITEM = "list_item", e.CODE_BLOCK = "code_block", e.HR = "horizontal_rule", e.BR = "hard_break", e.IMAGE = "image", e.EMOJI = "emoji", e.COMPONENT = "blok", e))(f || {}), m = /* @__PURE__ */ ((e) => (e.BOLD = "bold", e.STRONG = "strong", e.STRIKE = "strike", e.UNDERLINE = "underline", e.ITALIC = "italic", e.CODE = "code", e.LINK = "link", e.ANCHOR = "anchor", e.STYLED = "styled", e.SUPERSCRIPT = "superscript", e.SUBSCRIPT = "subscript", e.TEXT_STYLE = "textStyle", e.HIGHLIGHT = "highlight", e))(m || {}), _ = /* @__PURE__ */ ((e) => (e.TEXT = "text", e))(_ || {}), D = /* @__PURE__ */ ((e) => (e.SELF = "_self", e.BLANK = "_blank", e))(D || {}), A = /* @__PURE__ */ ((e) => (e.URL = "url", e.STORY = "story", e.ASSET = "asset", e.EMAIL = "email", e))(A || {});
const G = [
"area",
"base",
"br",
"col",
"embed",
"hr",
"img",
"input",
"link",
"meta",
"param",
"source",
"track",
"wbr"
], z = (e = {}) => Object.keys(e).map((r) => `${r}="${e[r]}"`).join(" "), p = (e = {}) => Object.keys(e).map((r) => `${r}: ${e[r]}`).join("; ");
function k(e) {
return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}
function D(e, r = {}, a) {
const d = x(r);
return `<${d ? `${e} ${d}` : e}>${Array.isArray(a) ? a.join("") : a || ""}</${e}>`;
const y = (e) => Object.fromEntries(Object.entries(e).filter(([r, a]) => a !== void 0));
function K(e, r = {}, a) {
const R = z(r), b = R ? `${e} ${R}` : e;
return G.includes(e) ? `<${b}>` : `<${b}>${Array.isArray(a) ? a.join("") : a || ""}</${e}>`;
}
function G(e = {}) {
function F(e = {}) {
let r = 0;
const {
renderFn: a = D,
textFn: d = U,
resolvers: m = {},
optimizeImages: s = !1
} = e, h = (t) => (i) => a(t, { ...i.attrs, key: `${t}-${r}` }, i.children || null), E = (t) => {
const { src: i, alt: l, ...f } = t.attrs || {};
let b = i, S = {};
if (s) {
const { src: y, attrs: H } = w(i, s);
b = y, S = H;
renderFn: a = K,
textFn: R = k,
resolvers: b = {},
optimizeImages: l = !1,
keyedResolvers: d = !1
} = e, u = (t) => (i) => {
const s = i.attrs || {};
return d && (s.key = `${t}-${r}`), a(t, s, i.children || null);
}, c = (t) => {
const { src: i, alt: s, title: o, srcset: $, sizes: h } = t.attrs || {};
let I = i, O = {};
if (l) {
const { src: H, attrs: P } = U(i, l);
I = H, O = P;
}
const C = {
src: b,
alt: l || "",
key: `img-${r}`,
...f,
...S
d && (O = {
...O,
key: `img-${r}`
});
const x = {
src: I,
alt: s,
title: o,
srcset: $,
sizes: h,
...O
};
return a("img", C, "");
}, c = (t) => {
const { level: i, ...l } = t.attrs || {};
return a(`h${i}`, { ...l, key: `h${i}-${r}` }, t.children);
return a("img", y(x));
}, g = (t) => {
var i, l, f, b;
return a("span", {
"data-type": "emoji",
"data-name": (i = t.attrs) == null ? void 0 : i.name,
emoji: (l = t.attrs) == null ? void 0 : l.emoji,
key: `emoji-${r}`
}, a("img", {
src: (f = t.attrs) == null ? void 0 : f.fallbackImage,
alt: (b = t.attrs) == null ? void 0 : b.alt,
const { level: i, ...s } = t.attrs || {}, o = {
...s
};
return d && (o.key = `h${i}-${r}`), a(`h${i}`, o, t.children);
}, S = (t) => {
var o, $, h, I;
const i = a("img", {
src: (o = t.attrs) == null ? void 0 : o.fallbackImage,
alt: ($ = t.attrs) == null ? void 0 : $.alt,
style: "width: 1.25em; height: 1.25em; vertical-align: text-top",
draggable: "false",
loading: "lazy"
}, ""));
}, $ = (t) => a("pre", { ...t.attrs, key: `code-${r}` }, a("code", { key: `code-${r}` }, t.children || "")), n = (t, i = !1) => ({ text: l, attrs: f }) => a(t, i ? {
style: P(f),
key: `${t}-${r}`
} : { ...f, key: `${t}-${r}` }, l), R = (t) => v(t), O = (t) => {
const { marks: i, ...l } = t;
}), s = {
"data-type": "emoji",
"data-name": (h = t.attrs) == null ? void 0 : h.name,
"data-emoji": (I = t.attrs) == null ? void 0 : I.emoji
};
return d && (s.key = `emoji-${r}`), a("span", s, i);
}, E = (t) => a("pre", {
...t.attrs,
key: `code-${r}`
}, a("code", { key: `code-${r}` }, t.children || "")), n = (t, i = !1) => ({ text: s, attrs: o }) => {
const { class: $, id: h, ...I } = o || {}, O = i ? {
class: $,
id: h,
style: p(I) || void 0
} : o || {};
return d && (O.key = `${t}-${r}`), a(t, y(O), s);
}, L = (t) => N(t), T = (t) => {
const { marks: i, ...s } = t;
return "text" in t ? i ? i.reduce(
(f, b) => R({ ...b, text: f }),
(o, $) => L({ ...$, text: o }),
// Fix: Ensure render function returns a string
R({ ...l, children: l.children })
L({ ...s, children: s.children })
// Fix: Cast children to string
) : d(l.text) : "";
}, I = (t) => {
const { linktype: i, href: l, anchor: f, ...b } = t.attrs || {};
let S = "";
) : R(s.text) : "";
}, v = (t) => {
const { linktype: i, href: s, anchor: o, ...$ } = t.attrs || {};
let h = "";
switch (i) {
case A.ASSET:
case A.URL:
S = l;
h = s;
break;
case A.EMAIL:
S = `mailto:${l}`;
h = `mailto:${s}`;
break;
case A.STORY:
S = l;
h = s;
break;
}
return f && (S = `${S}#${f}`), a("a", { ...b, href: S, key: `a-${r}` }, t.text);
}, L = (t) => {
var i, l;
return o && (h = `${h}#${o}`), a("a", { ...$, href: h, key: `a-${r}` }, t.text);
}, w = (t) => {
var i, s;
return console.warn("[StoryblokRichtText] - BLOK resolver is not available for vanilla usage"), a("span", {
blok: (i = t == null ? void 0 : t.attrs) == null ? void 0 : i.body[0],
id: (l = t.attrs) == null ? void 0 : l.id,
id: (s = t.attrs) == null ? void 0 : s.id,
key: `component-${r}`,
style: "display: none"
}, "");
}, j = new Map([
[o.DOCUMENT, h("div")],
[o.HEADING, c],
[o.PARAGRAPH, h("p")],
[o.UL_LIST, h("ul")],
[o.OL_LIST, h("ol")],
[o.LIST_ITEM, h("li")],
[o.IMAGE, E],
[o.EMOJI, g],
[o.CODE_BLOCK, $],
[o.HR, h("hr")],
[o.BR, h("br")],
[o.QUOTE, h("blockquote")],
[o.COMPONENT, L],
[N.TEXT, O],
[u.LINK, I],
[u.ANCHOR, I],
[u.STYLED, n("span", !0)],
[u.BOLD, n("strong")],
[u.TEXT_STYLE, n("span", !0)],
[u.ITALIC, n("em")],
[u.UNDERLINE, n("u")],
[u.STRIKE, n("s")],
[u.CODE, n("code")],
[u.SUPERSCRIPT, n("sup")],
[u.SUBSCRIPT, n("sub")],
[u.HIGHLIGHT, n("mark")],
...Object.entries(m).map(([t, i]) => [t, i])
});
}, C = new Map([
[f.DOCUMENT, u("div")],
[f.HEADING, g],
[f.PARAGRAPH, u("p")],
[f.UL_LIST, u("ul")],
[f.OL_LIST, u("ol")],
[f.LIST_ITEM, u("li")],
[f.IMAGE, c],
[f.EMOJI, S],
[f.CODE_BLOCK, E],
[f.HR, u("hr")],
[f.BR, u("br")],
[f.QUOTE, u("blockquote")],
[f.COMPONENT, w],
[_.TEXT, T],
[m.LINK, v],
[m.ANCHOR, v],
[m.STYLED, n("span", !0)],
[m.BOLD, n("strong")],
[m.TEXT_STYLE, n("span", !0)],
[m.ITALIC, n("em")],
[m.UNDERLINE, n("u")],
[m.STRIKE, n("s")],
[m.CODE, n("code")],
[m.SUPERSCRIPT, n("sup")],
[m.SUBSCRIPT, n("sub")],
[m.HIGHLIGHT, n("mark")],
...Object.entries(b).map(([t, i]) => [t, i])
]);
function T(t) {
function j(t) {
r += 1;
const i = j.get(t.type);
const i = C.get(t.type);
if (!i)

@@ -154,23 +192,23 @@ return console.error("<Storyblok>", `No resolver found for node type ${t.type}`), "";

return i(t);
const l = t.content ? t.content.map(v) : void 0;
const s = t.content ? t.content.map(N) : void 0;
return i({
...t,
children: l
children: s
// Fix: Update the type of 'children' to Node[]
});
}
function v(t) {
return Array.isArray(t) ? t.map(T) : T(t);
function N(t) {
return Array.isArray(t) ? t.map(j) : j(t);
}
return {
render: v
render: N
};
}
export {
o as BlockTypes,
_ as LinkTargets,
f as BlockTypes,
D as LinkTargets,
A as LinkTypes,
u as MarkTypes,
N as TextTypes,
G as richTextResolver
m as MarkTypes,
_ as TextTypes,
F as richTextResolver
};

@@ -7,2 +7,2 @@ /**

*/
(function(m,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(m=typeof globalThis<"u"?globalThis:m||self,n(m.StoryblokRichText={}))})(this,function(m){"use strict";var n=(e=>(e.DOCUMENT="doc",e.HEADING="heading",e.PARAGRAPH="paragraph",e.QUOTE="blockquote",e.OL_LIST="ordered_list",e.UL_LIST="bullet_list",e.LIST_ITEM="list_item",e.CODE_BLOCK="code_block",e.HR="horizontal_rule",e.BR="hard_break",e.IMAGE="image",e.EMOJI="emoji",e.COMPONENT="blok",e))(n||{}),u=(e=>(e.BOLD="bold",e.STRONG="strong",e.STRIKE="strike",e.UNDERLINE="underline",e.ITALIC="italic",e.CODE="code",e.LINK="link",e.ANCHOR="anchor",e.STYLED="styled",e.SUPERSCRIPT="superscript",e.SUBSCRIPT="subscript",e.TEXT_STYLE="textStyle",e.HIGHLIGHT="highlight",e))(u||{}),A=(e=>(e.TEXT="text",e))(A||{}),j=(e=>(e.SELF="_self",e.BLANK="_blank",e))(j||{}),T=(e=>(e.URL="url",e.STORY="story",e.ASSET="asset",e.EMAIL="email",e))(T||{});function C(e,r){if(!r)return{src:e,attrs:{}};let a=0,R=0;const g={},c=[];function f(o,d,$,s,E){typeof o!="number"||o<=d||o>=$?console.warn(`[StoryblokRichText] - ${s.charAt(0).toUpperCase()+s.slice(1)} value must be a number between ${d} and ${$} (inclusive)`):E.push(`${s}(${o})`)}if(typeof r=="object"){if(typeof r.width=="number"&&r.width>0?(g.width=r.width,a=r.width):console.warn("[StoryblokRichText] - Width value must be a number greater than 0"),r.height&&typeof r.height=="number"&&r.height>0?(g.height=r.height,R=r.height):console.warn("[StoryblokRichText] - Height value must be a number greater than 0"),r.loading&&["lazy","eager"].includes(r.loading)&&(g.loading=r.loading),r.class&&(g.class=r.class),r.filters){const{filters:o}=r||{},{blur:d,brightness:$,fill:s,format:E,grayscale:O,quality:L,rotate:v}=o||{};d&&f(d,0,100,"blur",c),L&&f(L,0,100,"quality",c),$&&f($,0,100,"brightness",c),s&&c.push(`fill(${s})`),O&&c.push("grayscale()"),v&&[0,90,180,270].includes(r.filters.rotate||0)&&c.push(`rotate(${v})`),E&&["webp","png","jpeg"].includes(E)&&c.push(`format(${E})`)}r.srcset&&(g.srcset=r.srcset.map(o=>{if(typeof o=="number")return`${e}/m/${o}x0/${c.length>0?"filters:"+c.join(":"):""} ${o}w`;if(Array.isArray(o)&&o.length===2){const[d,$]=o;return`${e}/m/${d}x${$}/${c.length>0?"filters:"+c.join(":"):""} ${d}w`}}).join(", ")),r.sizes&&(g.sizes=r.sizes.join(", "))}let I=`${e}/m/`;return a>0&&R>0&&(I=`${I}${a}x${R}/`),c.length>0&&(I=`${I}filters:${c.join(":")}`),{src:I,attrs:g}}const H=(e={})=>Object.keys(e).map(r=>`${r}="${e[r]}"`).join(" "),_=(e={})=>Object.keys(e).map(r=>`${r}: ${e[r]}`).join("; ");function w(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function x(e,r={},a){const R=H(r);return`<${R?`${e} ${R}`:e}>${Array.isArray(a)?a.join(""):a||""}</${e}>`}function P(e={}){let r=0;const{renderFn:a=x,textFn:R=w,resolvers:g={},optimizeImages:c=!1}=e,f=t=>i=>a(t,{...i.attrs,key:`${t}-${r}`},i.children||null),I=t=>{const{src:i,alt:l,...h}=t.attrs||{};let b=i,S={};if(c){const{src:p,attrs:k}=C(i,c);b=p,S=k}const D={src:b,alt:l||"",key:`img-${r}`,...h,...S};return a("img",D,"")},o=t=>{const{level:i,...l}=t.attrs||{};return a(`h${i}`,{...l,key:`h${i}-${r}`},t.children)},d=t=>{var i,l,h,b;return a("span",{"data-type":"emoji","data-name":(i=t.attrs)==null?void 0:i.name,emoji:(l=t.attrs)==null?void 0:l.emoji,key:`emoji-${r}`},a("img",{src:(h=t.attrs)==null?void 0:h.fallbackImage,alt:(b=t.attrs)==null?void 0:b.alt,style:"width: 1.25em; height: 1.25em; vertical-align: text-top",draggable:"false",loading:"lazy"},""))},$=t=>a("pre",{...t.attrs,key:`code-${r}`},a("code",{key:`code-${r}`},t.children||"")),s=(t,i=!1)=>({text:l,attrs:h})=>a(t,i?{style:_(h),key:`${t}-${r}`}:{...h,key:`${t}-${r}`},l),E=t=>y(t),O=t=>{const{marks:i,...l}=t;return"text"in t?i?i.reduce((h,b)=>E({...b,text:h}),E({...l,children:l.children})):R(l.text):""},L=t=>{const{linktype:i,href:l,anchor:h,...b}=t.attrs||{};let S="";switch(i){case T.ASSET:case T.URL:S=l;break;case T.EMAIL:S=`mailto:${l}`;break;case T.STORY:S=l;break}return h&&(S=`${S}#${h}`),a("a",{...b,href:S,key:`a-${r}`},t.text)},v=t=>{var i,l;return console.warn("[StoryblokRichtText] - BLOK resolver is not available for vanilla usage"),a("span",{blok:(i=t==null?void 0:t.attrs)==null?void 0:i.body[0],id:(l=t.attrs)==null?void 0:l.id,key:`component-${r}`,style:"display: none"},"")},U=new Map([[n.DOCUMENT,f("div")],[n.HEADING,o],[n.PARAGRAPH,f("p")],[n.UL_LIST,f("ul")],[n.OL_LIST,f("ol")],[n.LIST_ITEM,f("li")],[n.IMAGE,I],[n.EMOJI,d],[n.CODE_BLOCK,$],[n.HR,f("hr")],[n.BR,f("br")],[n.QUOTE,f("blockquote")],[n.COMPONENT,v],[A.TEXT,O],[u.LINK,L],[u.ANCHOR,L],[u.STYLED,s("span",!0)],[u.BOLD,s("strong")],[u.TEXT_STYLE,s("span",!0)],[u.ITALIC,s("em")],[u.UNDERLINE,s("u")],[u.STRIKE,s("s")],[u.CODE,s("code")],[u.SUPERSCRIPT,s("sup")],[u.SUBSCRIPT,s("sub")],[u.HIGHLIGHT,s("mark")],...Object.entries(g).map(([t,i])=>[t,i])]);function N(t){r+=1;const i=U.get(t.type);if(!i)return console.error("<Storyblok>",`No resolver found for node type ${t.type}`),"";if(t.type==="text")return i(t);const l=t.content?t.content.map(y):void 0;return i({...t,children:l})}function y(t){return Array.isArray(t)?t.map(N):N(t)}return{render:y}}m.BlockTypes=n,m.LinkTargets=j,m.LinkTypes=T,m.MarkTypes=u,m.TextTypes=A,m.richTextResolver=P,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})});
(function(d,L){typeof exports=="object"&&typeof module<"u"?L(exports):typeof define=="function"&&define.amd?define(["exports"],L):(d=typeof globalThis<"u"?globalThis:d||self,L(d.StoryblokRichText={}))})(this,function(d){"use strict";function L(e,r){if(!r)return{src:e,attrs:{}};let n=0,E=0;const b={},a=[];function S(o,g,R,I,l){typeof o!="number"||o<=g||o>=R?console.warn(`[StoryblokRichText] - ${I.charAt(0).toUpperCase()+I.slice(1)} value must be a number between ${g} and ${R} (inclusive)`):l.push(`${I}(${o})`)}if(typeof r=="object"){if(typeof r.width=="number"&&r.width>0?(b.width=r.width,n=r.width):console.warn("[StoryblokRichText] - Width value must be a number greater than 0"),r.height&&typeof r.height=="number"&&r.height>0?(b.height=r.height,E=r.height):console.warn("[StoryblokRichText] - Height value must be a number greater than 0"),r.loading&&["lazy","eager"].includes(r.loading)&&(b.loading=r.loading),r.class&&(b.class=r.class),r.filters){const{filters:o}=r||{},{blur:g,brightness:R,fill:I,format:l,grayscale:y,quality:j,rotate:A}=o||{};g&&S(g,0,100,"blur",a),j&&S(j,0,100,"quality",a),R&&S(R,0,100,"brightness",a),I&&a.push(`fill(${I})`),y&&a.push("grayscale()"),A&&[0,90,180,270].includes(r.filters.rotate||0)&&a.push(`rotate(${A})`),l&&["webp","png","jpeg"].includes(l)&&a.push(`format(${l})`)}r.srcset&&(b.srcset=r.srcset.map(o=>{if(typeof o=="number")return`${e}/m/${o}x0/${a.length>0?`filters:${a.join(":")}`:""} ${o}w`;if(Array.isArray(o)&&o.length===2){const[g,R]=o;return`${e}/m/${g}x${R}/${a.length>0?`filters:${a.join(":")}`:""} ${g}w`}else{console.warn("[StoryblokRichText] - srcset entry must be a number or a tuple of two numbers");return}}).join(", ")),r.sizes&&(b.sizes=r.sizes.join(", "))}let h=`${e}/m/`;return n>0&&E>0&&(h=`${h}${n}x${E}/`),a.length>0&&(h=`${h}filters:${a.join(":")}`),{src:h,attrs:b}}var c=(e=>(e.DOCUMENT="doc",e.HEADING="heading",e.PARAGRAPH="paragraph",e.QUOTE="blockquote",e.OL_LIST="ordered_list",e.UL_LIST="bullet_list",e.LIST_ITEM="list_item",e.CODE_BLOCK="code_block",e.HR="horizontal_rule",e.BR="hard_break",e.IMAGE="image",e.EMOJI="emoji",e.COMPONENT="blok",e))(c||{}),f=(e=>(e.BOLD="bold",e.STRONG="strong",e.STRIKE="strike",e.UNDERLINE="underline",e.ITALIC="italic",e.CODE="code",e.LINK="link",e.ANCHOR="anchor",e.STYLED="styled",e.SUPERSCRIPT="superscript",e.SUBSCRIPT="subscript",e.TEXT_STYLE="textStyle",e.HIGHLIGHT="highlight",e))(f||{}),N=(e=>(e.TEXT="text",e))(N||{}),w=(e=>(e.SELF="_self",e.BLANK="_blank",e))(w||{}),O=(e=>(e.URL="url",e.STORY="story",e.ASSET="asset",e.EMAIL="email",e))(O||{});const x=["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],P=(e={})=>Object.keys(e).map(r=>`${r}="${e[r]}"`).join(" "),p=(e={})=>Object.keys(e).map(r=>`${r}: ${e[r]}`).join("; ");function U(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}const C=e=>Object.fromEntries(Object.entries(e).filter(([r,n])=>n!==void 0));function k(e,r={},n){const E=P(r),b=E?`${e} ${E}`:e;return x.includes(e)?`<${b}>`:`<${b}>${Array.isArray(n)?n.join(""):n||""}</${e}>`}function D(e={}){let r=0;const{renderFn:n=k,textFn:E=U,resolvers:b={},optimizeImages:a=!1,keyedResolvers:S=!1}=e,h=t=>i=>{const s=i.attrs||{};return S&&(s.key=`${t}-${r}`),n(t,s,i.children||null)},o=t=>{const{src:i,alt:s,title:u,srcset:$,sizes:m}=t.attrs||{};let T=i,v={};if(a){const{src:F,attrs:Y}=L(i,a);T=F,v=Y}S&&(v={...v,key:`img-${r}`});const K={src:T,alt:s,title:u,srcset:$,sizes:m,...v};return n("img",C(K))},g=t=>{const{level:i,...s}=t.attrs||{},u={...s};return S&&(u.key=`h${i}-${r}`),n(`h${i}`,u,t.children)},R=t=>{var u,$,m,T;const i=n("img",{src:(u=t.attrs)==null?void 0:u.fallbackImage,alt:($=t.attrs)==null?void 0:$.alt,style:"width: 1.25em; height: 1.25em; vertical-align: text-top",draggable:"false",loading:"lazy"}),s={"data-type":"emoji","data-name":(m=t.attrs)==null?void 0:m.name,"data-emoji":(T=t.attrs)==null?void 0:T.emoji};return S&&(s.key=`emoji-${r}`),n("span",s,i)},I=t=>n("pre",{...t.attrs,key:`code-${r}`},n("code",{key:`code-${r}`},t.children||"")),l=(t,i=!1)=>({text:s,attrs:u})=>{const{class:$,id:m,...T}=u||{},v=i?{class:$,id:m,style:p(T)||void 0}:u||{};return S&&(v.key=`${t}-${r}`),n(t,C(v),s)},y=t=>_(t),j=t=>{const{marks:i,...s}=t;return"text"in t?i?i.reduce((u,$)=>y({...$,text:u}),y({...s,children:s.children})):E(s.text):""},A=t=>{const{linktype:i,href:s,anchor:u,...$}=t.attrs||{};let m="";switch(i){case O.ASSET:case O.URL:m=s;break;case O.EMAIL:m=`mailto:${s}`;break;case O.STORY:m=s;break}return u&&(m=`${m}#${u}`),n("a",{...$,href:m,key:`a-${r}`},t.text)},G=t=>{var i,s;return console.warn("[StoryblokRichtText] - BLOK resolver is not available for vanilla usage"),n("span",{blok:(i=t==null?void 0:t.attrs)==null?void 0:i.body[0],id:(s=t.attrs)==null?void 0:s.id,key:`component-${r}`,style:"display: none"})},z=new Map([[c.DOCUMENT,h("div")],[c.HEADING,g],[c.PARAGRAPH,h("p")],[c.UL_LIST,h("ul")],[c.OL_LIST,h("ol")],[c.LIST_ITEM,h("li")],[c.IMAGE,o],[c.EMOJI,R],[c.CODE_BLOCK,I],[c.HR,h("hr")],[c.BR,h("br")],[c.QUOTE,h("blockquote")],[c.COMPONENT,G],[N.TEXT,j],[f.LINK,A],[f.ANCHOR,A],[f.STYLED,l("span",!0)],[f.BOLD,l("strong")],[f.TEXT_STYLE,l("span",!0)],[f.ITALIC,l("em")],[f.UNDERLINE,l("u")],[f.STRIKE,l("s")],[f.CODE,l("code")],[f.SUPERSCRIPT,l("sup")],[f.SUBSCRIPT,l("sub")],[f.HIGHLIGHT,l("mark")],...Object.entries(b).map(([t,i])=>[t,i])]);function H(t){r+=1;const i=z.get(t.type);if(!i)return console.error("<Storyblok>",`No resolver found for node type ${t.type}`),"";if(t.type==="text")return i(t);const s=t.content?t.content.map(_):void 0;return i({...t,children:s})}function _(t){return Array.isArray(t)?t.map(H):H(t)}return{render:_}}d.BlockTypes=c,d.LinkTargets=w,d.LinkTypes=O,d.MarkTypes=f,d.TextTypes=N,d.richTextResolver=D,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});

@@ -161,3 +161,3 @@ export declare enum BlockTypes {

*/
export interface StoryblokRichTextOptions<T = string, S = (tag: string, attrs: Record<string, any>, text: string) => T> {
export interface StoryblokRichTextOptions<T = string, S = (tag: string, attrs: Record<string, any>, children?: T) => T> {
/**

@@ -169,3 +169,3 @@ * Defines the function that will be used to render the final HTML string (vanilla) or Framework component (React, Vue).

* ```typescript
* const renderFn = (tag: string, attrs: Record<string, any>, text: string) => {
* const renderFn = (tag: string, attrs: Record<string, any>, text?: string) => {
* return `<${tag} ${Object.keys(attrs).map(key => `${key}="${attrs[key]}"`).join(' ')}>${text}</${tag}>`

@@ -194,3 +194,3 @@ * }

*/
textFn?: Function;
textFn?: (text: string) => T;
/**

@@ -236,2 +236,16 @@ * Defines the resolvers for each type of node.

optimizeImages?: boolean | Partial<StoryblokRichTextImageOptimizationOptions>;
/**
* Defines whether to use the key attribute in the resolvers for framework use cases.
* @default false
* @example
*
* ```typescript
*
* const options: StoryblokRichTextOptions = {
* renderFn: h,
* keyedResolvers: true
* }
* ```
*/
keyedResolvers?: boolean;
}
{
"name": "@storyblok/richtext",
"type": "module",
"version": "2.1.0",
"packageManager": "pnpm@9.1.4",
"version": "3.0.0",
"packageManager": "pnpm@9.12.2",
"description": "Storyblok RichText Resolver",
"author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
"license": "MIT",
"homepage": "https://github.com/storyblok/richtext#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/storyblok/richtext.git"
"url": "git+https://github.com/storyblok/richtext.git"
},
"license": "MIT",
"keywords": [

@@ -58,36 +58,26 @@ "storyblok",

"devDependencies": {
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@storyblok/vue": "^8.0.8",
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@storyblok/eslint-config": "^0.3.0",
"@storyblok/vue": "^8.1.4",
"@vitejs/plugin-basic-ssl": "^1.1.0",
"@vitest/coverage-v8": "^2.0.4",
"@vitest/ui": "^2.0.4",
"@vitest/coverage-v8": "^2.1.3",
"@vitest/ui": "^2.1.3",
"eslint": "^9.13.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-vue": "^9.27.0",
"eslint-plugin-vue": "^9.29.1",
"kolorist": "^1.8.0",
"lint-staged": "^15.2.7",
"lint-staged": "^15.2.10",
"pathe": "^1.1.2",
"prettier": "^3.3.3",
"release-it": "^17.6.0",
"typescript": "^5.5.4",
"vite": "^5.3.5",
"vite-plugin-banner": "^0.7.1",
"vite-plugin-dts": "4.0.3",
"vite-plugin-inspect": "^0.8.5",
"release-it": "^17.10.0",
"typescript": "^5.6.3",
"vite": "^5.4.10",
"vite-plugin-banner": "^0.8.0",
"vite-plugin-dts": "4.3.0",
"vite-plugin-inspect": "^0.8.7",
"vite-plugin-qrcode": "^0.2.3",
"vitest": "^2.0.4",
"vue": "^3.4.34"
"vitest": "^2.1.3",
"vue": "^3.5.12"
},
"dependencies": {
"consola": "^3.2.3"
},
"lint-staged": {
"*.{vue,js,css,ts}": [
"prettier --write",
"eslint"
],
"*.md": [
"prettier --write"
]
},
"commitlint": {

@@ -97,43 +87,3 @@ "extends": [

]
},
"eslintConfig": {
"root": true,
"parser": "vue-eslint-parser",
"env": {
"node": true,
"vue/setup-compiler-macros": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"prettier"
],
"parserOptions": {
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"ignorePatterns": "dist/",
"rules": {
"vue/multi-word-component-names": 0
}
},
"prettier": {
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": false
},
"release": {
"branches": [
"main",
{
"name": "next",
"prerelease": true
},
{
"name": "beta",
"prerelease": true
}
]
}
}

@@ -32,3 +32,2 @@ ![](/.github/repo-banner.png)

## 🚀 Usage

@@ -38,3 +37,2 @@

### Installation

@@ -61,7 +59,7 @@

```ts
import { richTextResolver } from '@storyblok/richtext'
import { richTextResolver } from '@storyblok/richtext';
const { render } = richTextResolver()
const { render } = richTextResolver();
const html = render(doc)
const html = render(doc);

@@ -72,3 +70,3 @@ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `

</div>
`
`;
```

@@ -81,3 +79,3 @@

```ts
import { MarkTypes, richTextResolver } from '@storyblok/richtext'
import { MarkTypes, richTextResolver } from '@storyblok/richtext';

@@ -87,6 +85,6 @@ const html = richTextResolver({

[MarkTypes.LINK]: (node) => {
return `<button href="${node.attrs?.href}" target="${node.attrs?.target}">${node.children}</button>`
return `<button href="${node.attrs?.href}" target="${node.attrs?.target}">${node.children}</button>`;
},
},
}).render(doc)
}).render(doc);
```

@@ -109,8 +107,8 @@

[MarkTypes.LINK]: (node: Node<string>) => {
return `<button href="${node.attrs?.href}" target="${node.attrs?.target}">${node.children}</button>`
return `<button href="${node.attrs?.href}" target="${node.attrs?.target}">${node.children}</button>`;
},
},
}
};
const html = richTextResolver<string>(options).render(doc)
const html = richTextResolver<string>(options).render(doc);
```

@@ -122,6 +120,16 @@

renderFn: h,
}
const root = () => richTextResolver<VNode>(options).render(doc)
keyedResolvers: true,
};
const root = () => richTextResolver<VNode>(options).render(doc);
```
```ts
// React
const options: StoryblokRichTextOptions<React.ReactElement> = {
renderFn: React.createElement,
keyedResolvers: true,
};
const root = () => richTextResolver<React.ReactElement>(options).render(doc);
```
## Optimize Images

@@ -132,3 +140,3 @@

```ts
import { richTextResolver } from '@storyblok/richtext'
import { richTextResolver } from '@storyblok/richtext';

@@ -145,3 +153,2 @@ const html = richTextResolver({

format: 'webp',
blur: 120
quality: 10,

@@ -153,3 +160,3 @@ grayscale: true,

},
}).render(doc)
}).render(doc);
```

@@ -159,3 +166,3 @@

> [!WARNING]
> [!WARNING]
> This package does not provide proper HTML sanitization by default

@@ -178,5 +185,5 @@

- **sanitize-html**: A simple HTML sanitizer with a flexible API that can adjust to a wide range of applications.
GitHub: [sanitize-html](https://github.com/apostrophecms/sanitize-html)
GitHub: [sanitize-html](https://github.com/apostrophecms/sanitize-html)
### Example Usage

@@ -192,7 +199,7 @@

const sanitizedHTML = sanitizeHtml(html, {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img', 'figure', 'figcaption']),
allowedAttributes: {
...sanitizeHtml.defaults.allowedAttributes,
'img': ['src', 'alt', 'title']
}
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img', 'figure', 'figcaption']),
allowedAttributes: {
...sanitizeHtml.defaults.allowedAttributes,
img: ['src', 'alt', 'title']
}
});

@@ -203,3 +210,2 @@

## Setup

@@ -281,3 +287,2 @@

## 🔗 Related Links

@@ -284,0 +289,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡ī¸ by Socket Inc