# Nextra Dify Plugin

一个用于将 Nextra 文档项目与 Dify 知识库集成的 Next.js Webpack 插件。

## ✨ 特性

- 🔄 **自动同步**: 自动将 Nextra 文档同步到 Dify 知识库
- 📝 **MDX 支持**: 智能解析 MDX 文件内容和 frontmatter
- ✂️ **智能分割**: 支持自定义分割规则，将长文档分割为多个知识块
- 🎯 **灵活配置**: 支持包含/排除规则，精确控制同步范围
- 🏗️ **构建集成**: 无缝集成到 Next.js 构建流程
- 🔍 **智能命名**: 基于文件路径和菜单结构的智能文档命名
- 🎛️ **高级处理**: 支持 Dify 完整的文档处理规则配置
- 📦 **ESM 支持**: 支持 ES 模块和 CommonJS 双重导入方式

## 📦 安装

```bash
# Using npm
npm install nextra-dify-plugin

# Using yarn
yarn add nextra-dify-plugin

# Using pnpm
pnpm add nextra-dify-plugin
```

## 🚀 快速开始

### 1. 环境变量配置

在项目根目录创建 `.env.local` 文件：

```env
# Dify API 配置
DIFY_KNOWLEDGE_BASE_ID=your-knowledge-base-id
DIFY_API_TOKEN=your-api-token

# 可选：自定义 API 地址
DIFY_API_BASE_URL=https://api.dify.ai/v1
```

### 2. Next.js 配置

#### ESM 方式 (推荐)

```javascript
// next.config.mjs
import { NextraDifyPlugin } from 'nextra-dify-plugin'

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config, { dev, isServer }) => {
    // 只在生产构建的客户端侧启用
    if (!dev && !isServer) {
      config.plugins.push(
        new NextraDifyPlugin({
          knowledgeBaseId: process.env.DIFY_KNOWLEDGE_BASE_ID,
          apiToken: process.env.DIFY_API_TOKEN,
          projectName: 'my-docs',
          enableUpload: true,
          enableSplit: true,
          splitMarker: '<!-- split -->',
          include: ['pages/**/*.mdx', 'docs/**/*.mdx'],
          exclude: ['node_modules/**', '.next/**'],
          maxChunkSize: 4000,
          maxChunkSplitBeforeMarker: '^##\\s', // 正则：只匹配行首的二级标题
        })
      )
    }
    return config
  },
}

export default nextConfig
```

#### CommonJS 方式

```javascript
// next.config.js
const { NextraDifyPlugin } = require('nextra-dify-plugin')

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config, { dev, isServer }) => {
    if (!dev && !isServer) {
      config.plugins.push(
        new NextraDifyPlugin({
          knowledgeBaseId: process.env.DIFY_KNOWLEDGE_BASE_ID,
          apiToken: process.env.DIFY_API_TOKEN,
          projectName: 'my-docs',
          enableUpload: true,
          enableSplit: true,
          splitMarker: '<!-- split -->',
          include: ['pages/**/*.mdx', 'docs/**/*.mdx'],
          exclude: ['node_modules/**', '.next/**'],
        })
      )
    }
    return config
  },
}

module.exports = nextConfig
```

## ⚙️ 配置选项

### 基础配置

| 选项 | 类型 | 必需 | 默认值 | 说明 |
|------|------|------|--------|------|
| `knowledgeBaseId` | `string` | ✅ | - | Dify 知识库 ID |
| `apiToken` | `string` | ✅ | - | Dify API Token |
| `projectName` | `string` | ✅ | - | 项目名称，用作文档命名前缀 |
| `enableUpload` | `boolean` | ❌ | `false` | 是否启用上传功能 |
| `enableSplit` | `boolean` | ❌ | `false` | 是否启用内容分割 |
| `splitMarker` | `string` | ❌ | `'---'` | 分割标记 |
| `include` | `string[]` | ❌ | `['**/*.mdx']` | 包含规则 (glob 模式) |
| `exclude` | `string[]` | ❌ | `['node_modules/**', '.next/**']` | 排除规则 (glob 模式) |
| `apiBaseUrl` | `string` | ❌ | `'https://api.dify.ai/v1'` | Dify API 基础 URL |
| `maxChunkSize` | `number` | ❌ | `5000` | 分割时每个 chunk 的最大字符数 |
| `maxChunkSplitBeforeMarker` | `string` | ❌ | - | 超出最大字符数时，尝试在此标志前截断，支持正则表达式 |

### 高级处理规则配置

插件支持 Dify 的完整文档处理规则配置：

```javascript
config.plugins.push(
  new NextraDifyPlugin({
    // ... 基础配置
    process_rule: {
      mode: 'custom', // 'automatic' | 'custom'
      pre_processing_rules: [
        { id: 'remove_extra_spaces', enabled: true },
        { id: 'remove_urls_emails', enabled: false }
      ],
      segmentation: {
        separator: '\n\n\n\n',
        max_tokens: 2000,
        parent_mode: 'full-doc' // 'full-doc' | 'paragraph'
      },
      subchunk_segmentation: {
        separator: '\n\n',
        max_tokens: 400,
        chunk_overlap: 50
      },
      doc_type: 'business_document', // 文档类型
      doc_metadata: {
        title: 'API Documentation',
        language: 'Chinese',
        author: 'Development Team',
        description: 'Complete API reference'
      }
    }
  })
)
```

#### 文档类型 (`doc_type`)

支持的文档类型：
- `'book'` - 图书
- `'web_page'` - 网页
- `'paper'` - 学术论文/文章
- `'social_media_post'` - 社交媒体帖子
- `'wikipedia_entry'` - 维基百科条目
- `'personal_document'` - 个人文档
- `'business_document'` - 商业文档
- `'im_chat_log'` - 即时通讯记录
- `'synced_from_notion'` - Notion 同步文档
- `'synced_from_github'` - GitHub 同步文档
- `'others'` - 其他文档类型

## 📝 使用方法

### 基础使用

1. 配置环境变量和 Next.js 配置
2. 运行生产构建：`npm run build`
3. 插件会自动处理所有匹配的 MDX 文件并上传到 Dify 知识库

### 内容分割

插件支持两种内容分割方式：

#### 1. 使用分割标记

在 MDX 文件中使用分割标记来控制内容分割：

```mdx
---
title: API 使用指南
description: 详细的 API 使用说明
---

# API 使用指南

这是 API 的基础介绍内容。

<!-- split -->

## 认证

API 使用 Bearer Token 进行认证。

<!-- split -->

## 基础用法

这里是具体的使用示例...
```

#### 2. 智能字符数分割

当内容长度超过 `maxChunkSize` 时，插件会自动分割内容。如果配置了 `maxChunkSplitBeforeMarker`，插件会尝试在指定标志前进行截断，避免破坏上下文连贯性。

该选项支持正则表达式，提供更精确的匹配控制：

```javascript
plugin.push(new NextraDifyPlugin({
  // ... 其他配置
  maxChunkSize: 4000,
  // 常用正则表达式示例：
  maxChunkSplitBeforeMarker: '^##\\s', // 只匹配行首的二级标题
  // maxChunkSplitBeforeMarker: '^###\\s',   // 只匹配行首的三级标题
  // maxChunkSplitBeforeMarker: '^##[^#]',   // 匹配二级标题，但不匹配三级标题
  // maxChunkSplitBeforeMarker: '^#{1,3}\\s', // 匹配一到三级标题
}))
```

这样可以确保内容不会在段落中间被截断，而是在语义边界（如标题）处分割。正则表达式的使用让您可以精确控制分割点，避免 `##` 误匹配 `###` 等问题。

### 文档命名规则

文档名称按以下规则生成：

- 基础格式：`{projectName}_{菜单路径}`
- 分割文档：`{projectName}_{菜单路径}_{序号}`

示例：
- 文件：`pages/api/authentication.mdx`
- 生成名称：`my-docs_pages_api_authentication`
- 分割后：`my-docs_pages_api_authentication_1`, `my-docs_pages_api_authentication_2`

## 🔧 API 参考

### NextraDifyPlugin

主插件类，实现 Webpack 插件接口。

```typescript
import { type DifyPluginOptions, NextraDifyPlugin } from 'nextra-dify-plugin'

const plugin = new NextraDifyPlugin(options)
```

### DifyClient

Dify API 客户端，用于与 Dify 知识库交互。

```typescript
import { DifyClient } from 'nextra-dify-plugin'

const client = new DifyClient(apiToken, knowledgeBaseId, baseURL, processRule)
```

### MDXParser

MDX 文件解析器，用于解析和处理 MDX 内容。

```typescript
import { MDXParser } from 'nextra-dify-plugin'

const parser = new MDXParser(options)
```

### 类型定义

```typescript
import type {
  DifyApiResponse,
  DifyDocument,
  DifyPluginOptions,
  DocumentChunk,
  DocumentMetadata,
  DocumentType,
  MDXFile,
  PreProcessingRule,
  ProcessRule,
  SegmentationRule,
  SubchunkSegmentationRule,
  UploadResponse
} from 'nextra-dify-plugin'
```

## 🛠️ 开发

```bash
# 安装依赖
pnpm install

# 开发模式
pnpm dev

# 构建
pnpm build

# 运行测试
pnpm test

# 代码检查
pnpm lint

# 测试文档项目
pnpm test-docs
pnpm test-docs:build
pnpm test-docs:start
```

## 📜 License

MIT License - 查看 [LICENSE](LICENSE) 文件了解详细信息。
