@venizia/dev-configs 0.4.8-1 → 0.4.8-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 +64 -16
- package/dist/cli/codemod/async-style.d.ts +2 -2
- package/dist/cli/codemod/async-style.js +4 -2
- package/dist/cli/codemod/async-style.js.map +1 -1
- package/dist/cli/codemod/namespace-functions/rewriter.js +1 -1
- package/dist/cli/codemod/namespace-functions/rewriter.js.map +1 -1
- package/dist/linters/eslint.js +6 -1
- package/dist/linters/eslint.js.map +1 -1
- package/dist/linters/house/async-rules.d.ts +1 -1
- package/dist/linters/house/async-rules.js +3 -1
- package/dist/linters/house/async-rules.js.map +1 -1
- package/dist/linters/house/index.d.ts +1 -0
- package/dist/linters/house/index.js +1 -0
- package/dist/linters/house/index.js.map +1 -1
- package/dist/linters/house/no-await-new-chain.rule.d.ts +37 -0
- package/dist/linters/house/no-await-new-chain.rule.js +177 -0
- package/dist/linters/house/no-await-new-chain.rule.js.map +1 -0
- package/dist/linters/house/plugin.js +2 -0
- package/dist/linters/house/plugin.js.map +1 -1
- package/dist/linters/oxlint.d.ts +6 -5
- package/dist/linters/oxlint.js +8 -3
- package/dist/linters/oxlint.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ it as a dev dependency in an application that wants the same rules.
|
|
|
9
9
|
bun add -d @venizia/dev-configs oxlint oxlint-tsgolint eslint typescript
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
`oxlint` (>=1.
|
|
12
|
+
`oxlint` (>=1.89.0), `oxlint-tsgolint` (>=7.0.2004), `eslint` (9 or 10),
|
|
13
13
|
`typescript` (5 or 6) are optional peers. Install only the tools you use. Formatting is `bun fmt` (Bun 1.4.4 or newer), set in `bunfig.toml`: see [Formatting](#formatting). Keep the
|
|
14
14
|
ESLint config `.mjs`: a TypeScript one (`.mts`) makes ESLint require `jiti`, one more dependency. A
|
|
15
15
|
project that only wants the full ESLint preset installs `eslint` and skips the oxc tools.
|
|
@@ -95,19 +95,21 @@ Every IGNIS package and example does.
|
|
|
95
95
|
| Flag | Base value | Why |
|
|
96
96
|
| :--- | :--- | :--- |
|
|
97
97
|
| `experimentalDecorators` | `true` | `@inject`, `@controller`, `@repository` and the other decorators need it |
|
|
98
|
-
| `emitDecoratorMetadata` | `true` | Optional - restate it only if your code reads `design:*` metadata. IGNIS reads `design:paramtypes` once, to validate a `@repository` constructor, and skips the check when the metadata is absent. Under Bun it turns an interface-typed constructor parameter into a runtime import (`Export named 'X' not found`), so import such names with `import type`; `
|
|
98
|
+
| `emitDecoratorMetadata` | `true` | Optional - restate it only if your code reads `design:*` metadata. IGNIS reads `design:paramtypes` once, to validate a `@repository` constructor, and skips the check when the metadata is absent. Under Bun it turns an interface-typed constructor parameter into a runtime import (`Export named 'X' not found`), so import such names with `import type`; `bun check` (TS1272; the base tsconfig sets `isolatedModules`) finds most of them, loading `src/index.ts` under Bun the rest |
|
|
99
99
|
| `useDefineForClassFields` | `false` | Class fields are assigned, not defined, so a subclass field initializer does not shadow a value the base constructor set |
|
|
100
100
|
|
|
101
101
|
## Entry points
|
|
102
102
|
|
|
103
103
|
| Entry point | What it gives |
|
|
104
104
|
| :--- | :--- |
|
|
105
|
-
| `@venizia/dev-configs` |
|
|
105
|
+
| `@venizia/dev-configs` | `/compilers` and `/linters`, re-exported. Not `/checks` or `/testing` |
|
|
106
106
|
| `@venizia/dev-configs/compilers` | `BunCompiler` |
|
|
107
107
|
| `@venizia/dev-configs/testing` | `RejectionHelper` (`rejectionOf`, `expectRejection`), `SpawnHelper` (`spawnSyncBounded`), `RepoTmp` (`findRoot`, `apply`) - test helpers (imports `bun:test`; tests only) |
|
|
108
|
-
| `@venizia/dev-configs/
|
|
108
|
+
| `@venizia/dev-configs/testing/tmpdir-preload` | A bunfig test preload: a bare `bun test` keeps its temp folders in the repository (calls `RepoTmp.apply()`) |
|
|
109
|
+
| `@venizia/dev-configs/checks` | The engines behind `devz check <name>`: catalog, module cycles, purity, split report and the test-trimming checks. Bun-only tooling, never import it from browser code |
|
|
110
|
+
| `@venizia/dev-configs/linters` | `oxlintConfigs`, `OxlintConfigs`, `BrowserOxlintConfigs`, `ReactOxlintConfigs`, `LintIgnore`, `namingConventionConfigs`, `reactNamingConventionConfigs`, `houseConfigs`, `reactHouseConfigs`, `eslintConfigs`, `paddingConfigs`, the rule classes and their types |
|
|
109
111
|
| `@venizia/dev-configs/linters/oxlint` | `oxlintConfigs`, `OxlintConfigs`, `IOxlintPresetOptions`, `BrowserOxlintConfigs`, `ReactOxlintConfigs`, `LintIgnore`, the rule classes and their types: everything an oxlint config needs, and nothing that loads ESLint. Loads in milliseconds: `/linters` also loads ESLint and its plugins, which an oxlint config never uses |
|
|
110
|
-
| `@venizia/dev-configs/tsconfig.base.json` | Target and lib ES2025, `module`
|
|
112
|
+
| `@venizia/dev-configs/tsconfig.base.json` | Target and lib ES2025, `module` esnext with `moduleResolution` bundler, strict mode (`noImplicitAny` and `useUnknownInCatchVariables` on) with `strictPropertyInitialization` off (DI-injected properties have no initializer), `noEmitOnError`, tests excluded |
|
|
111
113
|
| `@venizia/dev-configs/tsconfig.common.json` | Extends the base and restates `module` as `esnext` and `moduleResolution` as `bundler` |
|
|
112
114
|
| `@venizia/dev-configs/tsconfig.browser.json` | Extends the base for a browser library built with a bundler: `module` ESNext, `moduleResolution` bundler, lib ES2025 + `DOM` + `DOM.Iterable`, `types: []` so no Bun types reach `dist` |
|
|
113
115
|
| `@venizia/dev-configs/tsconfig.react.json` | Extends `tsconfig.browser.json` and sets `jsx: react-jsx` |
|
|
@@ -123,7 +125,7 @@ Every IGNIS package and example does.
|
|
|
123
125
|
becomes a runtime import when Bun runs a decorated class's source, and loading fails with
|
|
124
126
|
`Export named 'X' not found`. `oxlint --fix` rewrites them.
|
|
125
127
|
|
|
126
|
-
oxlint
|
|
128
|
+
oxlint does not read decorator metadata, so it also rewrites the import of a decorated
|
|
127
129
|
constructor parameter's class to `import { type X }`. tsc then emits `Function` (or `Object` under Bun)
|
|
128
130
|
as that parameter's `design:paramtypes` entry. IGNIS never injects by that entry - `@inject` names its
|
|
129
131
|
key, and `@repository` skips `Object` and `Function` - so nothing breaks. Code that does read
|
|
@@ -142,9 +144,10 @@ Not ported:
|
|
|
142
144
|
|
|
143
145
|
#### lenientFallback
|
|
144
146
|
|
|
145
|
-
`prefer-nullish-coalescing` flags `||` on
|
|
146
|
-
`
|
|
147
|
-
|
|
147
|
+
`prefer-nullish-coalescing` flags `||` on a nullable left side, because `||` also swallows a real `0`
|
|
148
|
+
or `false`. `||` on a string is allowed in every preset: `opts.name?.trim() || 'guest'` is an
|
|
149
|
+
intentional empty-string fallback, and `??` would keep the `''`. A project where `0` falls back on
|
|
150
|
+
purpose too opts in with one line:
|
|
148
151
|
|
|
149
152
|
```ts
|
|
150
153
|
// .configs/lints/oxlint.config.mts
|
|
@@ -160,8 +163,9 @@ booleans. `BrowserOxlintConfigs.create()` and `ReactOxlintConfigs.create()` take
|
|
|
160
163
|
|
|
161
164
|
### houseConfigs and the house rules
|
|
162
165
|
|
|
163
|
-
`houseConfigs` is `namingConventionConfigs` plus the house rules oxlint cannot express
|
|
164
|
-
|
|
166
|
+
`houseConfigs` is `namingConventionConfigs` plus the house rules oxlint cannot express, the four async style rules
|
|
167
|
+
and the blank-line padding rules (`paddingConfigs`, below); `reactHouseConfigs` is the same over
|
|
168
|
+
`reactNamingConventionConfigs`, plus the React rules. The house rules ship as the ESLint plugin
|
|
165
169
|
`houseEslintPlugin`, registered as `venizia`:
|
|
166
170
|
|
|
167
171
|
| Class | Rule | Default | What it enforces |
|
|
@@ -176,10 +180,25 @@ booleans. `BrowserOxlintConfigs.create()` and `ReactOxlintConfigs.create()` take
|
|
|
176
180
|
with `[ConstClassValuesRule.NAME]: ConstClassValuesRule.build({ severity: 'error' })`. The 5-parameter
|
|
177
181
|
limit (V-C-02) is `venizia/max-params-own`, an error.
|
|
178
182
|
|
|
183
|
+
#### Blank-line padding
|
|
184
|
+
|
|
185
|
+
`paddingConfigs` holds two `@stylistic` rules, both `error`, on `.ts`, `.tsx`, `.mts` and `.cts` files.
|
|
186
|
+
`houseConfigs`, `reactHouseConfigs` and `eslintConfigs` carry it. It has no parser of its own: it rides on the
|
|
187
|
+
TypeScript parser of `namingConventionConfigs` or `eslintConfigs`. oxlint has none of these rules, so a
|
|
188
|
+
project that lints with oxlint alone gets no padding check. `devz lint --fix` writes the blank lines.
|
|
189
|
+
|
|
190
|
+
| Rule | What it enforces |
|
|
191
|
+
| :--- | :--- |
|
|
192
|
+
| `@stylistic/padding-line-between-statements` | A blank line after the imports (none needed between two imports), before a `return`, and around a block-like statement (a statement that ends in a block, such as `if`, `for`, `while`, `switch`, `try`, a function declaration or a bare block). Stacked `case` and `default` labels stay together |
|
|
193
|
+
| `@stylistic/lines-between-class-members` | A blank line between class members, except after a one-line member, so a run of one-line properties stays together |
|
|
194
|
+
|
|
195
|
+
Turn one off after the preset with `'off'`. See the
|
|
196
|
+
[changelog](https://ignis.venizia.ai/changelogs/2026-11-04-blank-line-padding-rules).
|
|
197
|
+
|
|
179
198
|
### namingConventionConfigs
|
|
180
199
|
|
|
181
200
|
`namingConventionConfigs` (type `Linter.Config[]`) sets only `@typescript-eslint/naming-convention`, with
|
|
182
|
-
its
|
|
201
|
+
its 16 selectors. It targets `.ts`, `.tsx`, `.mts` and `.cts`, and ignores `dist`, `build`,
|
|
183
202
|
`coverage`, `*.d.ts` and plain JavaScript. ESLint does not report unused disable comments in this
|
|
184
203
|
config, because oxlint owns the other rules.
|
|
185
204
|
|
|
@@ -239,9 +258,8 @@ flavor = "oxfmt"
|
|
|
239
258
|
|
|
240
259
|
### eslintConfigs
|
|
241
260
|
|
|
242
|
-
`eslintConfigs`
|
|
243
|
-
|
|
244
|
-
conventions, `curly`, plus these IGNIS rules (the node-protocol check runs in `oxlintConfigs` only):
|
|
261
|
+
`eslintConfigs` is the full ESLint preset: ESLint recommended, typescript-eslint, naming
|
|
262
|
+
conventions, `curly`, the padding rules, plus these IGNIS rules (the node-protocol check runs in `oxlintConfigs` only):
|
|
245
263
|
|
|
246
264
|
| Rule | Setting |
|
|
247
265
|
| :--- | :--- |
|
|
@@ -289,7 +307,13 @@ table above, as strict as the base. `react/no-deprecated` is left out: oxlint ha
|
|
|
289
307
|
Both React presets run the same fifteen `jsx-a11y` rules, including the six that need a human
|
|
290
308
|
decision (`click-events-have-key-events`, `no-static-element-interactions`,
|
|
291
309
|
`no-noninteractive-element-interactions`, `label-has-associated-control`, `heading-has-content`,
|
|
292
|
-
`anchor-is-valid`). `reactHouseConfigs` adds
|
|
310
|
+
`anchor-is-valid`). `reactHouseConfigs` adds three house rules oxlint has no port of:
|
|
311
|
+
|
|
312
|
+
| Rule | What it enforces |
|
|
313
|
+
| :--- | :--- |
|
|
314
|
+
| `venizia/no-leaked-render` | See the table above. On JSX files |
|
|
315
|
+
| `venizia/no-async-hook-callback` | A hook never gets an async function. On all source files |
|
|
316
|
+
| `venizia/effect-cleanup-consistency` | An effect callback returns a cleanup on every path or on none. On all source files |
|
|
293
317
|
|
|
294
318
|
The presets start strict. An application that wants less overrides the rule after the preset:
|
|
295
319
|
|
|
@@ -360,6 +384,30 @@ await BunCompiler.compile({
|
|
|
360
384
|
});
|
|
361
385
|
```
|
|
362
386
|
|
|
387
|
+
## The devz command
|
|
388
|
+
|
|
389
|
+
The package installs a `devz` binary. Run `devz --help` for the list, and `devz clean --help`,
|
|
390
|
+
`devz check --help` or `devz codemod --help` for the options of one command. A usage error in a command exits 2.
|
|
391
|
+
|
|
392
|
+
| Command | What it does |
|
|
393
|
+
| :--- | :--- |
|
|
394
|
+
| `devz lint [--fix] [files]` | Runs oxlint, ESLint and `bun fmt` from `.configs/lints/` and `.configs/formatters/.ignore`, and stops at the first tool that fails. With no file it checks the project; with files it handles only those, as a pre-commit hook passes them. `--fix` writes |
|
|
395
|
+
| `devz check purity --claims <file> [package] [--json]` | Probes every entry claimed browser-pure. Needs a build |
|
|
396
|
+
| `devz check module-cycles <dir> [--max <n>]` | Lists the import cycles of a built ESM folder; exits 1 when there are more than `--max` |
|
|
397
|
+
| `devz check split-report [--dist <dir>] [folder...]` | Reports hub files, stray types, missing barrels, long files and cycles. Never a gate |
|
|
398
|
+
| `devz check catalog [--glob <pattern>]... [--pinned <file>]... [--preset-prefix <prefix>]` | Guards dependency ranges against the root `workspaces.catalog` |
|
|
399
|
+
| `devz clean` | Removes `dist`, `node_modules/.cache` and the `*.tsbuildinfo` files next to the tsconfig. It takes no argument |
|
|
400
|
+
| `devz codemod <name> [paths...]` | Rewrites source files. A dry run unless `--write`; `--check` exits 1 while a rewrite remains |
|
|
401
|
+
|
|
402
|
+
`devz check` also runs the four tools of the test-trimming method: `test-weight`, `test-dead-code`,
|
|
403
|
+
`test-mutate` and `test-controls`.
|
|
404
|
+
|
|
405
|
+
The codemods are `drop-redundant-casts` (removes `as X` casts the compiler no longer needs),
|
|
406
|
+
`const-classes` (turns a string-literal union into a const class), `async-style` (applies the async style
|
|
407
|
+
fixers and lists the rest), `namespace-functions` (moves calls of a function that moved into a class to the
|
|
408
|
+
class form) and `connector-imports` (moves `@venizia/ignis/<connector sub-path>` imports to
|
|
409
|
+
`@venizia/ignis-connectors`).
|
|
410
|
+
|
|
363
411
|
## Where it sits
|
|
364
412
|
|
|
365
413
|
The root of the chain, with no IGNIS dependency: **dev-configs** -> inversion -> {filter, helpers}
|
|
@@ -48,12 +48,12 @@ export declare class AsyncStyle {
|
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,
|
|
51
|
-
* `no-return-await` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.
|
|
51
|
+
* `no-return-await`, `no-await-new-chain` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.
|
|
52
52
|
* It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would
|
|
53
53
|
* change or is left unfixed.
|
|
54
54
|
*/
|
|
55
55
|
export declare class AsyncStyleCommand {
|
|
56
|
-
static readonly USAGE = "Usage: devz codemod async-style [paths...] [--write | --check]\n\nApplies the fixers of
|
|
56
|
+
static readonly USAGE = "Usage: devz codemod async-style [paths...] [--write | --check]\n\nApplies the fixers of four house lint rules, so a repository can sweep them without a lint pass:\n\n venizia/no-inline-await `expect(await f())` becomes `const result = await f(); expect(result)`\n venizia/no-return-await `return await f()` becomes `return f()` (`const result = await f(); return result;` in a try)\n venizia/no-await-new-chain `await new Runner(options).run()` becomes\n `const runner = new Runner(options); await runner.run();`\n venizia/no-await-promise-chain `const x = await f().catch(() => null)` becomes\n `let x; try { x = await f(); } catch (error) { x = null; }`\n\nIt changes only what the fixers can change safely, and lists the rest with its file, line and rule:\nan `await` inside a ternary or logical operand, a loop test, an unbraced `if` branch, or after a call\nthat may have effects; an awaited `.then` or `.finally`, a `.catch` whose handler has a block body or\ncalls something, and an awaited chain that is not the whole initializer of a `const` or `let`; and\nevery venizia/no-silent-catch finding (a handler or catch block that swallows the error), which it never\nfixes: what to log is your decision.\n\n --write write the changed files (without it, nothing is written)\n --check dry run that exits 1 when anything would change or is left unfixed (for CI)\n --all with --write and no path: rewrite every source file under the working directory (--write needs a path or --all)\n --help print this text and exit\n\nWith no flag it lists what would change and writes nothing. Inside a git repository it reads the\nfiles git knows (tracked, or untracked and not ignored), and --write refuses a file with local changes\n(changed, staged or untracked): commit or stash it first, so git can undo the codemod.";
|
|
57
57
|
static run(opts: {
|
|
58
58
|
root: string;
|
|
59
59
|
args: string[];
|
|
@@ -6,10 +6,12 @@ const node_path_1 = require("node:path");
|
|
|
6
6
|
const files_1 = require("./files");
|
|
7
7
|
const USAGE = `Usage: devz codemod async-style [paths...] [--write | --check]
|
|
8
8
|
|
|
9
|
-
Applies the fixers of
|
|
9
|
+
Applies the fixers of four house lint rules, so a repository can sweep them without a lint pass:
|
|
10
10
|
|
|
11
11
|
venizia/no-inline-await \`expect(await f())\` becomes \`const result = await f(); expect(result)\`
|
|
12
12
|
venizia/no-return-await \`return await f()\` becomes \`return f()\` (\`const result = await f(); return result;\` in a try)
|
|
13
|
+
venizia/no-await-new-chain \`await new Runner(options).run()\` becomes
|
|
14
|
+
\`const runner = new Runner(options); await runner.run();\`
|
|
13
15
|
venizia/no-await-promise-chain \`const x = await f().catch(() => null)\` becomes
|
|
14
16
|
\`let x; try { x = await f(); } catch (error) { x = null; }\`
|
|
15
17
|
|
|
@@ -162,7 +164,7 @@ class AsyncStyle {
|
|
|
162
164
|
exports.AsyncStyle = AsyncStyle;
|
|
163
165
|
/**
|
|
164
166
|
* `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,
|
|
165
|
-
* `no-return-await` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.
|
|
167
|
+
* `no-return-await`, `no-await-new-chain` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.
|
|
166
168
|
* It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would
|
|
167
169
|
* change or is left unfixed.
|
|
168
170
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-style.js","sourceRoot":"","sources":["../../../src/cli/codemod/async-style.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport type { Linter } from 'eslint';\nimport { CodemodFiles } from './files';\n\nconst USAGE = `Usage: devz codemod async-style [paths...] [--write | --check]\n\nApplies the fixers of three house lint rules, so a repository can sweep them without a lint pass:\n\n venizia/no-inline-await \\`expect(await f())\\` becomes \\`const result = await f(); expect(result)\\`\n venizia/no-return-await \\`return await f()\\` becomes \\`return f()\\` (\\`const result = await f(); return result;\\` in a try)\n venizia/no-await-promise-chain \\`const x = await f().catch(() => null)\\` becomes\n \\`let x; try { x = await f(); } catch (error) { x = null; }\\`\n\nIt changes only what the fixers can change safely, and lists the rest with its file, line and rule:\nan \\`await\\` inside a ternary or logical operand, a loop test, an unbraced \\`if\\` branch, or after a call\nthat may have effects; an awaited \\`.then\\` or \\`.finally\\`, a \\`.catch\\` whose handler has a block body or\ncalls something, and an awaited chain that is not the whole initializer of a \\`const\\` or \\`let\\`; and\nevery venizia/no-silent-catch finding (a handler or catch block that swallows the error), which it never\nfixes: what to log is your decision.\n\n --write write the changed files (without it, nothing is written)\n --check dry run that exits 1 when anything would change or is left unfixed (for CI)\n --all with --write and no path: rewrite every source file under the working directory (--write needs a path or --all)\n --help print this text and exit\n\nWith no flag it lists what would change and writes nothing. Inside a git repository it reads the\nfiles git knows (tracked, or untracked and not ignored), and --write refuses a file with local changes\n(changed, staged or untracked): commit or stash it first, so git can undo the codemod.`;\n\n/** A usage error: nothing was read or written. */\nconst USAGE_ERROR_CODE = 2;\n\n/** A file that can hold an `await` or a `catch`. */\nconst ASYNC_TEXT = /\\b(await|catch)\\b/;\n\nclass AsyncStyleFlags {\n static readonly WRITE = '--write';\n static readonly CHECK = '--check';\n static readonly ALL = '--all';\n static readonly HELP = '--help';\n static readonly HELP_SHORT = '-h';\n\n static readonly SCHEME_SET = new Set<string>([\n this.WRITE,\n this.CHECK,\n this.ALL,\n this.HELP,\n this.HELP_SHORT,\n ]);\n\n static isValid(value: string): boolean {\n return this.SCHEME_SET.has(value);\n }\n}\n\nexport interface IAsyncStyleReport {\n line: number;\n column: number;\n /** The rule id, or `undefined` for a file ESLint could not parse. */\n ruleId: string | null;\n message: string;\n}\n\nexport interface IAsyncStyleResult {\n output: string;\n changed: boolean;\n /** How many findings of the original source carried a fix, once the fixers changed it. */\n fixes: number;\n /** What is still reported after every pass. */\n reports: IAsyncStyleReport[];\n}\n\n/** Runs the async-style rules, and only those, over source text with ESLint's own fixer loop. */\nexport class AsyncStyle {\n /** The `Linter` config: the TypeScript parser and the rules of `asyncRuleConfigs`, at error. */\n static async createConfig(): Promise<Linter.Config[]> {\n const { default: tseslint } = await import('typescript-eslint');\n const { asyncRuleConfigs } = await import('../../linters/house/async-rules.js');\n\n return [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser },\n // Only the async-style rules run here, so a `// eslint-disable-next-line` for any other rule looks unused and\n // ESLint's fixer would delete it. A codemod never touches a directive.\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n },\n ...asyncRuleConfigs,\n ];\n }\n\n /**\n * The self-check's config: four scope rules, run on the text before and after the fixers. A hoisted name must be\n * declared once, shadow nothing, be used after it is declared and be used at all; when the fixers break one of these\n * the count of that rule goes up, and the file is left as it was.\n */\n static async createChecks(): Promise<Linter.Config[]> {\n const { default: tseslint } = await import('typescript-eslint');\n\n return [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser },\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n plugins: { '@typescript-eslint': tseslint.plugin as never },\n rules: {\n '@typescript-eslint/no-redeclare': 'error',\n '@typescript-eslint/no-shadow': 'error',\n '@typescript-eslint/no-use-before-define': [\n 'error',\n { functions: false, classes: false },\n ],\n '@typescript-eslint/no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }],\n },\n },\n ];\n }\n\n /** What got worse between `source` and `output` by the self-check's rules: empty when nothing did. */\n static selfCheck(opts: {\n linter: Linter;\n checks: Linter.Config[];\n source: string;\n output: string;\n filename: string;\n }): string[] {\n const { linter, checks, source, output, filename } = opts;\n\n const count = (text: string): Map<string, number> => {\n const found = new Map<string, number>();\n\n for (const message of linter.verify(text, checks, { filename })) {\n const key = message.ruleId ?? 'parse error';\n found.set(key, (found.get(key) ?? 0) + 1);\n }\n\n return found;\n };\n\n const was = count(source);\n const now = count(output);\n\n return [...now]\n .filter(([rule, total]) => total > (was.get(rule) ?? 0))\n .map(([rule, total]) => `${rule}: ${was.get(rule) ?? 0} before, ${total} after`);\n }\n\n /**\n * Fixes `source` (ESLint applies up to ten passes) and returns the text and what is left. `filename` is relative to\n * the linter's `cwd`. The fixed text is checked against the original (`checks`): if it has more redeclarations,\n * shadowed names, uses before declaration or unused variables than the original, no fix is returned and the file is\n * reported as `self-check`, so a hoisted name that does not match the expression it replaced never reaches a file.\n */\n static fix(opts: {\n linter: Linter;\n config: Linter.Config[];\n checks: Linter.Config[];\n source: string;\n filename: string;\n }): IAsyncStyleResult {\n const { linter, config, checks, source, filename } = opts;\n // A fix can leave a new finding behind (the try/catch of no-await-promise-chain is a silent catch when the\n // fallback is a constant), so the count is of the fixable findings, not of the findings that went away.\n const fixable = linter\n .verify(source, config, { filename })\n .filter((message) => message.fix !== undefined).length;\n const result = linter.verifyAndFix(source, config, { filename });\n\n if (result.output !== source) {\n const broken = AsyncStyle.selfCheck({\n linter,\n checks,\n source,\n output: result.output,\n filename,\n });\n\n if (broken.length > 0) {\n return {\n output: source,\n changed: false,\n fixes: 0,\n reports: [\n {\n line: 1,\n column: 1,\n ruleId: 'self-check',\n message: `the fixers would have made this file worse (${broken.join('; ')}); it is left as it was - fix it by hand`,\n },\n ],\n };\n }\n }\n\n return {\n output: result.output,\n changed: result.output !== source,\n fixes: result.fixed ? fixable : 0,\n reports: result.messages.map((message) => ({\n line: message.line,\n column: message.column,\n ruleId: message.ruleId,\n message: message.message,\n })),\n };\n }\n}\n\n/**\n * `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,\n * `no-return-await` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.\n * It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would\n * change or is left unfixed.\n */\nexport class AsyncStyleCommand {\n static readonly USAGE = USAGE;\n\n static async run(opts: { root: string; args: string[] }): Promise<number> {\n const { root, args } = opts;\n\n if (args.includes(AsyncStyleFlags.HELP) || args.includes(AsyncStyleFlags.HELP_SHORT)) {\n console.log(USAGE);\n\n return 0;\n }\n\n const flags = args.filter((argument) => argument.startsWith('-'));\n const paths = args.filter((argument) => !argument.startsWith('-'));\n\n const unknown = flags.filter((flag) => !AsyncStyleFlags.isValid(flag));\n\n if (unknown.length > 0) {\n console.error(\n `devz codemod: unknown option ${unknown.map((flag) => `\"${flag}\"`).join(', ')}\\n${USAGE}`,\n );\n\n return USAGE_ERROR_CODE;\n }\n\n const isWrite = flags.includes(AsyncStyleFlags.WRITE);\n const isCheck = flags.includes(AsyncStyleFlags.CHECK);\n\n if (isWrite && isCheck) {\n console.error(\n `devz codemod: ${AsyncStyleFlags.WRITE} and ${AsyncStyleFlags.CHECK} contradict each other\\n${USAGE}`,\n );\n\n return USAGE_ERROR_CODE;\n }\n\n const refusal = CodemodFiles.refusal({\n command: 'async-style',\n isWrite,\n isAll: flags.includes(AsyncStyleFlags.ALL),\n paths,\n });\n\n if (refusal) {\n console.error(`${refusal}\\n${USAGE}`);\n\n return USAGE_ERROR_CODE;\n }\n\n let linter: Linter;\n\n try {\n const { Linter: EslintLinter } = await import('eslint');\n linter = new EslintLinter({ cwd: root });\n } catch {\n console.error('devz codemod: the \"eslint\" package is required to run the lint fixers');\n\n return 1;\n }\n\n const config = await AsyncStyle.createConfig();\n const checks = await AsyncStyle.createChecks();\n const targets = (paths.length > 0 ? paths : ['.']).map((path) => resolve(root, path));\n let changedCount = 0;\n let fixCount = 0;\n let reportCount = 0;\n let refusedCount = 0;\n\n for (const target of targets) {\n const files = CodemodFiles.collect({ target });\n const dirty = isWrite ? CodemodFiles.dirty({ target }) : undefined;\n\n if (files.length === 0 && paths.length > 0) {\n console.warn(\n `devz codemod: no source files under \"${relative(root, target) || target}\" (git ignores the path, or it holds none): nothing was read`,\n );\n }\n\n for (const file of files) {\n const source = readFileSync(file, 'utf8');\n\n if (!ASYNC_TEXT.test(source)) {\n continue;\n }\n\n const shown = relative(root, file).split('\\\\').join('/');\n const result = AsyncStyle.fix({ linter, config, checks, source, filename: shown });\n\n for (const report of result.reports) {\n reportCount += 1;\n console.warn(\n `${shown}:${report.line}:${report.column} ${report.ruleId ?? 'parse error'} ${report.message}`,\n );\n }\n\n if (!result.changed) {\n continue;\n }\n\n if (dirty?.has(file)) {\n refusedCount += 1;\n console.warn(\n `refused ${shown} has local changes (commit or stash them, then run again)`,\n );\n continue;\n }\n\n changedCount += 1;\n fixCount += result.fixes;\n console.log(`${isWrite ? 'changed' : 'would change'} ${shown} (${result.fixes} fix(es))`);\n\n if (isWrite) {\n writeFileSync(file, result.output);\n }\n }\n }\n\n console.log(\n `devz codemod async-style: ${changedCount} file(s) ${isWrite ? 'changed' : 'would change'}, ${fixCount} fix(es) ${isWrite ? 'applied' : 'would be applied'}, ${reportCount} left unfixed` +\n (refusedCount > 0 ? `, ${refusedCount} refused` : ''),\n );\n\n if (!isWrite && changedCount > 0) {\n console.log(`Nothing was written. Run again with ${AsyncStyleFlags.WRITE} to apply.`);\n }\n\n if (isWrite && refusedCount > 0) {\n return 1;\n }\n\n return isCheck && (changedCount > 0 || reportCount > 0) ? 1 : 0;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"async-style.js","sourceRoot":"","sources":["../../../src/cli/codemod/async-style.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport type { Linter } from 'eslint';\nimport { CodemodFiles } from './files';\n\nconst USAGE = `Usage: devz codemod async-style [paths...] [--write | --check]\n\nApplies the fixers of four house lint rules, so a repository can sweep them without a lint pass:\n\n venizia/no-inline-await \\`expect(await f())\\` becomes \\`const result = await f(); expect(result)\\`\n venizia/no-return-await \\`return await f()\\` becomes \\`return f()\\` (\\`const result = await f(); return result;\\` in a try)\n venizia/no-await-new-chain \\`await new Runner(options).run()\\` becomes\n \\`const runner = new Runner(options); await runner.run();\\`\n venizia/no-await-promise-chain \\`const x = await f().catch(() => null)\\` becomes\n \\`let x; try { x = await f(); } catch (error) { x = null; }\\`\n\nIt changes only what the fixers can change safely, and lists the rest with its file, line and rule:\nan \\`await\\` inside a ternary or logical operand, a loop test, an unbraced \\`if\\` branch, or after a call\nthat may have effects; an awaited \\`.then\\` or \\`.finally\\`, a \\`.catch\\` whose handler has a block body or\ncalls something, and an awaited chain that is not the whole initializer of a \\`const\\` or \\`let\\`; and\nevery venizia/no-silent-catch finding (a handler or catch block that swallows the error), which it never\nfixes: what to log is your decision.\n\n --write write the changed files (without it, nothing is written)\n --check dry run that exits 1 when anything would change or is left unfixed (for CI)\n --all with --write and no path: rewrite every source file under the working directory (--write needs a path or --all)\n --help print this text and exit\n\nWith no flag it lists what would change and writes nothing. Inside a git repository it reads the\nfiles git knows (tracked, or untracked and not ignored), and --write refuses a file with local changes\n(changed, staged or untracked): commit or stash it first, so git can undo the codemod.`;\n\n/** A usage error: nothing was read or written. */\nconst USAGE_ERROR_CODE = 2;\n\n/** A file that can hold an `await` or a `catch`. */\nconst ASYNC_TEXT = /\\b(await|catch)\\b/;\n\nclass AsyncStyleFlags {\n static readonly WRITE = '--write';\n static readonly CHECK = '--check';\n static readonly ALL = '--all';\n static readonly HELP = '--help';\n static readonly HELP_SHORT = '-h';\n\n static readonly SCHEME_SET = new Set<string>([\n this.WRITE,\n this.CHECK,\n this.ALL,\n this.HELP,\n this.HELP_SHORT,\n ]);\n\n static isValid(value: string): boolean {\n return this.SCHEME_SET.has(value);\n }\n}\n\nexport interface IAsyncStyleReport {\n line: number;\n column: number;\n /** The rule id, or `undefined` for a file ESLint could not parse. */\n ruleId: string | null;\n message: string;\n}\n\nexport interface IAsyncStyleResult {\n output: string;\n changed: boolean;\n /** How many findings of the original source carried a fix, once the fixers changed it. */\n fixes: number;\n /** What is still reported after every pass. */\n reports: IAsyncStyleReport[];\n}\n\n/** Runs the async-style rules, and only those, over source text with ESLint's own fixer loop. */\nexport class AsyncStyle {\n /** The `Linter` config: the TypeScript parser and the rules of `asyncRuleConfigs`, at error. */\n static async createConfig(): Promise<Linter.Config[]> {\n const { default: tseslint } = await import('typescript-eslint');\n const { asyncRuleConfigs } = await import('../../linters/house/async-rules.js');\n\n return [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser },\n // Only the async-style rules run here, so a `// eslint-disable-next-line` for any other rule looks unused and\n // ESLint's fixer would delete it. A codemod never touches a directive.\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n },\n ...asyncRuleConfigs,\n ];\n }\n\n /**\n * The self-check's config: four scope rules, run on the text before and after the fixers. A hoisted name must be\n * declared once, shadow nothing, be used after it is declared and be used at all; when the fixers break one of these\n * the count of that rule goes up, and the file is left as it was.\n */\n static async createChecks(): Promise<Linter.Config[]> {\n const { default: tseslint } = await import('typescript-eslint');\n\n return [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser },\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n plugins: { '@typescript-eslint': tseslint.plugin as never },\n rules: {\n '@typescript-eslint/no-redeclare': 'error',\n '@typescript-eslint/no-shadow': 'error',\n '@typescript-eslint/no-use-before-define': [\n 'error',\n { functions: false, classes: false },\n ],\n '@typescript-eslint/no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }],\n },\n },\n ];\n }\n\n /** What got worse between `source` and `output` by the self-check's rules: empty when nothing did. */\n static selfCheck(opts: {\n linter: Linter;\n checks: Linter.Config[];\n source: string;\n output: string;\n filename: string;\n }): string[] {\n const { linter, checks, source, output, filename } = opts;\n\n const count = (text: string): Map<string, number> => {\n const found = new Map<string, number>();\n\n for (const message of linter.verify(text, checks, { filename })) {\n const key = message.ruleId ?? 'parse error';\n found.set(key, (found.get(key) ?? 0) + 1);\n }\n\n return found;\n };\n\n const was = count(source);\n const now = count(output);\n\n return [...now]\n .filter(([rule, total]) => total > (was.get(rule) ?? 0))\n .map(([rule, total]) => `${rule}: ${was.get(rule) ?? 0} before, ${total} after`);\n }\n\n /**\n * Fixes `source` (ESLint applies up to ten passes) and returns the text and what is left. `filename` is relative to\n * the linter's `cwd`. The fixed text is checked against the original (`checks`): if it has more redeclarations,\n * shadowed names, uses before declaration or unused variables than the original, no fix is returned and the file is\n * reported as `self-check`, so a hoisted name that does not match the expression it replaced never reaches a file.\n */\n static fix(opts: {\n linter: Linter;\n config: Linter.Config[];\n checks: Linter.Config[];\n source: string;\n filename: string;\n }): IAsyncStyleResult {\n const { linter, config, checks, source, filename } = opts;\n // A fix can leave a new finding behind (the try/catch of no-await-promise-chain is a silent catch when the\n // fallback is a constant), so the count is of the fixable findings, not of the findings that went away.\n const fixable = linter\n .verify(source, config, { filename })\n .filter((message) => message.fix !== undefined).length;\n const result = linter.verifyAndFix(source, config, { filename });\n\n if (result.output !== source) {\n const broken = AsyncStyle.selfCheck({\n linter,\n checks,\n source,\n output: result.output,\n filename,\n });\n\n if (broken.length > 0) {\n return {\n output: source,\n changed: false,\n fixes: 0,\n reports: [\n {\n line: 1,\n column: 1,\n ruleId: 'self-check',\n message: `the fixers would have made this file worse (${broken.join('; ')}); it is left as it was - fix it by hand`,\n },\n ],\n };\n }\n }\n\n return {\n output: result.output,\n changed: result.output !== source,\n fixes: result.fixed ? fixable : 0,\n reports: result.messages.map((message) => ({\n line: message.line,\n column: message.column,\n ruleId: message.ruleId,\n message: message.message,\n })),\n };\n }\n}\n\n/**\n * `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,\n * `no-return-await`, `no-await-new-chain` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.\n * It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would\n * change or is left unfixed.\n */\nexport class AsyncStyleCommand {\n static readonly USAGE = USAGE;\n\n static async run(opts: { root: string; args: string[] }): Promise<number> {\n const { root, args } = opts;\n\n if (args.includes(AsyncStyleFlags.HELP) || args.includes(AsyncStyleFlags.HELP_SHORT)) {\n console.log(USAGE);\n\n return 0;\n }\n\n const flags = args.filter((argument) => argument.startsWith('-'));\n const paths = args.filter((argument) => !argument.startsWith('-'));\n\n const unknown = flags.filter((flag) => !AsyncStyleFlags.isValid(flag));\n\n if (unknown.length > 0) {\n console.error(\n `devz codemod: unknown option ${unknown.map((flag) => `\"${flag}\"`).join(', ')}\\n${USAGE}`,\n );\n\n return USAGE_ERROR_CODE;\n }\n\n const isWrite = flags.includes(AsyncStyleFlags.WRITE);\n const isCheck = flags.includes(AsyncStyleFlags.CHECK);\n\n if (isWrite && isCheck) {\n console.error(\n `devz codemod: ${AsyncStyleFlags.WRITE} and ${AsyncStyleFlags.CHECK} contradict each other\\n${USAGE}`,\n );\n\n return USAGE_ERROR_CODE;\n }\n\n const refusal = CodemodFiles.refusal({\n command: 'async-style',\n isWrite,\n isAll: flags.includes(AsyncStyleFlags.ALL),\n paths,\n });\n\n if (refusal) {\n console.error(`${refusal}\\n${USAGE}`);\n\n return USAGE_ERROR_CODE;\n }\n\n let linter: Linter;\n\n try {\n const { Linter: EslintLinter } = await import('eslint');\n linter = new EslintLinter({ cwd: root });\n } catch {\n console.error('devz codemod: the \"eslint\" package is required to run the lint fixers');\n\n return 1;\n }\n\n const config = await AsyncStyle.createConfig();\n const checks = await AsyncStyle.createChecks();\n const targets = (paths.length > 0 ? paths : ['.']).map((path) => resolve(root, path));\n let changedCount = 0;\n let fixCount = 0;\n let reportCount = 0;\n let refusedCount = 0;\n\n for (const target of targets) {\n const files = CodemodFiles.collect({ target });\n const dirty = isWrite ? CodemodFiles.dirty({ target }) : undefined;\n\n if (files.length === 0 && paths.length > 0) {\n console.warn(\n `devz codemod: no source files under \"${relative(root, target) || target}\" (git ignores the path, or it holds none): nothing was read`,\n );\n }\n\n for (const file of files) {\n const source = readFileSync(file, 'utf8');\n\n if (!ASYNC_TEXT.test(source)) {\n continue;\n }\n\n const shown = relative(root, file).split('\\\\').join('/');\n const result = AsyncStyle.fix({ linter, config, checks, source, filename: shown });\n\n for (const report of result.reports) {\n reportCount += 1;\n console.warn(\n `${shown}:${report.line}:${report.column} ${report.ruleId ?? 'parse error'} ${report.message}`,\n );\n }\n\n if (!result.changed) {\n continue;\n }\n\n if (dirty?.has(file)) {\n refusedCount += 1;\n console.warn(\n `refused ${shown} has local changes (commit or stash them, then run again)`,\n );\n continue;\n }\n\n changedCount += 1;\n fixCount += result.fixes;\n console.log(`${isWrite ? 'changed' : 'would change'} ${shown} (${result.fixes} fix(es))`);\n\n if (isWrite) {\n writeFileSync(file, result.output);\n }\n }\n }\n\n console.log(\n `devz codemod async-style: ${changedCount} file(s) ${isWrite ? 'changed' : 'would change'}, ${fixCount} fix(es) ${isWrite ? 'applied' : 'would be applied'}, ${reportCount} left unfixed` +\n (refusedCount > 0 ? `, ${refusedCount} refused` : ''),\n );\n\n if (!isWrite && changedCount > 0) {\n console.log(`Nothing was written. Run again with ${AsyncStyleFlags.WRITE} to apply.`);\n }\n\n if (isWrite && refusedCount > 0) {\n return 1;\n }\n\n return isCheck && (changedCount > 0 || reportCount > 0) ? 1 : 0;\n }\n}\n"]}
|
|
@@ -195,7 +195,7 @@ class NamespaceFunctions {
|
|
|
195
195
|
if (mapping) {
|
|
196
196
|
report({
|
|
197
197
|
node: element,
|
|
198
|
-
reason: `re-exports \`${name}\`; re-export ${mapping.className} as well, by hand
|
|
198
|
+
reason: `re-exports \`${name}\`; re-export ${mapping.className} as well, by hand`,
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewriter.js","sourceRoot":"","sources":["../../../../src/cli/codemod/namespace-functions/rewriter.ts"],"names":[],"mappings":"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","sourcesContent":["import type ts from 'typescript';\nimport type { INamespaceMapping } from './mapping';\n\ntype TTypeScript = typeof ts;\n\nexport interface INamespaceFunctionsReport {\n line: number;\n column: number;\n reason: string;\n}\n\nexport interface INamespaceFunctionsResult {\n output: string;\n changed: boolean;\n /** How many calls were rewritten. */\n rewritten: number;\n /** What the codemod found and left for a person, with where. */\n reports: INamespaceFunctionsReport[];\n}\n\ninterface IEdit {\n start: number;\n end: number;\n text: string;\n}\n\n/** One way the file reaches an old name: a named import of it, or a namespace import of its module. */\ninterface IBinding {\n mapping: INamespaceMapping;\n declaration: ts.ImportDeclaration;\n module: string;\n /** The local name: of the imported function, or of the namespace. */\n local: string;\n /** The identifier that declares `local`. */\n declarationName: ts.Identifier;\n /** The named import; `undefined` for `import * as name`. */\n specifier?: ts.ImportSpecifier;\n}\n\n/** A matched use of an old name: a call to rewrite, or any other use, which is reported. */\ninterface IUses {\n calls: ts.CallExpression[];\n values: ts.Node[];\n}\n\n/**\n * Rewrites the calls of functions that moved into a class, `oldName(a, b)` to\n * `ClassName.method({ first: a, second: b })`, from a mapping table. Syntactic: it reads one file and\n * needs no type checker, so it only follows names imported from a module the table lists. Every edit\n * is a text edit by position: the argument text, its comments and the untouched code stay as they are.\n */\nexport class NamespaceFunctions {\n static rewrite(opts: {\n typescript: TTypeScript;\n fileName: string;\n source: string;\n mappings: ReadonlyArray<INamespaceMapping>;\n }): INamespaceFunctionsResult {\n const { typescript, fileName, source, mappings } = opts;\n const sourceFile = typescript.createSourceFile(\n fileName,\n source,\n typescript.ScriptTarget.Latest,\n true,\n );\n const reports: INamespaceFunctionsReport[] = [];\n\n const report = (reportOpts: { node: ts.Node; reason: string }) => {\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(\n reportOpts.node.getStart(sourceFile),\n );\n reports.push({ line: line + 1, column: character + 1, reason: reportOpts.reason });\n };\n\n const lineOf = (node: ts.Node) =>\n sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;\n\n const byModule = new Map<string, INamespaceMapping[]>();\n\n for (const mapping of mappings) {\n for (const module of mapping.modules) {\n byModule.set(module, [...(byModule.get(module) ?? []), mapping]);\n }\n }\n\n const bindings = NamespaceFunctions.findBindings({\n typescript,\n sourceFile,\n byModule,\n report,\n });\n\n if (bindings.length === 0) {\n return { output: source, changed: false, rewritten: 0, reports };\n }\n\n const identifiers = NamespaceFunctions.collectIdentifiers({ typescript, sourceFile });\n const declarationsOf = (name: string) =>\n (identifiers.get(name) ?? []).filter((identifier) =>\n NamespaceFunctions.isDeclarationName({ typescript, identifier }),\n );\n\n const edits: IEdit[] = [];\n const removals = new Set<ts.ImportSpecifier>();\n /** The imports that lose an old name. */\n const trimmed = new Set<ts.ImportDeclaration>();\n const additions = new Map<ts.ImportDeclaration, Set<string>>();\n const newImports = new Map<string, { anchor: ts.ImportDeclaration; names: Set<string> }>();\n /** The class names this run imports, and from which module. */\n const planned = new Map<string, string>();\n let rewritten = 0;\n\n for (const binding of bindings) {\n const { mapping } = binding;\n const uses = NamespaceFunctions.findUses({ typescript, binding, identifiers });\n\n if (uses.calls.length === 0 && uses.values.length === 0) {\n continue;\n }\n\n const target = NamespaceFunctions.describeTarget({ mapping });\n\n for (const value of uses.values) {\n report({\n node: value,\n reason: `\\`${mapping.oldName}\\` is used as a value (passed, stored, exported or in typeof), so its import stays; change it by hand to ${mapping.className}.${mapping.method}`,\n });\n }\n\n if (uses.calls.length === 0) {\n continue;\n }\n\n const shadow = declarationsOf(binding.local).find(\n (identifier) => identifier !== binding.declarationName,\n );\n\n if (shadow) {\n report({\n node: shadow,\n reason: `\\`${binding.local}\\` is declared again in this file, so a call cannot be told apart from the import; rewrite the calls of \\`${mapping.oldName}\\` by hand as ${target}`,\n });\n continue;\n }\n\n const classModules = mapping.newModules ?? [binding.module];\n const isNamespaceReach = !binding.specifier && classModules.includes(binding.module);\n let classReference = `${binding.local}.${mapping.className}`;\n let needsImport = false;\n\n if (!isNamespaceReach) {\n const existing = NamespaceFunctions.findClassImport({\n typescript,\n sourceFile,\n className: mapping.className,\n modules: classModules,\n });\n const plannedModule = planned.get(mapping.className);\n const conflict = existing\n ? declarationsOf(existing.text).find((identifier) => identifier !== existing)\n : plannedModule === undefined\n ? declarationsOf(mapping.className)[0]\n : undefined;\n\n if (conflict) {\n report({\n node: uses.calls[0] ?? conflict,\n reason: `the name \\`${conflict.text}\\` is already declared in this file (line ${lineOf(conflict)}), so \\`${mapping.oldName}\\` is left; rewrite its calls by hand as ${target}`,\n });\n continue;\n }\n\n if (!existing && plannedModule !== undefined && !classModules.includes(plannedModule)) {\n report({\n node: uses.calls[0] ?? binding.declaration,\n reason: `\\`${mapping.className}\\` would be imported from both ${plannedModule} and ${classModules[0]}; rewrite the calls of \\`${mapping.oldName}\\` by hand as ${target}`,\n });\n continue;\n }\n\n classReference = existing?.text ?? mapping.className;\n needsImport = !existing && plannedModule === undefined;\n }\n\n let count = 0;\n let left = uses.values.length;\n\n for (const call of uses.calls) {\n const problem = NamespaceFunctions.checkCall({ typescript, call, mapping });\n\n if (problem) {\n left += 1;\n report({ node: call, reason: `${problem}; rewrite it by hand as ${target}` });\n continue;\n }\n\n edits.push(\n ...NamespaceFunctions.planCall({\n typescript,\n sourceFile,\n call,\n mapping,\n callee: `${classReference}.${mapping.method}`,\n }),\n );\n count += 1;\n }\n\n rewritten += count;\n\n if (count === 0) {\n continue;\n }\n\n if (needsImport) {\n const sameDeclaration =\n binding.specifier && classModules.includes(binding.module)\n ? binding.declaration\n : undefined;\n const declaration =\n sameDeclaration ??\n NamespaceFunctions.findNamedImport({ typescript, sourceFile, modules: classModules });\n\n if (declaration) {\n additions.set(\n declaration,\n new Set([...(additions.get(declaration) ?? []), mapping.className]),\n );\n planned.set(\n mapping.className,\n sameDeclaration ? binding.module : NamespaceFunctions.moduleOf({ declaration }),\n );\n } else {\n const module = classModules[0] ?? binding.module;\n const entry = newImports.get(module) ?? {\n anchor: binding.declaration,\n names: new Set<string>(),\n };\n entry.names.add(mapping.className);\n newImports.set(module, entry);\n planned.set(mapping.className, module);\n }\n }\n\n if (binding.specifier && left === 0) {\n removals.add(binding.specifier);\n trimmed.add(binding.declaration);\n }\n }\n\n if (rewritten === 0) {\n return { output: source, changed: false, rewritten: 0, reports };\n }\n\n for (const declaration of new Set([...additions.keys(), ...trimmed])) {\n edits.push(\n ...NamespaceFunctions.planImport({\n typescript,\n sourceFile,\n declaration,\n removals,\n additions: [...(additions.get(declaration) ?? [])],\n report,\n }),\n );\n }\n\n for (const [module, { anchor, names }] of newImports) {\n const quote = source.charAt(anchor.moduleSpecifier.getStart(sourceFile));\n edits.push({\n start: anchor.getStart(sourceFile),\n end: anchor.getStart(sourceFile),\n text: `import { ${[...names].join(', ')} } from ${quote}${module}${quote};\\n`,\n });\n }\n\n // At one position a replacement (the longer range) is applied before an insertion, so the\n // inserted key of an outer call lands in front of the rewritten callee of an inner one.\n let output = source;\n\n for (const edit of edits.sort((a, b) => b.start - a.start || b.end - a.end)) {\n output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);\n }\n\n return { output, changed: output !== source, rewritten, reports };\n }\n\n /** The named and namespace imports of an old name; reports the type-only imports and the re-exports. */\n private static findBindings(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n byModule: Map<string, INamespaceMapping[]>;\n report: (reportOpts: { node: ts.Node; reason: string }) => void;\n }): IBinding[] {\n const { typescript, sourceFile, byModule, report } = opts;\n const bindings: IBinding[] = [];\n\n for (const statement of sourceFile.statements) {\n if (\n typescript.isExportDeclaration(statement) &&\n statement.moduleSpecifier &&\n typescript.isStringLiteral(statement.moduleSpecifier) &&\n statement.exportClause &&\n typescript.isNamedExports(statement.exportClause)\n ) {\n const candidates = byModule.get(statement.moduleSpecifier.text) ?? [];\n\n for (const element of statement.exportClause.elements) {\n const name = (element.propertyName ?? element.name).text;\n const mapping = candidates.find((candidate) => candidate.oldName === name);\n\n if (mapping) {\n report({\n node: element,\n reason: `re-exports \\`${name}\\`; re-export ${mapping.className} as well, by hand (the old name goes away in 0.5)`,\n });\n }\n }\n\n continue;\n }\n\n if (\n !typescript.isImportDeclaration(statement) ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n !statement.importClause\n ) {\n continue;\n }\n\n const module = statement.moduleSpecifier.text;\n const candidates = byModule.get(module);\n const clause = statement.importClause;\n const named = clause.namedBindings;\n\n if (!candidates || !named) {\n continue;\n }\n\n if (typescript.isNamespaceImport(named)) {\n if (clause.isTypeOnly) {\n continue;\n }\n\n for (const mapping of candidates) {\n bindings.push({\n mapping,\n declaration: statement,\n module,\n local: named.name.text,\n declarationName: named.name,\n });\n }\n\n continue;\n }\n\n for (const element of named.elements) {\n const imported = (element.propertyName ?? element.name).text;\n const mapping = candidates.find((candidate) => candidate.oldName === imported);\n\n if (!mapping) {\n continue;\n }\n\n if (clause.isTypeOnly || element.isTypeOnly) {\n report({\n node: element,\n reason: `\\`${imported}\\` is imported as a type only; change it by hand to \\`typeof ${mapping.className}.${mapping.method}\\``,\n });\n continue;\n }\n\n bindings.push({\n mapping,\n declaration: statement,\n module,\n local: element.name.text,\n declarationName: element.name,\n specifier: element,\n });\n }\n }\n\n return bindings;\n }\n\n /** Every identifier of the file by its text; JSDoc is not walked, so a `{@link name}` never counts. */\n private static collectIdentifiers(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n }): Map<string, ts.Identifier[]> {\n const { typescript, sourceFile } = opts;\n const identifiers = new Map<string, ts.Identifier[]>();\n\n const walk = (node: ts.Node): void => {\n if (typescript.isIdentifier(node)) {\n identifiers.set(node.text, [...(identifiers.get(node.text) ?? []), node]);\n }\n\n typescript.forEachChild(node, walk);\n };\n\n walk(sourceFile);\n\n return identifiers;\n }\n\n /** The calls of the old name, and every other use of it. */\n private static findUses(opts: {\n typescript: TTypeScript;\n binding: IBinding;\n identifiers: Map<string, ts.Identifier[]>;\n }): IUses {\n const { typescript, binding, identifiers } = opts;\n const uses: IUses = { calls: [], values: [] };\n\n for (const identifier of identifiers.get(binding.local) ?? []) {\n if (\n identifier === binding.declarationName ||\n !NamespaceFunctions.isReference({ typescript, identifier })\n ) {\n continue;\n }\n\n if (!binding.specifier) {\n const parent = identifier.parent;\n const isMember =\n typescript.isPropertyAccessExpression(parent) &&\n parent.expression === identifier &&\n parent.name.text === binding.mapping.oldName;\n\n if (isMember) {\n const call = parent.parent;\n\n if (typescript.isCallExpression(call) && call.expression === parent) {\n uses.calls.push(call);\n } else {\n uses.values.push(parent);\n }\n\n continue;\n }\n\n if (\n typescript.isQualifiedName(parent) &&\n parent.left === identifier &&\n parent.right.text === binding.mapping.oldName\n ) {\n uses.values.push(parent);\n }\n\n continue;\n }\n\n const parent = identifier.parent;\n\n if (typescript.isCallExpression(parent) && parent.expression === identifier) {\n uses.calls.push(parent);\n continue;\n }\n\n uses.values.push(identifier);\n }\n\n return uses;\n }\n\n /** The identifier names a declaration: a variable, a parameter, a function, a class, an import, a type. */\n private static isDeclarationName(opts: {\n typescript: TTypeScript;\n identifier: ts.Identifier;\n }): boolean {\n const { typescript, identifier } = opts;\n const parent = identifier.parent;\n\n if (\n typescript.isVariableDeclaration(parent) ||\n typescript.isParameter(parent) ||\n typescript.isBindingElement(parent) ||\n typescript.isFunctionDeclaration(parent) ||\n typescript.isFunctionExpression(parent) ||\n typescript.isClassDeclaration(parent) ||\n typescript.isClassExpression(parent) ||\n typescript.isEnumDeclaration(parent) ||\n typescript.isInterfaceDeclaration(parent) ||\n typescript.isTypeAliasDeclaration(parent) ||\n typescript.isModuleDeclaration(parent) ||\n typescript.isImportSpecifier(parent) ||\n typescript.isImportClause(parent) ||\n typescript.isNamespaceImport(parent) ||\n typescript.isImportEqualsDeclaration(parent) ||\n typescript.isTypeParameterDeclaration(parent)\n ) {\n return parent.name === identifier;\n }\n\n return false;\n }\n\n /** The identifier reads a binding: not a property name, a label, a declaration or a lowercase JSX tag. */\n private static isReference(opts: {\n typescript: TTypeScript;\n identifier: ts.Identifier;\n }): boolean {\n const { typescript, identifier } = opts;\n const parent = identifier.parent;\n\n if (NamespaceFunctions.isDeclarationName({ typescript, identifier })) {\n return false;\n }\n\n if (typescript.isPropertyAccessExpression(parent) || typescript.isQualifiedName(parent)) {\n return typescript.isPropertyAccessExpression(parent)\n ? parent.name !== identifier\n : parent.right !== identifier;\n }\n\n if (\n typescript.isPropertyAssignment(parent) ||\n typescript.isPropertyDeclaration(parent) ||\n typescript.isPropertySignature(parent) ||\n typescript.isMethodDeclaration(parent) ||\n typescript.isMethodSignature(parent) ||\n typescript.isGetAccessorDeclaration(parent) ||\n typescript.isSetAccessorDeclaration(parent) ||\n typescript.isEnumMember(parent) ||\n typescript.isJsxAttribute(parent)\n ) {\n return parent.name !== identifier;\n }\n\n if (typescript.isBindingElement(parent)) {\n return parent.propertyName !== identifier;\n }\n\n if (typescript.isExportSpecifier(parent)) {\n return (\n !parent.parent.parent.moduleSpecifier && (parent.propertyName ?? parent.name) === identifier\n );\n }\n\n if (\n typescript.isLabeledStatement(parent) ||\n typescript.isBreakOrContinueStatement(parent) ||\n typescript.isMetaProperty(parent)\n ) {\n return false;\n }\n\n if (\n (typescript.isJsxOpeningElement(parent) ||\n typescript.isJsxSelfClosingElement(parent) ||\n typescript.isJsxClosingElement(parent)) &&\n parent.tagName === identifier\n ) {\n return !/^[a-z]/.test(identifier.text);\n }\n\n return true;\n }\n\n /** Why a call cannot be rewritten, or `undefined` when it can. */\n private static checkCall(opts: {\n typescript: TTypeScript;\n call: ts.CallExpression;\n mapping: INamespaceMapping;\n }): string | undefined {\n const { typescript, call, mapping } = opts;\n const { params, restKey, oldName } = mapping;\n const count = call.arguments.length;\n\n if (mapping.keepsOptions) {\n return undefined;\n }\n\n if (call.arguments.some((argument) => typescript.isSpreadElement(argument))) {\n return `this call of \\`${oldName}\\` has a spread argument`;\n }\n\n const required = params.reduce(\n (last, parameter, index) => (parameter.optional ? last : index + 1),\n 0,\n );\n\n if (count < required) {\n return `this call of \\`${oldName}\\` passes ${count} argument(s), fewer than the ${required} it needs`;\n }\n\n if (restKey === undefined && count > params.length) {\n return `this call of \\`${oldName}\\` passes ${count} argument(s), more than its ${params.length} parameter(s)`;\n }\n\n return undefined;\n }\n\n /** The edits that turn one call into the class form; the arguments keep their text and comments. */\n private static planCall(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n call: ts.CallExpression;\n mapping: INamespaceMapping;\n callee: string;\n }): IEdit[] {\n const { typescript, sourceFile, call, mapping, callee } = opts;\n const { params, restKey } = mapping;\n const edits: IEdit[] = [\n { start: call.expression.getStart(sourceFile), end: call.expression.end, text: callee },\n ];\n\n if (call.questionDotToken) {\n edits.push({\n start: call.questionDotToken.getStart(sourceFile),\n end: call.questionDotToken.end,\n text: '',\n });\n }\n\n if (mapping.keepsOptions) {\n return edits;\n }\n\n const argumentList = [...call.arguments];\n\n if (argumentList.length === 0) {\n if (params.length > 0 || restKey !== undefined) {\n const text = restKey === undefined ? '{}' : `{ ${restKey}: [] }`;\n edits.push({ start: call.arguments.pos, end: call.arguments.pos, text });\n }\n\n return edits;\n }\n\n const insert = (insertOpts: { at: number; text: string }) => {\n if (insertOpts.text !== '') {\n edits.push({ start: insertOpts.at, end: insertOpts.at, text: insertOpts.text });\n }\n };\n\n const positional = argumentList.slice(0, params.length);\n const rest = argumentList.slice(params.length);\n\n positional.forEach((argument, index) => {\n const key = params[index]?.key ?? '';\n const isShorthand = typescript.isIdentifier(argument) && argument.text === key;\n insert({\n at: argument.getStart(sourceFile),\n text: `${index === 0 ? '{ ' : ''}${isShorthand ? '' : `${key}: `}`,\n });\n });\n\n const first = rest[0];\n const last = argumentList[argumentList.length - 1];\n let suffix = ' }';\n\n if (first && restKey !== undefined) {\n insert({\n at: first.getStart(sourceFile),\n text: `${positional.length === 0 ? '{ ' : ''}${restKey}: [`,\n });\n suffix = '] }';\n } else if (restKey !== undefined) {\n suffix = `, ${restKey}: [] }`;\n }\n\n insert({ at: last?.end ?? call.arguments.end, text: suffix });\n\n return edits;\n }\n\n /** The local name of a value import of the class from one of `modules`. */\n private static findClassImport(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n className: string;\n modules: string[];\n }): ts.Identifier | undefined {\n const { typescript, sourceFile, className, modules } = opts;\n\n for (const statement of sourceFile.statements) {\n const declaration = NamespaceFunctions.asValueImport({ typescript, statement, modules });\n const named = declaration?.importClause?.namedBindings;\n\n if (!named || !typescript.isNamedImports(named)) {\n continue;\n }\n\n const element = named.elements.find(\n (candidate) =>\n !candidate.isTypeOnly && (candidate.propertyName ?? candidate.name).text === className,\n );\n\n if (element) {\n return element.name;\n }\n }\n\n return undefined;\n }\n\n /** The first value import with braces from one of `modules`, to add a class to. */\n private static findNamedImport(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n modules: string[];\n }): ts.ImportDeclaration | undefined {\n const { typescript, sourceFile, modules } = opts;\n\n for (const statement of sourceFile.statements) {\n const declaration = NamespaceFunctions.asValueImport({ typescript, statement, modules });\n const named = declaration?.importClause?.namedBindings;\n\n if (declaration && named && typescript.isNamedImports(named)) {\n return declaration;\n }\n }\n\n return undefined;\n }\n\n /** `statement` as an import that is not `import type`, from one of `modules`. */\n private static asValueImport(opts: {\n typescript: TTypeScript;\n statement: ts.Statement;\n modules: string[];\n }): ts.ImportDeclaration | undefined {\n const { typescript, statement, modules } = opts;\n\n if (\n typescript.isImportDeclaration(statement) &&\n typescript.isStringLiteral(statement.moduleSpecifier) &&\n modules.includes(statement.moduleSpecifier.text) &&\n statement.importClause &&\n !statement.importClause.isTypeOnly\n ) {\n return statement;\n }\n\n return undefined;\n }\n\n private static moduleOf(opts: { declaration: ts.ImportDeclaration }): string {\n const specifier = opts.declaration.moduleSpecifier;\n\n return 'text' in specifier && typeof specifier.text === 'string' ? specifier.text : '';\n }\n\n /**\n * The edit of one import's braces: the removed old names go, the added classes take the place of\n * the first removed one. Braces that hold a comment are not rewritten: the classes are appended\n * and the old names stay, reported. An import left with nothing is removed.\n */\n private static planImport(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n declaration: ts.ImportDeclaration;\n removals: Set<ts.ImportSpecifier>;\n additions: string[];\n report: (reportOpts: { node: ts.Node; reason: string }) => void;\n }): IEdit[] {\n const { typescript, sourceFile, declaration, removals, additions, report } = opts;\n const clause = declaration.importClause;\n const named = clause?.namedBindings;\n\n if (!clause || !named || !typescript.isNamedImports(named)) {\n return [];\n }\n\n const source = sourceFile.text;\n const elements = [...named.elements];\n const braces = source.slice(named.getStart(sourceFile), named.end);\n\n if (/\\/\\*|\\/\\//.test(braces)) {\n for (const element of elements.filter((candidate) => removals.has(candidate))) {\n report({\n node: element,\n reason: `the braces of this import hold a comment, so \\`${element.name.text}\\` stays imported; remove it by hand`,\n });\n }\n\n const last = elements[elements.length - 1];\n\n if (!last || additions.length === 0) {\n return [];\n }\n\n return [{ start: last.end, end: last.end, text: `, ${additions.join(', ')}` }];\n }\n\n const items: string[] = [];\n let isPlaced = false;\n\n for (const element of elements) {\n if (!removals.has(element)) {\n items.push(element.getText(sourceFile));\n continue;\n }\n\n if (!isPlaced) {\n items.push(...additions);\n isPlaced = true;\n }\n }\n\n if (!isPlaced) {\n items.push(...additions);\n }\n\n if (items.length > 0) {\n const start = named.getStart(sourceFile);\n const lineStart = source.lastIndexOf('\\n', declaration.getStart(sourceFile)) + 1;\n const indent = /^[ \\t]*/.exec(source.slice(lineStart))?.[0] ?? '';\n const text = braces.includes('\\n')\n ? `{\\n${indent} ${items.join(`,\\n${indent} `)},\\n${indent}}`\n : `{ ${items.join(', ')} }`;\n\n return [{ start, end: named.end, text }];\n }\n\n if (clause.name) {\n return [{ start: clause.name.end, end: named.end, text: '' }];\n }\n\n const start = declaration.getStart(sourceFile);\n const newline = /^\\r?\\n/.exec(source.slice(declaration.end))?.[0] ?? '';\n\n return [{ start, end: declaration.end + newline.length, text: '' }];\n }\n\n /** The call the old one becomes, for a report: `ParseUtility.toFloat({ input, digit })`. */\n private static describeTarget(opts: { mapping: INamespaceMapping }): string {\n const { className, method, params, restKey } = opts.mapping;\n const keys = [...params.map((parameter) => parameter.key), ...(restKey ? [restKey] : [])];\n\n return keys.length === 0\n ? `${className}.${method}()`\n : `${className}.${method}({ ${keys.join(', ')} })`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rewriter.js","sourceRoot":"","sources":["../../../../src/cli/codemod/namespace-functions/rewriter.ts"],"names":[],"mappings":"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","sourcesContent":["import type ts from 'typescript';\nimport type { INamespaceMapping } from './mapping';\n\ntype TTypeScript = typeof ts;\n\nexport interface INamespaceFunctionsReport {\n line: number;\n column: number;\n reason: string;\n}\n\nexport interface INamespaceFunctionsResult {\n output: string;\n changed: boolean;\n /** How many calls were rewritten. */\n rewritten: number;\n /** What the codemod found and left for a person, with where. */\n reports: INamespaceFunctionsReport[];\n}\n\ninterface IEdit {\n start: number;\n end: number;\n text: string;\n}\n\n/** One way the file reaches an old name: a named import of it, or a namespace import of its module. */\ninterface IBinding {\n mapping: INamespaceMapping;\n declaration: ts.ImportDeclaration;\n module: string;\n /** The local name: of the imported function, or of the namespace. */\n local: string;\n /** The identifier that declares `local`. */\n declarationName: ts.Identifier;\n /** The named import; `undefined` for `import * as name`. */\n specifier?: ts.ImportSpecifier;\n}\n\n/** A matched use of an old name: a call to rewrite, or any other use, which is reported. */\ninterface IUses {\n calls: ts.CallExpression[];\n values: ts.Node[];\n}\n\n/**\n * Rewrites the calls of functions that moved into a class, `oldName(a, b)` to\n * `ClassName.method({ first: a, second: b })`, from a mapping table. Syntactic: it reads one file and\n * needs no type checker, so it only follows names imported from a module the table lists. Every edit\n * is a text edit by position: the argument text, its comments and the untouched code stay as they are.\n */\nexport class NamespaceFunctions {\n static rewrite(opts: {\n typescript: TTypeScript;\n fileName: string;\n source: string;\n mappings: ReadonlyArray<INamespaceMapping>;\n }): INamespaceFunctionsResult {\n const { typescript, fileName, source, mappings } = opts;\n const sourceFile = typescript.createSourceFile(\n fileName,\n source,\n typescript.ScriptTarget.Latest,\n true,\n );\n const reports: INamespaceFunctionsReport[] = [];\n\n const report = (reportOpts: { node: ts.Node; reason: string }) => {\n const { line, character } = sourceFile.getLineAndCharacterOfPosition(\n reportOpts.node.getStart(sourceFile),\n );\n reports.push({ line: line + 1, column: character + 1, reason: reportOpts.reason });\n };\n\n const lineOf = (node: ts.Node) =>\n sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;\n\n const byModule = new Map<string, INamespaceMapping[]>();\n\n for (const mapping of mappings) {\n for (const module of mapping.modules) {\n byModule.set(module, [...(byModule.get(module) ?? []), mapping]);\n }\n }\n\n const bindings = NamespaceFunctions.findBindings({\n typescript,\n sourceFile,\n byModule,\n report,\n });\n\n if (bindings.length === 0) {\n return { output: source, changed: false, rewritten: 0, reports };\n }\n\n const identifiers = NamespaceFunctions.collectIdentifiers({ typescript, sourceFile });\n const declarationsOf = (name: string) =>\n (identifiers.get(name) ?? []).filter((identifier) =>\n NamespaceFunctions.isDeclarationName({ typescript, identifier }),\n );\n\n const edits: IEdit[] = [];\n const removals = new Set<ts.ImportSpecifier>();\n /** The imports that lose an old name. */\n const trimmed = new Set<ts.ImportDeclaration>();\n const additions = new Map<ts.ImportDeclaration, Set<string>>();\n const newImports = new Map<string, { anchor: ts.ImportDeclaration; names: Set<string> }>();\n /** The class names this run imports, and from which module. */\n const planned = new Map<string, string>();\n let rewritten = 0;\n\n for (const binding of bindings) {\n const { mapping } = binding;\n const uses = NamespaceFunctions.findUses({ typescript, binding, identifiers });\n\n if (uses.calls.length === 0 && uses.values.length === 0) {\n continue;\n }\n\n const target = NamespaceFunctions.describeTarget({ mapping });\n\n for (const value of uses.values) {\n report({\n node: value,\n reason: `\\`${mapping.oldName}\\` is used as a value (passed, stored, exported or in typeof), so its import stays; change it by hand to ${mapping.className}.${mapping.method}`,\n });\n }\n\n if (uses.calls.length === 0) {\n continue;\n }\n\n const shadow = declarationsOf(binding.local).find(\n (identifier) => identifier !== binding.declarationName,\n );\n\n if (shadow) {\n report({\n node: shadow,\n reason: `\\`${binding.local}\\` is declared again in this file, so a call cannot be told apart from the import; rewrite the calls of \\`${mapping.oldName}\\` by hand as ${target}`,\n });\n continue;\n }\n\n const classModules = mapping.newModules ?? [binding.module];\n const isNamespaceReach = !binding.specifier && classModules.includes(binding.module);\n let classReference = `${binding.local}.${mapping.className}`;\n let needsImport = false;\n\n if (!isNamespaceReach) {\n const existing = NamespaceFunctions.findClassImport({\n typescript,\n sourceFile,\n className: mapping.className,\n modules: classModules,\n });\n const plannedModule = planned.get(mapping.className);\n const conflict = existing\n ? declarationsOf(existing.text).find((identifier) => identifier !== existing)\n : plannedModule === undefined\n ? declarationsOf(mapping.className)[0]\n : undefined;\n\n if (conflict) {\n report({\n node: uses.calls[0] ?? conflict,\n reason: `the name \\`${conflict.text}\\` is already declared in this file (line ${lineOf(conflict)}), so \\`${mapping.oldName}\\` is left; rewrite its calls by hand as ${target}`,\n });\n continue;\n }\n\n if (!existing && plannedModule !== undefined && !classModules.includes(plannedModule)) {\n report({\n node: uses.calls[0] ?? binding.declaration,\n reason: `\\`${mapping.className}\\` would be imported from both ${plannedModule} and ${classModules[0]}; rewrite the calls of \\`${mapping.oldName}\\` by hand as ${target}`,\n });\n continue;\n }\n\n classReference = existing?.text ?? mapping.className;\n needsImport = !existing && plannedModule === undefined;\n }\n\n let count = 0;\n let left = uses.values.length;\n\n for (const call of uses.calls) {\n const problem = NamespaceFunctions.checkCall({ typescript, call, mapping });\n\n if (problem) {\n left += 1;\n report({ node: call, reason: `${problem}; rewrite it by hand as ${target}` });\n continue;\n }\n\n edits.push(\n ...NamespaceFunctions.planCall({\n typescript,\n sourceFile,\n call,\n mapping,\n callee: `${classReference}.${mapping.method}`,\n }),\n );\n count += 1;\n }\n\n rewritten += count;\n\n if (count === 0) {\n continue;\n }\n\n if (needsImport) {\n const sameDeclaration =\n binding.specifier && classModules.includes(binding.module)\n ? binding.declaration\n : undefined;\n const declaration =\n sameDeclaration ??\n NamespaceFunctions.findNamedImport({ typescript, sourceFile, modules: classModules });\n\n if (declaration) {\n additions.set(\n declaration,\n new Set([...(additions.get(declaration) ?? []), mapping.className]),\n );\n planned.set(\n mapping.className,\n sameDeclaration ? binding.module : NamespaceFunctions.moduleOf({ declaration }),\n );\n } else {\n const module = classModules[0] ?? binding.module;\n const entry = newImports.get(module) ?? {\n anchor: binding.declaration,\n names: new Set<string>(),\n };\n entry.names.add(mapping.className);\n newImports.set(module, entry);\n planned.set(mapping.className, module);\n }\n }\n\n if (binding.specifier && left === 0) {\n removals.add(binding.specifier);\n trimmed.add(binding.declaration);\n }\n }\n\n if (rewritten === 0) {\n return { output: source, changed: false, rewritten: 0, reports };\n }\n\n for (const declaration of new Set([...additions.keys(), ...trimmed])) {\n edits.push(\n ...NamespaceFunctions.planImport({\n typescript,\n sourceFile,\n declaration,\n removals,\n additions: [...(additions.get(declaration) ?? [])],\n report,\n }),\n );\n }\n\n for (const [module, { anchor, names }] of newImports) {\n const quote = source.charAt(anchor.moduleSpecifier.getStart(sourceFile));\n edits.push({\n start: anchor.getStart(sourceFile),\n end: anchor.getStart(sourceFile),\n text: `import { ${[...names].join(', ')} } from ${quote}${module}${quote};\\n`,\n });\n }\n\n // At one position a replacement (the longer range) is applied before an insertion, so the\n // inserted key of an outer call lands in front of the rewritten callee of an inner one.\n let output = source;\n\n for (const edit of edits.sort((a, b) => b.start - a.start || b.end - a.end)) {\n output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);\n }\n\n return { output, changed: output !== source, rewritten, reports };\n }\n\n /** The named and namespace imports of an old name; reports the type-only imports and the re-exports. */\n private static findBindings(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n byModule: Map<string, INamespaceMapping[]>;\n report: (reportOpts: { node: ts.Node; reason: string }) => void;\n }): IBinding[] {\n const { typescript, sourceFile, byModule, report } = opts;\n const bindings: IBinding[] = [];\n\n for (const statement of sourceFile.statements) {\n if (\n typescript.isExportDeclaration(statement) &&\n statement.moduleSpecifier &&\n typescript.isStringLiteral(statement.moduleSpecifier) &&\n statement.exportClause &&\n typescript.isNamedExports(statement.exportClause)\n ) {\n const candidates = byModule.get(statement.moduleSpecifier.text) ?? [];\n\n for (const element of statement.exportClause.elements) {\n const name = (element.propertyName ?? element.name).text;\n const mapping = candidates.find((candidate) => candidate.oldName === name);\n\n if (mapping) {\n report({\n node: element,\n reason: `re-exports \\`${name}\\`; re-export ${mapping.className} as well, by hand`,\n });\n }\n }\n\n continue;\n }\n\n if (\n !typescript.isImportDeclaration(statement) ||\n !typescript.isStringLiteral(statement.moduleSpecifier) ||\n !statement.importClause\n ) {\n continue;\n }\n\n const module = statement.moduleSpecifier.text;\n const candidates = byModule.get(module);\n const clause = statement.importClause;\n const named = clause.namedBindings;\n\n if (!candidates || !named) {\n continue;\n }\n\n if (typescript.isNamespaceImport(named)) {\n if (clause.isTypeOnly) {\n continue;\n }\n\n for (const mapping of candidates) {\n bindings.push({\n mapping,\n declaration: statement,\n module,\n local: named.name.text,\n declarationName: named.name,\n });\n }\n\n continue;\n }\n\n for (const element of named.elements) {\n const imported = (element.propertyName ?? element.name).text;\n const mapping = candidates.find((candidate) => candidate.oldName === imported);\n\n if (!mapping) {\n continue;\n }\n\n if (clause.isTypeOnly || element.isTypeOnly) {\n report({\n node: element,\n reason: `\\`${imported}\\` is imported as a type only; change it by hand to \\`typeof ${mapping.className}.${mapping.method}\\``,\n });\n continue;\n }\n\n bindings.push({\n mapping,\n declaration: statement,\n module,\n local: element.name.text,\n declarationName: element.name,\n specifier: element,\n });\n }\n }\n\n return bindings;\n }\n\n /** Every identifier of the file by its text; JSDoc is not walked, so a `{@link name}` never counts. */\n private static collectIdentifiers(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n }): Map<string, ts.Identifier[]> {\n const { typescript, sourceFile } = opts;\n const identifiers = new Map<string, ts.Identifier[]>();\n\n const walk = (node: ts.Node): void => {\n if (typescript.isIdentifier(node)) {\n identifiers.set(node.text, [...(identifiers.get(node.text) ?? []), node]);\n }\n\n typescript.forEachChild(node, walk);\n };\n\n walk(sourceFile);\n\n return identifiers;\n }\n\n /** The calls of the old name, and every other use of it. */\n private static findUses(opts: {\n typescript: TTypeScript;\n binding: IBinding;\n identifiers: Map<string, ts.Identifier[]>;\n }): IUses {\n const { typescript, binding, identifiers } = opts;\n const uses: IUses = { calls: [], values: [] };\n\n for (const identifier of identifiers.get(binding.local) ?? []) {\n if (\n identifier === binding.declarationName ||\n !NamespaceFunctions.isReference({ typescript, identifier })\n ) {\n continue;\n }\n\n if (!binding.specifier) {\n const parent = identifier.parent;\n const isMember =\n typescript.isPropertyAccessExpression(parent) &&\n parent.expression === identifier &&\n parent.name.text === binding.mapping.oldName;\n\n if (isMember) {\n const call = parent.parent;\n\n if (typescript.isCallExpression(call) && call.expression === parent) {\n uses.calls.push(call);\n } else {\n uses.values.push(parent);\n }\n\n continue;\n }\n\n if (\n typescript.isQualifiedName(parent) &&\n parent.left === identifier &&\n parent.right.text === binding.mapping.oldName\n ) {\n uses.values.push(parent);\n }\n\n continue;\n }\n\n const parent = identifier.parent;\n\n if (typescript.isCallExpression(parent) && parent.expression === identifier) {\n uses.calls.push(parent);\n continue;\n }\n\n uses.values.push(identifier);\n }\n\n return uses;\n }\n\n /** The identifier names a declaration: a variable, a parameter, a function, a class, an import, a type. */\n private static isDeclarationName(opts: {\n typescript: TTypeScript;\n identifier: ts.Identifier;\n }): boolean {\n const { typescript, identifier } = opts;\n const parent = identifier.parent;\n\n if (\n typescript.isVariableDeclaration(parent) ||\n typescript.isParameter(parent) ||\n typescript.isBindingElement(parent) ||\n typescript.isFunctionDeclaration(parent) ||\n typescript.isFunctionExpression(parent) ||\n typescript.isClassDeclaration(parent) ||\n typescript.isClassExpression(parent) ||\n typescript.isEnumDeclaration(parent) ||\n typescript.isInterfaceDeclaration(parent) ||\n typescript.isTypeAliasDeclaration(parent) ||\n typescript.isModuleDeclaration(parent) ||\n typescript.isImportSpecifier(parent) ||\n typescript.isImportClause(parent) ||\n typescript.isNamespaceImport(parent) ||\n typescript.isImportEqualsDeclaration(parent) ||\n typescript.isTypeParameterDeclaration(parent)\n ) {\n return parent.name === identifier;\n }\n\n return false;\n }\n\n /** The identifier reads a binding: not a property name, a label, a declaration or a lowercase JSX tag. */\n private static isReference(opts: {\n typescript: TTypeScript;\n identifier: ts.Identifier;\n }): boolean {\n const { typescript, identifier } = opts;\n const parent = identifier.parent;\n\n if (NamespaceFunctions.isDeclarationName({ typescript, identifier })) {\n return false;\n }\n\n if (typescript.isPropertyAccessExpression(parent) || typescript.isQualifiedName(parent)) {\n return typescript.isPropertyAccessExpression(parent)\n ? parent.name !== identifier\n : parent.right !== identifier;\n }\n\n if (\n typescript.isPropertyAssignment(parent) ||\n typescript.isPropertyDeclaration(parent) ||\n typescript.isPropertySignature(parent) ||\n typescript.isMethodDeclaration(parent) ||\n typescript.isMethodSignature(parent) ||\n typescript.isGetAccessorDeclaration(parent) ||\n typescript.isSetAccessorDeclaration(parent) ||\n typescript.isEnumMember(parent) ||\n typescript.isJsxAttribute(parent)\n ) {\n return parent.name !== identifier;\n }\n\n if (typescript.isBindingElement(parent)) {\n return parent.propertyName !== identifier;\n }\n\n if (typescript.isExportSpecifier(parent)) {\n return (\n !parent.parent.parent.moduleSpecifier && (parent.propertyName ?? parent.name) === identifier\n );\n }\n\n if (\n typescript.isLabeledStatement(parent) ||\n typescript.isBreakOrContinueStatement(parent) ||\n typescript.isMetaProperty(parent)\n ) {\n return false;\n }\n\n if (\n (typescript.isJsxOpeningElement(parent) ||\n typescript.isJsxSelfClosingElement(parent) ||\n typescript.isJsxClosingElement(parent)) &&\n parent.tagName === identifier\n ) {\n return !/^[a-z]/.test(identifier.text);\n }\n\n return true;\n }\n\n /** Why a call cannot be rewritten, or `undefined` when it can. */\n private static checkCall(opts: {\n typescript: TTypeScript;\n call: ts.CallExpression;\n mapping: INamespaceMapping;\n }): string | undefined {\n const { typescript, call, mapping } = opts;\n const { params, restKey, oldName } = mapping;\n const count = call.arguments.length;\n\n if (mapping.keepsOptions) {\n return undefined;\n }\n\n if (call.arguments.some((argument) => typescript.isSpreadElement(argument))) {\n return `this call of \\`${oldName}\\` has a spread argument`;\n }\n\n const required = params.reduce(\n (last, parameter, index) => (parameter.optional ? last : index + 1),\n 0,\n );\n\n if (count < required) {\n return `this call of \\`${oldName}\\` passes ${count} argument(s), fewer than the ${required} it needs`;\n }\n\n if (restKey === undefined && count > params.length) {\n return `this call of \\`${oldName}\\` passes ${count} argument(s), more than its ${params.length} parameter(s)`;\n }\n\n return undefined;\n }\n\n /** The edits that turn one call into the class form; the arguments keep their text and comments. */\n private static planCall(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n call: ts.CallExpression;\n mapping: INamespaceMapping;\n callee: string;\n }): IEdit[] {\n const { typescript, sourceFile, call, mapping, callee } = opts;\n const { params, restKey } = mapping;\n const edits: IEdit[] = [\n { start: call.expression.getStart(sourceFile), end: call.expression.end, text: callee },\n ];\n\n if (call.questionDotToken) {\n edits.push({\n start: call.questionDotToken.getStart(sourceFile),\n end: call.questionDotToken.end,\n text: '',\n });\n }\n\n if (mapping.keepsOptions) {\n return edits;\n }\n\n const argumentList = [...call.arguments];\n\n if (argumentList.length === 0) {\n if (params.length > 0 || restKey !== undefined) {\n const text = restKey === undefined ? '{}' : `{ ${restKey}: [] }`;\n edits.push({ start: call.arguments.pos, end: call.arguments.pos, text });\n }\n\n return edits;\n }\n\n const insert = (insertOpts: { at: number; text: string }) => {\n if (insertOpts.text !== '') {\n edits.push({ start: insertOpts.at, end: insertOpts.at, text: insertOpts.text });\n }\n };\n\n const positional = argumentList.slice(0, params.length);\n const rest = argumentList.slice(params.length);\n\n positional.forEach((argument, index) => {\n const key = params[index]?.key ?? '';\n const isShorthand = typescript.isIdentifier(argument) && argument.text === key;\n insert({\n at: argument.getStart(sourceFile),\n text: `${index === 0 ? '{ ' : ''}${isShorthand ? '' : `${key}: `}`,\n });\n });\n\n const first = rest[0];\n const last = argumentList[argumentList.length - 1];\n let suffix = ' }';\n\n if (first && restKey !== undefined) {\n insert({\n at: first.getStart(sourceFile),\n text: `${positional.length === 0 ? '{ ' : ''}${restKey}: [`,\n });\n suffix = '] }';\n } else if (restKey !== undefined) {\n suffix = `, ${restKey}: [] }`;\n }\n\n insert({ at: last?.end ?? call.arguments.end, text: suffix });\n\n return edits;\n }\n\n /** The local name of a value import of the class from one of `modules`. */\n private static findClassImport(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n className: string;\n modules: string[];\n }): ts.Identifier | undefined {\n const { typescript, sourceFile, className, modules } = opts;\n\n for (const statement of sourceFile.statements) {\n const declaration = NamespaceFunctions.asValueImport({ typescript, statement, modules });\n const named = declaration?.importClause?.namedBindings;\n\n if (!named || !typescript.isNamedImports(named)) {\n continue;\n }\n\n const element = named.elements.find(\n (candidate) =>\n !candidate.isTypeOnly && (candidate.propertyName ?? candidate.name).text === className,\n );\n\n if (element) {\n return element.name;\n }\n }\n\n return undefined;\n }\n\n /** The first value import with braces from one of `modules`, to add a class to. */\n private static findNamedImport(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n modules: string[];\n }): ts.ImportDeclaration | undefined {\n const { typescript, sourceFile, modules } = opts;\n\n for (const statement of sourceFile.statements) {\n const declaration = NamespaceFunctions.asValueImport({ typescript, statement, modules });\n const named = declaration?.importClause?.namedBindings;\n\n if (declaration && named && typescript.isNamedImports(named)) {\n return declaration;\n }\n }\n\n return undefined;\n }\n\n /** `statement` as an import that is not `import type`, from one of `modules`. */\n private static asValueImport(opts: {\n typescript: TTypeScript;\n statement: ts.Statement;\n modules: string[];\n }): ts.ImportDeclaration | undefined {\n const { typescript, statement, modules } = opts;\n\n if (\n typescript.isImportDeclaration(statement) &&\n typescript.isStringLiteral(statement.moduleSpecifier) &&\n modules.includes(statement.moduleSpecifier.text) &&\n statement.importClause &&\n !statement.importClause.isTypeOnly\n ) {\n return statement;\n }\n\n return undefined;\n }\n\n private static moduleOf(opts: { declaration: ts.ImportDeclaration }): string {\n const specifier = opts.declaration.moduleSpecifier;\n\n return 'text' in specifier && typeof specifier.text === 'string' ? specifier.text : '';\n }\n\n /**\n * The edit of one import's braces: the removed old names go, the added classes take the place of\n * the first removed one. Braces that hold a comment are not rewritten: the classes are appended\n * and the old names stay, reported. An import left with nothing is removed.\n */\n private static planImport(opts: {\n typescript: TTypeScript;\n sourceFile: ts.SourceFile;\n declaration: ts.ImportDeclaration;\n removals: Set<ts.ImportSpecifier>;\n additions: string[];\n report: (reportOpts: { node: ts.Node; reason: string }) => void;\n }): IEdit[] {\n const { typescript, sourceFile, declaration, removals, additions, report } = opts;\n const clause = declaration.importClause;\n const named = clause?.namedBindings;\n\n if (!clause || !named || !typescript.isNamedImports(named)) {\n return [];\n }\n\n const source = sourceFile.text;\n const elements = [...named.elements];\n const braces = source.slice(named.getStart(sourceFile), named.end);\n\n if (/\\/\\*|\\/\\//.test(braces)) {\n for (const element of elements.filter((candidate) => removals.has(candidate))) {\n report({\n node: element,\n reason: `the braces of this import hold a comment, so \\`${element.name.text}\\` stays imported; remove it by hand`,\n });\n }\n\n const last = elements[elements.length - 1];\n\n if (!last || additions.length === 0) {\n return [];\n }\n\n return [{ start: last.end, end: last.end, text: `, ${additions.join(', ')}` }];\n }\n\n const items: string[] = [];\n let isPlaced = false;\n\n for (const element of elements) {\n if (!removals.has(element)) {\n items.push(element.getText(sourceFile));\n continue;\n }\n\n if (!isPlaced) {\n items.push(...additions);\n isPlaced = true;\n }\n }\n\n if (!isPlaced) {\n items.push(...additions);\n }\n\n if (items.length > 0) {\n const start = named.getStart(sourceFile);\n const lineStart = source.lastIndexOf('\\n', declaration.getStart(sourceFile)) + 1;\n const indent = /^[ \\t]*/.exec(source.slice(lineStart))?.[0] ?? '';\n const text = braces.includes('\\n')\n ? `{\\n${indent} ${items.join(`,\\n${indent} `)},\\n${indent}}`\n : `{ ${items.join(', ')} }`;\n\n return [{ start, end: named.end, text }];\n }\n\n if (clause.name) {\n return [{ start: clause.name.end, end: named.end, text: '' }];\n }\n\n const start = declaration.getStart(sourceFile);\n const newline = /^\\r?\\n/.exec(source.slice(declaration.end))?.[0] ?? '';\n\n return [{ start, end: declaration.end + newline.length, text: '' }];\n }\n\n /** The call the old one becomes, for a report: `ParseUtility.toFloat({ input, digit })`. */\n private static describeTarget(opts: { mapping: INamespaceMapping }): string {\n const { className, method, params, restKey } = opts.mapping;\n const keys = [...params.map((parameter) => parameter.key), ...(restKey ? [restKey] : [])];\n\n return keys.length === 0\n ? `${className}.${method}()`\n : `${className}.${method}({ ${keys.join(', ')} })`;\n }\n}\n"]}
|
package/dist/linters/eslint.js
CHANGED
|
@@ -77,9 +77,14 @@ const STRICT_RULES = {
|
|
|
77
77
|
'@typescript-eslint/await-thenable': 'error',
|
|
78
78
|
'@typescript-eslint/no-floating-promises': 'error',
|
|
79
79
|
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
80
|
+
// `||` on a string is mostly an intentional empty-string fallback (`value?.trim() || fallback`); `??` keeps `''`.
|
|
81
|
+
// The same exception as the oxlint preset: objects, numbers and booleans still report.
|
|
80
82
|
'@typescript-eslint/prefer-nullish-coalescing': [
|
|
81
83
|
'error',
|
|
82
|
-
{
|
|
84
|
+
{
|
|
85
|
+
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: true,
|
|
86
|
+
ignorePrimitives: { string: true },
|
|
87
|
+
},
|
|
83
88
|
],
|
|
84
89
|
'@typescript-eslint/return-await': 'error',
|
|
85
90
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/linters/eslint.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAE5B,0CAA6C;AAC7C,0EAAyC;AACzC,2CAAwD;AACxD,yEAAmE;AACnE,2CAAmD;AACnD,uCAA2C;AAC3C,mCAA0F;AAE1F,mCAAmC;AACnC,MAAM,YAAY,GAAG;IACnB,SAAS;IACT,UAAU;IACV,UAAU;IACV,UAAU;IACV,SAAS;IACT,UAAU;IACV,UAAU;IACV,UAAU;CACX,CAAC;AAEF,qGAAqG;AACrG,MAAM,SAAS,GAAuB;IACpC,uBAAuB,EAAE,KAAK;IAC9B,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,KAAK;IACvB,oBAAoB,EAAE,KAAK;IAC3B,uBAAuB,EAAE,KAAK;IAC9B,uBAAuB,EAAE,KAAK;IAC9B,cAAc,EAAE,KAAK;IACrB,iBAAiB,EAAE,KAAK;IACxB,WAAW,EAAE,KAAK;IAClB,iBAAiB,EAAE,KAAK;IACxB,SAAS,EAAE,KAAK;IAChB,oCAAoC,EAAE,KAAK;IAC3C,4CAA4C,EAAE,KAAK;IACnD,kCAAkC,EAAE,KAAK;IACzC,yCAAyC,EAAE,KAAK;IAChD,yCAAyC,EAAE,KAAK;IAChD,iDAAiD,EAAE,KAAK;IACxD,wCAAwC,EAAE,KAAK;IAC/C,uCAAuC,EAAE,KAAK;IAC9C,+CAA+C,EAAE,KAAK;IACtD,kDAAkD,EAAE,KAAK;IACzD,kDAAkD,EAAE,KAAK;IACzD,mDAAmD,EAAE,KAAK;IAC1D,+BAA+B,EAAE,KAAK;IACtC,0CAA0C,EAAE,KAAK;IACjD,sCAAsC,EAAE,KAAK;IAC7C,+CAA+C,EAAE,KAAK;IACtD,wCAAwC,EAAE,KAAK;CAChD,CAAC;AAEF,kEAAkE;AAClE,MAAM,YAAY,GAAuB;IACvC,cAAc,EAAE,OAAO;IACvB,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;IACvB,iBAAiB,EAAE,OAAO;IAC1B,kBAAkB,EAAE,OAAO;IAC3B,uBAAuB,EAAE,OAAO;IAChC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO;IAClB,mBAAmB,EAAE,MAAM;IAC3B,WAAW,EAAE,OAAO;IACpB,iDAAiD,EAAE,OAAO;IAC1D,kCAAkC,EAAE,OAAO;IAC3C,uCAAuC,EAAE,OAAO;IAChD,oCAAoC,EAAE,CAAC,OAAO,CAAC;IAC/C,yCAAyC,EAAE,OAAO;IAClD,8BAA8B,EAAE,OAAO;IACvC,mCAAmC,EAAE,OAAO;IAC5C,iCAAiC,EAAE,OAAO;IAC1C,mCAAmC,EAAE,OAAO;IAC5C,yCAAyC,EAAE,OAAO;IAClD,0CAA0C,EAAE,OAAO;IACnD,8CAA8C,EAAE;QAC9C,OAAO;QACP,EAAE,
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/linters/eslint.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAE5B,0CAA6C;AAC7C,0EAAyC;AACzC,2CAAwD;AACxD,yEAAmE;AACnE,2CAAmD;AACnD,uCAA2C;AAC3C,mCAA0F;AAE1F,mCAAmC;AACnC,MAAM,YAAY,GAAG;IACnB,SAAS;IACT,UAAU;IACV,UAAU;IACV,UAAU;IACV,SAAS;IACT,UAAU;IACV,UAAU;IACV,UAAU;CACX,CAAC;AAEF,qGAAqG;AACrG,MAAM,SAAS,GAAuB;IACpC,uBAAuB,EAAE,KAAK;IAC9B,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,KAAK;IACvB,oBAAoB,EAAE,KAAK;IAC3B,uBAAuB,EAAE,KAAK;IAC9B,uBAAuB,EAAE,KAAK;IAC9B,cAAc,EAAE,KAAK;IACrB,iBAAiB,EAAE,KAAK;IACxB,WAAW,EAAE,KAAK;IAClB,iBAAiB,EAAE,KAAK;IACxB,SAAS,EAAE,KAAK;IAChB,oCAAoC,EAAE,KAAK;IAC3C,4CAA4C,EAAE,KAAK;IACnD,kCAAkC,EAAE,KAAK;IACzC,yCAAyC,EAAE,KAAK;IAChD,yCAAyC,EAAE,KAAK;IAChD,iDAAiD,EAAE,KAAK;IACxD,wCAAwC,EAAE,KAAK;IAC/C,uCAAuC,EAAE,KAAK;IAC9C,+CAA+C,EAAE,KAAK;IACtD,kDAAkD,EAAE,KAAK;IACzD,kDAAkD,EAAE,KAAK;IACzD,mDAAmD,EAAE,KAAK;IAC1D,+BAA+B,EAAE,KAAK;IACtC,0CAA0C,EAAE,KAAK;IACjD,sCAAsC,EAAE,KAAK;IAC7C,+CAA+C,EAAE,KAAK;IACtD,wCAAwC,EAAE,KAAK;CAChD,CAAC;AAEF,kEAAkE;AAClE,MAAM,YAAY,GAAuB;IACvC,cAAc,EAAE,OAAO;IACvB,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;IACvB,iBAAiB,EAAE,OAAO;IAC1B,kBAAkB,EAAE,OAAO;IAC3B,uBAAuB,EAAE,OAAO;IAChC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO;IAClB,mBAAmB,EAAE,MAAM;IAC3B,WAAW,EAAE,OAAO;IACpB,iDAAiD,EAAE,OAAO;IAC1D,kCAAkC,EAAE,OAAO;IAC3C,uCAAuC,EAAE,OAAO;IAChD,oCAAoC,EAAE,CAAC,OAAO,CAAC;IAC/C,yCAAyC,EAAE,OAAO;IAClD,8BAA8B,EAAE,OAAO;IACvC,mCAAmC,EAAE,OAAO;IAC5C,iCAAiC,EAAE,OAAO;IAC1C,mCAAmC,EAAE,OAAO;IAC5C,yCAAyC,EAAE,OAAO;IAClD,0CAA0C,EAAE,OAAO;IACnD,kHAAkH;IAClH,uFAAuF;IACvF,8CAA8C,EAAE;QAC9C,OAAO;QACP;YACE,sDAAsD,EAAE,IAAI;YAC5D,gBAAgB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SACnC;KACF;IACD,iCAAiC,EAAE,OAAO;CAC3C,CAAC;AAEF;;;;GAIG;AACU,QAAA,aAAa,GAAoB,IAAA,qBAAY,EAAC;IACzD,YAAE,CAAC,OAAO,CAAC,WAAW;IACtB,2BAAQ,CAAC,OAAO,CAAC,WAAW;IAC5B;QACE,KAAK,EAAE,YAAY;QACnB,eAAe,EAAE;YACf,aAAa,EAAE;gBACb,yFAAyF;gBACzF,cAAc,EAAE,EAAE,mBAAmB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;aAC7E;SACF;QACD,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE;YACL,GAAG,SAAS;YACZ,GAAG,YAAY;YACf,CAAC,0CAAkB,CAAC,IAAI,CAAC,EAAE,0CAAkB,CAAC,KAAK,EAAE;YACrD,mCAAmC,EAAE,wBAAgB,CAAC,KAAK,EAAsB;YACjF,CAAC,+BAAuB,CAAC,IAAI,CAAC,EAAE,+BAAuB,CAAC,KAAK,EAAsB;YACnF,CAAC,4BAAoB,CAAC,IAAI,CAAC,EAAE,4BAAoB,CAAC,KAAK,EAAE;SAC1D;KACF;IACD,GAAG,wBAAc;IACjB;QACE,OAAO,EAAE;YACP,kBAAkB;YAClB,WAAW;YACX,WAAW;YACX,UAAU;YACV,aAAa;YACb,mBAAmB;YACnB,eAAe;YACf,oBAAoB;YACpB,gBAAgB;SACjB;KACF;CACF,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACU,QAAA,uBAAuB,GAAoB;IACtD,6FAA6F;IAC7F,EAAE,OAAO,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,mBAAmB,CAAC,EAAE;IAC9F;QACE,KAAK,EAAE,CAAC,uBAAuB,CAAC;QAChC,eAAe,EAAE,EAAE,MAAM,EAAE,2BAAQ,CAAC,MAAuB,EAAE;QAC7D,OAAO,EAAE,EAAE,oBAAoB,EAAE,2BAAQ,CAAC,MAAe,EAAE;QAC3D,4FAA4F;QAC5F,aAAa,EAAE,EAAE,6BAA6B,EAAE,KAAK,EAAE;QACvD,KAAK,EAAE,EAAE,CAAC,4BAAoB,CAAC,IAAI,CAAC,EAAE,4BAAoB,CAAC,KAAK,EAAE,EAAE;KACrE;CACF,CAAC","sourcesContent":["import js from '@eslint/js';\nimport type { Linter } from 'eslint';\nimport { defineConfig } from 'eslint/config';\nimport tseslint from 'typescript-eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './house/common';\nimport { NoUnbracedCaseRule } from './house/no-unbraced-case.rule';\nimport { houseEslintPlugin } from './house/plugin';\nimport { paddingConfigs } from './padding';\nimport { NamingConventionRule, NoRestrictedImportsRule, NoUnusedVarsRule } from './rules';\n\n/** Every file the preset lints. */\nconst SOURCE_FILES = [\n '**/*.js',\n '**/*.cjs',\n '**/*.mjs',\n '**/*.jsx',\n '**/*.ts',\n '**/*.cts',\n '**/*.mts',\n '**/*.tsx',\n];\n\n/** Rules that stay off: the type checker, the formatter or the framework's own style covers them. */\nconst OFF_RULES: Linter.RulesRecord = {\n 'no-constant-condition': 'off',\n 'no-undef': 'off',\n 'no-unused-vars': 'off',\n 'no-mixed-operators': 'off',\n 'no-inner-declarations': 'off',\n 'no-dupe-class-members': 'off',\n 'no-redeclare': 'off',\n 'no-invalid-this': 'off',\n 'no-shadow': 'off',\n 'no-return-await': 'off',\n camelcase: 'off',\n '@typescript-eslint/no-explicit-any': 'off',\n '@typescript-eslint/no-unsafe-function-type': 'off',\n '@typescript-eslint/no-this-alias': 'off',\n '@typescript-eslint/no-empty-object-type': 'off',\n '@typescript-eslint/no-invalid-void-type': 'off',\n '@typescript-eslint/no-confusing-void-expression': 'off',\n '@typescript-eslint/no-extraneous-class': 'off',\n '@typescript-eslint/no-require-imports': 'off',\n '@typescript-eslint/strict-boolean-expressions': 'off',\n '@typescript-eslint/explicit-function-return-type': 'off',\n '@typescript-eslint/explicit-member-accessibility': 'off',\n '@typescript-eslint/explicit-module-boundary-types': 'off',\n '@typescript-eslint/array-type': 'off',\n '@typescript-eslint/no-non-null-assertion': 'off',\n '@typescript-eslint/no-empty-function': 'off',\n '@typescript-eslint/consistent-type-assertions': 'off',\n '@typescript-eslint/no-misused-promises': 'off',\n};\n\n/** The LoopBack 4 rule set, on top of the recommended presets. */\nconst STRICT_RULES: Linter.RulesRecord = {\n 'prefer-const': 'error',\n 'no-var': 'error',\n curly: ['error', 'all'],\n 'no-new-wrappers': 'error',\n 'no-throw-literal': 'error',\n 'no-unused-expressions': 'error',\n eqeqeq: ['error', 'smart'],\n 'no-void': 'error',\n 'no-useless-escape': 'warn',\n 'no-caller': 'error',\n '@typescript-eslint/adjacent-overload-signatures': 'error',\n '@typescript-eslint/prefer-for-of': 'error',\n '@typescript-eslint/unified-signatures': 'error',\n '@typescript-eslint/no-invalid-this': ['error'],\n '@typescript-eslint/no-use-before-define': 'error',\n '@typescript-eslint/no-shadow': 'error',\n '@typescript-eslint/ban-ts-comment': 'error',\n '@typescript-eslint/no-namespace': 'error',\n '@typescript-eslint/await-thenable': 'error',\n '@typescript-eslint/no-floating-promises': 'error',\n '@typescript-eslint/prefer-optional-chain': 'error',\n // `||` on a string is mostly an intentional empty-string fallback (`value?.trim() || fallback`); `??` keeps `''`.\n // The same exception as the oxlint preset: objects, numbers and booleans still report.\n '@typescript-eslint/prefer-nullish-coalescing': [\n 'error',\n {\n allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: true,\n ignorePrimitives: { string: true },\n },\n ],\n '@typescript-eslint/return-await': 'error',\n};\n\n/**\n * The full ESLint preset, owned here: the LoopBack 4 rule set on the ESLint and typescript-eslint\n * recommended presets, type-aware through the project service. A project on oxlint uses\n * `oxlintConfigs` + `namingConventionConfigs` instead.\n */\nexport const eslintConfigs: Linter.Config[] = defineConfig([\n js.configs.recommended,\n tseslint.configs.recommended,\n {\n files: SOURCE_FILES,\n languageOptions: {\n parserOptions: {\n // Finds each file's tsconfig; the default project covers root-level scripts and configs.\n projectService: { allowDefaultProject: ['*.js', '*.cjs', '*.mjs', '.*.js'] },\n },\n },\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: {\n ...OFF_RULES,\n ...STRICT_RULES,\n [NoUnbracedCaseRule.NAME]: NoUnbracedCaseRule.build(),\n '@typescript-eslint/no-unused-vars': NoUnusedVarsRule.build() as Linter.RuleEntry,\n [NoRestrictedImportsRule.NAME]: NoRestrictedImportsRule.build() as Linter.RuleEntry,\n [NamingConventionRule.NAME]: NamingConventionRule.build(),\n },\n },\n ...paddingConfigs,\n {\n ignores: [\n '**/node_modules/',\n '**/*.d.ts',\n '**/build/',\n '**/dist/',\n '**/release/',\n '**/babel.config.*',\n '**/.babelrc.*',\n '**/eslint.config.*',\n '**/.eslintrc.*',\n ],\n },\n]);\n\n/**\n * The one rule of `eslintConfigs` that oxlint cannot run yet, as a standalone ESLint preset to run\n * next to `oxlintConfigs`. It needs no type information, so ESLint stays fast.\n *\n * ```js\n * // .configs/lints/eslint.config.mjs\n * import { namingConventionConfigs } from '@venizia/dev-configs/linters';\n *\n * export default namingConventionConfigs;\n * ```\n */\nexport const namingConventionConfigs: Linter.Config[] = [\n // Global: ESLint does not read .gitignore, and still walks plain .js files no config claims.\n { ignores: ['**/dist/**', '**/build/**', '**/coverage/**', '**/*.d.ts', '**/*.{js,cjs,mjs}'] },\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser as Linter.Parser },\n plugins: { '@typescript-eslint': tseslint.plugin as never },\n // oxlint owns every other rule, so the disable comments for them are not ESLint's to judge.\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n rules: { [NamingConventionRule.NAME]: NamingConventionRule.build() },\n },\n];\n"]}
|
|
@@ -2,7 +2,7 @@ import type { Linter } from 'eslint';
|
|
|
2
2
|
/**
|
|
3
3
|
* The async style rules: `await` stands alone as a statement or as the whole initializer of a declaration
|
|
4
4
|
* (`no-inline-await`), a function returns the promise instead of `return await` (`no-return-await`), an `await`
|
|
5
|
-
* never takes a promise chain (`no-await-promise-chain`), and a caught error leaves a trace (`no-silent-catch`).
|
|
5
|
+
* never takes a promise chain (`no-await-promise-chain`) or a method called on a new instance (`no-await-new-chain`), and a caught error leaves a trace (`no-silent-catch`).
|
|
6
6
|
* They apply to test files too. Not exported from the package: `houseConfigs` and `reactHouseConfigs` carry them, and
|
|
7
7
|
* `devz codemod async-style` runs them alone.
|
|
8
8
|
*/
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.asyncRuleConfigs = void 0;
|
|
4
4
|
const common_1 = require("./common");
|
|
5
|
+
const no_await_new_chain_rule_1 = require("./no-await-new-chain.rule");
|
|
5
6
|
const no_await_promise_chain_rule_1 = require("./no-await-promise-chain.rule");
|
|
6
7
|
const no_inline_await_rule_1 = require("./no-inline-await.rule");
|
|
7
8
|
const no_return_await_rule_1 = require("./no-return-await.rule");
|
|
@@ -10,7 +11,7 @@ const plugin_1 = require("./plugin");
|
|
|
10
11
|
/**
|
|
11
12
|
* The async style rules: `await` stands alone as a statement or as the whole initializer of a declaration
|
|
12
13
|
* (`no-inline-await`), a function returns the promise instead of `return await` (`no-return-await`), an `await`
|
|
13
|
-
* never takes a promise chain (`no-await-promise-chain`), and a caught error leaves a trace (`no-silent-catch`).
|
|
14
|
+
* never takes a promise chain (`no-await-promise-chain`) or a method called on a new instance (`no-await-new-chain`), and a caught error leaves a trace (`no-silent-catch`).
|
|
14
15
|
* They apply to test files too. Not exported from the package: `houseConfigs` and `reactHouseConfigs` carry them, and
|
|
15
16
|
* `devz codemod async-style` runs them alone.
|
|
16
17
|
*/
|
|
@@ -21,6 +22,7 @@ exports.asyncRuleConfigs = [
|
|
|
21
22
|
rules: {
|
|
22
23
|
[no_inline_await_rule_1.NoInlineAwaitRule.NAME]: no_inline_await_rule_1.NoInlineAwaitRule.build(),
|
|
23
24
|
[no_return_await_rule_1.NoReturnAwaitRule.NAME]: no_return_await_rule_1.NoReturnAwaitRule.build(),
|
|
25
|
+
[no_await_new_chain_rule_1.NoAwaitNewChainRule.NAME]: no_await_new_chain_rule_1.NoAwaitNewChainRule.build(),
|
|
24
26
|
[no_await_promise_chain_rule_1.NoAwaitPromiseChainRule.NAME]: no_await_promise_chain_rule_1.NoAwaitPromiseChainRule.build(),
|
|
25
27
|
[no_silent_catch_rule_1.NoSilentCatchRule.NAME]: no_silent_catch_rule_1.NoSilentCatchRule.build(),
|
|
26
28
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-rules.js","sourceRoot":"","sources":["../../../src/linters/house/async-rules.ts"],"names":[],"mappings":";;;AACA,qCAAkD;AAClD,+EAAwE;AACxE,iEAA2D;AAC3D,iEAA2D;AAC3D,iEAA2D;AAC3D,qCAA6C;AAE7C;;;;;;GAMG;AACU,QAAA,gBAAgB,GAAoB;IAC/C;QACE,KAAK,EAAE,CAAC,uBAAuB,CAAC;QAChC,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE;YACL,CAAC,wCAAiB,CAAC,IAAI,CAAC,EAAE,wCAAiB,CAAC,KAAK,EAAE;YACnD,CAAC,wCAAiB,CAAC,IAAI,CAAC,EAAE,wCAAiB,CAAC,KAAK,EAAE;YACnD,CAAC,qDAAuB,CAAC,IAAI,CAAC,EAAE,qDAAuB,CAAC,KAAK,EAAE;YAC/D,CAAC,wCAAiB,CAAC,IAAI,CAAC,EAAE,wCAAiB,CAAC,KAAK,EAAE;SACpD;KACF;CACF,CAAC","sourcesContent":["import type { Linter } from 'eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './common';\nimport { NoAwaitPromiseChainRule } from './no-await-promise-chain.rule';\nimport { NoInlineAwaitRule } from './no-inline-await.rule';\nimport { NoReturnAwaitRule } from './no-return-await.rule';\nimport { NoSilentCatchRule } from './no-silent-catch.rule';\nimport { houseEslintPlugin } from './plugin';\n\n/**\n * The async style rules: `await` stands alone as a statement or as the whole initializer of a declaration\n * (`no-inline-await`), a function returns the promise instead of `return await` (`no-return-await`), an `await`\n * never takes a promise chain (`no-await-promise-chain`), and a caught error leaves a trace (`no-silent-catch`).\n * They apply to test files too. Not exported from the package: `houseConfigs` and `reactHouseConfigs` carry them, and\n * `devz codemod async-style` runs them alone.\n */\nexport const asyncRuleConfigs: Linter.Config[] = [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: {\n [NoInlineAwaitRule.NAME]: NoInlineAwaitRule.build(),\n [NoReturnAwaitRule.NAME]: NoReturnAwaitRule.build(),\n [NoAwaitPromiseChainRule.NAME]: NoAwaitPromiseChainRule.build(),\n [NoSilentCatchRule.NAME]: NoSilentCatchRule.build(),\n },\n },\n];\n"]}
|
|
1
|
+
{"version":3,"file":"async-rules.js","sourceRoot":"","sources":["../../../src/linters/house/async-rules.ts"],"names":[],"mappings":";;;AACA,qCAAkD;AAClD,uEAAgE;AAChE,+EAAwE;AACxE,iEAA2D;AAC3D,iEAA2D;AAC3D,iEAA2D;AAC3D,qCAA6C;AAE7C;;;;;;GAMG;AACU,QAAA,gBAAgB,GAAoB;IAC/C;QACE,KAAK,EAAE,CAAC,uBAAuB,CAAC;QAChC,OAAO,EAAE,EAAE,CAAC,+BAAsB,CAAC,EAAE,0BAAiB,EAAE;QACxD,KAAK,EAAE;YACL,CAAC,wCAAiB,CAAC,IAAI,CAAC,EAAE,wCAAiB,CAAC,KAAK,EAAE;YACnD,CAAC,wCAAiB,CAAC,IAAI,CAAC,EAAE,wCAAiB,CAAC,KAAK,EAAE;YACnD,CAAC,6CAAmB,CAAC,IAAI,CAAC,EAAE,6CAAmB,CAAC,KAAK,EAAE;YACvD,CAAC,qDAAuB,CAAC,IAAI,CAAC,EAAE,qDAAuB,CAAC,KAAK,EAAE;YAC/D,CAAC,wCAAiB,CAAC,IAAI,CAAC,EAAE,wCAAiB,CAAC,KAAK,EAAE;SACpD;KACF;CACF,CAAC","sourcesContent":["import type { Linter } from 'eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './common';\nimport { NoAwaitNewChainRule } from './no-await-new-chain.rule';\nimport { NoAwaitPromiseChainRule } from './no-await-promise-chain.rule';\nimport { NoInlineAwaitRule } from './no-inline-await.rule';\nimport { NoReturnAwaitRule } from './no-return-await.rule';\nimport { NoSilentCatchRule } from './no-silent-catch.rule';\nimport { houseEslintPlugin } from './plugin';\n\n/**\n * The async style rules: `await` stands alone as a statement or as the whole initializer of a declaration\n * (`no-inline-await`), a function returns the promise instead of `return await` (`no-return-await`), an `await`\n * never takes a promise chain (`no-await-promise-chain`) or a method called on a new instance (`no-await-new-chain`), and a caught error leaves a trace (`no-silent-catch`).\n * They apply to test files too. Not exported from the package: `houseConfigs` and `reactHouseConfigs` carry them, and\n * `devz codemod async-style` runs them alone.\n */\nexport const asyncRuleConfigs: Linter.Config[] = [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n plugins: { [HOUSE_PLUGIN_NAMESPACE]: houseEslintPlugin },\n rules: {\n [NoInlineAwaitRule.NAME]: NoInlineAwaitRule.build(),\n [NoReturnAwaitRule.NAME]: NoReturnAwaitRule.build(),\n [NoAwaitNewChainRule.NAME]: NoAwaitNewChainRule.build(),\n [NoAwaitPromiseChainRule.NAME]: NoAwaitPromiseChainRule.build(),\n [NoSilentCatchRule.NAME]: NoSilentCatchRule.build(),\n },\n },\n];\n"]}
|
|
@@ -5,6 +5,7 @@ export * from './effect-cleanup-consistency.rule';
|
|
|
5
5
|
export * from './hook-support';
|
|
6
6
|
export * from './max-params-own.rule';
|
|
7
7
|
export * from './no-async-hook-callback.rule';
|
|
8
|
+
export * from './no-await-new-chain.rule';
|
|
8
9
|
export * from './no-await-promise-chain.rule';
|
|
9
10
|
export * from './no-inline-await.rule';
|
|
10
11
|
export * from './no-leaked-render.rule';
|
|
@@ -23,6 +23,7 @@ __exportStar(require("./effect-cleanup-consistency.rule"), exports);
|
|
|
23
23
|
__exportStar(require("./hook-support"), exports);
|
|
24
24
|
__exportStar(require("./max-params-own.rule"), exports);
|
|
25
25
|
__exportStar(require("./no-async-hook-callback.rule"), exports);
|
|
26
|
+
__exportStar(require("./no-await-new-chain.rule"), exports);
|
|
26
27
|
__exportStar(require("./no-await-promise-chain.rule"), exports);
|
|
27
28
|
__exportStar(require("./no-inline-await.rule"), exports);
|
|
28
29
|
__exportStar(require("./no-leaked-render.rule"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/linters/house/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,2CAAyB;AACzB,4DAA0C;AAC1C,oEAAkD;AAClD,iDAA+B;AAC/B,wDAAsC;AACtC,gEAA8C;AAC9C,gEAA8C;AAC9C,yDAAuC;AACvC,0DAAwC;AACxC,sDAAoC;AACpC,yDAAuC;AACvC,yDAAuC;AACvC,0DAAwC;AACxC,2CAAyB;AACzB,0DAAwC;AACxC,4CAA0B","sourcesContent":["export { AwaitSupport } from './await-support';\nexport * from './common';\nexport * from './const-class-values.rule';\nexport * from './effect-cleanup-consistency.rule';\nexport * from './hook-support';\nexport * from './max-params-own.rule';\nexport * from './no-async-hook-callback.rule';\nexport * from './no-await-promise-chain.rule';\nexport * from './no-inline-await.rule';\nexport * from './no-leaked-render.rule';\nexport * from './no-new-error.rule';\nexport * from './no-return-await.rule';\nexport * from './no-silent-catch.rule';\nexport * from './no-unbraced-case.rule';\nexport * from './plugin';\nexport * from './promise-chain-support';\nexport * from './configs';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/linters/house/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iDAA+C;AAAtC,6GAAA,YAAY,OAAA;AACrB,2CAAyB;AACzB,4DAA0C;AAC1C,oEAAkD;AAClD,iDAA+B;AAC/B,wDAAsC;AACtC,gEAA8C;AAC9C,4DAA0C;AAC1C,gEAA8C;AAC9C,yDAAuC;AACvC,0DAAwC;AACxC,sDAAoC;AACpC,yDAAuC;AACvC,yDAAuC;AACvC,0DAAwC;AACxC,2CAAyB;AACzB,0DAAwC;AACxC,4CAA0B","sourcesContent":["export { AwaitSupport } from './await-support';\nexport * from './common';\nexport * from './const-class-values.rule';\nexport * from './effect-cleanup-consistency.rule';\nexport * from './hook-support';\nexport * from './max-params-own.rule';\nexport * from './no-async-hook-callback.rule';\nexport * from './no-await-new-chain.rule';\nexport * from './no-await-promise-chain.rule';\nexport * from './no-inline-await.rule';\nexport * from './no-leaked-render.rule';\nexport * from './no-new-error.rule';\nexport * from './no-return-await.rule';\nexport * from './no-silent-catch.rule';\nexport * from './no-unbraced-case.rule';\nexport * from './plugin';\nexport * from './promise-chain-support';\nexport * from './configs';\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Rule } from 'eslint';
|
|
2
|
+
import type { TRuleSeverity } from '../rules/common';
|
|
3
|
+
/**
|
|
4
|
+
* `venizia/no-await-new-chain`. A method is never called on a fresh instance inside an `await`:
|
|
5
|
+
* `await new Runner({ ... }).run(...)` and `const text = await new Response(body).text()` declare the instance first,
|
|
6
|
+
* then await on its own line (`const runner = new Runner({ ... }); await runner.run(...);`). A builder chain
|
|
7
|
+
* (`await new SignJWT(claims).setIssuer(iss).sign(key)`) declares the builder, then awaits its last call.
|
|
8
|
+
*
|
|
9
|
+
* `await new Promise(...)` calls no method and is allowed. `await new X().prop` is not a call and is allowed.
|
|
10
|
+
*
|
|
11
|
+
* The fix moves the instance, or the chain up to the last call, into a `const` in front of the statement. It is made
|
|
12
|
+
* only when nothing that does more than read a value runs before the `await` inside the statement; otherwise the
|
|
13
|
+
* finding is reported and left alone.
|
|
14
|
+
*/
|
|
15
|
+
export declare class NoAwaitNewChainRule {
|
|
16
|
+
static readonly NAME = "venizia/no-await-new-chain";
|
|
17
|
+
/** The expression under any transparent wrapper. */
|
|
18
|
+
private static unwrap;
|
|
19
|
+
/**
|
|
20
|
+
* The receiver of the last call when the awaited value is a method call on a `new` (directly or through a chain of
|
|
21
|
+
* calls and member reads), else `undefined`.
|
|
22
|
+
*/
|
|
23
|
+
private static receiverOf;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the `await` is the whole statement (`await f();`) or the whole initializer of a declaration with one
|
|
26
|
+
* declarator (`const { a } = await f();`). Nothing runs before it there: a binding pattern and its defaults are
|
|
27
|
+
* evaluated after the initializer.
|
|
28
|
+
*/
|
|
29
|
+
private static isFirstToRun;
|
|
30
|
+
/** `Response` becomes `response`, `ns.SignJWT` becomes `signJWT`; anything else is `instance`. */
|
|
31
|
+
private static nameOf;
|
|
32
|
+
static readonly RULE: Rule.RuleModule;
|
|
33
|
+
static build(opts?: {
|
|
34
|
+
severity?: TRuleSeverity;
|
|
35
|
+
}): TRuleSeverity;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=no-await-new-chain.rule.d.ts.map
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoAwaitNewChainRule = void 0;
|
|
4
|
+
const await_support_1 = require("./await-support");
|
|
5
|
+
const common_1 = require("./common");
|
|
6
|
+
/** Wrappers that carry no meaning of their own around the call or the instance: `(await new X().m()) as Y`, `new X()!.m()`, `new X()?.m()`. */
|
|
7
|
+
const TRANSPARENT_TYPES = new Set([
|
|
8
|
+
'ChainExpression',
|
|
9
|
+
'TSAsExpression',
|
|
10
|
+
'TSSatisfiesExpression',
|
|
11
|
+
'TSNonNullExpression',
|
|
12
|
+
]);
|
|
13
|
+
/** The classes whose `new` is awaited on its own account: `await new Promise(...)` calls no method, and `.then` on it is `no-await-promise-chain`'s. */
|
|
14
|
+
const EXEMPT_CLASSES = new Set(['Promise']);
|
|
15
|
+
/**
|
|
16
|
+
* `venizia/no-await-new-chain`. A method is never called on a fresh instance inside an `await`:
|
|
17
|
+
* `await new Runner({ ... }).run(...)` and `const text = await new Response(body).text()` declare the instance first,
|
|
18
|
+
* then await on its own line (`const runner = new Runner({ ... }); await runner.run(...);`). A builder chain
|
|
19
|
+
* (`await new SignJWT(claims).setIssuer(iss).sign(key)`) declares the builder, then awaits its last call.
|
|
20
|
+
*
|
|
21
|
+
* `await new Promise(...)` calls no method and is allowed. `await new X().prop` is not a call and is allowed.
|
|
22
|
+
*
|
|
23
|
+
* The fix moves the instance, or the chain up to the last call, into a `const` in front of the statement. It is made
|
|
24
|
+
* only when nothing that does more than read a value runs before the `await` inside the statement; otherwise the
|
|
25
|
+
* finding is reported and left alone.
|
|
26
|
+
*/
|
|
27
|
+
class NoAwaitNewChainRule {
|
|
28
|
+
static { this.NAME = `${common_1.HOUSE_PLUGIN_NAMESPACE}/no-await-new-chain`; }
|
|
29
|
+
/** The expression under any transparent wrapper. */
|
|
30
|
+
static unwrap(opts) {
|
|
31
|
+
let current = opts.node;
|
|
32
|
+
while (TRANSPARENT_TYPES.has(common_1.AstNode.getType({ node: current }) ?? '')) {
|
|
33
|
+
current = common_1.AstNode.readField({ node: current, key: 'expression' });
|
|
34
|
+
}
|
|
35
|
+
return current;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The receiver of the last call when the awaited value is a method call on a `new` (directly or through a chain of
|
|
39
|
+
* calls and member reads), else `undefined`.
|
|
40
|
+
*/
|
|
41
|
+
static receiverOf(opts) {
|
|
42
|
+
const operand = NoAwaitNewChainRule.unwrap({
|
|
43
|
+
node: common_1.AstNode.readField({ node: opts.awaitNode, key: 'argument' }),
|
|
44
|
+
});
|
|
45
|
+
if (common_1.AstNode.getType({ node: operand }) !== common_1.AstNodeTypes.CALL_EXPRESSION) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const callee = NoAwaitNewChainRule.unwrap({
|
|
49
|
+
node: common_1.AstNode.readField({ node: operand, key: 'callee' }),
|
|
50
|
+
});
|
|
51
|
+
if (common_1.AstNode.getType({ node: callee }) !== 'MemberExpression') {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const receiver = common_1.AstNode.readField({ node: callee, key: 'object' });
|
|
55
|
+
let current = NoAwaitNewChainRule.unwrap({ node: receiver });
|
|
56
|
+
// Down the chain: `new X().a().b` is a call of a member of a call of a member of the `new`.
|
|
57
|
+
for (;;) {
|
|
58
|
+
const type = common_1.AstNode.getType({ node: current });
|
|
59
|
+
if (type === common_1.AstNodeTypes.CALL_EXPRESSION) {
|
|
60
|
+
current = NoAwaitNewChainRule.unwrap({
|
|
61
|
+
node: common_1.AstNode.readField({ node: current, key: 'callee' }),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
else if (type === 'MemberExpression') {
|
|
65
|
+
current = NoAwaitNewChainRule.unwrap({
|
|
66
|
+
node: common_1.AstNode.readField({ node: current, key: 'object' }),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (common_1.AstNode.getType({ node: current }) !== common_1.AstNodeTypes.NEW_EXPRESSION) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const constructed = common_1.AstNode.readField({ node: current, key: 'callee' });
|
|
77
|
+
if (common_1.AstNode.getType({ node: constructed }) === 'Identifier' &&
|
|
78
|
+
EXEMPT_CLASSES.has(String(common_1.AstNode.readField({ node: constructed, key: 'name' })))) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return await_support_1.AwaitSupport.isNode(receiver) ? receiver : undefined;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Whether the `await` is the whole statement (`await f();`) or the whole initializer of a declaration with one
|
|
85
|
+
* declarator (`const { a } = await f();`). Nothing runs before it there: a binding pattern and its defaults are
|
|
86
|
+
* evaluated after the initializer.
|
|
87
|
+
*/
|
|
88
|
+
static isFirstToRun(opts) {
|
|
89
|
+
const { awaitNode, statement } = opts;
|
|
90
|
+
const type = common_1.AstNode.getType({ node: statement });
|
|
91
|
+
if (type === 'ExpressionStatement') {
|
|
92
|
+
return common_1.AstNode.readField({ node: statement, key: 'expression' }) === awaitNode;
|
|
93
|
+
}
|
|
94
|
+
if (type !== 'VariableDeclaration') {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const declarations = common_1.AstNode.readField({ node: statement, key: 'declarations' });
|
|
98
|
+
return (Array.isArray(declarations) &&
|
|
99
|
+
declarations.length === 1 &&
|
|
100
|
+
common_1.AstNode.readField({ node: declarations[0], key: 'init' }) === awaitNode);
|
|
101
|
+
}
|
|
102
|
+
/** `Response` becomes `response`, `ns.SignJWT` becomes `signJWT`; anything else is `instance`. */
|
|
103
|
+
static nameOf(opts) {
|
|
104
|
+
let current = NoAwaitNewChainRule.unwrap({ node: opts.receiver });
|
|
105
|
+
while (common_1.AstNode.getType({ node: current }) === common_1.AstNodeTypes.CALL_EXPRESSION ||
|
|
106
|
+
common_1.AstNode.getType({ node: current }) === 'MemberExpression') {
|
|
107
|
+
current = NoAwaitNewChainRule.unwrap({
|
|
108
|
+
node: common_1.AstNode.readField({
|
|
109
|
+
node: current,
|
|
110
|
+
key: common_1.AstNode.getType({ node: current }) === 'MemberExpression' ? 'object' : 'callee',
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const constructed = common_1.AstNode.readField({ node: current, key: 'callee' });
|
|
115
|
+
const word = common_1.AstNode.getType({ node: constructed }) === 'Identifier'
|
|
116
|
+
? common_1.AstNode.readField({ node: constructed, key: 'name' })
|
|
117
|
+
: common_1.AstNode.getType({ node: constructed }) === 'MemberExpression'
|
|
118
|
+
? common_1.AstNode.readField({
|
|
119
|
+
node: common_1.AstNode.readField({ node: constructed, key: 'property' }),
|
|
120
|
+
key: 'name',
|
|
121
|
+
})
|
|
122
|
+
: undefined;
|
|
123
|
+
return typeof word === 'string' && /^[A-Za-z_$][\w$]*$/.test(word)
|
|
124
|
+
? `${word[0]?.toLowerCase()}${word.slice(1)}`
|
|
125
|
+
: 'instance';
|
|
126
|
+
}
|
|
127
|
+
static { this.RULE = {
|
|
128
|
+
meta: {
|
|
129
|
+
type: 'suggestion',
|
|
130
|
+
fixable: 'code',
|
|
131
|
+
schema: [],
|
|
132
|
+
messages: {
|
|
133
|
+
chain: 'Do not call a method on a new instance inside an `await`: declare the instance first (`const runner = new Runner(options);`), then `await runner.run();` on its own line.',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
create: (context) => {
|
|
137
|
+
const { sourceCode } = context;
|
|
138
|
+
return {
|
|
139
|
+
[common_1.AstNodeTypes.AWAIT_EXPRESSION]: (node) => {
|
|
140
|
+
const receiver = NoAwaitNewChainRule.receiverOf({ awaitNode: node });
|
|
141
|
+
if (receiver === undefined) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const statement = await_support_1.AwaitSupport.hoistTarget({ awaitNode: node });
|
|
145
|
+
const range = await_support_1.AwaitSupport.rangeOf({ node: receiver });
|
|
146
|
+
const canFix = statement !== undefined &&
|
|
147
|
+
range !== undefined &&
|
|
148
|
+
(NoAwaitNewChainRule.isFirstToRun({ awaitNode: node, statement }) ||
|
|
149
|
+
!await_support_1.AwaitSupport.hasEffectBefore({ statement, awaitNode: node, sourceCode }));
|
|
150
|
+
context.report({
|
|
151
|
+
node,
|
|
152
|
+
messageId: 'chain',
|
|
153
|
+
fix: canFix && range !== undefined
|
|
154
|
+
? (fixer) => {
|
|
155
|
+
const name = await_support_1.AwaitSupport.freshName({
|
|
156
|
+
node,
|
|
157
|
+
base: NoAwaitNewChainRule.nameOf({ receiver }),
|
|
158
|
+
sourceCode,
|
|
159
|
+
});
|
|
160
|
+
const indent = await_support_1.AwaitSupport.indentOf({ node: statement, sourceCode });
|
|
161
|
+
return [
|
|
162
|
+
fixer.insertTextBefore(statement, `const ${name} = ${sourceCode.getText(receiver)};\n${indent}`),
|
|
163
|
+
fixer.replaceTextRange(range, name),
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
: null,
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
}; }
|
|
172
|
+
static build(opts = {}) {
|
|
173
|
+
return opts.severity ?? 'error';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.NoAwaitNewChainRule = NoAwaitNewChainRule;
|
|
177
|
+
//# sourceMappingURL=no-await-new-chain.rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-await-new-chain.rule.js","sourceRoot":"","sources":["../../../src/linters/house/no-await-new-chain.rule.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Rule } from 'eslint';\nimport type { TRuleSeverity } from '../rules/common';\nimport { AwaitSupport } from './await-support';\nimport { AstNode, AstNodeTypes, HOUSE_PLUGIN_NAMESPACE } from './common';\n\n/** Wrappers that carry no meaning of their own around the call or the instance: `(await new X().m()) as Y`, `new X()!.m()`, `new X()?.m()`. */\nconst TRANSPARENT_TYPES = new Set([\n 'ChainExpression',\n 'TSAsExpression',\n 'TSSatisfiesExpression',\n 'TSNonNullExpression',\n]);\n\n/** The classes whose `new` is awaited on its own account: `await new Promise(...)` calls no method, and `.then` on it is `no-await-promise-chain`'s. */\nconst EXEMPT_CLASSES = new Set(['Promise']);\n\n/**\n * `venizia/no-await-new-chain`. A method is never called on a fresh instance inside an `await`:\n * `await new Runner({ ... }).run(...)` and `const text = await new Response(body).text()` declare the instance first,\n * then await on its own line (`const runner = new Runner({ ... }); await runner.run(...);`). A builder chain\n * (`await new SignJWT(claims).setIssuer(iss).sign(key)`) declares the builder, then awaits its last call.\n *\n * `await new Promise(...)` calls no method and is allowed. `await new X().prop` is not a call and is allowed.\n *\n * The fix moves the instance, or the chain up to the last call, into a `const` in front of the statement. It is made\n * only when nothing that does more than read a value runs before the `await` inside the statement; otherwise the\n * finding is reported and left alone.\n */\nexport class NoAwaitNewChainRule {\n static readonly NAME = `${HOUSE_PLUGIN_NAMESPACE}/no-await-new-chain`;\n\n /** The expression under any transparent wrapper. */\n private static unwrap(opts: { node: unknown }): unknown {\n let current = opts.node;\n\n while (TRANSPARENT_TYPES.has(AstNode.getType({ node: current }) ?? '')) {\n current = AstNode.readField({ node: current, key: 'expression' });\n }\n\n return current;\n }\n\n /**\n * The receiver of the last call when the awaited value is a method call on a `new` (directly or through a chain of\n * calls and member reads), else `undefined`.\n */\n private static receiverOf(opts: { awaitNode: unknown }): Rule.Node | undefined {\n const operand = NoAwaitNewChainRule.unwrap({\n node: AstNode.readField({ node: opts.awaitNode, key: 'argument' }),\n });\n\n if (AstNode.getType({ node: operand }) !== AstNodeTypes.CALL_EXPRESSION) {\n return undefined;\n }\n\n const callee = NoAwaitNewChainRule.unwrap({\n node: AstNode.readField({ node: operand, key: 'callee' }),\n });\n\n if (AstNode.getType({ node: callee }) !== 'MemberExpression') {\n return undefined;\n }\n\n const receiver = AstNode.readField({ node: callee, key: 'object' });\n let current = NoAwaitNewChainRule.unwrap({ node: receiver });\n\n // Down the chain: `new X().a().b` is a call of a member of a call of a member of the `new`.\n for (;;) {\n const type = AstNode.getType({ node: current });\n\n if (type === AstNodeTypes.CALL_EXPRESSION) {\n current = NoAwaitNewChainRule.unwrap({\n node: AstNode.readField({ node: current, key: 'callee' }),\n });\n } else if (type === 'MemberExpression') {\n current = NoAwaitNewChainRule.unwrap({\n node: AstNode.readField({ node: current, key: 'object' }),\n });\n } else {\n break;\n }\n }\n\n if (AstNode.getType({ node: current }) !== AstNodeTypes.NEW_EXPRESSION) {\n return undefined;\n }\n\n const constructed = AstNode.readField({ node: current, key: 'callee' });\n\n if (\n AstNode.getType({ node: constructed }) === 'Identifier' &&\n EXEMPT_CLASSES.has(String(AstNode.readField({ node: constructed, key: 'name' })))\n ) {\n return undefined;\n }\n\n return AwaitSupport.isNode(receiver) ? receiver : undefined;\n }\n\n /**\n * Whether the `await` is the whole statement (`await f();`) or the whole initializer of a declaration with one\n * declarator (`const { a } = await f();`). Nothing runs before it there: a binding pattern and its defaults are\n * evaluated after the initializer.\n */\n private static isFirstToRun(opts: { awaitNode: unknown; statement: unknown }): boolean {\n const { awaitNode, statement } = opts;\n const type = AstNode.getType({ node: statement });\n\n if (type === 'ExpressionStatement') {\n return AstNode.readField({ node: statement, key: 'expression' }) === awaitNode;\n }\n\n if (type !== 'VariableDeclaration') {\n return false;\n }\n\n const declarations = AstNode.readField({ node: statement, key: 'declarations' });\n\n return (\n Array.isArray(declarations) &&\n declarations.length === 1 &&\n AstNode.readField({ node: declarations[0], key: 'init' }) === awaitNode\n );\n }\n\n /** `Response` becomes `response`, `ns.SignJWT` becomes `signJWT`; anything else is `instance`. */\n private static nameOf(opts: { receiver: unknown }): string {\n let current = NoAwaitNewChainRule.unwrap({ node: opts.receiver });\n\n while (\n AstNode.getType({ node: current }) === AstNodeTypes.CALL_EXPRESSION ||\n AstNode.getType({ node: current }) === 'MemberExpression'\n ) {\n current = NoAwaitNewChainRule.unwrap({\n node: AstNode.readField({\n node: current,\n key: AstNode.getType({ node: current }) === 'MemberExpression' ? 'object' : 'callee',\n }),\n });\n }\n\n const constructed = AstNode.readField({ node: current, key: 'callee' });\n const word =\n AstNode.getType({ node: constructed }) === 'Identifier'\n ? AstNode.readField({ node: constructed, key: 'name' })\n : AstNode.getType({ node: constructed }) === 'MemberExpression'\n ? AstNode.readField({\n node: AstNode.readField({ node: constructed, key: 'property' }),\n key: 'name',\n })\n : undefined;\n\n return typeof word === 'string' && /^[A-Za-z_$][\\w$]*$/.test(word)\n ? `${word[0]?.toLowerCase()}${word.slice(1)}`\n : 'instance';\n }\n\n static readonly RULE: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n fixable: 'code',\n schema: [],\n messages: {\n chain:\n 'Do not call a method on a new instance inside an `await`: declare the instance first (`const runner = new Runner(options);`), then `await runner.run();` on its own line.',\n },\n },\n create: (context) => {\n const { sourceCode } = context;\n\n return {\n [AstNodeTypes.AWAIT_EXPRESSION]: (node: Rule.Node) => {\n const receiver = NoAwaitNewChainRule.receiverOf({ awaitNode: node });\n\n if (receiver === undefined) {\n return;\n }\n\n const statement = AwaitSupport.hoistTarget({ awaitNode: node });\n const range = AwaitSupport.rangeOf({ node: receiver });\n const canFix =\n statement !== undefined &&\n range !== undefined &&\n (NoAwaitNewChainRule.isFirstToRun({ awaitNode: node, statement }) ||\n !AwaitSupport.hasEffectBefore({ statement, awaitNode: node, sourceCode }));\n\n context.report({\n node,\n messageId: 'chain',\n fix:\n canFix && range !== undefined\n ? (fixer) => {\n const name = AwaitSupport.freshName({\n node,\n base: NoAwaitNewChainRule.nameOf({ receiver }),\n sourceCode,\n });\n const indent = AwaitSupport.indentOf({ node: statement, sourceCode });\n\n return [\n fixer.insertTextBefore(\n statement,\n `const ${name} = ${sourceCode.getText(receiver)};\\n${indent}`,\n ),\n fixer.replaceTextRange(range, name),\n ];\n }\n : null,\n });\n },\n };\n },\n };\n\n static build(opts: { severity?: TRuleSeverity } = {}): TRuleSeverity {\n return opts.severity ?? 'error';\n }\n}\n"]}
|
|
@@ -6,6 +6,7 @@ const const_class_values_rule_1 = require("./const-class-values.rule");
|
|
|
6
6
|
const effect_cleanup_consistency_rule_1 = require("./effect-cleanup-consistency.rule");
|
|
7
7
|
const max_params_own_rule_1 = require("./max-params-own.rule");
|
|
8
8
|
const no_async_hook_callback_rule_1 = require("./no-async-hook-callback.rule");
|
|
9
|
+
const no_await_new_chain_rule_1 = require("./no-await-new-chain.rule");
|
|
9
10
|
const no_await_promise_chain_rule_1 = require("./no-await-promise-chain.rule");
|
|
10
11
|
const no_inline_await_rule_1 = require("./no-inline-await.rule");
|
|
11
12
|
const no_leaked_render_rule_1 = require("./no-leaked-render.rule");
|
|
@@ -21,6 +22,7 @@ exports.houseEslintPlugin = {
|
|
|
21
22
|
'effect-cleanup-consistency': effect_cleanup_consistency_rule_1.EffectCleanupConsistencyRule.RULE,
|
|
22
23
|
'max-params-own': max_params_own_rule_1.MaxParamsOwnRule.RULE,
|
|
23
24
|
'no-async-hook-callback': no_async_hook_callback_rule_1.NoAsyncHookCallbackRule.RULE,
|
|
25
|
+
'no-await-new-chain': no_await_new_chain_rule_1.NoAwaitNewChainRule.RULE,
|
|
24
26
|
'no-await-promise-chain': no_await_promise_chain_rule_1.NoAwaitPromiseChainRule.RULE,
|
|
25
27
|
'no-inline-await': no_inline_await_rule_1.NoInlineAwaitRule.RULE,
|
|
26
28
|
'no-leaked-render': no_leaked_render_rule_1.NoLeakedRenderRule.RULE,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/linters/house/plugin.ts"],"names":[],"mappings":";;;AACA,qCAAkD;AAClD,uEAAiE;AACjE,uFAAiF;AACjF,+DAAyD;AACzD,+EAAwE;AACxE,+EAAwE;AACxE,iEAA2D;AAC3D,mEAA6D;AAC7D,2DAAqD;AACrD,iEAA2D;AAC3D,iEAA2D;AAC3D,mEAA6D;AAE7D,qGAAqG;AACxF,QAAA,iBAAiB,GAAkB;IAC9C,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,+BAAsB,EAAE,EAAE;IACzD,KAAK,EAAE;QACL,oBAAoB,EAAE,8CAAoB,CAAC,IAAI;QAC/C,4BAA4B,EAAE,8DAA4B,CAAC,IAAI;QAC/D,gBAAgB,EAAE,sCAAgB,CAAC,IAAI;QACvC,wBAAwB,EAAE,qDAAuB,CAAC,IAAI;QACtD,wBAAwB,EAAE,qDAAuB,CAAC,IAAI;QACtD,iBAAiB,EAAE,wCAAiB,CAAC,IAAI;QACzC,kBAAkB,EAAE,0CAAkB,CAAC,IAAI;QAC3C,cAAc,EAAE,kCAAc,CAAC,IAAI;QACnC,iBAAiB,EAAE,wCAAiB,CAAC,IAAI;QACzC,iBAAiB,EAAE,wCAAiB,CAAC,IAAI;QACzC,kBAAkB,EAAE,0CAAkB,CAAC,IAAI;KAC5C;CACF,CAAC","sourcesContent":["import type { ESLint } from 'eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './common';\nimport { ConstClassValuesRule } from './const-class-values.rule';\nimport { EffectCleanupConsistencyRule } from './effect-cleanup-consistency.rule';\nimport { MaxParamsOwnRule } from './max-params-own.rule';\nimport { NoAsyncHookCallbackRule } from './no-async-hook-callback.rule';\nimport { NoAwaitPromiseChainRule } from './no-await-promise-chain.rule';\nimport { NoInlineAwaitRule } from './no-inline-await.rule';\nimport { NoLeakedRenderRule } from './no-leaked-render.rule';\nimport { NoNewErrorRule } from './no-new-error.rule';\nimport { NoReturnAwaitRule } from './no-return-await.rule';\nimport { NoSilentCatchRule } from './no-silent-catch.rule';\nimport { NoUnbracedCaseRule } from './no-unbraced-case.rule';\n\n/** The ESLint plugin that carries the house rules oxlint cannot express, registered as `venizia`. */\nexport const houseEslintPlugin: ESLint.Plugin = {\n meta: { name: `eslint-plugin-${HOUSE_PLUGIN_NAMESPACE}` },\n rules: {\n 'const-class-values': ConstClassValuesRule.RULE,\n 'effect-cleanup-consistency': EffectCleanupConsistencyRule.RULE,\n 'max-params-own': MaxParamsOwnRule.RULE,\n 'no-async-hook-callback': NoAsyncHookCallbackRule.RULE,\n 'no-await-promise-chain': NoAwaitPromiseChainRule.RULE,\n 'no-inline-await': NoInlineAwaitRule.RULE,\n 'no-leaked-render': NoLeakedRenderRule.RULE,\n 'no-new-error': NoNewErrorRule.RULE,\n 'no-return-await': NoReturnAwaitRule.RULE,\n 'no-silent-catch': NoSilentCatchRule.RULE,\n 'no-unbraced-case': NoUnbracedCaseRule.RULE,\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/linters/house/plugin.ts"],"names":[],"mappings":";;;AACA,qCAAkD;AAClD,uEAAiE;AACjE,uFAAiF;AACjF,+DAAyD;AACzD,+EAAwE;AACxE,uEAAgE;AAChE,+EAAwE;AACxE,iEAA2D;AAC3D,mEAA6D;AAC7D,2DAAqD;AACrD,iEAA2D;AAC3D,iEAA2D;AAC3D,mEAA6D;AAE7D,qGAAqG;AACxF,QAAA,iBAAiB,GAAkB;IAC9C,IAAI,EAAE,EAAE,IAAI,EAAE,iBAAiB,+BAAsB,EAAE,EAAE;IACzD,KAAK,EAAE;QACL,oBAAoB,EAAE,8CAAoB,CAAC,IAAI;QAC/C,4BAA4B,EAAE,8DAA4B,CAAC,IAAI;QAC/D,gBAAgB,EAAE,sCAAgB,CAAC,IAAI;QACvC,wBAAwB,EAAE,qDAAuB,CAAC,IAAI;QACtD,oBAAoB,EAAE,6CAAmB,CAAC,IAAI;QAC9C,wBAAwB,EAAE,qDAAuB,CAAC,IAAI;QACtD,iBAAiB,EAAE,wCAAiB,CAAC,IAAI;QACzC,kBAAkB,EAAE,0CAAkB,CAAC,IAAI;QAC3C,cAAc,EAAE,kCAAc,CAAC,IAAI;QACnC,iBAAiB,EAAE,wCAAiB,CAAC,IAAI;QACzC,iBAAiB,EAAE,wCAAiB,CAAC,IAAI;QACzC,kBAAkB,EAAE,0CAAkB,CAAC,IAAI;KAC5C;CACF,CAAC","sourcesContent":["import type { ESLint } from 'eslint';\nimport { HOUSE_PLUGIN_NAMESPACE } from './common';\nimport { ConstClassValuesRule } from './const-class-values.rule';\nimport { EffectCleanupConsistencyRule } from './effect-cleanup-consistency.rule';\nimport { MaxParamsOwnRule } from './max-params-own.rule';\nimport { NoAsyncHookCallbackRule } from './no-async-hook-callback.rule';\nimport { NoAwaitNewChainRule } from './no-await-new-chain.rule';\nimport { NoAwaitPromiseChainRule } from './no-await-promise-chain.rule';\nimport { NoInlineAwaitRule } from './no-inline-await.rule';\nimport { NoLeakedRenderRule } from './no-leaked-render.rule';\nimport { NoNewErrorRule } from './no-new-error.rule';\nimport { NoReturnAwaitRule } from './no-return-await.rule';\nimport { NoSilentCatchRule } from './no-silent-catch.rule';\nimport { NoUnbracedCaseRule } from './no-unbraced-case.rule';\n\n/** The ESLint plugin that carries the house rules oxlint cannot express, registered as `venizia`. */\nexport const houseEslintPlugin: ESLint.Plugin = {\n meta: { name: `eslint-plugin-${HOUSE_PLUGIN_NAMESPACE}` },\n rules: {\n 'const-class-values': ConstClassValuesRule.RULE,\n 'effect-cleanup-consistency': EffectCleanupConsistencyRule.RULE,\n 'max-params-own': MaxParamsOwnRule.RULE,\n 'no-async-hook-callback': NoAsyncHookCallbackRule.RULE,\n 'no-await-new-chain': NoAwaitNewChainRule.RULE,\n 'no-await-promise-chain': NoAwaitPromiseChainRule.RULE,\n 'no-inline-await': NoInlineAwaitRule.RULE,\n 'no-leaked-render': NoLeakedRenderRule.RULE,\n 'no-new-error': NoNewErrorRule.RULE,\n 'no-return-await': NoReturnAwaitRule.RULE,\n 'no-silent-catch': NoSilentCatchRule.RULE,\n 'no-unbraced-case': NoUnbracedCaseRule.RULE,\n },\n};\n"]}
|
package/dist/linters/oxlint.d.ts
CHANGED
|
@@ -15,16 +15,17 @@ import type { OxlintConfig } from 'oxlint';
|
|
|
15
15
|
* export default defineConfig(oxlintConfigs);
|
|
16
16
|
* ```
|
|
17
17
|
*
|
|
18
|
-
* `
|
|
19
|
-
*
|
|
18
|
+
* `prefer-nullish-coalescing` allows `||` on a string (`name?.trim() || 'guest'`) and reports it on
|
|
19
|
+
* every other nullable type. `OxlintConfigs.create({ lenientFallback: true })` is the same preset
|
|
20
|
+
* with `||` allowed on number operands too.
|
|
20
21
|
*/
|
|
21
22
|
export declare const oxlintConfigs: OxlintConfig;
|
|
22
23
|
/** Options of `OxlintConfigs.create`. */
|
|
23
24
|
export interface IOxlintPresetOptions {
|
|
24
25
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* Also allow `||` / `||=` where the left side is a number, so `limit || 20` passes: `0` falls
|
|
27
|
+
* back on purpose. A string is allowed by the base already. Left off, the base catches a real `0`
|
|
28
|
+
* swallowed by `||`.
|
|
28
29
|
*
|
|
29
30
|
* @default false
|
|
30
31
|
*/
|
package/dist/linters/oxlint.js
CHANGED
|
@@ -22,8 +22,9 @@ const JS_TS_FILES = ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.jsx', ...TS_FILES]
|
|
|
22
22
|
* export default defineConfig(oxlintConfigs);
|
|
23
23
|
* ```
|
|
24
24
|
*
|
|
25
|
-
* `
|
|
26
|
-
*
|
|
25
|
+
* `prefer-nullish-coalescing` allows `||` on a string (`name?.trim() || 'guest'`) and reports it on
|
|
26
|
+
* every other nullable type. `OxlintConfigs.create({ lenientFallback: true })` is the same preset
|
|
27
|
+
* with `||` allowed on number operands too.
|
|
27
28
|
*/
|
|
28
29
|
exports.oxlintConfigs = {
|
|
29
30
|
plugins: ['typescript', 'unicorn'],
|
|
@@ -124,7 +125,11 @@ exports.oxlintConfigs = {
|
|
|
124
125
|
// typescript-eslint, type-aware
|
|
125
126
|
'typescript/await-thenable': 'error',
|
|
126
127
|
'typescript/no-floating-promises': 'error',
|
|
127
|
-
|
|
128
|
+
// `||` on a string is mostly an intentional empty-string fallback (`value?.trim() || fallback`);
|
|
129
|
+
// `??` keeps `''` and changes behaviour. Objects and numbers still report.
|
|
130
|
+
[rules_1.PreferNullishCoalescingRule.NAME]: rules_1.PreferNullishCoalescingRule.build({
|
|
131
|
+
ignorePrimitives: { string: true },
|
|
132
|
+
}),
|
|
128
133
|
'typescript/return-await': 'error',
|
|
129
134
|
},
|
|
130
135
|
overrides: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxlint.js","sourceRoot":"","sources":["../../src/linters/oxlint.ts"],"names":[],"mappings":";;;AACA,qCAAsC;AACtC,mCAMiB;AAEjB,0CAA0C;AAC1C,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AACjE,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC,CAAC;AAEjF;;;;;;;;;;;;;;;;;;GAkBG;AACU,QAAA,aAAa,GAAiB;IACzC,OAAO,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC;IAClC,UAAU,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;IAClC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IAC5B,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;IACtB,cAAc,EAAE,CAAC,kBAAkB,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,CAAC;IACzF,KAAK,EAAE;QACL,qBAAqB;QACrB,mBAAmB,EAAE,OAAO;QAC5B,eAAe,EAAE,OAAO;QACxB,eAAe,EAAE,OAAO;QACxB,2BAA2B,EAAE,OAAO;QACpC,sBAAsB,EAAE,OAAO;QAC/B,iBAAiB,EAAE,OAAO;QAC1B,qBAAqB,EAAE,OAAO;QAC9B,gBAAgB,EAAE,OAAO;QACzB,iBAAiB,EAAE,OAAO;QAC1B,+BAA+B,EAAE,OAAO;QACxC,uBAAuB,EAAE,OAAO;QAChC,kBAAkB,EAAE,OAAO;QAC3B,aAAa,EAAE,OAAO;QACtB,eAAe,EAAE,OAAO;QACxB,iBAAiB,EAAE,OAAO;QAC1B,cAAc,EAAE,OAAO;QACvB,mBAAmB,EAAE,OAAO;QAC5B,UAAU,EAAE,OAAO;QACnB,0BAA0B,EAAE,OAAO;QACnC,kBAAkB,EAAE,OAAO;QAC3B,uBAAuB,EAAE,OAAO;QAChC,cAAc,EAAE,OAAO;QACvB,uBAAuB,EAAE,OAAO;QAChC,gBAAgB,EAAE,OAAO;QACzB,gBAAgB,EAAE,OAAO;QACzB,kBAAkB,EAAE,OAAO;QAC3B,kBAAkB,EAAE,OAAO;QAC3B,mBAAmB,EAAE,OAAO;QAC5B,yBAAyB,EAAE,OAAO;QAClC,sBAAsB,EAAE,OAAO;QAC/B,+BAA+B,EAAE,OAAO;QACxC,8BAA8B,EAAE,OAAO;QACvC,4BAA4B,EAAE,OAAO;QACrC,cAAc,EAAE,OAAO;QACvB,uBAAuB,EAAE,OAAO;QAChC,iBAAiB,EAAE,OAAO;QAC1B,gBAAgB,EAAE,OAAO;QACzB,kBAAkB,EAAE,OAAO;QAC3B,4BAA4B,EAAE,OAAO;QACrC,kBAAkB,EAAE,OAAO;QAC3B,sBAAsB,EAAE,OAAO;QAC/B,oBAAoB,EAAE,OAAO;QAC7B,gBAAgB,EAAE,OAAO;QACzB,mBAAmB,EAAE,OAAO;QAC5B,oBAAoB,EAAE,OAAO;QAC7B,6BAA6B,EAAE,OAAO;QACtC,kBAAkB,EAAE,OAAO;QAC3B,iCAAiC,EAAE,OAAO;QAC1C,0BAA0B,EAAE,OAAO;QACnC,kBAAkB,EAAE,OAAO;QAC3B,SAAS,EAAE,OAAO;QAClB,uBAAuB,EAAE,OAAO;QAChC,eAAe,EAAE,OAAO;QACxB,WAAW,EAAE,OAAO;QACpB,cAAc,EAAE,OAAO;QACvB,sBAAsB,EAAE,OAAO;QAE/B,sBAAsB;QACtB,CAAC,wBAAgB,CAAC,IAAI,CAAC,EAAE,wBAAgB,CAAC,KAAK,EAAE;QACjD,mBAAmB,EAAE,MAAM;QAC3B,uBAAuB,EAAE,OAAO;QAChC,iBAAiB,EAAE,OAAO;QAC1B,kBAAkB,EAAE,OAAO;QAC3B,CAAC,kBAAU,CAAC,IAAI,CAAC,EAAE,kBAAU,CAAC,KAAK,EAAE;QACrC,SAAS,EAAE,OAAO;QAClB,WAAW,EAAE,OAAO;QACpB,WAAW,EAAE,OAAO;QACpB,sBAAsB,EAAE,OAAO;QAC/B,CAAC,4BAAoB,CAAC,IAAI,CAAC,EAAE,4BAAoB,CAAC,KAAK,EAAE;QACzD,8BAA8B,EAAE,OAAO;QAEvC,oBAAoB;QACpB,2BAA2B,EAAE,OAAO;QACpC,qCAAqC,EAAE,OAAO;QAC9C,iCAAiC,EAAE,OAAO;QAC1C,wCAAwC,EAAE,OAAO;QACjD,2BAA2B,EAAE,OAAO;QACpC,yBAAyB,EAAE,OAAO;QAClC,gDAAgD,EAAE,OAAO;QACzD,0BAA0B,EAAE,OAAO;QACnC,2CAA2C,EAAE,OAAO;QACpD,0CAA0C,EAAE,OAAO;QACnD,oCAAoC,EAAE,OAAO;QAC7C,oCAAoC,EAAE,OAAO;QAC7C,4BAA4B,EAAE,OAAO;QACrC,qCAAqC,EAAE,OAAO;QAC9C,mCAAmC,EAAE,OAAO;QAC5C,yCAAyC,EAAE,OAAO;QAClD,0BAA0B,EAAE,OAAO;QACnC,+BAA+B,EAAE,OAAO;QAExC,gCAAgC;QAChC,2BAA2B,EAAE,OAAO;QACpC,iCAAiC,EAAE,OAAO;QAC1C,CAAC,mCAA2B,CAAC,IAAI,CAAC,EAAE,mCAA2B,CAAC,KAAK,EAAE;QACvE,yBAAyB,EAAE,OAAO;KACnC;IACD,SAAS,EAAE;QACT;YACE,mCAAmC;YACnC,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE;gBACL,mBAAmB,EAAE,KAAK;gBAC1B,eAAe,EAAE,KAAK;gBACtB,iBAAiB,EAAE,KAAK;gBACxB,iBAAiB,EAAE,KAAK;gBACxB,cAAc,EAAE,KAAK;gBACrB,gBAAgB,EAAE,KAAK;gBACvB,kBAAkB,EAAE,KAAK;gBACzB,8BAA8B,EAAE,KAAK;gBACrC,cAAc,EAAE,KAAK;gBACrB,kBAAkB,EAAE,KAAK;gBACzB,sBAAsB,EAAE,KAAK;gBAC7B,gBAAgB,EAAE,KAAK;gBACvB,oBAAoB,EAAE,KAAK;gBAC3B,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,OAAO;gBACjB,cAAc,EAAE,OAAO;gBACvB,oBAAoB,EAAE,OAAO;gBAC7B,eAAe,EAAE,OAAO;gBACxB,6FAA6F;gBAC7F,8FAA8F;gBAC9F,2FAA2F;gBAC3F,oCAAoC,EAAE;oBACpC,OAAO;oBACP;wBACE,MAAM,EAAE,cAAc;wBACtB,QAAQ,EAAE,qBAAqB;wBAC/B,uBAAuB,EAAE,KAAK;qBAC/B;iBACF;aACF;SACF;QACD;YACE,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE;gBACL,uBAAuB,EAAE,KAAK;gBAC9B,cAAc,EAAE,OAAO;gBACvB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;gBACvB,CAAC,+BAAuB,CAAC,IAAI,CAAC,EAAE,+BAAuB,CAAC,KAAK,EAAE;gBAC/D,oCAAoC,EAAE,KAAK;gBAC3C,0BAA0B,EAAE,KAAK;gBACjC,iCAAiC,EAAE,KAAK;aACzC;SACF;KACF;CACF,CAAC;AAsBF;;;;;;;;;;GAUG;AACH,MAAa,aAAa;IACxB,MAAM,CAAC,MAAM,CAAC,OAA6B,EAAE;QAC3C,MAAM,MAAM,GAAiB,IAAI,CAAC,eAAe;YAC/C,CAAC,CAAC;gBACE,GAAG,qBAAa;gBAChB,KAAK,EAAE;oBACL,GAAG,qBAAa,CAAC,KAAK;oBACtB,CAAC,mCAA2B,CAAC,IAAI,CAAC,EAAE,mCAA2B,CAAC,KAAK,CAAC;wBACpE,gBAAgB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;qBACjD,CAAC;iBACH;aACF;YACH,CAAC,CAAC,qBAAa,CAAC;QAElB,OAAO,mBAAU,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;CACF;AAhBD,sCAgBC","sourcesContent":["import type { OxlintConfig } from 'oxlint';\nimport { LintIgnore } from './ignore';\nimport {\n EqeqeqRule,\n NoRestrictedImportsRule,\n NoUnusedVarsRule,\n PreferNullishCoalescingRule,\n SwitchCaseBracesRule,\n} from './rules';\n\n/** File globs the rules are scoped to. */\nconst TS_FILES = ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'];\nconst JS_TS_FILES = ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.jsx', ...TS_FILES];\n\n/**\n * The oxlint port of `eslintConfigs`, generated with `@oxlint/migrate` and kept rule for rule.\n * Type-aware rules (`no-floating-promises`, `return-await`, ...) need `oxlint-tsgolint` installed.\n *\n * Not ported: `@typescript-eslint/naming-convention` (oxlint has no equivalent yet - keep it in\n * ESLint), `@typescript-eslint/prefer-optional-chain` (oxlint nursery), `no-invalid-this` (covered\n * by `noImplicitThis` in `tsconfig.base.json`). `n/prefer-node-protocol` maps to the unicorn rule.\n *\n * ```ts\n * // .configs/lints/oxlint.config.mts\n * import { defineConfig } from 'oxlint';\n * import { oxlintConfigs } from '@venizia/dev-configs/linters/oxlint';\n *\n * export default defineConfig(oxlintConfigs);\n * ```\n *\n * `OxlintConfigs.create({ lenientFallback: true })` is the same preset with `||` allowed on string\n * and number operands.\n */\nexport const oxlintConfigs: OxlintConfig = {\n plugins: ['typescript', 'unicorn'],\n categories: { correctness: 'off' },\n options: { typeAware: true },\n env: { builtin: true },\n ignorePatterns: ['**/node_modules/', '**/*.d.ts', '**/build/', '**/dist/', '**/release/'],\n rules: {\n // eslint:recommended\n 'constructor-super': 'error',\n 'for-direction': 'error',\n 'getter-return': 'error',\n 'no-async-promise-executor': 'error',\n 'no-case-declarations': 'error',\n 'no-class-assign': 'error',\n 'no-compare-neg-zero': 'error',\n 'no-cond-assign': 'error',\n 'no-const-assign': 'error',\n 'no-constant-binary-expression': 'error',\n 'no-constant-condition': 'error',\n 'no-control-regex': 'error',\n 'no-debugger': 'error',\n 'no-delete-var': 'error',\n 'no-dupe-else-if': 'error',\n 'no-dupe-keys': 'error',\n 'no-duplicate-case': 'error',\n 'no-empty': 'error',\n 'no-empty-character-class': 'error',\n 'no-empty-pattern': 'error',\n 'no-empty-static-block': 'error',\n 'no-ex-assign': 'error',\n 'no-extra-boolean-cast': 'error',\n 'no-fallthrough': 'error',\n 'no-func-assign': 'error',\n 'no-global-assign': 'error',\n 'no-import-assign': 'error',\n 'no-invalid-regexp': 'error',\n 'no-irregular-whitespace': 'error',\n 'no-loss-of-precision': 'error',\n 'no-misleading-character-class': 'error',\n 'no-new-native-nonconstructor': 'error',\n 'no-nonoctal-decimal-escape': 'error',\n 'no-obj-calls': 'error',\n 'no-prototype-builtins': 'error',\n 'no-regex-spaces': 'error',\n 'no-self-assign': 'error',\n 'no-setter-return': 'error',\n 'no-shadow-restricted-names': 'error',\n 'no-sparse-arrays': 'error',\n 'no-this-before-super': 'error',\n 'no-unassigned-vars': 'error',\n 'no-unreachable': 'error',\n 'no-unsafe-finally': 'error',\n 'no-unsafe-negation': 'error',\n 'no-unsafe-optional-chaining': 'error',\n 'no-unused-labels': 'error',\n 'no-unused-private-class-members': 'error',\n 'no-useless-backreference': 'error',\n 'no-useless-catch': 'error',\n 'no-with': 'error',\n 'preserve-caught-error': 'error',\n 'require-yield': 'error',\n 'use-isnan': 'error',\n 'valid-typeof': 'error',\n 'no-array-constructor': 'error',\n\n // Strict rules on top\n [NoUnusedVarsRule.NAME]: NoUnusedVarsRule.build(),\n 'no-useless-escape': 'warn',\n 'no-unused-expressions': 'error',\n 'no-new-wrappers': 'error',\n 'no-throw-literal': 'error',\n [EqeqeqRule.NAME]: EqeqeqRule.build(),\n 'no-void': 'error',\n 'no-caller': 'error',\n 'no-shadow': 'error',\n 'no-use-before-define': 'error',\n [SwitchCaseBracesRule.NAME]: SwitchCaseBracesRule.build(),\n 'unicorn/prefer-node-protocol': 'error',\n\n // typescript-eslint\n 'typescript/ban-ts-comment': 'error',\n 'typescript/no-duplicate-enum-values': 'error',\n 'typescript/no-empty-object-type': 'error',\n 'typescript/no-extra-non-null-assertion': 'error',\n 'typescript/no-misused-new': 'error',\n 'typescript/no-namespace': 'error',\n 'typescript/no-non-null-asserted-optional-chain': 'error',\n 'typescript/no-this-alias': 'error',\n 'typescript/no-unnecessary-type-constraint': 'error',\n 'typescript/no-unsafe-declaration-merging': 'error',\n 'typescript/no-unsafe-function-type': 'error',\n 'typescript/no-wrapper-object-types': 'error',\n 'typescript/prefer-as-const': 'error',\n 'typescript/prefer-namespace-keyword': 'error',\n 'typescript/triple-slash-reference': 'error',\n 'typescript/adjacent-overload-signatures': 'error',\n 'typescript/prefer-for-of': 'error',\n 'typescript/unified-signatures': 'error',\n\n // typescript-eslint, type-aware\n 'typescript/await-thenable': 'error',\n 'typescript/no-floating-promises': 'error',\n [PreferNullishCoalescingRule.NAME]: PreferNullishCoalescingRule.build(),\n 'typescript/return-await': 'error',\n },\n overrides: [\n {\n // TypeScript itself reports these.\n files: TS_FILES,\n rules: {\n 'constructor-super': 'off',\n 'getter-return': 'off',\n 'no-class-assign': 'off',\n 'no-const-assign': 'off',\n 'no-dupe-keys': 'off',\n 'no-func-assign': 'off',\n 'no-import-assign': 'off',\n 'no-new-native-nonconstructor': 'off',\n 'no-obj-calls': 'off',\n 'no-setter-return': 'off',\n 'no-this-before-super': 'off',\n 'no-unreachable': 'off',\n 'no-unsafe-negation': 'off',\n 'no-with': 'off',\n 'no-var': 'error',\n 'prefer-const': 'error',\n 'prefer-rest-params': 'error',\n 'prefer-spread': 'error',\n // A value import of a type becomes a runtime import when Bun runs a decorated class's source\n // (emitDecoratorMetadata) and fails with `Export named 'X' not found`. `import('pkg').T` type\n // annotations stay allowed: they are type-only by construction, and type an optional peer.\n 'typescript/consistent-type-imports': [\n 'error',\n {\n prefer: 'type-imports',\n fixStyle: 'inline-type-imports',\n disallowTypeAnnotations: false,\n },\n ],\n },\n },\n {\n files: JS_TS_FILES,\n rules: {\n 'no-constant-condition': 'off',\n 'prefer-const': 'error',\n 'no-var': 'error',\n curly: ['error', 'all'],\n [NoRestrictedImportsRule.NAME]: NoRestrictedImportsRule.build(),\n 'typescript/no-unsafe-function-type': 'off',\n 'typescript/no-this-alias': 'off',\n 'typescript/no-empty-object-type': 'off',\n },\n },\n ],\n};\n\n/** Options of `OxlintConfigs.create`. */\nexport interface IOxlintPresetOptions {\n /**\n * Allow `||` / `||=` where the left side is a string or a number, so `name || 'guest'` and\n * `limit || 20` pass: `''` and `0` fall back on purpose. Left off, the base catches a real\n * `''` or `0` swallowed by `||`.\n *\n * @default false\n */\n lenientFallback?: boolean;\n /**\n * Project paths to skip - generated files, vendored code - as in `--ignore-pattern`: `src/gen/**`.\n * Every rule is turned off for them (oxlint cannot ignore a project path from `.configs/`).\n * Share the list with ESLint through `LintIgnore`.\n *\n * @default []\n */\n ignore?: string[];\n}\n\n/**\n * Builds `oxlintConfigs` with options. Without any it returns the base preset unchanged.\n *\n * ```ts\n * // .configs/lints/oxlint.config.mts\n * import { defineConfig } from 'oxlint';\n * import { OxlintConfigs } from '@venizia/dev-configs/linters/oxlint';\n *\n * export default defineConfig(OxlintConfigs.create({ lenientFallback: true }));\n * ```\n */\nexport class OxlintConfigs {\n static create(opts: IOxlintPresetOptions = {}): OxlintConfig {\n const config: OxlintConfig = opts.lenientFallback\n ? {\n ...oxlintConfigs,\n rules: {\n ...oxlintConfigs.rules,\n [PreferNullishCoalescingRule.NAME]: PreferNullishCoalescingRule.build({\n ignorePrimitives: { string: true, number: true },\n }),\n },\n }\n : oxlintConfigs;\n\n return LintIgnore.oxlint({ config, patterns: opts.ignore ?? [] });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"oxlint.js","sourceRoot":"","sources":["../../src/linters/oxlint.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OxlintConfig } from 'oxlint';\nimport { LintIgnore } from './ignore';\nimport {\n EqeqeqRule,\n NoRestrictedImportsRule,\n NoUnusedVarsRule,\n PreferNullishCoalescingRule,\n SwitchCaseBracesRule,\n} from './rules';\n\n/** File globs the rules are scoped to. */\nconst TS_FILES = ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'];\nconst JS_TS_FILES = ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.jsx', ...TS_FILES];\n\n/**\n * The oxlint port of `eslintConfigs`, generated with `@oxlint/migrate` and kept rule for rule.\n * Type-aware rules (`no-floating-promises`, `return-await`, ...) need `oxlint-tsgolint` installed.\n *\n * Not ported: `@typescript-eslint/naming-convention` (oxlint has no equivalent yet - keep it in\n * ESLint), `@typescript-eslint/prefer-optional-chain` (oxlint nursery), `no-invalid-this` (covered\n * by `noImplicitThis` in `tsconfig.base.json`). `n/prefer-node-protocol` maps to the unicorn rule.\n *\n * ```ts\n * // .configs/lints/oxlint.config.mts\n * import { defineConfig } from 'oxlint';\n * import { oxlintConfigs } from '@venizia/dev-configs/linters/oxlint';\n *\n * export default defineConfig(oxlintConfigs);\n * ```\n *\n * `prefer-nullish-coalescing` allows `||` on a string (`name?.trim() || 'guest'`) and reports it on\n * every other nullable type. `OxlintConfigs.create({ lenientFallback: true })` is the same preset\n * with `||` allowed on number operands too.\n */\nexport const oxlintConfigs: OxlintConfig = {\n plugins: ['typescript', 'unicorn'],\n categories: { correctness: 'off' },\n options: { typeAware: true },\n env: { builtin: true },\n ignorePatterns: ['**/node_modules/', '**/*.d.ts', '**/build/', '**/dist/', '**/release/'],\n rules: {\n // eslint:recommended\n 'constructor-super': 'error',\n 'for-direction': 'error',\n 'getter-return': 'error',\n 'no-async-promise-executor': 'error',\n 'no-case-declarations': 'error',\n 'no-class-assign': 'error',\n 'no-compare-neg-zero': 'error',\n 'no-cond-assign': 'error',\n 'no-const-assign': 'error',\n 'no-constant-binary-expression': 'error',\n 'no-constant-condition': 'error',\n 'no-control-regex': 'error',\n 'no-debugger': 'error',\n 'no-delete-var': 'error',\n 'no-dupe-else-if': 'error',\n 'no-dupe-keys': 'error',\n 'no-duplicate-case': 'error',\n 'no-empty': 'error',\n 'no-empty-character-class': 'error',\n 'no-empty-pattern': 'error',\n 'no-empty-static-block': 'error',\n 'no-ex-assign': 'error',\n 'no-extra-boolean-cast': 'error',\n 'no-fallthrough': 'error',\n 'no-func-assign': 'error',\n 'no-global-assign': 'error',\n 'no-import-assign': 'error',\n 'no-invalid-regexp': 'error',\n 'no-irregular-whitespace': 'error',\n 'no-loss-of-precision': 'error',\n 'no-misleading-character-class': 'error',\n 'no-new-native-nonconstructor': 'error',\n 'no-nonoctal-decimal-escape': 'error',\n 'no-obj-calls': 'error',\n 'no-prototype-builtins': 'error',\n 'no-regex-spaces': 'error',\n 'no-self-assign': 'error',\n 'no-setter-return': 'error',\n 'no-shadow-restricted-names': 'error',\n 'no-sparse-arrays': 'error',\n 'no-this-before-super': 'error',\n 'no-unassigned-vars': 'error',\n 'no-unreachable': 'error',\n 'no-unsafe-finally': 'error',\n 'no-unsafe-negation': 'error',\n 'no-unsafe-optional-chaining': 'error',\n 'no-unused-labels': 'error',\n 'no-unused-private-class-members': 'error',\n 'no-useless-backreference': 'error',\n 'no-useless-catch': 'error',\n 'no-with': 'error',\n 'preserve-caught-error': 'error',\n 'require-yield': 'error',\n 'use-isnan': 'error',\n 'valid-typeof': 'error',\n 'no-array-constructor': 'error',\n\n // Strict rules on top\n [NoUnusedVarsRule.NAME]: NoUnusedVarsRule.build(),\n 'no-useless-escape': 'warn',\n 'no-unused-expressions': 'error',\n 'no-new-wrappers': 'error',\n 'no-throw-literal': 'error',\n [EqeqeqRule.NAME]: EqeqeqRule.build(),\n 'no-void': 'error',\n 'no-caller': 'error',\n 'no-shadow': 'error',\n 'no-use-before-define': 'error',\n [SwitchCaseBracesRule.NAME]: SwitchCaseBracesRule.build(),\n 'unicorn/prefer-node-protocol': 'error',\n\n // typescript-eslint\n 'typescript/ban-ts-comment': 'error',\n 'typescript/no-duplicate-enum-values': 'error',\n 'typescript/no-empty-object-type': 'error',\n 'typescript/no-extra-non-null-assertion': 'error',\n 'typescript/no-misused-new': 'error',\n 'typescript/no-namespace': 'error',\n 'typescript/no-non-null-asserted-optional-chain': 'error',\n 'typescript/no-this-alias': 'error',\n 'typescript/no-unnecessary-type-constraint': 'error',\n 'typescript/no-unsafe-declaration-merging': 'error',\n 'typescript/no-unsafe-function-type': 'error',\n 'typescript/no-wrapper-object-types': 'error',\n 'typescript/prefer-as-const': 'error',\n 'typescript/prefer-namespace-keyword': 'error',\n 'typescript/triple-slash-reference': 'error',\n 'typescript/adjacent-overload-signatures': 'error',\n 'typescript/prefer-for-of': 'error',\n 'typescript/unified-signatures': 'error',\n\n // typescript-eslint, type-aware\n 'typescript/await-thenable': 'error',\n 'typescript/no-floating-promises': 'error',\n // `||` on a string is mostly an intentional empty-string fallback (`value?.trim() || fallback`);\n // `??` keeps `''` and changes behaviour. Objects and numbers still report.\n [PreferNullishCoalescingRule.NAME]: PreferNullishCoalescingRule.build({\n ignorePrimitives: { string: true },\n }),\n 'typescript/return-await': 'error',\n },\n overrides: [\n {\n // TypeScript itself reports these.\n files: TS_FILES,\n rules: {\n 'constructor-super': 'off',\n 'getter-return': 'off',\n 'no-class-assign': 'off',\n 'no-const-assign': 'off',\n 'no-dupe-keys': 'off',\n 'no-func-assign': 'off',\n 'no-import-assign': 'off',\n 'no-new-native-nonconstructor': 'off',\n 'no-obj-calls': 'off',\n 'no-setter-return': 'off',\n 'no-this-before-super': 'off',\n 'no-unreachable': 'off',\n 'no-unsafe-negation': 'off',\n 'no-with': 'off',\n 'no-var': 'error',\n 'prefer-const': 'error',\n 'prefer-rest-params': 'error',\n 'prefer-spread': 'error',\n // A value import of a type becomes a runtime import when Bun runs a decorated class's source\n // (emitDecoratorMetadata) and fails with `Export named 'X' not found`. `import('pkg').T` type\n // annotations stay allowed: they are type-only by construction, and type an optional peer.\n 'typescript/consistent-type-imports': [\n 'error',\n {\n prefer: 'type-imports',\n fixStyle: 'inline-type-imports',\n disallowTypeAnnotations: false,\n },\n ],\n },\n },\n {\n files: JS_TS_FILES,\n rules: {\n 'no-constant-condition': 'off',\n 'prefer-const': 'error',\n 'no-var': 'error',\n curly: ['error', 'all'],\n [NoRestrictedImportsRule.NAME]: NoRestrictedImportsRule.build(),\n 'typescript/no-unsafe-function-type': 'off',\n 'typescript/no-this-alias': 'off',\n 'typescript/no-empty-object-type': 'off',\n },\n },\n ],\n};\n\n/** Options of `OxlintConfigs.create`. */\nexport interface IOxlintPresetOptions {\n /**\n * Also allow `||` / `||=` where the left side is a number, so `limit || 20` passes: `0` falls\n * back on purpose. A string is allowed by the base already. Left off, the base catches a real `0`\n * swallowed by `||`.\n *\n * @default false\n */\n lenientFallback?: boolean;\n /**\n * Project paths to skip - generated files, vendored code - as in `--ignore-pattern`: `src/gen/**`.\n * Every rule is turned off for them (oxlint cannot ignore a project path from `.configs/`).\n * Share the list with ESLint through `LintIgnore`.\n *\n * @default []\n */\n ignore?: string[];\n}\n\n/**\n * Builds `oxlintConfigs` with options. Without any it returns the base preset unchanged.\n *\n * ```ts\n * // .configs/lints/oxlint.config.mts\n * import { defineConfig } from 'oxlint';\n * import { OxlintConfigs } from '@venizia/dev-configs/linters/oxlint';\n *\n * export default defineConfig(OxlintConfigs.create({ lenientFallback: true }));\n * ```\n */\nexport class OxlintConfigs {\n static create(opts: IOxlintPresetOptions = {}): OxlintConfig {\n const config: OxlintConfig = opts.lenientFallback\n ? {\n ...oxlintConfigs,\n rules: {\n ...oxlintConfigs.rules,\n [PreferNullishCoalescingRule.NAME]: PreferNullishCoalescingRule.build({\n ignorePrimitives: { string: true, number: true },\n }),\n },\n }\n : oxlintConfigs;\n\n return LintIgnore.oxlint({ config, patterns: opts.ignore ?? [] });\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/dev-configs",
|
|
3
|
-
"version": "0.4.8-
|
|
3
|
+
"version": "0.4.8-3",
|
|
4
4
|
"description": "Shareable development configurations for TypeScript projects: oxlint presets with per-rule builders, the ESLint naming-convention rule, the legacy ESLint flat config, and TypeScript compiler options with critical decorator support (experimentalDecorators, emitDecoratorMetadata, useDefineForClassFields). Single source of truth for consistent code style, type checking, and build settings across monorepo packages.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"build-tools",
|