react-grep 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.global.js +3 -3
- package/dist/index.js +55 -3
- package/package.json +10 -3
package/dist/index.global.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var ReactGrep=(function(exports){'use strict';var d=typeof navigator<"u"&&/mac/i.test(navigator.userAgentData?.platform??navigator.userAgent);var
|
|
2
|
-
`)){let i=
|
|
3
|
-
exports.destroy=
|
|
1
|
+
var ReactGrep=(function(exports){'use strict';var d=typeof navigator<"u"&&/mac/i.test(navigator.userAgentData?.platform??navigator.userAgent);var f=new Map,R="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",P=[];for(let t=0;t<R.length;t++)P[R.charCodeAt(t)]=t;var g=(t,e)=>{let n=0,i=0;for(;e.i<t.length;){let o=P[t.charCodeAt(e.i++)];if(i+=(o&31)<<n,!(o&32))return i&1?-(i>>1):i>>1;n+=5;}return 0},D=t=>{let e=[],n=0,i=0,o=0;for(let r of t.split(";")){let s=[],a=0;if(r){let l={i:0};for(;l.i<r.length;){if(r.charCodeAt(l.i)===44){l.i++;continue}a+=g(r,l),!(l.i>=r.length||r.charCodeAt(l.i)===44)&&(n+=g(r,l),i+=g(r,l),o+=g(r,l),l.i<r.length&&r.charCodeAt(l.i)!==44&&g(r,l),s.push([a,n,i,o]));}}e.push(s);}return e},K=/^data:application\/json[^,]*;base64,([A-Za-z0-9+/=]+)$/,W=(t,e)=>{try{return new URL(t).origin===new URL(e).origin}catch{return false}},C=async(t,e)=>{if(t.startsWith("data:")){let o=K.exec(t);return o?atob(o[1]):null}let n=new URL(t,e).href;if(!W(e,n))return null;let i=await fetch(n);return i.ok?i.text():null},G=t=>{let e=[],n=[];for(let i of t){let o=D(i.map.mappings),r=i.offset.line,s=i.offset.column,a=e.length;for(;n.length<r+o.length;)n.push([]);for(let l=0;l<o.length;l++){let c=n[r+l];for(let u of o[l])c.push([l===0?u[0]+s:u[0],u[1]+a,u[2],u[3]]);}e.push(...i.map.sources);}for(let i of n)i.length>1&&i.sort((o,r)=>o[0]-r[0]);return {sources:e,mappings:n}},y=t=>{try{let e=JSON.parse(t);return Array.isArray(e.sections)?G(e.sections):!e.sources||!e.mappings?null:{sources:e.sources,mappings:D(e.mappings)}}catch{return null}},B=async t=>{try{let e=await fetch(t),i=(await e.text()).match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)$/m);if(i){let s=await C(i[1].trim(),t);if(s){let a=y(s);if(a)return a}}let o=e.headers.get("SourceMap")??e.headers.get("X-SourceMap");if(o){let s=await C(o.trim(),t);if(s){let a=y(s);if(a)return a}}let r=await fetch(`${t}.map`);if(r.ok){let s=await r.text();return y(s)}return null}catch{return null}},X=/^webpack-internal:\/\/\//,_=/^about:\/\/React\/Server\/file:\/\/\//,z=/[/\\](\.next[/\\].+?)(?:\?.*)?$/,V=async t=>{try{let e=decodeURIComponent(t.replace(_,"")),n=z.exec(e);if(!n)return null;let o=`${typeof location<"u"?location.origin:""}/__nextjs_source-map?filename=${encodeURIComponent(n[1])}`,r=await fetch(o);if(!r.ok)return null;let s=await r.text();return s?y(s):null}catch{return null}},A=/sourceMappingURL=(data:application\/json[^"'\s\\]+)/g,Y=()=>{if(typeof performance>"u"||!performance.getEntriesByType)return [];let t=new Set,e=[];for(let n of performance.getEntriesByType("resource")){let i=n;!i.name.endsWith(".js")||t.has(i.name)||(t.add(i.name),e.push(i.name));}return e},J=async t=>{try{let e=Y(),n=`sourceURL=${t}`;for(let i of e){let o=await fetch(i);if(!o.ok)continue;let r=await o.text(),s=r.indexOf(n);if(s===-1)continue;let a=r.substring(Math.max(0,s-2e5),s),l=null,c;for(A.lastIndex=0;(c=A.exec(a))!==null;)l=c[1];if(!l)continue;let u=await C(l,t);if(u)return y(u)}return null}catch{return null}},Z=t=>{let e=f.get(t);if(!e){if(f.size>=100){let n=f.keys().next().value;f.delete(n);}_.test(t)?e=V(t):X.test(t)?e=J(t):e=B(t),f.set(t,e);}return e},Q=(t,e,n)=>{if(e<0||e>=t.mappings.length)return null;let i=t.mappings[e];if(!i.length)return null;let o=0,r=i.length-1;for(;o<r;){let s=o+r+1>>1;i[s][0]<=n?o=s:r=s-1;}return i[o]},F=async(t,e,n)=>{let i=await Z(t);if(!i)return null;let o=Q(i,e-1,n-1);if(!o)return null;let r=i.sources[o[1]];return r.startsWith("file:///")&&(r=decodeURIComponent(new URL(r).pathname)),r=r.replace(/^(?:\.\.\/)+/,""),{fileName:r,lineNumber:o[2]+1,columnNumber:o[3]+1}};var b=t=>"env"in t&&typeof t.name=="string",k=new Set([0,1,11,14,15]),q=t=>{try{let e=Object.keys(t).find(n=>n.startsWith("__reactFiber$"));return e?t[e]:null}catch{return null}},ee=t=>{let e=t;for(;e;){if(k.has(e.tag))return e;e=e.return;}return null},te=t=>{if(typeof t=="function")return t;if(t&&typeof t=="object"){if("render"in t&&typeof t.render=="function")return t.render;if("type"in t&&typeof t.type=="function")return t.type}return null},x=t=>{let{type:e}=t;if(typeof e=="function")return e.displayName||e.name||"Anonymous";if(e&&typeof e=="object"){if("displayName"in e&&e.displayName)return e.displayName;let n=te(e);if(n)return n.displayName||n.name||"Anonymous"}return "Anonymous"},E=new Set(["jsxDEV","jsxs","jsx","createElement","react-stack-top-frame","react_stack_bottom_frame","fakeJSXCallSite"]),ne=/at (?:(.+) \()?(.+):(\d+):(\d+)\)?$/,oe=t=>{if(E.has(t))return true;let e=t.lastIndexOf(".");if(e!==-1){let i=t.substring(e+1).replace(/\s*\[.*$/,"");if(E.has(i))return true}let n=/\[as (\w+)\]/.exec(t);return n!==null&&E.has(n[1])},T=t=>{let e=t._debugStack?.stack;if(!e)return null;for(let n of e.split(`
|
|
2
|
+
`)){let i=ne.exec(n.trim());if(!i)continue;let[,o,r,s,a]=i;if(!(o&&oe(o))&&!r.includes("/node_modules/"))return {url:r,line:Number(s),column:Number(a)}}return null},M=async t=>{let e=await F(t.url,t.line,t.column);if(e)return e;let n=t.url;try{let i=new URL(t.url);n=decodeURIComponent(i.pathname);let o=n.indexOf("?");o!==-1&&(n=n.substring(0,o));}catch{}return n=n.replace(/\.\.\//g,""),n.startsWith("/")&&(n=n.substring(1)),{fileName:n,lineNumber:t.line,columnNumber:t.column}},$=async t=>{if(t._debugSource)return t._debugSource;let e=t._debugOwner;if(e&&!b(e)&&e._debugSource)return e._debugSource;let n=T(t);if(n)return M(n);if(e&&!b(e)){let i=T(e);if(i)return M(i)}return null},N=async t=>{if(t._debugSource)return t._debugSource;let e=T(t);return e?M(e):null},I=async t=>{let e=q(t);if(!e)return null;let n=ee(e);if(!n)return null;if(e.return!=null&&k.has(e.return.tag))return {kind:"component",name:x(n),elementTag:null,source:await $(n),callSite:null};let o=e._debugOwner,r=typeof e.type=="string"?e.type:null;return o&&!b(o)&&o===n?{kind:"element",name:x(o),elementTag:r,source:await N(e),callSite:await $(n)}:{kind:"children",name:o&&b(o)?o.name:x(o&&!b(o)&&k.has(o.tag)?o:n),elementTag:r,source:await N(e),callSite:null}};var p={name:"#93c5fd",tag:"#a78bfa",path:"#71717a",pathActive:"#a1a1aa",pathDim:"#3f3f46",hint:"#52525b"},ie={position:"fixed",pointerEvents:"none",zIndex:"2147483646",backgroundColor:"rgba(66, 135, 245, 0.15)",border:"1.5px solid rgba(66, 135, 245, 0.6)",borderRadius:"3px",display:"none",transition:"top 60ms ease-out, left 60ms ease-out, width 60ms ease-out, height 60ms ease-out"},re={position:"fixed",pointerEvents:"none",zIndex:"2147483647",display:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace",fontSize:"12px",lineHeight:"1.4",color:"#e4e4e7",backgroundColor:"#18181b",border:"1px solid #3f3f46",borderRadius:"6px",padding:"4px 8px",whiteSpace:"nowrap",maxWidth:"500px",overflow:"hidden",textOverflow:"ellipsis",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.4)"},L=(t,e)=>{Object.assign(t.style,e);},S=t=>{let e=t.split("/");return e.length<=2?t:`.../${e.slice(-2).join("/")}`},h=(t,e)=>{let n=document.createElement("span");return n.textContent=t,Object.assign(n.style,e),n},v=class{highlight=null;tooltip=null;copiedTimer=null;init(){this.highlight||(this.highlight=document.createElement("div"),this.highlight.dataset.reactGrep="highlight",L(this.highlight,ie),document.body.appendChild(this.highlight),this.tooltip=document.createElement("div"),this.tooltip.dataset.reactGrep="tooltip",L(this.tooltip,re),document.body.appendChild(this.tooltip));}show(e,n,i="source"){if(!this.highlight||!this.tooltip)return;let o=e.getBoundingClientRect();this.highlight.style.top=`${o.top}px`,this.highlight.style.left=`${o.left}px`,this.highlight.style.width=`${o.width}px`,this.highlight.style.height=`${o.height}px`,this.highlight.style.display="block",this.tooltip.textContent="",this.tooltip.appendChild(h(n.name,{color:p.name,fontWeight:"600"})),n.elementTag!=null&&(this.tooltip.appendChild(h(" > ",{color:p.path})),this.tooltip.appendChild(h(n.elementTag,{color:p.tag,fontWeight:"600"})));let r=n.source?`${n.source.fileName}:${n.source.lineNumber}`:null,s=n.callSite?`${n.callSite.fileName}:${n.callSite.lineNumber}`:null;if(r&&s){let u=i==="source"?p.pathActive:p.pathDim,O=i==="callSite"?p.pathActive:p.pathDim,H=d?"\u21E7":"Shift",U=S(r),j=S(s);this.tooltip.appendChild(h(` ${i==="callSite"?"(":""}${U}${i==="callSite"?")":""}`,{color:u})),this.tooltip.appendChild(h(` ${H} `,{color:p.hint})),this.tooltip.appendChild(h(`${i==="source"?"(":""}${j}${i==="source"?")":""}`,{color:O}));}else r&&this.tooltip.appendChild(h(` ${S(r)}`,{color:p.path}));let a=this.tooltip.getBoundingClientRect(),l=o.top-a.height-6,c=o.left;l<4&&(l=o.bottom+6),c+a.width>window.innerWidth-4&&(c=window.innerWidth-a.width-4),this.tooltip.style.top=`${l}px`,this.tooltip.style.left=`${Math.max(4,c)}px`,this.tooltip.style.display="block";}showCopied(e){this.tooltip&&(this.tooltip.textContent="",this.tooltip.appendChild(h("Copied!",{color:"#4ade80",fontWeight:"600"})),this.tooltip.appendChild(h(` ${S(e)}`,{color:"#a1a1aa"})),this.tooltip.style.display="block",this.copiedTimer&&clearTimeout(this.copiedTimer),this.copiedTimer=setTimeout(()=>this.hide(),1500));}hide(){this.highlight&&(this.highlight.style.display="none"),this.tooltip&&(this.tooltip.style.display="none");}destroy(){this.copiedTimer&&(clearTimeout(this.copiedTimer),this.copiedTimer=null),this.highlight?.remove(),this.tooltip?.remove(),this.highlight=null,this.tooltip=null;}};var w=class{overlay=new v;moveGeneration=0;clickGeneration=0;lastTarget=null;lastInfo=null;sourceToggled=false;shiftPressedClean=false;savedCursor="";boundHandlers;constructor(){this.boundHandlers={mousemove:this.handleMouseMove.bind(this),click:this.handleClick.bind(this),keydown:this.handleKeyDown.bind(this),keyup:this.handleKeyUp.bind(this)};}start(){window.addEventListener("mousemove",this.boundHandlers.mousemove),window.addEventListener("click",this.boundHandlers.click,true),window.addEventListener("keydown",this.boundHandlers.keydown),window.addEventListener("keyup",this.boundHandlers.keyup);}stop(){window.removeEventListener("mousemove",this.boundHandlers.mousemove),window.removeEventListener("click",this.boundHandlers.click,true),window.removeEventListener("keydown",this.boundHandlers.keydown),window.removeEventListener("keyup",this.boundHandlers.keyup),this.overlay.destroy(),this.restoreCursor(),this.lastTarget=null,this.lastInfo=null,this.sourceToggled=false,this.shiftPressedClean=false;}isModifierHeld(e){return d?e.metaKey:e.ctrlKey}async handleMouseMove(e){if(!this.isModifierHeld(e)){this.overlay.hide(),this.restoreCursor(),this.lastTarget=null,this.lastInfo=null;return}this.overlay.init(),this.setCrosshairCursor();let n=document.elementFromPoint(e.clientX,e.clientY);if(!n||n.closest("[data-react-grep]"))return;n!==this.lastTarget&&(this.sourceToggled=false);let i=++this.moveGeneration,o=await I(n);if(i===this.moveGeneration){if(!o){this.overlay.hide(),this.lastTarget=null,this.lastInfo=null;return}this.lastTarget=n,this.lastInfo=o,this.overlay.show(n,o,this.getActiveSource());}}async handleClick(e){if(!this.isModifierHeld(e)||!e.shiftKey)return;let n=document.elementFromPoint(e.clientX,e.clientY);if(!n||n.closest("[data-react-grep]"))return;e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation(),this.shiftPressedClean=false;let i=++this.clickGeneration,o=await I(n);if(i!==this.clickGeneration||!o)return;let r=this.getActiveCopySource(o);if(!r)return;let{fileName:s,lineNumber:a,columnNumber:l}=r,c=l!=null?`${s}:${a}:${l}`:`${s}:${a}`;await this.copyToClipboard(c),this.overlay.showCopied(c);}handleKeyDown(e){e.key==="Shift"&&this.isModifierHeld(e)&&(this.shiftPressedClean=true);}handleKeyUp(e){if(d&&e.key==="Meta"||!d&&e.key==="Control"){this.overlay.hide(),this.restoreCursor(),this.lastTarget=null,this.lastInfo=null;return}e.key==="Shift"&&this.shiftPressedClean&&this.lastTarget&&this.lastInfo&&this.lastInfo.callSite&&(this.sourceToggled=!this.sourceToggled,this.overlay.show(this.lastTarget,this.lastInfo,this.getActiveSource())),this.shiftPressedClean=false;}getActiveSource(){return this.sourceToggled?"callSite":"source"}getActiveCopySource(e){return this.sourceToggled&&e.callSite?e.callSite:e.source}setCrosshairCursor(){document.body.style.cursor!=="crosshair"&&(this.savedCursor=document.body.style.cursor,document.body.style.cursor="crosshair");}restoreCursor(){document.body.style.cursor==="crosshair"&&(document.body.style.cursor=this.savedCursor);}async copyToClipboard(e){try{await navigator.clipboard.writeText(e);}catch{}}};var m=null,se=()=>{m||(m=new w,m.start());},be=()=>{m&&(m.stop(),m=null);};if(typeof window<"u"){let t=()=>se();document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t):t();}
|
|
3
|
+
exports.destroy=be;exports.init=se;return exports;})({});
|
package/dist/index.js
CHANGED
|
@@ -129,6 +129,7 @@ var fetchAndParse = async (url) => {
|
|
|
129
129
|
return null;
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
|
+
var WEBPACK_INTERNAL_RE = /^webpack-internal:\/\/\//;
|
|
132
133
|
var ABOUT_SERVER_RE = /^about:\/\/React\/Server\/file:\/\/\//;
|
|
133
134
|
var NEXT_DOTDIR_RE = /[/\\](\.next[/\\].+?)(?:\?.*)?$/;
|
|
134
135
|
var fetchAndParseServerFile = async (url) => {
|
|
@@ -147,6 +148,43 @@ var fetchAndParseServerFile = async (url) => {
|
|
|
147
148
|
return null;
|
|
148
149
|
}
|
|
149
150
|
};
|
|
151
|
+
var WEBPACK_SM_RE = /sourceMappingURL=(data:application\/json[^"'\s\\]+)/g;
|
|
152
|
+
var getScriptUrls = () => {
|
|
153
|
+
if (typeof performance === "undefined" || !performance.getEntriesByType) return [];
|
|
154
|
+
const seen = /* @__PURE__ */ new Set();
|
|
155
|
+
const urls = [];
|
|
156
|
+
for (const entry of performance.getEntriesByType("resource")) {
|
|
157
|
+
const re = entry;
|
|
158
|
+
if (!re.name.endsWith(".js") || seen.has(re.name)) continue;
|
|
159
|
+
seen.add(re.name);
|
|
160
|
+
urls.push(re.name);
|
|
161
|
+
}
|
|
162
|
+
return urls;
|
|
163
|
+
};
|
|
164
|
+
var fetchAndParseWebpackInternal = async (url) => {
|
|
165
|
+
try {
|
|
166
|
+
const scriptUrls = getScriptUrls();
|
|
167
|
+
const marker = `sourceURL=${url}`;
|
|
168
|
+
for (const scriptUrl of scriptUrls) {
|
|
169
|
+
const res = await fetch(scriptUrl);
|
|
170
|
+
if (!res.ok) continue;
|
|
171
|
+
const text = await res.text();
|
|
172
|
+
const markerIdx = text.indexOf(marker);
|
|
173
|
+
if (markerIdx === -1) continue;
|
|
174
|
+
const before = text.substring(Math.max(0, markerIdx - 2e5), markerIdx);
|
|
175
|
+
let lastRef = null;
|
|
176
|
+
let m;
|
|
177
|
+
WEBPACK_SM_RE.lastIndex = 0;
|
|
178
|
+
while ((m = WEBPACK_SM_RE.exec(before)) !== null) lastRef = m[1];
|
|
179
|
+
if (!lastRef) continue;
|
|
180
|
+
const json = await fetchSourceMapJson(lastRef, url);
|
|
181
|
+
if (json) return parseSourceMap(json);
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
} catch {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
150
188
|
var getSourceMap = (url) => {
|
|
151
189
|
let promise = cache.get(url);
|
|
152
190
|
if (!promise) {
|
|
@@ -154,7 +192,9 @@ var getSourceMap = (url) => {
|
|
|
154
192
|
const oldest = cache.keys().next().value;
|
|
155
193
|
cache.delete(oldest);
|
|
156
194
|
}
|
|
157
|
-
|
|
195
|
+
if (ABOUT_SERVER_RE.test(url)) promise = fetchAndParseServerFile(url);
|
|
196
|
+
else if (WEBPACK_INTERNAL_RE.test(url)) promise = fetchAndParseWebpackInternal(url);
|
|
197
|
+
else promise = fetchAndParse(url);
|
|
158
198
|
cache.set(url, promise);
|
|
159
199
|
}
|
|
160
200
|
return promise;
|
|
@@ -181,6 +221,7 @@ var resolveOriginalPosition = async (url, line, column) => {
|
|
|
181
221
|
if (fileName.startsWith("file:///")) {
|
|
182
222
|
fileName = decodeURIComponent(new URL(fileName).pathname);
|
|
183
223
|
}
|
|
224
|
+
fileName = fileName.replace(/^(?:\.\.\/)+/, "");
|
|
184
225
|
return {
|
|
185
226
|
fileName,
|
|
186
227
|
lineNumber: seg[2] + 1,
|
|
@@ -243,11 +284,22 @@ var SKIP_FRAMES = /* @__PURE__ */ new Set([
|
|
|
243
284
|
"jsxDEV",
|
|
244
285
|
"jsxs",
|
|
245
286
|
"jsx",
|
|
287
|
+
"createElement",
|
|
246
288
|
"react-stack-top-frame",
|
|
247
289
|
"react_stack_bottom_frame",
|
|
248
290
|
"fakeJSXCallSite"
|
|
249
291
|
]);
|
|
250
|
-
var FRAME_RE = /at (?:(
|
|
292
|
+
var FRAME_RE = /at (?:(.+) \()?(.+):(\d+):(\d+)\)?$/;
|
|
293
|
+
var isSkippedFn = (name) => {
|
|
294
|
+
if (SKIP_FRAMES.has(name)) return true;
|
|
295
|
+
const dotIdx = name.lastIndexOf(".");
|
|
296
|
+
if (dotIdx !== -1) {
|
|
297
|
+
const base = name.substring(dotIdx + 1).replace(/\s*\[.*$/, "");
|
|
298
|
+
if (SKIP_FRAMES.has(base)) return true;
|
|
299
|
+
}
|
|
300
|
+
const aliasMatch = /\[as (\w+)\]/.exec(name);
|
|
301
|
+
return aliasMatch !== null && SKIP_FRAMES.has(aliasMatch[1]);
|
|
302
|
+
};
|
|
251
303
|
var parseFirstUserFrame = (fiber) => {
|
|
252
304
|
const stack = fiber._debugStack?.stack;
|
|
253
305
|
if (!stack) return null;
|
|
@@ -255,7 +307,7 @@ var parseFirstUserFrame = (fiber) => {
|
|
|
255
307
|
const match = FRAME_RE.exec(line.trim());
|
|
256
308
|
if (!match) continue;
|
|
257
309
|
const [, fnName, url, lineStr, colStr] = match;
|
|
258
|
-
if (fnName &&
|
|
310
|
+
if (fnName && isSkippedFn(fnName)) continue;
|
|
259
311
|
if (url.includes("/node_modules/")) continue;
|
|
260
312
|
return { url, line: Number(lineStr), column: Number(colStr) };
|
|
261
313
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-grep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Hold CMD to see React component names + file:line overlaid on any element",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"component",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
],
|
|
31
31
|
"type": "module",
|
|
32
32
|
"sideEffects": true,
|
|
33
|
+
"main": "dist/index.js",
|
|
33
34
|
"module": "dist/index.js",
|
|
34
35
|
"browser": "dist/index.global.js",
|
|
35
36
|
"types": "dist/index.d.ts",
|
|
@@ -47,10 +48,16 @@
|
|
|
47
48
|
"scripts": {
|
|
48
49
|
"build": "tsup",
|
|
49
50
|
"dev": "tsup --watch",
|
|
50
|
-
"check-types": "tsc --noEmit"
|
|
51
|
+
"check-types": "tsc --noEmit",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"test:coverage": "vitest run --coverage"
|
|
51
55
|
},
|
|
52
56
|
"devDependencies": {
|
|
57
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
58
|
+
"jsdom": "^28.0.0",
|
|
53
59
|
"tsup": "^8.2.4",
|
|
54
|
-
"typescript": "^5.7.0"
|
|
60
|
+
"typescript": "^5.7.0",
|
|
61
|
+
"vitest": "^4.0.18"
|
|
55
62
|
}
|
|
56
63
|
}
|