{"id":16323105,"url":"https://github.com/danielstjules/swaddle","last_synced_at":"2025-07-01T22:32:52.525Z","repository":{"id":57375790,"uuid":"89751327","full_name":"danielstjules/swaddle","owner":"danielstjules","description":"Automagically create API clients/wrappers in JavaScript","archived":false,"fork":false,"pushed_at":"2017-06-12T00:13:53.000Z","size":64,"stargazers_count":23,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-02T21:07:36.159Z","etag":null,"topics":["api","client","proxy","wrapper"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/danielstjules.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}},"created_at":"2017-04-28T23:16:01.000Z","updated_at":"2022-08-27T16:59:20.000Z","dependencies_parsed_at":"2022-08-30T00:41:53.841Z","dependency_job_id":null,"html_url":"https://github.com/danielstjules/swaddle","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/danielstjules/swaddle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fswaddle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fswaddle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fswaddle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fswaddle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielstjules","download_url":"https://codeload.github.com/danielstjules/swaddle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielstjules%2Fswaddle/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263046808,"owners_count":23405262,"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":["api","client","proxy","wrapper"],"created_at":"2024-10-10T22:53:57.597Z","updated_at":"2025-07-01T22:32:52.501Z","avatar_url":"https://github.com/danielstjules.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg height=\"150\" src=\"https://cloud.githubusercontent.com/assets/817212/25590381/5e0275c6-2e7e-11e7-9874-09e03071300b.png\" alt=\"swaddle\"\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n\u003c/h1\u003e\n\nAutomagically create API clients/wrappers in JavaScript. This is a great\nalternative for when client libraries don't already exist, and they can't be\neasily generated from a swagger API. How does it work? ES6 proxies!\n\n\n``` javascript\nlet repos = await github.users('octocat').repos.get()\n// GET https://api.github.com/users/octocat/repos\n```\n\n[![Build Status](https://travis-ci.org/danielstjules/swaddle.svg?branch=master)](https://travis-ci.org/danielstjules/swaddle)\n\n* [Overview](#overview)\n* [Installation](#installation)\n* [Options](#options)\n  * [aliases](#aliases)\n  * [fn](#fn)\n  * [returnBody](#returnbody)\n  * [sendAsBody](#sendasbody)\n  * [json](#json)\n  * [camelCase](#camelcase)\n  * [extension](#extension)\n  * [whitelist](#whitelist)\n* [Compatibility](#compatibility)\n\n## Overview\n\nThe library wraps an API, returning an object that builds the target URL with\neach property and invocation. It performs the request when an HTTP method is\ninvoked. Properties reserved for HTTP methods include: get, post, put, patch,\ndelete, head, and options.\n\nThe library also comes with some sane defaults for JSON APIs. Two options are\nset to true by default: json and returnBody. JSON response bodies are parsed,\nand the response body itself is returned instead of the response object.\nIn the example below, we also make use of the camelCase option, which creates\na camelCase client for a snake_case JSON API.\n\n``` javascript\nlet swaddle = require('swaddle')\nlet github = swaddle('https://api.github.com', {camelCase: true})\n\n// GET https://api.github.com/users/octocat\nlet user = await github.users.get('octocat')\nuser.publicRepos // instead of user.public_repos\n\n// Without async/await\ngithub.users.get('octocat').then((user) =\u003e {\n  // ...\n})\n\n// GET https://api.github.com/users/octocat/repos\nlet repos = await github.users('octocat').get()\n\n// GET https://api.github.com/repos/octocat/Spoon-Knife/stargazers\nlet stargazers = await github.repos('octocat', 'Spoon-Knife').stargazers.get()\n\n// GET https://api.github.com/search/repositories?q=tetris\nlet results = await github.search.repositories.get('?q=tetris')\n\n// Identical operations, both perform\n// GET https://api.example.com/users/octocat\nawait github.users('octocat').get()\nawait github.users().get('octocat')\n```\n\nThe library is compatible with a range of HTTP request clients,\nincluding:\n[`got`](https://github.com/sindresorhus/got),\n[`request`](https://github.com/request/request),\n[`request-promise`](https://github.com/request-promise),\n[`whatwg-fetch`](https://github.com/github/fetch), and\n[`node-fetch`](https://github.com/bitinn/node-fetch).\n\nNone are installed as a dependency, giving you the freedom to pick your\nfavorite. Unless provided, it will default to trying to require `got`,\n`request-promise`, `request`, or the browser's `fetch`, in that order.\n\n``` javascript\nlet swaddle = require('swaddle')\nlet request = require('request')\nlet github = swaddle('https://api.github.com', {\n  fn: request // Use `request` to perform requests\n})\n\ngithub.users('octocat').repos.get((err, repos) =\u003e {\n  // GET https://api.github.com/users/octocat/repos\n  // request uses callbacks instead of promises\n})\n```\n\n## Installation\n\n``` bash\nnpm install --save swaddle\nnpm install got # optional\n```\n\n## Options\n\nOptions are passed to the underlying request library in two ways. The first,\nis during initialization:\n\n``` javascript\nlet client = swaddle('https://api.example.com', {\n  headers: {\n    Authorization: 'Basic ' + Buffer.from('User:Pass').toString('base64')\n  }\n})\n```\n\nAny options set during initialization will be stored and inherited by all\nrequests to that API, unless otherwise overwritten. That is, in the following\nrequest, both basic auth and the custom header would be set:\n\n``` javascript\nclient.search.get('?q=foo', {\n  headers: {'x-custom-header': 'value'}\n}).then((res) =\u003e {\n  // ...\n})\n```\n\nAll options are passed through to the underlying request function,\nexcept for those reserved by swaddle.\n\n### aliases\n\nCreates aliases for the supplied HTTP methods. Default: none\n\n``` javascript\nlet swaddle = require('swaddle')\nlet client = swaddle('https://api.example.com', {\n  aliases: {create: 'post', destroy: 'delete'}\n})\n\nclient.threads.create({body: {subject: 'hi'}}).then((res) =\u003e {\n  // POST https://api.example.com/threads\n  // body: '{\"subject\": \"hi\"}'\n})\n```\n\n### fn\n\nThe request function to use. Unless provided, it will default to requiring\n`got`, `request-promise`, `request`, or the browser's `fetch`, in that order.\n\n``` javascript\nlet swaddle = require('swaddle')\nlet request = require('request-promise')\nlet client = swaddle('https://api.example.com', {\n  fn: request\n})\n```\n\n### returnBody\n\nReturns the response body instead of response object. Default: true\n\n``` javascript\nlet swaddle = require('swaddle')\n\nlet client = swaddle('https://api.example.com')\nclient.users.get().then((res) =\u003e {\n  // Don't need to access res.body\n})\n\nclient = swaddle('https://api.example.com', {returnBody: false})\nclient.users.get().then((err) =\u003e {\n  // Need to access res.body\n})\n```\n\n### sendAsBody\n\nAny literal or object passed to post, put, or patch, is set as the request body.\nThus no additional headers or options can be set at the time of the request.\nCombined with aliases, it can prevent an otherwise leaky HTTP abstraction.\nDefault: false\n\n``` javascript\nlet swaddle = require('swaddle')\nlet client = swaddle('https://api.example.com', {\n  aliases: {create: 'post'},\n  sendAsBody: true\n})\n\n// Don't need to write:\n// client.messages.post({body: 'foo'})\n\nclient.messages.create('foo').then((res) =\u003e {\n  // POST https://api.example.com/messages\n  // body: \"foo\"\n})\n```\n\n### json\n\nParses the JSON response. This is built into some libraries, but not all\n(e.g. fetch). Default: true\n\n``` javascript\nlet swaddle = require('swaddle')\n\nlet client = swaddle('https://api.example.com')\nclient.users.get().then((res) =\u003e {\n  // res.body has been parsed\n})\n\nclient = swaddle('https://api.example.com', {json: false})\nclient.users.get().then((res) =\u003e {\n  // res.body is a string response\n})\n```\n\n### camelCase\n\nCreates a camelCase client for a snake_case JSON API. Only available when both\nreturnBody and json are set to true. Camel case properties are appended as\nsnake case to the resulting url. Arguments passed during function invocation\nare unaffected. Any objects request or response body are recursively formatted.\nDefault: false\n\n``` javascript\nlet client = swaddle('https://api.example.com')\n\nclient.jobStatuses.get((err, res) =\u003e {\n  // GET http://api/job_statuses\n})\n\nclient.fooBar('bazQux').get().then((res) =\u003e {\n  // GET http://api/foo_bar/bazQux\n})\n\nclient.users(1).get().then((res) =\u003e {\n  // If the original response body was '{\"is_admin\": false}', then res is\n  // {isAdmin: false}\n})\n\nclient.users.post({\n  body: {isAdmin: false, name: 'Foo Bar'}\n}).then((res) =\u003e {\n  // POST http://api/users\n  // body: '{\"is_admin\": false, \"name\": \"Foo Bar\"}'\n})\n```\n\n### extension\n\nAllows you to specify an extension to be appended to any requests,\nrequired by some APIs. Default: empty\n\n``` javascript\nlet swaddle = require('swaddle')\nlet client = swaddle('https://api.example.com', {\n  extension: 'json'\n})\n\nclient.users(1).get().then((res) =\u003e {\n  // https://api.example.com/users/1.json\n})\n\nclient.search.get('?q=foo').then((res) =\u003e {\n  // https://api.example.com/search.json?q=foo\n})\n```\n\n### whitelist\n\nWhitelists properties that can be accessed. Required when polyfilling Proxy\nsupport for older browsers. Note that the exception is thrown during the\nproperty access, and not during request execution. Accepts arrays of strings\nfor top level resources, or objects with nested objects and arrays for listing\nsub-resources. Default: empty\n\n``` javascript\n// Single top level resource, /user\nvar client = swaddle('https://api.example.com', {\n  whitelist: ['users']\n});\n\nclient.users().get().then((res) =\u003e {\n  // success\n});\n\nclient.search\n// Error: search not listed in swaddle's whitelist\n\n// Can provide a combination of objects \u0026 arrays for sub-resources\n// Example supports: /users, /tickets, /tickets/replies, /tickets/related\nclient = swaddle(BASE_URL, {\n  whitelist: {\n    users: [],\n    tickets: ['replies', 'related'],\n  }\n})\n\nclient.tickets(1).replies.get().then((replies) =\u003e {\n  // success\n})\n```\n\n## Compatibility\n\nThe module has been tested and is compatible with the following module\nversions:\n\n| package                                               | version  |\n| ----------------------------------------------------- | --------:|\n[`got`](https://github.com/sindresorhus/got)            | ^7       |\n[`request`](https://github.com/request/request)         | ^2.81.0  |\n[`request-promise`](https://github.com/request-promise) | ^4.2.0   |\n[`whatwg-fetch`](https://github.com/github/fetch)       | ^2.03    |\n[`node-fetch`](https://github.com/bitinn/node-fetch)    | ^1.6.3   |\n\nThe library makes use of Proxies, which means it works with Node 6.4+,\nChrome 49+, FF 18+, Opera 36+, Safari 10+, and Edge. For older versions of Node\nand browsers such as IE9+ and Safari 6+, two things are required:\n* Installing a polyfill like\n  [`proxy-polyfill`](https://github.com/GoogleChrome/proxy-polyfill)\n* Enumerating available properties via `whitelist`\n\nThis is because polyfills require that properties you want to proxy be known at\ncreation time. In a browser with fetch, an example would then be:\n\n``` javascript\nvar github = swaddle('https://api.github.com', {\n  whitelist: {users: ['repos']}\n});\n\n// Default to using fetch in the browser\ngithub.users('octocat').repos.get().then((repos) =\u003e {\n  // repos\n});\n\ngithub.search\n// Error: search not listed in swaddle's whitelist\n```\n\nFor browsers, it's assumed that you're using browserify, webpack, or similar,\nto load the module with your build.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielstjules%2Fswaddle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielstjules%2Fswaddle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielstjules%2Fswaddle/lists"}