{"id":18637916,"url":"https://github.com/merhanmustafov/ts-url-builder","last_synced_at":"2025-07-05T20:34:20.240Z","repository":{"id":191025009,"uuid":"683721001","full_name":"MerhanMustafov/ts-url-builder","owner":"MerhanMustafov","description":"Strongly typed URL builder that types every next path depending on the previous one and every endpoint has its own queries ","archived":false,"fork":false,"pushed_at":"2023-09-02T15:18:55.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-27T10:15:57.620Z","etag":null,"topics":["builder-design-pattern","design-pattern","generic-types","typescript","url-builder"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/MerhanMustafov.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-27T13:50:14.000Z","updated_at":"2023-09-02T15:25:45.000Z","dependencies_parsed_at":"2023-08-27T18:58:15.100Z","dependency_job_id":"4b017317-9cac-4369-aa35-12008f74bcde","html_url":"https://github.com/MerhanMustafov/ts-url-builder","commit_stats":null,"previous_names":["merhanmustafov/ts-url-builder"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerhanMustafov%2Fts-url-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerhanMustafov%2Fts-url-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerhanMustafov%2Fts-url-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerhanMustafov%2Fts-url-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MerhanMustafov","download_url":"https://codeload.github.com/MerhanMustafov/ts-url-builder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239433909,"owners_count":19637806,"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":["builder-design-pattern","design-pattern","generic-types","typescript","url-builder"],"created_at":"2024-11-07T05:38:21.556Z","updated_at":"2025-02-18T08:21:15.991Z","avatar_url":"https://github.com/MerhanMustafov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ts-url-builder\n\u003cbr /\u003e\n\n❗ __To get the best out of this library you need to have Typescript in your project else you will NOT have the benefit of typing__\n\u003cbr /\u003e\n📌 There is __Template code__ section in the documentation, you can use it as a starting point\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Constraints\n⬇️ __The url builder supports up to 7 endpoints (including)__ \u003cbr /\u003e\n⬇️ __Only supports ES6 modules (import/export)__\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Description\n➡️ This is a library that brings the best out of __Typescript__ and combines that with __Builder Design Pattern__ providing you with one of the best yet simple __url builder tools__ out there.\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Welcome to `ts-url-bulder` documentation !\n\u003cbr /\u003e\n\nHere you will find everything you need to start building urls with ease and faster than ever. All you have to do is follow this guide that will walk you through the configuration which by the way is quite simple and easy. Once done with the configuration you are going to have an amazing tool that will surely speed up your dev process and reduce or even eliminate any typos you may accidentally make.\n\u003cbr /\u003e\n\n### What can you do with this tool🤔\nImagine if you can type your enpoint paths and the queries for each endpoint in such a way that __every next endpoint is typed depending on the previouse one and every endpoint has its own queries__ 🔝.Well, with this library you can do exactly that and on top of that you get __Intellisense__ which means you do not have to memorize or constantly check for the exact endpoint or query params. But that is not all, because the best about this library is that you are creating your urls by chaining methods which is very clean syntax. \n\u003cbr /\u003e\n#### Example\n```typescript\nimport { createUrlBuilderWith } from \"ts-url-builder\";\n\nconst config = {...}\n\n// config is required and baseUrl is optional\nconst urlBuilder = createUrlBuilderWith(config, baseUrl);\nurlBuilder.new().setPath(\"odds\").setPath(\"live\").setQuery(\"fixture\", 123).build();\n```\n#### Cool, right. Ok then, enough talk, let's get started !\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Get started\n\n- Installation\n```\n npm install ts-url-builder\n```\n- Import\n```typescript\nimport { createUrlBuilderWith } from \"ts-url-builder\";\n```\n\u003cbr /\u003e\n\n## What is `createUrlBuilderWith`\nThis is a function that accepts 2 arguments \u003cbr /\u003e\n1. `config` object which is __required__\n2. `baseUrl` a string which is __optional__\n\u003cbr /\u003e\n\nAnd returns an instance of the url builder.\n```typescript\nconst urlBuilder = createUrlBuilderWith(config, baseUrl)\n```\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n### What is `baseUrl` \n---\n`baseUrl` is just a string passed as __second argument__ to `createUrlBuilderWith` and is __optional__. Given that the \nconstraint is just a string it can be anything so make sure that you are passing the right base url. __The only thing you should know is that a base url should NOT end with \nslash (\"/\")__.\u003cbr /\u003e\n⚠️ https://localhost:3001/ __is wrong__ \u003cbr /\u003e\n⚠️ https://localhost:3001 __is correct__\n\n\u003cbr /\u003e\n\n### What is `config`\n---\n`config` is just an object but with a specific structrue.\n```typescript\nconst config = {\n\t0:{\n\t\t// query params of the base url\n\t\t// ...\n\t},\n\t1:{\n\t\t// first endpoints and the query params for the endpoints if any\n\t\t// if not just give the enpoint a null value\n\t\t// ...\n\t},\n\t2: {\n\t\t// second endpoints and the query params for the endpoints if any\n\t\t// if not just give the enpoint a null value\n\t\t// ...\n\t},\n\t3:{\n\t\t// third endpoints\n\t\t// ...\n\t},\n\t// ... \n\t7:{\n\t\t// IMPORTANT! 7 (including) is the maximum endpoints allowed\n\t}\n};\n```\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Usage\nWhen you create the config and pass it to `createUrlBuilderWith(config, baseUrl)` you will get urlBuilder instance. \u003cbr /\u003e\nThe `urlBuilder` instace have 4 methods \n1. `new` you __should always start with__ `new` method - it resets everything and gives you the opportunity to create one instance and use it wherever you want in your code.\n2. `setPath` this sets the path and can be chained up to 7 times (including) if you chain this method more than 7 it will just won't have typing.\n3. `setQuery` this sets the query for the current endpoint.\n4. `build` this is called at the end and returns the url string if the base url is not provided in `createUrlBuilderWith` it will return only the endpoint part.\n\n##### Example\n```typescript\nimport { createUrlBuilderWith } from \"ts-url-builder\";\n\nconst config = {...}\n\n// config is required and baseUrl is optional\nconst urlBuilder = createUrlBuilderWith(config, baseUrl);\nurlBuilder.new().setPath(\"odds\").setPath(\"live\").setQuery(\"fixture\", 123).build();\n```\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Advanced usage (Conditionals)\nYou can conditionally pass endpoints as well as query params with ternary operators like this:\n```typescript\nconst urlBuilder = createUrlBuilderWith(config);\n\n// the condition is hardcoded with true but you can change it to whatever you want\nurlBuilder.new()\n  .setPath(true ? \"odds\" : \"countries\") // this is how you can pass conditional endpoints\n  .setPath(\"live\")\n  .setQuery(true ? \"fixture\" : \"bet\", 123) // this is how you can pass conditional queries \n  .setQuery(\"league\", 56).build()\n```\n\u003cbr /\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n# Template code\n\nYoy can use this code as tempate to get started. Assuming you have already installed the library you can copy this code and start playing with it.\nThere are comments to help you clarify any question that may arise.\n```typescript\nimport { createUrlBuilderWith } from \"ts-url-builder\";\n\nconst config = {\n     // In 0: {...} are the queries for the base url\n     0: {\n          // this is how you type the value of the query param key\n          // if you want it to be a string\n          name: \"\" as string,\n\n          // if you want it to be a number\n          age: 0 as number,\n\n          // if you want it ot be a boolean\n          code: true as boolean,\n\n          // if you want it to be a string but specific once\n          country: \"\" as \"Bulgaria\" | \"Germany\" | \"Italy\" | \"United States\",\n     },\n\n     // In 1: {...} are the first enpoints and the queries for them if any of course.\n     1: {\n          // This is the first endpoint\n          countries: {\n               // these are the queries for the /countries endpoint\n               name: \"\" as string,\n               code: \"\" as string,\n               search: \"\" as string,\n          },\n\n          // This is the first endpoint\n          odds: {\n               // these are the queries for the /odds endpoint\n               fixture: 1 as number,\n               league: 1 as number,\n          },\n\n          // This is the first endpoint\n          // if you do not have queries for an endpoint just give it a null value\n          timezone: null,\n     },\n     // In 2: {...} are the second enpoints and the queries for them if any of course.\n     // !!! IMPORTANT: On the first nesting level inside 2: {...}\n     // are the enpoints from 1: {...}\n     // So REMEMBER that only those enpoints that have second path should be here\n     2: {\n          // This is the first endpoint's key from 1: {...}\n          countries: {\n               // This is the second endpoint for /countries\n               seasons: {\n                    // these are the queries for the /countries/seasons endpoint\n                    year: 0 as number,\n               },\n          },\n          // This is the first endpoint's key from 1: {...}\n          odds: {\n               // This is the second endpoint for /odds\n               live: {\n                    // These are the queries for the second endpoint /odds/live\n                    fixture: 1 as number,\n                    league: 1 as number,\n                    bet: 1 as number,\n               },\n               // This is the second endpoint for /odds\n               mapping: {\n                    // These are the queries for the second endpoint /odds/live\n                    page: 1 as number,\n               },\n               // This is the second endpoint for /odds\n               bookmakers: {\n                    id: 1 as number,\n                    search: \"\" as string,\n               },\n               // This is the second endpoint for /odds\n               bets: {\n                    id: 1 as number,\n                    search: \"\" as string,\n               },\n          },\n     },\n     // In 3: {...} are the third enpoints and the queries for them if any of course.\n     // !!! IMPORTANT: On the first nesting level inside 3: {...} are the keys from 1: {...} and on the second\n     // nesting level are the keys from 2: {...}\n     // So REMEMBER that only those enpoints that have third path should be here\n     3: {\n          // This is the first endpoint's key from 1: {...}\n          odds: {\n               // This is the second endpoint's key from 2: {...}\n               live: {\n                    // This is the third endpoint for /odds/live\n                    bets: {\n                         // These are the queries for the third endpoint /odds/live/bets\n                         id: 1 as number,\n                         search: \"\" as string,\n                    },\n               },\n          },\n     },\n     // ...\n     // 7:{...}\n\n     // Summary:\n     // Endpoints\n     // in 0: {...} you keep the base url query params\n     // in 1: {...} you keep the first endpoint and the queries for each endpoint if any\n     // in 2: {...} you keep the second endpoints and the queries for each endpoint if any.\n     // remember that the actual enpoint for second enpoint should come in the second nesting level inside 2: {...}\n     // in 3: {...} you keep the third endpoints and the queries for each endpoint if any.\n     // remember that the actual enpoint for third enpoint should come in the third nesting level inside 3: {...}\n\n     //...\n     // in 7: {...} you keep the seventh endpoints and the queries for each endpoint if any.\n     // remember that the actual enpoint for seventh enpoint should come in the seventh nesting level inside 7: {...}\n     // Queries\n     // - if endpoint does not have queries give the endpoint null value like in the timezone\n     // - How to type the value of a query key\n     // -- if string - \"\" as string,\n     // -- if number - 0 as number,\n     // -- if boolean - \"\" as boolean,\n     // -- if specific values - \"\" as \"Bulgaria\" | \"Germany\" | \"Italy\" | \"United States\",\n\n     // Constraints\n     // Maxsimum allowed endpoint are 7 (including)\n};\n\n\n// remember that the baseUrl should not end with slash (\"/\")\nconst urlBuilder = createUrlBuilderWith(config, \"http://localhost:3001\");\n\nurlBuilder.new().setPath(\"odds\").setPath(\"live\").setPath(\"bets\").setQuery(\"id\", 123).build();\n```\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmerhanmustafov%2Fts-url-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmerhanmustafov%2Fts-url-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmerhanmustafov%2Fts-url-builder/lists"}