fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at feat/skip-token 187 lines 4.6 kB view raw
1import type { Context } from '../../../ir/context'; 2import type { IR } from '../../../ir/types'; 3import { refToName } from '../../../utils/ref'; 4import type { ParameterObject, ReferenceObject, SchemaObject } from '../types/spec'; 5import { mediaTypeObjects } from './mediaType'; 6import { paginationField } from './pagination'; 7import { parseExtensions, schemaToIrSchema } from './schema'; 8 9/** 10 * Returns default parameter `allowReserved` based on value of `in`. 11 */ 12const defaultAllowReserved = (_in: ParameterObject['in']): boolean | undefined => { 13 switch (_in) { 14 // this keyword only applies to parameters with an `in` value of `query` 15 case 'query': 16 return false; 17 default: 18 return; 19 } 20}; 21 22/** 23 * Returns default parameter `explode` based on value of `style`. 24 */ 25const defaultExplode = (style: Required<ParameterObject>['style']): boolean => { 26 switch (style) { 27 // default value for `deepObject` is `false`, but that behavior is undefined 28 // so we use `true` to make this work with the `client-fetch` package 29 case 'deepObject': 30 case 'form': 31 return true; 32 default: 33 return false; 34 } 35}; 36 37/** 38 * Returns default parameter `style` based on value of `in`. 39 */ 40const defaultStyle = (_in: ParameterObject['in']): Required<ParameterObject>['style'] => { 41 switch (_in) { 42 case 'header': 43 case 'path': 44 return 'simple'; 45 case 'cookie': 46 case 'query': 47 return 'form'; 48 } 49}; 50 51export const parametersArrayToObject = ({ 52 context, 53 parameters, 54}: { 55 context: Context; 56 parameters?: ReadonlyArray<ParameterObject | ReferenceObject>; 57}): IR.ParametersObject | undefined => { 58 if (!parameters || !Object.keys(parameters).length) { 59 return; 60 } 61 62 const parametersObject: IR.ParametersObject = {}; 63 64 for (const parameterOrReference of parameters) { 65 const parameter = 66 '$ref' in parameterOrReference 67 ? context.dereference<ParameterObject>(parameterOrReference) 68 : parameterOrReference; 69 70 if (!parametersObject[parameter.in]) { 71 parametersObject[parameter.in] = {}; 72 } 73 74 // lowercase keys for case insensitive access 75 parametersObject[parameter.in]![parameter.name.toLocaleLowerCase()] = parameterToIrParameter({ 76 $ref: `#/todo/real/path/to/parameter/${parameter.name}`, 77 context, 78 parameter, 79 }); 80 } 81 82 return parametersObject; 83}; 84 85const parameterToIrParameter = ({ 86 $ref, 87 context, 88 parameter, 89}: { 90 $ref: string; 91 context: Context; 92 parameter: ParameterObject; 93}): IR.ParameterObject => { 94 // TODO: parser - fix 95 let schema = parameter.schema; 96 97 if (!schema) { 98 const contents = mediaTypeObjects({ content: parameter.content }); 99 // TODO: add support for multiple content types, for now prefer JSON 100 const content = contents.find((content) => content.type === 'json') || contents[0]; 101 if (content) { 102 schema = content.schema; 103 } 104 } 105 106 const finalSchema: SchemaObject = { 107 deprecated: parameter.deprecated, 108 description: parameter.description, 109 ...schema, 110 }; 111 112 const pagination = paginationField({ 113 context, 114 name: parameter.name, 115 schema: finalSchema, 116 }); 117 118 const style = parameter.style || defaultStyle(parameter.in); 119 const explode = parameter.explode !== undefined ? parameter.explode : defaultExplode(style); 120 const allowReserved = 121 parameter.allowReserved !== undefined 122 ? parameter.allowReserved 123 : defaultAllowReserved(parameter.in); 124 125 const irParameter: IR.ParameterObject = { 126 allowReserved, 127 explode, 128 location: parameter.in, 129 name: parameter.name, 130 schema: schemaToIrSchema({ 131 context, 132 schema: finalSchema, 133 state: { 134 $ref, 135 circularReferenceTracker: new Set(), 136 }, 137 }), 138 style, 139 }; 140 141 if (parameter.deprecated) { 142 irParameter.deprecated = parameter.deprecated; 143 } 144 145 if (parameter.description) { 146 irParameter.description = parameter.description; 147 } 148 149 if (pagination) { 150 irParameter.pagination = pagination; 151 } 152 153 if (parameter.required) { 154 irParameter.required = parameter.required; 155 } 156 157 parseExtensions({ 158 source: parameter, 159 target: irParameter, 160 }); 161 162 return irParameter; 163}; 164 165export const parseParameter = ({ 166 $ref, 167 context, 168 parameter, 169}: { 170 $ref: string; 171 context: Context; 172 parameter: ParameterObject; 173}) => { 174 if (!context.ir.components) { 175 context.ir.components = {}; 176 } 177 178 if (!context.ir.components.parameters) { 179 context.ir.components.parameters = {}; 180 } 181 182 context.ir.components.parameters[refToName($ref)] = parameterToIrParameter({ 183 $ref, 184 context, 185 parameter, 186 }); 187};