{"id":24083250,"url":"https://github.com/mitranim/xhttp","last_synced_at":"2025-04-30T18:23:05.624Z","repository":{"id":22918933,"uuid":"26267832","full_name":"mitranim/xhttp","owner":"mitranim","description":"[MOVED to mitranim/js] Tiny shortcuts for using the native fetch API. Provides a fluent builder-style API for request building and response reading.","archived":false,"fork":false,"pushed_at":"2022-02-15T16:18:26.000Z","size":222,"stargazers_count":32,"open_issues_count":0,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-26T06:56:58.177Z","etag":null,"topics":["browser","builder","fetch","http"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/mitranim.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":"2014-11-06T11:52:25.000Z","updated_at":"2024-09-15T10:53:55.000Z","dependencies_parsed_at":"2022-08-21T16:31:16.113Z","dependency_job_id":null,"html_url":"https://github.com/mitranim/xhttp","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fxhttp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fxhttp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fxhttp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mitranim%2Fxhttp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mitranim","download_url":"https://codeload.github.com/mitranim/xhttp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251758663,"owners_count":21639080,"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":["browser","builder","fetch","http"],"created_at":"2025-01-09T23:56:11.069Z","updated_at":"2025-04-30T18:23:05.598Z","avatar_url":"https://github.com/mitranim.png","language":"JavaScript","readme":"## Overview\n\nTiny syntactic shortcuts for native `Request`/`Response`/`Headers`/`fetch`.\n\n* Fluent builder-style API.\n* Interoperable with built-ins.\n* Shortcuts for common actions, such as:\n  * Building HTTP requests.\n    * A builder-style API is more concise and flexible than the native one.\n  * Handling HTTP errors in responses.\n    * Constructing descriptive exceptions with HTTP status and response text.\n* Tiny, dependency-free, single file, native module.\n\n## TOC\n\n* [#Usage](#usage)\n* [#API](#api)\n  * [`function req`](#function-req)\n  * [`class Err`](#class-err)\n  * [`class Req`](#class-req)\n  * [`class Res`](#class-res)\n  * [`class Head`](#class-head)\n  * [`function jsonDecode`](#function-jsondecode)\n  * [`function jsonEncode`](#function-jsonencode)\n  * [Undocumented](#undocumented)\n* [#Changelog](#changelog)\n* [#License](#license)\n* [#Misc](#misc)\n\n## Usage\n\nIn browsers and Deno, import by URL:\n\n```js\nimport * as h from 'https://cdn.jsdelivr.net/npm/xhttp@0.15.3/xhttp.mjs'\n```\n\nWhen using Node or NPM-oriented bundlers like Esbuild:\n\n```sh\nnpm i -E xhttp\n```\n\nExample usage:\n\n```js\nconst reqBody = {msg: `hello world`}\nconst resBody = await h.req().to(`/api`).post().json(reqBody).fetchOkJson()\n```\n\n## API\n\n### `function req`\n\nSame as [#`new Req`](#class-req) but syntactically shorter.\n\n### `class Err`\n\nSubclass of `Error` for HTTP responses. The error message includes the HTTP status code, if any.\n\n```ts\nclass Err extends Error {\n  message: string\n  status: int\n  res?: Response\n\n  constructor(message: string, status: int, res?: Response)\n}\n```\n\n### `class Req`\n\nRequest builder. Does _not_ subclass `Request`. Call `.req()` to create a native request, or the various `.fetchX()` methods to immediately execute. Unlike the native request, the body is not always a stream. This means `Req` can be stored and reused several times.\n\n```ts\nclass Req extends RequestInit {\n  /*\n  Similar to `fetch(this.req())`, but also constructs `Res` from the resulting\n  response.\n  */\n  fetch(): Promise\u003cRes\u003e\n\n  /*\n  Returns the resulting `Res` if the response is OK. If the response is\n  received, but HTTP status code is non-OK, throws a descriptive `Err`.\n\n  Shortcut for `(await this.fetch()).okRes()`.\n  */\n  fetchOk(): Promise\u003cRes\u003e\n\n  // Shortcut for `(await this.fetch()).okText()`.\n  fetchOkText(): Promise\u003cstring\u003e\n\n  // Shortcut for `(await this.fetch()).okJson()`.\n  fetchOkJson(): Promise\u003cany\u003e\n\n  /*\n  Mutates the request by applying the given options and returns the same\n  reference. Automatically merges headers.\n  */\n  mut(init: RequestInit): Req\n\n  // Shortcut for `new Request(this.url, this)`.\n  req(): Request\n\n  // Sets `.url` and returns the same reference.\n  to(val: string | {toString(): string}): Req\n\n  // Sets `.signal` and returns the same reference.\n  sig(val: AbortSignal): Req\n\n  // Sets `.method` and returns the same reference.\n  meth(val: string): Req\n\n  // Sets `.body` and returns the same reference. Short for \"input\".\n  inp(val: BodyInit): Req\n\n  // JSON-encodes the input, sets `.body`, and sets JSON request headers.\n  // Does NOT set the `accept` header. Returns the same reference.\n  json(val: any): Req\n\n  // Shortcuts for setting the corresponding HTTP method.\n  get(): Req\n  post(): Req\n  put(): Req\n  patch(): Req\n  delete(): Req\n\n  // Idempotently sets `.headers` and returns the resulting reference.\n  head(): Head\n\n  // Shortcuts for modifying the headers. All mutate and return the request.\n  headSet(key, val: string): Req\n  headAppend(key, val: string): Req\n  headDelete(key: string): Req\n  headMut(src: Headers | Record\u003cstring, string\u003e): Req\n\n  // Class used for `.headers`. Can override in subclass.\n  get Head(): {new(): Head}\n\n  // Class used for responses. Can override in subclass.\n  get Res(): {new(): Res; static from(res: Response): Res}\n}\n```\n\n### `class Res`\n\nSubclass of `Response` with additional shortcuts for response handling. Always wraps a native response received from another source. [#`Req`](#class-req) automatically uses this for responses. You don't need to construct this.\n\n```ts\nclass Res extends Response {\n  // Reference to the wrapped response.\n  res: Response\n\n  /*\n  Same as the native constructor, but takes an additional response reference\n  to wrap. Defers the following getters to the original:\n\n    get redirected\n    get type\n    get url\n  */\n  constructor(body?: BodyInit | null, init?: ResponseInit, res: Response)\n\n  /*\n  If `res.ok`, returns the response as-is. Otherwise throws an instance of\n  `Err` with the status code and response text in its error message.\n  */\n  okRes(): Promise\u003cRes\u003e\n\n  /*\n  Shortcut for `(await this.okRes()).text()`. On unsuccessful response,\n  throws a descriptive error. On success, returns response text.\n  */\n  okText(): Promise\u003cstring\u003e\n\n  /*\n  Shortcut for `(await this.okRes()).json()`. On unsuccessful response,\n  throws a descriptive error. On success, returns decoded JSON.\n  */\n  okJson(): Promise\u003cany\u003e\n\n  // Class used for response errors. Can override in subclass.\n  get Err(): {new(): Err}\n\n  // Shortcut for constructing from another response.\n  static from(res: Response): Res\n}\n```\n\n### `class Head`\n\nSubclass of `Headers` with additional shortcuts. Used internally by [`Req`](#class-req).\n\n```ts\nclass Head extends Headers {\n  /*\n  Merges the headers from the given source into the receiver. Mutates and\n  returns the same reference.\n  */\n  mut(src: Headers | Record\u003cstring, string\u003e): Head\n\n  /*\n  Overrides `Headers.prototype.set` to return the same reference, instead of\n  void. Also asserts input types.\n  */\n  set(key, val: string): Head\n\n  /*\n  Overrides `Headers.prototype.append` to return the same reference, instead of\n  void. Also asserts input types.\n  */\n  append(key, val: string): Head\n\n  /*\n  Similar to `.set`, but does nothing if the key is already present, or if the\n  value is empty.\n  */\n  setOpt(key: string, val?: string): Head\n\n  /*\n  Similar to `Set.prototype.clear`. Removes all content. Mutates and returns\n  the same reference.\n  */\n  clear(): Head\n}\n```\n\n### `function jsonDecode`\n\nSanity-checking wrapper for [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). If the input is nil or an empty string, returns `null`. Otherwise the input must be a primitive string. Throws on other inputs, without trying to stringify them.\n\n### `function jsonEncode`\n\nSanity-checking wrapper for [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). Equivalent to `JSON.stringify(val ?? null)`. If the input is `undefined`, returns `'null'` (string) rather than `undefined` (nil). Output is _always_ a valid JSON string.\n\n### Undocumented\n\nSome APIs are exported but undocumented to avoid bloating the docs. Check the source files and look for `export`.\n\n## Changelog\n\n### 0.15.3\n\nAdd `Head..setOpt`, `Res..Err`. Minor bugfixes.\n\n### 0.15.2\n\nBugfix for previous version.\n\n### 0.15.1\n\nAdd `req` shortcut.\n\n### 0.15.0\n\nFull revision.\n\n* Now provides shortcuts for `fetch` and other built-ins.\n* Now provides only 1 module for all environments.\n* No longer uses Node APIs.\n* No longer uses `XMLHttpRequest`.\n\n## License\n\nhttps://unlicense.org\n\n## Misc\n\nI'm receptive to suggestions. If this library _almost_ satisfies you but needs changes, open an issue or chat me up. Contacts: https://mitranim.com/#contacts\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fxhttp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmitranim%2Fxhttp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmitranim%2Fxhttp/lists"}