@dhiwise/component-tagger
Version:
Automatically annotate JSX components and HTML elements with data attributes
5 lines (4 loc) • 8.99 kB
JavaScript
;var z=Object.create;var x=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,ee=Object.prototype.hasOwnProperty;var te=(t,e)=>{for(var r in e)x(t,r,{get:e[r],enumerable:!0})},A=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Y(e))!ee.call(t,o)&&o!==r&&x(t,o,{get:()=>e[o],enumerable:!(n=Q(e,o))||n.enumerable});return t};var S=(t,e,r)=>(r=t!=null?z(Z(t)):{},A(e||!t||!t.__esModule?x(r,"default",{value:t,enumerable:!0}):r,t)),re=t=>A(x({},"__esModule",{value:!0}),t);var le={};te(le,{createVitePlugin:()=>V,default:()=>ae});module.exports=re(le);var j=require("unplugin");var E=S(require("path")),D=require("@babel/parser"),H=require("@babel/core"),N=S(require("magic-string"));var l=S(require("chalk")),I=S(require("picomatch"));var B=new Set(["Fragment","Suspense","StrictMode","Profiler","React.Fragment"]),_=["three","@react-three/fiber","@react-three/drei","@react-three/rapier","@react-three/a11y","@react-three/csg","@react-three/flex","@react-three/gpu-pathtracer","@react-three/postprocessing","@react-three/cannon","@react-three/xr","@react-three/test-renderer","three/addons","three/examples"],$=["object3D","audioListener","positionalAudio","mesh","batchedMesh","instancedMesh","scene","sprite","lOD","skinnedMesh","skeleton","bone","lineSegments","lineLoop","points","group","camera","perspectiveCamera","orthographicCamera","cubeCamera","arrayCamera","instancedBufferGeometry","bufferGeometry","boxBufferGeometry","circleBufferGeometry","coneBufferGeometry","cylinderBufferGeometry","dodecahedronBufferGeometry","extrudeBufferGeometry","icosahedronBufferGeometry","latheBufferGeometry","octahedronBufferGeometry","planeBufferGeometry","polyhedronBufferGeometry","ringBufferGeometry","shapeBufferGeometry","sphereBufferGeometry","tetrahedronBufferGeometry","torusBufferGeometry","torusKnotBufferGeometry","tubeBufferGeometry","wireframeGeometry","tetrahedronGeometry","octahedronGeometry","icosahedronGeometry","dodecahedronGeometry","polyhedronGeometry","tubeGeometry","torusKnotGeometry","torusGeometry","sphereGeometry","ringGeometry","planeGeometry","latheGeometry","shapeGeometry","extrudeGeometry","edgesGeometry","coneGeometry","cylinderGeometry","circleGeometry","boxGeometry","capsuleGeometry","material","shadowMaterial","spriteMaterial","rawShaderMaterial","shaderMaterial","pointsMaterial","meshPhysicalMaterial","meshStandardMaterial","meshPhongMaterial","meshToonMaterial","meshNormalMaterial","meshLambertMaterial","meshDepthMaterial","meshDistanceMaterial","meshBasicMaterial","meshMatcapMaterial","lineDashedMaterial","lineBasicMaterial","primitive","light","spotLightShadow","spotLight","pointLight","rectAreaLight","hemisphereLight","directionalLightShadow","directionalLight","ambientLight","lightShadow","ambientLightProbe","hemisphereLightProbe","lightProbe","spotLightHelper","skeletonHelper","pointLightHelper","hemisphereLightHelper","gridHelper","polarGridHelper","directionalLightHelper","cameraHelper","boxHelper","box3Helper","planeHelper","arrowHelper","axesHelper","texture","videoTexture","dataTexture","dataTexture3D","compressedTexture","cubeTexture","canvasTexture","depthTexture","raycaster","vector2","vector3","vector4","euler","matrix3","matrix4","quaternion","bufferAttribute","float16BufferAttribute","float32BufferAttribute","float64BufferAttribute","int8BufferAttribute","int16BufferAttribute","int32BufferAttribute","uint8BufferAttribute","uint16BufferAttribute","uint32BufferAttribute","instancedBufferAttribute","color","fog","fogExp2","shape","colorShiftMaterial"];function O(t){let e=new Set;for(let r of t.program.body)if(r.type==="ImportDeclaration"){let n=r,o=n.source.value;if(_.some(i=>o===i||o.startsWith(i+"/")))for(let i of n.specifiers)i.type==="ImportSpecifier"||i.type==="ImportDefaultSpecifier"?e.add(i.local.name):i.type==="ImportNamespaceSpecifier"&&e.add(`${i.local.name}.*`)}return e}var P=new Map;function ne(t){let e=t.sort().join(",");if(!P.has(e)){let r=t.map(o=>`**/*${o}`),n=(0,I.default)(r);P.set(e,n)}return P.get(e)}function b(t,e){let r=e.extensions||[".jsx",".tsx",".js",".ts"];return ne(r)(t)?![".test.",".spec.","__tests__","__mocks__"].some(i=>t.includes(i)):!1}function v(t,e,r){return e.includeElements&&e.includeElements.length>0?e.includeElements.includes(t):e.shouldTag?e.shouldTag(t):!(e.excludeElements&&e.excludeElements.includes(t)||B.has(t)||r&&oe(t,r))}function oe(t,e){if(e.has(t)||$.includes(t))return!0;for(let r of e)if(r.endsWith(".*")){let n=r.slice(0,-2);if(t.startsWith(`${n}.`))return!0}return!1}function ie(t){if(t){if(t.type==="StringLiteral")return t.value;if(t.type==="JSXExpressionContainer"){let e=t.expression;if(e.type==="StringLiteral")return e.value;if(e.type==="TemplateLiteral"&&e.quasis.length===1)return e.quasis[0].value.raw;if(e.type==="BinaryExpression"&&e.operator==="+"){let r=e.left.type==="StringLiteral"?e.left.value:"",n=e.right.type==="StringLiteral"?e.right.value:"";return r+n}if(e.type==="Identifier")return`[var:${e.name}]`}}}function X(t,e,r){let n={},o=["className","id","src","alt","href","type","name","value"],a=new Set([...o,...e.extractAttributes||[]]);for(let s of t.attributes)if(s.type==="JSXAttribute"&&s.name.type==="JSXIdentifier"){let f=s.name.name;if(!a.has(f))continue;if(s.value){let m=ie(s.value);m!==void 0&&(n[f]=m)}else n[f]="true"}else s.type==="JSXSpreadAttribute"&&(n["[spread]"]="true");let i="";return r&&r.children&&(i=r.children.map(s=>s.type==="JSXText"?s.value.trim():s.type==="JSXExpressionContainer"&&s.expression.type==="StringLiteral"?s.expression.value:"").filter(Boolean).join(" ").trim()),i&&(n.textContent=i),n}function F(t){let e=t.name;return e.type==="JSXIdentifier"?e.name:e.type==="JSXMemberExpression"?se(e):"Unknown"}function se(t){return`${t.object.name}.${t.property.name}`}function g(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}function R(t,e,r){return`${t}:${e}:${r}`}function c(t,e){if(!e.verbose)return;let r=t;t.includes("Error")||t.includes("error")?r=l.default.red(t):t.includes("Tagged")||t.includes("Summary")?r=l.default.green(t):t.includes("Processing")||t.includes("started")?r=l.default.blue(t):r=l.default.yellow(t),console.log(`[component-tagger] ${r}`)}function w(t){return l.default.green(`Component Tagger Summary:
- Total files scanned: ${l.default.cyan(t.totalFiles)}
- Files processed: ${l.default.cyan(t.processedFiles)}
- Elements tagged: ${l.default.cyan(t.totalElements)}`)}async function k(t,e,r){if(!b(e,r)||e.includes("node_modules")&&!r.processNodeModules||r.excludeDirectories&&r.excludeDirectories.some(i=>e.includes(i)))return null;let n=process.cwd(),o=E.relative(n,e),a=E.basename(e);c(`Processing file: ${o}`,r);try{let s=(0,D.parse)(t,{sourceType:"module",plugins:["jsx","typescript"]}),f=O(s),m=new N.default(t),T=0,h=null;return(0,H.traverse)(s,{JSXElement:C=>{h=C.node},JSXOpeningElement:C=>{if(!h)return;let d=C.node,M=F(d);if(!v(M,r,f))return;let q=X(d,r,h),L={elementName:M};Object.entries(q).forEach(([G,p])=>{L[G]=p});let y=d.loc?.start?.line??0,J=d.loc?.start?.column??0,W=h?.loc?.end?.line??y,K=r.generateComponentId?r.generateComponentId(o,y,J):R(o,y,J),u=` ${r.attributePrefix}-id="${g(K)}"`;if(r.includeLegacyAttributes&&(u+=` ${r.attributePrefix}-path="${g(o)}"`,u+=` ${r.attributePrefix}-line="${y}"`,u+=` ${r.attributePrefix}-end-line="${W}"`,u+=` ${r.attributePrefix}-file="${g(a)}"`,u+=` ${r.attributePrefix}-name="${g(M)}"`),r.includeContentAttribute){let G=JSON.stringify(L),p=encodeURIComponent(G);r.maxContentLength&&p.length>r.maxContentLength&&(p=p.substring(0,r.maxContentLength)+"..."),u+=` ${r.attributePrefix}-content="${p}"`}m.appendLeft(d.name.end??0,u),c(u.toString(),r),T++}}),T>0?(c(`Tagged ${T} components in ${o}`,r),{code:m.toString(),map:r.sourceMaps?m.generateMap({hires:!0}):null}):null}catch(i){return console.error(`Error processing file ${o}:`,i),null}}var U=(0,j.createUnplugin)((t={})=>{let e={extensions:[".jsx",".tsx",".js",".ts"],verbose:!1,attributePrefix:"data-component",includeContentAttribute:!0,maxContentLength:1e3,includeLegacyAttributes:!0,sourceMaps:!0,excludeDirectories:[],processNodeModules:!1,...t},r={totalFiles:0,processedFiles:0,totalElements:0};return{name:"component-tagger",transformInclude(n){return b(n,e)},async transform(n,o){if(o.includes("node_modules")&&!e.processNodeModules||e.excludeDirectories&&e.excludeDirectories.some(i=>o.includes(i)))return null;r.totalFiles++;let a=await k(n,o,e);if(a){r.processedFiles++;let i=(a.code.match(new RegExp(`${e.attributePrefix}-id="`,"g"))||[]).length;r.totalElements+=i}else r.processedFiles++;return a},buildStart(){c("Component tagger plugin started",e),r.totalFiles=0,r.processedFiles=0,r.totalElements=0},buildEnd(){c(w(r),e)}}});function V(t={}){let e=U.vite(t);return{...Array.isArray(e)?e[0]:e,enforce:"pre"}}var ae=V;0&&(module.exports={createVitePlugin});