eslint-plugin-yenz 2.2.0-beta.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/lib/rules/export-at-end-of-file.js +44 -1
- package/package.json +2 -2
- package/test/fixtures.ts +6 -0
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ class Foo { bar = () => {} }
|
|
|
124
124
|
## Preset Configurations
|
|
125
125
|
|
|
126
126
|
- `**recommended**` - Enables `type-ordering` as error and `no-loops` as warning
|
|
127
|
-
- `**all**` - Enables
|
|
127
|
+
- `**all**` - Enables `type-ordering`, `no-loops`, and `no-named-arrow-functions` as errors
|
|
128
128
|
|
|
129
129
|
# Release Procedure
|
|
130
130
|
|
|
@@ -134,14 +134,17 @@ class Foo { bar = () => {} }
|
|
|
134
134
|
4. Add code samples in `test/` that intentionally fail your new or updated rules to confirm they are caught.
|
|
135
135
|
5. Commit and push your changes, then open a PR.
|
|
136
136
|
6. **Bump to a pre-release version and publish a beta:**
|
|
137
|
+
|
|
137
138
|
```bash
|
|
138
139
|
yarn version --pre[major|minor|patch] --preid beta
|
|
139
140
|
npm publish --tag beta # or alpha, rc
|
|
140
141
|
```
|
|
142
|
+
|
|
141
143
|
Users can test it with:
|
|
142
144
|
7. After review, **merge your branch into `main`**.
|
|
143
145
|
8. Open a version bump PR against `main` and merge it in.
|
|
144
146
|
9. **Publish the stable release** from `main`:
|
|
147
|
+
|
|
145
148
|
```bash
|
|
146
149
|
yarn version --[major|minor|patch]
|
|
147
150
|
npm publish
|
|
@@ -149,6 +149,49 @@ function formatMergedSpecifierExport(items) {
|
|
|
149
149
|
.join(', ')} }`;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Returns a location that covers only the exported header (for example
|
|
154
|
+
* `export function foo()` through the closing `)`), not the whole declaration
|
|
155
|
+
* body, so editors underline the signature instead of the entire block.
|
|
156
|
+
*
|
|
157
|
+
* @param {object} exportNamedNode - Inline `ExportNamedDeclaration`.
|
|
158
|
+
* @param {import('eslint').SourceCode} sourceCode
|
|
159
|
+
* @returns {object} ESLint `SourceLocation` (`start` / `end` in line/column).
|
|
160
|
+
*/
|
|
161
|
+
function getInlineExportReportLoc(exportNamedNode, sourceCode) {
|
|
162
|
+
const declaration = exportNamedNode.declaration;
|
|
163
|
+
const { start } = exportNamedNode.loc;
|
|
164
|
+
|
|
165
|
+
const endsBeforeBraceBody =
|
|
166
|
+
(declaration.type === 'FunctionDeclaration'
|
|
167
|
+
|| declaration.type === 'ClassDeclaration'
|
|
168
|
+
|| declaration.type === 'TSInterfaceDeclaration')
|
|
169
|
+
&& declaration.body;
|
|
170
|
+
|
|
171
|
+
if (endsBeforeBraceBody) {
|
|
172
|
+
const bodyOpenIndex = declaration.body.range[0];
|
|
173
|
+
return {
|
|
174
|
+
start,
|
|
175
|
+
end: sourceCode.getLocFromIndex(bodyOpenIndex),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (declaration.type === 'TSTypeAliasDeclaration') {
|
|
180
|
+
const anchor = declaration.typeParameters ?? declaration.id;
|
|
181
|
+
const equalsToken = sourceCode.getTokenAfter(anchor, {
|
|
182
|
+
filter: (token) => token.type === 'Punctuator' && token.value === '=',
|
|
183
|
+
});
|
|
184
|
+
if (equalsToken) {
|
|
185
|
+
return {
|
|
186
|
+
start,
|
|
187
|
+
end: sourceCode.getLocFromIndex(equalsToken.range[0]),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return exportNamedNode.loc;
|
|
193
|
+
}
|
|
194
|
+
|
|
152
195
|
const exportAtEndOfFileRule = {
|
|
153
196
|
meta: {
|
|
154
197
|
type: 'suggestion',
|
|
@@ -180,7 +223,7 @@ const exportAtEndOfFileRule = {
|
|
|
180
223
|
|
|
181
224
|
violations.forEach((node) => {
|
|
182
225
|
context.report({
|
|
183
|
-
node,
|
|
226
|
+
loc: getInlineExportReportLoc(node, sourceCode),
|
|
184
227
|
message:
|
|
185
228
|
'Declare this without inline export and list it in a single export statement at the end of the file.',
|
|
186
229
|
...(node === lastViolation
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-yenz",
|
|
3
|
-
"version": "2.2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Adds custom rules that Jens likes",
|
|
5
5
|
"repository": "https://github.com/JensAstrup/eslint-plugin-yenz",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"license": "ISC",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"eslint": "^10.0.1",
|
|
24
|
-
"typescript": "^
|
|
24
|
+
"typescript": "^6.0.3",
|
|
25
25
|
"typescript-eslint": "^8.0.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
package/test/fixtures.ts
CHANGED
|
@@ -47,3 +47,9 @@ export class ExportClass { method() { return 1; } } // expect-error yenz/export-
|
|
|
47
47
|
export type FixtureExportType = 1 // expect-error yenz/export-at-end-of-file // fix: type FixtureExportType = 1
|
|
48
48
|
|
|
49
49
|
export interface FixtureExportIface { n: number } // expect-error yenz/export-at-end-of-file // fix: interface FixtureExportIface { n: number }
|
|
50
|
+
|
|
51
|
+
// Should pass (export-at-end-of-file — specifier exports and non-exported decls only):
|
|
52
|
+
function notExported() {}
|
|
53
|
+
function someExisting() {}
|
|
54
|
+
export { someExisting }
|
|
55
|
+
export { foo } from './other'
|