# @edgerules/node 中文文档

规范地址：https://npmcn.com/package/%40edgerules/node/

版本：0\.2\.8-alpha\.202611121551
npm 元数据更新时间：2026-11-12T15:54:27.587Z
中文译文更新时间：2026-11-13T06:50:42.656Z
软件包许可：未声明

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

原始 npm 页面：https://www.npmjs.com/package/%40edgerules/node
原文对照：https://npmcn.com/package/%40edgerules/node/?lang=original

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

- 包体积（解压后）：1.7 MB，35 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-07-04T12:29:40.662Z
- 最新版本发布：2026-11-12T15:54:27.344Z
- 近 30 天下载量：2400（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：35（近 12 个月 35 个）

## 中文简介

边缘规则为Node.js提供决定服务.

## 安装

```sh
npm install @edgerules/node
```

也可以使用：`pnpm add @edgerules/node`、`yarn add @edgerules/node`、`bun add @edgerules/node`

## README

# @ dedgerules/ 节点

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=rimvydasb_edgerules&metric=alert_status&token=98a392e505393c255f7de845e8b74a32911f2435)](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=rimvydasb_edgerules&metric=bugs&token=98a392e505393c255f7de845e8b74a32911f2435)](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=rimvydasb_edgerules&metric=code_smells&token=98a392e505393c255f7de845e8b74a32911f2435)](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=rimvydasb_edgerules&metric=coverage&token=98a392e505393c255f7de845e8b74a32911f2435)](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules) [![Duplicated Lines](https://sonarcloud.io/api/project_badges/measure?project=rimvydasb_edgerules&metric=duplicated_lines_density&token=98a392e505393c255f7de845e8b74a32911f2435)](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules)

边缘规则决定服务 **节点.js**二号舰:

| 导出 | 说明 |
| --- | --- |
| `@edgerules/node` | 生产建设——只执行(`DecisionService`(中文(简体) ) |
| `@edgerules/node/mutable` | 发展建设——执行+CRUD`MutableDecisionService`(中文(简体) ) |

* * *

## 安装

```sh
npm install @edgerules/node @edgerules/portable
```

> 需要节点.js 18或更后(仅ESM).

* * *

## 生产用途

### 从边框规则 DSL 字符串装入

```typescript
import { DecisionService } from '@edgerules/node';

const service = new DecisionService(`{
    applicant: {
        age:    <number, required: true>
        income: <number, default: 0>
    }
    isEligible: applicant.age >= 18 and applicant.income >= 1000
}`);

// Execute the whole model — inputs are bound via a model-shaped request object
const result = service.execute('*', { applicant: { age: 25, income: 2500 } });
// { applicant: { age: 25, income: 2500 }, isEligible: true }
```

### 从便携式JSON型号装入

```typescript
import { DecisionService } from '@edgerules/node';
import type { PortableContext } from '@edgerules/portable';

const model: PortableContext = {
  '@kind': 'context',
  fields: {
    taxRate: 0.21,
    calculateTax: {
      '@kind': 'method',
      parameters: { amount: 'number', rate: 'number' },
      body: { '@kind': 'context', fields: { result: 'amount * rate' } },
    },
  },
};

const service = new DecisionService(model);

// Execute a specific function — pass its arguments as request bindings
const tax = service.execute('calculateTax', { amount: 100, rate: 0.21 });
// { result: 21 }
```

### 执行规则集

```typescript
const service = new DecisionService(`{
    ruleset risk(age: number, income: number): {
        hitPolicy: "first-match"
        rules: [
            { when: { age: 18..25, income: < 30000 }, then: { level: "high",   limit: 1000  } }
            { when: { age: 18..25, income: >= 30000 }, then: { level: "medium", limit: 5000  } }
            { when: { age: > 25 },                     then: { level: "low",    limit: 20000 } }
        ]
        default: { level: "none", limit: 0 }
    }
    decision: risk(age: applicant.age, income: applicant.income)
}`);

const result = service.execute('decision', { applicant: { age: 23, income: 25000 } });
// { level: "high", limit: 1000 }
```

### 处理错误

每个执行或模型错误都是结构化的 `PortableError` - 从来不是普通的弦.

```typescript
import { DecisionService } from '@edgerules/node';
import type { PortableError } from '@edgerules/portable';

try {
  service.execute('unknownField');
} catch (err) {
  const error = err as PortableError;
  console.error(error.type);     // "EntryNotFound"
  console.error(error.message);  // human-readable, safe to surface
  console.error(error.path);     // "unknownField"
}
```

| `error.type` | 含义 |
| --- | --- |
| `EntryNotFound` | 模式中不存在路径 |
| `WrongFieldPath` | 无效路径, 出界数组索引 |
| `Parse` | 表达式字符串分析失败 |
| `Linking` | 类型不匹配或中断的引用 |
| `Execution` | 评价中的运行时间错误 |

* * *

## 可变/ 开发用法

使用 `./mutable` 要访问的子路径导入 `MutableDecisionService`,它添加了 CRUD 操作在行执行后. 这个构件用于IDEs,规则编辑器,以及测试工具- **没有** 用于生产交通.

```typescript
import { MutableDecisionService } from '@edgerules/node/mutable';

const service = new MutableDecisionService(`{
    taxRate: 0.21
    tax: amount * taxRate
}`);

// Read a node enriched with linked type information
const node = service.get('taxRate');
// { "@kind": "expression", "expression": "0.21", "type": "number", "linked": true }

// Update a field at runtime — the engine relinks lazily on the next execute
service.set('taxRate', 0.25);

// Read the entire model snapshot
const model = service.get('*');

// Add a new typed input
service.set('amount', { '@kind': 'placeholder', type: 'number', required: true });

// Remove a field
service.remove('taxRate');

// Rename a field
service.rename('tax', 'vat');

// Read a node as DSL source text instead of Portable JSON
service.getCode('tax');
// 'amount * taxRate'

// Write DSL source text back — returns a PortableNode, not code text
service.setCode('tax', 'amount * taxRate * 2');
```

### `get` 类型

```typescript
import { Kinds } from '@edgerules/node';

// Absent kinds: every declaration, with bodies
service.get('isEligible');

// The method signature only
service.get('isEligible', ['method-interface']);

// The type only, without its facts
service.get('Customer', ['type']);

// A project-explorer view without bodies and expression text
service.get('*', [...Kinds.EXPRESSION_INTERFACES, ...Kinds.TYPES, ...Kinds.INVOCABLE_INTERFACES]);
```

* * *

## API 参考

### `DecisionService`

| 方法 | 说明 |
| --- | --- |
| `new DecisionService(model)` | 从 DSL 字符串或根创建 `PortableContext` |
| `execute(method, args?)` | 评价 `method` (字段路径、功能或 `"*"`)反对选择性要求的约束 |

### `MutableDecisionService` (德文建设)

继承 `execute` 并添加:

| 方法 | 说明 |
| --- | --- |
| `get(path, kinds?)` | 读取节点, 通过过滤 `@kind`· ; `linked` 告诉模型是否链接 |
| `set(path, value)` | 写入表达式、占位符、方法、类型或上下文 |
| `getCode(path)` | 将节点读作 Edge Rules DSL 源文本 |
| `setCode(path, code)` | 从 Edge Rules DSL 源文本中写入节点; 返回 a `PortableNode`代码文本 |
| `remove(path)` | 删除条目 |
| `rename(oldPath, newPath)` | 在上下文中重命名一个条目 |

* * *

## 相关软件包

-   [`@edgerules/web`](https://www.npmjs.com/package/@edgerules/web) ——浏览器使用相同的 API
-   [`@edgerules/portable`](https://www.npmjs.com/package/@edgerules/portable) - 便携式JSON类型定义

## 常见问题

### @edgerules/node 是什么？

边缘规则为Node\.js提供决定服务\.

### 如何安装 @edgerules/node？

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

### @edgerules/node 支持 TypeScript 吗？

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

### @edgerules/node 支持 ESM 还是 CommonJS？

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

### @edgerules/node 可以商用吗？

@edgerules/node 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @edgerules/node 的下载量有多少？

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

### @edgerules/node 还在维护吗？

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

