{"id":19724101,"url":"https://github.com/cerebral/url-mapper","last_synced_at":"2025-08-17T16:38:06.405Z","repository":{"id":49114268,"uuid":"41427214","full_name":"cerebral/url-mapper","owner":"cerebral","description":"Take a URL and map to functions, parsing params","archived":false,"fork":false,"pushed_at":"2021-06-28T13:18:13.000Z","size":67,"stargazers_count":43,"open_issues_count":0,"forks_count":8,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-17T15:47:03.452Z","etag":null,"topics":["router","routing"],"latest_commit_sha":null,"homepage":"https://npm.runkit.com/url-mapper","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cerebral.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-26T13:29:13.000Z","updated_at":"2024-12-22T16:24:10.000Z","dependencies_parsed_at":"2022-09-26T16:41:02.017Z","dependency_job_id":null,"html_url":"https://github.com/cerebral/url-mapper","commit_stats":null,"previous_names":["christianalfoni/url-mapper"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/cerebral/url-mapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerebral%2Furl-mapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerebral%2Furl-mapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerebral%2Furl-mapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerebral%2Furl-mapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cerebral","download_url":"https://codeload.github.com/cerebral/url-mapper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cerebral%2Furl-mapper/sbom","scorecard":{"id":271173,"data":{"date":"2025-08-11","repo":{"name":"github.com/cerebral/url-mapper","commit":"4409178300b78b536ee17618e2085990fea7df87"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 3/16 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/cerebral/url-mapper/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/cerebral/url-mapper/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/cerebral/url-mapper/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/cerebral/url-mapper/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/cerebral/url-mapper/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/cerebral/url-mapper/test.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/release.yml:21","Warn: npmCommand not pinned by hash: .github/workflows/test.yml:28","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T13:23:58.906Z","repository_id":49114268,"created_at":"2025-08-17T13:23:58.906Z","updated_at":"2025-08-17T13:23:58.906Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270869861,"owners_count":24659888,"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","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["router","routing"],"created_at":"2024-11-11T23:24:31.080Z","updated_at":"2025-08-17T16:38:06.362Z","avatar_url":"https://github.com/cerebral.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# url-mapper\n\nTwo way `URL` \u003c==\u003e `route(params)` converter with mapper.\n\n[![NPM version][npm-image]][npm-url]\n![Github Action][action-image]\n[![Test coverage][coveralls-image]][coveralls-url]\n[![Commitizen friendly][commitizen-image]][commitizen-url]\n[![Semantic Release][semantic-release-image]][semantic-release-url]\n\n## Installation\n\n`npm install url-mapper --save`\n\n## Usage\n\n### Overview\n\nThe main purpose of `url-mapper` is to match given `URL` to one of the `routes`.\nIt will return the matched route (key and associated value) and parsed parameters.\nYou can associate anything you want with route: function, React component or just plain object.\n\n`url-mapper` is helpful when creating router packages for frameworks or can be used as router itself.\nIt allows you to outsource working with a url (mapping, parsing, stringifying) and concentrate on wiring up things related to your favorite framework.\n\n### Example\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport Mapper from 'url-mapper'\nimport { CoreApp, ComponentA, ComponentB, Component404 } from './components'\n\nconst urlMapper = Mapper()\n\n// routable part of url as first argument\nvar matchedRoute = urlMapper.map('/bar/baz/:42', {\n  '/foo/:id': ComponentA,\n  '/bar/:list/:itemId': ComponentB,\n  '*': Component404,\n})\n\nif (matchedRoute) {\n  const Component = matchedRoute.match // ComponentB\n  const props = matchedRoute.values // { list: 'baz', itemId: 42 }\n\n  ReactDOM.render(\n    \u003cCoreApp\u003e\n      \u003cComponent {...props} /\u003e\n    \u003c/CoreApp\u003e\n  )\n}\n```\n\nSee [`@cerebral/router`](https://github.com/cerebral/cerebral/blob/next/packages/node_modules/%40cerebral/router) as an example of building your own router solution on top of `url-mapper`.\nAlso see [example at Runkit Sandbox](https://npm.runkit.com/url-mapper) to try it right in your browser.\n\n## API\n\n### Main module\n\nAt top level the `url-mapper` module exports a factory which returns default implementation of an `URL` \u003c==\u003e `route(params)` converter.\n\n#### Factory\n\n##### Usage\n\n```js\nvar urlMapper = require('url-mapper')\nvar mapper = urlMapper(options)\n```\n\n##### Arguments\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eParam\u003c/th\u003e\u003cth\u003eType\u003c/th\u003e\u003cth\u003eDetails\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eoptions\u003c/th\u003e\u003ctd\u003e\u003ccode\u003eObject\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eOptions passed to converter.\n      \u003ctable\u003e\n        \u003ctr\u003e\n          \u003cth\u003eProperty\u003c/th\u003e\u003cth\u003eType\u003c/th\u003e\u003cth\u003eDetails\u003c/th\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n          \u003ctd\u003equery\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eBoolean\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eEnables converting values not defined in route as query in URL Object Notation\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n          \u003ctd\u003equerySeparator\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eString\u003c/code\u003e\u003c/td\u003e\n          \u003ctd\u003eString used to separate query from routable part. Default \u003ccode\u003e'?'\u003c/code\u003e.\u003c/td\u003e\n        \u003c/tr\u003e\n      \u003c/table\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n##### Returns\n\n`Object` - Object with `parse`, `stringify` and `map` methods.\n\nReturned methods deals with Express-style route definitions and cleaned routable part of url (without origin, base path, leading hash symbol).\n\nParams defined in route are mapped to the same named properties in the `values` Object with help of `path-to-regexp` module.\nIt is safe to pass Numbers and Booleans as well as Strings as path parameteres.\nThe original type would be preserved while parsing back stringified one.\n\nBy default, the query part is ignored.\nQuery part params are mapped to the same named properties in `values` Object if `{ query: true }` option was passed to factory.\nConversion of the query part is made with help of `URLON` module. Therefore, it can accept any JSON serializable value.\n\nHash part is ignored at all if any present.\nYou still can manage your routes in `location.hash` but don't provide `#` symbol before routable part.\n\n#### `parse` method\n\n##### Usage\n\n`mapper.parse(route, url)`\n\n##### Arguments\n\n| Param | Type     | Details                        |\n| ----- | -------- | ------------------------------ |\n| route | `String` | Express style route definition |\n| url   | `String` | Routable part of url           |\n\n##### Returns\n\n`Object` - values parsed from `url` with given `route`.\n\nPath parsed using `path-to-regexp` module, tweaked to support `Boolean` and `Number`.\nQuery part parsed with `URLON` module if { query: true } option was passed to factory.\n\n#### `stringify` method\n\n##### Usage\n\n`mapper.stringify(route, values)`\n\n##### Arguments\n\n| Param  | Type     | Details                                                |\n| ------ | -------- | ------------------------------------------------------ |\n| route  | `String` | Express style route definition                         |\n| values | `Object` | Object used to populate parameters in route definition |\n\n##### Returns\n\n`String` - values stringified to `url` with given `route`.\n\nProperties defined in route are stringified to path part using `path-to-regexp` module, tweaked to support `Boolean` and `Number`.\nProperties not defined in route are stringified to query part using `URLON` module if { query: true } option was passed to factory.\n\n#### `map` method\n\n##### Usage\n\n`mapper.map(url, routes)`\n\n##### Arguments\n\n| Param  | Type     | Details                |\n| ------ | -------- | ---------------------- |\n| url    | `String` | Routable part of url   |\n| routes | `Object` | Routes to map url with |\n\n##### Returns\n\n`Object` - Object representing matched route with properties:\n\n| Property | Type     | Details                                             |\n| -------- | -------- | --------------------------------------------------- |\n| route    | `String` | Matched `route` defined as key in `routes`          |\n| match    | `Any`    | Value from `routes` associated with matched `route` |\n| values   | `Object` | Values parsed from given `url` with matched `route` |\n\n### Matcher\n\nCustom converting algoritms could be implemented by providing a custom compile function.\nIf you don't like default route definition format or converting algorithms, feel free to make your own.\n\n#### Factory\n\n##### Usage\n\n```js\nvar urlMapper = require('url-mapper/mapper')\nvar mapper = urlMapper(compileFn, options)\n```\n\n##### Arguments\n\n| Param     | Type       | Details                                               |\n| --------- | ---------- | ----------------------------------------------------- |\n| compileFn | `Function` | Function used by mapper to \"compile\" a route.         |\n| options   | `Any`      | `Optional`. Passed to `compileFn` as second argument. |\n\nFor each route mapper would call `compileFn(route, options)` and cache result internally.\n`compileFn` should return `parse(url)` and `stringify(values)` methods for any given route.\nSee [default implementation](/compileRoute.js) for reference.\n\n##### Returns\n\n`Object` - Object with `parse(route, url)`, `stringify(route, values)` and `map(url, routes)` methods.\n\nThese methods will use cached methods returned by `compileFn` for given routes.\n\n[npm-image]: https://img.shields.io/npm/v/url-mapper.svg?style=flat\n[npm-url]: https://npmjs.org/package/url-mapper\n[action-image]: https://github.com/github/docs/actions/workflows/test.yml/badge.svg?branch=master\n[coveralls-image]: https://img.shields.io/coveralls/cerebral/url-mapper.svg?style=flat\n[coveralls-url]: https://coveralls.io/r/cerebral/url-mapper?branch=master\n[commitizen-image]: https://img.shields.io/badge/commitizen-friendly-brightgreen.svg\n[commitizen-url]: http://commitizen.github.io/cz-cli/\n[semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square\n[semantic-release-url]: https://github.com/semantic-release/semantic-release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcerebral%2Furl-mapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcerebral%2Furl-mapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcerebral%2Furl-mapper/lists"}