@prosekit/extensions
Advanced tools
Comparing version 0.0.0-next-20240620223217 to 0.0.0-next-20240621205958
@@ -12,3 +12,4 @@ import { Attrs } from '@prosekit/pm/model'; | ||
import { Extension } from '@prosekit/core'; | ||
import { getHighlighter } from 'shiki/bundle/full'; | ||
import { getSingletonHighlighter } from 'shiki/bundle/full'; | ||
import type { Highlighter } from 'shiki'; | ||
import { IndentListOptions } from 'prosemirror-flat-list'; | ||
@@ -26,3 +27,2 @@ import { InputRule } from '@prosekit/pm/inputrules'; | ||
import { ProseMirrorNode } from '@prosekit/pm/model'; | ||
import { Slice } from '@prosekit/pm/model'; | ||
import type { SpecialLanguage } from 'shiki'; | ||
@@ -94,3 +94,4 @@ import { ToggleCollapsedOptions } from 'prosemirror-flat-list'; | ||
/** | ||
* Theme registation | ||
* A list of shiki themes to pre-load. The first theme in the list will be | ||
* used to render the code block. | ||
* | ||
@@ -101,3 +102,3 @@ * @default ['one-dark-pro'] | ||
/** | ||
* Language registation | ||
* A list of shiki languages to pre-load. | ||
* | ||
@@ -925,33 +926,7 @@ * @default ['text'] | ||
declare const findNext: Command; | ||
export { findNext } | ||
export { findNext as findNext_alias_1 } | ||
declare const findNextNoWrap: Command; | ||
export { findNextNoWrap } | ||
export { findNextNoWrap as findNextNoWrap_alias_1 } | ||
declare const findPrev: Command; | ||
export { findPrev } | ||
export { findPrev as findPrev_alias_1 } | ||
declare const findPrevNoWrap: Command; | ||
export { findPrevNoWrap } | ||
export { findPrevNoWrap as findPrevNoWrap_alias_1 } | ||
export declare function getCheckRanges(transactions: readonly Transaction[], oldState: EditorState, newState: EditorState): Array<[number, number]>; | ||
export { getHighlighter } | ||
export declare function getPluginState(state: EditorState): PredictionPluginState | undefined; | ||
declare function getSearchState(state: EditorState): { | ||
query: SearchQuery; | ||
range: { | ||
from: number; | ||
to: number; | ||
} | null; | ||
} | undefined; | ||
export { getSearchState } | ||
export { getSearchState as getSearchState_alias_1 } | ||
export { getSingletonHighlighter } | ||
@@ -964,3 +939,3 @@ export declare function getTrMeta(tr: Transaction): PredictionPluginState; | ||
declare type HighlighterOptions = { | ||
export declare type HighlighterOptions = { | ||
themes: BundledTheme[]; | ||
@@ -971,2 +946,10 @@ langs: (BundledLanguage | SpecialLanguage)[]; | ||
declare type HighlighterResult = { | ||
highlighter: Highlighter; | ||
promise?: undefined; | ||
} | { | ||
highlighter?: undefined; | ||
promise: Promise<void>; | ||
}; | ||
/** | ||
@@ -1105,61 +1088,4 @@ * @public | ||
declare interface QueryImpl { | ||
findNext(state: EditorState, from: number, to: number): SearchResult | null; | ||
findPrev(state: EditorState, from: number, to: number): SearchResult | null; | ||
} | ||
export declare function prepareHighlighter(options: HighlighterOptions): HighlighterResult; | ||
declare const replaceAll: Command; | ||
export { replaceAll } | ||
export { replaceAll as replaceAll_alias_1 } | ||
declare const replaceCurrent: Command; | ||
export { replaceCurrent } | ||
export { replaceCurrent as replaceCurrent_alias_1 } | ||
declare const replaceNext: Command; | ||
export { replaceNext } | ||
export { replaceNext as replaceNext_alias_1 } | ||
declare const replaceNextNoWrap: Command; | ||
export { replaceNextNoWrap } | ||
export { replaceNextNoWrap as replaceNextNoWrap_alias_1 } | ||
declare function search(options?: { | ||
initialQuery?: SearchQuery; | ||
initialRange?: { | ||
from: number; | ||
to: number; | ||
}; | ||
}): Plugin_2; | ||
export { search } | ||
export { search as search_alias_1 } | ||
declare class SearchQuery { | ||
readonly search: string; | ||
readonly caseSensitive: boolean; | ||
readonly literal: boolean; | ||
readonly regexp: boolean; | ||
readonly replace: string; | ||
readonly valid: boolean; | ||
readonly wholeWord: boolean; | ||
impl: QueryImpl; | ||
constructor(config: { | ||
search: string; | ||
caseSensitive?: boolean; | ||
literal?: boolean; | ||
regexp?: boolean; | ||
replace?: string; | ||
wholeWord?: boolean; | ||
}); | ||
eq(other: SearchQuery): boolean; | ||
findNext(state: EditorState, from?: number, to?: number): SearchResult | null; | ||
findPrev(state: EditorState, from?: number, to?: number): SearchResult | null; | ||
checkResult(state: EditorState, result: SearchResult): boolean; | ||
unquote(string: string): string; | ||
getReplacement(state: EditorState, result: SearchResult): Slice; | ||
} | ||
export { SearchQuery } | ||
export { SearchQuery as SearchQuery_alias_1 } | ||
export { SearchQuery as SearchQuery_alias_2 } | ||
/** | ||
@@ -1207,18 +1133,2 @@ * Options for {@link defineSearchQuery} | ||
declare interface SearchResult { | ||
from: number; | ||
to: number; | ||
match: RegExpMatchArray | null; | ||
} | ||
export { SearchResult } | ||
export { SearchResult as SearchResult_alias_1 } | ||
export { SearchResult as SearchResult_alias_2 } | ||
declare function setSearchState(tr: Transaction, query: SearchQuery, range?: { | ||
from: number; | ||
to: number; | ||
} | null): Transaction; | ||
export { setSearchState } | ||
export { setSearchState as setSearchState_alias_1 } | ||
/** | ||
@@ -1278,4 +1188,2 @@ * @internal | ||
export declare function validRegExp(source: string): boolean; | ||
export { } |
@@ -126,22 +126,42 @@ import { | ||
import { createParser } from "prosemirror-highlight/shiki"; | ||
function createHighlighterLoader() { | ||
let highlighterPromise, highlighter, loadLangs = /* @__PURE__ */ new Set(); | ||
return function(lang, options) { | ||
return highlighterPromise ? highlighter ? loadLangs.has(lang) ? { highlighter } : { promise: highlighter.loadLanguage(lang).then(() => { | ||
loadLangs.add(lang); | ||
}).catch((error) => { | ||
console.warn(`Failed to load language '${lang}'`, error); | ||
}) } : { promise: highlighterPromise } : (highlighterPromise = import("./shiki-import-25BJYIO2.js").then(({ getHighlighter }) => getHighlighter(options)).then((h) => { | ||
highlighter = h; | ||
}), { promise: highlighterPromise }); | ||
}; | ||
// src/code-block/shiki-highlighter.ts | ||
var highlighter, loadedLangs = /* @__PURE__ */ new Set(), loadedThemes = /* @__PURE__ */ new Set(); | ||
async function createHighlighter(options) { | ||
let { getSingletonHighlighter } = await import("./shiki-import-UFUFVKJ2.js"); | ||
highlighter || (highlighter = await getSingletonHighlighter(options)); | ||
} | ||
async function loadLanguages(langs) { | ||
for (let lang of langs) { | ||
if (!highlighter) break; | ||
await highlighter.loadLanguage(lang), loadedLangs.add(lang); | ||
} | ||
} | ||
async function loadThemes(themes) { | ||
for (let theme of themes) { | ||
if (!highlighter) break; | ||
await highlighter.loadTheme(theme), loadedThemes.add(theme); | ||
} | ||
} | ||
function prepareHighlighter(options) { | ||
if (!highlighter) | ||
return { promise: createHighlighter(options) }; | ||
let langs = options.langs.filter((lang) => !loadedLangs.has(lang)); | ||
if (langs.length > 0) | ||
return { promise: loadLanguages(langs) }; | ||
let themes = options.themes.filter((theme) => !loadedThemes.has(theme)); | ||
return themes.length > 0 ? { promise: loadThemes(themes) } : { highlighter }; | ||
} | ||
// src/code-block/shiki-parser.ts | ||
function createLazyParser(highlighterOptions) { | ||
let parser, highlighterLoader = createHighlighterLoader(); | ||
return function(options) { | ||
let language = options.language || "", { highlighter, promise } = highlighterLoader( | ||
language, | ||
highlighterOptions | ||
); | ||
return highlighter ? (parser || (parser = createParser(highlighter)), parser(options)) : promise || []; | ||
let parser; | ||
return prepareHighlighter(highlighterOptions), function(options) { | ||
let language = options.language || "", { highlighter: highlighter2, promise } = prepareHighlighter({ | ||
langs: [language], | ||
themes: highlighterOptions.themes | ||
}); | ||
return highlighter2 ? (parser || (parser = createParser(highlighter2, { | ||
theme: highlighterOptions.themes[0] | ||
})), parser(options)) : promise; | ||
}; | ||
@@ -148,0 +168,0 @@ } |
// src/search/index.ts | ||
import { defineCommands, definePlugin } from "@prosekit/core"; | ||
// src/search/prosemirror-search/search.ts | ||
import { | ||
Plugin, | ||
PluginKey, | ||
TextSelection | ||
} from "@prosekit/pm/state"; | ||
import { DecorationSet, Decoration } from "@prosekit/pm/view"; | ||
// src/search/prosemirror-search/query.ts | ||
import { Slice, Fragment } from "@prosekit/pm/model"; | ||
import "@prosekit/pm/state"; | ||
var SearchQuery = class { | ||
/// Create a query object. | ||
constructor(config) { | ||
this.search = config.search, this.caseSensitive = !!config.caseSensitive, this.literal = !!config.literal, this.regexp = !!config.regexp, this.replace = config.replace || "", this.valid = !!this.search && !(this.regexp && !validRegExp(this.search)), this.wholeWord = !!config.wholeWord, this.impl = this.valid ? this.regexp ? new RegExpQuery(this) : new StringQuery(this) : nullQuery; | ||
} | ||
/// Compare this query to another query. | ||
eq(other) { | ||
return this.search == other.search && this.replace == other.replace && this.caseSensitive == other.caseSensitive && this.regexp == other.regexp && this.wholeWord == other.wholeWord; | ||
} | ||
/// Find the next occurrence of this query in the given range. | ||
findNext(state, from = 0, to = state.doc.content.size) { | ||
for (; ; ) { | ||
if (from >= to) return null; | ||
let result = this.impl.findNext(state, from, to); | ||
if (!result || this.checkResult(state, result)) return result; | ||
from = result.from + 1; | ||
} | ||
} | ||
/// Find the previous occurrence of this query in the given range. | ||
/// Note that, if `to` is given, it should be _less_ than `from`. | ||
findPrev(state, from = state.doc.content.size, to = 0) { | ||
for (; ; ) { | ||
if (from <= to) return null; | ||
let result = this.impl.findPrev(state, from, to); | ||
if (!result || this.checkResult(state, result)) return result; | ||
from = result.to - 1; | ||
} | ||
} | ||
/// @internal | ||
checkResult(state, result) { | ||
return this.wholeWord ? checkWordBoundary(state, result.from) && checkWordBoundary(state, result.to) : !0; | ||
} | ||
/// @internal | ||
unquote(string) { | ||
return this.literal ? string : string.replace( | ||
/\\([\\nrt])/g, | ||
(_, ch) => ch == "n" ? ` | ||
` : ch == "r" ? "\r" : ch == "t" ? " " : "\\" | ||
); | ||
} | ||
/// Get a replacement slice for a given search result. | ||
getReplacement(state, result) { | ||
let marks = state.doc.resolve(result.from).marksAcross(state.doc.resolve(result.to)), text = this.unquote(this.replace), nodes = [], i = 0, { match } = result; | ||
if (match) { | ||
text = text.replace( | ||
/\$([\d$&+])/g, | ||
(m, i2) => i2 == "$" ? "$" : i2 == "&" ? match[0] : i2 != "0" && +i2 < match.length ? match[+i2] : m | ||
); | ||
for (let pos = result.from; ; ) { | ||
let obj = text.indexOf("\uFFFC", i); | ||
if (obj < 0) break; | ||
let found = findLeafBetween(state, pos, result.to); | ||
if (!found) break; | ||
obj > i && nodes.push(state.schema.text(text.slice(i, obj), marks)), nodes.push(found.node), i = obj + 1, pos = found.pos + 1; | ||
} | ||
} | ||
return i < text.length && nodes.push(state.schema.text(text.slice(i), marks)), new Slice(Fragment.from(nodes), 0, 0); | ||
} | ||
}, nullQuery = new class { | ||
findNext() { | ||
return null; | ||
} | ||
findPrev() { | ||
return null; | ||
} | ||
}(), StringQuery = class { | ||
constructor(query) { | ||
this.query = query; | ||
let string = query.unquote(query.search); | ||
query.caseSensitive || (string = string.toLowerCase()), this.string = string; | ||
} | ||
findNext(state, from, to) { | ||
return scanTextblocks(state.doc, from, to, (node, start) => { | ||
let off = Math.max(from, start), content = textContent(node).slice( | ||
off - start, | ||
Math.min(node.content.size, to - start) | ||
), index = (this.query.caseSensitive ? content : content.toLowerCase()).indexOf(this.string); | ||
return index < 0 ? null : { | ||
from: off + index, | ||
to: off + index + this.string.length, | ||
match: null | ||
}; | ||
}); | ||
} | ||
findPrev(state, from, to) { | ||
return scanTextblocks(state.doc, from, to, (node, start) => { | ||
let off = Math.max(start, to), content = textContent(node).slice( | ||
off - start, | ||
Math.min(node.content.size, from - start) | ||
); | ||
this.query.caseSensitive || (content = content.toLowerCase()); | ||
let index = content.lastIndexOf(this.string); | ||
return index < 0 ? null : { | ||
from: off + index, | ||
to: off + index + this.string.length, | ||
match: null | ||
}; | ||
}); | ||
} | ||
}, baseFlags = "g" + (/x/.unicode == null ? "" : "u"), RegExpQuery = class { | ||
constructor(query) { | ||
this.query = query; | ||
this.regexp = new RegExp( | ||
query.search, | ||
baseFlags + (query.caseSensitive ? "" : "i") | ||
); | ||
} | ||
findNext(state, from, to) { | ||
return scanTextblocks(state.doc, from, to, (node, start) => { | ||
let content = textContent(node).slice( | ||
0, | ||
Math.min(node.content.size, to - start) | ||
); | ||
this.regexp.lastIndex = from - start; | ||
let match = this.regexp.exec(content); | ||
return match ? { | ||
from: start + match.index, | ||
to: start + match.index + match[0].length, | ||
match | ||
} : null; | ||
}); | ||
} | ||
findPrev(state, from, to) { | ||
return scanTextblocks(state.doc, from, to, (node, start) => { | ||
let content = textContent(node).slice( | ||
0, | ||
Math.min(node.content.size, from - start) | ||
), match; | ||
for (let off = 0; ; ) { | ||
this.regexp.lastIndex = off; | ||
let next = this.regexp.exec(content); | ||
if (!next) break; | ||
match = next, off = next.index + 1; | ||
} | ||
return match ? { | ||
from: start + match.index, | ||
to: start + match.index + match[0].length, | ||
match | ||
} : null; | ||
}); | ||
} | ||
}; | ||
function validRegExp(source) { | ||
try { | ||
return new RegExp(source, baseFlags), !0; | ||
} catch (e) { | ||
return !1; | ||
} | ||
} | ||
var TextContentCache = /* @__PURE__ */ new WeakMap(); | ||
function textContent(node) { | ||
let cached = TextContentCache.get(node); | ||
if (cached) return cached; | ||
let content = ""; | ||
for (let i = 0; i < node.childCount; i++) { | ||
let child = node.child(i); | ||
child.isText ? content += child.text : child.isLeaf ? content += "\uFFFC" : content += " " + textContent(child) + " "; | ||
} | ||
return TextContentCache.set(node, content), content; | ||
} | ||
function scanTextblocks(node, from, to, f, nodeStart = 0) { | ||
if (node.inlineContent) | ||
return f(node, nodeStart); | ||
if (!node.isLeaf) | ||
if (from > to) | ||
for (let i = node.childCount - 1, pos = nodeStart + node.content.size; i >= 0 && pos > to; i--) { | ||
let child = node.child(i); | ||
if (pos -= child.nodeSize, pos < from) { | ||
let result = scanTextblocks(child, from, to, f, pos + 1); | ||
if (result != null) return result; | ||
} | ||
} | ||
else | ||
for (let i = 0, pos = nodeStart; i < node.childCount && pos < to; i++) { | ||
let child = node.child(i), start = pos; | ||
if (pos += child.nodeSize, pos > from) { | ||
let result = scanTextblocks(child, from, to, f, start + 1); | ||
if (result != null) return result; | ||
} | ||
} | ||
return null; | ||
} | ||
function checkWordBoundary(state, pos) { | ||
let $pos = state.doc.resolve(pos), before = $pos.nodeBefore, after = $pos.nodeAfter; | ||
return !before || !after || !before.isText || !after.isText ? !0 : !/\p{L}$/u.test(before.text) || !/^\p{L}/u.test(after.text); | ||
} | ||
function findLeafBetween(state, from, to) { | ||
let found = null; | ||
return state.doc.nodesBetween(from, to, (node, pos) => { | ||
if (found) return !1; | ||
node.isLeaf && node.isInline && !node.isText && (found = { node, pos }); | ||
}), found; | ||
} | ||
// src/search/prosemirror-search/search.ts | ||
var SearchState = class { | ||
constructor(query, range, deco) { | ||
this.query = query; | ||
this.range = range; | ||
this.deco = deco; | ||
} | ||
}; | ||
function buildMatchDeco(state, query, range) { | ||
if (!query.valid) return DecorationSet.empty; | ||
let deco = [], sel = state.selection; | ||
for (let pos = range ? range.from : 0, end = range ? range.to : state.doc.content.size; ; ) { | ||
let next = query.findNext(state, pos, end); | ||
if (!next) break; | ||
let cls = next.from == sel.from && next.to == sel.to ? "ProseMirror-active-search-match" : "ProseMirror-search-match"; | ||
deco.push(Decoration.inline(next.from, next.to, { class: cls })), pos = next.to; | ||
} | ||
return DecorationSet.create(state.doc, deco); | ||
} | ||
var searchKey = new PluginKey("search"); | ||
function search(options = {}) { | ||
return new Plugin({ | ||
key: searchKey, | ||
state: { | ||
init(_config, state) { | ||
let query = options.initialQuery || new SearchQuery({ search: "" }), range = options.initialRange || null; | ||
return new SearchState( | ||
query, | ||
range, | ||
buildMatchDeco(state, query, range) | ||
); | ||
}, | ||
apply(tr, search2, _oldState, state) { | ||
let set = tr.getMeta(searchKey); | ||
if (set) | ||
return new SearchState( | ||
set.query, | ||
set.range, | ||
buildMatchDeco(state, set.query, set.range) | ||
); | ||
if (tr.docChanged || tr.selectionSet) { | ||
let range = search2.range; | ||
if (range) { | ||
let from = tr.mapping.map(range.from, 1), to = tr.mapping.map(range.to, -1); | ||
range = from < to ? { from, to } : null; | ||
} | ||
search2 = new SearchState( | ||
search2.query, | ||
range, | ||
buildMatchDeco(state, search2.query, range) | ||
); | ||
} | ||
return search2; | ||
} | ||
}, | ||
props: { | ||
decorations: (state) => searchKey.getState(state).deco | ||
} | ||
}); | ||
} | ||
function nextMatch(search2, state, wrap, curFrom, curTo) { | ||
let range = search2.range || { from: 0, to: state.doc.content.size }, next = search2.query.findNext(state, Math.max(curTo, range.from), range.to); | ||
return !next && wrap && (next = search2.query.findNext(state, range.from, Math.min(curFrom, range.to))), next; | ||
} | ||
function prevMatch(search2, state, wrap, curFrom, curTo) { | ||
let range = search2.range || { from: 0, to: state.doc.content.size }, prev = search2.query.findPrev( | ||
state, | ||
Math.min(curFrom, range.to), | ||
range.from | ||
); | ||
return !prev && wrap && (prev = search2.query.findPrev(state, range.to, Math.max(curTo, range.from))), prev; | ||
} | ||
function findCommand(wrap, dir) { | ||
return (state, dispatch) => { | ||
let search2 = searchKey.getState(state); | ||
if (!search2 || !search2.query.valid) return !1; | ||
let { from, to } = state.selection, next = dir > 0 ? nextMatch(search2, state, wrap, from, to) : prevMatch(search2, state, wrap, from, to); | ||
if (!next) return !1; | ||
let selection = TextSelection.create(state.doc, next.from, next.to); | ||
return dispatch && dispatch(state.tr.setSelection(selection).scrollIntoView()), !0; | ||
}; | ||
} | ||
var findNext = findCommand(!0, 1), findNextNoWrap = findCommand(!1, 1), findPrev = findCommand(!0, -1), findPrevNoWrap = findCommand(!1, -1); | ||
function replaceCommand(wrap, moveForward) { | ||
return (state, dispatch) => { | ||
let search2 = searchKey.getState(state); | ||
if (!search2 || !search2.query.valid) return !1; | ||
let { from } = state.selection, next = nextMatch(search2, state, wrap, from, from); | ||
if (!next) return !1; | ||
if (!dispatch) return !0; | ||
if (state.selection.from == next.from && state.selection.to == next.to) { | ||
let tr = state.tr.replace( | ||
next.from, | ||
next.to, | ||
search2.query.getReplacement(state, next) | ||
), after = moveForward && nextMatch(search2, state, wrap, next.from, next.to); | ||
after ? tr.setSelection( | ||
TextSelection.create( | ||
tr.doc, | ||
tr.mapping.map(after.from, 1), | ||
tr.mapping.map(after.to, -1) | ||
) | ||
) : tr.setSelection( | ||
TextSelection.create(tr.doc, next.from, tr.mapping.map(next.to, 1)) | ||
), dispatch(tr.scrollIntoView()); | ||
} else if (moveForward) | ||
dispatch( | ||
state.tr.setSelection(TextSelection.create(state.doc, next.from, next.to)).scrollIntoView() | ||
); | ||
else | ||
return !1; | ||
return !0; | ||
}; | ||
} | ||
var replaceNext = replaceCommand(!0, !0), replaceNextNoWrap = replaceCommand(!1, !0), replaceCurrent = replaceCommand(!1, !1), replaceAll = (state, dispatch) => { | ||
let search2 = searchKey.getState(state); | ||
if (!search2) return !1; | ||
let matches = [], range = search2.range || { from: 0, to: state.doc.content.size }; | ||
for (let pos = range.from; ; ) { | ||
let next = search2.query.findNext(state, pos, range.to); | ||
if (!next) break; | ||
matches.push(next), pos = next.to; | ||
} | ||
if (dispatch) { | ||
let tr = state.tr; | ||
for (let i = matches.length - 1; i >= 0; i--) { | ||
let match = matches[i]; | ||
tr.replace( | ||
match.from, | ||
match.to, | ||
search2.query.getReplacement(state, match) | ||
); | ||
} | ||
dispatch(tr); | ||
} | ||
return !0; | ||
}; | ||
// src/search/index.ts | ||
SearchQuery, | ||
findNext, | ||
findNextNoWrap, | ||
findPrev, | ||
findPrevNoWrap, | ||
replaceAll, | ||
replaceCurrent, | ||
replaceNext, | ||
replaceNextNoWrap, | ||
search | ||
} from "prosemirror-search"; | ||
function defineSearchQuery(options) { | ||
@@ -349,0 +16,0 @@ let query = new SearchQuery(options); |
{ | ||
"name": "@prosekit/extensions", | ||
"type": "module", | ||
"version": "0.0.0-next-20240620223217", | ||
"version": "0.0.0-next-20240621205958", | ||
"private": false, | ||
@@ -175,7 +175,8 @@ "author": { | ||
"prosemirror-flat-list": "^0.5.0", | ||
"prosemirror-highlight": "^0.6.0", | ||
"prosemirror-highlight": "^0.8.0", | ||
"prosemirror-search": "^0.1.0", | ||
"prosemirror-tables": "^1.3.7", | ||
"shiki": "^1.6.5", | ||
"@prosekit/core": "^0.0.0-next-20240620223217", | ||
"@prosekit/pm": "^0.0.0-next-20240620223217" | ||
"shiki": "^1.9.0", | ||
"@prosekit/core": "^0.0.0-next-20240621205958", | ||
"@prosekit/pm": "^0.0.0-next-20240621205958" | ||
}, | ||
@@ -182,0 +183,0 @@ "devDependencies": { |
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
105581
8
3053
+ Addedprosemirror-search@^0.1.0
+ Addedprosemirror-highlight@0.8.0(transitive)
+ Addedprosemirror-search@0.1.0(transitive)
- Removedprosemirror-highlight@0.6.0(transitive)
Updatedprosemirror-highlight@^0.8.0
Updatedshiki@^1.9.0