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

Improve OpenAPI logic #66

Merged
merged 1 commit into from
Oct 4, 2019
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
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const client = new NetlifyAPI('1234myAccessToken')
const sites = await client.listSites()
```

## Using Open API methods
## Using Open API operations

```js
const NetlifyAPI = require('netlify')
Expand Down Expand Up @@ -67,9 +67,9 @@ A getter that returns the formatted base URL of the endpoint the client is confi

### Open API Client methods

The client is dynamically generated from the [open-api](https://github.com/netlify/open-api) definition file. Each method is is named after the `operationId` name of each endpoint action. **To see list of available operations see the [open-api website](https://open-api.netlify.com/)**.
The client is dynamically generated from the [open-api](https://github.com/netlify/open-api) definition file. Each method is is named after the `operationId` name of each operation. **To see list of available operations see the [open-api website](https://open-api.netlify.com/)**.

Every open-api method has the following signature:
Every open-api operation has the following signature:

#### `promise(response) = client.operationId([params], [opts])`

Expand Down Expand Up @@ -103,7 +103,7 @@ Optional `opts` can include any property you want passed to `node-fetch`. The `h
}
```

All methods are conveniently consumed with async/await:
All operations are conveniently consumed with async/await:

```js
async function getSomeData() {
Expand All @@ -123,7 +123,7 @@ If the request response includes `json` in the `contentType` header, fetch will

### API Flow Methods

Some methods have been added in addition to the open API methods that make certain actions simpler to perform.
Some methods have been added in addition to the open API operations that make certain actions simpler to perform.

#### `promise(accessToken) = client.getAccessToken(ticket, [opts])`

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"lodash.set": "^4.3.2",
"micro-api-client": "^3.3.0",
"node-fetch": "^2.2.0",
"omit.js": "^1.0.2",
"p-map": "^2.1.0",
"p-wait-for": "^2.0.0",
"parallel-transform": "^1.1.0",
Expand Down
10 changes: 6 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const dfn = require('@netlify/open-api')
const pWaitFor = require('p-wait-for')
const debug = require('debug')('netlify')

const { methods, generateMethod } = require('./open-api')
const { generateOperation } = require('./open-api')
const { getOperations } = require('./operations')
const deploy = require('./deploy')

class NetlifyAPI {
Expand Down Expand Up @@ -107,12 +108,13 @@ class NetlifyAPI {
}
}

methods.forEach(method => {
const operations = getOperations()
operations.forEach(operation => {
// Generate open-api methods
/* {param1, param2, body, ... }, [opts] */
NetlifyAPI.prototype[method.operationId] = generateMethod(method)
NetlifyAPI.prototype[operation.operationId] = generateOperation(operation)
})

module.exports = NetlifyAPI

module.exports.methods = methods
module.exports.methods = operations
24 changes: 13 additions & 11 deletions src/open-api/index.js → src/open-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,20 @@ const { JSONHTTPError, TextHTTPError } = require('micro-api-client')
const debug = require('debug')('netlify:open-api')
const isStream = require('is-stream')

const { sleep, unixNow } = require('./util')

exports.methods = require('./shape-swagger')

// open-api 2.0
exports.generateMethod = method => {
const generateOperation = function(operation) {
//
// Warning: Expects `this`. These methods expect to live on the client prototype
//
return async function(params, opts) {
opts = Object.assign({}, opts)
params = Object.assign({}, this.globalParams, params)

let path = this.basePath + method.path
let path = this.basePath + operation.path
debug(`path template: ${path}`)

// Path parameters
Object.values(method.parameters.path).forEach(param => {
Object.values(operation.parameters.path).forEach(param => {
const val = params[param.name] || params[camelCase(param.name)]
if (val != null) {
path = path.replace(`{${param.name}}`, val)
Expand All @@ -39,7 +35,7 @@ exports.generateMethod = method => {

// qs parameters
let qs
Object.values(method.parameters.query).forEach(param => {
Object.values(operation.parameters.query).forEach(param => {
const val = params[param.name] || params[camelCase(param.name)]
if (val != null) {
if (!qs) qs = {}
Expand All @@ -58,7 +54,7 @@ exports.generateMethod = method => {
let bodyType = 'json'
if (params.body) {
body = params.body
Object.values(method.parameters.body).forEach(param => {
Object.values(operation.parameters.body).forEach(param => {
const type = get(param, 'schema.format')
if (type === 'binary') {
bodyType = 'binary'
Expand Down Expand Up @@ -86,8 +82,8 @@ exports.generateMethod = method => {
debug('specialHeaders: %O', specialHeaders)

opts.headers = new Headers(Object.assign({}, this.defaultHeaders, specialHeaders, opts.headers))
opts.method = method.verb.toUpperCase()
debug(`method: ${opts.method}`)
opts.method = operation.verb.toUpperCase()
debug(`HTTP method: ${opts.method}`)

// TODO: Consider using micro-api-client when it supports node-fetch

Expand Down Expand Up @@ -171,3 +167,9 @@ exports.generateMethod = method => {
return text
}
}

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

const unixNow = () => Math.floor(new Date() / 1000)

module.exports = { generateOperation }
7 changes: 0 additions & 7 deletions src/open-api/index.test.js

This file was deleted.

Binary file removed src/open-api/index.test.js.snap
Binary file not shown.
29 changes: 0 additions & 29 deletions src/open-api/shape-swagger.js

This file was deleted.

36 changes: 0 additions & 36 deletions src/open-api/util.js

This file was deleted.

28 changes: 28 additions & 0 deletions src/operations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const { paths } = require('@netlify/open-api')
const omit = require('omit.js')

// Retrieve all OpenAPI operations
const getOperations = function() {
return [].concat(
...Object.entries(paths).map(([path, pathItem]) => {
const operations = omit(pathItem, ['parameters'])
return Object.entries(operations).map(([method, operation]) => {
const parameters = getParameters(pathItem.parameters, operation.parameters)
return Object.assign({}, operation, { verb: method, path, parameters })
})
})
)
}

const getParameters = function(pathParameters = [], operationParameters = []) {
const parameters = [...pathParameters, ...operationParameters]
return parameters.reduce(addParameter, { path: {}, query: {}, body: {} })
}

const addParameter = function(parameters, param) {
return Object.assign({}, parameters, {
[param.in]: Object.assign({}, parameters[param.in], { [param.name]: param })
})
}

module.exports = { getOperations }
7 changes: 7 additions & 0 deletions src/operations.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const test = require('ava')

const { getOperations } = require('./operations')

test('Exported methods', t => {
t.snapshot(getOperations())
})
Loading