@qualcomm-ui/mdx-vite 3.2.2 → 3.3.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/dist/cli.js +125 -8
- package/dist/cli.js.map +4 -4
- package/dist/docs-plugin/config/config-loader.d.ts.map +1 -1
- package/dist/docs-plugin/config/config-schema.d.ts +1 -0
- package/dist/docs-plugin/config/config-schema.d.ts.map +1 -1
- package/dist/docs-plugin/config/types.d.ts +8 -0
- package/dist/docs-plugin/config/types.d.ts.map +1 -1
- package/dist/docs-plugin/link-validator.d.ts +35 -0
- package/dist/docs-plugin/link-validator.d.ts.map +1 -0
- package/dist/docs-plugin/search-indexer.d.ts +2 -0
- package/dist/docs-plugin/search-indexer.d.ts.map +1 -1
- package/dist/index.js +172 -55
- package/dist/index.js.map +4 -4
- package/dist/tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3617,7 +3617,8 @@ var configSchema = implement().with({
|
|
|
3617
3617
|
routingStrategy: z2.union([z2.literal("vite-generouted"), z2.any()]).optional(),
|
|
3618
3618
|
throwOnError: z2.boolean().optional(),
|
|
3619
3619
|
typeDocProps: z2.string().optional(),
|
|
3620
|
-
typeDocPropsOptions: typeDocPropsSchema.optional()
|
|
3620
|
+
typeDocPropsOptions: typeDocPropsSchema.optional(),
|
|
3621
|
+
validatePageLinks: z2.boolean().optional()
|
|
3621
3622
|
});
|
|
3622
3623
|
|
|
3623
3624
|
// src/docs-plugin/config/config-loader.ts
|
|
@@ -3648,7 +3649,8 @@ var ConfigLoader = class {
|
|
|
3648
3649
|
...conf,
|
|
3649
3650
|
appDirectory: conf.appDirectory || "app",
|
|
3650
3651
|
filePath: config3.filepath,
|
|
3651
|
-
pageDirectory: conf.pageDirectory ? removeTrailingSlash(conf.pageDirectory) : "routes"
|
|
3652
|
+
pageDirectory: conf.pageDirectory ? removeTrailingSlash(conf.pageDirectory) : "routes",
|
|
3653
|
+
validatePageLinks: conf.validatePageLinks ?? true
|
|
3652
3654
|
};
|
|
3653
3655
|
}
|
|
3654
3656
|
loadConfig() {
|
|
@@ -3658,7 +3660,7 @@ var ConfigLoader = class {
|
|
|
3658
3660
|
};
|
|
3659
3661
|
|
|
3660
3662
|
// src/docs-plugin/search-indexer.ts
|
|
3661
|
-
import
|
|
3663
|
+
import chalk3 from "chalk";
|
|
3662
3664
|
import { defined as defined2 } from "@qualcomm-ui/utils/guard";
|
|
3663
3665
|
|
|
3664
3666
|
// src/docs-plugin/doc-props/doc-props-indexer.ts
|
|
@@ -4602,12 +4604,99 @@ var DocPropsIndexer = class {
|
|
|
4602
4604
|
}
|
|
4603
4605
|
};
|
|
4604
4606
|
|
|
4607
|
+
// src/docs-plugin/link-validator.ts
|
|
4608
|
+
import chalk2 from "chalk";
|
|
4609
|
+
import { posix } from "node:path";
|
|
4610
|
+
import { visit as visit11 } from "unist-util-visit";
|
|
4611
|
+
var externalPrefixes = ["https://", "http://", "mailto:", "tel:"];
|
|
4612
|
+
function isExternal(url) {
|
|
4613
|
+
return externalPrefixes.some((prefix) => url.startsWith(prefix));
|
|
4614
|
+
}
|
|
4615
|
+
function resolveLink(url, sourcePathname) {
|
|
4616
|
+
if (isExternal(url)) {
|
|
4617
|
+
return null;
|
|
4618
|
+
}
|
|
4619
|
+
const [rawPath, fragment] = url.split("#", 2);
|
|
4620
|
+
let pathname;
|
|
4621
|
+
if (!rawPath || rawPath === "./" || rawPath === ".") {
|
|
4622
|
+
pathname = sourcePathname;
|
|
4623
|
+
} else if (rawPath.startsWith("/")) {
|
|
4624
|
+
pathname = rawPath;
|
|
4625
|
+
} else {
|
|
4626
|
+
const sourceDir = sourcePathname.endsWith("/") ? sourcePathname : posix.dirname(sourcePathname);
|
|
4627
|
+
pathname = posix.resolve(sourceDir, rawPath);
|
|
4628
|
+
}
|
|
4629
|
+
if (pathname !== "/" && pathname.endsWith("/")) {
|
|
4630
|
+
pathname = pathname.slice(0, -1);
|
|
4631
|
+
}
|
|
4632
|
+
return { fragment: fragment || void 0, pathname };
|
|
4633
|
+
}
|
|
4634
|
+
function collectLinks(tree, sourceFile, sourcePathname) {
|
|
4635
|
+
const links = [];
|
|
4636
|
+
visit11(tree, "link", (node) => {
|
|
4637
|
+
const resolved = resolveLink(node.url, sourcePathname);
|
|
4638
|
+
if (!resolved) {
|
|
4639
|
+
return;
|
|
4640
|
+
}
|
|
4641
|
+
links.push({
|
|
4642
|
+
fragment: resolved.fragment,
|
|
4643
|
+
sourceFile,
|
|
4644
|
+
sourcePathname,
|
|
4645
|
+
targetPathname: resolved.pathname,
|
|
4646
|
+
url: node.url
|
|
4647
|
+
});
|
|
4648
|
+
});
|
|
4649
|
+
return links;
|
|
4650
|
+
}
|
|
4651
|
+
function validateLinks(links, pageMap, docPropIds) {
|
|
4652
|
+
const invalid = [];
|
|
4653
|
+
for (const link of links) {
|
|
4654
|
+
const page = pageMap[link.targetPathname];
|
|
4655
|
+
if (!page) {
|
|
4656
|
+
invalid.push({ ...link, reason: "page-not-found" });
|
|
4657
|
+
continue;
|
|
4658
|
+
}
|
|
4659
|
+
if (link.fragment) {
|
|
4660
|
+
const inToc = page.toc?.some((h) => h.id === link.fragment);
|
|
4661
|
+
const inDocProps = docPropIds?.[link.targetPathname]?.has(link.fragment);
|
|
4662
|
+
if (!inToc && !inDocProps) {
|
|
4663
|
+
invalid.push({ ...link, reason: "fragment-not-found" });
|
|
4664
|
+
}
|
|
4665
|
+
}
|
|
4666
|
+
}
|
|
4667
|
+
return invalid;
|
|
4668
|
+
}
|
|
4669
|
+
function reportInvalidLinks(invalidLinks) {
|
|
4670
|
+
if (invalidLinks.length === 0) {
|
|
4671
|
+
return;
|
|
4672
|
+
}
|
|
4673
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
4674
|
+
for (const link of invalidLinks) {
|
|
4675
|
+
const existing = grouped.get(link.sourcePathname) ?? [];
|
|
4676
|
+
existing.push(link);
|
|
4677
|
+
grouped.set(link.sourcePathname, existing);
|
|
4678
|
+
}
|
|
4679
|
+
console.debug(
|
|
4680
|
+
`
|
|
4681
|
+
${chalk2.yellowBright.bold(`Found ${invalidLinks.length} broken link${invalidLinks.length === 1 ? "" : "s"}:`)}`
|
|
4682
|
+
);
|
|
4683
|
+
for (const [sourcePathname, links] of grouped) {
|
|
4684
|
+
console.debug(`
|
|
4685
|
+
${chalk2.blueBright.bold(sourcePathname)}`);
|
|
4686
|
+
for (const link of links) {
|
|
4687
|
+
const reason = link.reason === "page-not-found" ? "page not found" : `fragment "#${link.fragment}" not found`;
|
|
4688
|
+
console.debug(` ${chalk2.red("x")} ${link.url} \u2014 ${reason}`);
|
|
4689
|
+
}
|
|
4690
|
+
}
|
|
4691
|
+
console.debug("");
|
|
4692
|
+
}
|
|
4693
|
+
|
|
4605
4694
|
// src/docs-plugin/markdown/knowledge/section-extractor.ts
|
|
4606
4695
|
import { toString as toString2 } from "mdast-util-to-string";
|
|
4607
4696
|
import remarkGfm2 from "remark-gfm";
|
|
4608
4697
|
import remarkStringify4 from "remark-stringify";
|
|
4609
4698
|
import { unified as unified4 } from "unified";
|
|
4610
|
-
import { visit as
|
|
4699
|
+
import { visit as visit12 } from "unist-util-visit";
|
|
4611
4700
|
|
|
4612
4701
|
// src/docs-plugin/markdown/knowledge/utils.ts
|
|
4613
4702
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -4619,9 +4708,9 @@ function computeMd5(content) {
|
|
|
4619
4708
|
// src/docs-plugin/markdown/knowledge/section-extractor.ts
|
|
4620
4709
|
function transformLinks() {
|
|
4621
4710
|
return () => (tree) => {
|
|
4622
|
-
|
|
4711
|
+
visit12(tree, "link", (node) => {
|
|
4623
4712
|
let text = "";
|
|
4624
|
-
|
|
4713
|
+
visit12(node, "text", (textNode) => {
|
|
4625
4714
|
text += textNode.value;
|
|
4626
4715
|
});
|
|
4627
4716
|
Object.assign(node, {
|
|
@@ -5330,6 +5419,8 @@ var SearchIndexer = class {
|
|
|
5330
5419
|
mdxFileReader;
|
|
5331
5420
|
allowedHeadings;
|
|
5332
5421
|
metaJson;
|
|
5422
|
+
_collectedLinks = [];
|
|
5423
|
+
_docPropIds = {};
|
|
5333
5424
|
routeMetaNav = {};
|
|
5334
5425
|
config;
|
|
5335
5426
|
logWarnings;
|
|
@@ -5357,6 +5448,8 @@ var SearchIndexer = class {
|
|
|
5357
5448
|
_searchIndex = [];
|
|
5358
5449
|
reset() {
|
|
5359
5450
|
this.mdxFileReader.reset();
|
|
5451
|
+
this._collectedLinks = [];
|
|
5452
|
+
this._docPropIds = {};
|
|
5360
5453
|
this._pageMap = {};
|
|
5361
5454
|
this._searchIndex = [];
|
|
5362
5455
|
}
|
|
@@ -5467,6 +5560,11 @@ var SearchIndexer = class {
|
|
|
5467
5560
|
removeMermaidCodeBlocks: true
|
|
5468
5561
|
});
|
|
5469
5562
|
const tree = processor.runSync(processor.parse(fileContents));
|
|
5563
|
+
if (this.config.validatePageLinks) {
|
|
5564
|
+
this._collectedLinks.push(
|
|
5565
|
+
...collectLinks(tree, filePath, defaultSection.pathname)
|
|
5566
|
+
);
|
|
5567
|
+
}
|
|
5470
5568
|
const pageInfo = {
|
|
5471
5569
|
frontmatter,
|
|
5472
5570
|
id: defaultSection.id,
|
|
@@ -5479,9 +5577,9 @@ var SearchIndexer = class {
|
|
|
5479
5577
|
}
|
|
5480
5578
|
} catch (error) {
|
|
5481
5579
|
console.debug(
|
|
5482
|
-
`${
|
|
5580
|
+
`${chalk3.yellowBright.bold(
|
|
5483
5581
|
"Failed to parse mdx page content."
|
|
5484
|
-
)} ${
|
|
5582
|
+
)} ${chalk3.blueBright.bold(filePath)}`
|
|
5485
5583
|
);
|
|
5486
5584
|
if (this.config.throwOnError) {
|
|
5487
5585
|
throw new Error(error);
|
|
@@ -5510,6 +5608,17 @@ var SearchIndexer = class {
|
|
|
5510
5608
|
}
|
|
5511
5609
|
if (docPropSections.length) {
|
|
5512
5610
|
this._pageDocProps[defaultSection.pathname] = docProps;
|
|
5611
|
+
if (this.config.validatePageLinks) {
|
|
5612
|
+
const ids = /* @__PURE__ */ new Set();
|
|
5613
|
+
for (const section of docPropSections) {
|
|
5614
|
+
if (section.heading?.id) {
|
|
5615
|
+
ids.add(section.heading.id);
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
if (ids.size) {
|
|
5619
|
+
this._docPropIds[defaultSection.pathname] = ids;
|
|
5620
|
+
}
|
|
5621
|
+
}
|
|
5513
5622
|
}
|
|
5514
5623
|
if (!cached) {
|
|
5515
5624
|
this.mdxFileReader.updateCache(filePath, fileContents, {
|
|
@@ -5606,6 +5715,14 @@ var SearchIndexer = class {
|
|
|
5606
5715
|
).map((file) => this.compileTsxFile(file));
|
|
5607
5716
|
this._searchIndex.push(...mdxIndex.filter((entry) => !entry.hideFromSearch));
|
|
5608
5717
|
this.navBuilder.build();
|
|
5718
|
+
if (this.config.validatePageLinks) {
|
|
5719
|
+
const invalidLinks = validateLinks(
|
|
5720
|
+
this._collectedLinks,
|
|
5721
|
+
this._pageMap,
|
|
5722
|
+
this._docPropIds
|
|
5723
|
+
);
|
|
5724
|
+
reportInvalidLinks(invalidLinks);
|
|
5725
|
+
}
|
|
5609
5726
|
return compiledFiles;
|
|
5610
5727
|
}
|
|
5611
5728
|
};
|