@bagelink/sdk 0.0.464 → 0.0.471
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +44 -40
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +44 -40
- package/package.json +2 -2
- package/src/index.ts +130 -131
- package/src/openAPITools/functionGenerator.ts +133 -123
- package/src/openAPITools/index.ts +17 -17
- package/src/openAPITools/openApiTypes.ts +38 -38
- package/src/openAPITools/typeGenerator.ts +16 -14
- package/src/openAPITools/utils.ts +46 -46
|
@@ -1,50 +1,58 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
OperationObject,
|
|
3
|
-
|
|
2
|
+
OperationObject,
|
|
3
|
+
ParameterObject,
|
|
4
|
+
PathsObject,
|
|
5
|
+
RequestBodyObject,
|
|
6
|
+
ResponseObject,
|
|
7
|
+
ResponsesObject,
|
|
8
|
+
} from './openApiTypes'
|
|
4
9
|
import {
|
|
5
10
|
cleanPath,
|
|
6
11
|
formatType,
|
|
7
|
-
formatVarType,
|
|
8
|
-
|
|
12
|
+
formatVarType,
|
|
13
|
+
schemaToType,
|
|
14
|
+
toCamelCase,
|
|
15
|
+
toPascalCase,
|
|
16
|
+
} from './utils'
|
|
9
17
|
|
|
10
|
-
const allTypes: string[] = []
|
|
18
|
+
const allTypes: string[] = []
|
|
11
19
|
|
|
12
20
|
function collectTypeForImportStatement(typeName: string) {
|
|
13
|
-
typeName = typeName.trim().replace('[]', '')
|
|
21
|
+
typeName = typeName.trim().replace('[]', '')
|
|
14
22
|
if (typeName.includes('|')) {
|
|
15
23
|
typeName.split('|').forEach(
|
|
16
|
-
(singleType) => collectTypeForImportStatement(singleType),
|
|
17
|
-
)
|
|
18
|
-
return
|
|
24
|
+
(singleType) => { collectTypeForImportStatement(singleType) },
|
|
25
|
+
)
|
|
26
|
+
return
|
|
19
27
|
}
|
|
20
|
-
const primitiveTypes = ['string', 'number', 'boolean', 'null', 'void', 'any', 'Record<string, any>']
|
|
21
|
-
const isPrimitive = primitiveTypes.includes(typeName)
|
|
22
|
-
typeName = formatType(typeName)
|
|
23
|
-
if (!typeName || isPrimitive) return
|
|
24
|
-
if (!allTypes.includes(typeName)) allTypes.push(typeName)
|
|
28
|
+
const primitiveTypes = ['string', 'number', 'boolean', 'null', 'void', 'any', 'Record<string, any>']
|
|
29
|
+
const isPrimitive = primitiveTypes.includes(typeName)
|
|
30
|
+
typeName = formatType(typeName)
|
|
31
|
+
if (!typeName || isPrimitive) return
|
|
32
|
+
if (!allTypes.includes(typeName)) allTypes.push(typeName)
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
function getResponseType(response: ResponseObject): string | null {
|
|
28
|
-
const mediaTypeObject = response.content?.['application/json']
|
|
29
|
-
if (!mediaTypeObject || !mediaTypeObject.schema) return null
|
|
30
|
-
const responseType = schemaToType(mediaTypeObject.schema)
|
|
31
|
-
collectTypeForImportStatement(responseType)
|
|
32
|
-
return responseType
|
|
36
|
+
const mediaTypeObject = response.content?.['application/json']
|
|
37
|
+
if (!mediaTypeObject || !mediaTypeObject.schema) return null
|
|
38
|
+
const responseType = schemaToType(mediaTypeObject.schema)
|
|
39
|
+
collectTypeForImportStatement(responseType)
|
|
40
|
+
return responseType
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
function generateResponseType(responses?: ResponsesObject): string {
|
|
36
|
-
if (!responses) return ''
|
|
37
|
-
const types: string[] = []
|
|
44
|
+
if (!responses) return ''
|
|
45
|
+
const types: string[] = []
|
|
38
46
|
|
|
39
47
|
for (const [statusCode, response] of Object.entries(responses)) {
|
|
40
48
|
if (statusCode.startsWith('2')) {
|
|
41
|
-
const responseType = getResponseType(response)
|
|
49
|
+
const responseType = getResponseType(response)
|
|
42
50
|
if (responseType && responseType !== 'any') {
|
|
43
|
-
types.push(responseType)
|
|
51
|
+
types.push(responseType)
|
|
44
52
|
}
|
|
45
53
|
}
|
|
46
54
|
}
|
|
47
|
-
return types
|
|
55
|
+
return types.join(' | ')
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
/**
|
|
@@ -65,41 +73,41 @@ function generateAxiosFunction(
|
|
|
65
73
|
parameters: any,
|
|
66
74
|
requestBodyPayload: string,
|
|
67
75
|
): string {
|
|
68
|
-
let axiosFunction = `async (${allParams})${responseTypeStr} => axios.${method}(
|
|
69
|
-
const paramStr = parameters?.config?.params ? `, { params: {${parameters.config.params}} }` : ''
|
|
76
|
+
let axiosFunction = `async (${allParams})${responseTypeStr} => axios.${method}(`
|
|
77
|
+
const paramStr = parameters?.config?.params ? `, { params: {${parameters.config.params}} }` : ''
|
|
70
78
|
|
|
71
79
|
if (['get', 'delete'].includes(method)) {
|
|
72
|
-
axiosFunction += `${formattedPath}${paramStr}
|
|
80
|
+
axiosFunction += `${formattedPath}${paramStr}`
|
|
73
81
|
} else if (['post', 'put', 'patch', 'delete'].includes(method)) {
|
|
74
|
-
const bodyVar = requestBodyPayload ? `${requestBodyPayload}` : '{}'
|
|
82
|
+
const bodyVar = requestBodyPayload ? `${requestBodyPayload}` : '{}'
|
|
75
83
|
|
|
76
|
-
axiosFunction += `${formattedPath}, ${bodyVar}${paramStr}
|
|
84
|
+
axiosFunction += `${formattedPath}, ${bodyVar}${paramStr}`
|
|
77
85
|
}
|
|
78
|
-
axiosFunction += ')'
|
|
79
|
-
return axiosFunction
|
|
86
|
+
axiosFunction += ')'
|
|
87
|
+
return axiosFunction
|
|
80
88
|
}
|
|
81
89
|
|
|
82
|
-
const pathParamRegex = /\{([^}]+)\}/g
|
|
83
|
-
|
|
84
|
-
const params = path.match(pathParamRegex)?.map(
|
|
85
|
-
return params
|
|
86
|
-
}
|
|
90
|
+
const pathParamRegex = /\{([^}]+)\}/g
|
|
91
|
+
function getParamsFromPath(path: string) {
|
|
92
|
+
const params = path.match(pathParamRegex)?.map(p => p.slice(1, -1))
|
|
93
|
+
return params
|
|
94
|
+
}
|
|
87
95
|
|
|
88
96
|
function formatPathWithParams(path: string) {
|
|
89
|
-
const params = getParamsFromPath(path)
|
|
90
|
-
const formattedPath = params ? `\`${path.replace(pathParamRegex,
|
|
91
|
-
return formattedPath
|
|
97
|
+
const params = getParamsFromPath(path)
|
|
98
|
+
const formattedPath = params ? `\`${path.replace(pathParamRegex, v => `$${toCamelCase(v)}`)}\`` : `'${path}'`
|
|
99
|
+
return formattedPath
|
|
92
100
|
}
|
|
93
101
|
|
|
94
102
|
function generateRequestBody(requestBody?: RequestBodyObject): Record<string, string> {
|
|
95
|
-
const bodySchema = requestBody?.content
|
|
96
|
-
if (!bodySchema) return { requestBodyParam: '', requestBodyPayload: '' }
|
|
97
|
-
const requestBodyType = schemaToType(bodySchema)
|
|
98
|
-
collectTypeForImportStatement(requestBodyType)
|
|
99
|
-
const requestBodyPayload = toCamelCase(bodySchema
|
|
100
|
-
const defaultValue = requestBody
|
|
101
|
-
const requestBodyParam = formatVarType(requestBodyPayload, bodySchema, defaultValue)
|
|
102
|
-
return { requestBodyParam, requestBodyPayload }
|
|
103
|
+
const bodySchema = requestBody?.content['application/json']?.schema
|
|
104
|
+
if (!bodySchema) return { requestBodyParam: '', requestBodyPayload: '' }
|
|
105
|
+
const requestBodyType = schemaToType(bodySchema)
|
|
106
|
+
collectTypeForImportStatement(requestBodyType)
|
|
107
|
+
const requestBodyPayload = toCamelCase(bodySchema.title) || toCamelCase(requestBodyType) || 'requestBody'
|
|
108
|
+
const defaultValue = requestBody.content['application/json'].schema?.default
|
|
109
|
+
const requestBodyParam = formatVarType(requestBodyPayload, bodySchema, defaultValue)
|
|
110
|
+
return { requestBodyParam, requestBodyPayload }
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
/**
|
|
@@ -109,137 +117,139 @@ function generateRequestBody(requestBody?: RequestBodyObject): Record<string, st
|
|
|
109
117
|
* @returns A string representing all combined parameters.
|
|
110
118
|
*/
|
|
111
119
|
function combineAllParams(parameters: { params?: string }, requestBodyParam: string): string {
|
|
112
|
-
let allParamsArray: string[] = []
|
|
113
|
-
if (parameters && parameters.params) allParamsArray = parameters.params.split(',').map(
|
|
114
|
-
if (requestBodyParam) allParamsArray.push(requestBodyParam.trim())
|
|
120
|
+
let allParamsArray: string[] = []
|
|
121
|
+
if (parameters && parameters.params) allParamsArray = parameters.params.split(',').map(p => p.trim())
|
|
122
|
+
if (requestBodyParam) allParamsArray.push(requestBodyParam.trim())
|
|
115
123
|
|
|
116
124
|
allParamsArray = allParamsArray
|
|
117
|
-
.filter(
|
|
125
|
+
.filter(p => p).sort((a, b) => (a.includes('?') ? 1 : -1) - (b.includes('?') ? 1 : -1))
|
|
118
126
|
|
|
119
|
-
return allParamsArray.join(', ')
|
|
127
|
+
return allParamsArray.join(', ')
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
function generateFunctionParameters(params?: ParameterObject[]) {
|
|
123
|
-
if (!params || params.length === 0) return {}
|
|
131
|
+
if (!params || params.length === 0) return {}
|
|
124
132
|
|
|
125
|
-
const functionParams: string[] = []
|
|
126
|
-
const paramList: string[] = []
|
|
133
|
+
const functionParams: string[] = []
|
|
134
|
+
const paramList: string[] = []
|
|
127
135
|
|
|
128
136
|
for (const param of params) {
|
|
129
|
-
const paramType = schemaToType(param.schema)
|
|
130
|
-
collectTypeForImportStatement(paramType)
|
|
131
|
-
const paramName = param.name
|
|
132
|
-
const varName = toCamelCase(param.name) || 'param'
|
|
137
|
+
const paramType = schemaToType(param.schema)
|
|
138
|
+
collectTypeForImportStatement(paramType)
|
|
139
|
+
const paramName = param.name
|
|
140
|
+
const varName = toCamelCase(param.name) || 'param'
|
|
133
141
|
if (param.in === 'path' || param.in === 'query' || param.in === 'header') {
|
|
134
|
-
const defaultValue = param
|
|
135
|
-
const varType = formatVarType(varName, param.schema, param.required, defaultValue)
|
|
136
|
-
functionParams.push(varType)
|
|
142
|
+
const defaultValue = param.schema.default
|
|
143
|
+
const varType = formatVarType(varName, param.schema, param.required, defaultValue)
|
|
144
|
+
functionParams.push(varType)
|
|
137
145
|
}
|
|
138
146
|
if (param.in === 'query' || param.in === 'header') {
|
|
139
|
-
if (paramName === varName) paramList.push(paramName)
|
|
140
|
-
else paramList.push(`'${paramName}': ${varName}`)
|
|
147
|
+
if (paramName === varName) paramList.push(paramName)
|
|
148
|
+
else paramList.push(`'${paramName}': ${varName}`)
|
|
141
149
|
}
|
|
142
150
|
}
|
|
143
151
|
|
|
144
|
-
const paramsString = functionParams.join(', ')
|
|
145
|
-
const config: { params?: string } = {}
|
|
152
|
+
const paramsString = functionParams.join(', ')
|
|
153
|
+
const config: { params?: string } = {}
|
|
146
154
|
|
|
147
|
-
if (paramList.length > 0) config.params = paramList.join(', ')
|
|
148
|
-
return { params: paramsString, config }
|
|
155
|
+
if (paramList.length > 0) config.params = paramList.join(', ')
|
|
156
|
+
return { params: paramsString, config }
|
|
149
157
|
}
|
|
150
158
|
|
|
151
159
|
function generateFunctionForOperation(method: string, path: string, operation: OperationObject): string {
|
|
152
|
-
if (!operation) return ''
|
|
153
|
-
const parameters = generateFunctionParameters(operation.parameters)
|
|
154
|
-
const responseType = generateResponseType(operation.responses)
|
|
155
|
-
const formattedPath = formatPathWithParams(path)
|
|
156
|
-
const { requestBodyParam, requestBodyPayload } = generateRequestBody(operation.requestBody)
|
|
157
|
-
const allParams = combineAllParams(parameters, requestBodyParam)
|
|
158
|
-
const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : ''
|
|
159
|
-
return generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload)
|
|
160
|
+
if (!operation) return ''
|
|
161
|
+
const parameters = generateFunctionParameters(operation.parameters)
|
|
162
|
+
const responseType = generateResponseType(operation.responses)
|
|
163
|
+
const formattedPath = formatPathWithParams(path)
|
|
164
|
+
const { requestBodyParam, requestBodyPayload } = generateRequestBody(operation.requestBody)
|
|
165
|
+
const allParams = combineAllParams(parameters, requestBodyParam)
|
|
166
|
+
const responseTypeStr = responseType ? `: Promise<AxiosResponse<${responseType}>>` : ''
|
|
167
|
+
return generateAxiosFunction(method, formattedPath, allParams, responseTypeStr, parameters, requestBodyPayload)
|
|
160
168
|
}
|
|
161
169
|
|
|
162
|
-
const generateRandomString = () => Math.random().toString(36).substring(7)
|
|
170
|
+
const generateRandomString = () => Math.random().toString(36).substring(7)
|
|
163
171
|
|
|
164
172
|
function fileTemplate(tsString: string, typeForImport: string[], baseURL: string) {
|
|
165
173
|
const templateCode = (
|
|
166
|
-
`import
|
|
174
|
+
`import ax from 'axios';
|
|
167
175
|
import type { AxiosResponse } from 'axios';
|
|
168
176
|
import type {${typeForImport.join(', ')}} from './types.d';
|
|
169
177
|
|
|
170
178
|
const axios = ax.create({baseURL:${baseURL}});
|
|
171
179
|
${tsString}`
|
|
172
|
-
)
|
|
173
|
-
const doubleQuoteRegex = /"([^"]+)":/g
|
|
174
|
-
return templateCode.replace(doubleQuoteRegex, '$1:')
|
|
180
|
+
)
|
|
181
|
+
const doubleQuoteRegex = /"([^"]+)":/g
|
|
182
|
+
return templateCode.replace(doubleQuoteRegex, '$1:')
|
|
175
183
|
}
|
|
176
184
|
|
|
177
|
-
const functionsInventory: Record<string, any> = {}
|
|
178
|
-
const pathOperations: any[] = []
|
|
185
|
+
const functionsInventory: Record<string, any> = {}
|
|
186
|
+
const pathOperations: any[] = []
|
|
179
187
|
|
|
180
|
-
|
|
181
|
-
const cleanPathName = path.split('/').filter(
|
|
182
|
-
const matchingPaths = pathOperations.filter(
|
|
183
|
-
pathOperations.push({ path: cleanPathName, method })
|
|
184
|
-
return matchingPaths.length > 0
|
|
185
|
-
}
|
|
188
|
+
function hasConflict(path: string, method: string) {
|
|
189
|
+
const cleanPathName = path.split('/').filter(p => p && !p.match(/\{|\}/)).join('/')
|
|
190
|
+
const matchingPaths = pathOperations.filter(p => p.path === cleanPathName && p.method === method)
|
|
191
|
+
pathOperations.push({ path: cleanPathName, method })
|
|
192
|
+
return matchingPaths.length > 0
|
|
193
|
+
}
|
|
186
194
|
|
|
187
195
|
// Creates a placeholder for a function and stores its body in the inventory
|
|
188
|
-
|
|
189
|
-
const funcID = generateRandomString()
|
|
190
|
-
functionsInventory[funcID] = generateFunctionForOperation(method, path, operation)
|
|
191
|
-
return funcID
|
|
192
|
-
}
|
|
196
|
+
function createFunctionPlaceholder(path: string, method: string, operation: any) {
|
|
197
|
+
const funcID = generateRandomString()
|
|
198
|
+
functionsInventory[funcID] = generateFunctionForOperation(method, path, operation)
|
|
199
|
+
return funcID
|
|
200
|
+
}
|
|
193
201
|
|
|
194
202
|
function handlePathSegment(
|
|
195
203
|
path: string,
|
|
196
204
|
operation: any,
|
|
197
205
|
existingObj: Record<string, any> | null = null,
|
|
198
206
|
) {
|
|
199
|
-
const methods = Object.keys(operation)
|
|
200
|
-
const obj: Record<string, any> = {}
|
|
207
|
+
const methods = Object.keys(operation)
|
|
208
|
+
const obj: Record<string, any> = {}
|
|
201
209
|
for (const method of methods) {
|
|
202
|
-
let functionName = method.toLowerCase()
|
|
210
|
+
let functionName = method.toLowerCase()
|
|
203
211
|
if (hasConflict(path, method)) {
|
|
204
|
-
const params: string[] | undefined = getParamsFromPath(path)
|
|
205
|
-
functionName += (params ? `By${toPascalCase(params
|
|
212
|
+
const params: string[] | undefined = getParamsFromPath(path)
|
|
213
|
+
functionName += (params ? `By${toPascalCase(params.pop() || '')}` : 'All')
|
|
206
214
|
}
|
|
207
|
-
obj[functionName] = createFunctionPlaceholder(path, method, operation[method])
|
|
215
|
+
obj[functionName] = createFunctionPlaceholder(path, method, operation[method])
|
|
208
216
|
}
|
|
209
|
-
return { ...obj, ...existingObj }
|
|
217
|
+
return { ...obj, ...existingObj }
|
|
210
218
|
}
|
|
211
219
|
|
|
212
220
|
export function generateFunctions(paths: PathsObject, baseURL: string) {
|
|
213
|
-
let tsString = ''
|
|
214
|
-
const body: Record<string, any> = {}
|
|
215
|
-
const allPathsClean = Object.keys(paths).map(cleanPath)
|
|
221
|
+
let tsString = ''
|
|
222
|
+
const body: Record<string, any> = {}
|
|
223
|
+
const allPathsClean = Object.keys(paths).map(cleanPath)
|
|
216
224
|
for (const [path, operation] of Object.entries(paths)) {
|
|
217
|
-
const splitPath = path.split('/').filter(
|
|
225
|
+
const splitPath = path.split('/').filter(p => p && !p.match(/\{|\}/))
|
|
218
226
|
splitPath.reduce((acc, key: string, index: number, array: string[]) => {
|
|
219
|
-
const objFuncKey = toCamelCase(key)
|
|
220
|
-
if (!objFuncKey) return acc
|
|
221
|
-
const methods = Object.keys(operation)
|
|
227
|
+
const objFuncKey = toCamelCase(key)
|
|
228
|
+
if (!objFuncKey) return acc
|
|
229
|
+
const methods = Object.keys(operation)
|
|
222
230
|
if (
|
|
223
|
-
index === array.length - 1
|
|
224
|
-
methods.length === 1
|
|
225
|
-
allPathsClean.filter(
|
|
231
|
+
index === array.length - 1
|
|
232
|
+
&& methods.length === 1
|
|
233
|
+
&& allPathsClean.filter(p => p === cleanPath(path)).length === 1
|
|
226
234
|
) {
|
|
227
|
-
const method: string = methods[0]
|
|
228
|
-
const opp: any = { ...operation }[method]
|
|
229
|
-
acc[objFuncKey] = createFunctionPlaceholder(path, methods[0], opp)
|
|
235
|
+
const method: string = methods[0]
|
|
236
|
+
const opp: any = { ...operation }[method]
|
|
237
|
+
acc[objFuncKey] = createFunctionPlaceholder(path, methods[0], opp)
|
|
230
238
|
} else if (
|
|
231
239
|
index === array.length - 1
|
|
232
|
-
) acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey])
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
) { acc[objFuncKey] = handlePathSegment(path, operation, acc[objFuncKey])
|
|
241
|
+
}
|
|
242
|
+
else if (!acc[objFuncKey] || typeof acc[objFuncKey] !== 'object') { acc[objFuncKey] = {}
|
|
243
|
+
}
|
|
244
|
+
return acc[objFuncKey]
|
|
245
|
+
}, body)
|
|
236
246
|
}
|
|
237
247
|
for (const [parent, object] of Object.entries(body)) {
|
|
238
|
-
tsString += `export const ${parent} = ${JSON.stringify(object, null, 2)};\n
|
|
248
|
+
tsString += `export const ${parent} = ${JSON.stringify(object, null, 2)};\n`
|
|
239
249
|
}
|
|
240
250
|
Object.entries(functionsInventory).forEach(([key, value]) => {
|
|
241
|
-
tsString = tsString.replace(`"${key}"`, value)
|
|
242
|
-
})
|
|
243
|
-
tsString = fileTemplate(tsString, allTypes, baseURL)
|
|
244
|
-
return tsString
|
|
251
|
+
tsString = tsString.replace(`"${key}"`, value)
|
|
252
|
+
})
|
|
253
|
+
tsString = fileTemplate(tsString, allTypes, baseURL)
|
|
254
|
+
return tsString
|
|
245
255
|
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import axios from 'axios'
|
|
2
|
-
import type { OpenAPIDocument } from './openApiTypes'
|
|
3
|
-
import { generateTypes } from './typeGenerator'
|
|
4
|
-
import { generateFunctions } from './functionGenerator'
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import type { OpenAPIDocument } from './openApiTypes'
|
|
3
|
+
import { generateTypes } from './typeGenerator'
|
|
4
|
+
import { generateFunctions } from './functionGenerator'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
types: string
|
|
8
|
-
code: string
|
|
6
|
+
interface OpenAPIResponse {
|
|
7
|
+
types: string
|
|
8
|
+
code: string
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export default async (openApiUrl: string, baseURL: string): Promise<OpenAPIResponse> => {
|
|
12
12
|
try {
|
|
13
|
-
const { data: openApi } = await axios.get<OpenAPIDocument>(openApiUrl)
|
|
14
|
-
const schemas = openApi.components?.schemas
|
|
15
|
-
if (!schemas) throw new Error('No schemas found in OpenAPI document')
|
|
16
|
-
const types = generateTypes(schemas)
|
|
13
|
+
const { data: openApi } = await axios.get<OpenAPIDocument>(openApiUrl)
|
|
14
|
+
const schemas = openApi.components?.schemas
|
|
15
|
+
if (!schemas) throw new Error('No schemas found in OpenAPI document')
|
|
16
|
+
const types = generateTypes(schemas)
|
|
17
17
|
// Generate Functions
|
|
18
|
-
const { paths } = openApi
|
|
19
|
-
if (!paths) throw new Error('No paths found in OpenAPI document')
|
|
20
|
-
const code = generateFunctions(paths, baseURL)
|
|
21
|
-
return { types, code }
|
|
18
|
+
const { paths } = openApi
|
|
19
|
+
if (!paths) throw new Error('No paths found in OpenAPI document')
|
|
20
|
+
const code = generateFunctions(paths, baseURL) // TODO baseURL should not be set here, but should be instatiated in runtime somehow
|
|
21
|
+
return { types, code }
|
|
22
22
|
} catch (error: any) {
|
|
23
|
-
throw new Error(error)
|
|
23
|
+
throw new Error(error)
|
|
24
24
|
}
|
|
25
|
-
}
|
|
25
|
+
}
|
|
@@ -1,70 +1,70 @@
|
|
|
1
1
|
export interface OpenAPIDocument {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
openapi: string
|
|
3
|
+
info: InfoObject
|
|
4
|
+
paths: PathsObject
|
|
5
|
+
components?: ComponentsObject
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export
|
|
8
|
+
export interface PathsObject { [path: string]: PathItemObject }
|
|
9
9
|
|
|
10
10
|
export interface InfoObject {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
title: string
|
|
12
|
+
version: string
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface PathItemObject {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
get?: OperationObject
|
|
17
|
+
put?: OperationObject
|
|
18
|
+
post?: OperationObject
|
|
19
|
+
delete?: OperationObject
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export
|
|
22
|
+
export interface SchemasObject { [schema: string]: SchemaObject }
|
|
23
23
|
|
|
24
24
|
export interface ComponentsObject {
|
|
25
|
-
|
|
25
|
+
schemas?: SchemasObject
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export interface OperationObject {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
summary?: string
|
|
30
|
+
operationId?: string
|
|
31
|
+
parameters?: ParameterObject[]
|
|
32
|
+
requestBody?: RequestBodyObject
|
|
33
|
+
responses: ResponsesObject
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export
|
|
36
|
+
export interface ResponsesObject { [statusCode: string]: ResponseObject }
|
|
37
37
|
|
|
38
38
|
export interface SchemaObject {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
type?: string
|
|
40
|
+
properties?: { [property: string]: SchemaObject }
|
|
41
|
+
items?: SchemaObject
|
|
42
|
+
$ref?: string
|
|
43
|
+
enum: string[]
|
|
44
|
+
anyOf?: SchemaObject[]
|
|
45
|
+
allOf?: SchemaObject[]
|
|
46
|
+
title?: string
|
|
47
|
+
description?: string
|
|
48
|
+
default: any
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export interface ParameterObject {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
name: string
|
|
53
|
+
in: string
|
|
54
|
+
schema: SchemaObject
|
|
55
|
+
required?: boolean
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export interface RequestBodyObject {
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
description?: string
|
|
60
|
+
content: { [mediaType: string]: MediaTypeObject }
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export interface ResponseObject {
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
description: string
|
|
65
|
+
content?: { [mediaType: string]: MediaTypeObject }
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export interface MediaTypeObject {
|
|
69
|
-
|
|
69
|
+
schema?: SchemaObject
|
|
70
70
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import { formatType, formatVarType } from './utils'
|
|
2
|
-
import type { SchemasObject } from './openApiTypes'
|
|
1
|
+
import { formatType, formatVarType } from './utils'
|
|
2
|
+
import type { SchemasObject } from './openApiTypes'
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
export function generateTypes(schemas: SchemasObject): string {
|
|
5
|
+
return Object.entries(schemas).map(([typeName, schema]) => {
|
|
6
|
+
typeName = formatType(typeName)
|
|
7
|
+
if (schema.enum) {
|
|
8
|
+
return `export type ${typeName} = ${schema.enum.map((item: string) => `'${item}'`).join(' | ')};\n`
|
|
9
|
+
}
|
|
10
|
+
if (!schema.properties) return ''
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
const properties = Object.entries(schema.properties).map(([key, value]) => {
|
|
13
|
+
const varType = formatVarType(key, value)
|
|
14
|
+
return `\t\t${varType}`
|
|
15
|
+
}).join(';\n ')
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
}).join('\n')
|
|
17
|
+
return `export type ${typeName} = {\n ${properties};\n };\n`
|
|
18
|
+
}).join('\n')
|
|
19
|
+
}
|