{"id":14986710,"url":"https://github.com/ahmadnassri/node-oas-request","last_synced_at":"2025-06-29T13:03:09.565Z","repository":{"id":37086853,"uuid":"282136497","full_name":"ahmadnassri/node-oas-request","owner":"ahmadnassri","description":"OAS 3.x dynamic request client","archived":false,"fork":false,"pushed_at":"2025-01-07T20:53:50.000Z","size":553,"stargazers_count":12,"open_issues_count":7,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-12T23:48:50.013Z","etag":null,"topics":["node","oas","openapi"],"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/ahmadnassri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null},"funding":{"github":["ahmadnassri"]}},"created_at":"2020-07-24T06:01:32.000Z","updated_at":"2025-01-07T20:53:54.000Z","dependencies_parsed_at":"2025-04-11T20:35:09.468Z","dependency_job_id":"9ad552fa-374f-4ed9-9c99-1be3e801bf78","html_url":"https://github.com/ahmadnassri/node-oas-request","commit_stats":{"total_commits":436,"total_committers":5,"mean_commits":87.2,"dds":"0.34174311926605505","last_synced_commit":"fbf48a6000196c614226953c0b24df55bd0e4faa"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/ahmadnassri/node-oas-request","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmadnassri%2Fnode-oas-request","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmadnassri%2Fnode-oas-request/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmadnassri%2Fnode-oas-request/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmadnassri%2Fnode-oas-request/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahmadnassri","download_url":"https://codeload.github.com/ahmadnassri/node-oas-request/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmadnassri%2Fnode-oas-request/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262598141,"owners_count":23334667,"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":["node","oas","openapi"],"created_at":"2024-09-24T14:13:23.614Z","updated_at":"2025-06-29T13:03:09.483Z","avatar_url":"https://github.com/ahmadnassri.png","language":"JavaScript","funding_links":["https://github.com/sponsors/ahmadnassri"],"categories":[],"sub_categories":[],"readme":"# OpenAPI Spec HTTP Client\n\nFeed it a JSON Spec, it will spit out a lightweight HTTP client!\n\n[![license][license-img]][license-url]\n[![release][release-img]][release-url]\n[![semantic][semantic-img]][semantic-url]\n\n## Why\n\nWhile there are plenty of *\"code generators\"* for OpenAPI Specification, they create a lot of \"garbage\" code that you may not need,\nand there while there are others that follow a similar path of this library, they still attempt to do too much! *(like request validation before sending)*\n\nThis library does not concern itself with anything other than constructing an HTTP request and sending it!\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eFAQ\u003c/strong\u003e\u003c/summary\u003e\n\n-   **Why no validation?**  \n    You should rely on validation \u0026 sanitation at the source of truth: *The API server itself!*\n\n-   **YAML Support?**  \n    This package **does not** natively support OpenAPI Specification YAML format, but you can easily convert to JSON before calling `oas-rqeuest`\n\n      \u003cdetails\u003e\n        \u003csummary\u003eExample\u003c/summary\u003e\n\n    ###### using [`YAML`][]\n\n    ``` js\n    const YAML = require('yaml')\n    const { readFile } = require('fs/promises')\n\n    const file = await readFile('openapi.yml', 'utf8')\n\n    const spec = YAML.parse(file)\n\n    const OASRequest = require('oas-request')(spec)\n    ```\n\n    ###### using [`apidevtools/swagger-cli`][]\n\n    ``` bash\n    npx apidevtools/swagger-cli bundle spec/openapi.yml --outfile spec.json\n    ```\n\n      \u003c/details\u003e\n\n    \u003c/details\u003e\n\n## What\n\nSome feature highlights:\n\n-   Automatic methods creation\n-   Path Templating\n-   uses [`cross-fetch`][] for all HTTP operations\n\n## Usage\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cem\u003ee.g. \u003ccode\u003epetstore.json\u003c/code\u003e\u003c/em\u003e\u003c/summary\u003e\n\n``` json\n{\n  \"openapi\": \"3.0.0\",\n  \"info\": {\n    \"version\": \"1.0.0\",\n    \"title\": \"Swagger Petstore\"\n  },\n  \"servers\": [\n    {\n      \"url\": \"http://petstore.swagger.io/{version}\",\n      \"variables\": {\n        \"version\": {\n          \"description\": \"api version\",\n          \"default\": \"v1\"\n        }\n      }\n    }\n  ],\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"operationId\": \"listPets\",\n        \"parameters\": [\n          {\n            \"name\": \"limit\",\n            \"in\": \"query\",\n            \"description\": \"How many items to return at one time (max 100)\",\n            \"required\": false,\n            \"schema\": {\n              \"type\": \"integer\",\n              \"format\": \"int32\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"A paged array of pets\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/Pets\"\n                }\n              }\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"operationId\": \"createPets\",\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Null response\"\n          }\n        }\n      }\n    },\n    \"/pets/{petId}\": {\n      \"get\": {\n        \"operationId\": \"showPetById\",\n        \"parameters\": [\n          {\n            \"name\": \"petId\",\n            \"in\": \"path\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Expected response to a valid request\",\n            \"content\": {\n              \"application/json\": {\n                \"schema\": {\n                  \"$ref\": \"#/components/schemas/Pet\"\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  },\n  \"components\": {\n    \"schemas\": {\n      \"Pet\": {\n        \"type\": \"object\",\n        \"required\": [\n          \"id\",\n          \"name\"\n        ],\n        \"properties\": {\n          \"id\": {\n            \"type\": \"integer\",\n            \"format\": \"int64\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"tag\": {\n            \"type\": \"string\"\n          }\n        }\n      },\n      \"Pets\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"$ref\": \"#/components/schemas/Pet\"\n        }\n      }\n    }\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cbr/\u003e\n\n``` js\nconst spec = require('./petstore.json')\nconst OASRequest = require('oas-request')(spec)\n\n// define root server url\nconst request = new OASRequest({\n  server: 'http://petstore.swagger.io/v1'\n})\n\n// or use one from the OpenAPI Specification\nconst request = new OASRequest({\n  server: {\n    url: spec.servers[0].url\n    // populate values for server (see OpenAPI Specification #4.7.5)\n    variables: {\n      version: 'v2'\n    }\n  }\n})\n\n// auto generated methods match OpenAPI Specification \"operationId\"\nawait request.listPets()\nawait request.createPets()\nawait request.showPetById()\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cem\u003eAdvanced Usage\u003c/em\u003e\u003c/summary\u003e\n\n``` js\nconst spec = require('./petstore.json')\nconst OASRequest = require('oas-request')(spec)\n\n// always use JSON headers\nconst request = new OASRequest({\n  server: 'http://petstore.swagger.io/v1'\n  headers: {\n    'accept': 'application/json',\n    'content-type': 'application/json'\n  }\n})\n\n// POST with JSON\nconst body = JSON.stringify(body)\nconst response = await request.createPets({ body })\nconst data = await response.json()\n\nconsole.log(data)\n```\n\n\u003c/details\u003e\n\n### `new OASRequest(APIOptions)`\n\nConstruct a new instance of the API request, returns an Object with auto generated method names matching each of the unique OpenAPI Specification [`operationId`][]\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cem\u003eExample\u003c/em\u003e\u003c/summary\u003e\n\n###### `spec.json`\n\n``` json\n{\n  ...\n  \"paths\": {\n    \"/pets\": {\n      \"get\": {\n        \"operationId\": \"listPets\",\n        ...\n      },\n      \"post\": {\n        \"operationId\": \"createPets\",\n        ...\n      }\n    },\n    \"/pets/{petId}\": {\n      \"get\": {\n        \"operationId\": \"showPetById\",\n        ...\n      }\n    }\n  }\n}\n```\n\n###### `app.js`\n\n``` js\nconst spec = require('./petstore.json')\nconst OASRequest = require('oas-request')(spec)\n\n// define root server url\nconst request = new OASRequest({ server: 'http://petstore.swagger.io/v1' })\n\n// auto generated methods match OpenAPI Specification \"operationId\"\nawait request.listPets()\nawait request.createPets()\nawait request.showPetById()\n```\n\n\u003c/details\u003e\n\n#### `APIOptions`\n\n| property      | type             | required | default           | description                                                             |\n|---------------|------------------|----------|-------------------|-------------------------------------------------------------------------|\n| **`client`**  | `Function`       | ✗        | [`unfetch`][]     | a Function that executes the HTTP request. *(see [`clientFunction`][])* |\n| **`server`**  | `String｜Object` | ✗        | `spec.servers[0]` | Root server url String, or [`Server Object`][]                          |\n| **`headers`** | `Object`         | ✗        | `{}`              | Global HTTP request headers *(used with every request)*                 |\n| **`query`**   | `Object`         | ✗        | `{}`              | Global Query String *(used with every request)*                         |\n| **`params`**  | `Object`         | ✗        | `{}`              | Global [Path Templating][] parameters *(used with every request)*       |\n\n##### `clientFunction`\n\na `Function` with the signature: `Function(url, requestOptions)` to execute the HTTP request, the default built-in function uses [`cross-fetch`][], you can customize the client to use whatever HTTP library you prefer.\n\n\u003e **⚠️ Note**:\n\u003e\n\u003e -   `url` is an instance of [`URL`][]\n\u003e -   `options.query` will be processed to construct the `url`, then deleted.\n\u003e -   `options.params` will be processed and used in Path Templating, then deleted.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cem\u003eExample: always assume JSON\u003c/em\u003e\u003c/summary\u003e\n\n``` js\nconst spec = require('./petstore.json')\nconst fetch = require('cross-fetch')\nconst OASRequest = require('oas-request')(spec)\n\nconst request = new OASRequest({\n  client: async function (url, options) {\n    const response = await fetch(url, {\n      ...options,\n\n      // always set body to JSON\n      body: JSON.stringify(options.body),\n\n      headers: {\n        ...options.headers,\n        // always set headers to JSON\n        ...{\n          'accept': 'application/json',\n          'content-type': 'application/json'\n        }\n      }\n    })\n\n    // always parse body as JSON\n    response.data = await response.json()\n\n    return response\n  }\n})\n\nconst response = await request.createPet({\n  body { \n    id: 1,\n    name: 'Ruby'\n  }\n})\n\nconsole.log(response.data)\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cem\u003eExample: using \u003ccode\u003eaxios\u003c/code\u003e\u003c/summary\u003e\n\n``` js\nconst spec = require('./petstore.json')\nconst axios = require('axios')\nconst OASRequest = require('oas-request')(spec)\n\nconst request = new OASRequest({\n  client: async function (URL, options) {\n    return axios({ \n      ...options, \n      maxRedirects: 10,\n      url: URL.toString(),\n      httpsAgent: new https.Agent({ keepAlive: true })\n    })\n  }\n})\n\nconst response = await request.createPet({\n  data: { \n    id: 1,\n    name: 'Ruby'\n  },\n  timeout: 1000\n})\n```\n\n\u003c/details\u003e\n\n##### `ServerObject`\n\n\u003e ***⚠️ Note**: This is not the same as OpenAPI Specification's [Server Object][], though it's similarly structured*\n\n| property        | type     | required | description                                          |\n|-----------------|----------|----------|------------------------------------------------------|\n| **`url`**       | `String` | ✓        | Root server url                                      |\n| **`variables`** | `Object` | ✗        | Key-value pairs for server URL template substitution |\n\n### `__Operation__(requestOptions)`\n\n-   Operation method names are generated from the unique OpenAPI Specification [`operationId`][]\n-   Operations method will return with a call to the specified [`Client Function`][]\n\n#### `requestOptions`\n\nThe `requestOptions` Objects maps to [Fetch `init` parameter][] with some special considerations:\n\n-   `method` will always be set based on the OpenAPI Specification method for this operation\n-   `query` is a special property used to construct the final URL\n-   `params` is a special property used to construct the final URL Path *(Path Templating)*\n\n## Full Example\n\n``` js\nconst spec = require('./petstore.json')\nconst API = require('oas-request')(spec)\n\n// send to httpbin so we can inspect the result\nconst request = new OASRequest({\n  server: 'http://petstore.swagger.io/v1',\n  headers: {\n    'user-agent': 'my-awsome-api-client',\n    'x-special-header': 'sent-with-every-request'\n  }\n})\n\nawait request.listPets({\n  query: {\n    limit: 100\n  }\n})\n\nawait request.getPetById({\n  params: { petId: 'my-pet' }\n  headers: {\n    'x-additional-header': 'this operation needs this'\n  }\n})\n\nawait request.updatePetById({\n  params: { petId: 'my-pet' },\n  body: {\n    name: \"ruby\",\n    isGoodDog: true\n  }\n})\n```\n\n  [`YAML`]: https://www.npmjs.com/package/yaml\n  [`apidevtools/swagger-cli`]: https://www.npmjs.com/package/@apidevtools/swagger-cli\n  [`cross-fetch`]: https://github.com/lquixada/cross-fetch\n  [`operationId`]: http://spec.openapis.org/oas/v3.0.3#operation-object\n  [`unfetch`]: #clientFunction\n  [`clientFunction`]: #clientfunction\n  [`Server Object`]: #serverobject\n  [Path Templating]: http://spec.openapis.org/oas/v3.0.3#path-templating\n  [`URL`]: https://developer.mozilla.org/en-US/docs/Web/API/URL\n  [Server Object]: http://spec.openapis.org/oas/v3.0.3#server-object\n  [`Client Function`]: clientFunction\n  [Fetch `init` parameter]: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters\n\n----\n\u003e Author: [Ahmad Nassri](https://www.ahmadnassri.com/) \u0026bull;\n\u003e Twitter: [@AhmadNassri](https://twitter.com/AhmadNassri)\n\n[license-url]: LICENSE\n[license-img]: https://badgen.net/github/license/ahmadnassri/node-oas-request\n\n[release-url]: https://github.com/ahmadnassri/node-oas-request/releases\n[release-img]: https://badgen.net/github/release/ahmadnassri/node-oas-request\n\n[semantic-url]: https://github.com/ahmadnassri/node-oas-request/actions?query=workflow%3Arelease\n[semantic-img]: https://badgen.net/badge/📦/semantically%20released/blue\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmadnassri%2Fnode-oas-request","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahmadnassri%2Fnode-oas-request","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmadnassri%2Fnode-oas-request/lists"}