@onrails/biome-plugin 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/package.json +3 -2
- package/rules/carrier-sinks-need-from.grit +36 -0
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@ Reference the rule files in `biome.json` plugins:
|
|
|
18
18
|
"./node_modules/@onrails/biome-plugin/rules/no-promise-result.grit",
|
|
19
19
|
"./node_modules/@onrails/biome-plugin/rules/no-unsafe-unwrap.grit",
|
|
20
20
|
"./node_modules/@onrails/biome-plugin/rules/no-deprecated-synonyms.grit",
|
|
21
|
-
"./node_modules/@onrails/biome-plugin/rules/fluent-stays-local.grit"
|
|
21
|
+
"./node_modules/@onrails/biome-plugin/rules/fluent-stays-local.grit",
|
|
22
|
+
"./node_modules/@onrails/biome-plugin/rules/carrier-sinks-need-from.grit"
|
|
22
23
|
]
|
|
23
24
|
}
|
|
24
25
|
```
|
|
@@ -31,6 +32,7 @@ Reference the rule files in `biome.json` plugins:
|
|
|
31
32
|
| `no-unsafe-unwrap` | `._unsafeUnwrap()` / `._unsafeUnwrapErr()` calls — use `match` / `resolve` / `yieldResult` instead (error) |
|
|
32
33
|
| `no-deprecated-synonyms` | Deprecated synonyms (`chain`, `fold`, `getOrElse`, `of`, …) — use the canonical names (error, partly fixable) |
|
|
33
34
|
| `fluent-stays-local` | Bare `FluentResult<…>` / `FluentMaybe<…>` type references — broader net than the ESLint rule, see `ENGINE_DIVERGENCES` (error) |
|
|
35
|
+
| `carrier-sinks-need-from` | `JSON.parse` / `structuredClone` / `.json()` output cast to `Result<…>` / `Maybe<…>` without `Result.from` / `Maybe.from`; cast form only, see `ENGINE_DIVERGENCES` (error) |
|
|
34
36
|
|
|
35
37
|
## Fixes
|
|
36
38
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onrails/biome-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Biome GritQL plugin: boundary diagnostics for @onrails/result (Promise<Result<…>>, _unsafeUnwrap*).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"./rules/no-promise-result.grit": "./rules/no-promise-result.grit",
|
|
41
41
|
"./rules/no-unsafe-unwrap.grit": "./rules/no-unsafe-unwrap.grit",
|
|
42
42
|
"./rules/no-deprecated-synonyms.grit": "./rules/no-deprecated-synonyms.grit",
|
|
43
|
-
"./rules/fluent-stays-local.grit": "./rules/fluent-stays-local.grit"
|
|
43
|
+
"./rules/fluent-stays-local.grit": "./rules/fluent-stays-local.grit",
|
|
44
|
+
"./rules/carrier-sinks-need-from.grit": "./rules/carrier-sinks-need-from.grit"
|
|
44
45
|
},
|
|
45
46
|
"scripts": {
|
|
46
47
|
"typecheck": "echo 'noop (grit files only)'",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @onrails/biome-plugin: carrier-sinks-need-from
|
|
2
|
+
//
|
|
3
|
+
// Flag `JSON.parse(…)`, `structuredClone(…)` and `….json()` output cast to
|
|
4
|
+
// `Result<…>` / `Maybe<…>`. Plain data from those sinks has no methods once
|
|
5
|
+
// carriers keep them on a prototype, so the cast lies. Lift with
|
|
6
|
+
// `Result.from` / `Maybe.from` instead.
|
|
7
|
+
//
|
|
8
|
+
// Limitation: matches the direct `as` cast form only. The ESLint rule also
|
|
9
|
+
// follows annotated declarators, carrier-typed returns and parameter defaults,
|
|
10
|
+
// `const` bindings of a sink result, and `res.json<Result<…>>()`; GritQL cannot
|
|
11
|
+
// relate a declarator, return type or binding to its use. Declared in ENGINE_DIVERGENCES
|
|
12
|
+
// (`carrier-sinks-need-from` / `cast-form-only`).
|
|
13
|
+
|
|
14
|
+
engine biome(1.0)
|
|
15
|
+
language js
|
|
16
|
+
|
|
17
|
+
or {
|
|
18
|
+
`$sink as Result<$a, $b>`,
|
|
19
|
+
`$sink as Maybe<$a>`
|
|
20
|
+
} as $t where {
|
|
21
|
+
// the sink call itself (optionally awaited / parenthesized), not any call nested inside it:
|
|
22
|
+
// `Result.from(JSON.parse(raw)) as Result<T, E>` is lifted and must stay quiet
|
|
23
|
+
$sink <: or {
|
|
24
|
+
`JSON.parse($_)`,
|
|
25
|
+
`structuredClone($_)`,
|
|
26
|
+
`$_.json()`,
|
|
27
|
+
`await $_.json()`,
|
|
28
|
+
`($_.json())`,
|
|
29
|
+
`(await $_.json())`
|
|
30
|
+
},
|
|
31
|
+
register_diagnostic(
|
|
32
|
+
span = $t,
|
|
33
|
+
message = "Data from JSON.parse/structuredClone/.json() is typed as Result/Maybe but carries no methods — lift it with Result.from / Maybe.from.",
|
|
34
|
+
severity = "error"
|
|
35
|
+
)
|
|
36
|
+
}
|