Skip to content

Commit ca5e341

Browse files
authored
Merge pull request #9 from maxholman/qol20241013
chore: switch to openapi3-ts which requires no patches
2 parents 0cddbd1 + e297284 commit ca5e341

File tree

6 files changed

+63
-52
lines changed

6 files changed

+63
-52
lines changed

lib/build.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { writeFile } from 'node:fs/promises';
22
import prettierConfig from '@block65/eslint-config/prettier';
3-
import type { OpenAPIV3_1 } from 'openapi-types';
3+
import type { oas31 } from 'openapi3-ts';
44
import { format as prettier } from 'prettier';
55
import { processOpenApiDocument } from './process-document.js';
66

@@ -11,7 +11,7 @@ export async function build(
1111
) {
1212
const apischema = (await import(inputFile, {
1313
with: { type: 'json' },
14-
})) as { default: OpenAPIV3_1.Document };
14+
})) as { default: oas31.OpenAPIObject };
1515

1616
const banner = `
1717
/**

lib/process-document.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable no-restricted-syntax */
22
import { join, relative } from 'node:path';
33
import { $RefParser } from '@apidevtools/json-schema-ref-parser';
4-
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
4+
import type { oas30, oas31 } from 'openapi3-ts';
55
import toposort from 'toposort';
66
import {
77
InterfaceDeclaration,
@@ -14,6 +14,7 @@ import {
1414
VariableDeclarationKind,
1515
Writers,
1616
} from 'ts-morph';
17+
import type { Simplify } from 'type-fest';
1718
import { registerTypesFromSchema, schemaToType } from './process-schema.js';
1819
import {
1920
castToValidJsIdentifier,
@@ -60,7 +61,7 @@ function createUnion(...types: (string | undefined)[]) {
6061

6162
export async function processOpenApiDocument(
6263
outputDir: string,
63-
schema: OpenAPIV3_1.Document,
64+
schema: Simplify<oas31.OpenAPIObject>,
6465
tags?: string[] | undefined,
6566
) {
6667
const project = new Project();
@@ -191,22 +192,22 @@ export async function processOpenApiDocument(
191192
);
192193
}
193194

194-
for (const [path, pathItemObject] of Object.entries(schema.paths || {})) {
195+
for (const [path, pathItemObject] of Object.entries<oas31.PathItemObject>(
196+
schema.paths || {},
197+
)) {
195198
if (pathItemObject) {
196-
for (const [method, operationObject] of Object.entries(
197-
pathItemObject,
198-
).filter(
199-
([, o]) =>
200-
!tags ||
201-
(typeof o === 'object' && 'tags' in o
202-
? o.tags.some((t) => tags.includes(t))
203-
: false),
204-
)) {
199+
for (const [method, operationObject] of Object.entries(pathItemObject)
200+
// ensure op is an object
201+
.filter(
202+
(e): e is [string, oas31.OperationObject] => typeof e[1] === 'object',
203+
)
204+
// tags
205+
.filter(([, o]) => !tags || o.tags?.some((t) => tags?.includes(t)))) {
205206
if (
206207
typeof operationObject === 'object' &&
207208
'operationId' in operationObject
208209
) {
209-
const pathParameters: OpenAPIV3.ParameterObject[] = [];
210+
const pathParameters: oas30.ParameterObject[] = [];
210211

211212
const commandName = pascalCase(
212213
operationObject.operationId.replace(/command$/i, ''),
@@ -258,13 +259,13 @@ export async function processOpenApiDocument(
258259
? operationObject.requestBody
259260
: undefined;
260261

261-
const queryParameters: OpenAPIV3.ParameterObject[] = [];
262+
const queryParameters: oas30.ParameterObject[] = [];
262263

263264
for (const parameter of [
264265
...(operationObject.parameters || []),
265266
...(pathItemObject.parameters || []),
266267
]) {
267-
const resolvedParameter: OpenAPIV3.ParameterObject =
268+
const resolvedParameter: oas30.ParameterObject =
268269
'$ref' in parameter ? refs.get(parameter.$ref) : parameter;
269270

270271
if (resolvedParameter.in === 'path') {
@@ -481,7 +482,7 @@ export async function processOpenApiDocument(
481482
}
482483

483484
for (const [statusCode, response] of Object.entries(
484-
operationObject.responses,
485+
operationObject.responses || {},
485486
).filter(([s]) => s.startsWith('2'))) {
486487
// early out if response is 204
487488
if (statusCode === '204') {

lib/process-schema.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable no-console */
2-
import type { OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
2+
import type { oas31, oas30 } from 'openapi3-ts';
33
import {
44
Writers,
55
type CodeBlockWriter,
@@ -24,9 +24,7 @@ function maybeWithNullUnion(type: string | WriterFunction, withNull = false) {
2424
return withNull && type !== 'null' ? Writers.unionType(type, 'null') : type;
2525
}
2626

27-
function schemaTypeIsNull(
28-
schema: OpenAPIV3.SchemaObject | OpenAPIV3_1.SchemaObject,
29-
) {
27+
function schemaTypeIsNull(schema: oas30.SchemaObject | oas31.SchemaObject) {
3028
return (
3129
schema.type === 'null' ||
3230
('nullable' in schema && schema.nullable) ||
@@ -63,12 +61,9 @@ export function schemaToType(
6361
string,
6462
InterfaceDeclaration | TypeAliasDeclaration | EnumDeclaration
6563
>,
66-
parentSchema: OpenAPIV3_1.SchemaObject | OpenAPIV3.SchemaObject,
64+
parentSchema: oas31.SchemaObject | oas30.SchemaObject,
6765
propertyName: string,
68-
schemaObject:
69-
| OpenAPIV3_1.SchemaObject
70-
| OpenAPIV3.SchemaObject
71-
| OpenAPIV3_1.ReferenceObject,
66+
schemaObject: oas31.SchemaObject | oas30.SchemaObject | oas31.ReferenceObject,
7267
options: {
7368
exactOptionalPropertyTypes?: boolean;
7469
booleanAsStringish?: boolean;
@@ -127,9 +122,19 @@ export function schemaToType(
127122
},
128123
]
129124
: []),
130-
...(schemaObject.example
125+
126+
// 3
127+
...('example' in schemaObject
131128
? [{ tagName: 'example', text: String(schemaObject.example) }]
132129
: []),
130+
131+
// 3.1
132+
...('examples' in schemaObject
133+
? schemaObject.examples.map((example) => ({
134+
tagName: 'example',
135+
text: JSON.stringify(example),
136+
}))
137+
: []),
133138
...(schemaObject.deprecated ? [{ tagName: 'deprecated' }] : []),
134139
];
135140

@@ -168,13 +173,11 @@ export function schemaToType(
168173
items: {},
169174
...schemaObject,
170175
type: 'array',
171-
} satisfies
172-
| OpenAPIV3.ArraySchemaObject
173-
| OpenAPIV3_1.ArraySchemaObject)
174-
: {
176+
} satisfies typeof schemaObject)
177+
: ({
175178
...schemaObject,
176179
type,
177-
};
180+
} satisfies typeof schemaObject);
178181

179182
return (
180183
schemaToType(typesAndInterfaces, schemaObject, name, schema).type ||
@@ -420,10 +423,10 @@ export function registerTypesFromSchema(
420423
typesFile: SourceFile,
421424
schemaName: string,
422425
schemaObject:
423-
| OpenAPIV3.SchemaObject
424-
| OpenAPIV3.ReferenceObject
425-
| OpenAPIV3_1.SchemaObject
426-
| OpenAPIV3_1.ReferenceObject,
426+
| oas30.SchemaObject
427+
| oas30.ReferenceObject
428+
| oas31.SchemaObject
429+
| oas31.ReferenceObject,
427430
) {
428431
// deal with refs
429432
if ('$ref' in schemaObject) {

lib/utils.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import camelcase from 'camelcase';
2-
import type { OpenAPIV3_1 } from 'openapi-types';
2+
import type { oas31 } from 'openapi3-ts';
33
import wrap from 'word-wrap';
44

55
export function maybeJsDocDescription(
@@ -8,19 +8,17 @@ export function maybeJsDocDescription(
88
return str.length > 0 ? ['', ...str].filter(Boolean).join(' - ').trim() : '';
99
}
1010

11-
export function isReferenceObject(
12-
obj: unknown,
13-
): obj is OpenAPIV3_1.ReferenceObject {
11+
export function isReferenceObject(obj: unknown): obj is oas31.ReferenceObject {
1412
return typeof obj === 'object' && obj !== null && '$ref' in obj;
1513
}
1614

1715
export function getDependency(obj: unknown): string | undefined {
1816
return isReferenceObject(obj) ? obj.$ref : undefined;
1917
}
2018

21-
export function isNotReferenceObject<
22-
T extends OpenAPIV3_1.ReferenceObject | unknown,
23-
>(obj: T): obj is Exclude<T, OpenAPIV3_1.ReferenceObject> {
19+
export function isNotReferenceObject<T extends oas31.ReferenceObject | unknown>(
20+
obj: T,
21+
): obj is Exclude<T, oas31.ReferenceObject> {
2422
return !isReferenceObject(obj);
2523
}
2624

@@ -29,7 +27,7 @@ export function isNotNullOrUndefined<T>(obj: T | null | undefined): obj is T {
2927
}
3028

3129
export function getDependents(
32-
obj: OpenAPIV3_1.ReferenceObject | OpenAPIV3_1.SchemaObject,
30+
obj: oas31.ReferenceObject | oas31.SchemaObject,
3331
): string[] {
3432
const strOnly = (x: string | undefined): x is string => typeof x === 'string';
3533

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"eslint-plugin-react": "^7.37.1",
5555
"eslint-plugin-react-hooks": "^4.6.2",
5656
"js-yaml": "^4.1.0",
57-
"openapi-types": "^12.1.3",
57+
"openapi3-ts": "^4.4.0",
5858
"prettier": "^2.8.8",
5959
"typescript": "^5.6.2",
6060
"undici": "^6.19.8",

pnpm-lock.yaml

Lines changed: 15 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)