@diplodoc/yfmlint 1.3.4 → 1.4.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
@@ -1,4 +1,9 @@
1
1
  [![NPM version](https://img.shields.io/npm/v/@diplodoc/yfmlint.svg?style=flat)](https://www.npmjs.org/package/@diplodoc/yfmlint)
2
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=diplodoc-platform_yfmlint&metric=alert_status)](https://sonarcloud.io/summary/overall?id=diplodoc-platform_yfmlint)
3
+ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=diplodoc-platform_yfmlint&metric=coverage)](https://sonarcloud.io/summary/overall?id=diplodoc-platform_yfmlint)
4
+ [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=diplodoc-platform_yfmlint&metric=sqale_rating)](https://sonarcloud.io/summary/overall?id=diplodoc-platform_yfmlint)
5
+ [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=diplodoc-platform_yfmlint&metric=reliability_rating)](https://sonarcloud.io/summary/overall?id=diplodoc-platform_yfmlint)
6
+ [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=diplodoc-platform_yfmlint&metric=security_rating)](https://sonarcloud.io/summary/overall?id=diplodoc-platform_yfmlint)
2
7
 
3
8
  # YFM syntax linter
4
9
 
package/build/index.js CHANGED
@@ -21483,6 +21483,41 @@ var yfm001 = {
21483
21483
  };
21484
21484
 
21485
21485
  // src/rules/helpers.ts
21486
+ function validateLineNumberAndGetFilePath(params2, rawLineNumber) {
21487
+ const linesCount = params2.lines.length;
21488
+ const lineNumber = Math.min(Math.max(1, rawLineNumber || 1), linesCount);
21489
+ const env = params2.parsers.markdownit.env;
21490
+ const filePath = (env == null ? void 0 : env.path) || params2.name;
21491
+ return { lineNumber, filePath };
21492
+ }
21493
+ function resolveIncludeSource(params2, rawLineNumber, token, parentToken) {
21494
+ var _a, _b, _c, _d;
21495
+ const sourceFile = ((_a = token == null ? void 0 : token.meta) == null ? void 0 : _a.sourceFile) || ((_b = parentToken == null ? void 0 : parentToken.meta) == null ? void 0 : _b.sourceFile);
21496
+ const includeChain = ((_c = token == null ? void 0 : token.meta) == null ? void 0 : _c.includeChain) || ((_d = parentToken == null ? void 0 : parentToken.meta) == null ? void 0 : _d.includeChain);
21497
+ if (!sourceFile || !(includeChain == null ? void 0 : includeChain.length)) {
21498
+ return null;
21499
+ }
21500
+ const mainFileLine = includeChain[0].line;
21501
+ const lineNumber = Math.min(Math.max(1, mainFileLine), params2.lines.length);
21502
+ return {
21503
+ lineNumber,
21504
+ sourceFile,
21505
+ sourceLineNumber: rawLineNumber || 1,
21506
+ includeChain
21507
+ };
21508
+ }
21509
+ function formatIncludeChain(info, brokenTarget) {
21510
+ const parts = info.includeChain.map((entry) => `${entry.file}:${entry.line}`);
21511
+ parts.push(`${info.sourceFile}:${info.sourceLineNumber}`);
21512
+ return `${parts.join(" \u2192 ")} \u219B ${brokenTarget}`;
21513
+ }
21514
+ function createContextWithFileInfo(baseContext, filePath, paramsName) {
21515
+ const parts = [baseContext];
21516
+ if (filePath !== paramsName) {
21517
+ parts.push(`File: ${filePath}`);
21518
+ }
21519
+ return parts.filter(Boolean).join("; ");
21520
+ }
21486
21521
  function findLinksInInlineTokens(params2, ruleName, onError, handler) {
21487
21522
  params2.parsers.markdownit.tokens.filter((token) => token.type === "inline").forEach((inline) => {
21488
21523
  var _a;
@@ -21492,10 +21527,29 @@ function findLinksInInlineTokens(params2, ruleName, onError, handler) {
21492
21527
  if (handler) {
21493
21528
  handler(linkToken, inline);
21494
21529
  } else {
21495
- onError({
21496
- lineNumber: link.lineNumber || inline.lineNumber,
21497
- context: link.line || inline.line
21498
- });
21530
+ const rawLineNumber = link.lineNumber || inline.lineNumber;
21531
+ const includeSource = resolveIncludeSource(
21532
+ params2,
21533
+ rawLineNumber,
21534
+ link,
21535
+ inline
21536
+ );
21537
+ if (includeSource) {
21538
+ const href = linkToken.attrGet("href") || "";
21539
+ const context = formatIncludeChain(includeSource, href);
21540
+ onError({ lineNumber: includeSource.lineNumber, context });
21541
+ } else {
21542
+ const { lineNumber, filePath } = validateLineNumberAndGetFilePath(
21543
+ params2,
21544
+ rawLineNumber
21545
+ );
21546
+ const context = createContextWithFileInfo(
21547
+ link.line || inline.line,
21548
+ filePath,
21549
+ params2.name
21550
+ );
21551
+ onError({ lineNumber, context });
21552
+ }
21499
21553
  }
21500
21554
  }
21501
21555
  });
@@ -21510,10 +21564,29 @@ function findImagesInInlineTokens(params2, ruleName, onError, handler) {
21510
21564
  if (handler) {
21511
21565
  handler(imageToken, inline);
21512
21566
  } else {
21513
- onError({
21514
- lineNumber: image.lineNumber || inline.lineNumber,
21515
- context: image.line || inline.line
21516
- });
21567
+ const rawLineNumber = image.lineNumber || inline.lineNumber;
21568
+ const includeSource = resolveIncludeSource(
21569
+ params2,
21570
+ rawLineNumber,
21571
+ image,
21572
+ inline
21573
+ );
21574
+ if (includeSource) {
21575
+ const src = imageToken.attrGet("src") || "";
21576
+ const context = formatIncludeChain(includeSource, src);
21577
+ onError({ lineNumber: includeSource.lineNumber, context });
21578
+ } else {
21579
+ const { lineNumber, filePath } = validateLineNumberAndGetFilePath(
21580
+ params2,
21581
+ rawLineNumber
21582
+ );
21583
+ const context = createContextWithFileInfo(
21584
+ image.line || inline.line,
21585
+ filePath,
21586
+ params2.name
21587
+ );
21588
+ onError({ lineNumber, context });
21589
+ }
21517
21590
  }
21518
21591
  }
21519
21592
  });
@@ -21570,15 +21643,27 @@ var yfm003 = {
21570
21643
  const reason = linkToken.attrGet("YFM003");
21571
21644
  if (reason) {
21572
21645
  const reasonDescription = typeof reason === "string" && REASON_DESCRIPTION[reason] ? `Reason: ${REASON_DESCRIPTION[reason]}` : "";
21573
- const context = [
21574
- `Unreachable link: "${linkToken.attrGet("href")}"`,
21575
- reasonDescription,
21576
- `Line: ${linkToken.lineNumber || inline.lineNumber}`
21577
- ].filter(Boolean).join("; ");
21578
- onError({
21579
- lineNumber: linkToken.lineNumber || inline.lineNumber,
21580
- context
21581
- });
21646
+ const rawLineNumber = linkToken.lineNumber || inline.lineNumber;
21647
+ const href = linkToken.attrGet("href") || "";
21648
+ const includeSource = resolveIncludeSource(
21649
+ params2,
21650
+ rawLineNumber,
21651
+ linkToken,
21652
+ inline
21653
+ );
21654
+ if (includeSource) {
21655
+ const chain = formatIncludeChain(includeSource, href);
21656
+ const context = [chain, reasonDescription].filter(Boolean).join("; ");
21657
+ onError({ lineNumber: includeSource.lineNumber, context });
21658
+ } else {
21659
+ const { lineNumber } = validateLineNumberAndGetFilePath(params2, rawLineNumber);
21660
+ const context = [
21661
+ `Unreachable link: "${href}"`,
21662
+ reasonDescription,
21663
+ `Line: ${rawLineNumber}`
21664
+ ].filter(Boolean).join("; ");
21665
+ onError({ lineNumber, context });
21666
+ }
21582
21667
  }
21583
21668
  });
21584
21669
  }
@@ -21739,12 +21824,23 @@ var yfm010 = {
21739
21824
  if (!config) {
21740
21825
  return;
21741
21826
  }
21742
- findLinksInInlineTokens(params2, "YFM010", onError, (linkToken) => {
21743
- const autotitleAnchorError = `[Unreachable autotitle anchor: "${linkToken.attrGet("href")}"]`;
21744
- onError({
21745
- lineNumber: linkToken.lineNumber,
21746
- context: autotitleAnchorError + " " + (linkToken.line || "")
21747
- });
21827
+ findLinksInInlineTokens(params2, "YFM010", onError, (linkToken, inline) => {
21828
+ const href = linkToken.attrGet("href") || "";
21829
+ const rawLineNumber = linkToken.lineNumber || inline.lineNumber;
21830
+ const includeSource = resolveIncludeSource(
21831
+ params2,
21832
+ rawLineNumber,
21833
+ linkToken,
21834
+ inline
21835
+ );
21836
+ if (includeSource) {
21837
+ const context = formatIncludeChain(includeSource, href);
21838
+ onError({ lineNumber: includeSource.lineNumber, context });
21839
+ } else {
21840
+ const { lineNumber } = validateLineNumberAndGetFilePath(params2, rawLineNumber);
21841
+ const context = `Unreachable autotitle anchor: "${href}"; Line: ${rawLineNumber}`;
21842
+ onError({ lineNumber, context });
21843
+ }
21748
21844
  });
21749
21845
  }
21750
21846
  };