# @anvilco/anvil 中文文档

规范地址：https://npmcn.com/package/%40anvilco/anvil/

版本：4\.2\.0
npm 元数据更新时间：2026-11-03T00:01:01.231Z
中文译文更新时间：2026-11-06T07:39:32.288Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：135 kB，55 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：3 个
- 首次发布：2020-02-05T19:31:18.597Z
- 最新版本发布：2026-11-03T00:01:00.918Z
- 近 30 天下载量：269630（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：44（近 12 个月 4 个）

## 中文简介

Anvil API 客户端

## 安装

```sh
npm install @anvilco/anvil
```

也可以使用：`pnpm add @anvilco/anvil`、`yarn add @anvilco/anvil`、`bun add @anvilco/anvil`

## README

![Horizontal Lockupblack](https://user-images.githubusercontent.com/293079/169453889-ae211c6c-7634-4ccd-8ca9-8970c2621b6f.png#gh-light-mode-only) ![Horizontal Lockup copywhite](https://user-images.githubusercontent.com/293079/169453892-895f637b-4633-4a14-b997-960c9e17579b.png#gh-dark-mode-only)

# 节点的 Anvil API 客户端

此库将允许您与 [安维尔API](https://npmcn.com/package/%40anvilco/anvil/www.useanvil.com/developers) 在JavaScript / 节点JS.

[安维尔](https://www.useanvil.com/developers/) 为所有文件提供方便的API.

1.  [PDF 填补 API](https://www.useanvil.com/products/pdf-filling-api/) - 填写一个PDF模板,其中包含网络请求和结构化的JSON数据.
2.  [PDF 生成 API](https://www.useanvil.com/products/pdf-generation-api/) - 发送标记下来或HTML和Anvil会把它变成PDF.
3.  [Etch 电子签名与 API](https://www.useanvil.com/products/etch/) - 可自定义的、可嵌入的、带有API的电子签名平台,以控制签名过程的端到端.
4.  [工作流量(w/ API)](https://www.useanvil.com/products/workflows/) - Webforms + PDF + 有强大的无码构建器的电子符号. 轻松地收集结构化数据,生成PDF,并请求签名.

学着点 [Anvil 开发者页面](https://www.useanvil.com/developers/)见 [API 指南](https://www.useanvil.com/docs) 编辑 [参考图表QL](https://www.useanvil.com/docs/api/graphql/reference/) 用于完整文档.

## 使用量

这个库和Anvil API是打算用于服务器或类似服务器的环境. 它会在浏览器环境中失败.

要求节点20或更后.

```sh
yarn add @anvilco/anvil
```

它作为普通JS模块或ES模块工作,在JavaScript或TypeScript中:

```js
const Anvil = require('@anvilco/anvil')
// or
import Anvil from '@anvilco/anvil'
```

### 类型脚本

客户类型来自 [`@anvilco/types`](https://www.npmjs.com/package/@anvilco/types),它来自Anvil API的GraphQL schema和OpenAPI spec并安装在客户端中。 这个 `variables` 图QL方法及其有效载荷 `fillPDF` 财务报告和审定财务报表 `generatePDF` 从它们中键入,所以一个拼写错误或缺少的参数是一个编译错误。 对于您自己的询问以及API返回的种类,请使用它 `GraphQL` 名称空间 :

```ts
import type { GraphQL } from '@anvilco/types'

type Packet = GraphQL.Type<'EtchPacket'>
type PacketArgs = GraphQL.MutationArgs<'createEtchPacket'>
```

论点 `createEtchPacket` graphQL 计划只能调用 `JSON` 键入,并按名称导出以单独构建它们:

```ts
import type { EtchSigner } from '@anvilco/anvil'

const signer: EtchSigner = {
  id: 'signer1',
  name: 'Sally Signer',
  email: 'sally@example.com',
  signerType: 'embedded',
  fields: [{ fileId: 'lease', fieldId: 'signature1' }],
}
```

如果你通过自己的 `mutation` 至方法,其变量可能不同于API对该变异的参数;如果 TypeScript 对象,则将其投放.

```sh
npm install @anvilco/anvil
```

一个将 JSON 转换为已填充的 PDF 的基本实例, 然后将 PDF 保存为文件 :

```js
import fs from 'fs'
import Anvil from '@anvilco/anvil'

// The ID of the PDF template to fill
const pdfTemplateID = 'kA6Da9CuGqUtc6QiBDRR'
// Your API key from your Anvil organization settings
const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'

// JSON data to fill the PDF
const exampleData = {
  "title": "My PDF Title",
  "fontSize": 10,
  "textColor": "#CC0000",
  "data": {
    "someFieldId": "Hello World!"
  }
}
const anvilClient = new Anvil({ apiKey })
const { statusCode, data } = await anvilClient.fillPDF(pdfTemplateID, exampleData)

// By default, if the PDF has been published then the published version is what will
// be filled. If the PDF has not been published, then the most recent version will
// be filled. 
// 
// However, a version number can also be passed in that will be used retrieve and
// fill a specific version of the PDF.
// You can also use the constant `Anvil.VERSION_LATEST` (or `-1`) to fill the most 
// recent version of your PDF, whether that version has been published or not.
// Use this if you'd like to fill out a draft version of your template/PDF.
const options = { versionNumber: Anvil.VERSION_LATEST }
const { statusCode, data } = await anvilClient.fillPDF(pdfTemplateID, exampleData, options)

console.log(statusCode) // => 200

// Data will be the filled PDF raw bytes
fs.writeFileSync('output.pdf', data, { encoding: null })
```

## API 密码

-   [构造器](https://npmcn.com/package/%40anvilco/anvil/#readme-new-anviloptions)
-   [fillPDF(pdf TemplateID, 有效载荷\[, 选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-fillpdfpdftemplateid-payload-options)
-   [生成PDF( 负载\[, 选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-generatepdfpayload-options)
-   [创建 EtchPacket( 选项)](https://npmcn.com/package/%40anvilco/anvil/#readme-createetchpacketoptions)
-   [获取 EtchPacket( 选项)](https://npmcn.com/package/%40anvilco/anvil/#readme-getetchpacketoptions)
-   [生成 Etch SignUrl( 选项)](https://npmcn.com/package/%40anvilco/anvil/#readme-generateetchsignurloptions)
-   [下载文件( 文档GroupEid \[, 选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-downloaddocumentsdocumentgroupeid-options)
-   [伪造提交( 选项)](https://npmcn.com/package/%40anvilco/anvil/#readme-forgesubmitoptions)
-   [删除WeldData( 选项)](https://npmcn.com/package/%40anvilco/anvil/#readme-removewelddataoptions)
-   [请求GraphQL( queryInfo\[, 选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-requestgraphqlqueryinfo-options)
-   [requestREST( url, 获取选项\[, 客户端选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-requestresturl-fetchoptions-clientoptions)
-   [准备 GraphQLFile( path OrStream like Thing \[, 选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-preparegraphqlfilepathorstreamlikething-options)
-   [选项](https://npmcn.com/package/%40anvilco/anvil/#readme-options),包括: [认证](https://npmcn.com/package/%40anvilco/anvil/#readme-authentication) 财务报告和审定财务报表 [基础URL](https://npmcn.com/package/%40anvilco/anvil/#readme-baseurl)
-   [常数](https://npmcn.com/package/%40anvilco/anvil/#readme-constants)
-   [错误](https://npmcn.com/package/%40anvilco/anvil/#readme-errors)

#### 方法名称

每一种名称有缩写的方法,也都可以用平地骆驼案的缩写来称呼,反之亦然. 使用您喜欢的任意一种方法;它们都是相同的方法.

|  |  |
| --- | --- |
| `fillPDF` | `fillPdf` |
| `generatePDF` | `generatePdf` |
| `generateEtchSignUrl` | `generateEtchSignURL` |
| `requestGraphQL` | `requestGraphql` 或者说 `requestGraphQl` |
| `requestREST` | `requestRest` |
| `prepareGraphQLFile` | `prepareGraphqlFile` 或者说 `prepareGraphQlFile` |

这个 `baseURL` 选项也被接受为 `baseUrl`。 。 。 .

### 实例方法

##### 新安维尔( 选项)

创建 Anvil 客户端实例 .

-   `options` (目标) - [选项](https://npmcn.com/package/%40anvilco/anvil/#readme-options) 以Anvil客户为例.

```js
const anvilClient = new Anvil({ apiKey: 'abc123' })
```

  

##### fillPDF(pdf TemplateID, 有效载荷\[, 选项\])

以 JSON 数据填入 PDF 模板.

首先,你需要拥有 [上传到 Anvil 的 PDF](https://useanvil.com/docs/api/fill-pdf#creating-a-pdf-template)您可以在 PDF 模板的页面上找到 PDF 模板的ID :

![PDF Template ID](https://npmcn.com/package/%40anvilco/anvil/images/pdf-template-id.png)

如果您已经拥有安维尔页面的URL, ID也在那里 : `https://app.useanvil.com/org/<your-org-slug>/pdf/<pdf-template-id>`

一个例子是:

```js
const fs = require('fs')

// PDF template you uploaded to Anvil
const pdfTemplateID = 'kA6Da9CuGqUtc6QiBDRR'

// Your API key from your Anvil organization settings
const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'

// JSON data to fill the PDF
const payload = {
  "title": "My PDF Title",
  "fontSize": 10,
  "textColor": "#CC0000",
  "data": {
    "someFieldId": "Hello World!"
  }
}
// The 'options' parameter is optional
const options = {
  "dataType": "buffer"
}
const anvilClient = new Anvil({ apiKey })
const { statusCode, data } = await anvilClient.fillPDF(pdfTemplateID, payload, options)

// Be sure to write the file as raw bytes
fs.writeFileSync('filled.pdf', data, { encoding: null })
```

-   `pdfTemplateID` (String) - 来自Anvil UI的您 PDF 模板的ID
-   `payload` (Object) - 将填充PDF模板的JSON数据
    -   `title` (叫声) - _选项_ 设定编码为 PDF 文档的标题
    -   `fontSize` (数目) - _选项_ 设置所有已填入文本的字体大小 。 默认为10.
    -   `color` (叫声) - _选项_ 设置所有已填入文本的文本颜色 。 默认为深蓝色.
    -   `data` (Object) - 填充PDF的数据. 此对象中的密钥将对应 PDF 中的字段ID 。 这些字段ID及其类型可以在Anvil仪表板上的PDF模板页面上找到.
        -   举个例子 `{ "someFieldId": "Hello World!" }`
-   `options` (目标) - _选项_ 请求的任何其他备选方案
    -   `dataType` (Enum\[标\]- _选项_ 设置类型 `data` 已解决时返回的值 `Promise`默认为 `'buffer'`不过 `'arrayBuffer'` 财务报告和审定财务报表 `'stream'` 也得到支持.
    -   `versionNumber` (数目) - _选项_ 要填充的PDF模板版本. 默认为最近发布的版本,或者模板从未发布的最新版本. 见 [常数](https://npmcn.com/package/%40anvilco/anvil/#readme-constants)。 。 。 .
    -   `throwOnError` (布鲁伦) - _选项_ 覆盖客户端 [`throwOnError`](https://npmcn.com/package/%40anvilco/anvil/#readme-throwonerror) 为此请求.
-   回返a `Promise` 决心 `Object`
    -   `statusCode` (数目) - HTTP状态代码; `200` 是成功的
    -   `data` (Buffer QQ ArrayBuffer QQ Stream) - 已填充的PDF的原始二进制数据如果成功的话. 要么是一个缓冲器, 缓冲器, 要么是一个流,取决于 `dataType` 选项.
    -   `errors` (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
        -   `message` (叫声)

##### 生成PDF( 负载\[, 选项\])

从您的 HTML 和 CSS 或标记下动态生成一个新的 PDF .

可用于协议、发票、披露或任何其他文本重的文件。 这不需要您在Anvil UI中做任何事情,除了设置您的 API 密钥, 只要发送数据, 得到一个 PDF 。 见 [生成 PDF 文档](https://useanvil.com/api/generate-pdf) 详细情况.

-   [HTML 到 PDF 文档](https://www.useanvil.com/docs/api/generate-pdf#html--css-to-pdf)
-   [标记到 PDF 文件](https://www.useanvil.com/docs/api/generate-pdf#markdown-to-pdf)

看看我们 [HTML 发票模板](https://github.com/anvilco/html-pdf-invoice-template) 用于完整 HTML 到 PDF 示例.

一个例子是:

```js
const fs = require('fs')

// Your API key from your Anvil organization settings
const apiKey = '7j2JuUWmN4fGjBxsCltWaybHOEy3UEtt'

// An example using an HTML to PDF payload
const payload = {
  title: 'Example',
  type: 'html',
  data: {
    html: `
      <h1 class='header-one'>What is Lorem Ipsum?</h1>
      <p>
        Lorem Ipsum is simply dummy text...
      </p>
      <h3 class='header-two'>Where does it come from?</h3>
      <p>
        Contrary to popular belief, Lorem Ipsum is not simply <i>random text</i>
      </p>
    `,
    css: `
      body { font-size: 14px; color: #171717; }
      .header-one { text-decoration: underline; }
      .header-two { font-style: underline; }
    `,
  },
}

// An example using a Markdown payload
const payload = {
  title: 'Example Invoice',
  data: [{
    label: 'Name',
    content: 'Sally Jones',
  }, {
    content: 'Lorem **ipsum** dolor sit _amet_',
  }, {
    table: {
      firstRowHeaders: true,
      rows: [
        ['Description', 'Quantity', 'Price'],
        ['4x Large Widgets', '4', '$40.00'],
        ['10x Medium Sized Widgets in dark blue', '10', '$100.00'],
        ['10x Small Widgets in white', '6', '$60.00'],
      ],
    },
  }],
}
// The 'options' parameter is optional
const options = {
  "dataType": "buffer"
}
const anvilClient = new Anvil({ apiKey })
const { statusCode, data } = await anvilClient.generatePDF(payload, options)

// Be sure to write the file as raw bytes
fs.writeFileSync('generated.pdf', data, { encoding: null })
```

-   `payload` (Object) - 将填充PDF模板的JSON数据
    -   `title` (叫声) - _选项_ 设定编码为 PDF 文档的标题
    -   `data` (Array of Objects) - 生成PDF的数据. 见 [文档](https://useanvil.com/docs/api/generate-pdf#supported-format-of-data) 用于所有被支持的对象
        -   举个例子 `[{ "label": "Hello World!", "content": "Test" }]`
-   `options` (目标) - _选项_ 请求的任何其他备选方案
    -   `dataType` (Enum\[标\]- _选项_ 设置类型 `data` 已解决时返回的值 `Promise`默认为 `'buffer'`不过 `'arrayBuffer'` 财务报告和审定财务报表 `'stream'` 也得到支持.
    -   `throwOnError` (布鲁伦) - _选项_ 覆盖客户端 [`throwOnError`](https://npmcn.com/package/%40anvilco/anvil/#readme-throwonerror) 为此请求.
-   回返a `Promise` 决心 `Object`
    -   `statusCode` (数目) - HTTP状态代码; `200` 是成功的
    -   `data` (Buffer QQ ArrayBuffer QQ Stream) - 已填充的PDF的原始二进制数据如果成功的话. 要么是一个缓冲器, 缓冲器, 要么是一个流,取决于 `dataType` 选项.
    -   `errors` (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
        -   `message` (叫声)

##### 创建 EtchPacket( 选项)

创建 Etch 包并选择将其发送给第一个签名者.

```js
const anvilClient = new Anvil({ apiKey })

const { statusCode, data, errors } = await anvilClient.createEtchPacket({
  variables: {
    name: 'Example packet',
    // Test packets use development signatures and are not billed
    isTest: true,
    // Send it to the first signer right away
    isDraft: false,
    files: [{
      id: 'uploadedNDA',
      title: 'Demo NDA',
      file: Anvil.prepareGraphQLFile('./nda.pdf'),
      fields: [{
        id: 'signatureOne',
        type: 'signature',
        pageNum: 0,
        rect: { x: 100, y: 100, width: 150, height: 30 },
      }],
    }],
    signers: [{
      id: 'signerOne',
      name: 'Sally Signer',
      email: 'sally@example.com',
      // 'embedded' signers sign in your app with a URL from generateEtchSignUrl.
      // The default, 'email', sends them an email.
      signerType: 'embedded',
      fields: [{ fileId: 'uploadedNDA', fieldId: 'signatureOne' }],
    }],
  },
})

const etchPacket = data.data.createEtchPacket
const signerEid = etchPacket.documentGroup.signers[0].eid
```

-   `options` (object) - 有下列结构的物体:
    -   `variables` (目标) [API 文档](https://npmcn.com/package/%40anvilco/anvil/#readme-api-documentation) 区域。 见 [实例](https://npmcn.com/package/%40anvilco/anvil/#readme-examples) 区域.
    -   `responseQuery` (叫声) - _选项_ 一个 GraphQL 符合要求的查询, 用于突变响应中想要的数据 。 可忽略使用默认值 .
    -   `mutation` (叫声) - _选项_ 如果您想要完全控制 GraphQL 突变, 您可以通过一个 GraphQL 突变符合字符串, 用于突变调用 。 此字符串还应包括您的响应查询, 如 `responseQuery` 如果 `mutation` 通过。 示例
        
        ```graphql
          mutation CreateEtchPacket (
            $name: String,
            ...
          ) {
            createEtchPacket (
              name: $name,
              ...
            ) {
              id
              eid
              ...
            }
          }
        ```
        

##### 获取 EtchPacket( 选项)

得到一个小包的细节.

```js
const { statusCode, data, errors } = await anvilClient.getEtchPacket({
  variables: { eid: etchPacketEid },
})
const { status, documentGroup } = data.data.etchPacket
```

-   `options` (object) - 有下列结构的物体:
    -   `variables` (目标) - 要求 `eid`
        -   `eid` (String) - 您的 Etch 包装 eid
    -   `responseQuery` (叫声) - _选项_ 一个 GraphQL 查询符合要求的查询,用于查询答复中想要的数据 。 可忽略使用默认值 .

##### 生成 Etch SignUrl( 选项)

为 Etch Packet 签名程序创建 Etch 标志 URL 。 Etch Packet 及其签名人必须已经创建,数据包必须已经发送,签名人必须是 `embedded` 签名者.

```js
const { statusCode, url, errors } = await anvilClient.generateEtchSignUrl({
  variables: {
    signerEid,
    // Your ID for the user who will be signing
    clientUserId: 'user-123',
  },
})
// Send your user to `url` to sign
```

-   `options` (object) - 有下列结构的物体:
    -   `variables` (目标) - 要求 `clientUserId` 财务报告和审定财务报表 `signerEid`
        -   `clientUserId` (String) - 您将签名的用户的ID
        -   `signerEid` (String) - Etch Packet 签名器的eid,在反应中发现 `createEtchPacket` 实例方法
-   回返a `Promise` 决心 `Object`
    -   `statusCode` (数目) - HTTP状态代码; `200` 是成功的
    -   `url` (String) - 签名的 URL
    -   `errors` (Array of Objects) - 如果有问题将会出现. 见 [错误](https://npmcn.com/package/%40anvilco/anvil/#readme-errors)

##### 下载文件( 文档GroupEid \[, 选项\])

返回 Zip 文件格式中文档GroupEid 指定的文档组的缓冲、矩阵缓冲或流.

```js
const { statusCode, data, errors } = await anvilClient.downloadDocuments(documentGroupEid)
fs.writeFileSync('documents.zip', data, { encoding: null })

// Or stream it
const { data: stream } = await anvilClient.downloadDocuments(documentGroupEid, { dataType: 'stream' })
stream.pipe(fs.createWriteStream('documents.zip'))
```

-   `documentGroupEid` (字符串) - 要下载的文档组的 eid
-   `options` (目标) - _选项_ 请求的任何其他备选方案
    -   `dataType` (Enum\[标\]- _选项_ 设置类型 `data` 已解决时返回的值 `Promise`默认为 `'buffer'`不过 `'arrayBuffer'` 财务报告和审定财务报表 `'stream'` 也得到支持.
    -   `throwOnError` (布鲁伦) - _选项_ 覆盖客户端 [`throwOnError`](https://npmcn.com/package/%40anvilco/anvil/#readme-throwonerror) 为此请求.
-   回返a `Promise` 决心 `Object`
    -   `statusCode` (数量) - HTTP 状态代码, `200` 是成功的
    -   `response` (object) - 由客户端向Anvil app请求而产生的响应对象
    -   `data` (Buffer QQ ArrayBuffer QQ Stream) - 如果成功,则下载文件的原始二进制数据. 将采用缓冲、缓冲或流等形式,取决于 `dataType` 选项.
    -   `errors` (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
        -   `message` (叫声)

##### 伪造提交( 选项)

在 Workflow 中创建或更新对 Webform 的提交,与填写和提交 Webform 的人相同。 Webform在API中被称作"福格斯".

```js
const { statusCode, data, errors } = await anvilClient.forgeSubmit({
  variables: {
    // The webform's eid
    forgeEid: 'your-forge-eid',
    // Keys are the IDs of the webform's fields
    payload: {
      name: 'Sally Jones',
      email: 'sally@example.com',
    },
    isTest: true,
  },
})
const submission = data.data.forgeSubmit
const weldDataEid = submission.weldData.eid
```

-   `options` (object) - 有下列结构的物体:
    -   `variables` (目标) - 要求 `forgeEid` 财务报告和审定财务报表 `payload`。通过 `weldDataEid` 财务报告和审定财务报表 `submissionEid` 更新现有呈件。 见 [参考图表QL](https://www.useanvil.com/docs/api/graphql/reference/) 用于所有变量.
    -   `responseQuery` (叫声) - _选项_ 一个 GraphQL 符合要求的查询, 用于突变响应中想要的数据 。 可忽略使用默认值 .
    -   `mutation` (叫声) - _选项_ 你自己的完整的GraphQL突变. `responseQuery` 如果通过,则忽略.
-   回返a `Promise` 决心 `Object` 与 `statusCode`, (中文(简体) ), `data` 财务报告和审定财务报表 `errors`一样 [请求GraphQL](https://npmcn.com/package/%40anvilco/anvil/#readme-requestgraphqlqueryinfo-options)

##### 删除WeldData( 选项)

删除工作流程呈件(a) `WeldData`还有里面的一切.

```js
const { statusCode, data, errors } = await anvilClient.removeWeldData({
  variables: { eid: weldDataEid },
})
const removed = data.data.removeWeldData // true
```

-   `options` (object) - 有下列结构的物体:
    -   `variables` (目标) - 要求 `eid`
        -   `eid` (String) - 要删除的 WeldData 的 eid
    -   `mutation` (叫声) - _选项_ 你自己的完整的GraphQL突变.
-   回返a `Promise` 决心 `Object` 与 `statusCode`, (中文(简体) ), `data` 财务报告和审定财务报表 `errors`一样 [请求GraphQL](https://npmcn.com/package/%40anvilco/anvil/#readme-requestgraphqlqueryinfo-options)

##### 请求GraphQL( queryInfo\[, 选项\])

对于查询和突变的倒置功能,在此客户端中没有专门的功能.

见 [参考图表QL](https://www.useanvil.com/docs/api/graphql/reference/) 关于所有可能查询的清单

```js
const result = await client.requestGraphQL({
  query: `
    query WeldDataQuery ($eid: String!) {
      weldData (eid: $eid) {
        eid
        isComplete
        isTest
      }
    }
  `,
  variables: { eid: 'nxflNZqxDUbltLUbYWK' },
})
const { statusCode, data, errors } = result

if (errors) {
  // GraphQL errors (with a 200 statusCode) or HTTP errors. See Errors.
} else {
  const weldData = data.data.weldData
}
```

-   `queryInfo` (目标)
    -   `query` (String) - GraphQL 查询或突变来运行. 见 [参考图表QL](https://www.useanvil.com/docs/api/graphql/reference/) 关于所有可能查询的清单
    -   `variables` (Object) - 用于查询的图形QL变量。 要上传的文件可以在这里的任何地方;参见 [准备 GraphQLFile](https://npmcn.com/package/%40anvilco/anvil/#readme-preparegraphqlfilepathorstreamlikething-options)。 。 。 .
-   `options` (目标) - _选项_ 请求的任何其他备选方案
    -   `throwOnError` (布鲁伦) - _选项_ 覆盖客户端 [`throwOnError`](https://npmcn.com/package/%40anvilco/anvil/#readme-throwonerror) 为此请求.
-   回返a `Promise` 决心 `Object`
    -   `statusCode` (数字) - HTTP状态代码. 图QL 错误带回 `200`;只有当请求本身有问题时,例如,它有错误或未经授权,您才会看到其他代码.
    -   `data` (对象) - 无出错时显示
        -   `data` (对象) - 包含查询的实际结果
            -   `[queryName]` (Object) - 使用查询或突变名称来引用您要求的数据!
    -   `errors` (Array of Objects) - 当出现 GraphQL 或 HTTP 错误时显示 。 见 [错误](https://npmcn.com/package/%40anvilco/anvil/#readme-errors)

##### requestREST( url, 获取选项\[, 客户端选项\])

REST端点的倒置函数,在此客户端中没有专门的函数.

见 [参考图表QL](https://www.useanvil.com/docs/api/graphql/reference/) 关于所有可能查询的清单

```js
const result = await this.requestREST(
  `/api/v1/fill/${pdfTemplateID}.pdf`,
  {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: {
      'Content-Type': 'application/json',
    },
  },
  {
    dataType: 'stream',
  },
)
```

-   `url` (String) - 从基站URL的URL. 譬如说. `/api/v1/fill`
-   `fetchOptions` (对象) - 转到 [获取](https://undici.nodejs.org/#/docs/api/Fetch)。客户端使用 [未编辑](https://github.com/nodejs/undici)是因为 `fetch`。 。 。 .
-   `clientOptions` (目标) - _选项_ 请求的任何其他备选方案
    -   `dataType` (Enum\[标\]- _选项_ 设置类型 `data` 已解决时返回的值 `Promise`默认为 `'buffer'`, (中文(简体) ), `'arrayBuffer'`, (中文(简体) ), `'stream'`,以及 `'json'` 也得到支持.
    -   `throwOnError` (布鲁伦) - _选项_ 覆盖客户端 [`throwOnError`](https://npmcn.com/package/%40anvilco/anvil/#readme-throwonerror) 为此请求.
-   回返a `Promise` 决心 `Object`
    -   `statusCode` (数目) - HTTP状态代码; `200` 是成功的
    -   `data` (Buffer QQ ArrayBuffer QQ Stream) - 已填充的PDF的原始二进制数据如果成功的话. 要么是一个缓冲器, 缓冲器, 要么是一个流,取决于 `dataType` 选项.
    -   `errors` (天体阵列) - 如果状态为 QQ 400, 将会存在 。 参见错误
        -   `message` (叫声)

### 分类方法

-   [准备 GraphQLFile( path OrStream like Thing \[, 选项\])](https://npmcn.com/package/%40anvilco/anvil/#readme-preparegraphqlfilepathorstreamlikething-options)

##### 准备 GraphQLFile( path OrStream like Thing \[, 选项\])

一个很好的助手来准备 [文件](https://developer.mozilla.org/en-US/docs/Web/API/File) 上传并使用 GraphQL API 。 默认情况下, 这将以多段上传方式上传您的文件 [jaidenseric / GraphQL 多部分请求光谱](https://github.com/jaydenseric/graphql-multipart-request-spec)。作为路径或流提供的文件会被流到API,而不是首先被读入内存。 如果一项请求必须重新审理(见 [费率限制](https://npmcn.com/package/%40anvilco/anvil/#readme-rate-limits)),作为路径、文件流或 `Buffer` 被再次发送; 任何其他流只能被读取一次, 所以重试失败时会出现错误 。 注:请见下文某些可能需要手动提供 `filename`。 。 。 .

-   `pathOrSupportedInstance` (String QQ File Blob QQ Stream QQ BUFER) - 可以是几种事物之一. 下面列出所支持的,按偏好顺序排列:
    1.  A 类 `File` 举个例子.
    2.  A 类 `Blob` 举个例子.
    3.  A 类 `string` 这是要使用的文件的路径.
    4.  A 类 `ReadStream` 或
        1.  A 类 `path` 属性( 通常在从本地文件系统中装入流时会出现)
        2.  A 类 `filename` b. 《公约》 `options` 参数.
    5.  A 类 `Buffer` 实例 `filename` b. 《公约》 `options` 参数.
-   `options` (Object) - 在提供某些类型的值作为第一个参数时可能需要的选项. 譬如说, `Blob`s, (中文(简体) ), `Buffer`和某些类型的 `ReadStream`s 上传时不会知道文件名称或名称.
    -   `filename` (String) - 覆盖上传文件的文件名 。 如果提供通用的 ReadStream 或缓冲, 您需要在此提供文件名
    -   `mimetype` (String) - 可选的 mime 类型, 以指定可使用的文件 `string` 路径, `Buffer` 或者说 `ReadStream` 作为第一个参数提供.
-   返回 a `Object` 被客户端强制使用,以对抗我们的GraphQL API `Upload` 需要类型.

### 选项

Anvil客户端的选项. 每个选项密钥后显示默认值 .

```js
{
  // One of apiKey or accessToken is required. See Authentication.
  apiKey: <your_api_key>,
  accessToken: <oauth_access_token>,

  // Where to send requests. See baseURL. Also accepted as baseUrl.
  baseURL: 'https://app.useanvil.com',

  // Sent as the User-Agent header
  userAgent: 'Anvil API Client/<version>',

  // How many requests to allow per requestLimitMS until the first response from
  // the API tells the client your actual limits. See Rate Limits.
  requestLimit: 1,
  requestLimitMS: 1000,

  // An undici Dispatcher to send requests with, e.g. to use a proxy:
  // new ProxyAgent('http://proxy.example.com:8080'). Defaults to the client's own Agent.
  dispatcher: <undici_dispatcher>,

  // Reject with an AnvilRequestError when the API responds with an error, rather
  // than resolve with `errors`. See throwOnError.
  throwOnError: false,
}
```

##### 认证

使用 API 密钥或 OAuth 访问令牌认证 .

**API 密钥 :** 在您的 Anvil 组织设置中查找您的 API 密钥 。 请求使用 HTTP 基本认证 : `Basic base64(apiKey + ':')`。 。 。 .

```js
const anvilClient = new Anvil({ apiKey: 'your-api-key' })
```

**OAuth 访问令牌 :** 请求使用 Bearer 认证 。 Anvil的进入标志是JWT,它们作为-is发送: `Bearer <accessToken>`。任何其他种类的代号为 Base64 编码: `Bearer base64(accessToken)`。 。 。 .

```js
const anvilClient = new Anvil({ accessToken: 'your-oauth-access-token' })
```

如果你通过两者 `accessToken` 已使用.

##### 基础URL

默认, 请求去生产, `https://app.useanvil.com`设置 `baseURL` 让他们去别的地方 所有请求都前往主机:

-   瑞丝: `{baseURL}/api/v1/...`
-   图QL : `{baseURL}/graphql`
-   文件下载: `{baseURL}/api/document-group/{eid}.zip`

```js
const anvilClient = new Anvil({
  apiKey: 'your-api-key',
  baseURL: 'https://anvil.example.com',
})
```

别包括尾部斜线.

### 常数

-   `Anvil.VERSION_LATEST` (单位:千美元)`-1`\- 与我们一起 `fillPDF`是因为 `versionNumber` 选项,填写已发布或不发布的PDF模板的最新版本。 用来填稿.
-   `Anvil.VERSION_LATEST_PUBLISHED` (单位:千美元)`-2`) - 填充最新发布的版本. 与离开不同 `versionNumber` 中,如果模板从未发布,则返回错误.

### 错误

默认情况下,客户端的方法不会因为API对问题的反应而拒绝. 相反,他们以 `errors` 数组与 `statusCode`每个项目都有: `message`页:1 `name`或者两者兼有 让他们拒绝,你应当开口 [`throwOnError`](https://npmcn.com/package/%40anvilco/anvil/#readme-throwonerror)。 。 。 .

```js
const { statusCode, data, errors } = await anvilClient.fillPDF(pdfTemplateID, payload)
if (errors) {
  console.log(statusCode, errors)
}
```

`errors` 看起来像其中之一:

-   **图QL 错误**,如API返回的,经常带有 `200` `statusCode`数字 :
    
    ```js
    [{ message: 'Not Found', path: ['etchPacket'], locations: [{ line: 2, column: 3 }] }]
    ```
    
-   **一个 REST 错误 .** 校验错误没有 `message`,但列出每个问题字段:
    
    ```js
    [{ name: 'AssertionError', message: 'PDF did not generate properly from given HTML!' }]
    [{ name: 'ValidationError', status: 400, fields: [{ message: 'Required', property: 'data' }] }]
    ```
    
-   **一个不是JSON的反应**像一个 `502` 从代理。 这个 `name` 财务报告和审定财务报表 `message` 是 HTTP 状态文本 :
    
    ```js
    [{ name: 'Bad Gateway', message: 'Bad Gateway' }]
    ```
    
-   **无法解析的JSON反应.** 这是解析错误的 `name`, (中文(简体) ), `message`, (中文(简体) ), `code`, (中文(简体) ), `cause` 财务报告和审定财务报表 `stack`数字 :
    
    ```js
    [{ name: 'SyntaxError', message: 'Unexpected end of JSON input', stack: '...' }]
    ```
    

当一个请求完全无法提出时,例如由于网络出错,这些方法确实拒绝了. 这些是 `fetch` 错误,详情见 `cause`数字 :

```js
try {
  await anvilClient.fillPDF(pdfTemplateID, payload)
} catch (error) {
  console.log(error.message) // 'fetch failed'
  console.log(error.cause.code) // e.g. 'ECONNREFUSED'
}
```

如果连接在全响应到达之前关闭,则返回二进制数据的方法(如 `fillPDF` 或者说 `downloadDocuments`拒绝方式 `TypeError: terminated`。返回 JSON 的答案是 `errors: [{ name: 'TypeError', message: 'terminated' }]`。 。 。 .

它们也会为无效的参数投出, 就像一个不支持的参数 `dataType`。 。 。 .

##### 抛出错误

过 `throwOnError: true` 和拒绝的方法 `AnvilRequestError` 只要他们能解决 `errors`那边 `try`编号 :`catch` 处理各种故障。 默认关闭;随着关闭,方法行为如上.

```js
const Anvil = require('@anvilco/anvil')
const { AnvilRequestError } = Anvil
// Or: import Anvil, { AnvilRequestError } from '@anvilco/anvil'

const anvilClient = new Anvil({ apiKey, throwOnError: true })

try {
  const { data } = await anvilClient.fillPDF(pdfTemplateID, payload)
  fs.writeFileSync('filled.pdf', data, { encoding: null })
} catch (error) {
  if (error instanceof AnvilRequestError) {
    console.log(error.message) // e.g. '400: ValidationError (data: Required)'
    console.log(error.statusCode, error.errors)
  } else {
    throw error // e.g. 'fetch failed'
  }
}
```

成功的请求解决 就像它与 `throwOnError` 关闭.

`fillPDF`, (中文(简体) ), `generatePDF`, (中文(简体) ), `downloadDocuments`, (中文(简体) ), `requestGraphQL` 财务报告和审定财务报表 `requestREST` 还接受 `throwOnError` 在他们的选项中,要覆盖客户端对一个请求的设置:

```js
const { statusCode, errors } = await anvilClient.fillPDF(pdfTemplateID, payload, { throwOnError: false })
```

一个 `AnvilRequestError` 拥有:

-   `name` (叫声) - `'AnvilRequestError'`
-   `message` (String) - 状态代码,然后每个错误的 `name` 财务报告和审定财务报表 `message`字段,由 `'; '`。例如, `'400: ValidationError (data: Required)'` 或者说 `'200: Not Found; Forbidden'`。 。 。 .
-   `statusCode` (数字) - HTTP状态代码. 图QL 错误通常带一个 `200`。 。 。 .
-   `errors` (物体阵列) - `errors` 这种方法会解决的 见上.
-   `data` (Object) - API在错误同时返回的任何数据, 否则 `undefined`。一个 GraphQL 请求可以部分成功;这是 GraphQL 响应 `data`,因此查询的结果是: `error.data.etchPacket`没有 `data.data.etchPacket` 就像当一个请求成功.
-   `response` (回复) - 获取 `Response`,例如: [费率限制](https://npmcn.com/package/%40anvilco/anvil/#readme-rate-limits) 头. 其体相已已诵.

所有拒绝的东西 `throwOnError` 关闭仍然以同样的方式拒绝它: 网络错误,一个二进制响应被切短(`TypeError: terminated`),和无效参数。 JSON的答复被缩短,这将解决 `errors: [{ name: 'TypeError', message: 'terminated' }]`,以 `AnvilRequestError`A级 `429` 仍然被重审,而不是扔.

### 费率限制

我们的API已经设置了要求的费率限制. 此客户端最初提出的要求将会从 `X-RateLimit-Limit` 财务报告和审定财务报表 `X-RateLimit-Interval-Ms` 响应头,然后自动处理随后对您的请求的节奏。 在等待第一次答复时提出的任何请求,将在发出之前等待.

和 API 一样, 客户端通过滑动窗口计算请求: 它只在 `X-RateLimit-Limit` 请求已在最后 `X-RateLimit-Interval-Ms`。 。 。 .

如果这个客户仍然收到 `429 Too Many Requests` 错误响应,它将等待在 `Retry-After` 头,外加50ms,然后重试请求.

见 [Anvil API 文件](https://www.useanvil.com/docs/api/getting-started/#rate-limits) 关于费率限额的具体细节的更多信息.

## API 文档

我们的普通 API 文档可以找到 [这里](https://www.useanvil.com/api/). 它是有关我们API及其能力的最新信息的最佳资源.

见 [PDF 填补 API 文档](https://useanvil.com/docs/api/fill-pdf) 欲了解更多关于 `fillPDF` 方法.

## 实例

这个 [实例](https://github.com/anvilco/node-anvil/tree/main/examples) 文件夹在 JavaScript 和 TypeScript 有完整,可操作的例子: 填充 PDF , 从 Markdown 或 HTML 生成 PDF , 用模板或上传的 PDF 电子签名, 用签名文件下载后嵌入签名.

## 发展

见 [捐款额](https://npmcn.com/package/%40anvilco/anvil/CONTRIBUTING.md) 如何运行测试 并发布一个发布.

## 常见问题

### @anvilco/anvil 是什么？

Anvil API 客户端

### 如何安装 @anvilco/anvil？

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

### @anvilco/anvil 支持 TypeScript 吗？

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

### @anvilco/anvil 支持 ESM 还是 CommonJS？

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

### @anvilco/anvil 需要什么版本的 Node\.js？

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

### @anvilco/anvil 可以商用吗？

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

### @anvilco/anvil 的下载量有多少？

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

### @anvilco/anvil 还在维护吗？

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

