ts_config 0.1.2: React-layer carve-outs for JSX arrow returns and *Ref names, knip base trimmed, fromBase64 off
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
file length / file-length (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
palette drift / palette (push) Has been cancelled
shared gate tests / gate unit tests (push) Has been cancelled
ts_config tests / test (push) Has been cancelled
ts_core tests / test (push) Has been cancelled
web_ui tests / test (push) Has been cancelled

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Krzysztof Rudnicki 2026-09-16 22:53:21 +02:00
parent 8f5cd3c5cd
commit ba7ea0926f
7 changed files with 59 additions and 7 deletions

View File

@ -16,7 +16,7 @@ files in three different strictness tiers.
```jsonc
// package.json
"devDependencies": {
"@kuhyx/ts-config": "github:kuhyx/utils#ts_config-v0.1.1&path:/ts_config",
"@kuhyx/ts-config": "github:kuhyx/utils#ts_config-v0.1.2&path:/ts_config",
"eslint": "10.10.0",
"typescript": "6.0.3",
"typescript-eslint": "8.70.0"
@ -51,8 +51,18 @@ export default defineConfig({
});
```
`knip.json`: `{ "extends": "@kuhyx/ts-config/knip" }`. `.jscpd.json`: copy
`jscpd.base.json` (jscpd has no extends). `stryker.config.mjs`:
Knip has no `extends` (its schema rejects the key), so `knip.ts` spreads the
base and adds the repo's entries:
```ts
import type { KnipConfig } from "knip";
import base from "@kuhyx/ts-config/knip" with { type: "json" };
type KnipSettings = Exclude<KnipConfig, (...parameters: never) => unknown>;
const config: KnipSettings = { ...(base as KnipSettings), entry: ["scripts/*.mjs"] };
export default config;
```
`.jscpd.json`: copy `jscpd.base.json` (jscpd has no extends either). `stryker.config.mjs`:
`import { strykerBase } from "@kuhyx/ts-config/stryker"; export default { ...strykerBase };`
## Adopting the alias rule in an existing repo

View File

@ -55,6 +55,12 @@ export const overrides = [
// warns about is for non-ISO strings.
"unicorn/prefer-temporal": "off",
// Same class as prefer-temporal: `Uint8Array.fromBase64` is undefined
// on the Node these repos run (24.x, checked 2026-09-16), so the rule's
// replacement for `Buffer.from(s, "base64")` throws at runtime. Revisit
// when the toolchain gate moves Node past a release that ships it.
"unicorn/prefer-uint8array-base64": "off",
// The domain vocabulary is abbreviated on purpose: `os`, `spdx`, `repo`,
// `env`, `rng` are the names the source data and the maths use, and
// expanding them would obscure the mapping.

View File

@ -48,9 +48,26 @@ export const react = [
{
files: TS_FILES,
rules: {
// Same list as naming.js, minus `ref`: @eslint-react's
// naming-convention-ref-name wants every useRef() named `ref` or
// `*Ref`, and unicorn's `ref -> reference` replacement contradicts it
// on every one. `ref` is React's own word, like `props`.
"unicorn/name-replacements": ["error", { replacements: { props: false, ref: false } }],
// `className` is React's own prop name; in a React codebase the rule
// fires on every styled element and cannot be satisfied.
"unicorn/no-keyword-prefix": "off",
},
},
{
files: ["**/*.tsx", "**/*.jsx"],
rules: {
// `items.map((item) => (<li>…</li>))` is the JSX idiom in every React
// codebase and what Prettier formats to; the rule would rewrite each
// one to `{ return (…); }`, and cannot even autofix the ones with
// multi-line text. It has no option to exempt JSX, so it is off for
// JSX files only -- .ts files keep it.
"unicorn/consistent-arrow-return-style": "off",
},
},
];

View File

@ -1,7 +1,5 @@
{
"$schema": "https://unpkg.com/knip@6/schema.json",
"ignore": ["**/dist/**", "**/coverage/**", "**/*.d.ts"],
"ignoreDependencies": ["@kuhyx/ts-config"],
"ignoreExportsUsedInFile": true,
"rules": {
"binaries": "error",

View File

@ -1,6 +1,6 @@
{
"name": "@kuhyx/ts-config",
"version": "0.1.1",
"version": "0.1.2",
"private": false,
"type": "module",
"description": "The one lint/TypeScript bar every kuhyx TypeScript repo extends: a strict tsconfig base, ESLint flat-config presets (base, react, vitest, playwright, layer boundaries, a fast editor subset), and Knip / jscpd / Stryker bases. Plain JS, no build step -- consumable straight from a git tag.",

View File

@ -26,4 +26,4 @@ export const EXPECTED = {
};
/** Files that must lint clean: proves the presets do not fire on good code. */
export const CLEAN = ["src/mocks/user.ts", "src/utils/helper.ts"];
export const CLEAN = ["src/components/item-list.tsx", "src/mocks/user.ts", "src/utils/helper.ts"];

View File

@ -0,0 +1,21 @@
// Clean: the JSX map idiom with an implicit multi-line return, which the
// React layer exempts from unicorn/consistent-arrow-return-style.
import { useRef } from "react";
export function ItemList({ items }: { readonly items: readonly string[] }): React.JSX.Element {
return (
<ul>
{items.map((item) => (
<li key={item}>
{item}
</li>
))}
</ul>
);
}
/** Clean: a `*Ref` name satisfies both unicorn and @eslint-react. */
export function Focused(): React.JSX.Element {
const inputRef = useRef<HTMLInputElement>(null);
return <input ref={inputRef} />;
}