Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@portabletext/to-html

Package Overview
Dependencies
Maintainers
10
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@portabletext/to-html - npm Package Compare versions

Comparing version
4.0.0
to
4.0.1
+12
-12
dist/pt-to-html.js

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

"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var toolkit = require("@portabletext/toolkit");
import { nestLists, isPortableTextToolkitList, isPortableTextListItemBlock, isPortableTextToolkitSpan, isPortableTextBlock, isPortableTextToolkitTextNode, spanToPlainText, buildMarksTree } from "@portabletext/toolkit";
const allowedProtocols = ["http", "https", "mailto", "tel"], charMap = {

@@ -106,3 +104,3 @@ "&": "amp",

onMissingComponent: missingComponentHandler = printWarning
} = options, handleMissingComponent = missingComponentHandler || noop, blocks = Array.isArray(value) ? value : [value], nested = toolkit.nestLists(blocks, "html"), components = componentOverrides ? mergeComponents(defaultComponents, componentOverrides) : defaultComponents, renderNode = getNodeRenderer(components, handleMissingComponent);
} = options, handleMissingComponent = missingComponentHandler || noop, blocks = Array.isArray(value) ? value : [value], nested = nestLists(blocks, "html"), components = componentOverrides ? mergeComponents(defaultComponents, componentOverrides) : defaultComponents, renderNode = getNodeRenderer(components, handleMissingComponent);
return nested.map(

@@ -115,3 +113,3 @@ (node, index) => renderNode({ node, index, isInline: !1, renderNode })

const { node, index, isInline } = options;
return toolkit.isPortableTextToolkitList(node) ? renderList(node, index) : toolkit.isPortableTextListItemBlock(node) ? renderListItem(node, index) : toolkit.isPortableTextToolkitSpan(node) ? renderSpan(node) : toolkit.isPortableTextBlock(node) ? renderBlock(node, index, isInline) : toolkit.isPortableTextToolkitTextNode(node) ? renderText(node) : renderCustomBlock(node, index, isInline);
return isPortableTextToolkitList(node) ? renderList(node, index) : isPortableTextListItemBlock(node) ? renderListItem(node, index) : isPortableTextToolkitSpan(node) ? renderSpan(node) : isPortableTextBlock(node) ? renderBlock(node, index, isInline) : isPortableTextToolkitTextNode(node) ? renderText(node) : renderCustomBlock(node, index, isInline);
}

@@ -153,3 +151,3 @@ function renderListItem(node, index) {

return span === components.unknownMark && handleMissingComponent(unknownMarkWarning(markType), { nodeType: "mark", type: markType }), span({
text: toolkit.spanToPlainText(node),
text: spanToPlainText(node),
value: markDef,

@@ -193,3 +191,3 @@ markType,

function serializeBlock(options) {
const { node, index, isInline, renderNode } = options, children = toolkit.buildMarksTree(node).map(
const { node, index, isInline, renderNode } = options, children = buildMarksTree(node).map(
(child, i) => renderNode({ node: child, isInline: !0, index: i, renderNode })

@@ -207,7 +205,9 @@ );

}
exports.defaultComponents = defaultComponents;
exports.escapeHTML = escapeHTML;
exports.mergeComponents = mergeComponents;
exports.toHTML = toHTML;
exports.uriLooksSafe = uriLooksSafe;
export {
defaultComponents,
escapeHTML,
mergeComponents,
toHTML,
uriLooksSafe
};
//# sourceMappingURL=pt-to-html.js.map
{
"name": "@portabletext/to-html",
"version": "4.0.0",
"version": "4.0.1",
"description": "Render Portable Text to HTML",

@@ -19,8 +19,6 @@ "keywords": [

"sideEffects": false,
"type": "commonjs",
"type": "module",
"exports": {
".": {
"source": "./src/index.ts",
"import": "./dist/pt-to-html.mjs",
"require": "./dist/pt-to-html.js",
"default": "./dist/pt-to-html.js"

@@ -31,3 +29,2 @@ },

"main": "./dist/pt-to-html.js",
"module": "./dist/pt-to-html.mjs",
"types": "./dist/pt-to-html.d.ts",

@@ -59,9 +56,2 @@ "files": [

},
"tap": {
"allow-incomplete-coverage": true,
"node-arg": [
"-r",
"esbuild-register"
]
},
"dependencies": {

@@ -75,8 +65,8 @@ "@portabletext/toolkit": "^4.0.0",

"@sanity/browserslist-config": "^1.0.5",
"@sanity/pkg-utils": "^8.1.29",
"@sanity/pkg-utils": "^9.0.1",
"@sanity/prettier-config": "^2.0.1",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@vitest/coverage-v8": "^4.0.6",
"esbuild": "^0.25.12",
"esbuild-register": "^3.6.0",
"eslint": "^8.57.1",

@@ -88,5 +78,5 @@ "eslint-config-prettier": "^10.1.8",

"rimraf": "^4.4.1",
"tap": "^21.1.3",
"typedoc": "^0.28.14",
"typescript": "5.9.3"
"typescript": "5.9.3",
"vitest": "^4.0.6"
},

@@ -101,4 +91,4 @@ "engines": {

"build": "run-s clean pkg:build pkg:check",
"clean": "rimraf .nyc_output dist coverage",
"coverage": "tap test/*.test.* --coverage-report=html",
"clean": "rimraf dist coverage",
"coverage": "vitest run --coverage",
"docs:build": "typedoc",

@@ -110,5 +100,5 @@ "format": "prettier --write --cache --ignore-unknown .",

"release": "changeset publish",
"test": "tap test/*.test.*",
"test": "vitest run",
"type-check": "tsc --noEmit"
}
}
import type {ArbitraryTypedObject} from '@portabletext/types'
import type {PortableTextBlock} from '@portabletext/types'
import type {PortableTextBlockStyle} from '@portabletext/types'
import type {PortableTextListItemBlock} from '@portabletext/types'
import type {PortableTextListItemType} from '@portabletext/types'
import type {ToolkitPortableTextList} from '@portabletext/toolkit'
import type {ToolkitPortableTextListItem} from '@portabletext/toolkit'
import type {TypedObject} from '@portabletext/types'
export declare const defaultComponents: PortableTextHtmlComponents
export declare function escapeHTML(str: string): string
/**
* A virtual "list" node for Portable Text - not strictly part of Portable Text,
* but generated by this library to ease the rendering of lists in HTML etc
*/
export declare type HtmlPortableTextList = ToolkitPortableTextList
/**
* A virtual "list item" node for Portable Text - not strictly any different from a
* regular Portable Text Block, but we can guarantee that it has a `listItem` property.
*/
export declare type HtmlPortableTextListItem = ToolkitPortableTextListItem
export declare function mergeComponents(
parent: PortableTextHtmlComponents,
overrides: PortableTextComponents,
): PortableTextHtmlComponents
export declare type MissingComponentHandler = (
message: string,
options: {
type: string
nodeType: NodeType
},
) => void
/**
* Function that renders any node that might appear in a portable text array or block,
* including virtual "toolkit"-nodes like lists and nested spans
*/
export declare type NodeRenderer = <T extends TypedObject>(options: Serializable<T>) => string
export declare type NodeType = 'block' | 'mark' | 'blockStyle' | 'listStyle' | 'listItemStyle'
/**
* Component function type for rendering portable text blocks (paragraphs, headings, blockquotes etc)
*/
export declare type PortableTextBlockComponent = PortableTextComponent<PortableTextBlock>
/**
* Generic type for portable text components that takes blocks/inline blocks
*
* @template N Node types we expect to be rendering (`PortableTextBlock` should usually be part of this)
*/
export declare type PortableTextComponent<N> = (options: PortableTextComponentOptions<N>) => string
/**
* Options received by most Portable Text components
*
* @template T Type of data this component will receive in its `value` property
*/
export declare interface PortableTextComponentOptions<T> {
/**
* Data associated with this portable text node, eg the raw JSON value of a block/type
*/
value: T
/**
* Index within its parent
*/
index: number
/**
* Whether or not this node is "inline" - ie as a child of a text block,
* alongside text spans, or a block in and of itself.
*/
isInline: boolean
/**
* Serialized HTML of child nodes of this block/type
*/
children?: string
/**
* Function used to render any node that might appear in a portable text array or block,
* including virtual "toolkit"-nodes like lists and nested spans. You will rarely need
* to use this.
*/
renderNode: NodeRenderer
}
/**
* Object defining the different component functions to use for rendering various aspects
* of Portable Text and user-provided types, where only the overrides needs to be provided.
*/
export declare type PortableTextComponents = Partial<PortableTextHtmlComponents>
/**
* Object definining the different component functions to use for rendering various aspects
* of Portable Text and user-provided types.
*/
export declare interface PortableTextHtmlComponents {
/**
* Object of component functions that renders different types of objects that might appear
* both as part of the blocks array, or as inline objects _inside_ of a block,
* alongside text spans.
*
* Use the `isInline` property to check whether or not this is an inline object or a block
*
* The object has the shape `{typeName: ComponentFn}`, where `typeName` is the value set
* in individual `_type` attributes.
*/
types: Record<string, PortableTextTypeComponent | undefined>
/**
* Object of component functions that renders different types of marks that might appear in spans.
*
* The object has the shape `{markName: ComponentFn}`, where `markName` is the value set
* in individual `_type` attributes, values being stored in the parent blocks `markDefs`.
*/
marks: Record<string, PortableTextMarkComponent | undefined>
/**
* Object of component functions that renders blocks with different `style` properties.
*
* The object has the shape `{styleName: ComponentFn}`, where `styleName` is the value set
* in individual `style` attributes on blocks.
*
* Can also be set to a single component function, which would handle block styles of _any_ type.
*/
block:
| Record<PortableTextBlockStyle, PortableTextBlockComponent | undefined>
| PortableTextBlockComponent
/**
* Object of component functions used to render lists of different types (bulleted vs numbered,
* for instance, which by default is `<ul>` and `<ol>`, respectively)
*
* There is no actual "list" node type in the Portable Text specification, but a series of
* list item blocks with the same `level` and `listItem` properties will be grouped into a
* virtual one inside of this library.
*
* Can also be set to a single component function, which would handle lists of _any_ type.
*/
list:
| Record<PortableTextListItemType, PortableTextListComponent | undefined>
| PortableTextListComponent
/**
* Object of component functions used to render different list item styles.
*
* The object has the shape `{listItemType: ComponentFn}`, where `listItemType` is the value
* set in individual `listItem` attributes on blocks.
*
* Can also be set to a single component function, which would handle list items of _any_ type.
*/
listItem:
| Record<PortableTextListItemType, PortableTextListItemComponent | undefined>
| PortableTextListItemComponent
/**
* Component to use for rendering "hard breaks", eg `\n` inside of text spans
* Will by default render a `<br />`. Pass `false` to render as-is (`\n`)
*/
hardBreak: (() => string) | false
/**
* Used when rendering text nodes to HTML
*/
escapeHTML: (html: string) => string
/**
* Component function used when encountering a mark type there is no registered component for
* in the `components.marks` prop.
*/
unknownMark: PortableTextMarkComponent
/**
* Component function used when encountering an object type there is no registered component for
* in the `components.types` prop.
*/
unknownType: PortableTextComponent<UnknownNodeType>
/**
* Component function used when encountering a block style there is no registered component for
* in the `components.block` prop. Only used if `components.block` is an object.
*/
unknownBlockStyle: PortableTextComponent<PortableTextBlock>
/**
* Component function used when encountering a list style there is no registered component for
* in the `components.list` prop. Only used if `components.list` is an object.
*/
unknownList: PortableTextComponent<HtmlPortableTextList>
/**
* Component function used when encountering a list item style there is no registered component for
* in the `components.listItem` prop. Only used if `components.listItem` is an object.
*/
unknownListItem: PortableTextComponent<PortableTextListItemBlock>
}
/**
* Component function type for rendering (virtual, not part of the spec) portable text lists
*/
export declare type PortableTextListComponent = PortableTextComponent<HtmlPortableTextList>
/**
* Component function type for rendering portable text list items
*/
export declare type PortableTextListItemComponent = PortableTextComponent<PortableTextListItemBlock>
/**
* Component function type for rendering portable text marks and/or decorators
*
* @template M The mark type we expect
*/
export declare type PortableTextMarkComponent<M extends TypedObject = any> = (
options: PortableTextMarkComponentOptions<M>,
) => string
/**
* Options received by Portable Text mark components
*
* @template M Shape describing the data associated with this mark, if it is an annotation
*/
export declare interface PortableTextMarkComponentOptions<
M extends TypedObject = ArbitraryTypedObject,
> {
/**
* Mark definition, eg the actual data of the annotation. If the mark is a simple decorator, this will be `undefined`
*/
value?: M
/**
* Text content of this mark
*/
text: string
/**
* Key for this mark. The same key can be used amongst multiple text spans within the same block, so don't rely on this to be unique.
*/
markKey?: string
/**
* Type of mark - ie value of `_type` in the case of annotations, or the name of the decorator otherwise - eg `em`, `italic`.
*/
markType: string
/**
* Serialized HTML of child nodes of this mark
*/
children: string
/**
* Function used to render any node that might appear in a portable text array or block,
* including virtual "toolkit"-nodes like lists and nested spans. You will rarely need
* to use this.
*/
renderNode: NodeRenderer
}
/**
* Options for the Portable Text to HTML function
*/
export declare interface PortableTextOptions {
/**
* Component functions to use for rendering
*/
components?: Partial<PortableTextHtmlComponents>
/**
* Function to call when encountering unknown unknown types, eg blocks, marks,
* block style, list styles without an associated component function.
*
* Will print a warning message to the console by default.
* Pass `false` to disable.
*/
onMissingComponent?: MissingComponentHandler | false
}
export declare type PortableTextTypeComponent<V extends TypedObject = any> = (
options: PortableTextTypeComponentOptions<V>,
) => string
/**
* Options received by any user-defined type in the input array that is not a text block
*
* @template T Type of data this component will receive in its `value` property
*/
export declare type PortableTextTypeComponentOptions<T> = Omit<
PortableTextComponentOptions<T>,
'children'
>
export declare interface Serializable<T> {
node: T
index: number
isInline: boolean
renderNode: NodeRenderer
}
export declare interface SerializedBlock {
_key: string
children: string
index: number
isInline: boolean
node: PortableTextBlock | PortableTextListItemBlock
}
export declare function toHTML<B extends TypedObject = PortableTextBlock | ArbitraryTypedObject>(
value: B | B[],
options?: PortableTextOptions,
): string
/**
* Any node type that we can't identify - eg it has an `_type`,
* but we don't know anything about its other properties
*/
export declare type UnknownNodeType =
| {
[key: string]: unknown
_type: string
}
| TypedObject
export declare function uriLooksSafe(uri: string): boolean
export {}
import { nestLists, isPortableTextToolkitList, isPortableTextListItemBlock, isPortableTextToolkitSpan, isPortableTextBlock, isPortableTextToolkitTextNode, spanToPlainText, buildMarksTree } from "@portabletext/toolkit";
const allowedProtocols = ["http", "https", "mailto", "tel"], charMap = {
"&": "amp",
"<": "lt",
">": "gt",
'"': "quot",
"'": "#x27"
};
function escapeHTML(str) {
return replaceMultipleSpaces(str.replace(/[&<>"']/g, (s) => `&${charMap[s]};`));
}
function replaceMultipleSpaces(str) {
return str.replace(/ {2,}/g, (match) => `${"&nbsp;".repeat(match.length - 1)} `);
}
function uriLooksSafe(uri) {
const url = (uri || "").trim(), first = url.charAt(0);
if (first === "#" || first === "/")
return !0;
const colonIndex = url.indexOf(":");
if (colonIndex === -1)
return !0;
const proto = url.slice(0, colonIndex).toLowerCase();
if (allowedProtocols.indexOf(proto) !== -1)
return !0;
const queryIndex = url.indexOf("?");
if (queryIndex !== -1 && colonIndex > queryIndex)
return !0;
const hashIndex = url.indexOf("#");
return hashIndex !== -1 && colonIndex > hashIndex;
}
const defaultLists = {
number: ({ children }) => `<ol>${children}</ol>`,
bullet: ({ children }) => `<ul>${children}</ul>`
}, DefaultListItem = ({ children }) => `<li>${children}</li>`, link = ({ children, value }) => {
const href = value?.href || "";
return uriLooksSafe(href) ? `<a href="${escapeHTML(href)}">${children}</a>` : children;
}, defaultMarks = {
em: ({ children }) => `<em>${children}</em>`,
strong: ({ children }) => `<strong>${children}</strong>`,
code: ({ children }) => `<code>${children}</code>`,
underline: ({ children }) => `<span style="text-decoration:underline">${children}</span>`,
"strike-through": ({ children }) => `<del>${children}</del>`,
link
}, getTemplate = (type, prop) => `Unknown ${type}, specify a component for it in the \`components.${prop}\` option`, unknownTypeWarning = (typeName) => getTemplate(`block type "${typeName}"`, "types"), unknownMarkWarning = (markType) => getTemplate(`mark type "${markType}"`, "marks"), unknownBlockStyleWarning = (blockStyle) => getTemplate(`block style "${blockStyle}"`, "block"), unknownListStyleWarning = (listStyle) => getTemplate(`list style "${listStyle}"`, "list"), unknownListItemStyleWarning = (listStyle) => getTemplate(`list item style "${listStyle}"`, "listItem");
function printWarning(message) {
console.warn(message);
}
const DefaultUnknownType = ({
value,
isInline
}) => {
const warning = unknownTypeWarning(value._type);
return isInline ? `<span style="display:none">${warning}</span>` : `<div style="display:none">${warning}</div>`;
}, DefaultUnknownMark = ({
markType,
children
}) => `<span class="unknown__pt__mark__${markType}">${children}</span>`, DefaultUnknownBlockStyle = ({
children
}) => `<p>${children}</p>`, DefaultUnknownList = ({ children }) => `<ul>${children}</ul>`, DefaultUnknownListItem = ({
children
}) => `<li>${children}</li>`, DefaultHardBreak = () => "<br/>", defaultPortableTextBlockStyles = {
normal: ({ children }) => `<p>${children}</p>`,
blockquote: ({ children }) => `<blockquote>${children}</blockquote>`,
h1: ({ children }) => `<h1>${children}</h1>`,
h2: ({ children }) => `<h2>${children}</h2>`,
h3: ({ children }) => `<h3>${children}</h3>`,
h4: ({ children }) => `<h4>${children}</h4>`,
h5: ({ children }) => `<h5>${children}</h5>`,
h6: ({ children }) => `<h6>${children}</h6>`
}, defaultComponents = {
types: {},
block: defaultPortableTextBlockStyles,
marks: defaultMarks,
list: defaultLists,
listItem: DefaultListItem,
hardBreak: DefaultHardBreak,
escapeHTML,
unknownType: DefaultUnknownType,
unknownMark: DefaultUnknownMark,
unknownList: DefaultUnknownList,
unknownListItem: DefaultUnknownListItem,
unknownBlockStyle: DefaultUnknownBlockStyle
};
function mergeComponents(parent, overrides) {
const { block, list, listItem, marks, types, ...rest } = overrides;
return {
...parent,
block: mergeDeeply(parent, overrides, "block"),
list: mergeDeeply(parent, overrides, "list"),
listItem: mergeDeeply(parent, overrides, "listItem"),
marks: mergeDeeply(parent, overrides, "marks"),
types: mergeDeeply(parent, overrides, "types"),
...rest
};
}
function mergeDeeply(parent, overrides, key) {
const override = overrides[key], parentVal = parent[key];
return typeof override == "function" || override && typeof parentVal == "function" ? override : override ? { ...parentVal, ...override } : parentVal;
}
function toHTML(value, options = {}) {
const {
components: componentOverrides,
onMissingComponent: missingComponentHandler = printWarning
} = options, handleMissingComponent = missingComponentHandler || noop, blocks = Array.isArray(value) ? value : [value], nested = nestLists(blocks, "html"), components = componentOverrides ? mergeComponents(defaultComponents, componentOverrides) : defaultComponents, renderNode = getNodeRenderer(components, handleMissingComponent);
return nested.map(
(node, index) => renderNode({ node, index, isInline: !1, renderNode })
).join("");
}
const getNodeRenderer = (components, handleMissingComponent) => {
function renderNode(options) {
const { node, index, isInline } = options;
return isPortableTextToolkitList(node) ? renderList(node, index) : isPortableTextListItemBlock(node) ? renderListItem(node, index) : isPortableTextToolkitSpan(node) ? renderSpan(node) : isPortableTextBlock(node) ? renderBlock(node, index, isInline) : isPortableTextToolkitTextNode(node) ? renderText(node) : renderCustomBlock(node, index, isInline);
}
function renderListItem(node, index) {
const tree = serializeBlock({ node, index, isInline: !1, renderNode }), renderer = components.listItem, itemHandler = (typeof renderer == "function" ? renderer : renderer[node.listItem]) || components.unknownListItem;
if (itemHandler === components.unknownListItem) {
const style = node.listItem || "bullet";
handleMissingComponent(unknownListItemStyleWarning(style), {
type: style,
nodeType: "listItemStyle"
});
}
let children = tree.children;
if (node.style && node.style !== "normal") {
const { listItem, ...blockNode } = node;
children = renderNode({ node: blockNode, index, isInline: !1 });
}
return itemHandler({ value: node, index, isInline: !1, renderNode, children });
}
function renderList(node, index) {
const children = node.children.map(
(child, childIndex) => renderNode({
node: child._key ? child : { ...child, _key: `li-${index}-${childIndex}` },
index: childIndex,
isInline: !1
})
), component = components.list, list = (typeof component == "function" ? component : component[node.listItem]) || components.unknownList;
if (list === components.unknownList) {
const style = node.listItem || "bullet";
handleMissingComponent(unknownListStyleWarning(style), { nodeType: "listStyle", type: style });
}
return list({ value: node, index, isInline: !1, renderNode, children: children.join("") });
}
function renderSpan(node) {
const { markDef, markType, markKey } = node, span = components.marks[markType] || components.unknownMark, children = node.children.map(
(child, childIndex) => renderNode({ node: child, index: childIndex, isInline: !0 })
);
return span === components.unknownMark && handleMissingComponent(unknownMarkWarning(markType), { nodeType: "mark", type: markType }), span({
text: spanToPlainText(node),
value: markDef,
markType,
markKey,
renderNode,
children: children.join("")
});
}
function renderBlock(node, index, isInline) {
const { _key, ...props } = serializeBlock({ node, index, isInline, renderNode }), style = props.node.style || "normal", block = (typeof components.block == "function" ? components.block : components.block[style]) || components.unknownBlockStyle;
return block === components.unknownBlockStyle && handleMissingComponent(unknownBlockStyleWarning(style), {
nodeType: "blockStyle",
type: style
}), block({ ...props, value: props.node, renderNode });
}
function renderText(node) {
if (node.text === `
`) {
const hardBreak = components.hardBreak;
return hardBreak ? hardBreak() : `
`;
}
return components.escapeHTML(node.text);
}
function renderCustomBlock(value, index, isInline) {
const node = components.types[value._type];
return node || handleMissingComponent(unknownTypeWarning(value._type), {
nodeType: "block",
type: value._type
}), (node || components.unknownType)({
value,
isInline,
index,
renderNode
});
}
return renderNode;
};
function serializeBlock(options) {
const { node, index, isInline, renderNode } = options, children = buildMarksTree(node).map(
(child, i) => renderNode({ node: child, isInline: !0, index: i, renderNode })
);
return {
_key: node._key || `block-${index}`,
children: children.join(""),
index,
isInline,
node
};
}
function noop() {
}
export {
defaultComponents,
escapeHTML,
mergeComponents,
toHTML,
uriLooksSafe
};
//# sourceMappingURL=pt-to-html.mjs.map
{"version":3,"file":"pt-to-html.mjs","sources":["../src/escape.ts","../src/components/list.ts","../src/components/marks.ts","../src/warnings.ts","../src/components/unknown.ts","../src/components/defaults.ts","../src/components/merge.ts","../src/to-html.ts"],"sourcesContent":["const allowedProtocols = ['http', 'https', 'mailto', 'tel']\nconst charMap: Record<string, string> = {\n '&': 'amp',\n '<': 'lt',\n '>': 'gt',\n '\"': 'quot',\n \"'\": '#x27',\n}\n\nexport function escapeHTML(str: string): string {\n return replaceMultipleSpaces(str.replace(/[&<>\"']/g, (s) => `&${charMap[s]};`))\n}\n\nexport function replaceMultipleSpaces(str: string): string {\n return str.replace(/ {2,}/g, (match: string) => `${'&nbsp;'.repeat(match.length - 1)} `)\n}\n\nexport function uriLooksSafe(uri: string): boolean {\n const url = (uri || '').trim()\n const first = url.charAt(0)\n\n // Allow hash-links, absolute paths and \"same-protocol\" (//foo.bar) URLs\n if (first === '#' || first === '/') {\n return true\n }\n\n // If the URL does not contain a `:`, allow it\n const colonIndex = url.indexOf(':')\n if (colonIndex === -1) {\n return true\n }\n\n // If the protocol is in the allowed list, treat it as OK\n const proto = url.slice(0, colonIndex).toLowerCase()\n if (allowedProtocols.indexOf(proto) !== -1) {\n return true\n }\n\n // If the URL is `site/search?query=author:espen`, allow it\n const queryIndex = url.indexOf('?')\n if (queryIndex !== -1 && colonIndex > queryIndex) {\n return true\n }\n\n // If the URL is `site/search#my:encoded:data`, allow it\n const hashIndex = url.indexOf('#')\n if (hashIndex !== -1 && colonIndex > hashIndex) {\n return true\n }\n\n return false\n}\n","import type {PortableTextListComponent, PortableTextListItemComponent} from '../types'\n\nexport const defaultLists: Record<'number' | 'bullet', PortableTextListComponent> = {\n number: ({children}) => `<ol>${children}</ol>`,\n bullet: ({children}) => `<ul>${children}</ul>`,\n}\n\nexport const DefaultListItem: PortableTextListItemComponent = ({children}) => `<li>${children}</li>`\n","import type {TypedObject} from '@portabletext/types'\n\nimport {escapeHTML, uriLooksSafe} from '../escape'\nimport type {PortableTextMarkComponent} from '../types'\n\ninterface DefaultLink extends TypedObject {\n _type: 'link'\n href: string\n}\n\nconst link: PortableTextMarkComponent<DefaultLink> = ({children, value}) => {\n const href = value?.href || ''\n const looksSafe = uriLooksSafe(href)\n return looksSafe ? `<a href=\"${escapeHTML(href)}\">${children}</a>` : children\n}\n\nexport const defaultMarks: Record<string, PortableTextMarkComponent | undefined> = {\n 'em': ({children}) => `<em>${children}</em>`,\n 'strong': ({children}) => `<strong>${children}</strong>`,\n 'code': ({children}) => `<code>${children}</code>`,\n 'underline': ({children}) => `<span style=\"text-decoration:underline\">${children}</span>`,\n 'strike-through': ({children}) => `<del>${children}</del>`,\n link,\n}\n","const getTemplate = (type: string, prop: string): string =>\n `Unknown ${type}, specify a component for it in the \\`components.${prop}\\` option`\n\nexport const unknownTypeWarning = (typeName: string): string =>\n getTemplate(`block type \"${typeName}\"`, 'types')\n\nexport const unknownMarkWarning = (markType: string): string =>\n getTemplate(`mark type \"${markType}\"`, 'marks')\n\nexport const unknownBlockStyleWarning = (blockStyle: string): string =>\n getTemplate(`block style \"${blockStyle}\"`, 'block')\n\nexport const unknownListStyleWarning = (listStyle: string): string =>\n getTemplate(`list style \"${listStyle}\"`, 'list')\n\nexport const unknownListItemStyleWarning = (listStyle: string): string =>\n getTemplate(`list item style \"${listStyle}\"`, 'listItem')\n\nexport function printWarning(message: string): void {\n console.warn(message)\n}\n","import type {PortableTextHtmlComponents} from '../types'\nimport {unknownTypeWarning} from '../warnings'\n\nexport const DefaultUnknownType: PortableTextHtmlComponents['unknownType'] = ({\n value,\n isInline,\n}) => {\n const warning = unknownTypeWarning(value._type)\n return isInline\n ? `<span style=\"display:none\">${warning}</span>`\n : `<div style=\"display:none\">${warning}</div>`\n}\n\nexport const DefaultUnknownMark: PortableTextHtmlComponents['unknownMark'] = ({\n markType,\n children,\n}) => {\n return `<span class=\"unknown__pt__mark__${markType}\">${children}</span>`\n}\n\nexport const DefaultUnknownBlockStyle: PortableTextHtmlComponents['unknownBlockStyle'] = ({\n children,\n}) => {\n return `<p>${children}</p>`\n}\n\nexport const DefaultUnknownList: PortableTextHtmlComponents['unknownList'] = ({children}) => {\n return `<ul>${children}</ul>`\n}\n\nexport const DefaultUnknownListItem: PortableTextHtmlComponents['unknownListItem'] = ({\n children,\n}) => {\n return `<li>${children}</li>`\n}\n","import type {PortableTextBlockStyle} from '@portabletext/types'\n\nimport {escapeHTML} from '../escape'\nimport type {PortableTextBlockComponent, PortableTextHtmlComponents} from '../types'\nimport {DefaultListItem, defaultLists} from './list'\nimport {defaultMarks} from './marks'\nimport {\n DefaultUnknownBlockStyle,\n DefaultUnknownList,\n DefaultUnknownListItem,\n DefaultUnknownMark,\n DefaultUnknownType,\n} from './unknown'\n\nexport const DefaultHardBreak = (): string => '<br/>'\n\nexport const defaultPortableTextBlockStyles: Record<\n PortableTextBlockStyle,\n PortableTextBlockComponent | undefined\n> = {\n normal: ({children}) => `<p>${children}</p>`,\n blockquote: ({children}) => `<blockquote>${children}</blockquote>`,\n h1: ({children}) => `<h1>${children}</h1>`,\n h2: ({children}) => `<h2>${children}</h2>`,\n h3: ({children}) => `<h3>${children}</h3>`,\n h4: ({children}) => `<h4>${children}</h4>`,\n h5: ({children}) => `<h5>${children}</h5>`,\n h6: ({children}) => `<h6>${children}</h6>`,\n}\n\nexport const defaultComponents: PortableTextHtmlComponents = {\n types: {},\n\n block: defaultPortableTextBlockStyles,\n marks: defaultMarks,\n list: defaultLists,\n listItem: DefaultListItem,\n hardBreak: DefaultHardBreak,\n escapeHTML: escapeHTML,\n\n unknownType: DefaultUnknownType,\n unknownMark: DefaultUnknownMark,\n unknownList: DefaultUnknownList,\n unknownListItem: DefaultUnknownListItem,\n unknownBlockStyle: DefaultUnknownBlockStyle,\n}\n","import type {PortableTextComponents, PortableTextHtmlComponents} from '../types'\n\nexport function mergeComponents(\n parent: PortableTextHtmlComponents,\n overrides: PortableTextComponents,\n): PortableTextHtmlComponents {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {block, list, listItem, marks, types, ...rest} = overrides\n // @todo figure out how to not `as ...` these\n return {\n ...parent,\n block: mergeDeeply(parent, overrides, 'block') as PortableTextHtmlComponents['block'],\n list: mergeDeeply(parent, overrides, 'list') as PortableTextHtmlComponents['list'],\n listItem: mergeDeeply(parent, overrides, 'listItem') as PortableTextHtmlComponents['listItem'],\n marks: mergeDeeply(parent, overrides, 'marks') as PortableTextHtmlComponents['marks'],\n types: mergeDeeply(parent, overrides, 'types') as PortableTextHtmlComponents['types'],\n ...rest,\n }\n}\n\nfunction mergeDeeply(\n parent: PortableTextHtmlComponents,\n overrides: PortableTextComponents,\n key: 'block' | 'list' | 'listItem' | 'marks' | 'types',\n): PortableTextHtmlComponents[typeof key] {\n const override = overrides[key]\n const parentVal = parent[key]\n\n if (typeof override === 'function') {\n return override\n }\n\n if (override && typeof parentVal === 'function') {\n return override\n }\n\n if (override) {\n return {...parentVal, ...override} as PortableTextHtmlComponents[typeof key]\n }\n\n return parentVal\n}\n","import {\n buildMarksTree,\n isPortableTextBlock,\n isPortableTextListItemBlock,\n isPortableTextToolkitList,\n isPortableTextToolkitSpan,\n isPortableTextToolkitTextNode,\n nestLists,\n spanToPlainText,\n type ToolkitNestedPortableTextSpan,\n type ToolkitTextNode,\n} from '@portabletext/toolkit'\nimport type {\n ArbitraryTypedObject,\n PortableTextBlock,\n PortableTextListItemBlock,\n PortableTextMarkDefinition,\n PortableTextSpan,\n TypedObject,\n} from '@portabletext/types'\n\nimport {defaultComponents} from './components/defaults'\nimport {mergeComponents} from './components/merge'\nimport type {\n HtmlPortableTextList,\n MissingComponentHandler,\n NodeRenderer,\n PortableTextHtmlComponents,\n PortableTextOptions,\n Serializable,\n SerializedBlock,\n} from './types'\nimport {\n printWarning,\n unknownBlockStyleWarning,\n unknownListItemStyleWarning,\n unknownListStyleWarning,\n unknownMarkWarning,\n unknownTypeWarning,\n} from './warnings'\n\nexport function toHTML<B extends TypedObject = PortableTextBlock | ArbitraryTypedObject>(\n value: B | B[],\n options: PortableTextOptions = {},\n): string {\n const {\n components: componentOverrides,\n onMissingComponent: missingComponentHandler = printWarning,\n } = options\n\n const handleMissingComponent = missingComponentHandler || noop\n const blocks = Array.isArray(value) ? value : [value]\n const nested = nestLists(blocks, 'html')\n const components = componentOverrides\n ? mergeComponents(defaultComponents, componentOverrides)\n : defaultComponents\n\n const renderNode = getNodeRenderer(components, handleMissingComponent)\n const rendered = nested.map((node, index) =>\n renderNode({node: node, index, isInline: false, renderNode}),\n )\n\n return rendered.join('')\n}\n\nconst getNodeRenderer = (\n components: PortableTextHtmlComponents,\n handleMissingComponent: MissingComponentHandler,\n): NodeRenderer => {\n function renderNode<N extends TypedObject>(options: Serializable<N>): string {\n const {node, index, isInline} = options\n\n if (isPortableTextToolkitList(node)) {\n return renderList(node, index)\n }\n\n if (isPortableTextListItemBlock(node)) {\n return renderListItem(node, index)\n }\n\n if (isPortableTextToolkitSpan(node)) {\n return renderSpan(node)\n }\n\n if (isPortableTextBlock(node)) {\n return renderBlock(node, index, isInline)\n }\n\n if (isPortableTextToolkitTextNode(node)) {\n return renderText(node)\n }\n\n return renderCustomBlock(node, index, isInline)\n }\n\n function renderListItem(\n node: PortableTextListItemBlock<PortableTextMarkDefinition, PortableTextSpan>,\n index: number,\n ): string {\n const tree = serializeBlock({node, index, isInline: false, renderNode})\n const renderer = components.listItem\n const handler = typeof renderer === 'function' ? renderer : renderer[node.listItem]\n const itemHandler = handler || components.unknownListItem\n\n if (itemHandler === components.unknownListItem) {\n const style = node.listItem || 'bullet'\n handleMissingComponent(unknownListItemStyleWarning(style), {\n type: style,\n nodeType: 'listItemStyle',\n })\n }\n\n let children = tree.children\n if (node.style && node.style !== 'normal') {\n // Wrap any other style in whatever the block component says to use\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {listItem, ...blockNode} = node\n children = renderNode({node: blockNode, index, isInline: false, renderNode})\n }\n\n return itemHandler({value: node, index, isInline: false, renderNode, children})\n }\n\n function renderList(node: HtmlPortableTextList, index: number): string {\n const children = node.children.map((child, childIndex) =>\n renderNode({\n node: child._key ? child : {...child, _key: `li-${index}-${childIndex}`},\n index: childIndex,\n isInline: false,\n renderNode,\n }),\n )\n\n const component = components.list\n const handler = typeof component === 'function' ? component : component[node.listItem]\n const list = handler || components.unknownList\n\n if (list === components.unknownList) {\n const style = node.listItem || 'bullet'\n handleMissingComponent(unknownListStyleWarning(style), {nodeType: 'listStyle', type: style})\n }\n\n return list({value: node, index, isInline: false, renderNode, children: children.join('')})\n }\n\n function renderSpan(node: ToolkitNestedPortableTextSpan): string {\n const {markDef, markType, markKey} = node\n const span = components.marks[markType] || components.unknownMark\n const children = node.children.map((child, childIndex) =>\n renderNode({node: child, index: childIndex, isInline: true, renderNode}),\n )\n\n if (span === components.unknownMark) {\n handleMissingComponent(unknownMarkWarning(markType), {nodeType: 'mark', type: markType})\n }\n\n return span({\n text: spanToPlainText(node),\n value: markDef,\n markType,\n markKey,\n renderNode,\n children: children.join(''),\n })\n }\n\n function renderBlock(node: PortableTextBlock, index: number, isInline: boolean): string {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {_key, ...props} = serializeBlock({node, index, isInline, renderNode})\n const style = props.node.style || 'normal'\n const handler =\n typeof components.block === 'function' ? components.block : components.block[style]\n const block = handler || components.unknownBlockStyle\n\n if (block === components.unknownBlockStyle) {\n handleMissingComponent(unknownBlockStyleWarning(style), {\n nodeType: 'blockStyle',\n type: style,\n })\n }\n\n return block({...props, value: props.node, renderNode})\n }\n\n function renderText(node: ToolkitTextNode): string {\n if (node.text === '\\n') {\n const hardBreak = components.hardBreak\n return hardBreak ? hardBreak() : '\\n'\n }\n\n return components.escapeHTML(node.text)\n }\n\n function renderCustomBlock(value: TypedObject, index: number, isInline: boolean): string {\n const node = components.types[value._type]\n\n if (!node) {\n handleMissingComponent(unknownTypeWarning(value._type), {\n nodeType: 'block',\n type: value._type,\n })\n }\n\n const component = node || components.unknownType\n return component({\n value,\n isInline,\n index,\n renderNode,\n })\n }\n\n return renderNode\n}\n\nfunction serializeBlock(options: Serializable<PortableTextBlock>): SerializedBlock {\n const {node, index, isInline, renderNode} = options\n const tree = buildMarksTree(node)\n const children = tree.map((child, i) =>\n renderNode({node: child, isInline: true, index: i, renderNode}),\n )\n\n return {\n _key: node._key || `block-${index}`,\n children: children.join(''),\n index,\n isInline,\n node,\n }\n}\n\nfunction noop() {\n // Intentional noop\n}\n"],"names":[],"mappings":"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"}

Sorry, the diff of this file is not supported yet