valaxy 0.26.1 → 0.26.3

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.
@@ -5,7 +5,7 @@ import path$1, { join, dirname, resolve } from 'node:path';
5
5
  import { consola } from 'consola';
6
6
  import { colors } from 'consola/utils';
7
7
  import fg from 'fast-glob';
8
- import fs, { ensureFile } from 'fs-extra';
8
+ import fs from 'fs-extra';
9
9
  import matter from 'gray-matter';
10
10
  import { ensurePrefix, slash, uniq, objectEntries, isObject, isFunction, ensureSuffix } from '@antfu/utils';
11
11
  import _debug from 'debug';
@@ -19,8 +19,8 @@ import ora from 'ora';
19
19
  import { spawn } from 'cross-spawn';
20
20
  import { resolvePath } from 'mlly';
21
21
  import { resolveGlobal } from 'resolve-global';
22
- import { writeFile, readFile } from 'node:fs/promises';
23
22
  import yaml, { CORE_SCHEMA } from 'js-yaml';
23
+ import { readFile } from 'node:fs/promises';
24
24
  import dayjs from 'dayjs';
25
25
  import { Feed } from 'feed';
26
26
  import MarkdownIt from 'markdown-it';
@@ -98,6 +98,49 @@ const customElements = /* @__PURE__ */ new Set([
98
98
  ]);
99
99
  const defaultViteConfig = {};
100
100
 
101
+ function getKeyMaterial(password) {
102
+ const enc = new TextEncoder();
103
+ return webcrypto.subtle.importKey(
104
+ "raw",
105
+ enc.encode(password),
106
+ "PBKDF2",
107
+ false,
108
+ ["deriveBits", "deriveKey"]
109
+ );
110
+ }
111
+ function getCryptoDeriveKey(keyMaterial, salt) {
112
+ return webcrypto.subtle.deriveKey(
113
+ {
114
+ name: "PBKDF2",
115
+ salt,
116
+ iterations: 1e5,
117
+ hash: "SHA-256"
118
+ },
119
+ keyMaterial,
120
+ {
121
+ name: "AES-CBC",
122
+ length: 256
123
+ },
124
+ true,
125
+ ["encrypt", "decrypt"]
126
+ );
127
+ }
128
+ async function encryptContent(content, options) {
129
+ const { password, iv, salt } = options;
130
+ const keyMaterial = await getKeyMaterial(password);
131
+ const key = await getCryptoDeriveKey(keyMaterial, salt);
132
+ const enc = new TextEncoder();
133
+ const ciphertextData = await webcrypto.subtle.encrypt(
134
+ {
135
+ name: "AES-CBC",
136
+ iv
137
+ },
138
+ key,
139
+ enc.encode(content)
140
+ );
141
+ return String.fromCharCode(...new Uint8Array(ciphertextData));
142
+ }
143
+
101
144
  function getGitTimestamp(file, type = "updated") {
102
145
  return new Promise((resolve, _reject) => {
103
146
  const params = ["log"];
@@ -363,7 +406,6 @@ async function getAlias(options) {
363
406
  { find: /^valaxy$/, replacement: toAtFS(resolve(options.clientRoot, "index.ts")) },
364
407
  { find: "@valaxyjs/client/", replacement: `${toAtFS(options.clientRoot)}/` },
365
408
  // import theme
366
- { find: "virtual:valaxy-theme", replacement: `${toAtFS(options.themeRoot)}/client/index.ts` },
367
409
  { find: `valaxy-theme-${options.theme}/client`, replacement: `${toAtFS(resolve(options.themeRoot))}/client/index.ts` },
368
410
  { find: `valaxy-theme-${options.theme}/`, replacement: `${toAtFS(resolve(options.themeRoot))}/` },
369
411
  { find: `valaxy-theme-${options.theme}`, replacement: `${toAtFS(resolve(options.themeRoot))}/client/index.ts` }
@@ -584,292 +626,293 @@ The language '${lang}' is not loaded, falling back to '${defaultLang}' for synta
584
626
  ];
585
627
  }
586
628
 
629
+ //#region src/html-escape.ts
587
630
  const htmlEscapeMap = {
588
- "&": "&",
589
- "<": "&lt;",
590
- ">": "&gt;",
591
- "'": "&#39;",
592
- '"': "&quot;"
631
+ "&": "&amp;",
632
+ "<": "&lt;",
633
+ ">": "&gt;",
634
+ "'": "&#39;",
635
+ "\"": "&quot;"
593
636
  };
594
637
  const htmlEscapeRegexp = /[&<>'"]/g;
595
- const htmlEscape = (str) => str.replace(
596
- htmlEscapeRegexp,
597
- (char) => htmlEscapeMap[char]
598
- );
638
+ /**
639
+ * Escape html chars
640
+ */
641
+ const htmlEscape = (str) => str.replace(htmlEscapeRegexp, (char) => htmlEscapeMap[char]);
599
642
 
643
+ //#endregion
644
+ //#region src/resolve-title-from-token.ts
645
+ /**
646
+ * Resolve header title from markdown-it token
647
+ *
648
+ * Typically using the next token of `heading_open` token
649
+ */
600
650
  const resolveTitleFromToken = (token, { shouldAllowHtml, shouldEscapeText }) => {
601
- const children = token.children ?? [];
602
- const titleTokenTypes = ["text", "emoji", "code_inline"];
603
- if (shouldAllowHtml) {
604
- titleTokenTypes.push("html_inline");
605
- }
606
- const titleTokens = children.filter(
607
- (item) => titleTokenTypes.includes(item.type) && // filter permalink symbol that generated by markdown-it-anchor
608
- !item.meta?.isPermalinkSymbol
609
- );
610
- return titleTokens.reduce((result, item) => {
611
- if (shouldEscapeText) {
612
- if (item.type === "code_inline" || item.type === "text") {
613
- return `${result}${htmlEscape(item.content)}`;
614
- }
615
- }
616
- return `${result}${item.content}`;
617
- }, "").trim();
651
+ const children = token.children ?? [];
652
+ const titleTokenTypes = [
653
+ "text",
654
+ "emoji",
655
+ "code_inline"
656
+ ];
657
+ if (shouldAllowHtml) titleTokenTypes.push("html_inline");
658
+ const titleTokens = children.filter((item) => titleTokenTypes.includes(item.type) && !item.meta?.isPermalinkSymbol);
659
+ return titleTokens.reduce((result, item) => {
660
+ if (shouldEscapeText) {
661
+ if (item.type === "code_inline" || item.type === "text") return `${result}${htmlEscape(item.content)}`;
662
+ }
663
+ return `${result}${item.content}`;
664
+ }, "").trim();
618
665
  };
619
666
 
620
- const resolveHeadersFromTokens = (tokens, {
621
- level,
622
- shouldAllowHtml,
623
- shouldAllowNested,
624
- shouldEscapeText,
625
- slugify,
626
- format
627
- }) => {
628
- const headers = [];
629
- const stack = [];
630
- const push = (header) => {
631
- while (stack.length !== 0 && header.level <= stack[0].level) {
632
- stack.shift();
633
- }
634
- if (stack.length === 0) {
635
- headers.push(header);
636
- stack.push(header);
637
- } else {
638
- stack[0].children.push(header);
639
- stack.unshift(header);
640
- }
641
- };
642
- for (let i = 0; i < tokens.length; i += 1) {
643
- const token = tokens[i];
644
- if (token.type !== "heading_open") {
645
- continue;
646
- }
647
- if (token.level !== 0 && !shouldAllowNested) {
648
- continue;
649
- }
650
- const headerLevel = Number.parseInt(token.tag.slice(1), 10);
651
- if (!level.includes(headerLevel)) {
652
- continue;
653
- }
654
- const nextToken = tokens[i + 1];
655
- /* istanbul ignore if -- @preserve */
656
- if (!nextToken) {
657
- continue;
658
- }
659
- const title = resolveTitleFromToken(nextToken, {
660
- shouldAllowHtml,
661
- shouldEscapeText
662
- });
663
- const slug = token.attrGet("id") ?? slugify(title);
664
- push({
665
- level: headerLevel,
666
- title: format?.(title) ?? title,
667
- slug,
668
- link: `#${slug}`,
669
- children: []
670
- });
671
- }
672
- return headers;
667
+ //#endregion
668
+ //#region src/resolve-headers-from-tokens.ts
669
+ /**
670
+ * Resolve headers from markdown-it tokens
671
+ */
672
+ const resolveHeadersFromTokens = (tokens, { level, shouldAllowHtml, shouldAllowNested, shouldEscapeText, slugify: slugify$1, format }) => {
673
+ const headers = [];
674
+ const stack = [];
675
+ const push = (header) => {
676
+ while (stack.length !== 0 && header.level <= stack[0].level) stack.shift();
677
+ if (stack.length === 0) {
678
+ headers.push(header);
679
+ stack.push(header);
680
+ } else {
681
+ stack[0].children.push(header);
682
+ stack.unshift(header);
683
+ }
684
+ };
685
+ for (let i = 0; i < tokens.length; i += 1) {
686
+ const token = tokens[i];
687
+ if (token.type !== "heading_open") continue;
688
+ if (token.level !== 0 && !shouldAllowNested) continue;
689
+ const headerLevel = Number.parseInt(token.tag.slice(1), 10);
690
+ if (!level.includes(headerLevel)) continue;
691
+ const nextToken = tokens[i + 1];
692
+ /* istanbul ignore if -- @preserve */
693
+ if (!nextToken) continue;
694
+ const title = resolveTitleFromToken(nextToken, {
695
+ shouldAllowHtml,
696
+ shouldEscapeText
697
+ });
698
+ const slug = token.attrGet("id") ?? slugify$1(title);
699
+ push({
700
+ level: headerLevel,
701
+ title: format?.(title) ?? title,
702
+ slug,
703
+ link: `#${slug}`,
704
+ children: []
705
+ });
706
+ }
707
+ return headers;
673
708
  };
674
709
 
710
+ //#endregion
711
+ //#region src/slugify.ts
675
712
  const rControl = /[\u0000-\u001f]/g;
676
713
  const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
677
714
  const rCombining = /[\u0300-\u036F]/g;
715
+ /**
716
+ * Default slugification function
717
+ */
678
718
  const slugify = (str) => str.normalize("NFKD").replace(rCombining, "").replace(rControl, "").replace(rSpecial, "-").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "").replace(/^(\d)/, "_$1").toLowerCase();
679
719
 
680
- const headersPlugin = (md, {
681
- level = [2, 3],
682
- shouldAllowNested = false,
683
- slugify: slugify$1 = slugify,
684
- format
685
- } = {}) => {
686
- const render = md.renderer.render.bind(md.renderer);
687
- md.renderer.render = (tokens, options, env) => {
688
- env.headers = resolveHeadersFromTokens(tokens, {
689
- level,
690
- shouldAllowHtml: false,
691
- shouldAllowNested,
692
- shouldEscapeText: false,
693
- slugify: slugify$1,
694
- format
695
- });
696
- return render(tokens, options, env);
697
- };
720
+ //#region src/headers-plugin.ts
721
+ /**
722
+ * Get markdown headers info
723
+ *
724
+ * Extract them into env
725
+ */
726
+ const headersPlugin = (md, { level = [2, 3], shouldAllowNested = false, slugify: slugify$1 = slugify, format } = {}) => {
727
+ const render = md.renderer.render.bind(md.renderer);
728
+ md.renderer.render = (tokens, options, env) => {
729
+ env.headers = resolveHeadersFromTokens(tokens, {
730
+ level,
731
+ shouldAllowHtml: false,
732
+ shouldAllowNested,
733
+ shouldEscapeText: false,
734
+ slugify: slugify$1,
735
+ format
736
+ });
737
+ return render(tokens, options, env);
738
+ };
698
739
  };
699
740
 
741
+ //#region src/constants.ts
700
742
  const TAG_NAME_SCRIPT = "script";
701
743
  const TAG_NAME_STYLE = "style";
702
744
  const TAG_NAME_TEMPLATE = "template";
703
745
 
746
+ //#endregion
747
+ //#region src/sfc-regexp.ts
704
748
  const SCRIPT_SETUP_TAG_OPEN_REGEXP = /^<script\s+.*?\bsetup\b.*?>$/is;
705
- const createSfcRegexp = ({
706
- customBlocks
707
- }) => {
708
- const sfcTags = Array.from(
709
- /* @__PURE__ */ new Set([TAG_NAME_SCRIPT, TAG_NAME_STYLE, ...customBlocks])
710
- ).join("|");
711
- return new RegExp(
712
- `^\\s*(?<content>(?<tagOpen><(?<type>${sfcTags})\\s?.*?>)(?<contentStripped>.*)(?<tagClose><\\/\\k<type>\\s*>))\\s*$`,
713
- "is"
714
- );
749
+ /**
750
+ * Generate RegExp for sfc blocks
751
+ */
752
+ const createSfcRegexp = ({ customBlocks }) => {
753
+ const sfcTags = Array.from(new Set([
754
+ TAG_NAME_SCRIPT,
755
+ TAG_NAME_STYLE,
756
+ ...customBlocks
757
+ ])).join("|");
758
+ return new RegExp(`^\\s*(?<content>(?<tagOpen><(?<type>${sfcTags})\\s?.*?>)(?<contentStripped>.*)(?<tagClose><\\/\\k<type>\\s*>))\\s*$`, "is");
715
759
  };
716
760
 
761
+ //#endregion
762
+ //#region src/sfc-plugin.ts
763
+ /**
764
+ * Get Vue SFC blocks
765
+ *
766
+ * Extract them into env and avoid rendering them
767
+ */
717
768
  const sfcPlugin = (md, { customBlocks = [] } = {}) => {
718
- const sfcRegexp = createSfcRegexp({ customBlocks });
719
- const render = md.render.bind(md);
720
- md.render = (src, env = {}) => {
721
- env.sfcBlocks = {
722
- template: null,
723
- script: null,
724
- scriptSetup: null,
725
- scripts: [],
726
- styles: [],
727
- customBlocks: []
728
- };
729
- const rendered = render(src, env);
730
- env.sfcBlocks.template = {
731
- type: TAG_NAME_TEMPLATE,
732
- content: `<${TAG_NAME_TEMPLATE}>${rendered}</${TAG_NAME_TEMPLATE}>`,
733
- contentStripped: rendered,
734
- tagOpen: `<${TAG_NAME_TEMPLATE}>`,
735
- tagClose: `</${TAG_NAME_TEMPLATE}>`
736
- };
737
- return rendered;
738
- };
739
- const htmlBlockRule = md.renderer.rules.html_block;
740
- md.renderer.rules.html_block = (tokens, idx, options, env, self) => {
741
- /* istanbul ignore if -- @preserve */
742
- if (!env.sfcBlocks) {
743
- return htmlBlockRule(tokens, idx, options, env, self);
744
- }
745
- const token = tokens[idx];
746
- const content = token.content;
747
- const match = content.match(sfcRegexp);
748
- if (!match) {
749
- return htmlBlockRule(tokens, idx, options, env, self);
750
- }
751
- const sfcBlock = match.groups;
752
- if (sfcBlock.type === TAG_NAME_SCRIPT) {
753
- env.sfcBlocks.scripts.push(sfcBlock);
754
- if (SCRIPT_SETUP_TAG_OPEN_REGEXP.test(sfcBlock.tagOpen)) {
755
- env.sfcBlocks.scriptSetup = sfcBlock;
756
- } else {
757
- env.sfcBlocks.script = sfcBlock;
758
- }
759
- } else if (sfcBlock.type === TAG_NAME_STYLE) {
760
- env.sfcBlocks.styles.push(sfcBlock);
761
- } else {
762
- env.sfcBlocks.customBlocks.push(sfcBlock);
763
- }
764
- return "";
765
- };
769
+ const sfcRegexp = createSfcRegexp({ customBlocks });
770
+ const render = md.render.bind(md);
771
+ md.render = (src, env = {}) => {
772
+ env.sfcBlocks = {
773
+ template: null,
774
+ script: null,
775
+ scriptSetup: null,
776
+ scripts: [],
777
+ styles: [],
778
+ customBlocks: []
779
+ };
780
+ const rendered = render(src, env);
781
+ env.sfcBlocks.template = {
782
+ type: TAG_NAME_TEMPLATE,
783
+ content: `<${TAG_NAME_TEMPLATE}>${rendered}</${TAG_NAME_TEMPLATE}>`,
784
+ contentStripped: rendered,
785
+ tagOpen: `<${TAG_NAME_TEMPLATE}>`,
786
+ tagClose: `</${TAG_NAME_TEMPLATE}>`
787
+ };
788
+ return rendered;
789
+ };
790
+ const htmlBlockRule = md.renderer.rules.html_block;
791
+ md.renderer.rules.html_block = (tokens, idx, options, env, self) => {
792
+ /* istanbul ignore if -- @preserve */
793
+ if (!env.sfcBlocks) return htmlBlockRule(tokens, idx, options, env, self);
794
+ const token = tokens[idx];
795
+ const content = token.content;
796
+ const match = content.match(sfcRegexp);
797
+ if (!match) return htmlBlockRule(tokens, idx, options, env, self);
798
+ const sfcBlock = match.groups;
799
+ if (sfcBlock.type === TAG_NAME_SCRIPT) {
800
+ env.sfcBlocks.scripts.push(sfcBlock);
801
+ if (SCRIPT_SETUP_TAG_OPEN_REGEXP.test(sfcBlock.tagOpen)) env.sfcBlocks.scriptSetup = sfcBlock;
802
+ else env.sfcBlocks.script = sfcBlock;
803
+ } else if (sfcBlock.type === TAG_NAME_STYLE) env.sfcBlocks.styles.push(sfcBlock);
804
+ else env.sfcBlocks.customBlocks.push(sfcBlock);
805
+ return "";
806
+ };
766
807
  };
767
808
 
809
+ //#region src/title-plugin.ts
810
+ /**
811
+ * Get markdown page title info
812
+ *
813
+ * Extract it into env
814
+ */
768
815
  const titlePlugin = (md) => {
769
- const render = md.renderer.render.bind(md.renderer);
770
- md.renderer.render = (tokens, options, env) => {
771
- const tokenIdx = tokens.findIndex((token) => token.tag === "h1");
772
- env.title = tokenIdx > -1 ? resolveTitleFromToken(tokens[tokenIdx + 1], {
773
- shouldAllowHtml: false,
774
- shouldEscapeText: false
775
- }) : "";
776
- return render(tokens, options, env);
777
- };
816
+ const render = md.renderer.render.bind(md.renderer);
817
+ md.renderer.render = (tokens, options, env) => {
818
+ const tokenIdx = tokens.findIndex((token) => token.tag === "h1");
819
+ env.title = tokenIdx > -1 ? resolveTitleFromToken(tokens[tokenIdx + 1], {
820
+ shouldAllowHtml: false,
821
+ shouldEscapeText: false
822
+ }) : "";
823
+ return render(tokens, options, env);
824
+ };
778
825
  };
779
826
 
780
- const createRenderHeaders = ({
781
- listTag,
782
- listClass,
783
- itemClass,
784
- linkTag,
785
- linkClass
786
- }) => {
787
- const listTagString = htmlEscape(listTag);
788
- const listClassString = listClass ? ` class="${htmlEscape(listClass)}"` : "";
789
- const itemTagString = "li";
790
- const itemClassString = itemClass ? ` class="${htmlEscape(itemClass)}"` : "";
791
- const linkTagString = htmlEscape(linkTag);
792
- const linkClassString = linkClass ? ` class="${htmlEscape(linkClass)}"` : "";
793
- const linkTo = (link) => linkTag === "router-link" ? ` to="${link}"` : ` href="${link}"`;
794
- const renderHeaders = (headers) => `<${listTagString}${listClassString}>${headers.map(
795
- (header) => `<${itemTagString}${itemClassString}><${linkTagString}${linkClassString}${linkTo(header.link)}>${header.title}</${linkTagString}>${header.children.length > 0 ? renderHeaders(header.children) : ""}</${itemTagString}>`
796
- ).join("")}</${listTagString}>`;
797
- return renderHeaders;
827
+ //#region src/create-render-headers.ts
828
+ const createRenderHeaders = ({ listTag, listClass, itemClass, linkTag, linkClass }) => {
829
+ const listTagString = htmlEscape(listTag);
830
+ const listClassString = listClass ? ` class="${htmlEscape(listClass)}"` : "";
831
+ const itemTagString = "li";
832
+ const itemClassString = itemClass ? ` class="${htmlEscape(itemClass)}"` : "";
833
+ const linkTagString = htmlEscape(linkTag);
834
+ const linkClassString = linkClass ? ` class="${htmlEscape(linkClass)}"` : "";
835
+ const linkTo = (link) => linkTag === "router-link" ? ` to="${link}"` : ` href="${link}"`;
836
+ const renderHeaders = (headers) => `\
837
+ <${listTagString}${listClassString}>\
838
+ ${headers.map((header) => `\
839
+ <${itemTagString}${itemClassString}>\
840
+ <${linkTagString}${linkClassString}${linkTo(header.link)}>\
841
+ ${header.title}\
842
+ </${linkTagString}>\
843
+ ${header.children.length > 0 ? renderHeaders(header.children) : ""}\
844
+ </${itemTagString}>\
845
+ `).join("")}\
846
+ </${listTagString}>`;
847
+ return renderHeaders;
798
848
  };
799
849
 
800
- const createTocBlockRule = ({
801
- pattern,
802
- containerTag,
803
- containerClass
804
- }) => (state, startLine, endLine, silent) => {
805
- if (state.sCount[startLine] - state.blkIndent >= 4) {
806
- return false;
807
- }
808
- const pos = state.bMarks[startLine] + state.tShift[startLine];
809
- const max = state.eMarks[startLine];
810
- const lineFirstToken = state.src.slice(pos, max).split(" ")[0];
811
- if (!pattern.test(lineFirstToken)) return false;
812
- if (silent) return true;
813
- state.line = startLine + 1;
814
- const tokenOpen = state.push("toc_open", containerTag, 1);
815
- tokenOpen.markup = "";
816
- tokenOpen.map = [startLine, state.line];
817
- if (containerClass) {
818
- tokenOpen.attrSet("class", containerClass);
819
- }
820
- const tokenBody = state.push("toc_body", "", 0);
821
- tokenBody.markup = lineFirstToken;
822
- tokenBody.map = [startLine, state.line];
823
- tokenBody.hidden = true;
824
- const tokenClose = state.push("toc_close", containerTag, -1);
825
- tokenClose.markup = "";
826
- tokenBody.map = [startLine, state.line];
827
- return true;
850
+ //#endregion
851
+ //#region src/create-toc-block-rule.ts
852
+ /**
853
+ * Forked and modified from markdown-it-toc-done-right
854
+ *
855
+ * - remove the `inlineOptions` support
856
+ * - use markdown-it default renderer to render token whenever possible
857
+ *
858
+ * @see https://github.com/nagaozen/markdown-it-toc-done-right
859
+ */
860
+ const createTocBlockRule = ({ pattern, containerTag, containerClass }) => (state, startLine, endLine, silent) => {
861
+ if (state.sCount[startLine] - state.blkIndent >= 4) return false;
862
+ const pos = state.bMarks[startLine] + state.tShift[startLine];
863
+ const max = state.eMarks[startLine];
864
+ const lineFirstToken = state.src.slice(pos, max).split(" ")[0];
865
+ if (!pattern.test(lineFirstToken)) return false;
866
+ if (silent) return true;
867
+ state.line = startLine + 1;
868
+ const tokenOpen = state.push("toc_open", containerTag, 1);
869
+ tokenOpen.markup = "";
870
+ tokenOpen.map = [startLine, state.line];
871
+ if (containerClass) tokenOpen.attrSet("class", containerClass);
872
+ const tokenBody = state.push("toc_body", "", 0);
873
+ tokenBody.markup = lineFirstToken;
874
+ tokenBody.map = [startLine, state.line];
875
+ tokenBody.hidden = true;
876
+ const tokenClose = state.push("toc_close", containerTag, -1);
877
+ tokenClose.markup = "";
878
+ tokenBody.map = [startLine, state.line];
879
+ return true;
828
880
  };
829
881
 
830
- const tocPlugin = (md, {
831
- pattern = /^\[\[toc\]\]$/i,
832
- slugify: slugify$1 = slugify,
833
- format,
834
- level = [2, 3],
835
- shouldAllowNested = false,
836
- containerTag = "nav",
837
- containerClass = "table-of-contents",
838
- listTag = "ul",
839
- listClass = "",
840
- itemClass = "",
841
- linkTag = "a",
842
- linkClass = ""
843
- } = {}) => {
844
- md.block.ruler.before(
845
- "heading",
846
- "toc",
847
- createTocBlockRule({
848
- pattern,
849
- containerTag,
850
- containerClass
851
- }),
852
- {
853
- alt: ["paragraph", "reference", "blockquote"]
854
- }
855
- );
856
- const renderHeaders = createRenderHeaders({
857
- listTag,
858
- listClass,
859
- itemClass,
860
- linkTag,
861
- linkClass
862
- });
863
- md.renderer.rules.toc_body = (tokens) => renderHeaders(
864
- resolveHeadersFromTokens(tokens, {
865
- level,
866
- shouldAllowHtml: true,
867
- shouldAllowNested,
868
- shouldEscapeText: true,
869
- slugify: slugify$1,
870
- format
871
- })
872
- );
882
+ //#endregion
883
+ //#region src/toc-plugin.ts
884
+ /**
885
+ * Generate table of contents
886
+ *
887
+ * Forked and modified from markdown-it-toc-done-right:
888
+ *
889
+ * @see https://github.com/nagaozen/markdown-it-toc-done-right
890
+ */
891
+ const tocPlugin = (md, { pattern = /^\[\[toc\]\]$/i, slugify: slugify$1 = slugify, format, level = [2, 3], shouldAllowNested = false, containerTag = "nav", containerClass = "table-of-contents", listTag = "ul", listClass = "", itemClass = "", linkTag = "a", linkClass = "" } = {}) => {
892
+ md.block.ruler.before("heading", "toc", createTocBlockRule({
893
+ pattern,
894
+ containerTag,
895
+ containerClass
896
+ }), { alt: [
897
+ "paragraph",
898
+ "reference",
899
+ "blockquote"
900
+ ] });
901
+ const renderHeaders = createRenderHeaders({
902
+ listTag,
903
+ listClass,
904
+ itemClass,
905
+ linkTag,
906
+ linkClass
907
+ });
908
+ md.renderer.rules.toc_body = (tokens) => renderHeaders(resolveHeadersFromTokens(tokens, {
909
+ level,
910
+ shouldAllowHtml: true,
911
+ shouldAllowNested,
912
+ shouldEscapeText: true,
913
+ slugify: slugify$1,
914
+ format
915
+ }));
873
916
  };
874
917
 
875
918
  const indexRE = /(^|.*\/)index.md(.*)$/i;
@@ -1524,7 +1567,7 @@ async function setupMarkdownPlugins(md, options, base = "/") {
1524
1567
  return md;
1525
1568
  }
1526
1569
 
1527
- const version = "0.26.1";
1570
+ const version = "0.26.3";
1528
1571
 
1529
1572
  const GLOBAL_STATE = {
1530
1573
  valaxyApp: void 0,
@@ -2359,8 +2402,8 @@ function collectRedirects(redirectRules) {
2359
2402
  return redirects;
2360
2403
  }
2361
2404
  async function writeRedirectFiles(route, filePath) {
2362
- await ensureFile(filePath);
2363
- await writeFile(filePath, `
2405
+ await fs.ensureFile(filePath);
2406
+ await fs.writeFile(filePath, `
2364
2407
  <!DOCTYPE html>
2365
2408
  <html lang="en">
2366
2409
  <head>
@@ -2742,49 +2785,6 @@ function createScanDeadLinks(options) {
2742
2785
  };
2743
2786
  }
2744
2787
 
2745
- function getKeyMaterial(password) {
2746
- const enc = new TextEncoder();
2747
- return webcrypto.subtle.importKey(
2748
- "raw",
2749
- enc.encode(password),
2750
- "PBKDF2",
2751
- false,
2752
- ["deriveBits", "deriveKey"]
2753
- );
2754
- }
2755
- function getKey(keyMaterial, salt) {
2756
- return webcrypto.subtle.deriveKey(
2757
- {
2758
- name: "PBKDF2",
2759
- salt,
2760
- iterations: 1e5,
2761
- hash: "SHA-256"
2762
- },
2763
- keyMaterial,
2764
- {
2765
- name: "AES-CBC",
2766
- length: 256
2767
- },
2768
- true,
2769
- ["encrypt", "decrypt"]
2770
- );
2771
- }
2772
- async function encryptContent(content, options) {
2773
- const { password, iv, salt } = options;
2774
- const keyMaterial = await getKeyMaterial(password);
2775
- const key = await getKey(keyMaterial, salt);
2776
- const enc = new TextEncoder();
2777
- const ciphertextData = await webcrypto.subtle.encrypt(
2778
- {
2779
- name: "AES-CBC",
2780
- iv
2781
- },
2782
- key,
2783
- enc.encode(content)
2784
- );
2785
- return String.fromCharCode(...new Uint8Array(ciphertextData));
2786
- }
2787
-
2788
2788
  function createTransformEncrypt(options) {
2789
2789
  const { config: { siteConfig: { encrypt } } } = options;
2790
2790
  return async (code, id, pageData) => {
@@ -4538,4 +4538,4 @@ function run() {
4538
4538
  cli.parse();
4539
4539
  }
4540
4540
 
4541
- export { mergeValaxyConfig as A, resolveValaxyConfig as B, ALL_ROUTE as C, customElements as D, EXCERPT_SEPARATOR as E, defaultViteConfig as F, GLOBAL_STATE as G, version as H, processValaxyOptions as I, resolveOptions as J, resolveThemeValaxyConfig as K, createValaxyPlugin as L, getServerInfoText as M, createServer as N, getGitTimestamp as O, PATHNAME_PROTOCOL_RE as P, isExternal as Q, isPath as R, transformObject as S, isInstalledGlobally as T, resolveImportUrl as U, ViteValaxyPlugins as V, toAtFS as W, resolveImportPath as X, startValaxyDev as a, build$1 as b, cli as c, registerDevCommand as d, getIndexHtml as e, defineValaxyAddon as f, generateClientRedirects as g, defineAddon as h, resolveAddonsConfig as i, defaultSiteConfig as j, defineSiteConfig as k, resolveSiteConfigFromRoot as l, mergeViteConfigs as m, resolveSiteConfig as n, resolveThemeConfigFromRoot as o, postProcessForSSG as p, resolveUserThemeConfig as q, run as r, ssgBuild as s, defineValaxyTheme as t, defineTheme as u, loadConfigFromFile as v, defaultValaxyConfig as w, defineValaxyConfig as x, defineConfig as y, resolveValaxyConfigFromRoot as z };
4541
+ export { mergeValaxyConfig as A, resolveValaxyConfig as B, ALL_ROUTE as C, customElements as D, EXCERPT_SEPARATOR as E, defaultViteConfig as F, GLOBAL_STATE as G, version as H, processValaxyOptions as I, resolveOptions as J, resolveThemeValaxyConfig as K, createValaxyPlugin as L, getServerInfoText as M, createServer as N, encryptContent as O, PATHNAME_PROTOCOL_RE as P, getGitTimestamp as Q, isExternal as R, isPath as S, transformObject as T, isInstalledGlobally as U, ViteValaxyPlugins as V, resolveImportUrl as W, toAtFS as X, resolveImportPath as Y, startValaxyDev as a, build$1 as b, cli as c, registerDevCommand as d, getIndexHtml as e, defineValaxyAddon as f, generateClientRedirects as g, defineAddon as h, resolveAddonsConfig as i, defaultSiteConfig as j, defineSiteConfig as k, resolveSiteConfigFromRoot as l, mergeViteConfigs as m, resolveSiteConfig as n, resolveThemeConfigFromRoot as o, postProcessForSSG as p, resolveUserThemeConfig as q, run as r, ssgBuild as s, defineValaxyTheme as t, defineTheme as u, loadConfigFromFile as v, defaultValaxyConfig as w, defineValaxyConfig as x, defineConfig as y, resolveValaxyConfigFromRoot as z };