vitepress-linkcard 1.3.0 → 2.0.1

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
@@ -6,18 +6,18 @@ vitepress-linkcard
6
6
 
7
7
  **A VitePress plugin to generate a pretty linkcard with OGP.**
8
8
 
9
- A blog generated with this plugin is [here](https://asumoranda.com/posts/10-vitepress-linkcard.html).
9
+ You can see: [A blog generated with this plugin](https://asumoranda.com/posts/10-vitepress-linkcard.html) | [Docs by TypeDoc](https://asumo-1xts.github.io/vitepress-linkcard/)
10
10
 
11
11
  [![NPM Version](https://img.shields.io/npm/v/vitepress-linkcard?style=flat&logo=npm&logoColor=white&label=npmjs&color=%23CB3837)](https://www.npmjs.com/package/vitepress-linkcard)
12
12
  [![NPM bundle size](https://img.shields.io/bundlephobia/min/vitepress-linkcard)](https://www.npmjs.com/package/vitepress-linkcard)
13
+ [![VitePress](https://img.shields.io/badge/For_VitePress-v1_|_v2-%235C73E7?logo=vitepress&logoColor=white)](https://vuejs.github.io/vitepress/v1]/)
13
14
  [![NPM License](https://img.shields.io/npm/l/vitepress-linkcard)](/LICENSE)
14
15
 
15
- [![VitePress](https://img.shields.io/badge/For_VitePress-v1.6.4-%235C73E7?logo=vitepress&logoColor=white)](https://vuejs.github.io/vitepress/v1/)
16
16
  [![Yarn](https://img.shields.io/badge/Built_with_Yarn-v4.9.2-%232C8EBB?logo=yarn&logoColor=white)](https://yarnpkg.com/)
17
17
  [![ESLint](https://img.shields.io/badge/Lint_with-ESLint-%234B32C3?style=flat&logo=eslint&logoColor=white&labelColor=gray)](https://github.com/asumo-1xts/vitepress-linkcard/actions/workflows/eslint.yml)
18
18
  [![Prettier](https://img.shields.io/badge/Format_with-Prettier-%23F7B93E?style=flat&logo=prettier&logoColor=white&labelColor=gray)](https://github.com/asumo-1xts/vitepress-linkcard/actions/workflows/prettier.yml)
19
19
 
20
- <img src="https://github.com/asumo-1xts/vitepress-linkcard/blob/main/.github/screen.webp?raw=true" width=90% alt="How it shows" />
20
+ <img src="https://github.com/asumo-1xts/vitepress-linkcard/blob/main/.github/screen.gif?raw=true" width=90% alt="How it shows" />
21
21
 
22
22
  This plugin was forked from [markdown-it-link-to-card](https://github.com/luckrya/markdown-it-link-to-card).
23
23
 
@@ -47,10 +47,7 @@ export default defineConfig({
47
47
  markdown: {
48
48
  config: (md) => {
49
49
  md.use<LinkToCardPluginOptions>(linkToCardPlugin, {
50
- // // Supported options:
51
- // target: "_self",
52
- // borderColor: "#039393",
53
- // bgColor: "#CB3837"
50
+ // target: "_self" // if needed
54
51
  });
55
52
  },
56
53
  }
@@ -68,30 +65,57 @@ Generates a linkcard when `@:` appended.
68
65
 
69
66
  ## Supported options
70
67
 
71
- ### borderColor
68
+ ### Target
72
69
 
73
- Specifies the border color of linkcards with a color code. For exmaple:
70
+ As shown in [Usage](#usage), you can specify the target window in which to open a link.
74
71
 
75
- - `#7d7d7dff` (default)
76
- - `rgba(3, 147, 147, 0.39)`
77
- - ...
72
+ - `_blank` **(default)**
73
+ - `_self`
74
+ - `_top`
75
+ - `_parent`
78
76
 
79
- ### bgColor
77
+ ### Color theme
80
78
 
81
- Specifies the background color of linkcards with a color code. For exmaple:
79
+ You can customize:
82
80
 
83
- - `#7d7d7d00` (default)
84
- - `rgba(3, 147, 147, 0.39)`
85
- - ...
81
+ - Border color
82
+ - Background color
83
+ - Border color when hovered
84
+ - Background color when hovered
86
85
 
87
- ### target
86
+ **By default, all colors are set to `var(--vp-c-bg-soft)`.**
88
87
 
89
- Specifies the target window in which to open a link.
88
+ #### `docs/.vitepress/theme/custom.css`
90
89
 
91
- - `_blank` (default)
92
- - `_self`
93
- - `_top`
94
- - `_parent`
90
+ ```css
91
+ /* For example: like "Features" in VitePress */
92
+
93
+ .vitepress-linkcard-container {
94
+ border-color: #00000000 !important;
95
+ background-color: var(--vp-c-bg-soft) !important;
96
+ }
97
+
98
+ .vitepress-linkcard-container:hover {
99
+ border-color: var(--vp-c-brand-1) !important;
100
+ background-color: var(--vp-c-bg-soft) !important;
101
+ }
102
+ ```
103
+
104
+ #### `docs/.vitepress/theme/index.ts`
105
+
106
+ ``` ts
107
+ import DefaultTheme from 'vitepress/theme-without-fonts'
108
+ import type { Theme as ThemeConfig } from 'vitepress'
109
+ import './custom.css'
110
+
111
+ const Theme: ThemeConfig = {
112
+ extends: DefaultTheme
113
+ }
114
+
115
+ export default {
116
+ ...Theme
117
+ }
118
+ ```
95
119
 
96
120
  ## Other specifications
97
121
 
package/dist/.cjs.min.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /*!
2
- * vitepress-linkcard v1.3.0
3
- * (c) 2022 - 2025 luckrya
2
+ * vitepress-linkcard v2.0.1
3
+ * (c) 2022 - 2026 luckrya
4
4
  * Released under the MIT License.
5
5
  */
6
- Object.defineProperty(exports,"__esModule",{value:!0});var e=require("url"),t=require("child_process"),r=require("fs"),n=require("http"),o=require("https"),i=require("node:fs");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s,c,l=a(e),u=a(t),d=a(r),f=a(n),p=a(o),h=a(i);function g(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function v(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,m(n.key),n)}}function y(e,t,r){return(t=m(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function b(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function E(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?b(Object(r),!0).forEach(function(t){y(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):b(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function w(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,s=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(s.push(n.value),s.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return s}}(e,t)||function(e,t){if(e){if("string"==typeof e)return g(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?g(e,t):void 0}}
6
+ Object.defineProperty(exports,"__esModule",{value:!0});var e=require("url"),t=require("child_process"),r=require("fs"),n=require("http"),o=require("https"),i=require("node:fs");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s,c,l=a(e),u=a(t),f=a(r),d=a(n),p=a(o),h=a(i);function v(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function g(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,m(n.key),n)}}function y(e,t,r){return(t=m(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function b(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function E(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?b(Object(r),!0).forEach(function(t){y(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):b(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function w(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,s=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(s.push(n.value),s.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return s}}(e,t)||function(e,t){if(e){if("string"==typeof e)return v(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?v(e,t):void 0}}
7
7
  /*!
8
8
  * @luckrya/utility v0.1.0
9
9
  * (c) 2022 - 2022 Y.R
10
10
  * Released under the MIT License.
11
- */(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function m(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(c=s||(s={})).Array="[object Array]",c.Object="[object Object]",c.Function="[object Function]",c.Number="[object Number]",c.String="[object String]",c.Boolean="[object Boolean]",c.Undefined="[object Undefined]",c.Null="[object Null]",c.Error="[object Error]";var x=function(e){return Object.prototype.toString.call(e)===s.String},S=function(e){return Object.prototype.toString.call(e)===s.Function},O="undefined"!=typeof window,C=function(){var e,t="".concat(process.cwd(),"/.linkcard_cache.json"),r="".concat(process.cwd(),"/.config/.linkcard_cache.json");if(h.default.existsSync(t))e=t;else if(h.default.existsSync(r))e=r;else{e=t;h.default.writeFileSync(e,JSON.stringify({"https://example.com/":{description:"Example Website",logo:"https://example.com/example.png",title:"Example Title"}},null,2))}return e},N=function(){return function(e,t,r){return t&&v(e.prototype,t),r&&v(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}(function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)},[{key:"setFile",value:function(e){var t=e,r=this.readFile();r&&(t=Object.assign(r,t)),h.default.writeFileSync(C(),JSON.stringify(t)),function(){var e=C(),t=h.default.readFileSync(e,"utf-8").trim();if(t){var r=JSON.parse(t),n=JSON.stringify(r,null,2)+"\n";h.default.writeFileSync(e,n)}}()}},{key:"readFile",value:function(){var e=h.default.readFileSync(C(),"utf-8"),t=JSON.parse(e);if(function(e){return Object.prototype.toString.call(e)===s.Object}(t))return t}},{key:"has",value:function(e){return!!this.get(e)}},{key:"get",value:function(e){var t=this.readFile();return null==t?void 0:t[e]}},{key:"set",value:function(e,t){this.setFile(y({},e,t))}}])}(),k=new N;function T(e){return'style="'.concat(function(e){return Object.entries(e).map(function(e){var t,r=w(e,2),n=r[0],o=r[1];if(n&&o)return"".concat((t=n,t.replace(/\B([A-Z])/g,"-$1").toLowerCase()),": ").concat(o,";")}).filter(Boolean).join(" ")}(e),'"')}var j=function(e){return{"-webkit-box-orient":"vertical","-webkit-line-clamp":e,display:"-webkit-box",hyphens:"auto",lineClamp:e,overflow:"hidden",overflowWrap:"anywhere",textOverflow:"ellipsis",wordBreak:"break-word"}},R=function(e,t){var r,n,o,i,a={rel:'rel="noopener noreferrer"',target:'target="'.concat(t.target,'"'),href:'href="'.concat(t.href,'"'),title:'title="'.concat(t.linkTitle,'"'),borderColor:'borderColor="'.concat(t.borderColor,'"'),bgColor:'bgColor="'.concat(t.bgColor,'"')},s=function(e){return e.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#039;/g,"'")},c=(r=t.borderColor||"#7d7d7dff",n=t.bgColor||"#7d7d7d00",{a:T({color:"unset !important",display:"block",width:"100%",textDecoration:"none"}),container:T({display:"flex",alignItems:"center",flexWrap:"wrap",gap:"10px",borderRadius:"12px",border:"1px solid ".concat(r),backgroundColor:n,boxSizing:"border-box",width:"100%",height:"130px"}),img:T({borderRadius:"0px 12px 12px 0px",maxWidth:"40%",height:"128px",flexShrink:0,objectFit:"contain",overflow:"hidden"}),texts:T({flex:"1 1 0%",minWidth:"0"}),title:T(E(E({},j(2)),{},{opacity:1,fontSize:"16px",lineHeight:"22px",margin:"0 16px 8px 16px",fontWeight:"bold"})),domain:T(E(E({},j(1)),{},{opacity:1,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 8px 16px",textDecoration:"underline"})),description:T(E(E({},j(2)),{},{opacity:.8,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 0px 16px"}))}),l=t.href||"",u=new URL(l).origin.replace(/^https?:\/\//,"").replace(/^www\./,"")||"Unknown domain",d=e.title,f=e.description;"github.com"==u?(d=(null===(o=e.title)||void 0===o?void 0:o.split(":")[0].replace("GitHub - ",""))||"No title",f=(null===(i=f)||void 0===i?void 0:i.replace(" - ".concat(d),"").replace("Contribute to ".concat(d," development by creating an account on GitHub."),""))||""):(d=e.title||"No title",f=e.description||"");return'<span style="display:block;">\n <a '.concat(a.rel," ").concat(a.target," ").concat(a.href," ").concat(a.title," ").concat(c.a,">\n <span ").concat(c.container,">\n <span ").concat(c.texts,">\n <span ").concat(c.title,">\n ").concat(s(d),"\n </span>\n <span ").concat(c.domain,">\n ").concat(s(u),"\n </span>\n <span ").concat(c.description,">\n ").concat(s(f),'\n </span>\n </span>\n <img src="').concat(null==e?void 0:e.logo,'" ').concat(c.img,"/>\n </span>\n </a>\n</span>")};function D(e){return new URL(e)}var A="https://resources.whatwg.org/logo-url.svg",L=/(<[A-Za-z]+\s*[^>]*>(.*)<\/[A-Za-z]+>)/,q=/content=["|']([^>]*)["|']/,P=/href=["|']([^>]*)["|']/,H=/(<title\s*[^>]*>(.*)<\/title>)/g,F=function(e){return new RegExp("<".concat(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"meta","\\s[^>]*\\w+=['|\"]([a-zA-Z]|:|\\s)*").concat(e,"['|\"][^>]*\\/?>"))};function _(e){var t,r=e.match(F("title"));if(null!=r&&r.length){var n=r[0].match(q);n&&x(n[1])&&(t=n[1])}else{var o=e.match(H);if(null!=o&&o.length){var i=o[0].match(L);i&&x(i[2])&&(t=i[2])}}return t}function I(e){var t,r=e.match(F("description"));if(null!=r&&r.length){var n=r[0].match(q);n&&x(n[1])&&(t=n[1])}return t}function U(e){var t,r=e.match(F("image"));if(null!=r&&r.length){var n=r[0].match(q);n&&x(n[1])&&(t=n[1])}else{var o=e.match(F("icon","link"));if(null!=o&&o.length){var i=o[0].match(P);i&&x(i[1])&&(t=i[1])}}return t}function M(e,t){var r,n,o,i={title:_(e),description:I(e),logo:(r=U(e),r?D(r)?r:"".concat(null===(n=D(t))||void 0===n?void 0:n.origin).concat("/".concat(r).replace(/\/\//g,"/")):A)};return o=i,Object.values(o).filter(function(e){return x(e)}).length?i:null}function B(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var J,G={};
11
+ */(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function m(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}(c=s||(s={})).Array="[object Array]",c.Object="[object Object]",c.Function="[object Function]",c.Number="[object Number]",c.String="[object String]",c.Boolean="[object Boolean]",c.Undefined="[object Undefined]",c.Null="[object Null]",c.Error="[object Error]";var x=function(e){return Object.prototype.toString.call(e)===s.String},S=function(e){return Object.prototype.toString.call(e)===s.Function},O="undefined"!=typeof window,k=function(){var e,t="".concat(process.cwd(),"/.linkcard_cache.json"),r="".concat(process.cwd(),"/.config/.linkcard_cache.json");if(h.default.existsSync(t))e=t;else if(h.default.existsSync(r))e=r;else{e=t;h.default.writeFileSync(e,JSON.stringify({"https://example.com/":{description:"Example Website",logo:"https://example.com/example.png",title:"Example Title"}},null,2))}return e},N=function(){return function(e,t,r){return t&&g(e.prototype,t),r&&g(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}(function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)},[{key:"setFile",value:function(e){var t=e,r=this.readFile();r&&(t=Object.assign(r,t)),h.default.writeFileSync(k(),JSON.stringify(t)),function(){var e=k(),t=h.default.readFileSync(e,"utf-8").trim();if(t){var r=JSON.parse(t),n=JSON.stringify(r,null,2)+"\n";h.default.writeFileSync(e,n)}}()}},{key:"readFile",value:function(){var e=h.default.readFileSync(k(),"utf-8"),t=JSON.parse(e);if(function(e){return Object.prototype.toString.call(e)===s.Object}(t))return t}},{key:"has",value:function(e){return!!this.get(e)}},{key:"get",value:function(e){var t=this.readFile();return null==t?void 0:t[e]}},{key:"set",value:function(e,t){this.setFile(y({},e,t))}}])}(),T=new N;function j(e){return'style="'.concat(function(e){return Object.entries(e).map(function(e){var t,r=w(e,2),n=r[0],o=r[1];if(n&&o)return"".concat((t=n,t.replace(/\B([A-Z])/g,"-$1").toLowerCase()),": ").concat(o,";")}).filter(Boolean).join(" ")}(e),'"')}var C=function(e){return{"-webkit-box-orient":"vertical","-webkit-line-clamp":e,display:"-webkit-box",hyphens:"auto",lineClamp:e,overflow:"hidden",overflowWrap:"anywhere",textOverflow:"ellipsis",wordBreak:"break-word"}},R=function(e,t){var r,n,o={rel:'rel="noopener noreferrer"',target:'target="'.concat(t.target,'"'),href:'href="'.concat(t.href,'"'),title:'title="'.concat(t.linkTitle,'"')},i=function(e){return e.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#039;/g,"'")},a={a:j({color:"unset !important",display:"block",width:"100%",textDecoration:"none"}),container:j({display:"flex",alignItems:"center",flexWrap:"wrap",gap:"10px",borderRadius:"12px",border:"1px solid var(--vp-c-bg-soft)",backgroundColor:"var(--vp-c-bg-soft)",boxSizing:"border-box",width:"100%",height:"130px",transition:"border-color 0.25s, background-color 0.25s"}),img:j({borderRadius:"0px 12px 12px 0px",maxWidth:"40%",height:"129px",flexShrink:0,objectFit:"contain",overflow:"hidden"}),texts:j({flex:"1 1 0%",minWidth:"0"}),title:j(E(E({},C(2)),{},{opacity:1,fontSize:"16px",lineHeight:"22px",margin:"0 16px 8px 16px",fontWeight:"bold"})),domain:j(E(E({},C(1)),{},{opacity:1,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 8px 16px",textDecoration:"underline"})),description:j(E(E({},C(2)),{},{opacity:.8,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 0px 16px"}))},s=t.href||"",c=new URL(s).origin.replace(/^https?:\/\//,"").replace(/^www\./,"")||"Unknown domain",l=e.title,u=e.description;"github.com"==c?(l=(null===(r=e.title)||void 0===r?void 0:r.split(":")[0].replace("GitHub - ",""))||"No title",u=(null===(n=u)||void 0===n?void 0:n.replace(" - ".concat(l),"").replace("Contribute to ".concat(l," development by creating an account on GitHub."),""))||""):(l=e.title||"No title",u=e.description||"");return'<span style="display:block;">\n <a '.concat(o.rel," ").concat(o.target," ").concat(o.href," ").concat(o.title," ").concat(a.a,'>\n <span class="vitepress-linkcard-container" ').concat(a.container,">\n <span ").concat(a.texts,">\n <span ").concat(a.title,">\n ").concat(i(l),"\n </span>\n <span ").concat(a.domain,">\n ").concat(i(c),"\n </span>\n <span ").concat(a.description,">\n ").concat(i(u),'\n </span>\n </span>\n <img src="').concat(null==e?void 0:e.logo,'" ').concat(a.img,"/>\n </span>\n </a>\n</span>")};function D(e){return new URL(e)}var A="https://resources.whatwg.org/logo-url.svg",L=/(<[A-Za-z]+\s*[^>]*>(.*)<\/[A-Za-z]+>)/,q=/content=["|']([^>]*)["|']/,P=/href=["|']([^>]*)["|']/,H=/(<title\s*[^>]*>(.*)<\/title>)/g,F=function(e){return new RegExp("<".concat(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"meta","\\s[^>]*\\w+=['|\"]([a-zA-Z]|:|\\s)*").concat(e,"['|\"][^>]*\\/?>"))};function _(e){var t,r=e.match(F("title"));if(null!=r&&r.length){var n=r[0].match(q);n&&x(n[1])&&(t=n[1])}else{var o=e.match(H);if(null!=o&&o.length){var i=o[0].match(L);i&&x(i[2])&&(t=i[2])}}return t}function I(e){var t,r=e.match(F("description"));if(null!=r&&r.length){var n=r[0].match(q);n&&x(n[1])&&(t=n[1])}return t}function U(e){var t,r=e.match(F("image"));if(null!=r&&r.length){var n=r[0].match(q);n&&x(n[1])&&(t=n[1])}else{var o=e.match(F("icon","link"));if(null!=o&&o.length){var i=o[0].match(P);i&&x(i[1])&&(t=i[1])}}return t}function M(e,t){var r,n,o,i={title:_(e),description:I(e),logo:(r=U(e),r?D(r)?r:"".concat(null===(n=D(t))||void 0===n?void 0:n.origin).concat("/".concat(r).replace(/\/\//g,"/")):A)};return o=i,Object.values(o).filter(function(e){return x(e)}).length?i:null}function B(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var J,G={};
12
12
  /**
13
13
  * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object.
14
14
  *
@@ -20,4 +20,4 @@ Object.defineProperty(exports,"__esModule",{value:!0});var e=require("url"),t=re
20
20
  * @author Dan DeFelippi <dan@driverdan.com>
21
21
  * @contributor David Ellis <d.f.ellis@ieee.org>
22
22
  * @license MIT
23
- */var z=function(){if(J)return G;J=1;var e=l.default,t=u.default.spawn,r=d.default;return G.XMLHttpRequest=function(){var n,o,i=this,a=f.default,s=p.default,c={},l=!1,u={"User-Agent":"node-XMLHttpRequest",Accept:"*/*"},d={},h={},g=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","content-transfer-encoding","cookie","cookie2","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","via"],v=["TRACE","TRACK","CONNECT"],y=!1,b=!1,E={};this.UNSENT=0,this.OPENED=1,this.HEADERS_RECEIVED=2,this.LOADING=3,this.DONE=4,this.readyState=this.UNSENT,this.onreadystatechange=null,this.responseText="",this.responseXML="",this.status=null,this.statusText=null,this.withCredentials=!1;this.open=function(e,t,r,n,o){if(this.abort(),b=!1,!function(e){return e&&-1===v.indexOf(e)}(e))throw new Error("SecurityError: Request method not allowed");c={method:e,url:t.toString(),async:"boolean"!=typeof r||r,user:n||null,password:o||null},w(this.OPENED)},this.setDisableHeaderCheck=function(e){l=e},this.setRequestHeader=function(e,t){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");if(function(e){return l||e&&-1===g.indexOf(e.toLowerCase())}(e)){if(y)throw new Error("INVALID_STATE_ERR: send flag is true");e=h[e.toLowerCase()]||e,h[e.toLowerCase()]=e,d[e]=d[e]?d[e]+", "+t:t}else console.warn('Refused to set unsafe header "'+e+'"')},this.getResponseHeader=function(e){return"string"==typeof e&&this.readyState>this.OPENED&&o&&o.headers&&o.headers[e.toLowerCase()]&&!b?o.headers[e.toLowerCase()]:null},this.getAllResponseHeaders=function(){if(this.readyState<this.HEADERS_RECEIVED||b)return"";var e="";for(var t in o.headers)"set-cookie"!==t&&"set-cookie2"!==t&&(e+=t+": "+o.headers[t]+"\r\n");return e.substr(0,e.length-2)},this.getRequestHeader=function(e){return"string"==typeof e&&h[e.toLowerCase()]?d[h[e.toLowerCase()]]:""},this.send=function(l){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");if(y)throw new Error("INVALID_STATE_ERR: send has already been called");var f,p=!1,g=!1,v=e.parse(c.url);switch(v.protocol){case"https:":p=!0;case"http:":f=v.hostname;break;case"file:":g=!0;break;case void 0:case null:case"":f="localhost";break;default:throw new Error("Protocol not supported.")}if(g){if("GET"!==c.method)throw new Error("XMLHttpRequest: Only GET method is supported");if(c.async)r.readFile(v.pathname,"utf8",function(e,t){e?i.handleError(e):(i.status=200,i.responseText=t,w(i.DONE))});else try{this.responseText=r.readFileSync(v.pathname,"utf8"),this.status=200,w(i.DONE)}catch(e){this.handleError(e)}}else{var E=v.port||(p?443:80),m=v.pathname+(v.search?v.search:"");for(var x in u)h[x.toLowerCase()]||(d[x]=u[x]);if(d.Host=f,p&&443===E||80===E||(d.Host+=":"+v.port),c.user){void 0===c.password&&(c.password="");var S=new Buffer(c.user+":"+c.password);d.Authorization="Basic "+S.toString("base64")}"GET"===c.method||"HEAD"===c.method?l=null:l?(d["Content-Length"]=Buffer.isBuffer(l)?l.length:Buffer.byteLength(l),d["Content-Type"]||(d["Content-Type"]="text/plain;charset=UTF-8")):"POST"===c.method&&(d["Content-Length"]=0);var O={host:f,port:E,path:m,method:c.method,headers:d,agent:!1,withCredentials:i.withCredentials};if(b=!1,c.async){var C=p?s.request:a.request;y=!0,i.dispatchEvent("readystatechange");var N=function(e){i.handleError(e)};n=C(O,function t(r){if(301!==(o=r).statusCode&&302!==o.statusCode&&303!==o.statusCode&&307!==o.statusCode)o.setEncoding("utf8"),w(i.HEADERS_RECEIVED),i.status=o.statusCode,o.on("data",function(e){e&&(i.responseText+=e),y&&w(i.LOADING)}),o.on("end",function(){y&&(w(i.DONE),y=!1)}),o.on("error",function(e){i.handleError(e)});else{c.url=o.headers.location;var a=e.parse(c.url);f=a.hostname;var s={hostname:a.hostname,port:a.port,path:a.path,method:303===o.statusCode?"GET":c.method,headers:d,withCredentials:i.withCredentials};(n=C(s,t).on("error",N)).end()}}).on("error",N),l&&n.write(l),n.end(),i.dispatchEvent("loadstart")}else{var k=".node-xmlhttprequest-content-"+process.pid,T=".node-xmlhttprequest-sync-"+process.pid;r.writeFileSync(T,"","utf8");for(var j="var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http"+(p?"s":"")+".request;var options = "+JSON.stringify(O)+";var responseText = '';var req = doRequest(options, function(response) {response.setEncoding('utf8');response.on('data', function(chunk) { responseText += chunk;});response.on('end', function() {fs.writeFileSync('"+k+"', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');fs.unlinkSync('"+T+"');});response.on('error', function(error) {fs.writeFileSync('"+k+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+T+"');});}).on('error', function(error) {fs.writeFileSync('"+k+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+T+"');});"+(l?"req.write('"+JSON.stringify(l).slice(1,-1).replace(/'/g,"\\'")+"');":"")+"req.end();",R=t(process.argv[0],["-e",j]);r.existsSync(T););var D=JSON.parse(r.readFileSync(k,"utf8"));R.stdin.end(),r.unlinkSync(k),D.err?i.handleError(D.err):(o=D.data,i.status=D.data.statusCode,i.responseText=D.data.text,w(i.DONE))}}},this.handleError=function(e){this.status=0,this.statusText=e,this.responseText=e.stack,b=!0,w(this.DONE),this.dispatchEvent("error")},this.abort=function(){n&&(n.abort(),n=null),d=u,this.status=0,this.responseText="",this.responseXML="",b=!0,this.readyState===this.UNSENT||this.readyState===this.OPENED&&!y||this.readyState===this.DONE||(y=!1,w(this.DONE)),this.readyState=this.UNSENT,this.dispatchEvent("abort")},this.addEventListener=function(e,t){e in E||(E[e]=[]),E[e].push(t)},this.removeEventListener=function(e,t){e in E&&(E[e]=E[e].filter(function(e){return e!==t}))},this.dispatchEvent=function(e){if("function"==typeof i["on"+e]&&i["on"+e](),e in E)for(var t=0,r=E[e].length;t<r;t++)E[e][t].call(i)};var w=function(e){e!=i.LOADING&&i.readyState===e||(i.readyState=e,(c.async||i.readyState<i.OPENED||i.readyState===i.DONE)&&i.dispatchEvent("readystatechange"),i.readyState!==i.DONE||b||(i.dispatchEvent("load"),i.dispatchEvent("loadend")))}},G}(),X=B(z),V=new Map,W=O?window.XMLHttpRequest:X.XMLHttpRequest;function Z(e){if(V.has(e))return V.get(e);var t;try{var r=new W;r.open("GET",e,!1),r.setRequestHeader("Content-Type","text/html"),r.send(),200===r.status&&r.responseText&&(t=r.responseText,V.set(e,r.responseText))}catch(e){console.error("【XHR Error】:".concat(e instanceof Error?e.message:"get remote URL resource exception!"))}return t}var $=new Map;exports.generateCard=function(e,t){return new Promise(function(r){var n=Z(e);if(n){var o=M(n,e);if(o){var i={linkTitle:t.linkTitle,target:t.target||"_blank",classPrefix:t.classPrefix},a=R(o,E(E({},i),{},{href:e})),s={url:e,data:o,options:i,dom:a};$.set(e,s),r(s)}}})},exports.linkToCardPlugin=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};function r(e){var r,n=function(e){if(k.has(e))return k.get(e);var t=null,r=Z(e);return r&&(t=M(r,e))&&k.set(e,t),t}(e.url);if(n){!function(e,t){e.forEach(function(e,r){r!==t&&(e.hidden=!0)})}(e.tokens,e.i);var o={href:e.url,linkTitle:(r=e.tokens,r.map(function(e){var t=e.hidden,r=e.content;return t?r:""}).filter(Boolean).join("")),target:t.target||"_blank",classPrefix:t.classPrefix,borderColor:t.borderColor,bgColor:t.bgColor};return S(t.render)?t.render(n,o):R(n,o)}}e.renderer.renderInline=function(t,r,n){for(var o="",i=0;i<t.length;i++){var a=t[i],s=e.renderer.rules[a.type];a.hidden?o+="":S(s)?o+=s(t,i,r,n,e.renderer):o+=e.renderer.renderToken(t,i,r)}return o},e.renderer.rules.link_open=function(e,t,n,o,i){var a,s=e[t],c="a"===s.tag&&"link_open"===s.type,l=function(e){var t=new RegExp("^(".concat("@",":)([a-zA-Z0-9]+.*)")),r=null==e?void 0:e.match(t);return{isCardLink:!!r,url:null==r?void 0:r[2]}}(null===(a=s.attrs)||void 0===a||null===(a=a.filter(function(e){return e.includes("href")})[0])||void 0===a?void 0:a[1]),u=l.url,d=l.isCardLink;if(c&&d&&u){var f=r({url:u,tokens:e,i:t});if(f)return f}return i.renderToken(e,t,n)}};
23
+ */var z=function(){if(J)return G;J=1;var e=l.default,t=u.default.spawn,r=f.default;return G.XMLHttpRequest=function(){var n,o,i=this,a=d.default,s=p.default,c={},l=!1,u={"User-Agent":"node-XMLHttpRequest",Accept:"*/*"},f={},h={},v=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","content-transfer-encoding","cookie","cookie2","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","via"],g=["TRACE","TRACK","CONNECT"],y=!1,b=!1,E={};this.UNSENT=0,this.OPENED=1,this.HEADERS_RECEIVED=2,this.LOADING=3,this.DONE=4,this.readyState=this.UNSENT,this.onreadystatechange=null,this.responseText="",this.responseXML="",this.status=null,this.statusText=null,this.withCredentials=!1;this.open=function(e,t,r,n,o){if(this.abort(),b=!1,!function(e){return e&&-1===g.indexOf(e)}(e))throw new Error("SecurityError: Request method not allowed");c={method:e,url:t.toString(),async:"boolean"!=typeof r||r,user:n||null,password:o||null},w(this.OPENED)},this.setDisableHeaderCheck=function(e){l=e},this.setRequestHeader=function(e,t){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");if(function(e){return l||e&&-1===v.indexOf(e.toLowerCase())}(e)){if(y)throw new Error("INVALID_STATE_ERR: send flag is true");e=h[e.toLowerCase()]||e,h[e.toLowerCase()]=e,f[e]=f[e]?f[e]+", "+t:t}else console.warn('Refused to set unsafe header "'+e+'"')},this.getResponseHeader=function(e){return"string"==typeof e&&this.readyState>this.OPENED&&o&&o.headers&&o.headers[e.toLowerCase()]&&!b?o.headers[e.toLowerCase()]:null},this.getAllResponseHeaders=function(){if(this.readyState<this.HEADERS_RECEIVED||b)return"";var e="";for(var t in o.headers)"set-cookie"!==t&&"set-cookie2"!==t&&(e+=t+": "+o.headers[t]+"\r\n");return e.substr(0,e.length-2)},this.getRequestHeader=function(e){return"string"==typeof e&&h[e.toLowerCase()]?f[h[e.toLowerCase()]]:""},this.send=function(l){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");if(y)throw new Error("INVALID_STATE_ERR: send has already been called");var d,p=!1,v=!1,g=e.parse(c.url);switch(g.protocol){case"https:":p=!0;case"http:":d=g.hostname;break;case"file:":v=!0;break;case void 0:case null:case"":d="localhost";break;default:throw new Error("Protocol not supported.")}if(v){if("GET"!==c.method)throw new Error("XMLHttpRequest: Only GET method is supported");if(c.async)r.readFile(g.pathname,"utf8",function(e,t){e?i.handleError(e):(i.status=200,i.responseText=t,w(i.DONE))});else try{this.responseText=r.readFileSync(g.pathname,"utf8"),this.status=200,w(i.DONE)}catch(e){this.handleError(e)}}else{var E=g.port||(p?443:80),m=g.pathname+(g.search?g.search:"");for(var x in u)h[x.toLowerCase()]||(f[x]=u[x]);if(f.Host=d,p&&443===E||80===E||(f.Host+=":"+g.port),c.user){void 0===c.password&&(c.password="");var S=new Buffer(c.user+":"+c.password);f.Authorization="Basic "+S.toString("base64")}"GET"===c.method||"HEAD"===c.method?l=null:l?(f["Content-Length"]=Buffer.isBuffer(l)?l.length:Buffer.byteLength(l),f["Content-Type"]||(f["Content-Type"]="text/plain;charset=UTF-8")):"POST"===c.method&&(f["Content-Length"]=0);var O={host:d,port:E,path:m,method:c.method,headers:f,agent:!1,withCredentials:i.withCredentials};if(b=!1,c.async){var k=p?s.request:a.request;y=!0,i.dispatchEvent("readystatechange");var N=function(e){i.handleError(e)};n=k(O,function t(r){if(301!==(o=r).statusCode&&302!==o.statusCode&&303!==o.statusCode&&307!==o.statusCode)o.setEncoding("utf8"),w(i.HEADERS_RECEIVED),i.status=o.statusCode,o.on("data",function(e){e&&(i.responseText+=e),y&&w(i.LOADING)}),o.on("end",function(){y&&(w(i.DONE),y=!1)}),o.on("error",function(e){i.handleError(e)});else{c.url=o.headers.location;var a=e.parse(c.url);d=a.hostname;var s={hostname:a.hostname,port:a.port,path:a.path,method:303===o.statusCode?"GET":c.method,headers:f,withCredentials:i.withCredentials};(n=k(s,t).on("error",N)).end()}}).on("error",N),l&&n.write(l),n.end(),i.dispatchEvent("loadstart")}else{var T=".node-xmlhttprequest-content-"+process.pid,j=".node-xmlhttprequest-sync-"+process.pid;r.writeFileSync(j,"","utf8");for(var C="var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http"+(p?"s":"")+".request;var options = "+JSON.stringify(O)+";var responseText = '';var req = doRequest(options, function(response) {response.setEncoding('utf8');response.on('data', function(chunk) { responseText += chunk;});response.on('end', function() {fs.writeFileSync('"+T+"', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');fs.unlinkSync('"+j+"');});response.on('error', function(error) {fs.writeFileSync('"+T+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+j+"');});}).on('error', function(error) {fs.writeFileSync('"+T+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+j+"');});"+(l?"req.write('"+JSON.stringify(l).slice(1,-1).replace(/'/g,"\\'")+"');":"")+"req.end();",R=t(process.argv[0],["-e",C]);r.existsSync(j););var D=JSON.parse(r.readFileSync(T,"utf8"));R.stdin.end(),r.unlinkSync(T),D.err?i.handleError(D.err):(o=D.data,i.status=D.data.statusCode,i.responseText=D.data.text,w(i.DONE))}}},this.handleError=function(e){this.status=0,this.statusText=e,this.responseText=e.stack,b=!0,w(this.DONE),this.dispatchEvent("error")},this.abort=function(){n&&(n.abort(),n=null),f=u,this.status=0,this.responseText="",this.responseXML="",b=!0,this.readyState===this.UNSENT||this.readyState===this.OPENED&&!y||this.readyState===this.DONE||(y=!1,w(this.DONE)),this.readyState=this.UNSENT,this.dispatchEvent("abort")},this.addEventListener=function(e,t){e in E||(E[e]=[]),E[e].push(t)},this.removeEventListener=function(e,t){e in E&&(E[e]=E[e].filter(function(e){return e!==t}))},this.dispatchEvent=function(e){if("function"==typeof i["on"+e]&&i["on"+e](),e in E)for(var t=0,r=E[e].length;t<r;t++)E[e][t].call(i)};var w=function(e){e!=i.LOADING&&i.readyState===e||(i.readyState=e,(c.async||i.readyState<i.OPENED||i.readyState===i.DONE)&&i.dispatchEvent("readystatechange"),i.readyState!==i.DONE||b||(i.dispatchEvent("load"),i.dispatchEvent("loadend")))}},G}(),X=B(z),V=new Map,W=O?window.XMLHttpRequest:X.XMLHttpRequest;function Z(e){if(V.has(e))return V.get(e);var t;try{var r=new W;r.open("GET",e,!1),r.setRequestHeader("Content-Type","text/html"),r.send(),200===r.status&&r.responseText&&(t=r.responseText,V.set(e,r.responseText))}catch(e){console.error("【XHR Error】:".concat(e instanceof Error?e.message:"get remote URL resource exception!"))}return t}var $=new Map;exports.generateCard=function(e,t){return new Promise(function(r){var n=Z(e);if(n){var o=M(n,e);if(o){var i={linkTitle:t.linkTitle,target:t.target||"_blank",classPrefix:t.classPrefix},a=R(o,E(E({},i),{},{href:e})),s={url:e,data:o,options:i,dom:a};$.set(e,s),r(s)}}})},exports.linkToCardPlugin=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};function r(e){var r,n=function(e){if(T.has(e))return T.get(e);var t=null,r=Z(e);return r&&(t=M(r,e))&&T.set(e,t),t}(e.url);if(n){!function(e,t){e.forEach(function(e,r){r!==t&&(e.hidden=!0)})}(e.tokens,e.i);var o={href:e.url,linkTitle:(r=e.tokens,r.map(function(e){var t=e.hidden,r=e.content;return t?r:""}).filter(Boolean).join("")),target:t.target||"_blank",classPrefix:t.classPrefix};return S(t.render)?t.render(n,o):R(n,o)}}e.renderer.renderInline=function(t,r,n){for(var o="",i=0;i<t.length;i++){var a=t[i],s=e.renderer.rules[a.type];a.hidden?o+="":S(s)?o+=s(t,i,r,n,e.renderer):o+=e.renderer.renderToken(t,i,r)}return o},e.renderer.rules.link_open=function(e,t,n,o,i){var a,s=e[t],c="a"===s.tag&&"link_open"===s.type,l=function(e){var t=new RegExp("^(".concat("@",":)([a-zA-Z0-9]+.*)")),r=null==e?void 0:e.match(t);return{isCardLink:!!r,url:null==r?void 0:r[2]}}(null===(a=s.attrs)||void 0===a||null===(a=a.filter(function(e){return e.includes("href")})[0])||void 0===a?void 0:a[1]),u=l.url,f=l.isCardLink;if(c&&f&&u){var d=r({url:u,tokens:e,i:t});if(d)return d}return i.renderToken(e,t,n)}};
package/dist/.esm.min.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /*!
2
- * vitepress-linkcard v1.3.0
3
- * (c) 2022 - 2025 luckrya
2
+ * vitepress-linkcard v2.0.1
3
+ * (c) 2022 - 2026 luckrya
4
4
  * Released under the MIT License.
5
5
  */
6
- import e from"url";import t from"child_process";import r from"fs";import n from"http";import o from"https";import i from"node:fs";function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,d(n.key),n)}}function c(e,t,r){return(t=d(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function u(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach(function(t){c(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function f(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,s=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(s.push(n.value),s.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return s}}(e,t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(e,t):void 0}}
6
+ import e from"url";import t from"child_process";import r from"fs";import n from"http";import o from"https";import i from"node:fs";function a(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function s(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,p(n.key),n)}}function c(e,t,r){return(t=p(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),r.push.apply(r,n)}return r}function u(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach(function(t){c(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function f(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,s=[],c=!0,l=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=i.call(r)).done)&&(s.push(n.value),s.length!==t);c=!0);}catch(e){l=!0,o=e}finally{try{if(!c&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(l)throw o}}return s}}(e,t)||function(e,t){if(e){if("string"==typeof e)return a(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(e,t):void 0}}
7
7
  /*!
8
8
  * @luckrya/utility v0.1.0
9
9
  * (c) 2022 - 2022 Y.R
10
10
  * Released under the MIT License.
11
- */(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}var p,h;(h=p||(p={})).Array="[object Array]",h.Object="[object Object]",h.Function="[object Function]",h.Number="[object Number]",h.String="[object String]",h.Boolean="[object Boolean]",h.Undefined="[object Undefined]",h.Null="[object Null]",h.Error="[object Error]";var g=function(e){return Object.prototype.toString.call(e)===p.String},v=function(e){return Object.prototype.toString.call(e)===p.Function},y="undefined"!=typeof window,b=function(){var e,t="".concat(process.cwd(),"/.linkcard_cache.json"),r="".concat(process.cwd(),"/.config/.linkcard_cache.json");if(i.existsSync(t))e=t;else if(i.existsSync(r))e=r;else{e=t;i.writeFileSync(e,JSON.stringify({"https://example.com/":{description:"Example Website",logo:"https://example.com/example.png",title:"Example Title"}},null,2))}return e},m=function(){return function(e,t,r){return t&&s(e.prototype,t),r&&s(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}(function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)},[{key:"setFile",value:function(e){var t=e,r=this.readFile();r&&(t=Object.assign(r,t)),i.writeFileSync(b(),JSON.stringify(t)),function(){var e=b(),t=i.readFileSync(e,"utf-8").trim();if(t){var r=JSON.parse(t),n=JSON.stringify(r,null,2)+"\n";i.writeFileSync(e,n)}}()}},{key:"readFile",value:function(){var e=i.readFileSync(b(),"utf-8"),t=JSON.parse(e);if(function(e){return Object.prototype.toString.call(e)===p.Object}(t))return t}},{key:"has",value:function(e){return!!this.get(e)}},{key:"get",value:function(e){var t=this.readFile();return null==t?void 0:t[e]}},{key:"set",value:function(e,t){this.setFile(c({},e,t))}}])}(),E=new m;function w(e){return'style="'.concat(function(e){return Object.entries(e).map(function(e){var t,r=f(e,2),n=r[0],o=r[1];if(n&&o)return"".concat((t=n,t.replace(/\B([A-Z])/g,"-$1").toLowerCase()),": ").concat(o,";")}).filter(Boolean).join(" ")}(e),'"')}var x=function(e){return{"-webkit-box-orient":"vertical","-webkit-line-clamp":e,display:"-webkit-box",hyphens:"auto",lineClamp:e,overflow:"hidden",overflowWrap:"anywhere",textOverflow:"ellipsis",wordBreak:"break-word"}},S=function(e,t){var r,n,o,i,a={rel:'rel="noopener noreferrer"',target:'target="'.concat(t.target,'"'),href:'href="'.concat(t.href,'"'),title:'title="'.concat(t.linkTitle,'"'),borderColor:'borderColor="'.concat(t.borderColor,'"'),bgColor:'bgColor="'.concat(t.bgColor,'"')},s=function(e){return e.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#039;/g,"'")},c=(r=t.borderColor||"#7d7d7dff",n=t.bgColor||"#7d7d7d00",{a:w({color:"unset !important",display:"block",width:"100%",textDecoration:"none"}),container:w({display:"flex",alignItems:"center",flexWrap:"wrap",gap:"10px",borderRadius:"12px",border:"1px solid ".concat(r),backgroundColor:n,boxSizing:"border-box",width:"100%",height:"130px"}),img:w({borderRadius:"0px 12px 12px 0px",maxWidth:"40%",height:"128px",flexShrink:0,objectFit:"contain",overflow:"hidden"}),texts:w({flex:"1 1 0%",minWidth:"0"}),title:w(u(u({},x(2)),{},{opacity:1,fontSize:"16px",lineHeight:"22px",margin:"0 16px 8px 16px",fontWeight:"bold"})),domain:w(u(u({},x(1)),{},{opacity:1,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 8px 16px",textDecoration:"underline"})),description:w(u(u({},x(2)),{},{opacity:.8,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 0px 16px"}))}),l=t.href||"",f=new URL(l).origin.replace(/^https?:\/\//,"").replace(/^www\./,"")||"Unknown domain",d=e.title,p=e.description;"github.com"==f?(d=(null===(o=e.title)||void 0===o?void 0:o.split(":")[0].replace("GitHub - ",""))||"No title",p=(null===(i=p)||void 0===i?void 0:i.replace(" - ".concat(d),"").replace("Contribute to ".concat(d," development by creating an account on GitHub."),""))||""):(d=e.title||"No title",p=e.description||"");return'<span style="display:block;">\n <a '.concat(a.rel," ").concat(a.target," ").concat(a.href," ").concat(a.title," ").concat(c.a,">\n <span ").concat(c.container,">\n <span ").concat(c.texts,">\n <span ").concat(c.title,">\n ").concat(s(d),"\n </span>\n <span ").concat(c.domain,">\n ").concat(s(f),"\n </span>\n <span ").concat(c.description,">\n ").concat(s(p),'\n </span>\n </span>\n <img src="').concat(null==e?void 0:e.logo,'" ').concat(c.img,"/>\n </span>\n </a>\n</span>")};function O(e){return new URL(e)}var C="https://resources.whatwg.org/logo-url.svg",N=/(<[A-Za-z]+\s*[^>]*>(.*)<\/[A-Za-z]+>)/,k=/content=["|']([^>]*)["|']/,T=/href=["|']([^>]*)["|']/,j=/(<title\s*[^>]*>(.*)<\/title>)/g,R=function(e){return new RegExp("<".concat(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"meta","\\s[^>]*\\w+=['|\"]([a-zA-Z]|:|\\s)*").concat(e,"['|\"][^>]*\\/?>"))};function D(e){var t,r=e.match(R("title"));if(null!=r&&r.length){var n=r[0].match(k);n&&g(n[1])&&(t=n[1])}else{var o=e.match(j);if(null!=o&&o.length){var i=o[0].match(N);i&&g(i[2])&&(t=i[2])}}return t}function A(e){var t,r=e.match(R("description"));if(null!=r&&r.length){var n=r[0].match(k);n&&g(n[1])&&(t=n[1])}return t}function L(e){var t,r=e.match(R("image"));if(null!=r&&r.length){var n=r[0].match(k);n&&g(n[1])&&(t=n[1])}else{var o=e.match(R("icon","link"));if(null!=o&&o.length){var i=o[0].match(T);i&&g(i[1])&&(t=i[1])}}return t}function P(e,t){var r,n,o,i={title:D(e),description:A(e),logo:(r=L(e),r?O(r)?r:"".concat(null===(n=O(t))||void 0===n?void 0:n.origin).concat("/".concat(r).replace(/\/\//g,"/")):C)};return o=i,Object.values(o).filter(function(e){return g(e)}).length?i:null}function q(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var H,F={};
11
+ */(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:t+""}var d,h;(h=d||(d={})).Array="[object Array]",h.Object="[object Object]",h.Function="[object Function]",h.Number="[object Number]",h.String="[object String]",h.Boolean="[object Boolean]",h.Undefined="[object Undefined]",h.Null="[object Null]",h.Error="[object Error]";var v=function(e){return Object.prototype.toString.call(e)===d.String},g=function(e){return Object.prototype.toString.call(e)===d.Function},y="undefined"!=typeof window,b=function(){var e,t="".concat(process.cwd(),"/.linkcard_cache.json"),r="".concat(process.cwd(),"/.config/.linkcard_cache.json");if(i.existsSync(t))e=t;else if(i.existsSync(r))e=r;else{e=t;i.writeFileSync(e,JSON.stringify({"https://example.com/":{description:"Example Website",logo:"https://example.com/example.png",title:"Example Title"}},null,2))}return e},m=function(){return function(e,t,r){return t&&s(e.prototype,t),r&&s(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}(function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e)},[{key:"setFile",value:function(e){var t=e,r=this.readFile();r&&(t=Object.assign(r,t)),i.writeFileSync(b(),JSON.stringify(t)),function(){var e=b(),t=i.readFileSync(e,"utf-8").trim();if(t){var r=JSON.parse(t),n=JSON.stringify(r,null,2)+"\n";i.writeFileSync(e,n)}}()}},{key:"readFile",value:function(){var e=i.readFileSync(b(),"utf-8"),t=JSON.parse(e);if(function(e){return Object.prototype.toString.call(e)===d.Object}(t))return t}},{key:"has",value:function(e){return!!this.get(e)}},{key:"get",value:function(e){var t=this.readFile();return null==t?void 0:t[e]}},{key:"set",value:function(e,t){this.setFile(c({},e,t))}}])}(),E=new m;function w(e){return'style="'.concat(function(e){return Object.entries(e).map(function(e){var t,r=f(e,2),n=r[0],o=r[1];if(n&&o)return"".concat((t=n,t.replace(/\B([A-Z])/g,"-$1").toLowerCase()),": ").concat(o,";")}).filter(Boolean).join(" ")}(e),'"')}var x=function(e){return{"-webkit-box-orient":"vertical","-webkit-line-clamp":e,display:"-webkit-box",hyphens:"auto",lineClamp:e,overflow:"hidden",overflowWrap:"anywhere",textOverflow:"ellipsis",wordBreak:"break-word"}},S=function(e,t){var r,n,o={rel:'rel="noopener noreferrer"',target:'target="'.concat(t.target,'"'),href:'href="'.concat(t.href,'"'),title:'title="'.concat(t.linkTitle,'"')},i=function(e){return e.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#039;/g,"'")},a={a:w({color:"unset !important",display:"block",width:"100%",textDecoration:"none"}),container:w({display:"flex",alignItems:"center",flexWrap:"wrap",gap:"10px",borderRadius:"12px",border:"1px solid var(--vp-c-bg-soft)",backgroundColor:"var(--vp-c-bg-soft)",boxSizing:"border-box",width:"100%",height:"130px",transition:"border-color 0.25s, background-color 0.25s"}),img:w({borderRadius:"0px 12px 12px 0px",maxWidth:"40%",height:"129px",flexShrink:0,objectFit:"contain",overflow:"hidden"}),texts:w({flex:"1 1 0%",minWidth:"0"}),title:w(u(u({},x(2)),{},{opacity:1,fontSize:"16px",lineHeight:"22px",margin:"0 16px 8px 16px",fontWeight:"bold"})),domain:w(u(u({},x(1)),{},{opacity:1,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 8px 16px",textDecoration:"underline"})),description:w(u(u({},x(2)),{},{opacity:.8,fontSize:"12px",lineHeight:"16px",margin:"8px 16px 0px 16px"}))},s=t.href||"",c=new URL(s).origin.replace(/^https?:\/\//,"").replace(/^www\./,"")||"Unknown domain",l=e.title,f=e.description;"github.com"==c?(l=(null===(r=e.title)||void 0===r?void 0:r.split(":")[0].replace("GitHub - ",""))||"No title",f=(null===(n=f)||void 0===n?void 0:n.replace(" - ".concat(l),"").replace("Contribute to ".concat(l," development by creating an account on GitHub."),""))||""):(l=e.title||"No title",f=e.description||"");return'<span style="display:block;">\n <a '.concat(o.rel," ").concat(o.target," ").concat(o.href," ").concat(o.title," ").concat(a.a,'>\n <span class="vitepress-linkcard-container" ').concat(a.container,">\n <span ").concat(a.texts,">\n <span ").concat(a.title,">\n ").concat(i(l),"\n </span>\n <span ").concat(a.domain,">\n ").concat(i(c),"\n </span>\n <span ").concat(a.description,">\n ").concat(i(f),'\n </span>\n </span>\n <img src="').concat(null==e?void 0:e.logo,'" ').concat(a.img,"/>\n </span>\n </a>\n</span>")};function O(e){return new URL(e)}var k="https://resources.whatwg.org/logo-url.svg",N=/(<[A-Za-z]+\s*[^>]*>(.*)<\/[A-Za-z]+>)/,T=/content=["|']([^>]*)["|']/,j=/href=["|']([^>]*)["|']/,C=/(<title\s*[^>]*>(.*)<\/title>)/g,R=function(e){return new RegExp("<".concat(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"meta","\\s[^>]*\\w+=['|\"]([a-zA-Z]|:|\\s)*").concat(e,"['|\"][^>]*\\/?>"))};function D(e){var t,r=e.match(R("title"));if(null!=r&&r.length){var n=r[0].match(T);n&&v(n[1])&&(t=n[1])}else{var o=e.match(C);if(null!=o&&o.length){var i=o[0].match(N);i&&v(i[2])&&(t=i[2])}}return t}function A(e){var t,r=e.match(R("description"));if(null!=r&&r.length){var n=r[0].match(T);n&&v(n[1])&&(t=n[1])}return t}function L(e){var t,r=e.match(R("image"));if(null!=r&&r.length){var n=r[0].match(T);n&&v(n[1])&&(t=n[1])}else{var o=e.match(R("icon","link"));if(null!=o&&o.length){var i=o[0].match(j);i&&v(i[1])&&(t=i[1])}}return t}function P(e,t){var r,n,o,i={title:D(e),description:A(e),logo:(r=L(e),r?O(r)?r:"".concat(null===(n=O(t))||void 0===n?void 0:n.origin).concat("/".concat(r).replace(/\/\//g,"/")):k)};return o=i,Object.values(o).filter(function(e){return v(e)}).length?i:null}function q(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var H,F={};
12
12
  /**
13
13
  * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object.
14
14
  *
@@ -20,4 +20,4 @@ import e from"url";import t from"child_process";import r from"fs";import n from"
20
20
  * @author Dan DeFelippi <dan@driverdan.com>
21
21
  * @contributor David Ellis <d.f.ellis@ieee.org>
22
22
  * @license MIT
23
- */var _=function(){if(H)return F;H=1;var i=e,a=t.spawn,s=r;return F.XMLHttpRequest=function(){var e,t,r=this,c=n,l=o,u={},f=!1,d={"User-Agent":"node-XMLHttpRequest",Accept:"*/*"},p={},h={},g=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","content-transfer-encoding","cookie","cookie2","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","via"],v=["TRACE","TRACK","CONNECT"],y=!1,b=!1,m={};this.UNSENT=0,this.OPENED=1,this.HEADERS_RECEIVED=2,this.LOADING=3,this.DONE=4,this.readyState=this.UNSENT,this.onreadystatechange=null,this.responseText="",this.responseXML="",this.status=null,this.statusText=null,this.withCredentials=!1;this.open=function(e,t,r,n,o){if(this.abort(),b=!1,!function(e){return e&&-1===v.indexOf(e)}(e))throw new Error("SecurityError: Request method not allowed");u={method:e,url:t.toString(),async:"boolean"!=typeof r||r,user:n||null,password:o||null},E(this.OPENED)},this.setDisableHeaderCheck=function(e){f=e},this.setRequestHeader=function(e,t){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");if(function(e){return f||e&&-1===g.indexOf(e.toLowerCase())}(e)){if(y)throw new Error("INVALID_STATE_ERR: send flag is true");e=h[e.toLowerCase()]||e,h[e.toLowerCase()]=e,p[e]=p[e]?p[e]+", "+t:t}else console.warn('Refused to set unsafe header "'+e+'"')},this.getResponseHeader=function(e){return"string"==typeof e&&this.readyState>this.OPENED&&t&&t.headers&&t.headers[e.toLowerCase()]&&!b?t.headers[e.toLowerCase()]:null},this.getAllResponseHeaders=function(){if(this.readyState<this.HEADERS_RECEIVED||b)return"";var e="";for(var r in t.headers)"set-cookie"!==r&&"set-cookie2"!==r&&(e+=r+": "+t.headers[r]+"\r\n");return e.substr(0,e.length-2)},this.getRequestHeader=function(e){return"string"==typeof e&&h[e.toLowerCase()]?p[h[e.toLowerCase()]]:""},this.send=function(n){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");if(y)throw new Error("INVALID_STATE_ERR: send has already been called");var o,f=!1,g=!1,v=i.parse(u.url);switch(v.protocol){case"https:":f=!0;case"http:":o=v.hostname;break;case"file:":g=!0;break;case void 0:case null:case"":o="localhost";break;default:throw new Error("Protocol not supported.")}if(g){if("GET"!==u.method)throw new Error("XMLHttpRequest: Only GET method is supported");if(u.async)s.readFile(v.pathname,"utf8",function(e,t){e?r.handleError(e):(r.status=200,r.responseText=t,E(r.DONE))});else try{this.responseText=s.readFileSync(v.pathname,"utf8"),this.status=200,E(r.DONE)}catch(e){this.handleError(e)}}else{var m=v.port||(f?443:80),w=v.pathname+(v.search?v.search:"");for(var x in d)h[x.toLowerCase()]||(p[x]=d[x]);if(p.Host=o,f&&443===m||80===m||(p.Host+=":"+v.port),u.user){void 0===u.password&&(u.password="");var S=new Buffer(u.user+":"+u.password);p.Authorization="Basic "+S.toString("base64")}"GET"===u.method||"HEAD"===u.method?n=null:n?(p["Content-Length"]=Buffer.isBuffer(n)?n.length:Buffer.byteLength(n),p["Content-Type"]||(p["Content-Type"]="text/plain;charset=UTF-8")):"POST"===u.method&&(p["Content-Length"]=0);var O={host:o,port:m,path:w,method:u.method,headers:p,agent:!1,withCredentials:r.withCredentials};if(b=!1,u.async){var C=f?l.request:c.request;y=!0,r.dispatchEvent("readystatechange");var N=function(e){r.handleError(e)};e=C(O,function n(a){if(301!==(t=a).statusCode&&302!==t.statusCode&&303!==t.statusCode&&307!==t.statusCode)t.setEncoding("utf8"),E(r.HEADERS_RECEIVED),r.status=t.statusCode,t.on("data",function(e){e&&(r.responseText+=e),y&&E(r.LOADING)}),t.on("end",function(){y&&(E(r.DONE),y=!1)}),t.on("error",function(e){r.handleError(e)});else{u.url=t.headers.location;var s=i.parse(u.url);o=s.hostname;var c={hostname:s.hostname,port:s.port,path:s.path,method:303===t.statusCode?"GET":u.method,headers:p,withCredentials:r.withCredentials};(e=C(c,n).on("error",N)).end()}}).on("error",N),n&&e.write(n),e.end(),r.dispatchEvent("loadstart")}else{var k=".node-xmlhttprequest-content-"+process.pid,T=".node-xmlhttprequest-sync-"+process.pid;s.writeFileSync(T,"","utf8");for(var j="var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http"+(f?"s":"")+".request;var options = "+JSON.stringify(O)+";var responseText = '';var req = doRequest(options, function(response) {response.setEncoding('utf8');response.on('data', function(chunk) { responseText += chunk;});response.on('end', function() {fs.writeFileSync('"+k+"', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');fs.unlinkSync('"+T+"');});response.on('error', function(error) {fs.writeFileSync('"+k+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+T+"');});}).on('error', function(error) {fs.writeFileSync('"+k+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+T+"');});"+(n?"req.write('"+JSON.stringify(n).slice(1,-1).replace(/'/g,"\\'")+"');":"")+"req.end();",R=a(process.argv[0],["-e",j]);s.existsSync(T););var D=JSON.parse(s.readFileSync(k,"utf8"));R.stdin.end(),s.unlinkSync(k),D.err?r.handleError(D.err):(t=D.data,r.status=D.data.statusCode,r.responseText=D.data.text,E(r.DONE))}}},this.handleError=function(e){this.status=0,this.statusText=e,this.responseText=e.stack,b=!0,E(this.DONE),this.dispatchEvent("error")},this.abort=function(){e&&(e.abort(),e=null),p=d,this.status=0,this.responseText="",this.responseXML="",b=!0,this.readyState===this.UNSENT||this.readyState===this.OPENED&&!y||this.readyState===this.DONE||(y=!1,E(this.DONE)),this.readyState=this.UNSENT,this.dispatchEvent("abort")},this.addEventListener=function(e,t){e in m||(m[e]=[]),m[e].push(t)},this.removeEventListener=function(e,t){e in m&&(m[e]=m[e].filter(function(e){return e!==t}))},this.dispatchEvent=function(e){if("function"==typeof r["on"+e]&&r["on"+e](),e in m)for(var t=0,n=m[e].length;t<n;t++)m[e][t].call(r)};var E=function(e){e!=r.LOADING&&r.readyState===e||(r.readyState=e,(u.async||r.readyState<r.OPENED||r.readyState===r.DONE)&&r.dispatchEvent("readystatechange"),r.readyState!==r.DONE||b||(r.dispatchEvent("load"),r.dispatchEvent("loadend")))}},F}(),I=q(_),U=new Map,B=y?window.XMLHttpRequest:I.XMLHttpRequest;function J(e){if(U.has(e))return U.get(e);var t;try{var r=new B;r.open("GET",e,!1),r.setRequestHeader("Content-Type","text/html"),r.send(),200===r.status&&r.responseText&&(t=r.responseText,U.set(e,r.responseText))}catch(e){console.error("【XHR Error】:".concat(e instanceof Error?e.message:"get remote URL resource exception!"))}return t}var M=new Map;function G(e,t){return new Promise(function(r){var n=J(e);if(n){var o=P(n,e);if(o){var i={linkTitle:t.linkTitle,target:t.target||"_blank",classPrefix:t.classPrefix},a=S(o,u(u({},i),{},{href:e})),s={url:e,data:o,options:i,dom:a};M.set(e,s),r(s)}}})}var z=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};function r(e){var r,n=function(e){if(E.has(e))return E.get(e);var t=null,r=J(e);return r&&(t=P(r,e))&&E.set(e,t),t}(e.url);if(n){!function(e,t){e.forEach(function(e,r){r!==t&&(e.hidden=!0)})}(e.tokens,e.i);var o={href:e.url,linkTitle:(r=e.tokens,r.map(function(e){var t=e.hidden,r=e.content;return t?r:""}).filter(Boolean).join("")),target:t.target||"_blank",classPrefix:t.classPrefix,borderColor:t.borderColor,bgColor:t.bgColor};return v(t.render)?t.render(n,o):S(n,o)}}e.renderer.renderInline=function(t,r,n){for(var o="",i=0;i<t.length;i++){var a=t[i],s=e.renderer.rules[a.type];a.hidden?o+="":v(s)?o+=s(t,i,r,n,e.renderer):o+=e.renderer.renderToken(t,i,r)}return o},e.renderer.rules.link_open=function(e,t,n,o,i){var a,s=e[t],c="a"===s.tag&&"link_open"===s.type,l=function(e){var t=new RegExp("^(".concat("@",":)([a-zA-Z0-9]+.*)")),r=null==e?void 0:e.match(t);return{isCardLink:!!r,url:null==r?void 0:r[2]}}(null===(a=s.attrs)||void 0===a||null===(a=a.filter(function(e){return e.includes("href")})[0])||void 0===a?void 0:a[1]),u=l.url,f=l.isCardLink;if(c&&f&&u){var d=r({url:u,tokens:e,i:t});if(d)return d}return i.renderToken(e,t,n)}};export{G as generateCard,z as linkToCardPlugin};
23
+ */var _=function(){if(H)return F;H=1;var i=e,a=t.spawn,s=r;return F.XMLHttpRequest=function(){var e,t,r=this,c=n,l=o,u={},f=!1,p={"User-Agent":"node-XMLHttpRequest",Accept:"*/*"},d={},h={},v=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","content-transfer-encoding","cookie","cookie2","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","via"],g=["TRACE","TRACK","CONNECT"],y=!1,b=!1,m={};this.UNSENT=0,this.OPENED=1,this.HEADERS_RECEIVED=2,this.LOADING=3,this.DONE=4,this.readyState=this.UNSENT,this.onreadystatechange=null,this.responseText="",this.responseXML="",this.status=null,this.statusText=null,this.withCredentials=!1;this.open=function(e,t,r,n,o){if(this.abort(),b=!1,!function(e){return e&&-1===g.indexOf(e)}(e))throw new Error("SecurityError: Request method not allowed");u={method:e,url:t.toString(),async:"boolean"!=typeof r||r,user:n||null,password:o||null},E(this.OPENED)},this.setDisableHeaderCheck=function(e){f=e},this.setRequestHeader=function(e,t){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");if(function(e){return f||e&&-1===v.indexOf(e.toLowerCase())}(e)){if(y)throw new Error("INVALID_STATE_ERR: send flag is true");e=h[e.toLowerCase()]||e,h[e.toLowerCase()]=e,d[e]=d[e]?d[e]+", "+t:t}else console.warn('Refused to set unsafe header "'+e+'"')},this.getResponseHeader=function(e){return"string"==typeof e&&this.readyState>this.OPENED&&t&&t.headers&&t.headers[e.toLowerCase()]&&!b?t.headers[e.toLowerCase()]:null},this.getAllResponseHeaders=function(){if(this.readyState<this.HEADERS_RECEIVED||b)return"";var e="";for(var r in t.headers)"set-cookie"!==r&&"set-cookie2"!==r&&(e+=r+": "+t.headers[r]+"\r\n");return e.substr(0,e.length-2)},this.getRequestHeader=function(e){return"string"==typeof e&&h[e.toLowerCase()]?d[h[e.toLowerCase()]]:""},this.send=function(n){if(this.readyState!==this.OPENED)throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");if(y)throw new Error("INVALID_STATE_ERR: send has already been called");var o,f=!1,v=!1,g=i.parse(u.url);switch(g.protocol){case"https:":f=!0;case"http:":o=g.hostname;break;case"file:":v=!0;break;case void 0:case null:case"":o="localhost";break;default:throw new Error("Protocol not supported.")}if(v){if("GET"!==u.method)throw new Error("XMLHttpRequest: Only GET method is supported");if(u.async)s.readFile(g.pathname,"utf8",function(e,t){e?r.handleError(e):(r.status=200,r.responseText=t,E(r.DONE))});else try{this.responseText=s.readFileSync(g.pathname,"utf8"),this.status=200,E(r.DONE)}catch(e){this.handleError(e)}}else{var m=g.port||(f?443:80),w=g.pathname+(g.search?g.search:"");for(var x in p)h[x.toLowerCase()]||(d[x]=p[x]);if(d.Host=o,f&&443===m||80===m||(d.Host+=":"+g.port),u.user){void 0===u.password&&(u.password="");var S=new Buffer(u.user+":"+u.password);d.Authorization="Basic "+S.toString("base64")}"GET"===u.method||"HEAD"===u.method?n=null:n?(d["Content-Length"]=Buffer.isBuffer(n)?n.length:Buffer.byteLength(n),d["Content-Type"]||(d["Content-Type"]="text/plain;charset=UTF-8")):"POST"===u.method&&(d["Content-Length"]=0);var O={host:o,port:m,path:w,method:u.method,headers:d,agent:!1,withCredentials:r.withCredentials};if(b=!1,u.async){var k=f?l.request:c.request;y=!0,r.dispatchEvent("readystatechange");var N=function(e){r.handleError(e)};e=k(O,function n(a){if(301!==(t=a).statusCode&&302!==t.statusCode&&303!==t.statusCode&&307!==t.statusCode)t.setEncoding("utf8"),E(r.HEADERS_RECEIVED),r.status=t.statusCode,t.on("data",function(e){e&&(r.responseText+=e),y&&E(r.LOADING)}),t.on("end",function(){y&&(E(r.DONE),y=!1)}),t.on("error",function(e){r.handleError(e)});else{u.url=t.headers.location;var s=i.parse(u.url);o=s.hostname;var c={hostname:s.hostname,port:s.port,path:s.path,method:303===t.statusCode?"GET":u.method,headers:d,withCredentials:r.withCredentials};(e=k(c,n).on("error",N)).end()}}).on("error",N),n&&e.write(n),e.end(),r.dispatchEvent("loadstart")}else{var T=".node-xmlhttprequest-content-"+process.pid,j=".node-xmlhttprequest-sync-"+process.pid;s.writeFileSync(j,"","utf8");for(var C="var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http"+(f?"s":"")+".request;var options = "+JSON.stringify(O)+";var responseText = '';var req = doRequest(options, function(response) {response.setEncoding('utf8');response.on('data', function(chunk) { responseText += chunk;});response.on('end', function() {fs.writeFileSync('"+T+"', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');fs.unlinkSync('"+j+"');});response.on('error', function(error) {fs.writeFileSync('"+T+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+j+"');});}).on('error', function(error) {fs.writeFileSync('"+T+"', JSON.stringify({err: error}), 'utf8');fs.unlinkSync('"+j+"');});"+(n?"req.write('"+JSON.stringify(n).slice(1,-1).replace(/'/g,"\\'")+"');":"")+"req.end();",R=a(process.argv[0],["-e",C]);s.existsSync(j););var D=JSON.parse(s.readFileSync(T,"utf8"));R.stdin.end(),s.unlinkSync(T),D.err?r.handleError(D.err):(t=D.data,r.status=D.data.statusCode,r.responseText=D.data.text,E(r.DONE))}}},this.handleError=function(e){this.status=0,this.statusText=e,this.responseText=e.stack,b=!0,E(this.DONE),this.dispatchEvent("error")},this.abort=function(){e&&(e.abort(),e=null),d=p,this.status=0,this.responseText="",this.responseXML="",b=!0,this.readyState===this.UNSENT||this.readyState===this.OPENED&&!y||this.readyState===this.DONE||(y=!1,E(this.DONE)),this.readyState=this.UNSENT,this.dispatchEvent("abort")},this.addEventListener=function(e,t){e in m||(m[e]=[]),m[e].push(t)},this.removeEventListener=function(e,t){e in m&&(m[e]=m[e].filter(function(e){return e!==t}))},this.dispatchEvent=function(e){if("function"==typeof r["on"+e]&&r["on"+e](),e in m)for(var t=0,n=m[e].length;t<n;t++)m[e][t].call(r)};var E=function(e){e!=r.LOADING&&r.readyState===e||(r.readyState=e,(u.async||r.readyState<r.OPENED||r.readyState===r.DONE)&&r.dispatchEvent("readystatechange"),r.readyState!==r.DONE||b||(r.dispatchEvent("load"),r.dispatchEvent("loadend")))}},F}(),I=q(_),U=new Map,B=y?window.XMLHttpRequest:I.XMLHttpRequest;function J(e){if(U.has(e))return U.get(e);var t;try{var r=new B;r.open("GET",e,!1),r.setRequestHeader("Content-Type","text/html"),r.send(),200===r.status&&r.responseText&&(t=r.responseText,U.set(e,r.responseText))}catch(e){console.error("【XHR Error】:".concat(e instanceof Error?e.message:"get remote URL resource exception!"))}return t}var M=new Map;function G(e,t){return new Promise(function(r){var n=J(e);if(n){var o=P(n,e);if(o){var i={linkTitle:t.linkTitle,target:t.target||"_blank",classPrefix:t.classPrefix},a=S(o,u(u({},i),{},{href:e})),s={url:e,data:o,options:i,dom:a};M.set(e,s),r(s)}}})}var z=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};function r(e){var r,n=function(e){if(E.has(e))return E.get(e);var t=null,r=J(e);return r&&(t=P(r,e))&&E.set(e,t),t}(e.url);if(n){!function(e,t){e.forEach(function(e,r){r!==t&&(e.hidden=!0)})}(e.tokens,e.i);var o={href:e.url,linkTitle:(r=e.tokens,r.map(function(e){var t=e.hidden,r=e.content;return t?r:""}).filter(Boolean).join("")),target:t.target||"_blank",classPrefix:t.classPrefix};return g(t.render)?t.render(n,o):S(n,o)}}e.renderer.renderInline=function(t,r,n){for(var o="",i=0;i<t.length;i++){var a=t[i],s=e.renderer.rules[a.type];a.hidden?o+="":g(s)?o+=s(t,i,r,n,e.renderer):o+=e.renderer.renderToken(t,i,r)}return o},e.renderer.rules.link_open=function(e,t,n,o,i){var a,s=e[t],c="a"===s.tag&&"link_open"===s.type,l=function(e){var t=new RegExp("^(".concat("@",":)([a-zA-Z0-9]+.*)")),r=null==e?void 0:e.match(t);return{isCardLink:!!r,url:null==r?void 0:r[2]}}(null===(a=s.attrs)||void 0===a||null===(a=a.filter(function(e){return e.includes("href")})[0])||void 0===a?void 0:a[1]),u=l.url,f=l.isCardLink;if(c&&f&&u){var p=r({url:u,tokens:e,i:t});if(p)return p}return i.renderToken(e,t,n)}};export{G as generateCard,z as linkToCardPlugin};
package/dist/api.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { xhr, generateCardDomFragment, parserMetadata } from './assemble';
2
2
  const cache = new Map();
3
3
  /**
4
- * @param url
5
- * @param options
6
- * @returns
4
+ * Generates a link card by fetching and parsing metadata from a URL.
5
+ *
6
+ * @param url - The URL to fetch metadata from
7
+ * @param options - Rendering options for the card
8
+ * @returns A promise that resolves to a CardResponse containing the card data and HTML
7
9
  */
8
10
  export function generateCard(url, options) {
9
11
  return new Promise((resolve) => {
@@ -1,17 +1,17 @@
1
1
  import { STYLE } from './style';
2
2
  /**
3
- * @param data
4
- * @param options
5
- * @returns
3
+ * Generates the HTML DOM fragment for a link card display.
4
+ *
5
+ * @param data - The metadata extracted from the URL
6
+ * @param options - Rendering options including href, target, etc.
7
+ * @returns An HTML string containing the card markup
6
8
  */
7
9
  export const generateCardDomFragment = (data, options) => {
8
10
  const aa = {
9
11
  rel: `rel="noopener noreferrer"`,
10
12
  target: `target="${options.target}"`,
11
13
  href: `href="${options.href}"`,
12
- title: `title="${options.linkTitle}"`,
13
- borderColor: `borderColor="${options.borderColor}"`,
14
- bgColor: `bgColor="${options.bgColor}"`
14
+ title: `title="${options.linkTitle}"`
15
15
  };
16
16
  const inject = (s) => {
17
17
  return s;
@@ -22,18 +22,18 @@ export const generateCardDomFragment = (data, options) => {
22
22
  .replace(/&gt;/g, '>')
23
23
  .replace(/&quot;/g, '"')
24
24
  .replace(/&#039;/g, "'");
25
- const style = STYLE(options.borderColor || '#7d7d7dff', options.bgColor || '#7d7d7d00');
25
+ const style = STYLE();
26
26
  const url = options.href || '';
27
27
  const domain = new URL(url).origin.replace(/^https?:\/\//, '').replace(/^www\./, '') ||
28
28
  'Unknown domain';
29
29
  let title = data.title;
30
30
  let description = data.description;
31
- // Special handling for gitub.com
32
31
  if (domain == 'github.com') {
33
32
  title = data.title?.split(':')[0].replace('GitHub - ', '') || 'No title';
34
33
  description =
35
- description?.replace(` - ${title}`, '').replace(`Contribute to ${title} development by creating an account on GitHub.`, // 定型句
36
- '') || '';
34
+ description
35
+ ?.replace(` - ${title}`, '')
36
+ .replace(`Contribute to ${title} development by creating an account on GitHub.`, '') || '';
37
37
  }
38
38
  else {
39
39
  title = data.title || 'No title';
@@ -41,7 +41,7 @@ export const generateCardDomFragment = (data, options) => {
41
41
  }
42
42
  return `<span style="display:block;">
43
43
  <a ${aa.rel} ${aa.target} ${aa.href} ${aa.title} ${style.a}>
44
- <span ${inject(style.container)}>
44
+ <span class="vitepress-linkcard-container" ${inject(style.container)}>
45
45
  <span ${inject(style.texts)}>
46
46
  <span ${inject(style.title)}>
47
47
  ${escapeHTML(title)}
@@ -32,11 +32,11 @@ const format = () => {
32
32
  const formatted = JSON.stringify(parsed, null, 2) + '\n';
33
33
  fs.writeFileSync(filePath, formatted);
34
34
  };
35
+ /**
36
+ * A simple file-based cache for storing and retrieving structured data.
37
+ */
35
38
  export default class LocalFileCache {
36
39
  constructor() { }
37
- /**
38
- * @param data
39
- */
40
40
  setFile(data) {
41
41
  let content = data;
42
42
  const _content = this.readFile();
@@ -46,9 +46,6 @@ export default class LocalFileCache {
46
46
  fs.writeFileSync(CONFIG_FILE(), JSON.stringify(content));
47
47
  format();
48
48
  }
49
- /**
50
- * @returns
51
- */
52
49
  readFile() {
53
50
  const content = fs.readFileSync(CONFIG_FILE(), 'utf-8');
54
51
  const data = JSON.parse(content);
@@ -56,25 +53,13 @@ export default class LocalFileCache {
56
53
  return data;
57
54
  return undefined;
58
55
  }
59
- /**
60
- * @param url
61
- * @returns
62
- */
63
56
  has(url) {
64
57
  return !!this.get(url);
65
58
  }
66
- /**
67
- * @param url
68
- * @returns
69
- */
70
59
  get(url) {
71
60
  const cache = this.readFile();
72
61
  return cache?.[url];
73
62
  }
74
- /**
75
- * @param url
76
- * @param data
77
- */
78
63
  set(url, data) {
79
64
  this.setFile({ [url]: data });
80
65
  }
@@ -2,8 +2,10 @@ import { parserMetadata, xhr } from '.';
2
2
  import LocalFileCache from './local-file-cache';
3
3
  const cache = new LocalFileCache();
4
4
  /**
5
- * @param url
6
- * @returns
5
+ * Retrieves metadata for a given URL, using cache when available.
6
+ *
7
+ * @param url - The URL to fetch metadata from
8
+ * @returns The parsed URL metadata, or null if unavailable
7
9
  */
8
10
  export function getUrlMetadata(url) {
9
11
  if (cache.has(url))
@@ -1,6 +1,3 @@
1
- /**
2
- * TODO: Refactor
3
- */
4
1
  import { isString } from '@luckrya/utility';
5
2
  import { cleanPath, extractUrl } from './url';
6
3
  const DEFAULT_LOGO = 'https://resources.whatwg.org/logo-url.svg';
@@ -8,16 +5,7 @@ const HtmlTagContentReg = /(<[A-Za-z]+\s*[^>]*>(.*)<\/[A-Za-z]+>)/;
8
5
  const ContentAttrValueHtmlMetaTagReg = /content=["|']([^>]*)["|']/;
9
6
  const HrefAttrValueHtmlLinkTagReg = /href=["|']([^>]*)["|']/;
10
7
  const HtmlTitleTagReg = /(<title\s*[^>]*>(.*)<\/title>)/g;
11
- // const HtmlMetaTagReg = /<meta\s[^>]*\/?>/g;
12
- // const HtmlLinkTagReg = /<link\s[^>]*\/?>/g;
13
8
  const containArrSelfLosingHtmlTagReg = (attr, tag = 'meta') => new RegExp(`<${tag}\\s[^>]*\\w+=['|"]([a-zA-Z]|:|\\s)*${attr}['|"][^>]*\\/?>`);
14
- /**
15
- * @param htmlString
16
- * @returns
17
- * <title>$value</title>
18
- * <meta property="og:title" content="$value" />
19
- * <link data-react-helmet="true" href="https://s.xml" rel="search" title="$value" type="applon+xml">
20
- */
21
9
  function matchTitleByMetaTag(htmlString) {
22
10
  let title;
23
11
  const metas = htmlString.match(containArrSelfLosingHtmlTagReg('title'));
@@ -36,11 +24,6 @@ function matchTitleByMetaTag(htmlString) {
36
24
  }
37
25
  return title;
38
26
  }
39
- /**
40
- * @returns
41
- * <meta name="description" content="$value" />
42
- * <meta property="og:description" content="$value" />
43
- */
44
27
  function matchDescriptionByMetaTag(htmlString) {
45
28
  let description;
46
29
  const metas = htmlString.match(containArrSelfLosingHtmlTagReg('description'));
@@ -51,11 +34,6 @@ function matchDescriptionByMetaTag(htmlString) {
51
34
  }
52
35
  return description;
53
36
  }
54
- /**
55
- * @returns
56
- * <meta property="og:image" content="$value" />
57
- * <link rel="icon" href="$value">
58
- */
59
37
  function matchLogoByLinkOrMetaTag(htmlString) {
60
38
  let logo;
61
39
  const metas = htmlString.match(containArrSelfLosingHtmlTagReg('image'));
@@ -68,7 +46,6 @@ function matchLogoByLinkOrMetaTag(htmlString) {
68
46
  const linkHtmlTags = htmlString.match(containArrSelfLosingHtmlTagReg('icon', 'link'));
69
47
  if (linkHtmlTags?.length) {
70
48
  const content = linkHtmlTags[0].match(HrefAttrValueHtmlLinkTagReg);
71
- // logo 判断是否是完整地址
72
49
  if (content && isString(content[1]))
73
50
  logo = content[1];
74
51
  }
@@ -76,9 +53,11 @@ function matchLogoByLinkOrMetaTag(htmlString) {
76
53
  return logo;
77
54
  }
78
55
  /**
79
- * @param htmlString
80
- * @param url
81
- * @returns
56
+ * Parses HTML string to extract structured metadata for link card generation.
57
+ *
58
+ * @param htmlString - The HTML content to parse
59
+ * @param url - The URL of the page
60
+ * @returns Parsed metadata object, or null if no valid metadata found
82
61
  */
83
62
  export function parserMetadata(htmlString, url) {
84
63
  function absolute(logo) {
@@ -86,7 +65,7 @@ export function parserMetadata(htmlString, url) {
86
65
  return DEFAULT_LOGO;
87
66
  return extractUrl(logo)
88
67
  ? logo
89
- : `${extractUrl(url)?.origin}${cleanPath(`/${logo}`)}`; // TODO: no match "content='//img.xx.com/a.png'"
68
+ : `${extractUrl(url)?.origin}${cleanPath(`/${logo}`)}`;
90
69
  }
91
70
  const metadata = {
92
71
  title: matchTitleByMetaTag(htmlString),
@@ -98,10 +77,6 @@ export function parserMetadata(htmlString, url) {
98
77
  else
99
78
  return metadata;
100
79
  }
101
- /**
102
- * @param obj
103
- * @returns
104
- */
105
80
  function isEmptyStringObject(obj) {
106
81
  return !Object.values(obj).filter((v) => isString(v)).length;
107
82
  }
@@ -1,14 +1,6 @@
1
- /**
2
- * @param str
3
- * @returns
4
- */
5
1
  function hyphenate(str) {
6
2
  return str.replace(/\B([A-Z])/g, '-$1').toLowerCase();
7
3
  }
8
- /**
9
- * @param style
10
- * @returns
11
- */
12
4
  function join(style) {
13
5
  return Object.entries(style)
14
6
  .map(([k, v]) => {
@@ -18,17 +10,9 @@ function join(style) {
18
10
  .filter(Boolean)
19
11
  .join(' ');
20
12
  }
21
- /**
22
- * @param style
23
- * @returns
24
- */
25
13
  function inlineStyle(style) {
26
14
  return `style="${join(style)}"`;
27
15
  }
28
- /**
29
- * @param line
30
- * @returns
31
- */
32
16
  const ellipsisStyle = (line) => ({
33
17
  '-webkit-box-orient': 'vertical',
34
18
  '-webkit-line-clamp': line,
@@ -41,12 +25,9 @@ const ellipsisStyle = (line) => ({
41
25
  wordBreak: 'break-word'
42
26
  });
43
27
  /**
44
- See: * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/components/VPFeature.vue
45
- * @param borderColor
46
- * @param bgColor
47
- * @returns
28
+ * Generates complete inline styles for all link card components.
48
29
  */
49
- export const STYLE = (borderColor, bgColor) => ({
30
+ export const STYLE = () => ({
50
31
  a: inlineStyle({
51
32
  color: 'unset !important',
52
33
  display: 'block',
@@ -59,23 +40,24 @@ export const STYLE = (borderColor, bgColor) => ({
59
40
  flexWrap: 'wrap',
60
41
  gap: '10px',
61
42
  borderRadius: '12px',
62
- border: `1px solid ${borderColor}`,
63
- backgroundColor: bgColor,
43
+ border: `1px solid var(--vp-c-bg-soft)`,
44
+ backgroundColor: `var(--vp-c-bg-soft)`,
64
45
  boxSizing: 'border-box',
65
46
  width: '100%',
66
- height: '130px'
47
+ height: '130px',
48
+ transition: 'border-color 0.25s, background-color 0.25s'
67
49
  }),
68
50
  img: inlineStyle({
69
51
  borderRadius: '0px 12px 12px 0px',
70
52
  maxWidth: '40%',
71
- height: '128px', // container.height - 2px
53
+ height: '129px',
72
54
  flexShrink: 0,
73
55
  objectFit: 'contain',
74
56
  overflow: 'hidden'
75
57
  }),
76
58
  texts: inlineStyle({
77
59
  flex: '1 1 0%',
78
- minWidth: '0' // ellipsisを有効にするために必要
60
+ minWidth: '0'
79
61
  }),
80
62
  title: inlineStyle({
81
63
  ...ellipsisStyle(2),
@@ -101,10 +83,6 @@ export const STYLE = (borderColor, bgColor) => ({
101
83
  margin: '8px 16px 0px 16px'
102
84
  })
103
85
  });
104
- /**
105
- * @param prefix
106
- * @returns
107
- */
108
86
  export const classNames = (prefix) => ({
109
87
  container: `${prefix}__container`,
110
88
  img: `${prefix}__img`,
@@ -1,13 +1,17 @@
1
1
  /**
2
- * @param url
3
- * @returns
2
+ * Parses a URL string and returns a URL object.
3
+ *
4
+ * @param url - The URL string to parse
5
+ * @returns A URL object containing the parsed components
4
6
  */
5
7
  export function extractUrl(url) {
6
8
  return new URL(url);
7
9
  }
8
10
  /**
9
- * @param path
10
- * @returns
11
+ * Removes duplicate consecutive slashes from a path string.
12
+ *
13
+ * @param path - The path string to clean
14
+ * @returns The cleaned path with no consecutive slashes
11
15
  */
12
16
  export function cleanPath(path) {
13
17
  return path.replace(/\/\//g, '/');
@@ -1,13 +1,13 @@
1
- // Refactor: xmlhttprequest will be replaced later
2
1
  // @ts-expect-error: xmlhttprequest has no types
3
2
  import xhrForNode from 'xmlhttprequest';
4
3
  import { inBrowser, isString } from '@luckrya/utility';
5
- // TODO: Local File Cache
6
4
  const cache = new Map();
7
5
  const XHR = inBrowser ? window.XMLHttpRequest : xhrForNode.XMLHttpRequest;
8
6
  /**
9
- * @param url
10
- * @returns
7
+ * Performs a synchronous HTTP GET request to fetch HTML content from a URL.
8
+ *
9
+ * @param url - The URL to fetch content from
10
+ * @returns The HTML content as a string, or undefined if the request fails
11
11
  */
12
12
  export function sync(url) {
13
13
  if (cache.has(url))
@@ -29,8 +29,10 @@ export function sync(url) {
29
29
  return result;
30
30
  }
31
31
  /**
32
- * @param url
33
- * @returns
32
+ * Performs an asynchronous HTTP GET request to fetch HTML content from a URL.
33
+ *
34
+ * @param url - The URL to fetch content from
35
+ * @returns A Promise that resolves to the HTML content string
34
36
  */
35
37
  export function async(url) {
36
38
  return new Promise((resolve, reject) => {
@@ -1,8 +1,10 @@
1
1
  import { isFunction } from '@luckrya/utility';
2
2
  import { getUrlMetadata, generateCardDomFragment } from './assemble';
3
3
  /**
4
- * @param md
5
- * @param pluginOptions
4
+ * Markdown-it plugin that converts specially-formatted links into rich link preview cards.
5
+ *
6
+ * @param md - The markdown-it instance
7
+ * @param pluginOptions - Configuration options for the plugin
6
8
  */
7
9
  export const linkToCardPlugin = (md, pluginOptions = {}) => {
8
10
  function parseCardLinkHref(href) {
@@ -13,34 +15,21 @@ export const linkToCardPlugin = (md, pluginOptions = {}) => {
13
15
  url: match?.[2]
14
16
  };
15
17
  }
16
- /**
17
- * @param options
18
- * @returns
19
- */
20
18
  function assembleCardTpl(options) {
21
19
  const urlMetadata = getUrlMetadata(options.url);
22
20
  if (urlMetadata) {
23
- ignoreRestToken(options.tokens, options.i); // linkTitle 依赖 ignoreRestToken 的处理结果
21
+ ignoreRestToken(options.tokens, options.i);
24
22
  const cardDomOptions = {
25
23
  href: options.url,
26
24
  linkTitle: joinLinkTitle(options.tokens),
27
25
  target: pluginOptions.target || '_blank',
28
- classPrefix: pluginOptions.classPrefix,
29
- borderColor: pluginOptions.borderColor,
30
- bgColor: pluginOptions.bgColor
26
+ classPrefix: pluginOptions.classPrefix
31
27
  };
32
28
  return isFunction(pluginOptions.render)
33
29
  ? pluginOptions.render(urlMetadata, cardDomOptions)
34
30
  : generateCardDomFragment(urlMetadata, cardDomOptions);
35
31
  }
36
32
  }
37
- /**
38
- * https://markdown-it.github.io/markdown-it/#MarkdownIt.renderInline
39
- * @param tokens
40
- * @param rootOptions
41
- * @param env
42
- * @returns
43
- */
44
33
  md.renderer.renderInline = (tokens, rootOptions, env) => {
45
34
  let result = '';
46
35
  for (let i = 0; i < tokens.length; i++) {
@@ -58,15 +47,6 @@ export const linkToCardPlugin = (md, pluginOptions = {}) => {
58
47
  }
59
48
  return result;
60
49
  };
61
- /**
62
- * envは呼ばれなくても消さないこと
63
- * @param tokens
64
- * @param i
65
- * @param rootOptions
66
- * @param env
67
- * @param self
68
- * @returns
69
- */
70
50
  md.renderer.rules.link_open = (tokens, i, rootOptions, env, self) => {
71
51
  const token = tokens[i];
72
52
  const isLinkOpenToken = token.tag === 'a' && token.type === 'link_open';
@@ -80,21 +60,12 @@ export const linkToCardPlugin = (md, pluginOptions = {}) => {
80
60
  return self.renderToken(tokens, i, rootOptions);
81
61
  };
82
62
  };
83
- /**
84
- * TODO: handle softbreak https://markdown-it.github.io/
85
- * @param tokens
86
- * @param i
87
- */
88
63
  function ignoreRestToken(tokens, i) {
89
64
  tokens.forEach((token, index) => {
90
65
  if (index !== i)
91
66
  token.hidden = true;
92
67
  });
93
68
  }
94
- /**
95
- * @param tokens
96
- * @returns
97
- */
98
69
  function joinLinkTitle(tokens) {
99
70
  return tokens
100
71
  .map(({ hidden, content }) => {
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "@types/babel__core": "^7",
23
23
  "@types/markdown-it": "^13.0.2",
24
24
  "@types/node": "^25.0.3",
25
- "eslint": "npm:9.39.2",
25
+ "eslint": "^9.39.2",
26
26
  "eslint-plugin-vue": "^10.6.2",
27
27
  "globals": "^16.5.0",
28
28
  "jiti": "^2.6.1",
@@ -75,5 +75,5 @@
75
75
  },
76
76
  "type": "module",
77
77
  "types": "./types/index.d.ts",
78
- "version": "1.3.0"
78
+ "version": "2.0.1"
79
79
  }
package/types/api.d.ts CHANGED
@@ -6,9 +6,11 @@ interface CardResponse {
6
6
  dom: string;
7
7
  }
8
8
  /**
9
- * @param url
10
- * @param options
11
- * @returns
9
+ * Generates a link card by fetching and parsing metadata from a URL.
10
+ *
11
+ * @param url - The URL to fetch metadata from
12
+ * @param options - Rendering options for the card
13
+ * @returns A promise that resolves to a CardResponse containing the card data and HTML
12
14
  */
13
15
  export declare function generateCard(url: string, options: Omit<CardDomRenderOptions, 'href'>): Promise<CardResponse>;
14
16
  export {};
@@ -1,7 +1,9 @@
1
1
  import type { CardDomRender } from '../types';
2
2
  /**
3
- * @param data
4
- * @param options
5
- * @returns
3
+ * Generates the HTML DOM fragment for a link card display.
4
+ *
5
+ * @param data - The metadata extracted from the URL
6
+ * @param options - Rendering options including href, target, etc.
7
+ * @returns An HTML string containing the card markup
6
8
  */
7
9
  export declare const generateCardDomFragment: CardDomRender;
@@ -1,26 +1,11 @@
1
+ /**
2
+ * A simple file-based cache for storing and retrieving structured data.
3
+ */
1
4
  export default class LocalFileCache<V extends Record<string, unknown>> {
2
5
  constructor();
3
- /**
4
- * @param data
5
- */
6
6
  private setFile;
7
- /**
8
- * @returns
9
- */
10
7
  private readFile;
11
- /**
12
- * @param url
13
- * @returns
14
- */
15
8
  has(url: string): boolean;
16
- /**
17
- * @param url
18
- * @returns
19
- */
20
9
  get(url: string): V | undefined;
21
- /**
22
- * @param url
23
- * @param data
24
- */
25
10
  set(url: string, data: V): void;
26
11
  }
@@ -1,6 +1,8 @@
1
1
  import type { UrlMetadata } from '../types';
2
2
  /**
3
- * @param url
4
- * @returns
3
+ * Retrieves metadata for a given URL, using cache when available.
4
+ *
5
+ * @param url - The URL to fetch metadata from
6
+ * @returns The parsed URL metadata, or null if unavailable
5
7
  */
6
8
  export declare function getUrlMetadata(url: string): UrlMetadata | null | undefined;
@@ -1,10 +1,9 @@
1
- /**
2
- * TODO: Refactor
3
- */
4
1
  import type { UrlMetadata } from '../types';
5
2
  /**
6
- * @param htmlString
7
- * @param url
8
- * @returns
3
+ * Parses HTML string to extract structured metadata for link card generation.
4
+ *
5
+ * @param htmlString - The HTML content to parse
6
+ * @param url - The URL of the page
7
+ * @returns Parsed metadata object, or null if no valid metadata found
9
8
  */
10
9
  export declare function parserMetadata(htmlString: string, url: string): UrlMetadata | null;
@@ -1,10 +1,7 @@
1
1
  /**
2
- See: * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/components/VPFeature.vue
3
- * @param borderColor
4
- * @param bgColor
5
- * @returns
2
+ * Generates complete inline styles for all link card components.
6
3
  */
7
- export declare const STYLE: (borderColor: string, bgColor: string) => {
4
+ export declare const STYLE: () => {
8
5
  a: string;
9
6
  container: string;
10
7
  img: string;
@@ -13,10 +10,6 @@ export declare const STYLE: (borderColor: string, bgColor: string) => {
13
10
  domain: string;
14
11
  description: string;
15
12
  };
16
- /**
17
- * @param prefix
18
- * @returns
19
- */
20
13
  export declare const classNames: (prefix?: string) => {
21
14
  container: string;
22
15
  img: string;
@@ -1,10 +1,14 @@
1
1
  /**
2
- * @param url
3
- * @returns
2
+ * Parses a URL string and returns a URL object.
3
+ *
4
+ * @param url - The URL string to parse
5
+ * @returns A URL object containing the parsed components
4
6
  */
5
7
  export declare function extractUrl(url: string): URL;
6
8
  /**
7
- * @param path
8
- * @returns
9
+ * Removes duplicate consecutive slashes from a path string.
10
+ *
11
+ * @param path - The path string to clean
12
+ * @returns The cleaned path with no consecutive slashes
9
13
  */
10
14
  export declare function cleanPath(path: string): string;
@@ -1,10 +1,14 @@
1
1
  /**
2
- * @param url
3
- * @returns
2
+ * Performs a synchronous HTTP GET request to fetch HTML content from a URL.
3
+ *
4
+ * @param url - The URL to fetch content from
5
+ * @returns The HTML content as a string, or undefined if the request fails
4
6
  */
5
7
  export declare function sync(url: string): string | undefined;
6
8
  /**
7
- * @param url
8
- * @returns
9
+ * Performs an asynchronous HTTP GET request to fetch HTML content from a URL.
10
+ *
11
+ * @param url - The URL to fetch content from
12
+ * @returns A Promise that resolves to the HTML content string
9
13
  */
10
14
  export declare function async(url: string): Promise<string | undefined>;
@@ -1,6 +1,8 @@
1
1
  import type { LinkToCardPlugin } from './types';
2
2
  /**
3
- * @param md
4
- * @param pluginOptions
3
+ * Markdown-it plugin that converts specially-formatted links into rich link preview cards.
4
+ *
5
+ * @param md - The markdown-it instance
6
+ * @param pluginOptions - Configuration options for the plugin
5
7
  */
6
8
  export declare const linkToCardPlugin: LinkToCardPlugin;
package/types/types.d.ts CHANGED
@@ -1,25 +1,124 @@
1
1
  import type MarkdownIt from 'markdown-it';
2
+ /**
3
+ * Type definition for the link-to-card plugin compatible with markdown-it.
4
+ *
5
+ * @see {@link https://markdown-it.github.io/markdown-it/#MarkdownIt.use | MarkdownIt.use}
6
+ */
2
7
  export type LinkToCardPlugin = MarkdownIt.PluginWithOptions<LinkToCardPluginOptions>;
8
+ /**
9
+ * Configuration options for the link-to-card plugin.
10
+ *
11
+ * This interface defines the customization options available when using the vitepress-linkcard plugin.
12
+ * The plugin converts specially-formatted markdown links (prefixed with `@:`) into rich link preview cards
13
+ * with Open Graph Protocol (OGP) metadata.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { linkToCardPlugin } from 'vitepress-linkcard'
18
+ *
19
+ * markdownIt.use(linkToCardPlugin, {
20
+ * target: '_blank'
21
+ * })
22
+ * ```
23
+ *
24
+ * @see {@link https://daringfireball.net/projects/markdown/syntax#link | Markdown Link Syntax}
25
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target | HTML anchor target attribute}
26
+ */
3
27
  export interface LinkToCardPluginOptions {
28
+ /**
29
+ * Where to display the linked URL.
30
+ * @defaultValue `'_blank'` - Opens the link in a new tab/window
31
+ */
4
32
  target?: ATarget;
33
+ /**
34
+ * CSS class name prefix for the card DOM elements.
35
+ * When set, no inline styles are injected; only the class names are applied.
36
+ *
37
+ * @example `'my-docs__link-card'`
38
+ */
5
39
  classPrefix?: string;
40
+ /**
41
+ * Custom function to render the DOM fragment for the link card.
42
+ * When provided, this function is used instead of the default card renderer.
43
+ */
6
44
  render?: CardDomRender;
7
- borderColor?: string;
8
- bgColor?: string;
9
45
  }
46
+ /**
47
+ * Metadata extracted from a URL's HTML page using Open Graph Protocol tags and meta tags.
48
+ *
49
+ * This interface represents the structured data fetched from a web page to populate the link card display.
50
+ * The metadata is typically extracted from `<meta>` tags, OGP tags, and other HTML elements.
51
+ *
52
+ * @see {@link https://ogp.me/ | Open Graph Protocol}
53
+ */
10
54
  export interface UrlMetadata {
55
+ /**
56
+ * The title of the page, extracted from `<title>` or `<meta property="og:title">` tags.
57
+ */
11
58
  title?: string;
59
+ /**
60
+ * The description of the page, extracted from `<meta name="description">` or
61
+ * `<meta property="og:description">` tags.
62
+ */
12
63
  description?: string;
64
+ /**
65
+ * The logo or icon URL for the page, extracted from `<meta property="og:image">` or
66
+ * `<link rel="icon">` tags.
67
+ */
13
68
  logo?: string;
69
+ /**
70
+ * Additional metadata properties that may be extracted from the page.
71
+ */
14
72
  [key: string]: unknown;
15
73
  }
74
+ /**
75
+ * Valid values for the HTML anchor element's `target` attribute.
76
+ *
77
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target | MDN - target attribute}
78
+ */
16
79
  export type ATarget = '_self' | '_blank' | '_top' | '_parent';
80
+ /**
81
+ * Options passed to the card DOM renderer function.
82
+ *
83
+ * This interface provides all the necessary information to render a link card,
84
+ * including the URL, display preferences, and styling options.
85
+ */
17
86
  export interface CardDomRenderOptions {
87
+ /**
88
+ * The URL to link to.
89
+ */
18
90
  href: string;
91
+ /**
92
+ * The title text to display on the link (typically from the markdown link text).
93
+ */
19
94
  linkTitle: string;
95
+ /**
96
+ * Where to display the linked URL when clicked.
97
+ */
20
98
  target: ATarget;
99
+ /**
100
+ * CSS class name prefix for the card DOM elements.
101
+ */
21
102
  classPrefix?: string;
22
- borderColor?: string;
23
- bgColor?: string;
24
103
  }
104
+ /**
105
+ * Function signature for custom card DOM renderers.
106
+ *
107
+ * This type defines a function that takes URL metadata and rendering options,
108
+ * and returns an HTML string representing the link card.
109
+ *
110
+ * @param data - The metadata extracted from the URL
111
+ * @param options - Rendering and styling options for the card
112
+ * @returns An HTML string representing the rendered link card
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * const customRender: CardDomRender = (data, options) => {
117
+ * return `<div class="${options.classPrefix}">
118
+ * <h3>${data.title}</h3>
119
+ * <p>${data.description}</p>
120
+ * </div>`
121
+ * }
122
+ * ```
123
+ */
25
124
  export type CardDomRender = (data: UrlMetadata, options: CardDomRenderOptions) => string;