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 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 all rules (`type-ordering`, `no-loops`, `no-named-arrow-functions`) as errors
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-beta.1",
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": "^5.0.0",
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'