# eye-hub **Repository Path**: tanoo/eye-hub ## Basic Information - **Project Name**: eye-hub - **Description**: 函数中心 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-07 - **Last Updated**: 2026-09-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # eye-hub EYE 函数共享仓库。线上调试成熟的函数可以导出为一个独立 JSON 文件,经 PR 审核后供其它 EYE 项目按需安装。 所有已发布函数都可以导出,包括 `BUILTIN` 与 `CUSTOM_JS`。发布状态本身表示函数已经完成测试。 > EYE 全程通过 HTTPS 读取当前分支的 `catalog.json`,再读取用户选择的单个函数文件;不执行 > `git clone`,运行 EYE 的机器也不需要安装 Git。 ## catalog 自动构建 仓库内置 GitHub Actions。每次向任意分支推送提交时都会: 1. 校验 `functions/*.json` 的仓库包结构、文件名、版本、函数类型和发布状态。 2. 扫描整个 `functions/` 目录,以目录实际内容作为唯一数据源。 3. 自动创建或更新 `catalog.json`:新增文件会加入,修改文件会更新,删除文件会移除条目。 4. 为每个函数写入 SHA-256,按函数 key 排序,并由 GitHub Actions Bot 提交变化。 Pull Request 会执行相同校验,并要求 PR 中的 `catalog.json` 已同步。开发者也可在本地运行: ```bash node scripts/security-scan.mjs --current node scripts/security-scan.mjs --history node --test scripts/*.test.mjs node scripts/build-catalog.mjs node scripts/build-catalog.mjs --check ``` 目录构建只使用 Node.js 读取本地 JSON,不安装第三方依赖,也不会执行函数中的代码。 函数测试会在 VM 中运行包内脚本,以模拟 HTTP 响应验证行为,不使用真实凭证或访问云 API。 首次启用时,请在 GitHub 仓库的 `Settings → Actions → General → Workflow permissions` 中选择 `Read and write permissions`,否则工作流可以完成检查,但无法提交自动生成的 `catalog.json`。 ## 敏感信息保护 仓库禁止保存任何真实凭证和账户隐私数据,包括 SecretId、SecretKey、AccessKey、API Key、Token、 密码、Cookie、Webhook 签名密钥、私钥、个人邮箱、真实 UIN、账户余额、请求 ID、内部账号别名和线上测试完整响应。 函数包只能声明密钥引用编码,密钥值必须保存在 EYE 密钥中心。 克隆仓库后执行一次: ```bash node scripts/install-security-hooks.mjs ``` 该命令启用仓库内安全钩子:提交前检查 Git 隐私邮箱并扫描暂存内容;推送前扫描当前工作区、 全部可达 Git 历史及提交者邮箱。 扫描只输出文件位置、规则名和不可逆指纹,不会在终端或 CI 日志中再次显示疑似密钥。仓库 CI 也会运行相同扫描, 防止绕过本地钩子的提交被合并。测试数据必须使用带 `example`、`test`、`fake` 或 `dummy` 标识的占位值。 提交前请将本仓库的 Git 邮箱配置为代码托管平台提供的隐私邮箱: ```bash git config user.email "你的平台隐私邮箱" ``` 如果真实凭证曾进入 Git,无论后来是否删除,都应立即在供应商控制台撤销并重新生成;随后重写 Git 历史并强制更新远端。 不要只提交一个“删除密钥”的新版本,因为旧值仍可从历史提交读取。 ## 腾讯云账户余额查询 函数包:[`functions/tencent.balance.query.json`](functions/tencent.balance.query.json),版本 `1`, 名称为“腾讯云账户余额查询”。脚本、输入输出契约、完整说明和示例都在此单文件中。 1. 在 EYE 密钥中心保存腾讯云 `SecretId` 和 `SecretKey`。 2. 创建云账号资产,厂商 `vendor` 填 `tencent`,填写账号别名。 `accessKeyIdSecretRef` 选择 SecretId 的密钥编码,`accessKeySecretRef` 选择 SecretKey 的密钥编码; 使用临时凭证时,再为 `securityTokenSecretRef` 选择同组 Token 的密钥编码。 3. 为密钥所属用户配置 `finance:DescribeAccountBalance` 只读权限(资源为 `*`), 参见[腾讯云 CAM 权限指引](https://cloud.tencent.com/document/product/555/61542)。 4. 仓库变更发布后,在 EYE 的“函数仓库”中搜索“腾讯云账户余额查询”,安装为草稿。 在线测试时,`target` 选择上面的云账号;参数可保持默认。 5. 使用真实账号测试成功后发布函数,再绑定监控规则。例如 `balance < 100` 表示余额低于 100 元。 默认请求超时为 8000 毫秒;`region` 可留空,账户余额不按地域拆分; `tempCredit=true` 可额外查询临时信用额度。无需安装腾讯云 SDK。 函数调用[DescribeAccountBalance](https://cloud.tencent.com/document/api/555/20253), 将官方返回的“分”统一转换为人民币“元”。`balance`、`balanceText`、`availableCashAmount`、 `availableCashAmountText`、`creditAmount` 沿用阿里云余额查询的字段命名,另外提供欠费、冻结、 赠送余额和可用信用额度等字段。`balance` 优先取 `RealBalance`,缺失时兼容 `Balance`; 数值保留接口精度,文本显示两位小数。可选金额缺失返回 `null`,无效余额直接报错。 包内不含密钥值,`environment.secretRefs` 留空,因为 EYE 会从绑定资产的密钥引用动态加载凭证, 不同账号不需要共用固定编码。仅允许访问 `billing.tencentcloudapi.com`,适用于中国站人民币账户。 本包已通过本地模拟测试,尚未使用真实腾讯云账户联调。包内 `source.status=PUBLISHED` 是现有仓库格式要求, `lastTestSuccess=null` 表示没有 EYE 线上测试记录;使用时应先安装为草稿完成实际验证。 ## 分支约定 - `master`:正式发布版。EYE 可以安装为草稿,也可以直接发布。 - `dev`:测试版。EYE 强制只能安装为草稿,不能直接发布。 建议先合并到 `dev` 验证,再合并或提升到 `master`。 ## 仓库结构 ```text README.md catalog.json functions/ aliyun.balance.query.json example.http.check.json ``` - 一个函数对应 `functions/<函数 key>.json`,文件名与 `manifest.key` 一致。 - 函数主体、使用说明、环境引用全部保存在同一个 JSON 中,便于直接上传、审核和下载。 ## 推荐的函数文件结构 下面的分层是合理的:运行代码、说明和环境依赖各自独立,同时仍保持“一个函数一个文件”。 不要把说明拆成另一个文件,否则 PR、下载和版本升级时容易出现主体与说明不一致。 ```json { "format": "eye-function-hub", "version": 2, "manifest": { "key": "example.http.check", "packageVersion": 1, "name": "HTTP 状态检查", "summary": "请求指定地址并返回状态码和耗时", "fileName": "example.http.check.json", "exportedAt": "2026-08-07T16:00:00+08:00", "sourceRevision": 3, "sourceCode": "example_http_check" }, "function": { "code": "example_http_check", "type": "CUSTOM_JS", "builtinKey": null, "inputContractJson": "{\"slots\":[],\"params\":[{\"name\":\"url\",\"type\":\"string\",\"required\":true}]}", "outputContractJson": "[{\"name\":\"status\",\"type\":\"number\"},{\"name\":\"elapsedMs\",\"type\":\"number\"}]", "executionProfileJson": "{\"sideEffectFree\":true,\"allowedHosts\":[\"example.com\"]}", "scriptCode": "module.exports = async ({ params, helpers }) => { /* 函数代码 */ };" }, "documentation": { "overview": "用于检查业务 HTTP 地址是否正常响应。", "usage": "安装后先在线测试,再绑定到监控规则。", "inputs": "url:需要检查的 HTTPS 地址。", "outputs": "status:HTTP 状态码;elapsedMs:请求耗时。", "examples": [ { "title": "检查官网", "params": { "url": "https://example.com/health" } } ], "notes": ["不要在脚本或示例中写入密钥明文"] }, "environment": { "runtime": "CUSTOM_JS", "secretRefs": [ { "code": "EXAMPLE_API_KEY", "required": false, "description": "目标服务需要鉴权时配置" } ], "variables": [], "allowedHosts": ["example.com"] }, "compatibility": { "legacyCodes": ["example_http_check"] }, "source": { "status": "PUBLISHED", "revision": 3, "lastTestSuccess": true } } ``` 各部分职责: - `manifest`:仓库身份、名称和独立版本。升级时递增 `packageVersion`。 - `function`:真正入库并执行的函数主体、输入输出契约与执行配置。 - `documentation`:给使用者看的完整说明、示例和注意事项;安装后会随函数保存,可再次导出。 - `environment`:只声明密钥编码、环境变量和网络域名,严禁放密钥值。 - `compatibility.legacyCodes`:用于识别目标项目已有的同源函数,正式安装时可原位升级并保留 ID、规则引用和历史数据。 EYE 函数页面的“导出仓库 PR 包”会直接生成上述结构和正确文件名,一般不需要手写。 内置函数包的 `function.type` 为 `BUILTIN`,必须携带 `builtinKey`,`scriptCode` 可以为 `null`。 安装端只会绑定目标 EYE 版本已经存在的同名内置实现,仓库文件不会被当作系统代码执行。 ## catalog.json 每个分支各自维护一个 `catalog.json`。它只负责生成列表并指向对应单文件: ```json { "format": "eye-function-hub-catalog", "version": 1, "generatedAt": "2026-08-07T16:00:00+08:00", "functions": [ { "key": "example.http.check", "version": 1, "name": "HTTP 状态检查", "description": "请求指定地址并返回状态码和耗时", "path": "functions/example.http.check.json", "secretRefs": "EXAMPLE_API_KEY" } ] } ``` 规则: - `key` 必须唯一,使用 2–80 位小写字母、数字、点、下划线或横线。 - `version` 必须等于函数文件中的 `manifest.packageVersion`。 - 目录中的每一项都是函数;这里的“测试版”指 `dev` 分支里的函数,不是额外的 `.sh` 文件。 - `path` 只能位于 `functions/`,并且必须是 `functions/.json`。 - 可以额外填写文件的 `sha256`;填写后 EYE 会在安装前校验。 ## 上传一个函数 1. 在 EYE 函数中心发布函数(发布即表示已经测试通过)。 2. 在函数列表点击“导出”→“导出仓库 PR 包”。 3. 将下载的 `<函数 key>.json` 放入 `functions/`。 4. 运行 `node scripts/build-catalog.mjs`;GitHub Actions 也会在推送后自动创建或同步目录。 5. 提交 PR,并在说明中写明用途、环境引用、测试方式和是否有兼容性变化。 6. 先合并到 `dev` 做草稿安装验证;确认后再进入 `master`。 仓库包不能通过 EYE 的普通“导入函数”入口手动导入,必须在“函数仓库”中选择安装。 ## PR 检查清单 - [ ] 文件名等于 `.json` - [ ] `manifest.packageVersion` 已递增 - [ ] `catalog.json` 的 key、version、path 与函数文件一致 - [ ] 不包含 API Key、Token、密码、Cookie 等明文 - [ ] 不包含真实 UIN、余额、请求 ID、内部账号别名或线上测试响应 - [ ] 已运行 `node scripts/security-scan.mjs --current` 和 `--history` - [ ] 已使用隐私邮箱提交,未在 Git 元数据公开个人邮箱 - [ ] `documentation` 说明了输入、输出、示例和注意事项 - [ ] `environment.secretRefs` 只填写密钥编码和用途 - [ ] `executionProfileJson.allowedHosts` 只包含实际需要访问的域名 - [ ] 函数状态为已发布(发布即表示已经测试通过)