+5
.changeset/every-coins-sell.md
+5
.changeset/every-coins-sell.md
+32
-24
packages/openapi-ts/src/ir/types.d.ts
+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
+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
+2
-2
packages/openapi-ts/src/openApi/2.0.x/parser/operation.ts
+2
-2
packages/openapi-ts/src/openApi/2.0.x/parser/parameter.ts
+2
-2
packages/openapi-ts/src/openApi/2.0.x/parser/parameter.ts
+7
-5
packages/openapi-ts/src/openApi/2.0.x/parser/schema.ts
+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
+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
+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
+2
-2
packages/openapi-ts/src/openApi/3.0.x/parser/parameter.ts
+7
-5
packages/openapi-ts/src/openApi/3.0.x/parser/schema.ts
+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
+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
+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
+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
+2
-2
packages/openapi-ts/src/openApi/3.1.x/parser/parameter.ts
+7
-5
packages/openapi-ts/src/openApi/3.1.x/parser/schema.ts
+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
-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
+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}.
+2
-2
packages/openapi-ts/src/plugins/@hey-api/schemas/plugin.ts
+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);