fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 97 lines 2.7 kB view raw
1import type { Context } from '../../../ir/context'; 2import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; 3import type { SchemaType } from '../../../openApi/shared/types/schema'; 4import type { ParameterObject, ReferenceObject, RequestBodyObject } from '../types/spec'; 5import type { SchemaObject } from '../types/spec'; 6import { mediaTypeObjects } from './mediaType'; 7import { getSchemaType } from './schema'; 8 9const isPaginationType = (schemaType: SchemaType<SchemaObject> | undefined): boolean => 10 schemaType === 'boolean' || 11 schemaType === 'integer' || 12 schemaType === 'number' || 13 schemaType === 'string'; 14 15// We handle only simple values for now, up to 1 nested field 16export const paginationField = ({ 17 context, 18 name, 19 schema, 20}: { 21 context: Context; 22 name: string; 23 schema: SchemaObject | ReferenceObject; 24}): boolean | string => { 25 const paginationRegExp = getPaginationKeywordsRegExp(context.config.parser.pagination); 26 if (paginationRegExp.test(name)) { 27 return true; 28 } 29 30 if ('$ref' in schema) { 31 const ref = context.resolveRef<ParameterObject | RequestBodyObject | SchemaObject>(schema.$ref); 32 33 if ('content' in ref || 'in' in ref) { 34 let refSchema: SchemaObject | ReferenceObject | undefined; 35 36 if ('in' in ref) { 37 refSchema = ref.schema; 38 } 39 40 if (!refSchema) { 41 // parameter or body 42 const contents = mediaTypeObjects({ content: ref.content }); 43 // TODO: add support for multiple content types, for now prefer JSON 44 const content = contents.find((content) => content.type === 'json') || contents[0]; 45 if (content?.schema) { 46 refSchema = content.schema; 47 } 48 } 49 50 if (!refSchema) { 51 return false; 52 } 53 54 return paginationField({ 55 context, 56 name, 57 schema: refSchema, 58 }); 59 } 60 61 return paginationField({ 62 context, 63 name, 64 schema: ref, 65 }); 66 } 67 68 for (const name in schema.properties) { 69 const paginationRegExp = getPaginationKeywordsRegExp(context.config.parser.pagination); 70 71 if (paginationRegExp.test(name)) { 72 const property = schema.properties[name]!; 73 74 if (typeof property !== 'boolean' && !('$ref' in property)) { 75 const schemaType = getSchemaType({ schema: property }); 76 // TODO: resolve deeper references 77 78 if (isPaginationType(schemaType)) { 79 return name; 80 } 81 } 82 } 83 } 84 85 for (const allOf of schema.allOf ?? []) { 86 const pagination = paginationField({ 87 context, 88 name, 89 schema: allOf, 90 }); 91 if (pagination) { 92 return pagination; 93 } 94 } 95 96 return false; 97};