# @freshbooks/api 中文文档

规范地址：https://npmcn.com/package/%40freshbooks/api/

版本：4\.1\.0
npm 元数据更新时间：2024-09-11T17:12:32.722Z
中文译文更新时间：2026-11-15T13:50:56.706Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：353 kB，201 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=14
- 运行依赖：5 个
- 首次发布：2020-12-14T19:57:49.958Z
- 最新版本发布：2024-09-11T17:12:32.422Z
- 近 30 天下载量：10282（2026-10-16 至 2026-11-14，npm 官方下载统计）
- 已发布版本数：26（近 12 个月 0 个）

## 中文简介

FreshBooks API 的节点JS SDK

## 安装

```sh
npm install @freshbooks/api
```

也可以使用：`pnpm add @freshbooks/api`、`yarn add @freshbooks/api`、`bun add @freshbooks/api`

## README

# 新书节点JS SDK

[![npm](https://img.shields.io/npm/v/@freshbooks/api)](https://www.npmjs.com/package/@freshbooks/api) ![node-lts](https://img.shields.io/node/v-lts/@freshbooks/api) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/freshbooks/freshbooks-nodejs-sdk/Run%20Tests)](https://github.com/freshbooks/freshbooks-nodejs-sdk/actions?query=workflow%3A%22Run+Tests%22)

FreshBooks NodeJS SDK允许您更方便地使用FreshBooks API.

## 安装

使用您最喜欢的软件包管理器安装任何软件包并保存到您的 `package.json`数字 :

```shell
$ npm install @freshbooks/api

# Or, if you prefer yarn
$ yarn add @freshbooks/api
```

## 使用量

见 [完整文档](https://freshbooks.github.io/freshbooks-nodejs-sdk/)。 。 。 .

### 配置 API 客户端

您的应用程序将使用 REST API 进行交互 `Client` 对象,可从 `@freshbooks/api` 软件包. 客户端可立即使用有效的 OAuth 令牌,或提供客户端秘密,并重定向 URI 然后用来获取访问令牌.

#### 使用预生成的访问符

```typescript
import { Client } from '@freshbooks/api'

const clientId = process.env.FRESHBOOKS_APPLICATION_CLIENT_ID

// Get token from authentication or configuration
const token = process.env.FRESHBOOKS_TOKEN

// Instantiate new FreshBooks API client
const client = new Client(clientId, {
    accessToken: token,
})
```

#### 使用客户端秘密并重定向 URI

```typescript
import { Client } from '@freshbooks/api'

const clientId = process.env.FRESHBOOKS_APPLICATION_CLIENT_ID
const clientSecret = process.env.FRESHBOOKS_APPLICATION_CLIENT_SECRET

// Instantiate new FreshBooks API client
const client = new Client(clientId, {
    clientSecret,
    redirectUri: 'https://your-redirect-uri.com/'
})

// Give this URL to the user so they can authorize your application
const authUrl = client.getAuthRequestUrl()

// This will redirect them to https://your-redirect-uri.com/?code=XXX
const code = ...

// Returns an object containing the access token, refresh token, and expiry date
// Note that this function sets the token on this client instance to automatically
// authenticates all future requests with this client instance
const tokens = client.getAccessToken(code)
```

### 从 REST API 获取/ 设置数据

所有 REST API 方法都以 :

```typescript
{
    ok: boolean
    data?: T // model type of result
    error?: Error
}
```

示例 API 客户端呼叫 :

```typescript
try {
    // Get the current user
    const { data } = await client.users.me()

    console.log(`Hello, ${data.id}`)
} catch ({ statusCode, message }) {
    // Handle error if API call failed
    console.error(`Error fetching user: ${statusCode} - ${message}`)
}
```

#### 错误

如果 API 出错, 响应对象包含 `error` 对象,形状如下:

```typescript
{
    name: string        // Name of the method called
    message: string     // Error message
    statusCode?: string // HTTP Status Code
    errors?: APIError[] // More detailed message if available
}
```

并非所有API都调用返回特定错误的列表,但如果调用,其形式将是:

```typescript
{
    message: string    // Specific error message eg. 'Item not found.'
    errorCode?: number // A error code, if available. Eg. '1012'
    field?: string     // The field that caused the error, if available. Eg. `itemid`
    object?: string    // The resource, if available. Eg. `item`
    value?: string     // The value of the field, if available. Eg. `123432`
}
```

实例:

```typescript
clientData = {}
try {
    const client = await fbClient.clients.single(accountId, 00000)
    console.log('Not called')
} catch (err) {
    console.log(err.name)
    console.log(err.message)
    console.log(err.statusCode)
    console.log(err.errors)
}
/*
Output:
Get Client
Client not found.
404
[
  {
    message: 'Client not found.',
    errorCode: 1012,
    field: 'userid',
    object: 'client',
    value: '00000'
  }
]
*/
```

```typescript
clientData = {}
try {
    const client = await fbClient.clients.create(clientData, accountId)
    console.log('Not called')
} catch (err) {
    console.log(err.name)
    console.log(err.message)
    console.log(err.statusCode)
    console.log(err.errors)
}
/*
Output:
Create Client
At least one field among fname, lname, email and organization is required.
422
[
  {
    message: 'At least one field among fname, lname, email and organization is required.',
    errorCode: 7012,
    field: null,
    object: 'client',
    value: ''
  }
]
*/
```

### 铺设、过滤和包括

如果一个端点通过查询参数支持搜索或自定义包含,这些参数 可用 `QueryBuilderType`。见 [FreshBooks API - 参数](https://www.freshbooks.com/api/parameters) 文档.

```typescript
type QueryBuilderType = PaginationQueryBuilder | IncludesQueryBuilder | SearchQueryBuilder
```

API客户端上的适当方法将支持一系列构建者:

```typescript
public readonly invoices = {
    list: (accountId: string, queryBuilders?: QueryBuilderType[]) => Promise<Result<{
        invoices: Invoice[];
        pages: Pagination;
    }>>;
}
```

#### 倾斜

植入结果包含在 `list` 回应。 这个 `data` 对象将包含 `pages` 财产,包括:

```typescript
{
    page: number  // The current page of results
    pages: number // The number of pages of results
    total: number // The total number of results
    size: number  // The number of results per page
}
```

为了打通电话,首先创建一个 `PaginationQueryBuilder` 使用 `page` 财务报告和审定财务报表 `perPage` 函数 并传入 `list` 电话.

```typescript
import { PaginationQueryBuilder } from '@freshbooks/api/dist/models/builders/PaginationQueryBuilder'

const paginator = new PaginationQueryBuilder()
paginator.page(1).perPage(10)
let page = 1
let totalPages = 1

while (page <= totalPages) {
    let response = await fbClient.clients.list(accountId, [paginator])
    let { clients, pages } = response.data
    console.log(clients)
    console.log(`Page ${pages.page} of ${pages.pages} pages`)
    console.log(`Showing ${pages.size} per page for ${pages.total} total clients`)

    page++
    totalPages = pages.pages
    paginator.page(page)

    console.log('Clients:')
    clients.map((client) => console.log(client.organization))
}
```

#### 搜索过滤器

过滤返回的结果 `list` 方法调用,构建一个 `SearchQueryBuilder` 传过来,传进去 页:1 `list` 电话.

这个 `SearchQueryBuilder` 支持模式 : `equals`, (中文(简体) ), `in`, (中文(简体) ), `like`, (中文(简体) ), `between`,以及 `boolean`。 。 。 .

```typescript
s = SearchQueryBuilder()
s.in("email", "api@freshbooks.com")
console.log(s.build()) // "&search[email]=api@freshbooks.com"

s = SearchQueryBuilder()
s.in("clientids", [123, 456])
console.log(s.build()) // "&search[clientids][]=123&search[clientids][]=456"

s = SearchQueryBuilder()
s.like("email_like", "@freshbooks.com")
console.log(s.build()) // "&search[email_like]=@freshbooks.com"

s = SearchQueryBuilder()
s.between("amount", 1, 10)
console.log(s.build()) // "&search[amount_min]=1&search[amount_max]=10)"

s = SearchQueryBuilder()
s.between("start_date", date.today())
console.log(s.build()) // "&search[start_date]=2020-11-21"

s = SearchQueryBuilder()
// Boolean filters are mostly used on Project-like resources
s.boolean('complete', false) // "&complete=false"
```

示例 API 客户端调用 `SearchQueryBuilder`数字 :

```typescript
import { SearchQueryBuilder } from '@freshbooks/api/dist/models/builders/SearchQueryBuilder'

//create and populate SearchQueryBuilder
const searchQueryBuilder = new SearchQueryBuilder()
    .like('address_like', '200 King Street')
    .between('date', { min: new Date('2010-05-06'), max: new Date('2019-11-10') })

try {
    // Get invoices matching search query
    const { data } = await client.invoices.list(accountId, [searchQueryBuilder])

    console.log('Invoices: ', data)
} catch ({ statusCode, message }) {
    // Handle error if API call failed
    console.error(`Error fetching user: ${statusCode} - ${message}`)
}
```

#### 包括

将额外关系、分资源或数据纳入答复 `IncludesQueryBuilder` 可构建 然后可以传入 `list`, (中文(简体) ), `single`, (中文(简体) ), `create`,以及 `update` 打电话.

示例 API 客户端调用 `IncludesQueryBuilder`数字 :

```typescript
import { IncludesQueryBuilder } from '@freshbooks/api/dist/models/builders/IncludesQueryBuilder'

//create and populate IncludesQueryBuilder
const includesQueryBuilder = new IncludesQueryBuilder().includes('lines')
console.log(includesQueryBuilder.build()) // "&include[]=lines"

try {
    // Get invoices with included line items
    const { data } = await client.invoices.list(accountId, [includesQueryBuilder])

    console.log('Invoices: ', data)
} catch ({ statusCode, message }) {
    // Handle error if API call failed
    console.error(`Error fetching user: ${statusCode} - ${message}`)
}
```

### 数据字段注释

#### 日期和时间

由于历史原因,FreshBooks API中的许多资源(大多为会计重述)返回日期/时间 "美国/东部"时区. 已作出一定努力,将这些模型转换为返回 `Date` 已正常化为世界协调时的对象.

#### 货币价值

FreshBooks API 作为包含金额和货币代码的货币对象返回大多数货币值:

```typescript
export default interface Money {
    amount?: string
    code?: string
}
```

该量作为字符串返回并存储,以防止浮点精度问题. 如果你这样做 计算这些值时,建议使用一个库进行小数计算,例如: [小数点.js](https://www.npmjs.com/package/decimal.js), (中文(简体) ), [大块. js](https://www.npmjs.com/package/big.js), (中文(简体) ), 或者说 [大数.js](https://www.npmjs.com/package/bignumber.js)

## 常见问题

### @freshbooks/api 是什么？

FreshBooks API 的节点JS SDK

### 如何安装 @freshbooks/api？

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

### @freshbooks/api 支持 TypeScript 吗？

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

### @freshbooks/api 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @freshbooks/api 需要什么版本的 Node\.js？

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

### @freshbooks/api 可以商用吗？

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

### @freshbooks/api 的下载量有多少？

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

### @freshbooks/api 还在维护吗？

最新版本 4\.1\.0 发布于 2024/09/12（2 年前）；至今共发布 26 个版本，其中过去 12 个月发布了 0 个；首次发布于 2020/12/15。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

