Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

feat: adding support for server variables into oas-to-har #1241

Merged
merged 1 commit into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 134 additions & 94 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@readme/emojis": "^3.0.0",
"@readme/ui": "^1.17.8",
"babel-polyfill": "^6.26.0",
"oas": "^10.2.0",
"oas": "^10.4.0",
"prop-types": "^15.7.2",
"react-hot-loader": "^4.12.16",
"swagger2openapi": "^7.0.0",
Expand Down
1,914 changes: 1,914 additions & 0 deletions packages/api-explorer/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/api-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"js-cookie": "^2.1.4",
"lodash.clonedeep": "^4.5.0",
"lodash.kebabcase": "^4.1.1",
"oas": "^10.2.0",
"oas": "^10.4.0",
"prop-types": "^15.7.2",
"react-copy-to-clipboard": "^5.0.1",
"react-debounce-input": "^3.2.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/oas-extensions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 17 additions & 2 deletions packages/oas-to-har/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @readme/oas-to-har

Utility to transform an OAS operation into a HAR representation
Utility to transform an OAS operation into a [HAR](http://www.softwareishard.com/blog/har-12-spec/) representation

[![Build](https://github.com/readmeio/api-explorer/workflows/CI/badge.svg)](https://github.com/readmeio/api-explorer/tree/master/packages/oas-to-har)

Expand All @@ -19,9 +19,24 @@ const Oas = require('oas/tooling');
const oasToHar = require('@readme/oas-to-har');

const spec = new Oas('petstore.json');
console.log(oasToHar(spec));
console.log(oasToHar(spec, { path: '/pets', method: 'post'}));
```

### `oasToHar(har, operationSchema, values, auth, opts) => Object`

- `oas` *{Oas}*: Instance of our [oas/tooling](https://npm.im/oas) class.
- `operationSchema` *{Object\|Operation}*: Can either be an object with `path` and `method` properties (that exist in the supplied OAS), or an instance of our `Operation` class from [oas/tooling](https://npm.im/oas) - accessed through `new Oas(spec).operation(path, method)`.
- `values` *{Object}*: A object of payload data, with key-value data therein, that should be used to construct the request. Available data you can define here:
- `path`
- `query`
- `body`
- `cookie`
- `formData`
- `header`
- `server` — If the supplied OAS has multiple severs or server variables you can use this to set which server and variables to use. Shape of it should be: `{ selected: Integer, variables: { ...key-values }}`. `selected` should coorespond to index of the `servers` array in your OAS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mdash 👏

- `auth` *{Object}*: Authentication information for the request.
- `opts.proxyUrl` *{Boolean}*: Boolean to toggle if composed HAR objects should have their `url` be sent through our CORS-friendly proxy. Defaults to `false`.

## Credits
[Jon Ursenbach](https://github.com/erunion)

Expand Down
46 changes: 46 additions & 0 deletions packages/oas-to-har/__tests__/__fixtures__/server-variables.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"openapi": "3.0.3",
"info": {
"version": "1.0.0",
"title": "Server variables"
},
"servers": [
{
"url": "https://{name}.example.com:{port}/{basePath}",
"variables": {
"name": {
"default": "demo"
},
"port": {
"default": "443"
},
"basePath": {
"default": "v2"
}
}
},
{
"url": "http://{name}.local/{basePath}",
"variables": {
"name": {
"default": "demo"
},
"basePath": {
"default": "v2"
}
}
}
],
"paths": {
"/": {
"post": {
"summary": "Should fetch variables from defaults and user values",
"responses": {
"200": {
"description": "OK"
}
}
}
}
}
}
58 changes: 58 additions & 0 deletions packages/oas-to-har/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const oasToHar = require('../src/index');
const commonParameters = require('./__fixtures__/common-parameters.json');
const multipartFormData = require('./__fixtures__/multipart-form-data.json');
const multipartFormDataArrayOfFiles = require('./__fixtures__/multipart-form-data/array-of-files.json');
const serverVariables = require('./__fixtures__/server-variables.json');

const oas = new Oas();

Expand Down Expand Up @@ -53,6 +54,63 @@ describe('url', () => {
);
});

describe('server variables', () => {
const variablesOas = new Oas(serverVariables);
const operation = variablesOas.operation('/', 'post');

it('should use defaults if not supplied', () => {
const har = oasToHar(variablesOas, operation, {});
expect(har.log.entries[0].request.url).toBe('https://demo.example.com:443/v2/');
});

it('should support server variables', () => {
const formData = {
server: {
selected: 0,
variables: { name: 'buster', port: 8080, basePath: 'v2.1' },
},
};

const har = oasToHar(variablesOas, operation, formData);
expect(har.log.entries[0].request.url).toBe('https://buster.example.com:8080/v2.1/');
});

it('should support multiple/alternate servers', () => {
const formData = {
server: {
selected: 1,
variables: { name: 'buster', port: 8080, basePath: 'v2.1' },
},
};

const har = oasToHar(variablesOas, operation, formData);
expect(har.log.entries[0].request.url).toBe('http://buster.local/v2.1/');
});

it('should not error if the selected server does not exist', () => {
const formData = {
server: {
selected: 3,
},
};

const har = oasToHar(variablesOas, operation, formData);
expect(har.log.entries[0].request.url).toBe('https://example.com/');
});

it('should fill in missing variables with their defaults', () => {
const formData = {
server: {
selected: 0,
variables: { name: 'buster' }, // `port` and `basePath` are missing
},
};

const har = oasToHar(variablesOas, operation, formData);
expect(har.log.entries[0].request.url).toBe('https://buster.example.com:443/v2/');
});
});

describe('proxy url', () => {
const proxyOas = new Oas({
[extensions.PROXY_ENABLED]: true,
Expand Down
24 changes: 12 additions & 12 deletions packages/oas-to-har/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/oas-to-har/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
},
"dependencies": {
"@readme/oas-extensions": "^13.1.0",
"oas": "^10.2.0",
"oas": "^10.4.0",
"parse-data-url": "^3.0.0"
},
"devDependencies": {
Expand Down
18 changes: 16 additions & 2 deletions packages/oas-to-har/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,21 @@ module.exports = (
operation = new Operation(oas, operationSchema.path, operationSchema.method, operationSchema);
}

const formData = { ...defaultFormDataTypes, ...values };
const formData = {
...defaultFormDataTypes,
server: {
selected: 0,
variables: oas.defaultVariables(0),
},
...values,
};

// If the incoming `server.variables` is missing variables let's pad it out with defaults.
formData.server.variables = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we just move up into the object above or was this done to improve readability?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I'm loading values in as ...values above I don't have a clean way to re-fill server.variables with defaults if they're missing in the block above this.

...oas.defaultVariables(formData.server.selected),
...formData.server.variables,
};

const har = {
cookies: [],
headers: [],
Expand All @@ -106,7 +120,7 @@ module.exports = (
postData: {},
bodySize: 0,
method: operation.method.toUpperCase(),
url: `${oas.url()}${operation.path}`.replace(/\s/g, '%20'),
url: `${oas.url(formData.server.selected, formData.server.variables)}${operation.path}`.replace(/\s/g, '%20'),
httpVersion: 'HTTP/1.1',
};

Expand Down
24 changes: 12 additions & 12 deletions packages/oas-to-snippet/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/oas-to-snippet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"@readme/oas-to-har": "^13.1.0",
"@readme/syntax-highlighter": "^10.4.1",
"httpsnippet-client-api": "^3.0.0",
"oas": "^10.2.0"
"oas": "^10.4.0"
},
"devDependencies": {
"@readme/eslint-config": "^4.0.0",
Expand Down