/
interfaces.js
116 lines (103 loc) · 3.43 KB
/
interfaces.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import pick from 'lodash/pick'
import {eachOperation, opId} from './helpers'
const nullFn = () => null
const normalizeArray = (arg) => {
return Array.isArray(arg) ? arg : [arg]
}
// To allow stubbing of functions
export const self = {
mapTagOperations,
makeExecute
}
// Make an execute, bound to arguments defined in mapTagOperation's callback (cb)
export function makeExecute(swaggerJs = {}) {
return ({pathName, method, operationId}) => (parameters, opts = {}) => {
return swaggerJs.execute({
spec: swaggerJs.spec,
...pick(swaggerJs, 'requestInterceptor', 'responseInterceptor', 'userFetch'),
pathName,
method,
parameters,
operationId,
...opts
})
}
}
// Creates an interface with tags+operations = execute
// The shape
// { apis: { [tag]: { operations: [operation]: { execute }}}}
// NOTE: this is mostly for compatibility
export function makeApisTagOperationsOperationExecute(swaggerJs = {}) {
// { apis: tag: operations: execute }
const cb = self.makeExecute(swaggerJs)
const tagOperations = self.mapTagOperations({
v2OperationIdCompatibilityMode: swaggerJs.v2OperationIdCompatibilityMode,
spec: swaggerJs.spec,
cb,
})
const apis = {}
for (const tag in tagOperations) {
apis[tag] = {
operations: {}
}
for (const op in tagOperations[tag]) {
apis[tag].operations[op] = {execute: tagOperations[tag][op]}
}
}
return {apis}
}
// .apis[tag][operationId]:ExecuteFunction interface
export function makeApisTagOperation(swaggerJs = {}) {
const cb = self.makeExecute(swaggerJs)
return {
apis: self.mapTagOperations({
v2OperationIdCompatibilityMode: swaggerJs.v2OperationIdCompatibilityMode,
spec: swaggerJs.spec,
cb
})
}
}
/**
* Iterates over a spec, creating a hash of {[tag]: { [operationId], ... }, ...}
* with the value of calling `cb`.
*
* `spec` is a OAI v2.0 compliant specification object
* `cb` is called with ({ spec, operation, path, method })
* `defaultTag` will house all non-tagged operations
*
*/
export function mapTagOperations({spec, cb = nullFn, defaultTag = 'default', v2OperationIdCompatibilityMode}) {
const operationIdCounter = {}
const tagOperations = {} // Will house all tags + operations
eachOperation(spec, ({pathName, method, operation}) => {
const tags = operation.tags ? normalizeArray(operation.tags) : [defaultTag]
tags.forEach((tag) => {
if (typeof tag !== 'string') {
return
}
const tagObj = tagOperations[tag] = tagOperations[tag] || {}
const id = opId(operation, pathName, method, {v2OperationIdCompatibilityMode})
const cbResult = cb({spec, pathName, method, operation, operationId: id})
if (operationIdCounter[id]) {
operationIdCounter[id]++
tagObj[`${id}${operationIdCounter[id]}`] = cbResult
}
else if (typeof tagObj[id] !== 'undefined') {
// Bump counter ( for this operationId )
const originalCounterValue = (operationIdCounter[id] || 1)
operationIdCounter[id] = originalCounterValue + 1
// Append _x to the operationId
tagObj[`${id}${operationIdCounter[id]}`] = cbResult
// Rename the first operationId
const temp = tagObj[id]
delete tagObj[id]
tagObj[`${id}${originalCounterValue}`] = temp
}
else {
// Assign callback result ( usually a bound function )
tagObj[id] = cbResult
}
})
})
return tagOperations
}