@portabletext/toolkit
Advanced tools
Comparing version 2.0.10 to 2.0.11
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } | ||
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } | ||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); } | ||
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | ||
function isPortableTextSpan(node) { | ||
return node._type === "span" && "text" in node && typeof node.text === "string" && (typeof node.marks === "undefined" || Array.isArray(node.marks) && node.marks.every(mark => typeof mark === "string")); | ||
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")); | ||
} | ||
@@ -13,3 +13,3 @@ function isPortableTextBlock(node) { | ||
// allowed child types and marks, one might name them differently | ||
typeof node._type === "string" && | ||
typeof node._type == "string" && | ||
// Toolkit-types like nested spans are @-prefixed | ||
@@ -20,11 +20,11 @@ node._type[0] !== "@" && ( | ||
// Every mark definition needs to have an `_key` to be mappable in child spans | ||
node.markDefs.every(def => typeof def._key === "string")) && | ||
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) | ||
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 === "undefined" || typeof block.level === "number"); | ||
return isPortableTextBlock(block) && "listItem" in block && typeof block.listItem == "string" && (typeof block.level > "u" || typeof block.level == "number"); | ||
} | ||
@@ -42,35 +42,21 @@ function isPortableTextToolkitList(block) { | ||
function sortMarksByOccurences(span, index, blockChildren) { | ||
if (!isPortableTextSpan(span) || !span.marks) { | ||
return []; | ||
} | ||
if (!span.marks.length) { | ||
return []; | ||
} | ||
const marks = span.marks.slice(); | ||
const occurences = {}; | ||
marks.forEach(mark => { | ||
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; | ||
} | ||
if (sibling && isPortableTextSpan(sibling) && Array.isArray(sibling.marks) && sibling.marks.indexOf(mark) !== -1) occurences[mark]++;else break; | ||
} | ||
}); | ||
return marks.sort((markA, markB) => sortMarks(occurences, markA, markB)); | ||
}), marks.sort((markA, markB) => sortMarks(occurences, markA, markB)); | ||
} | ||
function sortMarks(occurences, markA, markB) { | ||
const aOccurences = occurences[markA]; | ||
const bOccurences = occurences[markB]; | ||
if (aOccurences !== bOccurences) { | ||
return bOccurences - aOccurences; | ||
} | ||
const aKnownPos = knownDecorators.indexOf(markA); | ||
const bKnownPos = knownDecorators.indexOf(markB); | ||
if (aKnownPos !== bKnownPos) { | ||
return aKnownPos - bKnownPos; | ||
} | ||
return markA.localeCompare(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); | ||
} | ||
@@ -83,60 +69,47 @@ function buildMarksTree(block) { | ||
} = block; | ||
if (!children || !children.length) { | ||
return []; | ||
} | ||
const sortedMarks = children.map(sortMarksByOccurences); | ||
const rootNode = { | ||
_type: "@span", | ||
children: [], | ||
markType: "<unknown>" | ||
}; | ||
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; | ||
} | ||
if (!span) continue; | ||
const marksNeeded = sortedMarks[i] || []; | ||
let pos = 1; | ||
if (nodeStack.length > 1) { | ||
for (pos; pos < nodeStack.length; pos++) { | ||
const mark = ((_a = nodeStack[pos]) == null ? void 0 : _a.markKey) || ""; | ||
const index = marksNeeded.indexOf(mark); | ||
if (index === -1) { | ||
break; | ||
} | ||
marksNeeded.splice(index, 1); | ||
} | ||
if (nodeStack.length > 1) for (pos; pos < nodeStack.length; pos++) { | ||
const mark = ((_a = nodeStack[pos]) == null ? void 0 : _a.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) { | ||
continue; | ||
} | ||
for (const markKey of marksNeeded) { | ||
const markDef = markDefs.find(def => def._key === markKey); | ||
const markType = markDef ? markDef._type : markKey; | ||
const 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("\n"); | ||
for (let line = lines.length; line-- > 1;) { | ||
lines.splice(line, 0, "\n"); | ||
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; | ||
} | ||
currentNode.children = currentNode.children.concat(lines.map(text => ({ | ||
_type: "@text", | ||
text | ||
}))); | ||
} else { | ||
currentNode.children = currentNode.children.concat(span); | ||
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); | ||
} | ||
@@ -151,62 +124,52 @@ } | ||
const block = blocks[i]; | ||
if (!block) { | ||
continue; | ||
} | ||
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]; | ||
const newLastChild = _objectSpread(_objectSpread({}, lastListItem), {}, { | ||
children: [...lastListItem.children, newList] | ||
}); | ||
currentList.children[currentList.children.length - 1] = newLastChild; | ||
} else { | ||
currentList.children.push(newList); | ||
if (block) { | ||
if (!isPortableTextListItemBlock(block)) { | ||
tree.push(block), currentList = void 0; | ||
continue; | ||
} | ||
currentList = newList; | ||
continue; | ||
} | ||
if ((block.level || 1) < currentList.level) { | ||
const matchingBranch = tree[tree.length - 1]; | ||
const match = matchingBranch && findListMatching(matchingBranch, block); | ||
if (match) { | ||
currentList = match; | ||
currentList.children.push(block); | ||
if (!currentList) { | ||
currentList = listFromBlock(block, i, mode), tree.push(currentList); | ||
continue; | ||
} | ||
currentList = listFromBlock(block, i, mode); | ||
tree.push(currentList); | ||
continue; | ||
} | ||
if (block.listItem !== currentList.listItem) { | ||
const matchingBranch = tree[tree.length - 1]; | ||
const match = matchingBranch && findListMatching(matchingBranch, { | ||
level: block.level || 1 | ||
}); | ||
if (match && match.listItem === block.listItem) { | ||
currentList = match; | ||
if (blockMatchesList(block, currentList)) { | ||
currentList.children.push(block); | ||
continue; | ||
} else { | ||
currentList = listFromBlock(block, i, mode); | ||
tree.push(currentList); | ||
} | ||
if ((block.level || 1) > currentList.level) { | ||
const newList = listFromBlock(block, i, mode); | ||
if (mode === "html") { | ||
const lastListItem = currentList.children[currentList.children.length - 1], | ||
newLastChild = _objectSpread(_objectSpread({}, 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); | ||
} | ||
console.warn("Unknown state encountered for block", block); | ||
tree.push(block); | ||
} | ||
@@ -221,3 +184,3 @@ return tree; | ||
_type: "@list", | ||
_key: "".concat(block._key || "".concat(index), "-parent"), | ||
_key: `${block._key || `${index}`}-parent`, | ||
mode, | ||
@@ -230,53 +193,34 @@ level: block.level || 1, | ||
function findListMatching(rootNode, matching) { | ||
const level = matching.level || 1; | ||
const style = matching.listItem || "normal"; | ||
const filterOnType = typeof matching.listItem === "string"; | ||
if (isPortableTextToolkitList(rootNode) && (rootNode.level || 1) === level && filterOnType && (rootNode.listItem || "normal") === style) { | ||
return rootNode; | ||
} | ||
if (!("children" in rootNode)) { | ||
return void 0; | ||
} | ||
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; | ||
} | ||
const leadingSpace = /^\s/; | ||
const trailingSpace = /^\s/; | ||
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 = ""; | ||
blocks.forEach((current, index) => { | ||
if (!isPortableTextBlock(current)) { | ||
return; | ||
} | ||
let pad = false; | ||
return blocks.forEach((current, index) => { | ||
if (!isPortableTextBlock(current)) return; | ||
let pad = !1; | ||
current.children.forEach(span => { | ||
if (isPortableTextSpan(span)) { | ||
text += pad && text && !trailingSpace.test(text) && !leadingSpace.test(span.text) ? " " : ""; | ||
text += span.text; | ||
pad = false; | ||
} else { | ||
pad = true; | ||
} | ||
}); | ||
if (index !== blocks.length - 1) { | ||
text += "\n\n"; | ||
} | ||
}); | ||
return text; | ||
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; | ||
} | ||
function spanToPlainText(span) { | ||
let text = ""; | ||
span.children.forEach(current => { | ||
if (isPortableTextToolkitTextNode(current)) { | ||
text += current.text; | ||
} else if (isPortableTextToolkitSpan(current)) { | ||
text += spanToPlainText(current); | ||
} | ||
}); | ||
return text; | ||
} | ||
const LIST_NEST_MODE_HTML = "html"; | ||
const LIST_NEST_MODE_DIRECT = "direct"; | ||
const LIST_NEST_MODE_HTML = "html", | ||
LIST_NEST_MODE_DIRECT = "direct"; | ||
export { LIST_NEST_MODE_DIRECT, LIST_NEST_MODE_HTML, buildMarksTree, isPortableTextBlock, isPortableTextListItemBlock, isPortableTextSpan, isPortableTextToolkitList, isPortableTextToolkitSpan, isPortableTextToolkitTextNode, nestLists, sortMarksByOccurences, spanToPlainText, toPlainText }; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@portabletext/toolkit", | ||
"version": "2.0.10", | ||
"version": "2.0.11", | ||
"description": "Toolkit of handy utility functions for dealing with Portable Text", | ||
@@ -29,8 +29,4 @@ "keywords": [ | ||
"source": "./src/index.ts", | ||
"import": "./dist/index.js", | ||
"require": "./dist/index.cjs", | ||
"node": { | ||
"module": "./dist/index.js", | ||
"import": "./dist/index.cjs.js" | ||
}, | ||
"import": "./dist/index.js", | ||
"default": "./dist/index.js" | ||
@@ -59,2 +55,3 @@ }, | ||
}, | ||
"browserslist": "extends @sanity/browserslist-config", | ||
"prettier": { | ||
@@ -87,30 +84,30 @@ "bracketSpacing": false, | ||
"dependencies": { | ||
"@portabletext/types": "^2.0.8" | ||
"@portabletext/types": "^2.0.9" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.23.0", | ||
"@babel/core": "^7.24.0", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.20.7", | ||
"@commitlint/cli": "^17.7.2", | ||
"@commitlint/config-conventional": "^17.7.0", | ||
"@sanity/pkg-utils": "^3.0.0", | ||
"@types/node": "^20.8.4", | ||
"@typescript-eslint/eslint-plugin": "^6.7.5", | ||
"@typescript-eslint/parser": "^6.7.5", | ||
"@vitest/coverage-v8": "^0.34.6", | ||
"@commitlint/cli": "^19.2.0", | ||
"@commitlint/config-conventional": "^19.1.0", | ||
"@sanity/pkg-utils": "^5.0.2", | ||
"@types/node": "^20.8.7", | ||
"@typescript-eslint/eslint-plugin": "^7.2.0", | ||
"@typescript-eslint/parser": "^7.2.0", | ||
"@vitest/coverage-v8": "^1.4.0", | ||
"commitizen": "^4.3.0", | ||
"cz-conventional-changelog": "^3.3.0", | ||
"eslint": "^8.51.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"eslint-config-sanity": "^6.0.0", | ||
"eslint": "^8.57.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-config-sanity": "^7.1.1", | ||
"husky": "^8.0.3", | ||
"npm-run-all": "^4.1.5", | ||
"prettier": "^3.0.3", | ||
"prettier-plugin-packagejson": "^2.4.6", | ||
"npm-run-all2": "^5.0.0", | ||
"prettier": "^3.2.5", | ||
"prettier-plugin-packagejson": "^2.4.12", | ||
"rimraf": "^4.4.1", | ||
"typedoc": "^0.25.2", | ||
"typescript": "^5.2.2", | ||
"vitest": "^0.34.6", | ||
"vitest-github-actions-reporter": "^0.10.0" | ||
"typedoc": "^0.25.12", | ||
"typescript": "^5.4.2", | ||
"vitest": "^1.4.0", | ||
"vitest-github-actions-reporter": "^0.11.1" | ||
}, | ||
"packageManager": "pnpm@8.9.0", | ||
"packageManager": "pnpm@8.15.4", | ||
"engines": { | ||
@@ -117,0 +114,0 @@ "node": "^14.13.1 || >=16.0.0" |
@@ -8,2 +8,3 @@ import type { | ||
} from '@portabletext/types' | ||
import type {ToolkitNestedPortableTextSpan, ToolkitPortableTextList, ToolkitTextNode} from './types' | ||
@@ -10,0 +11,0 @@ |
@@ -6,5 +6,6 @@ import type { | ||
} from '@portabletext/types' | ||
import type {ToolkitNestedPortableTextSpan, ToolkitTextNode} from './types' | ||
import {isPortableTextSpan} from './asserters' | ||
import {sortMarksByOccurences} from './sortMarksByOccurences' | ||
import type {ToolkitNestedPortableTextSpan, ToolkitTextNode} from './types' | ||
@@ -11,0 +12,0 @@ /** |
@@ -5,4 +5,4 @@ export * from './asserters' | ||
export * from './sortMarksByOccurences' | ||
export * from './spanToPlainText' | ||
export * from './toPlainText' | ||
export * from './spanToPlainText' | ||
export * from './types' |
import type {PortableTextBlock, PortableTextListItemBlock, TypedObject} from '@portabletext/types' | ||
import { | ||
isPortableTextListItemBlock, | ||
isPortableTextSpan, | ||
isPortableTextToolkitList, | ||
} from './asserters' | ||
import type { | ||
@@ -9,7 +15,2 @@ ToolkitListNestMode, | ||
} from './types' | ||
import { | ||
isPortableTextListItemBlock, | ||
isPortableTextSpan, | ||
isPortableTextToolkitList, | ||
} from './asserters' | ||
@@ -16,0 +17,0 @@ export type ToolkitNestListsOutputNode<T> = |
import type {PortableTextSpan, TypedObject} from '@portabletext/types' | ||
import {isPortableTextSpan} from './asserters' | ||
@@ -3,0 +4,0 @@ |
@@ -0,3 +1,3 @@ | ||
import {isPortableTextToolkitSpan, isPortableTextToolkitTextNode} from './asserters' | ||
import type {ToolkitNestedPortableTextSpan} from './types' | ||
import {isPortableTextToolkitSpan, isPortableTextToolkitTextNode} from './asserters' | ||
@@ -4,0 +4,0 @@ /** |
import type {ArbitraryTypedObject, PortableTextBlock} from '@portabletext/types' | ||
import {isPortableTextBlock, isPortableTextSpan} from './asserters' | ||
@@ -3,0 +4,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
133955
16
1511
0
Updated@portabletext/types@^2.0.9