# @growstack/sdk 中文文档

规范地址：https://npmcn.com/package/%40growstack/sdk/

版本：0\.4\.0
npm 元数据更新时间：2026-11-01T03:21:17.220Z
中文译文更新时间：2026-11-01T07:39:26.627Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：4.4 MB，26 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20
- 运行依赖：0 个
- 首次发布：2026-10-20T07:44:54.061Z
- 最新版本发布：2026-11-01T03:21:17.073Z
- 已发布版本数：5（近 12 个月 5 个）

## 中文简介

用于Growstack公共API的类型化、重试安全的客户端

## 安装

```sh
npm install @growstack/sdk
```

也可以使用：`pnpm add @growstack/sdk`、`yarn add @growstack/sdk`、`bun add @growstack/sdk`

## README

# @growstack / sdk

整个Growstack公共API的类型化客户端。MIT授权，ESM带有TypeScript声明，使用global `fetch` 在Node 20+， Bun， Vercel和edge运行时。

```sh
npm install @growstack/sdk
```

```ts
import { createGrowstack, GrowstackError } from '@growstack/sdk'

const growstack = createGrowstack({ apiKey: process.env.GROWSTACK_API_KEY! })
// For self-hosting: createGrowstack({ apiKey, baseUrl: 'https://marketing.example.com' })
```

每个实例都有自己的键、基URL和可选 `fetch(request)` 实现。在服务器上使用密钥。公钥只属于工作区跟踪策略所允许的浏览器操作。

在已登录的浏览器中，省略 `apiKey` 并使用应用程序的起源。SDK发送no 授权头并通过Fetch保存cookie `credentials` 选项, 默认为 `same-origin`． 集 `credentials: 'include'` 当你部署的时候 允许来自其他来源的cookie认证请求。

```ts
const personal = createGrowstack({ baseUrl: window.location.origin })
const accounts = await personal.connections.list()
```

连接和成员连接摘要需要会话。API密钥不能 访问它们。

## 发送事务性消息

需要 `messages:send`密钥上的授权发送方，以及经过验证的发送方域。这个 `message` 键是工作区发布的Simple消息模板。其他发布的模板键也以同样的方式工作。

```ts
const sent = await growstack.messages.create({
  body: {
    to: 'ana@example.com',
    from: { address: 'hello@mail.example.com' },
    purpose: 'transactional',
    template: {
      key: 'message',
      variables: { subject: 'Your receipt', body: 'Thank you for your order.' },
    },
  },
}, { idempotencyKey: 'order:example-42:receipt' })
console.log(sent.id)
```

## 插入联系人

需要 `people:write`． 电子邮件或外部标识符查找或创建现有联系人。省略的字段保持不变；相互冲突的身份永远不会悄然合并。

```ts
const { person, created } = await growstack.people.upsert({
  body: {
    identifier: { email: 'ana@example.com' },
    name: 'Ana',
    country: 'ES',
    source: 'shop',
  },
})
```

## 同步产品帐户

需要 `people:write`． 品牌标识符和不可变账户标识符标识 帐户。使用一个计数器或时间戳保持其源版本增加 种类。相等或更旧的版本返回 `ignored: true` 并保持所有数据完整。

```ts
const { account, ignored } = await growstack.productAccounts.upsert({
  path: { brand: 'heralded', externalId: 'workspace-42' },
  body: {
    revision: 5,
    name: 'Example workspace',
    status: 'paying',
    plan: 'Growth',
    currency: 'EUR',
    mrr: '79.00',
    users: [{ identifier: { email: 'ana@example.com' }, role: 'owner' }],
  },
})
```

省略的字段保持不变。提供的用户替换成员。用户接受 contact-upsert标识符;外部标识符可以包括电子邮件。 冲突的用户保持未链接和 `needsReview` 是真的。回顾明确 与 `productAccountUsers.review`,选择 `link` 或者 `keep_apart`. 后者保留了产品标识，而不附加冲突的电子邮件。

## 属性和字段历史

`properties` 管理的定义 `contact`， `company`， `deal`， `lead` 和 `product_account`. `personProperties` 公开相同的联系人定义。 共享属性只有一个键和类型 `appliesTo` 对象。

```ts
const definitions = await growstack.properties.list({ path: { object: 'contact' } })
const plan = definitions.data.find(property => property.key === 'plan')
const growth = plan?.optionDefinitions?.find(option => option.label === 'Growth')
const contact = await growstack.people.get({ path: { id: person.id } })
console.log(contact.attributes.plan) // Current label, such as 'Growth'
console.log(contact.attributeOptions?.plan) // { id: '<option UUID>', label: 'Growth' }
```

选择写入接受标签或选项id in `attributes`． 多选 接受一个有序的标签或id数组。读取保存标签 `attributes` 和公开 `{id, label}` 值 `attributeOptions`，为a使用数组 按其存储顺序多选。不匹配的值保持写入和 省略了 `attributeOptions`； `invalidProperties` 命名他们的字段。 重命名选项将保留其id，并将保存的引用解析为旧的 标签。 `optionDefinitions` 按id更新选项，并可以存档或合并它们。

`peopleChanges.list` 和 `companiesChanges.list` 返回字段随 他们的新旧价值观，演员和时间。重写相同的值会产生no 改变。租户导出包括定义和历史记录。

## 请求双重选择订阅

需要 `consent:write`． 创建具有双重选择的主题，或使用以这种方式配置的现有主题。

```ts
await growstack.topics.create({
  body: { key: 'product-updates', name: 'Product updates', doubleOptIn: true },
})
await growstack.subscriptions.create({
  body: { address: 'ana@example.com', topic: 'product-updates', source: 'shop' },
})
```

这将创建一个挂起的订阅。收件人通过电子邮件托管链接确认；SDK本身从不确认用户的同意。同意证据字段 `details` 和 `occurredAt` 需要一个密钥。公钥和已登录会话无法提交它们。

## 跟踪事件

需要 `events:write` 在秘钥上。浏览器跟踪使用公钥及其工作区的事件允许列表。

```ts
await growstack.track({
  body: { event: 'order.completed', email: 'ana@example.com', data: { order: 'example-42' } },
}, { idempotencyKey: 'order:example-42:completed' })
```

## 上传品牌标志

需要 `brands:manage`． 传递PNG， JPEG或WebP `Blob` 或者 `File`，最高可达200kib； 它的MIME类型。客户端发送原始字节和内容类型。

```ts
await growstack.brandsLogo.update({
  path: { id: brand.id },
  body: new Blob([imageBytes], { type: 'image/webp' }),
})
```

## 打开客户计费页面

需要一个密钥 `billing:write`． 该公司必须是帐单客户 而且品牌必须指定给发行公司。客户不需要 发票;然后页面显示一个空列表。测试模式被拒绝。使用HTTPS 返回的URL。返回的链接在五分钟内工作一次；创建它时 客户选择打开账单。

```ts
const portal = await growstack.billingPortalSessions.create({
  body: {
    companyId: customer.companyId,
    brandId: brand.id,
    returnUrl: 'https://app.example.com/account',
    locale: 'en',
  },
})
// Redirect your customer to portal.url.
```

该页面支持英语和罗马尼亚语，显示发票和报价pdf，并接受 发票支付。它不能接受引号。12个空闲小时后结束访问 或者当它的颁发密钥被移除或丢失时 `billing:write`.

## 处理错误

```ts
try {
  await growstack.people.upsert({
    body: { identifier: { email: 'ana@example.com' }, source: 'shop' },
  })
} catch (error) {
  if (error instanceof GrowstackError) {
    console.error(error.status, error.type, error.code, error.message, error.requestId)
    // error.issues contains field paths and messages when supplied by the API.
  } else {
    throw error // Network failures and cancellation retain their original errors.
  }
}
```

API信封之外的错误响应（例如网关的HTML 502）抛出 `GrowstackError` HTTP状态， `type: 'internal'`， `code: 'unexpected_response'` 和 `requestId: null`.

## 呼叫、重试和取消

方法接受生成的 `{ path, query, body }` 输入后跟可选 `{ idempotencyKey, signal }`，并返回解码后的成功消息体。操作使用Growstack的显式操作映射中的资源和操作，例如 `growstack.campaigns.send` 和 `growstack.peopleEmailAddresses.list`. `growstack.raw` 公开每个操作id，例如 `raw.peopleUpsert` 和 `raw.trackCreate`，投入和运输方式相同。

每个POST都接收一个自动UUID等幂键，除非您提供一个。生成的密钥保护一次调用内的重试。在表示相同操作的不同调用之间传递您自己的稳定密钥，如收据示例中所示。API的重放窗口是24小时。

由于网络故障，get和键控post在第一次尝试后最多重试三次，分别是429、5xx和409 `idempotency_key_in_use`． 每次重试都会保留确切的密钥和主体。延迟使用全抖动over `min(8000, 500 × 2^retryIndex)` 毫秒，或更长的有效时间 `Retry-After` 以秒为单位或作为HTTP日期。其他4xx，其他409和取消呼叫永远不会重试。PUT、PATCH和DELETE永远不会重试。

```ts
const controller = new AbortController()
const result = growstack.people.list({ query: { limit: 100 } }, { signal: controller.signal })
// controller.abort() cancels the request or a retry delay.
await result
```

## 迭代记录页

每个返回记录页的操作都有 `.all(input, options)`，包括POST查询和嵌套列表。它每次产生一条记录，保留过滤器和父参数，并在 `hasMore` 是假的。

```ts
for await (const person of growstack.people.list.all({ query: { limit: 100 } })) {
  console.log(person.id)
}
for await (const row of growstack.people.query.all({
  body: { filter: { person: 'country', op: 'eq', value: 'ES' }, limit: 100 },
})) {
  console.log(row.person.id)
}
```

每个POST页都有自己的键，可用于该页的重试。如果迭代器接收到调用方键，则应用于第一页；后面的页面生成新的键，因为它们的请求体不同。发件箱迭代器 `growstack.events.list.all` 发送检查点 `after` 当被追上时就会停止，即使最后一个检查点仍然可用。使用 `events.list` 直接为以后的投票保存检查点。

## 开发和发行

服务器拥有MIT公共文档。导出没有工人，连接或凭证，然后生成与固定 `@hey-api/openapi-ts` 获取客户端:

```sh
bun run --cwd apps/server openapi:export
bun run --cwd packages/sdk generate
bun run --cwd packages/sdk build
bun run verify
```

提交 `openapi.json`， `src/generated` 和 `src/bindings.gen.ts`． 根验证重新导出和重新生成它们，在漂移时失败，然后构建和类型检查SDK。TypeScript 6.0.3是一个本地开发依赖，因为生成器使用了它的编译器API；存储库的TypeScript 7仍然运行根类型检查。

组件创作用途 `growstack.components.preview` 和 `growstack.components.generate`. 存储库发布通过创建一个版本 `growstack.library.create` 或者 `growstack.libraryVersions.create`，然后呼叫 `growstack.libraryVersions.publish`． 结果的 `approvalId` 确定所需的工作空间评审； `publishedAt` 在获得批准之前保持为空。 存储库的 `bun run components` CLI使用Bun构建脚本依赖项并使用它们 相同的操作。看到 [`packages/components/README.md`](https://npmcn.com/package/%40growstack/components/README.md).

`bun run version:sdk patch|minor|major|<x.y.z>` 更新版本和变更日志。这个 `sdk-v<version>` 标记通过OIDC触发npm可信发布的发布工作流。监督器配置受信任的发布者并推送初始的 `sdk-v0.1.0` 标签。如果源存储库是私有的，则省略出处，当它变为公共时必须启用出处。该软件包包含已构建的SDK、MIT源代码和文档，没有生成脚本、服务器代码或测试。源代码支持存储库的 `@growstack/source` 出口条件。

## 管道和交易

`growstack.deals` 创建，读取，查询，编辑，重新打开和删除交易。 `growstack.pipelines` 和 `growstack.pipelineStages` 管理管道和阶段； 这些写操作需要所有者或管理会话。舞台剪辑保留了胜利和胜利 失去的类别。交易更新可以提供所需的字段以及 `stageId`； `expectedStageId` 拒绝陈腐的举动。查询响应包括开放和加权 工作区中的汇总报告货币，并确定不可用的汇率。 `growstack.dealSettings` 读取和更新报告币种和丢失原因。

## 常见问题

### @growstack/sdk 是什么？

用于Growstack公共API的类型化、重试安全的客户端

### 如何安装 @growstack/sdk？

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

### @growstack/sdk 支持 TypeScript 吗？

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

### @growstack/sdk 支持 ESM 还是 CommonJS？

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

### @growstack/sdk 需要什么版本的 Node\.js？

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

### @growstack/sdk 可以商用吗？

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

### @growstack/sdk 还在维护吗？

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

