# @finueva/drive 中文文档

规范地址：https://npmcn.com/package/%40finueva/drive/

版本：0\.36\.0
npm 元数据更新时间：2026-11-14T11:01:16.750Z
中文译文更新时间：2026-11-14T19:23:57.812Z
软件包许可：ISC

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40finueva/drive
原文对照：https://npmcn.com/package/%40finueva/drive/?lang=original
项目主页：https://github.com/Ifkafin/drive#readme
源码仓库：https://github.com/Ifkafin/drive

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：881 kB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：1 个
- 首次发布：2026-08-18T08:10:56.883Z
- 最新版本发布：2026-11-14T11:01:16.585Z
- 近 30 天下载量：3486（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：39（近 12 个月 39 个）

## 中文简介

Finueva Drive 的公共浏览器、 Worker 和节点客户端

## 安装

```sh
npm install @finueva/drive
```

也可以使用：`pnpm add @finueva/drive`、`yarn add @finueva/drive`、`bun add @finueva/drive`

## README

# `@finueva/drive`

Finueva Drive的公用TypeScript客户端. 该包被发布到npm;API仍然为局部实验.

一揽子措施仅限无害环境管理。 节点.js 22是精确的最小值;CI包可以限定节点.js 22和24. 现代浏览器和Cloudflare Workers使用Web Refer,Sreams,URL,并中止Signal.

## 出口

本组织候选人补充说: `ensureOrganizationWorkspaceAccess()` 到用户客户端。 第一项通过现有生态系统服务进行储存。 那就用会员自己的组织证书来称呼这个无体操作. 它只承认签名的用户并返回当前的工作空间/根. 它没有产生成员或配额。 认证删除停止了新的证书;已经签发的证书保留了现有的最多15分钟的吊销限制。 见 [安排工作空间访问](https://npmcn.com/package/apps/developer/docs/architecture/organization-access.md)消费者一体化需要经过批准的SDK发行.

| 导入 | 运行时间 |
| --- | --- |
| `@finueva/drive` | 浏览器客户端、 错误、 类型 |
| `@finueva/drive/client` | 浏览器客户端 |
| `@finueva/drive/server` | 工人/节点用户和服务客户端 |
| `@finueva/drive/core` | 错误值 |
| `@finueva/drive/types` | 公共运营类型 |

## 游客共享

管理人员可以恢复与 `getVisitorGrant({ workspaceId, itemId, grantId })` 用于复制链接或待发电子邮件,而不创建其他赠款。 直接/继承的列表条目 `source` 财务报告和审定财务报表 `sourceItemId`;使用该源项进行回收/撤销。 儿童的一般接触必须反映继承的公共联系.

共享访问源需要匹配的工人和添加剂迁移 `0013`管理人员使用 `createVisitorGrant`, (中文(简体) ), `listVisitorGrants` 财务报告和审定财务报表 `revokeVisitorGrant` 通过普通用户客户端。 创建需要 `{ workspaceId, itemId, idempotencyKey, command }`,命令明确选择其中之一 `{ mode: "anyone", role: "viewer", expiresAt }` 或者说 `{ mode: "email", role: "viewer", email, expiresAt }`。未知的电子邮件永远不会允许公众访问;访问者编辑器被拒绝。 应用程序拥有电子邮件发送.

`createDriveVisitorClient({ baseUrl, token })` 从根导出, `/client` 财务报告和审定财务报表 `/server`它只会暴露 `readItem`, (中文(简体) ), `listChildren`, (中文(简体) ), `createDownload` 财务报告和审定财务报表 `redeemInvitation`。它不需要 Auth 账户,省略了 cookie 和 裁判员,并在授权信头中发送能力 。 将收件人页面符号放入片段, 绝不查询字符串或路径段 。 任何直接读取的链接符号; 电子邮件挑战必须首先用新的 `createVisitorSessionToken()` 数值。 保留准确的会话符号进行明确的重试,然后用它创建访问客户端. 不使用一次性挑战来读取文件 .

赠款在30天内到期,24小时内提出挑战,7天内开会。 下载是当前版本的GET/HEAD描述符,寿命为60秒. 撤销会阻碍新的授权, 但无法回顾已经发布的 URL 。 见 [访客合同](https://npmcn.com/package/apps/developer/docs/architecture/security/visitor-sharing.md) 用于限制、交付重试、文件夹边界和消费者一体化.

## 浏览器

核准的生态系统服务器可单独使用 `createDriveProvisioningClient` 从 `/server` 调用 `provisionWorkspace(command)`配置精确的环境和 `getProvisioningCredential` 使用 Auth 服务证书而不是用户证书的提供者。 命令需要稳定的提供ID,精确的工作空间参考,以及明确的版本存储权限. 客户不推断配额,不遵循重定向,或重试. 见 [工作空间提供](https://npmcn.com/package/apps/developer/docs/sdk/provisioning.md) 所有权和回收边界.

```ts
import { createDriveClient, createVerifiedOperationKey } from "@finueva/drive";

const drive = createDriveClient({
  baseUrl: "https://drive.example.com",
  getCredential: async ({ signal }) => {
    signal.throwIfAborted();
    const credential = await auth.getDriveCredential({ workspace: { type: "personal" } });
    signal.throwIfAborted();
    return credential.token;
  },
  timeoutMilliseconds: 30_000,
});

const { data: workspace } = await drive.getCurrentWorkspace();
const page = await drive.listFolderChildren({
  workspaceId: workspace.workspaceId,
  itemId: workspace.rootItemId,
  limit: 50,
});
const matches = await drive.searchWorkspaceItems({
  workspaceId: workspace.workspaceId,
  query: "Project",
  limit: 50,
});

const completionIdempotencyKey = crypto.randomUUID();
const uploaded = await drive.uploadVerifiedFile({
  workspaceId: workspace.workspaceId,
  target: { type: "create", parentItemId: workspace.rootItemId, name: file.name },
  source: file, // Blob; File is supported without being required
  mediaType: file.type || "application/octet-stream",
  protectionClassification: "ordinary",
  idempotencyKey: createVerifiedOperationKey(),
  completionIdempotencyKey,
  onProgress: ({ phase, confirmedByteLength, totalByteLength }) => {
    renderProgress(phase, confirmedByteLength, totalByteLength);
  },
});
```

提供方每请求运行一次. SDK只通过 `Authorization: Bearer`,总是设置 `credentials: "omit"` 财务报告和审定财务报表 `cache: "no-store"`,从不读饼干。 配置不接受默认标题 。 信用获取,获取,和响应处理共享一个受限请求截止日期:默认为30秒,可配置从一毫秒到120秒. 后面的天体 PUT `uploadVerifiedFile` 不受该默认的约束;见 [上传进度和拖放检测](https://npmcn.com/package/%40finueva/drive/#readme-upload-progress-and-stall-detection)。 。 。 .

`auth` 是一个配置的 `@finueva/auth` 客户端。 选择确切的个人或组织工作空间。 本地获取不需要包装 .

批准 Drive 中的确切申请来源 `DRIVE_BROWSER_ORIGINS` 政策和分别配置归档 CORS。 API的反应必须曝光 `X-Request-ID` 财务报告和审定财务报表 `ETag`。见 [浏览器设置](https://github.com/Ifkafin/drive/blob/main/apps/developer/docs/architecture/configuration.md#native-api-browser-origins)。 。 。 .

## 工人和节点

```ts
import { createDriveServerClient } from "@finueva/drive/server";

const drive = createDriveServerClient({
  baseUrl: "https://drive.example.com",
  credential: ({ signal }) => requestCredential(request, signal),
});
```

使用用户权限时创建每个请求的客户端 。 一个固定 `credential` 字符串被接受为明确范围证书,但SDK不创建,刷新,坚持,或推断会话,cookie,提供者代币,或服务权限.

服务器客户端曝光当前 API 操作和流出 `downloadItem`。浏览器和用户客户端额外曝光基于 Blob `uploadVerifiedFile`。服务器客户端接受明确的准备、恢复和发布命令,而不是Blob管弦乐.

## 工作空间发现

`getCurrentWorkspaceSources()` 返回实际管理量与 已知的提供者种类。 它不创造外部联系或提供保健.

```ts
const recent = await drive.listWorkspaceItems({ workspaceId, view: "recent", limit: 25 });
const shared = await drive.listWorkspaceItems({ workspaceId, view: "shared" });
const trash = await drive.listWorkspaceItems({ workspaceId, view: "trash" });
const usage = await drive.getWorkspaceUsage({ workspaceId });
```

最近的意思是记录修改时间,而不是查看活动. 历史未知 时间戳和创建者的用户ID保持无效;未知的修改时间除外 从最近的结果,直到一个真正的突变。 共享名单 用户/团队赠款,不继承后代或所有工作空间可见项目。 废物 要求删除权限, 并保留当前 ETags 用于当前突变 方法。 。 。 续作是加密的、主/根/过滤式的和短寿命的; 在 stale- page 错误上重新启动 。 可选 `kind` 财务报告和审定财务报表 `creatorUserId` 过滤器应用于 帕吉尼通前的服务。 配额改为要求 `usage:read` 返回精确 十进制字节字符串,夹住可用性和未解决的保留证据. 这些源添加需要后端迁移 `0010`部署和SDK释放.

## 业务

使用当前API操作ID的方法; `downloadItem` 财务报告和审定财务报表 `uploadVerifiedFile` 运输工具:

-   `createVisitorGrant`
-   `getVisitorGrant`
-   `listVisitorGrants`
-   `revokeVisitorGrant`
-   `getFileAccessContext`
-   `createEditingSession`
-   `renewEditingSession`
-   `closeEditingSession`
-   `revokeEditingSession`
-   `listOwnedItems`
-   `transferItemOwnership`
-   `archiveItem`
-   `getWorkspaceSharingPolicy`
-   `updateWorkspaceSharingPolicy`
-   `registerItemRecipient`
-   `registerItemRecipients`
-   `listItemSharingPeople`
-   `listIncomingShares`
-   `getCurrentWorkspace`
-   `ensureOrganizationWorkspaceAccess`
-   `listWorkspaceItems`
-   `getCurrentUserWorkspaceUsage`
-   `getWorkspaceUsage`
-   `getCurrentWorkspaceSources`
-   `getItem`
-   `searchWorkspaceItems`
-   `listFolderChildren`
-   `createFolder`
-   `updateItem`
-   `trashItem`
-   `restoreItem`
-   `deleteItem`
-   `listItemVersions`
-   `getItemVersion`
-   `restoreItemVersion`
-   `createDownload`
-   `downloadItem`
-   `listItemPermissions`
-   `readEffectiveItemPermissions`
-   `createItemPermission`
-   `createInternalItemPermission`
-   `updateItemPermission`
-   `revokeItemPermission`
-   `revokeInternalItemPermission`
-   `prepareVerifiedTransfer`
-   `publishVerifiedTransfer`
-   `recoverVerifiedTransfer`
-   `uploadVerifiedFile`

`getCurrentWorkspace` 将证书中选定的 Auth 上下文映射到提供驱动器的工作空间和犬类管理根。 它只接受可选的 `{ signal }` 输入,从不作为副作用的条款,并返回任何应享权利、证书或私人持久性字段.

`getItem` 需求 `items:metadata:read`未经批准,被立墓碑或者未公布的物品被隐匿. 文件夹有 `currentVersion: null`; 文件显示其当前版本。 强 Etag 匹配项目修改 。 媒体类型和保护分类是不信任的元数据,而不是内容权威. 内部存储/提供者状态从未被曝光 .

`searchWorkspaceItems` 匹配 NFC,大小写敏感的名称前缀:1-64 Unicode代码点,最多255个UTF-8字节,没有C0/C1控制或U+2028/U+2029. 冻结 `{ items, nextCursor }` 页面默认为由二进制名称命令的50行,然后是项目ID。 结果后加 `volumeId` 财务报告和审定财务报表 `provider: "managed"` 改为项目元数据。 空页不能有光标 .

每一次突变都需要在操作定义一个时API的显式一能键. 项目生命周期变异还需要当前强项ETag作为 `ifMatch`; 赠款突变使用其有文件记载的收款或赠款先决条件。 变异从不自动重试. Sparse 更新省略 `undefined` 属性并保持清晰 `null` 过期.

成功调用返回 `{ data, status, requestId, validators }`。成功的反应必须包含一个有效的 `X-Request-ID`; Cononical API 错误必须在标题和正文中带有相同的请求ID. 任何缺失、畸形或不匹配的值都是 `invalid_response`。唯一暴露的验证器是 `etag`, (中文(简体) ), `permissionCollectionEtag`,以及 `permissionGrantEtag`。 。 。 .

`updateItem` 重命名并移动一个稳定项目ID。 立即改变继承的赠款祖先; Drive 不复制赠款. `trashItem` 保留了30天的墓碑, `restoreItem` 要求原父母继续活动 `deleteItem` 只有在保留期满后才能开始永久归档清理,并且不执行搁置。 永久删除目前被限制在最多25个子树项目和25个总版本;较大的树无法使用,直到存在持久的工作流程。 准确的复试恢复保留删除检查站,绝不引发盲目提供者重复.

`listItemVersions` 页面不可变现/被叠加的版本,每页最多50个. `getItemVersion` 核实所有三个工作空间/项目/版本的ID并隐藏没有的历史。 保留状态不全 . `restoreItemVersion` 解剖修改当前版本和项目修改,而不复制或覆盖归档字节.

`createDownload` 返回当前或明确不可变的版本的短寿命归档描述符,一个可见 `restore-pending` 冷药或无人 `304` 操作结果,其验证者保留源ETag。 完整、闭合、开放和后缀范围使用所选归档对象的强 ETag; 配置不当或多区域作为完整的表示, 而有效的非重叠范围失败 `range_not_satisfiable`。 。 。 . `downloadItem` 遵循一个没有驱动器证书、环境浏览器证书或推荐人的描述符,并返回提供者机构作为后压 `Response`; 它保持同样的 `304` 和冷藏结果 没有提供者的要求。 它验证确切状况、ETag、身份编码、长度和 `Content-Range`,取消不正确的上游机构,并保持呼叫者取消/死线权限的活动,直到流关闭或取消。 它永远不会返回 Blob, ArrayBuffer, 文本, 或基础64 的全文件便利值 .

客人的客户也会曝光 `downloadItem(input?: VisitorDownloadInput): Promise<Response>` 可选 `itemId`, (中文(简体) ), `method`, (中文(简体) ), `range` 财务报告和审定财务报表 `signal`。它使用相同的描述符 验证器和流运,包括方向拒绝和精确流运 字节数。 它不散开或复制完整的响应. 关于预览新鲜度, 捕获 `createDownload({ itemId, method: "HEAD" })` 定界读取前后; 比较描述符 `response.versionId`, (中文(简体) ), `byteLength`, (中文(简体) ), `contentType` 强壮 `etag`, (中文(简体) ), ,并将下载的ETag回复与该基准进行比较。 重新授权失败或 更改证据丢弃预览 。 这些是内容验证器,不是物品生命周期 (原始内容存档于2018-10-21). Etags. 访客仍只使用查看器,无法查询私人权限或恢复 冷的内涵.

## 核实的转让

见 [协调的 SDK 切换](https://npmcn.com/package/apps/developer/docs/sdk/verified-transfers.md) 消费者和资格界限.

`uploadVerifiedFile` 准备一个不可改变的全对象传输,将准确的 Blob 直接流到其已签名的提供者 URL,并在 Drive 独立验证保留提供者的收据后发布 。 普通路径是准备 → PUT → 发布;它不会对上传任务进行投票,也不会读回元数据. 最终 `published` 结果包括当前项目/版本身份、精确字节、完整的SHA-256、介质类型、保护分类和提供者ETag.

创建目标为 `{ type: "create", parentItemId, name }`替换为 `{ type: "replace", itemId, currentVersionId }`;明确的当前版本是写入的先决条件. 编辑客户端以其范围化的编辑证书和受众使用相同的替换协议. `getFileAccessContext` 当前的文件访问和编辑背景仍然可用.

生成准备密钥 `createVerifiedOperationKey()`,然后保留该密钥、完成密钥和重试的确切来源/意图。 密钥有固定的24小时回放期限; 新密钥允许绑定客户端时钟 skew. 退休、过期或错误签发的密钥返回可操作的关闭理由。 他们从未授权默默创建新的行动. 中断的准备或出版许可证最多一次立即重试网络出错/出错。 丢失的 PUT 响应或永久创建 `412` (a) 驱动器必须独立证明所保留的确切对象。 已出版的准备回放没有执行提供者 PUT 。 恢复只返回原已承认作业的现有能力.

通用帮助器支持0到1个GiB并递增256个KiB窗口的散列. 它并没有以 ArrayBuffer 或 Base64 字符串实现整个源. 已签名的供应商头需要整个 SHA-256, 准确的内容类型和长度, `cache-control: no-store, no-transform`,不可改变 `if-none-match: *`和完整的加密图案 当存在。 请求省略用户权限, cookie 和 referers; 重定向被拒绝 。 浏览器 `XMLHttpRequest` 进度路径是裁判员的例外和重定向保证:它适用页面的重定向政策,并报告拒绝的重定向(见 [上传进度和拖放检测](https://npmcn.com/package/%40finueva/drive/#readme-upload-progress-and-stall-detection)) (中文(简体) ). SDK对照来源验证退回的犬科收据并请求分类. ETag是提供者身份,而不是检查和的替代品.

进度回调是不可改变的,与行动隔离. 上传输入的所有字节 `completing`成功需要条条条 `published` 结果。 见 [上传进度和拖放检测](https://npmcn.com/package/%40finueva/drive/#readme-upload-progress-and-stall-detection) 用于字节级别的进展。 取消打电话者 停止进一步的管弦乐和报告 `aborted`。它不称为已退役的流产路线,也不称释放能力控件:服务的受限保留工调和了原来的不可改变的操作.

旧多部分/会话的写作和控制API是有意的: `createUpload`, (中文(简体) ), `getUploadStatus`, (中文(简体) ), `createUploadPartDescriptor`, (中文(简体) ), `recordUploadPart`, (中文(简体) ), `completeUpload`, (中文(简体) ), `abortUpload`, (中文(简体) ), `createFileVersionUpload`, (中文(简体) ), `commitFileVersion`, (中文(简体) ), `uploadFile` 财务报告和审定财务报表 `uploadFileVersion`. 这是一个协调的突破切入。 仅与匹配的当前服务和升级的消费者或孤立的v2部署相接. 历史读取、下载、编辑、赠款、访问者访问和不可改变的版本元数据仍然可用;没有新的会计当局从不被视为允许采用遗留数据.

### 上传进度和拖放检测

`onProgress` 在散列和发送时报告字节,顺序 `hashing`, (中文(简体) ), `preparing`, (中文(简体) ), `uploading`, (中文(简体) ), `completing`。 。 。 . `phase`, (中文(简体) ), `confirmedByteLength`, (中文(简体) ), `totalByteLength` 并且该部分保留其意义; `stage`, (中文(简体) ), `hashedByteLength` 财务报告和审定财务报表 `sentByteLength` 是可选添加。 每个计数器都是非减速的,一个舞台从不重复或回回,一个字节阶段报告最多约200回.

```ts
await drive.uploadVerifiedFile({
  ...intent,
  onProgress: ({ stage, hashedByteLength, sentByteLength, totalByteLength }) => {
    const done = stage === "hashing" ? hashedByteLength : sentByteLength;
    render(stage, (done ?? 0) / totalByteLength);
  },
});
```

发送字节需要能够观察上传的传输. 没有习惯 `fetch`,浏览器和网页视图发送一个跨源对象PUT通过 `XMLHttpRequest`,它报告真实的字节。 节点,工人,同源PUT, `upload: { transport: "fetch" }` 和习惯 `fetch` 只报告 0 , 然后整个文件 `completing`。如果您提供 `fetch`例如,每一次发送都用栅栏 `createUploadProgressFetch(fetch)` 其最内向的运输 获得同样的进步. `XMLHttpRequest` 无法在跟踪或设定前拒绝方向 `referrerPolicy: "no-referrer"`; 保留 `transport: "fetch"` 这些都比进步更重要.

该天体PUT不再有固定的30秒期限了. 当能力到期(在被接纳后最多5分钟,此后拒绝出版),当一个量度的转移没有发送用于 `upload.stallTimeoutMilliseconds` (违约30 000),或 `upload.maxDurationMilliseconds` 当设置。 明确 `timeoutMilliseconds` 除非 `upload.maxDurationMilliseconds` 已经设定。 在最后一个字节拒绝之前停止的传输 `timeout` 或者说 `network_error` ,而不发布;用原始密钥重试。 SDK构建时没有多段或可重复的上传,因此一个文件必须在可用的上行链路速度下符合能力窗口. 见 [已核实的传输指南](https://npmcn.com/package/apps/developer/docs/sdk/verified-transfers.md#upload-progress-and-stall-detection)。 。 。 .

```ts
const drive = createDriveClient({
  baseUrl,
  getCredential,
  upload: { stallTimeoutMilliseconds: 20_000, maxDurationMilliseconds: 240_000 },
});
```

## 错误

失败投出 `DriveError`. Knowen canonical API 信封保留其已关闭的API代码,HTTP状态,并请求ID. SDK拥有的代码是:

-   `credential_unavailable`
-   `invalid_input`
-   `network_error`
-   `timeout`
-   `aborted`
-   `invalid_response`

消息是固定的. `details` 是空的或包含一个 `reason` 从 `DRIVE_API_ERROR_REASONS`,通过键入读取 `error.details.reason`重播失败 `transfer_operation_retired`, (中文(简体) ), `transfer_operation_expired` 财务报告和审定财务报表 `transfer_operation_clock_skew`;呼叫者不得自动替换新密钥。 未知的细节或原因是 `invalid_response`。每个操作在证书查询或获取前都会验证输入。 出错输出从来不包括响应机构,URL,证书,提供者例外或提交值. JSON的读取有字节,块和截止限,被拒绝时被取消.

## 基础 URL

使用绝对的 HTTPS URL 。 普通 HTTP 仅用于 `localhost`, (中文(简体) ), `127.0.0.1`,或 `[::1]`。拒绝证书、查询字符串、碎片和其他协议.

## 释放状态

发行版由已审查的更改器选择. 资格 构建精确编译的驱动工作, 获取 `/api/v1/openapi.json` 通过Miniflare,检查生成的字节字节类型,将软件包打包,并安装了有生命周期脚本被禁用的柏油球入清洁外部项目.

`@finueva/drive` 在npm上发布. 源寄存器是私有的,因此没有公共出处. ADR 0016记录了已完成的维护者-2FA靴子;后来的放出使用受保护的OIDC工作流程和npm批准,没有存储npm令牌.

## 常见问题

### @finueva/drive 是什么？

Finueva Drive 的公共浏览器、 Worker 和节点客户端

### 如何安装 @finueva/drive？

在项目目录运行 npm install @finueva/drive，或使用 pnpm add / yarn add / bun add。

### @finueva/drive 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @finueva/drive 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @finueva/drive 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @finueva/drive 可以商用吗？

@finueva/drive 使用 ISC 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @finueva/drive 的下载量有多少？

根据 npm 官方下载统计，@finueva/drive 在 2026/10/15 – 2026/11/13 这 30 天内被下载 3,486 次，日均约 116 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @finueva/drive 还在维护吗？

最新版本 0\.36\.0 发布于 2026/11/14（今天）；至今共发布 39 个版本，其中过去 12 个月发布了 39 个；首次发布于 2026/08/18。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

