{"version":3,"file":"escapeInlineTags.cjs","names":["iterateJsdoc"],"sources":["../../src/rules/escapeInlineTags.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\n\nexport default iterateJsdoc(({\n  context,\n  jsdoc,\n  settings,\n  utils,\n}) => {\n  const {\n    mode,\n  } = settings;\n\n  if (mode !== 'typescript') {\n    return;\n  }\n\n  const {\n    allowedInlineTags = [],\n    enableFixer = false,\n    fixType = 'backslash',\n  } = context.options[0] || {};\n\n  const {\n    description,\n  } = utils.getDescription();\n\n  /** @type {string[]} */\n  const tagNames = [];\n\n  /** @type {number[]} */\n  const indexes = [];\n\n  const unescapedInlineTagRegex = /(?:^|\\s)@(\\w+)/gv;\n\n  const scopedPackageNameRegex = /^@[\\w.\\-]+\\/[\\w.\\-]+/v;\n\n  const declarationReferenceInlineTags = new Set([\n    'inheritDoc',\n    'link',\n    'linkcode',\n    'linkplain',\n  ]);\n\n  const markdownCodeSpanRegex = /(?<!\\\\)(`+)(?!`)[\\s\\S]*?(?<!`)\\1(?!`)/gv;\n\n  /**\n   * @param {string} desc\n   * @param {number} index\n   * @returns {boolean}\n   */\n  const isInsideMarkdownCodeSpan = (desc, index) => {\n    markdownCodeSpanRegex.lastIndex = 0;\n\n    let match;\n    while ((match = markdownCodeSpanRegex.exec(desc)) !== null) {\n      const delimiterLength = match[1].length;\n      const contentStart = match.index + delimiterLength;\n      const contentEnd = match.index + match[0].length - delimiterLength;\n\n      if (index < contentStart) {\n        return false;\n      }\n\n      if (index < contentEnd) {\n        return true;\n      }\n    }\n\n    return false;\n  };\n\n  /**\n   * @param {string} desc\n   * @param {number} atSignIndex\n   * @returns {string}\n   */\n  const getInlineTagName = (desc, atSignIndex) => {\n    const inlineTagStart = desc.lastIndexOf('{@', atSignIndex);\n\n    if (inlineTagStart === -1) {\n      return '';\n    }\n\n    const inlineTagEnd = desc.indexOf('}', inlineTagStart);\n\n    if (inlineTagEnd === -1 || inlineTagEnd <= atSignIndex) {\n      return '';\n    }\n\n    return desc.slice(inlineTagStart + 2).match(/^\\w+/v)?.[0] || '';\n  };\n\n  /**\n   * @param {string} desc\n   * @param {string} match\n   * @param {number} offset\n   * @returns {boolean}\n   */\n  const shouldIgnoreMatch = (desc, match, offset) => {\n    const atSignIndex = offset + match.lastIndexOf('@');\n    const inlineTagName = getInlineTagName(desc, atSignIndex);\n\n    return isInsideMarkdownCodeSpan(desc, atSignIndex) ||\n      declarationReferenceInlineTags.has(inlineTagName) &&\n        scopedPackageNameRegex.test(desc.slice(atSignIndex));\n  };\n\n  /**\n   * @param {string} tagName\n   * @returns {[\n   *   RegExp,\n   *   (description: string) => string\n   * ]}\n   */\n  const escapeInlineTags = (tagName) => {\n    const regex = new RegExp(`(^|\\\\s)@${\n      // No need to escape, as contains only safe characters\n      tagName\n    }`, 'gv');\n\n    return [\n      regex,\n      /**\n       * @param {string} desc\n       */\n      (desc) => {\n        return desc.replaceAll(\n          regex,\n          (match, prefix, offset) => {\n            if (shouldIgnoreMatch(desc, match, offset)) {\n              return match;\n            }\n\n            return fixType === 'backticks' ?\n              prefix + '`@' + tagName + '`' :\n              prefix + '\\\\@' + tagName;\n          },\n        );\n      },\n    ];\n  };\n\n  /**\n   * @param {string} desc\n   * @returns {string}\n   */\n  const getUnescapedInlineTagName = (desc) => {\n    unescapedInlineTagRegex.lastIndex = 0;\n\n    let match;\n    while ((match = unescapedInlineTagRegex.exec(desc)) !== null) {\n      const [\n        fullMatch,\n        tagName,\n      ] = match;\n\n      if (\n        allowedInlineTags.includes(tagName) ||\n        shouldIgnoreMatch(desc, fullMatch, match.index)\n      ) {\n        continue;\n      }\n\n      return tagName;\n    }\n\n    return '';\n  };\n\n  const normalizedDescription = description.startsWith('\\n') ?\n    description.slice(1) :\n    description;\n\n  let nextLineStartOffset = 0;\n  for (const [\n    idx,\n    descLine,\n  ] of normalizedDescription.split('\\n').entries()\n  ) {\n    const lineStartOffset = nextLineStartOffset;\n\n    // +1 for the `\\n` removed by split.\n    nextLineStartOffset += descLine.length + 1;\n\n    descLine.replaceAll(unescapedInlineTagRegex, (match, tagName, offset) => {\n      if (\n        allowedInlineTags.includes(tagName) ||\n        // Run ignore-detection against the full description text so that\n        // multi-line inline tags (e.g. `{@link` on one line and\n        // `@scope/pkg#Member}` on the next) are recognized as being inside an\n        // inline tag rather than scanned per-line.\n        shouldIgnoreMatch(\n          normalizedDescription,\n          match,\n          lineStartOffset + offset,\n        )\n      ) {\n        return match;\n      }\n\n      tagNames.push(tagName);\n      indexes.push(idx);\n\n      return match;\n    });\n  }\n\n  for (const [\n    idx,\n    tagName,\n  ] of tagNames.entries()) {\n    utils.reportJSDoc(\n      `Unexpected inline JSDoc tag. Did you mean to use {@${tagName}}, \\\\@${tagName}, or \\`@${tagName}\\`?`,\n      {\n        line: indexes[idx] + 1,\n      },\n      enableFixer ?\n        () => {\n          // `tagName` and `fixType` are constant here, so compute the escaper\n          // once rather than rebuilding the RegExp + closure for every line.\n          const [\n            ,\n            escapeInlineTag,\n          ] = escapeInlineTags(tagName);\n\n          utils.setBlockDescription((info, seedTokens, descLines) => {\n            return descLines.map((desc) => {\n              const newDesc = escapeInlineTag(desc);\n\n              return {\n                number: 0,\n                source: '',\n                tokens: seedTokens({\n                  ...info,\n                  description: newDesc,\n                  postDelimiter: newDesc.trim() ? ' ' : '',\n                }),\n              };\n            });\n          });\n        } :\n        null,\n    );\n  }\n\n  for (const tag of jsdoc.tags) {\n    if (tag.tag === 'example') {\n      continue;\n    }\n\n    /** @type {string} */\n    let tagName = '';\n    while (/** @type {string[]} */ (\n      utils.getTagDescription(tag, true)\n    // eslint-disable-next-line no-loop-func -- Safe\n    ).some((desc) => {\n      tagName = getUnescapedInlineTagName(desc);\n\n      return tagName;\n    })) {\n      const line = utils.setTagDescription(tag, ...escapeInlineTags(tagName)) +\n          tag.source[0].number;\n      utils.reportJSDoc(\n        `Unexpected inline JSDoc tag. Did you mean to use {@${tagName}}, \\\\@${tagName}, or \\`@${tagName}\\`?`,\n        {\n          line,\n        },\n        enableFixer ? () => {} : null,\n        true,\n      );\n    }\n  }\n}, {\n  iterateAllJsdocs: true,\n  meta: {\n    docs: {\n      description: 'Reports use of JSDoc tags in non-tag positions (in the default \"typescript\" mode).',\n      url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/escape-inline-tags.md#repos-sticky-header',\n    },\n    fixable: 'code',\n    schema: [\n      {\n        additionalProperties: false,\n        properties: {\n          allowedInlineTags: {\n            description: 'A listing of tags you wish to allow unescaped. Defaults to an empty array.',\n            items: {\n              type: 'string',\n            },\n            type: 'array',\n          },\n          enableFixer: {\n            description: 'Whether to enable the fixer. Defaults to `false`.',\n            type: 'boolean',\n          },\n          fixType: {\n            description: `How to escape the inline tag.\n\nMay be \"backticks\" to enclose tags in backticks (treating as code segments), or\n\"backslash\" to escape tags with a backslash, i.e., \\`\\\\@\\`\n\nDefaults to \"backslash\".`,\n            enum: [\n              'backticks',\n              'backslash',\n            ],\n            type: 'string',\n          },\n        },\n        type: 'object',\n      },\n    ],\n    type: 'suggestion',\n  },\n});\n"],"mappings":"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","ignoreList":[]}