11import type { OpenAPIV3_1 } from 'openapi-types'
2+ import { SchemaValidationError } from './errors'
23import { toPascalCase } from './utils'
34
45function isReferenceObject ( obj : any ) : obj is OpenAPIV3_1 . ReferenceObject {
@@ -46,14 +47,31 @@ export class SchemaGenerator {
4647 schema : OpenAPIV3_1 . SchemaObject | OpenAPIV3_1 . ReferenceObject
4748 } {
4849 if ( ! ref . startsWith ( '#/components/schemas/' ) ) {
49- throw new Error (
50- `Unsupported $ref format: ${ ref } . Only local component schema references are supported.`
50+ throw new SchemaValidationError (
51+ `Unsupported $ref format: ${ ref } ` ,
52+ 'unknown' ,
53+ ref ,
54+ 'Use the format "#/components/schemas/SchemaName" for schema references'
5155 )
5256 }
5357 const name = ref . split ( '/' ) . pop ( )
54- if ( ! name ) throw new Error ( `Invalid $ref: ${ ref } ` )
58+ if ( ! name ) {
59+ throw new SchemaValidationError (
60+ `Invalid $ref path: ${ ref } ` ,
61+ 'unknown' ,
62+ ref ,
63+ 'Ensure $ref follows "#/components/schemas/SchemaName" format'
64+ )
65+ }
5566 const schema = this . spec . components ?. schemas ?. [ name ]
56- if ( ! schema ) throw new Error ( `Schema not found for $ref: ${ ref } ` )
67+ if ( ! schema ) {
68+ throw new SchemaValidationError (
69+ `Schema not found for $ref: ${ ref } ` ,
70+ name ,
71+ ref ,
72+ `Check that the schema "${ name } " is defined in components.schemas`
73+ )
74+ }
5775 return { name, schema }
5876 }
5977
@@ -63,7 +81,12 @@ export class SchemaGenerator {
6381 ) : string {
6482 const schema = schemaObject || this . spec . components ?. schemas ?. [ name ]
6583 if ( ! schema ) {
66- throw new Error ( `Schema with name ${ name } not found.` )
84+ throw new SchemaValidationError (
85+ `Schema "${ name } " not found in specification` ,
86+ name ,
87+ `components.schemas.${ name } ` ,
88+ 'Check that the schema is defined in the components.schemas section'
89+ )
6790 }
6891
6992 if ( this . processedSchemas . has ( name ) && ! schemaObject ) {
@@ -95,8 +118,11 @@ export class SchemaGenerator {
95118 this . processedSchemas . get ( baseSchemaName )
96119
97120 if ( ! baseSchemaString ) {
98- throw new Error (
99- `Base schema ${ baseSchemaName } not found in processed schemas`
121+ throw new SchemaValidationError (
122+ `Base schema "${ baseSchemaName } " not found in processed schemas` ,
123+ baseSchemaName ,
124+ `allOf[0].$ref` ,
125+ 'Ensure the base schema is defined before using it in allOf'
100126 )
101127 }
102128
@@ -127,10 +153,14 @@ export class SchemaGenerator {
127153 if ( schema . oneOf && schema . discriminator ) {
128154 const discriminator = schema . discriminator . propertyName
129155 const options = items . map ( ( s ) => {
130- if ( ! isReferenceObject ( s ) )
131- throw new Error (
132- 'oneOf with discriminator must use $ref objects'
156+ if ( ! isReferenceObject ( s ) ) {
157+ throw new SchemaValidationError (
158+ 'oneOf with discriminator must use $ref objects' ,
159+ name ,
160+ 'oneOf' ,
161+ 'Move inline schemas to components.schemas and reference them with $ref'
133162 )
163+ }
134164 return this . mapSchemaObjectToZod ( name , s )
135165 } )
136166 const zodSchema = `z.discriminatedUnion('${ discriminator } ', [${ options . join ( ', ' ) } ])`
0 commit comments