{"_id":"@carlesandres/component-identity","_rev":"2-8671b74203cf00e4f44d4bc7b1a2d92b","name":"@carlesandres/component-identity","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@carlesandres/component-identity","version":"0.1.0","keywords":["react","components","lint","audit","data-component"],"author":{"name":"Carles Andres"},"license":"MIT","_id":"@carlesandres/component-identity@0.1.0","maintainers":[{"name":"carlesandres","email":"carlos.andres.c@gmail.com"}],"homepage":"https://github.com/carlesandres/component-identity#readme","bugs":{"url":"https://github.com/carlesandres/component-identity/issues"},"bin":{"component-identity":"dist/cli.js"},"dist":{"shasum":"44a72cc9a2b7b563a1ec10b1799fdca57d99c77b","tarball":"https://registry.npmjs.org/@carlesandres/component-identity/-/component-identity-0.1.0.tgz","fileCount":31,"integrity":"sha512-RUv0mHUFQ3/ls7XzGRLnevfmwF4LeeAfXmzRf+BcrzCq7+v7yD1qKIQyWc2U5V+AQUBt7xtqPmkXe1skY81B9g==","signatures":[{"sig":"MEUCIQC1mfHitqGOYB7gHj7XU31oZyvm9gSp7e1+d8dW35fj+gIgfqWR/13s49LzT34sBwubi0J6UyTRJartV1Pm8qH18kY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39032},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"10700bf7395b35e05c87cf3dfa0b734528506766","scripts":{"test":"node --test test/*.test.mjs","build":"tsc -p tsconfig.json","check":"tsc -p tsconfig.json --noEmit","prepack":"npm run build","pack:dry":"npm pack --dry-run","version:major":"npm version major","version:minor":"npm version minor","version:patch":"npm version patch","publish:public":"npm publish --access public"},"_npmUser":{"name":"carlesandres","email":"carlos.andres.c@gmail.com"},"repository":{"url":"git+https://github.com/carlesandres/component-identity.git","type":"git"},"_npmVersion":"11.14.1","description":"Audit exported React components for canonical data-component root attributes.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"typescript":"^5.8.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"25.9.3"},"_npmOperationalInternal":{"tmp":"tmp/component-identity_0.1.0_1781442849099_0.09404513400397208","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@carlesandres/component-identity","version":"0.1.1","description":"Audit exported React components for canonical data-component root attributes.","type":"module","bin":{"component-identity":"dist/cli.js"},"main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","check":"tsc -p tsconfig.json --noEmit","test":"node --test test/*.test.mjs","prepack":"npm run build","pack:dry":"npm pack --dry-run","version:patch":"npm version patch","version:minor":"npm version minor","version:major":"npm version major","publish:public":"npm publish --access public"},"keywords":["react","components","lint","audit","data-component"],"author":{"name":"Carles Andres"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/carlesandres/component-identity.git"},"bugs":{"url":"https://github.com/carlesandres/component-identity/issues"},"homepage":"https://github.com/carlesandres/component-identity#readme","engines":{"node":">=20"},"dependencies":{"typescript":"^5.8.3"},"devDependencies":{"@types/node":"25.9.3"},"gitHead":"daaa6db9653a76853d60021cf2d96bc6a9b5a660","_id":"@carlesandres/component-identity@0.1.1","_nodeVersion":"24.15.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-IJiMpz1za+nNqvHe8qk6a7KUnhl9Sdpc5SEohiJ4w835AMZO1dQlUGTprOXtZc2zfq4y13HC4xokOsFR9TCbOQ==","shasum":"b963dafd6140ed747b7c48a9e0933a38ce5facb0","tarball":"https://registry.npmjs.org/@carlesandres/component-identity/-/component-identity-0.1.1.tgz","fileCount":31,"unpackedSize":61122,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCID9Rtskcf6R3EuC1SpT5uw2r3nK2EPMjfkkM+bsHxTaFAiBZSrGK8RrxRjFHe8JM94vDWsexIceXSJgF0AdnX8++DA=="}]},"_npmUser":{"name":"carlesandres","email":"carlos.andres.c@gmail.com"},"directories":{},"maintainers":[{"name":"carlesandres","email":"carlos.andres.c@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/component-identity_0.1.1_1781991537612_0.97088114945567"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-14T13:14:08.971Z","modified":"2026-06-20T21:38:57.851Z","0.1.0":"2026-06-14T13:14:09.235Z","0.1.1":"2026-06-20T21:38:57.753Z"},"bugs":{"url":"https://github.com/carlesandres/component-identity/issues"},"author":{"name":"Carles Andres"},"license":"MIT","homepage":"https://github.com/carlesandres/component-identity#readme","keywords":["react","components","lint","audit","data-component"],"repository":{"type":"git","url":"git+https://github.com/carlesandres/component-identity.git"},"description":"Audit exported React components for canonical data-component root attributes.","maintainers":[{"name":"carlesandres","email":"carlos.andres.c@gmail.com"}],"readme":"# @carlesandres/component-identity\n\nAudit exported React components for a canonical `data-component` root attribute.\n\nThe convention is intentionally strict:\n\n```tsx\nexport function UserMenu() {\n  return <div data-component=\"user-menu\" />;\n}\n```\n\n`UserMenu` maps to `data-component=\"user-menu\"`. The mapping is one-to-one and uses kebab-case derived from the component name.\n\n## Install\n\n```sh\nnpm install --save-dev @carlesandres/component-identity\n```\n\n## Use\n\nAfter installing the package, add a config file:\n\n```sh\nnpx component-identity init\nnpx component-identity init --preset next\n```\n\nRun the audit:\n\n```sh\nnpx component-identity audit\n```\n\nUse JSON output for CI, reports, or agent tooling:\n\n```sh\nnpx component-identity report\nnpx component-identity audit --json\n```\n\nFor one-off use without installing first, use the scoped package name:\n\n```sh\nnpx @carlesandres/component-identity audit\n```\n\nThe audit exits with code `1` when violations are found, so it can be used directly in CI.\n\n```json\n{\n  \"scripts\": {\n    \"audit:components\": \"component-identity audit\"\n  }\n}\n```\n\n## What It Checks\n\nThe MVP checks named exported React components that return a root host DOM element:\n\n```tsx\nexport function UserMenu() {\n  return <div data-component=\"user-menu\" />;\n}\n\nexport const AccountCard = () => {\n  return <section data-component=\"account-card\" />;\n};\n```\n\nIt supports exported components declared as:\n\n- `export function ComponentName() { ... }`\n- `export const ComponentName = () => ...`\n- `export default function ComponentName() { ... }`\n- `const ComponentName = () => ...; export default ComponentName`\n- `const ComponentName = () => ...; export { ComponentName }`\n- `memo(ComponentName)` and nested `forwardRef(memo(...))` wrappers\n\n```tsx\nexport const Button = forwardRef<HTMLButtonElement>((props, ref) => {\n  return <button ref={ref} data-component=\"button\" {...props} />;\n});\n```\n\nFragments are audited through their first meaningful JSX DOM child. Empty fragments are reported as skipped with a `fragment-root` reason.\n\nIt ignores private components and reports skipped exported components whose root is another custom component or a non-JSX expression such as a portal call. Custom component roots can be treated as pass-through wrappers with `passThroughComponents`.\n\n## Autofix\n\nSimple missing or mismatched static root attributes can be fixed in place:\n\n```sh\nnpx component-identity audit --fix\n```\n\n## Config\n\n`component-identity.config.json`:\n\n```json\n{\n  \"attribute\": \"data-component\",\n  \"include\": [\n    \"src/**/*.{ts,tsx,js,jsx}\",\n    \"app/**/*.{ts,tsx,js,jsx}\",\n    \"components/**/*.{ts,tsx,js,jsx}\"\n  ],\n  \"exclude\": [\n    \"**/components/ui/**\",\n    \"**/*.test.*\",\n    \"**/*.spec.*\",\n    \"**/*.stories.*\",\n    \"**/*.d.ts\",\n    \"**/node_modules/**\",\n    \"**/dist/**\"\n  ],\n  \"excludeFiles\": [],\n  \"excludeComponents\": [],\n  \"passThroughComponents\": []\n}\n```\n\nUse `--config` to point at another config file and `--cwd` to audit a different directory. `excludeFiles` is an alias for additional file globs; `excludeComponents` accepts exact component names or `*` wildcards.\n\nUse `\"preset\": \"next\"`, `npx component-identity init --preset next`, or the exported `nextConfig` for Next.js projects. It extends the default excludes with app/page entry files such as pages, layouts, loading, error, and not-found files, while keeping tests, stories, and `components/ui` excluded.\n\nJSON reports include coverage fields: `componentsFound`, `componentsChecked`, `components`, `auditedComponents`, `skippedComponents`, `fixesApplied`, and `violations`.\n\n## Library API\n\n```ts\nimport { audit, componentNameToKebabCase } from \"@carlesandres/component-identity\";\n\nconst result = audit({ cwd: process.cwd() });\n\nif (!result.ok) {\n  console.log(result.violations);\n}\n\nconsole.log(componentNameToKebabCase(\"UserMenu\")); // \"user-menu\"\n```\n\n## Versioning And Publishing\n\nThis package is designed for normal npm versioning:\n\n```sh\nnpm run check\nnpm test\nnpm run pack:dry\nnpm run version:patch\nnpm run publish:public\n```\n\n`npm run prepack` builds `dist/` before packaging.\n\n## Contributions\n\nThis project is in a very early stage. For now, issues are accepted as contributions, but pull requests are not.\n","readmeFilename":"README.md"}