{"id":21296143,"url":"https://github.com/dukeferdinand/ts-utils","last_synced_at":"2026-05-12T16:02:28.168Z","repository":{"id":55611451,"uuid":"313819198","full_name":"DukeFerdinand/ts-utils","owner":"DukeFerdinand","description":"Typescript based utilities, functions, and other similar goodies","archived":false,"fork":false,"pushed_at":"2021-04-04T20:13:16.000Z","size":345,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-22T07:16:41.584Z","etag":null,"topics":["fetch","javascript","javascript-library","typescript","typescript-library"],"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/DukeFerdinand.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":"2020-11-18T04:06:11.000Z","updated_at":"2021-04-04T20:13:18.000Z","dependencies_parsed_at":"2022-08-15T04:20:49.309Z","dependency_job_id":null,"html_url":"https://github.com/DukeFerdinand/ts-utils","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DukeFerdinand%2Fts-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DukeFerdinand%2Fts-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DukeFerdinand%2Fts-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DukeFerdinand%2Fts-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DukeFerdinand","download_url":"https://codeload.github.com/DukeFerdinand/ts-utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243763236,"owners_count":20344189,"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":["fetch","javascript","javascript-library","typescript","typescript-library"],"created_at":"2024-11-21T14:20:22.069Z","updated_at":"2026-05-12T16:02:28.077Z","avatar_url":"https://github.com/DukeFerdinand.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## @dukeferdinand/ts-utils\n\n[![Build Status](https://travis-ci.com/DukeFerdinand/ts-utils.svg?branch=master)](https://travis-ci.com/DukeFerdinand/ts-utils) [![Maintainability](https://api.codeclimate.com/v1/badges/7c69c117fb3652083d1c/maintainability)](https://codeclimate.com/github/DukeFerdinand/ts-utils/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/7c69c117fb3652083d1c/test_coverage)](https://codeclimate.com/github/DukeFerdinand/ts-utils/test_coverage)\n\nWelcome to my library!\n\nIf you're reading this you're probably looking for a small, easy to use library without a lot of frills, and with first class TypeScript support.\n\nIf so, you're in the right place!\n\n### What's included\nSo far, not a lot. But what _is_ included is rock solid and tested to hell and back :)\n\n#### sync utils\n- `clone\u003cT\u003e(data: T): T` -\u003e adds proper typing to the standard `JSON.parse(JSON.stringify(DATA))` pattern for cloning data in memory\n- `toString(data: any): string` -\u003e Slightly more user friendly `JSON.stringify` that primarily acts as a wrapper while disallowing functions (personal choice)\n- `wrapped\u003cT, E extends Error, F extends Function\u003e(fn: F): () =\u003e Result\u003cT, E\u003e` -\u003e this one is a heavy hitter. It builds off of my other library [@dukeferdinand/ts-results](https://www.npmjs.com/package/@dukeferdinand/ts-results) and acts as a synchronous error wrapper for any function that may or may not fail\n\n#### async utils\n- `asyncWrapped\u003cT, E extends Error, F extends Function\u003e(fn: F): () =\u003e Promise\u003cResult\u003cT, E\u003e\u003e` -\u003e This one is pretty much just the async version of the previous `wrapped` util. It allows you to await a fallible function and gives you an `Ok` or `Err` response from whatever function you put in\n\n#### fetch util\n- `smartFetch` -\u003e see code block below for full type declaration (it's long). This builds directly off of something I've use in production environments for critical internal systems. It's basically the same approach as the `asyncWrapped` util, but it adds a LOT more good stuff directly geared towards HTTP requests. You can use it _almost_ 100% as a replacement for `fetch` because it's just a wrapper that catches and labels errors and ok values alike. I say _almost_ as there's probably some edge case I won't ever run into in my typical use cases, but feel free to open an issue and I'll add it in.\n\nHere's the main declaration as promised! See [the main fetch namespace](/lib/fetch/index.ts) for more technical details and types.\n```ts\nsmartFetch\u003cT, E\u003e(\n  method: RequestMethods, url: string, body?: any, config: GlobalConfig = {}\n): Promise\u003cResult\u003cT, E\u003e\u003e\n```\n\nHere's a basic flow chart for how to use `smartFetch`:\n\n1. Init your global config if needed:\n```js\n\nimport { SmartFetch } from '@dukeferdinand/ts-utils'\n\n// Optionally destructure here\nSmartFetch.initSmartFetch({\n  baseUrl: 'https://yourcompany.com'\n})\n\n```\n2. Make a request, get your data!\n```ts\nconst {RequestMethods} = SmartFetch\n\ninterface YourExpectedData {\n  data: string;\n  username: string;\n}\n\ninterface YourCustomError {\n  error: string;\n  code: number;\n  reason: string;\n}\n\nconst res =\n  await SmartFetch.smartFetch\u003cYourExpectedData, YourCustomError\u003e(RequestMethods.GET,'/get-route')\n\nif (res.isOk()) {\n  // Use your data\n  return res.unwrap() // -\u003e YourExpectedData\n} else {\n  // Handle your error\n  return res.unwrapErr() // -\u003e YourCustomError\n}\n```\n\n3. Optionally, if your API returns something with a non standard HTTP error (i.e. a `200` can still be an error), create a custom handler. Your custom handler will be passed a `res` variable, which is anything that can possibly be returned to your app, but NOT a normal HTTP error, see [the main fetch namespace](/lib/fetch/index.ts) for more technical details. This is mainly because the error checking is fairly generic and only really checks `res.ok` before parsing anything as json.\n\n```ts\n// Mock example to catch any response with an 'error' key, but only if 'error' is not an empty string\nfunction shouldThrow(res: { [index: string]: any }) {\n  if (Object.keys(res).includes('error') \u0026\u0026 res.error !== '') {\n    return true\n  }\n  return false\n}\n\n// Break because error is not an empty string\nconst shouldError = await SmartFetch.smartFetch(RequestMethods.GET, '/bad-route', null, {\n  shouldThrow\n})\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdukeferdinand%2Fts-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdukeferdinand%2Fts-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdukeferdinand%2Fts-utils/lists"}