fork of hey-api/openapi-ts because I need some additional things
at feat/skip-token 248 lines 8.7 kB view raw
1import type { MaybeFunc } from '@hey-api/types'; 2 3import type { 4 OpenApi, 5 OpenApiMetaObject, 6 OpenApiOperationObject, 7 OpenApiParameterObject, 8 OpenApiRequestBodyObject, 9 OpenApiResponseObject, 10 OpenApiSchemaObject, 11} from '../../openApi/types'; 12 13export type PatchInputFn = ( 14 spec: OpenApi.V2_0_X | OpenApi.V3_0_X | OpenApi.V3_1_X, 15) => void | Promise<void>; 16 17export type Patch = 18 | PatchInputFn 19 | { 20 /** 21 * Patch the raw OpenAPI spec object in place. Called before all other 22 * patch callbacks. Useful for bulk/structural transformations such as 23 * adding new component definitions or modifying many operations at once. 24 * 25 * @param spec The OpenAPI spec object for the current version. 26 * 27 * @example 28 * ```ts 29 * input: (spec) => { 30 * // Create new component parameters 31 * if (!spec.components) spec.components = {}; 32 * if (!spec.components.parameters) spec.components.parameters = {}; 33 * spec.components.parameters.MyParam = { 34 * in: 'query', 35 * name: 'myParam', 36 * schema: { type: 'string' } 37 * }; 38 * 39 * // Inject parameters into operations 40 * for (const [path, pathItem] of Object.entries(spec.paths ?? {})) { 41 * if (pathItem?.get) { 42 * if (!Array.isArray(pathItem.get.parameters)) { 43 * pathItem.get.parameters = []; 44 * } 45 * pathItem.get.parameters.push({ 46 * $ref: '#/components/parameters/MyParam' 47 * }); 48 * } 49 * } 50 * } 51 * ``` 52 */ 53 input?: PatchInputFn; 54 /** 55 * Patch the OpenAPI meta object in place. Useful for modifying general metadata such as title, description, version, or custom fields before further processing. 56 * 57 * @param meta The OpenAPI meta object for the current version. 58 */ 59 meta?: ( 60 meta: OpenApiMetaObject.V2_0_X | OpenApiMetaObject.V3_0_X | OpenApiMetaObject.V3_1_X, 61 ) => void; 62 /** 63 * Patch OpenAPI operations in place. Each function receives the operation 64 * object to be modified in place. Common use cases include injecting 65 * `operationId` for specs that don't have them, adding `x-*` extensions, 66 * setting `deprecated` based on path patterns, or injecting `security` 67 * requirements globally. 68 * 69 * Can be: 70 * - `Record<string, fn>`: Patch specific operations by `"METHOD /path"` key 71 * - `function`: Bulk callback receives `(method, path, operation)` for every operation 72 * 73 * Both patterns support async functions for operations like fetching data 74 * from external sources or performing I/O. 75 * 76 * @example 77 * ```js 78 * // Named operations 79 * operations: { 80 * 'GET /foo': (operation) => { 81 * operation.responses['200'].description = 'Success'; 82 * }, 83 * 'POST /bar': (operation) => { 84 * operation.deprecated = true; 85 * } 86 * } 87 * 88 * // Bulk callback for all operations 89 * operations: (method, path, operation) => { 90 * if (!operation.operationId) { 91 * operation.operationId = method + buildOperationName(path); 92 * } 93 * } 94 * 95 * // Async example - inject operationId based on path patterns 96 * operations: async (method, path, operation) => { 97 * if (operation.operationId) return; 98 * 99 * const segments = path.split('/').filter(Boolean); 100 * const parts = segments 101 * .map((seg) => seg.startsWith('{') ? 'ById' : seg) 102 * .join(''); 103 * operation.operationId = method + parts; 104 * } 105 * ``` 106 */ 107 operations?: 108 | Record< 109 string, 110 ( 111 operation: 112 | OpenApiOperationObject.V2_0_X 113 | OpenApiOperationObject.V3_0_X 114 | OpenApiOperationObject.V3_1_X, 115 ) => void | Promise<void> 116 > 117 | (( 118 method: string, 119 path: string, 120 operation: 121 | OpenApiOperationObject.V2_0_X 122 | OpenApiOperationObject.V3_0_X 123 | OpenApiOperationObject.V3_1_X, 124 ) => void | Promise<void>); 125 /** 126 * Patch OpenAPI parameters in place. The key is the parameter name, and the function receives the parameter object to modify directly. 127 * 128 * @example 129 * parameters: { 130 * limit: (parameter) => { 131 * parameter.schema.type = 'integer'; 132 * } 133 * } 134 */ 135 parameters?: Record< 136 string, 137 (parameter: OpenApiParameterObject.V3_0_X | OpenApiParameterObject.V3_1_X) => void 138 >; 139 /** 140 * Patch OpenAPI request bodies in place. The key is the request body name, and the function receives the request body object to modify directly. 141 * 142 * @example 143 * requestBodies: { 144 * CreateUserRequest: (requestBody) => { 145 * requestBody.required = true; 146 * } 147 * } 148 */ 149 requestBodies?: Record< 150 string, 151 (requestBody: OpenApiRequestBodyObject.V3_0_X | OpenApiRequestBodyObject.V3_1_X) => void 152 >; 153 /** 154 * Patch OpenAPI responses in place. The key is the response name, and the function receives the response object to modify directly. 155 * 156 * @example 157 * responses: { 158 * NotFound: (response) => { 159 * response.description = 'Resource not found.'; 160 * } 161 * } 162 */ 163 responses?: Record< 164 string, 165 (response: OpenApiResponseObject.V3_0_X | OpenApiResponseObject.V3_1_X) => void 166 >; 167 /** 168 * Each function receives the schema object to be modified in place. Common 169 * use cases include fixing incorrect data types, removing unwanted 170 * properties, adding missing fields, or standardizing date/time formats. 171 * 172 * Can be: 173 * - `Record<string, fn>`: Patch specific named schemas 174 * - `function`: Bulk callback receives `(name, schema)` for every schema 175 * 176 * Both patterns support async functions for operations like fetching data 177 * from external sources or performing I/O. 178 * 179 * @example 180 * ```js 181 * // Named schemas 182 * schemas: { 183 * Foo: (schema) => { 184 * // convert date-time format to timestamp 185 * delete schema.properties.updatedAt.format; 186 * schema.properties.updatedAt.type = 'number'; 187 * }, 188 * Bar: (schema) => { 189 * // add missing property 190 * schema.properties.metadata = { 191 * additionalProperties: true, 192 * type: 'object', 193 * }; 194 * schema.required = ['metadata']; 195 * }, 196 * Baz: (schema) => { 197 * // remove property 198 * delete schema.properties.internalField; 199 * } 200 * } 201 * 202 * // Bulk callback for all schemas 203 * schemas: (name, schema) => { 204 * const match = name.match(/_v(\d+)_(\d+)_(\d+)_/); 205 * if (match) { 206 * schema.description = (schema.description || '') + 207 * `\n@version ${match[1]}.${match[2]}.${match[3]}`; 208 * } 209 * } 210 * 211 * // Async example - fetch metadata from external source 212 * schemas: async (name, schema) => { 213 * const metadata = await fetchSchemaMetadata(name); 214 * if (metadata) { 215 * schema.description = `${schema.description}\n\n${metadata.notes}`; 216 * } 217 * } 218 * ``` 219 */ 220 schemas?: 221 | Record< 222 string, 223 ( 224 schema: 225 | OpenApiSchemaObject.V2_0_X 226 | OpenApiSchemaObject.V3_0_X 227 | OpenApiSchemaObject.V3_1_X, 228 ) => void | Promise<void> 229 > 230 | (( 231 name: string, 232 schema: 233 | OpenApiSchemaObject.V2_0_X 234 | OpenApiSchemaObject.V3_0_X 235 | OpenApiSchemaObject.V3_1_X, 236 ) => void | Promise<void>); 237 /** 238 * Patch the OpenAPI version string. The function receives the current version and should return the new version string. 239 * Useful for normalizing or overriding the version value before further processing. 240 * 241 * @param version The current OpenAPI version string. 242 * @returns The new version string to use. 243 * 244 * @example 245 * version: (version) => version.replace(/^v/, '') 246 */ 247 version?: MaybeFunc<(version: string) => string>; 248 };