Skip to content

Commit 5fa614d

Browse files
authored
fix: include schemas from all documents in dependency graph (#227)
previously schemas loaded from other documents like `$ref: './common.yaml#/components/schemas/FooBar'` were not always correctly considered when building the schema dependency graph. this meant that you could have schemas output in an ordering that would not build, due to variables not having been initialized.
1 parent e32afd5 commit 5fa614d

4 files changed

Lines changed: 25 additions & 9 deletions

File tree

integration-tests/typescript-koa/src/generated/todo-lists.yaml/schemas.ts

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

packages/openapi-code-generator/src/core/dependency-graph.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export function buildDependencyGraph(
106106
* Create an object mapping name -> Set(direct dependencies)
107107
*/
108108
const dependencyGraph = Object.fromEntries(
109+
// TODO: this may miss extracted in-line schemas
109110
Object.entries(input.allSchemas()).map(([name, schema]) => {
110111
return [
111112
getNameForRef({$ref: name}),

packages/openapi-code-generator/src/core/input.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636

3737
export type OperationGroup = {name: string; operations: IROperation[]}
3838
export type OperationGroupStrategy = "none" | "first-tag" | "first-slug"
39+
3940
export class Input {
4041
constructor(
4142
readonly loader: OpenapiLoader,
@@ -47,7 +48,17 @@ export class Input {
4748
}
4849

4950
allSchemas(): Record<string, IRModel> {
50-
const schemas = this.loader.entryPoint.components?.schemas ?? {}
51+
const allDocuments = this.loader.allDocuments()
52+
53+
const schemas = allDocuments.reduce(
54+
(acc, it) => {
55+
return Object.assign(acc, it.components?.schemas ?? {})
56+
},
57+
{} as {
58+
[schemaName: string]: Schema | Reference
59+
},
60+
)
61+
5162
return Object.fromEntries(
5263
Object.entries(schemas).map(([name, maybeSchema]) => {
5364
return [name, this.schema(normalizeSchemaObject(maybeSchema))]

packages/openapi-code-generator/src/core/openapi-loader.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import type {OpenapiValidator} from "./openapi-validator"
2121

2222
export class OpenapiLoader {
2323
private readonly virtualLibrary = new Map<string, VirtualDefinition>()
24-
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
25-
private readonly library = new Map<string, any>()
24+
private readonly library = new Map<string, OpenapiDocument>()
2625

2726
private constructor(
2827
private readonly entryPointKey: string,
@@ -50,6 +49,10 @@ export class OpenapiLoader {
5049
return this.library.get(this.entryPointKey)!
5150
}
5251

52+
allDocuments(): OpenapiDocument[] {
53+
return Array.from(this.library.values())
54+
}
55+
5356
paths(maybeRef: Reference | Path): Path {
5457
return isRef(maybeRef) ? this.$ref(maybeRef) : maybeRef
5558
}
@@ -81,7 +84,8 @@ export class OpenapiLoader {
8184
private $ref<T>({$ref}: Reference): T {
8285
const [key, objPath] = $ref.split("#")
8386

84-
const obj = key && this.library.get(key)
87+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
88+
const obj: any = key && this.library.get(key)
8589

8690
if (!obj) {
8791
throw new Error(`could not load $ref, key not loaded. $ref: '${$ref}'`)

0 commit comments

Comments
 (0)