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.

Merge pull request #1827 from john-cremit/feat/add-pagination-keywords-config

authored by

Lubos and committed by
GitHub
2945be45 052a7c60

+108 -32
+5
.changeset/sweet-cycles-do.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + feat: allow customizing pagination keywords using `input.pagination.keywords`
+28 -5
packages/openapi-ts/src/ir/__tests__/pagination.test.ts
··· 1 1 import { describe, expect, it } from 'vitest'; 2 2 3 - import { paginationKeywordsRegExp } from '../pagination'; 3 + import type { Config } from '../../types/config'; 4 + import { getPaginationKeywordsRegExp } from '../pagination'; 4 5 5 6 describe('paginationKeywordsRegExp', () => { 6 - const scenarios: Array<{ 7 + const defaultScenarios: Array<{ 7 8 result: boolean; 8 9 value: string; 9 10 }> = [ ··· 41 42 }, 42 43 ]; 43 44 44 - it.each(scenarios)( 45 + it.each(defaultScenarios)( 45 46 'is $value pagination param? $output', 46 47 async ({ result, value }) => { 47 - paginationKeywordsRegExp.lastIndex = 0; 48 - expect(paginationKeywordsRegExp.test(value)).toEqual(result); 48 + const paginationRegExp = getPaginationKeywordsRegExp(); 49 + expect(paginationRegExp.test(value)).toEqual(result); 50 + }, 51 + ); 52 + 53 + const customScenarios: Array<{ 54 + result: boolean; 55 + value: string; 56 + }> = [ 57 + { result: true, value: 'customPagination' }, 58 + { result: true, value: 'pageSize' }, 59 + { result: true, value: 'perPage' }, 60 + { result: false, value: 'page' }, 61 + ]; 62 + 63 + it.each(customScenarios)( 64 + 'with custom config, $value should match? $result', 65 + async ({ result, value }) => { 66 + const pagination: Config['input']['pagination'] = { 67 + keywords: ['customPagination', 'pageSize', 'perPage'], 68 + }; 69 + 70 + const paginationRegExp = getPaginationKeywordsRegExp(pagination); 71 + expect(paginationRegExp.test(value)).toEqual(result); 49 72 }, 50 73 ); 51 74 });
+19 -2
packages/openapi-ts/src/ir/pagination.ts
··· 1 + import type { Config } from '../types/config'; 1 2 import type { IR } from './types'; 2 3 3 - export const paginationKeywordsRegExp = 4 - /^(after|before|cursor|offset|page|start)$/; 4 + export const DEFAULT_PAGINATION_KEYWORDS = [ 5 + 'after', 6 + 'before', 7 + 'cursor', 8 + 'offset', 9 + 'page', 10 + 'start', 11 + ] as const; 12 + 13 + export function getPaginationKeywordsRegExp({ 14 + keywords = DEFAULT_PAGINATION_KEYWORDS, 15 + }: Config['input']['pagination'] = {}): RegExp { 16 + if (keywords.length === 0) { 17 + keywords = DEFAULT_PAGINATION_KEYWORDS; 18 + } 19 + const pattern = `^(${keywords.join('|')})$`; 20 + return new RegExp(pattern); 21 + } 5 22 6 23 export interface Pagination { 7 24 in: string;
+10 -6
packages/openapi-ts/src/openApi/2.0.x/parser/pagination.ts
··· 1 - import { paginationKeywordsRegExp } from '../../../ir/pagination'; 1 + import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; 2 2 import type { IR } from '../../../ir/types'; 3 3 import type { SchemaType } from '../../shared/types/schema'; 4 4 import type { ParameterObject, ReferenceObject } from '../types/spec'; 5 - import { type SchemaObject } from '../types/spec'; 5 + import type { SchemaObject } from '../types/spec'; 6 6 import { getSchemaType } from './schema'; 7 7 8 8 const isPaginationType = ( ··· 29 29 in: undefined; 30 30 }; 31 31 }): boolean | string => { 32 - paginationKeywordsRegExp.lastIndex = 0; 33 - if (paginationKeywordsRegExp.test(name)) { 32 + const paginationRegExp = getPaginationKeywordsRegExp( 33 + context.config.input.pagination, 34 + ); 35 + if (paginationRegExp.test(name)) { 34 36 return true; 35 37 } 36 38 ··· 83 85 } 84 86 85 87 for (const name in schema.properties) { 86 - paginationKeywordsRegExp.lastIndex = 0; 88 + const paginationRegExp = getPaginationKeywordsRegExp( 89 + context.config.input.pagination, 90 + ); 87 91 88 - if (paginationKeywordsRegExp.test(name)) { 92 + if (paginationRegExp.test(name)) { 89 93 const property = schema.properties[name]!; 90 94 91 95 if (typeof property !== 'boolean' && !('$ref' in property)) {
+10 -6
packages/openapi-ts/src/openApi/3.0.x/parser/pagination.ts
··· 1 - import { paginationKeywordsRegExp } from '../../../ir/pagination'; 1 + import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; 2 2 import type { IR } from '../../../ir/types'; 3 3 import type { SchemaType } from '../../shared/types/schema'; 4 4 import type { ··· 6 6 ReferenceObject, 7 7 RequestBodyObject, 8 8 } from '../types/spec'; 9 - import { type SchemaObject } from '../types/spec'; 9 + import type { SchemaObject } from '../types/spec'; 10 10 import { mediaTypeObject } from './mediaType'; 11 11 import { getSchemaType } from './schema'; 12 12 ··· 28 28 name: string; 29 29 schema: SchemaObject | ReferenceObject; 30 30 }): boolean | string => { 31 - paginationKeywordsRegExp.lastIndex = 0; 32 - if (paginationKeywordsRegExp.test(name)) { 31 + const paginationRegExp = getPaginationKeywordsRegExp( 32 + context.config.input.pagination, 33 + ); 34 + if (paginationRegExp.test(name)) { 33 35 return true; 34 36 } 35 37 ··· 72 74 } 73 75 74 76 for (const name in schema.properties) { 75 - paginationKeywordsRegExp.lastIndex = 0; 77 + const paginationRegExp = getPaginationKeywordsRegExp( 78 + context.config.input.pagination, 79 + ); 76 80 77 - if (paginationKeywordsRegExp.test(name)) { 81 + if (paginationRegExp.test(name)) { 78 82 const property = schema.properties[name]!; 79 83 80 84 if (typeof property !== 'boolean' && !('$ref' in property)) {
+10 -6
packages/openapi-ts/src/openApi/3.1.x/parser/pagination.ts
··· 1 - import { paginationKeywordsRegExp } from '../../../ir/pagination'; 1 + import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; 2 2 import type { IR } from '../../../ir/types'; 3 3 import type { SchemaType } from '../../shared/types/schema'; 4 4 import type { ParameterObject, RequestBodyObject } from '../types/spec'; 5 - import { type SchemaObject } from '../types/spec'; 5 + import type { SchemaObject } from '../types/spec'; 6 6 import { mediaTypeObject } from './mediaType'; 7 7 import { getSchemaTypes } from './schema'; 8 8 ··· 24 24 name: string; 25 25 schema: SchemaObject; 26 26 }): boolean | string => { 27 - paginationKeywordsRegExp.lastIndex = 0; 28 - if (paginationKeywordsRegExp.test(name)) { 27 + const paginationRegExp = getPaginationKeywordsRegExp( 28 + context.config.input.pagination, 29 + ); 30 + if (paginationRegExp.test(name)) { 29 31 return true; 30 32 } 31 33 ··· 68 70 } 69 71 70 72 for (const name in schema.properties) { 71 - paginationKeywordsRegExp.lastIndex = 0; 73 + const paginationRegExp = getPaginationKeywordsRegExp( 74 + context.config.input.pagination, 75 + ); 72 76 73 - if (paginationKeywordsRegExp.test(name)) { 77 + if (paginationRegExp.test(name)) { 74 78 const property = schema.properties[name]!; 75 79 76 80 if (typeof property !== 'boolean') {
+13 -7
packages/openapi-ts/src/plugins/@tanstack/query-core/plugin-legacy.ts
··· 5 5 import type { ImportExportItemObject } from '../../../compiler/utils'; 6 6 import { clientApi, clientModulePath } from '../../../generate/client'; 7 7 import { relativeModulePath } from '../../../generate/utils'; 8 - import { paginationKeywordsRegExp } from '../../../ir/pagination'; 8 + import { getPaginationKeywordsRegExp } from '../../../ir/pagination'; 9 9 import type { IR } from '../../../ir/types'; 10 10 import { isOperationParameterRequired } from '../../../openApi'; 11 11 import { getOperationKey } from '../../../openApi/common/parser/operation'; ··· 900 900 let paginationField!: Model | OperationParameter; 901 901 902 902 const paginationParameter = operation.parameters.find((parameter) => { 903 - paginationKeywordsRegExp.lastIndex = 0; 904 - if (paginationKeywordsRegExp.test(parameter.name)) { 903 + const paginationRegExp = getPaginationKeywordsRegExp( 904 + config.input.pagination, 905 + ); 906 + if (paginationRegExp.test(parameter.name)) { 905 907 paginationField = parameter; 906 908 return true; 907 909 } ··· 916 918 (model) => model.meta?.$ref === ref, 917 919 ); 918 920 return refModel?.properties.find((property) => { 919 - paginationKeywordsRegExp.lastIndex = 0; 920 - if (paginationKeywordsRegExp.test(property.name)) { 921 + const paginationRegExp = getPaginationKeywordsRegExp( 922 + config.input.pagination, 923 + ); 924 + if (paginationRegExp.test(property.name)) { 921 925 paginationField = property; 922 926 return true; 923 927 } ··· 925 929 } 926 930 927 931 return parameter.properties.find((property) => { 928 - paginationKeywordsRegExp.lastIndex = 0; 929 - if (paginationKeywordsRegExp.test(property.name)) { 932 + const paginationRegExp = getPaginationKeywordsRegExp( 933 + config.input.pagination, 934 + ); 935 + if (paginationRegExp.test(property.name)) { 930 936 paginationField = property; 931 937 return true; 932 938 }
+13
packages/openapi-ts/src/types/config.d.ts
··· 66 66 */ 67 67 organization?: string; 68 68 /** 69 + * Pagination configuration 70 + */ 71 + pagination?: { 72 + /** 73 + * Array of keywords to be considered as pagination field names. 74 + * These will be used to detect pagination fields in schemas and parameters. 75 + * 76 + * @default ['after', 'before', 'cursor', 'offset', 'page', 'start'] 77 + */ 78 + keywords?: ReadonlyArray<string>; 79 + }; 80 + /** 69 81 * Path to the OpenAPI specification. This can be either local or remote path. 70 82 * Both JSON and YAML file formats are supported. You can also pass the parsed 71 83 * object directly if you're fetching the file yourself. ··· 88 100 * the first match will be returned. 89 101 */ 90 102 tags?: ReadonlyArray<string>; 103 + 91 104 /** 92 105 * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** 93 106 *