@portabletext/toolkit
Advanced tools
+60
-54
@@ -1,7 +0,7 @@ | ||
| import type {ArbitraryTypedObject} from '@portabletext/types' | ||
| import type {PortableTextBlock} from '@portabletext/types' | ||
| import type {PortableTextListItemBlock} from '@portabletext/types' | ||
| import type {PortableTextMarkDefinition} from '@portabletext/types' | ||
| import type {PortableTextSpan} from '@portabletext/types' | ||
| import type {TypedObject} from '@portabletext/types' | ||
| import type { ArbitraryTypedObject } from "@portabletext/types"; | ||
| import type { PortableTextBlock } from "@portabletext/types"; | ||
| import type { PortableTextListItemBlock } from "@portabletext/types"; | ||
| import type { PortableTextMarkDefinition } from "@portabletext/types"; | ||
| import type { PortableTextSpan } from "@portabletext/types"; | ||
| import type { TypedObject } from "@portabletext/types"; | ||
@@ -43,3 +43,7 @@ /** | ||
| block: PortableTextBlock<M>, | ||
| ): (ToolkitNestedPortableTextSpan<M> | ToolkitTextNode | ArbitraryTypedObject)[] | ||
| ): ( | ||
| | ToolkitNestedPortableTextSpan<M> | ||
| | ToolkitTextNode | ||
| | ArbitraryTypedObject | ||
| )[]; | ||
@@ -54,3 +58,3 @@ /** | ||
| node: PortableTextBlock | TypedObject, | ||
| ): node is PortableTextBlock | ||
| ): node is PortableTextBlock; | ||
@@ -65,3 +69,3 @@ /** | ||
| block: PortableTextBlock | TypedObject, | ||
| ): block is PortableTextListItemBlock | ||
| ): block is PortableTextListItemBlock; | ||
@@ -76,3 +80,3 @@ /** | ||
| node: ArbitraryTypedObject | PortableTextSpan, | ||
| ): node is PortableTextSpan | ||
| ): node is PortableTextSpan; | ||
@@ -88,3 +92,3 @@ /** | ||
| block: TypedObject | ToolkitPortableTextList, | ||
| ): block is ToolkitPortableTextList | ||
| ): block is ToolkitPortableTextList; | ||
@@ -100,3 +104,3 @@ /** | ||
| span: TypedObject | ToolkitNestedPortableTextSpan, | ||
| ): span is ToolkitNestedPortableTextSpan | ||
| ): span is ToolkitNestedPortableTextSpan; | ||
@@ -112,3 +116,3 @@ /** | ||
| node: TypedObject | ToolkitTextNode, | ||
| ): node is ToolkitTextNode | ||
| ): node is ToolkitTextNode; | ||
@@ -118,3 +122,3 @@ /** | ||
| */ | ||
| export declare const LIST_NEST_MODE_DIRECT = 'direct' | ||
| export declare const LIST_NEST_MODE_DIRECT = "direct"; | ||
@@ -124,3 +128,3 @@ /** | ||
| */ | ||
| export declare const LIST_NEST_MODE_HTML = 'html' | ||
| export declare const LIST_NEST_MODE_HTML = "html"; | ||
@@ -149,16 +153,16 @@ /** | ||
| */ | ||
| export declare function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>( | ||
| blocks: T[], | ||
| mode: 'direct', | ||
| ): (T | ToolkitPortableTextDirectList)[] | ||
| export declare function nestLists< | ||
| T extends TypedObject = PortableTextBlock | TypedObject, | ||
| >(blocks: T[], mode: "direct"): (T | ToolkitPortableTextDirectList)[]; | ||
| export declare function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>( | ||
| blocks: T[], | ||
| mode: 'html', | ||
| ): (T | ToolkitPortableTextHtmlList)[] | ||
| export declare function nestLists< | ||
| T extends TypedObject = PortableTextBlock | TypedObject, | ||
| >(blocks: T[], mode: "html"): (T | ToolkitPortableTextHtmlList)[]; | ||
| export declare function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>( | ||
| export declare function nestLists< | ||
| T extends TypedObject = PortableTextBlock | TypedObject, | ||
| >( | ||
| blocks: T[], | ||
| mode: 'direct' | 'html', | ||
| ): (T | ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList)[] | ||
| mode: "direct" | "html", | ||
| ): (T | ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList)[]; | ||
@@ -206,3 +210,3 @@ /** | ||
| blockChildren: (PortableTextSpan | TypedObject)[], | ||
| ): string[] | ||
| ): string[]; | ||
@@ -219,3 +223,5 @@ /** | ||
| */ | ||
| export declare function spanToPlainText(span: ToolkitNestedPortableTextSpan): string | ||
| export declare function spanToPlainText( | ||
| span: ToolkitNestedPortableTextSpan, | ||
| ): string; | ||
@@ -225,3 +231,3 @@ /** | ||
| */ | ||
| export declare type ToolkitListNestMode = 'html' | 'direct' | ||
| export declare type ToolkitListNestMode = "html" | "direct"; | ||
@@ -238,7 +244,7 @@ /** | ||
| */ | ||
| _type: '@span' | ||
| _type: "@span"; | ||
| /** | ||
| * Unique key for this span | ||
| */ | ||
| _key?: string | ||
| _key?: string; | ||
| /** | ||
@@ -248,3 +254,3 @@ * Holds the value (definition) of the mark in the case of annotations. | ||
| */ | ||
| markDef?: M | ||
| markDef?: M; | ||
| /** | ||
@@ -254,3 +260,3 @@ * The key of the mark definition (in the case of annotations). | ||
| */ | ||
| markKey?: string | ||
| markKey?: string; | ||
| /** | ||
@@ -260,3 +266,3 @@ * Type of the mark. For annotations, this is the `_type` property of the value. | ||
| */ | ||
| markType: string | ||
| markType: string; | ||
| /** | ||
@@ -268,5 +274,5 @@ * Child nodes of this span. Can be toolkit-specific text nodes, nested spans | ||
| | ToolkitTextNode | ||
| | ToolkitNestedPortableTextSpan<PortableTextMarkDefinition> | ||
| | ToolkitNestedPortableTextSpan | ||
| | ArbitraryTypedObject | ||
| )[] | ||
| )[]; | ||
| } | ||
@@ -277,3 +283,3 @@ | ||
| | ToolkitPortableTextHtmlList | ||
| | ToolkitPortableTextDirectList | ||
| | ToolkitPortableTextDirectList; | ||
@@ -288,23 +294,23 @@ /** | ||
| */ | ||
| _type: '@list' | ||
| _type: "@list"; | ||
| /** | ||
| * Unique key for this list (within its parent) | ||
| */ | ||
| _key: string | ||
| _key: string; | ||
| /** | ||
| * List mode, signaling that list nodes can appear as direct children | ||
| */ | ||
| mode: 'direct' | ||
| mode: "direct"; | ||
| /** | ||
| * Level/depth of this list node (starts at `1`) | ||
| */ | ||
| level: number | ||
| level: number; | ||
| /** | ||
| * Style of this list item (`bullet`, `number` are common values, but can be customized) | ||
| */ | ||
| listItem: string | ||
| listItem: string; | ||
| /** | ||
| * Child nodes of this list - either portable text list items, or another, deeper list | ||
| */ | ||
| children: (PortableTextListItemBlock | ToolkitPortableTextDirectList)[] | ||
| children: (PortableTextListItemBlock | ToolkitPortableTextDirectList)[]; | ||
| } | ||
@@ -320,23 +326,23 @@ | ||
| */ | ||
| _type: '@list' | ||
| _type: "@list"; | ||
| /** | ||
| * Unique key for this list (within its parent) | ||
| */ | ||
| _key: string | ||
| _key: string; | ||
| /** | ||
| * List mode, signaling that list nodes will appear as children of the _list items_ | ||
| */ | ||
| mode: 'html' | ||
| mode: "html"; | ||
| /** | ||
| * Level/depth of this list node (starts at `1`) | ||
| */ | ||
| level: number | ||
| level: number; | ||
| /** | ||
| * Style of this list item (`bullet`, `number` are common values, but can be customized) | ||
| */ | ||
| listItem: string | ||
| listItem: string; | ||
| /** | ||
| * Child nodes of this list - toolkit-specific list items which can themselves hold deeper lists | ||
| */ | ||
| children: ToolkitPortableTextListItem[] | ||
| children: ToolkitPortableTextListItem[]; | ||
| } | ||
@@ -351,3 +357,3 @@ | ||
| | ToolkitPortableTextHtmlList | ||
| | ToolkitPortableTextDirectList | ||
| | ToolkitPortableTextDirectList; | ||
@@ -372,7 +378,7 @@ /** | ||
| */ | ||
| _type: '@text' | ||
| _type: "@text"; | ||
| /** | ||
| * The actual string value of the text node | ||
| */ | ||
| text: string | ||
| text: string; | ||
| } | ||
@@ -393,4 +399,4 @@ | ||
| block: PortableTextBlock | ArbitraryTypedObject[] | PortableTextBlock[], | ||
| ): string | ||
| ): string; | ||
| export {} | ||
| export {}; |
+11
-16
| { | ||
| "name": "@portabletext/toolkit", | ||
| "version": "3.0.2", | ||
| "version": "3.0.3-canary.0", | ||
| "description": "Toolkit of handy utility functions for dealing with Portable Text", | ||
@@ -28,4 +28,2 @@ "keywords": [ | ||
| "source": "./src/index.ts", | ||
| "import": "./dist/index.js", | ||
| "require": "./dist/index.cjs", | ||
| "default": "./dist/index.js" | ||
@@ -35,4 +33,3 @@ }, | ||
| }, | ||
| "main": "./dist/index.cjs", | ||
| "module": "./dist/index.js", | ||
| "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
@@ -45,3 +42,2 @@ "files": [ | ||
| "browserslist": "extends @sanity/browserslist-config", | ||
| "prettier": "@sanity/prettier-config", | ||
| "eslintConfig": { | ||
@@ -57,4 +53,3 @@ "parserOptions": { | ||
| "sanity", | ||
| "sanity/typescript", | ||
| "prettier" | ||
| "sanity/typescript" | ||
| ], | ||
@@ -73,16 +68,16 @@ "ignorePatterns": [ | ||
| "@sanity/pkg-utils": "^8.1.4", | ||
| "@sanity/prettier-config": "^2.0.1", | ||
| "@types/node": "^22.18.0", | ||
| "@types/node": "^24.10.0", | ||
| "@typescript-eslint/eslint-plugin": "^7.18.0", | ||
| "@typescript-eslint/parser": "^7.18.0", | ||
| "@vitest/coverage-v8": "^3.2.4", | ||
| "@vitest/coverage-v8": "^4.0.6", | ||
| "eslint": "^8.57.1", | ||
| "eslint-config-prettier": "^10.1.8", | ||
| "eslint-config-sanity": "^7.1.4", | ||
| "npm-run-all2": "^8.0.4", | ||
| "prettier": "^3.6.2", | ||
| "oxfmt": "^0.9.0", | ||
| "oxlint": "^1.25.0", | ||
| "oxlint-tsgolint": "^0.5.0", | ||
| "rimraf": "^4.4.1", | ||
| "typedoc": "^0.28.12", | ||
| "typescript": "5.9.2", | ||
| "vitest": "^3.2.4" | ||
| "vitest": "^4.0.6" | ||
| }, | ||
@@ -100,4 +95,4 @@ "engines": { | ||
| "docs:build": "typedoc", | ||
| "format": "prettier --write --cache --ignore-unknown .", | ||
| "lint": "eslint .", | ||
| "format": "oxfmt .", | ||
| "lint": "oxlint --deny-warnings --report-unused-disable-directives --type-aware", | ||
| "pkg:build": "pkg-utils build --strict", | ||
@@ -104,0 +99,0 @@ "pkg:check": "pkg-utils --strict", |
+3
-3
@@ -1,2 +0,2 @@ | ||
| import type {PortableTextBlock, PortableTextListItemBlock, TypedObject} from '@portabletext/types' | ||
| import type { PortableTextBlock, PortableTextListItemBlock, TypedObject } from '@portabletext/types' | ||
@@ -111,3 +111,3 @@ import { | ||
| } else { | ||
| ;(currentList as ToolkitPortableTextDirectList).children.push( | ||
| ; (currentList as ToolkitPortableTextDirectList).children.push( | ||
| newList as ToolkitPortableTextDirectList, | ||
@@ -142,3 +142,3 @@ ) | ||
| const matchingBranch = tree[tree.length - 1] | ||
| const match = matchingBranch && findListMatching(matchingBranch, {level: block.level || 1}) | ||
| const match = matchingBranch && findListMatching(matchingBranch, { level: block.level || 1 }) | ||
| if (match && match.listItem === block.listItem) { | ||
@@ -145,0 +145,0 @@ currentList = match |
+2
-2
@@ -109,3 +109,3 @@ import type { | ||
| PortableTextSpan | ToolkitPortableTextList | ||
| > {} | ||
| > { } | ||
@@ -170,5 +170,5 @@ /** | ||
| | ToolkitTextNode | ||
| | ToolkitNestedPortableTextSpan<PortableTextMarkDefinition> | ||
| | ToolkitNestedPortableTextSpan | ||
| | ArbitraryTypedObject | ||
| )[] | ||
| } |
-221
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: !0 }); | ||
| function isPortableTextSpan(node) { | ||
| return node._type === "span" && "text" in node && typeof node.text == "string" && (typeof node.marks > "u" || Array.isArray(node.marks) && node.marks.every((mark) => typeof mark == "string")); | ||
| } | ||
| function isPortableTextBlock(node) { | ||
| return ( | ||
| // A block doesn't _have_ to be named 'block' - to differentiate between | ||
| // allowed child types and marks, one might name them differently | ||
| typeof node._type == "string" && // Toolkit-types like nested spans are @-prefixed | ||
| node._type[0] !== "@" && // `markDefs` isn't _required_ per say, but if it's there, it needs to be an array | ||
| (!("markDefs" in node) || !node.markDefs || Array.isArray(node.markDefs) && // Every mark definition needs to have an `_key` to be mappable in child spans | ||
| node.markDefs.every((def) => typeof def._key == "string")) && // `children` is required and needs to be an array | ||
| "children" in node && Array.isArray(node.children) && // All children are objects with `_type` (usually spans, but can contain other stuff) | ||
| node.children.every((child) => typeof child == "object" && "_type" in child) | ||
| ); | ||
| } | ||
| function isPortableTextListItemBlock(block) { | ||
| return isPortableTextBlock(block) && "listItem" in block && typeof block.listItem == "string" && (typeof block.level > "u" || typeof block.level == "number"); | ||
| } | ||
| function isPortableTextToolkitList(block) { | ||
| return block._type === "@list"; | ||
| } | ||
| function isPortableTextToolkitSpan(span) { | ||
| return span._type === "@span"; | ||
| } | ||
| function isPortableTextToolkitTextNode(node) { | ||
| return node._type === "@text"; | ||
| } | ||
| const knownDecorators = ["strong", "em", "code", "underline", "strike-through"]; | ||
| function sortMarksByOccurences(span, index, blockChildren) { | ||
| if (!isPortableTextSpan(span) || !span.marks) | ||
| return []; | ||
| if (!span.marks.length) | ||
| return []; | ||
| const marks = span.marks.slice(), occurences = {}; | ||
| return marks.forEach((mark) => { | ||
| occurences[mark] = 1; | ||
| for (let siblingIndex = index + 1; siblingIndex < blockChildren.length; siblingIndex++) { | ||
| const sibling = blockChildren[siblingIndex]; | ||
| if (sibling && isPortableTextSpan(sibling) && Array.isArray(sibling.marks) && sibling.marks.indexOf(mark) !== -1) | ||
| occurences[mark]++; | ||
| else | ||
| break; | ||
| } | ||
| }), marks.sort((markA, markB) => sortMarks(occurences, markA, markB)); | ||
| } | ||
| function sortMarks(occurences, markA, markB) { | ||
| const aOccurences = occurences[markA], bOccurences = occurences[markB]; | ||
| if (aOccurences !== bOccurences) | ||
| return bOccurences - aOccurences; | ||
| const aKnownPos = knownDecorators.indexOf(markA), bKnownPos = knownDecorators.indexOf(markB); | ||
| return aKnownPos !== bKnownPos ? aKnownPos - bKnownPos : markA.localeCompare(markB); | ||
| } | ||
| function buildMarksTree(block) { | ||
| const { children } = block, markDefs = block.markDefs ?? []; | ||
| if (!children || !children.length) | ||
| return []; | ||
| const sortedMarks = children.map(sortMarksByOccurences), rootNode = { | ||
| _type: "@span", | ||
| children: [], | ||
| markType: "<unknown>" | ||
| }; | ||
| let nodeStack = [rootNode]; | ||
| for (let i = 0; i < children.length; i++) { | ||
| const span = children[i]; | ||
| if (!span) | ||
| continue; | ||
| const marksNeeded = sortedMarks[i] || []; | ||
| let pos = 1; | ||
| if (nodeStack.length > 1) | ||
| for (pos; pos < nodeStack.length; pos++) { | ||
| const mark = nodeStack[pos]?.markKey || "", index = marksNeeded.indexOf(mark); | ||
| if (index === -1) | ||
| break; | ||
| marksNeeded.splice(index, 1); | ||
| } | ||
| nodeStack = nodeStack.slice(0, pos); | ||
| let currentNode = nodeStack[nodeStack.length - 1]; | ||
| if (currentNode) { | ||
| for (const markKey of marksNeeded) { | ||
| const markDef = markDefs?.find((def) => def._key === markKey), markType = markDef ? markDef._type : markKey, node = { | ||
| _type: "@span", | ||
| _key: span._key, | ||
| children: [], | ||
| markDef, | ||
| markType, | ||
| markKey | ||
| }; | ||
| currentNode.children.push(node), nodeStack.push(node), currentNode = node; | ||
| } | ||
| if (isPortableTextSpan(span)) { | ||
| const lines = span.text.split(` | ||
| `); | ||
| for (let line = lines.length; line-- > 1; ) | ||
| lines.splice(line, 0, ` | ||
| `); | ||
| currentNode.children = currentNode.children.concat( | ||
| lines.map((text) => ({ _type: "@text", text })) | ||
| ); | ||
| } else | ||
| currentNode.children = currentNode.children.concat(span); | ||
| } | ||
| } | ||
| return rootNode.children; | ||
| } | ||
| function nestLists(blocks, mode) { | ||
| const tree = []; | ||
| let currentList; | ||
| for (let i = 0; i < blocks.length; i++) { | ||
| const block = blocks[i]; | ||
| if (block) { | ||
| if (!isPortableTextListItemBlock(block)) { | ||
| tree.push(block), currentList = void 0; | ||
| continue; | ||
| } | ||
| if (!currentList) { | ||
| currentList = listFromBlock(block, i, mode), tree.push(currentList); | ||
| continue; | ||
| } | ||
| if (blockMatchesList(block, currentList)) { | ||
| currentList.children.push(block); | ||
| continue; | ||
| } | ||
| if ((block.level || 1) > currentList.level) { | ||
| const newList = listFromBlock(block, i, mode); | ||
| if (mode === "html") { | ||
| const lastListItem = currentList.children[currentList.children.length - 1], newLastChild = { | ||
| ...lastListItem, | ||
| children: [...lastListItem.children, newList] | ||
| }; | ||
| currentList.children[currentList.children.length - 1] = newLastChild; | ||
| } else | ||
| currentList.children.push( | ||
| newList | ||
| ); | ||
| currentList = newList; | ||
| continue; | ||
| } | ||
| if ((block.level || 1) < currentList.level) { | ||
| const matchingBranch = tree[tree.length - 1], match = matchingBranch && findListMatching(matchingBranch, block); | ||
| if (match) { | ||
| currentList = match, currentList.children.push(block); | ||
| continue; | ||
| } | ||
| currentList = listFromBlock(block, i, mode), tree.push(currentList); | ||
| continue; | ||
| } | ||
| if (block.listItem !== currentList.listItem) { | ||
| const matchingBranch = tree[tree.length - 1], match = matchingBranch && findListMatching(matchingBranch, { level: block.level || 1 }); | ||
| if (match && match.listItem === block.listItem) { | ||
| currentList = match, currentList.children.push(block); | ||
| continue; | ||
| } else { | ||
| currentList = listFromBlock(block, i, mode), tree.push(currentList); | ||
| continue; | ||
| } | ||
| } | ||
| console.warn("Unknown state encountered for block", block), tree.push(block); | ||
| } | ||
| } | ||
| return tree; | ||
| } | ||
| function blockMatchesList(block, list) { | ||
| return (block.level || 1) === list.level && block.listItem === list.listItem; | ||
| } | ||
| function listFromBlock(block, index, mode) { | ||
| return { | ||
| _type: "@list", | ||
| _key: `${block._key || `${index}`}-parent`, | ||
| mode, | ||
| level: block.level || 1, | ||
| listItem: block.listItem, | ||
| children: [block] | ||
| }; | ||
| } | ||
| function findListMatching(rootNode, matching) { | ||
| const level = matching.level || 1, style = matching.listItem || "normal", filterOnType = typeof matching.listItem == "string"; | ||
| if (isPortableTextToolkitList(rootNode) && (rootNode.level || 1) === level && filterOnType && (rootNode.listItem || "normal") === style) | ||
| return rootNode; | ||
| if (!("children" in rootNode)) | ||
| return; | ||
| const node = rootNode.children[rootNode.children.length - 1]; | ||
| return node && !isPortableTextSpan(node) ? findListMatching(node, matching) : void 0; | ||
| } | ||
| function spanToPlainText(span) { | ||
| let text = ""; | ||
| return span.children.forEach((current) => { | ||
| isPortableTextToolkitTextNode(current) ? text += current.text : isPortableTextToolkitSpan(current) && (text += spanToPlainText(current)); | ||
| }), text; | ||
| } | ||
| const leadingSpace = /^\s/, trailingSpace = /\s$/; | ||
| function toPlainText(block) { | ||
| const blocks = Array.isArray(block) ? block : [block]; | ||
| let text = ""; | ||
| return blocks.forEach((current, index) => { | ||
| if (!isPortableTextBlock(current)) | ||
| return; | ||
| let pad = !1; | ||
| current.children.forEach((span) => { | ||
| isPortableTextSpan(span) ? (text += pad && text && !trailingSpace.test(text) && !leadingSpace.test(span.text) ? " " : "", text += span.text, pad = !1) : pad = !0; | ||
| }), index !== blocks.length - 1 && (text += ` | ||
| `); | ||
| }), text; | ||
| } | ||
| const LIST_NEST_MODE_HTML = "html", LIST_NEST_MODE_DIRECT = "direct"; | ||
| exports.LIST_NEST_MODE_DIRECT = LIST_NEST_MODE_DIRECT; | ||
| exports.LIST_NEST_MODE_HTML = LIST_NEST_MODE_HTML; | ||
| exports.buildMarksTree = buildMarksTree; | ||
| exports.isPortableTextBlock = isPortableTextBlock; | ||
| exports.isPortableTextListItemBlock = isPortableTextListItemBlock; | ||
| exports.isPortableTextSpan = isPortableTextSpan; | ||
| exports.isPortableTextToolkitList = isPortableTextToolkitList; | ||
| exports.isPortableTextToolkitSpan = isPortableTextToolkitSpan; | ||
| exports.isPortableTextToolkitTextNode = isPortableTextToolkitTextNode; | ||
| exports.nestLists = nestLists; | ||
| exports.sortMarksByOccurences = sortMarksByOccurences; | ||
| exports.spanToPlainText = spanToPlainText; | ||
| exports.toPlainText = toPlainText; | ||
| //# sourceMappingURL=index.cjs.map |
| {"version":3,"file":"index.cjs","sources":["../src/asserters.ts","../src/sortMarksByOccurences.ts","../src/buildMarksTree.ts","../src/nestLists.ts","../src/spanToPlainText.ts","../src/toPlainText.ts","../src/types.ts"],"sourcesContent":["import type {\n ArbitraryTypedObject,\n PortableTextBlock,\n PortableTextListItemBlock,\n PortableTextSpan,\n TypedObject,\n} from '@portabletext/types'\n\nimport type {ToolkitNestedPortableTextSpan, ToolkitPortableTextList, ToolkitTextNode} from './types'\n\n/**\n * Strict check to determine if node is a correctly formatted Portable Text span.\n *\n * @param node - Node to check\n * @returns True if valid Portable Text span, otherwise false\n */\nexport function isPortableTextSpan(\n node: ArbitraryTypedObject | PortableTextSpan,\n): node is PortableTextSpan {\n return (\n node._type === 'span' &&\n 'text' in node &&\n typeof node.text === 'string' &&\n (typeof node.marks === 'undefined' ||\n (Array.isArray(node.marks) && node.marks.every((mark) => typeof mark === 'string')))\n )\n}\n\n/**\n * Strict check to determine if node is a correctly formatted Portable Text block.\n *\n * @param node - Node to check\n * @returns True if valid Portable Text block, otherwise false\n */\nexport function isPortableTextBlock(\n node: PortableTextBlock | TypedObject,\n): node is PortableTextBlock {\n return (\n // A block doesn't _have_ to be named 'block' - to differentiate between\n // allowed child types and marks, one might name them differently\n typeof node._type === 'string' &&\n // Toolkit-types like nested spans are @-prefixed\n node._type[0] !== '@' &&\n // `markDefs` isn't _required_ per say, but if it's there, it needs to be an array\n (!('markDefs' in node) ||\n !node.markDefs ||\n (Array.isArray(node.markDefs) &&\n // Every mark definition needs to have an `_key` to be mappable in child spans\n node.markDefs.every((def) => typeof def._key === 'string'))) &&\n // `children` is required and needs to be an array\n 'children' in node &&\n Array.isArray(node.children) &&\n // All children are objects with `_type` (usually spans, but can contain other stuff)\n node.children.every((child) => typeof child === 'object' && '_type' in child)\n )\n}\n\n/**\n * Strict check to determine if node is a correctly formatted portable list item block.\n *\n * @param block - Block to check\n * @returns True if valid Portable Text list item block, otherwise false\n */\nexport function isPortableTextListItemBlock(\n block: PortableTextBlock | TypedObject,\n): block is PortableTextListItemBlock {\n return (\n isPortableTextBlock(block) &&\n 'listItem' in block &&\n typeof block.listItem === 'string' &&\n (typeof block.level === 'undefined' || typeof block.level === 'number')\n )\n}\n\n/**\n * Loose check to determine if block is a toolkit list node.\n * Only checks `_type`, assumes correct structure.\n *\n * @param block - Block to check\n * @returns True if toolkit list, otherwise false\n */\nexport function isPortableTextToolkitList(\n block: TypedObject | ToolkitPortableTextList,\n): block is ToolkitPortableTextList {\n return block._type === '@list'\n}\n\n/**\n * Loose check to determine if span is a toolkit span node.\n * Only checks `_type`, assumes correct structure.\n *\n * @param span - Span to check\n * @returns True if toolkit span, otherwise false\n */\nexport function isPortableTextToolkitSpan(\n span: TypedObject | ToolkitNestedPortableTextSpan,\n): span is ToolkitNestedPortableTextSpan {\n return span._type === '@span'\n}\n\n/**\n * Loose check to determine if node is a toolkit text node.\n * Only checks `_type`, assumes correct structure.\n *\n * @param node - Node to check\n * @returns True if toolkit text node, otherwise false\n */\nexport function isPortableTextToolkitTextNode(\n node: TypedObject | ToolkitTextNode,\n): node is ToolkitTextNode {\n return node._type === '@text'\n}\n","import type {PortableTextSpan, TypedObject} from '@portabletext/types'\n\nimport {isPortableTextSpan} from './asserters'\n\nconst knownDecorators = ['strong', 'em', 'code', 'underline', 'strike-through']\n\n/**\n * Figures out the optimal order of marks, in order to minimize the amount of\n * nesting/repeated elements in environments such as HTML. For instance, a naive\n * implementation might render something like:\n *\n * ```html\n * <strong>This block contains </strong>\n * <strong><a href=\"https://some.url/\">a link</a></strong>\n * <strong> and some bolded text</strong>\n * ```\n *\n * ...whereas an optimal order would be:\n *\n * ```html\n * <strong>\n * This block contains <a href=\"https://some.url/\">a link</a> and some bolded text\n * </strong>\n * ```\n *\n * This is particularly necessary for cases like links, where you don't want multiple\n * individual links for different segments of the link text, even if parts of it are\n * bolded/italicized.\n *\n * This function is meant to be used like: `block.children.map(sortMarksByOccurences)`,\n * and is used internally in {@link buildMarksTree | `buildMarksTree()`}.\n *\n * The marks are sorted in the following order:\n *\n * 1. Marks that are shared amongst the most adjacent siblings\n * 2. Non-default marks (links, custom metadata)\n * 3. Decorators (bold, emphasis, code etc), in a predefined, preferred order\n *\n * @param span - The current span to sort\n * @param index - The index of the current span within the block\n * @param blockChildren - All children of the block being sorted\n * @returns Array of decorators and annotations, sorted by \"most adjacent siblings\"\n */\nexport function sortMarksByOccurences(\n span: PortableTextSpan | TypedObject,\n index: number,\n blockChildren: (PortableTextSpan | TypedObject)[],\n): string[] {\n if (!isPortableTextSpan(span) || !span.marks) {\n return []\n }\n\n if (!span.marks.length) {\n return []\n }\n\n // Slicing because we'll be sorting with `sort()`, which mutates\n const marks = span.marks.slice()\n const occurences: Record<string, number> = {}\n marks.forEach((mark) => {\n occurences[mark] = 1\n\n for (let siblingIndex = index + 1; siblingIndex < blockChildren.length; siblingIndex++) {\n const sibling = blockChildren[siblingIndex]\n\n if (\n sibling &&\n isPortableTextSpan(sibling) &&\n Array.isArray(sibling.marks) &&\n sibling.marks.indexOf(mark) !== -1\n ) {\n occurences[mark]++\n } else {\n break\n }\n }\n })\n\n return marks.sort((markA, markB) => sortMarks(occurences, markA, markB))\n}\n\nfunction sortMarks<U extends string, T extends Record<U, number>>(\n occurences: T,\n markA: U,\n markB: U,\n): number {\n const aOccurences = occurences[markA]\n const bOccurences = occurences[markB]\n\n if (aOccurences !== bOccurences) {\n return bOccurences - aOccurences\n }\n\n const aKnownPos = knownDecorators.indexOf(markA)\n const bKnownPos = knownDecorators.indexOf(markB)\n\n // Sort known decorators last\n if (aKnownPos !== bKnownPos) {\n return aKnownPos - bKnownPos\n }\n\n // Sort other marks simply by key\n return markA.localeCompare(markB)\n}\n","import type {\n ArbitraryTypedObject,\n PortableTextBlock,\n PortableTextMarkDefinition,\n} from '@portabletext/types'\n\nimport {isPortableTextSpan} from './asserters'\nimport {sortMarksByOccurences} from './sortMarksByOccurences'\nimport type {ToolkitNestedPortableTextSpan, ToolkitTextNode} from './types'\n\n/**\n * Takes a Portable Text block and returns a nested tree of nodes optimized for rendering\n * in HTML-like environments where you want marks/annotations to be nested inside of eachother.\n * For instance, a naive span-by-span rendering might yield:\n *\n * ```html\n * <strong>This block contains </strong>\n * <strong><a href=\"https://some.url/\">a link</a></strong>\n * <strong> and some bolded and </strong>\n * <em><strong>italicized text</strong></em>\n * ```\n *\n * ...whereas an optimal order would be:\n *\n * ```html\n * <strong>\n * This block contains <a href=\"https://some.url/\">a link</a>\n * and some bolded and <em>italicized text</em>\n * </strong>\n * ```\n *\n * Note that since \"native\" Portable Text spans cannot be nested,\n * this function returns an array of \"toolkit specific\" types:\n * {@link ToolkitTextNode | `@text`} and {@link ToolkitNestedPortableTextSpan | `@span` }.\n *\n * The toolkit-specific type can hold both types, as well as any arbitrary inline objects,\n * creating an actual tree.\n *\n * @param block - The Portable Text block to create a tree of nodes from\n * @returns Array of (potentially) nested spans, text nodes and/or arbitrary inline objects\n */\nexport function buildMarksTree<M extends PortableTextMarkDefinition = PortableTextMarkDefinition>(\n block: PortableTextBlock<M>,\n): (ToolkitNestedPortableTextSpan<M> | ToolkitTextNode | ArbitraryTypedObject)[] {\n const {children} = block\n const markDefs = block.markDefs ?? []\n if (!children || !children.length) {\n return []\n }\n\n const sortedMarks = children.map(sortMarksByOccurences)\n\n const rootNode: ToolkitNestedPortableTextSpan<M> = {\n _type: '@span',\n children: [],\n markType: '<unknown>',\n }\n\n let nodeStack: ToolkitNestedPortableTextSpan<M>[] = [rootNode]\n\n for (let i = 0; i < children.length; i++) {\n const span = children[i]\n if (!span) {\n continue\n }\n\n const marksNeeded = sortedMarks[i] || []\n let pos = 1\n\n // Start at position one. Root is always plain and should never be removed\n if (nodeStack.length > 1) {\n for (pos; pos < nodeStack.length; pos++) {\n const mark = nodeStack[pos]?.markKey || ''\n const index = marksNeeded.indexOf(mark)\n\n if (index === -1) {\n break\n }\n\n marksNeeded.splice(index, 1)\n }\n }\n\n // Keep from beginning to first miss\n nodeStack = nodeStack.slice(0, pos)\n\n // Add needed nodes\n let currentNode = nodeStack[nodeStack.length - 1]\n if (!currentNode) {\n continue\n }\n\n for (const markKey of marksNeeded) {\n const markDef = markDefs?.find((def) => def._key === markKey)\n const markType = markDef ? markDef._type : markKey\n const node: ToolkitNestedPortableTextSpan<M> = {\n _type: '@span',\n _key: span._key,\n children: [],\n markDef,\n markType,\n markKey,\n }\n\n currentNode.children.push(node)\n nodeStack.push(node)\n currentNode = node\n }\n\n // Split at newlines to make individual line chunks, but keep newline\n // characters as individual elements in the array. We use these characters\n // in the span serializer to trigger hard-break rendering\n if (isPortableTextSpan(span)) {\n const lines = span.text.split('\\n')\n for (let line = lines.length; line-- > 1; ) {\n lines.splice(line, 0, '\\n')\n }\n\n currentNode.children = currentNode.children.concat(\n lines.map((text) => ({_type: '@text', text})),\n )\n } else {\n // This is some other inline object, not a text span\n currentNode.children = currentNode.children.concat(span)\n }\n }\n\n return rootNode.children\n}\n","import type {PortableTextBlock, PortableTextListItemBlock, TypedObject} from '@portabletext/types'\n\nimport {\n isPortableTextListItemBlock,\n isPortableTextSpan,\n isPortableTextToolkitList,\n} from './asserters'\nimport type {\n ToolkitListNestMode,\n ToolkitPortableTextDirectList,\n ToolkitPortableTextHtmlList,\n ToolkitPortableTextList,\n ToolkitPortableTextListItem,\n} from './types'\n\nexport type ToolkitNestListsOutputNode<T> =\n | T\n | ToolkitPortableTextHtmlList\n | ToolkitPortableTextDirectList\n\n/**\n * Takes an array of blocks and returns an array of nodes optimized for rendering in HTML-like\n * environment, where lists are nested inside of eachother instead of appearing \"flat\" as in\n * native Portable Text data structures.\n *\n * Note that the list node is not a native Portable Text node type, and thus is represented\n * using the {@link ToolkitPortableTextList | `@list`} type name (`{_type: '@list'}`).\n *\n * The nesting can be configured in two modes:\n *\n * - `direct`: deeper list nodes will appear as a direct child of the parent list\n * - `html`, deeper list nodes will appear as a child of the last _list item_ in the parent list\n *\n * When using `direct`, all list nodes will be of type {@link ToolkitPortableTextDirectList},\n * while with `html` they will be of type {@link ToolkitPortableTextHtmlList}\n *\n * These modes are available as {@link LIST_NEST_MODE_HTML} and {@link LIST_NEST_MODE_DIRECT}.\n *\n * @param blocks - Array of Portable Text blocks and other arbitrary types\n * @param mode - Mode to use for nesting, `direct` or `html`\n * @returns Array of potentially nested nodes optimized for rendering\n */\nexport function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>(\n blocks: T[],\n mode: 'direct',\n): (T | ToolkitPortableTextDirectList)[]\nexport function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>(\n blocks: T[],\n mode: 'html',\n): (T | ToolkitPortableTextHtmlList)[]\nexport function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>(\n blocks: T[],\n mode: 'direct' | 'html',\n): (T | ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList)[]\nexport function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>(\n blocks: T[],\n mode: ToolkitListNestMode,\n): ToolkitNestListsOutputNode<T>[] {\n const tree: ToolkitNestListsOutputNode<T>[] = []\n let currentList: ToolkitPortableTextList | undefined\n\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i]\n if (!block) {\n continue\n }\n\n if (!isPortableTextListItemBlock(block)) {\n tree.push(block)\n currentList = undefined\n continue\n }\n\n // Start of a new list?\n if (!currentList) {\n currentList = listFromBlock(block, i, mode)\n tree.push(currentList)\n continue\n }\n\n // New list item within same list?\n if (blockMatchesList(block, currentList)) {\n currentList.children.push(block)\n continue\n }\n\n // Different list props, are we going deeper?\n if ((block.level || 1) > currentList.level) {\n const newList = listFromBlock(block, i, mode)\n\n if (mode === 'html') {\n // Because HTML is kinda weird, nested lists needs to be nested within list items.\n // So while you would think that we could populate the parent list with a new sub-list,\n // we actually have to target the last list element (child) of the parent.\n // However, at this point we need to be very careful - simply pushing to the list of children\n // will mutate the input, and we don't want to blindly clone the entire tree.\n\n // Clone the last child while adding our new list as the last child of it\n const lastListItem = currentList.children[\n currentList.children.length - 1\n ] as ToolkitPortableTextListItem\n\n const newLastChild: ToolkitPortableTextListItem = {\n ...lastListItem,\n children: [...lastListItem.children, newList],\n }\n\n // Swap the last child\n currentList.children[currentList.children.length - 1] = newLastChild\n } else {\n ;(currentList as ToolkitPortableTextDirectList).children.push(\n newList as ToolkitPortableTextDirectList,\n )\n }\n\n // Set the newly created, deeper list as the current\n currentList = newList\n continue\n }\n\n // Different list props, are we going back up the tree?\n if ((block.level || 1) < currentList.level) {\n // Current list has ended, and we need to hook up with a parent of the same level and type\n const matchingBranch = tree[tree.length - 1]\n const match = matchingBranch && findListMatching(matchingBranch, block)\n if (match) {\n currentList = match\n currentList.children.push(block)\n continue\n }\n\n // Similar parent can't be found, assume new list\n currentList = listFromBlock(block, i, mode)\n tree.push(currentList)\n continue\n }\n\n // Different list props, different list style?\n if (block.listItem !== currentList.listItem) {\n const matchingBranch = tree[tree.length - 1]\n const match = matchingBranch && findListMatching(matchingBranch, {level: block.level || 1})\n if (match && match.listItem === block.listItem) {\n currentList = match\n currentList.children.push(block)\n continue\n } else {\n currentList = listFromBlock(block, i, mode)\n tree.push(currentList)\n continue\n }\n }\n\n // eslint-disable-next-line no-console\n console.warn('Unknown state encountered for block', block)\n tree.push(block)\n }\n\n return tree\n}\n\nfunction blockMatchesList(block: PortableTextBlock, list: ToolkitPortableTextList) {\n return (block.level || 1) === list.level && block.listItem === list.listItem\n}\n\nfunction listFromBlock(\n block: PortableTextListItemBlock,\n index: number,\n mode: ToolkitListNestMode,\n): ToolkitPortableTextList {\n return {\n _type: '@list',\n _key: `${block._key || `${index}`}-parent`,\n mode,\n level: block.level || 1,\n listItem: block.listItem,\n children: [block],\n }\n}\n\nfunction findListMatching<T extends TypedObject | PortableTextBlock>(\n rootNode: T,\n matching: Partial<PortableTextListItemBlock>,\n): ToolkitPortableTextList | undefined {\n const level = matching.level || 1\n const style = matching.listItem || 'normal'\n const filterOnType = typeof matching.listItem === 'string'\n if (\n isPortableTextToolkitList(rootNode) &&\n (rootNode.level || 1) === level &&\n filterOnType &&\n (rootNode.listItem || 'normal') === style\n ) {\n return rootNode\n }\n\n if (!('children' in rootNode)) {\n return undefined\n }\n\n const node = rootNode.children[rootNode.children.length - 1]\n return node && !isPortableTextSpan(node) ? findListMatching(node, matching) : undefined\n}\n","import {isPortableTextToolkitSpan, isPortableTextToolkitTextNode} from './asserters'\nimport type {ToolkitNestedPortableTextSpan} from './types'\n\n/**\n * Returns the plain-text representation of a\n * {@link ToolkitNestedPortableTextSpan | toolkit-specific Portable Text span}.\n *\n * Useful if you have a subset of nested nodes and want the text from just those,\n * instead of for the entire Portable Text block.\n *\n * @param span - Span node to get text from (Portable Text toolkit specific type)\n * @returns The plain-text version of the span\n */\nexport function spanToPlainText(span: ToolkitNestedPortableTextSpan): string {\n let text = ''\n span.children.forEach((current) => {\n if (isPortableTextToolkitTextNode(current)) {\n text += current.text\n } else if (isPortableTextToolkitSpan(current)) {\n text += spanToPlainText(current)\n }\n })\n return text\n}\n","import type {ArbitraryTypedObject, PortableTextBlock} from '@portabletext/types'\n\nimport {isPortableTextBlock, isPortableTextSpan} from './asserters'\n\nconst leadingSpace = /^\\s/\nconst trailingSpace = /\\s$/\n\n/**\n * Takes a Portable Text block (or an array of them) and returns the text value\n * of all the Portable Text span nodes. Adds whitespace when encountering inline,\n * non-span nodes to ensure text flow is optimal.\n *\n * Note that this only accounts for regular Portable Text blocks - any text inside\n * custom content types are not included in the output.\n *\n * @param block - Single block or an array of blocks to extract text from\n * @returns The plain-text content of the blocks\n */\nexport function toPlainText(\n block: PortableTextBlock | ArbitraryTypedObject[] | PortableTextBlock[],\n): string {\n const blocks = Array.isArray(block) ? block : [block]\n let text = ''\n\n blocks.forEach((current, index) => {\n if (!isPortableTextBlock(current)) {\n return\n }\n\n let pad = false\n current.children.forEach((span) => {\n if (isPortableTextSpan(span)) {\n // If the previous element was a non-span, and we have no natural whitespace\n // between the previous and the next span, insert it to give the spans some\n // room to breathe. However, don't do so if this is the first span.\n text += pad && text && !trailingSpace.test(text) && !leadingSpace.test(span.text) ? ' ' : ''\n text += span.text\n pad = false\n } else {\n pad = true\n }\n })\n\n if (index !== blocks.length - 1) {\n text += '\\n\\n'\n }\n })\n\n return text\n}\n","import type {\n ArbitraryTypedObject,\n PortableTextListItemBlock,\n PortableTextMarkDefinition,\n PortableTextSpan,\n} from '@portabletext/types'\n\n/**\n * List nesting mode for HTML, see the {@link nestLists | `nestLists()` function}\n */\nexport const LIST_NEST_MODE_HTML = 'html'\n\n/**\n * List nesting mode for direct, nested lists, see the {@link nestLists | `nestLists()` function}\n */\nexport const LIST_NEST_MODE_DIRECT = 'direct'\n\n/**\n * List nesting mode, see the {@link nestLists | `nestLists()` function}\n */\nexport type ToolkitListNestMode = 'html' | 'direct'\n\n/**\n * Toolkit-specific type representing a nested list\n *\n * See the `nestLists()` function for more info\n */\nexport type ToolkitPortableTextList = ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList\n\n/**\n * Toolkit-specific type representing a nested list in HTML mode, where deeper lists are nested\n * inside of the _list items_, eg `<ul><li>Some text<ul><li>Deeper</li></ul></li></ul>`\n */\nexport interface ToolkitPortableTextHtmlList {\n /**\n * Type name, prefixed with `@` to signal that this is a toolkit-specific node.\n */\n _type: '@list'\n\n /**\n * Unique key for this list (within its parent)\n */\n _key: string\n\n /**\n * List mode, signaling that list nodes will appear as children of the _list items_\n */\n mode: 'html'\n\n /**\n * Level/depth of this list node (starts at `1`)\n */\n level: number\n\n /**\n * Style of this list item (`bullet`, `number` are common values, but can be customized)\n */\n listItem: string\n\n /**\n * Child nodes of this list - toolkit-specific list items which can themselves hold deeper lists\n */\n children: ToolkitPortableTextListItem[]\n}\n\n/**\n * Toolkit-specific type representing a nested list in \"direct\" mode, where deeper lists are nested\n * inside of the lists children, alongside other blocks.\n */\nexport interface ToolkitPortableTextDirectList {\n /**\n * Type name, prefixed with `@` to signal that this is a toolkit-specific node.\n */\n _type: '@list'\n\n /**\n * Unique key for this list (within its parent)\n */\n _key: string\n\n /**\n * List mode, signaling that list nodes can appear as direct children\n */\n mode: 'direct'\n\n /**\n * Level/depth of this list node (starts at `1`)\n */\n level: number\n\n /**\n * Style of this list item (`bullet`, `number` are common values, but can be customized)\n */\n listItem: string\n\n /**\n * Child nodes of this list - either portable text list items, or another, deeper list\n */\n children: (PortableTextListItemBlock | ToolkitPortableTextDirectList)[]\n}\n\n/**\n * Toolkit-specific type representing a list item block, but where the children can be another list\n */\nexport interface ToolkitPortableTextListItem\n extends PortableTextListItemBlock<\n PortableTextMarkDefinition,\n PortableTextSpan | ToolkitPortableTextList\n > {}\n\n/**\n * Toolkit-specific type representing a text node, used when nesting spans.\n *\n * See the {@link buildMarksTree | `buildMarksTree()` function}\n */\nexport interface ToolkitTextNode {\n /**\n * Type name, prefixed with `@` to signal that this is a toolkit-specific node.\n */\n _type: '@text'\n\n /**\n * The actual string value of the text node\n */\n text: string\n}\n\n/**\n * Toolkit-specific type representing a portable text span that can hold other spans.\n * In this type, each span only has a single mark, instead of an array of them.\n */\nexport interface ToolkitNestedPortableTextSpan<\n M extends PortableTextMarkDefinition = PortableTextMarkDefinition,\n> {\n /**\n * Type name, prefixed with `@` to signal that this is a toolkit-specific node.\n */\n _type: '@span'\n\n /**\n * Unique key for this span\n */\n _key?: string\n\n /**\n * Holds the value (definition) of the mark in the case of annotations.\n * `undefined` if the mark is a decorator (strong, em or similar).\n */\n markDef?: M\n\n /**\n * The key of the mark definition (in the case of annotations).\n * `undefined` if the mark is a decorator (strong, em or similar).\n */\n markKey?: string\n\n /**\n * Type of the mark. For annotations, this is the `_type` property of the value.\n * For decorators, it will hold the name of the decorator (strong, em or similar).\n */\n markType: string\n\n /**\n * Child nodes of this span. Can be toolkit-specific text nodes, nested spans\n * or any inline object type.\n */\n children: (\n | ToolkitTextNode\n | ToolkitNestedPortableTextSpan<PortableTextMarkDefinition>\n | ArbitraryTypedObject\n )[]\n}\n"],"names":[],"mappings":"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"} |
-372
| import type {ArbitraryTypedObject} from '@portabletext/types' | ||
| import type {PortableTextBlock} from '@portabletext/types' | ||
| import type {PortableTextListItemBlock} from '@portabletext/types' | ||
| import type {PortableTextMarkDefinition} from '@portabletext/types' | ||
| import type {PortableTextSpan} from '@portabletext/types' | ||
| import type {TypedObject} from '@portabletext/types' | ||
| /** | ||
| * Takes a Portable Text block and returns a nested tree of nodes optimized for rendering | ||
| * in HTML-like environments where you want marks/annotations to be nested inside of eachother. | ||
| * For instance, a naive span-by-span rendering might yield: | ||
| * | ||
| * ```html | ||
| * <strong>This block contains </strong> | ||
| * <strong><a href="https://some.url/">a link</a></strong> | ||
| * <strong> and some bolded and </strong> | ||
| * <em><strong>italicized text</strong></em> | ||
| * ``` | ||
| * | ||
| * ...whereas an optimal order would be: | ||
| * | ||
| * ```html | ||
| * <strong> | ||
| * This block contains <a href="https://some.url/">a link</a> | ||
| * and some bolded and <em>italicized text</em> | ||
| * </strong> | ||
| * ``` | ||
| * | ||
| * Note that since "native" Portable Text spans cannot be nested, | ||
| * this function returns an array of "toolkit specific" types: | ||
| * {@link ToolkitTextNode | `@text`} and {@link ToolkitNestedPortableTextSpan | `@span` }. | ||
| * | ||
| * The toolkit-specific type can hold both types, as well as any arbitrary inline objects, | ||
| * creating an actual tree. | ||
| * | ||
| * @param block - The Portable Text block to create a tree of nodes from | ||
| * @returns Array of (potentially) nested spans, text nodes and/or arbitrary inline objects | ||
| */ | ||
| export declare function buildMarksTree< | ||
| M extends PortableTextMarkDefinition = PortableTextMarkDefinition, | ||
| >( | ||
| block: PortableTextBlock<M>, | ||
| ): (ToolkitNestedPortableTextSpan<M> | ToolkitTextNode | ArbitraryTypedObject)[] | ||
| /** | ||
| * Strict check to determine if node is a correctly formatted Portable Text block. | ||
| * | ||
| * @param node - Node to check | ||
| * @returns True if valid Portable Text block, otherwise false | ||
| */ | ||
| export declare function isPortableTextBlock( | ||
| node: PortableTextBlock | TypedObject, | ||
| ): node is PortableTextBlock | ||
| /** | ||
| * Strict check to determine if node is a correctly formatted portable list item block. | ||
| * | ||
| * @param block - Block to check | ||
| * @returns True if valid Portable Text list item block, otherwise false | ||
| */ | ||
| export declare function isPortableTextListItemBlock( | ||
| block: PortableTextBlock | TypedObject, | ||
| ): block is PortableTextListItemBlock | ||
| /** | ||
| * Strict check to determine if node is a correctly formatted Portable Text span. | ||
| * | ||
| * @param node - Node to check | ||
| * @returns True if valid Portable Text span, otherwise false | ||
| */ | ||
| export declare function isPortableTextSpan( | ||
| node: ArbitraryTypedObject | PortableTextSpan, | ||
| ): node is PortableTextSpan | ||
| /** | ||
| * Loose check to determine if block is a toolkit list node. | ||
| * Only checks `_type`, assumes correct structure. | ||
| * | ||
| * @param block - Block to check | ||
| * @returns True if toolkit list, otherwise false | ||
| */ | ||
| export declare function isPortableTextToolkitList( | ||
| block: TypedObject | ToolkitPortableTextList, | ||
| ): block is ToolkitPortableTextList | ||
| /** | ||
| * Loose check to determine if span is a toolkit span node. | ||
| * Only checks `_type`, assumes correct structure. | ||
| * | ||
| * @param span - Span to check | ||
| * @returns True if toolkit span, otherwise false | ||
| */ | ||
| export declare function isPortableTextToolkitSpan( | ||
| span: TypedObject | ToolkitNestedPortableTextSpan, | ||
| ): span is ToolkitNestedPortableTextSpan | ||
| /** | ||
| * Loose check to determine if node is a toolkit text node. | ||
| * Only checks `_type`, assumes correct structure. | ||
| * | ||
| * @param node - Node to check | ||
| * @returns True if toolkit text node, otherwise false | ||
| */ | ||
| export declare function isPortableTextToolkitTextNode( | ||
| node: TypedObject | ToolkitTextNode, | ||
| ): node is ToolkitTextNode | ||
| /** | ||
| * List nesting mode for direct, nested lists, see the {@link nestLists | `nestLists()` function} | ||
| */ | ||
| export declare const LIST_NEST_MODE_DIRECT = 'direct' | ||
| /** | ||
| * List nesting mode for HTML, see the {@link nestLists | `nestLists()` function} | ||
| */ | ||
| export declare const LIST_NEST_MODE_HTML = 'html' | ||
| /** | ||
| * Takes an array of blocks and returns an array of nodes optimized for rendering in HTML-like | ||
| * environment, where lists are nested inside of eachother instead of appearing "flat" as in | ||
| * native Portable Text data structures. | ||
| * | ||
| * Note that the list node is not a native Portable Text node type, and thus is represented | ||
| * using the {@link ToolkitPortableTextList | `@list`} type name (`{_type: '@list'}`). | ||
| * | ||
| * The nesting can be configured in two modes: | ||
| * | ||
| * - `direct`: deeper list nodes will appear as a direct child of the parent list | ||
| * - `html`, deeper list nodes will appear as a child of the last _list item_ in the parent list | ||
| * | ||
| * When using `direct`, all list nodes will be of type {@link ToolkitPortableTextDirectList}, | ||
| * while with `html` they will be of type {@link ToolkitPortableTextHtmlList} | ||
| * | ||
| * These modes are available as {@link LIST_NEST_MODE_HTML} and {@link LIST_NEST_MODE_DIRECT}. | ||
| * | ||
| * @param blocks - Array of Portable Text blocks and other arbitrary types | ||
| * @param mode - Mode to use for nesting, `direct` or `html` | ||
| * @returns Array of potentially nested nodes optimized for rendering | ||
| */ | ||
| export declare function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>( | ||
| blocks: T[], | ||
| mode: 'direct', | ||
| ): (T | ToolkitPortableTextDirectList)[] | ||
| export declare function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>( | ||
| blocks: T[], | ||
| mode: 'html', | ||
| ): (T | ToolkitPortableTextHtmlList)[] | ||
| export declare function nestLists<T extends TypedObject = PortableTextBlock | TypedObject>( | ||
| blocks: T[], | ||
| mode: 'direct' | 'html', | ||
| ): (T | ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList)[] | ||
| /** | ||
| * Figures out the optimal order of marks, in order to minimize the amount of | ||
| * nesting/repeated elements in environments such as HTML. For instance, a naive | ||
| * implementation might render something like: | ||
| * | ||
| * ```html | ||
| * <strong>This block contains </strong> | ||
| * <strong><a href="https://some.url/">a link</a></strong> | ||
| * <strong> and some bolded text</strong> | ||
| * ``` | ||
| * | ||
| * ...whereas an optimal order would be: | ||
| * | ||
| * ```html | ||
| * <strong> | ||
| * This block contains <a href="https://some.url/">a link</a> and some bolded text | ||
| * </strong> | ||
| * ``` | ||
| * | ||
| * This is particularly necessary for cases like links, where you don't want multiple | ||
| * individual links for different segments of the link text, even if parts of it are | ||
| * bolded/italicized. | ||
| * | ||
| * This function is meant to be used like: `block.children.map(sortMarksByOccurences)`, | ||
| * and is used internally in {@link buildMarksTree | `buildMarksTree()`}. | ||
| * | ||
| * The marks are sorted in the following order: | ||
| * | ||
| * 1. Marks that are shared amongst the most adjacent siblings | ||
| * 2. Non-default marks (links, custom metadata) | ||
| * 3. Decorators (bold, emphasis, code etc), in a predefined, preferred order | ||
| * | ||
| * @param span - The current span to sort | ||
| * @param index - The index of the current span within the block | ||
| * @param blockChildren - All children of the block being sorted | ||
| * @returns Array of decorators and annotations, sorted by "most adjacent siblings" | ||
| */ | ||
| export declare function sortMarksByOccurences( | ||
| span: PortableTextSpan | TypedObject, | ||
| index: number, | ||
| blockChildren: (PortableTextSpan | TypedObject)[], | ||
| ): string[] | ||
| /** | ||
| * Returns the plain-text representation of a | ||
| * {@link ToolkitNestedPortableTextSpan | toolkit-specific Portable Text span}. | ||
| * | ||
| * Useful if you have a subset of nested nodes and want the text from just those, | ||
| * instead of for the entire Portable Text block. | ||
| * | ||
| * @param span - Span node to get text from (Portable Text toolkit specific type) | ||
| * @returns The plain-text version of the span | ||
| */ | ||
| export declare function spanToPlainText(span: ToolkitNestedPortableTextSpan): string | ||
| /** | ||
| * List nesting mode, see the {@link nestLists | `nestLists()` function} | ||
| */ | ||
| export declare type ToolkitListNestMode = 'html' | 'direct' | ||
| /** | ||
| * Toolkit-specific type representing a portable text span that can hold other spans. | ||
| * In this type, each span only has a single mark, instead of an array of them. | ||
| */ | ||
| export declare interface ToolkitNestedPortableTextSpan< | ||
| M extends PortableTextMarkDefinition = PortableTextMarkDefinition, | ||
| > { | ||
| /** | ||
| * Type name, prefixed with `@` to signal that this is a toolkit-specific node. | ||
| */ | ||
| _type: '@span' | ||
| /** | ||
| * Unique key for this span | ||
| */ | ||
| _key?: string | ||
| /** | ||
| * Holds the value (definition) of the mark in the case of annotations. | ||
| * `undefined` if the mark is a decorator (strong, em or similar). | ||
| */ | ||
| markDef?: M | ||
| /** | ||
| * The key of the mark definition (in the case of annotations). | ||
| * `undefined` if the mark is a decorator (strong, em or similar). | ||
| */ | ||
| markKey?: string | ||
| /** | ||
| * Type of the mark. For annotations, this is the `_type` property of the value. | ||
| * For decorators, it will hold the name of the decorator (strong, em or similar). | ||
| */ | ||
| markType: string | ||
| /** | ||
| * Child nodes of this span. Can be toolkit-specific text nodes, nested spans | ||
| * or any inline object type. | ||
| */ | ||
| children: ( | ||
| | ToolkitTextNode | ||
| | ToolkitNestedPortableTextSpan<PortableTextMarkDefinition> | ||
| | ArbitraryTypedObject | ||
| )[] | ||
| } | ||
| export declare type ToolkitNestListsOutputNode<T> = | ||
| | T | ||
| | ToolkitPortableTextHtmlList | ||
| | ToolkitPortableTextDirectList | ||
| /** | ||
| * Toolkit-specific type representing a nested list in "direct" mode, where deeper lists are nested | ||
| * inside of the lists children, alongside other blocks. | ||
| */ | ||
| export declare interface ToolkitPortableTextDirectList { | ||
| /** | ||
| * Type name, prefixed with `@` to signal that this is a toolkit-specific node. | ||
| */ | ||
| _type: '@list' | ||
| /** | ||
| * Unique key for this list (within its parent) | ||
| */ | ||
| _key: string | ||
| /** | ||
| * List mode, signaling that list nodes can appear as direct children | ||
| */ | ||
| mode: 'direct' | ||
| /** | ||
| * Level/depth of this list node (starts at `1`) | ||
| */ | ||
| level: number | ||
| /** | ||
| * Style of this list item (`bullet`, `number` are common values, but can be customized) | ||
| */ | ||
| listItem: string | ||
| /** | ||
| * Child nodes of this list - either portable text list items, or another, deeper list | ||
| */ | ||
| children: (PortableTextListItemBlock | ToolkitPortableTextDirectList)[] | ||
| } | ||
| /** | ||
| * Toolkit-specific type representing a nested list in HTML mode, where deeper lists are nested | ||
| * inside of the _list items_, eg `<ul><li>Some text<ul><li>Deeper</li></ul></li></ul>` | ||
| */ | ||
| export declare interface ToolkitPortableTextHtmlList { | ||
| /** | ||
| * Type name, prefixed with `@` to signal that this is a toolkit-specific node. | ||
| */ | ||
| _type: '@list' | ||
| /** | ||
| * Unique key for this list (within its parent) | ||
| */ | ||
| _key: string | ||
| /** | ||
| * List mode, signaling that list nodes will appear as children of the _list items_ | ||
| */ | ||
| mode: 'html' | ||
| /** | ||
| * Level/depth of this list node (starts at `1`) | ||
| */ | ||
| level: number | ||
| /** | ||
| * Style of this list item (`bullet`, `number` are common values, but can be customized) | ||
| */ | ||
| listItem: string | ||
| /** | ||
| * Child nodes of this list - toolkit-specific list items which can themselves hold deeper lists | ||
| */ | ||
| children: ToolkitPortableTextListItem[] | ||
| } | ||
| /** | ||
| * Toolkit-specific type representing a nested list | ||
| * | ||
| * See the `nestLists()` function for more info | ||
| */ | ||
| export declare type ToolkitPortableTextList = | ||
| | ToolkitPortableTextHtmlList | ||
| | ToolkitPortableTextDirectList | ||
| /** | ||
| * Toolkit-specific type representing a list item block, but where the children can be another list | ||
| */ | ||
| export declare interface ToolkitPortableTextListItem | ||
| extends PortableTextListItemBlock< | ||
| PortableTextMarkDefinition, | ||
| PortableTextSpan | ToolkitPortableTextList | ||
| > {} | ||
| /** | ||
| * Toolkit-specific type representing a text node, used when nesting spans. | ||
| * | ||
| * See the {@link buildMarksTree | `buildMarksTree()` function} | ||
| */ | ||
| export declare interface ToolkitTextNode { | ||
| /** | ||
| * Type name, prefixed with `@` to signal that this is a toolkit-specific node. | ||
| */ | ||
| _type: '@text' | ||
| /** | ||
| * The actual string value of the text node | ||
| */ | ||
| text: string | ||
| } | ||
| /** | ||
| * Takes a Portable Text block (or an array of them) and returns the text value | ||
| * of all the Portable Text span nodes. Adds whitespace when encountering inline, | ||
| * non-span nodes to ensure text flow is optimal. | ||
| * | ||
| * Note that this only accounts for regular Portable Text blocks - any text inside | ||
| * custom content types are not included in the output. | ||
| * | ||
| * @param block - Single block or an array of blocks to extract text from | ||
| * @returns The plain-text content of the blocks | ||
| */ | ||
| export declare function toPlainText( | ||
| block: PortableTextBlock | ArbitraryTypedObject[] | PortableTextBlock[], | ||
| ): string | ||
| export {} |
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
3
-66.67%0
-100%81554
-39.31%14
-17.65%1281
-14.31%1
Infinity%