{"versions":{"1.0.0":{"name":"@boundaries/elements","version":"1.0.0","description":"Descriptor to define elements for @boundaries ecosystem","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8","object-hash":"3.0.0"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.0"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@1.0.0","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-b+fcPUEjIyofcEe39ZaeaoeCb2/a6kyi3ztRSS/ayc4Izs54vY4m5GUn8x9N24wWVPy0e6V4La9e+eZCPjCEMQ==","_resolved":"/tmp/deb0e013a625f6254254dee8fe766833/boundaries-elements-1.0.0.tgz","_from":"file:boundaries-elements-1.0.0.tgz","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-b+fcPUEjIyofcEe39ZaeaoeCb2/a6kyi3ztRSS/ayc4Izs54vY4m5GUn8x9N24wWVPy0e6V4La9e+eZCPjCEMQ==","shasum":"a074a4225a138145c2a74d89b73ee6b75662123d","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-1.0.0.tgz","fileCount":15,"unpackedSize":1301501,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEYX58THGPTgW8JspS0c53eiMUp8AZOJZPlKNOyv152XAiBR9IZS70I57Lg10OyunIeth5hEoqBc3+RvLbOwrIiGhg=="}],"size":213826},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_1.0.0_1762769447906_0.21886264180900827"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-11-10T10:10:48.152Z","publish_time":1762769448152,"_source_registry_name":"default","contributors":[]},"1.1.0":{"name":"@boundaries/elements","version":"1.1.0","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.0"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@1.1.0","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-/NvzEUzYdONn4D5O7lGX7AHDNXa/H0KPyckDe/Br3Bb0fKuXzEpoJv2VgOt4lj8OFGCf+Vc8tdlG26CMrCxubQ==","_resolved":"/tmp/46d97c6c4213789025b235d9ad1729c7/boundaries-elements-1.1.0.tgz","_from":"file:boundaries-elements-1.1.0.tgz","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-/NvzEUzYdONn4D5O7lGX7AHDNXa/H0KPyckDe/Br3Bb0fKuXzEpoJv2VgOt4lj8OFGCf+Vc8tdlG26CMrCxubQ==","shasum":"505cbf2153a407fa2d518cdec83d18d1804bed6a","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-1.1.0.tgz","fileCount":15,"unpackedSize":1401178,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCSnwRwu2/P7Q4TFSJFuWhniugggA/+WqGsIhzOgcDaMAIhAIR8iRDkoovrJsohMqpPiJ4ZZJ3FDgDddI0MU8IAA2Ro"}],"size":236695},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_1.1.0_1763203501053_0.1558515430483809"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-11-15T10:45:01.331Z","publish_time":1763203501331,"_source_registry_name":"default","contributors":[]},"1.1.1":{"name":"@boundaries/elements","version":"1.1.1","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.0"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@1.1.1","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-PdfbevdcQbJ1oIXSN0H8rRcWdNsnSWpMtoh+/afSovWavAiuazbnDD9iwAfDcDiJu0g3Xbhisl5epBmTrnaRyQ==","_resolved":"/tmp/205514d50ba8969426f55d652c804d91/boundaries-elements-1.1.1.tgz","_from":"file:boundaries-elements-1.1.1.tgz","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-PdfbevdcQbJ1oIXSN0H8rRcWdNsnSWpMtoh+/afSovWavAiuazbnDD9iwAfDcDiJu0g3Xbhisl5epBmTrnaRyQ==","shasum":"98ce33328784c3715297e4a8abcfd1cdb5dfbb0f","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-1.1.1.tgz","fileCount":15,"unpackedSize":1403608,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIC+SgRd2Nw+jPMx9mfg8yHj2cGhn7NkusFvVwbBz/0kjAiEAxRPC9dM3q/Dg7iRDwEaPphEEOK3Ev/m0uf/GgCrRUJM="}],"size":237338},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_1.1.1_1763893333304_0.3625353749536844"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-11-23T10:22:13.525Z","publish_time":1763893333525,"_source_registry_name":"default","contributors":[]},"1.1.2":{"name":"@boundaries/elements","version":"1.1.2","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.0"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@1.1.2","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-DnGHL+v36YVMoWhWZqyJYVZ9dapNm7h4N3/P0lDPirJj0CHVPkjChMCCotj74cg6LW7iPJZFGrdEfh0X0g2bmQ==","_resolved":"/tmp/d6e13ba158cea84bccc32e0743cefe1c/boundaries-elements-1.1.2.tgz","_from":"file:boundaries-elements-1.1.2.tgz","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-DnGHL+v36YVMoWhWZqyJYVZ9dapNm7h4N3/P0lDPirJj0CHVPkjChMCCotj74cg6LW7iPJZFGrdEfh0X0g2bmQ==","shasum":"d441438633f9562563b3bf9c48fb928ef9acb143","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-1.1.2.tgz","fileCount":15,"unpackedSize":1403756,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBuXnDWAD92tyWMcjOaFhkD/59VGG1AkGgKd5ZY8r+JoAiEAs5/148ecmHHrcvPQfYnlRoTKIhMzD2Eo5kiz7Wpkmsc="}],"size":237482},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_1.1.2_1765011729605_0.11386818955276201"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2025-12-06T09:02:09.836Z","publish_time":1765011729836,"_source_registry_name":"default","contributors":[]},"1.2.0":{"name":"@boundaries/elements","version":"1.2.0","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.9","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.0"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"pnpm check:types:code && pnpm check:types:test","check:types:code":"tsc --noEmit","check:types:test":"tsc --noEmit --project ./test/tsconfig.json","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@1.2.0","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-W65Gum02liMd3hmNrLmDBX1u5BmRMcunouFjLXyhxHnNY4YlK1kTxsgfflZ5XBGSnPnO0MkiUzAcoGzYrlx0RQ==","_resolved":"/tmp/4aa44d714a4decea30fe2cc12a3d3ce7/boundaries-elements-1.2.0.tgz","_from":"file:boundaries-elements-1.2.0.tgz","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-W65Gum02liMd3hmNrLmDBX1u5BmRMcunouFjLXyhxHnNY4YlK1kTxsgfflZ5XBGSnPnO0MkiUzAcoGzYrlx0RQ==","shasum":"ed5f0038829849686dae98cf23ef811b9a3415ed","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-1.2.0.tgz","fileCount":15,"unpackedSize":1473169,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDQjk37EqZMeA89Aqj6SzhE9XNq2N+aLNBCCC/18oEKrQIhANiDsxpgQu/F0ad3NP3Y6EaYkaY9vXty7MurLAtFdA95"}],"size":251085},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_1.2.0_1770096581840_0.19645478552833806"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-02-03T05:29:42.031Z","publish_time":1770096582031,"_source_registry_name":"default","contributors":[]},"2.0.0-beta.1":{"name":"@boundaries/elements","version":"2.0.0-beta.1","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.1"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@2.0.0-beta.1","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-bpCLN8EMZdtJHwYuxNXg+s5AqI+VCd4qTkFHZm0E6uEmAj1Eb4eJJrNx1Tdie6S05o27JL9N5EBvcpiN4UTLiQ==","_resolved":"/tmp/6a0066eea254deab9427a350404c1ada/boundaries-elements-2.0.0-beta.1.tgz","_from":"file:boundaries-elements-2.0.0-beta.1.tgz","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-bpCLN8EMZdtJHwYuxNXg+s5AqI+VCd4qTkFHZm0E6uEmAj1Eb4eJJrNx1Tdie6S05o27JL9N5EBvcpiN4UTLiQ==","shasum":"685c873f1a039f7962ea3b158c4567b6571f2f8f","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-2.0.0-beta.1.tgz","fileCount":15,"unpackedSize":1440239,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBqNFeFV57yg8ITXRJIG2UnmOr/uEZi159wlpFp17wfoAiEAiB3mXyhttCSBrCD2osCHE+SwpUI6cYKjqm9sId0VKac="}],"size":249842},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_2.0.0-beta.1_1773485728953_0.2820021310844236"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-03-14T10:55:29.122Z","publish_time":1773485729122,"_source_registry_name":"default","contributors":[]},"2.0.0-beta.2":{"name":"@boundaries/elements","version":"2.0.0-beta.2","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.1"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@2.0.0-beta.2","readmeFilename":"README.md","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-0dyyEkoPxQTiraP9wRGBwKiCyQuUhXIaxbESsUWUTsggaet3Hl/VtIvr1Km75b01alTlarYiqQ1pAzjOyDwr/w==","_resolved":"/tmp/6dc31bf46c3b2d0cd9a12c2e503188d6/boundaries-elements-2.0.0-beta.2.tgz","_from":"file:boundaries-elements-2.0.0-beta.2.tgz","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-0dyyEkoPxQTiraP9wRGBwKiCyQuUhXIaxbESsUWUTsggaet3Hl/VtIvr1Km75b01alTlarYiqQ1pAzjOyDwr/w==","shasum":"51223c63e418b8c0050879a3a89088279671b101","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-2.0.0-beta.2.tgz","fileCount":15,"unpackedSize":1441635,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDfbgn4VH7lLjZMxz6H1K7ytX6yLMeLuBGQcVQH4+jCgwIgVhBDqg9ty9YL9Cw2ZHjDn93T13eYJNqc4c694fOHOe4="}],"size":250220},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_2.0.0-beta.2_1773568369888_0.3450376204618417"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-03-15T09:52:50.090Z","publish_time":1773568370090,"_source_registry_name":"default","contributors":[]},"2.0.0":{"name":"@boundaries/elements","version":"2.0.0","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.8","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.1"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@2.0.0","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-2TM/rhXvbAeEE2/pZ/Dw+l3LzzaSuo9n3DJjw+StvwHnrzyjBYrXcD5Lw7tBI+wuNHy57JJfgRRKTDwb0PFZSw==","_resolved":"/tmp/19b09023a01b0587a0409373c48aba63/boundaries-elements-2.0.0.tgz","_from":"file:boundaries-elements-2.0.0.tgz","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-2TM/rhXvbAeEE2/pZ/Dw+l3LzzaSuo9n3DJjw+StvwHnrzyjBYrXcD5Lw7tBI+wuNHy57JJfgRRKTDwb0PFZSw==","shasum":"51501f91f3b1d56cdfa71c0863a4f43ca4ed884b","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-2.0.0.tgz","fileCount":15,"unpackedSize":1441628,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDlMi81sV/S8p6RxXWeXYPO1mNi7tM+7EBpJQbm1z7BHwIgDwVJHnF1rclAYFz2AxZp1ppjxGeXPmasLyb7yueH1hA="}],"size":250214},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_2.0.0_1773600314797_0.10286719291707525"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-03-15T18:45:15.082Z","publish_time":1773600315082,"_source_registry_name":"default","contributors":[]},"2.0.1":{"name":"@boundaries/elements","version":"2.0.1","description":"Element descriptors and matchers for @boundaries tools","keywords":["boundaries","elements","hierarchy"],"author":{"name":"Javier Brea"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/javierbrea/eslint-plugin-boundaries.git","folder":"packages/elements"},"publishConfig":{"access":"public"},"types":"dist/index.d.ts","module":"./dist/index.mjs","main":"dist/index.js","exports":{".":{"browser":{"types":"./dist/index.browser.d.ts","import":"./dist/index.browser.mjs","require":"./dist/index.browser.js"},"node":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"default":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"./package.json":"./package.json"},"dependencies":{"eslint-import-resolver-node":"0.3.9","eslint-module-utils":"2.12.1","handlebars":"4.7.9","is-core-module":"2.16.1","micromatch":"4.0.8"},"engines":{"node":">=18.18"},"devDependencies":{"@types/estree":"1.0.8","@types/is-core-module":"2.2.2","@types/micromatch":"4.0.10","@types/object-hash":"3.0.6","path-browserify":"1.0.1","tsup":"8.5.1"},"scripts":{"eslint":"eslint","build":"tsup --config tsup.config.js","check:all":"echo 'All checks passed'","check:spell":"cspell --quiet .","check:types":"tsc --noEmit","lint":"eslint .","lint:fix":"eslint . --fix","serve:mutation:report":"serve --config ./serve.test-mutation-report.json","serve:unit:report":"serve --config ./serve.test-unit-report.json","test:unit":"jest","test:mutation":"stryker run"},"_id":"@boundaries/elements@2.0.1","bugs":{"url":"https://github.com/javierbrea/eslint-plugin-boundaries/issues"},"homepage":"https://github.com/javierbrea/eslint-plugin-boundaries#readme","_integrity":"sha512-sAWO3D8PFP6pBXdxxW93SQi/KQqqhE2AAHo3AgWfdtJXwO6bfK6/wUN81XnOZk0qRC6vHzUEKhjwVD9dtDWvxg==","_resolved":"/tmp/67e54df06039dd0c38cbfa1debc94ce7/boundaries-elements-2.0.1.tgz","_from":"file:boundaries-elements-2.0.1.tgz","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-sAWO3D8PFP6pBXdxxW93SQi/KQqqhE2AAHo3AgWfdtJXwO6bfK6/wUN81XnOZk0qRC6vHzUEKhjwVD9dtDWvxg==","shasum":"46de6a95eb61e5226201d3b71975c8ce3c5b98a8","tarball":"http://123.232.10.234:8212/nexus/content/groups/npm-public/@boundaries/elements/-/elements-2.0.1.tgz","fileCount":15,"unpackedSize":1441628,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCK7bSidNkx/jJZWFwTSxG0j/FLzKBJrmIhnS3xOKQuzwIhAJW4QzuNqxbC4dtL/VX0xNGJsE90eFzTAQyqQEHrWmq9"}],"size":250211},"_npmUser":{"name":"anonymous","email":"javier.brea@gmail.com"},"directories":{},"maintainers":[{"name":"anonymous","email":"javier.brea@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements_2.0.1_1774879918392_0.44544829313032297"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2026-03-30T14:11:58.544Z","publish_time":1774879918544,"_source_registry_name":"default","contributors":[]}},"dist-tags":{"beta":"2.0.0-beta.2","latest":"2.0.1"},"name":"@boundaries/elements","time":{"created":"2025-11-10T10:10:59.436Z","modified":"2026-03-30T14:12:09.707Z","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"},"readme":"[![Build status][build-image]][build-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Quality Gate][quality-gate-image]][quality-gate-url]\n\n[![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[![NPM downloads][npm-downloads-image]][npm-downloads-url] [![License][license-image]][license-url]\n\n[![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# @boundaries/elements\n\n> Element 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- [Usage](#usage)\n  - [Configuration Options](#configuration-options)\n  - [Creating a matcher](#creating-a-matcher)\n  - [Element Descriptors](#element-descriptors)\n  - [Descriptions API](#descriptions-api)\n    - [Element Description](#element-description)\n    - [Dependency Description](#dependency-description)\n  - [Selectors](#selectors)\n    - [Element Selectors](#element-selectors)\n    - [Dependency Selectors](#dependency-selectors)\n    - [Template Variables](#template-variables)\n  - [Using Matchers](#using-matchers)\n    - [Element Matching](#element-matching)\n    - [Dependency Matching](#dependency-matching)\n  - [Flagging Dependencies as External](#flagging-dependencies-as-external)\n- [API Reference](#api-reference)\n- [Legacy Selectors](#legacy-selectors)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Introduction\n\n`@boundaries/elements` provides a powerful and flexible system for defining and enforcing architectural boundaries in your JavaScript and TypeScript projects. It allows you to:\n\n- **Define element types** based on file path patterns (e.g., components, services, helpers)\n- **Match elements** against specific criteria\n- **Validate dependencies** between different parts of your codebase\n- **Enforce architectural rules** by checking if dependencies between elements are allowed\n\nThis package is part of the [@boundaries ecosystem](https://github.com/javierbrea/eslint-plugin-boundaries) and uses [Micromatch patterns](https://github.com/micromatch/micromatch) for flexible and powerful pattern matching.\n\n>[!NOTE]\n> This package does not read or analyze your codebase directly. It provides the core logic for defining and matching elements and dependencies, which can be integrated into other tools such as linters or build systems.\n\n## Features\n\n- ✨ **Flexible pattern matching** using Micromatch syntax\n- 🎯 **Element type and category identification** based on file paths\n- 📝 **Template variables** for dynamic selector matching\n- ⚡ **Built-in caching** for optimal performance\n- 🔄 **Support for multiple file matching modes** (file, folder, full path)\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\nHere's a quick example to get you started:\n\n```typescript\nimport { Elements } from '@boundaries/elements';\n\n// Create an Elements instance\nconst elements = new Elements();\n\n// Define element descriptors\nconst matcher = elements.getMatcher([\n  {\n    type: \"component\",\n    category: \"react\",\n    pattern: \"src/components/*.tsx\",\n    mode: \"file\",\n    capture: [\"fileName\"],\n  },\n  {\n    type: \"service\",\n    category: \"data\",\n    pattern: \"src/services/*.ts\",\n    mode: \"file\",\n    capture: [\"fileName\"],\n  },\n]);\n\n// Match an element\nconst isComponent = matcher.isElementMatch(\"src/components/Button.tsx\", { \n  type: \"component\" \n}); // true\n\n// Match a dependency\nconst isValidDependency = matcher.isDependencyMatch(\n  {\n    from: \"src/components/Button.tsx\",\n    to: \"src/services/Api.ts\",\n    source: \"../services/Api\",\n    kind: \"value\",\n    nodeKind: \"ImportDeclaration\",\n  },\n  {\n    from: { category: \"react\" },\n    to: { type: \"service\" },\n    dependency: { nodeKind: \"ImportDeclaration\" },\n  }\n); // true\n```\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 element 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> - In **`file` and `folder` modes**, 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> - In **`full` mode**, 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 element descriptors:\n\n```typescript\nconst matcher = elements.getMatcher([\n  {\n    type: \"component\",\n    pattern: \"src/components/*\",\n    mode: \"folder\",\n  },\n  {\n    type: \"helper\",\n    pattern: \"src/helpers/*.js\",\n    mode: \"file\",\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  [/* descriptors */],\n  {\n    ignorePaths: [\"**/*.test.ts\"],\n  }\n);\n```\n\n### Element Descriptors\n\nElement descriptors define how files are identified and categorized. 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`): Additional categorization for the element, providing another layer of classification\n- **`mode`** (`\"file\" | \"folder\" | \"full\"`): 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- **`basePattern`** (`string`): Additional pattern that must match from the project root. Use it when using `file` or `folder` modes and you want to capture fragments from the rest of the path.\n- **`capture`** (`string[]`): Array of keys to capture path fragments\n- **`baseCapture`** (`string[]`): Array of keys to capture fragments from `basePattern`. If the same key is defined in both `capture` and `baseCapture`, the value from `capture` takes precedence.\n\n### Descriptions API\n\nThe matcher can also return normalized runtime descriptions. These descriptions are the canonical API used by `@boundaries/eslint-plugin` and are useful for debugging, reporting, and custom tooling.\n\n> [!IMPORTANT]\n> This section describes the **output API** of `describeElement` / `describeDependency`, which is different from the **input API** used by `isDependencyMatch`.\n\n#### Element Description\n\n`matcher.describeElement(filePath)` returns an object with normalized element metadata.\n\nCommon fields:\n\n- `path`: Absolute or relative file path used in the matcher call\n- `type`: Matched element type, or `null` if unknown\n- `category`: Matched element category, or `null`\n- `captured`: Captured values map from descriptor patterns, or `null`\n- `elementPath`: Path representing the detected element boundary, or `null`\n- `internalPath`: Path of the file relative to `elementPath`, or `null`\n- `origin`: One of `\"local\" | \"external\" | \"core\"`\n- `isIgnored`: Whether the file was excluded by `ignorePaths` / `includePaths`\n- `isUnknown`: Whether no descriptor matched\n\nAdditional fields for local known elements:\n\n- `parents`: Parent element chain, or `null`\n\n#### Dependency Description\n\n`matcher.describeDependency(options)` returns:\n\n```ts\n{\n  from: ElementDescription,\n  to: ElementDescription,\n  dependency: {\n    source: string,\n    module: string | null,\n    kind: \"value\" | \"type\" | \"typeof\",\n    nodeKind: string | null,\n    specifiers: string[] | null,\n    relationship: {\n      from: \"internal\" | \"child\" | \"descendant\" | \"sibling\" | \"parent\" | \"uncle\" | \"nephew\" | \"ancestor\" | null,\n      to: \"internal\" | \"child\" | \"descendant\" | \"sibling\" | \"parent\" | \"uncle\" | \"nephew\" | \"ancestor\" | null,\n    }\n  }\n}\n```\n\nNotes:\n\n- `dependency.source` is the raw import/export source string from code.\n- `dependency.module` is the normalized module base for external/core dependencies.\n- `dependency.relationship.to` describes how `to` relates to `from`.\n- `dependency.relationship.from` is the inverse perspective.\n- For unknown/ignored scenarios, some values can be `null`.\n\nExample:\n\n```ts\nconst description = matcher.describeDependency({\n  from: \"src/components/Button.tsx\",\n  to: \"src/services/Api.ts\",\n  source: \"../services/Api\",\n  kind: \"value\",\n  nodeKind: \"ImportDeclaration\",\n  specifiers: [\"ApiClient\"],\n});\n\nconsole.log(description.dependency.source); // \"../services/Api\"\nconsole.log(description.dependency.kind); // \"value\"\nconsole.log(description.dependency.relationship); // { from: ..., to: ... }\n```\n\n### Selectors\n\nSelectors are used to match elements and dependencies against specific criteria. They are objects where each property represents a matching condition.\n\n#### Element Selectors\n\nWhen matching elements, you can use element selectors that specify conditions on the element's properties.\n\nElement selectors support the following properties:\n\n- **`type`** (`string | string[]`): Micromatch pattern(s) for the element type/s\n- **`category`** (`string | string[]`): Micromatch pattern(s) for the element category/categories\n- **`captured`** (`object | object[]`): Captured values selector. When provided as an object, all keys must match (AND logic). When provided as an array of objects, the element matches if any of the objects matches all keys (OR logic). Each key in the objects can be a string or an array of strings representing micromatch patterns.\n- **`parent`** (`object` | `null`): Selector for the first parent in the element description (`parents[0]`). Supported properties are:\n  - **`type`** (`string | string[]`): Micromatch pattern(s) for parent type\n  - **`category`** (`string | string[]`): Micromatch pattern(s) for parent category\n  - **`elementPath`** (`string | string[]`): Micromatch pattern(s) for parent element path\n  - **`captured`** (`object | object[]`): Parent captured values selector. Uses the same semantics as `captured` in the root selector (object = AND, array = OR)\n- **`origin`** (`\"local\" | \"external\" | \"core\"`): Element origin\n  - `local`: Files within the project\n  - `external`: External dependencies (e.g., `node_modules`)\n  - `core`: Core modules (e.g., Node.js built-ins)\n- **`path`** (`string | string[]`): Micromatch pattern(s) for the file path\n- **`elementPath`** (`string | string[]`): Pattern(s) for the element path\n- **`internalPath`** (`string | string[]`): Pattern(s) for the path within the element. For file elements, it's the same as `elementPath`; for folder elements, it's relative to the folder.\n- **`isIgnored`** (`boolean`): Whether the element is ignored\n- **`isUnknown`** (`boolean`): Whether the element type is unknown (i.e., doesn't match any descriptor)\n\n\n> [!NOTE]\n> All properties in the selector are optional. You can also use `null` values in selector to match only elements with `null` values in the corresponding properties. In the case of `parent`, setting it to `null` will match elements that have no parents (i.e., top-level elements). If `parent` is an object, it will only match elements that have at least one parent, and the first parent (`parents[0]`) matches the specified conditions.\n\n#### Dependency Selectors\n\nWhen matching dependencies, you can use dependency selectors that specify conditions on the source and target elements, as well as the dependency metadata.\n\n- **`from`** (`element selector | element selector[]`): [Selector(s)](#element-selectors) for the source element\n- **`to`** (`element selector | element selector[]`): [Selector(s)](#element-selectors) for the target element\n- **`dependency`** (`object | object[]`): Selector(s) for dependency metadata. When an array is provided, the dependency metadata matches if any selector in the array matches (OR logic). Supported selector properties:\n  - **`kind`** (`string | string[]`): Micromatch pattern(s) for the dependency kind\n  - **`relationship`** (`object`): Relationship selectors from both perspectives:\n    - **`from`** (`string | string[]`): Relationship from the perspective of `from`\n    - **`to`** (`string | string[]`): Relationship from the perspective of `to`\n      - `internal`: Both files belong to the same element\n      - `child`: Target is a child of source\n      - `parent`: Target is a parent of source\n      - `sibling`: Elements share the same parent\n      - `uncle`: Target is a sibling of a source ancestor\n      - `nephew`: Target is a child of a source sibling\n      - `descendant`: Target is a descendant of source\n      - `ancestor`: Target is an ancestor of source\n  - **`specifiers`** (`string | string[]`): Pattern(s) for import/export specifiers (e.g., named imports)\n  - **`nodeKind`** (`string | string[]`): Pattern(s) for the AST node type causing the dependency (e.g., `\"ImportDeclaration\"`)\n  - **`source`** (`string | string[]`): Pattern(s) to match the source of the dependency (e.g., the import path)\n  - **`module`** (`string | string[]`): Pattern(s) for the base module name for external or core dependencies.\n\n> **⚠️ Important:** All properties in a selector must match for the selector to be considered a match (AND logic). Use multiple selectors for OR logic.\n\n> **Note:** You can also use the legacy selector syntax, but it’s deprecated and will be removed in a future release. See the [Legacy Selectors section](#legacy-selectors) for more details.\n\n#### Template Variables\n\nSelectors support template variables using [Handlebars syntax](https://handlebarsjs.com/) (`{{ variableName }}`). Templates are resolved at match time using:\n\n- **Element properties** (`type`, `category`, `captured`, etc.)\n- **Dependency properties** (`from`, `to`, `dependency`)\n\n#### Available Template Data\n\nWhen matching, the following data is automatically available:\n\n**For element matching:**\n- Properties of the element under match are available in the `element` object (type, category, captured, origin, path, etc.)\n\n**For dependency matching:**\n- `from`: Properties of the dependency source element\n- `to`: Properties of the dependency target element\n- `dependency`: Dependency metadata (`kind`, `nodeKind`, `specifiers`, `source`, `module`, `relationship`, etc.)\n\n#### Template Examples\n\n```ts\n// Using captured values in templates\nconst matcher = elements.getMatcher([\n  {\n    type: \"component\",\n    pattern: \"src/modules/(*)/**/*.component.tsx\",\n    capture: [\"module\", \"elementName\", \"fileName\"],\n    mode: \"file\"\n  }\n]);\n\n// Match components from specific module using template\nconst isAuthComponent = matcher.isElementMatch(\n  \"src/modules/auth/LoginForm.component.tsx\",\n  { \n    type: \"component\",\n    captured: { module: \"{{ element.captured.module }}\" } // This will always match\n  },\n);\n\n// Using captured array for OR logic\nconst isAuthOrUserComponent = matcher.isElementMatch(\n  \"src/modules/auth/LoginForm.component.tsx\",\n  { \n    type: \"component\",\n    captured: [\n      { module: \"auth\" },      // Matches if module is \"auth\"\n      { module: \"user\", fileName: \"UserProfile\" }       // OR if module is \"user\" and fileName is \"UserProfile\"\n    ]\n  },\n);\n\n// Using templates in dependency selectors\nconst isDependencyMatch = matcher.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: { type: \"{{ from.type }}\", captured: { fileName: \"{{ from.captured.fileName }}\" } },\n    to: { path: \"{{ to.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\n// Using templates in selectors\nconst isMatch = matcher.isElementMatch(\n  \"src/components/UserProfile.tsx\",\n  { type: \"{{ componentType }}\" },\n  {\n    extraTemplateData: { componentType: \"component\" }\n  }\n);\n```\n\n### Using Matchers\n\nYou can use element selectors with a created matcher to check if a given path corresponds to an element with specific properties, or if a dependency between two paths matches certain criteria.\n\n#### Element Matching\n\nTo match an element, use the `isElementMatch` method of the matcher, providing the file path and an element selector.\n\n```ts\nconst isElementMatch = matcher.isElementMatch(\"src/components/Button.tsx\", { type: \"component\" });\n```\n\n> [!TIP]\n> You can also provide an array of selectors to the `isElementMatch` method. In this case, the method will return `true` if the element matches any of the provided selectors (OR logic).\n\n#### Dependency Matching\n\nTo match a dependency, use the `isDependencyMatch` method of the matcher, providing the properties of the dependency and a dependency selector.\n\n**Dependency object properties:**\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`**: Element selector(s) for the source file\n- **`to`**: Element selector(s) for the target file\n- **`dependency`**: Dependency metadata selector(s)\n\n```ts\nconst isDependencyMatch = matcher.isDependencyMatch(\n  { // Dependency properties\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    from: { category: \"react\" }, // Dependency source selector/s\n    to: { type: \"service\" }, // Dependency target selector/s\n    dependency: [\n      { nodeKind: \"Import*\" },\n      { source: \"@services/*\" },\n    ], // Dependency metadata selector/s (OR logic)\n  }\n);\n```\n\n> [!TIP]\n> You can also provide an array of selectors to `from`, `to` and `dependency`. The matcher will return `true` when all provided selector groups match.\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([/* descriptors */]);\n  \n  // describeDependency({ from, to, source, kind }):\n  // to: null, source: 'unresolved-module' -> origin: 'external'\n  // to: '/project/src/Button.ts', source: './Button' -> 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([/* descriptors */]);\n  \n  // describeDependency({ from, to, source, kind }):\n  // to: '/project/node_modules/react/index.js', source: 'react' -> origin: 'external'\n  // to: '/project/src/utils.ts', source: './utils' -> 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([/* descriptors */]);\n  \n  // describeDependency({ from, to, source, kind }):\n  // to: '/monorepo/packages/shared/index.ts', source: '@myorg/shared' -> origin: 'external'\n  // to: '/monorepo/packages/app/src/utils/helper.ts', source: './utils/helper' -> 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([/* descriptors */]);\n  \n  // describeDependency({ from, to, source, kind }):\n  // source: '@myorg/shared' -> origin: 'external' (matches '@myorg/*')\n  // source: '~/utils/helper' -> origin: 'external' (matches '~/**')\n  // source: '@other/package' -> 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 in `full` mode (because `file` and `folder` modes match progressively from the right, so they may be 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  { type: 'component', pattern: 'src/**/*.ts', mode: 'full' }, // Relative to /project/packages/app\n]);\n\n// ✅ Correct: 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.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// ❌ Incorrect: Using relative file paths (won't detect outsideRootPath correctly)\nconst dep2 = matcher.describeDependency({\n  from: 'src/index.ts',                            // relative file path\n  to: '../shared/index.ts',                        // relative file path\n  source: '@myorg/shared',\n  kind: 'value',\n});\n// Result: Won't correctly detect if outside rootPath\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#### Methods\n\n##### `getMatcher`\n\nCreates a new matcher instance.\n\n- __Parameters__:\n  - `descriptors`: `array<ElementDescriptor>` Array of [element descriptors](#element-descriptors) to be used by the matcher.\n  - `options`: `ElementsOptions` Optional. [Configuration options](#configuration-options) for the matcher. These options will override the default options set in the `Elements` instance.\n- __Returns__: `Matcher` A new matcher instance.\n\n```ts\nconst matcher = elements.getMatcher([\n  {\n    type: \"component\",\n    pattern: \"src/components/*\",\n    mode: \"folder\",\n  },\n  {\n    type: \"helper\",\n    pattern: \"src/helpers/*.js\",\n    mode: \"file\",\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`\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#### `isElementMatch`\n\nChecks if a given path matches an element selector.\n\n```ts\nconst isElementMatch = matcher.isElementMatch(\"src/components/Button.tsx\", [{ type: \"component\" }]);\n```\n\n#### `isDependencyMatch`\n\nChecks if dependency properties match a dependency selector.\n\n```ts\nconst isDependencyMatch = matcher.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  },\n  {\n    from: [{ category: \"react\" }],\n    to: { type: \"service\" },\n    dependency: { nodeKind: \"Import*\" },\n  }\n);\n```\n\n#### `getElementSelectorMatching`\n\nReturns the first matching element selector or `null`.\n\n```ts\nconst matchingSelector = matcher.getElementSelectorMatching(\"src/components/Button.tsx\", [{ type: \"component\" }]);\n```\n\n#### `getDependencySelectorMatching`\n\nReturns the dependency selector matching result (`from`, `to`, `dependency`, `isMatch`).\n\n> [!NOTE]\n> This method provides detailed information about which part of the selector matched or didn't match. When arrays of selectors are provided in the `from`, `to` or `dependency` properties, the method will return the first selector that matches on each side, so the returned `from`, `to` and `dependency` will be the matching selector from each group.\n\n```ts\nconst matchingSelector = matcher.getDependencySelectorMatching(\n  {\n    from: \"src/components/Button.tsx\",\n    to: \"src/services/Api.ts\",\n    source: \"../services/Api\",\n    kind: \"type\",\n  },\n  {\n    to: { type: \"service\" },\n    dependency: { kind: \"type\" },\n  }\n);\n```\n\n#### `describeElement`\n\nReturns a detailed description of an element.\n\n```ts\nconst elementDescription = matcher.describeElement(\"src/components/Button.tsx\");\n```\n\n- __Parameters__:\n  - `path`: `string` The path of the element to describe.\n- __Returns__: [Element Description](#element-description).\n\n#### `describeDependency`\n\nReturns a detailed description of a dependency.\n\n```ts\nconst dependencyDescription = 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- __Parameters__:\n  - `dependency`: The [properties of the dependency to describe](#dependency-matching).\n- __Returns__: [Dependency Description](#dependency-description).\n\n#### `getElementSelectorMatchingDescription`\n\nMatches an element description against element selectors. As first argument, it should receive the result of `describeElement`.\n\nAs second argument, it should receive an array of element selectors. The method will return the first selector that matches the description or `null` if no selector matches.\n\n```ts\nconst elementDescription = matcher.describeElement(\"src/components/Button.tsx\");\nconst matchingSelector = matcher.getElementSelectorMatchingDescription(elementDescription, [{ type: \"component\" }]);\n```\n\n#### `getDependencySelectorMatchingDescription`\n\nMatches a dependency description against dependency selectors. As first argument, it should receive the result of `describeDependency`.\n\nAs second argument, it should receive an array of dependency selectors. The method will return the first selector that matches the description or `null` if no selector matches.\n\n> [!NOTE]\n> This method provides detailed information about which part of the selector matched or didn't match. When arrays of selectors are provided in the `from`, `to` or `dependency` properties in a dependency selector, the method will return the first selector that matches on each side, so the returned `from`, `to` and `dependency` will be the matching selector from each group.\n\n```ts\nconst dependencyDescription = 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});\nconst matchingSelector = matcher.getDependencySelectorMatchingDescription(dependencyDescription, [{ to: { type: \"service\" }, dependency: { kind: \"type\" } }]);\n```\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\n// Serialize cache to a serializable object\nconst cache = matcher.serializeCache();\n\n// Clear current cache\nmatcher.clearCache();\n\n// Restore cache from serialized object\nmatcher.setCacheFromSerialized(cache);\n```\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## 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/workflows/build/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.svg\n[release-url]: https://github.com/javierbrea/eslint-plugin-boundaries/releases","users":{}}