@aurelienbn/oxlint-plugin-alchemy (英语)
4 oxlint rules for Alchemy v2(基础设施作为效果):代码,用于进行打字检查和部署,然后因为运行在错误的相位或错误的范围而行为不当.
[注] 释放候选人. 已核对
alchemy2.0.0-β.79 (英语). 还没有消费者校正过.
pnpm add -D @aurelienbbn/oxlint-plugin-alchemy oxlint # oxlint >=1.82.0 <2.0.0
{
"jsPlugins": ["@aurelienbbn/oxlint-plugin-alchemy"],
"rules": {
"alchemy/config-in-init": "error",
"alchemy/no-disposable-in-instance-scope": "error",
"alchemy/worker-env-secret-literal": "error",
"alchemy/workflow-io-outside-task": "error"
}
}
无预设. 无自定义 : 每个定律都需要一个选择(在读取值的地方,资源生活的地方,步骤的名称),所以每个规则只报告.
什么火吗
export default Cloudflare.Worker(
"Api",
{ main: import.meta.url, env: { STRIPE_SECRET: "sk_live_..." } }, // ❌ worker-env-secret-literal: bound as plain_text
Effect.gen(function* () {
const pool = yield* Effect.acquireRelease(openPool, close); // ❌ no-disposable-in-instance-scope: never released on workerd
const apiKey = yield* Config.Redacted("API_KEY"); // ✅ read in the init, so Alchemy binds it
return {
fetch: Effect.gen(function* () {
const host = yield* Config.String("HOST"); // ❌ config-in-init: never bound, missing at runtime
const again = yield* Config.Redacted("API_KEY"); // ✅ already bound by the init
}),
};
}),
);
export class Sync extends Cloudflare.Workflow<Sync>()(
"Sync",
Effect.gen(function* () {
const kv = yield* Cloudflare.KV.ReadWriteNamespace(KV);
return Effect.fn(function* (input: { id: string }) {
yield* kv.put(input.id, "started"); // ❌ workflow-io-outside-task: runs again on every replay
yield* Cloudflare.Workflows.task("store", kv.put(input.id, "done")); // ✅ checkpointed
});
}),
) {}
每项规则的确切触发因素和范围
| 规则 | * 开火 | 匹配/ QQ 跳过 |
|---|---|---|
config-in-init | Config.<constructor>(..., "KEY") (单位:千美元)String, (中文(简体) ), Redacted, (中文(简体) ), Number, (中文(简体) ), Port, (中文(简体) ), schema,...; 效果 3 小写名称也)在 init 中返回的内容(内含,或 const Effect.gen 编号 : Effect.fn 通过引用返回的处理器:处理器、 RPC 方法、 持久对象实例效应、 工作流程正文 | qq 密钥也在内或内读 env 同一声明的道具, 值为输入 yield*s 在返回对象内部或运行本身(yield* warmup),非升键 |
no-disposable-in-instance-scope | Effect.acquireRelease, (中文(简体) ), Effect.acquireDisposable, (中文(简体) ), Effect.addFinalizer 最近的函数是运行时的 init 生成器,或者每个对象的构造器 持久对象 init 返回 | * 处理者和方法(活动范围) Effect.scoped(...), (中文(简体) ), Effect.acquireUseRelease (释放自己),助手功能 |
worker-env-secret-literal | 非空字符串文字,模板文字, process.env.X,或一个 ?? 编号 : || 倒置一个,作为云花板工人中密钥的值 env 道具 | 匹配密钥 secretPattern (默认) SECRET, (中文(简体) ), TOKEN, (中文(简体) ), PASSWORD, (中文(简体) ), API_KEY, (中文(简体) ), PRIVATE_KEY, (中文(简体) ), DSN, (中文(简体) ), DATABASE_URL,(......)而不是(......) benignPattern (默认) PUBLIC, (中文(简体) ), PUBLISHABLE, (中文(简体) ), _TTL, (中文(简体) ), _NAME, . . ) ⏭️ Config.*, (中文(简体) ), Redacted.make, (中文(简体) ), "" |
workflow-io-outside-task | 调用方法 const x = yield* <Alchemy binding> (任何从 alchemy/*直接由Workflow机构制作的Workflow int.(Effect.fn(...), (中文(简体) ), Effect.fn(name)(...),或箭头返回 Effect.gen(中文(简体) ) | 里面有电话 Cloudflare.Workflows.task(...) 参数(效果和回滚),调用嵌入式函数,接收器来自您自己的服务 |
运行时间在战术上得到承认: Cloudflare.Worker, (中文(简体) ), Cloudflare.DurableObject, (中文(简体) ), Cloudflare.Workflow 财务报告和审定财务报表 AWS.Lambda.Function,调用内线(X(id, props, init)),类别形式(X<Self>()(id, props, init)),或作为 Tag.make(props, init) 在同一文件中声明的标签类。 输入必须写为 Effect.gen(...) 或者说 Effect.succeed(...)可选的管道.
限制
- 单文件视图. 由另一个文件所建的、通过标识符传递的或由图层构成的索引是无形的。 A 类
Tag.make在从另一个文件导入的标签上不被识别. config-in-init假阳性 : 报告受不同声明约束的密钥(图层,工作流的主机工人)。 压制行,或读 键在这个init.workflow-io-outside-task故意缩小: 只有直接通话yield*炼金术绑定; I/O 通过您自己的服务或助手功能不被看到.- 其他炼金平台 (ECS, Containers, Railway, Fly,.)不被承认:他们的镜形语义不同(服务器在优雅的出道上运行最终确定器).
没有运出,谁拥有它
| 关切 | 拥有者 |
|---|---|
秘密名称 Config.String 改为 Config.Redacted | effect/require-redacted-secret-config 内 @aurelienbbn/oxlint-plugin-effect |
Date.now(), (中文(简体) ), Math.random()效果 | @effect/tsgo (单位:千美元)global-date*, (中文(简体) ), global-random*, (中文(简体) ), global-timers-in-effect(中文(简体) ) |
本地语言 WorkflowEntrypoint 决定主义,秘密比较 | @aurelienbbn/oxlint-plugin-cloudflare |
具有约束力的存在, Env 类型、部署有效性 | 炼金术本身的类型和 alchemy deploy |
资信: 每个规则都独立执行由Alchemy所记录的行为(alchemy-run/alchemy,Apache-2.0):Secrets & Config, runtime(Intance size vs request size), Cloudflare Workers) env 绑定, Cloudflare Workflows 重放语义; 没有文档文本或代码复制 .
登记的合同库存
从软件包导出 pnpm catalog. 规则特定选项和限制在上文和源测试中都有描述.
| 规则/检查 | 触发或审查范围 |
|---|---|
config-in-init | 要求处理器、 持久对象实例或由 Alchemy runtime init 返回的工作流程正文中读取效果/ 压缩密钥, 也可以在 init 本身中读取, 在部署时, Alchemy 将它们绑起 . |
no-disposable-in-instance-scope | Forbid Effect.access Release, Effect.access Disposable and Effect. 在其返回的处理器之外,在Alchemy runtime init(Cloudflare Worker,持久对象,工作流量,AWS Lambda函数)中直接添加最终处理器. |
worker-env-secret-literal | Forbid 字符串字元,模板字元和进程. env读取为密名密钥(SECRET,TOKEN,PASSWORD,API KEY,DSN,.)在一个Alchemy Cloudflare Worker的内嵌道具中被用Config绑定. 已编辑或已编辑值 . |
workflow-io-outside-task | 要求在Cloudflare Workflow init(KV, R2, D1, 持久对象. )中使用Alchemy生成的装订方式。 Workflow.task () 直接在 Workflow 机体中完成 . |
信用概念
- https://alchemy.run/cloudflare/compute/ 工人(英语: (化学管理/化学文献和Cloudflare/工人/工人.ts)
envJSDoc, Apache-2.0;灵感,独立执行) - https://alchemy.run/cloudflare/compute/workflows (中文(简体) ) (alchemy-runy/alchemy docs,Apache-2.0;灵感,独立实施)
- https://alchemy.run/environments/secrets (中文(简体) ) (alchemy-runy/alchemy docs,Apache-2.0;灵感,独立实施)
- https://alchemy.run/information-as-effects/runtime (英语) (alchemy-runy/alchemy docs,Apache-2.0;灵感,独立实施)