# @aws-blocks/bb-data 中文文档

规范地址：https://npmcn.com/package/%40aws-blocks/bb-data/

版本：0\.5\.0
npm 元数据更新时间：2026-11-02T10:25:06.409Z
中文译文更新时间：2026-11-07T13:00:44.636Z
软件包许可：Apache-2\.0

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

原始 npm 页面：https://www.npmjs.com/package/%40aws-blocks/bb-data
原文对照：https://npmcn.com/package/%40aws-blocks/bb-data/?lang=original
项目主页：https://github.com/aws-devtools-labs/aws-blocks/tree/main/packages/bb-data#readme
源码仓库：https://github.com/aws-devtools-labs/aws-blocks

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

- 包体积（解压后）：1.5 MB，284 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：8 个
- peer 依赖：kysely \>=0\.28\.12 \<0\.30\.0，constructs ^10\.6\.0，aws-cdk-lib ^2\.257\.0
- 首次发布：2026-06-15T23:39:25.245Z
- 最新版本发布：2026-11-02T10:25:05.910Z
- 近 30 天下载量：64487（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：15（近 12 个月 15 个）

## 中文简介

完整的 PostgreSQL 数据库——默认情况下提供 Aurora Serverles v2,或连接到现有的 PostgreSQL 数据库(Supabase, Neon等) 通过 `fromExisting()`。 与外国密钥、交易、行级安全以及打字机建立完整的关系模型

## 安装

```sh
npm install @aws-blocks/bb-data
```

也可以使用：`pnpm add @aws-blocks/bb-data`、`yarn add @aws-blocks/bb-data`、`bun add @aws-blocks/bb-data`

## README

# @aws- blocks/ bb- data (原始内容存档于2018-09-28) (英语)

完整的 PostgreSQL 数据库——默认情况下提供 Aurora Serverles v2,或连接到现有的 PostgreSQL 数据库(Supabase, Neon等) 通过 `fromExisting()`。与外国密钥、交易、行级安全以及一个类型安全的 Kysely 查询构建器建立完整的关系模型.

**何时使用 :** 复杂的多表JOIN,ACID交易,外接键约束,聚合,行级安全,或连接到现有的PostgreSQL数据库. 需要PostgreSQL全能时使用.

**不使用时 :** 用于简单的密钥值检查, 使用 `KVStore`。对于带有二级索引的 NoSQL,使用 `DistributedTable`对于没有FK/RLS/触发器的无服务器 SQL(多区域,即时提供),使用 `DistributedDatabase`。 。 。 .

> 设计与模拟等价细节 : [设计](https://npmcn.com/package/%40aws-blocks/bb-data/DESIGN.md)

## 快速启动

```typescript
import { Database, sql } from '@aws-blocks/bb-data';

const db = new Database(scope, 'main', {
  migrationsPath: './aws-blocks/migrations',
});

// Parameterized queries via sql tagged template (injection-safe)
const users = await db.query<{ id: string; name: string }>(
  sql`SELECT * FROM users WHERE active = ${true}`
);

const user = await db.queryOne<{ id: string; name: string }>(
  sql`SELECT * FROM users WHERE id = ${userId}`
);

const { rowCount } = await db.execute(
  sql`INSERT INTO users (id, name, email) VALUES (${id}, ${name}, ${email})`
);

// Transactions
await db.transaction(async (tx) => {
  await tx.execute(sql`UPDATE accounts SET balance = balance - ${100} WHERE id = ${fromId}`);
  await tx.execute(sql`UPDATE accounts SET balance = balance + ${100} WHERE id = ${toId}`);
});
```

## 移徙

创建编号 `.sql` 迁移目录中的文件 :

```
aws-blocks/migrations/
  001_create_users.sql
  002_create_posts.sql
  003_seed_admin.sql
```

```sql
-- 001_create_users.sql
CREATE TABLE users (
  id TEXT PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

迁移自动运行 :

-   **本地 dev :** 在第一次查询时( PGlite, 坚持在 `.bb-data/`(中文(简体) )
-   **AWS部署:** 期间使用自定义资源 Lambda `cdk deploy`

应用迁移情况在以下表格中跟踪: `_migrations` 页:1 每个文件运行一次.

> **设定 `migrationsPath` 与工程根相对的路径** (如"快起步"—— `'./aws-blocks/migrations'`); 由您运行的目录合成解析 `cdk` 编号 : `npm run deploy` 进来 这是最简单的可靠模式.
> 
> 你用不着 `fileURLToPath(import.meta.url)` 为了这个 您的后端模块在当地作为无害环境管理运行,但捆绑到 **常见JS** 在兰布达,在那里 `import.meta` 为空。 AWS 屏蔽闪烁 `import.meta.url` 编号 : `import.meta.dirname` {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}所以它不会在装货时坠毁 {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}但是在运行时 **捆绑输出** 位置,而不是您的源树。 所以别用 `import.meta.url` 在请求的时间读取与您来源相关的文件; 输入数据或将其作为Lambda资产.

## Kysely 查询构建器

对于没有原始 SQL 的类型安全查询:

```typescript
import { createKyselyAdapter } from '@aws-blocks/bb-data';

interface Schema {
  users: { id: string; email: string; name: string };
  posts: { id: string; user_id: string; title: string };
}

const kysely = createKyselyAdapter<Schema>(db);

// Type-safe SELECT
const users = await kysely
  .selectFrom('users')
  .where('email', '=', 'user@example.com')
  .selectAll()
  .execute();

// JOINs
const posts = await kysely
  .selectFrom('posts')
  .innerJoin('users', 'users.id', 'posts.user_id')
  .select(['posts.title', 'users.name'])
  .execute();

// Transactions
await kysely.transaction().execute(async (trx) => {
  await trx.insertInto('users').values({ id: '1', email: 'a@b.com', name: 'A' }).execute();
  await trx.insertInto('posts').values({ id: '1', user_id: '1', title: 'Hello' }).execute();
});
```

见 [Kysely 文档](https://kysely.dev/) 用于完整查询构建器 API.

## 行级安全( RLS)

与 Supabase 兼容会话变量的用户背景范围查询 :

```typescript
const scoped = db.withRLS({ userId: 'user-123', role: 'authenticated' });

// All queries on `scoped` run inside a transaction with SET LOCAL ROLE
// and request.jwt.claims set — PostgreSQL RLS policies are enforced.
const myPosts = await scoped.query<Post>(sql`SELECT * FROM posts`);
```

`request.jwt.claims` 总是带着 `sub` =: `userId` 财务报告和审定财务报表 `role` = 数字 `role` 你通过。 额外 `claims` 被合并,但他们不能 覆盖这两个:a `sub` 或者说 `role` 键入 `claims` 被忽略。 因此政策可以信任两者,例如: `USING (owner_id = current_setting('request.jwt.claims', true)::jsonb ->> 'sub')`。当您从身份提供者处转发请求时,将特定提供者的值置于他们自己的密钥下(例如 `claims: { idp_sub: token.sub }`) (中文(简体) ).

> **先决条件(当地和AWS):** `withRLS` 问题 `SET LOCAL ROLE <role>` (默认) `authenticated`) (中文(简体) ). 该角色必须存在,数据库用户必须是其中的一员. 在 PostgreSQL 16 上,以及Aurora 运行后,创建角色的用户只获得 `ADMIN` 上面没有 `SET`,所以明确赋予角色。 在您的迁移中添加:
> 
> ```sql
> CREATE ROLE authenticated;
> CREATE ROLE anon;
> GRANT authenticated TO CURRENT_USER;
> GRANT anon TO CURRENT_USER;
> -- grant table privileges to these roles as needed, then define RLS policies
> ```
> 
> 如果角色切换被拒绝, 每个 `withRLS()` 调用 500 失败 `QueryFailed`,而服务器日志为缺失的 `GRANT`。 。 。 .

## CRUD 处理器

从计划定义中生成输入的 CRUD 方法 :

```typescript
const crud = db.crud({
  tables: ['users', 'posts'],
  // `auth` takes no arguments — close over your request context to resolve the user.
  auth: async () => {
    const user = await auth.requireAuth(context);
    return { userId: user.userId };
  },
});

// Auto-generated flat method names per table:
//   crud.listUsers(), crud.getUser(id), crud.createUser(data),
//   crud.updateUser(id, data), crud.deleteUser(id)
//   crud.listPosts(), crud.getPost(id), ...
```

## 连接到现有数据库

```typescript
import { Database, fromExisting } from '@aws-blocks/bb-data';

// Supabase, Neon, or any PostgreSQL-compatible database
const db = new Database(scope, 'external', {
  connection: fromExisting({ connectionString: process.env.DATABASE_URL! }),
});
```

### TLS 证书验证

服务器的 TLS 证书是 **默认验证**管理下供应商 (Supabase, neon, RDS) 提交由特定供应商 CA 签名的证书 这不在Node的内置信托店里 所以验证需要打针 那个CA. `ssl.ca` 获取证书 **目录** (一个PEM字符串),不是路径—— 用于Supabase, 下载 `prod-ca-2021.crt` 从您的项目 **数据库设置 — SSL 配置**数字 :

```typescript
import { readFileSync } from 'node:fs';

const db = new Database(scope, 'external', {
  connection: fromExisting({
    connectionString: process.env.DATABASE_URL!,
    ssl: { ca: readFileSync('./supabase-ca.crt', 'utf8') },
  }),
});
```

`bb-data pull` 给您接线: 它会提示您的 CA 证书并输入 给 `aws-blocks/database.ca.ts` (捆绑成 ,所以连接是 **默认验证** - 包括: 在部署的Lambda, 没有运行时间配置. `DATABASE_CA_CERT` (内在 PEM 或文件路径 ) 覆盖已执行的证书 。 如果两者都没有,则 生成的接线返回到 `ssl: { rejectUnauthorized: false }` (单位:千美元)**加密但 未认证**仅以本地数据表示 **已部署的函数未关闭** (拒绝连接)而不是运行未经验证. 为生产提供CA.

## 从Supabase迁移

已经有Supabase软件了? `bb-data pull` 连接到您现有的 Supabase 数据库并生成一个完整、 类型安全的后端 —— 将您的表格、 数据和 RLS 政策保持原样 .

```sh
npx bb-data pull
```

它会做什么:

-   透视您的公示表( 只读 —— 您的数据库没有被修改)
-   生成打入的定义、 CRUD 操作和个性化迁移指南
-   将您的连接字符串保存到本地 `SUPABASE_DB_URL` 内 `.env.local` (部署时在SSM中加密). 只有该条目被添加或更新——其他设置、注释和文件的权限被保存 `SUPABASE_DB_URL` 线条本身是重写整行的,所以其末尾的注释不保存。 若为 `.env.local` 无法安全更新(例如,更改将改变另一个条目的读取方式), `db pull` 在生成任何文件之前停止,请您手动设置条目。 选择“ 生产” 对 `.env.production`。 。 。 .

它不迁移的东西:Supabase Auth、存储、实时或边缘函数。 如果使用第三方的OIDC供应商(Auth0, Clerfer, Google, Cognitto),可以将其接入Blocks——查看生成的 `MIGRATION_GUIDE.md#auth`。 。 。 .

在拉后,运行 `npm run dev` 开始根据您真正的数据库本地开发.

调取后, 用版本控制的 SQL 移入管理 `./migrations/` 自动应用 `npm run dev` 财务报告和审定财务报表 `npm run deploy`。参见生成 `MIGRATION_GUIDE.md#evolving-your-schema`。 。 。 .

## 处理错误

```typescript
import { DatabaseErrors } from '@aws-blocks/bb-data';
import { isBlocksError } from '@aws-blocks/core';

try {
  await db.execute(sql`INSERT INTO users (id, email) VALUES (${id}, ${email})`);
} catch (e: unknown) {
  if (isBlocksError(e, DatabaseErrors.UniqueConstraintViolation)) {
    // Duplicate key — email already exists. Serialized as HTTP 409 (Conflict),
    // not retriable (a blind retry of the same insert fails identically).
  }
  if (isBlocksError(e, DatabaseErrors.PermissionDenied)) {
    // Your statement was refused: a row-level-security policy rejected the row
    // (for example a withRLS() user writing someone else's row), or the role has
    // no grant on the table. Serialized as HTTP 403.
  }
  if (isBlocksError(e, DatabaseErrors.CheckViolation) || isBlocksError(e, DatabaseErrors.NotNullViolation)) {
    // A value fails a CHECK constraint, or a required column is missing.
    // Serialized as HTTP 400.
  }
  if (isBlocksError(e, DatabaseErrors.ForeignKeyViolation)) {
    // The referenced row doesn't exist, or other rows still reference the one
    // being deleted. Serialized as HTTP 409 (Conflict).
  }
  if (isBlocksError(e, DatabaseErrors.QueryFailed)) {
    // General query failure (syntax error, missing table, etc.)
  }
  if (isBlocksError(e, DatabaseErrors.TransactionFailed)) {
    // Transaction could not commit
  }
  if (isBlocksError(e, DatabaseErrors.SerializationFailure)) {
    // Serializable-isolation conflict with a concurrent transaction — serialized
    // as HTTP 409 (Conflict), retriable — safe to retry
  }
  if (isBlocksError(e, DatabaseErrors.ConnectionFailed)) {
    // Cannot reach the database — includes a `minCapacity: 0` cluster resuming
    // from auto-pause, which succeeds on retry a few seconds later
  }
}
```

每个错误的客户端可见消息是固定字符串; 驱动程序本身 文本,将表格、列和限制的名称保留在服务器上 错误 `cause`。仅限 `SerializationFailure` 财务报告和审定财务报表 `ConnectionFailed` 价值 重试: 请求出错( r)`PermissionDenied`, (中文(简体) ), `CheckViolation`, (中文(简体) ), `NotNullViolation`, (中文(简体) ), `ForeignKeyViolation`, (中文(简体) ), `UniqueConstraintViolation`失败 每次都一样.

每个错误都会中止所附的 Postgres 交易 。 内部a `db.transaction()` 调回,一个被捕获的错误使交易无法使用: 下个语句因 `QueryFailed`. 在外接他们 `transaction()`,或 在保存点中将语句包裹( )`SAVEPOINT s` . `ROLLBACK TO SAVEPOINT s`如果 交易应继续下去.

## 它的规定

-   **Aurora 无服务器 v2** ——相容后SQL相容,分级为0.5-128ACU. 存储 休息时加密为 **通过上下文旗选择进入** 因此,新项目的安全通过 默认不替换已存在的集群。 新设 `create-blocks-app` 项目 设定 `"@aws-blocks/bb-data:encryptStorageByDefault": true` 内 `cdk.json`,哪个 打开账户AWS管理的加密 `aws/rds` 键。 通过一个 `storageEncryptionKeyArn` (客户管理的 KMS 密钥的 ARN) 也转动 无论旗帜如何加密并使用该密钥( 它也加密) 生成的证书秘密 。 当国旗或密钥都没有设定时 集群合成时没有 `StorageEncrypted` 财产(现有, 未加密集群未受影响)和合成警告解释如何选择 进去 关键是 **进口** (锁不能改变它的政策),所以它的政策 必须已经授予部署本金 `kms:CreateGrant` + 键 `kms:DescribeKey` (RDS使用赠款加密存储量)和赠款 `kms:Decrypt` 页:1 在数据 API 上读取证书的校长。 钥匙必须在里面 页:1 **同一账户和区域** 作为集群.
-   **自动备份** ——默认保留 **15天时间**,这也是 点入时间恢复窗口。 由单人控制 `pointInTimeRecovery` 选项(模仿所有其他块块): `true` 启用15天窗口, `{ retentionDays: n }` 针入1至35天窗口 `false` 夹住1天 最小值( Aurora 无法关闭自动备份) 。 省略时跟随 堆栈宽度 `defaults.pointInTimeRecovery` (关于 `production`关闭在下面 `sandbox` ——最少1天着陆.
-   **云表日志导出** — PostgreSQL 引擎日志被导出到 Cloud Watch 记录 日志组保留跟随整个堆栈 `defaults.logRetention` 何时 设置;否则它使用账户默认值.
-   **职业介绍所** 私人子网(同化,无NAT)
-   **机密管理器** ——自动生成的证书. 尚未自动旋转 接通(在VPC组中旋转Lambda是计划的后续行动) 密钥用您的加密 `storageEncryptionKeyArn` 当一个被提供.
-   **移徙Lambda** —运行 `.sql` 通过自定义资源部署的文件
-   **行政会议** —— 说 `rds-data:*` 财务报告和审定财务报表 `secretsmanager:GetSecretValue` 给Lambda的应用软件

> **访问模式 :** 数据库完全通过 RDS 数据 API 连接 (HTTPS + 机密管理者证书),从不使用原始 Postgres socket. 数据库级别 IAM认证(`iamAuthentication`因此,它被故意置之不理—— 不适用于 Data API 访问路径.
> 
> **对现有未加密集群进行加密需要 替换——替换具有破坏性.** RDS 无法加密 已经设置了未加密的集群, 因此正在打开存储加密 上( 或更改 KMS 密钥) 使 CloudFormation 创建 **新建, 空** 加密集群并重点堆栈。 有一个 **无位置路径**。 。 。 . 旧的集群及其数据将取决于删除政策:
> 
> -   **生产(保留):** 古老的群落被抛在后头,成为孤儿,没有 更长时间的引用 。 应用程序回来 指向新的 **空** 分组。 迁移自定义资源 **没有** 在集群交换中重新运行—— 其唯一的 Cloud Formation 属性是服务符和迁移 散列, 集群被替换时也不会改变, 因此 Cloud Formation 永远不会 引用来. 因此,替换组产生 **无计划**· ; 仅当移取文件更改时( 更改移取文件) 移取会运行 ) (中文(简体) ). 您的数据仍然存在于孤星群中, 但未被恢复 .
> -   **沙盒(DESTROY): (中文(简体) )** 旧数据组及其所有数据为 **删除**。 。 。 .
> -   **抓图( T)`removalPolicy: 'snapshot'`:** 旧组图示为 它被替换。 生产 `deletionProtection: true`后续行动 删除旧集群可能失败并留作原地; 此清理路径是 未经核实的真实部署.
> 
> **取而代之为相.** 将加密调回 **关** - 删除 旗帜(或 `storageEncryptionKeyArn`)来自已经部署的项目 加密,是否通过删除 `cdk.json` 线条,或者通过一个将它放下的合并—— 并更改 `StorageEncrypted` 财产,所以 **同样取代 分组** (恢复到未加密) 使用相同的新空集群 / no-schema 上述结果。 在删除旗帜前审查 diff 和快照 不仅在添加之前.
> 
> 唯一安全的路线是将数据传遍你们自己: **简介** 页:1 现有集群, **恢复** 以加密方式快照到新集群 启用,然后切到它。 检查"云形" diff 并拍摄快照 在将此项更改部署到您需要的数据组之前。 正在添加或 更改 KMS 密钥还替换集群生成的证书密钥( a) 新的逻辑 id, 从而生成新的密码),所以记录现有的 证书——或者在旧集群上重置主密码——如果您仍然 需要进入孤儿群体.

## 地方发展

-   **引擎 :** PGlite (WASM PostgreSQL) —— 完整的 Postgres 兼容性
-   **存储 :** `.bb-data/{fullId}/` ——坚持跨重启,以擦去 `rm -rf .bb-data`
-   **移徙:** 在第一个查询中自动运行

### 本地对 AWS: 列类型

阵列和 `json` 编号 : `jsonb` 列返回相同的 JavaScript 值 两个引擎。 阵列( R)`text[]`, (中文(简体) ), `int[]`)作为JS阵列回来 `json` 编号 : `jsonb` 列作为解析对象返回, 不管你在本地运行 PGlite)或位于RDS数据API上的AWS上. 要素表述仍然遵循 缩写如下——例如:. `numeric[]` 元素作为字符串回来 数据API.

一些平面数字类型在两者的表示上仍然可能有所不同 引擎 : `numeric` 编号 : `decimal` 以字符串的形式在数据 API 上返回,并且 `bigint` 编号 : `int8` 回来当JS `number` 在数据 API 上 `pg` 编号 : PGlite 驱动程序默认情况下作为字符串返回. 刻出或清晰解析 如果你需要两个引擎的相同值.

一个 Postgres 键入 RDS 数据 API 无法返回 `tsvector`: 选择一个 `tsvector` 直接列(例如 `select *` 在一张产生量的桌子上 `search tsvector` 在 AWS 上失败。 从选定的列表中排除它——a `tsvector` 通常只用于 `WHERE` 编号 : `ORDER BY` 全文上游, 不读取为值 .

## 配置

```typescript
interface DatabaseOptions {
  /** Path to directory containing numbered .sql migration files. */
  migrationsPath?: string;
  /** Connect to an existing database instead of provisioning one. */
  connection?: ExternalDatabaseRef;
  /** Schema metadata for crud() support. */
  schema?: TableSchema;
  /** Aurora PostgreSQL engine version, e.g. '16.13'. Override the Aurora engine version. @default '16.13' */
  postgresVersion?: string;
  /**
   * ARN of a customer-managed KMS key for the cluster's storage-at-rest encryption
   * (also encrypts the auto-generated credentials secret). Supplying it turns
   * storage encryption on regardless of the `@aws-blocks/bb-data:encryptStorageByDefault`
   * context flag. When omitted, encryption follows that flag — on with the
   * account's AWS-managed `aws/rds` key when set, otherwise left unset. The key is
   * imported, so its policy must already grant the deploying principal
   * `kms:CreateGrant` + `kms:DescribeKey` and grant `kms:Decrypt` to the principal
   * reading the credentials secret; it must be in the same account + region.
   */
  storageEncryptionKeyArn?: string;
  /**
   * Automated-backup retention, which is also the point-in-time-recovery (PITR)
   * window. `true` enables the 15-day window; `{ retentionDays: n }` pins a
   * 1–35-day window; `false` clamps to the 1-day minimum (Aurora cannot disable
   * automated backups). When omitted, follows `defaults.pointInTimeRecovery`.
   */
  pointInTimeRecovery?: boolean | { retentionDays: number };
}
```

## 软件包导出条件

```json
{
  "exports": {
    ".": {
      "cdk": "./dist/index.cdk.js",
      "aws-runtime": "./dist/index.aws.js",
      "default": "./dist/index.mock.js"
    }
  }
}
```

## 业绩

-   **查询间隔 :** 10-50ms(温),~500ms从0 ACU起冷
-   **通过量 :** 请求通过 RDS 数据 API (HTTPS) 而不是集合数据库连接,所以没有连接池上限或 RDS 代理服务器; 货币以 Data API 请求限制和集群的 ACU 缩放相接.
-   **存储 :** 最多128个TiB,10个GiB增量的自动分级
-   **费用:** ~ 0.12/ACU-小时+~ 0.10/GB-月存储
-   **重复性 :** 3个AZ区6份,可用率99.99%

## 常见问题

### @aws-blocks/bb-data 是什么？

完整的 PostgreSQL 数据库——默认情况下提供 Aurora Serverles v2,或连接到现有的 PostgreSQL 数据库\(Supabase, Neon等\) 通过 fromExisting\(\)。 与外国密钥、交易、行级安全以及打字机建立完整的关系模型

### 如何安装 @aws-blocks/bb-data？

在项目目录运行 npm install @aws-blocks/bb-data，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：kysely（\>=0\.28\.12 \<0\.30\.0）、constructs（^10\.6\.0）、aws-cdk-lib（^2\.257\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。它还提供命令行工具 bb-data，可以用 npx bb-data 直接运行。

### @aws-blocks/bb-data 支持 TypeScript 吗？

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

### @aws-blocks/bb-data 支持 ESM 还是 CommonJS？

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

### @aws-blocks/bb-data 可以商用吗？

@aws-blocks/bb-data 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @aws-blocks/bb-data 的下载量有多少？

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

### @aws-blocks/bb-data 还在维护吗？

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

