{"_id":"@canonical/router-core","_rev":"24-b321fcd0831ffe30412bbd6aaa6f9645","name":"@canonical/router-core","dist-tags":{"latest":"0.43.0"},"versions":{"0.25.0":{"name":"@canonical/router-core","version":"0.25.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.25.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"mariadias143","email":"marianovadias@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"5c868ac66def375bec5daf1612166149de0a9f2b","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.25.0.tgz","fileCount":122,"integrity":"sha512-KnJtrlr3wPbbRX7Fa7OV1K+MOOW7vMbV2HDtyefKVBc9WkKtj3n0crF7FJh6KYTQJmZCzacGHHNLxAcVWzkZ8w==","signatures":[{"sig":"MEYCIQDWu7XU7jfbcf026peO6H2Avk1UZvSIrdz2ER7lhIuXjAIhALCN3j5WwVjQCOVhDf1n/c11XVabKA9MOSgQVGWY11tP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":187394},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"7f611c78991d7c9c99c183a92937200851cb053b","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"11.6.2","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.13.0","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.25.0","@canonical/webarchitect":"^0.25.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.25.0_1777069818766_0.30116068836545673","host":"s3://npm-registry-packages-npm-production"}},"0.26.0":{"name":"@canonical/router-core","version":"0.26.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.26.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"mariadias143","email":"marianovadias@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"29b5b0b4b0c2c5b568ed8ef17eb1c269398782d9","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.26.0.tgz","fileCount":123,"integrity":"sha512-uu6WLKzY2SwuTSJ4BX71hkfFb21MldStUZ/LARiZKyEF08rTZjBoOi5pybazIyM9Y1oYY8I8OEjjNsbdupNsGw==","signatures":[{"sig":"MEQCIB8rp/zDyw966S4VMbxZdkP7SBeWzDuYzpGrdgZKFSQeAiARLuB1ircC152Cjkp+Hy1oVSVu0fp4yeAFy/Bmq7aoqA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":195084},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"55fece1380dba8dcd3a88af443dd509d9aaaccb2","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"mariadias143","email":"marianovadias@gmail.com"},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.14.1+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.14.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.26.0","@canonical/webarchitect":"^0.26.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.26.0_1777070642565_0.8020821413917192","host":"s3://npm-registry-packages-npm-production"}},"0.27.0":{"name":"@canonical/router-core","version":"0.27.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.27.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"mariadias143","email":"marianovadias@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"d60362f165490dc4876d81ac61154f4ec17cc08a","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.27.0.tgz","fileCount":123,"integrity":"sha512-sO1xaCDFYcVzjxxcgIoHuRATh4JO1A/bDM71KFifaGFljApfUnjVBVzWawWZjk8082pM9W8MQGrNGPtPepSegA==","signatures":[{"sig":"MEUCIQCtEzhai2k+2TGZ4kzoJhXGoD71uV7fyVLgJbvOTRdhYwIgd4XHGFVMxL8QR7oc+faedJtKeGfOmxhWmeut/rOTeM4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":195764},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"5df5709bf7cb6f2016be2f6eba8391637e2e2a0c","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"mariadias143","email":"marianovadias@gmail.com"},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.14.1+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.14.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.27.0","@canonical/webarchitect":"^0.27.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.27.0_1777454199899_0.8267626629747791","host":"s3://npm-registry-packages-npm-production"}},"0.27.1-experimental.0":{"name":"@canonical/router-core","version":"0.27.1-experimental.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.27.1-experimental.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"mariadias143","email":"marianovadias@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"61c4cd73322a433b2bb2daf4db901c2aca2dcd3b","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.27.1-experimental.0.tgz","fileCount":123,"integrity":"sha512-/8hVoMcfvpbNgvQaQaUPDsr6ef6RGojVCh9LRXbYNtTLqY5TgFaWc+IqwTsUJWMijB/8OgvEzLr4+Y9OThqV3Q==","signatures":[{"sig":"MEUCICAbENZG+kTDPcP5ZPr+WD7jM2xSHD3fIQZ9XNqu0bwPAiEAuCQ7ij0EiCudVaYgNSmfK1M6MjKcTuXROyBfKIopNxE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.27.1-experimental.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":195858},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"d3f5b9aab7bec07fce40a12b45097d28d3cf0201","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.15.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.27.1-experimental.0","@canonical/webarchitect":"^0.27.1-experimental.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.27.1-experimental.0_1779386182565_0.9007476372925067","host":"s3://npm-registry-packages-npm-production"}},"0.28.0":{"name":"@canonical/router-core","version":"0.28.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.28.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"mariadias143","email":"marianovadias@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"93f5c915737f1aa1bad37f728255370ab110d24b","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.28.0.tgz","fileCount":131,"integrity":"sha512-Nof/InxKBpZn7Tgu4PGv3dtQCJgTjZbRomibB4YZrB975+70myNxjQFqA/pXmkBRhAGIlzXtLvQ/Kf68j18C1Q==","signatures":[{"sig":"MEQCIGkdQV1tnQg/ew4sKaKiT9bbGF791UsWYFBFEHFL+JuvAiBLvLej/lQGl5bB2omc22ehXUVtbM7fINowdOFC4OpMuA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.28.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":203342},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"8297d72122bcba903f7e8833cb23ccbaa164ed56","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.16.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.28.0","@canonical/webarchitect":"^0.28.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.28.0_1781617485854_0.722400688094853","host":"s3://npm-registry-packages-npm-production"}},"0.29.0-experimental.0":{"name":"@canonical/router-core","version":"0.29.0-experimental.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.29.0-experimental.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"mariadias143","email":"marianovadias@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"26ec7019896b96a156539b4717a760f293cf8a0c","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.29.0-experimental.0.tgz","fileCount":131,"integrity":"sha512-24zmG3XQBaA93I+0W0aiIpoRmZHVQa7Umm7Zg47JV4reVDbQCflwHz3RdpykrWMDozgGiOXCLDjcRlcM0VnufQ==","signatures":[{"sig":"MEUCIQCvwKgdax72aT3rbxULSKjH3r7fFsDaUyVNPEhKBvL8+AIgSF6QPOmGY5foKlCgVJL71RRTWpGZ4B0LZ8xz0PDk7mc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.29.0-experimental.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":203372},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"eda67fea634a79b9f77910d3106219efc9b30136","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.16.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.16.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.28.0","@canonical/webarchitect":"^0.29.0-experimental.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.29.0-experimental.0_1782338250228_0.8501007535407912","host":"s3://npm-registry-packages-npm-production"}},"0.29.0":{"name":"@canonical/router-core","version":"0.29.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.29.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"5d712e96dc8d9a2db68cc14e7ddcfc0a1b933d23","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.29.0.tgz","fileCount":131,"integrity":"sha512-Iln3g+UMPmi08kH6QpQFDMMch4EbbbRxvneL6l4vX76aHSIS4Lw0vQJ+Vc5pH58COUVex0FNI4NpY4dCinLdHA==","signatures":[{"sig":"MEUCIBWnbcs2kR5XHU27SJgZcA5ajVPefiMzimldZEFlEtlTAiEAsLA9uU0l5v/BDs+kJ4GQHfZKsJ/OgS985Unt8VEKA54=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.29.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":203342},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"535302c1e1e5dd8fa9bc2da4144de57ec4e63005","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.18.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.29.0","@canonical/webarchitect":"^0.29.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.29.0_1783071060483_0.05758844856118572","host":"s3://npm-registry-packages-npm-production"}},"0.30.0":{"name":"@canonical/router-core","version":"0.30.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.30.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"587661edbc2489d2a7c5157e8232b93c95ebdfdb","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.30.0.tgz","fileCount":135,"integrity":"sha512-BQqUgMtdc5CuxM7Y7hqShUgvL0th8RcxH/RPV46vk87UYC9PYbml5dQe/fF8SFUaUEsGbiODPKlxqAbewmxS6A==","signatures":[{"sig":"MEQCIFdq2OJw0qwOwot+FPULQuJrJwB486Ss/J2xxaAy0c0yAiB4g2VbrHFyiqyhmrBapvQA+c/Y2qwXVO1fbiI1E920ew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.30.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":223341},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"40fe86ac955473536ac14f074812a9821f5b65c0","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.18.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.30.0","@canonical/webarchitect":"^0.30.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.30.0_1783988106323_0.9600549150588398","host":"s3://npm-registry-packages-npm-production"}},"0.31.0":{"name":"@canonical/router-core","version":"0.31.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.31.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"70d07f25ddb1baa9e529a2188acbcdc33c0f6759","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.31.0.tgz","fileCount":135,"integrity":"sha512-6MmRAbDE6BC2ELq3/s2SRVnzQf/FZCykGBtwIZKza8GAtwDhp5tmVP8ugScjyaqvqEGwkCv2oTdsXcuA9Tp19Q==","signatures":[{"sig":"MEUCIQD+sIcKjYE6AvYzNfQnTzWAcIYYs51zt2Az6jpRyco8QgIgZIIglPQ39P1KD/3rk4M2+UI7kOZMdUhYMqBVKCNztgI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.31.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":223341},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"d4a67ebe42e62b8cf3de77f42f537309ca88d672","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.18.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.31.0","@canonical/webarchitect":"^0.31.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.31.0_1784323740868_0.005866215036685274","host":"s3://npm-registry-packages-npm-production"}},"0.32.0":{"name":"@canonical/router-core","version":"0.32.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.32.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"d597688270946fddbea317f29361bfa487f4fee4","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.32.0.tgz","fileCount":135,"integrity":"sha512-11zdDWNyz7HcIc/Az9urBtrRVyR+Mo7vtTMVB12S473tqfMb7r2YSoEIyXcxTFeM/f5d/CvXYvzsXg9El4pCUQ==","signatures":[{"sig":"MEQCIG4e7H7R+a2H1KuaoZM6X/8awrQCccrSdChZ3bU6/HKVAiAZFf6THsupeD3M0/NOWnVe3dt/pyRHPuV8GoO4cc/Mwg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.32.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":231628},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"5b279d8150e3988c68c6c2a741046bcd425624ca","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.18.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.32.0","@canonical/webarchitect":"^0.32.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.32.0_1784542935637_0.6514094107080495","host":"s3://npm-registry-packages-npm-production"}},"0.33.0":{"name":"@canonical/router-core","version":"0.33.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.33.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"bcc46f507c6c8618e30ac44414d929cb98982aa3","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.33.0.tgz","fileCount":135,"integrity":"sha512-amnm/aDOGKs3HZ490GeUovBl6s8ErLppClFYCM2qQjabUGLVLozc/x5SWvc5PEZXmYA0zQoPNnsn3gczRphs1A==","signatures":[{"sig":"MEQCICwaTxxQP2SexVGQzjEClR1gksRqdWNtejEE8UtSvhyoAiBh7o4DvO7rXH7l5rWA1aWz6y0N+RO16L68w0mQvekt2A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.33.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":231628},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"fca2bc4440fff2d511fc8db6686f9b19222fdbc7","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.18.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.33.0","@canonical/webarchitect":"^0.33.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.33.0_1784914670732_0.12519172785006139","host":"s3://npm-registry-packages-npm-production"}},"0.34.0":{"name":"@canonical/router-core","version":"0.34.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.34.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"93181a3801d194886343c1ce64044275e927221a","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.34.0.tgz","fileCount":135,"integrity":"sha512-JPiw8aos3Sj4FD3zhXaT3M88IhoMObY+mi126S47HMeYOGLoiTsaTVZwCVyKCkidVX4oU08eJeA6jwecS+5Dng==","signatures":[{"sig":"MEYCIQDZRNytvTARMHOAeSYj4XoZySR6ZGPnhLBsBHzD4JJkywIhAOJyoea14Nz7wZI2dSnUyK0z7zZWwqm4FzFAxIHxZSbh","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.34.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":231628},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"e8d25fecbe6e70edfc4cb300bad65f691dbbd26e","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.19.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^24.12.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.34.0","@canonical/webarchitect":"^0.34.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.34.0_1787317077527_0.7401918726082064","host":"s3://npm-registry-packages-npm-production"}},"0.35.0":{"name":"@canonical/router-core","version":"0.35.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.35.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"amylily1011","email":"amy.lily@canonical.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"65fe8497f46f87f54e5062b6b424cf5e4f1ccb7e","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.35.0.tgz","fileCount":119,"integrity":"sha512-vO2QJPUf/ENG3PDluRsVUs2OE7a5l8adon513wGvcwgDEtDcNm980d7kejATEL3xtGKVsYE6EfF8Rn5NFHe2Uw==","signatures":[{"sig":"MEYCIQCfhIR4dJ8E/l0xCagG+mK4aCFXmkeZigmZK9ddFa/1uwIhAJzB4wMh3hJVi1baBsXm8YO0NGEC6Brdtn2dSEkfythZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.35.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":244226},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"5198c5399ef657959272c0e35924391573d81146","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.19.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^26.0.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.35.0","@canonical/webarchitect":"^0.35.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.35.0_1787877250501_0.5901112289864978","host":"s3://npm-registry-packages-npm-production"}},"0.36.0":{"name":"@canonical/router-core","version":"0.36.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.36.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"3bd9a6b345978e3128cc215e227b13b5249e0baf","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.36.0.tgz","fileCount":119,"integrity":"sha512-zCmuiFJMeB6UoOjvOHoudz/1VDyKPe5IIuekD8D/EkprHdhATQFQY9Iskgfu+3UCjiJnyP3ejQ/TibkscjX3Cw==","signatures":[{"sig":"MEUCIQDPLTAaGtielD60Dv3z1AFk92GNyLp1ov60FTmgGR6baAIgPvejKaBQRQoV2kUcRRm1BePs66Vs7XXV7JuZBQtZKsk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.36.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":244226},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"78eb47ac10104e914eeacd331795e14b832703d4","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/9.0.7/node@v24.19.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^26.0.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.36.0","@canonical/webarchitect":"^0.36.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.36.0_1788012099906_0.889443837875596","host":"s3://npm-registry-packages-npm-production"}},"0.37.0":{"name":"@canonical/router-core","version":"0.37.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.37.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"abbiesims","email":"abbie.sims@canonical.com"},{"name":"ataku_b","email":"atakan99saglam@gmail.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ando.gq","email":"tom@ando.sh"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"71f1b262f0a5788650642e1c2d0fc1881562c7c9","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.37.0.tgz","fileCount":119,"integrity":"sha512-CWFC/V5TYzuHTMuJ/NzFw0czbLlGmbnOVfvM1TYzLqDKI+BYNAAVyLXr6qjy6TmPIYnx2QMC6CaGUV6KMThWzw==","signatures":[{"sig":"MEUCIFVdrAreLgJN0NivFvfPoMUAp4U+Ui5orxh3nSgVMD+MAiEArpSWejh6XDKT+ZWkmhkGcEaSeM7dFgWlnOX4pJ9G+jY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.37.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":258043},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"ac8383bdb4be1bcd6fa6c4960a1e3d78c0279688","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/10.0.1/node@v24.19.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.19.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^26.0.0","@biomejs/biome":"2.4.9","@canonical/biome-config":"^0.37.0","@canonical/webarchitect":"^0.37.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.37.0_1788345300624_0.9964180379399219","host":"s3://npm-registry-packages-npm-production"}},"0.38.0":{"name":"@canonical/router-core","version":"0.38.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.38.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"abbiesims","email":"abbie.sims@canonical.com"},{"name":"ataku_b","email":"atakan99saglam@gmail.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"e498882c4d0fa4d439983e88d8d353ad5ad49339","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.38.0.tgz","fileCount":119,"integrity":"sha512-zV2IhW/qayspcWInorxkkb0wWIQzEkNqGQitA/cHid2y2jXKR8whlr25NGNVWQ0pBjCGRPWsXqbkHLT5aP12RQ==","signatures":[{"sig":"MEQCIG3vACv0Gq5t9hkD868MhRju5vGZCrxqtL/fh/2B9utBAiBpZqJ+QKrfLEhsHg8HyqK2/cRc4Wh9P5HSiqM8XF5GNQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCTTQTkST0SU7rAS/ONqzTrCqZbBJrJc8aA58Ae217eQQIgeUKwl2XkZUj1y7dDNklje/y8W3DLPrycJS0zYyuWNs8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.38.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262065},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"4d10a68a9b299af6fe3d1d7d053e54ca128944ad","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/10.0.1/node@v24.20.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^26.0.0","@biomejs/biome":"2.5.13","@canonical/biome-config":"^0.38.0","@canonical/webarchitect":"^0.38.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.38.0_1789573076557_0.14921910672776306","host":"s3://npm-registry-packages-npm-production"}},"0.40.0":{"name":"@canonical/router-core","version":"0.40.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.40.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"abbiesims","email":"abbie.sims@canonical.com"},{"name":"ataku_b","email":"atakan99saglam@gmail.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"40f2293dae9f91b880243edc4be05d206720d3d0","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.40.0.tgz","fileCount":119,"integrity":"sha512-EWA+fdVywm0DZNQVqjbNjp7/K87wrMJRqDh5Bx3mLL35LmQrR7b7PNMPw5acZS3GjM5v6zZI+PGiWpVMkH7BWQ==","signatures":[{"sig":"MEYCIQC3exE6WYPMxEiixh9iopI4wdlWsT682mX43inmTe+jSgIhAJI6zUfqm9g+wdiaqaPqtfic3J64oU5CgBatygEdqwct","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCID0XhdiGcpi+hu7EpKCvOtnQkMB8tpzRg7gaIIWkA1AFAiEAggrmhy5AN6OHprTh2FAohCSKfFaRfyDqjOPdv05i/KY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.40.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262065},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"9136b71518260c5f33e7619da087198c931e4c13","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/10.0.1/node@v24.20.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^5.9.3","@types/node":"^26.0.0","@biomejs/biome":"2.5.13","@canonical/biome-config":"^0.40.0","@canonical/webarchitect":"^0.40.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.40.0_1789941848965_0.8327861087188078","host":"s3://npm-registry-packages-npm-production"}},"0.42.0":{"name":"@canonical/router-core","version":"0.42.0","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","_id":"@canonical/router-core@0.42.0","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"abbiesims","email":"abbie.sims@canonical.com"},{"name":"ataku_b","email":"atakan99saglam@gmail.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"homepage":"https://github.com/canonical/pragma#readme","bugs":{"url":"https://github.com/canonical/pragma/issues"},"dist":{"shasum":"1500e38fb470d75f19ca9a9ea1c90b5d1708cc4a","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.42.0.tgz","fileCount":119,"integrity":"sha512-biEQMAZXzgdMY2ihSW8K8xb89IUHUV9FOzt8KWqTRF/LwvMq8o/CL3GZNLzz2oeZYcKa8Lgpo1w8SGhBgw3RNw==","signatures":[{"sig":"MEQCIHc1RHaxuqA+vQnRyN+fuMUdgfKwsaumuvgWY26+iajtAiBVV3Yx+ssWrSISBRjGKPaNGGErZrZusyqOotY9wS3yYw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIDHhyjj/q2ASNqDykpqPUD1mHKgkDc3txULApglAZCrZAiEA+OYjIxu9p5tvx+UkIUtiaH7Oi7lqA5O+BzAIRGcmzTg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.42.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262197},"type":"module","types":"dist/types/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"75c2b17029ba899be3fa645be28290ac6fcb83a9","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:28870836-f57e-4400-9561-98bdb7dba710"}},"repository":{"url":"git+https://github.com/canonical/pragma.git","type":"git"},"_npmVersion":"lerna/10.0.1/node@v24.21.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"_nodeVersion":"24.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.18","typescript":"^7.0.2","@types/node":"^26.0.0","@biomejs/biome":"2.5.14","@canonical/biome-config":"^0.42.0","@canonical/webarchitect":"^0.42.0"},"_npmOperationalInternal":{"tmp":"tmp/router-core_0.42.0_1790560899117_0.15972780670057385","host":"s3://npm-registry-packages-npm-production"}},"0.43.0":{"_id":"@canonical/router-core@0.43.0","bugs":{"url":"https://github.com/canonical/pragma-web/issues"},"dist":{"shasum":"1c5301598f7b2d6f377302650d81c4899f239b71","tarball":"https://registry.npmjs.org/@canonical/router-core/-/router-core-0.43.0.tgz","fileCount":119,"integrity":"sha512-GsCxj38UiV+McmU2rl9ZNxw1rp76GkbPnWQv7Fc30paOVIdidfUDUYV9WgUU5Exual3AseDrnxG0dU30vgloYQ==","signatures":[{"sig":"MEQCIAphA4C2Y2tT2FMQ0nUJGE65ZwBd0dRyHGzl76U0G/u3AiAsYEvoQHo9RV4yvmv7DvQ3af2v/wSUCN8sO3TpqJjhIA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCv+z+b8a1CkmLMXetu9wt0IaJj2oraZjjGM6syRUyddwIhAM7iuvds2QnFR12johr3iGxuGBK1cCm6eB4/jTwDEnkQ"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@canonical%2frouter-core@0.43.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262252},"name":"@canonical/router-core","type":"module","types":"dist/types/index.d.ts","author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"module":"dist/esm/index.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"}},"gitHead":"581682464ef71de3f77dc2dc8bbe2b7e493bb05e","license":"LGPL-3.0","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","check":"bun run check:biome && bun run check:ts && bun run check:webarchitect","check:ts":"tsc --noEmit","build:all":"bun run build","check:fix":"bun run check:biome:fix && bun run check:ts","test:watch":"vitest","check:biome":"biome check","test:coverage":"vitest run --coverage","check:biome:fix":"biome check --write","check:webarchitect":"webarchitect library"},"version":"0.43.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"01798362-4c6a-40ad-a763-e801186a896d"}},"homepage":"https://github.com/canonical/pragma-web#readme","repository":{"url":"git+https://github.com/canonical/pragma-web.git","type":"git"},"_npmVersion":"lerna/10.0.1/node@v24.21.0+x64 (linux)","description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","directories":{},"maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"abbiesims","email":"abbie.sims@canonical.com"},{"name":"ataku_b","email":"atakan99saglam@gmail.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"_nodeVersion":"24.21.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^5.0.0","typescript":"^7.0.2","@types/node":"^26.0.0","@biomejs/biome":"2.5.14","@canonical/biome-config":"0.43.0","@canonical/webarchitect":"0.43.0","@canonical/typescript-config":"0.43.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/router-core_0.43.0_1790801964493_0.6445258595878671"}}},"time":{"created":"2026-04-24T22:30:18.682Z","modified":"2026-09-30T20:59:25.176Z","0.25.0":"2026-04-24T22:30:18.911Z","0.26.0":"2026-04-24T22:44:02.710Z","0.27.0":"2026-04-29T09:16:40.023Z","0.27.1-experimental.0":"2026-05-21T17:56:22.722Z","0.28.0":"2026-06-16T13:44:45.975Z","0.29.0-experimental.0":"2026-06-24T21:57:30.430Z","0.29.0":"2026-07-03T09:31:00.617Z","0.30.0":"2026-07-14T00:15:06.466Z","0.31.0":"2026-07-17T21:29:01.081Z","0.32.0":"2026-07-20T10:22:15.791Z","0.33.0":"2026-07-24T17:37:50.893Z","0.34.0":"2026-08-21T12:57:57.685Z","0.35.0":"2026-08-28T00:34:10.664Z","0.36.0":"2026-08-29T14:01:40.082Z","0.37.0":"2026-09-02T10:35:00.760Z","0.38.0":"2026-09-16T15:37:56.658Z","0.40.0":"2026-09-20T22:04:09.083Z","0.42.0":"2026-09-28T02:01:39.209Z","0.43.0":"2026-09-30T20:59:24.620Z"},"bugs":{"url":"https://github.com/canonical/pragma-web/issues"},"author":{"name":"Canonical Webteam","email":"webteam@canonical.com"},"license":"LGPL-3.0","homepage":"https://github.com/canonical/pragma-web#readme","repository":{"url":"git+https://github.com/canonical/pragma-web.git","type":"git"},"description":"Framework-agnostic router core built on flat route triplets and wrapper annotations","maintainers":[{"name":"ilayda21","email":"ilayda.cavusoglupars@canonical.com"},{"name":"frankban","email":"frankban@gmail.com"},{"name":"huwshimi","email":"huw@ikmail.com"},{"name":"anthonydillon","email":"me@anthonydillon.com"},{"name":"steverydz","email":"steverydz@gmail.com"},{"name":"bartaz","email":"bartek.szopka@canonical.com"},{"name":"jpmartinspt","email":"joao.figueiredo.martins@canonical.com"},{"name":"petesfrench","email":"peterfrench94@gmail.com"},{"name":"jmuzina","email":"jmuzina@pm.me"},{"name":"mtruj","email":"mariapaula.trujillo@canonical.com"},{"name":"edlerd","email":"david.edler@canonical.com"},{"name":"abehnia","email":"ardavan.behnia@canonical.com"},{"name":"canonical-organization","email":"is-admin@canonical.com"},{"name":"edisile-canonical","email":"eduard.manta@canonical.com"},{"name":"steciuk-canonical","email":"adam.steciuk@canonical.com"},{"name":"abbiesims","email":"abbie.sims@canonical.com"},{"name":"ataku_b","email":"atakan99saglam@gmail.com"},{"name":"ad.vl","email":"adrian.villa.g@gmail.com"},{"name":"engr-ali","email":"its.muhammad.ali.mughal@gmail.com"},{"name":"ninfa_jeon","email":"urvashi.sharma271099@gmail.com"},{"name":"ndv99","email":"n.devilliers1999@gmail.com"},{"name":"goulin-canonical","email":"goulin.khoge@canonical.com"},{"name":"immortalcodes","email":"21112002mj@gmail.com"},{"name":"alvaromateo","email":"alvaro.mateoalvarez@canonical.com"},{"name":"onibenjo-canonical","email":"benjaminaderopo.oni@canonical.com"}],"readme":"# @canonical/router-core\n\nFramework-agnostic routing primitives for Canonical apps. `@canonical/router-core` gives you flat route definitions, wrapper composition, typed navigation helpers, SSR dehydration, middleware hooks, and accessibility orchestration without locking you into a specific view layer.\n\n> **Stability: pre-1.0 / experimental.** The API is still consolidating and breaking changes may land between minor versions. Every breaking change ships with a conventional-commit subject and a CHANGELOG entry — those are the migration record. Pin a minor version if you need stability today.\n\n## Installation\n\n```bash\nbun add @canonical/router-core\n```\n\n## Quick start\n\n### 1. Define routes\n\n```tsx\nimport { route } from \"@canonical/router-core\";\n\nconst routes = {\n  home: route({\n    url: \"/\",\n    content: () => \"Home\",\n  }),\n  account: route({\n    url: \"/account/:team\",\n    content: ({ params }) => `Account: ${params.team}`,\n  }),\n} as const;\n```\n\n### 2. Create a router with an adapter\n\nThe adapter is the one construction axis — it decides where the location lives (browser URL, hash fragment, memory, a fixed server URL):\n\n```ts\nimport { createBrowserAdapter, createRouter } from \"@canonical/router-core\";\n\nconst router = createRouter(routes, { adapter: createBrowserAdapter() });\n```\n\nA router created **without** an adapter is a pure matcher: `match()`, `buildPath()`, and `load()` work, while `navigate()` and `setSearchParams()` throw — there is no location for them to change.\n\n### 3. Use typed helpers\n\n```ts\nrouter.buildPath(\"account\", { params: { team: \"web\" } });\n// \"/account/web\"\n\nrouter.navigate(\"home\");\nawait router.warm(\"account\", { params: { team: \"web\" } });\n```\n\n### 4. Render through your framework binding\n\nThe core package intentionally stops at route matching, state, dehydration, and accessibility orchestration. For React rendering, pair it with `@canonical/router-react`.\n\n## Mental model\n\n- **Routes are flat.** Every route is declared with `route()`.\n- **Wrappers are annotations.** Reuse layout with `wrapper()` and `group()`.\n- **Middleware is route-to-route transformation.** Use it to add auth, i18n, metrics, or shared wrapper policy. Middleware runs once, before the router is created.\n- **The adapter is the construction axis.** `createRouter(routes, { adapter })` is the only constructor; pick `createBrowserAdapter()`, `createHashAdapter()`, `createMemoryAdapter()`, `createServerAdapter()`, or bring your own `PlatformAdapter`.\n- **`warm()` is fire-and-forget.** It warms caches, preloads assets, or runs side effects at navigation time. It does not provide data to `content()` — components own their data via their cache library.\n- **Errors are state, not exceptions.** Every load commits a `status` onto the location (404 for no match, 400 for a rejected query string, the status of a thrown `StatusResponse`, 500 otherwise). Nothing is thrown at the view layer.\n- **URL params are validated by schemas.** Give a route a `params` or `search` [Standard Schema](https://standardschema.dev) validator (Zod, Valibot, ArkType, or hand-rolled) and the validated, typed output flows to `content()`, `warm()`, and the typed navigation helpers.\n- **SSR is built in.** `dehydrate()` preserves navigation state across the server/client boundary.\n\n## Design rationale\n\nThese are deliberate positions, not gaps. If the router feels smaller than others you have used, that is the design.\n\n### The router does not own data\n\n`warm()` is the only data-adjacent hook and it is fire-and-forget on purpose. It never blocks rendering and never passes data to `content()`. The supported pattern is **cache population**: the hook warms the cache your components already read from — `fetchQuery` into a Relay store, `queryClient.prefetchQuery` for TanStack Query — and the component's own hook finds the data already there.\n\nHanding loader data to components as props (the loader model other routers use) is rejected as an antipattern here:\n\n- it couples data lifetime to route lifetime — leaving the route drops data the cache could have kept;\n- it blocks navigation on the slowest fetch instead of letting the page stream in;\n- on a cache-aware app it double-fetches: the loader fetches, then the component's cache hook fetches again or needs bridging glue.\n\nOne consequence to know: because the hook never blocks, a redirect or status thrown from an **async** `warm()` is applied *late* — the destination may render briefly before the redirect lands (applied with replace semantics, so Back does not return to it). That flash is the honest price of never blocking render.\n\n### Errors are state, not exceptions\n\nHTTP-shaped failures are facts about the location, so they live on the location: `getState().location.status`. The router owns data errors (no match → 404, rejected query → 400, thrown `StatusResponse`/`Response` → its status, anything else → 500) and commits them as state; the view layer owns render errors with its native mechanism (an error boundary, in React). Nothing the router does throws into your component tree. See the two-channel guide in [`@canonical/router-react`'s README](../../react/router/README.md#error-handling).\n\n### Minimal API, low sugar\n\nOne orthogonal way per capability. There are no preset router factories — the adapter is the whole axis, so `createRouter(routes, { adapter })` is the entire construction story. Blocking is one method (`router.block()`) returning one handle. Convenience layers must earn their place; the surface we stabilize at 1.0 should be the smallest one that composes.\n\n## Progressive disclosure\n\n### Basic route\n\n```tsx\nimport { route } from \"@canonical/router-core\";\n\nconst settingsRoute = route({\n  url: \"/settings\",\n  content: () => \"Settings\",\n});\n```\n\n### Route with warm\n\n`warm()` is a fire-and-forget navigation-time hook. Use it to warm a cache, preload assets, fire analytics, or run permission checks. It does not return data to the component.\n\n```tsx\nconst userRoute = route({\n  url: \"/users/:id\",\n  warm: async ({ id }, _search, { signal }) => {\n    await queryClient.prefetchQuery({\n      queryKey: [\"user\", id],\n      queryFn: () => fetchUser(id),\n      signal,\n    });\n  },\n  content: ({ params }) => `User: ${params.id}`,\n});\n```\n\nThrowing from `warm()` is meaningful control flow: `redirect(to, status)` redirects, `throw new StatusResponse(404)` sets the location status. Both work from sync and async hooks — an async throw is applied late (after the route rendered) and only while the navigation is still current; any other async rejection is deliberately ignored, because a failed cache warm must never break navigation.\n\n### Schema validation for URL params\n\nRoutes accept [Standard Schema](https://standardschema.dev) validators for both kinds of URL parameters. Any spec-compliant library schema (Zod ≥3.24, Valibot, ArkType) can be passed directly; raw values always arrive as strings, so use coercion.\n\n**Path params** — the `params` field validates and coerces `:param` segments. A rejected URL is a **non-match**: matching falls through to the next route and ultimately the not-found route (404), exactly like a pattern mismatch.\n\n```tsx\nimport { createBrowserAdapter, createRouter, route } from \"@canonical/router-core\";\nimport { z } from \"zod\";\n\nconst productRoute = route({\n  url: \"/products/:id\",\n  params: z.object({ id: z.coerce.number().int().positive() }),\n  // \"/products/abc\" → 404; \"/products/42\" → params.id === 42 (a number)\n  content: ({ params }) => `Product #${params.id}`,\n});\n\nconst router = createRouter(\n  { product: productRoute },\n  { adapter: createBrowserAdapter() },\n);\n\nrouter.buildPath(\"product\", { params: { id: 42 } }); // \"/products/42\" — fully typed\n```\n\n**Search params** — the `search` field validates the query string. A rejected query throws `StatusResponse(400, { issues, message })`, which `load()` commits as a 400 **error result on the location** — a real 400 under SSR, `location.status === 400` on the client. It does not reach an error boundary. Prefer normalizing schemas that supply defaults over rejecting ones — a shared URL with a stale query should not error the page:\n\n```tsx\nconst listRoute = route({\n  url: \"/products\",\n  search: z.object({\n    page: z.coerce.number().int().min(1).catch(1),\n    sort: z.enum([\"price\", \"name\"]).catch(\"name\"),\n  }),\n  content: ({ search }) => `page ${search.page}, sorted by ${search.sort}`,\n});\n```\n\nNo dependency? Hand-roll the Standard Schema v1 shape (`{ \"~standard\": { version: 1, vendor, validate } }`, annotated with `StandardSchemaV1<In, Out>` for inference). See the [Router API reference](../../../docs/references/ROUTER_API.md#schema-validation).\n\nValidation runs at match time and is **synchronous** — async validators (e.g. Zod async refinements) throw with an explanatory error. For semantic checks (does the record exist?) use `warm` + `StatusResponse`.\n\n### Wrapper composition\n\n```tsx\nimport { group, route, wrapper } from \"@canonical/router-core\";\n\nconst appShell = wrapper({\n  id: \"app:shell\",\n  component: ({ children }) => `<main>${String(children)}</main>`,\n});\n\nconst [dashboardRoute, reportsRoute] = group(appShell, [\n  route({ url: \"/dashboard\", content: () => \"Dashboard\" }),\n  route({ url: \"/reports\", content: () => \"Reports\" }),\n] as const);\n```\n\n### Error signalling\n\nUse `StatusResponse` to give a failure an HTTP status. Thrown from `warm()`, it becomes the location's status — read it as state (`getState().location.status`, or `useRoute().status` in React), never from an error boundary:\n\n```tsx\nimport { route, StatusResponse } from \"@canonical/router-core\";\n\nconst adminRoute = route({\n  url: \"/admin\",\n  warm: () => {\n    if (!isAuthenticated()) {\n      throw new StatusResponse(401);\n    }\n  },\n  content: () => \"Admin panel\",\n});\n```\n\nThe `data` argument is optional; pass one to carry a typed payload (`new StatusResponse(503, { retryAfter: \"5m\" })`).\n\n### Redirects\n\nRuntime redirects — thrown from `warm()`, sync or async:\n\n```ts\nimport { redirect, route } from \"@canonical/router-core\";\n\nconst privateRoute = route({\n  url: \"/private\",\n  warm: () => {\n    if (!isAuthenticated()) {\n      redirect(\"/login\", 302);\n    }\n  },\n  content: () => \"private\",\n});\n```\n\nStatic redirect routes — declared entirely in the route map, no content; they answer with 301 or 308 (the permanent family; `redirect()` covers the temporary one):\n\n```ts\nconst legacyHome = route({\n  url: \"/home\",\n  redirect: \"/\",\n  status: 301,\n});\n```\n\n## Search param mutation\n\n`setSearchParams()` patches the current URL's search params without requiring the route name (adapter required — it changes the location):\n\n```ts\n// Merge into current search params\nrouter.setSearchParams({ page: \"2\" });\n\n// Functional update\nrouter.setSearchParams((current) => ({\n  ...current,\n  page: String(Number(current.page ?? \"0\") + 1),\n}));\n\n// Remove a param (set to null)\nrouter.setSearchParams({ filter: null });\n\n// Replace history entry instead of pushing\nrouter.setSearchParams({ page: \"2\" }, { replace: true });\n```\n\n`setSearchParams()` is how a page restates its own view — a filter, a grouping, a sort, a tab — so that the address can be copied and reopened on that view. It is not a navigation: the store commits the new location, subscribers are notified, and the adapter records the address (pushed, or replacing the current entry with `replace: true`), but there is no view transition, no scroll restoration, no focus move and no route announcement. The reader stays on the control they were using. A `getTitle` option still runs, so the document title follows the address.\n\nEverything else that changes the address stays a navigation, including one that differs only in its search: `navigate()` to the same page with other search params, the browser's back and forward, and a redirect reached from a search update (which the reader did not ask for) all run the full [accessibility](#accessibility) effects. Only the caller knows that an address is the same page restated, so the distinction is made by the method called, not inferred from the address — `/?user=ana` and `/?user=bob` may well be two different pages.\n\n## Navigation blocking\n\n`router.block(isActive)` registers a blocker and returns a handle. While `isActive()` returns true, `navigate()` is intercepted and held until the handle decides it:\n\n```ts\nconst blocker = router.block(() => formHasUnsavedChanges);\n\n// When a navigation is attempted while the blocker is active:\nblocker.state; // \"blocked\"\n\nblocker.subscribe((state) => {\n  // \"blocked\" → show your confirmation UI; \"idle\" → hide it\n});\n\nblocker.proceed(); // continue the blocked navigation\nblocker.cancel(); // stay on the current page\n\n// Remove the blocker; a navigation blocked on it is discarded, not resumed\nblocker.dispose();\n```\n\nBlockers intercept `router.navigate()` only — `setSearchParams()` and adapter-driven back/forward are not intercepted. For React, use `useBlocker()` from `@canonical/router-react`.\n\n## Middleware\n\nMiddleware is a route-to-route transformation (`<TRoute extends AnyRoute>(route: TRoute) => TRoute`), applied once before the router exists. Pass it through `RouterOptions.middleware` — the first entry in the array is the outermost transformation (applied last):\n\n```ts\nimport {\n  type AnyRoute,\n  createBrowserAdapter,\n  createRouter,\n  route,\n} from \"@canonical/router-core\";\n\nfunction withBasePath(basePath: string) {\n  return <TRoute extends AnyRoute>(currentRoute: TRoute): TRoute => {\n    return {\n      ...currentRoute,\n      url: `${basePath}${currentRoute.url}`,\n    } as TRoute;\n  };\n}\n\nconst routes = {\n  home: route({ url: \"/\", content: () => \"Home\" }),\n} as const;\n\nconst router = createRouter(routes, {\n  adapter: createBrowserAdapter(),\n  middleware: [withBasePath(\"/app\")],\n});\n```\n\nThe standalone `applyMiddleware(routes, middleware)` export is the lower-level array primitive (`readonly AnyRoute[]` in, same out) the option is built on; reach for it only when transforming route arrays outside a router.\n\nSee the [middleware cookbook](../../../docs/how-to-guides/ROUTER_MIDDLEWARE_COOKBOOK.md) for auth, i18n, and instrumentation patterns.\n\n## Platform adapters\n\nThe adapter decides where the location lives; everything else about the router is identical across them:\n\n- `createBrowserAdapter()` — auto-detects the best API: uses the Navigation API (`window.navigation`) when available, falls back to the History API (`pushState` / `popstate`) for older browsers.\n- `createNavigationAdapter()` — explicitly use the Navigation API. Baseline Newly Available since January 2026. Navigations the router makes are intercepted with `scroll: \"manual\"` and `focusReset: \"manual\"`, so the router's own scroll and focus management applies, as it does under the History API; navigations the browser starts (back/forward, reload) keep the browser's handling.\n- `createHistoryAdapter()` — explicitly use the History API.\n- `createHashAdapter()` — store the route in `window.location.hash`; useful where the path is fixed (Storybook, static file hosts).\n- `createMemoryAdapter(initialUrl?, options?)` — in-memory adapter for testing.\n- `createServerAdapter(url)` — a fixed URL for server-side rendering; its `navigate()` throws.\n\n```ts\nimport { createMemoryAdapter, createRouter } from \"@canonical/router-core\";\n\nconst testRouter = createRouter(routes, {\n  adapter: createMemoryAdapter(\"/users/42\"),\n});\n```\n\n### Externally owned location\n\nBy default `createMemoryAdapter()` owns its location: it keeps an internal entries array and index that `navigate`, `back`, and `forward` mutate. Some hosts already own navigation state and need the router as a pure resolver rather than a second state owner — an application store that decides what is shown, a replay harness driving location from a recorded sequence, a state machine where \"where we are\" is derived state. For those, pass a `history` delegate and the adapter keeps no entries array and no index of its own:\n\n```ts\nconst adapter = createMemoryAdapter(\"/\", {\n  history: {\n    getLocation: () => store.currentUrl, // the single source of the current location\n    onNavigate: (url, options) => store.go(url, options), // every navigate forwards here\n    subscribe: (listener) => store.subscribe(listener), // host announces location changes\n    onBack: () => store.back(), // optional — omit and back() becomes a no-op\n    onForward: () => store.forward(), // optional — omit and forward() becomes a no-op\n  },\n});\n```\n\nWith a delegate, `getLocation` reads the delegate, `navigate(to, options)` forwards to `onNavigate` and mutates nothing locally, and the adapter's `subscribe` is the seam through which the host announces changes. `back` and `forward` forward to the optional `onBack`/`onForward` hooks; when the host omits them they are no-ops, because a host that owns location owns its own history model. The `initialUrl` argument is ignored when a delegate is present. The entire route-resolution surface — matching, params, group wrappers — is unchanged.\n\nHost values are normalized at the boundary: `getLocation` reads and subscription notifications both hand consumers a fresh `URL`, so a host mutating its own URL object cannot reach router internals, and a delegate may return bare path strings. An error thrown by `onNavigate` propagates to the `navigate` caller.\n\n**The host must notify synchronously.** When the router navigates, it suppresses the echo of its own navigation through a guard that only holds for a notification fired synchronously within `onNavigate`. A host that batches change notifications (microtask, animation frame, or later) will miss the guard and every router-initiated navigation will resolve twice. If your store batches, notify the adapter's listener directly and synchronously inside `onNavigate`.\n\n## SSR and hydration\n\nOn the server, create the router with a server adapter, match the URL for the response status, and hydrate the store synchronously so rendering works without awaiting `load()`:\n\n```ts\nimport { createRouter, createServerAdapter } from \"@canonical/router-core\";\n\nconst router = createRouter(routes, {\n  adapter: createServerAdapter(url),\n  notFound: notFoundRoute,\n});\nconst serverMatch = router.match(url);\n\nif (serverMatch?.kind === \"redirect\") {\n  // Answer with a real HTTP redirect before rendering anything.\n  return respondRedirect(serverMatch.status, serverMatch.redirectTo);\n}\n\nif (serverMatch?.kind === \"route\" || serverMatch?.kind === \"not-found\") {\n  router.hydrate({\n    href: url,\n    kind: serverMatch.kind,\n    routeId: serverMatch.kind === \"route\" ? serverMatch.name : null,\n    status: serverMatch.status, // 200, or 404 for the matched not-found route\n  });\n}\n```\n\nThe router dehydrates navigation state only (`router.dehydrate()` → `{ href, kind, routeId, status }`). Data dehydration is the cache library's responsibility. On the client, pass the serialized state back as `hydratedState`:\n\n```ts\nimport { createBrowserAdapter, createRouter } from \"@canonical/router-core\";\n\nconst clientRouter = createRouter(routes, {\n  adapter: createBrowserAdapter(),\n  hydratedState: serializedState ?? undefined,\n});\n```\n\nFor the full React flow — `renderToStream`, `readDehydratedState`, and the `__INITIAL_DATA__` contract — see [packages/react/router/README.md](../../react/router/README.md) and the reference app in [apps/react/boilerplate-vite](../../../apps/react/boilerplate-vite).\n\n## Accessibility\n\nThe router auto-wires browser-side accessibility orchestration:\n\n- `ScrollManager` — saves/restores scroll positions across navigations\n- `FocusManager` — moves focus to `<h1>` on route change\n- `RouteAnnouncer` — announces route changes to screen readers\n- `ViewTransitionManager` — wraps navigations in View Transitions when available\n\nThey run for navigations — `navigate()`, back/forward, and redirects — and not for the initial load or a [`setSearchParams()`](#search-param-mutation) update. Override or disable them through `RouterOptions.accessibility`.\n\n## Public API\n\n### Functions and classes\n\n- `applyMiddleware()`\n- `createBrowserAdapter()`\n- `createHashAdapter()`\n- `createHistoryAdapter()`\n- `createMemoryAdapter()`\n- `createNavigationAdapter()`\n- `createRouter()`\n- `createRouterStore()`\n- `createServerAdapter()`\n- `createSubject()`\n- `createTrackedLocation()`\n- `group()`\n- `redirect()`\n- `route()`\n- `wrapper()`\n- `FocusManager`\n- `RouteAnnouncer`\n- `ScrollManager`\n- `ViewTransitionManager`\n- `Redirect`\n- `StatusResponse`\n\nAll supporting types (`Router`, `RouterOptions`, `RouterBlockerHandle`, `PlatformAdapter`, `MemoryAdapterOptions`, `StandardSchemaV1`, …) are exported from the package root.\n\n### Reference docs\n\n- API reference: [docs/references/ROUTER_API.md](../../../docs/references/ROUTER_API.md)\n- Migration guide: [docs/how-to-guides/MIGRATE_TO_PRAGMA_ROUTER.md](../../../docs/how-to-guides/MIGRATE_TO_PRAGMA_ROUTER.md)\n- Middleware cookbook: [docs/how-to-guides/ROUTER_MIDDLEWARE_COOKBOOK.md](../../../docs/how-to-guides/ROUTER_MIDDLEWARE_COOKBOOK.md)\n","readmeFilename":"README.md"}