@api-extractor-tools/eslint-plugin 0.1.0-alpha.0 → 0.1.0-alpha.2

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.
Files changed (104) hide show
  1. package/ARCHITECTURE.md +204 -0
  2. package/CHANGELOG.md +32 -0
  3. package/README.md +306 -10
  4. package/api-extractor.json +1 -0
  5. package/dist/configs/recommended.d.ts +1 -1
  6. package/dist/configs/recommended.d.ts.map +1 -1
  7. package/dist/configs/recommended.js +7 -1
  8. package/dist/configs/recommended.js.map +1 -1
  9. package/dist/index.d.ts +9 -16
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +11 -15
  12. package/dist/index.js.map +1 -1
  13. package/dist/node.d.ts +28 -0
  14. package/dist/node.d.ts.map +1 -0
  15. package/dist/node.js +41 -0
  16. package/dist/node.js.map +1 -0
  17. package/dist/rules/extra-release-tag.d.ts +24 -0
  18. package/dist/rules/extra-release-tag.d.ts.map +1 -0
  19. package/dist/rules/extra-release-tag.js +141 -0
  20. package/dist/rules/extra-release-tag.js.map +1 -0
  21. package/dist/rules/forgotten-export.d.ts +24 -0
  22. package/dist/rules/forgotten-export.d.ts.map +1 -0
  23. package/dist/rules/forgotten-export.js +212 -0
  24. package/dist/rules/forgotten-export.js.map +1 -0
  25. package/dist/rules/incompatible-release-tags.d.ts +25 -0
  26. package/dist/rules/incompatible-release-tags.d.ts.map +1 -0
  27. package/dist/rules/incompatible-release-tags.js +237 -0
  28. package/dist/rules/incompatible-release-tags.js.map +1 -0
  29. package/dist/rules/index.d.ts +8 -2
  30. package/dist/rules/index.d.ts.map +1 -1
  31. package/dist/rules/index.js +13 -1
  32. package/dist/rules/index.js.map +1 -1
  33. package/dist/rules/missing-release-tag.d.ts +4 -0
  34. package/dist/rules/missing-release-tag.d.ts.map +1 -1
  35. package/dist/rules/missing-release-tag.js +14 -21
  36. package/dist/rules/missing-release-tag.js.map +1 -1
  37. package/dist/rules/override-keyword.d.ts +4 -0
  38. package/dist/rules/override-keyword.d.ts.map +1 -1
  39. package/dist/rules/override-keyword.js +9 -11
  40. package/dist/rules/override-keyword.js.map +1 -1
  41. package/dist/rules/package-documentation.d.ts +5 -2
  42. package/dist/rules/package-documentation.d.ts.map +1 -1
  43. package/dist/rules/package-documentation.js +45 -35
  44. package/dist/rules/package-documentation.js.map +1 -1
  45. package/dist/rules/public-on-non-exported.d.ts +24 -0
  46. package/dist/rules/public-on-non-exported.d.ts.map +1 -0
  47. package/dist/rules/public-on-non-exported.js +191 -0
  48. package/dist/rules/public-on-non-exported.js.map +1 -0
  49. package/dist/rules/public-on-private-member.d.ts +24 -0
  50. package/dist/rules/public-on-private-member.d.ts.map +1 -0
  51. package/dist/rules/public-on-private-member.js +111 -0
  52. package/dist/rules/public-on-private-member.js.map +1 -0
  53. package/dist/rules/valid-enum-type.d.ts +17 -0
  54. package/dist/rules/valid-enum-type.d.ts.map +1 -0
  55. package/dist/rules/valid-enum-type.js +206 -0
  56. package/dist/rules/valid-enum-type.js.map +1 -0
  57. package/dist/types.d.ts +66 -24
  58. package/dist/types.d.ts.map +1 -1
  59. package/dist/types.js +4 -1
  60. package/dist/types.js.map +1 -1
  61. package/dist/utils/tsdoc-parser.d.ts +37 -6
  62. package/dist/utils/tsdoc-parser.d.ts.map +1 -1
  63. package/dist/utils/tsdoc-parser.js +40 -0
  64. package/dist/utils/tsdoc-parser.js.map +1 -1
  65. package/docs/rules/valid-enum-type.md +153 -0
  66. package/package.json +22 -8
  67. package/src/configs/recommended.ts +7 -1
  68. package/src/index.ts +21 -15
  69. package/src/node.ts +50 -0
  70. package/src/rules/extra-release-tag.ts +201 -0
  71. package/src/rules/forgotten-export.ts +274 -0
  72. package/src/rules/incompatible-release-tags.ts +331 -0
  73. package/src/rules/index.ts +13 -1
  74. package/src/rules/missing-release-tag.ts +11 -26
  75. package/src/rules/override-keyword.ts +6 -8
  76. package/src/rules/package-documentation.ts +54 -40
  77. package/src/rules/public-on-non-exported.ts +265 -0
  78. package/src/rules/public-on-private-member.ts +157 -0
  79. package/src/rules/valid-enum-type.ts +252 -0
  80. package/src/types.ts +60 -17
  81. package/src/utils/config-loader.ts +1 -0
  82. package/src/utils/entry-point.ts +1 -0
  83. package/src/utils/tsdoc-parser.ts +67 -0
  84. package/temp/eslint-plugin.api.md +101 -32
  85. package/test/index.test.ts +1 -0
  86. package/test/rules/extra-release-tag.test.ts +276 -0
  87. package/test/rules/forgotten-export.test.ts +190 -0
  88. package/test/rules/incompatible-release-tags.test.ts +340 -0
  89. package/test/rules/missing-release-tag.test.ts +2 -1
  90. package/test/rules/override-keyword.test.ts +2 -1
  91. package/test/rules/package-documentation.test.ts +113 -64
  92. package/test/rules/public-on-non-exported.test.ts +201 -0
  93. package/test/rules/public-on-private-member.test.ts +207 -0
  94. package/test/rules/valid-enum-type.test.ts +409 -0
  95. package/test/types.test-d.ts +20 -0
  96. package/test/utils/config-loader.test.ts +1 -0
  97. package/test/utils/tsdoc-parser.test.ts +117 -9
  98. package/tsconfig.json +1 -0
  99. package/vitest.config.mts +1 -0
  100. package/dist/utils/index.d.ts +0 -8
  101. package/dist/utils/index.d.ts.map +0 -1
  102. package/dist/utils/index.js +0 -21
  103. package/dist/utils/index.js.map +0 -1
  104. package/src/utils/index.ts +0 -17
@@ -0,0 +1,204 @@
1
+ # ESLint Plugin Architecture
2
+
3
+ This document describes the architecture of `@api-extractor-tools/eslint-plugin`.
4
+
5
+ ## Design Principles
6
+
7
+ ### Isomorphic Core
8
+
9
+ The plugin is designed to work in both Node.js and browser environments. While the core functionality aims to be environment-agnostic, the current implementation uses `@typescript-eslint/utils` which has transitive Node.js dependencies. Browser usage requires polyfills (see usage examples).
10
+
11
+ ### Explicit Configuration
12
+
13
+ Rules accept configuration explicitly via options rather than automatically discovering configuration files. This makes the rules predictable, testable, and environment-agnostic.
14
+
15
+ ### Optional Node.js Enhancements
16
+
17
+ Node.js-specific functionality (reading files from disk, discovering configuration) is provided as a separate entry point. This is purely a convenience layer - users can always provide equivalent configuration explicitly.
18
+
19
+ ## Package Structure
20
+
21
+ ```text
22
+ src/
23
+ ├── index.ts # Main entry point (isomorphic)
24
+ ├── node.ts # Node.js utilities entry point
25
+ ├── types.ts # TypeScript types (isomorphic)
26
+ ├── rules/
27
+ │ ├── index.ts # Rule exports
28
+ │ ├── missing-release-tag.ts
29
+ │ ├── override-keyword.ts
30
+ │ └── package-documentation.ts
31
+ ├── configs/
32
+ │ ├── index.ts # Config exports
33
+ │ └── recommended.ts # Recommended ruleset
34
+ └── utils/
35
+ ├── tsdoc-parser.ts # TSDoc parsing (isomorphic)
36
+ ├── config-loader.ts # Config file loading (Node.js only)
37
+ └── entry-point.ts # Entry point detection (Node.js only)
38
+ ```
39
+
40
+ ## Entry Points
41
+
42
+ ### Main Entry Point (`.`)
43
+
44
+ ```ts
45
+ import plugin from '@api-extractor-tools/eslint-plugin'
46
+ ```
47
+
48
+ Exports:
49
+
50
+ - `default` - The ESLint plugin object with `rules` and `configs`
51
+ - `rules` - All ESLint rules
52
+ - `recommendedRules` - Recommended rule configuration
53
+ - Types - `ApiExtractorConfig`, `ReleaseTag`, rule option types, etc.
54
+ - TSDoc utilities - `parseTSDocComment`, `extractReleaseTag`, etc.
55
+
56
+ This entry point can be used in browser environments with appropriate polyfills for `@typescript-eslint/utils` dependencies.
57
+
58
+ ### Node.js Entry Point (`./node`)
59
+
60
+ ```ts
61
+ import {
62
+ findApiExtractorConfig,
63
+ loadApiExtractorConfig,
64
+ } from '@api-extractor-tools/eslint-plugin/node'
65
+ ```
66
+
67
+ Exports:
68
+
69
+ - `findApiExtractorConfig(startDir)` - Discovers api-extractor.json by searching upward
70
+ - `loadApiExtractorConfig(path)` - Loads and parses an api-extractor.json file
71
+ - `resolveConfig(filePath, configPath?)` - Resolves config for a file
72
+ - `getMessageLogLevel(config, messageId)` - Gets log level for a message
73
+ - `findPackageJson(startDir)` - Discovers package.json by searching upward
74
+ - `isEntryPoint(filePath, pkgPath)` - Checks if a file is a package entry point
75
+
76
+ This entry point requires Node.js (`fs`, `path` modules).
77
+
78
+ ## Rules
79
+
80
+ ### missing-release-tag
81
+
82
+ Requires exported symbols to have a release tag (`@public`, `@beta`, `@alpha`, or `@internal`).
83
+
84
+ **Options:**
85
+
86
+ ```ts
87
+ interface MissingReleaseTagRuleOptions {
88
+ severity?: 'error' | 'warning' | 'none' // default: 'warning'
89
+ }
90
+ ```
91
+
92
+ ### override-keyword
93
+
94
+ Requires the TypeScript `override` keyword when the `@override` TSDoc tag is present.
95
+
96
+ **Options:** None (purely syntactic)
97
+
98
+ ### package-documentation
99
+
100
+ Enforces correct usage of the `@packageDocumentation` tag based on whether a file is a package entry point (barrel file). The rule automatically detects entry points by examining the nearest `package.json`.
101
+
102
+ - **Barrel files** (entry points): Requires `@packageDocumentation` tag to be present.
103
+ - **Non-barrel files**: Reports an error if `@packageDocumentation` tag is found.
104
+
105
+ **Options:** None
106
+
107
+ Note: This rule uses `findPackageJson` and `isEntryPoint` from the entry-point utilities to determine barrel file status. If no `package.json` is found, the rule is skipped.
108
+
109
+ ## Usage Examples
110
+
111
+ ### Browser Environment (ESLint 9 Flat Config)
112
+
113
+ ```js
114
+ import { Linter } from 'eslint-linter-browserify'
115
+ import * as tsParser from '@typescript-eslint/parser'
116
+ import { rules } from '@api-extractor-tools/eslint-plugin'
117
+
118
+ const linter = new Linter()
119
+
120
+ // Lint code using ESLint 9 flat config style
121
+ const messages = linter.verify(
122
+ code,
123
+ {
124
+ files: ['**/*.ts', '**/*.d.ts'],
125
+ plugins: {
126
+ '@api-extractor-tools': { rules },
127
+ },
128
+ languageOptions: {
129
+ parser: tsParser,
130
+ parserOptions: {
131
+ ecmaVersion: 'latest',
132
+ sourceType: 'module',
133
+ },
134
+ },
135
+ rules: {
136
+ '@api-extractor-tools/missing-release-tag': [
137
+ 'warn',
138
+ { severity: 'warning' },
139
+ ],
140
+ '@api-extractor-tools/override-keyword': 'error',
141
+ },
142
+ },
143
+ { filename: 'file.d.ts' },
144
+ )
145
+ ```
146
+
147
+ **Note:** When using in a browser, you'll need to polyfill or stub Node.js modules that `@typescript-eslint/parser` depends on (e.g., `fs`, `path`, `process`). See the demo-site for a working example using Vite aliases.
148
+
149
+ ### Node.js with ESLint Flat Config
150
+
151
+ ```js
152
+ // eslint.config.js
153
+ import apiExtractorPlugin from '@api-extractor-tools/eslint-plugin'
154
+
155
+ export default [apiExtractorPlugin.configs.recommended]
156
+ ```
157
+
158
+ ### Node.js with Config Discovery
159
+
160
+ ```js
161
+ // eslint.config.js
162
+ import apiExtractorPlugin from '@api-extractor-tools/eslint-plugin'
163
+ import {
164
+ findApiExtractorConfig,
165
+ loadApiExtractorConfig,
166
+ getMessageLogLevel,
167
+ } from '@api-extractor-tools/eslint-plugin/node'
168
+
169
+ // Discover and load api-extractor.json
170
+ const configPath = findApiExtractorConfig(process.cwd())
171
+ const config = configPath ? loadApiExtractorConfig(configPath) : null
172
+
173
+ // Get severity from config (or use default)
174
+ const severity = config
175
+ ? getMessageLogLevel(config, 'ae-missing-release-tag')
176
+ : 'warning'
177
+
178
+ export default [
179
+ {
180
+ plugins: { '@api-extractor-tools': apiExtractorPlugin },
181
+ rules: {
182
+ '@api-extractor-tools/missing-release-tag': ['warn', { severity }],
183
+ '@api-extractor-tools/override-keyword': 'error',
184
+ },
185
+ },
186
+ ]
187
+ ```
188
+
189
+ ## Dependencies
190
+
191
+ ### Runtime Dependencies
192
+
193
+ - `@microsoft/tsdoc` - TSDoc comment parsing (browser-compatible)
194
+
195
+ ### Dev Dependencies
196
+
197
+ - `@typescript-eslint/utils` - ESLint rule utilities and TypeScript AST types
198
+ - `@typescript-eslint/rule-tester` - Testing harness for ESLint rules
199
+ - `@typescript-eslint/parser` - TypeScript parser for ESLint (used in tests)
200
+
201
+ ### Peer Dependencies
202
+
203
+ - `eslint` >= 8.0.0
204
+ - `typescript` >= 5.5.0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @api-extractor-tools/eslint-plugin
2
2
 
3
+ ## 0.1.0-alpha.2
4
+
5
+ ### Minor Changes
6
+
7
+ - [#204](https://github.com/mike-north/api-extractor-tools/pull/204) [`3accc97`](https://github.com/mike-north/api-extractor-tools/commit/3accc97733d1b21eb7bbbe82b122a347e9b5ea76) Thanks [@mike-north](https://github.com/mike-north)! - fix: enforce @packageDocumentation only on package barrel files
8
+
9
+ The `package-documentation` rule now automatically detects whether a file is a package entry point by examining the nearest `package.json`. Barrel files are required to have the `@packageDocumentation` tag, and non-barrel files report an error if the tag is present. Previously the rule required the tag on every file regardless of whether it was an entry point.
10
+
11
+ ## 0.1.0-alpha.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [#182](https://github.com/mike-north/api-extractor-tools/pull/182) [`d77d4d1`](https://github.com/mike-north/api-extractor-tools/commit/d77d4d1657641e16dc98736b88ece121c3d27563) Thanks [@mike-north](https://github.com/mike-north)! - Integrate declaration-file-normalizer into build pipelines and add comprehensive test coverage.
16
+
17
+ **Test Coverage Improvements:**
18
+ - Added comprehensive test suite for declaration-file-normalizer (64 tests total)
19
+ - Improved coverage from 8.39% to 67.97%
20
+ - Coverage breakdown:
21
+ - index.ts: 96.77% statements, 92.3% branch coverage
22
+ - normalizer.ts: 100% coverage
23
+ - parser.ts: 86.56% statements, 66.66% branch coverage
24
+ - writer.ts: 90.9% statements, 66.66% branch coverage
25
+ - Added test suites for parser, writer, index orchestration, and CLI
26
+
27
+ **Build Pipeline Integration:**
28
+ - Integrated declaration-file-normalizer into build pipeline for all packages using API Extractor
29
+ - Build flow is now: `tsc → declaration-file-normalizer → api-extractor`
30
+ - This ensures stable union/intersection type ordering in API reports across builds
31
+
32
+ **Configuration:**
33
+ - Fixed vitest.config.mts to properly track index.ts coverage
34
+
3
35
  ## 0.1.0-alpha.0
4
36
 
5
37
  ### Minor Changes
package/README.md CHANGED
@@ -34,6 +34,12 @@ export default [
34
34
  '@api-extractor-tools/missing-release-tag': 'error',
35
35
  '@api-extractor-tools/override-keyword': 'error',
36
36
  '@api-extractor-tools/package-documentation': 'warn',
37
+ '@api-extractor-tools/forgotten-export': 'warn',
38
+ '@api-extractor-tools/incompatible-release-tags': 'warn',
39
+ '@api-extractor-tools/extra-release-tag': 'error',
40
+ '@api-extractor-tools/public-on-private-member': 'error',
41
+ '@api-extractor-tools/public-on-non-exported': 'error',
42
+ '@api-extractor-tools/valid-enum-type': 'warn',
37
43
  },
38
44
  },
39
45
  ]
@@ -57,6 +63,12 @@ module.exports = {
57
63
  '@api-extractor-tools/missing-release-tag': 'error',
58
64
  '@api-extractor-tools/override-keyword': 'error',
59
65
  '@api-extractor-tools/package-documentation': 'warn',
66
+ '@api-extractor-tools/forgotten-export': 'warn',
67
+ '@api-extractor-tools/incompatible-release-tags': 'warn',
68
+ '@api-extractor-tools/extra-release-tag': 'error',
69
+ '@api-extractor-tools/public-on-private-member': 'error',
70
+ '@api-extractor-tools/public-on-non-exported': 'error',
71
+ '@api-extractor-tools/valid-enum-type': 'warn',
60
72
  },
61
73
  }
62
74
  ```
@@ -144,6 +156,289 @@ export function foo() {}
144
156
  export function foo() {}
145
157
  ```
146
158
 
159
+ ### `@api-extractor-tools/forgotten-export`
160
+
161
+ Requires that types and symbols referenced by exported APIs are also exported from the entry point.
162
+
163
+ This rule mirrors API Extractor's `ae-forgotten-export` message.
164
+
165
+ ```ts
166
+ // ❌ Bad - MyInterface is used but not exported
167
+ interface MyInterface {
168
+ name: string
169
+ }
170
+
171
+ export function myFunction(param: MyInterface): void {}
172
+
173
+ // ✅ Good - MyInterface is exported
174
+ export interface MyInterface {
175
+ name: string
176
+ }
177
+
178
+ export function myFunction(param: MyInterface): void {}
179
+ ```
180
+
181
+ **Options:**
182
+
183
+ - `severity` (optional): Severity level for forgotten exports. Default: `'warning'`
184
+
185
+ ```json
186
+ {
187
+ "@api-extractor-tools/forgotten-export": ["warn", { "severity": "warning" }]
188
+ }
189
+ ```
190
+
191
+ ### `@api-extractor-tools/incompatible-release-tags`
192
+
193
+ Requires that exported APIs do not reference symbols with less visible release tags.
194
+
195
+ This rule mirrors API Extractor's `ae-incompatible-release-tags` message. For example, a `@public` API should not reference an `@internal` type.
196
+
197
+ Release tag visibility hierarchy (from least to most visible):
198
+
199
+ - `@internal` < `@alpha` < `@beta` < `@public`
200
+
201
+ ```ts
202
+ // ❌ Bad - public API using internal type
203
+ /**
204
+ * An internal interface.
205
+ * @internal
206
+ */
207
+ interface MyInterface {
208
+ name: string
209
+ }
210
+
211
+ /**
212
+ * A public function.
213
+ * @public
214
+ */
215
+ export function myFunction(param: MyInterface): void {}
216
+
217
+ // ✅ Good - public API using public type
218
+ /**
219
+ * A public interface.
220
+ * @public
221
+ */
222
+ export interface MyInterface {
223
+ name: string
224
+ }
225
+
226
+ /**
227
+ * A public function.
228
+ * @public
229
+ */
230
+ export function myFunction(param: MyInterface): void {}
231
+ ```
232
+
233
+ **Options:**
234
+
235
+ - `severity` (optional): Severity level for incompatible release tags. Default: `'warning'`
236
+
237
+ ```json
238
+ {
239
+ "@api-extractor-tools/incompatible-release-tags": [
240
+ "error",
241
+ { "severity": "warning" }
242
+ ]
243
+ }
244
+ ```
245
+
246
+ ### `@api-extractor-tools/extra-release-tag`
247
+
248
+ Requires that symbols have at most one release tag.
249
+
250
+ This rule mirrors API Extractor's `ae-extra-release-tag` message. Each symbol should have exactly one release tag (`@public`, `@beta`, `@alpha`, or `@internal`).
251
+
252
+ ```ts
253
+ // ❌ Bad - multiple release tags
254
+ /**
255
+ * A function with multiple tags.
256
+ * @public
257
+ * @beta
258
+ */
259
+ export function myFunction(): void {}
260
+
261
+ // ✅ Good - single release tag
262
+ /**
263
+ * A public function.
264
+ * @public
265
+ */
266
+ export function myFunction(): void {}
267
+ ```
268
+
269
+ **Options:**
270
+
271
+ - `severity` (optional): Severity level for extra release tags. Default: `'error'`
272
+
273
+ ```json
274
+ {
275
+ "@api-extractor-tools/extra-release-tag": ["error", { "severity": "error" }]
276
+ }
277
+ ```
278
+
279
+ ### `@api-extractor-tools/public-on-private-member`
280
+
281
+ Prevents the use of `@public` tag on private or protected class members.
282
+
283
+ Private and protected members cannot be public API since they are not accessible outside the class or to external consumers.
284
+
285
+ ```ts
286
+ // ❌ Bad - @public on private member
287
+ export class MyClass {
288
+ /**
289
+ * A private property.
290
+ * @public
291
+ */
292
+ private myProperty: string = ''
293
+ }
294
+
295
+ // ✅ Good - @internal on private member
296
+ export class MyClass {
297
+ /**
298
+ * A private property.
299
+ * @internal
300
+ */
301
+ private myProperty: string = ''
302
+ }
303
+
304
+ // ✅ Good - @public on public member
305
+ export class MyClass {
306
+ /**
307
+ * A public property.
308
+ * @public
309
+ */
310
+ public myProperty: string = ''
311
+ }
312
+ ```
313
+
314
+ **Options:**
315
+
316
+ - `severity` (optional): Severity level for public tags on private/protected members. Default: `'error'`
317
+
318
+ ```json
319
+ {
320
+ "@api-extractor-tools/public-on-private-member": [
321
+ "error",
322
+ { "severity": "error" }
323
+ ]
324
+ }
325
+ ```
326
+
327
+ ### `@api-extractor-tools/public-on-non-exported`
328
+
329
+ Prevents the use of `@public` tag on symbols that are not exported.
330
+
331
+ The `@public` tag indicates that a symbol is part of the public API, but non-exported symbols cannot be accessed by consumers.
332
+
333
+ ```ts
334
+ // ❌ Bad - @public on non-exported symbol
335
+ /**
336
+ * A function.
337
+ * @public
338
+ */
339
+ function myFunction(): void {}
340
+
341
+ // ✅ Good - @public on exported symbol
342
+ /**
343
+ * A function.
344
+ * @public
345
+ */
346
+ export function myFunction(): void {}
347
+
348
+ // ✅ Good - @internal on non-exported symbol
349
+ /**
350
+ * A function.
351
+ * @internal
352
+ */
353
+ function myFunction(): void {}
354
+
355
+ // ✅ Good - exported separately
356
+ /**
357
+ * A function.
358
+ * @public
359
+ */
360
+ function myFunction(): void {}
361
+
362
+ export { myFunction }
363
+ ```
364
+
365
+ **Options:**
366
+
367
+ - `severity` (optional): Severity level for public tags on non-exported symbols. Default: `'error'`
368
+
369
+ ```json
370
+ {
371
+ "@api-extractor-tools/public-on-non-exported": [
372
+ "error",
373
+ { "severity": "error" }
374
+ ]
375
+ }
376
+ ```
377
+
378
+ ### `@api-extractor-tools/valid-enum-type`
379
+
380
+ Validates the usage of the `@enumType` TSDoc tag on enum declarations and string literal union type aliases.
381
+
382
+ The `@enumType` tag specifies whether an enum is "open" (new members may be added) or "closed" (the set of members is fixed). This is used by the change detector to properly classify API changes.
383
+
384
+ ```ts
385
+ // ❌ Bad - missing value
386
+ /**
387
+ * @enumType
388
+ */
389
+ export enum Status {
390
+ Active,
391
+ Inactive,
392
+ }
393
+
394
+ // ❌ Bad - invalid value
395
+ /**
396
+ * @enumType invalid
397
+ */
398
+ export enum Status {
399
+ Active,
400
+ Inactive,
401
+ }
402
+
403
+ // ❌ Bad - @enumType on invalid construct
404
+ /**
405
+ * @enumType open
406
+ */
407
+ export function myFunction(): void {}
408
+
409
+ // ✅ Good - open enum
410
+ /**
411
+ * Status values for a resource.
412
+ * @enumType open
413
+ * @public
414
+ */
415
+ export enum Status {
416
+ Active = 'active',
417
+ Inactive = 'inactive',
418
+ }
419
+
420
+ // ✅ Good - closed string literal union
421
+ /**
422
+ * Supported formats.
423
+ * @enumType closed
424
+ * @public
425
+ */
426
+ export type Format = 'json' | 'xml'
427
+ ```
428
+
429
+ **Options:**
430
+
431
+ - `requireOnExported` (optional): When `true`, requires all exported enums and string literal unions to have an `@enumType` tag. Default: `false`
432
+
433
+ ```json
434
+ {
435
+ "@api-extractor-tools/valid-enum-type": [
436
+ "warn",
437
+ { "requireOnExported": true }
438
+ ]
439
+ }
440
+ ```
441
+
147
442
  ## Configuration Discovery
148
443
 
149
444
  Rules that read from `api-extractor.json` use the following strategy:
@@ -156,11 +451,17 @@ Rules that read from `api-extractor.json` use the following strategy:
156
451
 
157
452
  The `recommended` configuration enables all rules with these defaults:
158
453
 
159
- | Rule | Severity |
160
- | ----------------------- | -------- |
161
- | `missing-release-tag` | warn |
162
- | `override-keyword` | error |
163
- | `package-documentation` | warn |
454
+ | Rule | Severity |
455
+ | --------------------------- | -------- |
456
+ | `missing-release-tag` | warn |
457
+ | `override-keyword` | error |
458
+ | `package-documentation` | warn |
459
+ | `forgotten-export` | warn |
460
+ | `incompatible-release-tags` | warn |
461
+ | `extra-release-tag` | error |
462
+ | `public-on-private-member` | error |
463
+ | `public-on-non-exported` | error |
464
+ | `valid-enum-type` | warn |
164
465
 
165
466
  ## Requirements
166
467
 
@@ -176,8 +477,3 @@ The `recommended` configuration enables all rules with these defaults:
176
477
  ## License
177
478
 
178
479
  MIT
179
-
180
-
181
-
182
-
183
-
@@ -8,3 +8,4 @@
8
8
  "tsconfigFilePath": "<projectFolder>/tsconfig.json"
9
9
  }
10
10
  }
11
+
@@ -11,7 +11,7 @@ import type { TSESLint } from '@typescript-eslint/utils';
11
11
  /**
12
12
  * Recommended rule configuration.
13
13
  * These are the rules enabled by default with appropriate severity.
14
- * @public
14
+ * @alpha
15
15
  */
16
16
  export declare const recommendedRules: TSESLint.Linter.RulesRecord;
17
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAExD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAI9C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,QAAQ,CAAC,UAAU,CAAC,MAAM,CAO5B"}
1
+ {"version":3,"file":"recommended.d.ts","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAExD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAU9C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,QAAQ,CAAC,UAAU,CAAC,MAAM,CAO5B"}
@@ -14,12 +14,18 @@ exports.createFlatRecommendedConfig = createFlatRecommendedConfig;
14
14
  /**
15
15
  * Recommended rule configuration.
16
16
  * These are the rules enabled by default with appropriate severity.
17
- * @public
17
+ * @alpha
18
18
  */
19
19
  exports.recommendedRules = {
20
20
  '@api-extractor-tools/missing-release-tag': 'warn',
21
21
  '@api-extractor-tools/override-keyword': 'error',
22
22
  '@api-extractor-tools/package-documentation': 'warn',
23
+ '@api-extractor-tools/forgotten-export': 'warn',
24
+ '@api-extractor-tools/incompatible-release-tags': 'warn',
25
+ '@api-extractor-tools/extra-release-tag': 'error',
26
+ '@api-extractor-tools/public-on-private-member': 'error',
27
+ '@api-extractor-tools/public-on-non-exported': 'error',
28
+ '@api-extractor-tools/valid-enum-type': 'warn',
23
29
  };
24
30
  /**
25
31
  * Flat-config recommended configuration.
@@ -1 +1 @@
1
- {"version":3,"file":"recommended.js","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AA4BH,kEASC;AAjCD;;;;GAIG;AACU,QAAA,gBAAgB,GAAgC;IAC3D,0CAA0C,EAAE,MAAM;IAClD,uCAAuC,EAAE,OAAO;IAChD,4CAA4C,EAAE,MAAM;CACrD,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,2BAA2B,CACzC,MAA+B;IAE/B,OAAO;QACL,OAAO,EAAE;YACP,sBAAsB,EAAE,MAAoC;SAC7D;QACD,KAAK,EAAE,wBAAgB;KACxB,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"recommended.js","sourceRoot":"","sources":["../../src/configs/recommended.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAkCH,kEASC;AAvCD;;;;GAIG;AACU,QAAA,gBAAgB,GAAgC;IAC3D,0CAA0C,EAAE,MAAM;IAClD,uCAAuC,EAAE,OAAO;IAChD,4CAA4C,EAAE,MAAM;IACpD,uCAAuC,EAAE,MAAM;IAC/C,gDAAgD,EAAE,MAAM;IACxD,wCAAwC,EAAE,OAAO;IACjD,+CAA+C,EAAE,OAAO;IACxD,6CAA6C,EAAE,OAAO;IACtD,sCAAsC,EAAE,MAAM;CAC/C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,2BAA2B,CACzC,MAA+B;IAE/B,OAAO;QACL,OAAO,EAAE;YACP,sBAAsB,EAAE,MAAoC;SAC7D;QACD,KAAK,EAAE,wBAAgB;KACxB,CAAA;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,6 @@
1
1
  /**
2
2
  * ESLint plugin providing authoring-time feedback for API Extractor.
3
3
  *
4
- * @remarks
5
- * This plugin provides ESLint rules that mirror API Extractor's validations,
6
- * enabling developers to catch issues during development rather than at build time.
7
- *
8
4
  * @example
9
5
  * Using with flat config (eslint.config.js):
10
6
  * ```js
@@ -12,15 +8,6 @@
12
8
  *
13
9
  * export default [
14
10
  * apiExtractorPlugin.configs.recommended,
15
- * // Or configure rules individually:
16
- * {
17
- * plugins: {
18
- * '@api-extractor-tools': apiExtractorPlugin,
19
- * },
20
- * rules: {
21
- * '@api-extractor-tools/missing-release-tag': 'error',
22
- * },
23
- * },
24
11
  * ];
25
12
  * ```
26
13
  *
@@ -38,8 +25,14 @@
38
25
  import type { TSESLint } from '@typescript-eslint/utils';
39
26
  import { rules } from './rules';
40
27
  import { recommendedRules } from './configs';
41
- export type { ApiExtractorConfig, ApiExtractorLogLevel, ApiExtractorMessagesConfig, MessageConfig, ReleaseTag, MissingReleaseTagRuleOptions, OverrideKeywordRuleOptions, PackageDocumentationRuleOptions, ResolvedEntryPoints, } from './types';
28
+ export type { ApiExtractorConfig, ApiExtractorLogLevel, ApiExtractorMessagesConfig, MessageConfig, ReleaseTag, MissingReleaseTagRuleOptions, OverrideKeywordRuleOptions, PackageDocumentationRuleOptions, ResolvedEntryPoints, ValidEnumTypeRuleOptions, } from './types';
29
+ export type { ForgottenExportRuleOptions } from './rules/forgotten-export';
30
+ export type { IncompatibleReleaseTagsRuleOptions } from './rules/incompatible-release-tags';
31
+ export type { ExtraReleaseTagRuleOptions } from './rules/extra-release-tag';
32
+ export type { PublicOnPrivateMemberRuleOptions } from './rules/public-on-private-member';
33
+ export type { PublicOnNonExportedRuleOptions } from './rules/public-on-non-exported';
42
34
  export { RELEASE_TAGS } from './types';
35
+ export { parseTSDocComment, extractReleaseTag, hasOverrideTag, hasPackageDocumentation, getLeadingTSDocComment, findAllTSDocComments, extractEnumType, type EnumTypeValue, type EnumTypeExtraction, } from './utils/tsdoc-parser';
43
36
  /**
44
37
  * Plugin configuration type.
45
38
  * @internal
@@ -53,7 +46,7 @@ interface PluginConfigs {
53
46
  }
54
47
  /**
55
48
  * The ESLint plugin type.
56
- * @public
49
+ * @alpha
57
50
  */
58
51
  export interface ApiExtractorEslintPlugin {
59
52
  meta: {
@@ -65,7 +58,7 @@ export interface ApiExtractorEslintPlugin {
65
58
  }
66
59
  /**
67
60
  * The ESLint plugin object.
68
- * @public
61
+ * @alpha
69
62
  */
70
63
  declare const plugin: ApiExtractorEslintPlugin;
71
64
  export default plugin;