fromsrc 0.0.2 → 0.0.21
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/access.d.ts +7 -7
- package/dist/access.js +12 -5
- package/dist/adapter.js +8 -16
- package/dist/adapterbrowser.js +6 -10
- package/dist/adapternext.js +7 -18
- package/dist/adapterreactrouter.js +5 -9
- package/dist/adapterremix.js +8 -17
- package/dist/adaptertanstack.js +6 -10
- package/dist/algolia.js +43 -21
- package/dist/analytics.d.ts +1 -1
- package/dist/analytics.js +16 -10
- package/dist/ansi.js +76 -37
- package/dist/api.d.ts +10 -10
- package/dist/api.js +14 -11
- package/dist/audit.d.ts +6 -6
- package/dist/audit.js +29 -10
- package/dist/autotype.js +20 -10
- package/dist/batch.d.ts +6 -6
- package/dist/batch.js +16 -9
- package/dist/changelog.js +28 -14
- package/dist/changelogutil.d.ts +4 -4
- package/dist/changelogutil.js +33 -13
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +7 -3
- package/dist/client.d.ts +1 -1
- package/dist/codesample.d.ts +4 -4
- package/dist/codesample.js +63 -24
- package/dist/collapse.js +31 -13
- package/dist/collections.js +36 -16
- package/dist/components/accordion.d.ts +1 -1
- package/dist/components/accordion.js +5 -1
- package/dist/components/alert.d.ts +1 -1
- package/dist/components/alert.js +24 -13
- package/dist/components/announce.js +40 -17
- package/dist/components/autofill.js +17 -7
- package/dist/components/avatar.js +4 -4
- package/dist/components/avatarstack.js +2 -2
- package/dist/components/backtotop.d.ts +1 -1
- package/dist/components/backtotop.js +17 -4
- package/dist/components/badge.js +9 -4
- package/dist/components/banner.js +22 -5
- package/dist/components/breadcrumb.js +11 -4
- package/dist/components/breadcrumbnav.js +37 -21
- package/dist/components/button.js +23 -8
- package/dist/components/callout.d.ts +1 -1
- package/dist/components/callout.js +33 -29
- package/dist/components/changelog.js +21 -8
- package/dist/components/checkbox.js +32 -19
- package/dist/components/code.d.ts +1 -1
- package/dist/components/code.js +6 -3
- package/dist/components/codeblock.js +157 -39
- package/dist/components/codecopy.d.ts +1 -1
- package/dist/components/codecopy.js +36 -13
- package/dist/components/codegroup.js +87 -25
- package/dist/components/collapsible.d.ts +1 -1
- package/dist/components/collapsible.js +5 -1
- package/dist/components/command.d.ts +1 -1
- package/dist/components/command.js +42 -15
- package/dist/components/compare.js +20 -8
- package/dist/components/content.js +121 -79
- package/dist/components/copybutton.d.ts +1 -1
- package/dist/components/copybutton.js +14 -7
- package/dist/components/countdown.js +9 -3
- package/dist/components/create.js +34 -24
- package/dist/components/definition.js +11 -4
- package/dist/components/diffview.js +63 -29
- package/dist/components/divider.js +5 -1
- package/dist/components/docheader.js +8 -1
- package/dist/components/doclinkcard.js +27 -3
- package/dist/components/dropdown.d.ts +1 -1
- package/dist/components/dropdown.js +32 -11
- package/dist/components/dynamiccode.js +5 -3
- package/dist/components/editlink.js +35 -23
- package/dist/components/embed.js +15 -7
- package/dist/components/endpoint.d.ts +3 -3
- package/dist/components/endpoint.js +24 -9
- package/dist/components/errormessage.d.ts +1 -1
- package/dist/components/errormessage.js +4 -1
- package/dist/components/expandcode.d.ts +1 -1
- package/dist/components/expandcode.js +6 -2
- package/dist/components/feature.js +8 -1
- package/dist/components/featuregrid.d.ts +4 -4
- package/dist/components/featuregrid.js +7 -1
- package/dist/components/feedback.js +6 -2
- package/dist/components/feedbackwidget.js +10 -4
- package/dist/components/files.d.ts +1 -1
- package/dist/components/files.js +52 -18
- package/dist/components/folder.d.ts +1 -1
- package/dist/components/folder.js +21 -4
- package/dist/components/footer.js +5 -1
- package/dist/components/formlabel.d.ts +1 -1
- package/dist/components/formlabel.js +31 -18
- package/dist/components/github.js +43 -14
- package/dist/components/graph.js +38 -14
- package/dist/components/heading.js +36 -29
- package/dist/components/headingcopy.js +13 -5
- package/dist/components/hero.js +20 -14
- package/dist/components/highlight.d.ts +2 -2
- package/dist/components/highlight.js +14 -8
- package/dist/components/hover.d.ts +2 -2
- package/dist/components/hover.js +11 -4
- package/dist/components/icons.js +4 -1
- package/dist/components/inlinetoc.js +3 -1
- package/dist/components/input.js +13 -3
- package/dist/components/install.js +34 -24
- package/dist/components/kbd.js +19 -11
- package/dist/components/langicon.d.ts +1 -1
- package/dist/components/langicon.js +22 -17
- package/dist/components/language.d.ts +1 -1
- package/dist/components/language.js +12 -4
- package/dist/components/lastupdated.d.ts +2 -2
- package/dist/components/lastupdated.js +36 -12
- package/dist/components/link.d.ts +1 -1
- package/dist/components/linkcard.js +3 -1
- package/dist/components/list.d.ts +1 -1
- package/dist/components/list.js +4 -1
- package/dist/components/math.js +33 -8
- package/dist/components/mermaid.js +3 -3
- package/dist/components/mobilenav.d.ts +2 -1
- package/dist/components/mobilenav.js +116 -47
- package/dist/components/modal.d.ts +1 -1
- package/dist/components/modal.js +9 -2
- package/dist/components/navlink.js +17 -3
- package/dist/components/openapi.d.ts +1 -1
- package/dist/components/openapi.js +102 -32
- package/dist/components/openapischema.d.ts +1 -1
- package/dist/components/openapischema.js +29 -9
- package/dist/components/openapitags.js +6 -2
- package/dist/components/pagetransition.js +5 -3
- package/dist/components/pagination.js +3 -2
- package/dist/components/panel.js +91 -15
- package/dist/components/playground.d.ts +1 -1
- package/dist/components/playground.js +153 -50
- package/dist/components/popover.js +9 -7
- package/dist/components/prelink.js +40 -9
- package/dist/components/prevnext.d.ts +1 -1
- package/dist/components/prevnext.js +36 -16
- package/dist/components/progress.js +2 -2
- package/dist/components/property.js +3 -1
- package/dist/components/quote.d.ts +2 -2
- package/dist/components/quote.js +32 -4
- package/dist/components/radio.js +36 -18
- package/dist/components/rating.js +14 -3
- package/dist/components/recent.d.ts +1 -1
- package/dist/components/recent.js +26 -10
- package/dist/components/responsive.js +21 -13
- package/dist/components/results.js +8 -4
- package/dist/components/screenshot.js +61 -21
- package/dist/components/scrollprogress.js +9 -5
- package/dist/components/scrollspy.d.ts +2 -2
- package/dist/components/scrollspy.js +9 -3
- package/dist/components/search.js +47 -18
- package/dist/components/searchbutton.js +3 -1
- package/dist/components/searchdialog.js +35 -22
- package/dist/components/searcher.d.ts +1 -1
- package/dist/components/searcher.js +51 -26
- package/dist/components/select.js +27 -13
- package/dist/components/shortcuts.d.ts +1 -1
- package/dist/components/shortcuts.js +57 -38
- package/dist/components/sidebar.d.ts +2 -1
- package/dist/components/sidebar.js +221 -56
- package/dist/components/sidebarfilter.d.ts +1 -1
- package/dist/components/sidebarfilter.js +30 -6
- package/dist/components/sidebarscript.d.ts +5 -0
- package/dist/components/sidebarscript.js +18 -0
- package/dist/components/skeleton.js +15 -3
- package/dist/components/spinner.js +13 -3
- package/dist/components/status.js +20 -8
- package/dist/components/steps.js +3 -1
- package/dist/components/switch.js +4 -4
- package/dist/components/table.js +37 -12
- package/dist/components/tabnav.d.ts +1 -1
- package/dist/components/tabnav.js +48 -36
- package/dist/components/tabs.d.ts +1 -1
- package/dist/components/tabs.js +56 -40
- package/dist/components/tag.js +8 -3
- package/dist/components/terminal.js +14 -4
- package/dist/components/textarea.js +96 -82
- package/dist/components/theme.d.ts +1 -1
- package/dist/components/theme.js +25 -3
- package/dist/components/themeprovider.d.ts +4 -4
- package/dist/components/themeprovider.js +16 -5
- package/dist/components/toast.d.ts +1 -1
- package/dist/components/toast.js +23 -14
- package/dist/components/toc/default.d.ts +1 -1
- package/dist/components/toc/default.js +28 -13
- package/dist/components/toc/hook.js +28 -14
- package/dist/components/toc/index.js +8 -4
- package/dist/components/toc/inline.js +12 -2
- package/dist/components/toc/minimal.js +11 -5
- package/dist/components/toc/zigzag.d.ts +1 -1
- package/dist/components/toc/zigzag.js +37 -17
- package/dist/components/tocprogress.d.ts +1 -1
- package/dist/components/tocprogress.js +66 -34
- package/dist/components/tooltip.d.ts +1 -1
- package/dist/components/tooltip.js +20 -8
- package/dist/components/trigger.js +13 -5
- package/dist/components/twoslash.js +49 -26
- package/dist/components/typetable.js +23 -4
- package/dist/components/typewriter.js +6 -2
- package/dist/components/version.js +40 -14
- package/dist/components/video.js +25 -15
- package/dist/components/zoom.js +6 -2
- package/dist/config.d.ts +2 -2
- package/dist/config.js +56 -30
- package/dist/content.d.ts +5 -5
- package/dist/content.js +121 -57
- package/dist/contentcache.d.ts +10 -10
- package/dist/contentcache.js +9 -5
- package/dist/contentdiff.d.ts +4 -4
- package/dist/contentdiff.js +16 -8
- package/dist/contributors.d.ts +4 -4
- package/dist/contributors.js +49 -19
- package/dist/diff.d.ts +6 -6
- package/dist/diff.js +37 -16
- package/dist/draft.d.ts +11 -11
- package/dist/draft.js +9 -5
- package/dist/env.js +21 -7
- package/dist/export.js +4 -4
- package/dist/frontmatter.js +11 -9
- package/dist/github.js +60 -30
- package/dist/gitsource.d.ts +1 -1
- package/dist/gitsource.js +16 -9
- package/dist/hash.d.ts +6 -6
- package/dist/hash.js +19 -7
- package/dist/highlight.d.ts +4 -4
- package/dist/highlight.js +34 -14
- package/dist/hooks/anchor.js +26 -14
- package/dist/hooks/arrownav.js +25 -7
- package/dist/hooks/async.js +3 -3
- package/dist/hooks/battery.js +11 -3
- package/dist/hooks/breakpoint.js +10 -2
- package/dist/hooks/clickoutside.js +10 -3
- package/dist/hooks/clipboard-paste.js +7 -3
- package/dist/hooks/clipboard.d.ts +2 -2
- package/dist/hooks/clipboard.js +21 -15
- package/dist/hooks/copy.js +11 -6
- package/dist/hooks/countdown.js +1 -1
- package/dist/hooks/counter.js +1 -1
- package/dist/hooks/escapekey.js +6 -1
- package/dist/hooks/eventlistener.js +3 -1
- package/dist/hooks/eventsource.js +4 -2
- package/dist/hooks/eyedropper.js +7 -3
- package/dist/hooks/favicon.js +1 -1
- package/dist/hooks/fetch.js +12 -4
- package/dist/hooks/focustrap.js +20 -8
- package/dist/hooks/focuswithin.js +6 -2
- package/dist/hooks/form.d.ts +2 -2
- package/dist/hooks/form.js +15 -2
- package/dist/hooks/fullscreen.js +1 -1
- package/dist/hooks/geolocation.js +8 -8
- package/dist/hooks/hotkeys.js +19 -7
- package/dist/hooks/hover.d.ts +4 -1
- package/dist/hooks/hover.js +3 -1
- package/dist/hooks/idle.js +13 -3
- package/dist/hooks/infinitescroll.js +4 -2
- package/dist/hooks/interval.js +3 -1
- package/dist/hooks/inview.js +7 -3
- package/dist/hooks/keyboard.js +36 -12
- package/dist/hooks/keypress.js +6 -2
- package/dist/hooks/list.js +11 -1
- package/dist/hooks/longpress.js +3 -3
- package/dist/hooks/map.js +1 -1
- package/dist/hooks/measure.js +16 -7
- package/dist/hooks/mediarecorder.js +7 -3
- package/dist/hooks/networkstate.js +4 -2
- package/dist/hooks/os.js +12 -4
- package/dist/hooks/pagination.js +6 -4
- package/dist/hooks/permission.js +6 -2
- package/dist/hooks/queue.js +4 -2
- package/dist/hooks/readprogress.js +6 -2
- package/dist/hooks/resizeobserver.js +6 -4
- package/dist/hooks/script.js +1 -1
- package/dist/hooks/scrolllock.js +6 -2
- package/dist/hooks/scrollspy.js +4 -2
- package/dist/hooks/selection.js +6 -3
- package/dist/hooks/share.js +18 -9
- package/dist/hooks/speechrecognition.js +7 -3
- package/dist/hooks/stepper.js +4 -4
- package/dist/hooks/storage.js +9 -3
- package/dist/hooks/stylesheet.js +4 -2
- package/dist/hooks/textselection.js +6 -3
- package/dist/hooks/throttle.js +6 -2
- package/dist/hooks/undoredo.js +19 -11
- package/dist/hooks/vibrate.js +3 -1
- package/dist/hooks/viewtransition.js +8 -4
- package/dist/hooks/wakelock.js +12 -7
- package/dist/hooks/websocket.js +4 -2
- package/dist/hooks/windowsize.js +2 -2
- package/dist/i18n.d.ts +2 -2
- package/dist/i18n.js +27 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lastmodified.js +11 -5
- package/dist/linkcheck.d.ts +6 -6
- package/dist/linkcheck.js +55 -14
- package/dist/llms.js +20 -4
- package/dist/manifest.js +7 -7
- package/dist/mcp.js +28 -22
- package/dist/mdtoc.d.ts +4 -4
- package/dist/mdtoc.js +11 -5
- package/dist/mdxscope.d.ts +2 -2
- package/dist/mdxscope.js +3 -1
- package/dist/meta.js +19 -7
- package/dist/migrate.js +35 -25
- package/dist/navgen.d.ts +8 -8
- package/dist/navgen.js +73 -30
- package/dist/navtree.d.ts +1 -1
- package/dist/navtree.js +39 -19
- package/dist/oembed.d.ts +4 -4
- package/dist/oembed.js +24 -18
- package/dist/ogimage.d.ts +11 -11
- package/dist/ogimage.js +24 -24
- package/dist/openapi.js +60 -33
- package/dist/openapiguard.js +21 -11
- package/dist/openapiutil.js +66 -20
- package/dist/orama.js +52 -34
- package/dist/pipeline.d.ts +4 -4
- package/dist/pipeline.js +4 -4
- package/dist/preload.d.ts +2 -2
- package/dist/preload.js +4 -4
- package/dist/ranking.d.ts +6 -6
- package/dist/ranking.js +39 -13
- package/dist/readtime.js +3 -1
- package/dist/redirects.d.ts +2 -2
- package/dist/redirects.js +20 -12
- package/dist/rehype.js +16 -9
- package/dist/rehypeautolink.d.ts +2 -2
- package/dist/rehypeautolink.js +25 -23
- package/dist/rehypecode.js +38 -28
- package/dist/rehypecopy.js +17 -13
- package/dist/rehypeinline.js +33 -27
- package/dist/rehypelinks.js +28 -20
- package/dist/rehyperaw.js +9 -3
- package/dist/rehypeslug.d.ts +1 -1
- package/dist/rehypeslug.js +23 -19
- package/dist/rehypetablewrap.d.ts +2 -2
- package/dist/rehypetablewrap.js +9 -5
- package/dist/rehypetoc.d.ts +1 -1
- package/dist/rehypetoc.js +15 -7
- package/dist/remark.js +28 -13
- package/dist/remarkadmonition.js +40 -14
- package/dist/remarkannotation.d.ts +2 -2
- package/dist/remarkannotation.js +26 -10
- package/dist/remarkbadge.js +43 -31
- package/dist/remarkblockmath.js +29 -15
- package/dist/remarkcallout.js +32 -14
- package/dist/remarkcaption.js +28 -16
- package/dist/remarkcodetitle.js +29 -13
- package/dist/remarkcolumns.js +22 -10
- package/dist/remarkdetails.js +34 -14
- package/dist/remarkdirective.js +47 -20
- package/dist/remarkembed.js +38 -22
- package/dist/remarkfiletree.js +29 -19
- package/dist/remarkfootnote.js +46 -18
- package/dist/remarkgfm.js +13 -8
- package/dist/remarkheadingid.js +16 -6
- package/dist/remarkimage.js +54 -34
- package/dist/remarkinclude.js +20 -8
- package/dist/remarkinstall.js +20 -12
- package/dist/remarklinkcard.js +33 -14
- package/dist/remarkmath.js +34 -15
- package/dist/remarkmermaid.js +10 -6
- package/dist/remarkmeta.d.ts +2 -2
- package/dist/remarkmeta.js +15 -5
- package/dist/remarkreadingtime.d.ts +2 -2
- package/dist/remarkreadingtime.js +3 -1
- package/dist/remarksteps.js +26 -14
- package/dist/remarkstructure.js +16 -10
- package/dist/remarktabs.js +31 -14
- package/dist/remarktoc.js +40 -24
- package/dist/remarkts2js.js +51 -40
- package/dist/remarktwoslash.d.ts +4 -4
- package/dist/remarktwoslash.js +24 -14
- package/dist/remarkvideo.d.ts +4 -4
- package/dist/remarkvideo.js +42 -16
- package/dist/schema.d.ts +14 -14
- package/dist/schema.js +2 -2
- package/dist/search.js +106 -48
- package/dist/searchindex.js +86 -34
- package/dist/searchpolicy.js +1 -1
- package/dist/searchscore.js +5 -5
- package/dist/searchtypo.js +30 -10
- package/dist/seo.d.ts +2 -2
- package/dist/seo.js +14 -14
- package/dist/shortcodes.d.ts +4 -4
- package/dist/shortcodes.js +25 -20
- package/dist/sitemap.js +18 -8
- package/dist/snippets.js +26 -18
- package/dist/source.js +75 -41
- package/dist/stats.d.ts +4 -4
- package/dist/stats.js +18 -12
- package/dist/testing.d.ts +7 -7
- package/dist/testing.js +74 -29
- package/dist/themeutil.d.ts +6 -6
- package/dist/themeutil.js +145 -27
- package/dist/typegen.js +31 -12
- package/dist/validate.js +19 -7
- package/dist/validator.d.ts +11 -11
- package/dist/validator.js +68 -19
- package/dist/versioning.d.ts +7 -7
- package/dist/versioning.js +27 -11
- package/dist/watcher.js +39 -15
- package/dist/webhook.d.ts +6 -6
- package/dist/webhook.js +34 -12
- package/dist/workspace.js +26 -12
- package/package.json +137 -137
- package/styles/reset.css +1 -1
package/dist/stats.js
CHANGED
|
@@ -7,7 +7,7 @@ function analyzePage(content, path) {
|
|
|
7
7
|
const links = (content.match(/\[([^\]]*)\]\(([^)]*)\)/g) || []).length;
|
|
8
8
|
const images = (content.match(/!\[([^\]]*)\]\(([^)]*)\)/g) || []).length;
|
|
9
9
|
const codeBlocks = Math.floor((content.match(/^```/gm) || []).length / 2);
|
|
10
|
-
return {
|
|
10
|
+
return { codeBlocks, headings, images, links, path, words };
|
|
11
11
|
}
|
|
12
12
|
function extractLanguages(content) {
|
|
13
13
|
const langs = {};
|
|
@@ -21,8 +21,11 @@ async function collectFiles(dir) {
|
|
|
21
21
|
const files = [];
|
|
22
22
|
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
23
23
|
const full = join(dir, entry.name);
|
|
24
|
-
if (entry.isDirectory())
|
|
25
|
-
|
|
24
|
+
if (entry.isDirectory()) {
|
|
25
|
+
files.push(...await collectFiles(full));
|
|
26
|
+
} else if ([".md", ".mdx"].includes(extname(entry.name))) {
|
|
27
|
+
files.push(full);
|
|
28
|
+
}
|
|
26
29
|
}
|
|
27
30
|
return files;
|
|
28
31
|
}
|
|
@@ -32,25 +35,28 @@ async function analyzeDocs(dir) {
|
|
|
32
35
|
const languages = {};
|
|
33
36
|
let latest = "";
|
|
34
37
|
for (const file of files) {
|
|
35
|
-
const content = await readFile(file, "
|
|
38
|
+
const content = await readFile(file, "utf8");
|
|
36
39
|
const modified = (await stat(file)).mtime.toISOString();
|
|
37
|
-
if (modified > latest)
|
|
40
|
+
if (modified > latest) {
|
|
41
|
+
latest = modified;
|
|
42
|
+
}
|
|
38
43
|
pages.push(analyzePage(content, relative(dir, file)));
|
|
39
|
-
for (const [lang, count] of Object.entries(extractLanguages(content)))
|
|
44
|
+
for (const [lang, count] of Object.entries(extractLanguages(content))) {
|
|
40
45
|
languages[lang] = (languages[lang] || 0) + count;
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
48
|
const totalWords = pages.reduce((s, p) => s + p.words, 0);
|
|
43
49
|
const sum = (fn) => pages.reduce((s, p) => s + fn(p), 0);
|
|
44
50
|
return {
|
|
45
|
-
totalPages: pages.length,
|
|
46
|
-
totalWords,
|
|
47
51
|
avgWords: pages.length ? Math.round(totalWords / pages.length) : 0,
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
languages,
|
|
53
|
+
lastUpdated: latest || (/* @__PURE__ */ new Date()).toISOString(),
|
|
50
54
|
totalCodeBlocks: sum((p) => p.codeBlocks),
|
|
55
|
+
totalHeadings: sum((p) => p.headings),
|
|
51
56
|
totalImages: sum((p) => p.images),
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
totalLinks: sum((p) => p.links),
|
|
58
|
+
totalPages: pages.length,
|
|
59
|
+
totalWords
|
|
54
60
|
};
|
|
55
61
|
}
|
|
56
62
|
function formatStats(stats) {
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
interface TestCase {
|
|
2
2
|
name: string;
|
|
3
3
|
fn: () => Promise<void> | void;
|
|
4
|
-
}
|
|
5
|
-
|
|
4
|
+
}
|
|
5
|
+
interface TestResult {
|
|
6
6
|
name: string;
|
|
7
7
|
passed: boolean;
|
|
8
8
|
error?: string;
|
|
9
9
|
duration: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
10
|
+
}
|
|
11
|
+
interface TestSuite {
|
|
12
12
|
name: string;
|
|
13
13
|
results: TestResult[];
|
|
14
14
|
passed: number;
|
|
15
15
|
failed: number;
|
|
16
16
|
duration: number;
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
declare function createTestSuite(name: string): {
|
|
19
|
-
test: (caseName: string, fn: () => Promise<void> | void) => void;
|
|
20
19
|
run: () => Promise<TestSuite>;
|
|
20
|
+
test: (caseName: string, fn: () => Promise<void> | void) => void;
|
|
21
21
|
};
|
|
22
22
|
declare function assertFrontmatter(content: string, fields: string[]): void;
|
|
23
23
|
declare function assertHeadings(content: string, options?: {
|
package/dist/testing.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
function headingid(value) {
|
|
2
|
-
return value.toLowerCase().
|
|
2
|
+
return value.toLowerCase().replaceAll(/[^\w\s-]/g, "").trim().replaceAll(/\s+/g, "-");
|
|
3
3
|
}
|
|
4
4
|
function collectheadingids(content) {
|
|
5
5
|
return [...content.matchAll(/^#{1,6}\s+(.+)$/gm)].map((match) => {
|
|
6
6
|
const value = match[1];
|
|
7
|
-
if (!value)
|
|
7
|
+
if (!value) {
|
|
8
|
+
return "";
|
|
9
|
+
}
|
|
8
10
|
return headingid(value);
|
|
9
11
|
}).filter(Boolean);
|
|
10
12
|
}
|
|
11
13
|
function createTestSuite(name) {
|
|
12
14
|
const cases = [];
|
|
13
15
|
function test(caseName, fn) {
|
|
14
|
-
cases.push({ name: caseName
|
|
16
|
+
cases.push({ fn, name: caseName });
|
|
15
17
|
}
|
|
16
18
|
async function run() {
|
|
17
19
|
const results = [];
|
|
@@ -20,63 +22,87 @@ function createTestSuite(name) {
|
|
|
20
22
|
const t = performance.now();
|
|
21
23
|
try {
|
|
22
24
|
await c.fn();
|
|
23
|
-
results.push({ name: c.name, passed: true, duration: performance.now() - t });
|
|
24
|
-
} catch (e) {
|
|
25
25
|
results.push({
|
|
26
|
+
duration: performance.now() - t,
|
|
26
27
|
name: c.name,
|
|
27
|
-
passed:
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
passed: true
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
results.push({
|
|
32
|
+
duration: performance.now() - t,
|
|
33
|
+
error: error instanceof Error ? error.message : String(error),
|
|
34
|
+
name: c.name,
|
|
35
|
+
passed: false
|
|
30
36
|
});
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
return {
|
|
40
|
+
duration: performance.now() - start,
|
|
41
|
+
failed: results.filter((r) => !r.passed).length,
|
|
34
42
|
name,
|
|
35
|
-
results,
|
|
36
43
|
passed: results.filter((r) => r.passed).length,
|
|
37
|
-
|
|
38
|
-
duration: performance.now() - start
|
|
44
|
+
results
|
|
39
45
|
};
|
|
40
46
|
}
|
|
41
|
-
return {
|
|
47
|
+
return { run, test };
|
|
42
48
|
}
|
|
43
49
|
function assertFrontmatter(content, fields) {
|
|
44
50
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
45
|
-
if (!match)
|
|
51
|
+
if (!match) {
|
|
52
|
+
throw new Error("missing frontmatter");
|
|
53
|
+
}
|
|
46
54
|
const body = match[1];
|
|
47
|
-
if (!body)
|
|
55
|
+
if (!body) {
|
|
56
|
+
throw new Error("invalid frontmatter");
|
|
57
|
+
}
|
|
48
58
|
const lines = body.split("\n");
|
|
49
59
|
const values = /* @__PURE__ */ new Map();
|
|
50
60
|
for (const line of lines) {
|
|
51
61
|
const index = line.indexOf(":");
|
|
52
|
-
if (index < 1)
|
|
62
|
+
if (index < 1) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
53
65
|
const key = line.slice(0, index).trim();
|
|
54
|
-
if (!key)
|
|
55
|
-
|
|
66
|
+
if (!key) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (values.has(key)) {
|
|
70
|
+
throw new Error(`duplicate field: ${key}`);
|
|
71
|
+
}
|
|
56
72
|
const value = line.slice(index + 1).trim();
|
|
57
73
|
values.set(key, value);
|
|
58
74
|
}
|
|
59
75
|
for (const field of fields) {
|
|
60
|
-
if (!values.has(field))
|
|
76
|
+
if (!values.has(field)) {
|
|
77
|
+
throw new Error(`missing field: ${field}`);
|
|
78
|
+
}
|
|
61
79
|
const value = values.get(field) ?? "";
|
|
62
|
-
if (!value)
|
|
80
|
+
if (!value) {
|
|
81
|
+
throw new Error(`empty field: ${field}`);
|
|
82
|
+
}
|
|
63
83
|
}
|
|
64
84
|
}
|
|
65
85
|
function assertHeadings(content, options) {
|
|
66
86
|
const ids = collectheadingids(content);
|
|
67
87
|
const seen = /* @__PURE__ */ new Set();
|
|
68
88
|
for (const id of ids) {
|
|
69
|
-
if (seen.has(id))
|
|
89
|
+
if (seen.has(id)) {
|
|
90
|
+
throw new Error(`duplicate heading id: ${id}`);
|
|
91
|
+
}
|
|
70
92
|
seen.add(id);
|
|
71
93
|
}
|
|
72
94
|
const headings = [...content.matchAll(/^(#{1,6})\s+/gm)].map((m) => m[1]?.length ?? 0).filter((level) => level > 0);
|
|
73
95
|
if (options?.minCount && headings.length < options.minCount) {
|
|
74
|
-
throw new Error(
|
|
96
|
+
throw new Error(
|
|
97
|
+
`expected at least ${options.minCount} headings, found ${headings.length}`
|
|
98
|
+
);
|
|
75
99
|
}
|
|
76
100
|
if (options?.maxDepth) {
|
|
77
101
|
for (const level of headings) {
|
|
78
102
|
if (level > options.maxDepth) {
|
|
79
|
-
throw new Error(
|
|
103
|
+
throw new Error(
|
|
104
|
+
`heading h${level} exceeds max depth ${options.maxDepth}`
|
|
105
|
+
);
|
|
80
106
|
}
|
|
81
107
|
}
|
|
82
108
|
}
|
|
@@ -84,19 +110,32 @@ function assertHeadings(content, options) {
|
|
|
84
110
|
for (let i = 1; i < headings.length; i++) {
|
|
85
111
|
const current = headings[i];
|
|
86
112
|
const previous = headings[i - 1];
|
|
87
|
-
if (!current || !previous)
|
|
113
|
+
if (!current || !previous) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
88
116
|
if (current > previous + 1) {
|
|
89
|
-
throw new Error(
|
|
117
|
+
throw new Error(
|
|
118
|
+
`heading h${headings[i]} skips level after h${headings[i - 1]}`
|
|
119
|
+
);
|
|
90
120
|
}
|
|
91
121
|
}
|
|
92
122
|
}
|
|
93
123
|
}
|
|
94
124
|
function assertLinks(content) {
|
|
95
|
-
const placeholders = /* @__PURE__ */ new Set([
|
|
125
|
+
const placeholders = /* @__PURE__ */ new Set([
|
|
126
|
+
"#",
|
|
127
|
+
"todo",
|
|
128
|
+
"http://",
|
|
129
|
+
"https://",
|
|
130
|
+
"about:blank",
|
|
131
|
+
"javascript:void(0)"
|
|
132
|
+
]);
|
|
96
133
|
const headingids = new Set(collectheadingids(content));
|
|
97
134
|
const links = [...content.matchAll(/\[([^\]]*)\]\(([^)]*)\)/g)];
|
|
98
135
|
for (const [, text = "", url = ""] of links) {
|
|
99
|
-
if (!text.trim())
|
|
136
|
+
if (!text.trim()) {
|
|
137
|
+
throw new Error("empty link text");
|
|
138
|
+
}
|
|
100
139
|
const value = url.trim();
|
|
101
140
|
const lowered = value.toLowerCase();
|
|
102
141
|
if (!value || placeholders.has(lowered)) {
|
|
@@ -113,10 +152,14 @@ function assertLinks(content) {
|
|
|
113
152
|
function assertLength(content, options) {
|
|
114
153
|
const words = content.replace(/^---\n[\s\S]*?\n---\n?/, "").split(/\s+/).filter(Boolean).length;
|
|
115
154
|
if (options.minWords && words < options.minWords) {
|
|
116
|
-
throw new Error(
|
|
155
|
+
throw new Error(
|
|
156
|
+
`expected at least ${options.minWords} words, found ${words}`
|
|
157
|
+
);
|
|
117
158
|
}
|
|
118
159
|
if (options.maxWords && words > options.maxWords) {
|
|
119
|
-
throw new Error(
|
|
160
|
+
throw new Error(
|
|
161
|
+
`expected at most ${options.maxWords} words, found ${words}`
|
|
162
|
+
);
|
|
120
163
|
}
|
|
121
164
|
}
|
|
122
165
|
function formatTestSuite(suite) {
|
|
@@ -126,7 +169,9 @@ function formatTestSuite(suite) {
|
|
|
126
169
|
for (const r of suite.results) {
|
|
127
170
|
const status = r.passed ? "pass" : "FAIL";
|
|
128
171
|
lines.push(` ${status} ${r.name} (${Math.round(r.duration)}ms)`);
|
|
129
|
-
if (r.error)
|
|
172
|
+
if (r.error) {
|
|
173
|
+
lines.push(` ${r.error}`);
|
|
174
|
+
}
|
|
130
175
|
}
|
|
131
176
|
return lines.join("\n");
|
|
132
177
|
}
|
package/dist/themeutil.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
interface ThemeColors {
|
|
2
2
|
bg: string;
|
|
3
3
|
surface: string;
|
|
4
4
|
fg: string;
|
|
@@ -10,18 +10,18 @@ type ThemeColors = {
|
|
|
10
10
|
warning: string;
|
|
11
11
|
error: string;
|
|
12
12
|
info: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
13
|
+
}
|
|
14
|
+
interface ThemeConfig {
|
|
15
15
|
light: ThemeColors;
|
|
16
16
|
dark: ThemeColors;
|
|
17
17
|
radius?: string;
|
|
18
18
|
font?: string;
|
|
19
19
|
mono?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
20
|
+
}
|
|
21
|
+
interface ThemePreset {
|
|
22
22
|
name: string;
|
|
23
23
|
config: ThemeConfig;
|
|
24
|
-
}
|
|
24
|
+
}
|
|
25
25
|
declare function generateCss(config: ThemeConfig): string;
|
|
26
26
|
declare const presets: Record<string, ThemePreset>;
|
|
27
27
|
declare function mergeTheme(base: ThemeConfig, overrides: Partial<ThemeConfig>): ThemeConfig;
|
package/dist/themeutil.js
CHANGED
|
@@ -12,56 +12,174 @@ const colorKeys = [
|
|
|
12
12
|
"info"
|
|
13
13
|
];
|
|
14
14
|
function colors(bg, surface, fg, muted, dim, accent, line, success, warning, error, info) {
|
|
15
|
-
return {
|
|
15
|
+
return {
|
|
16
|
+
accent,
|
|
17
|
+
bg,
|
|
18
|
+
dim,
|
|
19
|
+
error,
|
|
20
|
+
fg,
|
|
21
|
+
info,
|
|
22
|
+
line,
|
|
23
|
+
muted,
|
|
24
|
+
success,
|
|
25
|
+
surface,
|
|
26
|
+
warning
|
|
27
|
+
};
|
|
16
28
|
}
|
|
17
29
|
function generateCss(config) {
|
|
18
30
|
const lines = [":root {"];
|
|
19
|
-
for (const key of colorKeys)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (config.
|
|
31
|
+
for (const key of colorKeys) {
|
|
32
|
+
lines.push(` --${key}: ${config.light[key]};`);
|
|
33
|
+
}
|
|
34
|
+
if (config.radius) {
|
|
35
|
+
lines.push(` --radius: ${config.radius};`);
|
|
36
|
+
}
|
|
37
|
+
if (config.font) {
|
|
38
|
+
lines.push(` --font: ${config.font};`);
|
|
39
|
+
}
|
|
40
|
+
if (config.mono) {
|
|
41
|
+
lines.push(` --mono: ${config.mono};`);
|
|
42
|
+
}
|
|
23
43
|
lines.push("}", "", ".dark {");
|
|
24
|
-
for (const key of colorKeys)
|
|
44
|
+
for (const key of colorKeys) {
|
|
45
|
+
lines.push(` --${key}: ${config.dark[key]};`);
|
|
46
|
+
}
|
|
25
47
|
lines.push("}");
|
|
26
48
|
return lines.join("\n");
|
|
27
49
|
}
|
|
28
50
|
const presets = {
|
|
29
51
|
default: {
|
|
30
|
-
name: "default",
|
|
31
52
|
config: {
|
|
32
|
-
light: colors(
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
light: colors(
|
|
54
|
+
"#ffffff",
|
|
55
|
+
"#f8f9fa",
|
|
56
|
+
"#1a1a1a",
|
|
57
|
+
"#6b7280",
|
|
58
|
+
"#9ca3af",
|
|
59
|
+
"#2563eb",
|
|
60
|
+
"#e5e7eb",
|
|
61
|
+
"#16a34a",
|
|
62
|
+
"#ca8a04",
|
|
63
|
+
"#dc2626",
|
|
64
|
+
"#2563eb"
|
|
65
|
+
),
|
|
66
|
+
dark: colors(
|
|
67
|
+
"#0a0a0a",
|
|
68
|
+
"#141414",
|
|
69
|
+
"#f5f5f5",
|
|
70
|
+
"#a1a1aa",
|
|
71
|
+
"#71717a",
|
|
72
|
+
"#3b82f6",
|
|
73
|
+
"#27272a",
|
|
74
|
+
"#22c55e",
|
|
75
|
+
"#eab308",
|
|
76
|
+
"#ef4444",
|
|
77
|
+
"#3b82f6"
|
|
78
|
+
)
|
|
79
|
+
},
|
|
80
|
+
name: "default"
|
|
35
81
|
},
|
|
36
|
-
|
|
37
|
-
name: "ocean",
|
|
82
|
+
forest: {
|
|
38
83
|
config: {
|
|
39
|
-
light: colors(
|
|
40
|
-
|
|
41
|
-
|
|
84
|
+
light: colors(
|
|
85
|
+
"#f5faf5",
|
|
86
|
+
"#e8f5e8",
|
|
87
|
+
"#1a2e1a",
|
|
88
|
+
"#4a6b4a",
|
|
89
|
+
"#7a9b7a",
|
|
90
|
+
"#2d8a4e",
|
|
91
|
+
"#c8e0c8",
|
|
92
|
+
"#1a7a35",
|
|
93
|
+
"#a68b00",
|
|
94
|
+
"#c0392b",
|
|
95
|
+
"#2d8a4e"
|
|
96
|
+
),
|
|
97
|
+
dark: colors(
|
|
98
|
+
"#0a160a",
|
|
99
|
+
"#142014",
|
|
100
|
+
"#e8f5e8",
|
|
101
|
+
"#8ab88a",
|
|
102
|
+
"#5a8a5a",
|
|
103
|
+
"#4caf50",
|
|
104
|
+
"#1e3a1e",
|
|
105
|
+
"#27ae60",
|
|
106
|
+
"#f39c12",
|
|
107
|
+
"#e74c3c",
|
|
108
|
+
"#4caf50"
|
|
109
|
+
)
|
|
110
|
+
},
|
|
111
|
+
name: "forest"
|
|
42
112
|
},
|
|
43
|
-
|
|
44
|
-
name: "forest",
|
|
113
|
+
ocean: {
|
|
45
114
|
config: {
|
|
46
|
-
light: colors(
|
|
47
|
-
|
|
48
|
-
|
|
115
|
+
light: colors(
|
|
116
|
+
"#f0f7ff",
|
|
117
|
+
"#e0efff",
|
|
118
|
+
"#0c1929",
|
|
119
|
+
"#4a6a8a",
|
|
120
|
+
"#7a9aba",
|
|
121
|
+
"#0066cc",
|
|
122
|
+
"#c4daf0",
|
|
123
|
+
"#0d7a3e",
|
|
124
|
+
"#b8860b",
|
|
125
|
+
"#c41e3a",
|
|
126
|
+
"#0066cc"
|
|
127
|
+
),
|
|
128
|
+
dark: colors(
|
|
129
|
+
"#0a1628",
|
|
130
|
+
"#112240",
|
|
131
|
+
"#e6f0ff",
|
|
132
|
+
"#8baac8",
|
|
133
|
+
"#5a7a98",
|
|
134
|
+
"#4d9fff",
|
|
135
|
+
"#1e3a5f",
|
|
136
|
+
"#2ecc71",
|
|
137
|
+
"#f1c40f",
|
|
138
|
+
"#e74c3c",
|
|
139
|
+
"#4d9fff"
|
|
140
|
+
)
|
|
141
|
+
},
|
|
142
|
+
name: "ocean"
|
|
49
143
|
},
|
|
50
144
|
rose: {
|
|
51
|
-
name: "rose",
|
|
52
145
|
config: {
|
|
53
|
-
light: colors(
|
|
54
|
-
|
|
55
|
-
|
|
146
|
+
light: colors(
|
|
147
|
+
"#fff5f7",
|
|
148
|
+
"#ffe4ea",
|
|
149
|
+
"#2a1015",
|
|
150
|
+
"#8a4a5a",
|
|
151
|
+
"#ba7a8a",
|
|
152
|
+
"#e11d48",
|
|
153
|
+
"#f0c8d0",
|
|
154
|
+
"#16a34a",
|
|
155
|
+
"#ca8a04",
|
|
156
|
+
"#dc2626",
|
|
157
|
+
"#e11d48"
|
|
158
|
+
),
|
|
159
|
+
dark: colors(
|
|
160
|
+
"#160a0e",
|
|
161
|
+
"#201418",
|
|
162
|
+
"#fce4ec",
|
|
163
|
+
"#c88a9a",
|
|
164
|
+
"#8a5a6a",
|
|
165
|
+
"#fb7185",
|
|
166
|
+
"#3a1e28",
|
|
167
|
+
"#22c55e",
|
|
168
|
+
"#eab308",
|
|
169
|
+
"#ef4444",
|
|
170
|
+
"#fb7185"
|
|
171
|
+
)
|
|
172
|
+
},
|
|
173
|
+
name: "rose"
|
|
56
174
|
}
|
|
57
175
|
};
|
|
58
176
|
function mergeTheme(base, overrides) {
|
|
59
177
|
return {
|
|
60
|
-
light: { ...base.light, ...overrides.light },
|
|
61
178
|
dark: { ...base.dark, ...overrides.dark },
|
|
62
|
-
radius: overrides.radius ?? base.radius,
|
|
63
179
|
font: overrides.font ?? base.font,
|
|
64
|
-
|
|
180
|
+
light: { ...base.light, ...overrides.light },
|
|
181
|
+
mono: overrides.mono ?? base.mono,
|
|
182
|
+
radius: overrides.radius ?? base.radius
|
|
65
183
|
};
|
|
66
184
|
}
|
|
67
185
|
function luminance(hex) {
|
package/dist/typegen.js
CHANGED
|
@@ -3,18 +3,30 @@ import { join } from 'node:path';
|
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
4
|
|
|
5
5
|
function inferType(value) {
|
|
6
|
-
if (value === null || value === void 0)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (typeof value === "
|
|
6
|
+
if (value === null || value === void 0) {
|
|
7
|
+
return "unknown";
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === "string") {
|
|
10
|
+
return "string";
|
|
11
|
+
}
|
|
12
|
+
if (typeof value === "number") {
|
|
13
|
+
return "number";
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === "boolean") {
|
|
16
|
+
return "boolean";
|
|
17
|
+
}
|
|
10
18
|
if (Array.isArray(value)) {
|
|
11
|
-
if (value.length === 0)
|
|
19
|
+
if (value.length === 0) {
|
|
20
|
+
return "unknown[]";
|
|
21
|
+
}
|
|
12
22
|
const types = [...new Set(value.map(inferType))];
|
|
13
23
|
return types.length === 1 ? `${types[0]}[]` : `(${types.join(" | ")})[]`;
|
|
14
24
|
}
|
|
15
25
|
if (typeof value === "object") {
|
|
16
26
|
const entries = Object.entries(value);
|
|
17
|
-
if (entries.length === 0)
|
|
27
|
+
if (entries.length === 0) {
|
|
28
|
+
return "Record<string, unknown>";
|
|
29
|
+
}
|
|
18
30
|
const fields = entries.map(([k, v]) => `${k}: ${inferType(v)}`).join("; ");
|
|
19
31
|
return `{ ${fields} }`;
|
|
20
32
|
}
|
|
@@ -26,8 +38,11 @@ async function scanFiles(dir) {
|
|
|
26
38
|
const entries = await readdir(current, { withFileTypes: true });
|
|
27
39
|
for (const entry of entries) {
|
|
28
40
|
const full = join(current, entry.name);
|
|
29
|
-
if (entry.isDirectory())
|
|
30
|
-
|
|
41
|
+
if (entry.isDirectory()) {
|
|
42
|
+
await walk(full);
|
|
43
|
+
} else if (entry.name.endsWith(".mdx")) {
|
|
44
|
+
paths.push(full);
|
|
45
|
+
}
|
|
31
46
|
}
|
|
32
47
|
}
|
|
33
48
|
await walk(dir);
|
|
@@ -40,9 +55,11 @@ async function generateTypes(config) {
|
|
|
40
55
|
const fieldCounts = /* @__PURE__ */ new Map();
|
|
41
56
|
let total = 0;
|
|
42
57
|
for (const file of files) {
|
|
43
|
-
const source = await readFile(file, "
|
|
58
|
+
const source = await readFile(file, "utf8");
|
|
44
59
|
const { data } = matter(source);
|
|
45
|
-
if (!data || typeof data !== "object")
|
|
60
|
+
if (!data || typeof data !== "object") {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
46
63
|
total++;
|
|
47
64
|
for (const [key, value] of Object.entries(data)) {
|
|
48
65
|
const type = inferType(value);
|
|
@@ -56,7 +73,9 @@ async function generateTypes(config) {
|
|
|
56
73
|
}
|
|
57
74
|
}
|
|
58
75
|
const lines = [`export interface ${name} {`];
|
|
59
|
-
const sorted = [...fieldTypes.entries()].sort(
|
|
76
|
+
const sorted = [...fieldTypes.entries()].sort(
|
|
77
|
+
([a], [b]) => a.localeCompare(b)
|
|
78
|
+
);
|
|
60
79
|
for (const [key, types] of sorted) {
|
|
61
80
|
const optional = (fieldCounts.get(key) ?? 0) < total;
|
|
62
81
|
const union = [...types].join(" | ");
|
|
@@ -68,7 +87,7 @@ async function generateTypes(config) {
|
|
|
68
87
|
}
|
|
69
88
|
async function writeTypes(config) {
|
|
70
89
|
const content = await generateTypes(config);
|
|
71
|
-
await writeFile(config.output, content, "
|
|
90
|
+
await writeFile(config.output, content, "utf8");
|
|
72
91
|
}
|
|
73
92
|
|
|
74
93
|
export { generateTypes, inferType, writeTypes };
|
package/dist/validate.js
CHANGED
|
@@ -18,22 +18,28 @@ async function validateLinks(options) {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
async function scanFile(filepath, relativePath) {
|
|
21
|
-
const content = await readFile(filepath, "
|
|
21
|
+
const content = await readFile(filepath, "utf8");
|
|
22
22
|
const lines = content.split("\n");
|
|
23
23
|
const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
24
24
|
const hrefRegex = /href=["']([^"']+)["']/g;
|
|
25
25
|
for (let i = 0; i < lines.length; i++) {
|
|
26
26
|
const line = lines[i];
|
|
27
|
-
if (line === void 0)
|
|
27
|
+
if (line === void 0) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
28
30
|
let match;
|
|
29
31
|
while ((match = linkRegex.exec(line)) !== null) {
|
|
30
32
|
const link = match[2];
|
|
31
|
-
if (!link)
|
|
33
|
+
if (!link) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
32
36
|
checkLink(link, relativePath, i + 1, issues, validSlugs, checkExternal);
|
|
33
37
|
}
|
|
34
38
|
while ((match = hrefRegex.exec(line)) !== null) {
|
|
35
39
|
const link = match[1];
|
|
36
|
-
if (!link)
|
|
40
|
+
if (!link) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
37
43
|
checkLink(link, relativePath, i + 1, issues, validSlugs, checkExternal);
|
|
38
44
|
}
|
|
39
45
|
}
|
|
@@ -53,9 +59,15 @@ async function validateLinks(options) {
|
|
|
53
59
|
return issues;
|
|
54
60
|
}
|
|
55
61
|
function checkLink(link, file, line, issues, validSlugs, checkExternal) {
|
|
56
|
-
if (link.startsWith("#"))
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
if (link.startsWith("#")) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (link.startsWith("mailto:")) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (link.startsWith("tel:")) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
59
71
|
if (link.startsWith("http://") || link.startsWith("https://")) {
|
|
60
72
|
if (checkExternal) {
|
|
61
73
|
issues.push({ file, line, link, type: "external" });
|