slop-police 0.3.1 → 0.3.3
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 +21 -14
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -40,9 +40,9 @@ slop-police reads `slop-police.json` from the current directory:
|
|
|
40
40
|
"no-redundant-value-alias": "error",
|
|
41
41
|
"no-single-string-cn": "off",
|
|
42
42
|
"no-pass-through-wrapper": "error",
|
|
43
|
+
"no-duplicate-code": "error",
|
|
43
44
|
"no-duplicate-function": "warn",
|
|
44
45
|
"no-placeholder-comment": "error",
|
|
45
|
-
"no-promise-default-fallback": "error",
|
|
46
46
|
"no-stringified-unknown-error": "warn"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -153,6 +153,26 @@ function parse(input: string) {
|
|
|
153
153
|
}
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
+
### no-duplicate-code
|
|
157
|
+
|
|
158
|
+
Copy-pasted code: at least 50 tokens in a row that repeat earlier code (in the same file or one before it by path) and span at least 10 lines. Tokens are compared by their text, so a renamed variable ends a copy, but comments, formatting, imports and TypeScript-only syntax are left out: code that differs only in its types is still a copy, and repeated types aren't reported. Test files are neither reported nor compared. `// slop-police-ignore no-duplicate-code` above a statement, class member or object property takes it out of the comparison, so it is not reported as a copy or as the original. Options: `minLines` (default `10`, counting every line a copy spans), `minTokens` (default `50`) and `isolate`, folders (relative to the config) that aren't compared with each other, such as packages that can't share code: `["packages/api", "packages/frontend"]`.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
// update-card.ts and delete-card.ts both check the card the same way:
|
|
162
|
+
const userId = ctx.userId;
|
|
163
|
+
assert(userId);
|
|
164
|
+
|
|
165
|
+
const cards = await getCardsWithDeck(ctx.db, [input.id]);
|
|
166
|
+
if (cards.length === 0) {
|
|
167
|
+
throw notFound("Card not found");
|
|
168
|
+
}
|
|
169
|
+
const card = cards[0];
|
|
170
|
+
if (card.deckAuthorId !== userId) {
|
|
171
|
+
throw forbidden("You don't own this card");
|
|
172
|
+
}
|
|
173
|
+
// delete-card.ts:6:5 Lines 6-16 duplicate update-card.ts:6-16
|
|
174
|
+
```
|
|
175
|
+
|
|
156
176
|
### no-duplicate-function
|
|
157
177
|
|
|
158
178
|
A function whose body has the same shape as functions in at least two other files: a helper that was rewritten instead of reused. Shapes ignore the names of parameters and locals and the values of literals, but not the names of what the body calls or reads. Bodies with fewer than 2 statements or 16 syntax nodes, and functions in test files, don't count. Option: `minFiles` (default `3`, at least `2`), the number of files a shape has to appear in.
|
|
@@ -167,19 +187,6 @@ export async function loadUsers(id: string) {
|
|
|
167
187
|
// Function loadUsers has the same body shape as loadPosts (posts.ts:1), loadTeams (teams.ts:1)
|
|
168
188
|
```
|
|
169
189
|
|
|
170
|
-
### no-promise-default-fallback
|
|
171
|
-
|
|
172
|
-
A promise `.catch()` handler that hides the rejection: an empty handler, or one that only returns `null`, `undefined`, `false`, `0`, `""`, `[]` or `{}`, optionally after `console.*` or `logger.*` calls. Only `.catch` on promises and other thenables counts.
|
|
173
|
-
|
|
174
|
-
```ts
|
|
175
|
-
const config = await fetchConfig().catch(() => null); // Promise rejection is replaced with null
|
|
176
|
-
navigator.clipboard.writeText(text).catch(() => {}); // Promise rejection is swallowed by an empty catch handler
|
|
177
|
-
const enabled = await fetchFlag().catch((error) => { // Promise rejection is logged and replaced with false
|
|
178
|
-
console.error("flag load failed", error);
|
|
179
|
-
return false;
|
|
180
|
-
});
|
|
181
|
-
```
|
|
182
|
-
|
|
183
190
|
### no-stringified-unknown-error
|
|
184
191
|
|
|
185
192
|
`error instanceof Error ? error.message : String(error)` (in either order), which flattens a caught value into a string and drops its type, stack and cause. A plain `instanceof Error` check counts when the variable is named `error`, `err`, `e` or `cause`; an `||` of `instanceof` checks counts for any name. A function that does nothing but this conversion, like `getErrorMessage(error)`, is where it belongs and isn't reported; use it instead of repeating the expression.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slop-police",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Type-aware TypeScript linter for the dead code and needless indirection AI agents leave behind",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"node": ">=22.18"
|
|
42
42
|
},
|
|
43
43
|
"optionalDependencies": {
|
|
44
|
-
"slop-police-darwin-arm64": "0.3.
|
|
45
|
-
"slop-police-darwin-x64": "0.3.
|
|
46
|
-
"slop-police-linux-arm64": "0.3.
|
|
47
|
-
"slop-police-linux-x64": "0.3.
|
|
44
|
+
"slop-police-darwin-arm64": "0.3.3",
|
|
45
|
+
"slop-police-darwin-x64": "0.3.3",
|
|
46
|
+
"slop-police-linux-arm64": "0.3.3",
|
|
47
|
+
"slop-police-linux-x64": "0.3.3"
|
|
48
48
|
}
|
|
49
49
|
}
|