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