{"id":26977458,"url":"https://github.com/seangarner/mongo-url-utils","last_synced_at":"2025-04-03T12:27:44.576Z","repository":{"id":31354480,"uuid":"34917305","full_name":"seangarner/mongo-url-utils","owner":"seangarner","description":"utilities to parse url param objects into objects that can be passed to mongo functions","archived":false,"fork":false,"pushed_at":"2019-04-15T06:48:55.000Z","size":102,"stargazers_count":6,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-12T13:17:18.535Z","etag":null,"topics":["javascript","mongo","nodejs","parsing","pegjs","url-parsing"],"latest_commit_sha":null,"homepage":null,"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/seangarner.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-05-01T18:29:57.000Z","updated_at":"2024-05-31T17:14:52.000Z","dependencies_parsed_at":"2022-08-24T17:10:28.678Z","dependency_job_id":null,"html_url":"https://github.com/seangarner/mongo-url-utils","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangarner%2Fmongo-url-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangarner%2Fmongo-url-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangarner%2Fmongo-url-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seangarner%2Fmongo-url-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seangarner","download_url":"https://codeload.github.com/seangarner/mongo-url-utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247000734,"owners_count":20867138,"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":["javascript","mongo","nodejs","parsing","pegjs","url-parsing"],"created_at":"2025-04-03T12:27:43.974Z","updated_at":"2025-04-03T12:27:44.563Z","avatar_url":"https://github.com/seangarner.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mongo-url-utils\n\n[![Build Status](https://travis-ci.org/seangarner/mongo-url-utils.svg?branch=master)](https://travis-ci.org/seangarner/mongo-url-utils)\n\nUtilities to parse url parameters into objects that can be passed to mongo functions.\n\n## compatibility\nCurrently depends on mongo 2.6 for the eq support.\n\nTested against node 4 LTS, 6 LTS and 8 LTS.\n\n\n## example\n```js\nvar mongoUrlUtils = require('mongo-url-utils');\n\nvar params = {\n  sort: '-age,+firstName',\n  fields: '-_id,+email,+firstName',\n  limit: '10',\n  skip: '0',\n  query: 'or(gt(age,18),eq(married,false))'\n};\n\nvar opts = mongoUrlUtils(params);\n\ncollection.find(opts.query, opts, function (err, docs) {\n  console.dir(docs);\n});\n```\n\nThe above would yield this `opts` object:\n```js\n{\n  query: {\n    $or: [\n      { age: { '$gt': 18 } },\n      { married: { '$eq': false } },\n    ]\n  },\n  options: {\n    sort: {\n      age: -1.\n      firstName: 1\n    },\n    fields: {\n      _id: 0,\n      email: 1,\n      firstName: 1\n    },\n    limit: 10,\n    skip: 0\n  }\n}\n```\n\nOr you can parse the query string directly:\n```js\nmongoUrlUtils('query=gt(age,21)\u0026sort=-age');\n\n// {\n//   query: { age: { '$gt': 21 } },\n//   options: {\n//     sort: { age: -1 }\n//   }\n// }\n```\n\n\n## `findIn`\nSugar to parse a url or params and pass to mongo `find` method of a collection.  Returns a cursor.\n```js\nvar people = db.collection('people');\nmongoUrlUtils.findIn(people, 'query=eq(id,3)').toArray(function (err, docs) {\n  // ...\n});\n```\n\n\n## `findOneIn`\nSugar to parse a url or params and pass to mongo `findOne` method of a collection.\n```js\nvar people = db.collection('people');\nmongoUrlUtils.findOneIn(people, 'query=eq(id,3)', function (err, person) {\n  // ...\n});\n```\n\n\n## find operators\nA find string is made up of any of the `query`, `sort`, `fields`, `limit` and `skip` operators.\n\n\n### `query`\nA query string which when parsed builds a query object for find.  Coverage of the mongo query\ninterface isn't 100% implemented yet.  Here's what's available:\n\noperator    | example\n----------- | -------------\n$eq         | `eq(name,\"West and Sons\")`\n$gte        | `gte(id,6)`\n$gt         | `gt(id,6)`\n$lte        | `lte(id,3)`\n$lt         | `lt(id,3)`\n$ne         | `ne(closed,true)`\n$size       | `size(grades,4)`\n$in         | `in(restaurant_id,[\"8165423\",\"5827429\"])`\n$nin        | `nin(id,[1,2,3,4,5])`\n$all        | `all(address.coord,[\"-47.9327\",\"-82.6261\"])`\n$and        | `and(eq(grades.score,5),eq(borough,\"Buckinghamshire\"))`\n$or         | `or(eq(id,1),eq(borough,\"Buckinghamshire\"))`\n$not        | `not(size(grades,0))`\n$regex      | `regex(address.street,\".*Road.*\")`\n$where      | `where(\"parseInt(this.restaurant_id, 10) === 5827429\")`\n$text       | `text(\"y hijos\", \"es\")`\n$mod        | `mod(id,5,1)`\n$elemMatch  | `elemMatch(grades,eq(score,2))`\n$exists     | `exists(closed,false)`\n$type       | `type(name,2)` or `type(name,String)` (see Mongo Types)\n\nExample; only return people who are widowed or age is greater than 50 and less than 70.\n```\nGET /people?query=or(eq(widowed,true),and(gt(age,50),lt(age,70)))\n```\n\nThere are also extra operators that wrap `$regex` providing a more predictable query without the\nfull power or danger associated with PCREs.\n\noperator    | example\n----------- | ----------------------------------\nstartsWith  | `startsWith(name, \"We\")`\nendsWith    | `endsWith(address.street, \"Road\")`\ncontains    | `contains(borough, \"shire\")`\n\nThe extra operators also support `$not`.  For example `not(contains(borough, \"shire\"))` would\nfind the docs in which `borough` does not contain `shire`.\n\n#### data type support\n\nIn addition to the string, number, boolean and `null` types, the query parser implements support for native Date parsing.\n\ntype | format | parsed as  | example usage\n-----|--------|------------|----------------------------------------------------------------------------\ndate | [Date Time String][ecma-datetime] | [Date][mdn-date]  | `gt(grades.date,Date(2015-04-28T17:00Z))`\n\nPlease submit pull requests for additional data types, particularly those that are found within the [MongoDB Extended JSON](https://docs.mongodb.org/manual/reference/mongodb-extended-json/) specification.\n\n#### case insensitive matching\nSome operators support the `i` flag to denote that the operator should match the value case\ninsensitively.  This is useful if you want to enable case insensitive match without allowing\nfull `$regex` powers (because `$regex` is the only way of achieving this in mongo).\n\n  - `eq(tags, 'NODE', i)` matches Node, NODE, node, NoDe, etc\n\nAlso supported with `ne`, `startsWith`, `endsWith` and `contains`, but must be enabled using the\n`disabledOperators` query option as the default is to disable this feature.\n\n```js\nvar options = {\n  query: {\n    caseInsensitiveOperators: true\n  }\n};\nmongoUrlUtils({query: 'regex(email,\"Person@Example.Com\",i)'}, options);\n```\n\n#### regex safety checking\nThe `regex` query operator can be dangerous allowing attackers to create an expensive expression.\nSet `safeRegex` to `true` to pass all regexes through [safe-regex](https://github.com/substack/safe-regex)\nand throw an error if an unsafe regex is sent.\n\n```js\nvar options = {\n  query: {\n    safeRegex: true\n  }\n};\nmongoUrlUtils({query: 'regex(email,\"(a+){10}y\")'}, options);\n// throws Error\n```\n\n#### mongo types\nThe `type()` query operator allows either integer identifiers as per the mongodb documentation.  For\nconvinience it also maps the following types to their ids: `Double`, `String`, `Object`, `Array`,\n`Binary`, `Undefined`, `ObjectId`, `Boolean`, `Date`, `Null`, `RegExp`, `Javascript`, `Symbol`,\n`ScopedJavascript`, `Int32`, `Timestamp` and `Int64`.\n\n#### todo\n  - full `$not` support\n    - missing for `regex`, `where`, `text`, `mod`, `elemMatch`, `exists`, `type`\n  - $nor\n  - /regex/ (can't use $regex with $in/$nin)\n\n\n### `sort`\nComma separated field names prefixed with a `+` for an ascending sort or `-` for a descending sort.\nThere is no default so either `-` or `+` must be provided.\n\nExample; return people sorted by oldest age first.\n\n```\nGET /people?sort=-age\n```\n\n### `fields`\nA [projection parameter](http://docs.mongodb.org/manual/reference/method/db.collection.find) which\nlimits which fields are returned.  Fields are comma separated.\n\nYou can either use an inclusive *or*  exclusive projection.  An inclusive (`+`) projection means\ngive me back only these fields.  An exclusive (`-`) projection means give me back all fields except\nthese.  Inclusive and exclusive cannot be mixed, with one exception for the `_id` field in an\ninclusive projection.\n\nExample; only return the first name and country of people and exclude `_id`.  This is the only\ntime you can mix `-` and `+`.\n\n```\nGET /people?fields=-_id,+firstName,+address.country\n```\n\nThe following projection operators are also supported:\n\noperator               | example\n---------------------- | ----------------------------------\n[elemMatch-projection] | `elemMatch(students,eq(school,102))`\n\nProjection operators can be mixed with projection parameters, however it's difficult to prevent\nmixed exclusive and exclusive parameters with operators so it's recommended that operators come last\nin the fields string.  e.g.\n\n```\nGET /courses?fields=-id,+title,elemMatch(students,eq(gender,\"female\"))\n```\n\n### `limit`\nLimit how many documents are returned.\n\nExample; return at most the first 10 documents.\n```\nGET /people?limit=10\n```\n\n### `skip`\nHow many documents to skip before returning the set.  When combined with `limit` it can be used to\npage results.\n\nExample; return all except the first 10 documents.\n```\nGET /people?skip=10\n```\n\n## disabling query operators\nPerhaps you don't want to allow all query operators for performance reasons.  It's possible to\ndisable operators at the parser level so the parser will throw an exception when a blacklisted\noperator is used.\n\nExample; disable the regex operator.\n```js\nvar options = {\n  query: {\n    disabledOperators: ['regex', 'text']\n  }\n};\nmongoUrlUtils({query: 'regex(email,\".*\\\\\\\\.gmail\\\\\\\\.com\")'}, options);\n\n// Error: regex operator is disabled\n```\n\n### a note on URL encoding\nBrowsers don't encode a literal `+` in the query string of a url but node will convert them into\nliteral spaces when parsing the querystring.  This is a little inconvenient for `sort` and `fields`\nwhich both prefix fields with `+`.  Both parsers works around this by treating a literal space as it\nwould a `+` at the beginning of the query value.\n\nIf this magic behavior concerns you it can be disabled by setting the `{strictEncoding: true}`\noption - but remember clients are now responsible for encoding `+` before making the request.\n\n```js\nvar options = {\n  strictEncoding: true\n};\nmongoUrlUtils('fields=+id,-_id', options); // throws an Error\nmongoUrlUtils('fields=%2Bid,-_id', options); // works as expected\n```\n\n[elemMatch-projection]: https://docs.mongodb.org/manual/reference/operator/projection/elemMatch/\n[mdn-date]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date\n[ecma-datetime]: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseangarner%2Fmongo-url-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseangarner%2Fmongo-url-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseangarner%2Fmongo-url-utils/lists"}