fork of hey-api/openapi-ts because I need some additional things
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};