@thethracian/oxlint-config 0.2.1 → 0.3.1
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/CHANGELOG.md +13 -0
- package/README.md +124 -18
- package/dist/codemod-fix/cli.d.ts +3 -0
- package/dist/codemod-fix/cli.d.ts.map +1 -0
- package/dist/codemod-fix/cli.js +22 -0
- package/dist/codemod-fix/cli.js.map +1 -0
- package/dist/codemod-fix/index.d.ts +44 -0
- package/dist/codemod-fix/index.d.ts.map +1 -0
- package/dist/codemod-fix/index.js +110 -0
- package/dist/codemod-fix/index.js.map +1 -0
- package/dist/codemods/arrow-body-style.d.ts +7 -0
- package/dist/codemods/arrow-body-style.d.ts.map +1 -0
- package/dist/codemods/arrow-body-style.js +106 -0
- package/dist/codemods/arrow-body-style.js.map +1 -0
- package/dist/codemods/comment-format.d.ts +24 -0
- package/dist/codemods/comment-format.d.ts.map +1 -0
- package/dist/codemods/comment-format.js +100 -0
- package/dist/codemods/comment-format.js.map +1 -0
- package/dist/codemods/explicit-return-types.d.ts +7 -0
- package/dist/codemods/explicit-return-types.d.ts.map +1 -0
- package/dist/codemods/explicit-return-types.js +350 -0
- package/dist/codemods/explicit-return-types.js.map +1 -0
- package/dist/codemods/format-file-header.d.ts +7 -0
- package/dist/codemods/format-file-header.d.ts.map +1 -0
- package/dist/codemods/format-file-header.js +163 -0
- package/dist/codemods/format-file-header.js.map +1 -0
- package/dist/codemods/format-jsdoc-comments.d.ts +7 -0
- package/dist/codemods/format-jsdoc-comments.d.ts.map +1 -0
- package/dist/codemods/format-jsdoc-comments.js +129 -0
- package/dist/codemods/format-jsdoc-comments.js.map +1 -0
- package/dist/codemods/function-declarations.d.ts +7 -0
- package/dist/codemods/function-declarations.d.ts.map +1 -0
- package/dist/codemods/function-declarations.js +202 -0
- package/dist/codemods/function-declarations.js.map +1 -0
- package/dist/codemods/inline-export-lists.d.ts +7 -0
- package/dist/codemods/inline-export-lists.d.ts.map +1 -0
- package/dist/codemods/inline-export-lists.js +168 -0
- package/dist/codemods/inline-export-lists.js.map +1 -0
- package/dist/codemods/internal-export-docs.d.ts +7 -0
- package/dist/codemods/internal-export-docs.d.ts.map +1 -0
- package/dist/codemods/internal-export-docs.js +93 -0
- package/dist/codemods/internal-export-docs.js.map +1 -0
- package/dist/codemods/no-ternary-branch-initializers.d.ts +14 -0
- package/dist/codemods/no-ternary-branch-initializers.d.ts.map +1 -0
- package/dist/codemods/no-ternary-branch-initializers.js +240 -0
- package/dist/codemods/no-ternary-branch-initializers.js.map +1 -0
- package/dist/codemods/no-ternary-variable-initializers.d.ts +14 -0
- package/dist/codemods/no-ternary-variable-initializers.d.ts.map +1 -0
- package/dist/codemods/no-ternary-variable-initializers.js +235 -0
- package/dist/codemods/no-ternary-variable-initializers.js.map +1 -0
- package/dist/codemods/no-ternary.d.ts +7 -0
- package/dist/codemods/no-ternary.d.ts.map +1 -0
- package/dist/codemods/no-ternary.js +215 -0
- package/dist/codemods/no-ternary.js.map +1 -0
- package/dist/codemods/rename-acronyms.d.ts +8 -0
- package/dist/codemods/rename-acronyms.d.ts.map +1 -0
- package/dist/codemods/rename-acronyms.js +193 -0
- package/dist/codemods/rename-acronyms.js.map +1 -0
- package/dist/codemods/run.d.ts +2 -0
- package/dist/codemods/run.d.ts.map +1 -0
- package/dist/codemods/run.js +14 -0
- package/dist/codemods/run.js.map +1 -0
- package/dist/codemods/sort-imports.d.ts +7 -0
- package/dist/codemods/sort-imports.d.ts.map +1 -0
- package/dist/codemods/sort-imports.js +235 -0
- package/dist/codemods/sort-imports.js.map +1 -0
- package/dist/index.d.ts +30 -96
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +156 -94
- package/dist/index.js.map +1 -1
- package/dist/rules/acronym-case.d.ts +7 -3
- package/dist/rules/acronym-case.d.ts.map +1 -1
- package/dist/rules/acronym-case.js +129 -118
- package/dist/rules/acronym-case.js.map +1 -1
- package/dist/rules/acronyms-1.d.ts +3 -0
- package/dist/rules/acronyms-1.d.ts.map +1 -0
- package/dist/rules/acronyms-1.js +407 -0
- package/dist/rules/acronyms-1.js.map +1 -0
- package/dist/rules/acronyms-2.d.ts +3 -0
- package/dist/rules/acronyms-2.d.ts.map +1 -0
- package/dist/rules/acronyms-2.js +407 -0
- package/dist/rules/acronyms-2.js.map +1 -0
- package/dist/rules/acronyms-3.d.ts +3 -0
- package/dist/rules/acronyms-3.d.ts.map +1 -0
- package/dist/rules/acronyms-3.js +407 -0
- package/dist/rules/acronyms-3.js.map +1 -0
- package/dist/rules/acronyms-4.d.ts +3 -0
- package/dist/rules/acronyms-4.d.ts.map +1 -0
- package/dist/rules/acronyms-4.js +377 -0
- package/dist/rules/acronyms-4.js.map +1 -0
- package/dist/rules/acronyms.d.ts +1 -8
- package/dist/rules/acronyms.d.ts.map +1 -1
- package/dist/rules/acronyms.js +14 -1578
- package/dist/rules/acronyms.js.map +1 -1
- package/dist/rules/boolean-prefix.d.ts +11 -2
- package/dist/rules/boolean-prefix.d.ts.map +1 -1
- package/dist/rules/boolean-prefix.js +95 -59
- package/dist/rules/boolean-prefix.js.map +1 -1
- package/dist/rules/camel-case-identifiers.d.ts +3 -4
- package/dist/rules/camel-case-identifiers.d.ts.map +1 -1
- package/dist/rules/camel-case-identifiers.js +59 -40
- package/dist/rules/camel-case-identifiers.js.map +1 -1
- package/dist/rules/char-class.d.ts +26 -13
- package/dist/rules/char-class.d.ts.map +1 -1
- package/dist/rules/char-class.js +56 -24
- package/dist/rules/char-class.js.map +1 -1
- package/dist/rules/diagnostic-guidance.d.ts +91 -0
- package/dist/rules/diagnostic-guidance.d.ts.map +1 -0
- package/dist/rules/diagnostic-guidance.js +243 -0
- package/dist/rules/diagnostic-guidance.js.map +1 -0
- package/dist/rules/effect-default-ast.d.ts +89 -0
- package/dist/rules/effect-default-ast.d.ts.map +1 -0
- package/dist/rules/effect-default-ast.js +208 -0
- package/dist/rules/effect-default-ast.js.map +1 -0
- package/dist/rules/effect-default-compat-rules.d.ts +76 -0
- package/dist/rules/effect-default-compat-rules.d.ts.map +1 -0
- package/dist/rules/effect-default-compat-rules.js +270 -0
- package/dist/rules/effect-default-compat-rules.js.map +1 -0
- package/dist/rules/effect-default-env-rules.d.ts +60 -0
- package/dist/rules/effect-default-env-rules.d.ts.map +1 -0
- package/dist/rules/effect-default-env-rules.js +259 -0
- package/dist/rules/effect-default-env-rules.js.map +1 -0
- package/dist/rules/effect-default-fiber-helpers.d.ts +13 -0
- package/dist/rules/effect-default-fiber-helpers.d.ts.map +1 -0
- package/dist/rules/effect-default-fiber-helpers.js +76 -0
- package/dist/rules/effect-default-fiber-helpers.js.map +1 -0
- package/dist/rules/effect-default-floating-helpers.d.ts +7 -0
- package/dist/rules/effect-default-floating-helpers.d.ts.map +1 -0
- package/dist/rules/effect-default-floating-helpers.js +113 -0
- package/dist/rules/effect-default-floating-helpers.js.map +1 -0
- package/dist/rules/effect-default-helpers.d.ts +8 -32
- package/dist/rules/effect-default-helpers.d.ts.map +1 -1
- package/dist/rules/effect-default-helpers.js +11 -535
- package/dist/rules/effect-default-helpers.js.map +1 -1
- package/dist/rules/effect-default-resource-helpers.d.ts +18 -4
- package/dist/rules/effect-default-resource-helpers.d.ts.map +1 -1
- package/dist/rules/effect-default-resource-helpers.js +30 -13
- package/dist/rules/effect-default-resource-helpers.js.map +1 -1
- package/dist/rules/effect-default-safety-helpers.d.ts +43 -0
- package/dist/rules/effect-default-safety-helpers.d.ts.map +1 -0
- package/dist/rules/effect-default-safety-helpers.js +126 -0
- package/dist/rules/effect-default-safety-helpers.js.map +1 -0
- package/dist/rules/effect-default-scan-helpers.d.ts +43 -0
- package/dist/rules/effect-default-scan-helpers.d.ts.map +1 -0
- package/dist/rules/effect-default-scan-helpers.js +141 -0
- package/dist/rules/effect-default-scan-helpers.js.map +1 -0
- package/dist/rules/effect-default-schema-helpers.d.ts +37 -0
- package/dist/rules/effect-default-schema-helpers.d.ts.map +1 -0
- package/dist/rules/effect-default-schema-helpers.js +104 -0
- package/dist/rules/effect-default-schema-helpers.js.map +1 -0
- package/dist/rules/effect-default-test-helpers.d.ts +18 -4
- package/dist/rules/effect-default-test-helpers.d.ts.map +1 -1
- package/dist/rules/effect-default-test-helpers.js +41 -20
- package/dist/rules/effect-default-test-helpers.js.map +1 -1
- package/dist/rules/effect-default-workflow-helpers.d.ts +91 -0
- package/dist/rules/effect-default-workflow-helpers.d.ts.map +1 -0
- package/dist/rules/effect-default-workflow-helpers.js +247 -0
- package/dist/rules/effect-default-workflow-helpers.js.map +1 -0
- package/dist/rules/effect-default.d.ts +1 -1
- package/dist/rules/effect-default.d.ts.map +1 -1
- package/dist/rules/effect-default.js +105 -680
- package/dist/rules/effect-default.js.map +1 -1
- package/dist/rules/effect-exported-declarations.d.ts +19 -0
- package/dist/rules/effect-exported-declarations.d.ts.map +1 -0
- package/dist/rules/effect-exported-declarations.js +237 -0
- package/dist/rules/effect-exported-declarations.js.map +1 -0
- package/dist/rules/effect-path-options.d.ts +49 -11
- package/dist/rules/effect-path-options.d.ts.map +1 -1
- package/dist/rules/effect-path-options.js +85 -52
- package/dist/rules/effect-path-options.js.map +1 -1
- package/dist/rules/effect-rule-aliases.d.ts +55 -0
- package/dist/rules/effect-rule-aliases.d.ts.map +1 -0
- package/dist/rules/effect-rule-aliases.js +278 -0
- package/dist/rules/effect-rule-aliases.js.map +1 -0
- package/dist/rules/effect-rule-core.d.ts +38 -24
- package/dist/rules/effect-rule-core.d.ts.map +1 -1
- package/dist/rules/effect-rule-core.js +157 -344
- package/dist/rules/effect-rule-core.js.map +1 -1
- package/dist/rules/effect-rule-names.d.ts +12 -3
- package/dist/rules/effect-rule-names.d.ts.map +1 -1
- package/dist/rules/effect-rule-names.js +15 -3
- package/dist/rules/effect-rule-names.js.map +1 -1
- package/dist/rules/effect-source-comments.d.ts +7 -0
- package/dist/rules/effect-source-comments.d.ts.map +1 -0
- package/dist/rules/effect-source-comments.js +227 -0
- package/dist/rules/effect-source-comments.js.map +1 -0
- package/dist/rules/effect-source-helpers.d.ts +4 -9
- package/dist/rules/effect-source-helpers.d.ts.map +1 -1
- package/dist/rules/effect-source-helpers.js +7 -358
- package/dist/rules/effect-source-helpers.js.map +1 -1
- package/dist/rules/effect-source-navigation.d.ts +25 -0
- package/dist/rules/effect-source-navigation.d.ts.map +1 -0
- package/dist/rules/effect-source-navigation.js +244 -0
- package/dist/rules/effect-source-navigation.js.map +1 -0
- package/dist/rules/effect-source-scan.d.ts +30 -7
- package/dist/rules/effect-source-scan.d.ts.map +1 -1
- package/dist/rules/effect-source-scan.js +372 -300
- package/dist/rules/effect-source-scan.js.map +1 -1
- package/dist/rules/effect-strict-ast-specs.d.ts +8 -0
- package/dist/rules/effect-strict-ast-specs.d.ts.map +1 -0
- package/dist/rules/effect-strict-ast-specs.js +166 -0
- package/dist/rules/effect-strict-ast-specs.js.map +1 -0
- package/dist/rules/effect-strict-boundary-helpers.d.ts +25 -0
- package/dist/rules/effect-strict-boundary-helpers.d.ts.map +1 -0
- package/dist/rules/effect-strict-boundary-helpers.js +127 -0
- package/dist/rules/effect-strict-boundary-helpers.js.map +1 -0
- package/dist/rules/effect-strict-core-specs.d.ts +8 -0
- package/dist/rules/effect-strict-core-specs.d.ts.map +1 -0
- package/dist/rules/effect-strict-core-specs.js +334 -0
- package/dist/rules/effect-strict-core-specs.js.map +1 -0
- package/dist/rules/effect-strict-external-helpers.d.ts +25 -0
- package/dist/rules/effect-strict-external-helpers.d.ts.map +1 -0
- package/dist/rules/effect-strict-external-helpers.js +87 -0
- package/dist/rules/effect-strict-external-helpers.js.map +1 -0
- package/dist/rules/effect-strict-helpers.d.ts +75 -33
- package/dist/rules/effect-strict-helpers.d.ts.map +1 -1
- package/dist/rules/effect-strict-helpers.js +93 -384
- package/dist/rules/effect-strict-helpers.js.map +1 -1
- package/dist/rules/effect-strict-internals.d.ts +198 -0
- package/dist/rules/effect-strict-internals.d.ts.map +1 -0
- package/dist/rules/effect-strict-internals.js +477 -0
- package/dist/rules/effect-strict-internals.js.map +1 -0
- package/dist/rules/effect-strict-segment-helpers.d.ts +79 -0
- package/dist/rules/effect-strict-segment-helpers.d.ts.map +1 -0
- package/dist/rules/effect-strict-segment-helpers.js +308 -0
- package/dist/rules/effect-strict-segment-helpers.js.map +1 -0
- package/dist/rules/effect-strict.d.ts +1 -1
- package/dist/rules/effect-strict.d.ts.map +1 -1
- package/dist/rules/effect-strict.js +10 -725
- package/dist/rules/effect-strict.js.map +1 -1
- package/dist/rules/max-import-depth.d.ts +2 -2
- package/dist/rules/max-import-depth.d.ts.map +1 -1
- package/dist/rules/max-import-depth.js +52 -17
- package/dist/rules/max-import-depth.js.map +1 -1
- package/dist/rules/max-line-length.d.ts +9 -2
- package/dist/rules/max-line-length.d.ts.map +1 -1
- package/dist/rules/max-line-length.js +52 -15
- package/dist/rules/max-line-length.js.map +1 -1
- package/dist/rules/no-commented-out-code.d.ts +3 -7
- package/dist/rules/no-commented-out-code.d.ts.map +1 -1
- package/dist/rules/no-commented-out-code.js +157 -102
- package/dist/rules/no-commented-out-code.js.map +1 -1
- package/dist/rules/pascal-case-types.d.ts +1 -1
- package/dist/rules/pascal-case-types.d.ts.map +1 -1
- package/dist/rules/pascal-case-types.js +65 -46
- package/dist/rules/pascal-case-types.js.map +1 -1
- package/dist/rules/plugin-commented-out-code-rule.d.ts +32 -0
- package/dist/rules/plugin-commented-out-code-rule.d.ts.map +1 -0
- package/dist/rules/plugin-commented-out-code-rule.js +135 -0
- package/dist/rules/plugin-commented-out-code-rule.js.map +1 -0
- package/dist/rules/plugin.d.ts +5 -0
- package/dist/rules/plugin.d.ts.map +1 -1
- package/dist/rules/plugin.js +168 -154
- package/dist/rules/plugin.js.map +1 -1
- package/dist/rules/private-underscore.d.ts +1 -1
- package/dist/rules/private-underscore.d.ts.map +1 -1
- package/dist/rules/private-underscore.js +11 -4
- package/dist/rules/private-underscore.js.map +1 -1
- package/dist/rules/require-file-doc.d.ts +5 -6
- package/dist/rules/require-file-doc.d.ts.map +1 -1
- package/dist/rules/require-file-doc.js +127 -78
- package/dist/rules/require-file-doc.js.map +1 -1
- package/dist/rules/require-function-doc-ignored-text.d.ts +7 -0
- package/dist/rules/require-function-doc-ignored-text.d.ts.map +1 -0
- package/dist/rules/require-function-doc-ignored-text.js +67 -0
- package/dist/rules/require-function-doc-ignored-text.js.map +1 -0
- package/dist/rules/require-function-doc-local-exports.d.ts +7 -0
- package/dist/rules/require-function-doc-local-exports.d.ts.map +1 -0
- package/dist/rules/require-function-doc-local-exports.js +114 -0
- package/dist/rules/require-function-doc-local-exports.js.map +1 -0
- package/dist/rules/require-function-doc.d.ts +3 -18
- package/dist/rules/require-function-doc.d.ts.map +1 -1
- package/dist/rules/require-function-doc.js +396 -221
- package/dist/rules/require-function-doc.js.map +1 -1
- package/dist/rules/source-cache.d.ts +13 -5
- package/dist/rules/source-cache.d.ts.map +1 -1
- package/dist/rules/source-cache.js +35 -22
- package/dist/rules/source-cache.js.map +1 -1
- package/package.json +10 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1 - 2026-05-25
|
|
4
|
+
|
|
5
|
+
### Changes
|
|
6
|
+
|
|
7
|
+
- chore(ts): consume published oxlint config (#8) (5a1b72a)
|
|
8
|
+
|
|
9
|
+
## 0.3.0 - 2026-05-25
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- feat(ci): keep performance gate local (#7) (635fdfe)
|
|
14
|
+
- feat(ts): rewrite codemod fixers with jscodeshift (#6) (989d924)
|
|
15
|
+
|
|
3
16
|
## 0.2.1 - 2026-05-24
|
|
4
17
|
|
|
5
18
|
### Changes
|
package/README.md
CHANGED
|
@@ -1,25 +1,96 @@
|
|
|
1
1
|
# @thethracian/oxlint-config
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/@thethracian/oxlint-config"><img alt="npm version" src="https://img.shields.io/npm/v/@thethracian/oxlint-config?style=flat-square"></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@thethracian/oxlint-config"><img alt="npm downloads" src="https://img.shields.io/npm/dw/@thethracian/oxlint-config?style=flat-square"></a>
|
|
6
|
+
<a href="https://socket.dev/npm/package/%40thethracian/oxlint-config"><img alt="Socket package analysis" src="https://socket.dev/api/badge/npm/package/@thethracian/oxlint-config"></a>
|
|
7
|
+
<a href="https://github.com/stefan-vatov/code-quality/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/stefan-vatov/code-quality/ci.yml?branch=main&style=flat-square"></a>
|
|
8
|
+
<a href="https://github.com/stefan-vatov/code-quality/blob/main/LICENSE"><img alt="MIT license" src="https://img.shields.io/badge/license-MIT-blue?style=flat-square"></a>
|
|
9
|
+
</p>
|
|
4
10
|
|
|
5
|
-
The
|
|
11
|
+
The Thracian Oxlint config is an experimental, painfully strict, very opinionated TypeScript lint profile for teams that want AI-generated code reviewed like production code.
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
```text
|
|
14
|
+
oxlint.config.mjs
|
|
15
|
+
import theThracian from '@thethracian/oxlint-config';
|
|
16
|
+
|
|
17
|
+
export default theThracian({ typeAware: true });
|
|
18
|
+
|
|
19
|
+
Result: native Oxlint rules + The Thracian custom rules + optional Effect policy checks.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Why Use It
|
|
23
|
+
|
|
24
|
+
- Strict by default: every rule is an error, not a suggestion.
|
|
25
|
+
- Agent-ready TypeScript: catches debug artifacts, unsafe escape hatches, silent catches, mutation, deep nesting, and oversized code.
|
|
26
|
+
- Effect-aware out of the box: 81 always-on Effect rules target lazy values, generator style, Promise boundaries, typed errors, Schema boundaries, resources, tests, and common hallucinated APIs.
|
|
27
|
+
- Strict Effect mode when you want it: opt in to 60 additional project-boundary rules for entrypoints, adapters, config layers, domain modules, service wiring, external calls, and test ownership.
|
|
28
|
+
- Importable config: consumers import one package instead of copying linter files around a codebase.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
9
31
|
|
|
10
32
|
```sh
|
|
11
33
|
pnpm add -D @thethracian/oxlint-config oxlint@^1.63.0
|
|
12
34
|
```
|
|
13
35
|
|
|
14
|
-
|
|
36
|
+
Create `oxlint.config.mjs`:
|
|
37
|
+
|
|
38
|
+
```js
|
|
15
39
|
import theThracian from '@thethracian/oxlint-config';
|
|
16
40
|
|
|
17
41
|
export default theThracian();
|
|
18
42
|
```
|
|
19
43
|
|
|
20
|
-
|
|
44
|
+
Run Oxlint:
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pnpm oxlint .
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Add package scripts for normal linting, type-aware linting, and the combined fixer:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"scripts": {
|
|
55
|
+
"lint": "oxlint src",
|
|
56
|
+
"lint:fix": "thx-codemod-fix src && oxlint src --fix && thx-codemod-fix src",
|
|
57
|
+
"lint:type-aware": "oxlint src --type-aware --type-check",
|
|
58
|
+
"lint:fix:type-aware": "thx-codemod-fix src && oxlint src --type-aware --type-check --fix && thx-codemod-fix src"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`thx-codemod-fix` is intentionally separate from `oxlint --fix` because Oxlint owns native rule fixes and the package CLI owns larger AST codemods. Running it before and after Oxlint is safe because the codemods are idempotent. The CLI defaults to `src`, but you can pass any files or directories your project wants fixed.
|
|
64
|
+
|
|
65
|
+
For staged files, wire the same package tools through `lint-staged`:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"lint-staged": {
|
|
70
|
+
"*.{ts,tsx,mts,cts}": [
|
|
71
|
+
"thx-codemod-fix",
|
|
72
|
+
"oxlint --type-aware --type-check --fix --no-error-on-unmatched-pattern",
|
|
73
|
+
"thx-codemod-fix"
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Programmatic consumers can use the same codemod runner:
|
|
21
80
|
|
|
22
81
|
```ts
|
|
82
|
+
import { codemodFix } from '@thethracian/oxlint-config/codemod-fix';
|
|
83
|
+
|
|
84
|
+
codemodFix({
|
|
85
|
+
paths: ['src', 'scripts'],
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Type-Aware Mode
|
|
90
|
+
|
|
91
|
+
Type-aware mode enables Oxlint's semantic TypeScript checks and the matching strict rules from this config.
|
|
92
|
+
|
|
93
|
+
```js
|
|
23
94
|
import theThracian from '@thethracian/oxlint-config';
|
|
24
95
|
|
|
25
96
|
export default theThracian({
|
|
@@ -27,14 +98,26 @@ export default theThracian({
|
|
|
27
98
|
});
|
|
28
99
|
```
|
|
29
100
|
|
|
30
|
-
|
|
31
|
-
target lazy Effect values, generator style, Promise boundaries, typed errors, resource safety,
|
|
32
|
-
Schema boundaries, test determinism, stale APIs, platform escape hatches, unsafe Effect type
|
|
33
|
-
assertions, service self-type drift, and common AI-generated Effect hallucinations.
|
|
101
|
+
Use this when you want checks such as unsafe calls, unsafe member access, floating promises, misused promises, and exhaustive switch handling. It is slower than syntax-only linting because Oxlint has to load TypeScript project information.
|
|
34
102
|
|
|
35
|
-
|
|
103
|
+
## Effect Defaults
|
|
36
104
|
|
|
37
|
-
|
|
105
|
+
Effect rules are enabled by default. They are designed for codebases where agents may produce plausible-looking but semantically weak Effect code.
|
|
106
|
+
|
|
107
|
+
The default bucket checks for patterns such as:
|
|
108
|
+
|
|
109
|
+
- floating `Effect` values that are never run, yielded, returned, or composed
|
|
110
|
+
- missing `yield*` inside `Effect.gen`
|
|
111
|
+
- nested `flatMap` code that should be `Effect.gen`
|
|
112
|
+
- string errors and untagged error channels
|
|
113
|
+
- unsafe Promise, throw, runtime, and sync boundaries
|
|
114
|
+
- Schema decode misuse at external data boundaries
|
|
115
|
+
- resource, fiber, stream, concurrency, and test determinism mistakes
|
|
116
|
+
- deprecated or invented Effect APIs
|
|
117
|
+
|
|
118
|
+
Disable the Effect bucket for non-Effect projects:
|
|
119
|
+
|
|
120
|
+
```js
|
|
38
121
|
import theThracian from '@thethracian/oxlint-config';
|
|
39
122
|
|
|
40
123
|
export default theThracian({
|
|
@@ -42,10 +125,11 @@ export default theThracian({
|
|
|
42
125
|
});
|
|
43
126
|
```
|
|
44
127
|
|
|
45
|
-
|
|
46
|
-
bucket:
|
|
128
|
+
## Strict Effect Mode
|
|
47
129
|
|
|
48
|
-
|
|
130
|
+
Strict mode adds project-boundary checks. It is intentionally opinionated and is best for Effect services with clear layers.
|
|
131
|
+
|
|
132
|
+
```js
|
|
49
133
|
import theThracian from '@thethracian/oxlint-config';
|
|
50
134
|
|
|
51
135
|
export default theThracian({
|
|
@@ -55,10 +139,9 @@ export default theThracian({
|
|
|
55
139
|
});
|
|
56
140
|
```
|
|
57
141
|
|
|
58
|
-
|
|
59
|
-
domain modules, adapters, and test types. Override them when a project uses a different layout:
|
|
142
|
+
Override the default project layout when your repository uses different paths:
|
|
60
143
|
|
|
61
|
-
```
|
|
144
|
+
```js
|
|
62
145
|
import theThracian from '@thethracian/oxlint-config';
|
|
63
146
|
|
|
64
147
|
export default theThracian({
|
|
@@ -75,3 +158,26 @@ export default theThracian({
|
|
|
75
158
|
},
|
|
76
159
|
});
|
|
77
160
|
```
|
|
161
|
+
|
|
162
|
+
## What It Enforces
|
|
163
|
+
|
|
164
|
+
| Area | Policy |
|
|
165
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
166
|
+
| Size and shape | 150-character lines, 500-line files, 75-line functions, max nesting depth 3, max 5 parameters, cyclomatic complexity 10 |
|
|
167
|
+
| TypeScript safety | no `any` escape hatches, no unsafe calls/member access, explicit function return types, strict equality |
|
|
168
|
+
| Async safety | no floating promises in type-aware mode, no misused promises, no unhandled Effect values |
|
|
169
|
+
| Debug and dynamic code | no `console`, `debugger`, `eval`, `new Function`, script URLs, warning comments, or commented-out code |
|
|
170
|
+
| Immutability | `prefer-const` and no parameter reassignment, including property mutation |
|
|
171
|
+
| Naming | PascalCase types, camelCase identifiers, boolean prefixes, private underscores, and consistent acronym casing |
|
|
172
|
+
| Effect | generator style, typed errors, Schema validation, resource safety, bounded concurrency, test determinism, and project boundaries |
|
|
173
|
+
|
|
174
|
+
## Registry Links
|
|
175
|
+
|
|
176
|
+
- npm: <https://www.npmjs.com/package/@thethracian/oxlint-config>
|
|
177
|
+
- Socket package analysis: <https://socket.dev/npm/package/%40thethracian/oxlint-config>
|
|
178
|
+
- Source: <https://github.com/stefan-vatov/code-quality/tree/main/ts>
|
|
179
|
+
- Issues: <https://github.com/stefan-vatov/code-quality/issues>
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/codemod-fix/cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* -------------------------------------------------------------------------- */
|
|
3
|
+
/* CLI entry point for running The Thracian codemod fixes. */
|
|
4
|
+
/* -------------------------------------------------------------------------- */
|
|
5
|
+
import { codemodFix } from './index.js';
|
|
6
|
+
const dryRunFlag = '--dry-run';
|
|
7
|
+
const rawArgs = process.argv.slice(2);
|
|
8
|
+
const dryRun = rawArgs.includes(dryRunFlag);
|
|
9
|
+
const paths = rawArgs.filter((arg) => arg !== dryRunFlag);
|
|
10
|
+
const result = codemodFix({ dryRun, paths });
|
|
11
|
+
const mode = (() => {
|
|
12
|
+
if (dryRun) {
|
|
13
|
+
return 'Would apply';
|
|
14
|
+
}
|
|
15
|
+
return 'Applied';
|
|
16
|
+
})();
|
|
17
|
+
process.stdout.write(`${mode} The Thracian codemod fixes to ${result.changedFiles.length} file(s); ` +
|
|
18
|
+
`scanned ${result.scannedFiles} file(s).\n`);
|
|
19
|
+
if (dryRun && result.changedFiles.length > 0) {
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/codemod-fix/cli.ts"],"names":[],"mappings":";AACA,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,UAAU,GAAG,WAAW,CAAC;AAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAW,EAAE,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC;AACnE,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7C,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE;IACzB,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC,EAAE,CAAC;AAEL,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,kCAAkC,MAAM,CAAC,YAAY,CAAC,MAAM,YAAY;IAC7E,WAAW,MAAM,CAAC,YAAY,aAAa,CAC9C,CAAC;AAEF,IAAI,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC7C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for running The Thracian codemod fixer.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface CodemodFixOptions {
|
|
7
|
+
cwd?: string;
|
|
8
|
+
dryRun?: boolean;
|
|
9
|
+
paths?: readonly string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Summary returned after scanning and optionally rewriting source files.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export interface CodemodFixResult {
|
|
17
|
+
changedFiles: string[];
|
|
18
|
+
scannedFiles: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Lists TypeScript source files under a root directory.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export declare const sourceFilesUnder: (root: string) => string[];
|
|
26
|
+
/**
|
|
27
|
+
* Applies all safe codemod fixes to a single source string.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export declare const applyCodemodFixToSource: (source: string) => string;
|
|
32
|
+
/**
|
|
33
|
+
* Applies all safe codemod fixes to one file.
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export declare const applyCodemodFixToFile: (path: string, dryRun: boolean) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Runs The Thracian codemod fixer across configured paths.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export declare const codemodFix: (options?: CodemodFixOptions) => CodemodFixResult;
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codemod-fix/index.ts"],"names":[],"mappings":"AAqBA;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,MAAM,EAoBrD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,KAAG,MAatD,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,EAAE,QAAQ,OAAO,KAAG,OAYrE,CAAC;AAUF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,UAAS,iBAAsB,KAAG,gBAiB5D,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* -------------------------------------------------------------------------- */
|
|
2
|
+
/* Public API for running The Thracian codemod fixes from package scripts or */
|
|
3
|
+
/* Tools. */
|
|
4
|
+
/* -------------------------------------------------------------------------- */
|
|
5
|
+
import { readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs';
|
|
6
|
+
import { addInternalExportDocs } from '../codemods/internal-export-docs.js';
|
|
7
|
+
import { addVoidReturnTypes } from '../codemods/explicit-return-types.js';
|
|
8
|
+
import { formatFileHeaderComment } from '../codemods/format-file-header.js';
|
|
9
|
+
import { formatJSDocComments } from '../codemods/format-jsdoc-comments.js';
|
|
10
|
+
import { inlineLocalExportLists } from '../codemods/inline-export-lists.js';
|
|
11
|
+
import { preferConciseArrowBodies } from '../codemods/arrow-body-style.js';
|
|
12
|
+
import { preferExplicitBranches } from '../codemods/no-ternary.js';
|
|
13
|
+
import { preferFunctionExpressions } from '../codemods/function-declarations.js';
|
|
14
|
+
import { renameMisCasedAcronyms } from '../codemods/rename-acronyms.js';
|
|
15
|
+
import { resolve } from 'node:path';
|
|
16
|
+
import { sortImportDeclarations } from '../codemods/sort-imports.js';
|
|
17
|
+
const defaultPaths = ['src'];
|
|
18
|
+
const sourceExtensions = new Set(['.ts', '.tsx', '.mts', '.cts']);
|
|
19
|
+
const ignoredDirectories = new Set(['bench', 'dist', 'fixtures', 'node_modules', 'test']);
|
|
20
|
+
const hasSourceExtension = (path) => [...sourceExtensions].some((extension) => path.endsWith(extension));
|
|
21
|
+
/**
|
|
22
|
+
* Lists TypeScript source files under a root directory.
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export const sourceFilesUnder = (root) => {
|
|
27
|
+
const files = [];
|
|
28
|
+
const visit = (directory) => {
|
|
29
|
+
for (const entry of readdirSync(directory)) {
|
|
30
|
+
const path = resolve(directory, entry);
|
|
31
|
+
const stats = statSync(path);
|
|
32
|
+
if (stats.isDirectory()) {
|
|
33
|
+
if (!ignoredDirectories.has(entry)) {
|
|
34
|
+
visit(path);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (stats.isFile() && hasSourceExtension(path)) {
|
|
38
|
+
files.push(path);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
visit(root);
|
|
43
|
+
return files;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Applies all safe codemod fixes to a single source string.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
export const applyCodemodFixToSource = (source) => formatJSDocComments(addInternalExportDocs(inlineLocalExportLists(addVoidReturnTypes(preferConciseArrowBodies(preferExplicitBranches(preferFunctionExpressions(sortImportDeclarations(renameMisCasedAcronyms(source)))))))));
|
|
51
|
+
/**
|
|
52
|
+
* Applies all safe codemod fixes to one file.
|
|
53
|
+
*
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export const applyCodemodFixToFile = (path, dryRun) => {
|
|
57
|
+
const before = readFileSync(path, 'utf8');
|
|
58
|
+
const after = formatFileHeaderComment(applyCodemodFixToSource(before));
|
|
59
|
+
if (after === before) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (!dryRun) {
|
|
63
|
+
writeFileSync(path, after);
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
67
|
+
const candidateFiles = (path) => {
|
|
68
|
+
const stats = statSync(path);
|
|
69
|
+
if (stats.isDirectory()) {
|
|
70
|
+
return sourceFilesUnder(path);
|
|
71
|
+
}
|
|
72
|
+
return [path];
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Runs The Thracian codemod fixer across configured paths.
|
|
76
|
+
*
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export const codemodFix = (options = {}) => {
|
|
80
|
+
const cwd = options.cwd ?? process.cwd();
|
|
81
|
+
const paths = (() => {
|
|
82
|
+
if (options.paths && options.paths.length > 0) {
|
|
83
|
+
return options.paths;
|
|
84
|
+
}
|
|
85
|
+
return defaultPaths;
|
|
86
|
+
})();
|
|
87
|
+
const dryRun = options.dryRun ?? false;
|
|
88
|
+
const changedFiles = [];
|
|
89
|
+
let scannedFiles = 0;
|
|
90
|
+
for (const path of paths) {
|
|
91
|
+
scannedFiles += scanPath(cwd, path, dryRun, changedFiles);
|
|
92
|
+
}
|
|
93
|
+
return { changedFiles, scannedFiles };
|
|
94
|
+
};
|
|
95
|
+
const collectChangedFile = (changedFiles, file, dryRun) => {
|
|
96
|
+
if (applyCodemodFixToFile(file, dryRun)) {
|
|
97
|
+
changedFiles.push(file);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const scanPath = (cwd, path, dryRun, changedFiles) => {
|
|
101
|
+
let scannedFiles = 0;
|
|
102
|
+
for (const file of candidateFiles(resolve(cwd, path))) {
|
|
103
|
+
if (hasSourceExtension(file)) {
|
|
104
|
+
scannedFiles += 1;
|
|
105
|
+
collectChangedFile(changedFiles, file, dryRun);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return scannedFiles;
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codemod-fix/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrow-body-style.d.ts","sourceRoot":"","sources":["../../src/codemods/arrow-body-style.ts"],"names":[],"mappings":"AAmJA;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,KAAG,MAazD,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import jscodeshift from 'jscodeshift';
|
|
2
|
+
const MAX_LINE_LENGTH = 150;
|
|
3
|
+
const NOT_FOUND_INDEX = -1;
|
|
4
|
+
const codemodAPI = jscodeshift.withParser('ts');
|
|
5
|
+
const isObjectRecord = (value) => typeof value === 'object' && value !== null;
|
|
6
|
+
const applyReplacements = (source, replacements) => [...replacements]
|
|
7
|
+
.sort((left, right) => right.start - left.start)
|
|
8
|
+
.reduce((current, replacement) => current.slice(0, replacement.start) + replacement.text + current.slice(replacement.end), source);
|
|
9
|
+
const nodeStart = (node) => {
|
|
10
|
+
if (isObjectRecord(node)) {
|
|
11
|
+
const { start } = node;
|
|
12
|
+
if (typeof start === 'number') {
|
|
13
|
+
return start;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
throw new Error('jscodeshift node is missing a start offset');
|
|
17
|
+
};
|
|
18
|
+
const nodeEnd = (node) => {
|
|
19
|
+
if (isObjectRecord(node)) {
|
|
20
|
+
const { end } = node;
|
|
21
|
+
if (typeof end === 'number') {
|
|
22
|
+
return end;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw new Error('jscodeshift node is missing an end offset');
|
|
26
|
+
};
|
|
27
|
+
const sourceForNode = (source, node) => source.slice(nodeStart(node), nodeEnd(node));
|
|
28
|
+
const hasAttachedComments = (node) => Boolean(node.comments?.length ||
|
|
29
|
+
(isObjectRecord(node) &&
|
|
30
|
+
Array.isArray(node.leadingComments) &&
|
|
31
|
+
node.leadingComments.length > 0) ||
|
|
32
|
+
(isObjectRecord(node) &&
|
|
33
|
+
Array.isArray(node.trailingComments) &&
|
|
34
|
+
node.trailingComments.length > 0));
|
|
35
|
+
const expressionNeedsParentheses = (expression) => expression.type === 'ObjectExpression';
|
|
36
|
+
const lineEndAfter = (source, end) => {
|
|
37
|
+
const nextLineBreak = source.indexOf('\n', end);
|
|
38
|
+
if (nextLineBreak === NOT_FOUND_INDEX) {
|
|
39
|
+
return source.length;
|
|
40
|
+
}
|
|
41
|
+
return nextLineBreak;
|
|
42
|
+
};
|
|
43
|
+
const wouldExceedLineLimit = (source, start, end, replacementText) => {
|
|
44
|
+
if (replacementText.includes('\n')) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const lineStart = source.lastIndexOf('\n', start) + 1;
|
|
48
|
+
const lineEnd = lineEndAfter(source, end);
|
|
49
|
+
const line = source.slice(lineStart, start) + replacementText + source.slice(end, lineEnd);
|
|
50
|
+
return line.length > MAX_LINE_LENGTH;
|
|
51
|
+
};
|
|
52
|
+
const replacementTextForExpression = (source, expression) => {
|
|
53
|
+
const expressionText = sourceForNode(source, expression);
|
|
54
|
+
if (expressionNeedsParentheses(expression)) {
|
|
55
|
+
return `(${expressionText})`;
|
|
56
|
+
}
|
|
57
|
+
return expressionText;
|
|
58
|
+
};
|
|
59
|
+
const onlyReturnStatement = (body) => {
|
|
60
|
+
if (body.body.length !== 1) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const [statement] = body.body;
|
|
64
|
+
if (statement?.type === 'ReturnStatement' && statement.argument) {
|
|
65
|
+
return { expression: statement.argument, statement };
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
};
|
|
69
|
+
const replacementForReturnExpression = (source, node, expression) => {
|
|
70
|
+
const text = replacementTextForExpression(source, expression);
|
|
71
|
+
if (wouldExceedLineLimit(source, nodeStart(node.body), nodeEnd(node.body), text)) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
return { end: nodeEnd(node.body), start: nodeStart(node.body), text };
|
|
75
|
+
};
|
|
76
|
+
const replacementForArrow = (source, node) => {
|
|
77
|
+
if (node.body.type !== 'BlockStatement') {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
const result = onlyReturnStatement(node.body);
|
|
81
|
+
if (!result) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
if (hasAttachedComments(result.statement)) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
return replacementForReturnExpression(source, node, result.expression);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Internal helper exported for package-local composition.
|
|
91
|
+
*
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
export const preferConciseArrowBodies = (source) => {
|
|
95
|
+
const replacements = [];
|
|
96
|
+
codemodAPI(source)
|
|
97
|
+
.find(codemodAPI.ArrowFunctionExpression)
|
|
98
|
+
.forEach((path) => {
|
|
99
|
+
const replacement = replacementForArrow(source, path.value);
|
|
100
|
+
if (replacement) {
|
|
101
|
+
replacements.push(replacement);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return applyReplacements(source, replacements);
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=arrow-body-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrow-body-style.js","sourceRoot":"","sources":["../../src/codemods/arrow-body-style.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface JSDocInput {
|
|
2
|
+
summary: string;
|
|
3
|
+
tags?: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Formats a classic multi-line JSDoc block.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare const formatJSDoc: (input: JSDocInput) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Formats a three-line fixed-width section header.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare const formatMainHeader: (text: string) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Formats a one-line fixed-width section header.
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare const formatSubheader: (text: string) => string;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=comment-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-format.d.ts","sourceRoot":"","sources":["../../src/codemods/comment-format.ts"],"names":[],"mappings":"AAIA,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAgFD;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,OAAO,UAAU,KAAG,MAW/C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,KAAG,MAOlC,CAAC;AAEf;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MAM9C,CAAC"}
|