{"id":15286126,"url":"https://github.com/digio/oaat","last_synced_at":"2026-04-28T23:02:36.990Z","repository":{"id":55982435,"uuid":"295313857","full_name":"digio/oaat","owner":"digio","description":"Open API AWS Tool","archived":false,"fork":false,"pushed_at":"2020-12-03T04:23:03.000Z","size":760,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-26T06:54:34.343Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-14T05:33:47.000Z","updated_at":"2020-12-03T04:22:59.000Z","dependencies_parsed_at":"2022-08-15T10:50:12.507Z","dependency_job_id":null,"html_url":"https://github.com/digio/oaat","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digio%2Foaat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digio%2Foaat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digio%2Foaat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digio%2Foaat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digio","download_url":"https://codeload.github.com/digio/oaat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245169889,"owners_count":20571973,"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":[],"created_at":"2024-09-30T15:10:34.819Z","updated_at":"2026-04-28T23:02:31.958Z","avatar_url":"https://github.com/digio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oaat\n\u003e Open API AWS Tool\n\n[![npm package][npm-image]][npm-url]\n[![Build Status][travis-image]][travis-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n[![Downloads][downloads-image]][npm-url]\n\n**O**pen **A**PI-spec **A**WS **t**ool for recording, linting \u0026 comparing API responses; building and deploying a spec to AWS API Gateway.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [Recording](#recording)\n- [Linting](#linting)\n- [Building](#building)\n- [Comparing](#comparing)\n- [Validating](#validating)\n- Deploying (Coming soon)\n- [Config file](#config-file)\n\n## Installation\n\n```\nnpm install -g oaat\n\n# Display help \noaat --help\n```\n\n**Note**: Node 12.3 or higher runtime required.\n\n## Usage\n\nThis tool does 5 things:\n- `oaat record` records API responses to requests specified in `x-examples` fields in an OpenAPI 3.x spec file.\n- `oaat lint` lints an OpenAPI 3.x spec file (basic formatting; tools like [speccy](https://www.npmjs.com/package/speccy) provide more capability, but don't do formatting).\n- `oaat build` creates an OpenAPI 3.x spec file with [API Gateway][api-gateway-url] headers, optionally with mock responses for the APIs.\n- `oaat compare` compares the earlier-recorded responses to the last responses for endpoints in an OpenAPI 3.x spec file.\n- `oaat validate` validates that a spec-file is compliant with the OpenAPI 3.x specification.\n- (Coming soon) `oaat deploy` deploys an OpenAPI 3.x spec file that has the API Gateway headers to API Gateway.\n\n## Recording\n\nThis tool provides the capability to record responses by making requests to the real API endpoints (`oaat record`),\nand optionally use them as mock responses later (`oaat deploy`),\nby reading an Open API spec file (v3.x) in _JSON_ format. \n\n### Command\n\n```shell script\n$ oaat record --help\nUsage: oaat record [options] \u003cjsonFile\u003e [serverUrl]\n\nRecord the responses of API spec file endpoint requests (optionally use a different server to make requests)\n\nOptions:\n  -o, --output \u003cfile\u003e          Output file (if different to jsonFile)\n  -c, --config \u003cfile\u003e          Config file to override default config\n  -s, --sec-tokens \u003ckey=val,\u003e  Pass security token(s) matching the \"key\" in spec.securitySchemes, with a \"value\"\n  -q, --quiet                  No logging\n  -v, --verbose                Verbose logging\n  -d, --dry-run                Dry run (no changes made)\n  -h, --help                   display help for command\n```\n\nTo get valid example responses - to use for mocking \u0026 as documentation - we need to add some custom\nproperties to the OpenAPI spec file.\n\n### `path.method.responses.statusCode[\"x-examples\"]`\n\nThe `x-examples` object is a custom field that allows for the description of multiple examples\nof inputs, and stores the corresponding response (for use in mocks and testing).\n\n`x-examples` is an object, with each child-property being the name of an example. There must be at-least one\nchild-property example-name for `x-examples`.\n\nEach example-object can have the following properties:\n\n- `parameters` - optional\n- `requestBody` - optional\n- `responseFile` - generated when recording a response\n\n#### `x-examples[exampleName].parameters`\n\nThis property is required whenever an API has a non-empty `path.method.parameters` array.\nThe elements in `x-examples[example-name].parameters` correspond to the elements in `parameters`.\nThe order of each `parameters` object is significant.\n\nEach `parameters` object has either a `value` or `script` property:\n\n- `value` can be any data type (string, number, array, object or null)\n- `script` is a reference to a JavaScript file. The JavaScript file must export a function\n  which returns a value which can be used in the corresponding `parameters` argument.\n  The function can be asynchronous. This is useful for situations where an endpoint relies\n  on the result of another endpoint.\n  \n#### `x-examples[exampleName].requestBody`\n\nThis property is required whenever an API has a non-empty `path.method.requestBody` property.\nThe `requestBody` object has either a `value` or `script` property - same as the `x-examples[exampleName].parameters` (above).\n\n#### `x-examples[exampleName].responseFile`\n\nThe `responseFile` property points to a mock-response file.\n\nWhen an API has no parameters, the `responseFile` property is generated for the 200 response automatically.\n**For all other response codes, the `responseFile` property will need to be added\nmanually, along with the mock file for that response.**\n\n#### Example\n\n```json\n\"paths\": {\n  \"/posts/{id}\": {\n    \"post\": {\n      \"tags\": [\"posts\"],\n      \"summary\": \"Get specific post\",\n      \"parameters\": [\n        {\n          \"name\": \"id\",\n          \"in\": \"path\",\n          \"description\": \"The ID of the post to retrieve\",\n          \"required\": true,\n          \"schema\": {\n            \"type\": \"integer\"\n          }\n        }\n      ],\n      \"requestBody\": {\n        \"description\": \"Optional description in *Markdown*\",\n        \"required\": true,\n        \"content\": {\n          \"application/json\": {\n            \"schema\": {\n              \"$ref\": \"#/components/schemas/Pet\" \n            }\n          }\n        }\n      },\n      \"responses\": {\n        \"200\": {\n          \"description\": \"successful operation\",\n          \"content\": {\n            \"*/*\": {\n              \"schema\": {\n                \"$ref\": \"#/components/schemas/Post\"\n              }\n            }\n          },\n          \"x-examples\": {\n            \"id_1\": {\n              \"parameters\": [{ \"value\": \"1\" }],\n              \"requestBody\": { \"script\": \"scripts/getIdFromDatabase.js\" }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nIn the above example, the `POST /posts/{id}` endpoint requires two parameters - a\n`path` parameter (`{id}`) and a `requestBody` parameter. The corresponding\n`x-examples[exampleName]` object has two properties: `parameters`, which uses the `value`\nproperty to specify the `id` parameter; the `requestBody` property uses the `script` property to specify\na JS file which will produce the value for the `requestBody` parameter.\n\nJS script example:\n\n```javascript\nconst queueWrapper = require('../src/queueWrapper');\n\n/**\n * Returns the post data\n * @param {string} serverUrl\n * @param {string} path        E.g. \"/post/{id}\"\n * @return {Promise\u003c*\u003e}\n */\nfunction doAsyncThing({ serverUrl }) {\n  return new Promise(resolve =\u003e {\n    setTimeout(() =\u003e resolve('async value 1'), 100);\n  });\n}\n\nmodule.exports = queueWrapper(doAsyncThing);\n\n```\n\nThe above JavaScript module exports an async function which returns an object asynchronously.\nThe `queueWrapper()` function is there to combine multiple requests into a single request, in scenarios where\nmultiple endpoint-examples require the same async-value. \n\n### Security tokens and headers\n\nAPIs are often protected with security tokens and headers. To call these APIs, the security token can \nbe passed to the command line via `-s securityHeaderType=123someValue,nextToken=nextValue,...`. Alternatively,\nthe security token values can be specified in the `securitySchemes` section of [configuration file](config-file).\nBy default, `securitySchemes` contains no keys.\n\n`oaat` will **always** pick the first security scheme when there are multiple security schemes available for an endpoint.\n\n### Disabling endpoint recording\n\nSometimes it may be necessary to disable the recording of certain endpoints, while keeping the endpoint in the spec.\n\n#### Disable entire endpoint (all responses)\n\nAdd the field `paths[path][method].x-ignore` with a value of `true` to disable the recording (and comparing) of this endpoint. \n\n#### Disable a single endpoint response\n\nAdd the field `paths[path][method].responses[status].x-ignore` with a value of `true` to disable the recording (and comparing) of this endpoint response.\n\n### Ignoring changes to certain fields - `path.method.responses.statusCode[\"x-test-ignore-paths\"]`\n\nThe `x-test-ignore-paths` property is an array of paths (in Lodash path format ([see example](https://lodash.com/docs/4.17.15#zipObjectDeep))) to be **ignored**.\n\nFor example, the `foo.correlationId` property may change in every request. When comparing a new request\nagainst the mock-file, the objects will never match. To overcome this, we can use the `x-test-ignore-paths`\nproperty to ignore this field when comparing the response to the mock-file:\n\n```json\n\"paths\": {\n  \"/foo/bar\": {\n    \"get\": {\n      \"summary\": \"Get foo's bars\",\n      \"produces\": [\"application/json\"],\n      \"parameters\": [],\n      \"responses\": {\n        \"200\": {\n          \"schema\": {\n            \"$ref\": \"#/definitions/Cart\"\n          },\n          \"x-test-ignore-paths\": [\n            \"foo.correlationId\"\n          ]\n        }\n      }\n    }\n  }\n}\n```\n\n## Linting\n\nThere are lots of good tools that can check the syntax and style of Open API Sepc 3.x files:\n\n- [Speccy][speccy-url]\n- [OpenAPI Tools][openapi-tools-url]\n\n`oaat` compliments these tools, as it lints things that the others don't:\n\n- sort `paths` alphabetically (true)\n- sort `components.schemas` alphabetically (true)\n- copy `x-examples` examples into `parameter.examples` and `requestBody.examples`\n\n### Command\n\n```shell script\n$ oaat lint --help\nUsage: oaat lint [options] \u003cjsonFile\u003e [serverUrl]\n\nTidy the API Spec up a bit\n\nOptions:\n  -o, --output \u003cfile\u003e          Output file (if different to jsonFile)\n  -c, --config \u003cfile\u003e          Config file to override default config\n  -s, --sec-tokens \u003ckey=val,\u003e  Pass security token(s) matching the \"key\" in spec.securitySchemes, with a \"value\"\n  -q, --quiet                  no logging\n  -v, --verbose                verbose logging\n  -h, --help                   display help for command\n```\n\nNote: `serverUrl` and `sec-tokens` are only required when the `config.lint.syncExamples` is `true`.\n\nSee the [configuration file](config-file) for further options.\n\n## Building\n\nCreates an OpenAPI 3.x spec file with [API Gateway][api-gateway-url] headers, optionally with mock responses for the APIs.\n\n### Command\n\n```shell script\n$ oaat build --help\nUsage: oaat build [options] \u003cjsonFile\u003e \u003coutputJsonFile\u003e [serverUrl]\n\nAdds custom headers \u0026 Swagger UI endpoint to allow deployment of spec file to AWS API Gateway with documentation\n\nOptions:\n  -c, --config \u003cfile\u003e  Config file to override default config\n  -m, --mock           Uses the recorded responses as mock responses\n  -q, --quiet          No logging\n  -v, --verbose        Verbose logging\n  -d, --dry-run        Dry run (no changes made)\n  -h, --help           display help for command\n```\n\n### Mocking\n\nAPI Gateway supports different kinds of integrations. One integration-type is \"mock\",\nwhereby static responses are returned for any API requests. Mock integrations are useful\nfor testing, documentation, or as a backup for the real API when things go wrong.\n\nTo create mock responses, add the `x-mock-file` property to each endpoint and specify the `-m`\nflag in the command. \n\n\u003e When using the `-m` option, the schema, security and requestBody information is not present in the generated spec file. \n\u003e This is due to limitations within API Gateway's handling of specific Open API Spec 3.x features (removing the schemas\n\u003e makes most of the issues disappear). However, the Swagger UI still loads the original spec file, so that the documentation\n\u003e is correct. \n\n#### `path.method.responses.statusCode[\"x-mock-file\"]`\n\n`x-mock-file` is either a `string` or an `object`, associating an endpoint with a response file.\n  \nWhen `x-mock-file` is a `string`, the value is a path to a response file, and the response-data is used\nregardless of the path-parameters supplied in the request.\n\nWhen `x-mock-file` is an `object`, the property-key is the API-path that is generated, and the value\nis a path to a response file (as above). In this mode, it is possible to generate multiple mock responses\nby specifying multiple API paths as property keys (see example below).\n\n##### Example\n\n```json\n\"paths\": {\n  \"/posts/{id}\": {\n    \"post\": {\n      \"responses\": {\n        \"200\": {\n          \"description\": \"String example\",\n          \"x-mock-file\": \"mock/foo.json\"\n        }\n      }\n    }\n  },\n  \"/users/{id}\": {\n    \"post\": {\n      \"responses\": {\n        \"200\": {\n          \"description\": \"Object example:\",\n          \"x-mock-file\": {\n            \"/users/alexa\": \"mocks/alexa.json\",           \n            \"/users/david\": \"mocks/david.json\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## Comparing\n\nCompares the earlier-recorded responses to the last responses for endpoints in an OpenAPI 3.x spec file.\nThis command can be used to do integration testing, by treating the recorded responses as\nsnapshots, and comparing those to the latest responses.\n\n### Command\n\n```shell script\nUsage: oaat compare [options] \u003cjsonFile\u003e [serverUrl]\n\nCompares recorded responses (referenced by the spec file) to the latest responses\n\nOptions:\n  -c, --config \u003cfile\u003e          Config file to override default config\n  -s, --sec-tokens \u003ckey=val,\u003e  Pass security token(s) matching the \"key\" in spec.securitySchemes, with a \"value\"\n  -m --compare-mode \u003cmode\u003e     Comparison mode: \"value\" (default), \"type\", \"schema\"\n  -q, --quiet                  no logging\n  -v, --verbose                verbose logging\n  -h, --help                   display help for command\n```\n\n## Validating\n\nThis command validates the JSON spec file against the Open API 3.x schema.\nAny errors are listed in the output.  \n\n### Command\n\n```shell script\n$ oaat validate --help\nUsage: oaat validate [options] \u003cjsonFile\u003e\n\nValidate the API spec file against the OAS 3.x schema\n\nOptions:\n  -h, --help  display help for command\n\n```\n\n## Config file\n\noaat has a default configuration which can be overridden using a config file.\nThe config file can be JSON or a CommonJS module which exports an object.\n\nExample:\n``` js\nmodule.exports = {\n  // Shared configuration for all commands\n  global: {\n    // The number of simultaneous requests HTTP requests to make. Increasing this value\n    // can lead to inconsistent results.\n    simultaneousRequests: 15,\n  },\n\n  // Configuration for the `oaat record` command:\n  record: {\n\n    // Path to a subdirectory (relative to the spec file) that contains the response files\n    // If you do not wish to put response files into a subdirectory, removeUnsedResponses is\n    // automatically set to false to avoid deleting files from your specfile folder!\n    responseBasePath: 'responses/',\n\n    // After renaming examples and generating new response files, old response files may no longer\n    // be being used. Set this to true to remove the unused (un-referenced by the spec file) response files. \n    removeUnusedResponses: true,\n\n    // A function to generate the name for each mock file.\n    // This is the default naming function:\n    responseFilenameFn(apiData) {\n      // console.log(apiData);  // Print the apiData structure to see what is available\n      const exampleName =\n        apiData.exampleIndex === 0\n          ? `DEFAULT${apiData.exampleName === 'default' ? '' : `_${apiData.exampleName}`}`\n          : apiData.exampleName;\n      return `${apiData.config.method.toUpperCase()}_${apiData.path.slice(1).replace(/\\//g, '_')}-${\n        apiData.statusCode\n      }_${exampleName}.json`;\n    },\n\n    // Whether to update the response file when the new response is an inexact match.\n    // For example, if a date field in the response is being ignored (because it always changes)\n    // but everything else in the response matches the previous response, should the response\n    // file be updated?\n    updateResponseWhenInexactMatch: true,\n\n    // Whether to update the response file when the new response's data-types match the\n    // old response's data types, but the values are different.\n    updateResponseWhenTypesMatch: true,\n\n    // Lint the spec file as well (true)\n    andLint: true,\n  },\n\n  // Configuration for the `lint` command\n  lint: {\n\n    // Sort the spec file's paths alphabetically (true)\n    sortPathsAlphabetically: true,\n\n    // Sort the spec file's component.schemas alphabetically (true)\n    sortComponentsAlphabetically: true,\n\n    // Updates the parameter and requestBody examples using the x-examples from the 200 response\n    // Requires a API server to be in the spec or specified in the command line if any paramaters come from scripts\n    // Requires config.securitySchemes (or `sec-tokens` on the command line) to be specified if any APIs specify the \"security\" property.\n    syncExamples: true\n  },\n\n  // Configuration for the `build` command\n  build: {\n\n    // The path that will serve the Swagger UI\n    specUIEndpoint: '/',\n\n    // The path that will serve the original spec itself (not the API Gateway version of the spec)\n    specFileEndpoint: '/open-api-spec.json',\n\n    // The value for the \u003ctitle\u003e element \n    webTitle: 'My Company',\n    \n    // A logo for the website (shown in the top-left corner)\n    webLogoUrl: 'https://www.elitedangerous.com/img/logo-elite-dangerous-icon.c7206b1e.svg',\n\n    // A URI (URL or data:image/x-icon;base64 encode image) for the favicon\n    webFaviconHref: 'url or data:image/x-icon;base64',\n  },\n  // If you wish to record your security tokens here, you may.\n  securitySchemes: {\n   schemeName1: { value: 'static value' },\n   schemeName2: { script: 'path/to/script.js' }\n  }\n};\n```\n\n\n---\n\n[npm-image]: https://img.shields.io/npm/v/oaat.svg\n[npm-url]: http://npmjs.org/package/oaat\n[travis-image]: https://travis-ci.org/digio/oaat.svg?branch=master\n[travis-url]: https://travis-ci.org/digio/oaat\n[coveralls-image]: https://coveralls.io/repos/github/digio/oaat/badge.svg?branch=master\n[coveralls-url]: https://coveralls.io/github/digio/oaat?branch=master\n[downloads-image]: https://img.shields.io/npm/dm/oaat.svg\n[api-gateway-url]: https://docs.aws.amazon.com/apigateway/index.html\n[speccy-url]: http://speccy.io/\n[openapi-tools-url]: https://openapi.tools/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigio%2Foaat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigio%2Foaat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigio%2Foaat/lists"}