{"id":15085954,"url":"https://github.com/vseplet/fetchify","last_synced_at":"2025-08-16T23:07:08.810Z","repository":{"id":196572991,"uuid":"696246072","full_name":"vseplet/fetchify","owner":"vseplet","description":"Gentle, promise-based HTTP client","archived":false,"fork":false,"pushed_at":"2024-08-17T18:44:32.000Z","size":84,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T23:15:31.828Z","etag":null,"topics":["axios","client","deno","fetch","https","nodejs","rate-limit","request"],"latest_commit_sha":null,"homepage":"https://jsr.io/@vseplet/fetchify","language":"TypeScript","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/vseplet.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-25T11:36:29.000Z","updated_at":"2025-04-09T10:26:58.000Z","dependencies_parsed_at":"2024-04-12T16:38:49.396Z","dependency_job_id":"ea842f4b-7366-4e62-aa05-dae74ce8ab57","html_url":"https://github.com/vseplet/fetchify","commit_stats":{"total_commits":55,"total_committers":4,"mean_commits":13.75,"dds":0.3090909090909091,"last_synced_commit":"57725d8020f00228ce89c5e5ec7ad808fefb9878"},"previous_names":["sevapp/fetchify","vseplet/fetchify"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vseplet%2Ffetchify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vseplet%2Ffetchify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vseplet%2Ffetchify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vseplet%2Ffetchify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vseplet","download_url":"https://codeload.github.com/vseplet/fetchify/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248312134,"owners_count":21082638,"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":["axios","client","deno","fetch","https","nodejs","rate-limit","request"],"created_at":"2024-09-25T07:02:03.134Z","updated_at":"2025-04-10T23:15:38.018Z","avatar_url":"https://github.com/vseplet.png","language":"TypeScript","readme":"# fetchify\n\n[![JSR](https://jsr.io/badges/@vseplet/fetchify)](https://jsr.io/@vseplet/fetchify)\n\n## 👋 👋 ATTENTION!\n\n\u003e This package is under development and will be frequently updated. The author\n\u003e would appreciate any help, advice, and pull requests! Thank you for your\n\u003e understanding 😊\n\n✅ [DENO RU COMMUNITY](https://t.me/+3rL7e9JzPLRhZTli)\n\nThis package is designed to make the process of interacting with various APIs\nthat have strict limitations more convenient and careful. For example, this\ncould be APIs like Notion or Telegram, which have stringent limits.\n\n- [fetchify](#fetchify)\n  - [👋 👋 ATTENTION!](#--attention)\n  - [Examples](#examples)\n  - [Import](#import)\n    - [Deno:](#deno)\n    - [Node.JS:](#nodejs)\n  - [Usage:](#usage)\n    - [Timeout](#timeout)\n    - [Rate-limit](#rate-limit)\n    - [Retries](#retries)\n    - [Parsing and validation](#parsing-and-validation)\n  - [DONATE](#donate)\n\n## 👋 👋 ATTENTION!\n\n\u003e This package is under development and will be frequently updated. The author\n\u003e would appreciate any help, advice, and pull requests! Thank you for your\n\u003e understanding 😊\n\n## Examples\n\n1. Gist\n   [deno telegram mailer](https://gist.github.com/sevapp/876e76399c2f88129f5259e17afe9582) +\n   article\n   [💌 Safe message sending script in Telegram with just 49 lines of code? Really?](https://dev.to/sevapp/safe-message-sending-script-in-telegram-with-just-49-lines-of-code-really-18jf)\n\n## Import\n\n#### Deno:\n\n```bash\ndeno add @vseplet/fetchify\n```\n\n#### Node.JS:\n\n```bash\nnpx jsr add @vseplet/fetchify\n```\n\nAnd import:\n\n```ts\nimport fetchify from \"@vseplet/fetchify\";\n```\n\n## Usage:\n\nThe first thing available to you is the **fetchify** function\n\n```ts\nconst json = await (await fetchify(\"https://catfact.ninja/fact\")).json();\nconsole.log(json);\n```\n\n### Timeout\n\nThis function has a similar interface to the classic **fetch** but extends it\nwith additional options, for example:\n\n```ts\nconst json = await (await fetchify(\n  \"https://catfact.ninja/fact\",\n  {\n    timeout: 1000, // Now, the waiting for a response will be interrupted after 1000 ms.\n  },\n)).json();\n\nconsole.log(json);\n```\n\n### Rate-limit\n\nBut you can also create an instance with a set base URL and rate-limiting\nconstraints:\n\n```ts\nconst jph = fetchify.create({\n  limiter: {\n    // Number of requests per second\n    rps: 3,\n    // You can handle the occurrence of a 429 error\n    // and return the time in ms that the request loop should delay\n    rt: (response) =\u003e 1000,\n  },\n  baseURL: \"https://jsonplaceholder.typicode.com\",\n  headers: {\n    \"hello\": \"world\",\n  },\n});\n\nfor (let i = 30; i--;) {\n  console.log(`send ${i}`);\n  // All basic methods supported: get post put delete head patch\n  jph.get(`/posts/${i}`).then((data) =\u003e console.log(`${i} ${data.status}`))\n    .catch((err) =\u003e console.log(`${i} ${err}`))\n    .finally(() =\u003e {\n    });\n}\n```\n\n### Retries\n\nYes, all methods comply with the **fetch** interface but also extend it with\nadditional options, for example:\n\n```ts\nawait jph.get(`/posts/10`, {\n  // Number of attempts\n  attempts: 10\n  // Time after which we stop waiting for a response\n  timeout: 1000\n});\n```\n\nIf you need to make a request to the configured **baseURL** but not through the\nrequest queue, you can add the flag:\n\n```ts\nawait jph.get(`/posts/10`, { unlimited: true });\n```\n\n### Parsing and validation\n\nIf you need to, you can try to parse JSON and validate it using\n[Zod](https://github.com/colinhacks/zod):\n\n```ts\nimport fetchify, { jsonZ, z } from \"@vseplet/fetchify\";\n\nconst schema = z.object({\n  id: z.string(), // there should actually be a z.number() here!\n  title: z.string(),\n  body: z.string(),\n  userId: z.number(),\n});\n\nconst { data, response } = await jsonZ(\n  fetchify(\"https://jsonplaceholder.typicode.com/posts/1\"),\n  schema,\n);\n```\n\nAnd get the error:\n\n```\nerror: Uncaught (in promise) ZodError: [\n  {\n    \"code\": \"invalid_type\",\n    \"expected\": \"string\",\n    \"received\": \"number\",\n    \"path\": [\n      \"id\"\n    ],\n    \"message\": \"Expected string, received number\"\n  }\n]\n```\n\nOr using [ValiBot](https://github.com/fabian-hiller/valibot):\n\n```ts\nimport fetchify, { jsonV, v } from \"@vseplet/fetchify\";\n\nconst schema = v.object({\n  id: v.number(), // v.number() is valid\n  title: v.string(),\n  body: v.string(),\n  userId: v.number(),\n});\n\nconst { data, response } = await jsonV(\n  fetchify(\"https://jsonplaceholder.typicode.com/posts/1\"),\n  schema,\n);\n\nconsole.log(data);\n// {\n//   id: 1,\n//   title: \"sunt aut facere repellat provident occaecati excepturi optio reprehenderit\",\n//   body: \"quia et suscipit\\n\" +\n//     \"suscipit recusandae consequuntur expedita et cum\\n\" +\n//     \"reprehenderit molestiae ut ut quas\"... 58 more characters,\n//   userId: 1\n// }\n```\n\n## DONATE\n\n🫶 You can support me and my work in the following ways: \u003cbr\u003e **TON**:\n`EQBiaSPuG33CuKXHClwsVvA-SazmLmtiTfXV7dQnqJdIlGgI`\u003cbr\u003e **USDT (TRC 20)**\n`(TRC20): TGPWzEiQjMYHjZx4fb3SDSumiSXdmjE4ZR`\u003cbr\u003e **BTC**:\n`bc1qq37svf4h8sg5qjsv99n9jf3r45dtd5yf5mdpc5`\u003cbr\u003e **ETH**:\n`0xAdc58F26cA3dCc01256cF1BeF6221f4bcaa3c660`\u003cbr\u003e **SOL**:\n`BckFFoxZw36ABbNS8Fc66LCdzJhu4ZwQANRdq49XmqKw`\u003cbr\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvseplet%2Ffetchify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvseplet%2Ffetchify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvseplet%2Ffetchify/lists"}