{"_id":"@boundaries/elements","_rev":"16-7a3cecc1815542cccd5703c7a3ef0c4d","name":"@boundaries/elements","dist-tags":{"beta":"3.0.0-beta.1","latest":"3.1.1"},"versions":{"1.0.0":{"name":"@boundaries/elements","version":"1.0.0","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@1.0.0","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"a074a4225a138145c2a74d89b73ee6b75662123d","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-1.0.0.tgz","fileCount":15,"integrity":"sha512-b+fcPUEjIyofcEe39ZaeaoeCb2/a6kyi3ztRSS/ayc4Izs54vY4m5GUn8x9N24wWVPy0e6V4La9e+eZCPjCEMQ==","signatures":[{"sig":"MEQCIEYX58THGPTgW8JspS0c53eiMUp8AZOJZPlKNOyv152XAiBR9IZS70I57Lg10OyunIeth5hEoqBc3+RvLbOwrIiGhg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1301501},"main":"dist/index.js","_from":"file:boundaries-elements-1.0.0.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","test:mutation":"stryker run","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/deb0e013a625f6254254dee8fe766833/boundaries-elements-1.0.0.tgz","_integrity":"sha512-b+fcPUEjIyofcEe39ZaeaoeCb2/a6kyi3ztRSS/ayc4Izs54vY4m5GUn8x9N24wWVPy0e6V4La9e+eZCPjCEMQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Descriptor to define elements for @boundaries ecosystem","directories":{},"_nodeVersion":"20.19.5","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","object-hash":"3.0.0","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.0","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_1.0.0_1762769447906_0.21886264180900827","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@boundaries/elements","version":"1.1.0","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@1.1.0","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"505cbf2153a407fa2d518cdec83d18d1804bed6a","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-1.1.0.tgz","fileCount":15,"integrity":"sha512-/NvzEUzYdONn4D5O7lGX7AHDNXa/H0KPyckDe/Br3Bb0fKuXzEpoJv2VgOt4lj8OFGCf+Vc8tdlG26CMrCxubQ==","signatures":[{"sig":"MEYCIQCSnwRwu2/P7Q4TFSJFuWhniugggA/+WqGsIhzOgcDaMAIhAIR8iRDkoovrJsohMqpPiJ4ZZJ3FDgDddI0MU8IAA2Ro","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1401178},"main":"dist/index.js","_from":"file:boundaries-elements-1.1.0.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","test:mutation":"stryker run","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/46d97c6c4213789025b235d9ad1729c7/boundaries-elements-1.1.0.tgz","_integrity":"sha512-/NvzEUzYdONn4D5O7lGX7AHDNXa/H0KPyckDe/Br3Bb0fKuXzEpoJv2VgOt4lj8OFGCf+Vc8tdlG26CMrCxubQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.19.5","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.0","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_1.1.0_1763203501053_0.1558515430483809","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@boundaries/elements","version":"1.1.1","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@1.1.1","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"98ce33328784c3715297e4a8abcfd1cdb5dfbb0f","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-1.1.1.tgz","fileCount":15,"integrity":"sha512-PdfbevdcQbJ1oIXSN0H8rRcWdNsnSWpMtoh+/afSovWavAiuazbnDD9iwAfDcDiJu0g3Xbhisl5epBmTrnaRyQ==","signatures":[{"sig":"MEUCIC+SgRd2Nw+jPMx9mfg8yHj2cGhn7NkusFvVwbBz/0kjAiEAxRPC9dM3q/Dg7iRDwEaPphEEOK3Ev/m0uf/GgCrRUJM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1403608},"main":"dist/index.js","_from":"file:boundaries-elements-1.1.1.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","test:mutation":"stryker run","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/205514d50ba8969426f55d652c804d91/boundaries-elements-1.1.1.tgz","_integrity":"sha512-PdfbevdcQbJ1oIXSN0H8rRcWdNsnSWpMtoh+/afSovWavAiuazbnDD9iwAfDcDiJu0g3Xbhisl5epBmTrnaRyQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.19.5","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.0","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_1.1.1_1763893333304_0.3625353749536844","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@boundaries/elements","version":"1.1.2","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@1.1.2","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"d441438633f9562563b3bf9c48fb928ef9acb143","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-1.1.2.tgz","fileCount":15,"integrity":"sha512-DnGHL+v36YVMoWhWZqyJYVZ9dapNm7h4N3/P0lDPirJj0CHVPkjChMCCotj74cg6LW7iPJZFGrdEfh0X0g2bmQ==","signatures":[{"sig":"MEUCIBuXnDWAD92tyWMcjOaFhkD/59VGG1AkGgKd5ZY8r+JoAiEAs5/148ecmHHrcvPQfYnlRoTKIhMzD2Eo5kiz7Wpkmsc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1403756},"main":"dist/index.js","_from":"file:boundaries-elements-1.1.2.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","test:mutation":"stryker run","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/d6e13ba158cea84bccc32e0743cefe1c/boundaries-elements-1.1.2.tgz","_integrity":"sha512-DnGHL+v36YVMoWhWZqyJYVZ9dapNm7h4N3/P0lDPirJj0CHVPkjChMCCotj74cg6LW7iPJZFGrdEfh0X0g2bmQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.19.6","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.0","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_1.1.2_1765011729605_0.11386818955276201","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@boundaries/elements","version":"1.2.0","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@1.2.0","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"ed5f0038829849686dae98cf23ef811b9a3415ed","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-1.2.0.tgz","fileCount":15,"integrity":"sha512-W65Gum02liMd3hmNrLmDBX1u5BmRMcunouFjLXyhxHnNY4YlK1kTxsgfflZ5XBGSnPnO0MkiUzAcoGzYrlx0RQ==","signatures":[{"sig":"MEYCIQDQjk37EqZMeA89Aqj6SzhE9XNq2N+aLNBCCC/18oEKrQIhANiDsxpgQu/F0ad3NP3Y6EaYkaY9vXty7MurLAtFdA95","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1473169},"main":"dist/index.js","_from":"file:boundaries-elements-1.2.0.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","test:mutation":"stryker run","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/4aa44d714a4decea30fe2cc12a3d3ce7/boundaries-elements-1.2.0.tgz","_integrity":"sha512-W65Gum02liMd3hmNrLmDBX1u5BmRMcunouFjLXyhxHnNY4YlK1kTxsgfflZ5XBGSnPnO0MkiUzAcoGzYrlx0RQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.20.0","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.0","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_1.2.0_1770096581840_0.19645478552833806","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.1":{"name":"@boundaries/elements","version":"2.0.0-beta.1","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@2.0.0-beta.1","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"685c873f1a039f7962ea3b158c4567b6571f2f8f","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-2.0.0-beta.1.tgz","fileCount":15,"integrity":"sha512-bpCLN8EMZdtJHwYuxNXg+s5AqI+VCd4qTkFHZm0E6uEmAj1Eb4eJJrNx1Tdie6S05o27JL9N5EBvcpiN4UTLiQ==","signatures":[{"sig":"MEUCIBqNFeFV57yg8ITXRJIG2UnmOr/uEZi159wlpFp17wfoAiEAiB3mXyhttCSBrCD2osCHE+SwpUI6cYKjqm9sId0VKac=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1440239},"main":"dist/index.js","_from":"file:boundaries-elements-2.0.0-beta.1.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/6a0066eea254deab9427a350404c1ada/boundaries-elements-2.0.0-beta.1.tgz","_integrity":"sha512-bpCLN8EMZdtJHwYuxNXg+s5AqI+VCd4qTkFHZm0E6uEmAj1Eb4eJJrNx1Tdie6S05o27JL9N5EBvcpiN4UTLiQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.20.0","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_2.0.0-beta.1_1773485728953_0.2820021310844236","host":"s3://npm-registry-packages-npm-production"}},"2.0.0-beta.2":{"name":"@boundaries/elements","version":"2.0.0-beta.2","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@2.0.0-beta.2","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"51223c63e418b8c0050879a3a89088279671b101","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-2.0.0-beta.2.tgz","fileCount":15,"integrity":"sha512-0dyyEkoPxQTiraP9wRGBwKiCyQuUhXIaxbESsUWUTsggaet3Hl/VtIvr1Km75b01alTlarYiqQ1pAzjOyDwr/w==","signatures":[{"sig":"MEUCIQDfbgn4VH7lLjZMxz6H1K7ytX6yLMeLuBGQcVQH4+jCgwIgVhBDqg9ty9YL9Cw2ZHjDn93T13eYJNqc4c694fOHOe4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1441635},"main":"dist/index.js","_from":"file:boundaries-elements-2.0.0-beta.2.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/6dc31bf46c3b2d0cd9a12c2e503188d6/boundaries-elements-2.0.0-beta.2.tgz","_integrity":"sha512-0dyyEkoPxQTiraP9wRGBwKiCyQuUhXIaxbESsUWUTsggaet3Hl/VtIvr1Km75b01alTlarYiqQ1pAzjOyDwr/w==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.20.1","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsup":"8.5.1","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_2.0.0-beta.2_1773568369888_0.3450376204618417","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@boundaries/elements","version":"2.0.0","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@2.0.0","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"51501f91f3b1d56cdfa71c0863a4f43ca4ed884b","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-2.0.0.tgz","fileCount":15,"integrity":"sha512-2TM/rhXvbAeEE2/pZ/Dw+l3LzzaSuo9n3DJjw+StvwHnrzyjBYrXcD5Lw7tBI+wuNHy57JJfgRRKTDwb0PFZSw==","signatures":[{"sig":"MEUCIQDlMi81sV/S8p6RxXWeXYPO1mNi7tM+7EBpJQbm1z7BHwIgDwVJHnF1rclAYFz2AxZp1ppjxGeXPmasLyb7yueH1hA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1441628},"main":"dist/index.js","_from":"file:boundaries-elements-2.0.0.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/19b09023a01b0587a0409373c48aba63/boundaries-elements-2.0.0.tgz","_integrity":"sha512-2TM/rhXvbAeEE2/pZ/Dw+l3LzzaSuo9n3DJjw+StvwHnrzyjBYrXcD5Lw7tBI+wuNHy57JJfgRRKTDwb0PFZSw==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.20.1","dependencies":{"handlebars":"4.7.8","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_2.0.0_1773600314797_0.10286719291707525","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@boundaries/elements","version":"2.0.1","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@2.0.1","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"46de6a95eb61e5226201d3b71975c8ce3c5b98a8","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-2.0.1.tgz","fileCount":15,"integrity":"sha512-sAWO3D8PFP6pBXdxxW93SQi/KQqqhE2AAHo3AgWfdtJXwO6bfK6/wUN81XnOZk0qRC6vHzUEKhjwVD9dtDWvxg==","signatures":[{"sig":"MEYCIQCK7bSidNkx/jJZWFwTSxG0j/FLzKBJrmIhnS3xOKQuzwIhAJW4QzuNqxbC4dtL/VX0xNGJsE90eFzTAQyqQEHrWmq9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1441628},"main":"dist/index.js","_from":"file:boundaries-elements-2.0.1.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/67e54df06039dd0c38cbfa1debc94ce7/boundaries-elements-2.0.1.tgz","_integrity":"sha512-sAWO3D8PFP6pBXdxxW93SQi/KQqqhE2AAHo3AgWfdtJXwO6bfK6/wUN81XnOZk0qRC6vHzUEKhjwVD9dtDWvxg==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.8.2","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"20.20.1","dependencies":{"handlebars":"4.7.9","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_2.0.1_1774879918392_0.44544829313032297","host":"s3://npm-registry-packages-npm-production"}},"3.0.0-beta.1":{"name":"@boundaries/elements","version":"3.0.0-beta.1","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@3.0.0-beta.1","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"bf869a0b614a9c8d7eb5f90d56fce49890a59042","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-3.0.0-beta.1.tgz","fileCount":15,"integrity":"sha512-5PFvPLIAXLajuCbFdyYx1qvn8EBzDJJWQvd/RF82P2nvbHFXhCJWk67BiZQS8QFrGmG3U9+mnBGkA6943iaQZw==","signatures":[{"sig":"MEUCIQCTKNfxfx3YtaczhOL7tQ1bXDks5z1c5sLl79ITxa5KagIgcMai4Xfwn+wuRQuCj/bJ/9H/GNaRRii2m9/KEviRRhk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2554387},"main":"dist/index.js","_from":"file:boundaries-elements-3.0.0-beta.1.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","test":"pnpm test:unit","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/e0b7997b654d0c1f0d83172cc0e8ba60/boundaries-elements-3.0.0-beta.1.tgz","_integrity":"sha512-5PFvPLIAXLajuCbFdyYx1qvn8EBzDJJWQvd/RF82P2nvbHFXhCJWk67BiZQS8QFrGmG3U9+mnBGkA6943iaQZw==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.9.8","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"22.23.1","dependencies":{"handlebars":"4.7.9","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tsup":"8.5.1","typescript":"5.9.3","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_3.0.0-beta.1_1783188162972_0.805951735534038","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@boundaries/elements","version":"3.0.0","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@3.0.0","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"19ec20f3d03afcc783f3521ee25c14570c982b6f","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-3.0.0.tgz","fileCount":15,"integrity":"sha512-HA9ezi7GjAA9k7+Gm96aCgu8XajbmGbgamsxqbPYz9417r5MJpHWIRUNsVBPp5D2XzeSrmvr2slvFjn3AkDU8g==","signatures":[{"sig":"MEUCIG2CEVZd8WfRyL22QIjmMjgA6BJQkRlZG9HZ6bva+P9SAiEA64mgQ1VV+s4C6+NZBUDwQFZ+GSYAanbk95TEFQ7JKLE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2554380},"main":"dist/index.js","_from":"file:boundaries-elements-3.0.0.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","test":"pnpm test:unit","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/d77954995dc6b4ac6b76cc62a35e2a5e/boundaries-elements-3.0.0.tgz","_integrity":"sha512-HA9ezi7GjAA9k7+Gm96aCgu8XajbmGbgamsxqbPYz9417r5MJpHWIRUNsVBPp5D2XzeSrmvr2slvFjn3AkDU8g==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.9.8","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"22.23.1","dependencies":{"handlebars":"4.7.9","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","typescript":"5.9.3","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_3.0.0_1783275674570_0.0337548071236462","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@boundaries/elements","version":"3.0.1","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@3.0.1","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"d20b83bc81d3912d2aabef0636b52cf5b4c02f6d","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-3.0.1.tgz","fileCount":15,"integrity":"sha512-T53UueJVRIn1B2G5FWo6T3rqAA1aHcuypRweQcbW6Z/leUygsHW54Gezkm/8uxB9Fw8ewE+izfKKmA9XVv7HdQ==","signatures":[{"sig":"MEYCIQDdH2YPZiRFigs0C64idqEVGrQySyMATSHMnD6/IO1axAIhAJR9EsV9dPO8+xKRs57PS3u5XF2T9BHA4K91TuUTwuvi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2556148},"main":"dist/index.js","_from":"file:boundaries-elements-3.0.1.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","test":"pnpm test:unit","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/44a9ad3737fe4bd81d91558b5a072e87/boundaries-elements-3.0.1.tgz","_integrity":"sha512-T53UueJVRIn1B2G5FWo6T3rqAA1aHcuypRweQcbW6Z/leUygsHW54Gezkm/8uxB9Fw8ewE+izfKKmA9XVv7HdQ==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.9.8","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"22.23.1","dependencies":{"handlebars":"4.7.9","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","typescript":"5.9.3","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_3.0.1_1783360739512_0.47787142334929533","host":"s3://npm-registry-packages-npm-production"}},"3.1.0":{"name":"@boundaries/elements","version":"3.1.0","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","_id":"@boundaries/elements@3.1.0","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"b3ef99c8d8bfb61344c5f70d8e01166094f27b50","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-3.1.0.tgz","fileCount":15,"integrity":"sha512-9YtjJG2sSHssCcmU4dCeqHHwHF5Il0Gc1C8AywksbZyvQ9CFvpNURFuJbT21OpMdp0KHWJB14clMy85oiGwX9w==","signatures":[{"sig":"MEQCIHp7kOirbTKiaNBLeDHGydEEPaxl6i2LOqh9VZG6al7hAiBDgXHJmIOTGQptm/vTcEnYE1XUuV0yEAohVhG9+qPxXw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2580568},"main":"dist/index.js","_from":"file:boundaries-elements-3.1.0.tgz","types":"dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"scripts":{"lint":"eslint .","test":"pnpm test:unit","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"_resolved":"/tmp/71717d42e50585705a9926ce851d3a55/boundaries-elements-3.1.0.tgz","_integrity":"sha512-9YtjJG2sSHssCcmU4dCeqHHwHF5Il0Gc1C8AywksbZyvQ9CFvpNURFuJbT21OpMdp0KHWJB14clMy85oiGwX9w==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.9.8","description":"Element descriptors and matchers for @boundaries tools","directories":{},"_nodeVersion":"22.23.1","dependencies":{"handlebars":"4.7.9","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","typescript":"5.9.3","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"tmp":"tmp/elements_3.1.0_1784567038194_0.44440932773340514","host":"s3://npm-registry-packages-npm-production"}},"3.1.1":{"_id":"@boundaries/elements@3.1.1","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"dist":{"shasum":"d18f01bbc0939025f3461d6f808a51deecff15db","tarball":"https://registry.npmjs.org/@boundaries/elements/-/elements-3.1.1.tgz","fileCount":15,"integrity":"sha512-ikqee8669yp2I+uLG67T5P5BSbe+y4NqW5Mk+7tYa+Ydzhpmh0pDyMaH9918J2Ll36ZqYKDb4g4QBeMpWg7VDg==","signatures":[{"sig":"MEUCIDK/iuD+r0T+cl4MZtXhQfPXJ3/u4X4jXkiXtNhSBoF5AiEAgjBioTn28SkrCtLx/fppMQ6vxA6V2RrIcualvfHGraU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCtcjdZEgExHtkDUUDa4mVi2M+Fcz4QX5M8d8U32VWJ6gIhANyhz/T8qw0r1V36uFXSKEpsfGX16j5Af7SY1sOzLb4D"}],"unpackedSize":2580616},"main":"dist/index.js","name":"@boundaries/elements","_from":"file:boundaries-elements-3.1.1.tgz","types":"dist/index.d.ts","author":{"name":"Javier Brea"},"module":"./dist/index.mjs","engines":{"node":">=18.18"},"exports":{".":{"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"license":"MIT","scripts":{"lint":"eslint .","test":"pnpm test:unit","build":"tsup --config tsup.config.js","eslint":"eslint","lint:fix":"eslint . --fix","check:all":"echo 'All checks passed'","test:unit":"jest","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","test:mutation":"stryker run","serve:unit:report":"serve --config ./serve.test-unit-report.json","serve:mutation:report":"serve --config ./serve.test-mutation-report.json"},"version":"3.1.1","_npmUser":{"name":"javierbrea","email":"javier.brea@gmail.com"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","keywords":["boundaries","elements","hierarchy"],"_resolved":"/tmp/6ac854c0d9292d4e7cb2b4c0073f3bc6/boundaries-elements-3.1.1.tgz","_integrity":"sha512-ikqee8669yp2I+uLG67T5P5BSbe+y4NqW5Mk+7tYa+Ydzhpmh0pDyMaH9918J2Ll36ZqYKDb4g4QBeMpWg7VDg==","repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"_npmVersion":"10.9.8","description":"Element descriptors and matchers for @boundaries tools","directories":{},"maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"_nodeVersion":"22.23.1","dependencies":{"handlebars":"4.7.9","micromatch":"4.0.8","is-core-module":"2.16.1","eslint-module-utils":"2.12.1","eslint-import-resolver-node":"0.3.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","typescript":"5.9.3","@types/estree":"1.0.8","path-browserify":"1.0.1","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","@types/is-core-module":"2.2.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_3.1.1_1786301166024_0.9792457306597697"}}},"time":{"created":"2025-11-10T10:10:47.753Z","modified":"2026-08-09T18:46:06.355Z","1.0.0":"2025-11-10T10:10:48.152Z","1.1.0":"2025-11-15T10:45:01.331Z","1.1.1":"2025-11-23T10:22:13.525Z","1.1.2":"2025-12-06T09:02:09.836Z","1.2.0":"2026-02-03T05:29:42.031Z","2.0.0-beta.1":"2026-03-14T10:55:29.122Z","2.0.0-beta.2":"2026-03-15T09:52:50.090Z","2.0.0":"2026-03-15T18:45:15.082Z","2.0.1":"2026-03-30T14:11:58.544Z","3.0.0-beta.1":"2026-07-04T18:02:43.139Z","3.0.0":"2026-07-05T18:21:14.818Z","3.0.1":"2026-07-06T17:58:59.679Z","3.1.0":"2026-07-20T17:03:58.359Z","3.1.1":"2026-08-09T18:46:06.118Z"},"bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"author":{"name":"Javier Brea"},"license":"MIT","homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","keywords":["boundaries","elements","hierarchy"],"repository":{"url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","type":"git","folder":"packages/elements"},"description":"Element descriptors and matchers for @boundaries tools","maintainers":[{"name":"javierbrea","email":"javier.brea@gmail.com"}],"readme":"[![License][license-image]][license-url] [![Build status][build-image]][build-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Quality Gate][quality-gate-image]][quality-gate-url] [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fjavierbrea%2Feslint-plugin-boundaries%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/javierbrea/eslint-plugin-boundaries/master) \n\n[![NPM downloads][npm-downloads-image]][npm-downloads-url] [![Renovate](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com) [![Last commit][last-commit-image]][last-commit-url] [![Last release][release-image]][release-url]\n\n# @boundaries/elements\n\n> Entity descriptors and matchers for `@boundaries` tools, such as `@boundaries/eslint-plugin`.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Core Concepts](#core-concepts)\n  - [Entities](#entities)\n  - [Elements](#elements)\n  - [Files](#files)\n  - [Modules](#modules)\n- [Usage](#usage)\n  - [Configuration Options](#configuration-options)\n  - [Creating a Matcher](#creating-a-matcher)\n  - [Element Descriptors](#element-descriptors)\n  - [File Descriptors](#file-descriptors)\n  - [Describing Entities](#describing-entities)\n  - [Describing Dependencies](#describing-dependencies)\n  - [Matching Entities](#matching-entities)\n  - [Matching Dependencies](#matching-dependencies)\n  - [Template Variables](#template-variables)\n  - [Flagging Dependencies as External](#flagging-dependencies-as-external)\n- [API Reference](#api-reference)\n  - [Class: Elements](#class-elements)\n  - [Matcher Instance Methods](#matcher-instance-methods)\n  - [Selector Reference](#selector-reference)\n  - [Description Reference](#description-reference)\n- [Legacy Selectors](#legacy-selectors)\n- [Migration from v2](#migration-from-v2)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Introduction\n\n`@boundaries/elements` provides a system for describing and matching **entities** in JavaScript and TypeScript projects. An entity is any file or dependency under analysis, described by three complementary facets:\n\n- **Element** — the architectural role (e.g., component, service, helper)\n- **File** — per-file metadata and categorization\n- **Module** — the origin of a dependency (local, external, or core)\n\nTogether, these facets let you define architectural boundaries, validate dependencies between parts of your codebase, and enforce structural rules. This package powers tools like [`@boundaries/eslint-plugin`](https://github.com/javierbrea/eslint-plugin-boundaries) and uses [Micromatch patterns](https://github.com/micromatch/micromatch) for flexible matching.\n\n>[!NOTE]\n> This package does not read or analyze your codebase directly. It provides the core logic for defining and matching entities and dependencies, which can be integrated into linters, build systems, or custom tooling.\n\n## Features\n\n- **Entity-based model** — describe files and dependencies as entities with element, file, and module facets\n- **Flexible pattern matching** using Micromatch syntax\n- **File categorization** independent from elements\n- **Module origin detection** — distinguish local, external, and core dependencies\n- **Template variables** for dynamic selector matching\n- **Built-in caching** for optimal performance\n- **Capture path fragments** for advanced matching scenarios\n\n## Installation\n\nInstall the package via npm:\n\n```bash\nnpm install @boundaries/elements\n```\n\n## Quick Start\n\nDefine how your project is structured, then describe and match entities:\n\n```typescript\nimport { Elements } from '@boundaries/elements';\n\nconst elements = new Elements();\n\n// Define your project structure\nconst matcher = elements.getMatcher({\n  elements: [\n    { type: \"component\", pattern: \"src/components/*\", capture: [\"name\"] },\n    { type: \"service\", pattern: \"src/services/*.ts\", capture: [\"name\"] },\n  ],\n  files: [\n    { pattern: \"**/*.spec.ts\", category: \"test\" },\n    { pattern: \"**/*.controller.ts\", category: \"controller\" },\n  ],\n});\n\n// Describe an entity — returns element, file, and module information\nconst entity = matcher.describeEntity(\"src/components/Button/Button.spec.ts\");\n\nconsole.log(entity.element.types);    // [\"component\"]\nconsole.log(entity.element.captured); // { name: \"Button\" }\nconsole.log(entity.file.categories);  // [\"test\"]\nconsole.log(entity.module.origin);    // \"local\"\n```\n\nMatch entities against selectors:\n\n```typescript\n// Does this file belong to a component?\nmatcher.isEntityMatch(\"src/components/Button/index.ts\", {\n  element: { type: \"component\" },\n}); // true\n\n// Is this file a test file inside a component?\nmatcher.isEntityMatch(\"src/components/Button/Button.spec.ts\", {\n  element: { type: \"component\" },\n  file: { categories: \"test\" },\n}); // true\n\n// Validate dependencies between entities\nmatcher.isDependencyMatch(\n  {\n    from: \"src/components/Button/index.ts\",\n    to: \"src/services/Api.ts\",\n    source: \"../../services/Api\",\n    kind: \"value\",\n    nodeKind: \"ImportDeclaration\",\n  },\n  {\n    from: { element: { type: \"component\" } },\n    to: { element: { type: \"service\" } },\n    dependency: { kind: \"value\" },\n  }\n); // true\n```\n\n## Core Concepts\n\n### Entities\n\nAn **entity** is the central abstraction in `@boundaries/elements`. Every file or dependency in your project is an entity, described by three facets:\n\n```\nEntity\n├── element  — architectural role (component, service, module, ...)\n├── file     — per-file metadata (categories, captured values)\n└── module   — origin information (local, external, core)\n```\n\nWhen you describe an entity, you get a composite object with all three facets:\n\n```typescript\nconst entity = matcher.describeEntity(\"src/modules/auth/auth.controller.ts\");\n// {\n//   element: { types: [\"module\"], path: \"src/modules/auth\", captured: { name: \"auth\" }, ... },\n//   file:    { categories: [\"controller\"], path: \"src/.../auth.controller.ts\", ... },\n//   module:  { origin: \"local\", source: null, internalPath: null }\n// }\n```\n\n### Elements\n\nAn **element** represents an architectural unit — a meaningful group of files in your project (components, services, modules, helpers, etc.). Elements are defined via [element descriptors](#element-descriptors) that map file path patterns to types.\n\nKey characteristics:\n- A file can belong to an element (or be unknown if no descriptor matches)\n- Elements form hierarchies: a component inside a module has that module as its parent\n- An element can have multiple types (e.g., a file matching both \"component\" and \"widget\" descriptors)\n\n### Files\n\nA **file** provides per-file metadata and categorization, independent from which element the file belongs to. Files are categorized via [file descriptors](#file-descriptors).\n\nFor example, within a \"module\" element, you can distinguish between controllers, services, models, and tests — all belonging to the same element but having different file categories.\n\nA file can match multiple file descriptors, accumulating all matched categories.\n\n### Modules\n\nA **module** describes the origin of a dependency:\n\n- **`local`** — files within your project\n- **`external`** — external dependencies (e.g., packages from `node_modules`)\n- **`core`** — Node.js built-in modules (e.g., `fs`, `path`, `node:crypto`)\n\nFor external and core modules, the module description also includes `source` (the base package name, e.g., `\"react\"`) and `internalPath` (the subpath, e.g., `\"hooks/useState\"` for `\"react/hooks/useState\"`).\n\n## Usage\n\n### Configuration Options\n\nWhen creating an `Elements` instance, you can provide configuration options that will be used as defaults for all matchers:\n\n```typescript\nconst elements = new Elements({\n  ignorePaths: [\"**/dist/**\", \"**/build/**\", \"**/node_modules/**\"],\n  includePaths: [\"src/**/*\"],\n  rootPath: \"/absolute/path/to/project\",\n  flagAsExternal: {\n    unresolvableAlias: true,\n    inNodeModules: true,\n    outsideRootPath: true,\n    customSourcePatterns: [\"@myorg/*\"],\n  },\n});\n```\n\n**Available options:**\n\n- **`ignorePaths`**: Micromatch pattern(s) to exclude certain paths from matching (default: none)\n- **`includePaths`**: Micromatch pattern(s) to include only specific paths (default: all paths)\n- **`legacyTemplates`**: Whether to enable legacy template syntax support (default: `true`, but it will be `false` in future releases). This allows using `${variable}` syntax in templates for backward compatibility.\n- **`cache`**: Whether to enable internal caching to improve performance (default: `true`)\n- **`rootPath`**: Absolute path to the project root. When configured, file paths should be provided as absolute paths to allow the package to determine which files are outside the project root (default: `undefined`)\n- **`flagAsExternal`**: Configuration for categorizing dependencies as external or local. Multiple conditions can be specified, and dependencies will be categorized as external if ANY condition is met (OR logic). See [Flagging Dependencies as External](#flagging-dependencies-as-external) for details.\n\n> [!NOTE]\n> **Pattern Matching with `rootPath`:**\n> When `rootPath` **is configured**:\n> - **Matching patterns** in element descriptors are **relative to the `rootPath`**. The package automatically converts absolute paths to relative paths internally for pattern matching.\n> - With **`partialMatch: true`** (the default), patterns are evaluated **right-to-left** (from the end of the path), so the relativity to `rootPath` is typically less important. For example, a pattern like `*.model.ts` will match any file ending with `.model.ts` regardless of its location within `rootPath`.\n> - With **`partialMatch: false`**, patterns must match the complete relative path from `rootPath`. Files outside `rootPath` maintain their absolute paths and require absolute patterns to match.\n\n### Creating a Matcher\n\nUse the `getMatcher` method to create a matcher with a descriptors configuration:\n\n```typescript\nconst matcher = elements.getMatcher({\n  elements: [\n    { type: \"component\", pattern: \"src/components/*\" },\n  ],\n  files: [\n    { category: \"helper\", pattern: \"src/helpers/*.js\" },\n  ]\n});\n```\n\nThe `getMatcher` method accepts a `DescriptorsConfig` object with the following properties:\n\n- **`elements`** (`ElementDescriptor[]`): Optional array of [element descriptors](#element-descriptors). If not provided, no element abstraction layer is created and only file descriptors are used.\n- **`files`** (`FileDescriptor[]`): Optional array of [file descriptors](#file-descriptors). If not provided, only element descriptors are used to describe files.\n- **`elementsSingleMatch`** (`boolean`): When `true`, only the first matching descriptor's type is used at each path level. When `false` (default), an element can match multiple type descriptors, accumulating all matched types in the `types` array. Takes precedence over the deprecated `elementsSingleType` when both are set.\n- **`elementsSingleType`** (`boolean`): _(Deprecated)_ Alias of `elementsSingleMatch`, kept for backward compatibility.\n- **`filesSingleMatch`** (`boolean`): When `true`, only the first matching file descriptor's category is used at each file; matching stops there. When `false` (default), a file accumulates every category whose descriptor pattern matches it.\n\n> [!NOTE]\n> `elementsSingleMatch`/`filesSingleMatch` are global shorthands equivalent to setting `stopMatching: true` on every descriptor. For finer-grained control — letting most descriptors accumulate while a few specific ones stop or override the accumulation — use the per-descriptor `stopMatching`/`exclusive` options described in [Element Descriptors](#element-descriptors) and [File Descriptors](#file-descriptors).\n\nYou can combine element and file descriptors:\n\n```typescript\nconst matcher = elements.getMatcher({\n  elements: [\n    { type: \"module\", pattern: \"src/modules/*\" },\n  ],\n  files: [\n    { pattern: \"**/*.controller.ts\", category: \"controller\", capture: [\"name\"] },\n    { pattern: \"**/*.service.ts\", category: \"service\", capture: [\"name\"] },\n    { pattern: \"**/*.model.ts\", category: \"model\", capture: [\"name\"] },\n  ],\n});\n```\n\n> **Tip:** Matchers with identical descriptors and options share the same cache instance for improved performance.\n\nYou can override the default options when creating a matcher:\n\n```typescript\nconst matcher = elements.getMatcher(\n  { elements: [/* descriptors */] },\n  {\n    ignorePaths: [\"**/*.test.ts\"],\n  }\n);\n```\n\n### Element Descriptors\n\nElement descriptors define how files are identified and categorized into architectural elements (e.g., modules, components, services). Each descriptor is an object with the following properties:\n\n- **`pattern`** (`string | string[]`): Micromatch pattern(s) to match file paths\n- **`type`** (`string`): The element type to assign to matching files\n- **`category`** (`string`): _(Deprecated)_ Additional categorization for the element. Use [file descriptors](#file-descriptors) with `categories` instead for more flexible per-file categorization.\n- **`mode`** (`\"file\" | \"folder\" | \"full\"`): _(Deprecated)_ Matching mode (default: `\"folder\"`)\n  - `\"folder\"`: Matches the first folder matching the pattern. The library will add `**/*` to the given pattern for matching files, because it needs to know exactly which folder has to be considered the element. So, you have to provide patterns matching the folder being the element, not the files directly.\n  - `\"file\"`: Matches files directly, but still matches progressively from the right. The provided pattern will not be modified.\n  - `\"full\"`: Matches the complete path.\n- **`partialMatch`** (`boolean`): Whether the pattern is allowed to match only a suffix of the file path (default: `true`). When `true`, the pattern is matched right-to-left, so it only needs to match the end of the path (`components/*` matches any path ending in `components/<something>`). This means you only need wildcards in the path segments you want to capture — intermediate segments are traversed automatically. If you also need to capture values from the beginning (left side) of the path, complement with `basePattern` and `baseCapture`. When `false`, the pattern is matched against the full file path from the project root, while keeping folder semantics (the element `path` is the matched folder prefix). It defaults to `true` for backward compatibility, but will most likely default to `false` in a future major version and eventually be removed, because requiring the full pattern is more intuitive and is already how file descriptors match. When `false`, the `mode` option has no effect.\n- **`basePattern`** (`string`): Additional pattern that must match from the project root. Only useful when `partialMatch: true` (the default): use it when you want to capture values from the beginning (left side) of the path, without having to define wildcards for every intermediate path segment between the root and the right-side `pattern`.\n- **`capture`** (`string[]`): Array of keys to capture path fragments\n- **`baseCapture`** (`string[]`): Array of keys to capture fragments from `basePattern`. Only useful together with `basePattern`, and therefore only when `partialMatch: true`. If the same key is defined in both `capture` and `baseCapture`, the value from `capture` takes precedence.\n- **`stopMatching`** (`boolean`): When `true`, if this descriptor matches, previously accumulated types at that path level are kept and no further descriptors are evaluated for that level (default: `false`). Applies independently at each path level, so it affects a parent level the same way it affects the main element.\n- **`exclusive`** (`boolean`): When `true`, if this descriptor matches, previously accumulated types at that path level are discarded, only this descriptor's type is kept, and no further descriptors are evaluated (default: `false`). Takes precedence over `stopMatching` when both are set. Applies independently at each path level, so it affects a parent level the same way it affects the main element.\n\n### File Descriptors\n\nFile descriptors allow categorizing individual files independently from the element they belong to. This provides more granular control over file classification within elements. Each descriptor is an object with the following properties:\n\n- **`pattern`** (`string | string[]`): Micromatch pattern(s) to match file paths. Each pattern is matched against the **full file path** in a single pass (there is no right-to-left accumulation, and no option to change it). Use `**/` to match files at any depth — for example `**/*.spec.ts` rather than `*.spec.ts`.\n- **`category`** (`string`): The category to assign to matching files (e.g., `\"controller\"`, `\"service\"`, `\"model\"`).\n- **`capture`** (`string[]`): Array of keys to capture path fragments from the pattern.\n- **`stopMatching`** (`boolean`): When `true`, if this descriptor matches, previously accumulated categories are kept and no further file descriptors are evaluated for that file (default: `false`).\n- **`exclusive`** (`boolean`): When `true`, if this descriptor matches, previously accumulated categories are discarded, only this descriptor's category is kept, and no further file descriptors are evaluated (default: `false`). Takes precedence over `stopMatching` when both are set.\n\n```typescript\nconst matcher = elements.getMatcher({\n  elements: [\n    { type: \"module\", pattern: \"src/modules/*\", capture: [\"moduleName\"] },\n  ],\n  files: [\n    { pattern: \"**/*.controller.ts\", category: \"controller\", capture: [\"name\"] },\n    { pattern: \"**/*.service.ts\", category: \"service\", capture: [\"name\"] },\n    { pattern: \"**/*.spec.ts\", category: \"test\", capture: [\"name\"] },\n    { pattern: \"**/index.ts\", category: \"public\", exclusive: true },\n  ],\n});\n```\n\n> [!NOTE]\n> A file can match multiple file descriptors, accumulating all matched categories in the `categories` array of the file description — unless a matching descriptor sets `stopMatching`/`exclusive`, or the global `filesSingleMatch` option is enabled.\n\n### Describing Entities\n\nThe `describeEntity` method is the primary way to get information about a file or dependency. It returns a unified description combining all three facets:\n\n```typescript\nconst entity = matcher.describeEntity(\"src/modules/auth/auth.controller.ts\");\n```\n\nThe result is an `EntityDescription` object:\n\n```ts\n{\n  element: ElementDescription,  // Architectural role\n  file: FileDescription,        // File-level metadata\n  module: ModuleDescription,    // Origin information\n}\n```\n\n**Element facet** — architectural information about the element the file belongs to:\n\n| Property | Type | Description |\n|---|---|---|\n| `types` | `string[] \\| null` | Matched element types (e.g., `[\"module\"]`). Contains multiple types unless `elementsSingleMatch` is enabled. `null` for unknown/ignored. |\n| `path` | `string \\| null` | Path representing the detected element boundary |\n| `captured` | `object \\| null` | Captured values from descriptor patterns |\n| `parents` | `ElementParent[]` | Parent element chain. Each parent has `types`, `path`, `category`, and `captured`. |\n| `fileInternalPath` | `string \\| null` | Path of the file relative to the element it belongs to |\n| `isIgnored` | `boolean` | Whether the file was excluded by `ignorePaths` / `includePaths` |\n| `isUnknown` | `boolean` | Whether no descriptor matched |\n\n**File facet** — per-file categorization based on [file descriptors](#file-descriptors):\n\n| Property | Type | Description |\n|---|---|---|\n| `categories` | `string[] \\| null` | Matched file categories (e.g., `[\"controller\"]`). `null` for unknown/ignored. |\n| `path` | `string \\| null` | File path |\n| `captured` | `object \\| null` | Captured values from file descriptor patterns |\n| `isIgnored` | `boolean` | Whether the file was excluded |\n| `isUnknown` | `boolean` | Whether no file descriptor matched |\n\n**Module facet** — origin information:\n\n| Property | Type | Description |\n|---|---|---|\n| `origin` | `\"local\" \\| \"external\" \\| \"core\"` | Where the dependency comes from |\n| `source` | `string \\| null` | Base module name for external/core (e.g., `\"react\"`). `null` for local. |\n| `internalPath` | `string \\| null` | Path within the module (e.g., `\"hooks/useState\"`). `null` for local. |\n\nExample:\n\n```typescript\nconst entity = matcher.describeEntity(\"src/modules/auth/auth.controller.ts\");\n\nconsole.log(entity.element.types);       // [\"module\"]\nconsole.log(entity.element.path);        // \"src/modules/auth\"\nconsole.log(entity.element.captured);    // { moduleName: \"auth\" }\nconsole.log(entity.file.categories);     // [\"controller\"]\nconsole.log(entity.file.captured);       // { name: \"auth\" }\nconsole.log(entity.module.origin);       // \"local\"\n```\n\nFor external dependencies, pass a `source` parameter:\n\n```typescript\nconst entity = matcher.describeEntity(\"react/hooks\", \"react/hooks\");\n\nconsole.log(entity.module.origin);       // \"external\"\nconsole.log(entity.module.source);       // \"react\"\nconsole.log(entity.module.internalPath); // \"hooks\"\n```\n\n> [!TIP]\n> For full details on all description properties and edge cases (ignored, unknown), see the [Description Reference](#description-reference) in the API Reference.\n\n### Describing Dependencies\n\nThe `describeDependency` method describes the relationship between two entities:\n\n```typescript\nconst dep = matcher.describeDependency({\n  from: \"src/components/Button/index.ts\",\n  to: \"src/services/Api.ts\",\n  source: \"../../services/Api\",\n  kind: \"value\",\n  nodeKind: \"ImportDeclaration\",\n  specifiers: [\"ApiClient\"],\n});\n```\n\nThe result contains:\n\n```ts\n{\n  from: EntityDescription,      // Source entity (the file importing)\n  to: EntityDescription,        // Target entity (the file being imported)\n  dependency: {\n    source: string,             // Raw import/export source string\n    kind: \"value\" | \"type\" | \"typeof\",\n    nodeKind: string | null,    // AST node type (e.g., \"ImportDeclaration\")\n    specifiers: string[] | null,\n    relationship: {\n      from: DependencyRelationshipType | null,\n      to: DependencyRelationshipType | null,\n    }\n  }\n}\n```\n\nBoth `from` and `to` are full [entity descriptions](#describing-entities), so you can inspect element, file, and module information for both sides:\n\n```typescript\nconsole.log(dep.from.element.types);     // [\"component\"]\nconsole.log(dep.to.element.types);       // [\"service\"]\nconsole.log(dep.to.module.origin);       // \"local\"\nconsole.log(dep.dependency.source);      // \"../../services/Api\"\nconsole.log(dep.dependency.kind);        // \"value\"\n```\n\nThe `relationship` field describes how the two entities relate to each other structurally. Possible values: `\"internal\"`, `\"child\"`, `\"parent\"`, `\"sibling\"`, `\"descendant\"`, `\"ancestor\"`, `\"uncle\"`, `\"nephew\"`, or `null`.\n\n- `relationship.to` — how `to` relates to `from` (e.g., `\"child\"` means the target is a child of the source)\n- `relationship.from` — the inverse perspective\n\n### Matching Entities\n\nTo check whether a file matches specific criteria, use `isEntityMatch` with an **entity selector**. An entity selector is an object with optional `element`, `file`, and `module` sub-selectors — all must match for the entity to match:\n\n```typescript\n// Match local modules with \"controller\" file category\nmatcher.isEntityMatch(\"src/modules/auth/auth.controller.ts\", {\n  element: { type: \"module\" },\n  file: { categories: \"controller\" },\n  module: { origin: \"local\" },\n}); // true\n```\n\nYou only need to specify the sub-selectors you care about:\n\n```typescript\n// Just check the element type\nmatcher.isEntityMatch(\"src/components/Button/index.ts\", {\n  element: { type: \"component\" },\n}); // true\n\n// Just check if it's an external dependency\nmatcher.isEntityMatch(\"react\", {\n  module: { origin: \"external\" },\n}, { source: \"react\" }); // true\n\n// Just check the file category\nmatcher.isEntityMatch(\"src/modules/auth/auth.spec.ts\", {\n  file: { categories: \"test\" },\n}); // true\n```\n\n#### Entity Selector Properties\n\n**Element sub-selector** — matches against element description properties:\n\n- **`type`** (`string | string[]`): Micromatch pattern(s) for the element type. Matches the first type in the `types` array.\n- **`types`** (`string | string[] | ArrayQuery<string>`): Micromatch pattern(s) for matching against all element types, or an [array query object](#array-query-selectors) for richer matching (`anyOf`, `allOf`, `noneOf`, `equalsTo`, `atIndex`, `hasLength`).\n- **`path`** (`string | string[]`): Micromatch pattern(s) for the element path.\n- **`captured`** (`object | object[]`): Captured values selector. Object = AND logic (all keys must match). Array of objects = OR logic (any object can match).\n- **`parent`** (`object | null`): Selector for the **first** (closest) parent element. Set to `null` to match top-level elements with no parents. Supports `type`, `types`, `path`, and `captured`. **Unchanged** — still matches only `parents[0]`.\n- **`parents`** (`ArrayQuery<ParentElementSingleSelector>`): [Array query](#array-query-selectors) over the **full ancestor chain**. `parents[0]` is the closest parent; the last element is the outermost ancestor. See [Array query selectors](#array-query-selectors) for operators.\n- **`fileInternalPath`** (`string | string[]`): Pattern(s) for the path of the file relative to the element.\n- **`isIgnored`** (`boolean`): Whether the element is ignored.\n- **`isUnknown`** (`boolean`): Whether no descriptor matched.\n\n**File sub-selector** — matches against file description properties:\n\n- **`path`** (`string | string[]`): Micromatch pattern(s) for the file path.\n- **`categories`** (`string | string[] | ArrayQuery<string>`): Micromatch pattern(s) for file categories, or an [array query object](#array-query-selectors) for richer matching (`anyOf`, `allOf`, `noneOf`, `equalsTo`, `atIndex`, `hasLength`).\n- **`captured`** (`object | object[]`): Captured values selector (same semantics as element).\n- **`isIgnored`** (`boolean`): Whether the file is ignored.\n- **`isUnknown`** (`boolean`): Whether no file descriptor matched.\n\n**Module sub-selector** — matches against module description properties:\n\n- **`origin`** (`string | string[]`): Micromatch pattern(s) for the origin (`\"local\"`, `\"external\"`, or `\"core\"`).\n- **`source`** (`string | string[]`): Micromatch pattern(s) for the base module name (e.g., `\"react\"`, `\"fs\"`).\n- **`internalPath`** (`string | string[]`): Micromatch pattern(s) for the path within the module.\n\n> [!NOTE]\n> All selector properties are optional and support `null` to match only entities with `null` in the corresponding description property.\n\n> [!NOTE]\n> For backward compatibility, entity selectors also accept flat element selectors (without the `element`/`file`/`module` nesting). Properties like `origin`, `elementPath`, and `internalPath` in flat selectors are automatically mapped to their new locations. See [Legacy Selectors](#legacy-selectors) for details.\n\n### Array Query Selectors\n\nThe `types` (element), `categories` (file), and `parents` (element) selector properties accept an **array query object** in addition to the plain string / string-array form. An array query gives you fine-grained control over how the target array is matched.\n\nAll operators present in the same object are **AND-combined**. An absent operator imposes no constraint.\n\n| Operator | Shape | Matches when |\n| --- | --- | --- |\n| `anyOf` | `(string \\| { expand: string })[]` | At least one array element matches at least one of the matchers. Empty operand never matches. |\n| `allOf` | `(string \\| { expand: string })[]` | For every matcher, at least one array element matches it. Empty operand vacuously matches. |\n| `noneOf` | `(string \\| { expand: string })[]` | No array element matches any of the matchers. Empty operand always matches. |\n| `equalsTo` | `string[]` | Array length equals `N` **and** `array[i]` matches `matcher[i]` (ordered, exact-length). |\n| `atIndex` | `{ index: number; matches: TMatcher \\| TMatcher[] }` | Resolves the index (negative counts from end), then that element matches `matches`. When `matches` is an array, OR semantics apply — the element must satisfy at least one of the matchers. Out-of-range never matches. |\n| `hasLength` | `number` | The array length is exactly this value. |\n\n**Edge cases:**\n- When the target array is `null` (unknown/ignored element or file), the entire query returns `false`.\n- An empty query object `{}` returns `true` for any non-null array (no constraints).\n- For `equalsTo`, order matters: `[\"a\", \"b\"]` does not match `[\"b\", \"a\"]`.\n- Negative `atIndex.index` counts from the end: `-1` = last element (outermost ancestor for `parents`).\n- All string matchers are micromatch patterns and are rendered as Handlebars templates before matching, exactly like all other selector values.\n\n**`TMatcher` per property:**\n- `types` (element) / `categories` (file): `string` (a micromatch pattern) or `{ expand: string }` (see below)\n- `parents`: `ParentElementSingleSelector` — an object supporting `type`, `types` (accepts `StringArrayQuery`), `path`, `category`, and `captured`\n\n#### `{ expand }` items in `anyOf` / `allOf` / `noneOf`\n\nFor `element.types`, `file.categories`, and `parent.types`, each item in `anyOf`, `allOf`, and `noneOf` can be a `{ expand: \"{{ path }}\" }` object instead of a plain string. The path is resolved against the template data at match time and the result is spread in place as additional string matchers.\n\nThis is useful when you need to build the operand list dynamically from the other side's property — for example, to match elements that share (or do not share) types with a given element.\n\n**Resolution:**\n- Path resolves to a string array → each element becomes a separate matcher.\n- Path resolves to a scalar → a single matcher.\n- Path resolves to null/undefined, or the value is not a single `{{ }}` expression → no matchers (empty-operand rules apply: empty `noneOf` always passes; empty `anyOf` never matches).\n\n```typescript\n// element.types: to element must not share any type with the from element\nmatcher.isEntityMatch(toFilePath, {\n  element: {\n    types: { noneOf: [{ expand: \"{{ from.element.types }}\" }] },\n  },\n}, { extraTemplateData: { from: { element: fromDescription } } });\n\n// element.types: mixed static + dynamic — exclude \"legacy\" and all of from's types\n{\n  element: {\n    types: { noneOf: [\"legacy\", { expand: \"{{ from.element.types }}\" }] },\n  },\n}\n\n// file.categories: to file must share at least one category with the from file\n{\n  file: {\n    categories: { anyOf: [{ expand: \"{{ from.file.categories }}\" }] },\n  },\n}\n```\n\n**Examples:**\n\n```typescript\n// element.types: require at least one of these types\nmatcher.isEntityMatch(filePath, {\n  element: { types: { anyOf: [\"component\", \"widget\"] } },\n});\n\n// element.types: forbid certain types\nmatcher.isEntityMatch(filePath, {\n  element: { types: { noneOf: [\"ignored\", \"legacy\"] } },\n});\n\n// file.categories: require both categories to be present\nmatcher.isFileMatch(filePath, {\n  categories: { allOf: [\"react\", \"test\"] },\n});\n\n// file.categories: file has exactly one category\nmatcher.isFileMatch(filePath, {\n  categories: { hasLength: 1 },\n});\n\n// element.parents: top-level element (no parents)\nmatcher.isEntityMatch(filePath, {\n  element: { parents: { hasLength: 0 } },\n});\n\n// element.parents: closest parent (index 0) is a module\nmatcher.isEntityMatch(filePath, {\n  element: { parents: { atIndex: { index: 0, matches: { type: \"module\" } } } },\n});\n\n// element.parents: outermost ancestor (index -1) is an app\nmatcher.isEntityMatch(filePath, {\n  element: { parents: { atIndex: { index: -1, matches: { type: \"app\" } } } },\n});\n\n// element.parents: closest parent is a module OR an app (OR via array)\nmatcher.isEntityMatch(filePath, {\n  element: {\n    parents: {\n      atIndex: { index: 0, matches: [{ type: \"module\" }, { type: \"app\" }] },\n    },\n  },\n});\n\n// file.categories: first category is \"components\" or \"ui\"\nmatcher.isFileMatch(filePath, {\n  categories: { atIndex: { index: 0, matches: [\"components\", \"ui\"] } },\n});\n\n// element.parents: ancestor chain has exactly two levels in order\nmatcher.isEntityMatch(filePath, {\n  element: {\n    parents: { equalsTo: [{ type: \"module\" }, { type: \"app\" }] },\n  },\n});\n```\n\n### Matching Dependencies\n\nTo check whether a dependency matches specific criteria, use `isDependencyMatch`. It takes the dependency properties and a dependency selector:\n\n```typescript\nmatcher.isDependencyMatch(\n  {\n    from: \"src/components/Button/index.ts\",\n    to: \"src/services/Api.ts\",\n    source: \"../../services/Api\",\n    kind: \"value\",\n    nodeKind: \"ImportDeclaration\",\n  },\n  {\n    from: { element: { type: \"component\" } },\n    to: { element: { type: \"service\" } },\n    dependency: { kind: \"value\" },\n  }\n); // true\n```\n\n**Dependency properties** (input):\n\n- **`from`** (`string`): Source file path\n- **`to`** (`string`): Target file path\n- **`source`** (`string`): Import/export source as written in code\n- **`kind`** (`string`): Import kind (`\"type\"`, `\"value\"`, `\"typeof\"`)\n- **`nodeKind`** (`string`): AST node kind\n- **`specifiers`** (`string[]`): Imported/exported names\n\n**Dependency selector:**\n\n- **`from`** (`entity selector | entity selector[]`): [Entity selector(s)](#matching-entities) for the source entity\n- **`to`** (`entity selector | entity selector[]`): [Entity selector(s)](#matching-entities) for the target entity\n- **`dependency`** (`object | object[]`): Selector(s) for dependency metadata. When an array is provided, the metadata matches if any selector matches (OR logic). Properties:\n  - **`kind`** (`string | string[]`): Micromatch pattern(s) for the dependency kind\n  - **`source`** (`string | string[]`): Pattern(s) to match the import/export source\n  - **`specifiers`** (`string | string[]`): Pattern(s) for import/export specifiers\n  - **`nodeKind`** (`string | string[]`): Pattern(s) for the AST node type\n  - **`relationship`** (`object`): Relationship selectors from both perspectives:\n    - **`from`** (`string | string[]`): Relationship from the source perspective\n    - **`to`** (`string | string[]`): Relationship from the target perspective (e.g., `\"internal\"`, `\"child\"`, `\"parent\"`, `\"sibling\"`, `\"descendant\"`, `\"ancestor\"`, `\"uncle\"`, `\"nephew\"`)\n\n> **Important:** All properties within a single selector must match for it to be considered a match (AND logic). Use arrays of selectors for OR logic.\n\n```typescript\n// Components can only import from services via type imports\nmatcher.isDependencyMatch(\n  { from: \"src/components/Button/index.ts\", to: \"src/services/Api.ts\", source: \"../../services/Api\", kind: \"type\", nodeKind: \"ImportDeclaration\" },\n  {\n    from: { element: { type: \"component\" } },\n    to: { element: { type: \"service\" } },\n    dependency: { kind: \"type\" },\n  }\n); // true\n\n// Match dependencies from external modules\nmatcher.isDependencyMatch(\n  { from: \"src/index.ts\", to: \"react\", source: \"react\", kind: \"value\", nodeKind: \"ImportDeclaration\" },\n  {\n    to: { module: { origin: \"external\", source: \"react*\" } },\n  }\n); // true\n```\n\n### Template Variables\n\nSelectors support template variables using [Handlebars syntax](https://handlebarsjs.com/) (`{{ variableName }}`). Templates are resolved at match time using the data available in the matching context.\n\n#### Available Template Data\n\n**For entity matching:**\n- Properties of the entity under match are available in the `element` object (types, captured, path, etc.)\n\n**For dependency matching:**\n- `from`: Properties of the source entity (with `element`, `file`, `module` sub-objects)\n- `to`: Properties of the target entity (with `element`, `file`, `module` sub-objects)\n- `dependency`: Dependency metadata (`kind`, `nodeKind`, `specifiers`, `source`, `relationship`, etc.)\n\n#### Template Examples\n\n```ts\nconst matcher = elements.getMatcher({\n  elements: [\n    {\n      type: \"component\",\n      pattern: \"src/modules/*/components/*\",\n      partialMatch: false,\n      capture: [\"module\", \"componentName\"]\n    }\n  ],\n});\n\n// Match components from specific module using template\nmatcher.isElementMatch(\n  \"src/modules/auth/components/login-form/LoginForm.tsx\",\n  { \n    type: \"component\",\n    captured: { module: \"{{ element.captured.module }}\" }\n  },\n);\n\n// Using captured array for OR logic\nmatcher.isElementMatch(\n  \"src/modules/auth/components/login-form/LoginForm.tsx\",\n  { \n    type: \"component\",\n    captured: [\n      { module: \"auth\" },\n      { module: \"user\", componentName: \"user-profile\" },\n    ]\n  },\n);\n\n// Using templates in dependency selectors\nmatcher.isDependencyMatch(\n  {\n    from: \"src/components/Button.tsx\",\n    to: \"src/services/Api.ts\",\n    source: \"../services/Api\",\n    kind: \"type\",\n    nodeKind: \"ImportDeclaration\",\n    specifiers: [\"calculateSum\", \"calculateAvg\"],\n  },\n  {\n    from: { element: { type: \"{{ from.element.types.[0] }}\" } },\n    to: { element: { path: \"{{ to.element.path }}\" } },\n    dependency: {\n      specifiers: \"{{ lookup dependency.specifiers 0 }}\",\n      kind: \"{{ dependency.kind }}\",\n    },\n  }\n);\n```\n\n#### Using Extra Template Data\n\nYou can provide additional template data using the `extraTemplateData` option in `MatcherOptions`:\n\n```ts\nmatcher.isElementMatch(\n  \"src/components/UserProfile.tsx\",\n  { type: \"{{ componentType }}\" },\n  {\n    extraTemplateData: { componentType: \"component\" }\n  }\n);\n```\n\n### Flagging Dependencies as External\n\nThe `flagAsExternal` configuration allows you to control how dependencies are categorized as external or local. This is especially useful in monorepo setups where you may want to treat inter-package dependencies as external even though they're within the same repository.\n\n**Multiple conditions can be specified, and dependencies will be flagged as external if ANY condition is met (OR logic).**\n\n#### Available Options\n\n- **`unresolvableAlias`** (boolean, default: `true`): Non-relative imports whose path cannot be resolved are categorized as external\n  \n  ```typescript\n  const elements = new Elements({\n    flagAsExternal: { unresolvableAlias: true },\n  });\n  const matcher = elements.getMatcher({ elements: [/* descriptors */] });\n  \n  // describeDependency({ from, to, source, kind }):\n  // to: null, source: 'unresolved-module' -> to.module.origin: 'external'\n  // to: '/project/src/Button.ts', source: './Button' -> to.module.origin: 'local'\n  ```\n\n- **`inNodeModules`** (boolean, default: `true`): Non-relative paths that include `node_modules` in the resolved path are categorized as external\n  \n  ```typescript\n  const elements = new Elements({\n    flagAsExternal: { inNodeModules: true },\n  });\n  const matcher = elements.getMatcher({ elements: [/* descriptors */] });\n  \n  // describeDependency({ from, to, source, kind }):\n  // to: '/project/node_modules/react/index.js', source: 'react' -> to.module.origin: 'external'\n  // to: '/project/src/utils.ts', source: './utils' -> to.module.origin: 'local'\n  ```\n\n- **`outsideRootPath`** (boolean, default: `false`): Dependencies whose resolved path is outside the configured `rootPath` are categorized as external. This is particularly useful in monorepo setups.\n  \n  > **Important:** This option requires `rootPath` to be configured. When using this option, all file paths must be absolute and include the `rootPath` prefix for files within the project.\n  \n  ```typescript\n  const elements = new Elements({\n    rootPath: '/monorepo/packages/app',\n    flagAsExternal: { outsideRootPath: true },\n  });\n  const matcher = elements.getMatcher({ elements: [/* descriptors */] });\n  \n  // describeDependency({ from, to, source, kind }):\n  // to: '/monorepo/packages/shared/index.ts', source: '@myorg/shared' -> to.module.origin: 'external'\n  // to: '/monorepo/packages/app/src/utils/helper.ts', source: './utils/helper' -> to.module.origin: 'local'\n  ```\n\n- **`customSourcePatterns`** (string[], default: `[]`): Array of micromatch patterns that, when matching the import/export source string, categorize the dependency as external\n  \n  ```typescript\n  const elements = new Elements({\n    flagAsExternal: { customSourcePatterns: ['@myorg/*', '~/**'] },\n  });\n  const matcher = elements.getMatcher({ elements: [/* descriptors */] });\n  \n  // describeDependency({ from, to, source, kind }):\n  // source: '@myorg/shared' -> to.module.origin: 'external' (matches '@myorg/*')\n  // source: '~/utils/helper' -> to.module.origin: 'external' (matches '~/**')\n  // source: '@other/package' -> to.module.origin: 'local' (no match, unless inNodeModules is true or other conditions met)\n  ```\n\n#### Path Requirements with `rootPath`\n\nWhen `rootPath` is configured, the package needs absolute paths to correctly determine which files are outside the project root, but matching patterns must remain relative to `rootPath`, especially when `partialMatch: false` (because the default `partialMatch: true` matches progressively from the right, so it is typically less affected by relativity).\n\n```typescript\nconst elements = new Elements({\n  rootPath: '/project/packages/app',\n  flagAsExternal: {\n    outsideRootPath: true,\n  },\n});\n\n// Matching patterns are relative to rootPath\nconst matcher = elements.getMatcher({\n  elements: [\n    { type: 'component', pattern: 'src/**/*.ts', partialMatch: false }, // Relative to /project/packages/app\n  ],\n});\n\n// Using absolute file paths with relative patterns\nconst dep = matcher.describeDependency({\n  from: '/project/packages/app/src/index.ts',      // absolute file path\n  to: '/project/packages/shared/index.ts',         // absolute file path\n  source: '@myorg/shared',\n  kind: 'value',\n});\n// Result: dep.to.module.origin === 'external' (outside rootPath)\n// Note: Pattern 'src/**/*.ts' matches because the package converts\n// absolute paths to relative internally for pattern matching\n```\n\n> **Key Points:**\n> - **File paths** in API calls (`from`, `to`, `filePath`) must be **absolute** when using `rootPath`\n> - **Matching patterns** in element descriptors stay **relative** to `rootPath`\n> - The package handles the conversion internally\n> - When not using `rootPath`, the package continues to work with relative paths as before, maintaining backward compatibility.\n\n## API Reference\n\n### Class: Elements\n\n#### Constructor\n\nCreates a new `Elements` instance with optional default configuration.\n\n```ts\nnew Elements(options?: ConfigurationOptions);\n```\n\n#### `getMatcher`\n\nCreates a new matcher instance.\n\n- __Parameters__:\n  - `descriptors`: `DescriptorsConfig` — A [descriptors configuration](#creating-a-matcher) object with optional `elements`, `files`, `elementsSingleMatch`, and `filesSingleMatch` properties.\n  - `options`: `ConfigOptions` — Optional. [Configuration options](#configuration-options) for the matcher. Overrides the defaults set in the `Elements` instance.\n- __Returns__: `Matcher`\n\n```ts\nconst matcher = elements.getMatcher({\n  elements: [\n    { type: \"component\", pattern: \"src/components/*\" },\n  ],\n  files: [\n    { pattern: \"**/*.spec.ts\", category: \"test\" },\n  ],\n});\n```\n\n#### `clearCache`\n\nClears all cached matcher instances and shared caches.\n\n```ts\nelements.clearCache();\n```\n\n#### `serializeCache`\n\nSerializes all cached matcher instances and shared caches to a plain object.\n\n```ts\nconst cache = elements.serializeCache();\n```\n\n#### `setCacheFromSerialized`\n\nSets the cached matcher instances and shared caches from a serialized object.\n\n```ts\nconst cache = elements.serializeCache();\nelements.setCacheFromSerialized(cache);\n```\n\n### Matcher Instance Methods\n\n#### Entity Methods\n\n##### `describeEntity`\n\nReturns a detailed [entity description](#describing-entities) combining element, file, and module information.\n\n- __Parameters__:\n  - `filePath`: `string` — Optional. The path of the file to describe.\n  - `source`: `string` — Optional. The dependency source string for determining module origin.\n- __Returns__: `EntityDescription`\n\n```ts\nconst entity = matcher.describeEntity(\"src/components/Button.tsx\");\n```\n\n##### `isEntityMatch`\n\nChecks if a given path matches an [entity selector](#matching-entities).\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `EntitySelector` — Entity selector or array of entity selectors.\n  - `options`: `EntityMatcherOptions` — Optional. Includes optional `source` for module origin resolution.\n- __Returns__: `boolean`\n\n```ts\nmatcher.isEntityMatch(\"src/modules/auth/auth.controller.ts\", {\n  element: { type: \"module\" },\n  file: { categories: \"controller\" },\n});\n```\n\n##### `getEntitySelectorMatching`\n\nReturns the first matching entity selector result, or `null`.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `EntitySelector` — Entity selector to match against.\n  - `options`: `EntityMatcherOptions` — Optional.\n- __Returns__: `EntitySingleSelectorMatchResult | null` — Contains matched `element`, `file`, and `module` sub-selectors.\n\n```ts\nconst result = matcher.getEntitySelectorMatching(\"src/modules/auth/auth.controller.ts\", {\n  element: { type: \"module\" },\n  file: { categories: \"controller\" },\n});\n```\n\n##### `getEntitySelectorMatchingDescription`\n\nMatches an entity description (from `describeEntity`) against entity selectors.\n\n- __Parameters__:\n  - `description`: `EntityDescription` — The entity description to match.\n  - `selector`: `EntitySelector` — The entity selector to match against.\n  - `options`: `MatcherOptions` — Optional.\n- __Returns__: `EntitySingleSelectorMatchResult | null`\n\n```ts\nconst entity = matcher.describeEntity(\"src/modules/auth/auth.controller.ts\");\nconst result = matcher.getEntitySelectorMatchingDescription(entity, [{\n  element: { type: \"module\" },\n  file: { categories: \"controller\" },\n}]);\n```\n\n#### Dependency Methods\n\n##### `describeDependency`\n\nReturns a detailed [dependency description](#describing-dependencies).\n\n- __Parameters__:\n  - `dependency`: Object with `from`, `to`, `source`, `kind`, `nodeKind`, and `specifiers` properties.\n- __Returns__: `DependencyDescription`\n\n```ts\nconst dep = matcher.describeDependency({\n  from: \"src/components/Button.tsx\",\n  to: \"src/services/Api.ts\",\n  source: \"../services/Api\",\n  kind: \"type\",\n  nodeKind: \"ImportDeclaration\",\n});\n```\n\n##### `isDependencyMatch`\n\nChecks if dependency properties match a [dependency selector](#matching-dependencies).\n\n- __Parameters__:\n  - `dependency`: Object with `from`, `to`, `source`, `kind`, `nodeKind`, and `specifiers` properties.\n  - `selector`: `DependencySelector` — Dependency selector or array of selectors.\n- __Returns__: `boolean`\n\n```ts\nmatcher.isDependencyMatch(\n  { from: \"src/components/Button.tsx\", to: \"src/services/Api.ts\", source: \"../services/Api\", kind: \"type\", nodeKind: \"ImportDeclaration\" },\n  {\n    from: { element: { type: \"component\" } },\n    to: { element: { type: \"service\" } },\n    dependency: { nodeKind: \"Import*\" },\n  }\n);\n```\n\n##### `getDependencySelectorMatching`\n\nReturns the dependency selector matching result (`from`, `to`, `dependency`, `isMatch`).\n\n> [!NOTE]\n> When arrays of selectors are provided in the `from`, `to`, or `dependency` properties, the method returns the first matching selector from each group.\n\n- __Parameters__:\n  - `dependency`: Dependency properties.\n  - `selector`: `DependencySelector`.\n- __Returns__: `DependencySelectorMatchResult`\n\n```ts\nconst result = matcher.getDependencySelectorMatching(\n  { from: \"src/components/Button.tsx\", to: \"src/services/Api.ts\", source: \"../services/Api\", kind: \"type\" },\n  { to: { element: { type: \"service\" } }, dependency: { kind: \"type\" } }\n);\n```\n\n##### `getDependencySelectorMatchingDescription`\n\nMatches a dependency description (from `describeDependency`) against dependency selectors.\n\n> [!NOTE]\n> When arrays of selectors are provided in the `from`, `to`, or `dependency` properties, the method returns the first matching selector from each group.\n\n- __Parameters__:\n  - `description`: `DependencyDescription` — Dependency description to match.\n  - `selector`: `DependencySelector` — Array of dependency selectors.\n- __Returns__: `DependencySelectorMatchResult`\n\n```ts\nconst dep = matcher.describeDependency({ from: \"src/components/Button.tsx\", to: \"src/services/Api.ts\", source: \"../services/Api\", kind: \"type\", nodeKind: \"ImportDeclaration\" });\nconst result = matcher.getDependencySelectorMatchingDescription(dep, [{\n  to: { element: { type: \"service\" } },\n  dependency: { kind: \"type\" },\n}]);\n```\n\n#### Element Methods\n\nThese methods operate on the element facet only. They are useful when you only need element-level information without file or module context.\n\n##### `describeElement`\n\nReturns a detailed description of the element a file belongs to.\n\n- __Parameters__:\n  - `filePath`: `string` — The path of the file to describe.\n- __Returns__: `ElementDescription`\n\n```ts\nconst element = matcher.describeElement(\"src/components/Button.tsx\");\nconsole.log(element.types);    // [\"component\"]\nconsole.log(element.captured); // { name: \"Button\" }\nconsole.log(element.parents);  // []\n```\n\n##### `isElementMatch`\n\nChecks if a given path matches an element selector.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `ElementSelector` — Element selector or array of element selectors.\n- __Returns__: `boolean`\n\n```ts\nmatcher.isElementMatch(\"src/components/Button.tsx\", [{ type: \"component\" }]);\n```\n\n##### `getElementSelectorMatching`\n\nReturns the first matching element selector, or `null`.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `ElementSelector` — Element selector to match against.\n- __Returns__: `ElementSingleSelector | null`\n\n```ts\nconst result = matcher.getElementSelectorMatching(\"src/components/Button.tsx\", [{ type: \"component\" }]);\n```\n\n##### `getElementSelectorMatchingDescription`\n\nMatches an element description (from `describeElement`) against element selectors.\n\n- __Parameters__:\n  - `description`: `ElementDescription` — The element description to match.\n  - `selector`: `ElementSelector` — Array of element selectors.\n- __Returns__: `ElementSingleSelector | null`\n\n```ts\nconst element = matcher.describeElement(\"src/components/Button.tsx\");\nconst result = matcher.getElementSelectorMatchingDescription(element, [{ type: \"component\" }]);\n```\n\n#### Module Methods\n\nThese methods operate on the module facet only. They are useful for checking the origin of a dependency independently.\n\n##### `describeModule`\n\nReturns the module origin description for a file or dependency.\n\n- __Parameters__:\n  - `filePath`: `string` — Optional. The path of the file.\n  - `source`: `string` — Optional. The dependency source string.\n- __Returns__: `ModuleDescription`\n\n```ts\nconst mod = matcher.describeModule(\"react/hooks\", \"react/hooks\");\nconsole.log(mod.origin);       // \"external\"\nconsole.log(mod.source);       // \"react\"\nconsole.log(mod.internalPath); // \"hooks\"\n```\n\n##### `isModuleMatch`\n\nChecks if a given path matches a module selector.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `ModuleSelector` — Module selector to match against.\n  - `options`: `EntityMatcherOptions` — Optional. Includes optional `source`.\n- __Returns__: `boolean`\n\n```ts\nmatcher.isModuleMatch(\"react\", { origin: \"external\" }, { source: \"react\" });\nmatcher.isModuleMatch(\"node:fs\", { origin: \"core\" }, { source: \"node:fs\" });\n```\n\n##### `getModuleSelectorMatching`\n\nReturns the first matching module selector, or `null`.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `ModuleSelector` — Module selector to match against.\n  - `options`: `EntityMatcherOptions` — Optional.\n- __Returns__: `ModuleSingleSelector | null`\n\n```ts\nconst result = matcher.getModuleSelectorMatching(\"react\", { origin: \"external\" }, { source: \"react\" });\n```\n\n##### `getModuleSelectorMatchingDescription`\n\nMatches a module description (from `describeModule`) against module selectors.\n\n- __Parameters__:\n  - `description`: `ModuleDescription` — The module description to match.\n  - `selector`: `ModuleSelector` — Module selector to match against.\n  - `options`: `EntityMatcherOptions` — Optional.\n- __Returns__: `ModuleSingleSelector | null`\n\n```ts\nconst mod = matcher.describeModule(\"react\", \"react\");\nconst result = matcher.getModuleSelectorMatchingDescription(mod, { origin: \"external\" });\n```\n\n#### File Methods\n\nThese methods operate on the file facet only. They are useful when you only need file-level information without element or module context.\n\n##### `describeFile`\n\nReturns a detailed description of a file given its path.\n\n- __Parameters__:\n  - `filePath`: `string` — The path of the file to describe.\n- __Returns__: `FileDescription`\n\n```ts\nconst file = matcher.describeFile(\"src/modules/auth/auth.controller.ts\");\nconsole.log(file.categories); // [\"controller\"]\nconsole.log(file.captured);   // { name: \"auth\" }\nconsole.log(file.isUnknown);  // false\n```\n\n##### `isFileMatch`\n\nChecks if a given path matches a file selector.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `FileSelector` — File selector or array of file selectors.\n  - `options`: `MatcherOptions` — Optional.\n- __Returns__: `boolean`\n\n```ts\nmatcher.isFileMatch(\"src/modules/auth/auth.spec.ts\", { categories: \"test\" }); // true\n```\n\n##### `getFileSelectorMatching`\n\nReturns the first matching file selector, or `null`.\n\n- __Parameters__:\n  - `filePath`: `string` — The file path to check.\n  - `selector`: `FileSelector` — File selector to match against.\n  - `options`: `MatcherOptions` — Optional.\n- __Returns__: `FileSingleSelector | null`\n\n```ts\nconst result = matcher.getFileSelectorMatching(\"src/modules/auth/auth.spec.ts\", [{ categories: \"test\" }]);\n```\n\n##### `getFileSelectorMatchingDescription`\n\nMatches a file description (from `describeFile`) against file selectors.\n\n- __Parameters__:\n  - `description`: `FileDescription` — The file description to match.\n  - `selector`: `FileSelector` — File selector to match against.\n  - `options`: `MatcherOptions` — Optional.\n- __Returns__: `FileSingleSelector | null`\n\n```ts\nconst file = matcher.describeFile(\"src/modules/auth/auth.spec.ts\");\nconst result = matcher.getFileSelectorMatchingDescription(file, [{ categories: \"test\" }]);\n```\n\n#### Cache Methods\n\n##### `clearCache`\n\nClears the matcher's internal cache.\n\n```ts\nmatcher.clearCache();\n```\n\n> [!WARNING]\n> This only clears the internal cache for this matcher instance. Shared cache for micromatch results, regex and captures is not affected. You can clear all caches using `Elements.clearCache()`.\n\n##### `serializeCache`\n\nSerializes the matcher's cache.\n\n```ts\nconst cache = matcher.serializeCache();\n```\n\n##### `setCacheFromSerialized`\n\nRestores the matcher's cache from a serialized object.\n\n```ts\nconst cache = matcher.serializeCache();\nmatcher.clearCache();\nmatcher.setCacheFromSerialized(cache);\n```\n\n### Selector Reference\n\nThis section provides a complete reference of all selector properties.\n\n#### Element Selector\n\n| Property | Type | Description |\n|---|---|---|\n| `type` | `string \\| string[]` | Micromatch pattern(s) for element type. Matches the first type in `types`. |\n| `types` | `string \\| string[]` | Micromatch pattern(s) for matching against all element types. |\n| `path` | `string \\| string[]` | Micromatch pattern(s) for the element path. |\n| `captured` | `object \\| object[]` | Captured values selector. Object = AND, array = OR. |\n| `parent` | `object \\| null` | Selector for the first parent. `null` matches elements with no parents. Supports `type`, `types`, `path`, `captured`, `category` (deprecated). |\n| `fileInternalPath` | `string \\| string[]` | Pattern(s) for the file path relative to the element. |\n| `category` | `string \\| string[]` | _(Deprecated)_ Use file selector `categories` instead. |\n| `isIgnored` | `boolean` | Whether the element is ignored. |\n| `isUnknown` | `boolean` | Whether the element is unknown. |\n\n#### File Selector\n\n| Property | Type | Description |\n|---|---|---|\n| `path` | `string \\| string[]` | Micromatch pattern(s) for the file path. |\n| `categories` | `string \\| string[]` | Micromatch pattern(s) for file categories. |\n| `captured` | `object \\| object[]` | Captured values selector. |\n| `isIgnored` | `boolean` | Whether the file is ignored. |\n| `isUnknown` | `boolean` | Whether the file is unknown. |\n\n#### Module Selector\n\n| Property | Type | Description |\n|---|---|---|\n| `origin` | `string \\| string[]` | Micromatch pattern(s) for origin (`\"local\"`, `\"external\"`, `\"core\"`). |\n| `source` | `string \\| string[]` | Micromatch pattern(s) for the base module name. |\n| `internalPath` | `string \\| string[]` | Micromatch pattern(s) for the path within the module. |\n\n#### Entity Selector\n\n| Property | Type | Description |\n|---|---|---|\n| `element` | `ElementSelector` | Element sub-selector. |\n| `file` | `FileSelector` | File sub-selector. |\n| `module` | `ModuleSelector` | Module sub-selector. |\n\n#### Dependency Selector\n\n| Property | Type | Description |\n|---|---|---|\n| `from` | `EntitySelector \\| EntitySelector[]` | Entity selector(s) for the source entity. |\n| `to` | `EntitySelector \\| EntitySelector[]` | Entity selector(s) for the target entity. |\n| `dependency` | `DependencyInfoSelector \\| DependencyInfoSelector[]` | Dependency metadata selector(s). OR logic when array. |\n\n**Dependency info selector properties:**\n\n| Property | Type | Description |\n|---|---|---|\n| `kind` | `string \\| string[]` | Micromatch pattern(s) for dependency kind. |\n| `source` | `string \\| string[]` | Pattern(s) for the import/export source. |\n| `specifiers` | `string \\| string[]` | Pattern(s) for import/export specifiers. |\n| `nodeKind` | `string \\| string[]` | Pattern(s) for the AST node type. |\n| `relationship` | `object` | `from` and `to` relationship selectors (see [Matching Dependencies](#matching-dependencies)). |\n\n### Description Reference\n\nThis section provides a complete reference of all description types returned by `describe*` methods.\n\n#### Element Description\n\nReturned by `describeElement(filePath)`.\n\n| Property | Type | Description |\n|---|---|---|\n| `types` | `string[] \\| null` | Matched element types. Multiple unless `elementsSingleMatch` is enabled. |\n| `path` | `string \\| null` | Detected element boundary path. |\n| `captured` | `object \\| null` | Captured values from descriptor patterns. |\n| `parents` | `ElementParent[]` | Parent element chain (each has `types`, `path`, `category`, `captured`). |\n| `fileInternalPath` | `string \\| null` | File path relative to the element. |\n| `category` | `string \\| null` | _(Deprecated)_ Element category. Use file `categories`. |\n| `filePath` | `string \\| null` | _(Deprecated)_ Full file path. Use file description `path`. |\n| `isIgnored` | `boolean` | Whether excluded by `ignorePaths`/`includePaths`. |\n| `isUnknown` | `boolean` | Whether no descriptor matched. |\n\n#### File Description\n\nReturned by `describeFile(filePath)` or `describeEntity(filePath).file`.\n\n| Property | Type | Description |\n|---|---|---|\n| `path` | `string \\| null` | File path. |\n| `categories` | `string[] \\| null` | Matched file categories. |\n| `captured` | `object \\| null` | Captured values from file descriptor patterns. |\n| `isIgnored` | `boolean` | Whether excluded. |\n| `isUnknown` | `boolean` | Whether no file descriptor matched. |\n\n#### Module Description\n\nReturned by `describeModule(filePath?, source?)` or `describeEntity(filePath, source?).module`.\n\n| Property | Type | Description |\n|---|---|---|\n| `origin` | `\"local\" \\| \"external\" \\| \"core\"` | Module origin. |\n| `source` | `string \\| null` | Base module name for external/core. `null` for local. |\n| `internalPath` | `string \\| null` | Subpath within the module. `null` for local. |\n\n#### Entity Description\n\nReturned by `describeEntity(filePath, source?)`.\n\n| Property | Type | Description |\n|---|---|---|\n| `element` | `ElementDescription` | Element facet. |\n| `file` | `FileDescription` | File facet. |\n| `module` | `ModuleDescription` | Module facet. |\n\n#### Dependency Description\n\nReturned by `describeDependency(options)`.\n\n| Property | Type | Description |\n|---|---|---|\n| `from` | `EntityDescription` | Source entity. |\n| `to` | `EntityDescription` | Target entity. |\n| `dependency` | `DependencyInfoDescription` | Dependency metadata (`source`, `kind`, `nodeKind`, `specifiers`, `relationship`). |\n\n## Legacy Selectors\n\nLegacy selectors are defined using a different syntax and are provided for backward compatibility. However, this syntax is deprecated and will be removed in a future release. It is recommended to migrate to the new selector syntax.\n\nSelectors can be defined as either a string or an array of strings representing the element type(s):\n\n```ts\n// Legacy selector using a string\nconst isElementMatch = matcher.isElementMatch(\"src/components/Button.tsx\", \"component\");\n// Legacy selector using an array of strings\nconst isElementMatch = matcher.isElementMatch(\"src/components/Button.tsx\", [\"component\", \"service\"]);\n```\n\nThey can also be defined as an array where the first element is the type and the second element is an object containing captured values:\n\n```ts\n// Legacy selector with captured values\nconst isElementMatch = matcher.isElementMatch(\n  \"src/modules/auth/LoginForm.component.tsx\",\n  [\"component\", { foo: \"auth\" }]\n);\n```\n\n> **Warning:** Avoid mixing legacy selectors with the new selector syntax in the same project, as this can lead to ambiguity. In particular, if you define a top-level array selector with two elements and the second one is an object containing a `type` or `category` key, it will be interpreted as legacy options rather than two separate selectors.\n\n## Migration from v2\n\nThis section describes how to migrate from v2 to the latest version. The main changes are:\n\n### 1. Wrap descriptor array in `DescriptorsConfig`\n\nThe `getMatcher` method now accepts a `DescriptorsConfig` object instead of a flat array:\n\n```diff\n- const matcher = elements.getMatcher([\n-   { type: \"component\", pattern: \"src/components/*\" },\n- ]);\n+ const matcher = elements.getMatcher({\n+   elements: [\n+     { type: \"component\", pattern: \"src/components/*\" },\n+   ],\n+ });\n```\n\n### 2. Update element description access: `type` -> `types`\n\nElement descriptions now use `types` (array) instead of `type` (string):\n\n```diff\n  const desc = matcher.describeElement(\"src/components/Button.tsx\");\n- console.log(desc.type);        // \"component\"\n+ console.log(desc.types);       // [\"component\"]\n+ console.log(desc.types[0]);    // \"component\"\n```\n\n### 3. Update dependency description access: flat -> entity structure\n\nDependency descriptions now use `EntityDescription` objects for `from` and `to`:\n\n```diff\n  const dep = matcher.describeDependency({ from, to, source, kind });\n- console.log(dep.from.type);     // \"component\"\n- console.log(dep.to.origin);     // \"local\"\n+ console.log(dep.from.element.types[0]);  // \"component\"\n+ console.log(dep.to.module.origin);       // \"local\"\n```\n\n### 4. Move `origin`/`internalPath` to module selectors\n\nProperties that described module origin have moved from element selectors to module selectors (within entity selectors):\n\n```diff\n  // Element selector (old)\n- { type: \"component\", origin: \"local\" }\n  // Entity selector (new)\n+ { element: { type: \"component\" }, module: { origin: \"local\" } }\n```\n\n> [!NOTE]\n> For backward compatibility, the old flat selector format is still accepted and automatically converted. However, it is deprecated and will be removed in a future version.\n\n### 5. Replace `dependency.module` with `to.module.source`\n\nThe `module` property in dependency metadata selectors has been removed. Use `to.module.source` instead:\n\n```diff\n  // Old: matching by module name in dependency metadata\n- { to: { type: \"service\" }, dependency: { module: \"react\" } }\n  // New: matching by module source in entity selector\n+ { to: { module: { source: \"react\" } } }\n```\n\n### 6. Regenerate serialized cache\n\nThe serialized cache format has changed. If you persist cache between runs, you need to regenerate it. Old caches are not compatible with the new format.\n\n## Contributing\n\nContributors are welcome.\nPlease read the [contributing guidelines](../../.github/CONTRIBUTING.md) and [code of conduct](../../.github/CODE_OF_CONDUCT.md).\n\n## License\n\nMIT, see [LICENSE](./LICENSE) for details.\n\n[coveralls-image]: https://coveralls.io/repos/github/javierbrea/eslint-plugin-boundaries/badge.svg\n[coveralls-url]: https://coveralls.io/github/javierbrea/eslint-plugin-boundaries\n[build-image]: https://github.com/javierbrea/eslint-plugin-boundaries/actions/workflows/build.yml/badge.svg\n[build-url]: https://github.com/javierbrea/eslint-plugin-boundaries/actions?query=workflow%3Abuild+branch%3Amaster\n[last-commit-image]: https://img.shields.io/github/last-commit/javierbrea/eslint-plugin-boundaries.svg\n[last-commit-url]: https://github.com/javierbrea/eslint-plugin-boundaries/commits\n[license-image]: https://img.shields.io/npm/l/eslint-plugin-boundaries.svg\n[license-url]: https://github.com/javierbrea/eslint-plugin-boundaries/blob/master/LICENSE\n[npm-downloads-image]: https://img.shields.io/npm/dm/@boundaries/elements.svg\n[npm-downloads-url]: https://www.npmjs.com/package/@boundaries/elements\n[quality-gate-image]: https://sonarcloud.io/api/project_badges/measure?project=javierbrea_eslint-plugin-boundaries_elements&metric=alert_status\n[quality-gate-url]: https://sonarcloud.io/dashboard?id=javierbrea_eslint-plugin-boundaries_elements\n[release-image]: https://img.shields.io/github/release-date/javierbrea/eslint-plugin-boundaries.sv","readmeFilename":"README.md"}