Merge branch 'main' into tiptap3-migration

This commit is contained in:
Philipinho
2025-12-13 00:57:13 +00:00
137 changed files with 6089 additions and 1602 deletions
@@ -0,0 +1,2 @@
export { UniqueID } from "./unique-id";
export * from "./unique-id.util";
@@ -0,0 +1,11 @@
import { generateNodeId } from "../utils";
import { UniqueID as TiptapUniqueID } from "@tiptap/extension-unique-id";
export const UniqueID = TiptapUniqueID.extend({
addOptions() {
return {
...this.parent?.(),
generateID: () => generateNodeId(),
};
},
});
@@ -0,0 +1,78 @@
import type { Extensions, JSONContent } from "@tiptap/core";
import { findChildren, getSchema } from "@tiptap/core";
import { Node } from "@tiptap/pm/model";
import { EditorState } from "@tiptap/pm/state";
import type { UniqueID } from "./unique-id";
/**
* Creates a new document with unique IDs added to the nodes. Does the same
* thing as the UniqueID extension, but without the need to create an `Editor`
* instance. This lets you add unique IDs to the document in the server.
*
* When you call it, include the `UniqueID` extension in the `extensions` array.
* The configuration from the `UniqueID` extension will be picked up
* automatically, including its configuration options like `types` and
* `attributeName`.
*
* @see `UniqueID` extension for more information.
*
* @throws {Error} If the `UniqueID` extension is not found in the extensions array.
*
* @example
* const doc = {
* type: 'doc',
* content: [
* { type: 'paragraph', content: [{ type: 'text', text: 'Hello, world!' }] }
* ]
* }
* const newDoc = addUniqueIds(doc, [StarterKit, UniqueID.configure({ types: ['paragraph', 'heading'] })])
* console.log(newDoc)
* // Result:
* // {
* // type: 'doc',
* // content: [
* // { type: 'paragraph', content: [{ type: 'text', text: 'Hello, world!' }], id: '123' }
* // ]
* // }
*
* @param doc - A Tiptap JSON document to add unique IDs to.
* @param extensions - The extensions to use. Must include the `UniqueID` extension.
* @returns The updated Tiptap JSON document, with the unique IDs added to the nodes.
*/
export function addUniqueIdsToDoc(
doc: JSONContent,
extensions: Extensions,
): JSONContent {
// Find the UniqueID extension in the extensions array. If it's not found, throw an error.
const uniqueIDExtension = extensions.find(
(ext) => ext.name === "uniqueID",
) as typeof UniqueID | undefined;
if (!uniqueIDExtension) {
throw new Error("UniqueID extension not found in the extensions array");
}
const { types, attributeName, generateID } = uniqueIDExtension.options;
// Convert the JSON content to a ProseMirror node
const schema = getSchema([
...extensions.filter((ext) => ext.name !== "uniqueID"),
uniqueIDExtension,
]);
const contentNode = Node.fromJSON(schema, doc);
// Find nodes that don't have a unique ID
const nodesWithoutId = findChildren(contentNode, (node) => {
return !node.attrs[attributeName] && types.includes(node.type.name);
});
// Edit the document to add unique IDs to the nodes that don't have a unique ID
let tr = EditorState.create({
doc: contentNode,
}).tr;
// eslint-disable-next-line no-restricted-syntax
for (const { node, pos } of nodesWithoutId) {
tr = tr.setNodeAttribute(pos, attributeName, generateID({ node, pos }));
}
// Return the updated document
return tr.doc.toJSON();
}