Files
RawMark/internal/api/openapi.json
T

2373 lines
58 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"openapi": "3.1.0",
"info": {
"title": "RawMark API",
"version": "1",
"description": "RawMark 的 REST API。自动化调用请在「API 令牌」中创建令牌,以 `Authorization: Bearer <token>` 访问;只读令牌可使用 GET 和 POST /export(只读导出)。令牌的管理接口只接受登录会话。所有错误响应均为 `{\"error\": \"说明\"}`。"
},
"servers": [
{
"url": "/api/v1"
}
],
"security": [
{
"bearer": []
},
{
"cookie": []
}
],
"paths": {
"/health": {
"get": {
"summary": "健康检查",
"tags": [
"系统"
],
"security": [
{}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
}
}
}
},
"/openapi.json": {
"get": {
"summary": "本文档",
"tags": [
"系统"
],
"security": [
{}
],
"responses": {
"200": {
"description": "OpenAPI 文档",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
}
}
}
},
"/auth/state": {
"get": {
"summary": "是否已初始化、当前是否已登录",
"tags": [
"登录"
],
"security": [
{}
],
"responses": {
"200": {
"description": "状态",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"setUp": {
"type": "boolean"
},
"authenticated": {
"type": "boolean"
}
}
}
}
}
}
}
}
},
"/auth/setup": {
"post": {
"summary": "首次设置登录密码",
"tags": [
"登录"
],
"security": [
{}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"password": {
"type": "string"
}
},
"required": [
"password"
]
}
}
}
},
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"400": {
"description": "密码过短",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"409": {
"description": "已初始化",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"description": "仅未初始化实例可设置密码;首次成功后自动登录,已初始化时返回 409。"
}
},
"/auth/login": {
"post": {
"summary": "登录,成功后设置会话 Cookie",
"tags": [
"登录"
],
"security": [
{}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"password": {
"type": "string"
}
},
"required": [
"password"
]
}
}
}
},
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"401": {
"description": "密码错误",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "失败次数过多",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/auth/logout": {
"post": {
"summary": "退出登录",
"tags": [
"登录"
],
"security": [
{}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
}
}
}
},
"/auth/password": {
"post": {
"summary": "修改登录密码;当前会话保留,其他设备需重新登录",
"tags": [
"登录"
],
"security": [
{
"cookie": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"current": {
"type": "string"
},
"next": {
"type": "string"
}
},
"required": [
"current",
"next"
]
}
}
}
},
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"400": {
"description": "新密码过短",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "当前密码错误",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"429": {
"description": "失败次数过多",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/settings": {
"get": {
"summary": "应用设置(全部设备共用的一份 JSON 对象)",
"tags": [
"设置"
],
"responses": {
"200": {
"description": "设置",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
},
"patch": {
"summary": "合并修改设置",
"tags": [
"设置"
],
"security": [
{
"cookie": []
}
],
"description": "按顶层键合并:请求中的键覆盖原值,值为 null 的键被删除。成功后经 WebSocket 推送 settings 事件。",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"responses": {
"200": {
"description": "合并后的设置",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"400": {
"description": "不是 JSON 对象",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"413": {
"description": "超过 1 MB",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/tree": {
"get": {
"summary": "全部笔记、图片与文件夹(含 .assets,不含隐藏条目或符号链接)",
"tags": [
"笔记"
],
"responses": {
"200": {
"description": "目录树",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"entries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Entry"
}
}
}
}
}
}
}
}
}
},
"/files/{path}": {
"parameters": [
{
"name": "path",
"in": "path",
"required": true,
"description": "仓库内的相对路径,如 `目录/笔记.md`(各段需 URL 编码)",
"schema": {
"type": "string"
}
}
],
"get": {
"summary": "读取笔记",
"tags": [
"笔记"
],
"responses": {
"200": {
"description": "Markdown 原文",
"headers": {
"ETag": {
"description": "内容版本(rev),带双引号",
"schema": {
"type": "string"
}
}
},
"content": {
"text/markdown": {
"schema": {
"type": "string"
}
}
}
},
"404": {
"description": "不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"put": {
"summary": "写入笔记(不存在的上级目录会自动创建)",
"tags": [
"笔记"
],
"description": "请求体整体作为笔记内容。`If-Match: \"rev\"` 要求当前版本一致,否则返回 412 与最新 rev;`If-None-Match: *` 要求笔记尚不存在;都不带则直接覆盖。",
"parameters": [
{
"name": "If-Match",
"in": "header",
"schema": {
"type": "string"
}
},
{
"name": "If-None-Match",
"in": "header",
"schema": {
"type": "string",
"enum": [
"*"
]
}
}
],
"requestBody": {
"required": true,
"content": {
"text/markdown": {
"schema": {
"type": "string"
}
}
}
},
"responses": {
"200": {
"description": "已写入",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"rev": {
"type": "string"
}
}
}
}
},
"headers": {
"ETag": {
"description": "内容版本(rev),带双引号",
"schema": {
"type": "string"
}
}
}
},
"400": {
"description": "路径无效",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"409": {
"description": "If-None-Match 时已存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"412": {
"description": "版本冲突",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"rev": {
"type": "string",
"description": "服务器上的当前版本;为空表示已不存在"
}
}
}
}
}
},
"413": {
"description": "超过 20 MB",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"delete": {
"summary": "把笔记、图片或文件夹移入回收站(笔记连同 .assets)",
"tags": [
"笔记"
],
"responses": {
"200": {
"description": "回收站条目",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrashItem"
}
}
}
},
"404": {
"description": "不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/move": {
"post": {
"summary": "移动或重命名笔记、图片或文件夹",
"tags": [
"笔记"
],
"description": "笔记的 .assets 目录随之移动,改名时改写本篇图片目录链接;图片移动或改名保持扩展名,并更新仓库笔记中的本地引用。维护笔记中的本地入链及相对出链。",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"from": {
"type": "string"
},
"to": {
"type": "string"
}
},
"required": [
"from",
"to"
]
}
}
}
},
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"404": {
"description": "源不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"409": {
"description": "目标已存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/folders": {
"post": {
"summary": "新建文件夹",
"tags": [
"笔记"
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"path": {
"type": "string"
}
},
"required": [
"path"
]
}
}
}
},
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"409": {
"description": "已存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/assets": {
"post": {
"summary": "上传图片到笔记的 .assets 目录",
"tags": [
"图片"
],
"parameters": [
{
"name": "note",
"in": "query",
"required": false,
"description": "所属笔记路径",
"schema": {
"type": "string"
}
},
{
"name": "folder",
"in": "query",
"description": "文件夹图片管理上传目标,空字符串表示根目录;与 note 互斥",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"format": "binary"
}
},
"required": [
"file"
]
}
}
}
},
"responses": {
"200": {
"description": "相对笔记所在目录的链接,可直接写入 Markdown",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"link": {
"type": "string"
}
}
}
}
}
},
"413": {
"description": "超过 50 MB",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"description": "note 与 folder 必须且只能指定一个;note 上传到笔记附件目录,folder 上传到目录的 assets 子目录。"
}
},
"/assets/import": {
"post": {
"summary": "下载公网图片到笔记的 .assets 目录",
"tags": [
"图片"
],
"description": "仅接受公网 HTTP/HTTPS 地址,实际连接及重定向均校验;不携带登录凭据或使用环境代理。重定向链最多 5 个请求、2 次下载尝试,单次超时 10 秒;仅超时、429 和 5xx 重试。支持 PNG/JPEG/GIF/WebP,按文件签名识别,最大 50 MB。",
"parameters": [
{
"name": "note",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri"
}
}
}
}
}
},
"responses": {
"200": {
"description": "相对笔记所在目录的图片链接",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"link": {
"type": "string"
}
}
}
}
}
},
"400": {
"description": "来源地址或笔记路径无效,或目标不是公网",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "所属笔记不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"413": {
"description": "图片超过 50 MB",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"422": {
"description": "不支持的图片类型",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"502": {
"description": "来源请求失败",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/raw/{path}": {
"parameters": [
{
"name": "path",
"in": "path",
"required": true,
"description": "仓库内的相对路径,如 `目录/笔记.md`(各段需 URL 编码)",
"schema": {
"type": "string"
}
}
],
"get": {
"summary": "读取仓库中的原始文件(图片等)",
"tags": [
"图片"
],
"responses": {
"200": {
"description": "文件内容",
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"404": {
"description": "不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/search": {
"get": {
"summary": "全文搜索",
"tags": [
"笔记"
],
"description": "空格分隔多个词,全部命中才返回;最多 50 条。",
"parameters": [
{
"name": "q",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "结果",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchResult"
}
}
}
}
}
}
}
}
}
},
"/trash": {
"get": {
"summary": "回收站列表",
"tags": [
"回收站"
],
"responses": {
"200": {
"description": "条目",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TrashItem"
}
}
}
}
}
}
}
}
}
},
"/trash/{id}/restore": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"post": {
"summary": "从回收站恢复",
"tags": [
"回收站"
],
"responses": {
"200": {
"description": "恢复的条目",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrashItem"
}
}
}
},
"404": {
"description": "不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"409": {
"description": "原位置已有同名文件",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/trash/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"delete": {
"summary": "彻底删除回收站条目",
"tags": [
"回收站"
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"404": {
"description": "不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/events": {
"get": {
"summary": "WebSocket:仓库变更推送",
"tags": [
"笔记"
],
"description": "升级为 WebSocket 后,服务器推送 JSON 数组,元素为 Event。客户端不发送消息。",
"responses": {
"101": {
"description": "切换为 WebSocket"
}
}
}
},
"/tokens": {
"get": {
"summary": "API 令牌列表",
"tags": [
"API 令牌"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "令牌",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"tokens": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIToken"
}
}
}
}
}
}
}
}
},
"post": {
"summary": "创建 API 令牌",
"tags": [
"API 令牌"
],
"security": [
{
"cookie": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"scope": {
"type": "string",
"enum": [
"read",
"write"
]
}
},
"required": [
"name",
"scope"
]
}
}
}
},
"responses": {
"200": {
"description": "token 明文只返回这一次",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"token": {
"type": "string"
},
"info": {
"$ref": "#/components/schemas/APIToken"
}
}
}
}
}
},
"400": {
"description": "名称或范围无效",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/tokens/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"delete": {
"summary": "吊销 API 令牌",
"tags": [
"API 令牌"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"404": {
"description": "不存在",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/themes": {
"get": {
"summary": "列出主题(含内置默认主题)",
"tags": [
"外观"
],
"responses": {
"200": {
"description": "主题列表",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"themes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Theme"
}
}
}
}
}
}
}
}
}
},
"/themes/{id}": {
"get": {
"summary": "读取主题 CSS",
"tags": [
"外观"
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "主题信息与 CSS",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"$ref": "#/components/schemas/Theme"
},
{
"type": "object",
"properties": {
"css": {
"type": "string"
}
}
}
]
}
}
}
},
"404": {
"description": "主题不存在或文件不完整"
}
}
}
},
"/plugins": {
"get": {
"summary": "列出已安装插件及启用状态",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"plugins": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Plugin"
}
}
}
}
}
}
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
}
}
},
"post": {
"summary": "安装 ZIP 插件;安装后默认停用,同 id 拒绝覆盖",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"201": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Plugin"
}
}
}
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
},
"409": {
"description": "同名插件已安装"
},
"413": {
"description": "ZIP 超过 10 MiB"
}
},
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"file"
],
"properties": {
"file": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
}
},
"/plugins/{id}": {
"patch": {
"summary": "修改全设备插件启用偏好",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Plugin"
}
}
}
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
},
"404": {
"description": "插件或指定版本的资源不存在"
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean"
}
}
}
}
}
}
},
"delete": {
"summary": "停用并卸载插件包,保留插件私有数据",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功"
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
},
"404": {
"description": "插件或指定版本的资源不存在"
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
]
}
},
"/plugins/{id}/data": {
"get": {
"summary": "读取插件私有 JSON,无数据时为 null",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {}
}
}
}
}
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
},
"404": {
"description": "插件或指定版本的资源不存在"
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
]
},
"put": {
"summary": "替换插件私有 JSON,最多 1 MiB",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {}
}
}
}
}
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
},
"404": {
"description": "插件或指定版本的资源不存在"
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"data"
],
"properties": {
"data": {}
}
}
}
}
}
}
},
"/plugins/{id}/assets/{revision}/{path}": {
"get": {
"summary": "鉴权读取指定安装版本的包内资源",
"tags": [
"插件"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功"
},
"401": {
"description": "需要登录会话"
},
"400": {
"description": "请求或插件包无效"
},
"403": {
"description": "不接受 API 令牌"
},
"404": {
"description": "插件或指定版本的资源不存在"
}
},
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "revision",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "path",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
]
}
},
"/import": {
"post": {
"summary": "导入 Markdown 文件或 ZIP 知识库",
"tags": [
"文件"
],
"description": "多选 .md 或单个 ZIP,总上传不超过 100 MB;ZIP 必须指定新建文件夹名称。目标目录必须存在,冲突不覆盖。解压及整理后上限 512 MiB、10,000 项,单篇笔记 20 MiB、附件 50 MiB。Markdown 与 ZIP 文件名须为 UTF-8。ZIP 层级保留,本地图片生成笔记独立附件,原附件保留;外部链接不下载,缺失本地目标以警告返回。",
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"files"
],
"properties": {
"dir": {
"type": "string",
"description": "目标目录,空字符串为根目录"
},
"folder": {
"type": "string",
"description": "ZIP 的新建文件夹名称;普通 Markdown 留空"
},
"files": {
"type": "array",
"items": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
},
"responses": {
"201": {
"description": "导入成功",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"paths",
"notes",
"assets",
"warnings"
],
"properties": {
"paths": {
"type": "array",
"items": {
"type": "string"
}
},
"notes": {
"type": "integer"
},
"assets": {
"type": "integer",
"description": "附件文件总数,包含原始附件和独立副本"
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"400": {
"description": "格式、路径或编码无效"
},
"401": {
"description": "未登录或令牌无效"
},
"403": {
"description": "只读令牌不能导入"
},
"404": {
"description": "目标目录不存在"
},
"409": {
"description": "目标已存在,不覆盖"
},
"413": {
"description": "超过上传、解压、文件数量或单文件大小限制"
}
}
}
},
"/assets/{path}": {
"put": {
"summary": "原位替换已有图片,保留路径和引用",
"tags": [
"图片"
],
"parameters": [
{
"name": "path",
"in": "path",
"required": true,
"description": "仓库中的图片路径",
"schema": {
"type": "string"
}
}
],
"description": "multipart file 字段的扩展名须与目标图片一致;不创建新文件,最大 50 MB。旧图片不会进入回收站。",
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "string",
"format": "binary"
}
},
"required": [
"file"
]
}
}
}
},
"responses": {
"200": {
"description": "替换成功"
},
"400": {
"description": "非法路径、空文件或扩展名不一致"
},
"404": {
"description": "目标图片不存在"
},
"413": {
"description": "超过 50 MB"
}
}
}
},
"/export": {
"post": {
"summary": "导出原始 Markdown 和本地附件",
"description": "接收非空路径列表;单篇无附件返回 .md,目录、多选或含附件返回 ZIP。ZIP 保留仓库相对路径;不下载外部资源,不跟随其他未选中笔记。缺失附件或非法路径返回错误。此 POST 接口不修改数据,只读令牌可调用。",
"tags": [
"文件"
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"paths"
],
"properties": {
"paths": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "原始 Markdown 或 ZIP 附件",
"content": {
"application/zip": {
"schema": {
"type": "string",
"format": "binary"
}
},
"text/markdown": {
"schema": {
"type": "string"
}
}
}
},
"400": {
"description": "路径无效"
},
"404": {
"description": "文件或附件不存在"
}
}
}
},
"/metadata": {
"get": {
"summary": "读取笔记关系、标签与资源引用索引",
"security": [
{
"cookie": []
},
{
"bearer": []
}
],
"responses": {
"200": {
"description": "索引就绪状态与元数据列表,不含笔记正文"
}
}
}
},
"/assets/cleanup": {
"post": {
"summary": "重新核对全库引用后,将孤立图片移入回收站",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"paths"
],
"properties": {
"paths": {
"type": "array",
"minItems": 1,
"maxItems": 1000,
"items": {
"type": "string"
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "已移入回收站的图片及跳过原因"
},
"400": {
"description": "请求无效,或笔记元数据异常,无法确认引用"
}
}
}
},
"/tree-icon": {
"put": {
"summary": "设置单个文件或目录的图标,null 恢复默认",
"tags": [
"文件"
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"path",
"icon"
],
"properties": {
"path": {
"type": "string"
},
"icon": {
"oneOf": [
{
"$ref": "#/components/schemas/TreeIcon"
},
{
"type": "null"
}
]
}
}
}
}
}
},
"responses": {
"200": {
"description": "成功",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Ok"
}
}
}
},
"400": {
"description": "非法路径或图标"
},
"404": {
"description": "文件不存在"
}
}
}
},
"/fonts": {
"get": {
"summary": "列出已导入字体",
"tags": [
"设置"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功"
},
"401": {
"description": "未登录"
},
"403": {
"description": "只接受登录会话"
}
}
},
"post": {
"summary": "导入字体,按内容去重(TTF/OTF/WOFF/WOFF2,上限30 MB)",
"tags": [
"设置"
],
"security": [
{
"cookie": []
}
],
"responses": {
"201": {
"description": "成功"
},
"401": {
"description": "未登录"
},
"403": {
"description": "只接受登录会话"
}
},
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"file"
],
"properties": {
"file": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
}
},
"/fonts/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"delete": {
"summary": "删除导入字体,将使用它的界面、正文和代码字体恢复Maple;Maple不可删除",
"tags": [
"设置"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功"
},
"401": {
"description": "未登录"
},
"403": {
"description": "只接受登录会话"
}
}
}
},
"/fonts/{id}/file": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"get": {
"summary": "读取导入字体文件",
"tags": [
"设置"
],
"security": [
{
"cookie": []
}
],
"responses": {
"200": {
"description": "成功"
},
"401": {
"description": "未登录"
},
"403": {
"description": "只接受登录会话"
}
}
}
}
},
"components": {
"securitySchemes": {
"bearer": {
"type": "http",
"scheme": "bearer",
"description": "API 令牌(rm_ 开头)"
},
"cookie": {
"type": "apiKey",
"in": "cookie",
"name": "rawmark_session",
"description": "浏览器登录会话"
}
},
"schemas": {
"Error": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
},
"required": [
"error"
]
},
"Ok": {
"type": "object",
"properties": {
"ok": {
"type": "boolean"
}
}
},
"Entry": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"dir": {
"type": "boolean"
},
"size": {
"type": "integer"
},
"mtime": {
"type": "integer",
"description": "修改时间(Unix 毫秒)"
},
"icon": {
"$ref": "#/components/schemas/TreeIcon"
}
}
},
"TrashItem": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"path": {
"type": "string",
"description": "原路径"
},
"dir": {
"type": "boolean"
},
"deletedAt": {
"type": "integer",
"description": "Unix 毫秒"
}
}
},
"SearchResult": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"line": {
"type": "integer",
"description": "第一处匹配所在行(从 1 开始);只有路径匹配时为 0"
},
"snippet": {
"type": "string"
}
}
},
"Event": {
"type": "object",
"description": "tree:目录结构变化;changed:内容变化(rev 为新版本);deleted:删除;moved:移动(from → path);settings:设置变化",
"properties": {
"type": {
"type": "string",
"enum": [
"tree",
"changed",
"deleted",
"moved",
"settings"
]
},
"path": {
"type": "string"
},
"from": {
"type": "string"
},
"rev": {
"type": "string"
}
}
},
"APIToken": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"scope": {
"type": "string",
"enum": [
"read",
"write"
]
},
"createdAt": {
"type": "integer"
},
"lastUsedAt": {
"type": "integer",
"description": "Unix 毫秒,0 为从未使用"
}
}
},
"Theme": {
"type": "object",
"required": [
"id",
"name",
"version"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
"Plugin": {
"type": "object",
"required": [
"id",
"name",
"version",
"apiVersion",
"revision",
"enabled"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"revision": {
"type": "string"
},
"apiVersion": {
"type": "integer",
"const": 1
},
"enabled": {
"type": "boolean"
}
}
},
"TreeIcon": {
"type": "object",
"required": [
"kind",
"value"
],
"properties": {
"kind": {
"type": "string",
"enum": [
"emoji",
"builtin"
]
},
"value": {
"type": "string",
"description": "Emoji 字符或内置线性图标名称,最多64字节"
}
}
}
}
}
}