# @b-jones-rfd/sp-rest-connect 中文文档

规范地址：https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/

版本：5\.1\.1
npm 元数据更新时间：2026-10-11T00:28:25.389Z
中文译文更新时间：2026-11-07T23:37:04.827Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40b-jones-rfd/sp-rest-connect
原文对照：https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/?lang=original
项目主页：https://github.com/B-Jones-RFD/sp-rest-connect#readme
源码仓库：https://github.com/B-Jones-RFD/sp-rest-connect

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

- 包体积（解压后）：238 kB，7 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：0 个
- 首次发布：2023-02-25T14:45:29.868Z
- 最新版本发布：2026-10-11T00:28:25.059Z
- 近 30 天下载量：2036（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：38（近 12 个月 12 个）

## 中文简介

使用 SharePoint REST 服务与列表和文档库交互

## 安装

```sh
npm install @b-jones-rfd/sp-rest-connect
```

也可以使用：`pnpm add @b-jones-rfd/sp-rest-connect`、`yarn add @b-jones-rfd/sp-rest-connect`、`bun add @b-jones-rfd/sp-rest-connect`

## README

[![CI](https://github.com/B-Jones-RFD/sp-rest-connect/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/B-Jones-RFD/sp-rest-connect/actions/workflows/main.yml) [![npm version](https://img.shields.io/npm/v/%40b-jones-rfd%2Fsp-rest-connect?style=flat-square)](https://www.npmjs.com/package/@b-jones-rfd/sp-rest-connect) [![npm unpacked size](https://img.shields.io/npm/unpacked-size/%40b-jones-rfd%2Fsp-rest-connect?style=flat-square)](https://www.npmjs.com/package/@b-jones-rfd/sp-rest-connect) [![node](https://img.shields.io/node/v/%40b-jones-rfd%2Fsp-rest-connect?style=flat-square)](https://nodejs.org/) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

# SharePoint REST 连接

一个小型、无依赖的节点客户端 **默认共享点** 资源 服务,带有内置的NTLMv2认证. 读取和写入列表项目, 上传并下载文档,管理文件夹. 每次呼叫返回一个输入 `Result` 而不是扔东西.

我厌倦了为工作项目重写这些.

## 所需资源

-   **节点.js 20或后.**
-   **内置共享点** ——2013,2016,2019或订阅版-与 NTLM 认证启用 。 共享点在线是 **没有** 支持; 确实 不接受 NTLM.
-   没有别的事了 没有运行时间依赖性: NTLM 在顶端执行 联 合 国 `node:http`编号 :`node:https` 财务报告和审定财务报表 `node:crypto`。 。 。 .

### 认证

仅 **NTLMv2 地图** 支持。 SharePoint 2013 并随后通过谈判 默认。 如果服务器没有发送NTLMv2要求的目标信息, 请求失败 `NTLM server did not send target info` 而不是沉默无声 降级为 NTLMv1, 在 Node 的 OpenSSL 3 中不安全且不可用 建设.

## 安装

```sh
npm i @b-jones-rfd/sp-rest-connect
# or
pnpm add @b-jones-rfd/sp-rest-connect
# or
yarn add @b-jones-rfd/sp-rest-connect
```

## 快开始

```ts
import { createSiteConnection } from '@b-jones-rfd/sp-rest-connect'

const connection = createSiteConnection({
  username: 'jsmith',
  password: process.env.SP_PASSWORD!,
  domain: 'CONTOSO', // NTLM (NetBIOS) domain, not a DNS name
  site: 'sharepoint.contoso.local',
  serverRelativeUrl: '/sites/finance',
})

// Read
type Invoice = { Id: number; Title: string; Amount: number }
const params = new URLSearchParams({ $select: 'Id,Title,Amount', $top: '500' })
const items = await connection.getAllListContents<Invoice>({
  listName: 'Invoices',
  params,
})
if (!items.success) throw new Error(items.error)
console.log(items.data.map((i) => i.Title))

// Write: the request digest and the list's entity type are handled for you
const created = await connection.addListItem({
  listName: 'Invoices',
  payload: { Title: 'INV-1042', Amount: 1250 },
})
if (created.success) console.log(created.data.Id)
```

更多实例包括文档上传 [`examples/basic.ts`](https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/examples/basic.ts)。 。 。 .

## 使用量

### 站点连接

`createSiteConnection(options)` 将每个动作绑在一个站点并返回 a `SiteConnection`。创建连接不执行网络 I/O; 证书 在封锁中被俘获,并用于每次呼叫。 它确实检查了形状 选项并丢出 `TypeError` 对于明显错误( 内部协议) `site`页:1 `serverRelativeUrl` 没有领先的斜线,所以错位 启动时失败, 而不是后来的不透明 404 .

| 选项 | 类型 | 需求 | 默认 | 说明 |
| --- | --- | --- | --- | --- |
| `username` | `string` | Y |  | Windows账户名称,没有域名. |
| `password` | `string` | Y |  | 账户密码。 从环境读取,而不是硬编码. |
| `site` | `string` | Y |  | 只使用主机名称, 例如 . `'sharepoint.contoso.local'`。 。 。 . |
| `serverRelativeUrl` | `string` | Y |  | 站点(web)路径,例如:. `'/sites/finance'`全部数据 `folder` 参数将据此解决. |
| `protocol` | `'https' | 'http'` | 无 | `'https'` |  |
| `domain` | `string` | 无 | `''` | NTLM (NetBIOS) 域名, 如. `'CONTOSO'`。为服务器本地账户留空. |
| `hostname` | `string` | 无 | `os.hostname()` | 工作站名传入NTLM握手. 很少需要改变. |
| `agentOptions` | `https.AgentOptions` | 无 |  | HTTP 代理的 TLS / socket 选项 。 见 [TLS 和内部证书](https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/#readme-tls-and-internal-certificates)。 。 。 . |
| `retry` | `RetryOptions` | 无 |  | 重试读取动作上的瞬态失败 。 见 [重试瞬间失败](https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/#readme-retrying-transient-failures)。 。 。 . |

### 独立行动

单用或只导入您需要的东西, 每个动作都会导出 作为工厂。 用相同的选项调用它以获得可重复使用的动作 :

```ts
import { getListContents } from '@b-jones-rfd/sp-rest-connect'

const fetchList = getListContents(siteConnectionOptions)
const items = await fetchList({ listName: 'Invoices' })
```

### 结果

每个行动都决定 `Result<T>` 绝不扔出:

```ts
type Result<T> = Success<T> | Failure

type Success<T> = { success: true; data: T }
type Failure = {
  success: false
  error: string // "Error in getListContents: HTTP 404: List 'Tasks' does not exist"
  code: FailureCode
  status?: number // HTTP status, for HTTP / AUTH failures
  details?: { code?: string; message?: string } // SharePoint's own error, when it sent one
  retryAfterMs?: number // from a Retry-After header, when present
}
```

检查 `success` 缩小,然后在 `code` 而不是在留言上 文本 :

| `code` | 含义 |
| --- | --- |
| `HTTP` | SharePoint以非-2xx状态(401/403除外)回答. 见 `status`编号 :`details`。 。 。 . |
| `AUTH` | 401或403——不良资质,NTLM被否决,或缺失/过期请求文摘. |
| `TIMEOUT` | 没有到达字节 `timeout` m. |
| `ABORTED` | 取消通过 `signal`。 。 。 . |
| `NETWORK` | DNS,连接或TLS在任何响应前失败. |
| `PARSE` | 2xx反应,其身体未达到预期状态. |
| `UNKNOWN` | 任何别的事. |

```ts
const res = await connection.addListItem({ listName, payload })
if (!res.success) {
  if (res.code === 'AUTH') await alertOps('credentials rejected')
  else if (res.code === 'TIMEOUT' || res.code === 'NETWORK') await retryLater()
  else log.error(res.error, res.details)
}
```

`error` 总是以动作名称为前缀的人类可读信件,用于 伐木业.

### 写入操作:请求摘要

SharePoint 需要一个 `X-RequestDigest` 每封信都写着标题 连接 处理好它:第一封信从 `/_api/contextinfo`, (中文(简体) ), 缓存到SharePoint说它过期前一分钟(30分钟后) 如果SharePoint仍以403拒绝,则摘要会被刷新 并重审过一次 同步写入共享一个获取 .

自己管理消化器,通过 `requestDigest` 明确——缓存是 然后绕行,不发生自动重试. `getFormDigestValue()` 获取 一个.

独立行动工厂各自保存自己的缓存. 分享一个,创建一个 上下文并当作第二个论点:

```ts
import {
  createConnectionContext,
  addListItem,
  deleteListItem,
} from '@b-jones-rfd/sp-rest-connect'

const ctx = createConnectionContext(options)
const add = addListItem(options, ctx)
const remove = deleteListItem(options, ctx) // shares add's digest
```

`getAuthToken()` 实值 **没有** 这个值——它返回NTLM握手头, 这是连接的,并且只是用作证书检查.

### 创建和更新项目

`addListItem` 财务报告和审定财务报表 `updateListItem` 取一个普通对象。 共享点需要 列表的实体类型( n)`__metadata.type`)在身体上;连接在上看 与 `getListItemType` 它第一次看到列表并缓存它:

```ts
await connection.addListItem({
  listName: 'Invoices',
  payload: { Title: 'INV-1042', Amount: 1250 },
})

await connection.updateListItem({
  listName: 'Invoices',
  spId: 17,
  patch: { Amount: 1300 },
})
```

包含 `__metadata: { type: 'SP.Data.InvoicesListItem' }` 在对象中 你自己跳过检查. `addListItem` 确定创建的项目为 SharePoint 将它带回了新 `Id`; 通过其它参数的类型 形状`addListItem<Invoice>(...)`) (中文(简体) ).

`updateListItem` 是部分更新( OData) `MERGE` 与 `If-Match: *`: 仅限 输入 `patch` 更改,最后的作者获胜.

### 大型文件

`addDocumentToLibrary` 接受一个 `Readable` 作为 `payload`,以及 `getDocumentStreamFromLibrary` 返回一个,所以文件从不需要适应 内存 :

```ts
import { createReadStream, createWriteStream } from 'node:fs'
import { stat } from 'node:fs/promises'
import { pipeline } from 'node:stream/promises'

const { size } = await stat('backup.zip')
await connection.addDocumentToLibrary({
  folder: 'Shared Documents/Archive',
  fileName: 'backup.zip',
  payload: createReadStream('backup.zip'),
  contentLength: size, // optional; without it the upload is chunked
})

const download = await connection.getDocumentStreamFromLibrary({
  folder: 'Shared Documents/Archive',
  fileName: 'backup.zip',
})
if (download.success)
  await pipeline(download.data, createWriteStream('restored.zip'))
```

只能发送一次流, 所以如果管理中的文摘显示为呆滞 中上载写入代码失败 `AUTH` 而不是再审;拨打 再来一次 下载时的 HTTP 错误报告为 `Failure` 在任何时间之前 溪流返回.

### 文件夹

每个 `folder` 参数相对 `serverRelativeUrl` 然后从 库名称 : `'Shared Documents'`, (中文(简体) ), `'Shared Documents/Reports/2026'`。 。 。 .

### 打字结果

`getListContents`, (中文(简体) ), `getFolderContents` 财务报告和审定财务报表 `getListItem` 选择类型参数 用于项目形状。 这是一种断言,而不是验证 但它在每一个呼叫站点都省下一个铸造者:

```ts
type Task = { Id: number; Title: string; Status: 'Open' | 'Done' }

const res = await connection.getListContents<Task>({
  listName: 'Tasks',
  params,
})
if (res.success) res.data.filter((t) => t.Status === 'Open')
```

### 拨号

最多共享点返回 `$top` 每个答复(如果未设定,100个) 和,当更多的保留,a `nextLink`.你有三种方法来处理:

```ts
// 1. Everything, in one array. Fails as a whole if any page fails.
const all = await connection.getAllListContents<Task>({
  listName: 'Tasks',
  params,
})

// 2. Page by page, as an async iterator. Ends after the last page or the first failure.
for await (const page of connection.iterateListContents<Task>({
  listName: 'Tasks',
})) {
  if (!page.success) throw new Error(page.error)
  process(page.data)
}

// 3. Manually: a single page exposes `nextLink`, which `getNextPage` follows.
const first = await connection.getListContents<Task>({ listName: 'Tasks' })
if (first.success && first.nextLink) {
  const second = await connection.getNextPage<Task>({
    nextLink: first.nextLink,
  })
}
```

`getAllFolderContents` 编号 : `iterateFolderContents` 对文档也这样做 图书馆文件夹。 两者 `getAll*` 财务报告和审定财务报表 `iterate*` 接受 `maxPages` 以上限 走开. `getNextPage` 只跟踪连接本身主机的链接, 所以您 证书从不发给别处.

### 重试瞬间失败

设定 `retry` 关于重试的连接 **读取** 失败的动作 `NETWORK`, (中文(简体) ), `TIMEOUT`,或HTTP 429/502/503/504。 写作从不重试 自动——重试 `addListItem` 可创建重复.

```ts
const connection = createSiteConnection({
  ...options,
  retry: { retries: 3, baseDelayMs: 300, maxDelayMs: 5000 },
})
```

拖延随着全身的焦躁而成指数增长,如果请求出现,则提前停止 `signal` 流产。 当SharePoint发送一个 `Retry-After` 页眉(429/503),即 以等待代替,或者,如果等待时间长于 `maxDelayMs`,重试停止 失败又随着 `retryAfterMs` 设置这样你就可以决定。 过 `retryOn(failure, attempt)` 更改可重试的内容; `isTransientFailure` 要扩展则导出(默认) .

### CAML 查询和 5000 项阈值

`$filter` 一旦列表通过 SharePoint 的列表, 未索引列失败 视图阈值(默认为5,000项). `queryListItems` 发送 CAML 查询 改为 `GetItems` 相反, SQL 服务器对索引列的评价 :

```ts
const open = await connection.queryListItems<Task>({
  listName: 'Tasks',
  viewXml: `<View>
    <Query><Where><Eq><FieldRef Name='Status'/><Value Type='Text'>Open</Value></Eq></Where></Query>
    <RowLimit>500</RowLimit>
  </View>`,
  params: new URLSearchParams({ $select: 'Id,Title,Status' }),
})
```

通过放入页面 `<RowLimit>` 在风景和逝去 `pagingInfo` 从 上页的最后一个项目—— `Paged=TRUE&p_ID=${last.Id}` 当风景 由 ID (默认) 命令. `GetItems` 是一个 POST, 因此管理请求 文摘被使用;仍作为读取 `retry` 目标.

### 请求

`batch` 在一次往返中发出多个REST电话(SharePoint 2016和 后来;2013年没有 `$batch` 结束点). 读作个别部分; 连续的写入被组合为一个更改器, 应用SharePoint 解剖论. 每个次级请求都得到自己的回应——失败的请求不会 批量失败, 请检查 `ok`数字 :

```ts
const res = await connection.batch({
  requests: [
    { method: 'GET', path: `_api/web/lists/GetByTitle('Tasks')/items?$top=5` },
    {
      method: 'POST',
      path: `_api/web/lists/GetByTitle('Tasks')/items`,
      body: { __metadata: { type }, Title: 'A' },
    },
    {
      method: 'MERGE',
      path: `_api/web/lists/GetByTitle('Tasks')/items(7)`,
      body: { __metadata: { type }, Title: 'B' },
    },
    { method: 'DELETE', path: `_api/web/lists/GetByTitle('Tasks')/items(8)` },
  ],
})
if (res.success) {
  const [list, created, merged, deleted] = res.data
  if (created.ok) console.log((created.json as { Id: number }).Id)
}
```

`path` 相对于该站点( e)`_api/...`)或同一上的绝对 URL 源代码。 每个子请求的默认值 : `Accept: application/json;odata=nometadata`, (中文(简体) ), `Content-Type: application/json;odata=verbose` 当有尸体 `If-Match: *` 打开 `MERGE`编号 :`PATCH`编号 :`DELETE`; 以 `headers`。 。 。 . 创建或合并列表项的机构仍然需要 `__metadata.type` - 那个 批量不为您解析实体类型( s)`getListItemType` 页:1.

### 共同选项

每个动作都接受:

-   `timeout` - 套接字 **不活动** 超时数以毫秒计。 请求失败 有代码 `TIMEOUT` 当没有字节到达这么久。 这不是一个帽子 总持续时间; 缓慢但稳定的下载从未超过。 不为所取.
-   `signal` - 一个 `AbortSignal`终止生成a `Failure` 有代码 `ABORTED`。对于整个呼叫的艰难期限,请使用 `signal: AbortSignal.timeout(30_000)`。 。 。 .

`getDocumentFromLibrary` 额外接受 `binary` (默认) `true`页:1 返回文件为 `Buffer`;没有理由关闭它.

### TLS 和内部证书

On-premises SharePoint通常在内部CA的证书后. 而不是设定 `NODE_TLS_REJECT_UNAUTHORIZED=0` 整个进程,通过 CA 连接:

```ts
import { readFileSync } from 'node:fs'

const connection = createSiteConnection({
  ...options,
  agentOptions: { ca: readFileSync('/etc/ssl/corp-root-ca.pem') },
})
```

`agentOptions` 接受任何东西 `https.Agent` 是否为 -- `ca`, (中文(简体) ), `cert`编号 :`key` 页:1 客户端证书, `rejectUnauthorized`, (中文(简体) ), `localAddress`,习惯 `lookup`, (中文(简体) ), 等——但 `keepAlive` 财务报告和审定财务报表 `maxSockets`,这是NTLM握手 修复。 毒剂按请求创建,后被销毁.

### 特殊字符

列表标题、文件夹路径和文件名称为%- 编码并有 oData 自动增加一倍,所以 `"Bob's Tasks"` 财务报告和审定财务报表 `'Shared Documents/Q1 2026'` 以书面形式工作.

## API 密码

完整生成的参考 : **[b-jones-rfd.github.io/sp-rest-连接](https://b-jones-rfd.github.io/sp-rest-connect/)**。 。 。 .

所有选项类型都导出( E)`AddListItemOptions`, (中文(简体) ), `GetListContentsOptions`, (中文(简体) ), ...)下面的每个成员都有记录,所以在你的编辑中徘徊 显示同样的细节。 每个写入动作也接受常见 `requestDigest` 选项(省略时自动管理); `listName` 这是 列表的显示标题.

### 名单

| 行动 | 所需选项 | `data` |
| --- | --- | --- |
| `getListContents<T>({ listName, params? })` | —— 说 | `T[]` - 一页; `nextLink` 等更多的东西还剩的时候再设置 \* 100个没有 `$top`。 。 。 . |
| `getAllListContents<T>({ listName, params?, maxPages? })` | —— 说 | `T[]` ——每页收缩. |
| `iterateListContents<T>({ listName, params?, maxPages? })` | —— 说 | 同步执行器 `PageResult<T>`。 。 。 . |
| `getNextPage<T>({ nextLink })` | —— 说 | `T[]` ——链接页;仅同源链接. |
| `queryListItems<T>({ listName, viewXml, pagingInfo?, params? })` | —— 说 | `T[]` —— CAML 查询结果通过 `GetItems`。 。 。 . |
| `getListItem<T>({ listName, spId })` | —— 说 | `T` ——项目对象. |
| `getListItemType({ listName })` | —— 说 | `string` - 比如说. `'SP.Data.InvoicesListItem'`。 。 。 . |
| `addListItem<T>({ listName, payload })` | `payload`对象 | `T & { Id: number }` - 创建的项目. |
| `updateListItem({ listName, spId, patch })` | `patch`对象 | `string` ——序列补丁 (SharePoint return no body). |
| `deleteListItem({ listName, spId })` | —— 说 | `''` |
| `addAttachmentToListItem({ listName, spId, fileName, payload })` | `payload`数字 : `Buffer` | `string` ——附件的服务器相对URL. |

### 文件库

| 行动 | 所需选项 | `data` |
| --- | --- | --- |
| `getFolderContents<T>({ folder, params? })` | —— 说 | `T[]` —— 一页 `SP.File` 对象(`Name`, (中文(简体) ), `Length`(......) ; (......); `nextLink` 当更多的还剩. |
| `getAllFolderContents<T>({ folder, params?, maxPages? })` | —— 说 | `T[]` ——每页收缩. |
| `iterateFolderContents<T>({ folder, params?, maxPages? })` | —— 说 | 同步执行器 `PageResult<T>`。 。 。 . |
| `getDocumentFromLibrary({ folder, fileName })` | —— 说 | `Buffer` ——文件内容. |
| `getDocumentStreamFromLibrary({ folder, fileName })` | —— 说 | `Readable` ——文件内容,未缓存. |
| `checkFolderExistsInLibrary({ folder })` | —— 说 | `boolean` ——缺少文件夹是成功的 `false`。 。 。 . |
| `createFolderInLibrary({ folder })` | 父关系必须存在 | `string` ——新文件夹的服务器相对URL. |
| `addDocumentToLibrary({ folder, fileName, payload, contentLength? })` | `payload`数字 : `Buffer | Readable` | `string` ——服务器相对URL;覆盖已存在文件. |
| `deleteDocumentFromLibrary({ folder, fileName })` | —— 说 | `string` ——已删除 `fileName`。 。 。 . |

### 击打

| 行动 | 所需选项 | `data` |
| --- | --- | --- |
| `batch({ requests })` | SharePoint 2016+ (英语) | `BatchResponse[]` —— 说 `{ status, ok, headers, body, json? }` 按顺序排列. |

### 认证

| 行动 | `data` |
| --- | --- |
| `getFormDigestValue({})` | `string` 请求摘要,如果你想管理 `requestDigest` 你自己来. |
| `getAuthToken({})` | `string` - NTLM 第3型 `Authorization` 头曰. 仅诊断;见上文. |

### 错误

`SpRestError` 财务报告和审定财务报表 `parseSharePointError(body)` 导出。 前者是 内部运输在行动前给非-2xx反应投出的东西 把它变成一个 `Failure`;后面的摘录 `{ code, message }` 从任何 OData 出错的身体形状。 NTLM运输本身不属于公众 API (英语). 如果您需要 SharePoint 端点, 请打开此软件包 一个问题.

## 迁移到 5.0

-   **`accessToken` 不见了.** 使用 `requestDigest`,或者省略它并让 连接管理摘要.
-   **`addListItem` 编号 : `updateListItem` 只取对象.** 替换 `payload: JSON.stringify({ __metadata: { type }, ... })` 与 `payload: { ... }` - 实体类型为你解决.
-   **`addListItem` 解析创建的项目**不是JSON的绳子 替换 `JSON.parse(res.data).Id` 与 `res.data.Id`。 。 。 .
-   **NTLM 帮助者(`get`, (中文(简体) ), `post`, (中文(简体) ), `auth`, (中文(简体) ), `request`,信息创建者)是 不再出口.**

4.x-结构中增加的任何东西 `Failure` 代码, `signal`, (中文(简体) ), `agentOptions`, (中文(简体) ), `retry`,键入读取,呼出,管理文摘,流出——不变.

## 捐款

这是一个个人项目 维护我自己使用。 已经出版,所以 但我现在不接受问题 也不接受请求. 安全报告是例外;见 [警卫](https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/SECURITY.md)。 。 。 .

如果你想在当地建造:

```sh
pnpm install
pnpm dev        # vitest in watch mode
pnpm ci         # lint, test, build, package checks
pnpm docs       # generate the API reference into docs/
```

## 版本

[交换器](https://semver.org/)见 [变化](https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/CHANGELOG.md) 用于发布注释和打破更改.

## 许可证

[麻省理工学院](https://npmcn.com/package/%40b-jones-rfd/sp-rest-connect/LICENSE)

## 常见问题

### @b-jones-rfd/sp-rest-connect 是什么？

使用 SharePoint REST 服务与列表和文档库交互

### 如何安装 @b-jones-rfd/sp-rest-connect？

在项目目录运行 npm install @b-jones-rfd/sp-rest-connect，或使用 pnpm add / yarn add / bun add。

### @b-jones-rfd/sp-rest-connect 支持 TypeScript 吗？

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

### @b-jones-rfd/sp-rest-connect 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @b-jones-rfd/sp-rest-connect 需要什么版本的 Node\.js？

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

### @b-jones-rfd/sp-rest-connect 可以商用吗？

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

### @b-jones-rfd/sp-rest-connect 的下载量有多少？

根据 npm 官方下载统计，@b-jones-rfd/sp-rest-connect 在 2026/10/08 – 2026/11/06 这 30 天内被下载 2,036 次，日均约 68 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @b-jones-rfd/sp-rest-connect 还在维护吗？

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

