{"id":17956992,"url":"https://github.com/pateketrueke/abstract-nested-router","last_synced_at":"2025-04-03T17:26:01.273Z","repository":{"id":40556777,"uuid":"188479835","full_name":"pateketrueke/abstract-nested-router","owner":"pateketrueke","description":"Minimal nested-routing impl!","archived":false,"fork":false,"pushed_at":"2022-06-26T17:49:28.000Z","size":800,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-09T06:14:14.106Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pateketrueke.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-24T19:54:05.000Z","updated_at":"2022-06-25T01:08:50.000Z","dependencies_parsed_at":"2022-06-27T17:20:56.895Z","dependency_job_id":null,"html_url":"https://github.com/pateketrueke/abstract-nested-router","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pateketrueke%2Fabstract-nested-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pateketrueke%2Fabstract-nested-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pateketrueke%2Fabstract-nested-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pateketrueke%2Fabstract-nested-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pateketrueke","download_url":"https://codeload.github.com/pateketrueke/abstract-nested-router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247044830,"owners_count":20874384,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-29T10:49:37.394Z","updated_at":"2025-04-03T17:26:01.251Z","avatar_url":"https://github.com/pateketrueke.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Abstract Nested Router\n\n\u003e It _tries_ to capture all matching routes from its **root**.\n\u003e\n\u003e [![Build status](https://github.com/pateketrueke/abstract-nested-router/actions/workflows/ci.yml/badge.svg)](https://github.com/pateketrueke/abstract-nested-router/actions/workflows/ci.yml)\n\u003e [![NPM version](https://badge.fury.io/js/abstract-nested-router.svg)](http://badge.fury.io/js/abstract-nested-router)\n\u003e [![Coverage Status](https://codecov.io/github/pateketrueke/abstract-nested-router/coverage.svg?branch=master)](https://codecov.io/github/pateketrueke/abstract-nested-router)\n\u003e [![Known Vulnerabilities](https://snyk.io/test/npm/abstract-nested-router/badge.svg)](https://snyk.io/test/npm/abstract-nested-router)\n\n```js\nimport Router from 'abstract-nested-router';\n\nconst r = new Router();\n\nr.add('/', { key: 'Home' });\nr.mount('/', () =\u003e {\n  r.add('/foo', { key: 'JustFoo' });\n  r.mount('/foo', () =\u003e {\n    r.add('/static', { key: 'StaticOne' });\n    r.mount('/nested', () =\u003e {\n      r.add('/', { key: 'NestedRoot' });\n      r.add('/:value', { key: 'NestedValue' });\n    });\n    r.add('/:bar', { key: 'AndNested' });\n  });\n  r.add('/baz', { key: 'Baz' });\n  r.add('/buzz', { key: 'Buzz' });\n  r.mount('/buzz', () =\u003e {\n    r.add('#test', { key: 'Anchor' });\n    r.add('#:quux', { key: 'Hashed' });\n  });\n  r.add('/*any', { key: 'Fallback' });\n});\n```\n\n## API\n\nAvailable methods:\n\n- `resolve(path, cb)` \u0026mdash; Progressively finds and invoke callback with `(err, routes)` as input, useful for third-party integrations, e.g. [yrv](https://www.npmjs.com/package/yrv)\n- `mount(path, cb)` \u0026mdash; Allow to register routes under the same route\n- `find(path[, retries])` \u0026mdash; Look up routes by path, in case of failure try passing `retries` as true\n- `add(path[, routeInfo])` \u0026mdash; Register a single route by path, additional info will be returned on match\n- `rm(path)` \u0026mdash; Remove a single route by full-path, it will fail if given route is not registered!\n\nOptions:\n\nWhile `routeInfo` can include anything, but special keys are considered:\n\n- `key` \u0026mdash; Unique identity for any route handler\n- `exact` \u0026mdash; Tell if routing should match exactly or not\n- `fallback` \u0026mdash; Tell if the route should be used as last resort\n\n### Params\n\nBy default all segments are optional, e.g. `/a/:b/:c` matches with `/a`, `/a/x` and `/a/x/y` so you can say `:b` and `:c` are optional parameters.\n\nMore advanced cases would require fragments to be optional, e.g. `/:foo(-bar)` matches with `/x` and `/x-bar` because `-bar` is an optional fragment.\n\nIn the latter case `params.foo` will always be `x` regardless if `-bar` is appended, if you want to match `bar` then use `/:foo(-:suffix)` instead.\n\n\u003e _Splat_ parameters will consume the rest of the segments/fragments if they're present, e.g. `/x*y` captures anything that begins with `x` and stores it on `params.y` so it matches `/xy`, `/xabc`, `/x/y`, `/x/a/b/c` and so on.\n\nEvery parameter can hold simple regex-like patterns, e.g. `/:id\u003c\\d+\u003e`\n\nSupported patterns:\n\n- `/:x` and `/*y` are optional segments and they cannot be empty\n- `\u003c...\u003e` to hold regex-like patterns, `-$.` are escaped, `/` is forbidden\n- `(...)` are used to mark fragments as optional, it translates to `(?:...)?`\n\n\u003e Please avoid `/` inside `(...)` or `\u003c...\u003e` as they will fail loudly!\n\n### Nesting\n\nConsider the following examples:\n\n```js\n// 1. regular\nr.add('/a');\nr.add('/a/:b');\nr.add('/a/:b/:c');\n\n// 2. nested\nr.mount('/a', () =\u003e {\n  r.mount('/:b', () =\u003e {\n    r.add('/:c');\n  });\n});\n\n// 3. concise\nr.add('/a/:b/:c');\n```\n\nIn the former way (1) we're declaring each route-level by hand, however they can be expressed at once as that latter one (3) which is more concise.\n\nThe middle form (2) is a shortcut to produce concise routes.\n\nSo which one is the best? It depends on the context:\n\n- Use concise routes to share the same `routeInfo` on all segments, it will be applied only if it's not yet defined on the route.\n- Use nested routes to use shared paths, it's convenient for creating stacks of context while mounting routes, etc.\n- Use regular routes to gain full control over its definition, this way each route can have its own separated context.\n\n\u003e Routes are sorted and matched by priority and type, routes with splat params will be tried last. As more static and with less parameters the route will be matched sooner!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpateketrueke%2Fabstract-nested-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpateketrueke%2Fabstract-nested-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpateketrueke%2Fabstract-nested-router/lists"}