fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 168 lines 4.1 kB view raw
1import type { Context } from '../../../ir/context'; 2import type { IR } from '../../../ir/types'; 3import type { 4 OperationObject, 5 ParameterObject, 6 ReferenceObject, 7 SchemaObject, 8} from '../types/spec'; 9import { paginationField } from './pagination'; 10import { parseExtensions, schemaToIrSchema } from './schema'; 11 12type Parameter = Exclude<ParameterObject, { in: 'body' }>; 13 14/** 15 * Returns default parameter `explode` based on value of `collectionFormat`. 16 */ 17const defaultExplode = (collectionFormat: Parameter['collectionFormat']): boolean => { 18 switch (collectionFormat) { 19 case 'multi': 20 return true; 21 case 'csv': 22 case 'pipes': 23 case 'ssv': 24 case 'tsv': 25 default: 26 return false; 27 } 28}; 29 30/** 31 * Returns default parameter `style` based on value of `in`. 32 */ 33const defaultStyle = (_in: Parameter['in']): Required<IR.ParameterObject>['style'] => { 34 switch (_in) { 35 case 'header': 36 case 'path': 37 return 'simple'; 38 case 'query': 39 default: 40 return 'form'; 41 } 42}; 43 44export const parametersArrayToObject = ({ 45 context, 46 operation, 47 parameters, 48}: { 49 context: Context; 50 operation: OperationObject; 51 parameters?: ReadonlyArray<ParameterObject | ReferenceObject>; 52}): IR.ParametersObject | undefined => { 53 if (!parameters || !Object.keys(parameters).length) { 54 return; 55 } 56 57 const parametersObject: IR.ParametersObject = {}; 58 59 for (const parameterOrReference of parameters) { 60 const parameter = 61 '$ref' in parameterOrReference 62 ? context.dereference<ParameterObject>(parameterOrReference) 63 : parameterOrReference; 64 65 // push request body parameters into a separate field 66 if (parameter.in === 'body' || parameter.in === 'formData') { 67 // @ts-expect-error 68 if (!operation.requestBody) { 69 // @ts-expect-error 70 operation.requestBody = []; 71 } 72 73 // @ts-expect-error 74 operation.requestBody.push(parameter); 75 continue; 76 } 77 78 if (!parametersObject[parameter.in]) { 79 parametersObject[parameter.in] = {}; 80 } 81 82 // lowercase keys for case insensitive access 83 parametersObject[parameter.in]![parameter.name.toLocaleLowerCase()] = parameterToIrParameter({ 84 $ref: `#/todo/real/path/to/parameter/${parameter.name}`, 85 context, 86 parameter, 87 }); 88 } 89 90 return parametersObject; 91}; 92 93const parameterToIrParameter = ({ 94 $ref, 95 context, 96 parameter, 97}: { 98 $ref: string; 99 context: Context; 100 parameter: Parameter; 101}): IR.ParameterObject => { 102 const schema = parameter; 103 104 const finalSchema: SchemaObject = 105 schema && '$ref' in schema 106 ? { 107 allOf: [ 108 { 109 ...schema, 110 $ref: schema.$ref as string, 111 required: Array.isArray(schema.required) ? schema.required : [], 112 type: schema.type as SchemaObject['type'], 113 }, 114 ], 115 description: parameter.description, 116 } 117 : { 118 description: parameter.description, 119 ...schema, 120 required: Array.isArray(schema.required) ? schema.required : [], 121 type: schema.type as SchemaObject['type'], 122 }; 123 124 const pagination = paginationField({ 125 context, 126 name: parameter.name, 127 schema: finalSchema, 128 }); 129 130 const style = defaultStyle(parameter.in); 131 const explode = defaultExplode(parameter.collectionFormat); 132 const allowReserved = false; 133 134 const irParameter: IR.ParameterObject = { 135 allowReserved, 136 explode, 137 location: parameter.in as IR.ParameterObject['location'], 138 name: parameter.name, 139 schema: schemaToIrSchema({ 140 context, 141 schema: finalSchema, 142 state: { 143 $ref, 144 circularReferenceTracker: new Set(), 145 }, 146 }), 147 style, 148 }; 149 150 if (parameter.description) { 151 irParameter.description = parameter.description; 152 } 153 154 if (pagination) { 155 irParameter.pagination = pagination; 156 } 157 158 if (parameter.required) { 159 irParameter.required = parameter.required; 160 } 161 162 parseExtensions({ 163 source: parameter, 164 target: irParameter, 165 }); 166 167 return irParameter; 168};