fork of hey-api/openapi-ts because I need some additional things

chore: fix types

Lubos c50190b0 0f85cc4e

Changed files
+106 -78
.changeset
packages
openapi-ts
+5
.changeset/every-coins-sell.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + **parser**: expose OpenAPI extension keywords
+32 -24
packages/openapi-ts/src/ir/types.d.ts
··· 8 8 9 9 import type { IRMediaType } from './mediaType'; 10 10 11 + /** 12 + * OpenAPI Specification Extensions. 13 + * 14 + * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. 15 + */ 16 + export interface SpecificationExtensions { 17 + [extension: `x-${string}`]: unknown; 18 + } 19 + 11 20 interface IRBodyObject { 12 21 mediaType: string; 13 22 /** ··· 26 35 schemas?: Record<string, IRSchemaObject>; 27 36 } 28 37 29 - export interface IROperationObject { 30 - [extension: `x-${string}`]: unknown; 38 + export interface IROperationObject extends SpecificationExtensions { 31 39 body?: IRBodyObject; 32 40 deprecated?: boolean; 33 41 description?: string; ··· 51 59 } 52 60 53 61 interface IRParameterObject 54 - extends Pick<JsonSchemaDraft2020_12, 'deprecated' | 'description'> { 55 - [extension: `x-${string}`]: unknown; 62 + extends Pick<JsonSchemaDraft2020_12, 'deprecated' | 'description'>, 63 + SpecificationExtensions { 56 64 /** 57 65 * Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 `:/?#[]@!$&'()*+,;=` to be included without percent-encoding. The default value is `false`. This property SHALL be ignored if the request body media type is not `application/x-www-form-urlencoded` or `multipart/form-data`. If a value is explicitly defined, then the value of `contentType` (implicit or explicit) SHALL be ignored. 58 66 */ ··· 126 134 127 135 interface IRSchemaObject 128 136 extends Pick< 129 - JsonSchemaDraft2020_12, 130 - | '$ref' 131 - | 'const' 132 - | 'default' 133 - | 'deprecated' 134 - | 'description' 135 - | 'exclusiveMaximum' 136 - | 'exclusiveMinimum' 137 - | 'maximum' 138 - | 'maxItems' 139 - | 'maxLength' 140 - | 'minimum' 141 - | 'minItems' 142 - | 'minLength' 143 - | 'pattern' 144 - | 'required' 145 - | 'title' 146 - | 'example' 147 - > { 148 - [extension: `x-${string}`]: unknown; 137 + JsonSchemaDraft2020_12, 138 + | '$ref' 139 + | 'const' 140 + | 'default' 141 + | 'deprecated' 142 + | 'description' 143 + | 'exclusiveMaximum' 144 + | 'exclusiveMinimum' 145 + | 'maximum' 146 + | 'maxItems' 147 + | 'maxLength' 148 + | 'minimum' 149 + | 'minItems' 150 + | 'minLength' 151 + | 'pattern' 152 + | 'required' 153 + | 'title' 154 + | 'example' 155 + >, 156 + SpecificationExtensions { 149 157 /** 150 158 * If the schema is intended to be used as an object property, it can be 151 159 * marked as read-only or write-only. This value controls whether the schema
+1 -4
packages/openapi-ts/src/openApi/2.0.x/parser/index.ts
··· 84 84 parseServers({ context }); 85 85 86 86 for (const path in context.spec.paths) { 87 - if (path.startsWith('x-')) { 88 - continue; 89 - } 90 - 87 + if (path.startsWith('x-')) continue; 91 88 const pathItem = context.spec.paths[path as PathKeys]!; 92 89 93 90 const finalPathItem = pathItem.$ref
+2 -2
packages/openapi-ts/src/openApi/2.0.x/parser/operation.ts
··· 78 78 }); 79 79 80 80 parseExtensions({ 81 - source: operation as Record<string, unknown>, 82 - target: irOperation as Record<string, unknown>, 81 + source: operation, 82 + target: irOperation, 83 83 }); 84 84 85 85 return irOperation;
+2 -2
packages/openapi-ts/src/openApi/2.0.x/parser/parameter.ts
··· 166 166 } 167 167 168 168 parseExtensions({ 169 - source: parameter as Record<string, unknown>, 170 - target: irParameter as Record<string, unknown>, 169 + source: parameter, 170 + target: irParameter, 171 171 }); 172 172 173 173 return irParameter;
+7 -5
packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts
··· 274 274 source, 275 275 target, 276 276 }: { 277 - source: Record<string, unknown>; 278 - target: Record<string, unknown>; 277 + source: object; 278 + target: object; 279 279 }) => { 280 280 for (const key in source) { 281 281 if (key.startsWith('x-')) { 282 - target[key] = source[key]; 282 + (target as Record<string, unknown>)[key] = ( 283 + source as Record<string, unknown> 284 + )[key]; 283 285 } 284 286 } 285 287 }; ··· 297 299 }); 298 300 299 301 parseExtensions({ 300 - source: schema as Record<string, unknown>, 301 - target: irSchema as Record<string, unknown>, 302 + source: schema, 303 + target: irSchema, 302 304 }); 303 305 304 306 return irSchema;
+5 -2
packages/openapi-ts/src/openApi/3.0.x/parser/index.ts
··· 120 120 parseServers({ context }); 121 121 122 122 for (const path in context.spec.paths) { 123 - const pathItem = context.spec.paths[path as keyof PathsObject]!; 123 + if (path.startsWith('x-')) continue; 124 + const pathItem = context.spec.paths[ 125 + path as keyof PathsObject 126 + ]! as PathItemObject; 124 127 125 128 const finalPathItem = pathItem.$ref 126 129 ? { ··· 149 152 servers: finalPathItem.servers, 150 153 summary: finalPathItem.summary, 151 154 }, 152 - path: path as keyof PathsObject, 155 + path: path as `/${string}`, 153 156 securitySchemesMap, 154 157 state, 155 158 };
+8 -3
packages/openapi-ts/src/openApi/3.0.x/parser/operation.ts
··· 6 6 import type { 7 7 OperationObject, 8 8 PathItemObject, 9 + ReferenceObject, 9 10 RequestBodyObject, 10 11 ResponseObject, 11 12 SecuritySchemeObject, ··· 75 76 }); 76 77 77 78 parseExtensions({ 78 - source: operation as Record<string, unknown>, 79 - target: irOperation as Record<string, unknown>, 79 + source: operation, 80 + target: irOperation, 80 81 }); 81 82 82 83 return irOperation; ··· 171 172 } 172 173 173 174 for (const name in operation.responses) { 175 + if (name.startsWith('x-')) continue; 176 + 174 177 if (!irOperation.responses) { 175 178 irOperation.responses = {}; 176 179 } 177 180 178 - const response = operation.responses[name]!; 181 + const response = operation.responses[name]! as 182 + | ResponseObject 183 + | ReferenceObject; 179 184 const responseObject = 180 185 '$ref' in response 181 186 ? context.resolveRef<ResponseObject>(response.$ref)
+2 -2
packages/openapi-ts/src/openApi/3.0.x/parser/parameter.ts
··· 174 174 } 175 175 176 176 parseExtensions({ 177 - source: parameter as Record<string, unknown>, 178 - target: irParameter as Record<string, unknown>, 177 + source: parameter, 178 + target: irParameter, 179 179 }); 180 180 181 181 return irParameter;
+7 -5
packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts
··· 280 280 source, 281 281 target, 282 282 }: { 283 - source: Record<string, unknown>; 284 - target: Record<string, unknown>; 283 + source: object; 284 + target: object; 285 285 }) => { 286 286 for (const key in source) { 287 287 if (key.startsWith('x-')) { 288 - target[key] = source[key]; 288 + (target as Record<string, unknown>)[key] = ( 289 + source as Record<string, unknown> 290 + )[key]; 289 291 } 290 292 } 291 293 }; ··· 303 305 }); 304 306 305 307 parseExtensions({ 306 - source: schema as Record<string, unknown>, 307 - target: irSchema as Record<string, unknown>, 308 + source: schema, 309 + target: irSchema, 308 310 }); 309 311 310 312 return irSchema;
+4 -3
packages/openapi-ts/src/openApi/3.0.x/types/spec.d.ts
··· 1 1 import type { EnumExtensions } from '~/openApi/shared/types/openapi-spec-extensions'; 2 2 3 3 /** 4 - * Type for OpenAPI Specification Extensions (x-* fields). 4 + * OpenAPI Specification Extensions. 5 + * 5 6 * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#specification-extensions Specification Extensions}. 6 7 */ 7 8 export interface SpecificationExtensions { ··· 284 285 * version: 1.0.1 285 286 * ``` 286 287 */ 287 - export interface InfoObject { 288 + export interface InfoObject extends SpecificationExtensions { 288 289 /** 289 290 * The contact information for the exposed API. 290 291 */ ··· 692 693 /** 693 694 * A relative path to an individual endpoint. The field name MUST begin with a forward slash (`/`). The path is **appended** (no relative URL resolution) to the expanded URL from the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#server-object Server Object}'s `url` field in order to construct the full URL. {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.4.md#path-templating Path templating} is allowed. When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts. Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to the tooling to decide which one to use. 694 695 */ 695 - [path: `/${string}`]: PathItemObject | unknown; 696 + [path: `/${string}`]: PathItemObject; 696 697 } 697 698 698 699 /**
+5 -2
packages/openapi-ts/src/openApi/3.1.x/parser/index.ts
··· 121 121 parseServers({ context }); 122 122 123 123 for (const path in context.spec.paths) { 124 - const pathItem = context.spec.paths[path as keyof PathsObject]!; 124 + if (path.startsWith('x-')) continue; 125 + const pathItem = context.spec.paths[ 126 + path as keyof PathsObject 127 + ]! as PathItemObject; 125 128 126 129 const finalPathItem = pathItem.$ref 127 130 ? { ··· 145 148 servers: finalPathItem.servers, 146 149 summary: finalPathItem.summary, 147 150 }, 148 - path: path as keyof PathsObject, 151 + path: path as `/${string}`, 149 152 securitySchemesMap, 150 153 state, 151 154 };
+8 -3
packages/openapi-ts/src/openApi/3.1.x/parser/operation.ts
··· 6 6 7 7 import type { 8 8 OperationObject, 9 + ReferenceObject, 9 10 RequestBodyObject, 10 11 ResponseObject, 11 12 SecuritySchemeObject, ··· 75 76 }); 76 77 77 78 parseExtensions({ 78 - source: operation as Record<string, unknown>, 79 - target: irOperation as Record<string, unknown>, 79 + source: operation, 80 + target: irOperation, 80 81 }); 81 82 82 83 return irOperation; ··· 156 157 } 157 158 158 159 for (const name in operation.responses) { 160 + if (name.startsWith('x-')) continue; 161 + 159 162 if (!irOperation.responses) { 160 163 irOperation.responses = {}; 161 164 } 162 165 163 - const response = operation.responses[name]!; 166 + const response = operation.responses[name]! as 167 + | ResponseObject 168 + | ReferenceObject; 164 169 const responseObject = 165 170 '$ref' in response 166 171 ? context.resolveRef<ResponseObject>(response.$ref)
+2 -2
packages/openapi-ts/src/openApi/3.1.x/parser/parameter.ts
··· 167 167 } 168 168 169 169 parseExtensions({ 170 - source: parameter as Record<string, unknown>, 171 - target: irParameter as Record<string, unknown>, 170 + source: parameter, 171 + target: irParameter, 172 172 }); 173 173 174 174 return irParameter;
+7 -5
packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts
··· 361 361 source, 362 362 target, 363 363 }: { 364 - source: Record<string, unknown>; 365 - target: Record<string, unknown>; 364 + source: object; 365 + target: object; 366 366 }) => { 367 367 for (const key in source) { 368 368 if (key.startsWith('x-')) { 369 - target[key] = source[key]; 369 + (target as Record<string, unknown>)[key] = ( 370 + source as Record<string, unknown> 371 + )[key]; 370 372 } 371 373 } 372 374 }; ··· 384 386 }); 385 387 386 388 parseExtensions({ 387 - source: schema as Record<string, unknown>, 388 - target: irSchema as Record<string, unknown>, 389 + source: schema, 390 + target: irSchema, 389 391 }); 390 392 391 393 return irSchema;
+1 -7
packages/openapi-ts/src/openApi/3.1.x/types/json-schema-draft-2020-12.d.ts
··· 1 1 import type { EnumExtensions } from '~/openApi/shared/types/openapi-spec-extensions'; 2 2 3 3 import type { MaybeArray } from '../../../types/utils'; 4 + import type { SpecificationExtensions } from './spec'; 4 5 import type { OpenApiSchemaExtensions } from './spec-extensions'; 5 - 6 - /** 7 - * Type for OpenAPI Specification Extensions (x-* fields). 8 - */ 9 - export interface SpecificationExtensions { 10 - [extension: `x-${string}`]: unknown; 11 - } 12 6 13 7 // TODO: left out some keywords related to structuring a complex schema and declaring a dialect 14 8 export interface JsonSchemaDraft2020_12
+5 -4
packages/openapi-ts/src/openApi/3.1.x/types/spec.d.ts
··· 1 1 import type { JsonSchemaDraft2020_12 } from './json-schema-draft-2020-12'; 2 2 3 3 /** 4 - * Type for OpenAPI Specification Extensions (x-* fields). 4 + * OpenAPI Specification Extensions. 5 + * 5 6 * See {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}. 6 7 */ 7 8 export interface SpecificationExtensions { ··· 429 430 * 430 431 * will map to `Dog` because of the definition in the `mapping` element. 431 432 */ 432 - export interface DiscriminatorObject { 433 + export interface DiscriminatorObject extends SpecificationExtensions { 433 434 /** 434 435 * An object to hold mappings between payload values and schema names or references. 435 436 */ ··· 1408 1409 /** 1409 1410 * A relative path to an individual endpoint. The field name MUST begin with a forward slash (`/`). The path is **appended** (no relative URL resolution) to the expanded URL from the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#server-object `Server Object`}'s `url` field in order to construct the full URL. {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#path-templating Path templating} is allowed. When matching URLs, concrete (non-templated) paths would be matched before their templated counterparts. Templated paths with the same hierarchy but different templated names MUST NOT exist as they are identical. In case of ambiguous matching, it's up to the tooling to decide which one to use. 1410 1411 */ 1411 - [path: `/${string}`]: PathItemObject | unknown; 1412 + [path: `/${string}`]: PathItemObject; 1412 1413 } 1413 1414 1414 1415 /** ··· 1672 1673 * 1673 1674 * This object MAY be extended with {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions Specification Extensions}, though as noted, additional properties MAY omit the `x-` prefix within this object. 1674 1675 */ 1675 - export type SchemaObject = JsonSchemaDraft2020_12; 1676 + export type SchemaObject = JsonSchemaDraft2020_12 & SpecificationExtensions; 1676 1677 1677 1678 /** 1678 1679 * Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#componentsSecuritySchemes Security Schemes} under the {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#components-object Components Object}.
+1 -1
packages/openapi-ts/src/openApi/shared/utils/patch.ts
··· 77 77 if (!schema || typeof schema !== 'object') continue; 78 78 79 79 const patchFn = patchOptions.schemas[key]!; 80 - patchFn(schema); 80 + patchFn(schema as Parameters<typeof patchFn>[0]); 81 81 } 82 82 } 83 83
+2 -2
packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts
··· 137 137 plugin, 138 138 schema: item, 139 139 }), 140 - ) as 140 + ) as unknown as 141 141 | OpenApiV3_0_XTypes['SchemaObject'] 142 142 | OpenApiV3_0_XTypes['ReferenceObject']; 143 143 } ··· 235 235 plugin, 236 236 schema: item, 237 237 }), 238 - ) as OpenApiV3_1_XTypes['SchemaObject']; 238 + ) as unknown as OpenApiV3_1_XTypes['SchemaObject']; 239 239 } 240 240 241 241 const schema = structuredClone(_schema);