Skip to content

Commit ff4a55c

Browse files
authored
feat(typescript): allow function to supply TS-aware rules (#1485)
1 parent 23c9791 commit ff4a55c

File tree

12 files changed

+904
-5
lines changed

12 files changed

+904
-5
lines changed

.README/README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,24 @@ export default [
4141
];
4242
```
4343

44-
Or with settings supplied:
44+
Or with TypeScript-aware extra rules and settings supplied:
4545

4646
```js
4747
import {jsdoc} from 'eslint-plugin-jsdoc';
4848

4949
export default [
5050
jsdoc({
5151
config: 'flat/recommended',
52+
rules: {
53+
'jsdoc/check-values': [
54+
'error',
55+
{
56+
allowedLicenses: [
57+
'MIT', 'ISC',
58+
],
59+
},
60+
],
61+
},
5262
// Uncomment this if you wish your `settings` to overwrite the config's own settings;
5363
// otherwise, the default behavior is to merge recursively
5464
// mergeSettings: false,

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,24 @@ export default [
6060
];
6161
```
6262

63-
Or with settings supplied:
63+
Or with TypeScript-aware extra rules and settings supplied:
6464

6565
```js
6666
import {jsdoc} from 'eslint-plugin-jsdoc';
6767

6868
export default [
6969
jsdoc({
7070
config: 'flat/recommended',
71+
rules: {
72+
'jsdoc/check-values': [
73+
'error',
74+
{
75+
allowedLicenses: [
76+
'MIT', 'ISC',
77+
],
78+
},
79+
],
80+
},
7181
// Uncomment this if you wish your `settings` to overwrite the config's own settings;
7282
// otherwise, the default behavior is to merge recursively
7383
// mergeSettings: false,

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"husky": "^9.1.7",
5959
"jsdoc-type-pratt-parser": "^5.1.1",
6060
"json-schema": "^0.4.0",
61+
"json-schema-to-typescript": "^15.0.4",
6162
"lint-staged": "^16.1.6",
6263
"mocha": "^11.7.2",
6364
"open-editor": "^5.1.0",
@@ -141,6 +142,7 @@
141142
"package-lock.json": "pnpm run install-offline"
142143
},
143144
"scripts": {
145+
"ruleTypes": "node ./src/bin/generateRuleTypes.js",
144146
"tsc": "tsc",
145147
"tsc-build": "tsc -p tsconfig-prod.json",
146148
"build": "node ./src/bin/buildEntryFileForTS.js && rimraf ./dist && NODE_ENV=production babel ./src --out-file-extension .cjs --out-dir ./dist --copy-files --source-maps --ignore ./src/bin/*.js --no-copy-ignored && replace 'require\\(\"\\.(.*?)\\.[^.]*?\"\\)' 'require(\".$1.cjs\")' 'dist' -r --include=\"*.cjs\" && pnpm tsc-build",

pnpm-lock.yaml

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/generateRuleTypes.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import index from '../index.js';
2+
import {
3+
compile,
4+
} from 'json-schema-to-typescript';
5+
import {
6+
writeFile,
7+
} from 'node:fs/promises';
8+
9+
let str = 'export interface Rules {\n';
10+
11+
for (const [
12+
ruleName,
13+
rule,
14+
] of Object.entries(index.rules)) {
15+
if (rule.meta?.schema?.[0]) {
16+
str += ` "jsdoc/${ruleName}": `;
17+
const ts = await compile({
18+
items: rule.meta.schema,
19+
type: 'array',
20+
}, 'Test', {
21+
bannerComment: '',
22+
});
23+
24+
str += ts
25+
.replace(/^export type Test = ?/v, '')
26+
.replace(/^export interface Test /v, '')
27+
.replaceAll('\n', '\n ').trimEnd().replace(/;$/v, '') +
28+
';\n\n';
29+
}
30+
}
31+
32+
str = str.replace(/\n$/v, '') + '}\n';
33+
34+
await writeFile(import.meta.dirname + '/../rules.d.ts', str);
35+
36+
// eslint-disable-next-line no-console -- Todo
37+
console.log('str', str);

src/index-esm.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ export default index;
1616
* cfg?: {
1717
* mergeSettings?: boolean,
1818
* config?: `flat/${import('./index-cjs.js').ConfigGroups}${import('./index-cjs.js').ConfigVariants}${import('./index-cjs.js').ErrorLevelVariants}`,
19-
* settings?: Partial<import('./iterateJsdoc.js').Settings>
19+
* settings?: Partial<import('./iterateJsdoc.js').Settings>,
20+
* rules?: {[key in keyof import('./rules.d.ts').Rules]?: ["error"|"warn"|"off", ...import('./rules.d.ts').Rules[key]]}
2021
* }
2122
* ) => import('eslint').Linter.Config)}
2223
*/
@@ -39,6 +40,10 @@ export const jsdoc = function (cfg) {
3940
outputConfig = index.configs[cfg.config];
4041
}
4142

43+
if (cfg?.rules) {
44+
outputConfig.rules = cfg.rules;
45+
}
46+
4247
outputConfig.settings = {
4348
jsdoc: cfg?.mergeSettings === false ?
4449
cfg.settings :

src/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,8 @@ export default index;
539539
* cfg?: {
540540
* mergeSettings?: boolean,
541541
* config?: `flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`,
542-
* settings?: Partial<import('./iterateJsdoc.js').Settings>
542+
* settings?: Partial<import('./iterateJsdoc.js').Settings>,
543+
* rules?: {[key in keyof import('./rules.d.ts').Rules]?: ["error"|"warn"|"off", ...import('./rules.d.ts').Rules[key]]}
543544
* }
544545
* ) => import('eslint').Linter.Config)}
545546
*/
@@ -562,6 +563,10 @@ export const jsdoc = function (cfg) {
562563
outputConfig = index.configs[cfg.config];
563564
}
564565

566+
if (cfg?.rules) {
567+
outputConfig.rules = cfg.rules;
568+
}
569+
565570
outputConfig.settings = {
566571
jsdoc: cfg?.mergeSettings === false ?
567572
cfg.settings :

src/jsdocUtils.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ const getTagNamesForMode = (mode, context) => {
529529
case 'permissive':
530530
return closureTags;
531531
case 'jsdoc':
532-
return jsdocTags; case 'typescript':
532+
return jsdocTags;
533+
case 'typescript':
533534
return typeScriptTags;
534535
default:
535536
if (!modeWarnSettings.hasBeenWarned(context, 'mode')) {

0 commit comments

Comments
 (0)