{"id":31366357,"url":"https://github.com/zexsm/odata.querybuilder","last_synced_at":"2025-09-27T10:28:30.118Z","repository":{"id":35031890,"uuid":"194716668","full_name":"ZEXSM/OData.QueryBuilder","owner":"ZEXSM","description":"OData.QueryBuilder - library for creating complex OData queries (OData version 4.01) based on data models with linq syntax.","archived":false,"fork":false,"pushed_at":"2024-07-01T18:38:11.000Z","size":346,"stargazers_count":83,"open_issues_count":22,"forks_count":29,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-09-07T09:06:51.330Z","etag":null,"topics":["builder","csharp","dotnet","odata","querybuilder"],"latest_commit_sha":null,"homepage":"","language":"C#","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/ZEXSM.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,"governance":null}},"created_at":"2019-07-01T17:35:31.000Z","updated_at":"2025-08-23T15:36:42.000Z","dependencies_parsed_at":"2023-10-28T11:30:19.088Z","dependency_job_id":null,"html_url":"https://github.com/ZEXSM/OData.QueryBuilder","commit_stats":{"total_commits":249,"total_committers":5,"mean_commits":49.8,"dds":0.04016064257028118,"last_synced_commit":"339874f86bb353f6007708985942200ddca4dd89"},"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/ZEXSM/OData.QueryBuilder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZEXSM%2FOData.QueryBuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZEXSM%2FOData.QueryBuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZEXSM%2FOData.QueryBuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZEXSM%2FOData.QueryBuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ZEXSM","download_url":"https://codeload.github.com/ZEXSM/OData.QueryBuilder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ZEXSM%2FOData.QueryBuilder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277218435,"owners_count":25781443,"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-09-27T02:00:08.978Z","response_time":73,"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":["builder","csharp","dotnet","odata","querybuilder"],"created_at":"2025-09-27T10:28:24.904Z","updated_at":"2025-09-27T10:28:30.108Z","avatar_url":"https://github.com/ZEXSM.png","language":"C#","readme":"# OData.QueryBuilder\r\nLibrary for creating complex OData queries (OData version 4.01) based on data models with linq syntax.\r\n\r\n[![Build Status](https://travis-ci.com/ZEXSM/OData.QueryBuilder.svg?branch=main)](https://travis-ci.com/ZEXSM/OData.QueryBuilder)\r\n[![Coverage Status](https://coveralls.io/repos/github/ZEXSM/OData.QueryBuilder/badge.svg?branch=master)](https://coveralls.io/github/ZEXSM/OData.QueryBuilder?branch=main)\r\n[![Nuget Status](https://img.shields.io/nuget/dt/OData.QueryBuilder.svg)](https://www.nuget.org/packages/OData.QueryBuilder)\r\n\r\n## Benefits\r\n* Support:\r\n  * nested extenders with a choice of filtering\r\n  * operators\r\n    * [`in`](#in)\r\n    * [`any`](#any)\r\n    * [`all`](#all)\r\n  * functions\r\n    * date\r\n        * [`date`](#date)\r\n    * string and collection\r\n        * [`contains`](#contains)\r\n        * [`substringof (deprecated)`](#substringof)\r\n        * [`toupper`](#toupper)\r\n        * [`tolower`](#tolower)\r\n        * [`concat`](#concat)\r\n        * [`indexof`](#indexof)\r\n        * [`startswith`](#startswith)\r\n        * [`length`](#length)\r\n    * type\r\n        * [`cast`](#cast)\r\n  * sorting by several fields with indication of direction\r\n  * dynamic properties\r\n    \r\n## Installation\r\nTo install `OData.QueryBuilder` from `Visual Studio`, find `OData.QueryBuilder` in the `NuGet` package manager user interface or enter the following command in the package manager console:\r\n```\r\nInstall-Package OData.QueryBuilder\r\n```\r\n\r\nTo add a link to the main dotnet project, run the following command line:\r\n```\r\ndotnet add package OData.QueryBuilder\r\n```\r\n\r\n## Usage\r\n\r\n1. Build instance\r\n\r\n    As soon as possible, create a new instance of the OData.QueryBuilder object indicating the data models and the optional base path:\r\n\r\n    ```csharp\r\n    var odataQueryBuilder = new ODataQueryBuilder\u003cYour OData root model\u003e(\u003cYour base url\u003e?);\r\n    \r\n    // specify the resource for which the request will be built\r\n    odataQueryBuilder.For\u003cYour OData entity model\u003e(s =\u003e s.ODataEntity)\r\n    ```\r\n    :information_source: __OData.Query Builder assumes you are using [OData Connected Service](https://marketplace.visualstudio.com/items?itemName=marketplace.ODataConnectedService) and you have a root model otherwise use:__\r\n    \r\n    ```csharp\r\n    var odataQueryBuilder = new ODataQueryBuilder(\u003cYour base url\u003e?);\r\n    \r\n    // specify the resource for which the request will be built\r\n    odataQueryBuilder.For\u003cYour OData entity model\u003e(\"ODataEntity\")\r\n    ```\r\n\r\n2. Select request type\r\n\r\n    The builder allows you to build queries on the key and the list:\r\n    * [ByKey](#ByKey)\r\n      * [expand](#expand)\r\n        * [filter](#filter)\r\n        * [select](#select)\r\n        * [orderby](#orderby)\r\n        * [orderby desc](#orderbydesc)\r\n        * [skip](#skip)\r\n        * [top](#top)\r\n        * [count](#count)\r\n      * [select](#select) \r\n    * [ByList](#ByList)\r\n      * [expand](#expand)\r\n        * [filter](#filter)\r\n        * [select](#select)\r\n        * [orderby](#orderby)\r\n        * [orderby desc](#orderbydesc)\r\n        * [top](#top)\r\n      * [filter](#filter)\r\n      * [select](#select)\r\n      * [orderby](#orderby)\r\n      * [orderby desc](#orderbydesc)\r\n      * [skip](#skip)\r\n      * [top](#top)\r\n      * [count](#count)\r\n3. Get Uri request or collection of operators from the builder\r\n    ```csharp\r\n    odataQueryBuilder.ToUri()\r\n    odataQueryBuilder.ToDictionary()\r\n    ```\r\n## Fluent api\r\n\r\n#### \u003ca name=\"ByKey\"/\u003e ByKey\r\n```csharp\r\nvar uri = new ODataQueryBuilder\u003cODataInfoContainer\u003e(\"http://mock/odata\")\r\n    .For\u003cODataTypeEntity\u003e(s =\u003e s.ODataType)\r\n    .ByKey(223123123)\r\n    .ToUri()\r\n```\r\n\u003e http://mock/odata/ODataType(223123123)\r\n```csharp\r\nvar uri = new ODataQueryBuilder\u003cODataInfoContainer\u003e(\"http://mock/odata\")\r\n    .For\u003cODataTypeEntity\u003e(s =\u003e s.ODataType)\r\n    .ByKey(\"223123123\")\r\n    .ToUri()\r\n```\r\n\u003e http://mock/odata/ODataType(\"223123123\")\r\n```csharp\r\nvar uri = new ODataQueryBuilder\u003cODataInfoContainer\u003e(\"http://mock/odata\")\r\n    .For\u003cODataTypeEntity\u003e(s =\u003e s.ODataType)\r\n    .ByKey(223123123)\r\n    .For\u003cODataKindEntity\u003e(s =\u003e s.ODataKind)\r\n    .ByKey(223123123)\r\n    .ToUri()\r\n```\r\n\u003e http://mock/odata/ODataType(223123123)/ODataKind(223123123)\r\n#### \u003ca name=\"ByList\"/\u003e ByList\r\n```csharp\r\nvar uri = new ODataQueryBuilder\u003cODataInfoContainer\u003e(\"http://mock/odata\")\r\n    .For\u003cODataTypeEntity\u003e(s =\u003e s.ODataType)\r\n    .ByList()\r\n    .ToUri()\r\n```\r\n\u003e http://mock/odata/ODataType\r\n\r\n## Usage options\r\n\r\n#### \u003ca name=\"select\"/\u003e select\r\n```csharp\r\n.Select(s =\u003e s.Id)\r\n```\r\n\u003e $select=Id\r\n```csharp\r\n.Select(s =\u003e new { s.Id, s.Sum, s.Type })\r\n```\r\n\u003e $select=Id,Sum,Type\r\n#### \u003ca name=\"expand\"/\u003e expand\r\n```csharp\r\n.Expand(s =\u003e s.BaseType)\r\n```\r\n\u003e $expand=BaseType\r\n```csharp\r\n.Expand(s =\u003e new { s.BaseType, s.ODataKind })\r\n```\r\n\u003e $expand=BaseType,ODataKind\r\n```csharp\r\n.Expand(f =\u003e f\r\n    .For\u003cODataKindEntity\u003e(s =\u003e s.ODataKind)\r\n    .Expand(s=\u003e s\r\n        .For\u003cODataCodeEntity\u003e(s =\u003e s.ODataCode)\r\n        .Filter(s =\u003e s.IdKind == 1)\r\n        .OrderBy(s =\u003e s.IdKind)\r\n        .Top(1)\r\n        .Select(s =\u003e s.IdCode));\r\n})\r\n```\r\n\u003e $expand=ODataKind($expand=ODataCode($filter=IdKind eq 1;$orderby=IdKind;$top=1;$select=IdCode))\r\n#### \u003ca name=\"filter\"/\u003e filter\r\n```csharp\r\n.Filter(s =\u003e s.ODataKind.ODataCode.Code \u003e= \"test_code\" || s.IdType \u003e= 5)\r\n```\r\n\u003e $filter=ODataKind/ODataCode/IdCode eq 'test_code' or IdType ge 5\r\n```csharp\r\n.Filter(s =\u003e s.IdRule != default(int?) \u0026\u0026 s.IdRule == null)\r\n```\r\n\u003e $filter=IdRule ne null and IdRule eq null \r\n```csharp\r\n.Filter(s =\u003e s.ODataKind.OpenDate == DateTime.Today || s.ODataKind.OpenDate == new DateTime(2019, 7, 9)) || s.ODataKind.OpenDate == DateTime.Now)\r\n```\r\n\u003e $filter=ODataKind/OpenDate eq 2019-02-09T00:00:00Z or ODataKind/OpenDate eq 2019-02-09T00:00:00Z or ODataKind/OpenDate eq 2019-02-09T15:10:20Z\r\n```csharp\r\n.Filter(s =\u003e s.IsActive \u0026\u0026 s.IsOpen == true \u0026\u0026 !s.ODataKind.ODataCode.IdActive)\r\n```\r\n\u003e $filter=IsActive and IsOpen eq true and not ODataKind/ODataCode/IdActive\r\n```csharp\r\n.Filter(s =\u003e s.ODataKind.Color == ColorEnum.Blue)\r\n```\r\n\u003e $filter=ODataKind/Color eq 2\r\n\r\n:information_source: *Use parenthesis in filter*\r\n```csharp\r\nvar constStrIds = new[] { \"123\", \"512\" };\r\nvar constValue = 3;\r\n...\r\n.Filter((s, f, o) =\u003e s.IdRule == constValue\r\n    \u0026\u0026 s.IsActive\r\n    \u0026\u0026 (f.Date(s.EndDate.Value) == default(DateTimeOffset?) || s.EndDate \u003e DateTime.Today)\r\n    \u0026\u0026 (f.Date((DateTimeOffset)s.BeginDate) != default(DateTime?) || f.Date((DateTime)s.BeginDate) \u003c= DateTime.Now)\r\n    \u0026\u0026 o.In(s.ODataKind.ODataCode.Code, constStrIds), useParenthesis: true)\r\n```\r\n\r\n\u003e $filter=(((IdRule eq 3 and IsActive) and (date(EndDate) eq null or EndDate gt 2020-08-29T00:00:00Z)) and (date(BeginDate) ne null or date(BeginDate) le 2020-08-29T18:09:15Z)) and ODataKind/ODataCode/Code in ('123','512')\r\n#### \u003ca name=\"orderby\"/\u003e orderby\r\n```csharp\r\n.OrderBy(s =\u003e s.IdType)\r\n```\r\n\u003e $orderby=IdType asc\r\n```csharp\r\n.OrderBy(s =\u003e new { s.IdType, s.Sum })\r\n```\r\n\u003e $orderby=IdType,Sum asc\r\n```csharp\r\n.OrderBy((entity, sort) =\u003e sort\r\n    .Ascending(entity.BeginDate)\r\n    .Descending(entity.EndDate)\r\n    .Ascending(entity.IdRule)\r\n    .Ascending(entity.Sum)\r\n    .Descending(entity.ODataKind.OpenDate))\r\n```\r\n\u003e $orderby=BeginDate asc,EndDate desc,IdRule asc,Sum asc,ODataKind/OpenDate desc\r\n#### \u003ca name=\"orderbydesc\"/\u003e orderby desc\r\n```csharp\r\n.OrderByDescending(s =\u003e s.IdType)\r\n```\r\n\u003e $orderby=IdType desc\r\n```csharp\r\n.OrderByDescending(s =\u003e new { s.IdType, s.Sum })\r\n```\r\n\u003e $orderby=IdType,Sum desc\r\n#### \u003ca name=\"count\"/\u003e count\r\n```csharp\r\n.Count()\r\n```\r\n\u003e $count=true\r\n```csharp\r\n.Count(false)\r\n```\r\n\u003e $count=false\r\n#### \u003ca name=\"skip\"/\u003e skip\r\n```csharp\r\n.Skip(12)\r\n```\r\n\u003e $skip=12\r\n#### \u003ca name=\"top\"/\u003e top\r\n```csharp\r\n.Top(100)\r\n```\r\n\u003e $top=100\r\n\r\n## Usage operators\r\n\r\n#### \u003ca name=\"in\"/\u003e in\r\n\r\n```csharp\r\n.Filter((s, f, o) =\u003e o.In(s.ODataKind.ODataCode.Code, new[] { \"123\", \"512\" }) \u0026\u0026 o.In(s.IdType, new[] { 123, 512 }))\r\n```\r\n\u003e $filter=ODataKind/ODataCode/Code in ('123','512') and IdType in (123,512)\r\n\r\n#### \u003ca name=\"any\"/\u003e any\r\n\r\n```csharp\r\n.Filter((s, f, o) =\u003e o.Any(s.ODataKind.ODataCodes, v =\u003e v.IdCode == 1)\r\n```\r\n\u003e $filter=ODataKind/ODataCodes/any(v:v/IdCode eq 1)\r\n\r\n#### \u003ca name=\"all\"/\u003e all\r\n\r\n```csharp\r\n.Filter((s, f, o) =\u003e o.All(s.ODataKind.ODataCodes, v =\u003e v.IdActive))\r\n```\r\n\u003e $filter=ODataKind/ODataCodes/all(v:v/IdActive)\r\n\r\n## Usage date functions\r\n\r\n#### \u003ca name=\"date\"/\u003e date\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.Date(s.Open) == DateTime.Today)\r\n```\r\n\u003e $filter=date(Open) eq 2019-02-09T00:00:00Z\r\n\r\n## Usage string and collections functions\r\n\r\n#### \u003ca name=\"contains\"/\u003e contains\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.Contains(s.ODataKind.ODataCode.Code, \"W\"))\r\n```\r\n\u003e $filter=contains(ODataKind/ODataCode/Code,'W')\r\n\r\n#### \u003ca name=\"substringof\"/\u003e substringof\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.SubstringOf(\"W\", s.ODataKind.ODataCode.Code))\r\n```\r\n\u003e $filter=substringof('W',ODataKind/ODataCode/Code)\r\n\r\n#### \u003ca name=\"toupper\"/\u003e toupper\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.ToUpper(s.ODataKind.ODataCode.Code) == \"TEST_CODE\")\r\n```\r\n\u003e $filter=toupper(ODataKind/ODataCode/Code) eq 'TEST_CODE'\r\n\r\n#### \u003ca name=\"tolower\"/\u003e tolower\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.ToLower(s.ODataKind.ODataCode.Code) == \"test_code\")\r\n```\r\n\u003e $filter=tolower(ODataKind/ODataCode/Code) eq 'test_code'\r\n\r\n#### \u003ca name=\"concat\"/\u003e concat\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.Concat(s.ODataKind.ODataCode.Code, \"_1\") == \"test_code_1\")\r\n```\r\n\u003e $filter=concat(ODataKind/ODataCode/Code, '_1') eq 'test_code_1'\r\n\r\n#### \u003ca name=\"indexof\"/\u003e indexof\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.IndexOf(s.ODataKind.ODataCode.Code, \"testCode\") == 1)\r\n```\r\n\u003e $filter=indexof(ODataKind/ODataCode/Code,'testCode') eq 1\r\n\r\n#### \u003ca name=\"startswith\"/\u003e startswith\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.StartsWith(s.ODataKind.ODataCode.Code, \"test\"))\r\n```\r\n\u003e $filter=startswith(ODataKind/ODataCode/Code,'test')\r\n\r\n#### \u003ca name=\"length\"/\u003e length\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.Length(s.ODataKind.ODataCode.Code) \u003e 0)\r\n```\r\n\u003e $filter=length(ODataKind/ODataCode/Code) gt 0\r\n\r\n## Usage type functions\r\n\r\n#### \u003ca name=\"cast\"/\u003e cast\r\n\r\n```csharp\r\n.Filter((s, f) =\u003e f.Contains(f.Cast(s.ODataKindNew.ODataCode.Code, \"Edm.String\"), \"55\"))\r\n```\r\n\u003e $filter=contains(cast(ODataKindNew/ODataCode/Code,Edm.String),'55')\r\n\r\n## Usage other functions\r\n\r\n#### ConvertEnumToString\r\n```csharp\r\n.Filter((s, f) =\u003e s.ODataKind.Color == f.ConvertEnumToString(ColorEnum.Blue))\r\n```\r\n\u003e $filter=ODataKind/Color eq 'Blue'\r\n\r\n#### ConvertDateTimeToString\r\n```csharp\r\n.Filter((s, f) =\u003e s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTime(2019, 2, 9), \"yyyy-MM-dd\"))\r\n```\r\n\u003e $filter=ODataKind/OpenDate eq 2019-02-09\r\n\r\n#### ConvertDateTimeOffsetToString\r\n```csharp\r\n.Filter((s, f) =\u003e s.ODataKind.OpenDate == f.ConvertDateTimeToString(new DateTimeOffset(new DateTime(2019, 2, 9)), \"yyyy-MM-dd\"))\r\n```\r\n\u003e $filter=ODataKind/OpenDate eq 2019-02-09\r\n\r\n#### ReplaceCharacters\r\n```csharp\r\nvar dictionary = new Dictionary\u003cstring, string\u003e { { \"\u0026\", \"%26\" } });\r\nvar constValue = \"3 \u0026 4\";\r\n...\r\n.Filter((s, f) =\u003e s.ODataKind.ODataCode.Code == f.ReplaceCharacters(\r\n    constValue,\r\n    dictionary)\r\n```\r\n\u003e $filter=ODataKind/ODataCode/Code eq '3 %26 4'\r\n\r\n```csharp\r\nvar strings = new string[] {\r\n    \"test\\\\YUYYUT\",\r\n    \"test1\\\\YUYY123\"\r\n};\r\n...\r\n.Filter((s, f, o) =\u003e o.In(s.ODataKind.ODataCode.Code, f.ReplaceCharacters(\r\n    strings,\r\n    new Dictionary\u003cstring, string\u003e() { { @\"\\\", \"%5C\" } })))\r\n```\r\n\u003e $filter=ODataKind/ODataCode/Code in ('test%5C%5CYUYYUT','test1%5C%5CYUYY123')\r\n\r\n## Using dynamic properties\r\n\r\nFor use-cases where a property which is used for queries needs to be dynamically resolved (eg. the user chooses the property name to filter on)\r\na special method `ODataProperty.FromPath\u003cTProperty\u003e()` can be invoked in the query expressions:\r\n\r\n```csharp\r\n...\r\n.Filter(s =\u003e ODataProperty.FromPath\u003cint\u003e(\"IdRule\") == 3))\r\n```\r\n\r\nNote that the generic type argument `TProperty` needs to match the type of the dynamically\r\nresolved property in the OData model.\r\n\r\n\r\n## Suppress exceptions\r\n\r\n:warning: __May result in loss of control over the expected result.__\r\n\r\n\u003e Suppression of inclusion excludes the whole expression from the request\r\n\r\nBy default, suppression of function and operator argument exceptions is disabled. To enable it, you must pass the configuration `ODataQueryBuilderOptions` when initializing the builder\r\nwith initialization of the `SuppressExceptionOfNullOrEmptyFunctionArgs` and` SuppressExceptionOfNullOrEmptyOperatorArgs` properties.\r\n\r\n```csharp\r\nvar builder = new ODataQueryBuilder\u003cODataInfoContainer\u003e(\"http://mock/odata\", new ODataQueryBuilderOptions {\r\n    SuppressExceptionOfNullOrEmptyFunctionArgs = true,\r\n    SuppressExceptionOfNullOrEmptyOperatorArgs = true,\r\n});\r\n\r\nvar uri = builder\r\n    .For\u003cODataTypeEntity\u003e(s =\u003e s.ODataType)\r\n    .ByList()\r\n    .Filter((s, f, o) =\u003e o.In(s.ODataKind.ODataCode.Code, new string[0]) || o.In(s.ODataKind.ODataCode.Code, null)\r\n        \u0026\u0026 f.Contains(s.ODataKind.ODataCode.Code, default(string)) \r\n        \u0026\u0026 o.In(s.IdType, new[] { 123, 512 }))\r\n    .ToUri()\r\n```\r\n\u003e http://mock/odata/ODataType?$filter=IdType in (123,512)\r\n\r\n## ODataQueryBuilderOptions\r\n\r\n### UseCorrectDateTimeFormat\r\n\u003e You should always manually set this option to `true` (__default__: `false`)\r\n* `true` DateTime format `$\"{dateTime:yyyy-MM-ddTHH:mm:sszzz}\"` (with UTC offset)\r\n* `false` DateTime format `$\"{dateTime:s}Z\"` (without UTC offset)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzexsm%2Fodata.querybuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzexsm%2Fodata.querybuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzexsm%2Fodata.querybuilder/lists"}