@@ -157,36 +157,36 @@ function deriveFunctionSchema(functionDeclaration: ts.FunctionDeclaration, conte
157157
158158 const paramTypeResult = deriveSchemaTypeForTsType ( paramType , paramTypePath , context ) ;
159159
160- if ( "errors" in paramTypeResult ) {
160+ if ( paramTypeResult instanceof Err ) {
161161 // Record the error, discard the parameter, but mark the function
162162 // as broken so we discard the whole thing at the end
163- issues . push ( ...paramTypeResult . errors )
163+ issues . push ( ...paramTypeResult . error )
164164 functionIsBroken = true ;
165165 return [ ] ;
166166 } else {
167- issues . push ( ...paramTypeResult . warnings )
167+ issues . push ( ...paramTypeResult . data . warnings )
168168 return [ {
169169 argumentName : paramName ,
170170 description : paramDesc ? paramDesc : null ,
171- type : paramTypeResult . typeDefinition ,
171+ type : paramTypeResult . data . typeDefinition ,
172172 } ]
173173 }
174174 } ) ;
175175
176176 const returnTypeResult = deriveSchemaTypeForTsType ( functionCallSig . getReturnType ( ) , [ { segmentType : "FunctionReturn" , functionName} ] , context ) ;
177177 let functionDefinition : schema . FunctionDefinition | null = null ;
178- if ( "errors" in returnTypeResult ) {
178+ if ( returnTypeResult instanceof Err ) {
179179 // Record the error, mark the function as broken so we discard the whole thing at the end
180- issues . push ( ...returnTypeResult . errors )
180+ issues . push ( ...returnTypeResult . error )
181181 functionIsBroken = true ;
182182 functionDefinition = null ;
183183 } else {
184- issues . push ( ...returnTypeResult . warnings )
184+ issues . push ( ...returnTypeResult . data . warnings )
185185 functionDefinition = {
186186 description : functionDescription ? functionDescription : null ,
187187 ndcKind : markedPureInJsDoc ? schema . FunctionNdcKind . Function : schema . FunctionNdcKind . Procedure ,
188188 arguments : functionSchemaArguments ,
189- resultType : returnTypeResult . typeDefinition
189+ resultType : returnTypeResult . data . typeDefinition
190190 }
191191 }
192192
@@ -219,26 +219,25 @@ function typePathSegmentToString(segment: TypePathSegment): string {
219219 }
220220}
221221
222- type DeriveSchemaTypeResult =
222+ type DerivedSchemaType =
223223 { typeDefinition : schema . TypeDefinition , warnings : string [ ] }
224- | { errors : string [ ] }
225224
226- function deriveSchemaTypeForTsType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number = 0 ) : DeriveSchemaTypeResult {
225+ function deriveSchemaTypeForTsType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number = 0 ) : Result < DerivedSchemaType , string [ ] > {
227226 const typeRenderedName = context . typeChecker . typeToString ( tsType ) ;
228227
229228 if ( recursionDepth > MAX_TYPE_DERIVATION_RECURSION )
230229 throw new Error ( `Schema inference validation exceeded depth ${ MAX_TYPE_DERIVATION_RECURSION } for type ${ typeRenderedName } ` )
231230
232231 if ( unwrapPromiseType ( tsType , context . typeChecker ) !== undefined ) {
233- return { errors : [ `Promise types are not supported, but one was encountered in ${ typePathToString ( typePath ) } .` ] } ;
232+ return new Err ( [ `Promise types are not supported, but one was encountered in ${ typePathToString ( typePath ) } .` ] ) ;
234233 }
235234
236235 if ( tsutils . isObjectType ( tsType ) && tsutils . isObjectFlagSet ( tsType , ts . ObjectFlags . Class ) ) {
237- return { errors : [ `Class types are not supported, but one was encountered in ${ typePathToString ( typePath ) } ` ] }
236+ return new Err ( [ `Class types are not supported, but one was encountered in ${ typePathToString ( typePath ) } ` ] ) ;
238237 }
239238
240239 if ( tsutils . isIntrinsicVoidType ( tsType ) ) {
241- return { errors : [ `The void type is not supported, but one was encountered in ${ typePathToString ( typePath ) } ` ] }
240+ return new Err ( [ `The void type is not supported, but one was encountered in ${ typePathToString ( typePath ) } ` ] ) ;
242241 }
243242
244243 const schemaTypeResult =
@@ -253,79 +252,70 @@ function deriveSchemaTypeForTsType(tsType: ts.Type, typePath: TypePathSegment[],
253252 // We don't know how to deal with this type, so just make it an opaque scalar
254253 const typeName = generateTypeNameFromTypePath ( typePath ) ;
255254 context . scalarTypeDefinitions [ typeName ] = { } ;
256- return {
255+ return new Ok ( {
257256 warnings : [ `Unable to derive an NDC type for ${ typePathToString ( typePath ) } (type: ${ context . typeChecker . typeToString ( tsType ) } ). Assuming that it is a scalar type.` ] ,
258257 typeDefinition : { type : "named" , kind : "scalar" , name : typeName }
259- } ;
258+ } ) ;
260259}
261260
262- function deriveSchemaTypeIfTsArrayType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number ) : DeriveSchemaTypeResult | undefined {
261+ function deriveSchemaTypeIfTsArrayType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number ) : Result < DerivedSchemaType , string [ ] > | undefined {
263262 if ( context . typeChecker . isArrayType ( tsType ) && tsutils . isTypeReference ( tsType ) ) {
264263 const typeArgs = context . typeChecker . getTypeArguments ( tsType )
265264 if ( typeArgs . length === 1 ) {
266265 const innerType = typeArgs [ 0 ] ! ;
267- const innerTypeResult = deriveSchemaTypeForTsType ( innerType , [ ...typePath , { segmentType : "Array" } ] , context , recursionDepth + 1 ) ;
268- return "errors" in innerTypeResult
269- ? innerTypeResult
270- : { typeDefinition : { type : "array" , elementType : innerTypeResult . typeDefinition } , warnings : innerTypeResult . warnings } ;
266+ return deriveSchemaTypeForTsType ( innerType , [ ...typePath , { segmentType : "Array" } ] , context , recursionDepth + 1 )
267+ . map ( innerTypeResult => ( { typeDefinition : { type : "array" , elementType : innerTypeResult . typeDefinition } , warnings : innerTypeResult . warnings } ) ) ;
271268 }
272269 }
273270}
274271
275- function deriveSchemaTypeIfScalarType ( tsType : ts . Type , context : TypeDerivationContext ) : DeriveSchemaTypeResult | undefined {
272+ function deriveSchemaTypeIfScalarType ( tsType : ts . Type , context : TypeDerivationContext ) : Result < DerivedSchemaType , string [ ] > | undefined {
276273 if ( tsutils . isIntrinsicBooleanType ( tsType ) ) {
277274 context . scalarTypeDefinitions [ "Boolean" ] = { } ;
278- return { typeDefinition : { type : "named" , kind : "scalar" , name : "Boolean" } , warnings : [ ] } ;
275+ return new Ok ( { typeDefinition : { type : "named" , kind : "scalar" , name : "Boolean" } , warnings : [ ] } ) ;
279276 }
280277 if ( tsutils . isIntrinsicStringType ( tsType ) ) {
281278 context . scalarTypeDefinitions [ "String" ] = { } ;
282- return { typeDefinition : { type : "named" , kind : "scalar" , name : "String" } , warnings : [ ] } ;
279+ return new Ok ( { typeDefinition : { type : "named" , kind : "scalar" , name : "String" } , warnings : [ ] } ) ;
283280 }
284281 if ( tsutils . isIntrinsicNumberType ( tsType ) ) {
285282 context . scalarTypeDefinitions [ "Float" ] = { } ;
286- return { typeDefinition : { type : "named" , kind : "scalar" , name : "Float" } , warnings : [ ] } ;
283+ return new Ok ( { typeDefinition : { type : "named" , kind : "scalar" , name : "Float" } , warnings : [ ] } ) ;
287284 }
288285}
289286
290- function deriveSchemaTypeIfNullableType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number ) : DeriveSchemaTypeResult | undefined {
287+ function deriveSchemaTypeIfNullableType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number ) : Result < DerivedSchemaType , string [ ] > | undefined {
291288 const notNullableResult = unwrapNullableType ( tsType ) ;
292289 if ( notNullableResult !== null ) {
293290 const [ notNullableType , nullOrUndefinability ] = notNullableResult ;
294- const notNullableTypeResult = deriveSchemaTypeForTsType ( notNullableType , typePath , context , recursionDepth + 1 ) ;
295- if ( "errors" in notNullableTypeResult ) return notNullableTypeResult ;
296- return { typeDefinition : { type : "nullable" , underlyingType : notNullableTypeResult . typeDefinition , nullOrUndefinability } , warnings : notNullableTypeResult . warnings }
291+ return deriveSchemaTypeForTsType ( notNullableType , typePath , context , recursionDepth + 1 )
292+ . map ( notNullableTypeResult => ( { typeDefinition : { type : "nullable" , underlyingType : notNullableTypeResult . typeDefinition , nullOrUndefinability } , warnings : notNullableTypeResult . warnings } ) )
297293 }
298294}
299295
300- function deriveSchemaTypeIfObjectType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number ) : DeriveSchemaTypeResult | undefined {
296+ function deriveSchemaTypeIfObjectType ( tsType : ts . Type , typePath : TypePathSegment [ ] , context : TypeDerivationContext , recursionDepth : number ) : Result < DerivedSchemaType , string [ ] > | undefined {
301297 const info = getObjectTypeInfo ( tsType , typePath , context . typeChecker , context . functionsFilePath ) ;
302298 if ( info ) {
303299 // Shortcut recursion if the type has already been named
304300 if ( context . objectTypeDefinitions [ info . generatedTypeName ] ) {
305- return { typeDefinition : { type : 'named' , name : info . generatedTypeName , kind : "object" } , warnings : [ ] } ;
301+ return new Ok ( { typeDefinition : { type : 'named' , name : info . generatedTypeName , kind : "object" } , warnings : [ ] } ) ;
306302 }
307303
308304 context . objectTypeDefinitions [ info . generatedTypeName ] = { properties : [ ] } ; // Break infinite recursion
309305
310- const errors : string [ ] = [ ] ;
311306 const warnings : string [ ] = [ ] ;
312- const properties = Array . from ( info . members ) . flatMap ( ( [ propertyName , propertyType ] ) => {
313- const propertyTypeResult = deriveSchemaTypeForTsType ( propertyType , [ ...typePath , { segmentType : "ObjectProperty" , typeName : info . generatedTypeName , propertyName } ] , context , recursionDepth + 1 ) ;
314- if ( "errors" in propertyTypeResult ) {
315- errors . push ( ...propertyTypeResult . errors )
316- return [ ] ;
317- } else {
318- warnings . push ( ...propertyTypeResult . warnings )
319- return [ { propertyName : propertyName , type : propertyTypeResult . typeDefinition } ]
320- }
307+ const propertyResults = Result . traverseAndCollectErrors ( Array . from ( info . members ) , ( [ propertyName , propertyType ] ) => {
308+ return deriveSchemaTypeForTsType ( propertyType , [ ...typePath , { segmentType : "ObjectProperty" , typeName : info . generatedTypeName , propertyName } ] , context , recursionDepth + 1 )
309+ . map ( propertyTypeResult => {
310+ warnings . push ( ...propertyTypeResult . warnings )
311+ return { propertyName : propertyName , type : propertyTypeResult . typeDefinition }
312+ } ) ;
321313 } ) ;
322314
323- if ( errors . length === 0 ) {
315+ return propertyResults . map ( properties => {
324316 context . objectTypeDefinitions [ info . generatedTypeName ] = { properties }
325317 return { typeDefinition : { type : 'named' , name : info . generatedTypeName , kind : "object" } , warnings }
326- } else {
327- return { errors } ;
328- }
318+ } )
329319 }
330320}
331321
0 commit comments