npm package: @nflow.red/node-red-contrib-nocobase
Description: Node-RED nodes for NocoBase REST API: auth, generic request, and common collection operations
Author: glwhappen
Latest version: 0.1.0

# node-red-contrib-nocobase

[![NPM version](https://badge.fury.io/js/node-red-contrib-nocobase.svg)](https://badge.fury.io/js/node-red-contrib-nocobase) [![node-red](https://img.shields.io/badge/node--red-v3.1-red)](https://nodered.org)

一套用于 [NocoBase](https://www.nocobase.com/) 的 Node-RED 自定义节点，让你在 Node-RED 中轻松操作 NocoBase 的数据集合与 API。

## ✨ 功能特性

- **配置简单**：通过统一的配置节点管理 NocoBase 服务地址与认证信息。
- **多种认证**：支持 `Bearer Token` 和 `X-API-KEY` 两种认证方式。
- **集合操作**：提供 `list`, `get`, `create`, `update`, `destroy` 等常用集合操作节点。
- **通用请求**：提供一个灵活的通用请求节点，可调用任意 NocoBase API。
- **动态覆盖**：所有节点的关键参数都支持通过 `msg` 对象动态传入，提高了流程的灵活性。
- **状态提示**：节点在运行时会实时更新状态（连接中、请求中、成功、失败），方便调试。

## 📥 安装

### 从 Node-RED 管理面板安装

1. 打开 Node-RED 编辑器。
2. 点击右上角菜单 > “管理面板”。
3. 切换到 “安装” 标签页。
4. 搜索 `node-red-contrib-nocobase` 并点击 “安装”。

### 从 npm 命令行安装

在你的 Node-RED 用户目录（通常是 `~/.node-red`）下执行：

```bash
npm install node-red-contrib-nocobase
```

然后重启 Node-RED。

## 🛠️ 节点说明

### **`nocobase-config` (配置节点)**

这是所有 NocoBase 节点的基础，用于配置连接信息。

- **基础地址 (Base URL)**: 你的 NocoBase 服务的 API 地址，例如 `https://your-app.nocobase.com/api`。
- **认证模式 (Auth Mode)**: 选择 `Bearer Token` 或 `API Key`。
- **Token / API Key**: 你的凭证。这些信息会被安全地存储。这些值可以被 `msg` 中的属性覆盖。
- **超时 (Timeout)**: 请求超时时间，单位毫秒，默认 15000。

### **`nocobase-auth` (登录)**

调用 `/auth:signIn` 接口，通过邮箱和密码获取 `token`。

- **邮箱 (Email)**: 登录邮箱。可通过 `msg.nocobase.email` 或 `msg.email` 覆盖。
- **密码 (Password)**: 登录密码。可通过 `msg.nocobase.password` 或 `msg.password` 覆盖。

**输出**:
- `msg.payload`: 完整的响应体，包含 `user` 和 `token`。
- `msg.nocobase.token`: 提取出的 `token`，可直接用于后续节点的认证。
- `msg.nocobase.user`: 登录的用户信息。

### **`nocobase-collection-list` (列表)**

执行 `GET /{collectionName}:list` 操作，用于查询集合数据列表。

- **集合名 (Collection Name)**: 要查询的集合名称，例如 `users`。可通过 `msg.collectionName` 覆盖。
- **过滤 (filter)**: JSON 格式的查询条件，例如 `{"title":{"$contains":"abc"}}`。可通过 `msg.filter` 覆盖。
- **字段 (fields)**: 需要返回的字段，逗号分隔，例如 `id,title,createdAt`。可通过 `msg.fields` 覆盖。
- **appends**: 关联数据的字段，逗号分隔。可通过 `msg.appends` 覆盖。
- **排序 (sort)**: 排序字段，例如 `-createdAt` 表示按创建时间降序。可通过 `msg.sort` 覆盖。
- **页码 (page)** / **每页 (pageSize)**: 分页参数。可通过 `msg.page` 和 `msg.pageSize` 覆盖。

**输出**:
- `msg.payload`: 查询到的数据列表及元信息 `meta`。

### **`nocobase-collection-get` (获取单条)**

执行 `GET /{collectionName}:get` 操作，获取单条记录。

- **集合名 (Collection Name)**: 同上。
- **filterByTk**: 按主键获取，直接填入主键值。
- **过滤 (filter)**: 使用复杂条件查询，返回找到的第一条记录。

**输出**:
- `msg.payload`: 查询到的单条数据对象。

### **`nocobase-collection-create` (创建)**

执行 `POST /{collectionName}:create` 操作，创建一条新记录。

- **集合名 (Collection Name)**: 同上。
- **请求体 (Body)**: 要创建的数据，JSON 格式。如果留空，则默认使用 `msg.payload`。

**输出**:
- `msg.payload`: 创建成功后的数据对象。

### **`nocobase-collection-update` (更新)**

执行 `POST /{collectionName}:update` 操作，更新符合条件的记录。

- **集合名 (Collection Name)**: 同上。
- **过滤 (filter)**: JSON 格式的查询条件，用于指定要更新哪些记录。
- **更新值 (values)**: 要更新的数据，JSON 格式。如果留空，则默认使用 `msg.payload` 作为 `values`。

**输出**:
- `msg.payload`: 更新后的数据对象。

### **`nocobase-collection-destroy` (删除)**

执行 `POST /{collectionName}:destroy` 操作，删除符合条件的记录。

- **集合名 (Collection Name)**: 同上。
- **过滤 (filter)**: JSON 格式的查询条件，用于指定要删除哪些记录。

**输出**:
- `msg.payload`: 操作结果。

### **`nocobase-request` (通用请求)**

一个万能节点，可以调用任意 NocoBase API。

- **方法 (Method)**: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`。
- **路径 (Path)**: API 路径，例如 `/collections:list` 或 `/{collectionName}:list`。
- **查询 (Query)**: URL 查询参数，JSON 格式，例如 `{"page":1,"pageSize":10}`。
- **请求体 (Body)**: `POST/PUT/PATCH` 请求的数据，JSON 格式。默认使用 `msg.payload`。

**输出**:
- `msg.payload`: API 响应体。
- `msg.nocobase.response`: 包含 `status` 和 `headers` 的响应信息。

## 🚀 示例流程

你可以通过导入 `flows/examples.json` 文件来快速体验。

1.  复制 `examples.json` 文件的内容。
2.  在 Node-RED 编辑器中，点击右上角菜单 > “导入”。
3.  粘贴 JSON 内容并点击 “导入”。

![示例流程截图占位](https://via.placeholder.com/800x300.png?text=Example+Flow+Screenshot)

**示例 1: 完整的集合操作 (CRUD)**

这个流程演示了如何从登录开始，然后依次对 `posts` 集合执行 `list`, `create`, `update`, `destroy` 操作。

**示例 2: 通用请求**

这个流程展示了如何使用 `nocobase-request` 节点直接调用 NocoBase 的系统 API，例如获取所有集合列表 (`/collections:list`)。

## ❓ 常见问题

### 如何在 `msg` 中传递参数？

所有节点都遵循 `msg` 优先的原则。你可以通过 `change` 节点或 `function` 节点在 `msg` 上设置相应的属性来动态控制节点的行为。

- **通用参数**: `msg.collectionName`, `msg.filter`, `msg.payload` 等。
- **认证参数**: `msg.nocobase.token`, `msg.nocobase.apiKey`, `msg.nocobase.baseUrl`。

例如，一个 `change` 节点可以这样配置：
- **设置** `msg.collectionName` **为** `products`
- **设置** `msg.filter` **为** `{"status":"published"}` (JSON 类型)

### 如何处理错误？

当 API 请求失败时（例如网络错误、认证失败、权限不足等），节点会：
1.  在节点下方显示红色的错误状态和简要信息。
2.  通过 `node.error()` 抛出详细错误，你可以在 `debug` 节点的 “Catch” 模式下捕获它。
3.  错误信息会包含 `_status` (HTTP 状态码) 和 `_data` (响应体) 属性，方便排查。

## 📜 License

MIT License

## 🧩 分类与默认值

- **节点分类 (Palette Category)**：为便于在调色板中集中查找，所有非配置节点统一归类到 `nocobase` 分类下。配置节点 `nocobase-config` 保持 `config` 分类不变。

- **JSON 字段默认值**：
  - 集合操作节点（`list`, `get`, `update`, `destroy`）的 `filter` 字段，以及通用请求节点的 `query` 字段，默认值已设置为 `{}`，减少了每次使用时手动输入空对象的麻烦。
  - `create` 和 `update` 节点的 `body` (更新值) 字段默认值保持为空字符串 (`''`)。这是为了继续优先使用 `msg.payload` 作为数据来源，避免无意中覆盖上游节点精心构造的数据流。

- **401 错误处理**：当出现 `401 Unauthorized` 错误时，通常表示认证失败。请检查：
  - **配置节点**：是否已正确设置 `Token` 或 `API Key`。
  - **消息覆盖**：是否通过 `msg.nocobase.token` 或 `msg.nocobase.apiKey` 提供了有效凭证。
  - 为了提升调试体验，当 API 未返回明确错误信息时，本插件会提供一个更友好的提示：`401 Unauthorized：请检查认证（token 或 API Key）`。

## 🔤 输入类型（typed）与运行时解析

本插件全面支持 `typedInput` 多源类型，并在运行时使用 `RED.util.evaluateNodeProperty(...)` 统一解析：

- 支持的类型：`msg` / `flow` / `global` / `env` / `json` / `str` / `num`。
- 解析规则示例：
  - `bodyType: 'msg'` 且 `body: 'payload'` → 等价于使用 `msg.payload`。
  - `filterType: 'json'` 且 `filter: '{}'` → 解析为一个空对象 `{}`。
  - `queryType: 'env'` 且 `query: 'MY_QUERY_ENV'` → 从环境变量读取并作为查询参数。
  - `pageType: 'num'` → 解析后自动转为数字；若为 `undefined` 则不传参。
- 典型用法：
  - 创建（create）：默认 `bodyType='msg'`，`body='payload'`，若解析为空则回落到 `msg.payload` 或 `{}`。
  - 更新（update）：`filterType='json'`，`filter='{}'`；`bodyType='msg'`，`body='payload'`，为空时回落到 `msg.payload`。
  - 通用请求（request）：`queryType='json'`，`query='{}'`；`bodyType='msg'`，`body='payload'`。

> 小贴士：如需从 `msg` 或上下文取值，请在编辑器中将对应字段的类型切换为 `msg` / `flow` / `global` 并填入属性路径或键名，例如 `payload`、`myVar` 等。

## 🔐 认证提供与覆盖策略

- 优先从消息中读取：`msg.nocobase.token` 或 `msg.nocobase.apiKey`（也支持 `msg.token` / `msg.apiKey`）。
- 其次回落到配置节点的 `credentials`：`token` 或 `apiKey`。
- 请求头自动设置：
  - `Authorization: Bearer <token>`（当存在 Token）
  - `X-API-KEY: <apiKey>`（当存在 API Key）