@aureienbn/克林特-插座效应
42 oxlint规则的效应代码:运行时边界,故障通道,通币,服务,Schema. 只不过什么 @effect/tsgo 不拥有.
pnpm add -D @aurelienbbn/oxlint-plugin-effect oxlint # oxlint >=1.82.0 <2.0.0
{
"jsPlugins": ["@aurelienbbn/oxlint-plugin-effect"],
"rules": {
"effect/require-all-concurrency": "error",
"effect/require-tagged-effect-fail": "error",
"effect/no-run-promise-in-runtime": ["error", { "allow": ["**/src/main.ts"] }]
}
}
没有预设: 启用每个规则的名称 .
第一个上游, 第二个插件
@effect/tsgo recommended oxlint preset ← enable FIRST, wins every overlap (type-aware)
floating Effects · missing yield* / return yield* · Effect-native globals & JSON
Effect.fn opportunities · try/catch and timers in generators · class Self mismatch
+
withEffectTsgoLayer extras ← @aurelienbbn/oxlint-config; off in recommended
any/unknown in error & requirements channels · unsafe Effect type assertions
deterministic service/error keys · Effect.provide outside entry points
│
▼
@aurelienbbn/oxlint-plugin-effect ← policies and syntactic failure modes tsgo doesn't own
带线的 withEffectTsgoLayer 从 @aurelienbbn/oxlint-config:它添加了四个外加,并在一个表格中解决与这个插件的所有重叠. 注意其版本锁定 : @effect/tsgo 0.45.0只接受牛林1.81.0/1.82.0和牛林-tsgolint 7.0.2001.
| 13条规则被取消 支持tsgo | 拥有者 |
|---|---|
no-floating-effect, (中文(简体) ), no-plain-yield, (中文(简体) ), require-return-on-failure-yield, (中文(简体) ), prefer-effect-fn, (中文(简体) ), no-raw-json-parse, (中文(简体) ), no-raw-json-stringify, (中文(简体) ), no-ambient-nondeterminism | ✅ recommended |
no-effect-type-assertion, (中文(简体) ), no-unsafe-error-channel, (中文(简体) ), matching-identifier | 仅与 withEffectTsgoLayer (或 correctness + 键 style 预设) |
no-nested-layer-provide, (中文(简体) ), no-cascading-layer-provide, (中文(简体) ), use-root-imports | 没有确切的主人 |
取决于类型的结论保持不变 @effect/tsgo。 。 。 . 所有权: docs/rule-ownership.md;目录门执行盘点.
什么火吗
const values = Effect.all(programs); // ❌ require-all-concurrency
const values = Effect.all(programs, { concurrency: 1 }); // ✅ explicit choice
const program = Effect.fail("boom"); // ❌ require-tagged-effect-fail
const program = Effect.fail(new DomainError({ reason })); // ✅ tagged error
const load = (id: string) => Effect.fn(`users.load.${id}`)(body); // ❌ no-dynamic-span-name
const load = Effect.fn("users.load")(body); // ✅ ids go in span attributes
class NotFound extends Schema.TaggedError<NotFound>()("Missing", {}) {} // ❌ tagged-error-name, twice
class NotFoundError extends Schema.TaggedError<NotFoundError>()("NotFoundError", {}) {} // ✅ catchTag greps to the class
const Status = Schema.Literals(["Pending", "partially-refunded"]); // ❌ schema-literal-case, twice
const Status = Schema.Literals(["pending", "partially_refunded"]); // ✅ one case on the wire
// orders/domain/order.ts
export interface Order {
readonly id: OrderId;
} // ❌ schema-domain-types
export const Order = Schema.Struct({ id: OrderId }); // ✅ the schema owns the shape
export type Order = typeof Order.Type;
const Concurrency = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(1))); // ❌ schema-check-branded
const Concurrency = Schema.Int.pipe(Schema.check(Schema.isGreaterThanOrEqualTo(1)), Schema.brand("Concurrency")); // ✅ only make or a decode builds one
const sync = Effect.fn("OrderSync.run")(body); // ❌ telemetry-name-format
const sync = Effect.fn("orders.sync")(body); // ✅ <area>.<operation>, lowercase snake_case
Effect.tryPromise(() => fetch(url)); // ❌ no-untyped-try-promise-catch, require-abort-signal
Effect.tryPromise({
try: (signal) => fetch(url, { signal }),
catch: (cause) => new HttpError({ cause }), // ✅ typed, cause kept, signal forwarded
});
- 货币规则要求明确选择他们不主张省略的货币没有约束.
- 一样
allow路径no-run-promise-in-runtime财务报告和审定财务报表no-unscoped-runtime-launch数字 : 共享边界匹配 . tagged-error-name与tsgo冲突deterministic-keys只有在tsgo的时候keyPatterns获得一个error目标:该目标需要一个符合软件包资格的标签(pkg/file/NotFoundError) (中文(简体) ). 避免出错keyPatterns,或关闭此规则.schema-literal-case保留Schema.Literals([...])数值,默认为蛇 大小写: 他们作为数据旅行(URLs,SQL,日志,电线合同),而蛇-case就是Postgres, Shopify REST(partially_refunded)和条纹(requires_payment_method(a) 使用.Schema.Literal("..."), (中文(简体) ),_tags和非字符串的字句超出了范围。 无修:重命名一线值需要协调改变.schema-domain-types创建一个仅包含Schema的域文件夹 : 内**/domain/**(选项)files),一个接口,一个对象类型(空白,在Readonly<>(a) 在工会或交叉点,报告立体工会或圆柱Schema.Struct, (中文(简体) ),Schema.TaggedStruct, (中文(简体) ),Schema.Union或者说Schema.Literals并获得类型typeof X.Type. 沉默:通用声明、持有行为的声明(方法、功能类型成员)或运行时的手柄(Schema.*, (中文(简体) ),Effect.*, (中文(简体) ),Layer.*, (中文(简体) ),Stream.*成员),命名类型的联盟,以及一个能扩展出一个计划类型的空界面. 不修:计是决定.schema-check-branded在类型中设置域检查 : 当一个值被解码、编码或构建时,检查才运行make,所以没有品牌代码仍然可以写{ concurrency: 0 }内**/domain/**(选项)files页:1Schema.check(...)或者说.check(...)连锁店都没有Schema.brand报告。 一个有线DTO不需要品牌(解码和编码两个都检查),所以规则默认不在其他文件夹中;内置的用法如实使用(英语:Schema.Int, (中文(简体) ),Schema.NonEmptyString不是它看到的检查。 一个只长出(attempts + 1)是通常的例外:压制它在那里.telemetry-name-format想要索引名称为<area>.<operation>小写点蛇 case (单位:千美元)mcp.auth.verify_api_key: 横跨地名,Rpc.make标记和annotateLogs, (中文(简体) ),annotateSpans, (中文(简体) ),annotateCurrentSpan财务报告和审定财务报表withSpan是因为attributes(允许一段:event) (中文(简体) ). 仅字符串;no-dynamic-span-name拥有运行时间名称.telemetry-name-format与logMessages: true将日志消息作为事件名 : 第一个论点是:Effect.log, (中文(简体) ),logTrace, (中文(简体) ),logDebug, (中文(简体) ),logInfo, (中文(简体) ),logWarning, (中文(简体) ),logError财务报告和审定财务报表logFatal(通过)Effect,别名,或从effect/Effect)必须是名称格式的文字,如Effect.logInfo("webhook.rejected", { attempt }),因此日志后端可以搜索并按它数. 变量、带有值或连结的模板也被报告: 值进入后面的参数或Effect.annotateLogs。 。 。 .- 启用
telemetry-name-format或者说effect-fn-name-matches-binding,而不是两者: 约束性规则将最后一段与约束性相联系(const syncAll = Effect.fn("orders.syncAll")),蛇 案例拒绝. - 🎨
dependencies-first, (中文(简体) ),padding-after-dependencies, (中文(简体) ),no-switch, (中文(简体) ),prefer-match, (中文(简体) ),prefer-effect-array-helpers, (中文(简体) ),schema-type-adjacent, (中文(简体) ),schema-literal-case, (中文(简体) ),schema-domain-types, (中文(简体) ),schema-check-branded, (中文(简体) ),tagged-error-name, (中文(简体) ),telemetry-name-format有意见. 在特殊呼叫地点进行镇压,而不是在共享配置中.
按工作划分的44个规则
| 任务 | 规则 |
|---|---|
| 失败(10) | no-catch-all-cause, (中文(简体) ), no-effect-ordie, (中文(简体) ), no-swallowed-failure, (中文(简体) ), no-untyped-try-promise-catch, (中文(简体) ), preserve-thrown-cause, (中文(简体) ), no-unsafe-error-mapper, (中文(简体) ), require-tagged-effect-fail, (中文(简体) ), no-effect-promise, (中文(简体) ), bounded-retry, (中文(简体) ), tagged-error-name 🎨 |
| 运行时间界限(7) | no-run-promise-in-runtime, (中文(简体) ), no-unscoped-runtime-launch, (中文(简体) ), prefer-run-main, (中文(简体) ), no-fork-detach, (中文(简体) ), no-managed-runtime-per-call, (中文(简体) ), prefer-it-effect (可选入,需求) @effect/vitest, (中文(简体) ), no-fake-timers-in-effect-tests |
| * 尸体和追踪(7) | no-unsafe-effect-body, (中文(简体) ), require-named-effect-fn, (中文(简体) ), effect-fn-name-matches-binding, (中文(简体) ), no-dynamic-span-name, (中文(简体) ), telemetry-name-format 🎨, dependencies-first 🎨, padding-after-dependencies 🎨 |
| * 服务层(4) | no-service-constructor-imports, (中文(简体) ), no-service-dependency-parameters, (中文(简体) ), no-service-option, (中文(简体) ), no-static-service-forwarders |
| QQ Schema 配置 (6) | no-schema-any, (中文(简体) ), schema-type-adjacent 🎨, schema-literal-case 🎨, schema-domain-types 🎨, schema-check-branded 🎨, require-redacted-secret-config |
| • 货币(3) | require-all-concurrency, (中文(简体) ), require-for-each-concurrency, (中文(简体) ), require-abort-signal |
| qq 风格(3) | no-switch, (中文(简体) ), prefer-match, (中文(简体) ), prefer-effect-array-helpers |
| qq阵列(4) | no-array-callback-reference, (中文(简体) ), no-array-for-each, (中文(简体) ), no-array-method-this-argument, (中文(简体) ), no-array-sort: 独角兽阵列检查,跳过效果模块(Option.some, (中文(简体) ), Effect.forEach, (中文(简体) ), Arr.sort(中文(简体) ) |
选项和默认
tests =: **/*.{test,spec}.{ts,tsx}。 。 。 .
| 规则 | 选项 | 默认 |
|---|---|---|
no-run-promise-in-runtime | allow | 测试, **/scripts/** |
no-unscoped-runtime-launch | allow | 测试, **/scripts/** |
prefer-run-main | allow | 测试, **/scripts/** |
no-managed-runtime-per-call | allow | 测试, **/scripts/** |
prefer-effect-array-helpers | allow | 测试, **/scripts/** |
ignoredObjects | Array, (中文(简体) ), Arr, (中文(简体) ), Effect, (中文(简体) ), HashMap, (中文(简体) ), HashSet, (中文(简体) ), Match, (中文(简体) ), Option, (中文(简体) ), Record, (中文(简体) ), Schedule, (中文(简体) ), Schema, (中文(简体) ), Stream | |
no-schema-any | allow | 测试, **/fixtures/**, (中文(简体) ), **/scripts/**, (中文(简体) ), tools/** |
no-effect-ordie | allow, (中文(简体) ), allowedCalls | [], (中文(简体) ), [] |
no-effect-promise | allow | [] |
mode | "all" - 或 "rejectable-only" | |
no-fork-detach | allow | [] |
no-swallowed-failure | allowInFinalizers | true |
prefer-it-effect | testFiles | 测试 |
require-abort-signal | abortableCalls | ["fetch"] |
require-redacted-secret-config | secretPattern | (SECRET|PASSWORD|PASSWD|TOKEN|API_?KEY|PRIVATE_?KEY|CREDENTIAL|DATABASE_URL|_DSN$) |
benignPattern | _(TTL|LENGTH|NAME|HEADER|URL_PREFIX|COUNT|ENABLED)$ | |
effect-fn-name-matches-binding | ignorePattern | 无 |
no-service-constructor-imports | serviceModules | 无(项目-当地来源总是计算在内) |
no-service-dependency-parameters | serviceTypeNames | [] |
tagged-error-name | suffix | "Error" |
schema-check-branded | files, (中文(简体) ), allow | ["**/domain/**"],测试和 **/scripts/** |
schema-domain-types | files, (中文(简体) ), allow | ["**/domain/**"],测试和 **/scripts/** |
schema-literal-case | case | "snake" - 或 "kebab", (中文(简体) ), "camel", (中文(简体) ), "pascal" |
telemetry-name-format | pattern | ^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$ (名称) |
minSegments | 2 (dot- 分隔的片段需要名称) | |
keyPattern | ^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$ (注释和属性密钥) | |
logMessages | false· ; true 第一个论点是: Effect.log* 改为名称格式 |
1个自定义, 5个建议
仅 padding-after-dependencies 有一个保留行为重写: 在主要服务依赖关系下插入空白行。 每个其它的固定需要项目知识:出错类型,运行时边界,货币政策,层所有者,追踪名称,平台适配器.
Effect.gen(function* () {
const repo = yield* UserRepo;
const user = yield* repo.findUser(id); // ❌ padding-after-dependencies
});
Effect.gen(function* () {
const repo = yield* UserRepo;
const user = yield* repo.findUser(id); // ✅ dependencies stand apart
});
5个编辑的建议
| 规则 | 建议 |
|---|---|
require-abort-signal | 向上移动 signal 输入 fetch |
effect-fn-name-matches-binding | 将字段重命名为绑定名称 |
no-fork-detach | forkChild → forkScoped 层构造器内部 |
no-swallowed-failure | 添加 { log: true } 改为 Effect.ignore |
require-redacted-secret-config | Config.String 编号 : Config.NonEmptyString → Config.Redacted |
移徙
| 变动 | 为什么 | 现在 |
|---|---|---|
prefer-schema-decode-unknown 删除 | 效果 4 的打出解码器( E)decodeSync, (中文(简体) ), decodeEffect, ) 采取 S["Encoded"]这样 as unknown 输入失败类型检查 ; decodeEither 已经不存在 | effecttsgo/prefer-schema-over-json 报告 JSON.parse, (中文(简体) ), typescript/no-explicit-any 报告 as any从您的配置中删除规则 |
no-unsafe-effect-body 仅保留 throw | 试验/捕获量和全球发电机计时器 effecttsgo/try-catch-in-effect-gen 财务报告和审定财务报表 effecttsgo/global-timers-in-effect (均为 recommended(三); Effect.gen 拒绝 async function* 在检查类型时 | 相同的规则名称,没有配置更改。 ⚠️ try编号 :finally 周围 yield* 无 catch 没有核实的 tsgo 拥有者 |
no-catch-all-cause, (中文(简体) ), no-swallowed-failure 拓宽 | 斯格的车 catch-to-ignore 编号 : catch-to-or-else-succeed 重写导致 Effect.ignoreCause 财务报告和审定财务报表 Effect.orElseSucceed(() => placeholder)默默地通过 | Effect.ignoreCause, (中文(简体) ), Effect.catchDefect 报告 no-catch-all-cause; 占位符 Effect.orElseSucceed 下级 no-swallowed-failure |
合同
| 专题 | 合同 |
|---|---|
| 效果版本 | 行使时间 4.0.0-rc.115; 匹配名称 4.0.0移动 effect/unstable/* 改为 effect/* (两者都承认). 未承诺可互换的效果 3/4 拼写 |
| 进口 | 名称空间和别名导入被确认; 忽略本地阴影 |
| 重叠 | @effect/tsgo类型识别诊断胜出; 定居在 withEffectTsgoLayer |
登记的合同库存
从软件包导出 pnpm catalog. 规则特定选项和限制在上文和源测试中都有描述.
| 规则/检查 | 触发或审查范围 |
|---|---|
bounded-retry | 要求 Effect. 重试同一文件中可见的策略来携带诸如 Schannel 这样的绑定 。 重现, 附表. up 到,时间表。 时间,时间,时间,或直到. |
dependencies-first | Effect bodys中运行时逻辑之前的 Yield 服务依赖性 . |
effect-fn-name-matches-binding | 要求一个 Effect.fn 的上一个点块横跨名称,以等同函数所约束的变量或属性. |
no-array-callback-reference | 忽略向数组方法的回调传递函数引用,跳过对非数组的效应模块的调用 . |
no-array-for-each | 取消对阵# 每一个都赞成..Effect.forEach) (中文(简体) ). |
no-array-method-this-argument | 放弃 thisArg 数组方法,跳过 Effect 的数据第一助手(Arr.filter(xs, f)),其第二个论点是回调. |
no-array-sort | Disallow Array# sort, 它会变异, 倾向于被吸附, 跳过效果的类助手(Arr.sort没有. |
no-catch-all-cause | Disallow Effect. Catch because, catch because Cause Filter, catch Defect, 忽略 Cause, sandbox, Layer. Catch because, and Effect 3 catch All 因为他们有缺陷. |
no-dynamic-span-name | 在 Effect.fn, Effect. with Span 中,使用 Span 、 make Span 、 make Span 、 make Span Copled 、 Layer. with Span 和 Stream. with Span 中,取消带有运行时间值和字符串组合的模板文字. |
no-effect-ordie | Disallow Effect.orDie, Effect.orDieWith, Lailer.orDie, and Effect.catch handers 仅死在所配置的逃生舱外. |
no-effect-promise | Disallow Effect. 保证在外配置文件, 除非Thunk是像"承诺"这样的全策略性承诺. 解析器或只有解析器的定时器. |
no-fake-timers-in-effect-tests | Disallow vi.use FakeTimers,vi.advanceTimers *,vi.run *Timers,以及vi.setSystemTime在导入@effect/vitest;使用TestClock. |
no-fork-detach | Disallow Effect.forkDetach 外部配置的文件和Effect.forkChild 直接在地层构造器内,其中Effect.forkScoped将纤维与地层范围联系起来. |
no-managed-runtime-per-call | Disallow MreamedRuntime. make under controduct file; 在模块范围构建运行时间一次 . |
no-run-promise-in-runtime | Disallow Effect.run Promitise, run PromiseExit, 及其运行* 在已配置的运行时边界以外的变体. |
no-schema-any | 贬斯克马. 任何外部配置的逃生标记文件 . |
no-service-constructor-imports | 拒绝从项目服务目录中将制作前缀导入为运行时代码 . |
no-service-dependency-parameters | 取消服务预测类型,并在参数中配置服务名. |
no-service-option | Disallow Effect. 服务选项,有利于由分层提供所需的服务. |
no-static-service-forwarders | 取消仅转发到效果服务方法的静态类属性. |
no-swallowed-failure | Disallow Effect.ignore 没有日志选项,以及Effect.catch handers 或 Effect. 或ElseSucceed倒计时器将错误丢弃给占位符. |
no-switch | 在效果代码中取消对 Match 的切换语句. |
no-unsafe-effect-body | Disallow srow into Effect.gen, Effect.fn, and Effect.fnUntracted bodys. (原始内容存档于2018-09-28). |
no-unsafe-error-mapper | 排除未知和任何效果错误映射参数 . |
no-unscoped-runtime-launch | Disallow Effect.runFork, runSync, runSyncExit, runCallback, 它们的运行 * 带有变体, 和 Layer. 在已配置的运行时边界外发射 . |
no-untyped-try-promise-catch | 要求 Effect. try and Effect.try 保证用抓取器映射被抛出或拒绝的值 . |
padding-after-dependencies | 在一个 Effect.gen, Effect.fn, 或 Effect.fn 的主要服务依赖关系之后需要一条空白行。 fnUntracted 发电机体,当逻辑跟随它们时. |
prefer-effect-array-helpers | 偏好效果阵列帮助器,而不是本地阵列帮助器方法. |
prefer-it-effect | 偏好它. effect/vitest over Effect.run Promise 或 Effect.runSync into plain it/测试测试文件中的回调(opt-in;需要@effect/vitest). |
prefer-match | 从效果上比起连锁立体立体. |
prefer-run-main | 偏好 NodeRuntime.runMain 或 BunRuntime.runMain 超越模块顶级效果.runPromise 或 Effect.runFork 语句. |
preserve-thrown-cause | 要求效果. try and Effect.try 保证捕捉者使用他们收到的抛出值. |
require-abort-signal | 要求 Effect.try 保证和效果. 保证调用调用调用(或配置的可中止调用)的thunks来接受中止信号参数并传递. |
require-all-concurrency | 需要明确的货币效应. |
require-for-each-concurrency | Effect.fects需要明确的通由. |
require-named-effect-fn | 要求 Effect.fn 调用包含非空名. |
require-redacted-secret-config | 需要配置 。 改编而来,而不是配置。 弦或相接. 非EmptyString用于配置密钥,其名称看起来像一个秘密. |
require-tagged-effect-fail | 对 Effect.fail and Effect.failSync 、 拒绝字节、 本地错误和相同文件未标记错误子类要求标记错误值 . |
schema-check-branded | 需要一个在域文件夹中添加检查的图案来进行品牌化,所以代码通过make构建其值,它运行检查. |
schema-domain-types | 需要宣布域类型为Schemas,由TypeScript类型产生,而不是界面,对象类型,字形结合或enum. |
schema-literal-case | 需要 Schema 的字符串值 。 字形([.])可跟随一例: 蛇入例为默认,或克巴布克克克克克克克克克克克克克克克克克克克克克克克克克克克克. |
schema-type-adjacent | 保留一个Schema的匹配型别名相邻,允许白空和JSDoc. |
tagged-error-name | 需要扩展Schema的课程 。 (原始内容存档于2017-10-21). Tagged Error, Schema. 标记 ErrorClass 或 Data 。 标记 Error 以错误后缀结尾,并使用他们的类名作为字元 tag. |
telemetry-name-format | 需要字面跨度名称、 Rpc. make 标记和(带有日志) 小写点缀蛇 case中的效果日志事件名称至少有两段,小写点缀蛇 case中的注释键. |
信用概念
- 效果捆绑 AGENTS.md “名称字符串应该与函数名称相匹配”(概念)
- 效果捆绑的 AI- docs “ 被紧扣的指数倒置, 并带有紧张和最大尝试” 模式( 概念)
- 效果捆绑的辅助文件
04_integration/10_managed-runtime.ts模块级别运行时间(概念) - 效果捆绑的辅助文件
09_testing/10_effect-tests.ts"用TestClock控制时间"(概念) - 效果捆绑的辅助文件
catch: (cause) => new X({ cause })公约(概念) - OpenTeleometry Tracking API规格,横跨名称指导"最普通的字符串. 低红度"(Apache-2.0,概念)
- 由Sandro Maglione(启发、独立重新执行)自动操作
- 由Dillon Mulroy(麻省理工学院,概念重新实施)
- 斯林特-插孔-独角兽
no-array-callback-reference(MIT;规则概念,独立地重新执行) - 斯林特-插孔-独角兽
no-array-for-each(MIT;规则概念,独立地重新执行) - 斯林特-插孔-独角兽
no-array-method-this-argument(MIT;规则概念,独立地重新执行) - 斯林特-插孔-独角兽
no-array-sort(MIT;规则概念,独立地重新执行) - 由 Rhys Sullivan 执行器, 点缀的蛇 case 跨度和属性名称, 例如
mcp.auth.verify_api_key(MIT,命名风格的灵感)