2026-06-06 17:18:15 +08:00
|
|
|
import {
|
|
|
|
|
API_KEY,
|
|
|
|
|
DOCS_BLOB_BASE_URL,
|
|
|
|
|
DOCS_FOLDERS_URL,
|
|
|
|
|
DOCS_NODES_BASE_URL,
|
|
|
|
|
DOCS_NODES_URL,
|
|
|
|
|
DOCS_TEXT_FILES_URL,
|
|
|
|
|
DOCS_UPLOAD_URL,
|
|
|
|
|
} from './config.js'
|
|
|
|
|
|
|
|
|
|
function buildHeaders(extra = {}) {
|
2026-06-08 11:51:39 +08:00
|
|
|
return API_KEY
|
|
|
|
|
? {
|
|
|
|
|
'X-API-Key': API_KEY,
|
|
|
|
|
...extra,
|
|
|
|
|
}
|
|
|
|
|
: { ...extra }
|
2026-06-06 17:18:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function parseJsonResponse(res) {
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
let message = `HTTP ${res.status}`
|
|
|
|
|
try {
|
|
|
|
|
const data = await res.json()
|
|
|
|
|
message = data.detail || data.error || message
|
|
|
|
|
} catch {
|
|
|
|
|
const text = await res.text()
|
|
|
|
|
if (text) message = text
|
|
|
|
|
}
|
|
|
|
|
throw new Error(message)
|
|
|
|
|
}
|
|
|
|
|
return res.json()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function fetchDocNodes() {
|
|
|
|
|
const res = await fetch(DOCS_NODES_URL, {
|
|
|
|
|
headers: buildHeaders(),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
})
|
|
|
|
|
const data = await parseJsonResponse(res)
|
|
|
|
|
return Array.isArray(data.nodes) ? data.nodes : []
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createDocFolder(name, parentId = null) {
|
|
|
|
|
const res = await fetch(DOCS_FOLDERS_URL, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: buildHeaders({ 'Content-Type': 'application/json' }),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
body: JSON.stringify({ name, parentId }),
|
|
|
|
|
})
|
|
|
|
|
const data = await parseJsonResponse(res)
|
|
|
|
|
return data.node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function createDocTextFile(name, parentId = null, content = '') {
|
|
|
|
|
const res = await fetch(DOCS_TEXT_FILES_URL, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: buildHeaders({ 'Content-Type': 'application/json' }),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
body: JSON.stringify({ name, parentId, content }),
|
|
|
|
|
})
|
|
|
|
|
const data = await parseJsonResponse(res)
|
|
|
|
|
return data.node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function uploadDocFile(file, parentId = null) {
|
|
|
|
|
const formData = new FormData()
|
|
|
|
|
formData.append('file', file)
|
|
|
|
|
formData.append('parent_id', parentId || '')
|
|
|
|
|
const res = await fetch(DOCS_UPLOAD_URL, {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: buildHeaders(),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
body: formData,
|
|
|
|
|
})
|
|
|
|
|
const data = await parseJsonResponse(res)
|
|
|
|
|
return data.node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function updateDocNode(nodeId, payload) {
|
|
|
|
|
const res = await fetch(`${DOCS_NODES_BASE_URL}/${encodeURIComponent(nodeId)}`, {
|
|
|
|
|
method: 'PATCH',
|
|
|
|
|
headers: buildHeaders({ 'Content-Type': 'application/json' }),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
})
|
|
|
|
|
const data = await parseJsonResponse(res)
|
|
|
|
|
return data.node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function replaceDocBlob(nodeId, file) {
|
|
|
|
|
const formData = new FormData()
|
|
|
|
|
formData.append('file', file, file.name || 'file')
|
|
|
|
|
const res = await fetch(`${DOCS_BLOB_BASE_URL}/${encodeURIComponent(nodeId)}/blob`, {
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
headers: buildHeaders(),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
body: formData,
|
|
|
|
|
})
|
|
|
|
|
const data = await parseJsonResponse(res)
|
|
|
|
|
return data.node
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function deleteDocNode(nodeId) {
|
|
|
|
|
const res = await fetch(`${DOCS_NODES_BASE_URL}/${encodeURIComponent(nodeId)}`, {
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
headers: buildHeaders(),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
})
|
|
|
|
|
return parseJsonResponse(res)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function fetchDocBlob(nodeId) {
|
|
|
|
|
const res = await fetch(`${DOCS_BLOB_BASE_URL}/${encodeURIComponent(nodeId)}/blob`, {
|
|
|
|
|
headers: buildHeaders(),
|
2026-06-08 11:51:39 +08:00
|
|
|
credentials: 'include',
|
2026-06-06 17:18:15 +08:00
|
|
|
})
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
let message = `HTTP ${res.status}`
|
|
|
|
|
try {
|
|
|
|
|
const data = await res.json()
|
|
|
|
|
message = data.detail || data.error || message
|
|
|
|
|
} catch {
|
|
|
|
|
const text = await res.text()
|
|
|
|
|
if (text) message = text
|
|
|
|
|
}
|
|
|
|
|
throw new Error(message)
|
|
|
|
|
}
|
|
|
|
|
return res.blob()
|
|
|
|
|
}
|