194 lines
6.2 KiB
JavaScript
194 lines
6.2 KiB
JavaScript
|
|
"use strict";
|
|||
|
|
|
|||
|
|
Object.defineProperty(exports, "__esModule", {
|
|||
|
|
value: true
|
|||
|
|
});
|
|||
|
|
exports.default = void 0;
|
|||
|
|
var _iterateJsdoc = _interopRequireDefault(require("../iterateJsdoc.cjs"));
|
|||
|
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|||
|
|
const defaultTags = {
|
|||
|
|
file: {
|
|||
|
|
initialCommentsOnly: true,
|
|||
|
|
mustExist: true,
|
|||
|
|
preventDuplicates: true
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @param {import('../iterateJsdoc.js').StateObject} state
|
|||
|
|
* @returns {void}
|
|||
|
|
*/
|
|||
|
|
const setDefaults = state => {
|
|||
|
|
// First iteration
|
|||
|
|
if (!state.globalTags) {
|
|||
|
|
state.globalTags = true;
|
|||
|
|
state.hasDuplicates = {};
|
|||
|
|
state.hasTag = {};
|
|||
|
|
state.hasNonCommentBeforeTag = {};
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
var _default = exports.default = (0, _iterateJsdoc.default)(({
|
|||
|
|
context,
|
|||
|
|
jsdocNode,
|
|||
|
|
state,
|
|||
|
|
utils
|
|||
|
|
}) => {
|
|||
|
|
const {
|
|||
|
|
tags = defaultTags
|
|||
|
|
} = context.options[0] || {};
|
|||
|
|
setDefaults(state);
|
|||
|
|
for (const tagName of Object.keys(tags)) {
|
|||
|
|
const targetTagName = /** @type {string} */utils.getPreferredTagName({
|
|||
|
|
tagName
|
|||
|
|
});
|
|||
|
|
const hasTag = Boolean(targetTagName && utils.hasTag(targetTagName));
|
|||
|
|
state.hasTag[tagName] = hasTag || state.hasTag[tagName];
|
|||
|
|
const hasDuplicate = state.hasDuplicates[tagName];
|
|||
|
|
if (hasDuplicate === false) {
|
|||
|
|
// Was marked before, so if a tag now, is a dupe
|
|||
|
|
state.hasDuplicates[tagName] = hasTag;
|
|||
|
|
} else if (!hasDuplicate && hasTag) {
|
|||
|
|
// No dupes set before, but has first tag, so change state
|
|||
|
|
// from `undefined` to `false` so can detect next time
|
|||
|
|
state.hasDuplicates[tagName] = false;
|
|||
|
|
state.hasNonCommentBeforeTag[tagName] = state.hasNonComment && state.hasNonComment < jsdocNode.range[0];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}, {
|
|||
|
|
exit({
|
|||
|
|
context,
|
|||
|
|
state,
|
|||
|
|
utils
|
|||
|
|
}) {
|
|||
|
|
setDefaults(state);
|
|||
|
|
const {
|
|||
|
|
tags = defaultTags
|
|||
|
|
} = context.options[0] || {};
|
|||
|
|
for (const [tagName, {
|
|||
|
|
initialCommentsOnly = false,
|
|||
|
|
mustExist = false,
|
|||
|
|
preventDuplicates = false
|
|||
|
|
}] of Object.entries(tags)) {
|
|||
|
|
const obj = utils.getPreferredTagNameObject({
|
|||
|
|
tagName
|
|||
|
|
});
|
|||
|
|
if (obj && typeof obj === 'object' && 'blocked' in obj) {
|
|||
|
|
utils.reportSettings(`\`settings.jsdoc.tagNamePreference\` cannot block @${obj.tagName} ` + 'for the `require-file-overview` rule');
|
|||
|
|
} else {
|
|||
|
|
const targetTagName = obj && typeof obj === 'object' && obj.replacement || obj;
|
|||
|
|
if (mustExist && !state.hasTag[tagName]) {
|
|||
|
|
utils.reportSettings(`Missing @${targetTagName}`);
|
|||
|
|
}
|
|||
|
|
if (preventDuplicates && state.hasDuplicates[tagName]) {
|
|||
|
|
utils.reportSettings(`Duplicate @${targetTagName}`);
|
|||
|
|
}
|
|||
|
|
if (initialCommentsOnly && state.hasNonCommentBeforeTag[tagName]) {
|
|||
|
|
utils.reportSettings(`@${targetTagName} should be at the beginning of the file`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
iterateAllJsdocs: true,
|
|||
|
|
meta: {
|
|||
|
|
docs: {
|
|||
|
|
description: 'Checks that all files have one `@file`, `@fileoverview`, or `@overview` tag at the beginning of the file.',
|
|||
|
|
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-file-overview.md#repos-sticky-header'
|
|||
|
|
},
|
|||
|
|
schema: [{
|
|||
|
|
additionalProperties: false,
|
|||
|
|
properties: {
|
|||
|
|
tags: {
|
|||
|
|
description: `The keys of this object are tag names, and the values are configuration
|
|||
|
|
objects indicating what will be checked for these whole-file tags.
|
|||
|
|
|
|||
|
|
Each configuration object has 3 potential boolean keys (which default
|
|||
|
|
to \`false\` when this option is supplied).
|
|||
|
|
|
|||
|
|
1. \`mustExist\` - enforces that all files have a \`@file\`, \`@fileoverview\`, or \`@overview\` tag.
|
|||
|
|
2. \`preventDuplicates\` - enforces that duplicate file overview tags within a given file will be reported
|
|||
|
|
3. \`initialCommentsOnly\` - reports file overview tags which are not, as per
|
|||
|
|
[the docs](https://jsdoc.app/tags-file.html), "at the beginning of
|
|||
|
|
the file"–where beginning of the file is interpreted in this rule
|
|||
|
|
as being when the overview tag is not preceded by anything other than
|
|||
|
|
a comment.
|
|||
|
|
|
|||
|
|
When no \`tags\` is present, the default is:
|
|||
|
|
|
|||
|
|
\`\`\`json
|
|||
|
|
{
|
|||
|
|
"file": {
|
|||
|
|
"initialCommentsOnly": true,
|
|||
|
|
"mustExist": true,
|
|||
|
|
"preventDuplicates": true,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
\`\`\`
|
|||
|
|
|
|||
|
|
You can add additional tag names and/or override \`file\` if you supply this
|
|||
|
|
option, e.g., in place of or in addition to \`file\`, giving other potential
|
|||
|
|
file global tags like \`@license\`, \`@copyright\`, \`@author\`, \`@module\` or
|
|||
|
|
\`@exports\`, optionally restricting them to a single use or preventing them
|
|||
|
|
from being preceded by anything besides comments.
|
|||
|
|
|
|||
|
|
For example:
|
|||
|
|
|
|||
|
|
\`\`\`js
|
|||
|
|
{
|
|||
|
|
"license": {
|
|||
|
|
"mustExist": true,
|
|||
|
|
"preventDuplicates": true,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
\`\`\`
|
|||
|
|
|
|||
|
|
This would require one and only one \`@license\` in the file, though because
|
|||
|
|
\`initialCommentsOnly\` is absent and defaults to \`false\`, the \`@license\`
|
|||
|
|
can be anywhere.
|
|||
|
|
|
|||
|
|
In the case of \`@license\`, you can use this rule along with the
|
|||
|
|
\`check-values\` rule (with its \`allowedLicenses\` or \`licensePattern\` options),
|
|||
|
|
to enforce a license whitelist be present on every JS file.
|
|||
|
|
|
|||
|
|
Note that if you choose to use \`preventDuplicates\` with \`license\`, you still
|
|||
|
|
have a way to allow multiple licenses for the whole page by using the SPDX
|
|||
|
|
"AND" expression, e.g., \`@license (MIT AND GPL-3.0)\`.
|
|||
|
|
|
|||
|
|
Note that the tag names are the main JSDoc tag name, so you should use \`file\`
|
|||
|
|
in this configuration object regardless of whether you have configured
|
|||
|
|
\`fileoverview\` instead of \`file\` on \`tagNamePreference\` (i.e., \`fileoverview\`
|
|||
|
|
will be checked, but you must use \`file\` on the configuration object).`,
|
|||
|
|
patternProperties: {
|
|||
|
|
'.*': {
|
|||
|
|
additionalProperties: false,
|
|||
|
|
properties: {
|
|||
|
|
initialCommentsOnly: {
|
|||
|
|
type: 'boolean'
|
|||
|
|
},
|
|||
|
|
mustExist: {
|
|||
|
|
type: 'boolean'
|
|||
|
|
},
|
|||
|
|
preventDuplicates: {
|
|||
|
|
type: 'boolean'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
type: 'object'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
type: 'object'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
type: 'object'
|
|||
|
|
}],
|
|||
|
|
type: 'suggestion'
|
|||
|
|
},
|
|||
|
|
nonComment({
|
|||
|
|
node,
|
|||
|
|
state
|
|||
|
|
}) {
|
|||
|
|
if (!state.hasNonComment) {
|
|||
|
|
state.hasNonComment = /** @type {[number, number]} */node.range?.[0];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
module.exports = exports.default;
|
|||
|
|
//# sourceMappingURL=requireFileOverview.cjs.map
|