# @felloh-org/lambda-wrapper 中文文档

规范地址：https://npmcn.com/package/%40felloh-org/lambda-wrapper/

版本：1\.11\.277
npm 元数据更新时间：2026-11-13T15:43:33.549Z
中文译文更新时间：2026-11-14T14:06:48.315Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40felloh-org/lambda-wrapper
原文对照：https://npmcn.com/package/%40felloh-org/lambda-wrapper/?lang=original

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

- 包体积（解压后）：1.3 MB，28 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- Node.js 要求：\>=20
- 运行依赖：24 个
- 首次发布：2021-12-21T23:11:11.473Z
- 最新版本发布：2026-11-13T15:43:33.367Z
- 近 30 天下载量：3432（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：490（近 12 个月 88 个）

## 中文简介

所有 Felloh 无服务器项目的 Lambda 包装器

## 安装

```sh
npm install @felloh-org/lambda-wrapper
```

也可以使用：`pnpm add @felloh-org/lambda-wrapper`、`yarn add @felloh-org/lambda-wrapper`、`bun add @felloh-org/lambda-wrapper`

## README

# 羊田包装工

[![release](https://github.com/felloh-org/lambda-wrapper/actions/workflows/release.yml/badge.svg)](https://github.com/felloh-org/lambda-wrapper/actions/workflows/release.yml)

为 Felloh 无服务器项目提供核心功能的共享库,包括依赖注入,记录,请求处理,数据库实体,以及AWS Lambda函数的响应模型.

## 安装

```bash
npm install @felloh-org/lambda-wrapper
# or
yarn add @felloh-org/lambda-wrapper
```

## 快速启动

```javascript
import { LambdaWrapper, DEFINITIONS, ResponseModel } from '@felloh-org/lambda-wrapper';

const configuration = {
  SERVICE_NAME: 'my-service',
};

export const handler = LambdaWrapper(configuration, async (di, request) => {
  const logger = di.get(DEFINITIONS.LOGGER);
  const warehouse = di.get(DEFINITIONS.WAREHOUSE);

  logger.info('Processing request');

  // Your handler logic here

  return new ResponseModel({ message: 'Success' }, 200).generate();
});
```

## 羊田包装工

核心包装器函数取一个配置对象和一个处理器函数,返回一个Lambda相容函数与内置的依赖性注入,错误处理,记录,和度量衡相匹配.

```javascript
import { LambdaWrapper } from '@felloh-org/lambda-wrapper';

const handler = LambdaWrapper(configuration, async (di, request, callback) => {
  // di      - DependencyInjection container with all services
  // request - RequestService instance with parsed request data
  // callback - Lambda callback (for non-async handlers)
});
```

### 处理器模式

**Async 处理器( 建议):**

```javascript
export const handler = LambdaWrapper(config, async (di, request) => {
  const response = new ResponseModel({ result: 'ok' }, 200);
  return response.generate();
});
```

**回调处理器 :**

```javascript
export const handler = LambdaWrapper(config, (di, request, callback) => {
  const response = new ResponseModel({ result: 'ok' }, 200);
  callback(null, response.generate());
});
```

**丢出错误作为回复 :**

```javascript
export const handler = LambdaWrapper(config, async (di, request) => {
  const params = request.getAll();

  if (!params.email) {
    const error = new ResponseModel({}, 422);
    error.addError({
      title: 'Validation Error',
      message: 'Email is required',
    });
    throw error;  // Returns a 422 response, not a 500
  }

  // continue processing...
});
```

### 处理错误

包装器自动捕获出错并返回适当的响应 :

-   **弹出反应模式** - 返回当前响应(例如400、404、422)
-   **抛出 Lambda 终结** - 使用错误返回回复 `code` 属性
-   **未处理错误** - 返回500个回复并记录出错
-   **数据库大小限制出错** - 返回413个响应

5xx错误自动被记录;4xx错误没有.

### 温暖支持

包装手柄 [无服务器插件加热](https://github.com/juanjoDiaz/serverless-plugin-warmup) 自动事件。 当检测到暖和事件时, 处理器会立即返回而不执行您的代码 .

## 依赖性注射系统

每个操作员都会收到 `DependencyInjection` 作为第一个参数。 该集装箱提供内置服务及您注册的任何定制服务.

### 内设服务

| 服务 | 定义 | 说明 |
| --- | --- | --- |
| 锁定器 | `DEFINITIONS.LOGGER` | 与温斯顿和巴塞利姆进行结构化伐木 |
| 请求 | `DEFINITIONS.REQUEST` | 解析 HTTP 请求数据 |
| 仓库 | `DEFINITIONS.WAREHOUSE` | TypeORM 数据库连接管理器 |
| 认证 | `DEFINITIONS.AUTHENTICATION` | 用户作用和组织检查 |
| 用户 | `DEFINITIONS.USER` | 目前来自Cognitto JWT索赔的用户 |
| 事件桥 | `DEFINITIONS.EVENT_BRIDGE` | AWS 事件Bridge 事件发布 |
| 秘诀 | `DEFINITIONS.SECRETS` | AWS 有缓存的秘密管理器 |
| HTTP 密码 | `DEFINITIONS.HTTP` | 基于 Axios 的 HTTP 客户端 |
| 网页 | `DEFINITIONS.WEBHOOK` | HMAC 签名的 Webhook 发送 |
| 审计 | `DEFINITIONS.AUDIT_LOGGER` | 通过 EventBridge 创建审计活动 |
| 支付启动对象 | `DEFINITIONS.PAYMENT_INITIATION_OBJECT` | 支付联系和电子商务查询 |
| 追踪 | `DEFINITIONS.TRACING` | OpenTeleometry 跨度和属性, 导出到 Honeycomb |

### 自定义服务

通过扩展创建自定义服务 `DependencyAwareClass`数字 :

```javascript
import { DependencyAwareClass, DEFINITIONS } from '@felloh-org/lambda-wrapper';

class PaymentProcessor extends DependencyAwareClass {
  async processPayment(transactionId) {
    const logger = this.getContainer().get(DEFINITIONS.LOGGER);
    const warehouse = this.getContainer().get(DEFINITIONS.WAREHOUSE);

    const connection = await warehouse.connect();
    const repo = connection.getRepository(TransactionEntity);
    const transaction = await repo.findOne({ where: { id: transactionId } });

    logger.info(`Processing payment ${transactionId}`);

    return transaction;
  }
}
```

在配置中注册自定义服务 :

```javascript
const configuration = {
  DEPENDENCIES: {
    PAYMENT_PROCESSOR: PaymentProcessor,
  },
};

export const handler = LambdaWrapper(configuration, async (di, request) => {
  const processor = di.get('PAYMENT_PROCESSOR');
  await processor.processPayment('txn_123');
});
```

### 集装箱 API

```javascript
// Get a service
const logger = di.get(DEFINITIONS.LOGGER);

// Get the raw Lambda event
const event = di.getEvent();

// Get the Lambda context
const context = di.getContext();

// Get configuration values
const config = di.getConfiguration();           // full config
const dbHost = di.getConfiguration('DB_HOST');   // specific key, returns null if missing

// Check if running in serverless-offline
if (di.isOffline) {
  // local development mode
}
```

## 服务

### 请求服务

解析并提供所有HTTP请求数据的访问权限.

```javascript
const request = di.get(DEFINITIONS.REQUEST);

// Get a single parameter (checks query params for GET, body for POST)
const email = request.get('email');
const page = request.get('page', '1');              // with default value

// Get all parameters
const allParams = request.getAll();

// Force reading from query string regardless of HTTP method
const queryParams = request.getAll('GET');

// Path parameters
const id = request.getPathParameter('id');
const allPath = request.getPathParameter();          // all path params

// Headers (case-insensitive)
const contentType = request.getHeader('Content-Type');
const allHeaders = request.getAllHeaders();

// Authorization
const token = request.getAuthorizationToken();       // extracts Bearer token

// Client info
const ip = request.getIp();
const browser = request.getUserBrowserAndDevice();   // parsed user-agent

// AWS event records (SQS, SNS, etc.)
const record = request.getAWSRecords();
```

**内容类型支持 :**

请求服务根据 `Content-Type` 页眉 :

-   `application/json` - JSON分析
-   `application/x-www-form-urlencoded` - 表格数据解析
-   `text/xml` - XML 通过 xml2js 解析
-   `multipart/form-data` - 以缓冲支持的文件上传解析

**请求验证 :**

```javascript
const constraints = {
  email: { presence: true, email: true },
  amount: { presence: true, numericality: { greaterThan: 0 } },
  start_date: { datetime: { dateOnly: true } },
};

await request.validateAgainstConstraints(constraints);
// Resolves on success, rejects with a 422 ResponseModel on failure
```

审定用途 [验证.js](https://validatejs.org/) 与日期支持 通过瞬间.

### Logger 服务

结构化伐木与温斯顿和巴塞利姆集成. 漂亮的打印输出在服务器无线模式下.

```javascript
const logger = di.get(DEFINITIONS.LOGGER);

// Standard logging
logger.info('Payment processed successfully');
logger.error(new Error('Connection failed'));
logger.warning(error);                            // routes to error() or info() based on LOGGER_SOFT_WARNING env

// Labels (lightweight markers for tracing)
logger.label('payment-initiated');
logger.label('silent-label', true);               // silent = not logged to console

// Metrics
logger.metric('response_time', 250);
logger.metric('ip_address', '10.0.0.1', true);   // silent = not logged to console

// Object inspection
logger.object('Processing payload', { id: 1, amount: 500 });
logger.object('Failed response', errorObj, 'error');  // supports 'info', 'warning', 'error'
```

Axios 错误会自动调整到 `config`, (中文(简体) ), `message`, (中文(简体) ), `response.status`,以及 `response.data` - 从日志中取出动词请求/标题数据.

### 追踪服务( 蜂窝站 / OpenTeleometry)

每件被包裹的引用都用OpenTeleometter来追踪,并用OTLP/HTTP来导出至Honeycomb. 追踪是 **关闭,除非 `HONEYCOMB_API_KEY` 设定** - 没有它,OpenTeleometry API 推出非记录跨度,所以服务可以无条件叫这些帮助者.

每一次引用你得到的, 没有代码更改的服务:

-   以触发器命名的一个根跨( q)`POST /organisations/{id}`,事件桥 `detail-type`, (中文(简体) ), `aws:sqs <function>`),携带 `faas.invocation_id`, (中文(简体) ), `faas.coldstart`, (中文(简体) ), `faas.trigger`,HTTP方法/路线/路径/客户IP/用户代理, `http.response.status_code`,以及 `felloh.request_id` 从 `ResponseModel` 体质;
-   每个孩子的跨度 `HTTPService.request()` 调用( n)`HTTP POST`,与 `server.address`, (中文(简体) ), `url.path` 和响应状态; 查询字符串从未被记录);
-   每个 `logger.error()` 记录为活动期间的例外事件。 记录出错并仍然返回 2xx 的处理器保留出错的追踪,所以"没有失败请求的错误"仍然可以查询; 2;
-   5xx 回复并投出错误标记此间距为错误 `error.type`· ;
-   处理器返回前明确冲出(Lambda在之后立即冻结进程),以 `HONEYCOMB_FLUSH_TIMEOUT_MS`。 。 。 .

```javascript
const tracing = di.get(DEFINITIONS.TRACING);

// Add business context to the invocation span - the fields you will actually query by
tracing.setAttributes({ organisation_id: organisation.id, transaction_id: transaction.id });

// Wrap a unit of work in a child span
const score = await tracing.withSpan('risk.score', async (span) => {
  span.setAttribute('model', 'laya');
  return scorer.score(narrative);
});

tracing.isEnabled();   // true when spans are being exported
tracing.getTracer();   // raw OpenTelemetry tracer for anything else
```

#### 错误细节: 跨度足够查找断层

当引用失败(推错,4xx/5xx回复,或记录在请求中的错误)时,引用跨度会带平坦可查询的字段,这样一个人或AI就可以将问题从Honeycomb中缩小:

| 外地 | 它告诉你什么 |
| --- | --- |
| `faas.handler`, (中文(简体) ), `code.function` | Lambda 处理器出口`handler.signup`)和被包裹的函数的名称(`Signup`),即要打开的文件 |
| `aws.log.group.names`, (中文(简体) ), `aws.log.stream.names`, (中文(简体) ), `aws.xray.trace_id`, (中文(简体) ), `faas.invocation_id` | 恰好在云表记录中 |
| `error.type`, (中文(简体) ), `error.message`, (中文(简体) ), `error.stack`, (中文(简体) ), `error.code`, (中文(简体) ), `error.cause` | 投出的错误, 堆放于 4 KB |
| `db.query.text`, (中文(简体) ), `db.query.parameters`, (中文(简体) ), `db.response.status_code`, (中文(简体) ), `db.error.detail`, (中文(简体) ), `db.error.position`, (中文(简体) ), `db.error.constraint`, (中文(简体) ), `db.error.table`, (中文(简体) ), `db.error.hint` | 对于 TypeORM/ Postgres 失败: 准确的语句、其(已编辑) 参数和 SQLSTATE 细节 |
| `felloh.upstream.method`, (中文(简体) ), `felloh.upstream.url`, (中文(简体) ), `felloh.upstream.status_code`, (中文(简体) ), `felloh.upstream.response_body` | 给服务商或其他服务商打不通的电话 被叫的是什么 回来的是什么 |
| `felloh.response.errors` | 这个 `errors[]` 阵列返回 API |
| `enduser.id`, (中文(简体) ), `felloh.request.path_parameters`, (中文(简体) ), `felloh.request.query`, (中文(简体) ), `felloh.request.body` | 谁打电话和什么。 车体被编辑(密码、信使、卡片号码、IBAN、排序代码和相近的密钥被替换)并被封为4 KB |
| `faas.remaining_time_ms`, (中文(简体) ), `faas.timeout_imminent` | 期末剩余预算;因超时监督而关闭的时间段 `faas.timeout_imminent = true` |
| `service.version` | 管道提供时部署的承诺 `GIT_SHA`, (中文(简体) ), `COMMIT_SHA` 或者说 `SERVICE_VERSION` |

#### Honeycomb 数据集定义

Honeycomb 的 Home, 服务映射和出错率特性绑定在下面选择的字段 **数据集设置 – 定义**。包装器为每一个都发出一个字段;当Honeycomb问:

| 定义 | 将包裹寄出 | 页:1 |
| --- | --- | --- |
| 错误 | `error` | 一个短 `Type: message` 每个失败跨度上的字符串: 5xx 响应, 无 HTTP 结果的抛出, 通过登录的错误 `logger.error()`或者超时监视器 缺少健康跨度和4xx反应,包括处理者投出404分和422分 `Response`; 保持跨度状态未设并仍然携带 `felloh.response.errors`。 。 。 . |
| HTTP 状态代码 | `http.response.status_code` | 当前 OpenTelemotry 名称; Honeycomb 的默认猜想是旧的 `http.status_code`,所以明确选择. |
| 路线 | `http.route` | API Gateway资源,例如:. `/organisations/{id}`。 。 。 . |
| 用户 | `enduser.id` | 当请求被认证时,来自授权方的Cognitto用户ID. |
| 姓名、服务名称、持续时间、追踪/扫描/父母身份证 | `name`, (中文(简体) ), `service.name`, (中文(简体) ), `duration_ms`, (中文(简体) ), `trace.trace_id`, (中文(简体) ), `trace.span_id`, (中文(简体) ), `trace.parent_id` | 由Honeycomb 的 OTLP 摄入; 无选择 . |
| 元数据: 注释类型 | `meta.annotation_type` | `span_event` 对于例外的事件,我们发出, `link` 为跨度链接。 一旦这些数据到达,由OTLP摄入. |
| 元数据: 链接 Span ID / 链接跟踪 ID | `trace.link.span_id`, (中文(简体) ), `trace.link.trace_id` | 由OTLP 摄入填充; 包件今天不创建链接 . |
| 日志: 严重性 | `severity` | 在包装的例外事件,总是 `error`。 。 。 . |
| 日志: 消息 | `message` | 显示包装的例外事件: 日志上下文加错误消息 。 标准 `exception.message` 还送来了. |

包装器只发送痕迹,所以两个日志定义绑定在跨事件上,而不是单独的日志流上.

两种行为值得了解:

-   **超时监视器.** 击出超时的Lambda在代码运行前被杀死 所以不会留下任何痕迹 在截止时间(剩余时间减去冲出时间和小差)之前不久,包装器将引用时段作为错误关闭,标记它 `faas.timeout_imminent`,并输出它。 如果接线员完成后, 横幅会保持原样 .
-   **请求捕捉尸体** 如下 `HONEYCOMB_CAPTURE_REQUEST`数字 : `errors` (默认)只将修改后的身体附在无效的引用上, `always` 把它固定在每一行间, `off` 从来没有寄出去。 路径参数和查询字符串总是被记录(已编辑).

配置(每个服务在 `serverless.yml` `provider.environment`,输油管值:

| 变量 | 默认 | 目的 |
| --- | --- | --- |
| `HONEYCOMB_API_KEY` | 未设置( 跟踪关闭) | Honeycomb 摄入键。 设定它可以追踪. |
| `HONEYCOMB_API_ENDPOINT` | `https://api.honeycomb.io` | 使用 `https://api.eu1.honeycomb.io` 给欧盟的团队. |
| `OTEL_SERVICE_NAME` | `SERVICE_NAME`函数名称 | Honeycomb 每个服务名称创建一个数据集. |
| `HONEYCOMB_DATASET` | 未设定 | Honeycomb Classic;基于环境的团队会让它不设. |
| `HONEYCOMB_SAMPLE_RATE` | `1` | 在根部保留1个N的痕迹. 纸币携带 `SampleRate` 所以Honeycomb重磅计数。 头部采样不能看到出错,所以保持1,直到体积强. |
| `HONEYCOMB_FLUSH_TIMEOUT_MS` | `2000` | 在每次引用中都添加了导出时的上行键等值 . |
| `HONEYCOMB_CAPTURE_REQUEST` | `errors` | 附加已编辑的请求正文时 : `errors`, (中文(简体) ), `always` 或者说 `off`。 。 。 . |
| `GIT_SHA` 编号 : `COMMIT_SHA` 编号 : `SERVICE_VERSION` | Lambda 函数版本 | 报为 `service.version`,所以一个追踪名称 部署的承诺。 把它从管道. |

资源属性来自Lambda环境: `service.name`, (中文(简体) ), `service.version`, (中文(简体) ), `deployment.environment.name` (单位:千美元)`STAGE`, (中文(简体) ), `cloud.region`, (中文(简体) ), `faas.name`, (中文(简体) ), `faas.version`, (中文(简体) ), `faas.max_memory`。 。 。 .

注释:

-   供养者为容器的生命而活;温取再用. `Tracing.reset()` 泪下 (测试).
-   出口者是一个普通的HTTPS呼叫Honeycomb,所以在寒冷的起步中增加了几百毫秒,并且大致是每次引用的冲出回程. 遥测失败被记录下来,并且永远不会失败请求.
-   如果Lambda地层已经注册了一个全局追踪器提供商,它就赢了;包装器的提供商则只冲出一个空缓冲器.

### 仓库服务

管理连接缓存中的 TypeORM 数据库连接 .

```javascript
const warehouse = di.get(DEFINITIONS.WAREHOUSE);

// Get a connection (cached by default)
const connection = await warehouse.connect();

// Force a new connection (bypass cache)
const fresh = await warehouse.connect(null, false);

// Connect to a specific database
const analytics = await warehouse.connect('analytics_db');

// Health check
await warehouse.status();
```

**连接类型 :**

通过 `WAREHOUSE_TYPE` 环境变量 :

-   `postgres` - 直接使用 PostgreSQL 连接 `WAREHOUSE_HOST`, (中文(简体) ), `WAREHOUSE_USERNAME`, (中文(简体) ), `WAREHOUSE_PASSWORD`, (中文(简体) ), `WAREHOUSE_DATABASE`
-   `postgres-ssm` - 使用AWS保密管理器获取的证书 `DB_CREDS_ARN`

### 认证 服务

检查用户角色和组织访问. Lazy-初始化了第一次使用时的数据库连接 .

```javascript
const auth = di.get(DEFINITIONS.AUTHENTICATION);
await auth.init();

// Check organisation access and roles in one call
// Throws a 401 ResponseModel if checks fail
await auth.checkUserRoles('org-123', ['admin', 'finance']);

// Check organisation access only
await auth.checkUserRoles('org-123');

// Check roles only
await auth.checkUserRoles(null, ['admin']);

// Individual checks
const roles = await auth.fetchUserRoles();                // ['admin', 'viewer']
const hasAdmin = await auth.hasRole('admin');              // true/false
const orgs = await auth.fetchUserOrganisations(user);     // includes descendants
```

### HTTPServices (韩语)

基于Axios的HTTP客户端具有可配置的超时功能.

```javascript
const http = di.get(DEFINITIONS.HTTP);

// Default timeout is 10 seconds
http.setDefaultTimeout(30000);

const response = await http.request({
  method: 'POST',
  url: 'https://api.example.com/payments',
  headers: { Authorization: 'Bearer token' },
  data: { amount: 1000 },
});
```

### 保密服务

从 AWS 机密管理器获取并缓存机密 .

```javascript
const secrets = di.get(DEFINITIONS.SECRETS);

// Fetched once, then cached for the Lambda execution
const creds = await secrets.get('arn:aws:secretsmanager:eu-west-1:123:secret:db-creds');
// { username: 'admin', password: '...', host: '...', ... }
```

### Webhook 服务

HMAC -SHA256号调度员在网络上签名.

```javascript
const webhook = di.get(DEFINITIONS.WEBHOOK);

await webhook.send(
  'https://example.com/webhook',
  { event: 'payment.completed', transaction_id: 'txn_123' },
  'webhook-signing-secret'
);
// POST with X-Signature header containing HMAC-SHA256 hex digest
```

### 审计

通过 EventBridge 创建审计线索事件 .

```javascript
const auditLogger = di.get(DEFINITIONS.AUDIT_LOGGER);

await auditLogger.createEvent('payment.refunded', 'entity-123', 'org-456');
```

## 反应模式

所有Lambda的回复都使用标准格式,并附有CORS头.

```javascript
import { ResponseModel } from '@felloh-org/lambda-wrapper';

// Basic response
const response = new ResponseModel({ users: [] }, 200);
return response.generate();

// Building a response
const response = new ResponseModel();
response.setData({ id: 1, name: 'Test' });
response.setCode(201);
response.setMetaVariable('pagination', { page: 1, total: 10 });
response.setBodyVariable('warnings', ['Deprecated field used']);
return response.generate();

// Adding errors
const error = new ResponseModel({}, 422);
error.addError({
  title: 'Validation Error',
  message: 'Email is not valid',
  documentation_url: 'https://developers.felloh.com/errors#error-responses',
  type: 'validation',
  code: 'validation.email',
});
throw error;  // or return error.generate()

// Static shorthand
return ResponseModel.generate({ result: 'ok' }, 200);
```

**生成的响应格式 :**

```json
{
  "statusCode": 200,
  "headers": {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Credentials": true
  },
  "body": "{\"data\":{},\"errors\":[],\"meta\":{\"code\":200,\"reason\":\"OK\",\"message\":\"The request was successful\",\"request_id\":\"uuid-v4\"}}"
}
```

**支持的状态代码 :**

| 代码 | 原因 |
| --- | --- |
| 200个 |  |
| 201 (韩语) | 已创建 |
| 204 (韩语) | 无内容 |
| 400个 | 错误请求 |
| 401 (中文(简体) ) | 未经授权 |
| 403 (韩语) | 禁止 |
| 404 (韩语) | 未找到 |
| 406个 | 无法接受 |
| 410个 | 不见了 |
| 413号 | 请求实体太大 |
| 422个 | 无法处理的实体 |
| 429个 | 请求过多 |
| 500个 | 内部服务器出错 |
| 502 (中文(简体) ) | 错误的网关 |
| 第503条 | 服务不可用 |
| 504 (中文(简体) ) | 网关超时 |

## 状态模型

用于健康检查和服务状况报告.

```javascript
import { StatusModel, STATUS_TYPES } from '@felloh-org/lambda-wrapper';

const status = new StatusModel('database', STATUS_TYPES.OK);
// STATUS_TYPES: OK, ACCEPTABLE_FAILURE, APPLICATION_FAILURE
```

## Lambda 终止

用于终止 Lambda 执行的自定义错误类, 并带有特定的状态代码和消费者化消息 .

```javascript
import { LambdaTermination } from '@felloh-org/lambda-wrapper';

// Terminates with a 503 response
throw new LambdaTermination(
  'Payment provider timeout after 30s',  // internal (logged)
  503,                                    // status code
  'Service temporarily unavailable',      // body (returned to consumer)
  'Provider X timed out'                  // details
);
```

## 事件桥事件

将打出的事件发布到 AWS EventBridge .

```javascript
import {
  LambdaWrapper,
  DEFINITIONS,
  TransactionCompleteEvent,
  TransactionCompleteEmailEvent,
  UserRegistrationEvent,
  CSVEmailEvent,
  RefundRequestEmailEvent,
  BaseEvent,
} from '@felloh-org/lambda-wrapper';

export const handler = LambdaWrapper(config, async (di) => {
  const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);

  // Use a pre-built event
  const event = new TransactionCompleteEvent();
  event.setDetailParam('transaction_id', 'txn_123');
  await eventBridge.put(event);

  // Or build a custom event
  const custom = new BaseEvent('order.shipped');
  custom.setDetailParam('order_id', 'ord_456');
  custom.setDetail({ order_id: 'ord_456', carrier: 'DHL' });
  await eventBridge.put(custom);
});
```

**可用事件类型 :**

| 活动 | 说明 |
| --- | --- |
| `BaseEvent` | 常规事件, 设置您自己的细节类型 |
| `TransactionCompleteEvent` | 已完成的交易 |
| `TransactionCompleteEmailEvent` | 交易收据电子邮件 |
| `UserRegistrationEvent` | 新用户注册 |
| `UserPasswordChangedEvent` | 密码已更改 |
| `UserPasswordResetEvent` | 请求重新设置密码 |
| `SandboxRegistrationEvent` | 沙盒账户注册 |
| `CSVEmailEvent` | CSV 导出电子邮件 |
| `POSCRequestEmailEvent` | POSC 请求电子邮件 |
| `RefundRequestEmailEvent` | 退款请求通知 |

## Webhook 模型

为 Webhook 有效载荷格式化交易和退款数据.

```javascript
import { TransactionWebhookModel, RefundWebhookModel } from '@felloh-org/lambda-wrapper';

// Transaction webhook
const payload = new TransactionWebhookModel(transaction, 'Payment received');
const data = payload.get();
// { transaction: { id, narrative }, amount, booking, status, currency, surcharge, ... }
```

## 数据库(TypeORM)

### 实体

库包括按域排列的 TypeORM 实体 :

| 域名 | 说明 |
| --- | --- |
| `payment` | 交易、退款、退款、付款链接、电子商务、供应商、会话 |
| `user` | 用户、组织、角色、功能、网络呼号、账单、合作伙伴、门户网站 |
| `bank` | 账户、分类账、结算、支付、调整、受益人 |
| `agent-data` | 预订、部件、供应商、包件类型 |
| `acquirer` | BIN数据、批量、调整、波段率、交易结算 |
| `aisp` | 开放式银行交易、无卡账户/协议/要求 |
| `nuapay` | Nuapay账户、余额、受益人、交易 |
| `nuvei` | 努维伊批、商、交易、元数据 |
| `trust-payments` | 信托付款批次、商户、交易、收费、手续费 |
| `total-processing` | 处理交易和元数据共计 |
| `planet` | 行星交易、元数据、批次 |
| `saltedge` | 盐源账户、连接、客户、交易、线索 |
| `basis-theory` | 切换符号 |
| `go-cardless` | 无卡德组织配置 |
| `marketing` | 营销联系人和ESU |
| `reference` | 国家 |
| `playbook` | 游戏本、请求、秘密、版本 |

### 移徙

根据数据库运行迁移 :

```bash
# Create database schemas
yarn orm:schema:create

# Run pending migrations
yarn orm:migration:run

# Generate a new migration
yarn orm:migration:generate <name>

# Revert last migration
yarn orm:revert
```

移徙需要下列环境变量:

| 变量 | 说明 |
| --- | --- |
| `WAREHOUSE_TYPE` | `postgres` 或者说 `postgres-ssm` |
| `WAREHOUSE_HOST` | 数据库主机(用于 `postgres` 类型) |
| `WAREHOUSE_USERNAME` | 数据库用户名(用于 `postgres` 类型) |
| `WAREHOUSE_PASSWORD` | 数据库密码(用于 `postgres` 类型) |
| `WAREHOUSE_DATABASE` | 数据库名称 |
| `WAREHOUSE_SCHEMA` | 数据库计划 |
| `DB_CREDS_ARN` | 保密管理器 ARN (用于 `postgres-ssm` 类型) |

### 数据库 Schemas

数据库按以下计划编排: `user`, (中文(简体) ), `payment`, (中文(简体) ), `bank`, (中文(简体) ), `agent_data`, (中文(简体) ), `nuapay`, (中文(简体) ), `trust_payments`, (中文(简体) ), `total_processing`, (中文(简体) ), `token`, (中文(简体) ), `nuvei`, (中文(简体) ), `reference`, (中文(简体) ), `saltedge`, (中文(简体) ), `acquirer`, (中文(简体) ), `operations`, (中文(简体) ), `basis_theory`, (中文(简体) ), `aisp`, (中文(简体) ), `go_cardless`, (中文(简体) ), `planet`, (中文(简体) ), `marketing`, (中文(简体) ), `amex`, (中文(简体) ), `crm`, (中文(简体) ), `shield`。 。 。 .

## 公用事业

### 已证实 延迟

为重试逻辑提供随机延迟,并带有可配置的延迟配置.

```javascript
import { PromisifiedDelay } from '@felloh-org/lambda-wrapper';

// High latency profile (2-20s delays, weighted towards shorter)
const delay = new PromisifiedDelay(true);

// Standard latency profile (2-5s delays)
const delay = new PromisifiedDelay(false);

// Use in retry loop
for (let attempt = 0; attempt < 3; attempt++) {
  try {
    return await makeRequest();
  } catch (error) {
    await delay.get();
  }
}
```

## 发展

### 图标

```bash
# Build for production (webpack)
yarn build

# Build for TypeORM migrations (babel)
yarn build:orm

# Run linter
yarn lint

# Run tests with coverage
yarn test

# Run dependency vulnerability audit
yarn audit:check

# Run database migrations
yarn orm:migration:run

# Generate a new migration
yarn orm:migration:generate <name>

# Revert last migration
yarn orm:revert

# Create database schemas
yarn orm:schema:create
```

### 环境变量

| 变量 | 说明 |
| --- | --- |
| `SERVICE_NAME` | 记录和活动的服务标识符 |
| `EVENT_BRIDGE_ARN` | AWS 事件桥总线 ARN |
| `REGION` | AWS 区域 |
| `WAREHOUSE_TYPE` | 数据库连接类型( E)`postgres` 或者说 `postgres-ssm`(中文(简体) ) |
| `WAREHOUSE_HOST` | 数据库主机 |
| `WAREHOUSE_USERNAME` | 数据库用户名 |
| `WAREHOUSE_PASSWORD` | 数据库密码 |
| `WAREHOUSE_DATABASE` | 数据库名称 |
| `WAREHOUSE_SCHEMA` | 数据库计划 |
| `DB_CREDS_ARN` | 数据库证书的秘密管理器 ARN |
| `DB_LOGGING` | 设定为 `true` 启用 TypeORM 查询记录 |
| `LOGGER_SOFT_WARNING` | 设定为 `true` 将警告降为信息级别 |
| `IS_OFFLINE` | 由无服务器离线设定用于本地开发 |

### 项目结构

```
src/
├── action/              # Action handlers (e.g. unmatched route)
├── config/              # Dependency definitions
├── dependency-injection/  # DI container and base class
├── entity/              # TypeORM entities by domain
├── enums/               # Shared enumerations
├── event/               # EventBridge event classes
├── migration/           # Database migrations by schema
├── model/               # Response, status, and webhook models
├── service/             # Core services (logger, request, warehouse, auth, etc.)
├── util/                # Utilities (LambdaTermination, PromisifiedDelay)
└── wrapper/             # Lambda wrapper implementation
```

### 排雷中心/发改委

该项目使用Concle CI,管道如下:

1.  **测试** - 平行进行林特、测试和依赖性审计
2.  **移徙。 装入** - 制定计划,在中转时进行迁移
3.  **移徙、生产** - 成功后促进生产
4.  **迁移.sandbox** - 成功后升入沙盒

### 测试

测试与源文件(如. `src/service/logger.test.js` 并行 `src/service/logger.js`) (中文(简体) ).

```bash
yarn test
```

## 许可证

麻省理工学院

## 常见问题

### @felloh-org/lambda-wrapper 是什么？

所有 Felloh 无服务器项目的 Lambda 包装器

### 如何安装 @felloh-org/lambda-wrapper？

在项目目录运行 npm install @felloh-org/lambda-wrapper，或使用 pnpm add / yarn add / bun add。

### @felloh-org/lambda-wrapper 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/felloh-org\_\_lambda-wrapper 是否存在。

### @felloh-org/lambda-wrapper 支持 ESM 还是 CommonJS？

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

### @felloh-org/lambda-wrapper 需要什么版本的 Node\.js？

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

### @felloh-org/lambda-wrapper 可以商用吗？

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

### @felloh-org/lambda-wrapper 的下载量有多少？

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

### @felloh-org/lambda-wrapper 还在维护吗？

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

