埃斯林特-插孔-埃利西亚
执行建筑、类型安全、生命周期和性能模式的 ESLint 插件 艾丽西亚.js 应用.
为什么
Elysia是一个流利而以链条为基础的框架,其正确性取决于 登记令, (中文(简体) ), 插件命名, (中文(简体) ), 计划声明,以及 平庸的环境结构解。这些限制大多无法在类型系统中表达出来 — 一个缺失的策略,一个未命名的插件,一个在路由后注册的钩子,或者 new Response() elysia会将所有类型检查都按原地顺序进行.
此插件会将那些不常态在平时固定下来 .
安装
pnpm add -D @boring-stack-pkg/eslint-plugin-elysia @typescript-eslint/parser
用法(平面配置)
// eslint.config.mjs
import tsParser from "@typescript-eslint/parser";
import elysia from "@boring-stack-pkg/eslint-plugin-elysia";
export default [
{
files: ["**/*.ts"],
languageOptions: {
parser: tsParser,
parserOptions: { ecmaVersion: "latest", sourceType: "module" },
},
plugins: { elysia },
rules: elysia.configs.recommended.rules,
},
];
建议的预设使所有十二条规则在 "error"酌情取代个别规则:
rules: {
...elysia.configs.recommended.rules,
"elysia/route-requires-tag": "warn",
"elysia/prefer-static-services": "off",
"elysia/no-direct-error-throw": [
"error",
{ factoryName: "HttpErrors", factoryMethod: "make" }
]
}
规则
| 规则 | 类别 | 说明 |
|---|---|---|
route-requires-schema | 司马 | 每条路线必须至少宣布其中一条 body编号 :query编号 :params编号 :response编号 :headers编号 :cookie。 。 。 . |
route-requires-tag | 公约 | 每条路线都要申报 detail.tags 为斯瓦格分组. |
no-direct-error-throw | 安全(可固定) | 否定 throw new Error(...); 使用打入错误厂. |
portable-schema-types | 安全问题 | 单位 *.schemas.ts,禁止 t.Integer(), (中文(简体) ), t.Tuple() 财务报告和审定财务报表 t.Union(x.map(...)),则OpenAPI客户端无法携带. |
consistent-status-via-set | 公约 | 内部路由处理器, 设置状态通过 set.status = N没有 new Response(body, { status })。 。 。 . |
prefer-destructured-context | 业绩 | 别把整个爱丽西亚传出去 Context - 控制器/服务——在边界拆除结构. |
require-plugin-name | 生命周期 | 导出 new Elysia(...) 实例必须声明 { name: "..." } 为运行时间分解. |
no-separate-model-interfaces | 公约 | 取消重复运行时 schema 形状的 TS 接口; 使用 typeof Schema.static (或等同为一. |
prefer-static-services | 业绩 | 别 new Service() 内部的路由处理器,当该类无国籍. |
require-hooks-before-routes | 生命周期 | 全球悬钩必须在同一情况下的任何路线之前注册——爱丽西亚的瀑布对命令敏感. |
prefer-throw-status | 公约 | 内部的路由处理器,偏好 throw status(...) 试验/捕获 人工反应. |
prefer-direct-return | 业绩 | 直接返回值; 让 Elysia 序列化 。 准备金 new Response(...) 用于流和自定义标题. |
no-decorate-state-collision | 安全问题 | 断开重复的密钥 .decorate() 编号 : .state() 编号 : .derive() 编号 : .resolve() 在一个单一的例子. |
路由- 要求- schema
// ❌
new Elysia().post("/users", create);
// ✅
new Elysia().post("/users", create, {
body: t.Object({ email: t.String() }),
detail: { tags: ["Users"] },
});
需要插件名称
// ❌
export const auth = new Elysia();
// ✅
export const auth = new Elysia({ name: "Auth.Plugin" });
程序前需要呼号
// ❌ onError will not fire for /health
new Elysia().get("/health", () => "ok").onError(handleError);
// ✅
new Elysia().onError(handleError).get("/health", () => "ok");
无解析态- 缩写
// ❌ silent overwrite — second decorate("db", ...) wins
new Elysia({ name: "db" }).decorate("db", a).decorate("db", b);
// ✅
new Elysia({ name: "db" }).decorate("db", buildDb()).state("requestId", "");
关于每个规则的全部选项和QQ/QQ片段,参见 docs/rules/。 。 。 .
设计说明
- 只有AST的设计. 没有
parserServices/ 类型检查器依赖性。 消费者不需要一个parserOptions.project设置。 规则在类型可以提供更多的信息的地方轻而易举地降解——这在"限制"下记录了每个规则 - 家庭联系公约. 镜像
eslint-plugin-module-boundaries财务报告和审定财务报表eslint-plugin-drizzle-conventions: 相同的插件导出形状, 相同的ESLintUtils.RuleCreator工厂 相同的平面配置预设结构 相同的kebab-case规则 ids. - 高压规则是明确的. 没有解析器服务就无法精确化的规则(
prefer-destructured-context, (中文(简体) ),no-separate-model-interfaces, (中文(简体) ),prefer-static-services, (中文(简体) ),prefer-throw-status在规则文件中记录其限制.
发展
pnpm install
pnpm test
pnpm typecheck
pnpm build
释放
标记 a v* 本地版本并按下标签.. .github/workflows/release.yml 运行 pnpm publish --access public 与 NPM_TOKEN。 。 。 .
许可证
麻省理工学院.