mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-12-24 01:17:50 +08:00
182 lines
6.0 KiB
Markdown
182 lines
6.0 KiB
Markdown
# Backend Document Manipulation
|
|
|
|
Backend Document Manipulation allows developers to programmatically modify documents stored on the Collaboration server (On premises and Cloud).
|
|
|
|
This feature provides flexibility in document management, enabling updates through JSON, which is a simpler alternative to using Yjs methods directly.
|
|
|
|
The feature is fully compliant with Version history, and allows to track changes from users, as well as the Backend Document Manipulation feature.
|
|
|
|
:::warning Subscription required
|
|
This feature requires a valid Business or Enterprise subscription and a running [Tiptap Cloud instance](https://collab.tiptap.dev/).
|
|
:::
|
|
|
|
### Use Cases
|
|
|
|
Backend Document Manipulation enables a variety of use cases, such as:
|
|
|
|
- Live translation of document content.
|
|
- Server-side components, like executing an SQL query and displaying results.
|
|
- Automatic typo and grammar corrections.
|
|
- Version history integration and conflict-free merging of concurrent edits.
|
|
|
|
This powerful feature set allows for extensive customization and automation of document handling on the Tiptap platform, catering to a wide range of collaborative editing scenarios.
|
|
|
|
## Update Document
|
|
|
|
To update an existing document on the Collaboration server, you can use the `PATCH` method with the following API endpoint:
|
|
|
|
```bash
|
|
PATCH /api/documents/:identifier?format=:format
|
|
```
|
|
|
|
This endpoint accepts a Yjs update message and applies it to the specified document. The `format` query parameter specifies the format of the update and can be one of the following:
|
|
|
|
- `binary`: Directly using Yjs's `Y.encodeStateAsUpdate` method.
|
|
- `base64`: The binary state encoded as a Base64 string.
|
|
- `json`: Updates the document using JSON format (with some caveats, see below).
|
|
|
|
Upon successful update, the server will return HTTP status `204`. If the document does not exist, it will return `404`, and if the payload is invalid or the update cannot be applied, it will return `422`.
|
|
|
|
Example `curl` command to update a document:
|
|
|
|
```bash
|
|
curl --location --request PATCH 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \\
|
|
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA' \\
|
|
--data '@yjsUpdate.binary.txt'
|
|
```
|
|
|
|
### Update via JSON
|
|
|
|
When updating via JSON, the server computes the difference between the current document state and the provided JSON, then internally calculates the required Yjs update to reach the target state.
|
|
|
|
To ensure precise updates, especially for node-specific changes, it is recommended to use the `nodeAttributeName` and `nodeAttributeValue` parameters. These can be generated by Tiptap's [UniqueID Extension](https://tiptap.dev/docs/editor/api/extensions/unique-id) or a custom implementation.
|
|
|
|
- `nodeAttributeName`: Configured as `attributeName` in the UniqueID extension.
|
|
- `nodeAttributeValue`: The unique value generated for the node to be updated.
|
|
|
|
From version 3.3.0 onwards, you can use `?mode=append` to append nodes to the document's JSON representation without altering existing content.
|
|
|
|
Omitting these parameters may result in overwriting any updates made between fetching the document and issuing the update call.
|
|
|
|
Here is an example of how to update a document using JSON:
|
|
|
|
```typescript
|
|
// Define the document name, secret, and application ID
|
|
const docName = ''
|
|
const secret = ''
|
|
const appId = '';
|
|
|
|
// Construct the base URL
|
|
const url = `https://${appId}.collab.tiptap.dev`
|
|
|
|
// Fetch the current document's JSON representation
|
|
const docJson = await axios.get(`${url}/api/documents/${docName}?format=json`, {
|
|
headers: {
|
|
Authorization: secret
|
|
},
|
|
})
|
|
|
|
// Extract the document's JSON content
|
|
const tiptapJson = docJson.data
|
|
const nodes = tiptapJson.content
|
|
|
|
// Find and log specific nodes using their unique identifiers
|
|
const query = nodes.find(n => n.attrs?.identifier === 'fe5c0789-85d9-4877-a2c3-bccf5d874866').content[0].text
|
|
const resultTable = nodes.find(n => n.attrs?.identifier === '246368b6-0746-4ca1-a16f-8d964aff4041')
|
|
|
|
console.log(`Query: ${query}`)
|
|
console.log(JSON.stringify(resultTable.content))
|
|
|
|
// Append new content to the result table node
|
|
resultTable.content.push({
|
|
// New table row content here
|
|
{
|
|
"type": "tableRow",
|
|
"content": [
|
|
{
|
|
"type": "tableCell",
|
|
"attrs": {
|
|
"colspan": 1,
|
|
"rowspan": 1
|
|
},
|
|
"content": [
|
|
{
|
|
"type": "paragraph",
|
|
"attrs": {
|
|
"textAlign": "left"
|
|
},
|
|
"content": [
|
|
{
|
|
"type": "text",
|
|
"text": "Jan"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "tableCell",
|
|
"attrs": {
|
|
"colspan": 1,
|
|
"rowspan": 1
|
|
},
|
|
"content": [
|
|
{
|
|
"type": "paragraph",
|
|
"attrs": {
|
|
"textAlign": "left"
|
|
},
|
|
"content": [
|
|
{
|
|
"type": "text",
|
|
"text": "Thurau"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "tableCell",
|
|
"attrs": {
|
|
"colspan": 1,
|
|
"rowspan": 1
|
|
},
|
|
"content": [
|
|
{
|
|
"type": "paragraph",
|
|
"attrs": {
|
|
"textAlign": "left"
|
|
},
|
|
"content": [
|
|
{
|
|
"type": "text",
|
|
"text": "jan@janthurau.de"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
})
|
|
|
|
// Send the updated JSON back to the server to apply the changes
|
|
await axios.patch(`${url}/api/documents/${docName}?format=json`, tiptapJson, {
|
|
headers: {
|
|
Authorization: secret
|
|
}
|
|
})
|
|
```
|
|
|
|
## Create Document
|
|
|
|
To seed a new document on the Tiptap Collab server, use the `POST` method with the following endpoint:
|
|
|
|
```bash
|
|
POST /api/documents/:identifier?format=:format
|
|
```
|
|
|
|
The server will return HTTP status `204` for successful creation, `409` if the document already exists (you must delete it first to overwrite), and `422` if the action failed.
|
|
|
|
The `format` parameter accepts the same values as the update endpoint (`binary`, `base64`, or `json`).
|